From f6b67f92a19e5441bee9ac57fbcd1a845935b3e0 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 11 Dec 2022 12:39:59 +0100 Subject: [PATCH 0001/1522] Cleanup: unused parameter --- source/blender/nodes/composite/nodes/node_composite_glare.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/nodes/composite/nodes/node_composite_glare.cc b/source/blender/nodes/composite/nodes/node_composite_glare.cc index 51772222bcf..d92df4c4b38 100644 --- a/source/blender/nodes/composite/nodes/node_composite_glare.cc +++ b/source/blender/nodes/composite/nodes/node_composite_glare.cc @@ -339,7 +339,7 @@ class GlareOperation : public NodeOperation { * --------------- */ /* Not yet implemented. Unreachable code due to the is_identity method. */ - Result execute_fog_glow(Result &highlights_result) + Result execute_fog_glow(Result & /*highlights_result*/) { BLI_assert_unreachable(); return Result(ResultType::Color, texture_pool()); @@ -350,7 +350,7 @@ class GlareOperation : public NodeOperation { * -------------- */ /* Not yet implemented. Unreachable code due to the is_identity method. */ - Result execute_streaks(Result &highlights_result) + Result execute_streaks(Result & /*highlights_result*/) { BLI_assert_unreachable(); return Result(ResultType::Color, texture_pool()); From c2ca30ea24197a3d25e01f0025b2c57fa49804e9 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 11 Dec 2022 14:15:46 +0100 Subject: [PATCH 0002/1522] Cleanup: avoid calling generic node update functions from versioning code This made it harder to change these functions in the future. No functional changes are expected and the versioning worked correctly in my test with a files created in Blender 2.69. Adding the sockets in the function was not necessary in my test, because those were already added before as part of `node_verify_sockets` in `ntreeBlendReadLib`. I kept it in just to be on the safe side. --- .../blenloader/intern/versioning_270.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 3885c23a422..5d966344717 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -276,13 +276,22 @@ static void do_version_hue_sat_node(bNodeTree *ntree, bNode *node) return; } - /* Make sure new sockets are properly created. */ - node_verify_sockets(ntree, node, false); /* Convert value from old storage to new sockets. */ NodeHueSat *nhs = node->storage; - bNodeSocket *hue = nodeFindSocket(node, SOCK_IN, "Hue"), - *saturation = nodeFindSocket(node, SOCK_IN, "Saturation"), - *value = nodeFindSocket(node, SOCK_IN, "Value"); + bNodeSocket *hue = nodeFindSocket(node, SOCK_IN, "Hue"); + bNodeSocket *saturation = nodeFindSocket(node, SOCK_IN, "Saturation"); + bNodeSocket *value = nodeFindSocket(node, SOCK_IN, "Value"); + if (hue == NULL) { + hue = nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Hue", "Hue"); + } + if (saturation == NULL) { + saturation = nodeAddStaticSocket( + ntree, node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Saturation", "Saturation"); + } + if (value == NULL) { + value = nodeAddStaticSocket(ntree, node, SOCK_IN, SOCK_FLOAT, PROP_FACTOR, "Value", "Value"); + } + ((bNodeSocketValueFloat *)hue->default_value)->value = nhs->hue; ((bNodeSocketValueFloat *)saturation->default_value)->value = nhs->sat; ((bNodeSocketValueFloat *)value->default_value)->value = nhs->val; From b2bee8416b0fbf5fbc70a57494c5827a3d8265ef Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 11 Dec 2022 15:07:27 +0100 Subject: [PATCH 0003/1522] Fix oslc precompiled binary not working on macOS due to wrong rpath --- build_files/build_environment/cmake/harvest.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index 8c9cf1fb878..10d0c414303 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -218,7 +218,7 @@ harvest_rpath_lib(openvdb/lib openvdb/lib "*${SHAREDLIBEXT}*") harvest_rpath_python(openvdb/lib/python${PYTHON_SHORT_VERSION} python/lib/python${PYTHON_SHORT_VERSION} "*pyopenvdb*") harvest(xr_openxr_sdk/include/openxr xr_openxr_sdk/include/openxr "*.h") harvest(xr_openxr_sdk/lib xr_openxr_sdk/lib "*.a") -harvest(osl/bin osl/bin "oslc") +harvest_rpath_bin(osl/bin osl/bin "oslc") harvest(osl/include osl/include "*.h") harvest(osl/lib osl/lib "*.a") harvest(osl/share/OSL/shaders osl/share/OSL/shaders "*.h") From 19491e5fc090b5f33b08b4b225466026fddf6b6b Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 11 Dec 2022 19:12:09 +0100 Subject: [PATCH 0004/1522] Nodes: extract function that builds the node declaration This also makes it easier to add some post processing on top of the node-defined declaration. --- source/blender/blenkernel/intern/node.cc | 6 ++---- source/blender/editors/space_node/node_templates.cc | 3 +-- source/blender/nodes/NOD_node_declaration.hh | 2 ++ source/blender/nodes/intern/node_declaration.cc | 6 ++++++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index da215c9003a..f195be3c0e6 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -1373,8 +1373,7 @@ void nodeRegisterType(bNodeType *nt) if (nt->declare && !nt->declaration_is_dynamic) { if (nt->fixed_declaration == nullptr) { nt->fixed_declaration = new blender::nodes::NodeDeclaration(); - blender::nodes::NodeDeclarationBuilder builder{*nt->fixed_declaration}; - nt->declare(builder); + blender::nodes::build_node_declaration(*nt, *nt->fixed_declaration); } } @@ -3607,8 +3606,7 @@ bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree * /*ntree*/, bNode *node) } if (node->typeinfo->declaration_is_dynamic) { node->runtime->declaration = new blender::nodes::NodeDeclaration(); - blender::nodes::NodeDeclarationBuilder builder{*node->runtime->declaration}; - node->typeinfo->declare(builder); + blender::nodes::build_node_declaration(*node->typeinfo, *node->runtime->declaration); } else { /* Declaration should have been created in #nodeRegisterType. */ diff --git a/source/blender/editors/space_node/node_templates.cc b/source/blender/editors/space_node/node_templates.cc index 18c6e49c8a2..c16e09f4b2f 100644 --- a/source/blender/editors/space_node/node_templates.cc +++ b/source/blender/editors/space_node/node_templates.cc @@ -361,8 +361,7 @@ static Vector ui_node_link_items(NodeLinkArg *arg, using namespace blender::nodes; r_node_decl.emplace(NodeDeclaration()); - NodeDeclarationBuilder node_decl_builder{*r_node_decl}; - arg->node_type->declare(node_decl_builder); + blender::nodes::build_node_declaration(*arg->node_type, *r_node_decl); Span socket_decls = (in_out == SOCK_IN) ? r_node_decl->inputs() : r_node_decl->outputs(); int index = 0; diff --git a/source/blender/nodes/NOD_node_declaration.hh b/source/blender/nodes/NOD_node_declaration.hh index 13f8af4ddf5..b06f0736917 100644 --- a/source/blender/nodes/NOD_node_declaration.hh +++ b/source/blender/nodes/NOD_node_declaration.hh @@ -367,6 +367,8 @@ void index(const bNode &node, void *r_value); void id_or_index(const bNode &node, void *r_value); } // namespace implicit_field_inputs +void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declaration); + /* -------------------------------------------------------------------- */ /** \name #OutputFieldDependency Inline Methods * \{ */ diff --git a/source/blender/nodes/intern/node_declaration.cc b/source/blender/nodes/intern/node_declaration.cc index f323d035668..7a6e237a18f 100644 --- a/source/blender/nodes/intern/node_declaration.cc +++ b/source/blender/nodes/intern/node_declaration.cc @@ -7,6 +7,12 @@ namespace blender::nodes { +void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declaration) +{ + NodeDeclarationBuilder node_decl_builder{r_declaration}; + typeinfo.declare(node_decl_builder); +} + bool NodeDeclaration::matches(const bNode &node) const { auto check_sockets = [&](ListBase sockets, Span socket_decls) { From 05bf5c4e0ea8bd53d7f121efc683f990afc8a69d Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 11 Dec 2022 19:38:26 +0100 Subject: [PATCH 0005/1522] Nodes: simplify handling of function nodes in declaration This adds an explicit post processing step to node declarations. The purpose of this is to keep the actual node declaration functions concise by avoiding to specify redundant information. Also it improves the separation of the creation of the declaration from using it. --- .../intern/node_tree_field_inferencing.cc | 12 ---------- source/blender/nodes/NOD_node_declaration.hh | 22 +++++-------------- .../blender/nodes/intern/node_declaration.cc | 15 +++++++++++++ 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/source/blender/blenkernel/intern/node_tree_field_inferencing.cc b/source/blender/blenkernel/intern/node_tree_field_inferencing.cc index 0413e28a297..82e425dfbb9 100644 --- a/source/blender/blenkernel/intern/node_tree_field_inferencing.cc +++ b/source/blender/blenkernel/intern/node_tree_field_inferencing.cc @@ -56,13 +56,6 @@ static InputSocketFieldType get_interface_input_field_type(const bNode &node, /* Get the field type from the declaration. */ const SocketDeclaration &socket_decl = *node_decl->inputs()[socket.index()]; const InputSocketFieldType field_type = socket_decl.input_field_type(); - if (field_type == InputSocketFieldType::Implicit) { - return field_type; - } - if (node_decl->is_function_node()) { - /* In a function node, every socket supports fields. */ - return InputSocketFieldType::IsSupported; - } return field_type; } @@ -93,11 +86,6 @@ static OutputFieldDependency get_interface_output_field_dependency(const bNode & /* Node declarations should be implemented for nodes involved here. */ BLI_assert(node_decl != nullptr); - if (node_decl->is_function_node()) { - /* In a generic function node, all outputs depend on all inputs. */ - return OutputFieldDependency::ForDependentField(); - } - /* Use the socket declaration. */ const SocketDeclaration &socket_decl = *node_decl->outputs()[socket.index()]; return socket_decl.output_field_dependency(); diff --git a/source/blender/nodes/NOD_node_declaration.hh b/source/blender/nodes/NOD_node_declaration.hh index b06f0736917..975cc96131c 100644 --- a/source/blender/nodes/NOD_node_declaration.hh +++ b/source/blender/nodes/NOD_node_declaration.hh @@ -309,7 +309,6 @@ class NodeDeclaration { private: Vector inputs_; Vector outputs_; - bool is_function_node_ = false; friend NodeDeclarationBuilder; @@ -320,11 +319,6 @@ class NodeDeclaration { Span outputs() const; Span sockets(eNodeSocketInOut in_out) const; - bool is_function_node() const - { - return is_function_node_; - } - MEM_CXX_CLASS_ALLOC_FUNCS("NodeDeclaration") }; @@ -332,22 +326,22 @@ class NodeDeclarationBuilder { private: NodeDeclaration &declaration_; Vector> builders_; + bool is_function_node_ = false; public: NodeDeclarationBuilder(NodeDeclaration &declaration); /** * All inputs support fields, and all outputs are fields if any of the inputs is a field. - * Calling field status definitions on each socket is unnecessary. Must be called before adding - * any sockets. + * Calling field status definitions on each socket is unnecessary. */ - void is_function_node(bool value = true) + void is_function_node() { - BLI_assert_msg(declaration_.inputs().is_empty() && declaration_.outputs().is_empty(), - "is_function_node() must be called before any socket is created"); - declaration_.is_function_node_ = value; + is_function_node_ = true; } + void finalize(); + template typename DeclType::Builder &add_input(StringRef name, StringRef identifier = ""); template @@ -553,10 +547,6 @@ inline typename DeclType::Builder &NodeDeclarationBuilder::add_socket(StringRef socket_decl->name_ = name; socket_decl->identifier_ = identifier.is_empty() ? name : identifier; socket_decl->in_out_ = in_out; - if (declaration_.is_function_node()) { - socket_decl->input_field_type_ = InputSocketFieldType::IsSupported; - socket_decl->output_field_dependency_ = OutputFieldDependency::ForDependentField(); - } declarations.append(std::move(socket_decl)); Builder &socket_decl_builder_ref = *socket_decl_builder; builders_.append(std::move(socket_decl_builder)); diff --git a/source/blender/nodes/intern/node_declaration.cc b/source/blender/nodes/intern/node_declaration.cc index 7a6e237a18f..0811bfeb516 100644 --- a/source/blender/nodes/intern/node_declaration.cc +++ b/source/blender/nodes/intern/node_declaration.cc @@ -11,6 +11,21 @@ void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declar { NodeDeclarationBuilder node_decl_builder{r_declaration}; typeinfo.declare(node_decl_builder); + node_decl_builder.finalize(); +} + +void NodeDeclarationBuilder::finalize() +{ + if (is_function_node_) { + for (SocketDeclarationPtr &socket_decl : declaration_.inputs_) { + if (socket_decl->input_field_type_ != InputSocketFieldType::Implicit) { + socket_decl->input_field_type_ = InputSocketFieldType::IsSupported; + } + } + for (SocketDeclarationPtr &socket_decl : declaration_.outputs_) { + socket_decl->output_field_dependency_ = OutputFieldDependency::ForDependentField(); + } + } } bool NodeDeclaration::matches(const bNode &node) const From 178eb5bac5fb8e65720d509e1afe3551d96cba05 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 11 Dec 2022 20:23:18 -0600 Subject: [PATCH 0006/1522] Cleanup: Add accessor for node index Add `bNode::index()` to allow accessing node indices directly without manually de-referencing the runtime struct. Also adds some asserts to make sure the access is valid and to check the nodes runtime vector. Eagerly maintain the node's index in the tree so it can be accessed without relying on the topology cache. Differential Revision: https://developer.blender.org/D16683 --- source/blender/blenkernel/BKE_node.h | 4 +++ source/blender/blenkernel/BKE_node_runtime.hh | 13 +++++++- source/blender/blenkernel/intern/node.cc | 14 +++++++-- .../blender/blenkernel/intern/node_runtime.cc | 10 +++---- .../blenkernel/intern/node_tree_update.cc | 14 +++++---- .../blender/editors/space_node/node_draw.cc | 1 + .../editors/space_node/node_relationships.cc | 30 +++++++++---------- .../blender/editors/space_node/node_select.cc | 2 +- source/blender/makesdna/DNA_node_types.h | 2 ++ 9 files changed, 59 insertions(+), 31 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index fd45d698785..5a1198791fb 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -668,6 +668,10 @@ void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node); * Find the first available, non-duplicate name for a given node. */ void nodeUniqueName(struct bNodeTree *ntree, struct bNode *node); +/** + * Create a new unique integer identifier for the node. Also set the node's + * index in the tree, which is an eagerly maintained cache. + */ void nodeUniqueID(struct bNodeTree *ntree, struct bNode *node); /** diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 88b68082ab7..979c7630865 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -251,12 +251,14 @@ class bNodeRuntime : NonCopyable, NonMovable { /** List of cached internal links (input to output), for muted nodes and operators. */ Vector internal_links; + /** Eagerly maintained cache of the node's index in the tree. */ + int index_in_tree = -1; + /** Only valid if #topology_cache_is_dirty is false. */ Vector inputs; Vector outputs; Map inputs_by_identifier; Map outputs_by_identifier; - int index_in_tree = -1; bool has_available_linked_inputs = false; bool has_available_linked_outputs = false; Vector direct_children_in_frame; @@ -467,6 +469,15 @@ inline blender::Span bNodeTree::root_frames() const /** \name #bNode Inline Methods * \{ */ +inline int bNode::index() const +{ + const int index = this->runtime->index_in_tree; + /* The order of nodes should always be consistent with the `nodes_by_id` vector. */ + BLI_assert(index == + this->runtime->owner_tree->runtime->nodes_by_id.index_of_as(this->identifier)); + return index; +} + inline blender::Span bNode::input_sockets() { BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this)); diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index f195be3c0e6..c98a9f67bbc 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -145,11 +145,13 @@ static void ntree_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, cons dst_runtime.nodes_by_id.reserve(ntree_src->all_nodes().size()); BLI_listbase_clear(&ntree_dst->nodes); - LISTBASE_FOREACH (const bNode *, src_node, &ntree_src->nodes) { + int i; + LISTBASE_FOREACH_INDEX (const bNode *, src_node, &ntree_src->nodes, i) { /* Don't find a unique name for every node, since they should have valid names already. */ bNode *new_node = blender::bke::node_copy_with_mapping( ntree_dst, *src_node, flag_subdata, false, socket_map); dst_runtime.nodes_by_id.add_new(new_node); + new_node->runtime->index_in_tree = i; } /* copy links */ @@ -673,9 +675,11 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree) BKE_animdata_blend_read_data(reader, ntree->adt); BLO_read_list(reader, &ntree->nodes); - LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { + int i; + LISTBASE_FOREACH_INDEX (bNode *, node, &ntree->nodes, i) { node->runtime = MEM_new(__func__); node->typeinfo = nullptr; + node->runtime->index_in_tree = i; /* Create the `nodes_by_id` cache eagerly so it can be expected to be valid. Because * we create it here we also have to check for zero identifiers from previous versions. */ @@ -2197,6 +2201,8 @@ void nodeUniqueID(bNodeTree *ntree, bNode *node) node->identifier = new_id; ntree->runtime->nodes_by_id.add_new(node); + node->runtime->index_in_tree = ntree->runtime->nodes_by_id.index_range().last(); + BLI_assert(node->runtime->index_in_tree == ntree->runtime->nodes_by_id.index_of(node)); } bNode *nodeAddNode(const bContext *C, bNodeTree *ntree, const char *idname) @@ -2936,8 +2942,10 @@ void nodeRebuildIDVector(bNodeTree *node_tree) { /* Rebuild nodes #VectorSet which must have the same order as the list. */ node_tree->runtime->nodes_by_id.clear(); - LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) { + int i; + LISTBASE_FOREACH_INDEX (bNode *, node, &node_tree->nodes, i) { node_tree->runtime->nodes_by_id.add_new(node); + node->runtime->index_in_tree = i; } } diff --git a/source/blender/blenkernel/intern/node_runtime.cc b/source/blender/blenkernel/intern/node_runtime.cc index 271be8c0a55..4bdc8f6f9b8 100644 --- a/source/blender/blenkernel/intern/node_runtime.cc +++ b/source/blender/blenkernel/intern/node_runtime.cc @@ -278,7 +278,7 @@ static void toposort_from_start_node(const ToposortDirection direction, Stack nodes_to_check; nodes_to_check.push({&start_node}); - node_states[start_node.runtime->index_in_tree].is_in_stack = true; + node_states[start_node.index()].is_in_stack = true; while (!nodes_to_check.is_empty()) { Item &item = nodes_to_check.peek(); bNode &node = *item.node; @@ -306,7 +306,7 @@ static void toposort_from_start_node(const ToposortDirection direction, } bNodeSocket &linked_socket = *socket.runtime->directly_linked_sockets[item.link_index]; bNode &linked_node = *linked_socket.runtime->owner_node; - ToposortNodeState &linked_node_state = node_states[linked_node.runtime->index_in_tree]; + ToposortNodeState &linked_node_state = node_states[linked_node.index()]; if (linked_node_state.is_done) { /* The linked node has already been visited. */ item.link_index++; @@ -324,7 +324,7 @@ static void toposort_from_start_node(const ToposortDirection direction, /* If no other element has been pushed, the current node can be pushed to the sorted list. */ if (&item == &nodes_to_check.peek()) { - ToposortNodeState &node_state = node_states[node.runtime->index_in_tree]; + ToposortNodeState &node_state = node_states[node.index()]; node_state.is_done = true; node_state.is_in_stack = false; r_sorted_nodes.append(&node); @@ -345,7 +345,7 @@ static void update_toposort(const bNodeTree &ntree, Array node_states(tree_runtime.nodes_by_id.size()); for (bNode *node : tree_runtime.nodes_by_id) { - if (node_states[node->runtime->index_in_tree].is_done) { + if (node_states[node->index()].is_done) { /* Ignore nodes that are done already. */ continue; } @@ -361,7 +361,7 @@ static void update_toposort(const bNodeTree &ntree, if (r_sorted_nodes.size() < tree_runtime.nodes_by_id.size()) { r_cycle_detected = true; for (bNode *node : tree_runtime.nodes_by_id) { - if (node_states[node->runtime->index_in_tree].is_done) { + if (node_states[node->index()].is_done) { /* Ignore nodes that are done already. */ continue; } diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc index 6a488606687..a49baf11680 100644 --- a/source/blender/blenkernel/intern/node_tree_update.cc +++ b/source/blender/blenkernel/intern/node_tree_update.cc @@ -492,9 +492,12 @@ class NodeTreeMainUpdater { #ifdef DEBUG /* Check the uniqueness of node identifiers. */ Set node_identifiers; - for (bNode *node : ntree.all_nodes()) { - BLI_assert(node->identifier > 0); - node_identifiers.add_new(node->identifier); + const Span nodes = ntree.all_nodes(); + for (const int i : nodes.index_range()) { + const bNode &node = *nodes[i]; + BLI_assert(node.identifier > 0); + node_identifiers.add_new(node.identifier); + BLI_assert(node.runtime->index_in_tree == i); } #endif @@ -761,15 +764,14 @@ class NodeTreeMainUpdater { Array toposort_indices(toposort.size()); for (const int i : toposort.index_range()) { const bNode &node = *toposort[i]; - toposort_indices[node.runtime->index_in_tree] = i; + toposort_indices[node.index()] = i; } LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { link->flag |= NODE_LINK_VALID; const bNode &from_node = *link->fromnode; const bNode &to_node = *link->tonode; - if (toposort_indices[from_node.runtime->index_in_tree] > - toposort_indices[to_node.runtime->index_in_tree]) { + if (toposort_indices[from_node.index()] > toposort_indices[to_node.index()]) { link->flag &= ~NODE_LINK_VALID; continue; } diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index d2ad57a138c..65cbb49aaed 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -268,6 +268,7 @@ void node_sort(bNodeTree &ntree) for (const int i : sort_nodes.index_range()) { BLI_addtail(&ntree.nodes, sort_nodes[i]); ntree.runtime->nodes_by_id.add_new(sort_nodes[i]); + sort_nodes[i]->runtime->index_in_tree = i; } } diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index f4c9b9d08aa..450d3bff286 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -1641,31 +1641,31 @@ static void node_join_attach_recursive(bNodeTree &ntree, bNode *frame, const VectorSet &selected_nodes) { - join_states[node->runtime->index_in_tree].done = true; + join_states[node->index()].done = true; if (node == frame) { - join_states[node->runtime->index_in_tree].descendent = true; + join_states[node->index()].descendent = true; } else if (node->parent) { /* call recursively */ - if (!join_states[node->parent->runtime->index_in_tree].done) { + if (!join_states[node->parent->index()].done) { node_join_attach_recursive(ntree, join_states, node->parent, frame, selected_nodes); } /* in any case: if the parent is a descendant, so is the child */ - if (join_states[node->parent->runtime->index_in_tree].descendent) { - join_states[node->runtime->index_in_tree].descendent = true; + if (join_states[node->parent->index()].descendent) { + join_states[node->index()].descendent = true; } else if (selected_nodes.contains(node)) { /* if parent is not an descendant of the frame, reattach the node */ nodeDetachNode(&ntree, node); nodeAttachNode(&ntree, node, frame); - join_states[node->runtime->index_in_tree].descendent = true; + join_states[node->index()].descendent = true; } } else if (selected_nodes.contains(node)) { nodeAttachNode(&ntree, node, frame); - join_states[node->runtime->index_in_tree].descendent = true; + join_states[node->index()].descendent = true; } } @@ -1685,7 +1685,7 @@ static int node_join_exec(bContext *C, wmOperator * /*op*/) Array join_states(ntree.all_nodes().size(), NodeJoinState{false, false}); for (bNode *node : ntree.all_nodes()) { - if (!join_states[node->runtime->index_in_tree].done) { + if (!join_states[node->index()].done) { node_join_attach_recursive(ntree, join_states, node, frame_node, selected_nodes); } } @@ -1818,26 +1818,26 @@ static void node_detach_recursive(bNodeTree &ntree, MutableSpan detach_states, bNode *node) { - detach_states[node->runtime->index_in_tree].done = true; + detach_states[node->index()].done = true; if (node->parent) { /* call recursively */ - if (!detach_states[node->parent->runtime->index_in_tree].done) { + if (!detach_states[node->parent->index()].done) { node_detach_recursive(ntree, detach_states, node->parent); } /* in any case: if the parent is a descendant, so is the child */ - if (detach_states[node->parent->runtime->index_in_tree].descendent) { - detach_states[node->runtime->index_in_tree].descendent = true; + if (detach_states[node->parent->index()].descendent) { + detach_states[node->index()].descendent = true; } else if (node->flag & NODE_SELECT) { /* if parent is not a descendant of a selected node, detach */ nodeDetachNode(&ntree, node); - detach_states[node->runtime->index_in_tree].descendent = true; + detach_states[node->index()].descendent = true; } } else if (node->flag & NODE_SELECT) { - detach_states[node->runtime->index_in_tree].descendent = true; + detach_states[node->index()].descendent = true; } } @@ -1853,7 +1853,7 @@ static int node_detach_exec(bContext *C, wmOperator * /*op*/) * relative order is preserved here! */ for (bNode *node : ntree.all_nodes()) { - if (!detach_states[node->runtime->index_in_tree].done) { + if (!detach_states[node->index()].done) { node_detach_recursive(ntree, detach_states, node); } } diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index 50d23733155..8b25e173d47 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -1267,7 +1267,7 @@ static int node_select_same_type_step_exec(bContext *C, wmOperator *op) } } - bNode *new_active_node = node_tree.all_nodes()[toposort[new_index]->runtime->index_in_tree]; + bNode *new_active_node = node_tree.all_nodes()[toposort[new_index]->index()]; if (new_active_node == &active_node) { return OPERATOR_CANCELLED; } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 11dfe4b99cc..4025726733f 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -358,6 +358,8 @@ typedef struct bNode { bNodeRuntimeHandle *runtime; #ifdef __cplusplus + /** The index in the owner node tree. */ + int index() const; blender::StringRefNull label_or_name() const; bool is_muted() const; bool is_reroute() const; From 9338ab1d625a14c74b39adfa3c6a8fcefa85e70f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 11 Dec 2022 20:27:36 -0600 Subject: [PATCH 0007/1522] Mesh: Avoid storing redundant pointer in corner normal calculation The `lnor` pointer was only used for fans containing a single face, and can be retrieved for a specific loop from the common data anyway. Also saves 8 bytes per corner during the calculation --- .../blender/blenkernel/intern/mesh_normals.cc | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index f32b23476b6..112d13a879b 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -796,7 +796,6 @@ struct LoopSplitTaskData { /** We have to create those outside of tasks, since #MemArena is not thread-safe. */ MLoopNorSpace *lnor_space; - float3 *lnor; const MLoop *ml_curr; const MLoop *ml_prev; int ml_curr_index; @@ -999,9 +998,9 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS const Span verts = common_data->verts; const Span edges = common_data->edges; const Span polynors = common_data->polynors; + MutableSpan loop_normals = common_data->loopnors; MLoopNorSpace *lnor_space = data->lnor_space; - float3 *lnor = data->lnor; const MLoop *ml_curr = data->ml_curr; const MLoop *ml_prev = data->ml_prev; const int ml_curr_index = data->ml_curr_index; @@ -1014,7 +1013,7 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS /* Simple case (both edges around that vertex are sharp in current polygon), * this loop just takes its poly normal. */ - copy_v3_v3(*lnor, polynors[mp_index]); + loop_normals[ml_curr_index] = polynors[mp_index]; #if 0 printf("BASIC: handling loop %d / edge %d / vert %d / poly %d\n", @@ -1042,12 +1041,13 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS sub_v3_v3v3(vec_prev, mv_3->co, mv_pivot->co); normalize_v3(vec_prev); - BKE_lnor_space_define(lnor_space, *lnor, vec_curr, vec_prev, nullptr); + BKE_lnor_space_define(lnor_space, loop_normals[ml_curr_index], vec_curr, vec_prev, nullptr); /* We know there is only one loop in this space, no need to create a link-list in this case. */ BKE_lnor_space_add_loop(lnors_spacearr, lnor_space, ml_curr_index, nullptr, true); if (!clnors_data.is_empty()) { - BKE_lnor_space_custom_data_to_normal(lnor_space, clnors_data[ml_curr_index], *lnor); + BKE_lnor_space_custom_data_to_normal( + lnor_space, clnors_data[ml_curr_index], loop_normals[ml_curr_index]); } } } @@ -1377,7 +1377,6 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const Span mloop static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common_data) { MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr; - MutableSpan loopnors = common_data->loopnors; const Span loops = common_data->loops; const Span polys = common_data->polys; @@ -1414,9 +1413,8 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common const MLoop *ml_curr = &loops[ml_curr_index]; const MLoop *ml_prev = &loops[ml_prev_index]; - float3 *lnors = &loopnors[ml_curr_index]; - for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++, lnors++) { + for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++) { const int *e2l_curr = edge_to_loops[ml_curr->e]; const int *e2l_prev = edge_to_loops[ml_prev->e]; @@ -1471,7 +1469,6 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common } if (IS_EDGE_SHARP(e2l_curr) && IS_EDGE_SHARP(e2l_prev)) { - data->lnor = lnors; data->ml_curr = ml_curr; data->ml_prev = ml_prev; data->ml_curr_index = ml_curr_index; @@ -1494,9 +1491,6 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common * All this due/thanks to link between normals and loop ordering (i.e. winding). */ else { -#if 0 /* Not needed for 'fan' loops. */ - data->lnor = lnors; -#endif data->ml_curr = ml_curr; data->ml_prev = ml_prev; data->ml_curr_index = ml_curr_index; From 0485baaf980887e237812b882d7a8c17f862676f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 11 Dec 2022 21:21:34 -0600 Subject: [PATCH 0008/1522] Cleanup: Reduce use of redundant local variables in normal calculation Since face corner indices are available, using pointers to MLoop and other data is redundant. Using fewer local variables means there is less state to keep track of when reading the algorithm, even if it requires more characters in some cases. --- .../blender/blenkernel/intern/mesh_normals.cc | 108 +++++++----------- 1 file changed, 44 insertions(+), 64 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index 112d13a879b..cd279484e6e 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -997,17 +997,13 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS const Span verts = common_data->verts; const Span edges = common_data->edges; + const Span loops = common_data->loops; const Span polynors = common_data->polynors; MutableSpan loop_normals = common_data->loopnors; MLoopNorSpace *lnor_space = data->lnor_space; - const MLoop *ml_curr = data->ml_curr; - const MLoop *ml_prev = data->ml_prev; const int ml_curr_index = data->ml_curr_index; -#if 0 /* Not needed for 'single' loop. */ const int ml_prev_index = data->ml_prev_index; - const int *e2l_prev = data->e2l_prev; -#endif const int mp_index = data->mp_index; /* Simple case (both edges around that vertex are sharp in current polygon), @@ -1018,8 +1014,8 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS #if 0 printf("BASIC: handling loop %d / edge %d / vert %d / poly %d\n", ml_curr_index, - ml_curr->e, - ml_curr->v, + loops[ml_curr_index].e, + loops[ml_curr_index].v, mp_index); #endif @@ -1027,12 +1023,12 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS if (lnors_spacearr) { float vec_curr[3], vec_prev[3]; - const uint mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */ + const uint mv_pivot_index = loops[ml_curr_index].v; /* The vertex we are "fanning" around! */ const MVert *mv_pivot = &verts[mv_pivot_index]; - const MEdge *me_curr = &edges[ml_curr->e]; + const MEdge *me_curr = &edges[loops[ml_curr_index].e]; const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &verts[me_curr->v2] : &verts[me_curr->v1]; - const MEdge *me_prev = &edges[ml_prev->e]; + const MEdge *me_prev = &edges[loops[ml_prev_index].e]; const MVert *mv_3 = (me_prev->v1 == mv_pivot_index) ? &verts[me_prev->v2] : &verts[me_prev->v1]; @@ -1070,12 +1066,9 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli #if 0 /* Not needed for 'fan' loops. */ float(*lnor)[3] = data->lnor; #endif - const MLoop *ml_curr = data->ml_curr; - const MLoop *ml_prev = data->ml_prev; const int ml_curr_index = data->ml_curr_index; const int ml_prev_index = data->ml_prev_index; const int mp_index = data->mp_index; - const int *e2l_prev = data->e2l_prev; BLI_Stack *edge_vectors = data->edge_vectors; @@ -1085,11 +1078,11 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli * same as the vertex normal, but I do not see any easy way to detect that (would need to count * number of sharp edges per vertex, I doubt the additional memory usage would be worth it, * especially as it should not be a common case in real-life meshes anyway). */ - const uint mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */ + const uint mv_pivot_index = loops[ml_curr_index].v; /* The vertex we are "fanning" around! */ const MVert *mv_pivot = &verts[mv_pivot_index]; - /* `ml_curr` would be mlfan_prev if we needed that one. */ - const MEdge *me_org = &edges[ml_curr->e]; + /* `ml_curr_index` would be mlfan_prev if we needed that one. */ + const MEdge *me_org = &edges[loops[ml_curr_index].e]; float vec_curr[3], vec_prev[3], vec_org[3]; float lnor[3] = {0.0f, 0.0f, 0.0f}; @@ -1105,8 +1098,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli /* Temp clnors stack. */ BLI_SMALLSTACK_DECLARE(clnors, short *); - const int *e2lfan_curr = e2l_prev; - const MLoop *mlfan_curr = ml_prev; + const MLoop *mlfan_curr = &loops[ml_prev_index]; /* `mlfan_vert_index` the loop of our current edge might not be the loop of our current vertex! */ int mlfan_curr_index = ml_prev_index; @@ -1133,7 +1125,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli // printf("FAN: vert %d, start edge %d\n", mv_pivot_index, ml_curr->e); while (true) { - const MEdge *me_curr = &edges[mlfan_curr->e]; + const MEdge *me_curr = &edges[loops[mlfan_curr_index].e]; /* Compute edge vectors. * NOTE: We could pre-compute those into an array, in the first iteration, instead of computing * them twice (or more) here. However, time gained is not worth memory and time lost, @@ -1147,7 +1139,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli normalize_v3(vec_curr); } - // printf("\thandling edge %d / loop %d\n", mlfan_curr->e, mlfan_curr_index); + // printf("\thandling edge %d / loop %d\n", loops[mlfan_curr_index].e, mlfan_curr_index); { /* Code similar to accumulate_vertex_normals_poly_v3. */ @@ -1185,7 +1177,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli } } - if (IS_EDGE_SHARP(e2lfan_curr) || (me_curr == me_org)) { + if (IS_EDGE_SHARP(edge_to_loops[loops[mlfan_curr_index].e]) || (me_curr == me_org)) { /* Current edge is sharp and we have finished with this fan of faces around this vert, * or this vert is smooth, and we have completed a full turn around it. */ // printf("FAN: Finished!\n"); @@ -1198,14 +1190,12 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli loop_manifold_fan_around_vert_next(loops, polys, loop_to_poly, - e2lfan_curr, + edge_to_loops[loops[mlfan_curr_index].e], mv_pivot_index, &mlfan_curr, &mlfan_curr_index, &mlfan_vert_index, &mpfan_curr_index); - - e2lfan_curr = edge_to_loops[mlfan_curr->e]; } { @@ -1312,13 +1302,11 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const Span mloop const Span loop_to_poly, const int *e2l_prev, BitVector<> &skip_loops, - const MLoop *ml_curr, - const MLoop *ml_prev, const int ml_curr_index, const int ml_prev_index, const int mp_curr_index) { - const uint mv_pivot_index = ml_curr->v; /* The vertex we are "fanning" around! */ + const uint mv_pivot_index = mloops[ml_curr_index].v; /* The vertex we are "fanning" around! */ const int *e2lfan_curr = e2l_prev; if (IS_EDGE_SHARP(e2lfan_curr)) { @@ -1328,7 +1316,7 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const Span mloop /* `mlfan_vert_index` the loop of our current edge might not be the loop of our current vertex! */ - const MLoop *mlfan_curr = ml_prev; + const MLoop *mlfan_curr = &mloops[ml_prev_index]; int mlfan_curr_index = ml_prev_index; int mlfan_vert_index = ml_curr_index; int mpfan_curr_index = mp_curr_index; @@ -1352,7 +1340,7 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const Span mloop &mlfan_vert_index, &mpfan_curr_index); - e2lfan_curr = edge_to_loops[mlfan_curr->e]; + e2lfan_curr = edge_to_loops[mloops[mlfan_curr_index].e]; if (IS_EDGE_SHARP(e2lfan_curr)) { /* Sharp loop/edge, so not a cyclic smooth fan. */ @@ -1362,7 +1350,7 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const Span mloop if (skip_loops[mlfan_vert_index]) { if (mlfan_vert_index == ml_curr_index) { /* We walked around a whole cyclic smooth fan without finding any already-processed loop, - * means we can use initial `ml_curr` / `ml_prev` edge as start for this smooth fan. */ + * means we can use initial current / previous edge as start for this smooth fan. */ return true; } /* Already checked in some previous looping, we can abort. */ @@ -1376,6 +1364,8 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const Span mloop static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common_data) { + using namespace blender; + using namespace blender::bke; MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr; const Span loops = common_data->loops; @@ -1407,23 +1397,16 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common */ for (const int mp_index : polys.index_range()) { const MPoly &poly = polys[mp_index]; - const int ml_last_index = (poly.loopstart + poly.totloop) - 1; - int ml_curr_index = poly.loopstart; - int ml_prev_index = ml_last_index; - const MLoop *ml_curr = &loops[ml_curr_index]; - const MLoop *ml_prev = &loops[ml_prev_index]; - - for (; ml_curr_index <= ml_last_index; ml_curr++, ml_curr_index++) { - const int *e2l_curr = edge_to_loops[ml_curr->e]; - const int *e2l_prev = edge_to_loops[ml_prev->e]; + for (const int ml_curr_index : IndexRange(poly.loopstart, poly.totloop)) { + const int ml_prev_index = mesh_topology::previous_poly_loop(poly, ml_curr_index); #if 0 printf("Checking loop %d / edge %u / vert %u (sharp edge: %d, skiploop: %d)", ml_curr_index, - ml_curr->e, - ml_curr->v, - IS_EDGE_SHARP(e2l_curr), + loops[ml_curr_index].e, + loops[ml_curr_index].v, + IS_EDGE_SHARP(edge_to_loops[loops[ml_curr_index].e]), skip_loops[ml_curr_index]); #endif @@ -1437,18 +1420,17 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common * However, this would complicate the code, add more memory usage, and despite its logical * complexity, #loop_manifold_fan_around_vert_next() is quite cheap in term of CPU cycles, * so really think it's not worth it. */ - if (!IS_EDGE_SHARP(e2l_curr) && (skip_loops[ml_curr_index] || - !loop_split_generator_check_cyclic_smooth_fan(loops, - polys, - edge_to_loops, - loop_to_poly, - e2l_prev, - skip_loops, - ml_curr, - ml_prev, - ml_curr_index, - ml_prev_index, - mp_index))) { + if (!IS_EDGE_SHARP(edge_to_loops[loops[ml_curr_index].e]) && + (skip_loops[ml_curr_index] || + !loop_split_generator_check_cyclic_smooth_fan(loops, + polys, + edge_to_loops, + loop_to_poly, + edge_to_loops[loops[ml_prev_index].e], + skip_loops, + ml_curr_index, + ml_prev_index, + mp_index))) { // printf("SKIPPING!\n"); } else { @@ -1468,12 +1450,13 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common memset(data, 0, sizeof(*data)); } - if (IS_EDGE_SHARP(e2l_curr) && IS_EDGE_SHARP(e2l_prev)) { - data->ml_curr = ml_curr; - data->ml_prev = ml_prev; + if (IS_EDGE_SHARP(edge_to_loops[loops[ml_curr_index].e]) && + IS_EDGE_SHARP(edge_to_loops[loops[ml_prev_index].e])) { + data->ml_curr = &loops[ml_curr_index]; + data->ml_prev = &loops[ml_prev_index]; data->ml_curr_index = ml_curr_index; -#if 0 /* Not needed for 'single' loop. */ data->ml_prev_index = ml_prev_index; +#if 0 /* Not needed for 'single' loop. */ data->e2l_prev = nullptr; /* Tag as 'single' task. */ #endif data->mp_index = mp_index; @@ -1491,11 +1474,11 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common * All this due/thanks to link between normals and loop ordering (i.e. winding). */ else { - data->ml_curr = ml_curr; - data->ml_prev = ml_prev; + data->ml_curr = &loops[ml_curr_index]; + data->ml_prev = &loops[ml_prev_index]; data->ml_curr_index = ml_curr_index; data->ml_prev_index = ml_prev_index; - data->e2l_prev = e2l_prev; /* Also tag as 'fan' task. */ + data->e2l_prev = edge_to_loops[loops[ml_prev_index].e]; /* Also tag as 'fan' task. */ data->mp_index = mp_index; if (lnors_spacearr) { data->lnor_space = BKE_lnor_space_create(lnors_spacearr); @@ -1513,9 +1496,6 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common loop_split_worker_do(common_data, data, edge_vectors); } } - - ml_prev = ml_curr; - ml_prev_index = ml_curr_index; } } From f06d7c98db8e7c3772602c4dbad332c02844dca2 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 11 Dec 2022 21:48:52 -0600 Subject: [PATCH 0009/1522] Cleanup: Remove unnecessary MLoop argument The loop was also retrievable with the index. This needed some care though, because previously the index became "detached" from the corresponding MLoop pointer for a short time. --- source/blender/blenkernel/intern/mesh_normals.cc | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index cd279484e6e..212c3342bef 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -951,11 +951,13 @@ static void loop_manifold_fan_around_vert_next(const Span loops, const Span loop_to_poly, const int *e2lfan_curr, const uint mv_pivot_index, - const MLoop **r_mlfan_curr, int *r_mlfan_curr_index, int *r_mlfan_vert_index, int *r_mpfan_curr_index) { + const int mlfan_curr_orig = *r_mlfan_curr_index; + const uint vert_fan_orig = loops[mlfan_curr_orig].v; + /* WARNING: This is rather complex! * We have to find our next edge around the vertex (fan mode). * First we find the next loop, which is either previous or next to mlfan_curr_index, depending @@ -969,10 +971,10 @@ static void loop_manifold_fan_around_vert_next(const Span loops, BLI_assert(*r_mlfan_curr_index >= 0); BLI_assert(*r_mpfan_curr_index >= 0); - const MLoop &mlfan_next = loops[*r_mlfan_curr_index]; + const uint vert_fan_next = loops[*r_mlfan_curr_index].v; const MPoly &mpfan_next = polys[*r_mpfan_curr_index]; - if (((*r_mlfan_curr)->v == mlfan_next.v && (*r_mlfan_curr)->v == mv_pivot_index) || - ((*r_mlfan_curr)->v != mlfan_next.v && (*r_mlfan_curr)->v != mv_pivot_index)) { + if ((vert_fan_orig == vert_fan_next && vert_fan_orig == mv_pivot_index) || + (vert_fan_orig != vert_fan_next && vert_fan_orig != mv_pivot_index)) { /* We need the previous loop, but current one is our vertex's loop. */ *r_mlfan_vert_index = *r_mlfan_curr_index; if (--(*r_mlfan_curr_index) < mpfan_next.loopstart) { @@ -986,8 +988,6 @@ static void loop_manifold_fan_around_vert_next(const Span loops, } *r_mlfan_vert_index = *r_mlfan_curr_index; } - *r_mlfan_curr = &loops[*r_mlfan_curr_index]; - /* And now we are back in sync, mlfan_curr_index is the index of `mlfan_curr`! Pff! */ } static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data) @@ -1098,7 +1098,6 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli /* Temp clnors stack. */ BLI_SMALLSTACK_DECLARE(clnors, short *); - const MLoop *mlfan_curr = &loops[ml_prev_index]; /* `mlfan_vert_index` the loop of our current edge might not be the loop of our current vertex! */ int mlfan_curr_index = ml_prev_index; @@ -1192,7 +1191,6 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli loop_to_poly, edge_to_loops[loops[mlfan_curr_index].e], mv_pivot_index, - &mlfan_curr, &mlfan_curr_index, &mlfan_vert_index, &mpfan_curr_index); @@ -1316,7 +1314,6 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const Span mloop /* `mlfan_vert_index` the loop of our current edge might not be the loop of our current vertex! */ - const MLoop *mlfan_curr = &mloops[ml_prev_index]; int mlfan_curr_index = ml_prev_index; int mlfan_vert_index = ml_curr_index; int mpfan_curr_index = mp_curr_index; @@ -1335,7 +1332,6 @@ static bool loop_split_generator_check_cyclic_smooth_fan(const Span mloop loop_to_poly, e2lfan_curr, mv_pivot_index, - &mlfan_curr, &mlfan_curr_index, &mlfan_vert_index, &mpfan_curr_index); From 9e9ebcdd728dfee01335f2d224d60e31140951f5 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 11 Dec 2022 22:47:46 -0600 Subject: [PATCH 0010/1522] Mesh: Reduce memory consumption when calculating corner normals Similar to previous commits, avoid using pointers that are redundant to their corresponding index. Also avoid storing the edge vectors stack in the data-per-loop when it can just be a function argument. Face corner normals are calculated when auto smooth or custom per-corner normals are used. This brings the per-face-corner data from 64 to 24 bytes, as measured by `sizeof`. In a large test file I observed a 20% performance improvement, from 285 to 239 ms. --- .../blender/blenkernel/intern/mesh_normals.cc | 45 +++++++------------ 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index 212c3342bef..e1ac8d5cca0 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -27,6 +27,7 @@ #include "BLI_stack.h" #include "BLI_task.h" #include "BLI_task.hh" +#include "BLI_timeit.hh" #include "BLI_utildefines.h" #include "BKE_customdata.h" @@ -792,23 +793,20 @@ void BKE_lnor_space_custom_normal_to_data(const MLoopNorSpace *lnor_space, #define LOOP_SPLIT_TASK_BLOCK_SIZE 1024 struct LoopSplitTaskData { - /* Specific to each instance (each task). */ + enum class Type : int8_t { + BlockEnd = 0, /* Set implicitly by calloc. */ + Fan = 1, + Single = 2, + }; /** We have to create those outside of tasks, since #MemArena is not thread-safe. */ MLoopNorSpace *lnor_space; - const MLoop *ml_curr; - const MLoop *ml_prev; int ml_curr_index; - int ml_prev_index; /** Also used a flag to switch between single or fan process! */ - const int *e2l_prev; + int ml_prev_index; int mp_index; - /** This one is special, it's owned and managed by worker tasks, - * avoid to have to create it for each fan! */ - BLI_Stack *edge_vectors; - - char pad_c; + Type flag; }; struct LoopSplitTaskDataCommon { @@ -1048,7 +1046,9 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS } } -static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data) +static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, + LoopSplitTaskData *data, + BLI_Stack *edge_vectors) { MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr; MutableSpan loopnors = common_data->loopnors; @@ -1070,8 +1070,6 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, LoopSpli const int ml_prev_index = data->ml_prev_index; const int mp_index = data->mp_index; - BLI_Stack *edge_vectors = data->edge_vectors; - /* Sigh! we have to fan around current vertex, until we find the other non-smooth edge, * and accumulate face normals into the vertex! * Note in case this vertex has only one sharp edges, this is a waste because the normal is the @@ -1253,11 +1251,9 @@ static void loop_split_worker_do(LoopSplitTaskDataCommon *common_data, LoopSplitTaskData *data, BLI_Stack *edge_vectors) { - BLI_assert(data->ml_curr); - if (data->e2l_prev) { + if (data->flag == LoopSplitTaskData::Type::Fan) { BLI_assert((edge_vectors == nullptr) || BLI_stack_is_empty(edge_vectors)); - data->edge_vectors = edge_vectors; - split_loop_nor_fan_do(common_data, data); + split_loop_nor_fan_do(common_data, data, edge_vectors); } else { /* No need for edge_vectors for 'single' case! */ @@ -1276,8 +1272,7 @@ static void loop_split_worker(TaskPool *__restrict pool, void *taskdata) nullptr; for (int i = 0; i < LOOP_SPLIT_TASK_BLOCK_SIZE; i++, data++) { - /* A nullptr ml_curr is used to tag ended data! */ - if (data->ml_curr == nullptr) { + if (data->flag == LoopSplitTaskData::Type::BlockEnd) { break; } @@ -1448,13 +1443,9 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common if (IS_EDGE_SHARP(edge_to_loops[loops[ml_curr_index].e]) && IS_EDGE_SHARP(edge_to_loops[loops[ml_prev_index].e])) { - data->ml_curr = &loops[ml_curr_index]; - data->ml_prev = &loops[ml_prev_index]; data->ml_curr_index = ml_curr_index; data->ml_prev_index = ml_prev_index; -#if 0 /* Not needed for 'single' loop. */ - data->e2l_prev = nullptr; /* Tag as 'single' task. */ -#endif + data->flag = LoopSplitTaskData::Type::Single; data->mp_index = mp_index; if (lnors_spacearr) { data->lnor_space = BKE_lnor_space_create(lnors_spacearr); @@ -1470,11 +1461,9 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common * All this due/thanks to link between normals and loop ordering (i.e. winding). */ else { - data->ml_curr = &loops[ml_curr_index]; - data->ml_prev = &loops[ml_prev_index]; data->ml_curr_index = ml_curr_index; data->ml_prev_index = ml_prev_index; - data->e2l_prev = edge_to_loops[loops[ml_prev_index].e]; /* Also tag as 'fan' task. */ + data->flag = LoopSplitTaskData::Type::Fan; data->mp_index = mp_index; if (lnors_spacearr) { data->lnor_space = BKE_lnor_space_create(lnors_spacearr); @@ -1495,8 +1484,6 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common } } - /* Last block of data. Since it is calloc'ed and we use first nullptr item as stopper, - * everything is fine. */ if (pool && data_idx) { BLI_task_pool_push(pool, loop_split_worker, data_buff, true, nullptr); } From 2bb47e03f780ee758b9dfc4e15d75f9f1353e912 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 11 Dec 2022 23:08:54 -0600 Subject: [PATCH 0011/1522] Cleanup: Use Span instead of MutableSpan for normals array --- source/blender/blenkernel/intern/mesh_normals.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index e1ac8d5cca0..f568111f2e0 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -822,7 +822,7 @@ struct LoopSplitTaskDataCommon { Span edges; Span loops; Span polys; - MutableSpan edge_to_loops; + Span edge_to_loops; Span loop_to_poly; Span polynors; Span vert_normals; From 8c11c0444891d5bc8f654e42b0f24f6337a77561 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 11 Dec 2022 23:14:01 -0600 Subject: [PATCH 0012/1522] Cleanup: Rename adjacent mesh loop accessors But the common, more important part of the function names at the beginning, to make them easier to find and more consistent. --- source/blender/blenkernel/BKE_mesh_mapping.h | 4 ++-- source/blender/blenkernel/intern/geometry_component_mesh.cc | 4 ++-- source/blender/blenkernel/intern/mesh_normals.cc | 2 +- source/blender/nodes/geometry/nodes/node_geo_edge_split.cc | 4 ++-- .../geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h index e218ee72694..b49d61ac0a8 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.h +++ b/source/blender/blenkernel/BKE_mesh_mapping.h @@ -356,12 +356,12 @@ Array> build_vert_to_loop_map(Span loops, int verts_num); Array> build_edge_to_loop_map(Span loops, int edges_num); Vector> build_edge_to_loop_map_resizable(Span loops, int edges_num); -inline int previous_poly_loop(const MPoly &poly, int loop_i) +inline int poly_loop_prev(const MPoly &poly, int loop_i) { return loop_i - 1 + (loop_i == poly.loopstart) * poly.totloop; } -inline int next_poly_loop(const MPoly &poly, int loop_i) +inline int poly_loop_next(const MPoly &poly, int loop_i) { if (loop_i == poly.loopstart + poly.totloop - 1) { return poly.loopstart; diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index c30426a8d98..87ddb76171e 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -618,7 +618,7 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh, /* For every corner, mix the values from the adjacent edges on the face. */ for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const int loop_index_prev = mesh_topology::previous_poly_loop(poly, loop_index); + const int loop_index_prev = mesh_topology::poly_loop_prev(poly, loop_index); const MLoop &loop = loops[loop_index]; const MLoop &loop_prev = loops[loop_index_prev]; mixer.mix_in(loop_index, old_values[loop.e]); @@ -645,7 +645,7 @@ void adapt_mesh_domain_edge_to_corner_impl(const Mesh &mesh, for (const int poly_index : range) { const MPoly &poly = polys[poly_index]; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { - const int loop_index_prev = mesh_topology::previous_poly_loop(poly, loop_index); + const int loop_index_prev = mesh_topology::poly_loop_prev(poly, loop_index); const MLoop &loop = loops[loop_index]; const MLoop &loop_prev = loops[loop_index_prev]; if (old_values[loop.e] && old_values[loop_prev.e]) { diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index f568111f2e0..b93892b639f 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -1390,7 +1390,7 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common const MPoly &poly = polys[mp_index]; for (const int ml_curr_index : IndexRange(poly.loopstart, poly.totloop)) { - const int ml_prev_index = mesh_topology::previous_poly_loop(poly, ml_curr_index); + const int ml_prev_index = mesh_topology::poly_loop_prev(poly, ml_curr_index); #if 0 printf("Checking loop %d / edge %u / vert %u (sharp edge: %d, skiploop: %d)", diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc index f44ab44aacd..30c3e710432 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc @@ -251,8 +251,8 @@ static void split_vertex_per_fan(const int vertex, static int adjacent_edge(Span loops, const int loop_i, const MPoly &poly, const int vertex) { const int adjacent_loop_i = (loops[loop_i].v == vertex) ? - bke::mesh_topology::previous_poly_loop(poly, loop_i) : - bke::mesh_topology::next_poly_loop(poly, loop_i); + bke::mesh_topology::poly_loop_prev(poly, loop_i) : + bke::mesh_topology::poly_loop_next(poly, loop_i); return loops[adjacent_loop_i].e; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc index e46061e0d65..08085d2619a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc @@ -88,7 +88,7 @@ class CornerPreviousEdgeFieldInput final : public bke::MeshFieldInput { [polys, loops, loop_to_poly_map = std::move(loop_to_poly_map)](const int corner_i) { const int poly_i = loop_to_poly_map[corner_i]; const MPoly &poly = polys[poly_i]; - const int corner_i_prev = bke::mesh_topology::previous_poly_loop(poly, corner_i); + const int corner_i_prev = bke::mesh_topology::poly_loop_prev(poly, corner_i); return loops[corner_i_prev].e; }); } From 40bc5aa7e568ad66c52b34712f02ebceaa6572f2 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 11 Dec 2022 23:28:01 -0600 Subject: [PATCH 0013/1522] Cleanup: Comment formatting in normal calculation But it below the `else` case to make the control flow clearer, since in the end that is more important. Also clarify the wording and fix grammar slightly. --- source/blender/blenkernel/intern/mesh_normals.cc | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index b93892b639f..5a15c54df9e 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -1451,16 +1451,14 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common data->lnor_space = BKE_lnor_space_create(lnors_spacearr); } } - /* We *do not need* to check/tag loops as already computed! - * Due to the fact a loop only links to one of its two edges, - * a same fan *will never be walked more than once!* - * Since we consider edges having neighbor polys with inverted - * (flipped) normals as sharp, we are sure that no fan will be skipped, - * even only considering the case (sharp curr_edge, smooth prev_edge), - * and not the alternative (smooth curr_edge, sharp prev_edge). - * All this due/thanks to link between normals and loop ordering (i.e. winding). - */ else { + /* We do not need to check/tag loops as already computed. Due to the fact that a loop + * only points to one of its two edges, the same fan will never be walked more than once. + * Since we consider edges that have neighbor polys with inverted (flipped) normals as + * sharp, we are sure that no fan will be skipped, even only considering the case (sharp + * current edge, smooth previous edge), and not the alternative (smooth current edge, + * sharp previous edge). All this due/thanks to the link between normals and loop + * ordering (i.e. winding). */ data->ml_curr_index = ml_curr_index; data->ml_prev_index = ml_prev_index; data->flag = LoopSplitTaskData::Type::Fan; From 719513dd9fe40a8efb12d847ed6ac3bfc6167261 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 12 Dec 2022 12:13:33 +0100 Subject: [PATCH 0014/1522] Tests: make mesh comparisons more strict Previously, it wouldn't detect the case when one mesh had an attribute that the other one did not. Not sure if this always was the case or whether this less strict test was implemented accidentally at some point. --- source/blender/blenkernel/intern/mesh.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index f59cd4f3a7c..1fafec810ba 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -500,14 +500,19 @@ static int customdata_compare( for (int i1 = 0; i1 < c1->totlayer; i1++) { l1 = c1->layers + i1; + if (l1->anonymous_id != nullptr) { + continue; + } + bool found_corresponding_layer = false; for (int i2 = 0; i2 < c2->totlayer; i2++) { l2 = c2->layers + i2; - if (l1->type != l2->type || !STREQ(l1->name, l2->name) || l1->anonymous_id != nullptr || - l2->anonymous_id != nullptr) { + if (l1->type != l2->type || !STREQ(l1->name, l2->name) || l2->anonymous_id != nullptr) { continue; } /* At this point `l1` and `l2` have the same name and type, so they should be compared. */ + found_corresponding_layer = true; + switch (l1->type) { case CD_MVERT: { @@ -719,6 +724,11 @@ static int customdata_compare( } } } + if (!found_corresponding_layer) { + if ((1 << l1->type) & CD_MASK_PROP_ALL) { + return MESHCMP_CDLAYERS_MISMATCH; + } + } } return 0; From 9c0d822737ff9bfca05424667ead642581325733 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 12 Dec 2022 12:22:38 +0100 Subject: [PATCH 0015/1522] GPU: Compile vulkan shaders to Spir-V binaries. Compile each static shader using shaderc to Spir-V binaries. The main goal is to make sure that the GLSL created using ShaderCreateInfo and able to compile to Spir-V. For the second stage a correct pipeline needs to be created and some shader would need more adjustments (push constants size). With this patch future changes to GLSL sources can already be checked against vulkan, without the backend finished. Mechanism has been tested using MacOS and MoltenVK. For other OS, we should finetune CMake files to find the right location to shaderc. ``` ************************************************************ *** Build Mon 12 Dec 2022 11:08:07 CET ************************************************************ Shader Test compilation result: 463 / 463 passed (skipped 118 for compatibility reasons) OpenGL backend shader compilation succeeded. Shader Test compilation result: 529 / 529 passed (skipped 52 for compatibility reasons) Vulkan backend shader compilation succeeded. ``` Reviewed By: fclem Maniphest Tasks: T102760 Differential Revision: https://developer.blender.org/D16610 --- .../cmake/platform/platform_apple.cmake | 3 +- .../compositor_screen_lens_distortion.glsl | 4 +- ...u_shader_compositor_texture_utilities.glsl | 26 +- .../draw/engines/eevee_next/eevee_defines.hh | 4 +- ...vee_depth_of_field_tiles_flatten_comp.glsl | 2 +- .../overlay_motion_path_line_vert.glsl | 16 +- .../shaders/workbench_shadow_vert.glsl | 3 +- .../draw/intern/shaders/common_smaa_lib.glsl | 24 +- .../draw/intern/shaders/common_view_lib.glsl | 24 +- source/blender/gpu/CMakeLists.txt | 4 + source/blender/gpu/intern/gpu_shader.cc | 3 + .../blender/gpu/intern/gpu_shader_builder.cc | 12 + .../gpu_shader_cfg_world_clip_lib.glsl | 43 +- source/blender/gpu/vulkan/vk_backend.cc | 15 + source/blender/gpu/vulkan/vk_backend.hh | 16 + source/blender/gpu/vulkan/vk_context.cc | 4 + source/blender/gpu/vulkan/vk_context.hh | 10 + source/blender/gpu/vulkan/vk_shader.cc | 875 +++++++++++++++++- source/blender/gpu/vulkan/vk_shader.hh | 26 +- source/blender/gpu/vulkan/vk_shader_log.cc | 44 + source/blender/gpu/vulkan/vk_shader_log.hh | 16 + 21 files changed, 1094 insertions(+), 80 deletions(-) create mode 100644 source/blender/gpu/vulkan/vk_shader_log.cc create mode 100644 source/blender/gpu/vulkan/vk_shader_log.hh diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index 7a39e6ffda3..b2101662969 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -105,9 +105,10 @@ if(WITH_VULKAN_BACKEND) set(VULKAN_ROOT_DIR ${LIBDIR}/vulkan/macOS) set(VULKAN_INCLUDE_DIR ${VULKAN_ROOT_DIR}/include) set(VULKAN_LIBRARY ${VULKAN_ROOT_DIR}/lib/libvulkan.1.dylib) + set(SHADERC_LIBRARY ${VULKAN_ROOT_DIR}/lib/libshaderc_combined.a) set(VULKAN_INCLUDE_DIRS ${VULKAN_INCLUDE_DIR} ${MOLTENVK_INCLUDE_DIRS}) - set(VULKAN_LIBRARIES ${VULKAN_LIBRARY} ${MOLTENVK_LIBRARIES}) + set(VULKAN_LIBRARIES ${VULKAN_LIBRARY} ${SHADERC_LIBRARY} ${MOLTENVK_LIBRARIES}) else() message(WARNING "Vulkan SDK was not found, disabling WITH_VULKAN_BACKEND") set(WITH_VULKAN_BACKEND OFF) diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl index dc572ea5aaf..58c1d97e81d 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl @@ -20,9 +20,9 @@ vec3 compute_chromatic_distortion_scale(float distance_squared) /* Compute the image coordinates after distortion by the given distortion scale computed by the * compute_distortion_scale function. Note that the function expects centered normalized UV * coordinates but outputs non-centered image coordinates. */ -vec2 compute_distorted_uv(vec2 uv, float scale) +vec2 compute_distorted_uv(vec2 uv, float uv_scale) { - return (uv * scale + 0.5) * texture_size(input_tx) - 0.5; + return (uv * uv_scale + 0.5) * texture_size(input_tx) - 0.5; } /* Compute the number of integration steps that should be used to approximate the distorted pixel diff --git a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl index 128fc6aeaf5..cd99e16add6 100644 --- a/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/library/gpu_shader_compositor_texture_utilities.glsl @@ -1,35 +1,35 @@ /* A shorthand for 1D textureSize with a zero LOD. */ -int texture_size(sampler1D sampler) +int texture_size(sampler1D sampler_1d) { - return textureSize(sampler, 0); + return textureSize(sampler_1d, 0); } /* A shorthand for 1D texelFetch with zero LOD and bounded access clamped to border. */ -vec4 texture_load(sampler1D sampler, int x) +vec4 texture_load(sampler1D sampler_1d, int x) { - const int texture_bound = texture_size(sampler) - 1; - return texelFetch(sampler, clamp(x, 0, texture_bound), 0); + const int texture_bound = texture_size(sampler_1d) - 1; + return texelFetch(sampler_1d, clamp(x, 0, texture_bound), 0); } /* A shorthand for 2D textureSize with a zero LOD. */ -ivec2 texture_size(sampler2D sampler) +ivec2 texture_size(sampler2D sampler_2d) { - return textureSize(sampler, 0); + return textureSize(sampler_2d, 0); } /* A shorthand for 2D texelFetch with zero LOD and bounded access clamped to border. */ -vec4 texture_load(sampler2D sampler, ivec2 texel) +vec4 texture_load(sampler2D sampler_2d, ivec2 texel) { - const ivec2 texture_bounds = texture_size(sampler) - ivec2(1); - return texelFetch(sampler, clamp(texel, ivec2(0), texture_bounds), 0); + const ivec2 texture_bounds = texture_size(sampler_2d) - ivec2(1); + return texelFetch(sampler_2d, clamp(texel, ivec2(0), texture_bounds), 0); } /* A shorthand for 2D texelFetch with zero LOD and a fallback value for out-of-bound access. */ -vec4 texture_load(sampler2D sampler, ivec2 texel, vec4 fallback) +vec4 texture_load(sampler2D sampler_2d, ivec2 texel, vec4 fallback) { - const ivec2 texture_bounds = texture_size(sampler) - ivec2(1); + const ivec2 texture_bounds = texture_size(sampler_2d) - ivec2(1); if (any(lessThan(texel, ivec2(0))) || any(greaterThan(texel, texture_bounds))) { return fallback; } - return texelFetch(sampler, texel, 0); + return texelFetch(sampler_2d, texel, 0); } diff --git a/source/blender/draw/engines/eevee_next/eevee_defines.hh b/source/blender/draw/engines/eevee_next/eevee_defines.hh index fca8737f661..55d3921e39b 100644 --- a/source/blender/draw/engines/eevee_next/eevee_defines.hh +++ b/source/blender/draw/engines/eevee_next/eevee_defines.hh @@ -9,7 +9,9 @@ * dragging larger headers into the createInfo pipeline which would cause problems. */ -#pragma once +#ifndef GPU_SHADER +# pragma once +#endif /* Hierarchical Z down-sampling. */ #define HIZ_MIP_COUNT 8 diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_tiles_flatten_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_tiles_flatten_comp.glsl index 88737ade386..33aefb7f76d 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_tiles_flatten_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_tiles_flatten_comp.glsl @@ -26,7 +26,7 @@ shared uint bg_min_coc; shared uint bg_max_coc; shared uint bg_min_intersectable_coc; -const uint dof_tile_large_coc_uint = floatBitsToUint(dof_tile_large_coc); +uint dof_tile_large_coc_uint = floatBitsToUint(dof_tile_large_coc); void main() { diff --git a/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert.glsl index 50c24de0838..331dcdf6519 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_line_vert.glsl @@ -13,8 +13,12 @@ vec2 proj(vec4 pos) return (0.5 * (pos.xy / pos.w) + 0.5) * sizeViewport.xy; } -#define SET_INTENSITY(A, B, C, min, max) \ - (((1.0 - (float(C - B) / float(C - A))) * (max - min)) + min) +float calc_intensity(int segment_start, int segment_current, int segment_end, float min, float max) +{ + return ((1.0 - (float(segment_end - segment_current) / float(segment_end - segment_start))) * + (max - min)) + + min; +} void main() { @@ -39,10 +43,10 @@ void main() else { /* black - before frameCurrent */ if (selected) { - intensity = SET_INTENSITY(frameStart, frame, frameCurrent, 0.25, 0.75); + intensity = calc_intensity(frameStart, frame, frameCurrent, 0.25, 0.75); } else { - intensity = SET_INTENSITY(frameStart, frame, frameCurrent, 0.68, 0.92); + intensity = calc_intensity(frameStart, frame, frameCurrent, 0.68, 0.92); } interp.color.rgb = mix(colorWire.rgb, blend_base, intensity); } @@ -55,10 +59,10 @@ void main() else { /* blue - after frameCurrent */ if (selected) { - intensity = SET_INTENSITY(frameCurrent, frame, frameEnd, 0.25, 0.75); + intensity = calc_intensity(frameCurrent, frame, frameEnd, 0.25, 0.75); } else { - intensity = SET_INTENSITY(frameCurrent, frame, frameEnd, 0.68, 0.92); + intensity = calc_intensity(frameCurrent, frame, frameEnd, 0.68, 0.92); } interp.color.rgb = mix(colorBonePose.rgb, blend_base, intensity); diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl index a220434ec45..fa4d5ef4d96 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl @@ -5,5 +5,6 @@ void main() { vData.pos = pos; vData.frontPosition = point_object_to_ndc(pos); - vData.backPosition = point_object_to_ndc(pos + lightDirection * lightDistance); + vec3 back_pos = pos + lightDirection * lightDistance; + vData.backPosition = point_object_to_ndc(back_pos); } diff --git a/source/blender/draw/intern/shaders/common_smaa_lib.glsl b/source/blender/draw/intern/shaders/common_smaa_lib.glsl index 0c040c9acfe..1b8a8202166 100644 --- a/source/blender/draw/intern/shaders/common_smaa_lib.glsl +++ b/source/blender/draw/intern/shaders/common_smaa_lib.glsl @@ -569,7 +569,7 @@ SamplerState PointSampler # define SMAAGather(tex, coord) tex.Gather(LinearSampler, coord, 0) # endif #endif -#if defined(SMAA_GLSL_3) || defined(SMAA_GLSL_4) || defined(GPU_METAL) +#if defined(SMAA_GLSL_3) || defined(SMAA_GLSL_4) || defined(GPU_METAL) || defined(GPU_VULKAN) # define SMAATexture2D(tex) sampler2D tex # define SMAATexturePass2D(tex) tex # define SMAASampleLevelZero(tex, coord) textureLod(tex, coord, 0.0) @@ -583,8 +583,28 @@ SamplerState PointSampler # define lerp(a, b, t) mix(a, b, t) # define saturate(a) clamp(a, 0.0, 1.0) # if defined(SMAA_GLSL_4) -# define mad(a, b, c) fma(a, b, c) # define SMAAGather(tex, coord) textureGather(tex, coord) +# endif +# if defined(SMAA_GLSL_4) +# define mad(a, b, c) fma(a, b, c) +# elif defined(GPU_VULKAN) +/* NOTE(Vulkan) mad macro doesn't work, define each override as work-around. */ +vec4 mad(vec4 a, vec4 b, vec4 c) +{ + return fma(a, b, c); +} +vec3 mad(vec3 a, vec3 b, vec3 c) +{ + return fma(a, b, c); +} +vec2 mad(vec2 a, vec2 b, vec2 c) +{ + return fma(a, b, c); +} +float mad(float a, float b, float c) +{ + return fma(a, b, c); +} # else # define mad(a, b, c) (a * b + c) # endif diff --git a/source/blender/draw/intern/shaders/common_view_lib.glsl b/source/blender/draw/intern/shaders/common_view_lib.glsl index d6985f86ddc..53ef194b4f5 100644 --- a/source/blender/draw/intern/shaders/common_view_lib.glsl +++ b/source/blender/draw/intern/shaders/common_view_lib.glsl @@ -234,12 +234,28 @@ uniform mat4 ModelMatrixInverse; (ProjectionMatrix * (ViewMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0))) #define point_object_to_view(p) ((ViewMatrix * vec4((ModelMatrix * vec4(p, 1.0)).xyz, 1.0)).xyz) #define point_object_to_world(p) ((ModelMatrix * vec4(p, 1.0)).xyz) -#define point_view_to_ndc(p) (ProjectionMatrix * vec4(p, 1.0)) #define point_view_to_object(p) ((ModelMatrixInverse * (ViewMatrixInverse * vec4(p, 1.0))).xyz) -#define point_view_to_world(p) ((ViewMatrixInverse * vec4(p, 1.0)).xyz) -#define point_world_to_ndc(p) (ProjectionMatrix * (ViewMatrix * vec4(p, 1.0))) #define point_world_to_object(p) ((ModelMatrixInverse * vec4(p, 1.0)).xyz) -#define point_world_to_view(p) ((ViewMatrix * vec4(p, 1.0)).xyz) + +vec4 point_view_to_ndc(vec3 p) +{ + return ProjectionMatrix * vec4(p, 1.0); +} + +vec3 point_view_to_world(vec3 p) +{ + return (ViewMatrixInverse * vec4(p, 1.0)).xyz; +} + +vec4 point_world_to_ndc(vec3 p) +{ + return ProjectionMatrix * (ViewMatrix * vec4(p, 1.0)); +} + +vec3 point_world_to_view(vec3 p) +{ + return (ViewMatrix * vec4(p, 1.0)).xyz; +} /* Due to some shader compiler bug, we somewhat need to access gl_VertexID * to make vertex shaders work. even if it's actually dead code. */ diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 86a38c02efc..9f9d216064a 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -43,6 +43,7 @@ set(INC set(INC_SYS ${Epoxy_INCLUDE_DIRS} + ${VULKAN_INCLUDE_DIRS} ) set(SRC @@ -197,6 +198,7 @@ set(VULKAN_SRC vulkan/vk_pixel_buffer.cc vulkan/vk_query.cc vulkan/vk_shader.cc + vulkan/vk_shader_log.cc vulkan/vk_storage_buffer.cc vulkan/vk_texture.cc vulkan/vk_uniform_buffer.cc @@ -212,6 +214,7 @@ set(VULKAN_SRC vulkan/vk_pixel_buffer.hh vulkan/vk_query.hh vulkan/vk_shader.hh + vulkan/vk_shader_log.hh vulkan/vk_storage_buffer.hh vulkan/vk_texture.hh vulkan/vk_uniform_buffer.hh @@ -275,6 +278,7 @@ endif() set(LIB ${Epoxy_LIBRARIES} + ${VULKAN_LIBRARIES} ) if(WITH_VULKAN_BACKEND) diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index 7f2a81c8141..0653ae11a0a 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -98,6 +98,9 @@ static void standard_defines(Vector &sources) case GPU_BACKEND_METAL: sources.append("#define GPU_METAL\n"); break; + case GPU_BACKEND_VULKAN: + sources.append("#define GPU_VULKAN\n"); + break; default: BLI_assert(false && "Invalid GPU Backend Type"); break; diff --git a/source/blender/gpu/intern/gpu_shader_builder.cc b/source/blender/gpu/intern/gpu_shader_builder.cc index 96e3eacd6f5..61cf95c6d17 100644 --- a/source/blender/gpu/intern/gpu_shader_builder.cc +++ b/source/blender/gpu/intern/gpu_shader_builder.cc @@ -54,6 +54,12 @@ void ShaderBuilder::init() break; #endif +#ifdef WITH_VULKAN_BACKEND + case GPU_BACKEND_VULKAN: + glSettings.context_type = GHOST_kDrawingContextTypeVulkan; + break; +#endif + default: BLI_assert_unreachable(); break; @@ -100,6 +106,9 @@ int main(int argc, const char *argv[]) backends_to_validate.append({"OpenGL", GPU_BACKEND_OPENGL}); #ifdef WITH_METAL_BACKEND backends_to_validate.append({"Metal", GPU_BACKEND_METAL}); +#endif +#ifdef WITH_VULKAN_BACKEND + backends_to_validate.append({"Vulkan", GPU_BACKEND_VULKAN}); #endif for (NamedBackend &backend : backends_to_validate) { GPU_backend_type_selection_set(backend.backend); @@ -114,6 +123,9 @@ int main(int argc, const char *argv[]) printf("Shader compilation failed for %s backend\n", backend.name.c_str()); exit_code = 1; } + else { + printf("%s backend shader compilation succeeded.\n", backend.name.c_str()); + } builder.exit(); } diff --git a/source/blender/gpu/shaders/gpu_shader_cfg_world_clip_lib.glsl b/source/blender/gpu/shaders/gpu_shader_cfg_world_clip_lib.glsl index 3edf0e31799..35f1c7a2427 100644 --- a/source/blender/gpu/shaders/gpu_shader_cfg_world_clip_lib.glsl +++ b/source/blender/gpu/shaders/gpu_shader_cfg_world_clip_lib.glsl @@ -1,40 +1,25 @@ #ifdef USE_WORLD_CLIP_PLANES # if defined(GPU_VERTEX_SHADER) || defined(GPU_GEOMETRY_SHADER) -# ifndef USE_GPU_SHADER_CREATE_INFO -uniform vec4 WorldClipPlanes[6]; -# endif - -# define _world_clip_planes_calc_clip_distance(wpos, _clipplanes) \ - { \ - vec4 _pos = vec4(wpos, 1.0); \ - gl_ClipDistance[0] = dot(_clipplanes[0], _pos); \ - gl_ClipDistance[1] = dot(_clipplanes[1], _pos); \ - gl_ClipDistance[2] = dot(_clipplanes[2], _pos); \ - gl_ClipDistance[3] = dot(_clipplanes[3], _pos); \ - gl_ClipDistance[4] = dot(_clipplanes[4], _pos); \ - gl_ClipDistance[5] = dot(_clipplanes[5], _pos); \ - } - /* When all shaders are builtin shaders are migrated this could be applied directly. */ # ifdef USE_GPU_SHADER_CREATE_INFO # define WorldClipPlanes clipPlanes.world +# else +uniform vec4 WorldClipPlanes[6]; # endif -/* HACK Dirty hack to be able to override the definition in common_view_lib.glsl. - * Not doing this would require changing the include order in every shaders. */ -# define world_clip_planes_calc_clip_distance(wpos) \ - _world_clip_planes_calc_clip_distance(wpos, WorldClipPlanes) + +void world_clip_planes_calc_clip_distance(vec3 wpos) +{ + vec4 pos = vec4(wpos, 1.0); + + gl_ClipDistance[0] = dot(WorldClipPlanes[0], pos); + gl_ClipDistance[1] = dot(WorldClipPlanes[1], pos); + gl_ClipDistance[2] = dot(WorldClipPlanes[2], pos); + gl_ClipDistance[3] = dot(WorldClipPlanes[3], pos); + gl_ClipDistance[4] = dot(WorldClipPlanes[4], pos); + gl_ClipDistance[5] = dot(WorldClipPlanes[5], pos); +} # endif -# define world_clip_planes_set_clip_distance(c) \ - { \ - gl_ClipDistance[0] = (c)[0]; \ - gl_ClipDistance[1] = (c)[1]; \ - gl_ClipDistance[2] = (c)[2]; \ - gl_ClipDistance[3] = (c)[3]; \ - gl_ClipDistance[4] = (c)[4]; \ - gl_ClipDistance[5] = (c)[5]; \ - } - #endif diff --git a/source/blender/gpu/vulkan/vk_backend.cc b/source/blender/gpu/vulkan/vk_backend.cc index b0212012fdf..b402ef2f503 100644 --- a/source/blender/gpu/vulkan/vk_backend.cc +++ b/source/blender/gpu/vulkan/vk_backend.cc @@ -5,6 +5,7 @@ * \ingroup gpu */ +#include "gpu_capabilities_private.hh" #include "gpu_platform_private.hh" #include "vk_batch.hh" @@ -144,4 +145,18 @@ void VKBackend::render_step() { } +shaderc::Compiler &VKBackend::get_shaderc_compiler() +{ + return shaderc_compiler_; +} + +void VKBackend::capabilities_init(VKContext &context) +{ + /* Reset all capabilities from previous context. */ + GCaps = {}; + GCaps.compute_shader_support = true; + GCaps.shader_storage_buffer_objects_support = true; + GCaps.shader_image_load_store_support = true; +} + } // namespace blender::gpu \ No newline at end of file diff --git a/source/blender/gpu/vulkan/vk_backend.hh b/source/blender/gpu/vulkan/vk_backend.hh index c78788298a5..4c6312ed682 100644 --- a/source/blender/gpu/vulkan/vk_backend.hh +++ b/source/blender/gpu/vulkan/vk_backend.hh @@ -9,9 +9,21 @@ #include "gpu_backend.hh" +#ifdef __APPLE__ +# include +#else +# include +#endif +#include "shaderc/shaderc.hpp" + namespace blender::gpu { +class VKContext; + class VKBackend : public GPUBackend { + private: + shaderc::Compiler shaderc_compiler_; + public: VKBackend() { @@ -50,6 +62,10 @@ class VKBackend : public GPUBackend { void render_end() override; void render_step() override; + shaderc::Compiler &get_shaderc_compiler(); + + static void capabilities_init(VKContext &context); + private: static void init_platform(); static void platform_exit(); diff --git a/source/blender/gpu/vulkan/vk_context.cc b/source/blender/gpu/vulkan/vk_context.cc index 0bf2d29e124..6013b5eb95c 100644 --- a/source/blender/gpu/vulkan/vk_context.cc +++ b/source/blender/gpu/vulkan/vk_context.cc @@ -7,6 +7,8 @@ #include "vk_context.hh" +#include "vk_backend.hh" + #include "GHOST_C-api.h" namespace blender::gpu { @@ -32,6 +34,8 @@ VKContext::VKContext(void *ghost_window, void *ghost_context) info.device = device_; info.instance = instance_; vmaCreateAllocator(&info, &mem_allocator_); + + VKBackend::capabilities_init(*this); } VKContext::~VKContext() diff --git a/source/blender/gpu/vulkan/vk_context.hh b/source/blender/gpu/vulkan/vk_context.hh index 7c83548536d..56d39169538 100644 --- a/source/blender/gpu/vulkan/vk_context.hh +++ b/source/blender/gpu/vulkan/vk_context.hh @@ -47,6 +47,16 @@ class VKContext : public Context { void debug_group_begin(const char *, int) override; void debug_group_end() override; + static VKContext *get(void) + { + return static_cast(Context::get()); + } + + VkDevice device_get() const + { + return device_; + } + VmaAllocator mem_allocator_get() const { return mem_allocator_; diff --git a/source/blender/gpu/vulkan/vk_shader.cc b/source/blender/gpu/vulkan/vk_shader.cc index d628f3eb851..40408759679 100644 --- a/source/blender/gpu/vulkan/vk_shader.cc +++ b/source/blender/gpu/vulkan/vk_shader.cc @@ -7,26 +7,679 @@ #include "vk_shader.hh" +#include "vk_backend.hh" +#include "vk_shader_log.hh" + +#include "BLI_string_utils.h" +#include "BLI_vector.hh" + +using namespace blender::gpu::shader; + +extern "C" char datatoc_glsl_shader_defines_glsl[]; + namespace blender::gpu { -void VKShader::vertex_shader_from_glsl(MutableSpan /*sources*/) + +/* -------------------------------------------------------------------- */ +/** \name Create Info + * \{ */ + +static const char *to_string(const Interpolation &interp) { + switch (interp) { + case Interpolation::SMOOTH: + return "smooth"; + case Interpolation::FLAT: + return "flat"; + case Interpolation::NO_PERSPECTIVE: + return "noperspective"; + default: + return "unknown"; + } } -void VKShader::geometry_shader_from_glsl(MutableSpan /*sources*/) +static const char *to_string(const Type &type) { + switch (type) { + case Type::FLOAT: + return "float"; + case Type::VEC2: + return "vec2"; + case Type::VEC3: + return "vec3"; + case Type::VEC4: + return "vec4"; + case Type::MAT3: + return "mat3"; + case Type::MAT4: + return "mat4"; + case Type::UINT: + return "uint"; + case Type::UVEC2: + return "uvec2"; + case Type::UVEC3: + return "uvec3"; + case Type::UVEC4: + return "uvec4"; + case Type::INT: + return "int"; + case Type::IVEC2: + return "ivec2"; + case Type::IVEC3: + return "ivec3"; + case Type::IVEC4: + return "ivec4"; + case Type::BOOL: + return "bool"; + default: + return "unknown"; + } } -void VKShader::fragment_shader_from_glsl(MutableSpan /*sources*/) +static const char *to_string(const eGPUTextureFormat &type) { + switch (type) { + case GPU_RGBA8UI: + return "rgba8ui"; + case GPU_RGBA8I: + return "rgba8i"; + case GPU_RGBA8: + return "rgba8"; + case GPU_RGBA32UI: + return "rgba32ui"; + case GPU_RGBA32I: + return "rgba32i"; + case GPU_RGBA32F: + return "rgba32f"; + case GPU_RGBA16UI: + return "rgba16ui"; + case GPU_RGBA16I: + return "rgba16i"; + case GPU_RGBA16F: + return "rgba16f"; + case GPU_RGBA16: + return "rgba16"; + case GPU_RG8UI: + return "rg8ui"; + case GPU_RG8I: + return "rg8i"; + case GPU_RG8: + return "rg8"; + case GPU_RG32UI: + return "rg32ui"; + case GPU_RG32I: + return "rg32i"; + case GPU_RG32F: + return "rg32f"; + case GPU_RG16UI: + return "rg16ui"; + case GPU_RG16I: + return "rg16i"; + case GPU_RG16F: + return "rg16f"; + case GPU_RG16: + return "rg16"; + case GPU_R8UI: + return "r8ui"; + case GPU_R8I: + return "r8i"; + case GPU_R8: + return "r8"; + case GPU_R32UI: + return "r32ui"; + case GPU_R32I: + return "r32i"; + case GPU_R32F: + return "r32f"; + case GPU_R16UI: + return "r16ui"; + case GPU_R16I: + return "r16i"; + case GPU_R16F: + return "r16f"; + case GPU_R16: + return "r16"; + case GPU_R11F_G11F_B10F: + return "r11f_g11f_b10f"; + case GPU_RGB10_A2: + return "rgb10_a2"; + default: + return "unknown"; + } } -void VKShader::compute_shader_from_glsl(MutableSpan /*sources*/) +static const char *to_string(const PrimitiveIn &layout) { + switch (layout) { + case PrimitiveIn::POINTS: + return "points"; + case PrimitiveIn::LINES: + return "lines"; + case PrimitiveIn::LINES_ADJACENCY: + return "lines_adjacency"; + case PrimitiveIn::TRIANGLES: + return "triangles"; + case PrimitiveIn::TRIANGLES_ADJACENCY: + return "triangles_adjacency"; + default: + return "unknown"; + } +} + +static const char *to_string(const PrimitiveOut &layout) +{ + switch (layout) { + case PrimitiveOut::POINTS: + return "points"; + case PrimitiveOut::LINE_STRIP: + return "line_strip"; + case PrimitiveOut::TRIANGLE_STRIP: + return "triangle_strip"; + default: + return "unknown"; + } +} + +static const char *to_string(const DepthWrite &value) +{ + switch (value) { + case DepthWrite::ANY: + return "depth_any"; + case DepthWrite::GREATER: + return "depth_greater"; + case DepthWrite::LESS: + return "depth_less"; + default: + return "depth_unchanged"; + } +} + +static void print_image_type(std::ostream &os, + const ImageType &type, + const ShaderCreateInfo::Resource::BindType bind_type) +{ + switch (type) { + case ImageType::INT_BUFFER: + case ImageType::INT_1D: + case ImageType::INT_1D_ARRAY: + case ImageType::INT_2D: + case ImageType::INT_2D_ARRAY: + case ImageType::INT_3D: + case ImageType::INT_CUBE: + case ImageType::INT_CUBE_ARRAY: + os << "i"; + break; + case ImageType::UINT_BUFFER: + case ImageType::UINT_1D: + case ImageType::UINT_1D_ARRAY: + case ImageType::UINT_2D: + case ImageType::UINT_2D_ARRAY: + case ImageType::UINT_3D: + case ImageType::UINT_CUBE: + case ImageType::UINT_CUBE_ARRAY: + os << "u"; + break; + default: + break; + } + + if (bind_type == ShaderCreateInfo::Resource::BindType::IMAGE) { + os << "image"; + } + else { + os << "sampler"; + } + + switch (type) { + case ImageType::FLOAT_BUFFER: + case ImageType::INT_BUFFER: + case ImageType::UINT_BUFFER: + os << "Buffer"; + break; + case ImageType::FLOAT_1D: + case ImageType::FLOAT_1D_ARRAY: + case ImageType::INT_1D: + case ImageType::INT_1D_ARRAY: + case ImageType::UINT_1D: + case ImageType::UINT_1D_ARRAY: + os << "1D"; + break; + case ImageType::FLOAT_2D: + case ImageType::FLOAT_2D_ARRAY: + case ImageType::INT_2D: + case ImageType::INT_2D_ARRAY: + case ImageType::UINT_2D: + case ImageType::UINT_2D_ARRAY: + case ImageType::SHADOW_2D: + case ImageType::SHADOW_2D_ARRAY: + case ImageType::DEPTH_2D: + case ImageType::DEPTH_2D_ARRAY: + os << "2D"; + break; + case ImageType::FLOAT_3D: + case ImageType::INT_3D: + case ImageType::UINT_3D: + os << "3D"; + break; + case ImageType::FLOAT_CUBE: + case ImageType::FLOAT_CUBE_ARRAY: + case ImageType::INT_CUBE: + case ImageType::INT_CUBE_ARRAY: + case ImageType::UINT_CUBE: + case ImageType::UINT_CUBE_ARRAY: + case ImageType::SHADOW_CUBE: + case ImageType::SHADOW_CUBE_ARRAY: + case ImageType::DEPTH_CUBE: + case ImageType::DEPTH_CUBE_ARRAY: + os << "Cube"; + break; + default: + break; + } + + switch (type) { + case ImageType::FLOAT_1D_ARRAY: + case ImageType::FLOAT_2D_ARRAY: + case ImageType::FLOAT_CUBE_ARRAY: + case ImageType::INT_1D_ARRAY: + case ImageType::INT_2D_ARRAY: + case ImageType::INT_CUBE_ARRAY: + case ImageType::UINT_1D_ARRAY: + case ImageType::UINT_2D_ARRAY: + case ImageType::UINT_CUBE_ARRAY: + case ImageType::SHADOW_2D_ARRAY: + case ImageType::SHADOW_CUBE_ARRAY: + case ImageType::DEPTH_2D_ARRAY: + case ImageType::DEPTH_CUBE_ARRAY: + os << "Array"; + break; + default: + break; + } + + switch (type) { + case ImageType::SHADOW_2D: + case ImageType::SHADOW_2D_ARRAY: + case ImageType::SHADOW_CUBE: + case ImageType::SHADOW_CUBE_ARRAY: + os << "Shadow"; + break; + default: + break; + } + os << " "; +} + +static std::ostream &print_qualifier(std::ostream &os, const Qualifier &qualifiers) +{ + if (bool(qualifiers & Qualifier::NO_RESTRICT) == false) { + os << "restrict "; + } + if (bool(qualifiers & Qualifier::READ) == false) { + os << "writeonly "; + } + if (bool(qualifiers & Qualifier::WRITE) == false) { + os << "readonly "; + } + return os; +} + +static void print_resource(std::ostream &os, const ShaderCreateInfo::Resource &res) +{ + os << "layout(binding = " << res.slot; + if (res.bind_type == ShaderCreateInfo::Resource::BindType::IMAGE) { + os << ", " << to_string(res.image.format); + } + else if (res.bind_type == ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER) { + os << ", std140"; + } + else if (res.bind_type == ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER) { + os << ", std430"; + } + os << ") "; + + int64_t array_offset; + StringRef name_no_array; + + switch (res.bind_type) { + case ShaderCreateInfo::Resource::BindType::SAMPLER: + os << "uniform "; + print_image_type(os, res.sampler.type, res.bind_type); + os << res.sampler.name << ";\n"; + break; + case ShaderCreateInfo::Resource::BindType::IMAGE: + os << "uniform "; + print_qualifier(os, res.image.qualifiers); + print_image_type(os, res.image.type, res.bind_type); + os << res.image.name << ";\n"; + break; + case ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER: + array_offset = res.uniformbuf.name.find_first_of("["); + name_no_array = (array_offset == -1) ? res.uniformbuf.name : + StringRef(res.uniformbuf.name.c_str(), array_offset); + os << "uniform " << name_no_array << " { " << res.uniformbuf.type_name << " _" + << res.uniformbuf.name << "; };\n"; + break; + case ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER: + array_offset = res.storagebuf.name.find_first_of("["); + name_no_array = (array_offset == -1) ? res.storagebuf.name : + StringRef(res.storagebuf.name.c_str(), array_offset); + print_qualifier(os, res.storagebuf.qualifiers); + os << "buffer "; + os << name_no_array << " { " << res.storagebuf.type_name << " _" << res.storagebuf.name + << "; };\n"; + break; + } +} + +static void print_resource_alias(std::ostream &os, const ShaderCreateInfo::Resource &res) +{ + int64_t array_offset; + StringRef name_no_array; + + switch (res.bind_type) { + case ShaderCreateInfo::Resource::BindType::UNIFORM_BUFFER: + array_offset = res.uniformbuf.name.find_first_of("["); + name_no_array = (array_offset == -1) ? res.uniformbuf.name : + StringRef(res.uniformbuf.name.c_str(), array_offset); + os << "#define " << name_no_array << " (_" << name_no_array << ")\n"; + break; + case ShaderCreateInfo::Resource::BindType::STORAGE_BUFFER: + array_offset = res.storagebuf.name.find_first_of("["); + name_no_array = (array_offset == -1) ? res.storagebuf.name : + StringRef(res.storagebuf.name.c_str(), array_offset); + os << "#define " << name_no_array << " (_" << name_no_array << ")\n"; + break; + default: + break; + } +} + +inline int get_location_count(const Type &type) +{ + if (type == shader::Type::MAT4) { + return 4; + } + else if (type == shader::Type::MAT3) { + return 3; + } + return 1; +} + +static void print_interface(std::ostream &os, + const std::string &prefix, + const StageInterfaceInfo &iface, + int &location, + const StringRefNull &suffix = "") +{ + if (iface.instance_name.is_empty()) { + for (const StageInterfaceInfo::InOut &inout : iface.inouts) { + os << "layout(location=" << location << ") " << prefix << " " << to_string(inout.interp) + << " " << to_string(inout.type) << " " << inout.name << ";\n"; + location += get_location_count(inout.type); + } + } + else { + std::string struct_name = prefix + iface.name; + std::string iface_attribute; + if (iface.instance_name.is_empty()) { + iface_attribute = "iface_"; + } + else { + iface_attribute = iface.instance_name; + } + std::string flat = ""; + if (prefix == "in") { + flat = "flat "; + } + const bool add_defines = iface.instance_name.is_empty(); + + os << "struct " << struct_name << " {\n"; + for (const StageInterfaceInfo::InOut &inout : iface.inouts) { + os << " " << to_string(inout.type) << " " << inout.name << ";\n"; + } + os << "};\n"; + os << "layout(location=" << location << ") " << prefix << " " << flat << struct_name << " " + << iface_attribute << suffix << ";\n"; + + if (add_defines) { + for (const StageInterfaceInfo::InOut &inout : iface.inouts) { + os << "#define " << inout.name << " (" << iface_attribute << "." << inout.name << ")\n"; + } + } + + for (const StageInterfaceInfo::InOut &inout : iface.inouts) { + location += get_location_count(inout.type); + } + } +} + +/** \} */ +static std::string main_function_wrapper(std::string &pre_main, std::string &post_main) +{ + std::stringstream ss; + /* Prototype for the original main. */ + ss << "\n"; + ss << "void main_function_();\n"; + /* Wrapper to the main function in order to inject code processing on globals. */ + ss << "void main() {\n"; + ss << pre_main; + ss << " main_function_();\n"; + ss << post_main; + ss << "}\n"; + /* Rename the original main. */ + ss << "#define main main_function_\n"; + ss << "\n"; + return ss.str(); +} + +static const std::string to_stage_name(shaderc_shader_kind stage) +{ + switch (stage) { + case shaderc_vertex_shader: + return std::string("vertex"); + case shaderc_geometry_shader: + return std::string("geometry"); + case shaderc_fragment_shader: + return std::string("fragment"); + case shaderc_compute_shader: + return std::string("compute"); + + default: + BLI_assert_msg(false, "Do not know how to convert shaderc_shader_kind to stage name."); + break; + } + return std::string("unknown stage"); +} + +static char *glsl_patch_get() +{ + static char patch[2048] = "\0"; + if (patch[0] != '\0') { + return patch; + } + + size_t slen = 0; + /* Version need to go first. */ + STR_CONCAT(patch, slen, "#version 450\n"); + STR_CONCAT(patch, slen, "#define gl_VertexID gl_VertexIndex\n"); + STR_CONCAT(patch, slen, "#define gpu_BaseInstance (0)\n"); + STR_CONCAT(patch, slen, "#define gpu_InstanceIndex (gl_InstanceIndex)\n"); + STR_CONCAT(patch, slen, "#define GPU_ARB_texture_cube_map_array\n"); + + STR_CONCAT(patch, slen, "#define gl_InstanceID gpu_InstanceIndex\n"); + + STR_CONCAT(patch, slen, "#define DFDX_SIGN 1.0\n"); + STR_CONCAT(patch, slen, "#define DFDY_SIGN 1.0\n"); + + /* GLSL Backend Lib. */ + STR_CONCAT(patch, slen, datatoc_glsl_shader_defines_glsl); + + BLI_assert(slen < sizeof(patch)); + return patch; +} + +static std::string combine_sources(Span sources) +{ + char *sources_combined = BLI_string_join_arrayN((const char **)sources.data(), sources.size()); + return std::string(sources_combined); +} + +Vector VKShader::compile_glsl_to_spirv(Span sources, + shaderc_shader_kind stage) +{ + std::string combined_sources = combine_sources(sources); + VKBackend &backend = static_cast(*VKBackend::get()); + shaderc::Compiler &compiler = backend.get_shaderc_compiler(); + shaderc::CompileOptions options; + options.SetOptimizationLevel(shaderc_optimization_level_performance); + + shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv( + combined_sources, stage, name, options); + if (module.GetNumErrors() != 0 || module.GetNumWarnings() != 0) { + std::string log = module.GetErrorMessage(); + Vector logcstr(log.c_str(), log.c_str() + log.size() + 1); + + VKLogParser parser; + print_log(sources, + logcstr.data(), + to_stage_name(stage).c_str(), + module.GetCompilationStatus() != shaderc_compilation_status_success, + &parser); + } + + if (module.GetCompilationStatus() != shaderc_compilation_status_success) { + compilation_failed_ = true; + return Vector(); + } + + return Vector(module.cbegin(), module.cend()); +} + +void VKShader::build_shader_module(Span spirv_module, VkShaderModule *r_shader_module) +{ + VkShaderModuleCreateInfo create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; + create_info.codeSize = spirv_module.size() * sizeof(uint32_t); + create_info.pCode = spirv_module.data(); + + VKContext &context = *static_cast(VKContext::get()); + + VkResult result = vkCreateShaderModule( + context.device_get(), &create_info, nullptr, r_shader_module); + if (result != VK_SUCCESS) { + compilation_failed_ = true; + *r_shader_module = VK_NULL_HANDLE; + } +} + +VKShader::VKShader(const char *name) : Shader(name) +{ + context_ = VKContext::get(); +} + +VKShader::~VKShader() +{ + VkDevice device = context_->device_get(); + if (vertex_module_ != VK_NULL_HANDLE) { + vkDestroyShaderModule(device, vertex_module_, nullptr); + vertex_module_ = VK_NULL_HANDLE; + } + if (geometry_module_ != VK_NULL_HANDLE) { + vkDestroyShaderModule(device, geometry_module_, nullptr); + geometry_module_ = VK_NULL_HANDLE; + } + if (fragment_module_ != VK_NULL_HANDLE) { + vkDestroyShaderModule(device, fragment_module_, nullptr); + fragment_module_ = VK_NULL_HANDLE; + } + if (compute_module_ != VK_NULL_HANDLE) { + vkDestroyShaderModule(device, compute_module_, nullptr); + compute_module_ = VK_NULL_HANDLE; + } +} + +void VKShader::build_shader_module(MutableSpan sources, + shaderc_shader_kind stage, + VkShaderModule *r_shader_module) +{ + BLI_assert_msg(ELEM(stage, + shaderc_vertex_shader, + shaderc_geometry_shader, + shaderc_fragment_shader, + shaderc_compute_shader), + "Only forced ShaderC shader kinds are supported."); + sources[0] = glsl_patch_get(); + Vector spirv_module = compile_glsl_to_spirv(sources, stage); + build_shader_module(spirv_module, &compute_module_); +} + +void VKShader::vertex_shader_from_glsl(MutableSpan sources) +{ + build_shader_module(sources, shaderc_vertex_shader, &vertex_module_); +} + +void VKShader::geometry_shader_from_glsl(MutableSpan sources) +{ + build_shader_module(sources, shaderc_geometry_shader, &geometry_module_); +} + +void VKShader::fragment_shader_from_glsl(MutableSpan sources) +{ + build_shader_module(sources, shaderc_fragment_shader, &fragment_module_); +} + +void VKShader::compute_shader_from_glsl(MutableSpan sources) +{ + build_shader_module(sources, shaderc_compute_shader, &compute_module_); } bool VKShader::finalize(const shader::ShaderCreateInfo * /*info*/) { - return false; + if (compilation_failed_) { + return false; + } + + if (vertex_module_ != VK_NULL_HANDLE) { + BLI_assert(fragment_module_ != VK_NULL_HANDLE); + BLI_assert(compute_module_ == VK_NULL_HANDLE); + + VkPipelineShaderStageCreateInfo vertex_stage_info = {}; + vertex_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + vertex_stage_info.stage = VK_SHADER_STAGE_VERTEX_BIT; + vertex_stage_info.module = vertex_module_; + vertex_stage_info.pName = "main"; + pipeline_infos_.append(vertex_stage_info); + + if (geometry_module_ != VK_NULL_HANDLE) { + VkPipelineShaderStageCreateInfo geo_stage_info = {}; + geo_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + geo_stage_info.stage = VK_SHADER_STAGE_GEOMETRY_BIT; + geo_stage_info.module = geometry_module_; + geo_stage_info.pName = "main"; + pipeline_infos_.append(geo_stage_info); + } + VkPipelineShaderStageCreateInfo fragment_stage_info = {}; + fragment_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + fragment_stage_info.stage = VK_SHADER_STAGE_FRAGMENT_BIT; + fragment_stage_info.module = fragment_module_; + fragment_stage_info.pName = "main"; + pipeline_infos_.append(fragment_stage_info); + } + else { + BLI_assert(vertex_module_ == VK_NULL_HANDLE); + BLI_assert(geometry_module_ == VK_NULL_HANDLE); + BLI_assert(fragment_module_ == VK_NULL_HANDLE); + BLI_assert(compute_module_ != VK_NULL_HANDLE); + + VkPipelineShaderStageCreateInfo compute_stage_info = {}; + compute_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; + compute_stage_info.stage = VK_SHADER_STAGE_GEOMETRY_BIT; + compute_stage_info.module = geometry_module_; + compute_stage_info.pName = "main"; + pipeline_infos_.append(compute_stage_info); + } + + return true; } void VKShader::transform_feedback_names_set(Span /*name_list*/, @@ -64,34 +717,222 @@ void VKShader::uniform_int(int /*location*/, { } -std::string VKShader::resources_declare(const shader::ShaderCreateInfo & /*info*/) const +std::string VKShader::resources_declare(const shader::ShaderCreateInfo &info) const { - return std::string(); + std::stringstream ss; + + ss << "\n/* Pass Resources. */\n"; + for (const ShaderCreateInfo::Resource &res : info.pass_resources_) { + print_resource(ss, res); + } + for (const ShaderCreateInfo::Resource &res : info.pass_resources_) { + print_resource_alias(ss, res); + } + + ss << "\n/* Batch Resources. */\n"; + for (const ShaderCreateInfo::Resource &res : info.batch_resources_) { + print_resource(ss, res); + } + for (const ShaderCreateInfo::Resource &res : info.batch_resources_) { + print_resource_alias(ss, res); + } + + if (!info.push_constants_.is_empty()) { + ss << "\n/* Push Constants. */\n"; + ss << "layout(push_constant) uniform constants\n"; + ss << "{\n"; + for (const ShaderCreateInfo::PushConst &uniform : info.push_constants_) { + ss << " " << to_string(uniform.type) << " pc_" << uniform.name; + if (uniform.array_size > 0) { + ss << "[" << uniform.array_size << "]"; + } + ss << ";\n"; + } + ss << "} PushConstants;\n"; + for (const ShaderCreateInfo::PushConst &uniform : info.push_constants_) { + ss << "#define " << uniform.name << " (PushConstants.pc_" << uniform.name << ")\n"; + } + } + + ss << "\n"; + return ss.str(); } -std::string VKShader::vertex_interface_declare(const shader::ShaderCreateInfo & /*info*/) const +std::string VKShader::vertex_interface_declare(const shader::ShaderCreateInfo &info) const { - return std::string(); + std::stringstream ss; + std::string post_main; + + ss << "\n/* Inputs. */\n"; + for (const ShaderCreateInfo::VertIn &attr : info.vertex_inputs_) { + ss << "layout(location = " << attr.index << ") "; + ss << "in " << to_string(attr.type) << " " << attr.name << ";\n"; + } + /* NOTE(D4490): Fix a bug where shader without any vertex attributes do not behave correctly. + */ + if (GPU_type_matches_ex(GPU_DEVICE_APPLE, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL) && + info.vertex_inputs_.is_empty()) { + ss << "in float gpu_dummy_workaround;\n"; + } + ss << "\n/* Interfaces. */\n"; + int location = 0; + for (const StageInterfaceInfo *iface : info.vertex_out_interfaces_) { + print_interface(ss, "out", *iface, location); + } + if (bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD)) { + /* Need this for stable barycentric. */ + ss << "flat out vec4 gpu_pos_flat;\n"; + ss << "out vec4 gpu_pos;\n"; + + post_main += " gpu_pos = gpu_pos_flat = gl_Position;\n"; + } + ss << "\n"; + + if (post_main.empty() == false) { + std::string pre_main; + ss << main_function_wrapper(pre_main, post_main); + } + return ss.str(); } -std::string VKShader::fragment_interface_declare(const shader::ShaderCreateInfo & /*info*/) const +std::string VKShader::fragment_interface_declare(const shader::ShaderCreateInfo &info) const { - return std::string(); + std::stringstream ss; + std::string pre_main; + + ss << "\n/* Interfaces. */\n"; + const Vector &in_interfaces = info.geometry_source_.is_empty() ? + info.vertex_out_interfaces_ : + info.geometry_out_interfaces_; + int location = 0; + for (const StageInterfaceInfo *iface : in_interfaces) { + print_interface(ss, "in", *iface, location); + } + if (bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD)) { + std::cout << "native" << std::endl; + /* NOTE(fclem): This won't work with geometry shader. Hopefully, we don't need geometry + * shader workaround if this extension/feature is detected. */ + ss << "\n/* Stable Barycentric Coordinates. */\n"; + ss << "flat in vec4 gpu_pos_flat;\n"; + ss << "__explicitInterpAMD in vec4 gpu_pos;\n"; + /* Globals. */ + ss << "vec3 gpu_BaryCoord;\n"; + ss << "vec3 gpu_BaryCoordNoPersp;\n"; + ss << "\n"; + ss << "vec2 stable_bary_(vec2 in_bary) {\n"; + ss << " vec3 bary = vec3(in_bary, 1.0 - in_bary.x - in_bary.y);\n"; + ss << " if (interpolateAtVertexAMD(gpu_pos, 0) == gpu_pos_flat) { return bary.zxy; }\n"; + ss << " if (interpolateAtVertexAMD(gpu_pos, 2) == gpu_pos_flat) { return bary.yzx; }\n"; + ss << " return bary.xyz;\n"; + ss << "}\n"; + ss << "\n"; + ss << "vec4 gpu_position_at_vertex(int v) {\n"; + ss << " if (interpolateAtVertexAMD(gpu_pos, 0) == gpu_pos_flat) { v = (v + 2) % 3; }\n"; + ss << " if (interpolateAtVertexAMD(gpu_pos, 2) == gpu_pos_flat) { v = (v + 1) % 3; }\n"; + ss << " return interpolateAtVertexAMD(gpu_pos, v);\n"; + ss << "}\n"; + + pre_main += " gpu_BaryCoord = stable_bary_(gl_BaryCoordSmoothAMD);\n"; + pre_main += " gpu_BaryCoordNoPersp = stable_bary_(gl_BaryCoordNoPerspAMD);\n"; + } + if (info.early_fragment_test_) { + ss << "layout(early_fragment_tests) in;\n"; + } + ss << "layout(" << to_string(info.depth_write_) << ") out float gl_FragDepth;\n"; + ss << "\n/* Outputs. */\n"; + for (const ShaderCreateInfo::FragOut &output : info.fragment_outputs_) { + ss << "layout(location = " << output.index; + switch (output.blend) { + case DualBlend::SRC_0: + ss << ", index = 0"; + break; + case DualBlend::SRC_1: + ss << ", index = 1"; + break; + default: + break; + } + ss << ") "; + ss << "out " << to_string(output.type) << " " << output.name << ";\n"; + } + ss << "\n"; + + if (pre_main.empty() == false) { + std::string post_main; + ss << main_function_wrapper(pre_main, post_main); + } + return ss.str(); } -std::string VKShader::geometry_interface_declare(const shader::ShaderCreateInfo & /*info*/) const +std::string VKShader::geometry_interface_declare(const shader::ShaderCreateInfo &info) const { - return std::string(); + int max_verts = info.geometry_layout_.max_vertices; + int invocations = info.geometry_layout_.invocations; + + std::stringstream ss; + ss << "\n/* Geometry Layout. */\n"; + ss << "layout(" << to_string(info.geometry_layout_.primitive_in); + if (invocations != -1) { + ss << ", invocations = " << invocations; + } + ss << ") in;\n"; + + ss << "layout(" << to_string(info.geometry_layout_.primitive_out) + << ", max_vertices = " << max_verts << ") out;\n"; + ss << "\n"; + return ss.str(); } -std::string VKShader::geometry_layout_declare(const shader::ShaderCreateInfo & /*info*/) const +static StageInterfaceInfo *find_interface_by_name(const Vector &ifaces, + const StringRefNull &name) { - return std::string(); + for (auto *iface : ifaces) { + if (iface->instance_name == name) { + return iface; + } + } + return nullptr; } -std::string VKShader::compute_layout_declare(const shader::ShaderCreateInfo & /*info*/) const +std::string VKShader::geometry_layout_declare(const shader::ShaderCreateInfo &info) const { - return std::string(); + std::stringstream ss; + + ss << "\n/* Interfaces. */\n"; + int location = 0; + for (const StageInterfaceInfo *iface : info.vertex_out_interfaces_) { + bool has_matching_output_iface = find_interface_by_name(info.geometry_out_interfaces_, + iface->instance_name) != nullptr; + const char *suffix = (has_matching_output_iface) ? "_in[]" : "[]"; + print_interface(ss, "in", *iface, location, suffix); + } + ss << "\n"; + + for (const StageInterfaceInfo *iface : info.geometry_out_interfaces_) { + bool has_matching_input_iface = find_interface_by_name(info.vertex_out_interfaces_, + iface->instance_name) != nullptr; + const char *suffix = (has_matching_input_iface) ? "_out" : ""; + print_interface(ss, "out", *iface, location, suffix); + } + ss << "\n"; + + return ss.str(); +} + +std::string VKShader::compute_layout_declare(const shader::ShaderCreateInfo &info) const +{ + std::stringstream ss; + ss << "\n/* Compute Layout. */\n"; + ss << "layout(local_size_x = " << info.compute_layout_.local_size_x; + if (info.compute_layout_.local_size_y != -1) { + ss << ", local_size_y = " << info.compute_layout_.local_size_y; + } + if (info.compute_layout_.local_size_z != -1) { + ss << ", local_size_z = " << info.compute_layout_.local_size_z; + } + ss << ") in;\n"; + ss << "\n"; + return ss.str(); } int VKShader::program_handle_get() const diff --git a/source/blender/gpu/vulkan/vk_shader.hh b/source/blender/gpu/vulkan/vk_shader.hh index 9ab0aca67eb..aa8f0b84ae7 100644 --- a/source/blender/gpu/vulkan/vk_shader.hh +++ b/source/blender/gpu/vulkan/vk_shader.hh @@ -9,13 +9,26 @@ #include "gpu_shader_private.hh" +#include "vk_backend.hh" +#include "vk_context.hh" + +#include "BLI_string_ref.hh" + namespace blender::gpu { class VKShader : public Shader { + private: + VKContext *context_ = nullptr; + VkShaderModule vertex_module_ = VK_NULL_HANDLE; + VkShaderModule geometry_module_ = VK_NULL_HANDLE; + VkShaderModule fragment_module_ = VK_NULL_HANDLE; + VkShaderModule compute_module_ = VK_NULL_HANDLE; + bool compilation_failed_ = false; + Vector pipeline_infos_; + public: - VKShader(const char *name) : Shader(name) - { - } + VKShader(const char *name); + virtual ~VKShader(); void vertex_shader_from_glsl(MutableSpan sources) override; void geometry_shader_from_glsl(MutableSpan sources) override; @@ -43,6 +56,13 @@ class VKShader : public Shader { /* DEPRECATED: Kept only because of BGL API. */ int program_handle_get() const override; + + private: + Vector compile_glsl_to_spirv(Span sources, shaderc_shader_kind kind); + void build_shader_module(Span spirv_module, VkShaderModule *r_shader_module); + void build_shader_module(MutableSpan sources, + shaderc_shader_kind stage, + VkShaderModule *r_shader_module); }; } // namespace blender::gpu \ No newline at end of file diff --git a/source/blender/gpu/vulkan/vk_shader_log.cc b/source/blender/gpu/vulkan/vk_shader_log.cc new file mode 100644 index 00000000000..4a7d1771c53 --- /dev/null +++ b/source/blender/gpu/vulkan/vk_shader_log.cc @@ -0,0 +1,44 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup gpu + */ + +#include "vk_shader_log.hh" + +#include "GPU_platform.h" + +namespace blender::gpu { + +char *VKLogParser::parse_line(char *log_line, GPULogItem &log_item) +{ + log_line = skip_name(log_line); + log_line = skip_separators(log_line, ":"); + + /* Parse error line & char numbers. */ + if (at_number(log_line)) { + char *error_line_number_end; + log_item.cursor.row = parse_number(log_line, &error_line_number_end); + log_line = error_line_number_end; + } + log_line = skip_separators(log_line, ": "); + + /* Skip to message. Avoid redundant info. */ + log_line = skip_severity_keyword(log_line, log_item); + log_line = skip_separators(log_line, ": "); + + return log_line; +} + +char *VKLogParser::skip_name(char *log_line) +{ + return skip_until(log_line, ':'); +} + +char *VKLogParser::skip_severity_keyword(char *log_line, GPULogItem &log_item) +{ + return skip_severity(log_line, log_item, "error", "warning"); +} + +} // namespace blender::gpu diff --git a/source/blender/gpu/vulkan/vk_shader_log.hh b/source/blender/gpu/vulkan/vk_shader_log.hh new file mode 100644 index 00000000000..fb12b7a5039 --- /dev/null +++ b/source/blender/gpu/vulkan/vk_shader_log.hh @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. All rights reserved. */ + +#include "gpu_shader_private.hh" + +namespace blender::gpu { + +class VKLogParser : public GPULogParser { + public: + char *parse_line(char *log_line, GPULogItem &log_item) override; + + protected: + char *skip_name(char *log_line); + char *skip_severity_keyword(char *log_line, GPULogItem &log_item); +}; +} // namespace blender::gpu \ No newline at end of file From 3e1152428d591db65b947308c91739344ef1dd51 Mon Sep 17 00:00:00 2001 From: Alaska Date: Mon, 12 Dec 2022 12:32:11 +0100 Subject: [PATCH 0016/1522] Cleanup: Code comments in tree.h Differential Revision: https://developer.blender.org/D16751 --- intern/cycles/kernel/light/tree.h | 77 +++++++++++++++---------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index ad9fd3d10e4..3b683b5562f 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -22,16 +22,15 @@ CCL_NAMESPACE_BEGIN -/* TODO: this seems like a relative expensive computation, and we can make it a lot cheaper - * by using a bounding sphere instead of a bounding box. This will be more inaccurate, but it - * might be fine when used along with the adaptive splitting. */ +/* TODO: this seems like a relative expensive computation. We can make it a lot cheaper by using a + * bounding sphere instead of a bounding box, but this will reduce the accuracy sometimes. */ ccl_device float light_tree_cos_bounding_box_angle(const BoundingBox bbox, const float3 P, const float3 point_to_centroid) { if (P.x > bbox.min.x && P.y > bbox.min.y && P.z > bbox.min.z && P.x < bbox.max.x && P.y < bbox.max.y && P.z < bbox.max.z) { - /* If P is inside the bbox, `theta_u` covers the whole sphere */ + /* If P is inside the bbox, `theta_u` covers the whole sphere. */ return -1.0f; } float cos_theta_u = 1.0f; @@ -53,7 +52,7 @@ ccl_device_forceinline float sin_from_cos(const float c) return safe_sqrtf(1.0f - sqr(c)); } -/* Compute vector v as in Fig .8. P_v is the corresponding point along the ray ccl_device float3 */ +/* Compute vector v as in Fig .8. P_v is the corresponding point along the ray. */ ccl_device float3 compute_v( const float3 centroid, const float3 P, const float3 D, const float3 bcone_axis, const float t) { @@ -95,12 +94,12 @@ ccl_device void light_tree_importance(const float3 N_or_D, const float sin_theta_u = sin_from_cos(cos_theta_u); - /* cos(theta_i') in the paper, omitted for volume */ + /* cos(theta_i') in the paper, omitted for volume. */ float cos_min_incidence_angle = 1.0f; float cos_max_incidence_angle = 1.0f; - /* when sampling the light tree for the second time in `shade_volume.h` and when query the pdf in - * `sample.h` */ + /* When sampling the light tree for the second time in `shade_volume.h` and when query the pdf in + * `sample.h`. */ const bool in_volume = is_zero(N_or_D); if (!in_volume_segment && !in_volume) { const float3 N = N_or_D; @@ -116,7 +115,7 @@ ccl_device void light_tree_importance(const float3 N_or_D, /* If the node is guaranteed to be behind the surface we're sampling, and the surface is * opaque, then we can give the node an importance of 0 as it contributes nothing to the * surface. This is more accurate than the bbox test if we are calculating the importance of - * an emitter with radius */ + * an emitter with radius. */ if (!has_transmission && cos_min_incidence_angle < 0) { return; } @@ -133,8 +132,8 @@ ccl_device void light_tree_importance(const float3 N_or_D, float cos_theta_o, sin_theta_o; fast_sincosf(bcone.theta_o, &sin_theta_o, &cos_theta_o); - /* minimum angle an emitter’s axis would form with the direction to the shading point, - * cos(theta') in the paper */ + /* Minimum angle an emitter’s axis would form with the direction to the shading point, + * cos(theta') in the paper. */ float cos_min_outgoing_angle; if ((cos_theta >= cos_theta_u) || (cos_theta_minus_theta_u >= cos_theta_o)) { /* theta - theta_o - theta_u <= 0 */ @@ -151,7 +150,7 @@ ccl_device void light_tree_importance(const float3 N_or_D, sin_theta_minus_theta_u * sin_theta_o; } else { - /* cluster invisible */ + /* Cluster is invisible. */ return; } @@ -200,14 +199,14 @@ ccl_device bool compute_emitter_centroid_and_dir(KernelGlobals kg, dir = klight->spot.dir; break; case LIGHT_POINT: - /* Disk-oriented normal */ + /* Disk-oriented normal. */ dir = safe_normalize(P - centroid); break; case LIGHT_AREA: dir = klight->area.dir; break; case LIGHT_BACKGROUND: - /* Aarbitrary centroid and direction */ + /* Arbitrary centroid and direction. */ centroid = make_float3(0.0f, 0.0f, 1.0f); dir = make_float3(0.0f, 0.0f, -1.0f); return !in_volume_segment; @@ -231,7 +230,7 @@ ccl_device bool compute_emitter_centroid_and_dir(KernelGlobals kg, dir = -safe_normalize(cross(vertices[1] - vertices[0], vertices[2] - vertices[0])); } else { - /* Double sided: any vector in the plane. */ + /* Double-sided: any vector in the plane. */ dir = safe_normalize(vertices[0] - vertices[1]); } } @@ -269,9 +268,9 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg, if (in_volume_segment) { const float3 D = N_or_D; - /* Closest point */ + /* Closest point. */ P_c = P + dot(centroid - P, D) * D; - /* minimal distance of the ray to the cluster */ + /* Minimal distance of the ray to the cluster. */ distance.x = len(centroid - P_c); distance.y = distance.x; point_to_centroid = -compute_v(centroid, P, D, bcone.axis, t); @@ -284,7 +283,7 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg, if (prim_id < 0) { const ccl_global KernelLight *klight = &kernel_data_fetch(lights, ~prim_id); switch (klight->type) { - /* Function templates only modifies cos_theta_u when in_volume_segment = true */ + /* Function templates only modifies cos_theta_u when in_volume_segment = true. */ case LIGHT_SPOT: is_visible = spot_light_tree_parameters( klight, centroid, P_c, cos_theta_u, distance, point_to_centroid); @@ -310,7 +309,7 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg, return; } } - else { /* mesh light */ + else { /* Mesh light. */ is_visible = triangle_light_tree_parameters( kg, kemitter, centroid, P_c, N_or_D, bcone, cos_theta_u, distance, point_to_centroid); } @@ -346,7 +345,7 @@ ccl_device void light_tree_node_importance(KernelGlobals kg, max_importance = 0.0f; min_importance = 0.0f; if (knode->num_prims == 1) { - /* At a leaf node with only one emitter */ + /* At a leaf node with only one emitter. */ light_tree_emitter_importance( kg, P, N_or_D, t, has_transmission, -knode->child_index, max_importance, min_importance); } @@ -358,7 +357,7 @@ ccl_device void light_tree_node_importance(KernelGlobals kg, float cos_theta_u; float distance; if (knode->bit_trail == 1) { - /* distant light node */ + /* Distant light node. */ if (in_volume_segment) { return; } @@ -372,7 +371,7 @@ ccl_device void light_tree_node_importance(KernelGlobals kg, if (in_volume_segment) { const float3 D = N_or_D; const float3 closest_point = P + dot(centroid - P, D) * D; - /* minimal distance of the ray to the cluster */ + /* Minimal distance of the ray to the cluster. */ distance = len(centroid - closest_point); point_to_centroid = -compute_v(centroid, P, D, bcone.axis, t); cos_theta_u = light_tree_cos_bounding_box_angle(bbox, closest_point, point_to_centroid); @@ -393,7 +392,7 @@ ccl_device void light_tree_node_importance(KernelGlobals kg, point_to_centroid = normalize_len(centroid - P, &distance); cos_theta_u = light_tree_cos_bounding_box_angle(bbox, P, point_to_centroid); } - /* clamp distance to half the radius of the cluster when splitting is disabled */ + /* Clamp distance to half the radius of the cluster when splitting is disabled. */ distance = fmaxf(0.5f * len(centroid - bbox.max), distance); } /* TODO: currently max_distance = min_distance, max_importance = min_importance for the @@ -436,8 +435,8 @@ ccl_device void sample_resevoir(const int current_index, return; } -/* pick an emitter from a leaf node using resevoir sampling, keep two reservoirs for upper and - * lower bounds */ +/* Pick an emitter from a leaf node using resevoir sampling, keep two reservoirs for upper and + * lower bounds. */ template ccl_device int light_tree_cluster_select_emitter(KernelGlobals kg, ccl_private float &rand, @@ -452,11 +451,11 @@ ccl_device int light_tree_cluster_select_emitter(KernelGlobals kg, float total_importance[2] = {0.0f, 0.0f}; int selected_index = -1; - /* Mark emitters with zero importance. Used for resevoir when total minimum importance = 0 */ + /* Mark emitters with zero importance. Used for resevoir when total minimum importance = 0. */ kernel_assert(knode->num_prims <= sizeof(uint) * 8); uint has_importance = 0; - const bool sample_max = (rand > 0.5f); /* sampling using the maximum importance */ + const bool sample_max = (rand > 0.5f); /* Sampling using the maximum importance. */ rand = rand * 2.0f - float(sample_max); for (int i = 0; i < knode->num_prims; i++) { @@ -485,7 +484,7 @@ ccl_device int light_tree_cluster_select_emitter(KernelGlobals kg, } if (total_importance[1] == 0.0f) { - /* uniformly sample emitters with positive maximum importance */ + /* Uniformly sample emitters with positive maximum importance. */ if (sample_max) { selected_importance[1] = 1.0f; total_importance[1] = float(popcount(has_importance)); @@ -540,7 +539,7 @@ ccl_device bool get_left_probability(KernelGlobals kg, } const float total_min_importance = min_left_importance + min_right_importance; - /* average two probabilities of picking the left child node using lower and upper bounds */ + /* Average two probabilities of picking the left child node using lower and upper bounds. */ const float probability_max = max_left_importance / total_max_importance; const float probability_min = total_min_importance > 0 ? min_left_importance / total_min_importance : @@ -572,28 +571,28 @@ ccl_device_noinline bool light_tree_sample(KernelGlobals kg, float pdf_emitter_from_leaf = 1.0f; int selected_light = -1; - int node_index = 0; /* root node */ + int node_index = 0; /* Root node. */ /* Traverse the light tree until a leaf node is reached. */ while (true) { const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes, node_index); if (knode->child_index <= 0) { - /* At a leaf node, we pick an emitter */ + /* At a leaf node, we pick an emitter. */ selected_light = light_tree_cluster_select_emitter( kg, randv, P, N_or_D, t, has_transmission, knode, &pdf_emitter_from_leaf); break; } - /* At an interior node, the left child is directly after the parent, - * while the right child is stored as the child index. */ + /* At an interior node, the left child is directly after the parent, while the right child is + * stored as the child index. */ const int left_index = node_index + 1; const int right_index = knode->child_index; float left_prob; if (!get_left_probability( kg, P, N_or_D, t, has_transmission, left_index, right_index, left_prob)) { - return false; /* both child nodes have zero importance */ + return false; /* Both child nodes have zero importance. */ } float discard; @@ -607,7 +606,7 @@ ccl_device_noinline bool light_tree_sample(KernelGlobals kg, return false; } - /* Sample a point on the chosen emitter */ + /* Sample a point on the chosen emitter. */ ccl_global const KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters, selected_light); @@ -650,7 +649,7 @@ ccl_device float light_tree_pdf( KernelGlobals kg, const float3 P, const float3 N, const int path_flag, const int prim) { const bool has_transmission = (path_flag & PATH_RAY_MIS_HAD_TRANSMISSION); - /* Target emitter info */ + /* Target emitter info. */ const int target_emitter = (prim >= 0) ? kernel_data_fetch(triangle_to_tree, prim) : kernel_data_fetch(light_to_tree, ~prim); ccl_global const KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters, @@ -659,11 +658,11 @@ ccl_device float light_tree_pdf( ccl_global const KernelLightTreeNode *kleaf = &kernel_data_fetch(light_tree_nodes, target_leaf); uint bit_trail = kleaf->bit_trail; - int node_index = 0; /* root node */ + int node_index = 0; /* Root node. */ float pdf = 1.0f; - /* Traverse the light tree until we reach the target leaf node */ + /* Traverse the light tree until we reach the target leaf node. */ while (true) { const ccl_global KernelLightTreeNode *knode = &kernel_data_fetch(light_tree_nodes, node_index); @@ -671,7 +670,7 @@ ccl_device float light_tree_pdf( break; } - /* Interior node */ + /* Interior node. */ const int left_index = node_index + 1; const int right_index = knode->child_index; From baf8b3bb8874836ed0862e8381602d34184a98d9 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 27 Sep 2022 15:56:15 -0500 Subject: [PATCH 0017/1522] Cleanup: Standardize variable names, use spans to pbvh uv islands. --- .../blender/blenkernel/intern/pbvh_pixels.cc | 8 ++-- .../blenkernel/intern/pbvh_uv_islands.cc | 39 ++++++++----------- .../blenkernel/intern/pbvh_uv_islands.hh | 18 ++++----- 3 files changed, 30 insertions(+), 35 deletions(-) diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index 4e073f195a9..bb7e912fd94 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -361,8 +361,10 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image return; } - uv_islands::MeshData mesh_data( - pbvh->looptri, pbvh->totprim, pbvh->totvert, pbvh->mloop, ldata_uv); + uv_islands::MeshData mesh_data({pbvh->looptri, pbvh->totprim}, + {pbvh->mloop, pbvh->totprim}, + pbvh->totvert, + {ldata_uv, pbvh->totprim}); uv_islands::UVIslands islands(mesh_data); uv_islands::UVIslandsMask uv_masks; @@ -385,7 +387,7 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image islands.extend_borders(uv_masks); update_geom_primitives(*pbvh, mesh_data); - UVPrimitiveLookup uv_primitive_lookup(mesh_data.looptri_len, islands); + UVPrimitiveLookup uv_primitive_lookup(mesh_data.looptris.size(), islands); EncodePixelsUserData user_data; user_data.pbvh = pbvh; diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index aec4929c5fa..21645e50e7e 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -95,8 +95,8 @@ rctf MeshPrimitive::uv_bounds() const static void mesh_data_init_vertices(MeshData &mesh_data) { - mesh_data.vertices.reserve(mesh_data.vert_len); - for (int64_t i = 0; i < mesh_data.vert_len; i++) { + mesh_data.vertices.reserve(mesh_data.verts_num); + for (int64_t i = 0; i < mesh_data.verts_num; i++) { MeshVertex vert; vert.v = i; mesh_data.vertices.append(vert); @@ -105,9 +105,9 @@ static void mesh_data_init_vertices(MeshData &mesh_data) static void mesh_data_init_primitives(MeshData &mesh_data) { - mesh_data.primitives.reserve(mesh_data.looptri_len); - for (int64_t i = 0; i < mesh_data.looptri_len; i++) { - const MLoopTri &tri = mesh_data.looptri[i]; + mesh_data.primitives.reserve(mesh_data.looptris.size()); + for (int64_t i = 0; i < mesh_data.looptris.size(); i++) { + const MLoopTri &tri = mesh_data.looptris[i]; MeshPrimitive primitive; primitive.index = i; primitive.poly = tri.poly; @@ -115,7 +115,7 @@ static void mesh_data_init_primitives(MeshData &mesh_data) for (int j = 0; j < 3; j++) { MeshUVVert uv_vert; uv_vert.loop = tri.tri[j]; - uv_vert.vertex = &mesh_data.vertices[mesh_data.mloop[uv_vert.loop].v]; + uv_vert.vertex = &mesh_data.vertices[mesh_data.loops[uv_vert.loop].v]; uv_vert.uv = mesh_data.mloopuv[uv_vert.loop].uv; primitive.vertices.append(uv_vert); } @@ -125,14 +125,14 @@ static void mesh_data_init_primitives(MeshData &mesh_data) static void mesh_data_init_edges(MeshData &mesh_data) { - mesh_data.edges.reserve(mesh_data.looptri_len * 2); - EdgeHash *eh = BLI_edgehash_new_ex(__func__, mesh_data.looptri_len * 3); - for (int64_t i = 0; i < mesh_data.looptri_len; i++) { - const MLoopTri &tri = mesh_data.looptri[i]; + mesh_data.edges.reserve(mesh_data.looptris.size() * 2); + EdgeHash *eh = BLI_edgehash_new_ex(__func__, mesh_data.looptris.size() * 3); + for (int64_t i = 0; i < mesh_data.looptris.size(); i++) { + const MLoopTri &tri = mesh_data.looptris[i]; MeshPrimitive &primitive = mesh_data.primitives[i]; for (int j = 0; j < 3; j++) { - int v1 = mesh_data.mloop[tri.tri[j]].v; - int v2 = mesh_data.mloop[tri.tri[(j + 1) % 3]].v; + int v1 = mesh_data.loops[tri.tri[j]].v; + int v2 = mesh_data.loops[tri.tri[(j + 1) % 3]].v; void **edge_index_ptr; int64_t edge_index; @@ -215,16 +215,11 @@ static void mesh_data_init(MeshData &mesh_data) mesh_data_init_primitive_uv_island_ids(mesh_data); } -MeshData::MeshData(const MLoopTri *looptri, - const int64_t looptri_len, - const int64_t vert_len, - const MLoop *mloop, - const MLoopUV *mloopuv) - : looptri(looptri), - looptri_len(looptri_len), - vert_len(vert_len), - mloop(mloop), - mloopuv(mloopuv) +MeshData::MeshData(const Span looptris, + const Span loops, + const int verts_num, + const Span mloopuv) + : looptris(looptris), verts_num(verts_num), loops(loops), mloopuv(mloopuv) { mesh_data_init(*this); } diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.hh b/source/blender/blenkernel/intern/pbvh_uv_islands.hh index a21afcdc562..4d81f5da00c 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.hh +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.hh @@ -92,11 +92,10 @@ struct MeshPrimitive { */ struct MeshData { public: - const MLoopTri *looptri; - const int64_t looptri_len; - const int64_t vert_len; - const MLoop *mloop; - const MLoopUV *mloopuv; + const Span looptris; + const int64_t verts_num; + const Span loops; + const Span mloopuv; Vector primitives; Vector edges; @@ -105,11 +104,10 @@ struct MeshData { int64_t uv_island_len; public: - explicit MeshData(const MLoopTri *looptri, - const int64_t looptri_len, - const int64_t vert_len, - const MLoop *mloop, - const MLoopUV *mloopuv); + explicit MeshData(const Span looptris, + const Span loops, + const int verts_num, + const Span mloopuv); }; struct UVVertex { From d17858cb37025c9732ef0987d2222e5de884bd95 Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Mon, 12 Dec 2022 15:56:50 +0100 Subject: [PATCH 0018/1522] Fix Cycles rectangular area light in volume segment sampled by ellipse --- intern/cycles/kernel/light/area.h | 5 +++-- intern/cycles/kernel/light/common.h | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/intern/cycles/kernel/light/area.h b/intern/cycles/kernel/light/area.h index 69cf810f800..9c0ca0c8a70 100644 --- a/intern/cycles/kernel/light/area.h +++ b/intern/cycles/kernel/light/area.h @@ -255,8 +255,9 @@ ccl_device_inline bool area_light_sample(const ccl_global KernelLight *klight, float3 inplane; if (in_volume_segment) { - /* FIXME: handle rectangular light. */ - inplane = ellipse_sample(axis_u * len_u * 0.5f, axis_v * len_v * 0.5f, randu, randv); + inplane = sample_rectangle ? + rectangle_sample(axis_u * len_u * 0.5f, axis_v * len_v * 0.5f, randu, randv) : + ellipse_sample(axis_u * len_u * 0.5f, axis_v * len_v * 0.5f, randu, randv); ls->P += inplane; ls->pdf = invarea; } diff --git a/intern/cycles/kernel/light/common.h b/intern/cycles/kernel/light/common.h index 5f0a3218ae1..9a08bbcf43a 100644 --- a/intern/cycles/kernel/light/common.h +++ b/intern/cycles/kernel/light/common.h @@ -34,6 +34,11 @@ ccl_device_inline float3 ellipse_sample(float3 ru, float3 rv, float randu, float return ru * randu + rv * randv; } +ccl_device_inline float3 rectangle_sample(float3 ru, float3 rv, float randu, float randv) +{ + return ru * (2.0f * randu - 1.0f) + rv * (2.0f * randv - 1.0f); +} + ccl_device float3 disk_light_sample(float3 v, float randu, float randv) { float3 ru, rv; From db68e2d4d3cc466198ec2f03fa0d03a6016d45f4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 12 Dec 2022 16:52:45 +0100 Subject: [PATCH 0019/1522] Build: install shaderc and vulkan libraries for Linux and macOS --- build_files/build_environment/cmake/harvest.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index 10d0c414303..2660d55d899 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -268,6 +268,10 @@ harvest(haru/include haru/include "*.h") harvest(haru/lib haru/lib "*.a") harvest(zstd/include zstd/include "*.h") harvest(zstd/lib zstd/lib "*.a") +harvest(shaderc shaderc "*") +harvest(vulkan_headers vulkan "*") +harvest_rpath_lib(vulkan_loader/lib vulkan/lib "*${SHAREDLIBEXT}*") +harvest(vulkan_loader/loader vulkan/loader "*") if(UNIX AND NOT APPLE) harvest(libglu/lib mesa/lib "*${SHAREDLIBEXT}*") From dbd3822329f16b24d46ac1336a792cb4f6b8a92e Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 12 Dec 2022 16:06:23 +0100 Subject: [PATCH 0020/1522] Cleanup: Extract asset test class into own header This manages setting up asset library directories for testing, which is useful for testing multiple asset library related compontents. So move it to a common header. No reason to squeeze everything into one file then. --- source/blender/asset_system/CMakeLists.txt | 4 +- .../asset_system/tests/asset_catalog_test.cc | 55 +------------- .../tests/asset_library_test_common.hh | 76 +++++++++++++++++++ 3 files changed, 82 insertions(+), 53 deletions(-) create mode 100644 source/blender/asset_system/tests/asset_library_test_common.hh diff --git a/source/blender/asset_system/CMakeLists.txt b/source/blender/asset_system/CMakeLists.txt index de1f41667d5..6f4e058e78d 100644 --- a/source/blender/asset_system/CMakeLists.txt +++ b/source/blender/asset_system/CMakeLists.txt @@ -46,10 +46,12 @@ blender_add_lib(bf_asset_system "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") if(WITH_GTESTS) set(TEST_SRC - tests/asset_catalog_test.cc tests/asset_catalog_path_test.cc + tests/asset_catalog_test.cc tests/asset_library_service_test.cc tests/asset_library_test.cc + + tests/asset_library_test_common.hh ) set(TEST_LIB bf_asset_system diff --git a/source/blender/asset_system/tests/asset_catalog_test.cc b/source/blender/asset_system/tests/asset_catalog_test.cc index 0a051bfd51f..144912d62a1 100644 --- a/source/blender/asset_system/tests/asset_catalog_test.cc +++ b/source/blender/asset_system/tests/asset_catalog_test.cc @@ -17,6 +17,8 @@ #include "testing/testing.h" +#include "asset_library_test_common.hh" + namespace blender::asset_system::tests { /* UUIDs from lib/tests/asset_library/blender_assets.cats.txt */ @@ -76,59 +78,8 @@ class TestableAssetCatalogService : public AssetCatalogService { } }; -class AssetCatalogTest : public testing::Test { +class AssetCatalogTest : public AssetLibraryTestBase { protected: - CatalogFilePath asset_library_root_; - CatalogFilePath temp_library_path_; - - static void SetUpTestSuite() - { - testing::Test::SetUpTestSuite(); - CLG_init(); - } - - static void TearDownTestSuite() - { - CLG_exit(); - testing::Test::TearDownTestSuite(); - } - - void SetUp() override - { - const std::string test_files_dir = blender::tests::flags_test_asset_dir(); - if (test_files_dir.empty()) { - FAIL(); - } - - asset_library_root_ = test_files_dir + SEP_STR + "asset_library"; - temp_library_path_ = ""; - } - - void TearDown() override - { - if (!temp_library_path_.empty()) { - BLI_delete(temp_library_path_.c_str(), true, true); - temp_library_path_ = ""; - } - } - - /* Register a temporary path, which will be removed at the end of the test. - * The returned path ends in a slash. */ - CatalogFilePath use_temp_path() - { - BKE_tempdir_init(""); - const CatalogFilePath tempdir = BKE_tempdir_session(); - temp_library_path_ = tempdir + "test-temporary-path" + SEP_STR; - return temp_library_path_; - } - - CatalogFilePath create_temp_path() - { - CatalogFilePath path = use_temp_path(); - BLI_dir_create_recursive(path.c_str()); - return path; - } - void assert_expected_item(const AssetCatalogPath &expected_path, const AssetCatalogTreeItem &actual_item) { diff --git a/source/blender/asset_system/tests/asset_library_test_common.hh b/source/blender/asset_system/tests/asset_library_test_common.hh new file mode 100644 index 00000000000..d8a8966487f --- /dev/null +++ b/source/blender/asset_system/tests/asset_library_test_common.hh @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#pragma once + +#include + +#include "BKE_appdir.h" + +#include "BLI_fileops.h" +#include "BLI_path_util.h" + +#include "CLG_log.h" + +#include "testing/testing.h" + +namespace blender::asset_system::tests { + +/** + * Functionality to setup and access directories on disk within which asset library related testing + * can be done. + */ +class AssetLibraryTestBase : public testing::Test { + protected: + std::string asset_library_root_; + std::string temp_library_path_; + + static void SetUpTestSuite() + { + testing::Test::SetUpTestSuite(); + CLG_init(); + } + + static void TearDownTestSuite() + { + CLG_exit(); + testing::Test::TearDownTestSuite(); + } + + void SetUp() override + { + const std::string test_files_dir = blender::tests::flags_test_asset_dir(); + if (test_files_dir.empty()) { + FAIL(); + } + + asset_library_root_ = test_files_dir + SEP_STR + "asset_library"; + temp_library_path_ = ""; + } + + void TearDown() override + { + if (!temp_library_path_.empty()) { + BLI_delete(temp_library_path_.c_str(), true, true); + temp_library_path_ = ""; + } + } + + /* Register a temporary path, which will be removed at the end of the test. + * The returned path ends in a slash. */ + std::string use_temp_path() + { + BKE_tempdir_init(""); + const std::string tempdir = BKE_tempdir_session(); + temp_library_path_ = tempdir + "test-temporary-path" + SEP_STR; + return temp_library_path_; + } + + std::string create_temp_path() + { + std::string path = use_temp_path(); + BLI_dir_create_recursive(path.c_str()); + return path; + } +}; + +} // namespace blender::asset_system::tests From 85d92afbd4dd961327191ecc68579d25a8e653ea Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Mon, 12 Dec 2022 17:07:55 +0100 Subject: [PATCH 0021/1522] Cleanup: Move asset catalog tree tests to own file The catalog tree is a unit on its own, and should be tested separately. This makes the testing files smaller and more focused, which can help maintaining them. --- source/blender/asset_system/CMakeLists.txt | 1 + .../asset_system/tests/asset_catalog_test.cc | 218 +--------------- .../tests/asset_catalog_tree_test.cc | 241 ++++++++++++++++++ .../tests/asset_library_test_common.hh | 33 +++ 4 files changed, 277 insertions(+), 216 deletions(-) create mode 100644 source/blender/asset_system/tests/asset_catalog_tree_test.cc diff --git a/source/blender/asset_system/CMakeLists.txt b/source/blender/asset_system/CMakeLists.txt index 6f4e058e78d..f8e1df40d80 100644 --- a/source/blender/asset_system/CMakeLists.txt +++ b/source/blender/asset_system/CMakeLists.txt @@ -48,6 +48,7 @@ if(WITH_GTESTS) set(TEST_SRC tests/asset_catalog_path_test.cc tests/asset_catalog_test.cc + tests/asset_catalog_tree_test.cc tests/asset_library_service_test.cc tests/asset_library_test.cc diff --git a/source/blender/asset_system/tests/asset_catalog_test.cc b/source/blender/asset_system/tests/asset_catalog_test.cc index 144912d62a1..87819f3683b 100644 --- a/source/blender/asset_system/tests/asset_catalog_test.cc +++ b/source/blender/asset_system/tests/asset_catalog_test.cc @@ -80,77 +80,6 @@ class TestableAssetCatalogService : public AssetCatalogService { class AssetCatalogTest : public AssetLibraryTestBase { protected: - void assert_expected_item(const AssetCatalogPath &expected_path, - const AssetCatalogTreeItem &actual_item) - { - if (expected_path != actual_item.catalog_path().str()) { - /* This will fail, but with a nicer error message than just calling FAIL(). */ - EXPECT_EQ(expected_path, actual_item.catalog_path()); - return; - } - - /* Is the catalog name as expected? "character", "Ellie", ... */ - EXPECT_EQ(expected_path.name(), actual_item.get_name()); - - /* Does the computed number of parents match? */ - const std::string expected_path_str = expected_path.str(); - const size_t expected_parent_count = std::count( - expected_path_str.begin(), expected_path_str.end(), AssetCatalogPath::SEPARATOR); - EXPECT_EQ(expected_parent_count, actual_item.count_parents()); - } - - /** - * Recursively iterate over all tree items using #AssetCatalogTree::foreach_item() and check if - * the items map exactly to \a expected_paths. - */ - void assert_expected_tree_items(AssetCatalogTree *tree, - const std::vector &expected_paths) - { - int i = 0; - tree->foreach_item([&](const AssetCatalogTreeItem &actual_item) { - ASSERT_LT(i, expected_paths.size()) - << "More catalogs in tree than expected; did not expect " << actual_item.catalog_path(); - assert_expected_item(expected_paths[i], actual_item); - i++; - }); - } - - /** - * Iterate over the root items of \a tree and check if the items map exactly to \a - * expected_paths. Similar to #assert_expected_tree_items() but calls - * #AssetCatalogTree::foreach_root_item() instead of #AssetCatalogTree::foreach_item(). - */ - void assert_expected_tree_root_items(AssetCatalogTree *tree, - const std::vector &expected_paths) - { - int i = 0; - tree->foreach_root_item([&](const AssetCatalogTreeItem &actual_item) { - ASSERT_LT(i, expected_paths.size()) - << "More catalogs in tree root than expected; did not expect " - << actual_item.catalog_path(); - assert_expected_item(expected_paths[i], actual_item); - i++; - }); - } - - /** - * Iterate over the child items of \a parent_item and check if the items map exactly to \a - * expected_paths. Similar to #assert_expected_tree_items() but calls - * #AssetCatalogTreeItem::foreach_child() instead of #AssetCatalogTree::foreach_item(). - */ - void assert_expected_tree_item_child_items(AssetCatalogTreeItem *parent_item, - const std::vector &expected_paths) - { - int i = 0; - parent_item->foreach_child([&](const AssetCatalogTreeItem &actual_item) { - ASSERT_LT(i, expected_paths.size()) - << "More catalogs in tree item than expected; did not expect " - << actual_item.catalog_path(); - assert_expected_item(expected_paths[i], actual_item); - i++; - }); - } - /* Used by on_blendfile_save__from_memory_into_existing_asset_lib* test functions. */ void save_from_memory_into_existing_asset_lib(const bool should_top_level_cdf_exist) { @@ -307,149 +236,6 @@ TEST_F(AssetCatalogTest, is_first_loaded_flag) << "The first-seen definition of a catalog should be returned"; } -TEST_F(AssetCatalogTest, insert_item_into_tree) -{ - { - AssetCatalogTree tree; - std::unique_ptr catalog_empty_path = AssetCatalog::from_path(""); - tree.insert_item(*catalog_empty_path); - - assert_expected_tree_items(&tree, {}); - } - - { - AssetCatalogTree tree; - - std::unique_ptr catalog = AssetCatalog::from_path("item"); - tree.insert_item(*catalog); - assert_expected_tree_items(&tree, {"item"}); - - /* Insert child after parent already exists. */ - std::unique_ptr child_catalog = AssetCatalog::from_path("item/child"); - tree.insert_item(*catalog); - assert_expected_tree_items(&tree, {"item", "item/child"}); - - std::vector expected_paths; - - /* Test inserting multi-component sub-path. */ - std::unique_ptr grandgrandchild_catalog = AssetCatalog::from_path( - "item/child/grandchild/grandgrandchild"); - tree.insert_item(*catalog); - expected_paths = { - "item", "item/child", "item/child/grandchild", "item/child/grandchild/grandgrandchild"}; - assert_expected_tree_items(&tree, expected_paths); - - std::unique_ptr root_level_catalog = AssetCatalog::from_path("root level"); - tree.insert_item(*catalog); - expected_paths = {"item", - "item/child", - "item/child/grandchild", - "item/child/grandchild/grandgrandchild", - "root level"}; - assert_expected_tree_items(&tree, expected_paths); - } - - { - AssetCatalogTree tree; - - std::unique_ptr catalog = AssetCatalog::from_path("item/child"); - tree.insert_item(*catalog); - assert_expected_tree_items(&tree, {"item", "item/child"}); - } - - { - AssetCatalogTree tree; - - std::unique_ptr catalog = AssetCatalog::from_path("white space"); - tree.insert_item(*catalog); - assert_expected_tree_items(&tree, {"white space"}); - } - - { - AssetCatalogTree tree; - - std::unique_ptr catalog = AssetCatalog::from_path("/item/white space"); - tree.insert_item(*catalog); - assert_expected_tree_items(&tree, {"item", "item/white space"}); - } - - { - AssetCatalogTree tree; - - std::unique_ptr catalog_unicode_path = AssetCatalog::from_path("Ružena"); - tree.insert_item(*catalog_unicode_path); - assert_expected_tree_items(&tree, {"Ružena"}); - - catalog_unicode_path = AssetCatalog::from_path("Ružena/Ružena"); - tree.insert_item(*catalog_unicode_path); - assert_expected_tree_items(&tree, {"Ružena", "Ružena/Ružena"}); - } -} - -TEST_F(AssetCatalogTest, load_single_file_into_tree) -{ - AssetCatalogService service(asset_library_root_); - service.load_from_disk(asset_library_root_ + SEP_STR + "blender_assets.cats.txt"); - - /* Contains not only paths from the CDF but also the missing parents (implicitly defined - * catalogs). */ - std::vector expected_paths{ - "character", - "character/Ellie", - "character/Ellie/backslashes", - "character/Ellie/poselib", - "character/Ellie/poselib/tailslash", - "character/Ellie/poselib/white space", - "character/Ružena", - "character/Ružena/poselib", - "character/Ružena/poselib/face", - "character/Ružena/poselib/hand", - "path", /* Implicit. */ - "path/without", /* Implicit. */ - "path/without/simplename", /* From CDF. */ - }; - - AssetCatalogTree *tree = service.get_catalog_tree(); - assert_expected_tree_items(tree, expected_paths); -} - -TEST_F(AssetCatalogTest, foreach_in_tree) -{ - { - AssetCatalogTree tree{}; - const std::vector no_catalogs{}; - - assert_expected_tree_items(&tree, no_catalogs); - assert_expected_tree_root_items(&tree, no_catalogs); - /* Need a root item to check child items. */ - std::unique_ptr catalog = AssetCatalog::from_path("something"); - tree.insert_item(*catalog); - tree.foreach_root_item([&no_catalogs, this](AssetCatalogTreeItem &item) { - assert_expected_tree_item_child_items(&item, no_catalogs); - }); - } - - AssetCatalogService service(asset_library_root_); - service.load_from_disk(asset_library_root_ + SEP_STR + "blender_assets.cats.txt"); - - std::vector expected_root_items{{"character", "path"}}; - AssetCatalogTree *tree = service.get_catalog_tree(); - assert_expected_tree_root_items(tree, expected_root_items); - - /* Test if the direct children of the root item are what's expected. */ - std::vector> expected_root_child_items = { - /* Children of the "character" root item. */ - {"character/Ellie", "character/Ružena"}, - /* Children of the "path" root item. */ - {"path/without"}, - }; - int i = 0; - tree->foreach_root_item([&expected_root_child_items, &i, this](AssetCatalogTreeItem &item) { - assert_expected_tree_item_child_items(&item, expected_root_child_items[i]); - i++; - }); -} - TEST_F(AssetCatalogTest, find_catalog_by_path) { TestableAssetCatalogService service(asset_library_root_); @@ -783,7 +569,7 @@ TEST_F(AssetCatalogTest, delete_catalog_leaf) }; AssetCatalogTree *tree = service.get_catalog_tree(); - assert_expected_tree_items(tree, expected_paths); + AssetCatalogTreeTestFunctions::expect_tree_items(tree, expected_paths); } TEST_F(AssetCatalogTest, delete_catalog_parent_by_id) @@ -837,7 +623,7 @@ TEST_F(AssetCatalogTest, delete_catalog_parent_by_path) }; AssetCatalogTree *tree = service.get_catalog_tree(); - assert_expected_tree_items(tree, expected_paths); + AssetCatalogTreeTestFunctions::expect_tree_items(tree, expected_paths); } TEST_F(AssetCatalogTest, delete_catalog_write_to_disk) diff --git a/source/blender/asset_system/tests/asset_catalog_tree_test.cc b/source/blender/asset_system/tests/asset_catalog_tree_test.cc new file mode 100644 index 00000000000..fb1cbde517d --- /dev/null +++ b/source/blender/asset_system/tests/asset_catalog_tree_test.cc @@ -0,0 +1,241 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2020 Blender Foundation. All rights reserved. */ + +#include "AS_asset_catalog.hh" +#include "AS_asset_catalog_tree.hh" + +#include "BKE_appdir.h" +#include "BKE_preferences.h" + +#include "BLI_fileops.h" +#include "BLI_path_util.h" + +#include "DNA_asset_types.h" +#include "DNA_userdef_types.h" + +#include "CLG_log.h" + +#include "testing/testing.h" + +#include "asset_library_test_common.hh" + +namespace blender::asset_system::tests { + +static void compare_item_with_path(const AssetCatalogPath &expected_path, + const AssetCatalogTreeItem &actual_item) +{ + if (expected_path != actual_item.catalog_path().str()) { + /* This will fail, but with a nicer error message than just calling FAIL(). */ + EXPECT_EQ(expected_path, actual_item.catalog_path()); + return; + } + + /* Is the catalog name as expected? "character", "Ellie", ... */ + EXPECT_EQ(expected_path.name(), actual_item.get_name()); + + /* Does the computed number of parents match? */ + const std::string expected_path_str = expected_path.str(); + const size_t expected_parent_count = std::count( + expected_path_str.begin(), expected_path_str.end(), AssetCatalogPath::SEPARATOR); + EXPECT_EQ(expected_parent_count, actual_item.count_parents()); +} + +/** + * Recursively iterate over all tree items using #AssetCatalogTree::foreach_item() and check if + * the items map exactly to \a expected_paths. + */ +void AssetCatalogTreeTestFunctions::expect_tree_items( + AssetCatalogTree *tree, const std::vector &expected_paths) +{ + int i = 0; + tree->foreach_item([&](const AssetCatalogTreeItem &actual_item) { + ASSERT_LT(i, expected_paths.size()) + << "More catalogs in tree than expected; did not expect " << actual_item.catalog_path(); + compare_item_with_path(expected_paths[i], actual_item); + i++; + }); +} + +/** + * Iterate over the root items of \a tree and check if the items map exactly to \a + * expected_paths. Similar to #assert_expected_tree_items() but calls + * #AssetCatalogTree::foreach_root_item() instead of #AssetCatalogTree::foreach_item(). + */ +void AssetCatalogTreeTestFunctions::expect_tree_root_items( + AssetCatalogTree *tree, const std::vector &expected_paths) +{ + int i = 0; + tree->foreach_root_item([&](const AssetCatalogTreeItem &actual_item) { + ASSERT_LT(i, expected_paths.size()) + << "More catalogs in tree root than expected; did not expect " + << actual_item.catalog_path(); + compare_item_with_path(expected_paths[i], actual_item); + i++; + }); +} + +/** + * Iterate over the child items of \a parent_item and check if the items map exactly to \a + * expected_paths. Similar to #assert_expected_tree_items() but calls + * #AssetCatalogTreeItem::foreach_child() instead of #AssetCatalogTree::foreach_item(). + */ +void AssetCatalogTreeTestFunctions::expect_tree_item_child_items( + AssetCatalogTreeItem *parent_item, const std::vector &expected_paths) +{ + int i = 0; + parent_item->foreach_child([&](const AssetCatalogTreeItem &actual_item) { + ASSERT_LT(i, expected_paths.size()) + << "More catalogs in tree item than expected; did not expect " + << actual_item.catalog_path(); + compare_item_with_path(expected_paths[i], actual_item); + i++; + }); +} + +class AssetCatalogTreeTest : public AssetLibraryTestBase, public AssetCatalogTreeTestFunctions { +}; + +TEST_F(AssetCatalogTreeTest, insert_item_into_tree) +{ + { + AssetCatalogTree tree; + std::unique_ptr catalog_empty_path = AssetCatalog::from_path(""); + tree.insert_item(*catalog_empty_path); + + expect_tree_items(&tree, {}); + } + + { + AssetCatalogTree tree; + + std::unique_ptr catalog = AssetCatalog::from_path("item"); + tree.insert_item(*catalog); + expect_tree_items(&tree, {"item"}); + + /* Insert child after parent already exists. */ + std::unique_ptr child_catalog = AssetCatalog::from_path("item/child"); + tree.insert_item(*catalog); + expect_tree_items(&tree, {"item", "item/child"}); + + std::vector expected_paths; + + /* Test inserting multi-component sub-path. */ + std::unique_ptr grandgrandchild_catalog = AssetCatalog::from_path( + "item/child/grandchild/grandgrandchild"); + tree.insert_item(*catalog); + expected_paths = { + "item", "item/child", "item/child/grandchild", "item/child/grandchild/grandgrandchild"}; + expect_tree_items(&tree, expected_paths); + + std::unique_ptr root_level_catalog = AssetCatalog::from_path("root level"); + tree.insert_item(*catalog); + expected_paths = {"item", + "item/child", + "item/child/grandchild", + "item/child/grandchild/grandgrandchild", + "root level"}; + expect_tree_items(&tree, expected_paths); + } + + { + AssetCatalogTree tree; + + std::unique_ptr catalog = AssetCatalog::from_path("item/child"); + tree.insert_item(*catalog); + expect_tree_items(&tree, {"item", "item/child"}); + } + + { + AssetCatalogTree tree; + + std::unique_ptr catalog = AssetCatalog::from_path("white space"); + tree.insert_item(*catalog); + expect_tree_items(&tree, {"white space"}); + } + + { + AssetCatalogTree tree; + + std::unique_ptr catalog = AssetCatalog::from_path("/item/white space"); + tree.insert_item(*catalog); + expect_tree_items(&tree, {"item", "item/white space"}); + } + + { + AssetCatalogTree tree; + + std::unique_ptr catalog_unicode_path = AssetCatalog::from_path("Ružena"); + tree.insert_item(*catalog_unicode_path); + expect_tree_items(&tree, {"Ružena"}); + + catalog_unicode_path = AssetCatalog::from_path("Ružena/Ružena"); + tree.insert_item(*catalog_unicode_path); + expect_tree_items(&tree, {"Ružena", "Ružena/Ružena"}); + } +} + +TEST_F(AssetCatalogTreeTest, load_single_file_into_tree) +{ + AssetCatalogService service(asset_library_root_); + service.load_from_disk(asset_library_root_ + SEP_STR + "blender_assets.cats.txt"); + + /* Contains not only paths from the CDF but also the missing parents (implicitly defined + * catalogs). */ + std::vector expected_paths{ + "character", + "character/Ellie", + "character/Ellie/backslashes", + "character/Ellie/poselib", + "character/Ellie/poselib/tailslash", + "character/Ellie/poselib/white space", + "character/Ružena", + "character/Ružena/poselib", + "character/Ružena/poselib/face", + "character/Ružena/poselib/hand", + "path", /* Implicit. */ + "path/without", /* Implicit. */ + "path/without/simplename", /* From CDF. */ + }; + + AssetCatalogTree *tree = service.get_catalog_tree(); + expect_tree_items(tree, expected_paths); +} + +TEST_F(AssetCatalogTreeTest, foreach_in_tree) +{ + { + AssetCatalogTree tree{}; + const std::vector no_catalogs{}; + + expect_tree_items(&tree, no_catalogs); + expect_tree_root_items(&tree, no_catalogs); + /* Need a root item to check child items. */ + std::unique_ptr catalog = AssetCatalog::from_path("something"); + tree.insert_item(*catalog); + tree.foreach_root_item([&no_catalogs](AssetCatalogTreeItem &item) { + expect_tree_item_child_items(&item, no_catalogs); + }); + } + + AssetCatalogService service(asset_library_root_); + service.load_from_disk(asset_library_root_ + SEP_STR + "blender_assets.cats.txt"); + + std::vector expected_root_items{{"character", "path"}}; + AssetCatalogTree *tree = service.get_catalog_tree(); + expect_tree_root_items(tree, expected_root_items); + + /* Test if the direct children of the root item are what's expected. */ + std::vector> expected_root_child_items = { + /* Children of the "character" root item. */ + {"character/Ellie", "character/Ružena"}, + /* Children of the "path" root item. */ + {"path/without"}, + }; + int i = 0; + tree->foreach_root_item([&expected_root_child_items, &i](AssetCatalogTreeItem &item) { + expect_tree_item_child_items(&item, expected_root_child_items[i]); + i++; + }); +} + +} // namespace blender::asset_system::tests diff --git a/source/blender/asset_system/tests/asset_library_test_common.hh b/source/blender/asset_system/tests/asset_library_test_common.hh index d8a8966487f..1a6428b4fa9 100644 --- a/source/blender/asset_system/tests/asset_library_test_common.hh +++ b/source/blender/asset_system/tests/asset_library_test_common.hh @@ -3,6 +3,7 @@ #pragma once #include +#include #include "BKE_appdir.h" @@ -13,6 +14,12 @@ #include "testing/testing.h" +namespace blender::asset_system { +class AssetCatalogTree; +class AssetCatalogTreeItem; +class AssetCatalogPath; +} // namespace blender::asset_system + namespace blender::asset_system::tests { /** @@ -73,4 +80,30 @@ class AssetLibraryTestBase : public testing::Test { } }; +class AssetCatalogTreeTestFunctions { + public: + /** + * Recursively iterate over all tree items using #AssetCatalogTree::foreach_item() and check if + * the items map exactly to \a expected_paths. + */ + static void expect_tree_items(AssetCatalogTree *tree, + const std::vector &expected_paths); + + /** + * Iterate over the root items of \a tree and check if the items map exactly to \a + * expected_paths. Similar to #assert_expected_tree_items() but calls + * #AssetCatalogTree::foreach_root_item() instead of #AssetCatalogTree::foreach_item(). + */ + static void expect_tree_root_items(AssetCatalogTree *tree, + const std::vector &expected_paths); + + /** + * Iterate over the child items of \a parent_item and check if the items map exactly to \a + * expected_paths. Similar to #assert_expected_tree_items() but calls + * #AssetCatalogTreeItem::foreach_child() instead of #AssetCatalogTree::foreach_item(). + */ + static void expect_tree_item_child_items(AssetCatalogTreeItem *parent_item, + const std::vector &expected_paths); +}; + } // namespace blender::asset_system::tests From 014ffc4615b8fc04ef37e9147074c0c86e347b06 Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Mon, 12 Dec 2022 17:07:57 +0100 Subject: [PATCH 0022/1522] Cycles: using concentric mapping when sampling disk --- intern/cycles/kernel/light/common.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intern/cycles/kernel/light/common.h b/intern/cycles/kernel/light/common.h index 9a08bbcf43a..bd2803eeade 100644 --- a/intern/cycles/kernel/light/common.h +++ b/intern/cycles/kernel/light/common.h @@ -30,8 +30,8 @@ typedef struct LightSample { ccl_device_inline float3 ellipse_sample(float3 ru, float3 rv, float randu, float randv) { - to_unit_disk(&randu, &randv); - return ru * randu + rv * randv; + const float2 rand = concentric_sample_disk(randu, randv); + return ru * rand.x + rv * rand.y; } ccl_device_inline float3 rectangle_sample(float3 ru, float3 rv, float randu, float randv) From d72c7eefd1c5784191d100ada3587acc5011ec72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 12 Dec 2022 17:36:36 +0100 Subject: [PATCH 0023/1522] Fix T101522: Animation: motion path range overwritten by 'Update Paths' Expand the motion path frame range options with an extra option "Manual Range". When chosen, Blender will not automatically update the path range any more. Additionally, the start/end frame fields are greyed out in the UI when one of the automatic range options is selected (i.e. all but the new "Manual Range" one). It is still possible to set the start/end frame temporarily, but the original behaviour (of recomputing those on update) remains. Manifest Task: T101522 --- release/scripts/startup/bl_ui/properties_animviz.py | 6 ++++-- source/blender/editors/animation/anim_motion_paths.c | 8 ++++++++ source/blender/makesdna/DNA_action_types.h | 1 + source/blender/makesrna/intern/rna_animviz.c | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py index 3062b84bd70..aa16a7c9bb8 100644 --- a/release/scripts/startup/bl_ui/properties_animviz.py +++ b/release/scripts/startup/bl_ui/properties_animviz.py @@ -32,8 +32,10 @@ class MotionPathButtonsPanel: col.prop(mps, "frame_step", text="Step") elif mps.type == 'RANGE': col = layout.column(align=True) - col.prop(mps, "frame_start", text="Frame Range Start") - col.prop(mps, "frame_end", text="End") + start_end_group = col.column(align=True) + start_end_group.active = mps.range == 'MANUAL' + start_end_group.prop(mps, "frame_start", text="Frame Range Start") + start_end_group.prop(mps, "frame_end", text="End") col.prop(mps, "frame_step", text="Step") # Calculation Range diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c index 4a83bb4c800..5cabb4fd014 100644 --- a/source/blender/editors/animation/anim_motion_paths.c +++ b/source/blender/editors/animation/anim_motion_paths.c @@ -344,9 +344,16 @@ void animviz_motionpath_compute_range(Object *ob, Scene *scene) { bAnimVizSettings *avs = ob->mode == OB_MODE_POSE ? &ob->pose->avs : &ob->avs; + if (avs->path_range == MOTIONPATH_RANGE_MANUAL) { + /* Don't touch manually-determined ranges. */ + return; + } + const bool has_action = ob->adt && ob->adt->action; if (avs->path_range == MOTIONPATH_RANGE_SCENE || !has_action || BLI_listbase_is_empty(&ob->adt->action->curves)) { + /* Default to the scene (preview) range if there is no animation data to + * find selected keys in. */ avs->path_sf = PSFRA; avs->path_ef = PEFRA; return; @@ -367,6 +374,7 @@ void animviz_motionpath_compute_range(Object *ob, Scene *scene) case MOTIONPATH_RANGE_KEYS_ALL: ED_keylist_all_keys_frame_range(keylist, &frame_range); break; + case MOTIONPATH_RANGE_MANUAL: case MOTIONPATH_RANGE_SCENE: BLI_assert_msg(false, "This should not happen, function should have exited earlier."); }; diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 53e87e905b5..481c9f5e673 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -139,6 +139,7 @@ typedef enum eMotionPath_Ranges { MOTIONPATH_RANGE_SCENE = 0, MOTIONPATH_RANGE_KEYS_SELECTED = 1, MOTIONPATH_RANGE_KEYS_ALL = 2, + MOTIONPATH_RANGE_MANUAL = 3, } eMotionPath_Ranges; /* bAnimVizSettings->path_viewflag */ diff --git a/source/blender/makesrna/intern/rna_animviz.c b/source/blender/makesrna/intern/rna_animviz.c index 96332788abe..887fa662e97 100644 --- a/source/blender/makesrna/intern/rna_animviz.c +++ b/source/blender/makesrna/intern/rna_animviz.c @@ -58,6 +58,7 @@ const EnumPropertyItem rna_enum_motionpath_range_items[] = { "Selected Keys", "From the first selected keyframe to the last"}, {MOTIONPATH_RANGE_SCENE, "SCENE", 0, "Scene Frame Range", "The entire Scene / Preview range"}, + {MOTIONPATH_RANGE_MANUAL, "MANUAL", 0, "Manual Range", "Manually determined frame range"}, {0, NULL, 0, NULL, NULL}, }; From 54aec4629ecd5d679daff167fc9eb7b7d99a3daa Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Mon, 12 Dec 2022 18:15:41 +0100 Subject: [PATCH 0024/1522] Cleanup: Remove unused code in Cycles * preempt_attr was copied from CUDA, but not used in HIP. * Remove shadowed variable before conditional in EnvironmentTextureNode code. Differential Revision: https://developer.blender.org/D16741 --- intern/cycles/device/hip/device.cpp | 4 ++-- intern/cycles/scene/light.cpp | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/intern/cycles/device/hip/device.cpp b/intern/cycles/device/hip/device.cpp index 518239f9877..d3566347834 100644 --- a/intern/cycles/device/hip/device.cpp +++ b/intern/cycles/device/hip/device.cpp @@ -163,10 +163,10 @@ void device_hip_info(vector &devices) /* If device has a kernel timeout and no compute preemption, we assume * it is connected to a display and will freeze the display while doing * computations. */ - int timeout_attr = 0, preempt_attr = 0; + int timeout_attr = 0; hipDeviceGetAttribute(&timeout_attr, hipDeviceAttributeKernelExecTimeout, num); - if (timeout_attr && !preempt_attr) { + if (timeout_attr) { VLOG_INFO << "Device is recognized as display."; info.description += " (Display)"; info.display_device = true; diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index f6e9098cd2b..b8addeaffd6 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -726,7 +726,6 @@ void LightManager::device_update_background(Device *device, foreach (ShaderNode *node, shader->graph->nodes) { if (node->type == EnvironmentTextureNode::get_node_type()) { EnvironmentTextureNode *env = (EnvironmentTextureNode *)node; - ImageMetaData metadata; if (!env->handle.empty()) { ImageMetaData metadata = env->handle.metadata(); environment_res.x = max(environment_res.x, (int)metadata.width); From f95de78ca2f14ad42bf06dae71ae0122045e31a9 Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Mon, 12 Dec 2022 17:16:08 +0100 Subject: [PATCH 0025/1522] Fix memory leak in lite build with animation rendering Differential Revision: https://developer.blender.org/D16745 --- source/blender/render/intern/pipeline.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/render/intern/pipeline.cc b/source/blender/render/intern/pipeline.cc index c3a6aa95700..4a926bb47cd 100644 --- a/source/blender/render/intern/pipeline.cc +++ b/source/blender/render/intern/pipeline.cc @@ -2126,6 +2126,7 @@ void RE_RenderAnim(Render *re, mh = BKE_movie_handle_get(rd.im_format.imtype); if (mh == nullptr) { + render_pipeline_free(re); BKE_report(re->reports, RPT_ERROR, "Movie format unsupported"); return; } From 18abc2feaad6ccf162ee4a254405f854f705d101 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 12 Dec 2022 17:22:04 +0100 Subject: [PATCH 0026/1522] Fix Cycles light tree not working with negative light strength Use absolute value of emission as estimate to make this work. Contributed by Alaska. Differential Revision: https://developer.blender.org/D16718 --- intern/cycles/scene/light_tree.cpp | 4 +++- intern/cycles/scene/shader.cpp | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index 9bf4bdca097..f9bd479cf1c 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -181,7 +181,9 @@ LightTreePrimitive::LightTreePrimitive(Scene *scene, int prim_id, int object_id) strength *= lamp->get_shader()->emission_estimate; } - energy = average(strength); + /* Use absolute value of energy so lights with negative strength are properly + * supported in the light tree. */ + energy = fabsf(average(strength)); } } diff --git a/intern/cycles/scene/shader.cpp b/intern/cycles/scene/shader.cpp index ca15d0e1c44..09255d7cee4 100644 --- a/intern/cycles/scene/shader.cpp +++ b/intern/cycles/scene/shader.cpp @@ -349,7 +349,7 @@ void Shader::estimate_emission() } ShaderInput *surf = graph->output()->input("Surface"); - emission_estimate = output_estimate_emission(surf->link, emission_is_constant); + emission_estimate = fabs(output_estimate_emission(surf->link, emission_is_constant)); if (is_zero(emission_estimate)) { emission_sampling = EMISSION_SAMPLING_NONE; From 312e42708f8073ef0882d11376c30dee5ac1aef8 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 12 Dec 2022 17:28:59 +0100 Subject: [PATCH 0027/1522] Fix T103066: Cycles missing full constant foler for mix float and mix vector --- intern/cycles/scene/constant_fold.cpp | 40 +++++++++++++++++++++++++++ intern/cycles/scene/constant_fold.h | 1 + intern/cycles/scene/shader_nodes.cpp | 6 ++++ 3 files changed, 47 insertions(+) diff --git a/intern/cycles/scene/constant_fold.cpp b/intern/cycles/scene/constant_fold.cpp index 1aa4515a087..224c8774cc6 100644 --- a/intern/cycles/scene/constant_fold.cpp +++ b/intern/cycles/scene/constant_fold.cpp @@ -386,6 +386,46 @@ void ConstantFolder::fold_mix_color(NodeMix type, bool clamp_factor, bool clamp) } } +void ConstantFolder::fold_mix_float(bool clamp_factor, bool clamp) const +{ + ShaderInput *fac_in = node->input("Factor"); + ShaderInput *float1_in = node->input("A"); + ShaderInput *float2_in = node->input("B"); + + float fac = clamp_factor ? saturatef(node->get_float(fac_in->socket_type)) : + node->get_float(fac_in->socket_type); + bool fac_is_zero = !fac_in->link && fac == 0.0f; + bool fac_is_one = !fac_in->link && fac == 1.0f; + + /* remove no-op node when factor is 0.0 */ + if (fac_is_zero) { + if (try_bypass_or_make_constant(float1_in, clamp)) { + return; + } + } + + /* remove useless mix floats nodes */ + if (float1_in->link && float2_in->link) { + if (float1_in->link == float2_in->link) { + try_bypass_or_make_constant(float1_in, clamp); + return; + } + } + else if (!float1_in->link && !float2_in->link) { + float value1 = node->get_float(float1_in->socket_type); + float value2 = node->get_float(float2_in->socket_type); + if (value1 == value2) { + try_bypass_or_make_constant(float1_in, clamp); + return; + } + } + /* remove no-op mix float node when factor is 1.0 */ + if (fac_is_one) { + try_bypass_or_make_constant(float2_in, clamp); + return; + } +} + void ConstantFolder::fold_math(NodeMathType type) const { ShaderInput *value1_in = node->input("Value1"); diff --git a/intern/cycles/scene/constant_fold.h b/intern/cycles/scene/constant_fold.h index 246ff2d31ee..14097e1a0e4 100644 --- a/intern/cycles/scene/constant_fold.h +++ b/intern/cycles/scene/constant_fold.h @@ -52,6 +52,7 @@ class ConstantFolder { /* Specific nodes. */ void fold_mix(NodeMix type, bool clamp) const; void fold_mix_color(NodeMix type, bool clamp_factor, bool clamp) const; + void fold_mix_float(bool clamp_factor, bool clamp) const; void fold_math(NodeMathType type) const; void fold_vector_math(NodeVectorMathType type) const; void fold_mapping(NodeMappingType type) const; diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index f032c52c1af..a64953c03ec 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -5132,6 +5132,9 @@ void MixFloatNode::constant_fold(const ConstantFolder &folder) } folder.make_constant(a * (1 - fac) + b * fac); } + else { + folder.fold_mix_float(use_clamp, false); + } } /* Mix Vector */ @@ -5185,6 +5188,9 @@ void MixVectorNode::constant_fold(const ConstantFolder &folder) } folder.make_constant(a * (one_float3() - fac) + b * fac); } + else { + folder.fold_mix_color(NODE_MIX_BLEND, use_clamp, false); + } } /* Mix Vector Non Uniform */ From f53bd178366a95c3cef8c4b1b99b4d7a0cdcf4eb Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 12 Dec 2022 17:51:21 +0100 Subject: [PATCH 0028/1522] Cycles: take into account film exposure for light sampling threshold To avoid issues with lights being either skipped or sampled unnecessarily when the exposure is set low or high. Contributed by Alaska. Differential Revision: https://developer.blender.org/D16703 --- intern/cycles/scene/integrator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/scene/integrator.cpp b/intern/cycles/scene/integrator.cpp index 64af0dadaa6..1aaac121c31 100644 --- a/intern/cycles/scene/integrator.cpp +++ b/intern/cycles/scene/integrator.cpp @@ -253,7 +253,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene kintegrator->use_light_tree = scene->integrator->use_light_tree; if (light_sampling_threshold > 0.0f) { - kintegrator->light_inv_rr_threshold = 1.0f / light_sampling_threshold; + kintegrator->light_inv_rr_threshold = scene->film->get_exposure() / light_sampling_threshold; } else { kintegrator->light_inv_rr_threshold = 0.0f; From 95a792a6338b8c72cd186e029cdb6056303dc0bd Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 12 Dec 2022 17:52:51 +0100 Subject: [PATCH 0029/1522] Fix wrong Cycles standalone exposure default value, should be 1 --- intern/cycles/scene/film.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/scene/film.cpp b/intern/cycles/scene/film.cpp index cffa6acad59..67439b25868 100644 --- a/intern/cycles/scene/film.cpp +++ b/intern/cycles/scene/film.cpp @@ -88,7 +88,7 @@ NODE_DEFINE(Film) { NodeType *type = NodeType::add("film", create); - SOCKET_FLOAT(exposure, "Exposure", 0.8f); + SOCKET_FLOAT(exposure, "Exposure", 1.0f); SOCKET_FLOAT(pass_alpha_threshold, "Pass Alpha Threshold", 0.0f); static NodeEnum filter_enum; From e4f9c50928d36b5eb61b36f2393439bd2d72e004 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 12 Dec 2022 18:21:34 +0100 Subject: [PATCH 0030/1522] Fix T102990: OpenVDB files load very slow from network drives The OpenVDB delay loading of voxel leaf data using mmap works poorly on network drives. It has a mechanism to make a temporary local file copy to avoid this, but we disabled that as it leads to other problems. Now disable delay loading entirely. It's not clear that this has much benefit in Blender. For rendering we need to load the entire grid to convert to NanoVDB, and for geometry nodes there also are no cases where we only need part of grids. --- intern/cycles/hydra/field.cpp | 5 ++++- source/blender/blenkernel/intern/volume.cc | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/intern/cycles/hydra/field.cpp b/intern/cycles/hydra/field.cpp index 67945be9d52..7cdb4c80d79 100644 --- a/intern/cycles/hydra/field.cpp +++ b/intern/cycles/hydra/field.cpp @@ -26,9 +26,12 @@ class HdCyclesVolumeLoader : public VDBImageLoader { HdCyclesVolumeLoader(const std::string &filePath, const std::string &gridName) : VDBImageLoader(gridName) { + /* Disably delay loading and file copying, this has poor performance + * on network drivers. */ + const bool delay_load = false; openvdb::io::File file(filePath); file.setCopyMaxBytes(0); - if (file.open()) { + if (file.open(delay_load)) { grid = file.readGrid(gridName); } } diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index e81657f9ef0..ae921764de4 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -324,8 +324,11 @@ struct VolumeGrid { * holding a mutex lock. */ blender::threading::isolate_task([&] { try { + /* Disably delay loading and file copying, this has poor performance + * on network drivers. */ + const bool delay_load = false; file.setCopyMaxBytes(0); - file.open(); + file.open(delay_load); openvdb::GridBase::Ptr vdb_grid = file.readGrid(name()); entry->grid->setTree(vdb_grid->baseTreePtr()); } @@ -883,8 +886,11 @@ bool BKE_volume_load(const Volume *volume, const Main *bmain) openvdb::GridPtrVec vdb_grids; try { + /* Disably delay loading and file copying, this has poor performance + * on network drivers. */ + const bool delay_load = false; file.setCopyMaxBytes(0); - file.open(); + file.open(delay_load); vdb_grids = *(file.readAllGridMetadata()); grids.metadata = file.getMetadata(); } From 42def76831e043febd2188a9a7a06a438920b96f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 12 Dec 2022 13:40:06 -0600 Subject: [PATCH 0031/1522] Cleanup: Add a bit more detail to curves offsets comment --- source/blender/makesdna/DNA_curves_types.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/makesdna/DNA_curves_types.h b/source/blender/makesdna/DNA_curves_types.h index a72a9bf4c68..847a4b8a02c 100644 --- a/source/blender/makesdna/DNA_curves_types.h +++ b/source/blender/makesdna/DNA_curves_types.h @@ -97,10 +97,10 @@ typedef struct CurvesGeometry { * this array is allocated with a length one larger than the number of curves. This is allowed * to be null when there are no curves. * - * Every curve offset must be at least one larger than the previous. - * In other words, every curve must have at least one point. + * Every curve offset must be at least one larger than the previous. In other words, every curve + * must have at least one point. The first value is 0 and the last value is #point_num. * - * \note This is *not* stored in #CustomData because its size is one larger than #curve_data. + * \note This is *not* stored as an attribute because its size is one larger than #curve_num. */ int *curve_offsets; From e378bd70ed6cb255f9a1cc092b88515bbf25d37c Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Thu, 8 Dec 2022 12:56:49 +0100 Subject: [PATCH 0032/1522] Cleanup: remove code duplication in cycles light sampling There has been an attempt to reorganize this part, however, it seems that didn't compile on HIP, and is reverted in rBc2dc65dfa4ae60fa5d2c3b0cfe86f99dcb5bf16f. This is another attempt of refactoring. as I have no idea why some things don't work on HIP, it's best to check whether this compiles on other platforms. The main changes are creating a new struct named `MeshLight` that is shared between `KernelLightDistribution` and `KernelLightTreeEmitter`, and a bit of renaming, so that light sampling with or without light tree could call the same function. Also, I noticed a patch D16714 referring to HIP compilation error. Not sure if it's related, but browsing https://builder.blender.org/admin/#/builders/30/builds/7826/steps/7/logs/stdio, it didn't work on gfx1102, not gfx9*. Differential Revision: https://developer.blender.org/D16722 --- intern/cycles/kernel/light/distribution.h | 38 +----------- intern/cycles/kernel/light/light.h | 76 ++++++++++++++++++++--- intern/cycles/kernel/light/tree.h | 56 ++++------------- intern/cycles/kernel/light/triangle.h | 2 +- intern/cycles/kernel/types.h | 19 +++--- intern/cycles/scene/light.cpp | 10 ++- 6 files changed, 98 insertions(+), 103 deletions(-) diff --git a/intern/cycles/kernel/light/distribution.h b/intern/cycles/kernel/light/distribution.h index 2f75a53ec2a..97c60376748 100644 --- a/intern/cycles/kernel/light/distribution.h +++ b/intern/cycles/kernel/light/distribution.h @@ -59,41 +59,9 @@ ccl_device_noinline bool light_distribution_sample(KernelGlobals kg, { /* Sample light index from distribution. */ const int index = light_distribution_sample(kg, &randu); - ccl_global const KernelLightDistribution *kdistribution = &kernel_data_fetch(light_distribution, - index); - const int prim = kdistribution->prim; - - if (prim >= 0) { - /* Mesh light. */ - const int object = kdistribution->mesh_light.object_id; - - /* Exclude synthetic meshes from shadow catcher pass. */ - if ((path_flag & PATH_RAY_SHADOW_CATCHER_PASS) && - !(kernel_data_fetch(object_flag, object) & SD_OBJECT_SHADOW_CATCHER)) { - return false; - } - - const int shader_flag = kdistribution->mesh_light.shader_flag; - if (!triangle_light_sample(kg, prim, object, randu, randv, time, ls, P)) { - return false; - } - ls->shader |= shader_flag; - } - else { - const int lamp = -prim - 1; - - if (UNLIKELY(light_select_reached_max_bounces(kg, lamp, bounce))) { - return false; - } - - if (!light_sample(kg, lamp, randu, randv, P, path_flag, ls)) { - return false; - } - ls->pdf_selection = kernel_data.integrator.distribution_pdf_lights; - } - - ls->pdf *= ls->pdf_selection; - return (ls->pdf > 0.0f); + const float pdf_selection = kernel_data.integrator.distribution_pdf_lights; + return light_sample( + kg, randu, randv, time, P, bounce, path_flag, index, pdf_selection, ls); } ccl_device_inline float light_distribution_pdf_lamp(KernelGlobals kg) diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h index b33aecf8b62..d04bffe8f8b 100644 --- a/intern/cycles/kernel/light/light.h +++ b/intern/cycles/kernel/light/light.h @@ -14,6 +14,13 @@ CCL_NAMESPACE_BEGIN +/* Light info. */ + +ccl_device_inline bool light_select_reached_max_bounces(KernelGlobals kg, int index, int bounce) +{ + return (bounce > kernel_data_fetch(lights, index).max_bounces); +} + /* Sample point on an individual light. */ template @@ -90,6 +97,68 @@ ccl_device_inline bool light_sample(KernelGlobals kg, return in_volume_segment || (ls->pdf > 0.0f); } +/* Sample a point on the chosen emitter. */ + +template +ccl_device_noinline bool light_sample(KernelGlobals kg, + const float randu, + const float randv, + const float time, + const float3 P, + const int bounce, + const uint32_t path_flag, + const int emitter_index, + const float pdf_selection, + ccl_private LightSample *ls) +{ + int prim; + MeshLight mesh_light; + if (kernel_data.integrator.use_light_tree) { + ccl_global const KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters, + emitter_index); + prim = kemitter->prim; + mesh_light = kemitter->mesh_light; + } + else { + ccl_global const KernelLightDistribution *kdistribution = &kernel_data_fetch( + light_distribution, emitter_index); + prim = kdistribution->prim; + mesh_light = kdistribution->mesh_light; + } + + /* A different value would be assigned in `triangle_light_sample()` if `!use_light_tree`. */ + ls->pdf_selection = pdf_selection; + + if (prim >= 0) { + /* Mesh light. */ + const int object = mesh_light.object_id; + + /* Exclude synthetic meshes from shadow catcher pass. */ + if ((path_flag & PATH_RAY_SHADOW_CATCHER_PASS) && + !(kernel_data_fetch(object_flag, object) & SD_OBJECT_SHADOW_CATCHER)) { + return false; + } + + const int shader_flag = mesh_light.shader_flag; + if (!triangle_light_sample(kg, prim, object, randu, randv, time, ls, P)) { + return false; + } + ls->shader |= shader_flag; + } + else { + if (UNLIKELY(light_select_reached_max_bounces(kg, ~prim, bounce))) { + return false; + } + + if (!light_sample(kg, ~prim, randu, randv, P, path_flag, ls)) { + return false; + } + } + + ls->pdf *= ls->pdf_selection; + return (ls->pdf > 0.0f); +} + /* Intersect ray with individual light. */ ccl_device bool lights_intersect(KernelGlobals kg, @@ -230,11 +299,4 @@ ccl_device_forceinline void light_update_position(KernelGlobals kg, } } -/* Light info. */ - -ccl_device_inline bool light_select_reached_max_bounces(KernelGlobals kg, int index, int bounce) -{ - return (bounce > kernel_data_fetch(lights, index).max_bounces); -} - CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 3b683b5562f..19fdb87f803 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -189,7 +189,7 @@ ccl_device bool compute_emitter_centroid_and_dir(KernelGlobals kg, ccl_private float3 ¢roid, ccl_private packed_float3 &dir) { - const int prim_id = kemitter->prim_id; + const int prim_id = kemitter->prim; if (prim_id < 0) { const ccl_global KernelLight *klight = &kernel_data_fetch(lights, ~prim_id); centroid = klight->co; @@ -223,10 +223,10 @@ ccl_device bool compute_emitter_centroid_and_dir(KernelGlobals kg, triangle_world_space_vertices(kg, object, prim_id, -1.0f, vertices); centroid = (vertices[0] + vertices[1] + vertices[2]) / 3.0f; - if (kemitter->mesh_light.emission_sampling == EMISSION_SAMPLING_FRONT) { + if (kemitter->emission_sampling == EMISSION_SAMPLING_FRONT) { dir = safe_normalize(cross(vertices[1] - vertices[0], vertices[2] - vertices[0])); } - else if (kemitter->mesh_light.emission_sampling == EMISSION_SAMPLING_BACK) { + else if (kemitter->emission_sampling == EMISSION_SAMPLING_BACK) { dir = -safe_normalize(cross(vertices[1] - vertices[0], vertices[2] - vertices[0])); } else { @@ -264,7 +264,7 @@ ccl_device void light_tree_emitter_importance(KernelGlobals kg, return; } - const int prim_id = kemitter->prim_id; + const int prim_id = kemitter->prim; if (in_volume_segment) { const float3 D = N_or_D; @@ -568,8 +568,8 @@ ccl_device_noinline bool light_tree_sample(KernelGlobals kg, const bool has_transmission = (shader_flags & SD_BSDF_HAS_TRANSMISSION); float pdf_leaf = 1.0f; - float pdf_emitter_from_leaf = 1.0f; - int selected_light = -1; + float pdf_selection = 1.0f; + int selected_emitter = -1; int node_index = 0; /* Root node. */ @@ -579,8 +579,8 @@ ccl_device_noinline bool light_tree_sample(KernelGlobals kg, if (knode->child_index <= 0) { /* At a leaf node, we pick an emitter. */ - selected_light = light_tree_cluster_select_emitter( - kg, randv, P, N_or_D, t, has_transmission, knode, &pdf_emitter_from_leaf); + selected_emitter = light_tree_cluster_select_emitter( + kg, randv, P, N_or_D, t, has_transmission, knode, &pdf_selection); break; } @@ -602,46 +602,14 @@ ccl_device_noinline bool light_tree_sample(KernelGlobals kg, pdf_leaf *= (node_index == left_index) ? left_prob : (1.0f - left_prob); } - if (selected_light < 0) { + if (selected_emitter < 0) { return false; } - /* Sample a point on the chosen emitter. */ - ccl_global const KernelLightTreeEmitter *kemitter = &kernel_data_fetch(light_tree_emitters, - selected_light); + pdf_selection *= pdf_leaf; - /* TODO: this is the same code as light_distribution_sample, except the index is determined - * differently. Would it be better to refactor this into a separate function? */ - const int prim = kemitter->prim_id; - if (prim >= 0) { - /* Mesh light. */ - const int object = kemitter->mesh_light.object_id; - - /* Exclude synthetic meshes from shadow catcher pass. */ - if ((path_flag & PATH_RAY_SHADOW_CATCHER_PASS) && - !(kernel_data_fetch(object_flag, object) & SD_OBJECT_SHADOW_CATCHER)) { - return false; - } - - const int mesh_shader_flag = kemitter->mesh_light.shader_flag; - if (!triangle_light_sample(kg, prim, object, randu, randv, time, ls, P)) { - return false; - } - ls->shader |= mesh_shader_flag; - } - else { - if (UNLIKELY(light_select_reached_max_bounces(kg, ~prim, bounce))) { - return false; - } - - if (!light_sample(kg, ~prim, randu, randv, P, path_flag, ls)) { - return false; - } - } - - ls->pdf_selection = pdf_leaf * pdf_emitter_from_leaf; - ls->pdf *= ls->pdf_selection; - return (ls->pdf > 0); + return light_sample( + kg, randu, randv, time, P, bounce, path_flag, selected_emitter, pdf_selection, ls); } /* We need to be able to find the probability of selecting a given light for MIS. */ diff --git a/intern/cycles/kernel/light/triangle.h b/intern/cycles/kernel/light/triangle.h index 1a5e8e9e62c..829bacb31f3 100644 --- a/intern/cycles/kernel/light/triangle.h +++ b/intern/cycles/kernel/light/triangle.h @@ -306,7 +306,7 @@ ccl_device_forceinline bool triangle_light_tree_parameters( const int object = kemitter->mesh_light.object_id; float3 vertices[3]; - triangle_world_space_vertices(kg, object, kemitter->prim_id, -1.0f, vertices); + triangle_world_space_vertices(kg, object, kemitter->prim, -1.0f, vertices); bool shape_above_surface = false; for (int i = 0; i < 3; i++) { diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 100f0806ed2..ff28f27a655 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -1338,13 +1338,15 @@ typedef struct KernelLight { } KernelLight; static_assert_align(KernelLight, 16); +using MeshLight = struct MeshLight { + int shader_flag; + int object_id; +}; + typedef struct KernelLightDistribution { float totarea; int prim; - struct { - int shader_flag; - int object_id; - } mesh_light; + MeshLight mesh_light; } KernelLightDistribution; static_assert_align(KernelLightDistribution, 16); @@ -1393,12 +1395,9 @@ typedef struct KernelLightTreeEmitter { float energy; /* prim_id denotes the location in the lights or triangles array. */ - int prim_id; - struct { - int shader_flag; - int object_id; - EmissionSampling emission_sampling; - } mesh_light; + int prim; + MeshLight mesh_light; + EmissionSampling emission_sampling; /* Parent. */ int parent_index; diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index b8addeaffd6..9070c444f63 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -616,18 +616,16 @@ void LightManager::device_update_tree(Device *, shader_flag |= SHADER_EXCLUDE_SHADOW_CATCHER; } - light_tree_emitters[emitter_index].prim_id = prim.prim_id + mesh->prim_offset; + light_tree_emitters[emitter_index].prim = prim.prim_id + mesh->prim_offset; light_tree_emitters[emitter_index].mesh_light.shader_flag = shader_flag; - light_tree_emitters[emitter_index].mesh_light.emission_sampling = - shader->emission_sampling; + light_tree_emitters[emitter_index].emission_sampling = shader->emission_sampling; triangle_array[prim.prim_id + object_lookup_offsets[prim.object_id]] = emitter_index; } else { - light_tree_emitters[emitter_index].prim_id = prim.prim_id; + light_tree_emitters[emitter_index].prim = prim.prim_id; light_tree_emitters[emitter_index].mesh_light.shader_flag = 0; light_tree_emitters[emitter_index].mesh_light.object_id = OBJECT_NONE; - light_tree_emitters[emitter_index].mesh_light.emission_sampling = - EMISSION_SAMPLING_FRONT_BACK; + light_tree_emitters[emitter_index].emission_sampling = EMISSION_SAMPLING_FRONT_BACK; light_array[~prim.prim_id] = emitter_index; } From f56488c20f44acaf31d75ba0a1e5dd2539c8f8a6 Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Mon, 12 Dec 2022 21:38:23 +0100 Subject: [PATCH 0033/1522] Fix Cycles ellipse area light returns zero pdf in volume segment --- intern/cycles/kernel/light/light.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/kernel/light/light.h b/intern/cycles/kernel/light/light.h index d04bffe8f8b..fe1df22bd60 100644 --- a/intern/cycles/kernel/light/light.h +++ b/intern/cycles/kernel/light/light.h @@ -156,7 +156,7 @@ ccl_device_noinline bool light_sample(KernelGlobals kg, } ls->pdf *= ls->pdf_selection; - return (ls->pdf > 0.0f); + return in_volume_segment || (ls->pdf > 0.0f); } /* Intersect ray with individual light. */ From b08301c865f42ab51b29efb80fcf68074a947d93 Mon Sep 17 00:00:00 2001 From: Erik Abrahamsson Date: Mon, 12 Dec 2022 23:01:49 +0100 Subject: [PATCH 0034/1522] Geometry Nodes: Optimization in Set Position node Adds an early return if Position/Offset inputs won't lead to any changes in the Geometry. It now also compares with the read-only Position attribute instead of getting it for write only, to work correctly with Copy-on-Write. Before, the `is_same`-check only worked for geometry created in the node tree. Differential Revision: https://developer.blender.org/D16738 --- .../geometry/nodes/node_geo_set_position.cc | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index e243fe3614c..e219d5bc0a1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -29,15 +29,22 @@ static void set_computed_position_and_offset(GeometryComponent &component, const IndexMask selection) { MutableAttributeAccessor attributes = *component.attributes_for_write(); - AttributeWriter positions = attributes.lookup_for_write("position"); + const VArray positions_read_only = attributes.lookup("position"); + if (in_positions.is_same(positions_read_only)) { + if (const std::optional offset = in_offsets.get_if_single()) { + if (math::is_zero(offset.value())) { + return; + } + } + } const int grain_size = 10000; switch (component.type()) { case GEO_COMPONENT_TYPE_MESH: { Mesh *mesh = static_cast(component).get_for_write(); MutableSpan verts = mesh->verts_for_write(); - if (in_positions.is_same(positions.varray)) { + if (in_positions.is_same(positions_read_only)) { devirtualize_varray(in_offsets, [&](const auto in_offsets) { threading::parallel_for( selection.index_range(), grain_size, [&](const IndexRange range) { @@ -63,15 +70,16 @@ static void set_computed_position_and_offset(GeometryComponent &component, break; } case GEO_COMPONENT_TYPE_CURVE: { - CurveComponent &curve_component = static_cast(component); - Curves &curves_id = *curve_component.get_for_write(); - bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); if (attributes.contains("handle_right") && attributes.contains("handle_left")) { + CurveComponent &curve_component = static_cast(component); + Curves &curves_id = *curve_component.get_for_write(); + bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); SpanAttributeWriter handle_right_attribute = attributes.lookup_or_add_for_write_span("handle_right", ATTR_DOMAIN_POINT); SpanAttributeWriter handle_left_attribute = attributes.lookup_or_add_for_write_span("handle_left", ATTR_DOMAIN_POINT); + AttributeWriter positions = attributes.lookup_for_write("position"); MutableVArraySpan out_positions_span = positions.varray; devirtualize_varray2( in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) { @@ -88,6 +96,7 @@ static void set_computed_position_and_offset(GeometryComponent &component, }); out_positions_span.save(); + positions.finish(); handle_right_attribute.finish(); handle_left_attribute.finish(); @@ -95,13 +104,12 @@ static void set_computed_position_and_offset(GeometryComponent &component, curves.calculate_bezier_auto_handles(); break; } - else { - ATTR_FALLTHROUGH; - } + ATTR_FALLTHROUGH; } default: { + AttributeWriter positions = attributes.lookup_for_write("position"); MutableVArraySpan out_positions_span = positions.varray; - if (in_positions.is_same(positions.varray)) { + if (in_positions.is_same(positions_read_only)) { devirtualize_varray(in_offsets, [&](const auto in_offsets) { threading::parallel_for( selection.index_range(), grain_size, [&](const IndexRange range) { @@ -123,11 +131,10 @@ static void set_computed_position_and_offset(GeometryComponent &component, }); } out_positions_span.save(); + positions.finish(); break; } } - - positions.finish(); } static void set_position_in_component(GeometryComponent &component, From 9437abdbceeed688d40b78da70465fd1ef415647 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 12 Dec 2022 15:14:45 -0600 Subject: [PATCH 0035/1522] Cleanup: Use LISTBASE_FOREACH macro --- source/blender/editors/space_view3d/view3d_cursor_snap.c | 2 +- source/blender/editors/transform/transform.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_cursor_snap.c b/source/blender/editors/space_view3d/view3d_cursor_snap.c index 6ddd47e0f52..771a964dbcd 100644 --- a/source/blender/editors/space_view3d/view3d_cursor_snap.c +++ b/source/blender/editors/space_view3d/view3d_cursor_snap.c @@ -524,7 +524,7 @@ static bool v3d_cursor_is_snap_invert(SnapCursorDataIntern *data_intern, const w const int snap_on = data_intern->snap_on; wmKeyMap *keymap = WM_keymap_active(wm, data_intern->keymap); - for (wmKeyMapItem *kmi = keymap->items.first; kmi; kmi = kmi->next) { + LISTBASE_FOREACH (const wmKeyMapItem *, kmi, &keymap->items) { if (kmi->flag & KMI_INACTIVE) { continue; } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 767e217117c..fcc5051d841 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1859,9 +1859,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve * lead to keymap conflicts for other modes (see T31584) */ if (ELEM(mode, TFM_TRANSLATION, TFM_ROTATION, TFM_RESIZE)) { - wmKeyMapItem *kmi; - - for (kmi = t->keymap->items.first; kmi; kmi = kmi->next) { + LISTBASE_FOREACH (const wmKeyMapItem *, kmi, &t->keymap->items) { if (kmi->flag & KMI_INACTIVE) { continue; } From 4ee2504eff3175e9b22320a06a8c9cadfe103ae6 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 12 Dec 2022 15:45:41 -0600 Subject: [PATCH 0036/1522] Cleanup: Remove cryptic "PET" acronym There is no need to make this an acronym, it only makes the code less accessible. It's a comment anyway, so brevity isn't the goal. --- source/blender/editors/transform/transform.c | 2 +- source/blender/editors/transform/transform_convert.c | 4 ++-- source/blender/editors/transform/transform_convert_curve.c | 3 ++- .../blender/editors/transform/transform_convert_lattice.c | 3 ++- source/blender/editors/transform/transform_convert_mball.c | 3 ++- source/blender/editors/transform/transform_convert_mesh.c | 6 ++++-- .../blender/editors/transform/transform_convert_mesh_skin.c | 3 ++- .../blender/editors/transform/transform_convert_mesh_uv.c | 3 ++- .../editors/transform/transform_convert_mesh_vert_cdata.c | 3 ++- source/blender/editors/transform/transform_convert_node.cc | 2 +- source/blender/editors/transform/transform_generics.c | 5 +++-- .../editors/transform/transform_mode_curveshrinkfatten.c | 2 +- source/blender/editors/transform/transform_mode_gpopacity.c | 2 +- .../editors/transform/transform_mode_gpshrinkfatten.c | 2 +- .../editors/transform/transform_mode_maskshrinkfatten.c | 2 +- 15 files changed, 27 insertions(+), 18 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index fcc5051d841..77b6f169a08 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1336,7 +1336,7 @@ bool calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], floa t->state = TRANS_RUNNING; - /* avoid calculating PET */ + /* Avoid calculating proportional editing. */ t->options = CTX_NO_PET; t->mode = TFM_DUMMY; diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index 00e7b15c59a..f9ad09b7a10 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -709,7 +709,7 @@ static int countAndCleanTransDataContainer(TransInfo *t) static void init_proportional_edit(TransInfo *t) { - /* NOTE: PET is not usable in pose mode yet T32444. */ + /* NOTE: Proportional editing is not usable in pose mode yet T32444. */ if (!ELEM(t->data_type, &TransConvertType_Action, &TransConvertType_Curve, @@ -726,7 +726,7 @@ static void init_proportional_edit(TransInfo *t) &TransConvertType_Node, &TransConvertType_Object, &TransConvertType_Particle)) { - /* Disable PET */ + /* Disable proportional editing */ t->options |= CTX_NO_PET; t->flag &= ~T_PROP_EDIT_ALL; return; diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c index 13ba28ec3d0..3a4098cf06f 100644 --- a/source/blender/editors/transform/transform_convert_curve.c +++ b/source/blender/editors/transform/transform_convert_curve.c @@ -131,7 +131,8 @@ static void createTransCurveVerts(bContext *UNUSED(C), TransInfo *t) } } - /* Support other objects using PET to adjust these, unless connected is enabled. */ + /* Support other objects using proportional editing to adjust these, unless connected is + * enabled. */ if (((is_prop_edit && !is_prop_connected) ? count : countsel) == 0) { tc->data_len = 0; continue; diff --git a/source/blender/editors/transform/transform_convert_lattice.c b/source/blender/editors/transform/transform_convert_lattice.c index e9b3401974b..cb391b4930b 100644 --- a/source/blender/editors/transform/transform_convert_lattice.c +++ b/source/blender/editors/transform/transform_convert_lattice.c @@ -52,7 +52,8 @@ static void createTransLatticeVerts(bContext *UNUSED(C), TransInfo *t) bp++; } - /* Support other objects using PET to adjust these, unless connected is enabled. */ + /* Support other objects using proportional editing to adjust these, unless connected is + * enabled. */ if (((is_prop_edit && !is_prop_connected) ? count : countsel) == 0) { tc->data_len = 0; continue; diff --git a/source/blender/editors/transform/transform_convert_mball.c b/source/blender/editors/transform/transform_convert_mball.c index c90052e9e8c..bae2ea8b20d 100644 --- a/source/blender/editors/transform/transform_convert_mball.c +++ b/source/blender/editors/transform/transform_convert_mball.c @@ -44,7 +44,8 @@ static void createTransMBallVerts(bContext *UNUSED(C), TransInfo *t) } } - /* Support other objects using PET to adjust these, unless connected is enabled. */ + /* Support other objects using proportional editing to adjust these, unless connected is + * enabled. */ if (((is_prop_edit && !is_prop_connected) ? count : countsel) == 0) { tc->data_len = 0; continue; diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index d8442175ab0..a8c34a95389 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -843,7 +843,8 @@ void transform_convert_mesh_islands_calc(struct BMEditMesh *em, MEM_freeN(group_index); } - /* for PET we need islands of 1 so connected vertices can use it with V3D_AROUND_LOCAL_ORIGINS */ + /* for proportional editing we need islands of 1 so connected vertices can use it with + * V3D_AROUND_LOCAL_ORIGINS */ if (calc_single_islands) { BMIter viter; BMVert *v; @@ -1484,7 +1485,8 @@ static void createTransEditVerts(bContext *UNUSED(C), TransInfo *t) * transform data is created by selected vertices. */ - /* Support other objects using PET to adjust these, unless connected is enabled. */ + /* Support other objects using proportional editing to adjust these, unless connected is + * enabled. */ if ((!prop_mode || (prop_mode & T_PROP_CONNECTED)) && (bm->totvertsel == 0)) { continue; } diff --git a/source/blender/editors/transform/transform_convert_mesh_skin.c b/source/blender/editors/transform/transform_convert_mesh_skin.c index cb6108a4c45..1139e61aefb 100644 --- a/source/blender/editors/transform/transform_convert_mesh_skin.c +++ b/source/blender/editors/transform/transform_convert_mesh_skin.c @@ -94,7 +94,8 @@ static void createTransMeshSkin(bContext *UNUSED(C), TransInfo *t) continue; } - /* Support other objects using PET to adjust these, unless connected is enabled. */ + /* Support other objects using proportional editing to adjust these, unless connected is + * enabled. */ if ((!prop_mode || (prop_mode & T_PROP_CONNECTED)) && (bm->totvertsel == 0)) { continue; } diff --git a/source/blender/editors/transform/transform_convert_mesh_uv.c b/source/blender/editors/transform/transform_convert_mesh_uv.c index 4f15fc240d3..5c90395ae22 100644 --- a/source/blender/editors/transform/transform_convert_mesh_uv.c +++ b/source/blender/editors/transform/transform_convert_mesh_uv.c @@ -314,7 +314,8 @@ static void createTransUVs(bContext *C, TransInfo *t) float *prop_dists = NULL; - /* Support other objects using PET to adjust these, unless connected is enabled. */ + /* Support other objects using proportional editing to adjust these, unless connected is + * enabled. */ if (((is_prop_edit && !is_prop_connected) ? count : countsel) == 0) { goto finally; } diff --git a/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c b/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c index d253261f458..6145962acbf 100644 --- a/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c +++ b/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c @@ -77,7 +77,8 @@ static void createTransMeshVertCData(bContext *UNUSED(C), TransInfo *t) struct TransMirrorData mirror_data = {NULL}; struct TransMeshDataCrazySpace crazyspace_data = {NULL}; - /* Support other objects using PET to adjust these, unless connected is enabled. */ + /* Support other objects using proportional editing to adjust these, unless connected is + * enabled. */ if ((!prop_mode || (prop_mode & T_PROP_CONNECTED)) && (bm->totvertsel == 0)) { continue; } diff --git a/source/blender/editors/transform/transform_convert_node.cc b/source/blender/editors/transform/transform_convert_node.cc index bd6f419e16e..7f54fa723f0 100644 --- a/source/blender/editors/transform/transform_convert_node.cc +++ b/source/blender/editors/transform/transform_convert_node.cc @@ -125,7 +125,7 @@ static void createTransNodeData(bContext * /*C*/, TransInfo *t) return; } - /* Nodes don't support PET and probably never will. */ + /* Nodes don't support proportional editing and probably never will. */ t->flag = t->flag & ~T_PROP_EDIT_ALL; /* set transform flags on nodes */ diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index e7ef408b848..449a53573e6 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -578,7 +578,8 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve t->flag |= T_NO_MIRROR; } - /* setting PET flag only if property exist in operator. Otherwise, assume it's not supported */ + /* Setting proportional editing flag only if property exist in operator. Otherwise, assume it's + * not supported. */ if (op && (prop = RNA_struct_find_property(op->ptr, "use_proportional_edit"))) { if (RNA_property_is_set(op->ptr, prop)) { if (RNA_property_boolean_get(op->ptr, prop)) { @@ -669,7 +670,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } } - /* Mirror is not supported with PET, turn it off. */ + /* Mirror is not supported with proportional editing, turn it off. */ #if 0 if (t->flag & T_PROP_EDIT) { t->flag &= ~T_MIRROR; diff --git a/source/blender/editors/transform/transform_mode_curveshrinkfatten.c b/source/blender/editors/transform/transform_mode_curveshrinkfatten.c index 0b87b45679a..276827d1b4c 100644 --- a/source/blender/editors/transform/transform_mode_curveshrinkfatten.c +++ b/source/blender/editors/transform/transform_mode_curveshrinkfatten.c @@ -71,7 +71,7 @@ static void applyCurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) *td->val = td->ival * ratio; } - /* apply PET */ + /* Apply proportional editing. */ *td->val = interpf(*td->val, td->ival, td->factor); CLAMP_MIN(*td->val, 0.0f); } diff --git a/source/blender/editors/transform/transform_mode_gpopacity.c b/source/blender/editors/transform/transform_mode_gpopacity.c index 8b9431b65ea..ddaabfe33cd 100644 --- a/source/blender/editors/transform/transform_mode_gpopacity.c +++ b/source/blender/editors/transform/transform_mode_gpopacity.c @@ -73,7 +73,7 @@ static void applyGPOpacity(TransInfo *t, const int UNUSED(mval[2])) if (td->val) { *td->val = td->ival * ratio; - /* apply PET */ + /* Apply proportional editing. */ *td->val = interpf(*td->val, td->ival, td->factor); CLAMP(*td->val, 0.0f, 1.0f); } diff --git a/source/blender/editors/transform/transform_mode_gpshrinkfatten.c b/source/blender/editors/transform/transform_mode_gpshrinkfatten.c index d8ec7d4ff50..0c3d25150ee 100644 --- a/source/blender/editors/transform/transform_mode_gpshrinkfatten.c +++ b/source/blender/editors/transform/transform_mode_gpshrinkfatten.c @@ -73,7 +73,7 @@ static void applyGPShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) if (td->val) { *td->val = td->ival * ratio; - /* apply PET */ + /* Apply proportional editing. */ *td->val = interpf(*td->val, td->ival, td->factor); if (*td->val <= 0.0f) { *td->val = 0.001f; diff --git a/source/blender/editors/transform/transform_mode_maskshrinkfatten.c b/source/blender/editors/transform/transform_mode_maskshrinkfatten.c index e2ccf61796b..9e743f96f53 100644 --- a/source/blender/editors/transform/transform_mode_maskshrinkfatten.c +++ b/source/blender/editors/transform/transform_mode_maskshrinkfatten.c @@ -89,7 +89,7 @@ static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2])) *td->val = td->ival * ratio; } - /* apply PET */ + /* Apply proportional editing. */ *td->val = interpf(*td->val, td->ival, td->factor); if (*td->val <= 0.0f) { *td->val = 0.001f; From e41abf9e26178ee4844004566be43acb7c7e39fb Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 12 Dec 2022 16:16:59 -0600 Subject: [PATCH 0037/1522] Cleanup: Remove runtime node flag, various node transform cleanups Remove another runtime node flag that's simpler as a local variable. Use references, C++ types, simpler for loops, etc. --- source/blender/editors/include/ED_node.hh | 3 + .../blender/editors/space_node/node_group.cc | 1 + .../blender/editors/space_node/node_intern.hh | 1 - .../transform/transform_convert_node.cc | 123 ++++++++---------- source/blender/makesdna/DNA_node_types.h | 2 +- 5 files changed, 61 insertions(+), 69 deletions(-) diff --git a/source/blender/editors/include/ED_node.hh b/source/blender/editors/include/ED_node.hh index 3929f5952e4..7b35bbf0b6e 100644 --- a/source/blender/editors/include/ED_node.hh +++ b/source/blender/editors/include/ED_node.hh @@ -2,6 +2,7 @@ #pragma once +#include "BLI_vector_set.hh" #include "ED_node.h" struct SpaceNode; @@ -11,6 +12,8 @@ struct bNodeTree; namespace blender::ed::space_node { +VectorSet get_selected_nodes(bNodeTree &node_tree); + void node_insert_on_link_flags_set(SpaceNode &snode, const ARegion ®ion); /** diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc index 93d2774c4b8..be9a6c69601 100644 --- a/source/blender/editors/space_node/node_group.cc +++ b/source/blender/editors/space_node/node_group.cc @@ -33,6 +33,7 @@ #include "DEG_depsgraph_build.h" #include "ED_node.h" /* own include */ +#include "ED_node.hh" #include "ED_render.h" #include "ED_screen.h" diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index ff1a0e55fd5..1a6859a3078 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -183,7 +183,6 @@ void node_keymap(wmKeyConfig *keyconf); rctf node_frame_rect_inside(const bNode &node); bool node_or_socket_isect_event(const bContext &C, const wmEvent &event); -VectorSet get_selected_nodes(bNodeTree &node_tree); void node_deselect_all(SpaceNode &snode); void node_socket_select(bNode *node, bNodeSocket &sock); void node_socket_deselect(bNode *node, bNodeSocket &sock, bool deselect_node); diff --git a/source/blender/editors/transform/transform_convert_node.cc b/source/blender/editors/transform/transform_convert_node.cc index 7f54fa723f0..8b15302853b 100644 --- a/source/blender/editors/transform/transform_convert_node.cc +++ b/source/blender/editors/transform/transform_convert_node.cc @@ -9,8 +9,8 @@ #include "MEM_guardedalloc.h" -#include "BLI_listbase.h" -#include "BLI_math.h" +#include "BLI_math_vector.h" +#include "BLI_math_vector.hh" #include "BLI_rect.h" #include "BKE_context.h" @@ -39,58 +39,60 @@ struct TransCustomDataNode { /** \name Node Transform Creation * \{ */ -/* transcribe given node into TransData2D for Transforming */ -static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node, const float dpi_fac) +static void create_transform_data_for_node(TransData &td, + TransData2D &td2d, + bNode &node, + const float dpi_fac) { float locx, locy; /* account for parents (nested nodes) */ - if (node->parent) { - nodeToView(node->parent, node->locx, node->locy, &locx, &locy); + if (node.parent) { + nodeToView(node.parent, node.locx, node.locy, &locx, &locy); } else { - locx = node->locx; - locy = node->locy; + locx = node.locx; + locy = node.locy; } /* use top-left corner as the transform origin for nodes */ /* Weirdo - but the node system is a mix of free 2d elements and DPI sensitive UI. */ #ifdef USE_NODE_CENTER - td2d->loc[0] = (locx * dpi_fac) + (BLI_rctf_size_x(&node->runtime->totr) * +0.5f); - td2d->loc[1] = (locy * dpi_fac) + (BLI_rctf_size_y(&node->runtime->totr) * -0.5f); + td2d.loc[0] = (locx * dpi_fac) + (BLI_rctf_size_x(&node.runtime->totr) * +0.5f); + td2d.loc[1] = (locy * dpi_fac) + (BLI_rctf_size_y(&node.runtime->totr) * -0.5f); #else - td2d->loc[0] = locx * dpi_fac; - td2d->loc[1] = locy * dpi_fac; + td2d.loc[0] = locx * dpi_fac; + td2d.loc[1] = locy * dpi_fac; #endif - td2d->loc[2] = 0.0f; - td2d->loc2d = td2d->loc; /* current location */ + td2d.loc[2] = 0.0f; + td2d.loc2d = td2d.loc; /* current location */ - td->loc = td2d->loc; - copy_v3_v3(td->iloc, td->loc); + td.loc = td2d.loc; + copy_v3_v3(td.iloc, td.loc); /* use node center instead of origin (top-left corner) */ - td->center[0] = td2d->loc[0]; - td->center[1] = td2d->loc[1]; - td->center[2] = 0.0f; + td.center[0] = td2d.loc[0]; + td.center[1] = td2d.loc[1]; + td.center[2] = 0.0f; - memset(td->axismtx, 0, sizeof(td->axismtx)); - td->axismtx[2][2] = 1.0f; + memset(td.axismtx, 0, sizeof(td.axismtx)); + td.axismtx[2][2] = 1.0f; - td->ext = nullptr; - td->val = nullptr; + td.ext = nullptr; + td.val = nullptr; - td->flag = TD_SELECTED; - td->dist = 0.0f; + td.flag = TD_SELECTED; + td.dist = 0.0f; - unit_m3(td->mtx); - unit_m3(td->smtx); + unit_m3(td.mtx); + unit_m3(td.smtx); - td->extra = node; + td.extra = &node; } -static bool is_node_parent_select(bNode *node) +static bool is_node_parent_select(const bNode *node) { while ((node = node->parent)) { - if (node->flag & NODE_TRANSFORM) { + if (node->flag & NODE_SELECT) { return true; } } @@ -99,8 +101,13 @@ static bool is_node_parent_select(bNode *node) static void createTransNodeData(bContext * /*C*/, TransInfo *t) { - const float dpi_fac = UI_DPI_FAC; + using namespace blender; + using namespace blender::ed; SpaceNode *snode = static_cast(t->area->spacedata.first); + bNodeTree *node_tree = snode->edittree; + if (!node_tree) { + return; + } /* Custom data to enable edge panning during the node transform */ TransCustomDataNode *customdata = MEM_cnew(__func__); @@ -119,37 +126,21 @@ static void createTransNodeData(bContext * /*C*/, TransInfo *t) TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t); - tc->data_len = 0; - - if (!snode->edittree) { - return; - } - /* Nodes don't support proportional editing and probably never will. */ t->flag = t->flag & ~T_PROP_EDIT_ALL; - /* set transform flags on nodes */ - for (bNode *node : snode->edittree->all_nodes()) { - if (node->flag & NODE_SELECT && !is_node_parent_select(node)) { - node->flag |= NODE_TRANSFORM; - tc->data_len++; - } - else { - node->flag &= ~NODE_TRANSFORM; - } - } - - if (tc->data_len == 0) { + VectorSet nodes = space_node::get_selected_nodes(*node_tree); + nodes.remove_if([&](bNode *node) { return is_node_parent_select(node); }); + if (nodes.is_empty()) { return; } - TransData *td = tc->data = MEM_cnew_array(tc->data_len, __func__); - TransData2D *td2d = tc->data_2d = MEM_cnew_array(tc->data_len, __func__); + tc->data_len = nodes.size(); + tc->data = MEM_cnew_array(tc->data_len, __func__); + tc->data_2d = MEM_cnew_array(tc->data_len, __func__); - for (bNode *node : snode->edittree->all_nodes()) { - if (node->flag & NODE_TRANSFORM) { - NodeToTransData(td++, td2d++, node, dpi_fac); - } + for (const int i : nodes.index_range()) { + create_transform_data_for_node(tc->data[i], tc->data_2d[i], *nodes[i], UI_DPI_FAC); } } @@ -161,43 +152,41 @@ static void createTransNodeData(bContext * /*C*/, TransInfo *t) static void node_snap_grid_apply(TransInfo *t) { - int i; + using namespace blender; if (!(activeSnap(t) && (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) { return; } - float grid_size[2]; - copy_v2_v2(grid_size, t->snap_spatial); + float2 grid_size = t->snap_spatial; if (t->modifiers & MOD_PRECISION) { - mul_v2_fl(grid_size, t->snap_spatial_precision); + grid_size *= t->snap_spatial_precision; } /* Early exit on unusable grid size. */ - if (is_zero_v2(grid_size)) { + if (math::is_zero(grid_size)) { return; } FOREACH_TRANS_DATA_CONTAINER (t, tc) { - TransData *td; - - for (i = 0, td = tc->data; i < tc->data_len; i++, td++) { + for (const int i : IndexRange(tc->data_len)) { + TransData &td = tc->data[i]; float iloc[2], loc[2], tvec[2]; - if (td->flag & TD_SKIP) { + if (td.flag & TD_SKIP) { continue; } - if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f)) { + if ((t->flag & T_PROP_EDIT) && (td.factor == 0.0f)) { continue; } - copy_v2_v2(iloc, td->loc); + copy_v2_v2(iloc, td.loc); loc[0] = roundf(iloc[0] / grid_size[0]) * grid_size[0]; loc[1] = roundf(iloc[1] / grid_size[1]) * grid_size[1]; sub_v2_v2v2(tvec, loc, iloc); - add_v2_v2(td->loc, tvec); + add_v2_v2(td.loc, tvec); } } } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 4025726733f..424a4c17e82 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -417,7 +417,7 @@ typedef struct bNode { /* node is always behind others */ #define NODE_BACKGROUND (1 << 12) /* automatic flag for nodes included in transforms */ -#define NODE_TRANSFORM (1 << 13) +// #define NODE_TRANSFORM (1 << 13) /* deprecated */ /* node is active texture */ /* NOTE: take care with this flag since its possible it gets From 57090a4b7228f065c22fcf2ac2e70e7a0ab10c2d Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 12 Dec 2022 17:09:58 -0600 Subject: [PATCH 0038/1522] Cleanup: Remove ifdef'd node transform code This has been turned off since 2013. --- source/blender/editors/transform/transform.h | 4 ---- .../transform/transform_convert_node.cc | 10 --------- .../editors/transform/transform_snap.cc | 21 ++----------------- 3 files changed, 2 insertions(+), 33 deletions(-) diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index a73b82b9092..169937d17e2 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -23,10 +23,6 @@ extern "C" { #endif -/* use node center for transform instead of upper-left corner. - * disabled since it makes absolute snapping not work so nicely - */ -// #define USE_NODE_CENTER /* -------------------------------------------------------------------- */ /** \name Types/ diff --git a/source/blender/editors/transform/transform_convert_node.cc b/source/blender/editors/transform/transform_convert_node.cc index 8b15302853b..f07baa09e8c 100644 --- a/source/blender/editors/transform/transform_convert_node.cc +++ b/source/blender/editors/transform/transform_convert_node.cc @@ -57,13 +57,8 @@ static void create_transform_data_for_node(TransData &td, /* use top-left corner as the transform origin for nodes */ /* Weirdo - but the node system is a mix of free 2d elements and DPI sensitive UI. */ -#ifdef USE_NODE_CENTER - td2d.loc[0] = (locx * dpi_fac) + (BLI_rctf_size_x(&node.runtime->totr) * +0.5f); - td2d.loc[1] = (locy * dpi_fac) + (BLI_rctf_size_y(&node.runtime->totr) * -0.5f); -#else td2d.loc[0] = locx * dpi_fac; td2d.loc[1] = locy * dpi_fac; -#endif td2d.loc[2] = 0.0f; td2d.loc2d = td2d.loc; /* current location */ @@ -235,11 +230,6 @@ static void flushTransNodes(TransInfo *t) float loc[2]; add_v2_v2v2(loc, td2d->loc, offset); -#ifdef USE_NODE_CENTER - loc[0] -= 0.5f * BLI_rctf_size_x(&node->runtime->totr); - loc[1] += 0.5f * BLI_rctf_size_y(&node->runtime->totr); -#endif - /* Weirdo - but the node system is a mix of free 2d elements and DPI sensitive UI. */ loc[0] /= dpi_fac; loc[1] /= dpi_fac; diff --git a/source/blender/editors/transform/transform_snap.cc b/source/blender/editors/transform/transform_snap.cc index 5373bdd7834..0157f478b57 100644 --- a/source/blender/editors/transform/transform_snap.cc +++ b/source/blender/editors/transform/transform_snap.cc @@ -1190,36 +1190,19 @@ static void TargetSnapOffset(TransInfo *t, TransData *td) if (t->spacetype == SPACE_NODE && td != nullptr) { bNode *node = static_cast(td->extra); char border = t->tsnap.snapNodeBorder; - float width = BLI_rctf_size_x(&node->runtime->totr); - float height = BLI_rctf_size_y(&node->runtime->totr); -#ifdef USE_NODE_CENTER - if (border & NODE_LEFT) { - t->tsnap.snapTarget[0] -= 0.5f * width; - } - if (border & NODE_RIGHT) { - t->tsnap.snapTarget[0] += 0.5f * width; - } - if (border & NODE_BOTTOM) { - t->tsnap.snapTarget[1] -= 0.5f * height; - } - if (border & NODE_TOP) { - t->tsnap.snapTarget[1] += 0.5f * height; - } -#else if (border & NODE_LEFT) { t->tsnap.snapTarget[0] -= 0.0f; } if (border & NODE_RIGHT) { - t->tsnap.snapTarget[0] += width; + t->tsnap.snapTarget[0] += BLI_rctf_size_x(&node->runtime->totr); } if (border & NODE_BOTTOM) { - t->tsnap.snapTarget[1] -= height; + t->tsnap.snapTarget[1] -= BLI_rctf_size_y(&node->runtime->totr); } if (border & NODE_TOP) { t->tsnap.snapTarget[1] += 0.0f; } -#endif } } From ab1c36ad3f0e6568fc951e4f75c5fbf01c463dd1 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 12 Dec 2022 18:19:32 -0600 Subject: [PATCH 0039/1522] Cleanup: Move two modifier files to C++ --- source/blender/modifiers/CMakeLists.txt | 4 +- .../intern/{MOD_array.c => MOD_array.cc} | 150 +++++++------- .../intern/{MOD_screw.c => MOD_screw.cc} | 185 +++++++++--------- source/blender/modifiers/intern/MOD_skin.c | 2 +- 4 files changed, 172 insertions(+), 169 deletions(-) rename source/blender/modifiers/intern/{MOD_array.c => MOD_array.cc} (89%) rename source/blender/modifiers/intern/{MOD_screw.c => MOD_screw.cc} (87%) diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index 807d5012681..63be9581175 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -34,7 +34,7 @@ set(INC_SYS set(SRC intern/MOD_armature.c - intern/MOD_array.c + intern/MOD_array.cc intern/MOD_bevel.c intern/MOD_boolean.cc intern/MOD_build.c @@ -71,7 +71,7 @@ set(SRC intern/MOD_particleinstance.c intern/MOD_particlesystem.cc intern/MOD_remesh.c - intern/MOD_screw.c + intern/MOD_screw.cc intern/MOD_shapekey.c intern/MOD_shrinkwrap.c intern/MOD_simpledeform.c diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.cc similarity index 89% rename from source/blender/modifiers/intern/MOD_array.c rename to source/blender/modifiers/intern/MOD_array.cc index 2d725af7fe4..1478ca0ecc5 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.cc @@ -73,11 +73,11 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte { ArrayModifierData *amd = (ArrayModifierData *)md; bool need_transform_dependency = false; - if (amd->start_cap != NULL) { + if (amd->start_cap != nullptr) { DEG_add_object_relation( ctx->node, amd->start_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier Start Cap"); } - if (amd->end_cap != NULL) { + if (amd->end_cap != nullptr) { DEG_add_object_relation( ctx->node, amd->end_cap, DEG_OB_COMP_GEOMETRY, "Array Modifier End Cap"); } @@ -86,7 +86,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte ctx->node, amd->curve_ob, DEG_OB_COMP_GEOMETRY, "Array Modifier Curve"); DEG_add_special_eval_flag(ctx->node, &amd->curve_ob->id, DAG_EVAL_NEED_CURVE_PATH); } - if (amd->offset_ob != NULL) { + if (amd->offset_ob != nullptr) { DEG_add_object_relation( ctx->node, amd->offset_ob, DEG_OB_COMP_TRANSFORM, "Array Modifier Offset"); need_transform_dependency = true; @@ -103,16 +103,16 @@ BLI_INLINE float sum_v3(const float v[3]) } /* Structure used for sorting vertices, when processing doubles */ -typedef struct SortVertsElem { +struct SortVertsElem { int vertex_num; /* The original index of the vertex, prior to sorting */ float co[3]; /* Its coordinates */ float sum_co; /* `sum_v3(co)`: just so we don't do the sum many times. */ -} SortVertsElem; +}; static int svert_sum_cmp(const void *e1, const void *e2) { - const SortVertsElem *sv1 = e1; - const SortVertsElem *sv2 = e2; + const SortVertsElem *sv1 = static_cast(e1); + const SortVertsElem *sv2 = static_cast(e2); if (sv1->sum_co > sv2->sum_co) { return 1; @@ -152,9 +152,8 @@ static void dm_mvert_map_doubles(int *doubles_map, const int source_verts_num, const float dist) { - const float dist3 = ((float)M_SQRT3 + 0.00005f) * dist; /* Just above sqrt(3) */ + const float dist3 = (float(M_SQRT3) + 0.00005f) * dist; /* Just above sqrt(3) */ int i_source, i_target, i_target_low_bound, target_end, source_end; - SortVertsElem *sorted_verts_target, *sorted_verts_source; SortVertsElem *sve_source, *sve_target, *sve_target_low_bound; bool target_scan_completed; @@ -162,8 +161,10 @@ static void dm_mvert_map_doubles(int *doubles_map, source_end = source_start + source_verts_num; /* build array of MVerts to be tested for merging */ - sorted_verts_target = MEM_malloc_arrayN(target_verts_num, sizeof(SortVertsElem), __func__); - sorted_verts_source = MEM_malloc_arrayN(source_verts_num, sizeof(SortVertsElem), __func__); + SortVertsElem *sorted_verts_target = static_cast( + MEM_malloc_arrayN(target_verts_num, sizeof(SortVertsElem), __func__)); + SortVertsElem *sorted_verts_source = static_cast( + MEM_malloc_arrayN(source_verts_num, sizeof(SortVertsElem), __func__)); /* Copy target vertices index and cos into SortVertsElem array */ svert_from_mvert(sorted_verts_target, mverts + target_start, target_start, target_end); @@ -305,7 +306,7 @@ static void mesh_merge_transform(Mesh *result, } /* remap the vertex groups if necessary */ - if (BKE_mesh_deform_verts(result) != NULL) { + if (BKE_mesh_deform_verts(result) != nullptr) { MDeformVert *dvert = BKE_mesh_deform_verts_for_write(result); BKE_object_defgroup_index_map_apply(&dvert[cap_verts_index], cap_nverts, remap, remap_len); } @@ -331,22 +332,22 @@ static void mesh_merge_transform(Mesh *result, } /* Set #CD_ORIGINDEX. */ - index_orig = CustomData_get_layer(&result->vdata, CD_ORIGINDEX); + index_orig = static_cast(CustomData_get_layer(&result->vdata, CD_ORIGINDEX)); if (index_orig) { copy_vn_i(index_orig + cap_verts_index, cap_nverts, ORIGINDEX_NONE); } - index_orig = CustomData_get_layer(&result->edata, CD_ORIGINDEX); + index_orig = static_cast(CustomData_get_layer(&result->edata, CD_ORIGINDEX)); if (index_orig) { copy_vn_i(index_orig + cap_edges_index, cap_nedges, ORIGINDEX_NONE); } - index_orig = CustomData_get_layer(&result->pdata, CD_ORIGINDEX); + index_orig = static_cast(CustomData_get_layer(&result->pdata, CD_ORIGINDEX)); if (index_orig) { copy_vn_i(index_orig + cap_polys_index, cap_npolys, ORIGINDEX_NONE); } - index_orig = CustomData_get_layer(&result->ldata, CD_ORIGINDEX); + index_orig = static_cast(CustomData_get_layer(&result->ldata, CD_ORIGINDEX)); if (index_orig) { copy_vn_i(index_orig + cap_loops_index, cap_nloops, ORIGINDEX_NONE); } @@ -367,12 +368,12 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, bool offset_has_scale; float current_offset[4][4]; float final_offset[4][4]; - int *full_doubles_map = NULL; + int *full_doubles_map = nullptr; int tot_doubles; const bool use_merge = (amd->flags & MOD_ARR_MERGE) != 0; const bool use_recalc_normals = BKE_mesh_vertex_normals_are_dirty(mesh) || use_merge; - const bool use_offset_ob = ((amd->offset_type & MOD_ARR_OFF_OBJ) && amd->offset_ob != NULL); + const bool use_offset_ob = ((amd->offset_type & MOD_ARR_OFF_OBJ) && amd->offset_ob != nullptr); int start_cap_nverts = 0, start_cap_nedges = 0, start_cap_npolys = 0, start_cap_nloops = 0; int end_cap_nverts = 0, end_cap_nedges = 0, end_cap_npolys = 0, end_cap_nloops = 0; @@ -380,11 +381,11 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, int chunk_nverts, chunk_nedges, chunk_nloops, chunk_npolys; int first_chunk_start, first_chunk_nverts, last_chunk_start, last_chunk_nverts; - Mesh *result, *start_cap_mesh = NULL, *end_cap_mesh = NULL; + Mesh *result, *start_cap_mesh = nullptr, *end_cap_mesh = nullptr; - int *vgroup_start_cap_remap = NULL; + int *vgroup_start_cap_remap = nullptr; int vgroup_start_cap_remap_len = 0; - int *vgroup_end_cap_remap = NULL; + int *vgroup_end_cap_remap = nullptr; int vgroup_end_cap_remap_len = 0; chunk_nverts = mesh->totvert; @@ -470,10 +471,10 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, mat4_to_size(scale, offset); offset_has_scale = !is_one_v3(scale); - if (amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob != NULL) { + if (amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob != nullptr) { Object *curve_ob = amd->curve_ob; CurveCache *curve_cache = curve_ob->runtime.curve_cache; - if (curve_cache != NULL && curve_cache->anim_path_accum_length != NULL) { + if (curve_cache != nullptr && curve_cache->anim_path_accum_length != nullptr) { float scale_fac = mat4_to_scale(curve_ob->object_to_world); length = scale_fac * BKE_anim_path_get_length(curve_cache); } @@ -548,7 +549,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, if (use_merge) { /* Will need full_doubles_map for handling merge */ - full_doubles_map = MEM_malloc_arrayN(result_nverts, sizeof(int), "mod array doubles map"); + full_doubles_map = static_cast(MEM_malloc_arrayN(result_nverts, sizeof(int), __func__)); copy_vn_i(full_doubles_map, result_nverts, -1); } @@ -576,8 +577,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, first_chunk_nverts = chunk_nverts; unit_m4(current_offset); - const float(*src_vert_normals)[3] = NULL; - float(*dst_vert_normals)[3] = NULL; + const float(*src_vert_normals)[3] = nullptr; + float(*dst_vert_normals)[3] = nullptr; if (!use_recalc_normals) { src_vert_normals = BKE_mesh_vertex_normals_ensure(mesh); dst_vert_normals = BKE_mesh_vertex_normals_for_write(result); @@ -672,12 +673,13 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, if (chunk_nloops > 0 && is_zero_v2(amd->uv_offset) == false) { const int totuv = CustomData_number_of_layers(&result->ldata, CD_MLOOPUV); for (i = 0; i < totuv; i++) { - MLoopUV *dmloopuv = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, i); + MLoopUV *dmloopuv = static_cast( + CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, i)); dmloopuv += chunk_nloops; for (c = 1; c < count; c++) { const float uv_offset[2] = { - amd->uv_offset[0] * (float)c, - amd->uv_offset[1] * (float)c, + amd->uv_offset[0] * float(c), + amd->uv_offset[1] * float(c), }; int l_index = chunk_nloops; for (; l_index-- != 0; dmloopuv++) { @@ -810,9 +812,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * return arrayModifier_doArray(amd, ctx, mesh); } -static bool isDisabled(const struct Scene *UNUSED(scene), - ModifierData *md, - bool UNUSED(useRenderParams)) +static bool isDisabled(const Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/) { ArrayModifierData *amd = (ArrayModifierData *)md; @@ -835,7 +835,7 @@ static bool isDisabled(const struct Scene *UNUSED(scene), return false; } -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; @@ -844,36 +844,36 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); - uiItemR(layout, ptr, "fit_type", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "fit_type", 0, nullptr, ICON_NONE); int fit_type = RNA_enum_get(ptr, "fit_type"); if (fit_type == MOD_ARR_FIXEDCOUNT) { - uiItemR(layout, ptr, "count", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "count", 0, nullptr, ICON_NONE); } else if (fit_type == MOD_ARR_FITLENGTH) { - uiItemR(layout, ptr, "fit_length", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "fit_length", 0, nullptr, ICON_NONE); } else if (fit_type == MOD_ARR_FITCURVE) { - uiItemR(layout, ptr, "curve", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "curve", 0, nullptr, ICON_NONE); } modifier_panel_end(layout, ptr); } -static void relative_offset_header_draw(const bContext *UNUSED(C), Panel *panel) +static void relative_offset_header_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); - uiItemR(layout, ptr, "use_relative_offset", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "use_relative_offset", 0, nullptr, ICON_NONE); } -static void relative_offset_draw(const bContext *UNUSED(C), Panel *panel) +static void relative_offset_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiLayoutSetPropSep(layout, true); @@ -883,20 +883,20 @@ static void relative_offset_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(col, ptr, "relative_offset_displace", 0, IFACE_("Factor"), ICON_NONE); } -static void constant_offset_header_draw(const bContext *UNUSED(C), Panel *panel) +static void constant_offset_header_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); - uiItemR(layout, ptr, "use_constant_offset", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "use_constant_offset", 0, nullptr, ICON_NONE); } -static void constant_offset_draw(const bContext *UNUSED(C), Panel *panel) +static void constant_offset_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiLayoutSetPropSep(layout, true); @@ -909,20 +909,20 @@ static void constant_offset_draw(const bContext *UNUSED(C), Panel *panel) /** * Object offset in a subpanel for consistency with the other offset types. */ -static void object_offset_header_draw(const bContext *UNUSED(C), Panel *panel) +static void object_offset_header_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); - uiItemR(layout, ptr, "use_object_offset", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "use_object_offset", 0, nullptr, ICON_NONE); } -static void object_offset_draw(const bContext *UNUSED(C), Panel *panel) +static void object_offset_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiLayoutSetPropSep(layout, true); @@ -932,20 +932,20 @@ static void object_offset_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(col, ptr, "offset_object", 0, IFACE_("Object"), ICON_NONE); } -static void symmetry_panel_header_draw(const bContext *UNUSED(C), Panel *panel) +static void symmetry_panel_header_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiItemR(layout, ptr, "use_merge_vertices", 0, IFACE_("Merge"), ICON_NONE); } -static void symmetry_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void symmetry_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiLayoutSetPropSep(layout, true); @@ -955,12 +955,12 @@ static void symmetry_panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(col, ptr, "use_merge_vertices_cap", 0, IFACE_("First and Last Copies"), ICON_NONE); } -static void uv_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void uv_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col; uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiLayoutSetPropSep(layout, true); @@ -969,12 +969,12 @@ static void uv_panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(col, ptr, "offset_v", UI_ITEM_R_EXPAND, IFACE_("V"), ICON_NONE); } -static void caps_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void caps_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col; uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiLayoutSetPropSep(layout, true); @@ -1002,8 +1002,8 @@ static void panelRegister(ARegionType *region_type) region_type, "object_offset", "", object_offset_header_draw, object_offset_draw, panel_type); modifier_subpanel_register( region_type, "merge", "", symmetry_panel_header_draw, symmetry_panel_draw, panel_type); - modifier_subpanel_register(region_type, "uv", "UVs", NULL, uv_panel_draw, panel_type); - modifier_subpanel_register(region_type, "caps", "Caps", NULL, caps_panel_draw, panel_type); + modifier_subpanel_register(region_type, "uv", "UVs", nullptr, uv_panel_draw, panel_type); + modifier_subpanel_register(region_type, "caps", "Caps", nullptr, caps_panel_draw, panel_type); } ModifierTypeInfo modifierType_Array = { @@ -1019,24 +1019,24 @@ ModifierTypeInfo modifierType_Array = { /* copyData */ BKE_modifier_copydata_generic, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, + /* deformVerts */ nullptr, + /* deformMatrices */ nullptr, + /* deformVertsEM */ nullptr, + /* deformMatricesEM */ nullptr, /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /* modifyGeometrySet */ nullptr, /* initData */ initData, - /* requiredDataMask */ NULL, - /* freeData */ NULL, + /* requiredDataMask */ nullptr, + /* freeData */ nullptr, /* isDisabled */ isDisabled, /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, + /* dependsOnTime */ nullptr, + /* dependsOnNormals */ nullptr, /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, + /* foreachTexLink */ nullptr, + /* freeRuntimeData */ nullptr, /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /* blendWrite */ nullptr, + /* blendRead */ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.cc similarity index 87% rename from source/blender/modifiers/intern/MOD_screw.c rename to source/blender/modifiers/intern/MOD_screw.cc index 8eb6c978568..930fa0c1aab 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.cc @@ -6,11 +6,10 @@ */ /* Screw modifier: revolves the edges about an axis */ -#include +#include #include "BLI_utildefines.h" -#include "BLI_alloca.h" #include "BLI_bitmap.h" #include "BLI_math.h" @@ -53,7 +52,7 @@ static void initData(ModifierData *md) } /** Used for gathering edge connectivity. */ -typedef struct ScrewVertConnect { +struct ScrewVertConnect { /** Distance from the center axis. */ float dist_sq; /** Location relative to the transformed axis. */ @@ -63,14 +62,14 @@ typedef struct ScrewVertConnect { /** Edges on either side, a bit of a waste since each edge ref's 2 edges. */ MEdge *e[2]; char flag; -} ScrewVertConnect; +}; -typedef struct ScrewVertIter { +struct ScrewVertIter { ScrewVertConnect *v_array; ScrewVertConnect *v_poin; uint v, v_other; MEdge *e; -} ScrewVertIter; +}; #define SV_UNUSED (UINT_MAX) #define SV_INVALID ((UINT_MAX)-1) @@ -90,8 +89,8 @@ static void screwvert_iter_init(ScrewVertIter *iter, iter->e = iter->v_poin->e[!dir]; } else { - iter->v_poin = NULL; - iter->e = NULL; + iter->v_poin = nullptr; + iter->e = nullptr; } } @@ -110,8 +109,8 @@ static void screwvert_iter_step(ScrewVertIter *iter) iter->e = iter->v_poin->e[(iter->v_poin->e[0] == iter->e)]; } else { - iter->e = NULL; - iter->v_poin = NULL; + iter->e = nullptr; + iter->v_poin = nullptr; } } @@ -126,7 +125,7 @@ static Mesh *mesh_remove_doubles_on_axis(Mesh *result, BLI_bitmap *vert_tag = BLI_BITMAP_NEW(totvert, __func__); const float merge_threshold_sq = square_f(merge_threshold); - const bool use_offset = axis_offset != NULL; + const bool use_offset = axis_offset != nullptr; uint tot_doubles = 0; for (uint i = 0; i < totvert; i += 1) { float axis_co[3]; @@ -149,15 +148,15 @@ static Mesh *mesh_remove_doubles_on_axis(Mesh *result, if (tot_doubles != 0) { uint tot = totvert * step_tot; - int *full_doubles_map = MEM_malloc_arrayN(tot, sizeof(int), __func__); - copy_vn_i(full_doubles_map, (int)tot, -1); + int *full_doubles_map = static_cast(MEM_malloc_arrayN(tot, sizeof(int), __func__)); + copy_vn_i(full_doubles_map, int(tot), -1); uint tot_doubles_left = tot_doubles; for (uint i = 0; i < totvert; i += 1) { if (BLI_BITMAP_TEST(vert_tag, i)) { int *doubles_map = &full_doubles_map[totvert + i]; for (uint step = 1; step < step_tot; step += 1) { - *doubles_map = (int)i; + *doubles_map = int(i); doubles_map += totvert; } tot_doubles_left -= 1; @@ -168,7 +167,7 @@ static Mesh *mesh_remove_doubles_on_axis(Mesh *result, } result = BKE_mesh_merge_verts(result, full_doubles_map, - (int)(tot_doubles * (step_tot - 1)), + int(tot_doubles * (step_tot - 1)), MESH_MERGE_VERTS_DUMP_IF_MAPPED); MEM_freeN(full_doubles_map); } @@ -206,16 +205,16 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * }; uint maxVerts = 0, maxEdges = 0, maxPolys = 0; - const uint totvert = (uint)mesh->totvert; - const uint totedge = (uint)mesh->totedge; - const uint totpoly = (uint)mesh->totpoly; + const uint totvert = uint(mesh->totvert); + const uint totedge = uint(mesh->totedge); + const uint totpoly = uint(mesh->totpoly); - uint *edge_poly_map = NULL; /* orig edge to orig poly */ - uint *vert_loop_map = NULL; /* orig vert to orig loop */ + uint *edge_poly_map = nullptr; /* orig edge to orig poly */ + uint *vert_loop_map = nullptr; /* orig vert to orig loop */ /* UV Coords */ - const uint mloopuv_layers_tot = (uint)CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV); - MLoopUV **mloopuv_layers = BLI_array_alloca(mloopuv_layers, mloopuv_layers_tot); + const uint mloopuv_layers_tot = uint(CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV)); + blender::Array mloopuv_layers(mloopuv_layers_tot); float uv_u_scale; float uv_v_minmax[2] = {FLT_MAX, -FLT_MAX}; float uv_v_range_inv; @@ -246,7 +245,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * const MVert *mv_orig; Object *ob_axis = ltmd->ob_axis; - ScrewVertConnect *vc, *vc_tmp, *vert_connect = NULL; + ScrewVertConnect *vc, *vc_tmp, *vert_connect = nullptr; const char mpoly_flag = (ltmd->flag & MOD_SCREW_SMOOTH_SHADING) ? ME_SMOOTH : 0; @@ -272,7 +271,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * axis_vec[ltmd->axis] = 1.0f; - if (ob_axis != NULL) { + if (ob_axis != nullptr) { /* Calculate the matrix relative to the axis object. */ invert_m4_m4(mtx_tmp_a, ctx->object->object_to_world); copy_m4_m4(mtx_tx_inv, ob_axis->object_to_world); @@ -331,7 +330,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * #endif } else { - axis_char = (char)(axis_char + ltmd->axis); /* 'X' + axis */ + axis_char = char(axis_char + ltmd->axis); /* 'X' + axis */ /* Useful to be able to use the axis vector in some cases still. */ zero_v3(axis_vec); @@ -339,9 +338,9 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } /* apply the multiplier */ - angle *= (float)ltmd->iter; - screw_ofs *= (float)ltmd->iter; - uv_u_scale = 1.0f / (float)(step_tot); + angle *= float(ltmd->iter); + screw_ofs *= float(ltmd->iter); + uv_u_scale = 1.0f / float(step_tot); /* multiplying the steps is a bit tricky, this works best */ step_tot = ((step_tot + 1) * ltmd->iter) - (ltmd->iter - 1); @@ -350,7 +349,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * NOTE: smaller than `FLT_EPSILON * 100` * gives problems with float precision so its never closed. */ if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) && - fabsf(fabsf(angle) - ((float)M_PI * 2.0f)) <= (FLT_EPSILON * 100.0f) && step_tot > 3) { + fabsf(fabsf(angle) - (float(M_PI) * 2.0f)) <= (FLT_EPSILON * 100.0f) && step_tot > 3) { close = 1; step_tot--; @@ -374,14 +373,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } if ((ltmd->flag & MOD_SCREW_UV_STRETCH_U) == 0) { - uv_u_scale = (uv_u_scale / (float)ltmd->iter) * (angle / ((float)M_PI * 2.0f)); + uv_u_scale = (uv_u_scale / float(ltmd->iter)) * (angle / (float(M_PI) * 2.0f)); } /* The `screw_ofs` cannot change from now on. */ const bool do_remove_doubles = (ltmd->flag & MOD_SCREW_MERGE) && (screw_ofs == 0.0f); result = BKE_mesh_new_nomain_from_template( - mesh, (int)maxVerts, (int)maxEdges, 0, (int)maxPolys * 4, (int)maxPolys); + mesh, int(maxVerts), int(maxEdges), 0, int(maxPolys) * 4, int(maxPolys)); const MVert *mvert_orig = BKE_mesh_verts(mesh); const MEdge *medge_orig = BKE_mesh_edges(mesh); @@ -394,12 +393,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MLoop *mloop_new = BKE_mesh_loops_for_write(result); if (!CustomData_has_layer(&result->pdata, CD_ORIGINDEX)) { - CustomData_add_layer(&result->pdata, CD_ORIGINDEX, CD_SET_DEFAULT, NULL, (int)maxPolys); + CustomData_add_layer(&result->pdata, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, int(maxPolys)); } - int *origindex = CustomData_get_layer(&result->pdata, CD_ORIGINDEX); + int *origindex = static_cast(CustomData_get_layer(&result->pdata, CD_ORIGINDEX)); - CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)totvert); + CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, int(totvert)); if (mloopuv_layers_tot) { const float zero_co[3] = {0}; @@ -409,7 +408,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * if (mloopuv_layers_tot) { uint uv_lay; for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { - mloopuv_layers[uv_lay] = CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, (int)uv_lay); + mloopuv_layers[uv_lay] = static_cast( + CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, int(uv_lay))); } if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) { @@ -444,15 +444,17 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * if (totpoly) { const MPoly *mp_orig; - edge_poly_map = MEM_malloc_arrayN(totedge, sizeof(*edge_poly_map), __func__); + edge_poly_map = static_cast( + MEM_malloc_arrayN(totedge, sizeof(*edge_poly_map), __func__)); memset(edge_poly_map, 0xff, sizeof(*edge_poly_map) * totedge); - vert_loop_map = MEM_malloc_arrayN(totvert, sizeof(*vert_loop_map), __func__); + vert_loop_map = static_cast( + MEM_malloc_arrayN(totvert, sizeof(*vert_loop_map), __func__)); memset(vert_loop_map, 0xff, sizeof(*vert_loop_map) * totvert); for (i = 0, mp_orig = mpoly_orig; i < totpoly; i++, mp_orig++) { - uint loopstart = (uint)mp_orig->loopstart; - uint loopend = loopstart + (uint)mp_orig->totloop; + uint loopstart = uint(mp_orig->loopstart); + uint loopend = loopstart + uint(mp_orig->totloop); const MLoop *ml_orig = &mloop_orig[loopstart]; uint k; @@ -490,7 +492,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * This makes the modifier faster with one less allocate. */ - vert_connect = MEM_malloc_arrayN(totvert, sizeof(ScrewVertConnect), __func__); + vert_connect = static_cast( + MEM_malloc_arrayN(totvert, sizeof(ScrewVertConnect), __func__)); /* skip the first slice of verts. */ // vert_connect = (ScrewVertConnect *) &medge_new[totvert]; vc = vert_connect; @@ -502,7 +505,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * med_new = medge_new; mv_new = mvert_new; - if (ob_axis != NULL) { + if (ob_axis != nullptr) { /* `mtx_tx` is initialized early on. */ for (i = 0; i < totvert; i++, mv_new++, mv_orig++, vc++) { vc->co[0] = mv_new->co[0] = mv_orig->co[0]; @@ -510,7 +513,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * vc->co[2] = mv_new->co[2] = mv_orig->co[2]; vc->flag = 0; - vc->e[0] = vc->e[1] = NULL; + vc->e[0] = vc->e[1] = nullptr; vc->v[0] = vc->v[1] = SV_UNUSED; mul_m4_v3(mtx_tx, vc->co); @@ -528,7 +531,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * vc->co[2] = mv_new->co[2] = mv_orig->co[2]; vc->flag = 0; - vc->e[0] = vc->e[1] = NULL; + vc->e[0] = vc->e[1] = nullptr; vc->v[0] = vc->v[1] = SV_UNUSED; /* Length in 2D, don't sqrt because this is only for comparison. */ @@ -767,9 +770,9 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * float step_angle; float mat[4][4]; /* Rotation Matrix */ - step_angle = (angle / (float)(step_tot - (!close))) * (float)step; + step_angle = (angle / float(step_tot - (!close))) * float(step); - if (ob_axis != NULL) { + if (ob_axis != nullptr) { axis_angle_normalized_to_mat3(mat3, axis_vec, step_angle); } else { @@ -778,11 +781,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * copy_m4_m3(mat, mat3); if (screw_ofs) { - madd_v3_v3fl(mat[3], axis_vec, screw_ofs * ((float)step / (float)(step_tot - 1))); + madd_v3_v3fl(mat[3], axis_vec, screw_ofs * (float(step) / float(step_tot - 1))); } /* copy a slice */ - CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)varray_stride, (int)totvert); + CustomData_copy_data(&mesh->vdata, &result->vdata, 0, int(varray_stride), int(totvert)); mv_new_base = mvert_new; mv_new = &mvert_new[varray_stride]; /* advance to the next slice */ @@ -794,7 +797,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* only need to set these if using non cleared memory */ // mv_new->mat_nr = mv_new->flag = 0; - if (ob_axis != NULL) { + if (ob_axis != nullptr) { sub_v3_v3(mv_new->co, mtx_tx[3]); mul_m4_v3(mat, mv_new->co); @@ -816,7 +819,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* we can avoid if using vert alloc trick */ if (vert_connect) { MEM_freeN(vert_connect); - vert_connect = NULL; + vert_connect = nullptr; } if (close) { @@ -860,7 +863,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * i2 = med_new_firstloop->v2; if (has_mpoly_orig) { - mat_nr = src_material_index == NULL ? 0 : src_material_index[mpoly_index_orig]; + mat_nr = src_material_index == nullptr ? 0 : src_material_index[mpoly_index_orig]; } else { mat_nr = 0; @@ -881,8 +884,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Polygon */ if (has_mpoly_orig) { CustomData_copy_data( - &mesh->pdata, &result->pdata, (int)mpoly_index_orig, (int)mpoly_index, 1); - origindex[mpoly_index] = (int)mpoly_index_orig; + &mesh->pdata, &result->pdata, int(mpoly_index_orig), int(mpoly_index), 1); + origindex[mpoly_index] = int(mpoly_index_orig); } else { origindex[mpoly_index] = ORIGINDEX_NONE; @@ -894,21 +897,21 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Loop-Custom-Data */ if (has_mloop_orig) { - int l_index = (int)(ml_new - mloop_new); + int l_index = int(ml_new - mloop_new); CustomData_copy_data( - &mesh->ldata, &result->ldata, (int)mloop_index_orig[0], l_index + 0, 1); + &mesh->ldata, &result->ldata, int(mloop_index_orig[0]), l_index + 0, 1); CustomData_copy_data( - &mesh->ldata, &result->ldata, (int)mloop_index_orig[1], l_index + 1, 1); + &mesh->ldata, &result->ldata, int(mloop_index_orig[1]), l_index + 1, 1); CustomData_copy_data( - &mesh->ldata, &result->ldata, (int)mloop_index_orig[1], l_index + 2, 1); + &mesh->ldata, &result->ldata, int(mloop_index_orig[1]), l_index + 2, 1); CustomData_copy_data( - &mesh->ldata, &result->ldata, (int)mloop_index_orig[0], l_index + 3, 1); + &mesh->ldata, &result->ldata, int(mloop_index_orig[0]), l_index + 3, 1); if (mloopuv_layers_tot) { uint uv_lay; - const float uv_u_offset_a = (float)(step)*uv_u_scale; - const float uv_u_offset_b = (float)(step + 1) * uv_u_scale; + const float uv_u_offset_a = float(step) * uv_u_scale; + const float uv_u_offset_b = float(step + 1) * uv_u_scale; for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index]; @@ -921,11 +924,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } else { if (mloopuv_layers_tot) { - int l_index = (int)(ml_new - mloop_new); + int l_index = int(ml_new - mloop_new); uint uv_lay; - const float uv_u_offset_a = (float)(step)*uv_u_scale; - const float uv_u_offset_b = (float)(step + 1) * uv_u_scale; + const float uv_u_offset_a = float(step) * uv_u_scale; + const float uv_u_offset_b = float(step + 1) * uv_u_scale; for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index]; @@ -1027,7 +1030,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * totvert, step_tot, axis_vec, - ob_axis != NULL ? mtx_tx[3] : NULL, + ob_axis != nullptr ? mtx_tx[3] : nullptr, ltmd->merge_dist); } @@ -1037,7 +1040,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { ScrewModifierData *ltmd = (ScrewModifierData *)md; - if (ltmd->ob_axis != NULL) { + if (ltmd->ob_axis != nullptr) { DEG_add_object_relation(ctx->node, ltmd->ob_axis, DEG_OB_COMP_TRANSFORM, "Screw Modifier"); DEG_add_depends_on_transform_relation(ctx->node, "Screw Modifier"); } @@ -1050,35 +1053,35 @@ static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *u walk(userData, ob, (ID **)<md->ob_axis, IDWALK_CB_NOP); } -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *sub, *row, *col; uiLayout *layout = panel->layout; int toggles_flag = UI_ITEM_R_TOGGLE | UI_ITEM_R_FORCE_BLANK_DECORATE; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); PointerRNA screw_obj_ptr = RNA_pointer_get(ptr, "object"); uiLayoutSetPropSep(layout, true); col = uiLayoutColumn(layout, false); - uiItemR(col, ptr, "angle", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "angle", 0, nullptr, ICON_NONE); row = uiLayoutRow(col, false); uiLayoutSetActive(row, RNA_pointer_is_null(&screw_obj_ptr) || !RNA_boolean_get(ptr, "use_object_screw_offset")); - uiItemR(row, ptr, "screw_offset", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "iterations", 0, NULL, ICON_NONE); + uiItemR(row, ptr, "screw_offset", 0, nullptr, ICON_NONE); + uiItemR(col, ptr, "iterations", 0, nullptr, ICON_NONE); uiItemS(layout); col = uiLayoutColumn(layout, false); row = uiLayoutRow(col, false); - uiItemR(row, ptr, "axis", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemR(row, ptr, "axis", UI_ITEM_R_EXPAND, nullptr, ICON_NONE); uiItemR(col, ptr, "object", 0, IFACE_("Axis Object"), ICON_NONE); sub = uiLayoutColumn(col, false); uiLayoutSetActive(sub, !RNA_pointer_is_null(&screw_obj_ptr)); - uiItemR(sub, ptr, "use_object_screw_offset", 0, NULL, ICON_NONE); + uiItemR(sub, ptr, "use_object_screw_offset", 0, nullptr, ICON_NONE); uiItemS(layout); @@ -1103,26 +1106,26 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) modifier_panel_end(layout, ptr); } -static void normals_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void normals_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col; uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiLayoutSetPropSep(layout, true); col = uiLayoutColumn(layout, false); - uiItemR(col, ptr, "use_smooth_shade", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "use_normal_calculate", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "use_normal_flip", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "use_smooth_shade", 0, nullptr, ICON_NONE); + uiItemR(col, ptr, "use_normal_calculate", 0, nullptr, ICON_NONE); + uiItemR(col, ptr, "use_normal_flip", 0, nullptr, ICON_NONE); } static void panelRegister(ARegionType *region_type) { PanelType *panel_type = modifier_panel_register(region_type, eModifierType_Screw, panel_draw); modifier_subpanel_register( - region_type, "normals", "Normals", NULL, normals_panel_draw, panel_type); + region_type, "normals", "Normals", nullptr, normals_panel_draw, panel_type); } ModifierTypeInfo modifierType_Screw = { @@ -1138,24 +1141,24 @@ ModifierTypeInfo modifierType_Screw = { /* copyData */ BKE_modifier_copydata_generic, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, + /* deformVerts */ nullptr, + /* deformMatrices */ nullptr, + /* deformVertsEM */ nullptr, + /* deformMatricesEM */ nullptr, /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /* modifyGeometrySet */ nullptr, /* initData */ initData, - /* requiredDataMask */ NULL, - /* freeData */ NULL, - /* isDisabled */ NULL, + /* requiredDataMask */ nullptr, + /* freeData */ nullptr, + /* isDisabled */ nullptr, /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, + /* dependsOnTime */ nullptr, + /* dependsOnNormals */ nullptr, /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, + /* foreachTexLink */ nullptr, + /* freeRuntimeData */ nullptr, /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /* blendWrite */ nullptr, + /* blendRead */ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 897a25711cd..4b0301f2884 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -1831,7 +1831,7 @@ static BMesh *build_skin(SkinNode *skin_nodes, })); so.mat_nr = 0; - /* BMESH_TODO: bumping up the stack level (see MOD_array.c) */ + /* BMESH_TODO: bumping up the stack level (see MOD_array.cc) */ BM_mesh_elem_toolflags_ensure(so.bm); BMO_push(so.bm, NULL); bmesh_edit_begin(so.bm, 0); From 485c5abedc3abda3118e5ba280243093a30b4143 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Tue, 13 Dec 2022 01:45:52 +0100 Subject: [PATCH 0040/1522] Fix T103067: Regression: Workbench render crash in 3.4 The workbench engine assumes that the Z pass exists, but didn't register it before. Since rB3411a96e7493, this is mandatory. --- source/blender/draw/engines/workbench/workbench_render.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/draw/engines/workbench/workbench_render.c b/source/blender/draw/engines/workbench/workbench_render.c index c49578ff170..1ed391400b6 100644 --- a/source/blender/draw/engines/workbench/workbench_render.c +++ b/source/blender/draw/engines/workbench/workbench_render.c @@ -217,4 +217,7 @@ void workbench_render(void *ved, RenderEngine *engine, RenderLayer *render_layer void workbench_render_update_passes(RenderEngine *engine, Scene *scene, ViewLayer *view_layer) { RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA); + if ((view_layer->passflag & SCE_PASS_Z) != 0) { + RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_Z, 1, "Z", SOCK_FLOAT); + } } From 17a20ed7feb4b8d3f44afa4bd68e2fb7f4bd5e4c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Dec 2022 12:21:44 +1100 Subject: [PATCH 0041/1522] Cleanup: resolve missing-declarations warning --- source/blender/editors/space_node/node_select.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index 8b25e173d47..7ecacde3874 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -26,7 +26,8 @@ #include "BKE_node_tree_update.h" #include "BKE_workspace.h" -#include "ED_node.h" /* own include */ +#include "ED_node.h" /* own include */ +#include "ED_node.hh" /* own include */ #include "ED_screen.h" #include "ED_select_utils.h" #include "ED_view3d.h" From 982fb66fb133bbae2d9a80c086b131f4ffdb879f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Dec 2022 11:12:39 +1100 Subject: [PATCH 0042/1522] Build: ensure meson is built before use Meson is built as part of external_python_site_packages, without this dependency it would be called before being built. Also remove Meson as a build requirement since the version is used. --- build_files/build_environment/cmake/check_software.cmake | 1 - build_files/build_environment/cmake/epoxy.cmake | 1 + build_files/build_environment/cmake/fribidi.cmake | 1 + build_files/build_environment/cmake/harfbuzz.cmake | 1 + build_files/build_environment/cmake/mesa.cmake | 2 ++ build_files/build_environment/cmake/wayland.cmake | 3 +++ build_files/build_environment/cmake/wayland_protocols.cmake | 2 ++ 7 files changed, 10 insertions(+), 1 deletion(-) diff --git a/build_files/build_environment/cmake/check_software.cmake b/build_files/build_environment/cmake/check_software.cmake index 34544ca176b..93ea3ff071d 100644 --- a/build_files/build_environment/cmake/check_software.cmake +++ b/build_files/build_environment/cmake/check_software.cmake @@ -12,7 +12,6 @@ if(UNIX) automake bison ${_libtoolize_name} - meson ninja pkg-config tclsh diff --git a/build_files/build_environment/cmake/epoxy.cmake b/build_files/build_environment/cmake/epoxy.cmake index 312784598d4..da9c204d5ec 100644 --- a/build_files/build_environment/cmake/epoxy.cmake +++ b/build_files/build_environment/cmake/epoxy.cmake @@ -26,5 +26,6 @@ endif() add_dependencies( external_epoxy + # Needed for `MESON`. external_python_site_packages ) diff --git a/build_files/build_environment/cmake/fribidi.cmake b/build_files/build_environment/cmake/fribidi.cmake index 6e063eb5b26..9d83191741f 100644 --- a/build_files/build_environment/cmake/fribidi.cmake +++ b/build_files/build_environment/cmake/fribidi.cmake @@ -18,6 +18,7 @@ ExternalProject_Add(external_fribidi add_dependencies( external_fribidi external_python + # Needed for `MESON`. external_python_site_packages ) diff --git a/build_files/build_environment/cmake/harfbuzz.cmake b/build_files/build_environment/cmake/harfbuzz.cmake index 619ed66f603..d889e7e6cb4 100644 --- a/build_files/build_environment/cmake/harfbuzz.cmake +++ b/build_files/build_environment/cmake/harfbuzz.cmake @@ -30,6 +30,7 @@ ExternalProject_Add(external_harfbuzz add_dependencies( external_harfbuzz external_python + # Needed for `MESON`. external_python_site_packages ) diff --git a/build_files/build_environment/cmake/mesa.cmake b/build_files/build_environment/cmake/mesa.cmake index 63b17189e10..8c7ec8fac07 100644 --- a/build_files/build_environment/cmake/mesa.cmake +++ b/build_files/build_environment/cmake/mesa.cmake @@ -53,4 +53,6 @@ add_dependencies( external_mesa ll external_zlib + # Needed for `MESON`. + external_python_site_packages ) diff --git a/build_files/build_environment/cmake/wayland.cmake b/build_files/build_environment/cmake/wayland.cmake index 279ca6a787c..76fbbcf3f97 100644 --- a/build_files/build_environment/cmake/wayland.cmake +++ b/build_files/build_environment/cmake/wayland.cmake @@ -24,4 +24,7 @@ add_dependencies( external_expat external_xml2 external_ffi + + # Needed for `MESON`. + external_python_site_packages ) diff --git a/build_files/build_environment/cmake/wayland_protocols.cmake b/build_files/build_environment/cmake/wayland_protocols.cmake index 6d5ff3eb89e..708d9adba1e 100644 --- a/build_files/build_environment/cmake/wayland_protocols.cmake +++ b/build_files/build_environment/cmake/wayland_protocols.cmake @@ -15,4 +15,6 @@ ExternalProject_Add(external_wayland_protocols add_dependencies( external_wayland_protocols external_wayland + # Needed for `MESON`. + external_python_site_packages ) From dd6f7c131818b12b44e5603427ea3c3438898eaf Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Dec 2022 11:22:05 +1100 Subject: [PATCH 0043/1522] Build: remove patch to build with older meson version for Wayland Revert part of [0] which was required to build with meson 0.55.1, rocky8 has version 0.58.2. [0]; 8bb084cda3c9079ddb55288bd03b0a10df88bf59 --- build_files/build_environment/cmake/wayland.cmake | 1 - build_files/build_environment/patches/wayland.diff | 11 ----------- 2 files changed, 12 deletions(-) delete mode 100644 build_files/build_environment/patches/wayland.diff diff --git a/build_files/build_environment/cmake/wayland.cmake b/build_files/build_environment/cmake/wayland.cmake index 76fbbcf3f97..ab573a8dca9 100644 --- a/build_files/build_environment/cmake/wayland.cmake +++ b/build_files/build_environment/cmake/wayland.cmake @@ -5,7 +5,6 @@ ExternalProject_Add(external_wayland DOWNLOAD_DIR ${DOWNLOAD_DIR} URL_HASH ${WAYLAND_HASH_TYPE}=${WAYLAND_HASH} PREFIX ${BUILD_DIR}/wayland - PATCH_COMMAND ${PATCH_CMD} -d ${BUILD_DIR}/wayland/src/external_wayland < ${PATCH_DIR}/wayland.diff # Use `-E` so the `PKG_CONFIG_PATH` can be defined to link against our own LIBEXPAT & LIBXML2. # # NOTE: passing link args "ffi/lib" should not be needed, but diff --git a/build_files/build_environment/patches/wayland.diff b/build_files/build_environment/patches/wayland.diff deleted file mode 100644 index c080b7b2964..00000000000 --- a/build_files/build_environment/patches/wayland.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- meson.build.orig 2022-06-30 22:59:11.000000000 +0100 -+++ meson.build 2022-09-27 13:21:26.428517668 +0100 -@@ -2,7 +2,7 @@ - 'wayland', 'c', - version: '1.21.0', - license: 'MIT', -- meson_version: '>= 0.56.0', -+ meson_version: '>= 0.55.1', - default_options: [ - 'warning_level=2', - 'buildtype=debugoptimized', From 6ce95c34ae1497ab94ba61f99ed426eadc1bf85d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Dec 2022 11:30:37 +1100 Subject: [PATCH 0044/1522] Build: disable cairo for harfbuzz This is only used for command line utilities, disable the dependency. --- build_files/build_environment/cmake/harfbuzz.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build_files/build_environment/cmake/harfbuzz.cmake b/build_files/build_environment/cmake/harfbuzz.cmake index d889e7e6cb4..3eb994f72fe 100644 --- a/build_files/build_environment/cmake/harfbuzz.cmake +++ b/build_files/build_environment/cmake/harfbuzz.cmake @@ -5,7 +5,7 @@ if(WIN32) set(HARFBUZZ_PKG_ENV FREETYPE_DIR=${LIBDIR}/freetype) else() set(HARFBUZZ_CONFIGURE_ENV ${CONFIGURE_ENV}) - set(HARFBUZZ_PKG_ENV PKG_CONFIG_PATH=${LIBDIR}/freetype/lib/pkgconfig:${LIBDIR}/brotli/lib/pkgconfig:$PKG_CONFIG_PATH) + set(HARFBUZZ_PKG_ENV PKG_CONFIG_PATH=${LIBDIR}/freetype/lib/pkgconfig:${LIBDIR}/brotli/lib/pkgconfig:${LIBDIR}/lib/python3.10/pkgconfig:$PKG_CONFIG_PATH) endif() set(HARFBUZZ_EXTRA_OPTIONS @@ -13,6 +13,9 @@ set(HARFBUZZ_EXTRA_OPTIONS -Dfreetype=enabled -Dglib=disabled -Dgobject=disabled + # Only used for command line utilities, + # disable as this would add an addition & unnecessary build-dependency. + -Dcairo=disabled ) ExternalProject_Add(external_harfbuzz From 2761f7c4a5bda3111ca0948a8ffcb17802f88cbb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Dec 2022 11:34:41 +1100 Subject: [PATCH 0045/1522] Build: fix MESA failing to build with missing EXPAT dependency --- build_files/build_environment/cmake/mesa.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build_files/build_environment/cmake/mesa.cmake b/build_files/build_environment/cmake/mesa.cmake index 8c7ec8fac07..ab07c09cc00 100644 --- a/build_files/build_environment/cmake/mesa.cmake +++ b/build_files/build_environment/cmake/mesa.cmake @@ -33,6 +33,8 @@ set(MESA_EXTRA_FLAGS # At some point we will likely want to support Wayland. # Disable for now since it's not officially supported. -Dplatforms=x11 + # Needed to find the local expat. + --pkg-config-path=${LIBDIR}/expat/lib/pkgconfig --native-file ${BUILD_DIR}/mesa/tmp/native-file.ini ) @@ -53,6 +55,8 @@ add_dependencies( external_mesa ll external_zlib + # Run-time dependency. + external_expat # Needed for `MESON`. external_python_site_packages ) From 9f11129d28da4e361becc8b7dd8bfada0cc0b52d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Dec 2022 11:41:05 +1100 Subject: [PATCH 0046/1522] Build: fix building sndfile with OPUS on Linux The PKGCONFIG file exposes the OPUS include: requiring to be replaced with . Manipulate the PKGCONFIG file instead of patching the source since the small change is only needed in one place. --- build_files/build_environment/cmake/sndfile.cmake | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/build_files/build_environment/cmake/sndfile.cmake b/build_files/build_environment/cmake/sndfile.cmake index 1e4249e7e53..60a33c6a236 100644 --- a/build_files/build_environment/cmake/sndfile.cmake +++ b/build_files/build_environment/cmake/sndfile.cmake @@ -1,9 +1,10 @@ # SPDX-License-Identifier: GPL-2.0-or-later set(SNDFILE_EXTRA_ARGS) -set(SNDFILE_ENV PKG_CONFIG_PATH=${mingw_LIBDIR}/ogg/lib/pkgconfig:${mingw_LIBDIR}/vorbis/lib/pkgconfig:${mingw_LIBDIR}/flac/lib/pkgconfig:${mingw_LIBDIR}/opus/lib/pkgconfig:${mingw_LIBDIR}) +set(SNDFILE_ENV) if(WIN32) + set(SNDFILE_ENV PKG_CONFIG_PATH=${mingw_LIBDIR}/ogg/lib/pkgconfig:${mingw_LIBDIR}/vorbis/lib/pkgconfig:${mingw_LIBDIR}/flac/lib/pkgconfig:${mingw_LIBDIR}/opus/lib/pkgconfig:${mingw_LIBDIR}) set(SNDFILE_ENV set ${SNDFILE_ENV} &&) # Shared for windows because static libs will drag in a libgcc dependency. set(SNDFILE_OPTIONS --disable-static --enable-shared ) @@ -11,6 +12,16 @@ else() set(SNDFILE_OPTIONS --enable-static --disable-shared ) endif() +if(UNIX AND NOT APPLE) + # NOTE(@campbellbarton): For some reason OPUS is alone in referencing the sub-directory, + # manipulate the package-config file to prevent this from happening. + # There is no problem with applying this change multiple times. + # + # Replace: Cflags: -I${includedir}/opus + # With: Cflags: -I${includedir} + set(SNDFILE_ENV sed -i s/{includedir}\\/opus/{includedir}/g ${LIBDIR}/opus/lib/pkgconfig/opus.pc && ${SNDFILE_ENV}) +endif() + ExternalProject_Add(external_sndfile URL file://${PACKAGE_DIR}/${SNDFILE_FILE} DOWNLOAD_DIR ${DOWNLOAD_DIR} From b751c28f78d9cf89d410c990df7eb3b7bedc16e0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Dec 2022 11:44:41 +1100 Subject: [PATCH 0047/1522] Build: resolve build error with vulkan_loader not finding Wayland --- .../build_environment/cmake/vulkan.cmake | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/build_files/build_environment/cmake/vulkan.cmake b/build_files/build_environment/cmake/vulkan.cmake index 1fd94dd59be..578e02ced3e 100644 --- a/build_files/build_environment/cmake/vulkan.cmake +++ b/build_files/build_environment/cmake/vulkan.cmake @@ -30,6 +30,17 @@ set(VULKAN_LOADER_EXTRA_ARGS -DVULKAN_HEADERS_INSTALL_DIR=${LIBDIR}/vulkan_headers ) +if(UNIX AND NOT APPLE) + # These are used in `cmake/FindWayland.cmake` from `external_vulkan_loader`. + # NOTE: When upgrading to CMAKE 3.22 we it would be cleaner to use: `PKG_CONFIG_ARGN`, + # so `pkgconfig` would find wayland. + set(VULKAN_LOADER_EXTRA_ARGS + ${VULKAN_LOADER_EXTRA_ARGS} + -DPKG_WAYLAND_INCLUDE_DIRS=${LIBDIR}/wayland/include + -DPKG_WAYLAND_LIBRARY_DIRS=${LIBDIR}/wayland/lib64 + ) +endif() + ExternalProject_Add(external_vulkan_loader URL file://${PACKAGE_DIR}/${VULKAN_LOADER_FILE} URL_HASH ${VULKAN_LOADER_HASH_TYPE}=${VULKAN_LOADER_HASH} @@ -43,7 +54,12 @@ add_dependencies( external_vulkan_headers ) -if(WIN32) +if(UNIX AND NOT APPLE) + add_dependencies( + external_vulkan_loader + external_wayland + ) +elseif(WIN32) if(BUILD_MODE STREQUAL Release) ExternalProject_Add_Step(external_vulkan_loader after_install COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/vulkan_loader/ ${HARVEST_TARGET}/vulkan From cfcc728de636963203ca5697226cebd7a314428f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Dec 2022 12:02:26 +1100 Subject: [PATCH 0048/1522] Cleanup: split python packages across multiple lines Having all packages on one line made reviewing changes difficult. Also note why Python modules are needed (with some TODO's where I wasn't able to find any reason given for their inclusion). --- .../build_environment/cmake/options.cmake | 2 +- .../cmake/python_site_packages.cmake | 24 ++++++++++++++++--- .../build_environment/cmake/versions.cmake | 20 +++++++++++++--- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/build_files/build_environment/cmake/options.cmake b/build_files/build_environment/cmake/options.cmake index 44eca741e77..0a7548f95fb 100644 --- a/build_files/build_environment/cmake/options.cmake +++ b/build_files/build_environment/cmake/options.cmake @@ -117,7 +117,7 @@ else() set(LIBEXT ".a") set(LIBPREFIX "lib") set(MESON ${LIBDIR}/python/bin/meson) -if(APPLE) + if(APPLE) set(SHAREDLIBEXT ".dylib") # Use same Xcode detection as Blender itself. diff --git a/build_files/build_environment/cmake/python_site_packages.cmake b/build_files/build_environment/cmake/python_site_packages.cmake index 4c0e7b1996c..93bfd00a721 100644 --- a/build_files/build_environment/cmake/python_site_packages.cmake +++ b/build_files/build_environment/cmake/python_site_packages.cmake @@ -5,7 +5,11 @@ if(WIN32 AND BUILD_MODE STREQUAL Debug) # zstandard is determined to build and link release mode libs in a debug # configuration, the only way to make it happy is to bend to its will # and give it a library to link with. - set(PIP_CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/python/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}_d.lib ${LIBDIR}/python/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}.lib) + set( + PIP_CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy + ${LIBDIR}/python/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}_d.lib + ${LIBDIR}/python/libs/python${PYTHON_SHORT_VERSION_NO_DOTS}.lib + ) else() set(PIP_CONFIGURE_COMMAND echo ".") endif() @@ -15,9 +19,23 @@ ExternalProject_Add(external_python_site_packages CONFIGURE_COMMAND ${PIP_CONFIGURE_COMMAND} BUILD_COMMAND "" PREFIX ${BUILD_DIR}/site_packages - # setuptools is downgraded to 63.2.0 (same as python 3.10.8) since numpy 1.23.x seemingly has + + # setuptools is downgraded to 63.2.0 (same as python 3.10.8) since numpy 1.23.x seemingly has # issues building on windows with the newer versions that ships with python 3.10.9+ - INSTALL_COMMAND ${PYTHON_BINARY} -m pip install --no-cache-dir ${SITE_PACKAGES_EXTRA} setuptools==63.2.0 cython==${CYTHON_VERSION} idna==${IDNA_VERSION} charset-normalizer==${CHARSET_NORMALIZER_VERSION} urllib3==${URLLIB3_VERSION} certifi==${CERTIFI_VERSION} requests==${REQUESTS_VERSION} zstandard==${ZSTANDARD_VERSION} autopep8==${AUTOPEP8_VERSION} pycodestyle==${PYCODESTYLE_VERSION} toml==${TOML_VERSION} meson==${MESON_VERSION} --no-binary :all: + INSTALL_COMMAND ${PYTHON_BINARY} -m pip install --no-cache-dir ${SITE_PACKAGES_EXTRA} + setuptools==63.2.0 + cython==${CYTHON_VERSION} + idna==${IDNA_VERSION} + charset-normalizer==${CHARSET_NORMALIZER_VERSION} + urllib3==${URLLIB3_VERSION} + certifi==${CERTIFI_VERSION} + requests==${REQUESTS_VERSION} + zstandard==${ZSTANDARD_VERSION} + autopep8==${AUTOPEP8_VERSION} + pycodestyle==${PYCODESTYLE_VERSION} + toml==${TOML_VERSION} + meson==${MESON_VERSION} + --no-binary :all: ) if(USE_PIP_NUMPY) diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 86f9d8349b1..097f632b356 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -203,7 +203,7 @@ set(OSL_FILE OpenShadingLanguage-${OSL_VERSION}.tar.gz) # NOTE: When updating the python version, it's required to check the versions of # it wants to use in PCbuild/get_externals.bat for the following dependencies: -# BZIP2, FFI, SQLITE and change the versions in this file as well. For compliance +# BZIP2, FFI, SQLITE and change the versions in this file as well. For compliance # reasons there can be no exceptions to this. set(PYTHON_VERSION 3.10.9) @@ -229,20 +229,34 @@ set(OPENVDB_HASH 64301c737e16b26c8f3085a31e6397e9) set(OPENVDB_HASH_TYPE MD5) set(OPENVDB_FILE openvdb-${OPENVDB_VERSION}.tar.gz) +# ------------------------------------------------------------------------------ +# Python Modules + +# Needed by: TODO. set(IDNA_VERSION 3.3) +# Needed by: TODO. set(CHARSET_NORMALIZER_VERSION 2.0.10) +# Needed by: TODO. set(URLLIB3_VERSION 1.26.8) set(URLLIB3_CPE "cpe:2.3:a:urllib3:urllib3:${URLLIB3_VERSION}:*:*:*:*:*:*:*") +# Needed by: Python's `requests` module (so add-ons can authenticate against trusted certificates). set(CERTIFI_VERSION 2021.10.8) +# Needed by: Some of Blender's add-ons (to support convenient interaction with online services). set(REQUESTS_VERSION 2.27.1) +# Needed by: Python's `numpy` module (used by some add-ons). set(CYTHON_VERSION 0.29.30) -# The version of the zstd library used to build the Python package should match ZSTD_VERSION +# Needed by: Python scripts that read `.blend` files, as files may use Z-standard compression. +# The version of the ZSTD library used to build the Python package should match ZSTD_VERSION # defined below. At this time of writing, 0.17.0 was already released, -# but built against zstd 1.5.1, while we use 1.5.0. +# but built against ZSTD 1.5.1, while we use 1.5.0. set(ZSTANDARD_VERSION 0.16.0) +# Auto-format Python source (developer tool, not used by Blender at run-time). set(AUTOPEP8_VERSION 1.6.0) +# Needed by: `autopep8` (so the version doesn't change on rebuild). set(PYCODESTYLE_VERSION 2.8.0) +# Needed by: `autopep8` (so the version doesn't change on rebuild). set(TOML_VERSION 0.10.2) +# Build system for other packages (not used by Blender at run-time). set(MESON_VERSION 0.63.0) set(NUMPY_VERSION 1.23.5) From adb49ffa240e2ef99a6a2ddb86666b2f06514b27 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Dec 2022 12:34:32 +1100 Subject: [PATCH 0049/1522] Cleanup: spelling in comments --- source/blender/blenkernel/intern/boids.c | 2 +- source/blender/blenkernel/intern/key.cc | 2 +- source/blender/blenkernel/intern/volume.cc | 6 +++--- source/blender/draw/engines/eevee/eevee_shaders.cc | 4 ++-- .../eevee/shaders/infos/eevee_legacy_common_info.hh | 6 +++--- .../eevee/shaders/infos/eevee_legacy_volume_info.hh | 2 +- source/blender/editors/interface/interface_handlers.cc | 2 +- source/blender/editors/interface/interface_icons.cc | 2 +- source/blender/gpu/GPU_texture.h | 8 ++++---- source/blender/gpu/intern/gpu_shader_create_info.cc | 4 ++-- source/blender/gpu/intern/gpu_shader_create_info.hh | 2 +- source/blender/gpu/intern/gpu_texture_private.hh | 2 +- source/blender/gpu/metal/mtl_batch.mm | 2 +- source/blender/gpu/metal/mtl_texture.mm | 6 +++--- .../blender/nodes/composite/nodes/node_composite_glare.cc | 6 +++--- 15 files changed, 28 insertions(+), 28 deletions(-) diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index a0458f0f8d8..63e393aa4f0 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -1127,7 +1127,7 @@ void boid_brain(BoidBrainData *bbd, int p, ParticleData *pa) /* decide on jumping & liftoff */ if (bpa->data.mode == eBoidMode_OnLand) { - /* fuzziness makes boids capable of misjudgement */ + /* Fuzziness makes boids capable of misjudgment. */ float mul = 1.0f + state->rule_fuzziness; if (boids->options & BOID_ALLOW_FLIGHT && bbd->wanted_co[2] > 0.0f) { diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index d3eb56d1563..7db815e7f9d 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -1877,7 +1877,7 @@ KeyBlock *BKE_keyblock_add_ctime(Key *key, const char *name, const bool do_force const float cpos = key->ctime / 100.0f; /* In case of absolute keys, there is no point in adding more than one key with the same pos. - * Hence only set new keybloc pos to current time if none previous one already use it. + * Hence only set new key-block pos to current time if none previous one already use it. * Now at least people just adding absolute keys without touching to ctime * won't have to systematically use retiming func (and have ordering issues, too). See T39897. */ diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index ae921764de4..b768ad07aa0 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -320,11 +320,11 @@ struct VolumeGrid { openvdb::io::File file(filepath); - /* Isolate file loading since that's potentially multithreaded and we are + /* Isolate file loading since that's potentially multi-threaded and we are * holding a mutex lock. */ blender::threading::isolate_task([&] { try { - /* Disably delay loading and file copying, this has poor performance + /* Disable delay loading and file copying, this has poor performance * on network drivers. */ const bool delay_load = false; file.setCopyMaxBytes(0); @@ -886,7 +886,7 @@ bool BKE_volume_load(const Volume *volume, const Main *bmain) openvdb::GridPtrVec vdb_grids; try { - /* Disably delay loading and file copying, this has poor performance + /* Disable delay loading and file copying, this has poor performance * on network drivers. */ const bool delay_load = false; file.setCopyMaxBytes(0); diff --git a/source/blender/draw/engines/eevee/eevee_shaders.cc b/source/blender/draw/engines/eevee/eevee_shaders.cc index fbdefcd8bee..d7901a9fac4 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders.cc +++ b/source/blender/draw/engines/eevee/eevee_shaders.cc @@ -1158,7 +1158,7 @@ World *EEVEE_world_default_get(void) * Source is provided separately, rather than via create-info as source is manipulated * by `eevee_shader_material_create_info_amend`. * - * We also retain the previous behaviour for ensuring library includes occur in the + * We also retain the previous behavior for ensuring library includes occur in the * correct order. */ static const char *eevee_get_vert_info(int options, char **r_src) { @@ -1288,7 +1288,7 @@ static char *eevee_get_defines(int options) * CreateInfo's for EEVEE materials are declared in: * `eevee/shaders/infos/eevee_legacy_material_info.hh` * - * This function should only contain defines which alter behaviour, but do not affect shader + * This function should only contain defines which alter behavior, but do not affect shader * resources. */ if ((options & VAR_WORLD_BACKGROUND) != 0) { diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh index 2b6f31774b3..45ecd339f5f 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh @@ -21,7 +21,7 @@ GPU_SHADER_CREATE_INFO(eevee_legacy_irradiance_lib) GPU_SHADER_CREATE_INFO(eevee_legacy_common_utiltex_lib) .sampler(2, ImageType::FLOAT_2D_ARRAY, "utilTex"); -/* Raytrace lib. */ +/* Ray-trace lib. */ GPU_SHADER_CREATE_INFO(eevee_legacy_raytrace_lib) .additional_info("draw_view") .additional_info("eevee_legacy_common_lib") @@ -33,7 +33,7 @@ GPU_SHADER_CREATE_INFO(eevee_legacy_ambient_occlusion_lib) .additional_info("eevee_legacy_raytrace_lib") .sampler(5, ImageType::FLOAT_2D, "horizonBuffer"); -/* Lightprobe lib. */ +/* Light-probe lib. */ GPU_SHADER_CREATE_INFO(eevee_legacy_lightprobe_lib) .additional_info("eevee_legacy_common_lib") .additional_info("eevee_legacy_common_utiltex_lib") @@ -128,7 +128,7 @@ GPU_SHADER_CREATE_INFO(eevee_legacy_surface_lib_hair) GPU_SHADER_CREATE_INFO(eevee_legacy_surface_lib_pointcloud) .define("USE_SURFACE_LIB_POINTCLOUD") - /* Pointcloud still uses the common interface as well. */ + /* Point-cloud still uses the common interface as well. */ .additional_info("eevee_legacy_surface_lib_common") .vertex_out(eevee_legacy_surface_point_cloud_iface); diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_volume_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_volume_info.hh index a95d734de56..e283536e182 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_volume_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_volume_info.hh @@ -2,7 +2,7 @@ #pragma once -/* Voluemtric iface. */ +/* Volumetric iface. */ GPU_SHADER_INTERFACE_INFO(legacy_volume_vert_geom_iface, "volumetric_vert_iface") .smooth(Type::VEC4, "vPos"); diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index f303dfa146c..2d90b6f0d22 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -995,7 +995,7 @@ static void ui_apply_but_funcs_after(bContext *C) BLI_listbase_clear(&UIAfterFuncs); LISTBASE_FOREACH_MUTABLE (uiAfterFunc *, afterf, &funcs) { - uiAfterFunc after = *afterf; /* copy to avoid memleak on exit() */ + uiAfterFunc after = *afterf; /* Copy to avoid memory leak on exit(). */ BLI_freelinkN(&funcs, afterf); if (after.context) { diff --git a/source/blender/editors/interface/interface_icons.cc b/source/blender/editors/interface/interface_icons.cc index 08804be4d04..8f6b46aa717 100644 --- a/source/blender/editors/interface/interface_icons.cc +++ b/source/blender/editors/interface/interface_icons.cc @@ -2312,7 +2312,7 @@ int UI_icon_from_rnaptr(const bContext *C, PointerRNA *ptr, int rnaicon, const b return rnaicon; } - /* try ID, material, texture or dynapaint slot */ + /* Try ID, material, texture or dynamic-paint slot. */ if (RNA_struct_is_ID(ptr->type)) { id = ptr->owner_id; } diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index fd3c938b56f..6cbdda4cd4c 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -187,7 +187,7 @@ typedef enum eGPUDataFormat { } eGPUDataFormat; /** Texture usage flags. - * Texture usage flags allow backend implementations to contextually optimise texture resources. + * Texture usage flags allow backend implementations to contextually optimize texture resources. * Any texture with an explicit flag should not perform operations which are not explicitly * specified in the usage flags. If usage is unknown upfront, then GPU_TEXTURE_USAGE_GENERAL can be * used. @@ -202,7 +202,7 @@ typedef enum eGPUTextureUsage { GPU_TEXTURE_USAGE_SHADER_READ = (1 << 0), /* Whether the texture is written to by a shader using imageStore. */ GPU_TEXTURE_USAGE_SHADER_WRITE = (1 << 1), - /* Whether a texture is used as an attachment in a framebuffer. */ + /* Whether a texture is used as an attachment in a frame-buffer. */ GPU_TEXTURE_USAGE_ATTACHMENT = (1 << 2), /* Whether the texture is used as a texture view, uses mip-map layer adjustment, * OR, uses swizzle access masks. Mip-map base layer adjustment and texture channel swizzling @@ -226,11 +226,11 @@ unsigned int GPU_texture_memory_usage_get(void); * \note \a data is expected to be float. If the \a format is not compatible with float data or if * the data is not in float format, use GPU_texture_update to upload the data with the right data * format. - * NOTE: _ex variants of texure creation functions allow specification of explicit usage for + * NOTE: `_ex` variants of texture creation functions allow specification of explicit usage for * optimal performance. Using standard texture creation will use the `GPU_TEXTURE_USAGE_GENERAL`. * * Textures created via other means will either inherit usage from the source resource, or also - * be initialised with `GPU_TEXTURE_USAGE_GENERAL`. + * be initialized with `GPU_TEXTURE_USAGE_GENERAL`. * * flag. \a mips is the number of mip level to allocate. It must be >= 1. */ diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc index 4544937d6fa..bc3f462e9f9 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.cc +++ b/source/blender/gpu/intern/gpu_shader_create_info.cc @@ -357,13 +357,13 @@ void gpu_shader_create_info_init() basic_depth_pointcloud_conservative_clipped = basic_depth_pointcloud_conservative_no_geom_clipped; - /* Overlay prepass wire. */ + /* Overlay pre-pass wire. */ overlay_outline_prepass_wire = overlay_outline_prepass_wire_no_geom; /* Edit UV Edges. */ overlay_edit_uv_edges = overlay_edit_uv_edges_no_geom; - /* Downsample Cube/Proe rendering. */ + /* Down-sample Cube/Probe rendering. */ eevee_legacy_effect_downsample_cube = eevee_legacy_effect_downsample_cube_no_geom; eevee_legacy_probe_filter_glossy = eevee_legacy_probe_filter_glossy_no_geom; eevee_legacy_lightprobe_planar_downsample = eevee_legacy_lightprobe_planar_downsample_no_geom; diff --git a/source/blender/gpu/intern/gpu_shader_create_info.hh b/source/blender/gpu/intern/gpu_shader_create_info.hh index 4bc340fd213..04d72716e8e 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.hh +++ b/source/blender/gpu/intern/gpu_shader_create_info.hh @@ -845,7 +845,7 @@ struct ShaderCreateInfo { /* -------------------------------------------------------------------- */ /** \name Transform feedback properties * - * Transform feedback enablement and output binding assignmnt. + * Transform feedback enablement and output binding assignment. * \{ */ Self &transform_feedback_mode(eGPUShaderTFBType tf_mode) diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh index 71fd34aab13..115e38443b5 100644 --- a/source/blender/gpu/intern/gpu_texture_private.hh +++ b/source/blender/gpu/intern/gpu_texture_private.hh @@ -82,7 +82,7 @@ class Texture { eGPUTextureFormatFlag format_flag_; /** Texture type. */ eGPUTextureType type_; - /** Texutre usage flags */ + /** Texture usage flags. */ eGPUTextureUsage gpu_image_usage_flags_; /** Number of mipmaps this texture has (Max miplvl). */ diff --git a/source/blender/gpu/metal/mtl_batch.mm b/source/blender/gpu/metal/mtl_batch.mm index ab2c8f3e79f..768278ec0c6 100644 --- a/source/blender/gpu/metal/mtl_batch.mm +++ b/source/blender/gpu/metal/mtl_batch.mm @@ -533,7 +533,7 @@ id MTLBatch::bind(uint v_first, uint v_count, uint i_fi } /* Ensure Context Render Pipeline State is fully setup and ready to execute the draw. - * This should happen after all other final rendeirng setup is complete. */ + * This should happen after all other final rendering setup is complete. */ MTLPrimitiveType mtl_prim_type = gpu_prim_type_to_metal(this->prim_type); if (!ctx->ensure_render_pipeline_state(mtl_prim_type)) { printf("FAILED TO ENSURE RENDER PIPELINE STATE"); diff --git a/source/blender/gpu/metal/mtl_texture.mm b/source/blender/gpu/metal/mtl_texture.mm index b53fe0fb714..303c971f0f5 100644 --- a/source/blender/gpu/metal/mtl_texture.mm +++ b/source/blender/gpu/metal/mtl_texture.mm @@ -223,7 +223,7 @@ id gpu::MTLTexture::get_metal_handle() if (mip_swizzle_view_ != nil || texture_view_dirty_flags_) { bake_mip_swizzle_view(); - /* Optimisation: If texture view does not change mip parameters, no texture view will be + /* Optimization: If texture view does not change mip parameters, no texture view will be * baked. This is because texture views remove the ability to perform lossless compression. */ if (mip_swizzle_view_ != nil) { @@ -620,7 +620,7 @@ void gpu::MTLTexture::update_sub( BLI_assert(blit_encoder != nil); /* If we need to use a texture view to write texture data as the source - * format is unwritable, if our texture has not been initialised with + * format is unwritable, if our texture has not been initialized with * texture view support, use a staging texture. */ if ((compatible_write_format != destination_format) && !(gpu_image_usage_flags_ & GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW)) { @@ -646,7 +646,7 @@ void gpu::MTLTexture::update_sub( /* Allocate stating texture if needed. */ if (use_staging_texture) { - /* Create staging texture to avoid shader-write limiting optimisation. */ + /* Create staging texture to avoid shader-write limiting optimization. */ BLI_assert(texture_descriptor_ != nullptr); MTLTextureUsage original_usage = texture_descriptor_.usage; texture_descriptor_.usage = original_usage | MTLTextureUsageShaderWrite | diff --git a/source/blender/nodes/composite/nodes/node_composite_glare.cc b/source/blender/nodes/composite/nodes/node_composite_glare.cc index d92df4c4b38..86888cd039d 100644 --- a/source/blender/nodes/composite/nodes/node_composite_glare.cc +++ b/source/blender/nodes/composite/nodes/node_composite_glare.cc @@ -384,7 +384,7 @@ class GlareOperation : public NodeOperation { /* For the given number of iterations, accumulate four ghosts with different scales and color * modulators. The result of the previous iteration is used as the input of the current * iteration. We start from index 1 because we are not interested in the scales produced for - * the first iteration according to visual judgement, see the compute_ghost_scales method. */ + * the first iteration according to visual judgment, see the compute_ghost_scales method. */ Result &input_ghost_result = base_ghost_result; const IndexRange iterations_range = IndexRange(get_number_of_iterations()).drop_front(1); for (const int i : iterations_range) { @@ -492,7 +492,7 @@ class GlareOperation : public NodeOperation { * have n number of iterations, that means the total number of accumulations is 4 * n. To get a * variety of scales, we generate an arithmetic progression that starts from 2.1 and ends at * zero exclusive, containing 4 * n elements. The start scale of 2.1 is chosen arbitrarily using - * visual judgement. To get more scale variations, every other scale is inverted with a slight + * visual judgment. To get more scale variations, every other scale is inverted with a slight * change in scale such that it alternates between scaling down and up, additionally every other * ghost is flipped across the image center by negating its scale. Finally, to get variations * across the number of iterations, a shift of 0.5 is introduced when the number of iterations is @@ -524,7 +524,7 @@ class GlareOperation : public NodeOperation { /* The operation computes two base ghosts by blurring the highlights with two different radii, * this method computes the blur radius for the smaller one. The value is chosen using visual - * judgement. Make sure to take the quality factor into account, see the get_quality_factor + * judgment. Make sure to take the quality factor into account, see the get_quality_factor * method for more information. */ float get_small_ghost_radius() { From e6e57cebecd13c2f30cee3a8262eda3c3191acbd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 13 Dec 2022 12:46:12 +1100 Subject: [PATCH 0050/1522] CMake: add missing headers --- source/blender/blenkernel/CMakeLists.txt | 2 ++ source/blender/draw/CMakeLists.txt | 2 ++ source/blender/editors/util/CMakeLists.txt | 1 + 3 files changed, 5 insertions(+) diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 227c9bd8c66..7bd87323ede 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -480,6 +480,7 @@ set(SRC BKE_type_conversions.hh BKE_undo_system.h BKE_unit.h + BKE_uv_islands.hh BKE_vfont.h BKE_vfontdata.h BKE_viewer_path.h @@ -504,6 +505,7 @@ set(SRC intern/multires_unsubdivide.h intern/ocean_intern.h intern/pbvh_intern.h + intern/pbvh_uv_islands.hh intern/subdiv_converter.h intern/subdiv_inline.h ) diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 513029bc675..2093c8a2331 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -280,6 +280,7 @@ set(SRC engines/image/image_buffer_cache.hh engines/image/image_drawing_mode.hh engines/image/image_engine.h + engines/image/image_enums.hh engines/image/image_instance_data.hh engines/image/image_partial_updater.hh engines/image/image_private.hh @@ -534,6 +535,7 @@ set(GLSL_SRC intern/draw_command_shared.hh intern/draw_common_shader_shared.h intern/draw_defines.h + intern/draw_pointcloud_private.hh intern/draw_shader_shared.h engines/gpencil/shaders/gpencil_frag.glsl diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index 8430f69b632..c15db57d3b7 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -63,6 +63,7 @@ set(SRC ../include/ED_mball.h ../include/ED_mesh.h ../include/ED_node.h + ../include/ED_node.hh ../include/ED_numinput.h ../include/ED_object.h ../include/ED_outliner.h From 8f5df25f33987120f3852c99a4ae5d1c72dd5912 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 13 Dec 2022 09:14:33 +0100 Subject: [PATCH 0051/1522] Cleanup: Use BKE_brush_mask_texture_get in sculpt code. In preparation to sanatize the mask texture and color texture in sculpt code. In sculpt mode the mask texture is read from mtex, leaving the mask_mtex when we want to use color textures in sculpt mode. --- source/blender/editors/sculpt_paint/sculpt.cc | 31 ++++++++++++------- .../editors/sculpt_paint/sculpt_expand.c | 9 +++--- .../editors/sculpt_paint/sculpt_intern.h | 2 +- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 113fec4fcdf..98cb6130f87 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -1319,6 +1319,7 @@ static bool sculpt_brush_use_topology_rake(const SculptSession *ss, const Brush */ static int sculpt_brush_needs_normal(const SculptSession *ss, Sculpt *sd, const Brush *brush) { + const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT); return ((SCULPT_TOOL_HAS_NORMAL_WEIGHT(brush->sculpt_tool) && (ss->cache->normal_weight > 0.0f)) || SCULPT_automasking_needs_normal(ss, sd, brush) || @@ -1334,7 +1335,7 @@ static int sculpt_brush_needs_normal(const SculptSession *ss, Sculpt *sd, const SCULPT_TOOL_ELASTIC_DEFORM, SCULPT_TOOL_THUMB) || - (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)) || + (mask_tex->brush_map_mode == MTEX_MAP_MODE_AREA)) || sculpt_brush_use_topology_rake(ss, brush); } @@ -2861,7 +2862,10 @@ static void calc_local_y(ViewContext *vc, const float center[3], float y[3]) mul_m4_v3(ob->world_to_object, y); } -static void calc_brush_local_mat(const Brush *brush, Object *ob, float local_mat[4][4]) +static void calc_brush_local_mat(const Brush *brush, + const MTex *mtex, + Object *ob, + float local_mat[4][4]) { const StrokeCache *cache = ob->sculpt->cache; float tmat[4][4]; @@ -2885,7 +2889,7 @@ static void calc_brush_local_mat(const Brush *brush, Object *ob, float local_mat /* Calculate the X axis of the local matrix. */ cross_v3_v3v3(v, up, cache->sculpt_normal); /* Apply rotation (user angle, rake, etc.) to X axis. */ - angle = brush->mtex.rot - cache->special_rotation; + angle = mtex->rot - cache->special_rotation; rotate_v3_v3v3fl(mat[0], v, cache->sculpt_normal, angle); /* Get other axes. */ @@ -2932,7 +2936,9 @@ static void update_brush_local_mat(Sculpt *sd, Object *ob) StrokeCache *cache = ob->sculpt->cache; if (cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0) { - calc_brush_local_mat(BKE_paint_brush(&sd->paint), ob, cache->brush_local_mat); + const Brush *brush = BKE_paint_brush(&sd->paint); + const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT); + calc_brush_local_mat(brush, mask_tex, ob, cache->brush_local_mat); } } @@ -3512,7 +3518,8 @@ static void do_brush_action(Sculpt *sd, update_sculpt_normal(sd, ob, nodes, totnode); } - if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) { + const MTex *mask_tex = BKE_brush_mask_texture_get(brush, static_cast(ob->mode)); + if (mask_tex->brush_map_mode == MTEX_MAP_MODE_AREA) { update_brush_local_mat(sd, ob); } @@ -4047,7 +4054,7 @@ static void sculpt_fix_noise_tear(Sculpt *sd, Object *ob) { SculptSession *ss = ob->sculpt; Brush *brush = BKE_paint_brush(&sd->paint); - MTex *mtex = &brush->mtex; + const MTex *mtex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT); if (ss->multires.active && mtex->tex && mtex->tex->type == TEX_NOISE) { multires_stitch_grids(ob); @@ -5196,12 +5203,12 @@ bool SCULPT_stroke_get_location(bContext *C, static void sculpt_brush_init_tex(Sculpt *sd, SculptSession *ss) { Brush *brush = BKE_paint_brush(&sd->paint); - MTex *mtex = &brush->mtex; + const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT); /* Init mtex nodes. */ - if (mtex->tex && mtex->tex->nodetree) { + if (mask_tex->tex && mask_tex->tex->nodetree) { /* Has internal flag to detect it only does it once. */ - ntreeTexBeginExecTree(mtex->tex->nodetree); + ntreeTexBeginExecTree(mask_tex->tex->nodetree); } if (ss->tex_pool == nullptr) { @@ -5630,10 +5637,10 @@ static void sculpt_stroke_update_step(bContext *C, static void sculpt_brush_exit_tex(Sculpt *sd) { Brush *brush = BKE_paint_brush(&sd->paint); - MTex *mtex = &brush->mtex; + const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT); - if (mtex->tex && mtex->tex->nodetree) { - ntreeTexEndExecTree(mtex->tex->nodetree->runtime->execdata); + if (mask_tex->tex && mask_tex->tex->nodetree) { + ntreeTexEndExecTree(mask_tex->tex->nodetree->runtime->execdata); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index c4955ab1f03..a8496712c41 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -193,7 +193,8 @@ static float sculpt_expand_max_vertex_falloff_get(ExpandCache *expand_cache) return expand_cache->max_vert_falloff; } - if (!expand_cache->brush->mtex.tex) { + const MTex *mask_tex = BKE_brush_mask_texture_get(expand_cache->brush, OB_MODE_SCULPT); + if (!mask_tex->tex) { return expand_cache->max_vert_falloff; } @@ -1882,13 +1883,14 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event } case SCULPT_EXPAND_MODAL_TEXTURE_DISTORTION_INCREASE: { if (expand_cache->texture_distortion_strength == 0.0f) { - if (expand_cache->brush->mtex.tex == NULL) { + const MTex *mask_tex = BKE_brush_mask_texture_get(expand_cache->brush, OB_MODE_SCULPT); + if (mask_tex->tex == NULL) { BKE_report(op->reports, RPT_WARNING, "Active brush does not contain any texture to distort the expand boundary"); break; } - if (expand_cache->brush->mtex.brush_map_mode != MTEX_MAP_MODE_3D) { + if (mask_tex->brush_map_mode != MTEX_MAP_MODE_3D) { BKE_report(op->reports, RPT_WARNING, "Texture mapping not set to 3D, results may be unpredictable"); @@ -2052,7 +2054,6 @@ static void sculpt_expand_cache_initial_config_set(bContext *C, IMB_colormanagement_srgb_to_scene_linear_v3(expand_cache->fill_color, expand_cache->fill_color); expand_cache->scene = CTX_data_scene(C); - expand_cache->mtex = &expand_cache->brush->mtex; expand_cache->texture_distortion_strength = 0.0f; expand_cache->blend_mode = expand_cache->brush->blend; } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 3fca2d096d1..e660e8fa8ac 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -752,7 +752,7 @@ typedef struct ExpandCache { /* Texture distortion data. */ Brush *brush; struct Scene *scene; - struct MTex *mtex; + // struct MTex *mtex; /* Controls how much texture distortion will be applied to the current falloff */ float texture_distortion_strength; From a14a15202407b14b73188e1f0997bcad9c670ab5 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 13 Dec 2022 10:15:32 +0100 Subject: [PATCH 0052/1522] PBVH: Fix crash with incorrect initialized span lengths. PBVH doesn't store the loop size. We need to get that from the mesh. We should perhaps also store the mloop len insize the PBVH. --- source/blender/blenkernel/intern/pbvh_pixels.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index bb7e912fd94..e21103c9f19 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -362,9 +362,9 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image } uv_islands::MeshData mesh_data({pbvh->looptri, pbvh->totprim}, - {pbvh->mloop, pbvh->totprim}, + {pbvh->mloop, mesh->totloop}, pbvh->totvert, - {ldata_uv, pbvh->totprim}); + {ldata_uv, mesh->totloop}); uv_islands::UVIslands islands(mesh_data); uv_islands::UVIslandsMask uv_masks; From e8c7866608bb71b674afd9420a22b993e066f873 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Tue, 13 Dec 2022 11:12:36 +0100 Subject: [PATCH 0053/1522] Add-ons: Exclude contrib for beta, rc and release builds. * Make it clearer that contrib isn't shipped with releases, by already excluding it in beta. * Improve the UI by hiding the "Testing" enum item in these case. Differential Revision: https://developer.blender.org/D16729 --- release/scripts/startup/bl_ui/__init__.py | 16 +++++++++++----- source/creator/CMakeLists.txt | 5 +++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index eaf61b58e6d..4822370c9ea 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -94,6 +94,16 @@ _namespace = globals() _modules_loaded = [_namespace[name] for name in _modules] del _namespace +def _addon_support_items(): + """Return the addon support levels suitable for this Blender build.""" + + items = [ + ('OFFICIAL', "Official", "Officially supported"), + ('COMMUNITY', "Community", "Maintained by community developers"), + ] + if bpy.app.version_cycle == 'alpha': + items.append(('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)")) + return items def register(): from bpy.utils import register_class @@ -141,11 +151,7 @@ def register(): ) WindowManager.addon_support = EnumProperty( - items=[ - ('OFFICIAL', "Official", "Officially supported"), - ('COMMUNITY', "Community", "Maintained by community developers"), - ('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)") - ], + items=_addon_support_items(), name="Support", description="Display support level", default={'OFFICIAL', 'COMMUNITY'}, diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 6837bc0da9e..82a37614841 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -394,9 +394,10 @@ install( if(WITH_PYTHON) # install(CODE "message(\"copying blender scripts...\")") - # exclude addons_contrib if release + # exclude addons_contrib if release branch if("${BLENDER_VERSION_CYCLE}" STREQUAL "release" OR - "${BLENDER_VERSION_CYCLE}" STREQUAL "rc") + "${BLENDER_VERSION_CYCLE}" STREQUAL "rc" OR + "${BLENDER_VERSION_CYCLE}" STREQUAL "beta") set(ADDON_EXCLUDE_CONDITIONAL "addons_contrib/*") else() set(ADDON_EXCLUDE_CONDITIONAL "_addons_contrib/*") # Dummy, won't do anything. From 85a743e08bfcaa321c7f0e7ced6bf9003a359888 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Tue, 13 Dec 2022 11:39:13 +0100 Subject: [PATCH 0054/1522] Fix T103061: GPencil export to SVG wrong line thickness When the line was very thin the precision of the thickness calculation was not precise enough. The algorithm has been improved. This affects SVG and PDF. --- source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc | 7 +++++-- source/blender/io/gpencil/intern/gpencil_io_export_svg.cc | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc index c042ca597c8..23fea9b6460 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc @@ -177,7 +177,8 @@ void GpencilExporterPDF::export_gpencil_layers() /* Apply layer thickness change. */ gps_duplicate->thickness += gpl->line_change; /* Apply object scale to thickness. */ - gps_duplicate->thickness *= mat4_to_scale(ob->object_to_world); + const float scalef = mat4_to_scale(ob->object_to_world); + gps_duplicate->thickness = ceilf((float)gps_duplicate->thickness * scalef); CLAMP_MIN(gps_duplicate->thickness, 1.0f); /* Fill. */ if ((is_fill) && (params_.flag & GP_EXPORT_FILL)) { @@ -236,7 +237,9 @@ void GpencilExporterPDF::export_stroke_to_polyline(bGPDlayer *gpl, if (is_stroke && !do_fill) { HPDF_Page_SetLineJoin(page_, HPDF_ROUND_JOIN); - HPDF_Page_SetLineWidth(page_, MAX2((radius * 2.0f) - gpl->line_change, 1.0f)); + const float width = MAX2( + MAX2(gps->thickness + gpl->line_change, (radius * 2.0f) + gpl->line_change), 1.0f); + HPDF_Page_SetLineWidth(page_, width); } /* Loop all points. */ diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc index b85fd33e116..2c4c09ce1a0 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc @@ -198,7 +198,8 @@ void GpencilExporterSVG::export_gpencil_layers() /* Apply layer thickness change. */ gps_duplicate->thickness += gpl->line_change; /* Apply object scale to thickness. */ - gps_duplicate->thickness *= mat4_to_scale(ob->object_to_world); + const float scalef = mat4_to_scale(ob->object_to_world); + gps_duplicate->thickness = ceilf((float)gps_duplicate->thickness * scalef); CLAMP_MIN(gps_duplicate->thickness, 1.0f); const bool is_normalized = ((params_.flag & GP_EXPORT_NORM_THICKNESS) != 0) || @@ -308,7 +309,9 @@ void GpencilExporterSVG::export_stroke_to_polyline(bGPDlayer *gpl, color_string_set(gpl, gps, node_gps, do_fill); if (is_stroke && !do_fill) { - node_gps.append_attribute("stroke-width").set_value((radius * 2.0f) - gpl->line_change); + const float width = MAX2( + MAX2(gps->thickness + gpl->line_change, (radius * 2.0f) + gpl->line_change), 1.0f); + node_gps.append_attribute("stroke-width").set_value(width); } std::string txt; From 9579e3eef2340a336329b8670e9b3923f7d75ce4 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 13 Dec 2022 15:52:50 +0100 Subject: [PATCH 0055/1522] Cleanup: remove unused parameter in calc_brush_local_mat. --- source/blender/editors/sculpt_paint/sculpt.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 98cb6130f87..416f394e8ee 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2862,10 +2862,7 @@ static void calc_local_y(ViewContext *vc, const float center[3], float y[3]) mul_m4_v3(ob->world_to_object, y); } -static void calc_brush_local_mat(const Brush *brush, - const MTex *mtex, - Object *ob, - float local_mat[4][4]) +static void calc_brush_local_mat(const MTex *mtex, Object *ob, float local_mat[4][4]) { const StrokeCache *cache = ob->sculpt->cache; float tmat[4][4]; @@ -2938,7 +2935,7 @@ static void update_brush_local_mat(Sculpt *sd, Object *ob) if (cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0) { const Brush *brush = BKE_paint_brush(&sd->paint); const MTex *mask_tex = BKE_brush_mask_texture_get(brush, OB_MODE_SCULPT); - calc_brush_local_mat(brush, mask_tex, ob, cache->brush_local_mat); + calc_brush_local_mat(mask_tex, ob, cache->brush_local_mat); } } From 0cd56b7a363149198c712d166087bbb63077c857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 13 Dec 2022 16:20:24 +0100 Subject: [PATCH 0056/1522] Fix T101169: fcurve.c: solve_cubic: incorrect comment The comment of `solve_cubic()` put the coefficients of the to-be-solved cubic equation in the wrong order. This is now fixed. No functional change, just a comment fix. --- source/blender/blenkernel/intern/fcurve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 3c4a068b42a..d2550f9db0d 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1436,7 +1436,7 @@ void BKE_fcurve_correct_bezpart(const float v1[2], float v2[2], float v3[2], con } /** - * Find roots of cubic equation (c0 x^3 + c1 x^2 + c2 x + c3) + * Find roots of cubic equation (c0 + c1 x + c2 x^2 + c3 x^3) * \return number of roots in `o`. * * \note it is up to the caller to allocate enough memory for `o`. From ea7570989d2abef4208dc41ba118859244b1db03 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 13 Dec 2022 17:25:37 +0100 Subject: [PATCH 0057/1522] Cleanup: add utility method to get group input nodes --- source/blender/blenkernel/BKE_node_runtime.hh | 5 +++++ .../blender/blenkernel/intern/node_tree_field_inferencing.cc | 4 ++-- source/blender/makesdna/DNA_node_types.h | 2 ++ source/blender/modifiers/intern/MOD_nodes.cc | 2 +- source/blender/nodes/intern/derived_node_tree.cc | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 979c7630865..6a00e70cb5b 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -421,6 +421,11 @@ inline const bNode *bNodeTree::group_output_node() const return this->runtime->group_output_node; } +inline blender::Span bNodeTree::group_input_nodes() const +{ + return this->nodes_by_type("NodeGroupInput"); +} + inline blender::Span bNodeTree::all_input_sockets() const { BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this)); diff --git a/source/blender/blenkernel/intern/node_tree_field_inferencing.cc b/source/blender/blenkernel/intern/node_tree_field_inferencing.cc index 82e425dfbb9..88fd3636633 100644 --- a/source/blender/blenkernel/intern/node_tree_field_inferencing.cc +++ b/source/blender/blenkernel/intern/node_tree_field_inferencing.cc @@ -340,7 +340,7 @@ static void determine_group_input_states( } /* Check if group inputs are required to be single values, because they are (indirectly) * connected to some socket that does not support fields. */ - for (const bNode *node : tree.nodes_by_type("NodeGroupInput")) { + for (const bNode *node : tree.group_input_nodes()) { for (const bNodeSocket *output_socket : node->output_sockets().drop_back(1)) { SocketFieldState &state = field_state_by_socket_id[output_socket->index_in_tree()]; if (state.requires_single) { @@ -349,7 +349,7 @@ static void determine_group_input_states( } } /* If an input does not support fields, this should be reflected in all Group Input nodes. */ - for (const bNode *node : tree.nodes_by_type("NodeGroupInput")) { + for (const bNode *node : tree.group_input_nodes()) { for (const bNodeSocket *output_socket : node->output_sockets().drop_back(1)) { SocketFieldState &state = field_state_by_socket_id[output_socket->index_in_tree()]; const bool supports_field = new_inferencing_interface.inputs[output_socket->index()] != diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 424a4c17e82..6313791bd3c 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -634,6 +634,8 @@ typedef struct bNodeTree { bool has_undefined_nodes_or_sockets() const; /** Get the active group output node. */ const bNode *group_output_node() const; + /** Get all input nodes of the node group. */ + blender::Span group_input_nodes() const; #endif } bNodeTree; diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index a8e5e2ab0a2..f5ede42b0ad 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1401,7 +1401,7 @@ static void attribute_search_update_fn( } } else { - for (const bNode *node : nmd->node_group->nodes_by_type("NodeGroupInput")) { + for (const bNode *node : nmd->node_group->group_input_nodes()) { for (const bNodeSocket *socket : node->output_sockets()) { if (socket->type == SOCK_GEOMETRY) { sockets_to_check.append(socket); diff --git a/source/blender/nodes/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc index 50fbf791536..ece60ffe4ab 100644 --- a/source/blender/nodes/intern/derived_node_tree.cc +++ b/source/blender/nodes/intern/derived_node_tree.cc @@ -115,7 +115,7 @@ Vector DInputSocket::get_corresponding_group_input_sockets() cons BLI_assert(child_context != nullptr); const bNodeTree &child_tree = child_context->btree(); - Span group_input_nodes = child_tree.nodes_by_type("NodeGroupInput"); + Span group_input_nodes = child_tree.group_input_nodes(); const int socket_index = bsocket_->index(); Vector sockets; for (const bNode *group_input_node : group_input_nodes) { From 246df68095835110a3e11eb3c7a9d2acb048332c Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Tue, 13 Dec 2022 08:37:04 -0800 Subject: [PATCH 0058/1522] Sculpt: Fix crash with unsupported attr types in pbvh draw --- source/blender/draw/intern/draw_pbvh.cc | 30 ++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index cac3e3339fc..d56a86ab44c 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -66,6 +66,22 @@ using blender::Vector; using string = std::string; +static bool valid_pbvh_attr(int type) +{ + switch (type) { + case CD_PBVH_CO_TYPE: + case CD_PBVH_NO_TYPE: + case CD_PBVH_FSET_TYPE: + case CD_PBVH_MASK_TYPE: + case CD_PROP_COLOR: + case CD_PROP_BYTE_COLOR: + case CD_MLOOPUV: + return true; + } + + return false; +} + struct PBVHVbo { uint64_t type; eAttrDomain domain; @@ -228,6 +244,10 @@ struct PBVHBatches { for (int i : IndexRange(attrs_num)) { PBVHAttrReq *attr = attrs + i; + if (!valid_pbvh_attr(attr->type)) { + continue; + } + PBVHVbo vbo(attr->domain, attr->type, string(attr->name)); vbo.build_key(); @@ -858,10 +878,10 @@ struct PBVHBatches { break; } default: - BLI_assert(0); - printf("%s: error\n", __func__); + printf("%s: Unsupported attribute type %d\n", __func__, type); + BLI_assert_unreachable(); - break; + return; } if (need_aliases) { @@ -1227,6 +1247,10 @@ struct PBVHBatches { for (int i : IndexRange(attrs_num)) { PBVHAttrReq *attr = attrs + i; + if (!valid_pbvh_attr(attr->type)) { + continue; + } + if (!has_vbo(attr->domain, int(attr->type), attr->name)) { create_vbo(attr->domain, uint32_t(attr->type), attr->name, args); } From 0a5e8a63420de7efcf874370009831da8f19e215 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Tue, 13 Dec 2022 08:46:05 -0800 Subject: [PATCH 0059/1522] Sculpt: Fix crash in dyntopo Attribute wrangler in PBVH_BMESH mode was converting real attributes (e.g. vertex node index) into simple arrays when validating the attribute list. --- source/blender/blenkernel/intern/paint.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 200eb3e8732..3100b4cc20c 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -2466,7 +2466,8 @@ static bool sculpt_attribute_create(SculptSession *ss, out->data = MEM_calloc_arrayN(totelem, elemsize, __func__); - out->data_for_bmesh = ss->bm != nullptr; + out->data_for_bmesh = false; + out->params.simple_array = true; out->bmesh_cd_offset = -1; out->layer = nullptr; out->elem_size = elemsize; @@ -2598,7 +2599,7 @@ static bool sculpt_attr_update(Object *ob, SculptAttribute *attr) attr, &attr->params, BKE_pbvh_type(ss->pbvh), - true); + attr->data_for_bmesh); } return bad; From b50c475cd251cbb730ac4af26cb99bc71e529147 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 13 Dec 2022 18:12:52 +0100 Subject: [PATCH 0060/1522] Cleanup: move listbase.c to c++ --- intern/ghost/test/CMakeLists.txt | 2 +- source/blender/blenlib/CMakeLists.txt | 2 +- .../intern/{listbase.c => listbase.cc} | 246 +++++++++--------- source/blender/makesdna/intern/CMakeLists.txt | 2 +- 4 files changed, 127 insertions(+), 125 deletions(-) rename source/blender/blenlib/intern/{listbase.c => listbase.cc} (72%) diff --git a/intern/ghost/test/CMakeLists.txt b/intern/ghost/test/CMakeLists.txt index 3f74f97f115..11dd6f75ef9 100644 --- a/intern/ghost/test/CMakeLists.txt +++ b/intern/ghost/test/CMakeLists.txt @@ -167,7 +167,7 @@ add_library(bli_lib "../../../source/blender/blenlib/intern/rct.c" "../../../source/blender/blenlib/intern/string.c" "../../../source/blender/blenlib/intern/string_utf8.c" - "../../../source/blender/blenlib/intern/listbase.c" + "../../../source/blender/blenlib/intern/listbase.cc" "../../../source/blender/blenlib/intern/math_color.c" "../../../source/blender/blenlib/intern/math_geom.c" "../../../source/blender/blenlib/intern/math_matrix.c" diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 1229344cb05..17218a2daed 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -89,7 +89,7 @@ set(SRC intern/lasso_2d.c intern/lazy_threading.cc intern/length_parameterize.cc - intern/listbase.c + intern/listbase.cc intern/math_base.c intern/math_base_inline.c intern/math_base_safe_inline.c diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.cc similarity index 72% rename from source/blender/blenlib/intern/listbase.c rename to source/blender/blenlib/intern/listbase.cc index 3932e5eb051..ee0c6fcd5c3 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.cc @@ -22,56 +22,56 @@ void BLI_movelisttolist(ListBase *dst, ListBase *src) { - if (src->first == NULL) { + if (src->first == nullptr) { return; } - if (dst->first == NULL) { + if (dst->first == nullptr) { dst->first = src->first; dst->last = src->last; } else { - ((Link *)dst->last)->next = src->first; - ((Link *)src->first)->prev = dst->last; + ((Link *)dst->last)->next = static_cast(src->first); + ((Link *)src->first)->prev = static_cast(dst->last); dst->last = src->last; } - src->first = src->last = NULL; + src->first = src->last = nullptr; } void BLI_movelisttolist_reverse(ListBase *dst, ListBase *src) { - if (src->first == NULL) { + if (src->first == nullptr) { return; } - if (dst->first == NULL) { + if (dst->first == nullptr) { dst->first = src->first; dst->last = src->last; } else { - ((Link *)src->last)->next = dst->first; - ((Link *)dst->first)->prev = src->last; + ((Link *)src->last)->next = static_cast(dst->first); + ((Link *)dst->first)->prev = static_cast(src->last); dst->first = src->first; } - src->first = src->last = NULL; + src->first = src->last = nullptr; } void BLI_addhead(ListBase *listbase, void *vlink) { - Link *link = vlink; + Link *link = static_cast(vlink); - if (link == NULL) { + if (link == nullptr) { return; } - link->next = listbase->first; - link->prev = NULL; + link->next = static_cast(listbase->first); + link->prev = nullptr; if (listbase->first) { ((Link *)listbase->first)->prev = link; } - if (listbase->last == NULL) { + if (listbase->last == nullptr) { listbase->last = link; } listbase->first = link; @@ -79,19 +79,19 @@ void BLI_addhead(ListBase *listbase, void *vlink) void BLI_addtail(ListBase *listbase, void *vlink) { - Link *link = vlink; + Link *link = static_cast(vlink); - if (link == NULL) { + if (link == nullptr) { return; } - link->next = NULL; - link->prev = listbase->last; + link->next = nullptr; + link->prev = static_cast(listbase->last); if (listbase->last) { ((Link *)listbase->last)->next = link; } - if (listbase->first == NULL) { + if (listbase->first == nullptr) { listbase->first = link; } listbase->last = link; @@ -99,9 +99,9 @@ void BLI_addtail(ListBase *listbase, void *vlink) void BLI_remlink(ListBase *listbase, void *vlink) { - Link *link = vlink; + Link *link = static_cast(vlink); - if (link == NULL) { + if (link == nullptr) { return; } @@ -132,8 +132,8 @@ bool BLI_remlink_safe(ListBase *listbase, void *vlink) void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) { - Link *linka = vlinka; - Link *linkb = vlinkb; + Link *linka = static_cast(vlinka); + Link *linkb = static_cast(vlinkb); if (!linka || !linkb) { return; @@ -185,15 +185,15 @@ void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vlinka, void *vlinkb) { - Link *linka = vlinka; - Link *linkb = vlinkb; - Link linkc = {NULL}; + Link *linka = static_cast(vlinka); + Link *linkb = static_cast(vlinkb); + Link linkc = {nullptr}; if (!linka || !linkb) { return; } - /* The reference to `linkc` assigns NULL, not a dangling pointer so it can be ignored. */ + /* The reference to `linkc` assigns nullptr, not a dangling pointer so it can be ignored. */ #if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 1201 /* gcc12.1+ only */ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wdangling-pointer" @@ -221,7 +221,7 @@ void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vli void *BLI_pophead(ListBase *listbase) { Link *link; - if ((link = listbase->first)) { + if ((link = static_cast(listbase->first))) { BLI_remlink(listbase, link); } return link; @@ -230,7 +230,7 @@ void *BLI_pophead(ListBase *listbase) void *BLI_poptail(ListBase *listbase) { Link *link; - if ((link = listbase->last)) { + if ((link = static_cast(listbase->last))) { BLI_remlink(listbase, link); } return link; @@ -238,9 +238,9 @@ void *BLI_poptail(ListBase *listbase) void BLI_freelinkN(ListBase *listbase, void *vlink) { - Link *link = vlink; + Link *link = static_cast(vlink); - if (link == NULL) { + if (link == nullptr) { return; } @@ -253,7 +253,7 @@ void BLI_freelinkN(ListBase *listbase, void *vlink) */ static void listbase_double_from_single(Link *iter, ListBase *listbase) { - Link *prev = NULL; + Link *prev = nullptr; listbase->first = iter; do { iter->prev = prev; @@ -281,7 +281,7 @@ static void listbase_double_from_single(Link *iter, ListBase *listbase) void BLI_listbase_sort(ListBase *listbase, int (*cmp)(const void *, const void *)) { if (listbase->first != listbase->last) { - Link *head = listbase->first; + Link *head = static_cast(listbase->first); head = listbase_sort_fn(head, cmp); listbase_double_from_single(head, listbase); } @@ -292,7 +292,7 @@ void BLI_listbase_sort_r(ListBase *listbase, void *thunk) { if (listbase->first != listbase->last) { - Link *head = listbase->first; + Link *head = static_cast(listbase->first); head = listbase_sort_fn_r(head, cmp, thunk); listbase_double_from_single(head, listbase); } @@ -300,25 +300,25 @@ void BLI_listbase_sort_r(ListBase *listbase, void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink) { - Link *prevlink = vprevlink; - Link *newlink = vnewlink; + Link *prevlink = static_cast(vprevlink); + Link *newlink = static_cast(vnewlink); /* newlink before nextlink */ - if (newlink == NULL) { + if (newlink == nullptr) { return; } /* empty list */ - if (listbase->first == NULL) { + if (listbase->first == nullptr) { listbase->first = newlink; listbase->last = newlink; return; } /* insert at head of list */ - if (prevlink == NULL) { - newlink->prev = NULL; - newlink->next = listbase->first; + if (prevlink == nullptr) { + newlink->prev = nullptr; + newlink->next = static_cast(listbase->first); newlink->next->prev = newlink; listbase->first = newlink; return; @@ -339,25 +339,25 @@ void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink) void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) { - Link *nextlink = vnextlink; - Link *newlink = vnewlink; + Link *nextlink = static_cast(vnextlink); + Link *newlink = static_cast(vnewlink); /* newlink before nextlink */ - if (newlink == NULL) { + if (newlink == nullptr) { return; } /* empty list */ - if (listbase->first == NULL) { + if (listbase->first == nullptr) { listbase->first = newlink; listbase->last = newlink; return; } /* insert at end of list */ - if (nextlink == NULL) { - newlink->prev = listbase->last; - newlink->next = NULL; + if (nextlink == nullptr) { + newlink->prev = static_cast(listbase->last); + newlink->next = nullptr; ((Link *)listbase->last)->next = newlink; listbase->last = newlink; return; @@ -378,14 +378,14 @@ void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink) { - Link *l_old = vreplacelink; - Link *l_new = vnewlink; + Link *l_old = static_cast(vreplacelink); + Link *l_new = static_cast(vnewlink); /* update adjacent links */ - if (l_old->next != NULL) { + if (l_old->next != nullptr) { l_old->next->prev = l_new; } - if (l_old->prev != NULL) { + if (l_old->prev != nullptr) { l_old->prev->next = l_new; } @@ -404,7 +404,7 @@ void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlin bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step) { - Link *link = vlink; + Link *link = static_cast(vlink); Link *hook = link; const bool is_up = step < 0; @@ -453,7 +453,7 @@ void BLI_freelist(ListBase *listbase) { Link *link, *next; - link = listbase->first; + link = static_cast(listbase->first); while (link) { next = link->next; free(link); @@ -467,7 +467,7 @@ void BLI_freelistN(ListBase *listbase) { Link *link, *next; - link = listbase->first; + link = static_cast(listbase->first); while (link) { next = link->next; MEM_freeN(link); @@ -482,7 +482,8 @@ int BLI_listbase_count_at_most(const ListBase *listbase, const int count_max) Link *link; int count = 0; - for (link = listbase->first; link && count != count_max; link = link->next) { + for (link = static_cast(listbase->first); link && count != count_max; + link = link->next) { count++; } @@ -494,7 +495,7 @@ int BLI_listbase_count(const ListBase *listbase) Link *link; int count = 0; - for (link = listbase->first; link; link = link->next) { + for (link = static_cast(listbase->first); link; link = link->next) { count++; } @@ -503,11 +504,11 @@ int BLI_listbase_count(const ListBase *listbase) void *BLI_findlink(const ListBase *listbase, int number) { - Link *link = NULL; + Link *link = nullptr; if (number >= 0) { - link = listbase->first; - while (link != NULL && number != 0) { + link = static_cast(listbase->first); + while (link != nullptr && number != 0) { number--; link = link->next; } @@ -518,11 +519,11 @@ void *BLI_findlink(const ListBase *listbase, int number) void *BLI_rfindlink(const ListBase *listbase, int number) { - Link *link = NULL; + Link *link = nullptr; if (number >= 0) { - link = listbase->last; - while (link != NULL && number != 0) { + link = static_cast(listbase->last); + while (link != nullptr && number != 0) { number--; link = link->prev; } @@ -533,11 +534,11 @@ void *BLI_rfindlink(const ListBase *listbase, int number) void *BLI_findlinkfrom(Link *start, int number) { - Link *link = NULL; + Link *link = nullptr; if (number >= 0) { link = start; - while (link != NULL && number != 0) { + while (link != nullptr && number != 0) { number--; link = link->next; } @@ -548,14 +549,14 @@ void *BLI_findlinkfrom(Link *start, int number) int BLI_findindex(const ListBase *listbase, const void *vlink) { - Link *link = NULL; + Link *link = nullptr; int number = 0; - if (vlink == NULL) { + if (vlink == nullptr) { return -1; } - link = listbase->first; + link = static_cast(listbase->first); while (link) { if (link == vlink) { return number; @@ -570,14 +571,14 @@ int BLI_findindex(const ListBase *listbase, const void *vlink) void *BLI_findstring(const ListBase *listbase, const char *id, const int offset) { - Link *link = NULL; + Link *link = nullptr; const char *id_iter; - if (id == NULL) { - return NULL; + if (id == nullptr) { + return nullptr; } - for (link = listbase->first; link; link = link->next) { + for (link = static_cast(listbase->first); link; link = link->next) { id_iter = ((const char *)link) + offset; if (id[0] == id_iter[0] && STREQ(id, id_iter)) { @@ -585,16 +586,16 @@ void *BLI_findstring(const ListBase *listbase, const char *id, const int offset) } } - return NULL; + return nullptr; } void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset) { /* Same as #BLI_findstring but find reverse. */ - Link *link = NULL; + Link *link = nullptr; const char *id_iter; - for (link = listbase->last; link; link = link->prev) { + for (link = static_cast(listbase->last); link; link = link->prev) { id_iter = ((const char *)link) + offset; if (id[0] == id_iter[0] && STREQ(id, id_iter)) { @@ -602,15 +603,15 @@ void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset } } - return NULL; + return nullptr; } void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int offset) { - Link *link = NULL; + Link *link = nullptr; const char *id_iter; - for (link = listbase->first; link; link = link->next) { + for (link = static_cast(listbase->first); link; link = link->next) { /* exact copy of BLI_findstring(), except for this line */ id_iter = *((const char **)(((const char *)link) + offset)); @@ -619,16 +620,16 @@ void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int off } } - return NULL; + return nullptr; } void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int offset) { /* Same as #BLI_findstring_ptr but find reverse. */ - Link *link = NULL; + Link *link = nullptr; const char *id_iter; - for (link = listbase->last; link; link = link->prev) { + for (link = static_cast(listbase->last); link; link = link->prev) { /* exact copy of BLI_rfindstring(), except for this line */ id_iter = *((const char **)(((const char *)link) + offset)); @@ -637,15 +638,15 @@ void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int of } } - return NULL; + return nullptr; } void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset) { - Link *link = NULL; + Link *link = nullptr; const void *ptr_iter; - for (link = listbase->first; link; link = link->next) { + for (link = static_cast(listbase->first); link; link = link->next) { /* exact copy of BLI_findstring(), except for this line */ ptr_iter = *((const void **)(((const char *)link) + offset)); @@ -654,16 +655,16 @@ void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset) } } - return NULL; + return nullptr; } void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset) { /* Same as #BLI_findptr but find reverse. */ - Link *link = NULL; + Link *link = nullptr; const void *ptr_iter; - for (link = listbase->last; link; link = link->prev) { + for (link = static_cast(listbase->last); link; link = link->prev) { /* exact copy of BLI_rfindstring(), except for this line */ ptr_iter = *((const void **)(((const char *)link) + offset)); @@ -672,7 +673,7 @@ void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset) } } - return NULL; + return nullptr; } void *BLI_listbase_bytes_find(const ListBase *listbase, @@ -680,10 +681,10 @@ void *BLI_listbase_bytes_find(const ListBase *listbase, const size_t bytes_size, const int offset) { - Link *link = NULL; + Link *link = nullptr; const void *ptr_iter; - for (link = listbase->first; link; link = link->next) { + for (link = static_cast(listbase->first); link; link = link->next) { ptr_iter = (const void *)(((const char *)link) + offset); if (memcmp(bytes, ptr_iter, bytes_size) == 0) { @@ -691,7 +692,7 @@ void *BLI_listbase_bytes_find(const ListBase *listbase, } } - return NULL; + return nullptr; } void *BLI_listbase_bytes_rfind(const ListBase *listbase, const void *bytes, @@ -700,10 +701,10 @@ void *BLI_listbase_bytes_rfind(const ListBase *listbase, { /* Same as #BLI_listbase_bytes_find but find reverse. */ - Link *link = NULL; + Link *link = nullptr; const void *ptr_iter; - for (link = listbase->last; link; link = link->prev) { + for (link = static_cast(listbase->last); link; link = link->prev) { ptr_iter = (const void *)(((const char *)link) + offset); if (memcmp(bytes, ptr_iter, bytes_size) == 0) { @@ -711,7 +712,7 @@ void *BLI_listbase_bytes_rfind(const ListBase *listbase, } } - return NULL; + return nullptr; } void *BLI_listbase_string_or_index_find(const ListBase *listbase, @@ -719,12 +720,13 @@ void *BLI_listbase_string_or_index_find(const ListBase *listbase, const size_t string_offset, const int index) { - Link *link = NULL; - Link *link_at_index = NULL; + Link *link = nullptr; + Link *link_at_index = nullptr; int index_iter; - for (link = listbase->first, index_iter = 0; link; link = link->next, index_iter++) { - if (string != NULL && string[0] != '\0') { + for (link = static_cast(listbase->first), index_iter = 0; link; + link = link->next, index_iter++) { + if (string != nullptr && string[0] != '\0') { const char *string_iter = ((const char *)link) + string_offset; if (string[0] == string_iter[0] && STREQ(string, string_iter)) { @@ -740,11 +742,11 @@ void *BLI_listbase_string_or_index_find(const ListBase *listbase, int BLI_findstringindex(const ListBase *listbase, const char *id, const int offset) { - Link *link = NULL; + Link *link = nullptr; const char *id_iter; int i = 0; - link = listbase->first; + link = static_cast(listbase->first); while (link) { id_iter = ((const char *)link) + offset; @@ -761,17 +763,17 @@ int BLI_findstringindex(const ListBase *listbase, const char *id, const int offs ListBase BLI_listbase_from_link(Link *some_link) { ListBase list = {some_link, some_link}; - if (some_link == NULL) { + if (some_link == nullptr) { return list; } /* Find the first element. */ - while (((Link *)list.first)->prev != NULL) { + while (((Link *)list.first)->prev != nullptr) { list.first = ((Link *)list.first)->prev; } /* Find the last element. */ - while (((Link *)list.last)->next != NULL) { + while (((Link *)list.last)->next != nullptr) { list.last = ((Link *)list.last)->next; } @@ -783,11 +785,11 @@ void BLI_duplicatelist(ListBase *dst, const ListBase *src) struct Link *dst_link, *src_link; /* in this order, to ensure it works if dst == src */ - src_link = src->first; - dst->first = dst->last = NULL; + src_link = static_cast(src->first); + dst->first = dst->last = nullptr; while (src_link) { - dst_link = MEM_dupallocN(src_link); + dst_link = static_cast(MEM_dupallocN(src_link)); BLI_addtail(dst, dst_link); src_link = src_link->next; @@ -796,9 +798,9 @@ void BLI_duplicatelist(ListBase *dst, const ListBase *src) void BLI_listbase_reverse(ListBase *lb) { - struct Link *curr = lb->first; - struct Link *prev = NULL; - struct Link *next = NULL; + struct Link *curr = static_cast(lb->first); + struct Link *prev = nullptr; + struct Link *next = nullptr; while (curr) { next = curr->next; curr->next = prev; @@ -808,7 +810,7 @@ void BLI_listbase_reverse(ListBase *lb) } /* swap first/last */ - curr = lb->first; + curr = static_cast(lb->first); lb->first = lb->last; lb->last = curr; } @@ -816,39 +818,39 @@ void BLI_listbase_reverse(ListBase *lb) void BLI_listbase_rotate_first(ListBase *lb, void *vlink) { /* make circular */ - ((Link *)lb->first)->prev = lb->last; - ((Link *)lb->last)->next = lb->first; + ((Link *)lb->first)->prev = static_cast(lb->last); + ((Link *)lb->last)->next = static_cast(lb->first); lb->first = vlink; lb->last = ((Link *)vlink)->prev; - ((Link *)lb->first)->prev = NULL; - ((Link *)lb->last)->next = NULL; + ((Link *)lb->first)->prev = nullptr; + ((Link *)lb->last)->next = nullptr; } void BLI_listbase_rotate_last(ListBase *lb, void *vlink) { /* make circular */ - ((Link *)lb->first)->prev = lb->last; - ((Link *)lb->last)->next = lb->first; + ((Link *)lb->first)->prev = static_cast(lb->last); + ((Link *)lb->last)->next = static_cast(lb->first); lb->first = ((Link *)vlink)->next; lb->last = vlink; - ((Link *)lb->first)->prev = NULL; - ((Link *)lb->last)->next = NULL; + ((Link *)lb->first)->prev = nullptr; + ((Link *)lb->last)->next = nullptr; } LinkData *BLI_genericNodeN(void *data) { LinkData *ld; - if (data == NULL) { - return NULL; + if (data == nullptr) { + return nullptr; } /* create new link, and make it hold the given data */ - ld = MEM_callocN(sizeof(LinkData), __func__); + ld = MEM_cnew(__func__); ld->data = data; return ld; diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt index 50fd51e88a1..2bf83d7abf0 100644 --- a/source/blender/makesdna/intern/CMakeLists.txt +++ b/source/blender/makesdna/intern/CMakeLists.txt @@ -135,7 +135,7 @@ set(SRC ../../blenlib/intern/BLI_mempool.c ../../blenlib/intern/endian_switch.c ../../blenlib/intern/hash_mm2a.c - ../../blenlib/intern/listbase.c + ../../blenlib/intern/listbase.cc ${SRC_DNA_DEFAULTS_INC} ) From 31ba4dd82e2fff2a79c398b1ec1bfa523d107def Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 13 Dec 2022 18:53:12 +0100 Subject: [PATCH 0061/1522] Build: bump OSL version to hash in 1.13 which is under development This includes string table changes to make the Cycles OptiX support work. --- build_files/build_environment/cmake/versions.cmake | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 097f632b356..870f2da9abe 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -195,9 +195,12 @@ set(TIFF_HASH_TYPE MD5) set(TIFF_FILE tiff-${TIFF_VERSION}.tar.gz) set(TIFF_CPE "cpe:2.3:a:libtiff:libtiff:${TIFF_VERSION}:*:*:*:*:*:*:*") -set(OSL_VERSION 1.12.7.1) -set(OSL_URI https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/archive/v${OSL_VERSION}.tar.gz) -set(OSL_HASH 53211da86c34ba6e0344998c1a6d219c) +# Recent commit from 1.13.0.2 under development, which includes string table +# changes that make the Cycles OptiX implementation work. Official 1.12 OSL +# releases should also build but without OptiX support. +set(OSL_VERSION 1a7670600c8b08c2443a78d03c8c27e9a1149140) +set(OSL_URI https://github.com/AcademySoftwareFoundation/OpenShadingLanguage/archive/${OSL_VERSION}.tar.gz) +set(OSL_HASH 7b6d6716b05d1addb92a8f47280bf77f) set(OSL_HASH_TYPE MD5) set(OSL_FILE OpenShadingLanguage-${OSL_VERSION}.tar.gz) From 2c5a525d6409dec84c6ace8fb5d67d8f10f5889d Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Tue, 13 Dec 2022 13:26:03 -0300 Subject: [PATCH 0062/1522] Cleanup: indentation, remove and rename variables The `transform_convert_clip_mirror_modifier_apply` code is made more readable by: - decreasing indentation; - removing `axis` and `tolerance` variables; - renaming `int clip` to `bool is_clipping`; --- .../editors/transform/transform_convert.c | 124 ++++++++---------- 1 file changed, 56 insertions(+), 68 deletions(-) diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index f9ad09b7a10..b5373b4fd6c 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -1070,87 +1070,75 @@ void transform_convert_clip_mirror_modifier_apply(TransDataContainer *tc) { Object *ob = tc->obedit; ModifierData *md = ob->modifiers.first; - float tolerance[3] = {0.0f, 0.0f, 0.0f}; - int axis = 0; for (; md; md = md->next) { if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) { MirrorModifierData *mmd = (MirrorModifierData *)md; - if (mmd->flag & MOD_MIR_CLIPPING) { - axis = 0; - if (mmd->flag & MOD_MIR_AXIS_X) { - axis |= 1; - tolerance[0] = mmd->tolerance; + if ((mmd->flag & MOD_MIR_CLIPPING) == 0) { + continue; + } + + if ((mmd->flag & (MOD_MIR_AXIS_X | MOD_MIR_AXIS_Y | MOD_MIR_AXIS_Y)) == 0) { + continue; + } + + float mtx[4][4], imtx[4][4]; + + if (mmd->mirror_ob) { + float obinv[4][4]; + + invert_m4_m4(obinv, mmd->mirror_ob->object_to_world); + mul_m4_m4m4(mtx, obinv, ob->object_to_world); + invert_m4_m4(imtx, mtx); + } + + TransData *td = tc->data; + for (int i = 0; i < tc->data_len; i++, td++) { + float loc[3], iloc[3]; + + if (td->loc == NULL) { + break; } + + if (td->flag & TD_SKIP) { + continue; + } + + copy_v3_v3(loc, td->loc); + copy_v3_v3(iloc, td->iloc); + + if (mmd->mirror_ob) { + mul_m4_v3(mtx, loc); + mul_m4_v3(mtx, iloc); + } + + bool is_clipping = false; + if (mmd->flag & MOD_MIR_AXIS_X) { + if (fabsf(iloc[0]) <= mmd->tolerance || loc[0] * iloc[0] < 0.0f) { + loc[0] = 0.0f; + is_clipping = true; + } + } + if (mmd->flag & MOD_MIR_AXIS_Y) { - axis |= 2; - tolerance[1] = mmd->tolerance; + if (fabsf(iloc[1]) <= mmd->tolerance || loc[1] * iloc[1] < 0.0f) { + loc[1] = 0.0f; + is_clipping = true; + } } if (mmd->flag & MOD_MIR_AXIS_Z) { - axis |= 4; - tolerance[2] = mmd->tolerance; + if (fabsf(iloc[2]) <= mmd->tolerance || loc[2] * iloc[2] < 0.0f) { + loc[2] = 0.0f; + is_clipping = true; + } } - if (axis) { - float mtx[4][4], imtx[4][4]; - int i; + if (is_clipping) { if (mmd->mirror_ob) { - float obinv[4][4]; - - invert_m4_m4(obinv, mmd->mirror_ob->object_to_world); - mul_m4_m4m4(mtx, obinv, ob->object_to_world); - invert_m4_m4(imtx, mtx); - } - - TransData *td = tc->data; - for (i = 0; i < tc->data_len; i++, td++) { - int clip; - float loc[3], iloc[3]; - - if (td->loc == NULL) { - break; - } - - if (td->flag & TD_SKIP) { - continue; - } - - copy_v3_v3(loc, td->loc); - copy_v3_v3(iloc, td->iloc); - - if (mmd->mirror_ob) { - mul_m4_v3(mtx, loc); - mul_m4_v3(mtx, iloc); - } - - clip = 0; - if (axis & 1) { - if (fabsf(iloc[0]) <= tolerance[0] || loc[0] * iloc[0] < 0.0f) { - loc[0] = 0.0f; - clip = 1; - } - } - - if (axis & 2) { - if (fabsf(iloc[1]) <= tolerance[1] || loc[1] * iloc[1] < 0.0f) { - loc[1] = 0.0f; - clip = 1; - } - } - if (axis & 4) { - if (fabsf(iloc[2]) <= tolerance[2] || loc[2] * iloc[2] < 0.0f) { - loc[2] = 0.0f; - clip = 1; - } - } - if (clip) { - if (mmd->mirror_ob) { - mul_m4_v3(imtx, loc); - } - copy_v3_v3(td->loc, loc); - } + mul_m4_v3(imtx, loc); } + copy_v3_v3(td->loc, loc); } } } From bdd34f4fa25c7382bac452db82af639bab453046 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 13 Dec 2022 13:36:48 -0600 Subject: [PATCH 0063/1522] Fix T103051: Changed behavior when removing a material slot Before f1c0249f34c4171ec311 the material was assigned to the previous slot rather than the next. Though the behavior is arbitrary, there is no reason to change it. --- source/blender/blenkernel/intern/mesh.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 1fafec810ba..1fd2a72f311 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1363,7 +1363,7 @@ void BKE_mesh_material_index_remove(Mesh *me, short index) } MutableVArraySpan indices_span(material_indices.varray); for (const int i : indices_span.index_range()) { - if (indices_span[i] > 0 && indices_span[i] > index) { + if (indices_span[i] > 0 && indices_span[i] >= index) { indices_span[i]--; } } From 29f342774ce134c723a7acf80adfa408e482a042 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 13 Dec 2022 14:11:06 -0600 Subject: [PATCH 0064/1522] Fix T103052: Box trim does not create face sets attribute Previously the sculpt box trim operator always created face sets, but after face sets became optional it only modified them if they already existed. Absent a better way to turn the behavior on and off, the fix is to just always create face sets. --- source/blender/editors/sculpt_paint/paint_mask.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index eb24d15dad5..ad9ae6b4349 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -1345,6 +1345,11 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext) static void sculpt_gesture_trim_begin(bContext *C, SculptGestureContext *sgcontext) { + Object *object = sgcontext->vc.obact; + SculptSession *ss = object->sculpt; + Mesh *mesh = (Mesh *)object->data; + ss->face_sets = BKE_sculpt_face_sets_ensure(mesh); + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); sculpt_gesture_trim_calculate_depth(sgcontext); sculpt_gesture_trim_geometry_generate(sgcontext); @@ -1369,9 +1374,9 @@ static void sculpt_gesture_trim_end(bContext *UNUSED(C), SculptGestureContext *s { Object *object = sgcontext->vc.obact; SculptSession *ss = object->sculpt; + Mesh *mesh = (Mesh *)object->data; - ss->face_sets = CustomData_get_layer_named( - &((Mesh *)object->data)->pdata, CD_PROP_INT32, ".sculpt_face_set"); + ss->face_sets = CustomData_get_layer_named(&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set"); if (ss->face_sets) { /* Assign a new Face Set ID to the new faces created by the trim operation. */ const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(object->data); From 8ee020d11fe8debfd64274658d71d0d60b27e676 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 13 Dec 2022 14:26:46 -0600 Subject: [PATCH 0065/1522] Fix T103195: Initialize face sets from bevel weights broken The conversion from char to float (divide by 255) wasn't removed in 291c313f80b4cccc8fcc. Also fix a crash when the edge crease layer didn't exist. --- source/blender/editors/sculpt_paint/sculpt_face_set.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index d0c8a19434b..7253a41f97f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -692,7 +692,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op) CustomData_get_layer(&mesh->edata, CD_CREASE)); sculpt_face_sets_init_flood_fill( ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool { - return creases[edge] < threshold; + return creases ? creases[edge] < threshold : true; }); break; } @@ -709,7 +709,7 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op) CustomData_get_layer(&mesh->edata, CD_BWEIGHT)); sculpt_face_sets_init_flood_fill( ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool { - return bevel_weights ? bevel_weights[edge] / 255.0f < threshold : true; + return bevel_weights ? bevel_weights[edge] < threshold : true; }); break; } From 6f9cfb037a8e5dbd8707877d0a9539ae8d358656 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Tue, 13 Dec 2022 12:24:24 -0800 Subject: [PATCH 0066/1522] Sculpt: Fix T102991: Multires fast navigate not implemented PBVH draw code now builds coarse triangle index buffers for multires. Note that the coarse grids can be at any multires depth but is currently hardcoded to 1. --- source/blender/blenkernel/BKE_pbvh.h | 3 +- source/blender/blenkernel/intern/pbvh.c | 19 ++- source/blender/draw/DRW_pbvh.h | 6 +- .../blender/draw/intern/draw_manager_data.cc | 6 +- source/blender/draw/intern/draw_pbvh.cc | 159 +++++++++++++----- .../gpu/intern/gpu_shader_builder_stubs.cc | 3 +- 6 files changed, 141 insertions(+), 55 deletions(-) diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 139b6ff6bbe..8f66d552387 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -414,7 +414,8 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, struct Mesh *me); int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden, const int *grid_indices, int totgrid, - int gridsize); + int gridsize, + int display_gridsize); /** * Multi-res level, only valid for type == #PBVH_GRIDS. diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 98e21c685a2..35c2c660fd2 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -383,7 +383,8 @@ static void update_vb(PBVH *pbvh, PBVHNode *node, BBC *prim_bbc, int offset, int int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden, const int *grid_indices, int totgrid, - int gridsize) + int gridsize, + int display_gridsize) { const int gridarea = (gridsize - 1) * (gridsize - 1); int totquad = 0; @@ -391,13 +392,18 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden, /* grid hidden layer is present, so have to check each grid for * visibility */ + int depth1 = (int)(log2((double)gridsize - 1.0) + DBL_EPSILON); + int depth2 = (int)(log2((double)display_gridsize - 1.0) + DBL_EPSILON); + + int skip = depth2 < depth1 ? 1 << (depth1 - depth2 - 1) : 1; + for (int i = 0; i < totgrid; i++) { const BLI_bitmap *gh = grid_hidden[grid_indices[i]]; if (gh) { /* grid hidden are present, have to check each element */ - for (int y = 0; y < gridsize - 1; y++) { - for (int x = 0; x < gridsize - 1; x++) { + for (int y = 0; y < gridsize - skip; y += skip) { + for (int x = 0; x < gridsize - skip; x += skip) { if (!paint_is_grid_face_hidden(gh, gridsize, x, y)) { totquad++; } @@ -414,8 +420,11 @@ int BKE_pbvh_count_grid_quads(BLI_bitmap **grid_hidden, static void build_grid_leaf_node(PBVH *pbvh, PBVHNode *node) { - int totquads = BKE_pbvh_count_grid_quads( - pbvh->grid_hidden, node->prim_indices, node->totprim, pbvh->gridkey.grid_size); + int totquads = BKE_pbvh_count_grid_quads(pbvh->grid_hidden, + node->prim_indices, + node->totprim, + pbvh->gridkey.grid_size, + pbvh->gridkey.grid_size); BKE_pbvh_node_fully_hidden_set(node, (totquads == 0)); BKE_pbvh_node_mark_rebuild_draw(node); } diff --git a/source/blender/draw/DRW_pbvh.h b/source/blender/draw/DRW_pbvh.h index ffd4b92d87b..6f9daac0a35 100644 --- a/source/blender/draw/DRW_pbvh.h +++ b/source/blender/draw/DRW_pbvh.h @@ -86,12 +86,14 @@ struct GPUBatch *DRW_pbvh_tris_get(PBVHBatches *batches, struct PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args, - int *r_prim_count); + int *r_prim_count, + bool do_coarse_grids); struct GPUBatch *DRW_pbvh_lines_get(struct PBVHBatches *batches, struct PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args, - int *r_prim_count); + int *r_prim_count, + bool do_coarse_grids); #ifdef __cplusplus } diff --git a/source/blender/draw/intern/draw_manager_data.cc b/source/blender/draw/intern/draw_manager_data.cc index beeff6f35c2..d4ffd3f8691 100644 --- a/source/blender/draw/intern/draw_manager_data.cc +++ b/source/blender/draw/intern/draw_manager_data.cc @@ -1220,10 +1220,12 @@ static void sculpt_draw_cb(DRWSculptCallbackData *scd, GPUBatch *geom; if (!scd->use_wire) { - geom = DRW_pbvh_tris_get(batches, scd->attrs, scd->attrs_num, pbvh_draw_args, &primcount); + geom = DRW_pbvh_tris_get( + batches, scd->attrs, scd->attrs_num, pbvh_draw_args, &primcount, scd->fast_mode); } else { - geom = DRW_pbvh_lines_get(batches, scd->attrs, scd->attrs_num, pbvh_draw_args, &primcount); + geom = DRW_pbvh_lines_get( + batches, scd->attrs, scd->attrs_num, pbvh_draw_args, &primcount, scd->fast_mode); } short index = 0; diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index d56a86ab44c..0bdfbf11cb8 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -115,6 +115,8 @@ struct PBVHBatch { string key; GPUBatch *tris = nullptr, *lines = nullptr; int tris_count = 0, lines_count = 0; + bool is_coarse = + false; /* Coarse multires, will use full-sized VBOs only index buffer changes. */ void sort_vbos(Vector &master_vbos) { @@ -138,6 +140,10 @@ struct PBVHBatch { { key = ""; + if (is_coarse) { + key += "c:"; + } + sort_vbos(master_vbos); for (int vbo_i : vbos) { @@ -173,6 +179,12 @@ struct PBVHBatches { int material_index = 0; + /* Stuff for displaying coarse multires grids. */ + GPUIndexBuf *tri_index_coarse = nullptr; + GPUIndexBuf *lines_index_coarse = nullptr; + int coarse_level = 0; /* Coarse multires depth. */ + int tris_count_coarse = 0, lines_count_coarse = 0; + int count_faces(PBVH_GPU_Args *args) { int count = 0; @@ -194,6 +206,7 @@ struct PBVHBatches { count = BKE_pbvh_count_grid_quads((BLI_bitmap **)args->grid_hidden, args->grid_indices, args->totprim, + args->ccg_key.grid_size, args->ccg_key.grid_size); break; @@ -233,9 +246,11 @@ struct PBVHBatches { GPU_INDEXBUF_DISCARD_SAFE(tri_index); GPU_INDEXBUF_DISCARD_SAFE(lines_index); + GPU_INDEXBUF_DISCARD_SAFE(tri_index_coarse); + GPU_INDEXBUF_DISCARD_SAFE(lines_index_coarse); } - string build_key(PBVHAttrReq *attrs, int attrs_num) + string build_key(PBVHAttrReq *attrs, int attrs_num, bool do_coarse_grids) { string key; PBVHBatch batch; @@ -255,6 +270,7 @@ struct PBVHBatches { batch.vbos.append(i); } + batch.is_coarse = do_coarse_grids; batch.build_key(vbos); return batch.key; } @@ -292,18 +308,21 @@ struct PBVHBatches { return nullptr; } - bool has_batch(PBVHAttrReq *attrs, int attrs_num) + bool has_batch(PBVHAttrReq *attrs, int attrs_num, bool do_coarse_grids) { - return batches.contains(build_key(attrs, attrs_num)); + return batches.contains(build_key(attrs, attrs_num, do_coarse_grids)); } - PBVHBatch &ensure_batch(PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args) + PBVHBatch &ensure_batch(PBVHAttrReq *attrs, + int attrs_num, + PBVH_GPU_Args *args, + bool do_coarse_grids) { - if (!has_batch(attrs, attrs_num)) { - create_batch(attrs, attrs_num, args); + if (!has_batch(attrs, attrs_num, do_coarse_grids)) { + create_batch(attrs, attrs_num, args, do_coarse_grids); } - return batches.lookup(build_key(attrs, attrs_num)); + return batches.lookup(build_key(attrs, attrs_num, do_coarse_grids)); } void fill_vbo_normal_faces( @@ -504,9 +523,12 @@ struct PBVHBatches { for (int x = 0; x < gridsize; x++) { CCGElem *elems[4] = { CCG_grid_elem(&args->ccg_key, grid, x, y), - CCG_grid_elem(&args->ccg_key, grid, x + 1, y), - CCG_grid_elem(&args->ccg_key, grid, x + 1, y + 1), - CCG_grid_elem(&args->ccg_key, grid, x, y + 1), + CCG_grid_elem(&args->ccg_key, grid, min_ii(x + 1, gridsize - 1), y), + CCG_grid_elem(&args->ccg_key, + grid, + min_ii(x + 1, gridsize - 1), + min_ii(y + 1, gridsize - 1)), + CCG_grid_elem(&args->ccg_key, grid, x, min_ii(y + 1, gridsize - 1)), }; func(x, y, grid_index, elems, 0); @@ -964,8 +986,10 @@ struct PBVHBatches { GPU_INDEXBUF_DISCARD_SAFE(tri_index); GPU_INDEXBUF_DISCARD_SAFE(lines_index); + GPU_INDEXBUF_DISCARD_SAFE(tri_index_coarse); + GPU_INDEXBUF_DISCARD_SAFE(lines_index_coarse); - tri_index = lines_index = nullptr; + tri_index = lines_index = tri_index_coarse = lines_index_coarse = nullptr; faces_count = tris_count = count; } } @@ -1061,7 +1085,7 @@ struct PBVHBatches { lines_index = GPU_indexbuf_build(&elb_lines); } - void create_index_grids(PBVH_GPU_Args *args) + void create_index_grids(PBVH_GPU_Args *args, bool do_coarse) { int *mat_index = static_cast( CustomData_get_layer_named(args->pdata, CD_PROP_INT32, "material_index")); @@ -1073,15 +1097,24 @@ struct PBVHBatches { needs_tri_index = true; int gridsize = args->ccg_key.grid_size; + int display_gridsize = gridsize; int totgrid = args->totprim; + int skip = 1; + + const int display_level = do_coarse ? coarse_level : args->ccg_key.level; + + if (display_level < args->ccg_key.level) { + display_gridsize = (1 << display_level) + 1; + skip = 1 << (args->ccg_key.level - display_level - 1); + } for (int i : IndexRange(args->totprim)) { int grid_index = args->grid_indices[i]; bool smooth = args->grid_flag_mats[grid_index].flag & ME_SMOOTH; BLI_bitmap *gh = args->grid_hidden[grid_index]; - for (int y = 0; y < gridsize - 1; y++) { - for (int x = 0; x < gridsize - 1; x++) { + for (int y = 0; y < gridsize - 1; y += skip) { + for (int x = 0; x < gridsize - 1; x += skip) { if (gh && paint_is_grid_face_hidden(gh, gridsize, x, y)) { /* Skip hidden faces by just setting smooth to true. */ smooth = true; @@ -1102,12 +1135,17 @@ struct PBVHBatches { CCGKey *key = &args->ccg_key; - uint visible_quad_len = BKE_pbvh_count_grid_quads( - (BLI_bitmap **)args->grid_hidden, args->grid_indices, totgrid, key->grid_size); + uint visible_quad_len = BKE_pbvh_count_grid_quads((BLI_bitmap **)args->grid_hidden, + args->grid_indices, + totgrid, + key->grid_size, + display_gridsize); GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 2 * visible_quad_len, INT_MAX); - GPU_indexbuf_init( - &elb_lines, GPU_PRIM_LINES, 2 * totgrid * gridsize * (gridsize - 1), INT_MAX); + GPU_indexbuf_init(&elb_lines, + GPU_PRIM_LINES, + 2 * totgrid * display_gridsize * (display_gridsize - 1), + INT_MAX); if (needs_tri_index) { uint offset = 0; @@ -1118,17 +1156,17 @@ struct PBVHBatches { BLI_bitmap *gh = args->grid_hidden[args->grid_indices[i]]; - for (int j = 0; j < gridsize - 1; j++) { - for (int k = 0; k < gridsize - 1; k++) { + for (int j = 0; j < gridsize - skip; j += skip) { + for (int k = 0; k < gridsize - skip; k += skip) { /* Skip hidden grid face */ if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) { continue; } /* Indices in a Clockwise QUAD disposition. */ v0 = offset + j * gridsize + k; - v1 = v0 + 1; - v2 = v1 + gridsize; - v3 = v2 - 1; + v1 = offset + j * gridsize + k + skip; + v2 = offset + (j + skip) * gridsize + k + skip; + v3 = offset + (j + skip) * gridsize + k; GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1); GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2); @@ -1136,7 +1174,7 @@ struct PBVHBatches { GPU_indexbuf_add_line_verts(&elb_lines, v0, v1); GPU_indexbuf_add_line_verts(&elb_lines, v0, v3); - if (j + 2 == gridsize) { + if (j / skip + 2 == display_gridsize) { GPU_indexbuf_add_line_verts(&elb_lines, v2, v3); } grid_visible = true; @@ -1151,22 +1189,38 @@ struct PBVHBatches { else { uint offset = 0; const uint grid_vert_len = square_uint(gridsize - 1) * 4; + for (int i = 0; i < totgrid; i++, offset += grid_vert_len) { bool grid_visible = false; BLI_bitmap *gh = args->grid_hidden[args->grid_indices[i]]; uint v0, v1, v2, v3; - for (int j = 0; j < gridsize - 1; j++) { - for (int k = 0; k < gridsize - 1; k++) { + for (int j = 0; j < gridsize - skip; j += skip) { + for (int k = 0; k < gridsize - skip; k += skip) { /* Skip hidden grid face */ if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) { continue; } - /* VBO data are in a Clockwise QUAD disposition. */ - v0 = offset + (j * (gridsize - 1) + k) * 4; - v1 = v0 + 1; - v2 = v0 + 2; - v3 = v0 + 3; + + v0 = (j * (gridsize - 1) + k) * 4; + + if (skip > 1) { + v1 = (j * (gridsize - 1) + k + skip - 1) * 4; + v2 = ((j + skip - 1) * (gridsize - 1) + k + skip - 1) * 4; + v3 = ((j + skip - 1) * (gridsize - 1) + k) * 4; + } + else { + v1 = v2 = v3 = v0; + } + + /* VBO data are in a Clockwise QUAD disposition. Note + * that vertices might be in different quads if we're + * building a coarse index buffer. + */ + v0 += offset; + v1 += offset + 1; + v2 += offset + 2; + v3 += offset + 3; GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1); GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2); @@ -1174,7 +1228,7 @@ struct PBVHBatches { GPU_indexbuf_add_line_verts(&elb_lines, v0, v1); GPU_indexbuf_add_line_verts(&elb_lines, v0, v3); - if (j + 2 == gridsize) { + if ((j / skip) + 2 == display_gridsize) { GPU_indexbuf_add_line_verts(&elb_lines, v2, v3); } grid_visible = true; @@ -1187,8 +1241,16 @@ struct PBVHBatches { } } - tri_index = GPU_indexbuf_build(&elb); - lines_index = GPU_indexbuf_build(&elb_lines); + if (do_coarse) { + tri_index_coarse = GPU_indexbuf_build(&elb); + lines_index_coarse = GPU_indexbuf_build(&elb_lines); + tris_count_coarse = visible_quad_len; + lines_count_coarse = totgrid * display_gridsize * (display_gridsize - 1); + } + else { + tri_index = GPU_indexbuf_build(&elb); + lines_index = GPU_indexbuf_build(&elb_lines); + } } void create_index(PBVH_GPU_Args *args) @@ -1201,7 +1263,12 @@ struct PBVHBatches { create_index_bmesh(args); break; case PBVH_GRIDS: - create_index_grids(args); + create_index_grids(args, false); + + if (args->ccg_key.level > coarse_level) { + create_index_grids(args, true); + } + break; } @@ -1227,7 +1294,7 @@ struct PBVHBatches { } } - void create_batch(PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args) + void create_batch(PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args, bool do_coarse_grids) { check_index_buffers(args); @@ -1236,12 +1303,14 @@ struct PBVHBatches { batch.tris = GPU_batch_create(GPU_PRIM_TRIS, nullptr, /* can be nullptr if buffer is empty */ - tri_index); - batch.tris_count = tris_count; + do_coarse_grids ? tri_index_coarse : tri_index); + batch.tris_count = do_coarse_grids ? tris_count_coarse : tris_count; + batch.is_coarse = do_coarse_grids; if (lines_index) { - batch.lines = GPU_batch_create(GPU_PRIM_LINES, nullptr, lines_index); - batch.lines_count = lines_count; + batch.lines = GPU_batch_create( + GPU_PRIM_LINES, nullptr, do_coarse_grids ? lines_index_coarse : lines_index); + batch.lines_count = do_coarse_grids ? lines_count_coarse : lines_count; } for (int i : IndexRange(attrs_num)) { @@ -1296,9 +1365,10 @@ GPUBatch *DRW_pbvh_tris_get(PBVHBatches *batches, PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args, - int *r_prim_count) + int *r_prim_count, + bool do_coarse_grids) { - PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args); + PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args, do_coarse_grids); *r_prim_count = batch.tris_count; @@ -1309,9 +1379,10 @@ GPUBatch *DRW_pbvh_lines_get(PBVHBatches *batches, PBVHAttrReq *attrs, int attrs_num, PBVH_GPU_Args *args, - int *r_prim_count) + int *r_prim_count, + bool do_coarse_grids) { - PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args); + PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args, do_coarse_grids); *r_prim_count = batch.lines_count; diff --git a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc index 2148e2c5a7a..48a5c52bebc 100644 --- a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc +++ b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc @@ -251,7 +251,8 @@ void *CustomData_get_layer(const struct CustomData * /*data*/, int /*type*/) int BKE_pbvh_count_grid_quads(BLI_bitmap ** /*grid_hidden*/, const int * /*grid_indices*/, int /*totgrid*/, - int /*gridsize*/) + int /*gridsize*/, + int /*display_gridsize*/) { BLI_assert_unreachable(); return 0; From 939b63bcd6c2e2bb92c7d5feb466bb44f4427fc8 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Tue, 13 Dec 2022 13:42:25 -0800 Subject: [PATCH 0067/1522] Sculpt: Fix more attribute bugs when switching PBVH modes Fixed more cases where attributes weren't being reinitialized on switching PBVH mode: * When PBVH_GRIDS and PBVH_BMESH force attributes into simple array mode they no longer override simple_array in the SculptAttributeParams parameters, instead they set a field in SculptAttribute itself. Thus if the attribute is reinitialized in another mode it won't retain the simple_array parameter. * sculpt_attribute_ensure_ex now calls sculpt_attr_update if the attribute already exists. * Fixed a bug from a couple commits ago that set SculptAttribute.data_for_bmesh wrong. --- source/blender/blenkernel/BKE_paint.h | 5 ++ source/blender/blenkernel/intern/multires.cc | 22 +++++++++ source/blender/blenkernel/intern/paint.cc | 51 +++++++++++--------- source/blender/draw/intern/draw_pbvh.cc | 4 ++ 4 files changed, 60 insertions(+), 22 deletions(-) diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 434255b2d9c..4acaa7b05e1 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -516,6 +516,11 @@ typedef struct SculptAttribute { int elem_size, elem_num; bool data_for_bmesh; /* Temporary data store as array outside of bmesh. */ + /* Data is a flat array outside the CustomData system. + * This will be true if simple_array is requested in + * SculptAttributeParams, or the PBVH type is PBVH_GRIDS or PBVH_BMESH. + */ + bool simple_array; /* Data stored per BMesh element. */ int bmesh_cd_offset; diff --git a/source/blender/blenkernel/intern/multires.cc b/source/blender/blenkernel/intern/multires.cc index 7f9a0d64e4b..3700432696a 100644 --- a/source/blender/blenkernel/intern/multires.cc +++ b/source/blender/blenkernel/intern/multires.cc @@ -426,6 +426,28 @@ void multires_flush_sculpt_updates(Object *object) } Mesh *mesh = static_cast(object->data); + + /* Check that the multires modifier still exists. + * Fixes crash when deleting multires modifier + * from within sculpt mode. + */ + ModifierData *md; + MultiresModifierData *mmd = nullptr; + VirtualModifierData virtualModifierData; + + for (md = BKE_modifiers_get_virtual_modifierlist(object, &virtualModifierData); md; + md = md->next) { + if (md->type == eModifierType_Multires) { + if (BKE_modifier_is_enabled(nullptr, md, eModifierMode_Realtime)) { + mmd = (MultiresModifierData *)md; + } + } + } + + if (!mmd) { + return; + } + multiresModifier_reshapeFromCCG( sculpt_session->multires.modifier->totlvl, mesh, sculpt_session->subdiv_ccg); diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 3100b4cc20c..718ec5318ac 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -2454,7 +2454,7 @@ static bool sculpt_attribute_create(SculptSession *ss, permanent = (out->params.permanent = false); } - simple_array = (out->params.simple_array = true); + simple_array = true; } BLI_assert(!(simple_array && permanent)); @@ -2466,8 +2466,8 @@ static bool sculpt_attribute_create(SculptSession *ss, out->data = MEM_calloc_arrayN(totelem, elemsize, __func__); - out->data_for_bmesh = false; - out->params.simple_array = true; + out->data_for_bmesh = ss->bm != nullptr; + out->simple_array = true; out->bmesh_cd_offset = -1; out->layer = nullptr; out->elem_size = elemsize; @@ -2477,6 +2477,8 @@ static bool sculpt_attribute_create(SculptSession *ss, return true; } + out->simple_array = false; + switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_BMESH: { CustomData *cdata = nullptr; @@ -2512,8 +2514,6 @@ static bool sculpt_attribute_create(SculptSession *ss, case PBVH_FACES: { CustomData *cdata = nullptr; - out->data_for_bmesh = false; - switch (domain) { case ATTR_DOMAIN_POINT: cdata = &me->vdata; @@ -2535,10 +2535,10 @@ static bool sculpt_attribute_create(SculptSession *ss, cdata->layers[index].flag |= CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY; } - out->data = nullptr; out->layer = cdata->layers + index; - out->bmesh_cd_offset = -1; out->data = out->layer->data; + out->data_for_bmesh = false; + out->bmesh_cd_offset = -1; out->elem_size = CustomData_get_elem_size(out->layer); break; @@ -2566,31 +2566,36 @@ static bool sculpt_attr_update(Object *ob, SculptAttribute *attr) bool bad = false; - if (attr->params.simple_array) { + if (attr->data) { bad = attr->elem_num != elem_num; - - if (bad) { - MEM_SAFE_FREE(attr->data); - } - else { - attr->data_for_bmesh = false; - } } - else { - CustomData *cdata = sculpt_get_cdata(ob, attr->domain); - if (cdata) { - int layer_index = CustomData_get_named_layer_index(cdata, attr->proptype, attr->name); + /* Check if we are a coerced simple array and shouldn't be. */ + bad |= attr->simple_array && !attr->params.simple_array && + !ELEM(BKE_pbvh_type(ss->pbvh), PBVH_GRIDS, PBVH_BMESH); - bad |= (ss->bm != nullptr) != attr->data_for_bmesh; + CustomData *cdata = sculpt_get_cdata(ob, attr->domain); + if (cdata && !attr->simple_array) { + int layer_index = CustomData_get_named_layer_index(cdata, attr->proptype, attr->name); + bad |= layer_index == -1; + bad |= (ss->bm != nullptr) != attr->data_for_bmesh; + + if (!bad) { if (attr->data_for_bmesh) { attr->bmesh_cd_offset = cdata->layers[layer_index].offset; } + else { + attr->data = cdata->layers[layer_index].data; + } } } if (bad) { + if (attr->simple_array) { + MEM_SAFE_FREE(attr->data); + } + sculpt_attribute_create(ss, ob, attr->domain, @@ -2725,6 +2730,8 @@ static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob, SculptAttribute *attr = BKE_sculpt_attribute_get(ob, domain, proptype, name); if (attr) { + sculpt_attr_update(ob, attr); + return attr; } @@ -2763,7 +2770,7 @@ static void sculptsession_bmesh_attr_update_internal(Object *ob) } } -void sculptsession_bmesh_add_layers(Object *ob) +static void sculptsession_bmesh_add_layers(Object *ob) { SculptSession *ss = ob->sculpt; SculptAttributeParams params = {0}; @@ -2870,7 +2877,7 @@ bool BKE_sculpt_attribute_destroy(Object *ob, SculptAttribute *attr) Mesh *me = BKE_object_get_original_mesh(ob); - if (attr->params.simple_array) { + if (attr->simple_array) { MEM_SAFE_FREE(attr->data); } else if (ss->bm) { diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index 0bdfbf11cb8..c3d660b8ecd 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -1368,6 +1368,8 @@ GPUBatch *DRW_pbvh_tris_get(PBVHBatches *batches, int *r_prim_count, bool do_coarse_grids) { + do_coarse_grids &= args->pbvh_type == PBVH_GRIDS; + PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args, do_coarse_grids); *r_prim_count = batch.tris_count; @@ -1382,6 +1384,8 @@ GPUBatch *DRW_pbvh_lines_get(PBVHBatches *batches, int *r_prim_count, bool do_coarse_grids) { + do_coarse_grids &= args->pbvh_type == PBVH_GRIDS; + PBVHBatch &batch = batches->ensure_batch(attrs, attrs_num, args, do_coarse_grids); *r_prim_count = batch.lines_count; From 9f1d7d930d0e12ab23ed620abcc617bb9d9ec307 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Tue, 13 Dec 2022 13:58:27 -0800 Subject: [PATCH 0068/1522] Cleanup: fix comile error from last commit --- source/blender/blenkernel/intern/paint.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 718ec5318ac..e6d61ddcdd3 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -75,7 +75,7 @@ static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob, const SculptAttributeParams *params, PBVHType pbvhtype, bool flat_array_for_bmesh); -void sculptsession_bmesh_add_layers(Object *ob); +static void sculptsession_bmesh_add_layers(Object *ob); using blender::MutableSpan; using blender::Span; From 23b776e5b313b069456f6d5c82a0a217058a94b1 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 13 Dec 2022 16:00:15 -0600 Subject: [PATCH 0069/1522] Cleanup: Remove disabled code --- .../blender/editors/space_node/node_edit.cc | 10 --------- source/blender/editors/transform/transform.c | 21 ------------------- 2 files changed, 31 deletions(-) diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 95f64999f6e..b7b82fbd661 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -791,16 +791,6 @@ void ED_node_set_active( ED_node_tree_propagate_change(nullptr, bmain, ntree); } } - else if (ntree->type == NTREE_TEXTURE) { - /* XXX */ -#if 0 - if (node->id) { - BIF_preview_changed(-1); - allqueue(REDRAWBUTSSHADING, 1); - allqueue(REDRAWIPO, 0); - } -#endif - } else if (ntree->type == NTREE_GEOMETRY) { if (node->type == GEO_NODE_VIEWER) { if ((node->flag & NODE_DO_OUTPUT) == 0) { diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 77b6f169a08..b8b4cf796f4 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -534,27 +534,6 @@ static void viewRedrawPost(bContext *C, TransInfo *t) /* XXX(ton): temp, first hack to get auto-render in compositor work. */ WM_event_add_notifier(C, NC_SCENE | ND_TRANSFORM_DONE, CTX_data_scene(C)); } - -#if 0 /* TRANSFORM_FIX_ME */ - if (t->spacetype == SPACE_VIEW3D) { - allqueue(REDRAWBUTSOBJECT, 0); - allqueue(REDRAWVIEW3D, 0); - } - else if (t->spacetype == SPACE_IMAGE) { - allqueue(REDRAWIMAGE, 0); - allqueue(REDRAWVIEW3D, 0); - } - else if (ELEM(t->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_GRAPH)) { - allqueue(REDRAWVIEW3D, 0); - allqueue(REDRAWACTION, 0); - allqueue(REDRAWNLA, 0); - allqueue(REDRAWIPO, 0); - allqueue(REDRAWTIME, 0); - allqueue(REDRAWBUTSOBJECT, 0); - } - - scrarea_queue_headredraw(curarea); -#endif } /* ************************************************* */ From a55163c880c4c5720a1db8021c42339a05474e70 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 13 Dec 2022 16:01:47 -0600 Subject: [PATCH 0070/1522] Cleanup: Reduce indentation when setting node active --- .../blender/editors/space_node/node_edit.cc | 197 +++++++++--------- 1 file changed, 99 insertions(+), 98 deletions(-) diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index b7b82fbd661..1bf5b938ee3 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -673,136 +673,137 @@ void ED_node_set_active( } nodeSetActive(ntree, node); + if (node->type == NODE_GROUP) { + return; + } - if (node->type != NODE_GROUP) { - const bool was_output = (node->flag & NODE_DO_OUTPUT) != 0; - bool do_update = false; + const bool was_output = (node->flag & NODE_DO_OUTPUT) != 0; + bool do_update = false; - /* generic node group output: set node as active output */ - if (node->type == NODE_GROUP_OUTPUT) { + /* generic node group output: set node as active output */ + if (node->type == NODE_GROUP_OUTPUT) { + for (bNode *node_iter : ntree->all_nodes()) { + if (node_iter->type == NODE_GROUP_OUTPUT) { + node_iter->flag &= ~NODE_DO_OUTPUT; + } + } + + node->flag |= NODE_DO_OUTPUT; + if (!was_output) { + do_update = true; + BKE_ntree_update_tag_active_output_changed(ntree); + } + } + + /* tree specific activate calls */ + if (ntree->type == NTREE_SHADER) { + if (ELEM(node->type, + SH_NODE_OUTPUT_MATERIAL, + SH_NODE_OUTPUT_WORLD, + SH_NODE_OUTPUT_LIGHT, + SH_NODE_OUTPUT_LINESTYLE)) { for (bNode *node_iter : ntree->all_nodes()) { - if (node_iter->type == NODE_GROUP_OUTPUT) { + if (node_iter->type == node->type) { node_iter->flag &= ~NODE_DO_OUTPUT; } } node->flag |= NODE_DO_OUTPUT; - if (!was_output) { - do_update = true; - BKE_ntree_update_tag_active_output_changed(ntree); - } + BKE_ntree_update_tag_active_output_changed(ntree); } - /* tree specific activate calls */ - if (ntree->type == NTREE_SHADER) { - if (ELEM(node->type, - SH_NODE_OUTPUT_MATERIAL, - SH_NODE_OUTPUT_WORLD, - SH_NODE_OUTPUT_LIGHT, - SH_NODE_OUTPUT_LINESTYLE)) { - for (bNode *node_iter : ntree->all_nodes()) { - if (node_iter->type == node->type) { - node_iter->flag &= ~NODE_DO_OUTPUT; - } - } + ED_node_tree_propagate_change(nullptr, bmain, ntree); - node->flag |= NODE_DO_OUTPUT; - BKE_ntree_update_tag_active_output_changed(ntree); - } + if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) { + /* If active texture changed, free glsl materials. */ + LISTBASE_FOREACH (Material *, ma, &bmain->materials) { + if (ma->nodetree && ma->use_nodes && ntreeHasTree(ma->nodetree, ntree)) { + GPU_material_free(&ma->gpumaterial); - ED_node_tree_propagate_change(nullptr, bmain, ntree); - - if ((node->flag & NODE_ACTIVE_TEXTURE) && !was_active_texture) { - /* If active texture changed, free glsl materials. */ - LISTBASE_FOREACH (Material *, ma, &bmain->materials) { - if (ma->nodetree && ma->use_nodes && ntreeHasTree(ma->nodetree, ntree)) { - GPU_material_free(&ma->gpumaterial); - - /* Sync to active texpaint slot, otherwise we can end up painting on a different slot - * than we are looking at. */ - if (ma->texpaintslot) { - if (node->id != nullptr && GS(node->id->name) == ID_IM) { - Image *image = (Image *)node->id; - for (int i = 0; i < ma->tot_slots; i++) { - if (ma->texpaintslot[i].ima == image) { - ma->paint_active_slot = i; - } + /* Sync to active texpaint slot, otherwise we can end up painting on a different slot + * than we are looking at. */ + if (ma->texpaintslot) { + if (node->id != nullptr && GS(node->id->name) == ID_IM) { + Image *image = (Image *)node->id; + for (int i = 0; i < ma->tot_slots; i++) { + if (ma->texpaintslot[i].ima == image) { + ma->paint_active_slot = i; } } } } } - - LISTBASE_FOREACH (World *, wo, &bmain->worlds) { - if (wo->nodetree && wo->use_nodes && ntreeHasTree(wo->nodetree, ntree)) { - GPU_material_free(&wo->gpumaterial); - } - } - - /* Sync to Image Editor under the following conditions: - * - current image is not pinned - * - current image is not a Render Result or ViewerNode (want to keep looking at these) */ - if (node->id != nullptr && GS(node->id->name) == ID_IM) { - Image *image = (Image *)node->id; - ED_space_image_sync(bmain, image, true); - } - - if (r_active_texture_changed) { - *r_active_texture_changed = true; - } - ED_node_tree_propagate_change(nullptr, bmain, ntree); - WM_main_add_notifier(NC_IMAGE, nullptr); } - WM_main_add_notifier(NC_MATERIAL | ND_NODES, node->id); + LISTBASE_FOREACH (World *, wo, &bmain->worlds) { + if (wo->nodetree && wo->use_nodes && ntreeHasTree(wo->nodetree, ntree)) { + GPU_material_free(&wo->gpumaterial); + } + } + + /* Sync to Image Editor under the following conditions: + * - current image is not pinned + * - current image is not a Render Result or ViewerNode (want to keep looking at these) */ + if (node->id != nullptr && GS(node->id->name) == ID_IM) { + Image *image = (Image *)node->id; + ED_space_image_sync(bmain, image, true); + } + + if (r_active_texture_changed) { + *r_active_texture_changed = true; + } + ED_node_tree_propagate_change(nullptr, bmain, ntree); + WM_main_add_notifier(NC_IMAGE, nullptr); } - else if (ntree->type == NTREE_COMPOSIT) { - /* make active viewer, currently only 1 supported... */ - if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { + + WM_main_add_notifier(NC_MATERIAL | ND_NODES, node->id); + } + else if (ntree->type == NTREE_COMPOSIT) { + /* make active viewer, currently only 1 supported... */ + if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { + for (bNode *node_iter : ntree->all_nodes()) { + if (ELEM(node_iter->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { + node_iter->flag &= ~NODE_DO_OUTPUT; + } + } + + node->flag |= NODE_DO_OUTPUT; + if (was_output == 0) { + BKE_ntree_update_tag_active_output_changed(ntree); + ED_node_tree_propagate_change(nullptr, bmain, ntree); + } + + /* Adding a node doesn't link this yet. */ + node->id = (ID *)BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); + } + else if (node->type == CMP_NODE_COMPOSITE) { + if (was_output == 0) { for (bNode *node_iter : ntree->all_nodes()) { - if (ELEM(node_iter->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { + if (node_iter->type == CMP_NODE_COMPOSITE) { node_iter->flag &= ~NODE_DO_OUTPUT; } } node->flag |= NODE_DO_OUTPUT; - if (was_output == 0) { - BKE_ntree_update_tag_active_output_changed(ntree); - ED_node_tree_propagate_change(nullptr, bmain, ntree); - } - - /* Adding a node doesn't link this yet. */ - node->id = (ID *)BKE_image_ensure_viewer(bmain, IMA_TYPE_COMPOSITE, "Viewer Node"); - } - else if (node->type == CMP_NODE_COMPOSITE) { - if (was_output == 0) { - for (bNode *node_iter : ntree->all_nodes()) { - if (node_iter->type == CMP_NODE_COMPOSITE) { - node_iter->flag &= ~NODE_DO_OUTPUT; - } - } - - node->flag |= NODE_DO_OUTPUT; - BKE_ntree_update_tag_active_output_changed(ntree); - ED_node_tree_propagate_change(nullptr, bmain, ntree); - } - } - else if (do_update) { + BKE_ntree_update_tag_active_output_changed(ntree); ED_node_tree_propagate_change(nullptr, bmain, ntree); } } - else if (ntree->type == NTREE_GEOMETRY) { - if (node->type == GEO_NODE_VIEWER) { - if ((node->flag & NODE_DO_OUTPUT) == 0) { - for (bNode *node_iter : ntree->all_nodes()) { - if (node_iter->type == GEO_NODE_VIEWER) { - node_iter->flag &= ~NODE_DO_OUTPUT; - } + else if (do_update) { + ED_node_tree_propagate_change(nullptr, bmain, ntree); + } + } + else if (ntree->type == NTREE_GEOMETRY) { + if (node->type == GEO_NODE_VIEWER) { + if ((node->flag & NODE_DO_OUTPUT) == 0) { + for (bNode *node_iter : ntree->all_nodes()) { + if (node_iter->type == GEO_NODE_VIEWER) { + node_iter->flag &= ~NODE_DO_OUTPUT; } - node->flag |= NODE_DO_OUTPUT; } - blender::ed::viewer_path::activate_geometry_node(*bmain, *snode, *node); + node->flag |= NODE_DO_OUTPUT; } + blender::ed::viewer_path::activate_geometry_node(*bmain, *snode, *node); } } } From f613614fcebf4dd769abd0d2cfb72fe95ff7bc4c Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 13 Dec 2022 16:42:06 -0600 Subject: [PATCH 0071/1522] Fix T103136: Cannot activate viewer node in group 90ea1b76434fe175e99 created an item for the viewer node path but didn't add it to the list, which also caused memory leaks. --- source/blender/editors/util/ed_viewer_path.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/util/ed_viewer_path.cc b/source/blender/editors/util/ed_viewer_path.cc index f0bbade6361..be569aa02fa 100644 --- a/source/blender/editors/util/ed_viewer_path.cc +++ b/source/blender/editors/util/ed_viewer_path.cc @@ -64,6 +64,7 @@ static void viewer_path_for_geometry_node(const SpaceNode &snode, NodeViewerPathElem *node_elem = BKE_viewer_path_elem_new_node(); node_elem->node_id = node->identifier; node_elem->node_name = BLI_strdup(node->name); + BLI_addtail(&r_dst.path, node_elem); } NodeViewerPathElem *viewer_node_elem = BKE_viewer_path_elem_new_node(); @@ -111,7 +112,7 @@ void activate_geometry_node(Main &bmain, SpaceNode &snode, bNode &node) } } - /* Enable viewer in one viewport if it is disable in all of them. */ + /* Enable viewer in one viewport if it is disabled in all of them. */ if (!found_view3d_with_enabled_viewer && any_view3d_without_viewer != nullptr) { any_view3d_without_viewer->flag2 |= V3D_SHOW_VIEWER; } From ae7ef8bcc66f25200a677718b3df500f876b1c57 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 13 Dec 2022 16:44:13 -0600 Subject: [PATCH 0072/1522] Cleanup: Use const variables in node drawing --- .../blender/editors/space_node/node_draw.cc | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 65cbb49aaed..3bb10404302 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -2813,9 +2813,9 @@ static void frame_node_draw_label(TreeDrawContext &tree_draw_ctx, BLF_wordwrap(fontid, line_width); LISTBASE_FOREACH (const TextLine *, line, &text->lines) { - ResultBLF info; if (line->line[0]) { BLF_position(fontid, x, y, 0); + ResultBLF info; BLF_draw_ex(fontid, line->line, line->len, &info); y -= line_spacing * info.lines; } @@ -2890,10 +2890,8 @@ static void frame_node_draw(const bContext &C, static void reroute_node_draw( const bContext &C, ARegion ®ion, bNodeTree &ntree, bNode &node, uiBlock &block) { - char showname[128]; /* 128 used below */ - const rctf &rct = node.runtime->totr; - /* skip if out of view */ + const rctf &rct = node.runtime->totr; if (rct.xmax < region.v2d.cur.xmin || rct.xmin > region.v2d.cur.xmax || rct.ymax < region.v2d.cur.ymin || node.runtime->totr.ymin > region.v2d.cur.ymax) { UI_block_end(&C, &block); @@ -2902,6 +2900,7 @@ static void reroute_node_draw( if (node.label[0] != '\0') { /* draw title (node label) */ + char showname[128]; /* 128 used below */ BLI_strncpy(showname, node.label, sizeof(showname)); const short width = 512; const int x = BLI_rctf_cent_x(&node.runtime->totr) - (width / 2); @@ -2987,7 +2986,7 @@ static void node_draw_nodetree(const bContext &C, continue; } - bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]); + const bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]); node_draw(C, tree_draw_ctx, region, snode, ntree, *nodes[i], *blocks[i], key); } @@ -3017,7 +3016,7 @@ static void node_draw_nodetree(const bContext &C, continue; } - bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]); + const bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]); node_draw(C, tree_draw_ctx, region, snode, ntree, *nodes[i], *blocks[i], key); } } @@ -3025,8 +3024,6 @@ static void node_draw_nodetree(const bContext &C, /* Draw the breadcrumb on the top of the editor. */ static void draw_tree_path(const bContext &C, ARegion ®ion) { - using namespace blender; - GPU_matrix_push_projection(); wmOrtho2_region_pixelspace(®ion); @@ -3042,7 +3039,7 @@ static void draw_tree_path(const bContext &C, ARegion ®ion) uiLayout *layout = UI_block_layout( block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, x, y, width, 1, 0, style); - Vector context_path = ed::space_node::context_path_for_space_node(C); + const Vector context_path = ed::space_node::context_path_for_space_node(C); ui::template_breadcrumbs(*layout, context_path); UI_block_layout_resolve(block, nullptr, nullptr); @@ -3115,7 +3112,7 @@ static void draw_nodetree(const bContext &C, SpaceNode *snode = CTX_wm_space_node(&C); ntree.ensure_topology_cache(); - Span nodes = ntree.all_nodes(); + const Span nodes = ntree.all_nodes(); Array blocks = node_uiblocks_init(C, nodes); @@ -3126,7 +3123,7 @@ static void draw_nodetree(const bContext &C, tree_draw_ctx.geo_tree_log->ensure_node_warnings(); tree_draw_ctx.geo_tree_log->ensure_node_run_time(); } - WorkSpace *workspace = CTX_wm_workspace(&C); + const WorkSpace *workspace = CTX_wm_workspace(&C); tree_draw_ctx.active_geometry_nodes_viewer = viewer_path::find_geometry_nodes_viewer( workspace->viewer_path, *snode); } From 75ad8da1ea6799e3983e4146f4b20dc4bfbb8415 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 13 Dec 2022 18:39:36 -0600 Subject: [PATCH 0073/1522] Refactor: Replace old Mesh edge split implementation Recently a new geometry node for splitting edges was added in D16399. However, there was already a similar implementation in mesh.cc that was mainly used to fake auto smooth support in Cycles by splitting sharp edges and edges around sharp faces. While there are still possibilities for optimization in the new code, the implementation is safer and simpler, multi-threaded, and aligns better with development plans for caching topology on Mesh and other recent developments with attributes. This patch removes the old code and moves the node implementation to the geometry module so it can be used in editors and RNA. The "free loop normals" argument is deprecated now, since it was only an internal optimization exposed for Cycles. The new mesh `editors` function creates an `IndexMask` of edges to split by reusing some of the code from the corner normal calculation. This change will help to simplify the changes in D16530 and T102858. Differential Revision: https://developer.blender.org/D16732 --- intern/cycles/blender/util.h | 1 + source/blender/blenkernel/BKE_mesh.h | 8 - source/blender/blenkernel/intern/mesh.cc | 261 ---------- source/blender/editors/include/ED_mesh.h | 6 + source/blender/editors/mesh/CMakeLists.txt | 12 + source/blender/editors/mesh/mesh_data.cc | 43 ++ .../blender/editors/object/object_bake_api.c | 4 +- source/blender/geometry/CMakeLists.txt | 2 + .../blender/geometry/GEO_mesh_split_edges.hh | 13 + .../geometry/intern/mesh_split_edges.cc | 490 ++++++++++++++++++ source/blender/makesrna/intern/rna_mesh_api.c | 9 +- .../geometry/nodes/node_geo_edge_split.cc | 484 +---------------- 12 files changed, 577 insertions(+), 756 deletions(-) create mode 100644 source/blender/geometry/GEO_mesh_split_edges.hh create mode 100644 source/blender/geometry/intern/mesh_split_edges.cc diff --git a/intern/cycles/blender/util.h b/intern/cycles/blender/util.h index dbdfbaddaf1..9a4b8c5cc64 100644 --- a/intern/cycles/blender/util.h +++ b/intern/cycles/blender/util.h @@ -113,6 +113,7 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/, if ((bool)mesh && subdivision_type == Mesh::SUBDIVISION_NONE) { if (mesh.use_auto_smooth()) { + mesh.calc_normals_split(); mesh.split_faces(false); } diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index a2067169506..6a55fe00bf6 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -254,14 +254,6 @@ void BKE_mesh_texspace_get_reference(struct Mesh *me, float **r_size); void BKE_mesh_texspace_copy_from_object(struct Mesh *me, struct Object *ob); -/** - * Split faces based on the edge angle and loop normals. - * Matches behavior of face splitting in render engines. - * - * \note Will leave #CD_NORMAL loop data layer which is used by render engines to set shading up. - */ -void BKE_mesh_split_faces(struct Mesh *mesh, bool free_loop_normals); - /** * Create new mesh from the given object at its current state. * The owner of this mesh is unknown, it is up to the caller to decide. diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 1fd2a72f311..77ef4674596 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1836,267 +1836,6 @@ void BKE_mesh_calc_normals_split(Mesh *mesh) BKE_mesh_calc_normals_split_ex(mesh, nullptr, ensure_corner_normal_layer(*mesh)); } -/* Split faces helper functions. */ - -struct SplitFaceNewVert { - struct SplitFaceNewVert *next; - int new_index; - int orig_index; - const float *vnor; -}; - -struct SplitFaceNewEdge { - struct SplitFaceNewEdge *next; - int new_index; - int orig_index; - int v1; - int v2; -}; - -/** - * Detect necessary new vertices, and update loop vertex indices accordingly. - * \warning Leaves mesh in invalid state. - * \param lnors_spacearr: Mandatory because trying to do the job in simple way without that data is - * doomed to fail, even when only dealing with smooth/flat faces one can find cases that no simple - * algorithm can handle properly. - */ -static int split_faces_prepare_new_verts(Mesh &mesh, - const MLoopNorSpaceArray &lnors_spacearr, - SplitFaceNewVert **new_verts, - MemArena &memarena) -{ - const int loops_len = mesh.totloop; - int verts_len = mesh.totvert; - MutableSpan loops = mesh.loops_for_write(); - BKE_mesh_vertex_normals_ensure(&mesh); - float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(&mesh); - - BitVector<> verts_used(verts_len, false); - BitVector<> done_loops(loops_len, false); - - BLI_assert(lnors_spacearr.data_type == MLNOR_SPACEARR_LOOP_INDEX); - - for (int loop_idx = 0; loop_idx < loops_len; loop_idx++) { - if (done_loops[loop_idx]) { - continue; - } - const MLoopNorSpace &lnor_space = *lnors_spacearr.lspacearr[loop_idx]; - const int vert_idx = loops[loop_idx].v; - const bool vert_used = verts_used[vert_idx]; - /* If vert is already used by another smooth fan, we need a new vert for this one. */ - const int new_vert_idx = vert_used ? verts_len++ : vert_idx; - - if (lnor_space.flags & MLNOR_SPACE_IS_SINGLE) { - /* Single loop in this fan... */ - BLI_assert(POINTER_AS_INT(lnor_space.loops) == loop_idx); - done_loops[loop_idx].set(); - if (vert_used) { - loops[loop_idx].v = new_vert_idx; - } - } - else { - for (const LinkNode *lnode = lnor_space.loops; lnode; lnode = lnode->next) { - const int ml_fan_idx = POINTER_AS_INT(lnode->link); - done_loops[ml_fan_idx].set(); - if (vert_used) { - loops[ml_fan_idx].v = new_vert_idx; - } - } - } - - if (!vert_used) { - verts_used[vert_idx].set(); - /* We need to update that vertex's normal here, we won't go over it again. */ - /* This is important! *DO NOT* set vnor to final computed lnor, - * vnor should always be defined to 'automatic normal' value computed from its polys, - * not some custom normal. - * Fortunately, that's the loop normal space's 'lnor' reference vector. ;) */ - copy_v3_v3(vert_normals[vert_idx], lnor_space.vec_lnor); - } - else { - /* Add new vert to list. */ - SplitFaceNewVert *new_vert = static_cast( - BLI_memarena_alloc(&memarena, sizeof(*new_vert))); - new_vert->orig_index = vert_idx; - new_vert->new_index = new_vert_idx; - new_vert->vnor = lnor_space.vec_lnor; /* See note above. */ - new_vert->next = *new_verts; - *new_verts = new_vert; - } - } - - return verts_len - mesh.totvert; -} - -/* Detect needed new edges, and update accordingly loops' edge indices. - * WARNING! Leaves mesh in invalid state. */ -static int split_faces_prepare_new_edges(Mesh *mesh, - SplitFaceNewEdge **new_edges, - MemArena *memarena) -{ - const int num_polys = mesh->totpoly; - int num_edges = mesh->totedge; - MutableSpan edges = mesh->edges_for_write(); - MutableSpan loops = mesh->loops_for_write(); - const Span polys = mesh->polys(); - - BitVector<> edges_used(num_edges, false); - EdgeHash *edges_hash = BLI_edgehash_new_ex(__func__, num_edges); - - const MPoly *mp = polys.data(); - for (int poly_idx = 0; poly_idx < num_polys; poly_idx++, mp++) { - MLoop *ml_prev = &loops[mp->loopstart + mp->totloop - 1]; - MLoop *ml = &loops[mp->loopstart]; - for (int loop_idx = 0; loop_idx < mp->totloop; loop_idx++, ml++) { - void **eval; - if (!BLI_edgehash_ensure_p(edges_hash, ml_prev->v, ml->v, &eval)) { - const int edge_idx = ml_prev->e; - - /* That edge has not been encountered yet, define it. */ - if (edges_used[edge_idx]) { - /* Original edge has already been used, we need to define a new one. */ - const int new_edge_idx = num_edges++; - *eval = POINTER_FROM_INT(new_edge_idx); - ml_prev->e = new_edge_idx; - - SplitFaceNewEdge *new_edge = (SplitFaceNewEdge *)BLI_memarena_alloc(memarena, - sizeof(*new_edge)); - new_edge->orig_index = edge_idx; - new_edge->new_index = new_edge_idx; - new_edge->v1 = ml_prev->v; - new_edge->v2 = ml->v; - new_edge->next = *new_edges; - *new_edges = new_edge; - } - else { - /* We can re-use original edge. */ - edges[edge_idx].v1 = ml_prev->v; - edges[edge_idx].v2 = ml->v; - *eval = POINTER_FROM_INT(edge_idx); - edges_used[edge_idx].set(); - } - } - else { - /* Edge already known, just update loop's edge index. */ - ml_prev->e = POINTER_AS_INT(*eval); - } - - ml_prev = ml; - } - } - - BLI_edgehash_free(edges_hash, nullptr); - - return num_edges - mesh->totedge; -} - -/* Perform actual split of vertices. */ -static void split_faces_split_new_verts(Mesh *mesh, - SplitFaceNewVert *new_verts, - const int num_new_verts) -{ - const int verts_len = mesh->totvert - num_new_verts; - float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(mesh); - - /* Normals were already calculated at the beginning of this operation, we rely on that to update - * them partially here. */ - BLI_assert(!BKE_mesh_vertex_normals_are_dirty(mesh)); - - /* Remember new_verts is a single linklist, so its items are in reversed order... */ - for (int i = mesh->totvert - 1; i >= verts_len; i--, new_verts = new_verts->next) { - BLI_assert(new_verts->new_index == i); - BLI_assert(new_verts->new_index != new_verts->orig_index); - CustomData_copy_data(&mesh->vdata, &mesh->vdata, new_verts->orig_index, i, 1); - if (new_verts->vnor) { - copy_v3_v3(vert_normals[i], new_verts->vnor); - } - } -} - -/* Perform actual split of edges. */ -static void split_faces_split_new_edges(Mesh *mesh, - SplitFaceNewEdge *new_edges, - const int num_new_edges) -{ - const int num_edges = mesh->totedge - num_new_edges; - MutableSpan edges = mesh->edges_for_write(); - - /* Remember new_edges is a single linklist, so its items are in reversed order... */ - MEdge *new_med = &edges[mesh->totedge - 1]; - for (int i = mesh->totedge - 1; i >= num_edges; i--, new_med--, new_edges = new_edges->next) { - BLI_assert(new_edges->new_index == i); - BLI_assert(new_edges->new_index != new_edges->orig_index); - CustomData_copy_data(&mesh->edata, &mesh->edata, new_edges->orig_index, i, 1); - new_med->v1 = new_edges->v1; - new_med->v2 = new_edges->v2; - } -} - -void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals) -{ - const int num_polys = mesh->totpoly; - - if (num_polys == 0) { - return; - } - BKE_mesh_tessface_clear(mesh); - - MLoopNorSpaceArray lnors_spacearr = {nullptr}; - /* Compute loop normals and loop normal spaces (a.k.a. smooth fans of faces around vertices). */ - BKE_mesh_calc_normals_split_ex(mesh, &lnors_spacearr, ensure_corner_normal_layer(*mesh)); - /* Stealing memarena from loop normals space array. */ - MemArena *memarena = lnors_spacearr.mem; - - SplitFaceNewVert *new_verts = nullptr; - SplitFaceNewEdge *new_edges = nullptr; - - /* Detect loop normal spaces (a.k.a. smooth fans) that will need a new vert. */ - const int num_new_verts = split_faces_prepare_new_verts( - *mesh, lnors_spacearr, &new_verts, *memarena); - - if (num_new_verts > 0) { - /* Reminder: beyond this point, there is no way out, mesh is in invalid state - * (due to early-reassignment of loops' vertex and edge indices to new, - * to-be-created split ones). */ - - const int num_new_edges = split_faces_prepare_new_edges(mesh, &new_edges, memarena); - /* We can have to split a vertex without having to add a single new edge... */ - const bool do_edges = (num_new_edges > 0); - - /* Reallocate all vert and edge related data. */ - CustomData_realloc(&mesh->vdata, mesh->totvert, mesh->totvert + num_new_verts); - mesh->totvert += num_new_verts; - if (do_edges) { - CustomData_realloc(&mesh->edata, mesh->totedge, mesh->totedge + num_new_edges); - mesh->totedge += num_new_edges; - } - - /* Update normals manually to avoid recalculation after this operation. */ - mesh->runtime->vert_normals = (float(*)[3])MEM_reallocN(mesh->runtime->vert_normals, - sizeof(float[3]) * mesh->totvert); - - /* Perform actual split of vertices and edges. */ - split_faces_split_new_verts(mesh, new_verts, num_new_verts); - if (do_edges) { - split_faces_split_new_edges(mesh, new_edges, num_new_edges); - } - } - - /* NOTE: after this point mesh is expected to be valid again. */ - - /* CD_NORMAL is expected to be temporary only. */ - if (free_loop_normals) { - CustomData_free_layers(&mesh->ldata, CD_NORMAL, mesh->totloop); - } - - /* Also frees new_verts/edges temp data, since we used its memarena to allocate them. */ - BKE_lnor_spacearr_free(&lnors_spacearr); - -#ifdef VALIDATE_MESH - BKE_mesh_validate(mesh, true, true); -#endif -} - /* **** Depsgraph evaluation **** */ void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh) diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index bab1f7e4c5e..b2864f2a6cc 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -581,6 +581,12 @@ void ED_mesh_report_mirror_ex(struct wmOperator *op, int totmirr, int totfail, c */ struct Mesh *ED_mesh_context(struct bContext *C); +/** + * Split all edges that would appear sharp based onface and edge sharpness tags and the auto smooth + * angle. + */ +void ED_mesh_split_faces(struct Mesh *mesh); + /* mesh backup */ typedef struct BMBackup { struct BMesh *bmcopy; diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt index a43968074d6..283969cee47 100644 --- a/source/blender/editors/mesh/CMakeLists.txt +++ b/source/blender/editors/mesh/CMakeLists.txt @@ -10,6 +10,7 @@ set(INC ../../bmesh ../../depsgraph ../../draw + ../../geometry ../../gpu ../../imbuf ../../makesdna @@ -76,6 +77,17 @@ if(WITH_GMP) add_definitions(-DWITH_GMP) endif() +if(WITH_TBB) + add_definitions(-DWITH_TBB) + + list(APPEND INC_SYS + ${TBB_INCLUDE_DIRS} + ) + + list(APPEND LIB + ${TBB_LIBRARIES} + ) +endif() blender_add_lib(bf_editor_mesh "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index 2e9f9729f6d..b2809030192 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -14,6 +14,7 @@ #include "DNA_view3d_types.h" #include "BLI_array.hh" +#include "BLI_index_mask_ops.hh" #include "BLI_math.h" #include "BLI_utildefines.h" @@ -42,6 +43,8 @@ #include "ED_uvedit.h" #include "ED_view3d.h" +#include "GEO_mesh_split_edges.hh" + #include "mesh_intern.h" /* own include */ using blender::Array; @@ -1464,3 +1467,43 @@ Mesh *ED_mesh_context(bContext *C) return (Mesh *)data; } + +void ED_mesh_split_faces(Mesh *mesh) +{ + using namespace blender; + Array edges(mesh->edges()); + const Span polys = mesh->polys(); + const Span loops = mesh->loops(); + const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : float(M_PI); + BKE_edges_sharp_from_angle_set(edges.data(), + edges.size(), + loops.data(), + loops.size(), + polys.data(), + BKE_mesh_poly_normals_ensure(mesh), + polys.size(), + split_angle); + + threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) { + for (const int poly_i : range) { + const MPoly &poly = polys[poly_i]; + if (!(poly.flag & ME_SMOOTH)) { + for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { + edges[loop.e].flag |= ME_SHARP; + } + } + } + }); + + Vector split_indices; + const IndexMask split_mask = index_mask_ops::find_indices_based_on_predicate( + edges.index_range(), 4096, split_indices, [&](const int64_t i) { + return edges[i].flag & ME_SHARP; + }); + + if (split_mask.is_empty()) { + return; + } + + geometry::split_edges(*mesh, split_mask); +} diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index e69ccf5a50d..d883388fbff 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -55,6 +55,7 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_mesh.h" #include "ED_object.h" #include "ED_screen.h" #include "ED_uvedit.h" @@ -670,7 +671,8 @@ static Mesh *bake_mesh_new_from_object(Depsgraph *depsgraph, Mesh *me = BKE_mesh_new_from_object(depsgraph, object, false, preserve_origindex); if (me->flag & ME_AUTOSMOOTH) { - BKE_mesh_split_faces(me, true); + ED_mesh_split_faces(me); + CustomData_free_layers(&me->ldata, CD_NORMAL, me->totloop); } return me; diff --git a/source/blender/geometry/CMakeLists.txt b/source/blender/geometry/CMakeLists.txt index 9e1929b60a8..e3c0c0c898d 100644 --- a/source/blender/geometry/CMakeLists.txt +++ b/source/blender/geometry/CMakeLists.txt @@ -19,6 +19,7 @@ set(SRC intern/fillet_curves.cc intern/mesh_merge_by_distance.cc intern/mesh_primitive_cuboid.cc + intern/mesh_split_edges.cc intern/mesh_to_curve_convert.cc intern/mesh_to_volume.cc intern/point_merge_by_distance.cc @@ -34,6 +35,7 @@ set(SRC GEO_fillet_curves.hh GEO_mesh_merge_by_distance.hh GEO_mesh_primitive_cuboid.hh + GEO_mesh_split_edges.hh GEO_mesh_to_curve.hh GEO_mesh_to_volume.hh GEO_point_merge_by_distance.hh diff --git a/source/blender/geometry/GEO_mesh_split_edges.hh b/source/blender/geometry/GEO_mesh_split_edges.hh new file mode 100644 index 00000000000..f104a55ae4d --- /dev/null +++ b/source/blender/geometry/GEO_mesh_split_edges.hh @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include "BLI_index_mask.hh" + +struct Mesh; + +namespace blender::geometry { + +void split_edges(Mesh &mesh, IndexMask mask); + +} // namespace blender::geometry diff --git a/source/blender/geometry/intern/mesh_split_edges.cc b/source/blender/geometry/intern/mesh_split_edges.cc new file mode 100644 index 00000000000..ba00ba5a8a6 --- /dev/null +++ b/source/blender/geometry/intern/mesh_split_edges.cc @@ -0,0 +1,490 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BLI_array_utils.hh" +#include "BLI_devirtualize_parameters.hh" +#include "BLI_index_mask.hh" + +#include "BKE_attribute.hh" +#include "BKE_attribute_math.hh" +#include "BKE_mesh.h" +#include "BKE_mesh_mapping.h" + +#include "GEO_mesh_split_edges.hh" + +namespace blender::geometry { + +/* Naively checks if the first vertices and the second vertices are the same. */ +static inline bool naive_edges_equal(const MEdge &edge1, const MEdge &edge2) +{ + return edge1.v1 == edge2.v1 && edge1.v2 == edge2.v2; +} + +template +static void copy_to_new_verts(MutableSpan data, const Span new_to_old_verts_map) +{ + const Span old_data = data.drop_back(new_to_old_verts_map.size()); + MutableSpan new_data = data.take_back(new_to_old_verts_map.size()); + array_utils::gather(old_data, new_to_old_verts_map, new_data); +} + +static void add_new_vertices(Mesh &mesh, const Span new_to_old_verts_map) +{ + CustomData_realloc(&mesh.vdata, mesh.totvert, mesh.totvert + new_to_old_verts_map.size()); + mesh.totvert += new_to_old_verts_map.size(); + + bke::MutableAttributeAccessor attributes = mesh.attributes_for_write(); + for (const bke::AttributeIDRef &id : attributes.all_ids()) { + if (attributes.lookup_meta_data(id)->domain != ATTR_DOMAIN_POINT) { + continue; + } + bke::GSpanAttributeWriter attribute = attributes.lookup_for_write_span(id); + if (!attribute) { + continue; + } + + attribute_math::convert_to_static_type(attribute.span.type(), [&](auto dummy) { + using T = decltype(dummy); + copy_to_new_verts(attribute.span.typed(), new_to_old_verts_map); + }); + + attribute.finish(); + } + if (float3 *orco = static_cast(CustomData_get_layer(&mesh.vdata, CD_ORCO))) { + copy_to_new_verts({orco, mesh.totvert}, new_to_old_verts_map); + } + if (int *orig_indices = static_cast(CustomData_get_layer(&mesh.vdata, CD_ORIGINDEX))) { + copy_to_new_verts({orig_indices, mesh.totvert}, new_to_old_verts_map); + } +} + +static void add_new_edges(Mesh &mesh, + const Span new_edges, + const Span new_to_old_edges_map) +{ + bke::MutableAttributeAccessor attributes = mesh.attributes_for_write(); + + /* Store a copy of the IDs locally since we will remove the existing attributes which + * can also free the names, since the API does not provide pointer stability. */ + Vector named_ids; + Vector anonymous_ids; + for (const bke::AttributeIDRef &id : attributes.all_ids()) { + if (attributes.lookup_meta_data(id)->domain != ATTR_DOMAIN_EDGE) { + continue; + } + if (!id.should_be_kept()) { + continue; + } + if (id.is_named()) { + named_ids.append(id.name()); + } + else { + anonymous_ids.append(bke::WeakAnonymousAttributeID(&id.anonymous_id())); + } + } + Vector local_edge_ids; + for (const StringRef name : named_ids) { + local_edge_ids.append(name); + } + for (const bke::WeakAnonymousAttributeID &id : anonymous_ids) { + local_edge_ids.append(id.get()); + } + + /* Build new arrays for the copied edge attributes. Unlike vertices, new edges aren't all at the + * end of the array, so just copying to the new edges would overwrite old values when they were + * still needed. */ + struct NewAttributeData { + const bke::AttributeIDRef &local_id; + const CPPType &type; + void *array; + }; + Vector dst_attributes; + for (const bke::AttributeIDRef &id : local_edge_ids) { + bke::GAttributeReader attribute = attributes.lookup(id); + if (!attribute) { + continue; + } + + const CPPType &type = attribute.varray.type(); + void *new_data = MEM_malloc_arrayN(new_edges.size(), type.size(), __func__); + + attribute_math::convert_to_static_type(type, [&](auto dummy) { + using T = decltype(dummy); + const VArray src = attribute.varray.typed(); + MutableSpan dst(static_cast(new_data), new_edges.size()); + array_utils::gather(src, new_to_old_edges_map, dst); + }); + + /* Free the original attribute as soon as possible to lower peak memory usage. */ + attributes.remove(id); + dst_attributes.append({id, type, new_data}); + } + + int *new_orig_indices = nullptr; + if (const int *orig_indices = static_cast( + CustomData_get_layer(&mesh.edata, CD_ORIGINDEX))) { + new_orig_indices = static_cast( + MEM_malloc_arrayN(new_edges.size(), sizeof(int), __func__)); + array_utils::gather(Span(orig_indices, mesh.totedge), + new_to_old_edges_map, + {new_orig_indices, new_edges.size()}); + } + + CustomData_free(&mesh.edata, mesh.totedge); + mesh.totedge = new_edges.size(); + CustomData_add_layer(&mesh.edata, CD_MEDGE, CD_CONSTRUCT, nullptr, mesh.totedge); + mesh.edges_for_write().copy_from(new_edges); + + if (new_orig_indices != nullptr) { + CustomData_add_layer(&mesh.edata, CD_ORIGINDEX, CD_ASSIGN, new_orig_indices, mesh.totedge); + } + + for (NewAttributeData &new_data : dst_attributes) { + attributes.add(new_data.local_id, + ATTR_DOMAIN_EDGE, + bke::cpp_type_to_custom_data_type(new_data.type), + bke::AttributeInitMoveArray(new_data.array)); + } +} + +/** + * Merge the new_edge into the original edge. + * + * NOTE: This function is very specific to the situation and makes a lot of assumptions. + */ +static void merge_edges(const int orig_edge_i, + const int new_edge_i, + MutableSpan new_loops, + Vector> &edge_to_loop_map, + Vector &new_edges, + Vector &new_to_old_edges_map) +{ + /* Merge back into the original edge by undoing the topology changes. */ + BLI_assert(edge_to_loop_map[new_edge_i].size() == 1); + const int loop_i = edge_to_loop_map[new_edge_i][0]; + new_loops[loop_i].e = orig_edge_i; + + /* We are putting the last edge in the location of new_edge in all the maps, to remove + * new_edge efficiently. We have to update the topology information for this last edge + * though. Essentially we are replacing every instance of last_edge_i with new_edge_i. */ + const int last_edge_i = new_edges.size() - 1; + if (last_edge_i != new_edge_i) { + BLI_assert(edge_to_loop_map[last_edge_i].size() == 1); + const int last_edge_loop_i = edge_to_loop_map[last_edge_i][0]; + new_loops[last_edge_loop_i].e = new_edge_i; + } + + /* We can now safely swap-remove. */ + new_edges.remove_and_reorder(new_edge_i); + edge_to_loop_map.remove_and_reorder(new_edge_i); + new_to_old_edges_map.remove_and_reorder(new_edge_i); +} + +/** + * Replace the vertex of an edge with a new one, and update the connected loops. + * + * NOTE: This only updates the loops containing the edge and the old vertex. It should therefore + * also be called on the adjacent edge. + */ +static void swap_vertex_of_edge(MEdge &edge, + const int old_vert, + const int new_vert, + MutableSpan loops, + const Span connected_loops) +{ + if (edge.v1 == old_vert) { + edge.v1 = new_vert; + } + else if (edge.v2 == old_vert) { + edge.v2 = new_vert; + } + else { + BLI_assert_unreachable(); + } + + for (const int loop_i : connected_loops) { + if (loops[loop_i].v == old_vert) { + loops[loop_i].v = new_vert; + } + /* The old vertex is on the loop containing the adjacent edge. Since this function is also + * called on the adjacent edge, we don't replace it here. */ + } +} + +/** Split the vertex into duplicates so that each fan has a different vertex. */ +static void split_vertex_per_fan(const int vertex, + const int start_offset, + const int orig_verts_num, + const Span fans, + const Span fan_sizes, + const Span> edge_to_loop_map, + MutableSpan new_edges, + MutableSpan new_loops, + MutableSpan new_to_old_verts_map) +{ + int fan_start = 0; + /* We don't need to create a new vertex for the last fan. That fan can just be connected to the + * original vertex. */ + for (const int i : fan_sizes.index_range().drop_back(1)) { + const int new_vert_i = start_offset + i; + new_to_old_verts_map[new_vert_i - orig_verts_num] = vertex; + + for (const int edge_i : fans.slice(fan_start, fan_sizes[i])) { + swap_vertex_of_edge( + new_edges[edge_i], vertex, new_vert_i, new_loops, edge_to_loop_map[edge_i]); + } + fan_start += fan_sizes[i]; + } +} + +/** + * Get the index of the adjacent edge to a loop connected to a vertex. In other words, for the + * given polygon return the unique edge connected to the given vertex and not on the given loop. + */ +static int adjacent_edge(Span loops, const int loop_i, const MPoly &poly, const int vertex) +{ + const int adjacent_loop_i = (loops[loop_i].v == vertex) ? + bke::mesh_topology::poly_loop_prev(poly, loop_i) : + bke::mesh_topology::poly_loop_next(poly, loop_i); + return loops[adjacent_loop_i].e; +} + +/** + * Calculate the disjoint fans connected to the vertex, where a fan is a group of edges connected + * through polygons. The connected_edges vector is rearranged in such a way that edges in the same + * fan are grouped together. The r_fans_sizes Vector gives the sizes of the different fans, and can + * be used to retrieve the fans from connected_edges. + */ +static void calc_vertex_fans(const int vertex, + const Span new_loops, + const Span polys, + const Span> edge_to_loop_map, + const Span loop_to_poly_map, + MutableSpan connected_edges, + Vector &r_fan_sizes) +{ + if (connected_edges.size() <= 1) { + r_fan_sizes.append(connected_edges.size()); + return; + } + + Vector search_edges; + int total_found_edges_num = 0; + int fan_size = 0; + const int total_edge_num = connected_edges.size(); + /* Iteratively go through the connected edges. The front contains already handled edges, while + * the back contains unhandled edges. */ + while (true) { + /* This edge has not been visited yet. */ + int curr_i = total_found_edges_num; + int curr_edge_i = connected_edges[curr_i]; + + /* Gather all the edges in this fan. */ + while (true) { + fan_size++; + + /* Add adjacent edges to search stack. */ + for (const int loop_i : edge_to_loop_map[curr_edge_i]) { + const int adjacent_edge_i = adjacent_edge( + new_loops, loop_i, polys[loop_to_poly_map[loop_i]], vertex); + + /* Find out if this edge was visited already. */ + int i = curr_i + 1; + for (; i < total_edge_num; i++) { + if (connected_edges[i] == adjacent_edge_i) { + break; + } + } + if (i == total_edge_num) { + /* Already visited this edge. */ + continue; + } + search_edges.append(adjacent_edge_i); + curr_i++; + std::swap(connected_edges[curr_i], connected_edges[i]); + } + + if (search_edges.is_empty()) { + break; + } + + curr_edge_i = search_edges.pop_last(); + } + /* We have now collected all the edges in this fan. */ + total_found_edges_num += fan_size; + BLI_assert(total_found_edges_num <= total_edge_num); + r_fan_sizes.append(fan_size); + if (total_found_edges_num == total_edge_num) { + /* We have found all the edges, so this final batch must be the last connected fan. */ + break; + } + fan_size = 0; + } +} + +/** + * Splits the edge into duplicates, so that each edge is connected to one poly. + */ +static void split_edge_per_poly(const int edge_i, + const int new_edge_start, + MutableSpan> edge_to_loop_map, + MutableSpan new_loops, + MutableSpan new_edges, + MutableSpan new_to_old_edges_map) +{ + if (edge_to_loop_map[edge_i].size() <= 1) { + return; + } + int new_edge_index = new_edge_start; + for (const int loop_i : edge_to_loop_map[edge_i].as_span().drop_front(1)) { + const MEdge new_edge(new_edges[edge_i]); + new_edges[new_edge_index] = new_edge; + new_to_old_edges_map[new_edge_index] = edge_i; + edge_to_loop_map[new_edge_index].append({loop_i}); + new_loops[loop_i].e = new_edge_index; + new_edge_index++; + } + /* Only the first loop is now connected to this edge. */ + edge_to_loop_map[edge_i].resize(1); +} + +void split_edges(Mesh &mesh, const IndexMask mask) +{ + /* Flag vertices that need to be split. */ + Array should_split_vert(mesh.totvert, false); + const Span edges = mesh.edges(); + for (const int edge_i : mask) { + const MEdge edge = edges[edge_i]; + should_split_vert[edge.v1] = true; + should_split_vert[edge.v2] = true; + } + + /* Precalculate topology info. */ + Array> vert_to_edge_map = bke::mesh_topology::build_vert_to_edge_map(edges, + mesh.totvert); + Vector> edge_to_loop_map = bke::mesh_topology::build_edge_to_loop_map_resizable( + mesh.loops(), mesh.totedge); + Array loop_to_poly_map = bke::mesh_topology::build_loop_to_poly_map(mesh.polys(), + mesh.totloop); + + /* Store offsets, so we can split edges in parallel. */ + Array edge_offsets(edges.size()); + Array num_edge_duplicates(edges.size()); + int new_edges_size = edges.size(); + for (const int edge : mask) { + edge_offsets[edge] = new_edges_size; + /* We add duplicates of the edge for each poly (except the first). */ + const int num_connected_loops = edge_to_loop_map[edge].size(); + const int num_duplicates = std::max(0, num_connected_loops - 1); + new_edges_size += num_duplicates; + num_edge_duplicates[edge] = num_duplicates; + } + + const Span polys = mesh.polys(); + + MutableSpan loops = mesh.loops_for_write(); + Vector new_edges(new_edges_size); + new_edges.as_mutable_span().take_front(edges.size()).copy_from(edges); + + edge_to_loop_map.resize(new_edges_size); + + /* Used for transferring attributes. */ + Vector new_to_old_edges_map(IndexRange(new_edges.size()).as_span()); + + /* Step 1: Split the edges. */ + threading::parallel_for(mask.index_range(), 512, [&](IndexRange range) { + for (const int mask_i : range) { + const int edge_i = mask[mask_i]; + split_edge_per_poly( + edge_i, edge_offsets[edge_i], edge_to_loop_map, loops, new_edges, new_to_old_edges_map); + } + }); + + /* Step 1.5: Update topology information (can't parallelize). */ + for (const int edge_i : mask) { + const MEdge &edge = edges[edge_i]; + for (const int duplicate_i : IndexRange(edge_offsets[edge_i], num_edge_duplicates[edge_i])) { + vert_to_edge_map[edge.v1].append(duplicate_i); + vert_to_edge_map[edge.v2].append(duplicate_i); + } + } + + /* Step 2: Calculate vertex fans. */ + Array> vertex_fan_sizes(mesh.totvert); + threading::parallel_for(IndexRange(mesh.totvert), 512, [&](IndexRange range) { + for (const int vert : range) { + if (!should_split_vert[vert]) { + continue; + } + calc_vertex_fans(vert, + loops, + polys, + edge_to_loop_map, + loop_to_poly_map, + vert_to_edge_map[vert], + vertex_fan_sizes[vert]); + } + }); + + /* Step 2.5: Calculate offsets for next step. */ + Array vert_offsets(mesh.totvert); + int total_verts_num = mesh.totvert; + for (const int vert : IndexRange(mesh.totvert)) { + if (!should_split_vert[vert]) { + continue; + } + vert_offsets[vert] = total_verts_num; + /* We only create a new vertex for each fan different from the first. */ + total_verts_num += vertex_fan_sizes[vert].size() - 1; + } + + /* Step 3: Split the vertices. + * Build a map from each new vertex to an old vertex to use for transferring attributes later. */ + const int new_verts_num = total_verts_num - mesh.totvert; + Array new_to_old_verts_map(new_verts_num); + threading::parallel_for(IndexRange(mesh.totvert), 512, [&](IndexRange range) { + for (const int vert : range) { + if (!should_split_vert[vert]) { + continue; + } + split_vertex_per_fan(vert, + vert_offsets[vert], + mesh.totvert, + vert_to_edge_map[vert], + vertex_fan_sizes[vert], + edge_to_loop_map, + new_edges, + loops, + new_to_old_verts_map); + } + }); + + /* Step 4: Deduplicate edges. We loop backwards so we can use remove_and_reorder. Although this + * does look bad (3 nested loops), in practice the inner loops are very small. For most meshes, + * there are at most 2 polygons connected to each edge, and hence you'll only get at most 1 + * duplicate per edge. */ + for (int mask_i = mask.size() - 1; mask_i >= 0; mask_i--) { + const int edge = mask[mask_i]; + int start_of_duplicates = edge_offsets[edge]; + int end_of_duplicates = start_of_duplicates + num_edge_duplicates[edge] - 1; + for (int duplicate = end_of_duplicates; duplicate >= start_of_duplicates; duplicate--) { + if (naive_edges_equal(new_edges[edge], new_edges[duplicate])) { + merge_edges(edge, duplicate, loops, edge_to_loop_map, new_edges, new_to_old_edges_map); + break; + } + for (int other = start_of_duplicates; other < duplicate; other++) { + if (naive_edges_equal(new_edges[other], new_edges[duplicate])) { + merge_edges(other, duplicate, loops, edge_to_loop_map, new_edges, new_to_old_edges_map); + break; + } + } + } + } + + /* Step 5: Resize the mesh to add the new vertices and rebuild the edges. */ + add_new_vertices(mesh, new_to_old_verts_map); + add_new_edges(mesh, new_edges, new_to_old_edges_map); + + BKE_mesh_tag_edges_split(&mesh); +} + +} // namespace blender::geometry diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 90267a3c3c5..289de8285be 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -174,9 +174,9 @@ static void rna_Mesh_flip_normals(Mesh *mesh) DEG_id_tag_update(&mesh->id, 0); } -static void rna_Mesh_split_faces(Mesh *mesh, bool free_loop_normals) +static void rna_Mesh_split_faces(Mesh *mesh, bool UNUSED(free_loop_normals)) { - BKE_mesh_split_faces(mesh, free_loop_normals != 0); + ED_mesh_split_faces(mesh); } static void rna_Mesh_update_gpu_tag(Mesh *mesh) @@ -234,8 +234,9 @@ void RNA_api_mesh(StructRNA *srna) func = RNA_def_function(srna, "split_faces", "rna_Mesh_split_faces"); RNA_def_function_ui_description(func, "Split faces based on the edge angle"); - RNA_def_boolean( - func, "free_loop_normals", 1, "Free Loop Normals", "Free loop normals custom data layer"); + /* TODO: This parameter has no effect anymore, since the internal code does not need to + * compute temporary CD_NORMAL loop data. It should be removed for next major release (4.0). */ + RNA_def_boolean(func, "free_loop_normals", 1, "Free Loop Normals", "Deprecated, has no effect"); func = RNA_def_function(srna, "calc_tangents", "rna_Mesh_calc_tangents"); RNA_def_function_flag(func, FUNC_USE_REPORTS); diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc index 30c3e710432..88ec358d9ac 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc @@ -1,14 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#include "BLI_array_utils.hh" -#include "BLI_task.hh" - #include "DNA_mesh_types.h" -#include "BKE_attribute_math.hh" -#include "BKE_mesh.h" -#include "BKE_mesh_mapping.h" -#include "BKE_mesh_runtime.h" +#include "GEO_mesh_split_edges.hh" #include "node_geometry_util.hh" @@ -21,480 +15,6 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output(N_("Mesh")); } -/* Naively checks if the first vertices and the second vertices are the same. */ -static inline bool naive_edges_equal(const MEdge &edge1, const MEdge &edge2) -{ - return edge1.v1 == edge2.v1 && edge1.v2 == edge2.v2; -} - -template -static void copy_to_new_verts(MutableSpan data, const Span new_to_old_verts_map) -{ - const Span old_data = data.drop_back(new_to_old_verts_map.size()); - MutableSpan new_data = data.take_back(new_to_old_verts_map.size()); - array_utils::gather(old_data, new_to_old_verts_map, new_data); -} - -static void add_new_vertices(Mesh &mesh, const Span new_to_old_verts_map) -{ - CustomData_realloc(&mesh.vdata, mesh.totvert, mesh.totvert + new_to_old_verts_map.size()); - mesh.totvert += new_to_old_verts_map.size(); - - MutableAttributeAccessor attributes = mesh.attributes_for_write(); - for (const AttributeIDRef &id : attributes.all_ids()) { - if (attributes.lookup_meta_data(id)->domain != ATTR_DOMAIN_POINT) { - continue; - } - GSpanAttributeWriter attribute = attributes.lookup_for_write_span(id); - if (!attribute) { - continue; - } - - attribute_math::convert_to_static_type(attribute.span.type(), [&](auto dummy) { - using T = decltype(dummy); - copy_to_new_verts(attribute.span.typed(), new_to_old_verts_map); - }); - - attribute.finish(); - } - if (float3 *orco = static_cast(CustomData_get_layer(&mesh.vdata, CD_ORCO))) { - copy_to_new_verts({orco, mesh.totvert}, new_to_old_verts_map); - } - if (int *orig_indices = static_cast(CustomData_get_layer(&mesh.vdata, CD_ORIGINDEX))) { - copy_to_new_verts({orig_indices, mesh.totvert}, new_to_old_verts_map); - } -} - -static void add_new_edges(Mesh &mesh, - const Span new_edges, - const Span new_to_old_edges_map) -{ - MutableAttributeAccessor attributes = mesh.attributes_for_write(); - - /* Store a copy of the IDs locally since we will remove the existing attributes which - * can also free the names, since the API does not provide pointer stability. */ - Vector named_ids; - Vector anonymous_ids; - for (const AttributeIDRef &id : attributes.all_ids()) { - if (attributes.lookup_meta_data(id)->domain != ATTR_DOMAIN_EDGE) { - continue; - } - if (!id.should_be_kept()) { - continue; - } - if (id.is_named()) { - named_ids.append(id.name()); - } - else { - anonymous_ids.append(WeakAnonymousAttributeID(&id.anonymous_id())); - } - } - Vector local_edge_ids; - for (const StringRef name : named_ids) { - local_edge_ids.append(name); - } - for (const WeakAnonymousAttributeID &id : anonymous_ids) { - local_edge_ids.append(id.get()); - } - - /* Build new arrays for the copied edge attributes. Unlike vertices, new edges aren't all at the - * end of the array, so just copying to the new edges would overwrite old values when they were - * still needed. */ - struct NewAttributeData { - const AttributeIDRef &local_id; - const CPPType &type; - void *array; - }; - Vector dst_attributes; - for (const AttributeIDRef &id : local_edge_ids) { - GAttributeReader attribute = attributes.lookup(id); - if (!attribute) { - continue; - } - - const CPPType &type = attribute.varray.type(); - void *new_data = MEM_malloc_arrayN(new_edges.size(), type.size(), __func__); - - attribute_math::convert_to_static_type(type, [&](auto dummy) { - using T = decltype(dummy); - const VArray src = attribute.varray.typed(); - MutableSpan dst(static_cast(new_data), new_edges.size()); - array_utils::gather(src, new_to_old_edges_map, dst); - }); - - /* Free the original attribute as soon as possible to lower peak memory usage. */ - attributes.remove(id); - dst_attributes.append({id, type, new_data}); - } - - int *new_orig_indices = nullptr; - if (const int *orig_indices = static_cast( - CustomData_get_layer(&mesh.edata, CD_ORIGINDEX))) { - new_orig_indices = static_cast( - MEM_malloc_arrayN(new_edges.size(), sizeof(int), __func__)); - array_utils::gather(Span(orig_indices, mesh.totedge), - new_to_old_edges_map, - {new_orig_indices, new_edges.size()}); - } - - CustomData_free(&mesh.edata, mesh.totedge); - mesh.totedge = new_edges.size(); - CustomData_add_layer(&mesh.edata, CD_MEDGE, CD_CONSTRUCT, nullptr, mesh.totedge); - mesh.edges_for_write().copy_from(new_edges); - - if (new_orig_indices != nullptr) { - CustomData_add_layer(&mesh.edata, CD_ORIGINDEX, CD_ASSIGN, new_orig_indices, mesh.totedge); - } - - for (NewAttributeData &new_data : dst_attributes) { - attributes.add(new_data.local_id, - ATTR_DOMAIN_EDGE, - bke::cpp_type_to_custom_data_type(new_data.type), - bke::AttributeInitMoveArray(new_data.array)); - } -} - -/** - * Merge the new_edge into the original edge. - * - * NOTE: This function is very specific to the situation and makes a lot of assumptions. - */ -static void merge_edges(const int orig_edge_i, - const int new_edge_i, - MutableSpan new_loops, - Vector> &edge_to_loop_map, - Vector &new_edges, - Vector &new_to_old_edges_map) -{ - /* Merge back into the original edge by undoing the topology changes. */ - BLI_assert(edge_to_loop_map[new_edge_i].size() == 1); - const int loop_i = edge_to_loop_map[new_edge_i][0]; - new_loops[loop_i].e = orig_edge_i; - - /* We are putting the last edge in the location of new_edge in all the maps, to remove - * new_edge efficiently. We have to update the topology information for this last edge - * though. Essentially we are replacing every instance of last_edge_i with new_edge_i. */ - const int last_edge_i = new_edges.size() - 1; - if (last_edge_i != new_edge_i) { - BLI_assert(edge_to_loop_map[last_edge_i].size() == 1); - const int last_edge_loop_i = edge_to_loop_map[last_edge_i][0]; - new_loops[last_edge_loop_i].e = new_edge_i; - } - - /* We can now safely swap-remove. */ - new_edges.remove_and_reorder(new_edge_i); - edge_to_loop_map.remove_and_reorder(new_edge_i); - new_to_old_edges_map.remove_and_reorder(new_edge_i); -} - -/** - * Replace the vertex of an edge with a new one, and update the connected loops. - * - * NOTE: This only updates the loops containing the edge and the old vertex. It should therefore - * also be called on the adjacent edge. - */ -static void swap_vertex_of_edge(MEdge &edge, - const int old_vert, - const int new_vert, - MutableSpan loops, - const Span connected_loops) -{ - if (edge.v1 == old_vert) { - edge.v1 = new_vert; - } - else if (edge.v2 == old_vert) { - edge.v2 = new_vert; - } - else { - BLI_assert_unreachable(); - } - - for (const int loop_i : connected_loops) { - if (loops[loop_i].v == old_vert) { - loops[loop_i].v = new_vert; - } - /* The old vertex is on the loop containing the adjacent edge. Since this function is also - * called on the adjacent edge, we don't replace it here. */ - } -} - -/** Split the vertex into duplicates so that each fan has a different vertex. */ -static void split_vertex_per_fan(const int vertex, - const int start_offset, - const int orig_verts_num, - const Span fans, - const Span fan_sizes, - const Span> edge_to_loop_map, - MutableSpan new_edges, - MutableSpan new_loops, - MutableSpan new_to_old_verts_map) -{ - int fan_start = 0; - /* We don't need to create a new vertex for the last fan. That fan can just be connected to the - * original vertex. */ - for (const int i : fan_sizes.index_range().drop_back(1)) { - const int new_vert_i = start_offset + i; - new_to_old_verts_map[new_vert_i - orig_verts_num] = vertex; - - for (const int edge_i : fans.slice(fan_start, fan_sizes[i])) { - swap_vertex_of_edge( - new_edges[edge_i], vertex, new_vert_i, new_loops, edge_to_loop_map[edge_i]); - } - fan_start += fan_sizes[i]; - } -} - -/** - * Get the index of the adjacent edge to a loop connected to a vertex. In other words, for the - * given polygon return the unique edge connected to the given vertex and not on the given loop. - */ -static int adjacent_edge(Span loops, const int loop_i, const MPoly &poly, const int vertex) -{ - const int adjacent_loop_i = (loops[loop_i].v == vertex) ? - bke::mesh_topology::poly_loop_prev(poly, loop_i) : - bke::mesh_topology::poly_loop_next(poly, loop_i); - return loops[adjacent_loop_i].e; -} - -/** - * Calculate the disjoint fans connected to the vertex, where a fan is a group of edges connected - * through polygons. The connected_edges vector is rearranged in such a way that edges in the same - * fan are grouped together. The r_fans_sizes Vector gives the sizes of the different fans, and can - * be used to retrieve the fans from connected_edges. - */ -static void calc_vertex_fans(const int vertex, - const Span new_loops, - const Span polys, - const Span> edge_to_loop_map, - const Span loop_to_poly_map, - MutableSpan connected_edges, - Vector &r_fan_sizes) -{ - if (connected_edges.size() <= 1) { - r_fan_sizes.append(connected_edges.size()); - return; - } - - Vector search_edges; - int total_found_edges_num = 0; - int fan_size = 0; - const int total_edge_num = connected_edges.size(); - /* Iteratively go through the connected edges. The front contains already handled edges, while - * the back contains unhandled edges. */ - while (true) { - /* This edge has not been visited yet. */ - int curr_i = total_found_edges_num; - int curr_edge_i = connected_edges[curr_i]; - - /* Gather all the edges in this fan. */ - while (true) { - fan_size++; - - /* Add adjacent edges to search stack. */ - for (const int loop_i : edge_to_loop_map[curr_edge_i]) { - const int adjacent_edge_i = adjacent_edge( - new_loops, loop_i, polys[loop_to_poly_map[loop_i]], vertex); - - /* Find out if this edge was visited already. */ - int i = curr_i + 1; - for (; i < total_edge_num; i++) { - if (connected_edges[i] == adjacent_edge_i) { - break; - } - } - if (i == total_edge_num) { - /* Already visited this edge. */ - continue; - } - search_edges.append(adjacent_edge_i); - curr_i++; - std::swap(connected_edges[curr_i], connected_edges[i]); - } - - if (search_edges.is_empty()) { - break; - } - - curr_edge_i = search_edges.pop_last(); - } - /* We have now collected all the edges in this fan. */ - total_found_edges_num += fan_size; - BLI_assert(total_found_edges_num <= total_edge_num); - r_fan_sizes.append(fan_size); - if (total_found_edges_num == total_edge_num) { - /* We have found all the edges, so this final batch must be the last connected fan. */ - break; - } - fan_size = 0; - } -} - -/** - * Splits the edge into duplicates, so that each edge is connected to one poly. - */ -static void split_edge_per_poly(const int edge_i, - const int new_edge_start, - MutableSpan> edge_to_loop_map, - MutableSpan new_loops, - MutableSpan new_edges, - MutableSpan new_to_old_edges_map) -{ - if (edge_to_loop_map[edge_i].size() <= 1) { - return; - } - int new_edge_index = new_edge_start; - for (const int loop_i : edge_to_loop_map[edge_i].as_span().drop_front(1)) { - const MEdge new_edge(new_edges[edge_i]); - new_edges[new_edge_index] = new_edge; - new_to_old_edges_map[new_edge_index] = edge_i; - edge_to_loop_map[new_edge_index].append({loop_i}); - new_loops[loop_i].e = new_edge_index; - new_edge_index++; - } - /* Only the first loop is now connected to this edge. */ - edge_to_loop_map[edge_i].resize(1); -} - -static void mesh_edge_split(Mesh &mesh, const IndexMask mask) -{ - /* Flag vertices that need to be split. */ - Array should_split_vert(mesh.totvert, false); - const Span edges = mesh.edges(); - for (const int edge_i : mask) { - const MEdge edge = edges[edge_i]; - should_split_vert[edge.v1] = true; - should_split_vert[edge.v2] = true; - } - - /* Precalculate topology info. */ - Array> vert_to_edge_map = bke::mesh_topology::build_vert_to_edge_map(edges, - mesh.totvert); - Vector> edge_to_loop_map = bke::mesh_topology::build_edge_to_loop_map_resizable( - mesh.loops(), mesh.totedge); - Array loop_to_poly_map = bke::mesh_topology::build_loop_to_poly_map(mesh.polys(), - mesh.totloop); - - /* Store offsets, so we can split edges in parallel. */ - Array edge_offsets(edges.size()); - Array num_edge_duplicates(edges.size()); - int new_edges_size = edges.size(); - for (const int edge : mask) { - edge_offsets[edge] = new_edges_size; - /* We add duplicates of the edge for each poly (except the first). */ - const int num_connected_loops = edge_to_loop_map[edge].size(); - const int num_duplicates = std::max(0, num_connected_loops - 1); - new_edges_size += num_duplicates; - num_edge_duplicates[edge] = num_duplicates; - } - - const Span polys = mesh.polys(); - - MutableSpan loops = mesh.loops_for_write(); - Vector new_edges(new_edges_size); - new_edges.as_mutable_span().take_front(edges.size()).copy_from(edges); - - edge_to_loop_map.resize(new_edges_size); - - /* Used for transferring attributes. */ - Vector new_to_old_edges_map(IndexRange(new_edges.size()).as_span()); - - /* Step 1: Split the edges. */ - threading::parallel_for(mask.index_range(), 512, [&](IndexRange range) { - for (const int mask_i : range) { - const int edge_i = mask[mask_i]; - split_edge_per_poly( - edge_i, edge_offsets[edge_i], edge_to_loop_map, loops, new_edges, new_to_old_edges_map); - } - }); - - /* Step 1.5: Update topology information (can't parallelize). */ - for (const int edge_i : mask) { - const MEdge &edge = edges[edge_i]; - for (const int duplicate_i : IndexRange(edge_offsets[edge_i], num_edge_duplicates[edge_i])) { - vert_to_edge_map[edge.v1].append(duplicate_i); - vert_to_edge_map[edge.v2].append(duplicate_i); - } - } - - /* Step 2: Calculate vertex fans. */ - Array> vertex_fan_sizes(mesh.totvert); - threading::parallel_for(IndexRange(mesh.totvert), 512, [&](IndexRange range) { - for (const int vert : range) { - if (!should_split_vert[vert]) { - continue; - } - calc_vertex_fans(vert, - loops, - polys, - edge_to_loop_map, - loop_to_poly_map, - vert_to_edge_map[vert], - vertex_fan_sizes[vert]); - } - }); - - /* Step 2.5: Calculate offsets for next step. */ - Array vert_offsets(mesh.totvert); - int total_verts_num = mesh.totvert; - for (const int vert : IndexRange(mesh.totvert)) { - if (!should_split_vert[vert]) { - continue; - } - vert_offsets[vert] = total_verts_num; - /* We only create a new vertex for each fan different from the first. */ - total_verts_num += vertex_fan_sizes[vert].size() - 1; - } - - /* Step 3: Split the vertices. - * Build a map from each new vertex to an old vertex to use for transferring attributes later. */ - const int new_verts_num = total_verts_num - mesh.totvert; - Array new_to_old_verts_map(new_verts_num); - threading::parallel_for(IndexRange(mesh.totvert), 512, [&](IndexRange range) { - for (const int vert : range) { - if (!should_split_vert[vert]) { - continue; - } - split_vertex_per_fan(vert, - vert_offsets[vert], - mesh.totvert, - vert_to_edge_map[vert], - vertex_fan_sizes[vert], - edge_to_loop_map, - new_edges, - loops, - new_to_old_verts_map); - } - }); - - /* Step 4: Deduplicate edges. We loop backwards so we can use remove_and_reorder. Although this - * does look bad (3 nested loops), in practice the inner loops are very small. For most meshes, - * there are at most 2 polygons connected to each edge, and hence you'll only get at most 1 - * duplicate per edge. */ - for (int mask_i = mask.size() - 1; mask_i >= 0; mask_i--) { - const int edge = mask[mask_i]; - int start_of_duplicates = edge_offsets[edge]; - int end_of_duplicates = start_of_duplicates + num_edge_duplicates[edge] - 1; - for (int duplicate = end_of_duplicates; duplicate >= start_of_duplicates; duplicate--) { - if (naive_edges_equal(new_edges[edge], new_edges[duplicate])) { - merge_edges(edge, duplicate, loops, edge_to_loop_map, new_edges, new_to_old_edges_map); - break; - } - for (int other = start_of_duplicates; other < duplicate; other++) { - if (naive_edges_equal(new_edges[other], new_edges[duplicate])) { - merge_edges(other, duplicate, loops, edge_to_loop_map, new_edges, new_to_old_edges_map); - break; - } - } - } - } - - /* Step 5: Resize the mesh to add the new vertices and rebuild the edges. */ - add_new_vertices(mesh, new_to_old_verts_map); - add_new_edges(mesh, new_edges, new_to_old_edges_map); - - BKE_mesh_tag_edges_split(&mesh); -} - static void node_geo_exec(GeoNodeExecParams params) { GeometrySet geometry_set = params.extract_input("Mesh"); @@ -513,7 +33,7 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - mesh_edge_split(*geometry_set.get_mesh_for_write(), mask); + geometry::split_edges(*geometry_set.get_mesh_for_write(), mask); } }); From b1b5b48d5341a0b3a7d650ab0b2b27e05e1a2e50 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Dec 2022 12:25:35 +1100 Subject: [PATCH 0074/1522] Cleanup: quiet format warning --- source/blender/draw/intern/draw_pbvh.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index c3d660b8ecd..bc9c449544c 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -900,7 +900,7 @@ struct PBVHBatches { break; } default: - printf("%s: Unsupported attribute type %d\n", __func__, type); + printf("%s: Unsupported attribute type %u\n", __func__, type); BLI_assert_unreachable(); return; From 76aba51a219560a8796bae171f1e31ebccf072e4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 9 Dec 2022 12:55:38 +1100 Subject: [PATCH 0075/1522] Build: update centos7 script to run on rocky8 --- ...centos7-setup.sh => linux-rocky8-setup.sh} | 76 ++++++++----------- 1 file changed, 32 insertions(+), 44 deletions(-) rename build_files/build_environment/linux/{linux-centos7-setup.sh => linux-rocky8-setup.sh} (64%) diff --git a/build_files/build_environment/linux/linux-centos7-setup.sh b/build_files/build_environment/linux/linux-rocky8-setup.sh similarity index 64% rename from build_files/build_environment/linux/linux-centos7-setup.sh rename to build_files/build_environment/linux/linux-rocky8-setup.sh index e664f530edb..a1696ad5ccc 100644 --- a/build_files/build_environment/linux/linux-centos7-setup.sh +++ b/build_files/build_environment/linux/linux-rocky8-setup.sh @@ -11,19 +11,25 @@ if [ `id -u` -ne 0 ]; then exit 1 fi +# Packages `ninja-build` and `meson` are not available unless CBR or PowerTools repositories are enabled. +# See: https://wiki.rockylinux.org/rocky/repo/#notes-on-unlisted-repositories +dnf config-manager --set-enabled powertools + # yum-config-manager does not come in the default minimal install, # so make sure it is installed and available. yum -y update yum -y install yum-utils -# Install all the packages needed for a new toolchain. +# Install all the packages needed for a new tool-chain. # # NOTE: Keep this separate from the packages install, since otherwise -# older toolchain will be installed. +# older tool-chain will be installed. yum -y update -yum -y install epel-release -yum -y install centos-release-scl -yum -y install devtoolset-9 +yum -y install scl-utils +yum -y install scl-utils-build + +# Currently this is defined by the VFX platform (CY2023), see: https://vfxplatform.com +yum -y install gcc-toolset-11 # Install packages needed for Blender's dependencies. PACKAGES_FOR_LIBS=( @@ -47,19 +53,12 @@ PACKAGES_FOR_LIBS=( automake libtool - # Meta-build system used by various packages. - meson + # TODO: why is this needed? + patchelf + # Builds generated by meson use Ninja for the actual build. ninja-build - # Required by Blender build option: `WITH_GHOST_X11`. - libXrandr-devel - libXinerama-devel - libXcursor-devel - libXi-devel - libX11-devel - libXt-devel - # Required by Blender build option: `WITH_GHOST_WAYLAND`. mesa-libEGL-devel # Required by: Blender & `external_opensubdiv` (probably others). @@ -79,16 +78,18 @@ PACKAGES_FOR_LIBS=( # Why are both needed? yasm - # Required by: `meson` (Python based build system). - python36 - # Required by: `mako` (Python module used for building `external_mesa`) - python-setuptools + # NOTE(@campbellbarton): while `python39` is available, the default Python version is 3.6. + # This is used for the `python3-mako` package for e.g. + # So use the "default" system Python since it means it's most compatible with other packages. + + # Required by: `mesa`. + expat-devel # Required by: `external_igc` & `external_osl` as a build-time dependency. bison # Required by: `external_osl` as a build-time dependency. flex - # TODO: dependencies build without this, consider removal. + # Required by: `external_ispc`. ncurses-devel ) @@ -96,35 +97,22 @@ PACKAGES_FOR_LIBS=( PACKAGES_FOR_BLENDER=( # Required by Blender build option: `WITH_GHOST_WAYLAND`. libxkbcommon-devel + + # Required by Blender build option: `WITH_GHOST_X11`. + libX11-devel + libXcursor-devel + libXi-devel + libXinerama-devel + libXrandr-devel + libXt-devel + libXxf86vm-devel ) yum -y install -y ${PACKAGES_FOR_LIBS[@]} ${PACKAGES_FOR_BLENDER[@]} -# Dependencies for Mesa -yum -y install expat-devel -python3 -m pip install mako - -# Dependencies for pip (needed for buildbot-worker). -yum -y install python36-pip python36-devel +# Dependencies for pip (needed for buildbot-worker), uses Python3.6. +yum -y install python3 python3-pip python3-devel # Dependencies for asound. yum -y install -y \ alsa-lib-devel pulseaudio-libs-devel - -alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake 10 \ - --slave /usr/local/bin/ctest ctest /usr/bin/ctest \ - --slave /usr/local/bin/cpack cpack /usr/bin/cpack \ - --slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake \ - --family cmake - -alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 20 \ - --slave /usr/local/bin/ctest ctest /usr/bin/ctest3 \ - --slave /usr/local/bin/cpack cpack /usr/bin/cpack3 \ - --slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake3 \ - --family cmake - -alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 20 \ - --slave /usr/local/bin/ctest ctest /usr/bin/ctest3 \ - --slave /usr/local/bin/cpack cpack /usr/bin/cpack3 \ - --slave /usr/local/bin/ccmake ccmake /usr/bin/ccmake3 \ - --family cmake From 93a629f14781a920a785c08555e04fbea47b5ac0 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Tue, 13 Dec 2022 18:30:20 -0800 Subject: [PATCH 0076/1522] Fix T103119: Allow Win32 Diacritical Composition Allow keyboard layouts which include "dead keys" to enter diacritics by calling MapVirtualKeyW even when not key_down. See D16770 for more details. Differential Revision: https://developer.blender.org/D16770 Reviewed by Campbell Barton --- intern/ghost/intern/GHOST_SystemWin32.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 7aef23b39b6..75a4cc8389a 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -1210,16 +1210,16 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA const bool ctrl_pressed = has_state && state[VK_CONTROL] & 0x80; const bool alt_pressed = has_state && state[VK_MENU] & 0x80; - if (!key_down) { - /* Pass. */ - } + /* We can be here with !key_down if processing dead keys (diacritics). See T103119. */ + /* No text with control key pressed (Alt can be used to insert special characters though!). */ - else if (ctrl_pressed && !alt_pressed) { + if (ctrl_pressed && !alt_pressed) { /* Pass. */ } /* Don't call #ToUnicodeEx on dead keys as it clears the buffer and so won't allow diacritical - * composition. */ - else if (MapVirtualKeyW(vk, 2) != 0) { + * composition. XXX: we are not checking return of MapVirtualKeyW for high bit set, which is + * what is supposed to indicate dead keys. But this is working now so approach cautiously. */ + else if (MapVirtualKeyW(vk, MAPVK_VK_TO_CHAR) != 0) { wchar_t utf16[3] = {0}; int r; /* TODO: #ToUnicodeEx can respond with up to 4 utf16 chars (only 2 here). @@ -1234,6 +1234,10 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA utf8_char[0] = '\0'; } } + if (!key_down) { + /* Clear or wm_event_add_ghostevent will warn of unexpected data on key up. */ + utf8_char[0] = '\0'; + } } #ifdef WITH_INPUT_IME From 4710582f8f37137fb1334c9f4b99ade1bb9f089a Mon Sep 17 00:00:00 2001 From: Ian Karanja Date: Tue, 13 Dec 2022 21:51:20 -0500 Subject: [PATCH 0077/1522] UI: Fix typo in 'CONSTRAINT_SPACE_PARLOCAL' description Differential Revision: https://developer.blender.org/D16690 --- source/blender/makesrna/intern/rna_object_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 3d4d72cefaf..9c62fd241e0 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -40,7 +40,7 @@ static const EnumPropertyItem space_items[] = { "LOCAL_WITH_PARENT", 0, "Local With Parent", - "The rest pose local space of a bone (thus matrix includes parent transforms)"}, + "The rest pose local space of a bone (this matrix includes parent transforms)"}, {CONSTRAINT_SPACE_LOCAL, "LOCAL", 0, "Local Space", "The local space of an object/bone"}, {0, NULL, 0, NULL, NULL}, }; From 5025a3833abcdf35530dba30786afc10d1e814dd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Dec 2022 14:12:05 +1100 Subject: [PATCH 0078/1522] CMake: fix build error on Linux where MAN page generation failed Move man-page generation to an install step to ensure the shared libraries have been copied before running Blender. --- source/creator/CMakeLists.txt | 62 ++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 82a37614841..3ecea7c5929 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -562,19 +562,6 @@ endmacro() if(UNIX AND NOT APPLE) - if(NOT WITH_PYTHON_MODULE) - if(WITH_DOC_MANPAGE) - add_custom_target( - blender_man_page ALL - COMMAND - ${CMAKE_SOURCE_DIR}/doc/manpage/blender.1.py - --blender ${EXECUTABLE_OUTPUT_PATH}/blender - --output ${CMAKE_CURRENT_BINARY_DIR}/blender.1 - ) - add_dependencies(blender_man_page blender) - endif() - endif() - if(PLATFORM_BUNDLED_LIBRARIES AND TARGETDIR_LIB) install( FILES ${PLATFORM_BUNDLED_LIBRARIES} @@ -603,12 +590,6 @@ if(UNIX AND NOT APPLE) DESTINATION "." ) - if(WITH_DOC_MANPAGE) - install( - FILES ${CMAKE_CURRENT_BINARY_DIR}/blender.1 - DESTINATION "." - ) - endif() install( FILES ${CMAKE_SOURCE_DIR}/release/freedesktop/blender.desktop @@ -655,13 +636,6 @@ if(UNIX AND NOT APPLE) TARGETS blender DESTINATION bin ) - if(WITH_DOC_MANPAGE) - # Manual page (only with `blender` binary). - install( - FILES ${CMAKE_CURRENT_BINARY_DIR}/blender.1 - DESTINATION share/man/man1 - ) - endif() # Misc files. install( @@ -1677,6 +1651,42 @@ if(WIN32) windows_generate_shared_manifest() endif() +# ----------------------------------------------------------------------------- +# Steps that Run Blender +# +# As executing Blender is needed - it's important this operation runs after the shared +# libraries have been installed to their destination. + +if(UNIX AND NOT APPLE) + if(NOT WITH_PYTHON_MODULE) + if(WITH_DOC_MANPAGE) + install( + CODE "\ +execute_process(\ + COMMAND \ + \"${CMAKE_SOURCE_DIR}/doc/manpage/blender.1.py\" \ + --blender \"${EXECUTABLE_OUTPUT_PATH}/blender\" \ + --output \"${CMAKE_CURRENT_BINARY_DIR}/blender.1\"\ +)" + DEPENDS blender + ) + + if(WITH_INSTALL_PORTABLE) + install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/blender.1 + DESTINATION "." + ) + else() + # Manual page (only with `blender` binary). + install( + FILES ${CMAKE_CURRENT_BINARY_DIR}/blender.1 + DESTINATION share/man/man1 + ) + endif() + endif() + endif() +endif() + # ----------------------------------------------------------------------------- # Post-install script From 1324db0ad154f1006c772bd1bbed173cfe80bb5d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Dec 2022 14:21:51 +1100 Subject: [PATCH 0079/1522] Cleanup: cmake indentation --- .../build_environment/cmake/cve_check.cmake | 14 ++--- .../build_environment/cmake/download.cmake | 13 ++-- .../build_environment/cmake/freetype.cmake | 7 ++- build_files/build_environment/cmake/gmp.cmake | 18 +++--- .../build_environment/cmake/harvest.cmake | 16 ++--- .../build_environment/cmake/ispc.cmake | 30 +++++----- .../build_environment/cmake/opencolorio.cmake | 12 ++-- .../build_environment/cmake/openjpeg.cmake | 6 +- .../build_environment/cmake/openpgl.cmake | 24 ++++---- .../build_environment/cmake/potrace.cmake | 4 +- .../build_environment/cmake/pthreads.cmake | 59 +++++++++---------- .../build_environment/cmake/sndfile.cmake | 8 +-- .../build_environment/cmake/yamlcpp.cmake | 3 +- 13 files changed, 110 insertions(+), 104 deletions(-) diff --git a/build_files/build_environment/cmake/cve_check.cmake b/build_files/build_environment/cmake/cve_check.cmake index ac42444aef1..941b6b0cae9 100644 --- a/build_files/build_environment/cmake/cve_check.cmake +++ b/build_files/build_environment/cmake/cve_check.cmake @@ -26,13 +26,13 @@ set(SBOMCONTENTS) get_cmake_property(_variableNames VARIABLES) foreach (_variableName ${_variableNames}) if(_variableName MATCHES "CPE$") - string(REPLACE ":" ";" CPE_LIST ${${_variableName}}) - string(REPLACE "_CPE" "_ID" CPE_DEPNAME ${_variableName}) - list(GET CPE_LIST 3 CPE_VENDOR) - list(GET CPE_LIST 4 CPE_NAME) - list(GET CPE_LIST 5 CPE_VERSION) - set(${CPE_DEPNAME} "${CPE_VENDOR},${CPE_NAME},${CPE_VERSION}") - set(SBOMCONTENTS "${SBOMCONTENTS}${CPE_VENDOR},${CPE_NAME},${CPE_VERSION},,,\n") + string(REPLACE ":" ";" CPE_LIST ${${_variableName}}) + string(REPLACE "_CPE" "_ID" CPE_DEPNAME ${_variableName}) + list(GET CPE_LIST 3 CPE_VENDOR) + list(GET CPE_LIST 4 CPE_NAME) + list(GET CPE_LIST 5 CPE_VERSION) + set(${CPE_DEPNAME} "${CPE_VENDOR},${CPE_NAME},${CPE_VERSION}") + set(SBOMCONTENTS "${SBOMCONTENTS}${CPE_VENDOR},${CPE_NAME},${CPE_VERSION},,,\n") endif() endforeach() configure_file(${CMAKE_SOURCE_DIR}/cmake/cve_check.csv.in ${CMAKE_CURRENT_BINARY_DIR}/cve_check.csv @ONLY) diff --git a/build_files/build_environment/cmake/download.cmake b/build_files/build_environment/cmake/download.cmake index a6fa82bceed..4f8ecc7d0ce 100644 --- a/build_files/build_environment/cmake/download.cmake +++ b/build_files/build_environment/cmake/download.cmake @@ -32,12 +32,13 @@ function(download_source dep) message("Checking source : ${dep} (${TARGET_FILE})") if(NOT EXISTS ${TARGET_FILE}) message("Checking source : ${dep} - source not found downloading from ${TARGET_URI}") - file(DOWNLOAD ${TARGET_URI} ${TARGET_FILE} - TIMEOUT 1800 # seconds - EXPECTED_HASH ${TARGET_HASH_TYPE}=${TARGET_HASH} - TLS_VERIFY ON - SHOW_PROGRESS - ) + file( + DOWNLOAD ${TARGET_URI} ${TARGET_FILE} + TIMEOUT 1800 # seconds + EXPECTED_HASH ${TARGET_HASH_TYPE}=${TARGET_HASH} + TLS_VERIFY ON + SHOW_PROGRESS + ) endif() if(EXISTS ${TARGET_FILE}) # Sometimes the download fails, but that is not a diff --git a/build_files/build_environment/cmake/freetype.cmake b/build_files/build_environment/cmake/freetype.cmake index c0cb3c3401b..27aace7a115 100644 --- a/build_files/build_environment/cmake/freetype.cmake +++ b/build_files/build_environment/cmake/freetype.cmake @@ -32,9 +32,10 @@ add_dependencies( if(BUILD_MODE STREQUAL Release AND WIN32) ExternalProject_Add_Step(external_freetype after_install COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freetype ${HARVEST_TARGET}/freetype - # harfbuzz *NEEDS* to find freetype.lib and will not be conviced to take alternative names so just give it - # what it wants. - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/freetype/lib/freetype2st.lib ${LIBDIR}/freetype/lib/freetype.lib + # harfbuzz *NEEDS* to find freetype.lib and will not be conviced to take alternative names so just give it + # what it wants. + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/freetype/lib/freetype2st.lib ${LIBDIR}/freetype/lib/freetype.lib + DEPENDEES install ) endif() diff --git a/build_files/build_environment/cmake/gmp.cmake b/build_files/build_environment/cmake/gmp.cmake index ddfdba6662d..df4d20fb934 100644 --- a/build_files/build_environment/cmake/gmp.cmake +++ b/build_files/build_environment/cmake/gmp.cmake @@ -40,19 +40,21 @@ endif() if(BUILD_MODE STREQUAL Release AND WIN32) ExternalProject_Add_Step(external_gmp after_install - COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def - COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/gmp/bin/libgmp-10.dll ${HARVEST_TARGET}/gmp/lib/libgmp-10.dll - COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib ${HARVEST_TARGET}/gmp/lib/libgmp-10.lib - COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/gmp/include ${HARVEST_TARGET}/gmp/include + COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def + COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/gmp/bin/libgmp-10.dll ${HARVEST_TARGET}/gmp/lib/libgmp-10.dll + COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib ${HARVEST_TARGET}/gmp/lib/libgmp-10.lib + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/gmp/include ${HARVEST_TARGET}/gmp/include + DEPENDEES install ) endif() if(BUILD_MODE STREQUAL Debug AND WIN32) -ExternalProject_Add_Step(external_gmp after_install - COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def - COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib + ExternalProject_Add_Step(external_gmp after_install + COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def + COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib + DEPENDEES install ) endif() diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index 2660d55d899..60d633c0ca9 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -14,14 +14,14 @@ if(WIN32) if(BUILD_MODE STREQUAL Release) add_custom_target(Harvest_Release_Results COMMAND # jpeg rename libfile + copy include - ${CMAKE_COMMAND} -E copy ${LIBDIR}/jpeg/lib/jpeg-static.lib ${HARVEST_TARGET}/jpeg/lib/libjpeg.lib && - ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/jpeg/include/ ${HARVEST_TARGET}/jpeg/include/ && - # png - ${CMAKE_COMMAND} -E copy ${LIBDIR}/png/lib/libpng16_static.lib ${HARVEST_TARGET}/png/lib/libpng.lib && - ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/png/include/ ${HARVEST_TARGET}/png/include/ && - # freeglut-> opengl - ${CMAKE_COMMAND} -E copy ${LIBDIR}/freeglut/lib/freeglut_static.lib ${HARVEST_TARGET}/opengl/lib/freeglut_static.lib && - ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freeglut/include/ ${HARVEST_TARGET}/opengl/include/ && + ${CMAKE_COMMAND} -E copy ${LIBDIR}/jpeg/lib/jpeg-static.lib ${HARVEST_TARGET}/jpeg/lib/libjpeg.lib && + ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/jpeg/include/ ${HARVEST_TARGET}/jpeg/include/ && + # png + ${CMAKE_COMMAND} -E copy ${LIBDIR}/png/lib/libpng16_static.lib ${HARVEST_TARGET}/png/lib/libpng.lib && + ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/png/include/ ${HARVEST_TARGET}/png/include/ && + # freeglut-> opengl + ${CMAKE_COMMAND} -E copy ${LIBDIR}/freeglut/lib/freeglut_static.lib ${HARVEST_TARGET}/opengl/lib/freeglut_static.lib && + ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freeglut/include/ ${HARVEST_TARGET}/opengl/include/ && DEPENDS ) endif() diff --git a/build_files/build_environment/cmake/ispc.cmake b/build_files/build_environment/cmake/ispc.cmake index c2dbedca55f..c6c41616b84 100644 --- a/build_files/build_environment/cmake/ispc.cmake +++ b/build_files/build_environment/cmake/ispc.cmake @@ -34,21 +34,21 @@ elseif(UNIX) endif() set(ISPC_EXTRA_ARGS - -DISPC_NO_DUMPS=On - -DISPC_INCLUDE_EXAMPLES=Off - -DISPC_INCLUDE_TESTS=Off - -DLLVM_ROOT=${LIBDIR}/llvm/lib/cmake/llvm - -DLLVM_LIBRARY_DIR=${LIBDIR}/llvm/lib - -DCLANG_EXECUTABLE=${LIBDIR}/llvm/bin/clang - -DCLANGPP_EXECUTABLE=${LIBDIR}/llvm/bin/clang++ - -DISPC_INCLUDE_TESTS=Off - -DCLANG_LIBRARY_DIR=${LIBDIR}/llvm/lib - -DCLANG_INCLUDE_DIRS=${LIBDIR}/llvm/include - -DPython3_ROOT_DIR=${LIBDIR}/python/ - -DPython3_EXECUTABLE=${PYTHON_BINARY} - ${ISPC_EXTRA_ARGS_WIN} - ${ISPC_EXTRA_ARGS_APPLE} - ${ISPC_EXTRA_ARGS_UNIX} + -DISPC_NO_DUMPS=On + -DISPC_INCLUDE_EXAMPLES=Off + -DISPC_INCLUDE_TESTS=Off + -DLLVM_ROOT=${LIBDIR}/llvm/lib/cmake/llvm + -DLLVM_LIBRARY_DIR=${LIBDIR}/llvm/lib + -DCLANG_EXECUTABLE=${LIBDIR}/llvm/bin/clang + -DCLANGPP_EXECUTABLE=${LIBDIR}/llvm/bin/clang++ + -DISPC_INCLUDE_TESTS=Off + -DCLANG_LIBRARY_DIR=${LIBDIR}/llvm/lib + -DCLANG_INCLUDE_DIRS=${LIBDIR}/llvm/include + -DPython3_ROOT_DIR=${LIBDIR}/python/ + -DPython3_EXECUTABLE=${PYTHON_BINARY} + ${ISPC_EXTRA_ARGS_WIN} + ${ISPC_EXTRA_ARGS_APPLE} + ${ISPC_EXTRA_ARGS_UNIX} ) ExternalProject_Add(external_ispc diff --git a/build_files/build_environment/cmake/opencolorio.cmake b/build_files/build_environment/cmake/opencolorio.cmake index 17336c73ddb..20683f718ac 100644 --- a/build_files/build_environment/cmake/opencolorio.cmake +++ b/build_files/build_environment/cmake/opencolorio.cmake @@ -105,10 +105,10 @@ if(WIN32) ) endif() else() - ExternalProject_Add_Step(external_opencolorio after_install - COMMAND cp ${LIBDIR}/yamlcpp/lib/libyaml-cpp.a ${LIBDIR}/opencolorio/lib/ - COMMAND cp ${LIBDIR}/expat/lib/libexpat.a ${LIBDIR}/opencolorio/lib/ - COMMAND cp ${LIBDIR}/pystring/lib/libpystring.a ${LIBDIR}/opencolorio/lib/ - DEPENDEES install - ) + ExternalProject_Add_Step(external_opencolorio after_install + COMMAND cp ${LIBDIR}/yamlcpp/lib/libyaml-cpp.a ${LIBDIR}/opencolorio/lib/ + COMMAND cp ${LIBDIR}/expat/lib/libexpat.a ${LIBDIR}/opencolorio/lib/ + COMMAND cp ${LIBDIR}/pystring/lib/libpystring.a ${LIBDIR}/opencolorio/lib/ + DEPENDEES install + ) endif() diff --git a/build_files/build_environment/cmake/openjpeg.cmake b/build_files/build_environment/cmake/openjpeg.cmake index ac35b5a6cc3..fc84e563375 100644 --- a/build_files/build_environment/cmake/openjpeg.cmake +++ b/build_files/build_environment/cmake/openjpeg.cmake @@ -39,8 +39,10 @@ if(MSVC) ) if(BUILD_MODE STREQUAL Release) ExternalProject_Add_Step(external_openjpeg_msvc after_install - COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openjpeg_msvc/lib ${HARVEST_TARGET}/openjpeg/lib && - ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openjpeg_msvc/include ${HARVEST_TARGET}/openjpeg/include + COMMAND + ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openjpeg_msvc/lib ${HARVEST_TARGET}/openjpeg/lib && + ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openjpeg_msvc/include ${HARVEST_TARGET}/openjpeg/include + DEPENDEES install ) endif() diff --git a/build_files/build_environment/cmake/openpgl.cmake b/build_files/build_environment/cmake/openpgl.cmake index b41264ac22b..081b8871832 100644 --- a/build_files/build_environment/cmake/openpgl.cmake +++ b/build_files/build_environment/cmake/openpgl.cmake @@ -4,10 +4,10 @@ # library itself does not depend on them, so should give no problems. set(OPENPGL_EXTRA_ARGS - -DOPENPGL_BUILD_STATIC=ON - -DOPENPGL_TBB_ROOT=${LIBDIR}/tbb - -DTBB_ROOT=${LIBDIR}/tbb - -DCMAKE_DEBUG_POSTFIX=_d + -DOPENPGL_BUILD_STATIC=ON + -DOPENPGL_TBB_ROOT=${LIBDIR}/tbb + -DTBB_ROOT=${LIBDIR}/tbb + -DCMAKE_DEBUG_POSTFIX=_d ) if(TBB_STATIC_LIBRARY) @@ -18,17 +18,17 @@ if(TBB_STATIC_LIBRARY) endif() ExternalProject_Add(external_openpgl - URL file://${PACKAGE_DIR}/${OPENPGL_FILE} - DOWNLOAD_DIR ${DOWNLOAD_DIR} - URL_HASH ${OPENPGL_HASH_TYPE}=${OPENPGL_HASH} - PREFIX ${BUILD_DIR}/openpgl - CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openpgl ${DEFAULT_CMAKE_FLAGS} ${OPENPGL_EXTRA_ARGS} - INSTALL_DIR ${LIBDIR}/openpgl + URL file://${PACKAGE_DIR}/${OPENPGL_FILE} + DOWNLOAD_DIR ${DOWNLOAD_DIR} + URL_HASH ${OPENPGL_HASH_TYPE}=${OPENPGL_HASH} + PREFIX ${BUILD_DIR}/openpgl + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openpgl ${DEFAULT_CMAKE_FLAGS} ${OPENPGL_EXTRA_ARGS} + INSTALL_DIR ${LIBDIR}/openpgl ) add_dependencies( - external_openpgl - external_tbb + external_openpgl + external_tbb ) if(WIN32) diff --git a/build_files/build_environment/cmake/potrace.cmake b/build_files/build_environment/cmake/potrace.cmake index 3d32d9cb327..853594a1fbf 100644 --- a/build_files/build_environment/cmake/potrace.cmake +++ b/build_files/build_environment/cmake/potrace.cmake @@ -15,8 +15,8 @@ if((WIN32 AND BUILD_MODE STREQUAL Release) OR UNIX) ) if(WIN32) ExternalProject_Add_Step(external_potrace after_install - COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/potrace ${HARVEST_TARGET}/potrace - DEPENDEES install + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/potrace ${HARVEST_TARGET}/potrace + DEPENDEES install ) endif() endif() diff --git a/build_files/build_environment/cmake/pthreads.cmake b/build_files/build_environment/cmake/pthreads.cmake index 6eaf670d39d..59521c74c5d 100644 --- a/build_files/build_environment/cmake/pthreads.cmake +++ b/build_files/build_environment/cmake/pthreads.cmake @@ -2,37 +2,36 @@ if(WIN32) - if(MSVC14) # vs2015 has timespec - set(PTHREAD_CPPFLAGS "/I. /DHAVE_CONFIG_H /D_TIMESPEC_DEFINED ") - else() # everything before doesn't - set(PTHREAD_CPPFLAGS "/I. /DHAVE_CONFIG_H ") - endif() + if(MSVC14) # vs2015 has timespec + set(PTHREAD_CPPFLAGS "/I. /DHAVE_CONFIG_H /D_TIMESPEC_DEFINED ") + else() # everything before doesn't + set(PTHREAD_CPPFLAGS "/I. /DHAVE_CONFIG_H ") + endif() - set(PTHREADS_BUILD cd ${BUILD_DIR}/pthreads/src/external_pthreads/ && cd && nmake VC-static /e CPPFLAGS=${PTHREAD_CPPFLAGS}) + set(PTHREADS_BUILD cd ${BUILD_DIR}/pthreads/src/external_pthreads/ && cd && nmake VC-static /e CPPFLAGS=${PTHREAD_CPPFLAGS}) - ExternalProject_Add(external_pthreads - URL file://${PACKAGE_DIR}/${PTHREADS_FILE} - DOWNLOAD_DIR ${DOWNLOAD_DIR} - URL_HASH ${PTHREADS_HASH_TYPE}=${PTHREADS_HASH} - PREFIX ${BUILD_DIR}/pthreads - CONFIGURE_COMMAND echo . - PATCH_COMMAND COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/pthreads/src/external_pthreads < ${PATCH_DIR}/pthreads.diff - BUILD_COMMAND ${PTHREADS_BUILD} - INSTALL_COMMAND COMMAND - ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/libpthreadVC3${LIBEXT} ${LIBDIR}/pthreads/lib/pthreadVC3${LIBEXT} && - ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/pthread.h ${LIBDIR}/pthreads/inc/pthread.h && - ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/sched.h ${LIBDIR}/pthreads/inc/sched.h && - ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/semaphore.h ${LIBDIR}/pthreads/inc/semaphore.h && - ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/_ptw32.h ${LIBDIR}/pthreads/inc/_ptw32.h - INSTALL_DIR ${LIBDIR}/pthreads + ExternalProject_Add(external_pthreads + URL file://${PACKAGE_DIR}/${PTHREADS_FILE} + DOWNLOAD_DIR ${DOWNLOAD_DIR} + URL_HASH ${PTHREADS_HASH_TYPE}=${PTHREADS_HASH} + PREFIX ${BUILD_DIR}/pthreads + CONFIGURE_COMMAND echo . + PATCH_COMMAND COMMAND ${PATCH_CMD} -p 1 -d ${BUILD_DIR}/pthreads/src/external_pthreads < ${PATCH_DIR}/pthreads.diff + BUILD_COMMAND ${PTHREADS_BUILD} + INSTALL_COMMAND COMMAND + ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/libpthreadVC3${LIBEXT} ${LIBDIR}/pthreads/lib/pthreadVC3${LIBEXT} && + ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/pthread.h ${LIBDIR}/pthreads/inc/pthread.h && + ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/sched.h ${LIBDIR}/pthreads/inc/sched.h && + ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/semaphore.h ${LIBDIR}/pthreads/inc/semaphore.h && + ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/_ptw32.h ${LIBDIR}/pthreads/inc/_ptw32.h + INSTALL_DIR ${LIBDIR}/pthreads + ) + + if(BUILD_MODE STREQUAL Release) + ExternalProject_Add_Step(external_pthreads after_install + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pthreads/inc/ ${HARVEST_TARGET}/pthreads/include/ + COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pthreads/lib/ ${HARVEST_TARGET}/pthreads/lib + DEPENDEES install ) - - if(BUILD_MODE STREQUAL Release) - ExternalProject_Add_Step(external_pthreads after_install - COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pthreads/inc/ ${HARVEST_TARGET}/pthreads/include/ - COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pthreads/lib/ ${HARVEST_TARGET}/pthreads/lib - DEPENDEES install - ) - endif() - + endif() endif() diff --git a/build_files/build_environment/cmake/sndfile.cmake b/build_files/build_environment/cmake/sndfile.cmake index 60a33c6a236..ff57ffe7c28 100644 --- a/build_files/build_environment/cmake/sndfile.cmake +++ b/build_files/build_environment/cmake/sndfile.cmake @@ -52,10 +52,10 @@ endif() if(BUILD_MODE STREQUAL Release AND WIN32) ExternalProject_Add_Step(external_sndfile after_install - COMMAND lib /def:${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.def /machine:x64 /out:${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/bin/libsndfile-1.dll ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.dll - COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.lib ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/include/sndfile.h ${HARVEST_TARGET}/sndfile/include/sndfile.h + COMMAND lib /def:${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.def /machine:x64 /out:${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/bin/libsndfile-1.dll ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.dll + COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/sndfile/src/external_sndfile/src/libsndfile-1.lib ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/include/sndfile.h ${HARVEST_TARGET}/sndfile/include/sndfile.h DEPENDEES install ) diff --git a/build_files/build_environment/cmake/yamlcpp.cmake b/build_files/build_environment/cmake/yamlcpp.cmake index d3be8854c57..4463db04426 100644 --- a/build_files/build_environment/cmake/yamlcpp.cmake +++ b/build_files/build_environment/cmake/yamlcpp.cmake @@ -10,7 +10,8 @@ if(WIN32) set(YAMLCPP_EXTRA_ARGS ${YAMLCPP_EXTRA_ARGS} -DBUILD_GMOCK=OFF - -DYAML_MSVC_SHARED_RT=ON) + -DYAML_MSVC_SHARED_RT=ON + ) endif() ExternalProject_Add(external_yamlcpp From 491fc5cacead98b1979560b752c0bd9ab0327519 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Dec 2022 14:57:13 +1100 Subject: [PATCH 0080/1522] Build: disable X11 support for spnav on Linux This prevented building Blender without X11 (Wayland only). --- build_files/build_environment/cmake/spnav.cmake | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/build_files/build_environment/cmake/spnav.cmake b/build_files/build_environment/cmake/spnav.cmake index 33a262cbc86..12b904866df 100644 --- a/build_files/build_environment/cmake/spnav.cmake +++ b/build_files/build_environment/cmake/spnav.cmake @@ -5,7 +5,20 @@ ExternalProject_Add(external_spnav DOWNLOAD_DIR ${DOWNLOAD_DIR} URL_HASH ${SPNAV_HASH_TYPE}=${SPNAV_HASH} PREFIX ${BUILD_DIR}/spnav - CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/spnav/src/external_spnav/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/spnav --disable-shared --enable-static --with-pic + + CONFIGURE_COMMAND + ${CONFIGURE_ENV} && + cd ${BUILD_DIR}/spnav/src/external_spnav/ && + ${CONFIGURE_COMMAND} + --prefix=${LIBDIR}/spnav + # X11 is not needed as Blender polls the device as part of the GHOST event loop. + # This is used to support `3dxserv`, however this is no longer supported by 3DCONNEXION. + # Disable so building without X11 is supported (WAYLAND only). + --disable-x11 + --disable-shared + --enable-static + --with-pic + BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/spnav/src/external_spnav/ && make -j${MAKE_THREADS} INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/spnav/src/external_spnav/ && make install INSTALL_DIR ${LIBDIR}/spnav From 396816faacf349a04edda2ef2e714b4a505bc0cf Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Dec 2022 15:10:34 +1100 Subject: [PATCH 0081/1522] Libs: bump libspnav to 1.1 Version 0.2.3 doesn't include the fix needed for space-mouse enterprise, see T101866. --- build_files/build_environment/cmake/versions.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 870f2da9abe..b27dcb4fa4e 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -369,9 +369,9 @@ set(WEBP_HASH_TYPE MD5) set(WEBP_FILE libwebp-${WEBP_VERSION}.tar.gz) set(WEBP_CPE "cpe:2.3:a:webmproject:libwebp:${WEBP_VERSION}:*:*:*:*:*:*:*") -set(SPNAV_VERSION 0.2.3) -set(SPNAV_URI http://downloads.sourceforge.net/project/spacenav/spacenav%20library%20%28SDK%29/libspnav%20${SPNAV_VERSION}/libspnav-${SPNAV_VERSION}.tar.gz) -set(SPNAV_HASH 44d840540d53326d4a119c0f1aa7bf0a) +set(SPNAV_VERSION 1.1) +set(SPNAV_URI https://github.com/FreeSpacenav/libspnav/releases/download/v${SPNAV_VERSION}/libspnav-${SPNAV_VERSION}.tar.gz) +set(SPNAV_HASH 7c0032034672dfba3c4bb9b49a440e70) set(SPNAV_HASH_TYPE MD5) set(SPNAV_FILE libspnav-${SPNAV_VERSION}.tar.gz) From ad39c0f31218b5a977dd32817f216851b6560427 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Dec 2022 15:23:47 +1100 Subject: [PATCH 0082/1522] Build: add missing library to the linux-rocky8-setup.sh script --- build_files/build_environment/linux/linux-rocky8-setup.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build_files/build_environment/linux/linux-rocky8-setup.sh b/build_files/build_environment/linux/linux-rocky8-setup.sh index a1696ad5ccc..7be07b40a3e 100644 --- a/build_files/build_environment/linux/linux-rocky8-setup.sh +++ b/build_files/build_environment/linux/linux-rocky8-setup.sh @@ -81,6 +81,7 @@ PACKAGES_FOR_LIBS=( # NOTE(@campbellbarton): while `python39` is available, the default Python version is 3.6. # This is used for the `python3-mako` package for e.g. # So use the "default" system Python since it means it's most compatible with other packages. + python3 # Required by: `mesa`. expat-devel @@ -89,8 +90,11 @@ PACKAGES_FOR_LIBS=( bison # Required by: `external_osl` as a build-time dependency. flex + # Required by: `external_ispc`. ncurses-devel + # Required by: `external_ispc` (when building with CLANG). + libstdc++-static ) # Additional packages needed for building Blender. From b848de754621ccbf2e2960919699df796413f2c7 Mon Sep 17 00:00:00 2001 From: nutti Date: Wed, 14 Dec 2022 15:40:53 +1100 Subject: [PATCH 0083/1522] Fix T102213: Invalid font size in the image editor with some scripts The size could be left at an unexpected value by scripts, causing the wrong size to be shown. Ref D16493 --- source/blender/editors/screen/area.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index a62e027ba03..af97b37acc1 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -3531,6 +3531,9 @@ void ED_region_info_draw_multiline(ARegion *region, /* background box */ rcti rect = *ED_region_visible_rect(region); + /* Needed in case scripts leave the font size at an unexpected value, see: T102213. */ + BLF_size(fontid, style->widget.points * U.dpi_fac); + /* Box fill entire width or just around text. */ if (!full_redraw) { const char **text = &text_array[0]; From fd36221930e35efd2c09af8fb91234a510e3b9dc Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Dec 2022 17:09:55 +1100 Subject: [PATCH 0084/1522] GHOST/Wayland: fix memory leak when Wayland fails to start --- intern/ghost/intern/GHOST_SystemWayland.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 0c292adb044..6bc07fed10c 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -5316,7 +5316,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) /* Connect to the Wayland server. */ display_->wl_display = wl_display_connect(nullptr); if (!display_->wl_display) { - gwl_display_destroy(display_); + this->~GHOST_SystemWayland(); throw std::runtime_error("Wayland: unable to connect to display!"); } @@ -5360,7 +5360,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) "WAYLAND found but libdecor was not, install libdecor for Wayland support, " "falling back to X11\n"); # endif - gwl_display_destroy(display_); + this->~GHOST_SystemWayland(); throw std::runtime_error("Wayland: unable to find libdecor!"); use_libdecor = true; @@ -5377,7 +5377,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) GWL_LibDecor_System &decor = *display_->libdecor; decor.context = libdecor_new(display_->wl_display, &libdecor_interface); if (!decor.context) { - gwl_display_destroy(display_); + this->~GHOST_SystemWayland(); throw std::runtime_error("Wayland: unable to create window decorations!"); } } @@ -5388,7 +5388,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) { GWL_XDG_Decor_System &decor = *display_->xdg_decor; if (!decor.shell) { - gwl_display_destroy(display_); + this->~GHOST_SystemWayland(); throw std::runtime_error("Wayland: unable to access xdg_shell!"); } } From 4263919270de7bbb5ebb03101b3a3442d4551736 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Dec 2022 17:47:29 +1100 Subject: [PATCH 0085/1522] Build: fix building FFMPEG on Linux PKG_CONFIG_PATH wasn't set properly on Linux. Also wrap long lines for better readability. --- .../build_environment/cmake/ffmpeg.cmake | 54 +++++++++++++++++-- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/build_files/build_environment/cmake/ffmpeg.cmake b/build_files/build_environment/cmake/ffmpeg.cmake index e2b60e161f2..41f8e16b913 100644 --- a/build_files/build_environment/cmake/ffmpeg.cmake +++ b/build_files/build_environment/cmake/ffmpeg.cmake @@ -1,9 +1,55 @@ # SPDX-License-Identifier: GPL-2.0-or-later -set(FFMPEG_CFLAGS "-I${mingw_LIBDIR}/lame/include -I${mingw_LIBDIR}/openjpeg/include/ -I${mingw_LIBDIR}/ogg/include -I${mingw_LIBDIR}/vorbis/include -I${mingw_LIBDIR}/theora/include -I${mingw_LIBDIR}/opus/include -I${mingw_LIBDIR}/vpx/include -I${mingw_LIBDIR}/x264/include -I${mingw_LIBDIR}/xvidcore/include -I${mingw_LIBDIR}/zlib/include -I${mingw_LIBDIR}/aom/include") -set(FFMPEG_LDFLAGS "-L${mingw_LIBDIR}/lame/lib -L${mingw_LIBDIR}/openjpeg/lib -L${mingw_LIBDIR}/ogg/lib -L${mingw_LIBDIR}/vorbis/lib -L${mingw_LIBDIR}/theora/lib -L${mingw_LIBDIR}/opus/lib -L${mingw_LIBDIR}/vpx/lib -L${mingw_LIBDIR}/x264/lib -L${mingw_LIBDIR}/xvidcore/lib -L${mingw_LIBDIR}/zlib/lib -L${mingw_LIBDIR}/aom/lib") -set(FFMPEG_EXTRA_FLAGS --pkg-config-flags=--static --extra-cflags=${FFMPEG_CFLAGS} --extra-ldflags=${FFMPEG_LDFLAGS}) -set(FFMPEG_ENV PKG_CONFIG_PATH=${mingw_LIBDIR}/openjpeg/lib/pkgconfig:${mingw_LIBDIR}/x264/lib/pkgconfig:${mingw_LIBDIR}/vorbis/lib/pkgconfig:${mingw_LIBDIR}/ogg/lib/pkgconfig:${mingw_LIBDIR}:${mingw_LIBDIR}/vpx/lib/pkgconfig:${mingw_LIBDIR}/theora/lib/pkgconfig:${mingw_LIBDIR}/openjpeg/lib/pkgconfig:${mingw_LIBDIR}/opus/lib/pkgconfig:${mingw_LIBDIR}/aom/lib/pkgconfig:) +if(WIN32) + set(temp_LIBDIR ${mingw_LIBDIR}) +else() + set(temp_LIBDIR ${LIBDIR}) +endif() + +set(FFMPEG_CFLAGS "\ +-I${temp_LIBDIR}/lame/include \ +-I${temp_LIBDIR}/openjpeg/include/ \ +-I${temp_LIBDIR}/ogg/include \ +-I${temp_LIBDIR}/vorbis/include \ +-I${temp_LIBDIR}/theora/include \ +-I${temp_LIBDIR}/opus/include \ +-I${temp_LIBDIR}/vpx/include \ +-I${temp_LIBDIR}/x264/include \ +-I${temp_LIBDIR}/xvidcore/include \ +-I${temp_LIBDIR}/zlib/include \ +-I${temp_LIBDIR}/aom/include" +) +set(FFMPEG_LDFLAGS "\ +-L${temp_LIBDIR}/lame/lib \ +-L${temp_LIBDIR}/openjpeg/lib \ +-L${temp_LIBDIR}/ogg/lib \ +-L${temp_LIBDIR}/vorbis/lib \ +-L${temp_LIBDIR}/theora/lib \ +-L${temp_LIBDIR}/opus/lib \ +-L${temp_LIBDIR}/vpx/lib \ +-L${temp_LIBDIR}/x264/lib \ +-L${temp_LIBDIR}/xvidcore/lib \ +-L${temp_LIBDIR}/zlib/lib \ +-L${temp_LIBDIR}/aom/lib" +) +set(FFMPEG_EXTRA_FLAGS + --pkg-config-flags=--static + --extra-cflags=${FFMPEG_CFLAGS} + --extra-ldflags=${FFMPEG_LDFLAGS} +) +set(FFMPEG_ENV "PKG_CONFIG_PATH=\ +${temp_LIBDIR}/openjpeg/lib/pkgconfig:\ +${temp_LIBDIR}/x264/lib/pkgconfig:\ +${temp_LIBDIR}/vorbis/lib/pkgconfig:\ +${temp_LIBDIR}/ogg/lib/pkgconfig:\ +${temp_LIBDIR}/vpx/lib/pkgconfig:\ +${temp_LIBDIR}/theora/lib/pkgconfig:\ +${temp_LIBDIR}/openjpeg/lib/pkgconfig:\ +${temp_LIBDIR}/opus/lib/pkgconfig:\ +${temp_LIBDIR}/aom/lib/pkgconfig" +) + +unset(temp_LIBDIR) if(WIN32) set(FFMPEG_ENV set ${FFMPEG_ENV} &&) From 893039591270ad6989a5450286f82b6604ce69f6 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Tue, 13 Dec 2022 15:40:18 +0100 Subject: [PATCH 0086/1522] Fix T101765: Curves sculptmode: object origin and 3D cursor are visible This is because OB_MODE_SCULPT_CURVES is not part of OB_MODE_ALL_PAINT (yet). While there is some chance it ends up there, there are a lot of more places that need checking and so patch only fixes the report very isolated. NOTE: T93501 is related (since the option to show these should also be hidden in sculptmode) Maniphest Tasks: T101765 Differential Revision: https://developer.blender.org/D16764 --- source/blender/draw/engines/overlay/overlay_extra.cc | 3 ++- source/blender/draw/intern/draw_view.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_extra.cc b/source/blender/draw/engines/overlay/overlay_extra.cc index 48dfb027545..3363a94a38f 100644 --- a/source/blender/draw/engines/overlay/overlay_extra.cc +++ b/source/blender/draw/engines/overlay/overlay_extra.cc @@ -1552,7 +1552,8 @@ void OVERLAY_extra_cache_populate(OVERLAY_Data *vedata, Object *ob) const bool is_select_mode = DRW_state_is_select(); const bool is_paint_mode = (draw_ctx->object_mode & - (OB_MODE_ALL_PAINT | OB_MODE_ALL_PAINT_GPENCIL)) != 0; + (OB_MODE_ALL_PAINT | OB_MODE_ALL_PAINT_GPENCIL | + OB_MODE_SCULPT_CURVES)) != 0; const bool from_dupli = (ob->base_flag & (BASE_FROM_SET | BASE_FROM_DUPLI)) != 0; const bool has_bounds = !ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_EMPTY, OB_SPEAKER, OB_LIGHTPROBE); const bool has_texspace = has_bounds && diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c index 35ff8891a0f..269942edaf8 100644 --- a/source/blender/draw/intern/draw_view.c +++ b/source/blender/draw/intern/draw_view.c @@ -59,7 +59,7 @@ static bool is_cursor_visible(const DRWContextState *draw_ctx, Scene *scene, Vie } /* don't draw cursor in paint modes, but with a few exceptions */ - if (draw_ctx->object_mode & OB_MODE_ALL_PAINT) { + if ((draw_ctx->object_mode & (OB_MODE_ALL_PAINT | OB_MODE_SCULPT_CURVES)) != 0) { /* exception: object is in weight paint and has deforming armature in pose mode */ if (draw_ctx->object_mode & OB_MODE_WEIGHT_PAINT) { if (BKE_object_pose_armature_get(draw_ctx->obact) != NULL) { From dba7837d449c6502600bd5bd907b89c7e860c7f0 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 14 Dec 2022 09:21:49 -0300 Subject: [PATCH 0087/1522] Fix typo in rB2c5a525d6409 `MOD_MIR_AXIS_Y` -> `MOD_MIR_AXIS_Z` This causes mirror-Z clipping to be non-functional. --- source/blender/editors/transform/transform_convert.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index b5373b4fd6c..22f42d4ab5c 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -1079,7 +1079,7 @@ void transform_convert_clip_mirror_modifier_apply(TransDataContainer *tc) continue; } - if ((mmd->flag & (MOD_MIR_AXIS_X | MOD_MIR_AXIS_Y | MOD_MIR_AXIS_Y)) == 0) { + if ((mmd->flag & (MOD_MIR_AXIS_X | MOD_MIR_AXIS_Y | MOD_MIR_AXIS_Z)) == 0) { continue; } From c30fdb9cf52d62dcd25fbc93f29c2983cc90a447 Mon Sep 17 00:00:00 2001 From: Patrick Mours Date: Wed, 14 Dec 2022 15:21:39 +0100 Subject: [PATCH 0088/1522] Fix mismatching PTX function declarations for OSL intrinsics with string parameters The use of a struct for device strings caused the CUDA compiler to generate byte arrays as the argument type, whereas OSL generated primitive integer types (for the hash). Fix that by using a typedef instead so that the CUDA compiler too will use an integer type in the PTX it generates. Maniphest Tasks: T101222 --- intern/cycles/kernel/osl/services_gpu.h | 110 ++++++++++++------------ intern/cycles/kernel/osl/types.h | 35 ++------ 2 files changed, 61 insertions(+), 84 deletions(-) diff --git a/intern/cycles/kernel/osl/services_gpu.h b/intern/cycles/kernel/osl/services_gpu.h index 75cf39919a0..744c7103b28 100644 --- a/intern/cycles/kernel/osl/services_gpu.h +++ b/intern/cycles/kernel/osl/services_gpu.h @@ -14,111 +14,111 @@ namespace DeviceStrings { /* "" */ -ccl_device_constant DeviceString _emptystring_ = {0ull}; +ccl_device_constant DeviceString _emptystring_ = 0ull; /* "common" */ -ccl_device_constant DeviceString u_common = {14645198576927606093ull}; +ccl_device_constant DeviceString u_common = 14645198576927606093ull; /* "world" */ -ccl_device_constant DeviceString u_world = {16436542438370751598ull}; +ccl_device_constant DeviceString u_world = 16436542438370751598ull; /* "shader" */ -ccl_device_constant DeviceString u_shader = {4279676006089868ull}; +ccl_device_constant DeviceString u_shader = 4279676006089868ull; /* "object" */ -ccl_device_constant DeviceString u_object = {973692718279674627ull}; +ccl_device_constant DeviceString u_object = 973692718279674627ull; /* "NDC" */ -ccl_device_constant DeviceString u_ndc = {5148305047403260775ull}; +ccl_device_constant DeviceString u_ndc = 5148305047403260775ull; /* "screen" */ -ccl_device_constant DeviceString u_screen = {14159088609039777114ull}; +ccl_device_constant DeviceString u_screen = 14159088609039777114ull; /* "camera" */ -ccl_device_constant DeviceString u_camera = {2159505832145726196ull}; +ccl_device_constant DeviceString u_camera = 2159505832145726196ull; /* "raster" */ -ccl_device_constant DeviceString u_raster = {7759263238610201778ull}; +ccl_device_constant DeviceString u_raster = 7759263238610201778ull; /* "hsv" */ -ccl_device_constant DeviceString u_hsv = {2177035556331879497ull}; +ccl_device_constant DeviceString u_hsv = 2177035556331879497ull; /* "hsl" */ -ccl_device_constant DeviceString u_hsl = {7749766809258288148ull}; +ccl_device_constant DeviceString u_hsl = 7749766809258288148ull; /* "XYZ" */ -ccl_device_constant DeviceString u_xyz = {4957977063494975483ull}; +ccl_device_constant DeviceString u_xyz = 4957977063494975483ull; /* "xyY" */ -ccl_device_constant DeviceString u_xyy = {5138822319725660255ull}; +ccl_device_constant DeviceString u_xyy = 5138822319725660255ull; /* "sRGB" */ -ccl_device_constant DeviceString u_srgb = {15368599878474175032ull}; +ccl_device_constant DeviceString u_srgb = 15368599878474175032ull; /* "object:location" */ -ccl_device_constant DeviceString u_object_location = {7846190347358762897ull}; +ccl_device_constant DeviceString u_object_location = 7846190347358762897ull; /* "object:color" */ -ccl_device_constant DeviceString u_object_color = {12695623857059169556ull}; +ccl_device_constant DeviceString u_object_color = 12695623857059169556ull; /* "object:alpha" */ -ccl_device_constant DeviceString u_object_alpha = {11165053919428293151ull}; +ccl_device_constant DeviceString u_object_alpha = 11165053919428293151ull; /* "object:index" */ -ccl_device_constant DeviceString u_object_index = {6588325838217472556ull}; +ccl_device_constant DeviceString u_object_index = 6588325838217472556ull; /* "geom:dupli_generated" */ -ccl_device_constant DeviceString u_geom_dupli_generated = {6715607178003388908ull}; +ccl_device_constant DeviceString u_geom_dupli_generated = 6715607178003388908ull; /* "geom:dupli_uv" */ -ccl_device_constant DeviceString u_geom_dupli_uv = {1294253317490155849ull}; +ccl_device_constant DeviceString u_geom_dupli_uv = 1294253317490155849ull; /* "material:index" */ -ccl_device_constant DeviceString u_material_index = {741770758159634623ull}; +ccl_device_constant DeviceString u_material_index = 741770758159634623ull; /* "object:random" */ -ccl_device_constant DeviceString u_object_random = {15789063994977955884ull}; +ccl_device_constant DeviceString u_object_random = 15789063994977955884ull; /* "particle:index" */ -ccl_device_constant DeviceString u_particle_index = {9489711748229903784ull}; +ccl_device_constant DeviceString u_particle_index = 9489711748229903784ull; /* "particle:random" */ -ccl_device_constant DeviceString u_particle_random = {17993722202766855761ull}; +ccl_device_constant DeviceString u_particle_random = 17993722202766855761ull; /* "particle:age" */ -ccl_device_constant DeviceString u_particle_age = {7380730644710951109ull}; +ccl_device_constant DeviceString u_particle_age = 7380730644710951109ull; /* "particle:lifetime" */ -ccl_device_constant DeviceString u_particle_lifetime = {16576828923156200061ull}; +ccl_device_constant DeviceString u_particle_lifetime = 16576828923156200061ull; /* "particle:location" */ -ccl_device_constant DeviceString u_particle_location = {10309536211423573010ull}; +ccl_device_constant DeviceString u_particle_location = 10309536211423573010ull; /* "particle:rotation" */ -ccl_device_constant DeviceString u_particle_rotation = {17858543768041168459ull}; +ccl_device_constant DeviceString u_particle_rotation = 17858543768041168459ull; /* "particle:size" */ -ccl_device_constant DeviceString u_particle_size = {16461524249715420389ull}; +ccl_device_constant DeviceString u_particle_size = 16461524249715420389ull; /* "particle:velocity" */ -ccl_device_constant DeviceString u_particle_velocity = {13199101248768308863ull}; +ccl_device_constant DeviceString u_particle_velocity = 13199101248768308863ull; /* "particle:angular_velocity" */ -ccl_device_constant DeviceString u_particle_angular_velocity = {16327930120486517910ull}; +ccl_device_constant DeviceString u_particle_angular_velocity = 16327930120486517910ull; /* "geom:numpolyvertices" */ -ccl_device_constant DeviceString u_geom_numpolyvertices = {382043551489988826ull}; +ccl_device_constant DeviceString u_geom_numpolyvertices = 382043551489988826ull; /* "geom:trianglevertices" */ -ccl_device_constant DeviceString u_geom_trianglevertices = {17839267571524187074ull}; +ccl_device_constant DeviceString u_geom_trianglevertices = 17839267571524187074ull; /* "geom:polyvertices" */ -ccl_device_constant DeviceString u_geom_polyvertices = {1345577201967881769ull}; +ccl_device_constant DeviceString u_geom_polyvertices = 1345577201967881769ull; /* "geom:name" */ -ccl_device_constant DeviceString u_geom_name = {13606338128269760050ull}; +ccl_device_constant DeviceString u_geom_name = 13606338128269760050ull; /* "geom:undisplaced" */ -ccl_device_constant DeviceString u_geom_undisplaced = {12431586303019276305ull}; +ccl_device_constant DeviceString u_geom_undisplaced = 12431586303019276305ull; /* "geom:is_smooth" */ -ccl_device_constant DeviceString u_is_smooth = {857544214094480123ull}; +ccl_device_constant DeviceString u_is_smooth = 857544214094480123ull; /* "geom:is_curve" */ -ccl_device_constant DeviceString u_is_curve = {129742495633653138ull}; +ccl_device_constant DeviceString u_is_curve = 129742495633653138ull; /* "geom:curve_thickness" */ -ccl_device_constant DeviceString u_curve_thickness = {10605802038397633852ull}; +ccl_device_constant DeviceString u_curve_thickness = 10605802038397633852ull; /* "geom:curve_length" */ -ccl_device_constant DeviceString u_curve_length = {11423459517663715453ull}; +ccl_device_constant DeviceString u_curve_length = 11423459517663715453ull; /* "geom:curve_tangent_normal" */ -ccl_device_constant DeviceString u_curve_tangent_normal = {12301397394034985633ull}; +ccl_device_constant DeviceString u_curve_tangent_normal = 12301397394034985633ull; /* "geom:curve_random" */ -ccl_device_constant DeviceString u_curve_random = {15293085049960492358ull}; +ccl_device_constant DeviceString u_curve_random = 15293085049960492358ull; /* "geom:is_point" */ -ccl_device_constant DeviceString u_is_point = {2511357849436175953ull}; +ccl_device_constant DeviceString u_is_point = 2511357849436175953ull; /* "geom:point_radius" */ -ccl_device_constant DeviceString u_point_radius = {9956381140398668479ull}; +ccl_device_constant DeviceString u_point_radius = 9956381140398668479ull; /* "geom:point_position" */ -ccl_device_constant DeviceString u_point_position = {15684484280742966916ull}; +ccl_device_constant DeviceString u_point_position = 15684484280742966916ull; /* "geom:point_random" */ -ccl_device_constant DeviceString u_point_random = {5632627207092325544ull}; +ccl_device_constant DeviceString u_point_random = 5632627207092325544ull; /* "geom:normal_map_normal" */ -ccl_device_constant DeviceString u_normal_map_normal = {10718948685686827073}; +ccl_device_constant DeviceString u_normal_map_normal = 10718948685686827073; /* "path:ray_length" */ -ccl_device_constant DeviceString u_path_ray_length = {16391985802412544524ull}; +ccl_device_constant DeviceString u_path_ray_length = 16391985802412544524ull; /* "path:ray_depth" */ -ccl_device_constant DeviceString u_path_ray_depth = {16643933224879500399ull}; +ccl_device_constant DeviceString u_path_ray_depth = 16643933224879500399ull; /* "path:diffuse_depth" */ -ccl_device_constant DeviceString u_path_diffuse_depth = {13191651286699118408ull}; +ccl_device_constant DeviceString u_path_diffuse_depth = 13191651286699118408ull; /* "path:glossy_depth" */ -ccl_device_constant DeviceString u_path_glossy_depth = {15717768399057252940ull}; +ccl_device_constant DeviceString u_path_glossy_depth = 15717768399057252940ull; /* "path:transparent_depth" */ -ccl_device_constant DeviceString u_path_transparent_depth = {7821650266475578543ull}; +ccl_device_constant DeviceString u_path_transparent_depth = 7821650266475578543ull; /* "path:transmission_depth" */ -ccl_device_constant DeviceString u_path_transmission_depth = {15113408892323917624ull}; +ccl_device_constant DeviceString u_path_transmission_depth = 15113408892323917624ull; } // namespace DeviceStrings @@ -1275,9 +1275,7 @@ ccl_device_extern bool osl_get_attribute(ccl_private ShaderGlobals *sg, object = sd->object; } - const uint64_t id = name.hash(); - - const AttributeDescriptor desc = find_attribute(kg, object, sd->prim, sd->type, id); + const AttributeDescriptor desc = find_attribute(kg, object, sd->prim, sd->type, name); if (desc.offset != ATTR_STD_NOT_FOUND) { return get_object_attribute(kg, sd, desc, type, derivatives, res); } diff --git a/intern/cycles/kernel/osl/types.h b/intern/cycles/kernel/osl/types.h index 717306a3d07..692c2349a30 100644 --- a/intern/cycles/kernel/osl/types.h +++ b/intern/cycles/kernel/osl/types.h @@ -5,47 +5,26 @@ CCL_NAMESPACE_BEGIN -struct DeviceString { #if defined(__KERNEL_GPU__) - /* Strings are represented by their hashes in CUDA and OptiX. */ - size_t str_; - - ccl_device_inline_method uint64_t hash() const - { - return str_; - } +/* Strings are represented by their hashes on the GPU. */ +typedef size_t DeviceString; #elif defined(OPENIMAGEIO_USTRING_H) - ustring str_; - - ccl_device_inline_method uint64_t hash() const - { - return str_.hash(); - } +typedef ustring DeviceString; #else - const char *str_; +typedef const char *DeviceString; #endif - ccl_device_inline_method bool operator==(DeviceString b) const - { - return str_ == b.str_; - } - ccl_device_inline_method bool operator!=(DeviceString b) const - { - return str_ != b.str_; - } -}; - ccl_device_inline DeviceString make_string(const char *str, size_t hash) { #if defined(__KERNEL_GPU__) (void)str; - return {hash}; + return hash; #elif defined(OPENIMAGEIO_USTRING_H) (void)hash; - return {ustring(str)}; + return ustring(str); #else (void)hash; - return {str}; + return str; #endif } From a243a9dc79ebe6cf4ee473be69a0d28b5b05375c Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 13 Dec 2022 17:24:24 +0100 Subject: [PATCH 0089/1522] Cleanup: Remove unused headers in asset files --- source/blender/asset_system/intern/asset_catalog.cc | 1 - source/blender/asset_system/intern/asset_library.cc | 1 - .../blender/asset_system/intern/asset_library_service.cc | 2 -- .../blender/asset_system/intern/asset_representation.cc | 2 -- source/blender/asset_system/tests/asset_catalog_test.cc | 3 --- .../asset_system/tests/asset_catalog_tree_test.cc | 9 --------- source/blender/asset_system/tests/asset_library_test.cc | 1 - source/blender/editors/asset/intern/asset_handle.cc | 2 -- source/blender/editors/asset/intern/asset_indexer.cc | 1 - source/blender/editors/asset/intern/asset_list.cc | 1 - source/blender/editors/asset/intern/asset_ops.cc | 4 ---- 11 files changed, 27 deletions(-) diff --git a/source/blender/asset_system/intern/asset_catalog.cc b/source/blender/asset_system/intern/asset_catalog.cc index 9b47aca1209..c295f2de16e 100644 --- a/source/blender/asset_system/intern/asset_catalog.cc +++ b/source/blender/asset_system/intern/asset_catalog.cc @@ -9,7 +9,6 @@ #include "AS_asset_catalog.hh" #include "AS_asset_catalog_tree.hh" -#include "AS_asset_library.h" #include "AS_asset_library.hh" #include "BLI_fileops.hh" diff --git a/source/blender/asset_system/intern/asset_library.cc b/source/blender/asset_system/intern/asset_library.cc index 73f81a50e46..9a6b73ef501 100644 --- a/source/blender/asset_system/intern/asset_library.cc +++ b/source/blender/asset_system/intern/asset_library.cc @@ -17,7 +17,6 @@ #include "BLI_fileops.h" #include "BLI_path_util.h" -#include "BLI_set.hh" #include "DNA_userdef_types.h" diff --git a/source/blender/asset_system/intern/asset_library_service.cc b/source/blender/asset_system/intern/asset_library_service.cc index 37136968946..79097ac8cd2 100644 --- a/source/blender/asset_system/intern/asset_library_service.cc +++ b/source/blender/asset_system/intern/asset_library_service.cc @@ -7,8 +7,6 @@ #include "BKE_blender.h" #include "BKE_preferences.h" -#include "BLI_fileops.h" /* For PATH_MAX (at least on Windows). */ -#include "BLI_path_util.h" #include "BLI_string_ref.hh" #include "DNA_asset_types.h" diff --git a/source/blender/asset_system/intern/asset_representation.cc b/source/blender/asset_system/intern/asset_representation.cc index c6bc5193570..573358b7df7 100644 --- a/source/blender/asset_system/intern/asset_representation.cc +++ b/source/blender/asset_system/intern/asset_representation.cc @@ -13,8 +13,6 @@ #include "AS_asset_representation.h" #include "AS_asset_representation.hh" -#include "BKE_asset.h" - namespace blender::asset_system { AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier, diff --git a/source/blender/asset_system/tests/asset_catalog_test.cc b/source/blender/asset_system/tests/asset_catalog_test.cc index 87819f3683b..3e117e3da97 100644 --- a/source/blender/asset_system/tests/asset_catalog_test.cc +++ b/source/blender/asset_system/tests/asset_catalog_test.cc @@ -4,7 +4,6 @@ #include "AS_asset_catalog.hh" #include "AS_asset_catalog_tree.hh" -#include "BKE_appdir.h" #include "BKE_preferences.h" #include "BLI_fileops.h" @@ -13,8 +12,6 @@ #include "DNA_asset_types.h" #include "DNA_userdef_types.h" -#include "CLG_log.h" - #include "testing/testing.h" #include "asset_library_test_common.hh" diff --git a/source/blender/asset_system/tests/asset_catalog_tree_test.cc b/source/blender/asset_system/tests/asset_catalog_tree_test.cc index fb1cbde517d..3355423cb48 100644 --- a/source/blender/asset_system/tests/asset_catalog_tree_test.cc +++ b/source/blender/asset_system/tests/asset_catalog_tree_test.cc @@ -4,17 +4,8 @@ #include "AS_asset_catalog.hh" #include "AS_asset_catalog_tree.hh" -#include "BKE_appdir.h" -#include "BKE_preferences.h" - -#include "BLI_fileops.h" #include "BLI_path_util.h" -#include "DNA_asset_types.h" -#include "DNA_userdef_types.h" - -#include "CLG_log.h" - #include "testing/testing.h" #include "asset_library_test_common.hh" diff --git a/source/blender/asset_system/tests/asset_library_test.cc b/source/blender/asset_system/tests/asset_library_test.cc index 059f3d9a46c..1b8d2f8ff0c 100644 --- a/source/blender/asset_system/tests/asset_library_test.cc +++ b/source/blender/asset_system/tests/asset_library_test.cc @@ -5,7 +5,6 @@ #include "AS_asset_library.h" #include "AS_asset_library.hh" -#include "BKE_appdir.h" #include "BKE_callbacks.h" #include "asset_library_service.hh" diff --git a/source/blender/editors/asset/intern/asset_handle.cc b/source/blender/editors/asset/intern/asset_handle.cc index 3528a3824db..26b6f09b231 100644 --- a/source/blender/editors/asset/intern/asset_handle.cc +++ b/source/blender/editors/asset/intern/asset_handle.cc @@ -6,7 +6,6 @@ #include -#include "AS_asset_identifier.hh" #include "AS_asset_representation.h" #include "AS_asset_representation.hh" @@ -15,7 +14,6 @@ #include "BLO_readfile.h" #include "ED_asset_handle.h" -#include "ED_asset_list.hh" #include "WM_api.h" diff --git a/source/blender/editors/asset/intern/asset_indexer.cc b/source/blender/editors/asset/intern/asset_indexer.cc index 23d6a9d1edc..247db565f36 100644 --- a/source/blender/editors/asset/intern/asset_indexer.cc +++ b/source/blender/editors/asset/intern/asset_indexer.cc @@ -26,7 +26,6 @@ #include "BKE_appdir.h" #include "BKE_asset.h" #include "BKE_idprop.hh" -#include "BKE_preferences.h" #include "CLG_log.h" diff --git a/source/blender/editors/asset/intern/asset_list.cc b/source/blender/editors/asset/intern/asset_list.cc index 4a1f26abad0..5b3d256c70c 100644 --- a/source/blender/editors/asset/intern/asset_list.cc +++ b/source/blender/editors/asset/intern/asset_list.cc @@ -15,7 +15,6 @@ #include "BKE_context.h" #include "BLI_map.hh" -#include "BLI_path_util.h" #include "BLI_utility_mixins.hh" #include "DNA_space_types.h" diff --git a/source/blender/editors/asset/intern/asset_ops.cc b/source/blender/editors/asset/intern/asset_ops.cc index da4e0794fe8..497b655c7ce 100644 --- a/source/blender/editors/asset/intern/asset_ops.cc +++ b/source/blender/editors/asset/intern/asset_ops.cc @@ -9,13 +9,11 @@ #include "BKE_bpath.h" #include "BKE_context.h" -#include "BKE_global.h" #include "BKE_lib_id.h" #include "BKE_main.h" #include "BKE_preferences.h" #include "BKE_report.h" -#include "BLI_fileops.h" #include "BLI_fnmatch.h" #include "BLI_path_util.h" #include "BLI_set.hh" @@ -37,8 +35,6 @@ #include "DNA_space_types.h" -#include "BLO_writefile.h" - using namespace blender; /* -------------------------------------------------------------------- */ From f4912e7f5b250b00e34888d79549f91562817654 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 13 Dec 2022 17:25:40 +0100 Subject: [PATCH 0090/1522] Fix asset loading indicator in node add menu disappearing too early The "Loading Asset Libraries" label in the menu would already disappear before the asset libraries are done loading. It only queried if the loading was started, not if it was finished. Especially notable when the asset library was slow to load, e.g. because it is not yet in the asset index. --- source/blender/editors/asset/intern/asset_list.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/asset/intern/asset_list.cc b/source/blender/editors/asset/intern/asset_list.cc index 5b3d256c70c..caceedbd4a5 100644 --- a/source/blender/editors/asset/intern/asset_list.cc +++ b/source/blender/editors/asset/intern/asset_list.cc @@ -111,6 +111,7 @@ class AssetList : NonCopyable { void clear(bContext *C); bool needsRefetch() const; + bool isLoaded() const; void iterate(AssetListIterFn fn) const; bool listen(const wmNotifier ¬ifier) const; int size() const; @@ -189,6 +190,11 @@ bool AssetList::needsRefetch() const return filelist_needs_force_reset(filelist_) || filelist_needs_reading(filelist_); } +bool AssetList::isLoaded() const +{ + return filelist_is_ready(filelist_); +} + void AssetList::iterate(AssetListIterFn fn) const { FileList *files = filelist_; @@ -422,7 +428,7 @@ bool ED_assetlist_is_loaded(const AssetLibraryReference *library_reference) if (list->needsRefetch()) { return false; } - return true; + return list->isLoaded(); } void ED_assetlist_ensure_previews_job(const AssetLibraryReference *library_reference, From fe3110a2859d84401dceda06fd41f3b082eae790 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 14 Dec 2022 11:59:11 -0300 Subject: [PATCH 0091/1522] Fix FallbackCyclesBlitShader compilation error Error: C0204: version directive must be first statement and may not be repeated --- intern/cycles/blender/display_driver.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/intern/cycles/blender/display_driver.cpp b/intern/cycles/blender/display_driver.cpp index 3c347145117..60dd5e2c1d2 100644 --- a/intern/cycles/blender/display_driver.cpp +++ b/intern/cycles/blender/display_driver.cpp @@ -57,7 +57,6 @@ int BlenderDisplayShader::get_tex_coord_attrib_location() /* TODO move shaders to standalone .glsl file. */ static const char *FALLBACK_VERTEX_SHADER = - "#version 330\n" "uniform vec2 fullscreen;\n" "in vec2 texCoord;\n" "in vec2 pos;\n" @@ -75,7 +74,6 @@ static const char *FALLBACK_VERTEX_SHADER = "}\n\0"; static const char *FALLBACK_FRAGMENT_SHADER = - "#version 330\n" "uniform sampler2D image_texture;\n" "in vec2 texCoord_interp;\n" "out vec4 fragColor;\n" From 8daaf71688b849cbbb31b2af7a1260db773b2348 Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Wed, 14 Dec 2022 08:03:28 -0700 Subject: [PATCH 0092/1522] deps_builder: add missing freetype dep to harfbuzz without it harfbuzz could build before freetype which it needs to build. --- build_files/build_environment/cmake/harfbuzz.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/build_files/build_environment/cmake/harfbuzz.cmake b/build_files/build_environment/cmake/harfbuzz.cmake index 3eb994f72fe..d34d312c9d8 100644 --- a/build_files/build_environment/cmake/harfbuzz.cmake +++ b/build_files/build_environment/cmake/harfbuzz.cmake @@ -33,6 +33,7 @@ ExternalProject_Add(external_harfbuzz add_dependencies( external_harfbuzz external_python + external_freetype # Needed for `MESON`. external_python_site_packages ) From 45dbd69296f0677481daff0c915dbc02db743e07 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 14 Dec 2022 16:08:26 +0100 Subject: [PATCH 0093/1522] Fix compiler error on MSVC after a243a9dc79eb --- source/blender/editors/asset/intern/asset_ops.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/asset/intern/asset_ops.cc b/source/blender/editors/asset/intern/asset_ops.cc index 497b655c7ce..3bbfa2ac0f4 100644 --- a/source/blender/editors/asset/intern/asset_ops.cc +++ b/source/blender/editors/asset/intern/asset_ops.cc @@ -14,6 +14,7 @@ #include "BKE_preferences.h" #include "BKE_report.h" +#include "BLI_fileops.h" /* MSVC needs this for `PATH_MAX` */ #include "BLI_fnmatch.h" #include "BLI_path_util.h" #include "BLI_set.hh" From f0dc4d67e56dbdd13feb6ae09d584974b8b567ad Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 14 Dec 2022 16:43:38 +0100 Subject: [PATCH 0094/1522] Geometry Nodes: support storing 2d vector attributes This allows choosing the 2d vector type in the Store Named Attribute node. Similar to byte-colors, there is not a special socket type for this (currently). In geometry nodes itself, vectors are all still 3d. --- source/blender/makesrna/intern/rna_nodetree.c | 4 +++- .../nodes/geometry/nodes/node_geo_store_named_attribute.cc | 7 ++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 6d827cf757a..4a977f09884 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2175,6 +2175,7 @@ static bool generic_attribute_type_supported(const EnumPropertyItem *item) { return ELEM(item->value, CD_PROP_FLOAT, + CD_PROP_FLOAT2, CD_PROP_FLOAT3, CD_PROP_COLOR, CD_PROP_BOOL, @@ -2192,7 +2193,8 @@ static const EnumPropertyItem *rna_GeometryNodeAttributeType_type_itemf(bContext static bool generic_attribute_type_supported_with_socket(const EnumPropertyItem *item) { - return generic_attribute_type_supported(item) && !ELEM(item->value, CD_PROP_BYTE_COLOR); + return generic_attribute_type_supported(item) && + !ELEM(item->value, CD_PROP_BYTE_COLOR, CD_PROP_FLOAT2); } static const EnumPropertyItem *rna_GeometryNodeAttributeType_type_with_socket_itemf( bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free) diff --git a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc index 50f066a647c..4970a926445 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc @@ -59,7 +59,7 @@ static void node_update(bNodeTree *ntree, bNode *node) bNodeSocket *socket_boolean = socket_color4f->next; bNodeSocket *socket_int32 = socket_boolean->next; - nodeSetSocketAvailability(ntree, socket_vector, data_type == CD_PROP_FLOAT3); + nodeSetSocketAvailability(ntree, socket_vector, ELEM(data_type, CD_PROP_FLOAT2, CD_PROP_FLOAT3)); nodeSetSocketAvailability(ntree, socket_float, data_type == CD_PROP_FLOAT); nodeSetSocketAvailability( ntree, socket_color4f, ELEM(data_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)); @@ -113,6 +113,11 @@ static void node_geo_exec(GeoNodeExecParams params) case CD_PROP_FLOAT: field = params.get_input>("Value_Float"); break; + case CD_PROP_FLOAT2: { + field = params.get_input>("Value_Vector"); + field = bke::get_implicit_type_conversions().try_convert(field, CPPType::get()); + break; + } case CD_PROP_FLOAT3: field = params.get_input>("Value_Vector"); break; From d88ebd31d6736b9b184da1c1c11ddb5183ecacbc Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Dec 2022 16:10:43 +0100 Subject: [PATCH 0095/1522] Cleanup: add comments explaining need for requests dependencies --- build_files/build_environment/cmake/versions.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index b27dcb4fa4e..6b56df4ee99 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -235,11 +235,11 @@ set(OPENVDB_FILE openvdb-${OPENVDB_VERSION}.tar.gz) # ------------------------------------------------------------------------------ # Python Modules -# Needed by: TODO. +# Needed by: `requests` module (so the version doesn't change on rebuild). set(IDNA_VERSION 3.3) -# Needed by: TODO. +# Needed by: `requests` module (so the version doesn't change on rebuild). set(CHARSET_NORMALIZER_VERSION 2.0.10) -# Needed by: TODO. +# Needed by: `requests` module (so the version doesn't change on rebuild). set(URLLIB3_VERSION 1.26.8) set(URLLIB3_CPE "cpe:2.3:a:urllib3:urllib3:${URLLIB3_VERSION}:*:*:*:*:*:*:*") # Needed by: Python's `requests` module (so add-ons can authenticate against trusted certificates). From 2221cfc044223d3e87013fe43ed5c5a1b28781a3 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Dec 2022 17:38:25 +0100 Subject: [PATCH 0096/1522] Cleanup: GCC compiler warnings in Cycles float8 test --- intern/cycles/test/util_float8_test.h | 53 +++++++++++++++++---------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/intern/cycles/test/util_float8_test.h b/intern/cycles/test/util_float8_test.h index 54701afaf8b..8ae95d75f47 100644 --- a/intern/cycles/test/util_float8_test.h +++ b/intern/cycles/test/util_float8_test.h @@ -22,13 +22,26 @@ static bool validate_cpu_capabilities() #endif } +/* These are not just static variables because we don't want to run the + * constructor until we know the instructions are supported. */ +static vfloat8 float8_a()() +{ + return make_vfloat8(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f) +} + +static vfloat8 float8_b()() +{ + return make_vfloat8(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f); +} + +static vfloat8 float8_c()() +{ + return make_vfloat8(1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f); +} + #define INIT_FLOAT8_TEST \ if (!validate_cpu_capabilities()) \ - return; \ -\ - const vfloat8 float8_a = make_vfloat8(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f); \ - const vfloat8 float8_b = make_vfloat8(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f); \ - const vfloat8 float8_c = make_vfloat8(1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f); + return; #define compare_vector_scalar(a, b) \ for (size_t index = 0; index < 8; index++) \ @@ -57,17 +70,17 @@ static bool validate_cpu_capabilities() static const float float_b = 1.5f; -TEST(TEST_CATEGORY_NAME, - float8_add_vv){basic_test_vv(float8_a, float8_b, +)} TEST(TEST_CATEGORY_NAME, float8_sub_vv){ - basic_test_vv(float8_a, float8_b, -)} TEST(TEST_CATEGORY_NAME, float8_mul_vv){ - basic_test_vv(float8_a, float8_b, *)} TEST(TEST_CATEGORY_NAME, float8_div_vv){ - basic_test_vv(float8_a, float8_b, /)} TEST(TEST_CATEGORY_NAME, float8_add_vf){ - basic_test_vf(float8_a, float_b, +)} TEST(TEST_CATEGORY_NAME, float8_sub_vf){ - basic_test_vf(float8_a, float_b, -)} TEST(TEST_CATEGORY_NAME, float8_mul_vf){ - basic_test_vf(float8_a, float_b, *)} TEST(TEST_CATEGORY_NAME, - float8_div_vf){basic_test_vf(float8_a, float_b, /)} +TEST(TEST_CATEGORY_NAME, float8_add_vv){ + basic_test_vv(float8_a(), float8_b(), +)} TEST(TEST_CATEGORY_NAME, float8_sub_vv){ + basic_test_vv(float8_a(), float8_b(), -)} TEST(TEST_CATEGORY_NAME, float8_mul_vv){ + basic_test_vv(float8_a(), float8_b(), *)} TEST(TEST_CATEGORY_NAME, float8_div_vv){ + basic_test_vv(float8_a(), float8_b(), /)} TEST(TEST_CATEGORY_NAME, float8_add_vf){ + basic_test_vf(float8_a(), float_b, +)} TEST(TEST_CATEGORY_NAME, float8_sub_vf){ + basic_test_vf(float8_a(), float_b, -)} TEST(TEST_CATEGORY_NAME, float8_mul_vf){ + basic_test_vf(float8_a(), float_b, *)} TEST(TEST_CATEGORY_NAME, float8_div_vf){ + basic_test_vf(float8_a(), float_b, /)} -TEST(TEST_CATEGORY_NAME, float8_ctor) +TEST(TEST_CATEGORY_NAME, float8_c() tor) { INIT_FLOAT8_TEST compare_vector_scalar(make_vfloat8(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f), @@ -85,18 +98,18 @@ TEST(TEST_CATEGORY_NAME, float8_sqrt) TEST(TEST_CATEGORY_NAME, float8_min_max) { INIT_FLOAT8_TEST - compare_vector_vector(min(float8_a, float8_b), float8_a); - compare_vector_vector(max(float8_a, float8_b), float8_b); + compare_vector_vector(min(float8_a(), float8_b()), float8_a()); + compare_vector_vector(max(float8_a(), float8_b()), float8_b()); } TEST(TEST_CATEGORY_NAME, float8_shuffle) { INIT_FLOAT8_TEST - vfloat8 res0 = shuffle<0, 1, 2, 3, 1, 3, 2, 0>(float8_a); + vfloat8 res0 = shuffle<0, 1, 2, 3, 1, 3, 2, 0>(float8_a()); compare_vector_vector(res0, make_vfloat8(0.1f, 0.2f, 0.3f, 0.4f, 0.6f, 0.8f, 0.7f, 0.5f)); - vfloat8 res1 = shuffle<3>(float8_a); + vfloat8 res1 = shuffle<3>(float8_a()); compare_vector_vector(res1, make_vfloat8(0.4f, 0.4f, 0.4f, 0.4f, 0.8f, 0.8f, 0.8f, 0.8f)); - vfloat8 res2 = shuffle<3, 2, 1, 0>(float8_a, float8_b); + vfloat8 res2 = shuffle<3, 2, 1, 0>(float8_a(), float8_b()); compare_vector_vector(res2, make_vfloat8(0.4f, 0.3f, 2.0f, 1.0f, 0.8f, 0.7f, 6.0f, 5.0f)); } From ecfcf1b97b707faa7a3076bf4d917cd333c331d8 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 13 Dec 2022 20:10:39 +0100 Subject: [PATCH 0097/1522] Cycles: disable light tree for existing scenes, enable on new scenes While it helps on many scenes, it can be disruptive for existing scenes and for benchmarks the differences in timing can be confusing. So be a bit more conservative and only it enable it for new scenes. --- intern/cycles/blender/addon/version_update.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py index 8ebb17e614a..7f81ac96309 100644 --- a/intern/cycles/blender/addon/version_update.py +++ b/intern/cycles/blender/addon/version_update.py @@ -241,6 +241,12 @@ def do_versions(self): layer.samples *= layer.samples cscene["use_square_samples"] = False + # Disable light tree for existing scenes. + if version <= (3, 5, 3): + cscene = scene.cycles + if not cscene.is_property_set("use_light_tree"): + cscene.use_light_tree = False + # Lamps for light in bpy.data.lights: if light.library not in libraries: From b0cc8e8ddec3f1771b69234860b40511be975039 Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Tue, 13 Dec 2022 19:14:29 +0100 Subject: [PATCH 0098/1522] Cycles: switch from pretabulated 2D PMJ02 to pretabulated 4D Sobol The first two dimensions of scrambled, shuffled Sobol and shuffled PMJ02 are equivalent, so this makes no real difference for the first two dimensions. But Sobol allows us to naturally extend to more dimensions. Pretabulated Sobol is now always used, and the sampling pattern settings is now only available as a debug option. This in turn allows the following two things (also implemented): * Use proper 3D samples for combined lens + motion blur sampling. This notably reduces the noise on objects that are simultaneously out-of-focus and motion blurred. * Use proper 3D samples for combined light selection + light sampling. Cycles was already doing something clever here with 2D samples, but using 3D samples is more straightforward and avoids overloading one of the dimensions. In the future this will also allow for proper sampling of e.g. volumetric light sources and other things that may need three or four dimensions. Differential Revision: https://developer.blender.org/D16443 --- intern/cycles/blender/addon/properties.py | 8 +- intern/cycles/blender/addon/ui.py | 24 ++- intern/cycles/blender/addon/version_update.py | 2 +- intern/cycles/blender/sync.cpp | 2 +- intern/cycles/kernel/CMakeLists.txt | 2 +- intern/cycles/kernel/data_arrays.h | 2 +- intern/cycles/kernel/data_template.h | 2 +- .../kernel/integrator/init_from_camera.h | 24 ++- intern/cycles/kernel/integrator/path_state.h | 20 ++ .../cycles/kernel/integrator/shade_surface.h | 3 +- .../cycles/kernel/integrator/shade_volume.h | 6 +- intern/cycles/kernel/light/distribution.h | 15 +- intern/cycles/kernel/light/sample.h | 14 +- intern/cycles/kernel/light/tree.h | 9 +- intern/cycles/kernel/sample/jitter.h | 90 --------- intern/cycles/kernel/sample/pattern.h | 46 ++++- intern/cycles/kernel/sample/tabulated_sobol.h | 174 ++++++++++++++++++ intern/cycles/kernel/types.h | 43 +++-- intern/cycles/scene/CMakeLists.txt | 4 +- intern/cycles/scene/integrator.cpp | 31 ++-- intern/cycles/scene/jitter.cpp | 57 ------ intern/cycles/scene/jitter.h | 15 -- intern/cycles/scene/tabulated_sobol.cpp | 71 +++++++ intern/cycles/scene/tabulated_sobol.h | 15 ++ 24 files changed, 425 insertions(+), 254 deletions(-) delete mode 100644 intern/cycles/kernel/sample/jitter.h create mode 100644 intern/cycles/kernel/sample/tabulated_sobol.h delete mode 100644 intern/cycles/scene/jitter.cpp delete mode 100644 intern/cycles/scene/jitter.h create mode 100644 intern/cycles/scene/tabulated_sobol.cpp create mode 100644 intern/cycles/scene/tabulated_sobol.h diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 2da763b9eb1..eff6384c85e 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -82,8 +82,8 @@ enum_use_layer_samples = ( ) enum_sampling_pattern = ( - ('SOBOL', "Sobol-Burley", "Use Sobol-Burley random sampling pattern", 0), - ('PROGRESSIVE_MULTI_JITTER', "Progressive Multi-Jitter", "Use Progressive Multi-Jitter random sampling pattern", 1), + ('SOBOL_BURLEY', "Sobol-Burley", "Use on-the-fly computed Owen-scrambled Sobol for random sampling", 0), + ('TABULATED_SOBOL', "Tabulated Sobol", "Use precomputed tables of Owen-scrambled Sobol for random sampling", 1), ) enum_emission_sampling = ( @@ -412,9 +412,9 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): sampling_pattern: EnumProperty( name="Sampling Pattern", - description="Random sampling pattern used by the integrator. When adaptive sampling is enabled, Progressive Multi-Jitter is always used instead of Sobol-Burley", + description="Random sampling pattern used by the integrator", items=enum_sampling_pattern, - default='PROGRESSIVE_MULTI_JITTER', + default='TABULATED_SOBOL', ) scrambling_distance: FloatProperty( diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index c3477ae0284..4746790aae8 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -364,16 +364,13 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel): row.prop(cscene, "seed") row.prop(cscene, "use_animated_seed", text="", icon='TIME') - col = layout.column(align=True) - col.prop(cscene, "sampling_pattern", text="Pattern") - col = layout.column(align=True) col.prop(cscene, "sample_offset") layout.separator() heading = layout.column(align=True, heading="Scrambling Distance") - heading.active = cscene.sampling_pattern != 'SOBOL' + heading.active = cscene.sampling_pattern != 'TABULATED_SOBOL' heading.prop(cscene, "auto_scrambling_distance", text="Automatic") heading.prop(cscene, "preview_scrambling_distance", text="Viewport") heading.prop(cscene, "scrambling_distance", text="Multiplier") @@ -396,11 +393,22 @@ class CYCLES_RENDER_PT_sampling_lights(CyclesButtonsPanel, Panel): bl_parent_id = "CYCLES_RENDER_PT_sampling" bl_options = {'DEFAULT_CLOSED'} - def draw_header(self, context): + def draw(self, context): layout = self.layout scene = context.scene cscene = scene.cycles + col.prop(cscene, "use_light_tree") + sub = col.row() + sub.prop(cscene, "light_sampling_threshold", text="Light Threshold") + sub.active = not cscene.use_light_tree + + +class CYCLES_RENDER_PT_sampling_debug(CyclesDebugButtonsPanel, Panel): + bl_label = "Debug" + bl_parent_id = "CYCLES_RENDER_PT_sampling" + bl_options = {'DEFAULT_CLOSED'} + def draw(self, context): layout = self.layout layout.use_property_split = True @@ -410,10 +418,7 @@ class CYCLES_RENDER_PT_sampling_lights(CyclesButtonsPanel, Panel): cscene = scene.cycles col = layout.column(align=True) - col.prop(cscene, "use_light_tree") - sub = col.row() - sub.prop(cscene, "light_sampling_threshold", text="Light Threshold") - sub.active = not cscene.use_light_tree + col.prop(cscene, "sampling_pattern", text="Pattern") class CYCLES_RENDER_PT_subdivision(CyclesButtonsPanel, Panel): @@ -2391,6 +2396,7 @@ classes = ( CYCLES_RENDER_PT_sampling_path_guiding_debug, CYCLES_RENDER_PT_sampling_lights, CYCLES_RENDER_PT_sampling_advanced, + CYCLES_RENDER_PT_sampling_debug, CYCLES_RENDER_PT_light_paths, CYCLES_RENDER_PT_light_paths_max_bounces, CYCLES_RENDER_PT_light_paths_clamping, diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py index 7f81ac96309..56d921e49cd 100644 --- a/intern/cycles/blender/addon/version_update.py +++ b/intern/cycles/blender/addon/version_update.py @@ -228,7 +228,7 @@ def do_versions(self): cscene.use_preview_denoising = False if not cscene.is_property_set("sampling_pattern") or \ cscene.get('sampling_pattern') >= 2: - cscene.sampling_pattern = 'PROGRESSIVE_MULTI_JITTER' + cscene.sampling_pattern = 'TABULATED_SOBOL' # Removal of square samples. cscene = scene.cycles diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp index f8be1b210b8..d87d094dc56 100644 --- a/intern/cycles/blender/sync.cpp +++ b/intern/cycles/blender/sync.cpp @@ -357,7 +357,7 @@ void BlenderSync::sync_integrator(BL::ViewLayer &b_view_layer, bool background) } SamplingPattern sampling_pattern = (SamplingPattern)get_enum( - cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_PMJ); + cscene, "sampling_pattern", SAMPLING_NUM_PATTERNS, SAMPLING_PATTERN_TABULATED_SOBOL); integrator->set_sampling_pattern(sampling_pattern); int samples = 1; diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 9dc343f597d..22c52a5802f 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -299,12 +299,12 @@ set(SRC_KERNEL_LIGHT_HEADERS ) set(SRC_KERNEL_SAMPLE_HEADERS - sample/jitter.h sample/lcg.h sample/mapping.h sample/mis.h sample/pattern.h sample/sobol_burley.h + sample/tabulated_sobol.h sample/util.h ) diff --git a/intern/cycles/kernel/data_arrays.h b/intern/cycles/kernel/data_arrays.h index 6914a4642e9..633678fe055 100644 --- a/intern/cycles/kernel/data_arrays.h +++ b/intern/cycles/kernel/data_arrays.h @@ -77,7 +77,7 @@ KERNEL_DATA_ARRAY(KernelShader, shaders) /* lookup tables */ KERNEL_DATA_ARRAY(float, lookup_table) -/* PMJ sample pattern */ +/* tabulated Sobol sample pattern */ KERNEL_DATA_ARRAY(float, sample_pattern_lut) /* image textures */ diff --git a/intern/cycles/kernel/data_template.h b/intern/cycles/kernel/data_template.h index 06df7fe1e62..af7a6d2ef41 100644 --- a/intern/cycles/kernel/data_template.h +++ b/intern/cycles/kernel/data_template.h @@ -179,7 +179,7 @@ KERNEL_STRUCT_MEMBER(integrator, float, sample_clamp_indirect) KERNEL_STRUCT_MEMBER(integrator, int, use_caustics) /* Sampling pattern. */ KERNEL_STRUCT_MEMBER(integrator, int, sampling_pattern) -KERNEL_STRUCT_MEMBER(integrator, int, pmj_sequence_size) +KERNEL_STRUCT_MEMBER(integrator, int, tabulated_sobol_sequence_size) KERNEL_STRUCT_MEMBER(integrator, float, scrambling_distance) /* Volume render. */ KERNEL_STRUCT_MEMBER(integrator, int, use_volumes) diff --git a/intern/cycles/kernel/integrator/init_from_camera.h b/intern/cycles/kernel/integrator/init_from_camera.h index 8df3e1b9fb3..e8b2224bce6 100644 --- a/intern/cycles/kernel/integrator/init_from_camera.h +++ b/intern/cycles/kernel/integrator/init_from_camera.h @@ -26,18 +26,22 @@ ccl_device_inline void integrate_camera_sample(KernelGlobals kg, const float2 rand_filter = (sample == 0) ? make_float2(0.5f, 0.5f) : path_rng_2D(kg, rng_hash, sample, PRNG_FILTER); - /* Depth of field sampling. */ - const float2 rand_lens = (kernel_data.cam.aperturesize > 0.0f) ? - path_rng_2D(kg, rng_hash, sample, PRNG_LENS) : - zero_float2(); - - /* Motion blur time sampling. */ - const float rand_time = (kernel_data.cam.shuttertime != -1.0f) ? - path_rng_1D(kg, rng_hash, sample, PRNG_TIME) : - 0.0f; + /* Motion blur (time) and depth of field (lens) sampling. (time, lens_x, lens_y) */ + const float3 rand_time_lens = (kernel_data.cam.shuttertime != -1.0f || + kernel_data.cam.aperturesize > 0.0f) ? + path_rng_3D(kg, rng_hash, sample, PRNG_LENS_TIME) : + zero_float3(); /* Generate camera ray. */ - camera_sample(kg, x, y, rand_filter.x, rand_filter.y, rand_lens.x, rand_lens.y, rand_time, ray); + camera_sample(kg, + x, + y, + rand_filter.x, + rand_filter.y, + rand_time_lens.y, + rand_time_lens.z, + rand_time_lens.x, + ray); } /* Return false to indicate that this pixel is finished. diff --git a/intern/cycles/kernel/integrator/path_state.h b/intern/cycles/kernel/integrator/path_state.h index 9d8ecdc47b4..8d90a9f6067 100644 --- a/intern/cycles/kernel/integrator/path_state.h +++ b/intern/cycles/kernel/integrator/path_state.h @@ -336,6 +336,14 @@ ccl_device_inline float2 path_state_rng_2D(KernelGlobals kg, kg, rng_state->rng_hash, rng_state->sample, rng_state->rng_offset + dimension); } +ccl_device_inline float3 path_state_rng_3D(KernelGlobals kg, + ccl_private const RNGState *rng_state, + const int dimension) +{ + return path_rng_3D( + kg, rng_state->rng_hash, rng_state->sample, rng_state->rng_offset + dimension); +} + ccl_device_inline float path_branched_rng_1D(KernelGlobals kg, ccl_private const RNGState *rng_state, const int branch, @@ -360,6 +368,18 @@ ccl_device_inline float2 path_branched_rng_2D(KernelGlobals kg, rng_state->rng_offset + dimension); } +ccl_device_inline float3 path_branched_rng_3D(KernelGlobals kg, + ccl_private const RNGState *rng_state, + const int branch, + const int num_branches, + const int dimension) +{ + return path_rng_3D(kg, + rng_state->rng_hash, + rng_state->sample * num_branches + branch, + rng_state->rng_offset + dimension); +} + /* Utility functions to get light termination value, * since it might not be needed in many cases. */ diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 113ebb60c20..19bec243757 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -147,10 +147,11 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg, { const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); const uint bounce = INTEGRATOR_STATE(state, path, bounce); - const float2 rand_light = path_state_rng_2D(kg, rng_state, PRNG_LIGHT); + const float3 rand_light = path_state_rng_3D(kg, rng_state, PRNG_LIGHT); if (!light_sample_from_position(kg, rng_state, + rand_light.z, rand_light.x, rand_light.y, sd->time, diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h index 4129b78feb0..0323738c09b 100644 --- a/intern/cycles/kernel/integrator/shade_volume.h +++ b/intern/cycles/kernel/integrator/shade_volume.h @@ -702,10 +702,11 @@ ccl_device_forceinline bool integrate_volume_equiangular_sample_light( /* Sample position on a light. */ const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); const uint bounce = INTEGRATOR_STATE(state, path, bounce); - const float2 rand_light = path_state_rng_2D(kg, rng_state, PRNG_LIGHT); + const float3 rand_light = path_state_rng_3D(kg, rng_state, PRNG_LIGHT); LightSample ls ccl_optional_struct_init; if (!light_sample_from_volume_segment(kg, + rand_light.z, rand_light.x, rand_light.y, sd->time, @@ -765,10 +766,11 @@ ccl_device_forceinline void integrate_volume_direct_light( { const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); const uint bounce = INTEGRATOR_STATE(state, path, bounce); - const float2 rand_light = path_state_rng_2D(kg, rng_state, PRNG_LIGHT); + const float3 rand_light = path_state_rng_3D(kg, rng_state, PRNG_LIGHT); if (!light_sample_from_position(kg, rng_state, + rand_light.z, rand_light.x, rand_light.y, sd->time, diff --git a/intern/cycles/kernel/light/distribution.h b/intern/cycles/kernel/light/distribution.h index 97c60376748..3ce65b4bfe9 100644 --- a/intern/cycles/kernel/light/distribution.h +++ b/intern/cycles/kernel/light/distribution.h @@ -11,7 +11,7 @@ CCL_NAMESPACE_BEGIN /* Simple CDF based sampling over all lights in the scene, without taking into * account shading position or normal. */ -ccl_device int light_distribution_sample(KernelGlobals kg, ccl_private float *randu) +ccl_device int light_distribution_sample(KernelGlobals kg, const float randn) { /* This is basically std::upper_bound as used by PBRT, to find a point light or * triangle to emit from, proportional to area. a good improvement would be to @@ -19,7 +19,7 @@ ccl_device int light_distribution_sample(KernelGlobals kg, ccl_private float *ra * arbitrary shaders. */ int first = 0; int len = kernel_data.integrator.num_distribution + 1; - float r = *randu; + float r = randn; do { int half_len = len >> 1; @@ -38,18 +38,13 @@ ccl_device int light_distribution_sample(KernelGlobals kg, ccl_private float *ra * make this fail on rare occasions. */ int index = clamp(first - 1, 0, kernel_data.integrator.num_distribution - 1); - /* Rescale to reuse random number. this helps the 2D samples within - * each area light be stratified as well. */ - float distr_min = kernel_data_fetch(light_distribution, index).totarea; - float distr_max = kernel_data_fetch(light_distribution, index + 1).totarea; - *randu = (r - distr_min) / (distr_max - distr_min); - return index; } template ccl_device_noinline bool light_distribution_sample(KernelGlobals kg, - float randu, + const float randn, + const float randu, const float randv, const float time, const float3 P, @@ -58,7 +53,7 @@ ccl_device_noinline bool light_distribution_sample(KernelGlobals kg, ccl_private LightSample *ls) { /* Sample light index from distribution. */ - const int index = light_distribution_sample(kg, &randu); + const int index = light_distribution_sample(kg, randn); const float pdf_selection = kernel_data.integrator.distribution_pdf_lights; return light_sample( kg, randu, randv, time, P, bounce, path_flag, index, pdf_selection, ls); diff --git a/intern/cycles/kernel/light/sample.h b/intern/cycles/kernel/light/sample.h index 8dfaf329e43..423024c6b3d 100644 --- a/intern/cycles/kernel/light/sample.h +++ b/intern/cycles/kernel/light/sample.h @@ -324,7 +324,8 @@ ccl_device_inline float light_sample_mis_weight_nee(KernelGlobals kg, * Uses either a flat distribution or light tree. */ ccl_device_inline bool light_sample_from_volume_segment(KernelGlobals kg, - float randu, + const float randn, + const float randu, const float randv, const float time, const float3 P, @@ -337,17 +338,19 @@ ccl_device_inline bool light_sample_from_volume_segment(KernelGlobals kg, #ifdef __LIGHT_TREE__ if (kernel_data.integrator.use_light_tree) { return light_tree_sample( - kg, randu, randv, time, P, D, t, SD_BSDF_HAS_TRANSMISSION, bounce, path_flag, ls); + kg, randn, randu, randv, time, P, D, t, SD_BSDF_HAS_TRANSMISSION, bounce, path_flag, ls); } else #endif { - return light_distribution_sample(kg, randu, randv, time, P, bounce, path_flag, ls); + return light_distribution_sample( + kg, randn, randu, randv, time, P, bounce, path_flag, ls); } } ccl_device bool light_sample_from_position(KernelGlobals kg, ccl_private const RNGState *rng_state, + const float randn, const float randu, const float randv, const float time, @@ -361,12 +364,13 @@ ccl_device bool light_sample_from_position(KernelGlobals kg, #ifdef __LIGHT_TREE__ if (kernel_data.integrator.use_light_tree) { return light_tree_sample( - kg, randu, randv, time, P, N, 0, shader_flags, bounce, path_flag, ls); + kg, randn, randu, randv, time, P, N, 0, shader_flags, bounce, path_flag, ls); } else #endif { - return light_distribution_sample(kg, randu, randv, time, P, bounce, path_flag, ls); + return light_distribution_sample( + kg, randn, randu, randv, time, P, bounce, path_flag, ls); } } diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 19fdb87f803..3c6f118ace3 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -551,8 +551,9 @@ ccl_device bool get_left_probability(KernelGlobals kg, template ccl_device_noinline bool light_tree_sample(KernelGlobals kg, - float randu, - float randv, + float randn, + const float randu, + const float randv, const float time, const float3 P, const float3 N_or_D, @@ -580,7 +581,7 @@ ccl_device_noinline bool light_tree_sample(KernelGlobals kg, if (knode->child_index <= 0) { /* At a leaf node, we pick an emitter. */ selected_emitter = light_tree_cluster_select_emitter( - kg, randv, P, N_or_D, t, has_transmission, knode, &pdf_selection); + kg, randn, P, N_or_D, t, has_transmission, knode, &pdf_selection); break; } @@ -598,7 +599,7 @@ ccl_device_noinline bool light_tree_sample(KernelGlobals kg, float discard; float total_prob = left_prob; node_index = left_index; - sample_resevoir(right_index, 1.0f - left_prob, node_index, discard, total_prob, randu); + sample_resevoir(right_index, 1.0f - left_prob, node_index, discard, total_prob, randn); pdf_leaf *= (node_index == left_index) ? left_prob : (1.0f - left_prob); } diff --git a/intern/cycles/kernel/sample/jitter.h b/intern/cycles/kernel/sample/jitter.h deleted file mode 100644 index 1cde9f9d3de..00000000000 --- a/intern/cycles/kernel/sample/jitter.h +++ /dev/null @@ -1,90 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2011-2022 Blender Foundation */ - -#include "kernel/sample/util.h" -#include "util/hash.h" - -#pragma once -CCL_NAMESPACE_BEGIN - -ccl_device uint pmj_shuffled_sample_index(KernelGlobals kg, uint sample, uint dimension, uint seed) -{ - const uint sample_count = kernel_data.integrator.pmj_sequence_size; - - /* Shuffle the pattern order and sample index to better decorrelate - * dimensions and make the most of the finite patterns we have. - * The funky sample mask stuff is to ensure that we only shuffle - * *within* the current sample pattern, which is necessary to avoid - * early repeat pattern use. */ - const uint pattern_i = hash_shuffle_uint(dimension, NUM_PMJ_PATTERNS, seed); - /* sample_count should always be a power of two, so this results in a mask. */ - const uint sample_mask = sample_count - 1; - const uint sample_shuffled = nested_uniform_scramble(sample, - hash_wang_seeded_uint(dimension, seed)); - sample = (sample & ~sample_mask) | (sample_shuffled & sample_mask); - - return ((pattern_i * sample_count) + sample) % (sample_count * NUM_PMJ_PATTERNS); -} - -ccl_device float pmj_sample_1D(KernelGlobals kg, - uint sample, - const uint rng_hash, - const uint dimension) -{ - uint seed = rng_hash; - - /* Use the same sample sequence seed for all pixels when using - * scrambling distance. */ - if (kernel_data.integrator.scrambling_distance < 1.0f) { - seed = kernel_data.integrator.seed; - } - - /* Fetch the sample. */ - const uint index = pmj_shuffled_sample_index(kg, sample, dimension, seed); - float x = kernel_data_fetch(sample_pattern_lut, index * NUM_PMJ_DIMENSIONS); - - /* Do limited Cranley-Patterson rotation when using scrambling distance. */ - if (kernel_data.integrator.scrambling_distance < 1.0f) { - const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) * - kernel_data.integrator.scrambling_distance; - x += jitter_x; - x -= floorf(x); - } - - return x; -} - -ccl_device float2 pmj_sample_2D(KernelGlobals kg, - uint sample, - const uint rng_hash, - const uint dimension) -{ - uint seed = rng_hash; - - /* Use the same sample sequence seed for all pixels when using - * scrambling distance. */ - if (kernel_data.integrator.scrambling_distance < 1.0f) { - seed = kernel_data.integrator.seed; - } - - /* Fetch the sample. */ - const uint index = pmj_shuffled_sample_index(kg, sample, dimension, seed); - float x = kernel_data_fetch(sample_pattern_lut, index * NUM_PMJ_DIMENSIONS); - float y = kernel_data_fetch(sample_pattern_lut, index * NUM_PMJ_DIMENSIONS + 1); - - /* Do limited Cranley-Patterson rotation when using scrambling distance. */ - if (kernel_data.integrator.scrambling_distance < 1.0f) { - const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) * - kernel_data.integrator.scrambling_distance; - const float jitter_y = hash_wang_seeded_float(dimension, rng_hash ^ 0xca0e1151) * - kernel_data.integrator.scrambling_distance; - x += jitter_x; - y += jitter_y; - x -= floorf(x); - y -= floorf(y); - } - - return make_float2(x, y); -} - -CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/sample/pattern.h b/intern/cycles/kernel/sample/pattern.h index e12f333b3a5..f6f1de448e0 100644 --- a/intern/cycles/kernel/sample/pattern.h +++ b/intern/cycles/kernel/sample/pattern.h @@ -3,7 +3,7 @@ #pragma once -#include "kernel/sample/jitter.h" +#include "kernel/sample/tabulated_sobol.h" #include "kernel/sample/sobol_burley.h" #include "util/hash.h" @@ -26,7 +26,7 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals kg, return sobol_burley_sample_1D(sample, dimension, rng_hash); } else { - return pmj_sample_1D(kg, sample, rng_hash, dimension); + return tabulated_sobol_sample_1D(kg, sample, rng_hash, dimension); } } @@ -43,7 +43,41 @@ ccl_device_forceinline float2 path_rng_2D(KernelGlobals kg, return sobol_burley_sample_2D(sample, dimension, rng_hash); } else { - return pmj_sample_2D(kg, sample, rng_hash, dimension); + return tabulated_sobol_sample_2D(kg, sample, rng_hash, dimension); + } +} + +ccl_device_forceinline float3 path_rng_3D(KernelGlobals kg, + uint rng_hash, + int sample, + int dimension) +{ +#ifdef __DEBUG_CORRELATION__ + return make_float3((float)drand48(), (float)drand48(), (float)drand48()); +#endif + + if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) { + return sobol_burley_sample_3D(sample, dimension, rng_hash); + } + else { + return tabulated_sobol_sample_3D(kg, sample, rng_hash, dimension); + } +} + +ccl_device_forceinline float4 path_rng_4D(KernelGlobals kg, + uint rng_hash, + int sample, + int dimension) +{ +#ifdef __DEBUG_CORRELATION__ + return make_float4((float)drand48(), (float)drand48(), (float)drand48(), (float)drand48()); +#endif + + if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) { + return sobol_burley_sample_4D(sample, dimension, rng_hash); + } + else { + return tabulated_sobol_sample_4D(kg, sample, rng_hash, dimension); } } @@ -97,7 +131,7 @@ ccl_device_inline uint path_rng_hash_init(KernelGlobals kg, ccl_device_inline bool sample_is_class_A(int pattern, int sample) { #if 0 - if (!(pattern == SAMPLING_PATTERN_PMJ || pattern == SAMPLING_PATTERN_SOBOL_BURLEY)) { + if (!(pattern == SAMPLING_PATTERN_TABULATED_SOBOL || pattern == SAMPLING_PATTERN_SOBOL_BURLEY)) { /* Fallback: assign samples randomly. * This is guaranteed to work "okay" for any sampler, but isn't good. * (NOTE: the seed constant is just a random number to guard against @@ -114,8 +148,8 @@ ccl_device_inline bool sample_is_class_A(int pattern, int sample) * Multi-Jittered Sample Sequences" by Christensen et al., but * implemented with efficient bit-fiddling. * - * This approach also turns out to work equally well with Sobol-Burley - * (see https://developer.blender.org/D15746#429471). + * This approach also turns out to work equally well with Owen + * scrambled and shuffled Sobol (see https://developer.blender.org/D15746#429471). */ return popcount(uint(sample) & 0xaaaaaaaa) & 1; } diff --git a/intern/cycles/kernel/sample/tabulated_sobol.h b/intern/cycles/kernel/sample/tabulated_sobol.h new file mode 100644 index 00000000000..7d4d2ee1a95 --- /dev/null +++ b/intern/cycles/kernel/sample/tabulated_sobol.h @@ -0,0 +1,174 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2011-2022 Blender Foundation */ + +#include "kernel/sample/util.h" +#include "util/hash.h" + +#pragma once +CCL_NAMESPACE_BEGIN + +ccl_device uint tabulated_sobol_shuffled_sample_index(KernelGlobals kg, + uint sample, + uint dimension, + uint seed) +{ + const uint sample_count = kernel_data.integrator.tabulated_sobol_sequence_size; + + /* Shuffle the pattern order and sample index to decorrelate + * dimensions and make the most of the finite patterns we have. + * The funky sample mask stuff is to ensure that we only shuffle + * *within* the current sample pattern, which is necessary to avoid + * early repeat pattern use. */ + const uint pattern_i = hash_shuffle_uint(dimension, NUM_TAB_SOBOL_PATTERNS, seed); + /* sample_count should always be a power of two, so this results in a mask. */ + const uint sample_mask = sample_count - 1; + const uint sample_shuffled = nested_uniform_scramble(sample, + hash_wang_seeded_uint(dimension, seed)); + sample = (sample & ~sample_mask) | (sample_shuffled & sample_mask); + + return ((pattern_i * sample_count) + sample) % (sample_count * NUM_TAB_SOBOL_PATTERNS); +} + +ccl_device float tabulated_sobol_sample_1D(KernelGlobals kg, + uint sample, + const uint rng_hash, + const uint dimension) +{ + uint seed = rng_hash; + + /* Use the same sample sequence seed for all pixels when using + * scrambling distance. */ + if (kernel_data.integrator.scrambling_distance < 1.0f) { + seed = kernel_data.integrator.seed; + } + + /* Fetch the sample. */ + const uint index = tabulated_sobol_shuffled_sample_index(kg, sample, dimension, seed); + float x = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS); + + /* Do limited Cranley-Patterson rotation when using scrambling distance. */ + if (kernel_data.integrator.scrambling_distance < 1.0f) { + const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) * + kernel_data.integrator.scrambling_distance; + x += jitter_x; + x -= floorf(x); + } + + return x; +} + +ccl_device float2 tabulated_sobol_sample_2D(KernelGlobals kg, + uint sample, + const uint rng_hash, + const uint dimension) +{ + uint seed = rng_hash; + + /* Use the same sample sequence seed for all pixels when using + * scrambling distance. */ + if (kernel_data.integrator.scrambling_distance < 1.0f) { + seed = kernel_data.integrator.seed; + } + + /* Fetch the sample. */ + const uint index = tabulated_sobol_shuffled_sample_index(kg, sample, dimension, seed); + float x = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS); + float y = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 1); + + /* Do limited Cranley-Patterson rotation when using scrambling distance. */ + if (kernel_data.integrator.scrambling_distance < 1.0f) { + const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) * + kernel_data.integrator.scrambling_distance; + const float jitter_y = hash_wang_seeded_float(dimension, rng_hash ^ 0xca0e1151) * + kernel_data.integrator.scrambling_distance; + x += jitter_x; + y += jitter_y; + x -= floorf(x); + y -= floorf(y); + } + + return make_float2(x, y); +} + +ccl_device float3 tabulated_sobol_sample_3D(KernelGlobals kg, + uint sample, + const uint rng_hash, + const uint dimension) +{ + uint seed = rng_hash; + + /* Use the same sample sequence seed for all pixels when using + * scrambling distance. */ + if (kernel_data.integrator.scrambling_distance < 1.0f) { + seed = kernel_data.integrator.seed; + } + + /* Fetch the sample. */ + const uint index = tabulated_sobol_shuffled_sample_index(kg, sample, dimension, seed); + float x = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS); + float y = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 1); + float z = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 2); + + /* Do limited Cranley-Patterson rotation when using scrambling distance. */ + if (kernel_data.integrator.scrambling_distance < 1.0f) { + const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) * + kernel_data.integrator.scrambling_distance; + const float jitter_y = hash_wang_seeded_float(dimension, rng_hash ^ 0xca0e1151) * + kernel_data.integrator.scrambling_distance; + const float jitter_z = hash_wang_seeded_float(dimension, rng_hash ^ 0xbf604c5a) * + kernel_data.integrator.scrambling_distance; + x += jitter_x; + y += jitter_y; + z += jitter_z; + x -= floorf(x); + y -= floorf(y); + z -= floorf(z); + } + + return make_float3(x, y, z); +} + +ccl_device float4 tabulated_sobol_sample_4D(KernelGlobals kg, + uint sample, + const uint rng_hash, + const uint dimension) +{ + uint seed = rng_hash; + + /* Use the same sample sequence seed for all pixels when using + * scrambling distance. */ + if (kernel_data.integrator.scrambling_distance < 1.0f) { + seed = kernel_data.integrator.seed; + } + + /* Fetch the sample. */ + const uint index = tabulated_sobol_shuffled_sample_index(kg, sample, dimension, seed); + float x = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS); + float y = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 1); + float z = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 2); + float w = kernel_data_fetch(sample_pattern_lut, index * NUM_TAB_SOBOL_DIMENSIONS + 3); + + /* Do limited Cranley-Patterson rotation when using scrambling distance. */ + if (kernel_data.integrator.scrambling_distance < 1.0f) { + const float jitter_x = hash_wang_seeded_float(dimension, rng_hash) * + kernel_data.integrator.scrambling_distance; + const float jitter_y = hash_wang_seeded_float(dimension, rng_hash ^ 0xca0e1151) * + kernel_data.integrator.scrambling_distance; + const float jitter_z = hash_wang_seeded_float(dimension, rng_hash ^ 0xbf604c5a) * + kernel_data.integrator.scrambling_distance; + const float jitter_w = hash_wang_seeded_float(dimension, rng_hash ^ 0x99634d1d) * + kernel_data.integrator.scrambling_distance; + x += jitter_x; + y += jitter_y; + z += jitter_z; + w += jitter_w; + x -= floorf(x); + y -= floorf(y); + z -= floorf(z); + w -= floorf(w); + } + + return make_float4(x, y, z, w); +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index ff28f27a655..69b73d78417 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -148,8 +148,7 @@ CCL_NAMESPACE_BEGIN enum PathTraceDimension { /* Init bounce */ PRNG_FILTER = 0, - PRNG_LENS = 1, - PRNG_TIME = 2, + PRNG_LENS_TIME = 1, /* Shade bounce */ PRNG_TERMINATE = 0, @@ -187,7 +186,7 @@ enum PathTraceDimension { enum SamplingPattern { SAMPLING_PATTERN_SOBOL_BURLEY = 0, - SAMPLING_PATTERN_PMJ = 1, + SAMPLING_PATTERN_TABULATED_SOBOL = 1, SAMPLING_NUM_PATTERNS, }; @@ -1032,13 +1031,28 @@ typedef struct LocalIntersection { typedef struct KernelCamera { /* type */ int type; + int use_dof_or_motion_blur; + + /* depth of field */ + float aperturesize; + float blades; + float bladesrotation; + float focaldistance; + + /* motion blur */ + float shuttertime; + int num_motion_steps, have_perspective_motion; + + int pad1; + int pad2; + int pad3; /* panorama */ int panorama_type; float fisheye_fov; float fisheye_lens; - float4 equirectangular_range; float fisheye_lens_polynomial_bias; + float4 equirectangular_range; float4 fisheye_lens_polynomial_coefficients; /* stereo */ @@ -1055,16 +1069,6 @@ typedef struct KernelCamera { float4 dx; float4 dy; - /* depth of field */ - float aperturesize; - float blades; - float bladesrotation; - float focaldistance; - - /* motion blur */ - float shuttertime; - int num_motion_steps, have_perspective_motion; - /* clipping */ float nearclip; float cliplength; @@ -1075,7 +1079,6 @@ typedef struct KernelCamera { /* render size */ float width, height; - int pad1; /* anamorphic lens bokeh */ float inv_aperture_ratio; @@ -1466,15 +1469,15 @@ typedef struct KernelShaderEvalInput { } KernelShaderEvalInput; static_assert_align(KernelShaderEvalInput, 16); -/* Pre-computed sample table sizes for PMJ02 sampler. +/* Pre-computed sample table sizes for the tabulated Sobol sampler. * * NOTE: min and max samples *must* be a power of two, and patterns * ideally should be as well. */ -#define MIN_PMJ_SAMPLES 256 -#define MAX_PMJ_SAMPLES 8192 -#define NUM_PMJ_DIMENSIONS 2 -#define NUM_PMJ_PATTERNS 256 +#define MIN_TAB_SOBOL_SAMPLES 256 +#define MAX_TAB_SOBOL_SAMPLES 8192 +#define NUM_TAB_SOBOL_DIMENSIONS 4 +#define NUM_TAB_SOBOL_PATTERNS 256 /* Device kernels. * diff --git a/intern/cycles/scene/CMakeLists.txt b/intern/cycles/scene/CMakeLists.txt index bb9915d6550..759a25ab7cb 100644 --- a/intern/cycles/scene/CMakeLists.txt +++ b/intern/cycles/scene/CMakeLists.txt @@ -23,7 +23,6 @@ set(SRC image_sky.cpp image_vdb.cpp integrator.cpp - jitter.cpp light.cpp light_tree.cpp mesh.cpp @@ -43,6 +42,7 @@ set(SRC stats.cpp svm.cpp tables.cpp + tabulated_sobol.cpp volume.cpp ) @@ -65,7 +65,6 @@ set(SRC_HEADERS integrator.h light.h light_tree.h - jitter.h mesh.h object.h osl.h @@ -81,6 +80,7 @@ set(SRC_HEADERS stats.h svm.h tables.h + tabulated_sobol.h volume.h ) diff --git a/intern/cycles/scene/integrator.cpp b/intern/cycles/scene/integrator.cpp index 1aaac121c31..ba376e8ba99 100644 --- a/intern/cycles/scene/integrator.cpp +++ b/intern/cycles/scene/integrator.cpp @@ -8,12 +8,12 @@ #include "scene/camera.h" #include "scene/film.h" #include "scene/integrator.h" -#include "scene/jitter.h" #include "scene/light.h" #include "scene/object.h" #include "scene/scene.h" #include "scene/shader.h" #include "scene/stats.h" +#include "scene/tabulated_sobol.h" #include "kernel/types.h" @@ -107,8 +107,11 @@ NODE_DEFINE(Integrator) static NodeEnum sampling_pattern_enum; sampling_pattern_enum.insert("sobol_burley", SAMPLING_PATTERN_SOBOL_BURLEY); - sampling_pattern_enum.insert("pmj", SAMPLING_PATTERN_PMJ); - SOCKET_ENUM(sampling_pattern, "Sampling Pattern", sampling_pattern_enum, SAMPLING_PATTERN_PMJ); + sampling_pattern_enum.insert("tabulated_sobol", SAMPLING_PATTERN_TABULATED_SOBOL); + SOCKET_ENUM(sampling_pattern, + "Sampling Pattern", + sampling_pattern_enum, + SAMPLING_PATTERN_TABULATED_SOBOL); SOCKET_FLOAT(scrambling_distance, "Scrambling Distance", 1.0f); static NodeEnum denoiser_type_enum; @@ -259,23 +262,23 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene kintegrator->light_inv_rr_threshold = 0.0f; } - constexpr int num_sequences = NUM_PMJ_PATTERNS; - int sequence_size = clamp(next_power_of_two(aa_samples - 1), MIN_PMJ_SAMPLES, MAX_PMJ_SAMPLES); - if (kintegrator->sampling_pattern == SAMPLING_PATTERN_PMJ && + /* Build pre-tabulated Sobol samples if needed. */ + int sequence_size = clamp( + next_power_of_two(aa_samples - 1), MIN_TAB_SOBOL_SAMPLES, MAX_TAB_SOBOL_SAMPLES); + if (kintegrator->sampling_pattern == SAMPLING_PATTERN_TABULATED_SOBOL && dscene->sample_pattern_lut.size() != - (sequence_size * NUM_PMJ_DIMENSIONS * NUM_PMJ_PATTERNS)) { - kintegrator->pmj_sequence_size = sequence_size; + (sequence_size * NUM_TAB_SOBOL_PATTERNS * NUM_TAB_SOBOL_DIMENSIONS)) { + kintegrator->tabulated_sobol_sequence_size = sequence_size; if (dscene->sample_pattern_lut.size() != 0) { dscene->sample_pattern_lut.free(); } - float2 *directions = (float2 *)dscene->sample_pattern_lut.alloc(sequence_size * num_sequences * - NUM_PMJ_DIMENSIONS); + float4 *directions = (float4 *)dscene->sample_pattern_lut.alloc( + sequence_size * NUM_TAB_SOBOL_PATTERNS * NUM_TAB_SOBOL_DIMENSIONS); TaskPool pool; - for (int j = 0; j < num_sequences; ++j) { - float2 *sequence = directions + j * sequence_size; - pool.push( - function_bind(&progressive_multi_jitter_02_generate_2D, sequence, sequence_size, j)); + for (int j = 0; j < NUM_TAB_SOBOL_PATTERNS; ++j) { + float4 *sequence = directions + j * sequence_size; + pool.push(function_bind(&tabulated_sobol_generate_4D, sequence, sequence_size, j)); } pool.wait_work(); diff --git a/intern/cycles/scene/jitter.cpp b/intern/cycles/scene/jitter.cpp deleted file mode 100644 index 8287a029752..00000000000 --- a/intern/cycles/scene/jitter.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2019-2022 Blender Foundation */ - -/* This file is based on "Progressive Multi-Jittered Sample Sequences" - * by Christensen, Kensler, and Kilpatrick, but with a much simpler and - * faster implementation based on "Stochastic Generation of (t, s) - * Sample Sequences" by Helmer, Christensen, and Kensler. - */ - -#include "scene/jitter.h" -#include "util/hash.h" - -#include -#include - -CCL_NAMESPACE_BEGIN - -void progressive_multi_jitter_02_generate_2D(float2 points[], int size, int rng_seed) -{ - /* Xor values for generating the PMJ02 sequence. These permute the - * order we visit the strata in, which is what makes the code below - * produce the PMJ02 sequence. Other choices are also possible, but - * result in different sequences. */ - static uint xors[2][32] = { - {0x00000000, 0x00000000, 0x00000002, 0x00000006, 0x00000006, 0x0000000e, 0x00000036, - 0x0000004e, 0x00000016, 0x0000002e, 0x00000276, 0x000006ce, 0x00000716, 0x00000c2e, - 0x00003076, 0x000040ce, 0x00000116, 0x0000022e, 0x00020676, 0x00060ece, 0x00061716, - 0x000e2c2e, 0x00367076, 0x004ec0ce, 0x00170116, 0x002c022e, 0x02700676, 0x06c00ece, - 0x07001716, 0x0c002c2e, 0x30007076, 0x4000c0ce}, - {0x00000000, 0x00000001, 0x00000003, 0x00000003, 0x00000007, 0x0000001b, 0x00000027, - 0x0000000b, 0x00000017, 0x0000013b, 0x00000367, 0x0000038b, 0x00000617, 0x0000183b, - 0x00002067, 0x0000008b, 0x00000117, 0x0001033b, 0x00030767, 0x00030b8b, 0x00071617, - 0x001b383b, 0x00276067, 0x000b808b, 0x00160117, 0x0138033b, 0x03600767, 0x03800b8b, - 0x06001617, 0x1800383b, 0x20006067, 0x0000808b}}; - - uint rng_i = rng_seed; - - points[0].x = hash_hp_float(rng_i++); - points[0].y = hash_hp_float(rng_i++); - - /* Subdivide the domain into smaller and smaller strata, filling in new - * points as we go. */ - for (int log_N = 0, N = 1; N < size; log_N++, N *= 2) { - float strata_count = (float)(N * 2); - for (int i = 0; i < N && (N + i) < size; i++) { - /* Find the strata that are already occupied in this cell. */ - uint occupied_x_stratum = (uint)(points[i ^ xors[0][log_N]].x * strata_count); - uint occupied_y_stratum = (uint)(points[i ^ xors[1][log_N]].y * strata_count); - - /* Generate a new point in the unoccupied strata. */ - points[N + i].x = ((float)(occupied_x_stratum ^ 1) + hash_hp_float(rng_i++)) / strata_count; - points[N + i].y = ((float)(occupied_y_stratum ^ 1) + hash_hp_float(rng_i++)) / strata_count; - } - } -} - -CCL_NAMESPACE_END diff --git a/intern/cycles/scene/jitter.h b/intern/cycles/scene/jitter.h deleted file mode 100644 index 8d497d5e9f5..00000000000 --- a/intern/cycles/scene/jitter.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2019-2022 Blender Foundation */ - -#ifndef __JITTER_H__ -#define __JITTER_H__ - -#include "util/types.h" - -CCL_NAMESPACE_BEGIN - -void progressive_multi_jitter_02_generate_2D(float2 points[], int size, int rng_seed); - -CCL_NAMESPACE_END - -#endif /* __JITTER_H__ */ diff --git a/intern/cycles/scene/tabulated_sobol.cpp b/intern/cycles/scene/tabulated_sobol.cpp new file mode 100644 index 00000000000..5d2f96da9de --- /dev/null +++ b/intern/cycles/scene/tabulated_sobol.cpp @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2019-2022 Blender Foundation */ + +/* This file is based on the paper "Stochastic Generation of (t, s) + * Sample Sequences" by Helmer, Christensen, and Kensler. + */ + +#include "scene/tabulated_sobol.h" +#include "util/hash.h" + +#include +#include + +CCL_NAMESPACE_BEGIN + +void tabulated_sobol_generate_4D(float4 points[], int size, int rng_seed) +{ + /* Xor values for generating the (4D) Owen-scrambled Sobol sequence. + * These permute the order we visit the strata in, which is what + * makes the code below produce the scrambled Sobol sequence. Other + * choices are also possible, but result in different sequences. */ + static uint xors[4][32] = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0x00000000, 0x00000001, 0x00000001, 0x00000007, 0x00000001, 0x00000013, 0x00000015, + 0x0000007f, 0x00000001, 0x00000103, 0x00000105, 0x0000070f, 0x00000111, 0x00001333, + 0x00001555, 0x00007fff, 0x00000001, 0x00010003, 0x00010005, 0x0007000f, 0x00010011, + 0x00130033, 0x00150055, 0x007f00ff, 0x00010101, 0x01030303, 0x01050505, 0x070f0f0f, + 0x01111111, 0x13333333, 0x15555555, 0x7fffffff}, + {0x00000000, 0x00000001, 0x00000003, 0x00000001, 0x00000005, 0x0000001f, 0x0000002b, + 0x0000003d, 0x00000011, 0x00000133, 0x00000377, 0x00000199, 0x00000445, 0x00001ccf, + 0x00002ddb, 0x0000366d, 0x00000101, 0x00010303, 0x00030707, 0x00010909, 0x00051515, + 0x001f3f3f, 0x002b6b6b, 0x003dbdbd, 0x00101011, 0x01303033, 0x03707077, 0x01909099, + 0x04515145, 0x1cf3f3cf, 0x2db6b6db, 0x36dbdb6d}, + {0x00000000, 0x00000001, 0x00000000, 0x00000003, 0x0000000d, 0x0000000c, 0x00000005, + 0x0000004f, 0x00000014, 0x000000e7, 0x00000329, 0x0000039c, 0x00000011, 0x00001033, + 0x00000044, 0x000030bb, 0x0000d1cd, 0x0000c2ec, 0x00005415, 0x0004fc3f, 0x00015054, + 0x000e5c97, 0x0032e5b9, 0x0039725c, 0x00000101, 0x01000303, 0x00000404, 0x03000b0b, + 0x0d001d1d, 0x0c002c2c, 0x05004545, 0x4f00cfcf}, + }; + + /* Randomize the seed, in case it's incrementing. The constant is just a + * random number, and has no other significance. */ + uint rng_i = hash_hp_seeded_uint(rng_seed, 0x44605a73); + + points[0].x = hash_hp_float(rng_i++); + points[0].y = hash_hp_float(rng_i++); + points[0].z = hash_hp_float(rng_i++); + points[0].w = hash_hp_float(rng_i++); + + /* Subdivide the domain into smaller and smaller strata, filling in new + * points as we go. */ + for (int log_N = 0, N = 1; N < size; log_N++, N *= 2) { + float strata_count = (float)(N * 2); + for (int i = 0; i < N && (N + i) < size; i++) { + /* Find the strata that are already occupied in this cell. */ + uint occupied_x_stratum = (uint)(points[i ^ xors[0][log_N]].x * strata_count); + uint occupied_y_stratum = (uint)(points[i ^ xors[1][log_N]].y * strata_count); + uint occupied_z_stratum = (uint)(points[i ^ xors[2][log_N]].z * strata_count); + uint occupied_w_stratum = (uint)(points[i ^ xors[3][log_N]].w * strata_count); + + /* Generate a new point in the unoccupied strata. */ + points[N + i].x = ((float)(occupied_x_stratum ^ 1) + hash_hp_float(rng_i++)) / strata_count; + points[N + i].y = ((float)(occupied_y_stratum ^ 1) + hash_hp_float(rng_i++)) / strata_count; + points[N + i].z = ((float)(occupied_z_stratum ^ 1) + hash_hp_float(rng_i++)) / strata_count; + points[N + i].w = ((float)(occupied_w_stratum ^ 1) + hash_hp_float(rng_i++)) / strata_count; + } + } +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/scene/tabulated_sobol.h b/intern/cycles/scene/tabulated_sobol.h new file mode 100644 index 00000000000..31d9bb8e93c --- /dev/null +++ b/intern/cycles/scene/tabulated_sobol.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2019-2022 Blender Foundation */ + +#ifndef __TABULATED_SOBOL_H__ +#define __TABULATED_SOBOL_H__ + +#include "util/types.h" + +CCL_NAMESPACE_BEGIN + +void tabulated_sobol_generate_4D(float4 points[], int size, int rng_seed); + +CCL_NAMESPACE_END + +#endif /* __TABULATED_SOBOL_H__ */ From d9192aaa6d2a0a17bcfe158bade77314f0679cf7 Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Wed, 14 Dec 2022 16:43:12 +0100 Subject: [PATCH 0099/1522] Cycles: limit the internal sample index of Sobol-Burley for performance This is done based on the render sample count so that it doesn't impact sampling quality. It's similar in spirit to the adaptive table size in D16561, but in this case for performance rather than memory usage. Differential Revision: https://developer.blender.org/D16726 --- intern/cycles/kernel/data_template.h | 2 +- intern/cycles/kernel/sample/pattern.h | 14 ++-- intern/cycles/kernel/sample/sobol_burley.h | 86 +++++++++++++++++++--- intern/cycles/scene/integrator.cpp | 1 + 4 files changed, 88 insertions(+), 15 deletions(-) diff --git a/intern/cycles/kernel/data_template.h b/intern/cycles/kernel/data_template.h index af7a6d2ef41..ddc462e02f6 100644 --- a/intern/cycles/kernel/data_template.h +++ b/intern/cycles/kernel/data_template.h @@ -180,6 +180,7 @@ KERNEL_STRUCT_MEMBER(integrator, int, use_caustics) /* Sampling pattern. */ KERNEL_STRUCT_MEMBER(integrator, int, sampling_pattern) KERNEL_STRUCT_MEMBER(integrator, int, tabulated_sobol_sequence_size) +KERNEL_STRUCT_MEMBER(integrator, int, sobol_index_mask) KERNEL_STRUCT_MEMBER(integrator, float, scrambling_distance) /* Volume render. */ KERNEL_STRUCT_MEMBER(integrator, int, use_volumes) @@ -204,7 +205,6 @@ KERNEL_STRUCT_MEMBER(integrator, int, use_guiding_mis_weights) /* Padding. */ KERNEL_STRUCT_MEMBER(integrator, int, pad1) -KERNEL_STRUCT_MEMBER(integrator, int, pad2) KERNEL_STRUCT_END(KernelIntegrator) /* SVM. For shader specialization. */ diff --git a/intern/cycles/kernel/sample/pattern.h b/intern/cycles/kernel/sample/pattern.h index f6f1de448e0..71018bb1e91 100644 --- a/intern/cycles/kernel/sample/pattern.h +++ b/intern/cycles/kernel/sample/pattern.h @@ -3,8 +3,8 @@ #pragma once -#include "kernel/sample/tabulated_sobol.h" #include "kernel/sample/sobol_burley.h" +#include "kernel/sample/tabulated_sobol.h" #include "util/hash.h" CCL_NAMESPACE_BEGIN @@ -23,7 +23,8 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals kg, #endif if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) { - return sobol_burley_sample_1D(sample, dimension, rng_hash); + const uint index_mask = kernel_data.integrator.sobol_index_mask; + return sobol_burley_sample_1D(sample, dimension, rng_hash, index_mask); } else { return tabulated_sobol_sample_1D(kg, sample, rng_hash, dimension); @@ -40,7 +41,8 @@ ccl_device_forceinline float2 path_rng_2D(KernelGlobals kg, #endif if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) { - return sobol_burley_sample_2D(sample, dimension, rng_hash); + const uint index_mask = kernel_data.integrator.sobol_index_mask; + return sobol_burley_sample_2D(sample, dimension, rng_hash, index_mask); } else { return tabulated_sobol_sample_2D(kg, sample, rng_hash, dimension); @@ -57,7 +59,8 @@ ccl_device_forceinline float3 path_rng_3D(KernelGlobals kg, #endif if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) { - return sobol_burley_sample_3D(sample, dimension, rng_hash); + const uint index_mask = kernel_data.integrator.sobol_index_mask; + return sobol_burley_sample_3D(sample, dimension, rng_hash, index_mask); } else { return tabulated_sobol_sample_3D(kg, sample, rng_hash, dimension); @@ -74,7 +77,8 @@ ccl_device_forceinline float4 path_rng_4D(KernelGlobals kg, #endif if (kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_SOBOL_BURLEY) { - return sobol_burley_sample_4D(sample, dimension, rng_hash); + const uint index_mask = kernel_data.integrator.sobol_index_mask; + return sobol_burley_sample_4D(sample, dimension, rng_hash, index_mask); } else { return tabulated_sobol_sample_4D(kg, sample, rng_hash, dimension); diff --git a/intern/cycles/kernel/sample/sobol_burley.h b/intern/cycles/kernel/sample/sobol_burley.h index 47796ae7998..f3fcde4ff62 100644 --- a/intern/cycles/kernel/sample/sobol_burley.h +++ b/intern/cycles/kernel/sample/sobol_burley.h @@ -65,31 +65,75 @@ ccl_device_forceinline float sobol_burley(uint rev_bit_index, } /* - * Computes a 1D Owen-scrambled and shuffled Sobol sample. + * NOTE: the functions below intentionally produce samples that are + * uncorrelated between functions. For example, a 1D sample and 2D + * sample produced with the same index, dimension, and seed are + * uncorrelated with each other. This allows more care-free usage + * of the functions together, without having to worry about + * e.g. 1D and 2D samples being accidentally correlated with each + * other. */ -ccl_device float sobol_burley_sample_1D(uint index, uint const dimension, uint seed) + +/* + * Computes a 1D Owen-scrambled and shuffled Sobol sample. + * + * `index` is the index of the sample in the sequence. + * + * `dimension` is which dimensions of the sample you want to fetch. Note + * that different 1D dimensions are uncorrelated. For samples with > 1D + * stratification, use the multi-dimensional sampling methods below. + * + * `seed`: different seeds produce statistically independent, + * uncorrelated sequences. + * + * `shuffled_index_mask` limits the sample sequence length, improving + * performance. It must be a string of binary 1 bits followed by a + * string of binary 0 bits (e.g. 0xffff0000) for the sampler to operate + * correctly. In general, `reverse_integer_bits(shuffled_index_mask)` + * should be >= the maximum number of samples expected to be taken. A safe + * default (but least performant) is 0xffffffff, for maximum sequence + * length. + */ +ccl_device float sobol_burley_sample_1D(uint index, + uint const dimension, + uint seed, + uint shuffled_index_mask) { /* Include the dimension in the seed, so we get decorrelated * sequences for different dimensions via shuffling. */ seed ^= hash_hp_uint(dimension); - /* Shuffle. */ + /* Shuffle and mask. The masking is just for better + * performance at low sample counts. */ index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xbff95bfe); + index &= shuffled_index_mask; return sobol_burley(index, 0, seed ^ 0x635c77bd); } /* * Computes a 2D Owen-scrambled and shuffled Sobol sample. + * + * `dimension_set` is which two dimensions of the sample you want to + * fetch. For example, 0 is the first two, 1 is the second two, etc. + * The dimensions within a single set are stratified, but different sets + * are uncorrelated. + * + * See sobol_burley_sample_1D for further usage details. */ -ccl_device float2 sobol_burley_sample_2D(uint index, const uint dimension_set, uint seed) +ccl_device float2 sobol_burley_sample_2D(uint index, + const uint dimension_set, + uint seed, + uint shuffled_index_mask) { /* Include the dimension set in the seed, so we get decorrelated * sequences for different dimension sets via shuffling. */ seed ^= hash_hp_uint(dimension_set); - /* Shuffle. */ + /* Shuffle and mask. The masking is just for better + * performance at low sample counts. */ index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xf8ade99a); + index &= shuffled_index_mask; return make_float2(sobol_burley(index, 0, seed ^ 0xe0aaaf76), sobol_burley(index, 1, seed ^ 0x94964d4e)); @@ -97,15 +141,27 @@ ccl_device float2 sobol_burley_sample_2D(uint index, const uint dimension_set, u /* * Computes a 3D Owen-scrambled and shuffled Sobol sample. + * + * `dimension_set` is which three dimensions of the sample you want to + * fetch. For example, 0 is the first three, 1 is the second three, etc. + * The dimensions within a single set are stratified, but different sets + * are uncorrelated. + * + * See sobol_burley_sample_1D for further usage details. */ -ccl_device float3 sobol_burley_sample_3D(uint index, const uint dimension_set, uint seed) +ccl_device float3 sobol_burley_sample_3D(uint index, + const uint dimension_set, + uint seed, + uint shuffled_index_mask) { /* Include the dimension set in the seed, so we get decorrelated * sequences for different dimension sets via shuffling. */ seed ^= hash_hp_uint(dimension_set); - /* Shuffle. */ + /* Shuffle and mask. The masking is just for better + * performance at low sample counts. */ index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xcaa726ac); + index &= shuffled_index_mask; return make_float3(sobol_burley(index, 0, seed ^ 0x9e78e391), sobol_burley(index, 1, seed ^ 0x67c33241), @@ -114,15 +170,27 @@ ccl_device float3 sobol_burley_sample_3D(uint index, const uint dimension_set, u /* * Computes a 4D Owen-scrambled and shuffled Sobol sample. + * + * `dimension_set` is which four dimensions of the sample you want to + * fetch. For example, 0 is the first four, 1 is the second four, etc. + * The dimensions within a single set are stratified, but different sets + * are uncorrelated. + * + * See sobol_burley_sample_1D for further usage details. */ -ccl_device float4 sobol_burley_sample_4D(uint index, const uint dimension_set, uint seed) +ccl_device float4 sobol_burley_sample_4D(uint index, + const uint dimension_set, + uint seed, + uint shuffled_index_mask) { /* Include the dimension set in the seed, so we get decorrelated * sequences for different dimension sets via shuffling. */ seed ^= hash_hp_uint(dimension_set); - /* Shuffle. */ + /* Shuffle and mask. The masking is just for better + * performance at low sample counts. */ index = reversed_bit_owen(reverse_integer_bits(index), seed ^ 0xc2c1a055); + index &= shuffled_index_mask; return make_float4(sobol_burley(index, 0, seed ^ 0x39468210), sobol_burley(index, 1, seed ^ 0xe9d8a845), diff --git a/intern/cycles/scene/integrator.cpp b/intern/cycles/scene/integrator.cpp index ba376e8ba99..7e5633733ae 100644 --- a/intern/cycles/scene/integrator.cpp +++ b/intern/cycles/scene/integrator.cpp @@ -253,6 +253,7 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene kintegrator->sampling_pattern = sampling_pattern; kintegrator->scrambling_distance = scrambling_distance; + kintegrator->sobol_index_mask = reverse_integer_bits(next_power_of_two(aa_samples - 1) - 1); kintegrator->use_light_tree = scene->integrator->use_light_tree; if (light_sampling_threshold > 0.0f) { From f879c20f72d9ce58a2e0ed26dc15557116d5961f Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 14 Dec 2022 18:05:31 +0100 Subject: [PATCH 0100/1522] Geometry Nodes: output uv map from primitive nodes as anonymous attributes This is essentially a left-over from the initial transition to fields where this was forgotten. The mesh primitive nodes used to create a named uv map attribute with a hard-coded name. The standard way to deal with that in geometry nodes now is to output the attribute as a socket instead. The user can then decide to store it as a named attribute or not. The benefits of not always storing the named attribute in the node are: * Improved performance and lower memory usage when the uv map is not used. * It's more obvious that there actually is a uv map. * The hard-coded name was inconsistent. The versioning code inserts a new Store Named Attribute node that stores the uv map immediatly. In many cases, users can probably just remove this node without affecting their final result, but we can't detect that. There is one behavior change which is that the stored uv map will be a 3d vector instead of a 2d vector which is what the nodes originally created. We could store the uv map as 2d vector inthe Store Named Attribute node, but that has the problem that older Blender versions don't support this and would crash immediately. Users can just change this to 2d vector manually if they don't care about forward compatibility. There is a plan to support 2d vectors more natively in geometry nodes: T92765. This change breaks forward compatibility in the case when the uv map was used. Differential Revision: https://developer.blender.org/D16637 --- .../blender/blenkernel/BKE_blender_version.h | 4 +- source/blender/blenkernel/intern/node.cc | 2 +- .../blenloader/intern/versioning_300.cc | 125 ++++++++++++++++-- .../nodes/geometry/node_geometry_util.hh | 4 +- .../nodes/node_geo_mesh_primitive_cone.cc | 20 ++- .../nodes/node_geo_mesh_primitive_cube.cc | 30 +++-- .../nodes/node_geo_mesh_primitive_cylinder.cc | 10 ++ .../nodes/node_geo_mesh_primitive_grid.cc | 31 ++++- .../node_geo_mesh_primitive_ico_sphere.cc | 34 ++++- .../node_geo_mesh_primitive_uv_sphere.cc | 31 ++++- 10 files changed, 249 insertions(+), 42 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index abf9d67370b..91a458e347f 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,13 +25,13 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 3 +#define BLENDER_FILE_SUBVERSION 4 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file * was written with too new a version. */ #define BLENDER_FILE_MIN_VERSION 305 -#define BLENDER_FILE_MIN_SUBVERSION 3 +#define BLENDER_FILE_MIN_SUBVERSION 4 /** User readable version string. */ const char *BKE_blender_version_string(void); diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index c98a9f67bbc..9bc42879d78 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -1130,7 +1130,7 @@ static void node_init(const bContext *C, bNodeTree *ntree, bNode *node) ntype->initfunc(ntree, node); } - if (ntree->typeinfo->node_add_init != nullptr) { + if (ntree->typeinfo && ntree->typeinfo->node_add_init) { ntree->typeinfo->node_add_init(ntree, node); } diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index a90a8cfd753..c22c74ac237 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -823,6 +823,99 @@ static void version_geometry_nodes_replace_transfer_attribute_node(bNodeTree *nt } } +/** + * The mesh primitive nodes created a uv map with a hardcoded name. Now they are outputting the uv + * map as a socket instead. The versioning just inserts a Store Named Attribute node after + * primitive nodes. + */ +static void version_geometry_nodes_primitive_uv_maps(bNodeTree &ntree) +{ + blender::Vector new_nodes; + LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree.nodes) { + if (!ELEM(node->type, + GEO_NODE_MESH_PRIMITIVE_CONE, + GEO_NODE_MESH_PRIMITIVE_CUBE, + GEO_NODE_MESH_PRIMITIVE_CYLINDER, + GEO_NODE_MESH_PRIMITIVE_GRID, + GEO_NODE_MESH_PRIMITIVE_ICO_SPHERE, + GEO_NODE_MESH_PRIMITIVE_UV_SPHERE)) { + continue; + } + bNodeSocket *primitive_output_socket = nullptr; + bNodeSocket *uv_map_output_socket = nullptr; + LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) { + if (STREQ(socket->name, "UV Map")) { + uv_map_output_socket = socket; + } + if (socket->type == SOCK_GEOMETRY) { + primitive_output_socket = socket; + } + } + if (uv_map_output_socket != nullptr) { + continue; + } + uv_map_output_socket = nodeAddStaticSocket( + &ntree, node, SOCK_OUT, SOCK_VECTOR, PROP_NONE, "UV Map", "UV Map"); + + bNode *store_attribute_node = nodeAddStaticNode( + nullptr, &ntree, GEO_NODE_STORE_NAMED_ATTRIBUTE); + new_nodes.append(store_attribute_node); + store_attribute_node->parent = node->parent; + store_attribute_node->locx = node->locx + 25; + store_attribute_node->locy = node->locy; + store_attribute_node->offsetx = node->offsetx; + store_attribute_node->offsety = node->offsety; + NodeGeometryStoreNamedAttribute &storage = *static_cast( + store_attribute_node->storage); + storage.domain = ATTR_DOMAIN_CORNER; + /* Intentionally use 3D instead of 2D vectors, because 2D vectors did not exist in older + * releases and would make the file crash when trying to open it. */ + storage.data_type = CD_PROP_FLOAT3; + + bNodeSocket *store_attribute_geometry_input = static_cast( + store_attribute_node->inputs.first); + bNodeSocket *store_attribute_name_input = store_attribute_geometry_input->next; + bNodeSocket *store_attribute_value_input = nullptr; + LISTBASE_FOREACH (bNodeSocket *, socket, &store_attribute_node->inputs) { + if (socket->type == SOCK_VECTOR) { + store_attribute_value_input = socket; + break; + } + } + bNodeSocket *store_attribute_geometry_output = static_cast( + store_attribute_node->outputs.first); + LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { + if (link->fromsock == primitive_output_socket) { + link->fromnode = store_attribute_node; + link->fromsock = store_attribute_geometry_output; + } + } + + bNodeSocketValueString *name_value = static_cast( + store_attribute_name_input->default_value); + const char *uv_map_name = node->type == GEO_NODE_MESH_PRIMITIVE_ICO_SPHERE ? "UVMap" : + "uv_map"; + BLI_strncpy(name_value->value, uv_map_name, sizeof(name_value->value)); + + nodeAddLink(&ntree, + node, + primitive_output_socket, + store_attribute_node, + store_attribute_geometry_input); + nodeAddLink( + &ntree, node, uv_map_output_socket, store_attribute_node, store_attribute_value_input); + } + + /* Move nodes to the front so that they are drawn behind existing nodes. */ + for (bNode *node : new_nodes) { + BLI_remlink(&ntree.nodes, node); + BLI_addhead(&ntree.nodes, node); + } + if (!new_nodes.is_empty()) { + nodeRebuildIDVector(&ntree); + } +} + void do_versions_after_linking_300(Main *bmain, ReportList * /*reports*/) { if (MAIN_VERSION_ATLEAST(bmain, 300, 0) && !MAIN_VERSION_ATLEAST(bmain, 300, 1)) { @@ -3708,18 +3801,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } - /** - * Versioning code until next subversion bump goes here. - * - * \note Be sure to check when bumping the version: - * - "versioning_userdef.c", #blo_do_versions_userdef - * - "versioning_userdef.c", #do_versions_theme - * - * \note Keep this message at the bottom of the function. - */ - { - /* Keep this block, even when empty. */ - + if (!MAIN_VERSION_ATLEAST(bmain, 305, 4)) { LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) { if (ntree->type == NTREE_GEOMETRY) { version_node_socket_name(ntree, GEO_NODE_COLLECTION_INFO, "Geometry", "Instances"); @@ -3732,5 +3814,24 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) image->seam_margin = 8; } } + + LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) { + if (ntree->type == NTREE_GEOMETRY) { + version_geometry_nodes_primitive_uv_maps(*ntree); + } + } + } + + /** + * Versioning code until next subversion bump goes here. + * + * \note Be sure to check when bumping the version: + * - "versioning_userdef.c", #blo_do_versions_userdef + * - "versioning_userdef.c", #do_versions_theme + * + * \note Keep this message at the bottom of the function. + */ + { + /* Keep this block, even when empty. */ } } diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh index 1b75d13a1aa..d1aeff2cd7a 100644 --- a/source/blender/nodes/geometry/node_geometry_util.hh +++ b/source/blender/nodes/geometry/node_geometry_util.hh @@ -46,12 +46,14 @@ void transform_geometry_set(GeoNodeExecParams ¶ms, Mesh *create_line_mesh(const float3 start, const float3 delta, int count); -Mesh *create_grid_mesh(int verts_x, int verts_y, float size_x, float size_y); +Mesh *create_grid_mesh( + int verts_x, int verts_y, float size_x, float size_y, const AttributeIDRef &uv_map_id); struct ConeAttributeOutputs { StrongAnonymousAttributeID top_id; StrongAnonymousAttributeID bottom_id; StrongAnonymousAttributeID side_id; + StrongAnonymousAttributeID uv_map_id; }; Mesh *create_cylinder_or_cone_mesh(float radius_top, diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc index e89a27a68c6..13c7c6a7a24 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc @@ -536,12 +536,14 @@ static void calculate_selection_outputs(const ConeConfig &config, * If the mesh is a truncated cone or a cylinder, the side faces are unwrapped into * a rectangle that fills the top half of the UV (or the entire UV, if there are no fills). */ -static void calculate_cone_uvs(Mesh *mesh, const ConeConfig &config) +static void calculate_cone_uvs(const ConeConfig &config, + Mesh *mesh, + const AttributeIDRef &uv_map_id) { MutableAttributeAccessor attributes = mesh->attributes_for_write(); SpanAttributeWriter uv_attribute = attributes.lookup_or_add_for_write_only_span( - "uv_map", ATTR_DOMAIN_CORNER); + uv_map_id, ATTR_DOMAIN_CORNER); MutableSpan uvs = uv_attribute.span; Array circle(config.circle_segments); @@ -698,7 +700,9 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top, calculate_cone_verts(config, verts); calculate_cone_edges(config, edges); calculate_cone_faces(config, loops, polys); - calculate_cone_uvs(mesh, config); + if (attribute_outputs.uv_map_id) { + calculate_cone_uvs(config, mesh, attribute_outputs.uv_map_id.get()); + } calculate_selection_outputs(config, attribute_outputs, mesh->attributes_for_write()); mesh->loose_edges_tag_none(); @@ -747,6 +751,7 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output(N_("Top")).field_source(); b.add_output(N_("Bottom")).field_source(); b.add_output(N_("Side")).field_source(); + b.add_output(N_("UV Map")).field_source(); } static void node_init(bNodeTree * /*tree*/, bNode *node) @@ -818,6 +823,9 @@ static void node_geo_exec(GeoNodeExecParams params) if (params.output_is_required("Side")) { attribute_outputs.side_id = StrongAnonymousAttributeID("side_selection"); } + if (params.output_is_required("UV Map")) { + attribute_outputs.uv_map_id = StrongAnonymousAttributeID("uv_map"); + } Mesh *mesh = create_cylinder_or_cone_mesh(radius_top, radius_bottom, @@ -847,6 +855,12 @@ static void node_geo_exec(GeoNodeExecParams params) AnonymousAttributeFieldInput::Create( std::move(attribute_outputs.side_id), params.attribute_producer_name())); } + if (attribute_outputs.uv_map_id) { + params.set_output( + "UV Map", + AnonymousAttributeFieldInput::Create(std::move(attribute_outputs.uv_map_id), + params.attribute_producer_name())); + } params.set_output("Mesh", GeometrySet::create_with_mesh(mesh)); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc index 0029b547375..53ae33fbd21 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc @@ -35,14 +35,16 @@ static void node_declare(NodeDeclarationBuilder &b) .max(1000) .description(N_("Number of vertices for the Z side of the shape")); b.add_output(N_("Mesh")); + b.add_output(N_("UV Map")).field_source(); } static Mesh *create_cuboid_mesh(const float3 &size, const int verts_x, const int verts_y, - const int verts_z) + const int verts_z, + const AttributeIDRef &uv_map_id) { - Mesh *mesh = geometry::create_cuboid_mesh(size, verts_x, verts_y, verts_z, "uv_map"); + Mesh *mesh = geometry::create_cuboid_mesh(size, verts_x, verts_y, verts_z, uv_map_id); BKE_id_material_eval_ensure_default_slot(&mesh->id); return mesh; } @@ -50,7 +52,8 @@ static Mesh *create_cuboid_mesh(const float3 &size, static Mesh *create_cube_mesh(const float3 size, const int verts_x, const int verts_y, - const int verts_z) + const int verts_z, + const AttributeIDRef &uv_map_id) { const int dimensions = (verts_x - 1 > 0) + (verts_y - 1 > 0) + (verts_z - 1 > 0); if (dimensions == 0) { @@ -76,20 +79,20 @@ static Mesh *create_cube_mesh(const float3 size, } if (dimensions == 2) { if (verts_z == 1) { /* XY plane. */ - return create_grid_mesh(verts_x, verts_y, size.x, size.y); + return create_grid_mesh(verts_x, verts_y, size.x, size.y, uv_map_id); } if (verts_y == 1) { /* XZ plane. */ - Mesh *mesh = create_grid_mesh(verts_x, verts_z, size.x, size.z); + Mesh *mesh = create_grid_mesh(verts_x, verts_z, size.x, size.z, uv_map_id); transform_mesh(*mesh, float3(0), float3(M_PI_2, 0.0f, 0.0f), float3(1)); return mesh; } /* YZ plane. */ - Mesh *mesh = create_grid_mesh(verts_z, verts_y, size.z, size.y); + Mesh *mesh = create_grid_mesh(verts_z, verts_y, size.z, size.y, uv_map_id); transform_mesh(*mesh, float3(0), float3(0.0f, M_PI_2, 0.0f), float3(1)); return mesh; } - return create_cuboid_mesh(size, verts_x, verts_y, verts_z); + return create_cuboid_mesh(size, verts_x, verts_y, verts_z, uv_map_id); } static void node_geo_exec(GeoNodeExecParams params) @@ -104,9 +107,20 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - Mesh *mesh = create_cube_mesh(size, verts_x, verts_y, verts_z); + StrongAnonymousAttributeID uv_map_id; + if (params.output_is_required("UV Map")) { + uv_map_id = StrongAnonymousAttributeID("uv_map"); + } + + Mesh *mesh = create_cube_mesh(size, verts_x, verts_y, verts_z, uv_map_id.get()); params.set_output("Mesh", GeometrySet::create_with_mesh(mesh)); + + if (uv_map_id) { + params.set_output("UV Map", + AnonymousAttributeFieldInput::Create( + std::move(uv_map_id), params.attribute_producer_name())); + } } } // namespace blender::nodes::node_geo_mesh_primitive_cube_cc diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc index b02b1fbae27..f27ec076ab2 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc @@ -46,6 +46,7 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output(N_("Top")).field_source(); b.add_output(N_("Side")).field_source(); b.add_output(N_("Bottom")).field_source(); + b.add_output(N_("UV Map")).field_source(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) @@ -115,6 +116,9 @@ static void node_geo_exec(GeoNodeExecParams params) if (params.output_is_required("Side")) { attribute_outputs.side_id = StrongAnonymousAttributeID("side_selection"); } + if (params.output_is_required("UV Map")) { + attribute_outputs.uv_map_id = StrongAnonymousAttributeID("uv_map"); + } /* The cylinder is a special case of the cone mesh where the top and bottom radius are equal. */ Mesh *mesh = create_cylinder_or_cone_mesh(radius, @@ -142,6 +146,12 @@ static void node_geo_exec(GeoNodeExecParams params) AnonymousAttributeFieldInput::Create( std::move(attribute_outputs.side_id), params.attribute_producer_name())); } + if (attribute_outputs.uv_map_id) { + params.set_output( + "UV Map", + AnonymousAttributeFieldInput::Create(std::move(attribute_outputs.uv_map_id), + params.attribute_producer_name())); + } params.set_output("Mesh", GeometrySet::create_with_mesh(mesh)); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc index 84af0e00312..aa085ae903d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc @@ -15,13 +15,17 @@ namespace blender::nodes { -static void calculate_uvs( - Mesh *mesh, Span verts, Span loops, const float size_x, const float size_y) +static void calculate_uvs(Mesh *mesh, + Span verts, + Span loops, + const float size_x, + const float size_y, + const AttributeIDRef &uv_map_id) { MutableAttributeAccessor attributes = mesh->attributes_for_write(); SpanAttributeWriter uv_attribute = attributes.lookup_or_add_for_write_only_span( - "uv_map", ATTR_DOMAIN_CORNER); + uv_map_id, ATTR_DOMAIN_CORNER); const float dx = (size_x == 0.0f) ? 0.0f : 1.0f / size_x; const float dy = (size_y == 0.0f) ? 0.0f : 1.0f / size_y; @@ -39,7 +43,8 @@ static void calculate_uvs( Mesh *create_grid_mesh(const int verts_x, const int verts_y, const float size_x, - const float size_y) + const float size_y, + const AttributeIDRef &uv_map_id) { BLI_assert(verts_x > 0 && verts_y > 0); const int edges_x = verts_x - 1; @@ -139,8 +144,8 @@ Mesh *create_grid_mesh(const int verts_x, } }); - if (mesh->totpoly != 0) { - calculate_uvs(mesh, verts, loops, size_x, size_y); + if (uv_map_id && mesh->totpoly != 0) { + calculate_uvs(mesh, verts, loops, size_x, size_y, uv_map_id); } mesh->loose_edges_tag_none(); @@ -175,6 +180,7 @@ static void node_declare(NodeDeclarationBuilder &b) .max(1000) .description(N_("Number of vertices in the Y direction")); b.add_output(N_("Mesh")); + b.add_output(N_("UV Map")).field_source(); } static void node_geo_exec(GeoNodeExecParams params) @@ -188,10 +194,21 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - Mesh *mesh = create_grid_mesh(verts_x, verts_y, size_x, size_y); + StrongAnonymousAttributeID uv_map_id; + if (params.output_is_required("UV Map")) { + uv_map_id = StrongAnonymousAttributeID("uv_map"); + } + + Mesh *mesh = create_grid_mesh(verts_x, verts_y, size_x, size_y, uv_map_id.get()); BKE_id_material_eval_ensure_default_slot(&mesh->id); params.set_output("Mesh", GeometrySet::create_with_mesh(mesh)); + + if (uv_map_id) { + params.set_output("UV Map", + AnonymousAttributeFieldInput::Create( + std::move(uv_map_id), params.attribute_producer_name())); + } } } // namespace blender::nodes::node_geo_mesh_primitive_grid_cc diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc index 8287c6a6714..1fa85fc8d56 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc @@ -25,12 +25,17 @@ static void node_declare(NodeDeclarationBuilder &b) .max(7) .description(N_("Number of subdivisions on top of the basic icosahedron")); b.add_output(N_("Mesh")); + b.add_output(N_("UV Map")).field_source(); } -static Mesh *create_ico_sphere_mesh(const int subdivisions, const float radius) +static Mesh *create_ico_sphere_mesh(const int subdivisions, + const float radius, + const AttributeIDRef &uv_map_id) { const float4x4 transform = float4x4::identity(); + const bool create_uv_map = bool(uv_map_id); + BMeshCreateParams bmesh_create_params{}; bmesh_create_params.use_toolflags = true; const BMAllocTemplate allocsize = {0, 0, 0, 0}; @@ -43,7 +48,7 @@ static Mesh *create_ico_sphere_mesh(const int subdivisions, const float radius) subdivisions, std::abs(radius), transform.values, - true); + create_uv_map); BMeshToMeshParams params{}; params.calc_object_remap = false; @@ -52,6 +57,18 @@ static Mesh *create_ico_sphere_mesh(const int subdivisions, const float radius) BM_mesh_bm_to_me(nullptr, bm, mesh, ¶ms); BM_mesh_free(bm); + /* The code above generates a "UVMap" attribute. The code below renames that attribute, we don't + * have a simple utility for that yet though so there is some overhead right now. */ + MutableAttributeAccessor attributes = mesh->attributes_for_write(); + if (create_uv_map) { + const VArraySpan orig_uv_map = attributes.lookup("UVMap"); + SpanAttributeWriter uv_map = attributes.lookup_or_add_for_write_only_span( + uv_map_id, ATTR_DOMAIN_CORNER); + uv_map.span.copy_from(orig_uv_map); + uv_map.finish(); + } + attributes.remove("UVMap"); + return mesh; } @@ -60,8 +77,19 @@ static void node_geo_exec(GeoNodeExecParams params) const int subdivisions = std::min(params.extract_input("Subdivisions"), 10); const float radius = params.extract_input("Radius"); - Mesh *mesh = create_ico_sphere_mesh(subdivisions, radius); + StrongAnonymousAttributeID uv_map_id; + if (params.output_is_required("UV Map")) { + uv_map_id = StrongAnonymousAttributeID("uv_map"); + } + + Mesh *mesh = create_ico_sphere_mesh(subdivisions, radius, uv_map_id.get()); params.set_output("Mesh", GeometrySet::create_with_mesh(mesh)); + + if (uv_map_id) { + params.set_output("UV Map", + AnonymousAttributeFieldInput::Create( + std::move(uv_map_id), params.attribute_producer_name())); + } } } // namespace blender::nodes::node_geo_mesh_primitive_ico_sphere_cc diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc index d1009083218..6be03be63f5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc @@ -33,6 +33,7 @@ static void node_declare(NodeDeclarationBuilder &b) .subtype(PROP_DISTANCE) .description(N_("Distance from the generated points to the origin")); b.add_output(N_("Mesh")); + b.add_output(N_("UV Map")).field_source(); } static int sphere_vert_total(const int segments, const int rings) @@ -255,12 +256,15 @@ BLI_NOINLINE static void calculate_sphere_corners(MutableSpan loops, } } -BLI_NOINLINE static void calculate_sphere_uvs(Mesh *mesh, const float segments, const float rings) +BLI_NOINLINE static void calculate_sphere_uvs(Mesh *mesh, + const float segments, + const float rings, + const AttributeIDRef &uv_map_id) { MutableAttributeAccessor attributes = mesh->attributes_for_write(); SpanAttributeWriter uv_attribute = attributes.lookup_or_add_for_write_only_span( - "uv_map", ATTR_DOMAIN_CORNER); + uv_map_id, ATTR_DOMAIN_CORNER); MutableSpan uvs = uv_attribute.span; const float dy = 1.0f / rings; @@ -301,7 +305,10 @@ BLI_NOINLINE static void calculate_sphere_uvs(Mesh *mesh, const float segments, uv_attribute.finish(); } -static Mesh *create_uv_sphere_mesh(const float radius, const int segments, const int rings) +static Mesh *create_uv_sphere_mesh(const float radius, + const int segments, + const int rings, + const AttributeIDRef &uv_map_id) { Mesh *mesh = BKE_mesh_new_nomain(sphere_vert_total(segments, rings), sphere_edge_total(segments, rings), @@ -325,7 +332,11 @@ static Mesh *create_uv_sphere_mesh(const float radius, const int segments, const [&]() { calculate_sphere_edge_indices(edges, segments, rings); }, [&]() { calculate_sphere_faces(polys, segments); }, [&]() { calculate_sphere_corners(loops, segments, rings); }, - [&]() { calculate_sphere_uvs(mesh, segments, rings); }); + [&]() { + if (uv_map_id) { + calculate_sphere_uvs(mesh, segments, rings, uv_map_id); + } + }); mesh->loose_edges_tag_none(); @@ -351,8 +362,18 @@ static void node_geo_exec(GeoNodeExecParams params) const float radius = params.extract_input("Radius"); - Mesh *mesh = create_uv_sphere_mesh(radius, segments_num, rings_num); + StrongAnonymousAttributeID uv_map_id; + if (params.output_is_required("UV Map")) { + uv_map_id = StrongAnonymousAttributeID("uv_map"); + } + + Mesh *mesh = create_uv_sphere_mesh(radius, segments_num, rings_num, uv_map_id.get()); params.set_output("Mesh", GeometrySet::create_with_mesh(mesh)); + if (uv_map_id) { + params.set_output("UV Map", + AnonymousAttributeFieldInput::Create( + std::move(uv_map_id), params.attribute_producer_name())); + } } } // namespace blender::nodes::node_geo_mesh_primitive_uv_sphere_cc From eae1be548dd5d36328121882106dc417ae8e02be Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 14 Dec 2022 11:08:35 -0600 Subject: [PATCH 0101/1522] Fix T103186: Missing anonymous attribute reference Creating the `WeakAnonymousAttributeID` doesn't increase the reference count, but destructing it does. --- source/blender/geometry/intern/mesh_split_edges.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/geometry/intern/mesh_split_edges.cc b/source/blender/geometry/intern/mesh_split_edges.cc index ba00ba5a8a6..19db9cbfc03 100644 --- a/source/blender/geometry/intern/mesh_split_edges.cc +++ b/source/blender/geometry/intern/mesh_split_edges.cc @@ -79,6 +79,7 @@ static void add_new_edges(Mesh &mesh, } else { anonymous_ids.append(bke::WeakAnonymousAttributeID(&id.anonymous_id())); + BKE_anonymous_attribute_id_increment_weak(&id.anonymous_id()); } } Vector local_edge_ids; @@ -98,8 +99,8 @@ static void add_new_edges(Mesh &mesh, void *array; }; Vector dst_attributes; - for (const bke::AttributeIDRef &id : local_edge_ids) { - bke::GAttributeReader attribute = attributes.lookup(id); + for (const bke::AttributeIDRef &local_id : local_edge_ids) { + bke::GAttributeReader attribute = attributes.lookup(local_id); if (!attribute) { continue; } @@ -115,8 +116,8 @@ static void add_new_edges(Mesh &mesh, }); /* Free the original attribute as soon as possible to lower peak memory usage. */ - attributes.remove(id); - dst_attributes.append({id, type, new_data}); + attributes.remove(local_id); + dst_attributes.append({local_id, type, new_data}); } int *new_orig_indices = nullptr; From 9fd834fbb3468133b807b50808f3ccfbf55cc7f1 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 14 Dec 2022 11:11:37 -0600 Subject: [PATCH 0102/1522] Fix T103143: Cycles can lose default color attribute The `render_color_index` skips attributes with different types and domains in order to give the proper order for the UI list. That is a different than an index in the group of all attributes. The most solid solution I could think of is exposing the name of the default color attribute. It's "solid" because we always address attributes by name internally. Doing something different is bound to create problems. It's also aligned with the design in T98366 and D15169. Another option would be to change the way the "attribute index" is incremented in Cycles. That would be a valid solution, but would be more complex and annoying. For consistency, I also exposed the name of the active color attribute the same way, though it isn't necessary to fix this particular bug. The properties aren't editable, that can come in 3.5 as part of D15169. Differential Revision: https://developer.blender.org/D16769 --- intern/cycles/blender/mesh.cpp | 6 +- .../blender/makesrna/intern/rna_attribute.c | 66 +++++++++++++++++++ 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index 1887440bc67..736b80bacd6 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -367,13 +367,11 @@ static void attr_create_generic(Scene *scene, { AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes; static const ustring u_velocity("velocity"); - - int attribute_index = 0; - int render_color_index = b_mesh.attributes.render_color_index(); + const ustring default_color_name{b_mesh.attributes.default_color_name().c_str()}; for (BL::Attribute &b_attribute : b_mesh.attributes) { const ustring name{b_attribute.name().c_str()}; - const bool is_render_color = (attribute_index++ == render_color_index); + const bool is_render_color = name == default_color_name; if (need_motion && name == u_velocity) { attr_create_motion(mesh, b_attribute, motion_scale); diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c index c5ddc9a0204..d65159af28a 100644 --- a/source/blender/makesrna/intern/rna_attribute.c +++ b/source/blender/makesrna/intern/rna_attribute.c @@ -651,6 +651,49 @@ static void rna_AttributeGroup_render_color_index_range( *softmin = *min; *softmax = *max; } + +static void rna_AttributeGroup_default_color_name_get(PointerRNA *ptr, char *value) +{ + const ID *id = ptr->owner_id; + const CustomDataLayer *layer = BKE_id_attributes_render_color_get(id); + if (!layer) { + value[0] = '\0'; + return; + } + BLI_strncpy(value, layer->name, MAX_CUSTOMDATA_LAYER_NAME); +} + +static int rna_AttributeGroup_default_color_name_length(PointerRNA *ptr) +{ + const ID *id = ptr->owner_id; + const CustomDataLayer *layer = BKE_id_attributes_render_color_get(id); + if (!layer) { + return 0; + } + return strlen(layer->name); +} + +static void rna_AttributeGroup_active_color_name_get(PointerRNA *ptr, char *value) +{ + const ID *id = ptr->owner_id; + const CustomDataLayer *layer = BKE_id_attributes_active_color_get(id); + if (!layer) { + value[0] = '\0'; + return; + } + BLI_strncpy(value, layer->name, MAX_CUSTOMDATA_LAYER_NAME); +} + +static int rna_AttributeGroup_active_color_name_length(PointerRNA *ptr) +{ + const ID *id = ptr->owner_id; + const CustomDataLayer *layer = BKE_id_attributes_active_color_get(id); + if (!layer) { + return 0; + } + return strlen(layer->name); +} + #else static void rna_def_attribute_float(BlenderRNA *brna) @@ -1110,6 +1153,29 @@ static void rna_def_attribute_group(BlenderRNA *brna) "rna_AttributeGroup_render_color_index_set", "rna_AttributeGroup_render_color_index_range"); RNA_def_property_update(prop, 0, "rna_AttributeGroup_update_active_color"); + + prop = RNA_def_property(srna, "default_color_name", PROP_STRING, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME); + RNA_def_property_string_funcs(prop, + "rna_AttributeGroup_default_color_name_get", + "rna_AttributeGroup_default_color_name_length", + NULL); + RNA_def_property_ui_text( + prop, + "Default Color Attribute", + "The name of the default color attribute used as a fallback for rendering"); + + prop = RNA_def_property(srna, "active_color_name", PROP_STRING, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME); + RNA_def_property_string_funcs(prop, + "rna_AttributeGroup_active_color_name_get", + "rna_AttributeGroup_active_color_name_length", + NULL); + RNA_def_property_ui_text(prop, + "Active Color Attribute", + "The name of the active color attribute for display and editing"); } void rna_def_attributes_common(StructRNA *srna) From c5f5046efd07a81232904ab6cb6a94f0c755f376 Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Wed, 14 Dec 2022 18:28:07 +0100 Subject: [PATCH 0103/1522] Fix T103208: unavailable socket linked to multi-input socket crashes Differential Revision: https://developer.blender.org/D16772 --- source/blender/nodes/intern/geometry_nodes_lazy_function.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index d7d633353bd..cad92cc0d90 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -157,9 +157,11 @@ class LazyFunctionForMultiInput : public LazyFunction { BLI_assert(socket.is_multi_input()); const bNodeTree &btree = socket.owner_tree(); for (const bNodeLink *link : socket.directly_linked_links()) { - if (!(link->is_muted() || nodeIsDanglingReroute(&btree, link->fromnode))) { - inputs_.append({"Input", *base_type_}); + if (link->is_muted() || !link->fromsock->is_available() || + nodeIsDanglingReroute(&btree, link->fromnode)) { + continue; } + inputs_.append({"Input", *base_type_}); } const CPPType *vector_type = get_vector_type(*base_type_); BLI_assert(vector_type != nullptr); From 77a4ab3ccf2df23f540ebb0a1fc5e5266990281d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Dec 2022 18:35:34 +0100 Subject: [PATCH 0104/1522] Fix wrong syntax in Cycles float8 test fix --- intern/cycles/test/util_float8_test.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/intern/cycles/test/util_float8_test.h b/intern/cycles/test/util_float8_test.h index 8ae95d75f47..bcceeada12c 100644 --- a/intern/cycles/test/util_float8_test.h +++ b/intern/cycles/test/util_float8_test.h @@ -24,17 +24,17 @@ static bool validate_cpu_capabilities() /* These are not just static variables because we don't want to run the * constructor until we know the instructions are supported. */ -static vfloat8 float8_a()() +static vfloat8 float8_a() { return make_vfloat8(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f) } -static vfloat8 float8_b()() +static vfloat8 float8_b() { return make_vfloat8(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f); } -static vfloat8 float8_c()() +static vfloat8 float8_c() { return make_vfloat8(1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f); } From d33758755b02f3a69631ed4fc671ba400f02b6a5 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Wed, 14 Dec 2022 18:24:50 +0100 Subject: [PATCH 0105/1522] Revert "Fix T102571: Can't stop audio playback when using multiple windows" This reverts commit 42b51bf6a91acd055d34e31c06c9dff46b0aac1b. Commit caused crash when playback is stopped, see T103008. --- source/blender/editors/screen/screen_ops.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index a4e98aa639a..9c0963d0fb1 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -4812,28 +4812,19 @@ bScreen *ED_screen_animation_no_scrub(const wmWindowManager *wm) int ED_screen_animation_play(bContext *C, int sync, int mode) { bScreen *screen = CTX_wm_screen(C); + Scene *scene = CTX_data_scene(C); + Scene *scene_eval = DEG_get_evaluated_scene(CTX_data_ensure_evaluated_depsgraph(C)); if (ED_screen_animation_playing(CTX_wm_manager(C))) { /* stop playback now */ ED_screen_animation_timer(C, 0, 0, 0); - Main *bmain = CTX_data_main(C); - LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { - LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { - Depsgraph *graph = BKE_scene_get_depsgraph(scene, view_layer); - if (graph) { - Scene *scene_eval = DEG_get_evaluated_scene(graph); - /* The audio handles are preserved throughout the dependency graph evaluation. - * Checking for scene->playback_handle even for non-evaluated scene should be okay. */ - BKE_sound_stop_scene(scene_eval); - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); - } - } - } + BKE_sound_stop_scene(scene_eval); + + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); } else { /* these settings are currently only available from a menu in the TimeLine */ if (mode == 1) { /* XXX only play audio forwards!? */ - Scene *scene_eval = DEG_get_evaluated_scene(CTX_data_ensure_evaluated_depsgraph(C)); BKE_sound_play_scene(scene_eval); } From 7efba6c59a225fbb478b1f554848f1086c190db0 Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Wed, 14 Dec 2022 18:48:13 +0100 Subject: [PATCH 0106/1522] Geometry Nodes: show correct type in socket tooltip Differential Revision: https://developer.blender.org/D16748 --- .../blender/editors/space_node/node_draw.cc | 86 ++++++++++++------- 1 file changed, 56 insertions(+), 30 deletions(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 3bb10404302..2790e8de6a8 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -39,6 +39,7 @@ #include "BKE_node_runtime.hh" #include "BKE_node_tree_update.h" #include "BKE_object.h" +#include "BKE_type_conversions.hh" #include "DEG_depsgraph.h" @@ -794,56 +795,76 @@ struct SocketTooltipData { const bNodeSocket *socket; }; -static void create_inspection_string_for_generic_value(const GPointer value, std::stringstream &ss) +static void create_inspection_string_for_generic_value(const bNodeSocket &socket, + const GPointer value, + std::stringstream &ss) { auto id_to_inspection_string = [&](const ID *id, const short idcode) { ss << (id ? id->name + 2 : TIP_("None")) << " (" << TIP_(BKE_idtype_idcode_to_name(idcode)) << ")"; }; - const CPPType &type = *value.type(); + const CPPType &value_type = *value.type(); const void *buffer = value.get(); - if (type.is()) { + if (value_type.is()) { id_to_inspection_string(*static_cast(buffer), ID_OB); + return; } - else if (type.is()) { + else if (value_type.is()) { id_to_inspection_string(*static_cast(buffer), ID_MA); + return; } - else if (type.is()) { + else if (value_type.is()) { id_to_inspection_string(*static_cast(buffer), ID_TE); + return; } - else if (type.is()) { + else if (value_type.is()) { id_to_inspection_string(*static_cast(buffer), ID_IM); + return; } - else if (type.is()) { + else if (value_type.is()) { id_to_inspection_string(*static_cast(buffer), ID_GR); + return; } - else if (type.is()) { - ss << *(int *)buffer << TIP_(" (Integer)"); + else if (value_type.is()) { + ss << *static_cast(buffer) << TIP_(" (String)"); + return; } - else if (type.is()) { - ss << *(float *)buffer << TIP_(" (Float)"); + + const CPPType &socket_type = *socket.typeinfo->base_cpp_type; + const bke::DataTypeConversions &convert = bke::get_implicit_type_conversions(); + if (!convert.is_convertible(value_type, socket_type)) { + return; } - else if (type.is()) { - ss << *(blender::float3 *)buffer << TIP_(" (Vector)"); + BUFFER_FOR_CPP_TYPE_VALUE(socket_type, socket_value); + convert.convert_to_uninitialized(value_type, socket_type, buffer, socket_value); + BLI_SCOPED_DEFER([&]() { socket_type.destruct(socket_value); }); + + if (socket_type.is()) { + ss << *static_cast(socket_value) << TIP_(" (Integer)"); } - else if (type.is()) { - const blender::ColorGeometry4f &color = *(blender::ColorGeometry4f *)buffer; + else if (socket_type.is()) { + ss << *static_cast(socket_value) << TIP_(" (Float)"); + } + else if (socket_type.is()) { + ss << *static_cast(socket_value) << TIP_(" (Vector)"); + } + else if (socket_type.is()) { + const blender::ColorGeometry4f &color = *static_cast(socket_value); ss << "(" << color.r << ", " << color.g << ", " << color.b << ", " << color.a << ")" << TIP_(" (Color)"); } - else if (type.is()) { - ss << ((*(bool *)buffer) ? TIP_("True") : TIP_("False")) << TIP_(" (Boolean)"); - } - else if (type.is()) { - ss << *(std::string *)buffer << TIP_(" (String)"); + else if (socket_type.is()) { + ss << ((*static_cast(socket_value)) ? TIP_("True") : TIP_("False")) + << TIP_(" (Boolean)"); } } -static void create_inspection_string_for_field_info(const geo_log::FieldInfoLog &value_log, +static void create_inspection_string_for_field_info(const bNodeSocket &socket, + const geo_log::FieldInfoLog &value_log, std::stringstream &ss) { - const CPPType &type = value_log.type; + const CPPType &socket_type = *socket.typeinfo->base_cpp_type; const Span input_tooltips = value_log.input_tooltips; if (input_tooltips.is_empty()) { @@ -852,22 +873,22 @@ static void create_inspection_string_for_field_info(const geo_log::FieldInfoLog ss << "Value has not been logged"; } else { - if (type.is()) { + if (socket_type.is()) { ss << TIP_("Integer field"); } - else if (type.is()) { + else if (socket_type.is()) { ss << TIP_("Float field"); } - else if (type.is()) { + else if (socket_type.is()) { ss << TIP_("Vector field"); } - else if (type.is()) { + else if (socket_type.is()) { ss << TIP_("Boolean field"); } - else if (type.is()) { + else if (socket_type.is()) { ss << TIP_("String field"); } - else if (type.is()) { + else if (socket_type.is()) { ss << TIP_("Color field"); } ss << TIP_(" based on:\n"); @@ -1012,6 +1033,11 @@ static std::optional create_socket_inspection_string(TreeDrawContex const bNodeSocket &socket) { using namespace blender::nodes::geo_eval_log; + + if (socket.typeinfo->base_cpp_type == nullptr) { + return std::nullopt; + } + tree_draw_ctx.geo_tree_log->ensure_socket_values(); ValueLog *value_log = tree_draw_ctx.geo_tree_log->find_socket_value_log(socket); if (value_log == nullptr) { @@ -1020,11 +1046,11 @@ static std::optional create_socket_inspection_string(TreeDrawContex std::stringstream ss; if (const geo_log::GenericValueLog *generic_value_log = dynamic_cast(value_log)) { - create_inspection_string_for_generic_value(generic_value_log->value, ss); + create_inspection_string_for_generic_value(socket, generic_value_log->value, ss); } else if (const geo_log::FieldInfoLog *gfield_value_log = dynamic_cast(value_log)) { - create_inspection_string_for_field_info(*gfield_value_log, ss); + create_inspection_string_for_field_info(socket, *gfield_value_log, ss); } else if (const geo_log::GeometryInfoLog *geo_value_log = dynamic_cast(value_log)) { From 8c14992db235964b04074fcdb94518d19debf124 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Dec 2022 19:01:42 +0100 Subject: [PATCH 0107/1522] Fix syntax errors in Cycles float8 test --- intern/cycles/test/util_float8_test.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intern/cycles/test/util_float8_test.h b/intern/cycles/test/util_float8_test.h index bcceeada12c..4da96dfb7b0 100644 --- a/intern/cycles/test/util_float8_test.h +++ b/intern/cycles/test/util_float8_test.h @@ -26,7 +26,7 @@ static bool validate_cpu_capabilities() * constructor until we know the instructions are supported. */ static vfloat8 float8_a() { - return make_vfloat8(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f) + return make_vfloat8(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f); } static vfloat8 float8_b() @@ -80,7 +80,7 @@ TEST(TEST_CATEGORY_NAME, float8_add_vv){ basic_test_vf(float8_a(), float_b, *)} TEST(TEST_CATEGORY_NAME, float8_div_vf){ basic_test_vf(float8_a(), float_b, /)} -TEST(TEST_CATEGORY_NAME, float8_c() tor) +TEST(TEST_CATEGORY_NAME, float8_ctor) { INIT_FLOAT8_TEST compare_vector_scalar(make_vfloat8(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f), From a501a2dbff797829b61f21c5aeb9d19dba3e3874 Mon Sep 17 00:00:00 2001 From: Hallam Roberts Date: Wed, 14 Dec 2022 19:19:52 +0100 Subject: [PATCH 0108/1522] Images: add mirror extension type This adds a new mirror image extension type for shaders and geometry nodes (next to the existing repeat, extend and clip options). See D16432 for a more detailed explanation of `wrap_mirror`. This also adds a new sampler flag `GPU_SAMPLER_MIRROR_REPEAT`. It acts as a modifier to `GPU_SAMPLER_REPEAT`, so any `REPEAT` flag must be set for the `MIRROR` flag to have an effect. Differential Revision: https://developer.blender.org/D16432 --- intern/cycles/device/cuda/device_impl.cpp | 3 + intern/cycles/device/hip/device_impl.cpp | 3 + intern/cycles/device/metal/device_impl.mm | 2 +- intern/cycles/kernel/device/cpu/image.h | 60 ++++++++++++++++++ intern/cycles/kernel/device/metal/compat.h | 4 ++ .../kernel/device/metal/context_begin.h | 8 ++- intern/cycles/kernel/device/oneapi/image.h | 17 +++++ intern/cycles/scene/shader_nodes.cpp | 1 + intern/cycles/util/texture.h | 2 + .../engines/workbench/workbench_materials.cc | 4 +- source/blender/gpu/GPU_texture.h | 3 +- source/blender/gpu/metal/mtl_context.mm | 9 ++- source/blender/gpu/opengl/gl_texture.cc | 14 +++-- source/blender/makesdna/DNA_node_types.h | 1 + source/blender/makesrna/intern/rna_nodetree.c | 62 +++++++------------ .../geometry/nodes/node_geo_image_texture.cc | 31 ++++++++++ .../shader/nodes/node_shader_tex_image.cc | 3 + 17 files changed, 174 insertions(+), 53 deletions(-) diff --git a/intern/cycles/device/cuda/device_impl.cpp b/intern/cycles/device/cuda/device_impl.cpp index c9764d1c21b..f354ba6aee1 100644 --- a/intern/cycles/device/cuda/device_impl.cpp +++ b/intern/cycles/device/cuda/device_impl.cpp @@ -952,6 +952,9 @@ void CUDADevice::tex_alloc(device_texture &mem) case EXTENSION_CLIP: address_mode = CU_TR_ADDRESS_MODE_BORDER; break; + case EXTENSION_MIRROR: + address_mode = CU_TR_ADDRESS_MODE_MIRROR; + break; default: assert(0); break; diff --git a/intern/cycles/device/hip/device_impl.cpp b/intern/cycles/device/hip/device_impl.cpp index a84f1edd70e..04de8619697 100644 --- a/intern/cycles/device/hip/device_impl.cpp +++ b/intern/cycles/device/hip/device_impl.cpp @@ -909,6 +909,9 @@ void HIPDevice::tex_alloc(device_texture &mem) * because it's unsupported in HIP. */ address_mode = hipAddressModeClamp; break; + case EXTENSION_MIRROR: + address_mode = hipAddressModeMirror; + break; default: assert(0); break; diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm index 24836e88755..95935ce2a3a 100644 --- a/intern/cycles/device/metal/device_impl.mm +++ b/intern/cycles/device/metal/device_impl.mm @@ -856,7 +856,7 @@ void MetalDevice::tex_alloc(device_texture &mem) /* sampler_index maps into the GPU's constant 'metal_samplers' array */ uint64_t sampler_index = mem.info.extension; if (mem.info.interpolation != INTERPOLATION_CLOSEST) { - sampler_index += 3; + sampler_index += 4; } /* Image Texture Storage */ diff --git a/intern/cycles/kernel/device/cpu/image.h b/intern/cycles/kernel/device/cpu/image.h index 320e6309128..eb50ac8217f 100644 --- a/intern/cycles/kernel/device/cpu/image.h +++ b/intern/cycles/kernel/device/cpu/image.h @@ -202,6 +202,14 @@ template struct TextureInterpolator { return clamp(x, 0, width - 1); } + static ccl_always_inline int wrap_mirror(int x, int width) + { + const int m = abs(x + (x < 0)) % (2 * width); + if (m >= width) + return 2 * width - m - 1; + return m; + } + /* ******** 2D interpolation ******** */ static ccl_always_inline OutT interp_closest(const TextureInfo &info, float x, float y) @@ -226,6 +234,10 @@ template struct TextureInterpolator { ix = wrap_clamp(ix, width); iy = wrap_clamp(iy, height); break; + case EXTENSION_MIRROR: + ix = wrap_mirror(ix, width); + iy = wrap_mirror(iy, height); + break; default: kernel_assert(0); return zero(); @@ -268,6 +280,12 @@ template struct TextureInterpolator { niy = wrap_clamp(iy + 1, height); iy = wrap_clamp(iy, height); break; + case EXTENSION_MIRROR: + nix = wrap_mirror(ix + 1, width); + ix = wrap_mirror(ix, width); + niy = wrap_mirror(iy + 1, height); + iy = wrap_mirror(iy, height); + break; default: kernel_assert(0); return zero(); @@ -331,6 +349,17 @@ template struct TextureInterpolator { nniy = wrap_clamp(iy + 2, height); iy = wrap_clamp(iy, height); break; + case EXTENSION_MIRROR: + pix = wrap_mirror(ix - 1, width); + nix = wrap_mirror(ix + 1, width); + nnix = wrap_mirror(ix + 2, width); + ix = wrap_mirror(ix, width); + + piy = wrap_mirror(iy - 1, height); + niy = wrap_mirror(iy + 1, height); + nniy = wrap_mirror(iy + 2, height); + iy = wrap_mirror(iy, height); + break; default: kernel_assert(0); return zero(); @@ -403,6 +432,11 @@ template struct TextureInterpolator { iy = wrap_clamp(iy, height); iz = wrap_clamp(iz, depth); break; + case EXTENSION_MIRROR: + ix = wrap_mirror(ix, width); + iy = wrap_mirror(iy, height); + iz = wrap_mirror(iz, depth); + break; default: kernel_assert(0); return zero(); @@ -480,6 +514,16 @@ template struct TextureInterpolator { niz = wrap_clamp(iz + 1, depth); iz = wrap_clamp(iz, depth); break; + case EXTENSION_MIRROR: + nix = wrap_mirror(ix + 1, width); + ix = wrap_mirror(ix, width); + + niy = wrap_mirror(iy + 1, height); + iy = wrap_mirror(iy, height); + + niz = wrap_mirror(iz + 1, depth); + iz = wrap_mirror(iz, depth); + break; default: kernel_assert(0); return zero(); @@ -595,6 +639,22 @@ template struct TextureInterpolator { nniz = wrap_clamp(iz + 2, depth); iz = wrap_clamp(iz, depth); break; + case EXTENSION_MIRROR: + pix = wrap_mirror(ix - 1, width); + nix = wrap_mirror(ix + 1, width); + nnix = wrap_mirror(ix + 2, width); + ix = wrap_mirror(ix, width); + + piy = wrap_mirror(iy - 1, height); + niy = wrap_mirror(iy + 1, height); + nniy = wrap_mirror(iy + 2, height); + iy = wrap_mirror(iy, height); + + piz = wrap_mirror(iz - 1, depth); + niz = wrap_mirror(iz + 1, depth); + nniz = wrap_mirror(iz + 2, depth); + iz = wrap_mirror(iz, depth); + break; default: kernel_assert(0); return zero(); diff --git a/intern/cycles/kernel/device/metal/compat.h b/intern/cycles/kernel/device/metal/compat.h index 2dd6cc98b59..3913931b4fb 100644 --- a/intern/cycles/kernel/device/metal/compat.h +++ b/intern/cycles/kernel/device/metal/compat.h @@ -301,10 +301,12 @@ enum SamplerType { SamplerFilterNearest_AddressRepeat, SamplerFilterNearest_AddressClampEdge, SamplerFilterNearest_AddressClampZero, + SamplerFilterNearest_AddressMirroredRepeat, SamplerFilterLinear_AddressRepeat, SamplerFilterLinear_AddressClampEdge, SamplerFilterLinear_AddressClampZero, + SamplerFilterLinear_AddressMirroredRepeat, SamplerCount }; @@ -313,7 +315,9 @@ constant constexpr array metal_samplers = { sampler(address::repeat, filter::nearest), sampler(address::clamp_to_edge, filter::nearest), sampler(address::clamp_to_zero, filter::nearest), + sampler(address::mirrored_repeat, filter::nearest), sampler(address::repeat, filter::linear), sampler(address::clamp_to_edge, filter::linear), sampler(address::clamp_to_zero, filter::linear), + sampler(address::mirrored_repeat, filter::linear), }; diff --git a/intern/cycles/kernel/device/metal/context_begin.h b/intern/cycles/kernel/device/metal/context_begin.h index e75ec9cadec..4bde9be455a 100644 --- a/intern/cycles/kernel/device/metal/context_begin.h +++ b/intern/cycles/kernel/device/metal/context_begin.h @@ -47,9 +47,11 @@ class MetalKernelContext { case 0: return texture_array[tid].tex.sample(sampler(address::repeat, filter::nearest), coords); case 1: return texture_array[tid].tex.sample(sampler(address::clamp_to_edge, filter::nearest), coords); case 2: return texture_array[tid].tex.sample(sampler(address::clamp_to_zero, filter::nearest), coords); - case 3: return texture_array[tid].tex.sample(sampler(address::repeat, filter::linear), coords); - case 4: return texture_array[tid].tex.sample(sampler(address::clamp_to_edge, filter::linear), coords); - case 5: return texture_array[tid].tex.sample(sampler(address::clamp_to_zero, filter::linear), coords); + case 3: return texture_array[tid].tex.sample(sampler(address::mirrored_repeat, filter::nearest), coords); + case 4: return texture_array[tid].tex.sample(sampler(address::repeat, filter::linear), coords); + case 5: return texture_array[tid].tex.sample(sampler(address::clamp_to_edge, filter::linear), coords); + case 6: return texture_array[tid].tex.sample(sampler(address::clamp_to_zero, filter::linear), coords); + case 7: return texture_array[tid].tex.sample(sampler(address::mirrored_repeat, filter::linear), coords); } } #endif diff --git a/intern/cycles/kernel/device/oneapi/image.h b/intern/cycles/kernel/device/oneapi/image.h index 2417b8eac3b..bdb81bb8645 100644 --- a/intern/cycles/kernel/device/oneapi/image.h +++ b/intern/cycles/kernel/device/oneapi/image.h @@ -24,6 +24,14 @@ ccl_device_inline int svm_image_texture_wrap_clamp(int x, int width) return clamp(x, 0, width - 1); } +ccl_device_inline int svm_image_texture_wrap_mirror(int x, int width) +{ + const int m = abs(x + (x < 0)) % (2 * width); + if (m >= width) + return 2 * width - m - 1; + return m; +} + ccl_device_inline float4 svm_image_texture_read(const TextureInfo &info, int x, int y, int z) { const int data_offset = x + info.width * y + info.width * info.height * z; @@ -85,6 +93,10 @@ ccl_device_inline float4 svm_image_texture_read_2d(int id, int x, int y) x = svm_image_texture_wrap_clamp(x, info.width); y = svm_image_texture_wrap_clamp(y, info.height); } + else if (info.extension == EXTENSION_MIRROR) { + x = svm_image_texture_wrap_mirror(x, info.width); + y = svm_image_texture_wrap_mirror(y, info.height); + } else { if (x < 0 || x >= info.width || y < 0 || y >= info.height) { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); @@ -109,6 +121,11 @@ ccl_device_inline float4 svm_image_texture_read_3d(int id, int x, int y, int z) y = svm_image_texture_wrap_clamp(y, info.height); z = svm_image_texture_wrap_clamp(z, info.depth); } + else if (info.extension == EXTENSION_MIRROR) { + x = svm_image_texture_wrap_mirror(x, info.width); + y = svm_image_texture_wrap_mirror(y, info.height); + z = svm_image_texture_wrap_mirror(z, info.depth); + } else { if (x < 0 || x >= info.width || y < 0 || y >= info.height || z < 0 || z >= info.depth) { return make_float4(0.0f, 0.0f, 0.0f, 0.0f); diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index a64953c03ec..e95f362793f 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -226,6 +226,7 @@ NODE_DEFINE(ImageTextureNode) extension_enum.insert("periodic", EXTENSION_REPEAT); extension_enum.insert("clamp", EXTENSION_EXTEND); extension_enum.insert("black", EXTENSION_CLIP); + extension_enum.insert("mirror", EXTENSION_MIRROR); SOCKET_ENUM(extension, "Extension", extension_enum, EXTENSION_REPEAT); static NodeEnum projection_enum; diff --git a/intern/cycles/util/texture.h b/intern/cycles/util/texture.h index 90e842933c2..6820cb9be0a 100644 --- a/intern/cycles/util/texture.h +++ b/intern/cycles/util/texture.h @@ -65,6 +65,8 @@ typedef enum ExtensionType { EXTENSION_EXTEND = 1, /* Clip to image size and set exterior pixels as transparent. */ EXTENSION_CLIP = 2, + /* Repeatedly flip the image horizontally and vertically. */ + EXTENSION_MIRROR = 3, EXTENSION_NUM_TYPES, } ExtensionType; diff --git a/source/blender/draw/engines/workbench/workbench_materials.cc b/source/blender/draw/engines/workbench/workbench_materials.cc index c95bebb61e8..296f8c53f2e 100644 --- a/source/blender/draw/engines/workbench/workbench_materials.cc +++ b/source/blender/draw/engines/workbench/workbench_materials.cc @@ -97,11 +97,13 @@ BLI_INLINE void workbench_material_get_image( case SH_NODE_TEX_IMAGE: { const NodeTexImage *storage = static_cast(node->storage); const bool use_filter = (storage->interpolation != SHD_INTERP_CLOSEST); - const bool use_repeat = (storage->extension == SHD_IMAGE_EXTENSION_REPEAT); + const bool use_mirror = (storage->extension == SHD_IMAGE_EXTENSION_MIRROR); + const bool use_repeat = use_mirror || (storage->extension == SHD_IMAGE_EXTENSION_REPEAT); const bool use_clip = (storage->extension == SHD_IMAGE_EXTENSION_CLIP); SET_FLAG_FROM_TEST(*r_sampler, use_filter, GPU_SAMPLER_FILTER); SET_FLAG_FROM_TEST(*r_sampler, use_repeat, GPU_SAMPLER_REPEAT); SET_FLAG_FROM_TEST(*r_sampler, use_clip, GPU_SAMPLER_CLAMP_BORDER); + SET_FLAG_FROM_TEST(*r_sampler, use_mirror, GPU_SAMPLER_MIRROR_REPEAT); break; } case SH_NODE_TEX_ENVIRONMENT: { diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 6cbdda4cd4c..17639d19e61 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -35,7 +35,8 @@ typedef enum eGPUSamplerState { GPU_SAMPLER_CLAMP_BORDER = (1 << 5), /* Clamp to border color instead of border texel. */ GPU_SAMPLER_COMPARE = (1 << 6), GPU_SAMPLER_ANISO = (1 << 7), - GPU_SAMPLER_ICON = (1 << 8), + GPU_SAMPLER_MIRROR_REPEAT = (1 << 8), /* Requires any REPEAT flag to be set. */ + GPU_SAMPLER_ICON = (1 << 9), GPU_SAMPLER_REPEAT = (GPU_SAMPLER_REPEAT_S | GPU_SAMPLER_REPEAT_T | GPU_SAMPLER_REPEAT_R), } eGPUSamplerState; diff --git a/source/blender/gpu/metal/mtl_context.mm b/source/blender/gpu/metal/mtl_context.mm index b20a0f7faa8..9e03f926787 100644 --- a/source/blender/gpu/metal/mtl_context.mm +++ b/source/blender/gpu/metal/mtl_context.mm @@ -1595,14 +1595,17 @@ id MTLContext::generate_sampler_from_state(MTLSamplerState samp MTLSamplerAddressMode clamp_type = (sampler_state.state & GPU_SAMPLER_CLAMP_BORDER) ? MTLSamplerAddressModeClampToBorderColor : MTLSamplerAddressModeClampToEdge; + MTLSamplerAddressMode repeat_type = (sampler_state.state & GPU_SAMPLER_MIRROR_REPEAT) ? + MTLSamplerAddressModeMirrorRepeat : + MTLSamplerAddressModeRepeat; descriptor.rAddressMode = (sampler_state.state & GPU_SAMPLER_REPEAT_R) ? - MTLSamplerAddressModeRepeat : + repeat_type : clamp_type; descriptor.sAddressMode = (sampler_state.state & GPU_SAMPLER_REPEAT_S) ? - MTLSamplerAddressModeRepeat : + repeat_type : clamp_type; descriptor.tAddressMode = (sampler_state.state & GPU_SAMPLER_REPEAT_T) ? - MTLSamplerAddressModeRepeat : + repeat_type : clamp_type; descriptor.borderColor = MTLSamplerBorderColorTransparentBlack; descriptor.minFilter = (sampler_state.state & GPU_SAMPLER_FILTER) ? diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index 6db73345d5f..6ec079f44b8 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -548,12 +548,13 @@ GLuint GLTexture::samplers_[GPU_SAMPLER_MAX] = {0}; void GLTexture::samplers_init() { glGenSamplers(GPU_SAMPLER_MAX, samplers_); - for (int i = 0; i <= GPU_SAMPLER_ICON - 1; i++) { + for (int i = 0; i < GPU_SAMPLER_ICON; i++) { eGPUSamplerState state = static_cast(i); GLenum clamp_type = (state & GPU_SAMPLER_CLAMP_BORDER) ? GL_CLAMP_TO_BORDER : GL_CLAMP_TO_EDGE; - GLenum wrap_s = (state & GPU_SAMPLER_REPEAT_S) ? GL_REPEAT : clamp_type; - GLenum wrap_t = (state & GPU_SAMPLER_REPEAT_T) ? GL_REPEAT : clamp_type; - GLenum wrap_r = (state & GPU_SAMPLER_REPEAT_R) ? GL_REPEAT : clamp_type; + GLenum repeat_type = (state & GPU_SAMPLER_MIRROR_REPEAT) ? GL_MIRRORED_REPEAT : GL_REPEAT; + GLenum wrap_s = (state & GPU_SAMPLER_REPEAT_S) ? repeat_type : clamp_type; + GLenum wrap_t = (state & GPU_SAMPLER_REPEAT_T) ? repeat_type : clamp_type; + GLenum wrap_r = (state & GPU_SAMPLER_REPEAT_R) ? repeat_type : clamp_type; GLenum mag_filter = (state & GPU_SAMPLER_FILTER) ? GL_LINEAR : GL_NEAREST; GLenum min_filter = (state & GPU_SAMPLER_FILTER) ? ((state & GPU_SAMPLER_MIPMAP) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) : @@ -577,7 +578,7 @@ void GLTexture::samplers_init() char sampler_name[128] = "\0\0"; SNPRINTF(sampler_name, - "%s%s%s%s%s%s%s%s%s%s", + "%s%s%s%s%s%s%s%s%s%s%s", (state == GPU_SAMPLER_DEFAULT) ? "_default" : "", (state & GPU_SAMPLER_FILTER) ? "_filter" : "", (state & GPU_SAMPLER_MIPMAP) ? "_mipmap" : "", @@ -585,6 +586,7 @@ void GLTexture::samplers_init() (state & GPU_SAMPLER_REPEAT_S) ? "S" : "", (state & GPU_SAMPLER_REPEAT_T) ? "T" : "", (state & GPU_SAMPLER_REPEAT_R) ? "R" : "", + (state & GPU_SAMPLER_MIRROR_REPEAT) ? "-mirror" : "", (state & GPU_SAMPLER_CLAMP_BORDER) ? "_clamp_border" : "", (state & GPU_SAMPLER_COMPARE) ? "_compare" : "", (state & GPU_SAMPLER_ANISO) ? "_aniso" : ""); @@ -612,7 +614,7 @@ void GLTexture::samplers_update() float aniso_filter = min_ff(max_anisotropy, U.anisotropic_filter); - for (int i = 0; i <= GPU_SAMPLER_ICON - 1; i++) { + for (int i = 0; i < GPU_SAMPLER_ICON; i++) { eGPUSamplerState state = static_cast(i); if ((state & GPU_SAMPLER_ANISO) && (state & GPU_SAMPLER_MIPMAP)) { glSamplerParameterf(samplers_[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso_filter); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 6313791bd3c..eddc26fe867 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -1754,6 +1754,7 @@ enum { #define SHD_IMAGE_EXTENSION_REPEAT 0 #define SHD_IMAGE_EXTENSION_EXTEND 1 #define SHD_IMAGE_EXTENSION_CLIP 2 +#define SHD_IMAGE_EXTENSION_MIRROR 3 /* image texture */ #define SHD_PROJ_FLAT 0 diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 4a977f09884..7e12483a543 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -4690,6 +4690,30 @@ static const EnumPropertyItem node_subsurface_method_items[] = { "automatically adjusted to match color textures"}, {0, NULL, 0, NULL, NULL}}; +static const EnumPropertyItem prop_image_extension[] = { + {SHD_IMAGE_EXTENSION_REPEAT, + "REPEAT", + 0, + "Repeat", + "Cause the image to repeat horizontally and vertically"}, + {SHD_IMAGE_EXTENSION_EXTEND, + "EXTEND", + 0, + "Extend", + "Extend by repeating edge pixels of the image"}, + {SHD_IMAGE_EXTENSION_CLIP, + "CLIP", + 0, + "Clip", + "Clip to image size and set exterior pixels as transparent"}, + {SHD_IMAGE_EXTENSION_MIRROR, + "MIRROR", + 0, + "Mirror", + "Repeatedly flip the image horizontally and vertically"}, + {0, NULL, 0, NULL, NULL}, +}; + /* -- Common nodes ---------------------------------------------------------- */ static void def_group_input(StructRNA *UNUSED(srna)) @@ -5431,25 +5455,6 @@ static void def_sh_tex_image(StructRNA *srna) {0, NULL, 0, NULL, NULL}, }; - static const EnumPropertyItem prop_image_extension[] = { - {SHD_IMAGE_EXTENSION_REPEAT, - "REPEAT", - 0, - "Repeat", - "Cause the image to repeat horizontally and vertically"}, - {SHD_IMAGE_EXTENSION_EXTEND, - "EXTEND", - 0, - "Extend", - "Extend by repeating edge pixels of the image"}, - {SHD_IMAGE_EXTENSION_CLIP, - "CLIP", - 0, - "Clip", - "Clip to image size and set exterior pixels as transparent"}, - {0, NULL, 0, NULL, NULL}, - }; - PropertyRNA *prop; prop = RNA_def_property(srna, "image", PROP_POINTER, PROP_NONE); @@ -5516,25 +5521,6 @@ static void def_geo_image_texture(StructRNA *srna) {0, NULL, 0, NULL, NULL}, }; - static const EnumPropertyItem prop_image_extension[] = { - {SHD_IMAGE_EXTENSION_REPEAT, - "REPEAT", - 0, - "Repeat", - "Cause the image to repeat horizontally and vertically"}, - {SHD_IMAGE_EXTENSION_EXTEND, - "EXTEND", - 0, - "Extend", - "Extend by repeating edge pixels of the image"}, - {SHD_IMAGE_EXTENSION_CLIP, - "CLIP", - 0, - "Clip", - "Clip to image size and set exterior pixels as transparent"}, - {0, NULL, 0, NULL, NULL}, - }; - PropertyRNA *prop; RNA_def_struct_sdna_from(srna, "NodeGeometryImageTexture", "storage"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc index 3c0f3af4ed2..6a2ff2e1ead 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc @@ -114,6 +114,15 @@ class ImageFieldsFunction : public fn::MultiFunction { return std::clamp(x, 0, width - 1); } + static int wrap_mirror(const int x, const int width) + { + const int m = std::abs(x + (x < 0)) % (2 * width); + if (m >= width) { + return 2 * width - m - 1; + } + return m; + } + static float4 image_pixel_lookup(const ImBuf &ibuf, const int px, const int py) { if (px < 0 || py < 0 || px >= ibuf.x || py >= ibuf.y) { @@ -173,6 +182,17 @@ class ImageFieldsFunction : public fn::MultiFunction { piy = wrap_clamp(piy, height); break; } + case SHD_IMAGE_EXTENSION_MIRROR: { + ppix = wrap_mirror(pix - 1, width); + ppiy = wrap_mirror(piy - 1, height); + nix = wrap_mirror(pix + 1, width); + niy = wrap_mirror(piy + 1, height); + nnix = wrap_mirror(pix + 2, width); + nniy = wrap_mirror(piy + 2, height); + pix = wrap_mirror(pix, width); + piy = wrap_mirror(piy, height); + break; + } default: return float4(0.0f, 0.0f, 0.0f, 0.0f); } @@ -233,6 +253,12 @@ class ImageFieldsFunction : public fn::MultiFunction { piy = wrap_clamp(piy, height); break; } + case SHD_IMAGE_EXTENSION_MIRROR: + nix = wrap_mirror(pix + 1, width); + niy = wrap_mirror(piy + 1, height); + pix = wrap_mirror(pix, width); + piy = wrap_mirror(piy, height); + break; default: case SHD_IMAGE_EXTENSION_REPEAT: pix = wrap_periodic(pix, width); @@ -282,6 +308,11 @@ class ImageFieldsFunction : public fn::MultiFunction { iy = wrap_clamp(iy, height); return image_pixel_lookup(ibuf, ix, iy); } + case SHD_IMAGE_EXTENSION_MIRROR: { + ix = wrap_mirror(ix, width); + iy = wrap_mirror(iy, height); + return image_pixel_lookup(ibuf, ix, iy); + } default: return float4(0.0f, 0.0f, 0.0f, 0.0f); } diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc index ab7d65020ed..d8fb30396a3 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc @@ -61,6 +61,9 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, case SHD_IMAGE_EXTENSION_CLIP: sampler_state |= GPU_SAMPLER_CLAMP_BORDER; break; + case SHD_IMAGE_EXTENSION_MIRROR: + sampler_state |= GPU_SAMPLER_REPEAT | GPU_SAMPLER_MIRROR_REPEAT; + break; default: break; } From 4121e32edd9135fc364426f4b3a1763aa32989f1 Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Wed, 14 Dec 2022 19:35:43 +0100 Subject: [PATCH 0109/1522] Fix T102740: don't allow inserting group into itself Differential Revision: https://developer.blender.org/D16602 --- .../blender/editors/space_node/node_group.cc | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc index be9a6c69601..2c28a8fae34 100644 --- a/source/blender/editors/space_node/node_group.cc +++ b/source/blender/editors/space_node/node_group.cc @@ -1114,6 +1114,24 @@ void NODE_OT_group_make(wmOperatorType *ot) /** \name Group Insert Operator * \{ */ +static bool node_tree_contains_tree_recursive(const bNodeTree &ntree_to_search_in, + const bNodeTree &ntree_to_search_for) +{ + if (&ntree_to_search_in == &ntree_to_search_for) { + return true; + } + ntree_to_search_in.ensure_topology_cache(); + for (const bNode *node : ntree_to_search_in.group_nodes()) { + if (node->id) { + if (node_tree_contains_tree_recursive(*reinterpret_cast(node->id), + ntree_to_search_for)) { + return true; + } + } + } + return false; +} + static int node_group_insert_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); @@ -1128,8 +1146,21 @@ static int node_group_insert_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - bNodeTree *ngroup = (bNodeTree *)gnode->id; + bNodeTree *ngroup = reinterpret_cast(gnode->id); VectorSet nodes_to_group = get_nodes_to_group(*ntree, gnode); + + /* Make sure that there won't be a node group containing itself afterwards. */ + for (const bNode *group : nodes_to_group) { + if (!group->is_group() || group->id == nullptr) { + continue; + } + if (node_tree_contains_tree_recursive(*reinterpret_cast(group->id), *ngroup)) { + BKE_reportf( + op->reports, RPT_WARNING, "Can not insert group '%s' in '%s'", group->name, gnode->name); + return OPERATOR_CANCELLED; + } + } + if (!node_group_make_test_selected(*ntree, nodes_to_group, ngroup->idname, *op->reports)) { return OPERATOR_CANCELLED; } From 56237f33a16b9ec4c6f271b09b66eeabc5306e44 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 14 Dec 2022 19:47:21 +0100 Subject: [PATCH 0110/1522] Fix T103101: random Cycles animation rendering freezing up the application --- source/blender/render/intern/engine.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/blender/render/intern/engine.cc b/source/blender/render/intern/engine.cc index b9672246c5f..7d78f957e31 100644 --- a/source/blender/render/intern/engine.cc +++ b/source/blender/render/intern/engine.cc @@ -1046,14 +1046,19 @@ bool RE_engine_render(Render *re, bool do_all) re->engine = engine; } - /* create render result */ + /* Create render result. Do this before acquiring lock, to avoid lock + * inversion as this calls python to get the render passes, while python UI + * code can also hold a lock on the render result. */ + const bool create_new_result = (re->result == nullptr || !(re->r.scemode & R_BUTS_PREVIEW)); + RenderResult *new_result = engine_render_create_result(re); + BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); - if (re->result == nullptr || !(re->r.scemode & R_BUTS_PREVIEW)) { + if (create_new_result) { if (re->result) { render_result_free(re->result); } - re->result = engine_render_create_result(re); + re->result = new_result; } BLI_rw_mutex_unlock(&re->resultmutex); From a3a9459050a96e75138b3441c069898f211f179c Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 14 Dec 2022 15:37:49 -0300 Subject: [PATCH 0111/1522] Fix erratic mouse wrapping movement on Windows (2) This is a solution in response to the issues mentioned in comments on rBe4f1d719080a and T103088. Apparently the workaround of checking if the mouse is already inside the area on the next event doesn't work for some tablets. Perhaps the order of events or some very small jitter is causing this issue on tablets. (Couldn't confirm). Whatever the cause, the solution of checking the timestamp of the event and thus ignoring the outdated ones is theoretically safer. It is the same solution seen in MacOS. Also calling `SendInput` 3 times every warp ensures that at least one event is dispatched. --- intern/ghost/intern/GHOST_SystemWin32.cpp | 55 +++++++++++++---------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 75a4cc8389a..8cb007a756a 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -1061,11 +1061,16 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind int32_t x_screen = screen_co[0], y_screen = screen_co[1]; if (window->getCursorGrabModeIsWarp()) { - /* WORKAROUND: - * Sometimes Windows ignores `SetCursorPos()` or `SendInput()` calls or the mouse event is - * outdated. Identify these cases by checking if the cursor is not yet within bounds. */ - static bool is_warping_x = false; - static bool is_warping_y = false; + static uint64_t last_warp_time = 0; + { + /* WORKAROUND: Check the mouse event timestamp so we can ignore mousemove events that were + * already in the queue before we changed the cursor position. */ + MOUSEMOVEPOINT mp = {x_screen, y_screen}; + ::GetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &mp, &mp, 1, GMMP_USE_DISPLAY_POINTS); + if (mp.time <= last_warp_time) { + return NULL; + } + } int32_t x_new = x_screen; int32_t y_new = y_screen; @@ -1112,31 +1117,35 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind window->getCursorGrabAccum(x_accum, y_accum); if (x_new != x_screen || y_new != y_screen) { - system->setCursorPosition(x_new, y_new); /* wrap */ + /* WORKAROUND: Store the current time so that we ignore outdated mousemove events. */ + last_warp_time = ::GetTickCount64(); - /* Do not update the accum values if we are an outdated or failed pos-warp event. */ - if (!is_warping_x) { - is_warping_x = x_new != x_screen; - if (is_warping_x) { - x_accum += (x_screen - x_new); - } - } + /* For more control over which timestamp to store in the event, we use `SendInput` instead of + * `SetCursorPos` here. + * It is quite unlikely to happen, but still possible that some event between + * `last_warp_time` and `GHOST_SystemWin32::setCursorPosition` is sent. */ + INPUT input[3] = {0}; + input[0].type = INPUT_MOUSE; + input[0].mi.dx = (LONG)(x_new * (65535.0f / GetSystemMetrics(SM_CXSCREEN))); + input[0].mi.dy = (LONG)(y_new * (65535.0f / GetSystemMetrics(SM_CYSCREEN))); + input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; + input[0].mi.time = last_warp_time; - if (!is_warping_y) { - is_warping_y = y_new != y_screen; - if (is_warping_y) { - y_accum += (y_screen - y_new); - } - } + /* Send 3 events with a jitter to make sure Windows does not occasionally and + * inexplicably ignore `SetCursorPos` or `SendInput`. */ + input[2] = input[1] = input[0]; + input[1].mi.dx += 1; + ::SendInput(3, input, sizeof(INPUT)); + + x_accum += (x_screen - x_new); + y_accum += (y_screen - y_new); window->setCursorGrabAccum(x_accum, y_accum); - /* When wrapping we don't need to add an event because the setCursorPosition call will cause - * a new event after. */ + /* When wrapping we don't need to add an event because the `SendInput` call will cause new + * events after. */ return NULL; } - is_warping_x = false; - is_warping_y = false; x_screen += x_accum; y_screen += y_accum; } From c725a53e8961ce3488c5ac2f0ddc2bb786d0d331 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 14 Dec 2022 14:40:02 -0600 Subject: [PATCH 0112/1522] Cleanup: Use standard node function names and namespace --- .../node_geo_distribute_points_in_volume.cc | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc index f2e66e03d26..b0c46c94396 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc @@ -19,11 +19,11 @@ #include "node_geometry_util.hh" -namespace blender::nodes { +namespace blender::nodes::node_geo_distribute_points_in_volume_cc { NODE_STORAGE_FUNCS(NodeGeometryDistributePointsInVolume) -static void geo_node_distribute_points_in_volume_declare(NodeDeclarationBuilder &b) +static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Volume")).supported_type(GEO_COMPONENT_TYPE_VOLUME); b.add_input(N_("Density")) @@ -49,14 +49,12 @@ static void geo_node_distribute_points_in_volume_declare(NodeDeclarationBuilder b.add_output(N_("Points")); } -static void geo_node_distribute_points_in_volume_layout(uiLayout *layout, - bContext * /*C*/, - PointerRNA *ptr) +static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) { uiItemR(layout, ptr, "mode", 0, "", ICON_NONE); } -static void node_distribute_points_in_volume_init(bNodeTree * /*tree*/, bNode *node) +static void node_init(bNodeTree * /*tree*/, bNode *node) { NodeGeometryDistributePointsInVolume *data = MEM_cnew( __func__); @@ -64,7 +62,7 @@ static void node_distribute_points_in_volume_init(bNodeTree * /*tree*/, bNode *n node->storage = data; } -static void node_distribute_points_in_volume_update(bNodeTree *ntree, bNode *node) +static void node_update(bNodeTree *ntree, bNode *node) { const NodeGeometryDistributePointsInVolume &storage = node_storage(*node); GeometryNodeDistributePointsInVolumeMode mode = GeometryNodeDistributePointsInVolumeMode( @@ -181,7 +179,7 @@ static void point_scatter_density_grid(const openvdb::FloatGrid &grid, #endif /* WITH_OPENVDB */ -static void geo_node_distribute_points_in_volume_exec(GeoNodeExecParams params) +static void node_geo_exec(GeoNodeExecParams params) { #ifdef WITH_OPENVDB GeometrySet geometry_set = params.extract_input("Volume"); @@ -265,10 +263,12 @@ static void geo_node_distribute_points_in_volume_exec(GeoNodeExecParams params) TIP_("Disabled, Blender was compiled without OpenVDB")); #endif } -} // namespace blender::nodes +} // namespace blender::nodes::node_geo_distribute_points_in_volume_cc void register_node_type_geo_distribute_points_in_volume() { + namespace file_ns = blender::nodes::node_geo_distribute_points_in_volume_cc; + static bNodeType ntype; geo_node_type_base(&ntype, GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME, @@ -278,11 +278,11 @@ void register_node_type_geo_distribute_points_in_volume() "NodeGeometryDistributePointsInVolume", node_free_standard_storage, node_copy_standard_storage); - ntype.initfunc = blender::nodes::node_distribute_points_in_volume_init; - ntype.updatefunc = blender::nodes::node_distribute_points_in_volume_update; + ntype.initfunc = file_ns::node_init; + ntype.updatefunc = file_ns::node_update; node_type_size(&ntype, 170, 100, 320); - ntype.declare = blender::nodes::geo_node_distribute_points_in_volume_declare; - ntype.geometry_node_execute = blender::nodes::geo_node_distribute_points_in_volume_exec; - ntype.draw_buttons = blender::nodes::geo_node_distribute_points_in_volume_layout; + ntype.declare = file_ns::node_declare; + ntype.geometry_node_execute = file_ns::node_geo_exec; + ntype.draw_buttons = file_ns::node_layout; nodeRegisterType(&ntype); } From 918df11a1a1f753e2274550b724a001116dfdf8d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 08:55:30 +1100 Subject: [PATCH 0113/1522] Build: prefer underscores for script naming Matches convention for most existing scripts. --- .../linux/{linux-rocky8-setup.sh => linux_rocky8_setup.sh} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename build_files/build_environment/linux/{linux-rocky8-setup.sh => linux_rocky8_setup.sh} (100%) diff --git a/build_files/build_environment/linux/linux-rocky8-setup.sh b/build_files/build_environment/linux/linux_rocky8_setup.sh similarity index 100% rename from build_files/build_environment/linux/linux-rocky8-setup.sh rename to build_files/build_environment/linux/linux_rocky8_setup.sh From f167e366da9aa0c1f48f36909da492de61e967ed Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 08:58:30 +1100 Subject: [PATCH 0114/1522] Build: add missing packages for the rocky8 setup script --- .../build_environment/linux/linux_rocky8_setup.sh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/build_files/build_environment/linux/linux_rocky8_setup.sh b/build_files/build_environment/linux/linux_rocky8_setup.sh index 7be07b40a3e..2f4efe0be97 100644 --- a/build_files/build_environment/linux/linux_rocky8_setup.sh +++ b/build_files/build_environment/linux/linux_rocky8_setup.sh @@ -15,7 +15,12 @@ fi # See: https://wiki.rockylinux.org/rocky/repo/#notes-on-unlisted-repositories dnf config-manager --set-enabled powertools -# yum-config-manager does not come in the default minimal install, +# Required by: TODO. +dnf install 'dnf-command(config-manager)' +# Required by: TODO. +dnf install epel-release + +# `yum-config-manager` does not come in the default minimal install, # so make sure it is installed and available. yum -y update yum -y install yum-utils @@ -82,8 +87,10 @@ PACKAGES_FOR_LIBS=( # This is used for the `python3-mako` package for e.g. # So use the "default" system Python since it means it's most compatible with other packages. python3 + # Required by: `external_mesa`. + python3-mako - # Required by: `mesa`. + # Required by: `external_mesa`. expat-devel # Required by: `external_igc` & `external_osl` as a build-time dependency. @@ -114,7 +121,7 @@ PACKAGES_FOR_BLENDER=( yum -y install -y ${PACKAGES_FOR_LIBS[@]} ${PACKAGES_FOR_BLENDER[@]} -# Dependencies for pip (needed for buildbot-worker), uses Python3.6. +# Dependencies for pip (needed for `buildbot-worker`), uses Python3.6. yum -y install python3 python3-pip python3-devel # Dependencies for asound. From 2d21fc3f5d4bb8f9c5d7e5312a79b5c98a850399 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 09:12:17 +1100 Subject: [PATCH 0115/1522] Cleanup: avoid multiplying lists multiple times Parenthesis are important in this case to avoid creating a list with multiplication, then multiplying it again. Oversight in 58c8c4fde35c158407ca2ba0c0bc099d1455f691. --- release/scripts/modules/bpy_extras/anim_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/modules/bpy_extras/anim_utils.py b/release/scripts/modules/bpy_extras/anim_utils.py index cfa7c2aa134..43973307ce6 100644 --- a/release/scripts/modules/bpy_extras/anim_utils.py +++ b/release/scripts/modules/bpy_extras/anim_utils.py @@ -539,7 +539,7 @@ class KeyframesCo: keyframe_points = fcurve.keyframe_points - co_buffer = [0] * 2 * len(keyframe_points) + co_buffer = [0] * (2 * len(keyframe_points)) keyframe_points.foreach_get("co", co_buffer) co_buffer.extend(key_values) From d173a52f56be3dd0f1dea6a9628bad52d2fcd0f7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 09:26:40 +1100 Subject: [PATCH 0116/1522] Cleanup: doc-strings and minor changes to anim_utils.py - Follow sphinx conventions for doc-strings. - Use __slots__ for KeyframesCo as dynamically assigning new members isn't needed. - Import from bpy.types instead of assigning. - Split typing imports across multiple lines as they tend to become quite large. --- .../scripts/modules/bpy_extras/anim_utils.py | 63 ++++++++++++------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/release/scripts/modules/bpy_extras/anim_utils.py b/release/scripts/modules/bpy_extras/anim_utils.py index 43973307ce6..3586401dd7a 100644 --- a/release/scripts/modules/bpy_extras/anim_utils.py +++ b/release/scripts/modules/bpy_extras/anim_utils.py @@ -9,13 +9,24 @@ __all__ = ( ) import bpy -from typing import Mapping, List, Tuple, Sequence +from bpy.types import Action -# (fcurve.data_path, fcurve.array_index) -FCurveKey = Tuple[str, int] -# [frame0, value0, frame1, value1, ...] +from typing import ( + List, + Mapping, + Sequence, + Tuple, +) + +FCurveKey = Tuple[ + # `fcurve.data_path`. + str, + # `fcurve.array_index`. + int, +] + +# List of `[frame0, value0, frame1, value1, ...]` pairs. ListKeyframes = List[float] -Action = bpy.types.Action def bake_action( @@ -144,11 +155,11 @@ def bake_action_iter( # Note: BBONE_PROPS is a list so we can preserve the ordering BBONE_PROPS = [ - 'bbone_curveinx', 'bbone_curveoutx', - 'bbone_curveinz', 'bbone_curveoutz', - 'bbone_rollin', 'bbone_rollout', - 'bbone_scalein', 'bbone_scaleout', - 'bbone_easein', 'bbone_easeout' + "bbone_curveinx", "bbone_curveoutx", + "bbone_curveinz", "bbone_curveoutz", + "bbone_rollin", "bbone_rollout", + "bbone_scalein", "bbone_scaleout", + "bbone_easein", "bbone_easeout" ] BBONE_PROPS_LENGTHS = { "bbone_curveinx": 1, @@ -433,14 +444,18 @@ def bake_action_iter( class KeyframesCo: - """A buffer for keyframe Co unpacked values per FCurveKey. FCurveKeys are added using - add_paths(), Co values stored using extend_co_values(), then finally use - insert_keyframes_into_*_action() for efficiently inserting keys into the fcurves. + """ + A buffer for keyframe Co unpacked values per ``FCurveKey``. ``FCurveKeys`` are added using + ``add_paths()``, Co values stored using extend_co_values(), then finally use + ``insert_keyframes_into_*_action()`` for efficiently inserting keys into the F-curves. Users are limited to one Action Group per instance. """ + __slots__ = ( + "keyframes_from_fcurve", + ) - # keyframes[(rna_path, array_index)] = list(time0,value0, time1,value1,...) + # `keyframes[(rna_path, array_index)] = list(time0,value0, time1,value1,...)`. keyframes_from_fcurve: Mapping[FCurveKey, ListKeyframes] def __init__(self): @@ -480,11 +495,12 @@ class KeyframesCo: action: Action, action_group_name: str, ) -> None: - """Assumes the action is new, that it has no fcurves. Otherwise, the only difference between versions is + """ + Assumes the action is new, that it has no F-curves. Otherwise, the only difference between versions is performance and implementation simplicity. - Args: - action_group_name (str): Name of Action Group that fcurves are added to. + :arg action_group_name: Name of Action Group that F-curves are added to. + :type action_group_name: str """ linear_enum_values = [ bpy.types.Keyframe.bl_rna.properties["interpolation"].enum_items["LINEAR"].value @@ -513,14 +529,15 @@ class KeyframesCo: action: Action, action_group_name: str, ) -> None: - """Assumes the action already exists, that it might already have fcurves. Otherwise, the + """ + Assumes the action already exists, that it might already have F-curves. Otherwise, the only difference between versions is performance and implementation simplicity. - Args: - lookup_fcurves (Mapping[FCurveKey, bpy.types.FCurve]): This is only used for efficiency. - It's a substitute for action.fcurves.find() which is a potentially expensive linear - search. - action_group_name (str): Name of Action Group that fcurves are added to. + :arg lookup_fcurves: : This is only used for efficiency. + It's a substitute for ``action.fcurves.find()`` which is a potentially expensive linear search. + :type lookup_fcurves: ``Mapping[FCurveKey, bpy.types.FCurve]`` + :arg action_group_name: Name of Action Group that F-curves are added to. + :type action_group_name: str """ linear_enum_values = [ bpy.types.Keyframe.bl_rna.properties["interpolation"].enum_items["LINEAR"].value From e476afff41249826dd51862af7b009571b3ca0ae Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 09:34:22 +1100 Subject: [PATCH 0117/1522] Cleanup: format --- .../build_environment/darwin/set_rpath.py | 2 ++ release/scripts/startup/bl_ui/__init__.py | 2 ++ source/blender/blenkernel/BKE_paint.h | 2 +- .../blenkernel/intern/blendfile_link_append.c | 15 +++++++-------- .../draw/engines/image/image_private.hh | 1 - .../workbench_shadow_caps_vert_no_geom.glsl | 7 ++++--- source/blender/editors/transform/transform.h | 1 - source/blender/gpu/metal/mtl_context.mm | 19 ++++++++----------- .../makesrna/intern/rna_gpencil_modifier.c | 18 +++++++++--------- source/blender/makesrna/intern/rna_layer.c | 3 ++- source/blender/makesrna/intern/rna_object.c | 9 +++++---- source/blender/makesrna/intern/rna_scene.c | 6 +++++- .../nodes/node_geo_instance_on_points.cc | 6 +++--- .../blender/windowmanager/intern/wm_files.c | 15 +++++++-------- 14 files changed, 55 insertions(+), 51 deletions(-) diff --git a/build_files/build_environment/darwin/set_rpath.py b/build_files/build_environment/darwin/set_rpath.py index 6ca58875ac1..e53497b84fb 100644 --- a/build_files/build_environment/darwin/set_rpath.py +++ b/build_files/build_environment/darwin/set_rpath.py @@ -6,6 +6,7 @@ import re import subprocess import sys + # Strip version numbers from dependenciesm macOS notarizatiom fails # with version symlinks. def strip_lib_version(name): @@ -14,6 +15,7 @@ def strip_lib_version(name): name = re.sub(r'(\.[0-9]+)+.cpython', '.cpython', name) return name + rpath = sys.argv[1] file = sys.argv[2] diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 4822370c9ea..592eaf57a97 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -94,6 +94,7 @@ _namespace = globals() _modules_loaded = [_namespace[name] for name in _modules] del _namespace + def _addon_support_items(): """Return the addon support levels suitable for this Blender build.""" @@ -105,6 +106,7 @@ def _addon_support_items(): items.append(('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)")) return items + def register(): from bpy.utils import register_class for mod in _modules_loaded: diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 4acaa7b05e1..5c878486c68 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -520,7 +520,7 @@ typedef struct SculptAttribute { * This will be true if simple_array is requested in * SculptAttributeParams, or the PBVH type is PBVH_GRIDS or PBVH_BMESH. */ - bool simple_array; + bool simple_array; /* Data stored per BMesh element. */ int bmesh_cd_offset; diff --git a/source/blender/blenkernel/intern/blendfile_link_append.c b/source/blender/blenkernel/intern/blendfile_link_append.c index ea68e939e5a..409ae39f6be 100644 --- a/source/blender/blenkernel/intern/blendfile_link_append.c +++ b/source/blender/blenkernel/intern/blendfile_link_append.c @@ -996,14 +996,13 @@ static void blendfile_link_append_proxies_convert(Main *bmain, ReportList *repor if (bf_reports.count.proxies_to_lib_overrides_success != 0 || bf_reports.count.proxies_to_lib_overrides_failures != 0) { - BKE_reportf( - bf_reports.reports, - RPT_WARNING, - "Proxies have been removed from Blender (%d proxies were automatically converted " - "to library overrides, %d proxies could not be converted and were cleared). " - "Consider re-saving any library .blend file with the newest Blender version", - bf_reports.count.proxies_to_lib_overrides_success, - bf_reports.count.proxies_to_lib_overrides_failures); + BKE_reportf(bf_reports.reports, + RPT_WARNING, + "Proxies have been removed from Blender (%d proxies were automatically converted " + "to library overrides, %d proxies could not be converted and were cleared). " + "Consider re-saving any library .blend file with the newest Blender version", + bf_reports.count.proxies_to_lib_overrides_success, + bf_reports.count.proxies_to_lib_overrides_failures); } } diff --git a/source/blender/draw/engines/image/image_private.hh b/source/blender/draw/engines/image/image_private.hh index 7fa58f43d06..8241b7e288e 100644 --- a/source/blender/draw/engines/image/image_private.hh +++ b/source/blender/draw/engines/image/image_private.hh @@ -34,7 +34,6 @@ struct IMAGE_Data { IMAGE_InstanceData *instance_data; }; - /** * Abstract class for a drawing mode of the image engine. * diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_vert_no_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_vert_no_geom.glsl index 8f21b55fa18..e2eabfa5b9e 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_vert_no_geom.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_vert_no_geom.glsl @@ -97,9 +97,10 @@ void main() #endif if (!is_manifold || !backface) { - bool do_front = (output_triangle_id==0)?true:false; - emit_cap(do_front, invert, output_vertex_id%3); - } else { + bool do_front = (output_triangle_id == 0) ? true : false; + emit_cap(do_front, invert, output_vertex_id % 3); + } + else { DISCARD_VERTEX } } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 169937d17e2..206c1830617 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -23,7 +23,6 @@ extern "C" { #endif - /* -------------------------------------------------------------------- */ /** \name Types/ * \{ */ diff --git a/source/blender/gpu/metal/mtl_context.mm b/source/blender/gpu/metal/mtl_context.mm index 9e03f926787..16530fcfeed 100644 --- a/source/blender/gpu/metal/mtl_context.mm +++ b/source/blender/gpu/metal/mtl_context.mm @@ -1596,17 +1596,14 @@ id MTLContext::generate_sampler_from_state(MTLSamplerState samp MTLSamplerAddressModeClampToBorderColor : MTLSamplerAddressModeClampToEdge; MTLSamplerAddressMode repeat_type = (sampler_state.state & GPU_SAMPLER_MIRROR_REPEAT) ? - MTLSamplerAddressModeMirrorRepeat : - MTLSamplerAddressModeRepeat; - descriptor.rAddressMode = (sampler_state.state & GPU_SAMPLER_REPEAT_R) ? - repeat_type : - clamp_type; - descriptor.sAddressMode = (sampler_state.state & GPU_SAMPLER_REPEAT_S) ? - repeat_type : - clamp_type; - descriptor.tAddressMode = (sampler_state.state & GPU_SAMPLER_REPEAT_T) ? - repeat_type : - clamp_type; + MTLSamplerAddressModeMirrorRepeat : + MTLSamplerAddressModeRepeat; + descriptor.rAddressMode = (sampler_state.state & GPU_SAMPLER_REPEAT_R) ? repeat_type : + clamp_type; + descriptor.sAddressMode = (sampler_state.state & GPU_SAMPLER_REPEAT_S) ? repeat_type : + clamp_type; + descriptor.tAddressMode = (sampler_state.state & GPU_SAMPLER_REPEAT_T) ? repeat_type : + clamp_type; descriptor.borderColor = MTLSamplerBorderColorTransparentBlack; descriptor.minFilter = (sampler_state.state & GPU_SAMPLER_FILTER) ? MTLSamplerMinMagFilterLinear : diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index d9186021eb0..6d74fd7eab8 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -3509,10 +3509,9 @@ static void rna_def_modifier_gpencillineart(BlenderRNA *brna) prop = RNA_def_property(srna, "use_object_instances", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "calculation_flags", LRT_ALLOW_DUPLI_OBJECTS); - RNA_def_property_ui_text( - prop, - "Instanced Objects", - "Allow particle objects and face/vertex instances to show in line art"); + RNA_def_property_ui_text(prop, + "Instanced Objects", + "Allow particle objects and face/vertex instances to show in line art"); RNA_def_property_update(prop, NC_SCENE, "rna_GpencilModifier_update"); prop = RNA_def_property(srna, "use_edge_overlap", PROP_BOOLEAN, PROP_NONE); @@ -3893,11 +3892,12 @@ static void rna_def_modifier_gpencillineart(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); prop = RNA_def_property(srna, "shadow_camera_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_ui_text(prop, - "Shadow Camera Size", - "Represents the \"Orthographic Scale\" of an orthographic camera. " - "If the camera is positioned at the light's location with this scale, it will " - "represent the coverage of the shadow \"camera\""); + RNA_def_property_ui_text( + prop, + "Shadow Camera Size", + "Represents the \"Orthographic Scale\" of an orthographic camera. " + "If the camera is positioned at the light's location with this scale, it will " + "represent the coverage of the shadow \"camera\""); RNA_def_property_ui_range(prop, 0.0f, 500.0f, 0.1f, 2); RNA_def_property_range(prop, 0.0f, 10000.0f); diff --git a/source/blender/makesrna/intern/rna_layer.c b/source/blender/makesrna/intern/rna_layer.c index 42d85d2d3bf..7931d7681f6 100644 --- a/source/blender/makesrna/intern/rna_layer.c +++ b/source/blender/makesrna/intern/rna_layer.c @@ -435,7 +435,8 @@ static void rna_def_layer_collection(BlenderRNA *brna) prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "collection->id.name"); RNA_def_property_clear_flag(prop, PROP_EDITABLE | PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Name", "Name of this layer collection (same as its collection one)"); + RNA_def_property_ui_text( + prop, "Name", "Name of this layer collection (same as its collection one)"); RNA_def_property_string_funcs( prop, "rna_LayerCollection_name_get", "rna_LayerCollection_name_length", NULL); RNA_def_struct_name_property(srna, prop); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 8caedfd248c..8a24aa113b7 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -782,10 +782,11 @@ static void rna_Object_dup_collection_set(PointerRNA *ptr, } } else { - BKE_report(NULL, - RPT_ERROR, - "Cannot set instance-collection as object belongs in collection being instanced, thus " - "causing a cycle"); + BKE_report( + NULL, + RPT_ERROR, + "Cannot set instance-collection as object belongs in collection being instanced, thus " + "causing a cycle"); } } diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 0fb5b30a57c..d2cf80d8891 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -7821,7 +7821,11 @@ void RNA_def_scene(BlenderRNA *brna) {3, "LINEAR", 0, "Linear", "Linear distance model"}, {4, "LINEAR_CLAMPED", 0, "Linear Clamped", "Linear distance model with clamping"}, {5, "EXPONENT", 0, "Exponential", "Exponential distance model"}, - {6, "EXPONENT_CLAMPED", 0, "Exponential Clamped", "Exponential distance model with clamping"}, + {6, + "EXPONENT_CLAMPED", + 0, + "Exponential Clamped", + "Exponential distance model with clamping"}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc index b9e5f403722..898a2d71ca7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc @@ -28,9 +28,9 @@ static void node_declare(NodeDeclarationBuilder &b) "instancing the entire geometry")); b.add_input(N_("Instance Index")) .implicit_field(implicit_field_inputs::id_or_index) - .description(N_( - "Index of the instance used for each point. This is only used when Pick Instances " - "is on. By default the point index is used")); + .description( + N_("Index of the instance used for each point. This is only used when Pick Instances " + "is on. By default the point index is used")); b.add_input(N_("Rotation")) .subtype(PROP_EULER) .supports_field() diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 1991a755c4b..2324426538b 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -891,14 +891,13 @@ static void file_read_reports_finalize(BlendFileReadReport *bf_reports) if (bf_reports->count.proxies_to_lib_overrides_success != 0 || bf_reports->count.proxies_to_lib_overrides_failures != 0) { - BKE_reportf( - bf_reports->reports, - RPT_WARNING, - "Proxies have been removed from Blender (%d proxies were automatically converted " - "to library overrides, %d proxies could not be converted and were cleared). " - "Consider re-saving any library .blend file with the newest Blender version", - bf_reports->count.proxies_to_lib_overrides_success, - bf_reports->count.proxies_to_lib_overrides_failures); + BKE_reportf(bf_reports->reports, + RPT_WARNING, + "Proxies have been removed from Blender (%d proxies were automatically converted " + "to library overrides, %d proxies could not be converted and were cleared). " + "Consider re-saving any library .blend file with the newest Blender version", + bf_reports->count.proxies_to_lib_overrides_success, + bf_reports->count.proxies_to_lib_overrides_failures); } if (bf_reports->count.sequence_strips_skipped != 0) { From 2dd27d5f06bd4bc01ce3db66a731468b3004552c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 09:39:23 +1100 Subject: [PATCH 0118/1522] Cleanup: remove function for accessing supported add-ons This was only called once in a situation where such functions are typically used as a dynamic enum callbacks. Prefer keeping the items close to the EnumProperty definition & avoid the need to note why this is a special case that doesn't follow the common pattern for enum callbacks. --- release/scripts/startup/bl_ui/__init__.py | 24 +++++++++++------------ 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 592eaf57a97..01ae0730fab 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -95,18 +95,6 @@ _modules_loaded = [_namespace[name] for name in _modules] del _namespace -def _addon_support_items(): - """Return the addon support levels suitable for this Blender build.""" - - items = [ - ('OFFICIAL', "Official", "Officially supported"), - ('COMMUNITY', "Community", "Maintained by community developers"), - ] - if bpy.app.version_cycle == 'alpha': - items.append(('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)")) - return items - - def register(): from bpy.utils import register_class for mod in _modules_loaded: @@ -152,13 +140,23 @@ def register(): description="Filter add-ons by category", ) + # These items are static but depend on the version cycle. + items = [ + ('OFFICIAL', "Official", "Officially supported"), + ('COMMUNITY', "Community", "Maintained by community developers"), + ] + if bpy.app.version_cycle == "alpha": + items.append(('TESTING', "Testing", "Newly contributed scripts (excluded from release builds)")) + WindowManager.addon_support = EnumProperty( - items=_addon_support_items(), + items=items, name="Support", description="Display support level", default={'OFFICIAL', 'COMMUNITY'}, options={'ENUM_FLAG'}, ) + del items + # done... From e0fbeb6e7ba7467f297f24d618d16b73ddb3f4b5 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 14 Dec 2022 17:07:44 -0600 Subject: [PATCH 0119/1522] Fix T103225: Line Art modifier skips loose edges 1ea169d90e39647eac72 neglected to increase the loose edge count. --- .../blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index dc65ffd60a4..c7a83efefdc 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -2109,11 +2109,11 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, loose_data.loose_array = static_cast( MEM_malloc_arrayN(loose_edges.count, sizeof(int), __func__)); if (loose_edges.count > 0) { - int loose_i = 0; + loose_data.loose_count = 0; for (const int64_t edge_i : IndexRange(me->totedge)) { if (loose_edges.is_loose_bits[edge_i]) { - loose_data.loose_array[loose_i] = int(edge_i); - loose_i++; + loose_data.loose_array[loose_data.loose_count] = int(edge_i); + loose_data.loose_count++; } } } From 36ca1312c4b2c9cd860f167e3e2fbd12337e9718 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 10:31:18 +1100 Subject: [PATCH 0120/1522] Cleanup: use doxy sections and comments in DNA_scene_types.h --- source/blender/makesdna/DNA_scene_types.h | 672 +++++++++++++--------- 1 file changed, 401 insertions(+), 271 deletions(-) diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 8832e044f5e..5f68b2d0c78 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -47,11 +47,9 @@ struct World; struct bGPdata; struct bNodeTree; -/* ************************************************************* */ -/* Scene Data */ - -/* ************************************************************* */ -/* Output Format Data */ +/* -------------------------------------------------------------------- */ +/** \name FFMPEG + * \{ */ typedef struct AviCodecData { /** Save format. */ @@ -100,17 +98,18 @@ typedef enum eFFMpegPreset { /* Used by WEBM/VP9 and h.264 to control encoding speed vs. file size. * WEBM/VP9 use these values directly, whereas h.264 map those to - * respectively the MEDIUM, SLOWER, and SUPERFAST presets. - */ - /** the default and recommended for most applications */ + * respectively the MEDIUM, SLOWER, and SUPERFAST presets. */ + + /** The default and recommended for most applications. */ FFM_PRESET_GOOD = 10, - /** recommended if you have lots of time and want the best compression efficiency */ + /** Recommended if you have lots of time and want the best compression efficiency. */ FFM_PRESET_BEST = 11, - /** recommended for live / fast encoding */ + /** Recommended for live / fast encoding. */ FFM_PRESET_REALTIME = 12, } eFFMpegPreset; -/* Mapping from easily-understandable descriptions to CRF values. +/** + * Mapping from easily-understandable descriptions to CRF values. * Assumes we output 8-bit video. Needs to be remapped if 10-bit * is output. * We use a slightly wider than "subjectively sane range" according @@ -160,12 +159,15 @@ typedef struct FFMpegCodecData { void *_pad1; } FFMpegCodecData; -/* ************************************************************* */ -/* Audio */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Audio + * \{ */ typedef struct AudioData { - int mixrate; /* 2.5: now in FFMpegCodecData: audio_mixrate */ - float main; /* 2.5: now in FFMpegCodecData: audio_volume */ + int mixrate; /* 2.5: now in FFMpegCodecData: audio_mixrate. */ + float main; /* 2.5: now in FFMpegCodecData: audio_volume. */ float speed_of_sound; float doppler_factor; int distance_model; @@ -175,8 +177,9 @@ typedef struct AudioData { char _pad2[4]; } AudioData; -/* *************************************************************** */ -/* Render Layers */ +/* -------------------------------------------------------------------- */ +/** \name Render Layers + * \{ */ /** Render Layer. */ typedef struct SceneRenderLayer { @@ -196,7 +199,7 @@ typedef struct SceneRenderLayer { /** Converted to ViewLayer layflag and flag. */ int layflag DNA_DEPRECATED; - /* pass_xor has to be after passflag */ + /* Pass_xor has to be after passflag. */ /** Pass_xor has to be after passflag. */ int passflag DNA_DEPRECATED; /** Converted to ViewLayer passflag and flag. */ @@ -227,6 +230,7 @@ typedef struct SceneRenderLayer { #define SCE_LAY_MOTION_BLUR (1 << 9) /* Flags between (1 << 9) and (1 << 15) are set to 1 already, for future options. */ + #define SCE_LAY_FLAG_DEFAULT ((1 << 15) - 1) #define SCE_LAY_UNUSED_4 (1 << 15) @@ -310,7 +314,13 @@ typedef enum eScenePassType { #define RE_PASSNAME_CRYPTOMATTE_ASSET "CryptoAsset" #define RE_PASSNAME_CRYPTOMATTE_MATERIAL "CryptoMaterial" -/** View - MultiView. */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Multi-View + * \{ */ + +/** View (Multi-view). */ typedef struct SceneRenderView { struct SceneRenderView *next, *prev; @@ -333,7 +343,7 @@ enum { SCE_VIEWS_FORMAT_MULTIVIEW = 1, }; -/** #ImageFormatData.views_format (also used for #Sequence.views_format) */ +/** #ImageFormatData.views_format (also used for #Sequence.views_format). */ enum { R_IMF_VIEWS_INDIVIDUAL = 0, R_IMF_VIEWS_STEREO_3D = 1, @@ -381,10 +391,15 @@ typedef enum eStereo3dInterlaceType { S3D_INTERLACE_CHECKERBOARD = 2, } eStereo3dInterlaceType; -/* *************************************************************** */ +/** \} */ -/* Generic image format settings, - * this is used for NodeImageFile and IMAGE_OT_save_as operator too. +/* -------------------------------------------------------------------- */ +/** \name Image Format Data + * \{ */ + +/** + * Generic image format settings, + * this is used for #NodeImageFile and IMAGE_OT_save_as operator too. * * NOTE: its a bit strange that even though this is an image format struct * the imtype can still be used to select video formats. @@ -413,28 +428,29 @@ typedef struct ImageFormatData { /* --- format specific --- */ - /* OpenEXR */ + /** OpenEXR. */ char exr_codec; - /* Cineon */ + /** Cineon. */ char cineon_flag; short cineon_white, cineon_black; float cineon_gamma; - /* Jpeg2000 */ + /** Jpeg2000. */ char jp2_flag; char jp2_codec; - /* TIFF */ + /** TIFF. */ char tiff_codec; char _pad[4]; - /* Multiview */ + /** Multi-view. */ char views_format; Stereo3dFormat stereo3d_format; - /* color management */ + /* Color management members. */ + char color_management; char _pad1[7]; ColorManagedViewSettings view_settings; @@ -480,22 +496,27 @@ typedef struct ImageFormatData { #define R_IMF_FLAG_ZBUF (1 << 0) #define R_IMF_FLAG_PREVIEW_JPG (1 << 1) -/* Return values from #BKE_imtype_valid_depths, note this is depths per channel. */ -/** #ImageFormatData.depth */ +/* */ + +/** + * #ImageFormatData.depth + * + * Return values from #BKE_imtype_valid_depths, note this is depths per channel. + */ typedef enum eImageFormatDepth { - /* 1bits (unused) */ + /** 1bits (unused). */ R_IMF_CHAN_DEPTH_1 = (1 << 0), - /* 8bits (default) */ + /** 8bits (default). */ R_IMF_CHAN_DEPTH_8 = (1 << 1), - /* 10bits (uncommon, Cineon/DPX support) */ + /** 10bits (uncommon, Cineon/DPX support). */ R_IMF_CHAN_DEPTH_10 = (1 << 2), - /* 12bits (uncommon, jp2/DPX support) */ + /** 12bits (uncommon, jp2/DPX support). */ R_IMF_CHAN_DEPTH_12 = (1 << 3), - /* 16bits (tiff, half float exr) */ + /** 16bits (TIFF, half float EXR). */ R_IMF_CHAN_DEPTH_16 = (1 << 4), - /* 24bits (unused) */ + /** 24bits (unused). */ R_IMF_CHAN_DEPTH_24 = (1 << 5), - /* 32bits (full float exr) */ + /** 32bits (full float EXR). */ R_IMF_CHAN_DEPTH_32 = (1 << 6), } eImageFormatDepth; @@ -518,16 +539,16 @@ typedef enum eImageFormatDepth { #define R_IMF_EXR_CODEC_MAX 10 /** #ImageFormatData.jp2_flag */ -#define R_IMF_JP2_FLAG_YCC (1 << 0) /* when disabled use RGB */ /* was R_JPEG2K_YCC */ -#define R_IMF_JP2_FLAG_CINE_PRESET (1 << 1) /* was R_JPEG2K_CINE_PRESET */ -#define R_IMF_JP2_FLAG_CINE_48 (1 << 2) /* was R_JPEG2K_CINE_48FPS */ +#define R_IMF_JP2_FLAG_YCC (1 << 0) /* When disabled use RGB. */ /* Was `R_JPEG2K_YCC`. */ +#define R_IMF_JP2_FLAG_CINE_PRESET (1 << 1) /* Was `R_JPEG2K_CINE_PRESET`. */ +#define R_IMF_JP2_FLAG_CINE_48 (1 << 2) /* Was `R_JPEG2K_CINE_48FPS`. */ /** #ImageFormatData.jp2_codec */ #define R_IMF_JP2_CODEC_JP2 0 #define R_IMF_JP2_CODEC_J2K 1 /** #ImageFormatData.cineon_flag */ -#define R_IMF_CINEON_FLAG_LOG (1 << 0) /* was R_CINEON_LOG */ +#define R_IMF_CINEON_FLAG_LOG (1 << 0) /* Was `R_CINEON_LOG`. */ /** #ImageFormatData.tiff_codec */ enum { @@ -537,6 +558,12 @@ enum { R_IMF_TIFF_CODEC_NONE = 3, }; +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Render Bake + * \{ */ + /** #ImageFormatData.color_management */ #define R_IMF_COLOR_MANAGEMENT_FOLLOW_SCENE 0 #define R_IMF_COLOR_MANAGEMENT_OVERRIDE 1 @@ -566,13 +593,13 @@ typedef struct BakeData { struct Object *cage_object; } BakeData; -/** #BakeData.margin_type (char) */ +/** #BakeData.margin_type (char). */ typedef enum eBakeMarginType { R_BAKE_ADJACENT_FACES = 0, R_BAKE_EXTEND = 1, } eBakeMarginType; -/** #BakeData.normal_swizzle (char) */ +/** #BakeData.normal_swizzle (char). */ typedef enum eBakeNormalSwizzle { R_BAKE_POSX = 0, R_BAKE_POSY = 1, @@ -582,19 +609,19 @@ typedef enum eBakeNormalSwizzle { R_BAKE_NEGZ = 5, } eBakeNormalSwizzle; -/** #BakeData.target (char) */ +/** #BakeData.target (char). */ typedef enum eBakeTarget { R_BAKE_TARGET_IMAGE_TEXTURES = 0, R_BAKE_TARGET_VERTEX_COLORS = 1, } eBakeTarget; -/** #BakeData.save_mode (char) */ +/** #BakeData.save_mode (char). */ typedef enum eBakeSaveMode { R_BAKE_SAVE_INTERNAL = 0, R_BAKE_SAVE_EXTERNAL = 1, } eBakeSaveMode; -/** #BakeData.view_from (char) */ +/** #BakeData.view_from (char). */ typedef enum eBakeViewFrom { R_BAKE_VIEW_FROM_ABOVE_SURFACE = 0, R_BAKE_VIEW_FROM_ACTIVE_CAMERA = 1, @@ -616,8 +643,11 @@ typedef enum eBakePassFilter { #define R_BAKE_PASS_FILTER_ALL (~0) -/* *************************************************************** */ -/* Render Data */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Render Data + * \{ */ typedef struct RenderData { struct ImageFormatData im_format; @@ -640,7 +670,7 @@ typedef struct RenderData { /** Frames to jump during render/playback. */ int frame_step; - /** Standalone player stereo settings */ /* XXX deprecated since .2.5 */ + /** Standalone player stereo settings. */ /* XXX deprecated since .2.5 */ short stereomode DNA_DEPRECATED; /** For the dimensions presets menu. */ @@ -651,7 +681,7 @@ typedef struct RenderData { char _pad6[2]; - /* from buttons: */ + /* From buttons: */ /** * The desired number of pixels in the x direction */ @@ -698,7 +728,7 @@ typedef struct RenderData { /** Render border to render sub-resions. */ rctf border; - /* information on different layers to be rendered */ + /* Information on different layers to be rendered. */ /** Converted to Scene->view_layers. */ ListBase layers DNA_DEPRECATED; /** Converted to Scene->active_layer. */ @@ -717,38 +747,38 @@ typedef struct RenderData { */ float gauss; - /* color management settings - color profiles, gamma correction, etc */ + /** Color management settings - color profiles, gamma correction, etc. */ int color_mgt_flag; - /* Dither noise intensity */ + /** Dither noise intensity. */ float dither_intensity; - /* Bake Render options */ + /* Bake Render options. */ short bake_mode, bake_flag; short bake_margin, bake_samples; short bake_margin_type; char _pad9[6]; float bake_biasdist, bake_user_scale; - /* path to render output */ + /* Path to render output. */ /** 1024 = FILE_MAX. */ /* NOTE: Excluded from `BKE_bpath_foreach_path_` / `scene_foreach_path` code. */ char pic[1024]; - /* stamps flags. */ + /** Stamps flags. */ int stamp; /** Select one of blenders bitmap fonts. */ short stamp_font_id; char _pad3[2]; - /* stamp info user data. */ + /** Stamp info user data. */ char stamp_udata[768]; - /* foreground/background color. */ + /* Foreground/background color. */ float fg_stamp[4]; float bg_stamp[4]; - /* sequencer options */ + /** Sequencer options. */ char seq_prev_type; /** UNUSED. */ char seq_rend_type; @@ -756,7 +786,7 @@ typedef struct RenderData { char seq_flag; char _pad5[3]; - /* render simplify */ + /* Render simplify. */ short simplify_subsurf; short simplify_subsurf_render; short simplify_gpencil; @@ -764,19 +794,19 @@ typedef struct RenderData { float simplify_particles_render; float simplify_volumes; - /* Freestyle line thickness options */ + /** Freestyle line thickness options. */ int line_thickness_mode; /** In pixels. */ float unit_line_thickness; - /* render engine */ + /** Render engine. */ char engine[32]; char _pad2[2]; - /* Performance Options */ + /** Performance Options. */ short perf_flag; - /* Cycles baking */ + /** Cycles baking. */ struct BakeData bake; int _pad8; @@ -784,16 +814,16 @@ typedef struct RenderData { short _pad4; - /* MultiView */ + /* MultiView. */ /** SceneRenderView. */ ListBase views; short actview; short views_format; - /* Hair Display */ + /* Hair Display. */ short hair_type, hair_subdiv; - /* Motion blur shutter */ + /** Motion blur shutter. */ struct CurveMapping mblur_shutter_curve; } RenderData; @@ -808,8 +838,11 @@ typedef enum eHairType { SCE_HAIR_SHAPE_STRIP = 1, } eHairType; -/* *************************************************************** */ -/* Render Conversion/Simplification Settings */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Render Conversion/Simplification Settings + * \{ */ /** Control render convert and shading engine. */ typedef struct RenderProfile { @@ -826,7 +859,7 @@ typedef struct RenderProfile { } RenderProfile; -/* UV Paint */ +/* UV Paint. */ /** #ToolSettings.uv_sculpt_settings */ #define UV_SCULPT_LOCK_BORDERS 1 #define UV_SCULPT_ALL_ISLANDS 2 @@ -836,7 +869,7 @@ typedef struct RenderProfile { #define UV_SCULPT_TOOL_RELAX_HC 2 #define UV_SCULPT_TOOL_RELAX_COTAN 3 -/* Stereo Flags */ +/* Stereo Flags. */ #define STEREO_RIGHT_NAME "right" #define STEREO_LEFT_NAME "left" #define STEREO_RIGHT_SUFFIX "_R" @@ -850,8 +883,11 @@ typedef enum eStereoViews { STEREO_MONO_ID = 3, } eStereoViews; -/* *************************************************************** */ -/* Markers */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Time Line Markers + * \{ */ typedef struct TimeMarker { struct TimeMarker *next, *prev; @@ -862,13 +898,16 @@ typedef struct TimeMarker { struct IDProperty *prop; } TimeMarker; -/* *************************************************************** */ -/* Paint Mode/Tool Data */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Paint Mode/Tool Data + * \{ */ #define PAINT_MAX_INPUT_SAMPLES 64 typedef struct Paint_Runtime { - /* Avoid having to compare with scene pointer everywhere. */ + /** Avoid having to compare with scene pointer everywhere. */ unsigned int tool_offset; unsigned short ob_mode; char _pad[2]; @@ -883,8 +922,10 @@ typedef struct PaintToolSlot { typedef struct Paint { struct Brush *brush; - /* Each tool has its own active brush, - * The currently active tool is defined by the current 'brush'. */ + /** + * Each tool has its own active brush, + * The currently active tool is defined by the current 'brush'. + */ struct PaintToolSlot *tool_slots; int tool_slots_len; char _pad1[4]; @@ -893,18 +934,17 @@ typedef struct Paint { /** Cavity curve. */ struct CurveMapping *cavity_curve; - /* WM Paint cursor */ + /** WM Paint cursor. */ void *paint_cursor; unsigned char paint_cursor_col[4]; - /* enum ePaintFlags */ + /** Enum #ePaintFlags. */ int flags; - /* Paint stroke can use up to PAINT_MAX_INPUT_SAMPLES inputs to - * smooth the stroke */ + /** Paint stroke can use up to PAINT_MAX_INPUT_SAMPLES inputs to smooth the stroke. */ int num_input_samples; - /* flags used for symmetry */ + /** Flags used for symmetry. */ int symmetry_flags; float tile_offset[3]; @@ -913,8 +953,11 @@ typedef struct Paint { struct Paint_Runtime runtime; } Paint; -/* ------------------------------------------- */ -/* Image Paint */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Image Paint + * \{ */ /** Texture/Image Editor. */ typedef struct ImagePaintSettings { @@ -922,7 +965,7 @@ typedef struct ImagePaintSettings { short flag, missing_data; - /* for projection painting only */ + /** For projection painting only. */ short seam_bleed, normal_angle; /** Capture size for re-projection. */ short screen_grab_size[2]; @@ -944,11 +987,14 @@ typedef struct ImagePaintSettings { char _pad[4]; } ImagePaintSettings; -/* ------------------------------------------- */ -/* Paint mode settings */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Paint Mode Settings + * \{ */ typedef struct PaintModeSettings { - /** Source to select canvas from to paint on (ePaintCanvasSource) */ + /** Source to select canvas from to paint on (#ePaintCanvasSource). */ char canvas_source; char _pad[7]; @@ -958,8 +1004,11 @@ typedef struct PaintModeSettings { } PaintModeSettings; -/* ------------------------------------------- */ -/* Particle Edit */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Particle Edit + * \{ */ /** Settings for a Particle Editing Brush. */ typedef struct ParticleBrushData { @@ -995,36 +1044,39 @@ typedef struct ParticleEditSettings { struct Object *shape_object; } ParticleEditSettings; -/* ------------------------------------------- */ -/* Sculpt */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Sculpt + * \{ */ /** Sculpt. */ typedef struct Sculpt { Paint paint; - /* For rotating around a pivot point */ + /** For rotating around a pivot point. */ // float pivot[3]; XXX not used? int flags; - /* Transform tool. */ + /** Transform tool. */ int transform_mode; int automasking_flags; - /* Control tablet input */ + // /* Control tablet input. */ // char tablet_size, tablet_strength; XXX not used? int radial_symm[3]; - /* Maximum edge length for dynamic topology sculpting (in pixels) */ + /** Maximum edge length for dynamic topology sculpting (in pixels). */ float detail_size; - /* Direction used for SCULPT_OT_symmetrize operator */ + /** Direction used for `SCULPT_OT_symmetrize` operator. */ int symmetrize_direction; - /* gravity factor for sculpting */ + /** Gravity factor for sculpting. */ float gravity_factor; - /* scale for constant detail size */ + /* Scale for constant detail size. */ /** Constant detail resolution (Blender unit / constant_detail). */ float constant_detail; float detail_percent; @@ -1037,7 +1089,8 @@ typedef struct Sculpt { float automasking_view_normal_limit, automasking_view_normal_falloff; struct CurveMapping *automasking_cavity_curve; - struct CurveMapping *automasking_cavity_curve_op; /* For use by operators */ + /** For use by operators. */ + struct CurveMapping *automasking_cavity_curve_op; struct Object *gravity_object; } Sculpt; @@ -1053,7 +1106,7 @@ typedef struct UvSculpt { typedef struct GpPaint { Paint paint; int flag; - /* Mode of paint (Materials or Vertex Color). */ + /** Mode of paint (Materials or Vertex Color). */ int mode; } GpPaint; @@ -1084,8 +1137,11 @@ typedef struct GpWeightPaint { char _pad[4]; } GpWeightPaint; -/* ------------------------------------------- */ -/* Vertex Paint */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Vertex Paint + * \{ */ /** Vertex Paint. */ typedef struct VPaint { @@ -1098,12 +1154,15 @@ typedef struct VPaint { /** #VPaint.flag */ enum { - /* weight paint only */ + /** Weight paint only. */ VP_FLAG_VGROUP_RESTRICT = (1 << 7), }; -/* ------------------------------------------- */ -/* GPencil Stroke Sculpting */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Grease-Pencil Stroke Sculpting + * \{ */ /** #GP_Sculpt_Settings.lock_axis */ typedef enum eGP_Lockaxis_Types { @@ -1136,14 +1195,14 @@ typedef struct GP_Sculpt_Settings { int flag; /** #eGP_Lockaxis_Types lock drawing to one axis. */ int lock_axis; - /** Threshold for intersections */ + /** Threshold for intersections. */ float isect_threshold; char _pad[4]; /** Multi-frame edit falloff effect by frame. */ struct CurveMapping *cur_falloff; /** Curve used for primitive tools. */ struct CurveMapping *cur_primitive; - /** Guides used for paint tools */ + /** Guides used for paint tools. */ struct GP_Sculpt_Guide guide; } GP_Sculpt_Settings; @@ -1155,15 +1214,15 @@ typedef enum eGP_Sculpt_SettingsFlag { GP_SCULPT_SETT_FLAG_PRIMITIVE_CURVE = (1 << 1), /** Scale thickness. */ GP_SCULPT_SETT_FLAG_SCALE_THICKNESS = (1 << 3), - /* Stroke Auto-Masking for sculpt. */ + /** Stroke Auto-Masking for sculpt. */ GP_SCULPT_SETT_FLAG_AUTOMASK_STROKE = (1 << 4), - /* Stroke Layer Auto-Masking for sculpt. */ + /** Stroke Layer Auto-Masking for sculpt. */ GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_STROKE = (1 << 5), - /* Stroke Material Auto-Masking for sculpt. */ + /** Stroke Material Auto-Masking for sculpt. */ GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_STROKE = (1 << 6), - /* Active Layer Auto-Masking for sculpt. */ + /** Active Layer Auto-Masking for sculpt. */ GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_ACTIVE = (1 << 7), - /* Active Material Auto-Masking for sculpt. */ + /** Active Material Auto-Masking for sculpt. */ GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_ACTIVE = (1 << 8), } eGP_Sculpt_SettingsFlag; @@ -1173,7 +1232,7 @@ typedef enum eGP_Sculpt_SelectMaskFlag { GP_SCULPT_MASK_SELECTMODE_POINT = (1 << 0), /** Only affect selected strokes. */ GP_SCULPT_MASK_SELECTMODE_STROKE = (1 << 1), - /** only affect selected segments. */ + /** Only affect selected segments. */ GP_SCULPT_MASK_SELECTMODE_SEGMENT = (1 << 2), } eGP_Sculpt_SelectMaskFlag; @@ -1195,23 +1254,23 @@ typedef struct GP_Interpolate_Settings { /** #GP_Interpolate_Settings.flag */ typedef enum eGP_Interpolate_SettingsFlag { - /* apply interpolation to all layers */ + /** Apply interpolation to all layers. */ GP_TOOLFLAG_INTERPOLATE_ALL_LAYERS = (1 << 0), - /* apply interpolation to only selected */ + /** Apply interpolation to only selected. */ GP_TOOLFLAG_INTERPOLATE_ONLY_SELECTED = (1 << 1), - /* Exclude breakdown keyframe type as extreme */ + /** Exclude breakdown keyframe type as extreme. */ GP_TOOLFLAG_INTERPOLATE_EXCLUDE_BREAKDOWNS = (1 << 2), } eGP_Interpolate_SettingsFlag; /** #GP_Interpolate_Settings.type */ typedef enum eGP_Interpolate_Type { - /* Traditional Linear Interpolation */ + /** Traditional Linear Interpolation. */ GP_IPO_LINEAR = 0, - /* CurveMap Defined Interpolation */ + /** CurveMap Defined Interpolation. */ GP_IPO_CURVEMAP = 1, - /* Easing Equations */ + /* Easing Equations. */ GP_IPO_BACK = 3, GP_IPO_BOUNCE = 4, GP_IPO_CIRC = 5, @@ -1224,37 +1283,41 @@ typedef enum eGP_Interpolate_Type { GP_IPO_SINE = 12, } eGP_Interpolate_Type; -/* *************************************************************** */ -/* Unified Paint Settings - */ +/** \} */ -/* These settings can override the equivalent fields in the active +/* -------------------------------------------------------------------- */ +/** \name Unified Paint Settings + * \{ */ + +/** + * These settings can override the equivalent fields in the active * Brush for any paint mode; the flag field controls whether these - * values are used */ + * values are used + */ typedef struct UnifiedPaintSettings { - /* unified radius of brush in pixels */ + /** Unified radius of brush in pixels. */ int size; - /* unified radius of brush in Blender units */ + /** Unified radius of brush in Blender units. */ float unprojected_radius; - /* unified strength of brush */ + /** Unified strength of brush. */ float alpha; - /* unified brush weight, [0, 1] */ + /** Unified brush weight, [0, 1]. */ float weight; - /* unified brush color */ + /** Unified brush color. */ float rgb[3]; - /* unified brush secondary color */ + /** Unified brush secondary color. */ float secondary_rgb[3]; - /* user preferences for sculpt and paint */ + /** User preferences for sculpt and paint. */ int flag; - /* rake rotation */ + /* Rake rotation. */ - /* record movement of mouse so that rake can start at an intuitive angle */ + /** Record movement of mouse so that rake can start at an intuitive angle. */ float last_rake[2]; float last_rake_angle; @@ -1277,35 +1340,39 @@ typedef struct UnifiedPaintSettings { */ float overlap_factor; char draw_inverted; - /* check is there an ongoing stroke right now */ + /** Check is there an ongoing stroke right now. */ char stroke_active; char draw_anchored; char do_linear_conversion; - /* store last location of stroke or whether the mesh was hit. - * Valid only while stroke is active */ + /** + * Store last location of stroke or whether the mesh was hit. + * Valid only while stroke is active. + */ float last_location[3]; int last_hit; float anchored_initial_mouse[2]; - /* radius of brush, premultiplied with pressure. - * In case of anchored brushes contains the anchored radius */ + /** + * Radius of brush, pre-multiplied with pressure. + * In case of anchored brushes contains the anchored radius. + */ float pixel_radius; float initial_pixel_radius; float start_pixel_radius; - /* drawing pressure */ + /** Drawing pressure. */ float size_pressure_value; - /* position of mouse, used to sample the texture */ + /** Position of mouse, used to sample the texture. */ float tex_mouse[2]; - /* position of mouse, used to sample the mask texture */ + /** Position of mouse, used to sample the mask texture. */ float mask_tex_mouse[2]; - /* ColorSpace cache to avoid locking up during sampling */ + /** ColorSpace cache to avoid locking up during sampling. */ struct ColorSpace *colorspace; } UnifiedPaintSettings; @@ -1316,7 +1383,7 @@ typedef enum { UNIFIED_PAINT_WEIGHT = (1 << 5), UNIFIED_PAINT_COLOR = (1 << 6), - /* only used if unified size is enabled, mirrors the brush flag BRUSH_LOCK_SIZE */ + /** Only used if unified size is enabled, mirrors the brush flag #BRUSH_LOCK_SIZE. */ UNIFIED_PAINT_BRUSH_LOCK_SIZE = (1 << 2), UNIFIED_PAINT_FLAG_UNUSED_0 = (1 << 3), @@ -1364,36 +1431,45 @@ enum { CURVE_PAINT_SURFACE_PLANE_VIEW = 2, }; -/* *************************************************************** */ -/* Stats */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Mesh Visualization + * \{ */ /** Stats for Meshes. */ typedef struct MeshStatVis { char type; char _pad1[2]; - /* overhang */ + /* Overhang. */ char overhang_axis; float overhang_min, overhang_max; - /* thickness */ + /* Thickness. */ float thickness_min, thickness_max; char thickness_samples; char _pad2[3]; - /* distort */ + /* Distort. */ float distort_min, distort_max; - /* sharp */ + /* Sharp. */ float sharp_min, sharp_max; } MeshStatVis; +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Sequencer Tool Settings + * \{ */ + typedef struct SequencerToolSettings { - /* eSeqImageFitMethod */ + /** #eSeqImageFitMethod. */ int fit_method; short snap_mode; short snap_flag; - /* eSeqOverlapMode */ + /** #eSeqOverlapMode. */ int overlap_mode; /** * When there are many snap points, @@ -1416,8 +1492,11 @@ typedef enum eSeqImageFitMethod { SEQ_USE_ORIGINAL_SIZE, } eSeqImageFitMethod; -/* *************************************************************** */ -/* Tool Settings */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Tool Settings + * \{ */ /** #CurvePaintSettings.surface_plane */ enum { @@ -1444,8 +1523,7 @@ typedef struct ToolSettings { /** Curves sculpt. */ CurvesSculpt *curves_sculpt; - /* Vertex group weight - used only for editmode, not weight - * paint */ + /** Vertex group weight - used only for editmode, not weight paint. */ float vgroup_weight; /** Remove doubles limit. */ @@ -1453,10 +1531,10 @@ typedef struct ToolSettings { char automerge; char object_flag; - /* Selection Mode for Mesh */ + /** Selection Mode for Mesh. */ char selectmode; - /* UV Calculation */ + /* UV Calculation. */ char unwrapper; char uvcalc_flag; char uv_flag; @@ -1465,11 +1543,11 @@ typedef struct ToolSettings { float uvcalc_margin; - /* Auto-IK */ + /* Auto-IK. */ /** Runtime only. */ short autoik_chainlen; - /* Grease Pencil */ + /* Grease Pencil. */ /** Flags/options for how the tool works. */ char gpencil_flags; @@ -1479,7 +1557,7 @@ typedef struct ToolSettings { char gpencil_v2d_align; char _pad0[2]; - /* Annotations */ + /* Annotations. */ /** Stroke placement settings - 3D View. */ char annotate_v3d_align; @@ -1490,43 +1568,44 @@ typedef struct ToolSettings { /** Stroke selection mode for Sculpt. */ char gpencil_selectmode_sculpt; - /* Grease Pencil Sculpt */ + /** Grease Pencil Sculpt. */ struct GP_Sculpt_Settings gp_sculpt; - /* Grease Pencil Interpolation Tool(s) */ + /** Grease Pencil Interpolation Tool(s). */ struct GP_Interpolate_Settings gp_interpolate; - /* Image Paint (8 bytes aligned please!) */ + /** Image Paint (8 bytes aligned please!). */ struct ImagePaintSettings imapaint; /** Settings for paint mode. */ struct PaintModeSettings paint_mode; - /* Particle Editing */ + /** Particle Editing. */ struct ParticleEditSettings particle; - /* Transform Proportional Area of Effect */ + /** Transform Proportional Area of Effect. */ float proportional_size; - /* Select Group Threshold */ + /** Select Group Threshold. */ float select_thresh; - /* Auto-Keying Mode */ + /* Auto-Keying Mode. */ /** Defines in DNA_userdef_types.h. */ short autokey_flag; char autokey_mode; /** Keyframe type (see DNA_curve_types.h). */ char keyframe_type; - /* Multires */ + /* Multires. */ char multires_subdiv_type; - /* Edge tagging, store operator settings (no UI access). */ + /** Edge tagging, store operator settings (no UI access). */ char edge_mode; char edge_mode_live_unwrap; - /* Transform */ + /* Transform. */ + char transform_pivot_point; char transform_flag; /** Snap elements (per space-type), #eSnapMode. */ @@ -1540,13 +1619,15 @@ typedef struct ToolSettings { short snap_flag_seq; short snap_uv_flag; /** Default snap source, #eSnapSourceSelect. */ - /* TODO(@gfxcoder): Rename `snap_target` to `snap_source` to avoid previous ambiguity of + /** + * TODO(@gfxcoder): Rename `snap_target` to `snap_source` to avoid previous ambiguity of * "target" (now, "source" is geometry to be moved and "target" is geometry to which moved - * geometry is snapped). */ + * geometry is snapped). + */ char snap_target; /** Snap mask for transform modes, #eSnapTransformMode. */ char snap_transform_mode_flag; - /** Steps to break transformation into with face nearest snapping */ + /** Steps to break transformation into with face nearest snapping. */ short snap_face_nearest_steps; char proportional_edit, prop_mode; @@ -1575,47 +1656,54 @@ typedef struct ToolSettings { /** Stroke selection mode for Vertex Paint. */ char gpencil_selectmode_vertex; - /* UV painting */ + /* UV painting. */ char uv_sculpt_settings; char uv_relax_method; char workspace_tool_type; - /* XXX: these sculpt_paint_* fields are deprecated, use the - * unified_paint_settings field instead! */ + /** + * XXX: these `sculpt_paint_*` fields are deprecated, use the + * unified_paint_settings field instead! + */ short sculpt_paint_settings DNA_DEPRECATED; int sculpt_paint_unified_size DNA_DEPRECATED; float sculpt_paint_unified_unprojected_radius DNA_DEPRECATED; float sculpt_paint_unified_alpha DNA_DEPRECATED; - /* Unified Paint Settings */ + /** Unified Paint Settings. */ struct UnifiedPaintSettings unified_paint_settings; struct CurvePaintSettings curve_paint_settings; struct MeshStatVis statvis; - /* Normal Editing */ + /** Normal Editing. */ float normal_vector[3]; char _pad6[4]; - /* Custom Curve Profile for bevel tool: + /** + * Custom Curve Profile for bevel tool: * Temporary until there is a proper preset system that stores the profiles or maybe stores - * entire bevel configurations. */ + * entire bevel configurations. + */ struct CurveProfile *custom_bevel_profile_preset; struct SequencerToolSettings *sequencer_tool_settings; } ToolSettings; -/* *************************************************************** */ -/* Assorted Scene Data */ +/** \} */ -/* ------------------------------------------- */ -/* Unit Settings */ +/* Assorted Scene Data. */ +/* -------------------------------------------------------------------- */ +/** \name Unit Settings + * \{ */ + +/** Display/Editing unit options for each scene. */ typedef struct UnitSettings { - /* Display/Editing unit options for each scene */ + /** Maybe have other unit conversions? */ float scale_length; /** Imperial, metric etc. */ @@ -1632,8 +1720,11 @@ typedef struct UnitSettings { char _pad[4]; } UnitSettings; -/* ------------------------------------------- */ -/* Global/Common Physics Settings */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Global/Common Physics Settings + * \{ */ typedef struct PhysicsSettings { float gravity[3]; @@ -1645,15 +1736,15 @@ typedef struct PhysicsSettings { * Safe Area options used in Camera View & Sequencer. */ typedef struct DisplaySafeAreas { - /* each value represents the (x,y) margins as a multiplier. - * 'center' in this context is just the name for a different kind of safe-area */ + /* Each value represents the (x,y) margins as a multiplier. + * 'center' in this context is just the name for a different kind of safe-area. */ /** Title Safe. */ float title[2]; /** Image/Graphics Safe. */ float action[2]; - /* use for alternate aspect ratio */ + /* Use for alternate aspect ratio. */ float title_center[2]; float action_center[2]; } DisplaySafeAreas; @@ -1671,7 +1762,7 @@ typedef struct SceneDisplay { float matcap_ssao_attenuation; int matcap_ssao_samples; - /** Method of AA for viewport rendering and image rendering */ + /** Method of AA for viewport rendering and image rendering. */ char viewport_aa; char render_aa; char _pad[6]; @@ -1752,8 +1843,11 @@ typedef struct SceneGpencil { char _pad[4]; } SceneGpencil; -/* *************************************************************** */ -/* Scene ID-Block */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Transform Orientation + * \{ */ typedef struct TransformOrientationSlot { int type; @@ -1762,7 +1856,7 @@ typedef struct TransformOrientationSlot { char _pad0[7]; } TransformOrientationSlot; -/** Indices when used in #Scene.orientation_slots */ +/** Indices when used in #Scene.orientation_slots. */ enum { SCE_ORIENT_DEFAULT = 0, SCE_ORIENT_TRANSLATE = 1, @@ -1770,11 +1864,17 @@ enum { SCE_ORIENT_SCALE = 3, }; +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Scene ID-Block + * \{ */ + typedef struct Scene { ID id; /** Animation data (must be immediately after id for utilities to use it). */ struct AnimData *adt; - /* runtime (must be immediately after id for utilities to use it). */ + /** Runtime (must be immediately after id for utilities to use it). */ DrawDataList drawdata; struct Object *camera; @@ -1790,9 +1890,9 @@ typedef struct Scene { /** 3d cursor location. */ View3DCursor cursor; - /** Bitflags for layer visibility (deprecated). */ + /** Bit-flags for layer visibility (deprecated). */ unsigned int lay DNA_DEPRECATED; - /** Active layer (deprecated) */ + /** Active layer (deprecated). */ int layact DNA_DEPRECATED; char _pad2[4]; @@ -1812,8 +1912,8 @@ typedef struct Scene { void *_pad4; struct DisplaySafeAreas safe_areas; - /* migrate or replace? depends on some internal things... */ - /* no, is on the right place (ton) */ + /* Migrate or replace? depends on some internal things... */ + /* No, is on the right place (ton). */ struct RenderData r; struct AudioData audio; @@ -1831,55 +1931,57 @@ typedef struct Scene { /** (runtime) info/cache used for presenting playback framerate info to the user. */ void *fps_info; - /* None of the dependency graph vars is mean to be saved. */ + /** None of the dependency graph vars is mean to be saved. */ struct GHash *depsgraph_hash; char _pad7[4]; - /* User-Defined KeyingSets */ + /* User-Defined KeyingSets. */ /** * Index of the active KeyingSet. * first KeyingSet has index 1, 'none' active is 0, 'add new' is -1 */ int active_keyingset; - /** KeyingSets for this scene */ + /** KeyingSets for this scene. */ ListBase keyingsets; - /* Units */ + /* Units. */ struct UnitSettings unit; - /** Grease Pencil - Annotations */ + /** Grease Pencil - Annotations. */ struct bGPdata *gpd; - /* Movie Tracking */ + /* Movie Tracking. */ /** Active movie clip. */ struct MovieClip *clip; - /* Physics simulation settings */ + /** Physics simulation settings. */ struct PhysicsSettings physics_settings; void *_pad8; - /* XXX. runtime flag for drawing, actually belongs in the window, - * only used by BKE_object_handle_update() */ + /** + * XXX: runtime flag for drawing, actually belongs in the window, + * only used by #BKE_object_handle_update() + */ struct CustomData_MeshMasks customdata_mask; - /* XXX. same as above but for temp operator use (gl renders) */ + /** XXX: same as above but for temp operator use (viewport renders). */ struct CustomData_MeshMasks customdata_mask_modal; - /* Color Management */ + /* Color Management. */ ColorManagedViewSettings view_settings; ColorManagedDisplaySettings display_settings; ColorManagedColorspaceSettings sequencer_colorspace_settings; - /* RigidBody simulation world+settings */ + /** RigidBody simulation world+settings. */ struct RigidBodyWorld *rigidbody_world; struct PreviewImage *preview; ListBase view_layers; - /* Not an actual datablock, but memory owned by scene. */ + /** Not an actual data-block, but memory owned by scene. */ struct Collection *master_collection; struct SceneCollection *collection DNA_DEPRECATED; - /** Settings to be override by workspaces. */ + /** Settings to be override by work-spaces. */ IDProperty *layer_properties; void *_pad9; @@ -1888,16 +1990,20 @@ typedef struct Scene { struct SceneGpencil grease_pencil_settings; } Scene; -/* **************** RENDERDATA ********************* */ +/** \} */ -/** #RenderData.flag */ -/* use preview range */ +/* -------------------------------------------------------------------- */ +/** \name Render Data Enum/Flags + * \{ */ + +/** #RenderData.flag. */ +/* Use preview range. */ #define SCER_PRV_RANGE (1 << 0) #define SCER_LOCK_FRAME_SELECTION (1 << 1) -/* show/use subframes (for checking motion blur) */ +/* Show/use subframes (for checking motion blur). */ #define SCER_SHOW_SUBFRAME (1 << 3) -/** #RenderData.mode */ +/** #RenderData.mode. */ #define R_MODE_UNUSED_0 (1 << 0) /* dirty */ #define R_MODE_UNUSED_1 (1 << 1) /* cleared */ #define R_MODE_UNUSED_2 (1 << 2) /* cleared */ @@ -1923,11 +2029,11 @@ typedef struct Scene { #define R_MODE_UNUSED_20 (1 << 20) /* cleared */ #define R_MODE_UNUSED_21 (1 << 21) /* cleared */ -#define R_NO_OVERWRITE (1 << 22) /* skip existing files */ -#define R_TOUCH (1 << 23) /* touch files before rendering */ +#define R_NO_OVERWRITE (1 << 22) /* Skip existing files. */ +#define R_TOUCH (1 << 23) /* Touch files before rendering. */ #define R_SIMPLIFY (1 << 24) #define R_EDGE_FRS (1 << 25) /* R_EDGE reserved for Freestyle */ -#define R_PERSISTENT_DATA (1 << 26) /* keep data around for re-render */ +#define R_PERSISTENT_DATA (1 << 26) /* Keep data around for re-render. */ #define R_MODE_UNUSED_27 (1 << 27) /* cleared */ /** #RenderData.seq_flag */ @@ -1953,7 +2059,7 @@ enum { /** #RenderData.scemode */ #define R_DOSEQ (1 << 0) #define R_BG_RENDER (1 << 1) -/* passepartout is camera option now, keep this for backward compatibility */ +/* Passepartout is camera option now, keep this for backward compatibility. */ #define R_PASSEPARTOUT (1 << 2) #define R_BUTS_PREVIEW (1 << 3) #define R_EXTENSION (1 << 4) @@ -1982,7 +2088,8 @@ enum { #define R_STAMP_CAMERA (1 << 3) #define R_STAMP_SCENE (1 << 4) #define R_STAMP_NOTE (1 << 5) -#define R_STAMP_DRAW (1 << 6) /* draw in the image */ +/** Draw in the image space. */ +#define R_STAMP_DRAW (1 << 6) #define R_STAMP_MARKER (1 << 7) #define R_STAMP_FILENAME (1 << 8) #define R_STAMP_SEQSTRIP (1 << 9) @@ -2007,12 +2114,12 @@ enum { /** #RenderData.color_mgt_flag */ enum { - /** deprecated, should only be used in versioning code only */ + /** Deprecated, should only be used in versioning code only. */ R_COLOR_MANAGEMENT = (1 << 0), R_COLOR_MANAGEMENT_UNUSED_1 = (1 << 1), }; -/* bake_mode: same as RE_BAKE_xxx defines */ +/* bake_mode: same as RE_BAKE_xxx defines. */ /** #RenderData.bake_flag */ #define R_BAKE_CLEAR (1 << 0) /* #define R_BAKE_OSA (1 << 1) */ /* deprecated */ @@ -2036,29 +2143,39 @@ enum { #define R_LINE_THICKNESS_ABSOLUTE 1 #define R_LINE_THICKNESS_RELATIVE 2 -/* sequencer seq_prev_type seq_rend_type */ +/* Sequencer seq_prev_type seq_rend_type. */ /** #RenderData.engine (scene.cc) */ extern const char *RE_engine_id_BLENDER_EEVEE; extern const char *RE_engine_id_BLENDER_WORKBENCH; extern const char *RE_engine_id_CYCLES; -/* **************** SCENE ********************* */ +/** \} */ -/* note that much higher maxframes give imprecise sub-frames, see: T46859 */ +/* -------------------------------------------------------------------- */ +/** \name Scene Defines + * \{ */ + +/* Note that much higher max-frames give imprecise sub-frames, see: T46859. */ /* Current precision is 16 for the sub-frames closer to MAXFRAME. */ -/* for general use */ +/* For general use. */ #define MAXFRAME 1048574 #define MAXFRAMEF 1048574.0f #define MINFRAME 0 #define MINFRAMEF 0.0f -/* (minimum frame number for current-frame) */ +/** (Minimum frame number for current-frame). */ #define MINAFRAME -1048574 #define MINAFRAMEF -1048574.0f +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Scene Related Macros + * \{ */ + #define BASE_VISIBLE(v3d, base) BKE_base_is_visible(v3d, base) #define BASE_SELECTABLE(v3d, base) \ (BASE_VISIBLE(v3d, base) && \ @@ -2089,7 +2206,13 @@ extern const char *RE_engine_id_CYCLES; #define TIME2FRA(a) ((((double)scene->r.frs_sec) * (double)(a)) / (double)scene->r.frs_sec_base) #define FPS (((double)scene->r.frs_sec) / (double)scene->r.frs_sec_base) -/* Base.flag is in DNA_object_types.h */ +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Scene Enum/Flags + * \{ */ + +/* Base.flag is in `DNA_object_types.h`. */ /** #ToolSettings.transform_flag */ enum { @@ -2114,12 +2237,14 @@ typedef enum eSnapFlag { SCE_SNAP = (1 << 0), SCE_SNAP_ROTATE = (1 << 1), SCE_SNAP_PEEL_OBJECT = (1 << 2), - SCE_SNAP_PROJECT = (1 << 3), /* Project individual elements instead of whole object. */ - SCE_SNAP_NOT_TO_ACTIVE = (1 << 4), /* Was `SCE_SNAP_NO_SELF`, but self should be active. */ + /** Project individual elements instead of whole object. */ + SCE_SNAP_PROJECT = (1 << 3), + /** Was `SCE_SNAP_NO_SELF`, but self should be active. */ + SCE_SNAP_NOT_TO_ACTIVE = (1 << 4), SCE_SNAP_ABS_GRID = (1 << 5), SCE_SNAP_BACKFACE_CULLING = (1 << 6), SCE_SNAP_KEEP_ON_SAME_OBJECT = (1 << 7), - /* see #eSnapTargetSelect */ + /** see #eSnapTargetSelect */ SCE_SNAP_TO_INCLUDE_EDITED = (1 << 8), SCE_SNAP_TO_INCLUDE_NONEDITED = (1 << 9), SCE_SNAP_TO_ONLY_SELECTABLE = (1 << 10), @@ -2140,8 +2265,11 @@ typedef enum eSnapSourceSelect { ENUM_OPERATORS(eSnapSourceSelect, SCE_SNAP_SOURCE_ACTIVE) -/** #TransSnap.target_select and #ToolSettings.snap_flag (#SCE_SNAP_NOT_TO_ACTIVE, - * #SCE_SNAP_TO_INCLUDE_EDITED, #SCE_SNAP_TO_INCLUDE_NONEDITED, #SCE_SNAP_TO_ONLY_SELECTABLE) */ +/** + * #TransSnap.target_select and #ToolSettings.snap_flag + * (#SCE_SNAP_NOT_TO_ACTIVE, #SCE_SNAP_TO_INCLUDE_EDITED, #SCE_SNAP_TO_INCLUDE_NONEDITED, + * #SCE_SNAP_TO_ONLY_SELECTABLE). + */ typedef enum eSnapTargetSelect { SCE_SNAP_TARGET_ALL = 0, SCE_SNAP_TARGET_NOT_SELECTED = (1 << 0), @@ -2263,7 +2391,7 @@ typedef enum eVGroupSelect { #define SCE_KEYS_NO_SELONLY (1 << 4) #define SCE_READFILE_LIBLINK_NEED_SETSCENE_CHECK (1 << 5) -/* return flag BKE_scene_base_iter_next functions */ +/* Return flag BKE_scene_base_iter_next functions. */ /* #define F_ERROR -1 */ /* UNUSED */ #define F_START 0 #define F_SCENE 1 @@ -2278,7 +2406,8 @@ typedef enum eVGroupSelect { /** #FFMpegCodecData.flags */ enum { #ifdef DNA_DEPRECATED_ALLOW - FFMPEG_MULTIPLEX_AUDIO = (1 << 0), /* deprecated, you can choose none as audiocodec now */ + /* DEPRECATED: you can choose none as audio-codec now. */ + FFMPEG_MULTIPLEX_AUDIO = (1 << 0), #endif FFMPEG_AUTOSPLIT_OUTPUT = (1 << 1), FFMPEG_LOSSLESS_OUTPUT = (1 << 2), @@ -2330,34 +2459,33 @@ typedef enum eSculptFlags { SCULPT_ONLY_DEFORM = (1 << 8), // SCULPT_SHOW_DIFFUSE = (1 << 9), /* deprecated */ - /* If set, the mesh will be drawn with smooth-shading in - * dynamic-topology mode */ + /** If set, the mesh will be drawn with smooth-shading in dynamic-topology mode. */ SCULPT_DYNTOPO_SMOOTH_SHADING = (1 << 10), - /* If set, dynamic-topology brushes will subdivide short edges */ + /** If set, dynamic-topology brushes will subdivide short edges. */ SCULPT_DYNTOPO_SUBDIVIDE = (1 << 12), - /* If set, dynamic-topology brushes will collapse short edges */ + /** If set, dynamic-topology brushes will collapse short edges. */ SCULPT_DYNTOPO_COLLAPSE = (1 << 11), - /* If set, dynamic-topology detail size will be constant in object space */ + /** If set, dynamic-topology detail size will be constant in object space. */ SCULPT_DYNTOPO_DETAIL_CONSTANT = (1 << 13), SCULPT_DYNTOPO_DETAIL_BRUSH = (1 << 14), SCULPT_DYNTOPO_DETAIL_MANUAL = (1 << 16), - /* Don't display mask in viewport, but still use it for strokes. */ + /** Don't display mask in viewport, but still use it for strokes. */ SCULPT_HIDE_MASK = (1 << 15), - /* Don't display face sets in viewport. */ + /** Don't display face sets in viewport. */ SCULPT_HIDE_FACE_SETS = (1 << 17), } eSculptFlags; -/* Sculpt.transform_mode */ +/** #Sculpt.transform_mode */ typedef enum eSculptTransformMode { SCULPT_TRANSFORM_MODE_ALL_VERTICES = 0, SCULPT_TRANSFORM_MODE_RADIUS_ELASTIC = 1, } eSculptTrasnformMode; -/** PaintModeSettings.mode */ +/** #PaintModeSettings.mode */ typedef enum ePaintCanvasSource { /** Paint on the active node of the active material slot. */ PAINT_CANVAS_SOURCE_MATERIAL = 0, @@ -2384,7 +2512,7 @@ enum { // #define IMAGEPAINT_DRAW_TOOL (1 << 1) /* deprecated */ // #define IMAGEPAINT_DRAW_TOOL_DRAWING (1 << 2) /* deprecated */ -/* projection painting only */ +/* Projection painting only. */ /** #ImagePaintSettings.flag */ #define IMAGEPAINT_PROJECT_XRAY (1 << 4) #define IMAGEPAINT_PROJECT_BACKFACE (1 << 5) @@ -2401,13 +2529,13 @@ enum { /** #ToolSettings.uvcalc_flag */ #define UVCALC_FILLHOLES (1 << 0) -/** would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */ +/** Would call this UVCALC_ASPECT_CORRECT, except it should be default with old file. */ #define UVCALC_NO_ASPECT_CORRECT (1 << 1) /** Adjust UV's while transforming with Vert or Edge Slide. */ #define UVCALC_TRANSFORM_CORRECT_SLIDE (1 << 2) /** Use mesh data after subsurf to compute UV's. */ #define UVCALC_USESUBSURF (1 << 3) -/** adjust UV's while transforming to avoid distortion */ +/** Adjust UV's while transforming to avoid distortion */ #define UVCALC_TRANSFORM_CORRECT (1 << 4) /** Keep equal values merged while correcting custom-data. */ #define UVCALC_TRANSFORM_CORRECT_KEEP_CONNECTED (1 << 5) @@ -2431,49 +2559,49 @@ enum { /** #ToolSettings.gpencil_flags */ typedef enum eGPencil_Flags { - /* When creating new frames, the last frame gets used as the basis for the new one */ + /** When creating new frames, the last frame gets used as the basis for the new one. */ GP_TOOL_FLAG_RETAIN_LAST = (1 << 1), - /* Add the strokes below all strokes in the layer */ + /** Add the strokes below all strokes in the layer. */ GP_TOOL_FLAG_PAINT_ONBACK = (1 << 2), - /* Show compact list of colors */ + /** Show compact list of colors. */ GP_TOOL_FLAG_THUMBNAIL_LIST = (1 << 3), - /* Generate wheight data for new strokes */ + /** Generate wheight data for new strokes. */ GP_TOOL_FLAG_CREATE_WEIGHTS = (1 << 4), - /* Automerge with last stroke */ + /** Auto-merge with last stroke. */ GP_TOOL_FLAG_AUTOMERGE_STROKE = (1 << 5), } eGPencil_Flags; /** #Scene.r.simplify_gpencil */ typedef enum eGPencil_SimplifyFlags { - /* Simplify */ + /** Simplify. */ SIMPLIFY_GPENCIL_ENABLE = (1 << 0), - /* Simplify on play */ + /** Simplify on play. */ SIMPLIFY_GPENCIL_ON_PLAY = (1 << 1), - /* Simplify fill on viewport */ + /** Simplify fill on viewport. */ SIMPLIFY_GPENCIL_FILL = (1 << 2), - /* Simplify modifier on viewport */ + /** Simplify modifier on viewport. */ SIMPLIFY_GPENCIL_MODIFIER = (1 << 3), - /* Simplify Shader FX */ + /** Simplify Shader FX. */ SIMPLIFY_GPENCIL_FX = (1 << 5), - /* Simplify layer tint */ + /** Simplify layer tint. */ SIMPLIFY_GPENCIL_TINT = (1 << 7), - /* Simplify Antialiasing */ + /** Simplify Anti-aliasing. */ SIMPLIFY_GPENCIL_AA = (1 << 8), } eGPencil_SimplifyFlags; -/** `ToolSettings.gpencil_*_align` - Stroke Placement mode flags */ +/** `ToolSettings.gpencil_*_align` - Stroke Placement mode flags. */ typedef enum eGPencil_Placement_Flags { - /* New strokes are added in viewport/data space (i.e. not screen space) */ + /** New strokes are added in viewport/data space (i.e. not screen space). */ GP_PROJECT_VIEWSPACE = (1 << 0), - /* Viewport space, but relative to render canvas (Sequencer Preview Only) */ - /* GP_PROJECT_CANVAS = (1 << 1), */ /* UNUSED */ + // /** Viewport space, but relative to render canvas (Sequencer Preview Only) */ + // GP_PROJECT_CANVAS = (1 << 1), /* UNUSED */ - /* Project into the screen's Z values */ + /** Project into the screen's Z values. */ GP_PROJECT_DEPTH_VIEW = (1 << 2), GP_PROJECT_DEPTH_STROKE = (1 << 3), - /* "Use Endpoints" */ + /** "Use Endpoints". */ GP_PROJECT_DEPTH_STROKE_ENDPOINTS = (1 << 4), GP_PROJECT_CURSOR = (1 << 5), GP_PROJECT_DEPTH_STROKE_FIRST = (1 << 6), @@ -2597,6 +2725,8 @@ enum { SCE_DISPLAY_AA_SAMPLES_32 = 32, }; +/** \} */ + #ifdef __cplusplus } #endif From 7766a20b8ffada607ec0e155e3f8be73f5afd6b9 Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Wed, 14 Dec 2022 17:26:40 -0700 Subject: [PATCH 0121/1522] Build: clarify some comments in the rocky8 setup script also moved the install of the config manager to before it is needed. --- build_files/build_environment/linux/linux_rocky8_setup.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/build_files/build_environment/linux/linux_rocky8_setup.sh b/build_files/build_environment/linux/linux_rocky8_setup.sh index 2f4efe0be97..48b49f80149 100644 --- a/build_files/build_environment/linux/linux_rocky8_setup.sh +++ b/build_files/build_environment/linux/linux_rocky8_setup.sh @@ -11,13 +11,14 @@ if [ `id -u` -ne 0 ]; then exit 1 fi +# Required by: config manager command below to enable powertools. +dnf install 'dnf-command(config-manager)' + # Packages `ninja-build` and `meson` are not available unless CBR or PowerTools repositories are enabled. # See: https://wiki.rockylinux.org/rocky/repo/#notes-on-unlisted-repositories dnf config-manager --set-enabled powertools -# Required by: TODO. -dnf install 'dnf-command(config-manager)' -# Required by: TODO. +# Required by: epel-release has the patchelf and rubygem-asciidoctor packages dnf install epel-release # `yum-config-manager` does not come in the default minimal install, From 530b23230990d8eb521d70b29f83b4da2c611966 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 10:51:06 +1100 Subject: [PATCH 0122/1522] Cleanup: use more descriptive name for function in BMesh doc generation Avoid the term "print" as the function doesn't print. --- doc/python_api/rst_from_bmesh_opdefines.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/python_api/rst_from_bmesh_opdefines.py b/doc/python_api/rst_from_bmesh_opdefines.py index 3b7093f0156..1285938feb1 100644 --- a/doc/python_api/rst_from_bmesh_opdefines.py +++ b/doc/python_api/rst_from_bmesh_opdefines.py @@ -370,7 +370,7 @@ def main(): args_in_wash = get_args_wash(args_in, args_in_index, False) - fw(".. function:: %s(bm, %s)\n\n" % (b[0], ", ".join([print_arg_in(arg) for arg in args_in_wash]))) + fw(".. function:: %s(bm, %s)\n\n" % (b[0], ", ".join([arg_name_with_default(arg) for arg in args_in_wash]))) # -- wash the comment comment_washed = [] @@ -423,8 +423,8 @@ def main(): print(OUT_RST) -def print_arg_in(arg): - (name, default_value, _, _) = arg +def arg_name_with_default(arg): + name, default_value, _, _ = arg if default_value is None: return name return name + '=' + default_value From b13a92a238d4fac149d7743554203b0a759be056 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 10:54:13 +1100 Subject: [PATCH 0123/1522] Cleanup: wrap long lines in CMake Also remove `mingw_LIBDIR` from PKG_CONFIG_PATH since it's not a package-file path. --- .../build_environment/cmake/harfbuzz.cmake | 18 +++++++++++++++--- .../build_environment/cmake/sndfile.cmake | 12 ++++++++++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/build_files/build_environment/cmake/harfbuzz.cmake b/build_files/build_environment/cmake/harfbuzz.cmake index d34d312c9d8..5f57ab6c0ff 100644 --- a/build_files/build_environment/cmake/harfbuzz.cmake +++ b/build_files/build_environment/cmake/harfbuzz.cmake @@ -5,7 +5,12 @@ if(WIN32) set(HARFBUZZ_PKG_ENV FREETYPE_DIR=${LIBDIR}/freetype) else() set(HARFBUZZ_CONFIGURE_ENV ${CONFIGURE_ENV}) - set(HARFBUZZ_PKG_ENV PKG_CONFIG_PATH=${LIBDIR}/freetype/lib/pkgconfig:${LIBDIR}/brotli/lib/pkgconfig:${LIBDIR}/lib/python3.10/pkgconfig:$PKG_CONFIG_PATH) + set(HARFBUZZ_PKG_ENV "PKG_CONFIG_PATH=\ +${LIBDIR}/freetype/lib/pkgconfig:\ +${LIBDIR}/brotli/lib/pkgconfig:\ +${LIBDIR}/lib/python3.10/pkgconfig:\ +$PKG_CONFIG_PATH" + ) endif() set(HARFBUZZ_EXTRA_OPTIONS @@ -23,8 +28,16 @@ ExternalProject_Add(external_harfbuzz URL_HASH ${HARFBUZZ_HASH_TYPE}=${HARFBUZZ_HASH} DOWNLOAD_DIR ${DOWNLOAD_DIR} PREFIX ${BUILD_DIR}/harfbuzz + CONFIGURE_COMMAND ${HARFBUZZ_CONFIGURE_ENV} && - ${CMAKE_COMMAND} -E env ${HARFBUZZ_PKG_ENV} ${MESON} setup --prefix ${LIBDIR}/harfbuzz ${HARFBUZZ_EXTRA_OPTIONS} --default-library static --libdir lib ${BUILD_DIR}/harfbuzz/src/external_harfbuzz-build ${BUILD_DIR}/harfbuzz/src/external_harfbuzz + ${CMAKE_COMMAND} -E env ${HARFBUZZ_PKG_ENV} + ${MESON} setup + --prefix ${LIBDIR}/harfbuzz ${HARFBUZZ_EXTRA_OPTIONS} + --default-library static + --libdir lib + ${BUILD_DIR}/harfbuzz/src/external_harfbuzz-build + ${BUILD_DIR}/harfbuzz/src/external_harfbuzz + BUILD_COMMAND ninja INSTALL_COMMAND ninja install INSTALL_DIR ${LIBDIR}/harfbuzz @@ -46,4 +59,3 @@ if(BUILD_MODE STREQUAL Release AND WIN32) DEPENDEES install ) endif() - diff --git a/build_files/build_environment/cmake/sndfile.cmake b/build_files/build_environment/cmake/sndfile.cmake index ff57ffe7c28..3ea4c776e56 100644 --- a/build_files/build_environment/cmake/sndfile.cmake +++ b/build_files/build_environment/cmake/sndfile.cmake @@ -4,7 +4,12 @@ set(SNDFILE_EXTRA_ARGS) set(SNDFILE_ENV) if(WIN32) - set(SNDFILE_ENV PKG_CONFIG_PATH=${mingw_LIBDIR}/ogg/lib/pkgconfig:${mingw_LIBDIR}/vorbis/lib/pkgconfig:${mingw_LIBDIR}/flac/lib/pkgconfig:${mingw_LIBDIR}/opus/lib/pkgconfig:${mingw_LIBDIR}) + set(SNDFILE_ENV "PKG_CONFIG_PATH=\ +${mingw_LIBDIR}/ogg/lib/pkgconfig:\ +${mingw_LIBDIR}/vorbis/lib/pkgconfig:\ +${mingw_LIBDIR}/flac/lib/pkgconfig:\ +${mingw_LIBDIR}/opus/lib/pkgconfig" +) set(SNDFILE_ENV set ${SNDFILE_ENV} &&) # Shared for windows because static libs will drag in a libgcc dependency. set(SNDFILE_OPTIONS --disable-static --enable-shared ) @@ -19,7 +24,10 @@ if(UNIX AND NOT APPLE) # # Replace: Cflags: -I${includedir}/opus # With: Cflags: -I${includedir} - set(SNDFILE_ENV sed -i s/{includedir}\\/opus/{includedir}/g ${LIBDIR}/opus/lib/pkgconfig/opus.pc && ${SNDFILE_ENV}) + set(SNDFILE_ENV + sed -i s/{includedir}\\/opus/{includedir}/g ${LIBDIR}/opus/lib/pkgconfig/opus.pc && + ${SNDFILE_ENV} + ) endif() ExternalProject_Add(external_sndfile From 230744d6fd96dcf5afe66a8f9b9f6f8bbe1f41bb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 14 Dec 2022 21:02:53 +1100 Subject: [PATCH 0124/1522] Revert "Fix T102346: Mouse escapes window during walk navigation" This reverts commits 9fd6dae7939a65b67045749a0eadeb6864ded183, 4cac8025f00798938813f52dcb117be83db97f22 (minor cleanup). Re-introducing T102346, which will be fixed in isolation. Unfortunately even when the cursor is hidden & grabbed, the underlying cursor coordinates are still shown in some cases. This caused bug where dragging a button in the sculpt-context popup would draw the brush at unexpected locations because internally the cursor was warping in the middle of the window, reported as T102792. Resolving this issue with the paint cursor is possible but tend towards over-complicated solutions. Revert this change in favor of a more localized workaround for walk-mode (as was done prior [0] to fix T99021). [0]: 4c4e8cc926a672ac60692b3fb8c20249f9cae679 --- intern/ghost/intern/GHOST_SystemWin32.cpp | 45 ++++------------------ intern/ghost/intern/GHOST_SystemX11.cpp | 47 ++++------------------- 2 files changed, 16 insertions(+), 76 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 8cb007a756a..d005eec3036 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -1075,46 +1075,17 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind int32_t x_new = x_screen; int32_t y_new = y_screen; int32_t x_accum, y_accum; + GHOST_Rect bounds; - /* Warp within bounds. */ - { - GHOST_Rect bounds; - int32_t bounds_margin = 0; - GHOST_TAxisFlag bounds_axis = GHOST_kAxisNone; - - if (window->getCursorGrabMode() == GHOST_kGrabHide) { - window->getClientBounds(bounds); - - /* WARNING(@campbellbarton): The current warping logic fails to warp on every event, - * so the box needs to small enough not to let the cursor escape the window but large - * enough that the cursor isn't being warped every time. - * If this was not the case it would be less trouble to simply warp the cursor to the - * center of the screen on every motion, see: D16558 (alternative fix for T102346). */ - const int32_t subregion_div = 4; /* One quarter of the region. */ - const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()}; - const int32_t center[2] = {(bounds.m_l + bounds.m_r) / 2, (bounds.m_t + bounds.m_b) / 2}; - /* Shrink the box to prevent the cursor escaping. */ - bounds.m_l = center[0] - (size[0] / (subregion_div * 2)); - bounds.m_r = center[0] + (size[0] / (subregion_div * 2)); - bounds.m_t = center[1] - (size[1] / (subregion_div * 2)); - bounds.m_b = center[1] + (size[1] / (subregion_div * 2)); - bounds_margin = 0; - bounds_axis = GHOST_TAxisFlag(GHOST_kAxisX | GHOST_kAxisY); - } - else { - /* Fallback to window bounds. */ - if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) { - window->getClientBounds(bounds); - } - bounds_margin = 2; - bounds_axis = window->getCursorGrabAxis(); - } - - /* Could also clamp to screen bounds wrap with a window outside the view will - * fail at the moment. Use inset in case the window is at screen bounds. */ - bounds.wrapPoint(x_new, y_new, bounds_margin, bounds_axis); + /* Fallback to window bounds. */ + if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) { + window->getClientBounds(bounds); } + /* Could also clamp to screen bounds wrap with a window outside the view will + * fail at the moment. Use inset in case the window is at screen bounds. */ + bounds.wrapPoint(x_new, y_new, 2, window->getCursorGrabAxis()); + window->getCursorGrabAccum(x_accum, y_accum); if (x_new != x_screen || y_new != y_screen) { /* WORKAROUND: Store the current time so that we ignore outdated mousemove events. */ diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 4a723435806..4baa3ff598f 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -950,48 +950,17 @@ void GHOST_SystemX11::processEvent(XEvent *xe) int32_t x_new = xme.x_root; int32_t y_new = xme.y_root; int32_t x_accum, y_accum; + GHOST_Rect bounds; - /* Warp within bounds. */ - { - GHOST_Rect bounds; - int32_t bounds_margin = 0; - GHOST_TAxisFlag bounds_axis = GHOST_kAxisNone; - - if (window->getCursorGrabMode() == GHOST_kGrabHide) { - window->getClientBounds(bounds); - - /* TODO(@campbellbarton): warp the cursor to `window->getCursorGrabInitPos`, - * on every motion event, see: D16557 (alternative fix for T102346). */ - const int32_t subregion_div = 4; /* One quarter of the region. */ - const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()}; - const int32_t center[2] = { - (bounds.m_l + bounds.m_r) / 2, - (bounds.m_t + bounds.m_b) / 2, - }; - /* Shrink the box to prevent the cursor escaping. */ - bounds.m_l = center[0] - (size[0] / (subregion_div * 2)); - bounds.m_r = center[0] + (size[0] / (subregion_div * 2)); - bounds.m_t = center[1] - (size[1] / (subregion_div * 2)); - bounds.m_b = center[1] + (size[1] / (subregion_div * 2)); - bounds_margin = 0; - bounds_axis = GHOST_TAxisFlag(GHOST_kAxisX | GHOST_kAxisY); - } - else { - /* Fallback to window bounds. */ - if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) { - window->getClientBounds(bounds); - } - /* Could also clamp to screen bounds wrap with a window outside the view will - * fail at the moment. Use offset of 8 in case the window is at screen bounds. */ - bounds_margin = 8; - bounds_axis = window->getCursorGrabAxis(); - } - - /* Could also clamp to screen bounds wrap with a window outside the view will - * fail at the moment. Use inset in case the window is at screen bounds. */ - bounds.wrapPoint(x_new, y_new, bounds_margin, bounds_axis); + /* fallback to window bounds */ + if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) { + window->getClientBounds(bounds); } + /* Could also clamp to screen bounds wrap with a window outside the view will + * fail at the moment. Use offset of 8 in case the window is at screen bounds. */ + bounds.wrapPoint(x_new, y_new, 8, window->getCursorGrabAxis()); + window->getCursorGrabAccum(x_accum, y_accum); if (x_new != xme.x_root || y_new != xme.y_root) { From c969a533f9c1b0e93d066331993286f8ee309d9c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 11:48:08 +1100 Subject: [PATCH 0125/1522] WM: support checking windowing capabilities Historically checks for windowing capabilities used platform pre-processor checks however that doesn't work when Blender is built with both X11 & Wayland. Add a capabilities flag which can be used to check which functionality is supported. This has the advantage of being more descriptive/readable. --- source/blender/windowmanager/WM_api.h | 9 +++++++++ source/blender/windowmanager/intern/wm_window.c | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 264b76472f7..df5659845fe 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -126,6 +126,15 @@ void WM_init_opengl(void); */ const char *WM_ghost_backend(void); +typedef enum eWM_CapabilitiesFlag { + /** Ability to warp the cursor (set it's location). */ + WM_CAPABILITY_CURSOR_WARP = (1 << 0), + /** Ability to access window positions & move them. */ + WM_CAPABILITY_WINDOW_POSITION = (1 << 1), +} eWM_CapabilitiesFlag; + +eWM_CapabilitiesFlag WM_capabilities_flag(void); + void WM_check(struct bContext *C); void WM_reinit_gizmomap_all(struct Main *bmain); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index f5dc18bb16e..7ee074660b0 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1646,6 +1646,23 @@ GHOST_TDrawingContextType wm_ghost_drawing_context_type(const eGPUBackendType gp return GHOST_kDrawingContextTypeNone; } +eWM_CapabilitiesFlag WM_capabilities_flag(void) +{ + static eWM_CapabilitiesFlag flag = -1; + if (flag != -1) { + return flag; + } + + flag = 0; + if (GHOST_SupportsCursorWarp()) { + flag |= WM_CAPABILITY_CURSOR_WARP; + } + if (GHOST_SupportsWindowPosition()) { + flag |= WM_CAPABILITY_WINDOW_POSITION; + } + return flag; +} + /** \} */ /* -------------------------------------------------------------------- */ From 0240b895994aa58258db6897ae0d6478da7fce5f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 11:57:00 +1100 Subject: [PATCH 0126/1522] Fix T102346: Mouse escapes window during walk navigation This is an alternative fix to [0] which kept the cursor centrally located as part of GHOST cursor grabbing which caused T102792. Now this is done as part of walk mode as it's the operator that most often ran into this problem although ideally this would be handled by GHOST - but that's a much bigger project. [0]: 9fd6dae7939a65b67045749a0eadeb6864ded183 --- .../space_view3d/view3d_navigate_walk.c | 53 ++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_navigate_walk.c b/source/blender/editors/space_view3d/view3d_navigate_walk.c index 2a426bfd480..a1d293dc53f 100644 --- a/source/blender/editors/space_view3d/view3d_navigate_walk.c +++ b/source/blender/editors/space_view3d/view3d_navigate_walk.c @@ -55,6 +55,14 @@ #define USE_TABLET_SUPPORT +/** + * Use alternative behavior when cursor warp is supported + * to prevent the cursor escaping the window bounds, see: T102346. + * + * \note this is not needed if cursor positioning is not supported. + */ +#define USE_CURSOR_WARP_HACK + /* -------------------------------------------------------------------- */ /** \name Modal Key-map * \{ */ @@ -221,6 +229,10 @@ typedef struct WalkInfo { bool need_rotation_keyframe; bool need_translation_keyframe; +#ifdef USE_CURSOR_WARP_HACK + bool need_modal_cursor_warp_hack; +#endif + /** Previous 2D mouse values. */ int prev_mval[2]; /** Initial mouse location. */ @@ -579,6 +591,10 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int walk->need_rotation_keyframe = false; walk->need_translation_keyframe = false; +#ifdef USE_CURSOR_WARP_HACK + walk->need_modal_cursor_warp_hack = false; +#endif + walk->time_lastdraw = PIL_check_seconds_timer(); walk->draw_handle_pixel = ED_region_draw_cb_activate( @@ -594,7 +610,31 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int copy_v2_v2_int(walk->init_mval, mval); copy_v2_v2_int(walk->prev_mval, mval); - WM_cursor_grab_enable(win, 0, true, NULL); +#ifdef USE_CURSOR_WARP_HACK + if (WM_capabilities_flag() & WM_CAPABILITY_CURSOR_WARP) { + int bounds[4]; + const rcti *rect = &walk->region->winrct; + const int center[2] = {BLI_rcti_cent_x(rect), BLI_rcti_cent_y(rect)}; + const int size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)}; + const int div = 4; /* Where 2 is the region size. */ + + bounds[0] = center[0] - (size[0] / div); /* X-min. */ + bounds[1] = center[1] + (size[1] / div); /* Y-max. */ + bounds[2] = center[0] + (size[0] / div); /* X-max. */ + bounds[3] = center[1] - (size[1] / div); /* Y-min. */ + + WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, false, bounds); + + /* Important to hide afterwards (not part of grabbing), + * since enabling cursor and hiding at the same time ignores bounds. */ + WM_cursor_modal_set(win, WM_CURSOR_NONE); + walk->need_modal_cursor_warp_hack = true; + } + else +#endif /* USE_CURSOR_WARP_HACK */ + { + WM_cursor_grab_enable(win, 0, true, NULL); + } return 1; } @@ -643,7 +683,16 @@ static int walkEnd(bContext *C, WalkInfo *walk) } #endif - WM_cursor_grab_enable(win, 0, true, NULL); + WM_cursor_grab_disable(win, NULL); + +#ifdef USE_CURSOR_WARP_HACK + if (walk->need_modal_cursor_warp_hack) { + WM_cursor_warp(win, + walk->region->winrct.xmin + walk->init_mval[0], + walk->region->winrct.ymin + walk->init_mval[1]); + WM_cursor_modal_restore(win); + } +#endif if (walk->state == WALK_CONFIRM) { MEM_freeN(walk); From 5da11e22de6ea84751b19718f5fab95db12749d2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 13:50:49 +1100 Subject: [PATCH 0127/1522] Cleanup: improve docs for grab functions & use rcti for the wrap region - Use typed enum for the wrap axis. - Rename `bounds` to `wrap_region`. - Take a `rcti` argument instead of an `int[4]`. - Pair wrap & wrap_region arguments together. --- .../editors/interface/interface_handlers.cc | 2 +- .../space_view3d/view3d_navigate_walk.c | 20 ++++++++-------- .../makesdna/DNA_windowmanager_types.h | 2 +- source/blender/windowmanager/WM_api.h | 22 +++++++++++++++--- source/blender/windowmanager/WM_types.h | 4 ++-- .../windowmanager/gizmo/intern/wm_gizmo_map.c | 2 +- .../blender/windowmanager/intern/wm_cursors.c | 23 ++++++++++++++----- .../windowmanager/intern/wm_event_system.cc | 18 ++++----------- .../windowmanager/intern/wm_operator_type.c | 9 +++----- .../blender/windowmanager/intern/wm_window.c | 2 ++ 10 files changed, 61 insertions(+), 43 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index 2d90b6f0d22..0144126f802 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -8306,7 +8306,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s /* number editing */ if (state == BUTTON_STATE_NUM_EDITING) { if (ui_but_is_cursor_warp(but)) { - WM_cursor_grab_enable(CTX_wm_window(C), WM_CURSOR_WRAP_XY, true, nullptr); + WM_cursor_grab_enable(CTX_wm_window(C), WM_CURSOR_WRAP_XY, nullptr, true); } ui_numedit_begin(but, data); } diff --git a/source/blender/editors/space_view3d/view3d_navigate_walk.c b/source/blender/editors/space_view3d/view3d_navigate_walk.c index a1d293dc53f..3d113c408eb 100644 --- a/source/blender/editors/space_view3d/view3d_navigate_walk.c +++ b/source/blender/editors/space_view3d/view3d_navigate_walk.c @@ -612,18 +612,18 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int #ifdef USE_CURSOR_WARP_HACK if (WM_capabilities_flag() & WM_CAPABILITY_CURSOR_WARP) { - int bounds[4]; - const rcti *rect = &walk->region->winrct; - const int center[2] = {BLI_rcti_cent_x(rect), BLI_rcti_cent_y(rect)}; - const int size[2] = {BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)}; + const rcti *winrct = &walk->region->winrct; + const int center[2] = {BLI_rcti_cent_x(winrct), BLI_rcti_cent_y(winrct)}; + const int size[2] = {BLI_rcti_size_x(winrct), BLI_rcti_size_y(winrct)}; const int div = 4; /* Where 2 is the region size. */ - bounds[0] = center[0] - (size[0] / div); /* X-min. */ - bounds[1] = center[1] + (size[1] / div); /* Y-max. */ - bounds[2] = center[0] + (size[0] / div); /* X-max. */ - bounds[3] = center[1] - (size[1] / div); /* Y-min. */ + rcti wrap_region = {}; + wrap_region.xmin = center[0] - (size[0] / div); + wrap_region.xmax = center[0] + (size[0] / div); + wrap_region.ymin = center[1] - (size[1] / div); + wrap_region.ymax = center[1] + (size[1] / div); - WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, false, bounds); + WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, &wrap_region, false); /* Important to hide afterwards (not part of grabbing), * since enabling cursor and hiding at the same time ignores bounds. */ @@ -633,7 +633,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int else #endif /* USE_CURSOR_WARP_HACK */ { - WM_cursor_grab_enable(win, 0, true, NULL); + WM_cursor_grab_enable(win, WM_CURSOR_WRAP_NONE, NULL, true); } return 1; diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 7231a995f10..af0bb721f60 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -277,7 +277,7 @@ typedef struct wmWindow { short lastcursor; /** The current modal cursor. */ short modalcursor; - /** Cursor grab mode. */ + /** Cursor grab mode #GHOST_TGrabCursorMode (run-time only) */ short grabcursor; /** Internal: tag this for extra mouse-move event, * makes cursors/buttons active on UI switching. */ diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index df5659845fe..37dce4db61d 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -321,9 +321,22 @@ void WM_cursor_modal_restore(struct wmWindow *win); */ void WM_cursor_wait(bool val); /** - * \param bounds: can be NULL + * Enable cursor grabbing, optionally hiding the cursor and wrapping cursor-motion + * within a sub-region of the window. + * + * \param wrap: an enum (#WM_CURSOR_WRAP_NONE, #WM_CURSOR_WRAP_XY... etc). + * \param wrap_region: Window-relative region for cursor wrapping (when `wrap` is + * #WM_CURSOR_WRAP_XY). When NULL, the window bounds are used for wrapping. + * + * \note The current grab state can be accessed by #wmWindowManager.grabcursor although. + */ +void WM_cursor_grab_enable(struct wmWindow *win, + eWM_CursorWrapAxis wrap, + const struct rcti *wrap_region, + bool hide); +/** + * */ -void WM_cursor_grab_enable(struct wmWindow *win, int wrap, bool hide, int bounds[4]); void WM_cursor_grab_disable(struct wmWindow *win, const int mouse_ungrab_xy[2]); /** * After this you can call restore too. @@ -344,7 +357,10 @@ void WM_paint_cursor_remove_by_type(struct wmWindowManager *wm, void WM_paint_cursor_tag_redraw(struct wmWindow *win, struct ARegion *region); /** - * This function requires access to the GHOST_SystemHandle (g_system). + * Set the cursor location in window coordinates (compatible with #wmEvent.xy). + * + * \note Some platforms don't support this, check: #WM_CAPABILITY_WINDOW_POSITION + * before relying on this functionality. */ void WM_cursor_warp(struct wmWindow *win, int x, int y); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index e4050397aaa..085ddaac5a5 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -185,12 +185,12 @@ enum { }; /** For #WM_cursor_grab_enable wrap axis. */ -enum { +typedef enum eWM_CursorWrapAxis { WM_CURSOR_WRAP_NONE = 0, WM_CURSOR_WRAP_X, WM_CURSOR_WRAP_Y, WM_CURSOR_WRAP_XY, -}; +} eWM_CursorWrapAxis; /** * Context to call operator in for #WM_operator_name_call. diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c index 9903b0e50fd..627ff1a0d9a 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c @@ -1062,7 +1062,7 @@ void wm_gizmomap_modal_set( gzmap->gzmap_context.modal = gz; if ((gz->flag & WM_GIZMO_MOVE_CURSOR) && (event->tablet.is_motion_absolute == false)) { - WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, true, NULL); + WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, NULL, true); copy_v2_v2_int(gzmap->gzmap_context.event_xy, event->xy); gzmap->gzmap_context.event_grabcursor = win->grabcursor; } diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index 43be87fce39..f7c030db1cd 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -223,22 +223,33 @@ void WM_cursor_wait(bool val) } } -void WM_cursor_grab_enable(wmWindow *win, int wrap, bool hide, int bounds[4]) +void WM_cursor_grab_enable(wmWindow *win, + const eWM_CursorWrapAxis wrap, + const rcti *wrap_region, + const bool hide) { + int _wrap_region_buf[4]; + int *wrap_region_screen = NULL; + /* Only grab cursor when not running debug. * It helps not to get a stuck WM when hitting a break-point. */ GHOST_TGrabCursorMode mode = GHOST_kGrabNormal; GHOST_TAxisFlag mode_axis = GHOST_kAxisX | GHOST_kAxisY; - if (bounds) { - wm_cursor_position_to_ghost_screen_coords(win, &bounds[0], &bounds[1]); - wm_cursor_position_to_ghost_screen_coords(win, &bounds[2], &bounds[3]); + if (wrap_region) { + wrap_region_screen = _wrap_region_buf; + wrap_region_screen[0] = wrap_region->xmin; + wrap_region_screen[1] = wrap_region->ymax; + wrap_region_screen[2] = wrap_region->xmax; + wrap_region_screen[3] = wrap_region->ymin; + wm_cursor_position_to_ghost_screen_coords(win, &wrap_region_screen[0], &wrap_region_screen[1]); + wm_cursor_position_to_ghost_screen_coords(win, &wrap_region_screen[2], &wrap_region_screen[3]); } if (hide) { mode = GHOST_kGrabHide; } - else if (wrap) { + else if (wrap != WM_CURSOR_WRAP_NONE) { mode = GHOST_kGrabWrap; if (wrap == WM_CURSOR_WRAP_X) { @@ -252,7 +263,7 @@ void WM_cursor_grab_enable(wmWindow *win, int wrap, bool hide, int bounds[4]) if ((G.debug & G_DEBUG) == 0) { if (win->ghostwin) { if (win->eventstate->tablet.is_motion_absolute == false) { - GHOST_SetCursorGrab(win->ghostwin, mode, mode_axis, bounds, NULL); + GHOST_SetCursorGrab(win->ghostwin, mode, mode_axis, wrap_region_screen, NULL); } win->grabcursor = mode; diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index 3b603b6a3c0..528495fe7ba 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -1517,8 +1517,8 @@ static int wm_operator_invoke(bContext *C, /* Grab cursor during blocking modal operators (X11) * Also check for macro. */ if (ot->flag & OPTYPE_BLOCKING || (op->opm && op->opm->type->flag & OPTYPE_BLOCKING)) { - int bounds[4] = {-1, -1, -1, -1}; - int wrap = WM_CURSOR_WRAP_NONE; + eWM_CursorWrapAxis wrap = WM_CURSOR_WRAP_NONE; + const rcti *wrap_region = nullptr; if (event && (U.uiflag & USER_CONTINUOUS_MOUSE)) { const wmOperator *op_test = op->opm ? op->opm : op; @@ -1536,7 +1536,6 @@ static int wm_operator_invoke(bContext *C, } if (wrap) { - const rcti *winrect = nullptr; ARegion *region = CTX_wm_region(C); ScrArea *area = CTX_wm_area(C); @@ -1547,21 +1546,14 @@ static int wm_operator_invoke(bContext *C, if (region && region->regiontype == RGN_TYPE_WINDOW && BLI_rcti_isect_pt_v(®ion->winrct, event->xy)) { - winrect = ®ion->winrct; + wrap_region = ®ion->winrct; } else if (area && BLI_rcti_isect_pt_v(&area->totrct, event->xy)) { - winrect = &area->totrct; - } - - if (winrect) { - bounds[0] = winrect->xmin; - bounds[1] = winrect->ymax; - bounds[2] = winrect->xmax; - bounds[3] = winrect->ymin; + wrap_region = &area->totrct; } } - WM_cursor_grab_enable(CTX_wm_window(C), wrap, false, bounds); + WM_cursor_grab_enable(CTX_wm_window(C), wrap, wrap_region, false); } /* Cancel UI handlers, typically tool-tips that can hang around diff --git a/source/blender/windowmanager/intern/wm_operator_type.c b/source/blender/windowmanager/intern/wm_operator_type.c index 1da8159df13..7b3f32a2d92 100644 --- a/source/blender/windowmanager/intern/wm_operator_type.c +++ b/source/blender/windowmanager/intern/wm_operator_type.c @@ -411,8 +411,8 @@ static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event) /* If operator is blocking, grab cursor. * This may end up grabbing twice, but we don't care. */ if (op->opm->type->flag & OPTYPE_BLOCKING) { - int bounds[4] = {-1, -1, -1, -1}; int wrap = WM_CURSOR_WRAP_NONE; + const rcti *wrap_region = NULL; if ((op->opm->flag & OP_IS_MODAL_GRAB_CURSOR) || (op->opm->type->flag & OPTYPE_GRAB_CURSOR_XY)) { @@ -428,14 +428,11 @@ static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event) if (wrap) { ARegion *region = CTX_wm_region(C); if (region) { - bounds[0] = region->winrct.xmin; - bounds[1] = region->winrct.ymax; - bounds[2] = region->winrct.xmax; - bounds[3] = region->winrct.ymin; + wrap_region = ®ion->winrct; } } - WM_cursor_grab_enable(win, wrap, false, bounds); + WM_cursor_grab_enable(win, wrap, wrap_region, false); } } } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 7ee074660b0..74907917193 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -2103,6 +2103,8 @@ void WM_init_input_devices(void) void WM_cursor_warp(wmWindow *win, int x, int y) { + /* This function requires access to the GHOST_SystemHandle (`g_system`). */ + if (!(win && win->ghostwin)) { return; } From b147af2b7ee4a995a9a444f864bcbb2ad03f9c4f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 14:56:58 +1100 Subject: [PATCH 0128/1522] Cleanup: remove duplicate doc-strings --- intern/ghost/intern/GHOST_SystemX11.cpp | 35 +-------------------- intern/ghost/intern/GHOST_WindowWayland.cpp | 4 --- intern/ghost/intern/GHOST_WindowX11.cpp | 5 --- 3 files changed, 1 insertion(+), 43 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 4baa3ff598f..72f34dac52e 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -275,10 +275,6 @@ uint8_t GHOST_SystemX11::getNumDisplays() const return uint8_t(1); } -/** - * Returns the dimensions of the main display on this system. - * \return The dimension of the main display. - */ void GHOST_SystemX11::getMainDisplayDimensions(uint32_t &width, uint32_t &height) const { if (m_display) { @@ -289,10 +285,6 @@ void GHOST_SystemX11::getMainDisplayDimensions(uint32_t &width, uint32_t &height } } -/** - * Returns the dimensions of the main display on this system. - * \return The dimension of the main display. - */ void GHOST_SystemX11::getAllDisplayDimensions(uint32_t &width, uint32_t &height) const { if (m_display) { @@ -301,22 +293,6 @@ void GHOST_SystemX11::getAllDisplayDimensions(uint32_t &width, uint32_t &height) } } -/** - * Create a new window. - * The new window is added to the list of windows managed. - * Never explicitly delete the window, use #disposeWindow() instead. - * \param title: The name of the window - * (displayed in the title bar of the window if the OS supports it). - * \param left: The coordinate of the left edge of the window. - * \param top: The coordinate of the top edge of the window. - * \param width: The width the window. - * \param height: The height the window. - * \param state: The state of the window when opened. - * \param glSettings: Misc OpenGL settings. - * \param exclusive: Use to show the window on top and ignore others (used full-screen). - * \param parentWindow: Parent window. - * \return The new window (or 0 if creation failed). - */ GHOST_IWindow *GHOST_SystemX11::createWindow(const char *title, int32_t left, int32_t top, @@ -417,11 +393,7 @@ static GHOST_Context *create_glx_context(Display *display, return nullptr; } -/** - * Create a new off-screen context. - * Never explicitly delete the context, use #disposeContext() instead. - * \return The new context (or 0 if creation failed). - */ + GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSettings) { /* During development: @@ -479,11 +451,6 @@ GHOST_IContext *GHOST_SystemX11::createOffscreenContext(GHOST_GLSettings glSetti return nullptr; } -/** - * Dispose of a context. - * \param context: Pointer to the context to be disposed. - * \return Indication of success. - */ GHOST_TSuccess GHOST_SystemX11::disposeContext(GHOST_IContext *context) { delete context; diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index 239693e0e5b..ffbb8370c46 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -1203,10 +1203,6 @@ void GHOST_WindowWayland::setOpaque() const } #endif -/** - * \param type: The type of rendering context create. - * \return Indication of success. - */ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType type) { GHOST_Context *context; diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 9f77bdc4dd0..00b0230888e 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -1112,11 +1112,6 @@ void GHOST_WindowX11::validate() m_invalid_window = false; } -/** - * Destructor. - * Closes the window and disposes resources allocated. - */ - GHOST_WindowX11::~GHOST_WindowX11() { std::map::iterator it = m_standard_cursors.begin(); From d715573aea95b91143e6e181d0100e69c6dab93c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 15:10:51 +1100 Subject: [PATCH 0129/1522] Cleanup: declare GHOST_Window::getCursorGrabBounds as const Needed so it the method can be called on a cosnt GHOST_Window. --- intern/ghost/GHOST_IWindow.h | 2 +- intern/ghost/intern/GHOST_Window.cpp | 2 +- intern/ghost/intern/GHOST_Window.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index 33b9d160f0f..403f9e388cc 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -274,7 +274,7 @@ class GHOST_IWindow { */ virtual GHOST_TSuccess setCursorShape(GHOST_TStandardCursor cursorShape) = 0; - virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) = 0; + virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) const = 0; virtual void getCursorGrabState(GHOST_TGrabCursorMode &mode, GHOST_TAxisFlag &axis_flag, diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index 144bfeab373..202f803f710 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -175,7 +175,7 @@ GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, return GHOST_kFailure; } -GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect &bounds) +GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect &bounds) const { if (m_cursorGrab != GHOST_kGrabWrap) { return GHOST_kFailure; diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index 741ce786859..04ce9fed950 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -152,7 +152,7 @@ class GHOST_Window : public GHOST_IWindow { * Gets the cursor grab region, if unset the window is used. * reset when grab is disabled. */ - GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) override; + GHOST_TSuccess getCursorGrabBounds(GHOST_Rect &bounds) const override; void getCursorGrabState(GHOST_TGrabCursorMode &mode, GHOST_TAxisFlag &axis_flag, From 18cc1b11084098d2d709a6eb904257ab327568b2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 15:19:57 +1100 Subject: [PATCH 0130/1522] Fix cursor warping display under Wayland Under Wayland the transform cursor wasn't displaying the warped cursor. This worked on other platforms because cursor motion is warped where as Wayland simulates cursor warping, so it's necessary to apply warping when requesting the cursor location too. --- intern/ghost/intern/GHOST_SystemWayland.cpp | 32 +++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 6bc07fed10c..efcbc79d5c2 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -5830,8 +5830,36 @@ static GHOST_TSuccess getCursorPositionClientRelative_impl( int32_t &y) { const wl_fixed_t scale = win->scale(); - x = wl_fixed_to_int(scale * seat_state_pointer->xy[0]); - y = wl_fixed_to_int(scale * seat_state_pointer->xy[1]); + + if (win->getCursorGrabModeIsWarp()) { + /* As the cursor is restored at the warped location, + * apply warping when requesting the cursor location. */ + GHOST_Rect wrap_bounds{}; + if (win->getCursorGrabModeIsWarp()) { + if (win->getCursorGrabBounds(wrap_bounds) == GHOST_kFailure) { + win->getClientBounds(wrap_bounds); + } + } + int xy_wrap[2] = { + seat_state_pointer->xy[0], + seat_state_pointer->xy[1], + }; + + GHOST_Rect wrap_bounds_scale; + wrap_bounds_scale.m_l = wl_fixed_from_int(wrap_bounds.m_l) / scale; + wrap_bounds_scale.m_t = wl_fixed_from_int(wrap_bounds.m_t) / scale; + wrap_bounds_scale.m_r = wl_fixed_from_int(wrap_bounds.m_r) / scale; + wrap_bounds_scale.m_b = wl_fixed_from_int(wrap_bounds.m_b) / scale; + wrap_bounds_scale.wrapPoint(UNPACK2(xy_wrap), 0, win->getCursorGrabAxis()); + + x = wl_fixed_to_int(scale * xy_wrap[0]); + y = wl_fixed_to_int(scale * xy_wrap[1]); + } + else { + x = wl_fixed_to_int(scale * seat_state_pointer->xy[0]); + y = wl_fixed_to_int(scale * seat_state_pointer->xy[1]); + } + return GHOST_kSuccess; } From 657a5f205acc70fce542d075e68e7f7dba707233 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 16:30:42 +1100 Subject: [PATCH 0131/1522] Cleanup: remove redundant property lookups in RNA API use --- source/blender/editors/geometry/geometry_attributes.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index 4e53349707d..d4850f5c124 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -572,11 +572,11 @@ static int geometry_attribute_convert_invoke(bContext *C, PropertyRNA *prop = RNA_struct_find_property(op->ptr, "domain"); if (!RNA_property_is_set(op->ptr, prop)) { - RNA_enum_set(op->ptr, "domain", meta_data.domain); + RNA_property_enum_set(op->ptr, prop, meta_data.domain); } prop = RNA_struct_find_property(op->ptr, "data_type"); if (!RNA_property_is_set(op->ptr, prop)) { - RNA_enum_set(op->ptr, "data_type", meta_data.data_type); + RNA_property_enum_set(op->ptr, prop, meta_data.data_type); } return WM_operator_props_dialog_popup(C, op, 300); @@ -642,11 +642,11 @@ static int geometry_color_attribute_convert_invoke(bContext *C, PropertyRNA *prop = RNA_struct_find_property(op->ptr, "domain"); if (!RNA_property_is_set(op->ptr, prop)) { - RNA_enum_set(op->ptr, "domain", meta_data.domain); + RNA_property_enum_set(op->ptr, prop, meta_data.domain); } prop = RNA_struct_find_property(op->ptr, "data_type"); if (!RNA_property_is_set(op->ptr, prop)) { - RNA_enum_set(op->ptr, "data_type", meta_data.data_type); + RNA_property_enum_set(op->ptr, prop, meta_data.data_type); } return WM_operator_props_dialog_popup(C, op, 300); From 7571222a690372bc907cf42c5fd9faa7f78abc74 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 17:24:23 +1100 Subject: [PATCH 0132/1522] Cleanup: add trailing commas for multi-line collections Avoid accidentally missing commas between strings, see: T101020. Also use single quotes for enum identifiers. --- intern/cycles/blender/addon/presets.py | 2 +- .../scripts/modules/bpy_extras/anim_utils.py | 2 +- .../scripts/modules/bpy_extras/io_utils.py | 2 +- release/scripts/startup/bl_operators/clip.py | 2 +- .../scripts/startup/bl_operators/object.py | 2 +- .../bl_operators/object_quick_effects.py | 2 +- .../scripts/startup/bl_operators/presets.py | 16 ++++----- .../bl_operators/screen_play_rendered_anim.py | 2 +- .../scripts/startup/bl_operators/userpref.py | 4 +-- .../scripts/startup/bl_operators/view3d.py | 4 +-- release/scripts/startup/bl_operators/wm.py | 11 +++--- .../bl_ui/properties_grease_pencil_common.py | 4 +-- .../startup/bl_ui/properties_output.py | 4 +-- .../startup/bl_ui/properties_paint_common.py | 6 ++-- .../startup/bl_ui/properties_physics_cloth.py | 4 +-- .../bl_ui/properties_physics_common.py | 4 +-- release/scripts/startup/bl_ui/space_clip.py | 2 +- .../startup/bl_ui/space_filebrowser.py | 6 ++-- release/scripts/startup/bl_ui/space_image.py | 4 +-- release/scripts/startup/bl_ui/space_node.py | 24 ++++++------- .../scripts/startup/bl_ui/space_sequencer.py | 8 ++--- release/scripts/startup/bl_ui/space_text.py | 4 +-- .../startup/bl_ui/space_toolsystem_common.py | 5 +-- .../startup/bl_ui/space_toolsystem_toolbar.py | 34 +++++++++---------- .../scripts/startup/bl_ui/space_userpref.py | 4 +-- release/scripts/startup/bl_ui/space_view3d.py | 27 ++++++++++----- release/scripts/startup/nodeitems_builtins.py | 2 +- tests/python/bl_pyapi_idprop.py | 2 +- 28 files changed, 102 insertions(+), 91 deletions(-) diff --git a/intern/cycles/blender/addon/presets.py b/intern/cycles/blender/addon/presets.py index 6ad22d765aa..643f54a2bc3 100644 --- a/intern/cycles/blender/addon/presets.py +++ b/intern/cycles/blender/addon/presets.py @@ -92,7 +92,7 @@ class AddPresetPerformance(AddPresetBase, Operator): preset_defines = [ "render = bpy.context.scene.render", - "cycles = bpy.context.scene.cycles" + "cycles = bpy.context.scene.cycles", ] preset_values = [ diff --git a/release/scripts/modules/bpy_extras/anim_utils.py b/release/scripts/modules/bpy_extras/anim_utils.py index 3586401dd7a..3b90b18359e 100644 --- a/release/scripts/modules/bpy_extras/anim_utils.py +++ b/release/scripts/modules/bpy_extras/anim_utils.py @@ -159,7 +159,7 @@ def bake_action_iter( "bbone_curveinz", "bbone_curveoutz", "bbone_rollin", "bbone_rollout", "bbone_scalein", "bbone_scaleout", - "bbone_easein", "bbone_easeout" + "bbone_easein", "bbone_easeout", ] BBONE_PROPS_LENGTHS = { "bbone_curveinx": 1, diff --git a/release/scripts/modules/bpy_extras/io_utils.py b/release/scripts/modules/bpy_extras/io_utils.py index 4dbe0d6f05b..04b536fce40 100644 --- a/release/scripts/modules/bpy_extras/io_utils.py +++ b/release/scripts/modules/bpy_extras/io_utils.py @@ -12,7 +12,7 @@ __all__ = ( "path_reference", "path_reference_copy", "path_reference_mode", - "unique_name" + "unique_name", ) import bpy diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index 73c0b4cfd8f..4e018ffc457 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -1028,7 +1028,7 @@ class CLIP_OT_track_settings_to_track(Operator): "use_red_channel", "use_green_channel", "use_blue_channel", - "weight" + "weight", ) _attrs_marker = ( diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py index e3685b6ad78..6a130edbb38 100644 --- a/release/scripts/startup/bl_operators/object.py +++ b/release/scripts/startup/bl_operators/object.py @@ -776,7 +776,7 @@ class TransformsToDeltasAnim(Operator): "rotation_euler": "delta_rotation_euler", "rotation_quaternion": "delta_rotation_quaternion", # "rotation_axis_angle" : "delta_rotation_axis_angle", - "scale": "delta_scale" + "scale": "delta_scale", } DELTA_PATHS = STANDARD_TO_DELTA_PATHS.values() diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py index e48bd2c8987..d8b0e85be0e 100644 --- a/release/scripts/startup/bl_operators/object_quick_effects.py +++ b/release/scripts/startup/bl_operators/object_quick_effects.py @@ -46,7 +46,7 @@ class QuickFur(ObjectModeOperator, Operator): items=( ('LIGHT', "Light", ""), ('MEDIUM', "Medium", ""), - ('HEAVY', "Heavy", "") + ('HEAVY', "Heavy", ""), ), default='MEDIUM', ) diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index 203eb128f0f..e4b9021926e 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -20,7 +20,7 @@ from bpy.app.translations import ( WindowManager.preset_name = StringProperty( name="Preset Name", description="Name for new preset", - default=data_("New Preset") + default=data_("New Preset"), ) @@ -309,7 +309,7 @@ class AddPresetCamera(AddPresetBase, Operator): preset_values = [ "cam.sensor_width", "cam.sensor_height", - "cam.sensor_fit" + "cam.sensor_fit", ] if self.use_focal_length: preset_values.append("cam.lens") @@ -439,7 +439,7 @@ class AddPresetTrackingCamera(AddPresetBase, Operator): "camera.pixel_aspect", "camera.k1", "camera.k2", - "camera.k3" + "camera.k3", ] if self.use_focal_length: preset_values.append("camera.units") @@ -459,7 +459,7 @@ class AddPresetTrackingTrackColor(AddPresetBase, Operator): preset_values = [ "track.color", - "track.use_custom_color" + "track.use_custom_color", ] preset_subdir = "tracking_track_color" @@ -489,7 +489,7 @@ class AddPresetTrackingSettings(AddPresetBase, Operator): "settings.use_default_red_channel", "settings.use_default_green_channel", "settings.use_default_blue_channel", - "settings.default_weight" + "settings.default_weight", ] preset_subdir = "tracking_settings" @@ -507,7 +507,7 @@ class AddPresetNodeColor(AddPresetBase, Operator): preset_values = [ "node.color", - "node.use_custom_color" + "node.use_custom_color", ] preset_subdir = "node_color" @@ -616,7 +616,7 @@ class AddPresetGpencilBrush(AddPresetBase, Operator): preset_defines = [ "brush = bpy.context.tool_settings.gpencil_paint.brush", - "settings = brush.gpencil_settings" + "settings = brush.gpencil_settings", ] preset_values = [ @@ -650,7 +650,7 @@ class AddPresetGpencilMaterial(AddPresetBase, Operator): preset_defines = [ "material = bpy.context.object.active_material", - "gpcolor = material.grease_pencil" + "gpcolor = material.grease_pencil", ] preset_values = [ diff --git a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py index 85bf38b08a8..11885da487e 100644 --- a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py +++ b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py @@ -133,7 +133,7 @@ class PlayRenderedAnim(Operator): "-speed", str(fps_final), "-in_out", str(frame_start), str(frame_end), "-frame", str(scene.frame_current), - "-time_units", "Frames" + "-time_units", "Frames", ] cmd.extend(opts) elif preset == 'FRAMECYCLER': diff --git a/release/scripts/startup/bl_operators/userpref.py b/release/scripts/startup/bl_operators/userpref.py index f1816b05aba..dc8504c057e 100644 --- a/release/scripts/startup/bl_operators/userpref.py +++ b/release/scripts/startup/bl_operators/userpref.py @@ -3,7 +3,7 @@ import bpy from bpy.types import ( Operator, - OperatorFileListElement + OperatorFileListElement, ) from bpy.props import ( BoolProperty, @@ -981,7 +981,7 @@ class PREFERENCES_OT_studiolight_install(Operator): ('MATCAP', "MatCap", "Install custom MatCaps"), ('WORLD', "World", "Install custom HDRIs"), ('STUDIO', "Studio", "Install custom Studio Lights"), - ) + ), ) def execute(self, context): diff --git a/release/scripts/startup/bl_operators/view3d.py b/release/scripts/startup/bl_operators/view3d.py index 59e668d81ea..bb0d163fdd6 100644 --- a/release/scripts/startup/bl_operators/view3d.py +++ b/release/scripts/startup/bl_operators/view3d.py @@ -32,7 +32,7 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator): TRANSFORM_OT_translate={ "orient_type": 'NORMAL', "constraint_axis": (False, False, True), - } + }, ) elif select_mode[2] and totface > 1: bpy.ops.mesh.extrude_faces_move('INVOKE_REGION_WIN') @@ -57,7 +57,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator): dissolve_and_intersect: BoolProperty( name="dissolve_and_intersect", default=False, - description="Dissolves adjacent faces and intersects new geometry" + description="Dissolves adjacent faces and intersects new geometry", ) @classmethod diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index abe304d84eb..bdb679eba07 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1377,7 +1377,8 @@ class WM_OT_properties_edit(Operator): name="Array Length", default=3, min=1, - max=32, # 32 is the maximum size for RNA array properties. + # 32 is the maximum size for RNA array properties. + max=32, ) # Integer properties. @@ -1458,7 +1459,7 @@ class WM_OT_properties_edit(Operator): # Store the value converted to a string as a fallback for otherwise unsupported types. eval_string: StringProperty( name="Value", - description="Python value for unsupported custom property types" + description="Python value for unsupported custom property types", ) type_items = rna_custom_property_type_items @@ -1904,7 +1905,7 @@ class WM_OT_properties_edit_value(Operator): # Store the value converted to a string as a fallback for otherwise unsupported types. eval_string: StringProperty( name="Value", - description="Value for custom property types that can only be edited as a Python expression" + description="Value for custom property types that can only be edited as a Python expression", ) def execute(self, context): @@ -2470,11 +2471,11 @@ class BatchRenameAction(bpy.types.PropertyGroup): replace_match_case: BoolProperty(name="Case Sensitive") use_replace_regex_src: BoolProperty( name="Regular Expression Find", - description="Use regular expressions to match text in the 'Find' field" + description="Use regular expressions to match text in the 'Find' field", ) use_replace_regex_dst: BoolProperty( name="Regular Expression Replace", - description="Use regular expression for the replacement text (supporting groups)" + description="Use regular expression for the replacement text (supporting groups)", ) # type: 'CASE'. diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index f4be9c793ac..3aa8879c594 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -210,12 +210,12 @@ class GPENCIL_MT_snap_pie(Menu): pie.operator( "gpencil.snap_to_cursor", text="Selection to Cursor", - icon='RESTRICT_SELECT_OFF' + icon='RESTRICT_SELECT_OFF', ).use_offset = False pie.operator( "gpencil.snap_to_cursor", text="Selection to Cursor (Keep Offset)", - icon='RESTRICT_SELECT_OFF' + icon='RESTRICT_SELECT_OFF', ).use_offset = True pie.separator() pie.operator("view3d.snap_cursor_to_center", text="Cursor to World Origin", icon='CURSOR') diff --git a/release/scripts/startup/bl_ui/properties_output.py b/release/scripts/startup/bl_ui/properties_output.py index 61384f25afb..c97d7579a81 100644 --- a/release/scripts/startup/bl_ui/properties_output.py +++ b/release/scripts/startup/bl_ui/properties_output.py @@ -386,7 +386,7 @@ class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel): 'MKV', 'OGG', 'MPEG4', - 'WEBM' + 'WEBM', } if needs_codec: layout.prop(ffmpeg, "codec") @@ -402,7 +402,7 @@ class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel): 'H264', 'MPEG4', 'WEBM', - 'AV1' + 'AV1', } if use_crf: layout.prop(ffmpeg, "constant_rate_factor") diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 3cd5df4df7d..6c060d57a6b 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -1196,7 +1196,7 @@ def brush_basic_texpaint_settings(layout, context, brush, *, compact=False): unified_name="use_unified_size", slider=True, text="Radius", - header=True + header=True, ) UnifiedPaintPanel.prop_unified( layout, @@ -1205,7 +1205,7 @@ def brush_basic_texpaint_settings(layout, context, brush, *, compact=False): "strength", pressure_name="use_pressure_strength", unified_name="use_unified_strength", - header=True + header=True, ) @@ -1345,7 +1345,7 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False) "builtin.line", "builtin.box", "builtin.circle", - "builtin.polyline" + "builtin.polyline", }: settings = context.tool_settings.gpencil_sculpt if compact: diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index e1d26fdcd69..335cf08a715 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -422,7 +422,7 @@ class PHYSICS_PT_cloth_property_weights(PhysicButtonsPanel, Panel): col = flow.column() col.prop_search( cloth, "vertex_group_bending", ob, "vertex_groups", - text="Bending Group" + text="Bending Group", ) col.prop(cloth, "bending_stiffness_max", text="Max Bending") @@ -431,7 +431,7 @@ class PHYSICS_PT_cloth_property_weights(PhysicButtonsPanel, Panel): col = flow.column() col.prop_search( cloth, "vertex_group_shrink", ob, "vertex_groups", - text="Shrinking Group" + text="Shrinking Group", ) col.prop(cloth, "shrink_max", text="Max Shrinking") diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 60f384a3839..4146a8ca51a 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -86,7 +86,7 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel): col, obj.rigid_body, "Rigid Body", "rigidbody.object_add", "rigidbody.object_remove", - 'RIGID_BODY' + 'RIGID_BODY', ) # all types of objects can have rigid body constraint. @@ -94,7 +94,7 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel): col, obj.rigid_body_constraint, "Rigid Body Constraint", "rigidbody.constraint_add", "rigidbody.constraint_remove", - 'RIGID_BODY_CONSTRAINT' + 'RIGID_BODY_CONSTRAINT', ) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index fd46fe3099e..5bf68cb04de 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -1166,7 +1166,7 @@ from bl_ui.properties_mask_common import ( MASK_PT_point, MASK_PT_display, MASK_PT_transforms, - MASK_PT_tools + MASK_PT_tools, ) diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 614f350533b..b2eeb4e6cf0 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -41,14 +41,14 @@ class FILEBROWSER_HT_header(Header): layout.popover( panel="ASSETBROWSER_PT_filter", text="", - icon='FILTER' + icon='FILTER', ) layout.operator( "screen.region_toggle", text="", icon='PREFERENCES', - depress=is_option_region_visible(context, space_data) + depress=is_option_region_visible(context, space_data), ).region_type = 'TOOL_PROPS' def draw(self, context): @@ -464,7 +464,7 @@ class FILEBROWSER_PT_directory_path(Panel): "screen.region_toggle", text="", icon='PREFERENCES', - depress=is_option_region_visible(context, space) + depress=is_option_region_visible(context, space), ).region_type = 'TOOL_PROPS' diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index f4c64831b3e..84aeacea03c 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -697,7 +697,7 @@ class _draw_tool_settings_context_mode: pressure_name="use_pressure_size", unified_name="use_unified_size", slider=True, - header=True + header=True, ) UnifiedPaintPanel.prop_unified( layout, @@ -707,7 +707,7 @@ class _draw_tool_settings_context_mode: pressure_name="use_pressure_strength", unified_name="use_unified_strength", slider=True, - header=True + header=True, ) @staticmethod diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 3eed3ee5cd3..103afa783be 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -14,7 +14,7 @@ from bl_ui.space_toolsystem_common import ( ) from bl_ui.properties_material import ( EEVEE_MATERIAL_PT_settings, - MATERIAL_PT_viewport + MATERIAL_PT_viewport, ) from bl_ui.properties_world import ( WORLD_PT_viewport_display @@ -496,18 +496,18 @@ class NODE_MT_context_menu(Menu): # If no nodes are selected. if selected_nodes_len == 0: layout.operator_context = 'INVOKE_DEFAULT' - layout.menu("NODE_MT_add", icon="ADD") - layout.operator("node.clipboard_paste", text="Paste", icon="PASTEDOWN") + layout.menu("NODE_MT_add", icon='ADD') + layout.operator("node.clipboard_paste", text="Paste", icon='PASTEDOWN') layout.separator() - layout.operator("node.find_node", text="Find...", icon="VIEWZOOM") + layout.operator("node.find_node", text="Find...", icon='VIEWZOOM') layout.separator() if is_geometrynodes: layout.operator_context = 'INVOKE_DEFAULT' - layout.operator("node.select", text="Clear Viewer", icon="HIDE_ON").clear_viewer = True + layout.operator("node.select", text="Clear Viewer", icon='HIDE_ON').clear_viewer = True layout.operator("node.links_cut") layout.operator("node.links_mute") @@ -521,19 +521,19 @@ class NODE_MT_context_menu(Menu): if is_geometrynodes: layout.operator_context = 'INVOKE_DEFAULT' - layout.operator("node.link_viewer", text="Link to Viewer", icon="HIDE_OFF") + layout.operator("node.link_viewer", text="Link to Viewer", icon='HIDE_OFF') layout.separator() - layout.operator("node.clipboard_copy", text="Copy", icon="COPYDOWN") - layout.operator("node.clipboard_paste", text="Paste", icon="PASTEDOWN") + layout.operator("node.clipboard_copy", text="Copy", icon='COPYDOWN') + layout.operator("node.clipboard_paste", text="Paste", icon='PASTEDOWN') layout.operator_context = 'INVOKE_DEFAULT' - layout.operator("node.duplicate_move", icon="DUPLICATE") + layout.operator("node.duplicate_move", icon='DUPLICATE') layout.separator() - layout.operator("node.delete", icon="X") + layout.operator("node.delete", icon='X') layout.operator_context = 'EXEC_REGION_WIN' layout.operator("node.delete_reconnect", text="Dissolve") @@ -546,7 +546,7 @@ class NODE_MT_context_menu(Menu): layout.separator() - layout.operator("node.group_make", text="Make Group", icon="NODETREE") + layout.operator("node.group_make", text="Make Group", icon='NODETREE') layout.operator("node.group_insert", text="Insert Into Group") if active_node and active_node.type == 'GROUP': @@ -878,7 +878,7 @@ class NodeTreeInterfacePanel(Panel): props = property_row.operator_menu_enum( "node.tree_socket_change_type", "socket_type", - text=active_socket.bl_label if active_socket.bl_label else active_socket.bl_idname + text=active_socket.bl_label if active_socket.bl_label else active_socket.bl_idname, ) props.in_out = in_out diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 1fed23a992c..56781b8c6d7 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -732,7 +732,7 @@ class SEQUENCER_MT_add_scene(Menu): layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("sequencer.scene_strip_add_new", text="New Scene", icon="ADD").type = 'NEW' + layout.operator("sequencer.scene_strip_add_new", text="New Scene", icon='ADD').type = 'NEW' bpy_data_scenes_len = len(bpy.data.scenes) if bpy_data_scenes_len > 10: @@ -1378,7 +1378,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', 'SPEED', - 'MULTICAM', 'GAUSSIAN_BLUR', 'TEXT', 'COLORMIX' + 'MULTICAM', 'GAUSSIAN_BLUR', 'TEXT', 'COLORMIX', } def draw(self, context): @@ -2112,7 +2112,7 @@ class SEQUENCER_PT_adjust_video(SequencerButtonsPanel, Panel): 'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', - 'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX' + 'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX', } def draw(self, context): @@ -2160,7 +2160,7 @@ class SEQUENCER_PT_adjust_color(SequencerButtonsPanel, Panel): 'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', - 'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX' + 'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX', } def draw(self, context): diff --git a/release/scripts/startup/bl_ui/space_text.py b/release/scripts/startup/bl_ui/space_text.py index d2db6ca8308..aba15d050f9 100644 --- a/release/scripts/startup/bl_ui/space_text.py +++ b/release/scripts/startup/bl_ui/space_text.py @@ -272,7 +272,7 @@ class TEXT_MT_templates_py(Menu): bpy.utils.script_paths(subdir="templates_py"), "text.open", props_default={"internal": True}, - filter_ext=lambda ext: (ext.lower() == ".py") + filter_ext=lambda ext: (ext.lower() == ".py"), ) @@ -284,7 +284,7 @@ class TEXT_MT_templates_osl(Menu): bpy.utils.script_paths(subdir="templates_osl"), "text.open", props_default={"internal": True}, - filter_ext=lambda ext: (ext.lower() == ".osl") + filter_ext=lambda ext: (ext.lower() == ".osl"), ) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index 81acc0837aa..ddffbc2b827 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -225,7 +225,7 @@ class ToolSelectPanelHelper: return next( (cls for cls in ToolSelectPanelHelper.__subclasses__() if cls.bl_space_type == space_type), - None + None, ) @staticmethod @@ -904,7 +904,8 @@ class ToolSelectPanelHelper: "workspace_tool_type", value='DEFAULT', text="Active Tool", - icon='TOOL_SETTINGS', # Could use a less generic icon. + # Could use a less generic icon. + icon='TOOL_SETTINGS', ) is_active_tool = (tool_settings.workspace_tool_type == 'DEFAULT') diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index b15e55a44f9..c18c2fe4b01 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -32,7 +32,7 @@ def generate_from_enum_ex( attr, cursor='DEFAULT', tooldef_keywords={}, - exclude_filter={} + exclude_filter={}, ): tool_defs = [] for enum in type.bl_rna.properties[attr].enum_items_static: @@ -49,8 +49,8 @@ def generate_from_enum_ex( cursor=cursor, data_block=idname, **tooldef_keywords, - ) - ) + ), + ), ) return tuple(tool_defs) @@ -1633,7 +1633,7 @@ class _defs_weight_paint: cursor='EYEDROPPER', widget=None, keymap=(), - draw_settings=draw_settings + draw_settings=draw_settings, ) @ToolDef.from_fn @@ -1660,7 +1660,7 @@ class _defs_weight_paint: "weight", unified_name="use_unified_weight", slider=True, - header=True + header=True, ) UnifiedPaintPanel.prop_unified( layout, @@ -1668,7 +1668,7 @@ class _defs_weight_paint: brush, "strength", unified_name="use_unified_strength", - header=True + header=True, ) props = tool.operator_properties("paint.weight_gradient") @@ -2323,7 +2323,7 @@ class _defs_curves_sculpt: idname="builtin_brush.selection_paint", label="Selection Paint", icon="ops.generic.select_paint", - data_block="SELECTION_PAINT" + data_block="SELECTION_PAINT", ) @ToolDef.from_fn @@ -2332,7 +2332,7 @@ class _defs_curves_sculpt: idname="builtin_brush.comb", label="Comb", icon="ops.curves.sculpt_comb", - data_block='COMB' + data_block='COMB', ) @ToolDef.from_fn @@ -2341,7 +2341,7 @@ class _defs_curves_sculpt: idname="builtin_brush.add", label="Add", icon="ops.curves.sculpt_add", - data_block='ADD' + data_block='ADD', ) @ToolDef.from_fn @@ -2350,7 +2350,7 @@ class _defs_curves_sculpt: idname="builtin_brush.delete", label="Delete", icon="ops.curves.sculpt_delete", - data_block='DELETE' + data_block='DELETE', ) @ToolDef.from_fn @@ -2359,7 +2359,7 @@ class _defs_curves_sculpt: idname="builtin_brush.snake_hook", label="Snake Hook", icon="ops.curves.sculpt_snake_hook", - data_block='SNAKE_HOOK' + data_block='SNAKE_HOOK', ) @ToolDef.from_fn @@ -2368,7 +2368,7 @@ class _defs_curves_sculpt: idname="builtin_brush.grow_shrink", label="Grow/Shrink", icon="ops.curves.sculpt_grow_shrink", - data_block='GROW_SHRINK' + data_block='GROW_SHRINK', ) @ToolDef.from_fn @@ -2377,7 +2377,7 @@ class _defs_curves_sculpt: idname="builtin_brush.pinch", label="Pinch", icon="ops.curves.sculpt_pinch", - data_block='PINCH' + data_block='PINCH', ) @ToolDef.from_fn @@ -2386,7 +2386,7 @@ class _defs_curves_sculpt: idname="builtin_brush.smooth", label="Smooth", icon="ops.curves.sculpt_smooth", - data_block='SMOOTH' + data_block='SMOOTH', ) @ToolDef.from_fn @@ -2395,7 +2395,7 @@ class _defs_curves_sculpt: idname="builtin_brush.puff", label="Puff", icon="ops.curves.sculpt_puff", - data_block='PUFF' + data_block='PUFF', ) @ToolDef.from_fn @@ -2404,7 +2404,7 @@ class _defs_curves_sculpt: idname="builtin_brush.density", label="Density", icon="ops.curves.sculpt_density", - data_block="DENSITY" + data_block="DENSITY", ) @ToolDef.from_fn @@ -2413,7 +2413,7 @@ class _defs_curves_sculpt: idname="builtin_brush.slide", label="Slide", icon="ops.curves.sculpt_slide", - data_block="SLIDE" + data_block="SLIDE", ) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 11f5fdaa348..759b222c562 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -1131,7 +1131,7 @@ class PreferenceThemeSpacePanel: }, 'CLIP_EDITOR': { "handle_vertex_select", - } + }, } # TODO theme_area should be deprecated @@ -2289,7 +2289,7 @@ class USERPREF_PT_experimental_virtual_reality(ExperimentalPanel, Panel): context, ( ({"property": "use_virtual_reality_scene_inspection"}, "T71347"), ({"property": "use_virtual_reality_immersive_drawing"}, "T71348"), - ) + ), ) """ diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 63aff89aa7d..263a323bb63 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -845,13 +845,13 @@ class VIEW3D_HT_header(Header): layout.popover( panel="VIEW3D_PT_gpencil_sculpt_automasking", text="", - icon="MOD_MASK" + icon='MOD_MASK', ) elif object_mode == 'SCULPT': layout.popover( panel="VIEW3D_PT_sculpt_automasking", text="", - icon="MOD_MASK" + icon='MOD_MASK', ) else: # Transform settings depending on tool header visibility @@ -1254,12 +1254,21 @@ class VIEW3D_MT_view(Menu): layout.separator() - layout.operator("render.opengl", text="Viewport Render Image", icon='RENDER_STILL') - layout.operator("render.opengl", text="Viewport Render Animation", icon='RENDER_ANIMATION').animation = True - props = layout.operator("render.opengl", - text="Viewport Render Keyframes", - icon='RENDER_ANIMATION', - ) + layout.operator( + "render.opengl", + text="Viewport Render Image", + icon='RENDER_STILL', + ) + layout.operator( + "render.opengl", + text="Viewport Render Animation", + icon='RENDER_ANIMATION', + ).animation = True + props = layout.operator( + "render.opengl", + text="Viewport Render Keyframes", + icon='RENDER_ANIMATION', + ) props.animation = True props.render_keyed_only = True @@ -6218,7 +6227,7 @@ class VIEW3D_PT_shading_compositor(Panel): row.active = not is_macos row.prop(shading, "use_compositor", expand=True) if is_macos and shading.use_compositor != "DISABLED": - self.layout.label(text="Compositor not supported on MacOS.", icon="ERROR") + self.layout.label(text="Compositor not supported on MacOS.", icon='ERROR') class VIEW3D_PT_gizmo_display(Panel): diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index d1946b2f01d..2856e33931b 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -213,7 +213,7 @@ shader_node_categories = [ NodeItem("ShaderNodeVolumeScatter", poll=eevee_cycles_shader_nodes_poll), NodeItem("ShaderNodeVolumePrincipled"), NodeItem("ShaderNodeEeveeSpecular", poll=object_eevee_shader_nodes_poll), - NodeItem("ShaderNodeBsdfHairPrincipled", poll=object_cycles_shader_nodes_poll) + NodeItem("ShaderNodeBsdfHairPrincipled", poll=object_cycles_shader_nodes_poll), ]), ShaderNodeCategory("SH_NEW_TEXTURE", "Texture", items=[ NodeItem("ShaderNodeTexImage"), diff --git a/tests/python/bl_pyapi_idprop.py b/tests/python/bl_pyapi_idprop.py index ddce132dd5a..dcb8a3a33d3 100644 --- a/tests/python/bl_pyapi_idprop.py +++ b/tests/python/bl_pyapi_idprop.py @@ -218,7 +218,7 @@ class TestBufferProtocol(TestHelper, unittest.TestCase): def assertEqualMemviews(self, view1, view2): props_to_compare = ( "contiguous", "format", "itemsize", "nbytes", "ndim", - "readonly", "shape", "strides", "suboffsets" + "readonly", "shape", "strides", "suboffsets", ) for attr in props_to_compare: self.assertEqual(getattr(view1, attr), getattr(view2, attr)) From 9e47db4f43a2b882d0a7d9f14560e90e1487b4c5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 18:03:09 +1100 Subject: [PATCH 0133/1522] Correct build error with MSVC --- .../editors/space_view3d/view3d_navigate_walk.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_navigate_walk.c b/source/blender/editors/space_view3d/view3d_navigate_walk.c index 3d113c408eb..5606527a5fd 100644 --- a/source/blender/editors/space_view3d/view3d_navigate_walk.c +++ b/source/blender/editors/space_view3d/view3d_navigate_walk.c @@ -617,11 +617,12 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int const int size[2] = {BLI_rcti_size_x(winrct), BLI_rcti_size_y(winrct)}; const int div = 4; /* Where 2 is the region size. */ - rcti wrap_region = {}; - wrap_region.xmin = center[0] - (size[0] / div); - wrap_region.xmax = center[0] + (size[0] / div); - wrap_region.ymin = center[1] - (size[1] / div); - wrap_region.ymax = center[1] + (size[1] / div); + const rcti wrap_region = { + .xmin = center[0] - (size[0] / div), + .xmax = center[0] + (size[0] / div), + .ymin = center[1] - (size[1] / div), + .ymax = center[1] + (size[1] / div), + }; WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, &wrap_region, false); From e5f139e99d1a89988c5d3383989ac4d2b308ac1f Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Tue, 6 Dec 2022 14:49:44 +0100 Subject: [PATCH 0134/1522] Fix T101889: Curves editmode points are drawn from evaluated curves Editmode should display the original (non-evaluated) points unless there is something like an "On Cage" option of a modifier [which none of the curves modifiers have]. This was not the case since the introduction in rBe15320568a29. So we now draw the editpoints from the original curves. This also means that original and evaluated curves might not have the same number of points, so we have to get independent of `proc_point_buf` since that would possibly create vertexbuffers of different sizes (compared to the original curves) which is not allowed for a single batch. - remove the "pos" alias from the vertex buffer format of proc_point_buf - instead, create a new "edit_points_pos" vertex buffer - fill that with the original (un-evaluated) curves positions - dont request `proc_point_buf` anymore - rename the editpoints flags buffer to be more consistent And since original and evaluated points might also be in completely different positions, we also need to draw connecting lines between those editpoints to not have them float in thin air. For drawing these in editmode, a simple polyline was chosen (instead of drawing lines in a resolution that is take from the old particle system -- which is not depending on points even but has a hardcoded resolution that can only be upped by the hair_subdiv scene render setting) - create appropriate batch and indexbuffer for this - positions vertex buffer can be reused - reuse particle edit shader (instead of curve edi shader) to get segment highlighting {F14055436} NOTE: this also removes the broken depth handling and instead makes it work (also XRay is properly taken into account) by binding the correct overlay framebuffer. NOTE: to further clarify the distinction between curves drawing (that is based on the old partice system drawing) and drawing in editmode, the corresponding vertexbuffers have been moved out of CurvesEvalCache into CurvesBatchCache directly. NOTE: drawing the lines in editmode could be improved (taking the "real" resolution of splines into account, but since this should happen on the GPU in a compute shader, this is for later) Potentionally fixes T101889. Maniphest Tasks: T101889 Differential Revision: https://developer.blender.org/D16281 --- .../engines/overlay/overlay_edit_curves.cc | 42 +++--- .../draw/engines/overlay/overlay_private.hh | 4 +- source/blender/draw/intern/draw_cache_impl.h | 1 + .../draw/intern/draw_cache_impl_curves.cc | 129 ++++++++++++++---- .../blender/draw/intern/draw_curves_private.h | 5 +- 5 files changed, 130 insertions(+), 51 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_edit_curves.cc b/source/blender/draw/engines/overlay/overlay_edit_curves.cc index dab44c655a5..c2b7e3ee92f 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_curves.cc +++ b/source/blender/draw/engines/overlay/overlay_edit_curves.cc @@ -22,12 +22,11 @@ void OVERLAY_edit_curves_init(OVERLAY_Data *vedata) /* Create view with depth offset. */ DRWView *default_view = (DRWView *)DRW_view_default_get(); - pd->view_edit_curves_points = default_view; + pd->view_edit_curves = DRW_view_create_with_zoffset(default_view, draw_ctx->rv3d, 1.0f); } void OVERLAY_edit_curves_cache_init(OVERLAY_Data *vedata) { - OVERLAY_TextureList *txl = vedata->txl; OVERLAY_PassList *psl = vedata->psl; OVERLAY_PrivateData *pd = vedata->stl->pd; @@ -35,33 +34,35 @@ void OVERLAY_edit_curves_cache_init(OVERLAY_Data *vedata) DRWState state = (DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_ALPHA | DRW_STATE_WRITE_DEPTH); - /* Common boilerplate for shading groups. */ - DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); - const DRWContextState *draw_ctx = DRW_context_state_get(); - const View3D *v3d = draw_ctx->v3d; - GPUTexture **depth_tex = (pd->edit_curves.do_zbufclip) ? &dtxl->depth : &txl->dummy_depth_tx; - const float backwire_opacity = (pd->edit_curves.do_zbufclip) ? v3d->overlay.backwire_opacity : - 1.0f; + GPUShader *sh; + DRWShadingGroup *grp; /* Run Twice for in-front passes. */ for (int i = 0; i < 2; i++) { DRW_PASS_CREATE(psl->edit_curves_points_ps[i], (state | pd->clipping_state)); - - GPUShader *sh = OVERLAY_shader_edit_curve_point(); - DRWShadingGroup *grp = pd->edit_curves_points_grp[i] = DRW_shgroup_create( - sh, psl->edit_curves_points_ps[i]); + sh = OVERLAY_shader_edit_particle_point(); + grp = pd->edit_curves_points_grp[i] = DRW_shgroup_create(sh, psl->edit_curves_points_ps[i]); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); - DRW_shgroup_uniform_float_copy(grp, "alpha", backwire_opacity); - DRW_shgroup_uniform_texture_ref(grp, "depthTex", depth_tex); + + DRW_PASS_CREATE(psl->edit_curves_lines_ps[i], (state | pd->clipping_state)); + sh = OVERLAY_shader_edit_particle_strand(); + grp = pd->edit_curves_lines_grp[i] = DRW_shgroup_create(sh, psl->edit_curves_lines_ps[i]); + DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); + DRW_shgroup_uniform_bool_copy(grp, "useWeight", false); } } static void overlay_edit_curves_add_ob_to_pass(OVERLAY_PrivateData *pd, Object *ob, bool in_front) { Curves *curves = static_cast(ob->data); + DRWShadingGroup *point_shgrp = pd->edit_curves_points_grp[in_front]; struct GPUBatch *geom_points = DRW_curves_batch_cache_get_edit_points(curves); DRW_shgroup_call_no_cull(point_shgrp, geom_points, ob); + + DRWShadingGroup *lines_shgrp = pd->edit_curves_lines_grp[in_front]; + struct GPUBatch *geom_lines = DRW_curves_batch_cache_get_edit_lines(curves); + DRW_shgroup_call_no_cull(lines_shgrp, geom_lines, ob); } void OVERLAY_edit_curves_cache_populate(OVERLAY_Data *vedata, Object *ob) @@ -80,13 +81,20 @@ void OVERLAY_edit_curves_draw(OVERLAY_Data *vedata) { OVERLAY_PassList *psl = vedata->psl; OVERLAY_PrivateData *pd = vedata->stl->pd; + OVERLAY_FramebufferList *fbl = vedata->fbl; + + if (DRW_state_is_fbo()) { + GPU_framebuffer_bind(fbl->overlay_default_fb); + } if (pd->edit_curves.do_zbufclip) { - DRW_view_set_active(pd->view_edit_curves_points); + DRW_view_set_active(pd->view_edit_curves); DRW_draw_pass(psl->edit_curves_points_ps[NOT_IN_FRONT]); + DRW_draw_pass(psl->edit_curves_lines_ps[NOT_IN_FRONT]); } else { - DRW_view_set_active(pd->view_edit_curves_points); + DRW_view_set_active(pd->view_edit_curves); DRW_draw_pass(psl->edit_curves_points_ps[IN_FRONT]); + DRW_draw_pass(psl->edit_curves_lines_ps[IN_FRONT]); } } diff --git a/source/blender/draw/engines/overlay/overlay_private.hh b/source/blender/draw/engines/overlay/overlay_private.hh index b1118e084a6..5636286a8ac 100644 --- a/source/blender/draw/engines/overlay/overlay_private.hh +++ b/source/blender/draw/engines/overlay/overlay_private.hh @@ -76,6 +76,7 @@ typedef struct OVERLAY_PassList { DRWPass *edit_mesh_faces_ps[2]; DRWPass *edit_mesh_faces_cage_ps[2]; DRWPass *edit_curves_points_ps[2]; + DRWPass *edit_curves_lines_ps[2]; DRWPass *edit_mesh_analysis_ps; DRWPass *edit_mesh_normals_ps; DRWPass *edit_particle_ps; @@ -264,6 +265,7 @@ typedef struct OVERLAY_PrivateData { DRWShadingGroup *edit_uv_face_dots_grp; DRWShadingGroup *edit_uv_stretching_grp; DRWShadingGroup *edit_curves_points_grp[2]; + DRWShadingGroup *edit_curves_lines_grp[2]; DRWShadingGroup *extra_grid_grp; DRWShadingGroup *facing_grp[2]; DRWShadingGroup *fade_grp[2]; @@ -305,7 +307,7 @@ typedef struct OVERLAY_PrivateData { DRWView *view_edit_verts; DRWView *view_edit_text; DRWView *view_reference_images; - DRWView *view_edit_curves_points; + DRWView *view_edit_curves; /** TODO: get rid of this. */ ListBase bg_movie_clips; diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index feb83283e90..6f7f34a3d79 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -137,6 +137,7 @@ struct GPUVertBuf **DRW_curves_texture_for_evaluated_attribute(struct Curves *cu bool *r_is_point_domain); struct GPUBatch *DRW_curves_batch_cache_get_edit_points(struct Curves *curves); +struct GPUBatch *DRW_curves_batch_cache_get_edit_lines(struct Curves *curves); void DRW_curves_batch_cache_create_requested(struct Object *ob); diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index 1fc4d2e1f91..10ca2ef0c26 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -23,6 +23,8 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DEG_depsgraph_query.h" + #include "BKE_curves.hh" #include "BKE_geometry_set.hh" @@ -51,6 +53,15 @@ struct CurvesBatchCache { CurvesEvalCache curves_cache; GPUBatch *edit_points; + GPUBatch *edit_lines; + + /* Editmode (original) point positions. */ + GPUVertBuf *edit_points_pos; + + /* Editmode data (such as selection). */ + GPUVertBuf *edit_points_data; + + GPUIndexBuf *edit_lines_ibo; /* Whether the cache is invalid. */ bool is_dirty; @@ -99,13 +110,22 @@ static void curves_discard_attributes(CurvesEvalCache &curves_cache) } } -static void curves_batch_cache_clear_data(CurvesEvalCache &curves_cache) +static void curves_batch_cache_clear_edit_data(CurvesBatchCache *cache) +{ + /* TODO: more granular update tagging. */ + GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_pos); + GPU_VERTBUF_DISCARD_SAFE(cache->edit_points_data); + GPU_INDEXBUF_DISCARD_SAFE(cache->edit_lines_ibo); + + GPU_BATCH_DISCARD_SAFE(cache->edit_points); + GPU_BATCH_DISCARD_SAFE(cache->edit_lines); +} + +static void curves_batch_cache_clear_eval_data(CurvesEvalCache &curves_cache) { /* TODO: more granular update tagging. */ GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_point_buf); GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_length_buf); - GPU_VERTBUF_DISCARD_SAFE(curves_cache.data_edit_points); - GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_buf); GPU_VERTBUF_DISCARD_SAFE(curves_cache.proc_strand_seg_buf); @@ -126,9 +146,8 @@ static void curves_batch_cache_clear(Curves &curves) return; } - curves_batch_cache_clear_data(cache->curves_cache); - - GPU_BATCH_DISCARD_SAFE(cache->edit_points); + curves_batch_cache_clear_eval_data(cache->curves_cache); + curves_batch_cache_clear_edit_data(cache); } void DRW_curves_batch_cache_validate(Curves *curves) @@ -258,7 +277,6 @@ static void curves_batch_cache_ensure_procedural_pos(const Curves &curves, /* Initialize vertex format. */ GPUVertFormat format = {0}; GPU_vertformat_attr_add(&format, "posTime", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - GPU_vertformat_alias_add(&format, "pos"); cache.proc_point_buf = GPU_vertbuf_create_with_format_ex( &format, GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY); @@ -282,47 +300,85 @@ static void curves_batch_cache_ensure_procedural_pos(const Curves &curves, } } -static void curves_batch_cache_ensure_data_edit_points(const Curves &curves_id, - CurvesEvalCache &cache) +static void curves_batch_cache_ensure_edit_points_pos(const Curves &curves_id, + CurvesBatchCache &cache) +{ + using namespace blender; + const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); + + static GPUVertFormat format_pos = {0}; + static uint pos; + if (format_pos.attr_len == 0) { + pos = GPU_vertformat_attr_add(&format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + } + + GPU_vertbuf_init_with_format(cache.edit_points_pos, &format_pos); + GPU_vertbuf_data_alloc(cache.edit_points_pos, curves.points_num()); + + Span positions = curves.positions(); + GPU_vertbuf_attr_fill(cache.edit_points_pos, pos, positions.data()); +} + +static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id, + CurvesBatchCache &cache) { using namespace blender; const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); static GPUVertFormat format_data = {0}; - static uint data; + static uint color; if (format_data.attr_len == 0) { - data = GPU_vertformat_attr_add(&format_data, "data", GPU_COMP_U8, 1, GPU_FETCH_INT); + color = GPU_vertformat_attr_add(&format_data, "color", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); } - GPU_vertbuf_init_with_format(cache.data_edit_points, &format_data); - GPU_vertbuf_data_alloc(cache.data_edit_points, curves.points_num()); + GPU_vertbuf_init_with_format(cache.edit_points_data, &format_data); + GPU_vertbuf_data_alloc(cache.edit_points_data, curves.points_num()); VArray selection; switch (curves_id.selection_domain) { case ATTR_DOMAIN_POINT: selection = curves.selection_point_float(); for (const int point_i : selection.index_range()) { - uint8_t vflag = 0; - const float point_selection = selection[point_i]; - SET_FLAG_FROM_TEST(vflag, (point_selection > 0.0f), VFLAG_VERT_SELECTED); - GPU_vertbuf_attr_set(cache.data_edit_points, data, point_i, &vflag); + const float point_selection = (selection[point_i] > 0.0f) ? 1.0f : 0.0f; + GPU_vertbuf_attr_set(cache.edit_points_data, color, point_i, &point_selection); } break; case ATTR_DOMAIN_CURVE: selection = curves.selection_curve_float(); for (const int curve_i : curves.curves_range()) { - uint8_t vflag = 0; - const float curve_selection = selection[curve_i]; - SET_FLAG_FROM_TEST(vflag, (curve_selection > 0.0f), VFLAG_VERT_SELECTED); + const float curve_selection = (selection[curve_i] > 0.0f) ? 1.0f : 0.0f; const IndexRange points = curves.points_for_curve(curve_i); for (const int point_i : points) { - GPU_vertbuf_attr_set(cache.data_edit_points, data, point_i, &vflag); + GPU_vertbuf_attr_set(cache.edit_points_data, color, point_i, &curve_selection); } } break; } } +static void curves_batch_cache_ensure_edit_lines(const Curves &curves_id, CurvesBatchCache &cache) +{ + using namespace blender; + const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); + + const int vert_len = curves.points_num(); + const int curve_len = curves.curves_num(); + const int index_len = vert_len + curve_len; + + GPUIndexBufBuilder elb; + GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, index_len, vert_len); + + for (const int i : curves.curves_range()) { + const IndexRange points = curves.points_for_curve(i); + for (const int i_point : points) { + GPU_indexbuf_add_generic_vert(&elb, i_point); + } + GPU_indexbuf_add_primitive_restart(&elb); + } + + GPU_indexbuf_build_in_place(&elb, cache.edit_lines_ibo); +} + void drw_curves_get_attribute_sampler_name(const char *layer_name, char r_sampler_name[32]) { char attr_safe_name[GPU_MAX_SAFE_ATTR_NAME]; @@ -617,6 +673,12 @@ GPUBatch *DRW_curves_batch_cache_get_edit_points(Curves *curves) return DRW_batch_request(&cache.edit_points); } +GPUBatch *DRW_curves_batch_cache_get_edit_lines(Curves *curves) +{ + CurvesBatchCache &cache = curves_batch_cache_get(*curves); + return DRW_batch_request(&cache.edit_lines); +} + static void request_attribute(Curves &curves, const char *name) { CurvesBatchCache &cache = curves_batch_cache_get(curves); @@ -684,18 +746,27 @@ GPUVertBuf **DRW_curves_texture_for_evaluated_attribute(Curves *curves, void DRW_curves_batch_cache_create_requested(Object *ob) { Curves *curves = static_cast(ob->data); + Object *orig = DEG_get_original_object(ob); + Curves *curves_orig = static_cast(orig->data); + CurvesBatchCache &cache = curves_batch_cache_get(*curves); if (DRW_batch_requested(cache.edit_points, GPU_PRIM_POINTS)) { - DRW_vbo_request(cache.edit_points, &cache.curves_cache.proc_point_buf); - DRW_vbo_request(cache.edit_points, &cache.curves_cache.data_edit_points); + DRW_vbo_request(cache.edit_points, &cache.edit_points_pos); + DRW_vbo_request(cache.edit_points, &cache.edit_points_data); } - - if (DRW_vbo_requested(cache.curves_cache.proc_point_buf)) { - curves_batch_cache_ensure_procedural_pos(*curves, cache.curves_cache, nullptr); + if (DRW_batch_requested(cache.edit_lines, GPU_PRIM_LINE_STRIP)) { + DRW_ibo_request(cache.edit_lines, &cache.edit_lines_ibo); + DRW_vbo_request(cache.edit_lines, &cache.edit_points_pos); + DRW_vbo_request(cache.edit_lines, &cache.edit_points_data); } - - if (DRW_vbo_requested(cache.curves_cache.data_edit_points)) { - curves_batch_cache_ensure_data_edit_points(*curves, cache.curves_cache); + if (DRW_vbo_requested(cache.edit_points_pos)) { + curves_batch_cache_ensure_edit_points_pos(*curves_orig, cache); + } + if (DRW_vbo_requested(cache.edit_points_data)) { + curves_batch_cache_ensure_edit_points_data(*curves_orig, cache); + } + if (DRW_ibo_requested(cache.edit_lines_ibo)) { + curves_batch_cache_ensure_edit_lines(*curves_orig, cache); } } diff --git a/source/blender/draw/intern/draw_curves_private.h b/source/blender/draw/intern/draw_curves_private.h index 715706fd7a6..36deca46e94 100644 --- a/source/blender/draw/intern/draw_curves_private.h +++ b/source/blender/draw/intern/draw_curves_private.h @@ -64,12 +64,9 @@ typedef struct CurvesEvalFinalCache { /* Curves procedural display: Evaluation is done on the GPU. */ typedef struct CurvesEvalCache { - /* Input control point positions combined with parameter data. */ + /* Control point positions on evaluated data-block combined with parameter data. */ GPUVertBuf *proc_point_buf; - /* Editmode data (such as selection flags) used by overlay_edit_curve_point.glsl */ - GPUVertBuf *data_edit_points; - /** Info of control points strands (segment count and base index) */ GPUVertBuf *proc_strand_buf; From 69d1ddd4c64056048a8d71fe7db5f878cefe4614 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 15 Dec 2022 10:25:06 +0100 Subject: [PATCH 0135/1522] Fix Cycles Light Tree UI after recent changes. --- intern/cycles/blender/addon/ui.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 4746790aae8..d45d7afb16f 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -395,9 +395,13 @@ class CYCLES_RENDER_PT_sampling_lights(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + scene = context.scene cscene = scene.cycles + col = layout.column(align=True) col.prop(cscene, "use_light_tree") sub = col.row() sub.prop(cscene, "light_sampling_threshold", text="Light Threshold") From ba347d7c9e4ae53d98cce1231fc919591b3c5d81 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Thu, 15 Dec 2022 10:44:56 +0100 Subject: [PATCH 0136/1522] Fix Cycles UI for Scrambling Distance, only works with Tabulated Sobol. Thanks to Alaska for finding this. --- intern/cycles/blender/addon/ui.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index d45d7afb16f..6ac97a32f61 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -370,7 +370,7 @@ class CYCLES_RENDER_PT_sampling_advanced(CyclesButtonsPanel, Panel): layout.separator() heading = layout.column(align=True, heading="Scrambling Distance") - heading.active = cscene.sampling_pattern != 'TABULATED_SOBOL' + heading.active = cscene.sampling_pattern == 'TABULATED_SOBOL' heading.prop(cscene, "auto_scrambling_distance", text="Automatic") heading.prop(cscene, "preview_scrambling_distance", text="Viewport") heading.prop(cscene, "scrambling_distance", text="Multiplier") From e0ef5f360222148d52e68d820df499dd6da5ce8a Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Thu, 15 Dec 2022 10:52:58 +0100 Subject: [PATCH 0137/1522] Fix T103234: GPencil applying armature does not work The problem was the bake function was using the evaluated data and must use the original data. The problem was caused by commit: rBcff6eb65804d: Cleanup: Remove duplicate Bake modifier code. Fix by Philipp Oeser --- source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c index d99d9950efb..5163f4d7020 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c @@ -118,14 +118,12 @@ static void bakeModifier(Main *UNUSED(bmain), GpencilModifierData *md, Object *ob) { - Object *object_eval = DEG_get_evaluated_object(depsgraph, ob); ArmatureGpencilModifierData *mmd = (ArmatureGpencilModifierData *)md; - GpencilModifierData *md_eval = BKE_gpencil_modifiers_findby_name(object_eval, md->name); if (mmd->object == NULL) { return; } - generic_bake_deform_stroke(depsgraph, md_eval, object_eval, true, deformStroke); + generic_bake_deform_stroke(depsgraph, md, ob, true, deformStroke); } static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams)) From 0e1440eefd98ef359ea83b465ada175364b1c4bf Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Thu, 15 Dec 2022 10:53:46 +0100 Subject: [PATCH 0138/1522] Paint: Orbit around selection/stroke: remove redundant case Since rB8014180720d8, all paint modes support orbiting around last stroke, so [a] the comment there is out of date and [b] the fallback case of orbiting around the center will never be used (unless there is no stroke information - but BKE_paint_stroke_get_average handles that anyways). Spotted while looking into T101766. Maniphest Tasks: T101766 Differential Revision: https://developer.blender.org/D16779 --- .../blender/editors/space_view3d/view3d_navigate.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_navigate.c b/source/blender/editors/space_view3d/view3d_navigate.c index 047b48a72d9..ed0225f578b 100644 --- a/source/blender/editors/space_view3d/view3d_navigate.c +++ b/source/blender/editors/space_view3d/view3d_navigate.c @@ -174,19 +174,7 @@ bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3]) if (ob_act && (ob_act->mode & OB_MODE_ALL_PAINT) && /* with weight-paint + pose-mode, fall through to using calculateTransformCenter */ ((ob_act->mode & OB_MODE_WEIGHT_PAINT) && BKE_object_pose_armature_get(ob_act)) == 0) { - /* in case of sculpting use last average stroke position as a rotation - * center, in other cases it's not clear what rotation center shall be - * so just rotate around object origin - */ - if (ob_act->mode & - (OB_MODE_SCULPT | OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) { - float stroke[3]; - BKE_paint_stroke_get_average(scene, ob_act_eval, stroke); - copy_v3_v3(lastofs, stroke); - } - else { - copy_v3_v3(lastofs, ob_act_eval->object_to_world[3]); - } + BKE_paint_stroke_get_average(scene, ob_act_eval, lastofs); is_set = true; } else if (ob_act && (ob_act->mode & OB_MODE_EDIT) && (ob_act->type == OB_FONT)) { From 9fe1db1d2b44854a6f98b2e213450fab34f8160a Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Thu, 15 Dec 2022 13:08:46 +0100 Subject: [PATCH 0139/1522] GPencil: Fix potential memory leak If the layer was omitted there was a memory leak. --- .../editors/gpencil/gpencil_interpolate.c | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c index d4d072d7580..ad0f1f0dc34 100644 --- a/source/blender/editors/gpencil/gpencil_interpolate.c +++ b/source/blender/editors/gpencil/gpencil_interpolate.c @@ -486,21 +486,20 @@ static void gpencil_interpolate_set_points(bContext *C, tGPDinterpolate *tgpi) continue; } - /* create temp data for each layer */ + bGPDframe *gpf_prv = gpencil_get_previous_keyframe(gpl, scene->r.cfra, exclude_breakdowns); + if (gpf_prv == NULL) { + continue; + } + bGPDframe *gpf_next = gpencil_get_next_keyframe(gpl, scene->r.cfra, exclude_breakdowns); + if (gpf_next == NULL) { + continue; + } + + /* Create temp data for each layer. */ tgpil = MEM_callocN(sizeof(tGPDinterpolate_layer), "GPencil Interpolate Layer"); - tgpil->gpl = gpl; - bGPDframe *gpf = gpencil_get_previous_keyframe(gpl, scene->r.cfra, exclude_breakdowns); - if (gpf == NULL) { - continue; - } - tgpil->prevFrame = BKE_gpencil_frame_duplicate(gpf, true); - - gpf = gpencil_get_next_keyframe(gpl, scene->r.cfra, exclude_breakdowns); - if (gpf == NULL) { - continue; - } - tgpil->nextFrame = BKE_gpencil_frame_duplicate(gpf, true); + tgpil->prevFrame = BKE_gpencil_frame_duplicate(gpf_prv, true); + tgpil->nextFrame = BKE_gpencil_frame_duplicate(gpf_next, true); BLI_addtail(&tgpi->ilayers, tgpil); From 51759e659579eb48181306ae1574d4dfdd4a4ed9 Mon Sep 17 00:00:00 2001 From: Nate Rupsis Date: Tue, 13 Dec 2022 08:09:08 -0500 Subject: [PATCH 0140/1522] Fix T101130: Scaling of NLA Strip Via S Hotkey Not Working After switching over to using start_frame / end_frame, scaling an NLA strip didn't scale the strip, it just repeated the action. Now withing the NLA transform code, we look for TFM_TIME_EXTEND / TFM_TIME_SCALE transform mode, and handle the update to strip scale accordingly --- source/blender/blenkernel/intern/nla.c | 20 ++++++++------ .../editors/transform/transform_convert_nla.c | 27 ++++++++++++++++++- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index ad8085be3d6..5cdfe98f2e0 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -973,21 +973,19 @@ void BKE_nlameta_flush_transforms(NlaStrip *mstrip) oEnd = ((NlaStrip *)mstrip->strips.last)->end; offset = mstrip->start - oStart; + /* check if scale changed */ + oLen = oEnd - oStart; + nLen = mstrip->end - mstrip->start; + scaleChanged = !IS_EQF(oLen, nLen); + /* optimization: * don't flush if nothing changed yet * TODO: maybe we need a flag to say always flush? */ - if (IS_EQF(oStart, mstrip->start) && IS_EQF(oEnd, mstrip->end)) { + if (IS_EQF(oStart, mstrip->start) && IS_EQF(oEnd, mstrip->end) && !scaleChanged) { return; } - /* check if scale changed */ - oLen = oEnd - oStart; - nLen = mstrip->end - mstrip->start; - if (IS_EQF(nLen, oLen) == 0) { - scaleChanged = 1; - } - /* for each child-strip, calculate new start/end points based on this new info */ for (strip = mstrip->strips.first; strip; strip = strip->next) { if (scaleChanged) { @@ -1001,6 +999,12 @@ void BKE_nlameta_flush_transforms(NlaStrip *mstrip) * then wait for second pass to flush scale properly. */ strip->start = (p1 * nLen) + mstrip->start; strip->end = (p2 * nLen) + mstrip->start; + + // Recompute the playback scale, given the new start & end frame of the strip. + const double action_len = strip->actend - strip->actstart; + const double repeated_len = action_len * strip->repeat; + const double strip_len = strip->end - strip->start; + strip->scale = strip_len / repeated_len; } else { /* just apply the changes in offset to both ends of the strip */ diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c index 830094ebe83..ab71fe42f07 100644 --- a/source/blender/editors/transform/transform_convert_nla.c +++ b/source/blender/editors/transform/transform_convert_nla.c @@ -76,6 +76,11 @@ static void applyTransformNLA_translation(PointerRNA *strip_rna_ptr, const Trans RNA_float_set(strip_rna_ptr, "frame_end", transdata->h2[0]); } +static void applyTransformNLA_timeScale(PointerRNA *strip_rna_ptr, const float value) +{ + RNA_float_set(strip_rna_ptr, "scale", value); +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -204,6 +209,7 @@ static void createTransNlaData(bContext *C, TransInfo *t) tdn->h1[1] = yval; tdn->h2[0] = strip->end; tdn->h2[1] = yval; + tdn->h1[2] = tdn->h2[2] = strip->scale; center[0] = (float)scene->r.cfra; center[1] = yval; @@ -333,6 +339,8 @@ static void recalcData_nla(TransInfo *t) strip->next->start = tdn->h2[0]; } + strip->scale = tdn->h1[2]; + /* flush transforms to child strips (since this should be a meta) */ BKE_nlameta_flush_transforms(strip); @@ -399,7 +407,24 @@ static void recalcData_nla(TransInfo *t) */ RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr); - applyTransformNLA_translation(&strip_ptr, tdn); + switch (t->mode) { + case TFM_TIME_EXTEND: + case TFM_TIME_SCALE: { + /* The final scale is the product of the original strip scale (from before the transform + * operation started) and the current scale value of this transform operation. */ + const float originalStripScale = tdn->h1[2]; + const float newStripScale = originalStripScale * t->values_final[0]; + applyTransformNLA_timeScale(&strip_ptr, newStripScale); + applyTransformNLA_translation(&strip_ptr, tdn); + break; + } + case TFM_TRANSLATION: + applyTransformNLA_translation(&strip_ptr, tdn); + break; + default: + printf("recalcData_nla: unsupported NLA transformation mode %d\n", t->mode); + continue; + } /* flush transforms to child strips (since this should be a meta) */ BKE_nlameta_flush_transforms(strip); From d2aebf10fae7bd6f0e854deea2c3c776bd5cde8c Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Thu, 15 Dec 2022 09:04:59 -0700 Subject: [PATCH 0141/1522] cmake/win: Allow running blender_test from the VS debugger This was missing some paths setup in the environment, ctest normally sets this up before running the tests from the CLI but that does not help the IDE all that much. --- tests/gtests/runner/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/gtests/runner/CMakeLists.txt b/tests/gtests/runner/CMakeLists.txt index be0aa65d409..eac76db22db 100644 --- a/tests/gtests/runner/CMakeLists.txt +++ b/tests/gtests/runner/CMakeLists.txt @@ -43,6 +43,7 @@ if(WIN32) target_link_libraries(blender_test ${_lib}) target_link_options(blender_test PRIVATE /wholearchive:$) endforeach() + set_target_properties(blender_test PROPERTIES VS_DEBUGGER_ENVIRONMENT "${PLATFORM_ENV_INSTALL};$") elseif(APPLE) # force_load for `_test_libs` ensures that all symbols definitely make it into the test binary. # But linking against them again using `target_link_libraries` creates duplicate symbol From bd04e80c09f00eac05a7f5d8d0cf6732ae245763 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 14 Dec 2022 19:12:17 -0600 Subject: [PATCH 0142/1522] Cleanup: Move mesh modifier apply function to editors module The function was highly related to the apply modifier operator, and only used once. This was too specific to be in the blenkernel, especially in a mesh conversion file. --- source/blender/blenkernel/BKE_mesh.h | 12 -- .../blender/blenkernel/intern/mesh_convert.cc | 136 --------------- .../blender/editors/object/object_modifier.cc | 155 ++++++++++++++++-- 3 files changed, 140 insertions(+), 163 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 6a55fe00bf6..472c82c3a81 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -279,18 +279,6 @@ struct Mesh *BKE_mesh_new_from_object_to_bmain(struct Main *bmain, struct Object *object, bool preserve_all_data_layers); -/** - * \param use_virtual_modifiers: When enabled calculate virtual-modifiers before applying `md_eval` - * support this since virtual-modifiers are not modifiers from a user perspective, - * allowing shape keys to be included with the modifier being applied, see: T91923. - */ -struct Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph, - struct Scene *scene, - struct Object *ob_eval, - struct ModifierData *md_eval, - bool use_virtual_modifiers, - bool build_shapekey_layers); - /** * Move data from a mesh outside of the main data-base into a mesh in the data-base. * Takes ownership of the source mesh. diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index fd2bb67c648..7a4c3c0834b 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -1102,142 +1102,6 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain, return mesh_in_bmain; } -static void add_shapekey_layers(Mesh *mesh_dest, Mesh *mesh_src) -{ - KeyBlock *kb; - Key *key = mesh_src->key; - int i; - - if (!mesh_src->key) { - return; - } - - /* ensure we can use mesh vertex count for derived mesh custom data */ - if (mesh_src->totvert != mesh_dest->totvert) { - CLOG_ERROR(&LOG, - "vertex size mismatch (mesh/dm) '%s' (%d != %d)", - mesh_src->id.name + 2, - mesh_src->totvert, - mesh_dest->totvert); - return; - } - - for (i = 0, kb = (KeyBlock *)key->block.first; kb; kb = kb->next, i++) { - int ci; - float *array; - - if (mesh_src->totvert != kb->totelem) { - CLOG_ERROR(&LOG, - "vertex size mismatch (Mesh '%s':%d != KeyBlock '%s':%d)", - mesh_src->id.name + 2, - mesh_src->totvert, - kb->name, - kb->totelem); - array = (float *)MEM_calloc_arrayN(size_t(mesh_src->totvert), sizeof(float[3]), __func__); - } - else { - array = (float *)MEM_malloc_arrayN(size_t(mesh_src->totvert), sizeof(float[3]), __func__); - memcpy(array, kb->data, sizeof(float[3]) * size_t(mesh_src->totvert)); - } - - CustomData_add_layer_named( - &mesh_dest->vdata, CD_SHAPEKEY, CD_ASSIGN, array, mesh_dest->totvert, kb->name); - ci = CustomData_get_layer_index_n(&mesh_dest->vdata, CD_SHAPEKEY, i); - - mesh_dest->vdata.layers[ci].uid = kb->uid; - } -} - -Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph, - Scene *scene, - Object *ob_eval, - ModifierData *md_eval, - const bool use_virtual_modifiers, - const bool build_shapekey_layers) -{ - Mesh *me = ob_eval->runtime.data_orig ? (Mesh *)ob_eval->runtime.data_orig : - (Mesh *)ob_eval->data; - const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md_eval->type); - Mesh *result = nullptr; - KeyBlock *kb; - ModifierEvalContext mectx = {depsgraph, ob_eval, MOD_APPLY_TO_BASE_MESH}; - - if (!(md_eval->mode & eModifierMode_Realtime)) { - return result; - } - - if (mti->isDisabled && mti->isDisabled(scene, md_eval, false)) { - return result; - } - - if (build_shapekey_layers && me->key && - (kb = (KeyBlock *)BLI_findlink(&me->key->block, ob_eval->shapenr - 1))) { - MutableSpan verts = me->verts_for_write(); - BKE_keyblock_convert_to_mesh(kb, verts.data(), me->totvert); - } - - Mesh *mesh_temp = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE); - int numVerts = 0; - float(*deformedVerts)[3] = nullptr; - - if (use_virtual_modifiers) { - VirtualModifierData virtualModifierData; - for (ModifierData *md_eval_virt = - BKE_modifiers_get_virtual_modifierlist(ob_eval, &virtualModifierData); - md_eval_virt && (md_eval_virt != ob_eval->modifiers.first); - md_eval_virt = md_eval_virt->next) { - if (!BKE_modifier_is_enabled(scene, md_eval_virt, eModifierMode_Realtime)) { - continue; - } - /* All virtual modifiers are deform modifiers. */ - const ModifierTypeInfo *mti_virt = BKE_modifier_get_info((ModifierType)md_eval_virt->type); - BLI_assert(mti_virt->type == eModifierTypeType_OnlyDeform); - if (mti_virt->type != eModifierTypeType_OnlyDeform) { - continue; - } - - if (deformedVerts == nullptr) { - deformedVerts = BKE_mesh_vert_coords_alloc(me, &numVerts); - } - mti_virt->deformVerts(md_eval_virt, &mectx, mesh_temp, deformedVerts, numVerts); - } - } - - if (mti->type == eModifierTypeType_OnlyDeform) { - if (deformedVerts == nullptr) { - deformedVerts = BKE_mesh_vert_coords_alloc(me, &numVerts); - } - result = mesh_temp; - mti->deformVerts(md_eval, &mectx, result, deformedVerts, numVerts); - BKE_mesh_vert_coords_apply(result, deformedVerts); - - if (build_shapekey_layers) { - add_shapekey_layers(result, me); - } - } - else { - if (deformedVerts != nullptr) { - BKE_mesh_vert_coords_apply(mesh_temp, deformedVerts); - } - - if (build_shapekey_layers) { - add_shapekey_layers(mesh_temp, me); - } - - result = mti->modifyMesh(md_eval, &mectx, mesh_temp); - ASSERT_IS_VALID_MESH(result); - - if (mesh_temp != result) { - BKE_id_free(nullptr, mesh_temp); - } - } - - if (deformedVerts != nullptr) { - MEM_freeN(deformedVerts); - } - - return result; -} static KeyBlock *keyblock_ensure_from_uid(Key &key, const int uid, const StringRefNull name) { diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 3a239506cb3..28010b7c608 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -9,6 +9,8 @@ #include #include +#include "CLG_log.h" + #include "MEM_guardedalloc.h" #include "DNA_anim_types.h" @@ -95,6 +97,8 @@ using blender::Span; +static CLG_LogRef LOG = {"ed.object"}; + static void modifier_skin_customdata_delete(struct Object *ob); /* ------------------------------------------------------------------- */ @@ -650,18 +654,134 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList * /*reports*/, return true; } -/* Gets mesh for the modifier which corresponds to an evaluated state. */ -static Mesh *modifier_apply_create_mesh_for_modifier(Depsgraph *depsgraph, - Object *object, - ModifierData *md_eval, - bool use_virtual_modifiers, - bool build_shapekey_layers) +static void add_shapekey_layers(Mesh *mesh_dest, Mesh *mesh_src) { - Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); - Object *object_eval = DEG_get_evaluated_object(depsgraph, object); - Mesh *mesh_applied = BKE_mesh_create_derived_for_modifier( - depsgraph, scene_eval, object_eval, md_eval, use_virtual_modifiers, build_shapekey_layers); - return mesh_applied; + KeyBlock *kb; + Key *key = mesh_src->key; + int i; + + if (!mesh_src->key) { + return; + } + + for (i = 0, kb = (KeyBlock *)key->block.first; kb; kb = kb->next, i++) { + int ci; + float *array; + + if (mesh_src->totvert != kb->totelem) { + CLOG_ERROR(&LOG, + "vertex size mismatch (Mesh '%s':%d != KeyBlock '%s':%d)", + mesh_src->id.name + 2, + mesh_src->totvert, + kb->name, + kb->totelem); + array = (float *)MEM_calloc_arrayN(size_t(mesh_src->totvert), sizeof(float[3]), __func__); + } + else { + array = (float *)MEM_malloc_arrayN(size_t(mesh_src->totvert), sizeof(float[3]), __func__); + memcpy(array, kb->data, sizeof(float[3]) * size_t(mesh_src->totvert)); + } + + CustomData_add_layer_named( + &mesh_dest->vdata, CD_SHAPEKEY, CD_ASSIGN, array, mesh_dest->totvert, kb->name); + ci = CustomData_get_layer_index_n(&mesh_dest->vdata, CD_SHAPEKEY, i); + + mesh_dest->vdata.layers[ci].uid = kb->uid; + } +} + +/** + * \param use_virtual_modifiers: When enabled, calculate virtual-modifiers before applying + * `md_eval`. This is supported because virtual-modifiers are not modifiers from a user + * perspective, allowing shape keys to be included with the modifier being applied, see: T91923. + */ +static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph, + Scene *scene, + Object *ob_eval, + ModifierData *md_eval, + const bool use_virtual_modifiers, + const bool build_shapekey_layers) +{ + Mesh *me = ob_eval->runtime.data_orig ? (Mesh *)ob_eval->runtime.data_orig : + (Mesh *)ob_eval->data; + const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md_eval->type); + Mesh *result = nullptr; + KeyBlock *kb; + ModifierEvalContext mectx = {depsgraph, ob_eval, MOD_APPLY_TO_BASE_MESH}; + + if (!(md_eval->mode & eModifierMode_Realtime)) { + return result; + } + + if (mti->isDisabled && mti->isDisabled(scene, md_eval, false)) { + return result; + } + + if (build_shapekey_layers && me->key && + (kb = (KeyBlock *)BLI_findlink(&me->key->block, ob_eval->shapenr - 1))) { + BKE_keyblock_convert_to_mesh(kb, me->verts_for_write().data(), me->totvert); + } + + Mesh *mesh_temp = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE); + int numVerts = 0; + float(*deformedVerts)[3] = nullptr; + + if (use_virtual_modifiers) { + VirtualModifierData virtualModifierData; + for (ModifierData *md_eval_virt = + BKE_modifiers_get_virtual_modifierlist(ob_eval, &virtualModifierData); + md_eval_virt && (md_eval_virt != ob_eval->modifiers.first); + md_eval_virt = md_eval_virt->next) { + if (!BKE_modifier_is_enabled(scene, md_eval_virt, eModifierMode_Realtime)) { + continue; + } + /* All virtual modifiers are deform modifiers. */ + const ModifierTypeInfo *mti_virt = BKE_modifier_get_info((ModifierType)md_eval_virt->type); + BLI_assert(mti_virt->type == eModifierTypeType_OnlyDeform); + if (mti_virt->type != eModifierTypeType_OnlyDeform) { + continue; + } + + if (deformedVerts == nullptr) { + deformedVerts = BKE_mesh_vert_coords_alloc(me, &numVerts); + } + mti_virt->deformVerts(md_eval_virt, &mectx, mesh_temp, deformedVerts, numVerts); + } + } + + if (mti->type == eModifierTypeType_OnlyDeform) { + if (deformedVerts == nullptr) { + deformedVerts = BKE_mesh_vert_coords_alloc(me, &numVerts); + } + result = mesh_temp; + mti->deformVerts(md_eval, &mectx, result, deformedVerts, numVerts); + BKE_mesh_vert_coords_apply(result, deformedVerts); + + if (build_shapekey_layers) { + add_shapekey_layers(result, me); + } + } + else { + if (deformedVerts != nullptr) { + BKE_mesh_vert_coords_apply(mesh_temp, deformedVerts); + } + + if (build_shapekey_layers) { + add_shapekey_layers(mesh_temp, me); + } + + result = mti->modifyMesh(md_eval, &mectx, mesh_temp); + + if (mesh_temp != result) { + BKE_id_free(nullptr, mesh_temp); + } + } + + if (deformedVerts != nullptr) { + MEM_freeN(deformedVerts); + } + + return result; } static bool modifier_apply_shape(Main *bmain, @@ -697,8 +817,12 @@ static bool modifier_apply_shape(Main *bmain, return false; } - Mesh *mesh_applied = modifier_apply_create_mesh_for_modifier( - depsgraph, ob, md_eval, true, false); + Mesh *mesh_applied = create_applied_mesh_for_modifier(depsgraph, + DEG_get_evaluated_scene(depsgraph), + DEG_get_evaluated_object(depsgraph, ob), + md_eval, + true, + false); if (!mesh_applied) { BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply"); return false; @@ -756,9 +880,10 @@ static bool modifier_apply_obdata( } } else { - Mesh *mesh_applied = modifier_apply_create_mesh_for_modifier( + Mesh *mesh_applied = create_applied_mesh_for_modifier( depsgraph, - ob, + DEG_get_evaluated_scene(depsgraph), + DEG_get_evaluated_object(depsgraph, ob), md_eval, /* It's important not to apply virtual modifiers (e.g. shape-keys) because they're kept, * causing them to be applied twice, see: T97758. */ From 970f4c2f9f0e9cda6fa61f9ddf6da12d6bb91f2a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 14 Dec 2022 19:24:34 -0600 Subject: [PATCH 0143/1522] Cleanup: Various improvements to modifier apply operator Use C++ casts, decrease variable scope, use references, use const. --- .../blender/editors/object/object_modifier.cc | 67 +++++++++---------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 28010b7c608..2fa37f205ab 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -654,39 +654,33 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList * /*reports*/, return true; } -static void add_shapekey_layers(Mesh *mesh_dest, Mesh *mesh_src) +static void add_shapekey_layers(Mesh &mesh_dest, const Mesh &mesh_src) { - KeyBlock *kb; - Key *key = mesh_src->key; - int i; - - if (!mesh_src->key) { + if (!mesh_src.key) { return; } - - for (i = 0, kb = (KeyBlock *)key->block.first; kb; kb = kb->next, i++) { - int ci; - float *array; - - if (mesh_src->totvert != kb->totelem) { + int i; + LISTBASE_FOREACH_INDEX (const KeyBlock *, kb, &mesh_src.key->block, i) { + void *array; + if (mesh_src.totvert != kb->totelem) { CLOG_ERROR(&LOG, "vertex size mismatch (Mesh '%s':%d != KeyBlock '%s':%d)", - mesh_src->id.name + 2, - mesh_src->totvert, + mesh_src.id.name + 2, + mesh_src.totvert, kb->name, kb->totelem); - array = (float *)MEM_calloc_arrayN(size_t(mesh_src->totvert), sizeof(float[3]), __func__); + array = MEM_calloc_arrayN(size_t(mesh_src.totvert), sizeof(float[3]), __func__); } else { - array = (float *)MEM_malloc_arrayN(size_t(mesh_src->totvert), sizeof(float[3]), __func__); - memcpy(array, kb->data, sizeof(float[3]) * size_t(mesh_src->totvert)); + array = MEM_malloc_arrayN(size_t(mesh_src.totvert), sizeof(float[3]), __func__); + memcpy(array, kb->data, sizeof(float[3]) * size_t(mesh_src.totvert)); } CustomData_add_layer_named( - &mesh_dest->vdata, CD_SHAPEKEY, CD_ASSIGN, array, mesh_dest->totvert, kb->name); - ci = CustomData_get_layer_index_n(&mesh_dest->vdata, CD_SHAPEKEY, i); + &mesh_dest.vdata, CD_SHAPEKEY, CD_ASSIGN, array, mesh_dest.totvert, kb->name); + const int ci = CustomData_get_layer_index_n(&mesh_dest.vdata, CD_SHAPEKEY, i); - mesh_dest->vdata.layers[ci].uid = kb->uid; + mesh_dest.vdata.layers[ci].uid = kb->uid; } } @@ -702,27 +696,28 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph, const bool use_virtual_modifiers, const bool build_shapekey_layers) { - Mesh *me = ob_eval->runtime.data_orig ? (Mesh *)ob_eval->runtime.data_orig : - (Mesh *)ob_eval->data; - const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md_eval->type); - Mesh *result = nullptr; - KeyBlock *kb; - ModifierEvalContext mectx = {depsgraph, ob_eval, MOD_APPLY_TO_BASE_MESH}; + Mesh *me = ob_eval->runtime.data_orig ? reinterpret_cast(ob_eval->runtime.data_orig) : + reinterpret_cast(ob_eval->data); + const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md_eval->type)); + const ModifierEvalContext mectx = {depsgraph, ob_eval, MOD_APPLY_TO_BASE_MESH}; if (!(md_eval->mode & eModifierMode_Realtime)) { - return result; + return nullptr; } if (mti->isDisabled && mti->isDisabled(scene, md_eval, false)) { - return result; + return nullptr; } - if (build_shapekey_layers && me->key && - (kb = (KeyBlock *)BLI_findlink(&me->key->block, ob_eval->shapenr - 1))) { - BKE_keyblock_convert_to_mesh(kb, me->verts_for_write().data(), me->totvert); + if (build_shapekey_layers && me->key) { + if (KeyBlock *kb = static_cast( + BLI_findlink(&me->key->block, ob_eval->shapenr - 1))) { + BKE_keyblock_convert_to_mesh(kb, me->verts_for_write().data(), me->totvert); + } } - Mesh *mesh_temp = (Mesh *)BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE); + Mesh *mesh_temp = reinterpret_cast( + BKE_id_copy_ex(nullptr, &me->id, nullptr, LIB_ID_COPY_LOCALIZE)); int numVerts = 0; float(*deformedVerts)[3] = nullptr; @@ -736,7 +731,7 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph, continue; } /* All virtual modifiers are deform modifiers. */ - const ModifierTypeInfo *mti_virt = BKE_modifier_get_info((ModifierType)md_eval_virt->type); + const ModifierTypeInfo *mti_virt = BKE_modifier_get_info(ModifierType(md_eval_virt->type)); BLI_assert(mti_virt->type == eModifierTypeType_OnlyDeform); if (mti_virt->type != eModifierTypeType_OnlyDeform) { continue; @@ -749,6 +744,7 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph, } } + Mesh *result = nullptr; if (mti->type == eModifierTypeType_OnlyDeform) { if (deformedVerts == nullptr) { deformedVerts = BKE_mesh_vert_coords_alloc(me, &numVerts); @@ -758,7 +754,7 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph, BKE_mesh_vert_coords_apply(result, deformedVerts); if (build_shapekey_layers) { - add_shapekey_layers(result, me); + add_shapekey_layers(*result, *me); } } else { @@ -767,11 +763,10 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph, } if (build_shapekey_layers) { - add_shapekey_layers(mesh_temp, me); + add_shapekey_layers(*mesh_temp, *me); } result = mti->modifyMesh(md_eval, &mectx, mesh_temp); - if (mesh_temp != result) { BKE_id_free(nullptr, mesh_temp); } From 6546113f1ed237029a1c37502908d31cc39f9e87 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 15 Dec 2022 17:30:40 +0100 Subject: [PATCH 0144/1522] Cleanup: fix warning --- source/blender/blenkernel/intern/mesh.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 77ef4674596..16858a70a0c 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -725,7 +725,7 @@ static int customdata_compare( } } if (!found_corresponding_layer) { - if ((1 << l1->type) & CD_MASK_PROP_ALL) { + if ((uint64_t(1) << l1->type) & CD_MASK_PROP_ALL) { return MESHCMP_CDLAYERS_MISMATCH; } } From c6ff8eb837ae91d3fc0b9f9fc3646d6601f096fb Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 15 Dec 2022 15:10:09 +0100 Subject: [PATCH 0145/1522] Fix build issue with NanoVDB and HIP on Linux This patch was already accepted upstream, so this is temporary until we update to a new OpenVDB release that includes it. --- .../build_environment/patches/openvdb.diff | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/build_files/build_environment/patches/openvdb.diff b/build_files/build_environment/patches/openvdb.diff index 9896460c26c..d3f19985815 100644 --- a/build_files/build_environment/patches/openvdb.diff +++ b/build_files/build_environment/patches/openvdb.diff @@ -90,3 +90,25 @@ diff -Naur orig/openvdb/openvdb/tree/ValueAccessor.h openvdb/openvdb/openvdb/tre CacheItem(TreeCacheT& parent) : mParent(&parent) +diff --git a/nanovdb/nanovdb/NanoVDB.h b/nanovdb/nanovdb/NanoVDB.h +index f7fc304..fde5c47 100644 +--- a/nanovdb/nanovdb/NanoVDB.h ++++ b/nanovdb/nanovdb/NanoVDB.h +@@ -1877,7 +1877,7 @@ __hostdev__ static inline uint32_t FindLowestOn(uint64_t v) + { + NANOVDB_ASSERT(v); + #if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS) +- return __ffsll(v); ++ return __ffsll(static_cast(v)); + #elif defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS) + unsigned long index; + _BitScanForward64(&index, v); +@@ -2592,7 +2592,7 @@ public: + /// + /// @note This method is only defined for IndexGrid = NanoGrid + template +- __hostdev__ typename enable_if::value, uint64_t>::type valueCount() const {return DataType::mData1;} ++ __hostdev__ typename enable_if::value, const uint64_t&>::type valueCount() const {return DataType::mData1;} + + /// @brief Return a const reference to the tree + __hostdev__ const TreeT& tree() const { return *reinterpret_cast(this->treePtr()); } From 62f8d0d8c84e96e94fc580b7482e46298bfef822 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 15 Dec 2022 19:13:55 +0100 Subject: [PATCH 0146/1522] Fix T103170: missing Cycles viewport light threshold update after exposure edit --- intern/cycles/scene/scene.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/intern/cycles/scene/scene.cpp b/intern/cycles/scene/scene.cpp index db96af19530..e4552713a9d 100644 --- a/intern/cycles/scene/scene.cpp +++ b/intern/cycles/scene/scene.cpp @@ -257,6 +257,9 @@ void Scene::device_update(Device *device_, Progress &progress) light_manager->tag_update(this, ccl::LightManager::LIGHT_MODIFIED); object_manager->tag_update(this, ccl::ObjectManager::OBJECT_MODIFIED); } + if (film->exposure_is_modified()) { + integrator->tag_modified(); + } progress.set_status("Updating Shaders"); shader_manager->device_update(device, &dscene, this, progress); From ef35247ee1e16bab802cc5ee2a06ae1ea2b159a1 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 15 Dec 2022 19:17:36 +0100 Subject: [PATCH 0147/1522] Fix make deps harvest error on Linux, due to macOS specific folder in Vulkan --- build_files/build_environment/cmake/harvest.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index 60d633c0ca9..252e52361c5 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -271,7 +271,9 @@ harvest(zstd/lib zstd/lib "*.a") harvest(shaderc shaderc "*") harvest(vulkan_headers vulkan "*") harvest_rpath_lib(vulkan_loader/lib vulkan/lib "*${SHAREDLIBEXT}*") -harvest(vulkan_loader/loader vulkan/loader "*") +if(APPLE) + harvest(vulkan_loader/loader vulkan/loader "*") +endif() if(UNIX AND NOT APPLE) harvest(libglu/lib mesa/lib "*${SHAREDLIBEXT}*") From 7608ebe44aa343f40f1d79f719097111eaa0c722 Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Thu, 15 Dec 2022 19:32:30 +0100 Subject: [PATCH 0148/1522] Fix: ignore unavailable sockets linked to multi-input socket Differential Revision: https://developer.blender.org/D16784 --- .../blender/nodes/intern/geometry_nodes_lazy_function.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index cad92cc0d90..9b89d056675 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -1141,10 +1141,11 @@ struct GeometryNodesLazyFunctionGraphBuilder { if (multi_input_link == link) { break; } - if (!(multi_input_link->is_muted() || - nodeIsDanglingReroute(&btree_, multi_input_link->fromnode))) { - link_index++; + if (multi_input_link->is_muted() || !multi_input_link->fromsock->is_available() || + nodeIsDanglingReroute(&btree_, multi_input_link->fromnode)) { + continue; } + link_index++; } if (to_bsocket.owner_node().is_muted()) { if (link_index == 0) { From ae886596a0f1a22037232eabe4ae0cde171951c6 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 15 Dec 2022 14:03:28 -0600 Subject: [PATCH 0149/1522] Nodes: Allow skipping node attachment after dragging This patch allows skipping the automatic insertion of nodes on top of links when the transform operator ends. When putting nodes into small spaces this often gets in the way and wastes time. Now, when holding `alt`, this is turned off. The header text is also improved to add this shortcut and to remove the Dx and Dy values and improve the formatting a bit. Making this functionality optional might allow us to use it in more places in the future, like for the nodes added by link-drag-search. Differential Revision: https://developer.blender.org/D16230 --- .../keyconfig/keymap_data/blender_default.py | 2 + .../keymap_data/industry_compatible_data.py | 2 + source/blender/editors/transform/transform.c | 38 ++++++++- source/blender/editors/transform/transform.h | 7 +- .../transform/transform_convert_node.cc | 18 ++++- .../transform/transform_mode_translate.c | 79 ++++++++++--------- 6 files changed, 101 insertions(+), 45 deletions(-) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 4c5969d4f0d..e6b8cc12b29 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5779,6 +5779,8 @@ def km_transform_modal_map(_params): ("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None), ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None), ("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None), + ("NODE_ATTACH_ON", {"type": 'LEFT_ALT', "value": 'RELEASE', "any": True}, None), + ("NODE_ATTACH_OFF", {"type": 'LEFT_ALT', "value": 'PRESS', "any": True}, None), ("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, None), ("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True}, None), ("PRECISION", {"type": 'LEFT_SHIFT', "value": 'ANY', "any": True}, None), diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index f7929005e06..2f15d908364 100644 --- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -3996,6 +3996,8 @@ def km_transform_modal_map(_params): ("AUTOIK_CHAIN_LEN_UP", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "shift": True}, None), ("AUTOIK_CHAIN_LEN_DOWN", {"type": 'WHEELUPMOUSE', "value": 'PRESS', "shift": True}, None), ("INSERTOFS_TOGGLE_DIR", {"type": 'T', "value": 'PRESS'}, None), + ("NODE_ATTACH_ON", {"type": 'LEFT_ALT', "value": 'RELEASE', "any": True}, None), + ("NODE_ATTACH_OFF", {"type": 'LEFT_ALT', "value": 'PRESS', "any": True}, None), ("AUTOCONSTRAIN", {"type": 'MIDDLEMOUSE', "value": 'ANY'}, None), ("AUTOCONSTRAINPLANE", {"type": 'MIDDLEMOUSE', "value": 'ANY', "shift": True}, None), ("PRECISION", {"type": 'LEFT_SHIFT', "value": 'ANY', "any": True}, None), diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index b8b4cf796f4..cdbd85e85a1 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -599,7 +599,9 @@ static bool transform_modal_item_poll(const wmOperator *op, int value) } break; } - case TFM_MODAL_INSERTOFS_TOGGLE_DIR: { + case TFM_MODAL_INSERTOFS_TOGGLE_DIR: + case TFM_MODAL_NODE_ATTACH_ON: + case TFM_MODAL_NODE_ATTACH_OFF: { if (t->spacetype != SPACE_NODE) { return false; } @@ -661,6 +663,8 @@ wmKeyMap *transform_modal_keymap(wmKeyConfig *keyconf) 0, "Toggle Direction for Node Auto-Offset", ""}, + {TFM_MODAL_NODE_ATTACH_ON, "NODE_ATTACH_ON", 0, "Node Attachment", ""}, + {TFM_MODAL_NODE_ATTACH_OFF, "NODE_ATTACH_OFF", 0, "Node Attachment (Off)", ""}, {TFM_MODAL_TRANSLATE, "TRANSLATE", 0, "Move", ""}, {TFM_MODAL_ROTATE, "ROTATE", 0, "Rotate", ""}, {TFM_MODAL_RESIZE, "RESIZE", 0, "Resize", ""}, @@ -1112,6 +1116,17 @@ int transformEvent(TransInfo *t, const wmEvent *event) t->redraw |= TREDRAW_SOFT; } break; + case TFM_MODAL_NODE_ATTACH_ON: + t->modifiers |= MOD_NODE_ATTACH; + t->redraw |= TREDRAW_HARD; + handled = true; + break; + case TFM_MODAL_NODE_ATTACH_OFF: + t->modifiers &= ~MOD_NODE_ATTACH; + t->redraw |= TREDRAW_HARD; + handled = true; + break; + case TFM_MODAL_AUTOCONSTRAINT: case TFM_MODAL_AUTOCONSTRAINTPLANE: if ((t->flag & T_RELEASE_CONFIRM) && (event->prev_val == KM_RELEASE) && @@ -1857,6 +1872,27 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } } } + if (t->data_type == &TransConvertType_Node) { + /* Set the initial auto-attach flag based on whether the chosen keymap key is pressed at the + * start of the operator. */ + t->modifiers |= MOD_NODE_ATTACH; + LISTBASE_FOREACH (const wmKeyMapItem *, kmi, &t->keymap->items) { + if (kmi->flag & KMI_INACTIVE) { + continue; + } + + if (kmi->propvalue == TFM_MODAL_NODE_ATTACH_OFF && kmi->val == KM_PRESS) { + if ((ELEM(kmi->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY) && (event->modifier & KM_CTRL)) || + (ELEM(kmi->type, EVT_LEFTSHIFTKEY, EVT_RIGHTSHIFTKEY) && + (event->modifier & KM_SHIFT)) || + (ELEM(kmi->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY) && (event->modifier & KM_ALT)) || + ((kmi->type == EVT_OSKEY) && (event->modifier & KM_OSKEY))) { + t->modifiers &= ~MOD_NODE_ATTACH; + } + break; + } + } + } initSnapping(t, op); /* Initialize snapping data AFTER mode flags */ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 206c1830617..29df931e136 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -152,8 +152,9 @@ typedef enum { MOD_SNAP = 1 << 2, MOD_SNAP_INVERT = 1 << 3, MOD_CONSTRAINT_SELECT_PLANE = 1 << 4, + MOD_NODE_ATTACH = 1 << 5, } eTModifier; -ENUM_OPERATORS(eTModifier, MOD_CONSTRAINT_SELECT_PLANE) +ENUM_OPERATORS(eTModifier, MOD_NODE_ATTACH) /** #TransSnap.status */ typedef enum eTSnap { @@ -244,8 +245,8 @@ enum { TFM_MODAL_AUTOIK_LEN_INC = 22, TFM_MODAL_AUTOIK_LEN_DEC = 23, - // TFM_MODAL_UNUSED_1 = 24, - // TFM_MODAL_UNUSED_2 = 25, + TFM_MODAL_NODE_ATTACH_ON = 24, + TFM_MODAL_NODE_ATTACH_OFF = 25, /** For analog input, like track-pad. */ TFM_MODAL_PROPSIZE = 26, diff --git a/source/blender/editors/transform/transform_convert_node.cc b/source/blender/editors/transform/transform_convert_node.cc index f07baa09e8c..ea89d50a86d 100644 --- a/source/blender/editors/transform/transform_convert_node.cc +++ b/source/blender/editors/transform/transform_convert_node.cc @@ -116,6 +116,13 @@ static void createTransNodeData(bContext * /*C*/, TransInfo *t) NODE_EDGE_PAN_ZOOM_INFLUENCE); customdata->viewrect_prev = customdata->edgepan_data.initial_rect; + if (t->modifiers & MOD_NODE_ATTACH) { + space_node::node_insert_on_link_flags_set(*snode, *t->region); + } + else { + space_node::node_insert_on_link_flags_clear(*snode->edittree); + } + t->custom.type.data = customdata; t->custom.type.use_free = true; @@ -245,7 +252,12 @@ static void flushTransNodes(TransInfo *t) /* handle intersection with noodles */ if (tc->data_len == 1) { - space_node::node_insert_on_link_flags_set(*snode, *t->region); + if (t->modifiers & MOD_NODE_ATTACH) { + space_node::node_insert_on_link_flags_set(*snode, *t->region); + } + else { + space_node::node_insert_on_link_flags_clear(*snode->edittree); + } } } } @@ -279,7 +291,9 @@ static void special_aftertrans_update__node(bContext *C, TransInfo *t) if (!canceled) { ED_node_post_apply_transform(C, snode->edittree); - space_node::node_insert_on_link_flags(*bmain, *snode); + if (t->modifiers & MOD_NODE_ATTACH) { + space_node::node_insert_on_link_flags(*bmain, *snode); + } } space_node::node_insert_on_link_flags_clear(*ntree); diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index 59d34c3918b..ce82c788dfe 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -296,47 +296,48 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_ } } else { - if (t->flag & T_2D_EDIT) { - ofs += BLI_snprintf_rlen(str + ofs, - UI_MAX_DRAW_STR - ofs, - "Dx: %s Dy: %s (%s)%s", - dvec_str[0], - dvec_str[1], - dist_str, - t->con.text); + if (t->spacetype == SPACE_NODE) { + SpaceNode *snode = (SpaceNode *)t->area->spacedata.first; + if ((snode->flag & SNODE_SKIP_INSOFFSET) == 0) { + const char *str_dir = (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_RIGHT) ? + TIP_("right") : + TIP_("left"); + char str_dir_km[64]; + WM_modalkeymap_items_to_string( + t->keymap, TFM_MODAL_INSERTOFS_TOGGLE_DIR, true, str_dir_km, sizeof(str_dir_km)); + ofs += BLI_snprintf_rlen(str, + UI_MAX_DRAW_STR, + TIP_("%s: Toggle auto-offset direction (%s)"), + str_dir_km, + str_dir); + } + + char str_attach_km[64]; + WM_modalkeymap_items_to_string( + t->keymap, TFM_MODAL_NODE_ATTACH_OFF, true, str_attach_km, sizeof(str_attach_km)); + ofs += BLI_snprintf_rlen( + str + ofs, UI_MAX_DRAW_STR - ofs, TIP_(", %s: Toggle auto-attach"), str_attach_km); } else { - ofs += BLI_snprintf_rlen(str + ofs, - UI_MAX_DRAW_STR - ofs, - "Dx: %s Dy: %s Dz: %s (%s)%s", - dvec_str[0], - dvec_str[1], - dvec_str[2], - dist_str, - t->con.text); - } - } - - if (t->spacetype == SPACE_NODE) { - SpaceNode *snode = (SpaceNode *)t->area->spacedata.first; - - if ((snode->flag & SNODE_SKIP_INSOFFSET) == 0) { - const char *str_old = BLI_strdup(str); - const char *str_dir = (snode->insert_ofs_dir == SNODE_INSERTOFS_DIR_RIGHT) ? TIP_("right") : - TIP_("left"); - char str_km[64]; - - WM_modalkeymap_items_to_string( - t->keymap, TFM_MODAL_INSERTOFS_TOGGLE_DIR, true, str_km, sizeof(str_km)); - - ofs += BLI_snprintf_rlen(str, - UI_MAX_DRAW_STR, - TIP_("Auto-offset set to %s - press %s to toggle direction | %s"), - str_dir, - str_km, - str_old); - - MEM_freeN((void *)str_old); + if (t->flag & T_2D_EDIT) { + ofs += BLI_snprintf_rlen(str + ofs, + UI_MAX_DRAW_STR - ofs, + "Dx: %s Dy: %s (%s)%s", + dvec_str[0], + dvec_str[1], + dist_str, + t->con.text); + } + else { + ofs += BLI_snprintf_rlen(str + ofs, + UI_MAX_DRAW_STR - ofs, + "Dx: %s Dy: %s Dz: %s (%s)%s", + dvec_str[0], + dvec_str[1], + dvec_str[2], + dist_str, + t->con.text); + } } } } From b1494bcea7b6bb6088c5ad245889fa687ed23699 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 15 Dec 2022 14:05:01 -0600 Subject: [PATCH 0150/1522] Geometry Nodes: Add error message when applying modifier with no mesh If the resulting geometry from applying a geometry nodes modifier contains no mesh, give an error message. This gives people something to search and makes the behavior more purposeful. Also remove the `modifyMesh` implementation from the geometry nodes modifier, since it isn't necessary anymore. And remove the existing "Modifier returned error, skipping apply" message which was cryptic and redundant if applying returns an actual error message. Resolves T103229 Differential Revision: https://developer.blender.org/D16782 --- .../blender/editors/object/object_modifier.cc | 28 ++++++++++++++----- source/blender/modifiers/intern/MOD_nodes.cc | 15 +--------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 2fa37f205ab..2401fdf2d93 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -694,7 +694,8 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph, Object *ob_eval, ModifierData *md_eval, const bool use_virtual_modifiers, - const bool build_shapekey_layers) + const bool build_shapekey_layers, + ReportList *reports) { Mesh *me = ob_eval->runtime.data_orig ? reinterpret_cast(ob_eval->runtime.data_orig) : reinterpret_cast(ob_eval->data); @@ -766,9 +767,21 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph, add_shapekey_layers(*mesh_temp, *me); } - result = mti->modifyMesh(md_eval, &mectx, mesh_temp); - if (mesh_temp != result) { - BKE_id_free(nullptr, mesh_temp); + if (mti->modifyGeometrySet) { + GeometrySet geometry_set = GeometrySet::create_with_mesh(mesh_temp, + GeometryOwnershipType::Owned); + mti->modifyGeometrySet(md_eval, &mectx, &geometry_set); + if (!geometry_set.has_mesh()) { + BKE_report(reports, RPT_ERROR, "Evaluated geometry from modifier does not contain a mesh"); + return nullptr; + } + result = geometry_set.get_component_for_write().release(); + } + else { + result = mti->modifyMesh(md_eval, &mectx, mesh_temp); + if (mesh_temp != result) { + BKE_id_free(nullptr, mesh_temp); + } } } @@ -817,7 +830,8 @@ static bool modifier_apply_shape(Main *bmain, DEG_get_evaluated_object(depsgraph, ob), md_eval, true, - false); + false, + reports); if (!mesh_applied) { BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply"); return false; @@ -883,9 +897,9 @@ static bool modifier_apply_obdata( /* It's important not to apply virtual modifiers (e.g. shape-keys) because they're kept, * causing them to be applied twice, see: T97758. */ false, - true); + true, + reports); if (!mesh_applied) { - BKE_report(reports, RPT_ERROR, "Modifier returned error, skipping apply"); return false; } diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index f5ede42b0ad..64261ae5b10 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1309,19 +1309,6 @@ static void modifyGeometry(ModifierData *md, } } -static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) -{ - GeometrySet geometry_set = GeometrySet::create_with_mesh(mesh, GeometryOwnershipType::Editable); - - modifyGeometry(md, ctx, geometry_set); - - Mesh *new_mesh = geometry_set.get_component_for_write().release(); - if (new_mesh == nullptr) { - return BKE_mesh_new_nomain(0, 0, 0, 0, 0); - } - return new_mesh; -} - static void modifyGeometrySet(ModifierData *md, const ModifierEvalContext *ctx, GeometrySet *geometry_set) @@ -1882,7 +1869,7 @@ ModifierTypeInfo modifierType_Nodes = { /* deformMatrices */ nullptr, /* deformVertsEM */ nullptr, /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, + /* modifyMesh */ nullptr, /* modifyGeometrySet */ modifyGeometrySet, /* initData */ initData, From 6514bb05ea5a138d897151db02cb0bad9fe01968 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 15 Dec 2022 14:18:57 -0600 Subject: [PATCH 0151/1522] Mesh: Store active & default color attributes with strings Attributes are unifying around a name-based API, and we would like to be able to move away from CustomData in the future. This patch moves the identification of active and fallback (render) color attributes to strings on the mesh from flags on CustomDataLayer. This also removes some ugliness used to retrieve these attributes and maintain the active status. The design is described more here: T98366 The patch keeps forward compatibility working until 4.0 with the same method as the mesh struct of array refactors (T95965). The strings are allowed to not correspond to an attribute, to allow setting the active/default attribute independently of actually filling its data. When applying a modifier, if the strings don't match an attribute, they will be removed. The realize instances / join node and join operator take the names from the first / active input mesh. While other heuristics may be helpful (and could be a future improvement), just using the first is simple and predictable. Differential Revision: https://developer.blender.org/D15169 --- source/blender/blenkernel/BKE_attribute.h | 19 +- .../blenkernel/BKE_mesh_legacy_convert.h | 3 + source/blender/blenkernel/intern/attribute.cc | 137 ++++----- .../blender/blenkernel/intern/customdata.cc | 3 +- source/blender/blenkernel/intern/mesh.cc | 13 + .../blenkernel/intern/mesh_legacy_convert.cc | 140 ++++++++- .../blenkernel/intern/mesh_remesh_voxel.cc | 15 - source/blender/blenkernel/intern/paint.cc | 30 +- source/blender/blenkernel/intern/pbvh.c | 10 +- .../blenloader/intern/versioning_300.cc | 8 +- .../blenloader/intern/versioning_400.cc | 1 + source/blender/draw/DRW_pbvh.h | 3 + .../draw_cache_extract_mesh_render_data.cc | 19 +- .../draw/intern/draw_cache_impl_mesh.cc | 41 +-- .../draw/intern/draw_cache_impl_particles.c | 18 +- .../blender/draw/intern/draw_manager_data.cc | 4 +- source/blender/draw/intern/draw_pbvh.cc | 29 +- .../editors/geometry/geometry_attributes.cc | 60 ++-- source/blender/editors/mesh/mesh_data.cc | 165 +++++------ .../blender/editors/object/object_bake_api.c | 7 +- .../blender/editors/object/object_modifier.cc | 25 ++ .../editors/sculpt_paint/paint_image_proj.cc | 6 +- .../editors/sculpt_paint/paint_vertex.cc | 277 +++++++++--------- .../sculpt_paint/paint_vertex_color_ops.cc | 34 +-- source/blender/editors/sculpt_paint/sculpt.cc | 17 +- .../editors/sculpt_paint/sculpt_undo.c | 2 +- .../BlenderStrokeRenderer.cpp | 4 +- .../geometry/intern/realize_instances.cc | 9 + .../gpu/intern/gpu_shader_builder_stubs.cc | 20 -- source/blender/io/collada/MeshImporter.cpp | 4 +- .../exporter/obj_export_file_writer.cc | 9 +- .../wavefront_obj/importer/obj_import_mesh.cc | 1 + .../blender/makesdna/DNA_customdata_types.h | 2 + source/blender/makesdna/DNA_mesh_types.h | 5 + .../blender/makesrna/intern/rna_attribute.c | 71 +++-- source/blender/makesrna/intern/rna_material.c | 2 +- source/blender/makesrna/intern/rna_mesh.c | 16 +- 37 files changed, 666 insertions(+), 563 deletions(-) diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h index 3f4981993eb..eef1459be81 100644 --- a/source/blender/blenkernel/BKE_attribute.h +++ b/source/blender/blenkernel/BKE_attribute.h @@ -105,16 +105,6 @@ int BKE_id_attribute_to_index(const struct ID *id, eAttrDomainMask domain_mask, eCustomDataMask layer_mask); -struct CustomDataLayer *BKE_id_attribute_subset_active_get(const struct ID *id, - int active_flag, - eAttrDomainMask domain_mask, - eCustomDataMask mask); -void BKE_id_attribute_subset_active_set(struct ID *id, - struct CustomDataLayer *layer, - int active_flag, - eAttrDomainMask domain_mask, - eCustomDataMask mask); - /** * Sets up a temporary ID with arbitrary CustomData domains. `r_id` will * be zero initialized with ID type id_type and any non-nullptr @@ -130,10 +120,13 @@ void BKE_id_attribute_copy_domains_temp(short id_type, const struct CustomData *cdata, struct ID *r_id); +const char *BKE_id_attributes_active_color_name(const struct ID *id); +const char *BKE_id_attributes_default_color_name(const struct ID *id); + struct CustomDataLayer *BKE_id_attributes_active_color_get(const struct ID *id); -void BKE_id_attributes_active_color_set(struct ID *id, struct CustomDataLayer *active_layer); -struct CustomDataLayer *BKE_id_attributes_render_color_get(const struct ID *id); -void BKE_id_attributes_render_color_set(struct ID *id, struct CustomDataLayer *active_layer); +void BKE_id_attributes_active_color_set(struct ID *id, const char *name); +struct CustomDataLayer *BKE_id_attributes_default_color_get(const struct ID *id); +void BKE_id_attributes_default_color_set(struct ID *id, const char *name); struct CustomDataLayer *BKE_id_attributes_color_find(const struct ID *id, const char *name); bool BKE_id_attribute_calc_unique_name(struct ID *id, const char *name, char *outname); diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h index e46942aa9e9..65804e9ac24 100644 --- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h +++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h @@ -85,6 +85,9 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(struct Mesh *mesh); /** Convert from runtime loose edge cache to legacy edge flag. */ void BKE_mesh_legacy_convert_loose_edges_to_flag(struct Mesh *mesh); +void BKE_mesh_legacy_attribute_flags_to_strings(struct Mesh *mesh); +void BKE_mesh_legacy_attribute_strings_to_flags(struct Mesh *mesh); + #endif /** diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc index 80647362826..58990c5c024 100644 --- a/source/blender/blenkernel/intern/attribute.cc +++ b/source/blender/blenkernel/intern/attribute.cc @@ -145,6 +145,7 @@ bool BKE_id_attribute_rename(ID *id, const char *new_name, ReportList *reports) { + using namespace blender; if (BKE_id_attribute_required(id, old_name)) { BLI_assert_msg(0, "Required attribute name is not editable"); return false; @@ -166,6 +167,14 @@ bool BKE_id_attribute_rename(ID *id, char result_name[MAX_CUSTOMDATA_LAYER_NAME]; BKE_id_attribute_calc_unique_name(id, new_name, result_name); + + if (StringRef(old_name) == BKE_id_attributes_active_color_name(id)) { + BKE_id_attributes_active_color_set(id, result_name); + } + if (StringRef(old_name) == BKE_id_attributes_default_color_name(id)) { + BKE_id_attributes_default_color_set(id, result_name); + } + BLI_strncpy_utf8(layer->name, result_name, sizeof(layer->name)); return true; @@ -287,6 +296,7 @@ CustomDataLayer *BKE_id_attribute_duplicate(ID *id, const char *name, ReportList bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports) { + using namespace blender; using namespace blender::bke; if (!name || name[0] == '\0') { BKE_report(reports, RPT_ERROR, "The attribute name must not be empty"); @@ -306,6 +316,12 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports) for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) { if (CustomData *data = info[domain].customdata) { if (BM_data_layer_free_named(em->bm, data, name)) { + if (name == StringRef(mesh->active_color_attribute)) { + MEM_SAFE_FREE(mesh->active_color_attribute); + } + else if (name == StringRef(mesh->default_color_attribute)) { + MEM_SAFE_FREE(mesh->default_color_attribute); + } return true; } } @@ -327,6 +343,9 @@ CustomDataLayer *BKE_id_attribute_find(const ID *id, const int type, const eAttrDomain domain) { + if (!name) { + return nullptr; + } DomainInfo info[ATTR_DOMAIN_NUM]; get_domains(id, info); @@ -350,6 +369,9 @@ CustomDataLayer *BKE_id_attribute_search(ID *id, const eCustomDataMask type_mask, const eAttrDomainMask domain_mask) { + if (!name) { + return nullptr; + } DomainInfo info[ATTR_DOMAIN_NUM]; get_domains(id, info); @@ -633,104 +655,69 @@ int BKE_id_attribute_to_index(const ID *id, return -1; } -CustomDataLayer *BKE_id_attribute_subset_active_get(const ID *id, - int active_flag, - eAttrDomainMask domain_mask, - eCustomDataMask mask) +const char *BKE_id_attributes_active_color_name(const ID *id) { - DomainInfo info[ATTR_DOMAIN_NUM]; - eAttrDomain domains[ATTR_DOMAIN_NUM]; - - get_domains_types(domains); - get_domains(id, info); - - CustomDataLayer *candidate = nullptr; - for (int i = 0; i < ARRAY_SIZE(domains); i++) { - if (!((1 << domains[i]) & domain_mask) || !info[domains[i]].customdata) { - continue; - } - - CustomData *cdata = info[domains[i]].customdata; - - for (int j = 0; j < cdata->totlayer; j++) { - CustomDataLayer *layer = cdata->layers + j; - - if (!(CD_TYPE_AS_MASK(layer->type) & mask) || (layer->flag & CD_FLAG_TEMPORARY)) { - continue; - } - - if (layer->flag & active_flag) { - return layer; - } - - candidate = layer; - } + if (GS(id->name) == ID_ME) { + return reinterpret_cast(id)->active_color_attribute; } - - return candidate; + return nullptr; } -void BKE_id_attribute_subset_active_set(ID *id, - CustomDataLayer *layer, - int active_flag, - eAttrDomainMask domain_mask, - eCustomDataMask mask) +const char *BKE_id_attributes_default_color_name(const ID *id) { - DomainInfo info[ATTR_DOMAIN_NUM]; - eAttrDomain domains[ATTR_DOMAIN_NUM]; - - get_domains_types(domains); - get_domains(id, info); - - for (int i = 0; i < ATTR_DOMAIN_NUM; i++) { - eAttrDomainMask domain_mask2 = (eAttrDomainMask)(1 << domains[i]); - - if (!(domain_mask2 & domain_mask) || !info[domains[i]].customdata) { - continue; - } - - CustomData *cdata = info[domains[i]].customdata; - - for (int j = 0; j < cdata->totlayer; j++) { - CustomDataLayer *layer_iter = cdata->layers + j; - - if (!(CD_TYPE_AS_MASK(layer_iter->type) & mask) || (layer_iter->flag & CD_FLAG_TEMPORARY)) { - continue; - } - - layer_iter->flag &= ~active_flag; - } + if (GS(id->name) == ID_ME) { + return reinterpret_cast(id)->default_color_attribute; } - - layer->flag |= active_flag; + return nullptr; } CustomDataLayer *BKE_id_attributes_active_color_get(const ID *id) { - return BKE_id_attribute_subset_active_get( - id, CD_FLAG_COLOR_ACTIVE, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); + return BKE_id_attributes_color_find(id, BKE_id_attributes_active_color_name(id)); } -void BKE_id_attributes_active_color_set(ID *id, CustomDataLayer *active_layer) +void BKE_id_attributes_active_color_set(ID *id, const char *name) { - BKE_id_attribute_subset_active_set( - id, active_layer, CD_FLAG_COLOR_ACTIVE, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); + switch (GS(id->name)) { + case ID_ME: { + Mesh *mesh = reinterpret_cast(id); + MEM_SAFE_FREE(mesh->active_color_attribute); + if (name) { + mesh->active_color_attribute = BLI_strdup(name); + } + break; + } + default: + break; + } } -CustomDataLayer *BKE_id_attributes_render_color_get(const ID *id) +CustomDataLayer *BKE_id_attributes_default_color_get(const ID *id) { - return BKE_id_attribute_subset_active_get( - id, CD_FLAG_COLOR_RENDER, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); + return BKE_id_attributes_color_find(id, BKE_id_attributes_default_color_name(id)); } -void BKE_id_attributes_render_color_set(ID *id, CustomDataLayer *active_layer) +void BKE_id_attributes_default_color_set(ID *id, const char *name) { - BKE_id_attribute_subset_active_set( - id, active_layer, CD_FLAG_COLOR_RENDER, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); + switch (GS(id->name)) { + case ID_ME: { + Mesh *mesh = reinterpret_cast(id); + MEM_SAFE_FREE(mesh->default_color_attribute); + if (name) { + mesh->default_color_attribute = BLI_strdup(name); + } + break; + } + default: + break; + } } CustomDataLayer *BKE_id_attributes_color_find(const ID *id, const char *name) { + if (!name) { + return nullptr; + } CustomDataLayer *layer = BKE_id_attribute_find(id, name, CD_PROP_COLOR, ATTR_DOMAIN_POINT); if (layer == nullptr) { layer = BKE_id_attribute_find(id, name, CD_PROP_COLOR, ATTR_DOMAIN_CORNER); diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index c8d7c4f2fdc..cb22f4a650c 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -2347,8 +2347,7 @@ bool CustomData_merge(const CustomData *source, newlayer->active_rnd = lastrender; newlayer->active_clone = lastclone; newlayer->active_mask = lastmask; - newlayer->flag |= flag & (CD_FLAG_EXTERNAL | CD_FLAG_IN_MEMORY | CD_FLAG_COLOR_ACTIVE | - CD_FLAG_COLOR_RENDER); + newlayer->flag |= flag & (CD_FLAG_EXTERNAL | CD_FLAG_IN_MEMORY); changed = true; if (layer->anonymous_id != nullptr) { diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 16858a70a0c..6ec171c4bcc 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -144,6 +144,10 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int mesh_dst->mat = (Material **)MEM_dupallocN(mesh_src->mat); BKE_defgroup_copy_list(&mesh_dst->vertex_group_names, &mesh_src->vertex_group_names); + mesh_dst->active_color_attribute = static_cast( + MEM_dupallocN(mesh_src->active_color_attribute)); + mesh_dst->default_color_attribute = static_cast( + MEM_dupallocN(mesh_src->default_color_attribute)); const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE; CustomData_copy(&mesh_src->vdata, &mesh_dst->vdata, mask.vmask, alloc_type, mesh_dst->totvert); @@ -253,6 +257,9 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address BKE_mesh_legacy_bevel_weight_from_layers(mesh); BKE_mesh_legacy_face_set_from_generic(mesh, poly_layers); BKE_mesh_legacy_edge_crease_from_layers(mesh); + BKE_mesh_legacy_attribute_strings_to_flags(mesh); + mesh->active_color_attribute = nullptr; + mesh->default_color_attribute = nullptr; BKE_mesh_legacy_convert_loose_edges_to_flag(mesh); /* When converting to the old mesh format, don't save redundant attributes. */ names_to_skip.add_multiple_new({".hide_vert", @@ -288,6 +295,8 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address } BKE_defbase_blend_write(writer, &mesh->vertex_group_names); + BLO_write_string(writer, mesh->active_color_attribute); + BLO_write_string(writer, mesh->default_color_attribute); BLO_write_pointer_array(writer, mesh->totcol, mesh->mat); BLO_write_raw(writer, sizeof(MSelect) * mesh->totselect, mesh->mselect); @@ -337,6 +346,8 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id) * Don't read them again if they were read as part of #CustomData. */ BKE_defvert_blend_read(reader, mesh->totvert, mesh->dvert); } + BLO_read_data_address(reader, &mesh->active_color_attribute); + BLO_read_data_address(reader, &mesh->default_color_attribute); mesh->texflag &= ~ME_AUTOSPACE_EVALUATED; mesh->edit_mesh = nullptr; @@ -893,6 +904,8 @@ static void mesh_clear_geometry(Mesh *mesh) mesh->totselect = 0; BLI_freelistN(&mesh->vertex_group_names); + MEM_SAFE_FREE(mesh->active_color_attribute); + MEM_SAFE_FREE(mesh->default_color_attribute); } void BKE_mesh_clear_geometry(Mesh *mesh) diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 1673e972a32..a53b0e66924 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -525,7 +525,7 @@ static void convert_mfaces_to_mpolys(ID *id, #undef ME_FGON } -static void update_active_fdata_layers(CustomData *fdata, CustomData *ldata) +static void update_active_fdata_layers(Mesh &mesh, CustomData *fdata, CustomData *ldata) { int act; @@ -544,10 +544,10 @@ static void update_active_fdata_layers(CustomData *fdata, CustomData *ldata) } if (CustomData_has_layer(ldata, CD_PROP_BYTE_COLOR)) { - act = CustomData_get_active_layer(ldata, CD_PROP_BYTE_COLOR); + act = CustomData_get_named_layer(ldata, CD_PROP_BYTE_COLOR, mesh.active_color_attribute); CustomData_set_layer_active(fdata, CD_MCOL, act); - act = CustomData_get_render_layer(ldata, CD_PROP_BYTE_COLOR); + act = CustomData_get_named_layer(ldata, CD_PROP_BYTE_COLOR, mesh.default_color_attribute); CustomData_set_layer_render(fdata, CD_MCOL, act); act = CustomData_get_clone_layer(ldata, CD_PROP_BYTE_COLOR); @@ -599,7 +599,7 @@ static bool check_matching_legacy_layer_counts(CustomData *fdata, CustomData *ld } #endif -static void add_mface_layers(CustomData *fdata, CustomData *ldata, int total) +static void add_mface_layers(Mesh &mesh, CustomData *fdata, CustomData *ldata, int total) { /* avoid accumulating extra layers */ BLI_assert(!check_matching_legacy_layer_counts(fdata, ldata, false)); @@ -631,7 +631,7 @@ static void add_mface_layers(CustomData *fdata, CustomData *ldata, int total) } } - update_active_fdata_layers(fdata, ldata); + update_active_fdata_layers(mesh, fdata, ldata); } static void mesh_ensure_tessellation_customdata(Mesh *me) @@ -652,7 +652,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me) if (tottex_tessface != tottex_original || totcol_tessface != totcol_original) { BKE_mesh_tessface_clear(me); - add_mface_layers(&me->fdata, &me->ldata, me->totface); + add_mface_layers(*me, &me->fdata, &me->ldata, me->totface); /* TODO: add some `--debug-mesh` option. */ if (G.debug & G_DEBUG) { @@ -931,7 +931,8 @@ int BKE_mesh_mface_index_validate(MFace *mface, CustomData *fdata, int mfindex, return nr; } -static int mesh_tessface_calc(CustomData *fdata, +static int mesh_tessface_calc(Mesh &mesh, + CustomData *fdata, CustomData *ldata, CustomData *pdata, MVert *mvert, @@ -1140,7 +1141,7 @@ static int mesh_tessface_calc(CustomData *fdata, /* #CD_ORIGINDEX will contain an array of indices from tessellation-faces to the polygons * they are directly tessellated from. */ CustomData_add_layer(fdata, CD_ORIGINDEX, CD_ASSIGN, mface_to_poly_map, totface); - add_mface_layers(fdata, ldata, totface); + add_mface_layers(mesh, fdata, ldata, totface); /* NOTE: quad detection issue - fourth vertidx vs fourth loopidx: * Polygons take care of their loops ordering, hence not of their vertices ordering. @@ -1178,7 +1179,8 @@ static int mesh_tessface_calc(CustomData *fdata, void BKE_mesh_tessface_calc(Mesh *mesh) { - mesh->totface = mesh_tessface_calc(&mesh->fdata, + mesh->totface = mesh_tessface_calc(*mesh, + &mesh->fdata, &mesh->ldata, &mesh->pdata, BKE_mesh_verts_for_write(mesh), @@ -1567,3 +1569,123 @@ void BKE_mesh_legacy_convert_loose_edges_to_flag(Mesh *mesh) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Attribute Active Flag to String Conversion + * \{ */ + +void BKE_mesh_legacy_attribute_flags_to_strings(Mesh *mesh) +{ + using namespace blender; + /* It's not clear whether the active/render status was stored in the dedicated flags or in the + * generic CustomData layer indices, so convert from both, preferring the explicit flags. */ + + auto active_from_flags = [&](const CustomData &data) { + if (!mesh->active_color_attribute) { + for (const int i : IndexRange(data.totlayer)) { + if (data.layers[i].flag & CD_FLAG_COLOR_ACTIVE) { + mesh->active_color_attribute = BLI_strdup(data.layers[i].name); + } + } + } + }; + auto active_from_indices = [&](const CustomData &data) { + if (!mesh->active_color_attribute) { + const int i = CustomData_get_active_layer_index(&data, CD_PROP_COLOR); + if (i != -1) { + mesh->active_color_attribute = BLI_strdup(data.layers[i].name); + } + } + if (!mesh->active_color_attribute) { + const int i = CustomData_get_active_layer_index(&data, CD_PROP_BYTE_COLOR); + if (i != -1) { + mesh->active_color_attribute = BLI_strdup(data.layers[i].name); + } + } + }; + auto default_from_flags = [&](const CustomData &data) { + if (!mesh->default_color_attribute) { + for (const int i : IndexRange(data.totlayer)) { + if (data.layers[i].flag & CD_FLAG_COLOR_RENDER) { + mesh->default_color_attribute = BLI_strdup(data.layers[i].name); + } + } + } + }; + auto default_from_indices = [&](const CustomData &data) { + if (!mesh->default_color_attribute) { + const int i = CustomData_get_render_layer_index(&data, CD_PROP_COLOR); + if (i != -1) { + mesh->default_color_attribute = BLI_strdup(data.layers[i].name); + } + } + if (!mesh->default_color_attribute) { + const int i = CustomData_get_render_layer_index(&data, CD_PROP_BYTE_COLOR); + if (i != -1) { + mesh->default_color_attribute = BLI_strdup(data.layers[i].name); + } + } + }; + + active_from_flags(mesh->vdata); + active_from_flags(mesh->ldata); + active_from_indices(mesh->vdata); + active_from_indices(mesh->ldata); + + default_from_flags(mesh->vdata); + default_from_flags(mesh->ldata); + default_from_indices(mesh->vdata); + default_from_indices(mesh->ldata); +} + +void BKE_mesh_legacy_attribute_strings_to_flags(Mesh *mesh) +{ + using namespace blender; + CustomData *vdata = &mesh->vdata; + CustomData *ldata = &mesh->ldata; + + CustomData_clear_layer_flag( + vdata, CD_PROP_BYTE_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER); + CustomData_clear_layer_flag(ldata, CD_PROP_COLOR, CD_FLAG_COLOR_ACTIVE | CD_FLAG_COLOR_RENDER); + + if (const char *name = mesh->active_color_attribute) { + int i; + if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_BYTE_COLOR, name)) != -1) { + CustomData_set_layer_active_index(vdata, CD_PROP_BYTE_COLOR, i); + vdata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE; + } + else if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_COLOR, name)) != -1) { + CustomData_set_layer_active_index(vdata, CD_PROP_COLOR, i); + vdata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE; + } + else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_BYTE_COLOR, name)) != -1) { + CustomData_set_layer_active_index(ldata, CD_PROP_BYTE_COLOR, i); + ldata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE; + } + else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_COLOR, name)) != -1) { + CustomData_set_layer_active_index(ldata, CD_PROP_COLOR, i); + ldata->layers[i].flag |= CD_FLAG_COLOR_ACTIVE; + } + } + if (const char *name = mesh->default_color_attribute) { + int i; + if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_BYTE_COLOR, name)) != -1) { + CustomData_set_layer_render_index(vdata, CD_PROP_BYTE_COLOR, i); + vdata->layers[i].flag |= CD_FLAG_COLOR_RENDER; + } + else if ((i = CustomData_get_named_layer_index(vdata, CD_PROP_COLOR, name)) != -1) { + CustomData_set_layer_render_index(vdata, CD_PROP_COLOR, i); + vdata->layers[i].flag |= CD_FLAG_COLOR_RENDER; + } + else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_BYTE_COLOR, name)) != -1) { + CustomData_set_layer_render_index(ldata, CD_PROP_BYTE_COLOR, i); + ldata->layers[i].flag |= CD_FLAG_COLOR_RENDER; + } + else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_COLOR, name)) != -1) { + CustomData_set_layer_render_index(ldata, CD_PROP_COLOR, i); + ldata->layers[i].flag |= CD_FLAG_COLOR_RENDER; + } + } +} + +/** \} */ diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index 86c77327f98..a2916c75d51 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -494,21 +494,6 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source) MEM_SAFE_FREE(target_lmap); MEM_SAFE_FREE(target_lmap_mem); free_bvhtree_from_mesh(&bvhtree); - - /* Transfer active/render color attributes */ - - CustomDataLayer *active_layer = BKE_id_attributes_active_color_get(&source->id); - CustomDataLayer *render_layer = BKE_id_attributes_render_color_get(&source->id); - - if (active_layer) { - BKE_id_attributes_active_color_set( - &target->id, BKE_id_attributes_color_find(&target->id, active_layer->name)); - } - - if (render_layer) { - BKE_id_attributes_render_color_set( - &target->id, BKE_id_attributes_color_find(&target->id, render_layer->name)); - } } struct Mesh *BKE_mesh_remesh_voxel_fix_poles(const Mesh *mesh) diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index e6d61ddcdd3..ebbe3c2c4fa 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -1919,32 +1919,24 @@ void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval) void BKE_sculpt_color_layer_create_if_needed(Object *object) { + using namespace blender; + using namespace blender::bke; Mesh *orig_me = BKE_object_get_original_mesh(object); - int types[] = {CD_PROP_COLOR, CD_PROP_BYTE_COLOR}; - bool has_color = false; - - for (int i = 0; i < ARRAY_SIZE(types); i++) { - has_color = CustomData_has_layer(&orig_me->vdata, types[i]) || - CustomData_has_layer(&orig_me->ldata, types[i]); - - if (has_color) { - break; - } - } - - if (has_color) { + if (orig_me->attributes().contains(orig_me->active_color_attribute)) { return; } - CustomData_add_layer(&orig_me->vdata, CD_PROP_COLOR, CD_SET_DEFAULT, nullptr, orig_me->totvert); - CustomDataLayer *layer = orig_me->vdata.layers + - CustomData_get_layer_index(&orig_me->vdata, CD_PROP_COLOR); + char unique_name[MAX_CUSTOMDATA_LAYER_NAME]; + BKE_id_attribute_calc_unique_name(&orig_me->id, "Color", unique_name); + if (!orig_me->attributes_for_write().add( + unique_name, ATTR_DOMAIN_POINT, CD_PROP_COLOR, AttributeInitDefaultValue())) { + return; + } - BKE_mesh_tessface_clear(orig_me); - - BKE_id_attributes_active_color_set(&orig_me->id, layer); + BKE_id_attributes_active_color_set(&orig_me->id, unique_name); DEG_id_tag_update(&orig_me->id, ID_RECALC_GEOMETRY_ALL_MODES); + BKE_mesh_tessface_clear(orig_me); if (object->sculpt && object->sculpt->pbvh) { BKE_pbvh_update_active_vcol(object->sculpt->pbvh, orig_me); diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 35c2c660fd2..efaeb89c9a9 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -696,6 +696,9 @@ static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node) args->mpoly = pbvh->mpoly; args->vert_normals = pbvh->vert_normals; + args->active_color = pbvh->mesh->active_color_attribute; + args->render_color = pbvh->mesh->default_color_attribute; + args->prim_indices = node->prim_indices; args->face_sets = pbvh->face_sets; break; @@ -711,6 +714,9 @@ static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node) args->face_sets = pbvh->face_sets; args->mpoly = pbvh->mpoly; + args->active_color = pbvh->mesh->active_color_attribute; + args->render_color = pbvh->mesh->default_color_attribute; + args->mesh_grids_num = pbvh->totgrid; args->grids = pbvh->grids; args->gridfaces = pbvh->gridfaces; @@ -1588,7 +1594,7 @@ void pbvh_update_BB_redraw(PBVH *pbvh, PBVHNode **nodes, int totnode, int flag) bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, eAttrDomain *r_attr) { - CustomDataLayer *layer = BKE_id_attributes_active_color_get((ID *)me); + CustomDataLayer *layer = BKE_id_attributes_color_find(&me->id, me->active_color_attribute); if (!layer || !ELEM(layer->type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) { *r_layer = NULL; @@ -1596,7 +1602,7 @@ bool BKE_pbvh_get_color_layer(const Mesh *me, CustomDataLayer **r_layer, eAttrDo return false; } - eAttrDomain domain = BKE_id_attribute_domain((ID *)me, layer); + eAttrDomain domain = BKE_id_attribute_domain(&me->id, layer); if (!ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER)) { *r_layer = NULL; diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index c22c74ac237..79b1164c0dd 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3197,10 +3197,10 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) if (actlayer) { if (step) { - BKE_id_attributes_render_color_set(&me->id, actlayer); + BKE_id_attributes_default_color_set(&me->id, actlayer->name); } else { - BKE_id_attributes_active_color_set(&me->id, actlayer); + BKE_id_attributes_active_color_set(&me->id, actlayer->name); } } } @@ -3362,10 +3362,10 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) if (actlayer) { if (step) { - BKE_id_attributes_render_color_set(&me->id, actlayer); + BKE_id_attributes_default_color_set(&me->id, actlayer->name); } else { - BKE_id_attributes_active_color_set(&me->id, actlayer); + BKE_id_attributes_active_color_set(&me->id, actlayer->name); } } } diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 7edeb8a40a5..583e885a487 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -33,6 +33,7 @@ static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh) BKE_mesh_legacy_bevel_weight_to_layers(&mesh); BKE_mesh_legacy_face_set_to_generic(&mesh); BKE_mesh_legacy_edge_crease_to_layers(&mesh); + BKE_mesh_legacy_attribute_flags_to_strings(&mesh); } static void version_motion_tracking_legacy_camera_object(MovieClip &movieclip) diff --git a/source/blender/draw/DRW_pbvh.h b/source/blender/draw/DRW_pbvh.h index 6f9daac0a35..6956b44c695 100644 --- a/source/blender/draw/DRW_pbvh.h +++ b/source/blender/draw/DRW_pbvh.h @@ -48,6 +48,9 @@ typedef struct PBVH_GPU_Args { struct CustomData *vdata, *ldata, *pdata; const float (*vert_normals)[3]; + const char *active_color; + const char *render_color; + int face_sets_color_seed, face_sets_color_default; int *face_sets; /* for PBVH_FACES and PBVH_GRIDS */ diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc index bfec7cd6f7b..ba117a75be6 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc @@ -426,23 +426,8 @@ static void retrieve_active_attribute_names(MeshRenderData &mr, const Mesh &mesh) { const Mesh *mesh_final = editmesh_final_or_this(&object, &mesh); - const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(mesh_final); - const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(mesh_final); - - /* Necessary because which attributes are active/default is stored in #CustomData. */ - Mesh me_query = blender::dna::shallow_zero_initialize(); - BKE_id_attribute_copy_domains_temp( - ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id); - - mr.active_color_name = nullptr; - mr.default_color_name = nullptr; - - if (const CustomDataLayer *active = BKE_id_attributes_active_color_get(&me_query.id)) { - mr.active_color_name = active->name; - } - if (const CustomDataLayer *render = BKE_id_attributes_render_color_get(&me_query.id)) { - mr.default_color_name = render->name; - } + mr.active_color_name = mesh_final->active_color_attribute; + mr.default_color_name = mesh_final->default_color_attribute; } MeshRenderData *mesh_render_data_create(Object *object, diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc index 927b72325ff..2f560d161d7 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.cc +++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc @@ -282,19 +282,13 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final); const CustomData *cd_edata = mesh_cd_edata_get_from_mesh(me_final); - /* Create a mesh with final customdata domains - * we can query with attribute API. */ - Mesh me_query = blender::dna::shallow_zero_initialize(); - - BKE_id_attribute_copy_domains_temp( - ID_ME, cd_vdata, cd_edata, cd_ldata, cd_pdata, nullptr, &me_query.id); - /* See: DM_vertex_attributes_from_gpu for similar logic */ DRW_MeshCDMask cd_used; mesh_cd_layers_type_clear(&cd_used); - const CustomDataLayer *default_color = BKE_id_attributes_render_color_get(&me_query.id); - const StringRefNull default_color_name = default_color ? default_color->name : ""; + const StringRefNull default_color_name = me_final->default_color_attribute ? + me_final->default_color_attribute : + ""; for (int i = 0; i < gpumat_array_len; i++) { GPUMaterial *gpumat = gpumat_array[i]; @@ -883,28 +877,21 @@ static void request_active_and_default_color_attributes(const Object &object, const CustomData *cd_vdata = mesh_cd_vdata_get_from_mesh(me_final); const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final); - /* Necessary because which attributes are active/default is stored in #CustomData. */ - Mesh me_query = blender::dna::shallow_zero_initialize(); - BKE_id_attribute_copy_domains_temp( - ID_ME, cd_vdata, nullptr, cd_ldata, nullptr, nullptr, &me_query.id); - auto request_color_attribute = [&](const char *name) { - int layer_index; - eCustomDataType type; - if (drw_custom_data_match_attribute(cd_vdata, name, &layer_index, &type)) { - drw_attributes_add_request(&attributes, name, type, layer_index, ATTR_DOMAIN_POINT); - } - else if (drw_custom_data_match_attribute(cd_ldata, name, &layer_index, &type)) { - drw_attributes_add_request(&attributes, name, type, layer_index, ATTR_DOMAIN_CORNER); + if (name) { + int layer_index; + eCustomDataType type; + if (drw_custom_data_match_attribute(cd_vdata, name, &layer_index, &type)) { + drw_attributes_add_request(&attributes, name, type, layer_index, ATTR_DOMAIN_POINT); + } + else if (drw_custom_data_match_attribute(cd_ldata, name, &layer_index, &type)) { + drw_attributes_add_request(&attributes, name, type, layer_index, ATTR_DOMAIN_CORNER); + } } }; - if (const CustomDataLayer *active = BKE_id_attributes_active_color_get(&me_query.id)) { - request_color_attribute(active->name); - } - if (const CustomDataLayer *render = BKE_id_attributes_render_color_get(&me_query.id)) { - request_color_attribute(render->name); - } + request_color_attribute(me_final->active_color_attribute); + request_color_attribute(me_final->default_color_attribute); } GPUBatch *DRW_mesh_batch_cache_get_all_verts(Mesh *me) diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index cddab74c46f..e1d63158b0b 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -841,8 +841,16 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR)) { cache->num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR); - active_col = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR); - render_col = CustomData_get_render_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR); + if (psmd->mesh_final->active_color_attribute != NULL) { + active_col = CustomData_get_named_layer(&psmd->mesh_final->ldata, + CD_PROP_BYTE_COLOR, + psmd->mesh_final->active_color_attribute); + } + if (psmd->mesh_final->default_color_attribute != NULL) { + render_col = CustomData_get_named_layer(&psmd->mesh_final->ldata, + CD_PROP_BYTE_COLOR, + psmd->mesh_final->default_color_attribute); + } } } @@ -1168,7 +1176,11 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, } if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR)) { num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR); - active_col = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR); + if (psmd->mesh_final->active_color_attribute != NULL) { + active_col = CustomData_get_named_layer(&psmd->mesh_final->ldata, + CD_PROP_BYTE_COLOR, + psmd->mesh_final->active_color_attribute); + } } } diff --git a/source/blender/draw/intern/draw_manager_data.cc b/source/blender/draw/intern/draw_manager_data.cc index d4ffd3f8691..c7b1ddffab3 100644 --- a/source/blender/draw/intern/draw_manager_data.cc +++ b/source/blender/draw/intern/draw_manager_data.cc @@ -1408,8 +1408,8 @@ void DRW_shgroup_call_sculpt(DRWShadingGroup *shgroup, Mesh *me = BKE_object_get_original_mesh(ob); if (use_color) { - CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); - + const CustomDataLayer *layer = BKE_id_attributes_color_find(&me->id, + me->active_color_attribute); if (layer) { eAttrDomain domain = BKE_id_attribute_domain(&me->id, layer); diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index bc9c449544c..d62ace4fb57 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -24,6 +24,7 @@ #include "BLI_map.hh" #include "BLI_math_color.h" #include "BLI_math_vec_types.hh" +#include "BLI_string_ref.hh" #include "BLI_timeit.hh" #include "BLI_utildefines.h" #include "BLI_vector.hh" @@ -916,33 +917,9 @@ struct PBVHBatches { const char *prefix = "a"; if (ELEM(type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) { - Mesh query_mesh; - - /* Check if we have args->me; if not use get_cdata to build something we - * can query for color attributes. - */ - if (args->me) { - memcpy(static_cast(&query_mesh), - static_cast(args->me), - sizeof(Mesh)); - } - else { - BKE_id_attribute_copy_domains_temp(ID_ME, - get_cdata(ATTR_DOMAIN_POINT, args), - nullptr, - get_cdata(ATTR_DOMAIN_CORNER, args), - nullptr, - nullptr, - &query_mesh.id); - } - prefix = "c"; - - CustomDataLayer *render = BKE_id_attributes_render_color_get(&query_mesh.id); - CustomDataLayer *active = BKE_id_attributes_active_color_get(&query_mesh.id); - - is_render = render && layer && STREQ(render->name, layer->name); - is_active = active && layer && STREQ(active->name, layer->name); + is_active = blender::StringRef(args->active_color) == layer->name; + is_render = blender::StringRef(args->render_color) == layer->name; } else { switch (type) { diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index d4850f5c124..c4cf34b3b94 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -107,8 +107,9 @@ static int geometry_attribute_add_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static void next_color_attribute(ID *id, CustomDataLayer *layer, bool is_render) +static void next_color_attribute(ID *id, const StringRefNull name, bool is_render) { + const CustomDataLayer *layer = BKE_id_attributes_color_find(id, name.c_str()); int index = BKE_id_attribute_to_index(id, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); index++; @@ -122,18 +123,18 @@ static void next_color_attribute(ID *id, CustomDataLayer *layer, bool is_render) if (layer) { if (is_render) { - BKE_id_attributes_active_color_set(id, layer); + BKE_id_attributes_active_color_set(id, layer->name); } else { - BKE_id_attributes_render_color_set(id, layer); + BKE_id_attributes_default_color_set(id, layer->name); } } } -static void next_color_attributes(ID *id, CustomDataLayer *layer) +static void next_color_attributes(ID *id, const StringRefNull name) { - next_color_attribute(id, layer, false); /* active */ - next_color_attribute(id, layer, true); /* render */ + next_color_attribute(id, name, false); /* active */ + next_color_attribute(id, name, true); /* render */ } void GEOMETRY_OT_attribute_add(wmOperatorType *ot) @@ -181,7 +182,7 @@ static int geometry_attribute_remove_exec(bContext *C, wmOperator *op) ID *id = static_cast(ob->data); CustomDataLayer *layer = BKE_id_attributes_active_get(id); - next_color_attributes(id, layer); + next_color_attributes(id, layer->name); if (!BKE_id_attribute_remove(id, layer->name, op->reports)) { return OPERATOR_CANCELLED; @@ -231,10 +232,10 @@ static int geometry_color_attribute_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - BKE_id_attributes_active_color_set(id, layer); + BKE_id_attributes_active_color_set(id, layer->name); - if (!BKE_id_attributes_render_color_get(id)) { - BKE_id_attributes_render_color_set(id, layer); + if (!BKE_id_attributes_color_find(id, BKE_id_attributes_default_color_name(id))) { + BKE_id_attributes_default_color_set(id, layer->name); } BKE_object_attributes_active_color_fill(ob, color, false); @@ -411,13 +412,8 @@ static int geometry_color_attribute_set_render_exec(bContext *C, wmOperator *op) char name[MAX_NAME]; RNA_string_get(op->ptr, "name", name); - CustomDataLayer *layer = BKE_id_attribute_find(id, name, CD_PROP_COLOR, ATTR_DOMAIN_POINT); - layer = !layer ? BKE_id_attribute_find(id, name, CD_PROP_BYTE_COLOR, ATTR_DOMAIN_POINT) : layer; - layer = !layer ? BKE_id_attribute_find(id, name, CD_PROP_COLOR, ATTR_DOMAIN_CORNER) : layer; - layer = !layer ? BKE_id_attribute_find(id, name, CD_PROP_BYTE_COLOR, ATTR_DOMAIN_CORNER) : layer; - - if (layer) { - BKE_id_attributes_render_color_set(id, layer); + if (BKE_id_attributes_color_find(id, name)) { + BKE_id_attributes_default_color_set(id, name); DEG_id_tag_update(id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, id); @@ -453,15 +449,14 @@ static int geometry_color_attribute_remove_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); ID *id = static_cast(ob->data); - CustomDataLayer *layer = BKE_id_attributes_active_color_get(id); - - if (layer == nullptr) { + const std::string active_name = StringRef(BKE_id_attributes_active_color_name(id)); + if (active_name.empty()) { return OPERATOR_CANCELLED; } - next_color_attributes(id, layer); + next_color_attributes(id, active_name); - if (!BKE_id_attribute_remove(id, layer->name, op->reports)) { + if (!BKE_id_attribute_remove(id, active_name.c_str(), op->reports)) { return OPERATOR_CANCELLED; } @@ -477,10 +472,10 @@ static bool geometry_color_attributes_remove_poll(bContext *C) return false; } - Object *ob = ED_object_context(C); - ID *data = ob ? static_cast(ob->data) : nullptr; + const Object *ob = ED_object_context(C); + const ID *data = static_cast(ob->data); - if (BKE_id_attributes_active_color_get(data) != nullptr) { + if (BKE_id_attributes_color_find(data, BKE_id_attributes_active_color_name(data))) { return true; } @@ -506,18 +501,17 @@ static int geometry_color_attribute_duplicate_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); ID *id = static_cast(ob->data); - const CustomDataLayer *layer = BKE_id_attributes_active_color_get(id); - - if (layer == nullptr) { + const char *active_name = BKE_id_attributes_active_color_name(id); + if (active_name == nullptr) { return OPERATOR_CANCELLED; } - CustomDataLayer *new_layer = BKE_id_attribute_duplicate(id, layer->name, op->reports); + CustomDataLayer *new_layer = BKE_id_attribute_duplicate(id, active_name, op->reports); if (new_layer == nullptr) { return OPERATOR_CANCELLED; } - BKE_id_attributes_active_color_set(id, new_layer); + BKE_id_attributes_active_color_set(id, new_layer->name); DEG_id_tag_update(id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, id); @@ -535,10 +529,10 @@ static bool geometry_color_attributes_duplicate_poll(bContext *C) return false; } - Object *ob = ED_object_context(C); - ID *data = ob ? static_cast(ob->data) : nullptr; + const Object *ob = ED_object_context(C); + const ID *data = static_cast(ob->data); - if (BKE_id_attributes_active_color_get(data) != nullptr) { + if (BKE_id_attributes_color_find(data, BKE_id_attributes_active_color_name(data))) { return true; } diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index b2809030192..a2310dddc61 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -377,79 +377,71 @@ bool ED_mesh_uv_remove_named(Mesh *me, const char *name) return false; } -int ED_mesh_color_add(Mesh *me, - const char *name, - const bool active_set, - const bool do_init, - ReportList * /*reports*/) +int ED_mesh_color_add( + Mesh *me, const char *name, const bool active_set, const bool do_init, ReportList *reports) { - /* NOTE: keep in sync with #ED_mesh_uv_add. */ + /* If no name is supplied, provide a backwards compatible default. */ + if (!name) { + name = "Col"; + } - BMEditMesh *em; - int layernum; + if (const CustomDataLayer *layer = BKE_id_attribute_find( + &me->id, me->active_color_attribute, CD_PROP_BYTE_COLOR, ATTR_DOMAIN_CORNER)) { + int dummy; + const CustomData *data = mesh_customdata_get_type(me, BM_LOOP, &dummy); + return CustomData_get_named_layer(data, CD_PROP_BYTE_COLOR, layer->name); + } - if (me->edit_mesh) { - em = me->edit_mesh; + CustomDataLayer *layer = BKE_id_attribute_new( + &me->id, name, CD_PROP_BYTE_COLOR, ATTR_DOMAIN_CORNER, reports); - layernum = CustomData_number_of_layers(&em->bm->ldata, CD_PROP_BYTE_COLOR); - - /* CD_PROP_BYTE_COLOR */ - BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_PROP_BYTE_COLOR, name); - /* copy data from active vertex color layer */ - if (layernum && do_init) { - const int layernum_dst = CustomData_get_active_layer(&em->bm->ldata, CD_PROP_BYTE_COLOR); - BM_data_layer_copy(em->bm, &em->bm->ldata, CD_PROP_BYTE_COLOR, layernum_dst, layernum); - } - if (active_set || layernum == 0) { - CustomData_set_layer_active(&em->bm->ldata, CD_PROP_BYTE_COLOR, layernum); + if (do_init) { + const char *active_name = me->active_color_attribute; + if (const CustomDataLayer *active_layer = BKE_id_attributes_color_find(&me->id, active_name)) { + if (const BMEditMesh *em = me->edit_mesh) { + BMesh &bm = *em->bm; + const int src_i = CustomData_get_named_layer(&bm.ldata, CD_PROP_BYTE_COLOR, active_name); + const int dst_i = CustomData_get_named_layer(&bm.ldata, CD_PROP_BYTE_COLOR, layer->name); + BM_data_layer_copy(&bm, &bm.ldata, CD_PROP_BYTE_COLOR, src_i, dst_i); + } + else { + memcpy(layer->data, active_layer->data, CustomData_get_elem_size(layer) * me->totloop); + } } } - else { - layernum = CustomData_number_of_layers(&me->ldata, CD_PROP_BYTE_COLOR); - if (CustomData_get_active_layer(&me->ldata, CD_PROP_BYTE_COLOR) != -1 && do_init) { - CustomData_add_layer_named(&me->ldata, - CD_PROP_BYTE_COLOR, - CD_DUPLICATE, - CustomData_get_layer(&me->ldata, CD_PROP_BYTE_COLOR), - me->totloop, - name); - } - else { - CustomData_add_layer_named( - &me->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, nullptr, me->totloop, name); - } - - if (active_set || layernum == 0) { - CustomData_set_layer_active(&me->ldata, CD_PROP_BYTE_COLOR, layernum); - } - - BKE_mesh_tessface_clear(me); + if (active_set) { + BKE_id_attributes_active_color_set(&me->id, layer->name); } DEG_id_tag_update(&me->id, 0); WM_main_add_notifier(NC_GEOM | ND_DATA, me); - return layernum; + int dummy; + const CustomData *data = mesh_customdata_get_type(me, BM_LOOP, &dummy); + return CustomData_get_named_layer(data, CD_PROP_BYTE_COLOR, layer->name); } bool ED_mesh_color_ensure(Mesh *me, const char *name) { + using namespace blender; BLI_assert(me->edit_mesh == nullptr); - CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); - - if (!layer) { - CustomData_add_layer_named( - &me->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, nullptr, me->totloop, name); - layer = me->ldata.layers + CustomData_get_layer_index(&me->ldata, CD_PROP_BYTE_COLOR); - - BKE_id_attributes_active_color_set(&me->id, layer); - BKE_mesh_tessface_clear(me); + if (me->attributes().contains(me->active_color_attribute)) { + return true; } + char unique_name[MAX_CUSTOMDATA_LAYER_NAME]; + BKE_id_attribute_calc_unique_name(&me->id, name, unique_name); + if (!me->attributes_for_write().add( + unique_name, ATTR_DOMAIN_CORNER, CD_PROP_BYTE_COLOR, bke::AttributeInitDefaultValue())) { + return false; + } + + BKE_id_attributes_active_color_set(&me->id, unique_name); + BKE_mesh_tessface_clear(me); DEG_id_tag_update(&me->id, 0); - return (layer != nullptr); + return true; } /*********************** General poll ************************/ @@ -464,57 +456,44 @@ static bool layers_poll(bContext *C) /*********************** Sculpt Vertex colors operators ************************/ -int ED_mesh_sculpt_color_add(Mesh *me, - const char *name, - const bool do_init, - ReportList * /*reports*/) +int ED_mesh_sculpt_color_add(Mesh *me, const char *name, const bool do_init, ReportList *reports) { - /* NOTE: keep in sync with #ED_mesh_uv_add. */ - - BMEditMesh *em; - int layernum; - - if (me->edit_mesh) { - em = me->edit_mesh; - - layernum = CustomData_number_of_layers(&em->bm->vdata, CD_PROP_COLOR); - - /* CD_PROP_COLOR */ - BM_data_layer_add_named(em->bm, &em->bm->vdata, CD_PROP_COLOR, name); - /* copy data from active vertex color layer */ - if (layernum && do_init) { - const int layernum_dst = CustomData_get_active_layer(&em->bm->vdata, CD_PROP_COLOR); - BM_data_layer_copy(em->bm, &em->bm->vdata, CD_PROP_COLOR, layernum_dst, layernum); - } - if (layernum == 0) { - CustomData_set_layer_active(&em->bm->vdata, CD_PROP_COLOR, layernum); - } + /* If no name is supplied, provide a backwards compatible default. */ + if (!name) { + name = "Color"; } - else { - layernum = CustomData_number_of_layers(&me->vdata, CD_PROP_COLOR); - if (CustomData_has_layer(&me->vdata, CD_PROP_COLOR) && do_init) { - const MPropCol *color_data = (const MPropCol *)CustomData_get_layer(&me->vdata, - CD_PROP_COLOR); - CustomData_add_layer_named( - &me->vdata, CD_PROP_COLOR, CD_DUPLICATE, (MPropCol *)color_data, me->totvert, name); - } - else { - CustomData_add_layer_named( - &me->vdata, CD_PROP_COLOR, CD_SET_DEFAULT, nullptr, me->totvert, name); - } + if (const CustomDataLayer *layer = BKE_id_attribute_find( + &me->id, me->active_color_attribute, CD_PROP_COLOR, ATTR_DOMAIN_POINT)) { + int dummy; + const CustomData *data = mesh_customdata_get_type(me, BM_LOOP, &dummy); + return CustomData_get_named_layer(data, CD_PROP_BYTE_COLOR, layer->name); + } - if (layernum == 0) { - CustomData_set_layer_active(&me->vdata, CD_PROP_COLOR, layernum); - } + CustomDataLayer *layer = BKE_id_attribute_new( + &me->id, name, CD_PROP_COLOR, ATTR_DOMAIN_POINT, reports); - BKE_mesh_tessface_clear(me); + if (do_init) { + const char *active_name = me->active_color_attribute; + if (const CustomDataLayer *active_layer = BKE_id_attributes_color_find(&me->id, active_name)) { + if (const BMEditMesh *em = me->edit_mesh) { + BMesh &bm = *em->bm; + const int src_i = CustomData_get_named_layer(&bm.vdata, CD_PROP_COLOR, active_name); + const int dst_i = CustomData_get_named_layer(&bm.vdata, CD_PROP_COLOR, layer->name); + BM_data_layer_copy(&bm, &bm.vdata, CD_PROP_COLOR, src_i, dst_i); + } + else { + memcpy(layer->data, active_layer->data, CustomData_get_elem_size(layer) * me->totloop); + } + } } DEG_id_tag_update(&me->id, 0); WM_main_add_notifier(NC_GEOM | ND_DATA, me); - return layernum; + int dummy; + const CustomData *data = mesh_customdata_get_type(me, BM_VERT, &dummy); + return CustomData_get_named_layer(data, CD_PROP_COLOR, layer->name); } /*********************** UV texture operators ************************/ diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index d883388fbff..b2b24a88204 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -452,7 +452,7 @@ static bool bake_object_check(const Scene *scene, } if (target == R_BAKE_TARGET_VERTEX_COLORS) { - if (BKE_id_attributes_active_color_get(&me->id) == NULL) { + if (!BKE_id_attributes_color_find(&me->id, me->active_color_attribute)) { BKE_reportf(reports, RPT_ERROR, "Mesh does not have an active color attribute \"%s\"", @@ -950,7 +950,7 @@ static bool bake_targets_init_vertex_colors(Main *bmain, } Mesh *me = ob->data; - if (BKE_id_attributes_active_color_get(&me->id) == NULL) { + if (!BKE_id_attributes_color_find(&me->id, me->active_color_attribute)) { BKE_report(reports, RPT_ERROR, "No active color attribute to bake to"); return false; } @@ -1131,7 +1131,8 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) { Mesh *me = ob->data; BMEditMesh *em = me->edit_mesh; - CustomDataLayer *active_color_layer = BKE_id_attributes_active_color_get(&me->id); + CustomDataLayer *active_color_layer = BKE_id_attributes_color_find(&me->id, + me->active_color_attribute); BLI_assert(active_color_layer != NULL); const eAttrDomain domain = BKE_id_attribute_domain(&me->id, active_color_layer); diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 2401fdf2d93..3a98108989e 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -858,6 +858,28 @@ static bool modifier_apply_shape(Main *bmain, return true; } +static void remove_invalid_attribute_strings(Mesh &mesh) +{ + using namespace blender; + bke::AttributeAccessor attributes = mesh.attributes(); + if (mesh.active_color_attribute) { + const std::optional meta_data = attributes.lookup_meta_data( + mesh.active_color_attribute); + if (!meta_data || !(meta_data->domain & ATTR_DOMAIN_MASK_COLOR) || + !(meta_data->data_type & CD_MASK_COLOR_ALL)) { + MEM_freeN(mesh.active_color_attribute); + } + } + if (mesh.default_color_attribute) { + const std::optional meta_data = attributes.lookup_meta_data( + mesh.default_color_attribute); + if (!meta_data || !(meta_data->domain & ATTR_DOMAIN_MASK_COLOR) || + !(meta_data->data_type & CD_MASK_COLOR_ALL)) { + MEM_freeN(mesh.default_color_attribute); + } + } +} + static bool modifier_apply_obdata( ReportList *reports, Depsgraph *depsgraph, Scene *scene, Object *ob, ModifierData *md_eval) { @@ -910,6 +932,9 @@ static bool modifier_apply_obdata( /* Anonymous attributes shouldn't be available on the applied geometry. */ me->attributes_for_write().remove_anonymous(); + /* Remove strings referring to attributes if they no longer exist. */ + remove_invalid_attribute_strings(*me); + if (md_eval->type == eModifierType_Multires) { multires_customdata_delete(me); } diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.cc b/source/blender/editors/sculpt_paint/paint_image_proj.cc index 3a13f212f0d..4eeeb760b23 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.cc +++ b/source/blender/editors/sculpt_paint/paint_image_proj.cc @@ -6553,10 +6553,10 @@ static CustomDataLayer *proj_paint_color_attribute_create(wmOperator *op, Object return nullptr; } - BKE_id_attributes_active_color_set(id, layer); + BKE_id_attributes_active_color_set(id, layer->name); - if (!BKE_id_attributes_render_color_get(id)) { - BKE_id_attributes_render_color_set(id, layer); + if (!BKE_id_attributes_default_color_get(id)) { + BKE_id_attributes_default_color_set(id, layer->name); } BKE_object_attributes_active_color_fill(ob, color, false); diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc index 6306e3b31a3..db23fc564f6 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -136,14 +136,14 @@ struct NormalAnglePrecalc { /* Returns number of elements. */ static int get_vcol_elements(Mesh *me, size_t *r_elem_size) { - const CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); - const eAttrDomain domain = BKE_id_attribute_domain(&me->id, layer); + const std::optional meta_data = me->attributes().lookup_meta_data( + me->active_color_attribute); if (r_elem_size) { - *r_elem_size = layer->type == CD_PROP_COLOR ? sizeof(float) * 4ULL : 4ULL; + *r_elem_size = meta_data->data_type == CD_PROP_COLOR ? sizeof(float[4]) : 4ULL; } - switch (domain) { + switch (meta_data->domain) { case ATTR_DOMAIN_POINT: return me->totvert; case ATTR_DOMAIN_CORNER: @@ -234,15 +234,20 @@ static void paint_last_stroke_update(Scene *scene, const float location[3]) bool vertex_paint_mode_poll(bContext *C) { const Object *ob = CTX_data_active_object(C); + if (!ob) { + return false; + } + const Mesh *mesh = static_cast(ob->data); - if (!(ob && ob->mode == OB_MODE_VERTEX_PAINT && ((const Mesh *)ob->data)->totpoly)) { + if (!(ob->mode == OB_MODE_VERTEX_PAINT && mesh->totpoly)) { return false; } - const CustomDataLayer *layer = BKE_id_attributes_active_color_get( - static_cast(ob->data)); + if (!mesh->attributes().contains(mesh->active_color_attribute)) { + return false; + } - return layer != nullptr; + return true; } static bool vertex_paint_poll_ex(bContext *C, bool check_tool) @@ -2845,8 +2850,6 @@ static void *vpaint_init_vpaint(bContext *C, { VPaintData *vpd; - size_t elem_size; - int elem_num = get_vcol_elements(me, &elem_size); /* make mode data storage */ vpd = MEM_new>("VPaintData"); @@ -2870,12 +2873,11 @@ static void *vpaint_init_vpaint(bContext *C, vpd->is_texbrush = !(brush->vertexpaint_tool == VPAINT_TOOL_BLUR) && brush->mtex.tex; if (brush->vertexpaint_tool == VPAINT_TOOL_SMEAR) { - CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); + const GVArray attribute = me->attributes().lookup(me->active_color_attribute, domain); + vpd->smear.color_prev = MEM_malloc_arrayN(attribute.size(), attribute.type().size(), __func__); + attribute.materialize(vpd->smear.color_prev); - vpd->smear.color_prev = MEM_malloc_arrayN(elem_num, elem_size, __func__); - memcpy(vpd->smear.color_prev, layer->data, elem_size * elem_num); - - vpd->smear.color_curr = (uint *)MEM_dupallocN(vpd->smear.color_prev); + vpd->smear.color_curr = MEM_dupallocN(vpd->smear.color_prev); } /* Create projection handle */ @@ -2908,30 +2910,31 @@ static bool vpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo ED_mesh_color_ensure(me, nullptr); - CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); - if (!layer) { + const std::optional meta_data = me->attributes().lookup_meta_data( + me->active_color_attribute); + + if (!meta_data) { return false; } - eAttrDomain domain = BKE_id_attribute_domain(&me->id, layer); void *vpd = nullptr; - if (domain == ATTR_DOMAIN_POINT) { - if (layer->type == CD_PROP_COLOR) { + if (meta_data->domain == ATTR_DOMAIN_POINT) { + if (meta_data->data_type == CD_PROP_COLOR) { vpd = vpaint_init_vpaint( C, op, scene, depsgraph, vp, ob, me, brush); } - else if (layer->type == CD_PROP_BYTE_COLOR) { + else if (meta_data->data_type == CD_PROP_BYTE_COLOR) { vpd = vpaint_init_vpaint( C, op, scene, depsgraph, vp, ob, me, brush); } } - else if (domain == ATTR_DOMAIN_CORNER) { - if (layer->type == CD_PROP_COLOR) { + else if (meta_data->domain == ATTR_DOMAIN_CORNER) { + if (meta_data->data_type == CD_PROP_COLOR) { vpd = vpaint_init_vpaint( C, op, scene, depsgraph, vp, ob, me, brush); } - else if (layer->type == CD_PROP_BYTE_COLOR) { + else if (meta_data->data_type == CD_PROP_BYTE_COLOR) { vpd = vpaint_init_vpaint( C, op, scene, depsgraph, vp, ob, me, brush); } @@ -3753,12 +3756,16 @@ static void vpaint_do_paint(bContext *C, int totnode; PBVHNode **nodes = vwpaint_pbvh_gather_generic(ob, vp, sd, brush, &totnode); - CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); - Color *color_data = static_cast(layer->data); + bke::GSpanAttributeWriter attribute = me->attributes_for_write().lookup_for_write_span( + me->active_color_attribute); + BLI_assert(attribute.domain == domain); + + Color *color_data = static_cast(attribute.span.data()); /* Paint those leaves. */ vpaint_paint_leaves(C, sd, vp, vpd, ob, me, color_data, nodes, totnode); + attribute.finish(); if (nodes) { MEM_freeN(nodes); } @@ -4075,98 +4082,114 @@ void PAINT_OT_vertex_paint(wmOperatorType *ot) /** \name Set Vertex Colors Operator * \{ */ -template -static bool vertex_color_set(Object *ob, ColorPaint4f paintcol_in, CustomDataLayer *layer) +template +static void fill_bm_face_or_corner_attribute(BMesh &bm, + const T &value, + const eAttrDomain domain, + const int cd_offset, + const bool use_vert_sel) { - Mesh *me; - if (((me = BKE_mesh_from_object(ob)) == nullptr) || - (ED_mesh_color_ensure(me, nullptr) == false)) { - return false; + BMFace *f; + BMIter iter; + BM_ITER_MESH (f, &iter, &bm, BM_FACES_OF_MESH) { + BMLoop *l = f->l_first; + do { + if (!(use_vert_sel && !BM_elem_flag_test(l->v, BM_ELEM_SELECT))) { + if (domain == ATTR_DOMAIN_CORNER) { + *static_cast(BM_ELEM_CD_GET_VOID_P(l, cd_offset)) = value; + } + else if (domain == ATTR_DOMAIN_POINT) { + *static_cast(BM_ELEM_CD_GET_VOID_P(l->v, cd_offset)) = value; + } + } + } while ((l = l->next) != f->l_first); } +} - const blender::VArray select_vert = me->attributes().lookup_or_default( +template +static void fill_mesh_face_or_corner_attribute(Mesh &mesh, + const T &value, + const eAttrDomain domain, + const MutableSpan data, + const bool use_vert_sel, + const bool use_face_sel) +{ + const VArray select_vert = mesh.attributes().lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); - const blender::VArray select_poly = me->attributes().lookup_or_default( + const VArray select_poly = mesh.attributes().lookup_or_default( ".select_poly", ATTR_DOMAIN_FACE, false); - Color paintcol = fromFloat(paintcol_in); + const Span polys = mesh.polys(); + const Span loops = mesh.loops(); - const bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; - const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; - - if (me->edit_mesh) { - BMesh *bm = me->edit_mesh->bm; - BMFace *f; - BMIter iter; - - int cd_offset = -1; - - /* Find customdata offset inside of bmesh. */ - CustomData *cdata = domain == ATTR_DOMAIN_POINT ? &bm->vdata : &bm->ldata; - - for (int i = 0; i < cdata->totlayer; i++) { - if (STREQ(cdata->layers[i].name, layer->name)) { - cd_offset = layer->offset; - } + for (const int i : polys.index_range()) { + if (use_face_sel && !select_poly[i]) { + continue; } + const MPoly &poly = polys[i]; - BLI_assert(cd_offset != -1); + int j = 0; + do { + uint vidx = loops[poly.loopstart + j].v; - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - Color *color; - BMLoop *l = f->l_first; - - do { - if (!(use_vert_sel && !BM_elem_flag_test(l->v, BM_ELEM_SELECT))) { - if constexpr (domain == ATTR_DOMAIN_CORNER) { - color = static_cast(BM_ELEM_CD_GET_VOID_P(l, cd_offset)); - } - else { - color = static_cast(BM_ELEM_CD_GET_VOID_P(l->v, cd_offset)); - } - - *color = paintcol; + if (!(use_vert_sel && !(select_vert[vidx]))) { + if (domain == ATTR_DOMAIN_CORNER) { + data[poly.loopstart + j] = value; } - } while ((l = l->next) != f->l_first); + else { + data[vidx] = value; + } + } + j++; + } while (j < poly.totloop); + } + + BKE_mesh_tessface_clear(&mesh); +} + +static void fill_mesh_color(Mesh &mesh, + const ColorPaint4f &color, + const StringRef attribute_name, + const bool use_vert_sel, + const bool use_face_sel) +{ + if (mesh.edit_mesh) { + BMesh *bm = mesh.edit_mesh->bm; + const std::string name = attribute_name; + const CustomDataLayer *layer = BKE_id_attributes_color_find(&mesh.id, name.c_str()); + const eAttrDomain domain = BKE_id_attribute_domain(&mesh.id, layer); + if (layer->type == CD_PROP_COLOR) { + fill_bm_face_or_corner_attribute( + *bm, color, domain, layer->offset, use_vert_sel); + } + else if (layer->type == CD_PROP_BYTE_COLOR) { + fill_bm_face_or_corner_attribute( + *bm, color.encode(), domain, layer->offset, use_vert_sel); } } else { - Color *color_layer = static_cast(layer->data); - const Span polys = me->polys(); - const Span loops = me->loops(); - - for (const int i : polys.index_range()) { - if (use_face_sel && !select_poly[i]) { - continue; - } - const MPoly &poly = polys[i]; - - int j = 0; - do { - uint vidx = loops[poly.loopstart + j].v; - - if (!(use_vert_sel && !(select_vert[vidx]))) { - if constexpr (domain == ATTR_DOMAIN_CORNER) { - color_layer[poly.loopstart + j] = paintcol; - } - else { - color_layer[vidx] = paintcol; - } - } - j++; - } while (j < poly.totloop); + bke::GSpanAttributeWriter attribute = mesh.attributes_for_write().lookup_for_write_span( + attribute_name); + if (attribute.span.type().is()) { + fill_mesh_face_or_corner_attribute( + mesh, + color, + attribute.domain, + attribute.span.typed().cast(), + use_vert_sel, + use_face_sel); } - - /* remove stale me->mcol, will be added later */ - BKE_mesh_tessface_clear(me); + else if (attribute.span.type().is()) { + fill_mesh_face_or_corner_attribute( + mesh, + color.encode(), + attribute.domain, + attribute.span.typed().cast(), + use_vert_sel, + use_face_sel); + } + attribute.finish(); } - - DEG_id_tag_update(&me->id, ID_RECALC_COPY_ON_WRITE); - - /* NOTE: Original mesh is used for display, so tag it directly here. */ - BKE_mesh_batch_cache_dirty_tag(me, BKE_MESH_BATCH_DIRTY_ALL); - - return true; } /** @@ -4176,46 +4199,26 @@ static bool paint_object_attributes_active_color_fill_ex(Object *ob, ColorPaint4f fill_color, bool only_selected = true) { - Mesh *me = BKE_object_get_original_mesh(ob); + Mesh *me = BKE_mesh_from_object(ob); if (!me) { return false; } - CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); - if (!layer) { - return false; - } - /* Store original #Mesh.editflag. */ - const decltype(me->editflag) editflag = me->editflag; - if (!only_selected) { - me->editflag &= ~ME_EDIT_PAINT_FACE_SEL; - me->editflag &= ~ME_EDIT_PAINT_VERT_SEL; - } - eAttrDomain domain = BKE_id_attribute_domain(&me->id, layer); - bool ok = false; - if (domain == ATTR_DOMAIN_POINT) { - if (layer->type == CD_PROP_COLOR) { - ok = vertex_color_set(ob, fill_color, layer); - } - else if (layer->type == CD_PROP_BYTE_COLOR) { - ok = vertex_color_set(ob, fill_color, layer); - } - } - else { - if (layer->type == CD_PROP_COLOR) { - ok = vertex_color_set(ob, fill_color, layer); - } - else if (layer->type == CD_PROP_BYTE_COLOR) { - ok = vertex_color_set(ob, fill_color, layer); - } - } - /* Restore #Mesh.editflag. */ - me->editflag = editflag; - return ok; + + const bool use_face_sel = only_selected ? (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0 : false; + const bool use_vert_sel = only_selected ? (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0 : false; + fill_mesh_color(*me, fill_color, me->active_color_attribute, use_vert_sel, use_face_sel); + + DEG_id_tag_update(&me->id, ID_RECALC_COPY_ON_WRITE); + + /* NOTE: Original mesh is used for display, so tag it directly here. */ + BKE_mesh_batch_cache_dirty_tag(me, BKE_MESH_BATCH_DIRTY_ALL); + + return true; } -extern "C" bool BKE_object_attributes_active_color_fill(Object *ob, - const float fill_color[4], - bool only_selected) +bool BKE_object_attributes_active_color_fill(Object *ob, + const float fill_color[4], + bool only_selected) { return paint_object_attributes_active_color_fill_ex(ob, ColorPaint4f(fill_color), only_selected); } diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc index 09374422888..bb8a298503c 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc @@ -77,8 +77,7 @@ static bool vertex_paint_from_weight(Object *ob) return false; } - const CustomDataLayer *active_color_layer = BKE_id_attributes_active_color_get(&me->id); - if (active_color_layer == nullptr) { + if (!me->attributes().contains(me->active_color_attribute)) { BLI_assert_unreachable(); return false; } @@ -93,7 +92,7 @@ static bool vertex_paint_from_weight(Object *ob) bke::MutableAttributeAccessor attributes = me->attributes_for_write(); - bke::GAttributeWriter color_attribute = attributes.lookup_for_write(active_color_layer->name); + bke::GAttributeWriter color_attribute = attributes.lookup_for_write(me->active_color_attribute); if (!color_attribute) { BLI_assert_unreachable(); return false; @@ -178,25 +177,22 @@ static IndexMask get_selected_indices(const Mesh &mesh, static void face_corner_color_equalize_verts(Mesh &mesh, const IndexMask selection) { using namespace blender; - - const CustomDataLayer *active_color_layer = BKE_id_attributes_active_color_get(&mesh.id); - if (active_color_layer == nullptr) { + const StringRef name = mesh.active_color_attribute; + bke::MutableAttributeAccessor attributes = mesh.attributes_for_write(); + bke::GSpanAttributeWriter attribute = attributes.lookup_for_write_span(name); + if (!attribute) { BLI_assert_unreachable(); return; } - - bke::AttributeAccessor attributes = mesh.attributes(); - - if (attributes.lookup_meta_data(active_color_layer->name)->domain == ATTR_DOMAIN_POINT) { + if (attribute.domain == ATTR_DOMAIN_POINT) { return; } - GVArray color_attribute_point = attributes.lookup(active_color_layer->name, ATTR_DOMAIN_POINT); - + GVArray color_attribute_point = attributes.lookup(name, ATTR_DOMAIN_POINT); GVArray color_attribute_corner = attributes.adapt_domain( color_attribute_point, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CORNER); - - color_attribute_corner.materialize(selection, active_color_layer->data); + color_attribute_corner.materialize(selection, attribute.span.data()); + attribute.finish(); } static bool vertex_color_smooth(Object *ob) @@ -252,16 +248,14 @@ template static bool transform_active_color(Mesh &mesh, const TransformFn &transform_fn) { using namespace blender; - - const CustomDataLayer *active_color_layer = BKE_id_attributes_active_color_get(&mesh.id); - if (active_color_layer == nullptr) { + const StringRef name = mesh.active_color_attribute; + bke::MutableAttributeAccessor attributes = mesh.attributes_for_write(); + if (!attributes.contains(name)) { BLI_assert_unreachable(); return false; } - bke::MutableAttributeAccessor attributes = mesh.attributes_for_write(); - - bke::GAttributeWriter color_attribute = attributes.lookup_for_write(active_color_layer->name); + bke::GAttributeWriter color_attribute = attributes.lookup_for_write(name); if (!color_attribute) { BLI_assert_unreachable(); return false; diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 416f394e8ee..654083605da 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -31,6 +31,7 @@ #include "DNA_scene_types.h" #include "BKE_attribute.h" +#include "BKE_attribute.hh" #include "BKE_brush.h" #include "BKE_ccg.h" #include "BKE_colortools.h" @@ -131,10 +132,20 @@ const float *SCULPT_vertex_co_get(SculptSession *ss, PBVHVertRef vertex) bool SCULPT_has_loop_colors(const Object *ob) { + using namespace blender; Mesh *me = BKE_object_get_original_mesh(ob); - const CustomDataLayer *layer = BKE_id_attributes_active_color_get(&me->id); - - return layer && BKE_id_attribute_domain(&me->id, layer) == ATTR_DOMAIN_CORNER; + const std::optional meta_data = me->attributes().lookup_meta_data( + me->active_color_attribute); + if (!meta_data) { + return false; + } + if (meta_data->domain != ATTR_DOMAIN_CORNER) { + return false; + } + if (!(CD_TYPE_AS_MASK(meta_data->data_type) & CD_MASK_COLOR_ALL)) { + return false; + } + return true; } bool SCULPT_has_colors(const SculptSession *ss) diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index ef8339d8971..e5cb9c924b6 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -1860,7 +1860,7 @@ static void sculpt_undo_set_active_layer(struct bContext *C, SculptAttrRef *attr } if (layer) { - BKE_id_attributes_active_color_set(&me->id, layer); + BKE_id_attributes_active_color_set(&me->id, layer->name); if (ob->sculpt && ob->sculpt->pbvh) { BKE_pbvh_update_active_vcol(ob->sculpt->pbvh, me); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index 1c51ff02aaf..fa93a44af66 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -26,6 +26,7 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "BKE_attribute.h" #include "BKE_collection.h" #include "BKE_customdata.h" #include "BKE_global.h" @@ -606,7 +607,8 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex) &mesh->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, nullptr, mesh->totloop, "Color"); MLoopCol *transp = (MLoopCol *)CustomData_add_layer_named( &mesh->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, nullptr, mesh->totloop, "Alpha"); - CustomData_set_layer_active(&mesh->ldata, CD_PROP_BYTE_COLOR, 0); + BKE_id_attributes_active_color_set( + &mesh->id, CustomData_get_layer_name(&mesh->ldata, CD_PROP_BYTE_COLOR, 0)); mesh->mat = (Material **)MEM_mallocN(sizeof(Material *) * mesh->totcol, "MaterialList"); for (const auto item : group->materials.items()) { diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 57a4ae70b5f..2e6fb87e823 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -1125,6 +1125,15 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, } }); + if (first_mesh.active_color_attribute) { + MEM_SAFE_FREE(dst_mesh->active_color_attribute); + dst_mesh->active_color_attribute = BLI_strdup(first_mesh.active_color_attribute); + } + if (first_mesh.default_color_attribute) { + MEM_SAFE_FREE(dst_mesh->default_color_attribute); + dst_mesh->default_color_attribute = BLI_strdup(first_mesh.default_color_attribute); + } + /* Tag modified attributes. */ for (GSpanAttributeWriter &dst_attribute : dst_attribute_writers) { dst_attribute.finish(); diff --git a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc index 48a5c52bebc..cebdab2c415 100644 --- a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc +++ b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc @@ -111,26 +111,6 @@ void UI_GetThemeColorShadeAlpha4ubv(int /*colorid*/, /** \name Stubs of BKE_attribute.h * \{ */ -void BKE_id_attribute_copy_domains_temp(short /*id_type*/, - const struct CustomData * /*vdata*/, - const struct CustomData * /*edata*/, - const struct CustomData * /*ldata*/, - const struct CustomData * /*pdata*/, - const struct CustomData * /*cdata*/, - struct ID * /*r_id*/) -{ -} - -struct CustomDataLayer *BKE_id_attributes_active_color_get(const struct ID * /*id*/) -{ - return nullptr; -} - -struct CustomDataLayer *BKE_id_attributes_render_color_get(const struct ID * /*id*/) -{ - return nullptr; -} - eAttrDomain BKE_id_attribute_domain(const struct ID * /*id*/, const struct CustomDataLayer * /*layer*/) { diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp index 3f676fa9df9..436d919f8d5 100644 --- a/source/blender/io/collada/MeshImporter.cpp +++ b/source/blender/io/collada/MeshImporter.cpp @@ -16,6 +16,7 @@ #include "MEM_guardedalloc.h" +#include "BKE_attribute.h" #include "BKE_customdata.h" #include "BKE_displist.h" #include "BKE_global.h" @@ -486,7 +487,8 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me) CustomData_add_layer_named( &me->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, nullptr, me->totloop, colname.c_str()); } - CustomData_set_layer_active(&me->ldata, CD_PROP_BYTE_COLOR, 0); + BKE_id_attributes_active_color_set( + &me->id, CustomData_get_layer_name(&me->ldata, CD_PROP_BYTE_COLOR, 0)); } } } diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc index 599357ece37..909c179dda3 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc @@ -251,14 +251,11 @@ void OBJWriter::write_vertex_coords(FormatHandler &fh, const int tot_count = obj_mesh_data.tot_vertices(); const Mesh *mesh = obj_mesh_data.get_mesh(); - const CustomDataLayer *colors_layer = nullptr; - if (write_colors) { - colors_layer = BKE_id_attributes_active_color_get(&mesh->id); - } - if (write_colors && (colors_layer != nullptr)) { + const StringRef name = mesh->active_color_attribute; + if (write_colors && !name.is_empty()) { const bke::AttributeAccessor attributes = mesh->attributes(); const VArray attribute = attributes.lookup_or_default( - colors_layer->name, ATTR_DOMAIN_POINT, {0.0f, 0.0f, 0.0f, 0.0f}); + name, ATTR_DOMAIN_POINT, {0.0f, 0.0f, 0.0f, 0.0f}); BLI_assert(tot_count == attribute.size()); obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) { diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc index b2b49457051..42293a9b992 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc @@ -376,6 +376,7 @@ void MeshFromGeometry::create_colors(Mesh *mesh) /* This block is suitable, use colors from it. */ CustomDataLayer *color_layer = BKE_id_attribute_new( &mesh->id, "Color", CD_PROP_COLOR, ATTR_DOMAIN_POINT, nullptr); + BKE_id_attributes_active_color_set(&mesh->id, color_layer->name); float4 *colors = (float4 *)color_layer->data; int offset = mesh_geometry_.vertex_index_min_ - block.start_vertex_index; for (int i = 0, n = mesh_geometry_.get_vertex_count(); i != n; ++i) { diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 0355ed3febe..5a534fa7904 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -244,8 +244,10 @@ enum { CD_FLAG_EXTERNAL = (1 << 3), /* Indicates external data is read into memory */ CD_FLAG_IN_MEMORY = (1 << 4), +#ifdef DNA_DEPRECATED_ALLOW CD_FLAG_COLOR_ACTIVE = (1 << 5), CD_FLAG_COLOR_RENDER = (1 << 6) +#endif }; /* Limits */ diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 7a28485c768..5e04c23445d 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -151,6 +151,11 @@ typedef struct Mesh { * default and Face Sets can be used without affecting the color of the mesh. */ int face_sets_color_default; + /** The color attribute currently selected in the list and edited by a user. */ + char *active_color_attribute; + /** The color attribute used by default (i.e. for rendering) if no name is given explicitly. */ + char *default_color_attribute; + /** * User-defined symmetry flag (#eMeshSymmetryType) that causes editing operations to maintain * symmetrical geometry. Supported by operations such as transform and weight-painting. diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c index d65159af28a..1fd7ce85125 100644 --- a/source/blender/makesrna/intern/rna_attribute.c +++ b/source/blender/makesrna/intern/rna_attribute.c @@ -560,7 +560,10 @@ static void rna_AttributeGroup_update_active(Main *bmain, Scene *scene, PointerR static PointerRNA rna_AttributeGroup_active_color_get(PointerRNA *ptr) { ID *id = ptr->owner_id; - CustomDataLayer *layer = BKE_id_attributes_active_color_get(id); + CustomDataLayer *layer = BKE_id_attribute_search(ptr->owner_id, + BKE_id_attributes_active_color_name(id), + CD_MASK_COLOR_ALL, + ATTR_DOMAIN_MASK_COLOR); PointerRNA attribute_ptr; RNA_pointer_create(id, &RNA_Attribute, layer, &attribute_ptr); @@ -573,13 +576,16 @@ static void rna_AttributeGroup_active_color_set(PointerRNA *ptr, { ID *id = ptr->owner_id; CustomDataLayer *layer = attribute_ptr.data; - - BKE_id_attributes_active_color_set(id, layer); + BKE_id_attributes_active_color_set(id, layer->name); } static int rna_AttributeGroup_active_color_index_get(PointerRNA *ptr) { - const CustomDataLayer *layer = BKE_id_attributes_active_color_get(ptr->owner_id); + const CustomDataLayer *layer = BKE_id_attribute_search( + ptr->owner_id, + BKE_id_attributes_active_color_name(ptr->owner_id), + CD_MASK_COLOR_ALL, + ATTR_DOMAIN_MASK_COLOR); return BKE_id_attribute_to_index( ptr->owner_id, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); @@ -595,7 +601,7 @@ static void rna_AttributeGroup_active_color_index_set(PointerRNA *ptr, int value return; } - BKE_id_attributes_active_color_set(ptr->owner_id, layer); + BKE_id_attributes_active_color_set(ptr->owner_id, layer->name); } static void rna_AttributeGroup_active_color_index_range( @@ -623,7 +629,8 @@ static void rna_AttributeGroup_update_active_color(Main *UNUSED(bmain), static int rna_AttributeGroup_render_color_index_get(PointerRNA *ptr) { - CustomDataLayer *layer = BKE_id_attributes_render_color_get(ptr->owner_id); + const CustomDataLayer *layer = BKE_id_attributes_color_find( + ptr->owner_id, BKE_id_attributes_default_color_name(ptr->owner_id)); return BKE_id_attribute_to_index( ptr->owner_id, layer, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL); @@ -639,7 +646,7 @@ static void rna_AttributeGroup_render_color_index_set(PointerRNA *ptr, int value return; } - BKE_id_attributes_render_color_set(ptr->owner_id, layer); + BKE_id_attributes_default_color_set(ptr->owner_id, layer->name); } static void rna_AttributeGroup_render_color_index_range( @@ -655,43 +662,61 @@ static void rna_AttributeGroup_render_color_index_range( static void rna_AttributeGroup_default_color_name_get(PointerRNA *ptr, char *value) { const ID *id = ptr->owner_id; - const CustomDataLayer *layer = BKE_id_attributes_render_color_get(id); - if (!layer) { + const char *name = BKE_id_attributes_default_color_name(id); + if (!name) { value[0] = '\0'; return; } - BLI_strncpy(value, layer->name, MAX_CUSTOMDATA_LAYER_NAME); + BLI_strncpy(value, name, MAX_CUSTOMDATA_LAYER_NAME); } static int rna_AttributeGroup_default_color_name_length(PointerRNA *ptr) { const ID *id = ptr->owner_id; - const CustomDataLayer *layer = BKE_id_attributes_render_color_get(id); - if (!layer) { - return 0; + const char *name = BKE_id_attributes_default_color_name(id); + return name ? strlen(name) : 0; +} + +static void rna_AttributeGroup_default_color_name_set(PointerRNA *ptr, const char *value) +{ + ID *id = ptr->owner_id; + if (GS(id->name) == ID_ME) { + Mesh *mesh = (Mesh *)id; + MEM_SAFE_FREE(mesh->default_color_attribute); + if (value[0]) { + mesh->default_color_attribute = BLI_strdup(value); + } } - return strlen(layer->name); } static void rna_AttributeGroup_active_color_name_get(PointerRNA *ptr, char *value) { const ID *id = ptr->owner_id; - const CustomDataLayer *layer = BKE_id_attributes_active_color_get(id); - if (!layer) { + const char *name = BKE_id_attributes_active_color_name(id); + if (!name) { value[0] = '\0'; return; } - BLI_strncpy(value, layer->name, MAX_CUSTOMDATA_LAYER_NAME); + BLI_strncpy(value, name, MAX_CUSTOMDATA_LAYER_NAME); } static int rna_AttributeGroup_active_color_name_length(PointerRNA *ptr) { const ID *id = ptr->owner_id; - const CustomDataLayer *layer = BKE_id_attributes_active_color_get(id); - if (!layer) { - return 0; + const char *name = BKE_id_attributes_active_color_name(id); + return name ? strlen(name) : 0; +} + +static void rna_AttributeGroup_active_color_name_set(PointerRNA *ptr, const char *value) +{ + ID *id = ptr->owner_id; + if (GS(id->name) == ID_ME) { + Mesh *mesh = (Mesh *)id; + MEM_SAFE_FREE(mesh->default_color_attribute); + if (value[0]) { + mesh->default_color_attribute = BLI_strdup(value); + } } - return strlen(layer->name); } #else @@ -1160,7 +1185,7 @@ static void rna_def_attribute_group(BlenderRNA *brna) RNA_def_property_string_funcs(prop, "rna_AttributeGroup_default_color_name_get", "rna_AttributeGroup_default_color_name_length", - NULL); + "rna_AttributeGroup_default_color_name_set"); RNA_def_property_ui_text( prop, "Default Color Attribute", @@ -1172,7 +1197,7 @@ static void rna_def_attribute_group(BlenderRNA *brna) RNA_def_property_string_funcs(prop, "rna_AttributeGroup_active_color_name_get", "rna_AttributeGroup_active_color_name_length", - NULL); + "rna_AttributeGroup_active_color_name_set"); RNA_def_property_ui_text(prop, "Active Color Attribute", "The name of the active color attribute for display and editing"); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 1141d7e75a4..71a4a4b37f4 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -171,7 +171,7 @@ static void rna_Material_active_paint_texture_index_update(bContext *C, PointerR Mesh *mesh = ob->data; CustomDataLayer *layer = BKE_id_attributes_color_find(&mesh->id, slot->attribute_name); if (layer != NULL) { - BKE_id_attributes_active_color_set(&mesh->id, layer); + BKE_id_attributes_active_color_set(&mesh->id, layer->name); } DEG_id_tag_update(&ob->id, 0); WM_main_add_notifier(NC_GEOM | ND_DATA, &ob->id); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 2ca465c95b8..7351ca1d8ca 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1037,12 +1037,16 @@ static int rna_MeshLoopColorLayer_data_length(PointerRNA *ptr) static bool rna_MeshLoopColorLayer_active_render_get(PointerRNA *ptr) { - return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_PROP_BYTE_COLOR, 1); + const Mesh *mesh = rna_mesh(ptr); + const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data; + return mesh->default_color_attribute && STREQ(mesh->default_color_attribute, layer->name); } static bool rna_MeshLoopColorLayer_active_get(PointerRNA *ptr) { - return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_PROP_BYTE_COLOR, 0); + const Mesh *mesh = rna_mesh(ptr); + const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data; + return mesh->active_color_attribute && STREQ(mesh->active_color_attribute, layer->name); } static void rna_MeshLoopColorLayer_active_render_set(PointerRNA *ptr, bool value) @@ -1077,12 +1081,16 @@ static int rna_MeshVertColorLayer_data_length(PointerRNA *ptr) static bool rna_MeshVertColorLayer_active_render_get(PointerRNA *ptr) { - return rna_CustomDataLayer_active_get(ptr, rna_mesh_vdata(ptr), CD_PROP_COLOR, 1); + const Mesh *mesh = rna_mesh(ptr); + const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data; + return mesh->default_color_attribute && STREQ(mesh->default_color_attribute, layer->name); } static bool rna_MeshVertColorLayer_active_get(PointerRNA *ptr) { - return rna_CustomDataLayer_active_get(ptr, rna_mesh_vdata(ptr), CD_PROP_COLOR, 0); + const Mesh *mesh = rna_mesh(ptr); + const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data; + return mesh->active_color_attribute && STREQ(mesh->active_color_attribute, layer->name); } static void rna_MeshVertColorLayer_active_render_set(PointerRNA *ptr, bool value) From 3d29bbcc387feea063b48ce747668d1143f312f7 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 15 Dec 2022 21:29:56 +0100 Subject: [PATCH 0152/1522] Fix T103049: Cycles specular light leak regression The logic here is not ideal but was unintentionally changed in refactoring for path guiding, now restore it back to 3.3 behavior again. --- intern/cycles/kernel/closure/bsdf.h | 8 ++--- .../kernel/closure/bsdf_ashikhmin_shirley.h | 7 ++-- .../cycles/kernel/closure/bsdf_microfacet.h | 34 +++++++++++-------- .../kernel/closure/bsdf_microfacet_multi.h | 4 ++- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index 2f5c5d7bd0c..6de645cd1fe 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -580,11 +580,11 @@ ccl_device_inline case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID: case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - eval = bsdf_microfacet_ggx_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_microfacet_ggx_eval(sc, sd->N, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: - eval = bsdf_microfacet_multi_ggx_eval(sc, sd->I, omega_in, pdf, &sd->lcg_state); + eval = bsdf_microfacet_multi_ggx_eval(sc, sd->N, sd->I, omega_in, pdf, &sd->lcg_state); break; case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: @@ -592,10 +592,10 @@ ccl_device_inline break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - eval = bsdf_microfacet_beckmann_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_microfacet_beckmann_eval(sc, sd->N, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: - eval = bsdf_ashikhmin_shirley_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_ashikhmin_shirley_eval(sc, sd->N, sd->I, omega_in, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: eval = bsdf_ashikhmin_velvet_eval(sc, sd->I, omega_in, pdf); diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h index 14a4094d485..db02dad3909 100644 --- a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h +++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h @@ -40,11 +40,13 @@ ccl_device_inline float bsdf_ashikhmin_shirley_roughness_to_exponent(float rough } ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval(ccl_private const ShaderClosure *sc, + const float3 Ng, const float3 I, const float3 omega_in, ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; + const float cosNgI = dot(Ng, omega_in); float3 N = bsdf->N; float NdotI = dot(N, I); /* in Cycles/OSL convention I is omega_out */ @@ -52,7 +54,8 @@ ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval(ccl_private const Sh float out = 0.0f; - if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f || !(NdotI > 0.0f && NdotO > 0.0f)) { + if ((cosNgI < 0.0f) || fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f || + !(NdotI > 0.0f && NdotO > 0.0f)) { *pdf = 0.0f; return zero_spectrum(); } @@ -210,7 +213,7 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc } else { /* leave the rest to eval */ - *eval = bsdf_ashikhmin_shirley_eval(sc, I, *omega_in, pdf); + *eval = bsdf_ashikhmin_shirley_eval(sc, N, I, *omega_in, pdf); } return label; diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 39d0fb8f5f5..dcd55dc9bd7 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -517,27 +517,30 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const Microfac } ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc, + const float3 Ng, const float3 I, const float3 omega_in, ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; + const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; const float alpha_x = bsdf->alpha_x; const float alpha_y = bsdf->alpha_y; - const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - const float3 N = bsdf->N; - const float cosNO = dot(N, I); - const float cosNI = dot(N, omega_in); + const float cosNgI = dot(Ng, omega_in); - if (((cosNI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) { + if (((cosNgI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) { *pdf = 0.0f; return zero_spectrum(); } - return (cosNI < 0.0f) ? bsdf_microfacet_ggx_eval_transmit( - bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) : - bsdf_microfacet_ggx_eval_reflect( - bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI); + const float3 N = bsdf->N; + const float cosNO = dot(N, I); + const float cosNI = dot(N, omega_in); + + return (cosNgI < 0.0f) ? bsdf_microfacet_ggx_eval_transmit( + bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) : + bsdf_microfacet_ggx_eval_reflect( + bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI); } ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, @@ -942,23 +945,26 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const Mic } ccl_device Spectrum bsdf_microfacet_beckmann_eval(ccl_private const ShaderClosure *sc, + const float3 Ng, const float3 I, const float3 omega_in, ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; + const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; const float alpha_x = bsdf->alpha_x; const float alpha_y = bsdf->alpha_y; - const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - const float3 N = bsdf->N; - const float cosNO = dot(N, I); - const float cosNI = dot(N, omega_in); + const float cosNgI = dot(Ng, omega_in); - if (((cosNI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) { + if (((cosNgI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) { *pdf = 0.0f; return zero_spectrum(); } + const float3 N = bsdf->N; + const float cosNO = dot(N, I); + const float cosNI = dot(N, omega_in); + return (cosNI < 0.0f) ? bsdf_microfacet_beckmann_eval_transmit( bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) : bsdf_microfacet_beckmann_eval_reflect( diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h index 73bbe80b2d4..29e1473160e 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h @@ -416,14 +416,16 @@ ccl_device int bsdf_microfacet_multi_ggx_refraction_setup(ccl_private Microfacet } ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosure *sc, + const float3 Ng, const float3 I, const float3 omega_in, ccl_private float *pdf, ccl_private uint *lcg_state) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; + const float cosNgI = dot(Ng, omega_in); - if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { + if ((cosNgI < 0.0f) || bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { *pdf = 0.0f; return zero_spectrum(); } From 2c22795dfdceed35b2c9d95da3f92f4ce9129025 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Dec 2022 18:09:40 +1100 Subject: [PATCH 0153/1522] Build: upgrade pre-built libraries for Linux Replace ../lib/linux_centos7_x86_64 with ../lib/linux_x86_64_glibc_228, built with Rocky8 Linux, compatible with the VFX platform CY2023, see: T99618. - Update build-bot configuration. - Remove unnecessary check for Blosc, this is part of OpenVDB lib now. - Remove WITH_CXX11_ABI, always use new C++11 ABI now - Replace centos7 by glibc_228 everywhere Note that existing builds with cached paths pointing to "../lib/linux_centos7_x86_64" will need to be updated. Includes contributions by Brecht. --- CMakeLists.txt | 11 ---------- GNUmakefile | 2 +- .../buildbot/config/blender_linux.cmake | 5 ++--- .../cmake/platform/platform_unix.cmake | 20 ++++++++----------- build_files/config/pipeline_config.yaml | 2 +- build_files/utils/make_update.py | 6 +++--- intern/cycles/kernel/CMakeLists.txt | 3 ++- 7 files changed, 17 insertions(+), 32 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4de2454cfd8..74bfb23a3a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -749,11 +749,6 @@ if("${CMAKE_GENERATOR}" MATCHES "Ninja") mark_as_advanced(WITH_NINJA_POOL_JOBS) endif() -if(UNIX AND NOT APPLE) - option(WITH_CXX11_ABI "Use native C++11 ABI of compiler" ON) - mark_as_advanced(WITH_CXX11_ABI) -endif() - # Installation process. set(POSTINSTALL_SCRIPT "" CACHE FILEPATH "Run given CMake script after installation process") mark_as_advanced(POSTINSTALL_SCRIPT) @@ -1721,12 +1716,6 @@ if( string(APPEND CMAKE_C_FLAGS " -std=gnu11") endif() -if(UNIX AND NOT APPLE) - if(NOT WITH_CXX11_ABI) - string(APPEND PLATFORM_CFLAGS " -D_GLIBCXX_USE_CXX11_ABI=0") - endif() -endif() - if(WITH_COMPILER_SHORT_FILE_MACRO) # Use '-fmacro-prefix-map' for Clang and GCC (MSVC doesn't support this). add_check_c_compiler_flag(C_PREFIX_MAP_FLAGS C_MACRO_PREFIX_MAP -fmacro-prefix-map=foo=bar) diff --git a/GNUmakefile b/GNUmakefile index 439b435f5f4..ba9ee978817 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -211,7 +211,7 @@ endif # Set the LIBDIR, an empty string when not found. LIBDIR:=$(wildcard ../lib/${OS_NCASE}_${CPU}) ifeq (, $(LIBDIR)) - LIBDIR:=$(wildcard ../lib/${OS_NCASE}_centos7_${CPU}) + LIBDIR:=$(wildcard ../lib/${OS_NCASE}_${CPU}_glibc_228) endif ifeq (, $(LIBDIR)) LIBDIR:=$(wildcard ../lib/${OS_NCASE}) diff --git a/build_files/buildbot/config/blender_linux.cmake b/build_files/buildbot/config/blender_linux.cmake index 3f3695ed481..ae7849002f7 100644 --- a/build_files/buildbot/config/blender_linux.cmake +++ b/build_files/buildbot/config/blender_linux.cmake @@ -4,10 +4,9 @@ include("${CMAKE_CURRENT_LIST_DIR}/../../cmake/config/blender_release.cmake") -message(STATUS "Building in CentOS 7 64bit environment") +message(STATUS "Building in Rocky 8 Linux 64bit environment") -set(LIBDIR_NAME "linux_centos7_x86_64") -set(WITH_CXX11_ABI OFF CACHE BOOL "" FORCE) +set(LIBDIR_NAME "linux_x86_64_glibc_228") # ######## Linux-specific build options ######## # Options which are specific to Linux-only platforms diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index bcc90cef7c2..cfb3ecc564b 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -10,16 +10,15 @@ if(NOT DEFINED LIBDIR) string(TOLOWER ${LIBDIR_NAME} LIBDIR_NAME) set(LIBDIR_NATIVE_ABI ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_NAME}) - # Path to precompiled libraries with known CentOS 7 ABI. - set(LIBDIR_CENTOS7_ABI ${CMAKE_SOURCE_DIR}/../lib/linux_centos7_x86_64) + # Path to precompiled libraries with known glibc 2.28 ABI. + set(LIBDIR_GLIBC228_ABI ${CMAKE_SOURCE_DIR}/../lib/linux_x86_64_glibc_228) # Choose the best suitable libraries. if(EXISTS ${LIBDIR_NATIVE_ABI}) set(LIBDIR ${LIBDIR_NATIVE_ABI}) set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True) - elseif(EXISTS ${LIBDIR_CENTOS7_ABI}) - set(LIBDIR ${LIBDIR_CENTOS7_ABI}) - set(WITH_CXX11_ABI OFF) + elseif(EXISTS ${LIBDIR_GLIBC228_ABI}) + set(LIBDIR ${LIBDIR_GLIBC228_ABI}) if(WITH_MEM_JEMALLOC) # jemalloc provides malloc hooks. set(WITH_LIBC_MALLOC_HOOK_WORKAROUND False) @@ -30,7 +29,7 @@ if(NOT DEFINED LIBDIR) # Avoid namespace pollustion. unset(LIBDIR_NATIVE_ABI) - unset(LIBDIR_CENTOS7_ABI) + unset(LIBDIR_GLIBC228_ABI) endif() # Support restoring this value once pre-compiled libraries have been handled. @@ -330,10 +329,8 @@ if(WITH_OPENVDB) find_package(OpenVDB) set_and_warn_library_found("OpenVDB" OPENVDB_FOUND WITH_OPENVDB) - if(OPENVDB_FOUND) - add_bundled_libraries(openvdb/lib) - find_package_wrapper(Blosc) - set_and_warn_library_found("Blosc" BLOSC_FOUND WITH_OPENVDB_BLOSC) + if(WITH_OPENVDB) + add_bundled_libraries(openvdb/lib) endif() endif() @@ -667,8 +664,7 @@ if(WITH_GHOST_WAYLAND) pkg_check_modules(wayland-protocols wayland-protocols>=1.15) pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir) else() - # CentOS 7 packages have too old a version, a newer version exist in the - # precompiled libraries. + # Rocky8 packages have too old a version, a newer version exist in the pre-compiled libraries. find_path(WAYLAND_PROTOCOLS_DIR NAMES unstable/xdg-decoration/xdg-decoration-unstable-v1.xml PATH_SUFFIXES share/wayland-protocols diff --git a/build_files/config/pipeline_config.yaml b/build_files/config/pipeline_config.yaml index d344b88f255..653c5eeb3b2 100644 --- a/build_files/config/pipeline_config.yaml +++ b/build_files/config/pipeline_config.yaml @@ -30,7 +30,7 @@ update-code: linux-x86_64: branch: trunk commit_id: HEAD - path: lib/linux_centos7_x86_64 + path: lib/linux_x86_64_glibc_228 windows-amd64: branch: trunk commit_id: HEAD diff --git a/build_files/utils/make_update.py b/build_files/utils/make_update.py index 93820ee994a..fbadeecd597 100755 --- a/build_files/utils/make_update.py +++ b/build_files/utils/make_update.py @@ -41,7 +41,7 @@ def parse_arguments() -> argparse.Namespace: parser.add_argument("--svn-command", default="svn") parser.add_argument("--svn-branch", default=None) parser.add_argument("--git-command", default="git") - parser.add_argument("--use-centos-libraries", action="store_true") + parser.add_argument("--use-linux-libraries", action="store_true") return parser.parse_args() @@ -71,8 +71,8 @@ def svn_update(args: argparse.Namespace, release_version: Optional[str]) -> None # this script is bundled as part of the precompiled libraries. However it # is used by the buildbot. lib_platform = "win64_vc15" - elif args.use_centos_libraries: - lib_platform = "linux_centos7_x86_64" + elif args.use_linux_libraries: + lib_platform = "linux_x86_64_glibc_228" else: # No precompiled libraries for Linux. lib_platform = None diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 22c52a5802f..dd0de5120fd 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -860,8 +860,9 @@ if(WITH_CYCLES_DEVICE_ONEAPI) else() list(APPEND sycl_compiler_flags -fPIC) - # We avoid getting __FAST_MATH__ to be defined when building on CentOS 7 until the compilation + # We avoid getting __FAST_MATH__ to be defined when building on CentOS-7 until the compilation # crash it triggers at either AoT or JIT stages gets fixed. + # TODO: check if this is still needed on Rocky-8. list(APPEND sycl_compiler_flags -fhonor-nans) # add $ORIGIN to cycles_kernel_oneapi.so rpath so libsycl.so and From e58f5422c37762ab5b4302e7481a9ffed023913a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Dec 2022 10:50:18 +1100 Subject: [PATCH 0154/1522] Cleanup: remove unused active name set callback functions --- .../blender/makesrna/intern/rna_attribute.c | 28 ++----------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c index 1fd7ce85125..efa87523204 100644 --- a/source/blender/makesrna/intern/rna_attribute.c +++ b/source/blender/makesrna/intern/rna_attribute.c @@ -677,18 +677,6 @@ static int rna_AttributeGroup_default_color_name_length(PointerRNA *ptr) return name ? strlen(name) : 0; } -static void rna_AttributeGroup_default_color_name_set(PointerRNA *ptr, const char *value) -{ - ID *id = ptr->owner_id; - if (GS(id->name) == ID_ME) { - Mesh *mesh = (Mesh *)id; - MEM_SAFE_FREE(mesh->default_color_attribute); - if (value[0]) { - mesh->default_color_attribute = BLI_strdup(value); - } - } -} - static void rna_AttributeGroup_active_color_name_get(PointerRNA *ptr, char *value) { const ID *id = ptr->owner_id; @@ -707,18 +695,6 @@ static int rna_AttributeGroup_active_color_name_length(PointerRNA *ptr) return name ? strlen(name) : 0; } -static void rna_AttributeGroup_active_color_name_set(PointerRNA *ptr, const char *value) -{ - ID *id = ptr->owner_id; - if (GS(id->name) == ID_ME) { - Mesh *mesh = (Mesh *)id; - MEM_SAFE_FREE(mesh->default_color_attribute); - if (value[0]) { - mesh->default_color_attribute = BLI_strdup(value); - } - } -} - #else static void rna_def_attribute_float(BlenderRNA *brna) @@ -1185,7 +1161,7 @@ static void rna_def_attribute_group(BlenderRNA *brna) RNA_def_property_string_funcs(prop, "rna_AttributeGroup_default_color_name_get", "rna_AttributeGroup_default_color_name_length", - "rna_AttributeGroup_default_color_name_set"); + NULL); RNA_def_property_ui_text( prop, "Default Color Attribute", @@ -1197,7 +1173,7 @@ static void rna_def_attribute_group(BlenderRNA *brna) RNA_def_property_string_funcs(prop, "rna_AttributeGroup_active_color_name_get", "rna_AttributeGroup_active_color_name_length", - "rna_AttributeGroup_active_color_name_set"); + NULL); RNA_def_property_ui_text(prop, "Active Color Attribute", "The name of the active color attribute for display and editing"); From edfef62371d5b111c7ae4bc4f6f3da2253decdc9 Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Fri, 16 Dec 2022 09:47:21 +0900 Subject: [PATCH 0155/1522] Fix T103183: UV map name of mesh converted from curve is untranslated Upon conversion, the newly-created UV map with default name "UVMap" should be translated. Reviewed By: mont29 Maniphest Tasks: T103183 Differential Revision: https://developer.blender.org/D16775 --- source/blender/blenkernel/intern/mesh_convert.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 7a4c3c0834b..db4d6396c92 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -26,6 +26,8 @@ #include "BLI_string.h" #include "BLI_utildefines.h" +#include "BLT_translation.h" + #include "BKE_DerivedMesh.h" #include "BKE_curves.hh" #include "BKE_deform.h" @@ -199,7 +201,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba SpanAttributeWriter material_indices = attributes.lookup_or_add_for_write_only_span( "material_index", ATTR_DOMAIN_FACE); MLoopUV *mloopuv = static_cast(CustomData_add_layer_named( - &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, "UVMap")); + &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, DATA_("UVMap"))); /* verts and faces */ vertcount = 0; From 841020dba2563fbae2cb757ee3c9de9826871b4d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Dec 2022 12:30:56 +1100 Subject: [PATCH 0156/1522] Fix active/default color names not being editable Revert [0] and enable the editable flag as the intent for [1] was that these values would be editable. [0]: e58f5422c37762ab5b4302e7481a9ffed023913a [1]: 6514bb05ea5a138d897151db02cb0bad9fe01968 --- .../blender/makesrna/intern/rna_attribute.c | 30 ++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c index efa87523204..98b3fa8553e 100644 --- a/source/blender/makesrna/intern/rna_attribute.c +++ b/source/blender/makesrna/intern/rna_attribute.c @@ -677,6 +677,18 @@ static int rna_AttributeGroup_default_color_name_length(PointerRNA *ptr) return name ? strlen(name) : 0; } +static void rna_AttributeGroup_default_color_name_set(PointerRNA *ptr, const char *value) +{ + ID *id = ptr->owner_id; + if (GS(id->name) == ID_ME) { + Mesh *mesh = (Mesh *)id; + MEM_SAFE_FREE(mesh->default_color_attribute); + if (value[0]) { + mesh->default_color_attribute = BLI_strdup(value); + } + } +} + static void rna_AttributeGroup_active_color_name_get(PointerRNA *ptr, char *value) { const ID *id = ptr->owner_id; @@ -695,6 +707,18 @@ static int rna_AttributeGroup_active_color_name_length(PointerRNA *ptr) return name ? strlen(name) : 0; } +static void rna_AttributeGroup_active_color_name_set(PointerRNA *ptr, const char *value) +{ + ID *id = ptr->owner_id; + if (GS(id->name) == ID_ME) { + Mesh *mesh = (Mesh *)id; + MEM_SAFE_FREE(mesh->default_color_attribute); + if (value[0]) { + mesh->default_color_attribute = BLI_strdup(value); + } + } +} + #else static void rna_def_attribute_float(BlenderRNA *brna) @@ -1156,24 +1180,22 @@ static void rna_def_attribute_group(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_AttributeGroup_update_active_color"); prop = RNA_def_property(srna, "default_color_name", PROP_STRING, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME); RNA_def_property_string_funcs(prop, "rna_AttributeGroup_default_color_name_get", "rna_AttributeGroup_default_color_name_length", - NULL); + "rna_AttributeGroup_default_color_name_set"); RNA_def_property_ui_text( prop, "Default Color Attribute", "The name of the default color attribute used as a fallback for rendering"); prop = RNA_def_property(srna, "active_color_name", PROP_STRING, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME); RNA_def_property_string_funcs(prop, "rna_AttributeGroup_active_color_name_get", "rna_AttributeGroup_active_color_name_length", - NULL); + "rna_AttributeGroup_active_color_name_set"); RNA_def_property_ui_text(prop, "Active Color Attribute", "The name of the active color attribute for display and editing"); From 75c2e8110395e0082fec365d80337ffe2fcef64e Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Fri, 16 Dec 2022 16:55:16 +1300 Subject: [PATCH 0157/1522] Cleanup: format --- source/blender/blenkernel/intern/mesh_convert.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index db4d6396c92..8354de20e20 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -1104,7 +1104,6 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain, return mesh_in_bmain; } - static KeyBlock *keyblock_ensure_from_uid(Key &key, const int uid, const StringRefNull name) { if (KeyBlock *kb = BKE_keyblock_find_uid(&key, uid)) { From a6c30e1a0c62041c02f03270a15334d6de22db5e Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Fri, 16 Dec 2022 16:20:11 +1300 Subject: [PATCH 0158/1522] Fix T103237: Prevent UV Unwrap from packing hidden UV islands When migrating to the new packing API, pin_unselected was not implemented correctly. Regression from rB143e74c0b8eb, rBe3075f3cf7ce, rB0ce18561bc82. Differential Revision: https://developer.blender.org/D16788 Reviewed By: Campbell Barton Duplicated in blender-v3.4-release as rB3dcd9992676a --- source/blender/editors/uvedit/uvedit_islands.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/uvedit/uvedit_islands.cc b/source/blender/editors/uvedit/uvedit_islands.cc index efba43b7ffd..893fd22a405 100644 --- a/source/blender/editors/uvedit/uvedit_islands.cc +++ b/source/blender/editors/uvedit/uvedit_islands.cc @@ -618,13 +618,21 @@ static BoxPack *pack_islands_params(const blender::Vector &island_ return box_array; } -static bool island_has_pins(const Scene *scene, FaceIsland *island, const bool pin_unselected) +static bool island_has_pins(const Scene *scene, + FaceIsland *island, + const UVPackIsland_Params *params) { + const bool pin_unselected = params->pin_unselected; + const bool only_selected_faces = params->only_selected_faces; BMLoop *l; BMIter iter; const int cd_loop_uv_offset = island->cd_loop_uv_offset; for (int i = 0; i < island->faces_len; i++) { - BM_ITER_ELEM (l, &iter, island->faces[i], BM_LOOPS_OF_FACE) { + BMFace *efa = island->faces[i]; + if (pin_unselected && only_selected_faces && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { + return true; + } + BM_ITER_ELEM (l, &iter, efa, BM_LOOPS_OF_FACE) { MLoopUV *luv = static_cast(BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset)); if (luv->flag & MLOOPUV_PINNED) { return true; @@ -697,7 +705,7 @@ void ED_uvedit_pack_islands_multi(const Scene *scene, /* Remove from linked list and append to blender::Vector. */ LISTBASE_FOREACH_MUTABLE (struct FaceIsland *, island, &island_list) { BLI_remlink(&island_list, island); - if (params->ignore_pinned && island_has_pins(scene, island, params->pin_unselected)) { + if (params->ignore_pinned && island_has_pins(scene, island, params)) { MEM_freeN(island->faces); MEM_freeN(island); continue; From 0079460dc79a6c4798ec41e86550d8f0882ed313 Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Fri, 16 Dec 2022 17:22:41 +1300 Subject: [PATCH 0159/1522] Fix T102923: replace zero check with epsilons with uv constrain to bounds Small roundoff errors during UV editing can sometimes occur, most likely due to so-called "catastrophic cancellation". Here we set a tolerance around zero when using Constrain-To-Bounds and UV Scaling. The tolerance is set at one quarter of a texel, on a 65536 x 65536 texture. TODO: If this fix holds, we should formalize the tolerance into the UV editing subsystem, perhaps as a helper function, and investigate where else it needs to be applied. Differential Revision: https://developer.blender.org/D16702 --- .../blender/editors/transform/transform_mode_resize.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c index 70599c3577c..4e671768721 100644 --- a/source/blender/editors/transform/transform_mode_resize.c +++ b/source/blender/editors/transform/transform_mode_resize.c @@ -95,9 +95,14 @@ static void constrain_scale_to_boundary(const float numerator, const float denominator, float *scale) { - if (denominator == 0.0f) { - /* The origin of the scale is on the edge of the boundary. */ - if (numerator < 0.0f) { + /* It's possible the numerator or denominator can be very close to zero due to so-called + * "catastrophic cancellation". See T102923 for an example. We use epsilon tests here to + * distinguish between genuine negative coordinates versus coordinates that should be rounded off + * to zero. */ + const float epsilon = 0.25f / 65536.0f; /* i.e. Quarter of a texel on a 65536 x 65536 texture. */ + if (fabsf(denominator) < epsilon) { + /* The origin of the scale is very near the edge of the boundary. */ + if (numerator < -epsilon) { /* Negative scale will wrap around and put us outside the boundary. */ *scale = 0.0f; /* Hold at the boundary instead. */ } From ba7afbe3a124c170580f12a9222ab18faf38770c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Dec 2022 15:33:15 +1100 Subject: [PATCH 0160/1522] Build: remove opus workaround for sndfile For some reason SNDFILE now builds without this workaround, which broke building FFMPEG. --- build_files/build_environment/cmake/sndfile.cmake | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/build_files/build_environment/cmake/sndfile.cmake b/build_files/build_environment/cmake/sndfile.cmake index 3ea4c776e56..8fc614c06c3 100644 --- a/build_files/build_environment/cmake/sndfile.cmake +++ b/build_files/build_environment/cmake/sndfile.cmake @@ -17,19 +17,6 @@ else() set(SNDFILE_OPTIONS --enable-static --disable-shared ) endif() -if(UNIX AND NOT APPLE) - # NOTE(@campbellbarton): For some reason OPUS is alone in referencing the sub-directory, - # manipulate the package-config file to prevent this from happening. - # There is no problem with applying this change multiple times. - # - # Replace: Cflags: -I${includedir}/opus - # With: Cflags: -I${includedir} - set(SNDFILE_ENV - sed -i s/{includedir}\\/opus/{includedir}/g ${LIBDIR}/opus/lib/pkgconfig/opus.pc && - ${SNDFILE_ENV} - ) -endif() - ExternalProject_Add(external_sndfile URL file://${PACKAGE_DIR}/${SNDFILE_FILE} DOWNLOAD_DIR ${DOWNLOAD_DIR} From 8b2afe93b4730e15e30cdc76a95628a3ca22c3d7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Dec 2022 15:35:20 +1100 Subject: [PATCH 0161/1522] Build: correct extension type for SNDFILE --- build_files/build_environment/cmake/versions.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake index 6b56df4ee99..a4fc7dcc569 100644 --- a/build_files/build_environment/cmake/versions.cmake +++ b/build_files/build_environment/cmake/versions.cmake @@ -359,7 +359,7 @@ set(SNDFILE_VERSION 1.1.0) set(SNDFILE_URI https://github.com/libsndfile/libsndfile/releases/download/1.1.0/libsndfile-${SNDFILE_VERSION}.tar.xz) set(SNDFILE_HASH e63dead2b4f0aaf323687619d007ee6a) set(SNDFILE_HASH_TYPE MD5) -set(SNDFILE_FILE libsndfile-${SNDFILE_VERSION}.tar.gz) +set(SNDFILE_FILE libsndfile-${SNDFILE_VERSION}.tar.xz) set(SNDFILE_CPE "cpe:2.3:a:libsndfile_project:libsndfile:${SNDFILE_VERSION}:*:*:*:*:*:*:*") set(WEBP_VERSION 1.2.2) From f2945f38959afb544a52a1d0d57be106c5dadf47 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Dec 2022 17:22:09 +1100 Subject: [PATCH 0162/1522] UI: don't change mouse cursor while it's grabbed The paint cursor was continuously set which meant hiding the cursor while interacting with buttons would immediately show it again. This exposed cursor warping. --- source/blender/editors/sculpt_paint/paint_cursor.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index 15e45b8ac21..deb1fff946b 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -1400,6 +1400,11 @@ static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext *pcon static void paint_update_mouse_cursor(PaintCursorContext *pcontext) { + if (pcontext->win->grabcursor != 0) { + /* Don't set the cursor while it's grabbed, since this will show the cursor when interacting + * with the UI (dragging a number button for e.g.), see: T102792. */ + return; + } WM_cursor_set(pcontext->win, WM_CURSOR_PAINT); } From 79a34758f52ad2dce1d0545ee23ff85b6d15e119 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Dec 2022 18:37:44 +1100 Subject: [PATCH 0163/1522] Fix T103253: Infinite drag of number buttons is broken on WIN32 Recent reverting of changes to cursor grabbing intended to match Blender 3.3 release. This is the case for 3.4x branch, however there is an additional change to grabbing on WIN32 by Germano [0] which is a significant improvement on old grabbing logic for Windows. So instead of matching 3.3x behavior, restore logic that keeps the cursor centered while grabbing & hidden. This re-introduces T102792 issue displaying the paint-brush while dragging buttons, this will have to be solved separately. Re-apply [1] & [2], revert [3] & [4]. [4]: a3a9459050a96e75138b3441c069898f211f179c [0]: 9fd6dae7939a65b67045749a0eadeb6864ded183 [1]: 4cac8025f00798938813f52dcb117be83db97f22 [2]: 230744d6fd96dcf5afe66a8f9b9f6f8bbe1f41bb [3]: 0240b895994aa58258db6897ae0d6478da7fce5f --- intern/ghost/intern/GHOST_SystemWin32.cpp | 45 +++++++++++++--- intern/ghost/intern/GHOST_SystemX11.cpp | 47 ++++++++++++++--- .../space_view3d/view3d_navigate_walk.c | 52 +------------------ source/tools | 2 +- 4 files changed, 78 insertions(+), 68 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index d005eec3036..8cb007a756a 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -1075,17 +1075,46 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind int32_t x_new = x_screen; int32_t y_new = y_screen; int32_t x_accum, y_accum; - GHOST_Rect bounds; - /* Fallback to window bounds. */ - if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) { - window->getClientBounds(bounds); + /* Warp within bounds. */ + { + GHOST_Rect bounds; + int32_t bounds_margin = 0; + GHOST_TAxisFlag bounds_axis = GHOST_kAxisNone; + + if (window->getCursorGrabMode() == GHOST_kGrabHide) { + window->getClientBounds(bounds); + + /* WARNING(@campbellbarton): The current warping logic fails to warp on every event, + * so the box needs to small enough not to let the cursor escape the window but large + * enough that the cursor isn't being warped every time. + * If this was not the case it would be less trouble to simply warp the cursor to the + * center of the screen on every motion, see: D16558 (alternative fix for T102346). */ + const int32_t subregion_div = 4; /* One quarter of the region. */ + const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()}; + const int32_t center[2] = {(bounds.m_l + bounds.m_r) / 2, (bounds.m_t + bounds.m_b) / 2}; + /* Shrink the box to prevent the cursor escaping. */ + bounds.m_l = center[0] - (size[0] / (subregion_div * 2)); + bounds.m_r = center[0] + (size[0] / (subregion_div * 2)); + bounds.m_t = center[1] - (size[1] / (subregion_div * 2)); + bounds.m_b = center[1] + (size[1] / (subregion_div * 2)); + bounds_margin = 0; + bounds_axis = GHOST_TAxisFlag(GHOST_kAxisX | GHOST_kAxisY); + } + else { + /* Fallback to window bounds. */ + if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) { + window->getClientBounds(bounds); + } + bounds_margin = 2; + bounds_axis = window->getCursorGrabAxis(); + } + + /* Could also clamp to screen bounds wrap with a window outside the view will + * fail at the moment. Use inset in case the window is at screen bounds. */ + bounds.wrapPoint(x_new, y_new, bounds_margin, bounds_axis); } - /* Could also clamp to screen bounds wrap with a window outside the view will - * fail at the moment. Use inset in case the window is at screen bounds. */ - bounds.wrapPoint(x_new, y_new, 2, window->getCursorGrabAxis()); - window->getCursorGrabAccum(x_accum, y_accum); if (x_new != x_screen || y_new != y_screen) { /* WORKAROUND: Store the current time so that we ignore outdated mousemove events. */ diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 72f34dac52e..3122a7ce562 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -917,17 +917,48 @@ void GHOST_SystemX11::processEvent(XEvent *xe) int32_t x_new = xme.x_root; int32_t y_new = xme.y_root; int32_t x_accum, y_accum; - GHOST_Rect bounds; - /* fallback to window bounds */ - if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) { - window->getClientBounds(bounds); + /* Warp within bounds. */ + { + GHOST_Rect bounds; + int32_t bounds_margin = 0; + GHOST_TAxisFlag bounds_axis = GHOST_kAxisNone; + + if (window->getCursorGrabMode() == GHOST_kGrabHide) { + window->getClientBounds(bounds); + + /* TODO(@campbellbarton): warp the cursor to `window->getCursorGrabInitPos`, + * on every motion event, see: D16557 (alternative fix for T102346). */ + const int32_t subregion_div = 4; /* One quarter of the region. */ + const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()}; + const int32_t center[2] = { + (bounds.m_l + bounds.m_r) / 2, + (bounds.m_t + bounds.m_b) / 2, + }; + /* Shrink the box to prevent the cursor escaping. */ + bounds.m_l = center[0] - (size[0] / (subregion_div * 2)); + bounds.m_r = center[0] + (size[0] / (subregion_div * 2)); + bounds.m_t = center[1] - (size[1] / (subregion_div * 2)); + bounds.m_b = center[1] + (size[1] / (subregion_div * 2)); + bounds_margin = 0; + bounds_axis = GHOST_TAxisFlag(GHOST_kAxisX | GHOST_kAxisY); + } + else { + /* Fallback to window bounds. */ + if (window->getCursorGrabBounds(bounds) == GHOST_kFailure) { + window->getClientBounds(bounds); + } + /* Could also clamp to screen bounds wrap with a window outside the view will + * fail at the moment. Use offset of 8 in case the window is at screen bounds. */ + bounds_margin = 8; + bounds_axis = window->getCursorGrabAxis(); + } + + /* Could also clamp to screen bounds wrap with a window outside the view will + * fail at the moment. Use inset in case the window is at screen bounds. */ + bounds.wrapPoint(x_new, y_new, bounds_margin, bounds_axis); } - /* Could also clamp to screen bounds wrap with a window outside the view will - * fail at the moment. Use offset of 8 in case the window is at screen bounds. */ - bounds.wrapPoint(x_new, y_new, 8, window->getCursorGrabAxis()); - window->getCursorGrabAccum(x_accum, y_accum); if (x_new != xme.x_root || y_new != xme.y_root) { diff --git a/source/blender/editors/space_view3d/view3d_navigate_walk.c b/source/blender/editors/space_view3d/view3d_navigate_walk.c index 5606527a5fd..9aa8328287b 100644 --- a/source/blender/editors/space_view3d/view3d_navigate_walk.c +++ b/source/blender/editors/space_view3d/view3d_navigate_walk.c @@ -55,14 +55,6 @@ #define USE_TABLET_SUPPORT -/** - * Use alternative behavior when cursor warp is supported - * to prevent the cursor escaping the window bounds, see: T102346. - * - * \note this is not needed if cursor positioning is not supported. - */ -#define USE_CURSOR_WARP_HACK - /* -------------------------------------------------------------------- */ /** \name Modal Key-map * \{ */ @@ -229,10 +221,6 @@ typedef struct WalkInfo { bool need_rotation_keyframe; bool need_translation_keyframe; -#ifdef USE_CURSOR_WARP_HACK - bool need_modal_cursor_warp_hack; -#endif - /** Previous 2D mouse values. */ int prev_mval[2]; /** Initial mouse location. */ @@ -591,10 +579,6 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int walk->need_rotation_keyframe = false; walk->need_translation_keyframe = false; -#ifdef USE_CURSOR_WARP_HACK - walk->need_modal_cursor_warp_hack = false; -#endif - walk->time_lastdraw = PIL_check_seconds_timer(); walk->draw_handle_pixel = ED_region_draw_cb_activate( @@ -610,32 +594,7 @@ static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const int copy_v2_v2_int(walk->init_mval, mval); copy_v2_v2_int(walk->prev_mval, mval); -#ifdef USE_CURSOR_WARP_HACK - if (WM_capabilities_flag() & WM_CAPABILITY_CURSOR_WARP) { - const rcti *winrct = &walk->region->winrct; - const int center[2] = {BLI_rcti_cent_x(winrct), BLI_rcti_cent_y(winrct)}; - const int size[2] = {BLI_rcti_size_x(winrct), BLI_rcti_size_y(winrct)}; - const int div = 4; /* Where 2 is the region size. */ - - const rcti wrap_region = { - .xmin = center[0] - (size[0] / div), - .xmax = center[0] + (size[0] / div), - .ymin = center[1] - (size[1] / div), - .ymax = center[1] + (size[1] / div), - }; - - WM_cursor_grab_enable(win, WM_CURSOR_WRAP_XY, &wrap_region, false); - - /* Important to hide afterwards (not part of grabbing), - * since enabling cursor and hiding at the same time ignores bounds. */ - WM_cursor_modal_set(win, WM_CURSOR_NONE); - walk->need_modal_cursor_warp_hack = true; - } - else -#endif /* USE_CURSOR_WARP_HACK */ - { - WM_cursor_grab_enable(win, WM_CURSOR_WRAP_NONE, NULL, true); - } + WM_cursor_grab_enable(win, 0, NULL, true); return 1; } @@ -686,15 +645,6 @@ static int walkEnd(bContext *C, WalkInfo *walk) WM_cursor_grab_disable(win, NULL); -#ifdef USE_CURSOR_WARP_HACK - if (walk->need_modal_cursor_warp_hack) { - WM_cursor_warp(win, - walk->region->winrct.xmin + walk->init_mval[0], - walk->region->winrct.ymin + walk->init_mval[1]); - WM_cursor_modal_restore(win); - } -#endif - if (walk->state == WALK_CONFIRM) { MEM_freeN(walk); return OPERATOR_FINISHED; diff --git a/source/tools b/source/tools index 9e33a8678a3..fdfa2fcb949 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit 9e33a8678a3b97d2fdb833349657c3cc1c04811f +Subproject commit fdfa2fcb9495d87571f2dfe2ae9fa0e032536600 From ba89f640fe6566437f8aaf4974dcda473671c7f4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Dec 2022 18:37:47 +1100 Subject: [PATCH 0164/1522] Fix T102792: Sculpt cursor jumps to random place Restrict the condition under which paint cursors read use the cursor location from the the operating-system. This caused a glitch when dragging UI elements in painting context popup. Since the paint cursor would display using mouse motion which was clamped to the window center - an internal detail of hidden cursor grabbing. Now only read the cursor coordinates when clamped to a region which is used for the transform cursor to stay visible even when the cursor wraps around. --- source/blender/windowmanager/intern/wm_draw.c | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index cbbd0eb3a4f..15826af32fa 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -63,6 +63,31 @@ # include "BKE_subsurf.h" #endif +/* -------------------------------------------------------------------- */ +/** \name Internal Utilities + * \{ */ + +/** + * Return true when the cursor is grabbed and wrapped within a region. + */ +static bool wm_window_grab_warp_region_is_set(const wmWindow *win) +{ + if (ELEM(win->grabcursor, GHOST_kGrabWrap, GHOST_kGrabHide)) { + GHOST_TGrabCursorMode mode_dummy; + GHOST_TAxisFlag wrap_axis_dummy; + int bounds[4] = {0}; + bool use_software_cursor_dummy = false; + GHOST_GetCursorGrabState( + win->ghostwin, &mode_dummy, &wrap_axis_dummy, bounds, &use_software_cursor_dummy); + if ((bounds[0] != bounds[2]) || (bounds[1] != bounds[3])) { + return true; + } + } + return false; +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Draw Paint Cursor * \{ */ @@ -102,8 +127,14 @@ static void wm_paintcursor_draw(bContext *C, ScrArea *area, ARegion *region) region->winrct.ymin, BLI_rcti_size_x(®ion->winrct) + 1, BLI_rcti_size_y(®ion->winrct) + 1); - - if (ELEM(win->grabcursor, GHOST_kGrabWrap, GHOST_kGrabHide)) { + /* Reading the cursor location from the operating-system while the cursor is grabbed + * conflicts with grabbing logic that hides the cursor, then keeps it centered to accumulate + * deltas without it escaping from the window. In this case we never want to show the actual + * cursor coordinates so limit reading the cursor location to when the cursor is grabbed and + * wrapping in a region since this is the case when it would otherwise attempt to draw the + * cursor outside the view/window. See: T102792. */ + if ((WM_capabilities_flag() & WM_CAPABILITY_CURSOR_WARP) && + wm_window_grab_warp_region_is_set(win)) { int x = 0, y = 0; wm_cursor_position_get(win, &x, &y); pc->draw(C, x, y, pc->customdata); From c37e07bc01a413ffb0ed65ccdf8f10e26795c7c8 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 16 Dec 2022 12:18:49 +0100 Subject: [PATCH 0165/1522] Geometry Nodes: improve dot graph export of lazy function graph * Dim default input values. * Print default input values instead of type name. * Add node/socket names to group input/output nodes. --- .../functions/FN_field_cpp_type_make.hh | 2 +- .../functions/FN_lazy_function_graph.hh | 16 ++++++- .../functions/intern/lazy_function_graph.cc | 44 ++++++++++++++--- .../nodes/NOD_geometry_nodes_lazy_function.hh | 4 ++ .../intern/geometry_nodes_lazy_function.cc | 48 ++++++++++++++++++- 5 files changed, 103 insertions(+), 11 deletions(-) diff --git a/source/blender/functions/FN_field_cpp_type_make.hh b/source/blender/functions/FN_field_cpp_type_make.hh index 79e46faa9e7..7a4112b432b 100644 --- a/source/blender/functions/FN_field_cpp_type_make.hh +++ b/source/blender/functions/FN_field_cpp_type_make.hh @@ -38,7 +38,7 @@ inline ValueOrFieldCPPType::ValueOrFieldCPPType(TypeTag /*value_type* * Create a new #ValueOrFieldCPPType that can be accessed through `ValueOrFieldCPPType::get()`. */ #define FN_FIELD_CPP_TYPE_MAKE(VALUE_TYPE) \ - BLI_CPP_TYPE_MAKE(blender::fn::ValueOrField, CPPTypeFlags::None) \ + BLI_CPP_TYPE_MAKE(blender::fn::ValueOrField, CPPTypeFlags::Printable) \ template<> \ const blender::fn::ValueOrFieldCPPType & \ blender::fn::ValueOrFieldCPPType::get_impl() \ diff --git a/source/blender/functions/FN_lazy_function_graph.hh b/source/blender/functions/FN_lazy_function_graph.hh index 4ede28c4f26..7352004b7fe 100644 --- a/source/blender/functions/FN_lazy_function_graph.hh +++ b/source/blender/functions/FN_lazy_function_graph.hh @@ -167,15 +167,25 @@ class FunctionNode : public Node { const LazyFunction &function() const; }; +class DummyDebugInfo { + public: + virtual ~DummyDebugInfo() = default; + virtual std::string node_name() const; + virtual std::string input_name(const int i) const; + virtual std::string output_name(const int i) const; +}; + /** * A #Node that does *not* correspond to a #LazyFunction. Instead it can be used to indicate inputs * and outputs of the entire graph. It can have an arbitrary number of inputs and outputs. */ class DummyNode : public Node { private: - std::string name_; + const DummyDebugInfo *debug_info_ = nullptr; friend Node; + friend Socket; + friend Graph; }; /** @@ -208,7 +218,9 @@ class Graph : NonCopyable, NonMovable { /** * Add a new dummy node with the given socket types. */ - DummyNode &add_dummy(Span input_types, Span output_types); + DummyNode &add_dummy(Span input_types, + Span output_types, + const DummyDebugInfo *debug_info = nullptr); /** * Add a link between the two given sockets. diff --git a/source/blender/functions/intern/lazy_function_graph.cc b/source/blender/functions/intern/lazy_function_graph.cc index cc55b70d166..60605a4e64c 100644 --- a/source/blender/functions/intern/lazy_function_graph.cc +++ b/source/blender/functions/intern/lazy_function_graph.cc @@ -48,13 +48,16 @@ FunctionNode &Graph::add_function(const LazyFunction &fn) return node; } -DummyNode &Graph::add_dummy(Span input_types, Span output_types) +DummyNode &Graph::add_dummy(Span input_types, + Span output_types, + const DummyDebugInfo *debug_info) { DummyNode &node = *allocator_.construct().release(); node.fn_ = nullptr; node.inputs_ = allocator_.construct_elements_and_pointer_array(input_types.size()); node.outputs_ = allocator_.construct_elements_and_pointer_array( output_types.size()); + node.debug_info_ = debug_info; for (const int i : input_types.index_range()) { InputSocket &socket = *node.inputs_[i]; @@ -100,6 +103,8 @@ bool Graph::node_indices_are_valid() const return true; } +static const char *fallback_name = "No Name"; + std::string Socket::name() const { if (node_->is_function()) { @@ -110,15 +115,41 @@ std::string Socket::name() const } return fn.output_name(index_in_node_); } - return "Unnamed"; + const DummyNode &dummy_node = *static_cast(node_); + if (dummy_node.debug_info_) { + if (is_input_) { + return dummy_node.debug_info_->input_name(index_in_node_); + } + return dummy_node.debug_info_->output_name(index_in_node_); + } + return fallback_name; } std::string Node::name() const { - if (fn_ == nullptr) { - return static_cast(this)->name_; + if (this->is_function()) { + return fn_->name(); } - return fn_->name(); + const DummyNode &dummy_node = *static_cast(this); + if (dummy_node.debug_info_) { + return dummy_node.debug_info_->node_name(); + } + return fallback_name; +} + +std::string DummyDebugInfo::node_name() const +{ + return fallback_name; +} + +std::string DummyDebugInfo::input_name(const int /*i*/) const +{ + return fallback_name; +} + +std::string DummyDebugInfo::output_name(const int /*i*/) const +{ + return fallback_name; } std::string Graph::to_dot() const @@ -166,10 +197,11 @@ std::string Graph::to_dot() const value_string = type.to_string(default_value); } else { - value_string = "<" + type.name() + ">"; + value_string = type.name(); } dot::Node &default_value_dot_node = digraph.new_node(value_string); default_value_dot_node.set_shape(dot::Attr_shape::Ellipse); + default_value_dot_node.attributes.set("color", "#00000055"); digraph.new_edge(default_value_dot_node, to_dot_port); } } diff --git a/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh b/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh index 240a0115f68..f21100414b3 100644 --- a/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh +++ b/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh @@ -110,6 +110,10 @@ struct GeometryNodesLazyFunctionGraphInfo { * we have to keep track of them separately. */ Vector> functions; + /** + * Debug info that has to be destructed when the graph is not used anymore. + */ + Vector> dummy_debug_infos_; /** * Many sockets have default values. Since those are not owned by the lazy-function graph, we * have to keep track of them separately. This only owns the values, the memory is owned by the diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 9b89d056675..8d11089f253 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -698,6 +698,36 @@ static GMutablePointer get_socket_default_value(LinearAllocator<> &allocator, return {type, buffer}; } +class GroupInputDebugInfo : public lf::DummyDebugInfo { + public: + Vector socket_names; + + std::string node_name() const override + { + return "Group Input"; + } + + std::string output_name(const int i) const override + { + return this->socket_names[i]; + } +}; + +class GroupOutputDebugInfo : public lf::DummyDebugInfo { + public: + Vector socket_names; + + std::string node_name() const + { + return "Group Output"; + } + + std::string input_name(const int i) const override + { + return this->socket_names[i]; + } +}; + /** * Utility class to build a lazy-function graph based on a geometry nodes tree. * This is mainly a separate class because it makes it easier to have variables that can be @@ -794,15 +824,21 @@ struct GeometryNodesLazyFunctionGraphBuilder { void build_group_input_node() { /* Create a dummy node for the group inputs. */ - group_input_lf_node_ = &lf_graph_->add_dummy({}, group_input_types_); + auto debug_info = std::make_unique(); + group_input_lf_node_ = &lf_graph_->add_dummy({}, group_input_types_, debug_info.get()); + + const bNodeSocket *interface_bsocket = static_cast(btree_.inputs.first); for (const int group_input_index : group_input_indices_) { + BLI_SCOPED_DEFER([&]() { interface_bsocket = interface_bsocket->next; }); if (group_input_index == -1) { mapping_->group_input_sockets.append(nullptr); } else { mapping_->group_input_sockets.append(&group_input_lf_node_->output(group_input_index)); + debug_info->socket_names.append(interface_bsocket->name); } } + lf_graph_info_->dummy_debug_infos_.append(std::move(debug_info)); } void handle_nodes() @@ -925,8 +961,13 @@ struct GeometryNodesLazyFunctionGraphBuilder { void handle_group_output_node(const bNode &bnode) { - lf::DummyNode &group_output_lf_node = lf_graph_->add_dummy(group_output_types_, {}); + auto debug_info = std::make_unique(); + lf::DummyNode &group_output_lf_node = lf_graph_->add_dummy( + group_output_types_, {}, debug_info.get()); + + const bNodeSocket *interface_bsocket = static_cast(btree_.outputs.first); for (const int btree_index : group_output_indices_.index_range()) { + BLI_SCOPED_DEFER([&]() { interface_bsocket = interface_bsocket->next; }); const int lf_index = group_output_indices_[btree_index]; if (lf_index == -1) { continue; @@ -936,7 +977,10 @@ struct GeometryNodesLazyFunctionGraphBuilder { input_socket_map_.add(&bsocket, &lf_socket); mapping_->dummy_socket_map.add(&bsocket, &lf_socket); mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket); + debug_info->socket_names.append(interface_bsocket->name); } + + lf_graph_info_->dummy_debug_infos_.append(std::move(debug_info)); } void handle_group_node(const bNode &bnode) From 3334ff0e32354fe45a2cc4f45aa653f21b39f6c5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Dec 2022 23:00:52 +1100 Subject: [PATCH 0166/1522] CMake: warn Linux references old linux_centos7_x86_64 paths When the centos7 library dir is found, warn when the values of cached variables reference it, listing the variables and their values. --- CMakeLists.txt | 18 +++++++++++++++++ build_files/cmake/macros.cmake | 37 ++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 74bfb23a3a4..c9e0de18913 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2007,6 +2007,24 @@ if(0) print_all_vars() endif() +set(LIBDIR_STALE) + +if(UNIX AND NOT APPLE) + # Only search for the path if it's found on the system. + if (EXISTS "../lib/linux_centos7_x86_64") + set(LIBDIR_STALE "/lib/linux_centos7_x86_64/") + endif() +endif() + +if(LIBDIR_STALE) + print_cached_vars_containing_value( + "${LIBDIR_STALE}" + "\nWARNING: found cached references to old library paths!\n" + "\nIt is *strongly* recommended to reference updated library paths!\n" + ) +endif() +unset(LIBDIR_STALE) + # Should be the last step of configuration. if(POSTCONFIGURE_SCRIPT) include(${POSTCONFIGURE_SCRIPT}) diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 7064ca93e8b..dc07be70f84 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -1209,6 +1209,43 @@ function(print_all_vars) endforeach() endfunction() +# Print a list of all cached variables with values containing `contents`. +function(print_cached_vars_containing_value + contents + msg_header + msg_footer + ) + set(_list_info) + set(_found) + get_cmake_property(_vars VARIABLES) + foreach(_var ${_vars}) + if (DEFINED CACHE{${_var}}) + # Skip "_" prefixed variables, these are used for internal book-keeping, + # not under user control. + string(FIND "${_var}" "_" _found) + if(NOT (_found EQUAL 0)) + string(FIND "${${_var}}" "${contents}" _found) + if(NOT (_found EQUAL -1)) + if(_found) + list(APPEND _list_info "${_var}=${${_var}}") + endif() + endif() + endif() + endif() + endforeach() + unset(_var) + unset(_vars) + unset(_found) + if(_list_info) + message(${msg_header}) + foreach(_var ${_list_info}) + message(" * ${_var}") + endforeach() + message(${msg_footer}) + endif() + unset(_list_info) +endfunction() + macro(openmp_delayload projectname ) From 9a25c48f08c8df84062a8c7582379be49ca74655 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Dec 2022 23:28:28 +1100 Subject: [PATCH 0167/1522] Build: resolve failure to copy indirect dependencies for USD on Linux Even when building without OpenImageIO and OpenVDB, USD depends on these libraries. Ensure these libraries are copied when building with USD. --- build_files/cmake/platform/platform_unix.cmake | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index cfb3ecc564b..2b68fa60f15 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -1013,6 +1013,18 @@ endfunction() configure_atomic_lib_if_needed() +# Handle library inter-dependencies. +# FIXME: find a better place to handle inter-library dependencies. +# This is done near the end of the file to ensure bundled libraries are not added multiple times. +if(WITH_USD) + if(NOT WITH_OPENIMAGEIO) + add_bundled_libraries(openimageio/lib) + endif() + if(NOT WITH_OPENVDB) + add_bundled_libraries(openvdb/lib) + endif() +endif() + if(PLATFORM_BUNDLED_LIBRARIES) # For the installed Python module and installed Blender executable, we set the # rpath to the relative path where the install step will copy the shared libraries. From 599c0db3fff0a66f4c46f6378daa1ac7e656c13b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Dec 2022 23:47:35 +1100 Subject: [PATCH 0168/1522] Cleanup: indentation in CMake files --- build_files/cmake/macros.cmake | 12 +-- .../cmake/platform/platform_unix.cmake | 4 +- source/creator/CMakeLists.txt | 74 +++++++++---------- 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index dc07be70f84..178a63fba7c 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -1371,13 +1371,13 @@ macro(windows_generate_shared_manifest) NAME "blender.shared" ) install( - FILES ${CMAKE_BINARY_DIR}/Release/blender.shared.manifest - DESTINATION "./blender.shared" - CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel + FILES ${CMAKE_BINARY_DIR}/Release/blender.shared.manifest + DESTINATION "./blender.shared" + CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel ) install( - FILES ${CMAKE_BINARY_DIR}/Debug/blender.shared.manifest - DESTINATION "./blender.shared" - CONFIGURATIONS Debug + FILES ${CMAKE_BINARY_DIR}/Debug/blender.shared.manifest + DESTINATION "./blender.shared" + CONFIGURATIONS Debug ) endmacro() diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index 2b68fa60f15..cf9226433a3 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -351,9 +351,9 @@ endif() if(WITH_USD) find_package_wrapper(USD) set_and_warn_library_found("USD" USD_FOUND WITH_USD) - if(WITH_USD) + if(WITH_USD) add_bundled_libraries(usd/lib) - endif() + endif() endif() if(WITH_MATERIALX) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 3ecea7c5929..47efd9a67b6 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -953,30 +953,30 @@ elseif(WIN32) endif() if(WITH_OPENVDB) - windows_install_shared_manifest( - FILES ${LIBDIR}/openvdb/bin/openvdb.dll - RELEASE - ) - windows_install_shared_manifest( - FILES ${LIBDIR}/openvdb/bin/openvdb_d.dll - DEBUG - ) + windows_install_shared_manifest( + FILES ${LIBDIR}/openvdb/bin/openvdb.dll + RELEASE + ) + windows_install_shared_manifest( + FILES ${LIBDIR}/openvdb/bin/openvdb_d.dll + DEBUG + ) - # This will not exist for 3.4 and earlier lib folders - # to ease the transition, support both 3.4 and 3.5 lib - # folders. - if(EXISTS ${LIBDIR}/openvdb/python/pyopenvdb_d.pyd) - install( - FILES ${LIBDIR}/openvdb/python/pyopenvdb_d.pyd - DESTINATION ${TARGETDIR_VER}/python/lib/site-packages - CONFIGURATIONS Debug - ) - install( - FILES ${LIBDIR}/openvdb/python/pyopenvdb.pyd - DESTINATION ${TARGETDIR_VER}/python/lib/site-packages - CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel - ) - endif() + # This will not exist for 3.4 and earlier lib folders + # to ease the transition, support both 3.4 and 3.5 lib + # folders. + if(EXISTS ${LIBDIR}/openvdb/python/pyopenvdb_d.pyd) + install( + FILES ${LIBDIR}/openvdb/python/pyopenvdb_d.pyd + DESTINATION ${TARGETDIR_VER}/python/lib/site-packages + CONFIGURATIONS Debug + ) + install( + FILES ${LIBDIR}/openvdb/python/pyopenvdb.pyd + DESTINATION ${TARGETDIR_VER}/python/lib/site-packages + CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel + ) + endif() endif() if(WITH_MATERIALX) @@ -1137,22 +1137,22 @@ elseif(WIN32) # MaterialX python bindings install( - DIRECTORY ${LIBDIR}/materialx/python/Release/MaterialX - DESTINATION ${TARGETDIR_VER}/python/lib/site-packages/ - CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel - PATTERN ".svn" EXCLUDE - PATTERN "__pycache__" EXCLUDE # * any cache * - PATTERN "*.pyc" EXCLUDE # * any cache * - PATTERN "*.pyo" EXCLUDE # * any cache * + DIRECTORY ${LIBDIR}/materialx/python/Release/MaterialX + DESTINATION ${TARGETDIR_VER}/python/lib/site-packages/ + CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel + PATTERN ".svn" EXCLUDE + PATTERN "__pycache__" EXCLUDE # * any cache * + PATTERN "*.pyc" EXCLUDE # * any cache * + PATTERN "*.pyo" EXCLUDE # * any cache * ) install( - DIRECTORY ${LIBDIR}/materialx/python/Debug/MaterialX - DESTINATION ${TARGETDIR_VER}/python/lib/site-packages/ - CONFIGURATIONS Debug - PATTERN ".svn" EXCLUDE - PATTERN "__pycache__" EXCLUDE # * any cache * - PATTERN "*.pyc" EXCLUDE # * any cache * - PATTERN "*.pyo" EXCLUDE # * any cache * + DIRECTORY ${LIBDIR}/materialx/python/Debug/MaterialX + DESTINATION ${TARGETDIR_VER}/python/lib/site-packages/ + CONFIGURATIONS Debug + PATTERN ".svn" EXCLUDE + PATTERN "__pycache__" EXCLUDE # * any cache * + PATTERN "*.pyc" EXCLUDE # * any cache * + PATTERN "*.pyo" EXCLUDE # * any cache * ) endif() From c9eb5834607804eec1ead46289bb66a968ff2a1c Mon Sep 17 00:00:00 2001 From: Patrick Mours Date: Fri, 16 Dec 2022 14:01:51 +0100 Subject: [PATCH 0169/1522] Fix T103257: Enabling or disabling viewport denoising while using OptiX OSL results in an error Switching viewport denoising causes kernels to be reloaded with a new feature mask, which would destroy the existing OptiX pipelines. But OSL kernels were not reloaded as well, leaving the shading pipeline uninitialized and therefore causing an error when it is later attempted to execute it. This fixes that by ensuring OSL kernels are always reloaded when the normal kernels are too. --- intern/cycles/device/optix/device_impl.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/intern/cycles/device/optix/device_impl.cpp b/intern/cycles/device/optix/device_impl.cpp index f4d1969f3f3..601e1193e26 100644 --- a/intern/cycles/device/optix/device_impl.cpp +++ b/intern/cycles/device/optix/device_impl.cpp @@ -579,7 +579,11 @@ bool OptiXDevice::load_kernels(const uint kernel_features) link_options.maxTraceDepth = 1; link_options.debugLevel = module_options.debugLevel; - if (kernel_features & (KERNEL_FEATURE_NODE_RAYTRACE | KERNEL_FEATURE_MNEE) && !use_osl) { + if (use_osl) { + /* Re-create OSL pipeline in case kernels are reloaded after it has been created before. */ + load_osl_kernels(); + } + else if (kernel_features & (KERNEL_FEATURE_NODE_RAYTRACE | KERNEL_FEATURE_MNEE)) { /* Create shader raytracing and MNEE pipeline. */ vector pipeline_groups; pipeline_groups.reserve(NUM_PROGRAM_GROUPS); @@ -743,6 +747,11 @@ bool OptiXDevice::load_osl_kernels() } } + if (osl_kernels.empty()) { + /* No OSL shader groups, so no need to create a pipeline. */ + return true; + } + OptixProgramGroupOptions group_options = {}; /* There are no options currently. */ OptixModuleCompileOptions module_options = {}; module_options.optLevel = OPTIX_COMPILE_OPTIMIZATION_LEVEL_3; From a8530d31c2971756df7f2b440a0de3d6fcfc3061 Mon Sep 17 00:00:00 2001 From: Patrick Mours Date: Fri, 16 Dec 2022 15:41:21 +0100 Subject: [PATCH 0170/1522] Fix T103258: Deleting a shader with OptiX OSL results in an illegal address error Materials without connections to the output node would crash with OSL in OptiX, since the Cycles `OSLCompiler` generates an empty shader group reference for them, which resulted in the OptiX device implementation setting an empty SBT entry for the corresponding direct callables, which then crashed when calling those direct callables was attempted in `osl_eval_nodes`. This fixes that by setting the SBT entries for empty shader groups to a dummy direct callable that does nothing. --- intern/cycles/device/optix/device_impl.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/intern/cycles/device/optix/device_impl.cpp b/intern/cycles/device/optix/device_impl.cpp index 601e1193e26..23e7bbfa7bb 100644 --- a/intern/cycles/device/optix/device_impl.cpp +++ b/intern/cycles/device/optix/device_impl.cpp @@ -866,6 +866,11 @@ bool OptiXDevice::load_osl_kernels() optix_assert(optixSbtRecordPackHeader(osl_groups[i], &sbt_data[NUM_PROGRAM_GROUPS + i])); optix_assert(optixProgramGroupGetStackSize(osl_groups[i], &osl_stack_size[i])); } + else { + /* Default to "__direct_callable__dummy_services", so that OSL evaluation for empty + * materials has direct callables to call and does not crash. */ + optix_assert(optixSbtRecordPackHeader(osl_groups.back(), &sbt_data[NUM_PROGRAM_GROUPS + i])); + } } sbt_data.copy_to_device(); /* Upload updated SBT to device. */ From bea5fe65055e32a0a95232450b014c0d84e21e68 Mon Sep 17 00:00:00 2001 From: Charlie Jolly Date: Fri, 18 Nov 2022 12:52:14 +0000 Subject: [PATCH 0171/1522] Nodes: Add Exclusion color mix mode Expands Color Mix nodes with new Exclusion mode. Similar to Difference but produces less contrast. Requested by Pierre Schiller @3D_director and @OmarSquircleArt on twitter. Differential Revision: https://developer.blender.org/D16543 --- .../kernel/osl/shaders/node_color_blend.h | 5 ++ intern/cycles/kernel/osl/shaders/node_mix.osl | 7 +++ .../kernel/osl/shaders/node_mix_color.osl | 2 + intern/cycles/kernel/svm/color_util.h | 7 +++ intern/cycles/kernel/svm/types.h | 1 + intern/cycles/scene/shader_nodes.cpp | 2 + source/blender/blenkernel/intern/material.cc | 8 +++ .../blender/compositor/nodes/COM_MixNode.cc | 3 + .../compositor/operations/COM_MixOperation.cc | 60 ++++++++++++++++++- .../compositor/operations/COM_MixOperation.h | 8 +++ .../freestyle/intern/python/BPy_Freestyle.cpp | 3 + .../common/gpu_shader_common_mix_rgb.glsl | 6 ++ .../gpu_shader_material_mix_color.glsl | 17 ++++++ source/blender/makesdna/DNA_material_types.h | 1 + source/blender/makesrna/intern/rna_material.c | 1 + .../composite/nodes/node_composite_mixrgb.cc | 2 + .../nodes/shader/nodes/node_shader_mix.cc | 2 + .../nodes/shader/nodes/node_shader_mix_rgb.cc | 2 + 18 files changed, 136 insertions(+), 1 deletion(-) diff --git a/intern/cycles/kernel/osl/shaders/node_color_blend.h b/intern/cycles/kernel/osl/shaders/node_color_blend.h index ab4b4809a97..205784c0cda 100644 --- a/intern/cycles/kernel/osl/shaders/node_color_blend.h +++ b/intern/cycles/kernel/osl/shaders/node_color_blend.h @@ -73,6 +73,11 @@ color node_mix_diff(float t, color col1, color col2) return mix(col1, abs(col1 - col2), t); } +color node_mix_exclusion(float t, color col1, color col2) +{ + return max(mix(col1, col1 + col2 - 2.0 * col1 * col2, t), 0.0); +} + color node_mix_dark(float t, color col1, color col2) { return mix(col1, min(col1, col2), t); diff --git a/intern/cycles/kernel/osl/shaders/node_mix.osl b/intern/cycles/kernel/osl/shaders/node_mix.osl index 1bf3abc7f08..6b6806dd05f 100644 --- a/intern/cycles/kernel/osl/shaders/node_mix.osl +++ b/intern/cycles/kernel/osl/shaders/node_mix.osl @@ -76,6 +76,11 @@ color node_mix_diff(float t, color col1, color col2) return mix(col1, abs(col1 - col2), t); } +color node_mix_exclusion(float t, color col1, color col2) +{ + return max(mix(col1, col1 + col2 - 2.0 * col1 * col2, t), 0.0); +} + color node_mix_dark(float t, color col1, color col2) { return mix(col1, min(col1, col2), t); @@ -291,6 +296,8 @@ shader node_mix(string mix_type = "mix", Color = node_mix_div(t, Color1, Color2); if (mix_type == "difference") Color = node_mix_diff(t, Color1, Color2); + if (mix_type == "exclusion") + Color = node_mix_exclusion(t, Color1, Color2); if (mix_type == "darken") Color = node_mix_dark(t, Color1, Color2); if (mix_type == "lighten") diff --git a/intern/cycles/kernel/osl/shaders/node_mix_color.osl b/intern/cycles/kernel/osl/shaders/node_mix_color.osl index 3ddd89ed306..30521aa1efd 100644 --- a/intern/cycles/kernel/osl/shaders/node_mix_color.osl +++ b/intern/cycles/kernel/osl/shaders/node_mix_color.osl @@ -31,6 +31,8 @@ shader node_mix_color(string blend_type = "mix", Result = node_mix_div(t, A, B); if (blend_type == "difference") Result = node_mix_diff(t, A, B); + if (blend_type == "exclusion") + Result = node_mix_exclusion(t, A, B); if (blend_type == "darken") Result = node_mix_dark(t, A, B); if (blend_type == "lighten") diff --git a/intern/cycles/kernel/svm/color_util.h b/intern/cycles/kernel/svm/color_util.h index 96adb6fd64c..5e9e9db82af 100644 --- a/intern/cycles/kernel/svm/color_util.h +++ b/intern/cycles/kernel/svm/color_util.h @@ -79,6 +79,11 @@ ccl_device float3 svm_mix_diff(float t, float3 col1, float3 col2) return interp(col1, fabs(col1 - col2), t); } +ccl_device float3 svm_mix_exclusion(float t, float3 col1, float3 col2) +{ + return max(interp(col1, col1 + col2 - 2.0f * col1 * col2, t), zero_float3()); +} + ccl_device float3 svm_mix_dark(float t, float3 col1, float3 col2) { return interp(col1, min(col1, col2), t); @@ -266,6 +271,8 @@ ccl_device_noinline_cpu float3 svm_mix(NodeMix type, float t, float3 c1, float3 return svm_mix_div(t, c1, c2); case NODE_MIX_DIFF: return svm_mix_diff(t, c1, c2); + case NODE_MIX_EXCLUSION: + return svm_mix_exclusion(t, c1, c2); case NODE_MIX_DARK: return svm_mix_dark(t, c1, c2); case NODE_MIX_LIGHT: diff --git a/intern/cycles/kernel/svm/types.h b/intern/cycles/kernel/svm/types.h index 9dd8f196e0f..7e956505c7f 100644 --- a/intern/cycles/kernel/svm/types.h +++ b/intern/cycles/kernel/svm/types.h @@ -136,6 +136,7 @@ typedef enum NodeMix { NODE_MIX_COL, NODE_MIX_SOFT, NODE_MIX_LINEAR, + NODE_MIX_EXCLUSION, NODE_MIX_CLAMP /* used for the clamp UI option */ } NodeMix; diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index e95f362793f..8cd64cd189e 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -4948,6 +4948,7 @@ NODE_DEFINE(MixNode) type_enum.insert("color", NODE_MIX_COL); type_enum.insert("soft_light", NODE_MIX_SOFT); type_enum.insert("linear_light", NODE_MIX_LINEAR); + type_enum.insert("exclusion", NODE_MIX_EXCLUSION); SOCKET_ENUM(mix_type, "Type", type_enum, NODE_MIX_BLEND); SOCKET_BOOLEAN(use_clamp, "Use Clamp", false); @@ -5026,6 +5027,7 @@ NODE_DEFINE(MixColorNode) type_enum.insert("color", NODE_MIX_COL); type_enum.insert("soft_light", NODE_MIX_SOFT); type_enum.insert("linear_light", NODE_MIX_LINEAR); + type_enum.insert("exclusion", NODE_MIX_EXCLUSION); SOCKET_ENUM(blend_type, "Type", type_enum, NODE_MIX_BLEND); SOCKET_IN_FLOAT(fac, "Factor", 0.5f); diff --git a/source/blender/blenkernel/intern/material.cc b/source/blender/blenkernel/intern/material.cc index 51e61dbebad..4b0508ddf20 100644 --- a/source/blender/blenkernel/intern/material.cc +++ b/source/blender/blenkernel/intern/material.cc @@ -1689,6 +1689,14 @@ void ramp_blend(int type, float r_col[3], const float fac, const float col[3]) r_col[1] = facm * (r_col[1]) + fac * fabsf(r_col[1] - col[1]); r_col[2] = facm * (r_col[2]) + fac * fabsf(r_col[2] - col[2]); break; + case MA_RAMP_EXCLUSION: + r_col[0] = max_ff(facm * (r_col[0]) + fac * (r_col[0] + col[0] - 2.0f * r_col[0] * col[0]), + 0.0f); + r_col[1] = max_ff(facm * (r_col[1]) + fac * (r_col[1] + col[1] - 2.0f * r_col[1] * col[1]), + 0.0f); + r_col[2] = max_ff(facm * (r_col[2]) + fac * (r_col[2] + col[2] - 2.0f * r_col[2] * col[2]), + 0.0f); + break; case MA_RAMP_DARK: r_col[0] = min_ff(r_col[0], col[0]) * fac + r_col[0] * facm; r_col[1] = min_ff(r_col[1], col[1]) * fac + r_col[1] * facm; diff --git a/source/blender/compositor/nodes/COM_MixNode.cc b/source/blender/compositor/nodes/COM_MixNode.cc index e9179d7063c..5fdb1cab7b1 100644 --- a/source/blender/compositor/nodes/COM_MixNode.cc +++ b/source/blender/compositor/nodes/COM_MixNode.cc @@ -57,6 +57,9 @@ void MixNode::convert_to_operations(NodeConverter &converter, case MA_RAMP_DIFF: convert_prog = new MixDifferenceOperation(); break; + case MA_RAMP_EXCLUSION: + convert_prog = new MixExclusionOperation(); + break; case MA_RAMP_SAT: convert_prog = new MixSaturationOperation(); break; diff --git a/source/blender/compositor/operations/COM_MixOperation.cc b/source/blender/compositor/operations/COM_MixOperation.cc index 7a6c48b89c0..96b6cb52afe 100644 --- a/source/blender/compositor/operations/COM_MixOperation.cc +++ b/source/blender/compositor/operations/COM_MixOperation.cc @@ -494,7 +494,65 @@ void MixDifferenceOperation::update_memory_buffer_row(PixelCursor &p) } } -/* ******** Mix Difference Operation ******** */ +/* ******** Mix Exclusion Operation ******** */ + +void MixExclusionOperation::execute_pixel_sampled(float output[4], + float x, + float y, + PixelSampler sampler) +{ + float input_color1[4]; + float input_color2[4]; + float input_value[4]; + + input_value_operation_->read_sampled(input_value, x, y, sampler); + input_color1_operation_->read_sampled(input_color1, x, y, sampler); + input_color2_operation_->read_sampled(input_color2, x, y, sampler); + + float value = input_value[0]; + if (this->use_value_alpha_multiply()) { + value *= input_color2[3]; + } + float valuem = 1.0f - value; + output[0] = max_ff(valuem * input_color1[0] + value * (input_color1[0] + input_color2[0] - + 2.0f * input_color1[0] * input_color2[0]), + 0.0f); + output[1] = max_ff(valuem * input_color1[1] + value * (input_color1[1] + input_color2[1] - + 2.0f * input_color1[1] * input_color2[1]), + 0.0f); + output[2] = max_ff(valuem * input_color1[2] + value * (input_color1[2] + input_color2[2] - + 2.0f * input_color1[2] * input_color2[2]), + 0.0f); + output[3] = input_color1[3]; + + clamp_if_needed(output); +} + +void MixExclusionOperation::update_memory_buffer_row(PixelCursor &p) +{ + while (p.out < p.row_end) { + float value = p.value[0]; + if (this->use_value_alpha_multiply()) { + value *= p.color2[3]; + } + const float value_m = 1.0f - value; + p.out[0] = max_ff(value_m * p.color1[0] + + value * (p.color1[0] + p.color2[0] - 2.0f * p.color1[0] * p.color2[0]), + 0.0f); + p.out[1] = max_ff(value_m * p.color1[1] + + value * (p.color1[1] + p.color2[1] - 2.0f * p.color1[1] * p.color2[1]), + 0.0f); + p.out[2] = max_ff(value_m * p.color1[2] + + value * (p.color1[2] + p.color2[2] - 2.0f * p.color1[2] * p.color2[2]), + 0.0f); + p.out[3] = p.color1[3]; + + clamp_if_needed(p.out); + p.next(); + } +} + +/* ******** Mix Divide Operation ******** */ void MixDivideOperation::execute_pixel_sampled(float output[4], float x, diff --git a/source/blender/compositor/operations/COM_MixOperation.h b/source/blender/compositor/operations/COM_MixOperation.h index 73c1f9fcb22..d7e5afcd9fc 100644 --- a/source/blender/compositor/operations/COM_MixOperation.h +++ b/source/blender/compositor/operations/COM_MixOperation.h @@ -143,6 +143,14 @@ class MixDifferenceOperation : public MixBaseOperation { void update_memory_buffer_row(PixelCursor &p) override; }; +class MixExclusionOperation : public MixBaseOperation { + public: + void execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) override; + + protected: + void update_memory_buffer_row(PixelCursor &p) override; +}; + class MixDivideOperation : public MixBaseOperation { public: void execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) override; diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp index f99e66c822d..402acd28602 100644 --- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp +++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp @@ -91,6 +91,9 @@ static int ramp_blend_type(const char *type) if (STREQ(type, "DIFFERENCE")) { return MA_RAMP_DIFF; } + if (STREQ(type, "EXCLUSION")) { + return MA_RAMP_EXCLUSION; + } if (STREQ(type, "DARKEN")) { return MA_RAMP_DARK; } diff --git a/source/blender/gpu/shaders/common/gpu_shader_common_mix_rgb.glsl b/source/blender/gpu/shaders/common/gpu_shader_common_mix_rgb.glsl index 39f3c722dd2..4845524d873 100644 --- a/source/blender/gpu/shaders/common/gpu_shader_common_mix_rgb.glsl +++ b/source/blender/gpu/shaders/common/gpu_shader_common_mix_rgb.glsl @@ -101,6 +101,12 @@ void mix_diff(float fac, vec4 col1, vec4 col2, out vec4 outcol) outcol.a = col1.a; } +void mix_exclusion(float fac, vec4 col1, vec4 col2, out vec4 outcol) +{ + outcol = max(mix(col1, col1 + col2 - 2.0 * col1 * col2, fac), 0.0); + outcol.a = col1.a; +} + void mix_dark(float fac, vec4 col1, vec4 col2, out vec4 outcol) { outcol.rgb = mix(col1.rgb, min(col1.rgb, col2.rgb), fac); diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_mix_color.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_mix_color.glsl index 933a8de9cb7..ec4845c84d1 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_mix_color.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_mix_color.glsl @@ -171,6 +171,23 @@ void node_mix_diff(float fac, outcol.a = col1.a; } +void node_mix_exclusion(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + outcol = max(mix(col1, col1 + col2 - 2.0 * col1 * col2, fac), 0.0); + outcol.a = col1.a; +} + void node_mix_dark(float fac, vec3 facvec, float f1, diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 460670225c8..3b8ccc2bc38 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -269,6 +269,7 @@ typedef struct Material { #define MA_RAMP_COLOR 15 #define MA_RAMP_SOFT 16 #define MA_RAMP_LINEAR 17 +#define MA_RAMP_EXCLUSION 18 /* texco */ #define TEXCO_ORCO (1 << 0) diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 71a4a4b37f4..7874f06da47 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -40,6 +40,7 @@ const EnumPropertyItem rna_enum_ramp_blend_items[] = { {MA_RAMP_LINEAR, "LINEAR_LIGHT", 0, "Linear Light", ""}, RNA_ENUM_ITEM_SEPR, {MA_RAMP_DIFF, "DIFFERENCE", 0, "Difference", ""}, + {MA_RAMP_EXCLUSION, "EXCLUSION", 0, "Exclusion", ""}, {MA_RAMP_SUB, "SUBTRACT", 0, "Subtract", ""}, {MA_RAMP_DIV, "DIVIDE", 0, "Divide", ""}, RNA_ENUM_ITEM_SEPR, diff --git a/source/blender/nodes/composite/nodes/node_composite_mixrgb.cc b/source/blender/nodes/composite/nodes/node_composite_mixrgb.cc index a1fbbfe7d40..acdd569971a 100644 --- a/source/blender/nodes/composite/nodes/node_composite_mixrgb.cc +++ b/source/blender/nodes/composite/nodes/node_composite_mixrgb.cc @@ -93,6 +93,8 @@ class MixRGBShaderNode : public ShaderNode { return "mix_div"; case MA_RAMP_DIFF: return "mix_diff"; + case MA_RAMP_EXCLUSION: + return "mix_exclusion"; case MA_RAMP_DARK: return "mix_dark"; case MA_RAMP_LIGHT: diff --git a/source/blender/nodes/shader/nodes/node_shader_mix.cc b/source/blender/nodes/shader/nodes/node_shader_mix.cc index 68344153591..4200041605c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix.cc @@ -258,6 +258,8 @@ static const char *gpu_shader_get_name(eNodeSocketDatatype data_type, return "node_mix_div_fallback"; case MA_RAMP_DIFF: return "node_mix_diff"; + case MA_RAMP_EXCLUSION: + return "node_mix_exclusion"; case MA_RAMP_DARK: return "node_mix_dark"; case MA_RAMP_LIGHT: diff --git a/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc index 98771098f81..aadbdbe4716 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc @@ -35,6 +35,8 @@ static const char *gpu_shader_get_name(int mode) return "mix_div_fallback"; case MA_RAMP_DIFF: return "mix_diff"; + case MA_RAMP_EXCLUSION: + return "mix_exclusion"; case MA_RAMP_DARK: return "mix_dark"; case MA_RAMP_LIGHT: From 9e94135f17906c64e8306e893cd76dbef59dda15 Mon Sep 17 00:00:00 2001 From: Christophe Hery Date: Fri, 16 Dec 2022 09:42:30 -0600 Subject: [PATCH 0172/1522] Fix: Crash after mesh color attribute name commit 6514bb05ea5a138d8971 missed a null check when accessing the active and default color attribute names, since the CustomData API does not do that check itself. --- .../blender/blenkernel/intern/mesh_legacy_convert.cc | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index a53b0e66924..28bbc0ffae3 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -544,11 +544,15 @@ static void update_active_fdata_layers(Mesh &mesh, CustomData *fdata, CustomData } if (CustomData_has_layer(ldata, CD_PROP_BYTE_COLOR)) { - act = CustomData_get_named_layer(ldata, CD_PROP_BYTE_COLOR, mesh.active_color_attribute); - CustomData_set_layer_active(fdata, CD_MCOL, act); + if (mesh.active_color_attribute != NULL) { + act = CustomData_get_named_layer(ldata, CD_PROP_BYTE_COLOR, mesh.active_color_attribute); + CustomData_set_layer_active(fdata, CD_MCOL, act); + } - act = CustomData_get_named_layer(ldata, CD_PROP_BYTE_COLOR, mesh.default_color_attribute); - CustomData_set_layer_render(fdata, CD_MCOL, act); + if (mesh.default_color_attribute != NULL) { + act = CustomData_get_named_layer(ldata, CD_PROP_BYTE_COLOR, mesh.default_color_attribute); + CustomData_set_layer_render(fdata, CD_MCOL, act); + } act = CustomData_get_clone_layer(ldata, CD_PROP_BYTE_COLOR); CustomData_set_layer_clone(fdata, CD_MCOL, act); From d77a6849e664d2506f8a3a0392f7864534870dfd Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 16 Dec 2022 09:43:39 -0600 Subject: [PATCH 0173/1522] Cleanup: Remove duplicate UV islands header This code was duplicated from `pbvh_uv_islands.hh`, which was the version that was actually used. --- source/blender/blenkernel/BKE_uv_islands.hh | 746 -------------------- source/blender/blenkernel/CMakeLists.txt | 1 - 2 files changed, 747 deletions(-) delete mode 100644 source/blender/blenkernel/BKE_uv_islands.hh diff --git a/source/blender/blenkernel/BKE_uv_islands.hh b/source/blender/blenkernel/BKE_uv_islands.hh deleted file mode 100644 index 406ecf39b71..00000000000 --- a/source/blender/blenkernel/BKE_uv_islands.hh +++ /dev/null @@ -1,746 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include -#include - -#include "BLI_array.hh" -#include "BLI_edgehash.h" -#include "BLI_float3x3.hh" -#include "BLI_map.hh" -#include "BLI_math.h" -#include "BLI_math_vec_types.hh" -#include "BLI_rect.h" -#include "BLI_vector.hh" -#include "BLI_vector_list.hh" - -#include "DNA_meshdata_types.h" - -namespace blender::bke::uv_islands { - -struct MeshEdge; -struct MeshPrimitive; -struct UVBorder; -struct UVEdge; -struct UVIslands; -struct UVIslandsMask; -struct UVPrimitive; -struct UVPrimitiveEdge; -struct UVVertex; - -struct MeshVertex { - int64_t v; - Vector edges; -}; - -struct MeshUVVert { - MeshVertex *vertex; - float2 uv; - int64_t loop; -}; - -struct MeshEdge { - MeshVertex *vert1; - MeshVertex *vert2; - Vector primitives; -}; - -/** Represents a triangle in 3d space (MLoopTri) */ -struct MeshPrimitive { - int64_t index; - int64_t poly; - Vector edges; - Vector vertices; - - /** - * UV island this primitive belongs to. This is used to speed up the initial uv island - * extraction, but should not be used when extending uv islands. - */ - int64_t uv_island_id; - - MeshUVVert *get_other_uv_vertex(const MeshVertex *v1, const MeshVertex *v2) - { - BLI_assert(vertices[0].vertex == v1 || vertices[1].vertex == v1 || vertices[2].vertex == v1); - BLI_assert(vertices[0].vertex == v2 || vertices[1].vertex == v2 || vertices[2].vertex == v2); - for (MeshUVVert &uv_vertex : vertices) { - if (uv_vertex.vertex != v1 && uv_vertex.vertex != v2) { - return &uv_vertex; - } - } - return nullptr; - } - - rctf uv_bounds() const; - - bool has_shared_uv_edge(const MeshPrimitive *other) const - { - int shared_uv_verts = 0; - for (const MeshUVVert &vert : vertices) { - for (const MeshUVVert &other_vert : other->vertices) { - if (vert.uv == other_vert.uv) { - shared_uv_verts += 1; - } - } - } - return shared_uv_verts >= 2; - } -}; - -/** - * MeshData contains input geometry data converted in a list of primitives, edges and vertices for - * quick access for both local space and uv space. - */ -struct MeshData { - public: - const MLoopTri *looptri; - const int64_t looptri_len; - const int64_t vert_len; - const MLoop *mloop; - const MLoopUV *mloopuv; - - public: - Vector primitives; - Vector edges; - Vector vertices; - /** Total number of uv islands detected. */ - int64_t uv_island_len; - - explicit MeshData(const MLoopTri *looptri, - const int64_t looptri_len, - const int64_t vert_len, - const MLoop *mloop, - const MLoopUV *mloopuv) - : looptri(looptri), - looptri_len(looptri_len), - vert_len(vert_len), - mloop(mloop), - mloopuv(mloopuv) - { - init_vertices(); - init_primitives(); - init_edges(); - init_primitive_uv_island_ids(); - } - - void init_vertices() - { - vertices.reserve(vert_len); - for (int64_t i = 0; i < vert_len; i++) { - MeshVertex vert; - vert.v = i; - vertices.append(vert); - } - } - - void init_primitives() - { - primitives.reserve(looptri_len); - for (int64_t i = 0; i < looptri_len; i++) { - const MLoopTri &tri = looptri[i]; - MeshPrimitive primitive; - primitive.index = i; - primitive.poly = tri.poly; - - for (int j = 0; j < 3; j++) { - MeshUVVert uv_vert; - uv_vert.loop = tri.tri[j]; - uv_vert.vertex = &vertices[mloop[uv_vert.loop].v]; - uv_vert.uv = mloopuv[uv_vert.loop].uv; - primitive.vertices.append(uv_vert); - } - primitives.append(primitive); - } - } - - void init_edges() - { - edges.reserve(looptri_len * 2); - EdgeHash *eh = BLI_edgehash_new_ex(__func__, looptri_len * 3); - for (int64_t i = 0; i < looptri_len; i++) { - const MLoopTri &tri = looptri[i]; - MeshPrimitive &primitive = primitives[i]; - for (int j = 0; j < 3; j++) { - int v1 = mloop[tri.tri[j]].v; - int v2 = mloop[tri.tri[(j + 1) % 3]].v; - /* TODO: Use lookup_ptr to be able to store edge 0. */ - void *v = BLI_edgehash_lookup(eh, v1, v2); - int64_t edge_index; - if (v == nullptr) { - edge_index = edges.size(); - BLI_edgehash_insert(eh, v1, v2, POINTER_FROM_INT(edge_index + 1)); - MeshEdge edge; - edge.vert1 = &vertices[v1]; - edge.vert2 = &vertices[v2]; - edges.append(edge); - MeshEdge *edge_ptr = &edges.last(); - vertices[v1].edges.append(edge_ptr); - vertices[v2].edges.append(edge_ptr); - } - else { - edge_index = POINTER_AS_INT(v) - 1; - } - - MeshEdge *edge = &edges[edge_index]; - edge->primitives.append(&primitive); - primitive.edges.append(edge); - } - } - BLI_edgehash_free(eh, nullptr); - } - - static const int64_t INVALID_UV_ISLAND_ID = -1; - /** - * NOTE: doesn't support weird topology where unconnected mesh primitives share the same uv - * island. For a accurate implementation we should use implement an uv_prim_lookup. - */ - static void extract_uv_neighbors(Vector &prims_to_add, MeshPrimitive *primitive) - { - for (MeshEdge *edge : primitive->edges) { - for (MeshPrimitive *other_primitive : edge->primitives) { - if (primitive == other_primitive) { - continue; - } - if (other_primitive->uv_island_id != MeshData::INVALID_UV_ISLAND_ID) { - continue; - } - - if (primitive->has_shared_uv_edge(other_primitive)) { - prims_to_add.append(other_primitive); - } - } - } - } - - void init_primitive_uv_island_ids() - { - for (MeshPrimitive &primitive : primitives) { - primitive.uv_island_id = INVALID_UV_ISLAND_ID; - } - - int64_t uv_island_id = 0; - Vector prims_to_add; - for (MeshPrimitive &primitive : primitives) { - /* Early exit when uv island id is already extracted during uv neighbor extractions. */ - if (primitive.uv_island_id != INVALID_UV_ISLAND_ID) { - continue; - } - - prims_to_add.append(&primitive); - while (!prims_to_add.is_empty()) { - MeshPrimitive *primitive = prims_to_add.pop_last(); - primitive->uv_island_id = uv_island_id; - extract_uv_neighbors(prims_to_add, primitive); - } - uv_island_id++; - } - uv_island_len = uv_island_id; - } -}; - -struct UVVertex { - MeshVertex *vertex; - /* Position in uv space. */ - float2 uv; - - /* uv edges that share this UVVertex. */ - Vector uv_edges; - - struct { - bool is_border : 1; - bool is_extended : 1; - } flags; - - explicit UVVertex() - { - flags.is_border = false; - flags.is_extended = false; - } - - explicit UVVertex(const MeshUVVert &vert) : vertex(vert.vertex), uv(vert.uv) - { - flags.is_border = false; - flags.is_extended = false; - } -}; - -struct UVEdge { - std::array vertices; - Vector uv_primitives; - - bool has_shared_edge(const MeshUVVert &v1, const MeshUVVert &v2) const - { - return (vertices[0]->uv == v1.uv && vertices[1]->uv == v2.uv) || - (vertices[0]->uv == v2.uv && vertices[1]->uv == v1.uv); - } - - bool has_shared_edge(const UVVertex &v1, const UVVertex &v2) const - { - return (vertices[0]->uv == v1.uv && vertices[1]->uv == v2.uv) || - (vertices[0]->uv == v2.uv && vertices[1]->uv == v1.uv); - } - - bool has_shared_edge(const UVEdge &other) const - { - return has_shared_edge(*other.vertices[0], *other.vertices[1]); - } - - bool has_same_vertices(const MeshVertex &vert1, const MeshVertex &vert2) const - { - return (vertices[0]->vertex == &vert1 && vertices[1]->vertex == &vert2) || - (vertices[0]->vertex == &vert2 && vertices[1]->vertex == &vert1); - } - - bool has_same_uv_vertices(const UVEdge &other) const - { - return has_shared_edge(other) && - has_same_vertices(*other.vertices[0]->vertex, *other.vertices[1]->vertex); - ; - } - - bool has_same_vertices(const MeshEdge &edge) const - { - return has_same_vertices(*edge.vert1, *edge.vert2); - } - - bool is_border_edge() const - { - return uv_primitives.size() == 1; - } - - void append_to_uv_vertices() - { - for (UVVertex *vertex : vertices) { - vertex->uv_edges.append_non_duplicates(this); - } - } - - UVVertex *get_other_uv_vertex(const MeshVertex *vertex) - { - if (vertices[0]->vertex == vertex) { - return vertices[1]; - } - return vertices[0]; - } -}; - -struct UVPrimitive { - /** - * Index of the primitive in the original mesh. - */ - MeshPrimitive *primitive; - Vector edges; - - explicit UVPrimitive(MeshPrimitive *primitive) : primitive(primitive) - { - } - - void append_to_uv_edges() - { - for (UVEdge *uv_edge : edges) { - uv_edge->uv_primitives.append_non_duplicates(this); - } - } - void append_to_uv_vertices() - { - for (UVEdge *uv_edge : edges) { - uv_edge->append_to_uv_vertices(); - } - } - - Vector> shared_edges(UVPrimitive &other) - { - Vector> result; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (edges[i]->has_shared_edge(*other.edges[j])) { - result.append(std::pair(edges[i], other.edges[j])); - } - } - } - return result; - } - - bool has_shared_edge(const UVPrimitive &other) const - { - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (edges[i]->has_shared_edge(*other.edges[j])) { - return true; - } - } - } - return false; - } - - bool has_shared_edge(const MeshPrimitive &primitive) const - { - for (const UVEdge *uv_edge : edges) { - const MeshUVVert *v1 = &primitive.vertices.last(); - for (int i = 0; i < primitive.vertices.size(); i++) { - const MeshUVVert *v2 = &primitive.vertices[i]; - if (uv_edge->has_shared_edge(*v1, *v2)) { - return true; - } - v1 = v2; - } - } - return false; - } - - /** - * Get the UVVertex in the order that the verts are ordered in the MeshPrimitive. - */ - const UVVertex *get_uv_vertex(const uint8_t mesh_vert_index) const - { - const MeshVertex *mesh_vertex = primitive->vertices[mesh_vert_index].vertex; - for (const UVEdge *uv_edge : edges) { - for (const UVVertex *uv_vert : uv_edge->vertices) { - if (uv_vert->vertex == mesh_vertex) { - return uv_vert; - } - } - } - BLI_assert_unreachable(); - return nullptr; - } - - /** - * Get the UVEdge that share the given uv coordinates. - * Will assert when no UVEdge found. - */ - UVEdge *get_uv_edge(const float2 uv1, const float2 uv2) const - { - for (UVEdge *uv_edge : edges) { - const float2 &e1 = uv_edge->vertices[0]->uv; - const float2 &e2 = uv_edge->vertices[1]->uv; - if ((e1 == uv1 && e2 == uv2) || (e1 == uv2 && e2 == uv1)) { - return uv_edge; - } - } - BLI_assert_unreachable(); - return nullptr; - } - - UVEdge *get_uv_edge(const MeshVertex *v1, const MeshVertex *v2) const - { - for (UVEdge *uv_edge : edges) { - const MeshVertex *e1 = uv_edge->vertices[0]->vertex; - const MeshVertex *e2 = uv_edge->vertices[1]->vertex; - if ((e1 == v1 && e2 == v2) || (e1 == v2 && e2 == v1)) { - return uv_edge; - } - } - BLI_assert_unreachable(); - return nullptr; - } - - const bool contains_uv_vertex(const UVVertex *uv_vertex) const - { - for (UVEdge *edge : edges) { - if (std::find(edge->vertices.begin(), edge->vertices.end(), uv_vertex) != - edge->vertices.end()) { - return true; - } - } - return false; - } - - const UVVertex *get_other_uv_vertex(const UVVertex *v1, const UVVertex *v2) const - { - BLI_assert(contains_uv_vertex(v1)); - BLI_assert(contains_uv_vertex(v2)); - - for (const UVEdge *edge : edges) { - for (const UVVertex *uv_vertex : edge->vertices) { - if (uv_vertex != v1 && uv_vertex != v2) { - return uv_vertex; - } - } - } - BLI_assert_unreachable(); - return nullptr; - } - - UVBorder extract_border() const; -}; - -struct UVBorderEdge { - UVEdge *edge; - bool tag = false; - UVPrimitive *uv_primitive; - /* Should the vertices of the edge be evaluated in reverse order. */ - bool reverse_order = false; - - int64_t index = -1; - int64_t prev_index = -1; - int64_t next_index = -1; - int64_t border_index = -1; - - explicit UVBorderEdge(UVEdge *edge, UVPrimitive *uv_primitive) - : edge(edge), uv_primitive(uv_primitive) - { - } - - UVVertex *get_uv_vertex(int index) - { - int actual_index = reverse_order ? 1 - index : index; - return edge->vertices[actual_index]; - } - - const UVVertex *get_uv_vertex(int index) const - { - int actual_index = reverse_order ? 1 - index : index; - return edge->vertices[actual_index]; - } - - /** - * Get the uv vertex from the primitive that is not part of the edge. - */ - const UVVertex *get_other_uv_vertex() const - { - return uv_primitive->get_other_uv_vertex(edge->vertices[0], edge->vertices[1]); - } - - float length() const - { - return len_v2v2(edge->vertices[0]->uv, edge->vertices[1]->uv); - } -}; - -struct UVBorderCorner { - UVBorderEdge *first; - UVBorderEdge *second; - float angle; - - UVBorderCorner(UVBorderEdge *first, UVBorderEdge *second, float angle) - : first(first), second(second), angle(angle) - { - } - - /** - * Calculate a uv coordinate between the edges of the corner. - * - * 'min_uv_distance' is the minimum distance between the corner and the - * resulting uv coordinate. The distance is in uv space. - */ - float2 uv(float factor, float min_uv_distance); -}; - -struct UVBorder { - /** Ordered list of UV Verts of the border of this island. */ - // TODO: support multiple rings + order (CW, CCW) - Vector edges; - - /** - * Check if the border is counter clock wise from its island. - */ - bool is_ccw() const; - - /** - * Flip the order of the verts, changing the order between CW and CCW. - */ - void flip(); - - /** - * Calculate the outside angle of the given vert. - */ - float outside_angle(const UVBorderEdge &vert) const; - - void update_indexes(uint64_t border_index); - - static std::optional extract_from_edges(Vector &edges); - - /** Remove edge from the border. updates the indexes. */ - void remove(int64_t index) - { - /* Could read the border_index from any border edge as they are consistent. */ - uint64_t border_index = edges[0].border_index; - edges.remove(index); - update_indexes(border_index); - } -}; - -struct UVIsland { - VectorList uv_vertices; - VectorList uv_edges; - VectorList uv_primitives; - /** - * List of borders of this island. There can be multiple borders per island as a border could - * be completely encapsulated by another one. - */ - Vector borders; - - /** - * Key is mesh vert index, Value is list of UVVertices that refer to the mesh vertex with that - * index. Map is used internally to quickly lookup similar UVVertices. - */ - Map> uv_vertex_lookup; - - UVVertex *lookup(const UVVertex &vertex) - { - int64_t vert_index = vertex.vertex->v; - Vector &vertices = uv_vertex_lookup.lookup_or_add_default(vert_index); - for (UVVertex *v : vertices) { - if (v->uv == vertex.uv) { - return v; - } - } - return nullptr; - } - - UVVertex *lookup_or_create(const UVVertex &vertex) - { - UVVertex *found_vertex = lookup(vertex); - if (found_vertex != nullptr) { - return found_vertex; - } - - uv_vertices.append(vertex); - UVVertex *result = &uv_vertices.last(); - result->uv_edges.clear(); - /* v is already a key. Ensured by UVIsland::lookup in this method. */ - uv_vertex_lookup.lookup(vertex.vertex->v).append(result); - return result; - } - - UVEdge *lookup(const UVEdge &edge) - { - UVVertex *found_vertex = lookup(*edge.vertices[0]); - if (found_vertex == nullptr) { - return nullptr; - } - for (UVEdge *e : found_vertex->uv_edges) { - UVVertex *other_vertex = e->get_other_uv_vertex(found_vertex->vertex); - if (other_vertex->vertex == edge.vertices[1]->vertex && - other_vertex->uv == edge.vertices[1]->uv) { - return e; - } - } - return nullptr; - } - - UVEdge *lookup_or_create(const UVEdge &edge) - { - UVEdge *found_edge = lookup(edge); - if (found_edge != nullptr) { - return found_edge; - } - - uv_edges.append(edge); - UVEdge *result = &uv_edges.last(); - result->uv_primitives.clear(); - return result; - } - - /** Initialize the border attribute. */ - void extract_borders(); - /** Iterative extend border to fit the mask. */ - void extend_border(const UVIslandsMask &mask, const short island_index); - - private: - void append(const UVPrimitive &primitive) - { - uv_primitives.append(primitive); - UVPrimitive *new_prim_ptr = &uv_primitives.last(); - for (int i = 0; i < 3; i++) { - UVEdge *other_edge = primitive.edges[i]; - UVEdge uv_edge_template; - uv_edge_template.vertices[0] = lookup_or_create(*other_edge->vertices[0]); - uv_edge_template.vertices[1] = lookup_or_create(*other_edge->vertices[1]); - new_prim_ptr->edges[i] = lookup_or_create(uv_edge_template); - new_prim_ptr->edges[i]->append_to_uv_vertices(); - new_prim_ptr->edges[i]->uv_primitives.append(new_prim_ptr); - } - } - - public: - bool has_shared_edge(const UVPrimitive &primitive) const - { - for (const VectorList::UsedVector &prims : uv_primitives) { - for (const UVPrimitive &prim : prims) { - if (prim.has_shared_edge(primitive)) { - return true; - } - } - } - return false; - } - - bool has_shared_edge(const MeshPrimitive &primitive) const - { - for (const VectorList::UsedVector &primitives : uv_primitives) { - for (const UVPrimitive &prim : primitives) { - if (prim.has_shared_edge(primitive)) { - return true; - } - } - } - return false; - } - - const void extend_border(const UVPrimitive &primitive) - { - for (const VectorList::UsedVector &primitives : uv_primitives) { - for (const UVPrimitive &prim : primitives) { - if (prim.has_shared_edge(primitive)) { - append(primitive); - } - } - } - } -}; - -struct UVIslands { - Vector islands; - - explicit UVIslands(MeshData &mesh_data); - - void extract_borders(); - void extend_borders(const UVIslandsMask &islands_mask); -}; - -/** Mask to find the index of the UVIsland for a given UV coordinate. */ -struct UVIslandsMask { - - /** Mask for each udim tile. */ - struct Tile { - float2 udim_offset; - ushort2 tile_resolution; - ushort2 mask_resolution; - Array mask; - - Tile(float2 udim_offset, ushort2 tile_resolution); - - bool is_masked(const uint16_t island_index, const float2 uv) const; - bool contains(const float2 uv) const; - float get_pixel_size_in_uv_space() const; - }; - - Vector tiles; - - void add_tile(float2 udim_offset, ushort2 resolution); - - /** - * Find a tile containing the given uv coordinate. - */ - const Tile *find_tile(const float2 uv) const; - - /** - * Is the given uv coordinate part of the given island_index mask. - * - * true - part of the island mask. - * false - not part of the island mask. - */ - bool is_masked(const uint16_t island_index, const float2 uv) const; - - /** - * Add the given UVIslands to the mask. Tiles should be added beforehand using the 'add_tile' - * method. - */ - void add(const UVIslands &islands); - - void dilate(int max_iterations); -}; - -} // namespace blender::bke::uv_islands diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 7bd87323ede..d645408c6e9 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -480,7 +480,6 @@ set(SRC BKE_type_conversions.hh BKE_undo_system.h BKE_unit.h - BKE_uv_islands.hh BKE_vfont.h BKE_vfontdata.h BKE_viewer_path.h From ea731f42db32bf8bf3bf0f799fb4a6d298922b52 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Fri, 16 Dec 2022 17:01:03 +0100 Subject: [PATCH 0174/1522] Fix T103187: Opening node search menu is slow because of assets. Avoid utility function call that would query the file system, this was a bottleneck. The path joining was also problematic. See patch for more details. Differential Revision: https://developer.blender.org/D16768 Reviewed by: Jacques Lucke --- source/blender/editors/space_file/filelist.cc | 26 +++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc index bf0f9c865a8..c40ba5d016b 100644 --- a/source/blender/editors/space_file/filelist.cc +++ b/source/blender/editors/space_file/filelist.cc @@ -323,7 +323,6 @@ static void filelist_readjob_main_assets(FileListReadJob *job_params, /* helper, could probably go in BKE actually? */ static int groupname_to_code(const char *group); -static uint64_t groupname_to_filter_id(const char *group); static void filelist_cache_clear(FileListEntryCache *cache, size_t new_size); static bool filelist_intern_entry_is_main_file(const FileListInternEntry *intern_entry); @@ -751,7 +750,7 @@ static bool is_filtered_file(FileListInternEntry *file, } static bool is_filtered_id_file_type(const FileListInternEntry *file, - const char *id_group, + const short id_code, const char *name, const FileListFilter *filter) { @@ -761,12 +760,12 @@ static bool is_filtered_id_file_type(const FileListInternEntry *file, /* We only check for types if some type are enabled in filtering. */ if ((filter->filter || filter->filter_id) && (filter->flags & FLF_DO_FILTER)) { - if (id_group) { + if (id_code) { if (!name && (filter->flags & FLF_HIDE_LIB_DIR)) { return false; } - uint64_t filter_id = groupname_to_filter_id(id_group); + const uint64_t filter_id = BKE_idtype_idcode_to_idfilter(id_code); if (!(filter_id & filter->filter_id)) { return false; } @@ -851,15 +850,11 @@ static bool is_filtered_asset(FileListInternEntry *file, FileListFilter *filter) } static bool is_filtered_lib_type(FileListInternEntry *file, - const char *root, + const char * /*root*/, FileListFilter *filter) { - char path[FILE_MAX_LIBEXTRA], dir[FILE_MAX_LIBEXTRA], *group, *name; - - BLI_path_join(path, sizeof(path), root, file->relpath); - - if (BLO_library_path_explode(path, dir, &group, &name)) { - return is_filtered_id_file_type(file, group, name, filter); + if (file->typeflag & FILE_TYPE_BLENDERLIB) { + return is_filtered_id_file_type(file, file->blentype, file->name, filter); } return is_filtered_file_type(file, filter); } @@ -881,7 +876,7 @@ static bool is_filtered_main_assets(FileListInternEntry *file, FileListFilter *filter) { /* "Filtered" means *not* being filtered out... So return true if the file should be visible. */ - return is_filtered_id_file_type(file, file->relpath, file->name, filter) && + return is_filtered_id_file_type(file, file->blentype, file->name, filter) && is_filtered_asset(file, filter); } @@ -2882,13 +2877,6 @@ static int groupname_to_code(const char *group) return buf[0] ? BKE_idtype_idcode_from_name(buf) : 0; } -static uint64_t groupname_to_filter_id(const char *group) -{ - int id_code = groupname_to_code(group); - - return BKE_idtype_idcode_to_idfilter(id_code); -} - /** * From here, we are in 'Job Context', * i.e. have to be careful about sharing stuff between background working thread. From 6ced6c9545e54d3e27ec6d233b31e902d6624924 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 16 Dec 2022 11:02:43 -0600 Subject: [PATCH 0175/1522] Fix std::optional value() build error on older macOS SDK Patch from @dupoxy Differential Revision: https://developer.blender.org/D16796 --- source/blender/nodes/geometry/nodes/node_geo_set_position.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index e219d5bc0a1..ec8c82fc66d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -33,7 +33,7 @@ static void set_computed_position_and_offset(GeometryComponent &component, if (in_positions.is_same(positions_read_only)) { if (const std::optional offset = in_offsets.get_if_single()) { - if (math::is_zero(offset.value())) { + if (math::is_zero(*offset)) { return; } } From 3aca0bc66a479e1cca9b688e8140da3ee06e8397 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 16 Dec 2022 18:30:47 +0100 Subject: [PATCH 0176/1522] Geometry Nodes: simplify handling of invalid group interface sockets Previously, the code tried to keep node groups working even if some of their input/output sockets had undefined type. This caused some complexity with no benefit because not all places outside of this file would handle the case correctly. Now node groups with undefined interface sockets are disabled and have to be fixed manually before they work again. Undefined interface sockets are mostly caused by invalid Python API usage and incomplete forward compatibility (e.g. when newer versions introduce new socket types that the older version does not know). --- source/blender/blenkernel/BKE_node_runtime.hh | 14 +++ .../blender/blenkernel/intern/node_runtime.cc | 8 ++ source/blender/makesdna/DNA_node_types.h | 3 + .../intern/geometry_nodes_lazy_function.cc | 104 ++++++------------ 4 files changed, 59 insertions(+), 70 deletions(-) diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 6a00e70cb5b..b4b9df32663 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -141,6 +141,8 @@ class bNodeTreeRuntime : NonCopyable, NonMovable { bool has_undefined_nodes_or_sockets = false; bNode *group_output_node = nullptr; Vector root_frames; + Vector interface_inputs; + Vector interface_outputs; }; /** @@ -426,6 +428,18 @@ inline blender::Span bNodeTree::group_input_nodes() const return this->nodes_by_type("NodeGroupInput"); } +inline blender::Span bNodeTree::interface_inputs() const +{ + BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this)); + return this->runtime->interface_inputs; +} + +inline blender::Span bNodeTree::interface_outputs() const +{ + BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this)); + return this->runtime->interface_outputs; +} + inline blender::Span bNodeTree::all_input_sockets() const { BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this)); diff --git a/source/blender/blenkernel/intern/node_runtime.cc b/source/blender/blenkernel/intern/node_runtime.cc index 4bdc8f6f9b8..0f0b04f920e 100644 --- a/source/blender/blenkernel/intern/node_runtime.cc +++ b/source/blender/blenkernel/intern/node_runtime.cc @@ -42,6 +42,13 @@ static void double_checked_lock_with_task_isolation(std::mutex &mutex, double_checked_lock(mutex, data_is_dirty, [&]() { threading::isolate_task(fn); }); } +static void update_interface_sockets(const bNodeTree &ntree) +{ + bNodeTreeRuntime &tree_runtime = *ntree.runtime; + tree_runtime.interface_inputs = ntree.inputs; + tree_runtime.interface_outputs = ntree.outputs; +} + static void update_node_vector(const bNodeTree &ntree) { bNodeTreeRuntime &tree_runtime = *ntree.runtime; @@ -429,6 +436,7 @@ static void ensure_topology_cache(const bNodeTree &ntree) bNodeTreeRuntime &tree_runtime = *ntree.runtime; double_checked_lock_with_task_isolation( tree_runtime.topology_cache_mutex, tree_runtime.topology_cache_is_dirty, [&]() { + update_interface_sockets(ntree); update_node_vector(ntree); update_link_vector(ntree); update_socket_vectors_and_owner_node(ntree); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index eddc26fe867..6acb2208962 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -636,6 +636,9 @@ typedef struct bNodeTree { const bNode *group_output_node() const; /** Get all input nodes of the node group. */ blender::Span group_input_nodes() const; + /** Inputs and outputs of the entire node group. */ + blender::Span interface_inputs() const; + blender::Span interface_outputs() const; #endif } bNodeTree; diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 8d11089f253..9ded1827ccc 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -746,20 +746,9 @@ struct GeometryNodesLazyFunctionGraphBuilder { /** * All group input nodes are combined into one dummy node in the lazy-function graph. - * If some input has an invalid type, it is ignored in the new graph. In this case null and -1 is - * used in the vectors below. */ - Vector group_input_types_; - Vector group_input_indices_; lf::DummyNode *group_input_lf_node_; - /** - * The output types or null if an output is invalid. Each group output node gets a separate - * corresponding dummy node in the new graph. - */ - Vector group_output_types_; - Vector group_output_indices_; - public: GeometryNodesLazyFunctionGraphBuilder(const bNodeTree &btree, GeometryNodesLazyFunctionGraphInfo &lf_graph_info) @@ -776,8 +765,6 @@ struct GeometryNodesLazyFunctionGraphBuilder { conversions_ = &bke::get_implicit_type_conversions(); this->prepare_node_multi_functions(); - this->prepare_group_inputs(); - this->prepare_group_outputs(); this->build_group_input_node(); this->handle_nodes(); this->handle_links(); @@ -793,50 +780,21 @@ struct GeometryNodesLazyFunctionGraphBuilder { lf_graph_info_->node_multi_functions = std::make_unique(btree_); } - void prepare_group_inputs() - { - LISTBASE_FOREACH (const bNodeSocket *, interface_bsocket, &btree_.inputs) { - const CPPType *type = get_socket_cpp_type(*interface_bsocket->typeinfo); - if (type != nullptr) { - const int index = group_input_types_.append_and_get_index(type); - group_input_indices_.append(index); - } - else { - group_input_indices_.append(-1); - } - } - } - - void prepare_group_outputs() - { - LISTBASE_FOREACH (const bNodeSocket *, interface_bsocket, &btree_.outputs) { - const CPPType *type = get_socket_cpp_type(*interface_bsocket->typeinfo); - if (type != nullptr) { - const int index = group_output_types_.append_and_get_index(type); - group_output_indices_.append(index); - } - else { - group_output_indices_.append(-1); - } - } - } - void build_group_input_node() { + Vector input_cpp_types; + const Span interface_inputs = btree_.interface_inputs(); + for (const bNodeSocket *interface_input : interface_inputs) { + input_cpp_types.append(interface_input->typeinfo->geometry_nodes_cpp_type); + } + /* Create a dummy node for the group inputs. */ auto debug_info = std::make_unique(); - group_input_lf_node_ = &lf_graph_->add_dummy({}, group_input_types_, debug_info.get()); + group_input_lf_node_ = &lf_graph_->add_dummy({}, input_cpp_types, debug_info.get()); - const bNodeSocket *interface_bsocket = static_cast(btree_.inputs.first); - for (const int group_input_index : group_input_indices_) { - BLI_SCOPED_DEFER([&]() { interface_bsocket = interface_bsocket->next; }); - if (group_input_index == -1) { - mapping_->group_input_sockets.append(nullptr); - } - else { - mapping_->group_input_sockets.append(&group_input_lf_node_->output(group_input_index)); - debug_info->socket_names.append(interface_bsocket->name); - } + for (const int i : interface_inputs.index_range()) { + mapping_->group_input_sockets.append(&group_input_lf_node_->output(i)); + debug_info->socket_names.append(interface_inputs[i]->name); } lf_graph_info_->dummy_debug_infos_.append(std::move(debug_info)); } @@ -946,13 +904,9 @@ struct GeometryNodesLazyFunctionGraphBuilder { void handle_group_input_node(const bNode &bnode) { - for (const int btree_index : group_input_indices_.index_range()) { - const int lf_index = group_input_indices_[btree_index]; - if (lf_index == -1) { - continue; - } - const bNodeSocket &bsocket = bnode.output_socket(btree_index); - lf::OutputSocket &lf_socket = group_input_lf_node_->output(lf_index); + for (const int i : btree_.interface_inputs().index_range()) { + const bNodeSocket &bsocket = bnode.output_socket(i); + lf::OutputSocket &lf_socket = group_input_lf_node_->output(i); output_socket_map_.add_new(&bsocket, &lf_socket); mapping_->dummy_socket_map.add_new(&bsocket, &lf_socket); mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket); @@ -961,23 +915,23 @@ struct GeometryNodesLazyFunctionGraphBuilder { void handle_group_output_node(const bNode &bnode) { + Vector output_cpp_types; + const Span interface_outputs = btree_.interface_outputs(); + for (const bNodeSocket *interface_input : interface_outputs) { + output_cpp_types.append(interface_input->typeinfo->geometry_nodes_cpp_type); + } + auto debug_info = std::make_unique(); lf::DummyNode &group_output_lf_node = lf_graph_->add_dummy( - group_output_types_, {}, debug_info.get()); + output_cpp_types, {}, debug_info.get()); - const bNodeSocket *interface_bsocket = static_cast(btree_.outputs.first); - for (const int btree_index : group_output_indices_.index_range()) { - BLI_SCOPED_DEFER([&]() { interface_bsocket = interface_bsocket->next; }); - const int lf_index = group_output_indices_[btree_index]; - if (lf_index == -1) { - continue; - } - const bNodeSocket &bsocket = bnode.input_socket(btree_index); - lf::InputSocket &lf_socket = group_output_lf_node.input(lf_index); + for (const int i : interface_outputs.index_range()) { + const bNodeSocket &bsocket = bnode.input_socket(i); + lf::InputSocket &lf_socket = group_output_lf_node.input(i); input_socket_map_.add(&bsocket, &lf_socket); mapping_->dummy_socket_map.add(&bsocket, &lf_socket); mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket); - debug_info->socket_names.append(interface_bsocket->name); + debug_info->socket_names.append(interface_outputs[i]->name); } lf_graph_info_->dummy_debug_infos_.append(std::move(debug_info)); @@ -1310,6 +1264,16 @@ const GeometryNodesLazyFunctionGraphInfo *ensure_geometry_nodes_lazy_function_gr return nullptr; } } + for (const bNodeSocket *interface_bsocket : btree.interface_inputs()) { + if (interface_bsocket->typeinfo->geometry_nodes_cpp_type == nullptr) { + return nullptr; + } + } + for (const bNodeSocket *interface_bsocket : btree.interface_outputs()) { + if (interface_bsocket->typeinfo->geometry_nodes_cpp_type == nullptr) { + return nullptr; + } + } std::unique_ptr &lf_graph_info_ptr = btree.runtime->geometry_nodes_lazy_function_graph_info; From 5ffcd8779eb27145cbc8de0450be0e2c7b03a915 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 16 Dec 2022 19:39:14 +0100 Subject: [PATCH 0177/1522] Fix: socket tooltip not showing when there was no type conversion --- source/blender/editors/space_node/node_draw.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 2790e8de6a8..4d551557bac 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -833,10 +833,13 @@ static void create_inspection_string_for_generic_value(const bNodeSocket &socket const CPPType &socket_type = *socket.typeinfo->base_cpp_type; const bke::DataTypeConversions &convert = bke::get_implicit_type_conversions(); - if (!convert.is_convertible(value_type, socket_type)) { - return; + if (value_type != socket_type) { + if (!convert.is_convertible(value_type, socket_type)) { + return; + } } BUFFER_FOR_CPP_TYPE_VALUE(socket_type, socket_value); + /* This will just copy the value if the types are equal. */ convert.convert_to_uninitialized(value_type, socket_type, buffer, socket_value); BLI_SCOPED_DEFER([&]() { socket_type.destruct(socket_value); }); From a43e4988788a0dcea92da2367d6f8bc71ea8b2c6 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 16 Dec 2022 12:00:30 -0600 Subject: [PATCH 0178/1522] Cleanup: Remove unnecessary node link flag Links that are currently being dragged are now stored outside of the node tree, so we don't need a flag to distinguish them from "proper" links. --- source/blender/editors/space_node/drawnode.cc | 2 +- source/blender/editors/space_node/node_relationships.cc | 5 ----- source/blender/makesdna/DNA_node_types.h | 1 - 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 708efc0c7a6..16771ef7347 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -2199,7 +2199,7 @@ void node_draw_link(const bContext &C, } /* Links from field to non-field sockets are not allowed. */ - if (snode.edittree->type == NTREE_GEOMETRY && !(link.flag & NODE_LINK_DRAGGED)) { + if (snode.edittree->type == NTREE_GEOMETRY) { if ((link.fromsock && link.fromsock->display_shape == SOCK_DISPLAY_SHAPE_DIAMOND) && (link.tosock && link.tosock->display_shape == SOCK_DISPLAY_SHAPE_CIRCLE)) { th_col1 = th_col2 = th_col3 = TH_REDALERT; diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 450d3bff286..ea6502dbf00 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -91,7 +91,6 @@ static bNodeLink *create_drag_link(bNode &node, bNodeSocket &sock) oplink->tosock = &sock; } oplink->flag |= NODE_LINK_VALID; - oplink->flag |= NODE_LINK_DRAGGED; return oplink; } @@ -903,8 +902,6 @@ static void node_link_exit(bContext &C, wmOperator &op, const bool apply_links) bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op.customdata; for (bNodeLink *link : nldrag->links) { - link->flag &= ~NODE_LINK_DRAGGED; - if (apply_links && link->tosock && link->fromsock) { /* before actually adding the link, * let nodes perform special link insertion handling @@ -1110,7 +1107,6 @@ static std::unique_ptr node_link_init(SpaceNode &snode, *oplink = *link; oplink->next = oplink->prev = nullptr; oplink->flag |= NODE_LINK_VALID; - oplink->flag |= NODE_LINK_DRAGGED; nldrag->links.append(oplink); nodeRemLink(snode.edittree, link); @@ -1153,7 +1149,6 @@ static std::unique_ptr node_link_init(SpaceNode &snode, *oplink = *link_to_pick; oplink->next = oplink->prev = nullptr; oplink->flag |= NODE_LINK_VALID; - oplink->flag |= NODE_LINK_DRAGGED; nldrag->links.append(oplink); nodeRemLink(snode.edittree, link_to_pick); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 6acb2208962..97505fdf5fe 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -499,7 +499,6 @@ typedef struct bNodeLink { #define NODE_LINK_TEST (1 << 2) /* free test flag, undefined */ #define NODE_LINK_TEMP_HIGHLIGHT (1 << 3) /* Link is highlighted for picking. */ #define NODE_LINK_MUTED (1 << 4) /* Link is muted. */ -#define NODE_LINK_DRAGGED (1 << 5) /* Node link is being dragged by the user. */ /* tree->edit_quality/tree->render_quality */ #define NTREE_QUALITY_HIGH 0 From c9288ab41f491eba463812c99c1237adca5cf210 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 16 Dec 2022 12:57:15 -0600 Subject: [PATCH 0179/1522] Cleanup: Remove redundant information from node link drag struct --- .../blender/editors/space_node/node_intern.hh | 1 - .../editors/space_node/node_relationships.cc | 17 ++--------------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index 1a6859a3078..a4eb0c12713 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -44,7 +44,6 @@ struct AssetItemTree; struct bNodeLinkDrag { /** Links dragged by the operator. */ Vector links; - bool from_multi_input_socket; eNodeSocketInOut in_out; /** Draw handler for the "+" icon when dragging a link in empty space. */ diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index ea6502dbf00..5f42f75e1d2 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -98,7 +98,6 @@ static void pick_link( wmOperator &op, bNodeLinkDrag &nldrag, SpaceNode &snode, bNode *node, bNodeLink &link_to_pick) { clear_picking_highlight(&snode.edittree->links); - RNA_boolean_set(op.ptr, "has_link_picked", true); bNodeLink *link = create_drag_link(*link_to_pick.fromnode, *link_to_pick.fromsock); @@ -1032,7 +1031,7 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event) switch (event->type) { case MOUSEMOVE: - if (nldrag->from_multi_input_socket && !RNA_boolean_get(op->ptr, "has_link_picked")) { + if (nldrag->start_socket->is_multi_input() && nldrag->links.is_empty()) { pick_input_link_by_link_intersect(*C, *op, *nldrag, cursor); } else { @@ -1137,14 +1136,11 @@ static std::unique_ptr node_link_init(SpaceNode &snode, bNodeLink *link_to_pick; LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &snode.edittree->links) { if (link->tosock == sock) { - if (sock->flag & SOCK_MULTI_INPUT) { - nldrag->from_multi_input_socket = true; - } link_to_pick = link; } } - if (link_to_pick != nullptr && !nldrag->from_multi_input_socket) { + if (link_to_pick != nullptr && !nldrag->start_socket->is_multi_input()) { bNodeLink *oplink = MEM_cnew("drag link op link"); *oplink = *link_to_pick; oplink->next = oplink->prev = nullptr; @@ -1185,7 +1181,6 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event) float2 cursor; UI_view2d_region_to_view(®ion.v2d, mval[0], mval[1], &cursor[0], &cursor[1]); RNA_float_set_array(op->ptr, "drag_start", cursor); - RNA_boolean_set(op->ptr, "has_link_picked", false); ED_preview_kill_jobs(CTX_wm_manager(C), &bmain); @@ -1241,14 +1236,6 @@ void NODE_OT_link(wmOperatorType *ot) PropertyRNA *prop; RNA_def_boolean(ot->srna, "detach", false, "Detach", "Detach and redirect existing links"); - prop = RNA_def_boolean( - ot->srna, - "has_link_picked", - false, - "Has Link Picked", - "The operation has placed a link. Only used for multi-input sockets, where the " - "link is picked later"); - RNA_def_property_flag(prop, PROP_HIDDEN); RNA_def_float_array(ot->srna, "drag_start", 2, From 4352ac0558ab2f8594c06cffc48e3b1ee41b47da Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 16 Dec 2022 13:22:34 -0600 Subject: [PATCH 0180/1522] Cleanup: Return early in node link operator, remove useless comments --- .../editors/space_node/node_relationships.cc | 49 ++++++++----------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 5f42f75e1d2..c4c3924ec6a 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -94,8 +94,10 @@ static bNodeLink *create_drag_link(bNode &node, bNodeSocket &sock) return oplink; } -static void pick_link( - wmOperator &op, bNodeLinkDrag &nldrag, SpaceNode &snode, bNode *node, bNodeLink &link_to_pick) +static void pick_link(bNodeLinkDrag &nldrag, + SpaceNode &snode, + bNode *node, + bNodeLink &link_to_pick) { clear_picking_highlight(&snode.edittree->links); @@ -163,7 +165,7 @@ static void pick_input_link_by_link_intersect(const bContext &C, ED_area_tag_redraw(CTX_wm_area(&C)); if (!node_find_indicated_socket(*snode, &node, &socket, cursor, SOCK_IN)) { - pick_link(op, nldrag, *snode, node, *link_to_pick); + pick_link(nldrag, *snode, node, *link_to_pick); } } } @@ -1014,8 +1016,6 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur } } -/* Loop that adds a node-link, called by function below. */ -/* in_out = starting socket */ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event) { bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op->customdata; @@ -1084,7 +1084,7 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event) } static std::unique_ptr node_link_init(SpaceNode &snode, - float2 cursor, + const float2 cursor, const bool detach) { /* output indicated? */ @@ -1115,7 +1115,6 @@ static std::unique_ptr node_link_init(SpaceNode &snode, else { /* dragged links are fixed on output side */ nldrag->in_out = SOCK_OUT; - /* create a new link */ nldrag->links.append(create_drag_link(*node, *sock)); } return nldrag; @@ -1158,7 +1157,6 @@ static std::unique_ptr node_link_init(SpaceNode &snode, else { /* dragged links are fixed on input side */ nldrag->in_out = SOCK_IN; - /* create a new link */ nldrag->links.append(create_drag_link(*node, *sock)); } return nldrag; @@ -1185,23 +1183,22 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event) ED_preview_kill_jobs(CTX_wm_manager(C), &bmain); std::unique_ptr nldrag = node_link_init(snode, cursor, detach); - - if (nldrag) { - UI_view2d_edge_pan_operator_init(C, &nldrag->pan_data, op); - - /* Add "+" icon when the link is dragged in empty space. */ - if (should_create_drag_link_search_menu(*snode.edittree, *nldrag)) { - draw_draglink_tooltip_activate(*CTX_wm_region(C), *nldrag); - } - snode.runtime->linkdrag = std::move(nldrag); - op->customdata = snode.runtime->linkdrag.get(); - - /* add modal handler */ - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; + if (!nldrag) { + return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } - return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; + + UI_view2d_edge_pan_operator_init(C, &nldrag->pan_data, op); + + /* Add "+" icon when the link is dragged in empty space. */ + if (should_create_drag_link_search_menu(*snode.edittree, *nldrag)) { + draw_draglink_tooltip_activate(*CTX_wm_region(C), *nldrag); + } + snode.runtime->linkdrag = std::move(nldrag); + op->customdata = snode.runtime->linkdrag.get(); + + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; } static void node_link_cancel(bContext *C, wmOperator *op) @@ -1233,8 +1230,6 @@ void NODE_OT_link(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; - PropertyRNA *prop; - RNA_def_boolean(ot->srna, "detach", false, "Detach", "Detach and redirect existing links"); RNA_def_float_array(ot->srna, "drag_start", @@ -1246,8 +1241,6 @@ void NODE_OT_link(wmOperatorType *ot) "The position of the mouse cursor at the start of the operation", -UI_PRECISION_FLOAT_MAX, UI_PRECISION_FLOAT_MAX); - RNA_def_property_flag(prop, PROP_HIDDEN); - RNA_def_property_flag(prop, PROP_HIDDEN); UI_view2d_edge_pan_operator_properties_ex(ot, NODE_EDGE_PAN_INSIDE_PAD, From 4254810e5028c6ebd745bb53c4cfa8c97483af8b Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 16 Dec 2022 14:03:49 -0600 Subject: [PATCH 0181/1522] Cleanup: Slightly refactor cancelling link drag operator Clarify that the dragged links aren't stored in the tree, use a separate function for cancelling vs. applying the links to the tree. --- .../editors/space_node/node_relationships.cc | 81 +++++++++---------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index c4c3924ec6a..360f713e1a7 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -894,42 +894,41 @@ static void node_remove_extra_links(SpaceNode &snode, bNodeLink &link) } } -static void node_link_exit(bContext &C, wmOperator &op, const bool apply_links) +static void add_dragged_links_to_tree(bContext &C, bNodeLinkDrag &nldrag) { Main *bmain = CTX_data_main(&C); ARegion ®ion = *CTX_wm_region(&C); SpaceNode &snode = *CTX_wm_space_node(&C); bNodeTree &ntree = *snode.edittree; - bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op.customdata; - for (bNodeLink *link : nldrag->links) { - if (apply_links && link->tosock && link->fromsock) { - /* before actually adding the link, - * let nodes perform special link insertion handling - */ - if (link->fromnode->typeinfo->insert_link) { - link->fromnode->typeinfo->insert_link(&ntree, link->fromnode, link); - } - if (link->tonode->typeinfo->insert_link) { - link->tonode->typeinfo->insert_link(&ntree, link->tonode, link); - } - - /* add link to the node tree */ - BLI_addtail(&ntree.links, link); - BKE_ntree_update_tag_link_added(&ntree, link); - - /* we might need to remove a link */ - node_remove_extra_links(snode, *link); + for (bNodeLink *link : nldrag.links) { + if (!link->tosock || !link->fromsock) { + MEM_freeN(link); + continue; } - else { - nodeRemLink(&ntree, link); + + /* before actually adding the link, + * let nodes perform special link insertion handling + */ + if (link->fromnode->typeinfo->insert_link) { + link->fromnode->typeinfo->insert_link(&ntree, link->fromnode, link); } + if (link->tonode->typeinfo->insert_link) { + link->tonode->typeinfo->insert_link(&ntree, link->tonode, link); + } + + /* add link to the node tree */ + BLI_addtail(&ntree.links, link); + BKE_ntree_update_tag_link_added(&ntree, link); + + /* we might need to remove a link */ + node_remove_extra_links(snode, *link); } ED_node_tree_propagate_change(&C, bmain, &ntree); /* Ensure drag-link tool-tip is disabled. */ - draw_draglink_tooltip_deactivate(*CTX_wm_region(&C), *nldrag); + draw_draglink_tooltip_deactivate(region, nldrag); ED_workspace_status_text(&C, nullptr); ED_region_tag_redraw(®ion); @@ -938,6 +937,19 @@ static void node_link_exit(bContext &C, wmOperator &op, const bool apply_links) snode.runtime->linkdrag.reset(); } +static void node_link_cancel(bContext *C, wmOperator *op) +{ + SpaceNode *snode = CTX_wm_space_node(C); + bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op->customdata; + draw_draglink_tooltip_deactivate(*CTX_wm_region(C), *nldrag); + UI_view2d_edge_pan_cancel(C, &nldrag->pan_data); + for (bNodeLink *link : nldrag->links) { + MEM_freeN(link); + } + snode->runtime->linkdrag.reset(); + clear_picking_highlight(&snode->edittree->links); +} + static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cursor) { SpaceNode &snode = *CTX_wm_space_node(&C); @@ -1061,22 +1073,21 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event) } } - /* Finish link. */ - node_link_exit(*C, *op, true); + add_dragged_links_to_tree(*C, *nldrag); return OPERATOR_FINISHED; } break; case RIGHTMOUSE: case MIDDLEMOUSE: { if (event->val == KM_RELEASE) { - node_link_exit(*C, *op, true); - return OPERATOR_FINISHED; + node_link_cancel(C, op); + return OPERATOR_CANCELLED; } break; } case EVT_ESCKEY: { - node_link_exit(*C, *op, true); - return OPERATOR_FINISHED; + node_link_cancel(C, op); + return OPERATOR_CANCELLED; } } @@ -1201,18 +1212,6 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_RUNNING_MODAL; } -static void node_link_cancel(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op->customdata; - - UI_view2d_edge_pan_cancel(C, &nldrag->pan_data); - - snode->runtime->linkdrag.reset(); - - clear_picking_highlight(&snode->edittree->links); -} - void NODE_OT_link(wmOperatorType *ot) { /* identifiers */ From 7c85f11c427d0d07444d99c34acae5ece56d987e Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Fri, 9 Dec 2022 02:27:40 +0100 Subject: [PATCH 0182/1522] Cycles: Change bake jittering to avoid issues with skinny triangles Partially addresses T72011. The problem here is that the previous barycentric clamping did not deal well with skinny triangles and would end up generating "sub-pixel jittering" locations that were actually >20 pixels away. Differential Revision: https://developer.blender.org/D16727 --- .../cycles/kernel/integrator/init_from_bake.h | 51 ++++++++++++------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/intern/cycles/kernel/integrator/init_from_bake.h b/intern/cycles/kernel/integrator/init_from_bake.h index cc3fbe3fe39..2a5bda50fb3 100644 --- a/intern/cycles/kernel/integrator/init_from_bake.h +++ b/intern/cycles/kernel/integrator/init_from_bake.h @@ -16,18 +16,40 @@ CCL_NAMESPACE_BEGIN -/* This helps with AA but it's not the real solution as it does not AA the geometry - * but it's better than nothing, thus committed. */ -ccl_device_inline float bake_clamp_mirror_repeat(float u, float max) +/* In order to perform anti-aliasing during baking, we jitter the input barycentric coordinates + * (which are for the center of the texel) within the texel. + * However, the baking code corrently doesn't support going to neighboring triangle, so if the + * jittered location falls outside of the input triangle, we need to bring it back in somehow. + * Clamping is a bad choice here since it can produce noticeable artifacts at triangle edges, + * but properly uniformly sampling the intersection of triangle and texel would be very + * performance-heavy, so cheat by just trying different jittering until we end up inside the + * triangle. + * For triangles that are smaller than a texel, this might take too many attempts, so eventually + * we just give up and don't jitter in that case. + * This is not a particularly elegant solution, but it's probably the best we can do. */ +ccl_device_inline void bake_jitter_barycentric(float &u, + float &v, + float2 rand_filter, + const float dudx, + const float dudy, + const float dvdx, + const float dvdy) { - /* use mirror repeat (like opengl texture) so that if the barycentric - * coordinate goes past the end of the triangle it is not always clamped - * to the same value, gives ugly patterns */ - u /= max; - float fu = floorf(u); - u = u - fu; - - return ((((int)fu) & 1) ? 1.0f - u : u) * max; + for (int i = 0; i < 10; i++) { + /* Offset UV according to differentials. */ + float jitterU = u + (rand_filter.x - 0.5f) * dudx + (rand_filter.y - 0.5f) * dudy; + float jitterV = v + (rand_filter.x - 0.5f) * dvdx + (rand_filter.y - 0.5f) * dvdy; + /* If this location is inside the triangle, return. */ + if (jitterU > 0.0f && jitterV > 0.0f && jitterU + jitterV < 1.0f) { + u = jitterU; + v = jitterV; + return; + } + /* Retry with new jitter value. */ + rand_filter = hash_float2_to_float2(rand_filter); + } + /* Retries exceeded, give up and just use center value. */ + return; } /* Offset towards center of triangle to avoid ray-tracing precision issues. */ @@ -144,12 +166,7 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg, } /* Sub-pixel offset. */ - if (sample > 0) { - u = bake_clamp_mirror_repeat(u + dudx * (rand_filter.x - 0.5f) + dudy * (rand_filter.y - 0.5f), - 1.0f); - v = bake_clamp_mirror_repeat(v + dvdx * (rand_filter.x - 0.5f) + dvdy * (rand_filter.y - 0.5f), - 1.0f - u); - } + bake_jitter_barycentric(u, v, rand_filter, dudx, dudy, dvdx, dvdy); /* Convert from Blender to Cycles/Embree/OptiX barycentric convention. */ const float tmp = u; From 347c82be6dba0e35aca1e9fe2e417b256998786f Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Sun, 27 Nov 2022 02:40:11 +0100 Subject: [PATCH 0183/1522] Fix T98951: Shadow catcher objects are double-counting data passes Differential Revision: https://developer.blender.org/D16627 --- intern/cycles/kernel/film/data_passes.h | 6 ++++++ intern/cycles/kernel/film/denoising_passes.h | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/intern/cycles/kernel/film/data_passes.h b/intern/cycles/kernel/film/data_passes.h index 3c538a74978..0ed5828ff30 100644 --- a/intern/cycles/kernel/film/data_passes.h +++ b/intern/cycles/kernel/film/data_passes.h @@ -33,6 +33,12 @@ ccl_device_inline void film_write_data_passes(KernelGlobals kg, return; } + /* Don't write data passes for paths that were split off for shadow catchers + * to avoid double-counting. */ + if (path_flag & PATH_RAY_SHADOW_CATCHER_PASS) { + return; + } + const int flag = kernel_data.film.pass_flag; if (!(flag & PASS_ANY)) { diff --git a/intern/cycles/kernel/film/denoising_passes.h b/intern/cycles/kernel/film/denoising_passes.h index dfc21d787f2..0a32df19a3e 100644 --- a/intern/cycles/kernel/film/denoising_passes.h +++ b/intern/cycles/kernel/film/denoising_passes.h @@ -16,7 +16,8 @@ ccl_device_forceinline void film_write_denoising_features_surface(KernelGlobals ccl_global float *ccl_restrict render_buffer) { - if (!(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_DENOISING_FEATURES)) { + const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); + if (!(path_flag & PATH_RAY_DENOISING_FEATURES)) { return; } @@ -25,6 +26,12 @@ ccl_device_forceinline void film_write_denoising_features_surface(KernelGlobals return; } + /* Don't write denoising passes for paths that were split off for shadow catchers + * to avoid double-counting. */ + if (path_flag & PATH_RAY_SHADOW_CATCHER_PASS) { + return; + } + ccl_global float *buffer = film_pass_pixel_render_buffer(kg, state, render_buffer); if (kernel_data.film.pass_denoising_depth != PASS_UNUSED) { From 6d3cc9c38a7a951beb964b20089223df78204033 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 17 Dec 2022 12:28:10 +1100 Subject: [PATCH 0184/1522] Cleanup: cmake indentation --- .../build_environment/cmake/harvest.cmake | 509 +++++++++--------- 1 file changed, 267 insertions(+), 242 deletions(-) diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake index 252e52361c5..4ea121492e2 100644 --- a/build_files/build_environment/cmake/harvest.cmake +++ b/build_files/build_environment/cmake/harvest.cmake @@ -11,276 +11,301 @@ message("HARVEST_TARGET = ${HARVEST_TARGET}") if(WIN32) -if(BUILD_MODE STREQUAL Release) - add_custom_target(Harvest_Release_Results - COMMAND # jpeg rename libfile + copy include + if(BUILD_MODE STREQUAL Release) + add_custom_target(Harvest_Release_Results + COMMAND # JPEG rename lib-file + copy include. ${CMAKE_COMMAND} -E copy ${LIBDIR}/jpeg/lib/jpeg-static.lib ${HARVEST_TARGET}/jpeg/lib/libjpeg.lib && ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/jpeg/include/ ${HARVEST_TARGET}/jpeg/include/ && - # png + # PNG. ${CMAKE_COMMAND} -E copy ${LIBDIR}/png/lib/libpng16_static.lib ${HARVEST_TARGET}/png/lib/libpng.lib && ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/png/include/ ${HARVEST_TARGET}/png/include/ && - # freeglut-> opengl + # FREEGLUT -> OPENGL. ${CMAKE_COMMAND} -E copy ${LIBDIR}/freeglut/lib/freeglut_static.lib ${HARVEST_TARGET}/opengl/lib/freeglut_static.lib && ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freeglut/include/ ${HARVEST_TARGET}/opengl/include/ && - DEPENDS - ) -endif() -else(WIN32) - -function(harvest from to) - set(pattern "") - foreach(f ${ARGN}) - set(pattern ${f}) - endforeach() - - if(pattern STREQUAL "") - get_filename_component(dirpath ${to} DIRECTORY) - get_filename_component(filename ${to} NAME) - install( - FILES ${LIBDIR}/${from} - DESTINATION ${HARVEST_TARGET}/${dirpath} - RENAME ${filename} - ) - else() - install( - DIRECTORY ${LIBDIR}/${from}/ - DESTINATION ${HARVEST_TARGET}/${to} - USE_SOURCE_PERMISSIONS - FILES_MATCHING PATTERN ${pattern} - PATTERN "pkgconfig" EXCLUDE - PATTERN "cmake" EXCLUDE - PATTERN "__pycache__" EXCLUDE - PATTERN "tests" EXCLUDE - PATTERN "meson*" EXCLUDE + DEPENDS ) endif() -endfunction() -# Set rpath on shared libraries to $ORIGIN since all will be installed in the same -# lib folder, and remove any absolute paths. -# -# Ideally this would be done as part of the Blender build since it makes assumptions -# about where the files will be installed. However it would add patchelf as a new -# dependency for building. -# -# Also removes versioned symlinks, which give errors with macOS notarization. -if(APPLE) - set(set_rpath_cmd python3 ${CMAKE_CURRENT_SOURCE_DIR}/darwin/set_rpath.py @loader_path) else() - set(set_rpath_cmd patchelf --set-rpath $ORIGIN) -endif() -function(harvest_rpath_lib from to pattern) - harvest(${from} ${to} ${pattern}) + function(harvest from to) + set(pattern "") + foreach(f ${ARGN}) + set(pattern ${f}) + endforeach() - install(CODE "\ - cmake_policy(SET CMP0009 NEW)\n - file(GLOB_RECURSE shared_libs ${HARVEST_TARGET}/${to}/${pattern}) \n - foreach(f \${shared_libs}) \n - if(IS_SYMLINK \${f})\n - if(APPLE)\n - file(REMOVE_RECURSE \${f}) + if(pattern STREQUAL "") + get_filename_component(dirpath ${to} DIRECTORY) + get_filename_component(filename ${to} NAME) + install( + FILES ${LIBDIR}/${from} + DESTINATION ${HARVEST_TARGET}/${dirpath} + RENAME ${filename} + ) + else() + install( + DIRECTORY ${LIBDIR}/${from}/ + DESTINATION ${HARVEST_TARGET}/${to} + USE_SOURCE_PERMISSIONS + FILES_MATCHING PATTERN ${pattern} + PATTERN "pkgconfig" EXCLUDE + PATTERN "cmake" EXCLUDE + PATTERN "__pycache__" EXCLUDE + PATTERN "tests" EXCLUDE + PATTERN "meson*" EXCLUDE + ) + endif() + endfunction() + + # Set rpath on shared libraries to $ORIGIN since all will be installed in the same + # lib folder, and remove any absolute paths. + # + # Ideally this would be done as part of the Blender build since it makes assumptions + # about where the files will be installed. However it would add patchelf as a new + # dependency for building. + # + # Also removes versioned symlinks, which give errors with macOS notarization. + if(APPLE) + set(set_rpath_cmd python3 ${CMAKE_CURRENT_SOURCE_DIR}/darwin/set_rpath.py @loader_path) + else() + set(set_rpath_cmd patchelf --set-rpath $ORIGIN) + endif() + + function(harvest_rpath_lib from to pattern) + harvest(${from} ${to} ${pattern}) + + install(CODE "\ + cmake_policy(SET CMP0009 NEW)\n + file(GLOB_RECURSE shared_libs ${HARVEST_TARGET}/${to}/${pattern}) \n + foreach(f \${shared_libs}) \n + if(IS_SYMLINK \${f})\n + if(APPLE)\n + file(REMOVE_RECURSE \${f}) + endif()\n + else()\n + execute_process(COMMAND ${set_rpath_cmd} \${f}) \n endif()\n - else()\n - execute_process(COMMAND ${set_rpath_cmd} \${f}) \n - endif()\n - endforeach()") -endfunction() + endforeach()") + endfunction() -# Set rpath on utility binaries assuming they are run from their install location. -function(harvest_rpath_bin from to pattern) - harvest(${from} ${to} ${pattern}) + # Set rpath on utility binaries assuming they are run from their install location. + function(harvest_rpath_bin from to pattern) + harvest(${from} ${to} ${pattern}) - install(CODE "\ - file(GLOB_RECURSE shared_libs ${HARVEST_TARGET}/${to}/${pattern}) \n - foreach(f \${shared_libs}) \n - execute_process(COMMAND ${set_rpath_cmd}/../lib; \${f}) \n - endforeach()") -endfunction() + install(CODE "\ + file(GLOB_RECURSE shared_libs ${HARVEST_TARGET}/${to}/${pattern}) \n + foreach(f \${shared_libs}) \n + execute_process(COMMAND ${set_rpath_cmd}/../lib; \${f}) \n + endforeach()") + endfunction() -# Set rpath on Python module to point to the shared libraries folder in the Blender -# installation. -function(harvest_rpath_python from to pattern) - harvest(${from} ${to} ${pattern}) + # Set rpath on Python module to point to the shared libraries folder in the Blender + # installation. + function(harvest_rpath_python from to pattern) + harvest(${from} ${to} ${pattern}) - install(CODE "\ - file(GLOB_RECURSE shared_libs ${HARVEST_TARGET}/${to}/${pattern}\.so*) \n - foreach(f \${shared_libs}) \n - if(IS_SYMLINK \${f})\n - if(APPLE)\n - file(REMOVE_RECURSE \${f}) + install(CODE "\ + file(GLOB_RECURSE shared_libs ${HARVEST_TARGET}/${to}/${pattern}\.so*) \n + foreach(f \${shared_libs}) \n + if(IS_SYMLINK \${f})\n + if(APPLE)\n + file(REMOVE_RECURSE \${f}) + endif()\n + else()\n + get_filename_component(f_dir \${f} DIRECTORY) \n + file(RELATIVE_PATH relative_dir \${f_dir} ${HARVEST_TARGET}) \n + execute_process(COMMAND ${set_rpath_cmd}/\${relative_dir}../lib \${f}) \n endif()\n - else()\n - get_filename_component(f_dir \${f} DIRECTORY) \n - file(RELATIVE_PATH relative_dir \${f_dir} ${HARVEST_TARGET}) \n - execute_process(COMMAND ${set_rpath_cmd}/\${relative_dir}../lib \${f}) \n - endif()\n - endforeach()") -endfunction() + endforeach()") + endfunction() -harvest(alembic/include alembic/include "*.h") -harvest(alembic/lib/libAlembic.a alembic/lib/libAlembic.a) -harvest_rpath_bin(alembic/bin alembic/bin "*") -harvest(brotli/include brotli/include "*.h") -harvest(brotli/lib brotli/lib "*.a") -harvest(boost/include boost/include "*") -harvest_rpath_lib(boost/lib boost/lib "*${SHAREDLIBEXT}*") -harvest(imath/include imath/include "*.h") -harvest_rpath_lib(imath/lib imath/lib "*${SHAREDLIBEXT}*") -harvest(ffmpeg/include ffmpeg/include "*.h") -harvest(ffmpeg/lib ffmpeg/lib "*.a") -harvest(fftw3/include fftw3/include "*.h") -harvest(fftw3/lib fftw3/lib "*.a") -harvest(flac/lib sndfile/lib "libFLAC.a") -harvest(freetype/include freetype/include "*.h") -harvest(freetype/lib/libfreetype2ST.a freetype/lib/libfreetype.a) -harvest(fribidi/include fribidi/include "*.h") -harvest(fribidi/lib fribidi/lib "*.a") -harvest(epoxy/include epoxy/include "*.h") -harvest(epoxy/lib epoxy/lib "*.a") -harvest(gmp/include gmp/include "*.h") -harvest(gmp/lib gmp/lib "*.a") -harvest(harfbuzz/include harfbuzz/include "*.h") -harvest(harfbuzz/lib harfbuzz/lib "*.a") -harvest(jemalloc/include jemalloc/include "*.h") -harvest(jemalloc/lib jemalloc/lib "*.a") -harvest(jpeg/include jpeg/include "*.h") -harvest(jpeg/lib jpeg/lib "libjpeg.a") -harvest(lame/lib ffmpeg/lib "*.a") -if(NOT APPLE) - harvest(level-zero/include/level_zero level-zero/include/level_zero "*.h") - harvest(level-zero/lib level-zero/lib "*${SHAREDLIBEXT}*") -endif() -harvest(llvm/bin llvm/bin "clang-format") -if(BUILD_CLANG_TOOLS) - harvest(llvm/bin llvm/bin "clang-tidy") - harvest(llvm/share/clang llvm/share "run-clang-tidy.py") -endif() -harvest(llvm/include llvm/include "*") -harvest(llvm/bin llvm/bin "llvm-config") -harvest(llvm/lib llvm/lib "libLLVM*.a") -harvest(llvm/lib llvm/lib "libclang*.a") -harvest(llvm/lib/clang llvm/lib/clang "*.h") -if(APPLE) - harvest(openmp/lib openmp/lib "libomp.dylib") - harvest(openmp/include openmp/include "*.h") -endif() -if(BLENDER_PLATFORM_ARM) - harvest(sse2neon sse2neon "*.h") -endif() -harvest(ogg/lib ffmpeg/lib "*.a") -harvest(openal/include openal/include "*.h") -if(UNIX AND NOT APPLE) - harvest(openal/lib openal/lib "*.a") + harvest(alembic/include alembic/include "*.h") + harvest(alembic/lib/libAlembic.a alembic/lib/libAlembic.a) + harvest_rpath_bin(alembic/bin alembic/bin "*") + harvest(brotli/include brotli/include "*.h") + harvest(brotli/lib brotli/lib "*.a") + harvest(boost/include boost/include "*") + harvest_rpath_lib(boost/lib boost/lib "*${SHAREDLIBEXT}*") + harvest(imath/include imath/include "*.h") + harvest_rpath_lib(imath/lib imath/lib "*${SHAREDLIBEXT}*") + harvest(ffmpeg/include ffmpeg/include "*.h") + harvest(ffmpeg/lib ffmpeg/lib "*.a") + harvest(fftw3/include fftw3/include "*.h") + harvest(fftw3/lib fftw3/lib "*.a") + harvest(flac/lib sndfile/lib "libFLAC.a") + harvest(freetype/include freetype/include "*.h") + harvest(freetype/lib/libfreetype2ST.a freetype/lib/libfreetype.a) + harvest(fribidi/include fribidi/include "*.h") + harvest(fribidi/lib fribidi/lib "*.a") + harvest(epoxy/include epoxy/include "*.h") + harvest(epoxy/lib epoxy/lib "*.a") + harvest(gmp/include gmp/include "*.h") + harvest(gmp/lib gmp/lib "*.a") + harvest(harfbuzz/include harfbuzz/include "*.h") + harvest(harfbuzz/lib harfbuzz/lib "*.a") + harvest(jemalloc/include jemalloc/include "*.h") + harvest(jemalloc/lib jemalloc/lib "*.a") + harvest(jpeg/include jpeg/include "*.h") + harvest(jpeg/lib jpeg/lib "libjpeg.a") + harvest(lame/lib ffmpeg/lib "*.a") + if(NOT APPLE) + harvest(level-zero/include/level_zero level-zero/include/level_zero "*.h") + harvest(level-zero/lib level-zero/lib "*${SHAREDLIBEXT}*") + endif() + harvest(llvm/bin llvm/bin "clang-format") + if(BUILD_CLANG_TOOLS) + harvest(llvm/bin llvm/bin "clang-tidy") + harvest(llvm/share/clang llvm/share "run-clang-tidy.py") + endif() + harvest(llvm/include llvm/include "*") + harvest(llvm/bin llvm/bin "llvm-config") + harvest(llvm/lib llvm/lib "libLLVM*.a") + harvest(llvm/lib llvm/lib "libclang*.a") + harvest(llvm/lib/clang llvm/lib/clang "*.h") + if(APPLE) + harvest(openmp/lib openmp/lib "libomp.dylib") + harvest(openmp/include openmp/include "*.h") + endif() + if(BLENDER_PLATFORM_ARM) + harvest(sse2neon sse2neon "*.h") + endif() + harvest(ogg/lib ffmpeg/lib "*.a") + harvest(openal/include openal/include "*.h") + if(UNIX AND NOT APPLE) + harvest(openal/lib openal/lib "*.a") - harvest(zlib/include zlib/include "*.h") - harvest(zlib/lib zlib/lib "*.a") + harvest(zlib/include zlib/include "*.h") + harvest(zlib/lib zlib/lib "*.a") - harvest(xml2/include xml2/include "*.h") - harvest(xml2/lib xml2/lib "*.a") + harvest(xml2/include xml2/include "*.h") + harvest(xml2/lib xml2/lib "*.a") - harvest(wayland-protocols/share/wayland-protocols wayland-protocols/share/wayland-protocols/ "*.xml") + harvest( + wayland-protocols/share/wayland-protocols + wayland-protocols/share/wayland-protocols/ + "*.xml" + ) harvest(wayland/bin wayland/bin "wayland-scanner") harvest(wayland/include wayland/include "*.h") harvest(wayland_libdecor/include wayland_libdecor/include "*.h") else() harvest(blosc/lib openvdb/lib "*.a") - harvest(xml2/lib opencollada/lib "*.a") -endif() -harvest(opencollada/include/opencollada opencollada/include "*.h") -harvest(opencollada/lib/opencollada opencollada/lib "*.a") -harvest(opencolorio/include opencolorio/include "*.h") -harvest_rpath_lib(opencolorio/lib opencolorio/lib "*${SHAREDLIBEXT}*") -harvest_rpath_python(opencolorio/lib/python${PYTHON_SHORT_VERSION} python/lib/python${PYTHON_SHORT_VERSION} "*") -harvest(openexr/include openexr/include "*.h") -harvest_rpath_lib(openexr/lib openexr/lib "*${SHAREDLIBEXT}*") -harvest_rpath_bin(openimageio/bin openimageio/bin "idiff") -harvest_rpath_bin(openimageio/bin openimageio/bin "maketx") -harvest_rpath_bin(openimageio/bin openimageio/bin "oiiotool") -harvest(openimageio/include openimageio/include "*") -harvest_rpath_lib(openimageio/lib openimageio/lib "*${SHAREDLIBEXT}*") -harvest_rpath_python(openimageio/lib/python${PYTHON_SHORT_VERSION} python/lib/python${PYTHON_SHORT_VERSION} "*") -harvest(openimagedenoise/include openimagedenoise/include "*") -harvest(openimagedenoise/lib openimagedenoise/lib "*.a") -harvest(embree/include embree/include "*.h") -harvest(embree/lib embree/lib "*.a") -harvest(openpgl/include openpgl/include "*.h") -harvest(openpgl/lib openpgl/lib "*.a") -harvest(openpgl/lib/cmake/openpgl-${OPENPGL_SHORT_VERSION} openpgl/lib/cmake/openpgl "*.cmake") -harvest(openjpeg/include/openjpeg-${OPENJPEG_SHORT_VERSION} openjpeg/include "*.h") -harvest(openjpeg/lib openjpeg/lib "*.a") -harvest(opensubdiv/include opensubdiv/include "*.h") -harvest_rpath_lib(opensubdiv/lib opensubdiv/lib "*${SHAREDLIBEXT}*") -harvest(openvdb/include/openvdb openvdb/include/openvdb "*.h") -harvest(openvdb/include/nanovdb openvdb/include/nanovdb "*.h") -harvest_rpath_lib(openvdb/lib openvdb/lib "*${SHAREDLIBEXT}*") -harvest_rpath_python(openvdb/lib/python${PYTHON_SHORT_VERSION} python/lib/python${PYTHON_SHORT_VERSION} "*pyopenvdb*") -harvest(xr_openxr_sdk/include/openxr xr_openxr_sdk/include/openxr "*.h") -harvest(xr_openxr_sdk/lib xr_openxr_sdk/lib "*.a") -harvest_rpath_bin(osl/bin osl/bin "oslc") -harvest(osl/include osl/include "*.h") -harvest(osl/lib osl/lib "*.a") -harvest(osl/share/OSL/shaders osl/share/OSL/shaders "*.h") -harvest(png/include png/include "*.h") -harvest(png/lib png/lib "*.a") -harvest(pugixml/include pugixml/include "*.hpp") -harvest(pugixml/lib pugixml/lib "*.a") -harvest(python/bin python/bin "python${PYTHON_SHORT_VERSION}") -harvest(python/include python/include "*h") -harvest(python/lib python/lib "*") -harvest(sdl/include/SDL2 sdl/include "*.h") -harvest(sdl/lib sdl/lib "libSDL2.a") -harvest(sndfile/include sndfile/include "*.h") -harvest(sndfile/lib sndfile/lib "*.a") -harvest(spnav/include spnav/include "*.h") -harvest(spnav/lib spnav/lib "*.a") -harvest(tbb/include tbb/include "*.h") -harvest_rpath_lib(tbb/lib tbb/lib "libtbb${SHAREDLIBEXT}") -harvest(theora/lib ffmpeg/lib "*.a") -harvest(tiff/include tiff/include "*.h") -harvest(tiff/lib tiff/lib "*.a") -harvest(vorbis/lib ffmpeg/lib "*.a") -harvest(opus/lib ffmpeg/lib "*.a") -harvest(vpx/lib ffmpeg/lib "*.a") -harvest(x264/lib ffmpeg/lib "*.a") -harvest(xvidcore/lib ffmpeg/lib "*.a") -harvest(aom/lib ffmpeg/lib "*.a") -harvest(webp/lib webp/lib "*.a") -harvest(webp/include webp/include "*.h") -harvest(usd/include usd/include "*.h") -harvest_rpath_lib(usd/lib usd/lib "libusd_ms${SHAREDLIBEXT}") -harvest(usd/lib/usd usd/lib/usd "*") -harvest_rpath_python(usd/lib/python/pxr python/lib/python${PYTHON_SHORT_VERSION}/site-packages/pxr "*") -harvest(usd/plugin usd/plugin "*") -harvest(materialx/include materialx/include "*.h") -harvest_rpath_lib(materialx/lib materialx/lib "*${SHAREDLIBEXT}*") -harvest(materialx/libraries materialx/libraries "*") -harvest(materialx/lib/cmake/MaterialX materialx/lib/cmake/MaterialX "*.cmake") -harvest_rpath_python(materialx/python/MaterialX python/lib/python${PYTHON_SHORT_VERSION}/site-packages/MaterialX "*") -# We do not need anything from the resources folder, but the MaterialX config -# file will complain if the folder does not exist, so just copy the readme.md -# files to ensure the folder will exist. -harvest(materialx/resources materialx/resources "README.md") -harvest(potrace/include potrace/include "*.h") -harvest(potrace/lib potrace/lib "*.a") -harvest(haru/include haru/include "*.h") -harvest(haru/lib haru/lib "*.a") -harvest(zstd/include zstd/include "*.h") -harvest(zstd/lib zstd/lib "*.a") -harvest(shaderc shaderc "*") -harvest(vulkan_headers vulkan "*") -harvest_rpath_lib(vulkan_loader/lib vulkan/lib "*${SHAREDLIBEXT}*") -if(APPLE) - harvest(vulkan_loader/loader vulkan/loader "*") -endif() + harvest(xml2/lib opencollada/lib "*.a") + endif() + harvest(opencollada/include/opencollada opencollada/include "*.h") + harvest(opencollada/lib/opencollada opencollada/lib "*.a") + harvest(opencolorio/include opencolorio/include "*.h") + harvest_rpath_lib(opencolorio/lib opencolorio/lib "*${SHAREDLIBEXT}*") + harvest_rpath_python( + opencolorio/lib/python${PYTHON_SHORT_VERSION} + python/lib/python${PYTHON_SHORT_VERSION} + "*" + ) + harvest(openexr/include openexr/include "*.h") + harvest_rpath_lib(openexr/lib openexr/lib "*${SHAREDLIBEXT}*") + harvest_rpath_bin(openimageio/bin openimageio/bin "idiff") + harvest_rpath_bin(openimageio/bin openimageio/bin "maketx") + harvest_rpath_bin(openimageio/bin openimageio/bin "oiiotool") + harvest(openimageio/include openimageio/include "*") + harvest_rpath_lib(openimageio/lib openimageio/lib "*${SHAREDLIBEXT}*") + harvest_rpath_python( + openimageio/lib/python${PYTHON_SHORT_VERSION} + python/lib/python${PYTHON_SHORT_VERSION} + "*" + ) + harvest(openimagedenoise/include openimagedenoise/include "*") + harvest(openimagedenoise/lib openimagedenoise/lib "*.a") + harvest(embree/include embree/include "*.h") + harvest(embree/lib embree/lib "*.a") + harvest(openpgl/include openpgl/include "*.h") + harvest(openpgl/lib openpgl/lib "*.a") + harvest(openpgl/lib/cmake/openpgl-${OPENPGL_SHORT_VERSION} openpgl/lib/cmake/openpgl "*.cmake") + harvest(openjpeg/include/openjpeg-${OPENJPEG_SHORT_VERSION} openjpeg/include "*.h") + harvest(openjpeg/lib openjpeg/lib "*.a") + harvest(opensubdiv/include opensubdiv/include "*.h") + harvest_rpath_lib(opensubdiv/lib opensubdiv/lib "*${SHAREDLIBEXT}*") + harvest(openvdb/include/openvdb openvdb/include/openvdb "*.h") + harvest(openvdb/include/nanovdb openvdb/include/nanovdb "*.h") + harvest_rpath_lib(openvdb/lib openvdb/lib "*${SHAREDLIBEXT}*") + harvest_rpath_python( + openvdb/lib/python${PYTHON_SHORT_VERSION} + python/lib/python${PYTHON_SHORT_VERSION} + "*pyopenvdb*" + ) + harvest(xr_openxr_sdk/include/openxr xr_openxr_sdk/include/openxr "*.h") + harvest(xr_openxr_sdk/lib xr_openxr_sdk/lib "*.a") + harvest_rpath_bin(osl/bin osl/bin "oslc") + harvest(osl/include osl/include "*.h") + harvest(osl/lib osl/lib "*.a") + harvest(osl/share/OSL/shaders osl/share/OSL/shaders "*.h") + harvest(png/include png/include "*.h") + harvest(png/lib png/lib "*.a") + harvest(pugixml/include pugixml/include "*.hpp") + harvest(pugixml/lib pugixml/lib "*.a") + harvest(python/bin python/bin "python${PYTHON_SHORT_VERSION}") + harvest(python/include python/include "*h") + harvest(python/lib python/lib "*") + harvest(sdl/include/SDL2 sdl/include "*.h") + harvest(sdl/lib sdl/lib "libSDL2.a") + harvest(sndfile/include sndfile/include "*.h") + harvest(sndfile/lib sndfile/lib "*.a") + harvest(spnav/include spnav/include "*.h") + harvest(spnav/lib spnav/lib "*.a") + harvest(tbb/include tbb/include "*.h") + harvest_rpath_lib(tbb/lib tbb/lib "libtbb${SHAREDLIBEXT}") + harvest(theora/lib ffmpeg/lib "*.a") + harvest(tiff/include tiff/include "*.h") + harvest(tiff/lib tiff/lib "*.a") + harvest(vorbis/lib ffmpeg/lib "*.a") + harvest(opus/lib ffmpeg/lib "*.a") + harvest(vpx/lib ffmpeg/lib "*.a") + harvest(x264/lib ffmpeg/lib "*.a") + harvest(xvidcore/lib ffmpeg/lib "*.a") + harvest(aom/lib ffmpeg/lib "*.a") + harvest(webp/lib webp/lib "*.a") + harvest(webp/include webp/include "*.h") + harvest(usd/include usd/include "*.h") + harvest_rpath_lib(usd/lib usd/lib "libusd_ms${SHAREDLIBEXT}") + harvest(usd/lib/usd usd/lib/usd "*") + harvest_rpath_python( + usd/lib/python/pxr + python/lib/python${PYTHON_SHORT_VERSION}/site-packages/pxr + "*" + ) + harvest(usd/plugin usd/plugin "*") + harvest(materialx/include materialx/include "*.h") + harvest_rpath_lib(materialx/lib materialx/lib "*${SHAREDLIBEXT}*") + harvest(materialx/libraries materialx/libraries "*") + harvest(materialx/lib/cmake/MaterialX materialx/lib/cmake/MaterialX "*.cmake") + harvest_rpath_python( + materialx/python/MaterialX + python/lib/python${PYTHON_SHORT_VERSION}/site-packages/MaterialX + "*" + ) + # We do not need anything from the resources folder, but the MaterialX config + # file will complain if the folder does not exist, so just copy the readme.md + # files to ensure the folder will exist. + harvest(materialx/resources materialx/resources "README.md") + harvest(potrace/include potrace/include "*.h") + harvest(potrace/lib potrace/lib "*.a") + harvest(haru/include haru/include "*.h") + harvest(haru/lib haru/lib "*.a") + harvest(zstd/include zstd/include "*.h") + harvest(zstd/lib zstd/lib "*.a") + harvest(shaderc shaderc "*") + harvest(vulkan_headers vulkan "*") + harvest_rpath_lib(vulkan_loader/lib vulkan/lib "*${SHAREDLIBEXT}*") + if(APPLE) + harvest(vulkan_loader/loader vulkan/loader "*") + endif() -if(UNIX AND NOT APPLE) - harvest(libglu/lib mesa/lib "*${SHAREDLIBEXT}*") - harvest(mesa/lib64 mesa/lib "*${SHAREDLIBEXT}*") + if(UNIX AND NOT APPLE) + harvest(libglu/lib mesa/lib "*${SHAREDLIBEXT}*") + harvest(mesa/lib64 mesa/lib "*${SHAREDLIBEXT}*") - harvest(dpcpp dpcpp "*") - harvest(igc dpcpp/lib/igc "*") - harvest(ocloc dpcpp/lib/ocloc "*") -endif() + harvest(dpcpp dpcpp "*") + harvest(igc dpcpp/lib/igc "*") + harvest(ocloc dpcpp/lib/ocloc "*") + endif() endif() From 067fe443d8358d62dc570fde3327ca1d557a824c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 17 Dec 2022 12:47:43 +1100 Subject: [PATCH 0185/1522] Cleanup: consistent naming for normals Use consistent naming for {vert/poly/loop/face}_normals. --- source/blender/blenkernel/BKE_key.h | 12 +- source/blender/blenkernel/BKE_mesh.h | 22 ++-- source/blender/blenkernel/BKE_mesh_tangent.h | 2 +- source/blender/blenkernel/BKE_shrinkwrap.h | 2 +- source/blender/blenkernel/intern/key.cc | 24 ++-- source/blender/blenkernel/intern/mesh.cc | 10 +- .../blenkernel/intern/mesh_iterators.cc | 22 ++-- .../blenkernel/intern/mesh_legacy_convert.cc | 17 +-- .../blender/blenkernel/intern/mesh_normals.cc | 117 +++++++++--------- .../blender/blenkernel/intern/mesh_tangent.cc | 26 ++-- source/blender/blenkernel/intern/pbvh.c | 16 +-- .../blender/blenkernel/intern/shrinkwrap.cc | 6 +- .../draw/engines/overlay/overlay_edit_mesh.cc | 4 +- source/blender/draw/intern/draw_cache_impl.h | 4 +- .../draw/intern/draw_cache_impl_mesh.cc | 4 +- .../extract_mesh_vbo_pos_nor.cc | 9 +- .../blender/editors/armature/meshlaplacian.c | 18 +-- source/blender/editors/mesh/editmesh_tools.c | 12 +- .../io/alembic/intern/abc_reader_mesh.cc | 8 +- source/blender/makesrna/intern/rna_mesh_api.c | 14 +-- .../modifiers/intern/MOD_normal_edit.cc | 40 +++--- .../modifiers/intern/MOD_weighted_normal.cc | 20 +-- 22 files changed, 206 insertions(+), 203 deletions(-) diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index 6cae56b775f..813dc9aba34 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -139,15 +139,15 @@ void BKE_keyblock_convert_to_mesh(const struct KeyBlock *kb, struct MVert *mvert * * \param kb: the KeyBlock to use to compute normals. * \param mesh: the Mesh to apply key-block to. - * \param r_vertnors: if non-NULL, an array of vectors, same length as number of vertices. - * \param r_polynors: if non-NULL, an array of vectors, same length as number of polygons. - * \param r_loopnors: if non-NULL, an array of vectors, same length as number of loops. + * \param r_vert_normals: if non-NULL, an array of vectors, same length as number of vertices. + * \param r_poly_normals: if non-NULL, an array of vectors, same length as number of polygons. + * \param r_loop_normals: if non-NULL, an array of vectors, same length as number of loops. */ void BKE_keyblock_mesh_calc_normals(const struct KeyBlock *kb, const struct Mesh *mesh, - float (*r_vertnors)[3], - float (*r_polynors)[3], - float (*r_loopnors)[3]); + float (*r_vert_normals)[3], + float (*r_poly_normals)[3], + float (*r_loop_normals)[3]); void BKE_keyblock_update_from_vertcos(const struct Object *ob, struct KeyBlock *kb, diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 472c82c3a81..066d302fdd1 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -481,7 +481,7 @@ void BKE_edges_sharp_from_angle_set(struct MEdge *medges, const struct MLoop *mloops, int numLoops, const struct MPoly *mpolys, - const float (*polynors)[3], + const float (*poly_normals)[3], int numPolys, float split_angle); @@ -603,10 +603,10 @@ void BKE_mesh_normals_loop_split(const struct MVert *mverts, const struct MEdge *medges, int numEdges, const struct MLoop *mloops, - float (*r_loopnors)[3], + float (*r_loop_normals)[3], int numLoops, const struct MPoly *mpolys, - const float (*polynors)[3], + const float (*poly_normals)[3], int numPolys, bool use_split_normals, float split_angle, @@ -620,22 +620,22 @@ void BKE_mesh_normals_loop_custom_set(const struct MVert *mverts, struct MEdge *medges, int numEdges, const struct MLoop *mloops, - float (*r_custom_loopnors)[3], + float (*r_custom_loop_normals)[3], int numLoops, const struct MPoly *mpolys, - const float (*polynors)[3], + const float (*poly_normals)[3], int numPolys, short (*r_clnors_data)[2]); void BKE_mesh_normals_loop_custom_from_verts_set(const struct MVert *mverts, const float (*vert_normals)[3], - float (*r_custom_vertnors)[3], + float (*r_custom_vert_normals)[3], int numVerts, struct MEdge *medges, int numEdges, const struct MLoop *mloops, int numLoops, const struct MPoly *mpolys, - const float (*polynors)[3], + const float (*poly_normals)[3], int numPolys, short (*r_clnors_data)[2]); @@ -672,18 +672,18 @@ void BKE_mesh_calc_normals_split_ex(struct Mesh *mesh, * Higher level functions hiding most of the code needed around call to * #BKE_mesh_normals_loop_custom_set(). * - * \param r_custom_loopnors: is not const, since code will replace zero_v3 normals there + * \param r_custom_loop_normals: is not const, since code will replace zero_v3 normals there * with automatically computed vectors. */ -void BKE_mesh_set_custom_normals(struct Mesh *mesh, float (*r_custom_loopnors)[3]); +void BKE_mesh_set_custom_normals(struct Mesh *mesh, float (*r_custom_loop_normals)[3]); /** * Higher level functions hiding most of the code needed around call to * #BKE_mesh_normals_loop_custom_from_verts_set(). * - * \param r_custom_vertnors: is not const, since code will replace zero_v3 normals there + * \param r_custom_vert_normals: is not const, since code will replace zero_v3 normals there * with automatically computed vectors. */ -void BKE_mesh_set_custom_normals_from_verts(struct Mesh *mesh, float (*r_custom_vertnors)[3]); +void BKE_mesh_set_custom_normals_from_verts(struct Mesh *mesh, float (*r_custom_vert_normals)[3]); /* *** mesh_evaluate.cc *** */ diff --git a/source/blender/blenkernel/BKE_mesh_tangent.h b/source/blender/blenkernel/BKE_mesh_tangent.h index 58142653a90..b018ab978b2 100644 --- a/source/blender/blenkernel/BKE_mesh_tangent.h +++ b/source/blender/blenkernel/BKE_mesh_tangent.h @@ -21,7 +21,7 @@ void BKE_mesh_calc_loop_tangent_single_ex(const struct MVert *mverts, int numVerts, const struct MLoop *mloops, float (*r_looptangent)[4], - const float (*loopnors)[3], + const float (*loop_normals)[3], const struct MLoopUV *loopuv, int numLoops, const struct MPoly *mpolys, diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index 70065ab5961..b13a1cbd034 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -75,7 +75,7 @@ typedef struct ShrinkwrapTreeData { const struct MPoly *polys; const float (*vert_normals)[3]; - const float (*pnors)[3]; + const float (*poly_normals)[3]; const float (*clnors)[3]; ShrinkwrapBoundaryData *boundary; } ShrinkwrapTreeData; diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 7db815e7f9d..c283ea828e8 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -2240,11 +2240,11 @@ void BKE_keyblock_convert_to_mesh(const KeyBlock *kb, MVert *mvert, const int to void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, const Mesh *mesh, - float (*r_vertnors)[3], - float (*r_polynors)[3], - float (*r_loopnors)[3]) + float (*r_vert_normals)[3], + float (*r_poly_normals)[3], + float (*r_loop_normals)[3]) { - if (r_vertnors == nullptr && r_polynors == nullptr && r_loopnors == nullptr) { + if (r_vert_normals == nullptr && r_poly_normals == nullptr && r_loop_normals == nullptr) { return; } @@ -2254,21 +2254,21 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, const MPoly *polys = BKE_mesh_polys(mesh); const MLoop *loops = BKE_mesh_loops(mesh); - const bool loop_normals_needed = r_loopnors != nullptr; - const bool vert_normals_needed = r_vertnors != nullptr || loop_normals_needed; - const bool poly_normals_needed = r_polynors != nullptr || vert_normals_needed || + const bool loop_normals_needed = r_loop_normals != nullptr; + const bool vert_normals_needed = r_vert_normals != nullptr || loop_normals_needed; + const bool poly_normals_needed = r_poly_normals != nullptr || vert_normals_needed || loop_normals_needed; - float(*vert_normals)[3] = r_vertnors; - float(*poly_normals)[3] = r_polynors; + float(*vert_normals)[3] = r_vert_normals; + float(*poly_normals)[3] = r_poly_normals; bool free_vert_normals = false; bool free_poly_normals = false; - if (vert_normals_needed && r_vertnors == nullptr) { + if (vert_normals_needed && r_vert_normals == nullptr) { vert_normals = static_cast( MEM_malloc_arrayN(mesh->totvert, sizeof(float[3]), __func__)); free_vert_normals = true; } - if (poly_normals_needed && r_polynors == nullptr) { + if (poly_normals_needed && r_poly_normals == nullptr) { poly_normals = static_cast( MEM_malloc_arrayN(mesh->totpoly, sizeof(float[3]), __func__)); free_poly_normals = true; @@ -2297,7 +2297,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, edges, mesh->totedge, loops, - r_loopnors, + r_loop_normals, mesh->totloop, polys, poly_normals, diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 6ec171c4bcc..c9418266729 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1792,17 +1792,17 @@ void BKE_mesh_vert_coords_apply_with_mat4(Mesh *mesh, static float (*ensure_corner_normal_layer(Mesh &mesh))[3] { - float(*r_loopnors)[3]; + float(*r_loop_normals)[3]; if (CustomData_has_layer(&mesh.ldata, CD_NORMAL)) { - r_loopnors = (float(*)[3])CustomData_get_layer(&mesh.ldata, CD_NORMAL); - memset(r_loopnors, 0, sizeof(float[3]) * mesh.totloop); + r_loop_normals = (float(*)[3])CustomData_get_layer(&mesh.ldata, CD_NORMAL); + memset(r_loop_normals, 0, sizeof(float[3]) * mesh.totloop); } else { - r_loopnors = (float(*)[3])CustomData_add_layer( + r_loop_normals = (float(*)[3])CustomData_add_layer( &mesh.ldata, CD_NORMAL, CD_SET_DEFAULT, nullptr, mesh.totloop); CustomData_set_layer_flag(&mesh.ldata, CD_NORMAL, CD_FLAG_TEMPORARY); } - return r_loopnors; + return r_loop_normals; } void BKE_mesh_calc_normals_split_ex(Mesh *mesh, diff --git a/source/blender/blenkernel/intern/mesh_iterators.cc b/source/blender/blenkernel/intern/mesh_iterators.cc index a99e9b2348d..bc765c0ddd0 100644 --- a/source/blender/blenkernel/intern/mesh_iterators.cc +++ b/source/blender/blenkernel/intern/mesh_iterators.cc @@ -163,10 +163,10 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh, const float(*vertexCos)[3] = mesh->runtime->edit_data->vertexCos; /* XXX: investigate using EditMesh data. */ - const float(*lnors)[3] = (flag & MESH_FOREACH_USE_NORMAL) ? - static_cast( - CustomData_get_layer(&mesh->ldata, CD_NORMAL)) : - nullptr; + const float(*loop_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ? + static_cast( + CustomData_get_layer(&mesh->ldata, CD_NORMAL)) : + nullptr; int f_idx; @@ -179,16 +179,16 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh, do { const BMVert *eve = l_iter->v; const int v_idx = BM_elem_index_get(eve); - const float *no = lnors ? *lnors++ : nullptr; + const float *no = loop_normals ? *loop_normals++ : nullptr; func(userData, v_idx, f_idx, vertexCos ? vertexCos[v_idx] : eve->co, no); } while ((l_iter = l_iter->next) != l_first); } } else { - const float(*lnors)[3] = (flag & MESH_FOREACH_USE_NORMAL) ? - static_cast( - CustomData_get_layer(&mesh->ldata, CD_NORMAL)) : - nullptr; + const float(*loop_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ? + static_cast( + CustomData_get_layer(&mesh->ldata, CD_NORMAL)) : + nullptr; const MVert *mv = BKE_mesh_verts(mesh); const MLoop *ml = BKE_mesh_loops(mesh); @@ -204,7 +204,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh, for (i = 0; i < mp->totloop; i++, ml++) { const int v_idx = v_index ? v_index[ml->v] : ml->v; const int f_idx = f_index ? f_index[p_idx] : p_idx; - const float *no = lnors ? *lnors++ : nullptr; + const float *no = loop_normals ? *loop_normals++ : nullptr; if (ELEM(ORIGINDEX_NONE, v_idx, f_idx)) { continue; } @@ -217,7 +217,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh, for (i = 0; i < mp->totloop; i++, ml++) { const int v_idx = ml->v; const int f_idx = p_idx; - const float *no = lnors ? *lnors++ : nullptr; + const float *no = loop_normals ? *loop_normals++ : nullptr; func(userData, v_idx, f_idx, mv[ml->v].co, no); } } diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 28bbc0ffae3..5c9c74c6dc8 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -326,12 +326,13 @@ static void bm_corners_to_loops_ex(ID *id, } if (CustomData_has_layer(fdata, CD_TESSLOOPNORMAL)) { - float(*lnors)[3] = (float(*)[3])CustomData_get(ldata, loopstart, CD_NORMAL); - const short(*tlnors)[3] = (short(*)[3])CustomData_get(fdata, findex, CD_TESSLOOPNORMAL); + float(*loop_normals)[3] = (float(*)[3])CustomData_get(ldata, loopstart, CD_NORMAL); + const short(*tessloop_normals)[3] = (short(*)[3])CustomData_get( + fdata, findex, CD_TESSLOOPNORMAL); const int max = mf->v4 ? 4 : 3; - for (int i = 0; i < max; i++, lnors++, tlnors++) { - normal_short_to_float_v3(*lnors, *tlnors); + for (int i = 0; i < max; i++, loop_normals++, tessloop_normals++) { + normal_short_to_float_v3(*loop_normals, *tessloop_normals); } } @@ -842,12 +843,12 @@ static void mesh_loops_to_tessdata(CustomData *fdata, } if (hasLoopNormal) { - short(*fnors)[4][3] = (short(*)[4][3])CustomData_get_layer(fdata, CD_TESSLOOPNORMAL); - const float(*lnors)[3] = (const float(*)[3])CustomData_get_layer(ldata, CD_NORMAL); + short(*face_normals)[4][3] = (short(*)[4][3])CustomData_get_layer(fdata, CD_TESSLOOPNORMAL); + const float(*loop_normals)[3] = (const float(*)[3])CustomData_get_layer(ldata, CD_NORMAL); - for (findex = 0, lidx = loopindices; findex < num_faces; lidx++, findex++, fnors++) { + for (findex = 0, lidx = loopindices; findex < num_faces; lidx++, findex++, face_normals++) { for (j = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3; j--;) { - normal_float_to_short_v3((*fnors)[j], lnors[(*lidx)[j]]); + normal_float_to_short_v3((*face_normals)[j], loop_normals[(*lidx)[j]]); } } } diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index 5a15c54df9e..3db34786661 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -814,7 +814,7 @@ struct LoopSplitTaskDataCommon { * Note we do not need to protect it, though, since two different tasks will *always* affect * different elements in the arrays. */ MLoopNorSpaceArray *lnors_spacearr; - MutableSpan loopnors; + MutableSpan loop_normals; MutableSpan clnors_data; /* Read-only. */ @@ -824,7 +824,7 @@ struct LoopSplitTaskDataCommon { Span polys; Span edge_to_loops; Span loop_to_poly; - Span polynors; + Span poly_normals; Span vert_normals; }; @@ -906,7 +906,7 @@ void BKE_edges_sharp_from_angle_set(MEdge *medges, const MLoop *mloops, const int numLoops, const MPoly *mpolys, - const float (*polynors)[3], + const float (*poly_normals)[3], const int numPolys, const float split_angle) { @@ -929,7 +929,7 @@ void BKE_edges_sharp_from_angle_set(MEdge *medges, {mpolys, numPolys}, {mloops, numLoops}, loop_to_poly, - {reinterpret_cast(polynors), numPolys}, + {reinterpret_cast(poly_normals), numPolys}, true, split_angle, edge_to_loops, @@ -996,8 +996,8 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS const Span verts = common_data->verts; const Span edges = common_data->edges; const Span loops = common_data->loops; - const Span polynors = common_data->polynors; - MutableSpan loop_normals = common_data->loopnors; + const Span poly_normals = common_data->poly_normals; + MutableSpan loop_normals = common_data->loop_normals; MLoopNorSpace *lnor_space = data->lnor_space; const int ml_curr_index = data->ml_curr_index; @@ -1007,7 +1007,7 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS /* Simple case (both edges around that vertex are sharp in current polygon), * this loop just takes its poly normal. */ - loop_normals[ml_curr_index] = polynors[mp_index]; + loop_normals[ml_curr_index] = poly_normals[mp_index]; #if 0 printf("BASIC: handling loop %d / edge %d / vert %d / poly %d\n", @@ -1051,7 +1051,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, BLI_Stack *edge_vectors) { MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr; - MutableSpan loopnors = common_data->loopnors; + MutableSpan loop_normals = common_data->loop_normals; MutableSpan clnors_data = common_data->clnors_data; const Span verts = common_data->verts; @@ -1060,7 +1060,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, const Span loops = common_data->loops; const Span edge_to_loops = common_data->edge_to_loops; const Span loop_to_poly = common_data->loop_to_poly; - const Span polynors = common_data->polynors; + const Span poly_normals = common_data->poly_normals; MLoopNorSpace *lnor_space = data->lnor_space; #if 0 /* Not needed for 'fan' loops. */ @@ -1143,7 +1143,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, /* Calculate angle between the two poly edges incident on this vertex. */ const float fac = saacos(dot_v3v3(vec_curr, vec_prev)); /* Accumulate */ - madd_v3_v3fl(lnor, polynors[mpfan_curr_index], fac); + madd_v3_v3fl(lnor, poly_normals[mpfan_curr_index], fac); if (!clnors_data.is_empty()) { /* Accumulate all clnors, if they are not all equal we have to fix that! */ @@ -1157,13 +1157,13 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, clnors_avg[0] += (*clnor)[0]; clnors_avg[1] += (*clnor)[1]; clnors_count++; - /* We store here a pointer to all custom lnors processed. */ + /* We store here a pointer to all custom loop_normals processed. */ BLI_SMALLSTACK_PUSH(clnors, (short *)*clnor); } } /* We store here a pointer to all loop-normals processed. */ - BLI_SMALLSTACK_PUSH(normal, (float *)(loopnors[mlfan_vert_index])); + BLI_SMALLSTACK_PUSH(normal, (float *)(loop_normals[mlfan_vert_index])); if (lnors_spacearr) { /* Assign current lnor space to current 'vertex' loop. */ @@ -1203,7 +1203,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, if (lnors_spacearr) { if (UNLIKELY(lnor_len == 0.0f)) { /* Use vertex normal as fallback! */ - copy_v3_v3(lnor, loopnors[mlfan_vert_index]); + copy_v3_v3(lnor, loop_normals[mlfan_vert_index]); lnor_len = 1.0f; } @@ -1497,10 +1497,10 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, const MEdge *medges, const int numEdges, const MLoop *mloops, - float (*r_loopnors)[3], + float (*r_loop_normals)[3], const int numLoops, const MPoly *mpolys, - const float (*polynors)[3], + const float (*poly_normals)[3], const int numPolys, const bool use_split_normals, const float split_angle, @@ -1515,11 +1515,11 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, BLI_assert(use_split_normals || !(r_lnors_spacearr)); if (!use_split_normals) { - /* In this case, we simply fill lnors with vnors (or fnors for flat faces), quite simple! + /* In this case, simply fill `r_loop_normals` with `vert_normals` + * (or `poly_normals` for flat faces), quite simple! * Note this is done here to keep some logic and consistency in this quite complex code, - * since we may want to use lnors even when mesh's 'autosmooth' is disabled - * (see e.g. mesh mapping code). - * As usual, we could handle that on case-by-case basis, + * since we may want to use loop_normals even when mesh's 'autosmooth' is disabled + * (see e.g. mesh mapping code). As usual, we could handle that on case-by-case basis, * but simpler to keep it well confined here. */ int mp_index; @@ -1531,10 +1531,10 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, for (; ml_index < ml_index_end; ml_index++) { if (is_poly_flat) { - copy_v3_v3(r_loopnors[ml_index], polynors[mp_index]); + copy_v3_v3(r_loop_normals[ml_index], poly_normals[mp_index]); } else { - copy_v3_v3(r_loopnors[ml_index], vert_normals[mloops[ml_index].v]); + copy_v3_v3(r_loop_normals[ml_index], vert_normals[mloops[ml_index].v]); } } } @@ -1591,7 +1591,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, /* Init data common to all tasks. */ LoopSplitTaskDataCommon common_data; common_data.lnors_spacearr = r_lnors_spacearr; - common_data.loopnors = {reinterpret_cast(r_loopnors), numLoops}; + common_data.loop_normals = {reinterpret_cast(r_loop_normals), numLoops}; common_data.clnors_data = {reinterpret_cast(clnors_data), clnors_data ? numLoops : 0}; common_data.verts = {mverts, numVerts}; common_data.edges = {medges, numEdges}; @@ -1599,7 +1599,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, common_data.loops = loops; common_data.edge_to_loops = edge_to_loops; common_data.loop_to_poly = loop_to_poly; - common_data.polynors = {reinterpret_cast(polynors), numPolys}; + common_data.poly_normals = {reinterpret_cast(poly_normals), numPolys}; common_data.vert_normals = {reinterpret_cast(vert_normals), numVerts}; /* Pre-populate all loop normals as if their verts were all smooth. @@ -1608,7 +1608,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, for (const int poly_i : range) { const MPoly &poly = polys[poly_i]; for (const int loop_i : IndexRange(poly.loopstart, poly.totloop)) { - copy_v3_v3(r_loopnors[loop_i], vert_normals[loops[loop_i].v]); + copy_v3_v3(r_loop_normals[loop_i], vert_normals[loops[loop_i].v]); } } }); @@ -1618,7 +1618,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, polys, loops, loop_to_poly, - {reinterpret_cast(polynors), numPolys}, + {reinterpret_cast(poly_normals), numPolys}, check_angle, split_angle, edge_to_loops, @@ -1653,9 +1653,9 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, * Compute internal representation of given custom normals (as an array of float[2]). * It also makes sure the mesh matches those custom normals, by setting sharp edges flag as needed * to get a same custom lnor for all loops sharing a same smooth fan. - * If use_vertices if true, r_custom_loopnors is assumed to be per-vertex, not per-loop + * If use_vertices if true, r_custom_loop_normals is assumed to be per-vertex, not per-loop * (this allows to set whole vert's normals at once, useful in some cases). - * r_custom_loopnors is expected to have normalized normals, or zero ones, + * r_custom_loop_normals is expected to have normalized normals, or zero ones, * in which case they will be replaced by default loop/vertex normal. */ static void mesh_normals_loop_custom_set(const MVert *mverts, @@ -1664,10 +1664,10 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, MEdge *medges, const int numEdges, const MLoop *mloops, - float (*r_custom_loopnors)[3], + float (*r_custom_loop_normals)[3], const int numLoops, const MPoly *mpolys, - const float (*polynors)[3], + const float (*poly_normals)[3], const int numPolys, short (*r_clnors_data)[2], const bool use_vertices) @@ -1682,7 +1682,8 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, * So better to keep some simplicity here, and just call #BKE_mesh_normals_loop_split() twice! */ MLoopNorSpaceArray lnors_spacearr = {nullptr}; BitVector<> done_loops(numLoops, false); - float(*lnors)[3] = (float(*)[3])MEM_calloc_arrayN(size_t(numLoops), sizeof(*lnors), __func__); + float(*loop_normals)[3] = (float(*)[3])MEM_calloc_arrayN( + size_t(numLoops), sizeof(*loop_normals), __func__); const Array loop_to_poly = mesh_topology::build_loop_to_poly_map({mpolys, numPolys}, numLoops); /* In this case we always consider split nors as ON, @@ -1699,10 +1700,10 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, medges, numEdges, mloops, - lnors, + loop_normals, numLoops, mpolys, - polynors, + poly_normals, numPolys, use_split_normals, split_angle, @@ -1713,15 +1714,15 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, /* Set all given zero vectors to their default value. */ if (use_vertices) { for (int i = 0; i < numVerts; i++) { - if (is_zero_v3(r_custom_loopnors[i])) { - copy_v3_v3(r_custom_loopnors[i], vert_normals[i]); + if (is_zero_v3(r_custom_loop_normals[i])) { + copy_v3_v3(r_custom_loop_normals[i], vert_normals[i]); } } } else { for (int i = 0; i < numLoops; i++) { - if (is_zero_v3(r_custom_loopnors[i])) { - copy_v3_v3(r_custom_loopnors[i], lnors[i]); + if (is_zero_v3(r_custom_loop_normals[i])) { + copy_v3_v3(r_custom_loop_normals[i], loop_normals[i]); } } } @@ -1729,9 +1730,9 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, BLI_assert(lnors_spacearr.data_type == MLNOR_SPACEARR_LOOP_INDEX); /* Now, check each current smooth fan (one lnor space per smooth fan!), - * and if all its matching custom lnors are not (enough) equal, add sharp edges as needed. + * and if all its matching custom loop_normals are not (enough) equal, add sharp edges as needed. * This way, next time we run BKE_mesh_normals_loop_split(), we'll get lnor spacearr/smooth fans - * matching given custom lnors. + * matching given custom loop_normals. * Note this code *will never* unsharp edges! And quite obviously, * when we set custom normals per vertices, running this is absolutely useless. */ if (use_vertices) { @@ -1775,7 +1776,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, const int lidx = POINTER_AS_INT(loops->link); const MLoop *ml = &mloops[lidx]; const int nidx = lidx; - float *nor = r_custom_loopnors[nidx]; + float *nor = r_custom_loop_normals[nidx]; if (!org_nor) { org_nor = nor; @@ -1807,7 +1808,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, const int lidx = POINTER_AS_INT(loops->link); const MLoop *ml = &mloops[lidx]; const int nidx = lidx; - float *nor = r_custom_loopnors[nidx]; + float *nor = r_custom_loop_normals[nidx]; if (dot_v3v3(org_nor, nor) < LNOR_SPACE_TRIGO_THRESHOLD) { const MPoly *mp = &mpolys[loop_to_poly[lidx]]; @@ -1818,7 +1819,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, } } - /* And now, recompute our new auto lnors and lnor spacearr! */ + /* And now, recompute our new auto `loop_normals` and lnor spacearr! */ BKE_lnor_spacearr_clear(&lnors_spacearr); BKE_mesh_normals_loop_split(mverts, vert_normals, @@ -1826,10 +1827,10 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, medges, numEdges, mloops, - lnors, + loop_normals, numLoops, mpolys, - polynors, + poly_normals, numPolys, use_split_normals, split_angle, @@ -1858,7 +1859,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, if (lnors_spacearr.lspacearr[i]->flags & MLNOR_SPACE_IS_SINGLE) { BLI_assert(POINTER_AS_INT(loops) == i); const int nidx = use_vertices ? int(mloops[i].v) : i; - float *nor = r_custom_loopnors[nidx]; + float *nor = r_custom_loop_normals[nidx]; BKE_lnor_space_custom_normal_to_data(lnors_spacearr.lspacearr[i], nor, r_clnors_data[i]); done_loops[i].reset(); @@ -1872,7 +1873,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, while (loops) { const int lidx = POINTER_AS_INT(loops->link); const int nidx = use_vertices ? int(mloops[lidx].v) : lidx; - float *nor = r_custom_loopnors[nidx]; + float *nor = r_custom_loop_normals[nidx]; avg_nor_count++; add_v3_v3(avg_nor, nor); @@ -1893,7 +1894,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, } } - MEM_freeN(lnors); + MEM_freeN(loop_normals); BKE_lnor_spacearr_free(&lnors_spacearr); } @@ -1903,10 +1904,10 @@ void BKE_mesh_normals_loop_custom_set(const MVert *mverts, MEdge *medges, const int numEdges, const MLoop *mloops, - float (*r_custom_loopnors)[3], + float (*r_custom_loop_normals)[3], const int numLoops, const MPoly *mpolys, - const float (*polynors)[3], + const float (*poly_normals)[3], const int numPolys, short (*r_clnors_data)[2]) { @@ -1916,10 +1917,10 @@ void BKE_mesh_normals_loop_custom_set(const MVert *mverts, medges, numEdges, mloops, - r_custom_loopnors, + r_custom_loop_normals, numLoops, mpolys, - polynors, + poly_normals, numPolys, r_clnors_data, false); @@ -1927,14 +1928,14 @@ void BKE_mesh_normals_loop_custom_set(const MVert *mverts, void BKE_mesh_normals_loop_custom_from_verts_set(const MVert *mverts, const float (*vert_normals)[3], - float (*r_custom_vertnors)[3], + float (*r_custom_vert_normals)[3], const int numVerts, MEdge *medges, const int numEdges, const MLoop *mloops, const int numLoops, const MPoly *mpolys, - const float (*polynors)[3], + const float (*poly_normals)[3], const int numPolys, short (*r_clnors_data)[2]) { @@ -1944,10 +1945,10 @@ void BKE_mesh_normals_loop_custom_from_verts_set(const MVert *mverts, medges, numEdges, mloops, - r_custom_vertnors, + r_custom_vert_normals, numLoops, mpolys, - polynors, + poly_normals, numPolys, r_clnors_data, true); @@ -1986,14 +1987,14 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const use_vertices); } -void BKE_mesh_set_custom_normals(Mesh *mesh, float (*r_custom_loopnors)[3]) +void BKE_mesh_set_custom_normals(Mesh *mesh, float (*r_custom_loop_normals)[3]) { - mesh_set_custom_normals(mesh, r_custom_loopnors, false); + mesh_set_custom_normals(mesh, r_custom_loop_normals, false); } -void BKE_mesh_set_custom_normals_from_verts(Mesh *mesh, float (*r_custom_vertnors)[3]) +void BKE_mesh_set_custom_normals_from_verts(Mesh *mesh, float (*r_custom_vert_normals)[3]) { - mesh_set_custom_normals(mesh, r_custom_vertnors, true); + mesh_set_custom_normals(mesh, r_custom_vert_normals, true); } void BKE_mesh_normals_loop_to_vertex(const int numVerts, diff --git a/source/blender/blenkernel/intern/mesh_tangent.cc b/source/blender/blenkernel/intern/mesh_tangent.cc index 49ea23a1552..8534a68cca4 100644 --- a/source/blender/blenkernel/intern/mesh_tangent.cc +++ b/source/blender/blenkernel/intern/mesh_tangent.cc @@ -58,7 +58,7 @@ struct BKEMeshToTangent { mikk::float3 GetNormal(const uint face_num, const uint vert_num) { - return mikk::float3(lnors[uint(mpolys[face_num].loopstart) + vert_num]); + return mikk::float3(loop_normals[uint(mpolys[face_num].loopstart) + vert_num]); } void SetTangentSpace(const uint face_num, const uint vert_num, mikk::float3 T, bool orientation) @@ -67,20 +67,20 @@ struct BKEMeshToTangent { copy_v4_fl4(p_res, T.x, T.y, T.z, orientation ? 1.0f : -1.0f); } - const MPoly *mpolys; /* faces */ - const MLoop *mloops; /* faces vertices */ - const MVert *mverts; /* vertices */ - const MLoopUV *luvs; /* texture coordinates */ - const float (*lnors)[3]; /* loops' normals */ - float (*tangents)[4]; /* output tangents */ - int num_polys; /* number of polygons */ + const MPoly *mpolys; /* faces */ + const MLoop *mloops; /* faces vertices */ + const MVert *mverts; /* vertices */ + const MLoopUV *luvs; /* texture coordinates */ + const float (*loop_normals)[3]; /* loops' normals */ + float (*tangents)[4]; /* output tangents */ + int num_polys; /* number of polygons */ }; void BKE_mesh_calc_loop_tangent_single_ex(const MVert *mverts, const int /*numVerts*/, const MLoop *mloops, float (*r_looptangent)[4], - const float (*loopnors)[3], + const float (*loop_normals)[3], const MLoopUV *loopuvs, const int /*numLoops*/, const MPoly *mpolys, @@ -93,7 +93,7 @@ void BKE_mesh_calc_loop_tangent_single_ex(const MVert *mverts, mesh_to_tangent.mloops = mloops; mesh_to_tangent.mverts = mverts; mesh_to_tangent.luvs = loopuvs; - mesh_to_tangent.lnors = loopnors; + mesh_to_tangent.loop_normals = loop_normals; mesh_to_tangent.tangents = r_looptangent; mesh_to_tangent.num_polys = numPolys; @@ -133,9 +133,9 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, return; } - const float(*loopnors)[3] = static_cast( + const float(*loop_normals)[3] = static_cast( CustomData_get_layer(&mesh->ldata, CD_NORMAL)); - if (!loopnors) { + if (!loop_normals) { BKE_report( reports, RPT_ERROR, "Tangent space computation needs loop normals, none found, aborting"); return; @@ -145,7 +145,7 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, mesh->totvert, BKE_mesh_loops(mesh), r_looptangents, - loopnors, + loop_normals, loopuvs, mesh->totloop, BKE_mesh_polys(mesh), diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index efaeb89c9a9..ca0039d1a58 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1335,7 +1335,7 @@ typedef struct PBVHUpdateData { PBVHNode **nodes; int totnode; - float (*vnors)[3]; + float (*vert_normals)[3]; int flag; bool show_sculpt_face_sets; PBVHAttrReq *attrs; @@ -1349,7 +1349,7 @@ static void pbvh_update_normals_clear_task_cb(void *__restrict userdata, PBVHUpdateData *data = userdata; PBVH *pbvh = data->pbvh; PBVHNode *node = data->nodes[n]; - float(*vnors)[3] = data->vnors; + float(*vert_normals)[3] = data->vert_normals; if (node->flag & PBVH_UpdateNormals) { const int *verts = node->vert_indices; @@ -1357,7 +1357,7 @@ static void pbvh_update_normals_clear_task_cb(void *__restrict userdata, for (int i = 0; i < totvert; i++) { const int v = verts[i]; if (pbvh->vert_bitmap[v]) { - zero_v3(vnors[v]); + zero_v3(vert_normals[v]); } } } @@ -1371,7 +1371,7 @@ static void pbvh_update_normals_accum_task_cb(void *__restrict userdata, PBVH *pbvh = data->pbvh; PBVHNode *node = data->nodes[n]; - float(*vnors)[3] = data->vnors; + float(*vert_normals)[3] = data->vert_normals; if (node->flag & PBVH_UpdateNormals) { uint mpoly_prev = UINT_MAX; @@ -1405,7 +1405,7 @@ static void pbvh_update_normals_accum_task_cb(void *__restrict userdata, * Not exact equivalent though, since atomicity is only ensured for one component * of the vector at a time, but here it shall not make any sensible difference. */ for (int k = 3; k--;) { - atomic_add_and_fetch_fl(&vnors[v][k], fn[k]); + atomic_add_and_fetch_fl(&vert_normals[v][k], fn[k]); } } } @@ -1420,7 +1420,7 @@ static void pbvh_update_normals_store_task_cb(void *__restrict userdata, PBVHUpdateData *data = userdata; PBVH *pbvh = data->pbvh; PBVHNode *node = data->nodes[n]; - float(*vnors)[3] = data->vnors; + float(*vert_normals)[3] = data->vert_normals; if (node->flag & PBVH_UpdateNormals) { const int *verts = node->vert_indices; @@ -1432,7 +1432,7 @@ static void pbvh_update_normals_store_task_cb(void *__restrict userdata, /* No atomics necessary because we are iterating over uniq_verts only, * so we know only this thread will handle this vertex. */ if (pbvh->vert_bitmap[v]) { - normalize_v3(vnors[v]); + normalize_v3(vert_normals[v]); pbvh->vert_bitmap[v] = false; } } @@ -1456,7 +1456,7 @@ static void pbvh_faces_update_normals(PBVH *pbvh, PBVHNode **nodes, int totnode) PBVHUpdateData data = { .pbvh = pbvh, .nodes = nodes, - .vnors = pbvh->vert_normals, + .vert_normals = pbvh->vert_normals, }; TaskParallelSettings settings; diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index f28748dcbce..b8288160b82 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -134,7 +134,7 @@ bool BKE_shrinkwrap_init_tree( } if (force_normals || BKE_shrinkwrap_needs_normals(shrinkType, shrinkMode)) { - data->pnors = BKE_mesh_poly_normals_ensure(mesh); + data->poly_normals = BKE_mesh_poly_normals_ensure(mesh); if ((mesh->flag & ME_AUTOSMOOTH) != 0) { data->clnors = static_cast(CustomData_get_layer(&mesh->ldata, CD_NORMAL)); } @@ -1218,8 +1218,8 @@ void BKE_shrinkwrap_compute_smooth_normal(const ShrinkwrapTreeData *tree, } } /* Use the polygon normal if flat. */ - else if (tree->pnors != nullptr) { - copy_v3_v3(r_no, tree->pnors[tri->poly]); + else if (tree->poly_normals != nullptr) { + copy_v3_v3(r_no, tree->poly_normals[tri->poly]); } /* Finally fallback to the looptri normal. */ else { diff --git a/source/blender/draw/engines/overlay/overlay_edit_mesh.cc b/source/blender/draw/engines/overlay/overlay_edit_mesh.cc index 4509fd53ed8..f705bde6b54 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_mesh.cc +++ b/source/blender/draw/engines/overlay/overlay_edit_mesh.cc @@ -285,11 +285,11 @@ void OVERLAY_edit_mesh_cache_populate(OVERLAY_Data *vedata, Object *ob) struct GPUBatch *normal_geom = DRW_cache_normal_arrow_get(); Mesh *me = static_cast(ob->data); if (vnormals_do) { - geom = DRW_mesh_batch_cache_get_edit_vnors(me); + geom = DRW_mesh_batch_cache_get_edit_vert_normals(me); DRW_shgroup_call_instances_with_attrs(pd->edit_mesh_normals_grp, ob, normal_geom, geom); } if (lnormals_do) { - geom = DRW_mesh_batch_cache_get_edit_lnors(me); + geom = DRW_mesh_batch_cache_get_edit_loop_normals(me); DRW_shgroup_call_instances_with_attrs(pd->edit_mesh_normals_grp, ob, normal_geom, geom); } if (fnormals_do) { diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 6f7f34a3d79..73ca5821ff0 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -213,8 +213,8 @@ struct GPUBatch *DRW_mesh_batch_cache_get_surface_viewer_attribute(struct Mesh * struct GPUBatch *DRW_mesh_batch_cache_get_edit_triangles(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_edit_vertices(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_edit_edges(struct Mesh *me); -struct GPUBatch *DRW_mesh_batch_cache_get_edit_vnors(struct Mesh *me); -struct GPUBatch *DRW_mesh_batch_cache_get_edit_lnors(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_edit_vert_normals(struct Mesh *me); +struct GPUBatch *DRW_mesh_batch_cache_get_edit_loop_normals(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_edit_facedots(struct Mesh *me); struct GPUBatch *DRW_mesh_batch_cache_get_edit_skin_roots(struct Mesh *me); diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc index 2f560d161d7..15057af2472 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.cc +++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc @@ -1111,14 +1111,14 @@ GPUBatch *DRW_mesh_batch_cache_get_edit_vertices(Mesh *me) return DRW_batch_request(&cache->batch.edit_vertices); } -GPUBatch *DRW_mesh_batch_cache_get_edit_vnors(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_edit_vert_normals(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); mesh_batch_cache_add_request(cache, MBC_EDIT_VNOR); return DRW_batch_request(&cache->batch.edit_vnor); } -GPUBatch *DRW_mesh_batch_cache_get_edit_lnors(Mesh *me) +GPUBatch *DRW_mesh_batch_cache_get_edit_loop_normals(Mesh *me) { MeshBatchCache *cache = mesh_batch_cache_get(me); mesh_batch_cache_add_request(cache, MBC_EDIT_LNOR); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc index 8d9e6742d61..ac3317e27ec 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc @@ -264,16 +264,17 @@ static void extract_pos_nor_init_subdiv(const DRWSubdivCache *subdiv_cache, if (subdiv_cache->use_custom_loop_normals) { Mesh *coarse_mesh = subdiv_cache->mesh; - const float(*lnors)[3] = static_cast( + const float(*loop_normals)[3] = static_cast( CustomData_get_layer(&coarse_mesh->ldata, CD_NORMAL)); - BLI_assert(lnors != nullptr); + BLI_assert(loop_normals != nullptr); GPUVertBuf *src_custom_normals = GPU_vertbuf_calloc(); GPU_vertbuf_init_with_format(src_custom_normals, get_custom_normals_format()); GPU_vertbuf_data_alloc(src_custom_normals, coarse_mesh->totloop); - memcpy( - GPU_vertbuf_get_data(src_custom_normals), lnors, sizeof(float[3]) * coarse_mesh->totloop); + memcpy(GPU_vertbuf_get_data(src_custom_normals), + loop_normals, + sizeof(float[3]) * coarse_mesh->totloop); GPUVertBuf *dst_custom_normals = GPU_vertbuf_calloc(); GPU_vertbuf_init_build_on_device( diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index dfb9e8a79fa..de83d5d0c1f 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -78,8 +78,8 @@ struct LaplacianSystem { const MLoop *mloop; /* needed to find vertices by index */ int verts_num; int tris_num; - float (*verts)[3]; /* vertex coordinates */ - float (*vnors)[3]; /* vertex normals */ + float (*verts)[3]; /* vertex coordinates */ + float (*vert_normals)[3]; /* vertex normals */ float (*root)[3]; /* bone root */ float (*tip)[3]; /* bone tip */ @@ -489,7 +489,7 @@ static float heat_source_distance(LaplacianSystem *sys, int vertex, int source) dist = normalize_v3(d); /* if the vertex normal does not point along the bone, increase distance */ - cosine = dot_v3v3(d, sys->heat.vnors[vertex]); + cosine = dot_v3v3(d, sys->heat.vert_normals[vertex]); return dist / (0.5f * (cosine + 1.001f)); } @@ -553,7 +553,7 @@ static void heat_calc_vnormals(LaplacianSystem *sys) float fnor[3]; int a, v1, v2, v3, (*face)[3]; - sys->heat.vnors = MEM_callocN(sizeof(float[3]) * sys->verts_num, "HeatVNors"); + sys->heat.vert_normals = MEM_callocN(sizeof(float[3]) * sys->verts_num, "HeatVNors"); for (a = 0, face = sys->faces; a < sys->faces_num; a++, face++) { v1 = (*face)[0]; @@ -562,13 +562,13 @@ static void heat_calc_vnormals(LaplacianSystem *sys) normal_tri_v3(fnor, sys->verts[v1], sys->verts[v2], sys->verts[v3]); - add_v3_v3(sys->heat.vnors[v1], fnor); - add_v3_v3(sys->heat.vnors[v2], fnor); - add_v3_v3(sys->heat.vnors[v3], fnor); + add_v3_v3(sys->heat.vert_normals[v1], fnor); + add_v3_v3(sys->heat.vert_normals[v2], fnor); + add_v3_v3(sys->heat.vert_normals[v3], fnor); } for (a = 0; a < sys->verts_num; a++) { - normalize_v3(sys->heat.vnors[a]); + normalize_v3(sys->heat.vert_normals[a]); } } @@ -615,7 +615,7 @@ static void heat_system_free(LaplacianSystem *sys) MEM_freeN(sys->heat.mindist); MEM_freeN(sys->heat.H); MEM_freeN(sys->heat.p); - MEM_freeN(sys->heat.vnors); + MEM_freeN(sys->heat.vert_normals); } static float heat_limit_weight(float weight) diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 68675fab6b4..63447c85818 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -9627,11 +9627,11 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op) BKE_editmesh_ensure_autosmooth(em, obedit->data); BKE_editmesh_lnorspace_update(em, obedit->data); - float(*vnors)[3] = MEM_mallocN(sizeof(*vnors) * bm->totvert, __func__); + float(*vert_normals)[3] = MEM_mallocN(sizeof(*vert_normals) * bm->totvert, __func__); { int v_index; BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, v_index) { - BM_vert_calc_normal_ex(v, BM_ELEM_SELECT, vnors[v_index]); + BM_vert_calc_normal_ex(v, BM_ELEM_SELECT, vert_normals[v_index]); } } @@ -9647,10 +9647,10 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op) const int l_index = BM_elem_index_get(l); const int v_index = BM_elem_index_get(l->v); - if (!is_zero_v3(vnors[v_index])) { + if (!is_zero_v3(vert_normals[v_index])) { short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); BKE_lnor_space_custom_normal_to_data( - bm->lnor_spacearr->lspacearr[l_index], vnors[v_index], clnors); + bm->lnor_spacearr->lspacearr[l_index], vert_normals[v_index], clnors); if (bm->lnor_spacearr->lspacearr[l_index]->flags & MLNOR_SPACE_IS_SINGLE) { BLI_BITMAP_ENABLE(loop_set, l_index); @@ -9674,13 +9674,13 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op) const int loop_index = BM_elem_index_get(l); short *clnors = BM_ELEM_CD_GET_VOID_P(l, cd_clnors_offset); BKE_lnor_space_custom_normal_to_data( - bm->lnor_spacearr->lspacearr[loop_index], vnors[v_index], clnors); + bm->lnor_spacearr->lspacearr[loop_index], vert_normals[v_index], clnors); } } } MEM_freeN(loop_set); - MEM_freeN(vnors); + MEM_freeN(vert_normals); EDBM_update(obedit->data, &(const struct EDBMUpdate_Params){ .calc_looptri = true, diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc index f2183624888..f632891dfda 100644 --- a/source/blender/io/alembic/intern/abc_reader_mesh.cc +++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc @@ -299,17 +299,17 @@ static void process_vertex_normals(CDStreamConfig &config, return; } - float(*vnors)[3] = static_cast( + float(*vert_normals)[3] = static_cast( MEM_malloc_arrayN(normals_count, sizeof(float[3]), "ABC::VertexNormals")); const N3fArraySample &vertex_normals = *vertex_normals_ptr; for (int index = 0; index < normals_count; index++) { - copy_zup_from_yup(vnors[index], vertex_normals[index].getValue()); + copy_zup_from_yup(vert_normals[index], vertex_normals[index].getValue()); } config.mesh->flag |= ME_AUTOSMOOTH; - BKE_mesh_set_custom_normals_from_verts(config.mesh, vnors); - MEM_freeN(vnors); + BKE_mesh_set_custom_normals_from_verts(config.mesh, vert_normals); + MEM_freeN(vert_normals); } static void process_normals(CDStreamConfig &config, diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 289de8285be..0675c39299e 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -102,14 +102,14 @@ static void rna_Mesh_calc_smooth_groups( } static void rna_Mesh_normals_split_custom_do(Mesh *mesh, - float (*custom_loopnors)[3], + float (*custom_loop_or_vert_normals)[3], const bool use_verts) { if (use_verts) { - BKE_mesh_set_custom_normals_from_verts(mesh, custom_loopnors); + BKE_mesh_set_custom_normals_from_verts(mesh, custom_loop_or_vert_normals); } else { - BKE_mesh_set_custom_normals(mesh, custom_loopnors); + BKE_mesh_set_custom_normals(mesh, custom_loop_or_vert_normals); } } @@ -118,7 +118,7 @@ static void rna_Mesh_normals_split_custom_set(Mesh *mesh, int normals_len, float *normals) { - float(*loopnors)[3] = (float(*)[3])normals; + float(*loop_normals)[3] = (float(*)[3])normals; const int numloops = mesh->totloop; if (normals_len != numloops * 3) { @@ -130,7 +130,7 @@ static void rna_Mesh_normals_split_custom_set(Mesh *mesh, return; } - rna_Mesh_normals_split_custom_do(mesh, loopnors, false); + rna_Mesh_normals_split_custom_do(mesh, loop_normals, false); DEG_id_tag_update(&mesh->id, 0); } @@ -140,7 +140,7 @@ static void rna_Mesh_normals_split_custom_set_from_vertices(Mesh *mesh, int normals_len, float *normals) { - float(*vertnors)[3] = (float(*)[3])normals; + float(*vert_normals)[3] = (float(*)[3])normals; const int numverts = mesh->totvert; if (normals_len != numverts * 3) { @@ -152,7 +152,7 @@ static void rna_Mesh_normals_split_custom_set_from_vertices(Mesh *mesh, return; } - rna_Mesh_normals_split_custom_do(mesh, vertnors, true); + rna_Mesh_normals_split_custom_do(mesh, vert_normals, true); DEG_id_tag_update(&mesh->id, 0); } diff --git a/source/blender/modifiers/intern/MOD_normal_edit.cc b/source/blender/modifiers/intern/MOD_normal_edit.cc index 29404fb044a..cc25f032228 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.cc +++ b/source/blender/modifiers/intern/MOD_normal_edit.cc @@ -176,7 +176,7 @@ static bool polygons_check_flip(MLoop *mloop, float (*nos)[3], CustomData *ldata, const MPoly *mpoly, - float (*polynors)[3], + float (*poly_normals)[3], const int polys_num) { const MPoly *mp; @@ -198,9 +198,9 @@ static bool polygons_check_flip(MLoop *mloop, } /* If average of new loop normals is opposed to polygon normal, flip polygon. */ - if (dot_v3v3(polynors[i], norsum) < 0.0f) { + if (dot_v3v3(poly_normals[i], norsum) < 0.0f) { BKE_mesh_polygon_flip_ex(mp, mloop, ldata, nos, mdisp, true); - negate_v3(polynors[i]); + negate_v3(poly_normals[i]); flipped = true; } } @@ -213,8 +213,8 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, Object *ob, Mesh *mesh, short (*clnors)[2], - float (*loopnors)[3], - const float (*polynors)[3], + float (*loop_normals)[3], + const float (*poly_normals)[3], const short mix_mode, const float mix_factor, const float mix_limit, @@ -308,7 +308,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, } } - if (loopnors) { + if (loop_normals) { mix_normals(mix_factor, dvert, defgrp_index, @@ -317,7 +317,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, mix_mode, verts_num, mloop, - loopnors, + loop_normals, nos, loops_num); } @@ -338,7 +338,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, nos, loops_num, mpoly, - polynors, + poly_normals, polys_num, clnors); @@ -352,8 +352,8 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, Object *ob, Mesh *mesh, short (*clnors)[2], - float (*loopnors)[3], - const float (*polynors)[3], + float (*loop_normals)[3], + const float (*poly_normals)[3], const short mix_mode, const float mix_factor, const float mix_limit, @@ -425,7 +425,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, MEM_freeN(cos); } - if (loopnors) { + if (loop_normals) { mix_normals(mix_factor, dvert, defgrp_index, @@ -434,7 +434,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, mix_mode, verts_num, mloop, - loopnors, + loop_normals, nos, loops_num); } @@ -454,7 +454,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, nos, loops_num, mpoly, - polynors, + poly_normals, polys_num, clnors); @@ -535,7 +535,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, int defgrp_index; const MDeformVert *dvert; - float(*loopnors)[3] = nullptr; + float(*loop_normals)[3] = nullptr; CustomData *ldata = &result->ldata; @@ -546,8 +546,8 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, if (use_current_clnors) { clnors = static_cast( CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, loops_num)); - loopnors = static_cast( - MEM_malloc_arrayN(size_t(loops_num), sizeof(*loopnors), __func__)); + loop_normals = static_cast( + MEM_malloc_arrayN(size_t(loops_num), sizeof(*loop_normals), __func__)); BKE_mesh_normals_loop_split(verts, vert_normals, @@ -555,7 +555,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, edges, edges_num, loops, - loopnors, + loop_normals, loops_num, polys, poly_normals, @@ -580,7 +580,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, ob, result, clnors, - loopnors, + loop_normals, poly_normals, enmd->mix_mode, enmd->mix_factor, @@ -603,7 +603,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, ob, result, clnors, - loopnors, + loop_normals, poly_normals, enmd->mix_mode, enmd->mix_factor, @@ -621,7 +621,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, polys_num); } - MEM_SAFE_FREE(loopnors); + MEM_SAFE_FREE(loop_normals); result->runtime->is_original_bmesh = false; diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.cc b/source/blender/modifiers/intern/MOD_weighted_normal.cc index 9d2460be2be..76d8d27b899 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.cc +++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc @@ -83,7 +83,7 @@ struct WeightedNormalData { float split_angle; const MPoly *mpoly; - const float (*polynors)[3]; + const float (*poly_normals)[3]; const int *poly_strength; const MDeformVert *dvert; @@ -131,7 +131,7 @@ static void aggregate_item_normal(WeightedNormalModifierData *wnmd, const float curr_val, const bool use_face_influence) { - const float(*polynors)[3] = wn_data->polynors; + const float(*poly_normals)[3] = wn_data->poly_normals; const MDeformVert *dvert = wn_data->dvert; const int defgrp_index = wn_data->defgrp_index; @@ -175,7 +175,7 @@ static void aggregate_item_normal(WeightedNormalModifierData *wnmd, cached_inverse_powers_of_weight[loops_num] : 1.0f / powf(weight, loops_num); - madd_v3_v3fl(item_data->normal, polynors[mp_index], curr_val * inverted_n_weight); + madd_v3_v3fl(item_data->normal, poly_normals[mp_index], curr_val * inverted_n_weight); } static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, @@ -195,7 +195,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, const Span loop_to_poly = wn_data->loop_to_poly; const MPoly *mpoly = wn_data->mpoly; - const float(*polynors)[3] = wn_data->polynors; + const float(*poly_normals)[3] = wn_data->poly_normals; const int *poly_strength = wn_data->poly_strength; const MDeformVert *dvert = wn_data->dvert; @@ -232,7 +232,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, loop_normals, loops_num, mpoly, - polynors, + poly_normals, polys_num, true, split_angle, @@ -364,7 +364,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, loop_normals, loops_num, mpoly, - polynors, + poly_normals, polys_num, clnors); } @@ -395,7 +395,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, mloop, loops_num, mpoly, - polynors, + poly_normals, polys_num, clnors); @@ -414,7 +414,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, loop_normals, loops_num, mpoly, - polynors, + poly_normals, polys_num, true, split_angle, @@ -438,7 +438,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, loop_normals, loops_num, mpoly, - polynors, + poly_normals, polys_num, clnors); } @@ -641,7 +641,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * wn_data.split_angle = split_angle; wn_data.mpoly = mpoly; - wn_data.polynors = BKE_mesh_poly_normals_ensure(mesh); + wn_data.poly_normals = BKE_mesh_poly_normals_ensure(mesh); wn_data.poly_strength = static_cast(CustomData_get_layer_named( &result->pdata, CD_PROP_INT32, MOD_WEIGHTEDNORMALS_FACEWEIGHT_CDLAYER_ID)); From 6797de4e10622a9c30b5e5c72c94e520b6b6c656 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 17 Dec 2022 13:14:01 +1100 Subject: [PATCH 0186/1522] Cleanup: spelling in comments --- intern/cycles/hydra/field.cpp | 3 +-- intern/cycles/kernel/integrator/init_from_bake.h | 2 +- intern/ghost/intern/GHOST_SystemWin32.cpp | 4 ++-- source/blender/blenkernel/intern/key.cc | 8 ++++---- .../draw/engines/basic/shaders/infos/basic_depth_info.hh | 2 +- .../eevee/shaders/infos/engine_eevee_legacy_shared.h | 2 +- source/blender/editors/asset/intern/asset_indexer.cc | 3 ++- source/blender/editors/include/ED_mesh.h | 4 ++-- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/intern/cycles/hydra/field.cpp b/intern/cycles/hydra/field.cpp index 7cdb4c80d79..e72d86c216c 100644 --- a/intern/cycles/hydra/field.cpp +++ b/intern/cycles/hydra/field.cpp @@ -26,8 +26,7 @@ class HdCyclesVolumeLoader : public VDBImageLoader { HdCyclesVolumeLoader(const std::string &filePath, const std::string &gridName) : VDBImageLoader(gridName) { - /* Disably delay loading and file copying, this has poor performance - * on network drivers. */ + /* Disable delay loading and file copying, this has poor performance on network drivers. */ const bool delay_load = false; openvdb::io::File file(filePath); file.setCopyMaxBytes(0); diff --git a/intern/cycles/kernel/integrator/init_from_bake.h b/intern/cycles/kernel/integrator/init_from_bake.h index 2a5bda50fb3..308f708380f 100644 --- a/intern/cycles/kernel/integrator/init_from_bake.h +++ b/intern/cycles/kernel/integrator/init_from_bake.h @@ -18,7 +18,7 @@ CCL_NAMESPACE_BEGIN /* In order to perform anti-aliasing during baking, we jitter the input barycentric coordinates * (which are for the center of the texel) within the texel. - * However, the baking code corrently doesn't support going to neighboring triangle, so if the + * However, the baking code currently doesn't support going to neighboring triangle, so if the * jittered location falls outside of the input triangle, we need to bring it back in somehow. * Clamping is a bad choice here since it can produce noticeable artifacts at triangle edges, * but properly uniformly sampling the intersection of triangle and texel would be very diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 8cb007a756a..d1e0d138918 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -1063,7 +1063,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind if (window->getCursorGrabModeIsWarp()) { static uint64_t last_warp_time = 0; { - /* WORKAROUND: Check the mouse event timestamp so we can ignore mousemove events that were + /* WORKAROUND: Check the mouse event timestamp so we can ignore mouse-move events that were * already in the queue before we changed the cursor position. */ MOUSEMOVEPOINT mp = {x_screen, y_screen}; ::GetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &mp, &mp, 1, GMMP_USE_DISPLAY_POINTS); @@ -1117,7 +1117,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind window->getCursorGrabAccum(x_accum, y_accum); if (x_new != x_screen || y_new != y_screen) { - /* WORKAROUND: Store the current time so that we ignore outdated mousemove events. */ + /* WORKAROUND: Store the current time so that we ignore outdated mouse-move events. */ last_warp_time = ::GetTickCount64(); /* For more control over which timestamp to store in the event, we use `SendInput` instead of diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index c283ea828e8..26cec31e177 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -890,8 +890,8 @@ static void key_evaluate_relative(const int start, end = tot; } - /* in case of beztriple */ - elemstr[0] = 1; /* nr of ipofloats */ + /* In case of Bezier-triple. */ + elemstr[0] = 1; /* Number of IPO-floats. */ elemstr[1] = IPO_BEZTRIPLE; elemstr[2] = 0; @@ -1132,8 +1132,8 @@ static void do_key(const int start, } } - /* in case of beztriple */ - elemstr[0] = 1; /* nr of ipofloats */ + /* In case of bezier-triples. */ + elemstr[0] = 1; /* Number of IPO-floats. */ elemstr[1] = IPO_BEZTRIPLE; elemstr[2] = 0; diff --git a/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh b/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh index 64988274e03..a14d2cc71e8 100644 --- a/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh +++ b/source/blender/draw/engines/basic/shaders/infos/basic_depth_info.hh @@ -31,7 +31,7 @@ GPU_SHADER_CREATE_INFO(basic_curves) .vertex_source("basic_depth_curves_vert.glsl") .additional_info("draw_hair"); -/* Geometry-shader alterantive paths. */ +/* Geometry-shader alternative paths. */ GPU_SHADER_CREATE_INFO(basic_mesh_conservative_no_geom) .vertex_in(0, Type::VEC3, "pos") .vertex_source("basic_depth_vert_conservative_no_geom.glsl") diff --git a/source/blender/draw/engines/eevee/shaders/infos/engine_eevee_legacy_shared.h b/source/blender/draw/engines/eevee/shaders/infos/engine_eevee_legacy_shared.h index 291094bb997..f49c750fbc0 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/engine_eevee_legacy_shared.h +++ b/source/blender/draw/engines/eevee/shaders/infos/engine_eevee_legacy_shared.h @@ -9,7 +9,7 @@ typedef struct CommonUniformBlock CommonUniformBlock; #endif #ifdef GPU_SHADER -/* Catch for non-create info cass. */ +/* Catch for non-create info case. */ # ifndef BLI_STATIC_ASSERT_ALIGN # define BLI_STATIC_ASSERT_ALIGN(type, alignment) # endif diff --git a/source/blender/editors/asset/intern/asset_indexer.cc b/source/blender/editors/asset/intern/asset_indexer.cc index 247db565f36..7db23161926 100644 --- a/source/blender/editors/asset/intern/asset_indexer.cc +++ b/source/blender/editors/asset/intern/asset_indexer.cc @@ -324,7 +324,8 @@ static void init_value_from_file_indexer_entries(DictionaryValue &result, for (LinkNode *ln = indexer_entries.entries; ln; ln = ln->next) { const FileIndexerEntry *indexer_entry = static_cast(ln->link); - /* We also get non asset types (brushes, workspaces), when browsing using the asset browser. */ + /* We also get non asset types (brushes, work-spaces), when browsing using the asset browser. + */ if (indexer_entry->datablock_info.asset_data == nullptr) { continue; } diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index b2864f2a6cc..59f348f6d8a 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -582,8 +582,8 @@ void ED_mesh_report_mirror_ex(struct wmOperator *op, int totmirr, int totfail, c struct Mesh *ED_mesh_context(struct bContext *C); /** - * Split all edges that would appear sharp based onface and edge sharpness tags and the auto smooth - * angle. + * Split all edges that would appear sharp based on face and edge sharpness tags and the + * auto smooth angle. */ void ED_mesh_split_faces(struct Mesh *mesh); From 2ac6e26c258faec43e60ccfbe3fa1f904f2c6a89 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 17 Dec 2022 13:30:07 +1100 Subject: [PATCH 0187/1522] Cleanup: cmake formatting --- CMakeLists.txt | 6 ++-- .../build_environment/cmake/cve_check.cmake | 2 +- .../build_environment/cmake/download.cmake | 16 +++++----- .../build_environment/cmake/embree.cmake | 29 ++++++++++--------- build_files/build_environment/cmake/gmp.cmake | 12 ++++---- .../build_environment/cmake/opencollada.cmake | 4 +-- build_files/build_environment/cmake/usd.cmake | 5 ++-- .../buildbot/config/blender_linux.cmake | 2 +- build_files/cmake/Modules/FindOpenEXR.cmake | 2 +- build_files/cmake/have_features.cmake | 2 +- build_files/cmake/macros.cmake | 16 +++++----- .../platform/platform_old_libs_update.cmake | 2 +- .../cmake/platform/platform_unix.cmake | 2 +- .../cmake/platform/platform_win32.cmake | 10 +++---- intern/cycles/CMakeLists.txt | 2 +- intern/cycles/cmake/macros.cmake | 4 +-- intern/cycles/device/CMakeLists.txt | 2 +- intern/cycles/doc/license/CMakeLists.txt | 2 +- intern/cycles/kernel/CMakeLists.txt | 20 ++++++------- .../cycles/kernel/osl/shaders/CMakeLists.txt | 2 +- intern/ghost/CMakeLists.txt | 2 +- intern/locale/CMakeLists.txt | 2 +- source/blender/makesrna/intern/CMakeLists.txt | 2 +- source/creator/CMakeLists.txt | 2 +- 24 files changed, 76 insertions(+), 74 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c9e0de18913..62e03a003b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -576,8 +576,8 @@ endif() # OpenGL -option(WITH_OPENGL "When off limits visibility of the opengl headers to just bf_gpu and gawain (temporary option for development purposes)" ON) -option(WITH_GPU_BUILDTIME_SHADER_BUILDER "Shader builder is a developer option enabling linting on GLSL during compilation" OFF) +option(WITH_OPENGL "When off limits visibility of the opengl headers to just bf_gpu and gawain (temporary option for development purposes)" ON) +option(WITH_GPU_BUILDTIME_SHADER_BUILDER "Shader builder is a developer option enabling linting on GLSL during compilation" OFF) mark_as_advanced( WITH_OPENGL @@ -2011,7 +2011,7 @@ set(LIBDIR_STALE) if(UNIX AND NOT APPLE) # Only search for the path if it's found on the system. - if (EXISTS "../lib/linux_centos7_x86_64") + if(EXISTS "../lib/linux_centos7_x86_64") set(LIBDIR_STALE "/lib/linux_centos7_x86_64/") endif() endif() diff --git a/build_files/build_environment/cmake/cve_check.cmake b/build_files/build_environment/cmake/cve_check.cmake index 941b6b0cae9..979b5d2a794 100644 --- a/build_files/build_environment/cmake/cve_check.cmake +++ b/build_files/build_environment/cmake/cve_check.cmake @@ -24,7 +24,7 @@ set(SBOMCONTENTS) get_cmake_property(_variableNames VARIABLES) -foreach (_variableName ${_variableNames}) +foreach(_variableName ${_variableNames}) if(_variableName MATCHES "CPE$") string(REPLACE ":" ";" CPE_LIST ${${_variableName}}) string(REPLACE "_CPE" "_ID" CPE_DEPNAME ${_variableName}) diff --git a/build_files/build_environment/cmake/download.cmake b/build_files/build_environment/cmake/download.cmake index 4f8ecc7d0ce..dab4417109a 100644 --- a/build_files/build_environment/cmake/download.cmake +++ b/build_files/build_environment/cmake/download.cmake @@ -10,22 +10,22 @@ function(download_source dep) if(PACKAGE_USE_UPSTREAM_SOURCES) set(TARGET_URI ${${dep}_URI}) elseif(BLENDER_VERSION) - set(TARGET_URI https://svn.blender.org/svnroot/bf-blender/tags/blender-${BLENDER_VERSION}-release/lib/packages/${TARGET_FILE}) + set(TARGET_URI https://svn.blender.org/svnroot/bf-blender/tags/blender-${BLENDER_VERSION}-release/lib/packages/${TARGET_FILE}) else() - set(TARGET_URI https://svn.blender.org/svnroot/bf-blender/trunk/lib/packages/${TARGET_FILE}) + set(TARGET_URI https://svn.blender.org/svnroot/bf-blender/trunk/lib/packages/${TARGET_FILE}) endif() # Validate all required variables are set and give an explicit error message # rather than CMake erroring out later on with a more ambigious error. - if (NOT DEFINED TARGET_FILE) + if(NOT DEFINED TARGET_FILE) message(FATAL_ERROR "${dep}_FILE variable not set") endif() - if (NOT DEFINED TARGET_HASH) + if(NOT DEFINED TARGET_HASH) message(FATAL_ERROR "${dep}_HASH variable not set") endif() - if (NOT DEFINED TARGET_HASH_TYPE) + if(NOT DEFINED TARGET_HASH_TYPE) message(FATAL_ERROR "${dep}_HASH_TYPE variable not set") endif() - if (NOT DEFINED TARGET_URI) + if(NOT DEFINED TARGET_URI) message(FATAL_ERROR "${dep}_URI variable not set") endif() set(TARGET_FILE ${PACKAGE_DIR}/${TARGET_FILE}) @@ -43,11 +43,11 @@ function(download_source dep) if(EXISTS ${TARGET_FILE}) # Sometimes the download fails, but that is not a # fail condition for "file(DOWNLOAD" it will warn about - # a crc mismatch and just carry on, we need to explicitly + # a CRC mismatch and just carry on, we need to explicitly # catch this and remove the bogus 0 byte file so we can # retry without having to go find the file and manually # delete it. - file (SIZE ${TARGET_FILE} TARGET_SIZE) + file(SIZE ${TARGET_FILE} TARGET_SIZE) if(${TARGET_SIZE} EQUAL 0) file(REMOVE ${TARGET_FILE}) message(FATAL_ERROR "for ${TARGET_FILE} file size 0, download likely failed, deleted...") diff --git a/build_files/build_environment/cmake/embree.cmake b/build_files/build_environment/cmake/embree.cmake index 8c689cf000b..f57f710d0e6 100644 --- a/build_files/build_environment/cmake/embree.cmake +++ b/build_files/build_environment/cmake/embree.cmake @@ -15,10 +15,11 @@ set(EMBREE_EXTRA_ARGS -DTBB_ROOT=${LIBDIR}/tbb ) -if (NOT BLENDER_PLATFORM_ARM) +if(NOT BLENDER_PLATFORM_ARM) set(EMBREE_EXTRA_ARGS ${EMBREE_EXTRA_ARGS} - -DEMBREE_MAX_ISA=AVX2) + -DEMBREE_MAX_ISA=AVX2 + ) endif() if(TBB_STATIC_LIBRARY) @@ -52,17 +53,17 @@ if(WIN32) ) else() ExternalProject_Add_Step(external_embree after_install - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/embree3.lib ${HARVEST_TARGET}/embree/lib/embree3_d.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/embree_avx.lib ${HARVEST_TARGET}/embree/lib/embree_avx_d.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/embree_avx2.lib ${HARVEST_TARGET}/embree/lib/embree_avx2_d.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/embree_sse42.lib ${HARVEST_TARGET}/embree/lib/embree_sse42_d.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/lexers.lib ${HARVEST_TARGET}/embree/lib/lexers_d.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/math.lib ${HARVEST_TARGET}/embree/lib/math_d.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/simd.lib ${HARVEST_TARGET}/embree/lib/simd_d.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/sys.lib ${HARVEST_TARGET}/embree/lib/sys_d.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/tasking.lib ${HARVEST_TARGET}/embree/lib/tasking_d.lib - DEPENDEES install - ) - endif() + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/embree3.lib ${HARVEST_TARGET}/embree/lib/embree3_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/embree_avx.lib ${HARVEST_TARGET}/embree/lib/embree_avx_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/embree_avx2.lib ${HARVEST_TARGET}/embree/lib/embree_avx2_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/embree_sse42.lib ${HARVEST_TARGET}/embree/lib/embree_sse42_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/lexers.lib ${HARVEST_TARGET}/embree/lib/lexers_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/math.lib ${HARVEST_TARGET}/embree/lib/math_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/simd.lib ${HARVEST_TARGET}/embree/lib/simd_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/sys.lib ${HARVEST_TARGET}/embree/lib/sys_d.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/embree/lib/tasking.lib ${HARVEST_TARGET}/embree/lib/tasking_d.lib + DEPENDEES install + ) +endif() endif() diff --git a/build_files/build_environment/cmake/gmp.cmake b/build_files/build_environment/cmake/gmp.cmake index df4d20fb934..820da4bdf7d 100644 --- a/build_files/build_environment/cmake/gmp.cmake +++ b/build_files/build_environment/cmake/gmp.cmake @@ -40,10 +40,10 @@ endif() if(BUILD_MODE STREQUAL Release AND WIN32) ExternalProject_Add_Step(external_gmp after_install - COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def - COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib - COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/gmp/bin/libgmp-10.dll ${HARVEST_TARGET}/gmp/lib/libgmp-10.dll - COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib ${HARVEST_TARGET}/gmp/lib/libgmp-10.lib + COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def + COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib + COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/gmp/bin/libgmp-10.dll ${HARVEST_TARGET}/gmp/lib/libgmp-10.dll + COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib ${HARVEST_TARGET}/gmp/lib/libgmp-10.lib COMMAND ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/gmp/include ${HARVEST_TARGET}/gmp/include DEPENDEES install @@ -52,8 +52,8 @@ endif() if(BUILD_MODE STREQUAL Debug AND WIN32) ExternalProject_Add_Step(external_gmp after_install - COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def - COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib + COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-3.dll.def ${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def + COMMAND lib /def:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.def /machine:x64 /out:${BUILD_DIR}/gmp/src/external_gmp/.libs/libgmp-10.lib DEPENDEES install ) diff --git a/build_files/build_environment/cmake/opencollada.cmake b/build_files/build_environment/cmake/opencollada.cmake index 9e403f25181..0042a961525 100644 --- a/build_files/build_environment/cmake/opencollada.cmake +++ b/build_files/build_environment/cmake/opencollada.cmake @@ -26,9 +26,9 @@ else() -DLIBXML2_INCLUDE_DIR=${LIBDIR}/xml2/include/libxml2 ) if(BUILD_MODE STREQUAL Release) - list(APPEND OPENCOLLADA_EXTRA_ARGS -DLIBXML2_LIBRARIES=${LIBDIR}/xml2/lib/libxml2s.lib) + list(APPEND OPENCOLLADA_EXTRA_ARGS -DLIBXML2_LIBRARIES=${LIBDIR}/xml2/lib/libxml2s.lib) else() - list(APPEND OPENCOLLADA_EXTRA_ARGS -DLIBXML2_LIBRARIES=${LIBDIR}/xml2/lib/libxml2sd.lib) + list(APPEND OPENCOLLADA_EXTRA_ARGS -DLIBXML2_LIBRARIES=${LIBDIR}/xml2/lib/libxml2sd.lib) endif() set(PATCH_MAYBE_DOS2UNIX_CMD) endif() diff --git a/build_files/build_environment/cmake/usd.cmake b/build_files/build_environment/cmake/usd.cmake index 439d098a847..98c7931808f 100644 --- a/build_files/build_environment/cmake/usd.cmake +++ b/build_files/build_environment/cmake/usd.cmake @@ -34,7 +34,8 @@ elseif(UNIX) if(APPLE) set(USD_SHARED_LINKER_FLAGS "-Xlinker -undefined -Xlinker dynamic_lookup") list(APPEND USD_PLATFORM_FLAGS - -DCMAKE_SHARED_LINKER_FLAGS=${USD_SHARED_LINKER_FLAGS}) + -DCMAKE_SHARED_LINKER_FLAGS=${USD_SHARED_LINKER_FLAGS} + ) endif() endif() @@ -112,7 +113,7 @@ add_dependencies( # Since USD 21.11 the libraries are prefixed with "usd_", i.e. "libusd_m.a" became "libusd_usd_m.a". # See https://github.com/PixarAnimationStudios/USD/blob/release/CHANGELOG.md#2111---2021-11-01 if(NOT WIN32) - if (USD_VERSION VERSION_LESS 21.11) + if(USD_VERSION VERSION_LESS 21.11) set(PXR_LIB_PREFIX "") else() set(PXR_LIB_PREFIX "usd_") diff --git a/build_files/buildbot/config/blender_linux.cmake b/build_files/buildbot/config/blender_linux.cmake index ae7849002f7..18a1de51b2d 100644 --- a/build_files/buildbot/config/blender_linux.cmake +++ b/build_files/buildbot/config/blender_linux.cmake @@ -27,4 +27,4 @@ set(LIBDIR "${CMAKE_CURRENT_LIST_DIR}/../../../../lib/${LIBDIR_NAME}" CACHE STRI # Platform specific configuration, to ensure static linking against everything. # Additional linking libraries -set(CMAKE_EXE_LINKER_FLAGS "-lrt -no-pie" CACHE STRING "" FORCE) +set(CMAKE_EXE_LINKER_FLAGS "-lrt -no-pie" CACHE STRING "" FORCE) diff --git a/build_files/cmake/Modules/FindOpenEXR.cmake b/build_files/cmake/Modules/FindOpenEXR.cmake index 1cc3e50ba92..bbc1e11539f 100644 --- a/build_files/cmake/Modules/FindOpenEXR.cmake +++ b/build_files/cmake/Modules/FindOpenEXR.cmake @@ -172,7 +172,7 @@ ENDIF() # handle the QUIETLY and REQUIRED arguments and set OPENEXR_FOUND to TRUE if # all listed variables are TRUE INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenEXR DEFAULT_MSG +FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenEXR DEFAULT_MSG _openexr_LIBRARIES OPENEXR_INCLUDE_DIR) IF(OPENEXR_FOUND) diff --git a/build_files/cmake/have_features.cmake b/build_files/cmake/have_features.cmake index dc3b61849ea..3b2fdad30b9 100644 --- a/build_files/cmake/have_features.cmake +++ b/build_files/cmake/have_features.cmake @@ -22,7 +22,7 @@ endif() # Used for: `source/blender/blenlib/intern/system.c`. # `execinfo` is not available on non-GLIBC systems (at least not on MUSL-LIBC), -# so check the presence of the header before including it and using the it for back-trace. +# so check the presence of the header before including it and using the it for back-trace. set(HAVE_EXECINFO_H OFF) if(NOT MSVC) include(CheckIncludeFiles) diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 178a63fba7c..b632cb9c551 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -326,8 +326,8 @@ function(blender_add_lib__impl # NOTE: If separated libraries for debug and release are needed every library is the list are # to be prefixed explicitly. # - # Use: "optimized libfoo optimized libbar debug libfoo_d debug libbar_d" - # NOT: "optimized libfoo libbar debug libfoo_d libbar_d" + # Use: "optimized libfoo optimized libbar debug libfoo_d debug libbar_d" + # NOT: "optimized libfoo libbar debug libfoo_d libbar_d" if(NOT "${library_deps}" STREQUAL "") set(next_library_mode "") foreach(library ${library_deps}) @@ -535,7 +535,7 @@ function(setup_platform_linker_flags set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " ${PLATFORM_LINKFLAGS_DEBUG}") get_target_property(target_type ${target} TYPE) - if (target_type STREQUAL "EXECUTABLE") + if(target_type STREQUAL "EXECUTABLE") set_property(TARGET ${target} APPEND_STRING PROPERTY LINK_FLAGS " ${PLATFORM_LINKFLAGS_EXECUTABLE}") endif() endfunction() @@ -1219,7 +1219,7 @@ function(print_cached_vars_containing_value set(_found) get_cmake_property(_vars VARIABLES) foreach(_var ${_vars}) - if (DEFINED CACHE{${_var}}) + if(DEFINED CACHE{${_var}}) # Skip "_" prefixed variables, these are used for internal book-keeping, # not under user control. string(FIND "${_var}" "_" _found) @@ -1256,10 +1256,10 @@ macro(openmp_delayload else() set(OPENMP_DLL_NAME "vcomp140") endif() - set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib") - set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " /DELAYLOAD:${OPENMP_DLL_NAME}d.dll delayimp.lib") - set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib") - set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib") + set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_RELEASE " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib") + set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG " /DELAYLOAD:${OPENMP_DLL_NAME}d.dll delayimp.lib") + set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_RELWITHDEBINFO " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib") + set_property(TARGET ${projectname} APPEND_STRING PROPERTY LINK_FLAGS_MINSIZEREL " /DELAYLOAD:${OPENMP_DLL_NAME}.dll delayimp.lib") endif() endif() endmacro() diff --git a/build_files/cmake/platform/platform_old_libs_update.cmake b/build_files/cmake/platform/platform_old_libs_update.cmake index 14f64ff0607..c51029ab570 100644 --- a/build_files/cmake/platform/platform_old_libs_update.cmake +++ b/build_files/cmake/platform/platform_old_libs_update.cmake @@ -5,7 +5,7 @@ function(unset_cache_variables pattern) get_cmake_property(_cache_variables CACHE_VARIABLES) - foreach (_cache_variable ${_cache_variables}) + foreach(_cache_variable ${_cache_variables}) if("${_cache_variable}" MATCHES "${pattern}") unset(${_cache_variable} CACHE) endif() diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index cf9226433a3..bdf39d04d32 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -789,7 +789,7 @@ if(WITH_GHOST_X11) endif() if(WITH_X11_ALPHA) - find_library(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH}) + find_library(X11_Xrender_LIB Xrender ${X11_LIB_SEARCH_PATH}) mark_as_advanced(X11_Xrender_LIB) if(NOT X11_Xrender_LIB) message(FATAL_ERROR "libXrender not found. Disable WITH_X11_ALPHA if you diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index f58b9bd4676..da418a27274 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -302,7 +302,7 @@ endif() file(GLOB children RELATIVE ${LIBDIR} ${LIBDIR}/*) foreach(child ${children}) if(IS_DIRECTORY ${LIBDIR}/${child}) - list(APPEND CMAKE_PREFIX_PATH ${LIBDIR}/${child}) + list(APPEND CMAKE_PREFIX_PATH ${LIBDIR}/${child}) endif() endforeach() @@ -555,7 +555,7 @@ if(WITH_BOOST) set(BOOST_PREFIX "") # This is file new in 3.4 if it does not exist, assume we are building against 3.3 libs set(BOOST_34_TRIGGER_FILE ${BOOST_LIBPATH}/${BOOST_PREFIX}boost_python310-${BOOST_DEBUG_POSTFIX}.lib) - if (NOT EXISTS ${BOOST_34_TRIGGER_FILE}) + if(NOT EXISTS ${BOOST_34_TRIGGER_FILE}) set(BOOST_DEBUG_POSTFIX "vc142-mt-gd-x64-${BOOST_VERSION}") set(BOOST_PREFIX "lib") endif() @@ -573,7 +573,7 @@ if(WITH_BOOST) debug ${BOOST_LIBPATH}/${BOOST_PREFIX}boost_thread-${BOOST_DEBUG_POSTFIX}.lib debug ${BOOST_LIBPATH}/${BOOST_PREFIX}boost_chrono-${BOOST_DEBUG_POSTFIX}.lib ) - if (EXISTS ${BOOST_34_TRIGGER_FILE}) + if(EXISTS ${BOOST_34_TRIGGER_FILE}) if(WITH_USD) set(BOOST_PYTHON_LIBRARIES debug ${BOOST_LIBPATH}/${BOOST_PREFIX}boost_python310-${BOOST_DEBUG_POSTFIX}.lib @@ -624,7 +624,7 @@ endif() if(WITH_LLVM) set(LLVM_ROOT_DIR ${LIBDIR}/llvm CACHE PATH "Path to the LLVM installation") - set(LLVM_INCLUDE_DIRS ${LLVM_ROOT_DIR}/$<$:Debug>/include CACHE PATH "Path to the LLVM include directory") + set(LLVM_INCLUDE_DIRS ${LLVM_ROOT_DIR}/$<$:Debug>/include CACHE PATH "Path to the LLVM include directory") file(GLOB LLVM_LIBRARY_OPTIMIZED ${LLVM_ROOT_DIR}/lib/*.lib) if(EXISTS ${LLVM_ROOT_DIR}/debug/lib) @@ -1030,7 +1030,7 @@ if(WITH_CYCLES AND WITH_CYCLES_DEVICE_ONEAPI) ${SYCL_ROOT_DIR}/bin/pi_*.dll ) list(REMOVE_ITEM _sycl_pi_runtime_libraries_glob "${SYCL_ROOT_DIR}/bin/pi_opencl.dll") - list (APPEND _sycl_runtime_libraries ${_sycl_pi_runtime_libraries_glob}) + list(APPEND _sycl_runtime_libraries ${_sycl_pi_runtime_libraries_glob}) unset(_sycl_pi_runtime_libraries_glob) list(APPEND PLATFORM_BUNDLED_LIBRARIES ${_sycl_runtime_libraries}) diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index 22942e1fc46..53e87fc5c3a 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -298,7 +298,7 @@ if(WITH_CYCLES_DEVICE_METAL) add_definitions(-DWITH_METAL) endif() -if (WITH_CYCLES_DEVICE_ONEAPI) +if(WITH_CYCLES_DEVICE_ONEAPI) add_definitions(-DWITH_ONEAPI) endif() diff --git a/intern/cycles/cmake/macros.cmake b/intern/cycles/cmake/macros.cmake index cd6feee4a3c..d1a929f2b35 100644 --- a/intern/cycles/cmake/macros.cmake +++ b/intern/cycles/cmake/macros.cmake @@ -45,8 +45,8 @@ macro(cycles_add_library target library_deps) # NOTE: If separated libraries for debug and release ar eneeded every library is the list are # to be prefixed explicitly. # - # Use: "optimized libfoo optimized libbar debug libfoo_d debug libbar_d" - # NOT: "optimized libfoo libbar debug libfoo_d libbar_d" + # Use: "optimized libfoo optimized libbar debug libfoo_d debug libbar_d" + # NOT: "optimized libfoo libbar debug libfoo_d libbar_d" # # TODO(sergey): This is the same as Blender's side CMake. Find a way to avoid duplication # somehow in a way which allows to have Cycles standalone. diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt index 6808d8c04d7..c7e95d44d9b 100644 --- a/intern/cycles/device/CMakeLists.txt +++ b/intern/cycles/device/CMakeLists.txt @@ -162,7 +162,7 @@ if(WITH_CYCLES_DEVICE_METAL) ) endif() -if (WITH_CYCLES_DEVICE_ONEAPI) +if(WITH_CYCLES_DEVICE_ONEAPI) if(WITH_CYCLES_ONEAPI_BINARIES) set(cycles_kernel_oneapi_lib_suffix "_aot") else() diff --git a/intern/cycles/doc/license/CMakeLists.txt b/intern/cycles/doc/license/CMakeLists.txt index df49095166c..0b050b95439 100644 --- a/intern/cycles/doc/license/CMakeLists.txt +++ b/intern/cycles/doc/license/CMakeLists.txt @@ -10,4 +10,4 @@ set(LICENSES Zlib-license.txt ) -delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${LICENSES}" ${CYCLES_INSTALL_PATH}/license) +delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${LICENSES}" ${CYCLES_INSTALL_PATH}/license) diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index dd0de5120fd..a7a6c0a6007 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -728,8 +728,8 @@ if(WITH_CYCLES_DEVICE_ONEAPI) ${SRC_UTIL_HEADERS} ) - set (SYCL_OFFLINE_COMPILER_PARALLEL_JOBS 1 CACHE STRING "Number of parallel compiler instances to use for device binaries compilation (expect ~8GB peak memory usage per instance).") - if (WITH_CYCLES_ONEAPI_BINARIES) + set(SYCL_OFFLINE_COMPILER_PARALLEL_JOBS 1 CACHE STRING "Number of parallel compiler instances to use for device binaries compilation (expect ~8GB peak memory usage per instance).") + if(WITH_CYCLES_ONEAPI_BINARIES) message(STATUS "${SYCL_OFFLINE_COMPILER_PARALLEL_JOBS} instance(s) of oneAPI offline compiler will be used.") endif() # SYCL_CPP_FLAGS is a variable that the user can set to pass extra compiler options @@ -753,25 +753,25 @@ if(WITH_CYCLES_DEVICE_ONEAPI) ) # Set defaults for spir64 and spir64_gen options - if (NOT DEFINED CYCLES_ONEAPI_SYCL_OPTIONS_spir64) + if(NOT DEFINED CYCLES_ONEAPI_SYCL_OPTIONS_spir64) set(CYCLES_ONEAPI_SYCL_OPTIONS_spir64 "-options '-ze-opt-large-register-file -ze-opt-regular-grf-kernel integrator_intersect'") endif() - if (NOT DEFINED CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen) - SET (CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "${CYCLES_ONEAPI_SYCL_OPTIONS_spir64}" CACHE STRING "Extra build options for spir64_gen target") + if(NOT DEFINED CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen) + set(CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "${CYCLES_ONEAPI_SYCL_OPTIONS_spir64}" CACHE STRING "Extra build options for spir64_gen target") endif() # Enable zebin, a graphics binary format with improved compatibility. string(PREPEND CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "--format zebin ") string(PREPEND CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "-device ${CYCLES_ONEAPI_SPIR64_GEN_DEVICES} ") - if (WITH_CYCLES_ONEAPI_BINARIES) + if(WITH_CYCLES_ONEAPI_BINARIES) # AoT binaries aren't currently reused when calling sycl::build. - list (APPEND sycl_compiler_flags -DSYCL_SKIP_KERNELS_PRELOAD) + list(APPEND sycl_compiler_flags -DSYCL_SKIP_KERNELS_PRELOAD) # Iterate over all targest and their options - list (JOIN CYCLES_ONEAPI_SYCL_TARGETS "," targets_string) - list (APPEND sycl_compiler_flags -fsycl-targets=${targets_string}) + list(JOIN CYCLES_ONEAPI_SYCL_TARGETS "," targets_string) + list(APPEND sycl_compiler_flags -fsycl-targets=${targets_string}) foreach(target ${CYCLES_ONEAPI_SYCL_TARGETS}) if(DEFINED CYCLES_ONEAPI_SYCL_OPTIONS_${target}) - list (APPEND sycl_compiler_flags -Xsycl-target-backend=${target} "${CYCLES_ONEAPI_SYCL_OPTIONS_${target}}") + list(APPEND sycl_compiler_flags -Xsycl-target-backend=${target} "${CYCLES_ONEAPI_SYCL_OPTIONS_${target}}") endif() endforeach() else() diff --git a/intern/cycles/kernel/osl/shaders/CMakeLists.txt b/intern/cycles/kernel/osl/shaders/CMakeLists.txt index bfd203416cb..00336ebfb76 100644 --- a/intern/cycles/kernel/osl/shaders/CMakeLists.txt +++ b/intern/cycles/kernel/osl/shaders/CMakeLists.txt @@ -135,7 +135,7 @@ foreach(_file ${SRC_OSL}) string(REPLACE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} _OSO_FILE ${_OSO_FILE}) add_custom_command( OUTPUT ${_OSO_FILE} - COMMAND ${CMAKE_COMMAND} -E env ${PLATFORM_ENV_BUILD} ${OSL_COMPILER} -q -O2 -I"${CMAKE_CURRENT_SOURCE_DIR}" -I"${OSL_SHADER_DIR}" -o ${_OSO_FILE} ${_OSL_FILE} + COMMAND ${CMAKE_COMMAND} -E env ${PLATFORM_ENV_BUILD} ${OSL_COMPILER} -q -O2 -I"${CMAKE_CURRENT_SOURCE_DIR}" -I"${OSL_SHADER_DIR}" -o ${_OSO_FILE} ${_OSL_FILE} DEPENDS ${_OSL_FILE} ${SRC_OSL_HEADERS} ${OSL_COMPILER} ) list(APPEND SRC_OSO diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index 9e0b48465c6..fd706d758a3 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -129,7 +129,7 @@ list(APPEND SRC if(WITH_HEADLESS) add_definitions(-DWITH_HEADLESS) -elseif (WITH_GHOST_SDL) +elseif(WITH_GHOST_SDL) list(APPEND SRC intern/GHOST_ContextSDL.cpp intern/GHOST_DisplayManagerSDL.cpp diff --git a/intern/locale/CMakeLists.txt b/intern/locale/CMakeLists.txt index bdad0a0af79..7ba79504383 100644 --- a/intern/locale/CMakeLists.txt +++ b/intern/locale/CMakeLists.txt @@ -20,7 +20,7 @@ set(LIB if(WIN32) # This is set in platform_win32.cmake, will exist for 3.4+ library # folders which are dynamic, but not for 3.3 which will be static. - if (EXISTS ${BOOST_34_TRIGGER_FILE}) + if(EXISTS ${BOOST_34_TRIGGER_FILE}) add_definitions (-DBOOST_ALL_DYN_LINK=1) endif() endif() diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index f370d47b3f7..20439e69f35 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -412,7 +412,7 @@ endif() # `valgrind --leak-check=full --track-origins=yes` add_custom_command( OUTPUT ${GENSRC} - COMMAND "$" ${CMAKE_CURRENT_BINARY_DIR}/ ${CMAKE_CURRENT_BINARY_DIR}/../ + COMMAND "$" ${CMAKE_CURRENT_BINARY_DIR}/ ${CMAKE_CURRENT_BINARY_DIR}/../ DEPENDS makesrna ) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 47efd9a67b6..3570e9e8b4a 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -385,7 +385,7 @@ endif() # Install Targets (Generic, All Platforms) -# important to make a clean install each time, else old scripts get loaded. +# Important to make a clean install each time, else old scripts get loaded. install( CODE "file(REMOVE_RECURSE ${TARGETDIR_VER})" From 025570c44e4e7c83331266876a7ef1969466ed23 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 17 Dec 2022 13:53:30 +1100 Subject: [PATCH 0188/1522] Build: bump minimum GCC version from 9.3.1 to 11.0.0 Increase the minimum version as part of the VFX platform 2023. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 62e03a003b2..428207f0231 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,7 +117,7 @@ enable_testing() # Keep in sync with: https://wiki.blender.org/wiki/Building_Blender if(CMAKE_COMPILER_IS_GNUCC) - if("${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "9.3.1") + if("${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "11.0.0") message(FATAL_ERROR "The minimum supported version of GCC is 9.3.1") endif() elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") From dc8355cfe2207c4aa47a7e463c176fa38a055726 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 17 Dec 2022 13:56:01 +1100 Subject: [PATCH 0189/1522] Correct GCC version in message Missed last commit. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 428207f0231..a6683ce40b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,7 +118,7 @@ enable_testing() if(CMAKE_COMPILER_IS_GNUCC) if("${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "11.0.0") - message(FATAL_ERROR "The minimum supported version of GCC is 9.3.1") + message(FATAL_ERROR "The minimum supported version of GCC is 11.0.0") endif() elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") if(CMAKE_COMPILER_IS_GNUCC AND ("${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "8.0")) From 68ba311c5cb148ddd55763c788706f945f48b9d1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 17 Dec 2022 13:59:20 +1100 Subject: [PATCH 0190/1522] Cleanup: use SPDX license headers --- .../build_environment/cmake/shaderc.cmake | 21 ++----------------- .../cmake/shaderc_deps.cmake | 19 +---------------- .../build_environment/cmake/vulkan.cmake | 19 +---------------- 3 files changed, 4 insertions(+), 55 deletions(-) diff --git a/build_files/build_environment/cmake/shaderc.cmake b/build_files/build_environment/cmake/shaderc.cmake index 669750913f0..9831f533ab3 100644 --- a/build_files/build_environment/cmake/shaderc.cmake +++ b/build_files/build_environment/cmake/shaderc.cmake @@ -1,20 +1,5 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ***** END GPL LICENSE BLOCK ***** +# SPDX-License-Identifier: GPL-2.0-or-later + set(SHADERC_EXTRA_ARGS -DSHADERC_SKIP_TESTS=On -DSHADERC_SPIRV_TOOLS_DIR=${BUILD_DIR}/shaderc_spirv_tools/src/external_shaderc_spirv_tools @@ -60,5 +45,3 @@ if(WIN32) ) endif() endif() - - diff --git a/build_files/build_environment/cmake/shaderc_deps.cmake b/build_files/build_environment/cmake/shaderc_deps.cmake index bfe14a55f5b..5be13fc696d 100644 --- a/build_files/build_environment/cmake/shaderc_deps.cmake +++ b/build_files/build_environment/cmake/shaderc_deps.cmake @@ -1,20 +1,4 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ***** END GPL LICENSE BLOCK ***** +# SPDX-License-Identifier: GPL-2.0-or-later # These are build time requirements for shaderc. We only have to unpack these # shaderc will build them. @@ -48,4 +32,3 @@ ExternalProject_Add(external_shaderc_spirv_tools BUILD_COMMAND echo . INSTALL_COMMAND echo . ) - diff --git a/build_files/build_environment/cmake/vulkan.cmake b/build_files/build_environment/cmake/vulkan.cmake index 578e02ced3e..6f194fee589 100644 --- a/build_files/build_environment/cmake/vulkan.cmake +++ b/build_files/build_environment/cmake/vulkan.cmake @@ -1,20 +1,4 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ***** END GPL LICENSE BLOCK ***** +# SPDX-License-Identifier: GPL-2.0-or-later set(VULKAN_HEADERS_EXTRA_ARGS) @@ -68,4 +52,3 @@ elseif(WIN32) ) endif() endif() - From 02c8ce449ec0271bb38d47cbeb80caee7349d42d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 17 Dec 2022 14:03:57 +1100 Subject: [PATCH 0191/1522] License headers: add missing license identifiers --- build_files/build_environment/darwin/set_rpath.py | 4 +++- .../blender/draw/engines/eevee/engine_eevee_shared_defines.h | 3 ++- .../engines/eevee/shaders/infos/eevee_legacy_bloom_info.hh | 3 ++- .../engines/eevee/shaders/infos/eevee_legacy_common_info.hh | 1 + .../draw/engines/eevee/shaders/infos/eevee_legacy_dof_info.hh | 4 +++- .../engines/eevee/shaders/infos/eevee_legacy_effects_info.hh | 4 +++- .../eevee/shaders/infos/eevee_legacy_lightprobe_info.hh | 1 + .../engines/eevee/shaders/infos/eevee_legacy_material_info.hh | 2 ++ .../eevee/shaders/infos/eevee_legacy_motion_blur_info.hh | 1 + .../engines/eevee/shaders/infos/eevee_legacy_shadow_info.hh | 1 + .../engines/eevee/shaders/infos/eevee_legacy_volume_info.hh | 2 ++ .../engines/eevee/shaders/infos/engine_eevee_legacy_shared.h | 1 + 12 files changed, 22 insertions(+), 5 deletions(-) diff --git a/build_files/build_environment/darwin/set_rpath.py b/build_files/build_environment/darwin/set_rpath.py index e53497b84fb..fec1abca1fb 100644 --- a/build_files/build_environment/darwin/set_rpath.py +++ b/build_files/build_environment/darwin/set_rpath.py @@ -1,5 +1,7 @@ #!/usr/bin/env python3 -# macOS utility to remove all rpaths and add a new one. +# SPDX-License-Identifier: GPL-2.0-or-later + +# macOS utility to remove all `rpaths` and add a new one. import os import re diff --git a/source/blender/draw/engines/eevee/engine_eevee_shared_defines.h b/source/blender/draw/engines/eevee/engine_eevee_shared_defines.h index 0f7f10914ad..01e246ac4b1 100644 --- a/source/blender/draw/engines/eevee/engine_eevee_shared_defines.h +++ b/source/blender/draw/engines/eevee/engine_eevee_shared_defines.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef GPU_SHADER_EEVEE_LEGACY_DEFINES #define GPU_SHADER_EEVEE_LEGACY_DEFINES @@ -27,4 +28,4 @@ #define DOF_DILATE_RING_COUNT 3 #define DOF_FAST_GATHER_COC_ERROR 0.05 -#endif \ No newline at end of file +#endif diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_bloom_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_bloom_info.hh index 60b8d255cea..b917d27e8fc 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_bloom_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_bloom_info.hh @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "gpu_shader_create_info.hh" @@ -53,4 +54,4 @@ GPU_SHADER_CREATE_INFO(eevee_legacy_bloom_resolve) GPU_SHADER_CREATE_INFO(eevee_legacy_bloom_resolve_hq) .define("HIGH_QUALITY") .additional_info("eevee_legacy_bloom_resolve") - .do_static_compilation(true); \ No newline at end of file + .do_static_compilation(true); diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh index 45ecd339f5f..a9c7687e5cd 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "gpu_shader_create_info.hh" diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_dof_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_dof_info.hh index 4350eb61f76..56bc957dd42 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_dof_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_dof_info.hh @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + #include "gpu_shader_create_info.hh" /* DOF Lib */ @@ -286,4 +288,4 @@ GPU_SHADER_CREATE_INFO(eevee_legacy_depth_of_field_resolve_HQ_BOKEH) GPU_SHADER_CREATE_INFO(eevee_legacy_depth_of_field_resolve_LQ_BOKEH) .additional_info("eevee_legacy_depth_of_field_resolve_LQ") .additional_info("eevee_legacy_depth_of_field_resolve_bokeh") - .do_static_compilation(true); \ No newline at end of file + .do_static_compilation(true); diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_effects_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_effects_info.hh index 51a87ae7b98..1afe84be417 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_effects_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_effects_info.hh @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + #include "gpu_shader_create_info.hh" /* effect_minmaxz_frag permutation inputs. */ @@ -349,4 +351,4 @@ GPU_SHADER_CREATE_INFO(eevee_legacy_cryptomatte_mesh) .additional_info("eevee_legacy_cryptomatte_common") .additional_info("eevee_legacy_material_surface_vert") .auto_resource_location(true) - .do_static_compilation(true); \ No newline at end of file + .do_static_compilation(true); diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_lightprobe_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_lightprobe_info.hh index b8d03ca63c1..71724dc0c39 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_lightprobe_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_lightprobe_info.hh @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "gpu_shader_create_info.hh" diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh index ee06fae6e55..2d1671ac98d 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + #include "eevee_legacy_volume_info.hh" #include "gpu_shader_create_info.hh" diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_motion_blur_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_motion_blur_info.hh index 97f1a6a97ff..93f3216076e 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_motion_blur_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_motion_blur_info.hh @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "gpu_shader_create_info.hh" diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_shadow_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_shadow_info.hh index d936f0caeb9..7199e8ad88f 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_shadow_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_shadow_info.hh @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ #include "gpu_shader_create_info.hh" diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_volume_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_volume_info.hh index e283536e182..411134a5184 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_volume_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_volume_info.hh @@ -1,3 +1,5 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + #include "gpu_shader_create_info.hh" #pragma once diff --git a/source/blender/draw/engines/eevee/shaders/infos/engine_eevee_legacy_shared.h b/source/blender/draw/engines/eevee/shaders/infos/engine_eevee_legacy_shared.h index f49c750fbc0..1170078d9a5 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/engine_eevee_legacy_shared.h +++ b/source/blender/draw/engines/eevee/shaders/infos/engine_eevee_legacy_shared.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ /** \file * \ingroup draw From a0a7db9f704d28673b73e124874d5571adc5eb42 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 17 Dec 2022 14:11:11 +1100 Subject: [PATCH 0192/1522] Cleanup: duplicate words in comments --- source/blender/blenkernel/BKE_mesh_runtime.h | 2 +- source/blender/blenkernel/intern/object_update.cc | 2 +- source/blender/blenlib/BLI_span.hh | 4 ++-- source/blender/depsgraph/DEG_depsgraph_query.h | 2 +- source/blender/depsgraph/intern/builder/deg_builder_key.h | 6 +++--- source/blender/editors/mesh/editmesh_knife.c | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh_runtime.h b/source/blender/blenkernel/BKE_mesh_runtime.h index 083f83ef059..e2346f3a74d 100644 --- a/source/blender/blenkernel/BKE_mesh_runtime.h +++ b/source/blender/blenkernel/BKE_mesh_runtime.h @@ -28,7 +28,7 @@ struct Scene; int BKE_mesh_runtime_looptri_len(const struct Mesh *mesh); /** - * Return mesh triangulation data, calculated lazily when necessary necessary. + * Return mesh triangulation data, calculated lazily when necessary. * See #MLoopTri for further description of mesh triangulation. * * \note Prefer #Mesh::looptris() in C++ code. diff --git a/source/blender/blenkernel/intern/object_update.cc b/source/blender/blenkernel/intern/object_update.cc index 106c9594718..625aa666023 100644 --- a/source/blender/blenkernel/intern/object_update.cc +++ b/source/blender/blenkernel/intern/object_update.cc @@ -142,7 +142,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o CustomData_MeshMasks_update(&cddata_masks, &CD_MASK_BAREMESH); /* Custom attributes should not be removed automatically. They might be used by the render * engine or scripts. They can still be removed explicitly using geometry nodes. - * Crease can be be used in generic situations with geometry nodes as well. */ + * Crease can be used in generic situations with geometry nodes as well. */ cddata_masks.vmask |= CD_MASK_PROP_ALL | CD_MASK_CREASE; cddata_masks.emask |= CD_MASK_PROP_ALL | CD_MASK_CREASE; cddata_masks.fmask |= CD_MASK_PROP_ALL; diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh index 94464ef5088..84a5c87d423 100644 --- a/source/blender/blenlib/BLI_span.hh +++ b/source/blender/blenlib/BLI_span.hh @@ -152,7 +152,7 @@ template class Span { /** * Returns a contiguous part of the array. This invokes undefined behavior when the start or size - * is negative. Clamps the size of the new new span so it fits in the current one. + * is negative. Clamps the size of the new span so it fits in the current one. */ constexpr Span slice_safe(const int64_t start, const int64_t size) const { @@ -608,7 +608,7 @@ template class MutableSpan { /** * Returns a contiguous part of the array. This invokes undefined behavior when the start or size - * is negative. Clamps the size of the new new span so it fits in the current one. + * is negative. Clamps the size of the new span so it fits in the current one. */ constexpr MutableSpan slice_safe(const int64_t start, const int64_t size) const { diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h index 4a9025641f9..94cb9757867 100644 --- a/source/blender/depsgraph/DEG_depsgraph_query.h +++ b/source/blender/depsgraph/DEG_depsgraph_query.h @@ -162,7 +162,7 @@ typedef struct DEGObjectIterSettings { } DEGObjectIterSettings; /** - * Flags to to get objects for draw manager and final render. + * Flags to get objects for draw manager and final render. */ #define DEG_OBJECT_ITER_FOR_RENDER_ENGINE_FLAGS \ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | \ diff --git a/source/blender/depsgraph/intern/builder/deg_builder_key.h b/source/blender/depsgraph/intern/builder/deg_builder_key.h index 4f8b2dc9f8f..519872a3387 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_key.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_key.h @@ -139,9 +139,9 @@ struct OperationKey { int name_tag = -1; }; -/* Similar to the the OperationKey but does not contain external references, which makes it +/* Similar to the #OperationKey but does not contain external references, which makes it * suitable to identify operations even after the original database or graph was destroyed. - * The downside of this key over the OperationKey is that it performs string allocation upon + * The downside of this key over the #OperationKey is that it performs string allocation upon * the key construction. */ struct PersistentOperationKey : public OperationKey { /* Create the key which identifies the given operation node. */ @@ -155,7 +155,7 @@ struct PersistentOperationKey : public OperationKey { component_name_storage_ = component_node->name; name_storage_ = operation_node->name; - /* Assign fields used by the OperationKey API. */ + /* Assign fields used by the #OperationKey API. */ id = id_node->id_orig; component_type = component_node->type; component_name = component_name_storage_.c_str(); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index dbe77805dd8..b7129b4b4d4 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -4321,7 +4321,7 @@ static void knifetool_finish_single_post(KnifeTool_OpData *UNUSED(kcd), Object * static void knifetool_finish_ex(KnifeTool_OpData *kcd) { /* Separate pre/post passes are needed because `em->looptris` recalculation from the 'post' pass - * causes causes triangle indices in #KnifeTool_OpData.bvh to get out of sync. + * causes triangle indices in #KnifeTool_OpData.bvh to get out of sync. * So perform all the cuts before doing any mesh recalculation, see: T101721. */ for (uint ob_index = 0; ob_index < kcd->objects_len; ob_index++) { Object *ob = kcd->objects[ob_index]; From 0cc573c8c42ab96ed8cab23606fa22d3b959da08 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 17 Dec 2022 15:58:30 +1100 Subject: [PATCH 0193/1522] Cleanup: white space around comment blocks --- intern/cycles/kernel/integrator/shade_volume.h | 2 +- source/blender/blenkernel/BKE_key.h | 1 + source/blender/blenkernel/BKE_particle.h | 2 +- source/blender/blenkernel/BKE_pbvh.h | 6 +++--- source/blender/blenkernel/BKE_pointcache.h | 2 +- source/blender/blenkernel/intern/curves.cc | 2 +- source/blender/blenkernel/intern/dynamicpaint.c | 4 ++-- source/blender/blenkernel/intern/idprop.c | 2 -- source/blender/blenkernel/intern/key.cc | 4 ---- source/blender/blenkernel/intern/multires.cc | 2 +- source/blender/blenkernel/intern/particle.c | 3 ++- source/blender/blenkernel/intern/softbody.c | 2 +- source/blender/blenlib/intern/string_utf8.c | 6 +++--- .../blenlib/tests/BLI_string_utf8_test.cc | 16 ++++++++-------- .../compositor_glare_ghost_accumulate.glsl | 2 +- .../shaders/compositor_glare_ghost_base.glsl | 2 +- .../depsgraph/intern/builder/deg_builder_key.h | 2 +- .../engines/eevee/engine_eevee_shared_defines.h | 2 +- .../shaders/infos/eevee_legacy_common_info.hh | 2 +- .../draw/engines/eevee/shaders/surface_lib.glsl | 2 +- ...rlay_armature_shape_outline_vert_no_geom.glsl | 2 +- .../workbench_shadow_caps_vert_no_geom.glsl | 4 ++-- .../shaders/workbench_shadow_vert_no_geom.glsl | 6 +++--- source/blender/draw/intern/draw_pbvh.cc | 2 +- source/blender/draw/intern/draw_shader_shared.h | 2 +- source/blender/draw/intern/draw_texture_pool.cc | 2 +- source/blender/editors/gpencil/gpencil_fill.c | 2 +- source/blender/editors/include/ED_anim_api.h | 2 +- .../editors/interface/interface_templates.cc | 2 +- source/blender/editors/sculpt_paint/sculpt.cc | 2 +- .../editors/sculpt_paint/sculpt_automasking.cc | 2 +- source/blender/editors/space_clip/clip_draw.c | 2 +- .../blender/geometry/intern/uv_parametrizer.cc | 2 +- source/blender/gpu/metal/mtl_command_buffer.mm | 2 +- source/blender/gpu/metal/mtl_shader.hh | 12 ++++++------ .../gpu_shader_3D_polyline_vert_no_geom.glsl | 2 +- source/blender/gpu/vulkan/vk_storage_buffer.cc | 4 ++-- source/blender/makesrna/intern/rna_nla.c | 5 +++-- .../nodes/geometry/nodes/node_geo_dual_mesh.cc | 2 +- source/blender/python/intern/bpy_app_handlers.c | 8 ++++++-- .../blender/python/mathutils/mathutils_Matrix.c | 2 +- 41 files changed, 68 insertions(+), 67 deletions(-) diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h index 0323738c09b..456bebe771a 100644 --- a/intern/cycles/kernel/integrator/shade_volume.h +++ b/intern/cycles/kernel/integrator/shade_volume.h @@ -1030,7 +1030,7 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg, const float3 initial_throughput = INTEGRATOR_STATE(state, path, throughput); /* The path throughput used to calculate the throughput for direct light. */ float3 unlit_throughput = initial_throughput; - /* If a new path segment is generated at the direct scatter position.*/ + /* If a new path segment is generated at the direct scatter position. */ bool guiding_generated_new_segment = false; float rand_phase_guiding = 0.5f; # endif diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index 813dc9aba34..7fb3e71ad3d 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -157,6 +157,7 @@ void BKE_keyblock_convert_from_vertcos(const struct Object *ob, const float (*vertCos)[3]); float (*BKE_keyblock_convert_to_vertcos(const struct Object *ob, const struct KeyBlock *kb))[3]; +/** RAW coordinates offsets. */ void BKE_keyblock_update_from_offset(const struct Object *ob, struct KeyBlock *kb, const float (*ofs)[3]); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 05b9aca7544..618e69b5436 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -665,7 +665,7 @@ float psys_get_current_display_percentage(struct ParticleSystem *psys, bool use_ /* psys_reset */ #define PSYS_RESET_ALL 1 #define PSYS_RESET_DEPSGRAPH 2 -/* #define PSYS_RESET_CHILDREN 3 */ /*UNUSED*/ +// #define PSYS_RESET_CHILDREN 3 /*UNUSED*/ #define PSYS_RESET_CACHE_MISS 4 /* index_dmcache */ diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 8f66d552387..a1e1253bd54 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -71,7 +71,7 @@ struct PBVHPublic { /* A generic PBVH vertex. * - * Note: in PBVH_GRIDS we consider the final grid points + * NOTE: in PBVH_GRIDS we consider the final grid points * to be vertices. This is not true of edges or faces which are pulled from * the base mesh. */ @@ -79,12 +79,12 @@ typedef struct PBVHVertRef { intptr_t i; } PBVHVertRef; -/* Note: edges in PBVH_GRIDS are always pulled from the base mesh.*/ +/* NOTE: edges in PBVH_GRIDS are always pulled from the base mesh. */ typedef struct PBVHEdgeRef { intptr_t i; } PBVHEdgeRef; -/* Note: faces in PBVH_GRIDS are always puled from the base mesh.*/ +/* NOTE: faces in PBVH_GRIDS are always puled from the base mesh. */ typedef struct PBVHFaceRef { intptr_t i; } PBVHFaceRef; diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index 4331a25c112..79a3bdf7c3c 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -27,7 +27,7 @@ extern "C" { #define PTCACHE_RESET_DEPSGRAPH 0 #define PTCACHE_RESET_BAKED 1 #define PTCACHE_RESET_OUTDATED 2 -/* #define PTCACHE_RESET_FREE 3 */ /*UNUSED*/ +// #define PTCACHE_RESET_FREE 3 /*UNUSED*/ /* Add the blend-file name after `blendcache_`. */ #define PTCACHE_EXT ".bphys" diff --git a/source/blender/blenkernel/intern/curves.cc b/source/blender/blenkernel/intern/curves.cc index 8d3f90230f6..84ffb5e5314 100644 --- a/source/blender/blenkernel/intern/curves.cc +++ b/source/blender/blenkernel/intern/curves.cc @@ -203,7 +203,7 @@ IDTypeInfo IDType_ID_CV = { /* id_filter */ FILTER_ID_CV, /* main_listbase_index */ INDEX_ID_CV, /* struct_size */ sizeof(Curves), - /* name*/ "Curves", + /* name */ "Curves", /* name_plural */ "hair_curves", /* translation_context */ BLT_I18NCONTEXT_ID_CURVES, /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE, diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index e0ae3f42be6..ef8a4990842 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -3029,7 +3029,7 @@ int dynamicPaint_createUVSurface(Scene *scene, #if 0 /* ----------------------------------------------------------------- * For debug, write a dump of adjacency data to a file. - * -----------------------------------------------------------------*/ + * ----------------------------------------------------------------- */ FILE *dump_file = fopen("dynpaint-adj-data.txt", "w"); int *tmp = MEM_callocN(sizeof(int) * active_points, "tmp"); for (int ty = 0; ty < h; ty++) { @@ -3140,7 +3140,7 @@ int dynamicPaint_createUVSurface(Scene *scene, #if 0 /* ----------------------------------------------------------------- * For debug, output pixel statuses to the color map - * -----------------------------------------------------------------*/ + * ----------------------------------------------------------------- */ for (index = 0; index < sData->total_points; index++) { ImgSeqFormatData *f_data = (ImgSeqFormatData *)sData->format_data; PaintUVPoint *uvPoint = &((PaintUVPoint *)f_data->uv_p)[index]; diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index f876caf9d91..00e7425c8af 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -58,8 +58,6 @@ static size_t idp_size_table[] = { #define GETPROP(prop, i) &(IDP_IDPArray(prop)[i]) -/* --------- property array type -------------*/ - IDProperty *IDP_NewIDPArray(const char *name) { IDProperty *prop = MEM_callocN(sizeof(IDProperty), "IDProperty prop array"); diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 26cec31e177..99010c70e90 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -2472,8 +2472,6 @@ float (*BKE_keyblock_convert_to_vertcos(const Object *ob, const KeyBlock *kb))[3 return vertCos; } -/************************* raw coord offsets ************************/ - void BKE_keyblock_update_from_offset(const Object *ob, KeyBlock *kb, const float (*ofs)[3]) { int a; @@ -2509,8 +2507,6 @@ void BKE_keyblock_update_from_offset(const Object *ob, KeyBlock *kb, const float } } -/* ==========================================================*/ - bool BKE_keyblock_move(Object *ob, int org_index, int new_index) { Key *key = BKE_key_from_object(ob); diff --git a/source/blender/blenkernel/intern/multires.cc b/source/blender/blenkernel/intern/multires.cc index 3700432696a..8ba8b657a16 100644 --- a/source/blender/blenkernel/intern/multires.cc +++ b/source/blender/blenkernel/intern/multires.cc @@ -670,7 +670,7 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl) if (mdisps && levels > 0) { if (lvl > 0) { - /* MLoop *ml = me->mloop; */ /*UNUSED*/ + // MLoop *ml = me->mloop; /*UNUSED*/ int nsize = multires_side_tot[lvl]; int hsize = multires_side_tot[mmd->totlvl]; int i, j; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 6a277295efd..f9abe7de830 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3332,7 +3332,8 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re PARTICLE_P; float birthtime = 0.0, dietime = 0.0; - float t, time = 0.0, dfra = 1.0 /* , frs_sec = sim->scene->r.frs_sec*/ /*UNUSED*/; + float t, time = 0.0, dfra = 1.0; + // float frs_sec = sim->scene->r.frs_sec; /*UNUSED*/ float col[4] = {0.5f, 0.5f, 0.5f, 1.0f}; float prev_tangent[3] = {0.0f, 0.0f, 0.0f}, hairmat[4][4]; float rotmat[3][3]; diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index efe423ccfc5..0a6cb1a8556 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -233,7 +233,7 @@ static float _final_mass(Object *ob, BodyPoint *bp) CLOG_ERROR(&LOG, "sb or bp == NULL"); return 1.0f; } -/* helper functions for everything is animateble jow_go_for2_5 ------*/ +/* Helper functions for everything is animateble jow_go_for2_5. */ /* +++ collider caching and dicing +++ */ diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index 26facda7abf..e2124ad4931 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -267,7 +267,7 @@ size_t BLI_strncpy_utf8_rlen(char *__restrict dst, const char *__restrict src, s #undef BLI_STR_UTF8_CPY -/* --------------------------------------------------------------------------*/ +/* -------------------------------------------------------------------- */ /* wchar_t / utf8 functions */ size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, @@ -359,7 +359,7 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w, } /* end wchar_t / utf8 functions */ -/* --------------------------------------------------------------------------*/ +/* -------------------------------------------------------------------- */ int BLI_wcwidth(char32_t ucs) { @@ -399,7 +399,7 @@ int BLI_str_utf8_char_width_safe(const char *p) return (columns < 0) ? 1 : columns; } -/* --------------------------------------------------------------------------*/ +/* -------------------------------------------------------------------- */ /* copied from glib's gutf8.c, added 'Err' arg */ diff --git a/source/blender/blenlib/tests/BLI_string_utf8_test.cc b/source/blender/blenlib/tests/BLI_string_utf8_test.cc index d66bade40ed..2b032ec0982 100644 --- a/source/blender/blenlib/tests/BLI_string_utf8_test.cc +++ b/source/blender/blenlib/tests/BLI_string_utf8_test.cc @@ -463,7 +463,7 @@ TEST(string, StrCursorStepNextUtf32AllCombining) TEST(string, StrCursorStepNextUtf32Complex) { - /* Combining character, "A", two combining characters, "B".*/ + /* Combining character, "A", two combining characters, "B". */ const char32_t complex[] = U"\u0300\u0041\u0300\u0320\u0042"; const size_t len = 5; int pos = 0; @@ -486,7 +486,7 @@ TEST(string, StrCursorStepNextUtf32Complex) TEST(string, StrCursorStepNextUtf32Invalid) { - /* Latin1 "À", tab, carriage return, linefeed, separated by combining characters.*/ + /* Latin1 "À", tab, carriage return, linefeed, separated by combining characters. */ const char32_t invalid[] = U"\u00C0\u0300\u0009\u0300\u000D\u0300\u000A\u0300"; const size_t len = 8; int pos = 0; @@ -573,7 +573,7 @@ TEST(string, StrCursorStepPrevUtf32AllCombining) TEST(string, StrCursorStepPrevUtf32Complex) { - /* Combining character, "A", two combining characters, "B".*/ + /* Combining character, "A", two combining characters, "B". */ const char32_t complex[] = U"\u0300\u0041\u0300\u0320\u0042"; const size_t len = 5; int pos = 5; @@ -596,7 +596,7 @@ TEST(string, StrCursorStepPrevUtf32Complex) TEST(string, StrCursorStepPrevUtf32Invalid) { - /* Latin1 "À", tab, carriage return, linefeed, separated by combining characters.*/ + /* Latin1 "À", tab, carriage return, linefeed, separated by combining characters. */ const char32_t invalid[] = U"\u00C0\u0300\u0009\u0300\u000D\u0300\u000A\u0300"; const size_t len = 8; int pos = 8; @@ -690,7 +690,7 @@ TEST(string, StrCursorStepNextUtf8AllCombining) TEST(string, StrCursorStepNextUtf8AllComplex) { - /* Combining character, "A", "©", two combining characters, "B".*/ + /* Combining character, "A", "©", two combining characters, "B". */ const char complex[] = "\xCC\x80\x41\xC2\xA9\xCC\x80\xCC\xA0\x42"; const size_t len = 10; int pos = 0; @@ -723,7 +723,7 @@ TEST(string, StrCursorStepNextUtf8AllComplex) TEST(string, StrCursorStepNextUtf8Invalid) { - /* Latin1 "À", combining, tab, carriage return, linefeed, combining.*/ + /* Latin1 "À", combining, tab, carriage return, linefeed, combining. */ const char invalid[] = "\xC0\xCC\x80\x09\x0D\x0A\xCC\x80"; const size_t len = 8; int pos = 0; @@ -818,7 +818,7 @@ TEST(string, StrCursorStepPrevUtf8AllCombining) TEST(string, StrCursorStepPrevUtf8Complex) { - /* Combining character, "A", "©", two combining characters, "B".*/ + /* Combining character, "A", "©", two combining characters, "B". */ const char complex[] = "\xCC\x80\x41\xC2\xA9\xCC\x80\xCC\xA0\x42"; const size_t len = 10; int pos = 10; @@ -851,7 +851,7 @@ TEST(string, StrCursorStepPrevUtf8Complex) TEST(string, StrCursorStepPrevUtf8Invalid) { - /* Latin1 "À", combining, tab, carriage return, linefeed, combining.*/ + /* Latin1 "À", combining, tab, carriage return, linefeed, combining. */ const char invalid[] = "\xC0\xCC\x80\x09\x0D\x0A\xCC\x80"; const size_t len = 8; int pos = 8; diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_accumulate.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_accumulate.glsl index 6b6d139b84d..83598fb8a63 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_accumulate.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_accumulate.glsl @@ -6,7 +6,7 @@ void main() ivec2 input_size = texture_size(input_ghost_tx); /* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size - * to get the coordinates into the sampler's expected [0, 1] range*/ + * to get the coordinates into the sampler's expected [0, 1] range. */ vec2 coordinates = (vec2(texel) + vec2(0.5)) / input_size; /* We accumulate four variants of the input ghost texture, each is scaled by some amount and diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_base.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_base.glsl index b71866f33d6..177b9a86210 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_base.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_base.glsl @@ -6,7 +6,7 @@ void main() ivec2 input_size = texture_size(small_ghost_tx); /* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size - * to get the coordinates into the sampler's expected [0, 1] range*/ + * to get the coordinates into the sampler's expected [0, 1] range. */ vec2 coordinates = (vec2(texel) + vec2(0.5)) / input_size; /* The small ghost is scaled down with the origin as the center of the image by a factor of 2.13, diff --git a/source/blender/depsgraph/intern/builder/deg_builder_key.h b/source/blender/depsgraph/intern/builder/deg_builder_key.h index 519872a3387..2d08e231114 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_key.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_key.h @@ -151,7 +151,7 @@ struct PersistentOperationKey : public OperationKey { const IDNode *id_node = component_node->owner; /* Copy names over to our object, so that the key stays valid even after the `operation_node` - * is destroyed.*/ + * is destroyed. */ component_name_storage_ = component_node->name; name_storage_ = operation_node->name; diff --git a/source/blender/draw/engines/eevee/engine_eevee_shared_defines.h b/source/blender/draw/engines/eevee/engine_eevee_shared_defines.h index 01e246ac4b1..731bb0c9deb 100644 --- a/source/blender/draw/engines/eevee/engine_eevee_shared_defines.h +++ b/source/blender/draw/engines/eevee/engine_eevee_shared_defines.h @@ -21,7 +21,7 @@ /* Motion Blur. */ #define EEVEE_VELOCITY_TILE_SIZE 32 -/* Depth of Field*/ +/* Depth of Field. */ #define DOF_TILE_DIVISOR 16 #define DOF_BOKEH_LUT_SIZE 32 #define DOF_GATHER_RING_COUNT 5 diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh index a9c7687e5cd..13145c2d0f5 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh @@ -200,7 +200,7 @@ GPU_SHADER_CREATE_INFO(eevee_legacy_closure_eval_translucent_lib) .additional_info("eevee_legacy_closure_eval_lib") .additional_info("eevee_legacy_renderpass_lib"); -/* eevee_legacy_closure_eval_surface_lib*/ +/* eevee_legacy_closure_eval_surface_lib */ GPU_SHADER_CREATE_INFO(eevee_legacy_closure_eval_surface_lib) .additional_info("eevee_legacy_closure_eval_diffuse_lib") .additional_info("eevee_legacy_closure_eval_glossy_lib") diff --git a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl index aedcb009ab1..5ee020358b5 100644 --- a/source/blender/draw/engines/eevee/shaders/surface_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/surface_lib.glsl @@ -45,7 +45,7 @@ out ShaderStageInterface{SURFACE_INTERFACE} dataOut; dataOut.worldNormal = dataIn[vert].worldNormal; \ dataOut.viewNormal = dataIn[vert].viewNormal; -# else /* GPU_VERTEX_SHADER || GPU_FRAGMENT_SHADER*/ +# else /* GPU_VERTEX_SHADER || GPU_FRAGMENT_SHADER */ IN_OUT ShaderStageInterface{SURFACE_INTERFACE}; diff --git a/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl index 57c0ecb0b9b..9b2b4c65f96 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_armature_shape_outline_vert_no_geom.glsl @@ -143,7 +143,7 @@ void main() * (avoid problems with point behind near plane). * If the chosen point is parallel to the edge in screen space, * choose the other point anyway. - * This fixes some issue with cubes in orthographic views.*/ + * This fixes some issue with cubes in orthographic views. */ if (vPos[0].z < vPos[3].z) { hidden_point = (abs(fac0) > 1e-5) ? ssPos[0] : ssPos[3]; } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_vert_no_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_vert_no_geom.glsl index e2eabfa5b9e..b7347ce4864 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_vert_no_geom.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_caps_vert_no_geom.glsl @@ -2,10 +2,10 @@ #pragma USE_SSBO_VERTEX_FETCH(TriangleList, 6) #ifdef DOUBLE_MANIFOLD -# define vert_len 6 /* Triangle Strip with 6 verts = 4 triangles = 12 verts*/ +# define vert_len 6 /* Triangle Strip with 6 verts = 4 triangles = 12 verts. */ # define emit_triangle_count 2 #else -# define vert_len 6 /* Triangle Strip with 6 verts = 4 triangles = 12 verts*/ +# define vert_len 6 /* Triangle Strip with 6 verts = 4 triangles = 12 verts. */ # define emit_triangle_count 2 #endif diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert_no_geom.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert_no_geom.glsl index 277f85ca457..0da97d5325a 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert_no_geom.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert_no_geom.glsl @@ -4,10 +4,10 @@ * geometry manifold type */ #ifdef DOUBLE_MANIFOLD -# define vert_len 12 /* Triangle Strip with 6 verts = 4 triangles = 12 verts*/ +# define vert_len 12 /* Triangle Strip with 6 verts = 4 triangles = 12 verts. */ # define emit_triangle_count 4 #else -# define vert_len 6 /* Triang;e Strip with 4 verts = 2 triangles = 6 verts*/ +# define vert_len 6 /* Triangle Strip with 4 verts = 2 triangles = 6 verts. */ # define emit_triangle_count 2 #endif @@ -157,4 +157,4 @@ void main() DISCARD_VERTEX #endif } -} \ No newline at end of file +} diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index d62ace4fb57..8ba827b266c 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -984,7 +984,7 @@ struct PBVHBatches { const blender::Span edges = args->me->edges(); - /* Calculate number of edges*/ + /* Calculate number of edges. */ int edge_count = 0; for (int i = 0; i < args->totprim; i++) { const MLoopTri *lt = args->mlooptri + args->prim_indices[i]; diff --git a/source/blender/draw/intern/draw_shader_shared.h b/source/blender/draw/intern/draw_shader_shared.h index be389941dae..23ded2ea5e9 100644 --- a/source/blender/draw/intern/draw_shader_shared.h +++ b/source/blender/draw/intern/draw_shader_shared.h @@ -327,7 +327,7 @@ struct DRWDebugVert { uint pos0; uint pos1; uint pos2; - /* Named vert_color to avoid global namespace collision with uniform color.*/ + /* Named vert_color to avoid global namespace collision with uniform color. */ uint vert_color; }; BLI_STATIC_ASSERT_ALIGN(DRWDebugVert, 16) diff --git a/source/blender/draw/intern/draw_texture_pool.cc b/source/blender/draw/intern/draw_texture_pool.cc index ffba98205c4..aea96272460 100644 --- a/source/blender/draw/intern/draw_texture_pool.cc +++ b/source/blender/draw/intern/draw_texture_pool.cc @@ -49,7 +49,7 @@ GPUTexture *DRW_texture_pool_query(DRWTexturePool *pool, eGPUTextureUsage usage, void *user) { - /* Texture pools have an implicit usage as a texture attachment*/ + /* Texture pools have an implicit usage as a texture attachment. */ BLI_assert_msg(usage & GPU_TEXTURE_USAGE_ATTACHMENT, "Pool textures must be of usage type attachment."); usage = usage | GPU_TEXTURE_USAGE_ATTACHMENT; diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 97cb4c30666..65bd8da452a 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -510,7 +510,7 @@ static void gpencil_stroke_collision( const float connection_dist = tgpf->fill_extend_fac * 0.1f; float diff_mat[4][4], inv_mat[4][4]; - /* Transform matrix for original stroke.*/ + /* Transform matrix for original stroke. */ BKE_gpencil_layer_transform_matrix_get(tgpf->depsgraph, tgpf->ob, gpl, diff_mat); invert_m4_m4(inv_mat, diff_mat); diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 8fe2d0ae60f..9eaaff9f7fa 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -1052,7 +1052,7 @@ void ED_keymap_anim(struct wmKeyConfig *keyconf); void ED_operatormacros_graph(void); /* space_action */ void ED_operatormacros_action(void); -/* space_nla*/ +/* space_nla */ void ED_operatormacros_nla(void); /** \} */ diff --git a/source/blender/editors/interface/interface_templates.cc b/source/blender/editors/interface/interface_templates.cc index 6c71c1bcc65..2e4c0e1c1b0 100644 --- a/source/blender/editors/interface/interface_templates.cc +++ b/source/blender/editors/interface/interface_templates.cc @@ -5789,7 +5789,7 @@ void uiTemplateColorPicker(uiLayout *layout, } } -static void ui_template_palette_menu(bContext * /* C*/, uiLayout *layout, void * /*but_p*/) +static void ui_template_palette_menu(bContext * /*C*/, uiLayout *layout, void * /*but_p*/) { uiLayout *row; diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 654083605da..9cb30c9f83d 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -639,7 +639,7 @@ void SCULPT_visibility_sync_all_from_faces(Object *ob) BMIter iter; BMFace *f; - /* Hide all verts and edges attached to faces.*/ + /* Hide all verts and edges attached to faces. */ BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) { BMLoop *l = f->l_first; do { diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.cc b/source/blender/editors/sculpt_paint/sculpt_automasking.cc index 02495059810..cdb12588401 100644 --- a/source/blender/editors/sculpt_paint/sculpt_automasking.cc +++ b/source/blender/editors/sculpt_paint/sculpt_automasking.cc @@ -774,7 +774,7 @@ static void sculpt_normal_occlusion_automasking_fill(AutomaskingCache *automaski SculptSession *ss = ob->sculpt; const int totvert = SCULPT_vertex_count_get(ss); - /* No need to build original data since this is only called at the beginning of strokes.*/ + /* No need to build original data since this is only called at the beginning of strokes. */ AutomaskingNodeData nodedata; nodedata.have_orig_data = false; diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index f1835ca40a8..f03d99eac8e 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -978,7 +978,7 @@ static void draw_marker_slide_zones(SpaceClip *sc, if ((sc->flag & SC_SHOW_MARKER_PATTERN) && ((track->pat_flag & SELECT) == sel || outline)) { float pat_min[2], pat_max[2]; - /* float dx = 12.0f / width, dy = 12.0f / height;*/ /* XXX UNUSED */ + // float dx = 12.0f / width, dy = 12.0f / height; /*UNUSED*/ float tilt_ctrl[2]; if (!outline) { diff --git a/source/blender/geometry/intern/uv_parametrizer.cc b/source/blender/geometry/intern/uv_parametrizer.cc index d197fdb644c..ed8c4b46e50 100644 --- a/source/blender/geometry/intern/uv_parametrizer.cc +++ b/source/blender/geometry/intern/uv_parametrizer.cc @@ -3893,7 +3893,7 @@ void GEO_uv_parametrizer_face_add(ParamHandle *phandle, int i1 = permute[(i + 1) % pm]; int i2 = permute[(i + 2) % pm]; if (!p_face_exists(phandle, vkeys, i0, i1, i2)) { - i--; /* ...All good...*/ + i--; /* All good. */ continue; } diff --git a/source/blender/gpu/metal/mtl_command_buffer.mm b/source/blender/gpu/metal/mtl_command_buffer.mm index 8ff0f7aa2ca..b78540241ad 100644 --- a/source/blender/gpu/metal/mtl_command_buffer.mm +++ b/source/blender/gpu/metal/mtl_command_buffer.mm @@ -676,7 +676,7 @@ void MTLRenderPassState::bind_fragment_sampler(MTLSamplerBinding &sampler_bindin BLI_assert(slot < MTL_MAX_TEXTURE_SLOTS); UNUSED_VARS_NDEBUG(shader_interface); - /* If sampler state has not changed for the given slot, we do not need to fetch*/ + /* If sampler state has not changed for the given slot, we do not need to fetch. */ if (this->cached_fragment_sampler_state_bindings[slot].sampler_state == nil || !(this->cached_fragment_sampler_state_bindings[slot].binding_state == sampler_binding.state) || diff --git a/source/blender/gpu/metal/mtl_shader.hh b/source/blender/gpu/metal/mtl_shader.hh index 2988677bc31..29df1f22ced 100644 --- a/source/blender/gpu/metal/mtl_shader.hh +++ b/source/blender/gpu/metal/mtl_shader.hh @@ -637,15 +637,15 @@ inline bool mtl_convert_vertex_format(MTLVertexFormat shader_attrib_format, out_vert_format = MTLVertexFormatChar4; } else if (shader_attrib_format == MTLVertexFormatInt3 && component_length == 3) { - /* Same as above case for matching length and signage (Len=3)*/ + /* Same as above case for matching length and signage (Len=3). */ out_vert_format = MTLVertexFormatChar3; } else if (shader_attrib_format == MTLVertexFormatInt2 && component_length == 2) { - /* Same as above case for matching length and signage (Len=2)*/ + /* Same as above case for matching length and signage (Len=2). */ out_vert_format = MTLVertexFormatChar2; } else if (shader_attrib_format == MTLVertexFormatInt && component_length == 1) { - /* Same as above case for matching length and signage (Len=1)*/ + /* Same as above case for matching length and signage (Len=1). */ out_vert_format = MTLVertexFormatChar; } else if (shader_attrib_format == MTLVertexFormatInt && component_length == 4) { @@ -718,15 +718,15 @@ inline bool mtl_convert_vertex_format(MTLVertexFormat shader_attrib_format, out_vert_format = MTLVertexFormatUChar4; } else if (shader_attrib_format == MTLVertexFormatUInt3 && component_length == 3) { - /* Same as above case for matching length and signage (Len=3)*/ + /* Same as above case for matching length and signage (Len=3). */ out_vert_format = MTLVertexFormatUChar3; } else if (shader_attrib_format == MTLVertexFormatUInt2 && component_length == 2) { - /* Same as above case for matching length and signage (Len=2)*/ + /* Same as above case for matching length and signage (Len=2). */ out_vert_format = MTLVertexFormatUChar2; } else if (shader_attrib_format == MTLVertexFormatUInt && component_length == 1) { - /* Same as above case for matching length and signage (Len=1)*/ + /* Same as above case for matching length and signage (Len=1). */ out_vert_format = MTLVertexFormatUChar; } else if (shader_attrib_format == MTLVertexFormatInt && component_length == 4) { diff --git a/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert_no_geom.glsl b/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert_no_geom.glsl index 4c1aebd9caf..d546f98d165 100644 --- a/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert_no_geom.glsl +++ b/source/blender/gpu/shaders/gpu_shader_3D_polyline_vert_no_geom.glsl @@ -56,7 +56,7 @@ void main() /* Index of the quad primitive. Each quad corresponds to one line in the input primitive. */ int quad_id = gl_VertexID / 6; - /* Determine vertex within the quad (A, B, C)(A, C, D).*/ + /* Determine vertex within the quad (A, B, C)(A, C, D). */ int quad_vertex_id = gl_VertexID % 6; uint src_index_a; diff --git a/source/blender/gpu/vulkan/vk_storage_buffer.cc b/source/blender/gpu/vulkan/vk_storage_buffer.cc index 2b6fda0547d..40c770fa1d2 100644 --- a/source/blender/gpu/vulkan/vk_storage_buffer.cc +++ b/source/blender/gpu/vulkan/vk_storage_buffer.cc @@ -23,7 +23,7 @@ void VKStorageBuffer::unbind() { } -void VKStorageBuffer::clear(eGPUTextureFormat /* internal_format*/, +void VKStorageBuffer::clear(eGPUTextureFormat /*internal_format*/, eGPUDataFormat /*data_format*/, void * /*data*/) { @@ -39,4 +39,4 @@ void VKStorageBuffer::read(void * /*data*/) { } -} // namespace blender::gpu \ No newline at end of file +} // namespace blender::gpu diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index de033408170..a61f6fb8c2e 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -320,8 +320,9 @@ static void rna_NlaStrip_frame_end_ui_set(PointerRNA *ptr, float value) float action_length_delta = (old_strip_end - data->end) / data->scale; /* If no repeats are used, then modify the action end frame : */ if (IS_EQF(data->repeat, 1.0f)) { - /* If they're equal, strip has been reduced by the same amount as the whole strip length, so - * clamp the action clip length to 1 frame, and add a frame to end so that len(strip)!=0 :*/ + /* If they're equal, strip has been reduced by the same amount as the whole strip length, + * so clamp the action clip length to 1 frame, and add a frame to end so that + * `len(strip) != 0`. */ if (IS_EQF(action_length_delta, actlen)) { data->actend = data->actstart + 1.0f; data->end += 1.0f; diff --git a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc index eb8f0b8e0ba..e692ca69cf0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc @@ -136,7 +136,7 @@ static void transfer_attributes( MutableAttributeAccessor dst_attributes) { /* Retrieve all attributes except for position which is handled manually. - * Remove anonymous attributes that don't need to be propagated.*/ + * Remove anonymous attributes that don't need to be propagated. */ Set attribute_ids = src_attributes.all_ids(); attribute_ids.remove("position"); attribute_ids.remove_if([](const AttributeIDRef &id) { return !id.should_be_kept(); }); diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index 3580481941d..947ec5d60bb 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -94,8 +94,10 @@ static PyStructSequence_Desc app_cb_info_desc = { # endif #endif -/* --------------------------------------------------------------------------*/ -/* permanent tagging code */ +/* -------------------------------------------------------------------- */ +/** \name Permanent Tagging Code + * \{ */ + #define PERMINENT_CB_ID "_bpy_persistent" static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type), @@ -190,6 +192,8 @@ static PyTypeObject BPyPersistent_Type = { /*tp_vectorcall*/ NULL, }; +/** \} */ + static PyObject *py_cb_array[BKE_CB_EVT_TOT] = {NULL}; static PyObject *make_app_cb_info(void) diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c index 21ad79bc94d..e4004efddbc 100644 --- a/source/blender/python/mathutils/mathutils_Matrix.c +++ b/source/blender/python/mathutils/mathutils_Matrix.c @@ -3795,7 +3795,7 @@ PyTypeObject matrix_access_Type = { /*tp_doc*/ NULL, /*tp_traverse*/ (traverseproc)MatrixAccess_traverse, /*tp_clear*/ (inquiry)MatrixAccess_clear, - /*tp_richcompare*/ NULL /* MatrixAccess_richcmpr */ /* TODO*/, + /*tp_richcompare*/ NULL /* MatrixAccess_richcmpr */ /* TODO */, /*tp_weaklistoffset*/ 0, /*tp_iter*/ (getiterfunc)MatrixAccess_iter, /*tp_iternext*/ NULL, From e07c5a14c9948bbbfd87d69805d770c080eb8891 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 17 Dec 2022 16:00:40 +1100 Subject: [PATCH 0194/1522] Cleanup: sort cmake file lists --- source/blender/editors/space_node/CMakeLists.txt | 2 +- source/blender/gpu/CMakeLists.txt | 12 ++++++------ source/blender/nodes/CMakeLists.txt | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index f8289b42463..3236082c0d2 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -29,8 +29,8 @@ set(INC set(SRC - add_node_search.cc add_menu_assets.cc + add_node_search.cc drawnode.cc link_drag_search.cc node_add.cc diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 9f9d216064a..02793fa74be 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -12,9 +12,9 @@ endif() set(INC . intern - vulkan metal opengl + vulkan ../blenkernel ../blenlib ../bmesh @@ -579,15 +579,15 @@ set(SRC_SHADER_CREATE_INFOS ../draw/engines/workbench/shaders/infos/workbench_transparent_resolve_info.hh ../draw/engines/workbench/shaders/infos/workbench_volume_info.hh - ../draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh ../draw/engines/eevee/shaders/infos/eevee_legacy_bloom_info.hh - ../draw/engines/eevee/shaders/infos/eevee_legacy_lightprobe_info.hh - ../draw/engines/eevee/shaders/infos/eevee_legacy_effects_info.hh + ../draw/engines/eevee/shaders/infos/eevee_legacy_common_info.hh ../draw/engines/eevee/shaders/infos/eevee_legacy_dof_info.hh - ../draw/engines/eevee/shaders/infos/eevee_legacy_volume_info.hh - ../draw/engines/eevee/shaders/infos/eevee_legacy_shadow_info.hh + ../draw/engines/eevee/shaders/infos/eevee_legacy_effects_info.hh + ../draw/engines/eevee/shaders/infos/eevee_legacy_lightprobe_info.hh ../draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh ../draw/engines/eevee/shaders/infos/eevee_legacy_motion_blur_info.hh + ../draw/engines/eevee/shaders/infos/eevee_legacy_shadow_info.hh + ../draw/engines/eevee/shaders/infos/eevee_legacy_volume_info.hh ../draw/engines/image/shaders/infos/engine_image_info.hh ../draw/intern/shaders/draw_debug_info.hh diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index c520f804093..27da5f6cf8e 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -64,8 +64,8 @@ set(SRC NOD_math_functions.hh NOD_multi_function.hh NOD_node_declaration.hh - NOD_shader.h NOD_register.hh + NOD_shader.h NOD_socket.h NOD_socket_declarations.hh NOD_socket_declarations_geometry.hh From c18055ba5c81af73f83d5a2ac410f7df5412754e Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 17 Dec 2022 11:51:12 +0100 Subject: [PATCH 0195/1522] Cleanup: quiet warning --- source/blender/editors/armature/armature_edit.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index 780e2fae00e..3c0617a1dfc 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -394,7 +394,8 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op) vec[type] = 1.0f; } else { - vec[type - 2] = -1.0f; + /* Use casting to quiet -Warray-bounds warning in gcc. */ + vec[(int)type - 2] = -1.0f; } mul_m3_v3(imat, vec); normalize_v3(vec); From 28511ac6cf83dfd56026125ff97630becb44fdf2 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 17 Dec 2022 14:46:15 +0100 Subject: [PATCH 0196/1522] Fix T103294: bring back modifyMesh function for geometry nodes modifier This was removed inrBb1494bcea7b6bb608 under the assumption that it is not needed anymore. Apparently it is, so this commit brings it back. --- source/blender/modifiers/intern/MOD_nodes.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 64261ae5b10..f5ede42b0ad 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1309,6 +1309,19 @@ static void modifyGeometry(ModifierData *md, } } +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) +{ + GeometrySet geometry_set = GeometrySet::create_with_mesh(mesh, GeometryOwnershipType::Editable); + + modifyGeometry(md, ctx, geometry_set); + + Mesh *new_mesh = geometry_set.get_component_for_write().release(); + if (new_mesh == nullptr) { + return BKE_mesh_new_nomain(0, 0, 0, 0, 0); + } + return new_mesh; +} + static void modifyGeometrySet(ModifierData *md, const ModifierEvalContext *ctx, GeometrySet *geometry_set) @@ -1869,7 +1882,7 @@ ModifierTypeInfo modifierType_Nodes = { /* deformMatrices */ nullptr, /* deformVertsEM */ nullptr, /* deformMatricesEM */ nullptr, - /* modifyMesh */ nullptr, + /* modifyMesh */ modifyMesh, /* modifyGeometrySet */ modifyGeometrySet, /* initData */ initData, From 8709a51fa9073884510a546ca99de45321f1d26f Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Sat, 17 Dec 2022 16:35:54 +0100 Subject: [PATCH 0197/1522] Fix T103293: GPencil Multiframe Scale affects stroke thickness inversely The problem was the falloff factor was applied directly and in the thickness must be inversed. Now the thickess is calculated using an interpolation. --- source/blender/editors/transform/transform_mode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/transform/transform_mode.c b/source/blender/editors/transform/transform_mode.c index aeceedf0690..95d2b4d6439 100644 --- a/source/blender/editors/transform/transform_mode.c +++ b/source/blender/editors/transform/transform_mode.c @@ -1029,8 +1029,9 @@ void ElementResize(const TransInfo *t, applyNumInput(&num_evil, values_final_evil); float ratio = values_final_evil[0]; - *td->val = td->ival * fabs(ratio) * gps->runtime.multi_frame_falloff; - CLAMP_MIN(*td->val, 0.001f); + float transformed_value = td->ival * fabs(ratio); + *td->val = max_ff(interpf(transformed_value, td->ival, gps->runtime.multi_frame_falloff), + 0.001f); } } else { From 5a761a47e1ccb4f6760d2b556b481ef9cc5938ca Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 18 Dec 2022 14:18:01 +1100 Subject: [PATCH 0198/1522] Cleanup: replace StringIO seek() & read() with a call to getvalue() --- release/scripts/modules/bl_ui_utils/bug_report_url.py | 4 +--- release/scripts/modules/console_python.py | 7 ++----- tests/python/bl_pyapi_idprop_datablock.py | 3 +-- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/release/scripts/modules/bl_ui_utils/bug_report_url.py b/release/scripts/modules/bl_ui_utils/bug_report_url.py index 6755c2bad9d..37a52a5141c 100644 --- a/release/scripts/modules/bl_ui_utils/bug_report_url.py +++ b/release/scripts/modules/bl_ui_utils/bug_report_url.py @@ -59,10 +59,8 @@ def url_prefill_from_blender(*, addon_info=None): "\n" ) - fh.seek(0) - form_number = 2 if addon_info else 1 return ( "https://developer.blender.org/maniphest/task/edit/form/%i?description=" % form_number + - urllib.parse.quote(fh.read()) + urllib.parse.quote(fh.getvalue()) ) diff --git a/release/scripts/modules/console_python.py b/release/scripts/modules/console_python.py index 5cf55d3c3b5..a0feceabb3d 100644 --- a/release/scripts/modules/console_python.py +++ b/release/scripts/modules/console_python.py @@ -156,11 +156,8 @@ def execute(context, is_interactive): if _BPY_MAIN_OWN: sys.modules["__main__"] = main_mod_back - stdout.seek(0) - stderr.seek(0) - - output = stdout.read() - output_err = stderr.read() + output = stdout.getvalue() + output_err = stderr.getvalue() # cleanup sys.last_traceback = None diff --git a/tests/python/bl_pyapi_idprop_datablock.py b/tests/python/bl_pyapi_idprop_datablock.py index ba545aee151..b72b205ad9e 100644 --- a/tests/python/bl_pyapi_idprop_datablock.py +++ b/tests/python/bl_pyapi_idprop_datablock.py @@ -65,8 +65,7 @@ def expect_output_or_abort(*, fn, match_stderr=None, match_stdout=None): for (handle, match) in ((stdout, match_stdout), (stderr, match_stderr)): if not match: continue - handle.seek(0) - output = handle.read() + output = handle.getvalue() if not re.match(match, output): print_fail_msg_and_exit("%r not found in %r" % (match, output)) From 0beb358a69d0c9c5436995c2945eadbae95e8965 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Sun, 18 Dec 2022 07:08:57 -0800 Subject: [PATCH 0199/1522] Fix T103198: Missing bounds check for material_index attr in texpaint Texpaint now bounds checks material indices when looking up materials, in case the user has corrupted the material_index attribute somehow. We may wish to report this to the user somehow on entering texture paint mode. --- .../editors/sculpt_paint/paint_image_proj.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.cc b/source/blender/editors/sculpt_paint/paint_image_proj.cc index 4eeeb760b23..7c7ebbbb9fc 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.cc +++ b/source/blender/editors/sculpt_paint/paint_image_proj.cc @@ -545,10 +545,20 @@ static int project_paint_face_paint_tile(Image *ima, const float *uv) return 1001 + 10 * ty + tx; } +static Material *tex_get_material(const ProjPaintState *ps, int poly_i) +{ + int mat_nr = ps->material_indices == nullptr ? 0 : ps->material_indices[poly_i]; + if (mat_nr >= 0 && mat_nr <= ps->ob->totcol) { + return ps->mat_array[mat_nr]; + } + + return nullptr; +} + static TexPaintSlot *project_paint_face_paint_slot(const ProjPaintState *ps, int tri_index) { const int poly_i = ps->mlooptri_eval[tri_index].poly; - Material *ma = ps->mat_array[ps->material_indices == nullptr ? 0 : ps->material_indices[poly_i]]; + Material *ma = tex_get_material(ps, poly_i); return ma ? ma->texpaintslot + ma->paint_active_slot : nullptr; } @@ -559,7 +569,7 @@ static Image *project_paint_face_paint_image(const ProjPaintState *ps, int tri_i } const int poly_i = ps->mlooptri_eval[tri_index].poly; - Material *ma = ps->mat_array[ps->material_indices == nullptr ? 0 : ps->material_indices[poly_i]]; + Material *ma = tex_get_material(ps, poly_i); TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_active_slot : nullptr; return slot ? slot->ima : ps->canvas_ima; } @@ -567,14 +577,14 @@ static Image *project_paint_face_paint_image(const ProjPaintState *ps, int tri_i static TexPaintSlot *project_paint_face_clone_slot(const ProjPaintState *ps, int tri_index) { const int poly_i = ps->mlooptri_eval[tri_index].poly; - Material *ma = ps->mat_array[ps->material_indices == nullptr ? 0 : ps->material_indices[poly_i]]; + Material *ma = tex_get_material(ps, poly_i); return ma ? ma->texpaintslot + ma->paint_clone_slot : nullptr; } static Image *project_paint_face_clone_image(const ProjPaintState *ps, int tri_index) { const int poly_i = ps->mlooptri_eval[tri_index].poly; - Material *ma = ps->mat_array[ps->material_indices == nullptr ? 0 : ps->material_indices[poly_i]]; + Material *ma = tex_get_material(ps, poly_i); TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_clone_slot : nullptr; return slot ? slot->ima : ps->clone_ima; } From 17e266cd55ea58bd82094c3874254748a6d199be Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Sun, 18 Dec 2022 07:20:12 -0800 Subject: [PATCH 0200/1522] Cleanup: make paint_init_pivot an api method. I had forgotten about curves sculpt mode when I wrote this function. It just initializes the viewport pivot point to the evaluated object bounding box. Should be used inside the mode entry function. --- source/blender/editors/sculpt_paint/paint_image.cc | 2 +- source/blender/editors/sculpt_paint/paint_intern.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/sculpt_paint/paint_image.cc b/source/blender/editors/sculpt_paint/paint_image.cc index 1ab364c4877..a57287b924b 100644 --- a/source/blender/editors/sculpt_paint/paint_image.cc +++ b/source/blender/editors/sculpt_paint/paint_image.cc @@ -759,7 +759,7 @@ void PAINT_OT_sample_color(wmOperatorType *ot) /******************** texture paint toggle operator ********************/ -static void paint_init_pivot(Object *ob, Scene *scene) +void paint_init_pivot(Object *ob, Scene *scene) { UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 8a2c6955679..a3449e52225 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -517,6 +517,9 @@ enum eBlurKernelType; BlurKernel *paint_new_blur_kernel(struct Brush *br, bool proj); void paint_delete_blur_kernel(BlurKernel *); +/* Initialize viewport pivot from evaulated bounding box center of ob. */ +void paint_init_pivot(struct Object *ob, struct Scene *scene); + /* paint curve defines */ #define PAINT_CURVE_NUM_SEGMENTS 40 From 8666791b2e7542913e824a34eed2e579381377b0 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Sun, 18 Dec 2022 07:50:35 -0800 Subject: [PATCH 0201/1522] Fix T103261: Undo after mask extract doesn't restore active object --- source/blender/editors/mesh/editmesh_mask_extract.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c index 070f748c78e..bb4d745a677 100644 --- a/source/blender/editors/mesh/editmesh_mask_extract.c +++ b/source/blender/editors/mesh/editmesh_mask_extract.c @@ -37,6 +37,7 @@ #include "ED_object.h" #include "ED_screen.h" #include "ED_sculpt.h" +#include "ED_undo.h" #include "ED_view3d.h" #include "bmesh_tools.h" @@ -287,6 +288,16 @@ static int paint_mask_extract_exec(bContext *C, wmOperator *op) params.add_boundary_loop = RNA_boolean_get(op->ptr, "add_boundary_loop"); params.apply_shrinkwrap = RNA_boolean_get(op->ptr, "apply_shrinkwrap"); params.add_solidify = RNA_boolean_get(op->ptr, "add_solidify"); + + /* Push an undo step prior to extraction. + * Note: A second push happens after the operator due to + * the OPTYPE_UNDO flag; having an initial undo step here + * is just needed to preserve the active object pointer. + * + * Fixes T103261. + */ + ED_undo_push_op(C, op); + return geometry_extract_apply(C, op, geometry_extract_tag_masked_faces, ¶ms); } From 50c7eb14f455de9f932028861899d5d6b6f20527 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 18 Dec 2022 14:06:43 -0600 Subject: [PATCH 0202/1522] Fix T103321: NodeSocket.node is None in Node.copy callback Tag the topology cache dirty before Python can do arbitrary things in the RNA copy callback. --- source/blender/blenkernel/intern/node.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 9bc42879d78..84bf186367b 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -2326,6 +2326,10 @@ bNode *node_copy_with_mapping(bNodeTree *dst_tree, node_src.typeinfo->copyfunc(dst_tree, node_dst, &node_src); } + if (dst_tree) { + BKE_ntree_update_tag_node_new(dst_tree, node_dst); + } + /* Only call copy function when a copy is made for the main database, not * for cases like the dependency graph and localization. */ if (node_dst->typeinfo->copyfunc_api && !(flag & LIB_ID_CREATE_NO_MAIN)) { @@ -2335,10 +2339,6 @@ bNode *node_copy_with_mapping(bNodeTree *dst_tree, node_dst->typeinfo->copyfunc_api(&ptr, &node_src); } - if (dst_tree) { - BKE_ntree_update_tag_node_new(dst_tree, node_dst); - } - /* Reset the declaration of the new node. */ nodeDeclarationEnsure(dst_tree, node_dst); From f0ac5e8aec03f7d0ca07d3792e50da929159478b Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 18 Dec 2022 14:40:30 -0600 Subject: [PATCH 0203/1522] Cleanup: Move context.c to C++ --- source/blender/blenkernel/BKE_context.h | 2 +- source/blender/blenkernel/CMakeLists.txt | 2 +- .../intern/{context.c => context.cc} | 397 +++++++++--------- source/blender/python/BPY_extern.h | 7 - 4 files changed, 209 insertions(+), 199 deletions(-) rename source/blender/blenkernel/intern/{context.c => context.cc} (75%) diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index e1406e63ce1..90597a3e273 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -99,7 +99,7 @@ typedef struct bContextStore { } bContextStore; /* for the context's rna mode enum - * keep aligned with data_mode_strings in context.c */ + * keep aligned with data_mode_strings in context.cc */ typedef enum eContextObjectMode { CTX_MODE_EDIT_MESH = 0, CTX_MODE_EDIT_CURVE, diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index d645408c6e9..c12c0c06ed8 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -97,7 +97,7 @@ set(SRC intern/colortools.c intern/compute_contexts.cc intern/constraint.c - intern/context.c + intern/context.cc intern/cpp_types.cc intern/crazyspace.cc intern/cryptomatte.cc diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.cc similarity index 75% rename from source/blender/blenkernel/intern/context.c rename to source/blender/blenkernel/intern/context.cc index 0ddd53ccb99..4469f22346a 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.cc @@ -4,9 +4,9 @@ * \ingroup bke */ -#include -#include -#include +#include +#include +#include #include "MEM_guardedalloc.h" @@ -58,15 +58,15 @@ struct bContext { /* windowmanager context */ struct { - struct wmWindowManager *manager; - struct wmWindow *window; - struct WorkSpace *workspace; - struct bScreen *screen; - struct ScrArea *area; - struct ARegion *region; - struct ARegion *menu; - struct wmGizmoGroup *gizmo_group; - struct bContextStore *store; + wmWindowManager *manager; + wmWindow *window; + WorkSpace *workspace; + bScreen *screen; + ScrArea *area; + ARegion *region; + ARegion *menu; + wmGizmoGroup *gizmo_group; + bContextStore *store; /* Operator poll. */ /** @@ -82,8 +82,8 @@ struct bContext { /* data context */ struct { - struct Main *main; - struct Scene *scene; + Main *main; + Scene *scene; int recursion; /** True if python is initialized. */ @@ -101,14 +101,15 @@ struct bContext { bContext *CTX_create(void) { - bContext *C = MEM_callocN(sizeof(bContext), "bContext"); + bContext *C = MEM_cnew(__func__); return C; } bContext *CTX_copy(const bContext *C) { - bContext *newC = MEM_dupallocN((void *)C); + bContext *newC = MEM_new(__func__); + *newC = *C; memset(&newC->wm.operator_poll_msg_dyn_params, 0, sizeof(newC->wm.operator_poll_msg_dyn_params)); @@ -129,22 +130,23 @@ bContextStore *CTX_store_add(ListBase *contexts, const char *name, const Pointer { /* ensure we have a context to put the entry in, if it was already used * we have to copy the context to ensure */ - bContextStore *ctx = contexts->last; + bContextStore *ctx = static_cast(contexts->last); if (!ctx || ctx->used) { if (ctx) { bContextStore *lastctx = ctx; - ctx = MEM_dupallocN(lastctx); + ctx = MEM_new(__func__); + *ctx = *lastctx; BLI_duplicatelist(&ctx->entries, &lastctx->entries); } else { - ctx = MEM_callocN(sizeof(bContextStore), "bContextStore"); + ctx = MEM_cnew(__func__); } BLI_addtail(contexts, ctx); } - bContextStoreEntry *entry = MEM_callocN(sizeof(bContextStoreEntry), "bContextStoreEntry"); + bContextStoreEntry *entry = MEM_cnew(__func__); BLI_strncpy(entry->name, name, sizeof(entry->name)); entry->ptr = *ptr; @@ -157,23 +159,25 @@ bContextStore *CTX_store_add_all(ListBase *contexts, bContextStore *context) { /* ensure we have a context to put the entries in, if it was already used * we have to copy the context to ensure */ - bContextStore *ctx = contexts->last; + bContextStore *ctx = static_cast(contexts->last); if (!ctx || ctx->used) { if (ctx) { bContextStore *lastctx = ctx; - ctx = MEM_dupallocN(lastctx); + ctx = MEM_new(__func__); + *ctx = *lastctx; BLI_duplicatelist(&ctx->entries, &lastctx->entries); } else { - ctx = MEM_callocN(sizeof(bContextStore), "bContextStore"); + ctx = MEM_cnew(__func__); } BLI_addtail(contexts, ctx); } LISTBASE_FOREACH (bContextStoreEntry *, tentry, &context->entries) { - bContextStoreEntry *entry = MEM_dupallocN(tentry); + bContextStoreEntry *entry = MEM_cnew(__func__); + *entry = *tentry; BLI_addtail(&ctx->entries, entry); } @@ -194,21 +198,22 @@ const PointerRNA *CTX_store_ptr_lookup(const bContextStore *store, const char *name, const StructRNA *type) { - bContextStoreEntry *entry = BLI_rfindstring( - &store->entries, name, offsetof(bContextStoreEntry, name)); + bContextStoreEntry *entry = static_cast( + BLI_rfindstring(&store->entries, name, offsetof(bContextStoreEntry, name))); if (!entry) { - return NULL; + return nullptr; } if (type && !RNA_struct_is_a(entry->ptr.type, type)) { - return NULL; + return nullptr; } return &entry->ptr; } bContextStore *CTX_store_copy(bContextStore *store) { - bContextStore *ctx = MEM_dupallocN(store); + bContextStore *ctx = MEM_cnew(__func__); + *ctx = *store; BLI_duplicatelist(&ctx->entries, &store->entries); return ctx; @@ -223,7 +228,7 @@ void CTX_store_free(bContextStore *store) void CTX_store_free_list(ListBase *contexts) { bContextStore *ctx; - while ((ctx = BLI_pophead(contexts))) { + while ((ctx = static_cast(BLI_pophead(contexts)))) { CTX_store_free(ctx); } } @@ -248,7 +253,7 @@ void *CTX_py_dict_get_orig(const bContext *C) return C->data.py_context_orig; } -void CTX_py_state_push(bContext *C, struct bContext_PyState *pystate, void *value) +void CTX_py_state_push(bContext *C, bContext_PyState *pystate, void *value) { pystate->py_context = C->data.py_context; pystate->py_context_orig = C->data.py_context_orig; @@ -256,7 +261,7 @@ void CTX_py_state_push(bContext *C, struct bContext_PyState *pystate, void *valu C->data.py_context = value; C->data.py_context_orig = value; } -void CTX_py_state_pop(bContext *C, struct bContext_PyState *pystate) +void CTX_py_state_pop(bContext *C, bContext_PyState *pystate) { C->data.py_context = pystate->py_context; C->data.py_context_orig = pystate->py_context_orig; @@ -300,7 +305,7 @@ static void *ctx_wm_python_context_get(const bContext *C, /* don't allow UI context access from non-main threads */ if (!BLI_thread_is_main()) { - return NULL; + return nullptr; } return fall_through; @@ -318,14 +323,14 @@ static eContextResult ctx_data_get(bContext *C, const char *member, bContextData #ifdef WITH_PYTHON if (CTX_py_dict_get(C)) { if (BPY_context_member_get(C, member, result)) { - return 1; + return CTX_RESULT_OK; } } #endif /* don't allow UI context access from non-main threads */ if (!BLI_thread_is_main()) { - return done; + return CTX_RESULT_MEMBER_NOT_FOUND; } /* we check recursion to ensure that we do not get infinite @@ -340,7 +345,7 @@ static eContextResult ctx_data_get(bContext *C, const char *member, bContextData if (done != 1 && recursion < 1 && C->wm.store) { C->data.recursion = 1; - const PointerRNA *ptr = CTX_store_ptr_lookup(C->wm.store, member, NULL); + const PointerRNA *ptr = CTX_store_ptr_lookup(C->wm.store, member, nullptr); if (ptr) { result->ptr = *ptr; @@ -367,7 +372,7 @@ static eContextResult ctx_data_get(bContext *C, const char *member, bContextData } if (done != 1 && recursion < 4 && (screen = CTX_wm_screen(C))) { - bContextDataCallback cb = screen->context; + bContextDataCallback cb = reinterpret_cast(screen->context); C->data.recursion = 4; if (cb) { ret = cb(C, member, result); @@ -379,7 +384,7 @@ static eContextResult ctx_data_get(bContext *C, const char *member, bContextData C->data.recursion = recursion; - return done; + return eContextResult(done); } static void *ctx_data_pointer_get(const bContext *C, const char *member) @@ -390,14 +395,14 @@ static void *ctx_data_pointer_get(const bContext *C, const char *member) return result.ptr.data; } - return NULL; + return nullptr; } static bool ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer) { - /* if context is NULL, pointer must be NULL too and that is a valid return */ - if (C == NULL) { - *pointer = NULL; + /* if context is nullptr, pointer must be nullptr too and that is a valid return */ + if (C == nullptr) { + *pointer = nullptr; return true; } @@ -408,7 +413,7 @@ static bool ctx_data_pointer_verify(const bContext *C, const char *member, void return true; } - *pointer = NULL; + *pointer = nullptr; return false; } @@ -445,10 +450,11 @@ static int ctx_data_base_collection_get(const bContext *C, const char *member, L bool ok = false; CollectionPointerLink *ctx_object; - for (ctx_object = ctx_object_list.first; ctx_object; ctx_object = ctx_object->next) { - Object *ob = ctx_object->ptr.data; + for (ctx_object = static_cast(ctx_object_list.first); ctx_object; + ctx_object = ctx_object->next) { + Object *ob = static_cast(ctx_object->ptr.data); Base *base = BKE_view_layer_base_find(view_layer, ob); - if (base != NULL) { + if (base != nullptr) { CTX_data_list_add(&result, &scene->id, &RNA_ObjectBase, base); ok = true; } @@ -509,7 +515,7 @@ ListBase CTX_data_collection_get(const bContext *C, const char *member) return result.list; } - ListBase list = {NULL, NULL}; + ListBase list = {nullptr, nullptr}; return list; } @@ -545,7 +551,7 @@ static void data_dir_add(ListBase *lb, const char *member, const bool use_all) return; } - link = MEM_callocN(sizeof(LinkData), "LinkData"); + link = MEM_cnew(__func__); link->data = (void *)member; BLI_addtail(lb, link); } @@ -570,7 +576,7 @@ ListBase CTX_data_dir_get_ex(const bContext *C, PropertyRNA *iterprop; PointerRNA ctx_ptr; - RNA_pointer_create(NULL, &RNA_Context, (void *)C, &ctx_ptr); + RNA_pointer_create(nullptr, &RNA_Context, (void *)C, &ctx_ptr); iterprop = RNA_struct_iterator_property(ctx_ptr.type); @@ -588,7 +594,8 @@ ListBase CTX_data_dir_get_ex(const bContext *C, if (use_store && C->wm.store) { bContextStoreEntry *entry; - for (entry = C->wm.store->entries.first; entry; entry = entry->next) { + for (entry = static_cast(C->wm.store->entries.first); entry; + entry = entry->next) { data_dir_add(&lb, entry->name, use_all); } } @@ -613,7 +620,7 @@ ListBase CTX_data_dir_get_ex(const bContext *C, } } if ((screen = CTX_wm_screen(C)) && screen->context) { - bContextDataCallback cb = screen->context; + bContextDataCallback cb = reinterpret_cast(screen->context); memset(&result, 0, sizeof(result)); cb(C, "", &result); @@ -659,7 +666,7 @@ void CTX_data_pointer_set_ptr(bContextDataResult *result, const PointerRNA *ptr) void CTX_data_id_list_add(bContextDataResult *result, ID *id) { - CollectionPointerLink *link = MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_id_list_add"); + CollectionPointerLink *link = MEM_cnew(__func__); RNA_id_pointer_create(id, &link->ptr); BLI_addtail(&result->list, link); @@ -667,7 +674,7 @@ void CTX_data_id_list_add(bContextDataResult *result, ID *id) void CTX_data_list_add(bContextDataResult *result, ID *id, StructRNA *type, void *data) { - CollectionPointerLink *link = MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_list_add"); + CollectionPointerLink *link = MEM_cnew(__func__); RNA_pointer_create(id, type, data, &link->ptr); BLI_addtail(&result->list, link); @@ -675,7 +682,7 @@ void CTX_data_list_add(bContextDataResult *result, ID *id, StructRNA *type, void void CTX_data_list_add_ptr(bContextDataResult *result, const PointerRNA *ptr) { - CollectionPointerLink *link = MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_list_add"); + CollectionPointerLink *link = MEM_cnew(__func__); link->ptr = *ptr; BLI_addtail(&result->list, link); @@ -718,77 +725,79 @@ wmWindowManager *CTX_wm_manager(const bContext *C) bool CTX_wm_interface_locked(const bContext *C) { - return (bool)C->wm.manager->is_interface_locked; + return bool(C->wm.manager->is_interface_locked); } wmWindow *CTX_wm_window(const bContext *C) { - return ctx_wm_python_context_get(C, "window", &RNA_Window, C->wm.window); + return static_cast( + ctx_wm_python_context_get(C, "window", &RNA_Window, C->wm.window)); } WorkSpace *CTX_wm_workspace(const bContext *C) { - return ctx_wm_python_context_get(C, "workspace", &RNA_WorkSpace, C->wm.workspace); + return static_cast( + ctx_wm_python_context_get(C, "workspace", &RNA_WorkSpace, C->wm.workspace)); } bScreen *CTX_wm_screen(const bContext *C) { - return ctx_wm_python_context_get(C, "screen", &RNA_Screen, C->wm.screen); + return static_cast(ctx_wm_python_context_get(C, "screen", &RNA_Screen, C->wm.screen)); } ScrArea *CTX_wm_area(const bContext *C) { - return ctx_wm_python_context_get(C, "area", &RNA_Area, C->wm.area); + return static_cast(ctx_wm_python_context_get(C, "area", &RNA_Area, C->wm.area)); } SpaceLink *CTX_wm_space_data(const bContext *C) { ScrArea *area = CTX_wm_area(C); - return (area) ? area->spacedata.first : NULL; + return (area) ? static_cast(area->spacedata.first) : nullptr; } ARegion *CTX_wm_region(const bContext *C) { - return ctx_wm_python_context_get(C, "region", &RNA_Region, C->wm.region); + return static_cast(ctx_wm_python_context_get(C, "region", &RNA_Region, C->wm.region)); } void *CTX_wm_region_data(const bContext *C) { ARegion *region = CTX_wm_region(C); - return (region) ? region->regiondata : NULL; + return (region) ? region->regiondata : nullptr; } -struct ARegion *CTX_wm_menu(const bContext *C) +ARegion *CTX_wm_menu(const bContext *C) { return C->wm.menu; } -struct wmGizmoGroup *CTX_wm_gizmo_group(const bContext *C) +wmGizmoGroup *CTX_wm_gizmo_group(const bContext *C) { return C->wm.gizmo_group; } -struct wmMsgBus *CTX_wm_message_bus(const bContext *C) +wmMsgBus *CTX_wm_message_bus(const bContext *C) { - return C->wm.manager ? C->wm.manager->message_bus : NULL; + return C->wm.manager ? C->wm.manager->message_bus : nullptr; } -struct ReportList *CTX_wm_reports(const bContext *C) +ReportList *CTX_wm_reports(const bContext *C) { if (C->wm.manager) { return &(C->wm.manager->reports); } - return NULL; + return nullptr; } View3D *CTX_wm_view3d(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_VIEW3D) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } RegionView3D *CTX_wm_region_view3d(const bContext *C) @@ -798,163 +807,163 @@ RegionView3D *CTX_wm_region_view3d(const bContext *C) if (area && area->spacetype == SPACE_VIEW3D) { if (region && region->regiontype == RGN_TYPE_WINDOW) { - return region->regiondata; + return static_cast(region->regiondata); } } - return NULL; + return nullptr; } -struct SpaceText *CTX_wm_space_text(const bContext *C) +SpaceText *CTX_wm_space_text(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_TEXT) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceConsole *CTX_wm_space_console(const bContext *C) +SpaceConsole *CTX_wm_space_console(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_CONSOLE) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceImage *CTX_wm_space_image(const bContext *C) +SpaceImage *CTX_wm_space_image(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_IMAGE) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceProperties *CTX_wm_space_properties(const bContext *C) +SpaceProperties *CTX_wm_space_properties(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_PROPERTIES) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceFile *CTX_wm_space_file(const bContext *C) +SpaceFile *CTX_wm_space_file(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_FILE) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceSeq *CTX_wm_space_seq(const bContext *C) +SpaceSeq *CTX_wm_space_seq(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_SEQ) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceOutliner *CTX_wm_space_outliner(const bContext *C) +SpaceOutliner *CTX_wm_space_outliner(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_OUTLINER) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceNla *CTX_wm_space_nla(const bContext *C) +SpaceNla *CTX_wm_space_nla(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_NLA) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceNode *CTX_wm_space_node(const bContext *C) +SpaceNode *CTX_wm_space_node(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_NODE) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceGraph *CTX_wm_space_graph(const bContext *C) +SpaceGraph *CTX_wm_space_graph(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_GRAPH) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceAction *CTX_wm_space_action(const bContext *C) +SpaceAction *CTX_wm_space_action(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_ACTION) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceInfo *CTX_wm_space_info(const bContext *C) +SpaceInfo *CTX_wm_space_info(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_INFO) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C) +SpaceUserPref *CTX_wm_space_userpref(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_USERPREF) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceClip *CTX_wm_space_clip(const bContext *C) +SpaceClip *CTX_wm_space_clip(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_CLIP) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceTopBar *CTX_wm_space_topbar(const bContext *C) +SpaceTopBar *CTX_wm_space_topbar(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_TOPBAR) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } -struct SpaceSpreadsheet *CTX_wm_space_spreadsheet(const bContext *C) +SpaceSpreadsheet *CTX_wm_space_spreadsheet(const bContext *C) { ScrArea *area = CTX_wm_area(C); if (area && area->spacetype == SPACE_SPREADSHEET) { - return area->spacedata.first; + return static_cast(area->spacedata.first); } - return NULL; + return nullptr; } void CTX_wm_manager_set(bContext *C, wmWindowManager *wm) { C->wm.manager = wm; - C->wm.window = NULL; - C->wm.screen = NULL; - C->wm.area = NULL; - C->wm.region = NULL; + C->wm.window = nullptr; + C->wm.screen = nullptr; + C->wm.area = nullptr; + C->wm.region = nullptr; } #ifdef WITH_PYTHON @@ -970,14 +979,16 @@ void CTX_wm_window_set(bContext *C, wmWindow *win) if (win) { C->data.scene = win->scene; } - C->wm.workspace = (win) ? BKE_workspace_active_get(win->workspace_hook) : NULL; - C->wm.screen = (win) ? BKE_workspace_active_screen_get(win->workspace_hook) : NULL; - C->wm.area = NULL; - C->wm.region = NULL; + C->wm.workspace = (win) ? BKE_workspace_active_get(win->workspace_hook) : nullptr; + C->wm.screen = (win) ? BKE_workspace_active_screen_get(win->workspace_hook) : nullptr; + C->wm.area = nullptr; + C->wm.region = nullptr; #ifdef WITH_PYTHON - if (C->data.py_context != NULL) { - BPY_context_dict_clear_members(C, PYCTX_WINDOW_MEMBERS); + if (C->data.py_context != nullptr) { + const char *members[] = {PYCTX_WINDOW_MEMBERS}; + BPY_context_dict_clear_members_array( + &C->data.py_context, C->data.py_context_orig, members, ARRAY_SIZE(members)); } #endif } @@ -985,12 +996,14 @@ void CTX_wm_window_set(bContext *C, wmWindow *win) void CTX_wm_screen_set(bContext *C, bScreen *screen) { C->wm.screen = screen; - C->wm.area = NULL; - C->wm.region = NULL; + C->wm.area = nullptr; + C->wm.region = nullptr; #ifdef WITH_PYTHON - if (C->data.py_context != NULL) { - BPY_context_dict_clear_members(C, PYCTX_SCREEN_MEMBERS); + if (C->data.py_context != nullptr) { + const char *members[] = {PYCTX_SCREEN_MEMBERS}; + BPY_context_dict_clear_members_array( + &C->data.py_context, C->data.py_context_orig, members, ARRAY_SIZE(members)); } #endif } @@ -998,11 +1011,13 @@ void CTX_wm_screen_set(bContext *C, bScreen *screen) void CTX_wm_area_set(bContext *C, ScrArea *area) { C->wm.area = area; - C->wm.region = NULL; + C->wm.region = nullptr; #ifdef WITH_PYTHON - if (C->data.py_context != NULL) { - BPY_context_dict_clear_members(C, PYCTX_AREA_MEMBERS); + if (C->data.py_context != nullptr) { + const char *members[] = {PYCTX_AREA_MEMBERS}; + BPY_context_dict_clear_members_array( + &C->data.py_context, C->data.py_context_orig, members, ARRAY_SIZE(members)); } #endif } @@ -1012,8 +1027,10 @@ void CTX_wm_region_set(bContext *C, ARegion *region) C->wm.region = region; #ifdef WITH_PYTHON - if (C->data.py_context != NULL) { - BPY_context_dict_clear_members(C, PYCTX_REGION_MEMBERS); + if (C->data.py_context != nullptr) { + const char *members[] = {PYCTX_REGION_MEMBERS}; + BPY_context_dict_clear_members_array( + &C->data.py_context, C->data.py_context_orig, members, ARRAY_SIZE(members)); } #endif } @@ -1023,22 +1040,22 @@ void CTX_wm_menu_set(bContext *C, ARegion *menu) C->wm.menu = menu; } -void CTX_wm_gizmo_group_set(bContext *C, struct wmGizmoGroup *gzgroup) +void CTX_wm_gizmo_group_set(bContext *C, wmGizmoGroup *gzgroup) { C->wm.gizmo_group = gzgroup; } void CTX_wm_operator_poll_msg_clear(bContext *C) { - struct bContextPollMsgDyn_Params *params = &C->wm.operator_poll_msg_dyn_params; - if (params->free_fn != NULL) { + bContextPollMsgDyn_Params *params = &C->wm.operator_poll_msg_dyn_params; + if (params->free_fn != nullptr) { params->free_fn(C, params->user_data); } - params->get_fn = NULL; - params->free_fn = NULL; - params->user_data = NULL; + params->get_fn = nullptr; + params->free_fn = nullptr; + params->user_data = nullptr; - C->wm.operator_poll_msg = NULL; + C->wm.operator_poll_msg = nullptr; } void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg) { @@ -1047,8 +1064,7 @@ void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg) C->wm.operator_poll_msg = msg; } -void CTX_wm_operator_poll_msg_set_dynamic(bContext *C, - const struct bContextPollMsgDyn_Params *params) +void CTX_wm_operator_poll_msg_set_dynamic(bContext *C, const bContextPollMsgDyn_Params *params) { CTX_wm_operator_poll_msg_clear(C); @@ -1057,10 +1073,10 @@ void CTX_wm_operator_poll_msg_set_dynamic(bContext *C, const char *CTX_wm_operator_poll_msg_get(bContext *C, bool *r_free) { - struct bContextPollMsgDyn_Params *params = &C->wm.operator_poll_msg_dyn_params; - if (params->get_fn != NULL) { + bContextPollMsgDyn_Params *params = &C->wm.operator_poll_msg_dyn_params; + if (params->get_fn != nullptr) { char *msg = params->get_fn(C, params->user_data); - if (msg != NULL) { + if (msg != nullptr) { *r_free = true; } return msg; @@ -1075,7 +1091,7 @@ const char *CTX_wm_operator_poll_msg_get(bContext *C, bool *r_free) Main *CTX_data_main(const bContext *C) { Main *bmain; - if (ctx_data_pointer_verify(C, "blend_data", (void *)&bmain)) { + if (ctx_data_pointer_verify(C, "blend_data", (void **)&bmain)) { return bmain; } @@ -1091,7 +1107,7 @@ void CTX_data_main_set(bContext *C, Main *bmain) Scene *CTX_data_scene(const bContext *C) { Scene *scene; - if (ctx_data_pointer_verify(C, "scene", (void *)&scene)) { + if (ctx_data_pointer_verify(C, "scene", (void **)&scene)) { return scene; } @@ -1102,7 +1118,7 @@ ViewLayer *CTX_data_view_layer(const bContext *C) { ViewLayer *view_layer; - if (ctx_data_pointer_verify(C, "view_layer", (void *)&view_layer)) { + if (ctx_data_pointer_verify(C, "view_layer", (void **)&view_layer)) { return view_layer; } @@ -1129,7 +1145,7 @@ LayerCollection *CTX_data_layer_collection(const bContext *C) ViewLayer *view_layer = CTX_data_view_layer(C); LayerCollection *layer_collection; - if (ctx_data_pointer_verify(C, "layer_collection", (void *)&layer_collection)) { + if (ctx_data_pointer_verify(C, "layer_collection", (void **)&layer_collection)) { if (BKE_view_layer_has_collection(view_layer, layer_collection->collection)) { return layer_collection; } @@ -1142,7 +1158,7 @@ LayerCollection *CTX_data_layer_collection(const bContext *C) Collection *CTX_data_collection(const bContext *C) { Collection *collection; - if (ctx_data_pointer_verify(C, "collection", (void *)&collection)) { + if (ctx_data_pointer_verify(C, "collection", (void **)&collection)) { return collection; } @@ -1229,8 +1245,8 @@ enum eContextObjectMode CTX_data_mode_enum_ex(const Object *obedit, enum eContextObjectMode CTX_data_mode_enum(const bContext *C) { Object *obedit = CTX_data_edit_object(C); - Object *obact = obedit ? NULL : CTX_data_active_object(C); - return CTX_data_mode_enum_ex(obedit, obact, obact ? obact->mode : OB_MODE_OBJECT); + Object *obact = obedit ? nullptr : CTX_data_active_object(C); + return CTX_data_mode_enum_ex(obedit, obact, obact ? eObjectMode(obact->mode) : OB_MODE_OBJECT); } /** @@ -1260,7 +1276,7 @@ static const char *data_mode_strings[] = { "greasepencil_weight", "greasepencil_vertex", "curves_sculpt", - NULL, + nullptr, }; BLI_STATIC_ASSERT(ARRAY_SIZE(data_mode_strings) == CTX_MODE_NUM + 1, "Must have a string for each context mode") @@ -1274,8 +1290,9 @@ void CTX_data_scene_set(bContext *C, Scene *scene) C->data.scene = scene; #ifdef WITH_PYTHON - if (C->data.py_context != NULL) { - BPY_context_dict_clear_members(C, "scene"); + if (C->data.py_context != nullptr) { + const char *members[] = {"scene"}; + BPY_context_dict_clear_members_array(&C->data.py_context, C->data.py_context_orig, members, 1); } #endif } @@ -1288,7 +1305,7 @@ ToolSettings *CTX_data_tool_settings(const bContext *C) return scene->toolsettings; } - return NULL; + return nullptr; } bool CTX_data_selected_ids(const bContext *C, ListBase *list) @@ -1351,17 +1368,17 @@ bool CTX_data_selectable_bases(const bContext *C, ListBase *list) return ctx_data_base_collection_get(C, "selectable_objects", list); } -struct Object *CTX_data_active_object(const bContext *C) +Object *CTX_data_active_object(const bContext *C) { - return ctx_data_pointer_get(C, "active_object"); + return static_cast(ctx_data_pointer_get(C, "active_object")); } -struct Base *CTX_data_active_base(const bContext *C) +Base *CTX_data_active_base(const bContext *C) { - Object *ob = ctx_data_pointer_get(C, "active_object"); + Object *ob = CTX_data_active_object(C); - if (ob == NULL) { - return NULL; + if (ob == nullptr) { + return nullptr; } const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); @@ -1369,39 +1386,39 @@ struct Base *CTX_data_active_base(const bContext *C) return BKE_view_layer_base_find(view_layer, ob); } -struct Object *CTX_data_edit_object(const bContext *C) +Object *CTX_data_edit_object(const bContext *C) { - return ctx_data_pointer_get(C, "edit_object"); + return static_cast(ctx_data_pointer_get(C, "edit_object")); } -struct Image *CTX_data_edit_image(const bContext *C) +Image *CTX_data_edit_image(const bContext *C) { - return ctx_data_pointer_get(C, "edit_image"); + return static_cast(ctx_data_pointer_get(C, "edit_image")); } -struct Text *CTX_data_edit_text(const bContext *C) +Text *CTX_data_edit_text(const bContext *C) { - return ctx_data_pointer_get(C, "edit_text"); + return static_cast(ctx_data_pointer_get(C, "edit_text")); } -struct MovieClip *CTX_data_edit_movieclip(const bContext *C) +MovieClip *CTX_data_edit_movieclip(const bContext *C) { - return ctx_data_pointer_get(C, "edit_movieclip"); + return static_cast(ctx_data_pointer_get(C, "edit_movieclip")); } -struct Mask *CTX_data_edit_mask(const bContext *C) +Mask *CTX_data_edit_mask(const bContext *C) { - return ctx_data_pointer_get(C, "edit_mask"); + return static_cast(ctx_data_pointer_get(C, "edit_mask")); } -struct EditBone *CTX_data_active_bone(const bContext *C) +EditBone *CTX_data_active_bone(const bContext *C) { - return ctx_data_pointer_get(C, "active_bone"); + return static_cast(ctx_data_pointer_get(C, "active_bone")); } -struct CacheFile *CTX_data_edit_cachefile(const bContext *C) +CacheFile *CTX_data_edit_cachefile(const bContext *C) { - return ctx_data_pointer_get(C, "edit_cachefile"); + return static_cast(ctx_data_pointer_get(C, "edit_cachefile")); } bool CTX_data_selected_bones(const bContext *C, ListBase *list) @@ -1424,9 +1441,9 @@ bool CTX_data_editable_bones(const bContext *C, ListBase *list) return ctx_data_collection_get(C, "editable_bones", list); } -struct bPoseChannel *CTX_data_active_pose_bone(const bContext *C) +bPoseChannel *CTX_data_active_pose_bone(const bContext *C) { - return ctx_data_pointer_get(C, "active_pose_bone"); + return static_cast(ctx_data_pointer_get(C, "active_pose_bone")); } bool CTX_data_selected_pose_bones(const bContext *C, ListBase *list) @@ -1446,17 +1463,17 @@ bool CTX_data_visible_pose_bones(const bContext *C, ListBase *list) bGPdata *CTX_data_gpencil_data(const bContext *C) { - return ctx_data_pointer_get(C, "gpencil_data"); + return static_cast(ctx_data_pointer_get(C, "gpencil_data")); } bGPDlayer *CTX_data_active_gpencil_layer(const bContext *C) { - return ctx_data_pointer_get(C, "active_gpencil_layer"); + return static_cast(ctx_data_pointer_get(C, "active_gpencil_layer")); } bGPDframe *CTX_data_active_gpencil_frame(const bContext *C) { - return ctx_data_pointer_get(C, "active_gpencil_frame"); + return static_cast(ctx_data_pointer_get(C, "active_gpencil_frame")); } bool CTX_data_visible_gpencil_layers(const bContext *C, ListBase *list) @@ -1476,7 +1493,7 @@ bool CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list) const AssetLibraryReference *CTX_wm_asset_library_ref(const bContext *C) { - return ctx_data_pointer_get(C, "asset_library_ref"); + return static_cast(ctx_data_pointer_get(C, "asset_library_ref")); } AssetHandle CTX_wm_asset_handle(const bContext *C, bool *r_is_valid) @@ -1497,11 +1514,11 @@ AssetHandle CTX_wm_asset_handle(const bContext *C, bool *r_is_valid) (FileDirEntry *)CTX_data_pointer_get_type(C, "active_file", &RNA_FileSelectEntry).data; if (file && file->asset) { *r_is_valid = true; - return (AssetHandle){.file_data = file}; + AssetHandle{file}; } *r_is_valid = false; - return (AssetHandle){0}; + return AssetHandle{nullptr}; } Depsgraph *CTX_data_depsgraph_pointer(const bContext *C) diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h index aecefa97423..cb8dd0a8bc2 100644 --- a/source/blender/python/BPY_extern.h +++ b/source/blender/python/BPY_extern.h @@ -106,11 +106,6 @@ void BPY_context_set(struct bContext *C); */ void BPY_context_update(struct bContext *C); -#define BPY_context_dict_clear_members(C, ...) \ - BPY_context_dict_clear_members_array(&((C)->data.py_context), \ - (C)->data.py_context_orig, \ - ((const char *[]){__VA_ARGS__}), \ - VA_NARGS_COUNT(__VA_ARGS__)) /** * Use for `CTX_*_set(..)` functions need to set values which are later read back as expected. * In this case we don't want the Python context to override the values as it causes problems @@ -118,8 +113,6 @@ void BPY_context_update(struct bContext *C); * * \param dict_p: A pointer to #bContext.data.py_context so we can assign a new value. * \param dict_orig: The value of #bContext.data.py_context_orig to check if we need to copy. - * - * \note Typically accessed via #BPY_context_dict_clear_members macro. */ void BPY_context_dict_clear_members_array(void **dict_p, void *dict_orig, From d59f6ffdcb4a008e5d3a8a2638fea40cf19912a0 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 18 Dec 2022 18:35:40 -0600 Subject: [PATCH 0204/1522] Fix: Wrong const iterator type for blender::Vector --- source/blender/blenlib/BLI_vector.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh index be594377eb3..8860bb05127 100644 --- a/source/blender/blenlib/BLI_vector.hh +++ b/source/blender/blenlib/BLI_vector.hh @@ -902,11 +902,11 @@ class Vector { std::reverse_iterator rbegin() const { - return std::reverse_iterator(this->end()); + return std::reverse_iterator(this->end()); } std::reverse_iterator rend() const { - return std::reverse_iterator(this->begin()); + return std::reverse_iterator(this->begin()); } /** From 7d7e90ca685954409ece007d03d2e93860a6cef7 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 18 Dec 2022 19:13:15 -0600 Subject: [PATCH 0205/1522] UI: Use vector instead of linked lists for context store Duplicating context lists took a measurable amount of time when drawing large node trees in the node editor. Instead of using a linked list of entries, which results in many small allocations, use a vector. Also, use std::string and StringRefNull instead of char buffers and pointers. --- source/blender/blenkernel/BKE_context.h | 41 ++++++---- source/blender/blenkernel/intern/context.cc | 74 ++++++------------- source/blender/editors/interface/interface.cc | 4 +- 3 files changed, 53 insertions(+), 66 deletions(-) diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 90597a3e273..f836b98f3b2 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -16,6 +16,11 @@ #include "DNA_object_enums.h" #include "RNA_types.h" +#ifdef __cplusplus +# include "BLI_string_ref.hh" +# include "BLI_vector.hh" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -84,19 +89,22 @@ typedef int /*eContextResult*/ (*bContextDataCallback)(const bContext *C, const char *member, bContextDataResult *result); -typedef struct bContextStoreEntry { - struct bContextStoreEntry *next, *prev; +#ifdef __cplusplus - char name[128]; +struct bContextStoreEntry { + std::string name; PointerRNA ptr; -} bContextStoreEntry; +}; -typedef struct bContextStore { - struct bContextStore *next, *prev; +struct bContextStore { + bContextStore *next = nullptr; + bContextStore *prev = nullptr; - ListBase entries; - bool used; -} bContextStore; + blender::Vector entries; + bool used = false; +}; + +#endif /* for the context's rna mode enum * keep aligned with data_mode_strings in context.cc */ @@ -132,18 +140,23 @@ void CTX_free(bContext *C); bContext *CTX_copy(const bContext *C); +#ifdef __cplusplus + /* Stored Context */ -bContextStore *CTX_store_add(ListBase *contexts, const char *name, const PointerRNA *ptr); +bContextStore *CTX_store_add(ListBase *contexts, + blender::StringRefNull name, + const PointerRNA *ptr); bContextStore *CTX_store_add_all(ListBase *contexts, bContextStore *context); bContextStore *CTX_store_get(bContext *C); void CTX_store_set(bContext *C, bContextStore *store); const PointerRNA *CTX_store_ptr_lookup(const bContextStore *store, - const char *name, - const StructRNA *type CPP_ARG_DEFAULT(nullptr)); -bContextStore *CTX_store_copy(bContextStore *store); + blender::StringRefNull name, + const StructRNA *type = nullptr); +bContextStore *CTX_store_copy(const bContextStore *store); void CTX_store_free(bContextStore *store); -void CTX_store_free_list(ListBase *contexts); + +#endif /* need to store if python is initialized or not */ bool CTX_py_init_get(bContext *C); diff --git a/source/blender/blenkernel/intern/context.cc b/source/blender/blenkernel/intern/context.cc index 4469f22346a..8d8e96f26c8 100644 --- a/source/blender/blenkernel/intern/context.cc +++ b/source/blender/blenkernel/intern/context.cc @@ -126,7 +126,9 @@ void CTX_free(bContext *C) /* store */ -bContextStore *CTX_store_add(ListBase *contexts, const char *name, const PointerRNA *ptr) +bContextStore *CTX_store_add(ListBase *contexts, + const blender::StringRefNull name, + const PointerRNA *ptr) { /* ensure we have a context to put the entry in, if it was already used * we have to copy the context to ensure */ @@ -134,23 +136,16 @@ bContextStore *CTX_store_add(ListBase *contexts, const char *name, const Pointer if (!ctx || ctx->used) { if (ctx) { - bContextStore *lastctx = ctx; - ctx = MEM_new(__func__); - *ctx = *lastctx; - BLI_duplicatelist(&ctx->entries, &lastctx->entries); + ctx = MEM_new(__func__, *ctx); } else { - ctx = MEM_cnew(__func__); + ctx = MEM_new(__func__); } BLI_addtail(contexts, ctx); } - bContextStoreEntry *entry = MEM_cnew(__func__); - BLI_strncpy(entry->name, name, sizeof(entry->name)); - entry->ptr = *ptr; - - BLI_addtail(&ctx->entries, entry); + ctx->entries.append(bContextStoreEntry{name, *ptr}); return ctx; } @@ -163,22 +158,17 @@ bContextStore *CTX_store_add_all(ListBase *contexts, bContextStore *context) if (!ctx || ctx->used) { if (ctx) { - bContextStore *lastctx = ctx; - ctx = MEM_new(__func__); - *ctx = *lastctx; - BLI_duplicatelist(&ctx->entries, &lastctx->entries); + ctx = MEM_new(__func__, *ctx); } else { - ctx = MEM_cnew(__func__); + ctx = MEM_new(__func__); } BLI_addtail(contexts, ctx); } - LISTBASE_FOREACH (bContextStoreEntry *, tentry, &context->entries) { - bContextStoreEntry *entry = MEM_cnew(__func__); - *entry = *tentry; - BLI_addtail(&ctx->entries, entry); + for (const bContextStoreEntry &src_entry : context->entries) { + ctx->entries.append(src_entry); } return ctx; @@ -195,42 +185,27 @@ void CTX_store_set(bContext *C, bContextStore *store) } const PointerRNA *CTX_store_ptr_lookup(const bContextStore *store, - const char *name, + const blender::StringRefNull name, const StructRNA *type) { - bContextStoreEntry *entry = static_cast( - BLI_rfindstring(&store->entries, name, offsetof(bContextStoreEntry, name))); - if (!entry) { - return nullptr; + for (auto entry = store->entries.rbegin(); entry != store->entries.rend(); ++entry) { + if (entry->name == name) { + if (type && RNA_struct_is_a(entry->ptr.type, type)) { + return &entry->ptr; + } + } } - - if (type && !RNA_struct_is_a(entry->ptr.type, type)) { - return nullptr; - } - return &entry->ptr; + return nullptr; } -bContextStore *CTX_store_copy(bContextStore *store) +bContextStore *CTX_store_copy(const bContextStore *store) { - bContextStore *ctx = MEM_cnew(__func__); - *ctx = *store; - BLI_duplicatelist(&ctx->entries, &store->entries); - - return ctx; + return MEM_new(__func__, *store); } void CTX_store_free(bContextStore *store) { - BLI_freelistN(&store->entries); - MEM_freeN(store); -} - -void CTX_store_free_list(ListBase *contexts) -{ - bContextStore *ctx; - while ((ctx = static_cast(BLI_pophead(contexts)))) { - CTX_store_free(ctx); - } + MEM_delete(store); } /* is python initialized? */ @@ -592,11 +567,8 @@ ListBase CTX_data_dir_get_ex(const bContext *C, RNA_PROP_END; } if (use_store && C->wm.store) { - bContextStoreEntry *entry; - - for (entry = static_cast(C->wm.store->entries.first); entry; - entry = entry->next) { - data_dir_add(&lb, entry->name, use_all); + for (const bContextStoreEntry &entry : C->wm.store->entries) { + data_dir_add(&lb, entry.name.c_str(), use_all); } } if ((region = CTX_wm_region(C)) && region->type && region->type->context) { diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index 4d423f989a6..c16c3068320 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -3470,7 +3470,9 @@ void UI_block_free(const bContext *C, uiBlock *block) MEM_freeN(block->func_argN); } - CTX_store_free_list(&block->contexts); + LISTBASE_FOREACH_MUTABLE (bContextStore *, store, &block->contexts) { + CTX_store_free(store); + } BLI_freelistN(&block->saferct); BLI_freelistN(&block->color_pickers.list); From 1eb90ee519c4537be6ecd86b41cb5e7aa092581a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sun, 18 Dec 2022 21:45:32 -0600 Subject: [PATCH 0206/1522] UI: Use vector instead of linked list for block button groups This simplifies some memory management, ammortizes some of the many small allocations when building UI layouts, and simplifies the code that deals with the groups. `uiBlock` is no longer a trivial type. In my testing this saved a few ms when drawing a large node tree. --- source/blender/editors/interface/interface.cc | 11 ++--- .../interface/interface_button_group.cc | 49 ++++++------------- .../editors/interface/interface_intern.hh | 29 ++++++----- .../editors/interface/interface_layout.cc | 12 ++--- .../editors/interface/interface_panel.cc | 19 +++---- .../interface_template_search_menu.cc | 6 ++- 6 files changed, 50 insertions(+), 76 deletions(-) diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index c16c3068320..6728b1e3a41 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -3478,10 +3478,9 @@ void UI_block_free(const bContext *C, uiBlock *block) BLI_freelistN(&block->color_pickers.list); BLI_freelistN(&block->dynamic_listeners); - ui_block_free_button_groups(block); ui_block_free_views(block); - MEM_freeN(block); + MEM_delete(block); } void UI_block_listen(const uiBlock *block, const wmRegionListenerParams *listener_params) @@ -3597,13 +3596,11 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, eU wmWindow *window = CTX_wm_window(C); Scene *scene = CTX_data_scene(C); - uiBlock *block = MEM_cnew(__func__); + uiBlock *block = MEM_new(__func__); block->active = true; block->emboss = emboss; block->evil_C = (void *)C; /* XXX */ - BLI_listbase_clear(&block->button_groups); - if (scene) { /* store display device name, don't lookup for transformations yet * block could be used for non-color displays where looking up for transformation @@ -4058,7 +4055,7 @@ uiBut *ui_but_change_type(uiBut *but, eButType new_type) ui_but_alloc_info(new_type, &alloc_size, &alloc_str, &new_has_custom_type); if (new_has_custom_type || old_has_custom_type) { - const void *old_but_ptr = but; + const uiBut *old_but_ptr = but; /* Button may have pointer to a member within itself, this will have to be updated. */ const bool has_str_ptr_to_self = but->str == but->strdata; const bool has_poin_ptr_to_self = but->poin == (char *)but; @@ -4082,7 +4079,7 @@ uiBut *ui_but_change_type(uiBut *but, eButType new_type) } #ifdef WITH_PYTHON if (UI_editsource_enable_check()) { - UI_editsource_but_replace(static_cast(old_but_ptr), but); + UI_editsource_but_replace(old_but_ptr, but); } #endif } diff --git a/source/blender/editors/interface/interface_button_group.cc b/source/blender/editors/interface/interface_button_group.cc index ed9065423e4..371cfda47df 100644 --- a/source/blender/editors/interface/interface_button_group.cc +++ b/source/blender/editors/interface/interface_button_group.cc @@ -17,54 +17,35 @@ void ui_block_new_button_group(uiBlock *block, uiButtonGroupFlag flag) { /* Don't create a new group if there is a "lock" on new groups. */ - if (!BLI_listbase_is_empty(&block->button_groups)) { - uiButtonGroup *last_button_group = static_cast(block->button_groups.last); - if (last_button_group->flag & UI_BUTTON_GROUP_LOCK) { + if (!block->button_groups.is_empty()) { + uiButtonGroup &last_group = block->button_groups.last(); + if (last_group.flag & UI_BUTTON_GROUP_LOCK) { return; } } - uiButtonGroup *new_group = MEM_cnew(__func__); - new_group->flag = flag; - BLI_addtail(&block->button_groups, new_group); + block->button_groups.append({}); + block->button_groups.last().flag = flag; } void ui_button_group_add_but(uiBlock *block, uiBut *but) { - if (BLI_listbase_is_empty(&block->button_groups)) { + if (block->button_groups.is_empty()) { ui_block_new_button_group(block, uiButtonGroupFlag(0)); } - uiButtonGroup *current_button_group = static_cast(block->button_groups.last); - - /* We can't use the button directly because adding it to - * this list would mess with its `prev` and `next` pointers. */ - LinkData *button_link = BLI_genericNodeN(but); - BLI_addtail(¤t_button_group->buttons, button_link); + uiButtonGroup ¤t_group = block->button_groups.last(); + current_group.buttons.append(but); } -static void button_group_free(uiButtonGroup *button_group) +void ui_button_group_replace_but_ptr(uiBlock *block, const uiBut *old_but_ptr, uiBut *new_but) { - BLI_freelistN(&button_group->buttons); - MEM_freeN(button_group); -} - -void ui_block_free_button_groups(uiBlock *block) -{ - LISTBASE_FOREACH_MUTABLE (uiButtonGroup *, button_group, &block->button_groups) { - button_group_free(button_group); - } -} - -void ui_button_group_replace_but_ptr(uiBlock *block, const void *old_but_ptr, uiBut *new_but) -{ - LISTBASE_FOREACH (uiButtonGroup *, button_group, &block->button_groups) { - LISTBASE_FOREACH (LinkData *, link, &button_group->buttons) { - if (link->data == old_but_ptr) { - link->data = new_but; - return; - } - } + for (uiButtonGroup &group : block->button_groups) { + std::replace_if( + group.buttons.begin(), + group.buttons.end(), + [&](const uiBut *ptr) { return ptr == old_but_ptr; }, + new_but); } } diff --git a/source/blender/editors/interface/interface_intern.hh b/source/blender/editors/interface/interface_intern.hh index 1b846a97403..fc64500dbaa 100644 --- a/source/blender/editors/interface/interface_intern.hh +++ b/source/blender/editors/interface/interface_intern.hh @@ -9,6 +9,7 @@ #include "BLI_compiler_attrs.h" #include "BLI_rect.h" +#include "BLI_vector.hh" #include "DNA_listBase.h" #include "RNA_types.h" @@ -456,18 +457,6 @@ enum eBlockContentHints { UI_BLOCK_CONTAINS_SUBMENU_BUT = (1 << 0), }; -/** - * A group of button references, used by property search to keep track of sets of buttons that - * should be searched together. For example, in property split layouts number buttons and their - * labels (and even their decorators) are separate buttons, but they must be searched and - * highlighted together. - */ -struct uiButtonGroup { - void *next, *prev; - ListBase buttons; /* #LinkData with #uiBut data field. */ - short flag; -}; - /* #uiButtonGroup.flag. */ enum uiButtonGroupFlag { /** While this flag is set, don't create new button groups for layout item calls. */ @@ -477,6 +466,17 @@ enum uiButtonGroupFlag { }; ENUM_OPERATORS(uiButtonGroupFlag, UI_BUTTON_GROUP_PANEL_HEADER); +/** + * A group of button references, used by property search to keep track of sets of buttons that + * should be searched together. For example, in property split layouts number buttons and their + * labels (and even their decorators) are separate buttons, but they must be searched and + * highlighted together. + */ +struct uiButtonGroup { + blender::Vector buttons; + uiButtonGroupFlag flag; +}; + struct uiBlockDynamicListener { struct uiBlockDynamicListener *next, *prev; @@ -493,7 +493,7 @@ struct uiBlock { /** Used for `UI_butstore_*` runtime function. */ ListBase butstore; - ListBase button_groups; /* #uiButtonGroup. */ + blender::Vector button_groups; ListBase layouts; uiLayout *curlayout; @@ -1273,8 +1273,7 @@ void ui_item_paneltype_func(bContext *C, uiLayout *layout, void *arg_pt); */ void ui_block_new_button_group(uiBlock *block, uiButtonGroupFlag flag); void ui_button_group_add_but(uiBlock *block, uiBut *but); -void ui_button_group_replace_but_ptr(uiBlock *block, const void *old_but_ptr, uiBut *new_but); -void ui_block_free_button_groups(uiBlock *block); +void ui_button_group_replace_but_ptr(uiBlock *block, const uiBut *old_but_ptr, uiBut *new_but); /* interface_drag.cc */ diff --git a/source/blender/editors/interface/interface_layout.cc b/source/blender/editors/interface/interface_layout.cc index b0d5728c9f9..9d755ac022a 100644 --- a/source/blender/editors/interface/interface_layout.cc +++ b/source/blender/editors/interface/interface_layout.cc @@ -5227,10 +5227,9 @@ static bool button_matches_search_filter(uiBut *but, const char *search_filter) /** * Test for a search result within a specific button group. */ -static bool button_group_has_search_match(uiButtonGroup *button_group, const char *search_filter) +static bool button_group_has_search_match(const uiButtonGroup &group, const char *search_filter) { - LISTBASE_FOREACH (LinkData *, link, &button_group->buttons) { - uiBut *but = static_cast(link->data); + for (uiBut *but : group.buttons) { if (button_matches_search_filter(but, search_filter)) { return true; } @@ -5251,13 +5250,12 @@ static bool button_group_has_search_match(uiButtonGroup *button_group, const cha static bool block_search_filter_tag_buttons(uiBlock *block, const char *search_filter) { bool has_result = false; - LISTBASE_FOREACH (uiButtonGroup *, button_group, &block->button_groups) { - if (button_group_has_search_match(button_group, search_filter)) { + for (const uiButtonGroup &group : block->button_groups) { + if (button_group_has_search_match(group, search_filter)) { has_result = true; } else { - LISTBASE_FOREACH (LinkData *, link, &button_group->buttons) { - uiBut *but = static_cast(link->data); + for (uiBut *but : group.buttons) { but->flag |= UI_SEARCH_FILTER_NO_MATCH; } } diff --git a/source/blender/editors/interface/interface_panel.cc b/source/blender/editors/interface/interface_panel.cc index c924d758caa..28aae7d779f 100644 --- a/source/blender/editors/interface/interface_panel.cc +++ b/source/blender/editors/interface/interface_panel.cc @@ -754,18 +754,16 @@ void UI_panel_header_buttons_end(Panel *panel) uiBlock *block = panel->runtime.block; /* A button group should always be created in #UI_panel_header_buttons_begin. */ - BLI_assert(!BLI_listbase_is_empty(&block->button_groups)); + BLI_assert(!block->button_groups.is_empty()); - uiButtonGroup *button_group = static_cast(block->button_groups.last); - - button_group->flag &= ~UI_BUTTON_GROUP_LOCK; + uiButtonGroup &button_group = block->button_groups.last(); + button_group.flag &= ~UI_BUTTON_GROUP_LOCK; /* Repurpose the first header button group if it is empty, in case the first button added to * the panel doesn't add a new group (if the button is created directly rather than through an * interface layout call). */ - if (BLI_listbase_is_single(&block->button_groups) && - BLI_listbase_is_empty(&button_group->buttons)) { - button_group->flag &= ~UI_BUTTON_GROUP_PANEL_HEADER; + if (block->button_groups.size() > 0) { + button_group.flag &= ~UI_BUTTON_GROUP_PANEL_HEADER; } else { /* Always add a new button group. Although this may result in many empty groups, without it, @@ -940,12 +938,11 @@ static void panel_remove_invisible_layouts_recursive(Panel *panel, const Panel * /* If sub-panels have no search results but the parent panel does, then the parent panel open * and the sub-panels will close. In that case there must be a way to hide the buttons in the * panel but keep the header buttons. */ - LISTBASE_FOREACH (uiButtonGroup *, button_group, &block->button_groups) { - if (button_group->flag & UI_BUTTON_GROUP_PANEL_HEADER) { + for (const uiButtonGroup &button_group : block->button_groups) { + if (button_group.flag & UI_BUTTON_GROUP_PANEL_HEADER) { continue; } - LISTBASE_FOREACH (LinkData *, link, &button_group->buttons) { - uiBut *but = static_cast(link->data); + for (uiBut *but : button_group.buttons) { but->flag |= UI_HIDDEN; } } diff --git a/source/blender/editors/interface/interface_template_search_menu.cc b/source/blender/editors/interface/interface_template_search_menu.cc index 54213bdc5c3..e953119dfdc 100644 --- a/source/blender/editors/interface/interface_template_search_menu.cc +++ b/source/blender/editors/interface/interface_template_search_menu.cc @@ -1040,7 +1040,8 @@ static bool ui_search_menu_create_context_menu(struct bContext *C, MenuSearch_Item *item = (MenuSearch_Item *)active; bool has_menu = false; - memset(&data->context_menu_data, 0x0, sizeof(data->context_menu_data)); + new (&data->context_menu_data.but) uiBut(); + new (&data->context_menu_data.block) uiBlock(); uiBut *but = &data->context_menu_data.but; uiBlock *block = &data->context_menu_data.block; @@ -1083,7 +1084,8 @@ static struct ARegion *ui_search_menu_create_tooltip(struct bContext *C, MenuSearch_Data *data = (MenuSearch_Data *)arg; MenuSearch_Item *item = (MenuSearch_Item *)active; - memset(&data->context_menu_data, 0x0, sizeof(data->context_menu_data)); + new (&data->context_menu_data.but) uiBut(); + new (&data->context_menu_data.block) uiBlock(); uiBut *but = &data->context_menu_data.but; uiBlock *block = &data->context_menu_data.block; unit_m4(block->winmat); From 67318b197790eac25b8b1928fdfe0359e8eafb94 Mon Sep 17 00:00:00 2001 From: Omar Emara Date: Mon, 19 Dec 2022 10:04:03 +0200 Subject: [PATCH 0207/1522] Realtime Compositor: Implement variable size blur This patch implements the variable size mode of the blur node. This is not identical to the CPU implementation, but is visually very close. That's because of two things. First, the Extend Bounds option introduces a 2px offset that doesn't make sense, which is likely a bug in the CPU implementation. Second, the CPU implementation approximate the result using three passes, the first two of which are separable morphological operators applied on the size input. But this approximation does not provide an advantage because the last pass is non-separable anyways. So the GPU implementation does not attempt this approximation for more accurate and faster results. Differential Revision: https://developer.blender.org/D16762 Reviews By: Clement Foucault --- .../realtime_compositor/CMakeLists.txt | 2 + .../shaders/compositor_symmetric_blur.glsl | 16 +- ...mpositor_symmetric_blur_variable_size.glsl | 155 ++++++++++++++++++ ...sitor_symmetric_blur_variable_size_info.hh | 14 ++ .../composite/nodes/node_composite_blur.cc | 53 +++++- 5 files changed, 231 insertions(+), 9 deletions(-) create mode 100644 source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur_variable_size.glsl create mode 100644 source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_variable_size_info.hh diff --git a/source/blender/compositor/realtime_compositor/CMakeLists.txt b/source/blender/compositor/realtime_compositor/CMakeLists.txt index 0881982c6d3..27ffcee3b80 100644 --- a/source/blender/compositor/realtime_compositor/CMakeLists.txt +++ b/source/blender/compositor/realtime_compositor/CMakeLists.txt @@ -119,6 +119,7 @@ set(GLSL_SRC shaders/compositor_set_alpha.glsl shaders/compositor_split_viewer.glsl shaders/compositor_symmetric_blur.glsl + shaders/compositor_symmetric_blur_variable_size.glsl shaders/compositor_symmetric_separable_blur.glsl shaders/compositor_tone_map_photoreceptor.glsl shaders/compositor_tone_map_simple.glsl @@ -206,6 +207,7 @@ set(SRC_SHADER_CREATE_INFOS shaders/infos/compositor_set_alpha_info.hh shaders/infos/compositor_split_viewer_info.hh shaders/infos/compositor_symmetric_blur_info.hh + shaders/infos/compositor_symmetric_blur_variable_size_info.hh shaders/infos/compositor_symmetric_separable_blur_info.hh shaders/infos/compositor_tone_map_photoreceptor_info.hh shaders/infos/compositor_tone_map_simple_info.hh diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl index df08991a35c..59527d39233 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur.glsl @@ -1,16 +1,20 @@ #pragma BLENDER_REQUIRE(gpu_shader_compositor_blur_common.glsl) #pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) +/* Loads the input color of the pixel at the given texel. If gamma correction is enabled, the color + * is gamma corrected. If bounds are extended, then the input is treated as padded by a blur size + * amount of pixels of zero color, and the given texel is assumed to be in the space of the image + * after padding. So we offset the texel by the blur radius amount and fallback to a zero color if + * it is out of bounds. For instance, if the input is padded by 5 pixels to the left of the image, + * the first 5 pixels should be out of bounds and thus zero, hence the introduced offset. */ vec4 load_input(ivec2 texel) { vec4 color; if (extend_bounds) { - /* If bounds are extended, then we treat the input as padded by a radius amount of pixels. So - * we load the input with an offset by the radius amount and fallback to a transparent color if - * it is out of bounds. Notice that we subtract 1 because the weights texture have an extra - * center weight, see the SymmetricBlurWeights for more information. */ - ivec2 blur_size = texture_size(weights_tx) - 1; - color = texture_load(input_tx, texel - blur_size, vec4(0.0)); + /* Notice that we subtract 1 because the weights texture have an extra center weight, see the + * SymmetricBlurWeights class for more information. */ + ivec2 blur_radius = texture_size(weights_tx) - 1; + color = texture_load(input_tx, texel - blur_radius, vec4(0.0)); } else { color = texture_load(input_tx, texel); diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur_variable_size.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur_variable_size.glsl new file mode 100644 index 00000000000..448f3739873 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur_variable_size.glsl @@ -0,0 +1,155 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_math_utils.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_compositor_blur_common.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +/* Loads the input color of the pixel at the given texel. If gamma correction is enabled, the color + * is gamma corrected. If bounds are extended, then the input is treated as padded by a blur size + * amount of pixels of zero color, and the given texel is assumed to be in the space of the image + * after padding. So we offset the texel by the blur radius amount and fallback to a zero color if + * it is out of bounds. For instance, if the input is padded by 5 pixels to the left of the image, + * the first 5 pixels should be out of bounds and thus zero, hence the introduced offset. */ +vec4 load_input(ivec2 texel) +{ + vec4 color; + if (extend_bounds) { + /* Notice that we subtract 1 because the weights texture have an extra center weight, see the + * SymmetricBlurWeights class for more information. */ + ivec2 blur_radius = texture_size(weights_tx) - 1; + color = texture_load(input_tx, texel - blur_radius, vec4(0.0)); + } + else { + color = texture_load(input_tx, texel); + } + + if (gamma_correct) { + color = gamma_correct_blur_input(color); + } + + return color; +} + +/* Similar to load_input but loads the size instead, has no gamma correction, and clamps to borders + * instead of returning zero for out of bound access. See load_input for more information. */ +float load_size(ivec2 texel) +{ + if (extend_bounds) { + ivec2 blur_radius = texture_size(weights_tx) - 1; + return texture_load(size_tx, texel - blur_radius).x; + } + else { + return texture_load(size_tx, texel).x; + } +} + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + + vec4 accumulated_color = vec4(0.0); + vec4 accumulated_weight = vec4(0.0); + + /* First, compute the contribution of the center pixel. */ + vec4 center_color = load_input(texel); + float center_weight = texture_load(weights_tx, ivec2(0)).x; + accumulated_color += center_color * center_weight; + accumulated_weight += center_weight; + + ivec2 weights_size = texture_size(weights_tx); + + /* Then, compute the contributions of the pixels along the x axis of the filter, but only + * accumulate them if their distance to the center is less their computed variable blur size, + * noting that the weights texture only stores the weights for the positive half, but since the + * filter is symmetric, the same weight is used for the negative half and we add both of their + * contributions. */ + for (int x = 1; x < weights_size.x; x++) { + float weight = texture_load(weights_tx, ivec2(x, 0)).x; + + float right_size = load_size(texel + ivec2(x, 0)); + float right_blur_radius = right_size * weights_size.x; + if (x < right_blur_radius) { + accumulated_color += load_input(texel + ivec2(x, 0)) * weight; + accumulated_weight += weight; + } + + float left_size = load_size(texel + ivec2(-x, 0)); + float left_blur_radius = right_size * weights_size.x; + if (x < left_blur_radius) { + accumulated_color += load_input(texel + ivec2(-x, 0)) * weight; + accumulated_weight += weight; + } + } + + /* Then, compute the contributions of the pixels along the y axis of the filter, but only + * accumulate them if their distance to the center is less their computed variable blur size, + * noting that the weights texture only stores the weights for the positive half, but since the + * filter is symmetric, the same weight is used for the negative half and we add both of their + * contributions. */ + for (int y = 1; y < weights_size.y; y++) { + float weight = texture_load(weights_tx, ivec2(0, y)).x; + + float top_size = load_size(texel + ivec2(0, y)); + float top_blur_radius = top_size * weights_size.y; + if (y < top_blur_radius) { + accumulated_color += load_input(texel + ivec2(0, y)) * weight; + accumulated_weight += weight; + } + + float bottom_size = load_size(texel + ivec2(0, -y)); + float bottom_blur_radius = bottom_size * weights_size.x; + if (y < bottom_blur_radius) { + accumulated_color += load_input(texel + ivec2(0, -y)) * weight; + accumulated_weight += weight; + } + } + + /* Finally, compute the contributions of the pixels in the four quadrants of the filter, but only + * accumulate them if the center lies inside the rectangle centered at the pixel whose width and + * height is the variable blur size, noting that the weights texture only stores the weights for + * the upper right quadrant, but since the filter is symmetric, the same weight is used for the + * rest of the quadrants and we add all four of their contributions. */ + for (int y = 1; y < weights_size.y; y++) { + for (int x = 1; x < weights_size.x; x++) { + float weight = texture_load(weights_tx, ivec2(x, y)).x; + + /* Upper right quadrant. */ + float upper_right_size = load_size(texel + ivec2(x, y)); + vec2 upper_right_blur_radius = upper_right_size * weights_size; + if (x < upper_right_blur_radius.x && y < upper_right_blur_radius.y) { + accumulated_color += load_input(texel + ivec2(x, y)) * weight; + accumulated_weight += weight; + } + + /* Upper left quadrant. */ + float upper_left_size = load_size(texel + ivec2(-x, y)); + vec2 upper_left_blur_radius = upper_left_size * weights_size; + if (x < upper_left_blur_radius.x && y < upper_left_blur_radius.y) { + accumulated_color += load_input(texel + ivec2(-x, y)) * weight; + accumulated_weight += weight; + } + + /* Bottom right quadrant. */ + float bottom_right_size = load_size(texel + ivec2(x, -y)); + vec2 bottom_right_blur_radius = bottom_right_size * weights_size; + if (x < bottom_right_blur_radius.x && y < bottom_right_blur_radius.y) { + accumulated_color += load_input(texel + ivec2(x, -y)) * weight; + accumulated_weight += weight; + } + + /* Bottom left quadrant. */ + float bottom_left_size = load_size(texel + ivec2(-x, -y)); + vec2 bottom_left_blur_radius = bottom_left_size * weights_size; + if (x < bottom_left_blur_radius.x && y < bottom_left_blur_radius.y) { + accumulated_color += load_input(texel + ivec2(-x, -y)) * weight; + accumulated_weight += weight; + } + } + } + + accumulated_color = safe_divide(accumulated_color, accumulated_weight); + + if (gamma_correct) { + accumulated_color = gamma_uncorrect_blur_output(accumulated_color); + } + + imageStore(output_img, texel, accumulated_color); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_variable_size_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_variable_size_info.hh new file mode 100644 index 00000000000..f226f8c3d19 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_symmetric_blur_variable_size_info.hh @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_symmetric_blur_variable_size) + .local_group_size(16, 16) + .push_constant(Type::BOOL, "extend_bounds") + .push_constant(Type::BOOL, "gamma_correct") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .sampler(1, ImageType::FLOAT_2D, "weights_tx") + .sampler(2, ImageType::FLOAT_2D, "size_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_symmetric_blur_variable_size.glsl") + .do_static_compilation(true); diff --git a/source/blender/nodes/composite/nodes/node_composite_blur.cc b/source/blender/nodes/composite/nodes/node_composite_blur.cc index c178c320a06..147aa9d09ee 100644 --- a/source/blender/nodes/composite/nodes/node_composite_blur.cc +++ b/source/blender/nodes/composite/nodes/node_composite_blur.cc @@ -106,7 +106,10 @@ class BlurOperation : public NodeOperation { return; } - if (use_separable_filter()) { + if (!get_input("Size").is_single_value() && get_variable_size()) { + execute_variable_size(); + } + else if (use_separable_filter()) { symmetric_separable_blur(context(), get_input("Image"), get_result("Image"), @@ -116,11 +119,11 @@ class BlurOperation : public NodeOperation { node_storage(bnode()).gamma); } else { - execute_blur(); + execute_constant_size(); } } - void execute_blur() + void execute_constant_size() { GPUShader *shader = shader_manager().get("compositor_symmetric_blur"); GPU_shader_bind(shader); @@ -155,6 +158,45 @@ class BlurOperation : public NodeOperation { weights.unbind_as_texture(); } + void execute_variable_size() + { + GPUShader *shader = shader_manager().get("compositor_symmetric_blur_variable_size"); + GPU_shader_bind(shader); + + GPU_shader_uniform_1b(shader, "extend_bounds", get_extend_bounds()); + GPU_shader_uniform_1b(shader, "gamma_correct", node_storage(bnode()).gamma); + + const Result &input_image = get_input("Image"); + input_image.bind_as_texture(shader, "input_tx"); + + const float2 blur_radius = compute_blur_radius(); + + const SymmetricBlurWeights &weights = context().cache_manager().get_symmetric_blur_weights( + node_storage(bnode()).filtertype, blur_radius); + weights.bind_as_texture(shader, "weights_tx"); + + const Result &input_size = get_input("Size"); + input_size.bind_as_texture(shader, "size_tx"); + + Domain domain = compute_domain(); + if (get_extend_bounds()) { + /* Add a radius amount of pixels in both sides of the image, hence the multiply by 2. */ + domain.size += int2(math::ceil(blur_radius)) * 2; + } + + Result &output_image = get_result("Image"); + output_image.allocate_texture(domain); + output_image.bind_as_image(shader, "output_img"); + + compute_dispatch_threads_at_least(shader, domain.size); + + GPU_shader_unbind(); + output_image.unbind_as_image(); + input_image.unbind_as_texture(); + weights.unbind_as_texture(); + input_size.unbind_as_texture(); + } + float2 compute_blur_radius() { const float size = math::clamp(get_input("Size").get_float_value_default(1.0f), 0.0f, 1.0f); @@ -228,6 +270,11 @@ class BlurOperation : public NodeOperation { { return bnode().custom1 & CMP_NODEFLAG_BLUR_EXTEND_BOUNDS; } + + bool get_variable_size() + { + return bnode().custom1 & CMP_NODEFLAG_BLUR_VARIABLE_SIZE; + } }; static NodeOperation *get_compositor_operation(Context &context, DNode node) From c3cc8d2f6a76dcbca560c6ba1c09427a310be49e Mon Sep 17 00:00:00 2001 From: Omar Emara Date: Mon, 19 Dec 2022 10:08:59 +0200 Subject: [PATCH 0208/1522] Realtime Compositor: Implement Streaks Glare node This patch implements the Streaks Glare node. Which is an approximation to the existing implementation in the CPU compositor. The difference due to the approximation is bearily visible in artificial test cases, but is less visible in actual use cases. Since the difference is rather similar to that we discussed in the Simple Star mode, the decision to allow that difference would probably hold here. For the future, we can look into approximating this further using a closed form IIR recursive filter with parallel interconnection and block-based parallelism. That's because the streak filter is already very similar to the causal pass of a fourth order recursive filter, just with exponential steps. Differential Revision: https://developer.blender.org/D16789 Reviewed By: Clement Foucault --- .../realtime_compositor/CMakeLists.txt | 2 + .../compositor_glare_streaks_accumulate.glsl | 9 + .../compositor_glare_streaks_filter.glsl | 41 ++++ .../shaders/infos/compositor_glare_info.hh | 22 ++ .../composite/nodes/node_composite_glare.cc | 229 +++++++++++++++--- 5 files changed, 267 insertions(+), 36 deletions(-) create mode 100644 source/blender/compositor/realtime_compositor/shaders/compositor_glare_streaks_accumulate.glsl create mode 100644 source/blender/compositor/realtime_compositor/shaders/compositor_glare_streaks_filter.glsl diff --git a/source/blender/compositor/realtime_compositor/CMakeLists.txt b/source/blender/compositor/realtime_compositor/CMakeLists.txt index 27ffcee3b80..5826c70793c 100644 --- a/source/blender/compositor/realtime_compositor/CMakeLists.txt +++ b/source/blender/compositor/realtime_compositor/CMakeLists.txt @@ -106,6 +106,8 @@ set(GLSL_SRC shaders/compositor_glare_simple_star_diagonal_pass.glsl shaders/compositor_glare_simple_star_horizontal_pass.glsl shaders/compositor_glare_simple_star_vertical_pass.glsl + shaders/compositor_glare_streaks_accumulate.glsl + shaders/compositor_glare_streaks_filter.glsl shaders/compositor_image_crop.glsl shaders/compositor_morphological_distance.glsl shaders/compositor_morphological_distance_feather.glsl diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_streaks_accumulate.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_streaks_accumulate.glsl new file mode 100644 index 00000000000..0156edf088a --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_streaks_accumulate.glsl @@ -0,0 +1,9 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + vec4 attenuated_streak = texture_load(streak_tx, texel) * attenuation_factor; + vec4 current_accumulated_streaks = imageLoad(accumulated_streaks_img, texel); + imageStore(accumulated_streaks_img, texel, current_accumulated_streaks + attenuated_streak); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_streaks_filter.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_streaks_filter.glsl new file mode 100644 index 00000000000..7fe7d45e4fd --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_streaks_filter.glsl @@ -0,0 +1,41 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + ivec2 input_size = texture_size(input_streak_tx); + + /* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size + * to get the coordinates into the sampler's expected [0, 1] range. Similarly, transform the + * vector into the sampler's space by dividing by the input size. */ + vec2 coordinates = (vec2(texel) + vec2(0.5)) / input_size; + vec2 vector = streak_vector / input_size; + + /* Load three equally spaced neighbours to the current pixel in the direction of the streak + * vector. */ + vec4 neighbours[3]; + neighbours[0] = texture(input_streak_tx, coordinates + vector); + neighbours[1] = texture(input_streak_tx, coordinates + vector * 2.0); + neighbours[2] = texture(input_streak_tx, coordinates + vector * 3.0); + + /* Attenuate the value of two of the channels for each of the neighbours by multiplying by the + * color modulator. The particular channels for each neighbour were chosen to be visually similar + * to the modulation pattern of chromatic aberration. */ + neighbours[0].gb *= color_modulator; + neighbours[1].rg *= color_modulator; + neighbours[2].rb *= color_modulator; + + /* Compute the weighted sum of all neighbours using the given fade factors as weights. The + * weights are expected to be lower for neighbours that are further away. */ + vec4 weighted_neighbours_sum = vec4(0.0); + for (int i = 0; i < 3; i++) { + weighted_neighbours_sum += fade_factors[i] * neighbours[i]; + } + + /* The output is the average between the center color and the weighted sum of the neighbours. + * Which intuitively mean that highlights will spread in the direction of the streak, which is + * the desired result. */ + vec4 center_color = texture(input_streak_tx, coordinates); + vec4 output_color = (center_color + weighted_neighbours_sum) / 2.0; + imageStore(output_streak_img, texel, output_color); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_glare_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_glare_info.hh index 0e078373dfe..029bb027d5b 100644 --- a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_glare_info.hh +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_glare_info.hh @@ -82,3 +82,25 @@ GPU_SHADER_CREATE_INFO(compositor_glare_simple_star_anti_diagonal_pass) .image(0, GPU_RGBA16F, Qualifier::READ_WRITE, ImageType::FLOAT_2D, "anti_diagonal_img") .compute_source("compositor_glare_simple_star_anti_diagonal_pass.glsl") .do_static_compilation(true); + +/* ------- + * Streaks + * ------- */ + +GPU_SHADER_CREATE_INFO(compositor_glare_streaks_filter) + .local_group_size(16, 16) + .push_constant(Type::FLOAT, "color_modulator") + .push_constant(Type::VEC3, "fade_factors") + .push_constant(Type::VEC2, "streak_vector") + .sampler(0, ImageType::FLOAT_2D, "input_streak_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_streak_img") + .compute_source("compositor_glare_streaks_filter.glsl") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_glare_streaks_accumulate) + .local_group_size(16, 16) + .push_constant(Type::FLOAT, "attenuation_factor") + .sampler(0, ImageType::FLOAT_2D, "streak_tx") + .image(0, GPU_RGBA16F, Qualifier::READ_WRITE, ImageType::FLOAT_2D, "accumulated_streaks_img") + .compute_source("compositor_glare_streaks_accumulate.glsl") + .do_static_compilation(true); diff --git a/source/blender/nodes/composite/nodes/node_composite_glare.cc b/source/blender/nodes/composite/nodes/node_composite_glare.cc index 86888cd039d..b02d9e6166b 100644 --- a/source/blender/nodes/composite/nodes/node_composite_glare.cc +++ b/source/blender/nodes/composite/nodes/node_composite_glare.cc @@ -9,6 +9,7 @@ #include "BLI_assert.h" #include "BLI_index_range.hh" +#include "BLI_math_base.h" #include "BLI_math_base.hh" #include "BLI_math_vec_types.hh" @@ -31,6 +32,8 @@ #include "node_composite_util.hh" +#define MAX_GLARE_ITERATIONS 5 + namespace blender::nodes::node_composite_glare_cc { NODE_STORAGE_FUNCS(NodeGlare) @@ -128,19 +131,9 @@ class GlareOperation : public NodeOperation { return true; } - /* Only the ghost and simple star operations are currently supported. */ - switch (node_storage(bnode()).type) { - case CMP_NODE_GLARE_SIMPLE_STAR: - return false; - case CMP_NODE_GLARE_FOG_GLOW: - return true; - case CMP_NODE_GLARE_STREAKS: - return true; - case CMP_NODE_GLARE_GHOST: - return false; - default: - BLI_assert_unreachable(); - return true; + /* The fog glow mode is currently unsupported. */ + if (node_storage(bnode()).type == CMP_NODE_GLARE_FOG_GLOW) { + return true; } return false; @@ -334,26 +327,174 @@ class GlareOperation : public NodeOperation { return size.x + size.y - 1; } - /* --------------- - * Fog Glow Glare. - * --------------- */ - - /* Not yet implemented. Unreachable code due to the is_identity method. */ - Result execute_fog_glow(Result & /*highlights_result*/) - { - BLI_assert_unreachable(); - return Result(ResultType::Color, texture_pool()); - } - /* -------------- * Streaks Glare. * -------------- */ - /* Not yet implemented. Unreachable code due to the is_identity method. */ - Result execute_streaks(Result & /*highlights_result*/) + Result execute_streaks(Result &highlights_result) { - BLI_assert_unreachable(); - return Result(ResultType::Color, texture_pool()); + /* Create an initially zero image where streaks will be accumulated. */ + const float4 zero_color = float4(0.0f); + const int2 glare_size = get_glare_size(); + Result accumulated_streaks_result = Result::Temporary(ResultType::Color, texture_pool()); + accumulated_streaks_result.allocate_texture(glare_size); + GPU_texture_clear(accumulated_streaks_result.texture(), GPU_DATA_FLOAT, zero_color); + + /* For each streak, compute its direction and apply a streak filter in that direction, then + * accumulate the result into the accumulated streaks result. */ + for (const int streak_index : IndexRange(get_number_of_streaks())) { + const float2 streak_direction = compute_streak_direction(streak_index); + Result streak_result = apply_streak_filter(highlights_result, streak_direction); + + GPUShader *shader = shader_manager().get("compositor_glare_streaks_accumulate"); + GPU_shader_bind(shader); + + const float attenuation_factor = compute_streak_attenuation_factor(); + GPU_shader_uniform_1f(shader, "attenuation_factor", attenuation_factor); + + streak_result.bind_as_texture(shader, "streak_tx"); + accumulated_streaks_result.bind_as_image(shader, "accumulated_streaks_img", true); + + compute_dispatch_threads_at_least(shader, glare_size); + + streak_result.unbind_as_texture(); + accumulated_streaks_result.unbind_as_image(); + + streak_result.release(); + GPU_shader_unbind(); + } + + return accumulated_streaks_result; + } + + Result apply_streak_filter(Result &highlights_result, const float2 &streak_direction) + { + GPUShader *shader = shader_manager().get("compositor_glare_streaks_filter"); + GPU_shader_bind(shader); + + /* Copy the highlights result into a new image because the output will be copied to the input + * after each iteration and the highlights result is still needed to compute other streaks. */ + const int2 glare_size = get_glare_size(); + Result input_streak_result = Result::Temporary(ResultType::Color, texture_pool()); + input_streak_result.allocate_texture(glare_size); + GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE); + GPU_texture_copy(input_streak_result.texture(), highlights_result.texture()); + + Result output_streak_result = Result::Temporary(ResultType::Color, texture_pool()); + output_streak_result.allocate_texture(glare_size); + + /* For the given number of iterations, apply the streak filter in the given direction. The + * result of the previous iteration is used as the input of the current iteration. */ + const IndexRange iterations_range = IndexRange(get_number_of_iterations()); + for (const int iteration : iterations_range) { + const float color_modulator = compute_streak_color_modulator(iteration); + const float iteration_magnitude = compute_streak_iteration_magnitude(iteration); + const float3 fade_factors = compute_streak_fade_factors(iteration_magnitude); + const float2 streak_vector = streak_direction * iteration_magnitude; + + GPU_shader_uniform_1f(shader, "color_modulator", color_modulator); + GPU_shader_uniform_3fv(shader, "fade_factors", fade_factors); + GPU_shader_uniform_2fv(shader, "streak_vector", streak_vector); + + input_streak_result.bind_as_texture(shader, "input_streak_tx"); + GPU_texture_filter_mode(input_streak_result.texture(), true); + GPU_texture_wrap_mode(input_streak_result.texture(), false, false); + + output_streak_result.bind_as_image(shader, "output_streak_img"); + + compute_dispatch_threads_at_least(shader, glare_size); + + input_streak_result.unbind_as_texture(); + output_streak_result.unbind_as_image(); + + /* The accumulated result serves as the input for the next iteration, so copy the result to + * the input result since it can't be used for reading and writing simultaneously. Skip + * copying for the last iteration since it is not needed. */ + if (iteration != iterations_range.last()) { + GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE); + GPU_texture_copy(input_streak_result.texture(), output_streak_result.texture()); + } + } + + input_streak_result.release(); + GPU_shader_unbind(); + + return output_streak_result; + } + + /* As the number of iterations increase, the streaks spread farther and their intensity decrease. + * To maintain similar intensities regardless of the number of iterations, streaks with lower + * number of iteration are linearly attenuated. When the number of iterations is maximum, we need + * not attenuate, so the denominator should be one, and when the number of iterations is one, we + * need the attenuation to be maximum. This can be modeled as a simple decreasing linear equation + * by substituting the two aforementioned cases. */ + float compute_streak_attenuation_factor() + { + return 1.0f / (MAX_GLARE_ITERATIONS + 1 - get_number_of_iterations()); + } + + /* Given the index of the streak in the [0, Number Of Streaks - 1] range, compute the unit + * direction vector defining the streak. The streak directions should make angles with the + * x-axis that are equally spaced and covers the whole two pi range, starting with the user + * supplied angle. */ + float2 compute_streak_direction(int streak_index) + { + const int number_of_streaks = get_number_of_streaks(); + const float start_angle = get_streaks_start_angle(); + const float angle = start_angle + (float(streak_index) / number_of_streaks) * (M_PI * 2.0f); + return float2(math::cos(angle), math::sin(angle)); + } + + /* Different color channels of the streaks can be modulated by being multiplied by the color + * modulator computed by this method. The color modulation is expected to be maximum when the + * modulation factor is 1 and non existent when it is zero. But since the color modulator is + * multiplied to the channel and the multiplicative identity is 1, we invert the modulation + * factor. Moreover, color modulation should be less visible on higher iterations because they + * produce the farther more faded away parts of the streaks. To achieve that, the modulation + * factor is raised to the power of the iteration, noting that the modulation value is in the + * [0, 1] range so the higher the iteration the lower the resulting modulation factor. The plus + * one makes sure the power starts at one. */ + float compute_streak_color_modulator(int iteration) + { + return 1.0f - std::pow(get_color_modulation_factor(), iteration + 1); + } + + /* Streaks are computed by iteratively applying a filter that samples 3 neighbouring pixels in + * the direction of the streak. Those neighbouring pixels are then combined using a weighted sum. + * The weights of the neighbours are the fade factors computed by this method. Farther neighbours + * are expected to have lower weights because they contribute less to the combined result. Since + * the iteration magnitude represents how far the neighbours are, as noted in the description of + * the compute_streak_iteration_magnitude method, the fade factor for the closest neighbour is + * computed as the user supplied fade parameter raised to the power of the magnitude, noting that + * the fade value is in the [0, 1] range while the magnitude is larger than or equal one, so the + * higher the power the lower the resulting fade factor. Furthermore, the other two neighbours + * are just squared and cubed versions of the fade factor for the closest neighbour to get even + * lower fade factors for those farther neighbours. */ + float3 compute_streak_fade_factors(float iteration_magnitude) + { + const float fade_factor = std::pow(node_storage(bnode()).fade, iteration_magnitude); + return float3(fade_factor, std::pow(fade_factor, 2.0f), std::pow(fade_factor, 3.0f)); + } + + /* Streaks are computed by iteratively applying a filter that samples the neighbouring pixels in + * the direction of the streak. Each higher iteration samples pixels that are farther away, the + * magnitude computed by this method describes how farther away the neighbours are sampled. The + * magnitude exponentially increase with the iteration. A base of 4, was chosen as compromise + * between better quality and performance, since a lower base corresponds to more tightly spaced + * neighbours but would require more iterations to produce a streak of the same length. */ + float compute_streak_iteration_magnitude(int iteration) + { + return std::pow(4.0f, iteration); + } + + float get_streaks_start_angle() + { + return node_storage(bnode()).angle_ofs; + } + + int get_number_of_streaks() + { + return node_storage(bnode()).streaks; } /* ------------ @@ -377,9 +518,9 @@ class GlareOperation : public NodeOperation { /* Create an initially zero image where ghosts will be accumulated. */ const float4 zero_color = float4(0.0f); const int2 glare_size = get_glare_size(); - Result accumulated_ghost_result = Result::Temporary(ResultType::Color, texture_pool()); - accumulated_ghost_result.allocate_texture(glare_size); - GPU_texture_clear(accumulated_ghost_result.texture(), GPU_DATA_FLOAT, zero_color); + Result accumulated_ghosts_result = Result::Temporary(ResultType::Color, texture_pool()); + accumulated_ghosts_result.allocate_texture(glare_size); + GPU_texture_clear(accumulated_ghosts_result.texture(), GPU_DATA_FLOAT, zero_color); /* For the given number of iterations, accumulate four ghosts with different scales and color * modulators. The result of the previous iteration is used as the input of the current @@ -392,26 +533,26 @@ class GlareOperation : public NodeOperation { GPU_shader_uniform_4fv(shader, "scales", scales.data()); input_ghost_result.bind_as_texture(shader, "input_ghost_tx"); - accumulated_ghost_result.bind_as_image(shader, "accumulated_ghost_img", true); + accumulated_ghosts_result.bind_as_image(shader, "accumulated_ghost_img", true); compute_dispatch_threads_at_least(shader, glare_size); input_ghost_result.unbind_as_texture(); - accumulated_ghost_result.unbind_as_image(); + accumulated_ghosts_result.unbind_as_image(); /* The accumulated result serves as the input for the next iteration, so copy the result to * the input result since it can't be used for reading and writing simultaneously. Skip * copying for the last iteration since it is not needed. */ if (i != iterations_range.last()) { GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE); - GPU_texture_copy(input_ghost_result.texture(), accumulated_ghost_result.texture()); + GPU_texture_copy(input_ghost_result.texture(), accumulated_ghosts_result.texture()); } } GPU_shader_unbind(); input_ghost_result.release(); - return accumulated_ghost_result; + return accumulated_ghosts_result; } /* Computes two ghosts by blurring the highlights with two different radii, then adds them into a @@ -544,7 +685,18 @@ class GlareOperation : public NodeOperation { * subtract from one. */ float get_ghost_color_modulation_factor() { - return 1.0f - node_storage(bnode()).colmod; + return 1.0f - get_color_modulation_factor(); + } + + /* --------------- + * Fog Glow Glare. + * --------------- */ + + /* Not yet implemented. Unreachable code due to the is_identity method. */ + Result execute_fog_glow(Result & /*highlights_result*/) + { + BLI_assert_unreachable(); + return Result(ResultType::Color, texture_pool()); } /* ---------- @@ -595,6 +747,11 @@ class GlareOperation : public NodeOperation { return node_storage(bnode()).iter; } + float get_color_modulation_factor() + { + return node_storage(bnode()).colmod; + } + /* The glare node can compute the glare on a fraction of the input image size to improve * performance. The quality values and their corresponding quality factors are as follows: * From 923f394485f0a0171d3969bed137598cac4c96af Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Thu, 1 Dec 2022 11:41:26 +0100 Subject: [PATCH 0209/1522] Fix Outliner: Click next to View Layer name triggers object select Unlike other (closed) hierarchies, view layers dont show their contents next to their names. Code would still find the item via outliner_find_item_at_x_in_row though, this is now prevented (same as if the viewlayer was open [instead of collapsed]). Fixes T102357. Maniphest Tasks: T102357 Differential Revision: https://developer.blender.org/D16662 --- source/blender/editors/space_outliner/outliner_utils.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_outliner/outliner_utils.cc b/source/blender/editors/space_outliner/outliner_utils.cc index 2deedccc29e..e28f45227ee 100644 --- a/source/blender/editors/space_outliner/outliner_utils.cc +++ b/source/blender/editors/space_outliner/outliner_utils.cc @@ -133,9 +133,11 @@ TreeElement *outliner_find_item_at_x_in_row(const SpaceOutliner *space_outliner, bool *r_is_merged_icon, bool *r_is_over_icon) { - /* if parent_te is opened, it doesn't show children in row */ + TreeStoreElem *parent_tselem = TREESTORE(parent_te); TreeElement *te = parent_te; - if (!TSELEM_OPEN(TREESTORE(parent_te), space_outliner)) { + + /* If parent_te is opened, or it is a ViewLayer, it doesn't show children in row. */ + if (!TSELEM_OPEN(parent_tselem, space_outliner) && parent_tselem->type != TSE_R_LAYER) { te = outliner_find_item_at_x_in_row_recursive(parent_te, view_co_x, r_is_merged_icon); } From 288d4c95459b74568a63b204df1a387284d8cbdb Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 19 Dec 2022 12:50:09 +0100 Subject: [PATCH 0210/1522] Fix: asset handle in context is always none The issue was introduced in rBf0ac5e8aec03f7d0ca07d3792e5. --- source/blender/blenkernel/intern/context.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/context.cc b/source/blender/blenkernel/intern/context.cc index 8d8e96f26c8..df18cf1795c 100644 --- a/source/blender/blenkernel/intern/context.cc +++ b/source/blender/blenkernel/intern/context.cc @@ -1486,7 +1486,7 @@ AssetHandle CTX_wm_asset_handle(const bContext *C, bool *r_is_valid) (FileDirEntry *)CTX_data_pointer_get_type(C, "active_file", &RNA_FileSelectEntry).data; if (file && file->asset) { *r_is_valid = true; - AssetHandle{file}; + return AssetHandle{file}; } *r_is_valid = false; From 4cb2204d3a28a2e3f42f0460becbe75a00ea73e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 19 Dec 2022 13:14:33 +0100 Subject: [PATCH 0211/1522] Fix T103037: Regression: Grease Pencil Line Texture last point gets distorted This was due to a missing endpoint case that wasn't handled in the port. The last point still have to be discarded manually because of the dot/stroke setting of the material. The first test `ma1.x == -1` is not necessary anymore since the index buffer do not contain this point (which was rendered using instance rendering before. Reviewed By: jbakker Differential Revision: https://developer.blender.org/D16812 --- source/blender/draw/intern/shaders/common_gpencil_lib.glsl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/blender/draw/intern/shaders/common_gpencil_lib.glsl b/source/blender/draw/intern/shaders/common_gpencil_lib.glsl index def841b07aa..5b79ce71739 100644 --- a/source/blender/draw/intern/shaders/common_gpencil_lib.glsl +++ b/source/blender/draw/intern/shaders/common_gpencil_lib.glsl @@ -187,6 +187,13 @@ vec4 gpencil_vertex(vec4 viewport_size, is_squares = false; } + /* Endpoints, we discard the vertices. */ + if (!is_dot && ma2.x == -1) { + /* We set the vertex at the camera origin to generate 0 fragments. */ + out_ndc = vec4(0.0, 0.0, -3e36, 0.0); + return out_ndc; + } + /* Avoid using a vertex attribute for quad positioning. */ float x = float(gl_VertexID & 1) * 2.0 - 1.0; /* [-1..1] */ float y = float(gl_VertexID & 2) - 1.0; /* [-1..1] */ From 1a986f7ebad5ad49236ce312208a359a954ec496 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Mon, 19 Dec 2022 10:06:47 -0300 Subject: [PATCH 0212/1522] Revert "Fix erratic mouse wrapping movement on Windows (2)" This reverts commit a3a9459050a96e75138b3441c069898f211f179c. And fixes T103337. a3a9459050a9 has some flaws and it needs to go through review (See D16803). Conflicts: intern/ghost/intern/GHOST_SystemWin32.cpp --- intern/ghost/intern/GHOST_SystemWin32.cpp | 55 ++++++++++------------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index d1e0d138918..75a4cc8389a 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -1061,16 +1061,11 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind int32_t x_screen = screen_co[0], y_screen = screen_co[1]; if (window->getCursorGrabModeIsWarp()) { - static uint64_t last_warp_time = 0; - { - /* WORKAROUND: Check the mouse event timestamp so we can ignore mouse-move events that were - * already in the queue before we changed the cursor position. */ - MOUSEMOVEPOINT mp = {x_screen, y_screen}; - ::GetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &mp, &mp, 1, GMMP_USE_DISPLAY_POINTS); - if (mp.time <= last_warp_time) { - return NULL; - } - } + /* WORKAROUND: + * Sometimes Windows ignores `SetCursorPos()` or `SendInput()` calls or the mouse event is + * outdated. Identify these cases by checking if the cursor is not yet within bounds. */ + static bool is_warping_x = false; + static bool is_warping_y = false; int32_t x_new = x_screen; int32_t y_new = y_screen; @@ -1117,35 +1112,31 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind window->getCursorGrabAccum(x_accum, y_accum); if (x_new != x_screen || y_new != y_screen) { - /* WORKAROUND: Store the current time so that we ignore outdated mouse-move events. */ - last_warp_time = ::GetTickCount64(); + system->setCursorPosition(x_new, y_new); /* wrap */ - /* For more control over which timestamp to store in the event, we use `SendInput` instead of - * `SetCursorPos` here. - * It is quite unlikely to happen, but still possible that some event between - * `last_warp_time` and `GHOST_SystemWin32::setCursorPosition` is sent. */ - INPUT input[3] = {0}; - input[0].type = INPUT_MOUSE; - input[0].mi.dx = (LONG)(x_new * (65535.0f / GetSystemMetrics(SM_CXSCREEN))); - input[0].mi.dy = (LONG)(y_new * (65535.0f / GetSystemMetrics(SM_CYSCREEN))); - input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; - input[0].mi.time = last_warp_time; + /* Do not update the accum values if we are an outdated or failed pos-warp event. */ + if (!is_warping_x) { + is_warping_x = x_new != x_screen; + if (is_warping_x) { + x_accum += (x_screen - x_new); + } + } - /* Send 3 events with a jitter to make sure Windows does not occasionally and - * inexplicably ignore `SetCursorPos` or `SendInput`. */ - input[2] = input[1] = input[0]; - input[1].mi.dx += 1; - ::SendInput(3, input, sizeof(INPUT)); - - x_accum += (x_screen - x_new); - y_accum += (y_screen - y_new); + if (!is_warping_y) { + is_warping_y = y_new != y_screen; + if (is_warping_y) { + y_accum += (y_screen - y_new); + } + } window->setCursorGrabAccum(x_accum, y_accum); - /* When wrapping we don't need to add an event because the `SendInput` call will cause new - * events after. */ + /* When wrapping we don't need to add an event because the setCursorPosition call will cause + * a new event after. */ return NULL; } + is_warping_x = false; + is_warping_y = false; x_screen += x_accum; y_screen += y_accum; } From 81f425a36ff6b6d9bbc324a16478955758f9b5ac Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Mon, 19 Dec 2022 17:08:30 +0100 Subject: [PATCH 0213/1522] Metal: Remove Vec3 packing from uniform buffer generation as this causes UBO misalignment in Metal. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Differential Revision: https://developer.blender.org/D16721 --- source/blender/gpu/intern/gpu_uniform_buffer.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/gpu/intern/gpu_uniform_buffer.cc b/source/blender/gpu/intern/gpu_uniform_buffer.cc index 5d9e2af631e..e7e36efd19b 100644 --- a/source/blender/gpu/intern/gpu_uniform_buffer.cc +++ b/source/blender/gpu/intern/gpu_uniform_buffer.cc @@ -14,6 +14,7 @@ #include "gpu_backend.hh" #include "gpu_node_graph.h" +#include "GPU_context.h" #include "GPU_material.h" #include "GPU_uniform_buffer.h" @@ -56,6 +57,10 @@ static eGPUType get_padded_gpu_type(LinkData *link) { GPUInput *input = (GPUInput *)link->data; eGPUType gputype = input->type; + /* Metal cannot pack floats after vec3. */ + if (GPU_backend_get_type() == GPU_BACKEND_METAL) { + return (gputype == GPU_VEC3) ? GPU_VEC4 : gputype; + } /* Unless the vec3 is followed by a float we need to treat it as a vec4. */ if (gputype == GPU_VEC3 && (link->next != nullptr) && (((GPUInput *)link->next->data)->type != GPU_FLOAT)) { @@ -89,6 +94,11 @@ static void buffer_from_list_inputs_sort(ListBase *inputs) /* Order them as mat4, vec4, vec3, vec2, float. */ BLI_listbase_sort(inputs, inputs_cmp); + /* Metal cannot pack floats after vec3. */ + if (GPU_backend_get_type() == GPU_BACKEND_METAL) { + return; + } + /* Creates a lookup table for the different types; */ LinkData *inputs_lookup[MAX_UBO_GPU_TYPE + 1] = {nullptr}; eGPUType cur_type = static_cast(MAX_UBO_GPU_TYPE + 1); From 9f575ece39e8abacb31ee830abcfc7d5830b94b1 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 19 Dec 2022 13:05:05 -0600 Subject: [PATCH 0214/1522] Fix T103307: Crash reading particle hair key.co 05952aa94d33eeb504f accessed the vertex array when the mesh was null. --- source/blender/makesrna/intern/rna_particle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index a56e7d28ef7..aef5aea5bac 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -212,8 +212,8 @@ static void rna_ParticleHairKey_location_object_get(PointerRNA *ptr, float *valu if (pa) { Mesh *hair_mesh = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_mesh : NULL; - const MVert *verts = BKE_mesh_verts(hair_mesh); if (hair_mesh) { + const MVert *verts = BKE_mesh_verts(hair_mesh); const MVert *mv = &verts[pa->hair_index + (hkey - pa->hair)]; copy_v3_v3(values, mv->co); } From 5fe297df48729f7c6614b31e8873ce94d77d957a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 19 Dec 2022 13:59:33 -0600 Subject: [PATCH 0215/1522] Fix: Set position node doesn't tag mesh normals dirty Caused by b08301c865f42ab51b29efb. This also contains an optimization compared to the previous version to avoid recalculating normals when the entire mesh has moved by the same offset. Reported by Demeter in chat. --- .../blender/nodes/geometry/nodes/node_geo_set_position.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index ec8c82fc66d..2a56152a2b4 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -54,6 +54,12 @@ static void set_computed_position_and_offset(GeometryComponent &component, } }); }); + if (in_offsets.is_single() && selection.size() == verts.size()) { + BKE_mesh_tag_coords_changed_uniformly(mesh); + } + else { + BKE_mesh_tag_coords_changed(mesh); + } } else { devirtualize_varray2( @@ -66,6 +72,7 @@ static void set_computed_position_and_offset(GeometryComponent &component, } }); }); + BKE_mesh_tag_coords_changed(mesh); } break; } From 4ae0da1bbc61e5b712508646ef7b4bbea9014abf Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 19 Dec 2022 14:24:49 -0600 Subject: [PATCH 0216/1522] Geometry Nodes: Avoid mesh copy in some cases Accessing a mesh with write access can be costly if it is used elsewhere at the same time because of copy-on-write. When always did that at the end of the modifier calculation, but it's trivial to only do that when we might need actually use the mesh to add original index layers. --- source/blender/modifiers/intern/MOD_nodes.cc | 36 ++++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index f5ede42b0ad..258971c3565 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1282,29 +1282,29 @@ static void modifyGeometry(ModifierData *md, bool use_orig_index_verts = false; bool use_orig_index_edges = false; bool use_orig_index_polys = false; - if (geometry_set.has_mesh()) { - const Mesh &mesh = *geometry_set.get_mesh_for_read(); - use_orig_index_verts = CustomData_has_layer(&mesh.vdata, CD_ORIGINDEX); - use_orig_index_edges = CustomData_has_layer(&mesh.edata, CD_ORIGINDEX); - use_orig_index_polys = CustomData_has_layer(&mesh.pdata, CD_ORIGINDEX); + if (const Mesh *mesh = geometry_set.get_mesh_for_read()) { + use_orig_index_verts = CustomData_has_layer(&mesh->vdata, CD_ORIGINDEX); + use_orig_index_edges = CustomData_has_layer(&mesh->edata, CD_ORIGINDEX); + use_orig_index_polys = CustomData_has_layer(&mesh->pdata, CD_ORIGINDEX); } geometry_set = compute_geometry( tree, *lf_graph_info, *output_node, std::move(geometry_set), nmd, ctx); - if (geometry_set.has_mesh()) { - /* Add #CD_ORIGINDEX layers if they don't exist already. This is required because the - * #eModifierTypeFlag_SupportsMapping flag is set. If the layers did not exist before, it is - * assumed that the output mesh does not have a mapping to the original mesh. */ - Mesh &mesh = *geometry_set.get_mesh_for_write(); - if (use_orig_index_verts) { - CustomData_add_layer(&mesh.vdata, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, mesh.totvert); - } - if (use_orig_index_edges) { - CustomData_add_layer(&mesh.edata, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, mesh.totedge); - } - if (use_orig_index_polys) { - CustomData_add_layer(&mesh.pdata, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, mesh.totpoly); + if (use_orig_index_verts || use_orig_index_edges || use_orig_index_polys) { + if (Mesh *mesh = geometry_set.get_mesh_for_write()) { + /* Add #CD_ORIGINDEX layers if they don't exist already. This is required because the + * #eModifierTypeFlag_SupportsMapping flag is set. If the layers did not exist before, it is + * assumed that the output mesh does not have a mapping to the original mesh. */ + if (use_orig_index_verts) { + CustomData_add_layer(&mesh->vdata, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, mesh->totvert); + } + if (use_orig_index_edges) { + CustomData_add_layer(&mesh->edata, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, mesh->totedge); + } + if (use_orig_index_polys) { + CustomData_add_layer(&mesh->pdata, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, mesh->totpoly); + } } } } From c2a8d8b18ddbcbba9419c00f53f1313d5e1c6f7e Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 19 Dec 2022 14:56:39 -0600 Subject: [PATCH 0217/1522] Fix T103301: Active and default color attributes lost in many operations When creating a new mesh to change it in some way, the active and default color attribute names should be copied to the new mesh. Doing that in the generic "copy parameters for eval" function should cover the vast majority of cases. --- source/blender/blenkernel/intern/mesh.cc | 13 +++++++++++++ source/blender/geometry/intern/realize_instances.cc | 9 --------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index c9418266729..a7f1eb1df00 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -979,6 +979,18 @@ Mesh *BKE_mesh_new_nomain( return mesh; } +static void copy_attribute_names(const Mesh &mesh_src, Mesh &mesh_dst) +{ + if (mesh_src.active_color_attribute) { + MEM_SAFE_FREE(mesh_dst.active_color_attribute); + mesh_dst.active_color_attribute = BLI_strdup(mesh_src.active_color_attribute); + } + if (mesh_src.default_color_attribute) { + MEM_SAFE_FREE(mesh_dst.default_color_attribute); + mesh_dst.default_color_attribute = BLI_strdup(mesh_src.default_color_attribute); + } +} + void BKE_mesh_copy_parameters(Mesh *me_dst, const Mesh *me_src) { /* Copy general settings. */ @@ -1008,6 +1020,7 @@ void BKE_mesh_copy_parameters_for_eval(Mesh *me_dst, const Mesh *me_src) BLI_assert(me_dst->id.tag & (LIB_TAG_NO_MAIN | LIB_TAG_COPIED_ON_WRITE)); BKE_mesh_copy_parameters(me_dst, me_src); + copy_attribute_names(*me_src, *me_dst); /* Copy vertex group names. */ BLI_assert(BLI_listbase_is_empty(&me_dst->vertex_group_names)); diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 2e6fb87e823..57a4ae70b5f 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -1125,15 +1125,6 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, } }); - if (first_mesh.active_color_attribute) { - MEM_SAFE_FREE(dst_mesh->active_color_attribute); - dst_mesh->active_color_attribute = BLI_strdup(first_mesh.active_color_attribute); - } - if (first_mesh.default_color_attribute) { - MEM_SAFE_FREE(dst_mesh->default_color_attribute); - dst_mesh->default_color_attribute = BLI_strdup(first_mesh.default_color_attribute); - } - /* Tag modified attributes. */ for (GSpanAttributeWriter &dst_attribute : dst_attribute_writers) { dst_attribute.finish(); From 194cc8410bd77ccfe24119dcd61468e79641c49c Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 20 Dec 2022 12:14:12 +0900 Subject: [PATCH 0218/1522] Fix (unreported) lost ID tags on undo. ID tags were fully cleared on file write, however some should be written so that they are preserved accross undo steps. Currently this likely did not cause any serious issue, as the missing ones were not that critical. --- source/blender/blenloader/intern/readfile.cc | 4 ++-- source/blender/blenloader/intern/writefile.cc | 2 +- source/blender/makesdna/DNA_ID.h | 9 +++++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index d7db103a460..938041368f0 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -2034,7 +2034,7 @@ static void direct_link_id_common( id->py_instance = nullptr; /* Initialize with provided tag. */ - id->tag = tag; + id->tag = tag | (id->tag & LIB_TAG_KEEP_ON_UNDO); if (ID_IS_LINKED(id)) { id->library_weak_reference = nullptr; @@ -3105,7 +3105,7 @@ static void read_libblock_undo_restore_identical( BLI_assert(id_old != nullptr); /* Some tags need to be preserved here. */ - id_old->tag = tag | (id_old->tag & LIB_TAG_EXTRAUSER); + id_old->tag = tag | (id_old->tag & LIB_TAG_KEEP_ON_UNDO); id_old->lib = main->curlib; id_old->us = ID_FAKE_USERS(id_old); /* Do not reset id->icon_id here, memory allocated for it remains valid. */ diff --git a/source/blender/blenloader/intern/writefile.cc b/source/blender/blenloader/intern/writefile.cc index bc1a90fb022..7e2840c3379 100644 --- a/source/blender/blenloader/intern/writefile.cc +++ b/source/blender/blenloader/intern/writefile.cc @@ -1253,7 +1253,7 @@ static bool write_file_handle(Main *mainvar, memcpy(id_buffer, id, idtype_struct_size); /* Clear runtime data to reduce false detection of changed data in undo/redo context. */ - ((ID *)id_buffer)->tag = 0; + ((ID *)id_buffer)->tag &= LIB_TAG_KEEP_ON_UNDO; ((ID *)id_buffer)->us = 0; ((ID *)id_buffer)->icon_id = 0; /* Those listbase data change every time we add/remove an ID, and also often when diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 3feb341b773..fb23dd8644a 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -848,6 +848,15 @@ enum { LIB_TAG_LIB_OVERRIDE_NEED_RESYNC = 1 << 21, }; +/** + * Most of ID tags are cleared on file write (i.e. also when storing undo steps), since they + * either have of very short lifetime (not expected to exist accross undo steps), or are info that + * will be re-generated when reading undo steps. + * + * However a few of these need to be explicitely preserved accross undo steps. + */ +#define LIB_TAG_KEEP_ON_UNDO (LIB_TAG_EXTRAUSER | LIB_TAG_MISSING) + /* Tag given ID for an update in all the dependency graphs. */ typedef enum IDRecalcFlag { /*************************************************************************** From 9837a32822b97f03a53588682db40ef84d8f7fc7 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 20 Dec 2022 13:05:47 +0900 Subject: [PATCH 0219/1522] Correction to previous commit re ID tags and undo. Explicitely separate handling of ID tags for undo read/write versus regular .blend file read/write. --- source/blender/blenloader/intern/readfile.cc | 7 ++++++- source/blender/blenloader/intern/writefile.cc | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 938041368f0..f7fffd82db4 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -2034,7 +2034,12 @@ static void direct_link_id_common( id->py_instance = nullptr; /* Initialize with provided tag. */ - id->tag = tag | (id->tag & LIB_TAG_KEEP_ON_UNDO); + if (BLO_read_data_is_undo(reader)) { + id->tag = tag | (id->tag & LIB_TAG_KEEP_ON_UNDO); + } + else { + id->tag = tag; + } if (ID_IS_LINKED(id)) { id->library_weak_reference = nullptr; diff --git a/source/blender/blenloader/intern/writefile.cc b/source/blender/blenloader/intern/writefile.cc index 7e2840c3379..a964c9bd983 100644 --- a/source/blender/blenloader/intern/writefile.cc +++ b/source/blender/blenloader/intern/writefile.cc @@ -1253,7 +1253,12 @@ static bool write_file_handle(Main *mainvar, memcpy(id_buffer, id, idtype_struct_size); /* Clear runtime data to reduce false detection of changed data in undo/redo context. */ - ((ID *)id_buffer)->tag &= LIB_TAG_KEEP_ON_UNDO; + if (wd->use_memfile) { + ((ID *)id_buffer)->tag &= LIB_TAG_KEEP_ON_UNDO; + } + else { + ((ID *)id_buffer)->tag = 0; + } ((ID *)id_buffer)->us = 0; ((ID *)id_buffer)->icon_id = 0; /* Those listbase data change every time we add/remove an ID, and also often when From b93025db590a9b64a68015ac6d4f8c208e8a2a52 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 16 Dec 2022 10:13:40 +0900 Subject: [PATCH 0220/1522] Add concept of 'runtime' ID in Main data-base. Such IDs are tagged with the new `LIB_TAG_RUNTIME`. They are essentially like any other regular ID, except that they do not get written in .blend files. They also do not make their linked data usages directly linked. They do be written in undo steps however. This tag should be ignored in any non-Main IDs (e.g. evaluated data, `NO_MAIN`, etc.). This commit also adds a new RNA ID property, `is_runtime`. This is not a direct mapping to the DNA tag, as a non-main ID will also return True, and the property is only editable for Main IDs. Some basic testing for expected behavior of that new tag was also added to `blendfile_io` py unittest. Required for brush asset project, see T101908. Reviewed By: brecht Differential Revision: https://developer.blender.org/D16675 --- source/blender/blenloader/intern/readfile.cc | 7 ++ source/blender/blenloader/intern/writefile.cc | 13 ++- source/blender/makesdna/DNA_ID.h | 12 ++- source/blender/makesrna/intern/rna_ID.c | 38 +++++++++ tests/python/bl_blendfile_io.py | 82 +++++++++++++++++++ 5 files changed, 149 insertions(+), 3 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index f7fffd82db4..87d3255056b 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -2020,8 +2020,15 @@ static void direct_link_id_common( /* When actually reading a file, we do want to reset/re-generate session UUIDS. * In undo case, we want to re-use existing ones. */ id->session_uuid = MAIN_ID_SESSION_UUID_UNSET; + + /* Runtime IDs should never be written in .blend files (except memfiles from undo). */ + BLI_assert((id->tag & LIB_TAG_RUNTIME) == 0); } + /* No-main and other types of special IDs should never be written in .blend files. */ + BLI_assert((id->tag & (LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT | LIB_TAG_NOT_ALLOCATED)) == + 0); + if ((tag & LIB_TAG_TEMP_MAIN) == 0) { BKE_lib_libblock_session_uuid_ensure(id); } diff --git a/source/blender/blenloader/intern/writefile.cc b/source/blender/blenloader/intern/writefile.cc index a964c9bd983..0e3c1645fb4 100644 --- a/source/blender/blenloader/intern/writefile.cc +++ b/source/blender/blenloader/intern/writefile.cc @@ -1097,7 +1097,10 @@ static int write_id_direct_linked_data_process_cb(LibraryIDLinkCallbackData *cb_ } BLI_assert(!ID_IS_LINKED(id_self)); BLI_assert((cb_flag & IDWALK_CB_INDIRECT_USAGE) == 0); - UNUSED_VARS_NDEBUG(id_self); + + if (id_self->tag & LIB_TAG_RUNTIME) { + return IDWALK_RET_NOP; + } if (cb_flag & IDWALK_CB_DIRECT_WEAK_LINK) { id_lib_indirect_weak_link(id); @@ -1207,12 +1210,18 @@ static bool write_file_handle(Main *mainvar, /* We only write unused IDs in undo case. * NOTE: All Scenes, WindowManagers and WorkSpaces should always be written to disk, so - * their user-count should never be nullptr currently. */ + * their user-count should never be zero currently. */ if (id->us == 0 && !wd->use_memfile) { BLI_assert(!ELEM(GS(id->name), ID_SCE, ID_WM, ID_WS)); continue; } + if ((id->tag & LIB_TAG_RUNTIME) != 0 && !wd->use_memfile) { + /* Runtime IDs are never written to .blend files, and they should not influence + * (in)direct status of linked IDs they may use. */ + continue; + } + const bool do_override = !ELEM(override_storage, nullptr, bmain) && ID_IS_OVERRIDE_LIBRARY_REAL(id); diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index fb23dd8644a..90d44d95139 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -808,6 +808,16 @@ enum { * RESET_NEVER */ LIB_TAG_NO_MAIN = 1 << 15, + /** + * ID is considered as runtime, and should not be saved when writing .blend file, nor influence + * (in)direct status of linked data. + * + * Only meaningful for IDs belonging to regular Main database, all other cases are implicitely + * considered runtime-only. + * + * RESET_NEVER + */ + LIB_TAG_RUNTIME = 1 << 22, /** * Datablock does not refcount usages of other IDs. * @@ -855,7 +865,7 @@ enum { * * However a few of these need to be explicitely preserved accross undo steps. */ -#define LIB_TAG_KEEP_ON_UNDO (LIB_TAG_EXTRAUSER | LIB_TAG_MISSING) +#define LIB_TAG_KEEP_ON_UNDO (LIB_TAG_EXTRAUSER | LIB_TAG_MISSING | LIB_TAG_RUNTIME) /* Tag given ID for an update in all the dependency graphs. */ typedef enum IDRecalcFlag { diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index f9dbd0bc824..7a13d840c9a 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -574,6 +574,33 @@ IDProperty **rna_ID_idprops(PointerRNA *ptr) return &id->properties; } +int rna_ID_is_runtime_editable(PointerRNA *ptr, const char **r_info) +{ + ID *id = (ID *)ptr->data; + /* TODO: This should be abstracted in a BKE function or define, somewhat related to T88555. */ + if (id->tag & (LIB_TAG_NO_MAIN | LIB_TAG_TEMP_MAIN | LIB_TAG_LOCALIZED | + LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT | LIB_TAG_COPIED_ON_WRITE)) { + *r_info = + "Cannot edit 'runtime' status of non-blendfile data-blocks, as they are by definition " + "always runtime"; + return 0; + } + + return PROP_EDITABLE; +} + +bool rna_ID_is_runtime_get(PointerRNA *ptr) +{ + ID *id = (ID *)ptr->data; + /* TODO: This should be abstracted in a BKE function or define, somewhat related to T88555. */ + if (id->tag & (LIB_TAG_NO_MAIN | LIB_TAG_TEMP_MAIN | LIB_TAG_LOCALIZED | + LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT | LIB_TAG_COPIED_ON_WRITE)) { + return true; + } + + return (id->tag & LIB_TAG_RUNTIME) != 0; +} + void rna_ID_fake_user_set(PointerRNA *ptr, bool value) { ID *id = (ID *)ptr->data; @@ -2030,6 +2057,17 @@ static void rna_def_ID(BlenderRNA *brna) "This data-block is not an independent one, but is actually a sub-data of another ID " "(typical example: root node trees or master collections)"); + prop = RNA_def_property(srna, "is_runtime_data", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "tag", LIB_TAG_RUNTIME); + RNA_def_property_editable_func(prop, "rna_ID_is_runtime_editable"); + RNA_def_property_boolean_funcs(prop, "rna_ID_is_runtime_get", NULL); + RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON); + RNA_def_property_ui_text(prop, + "Runtime Data", + "This data-block is runtime data, i.e. it won't be saved in .blend " + "file. Note that e.g. evaluated IDs are always runtime, so this value " + "is only editable for data-blocks in Main data-base"); + prop = RNA_def_property(srna, "tag", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "tag", LIB_TAG_DOIT); RNA_def_property_flag(prop, PROP_LIB_EXCEPTION); diff --git a/tests/python/bl_blendfile_io.py b/tests/python/bl_blendfile_io.py index fa63b789751..ae49afdfadb 100644 --- a/tests/python/bl_blendfile_io.py +++ b/tests/python/bl_blendfile_io.py @@ -47,8 +47,90 @@ class TestBlendFileSaveLoadBasic(TestHelper): assert orig_data == read_data +# NOTE: Technically this should rather be in `bl_id_management.py` test, but that file uses `unittest` module, +# which makes mixing it with tests system used here and passing extra parameters complicated. +# Since the main effect of 'RUNTIME' ID tag is on file save, it can as well be here for now. +class TestIdRuntimeTag(TestHelper): + + def __init__(self, args): + self.args = args + + def unique_blendfile_name(self, base_name): + return base_name + self.__class__.__name__ + ".blend" + + def test_basics(self): + output_dir = self.args.output_dir + self.ensure_path(output_dir) + bpy.ops.wm.read_homefile(use_empty=False, use_factory_startup=True) + + obj = bpy.data.objects['Cube'] + assert obj.is_runtime_data == False + assert bpy.context.view_layer.depsgraph.ids['Cube'].is_runtime_data == True + + output_work_path = os.path.join(output_dir, self.unique_blendfile_name("blendfile")) + bpy.ops.wm.save_as_mainfile(filepath=output_work_path, check_existing=False, compress=False) + + bpy.ops.wm.open_mainfile(filepath=output_work_path, load_ui=False) + obj = bpy.data.objects['Cube'] + assert obj.is_runtime_data == False + + obj.is_runtime_data = True + assert obj.is_runtime_data == True + + bpy.ops.wm.save_as_mainfile(filepath=output_work_path, check_existing=False, compress=False) + bpy.ops.wm.open_mainfile(filepath=output_work_path, load_ui=False) + + assert 'Cube' not in bpy.data.objects + mesh = bpy.data.meshes['Cube'] + assert mesh.is_runtime_data == False + assert mesh.users == 0 + + def test_linking(self): + output_dir = self.args.output_dir + self.ensure_path(output_dir) + bpy.ops.wm.read_homefile(use_empty=False, use_factory_startup=True) + + material = bpy.data.materials.new("LibMaterial") + material.use_fake_user = True + + output_lib_path = os.path.join(output_dir, self.unique_blendfile_name("blendlib_runtimetag_basic")) + bpy.ops.wm.save_as_mainfile(filepath=output_lib_path, check_existing=False, compress=False) + + bpy.ops.wm.read_homefile(use_empty=False, use_factory_startup=True) + + obj = bpy.data.objects['Cube'] + assert obj.is_runtime_data == False + obj.is_runtime_data = True + + link_dir = os.path.join(output_lib_path, "Material") + bpy.ops.wm.link(directory=link_dir, filename="LibMaterial") + + linked_material = bpy.data.materials['LibMaterial'] + assert linked_material.is_library_indirect == False + + obj.material_slots[0].link = 'OBJECT' + obj.material_slots[0].material = linked_material + + output_work_path = os.path.join(output_dir, self.unique_blendfile_name("blendfile")) + bpy.ops.wm.save_as_mainfile(filepath=output_work_path, check_existing=False, compress=False) + + # Only usage of this linked material is a runtime ID (object), + # so writing .blend file will have properly reset its tag to indirectly linked data. + assert linked_material.is_library_indirect == True + + bpy.ops.wm.open_mainfile(filepath=output_work_path, load_ui=False) + + assert 'Cube' not in bpy.data.objects + assert 'LibMaterial' not in bpy.data.materials + mesh = bpy.data.meshes['Cube'] + assert mesh.is_runtime_data == False + assert mesh.users == 0 + + TESTS = ( TestBlendFileSaveLoadBasic, + + TestIdRuntimeTag, ) From edb5dcaa31709241f964293e1514d2b81e4ef25e Mon Sep 17 00:00:00 2001 From: Yiming Wu Date: Mon, 19 Dec 2022 21:43:59 +0800 Subject: [PATCH 0221/1522] Cleanup: Uninitialized variables in lineart_shadow.c --- .../blender/gpencil_modifiers/intern/lineart/lineart_shadow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c index edea052e728..7ac1ecb3796 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c @@ -588,7 +588,7 @@ static void lineart_shadow_edge_cut(LineartData *ld, new_seg_2->ratio = end; } - double r_fb_co_1[4], r_fb_co_2[4], r_gloc_1[3], r_gloc_2[3]; + double r_fb_co_1[4]={0}, r_fb_co_2[4]={0}, r_gloc_1[3]={0}, r_gloc_2[3]={0}; double r_new_in_the_middle[4], r_new_in_the_middle_global[3], r_new_at; double *s1_fb_co_1, *s1_fb_co_2, *s1_gloc_1, *s1_gloc_2; From 105c0aa5b6dea92751e6ee459d91a79f7d6b2240 Mon Sep 17 00:00:00 2001 From: Omar Emara Date: Tue, 20 Dec 2022 10:09:25 +0200 Subject: [PATCH 0222/1522] Fix T103064: Realtime Compositor crashes on undo The Realtime Compositor crashes on undo after an operation like Dissolve node. The compositor evaluator stored a reference to the compositor node tree assuming that it will always be valid. This is not guaranteed, however, and changes to the node tree can invalidate that reference. So we get the node tree from the context directly every time to fix the crash. --- .../compositor/realtime_compositor/COM_evaluator.hh | 9 +++++---- .../compositor/realtime_compositor/intern/evaluator.cc | 5 ++--- .../blender/draw/engines/compositor/compositor_engine.cc | 8 +------- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/source/blender/compositor/realtime_compositor/COM_evaluator.hh b/source/blender/compositor/realtime_compositor/COM_evaluator.hh index 258a2a038c4..c8e953da268 100644 --- a/source/blender/compositor/realtime_compositor/COM_evaluator.hh +++ b/source/blender/compositor/realtime_compositor/COM_evaluator.hh @@ -102,8 +102,9 @@ class Evaluator { private: /* A reference to the compositor context. */ Context &context_; - /* A reference to the compositor node tree. */ - bNodeTree &node_tree_; + /* A derived node tree representing the compositor node tree. This is constructed when the node + * tree is compiled and reset when the evaluator is reset, so it gets reconstructed every time + * the node tree changes. */ std::unique_ptr derived_node_tree_; /* The compiled operations stream. This contains ordered pointers to the operations that were * compiled. This is initialized when the node tree is compiled and freed when the evaluator @@ -116,8 +117,8 @@ class Evaluator { bool is_compiled_ = false; public: - /* Construct an evaluator from a compositor node tree and a context. */ - Evaluator(Context &context, bNodeTree &node_tree); + /* Construct an evaluator from a context. */ + Evaluator(Context &context); /* Evaluate the compositor node tree. If the node tree is already compiled into an operations * stream, that stream will be evaluated directly. Otherwise, the node tree will be compiled and diff --git a/source/blender/compositor/realtime_compositor/intern/evaluator.cc b/source/blender/compositor/realtime_compositor/intern/evaluator.cc index 1cd7d4f8951..1b52e1d381d 100644 --- a/source/blender/compositor/realtime_compositor/intern/evaluator.cc +++ b/source/blender/compositor/realtime_compositor/intern/evaluator.cc @@ -21,8 +21,7 @@ namespace blender::realtime_compositor { using namespace nodes::derived_node_tree_types; -Evaluator::Evaluator(Context &context, bNodeTree &node_tree) - : context_(context), node_tree_(node_tree) +Evaluator::Evaluator(Context &context) : context_(context) { } @@ -67,7 +66,7 @@ bool Evaluator::validate_node_tree() void Evaluator::compile_and_evaluate() { - derived_node_tree_ = std::make_unique(node_tree_); + derived_node_tree_ = std::make_unique(*context_.get_scene()->nodetree); if (!validate_node_tree()) { return; diff --git a/source/blender/draw/engines/compositor/compositor_engine.cc b/source/blender/draw/engines/compositor/compositor_engine.cc index 3b7378f280b..03ef0be81b4 100644 --- a/source/blender/draw/engines/compositor/compositor_engine.cc +++ b/source/blender/draw/engines/compositor/compositor_engine.cc @@ -90,7 +90,7 @@ class Engine { public: Engine(char *info_message) : context_(texture_pool_, info_message), - evaluator_(context_, node_tree()), + evaluator_(context_), last_viewport_size_(context_.get_output_size()) { } @@ -124,12 +124,6 @@ class Engine { evaluator_.reset(); } } - - /* Get a reference to the compositor node tree. */ - static bNodeTree &node_tree() - { - return *DRW_context_state_get()->scene->nodetree; - } }; } // namespace blender::draw::compositor From 844b6e39826ff62334705307b1e5cc1eb286d298 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 20 Dec 2022 13:05:02 +0100 Subject: [PATCH 0223/1522] Nodes: use CacheMutex to protect topology cache No functional changes are expected. --- source/blender/blenkernel/BKE_node_runtime.hh | 8 +- source/blender/blenkernel/intern/node.cc | 2 +- .../blender/blenkernel/intern/node_runtime.cc | 79 +++++++------------ .../blenkernel/intern/node_tree_update.cc | 2 +- 4 files changed, 34 insertions(+), 57 deletions(-) diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index b4b9df32663..4ecc82b7fc3 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -5,6 +5,7 @@ #include #include +#include "BLI_cache_mutex.hh" #include "BLI_multi_value_map.hh" #include "BLI_utility_mixins.hh" #include "BLI_vector.hh" @@ -119,9 +120,8 @@ class bNodeTreeRuntime : NonCopyable, NonMovable { * Protects access to all topology cache variables below. This is necessary so that the cache can * be updated on a const #bNodeTree. */ - std::mutex topology_cache_mutex; - bool topology_cache_is_dirty = true; - bool topology_cache_exists = false; + CacheMutex topology_cache_mutex; + std::atomic topology_cache_exists = false; /** * Under some circumstances, it can be useful to use the cached data while editing the * #bNodeTree. By default, this is protected against using an assert. @@ -298,7 +298,7 @@ inline bool topology_cache_is_available(const bNodeTree &tree) if (tree.runtime->allow_use_dirty_topology_cache.load() > 0) { return true; } - if (tree.runtime->topology_cache_is_dirty) { + if (tree.runtime->topology_cache_mutex.is_dirty()) { return false; } return true; diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 84bf186367b..66c90745110 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -2010,7 +2010,7 @@ bNode *nodeFindNodebyName(bNodeTree *ntree, const char *name) void nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **r_node, int *r_sockindex) { *r_node = nullptr; - if (!ntree->runtime->topology_cache_is_dirty) { + if (ntree->runtime->topology_cache_mutex.is_cached()) { bNode *node = &sock->owner_node(); *r_node = node; if (r_sockindex) { diff --git a/source/blender/blenkernel/intern/node_runtime.cc b/source/blender/blenkernel/intern/node_runtime.cc index 0f0b04f920e..642dfcc0490 100644 --- a/source/blender/blenkernel/intern/node_runtime.cc +++ b/source/blender/blenkernel/intern/node_runtime.cc @@ -22,26 +22,6 @@ void preprocess_geometry_node_tree_for_evaluation(bNodeTree &tree_cow) blender::nodes::ensure_geometry_nodes_lazy_function_graph(tree_cow); } -static void double_checked_lock(std::mutex &mutex, bool &data_is_dirty, FunctionRef fn) -{ - if (!data_is_dirty) { - return; - } - std::lock_guard lock{mutex}; - if (!data_is_dirty) { - return; - } - fn(); - data_is_dirty = false; -} - -static void double_checked_lock_with_task_isolation(std::mutex &mutex, - bool &data_is_dirty, - FunctionRef fn) -{ - double_checked_lock(mutex, data_is_dirty, [&]() { threading::isolate_task(fn); }); -} - static void update_interface_sockets(const bNodeTree &ntree) { bNodeTreeRuntime &tree_runtime = *ntree.runtime; @@ -434,37 +414,34 @@ static void update_group_output_node(const bNodeTree &ntree) static void ensure_topology_cache(const bNodeTree &ntree) { bNodeTreeRuntime &tree_runtime = *ntree.runtime; - double_checked_lock_with_task_isolation( - tree_runtime.topology_cache_mutex, tree_runtime.topology_cache_is_dirty, [&]() { - update_interface_sockets(ntree); - update_node_vector(ntree); - update_link_vector(ntree); - update_socket_vectors_and_owner_node(ntree); - update_internal_link_inputs(ntree); - update_directly_linked_links_and_sockets(ntree); - threading::parallel_invoke( - tree_runtime.nodes_by_id.size() > 32, - [&]() { update_logical_origins(ntree); }, - [&]() { update_nodes_by_type(ntree); }, - [&]() { update_sockets_by_identifier(ntree); }, - [&]() { - update_toposort(ntree, - ToposortDirection::LeftToRight, - tree_runtime.toposort_left_to_right, - tree_runtime.has_available_link_cycle); - }, - [&]() { - bool dummy; - update_toposort(ntree, - ToposortDirection::RightToLeft, - tree_runtime.toposort_right_to_left, - dummy); - }, - [&]() { update_root_frames(ntree); }, - [&]() { update_direct_frames_childrens(ntree); }); - update_group_output_node(ntree); - tree_runtime.topology_cache_exists = true; - }); + tree_runtime.topology_cache_mutex.ensure([&]() { + update_interface_sockets(ntree); + update_node_vector(ntree); + update_link_vector(ntree); + update_socket_vectors_and_owner_node(ntree); + update_internal_link_inputs(ntree); + update_directly_linked_links_and_sockets(ntree); + threading::parallel_invoke( + tree_runtime.nodes_by_id.size() > 32, + [&]() { update_logical_origins(ntree); }, + [&]() { update_nodes_by_type(ntree); }, + [&]() { update_sockets_by_identifier(ntree); }, + [&]() { + update_toposort(ntree, + ToposortDirection::LeftToRight, + tree_runtime.toposort_left_to_right, + tree_runtime.has_available_link_cycle); + }, + [&]() { + bool dummy; + update_toposort( + ntree, ToposortDirection::RightToLeft, tree_runtime.toposort_right_to_left, dummy); + }, + [&]() { update_root_frames(ntree); }, + [&]() { update_direct_frames_childrens(ntree); }); + update_group_output_node(ntree); + tree_runtime.topology_cache_exists = true; + }); } } // namespace blender::bke::node_tree_runtime diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc index a49baf11680..2750d6ce0c8 100644 --- a/source/blender/blenkernel/intern/node_tree_update.cc +++ b/source/blender/blenkernel/intern/node_tree_update.cc @@ -51,7 +51,7 @@ enum eNodeTreeChangedFlag { static void add_tree_tag(bNodeTree *ntree, const eNodeTreeChangedFlag flag) { ntree->runtime->changed_flag |= flag; - ntree->runtime->topology_cache_is_dirty = true; + ntree->runtime->topology_cache_mutex.tag_dirty(); } static void add_node_tag(bNodeTree *ntree, bNode *node, const eNodeTreeChangedFlag flag) From 2712265598a09c3868b9d097488f22d42efbf6eb Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Tue, 20 Dec 2022 14:03:22 +0100 Subject: [PATCH 0224/1522] Metal: Addressing a number of small outstanding issues across Metal backend. - Support for non-contiguous shader resource bindings for all cases required by create-info - Implement missing geometry shader alternative path for edit curve handle. - Add support for non-float dummy textures to address all cases where default bindings may be required. Authored by Apple: Michael Parkin-White Ref T96261 Depends on D16721 Reviewed By: fclem Differential Revision: https://developer.blender.org/D16777 --- .../shaders/infos/overlay_edit_mode_info.hh | 4 +- ...verlay_edit_curve_handle_vert_no_geom.glsl | 162 +++++++++++++++++- .../gpu/intern/gpu_shader_create_info.cc | 2 + .../blender/gpu/intern/gpu_texture_private.hh | 13 ++ source/blender/gpu/metal/mtl_batch.mm | 68 +++++--- source/blender/gpu/metal/mtl_context.hh | 8 +- source/blender/gpu/metal/mtl_context.mm | 150 ++++++++++------ source/blender/gpu/metal/mtl_drawlist.mm | 3 +- source/blender/gpu/metal/mtl_framebuffer.mm | 10 +- source/blender/gpu/metal/mtl_immediate.mm | 6 +- .../gpu/metal/mtl_pso_descriptor_state.hh | 15 +- source/blender/gpu/metal/mtl_shader.mm | 37 ++-- .../blender/gpu/metal/mtl_shader_generator.hh | 1 + .../blender/gpu/metal/mtl_shader_generator.mm | 69 +++++++- .../blender/gpu/metal/mtl_shader_interface.hh | 4 + .../blender/gpu/metal/mtl_shader_interface.mm | 16 +- .../gpu/metal/mtl_shader_interface_type.hh | 23 +++ source/blender/gpu/metal/mtl_texture.mm | 5 - source/blender/gpu/metal/mtl_vertex_buffer.hh | 1 + source/blender/imbuf/intern/util_gpu.c | 18 +- 20 files changed, 480 insertions(+), 135 deletions(-) diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh index 3e0492d024c..b1c28bcb3e3 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_edit_mode_info.hh @@ -397,8 +397,8 @@ GPU_SHADER_CREATE_INFO(overlay_edit_curve_handle_no_geom) /* NOTE: Color already in Linear space. Which is what we want. */ .define("srgbTarget", "false") .vertex_in(0, Type::VEC3, "pos") - .vertex_in(1, Type::UINT, "data") - .vertex_out(overlay_edit_curve_handle_iface) + .vertex_in(1, Type::UCHAR, "data") + .vertex_out(overlay_edit_smooth_color_iface) .push_constant(Type::BOOL, "showCurveHandles") .push_constant(Type::INT, "curveHandleDisplay") .fragment_out(0, Type::VEC4, "fragColor") diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl index 8b4b7afb996..518b98e4ce5 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_curve_handle_vert_no_geom.glsl @@ -1,16 +1,166 @@ -/* TODO(Metal): Implement correct SSBO implementation for geom shader workaround. - * Currently included as placeholder to unblock failing compilation in Metal. */ #pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl) #pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma USE_SSBO_VERTEX_FETCH(TriangleStrip, 10) + +#define DISCARD_VERTEX \ + gl_Position = vec4(0.0); \ + finalColor = vec4(0.0); \ + return; + +void output_line(vec2 offset, vec4 color, vec3 out_world_pos, vec4 out_ndc_pos) +{ + finalColor = color; + gl_Position = out_ndc_pos; + gl_Position.xy += offset * out_ndc_pos.w; + view_clipping_distances(out_world_pos); +} void main() { GPU_INTEL_VERTEX_SHADER_WORKAROUND - vec3 world_pos = point_object_to_world(pos); - gl_Position = point_world_to_ndc(world_pos); - vert.flag = data; + /* Perform vertex shader for each input primitive. */ + vec3 in_pos[2]; + vec3 world_pos[2]; + vec4 ndc_pos[2]; + uint vert_flag[2]; - view_clipping_distances(world_pos); + /* Input prim is LineList. */ + /* Index of the input line primitive. */ + int input_line_id = gl_VertexID / 10; + /* Index of output vertex set. Grouped into pairs as outputted by original "output_line" function + * in overlay_edit_curve_handle_geom.glsl. */ + int output_prim_id = (gl_VertexID / 2) % 5; + /* ID of vertex within line primitive (0 or 1) for current vertex. */ + int output_prim_vert_id = gl_VertexID % 2; + + for (int i = 0; i < 2; i++) { + in_pos[i] = vertex_fetch_attribute((input_line_id * 2) + i, pos, vec3).xyz; + vert_flag[i] = (uint)vertex_fetch_attribute((input_line_id * 2) + i, data, uchar); + world_pos[i] = point_object_to_world(in_pos[i]); + ndc_pos[i] = point_world_to_ndc(world_pos[i]); + } + + /* Perform Geometry shader equivalent calculation. */ + uint is_active_nurb = (vert_flag[1] & ACTIVE_NURB); + uint color_id = (vert_flag[1] >> COLOR_SHIFT); + + /* Don't output any edges if we don't show handles */ + if (!showCurveHandles && (color_id < 5)) { + return; + } + + bool edge_selected = (((vert_flag[1] | vert_flag[0]) & VERT_SELECTED) != 0u); + bool handle_selected = (showCurveHandles && + (((vert_flag[1] | vert_flag[0]) & VERT_SELECTED_BEZT_HANDLE) != 0u)); + + bool is_gpencil = ((vert_flag[1] & VERT_GPENCIL_BEZT_HANDLE) != 0u); + + /* If handle type is only selected and the edge is not selected, don't show. */ + if ((curveHandleDisplay != CURVE_HANDLE_ALL) && (!handle_selected)) { + /* Nurbs must show the handles always. */ + bool is_u_segment = (((vert_flag[1] ^ vert_flag[0]) & EVEN_U_BIT) != 0u); + if ((!is_u_segment) && (color_id <= 4)) { + return; + } + if (is_gpencil) { + return; + } + } + + vec4 inner_color; + if (color_id == 0) { + inner_color = (edge_selected) ? colorHandleSelFree : colorHandleFree; + } + else if (color_id == 1) { + inner_color = (edge_selected) ? colorHandleSelAuto : colorHandleAuto; + } + else if (color_id == 2) { + inner_color = (edge_selected) ? colorHandleSelVect : colorHandleVect; + } + else if (color_id == 3) { + inner_color = (edge_selected) ? colorHandleSelAlign : colorHandleAlign; + } + else if (color_id == 4) { + inner_color = (edge_selected) ? colorHandleSelAutoclamp : colorHandleAutoclamp; + } + else { + bool is_selected = (((vert_flag[1] & vert_flag[0]) & VERT_SELECTED) != 0); + bool is_u_segment = (((vert_flag[1] ^ vert_flag[0]) & EVEN_U_BIT) != 0); + if (is_u_segment) { + inner_color = (is_selected) ? colorNurbSelUline : colorNurbUline; + } + else { + inner_color = (is_selected) ? colorNurbSelVline : colorNurbVline; + } + } + + vec4 outer_color = (is_active_nurb != 0) ? + mix(colorActiveSpline, + inner_color, + 0.25) /* Minimize active color bleeding on inner_color. */ + : + vec4(inner_color.rgb, 0.0); + + vec2 v1_2 = (ndc_pos[1].xy / ndc_pos[1].w - ndc_pos[0].xy / ndc_pos[0].w); + vec2 offset = sizeEdge * 4.0 * sizeViewportInv; /* 4.0 is eyeballed */ + + if (abs(v1_2.x * sizeViewport.x) < abs(v1_2.y * sizeViewport.y)) { + offset.y = 0.0; + } + else { + offset.x = 0.0; + } + + /* Output geometry based on output line ID. */ + switch (output_prim_id) { + case 0: { + /* draw the transparent border (AA). */ + if (is_active_nurb != 0u) { + offset *= 0.75; /* Don't make the active "halo" appear very thick. */ + output_line(offset * 2.0, + vec4(colorActiveSpline.rgb, 0.0), + world_pos[output_prim_vert_id], + ndc_pos[output_prim_vert_id]); + } + else { + DISCARD_VERTEX + } + break; + } + case 1: { + /* draw the outline. */ + output_line( + offset, outer_color, world_pos[output_prim_vert_id], ndc_pos[output_prim_vert_id]); + break; + } + case 2: { + /* draw the core of the line. */ + output_line( + vec2(0.0), inner_color, world_pos[output_prim_vert_id], ndc_pos[output_prim_vert_id]); + break; + } + case 3: { + /* draw the outline. */ + output_line( + -offset, outer_color, world_pos[output_prim_vert_id], ndc_pos[output_prim_vert_id]); + break; + } + case 4: { + /* draw the transparent border (AA). */ + if (is_active_nurb != 0u) { + output_line(offset * -2.0, + vec4(colorActiveSpline.rgb, 0.0), + world_pos[output_prim_vert_id], + ndc_pos[output_prim_vert_id]); + } + break; + } + + default: { + DISCARD_VERTEX + break; + } + } } diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc index bc3f462e9f9..0e3057ee8c1 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.cc +++ b/source/blender/gpu/intern/gpu_shader_create_info.cc @@ -334,6 +334,8 @@ void gpu_shader_create_info_init() overlay_edit_mesh_edge_flat = overlay_edit_mesh_edge_flat_no_geom; overlay_edit_mesh_edge_clipped = overlay_edit_mesh_edge_clipped_no_geom; overlay_edit_mesh_edge_flat_clipped = overlay_edit_mesh_edge_flat_clipped_no_geom; + overlay_edit_curve_handle = overlay_edit_curve_handle_no_geom; + overlay_edit_curve_handle_clipped = overlay_edit_curve_handle_clipped_no_geom; /* Overlay Armature Shape outline. */ overlay_armature_shape_outline = overlay_armature_shape_outline_no_geom; diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh index 115e38443b5..fc5e39a3534 100644 --- a/source/blender/gpu/intern/gpu_texture_private.hh +++ b/source/blender/gpu/intern/gpu_texture_private.hh @@ -43,6 +43,19 @@ typedef enum eGPUTextureType { ENUM_OPERATORS(eGPUTextureType, GPU_TEXTURE_CUBE_ARRAY) +/* Format types for samplers within the shader. + * This covers the sampler format type permutations within GLSL/MSL.*/ +typedef enum eGPUSamplerFormat { + GPU_SAMPLER_TYPE_FLOAT = 0, + GPU_SAMPLER_TYPE_INT = 1, + GPU_SAMPLER_TYPE_UINT = 2, + /* Special case for depth, as these require differing dummy formats. */ + GPU_SAMPLER_TYPE_DEPTH = 3, + GPU_SAMPLER_TYPE_MAX = 4 +} eGPUSamplerFormat; + +ENUM_OPERATORS(eGPUSamplerFormat, GPU_SAMPLER_TYPE_UINT) + #ifdef DEBUG # define DEBUG_NAME_LEN 64 #else diff --git a/source/blender/gpu/metal/mtl_batch.mm b/source/blender/gpu/metal/mtl_batch.mm index 768278ec0c6..13496e8ad6f 100644 --- a/source/blender/gpu/metal/mtl_batch.mm +++ b/source/blender/gpu/metal/mtl_batch.mm @@ -154,11 +154,13 @@ int MTLBatch::prepare_vertex_binding(MTLVertBuf *verts, continue; } - /* Fetch metal attribute information. */ - const MTLShaderInputAttribute &mtl_attr = interface->get_attribute(input->location); + /* Fetch metal attribute information (ShaderInput->binding is used to fetch the corresponding + * slot. */ + const MTLShaderInputAttribute &mtl_attr = interface->get_attribute(input->binding); BLI_assert(mtl_attr.location >= 0); /* Verify that the attribute location from the shader interface - * matches the attribute location returned. */ + * matches the attribute location returned in the input table. These should always be the + * same. */ BLI_assert(mtl_attr.location == input->location); /* Check if attribute is already present in the given slot. */ @@ -247,12 +249,16 @@ int MTLBatch::prepare_vertex_binding(MTLVertBuf *verts, buffer_index; /* Update total attribute account. */ - desc.vertex_descriptor.num_attributes = max_ii( - mtl_attr.location + i + 1, desc.vertex_descriptor.num_attributes); + desc.vertex_descriptor.total_attributes++; + desc.vertex_descriptor.max_attribute_value = max_ii( + mtl_attr.location + i, desc.vertex_descriptor.max_attribute_value); MTL_LOG_INFO("-- Sub-Attrib Location: %d, offset: %d, buffer index: %d\n", mtl_attr.location + i, attribute_offset + i * 16, buffer_index); + + /* Update attribute used-slot mask for array elements. */ + attr_mask &= ~(1 << (mtl_attr.location + i)); } MTL_LOG_INFO( "Float4x4 attribute type added for '%s' at attribute locations: %d to %d\n", @@ -262,7 +268,8 @@ int MTLBatch::prepare_vertex_binding(MTLVertBuf *verts, } /* Ensure we are not exceeding the attribute limit. */ - BLI_assert(desc.vertex_descriptor.num_attributes <= MTL_MAX_VERTEX_INPUT_ATTRIBUTES); + BLI_assert(desc.vertex_descriptor.max_attribute_value < + MTL_MAX_VERTEX_INPUT_ATTRIBUTES); } } else { @@ -330,11 +337,11 @@ int MTLBatch::prepare_vertex_binding(MTLVertBuf *verts, } desc.vertex_descriptor.attributes[mtl_attr.location].offset = attribute_offset; desc.vertex_descriptor.attributes[mtl_attr.location].buffer_index = buffer_index; - desc.vertex_descriptor.num_attributes = ((mtl_attr.location + 1) > - desc.vertex_descriptor.num_attributes) ? - (mtl_attr.location + 1) : - desc.vertex_descriptor.num_attributes; - + desc.vertex_descriptor.max_attribute_value = + ((mtl_attr.location) > desc.vertex_descriptor.max_attribute_value) ? + (mtl_attr.location) : + desc.vertex_descriptor.max_attribute_value; + desc.vertex_descriptor.total_attributes++; /* SSBO Vertex Fetch attribute bind. */ if (active_shader_->get_uses_ssbo_vertex_fetch()) { BLI_assert_msg(desc.vertex_descriptor.attributes[mtl_attr.location].format == @@ -356,9 +363,9 @@ int MTLBatch::prepare_vertex_binding(MTLVertBuf *verts, desc.vertex_descriptor.num_ssbo_attributes++; } - /* NOTE: We are setting num_attributes to be up to the maximum found index, because of - * this, it is possible that we may skip over certain attributes if they were not in the - * source GPUVertFormat. */ + /* NOTE: We are setting max_attribute_value to be up to the maximum found index, because + * of this, it is possible that we may skip over certain attributes if they were not in + * the source GPUVertFormat. */ MTL_LOG_INFO( " -- Batch Attribute(%d): ORIG Shader Format: %d, ORIG Vert format: %d, Vert " "components: %d, Fetch Mode %d --> FINAL FORMAT: %d\n", @@ -472,6 +479,9 @@ id MTLBatch::bind(uint v_first, uint v_count, uint i_fi this->elem ? @"(indexed)" : @"", active_shader_->get_interface()->get_name()]]; } + + /*** Bind Vertex Buffers and Index Buffers **/ + /* SSBO Vertex Fetch Buffer bindings. */ if (uses_ssbo_fetch) { @@ -536,7 +546,7 @@ id MTLBatch::bind(uint v_first, uint v_count, uint i_fi * This should happen after all other final rendering setup is complete. */ MTLPrimitiveType mtl_prim_type = gpu_prim_type_to_metal(this->prim_type); if (!ctx->ensure_render_pipeline_state(mtl_prim_type)) { - printf("FAILED TO ENSURE RENDER PIPELINE STATE"); + MTL_LOG_ERROR("Failed to prepare and apply render pipeline state.\n"); BLI_assert(false); if (G.debug & G_DEBUG_GPU) { @@ -705,18 +715,22 @@ void MTLBatch::prepare_vertex_descriptor_and_bindings( /* DEBUG: verify if our attribute bindings have been fully provided as expected. */ #if MTL_DEBUG_SHADER_ATTRIBUTES == 1 if (attr_mask != 0) { - for (uint16_t mask = 1, a = 0; a < 16; a++, mask <<= 1) { - if (attr_mask & mask) { - /* Fallback for setting default attributes, for missed slots. Attributes flagged with - * 'MTLVertexFormatInvalid' in the vertex descriptor are bound to a NULL buffer during PSO - * creation. */ - MTL_LOG_WARNING("MTLBatch: Missing expected attribute '%s' at index '%d' for shader: %s\n", - this->active_shader->interface->attributes[a].name, - a, - interface->name); - /* Ensure any assigned attribute has not been given an invalid format. This should not - * occur and may be the result of an unsupported attribute type conversion. */ - BLI_assert(desc.attributes[a].format == MTLVertexFormatInvalid); + /* Attributes are not necessarily contiguous. */ + for (int i = 0; i < active_shader_->get_interface()->get_total_attributes(); i++) { + const MTLShaderInputAttribute &attr = active_shader_->get_interface()->get_attribute(i); + if (attr_mask & (1 << attr.location)) { + MTL_LOG_WARNING( + "Warning: Missing expected attribute '%s' with location: %u in shader %s (attr " + "number: %u)\n", + active_shader_->get_interface()->get_name_at_offset(attr.name_offset), + attr.location, + active_shader_->name_get(), + i); + + /* If an attribute is not included, then format in vertex descriptor should be invalid due + * to nil assignment. */ + BLI_assert(desc.vertex_descriptor.attributes[attr.location].format == + MTLVertexFormatInvalid); } } } diff --git a/source/blender/gpu/metal/mtl_context.hh b/source/blender/gpu/metal/mtl_context.hh index aa0a01b11d9..3656fbdcd19 100644 --- a/source/blender/gpu/metal/mtl_context.hh +++ b/source/blender/gpu/metal/mtl_context.hh @@ -655,9 +655,9 @@ class MTLContext : public Context { /** Dummy Resources */ /* Maximum of 32 texture types. Though most combinations invalid. */ - gpu::MTLTexture *dummy_textures_[GPU_TEXTURE_BUFFER] = {nullptr}; - GPUVertFormat dummy_vertformat_; - GPUVertBuf *dummy_verts_ = nullptr; + gpu::MTLTexture *dummy_textures_[GPU_SAMPLER_TYPE_MAX][GPU_TEXTURE_BUFFER] = {nullptr}; + GPUVertFormat dummy_vertformat_[GPU_SAMPLER_TYPE_MAX]; + GPUVertBuf *dummy_verts_[GPU_SAMPLER_TYPE_MAX] = {nullptr}; public: /* GPUContext interface. */ @@ -743,7 +743,7 @@ class MTLContext : public Context { id get_null_buffer(); id get_null_attribute_buffer(); - gpu::MTLTexture *get_dummy_texture(eGPUTextureType type); + gpu::MTLTexture *get_dummy_texture(eGPUTextureType type, eGPUSamplerFormat sampler_format); void free_dummy_resources(); /* State assignment. */ diff --git a/source/blender/gpu/metal/mtl_context.mm b/source/blender/gpu/metal/mtl_context.mm index 16530fcfeed..530ea35294e 100644 --- a/source/blender/gpu/metal/mtl_context.mm +++ b/source/blender/gpu/metal/mtl_context.mm @@ -13,6 +13,7 @@ #include "mtl_shader_interface.hh" #include "mtl_state.hh" #include "mtl_uniform_buffer.hh" +#include "mtl_vertex_buffer.hh" #include "DNA_userdef_types.h" @@ -512,53 +513,98 @@ id MTLContext::get_null_attribute_buffer() return null_attribute_buffer_; } -gpu::MTLTexture *MTLContext::get_dummy_texture(eGPUTextureType type) +gpu::MTLTexture *MTLContext::get_dummy_texture(eGPUTextureType type, + eGPUSamplerFormat sampler_format) { /* Decrement 1 from texture type as they start from 1 and go to 32 (inclusive). Remap to 0..31 */ - gpu::MTLTexture *dummy_tex = dummy_textures_[type - 1]; + gpu::MTLTexture *dummy_tex = dummy_textures_[sampler_format][type - 1]; if (dummy_tex != nullptr) { return dummy_tex; } else { + /* Determine format for dummy texture. */ + eGPUTextureFormat format = GPU_RGBA8; + switch (sampler_format) { + case GPU_SAMPLER_TYPE_FLOAT: + format = GPU_RGBA8; + break; + case GPU_SAMPLER_TYPE_INT: + format = GPU_RGBA8I; + break; + case GPU_SAMPLER_TYPE_UINT: + format = GPU_RGBA8UI; + break; + case GPU_SAMPLER_TYPE_DEPTH: + format = GPU_DEPTH32F_STENCIL8; + break; + default: + BLI_assert_unreachable(); + } + + /* Create dummy texture based on desired type. */ GPUTexture *tex = nullptr; switch (type) { case GPU_TEXTURE_1D: - tex = GPU_texture_create_1d("Dummy 1D", 128, 1, GPU_RGBA8, nullptr); + tex = GPU_texture_create_1d("Dummy 1D", 128, 1, format, nullptr); break; case GPU_TEXTURE_1D_ARRAY: - tex = GPU_texture_create_1d_array("Dummy 1DArray", 128, 1, 1, GPU_RGBA8, nullptr); + tex = GPU_texture_create_1d_array("Dummy 1DArray", 128, 1, 1, format, nullptr); break; case GPU_TEXTURE_2D: - tex = GPU_texture_create_2d("Dummy 2D", 128, 128, 1, GPU_RGBA8, nullptr); + tex = GPU_texture_create_2d("Dummy 2D", 128, 128, 1, format, nullptr); break; case GPU_TEXTURE_2D_ARRAY: - tex = GPU_texture_create_2d_array("Dummy 2DArray", 128, 128, 1, 1, GPU_RGBA8, nullptr); + tex = GPU_texture_create_2d_array("Dummy 2DArray", 128, 128, 1, 1, format, nullptr); break; case GPU_TEXTURE_3D: - tex = GPU_texture_create_3d( - "Dummy 3D", 128, 128, 1, 1, GPU_RGBA8, GPU_DATA_UBYTE, nullptr); + tex = GPU_texture_create_3d("Dummy 3D", 128, 128, 1, 1, format, GPU_DATA_UBYTE, nullptr); break; case GPU_TEXTURE_CUBE: - tex = GPU_texture_create_cube("Dummy Cube", 128, 1, GPU_RGBA8, nullptr); + tex = GPU_texture_create_cube("Dummy Cube", 128, 1, format, nullptr); break; case GPU_TEXTURE_CUBE_ARRAY: - tex = GPU_texture_create_cube_array("Dummy CubeArray", 128, 1, 1, GPU_RGBA8, nullptr); + tex = GPU_texture_create_cube_array("Dummy CubeArray", 128, 1, 1, format, nullptr); break; case GPU_TEXTURE_BUFFER: - if (!dummy_verts_) { - GPU_vertformat_clear(&dummy_vertformat_); - GPU_vertformat_attr_add(&dummy_vertformat_, "dummy", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - dummy_verts_ = GPU_vertbuf_create_with_format_ex(&dummy_vertformat_, GPU_USAGE_STATIC); - GPU_vertbuf_data_alloc(dummy_verts_, 64); + if (!dummy_verts_[sampler_format]) { + GPU_vertformat_clear(&dummy_vertformat_[sampler_format]); + + GPUVertCompType comp_type = GPU_COMP_F32; + GPUVertFetchMode fetch_mode = GPU_FETCH_FLOAT; + + switch (sampler_format) { + case GPU_SAMPLER_TYPE_FLOAT: + case GPU_SAMPLER_TYPE_DEPTH: + comp_type = GPU_COMP_F32; + fetch_mode = GPU_FETCH_FLOAT; + break; + case GPU_SAMPLER_TYPE_INT: + comp_type = GPU_COMP_I32; + fetch_mode = GPU_FETCH_INT; + break; + case GPU_SAMPLER_TYPE_UINT: + comp_type = GPU_COMP_U32; + fetch_mode = GPU_FETCH_INT; + break; + default: + BLI_assert_unreachable(); + } + + GPU_vertformat_attr_add( + &dummy_vertformat_[sampler_format], "dummy", comp_type, 4, fetch_mode); + dummy_verts_[sampler_format] = GPU_vertbuf_create_with_format_ex( + &dummy_vertformat_[sampler_format], + GPU_USAGE_STATIC | GPU_USAGE_FLAG_BUFFER_TEXTURE_ONLY); + GPU_vertbuf_data_alloc(dummy_verts_[sampler_format], 64); } - tex = GPU_texture_create_from_vertbuf("Dummy TextureBuffer", dummy_verts_); + tex = GPU_texture_create_from_vertbuf("Dummy TextureBuffer", dummy_verts_[sampler_format]); break; default: BLI_assert_msg(false, "Unrecognised texture type"); return nullptr; } gpu::MTLTexture *metal_tex = static_cast(reinterpret_cast(tex)); - dummy_textures_[type - 1] = metal_tex; + dummy_textures_[sampler_format][type - 1] = metal_tex; return metal_tex; } return nullptr; @@ -566,15 +612,17 @@ gpu::MTLTexture *MTLContext::get_dummy_texture(eGPUTextureType type) void MTLContext::free_dummy_resources() { - for (int tex = 0; tex < GPU_TEXTURE_BUFFER; tex++) { - if (dummy_textures_[tex]) { - GPU_texture_free( - reinterpret_cast(static_cast(dummy_textures_[tex]))); - dummy_textures_[tex] = nullptr; + for (int format = 0; format < GPU_SAMPLER_TYPE_MAX; format++) { + for (int tex = 0; tex < GPU_TEXTURE_BUFFER; tex++) { + if (dummy_textures_[format][tex]) { + GPU_texture_free( + reinterpret_cast(static_cast(dummy_textures_[format][tex]))); + dummy_textures_[format][tex] = nullptr; + } + } + if (dummy_verts_[format]) { + GPU_vertbuf_discard(dummy_verts_[format]); } - } - if (dummy_verts_) { - GPU_vertbuf_discard(dummy_verts_); } } @@ -809,31 +857,31 @@ bool MTLContext::ensure_render_pipeline_state(MTLPrimitiveType mtl_prim_type) } /* Transform feedback buffer binding. */ - /* TOOD(Metal): Include this code once MTLVertBuf is merged. We bind the vertex buffer to which - * transform feedback data will be written. */ - // GPUVertBuf *tf_vbo = - // this->pipeline_state.active_shader->get_transform_feedback_active_buffer(); - // if (tf_vbo != nullptr && pipeline_state_instance->transform_feedback_buffer_index >= 0) { + GPUVertBuf *tf_vbo = + this->pipeline_state.active_shader->get_transform_feedback_active_buffer(); + if (tf_vbo != nullptr && pipeline_state_instance->transform_feedback_buffer_index >= 0) { - // /* Ensure primitive type is either GPU_LINES, GPU_TRIANGLES or GPU_POINT */ - // BLI_assert(mtl_prim_type == MTLPrimitiveTypeLine || - // mtl_prim_type == MTLPrimitiveTypeTriangle || - // mtl_prim_type == MTLPrimitiveTypePoint); + /* Ensure primitive type is either GPU_LINES, GPU_TRIANGLES or GPU_POINT */ + BLI_assert(mtl_prim_type == MTLPrimitiveTypeLine || + mtl_prim_type == MTLPrimitiveTypeTriangle || + mtl_prim_type == MTLPrimitiveTypePoint); - // /* Fetch active transform feedback buffer from vertbuf */ - // MTLVertBuf *tf_vbo_mtl = static_cast(reinterpret_cast(tf_vbo)); - // int tf_buffer_offset = 0; - // id tf_buffer_mtl = tf_vbo_mtl->get_metal_buffer(&tf_buffer_offset); + /* Fetch active transform feedback buffer from vertbuf */ + MTLVertBuf *tf_vbo_mtl = static_cast(reinterpret_cast(tf_vbo)); + /* Ensure TF buffer is ready. */ + tf_vbo_mtl->bind(); + id tf_buffer_mtl = tf_vbo_mtl->get_metal_buffer(); + BLI_assert(tf_buffer_mtl != nil); - // if (tf_buffer_mtl != nil && tf_buffer_offset >= 0) { - // [rec setVertexBuffer:tf_buffer_mtl - // offset:tf_buffer_offset - // atIndex:pipeline_state_instance->transform_feedback_buffer_index]; - // printf("Successfully bound VBO: %p for transform feedback (MTL Buffer: %p)\n", - // tf_vbo_mtl, - // tf_buffer_mtl); - // } - // } + if (tf_buffer_mtl != nil) { + [rec setVertexBuffer:tf_buffer_mtl + offset:0 + atIndex:pipeline_state_instance->transform_feedback_buffer_index]; + MTL_LOG_INFO("Successfully bound VBO: %p for transform feedback (MTL Buffer: %p)\n", + tf_vbo_mtl, + tf_buffer_mtl); + } + } /* Matrix Bindings. */ /* This is now called upon shader bind. We may need to re-evaluate this though, @@ -1221,7 +1269,9 @@ void MTLContext::ensure_texture_bindings( if (bind_dummy_texture) { if (bool(shader_texture_info.stage_mask & ShaderStage::VERTEX)) { rps.bind_vertex_texture( - get_dummy_texture(shader_texture_info.type)->get_metal_handle(), slot); + get_dummy_texture(shader_texture_info.type, shader_texture_info.sampler_format) + ->get_metal_handle(), + slot); /* Bind default sampler state. */ MTLSamplerBinding default_binding = {true, DEFAULT_SAMPLER_STATE}; @@ -1229,7 +1279,9 @@ void MTLContext::ensure_texture_bindings( } if (bool(shader_texture_info.stage_mask & ShaderStage::FRAGMENT)) { rps.bind_fragment_texture( - get_dummy_texture(shader_texture_info.type)->get_metal_handle(), slot); + get_dummy_texture(shader_texture_info.type, shader_texture_info.sampler_format) + ->get_metal_handle(), + slot); /* Bind default sampler state. */ MTLSamplerBinding default_binding = {true, DEFAULT_SAMPLER_STATE}; diff --git a/source/blender/gpu/metal/mtl_drawlist.mm b/source/blender/gpu/metal/mtl_drawlist.mm index 99194d2b72c..3a1fe405c49 100644 --- a/source/blender/gpu/metal/mtl_drawlist.mm +++ b/source/blender/gpu/metal/mtl_drawlist.mm @@ -185,8 +185,9 @@ void MTLDrawList::submit() can_use_MDI = can_use_MDI && (is_finishing_a_buffer || command_len_ > 2); /* Bind Batch to setup render pipeline state. */ + BLI_assert(batch_ != nullptr); id rec = batch_->bind(0, 0, 0, 0); - if (!rec) { + if (rec == nil) { BLI_assert_msg(false, "A RenderCommandEncoder should always be available!\n"); return; } diff --git a/source/blender/gpu/metal/mtl_framebuffer.mm b/source/blender/gpu/metal/mtl_framebuffer.mm index 975e78fc466..467a4a6f412 100644 --- a/source/blender/gpu/metal/mtl_framebuffer.mm +++ b/source/blender/gpu/metal/mtl_framebuffer.mm @@ -95,7 +95,7 @@ void MTLFrameBuffer::bind(bool enabled_srgb) /* Verify Context is valid. */ if (context_ != static_cast(unwrap(GPU_context_active_get()))) { - BLI_assert(false && "Trying to use the same frame-buffer in multiple context's."); + BLI_assert_msg(false, "Trying to use the same frame-buffer in multiple context's."); return; } @@ -986,7 +986,7 @@ bool MTLFrameBuffer::add_depth_attachment(gpu::MTLTexture *texture, int miplevel if (layer == -1) { mtl_depth_attachment_.slice = 0; mtl_depth_attachment_.depth_plane = 0; - mtl_depth_attachment_.render_target_array_length = 1; + mtl_depth_attachment_.render_target_array_length = 6; use_multilayered_rendering_ = true; } break; @@ -1007,7 +1007,7 @@ bool MTLFrameBuffer::add_depth_attachment(gpu::MTLTexture *texture, int miplevel mtl_depth_attachment_.depth_plane = 0; break; default: - BLI_assert(false && "Unrecognized texture type"); + BLI_assert_msg(false, "Unrecognized texture type"); break; } @@ -1108,7 +1108,7 @@ bool MTLFrameBuffer::add_stencil_attachment(gpu::MTLTexture *texture, int miplev if (layer == -1) { mtl_stencil_attachment_.slice = 0; mtl_stencil_attachment_.depth_plane = 0; - mtl_stencil_attachment_.render_target_array_length = 1; + mtl_stencil_attachment_.render_target_array_length = 6; use_multilayered_rendering_ = true; } break; @@ -1129,7 +1129,7 @@ bool MTLFrameBuffer::add_stencil_attachment(gpu::MTLTexture *texture, int miplev mtl_stencil_attachment_.depth_plane = 0; break; default: - BLI_assert(false && "Unrecognized texture type"); + BLI_assert_msg(false, "Unrecognized texture type"); break; } diff --git a/source/blender/gpu/metal/mtl_immediate.mm b/source/blender/gpu/metal/mtl_immediate.mm index ee48bdd6ee1..7af5ca30578 100644 --- a/source/blender/gpu/metal/mtl_immediate.mm +++ b/source/blender/gpu/metal/mtl_immediate.mm @@ -101,11 +101,11 @@ void MTLImmediate::end() /* Reset vertex descriptor to default state. */ desc.reset_vertex_descriptor(); - - desc.vertex_descriptor.num_attributes = interface->get_total_attributes(); + desc.vertex_descriptor.total_attributes = interface->get_total_attributes(); + desc.vertex_descriptor.max_attribute_value = interface->get_total_attributes() - 1; desc.vertex_descriptor.num_vert_buffers = 1; - for (int i = 0; i < desc.vertex_descriptor.num_attributes; i++) { + for (int i = 0; i < desc.vertex_descriptor.total_attributes; i++) { desc.vertex_descriptor.attributes[i].format = MTLVertexFormatInvalid; } desc.vertex_descriptor.uses_ssbo_vertex_fetch = diff --git a/source/blender/gpu/metal/mtl_pso_descriptor_state.hh b/source/blender/gpu/metal/mtl_pso_descriptor_state.hh index 04ceb5bdf03..8b0d69c6251 100644 --- a/source/blender/gpu/metal/mtl_pso_descriptor_state.hh +++ b/source/blender/gpu/metal/mtl_pso_descriptor_state.hh @@ -84,7 +84,8 @@ struct MTLVertexDescriptor { MTLVertexAttributeDescriptorPSO attributes[GPU_VERT_ATTR_MAX_LEN]; MTLVertexBufferLayoutDescriptorPSO buffer_layouts[GPU_BATCH_VBO_MAX_LEN + GPU_BATCH_INST_VBO_MAX_LEN]; - int num_attributes; + int max_attribute_value; + int total_attributes; int num_vert_buffers; MTLPrimitiveTopologyClass prim_topology_class; @@ -97,7 +98,8 @@ struct MTLVertexDescriptor { bool operator==(const MTLVertexDescriptor &other) const { - if ((this->num_attributes != other.num_attributes) || + if ((this->max_attribute_value != other.max_attribute_value) || + (this->total_attributes != other.total_attributes) || (this->num_vert_buffers != other.num_vert_buffers)) { return false; } @@ -105,7 +107,7 @@ struct MTLVertexDescriptor { return false; }; - for (const int a : IndexRange(this->num_attributes)) { + for (const int a : IndexRange(this->max_attribute_value + 1)) { if (!(this->attributes[a] == other.attributes[a])) { return false; } @@ -125,8 +127,8 @@ struct MTLVertexDescriptor { uint64_t hash() const { - uint64_t hash = (uint64_t)(this->num_attributes ^ this->num_vert_buffers); - for (const int a : IndexRange(this->num_attributes)) { + uint64_t hash = (uint64_t)(this->max_attribute_value ^ this->num_vert_buffers); + for (const int a : IndexRange(this->max_attribute_value + 1)) { hash ^= this->attributes[a].hash() << a; } @@ -247,7 +249,8 @@ struct MTLRenderPipelineStateDescriptor { /* Reset the Vertex Descriptor to default. */ void reset_vertex_descriptor() { - vertex_descriptor.num_attributes = 0; + vertex_descriptor.total_attributes = 0; + vertex_descriptor.max_attribute_value = 0; vertex_descriptor.num_vert_buffers = 0; for (int i = 0; i < GPU_VERT_ATTR_MAX_LEN; i++) { vertex_descriptor.attributes[i].format = MTLVertexFormatInvalid; diff --git a/source/blender/gpu/metal/mtl_shader.mm b/source/blender/gpu/metal/mtl_shader.mm index 006d3394378..747746ea424 100644 --- a/source/blender/gpu/metal/mtl_shader.mm +++ b/source/blender/gpu/metal/mtl_shader.mm @@ -29,6 +29,7 @@ #include "mtl_shader_generator.hh" #include "mtl_shader_interface.hh" #include "mtl_texture.hh" +#include "mtl_vertex_buffer.hh" extern char datatoc_mtl_shader_common_msl[]; @@ -347,9 +348,8 @@ bool MTLShader::transform_feedback_enable(GPUVertBuf *buf) BLI_assert(buf); transform_feedback_active_ = true; transform_feedback_vertbuf_ = buf; - /* TODO(Metal): Enable this assertion once #MTLVertBuf lands. */ - // BLI_assert(static_cast(unwrap(transform_feedback_vertbuf_))->get_usage_type() == - // GPU_USAGE_DEVICE_ONLY); + BLI_assert(static_cast(unwrap(transform_feedback_vertbuf_))->get_usage_type() == + GPU_USAGE_DEVICE_ONLY); return true; } @@ -568,6 +568,7 @@ void MTLShader::shader_source_from_msl(NSString *input_vertex_source, void MTLShader::set_interface(MTLShaderInterface *interface) { /* Assign gpu::Shader super-class interface. */ + BLI_assert(Shader::interface == nullptr); Shader::interface = interface; } @@ -709,7 +710,7 @@ MTLRenderPipelineStateInstance *MTLShader::bake_current_pipeline_state( MTL_uniform_buffer_base_index = MTL_SSBO_VERTEX_FETCH_IBO_INDEX + 1; } else { - for (const uint i : IndexRange(current_state.vertex_descriptor.num_attributes)) { + for (const uint i : IndexRange(current_state.vertex_descriptor.max_attribute_value + 1)) { /* Metal back-end attribute descriptor state. */ MTLVertexAttributeDescriptorPSO &attribute_desc = @@ -727,8 +728,9 @@ MTLRenderPipelineStateInstance *MTLShader::bake_current_pipeline_state( * https://developer.apple.com/documentation/metal/mtlvertexattributedescriptor/1516081-format?language=objc */ if (attribute_desc.format == MTLVertexFormatInvalid) { + /* If attributes are non-contiguous, we can skip over gaps. */ MTL_LOG_WARNING( - "MTLShader: baking pipeline state for '%s'- expected input attribute at " + "MTLShader: baking pipeline state for '%s'- skipping input attribute at " "index '%d' but none was specified in the current vertex state\n", mtl_interface->get_name(), i); @@ -777,7 +779,8 @@ MTLRenderPipelineStateInstance *MTLShader::bake_current_pipeline_state( } /* Mark empty attribute conversion. */ - for (int i = current_state.vertex_descriptor.num_attributes; i < GPU_VERT_ATTR_MAX_LEN; + for (int i = current_state.vertex_descriptor.max_attribute_value + 1; + i < GPU_VERT_ATTR_MAX_LEN; i++) { int MTL_attribute_conversion_mode = 0; [values setConstantValue:&MTL_attribute_conversion_mode @@ -790,13 +793,15 @@ MTLRenderPipelineStateInstance *MTLShader::bake_current_pipeline_state( * #GPUVertFormat, however, if attributes have not been set, we can sort them out here. */ for (const uint i : IndexRange(mtl_interface->get_total_attributes())) { const MTLShaderInputAttribute &attribute = mtl_interface->get_attribute(i); - MTLVertexAttributeDescriptor *current_attribute = desc.vertexDescriptor.attributes[i]; + MTLVertexAttributeDescriptor *current_attribute = + desc.vertexDescriptor.attributes[attribute.location]; if (current_attribute.format == MTLVertexFormatInvalid) { #if MTL_DEBUG_SHADER_ATTRIBUTES == 1 - MTL_LOG_INFO("-> Filling in unbound attribute '%s' for shader PSO '%s' \n", - attribute.name, - mtl_interface->name); + printf("-> Filling in unbound attribute '%s' for shader PSO '%s' with location: %u\n", + mtl_interface->get_name_at_offset(attribute.name_offset), + mtl_interface->get_name(), + attribute.location); #endif current_attribute.format = attribute.format; current_attribute.offset = 0; @@ -828,28 +833,30 @@ MTLRenderPipelineStateInstance *MTLShader::bake_current_pipeline_state( } } - /* Primitive Topology */ + /* Primitive Topology. */ desc.inputPrimitiveTopology = pipeline_descriptor.vertex_descriptor.prim_topology_class; } - /* Update constant value for 'MTL_uniform_buffer_base_index' */ + /* Update constant value for 'MTL_uniform_buffer_base_index'. */ [values setConstantValue:&MTL_uniform_buffer_base_index type:MTLDataTypeInt withName:@"MTL_uniform_buffer_base_index"]; - /* Transform feedback constant */ + /* Transform feedback constant. + * Ensure buffer is placed after existing buffers, including default buffers. */ int MTL_transform_feedback_buffer_index = (this->transform_feedback_type_ != GPU_SHADER_TFB_NONE) ? MTL_uniform_buffer_base_index + - mtl_interface->get_total_uniform_blocks() : + mtl_interface->get_max_ubo_index() + 2 : -1; + if (this->transform_feedback_type_ != GPU_SHADER_TFB_NONE) { [values setConstantValue:&MTL_transform_feedback_buffer_index type:MTLDataTypeInt withName:@"MTL_transform_feedback_buffer_index"]; } - /* gl_PointSize constant */ + /* gl_PointSize constant. */ bool null_pointsize = true; float MTL_pointsize = pipeline_descriptor.point_size; if (pipeline_descriptor.vertex_descriptor.prim_topology_class == diff --git a/source/blender/gpu/metal/mtl_shader_generator.hh b/source/blender/gpu/metal/mtl_shader_generator.hh index c0315eb4c6a..f4cf42deb68 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.hh +++ b/source/blender/gpu/metal/mtl_shader_generator.hh @@ -228,6 +228,7 @@ struct MSLTextureSampler { uint location; eGPUTextureType get_texture_binding_type() const; + eGPUSamplerFormat get_sampler_format() const; void resolve_binding_indices(); diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm index cac4b3a9546..b8c9a28efbd 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.mm +++ b/source/blender/gpu/metal/mtl_shader_generator.mm @@ -336,7 +336,8 @@ static bool extract_ssbo_pragma_info(const MTLShader *shader, /* SSBO Vertex-fetch parameter extraction. */ static std::regex use_ssbo_fetch_mode_find( "#pragma " - "USE_SSBO_VERTEX_FETCH\\(\\s*(TriangleList|LineList|\\w+)\\s*,\\s*([0-9]+)\\s*\\)"); + "USE_SSBO_VERTEX_FETCH\\(\\s*(TriangleList|LineList|TriangleStrip|\\w+)\\s*,\\s*([0-9]+)\\s*" + "\\)"); /* Perform regex search if pragma string found. */ std::smatch vertex_shader_ssbo_flags; @@ -352,6 +353,7 @@ static bool extract_ssbo_pragma_info(const MTLShader *shader, * Supported Primitive Types (Others can be added if needed, but List types for efficiency): * - TriangleList * - LineList + * - TriangleStrip (To be used with caution). * * Output vertex count is determined by calculating the number of input primitives, and * multiplying that by the number of output vertices specified. */ @@ -365,6 +367,9 @@ static bool extract_ssbo_pragma_info(const MTLShader *shader, else if (str_output_primitive_type == "LineList") { out_prim_tye = MTLPrimitiveTypeLine; } + else if (str_output_primitive_type == "TriangleStrip") { + out_prim_tye = MTLPrimitiveTypeTriangleStrip; + } else { MTL_LOG_ERROR("Unsupported output primitive type for SSBO VERTEX FETCH MODE. Shader: %s", shader->name_get()); @@ -555,8 +560,6 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info) BLI_assert(shd_builder_->glsl_fragment_source_.size() > 0); } - /** Determine use of Transform Feedback. **/ - msl_iface.uses_transform_feedback = false; if (transform_feedback_type_ != GPU_SHADER_TFB_NONE) { /* Ensure #TransformFeedback is configured correctly. */ BLI_assert(tf_output_name_list_.size() > 0); @@ -1270,8 +1273,10 @@ void MSLGeneratorInterface::prepare_from_createinfo(const shader::ShaderCreateIn access = MSLTextureSamplerAccess::TEXTURE_ACCESS_READ; } BLI_assert(used_slot >= 0 && used_slot < MTL_MAX_TEXTURE_SLOTS); + + /* Writeable image targets only assigned to Fragment shader. */ MSLTextureSampler msl_tex( - ShaderStage::BOTH, res.image.type, res.image.name, access, used_slot); + ShaderStage::FRAGMENT, res.image.type, res.image.name, access, used_slot); texture_samplers.append(msl_tex); } break; @@ -1344,6 +1349,10 @@ void MSLGeneratorInterface::prepare_from_createinfo(const shader::ShaderCreateIn fragment_outputs.append(mtl_frag_out); } + + /* Transform feedback. */ + uses_transform_feedback = (create_info_->tf_type_ != GPU_SHADER_TFB_NONE) && + (create_info_->tf_names_.size() > 0); } bool MSLGeneratorInterface::use_argument_buffer_for_samplers() const @@ -1514,7 +1523,7 @@ std::string MSLGeneratorInterface::generate_msl_fragment_entry_stub() if (this->uses_barycentrics) { /* Main barycentrics. */ - out << "fragment_shader_instance.gpu_BaryCoord = mtl_barycentric_coord.xyz;"; + out << "fragment_shader_instance.gpu_BaryCoord = mtl_barycentric_coord.xyz;" << std::endl; /* barycentricDist represents the world-space distance from the current world-space position * to the opposite edge of the vertex. */ @@ -2381,8 +2390,8 @@ std::string MSLGeneratorInterface::generate_msl_texture_vars(ShaderStage shader_ out << "\t" << ((shader_stage == ShaderStage::VERTEX) ? "vertex_shader_instance." : "fragment_shader_instance.") - << this->texture_samplers[i].name << ".samp = &samplers.sampler_args[" << i << "];" - << std::endl; + << this->texture_samplers[i].name << ".samp = &samplers.sampler_args[" + << this->texture_samplers[i].location << "];" << std::endl; } else { out << "\t" @@ -2613,6 +2622,7 @@ MTLShaderInterface *MSLGeneratorInterface::bake_shader_interface(const char *nam name_buffer_offset), texture_sampler.location, texture_sampler.get_texture_binding_type(), + texture_sampler.get_sampler_format(), texture_sampler.stage); } @@ -3011,6 +3021,51 @@ eGPUTextureType MSLTextureSampler::get_texture_binding_type() const }; } +eGPUSamplerFormat MSLTextureSampler::get_sampler_format() const +{ + switch (this->type) { + case ImageType::FLOAT_BUFFER: + case ImageType::FLOAT_1D: + case ImageType::FLOAT_1D_ARRAY: + case ImageType::FLOAT_2D: + case ImageType::FLOAT_2D_ARRAY: + case ImageType::FLOAT_3D: + case ImageType::FLOAT_CUBE: + case ImageType::FLOAT_CUBE_ARRAY: + return GPU_SAMPLER_TYPE_FLOAT; + case ImageType::INT_BUFFER: + case ImageType::INT_1D: + case ImageType::INT_1D_ARRAY: + case ImageType::INT_2D: + case ImageType::INT_2D_ARRAY: + case ImageType::INT_3D: + case ImageType::INT_CUBE: + case ImageType::INT_CUBE_ARRAY: + return GPU_SAMPLER_TYPE_INT; + case ImageType::UINT_BUFFER: + case ImageType::UINT_1D: + case ImageType::UINT_1D_ARRAY: + case ImageType::UINT_2D: + case ImageType::UINT_2D_ARRAY: + case ImageType::UINT_3D: + case ImageType::UINT_CUBE: + case ImageType::UINT_CUBE_ARRAY: + return GPU_SAMPLER_TYPE_UINT; + case ImageType::SHADOW_2D: + case ImageType::SHADOW_2D_ARRAY: + case ImageType::SHADOW_CUBE: + case ImageType::SHADOW_CUBE_ARRAY: + case ImageType::DEPTH_2D: + case ImageType::DEPTH_2D_ARRAY: + case ImageType::DEPTH_CUBE: + case ImageType::DEPTH_CUBE_ARRAY: + return GPU_SAMPLER_TYPE_DEPTH; + default: + BLI_assert_unreachable(); + } + return GPU_SAMPLER_TYPE_FLOAT; +} + /** \} */ } // namespace blender::gpu diff --git a/source/blender/gpu/metal/mtl_shader_interface.hh b/source/blender/gpu/metal/mtl_shader_interface.hh index 0da84cad997..4556d4d78c1 100644 --- a/source/blender/gpu/metal/mtl_shader_interface.hh +++ b/source/blender/gpu/metal/mtl_shader_interface.hh @@ -130,6 +130,7 @@ struct MTLShaderTexture { /* Texture resource bind slot in shader `[[texture(n)]]`. */ int slot_index; eGPUTextureType type; + eGPUSamplerFormat sampler_format; ShaderStage stage_mask; }; @@ -168,6 +169,7 @@ class MTLShaderInterface : public ShaderInterface { /* Uniform Blocks. */ uint32_t total_uniform_blocks_; + uint32_t max_uniformbuf_index_; MTLShaderUniformBlock ubos_[MTL_MAX_UNIFORM_BUFFER_BINDINGS]; MTLShaderUniformBlock push_constant_block_; @@ -209,6 +211,7 @@ class MTLShaderInterface : public ShaderInterface { void add_texture(uint32_t name_offset, uint32_t texture_slot, eGPUTextureType tex_binding_type, + eGPUSamplerFormat sampler_format, ShaderStage stage_mask = ShaderStage::FRAGMENT); void add_push_constant_block(uint32_t name_offset); @@ -228,6 +231,7 @@ class MTLShaderInterface : public ShaderInterface { /* Fetch Uniform Blocks. */ const MTLShaderUniformBlock &get_uniform_block(uint index) const; uint32_t get_total_uniform_blocks() const; + uint32_t get_max_ubo_index() const; bool has_uniform_block(uint32_t block_index) const; uint32_t get_uniform_block_size(uint32_t block_index) const; diff --git a/source/blender/gpu/metal/mtl_shader_interface.mm b/source/blender/gpu/metal/mtl_shader_interface.mm index 97a82345761..317d0f49763 100644 --- a/source/blender/gpu/metal/mtl_shader_interface.mm +++ b/source/blender/gpu/metal/mtl_shader_interface.mm @@ -55,6 +55,7 @@ void MTLShaderInterface::init() { total_attributes_ = 0; total_uniform_blocks_ = 0; + max_uniformbuf_index_ = 0; total_uniforms_ = 0; total_textures_ = 0; max_texture_index_ = -1; @@ -121,6 +122,7 @@ uint32_t MTLShaderInterface::add_uniform_block(uint32_t name_offset, uni_block.size = size; uni_block.current_offset = 0; uni_block.stage_mask = ShaderStage::BOTH; + max_uniformbuf_index_ = max_ii(max_uniformbuf_index_, buffer_index); return (total_uniform_blocks_++); } @@ -187,9 +189,11 @@ void MTLShaderInterface::add_uniform(uint32_t name_offset, eMTLDataType type, in void MTLShaderInterface::add_texture(uint32_t name_offset, uint32_t texture_slot, eGPUTextureType tex_binding_type, + eGPUSamplerFormat sampler_format, ShaderStage stage_mask) { BLI_assert(texture_slot >= 0 && texture_slot < GPU_max_textures()); + BLI_assert(sampler_format < GPU_SAMPLER_TYPE_MAX); if (texture_slot >= 0 && texture_slot < GPU_max_textures()) { MTLShaderTexture &tex = textures_[texture_slot]; @@ -197,6 +201,7 @@ void MTLShaderInterface::add_texture(uint32_t name_offset, tex.name_offset = name_offset; tex.slot_index = texture_slot; tex.type = tex_binding_type; + tex.sampler_format = sampler_format; tex.stage_mask = stage_mask; tex.used = true; total_textures_++; @@ -281,7 +286,11 @@ void MTLShaderInterface::prepare_common_shader_inputs() MTLShaderInputAttribute &shd_attr = attributes_[attr_index]; current_input->name_offset = shd_attr.name_offset; current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_attr.name_offset)); - current_input->location = attr_index; + /* For Metal, we flatten the vertex attribute indices within the shader in order to minimise + * complexity. ShaderInput "Location" contains the original attribute location, as can be + * fetched using `GPU_shader_get_attribute_info`. ShaderInput binding contains the array index + * into the MTLShaderInterface `attributes_` array. */ + current_input->location = shd_attr.location; current_input->binding = attr_index; current_input++; } @@ -419,6 +428,11 @@ uint32_t MTLShaderInterface::get_total_uniform_blocks() const return total_uniform_blocks_; } +uint32_t MTLShaderInterface::get_max_ubo_index() const +{ + return max_uniformbuf_index_; +} + bool MTLShaderInterface::has_uniform_block(uint32_t block_index) const { return (block_index < total_uniform_blocks_); diff --git a/source/blender/gpu/metal/mtl_shader_interface_type.hh b/source/blender/gpu/metal/mtl_shader_interface_type.hh index 3c4c87ee25b..1ae429c55bc 100644 --- a/source/blender/gpu/metal/mtl_shader_interface_type.hh +++ b/source/blender/gpu/metal/mtl_shader_interface_type.hh @@ -6,6 +6,7 @@ #pragma once #include "BLI_assert.h" +#include "GPU_material.h" enum eMTLDataType { MTL_DATATYPE_CHAR, @@ -249,3 +250,25 @@ inline uint mtl_get_data_type_alignment(eMTLDataType type) return 0; }; } + +inline eMTLDataType gpu_type_to_mtl_type(eGPUType type) +{ + switch (type) { + case GPU_FLOAT: + return MTL_DATATYPE_FLOAT; + case GPU_VEC2: + return MTL_DATATYPE_FLOAT2; + case GPU_VEC3: + return MTL_DATATYPE_FLOAT3; + case GPU_VEC4: + return MTL_DATATYPE_FLOAT4; + case GPU_MAT3: + return MTL_DATATYPE_FLOAT3x3; + case GPU_MAT4: + return MTL_DATATYPE_FLOAT4x4; + default: + BLI_assert(false && "Other types unsupported"); + return MTL_DATATYPE_FLOAT; + } + return MTL_DATATYPE_FLOAT; +} \ No newline at end of file diff --git a/source/blender/gpu/metal/mtl_texture.mm b/source/blender/gpu/metal/mtl_texture.mm index 303c971f0f5..411d1187610 100644 --- a/source/blender/gpu/metal/mtl_texture.mm +++ b/source/blender/gpu/metal/mtl_texture.mm @@ -1668,9 +1668,6 @@ bool gpu::MTLTexture::init_internal(GPUVertBuf *vbo) /* Track Status. */ vert_buffer_ = mtl_vbo; vert_buffer_mtl_ = source_buffer; - /* Cleanup. */ - [texture_descriptor_ release]; - texture_descriptor_ = nullptr; return true; } @@ -1882,8 +1879,6 @@ void gpu::MTLTexture::ensure_baked() /* Standard texture allocation. */ texture_ = [ctx->device newTextureWithDescriptor:texture_descriptor_]; - [texture_descriptor_ release]; - texture_descriptor_ = nullptr; texture_.label = [NSString stringWithUTF8String:this->get_name()]; BLI_assert(texture_); is_baked_ = true; diff --git a/source/blender/gpu/metal/mtl_vertex_buffer.hh b/source/blender/gpu/metal/mtl_vertex_buffer.hh index 2cc8b0a9636..54d2b7a86a3 100644 --- a/source/blender/gpu/metal/mtl_vertex_buffer.hh +++ b/source/blender/gpu/metal/mtl_vertex_buffer.hh @@ -42,6 +42,7 @@ class MTLVertBuf : public VertBuf { * Access limited to friend classes. */ id get_metal_buffer() { + BLI_assert(vbo_ != nullptr); vbo_->debug_ensure_used(); return vbo_->get_metal_buffer(); } diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c index 258ef15d684..5bd18ee028a 100644 --- a/source/blender/imbuf/intern/util_gpu.c +++ b/source/blender/imbuf/intern/util_gpu.c @@ -351,13 +351,23 @@ GPUTexture *IMB_create_gpu_texture(const char *name, bool freebuf = false; /* Create Texture. */ - tex = GPU_texture_create_2d_ex( - name, UNPACK2(size), 9999, tex_format, GPU_TEXTURE_USAGE_SHADER_READ, NULL); + tex = GPU_texture_create_2d_ex(name, + UNPACK2(size), + 9999, + tex_format, + GPU_TEXTURE_USAGE_SHADER_READ | + GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW, + NULL); if (tex == NULL) { size[0] = max_ii(1, size[0] / 2); size[1] = max_ii(1, size[1] / 2); - tex = GPU_texture_create_2d_ex( - name, UNPACK2(size), 9999, tex_format, GPU_TEXTURE_USAGE_SHADER_READ, NULL); + tex = GPU_texture_create_2d_ex(name, + UNPACK2(size), + 9999, + tex_format, + GPU_TEXTURE_USAGE_SHADER_READ | + GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW, + NULL); do_rescale = true; } BLI_assert(tex != NULL); From df1fe18ed75812265cf2af186f6b082d8d27d9fe Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Tue, 20 Dec 2022 14:08:37 +0100 Subject: [PATCH 0225/1522] Metal: Fix GPencil texture buffer attribute packing issue and cutting tool rendering. Line Loop topology support for cutting tool and add support for packing several vertex attributes across individual pixels within a texture buffer. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D16783 --- source/blender/gpu/metal/mtl_immediate.mm | 129 +++++++++++++--------- source/blender/gpu/metal/mtl_primitive.hh | 2 +- source/blender/gpu/metal/mtl_texture.mm | 41 ++++++- 3 files changed, 113 insertions(+), 59 deletions(-) diff --git a/source/blender/gpu/metal/mtl_immediate.mm b/source/blender/gpu/metal/mtl_immediate.mm index 7af5ca30578..f0809e6e9d3 100644 --- a/source/blender/gpu/metal/mtl_immediate.mm +++ b/source/blender/gpu/metal/mtl_immediate.mm @@ -39,8 +39,16 @@ uchar *MTLImmediate::begin() metal_primitive_mode_ = mtl_prim_type_to_topology_class(metal_primitive_type_); has_begun_ = true; + /* If prim type is line loop, add an extra vertex at the end for placing the closing line, + * as metal does not support this primitive type. We treat this as a Line strip with one + * extra value. */ + int vertex_alloc_length = vertex_len; + if (prim_type == GPU_PRIM_LINE_LOOP) { + vertex_alloc_length++; + } + /* Allocate a range of data and return host-accessible pointer. */ - const size_t bytes_needed = vertex_buffer_size(&vertex_format, vertex_len); + const size_t bytes_needed = vertex_buffer_size(&vertex_format, vertex_alloc_length); current_allocation_ = context_->get_scratchbuffer_manager() .scratch_buffer_allocate_range_aligned(bytes_needed, 256); [current_allocation_.metal_buffer retain]; @@ -266,71 +274,88 @@ void MTLImmediate::end() * For immediate mode, generating these is currently very cheap, as we use * fast scratch buffer allocations. Though we may benefit from caching of * frequently used buffer sizes. */ + bool rendered = false; if (mtl_needs_topology_emulation(this->prim_type)) { - /* Debug safety check for SSBO FETCH MODE. */ - if (active_mtl_shader->get_uses_ssbo_vertex_fetch()) { - BLI_assert(false && "Topology emulation not supported with SSBO Vertex Fetch mode"); - } - /* Emulate Tri-fan. */ - if (this->prim_type == GPU_PRIM_TRI_FAN) { - /* Prepare Triangle-Fan emulation index buffer on CPU based on number of input - * vertices. */ - uint32_t base_vert_count = this->vertex_idx; - uint32_t num_triangles = max_ii(base_vert_count - 2, 0); - uint32_t fan_index_count = num_triangles * 3; - BLI_assert(num_triangles > 0); + switch (this->prim_type) { + case GPU_PRIM_TRI_FAN: { + /* Debug safety check for SSBO FETCH MODE. */ + if (active_mtl_shader->get_uses_ssbo_vertex_fetch()) { + BLI_assert( + false && + "Topology emulation for TriangleFan not supported with SSBO Vertex Fetch mode"); + } - uint32_t alloc_size = sizeof(uint32_t) * fan_index_count; - uint32_t *index_buffer = nullptr; + /* Prepare Triangle-Fan emulation index buffer on CPU based on number of input + * vertices. */ + uint32_t base_vert_count = this->vertex_idx; + uint32_t num_triangles = max_ii(base_vert_count - 2, 0); + uint32_t fan_index_count = num_triangles * 3; + BLI_assert(num_triangles > 0); - MTLTemporaryBuffer allocation = - context_->get_scratchbuffer_manager().scratch_buffer_allocate_range_aligned( - alloc_size, 128); - index_buffer = (uint32_t *)allocation.data; + uint32_t alloc_size = sizeof(uint32_t) * fan_index_count; + uint32_t *index_buffer = nullptr; - int a = 0; - for (int i = 0; i < num_triangles; i++) { - index_buffer[a++] = 0; - index_buffer[a++] = i + 1; - index_buffer[a++] = i + 2; - } + MTLTemporaryBuffer allocation = + context_->get_scratchbuffer_manager().scratch_buffer_allocate_range_aligned( + alloc_size, 128); + index_buffer = (uint32_t *)allocation.data; - @autoreleasepool { + int a = 0; + for (int i = 0; i < num_triangles; i++) { + index_buffer[a++] = 0; + index_buffer[a++] = i + 1; + index_buffer[a++] = i + 2; + } - id index_buffer_mtl = nil; - uint32_t index_buffer_offset = 0; + @autoreleasepool { - /* Region of scratch buffer used for topology emulation element data. - * NOTE(Metal): We do not need to manually flush as the entire scratch - * buffer for current command buffer is flushed upon submission. */ - index_buffer_mtl = allocation.metal_buffer; - index_buffer_offset = allocation.buffer_offset; + id index_buffer_mtl = nil; + uint32_t index_buffer_offset = 0; - /* Set depth stencil state (requires knowledge of primitive type). */ - context_->ensure_depth_stencil_state(MTLPrimitiveTypeTriangle); + /* Region of scratch buffer used for topology emulation element data. + * NOTE(Metal): We do not need to manually flush as the entire scratch + * buffer for current command buffer is flushed upon submission. */ + index_buffer_mtl = allocation.metal_buffer; + index_buffer_offset = allocation.buffer_offset; - /* Bind Vertex Buffer. */ - rps.bind_vertex_buffer( - current_allocation_.metal_buffer, current_allocation_.buffer_offset, 0); + /* Set depth stencil state (requires knowledge of primitive type). */ + context_->ensure_depth_stencil_state(MTLPrimitiveTypeTriangle); - /* Draw. */ - [rec drawIndexedPrimitives:MTLPrimitiveTypeTriangle - indexCount:fan_index_count - indexType:MTLIndexTypeUInt32 - indexBuffer:index_buffer_mtl - indexBufferOffset:index_buffer_offset]; - } - } - else { - /* TODO(Metal): Topology emulation for line loop. - * NOTE(Metal): This is currently not used anywhere and modified at the high - * level for efficiency in such cases. */ - BLI_assert_msg(false, "LineLoop requires emulation support in immediate mode."); + /* Bind Vertex Buffer. */ + rps.bind_vertex_buffer( + current_allocation_.metal_buffer, current_allocation_.buffer_offset, 0); + + /* Draw. */ + [rec drawIndexedPrimitives:MTLPrimitiveTypeTriangle + indexCount:fan_index_count + indexType:MTLIndexTypeUInt32 + indexBuffer:index_buffer_mtl + indexBufferOffset:index_buffer_offset]; + context_->main_command_buffer.register_draw_counters(fan_index_count); + } + rendered = true; + } break; + case GPU_PRIM_LINE_LOOP: { + /* Patch final vertex of line loop to close. Rendered using LineStrip. + * Note: vertex_len represents original length, however, allocated Metal + * buffer contains space for one extra vertex when LineLoop is used. */ + uchar *buffer_data = reinterpret_cast(current_allocation_.data); + memcpy(buffer_data + (vertex_len)*vertex_format.stride, + buffer_data, + vertex_format.stride); + this->vertex_idx++; + } break; + default: { + BLI_assert_unreachable(); + } break; } } - else { + + /* If not yet rendered, run through main render path. LineLoop primitive topology emulation + * will simply amend original data passed into default rendering path. */ + if (!rendered) { MTLPrimitiveType primitive_type = metal_primitive_type_; int vertex_count = this->vertex_idx; diff --git a/source/blender/gpu/metal/mtl_primitive.hh b/source/blender/gpu/metal/mtl_primitive.hh index b32854a04bf..0b66a51d630 100644 --- a/source/blender/gpu/metal/mtl_primitive.hh +++ b/source/blender/gpu/metal/mtl_primitive.hh @@ -39,10 +39,10 @@ static inline MTLPrimitiveType gpu_prim_type_to_metal(GPUPrimType prim_type) return MTLPrimitiveTypePoint; case GPU_PRIM_LINES: case GPU_PRIM_LINES_ADJ: - case GPU_PRIM_LINE_LOOP: return MTLPrimitiveTypeLine; case GPU_PRIM_LINE_STRIP: case GPU_PRIM_LINE_STRIP_ADJ: + case GPU_PRIM_LINE_LOOP: return MTLPrimitiveTypeLineStrip; case GPU_PRIM_TRIS: case GPU_PRIM_TRI_FAN: diff --git a/source/blender/gpu/metal/mtl_texture.mm b/source/blender/gpu/metal/mtl_texture.mm index 411d1187610..d2d466bffe1 100644 --- a/source/blender/gpu/metal/mtl_texture.mm +++ b/source/blender/gpu/metal/mtl_texture.mm @@ -1621,6 +1621,7 @@ bool gpu::MTLTexture::init_internal(GPUVertBuf *vbo) } /* Verify Texture and vertex buffer alignment. */ + const GPUVertFormat *format = GPU_vertbuf_get_format(vbo); int bytes_per_pixel = get_mtl_format_bytesize(mtl_format); int bytes_per_row = bytes_per_pixel * w_; @@ -1628,12 +1629,40 @@ bool gpu::MTLTexture::init_internal(GPUVertBuf *vbo) uint32_t align_requirement = static_cast( [mtl_ctx->device minimumLinearTextureAlignmentForPixelFormat:mtl_format]); - /* Verify per-vertex size aligns with texture size. */ - const GPUVertFormat *format = GPU_vertbuf_get_format(vbo); - BLI_assert(bytes_per_pixel == format->stride && - "Pixel format stride MUST match the texture format stride -- These being different " - "is likely caused by Metal's VBO padding to a minimum of 4-bytes per-vertex"); - UNUSED_VARS_NDEBUG(format); + /* If stride is larger than bytes per pixel, but format has multiple attributes, + * split attributes across several pixels. */ + if (format->stride > bytes_per_pixel && format->attr_len > 1) { + + /* We need to increase the number of pixels available to store additional attributes. + * First ensure that the total stride of the vertex format fits uniformly into + * multiple pixels. If these sizes are different, then attributes are of differing + * sizes and this operation is unsupported. */ + if (bytes_per_pixel * format->attr_len != format->stride) { + BLI_assert_msg(false, + "Cannot split attributes across multiple pixels as attribute format sizes do " + "not match."); + return false; + } + + /* Provide a single pixel per attribute. */ + /* Increase bytes per row to ensure there are enough bytes for all vertex attribute data. */ + bytes_per_row *= format->attr_len; + BLI_assert(bytes_per_row == format->stride * w_); + + /* Multiply width of image to provide one attribute per pixel. */ + w_ *= format->attr_len; + BLI_assert(bytes_per_row == bytes_per_pixel * w_); + BLI_assert_msg(w_ == mtl_vbo->vertex_len * format->attr_len, + "Image should contain one pixel for each attribute in every vertex."); + } + else { + /* Verify per-vertex size aligns with texture size. */ + BLI_assert(bytes_per_pixel == format->stride && + "Pixel format stride MUST match the texture format stride -- These being different " + "is likely caused by Metal's VBO padding to a minimum of 4-bytes per-vertex." + " If multiple attributes are used. Each attribute is to be packed into its own " + "individual pixel when stride length is exceeded. "); + } /* Create texture descriptor. */ BLI_assert(type_ == GPU_TEXTURE_BUFFER); From b3464fe152ca8a7b50dddf0774e33d24e38fd6b5 Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Tue, 20 Dec 2022 14:15:52 +0100 Subject: [PATCH 0226/1522] Metal: Implement suppot for clip plane toggling via GPU_clip_distances. The Metal backend already supports output for the 6 clipping planes via gl_ClipDistances equivalent, however, functionality to toggle clipping plane enablement was missing. Authored by Apple: Michael Parkin-White Ref T96261 Depends on D16777 Reviewed By: fclem Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D16813 --- .../infos/eevee_legacy_material_info.hh | 4 ++- source/blender/gpu/metal/mtl_context.hh | 3 ++ .../gpu/metal/mtl_pso_descriptor_state.hh | 10 ++++++ source/blender/gpu/metal/mtl_shader.mm | 31 +++++++++++++++++ .../blender/gpu/metal/mtl_shader_generator.mm | 25 +++++++++----- source/blender/gpu/metal/mtl_state.hh | 2 ++ source/blender/gpu/metal/mtl_state.mm | 34 +++++++++++++++++-- .../gpu/shaders/metal/mtl_shader_common.msl | 16 +++++++++ 8 files changed, 113 insertions(+), 12 deletions(-) diff --git a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh index 2d1671ac98d..dd848d6fef9 100644 --- a/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh +++ b/source/blender/draw/engines/eevee/shaders/infos/eevee_legacy_material_info.hh @@ -59,7 +59,9 @@ GPU_SHADER_CREATE_INFO(eevee_legacy_material_surface_vert_common) .additional_info("eevee_legacy_material_empty_base") .additional_info("draw_resource_id_varying") .additional_info("eevee_legacy_common_utiltex_lib") - .additional_info("eevee_legacy_closure_eval_surface_lib"); + .additional_info("eevee_legacy_closure_eval_surface_lib") + /* Planar reflections assigns to gl_ClipDistance via surface_vert.glsl. */ + .define("USE_CLIP_PLANES"); GPU_SHADER_CREATE_INFO(eevee_legacy_material_surface_vert) .additional_info("eevee_legacy_material_surface_vert_common") diff --git a/source/blender/gpu/metal/mtl_context.hh b/source/blender/gpu/metal/mtl_context.hh index 3656fbdcd19..a26e31aadde 100644 --- a/source/blender/gpu/metal/mtl_context.hh +++ b/source/blender/gpu/metal/mtl_context.hh @@ -460,6 +460,9 @@ struct MTLContextGlobalShaderPipelineState { /* Render parameters. */ float point_size = 1.0f; float line_width = 1.0f; + + /* Clipping plane enablement. */ + bool clip_distance_enabled[6] = {false}; }; /* Command Buffer Manager - Owned by MTLContext. diff --git a/source/blender/gpu/metal/mtl_pso_descriptor_state.hh b/source/blender/gpu/metal/mtl_pso_descriptor_state.hh index 8b0d69c6251..1890f6e8ccd 100644 --- a/source/blender/gpu/metal/mtl_pso_descriptor_state.hh +++ b/source/blender/gpu/metal/mtl_pso_descriptor_state.hh @@ -174,6 +174,9 @@ struct MTLRenderPipelineStateDescriptor { /* Global color write mask as this cannot be specified per attachment. */ MTLColorWriteMask color_write_mask; + /* Clip distance enablement. */ + uchar clipping_plane_enable_mask = 0; + /* Point size required by point primitives. */ float point_size = 0.0f; @@ -184,6 +187,10 @@ struct MTLRenderPipelineStateDescriptor { return false; } + if (clipping_plane_enable_mask != other.clipping_plane_enable_mask) { + return false; + } + if ((num_color_attachments != other.num_color_attachments) || (depth_attachment_format != other.depth_attachment_format) || (stencil_attachment_format != other.stencil_attachment_format) || @@ -243,6 +250,9 @@ struct MTLRenderPipelineStateDescriptor { hash |= uint64_t((this->blending_enabled && (this->num_color_attachments > 0)) ? 1 : 0) << 62; hash ^= uint64_t(this->point_size); + /* Clipping plane enablement. */ + hash ^= uint64_t(clipping_plane_enable_mask) << 20; + return hash; } diff --git a/source/blender/gpu/metal/mtl_shader.mm b/source/blender/gpu/metal/mtl_shader.mm index 747746ea424..496f919d189 100644 --- a/source/blender/gpu/metal/mtl_shader.mm +++ b/source/blender/gpu/metal/mtl_shader.mm @@ -654,6 +654,14 @@ MTLRenderPipelineStateInstance *MTLShader::bake_current_pipeline_state( pipeline_descriptor.src_rgb_blend_factor = ctx->pipeline_state.src_rgb_blend_factor; pipeline_descriptor.point_size = ctx->pipeline_state.point_size; + /* Resolve clipping plane enablement. */ + pipeline_descriptor.clipping_plane_enable_mask = 0; + for (const int plane : IndexRange(6)) { + pipeline_descriptor.clipping_plane_enable_mask = + pipeline_descriptor.clipping_plane_enable_mask | + ((ctx->pipeline_state.clip_distance_enabled[plane]) ? (1 << plane) : 0); + } + /* Primitive Type -- Primitive topology class needs to be specified for layered rendering. */ bool requires_specific_topology_class = uses_mtl_array_index_ || prim_type == MTLPrimitiveTopologyClassPoint; @@ -856,6 +864,29 @@ MTLRenderPipelineStateInstance *MTLShader::bake_current_pipeline_state( withName:@"MTL_transform_feedback_buffer_index"]; } + /* Clipping planes. */ + int MTL_clip_distances_enabled = (pipeline_descriptor.clipping_plane_enable_mask > 0) ? 1 : 0; + + /* Only define specialization constant if planes are required. + * We guard clip_planes usage on this flag. */ + [values setConstantValue:&MTL_clip_distances_enabled + type:MTLDataTypeInt + withName:@"MTL_clip_distances_enabled"]; + + if (MTL_clip_distances_enabled > 0) { + /* Assign individual enablement flags. Only define a flag function constant + * if it is used. */ + for (const int plane : IndexRange(6)) { + int plane_enabled = ctx->pipeline_state.clip_distance_enabled[plane] ? 1 : 0; + if (plane_enabled) { + [values + setConstantValue:&plane_enabled + type:MTLDataTypeInt + withName:[NSString stringWithFormat:@"MTL_clip_distance_enabled%d", plane]]; + } + } + } + /* gl_PointSize constant. */ bool null_pointsize = true; float MTL_pointsize = pipeline_descriptor.point_size; diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm index b8c9a28efbd..b938f3fd228 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.mm +++ b/source/blender/gpu/metal/mtl_shader_generator.mm @@ -1876,11 +1876,14 @@ std::string MSLGeneratorInterface::generate_msl_vertex_out_struct(ShaderStage sh out << "#if defined(USE_CLIP_PLANES) || defined(USE_WORLD_CLIP_PLANES)" << std::endl; if (this->clip_distances.size() > 1) { /* Output array of clip distances if specified. */ - out << "\tfloat clipdistance [[clip_distance]] [" << this->clip_distances.size() << "];" - << std::endl; + out << "\tfloat clipdistance [[clip_distance, " + "function_constant(MTL_clip_distances_enabled)]] [" + << this->clip_distances.size() << "];" << std::endl; } else if (this->clip_distances.size() > 0) { - out << "\tfloat clipdistance [[clip_distance]];" << std::endl; + out << "\tfloat clipdistance [[clip_distance, " + "function_constant(MTL_clip_distances_enabled)]];" + << std::endl; } out << "#endif" << std::endl; } @@ -2157,18 +2160,24 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_population() << std::endl; } - /* Output clip-distances. */ - out << "#if defined(USE_CLIP_PLANES) || defined(USE_WORLD_CLIP_PLANES)" << std::endl; + /* Output clip-distances. + * Clip distances are only written to if both clipping planes are turned on for the shader, + * and the clipping planes are enabled. Enablement is controlled on a per-plane basis + * via function constants in the shader pipeline state object (PSO). */ + out << "#if defined(USE_CLIP_PLANES) || defined(USE_WORLD_CLIP_PLANES)" << std::endl + << "if(MTL_clip_distances_enabled) {" << std::endl; if (this->clip_distances.size() > 1) { for (int cd = 0; cd < this->clip_distances.size(); cd++) { - out << "\toutput.clipdistance[" << cd << "] = vertex_shader_instance.gl_ClipDistance_" << cd - << ";" << std::endl; + /* Default value when clipping is disabled >= 0.0 to ensure primitive is not clipped. */ + out << "\toutput.clipdistance[" << cd + << "] = (is_function_constant_defined(MTL_clip_distance_enabled" << cd + << "))?vertex_shader_instance.gl_ClipDistance_" << cd << ":1.0;" << std::endl; } } else if (this->clip_distances.size() > 0) { out << "\toutput.clipdistance = vertex_shader_instance.gl_ClipDistance_0;" << std::endl; } - out << "#endif" << std::endl; + out << "}" << std::endl << "#endif" << std::endl; /* Populate output vertex variables. */ int output_id = 0; diff --git a/source/blender/gpu/metal/mtl_state.hh b/source/blender/gpu/metal/mtl_state.hh index 56114fd313e..bc6c700859d 100644 --- a/source/blender/gpu/metal/mtl_state.hh +++ b/source/blender/gpu/metal/mtl_state.hh @@ -80,6 +80,8 @@ class MTLStateManager : public StateManager { void mtl_depth_range(float near, float far); void mtl_stencil_mask(uint mask); void mtl_stencil_set_func(eGPUStencilTest stencil_func, int ref, uint mask); + void mtl_clip_plane_enable(uint i); + void mtl_clip_plane_disable(uint i); MEM_CXX_CLASS_ALLOC_FUNCS("MTLStateManager") }; diff --git a/source/blender/gpu/metal/mtl_state.mm b/source/blender/gpu/metal/mtl_state.mm index aeb1ec15de3..95b7e5edc7a 100644 --- a/source/blender/gpu/metal/mtl_state.mm +++ b/source/blender/gpu/metal/mtl_state.mm @@ -35,6 +35,12 @@ MTLStateManager::MTLStateManager(MTLContext *ctx) : StateManager() /* Force update using default state. */ current_ = ~state; current_mutable_ = ~mutable_state; + + /* Clip distances initial mask forces to 0x111, which exceeds + * max clip plane count of 6, so limit to ensure all clipping + * planes get disabled. */ + current_.clip_distances = 6; + set_state(state); set_mutable_state(mutable_state); } @@ -52,6 +58,7 @@ void MTLStateManager::force_state() { /* Little exception for clip distances since they need to keep the old count correct. */ uint32_t clip_distances = current_.clip_distances; + BLI_assert(clip_distances <= 6); current_ = ~this->state; current_.clip_distances = clip_distances; current_mutable_ = ~this->mutable_state; @@ -329,11 +336,32 @@ void MTLStateManager::set_stencil_mask(const eGPUStencilTest test, const GPUStat } } +void MTLStateManager::mtl_clip_plane_enable(uint i) +{ + BLI_assert(context_); + MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state; + pipeline_state.clip_distance_enabled[i] = true; + pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG; +} + +void MTLStateManager::mtl_clip_plane_disable(uint i) +{ + BLI_assert(context_); + MTLContextGlobalShaderPipelineState &pipeline_state = context_->pipeline_state; + pipeline_state.clip_distance_enabled[i] = false; + pipeline_state.dirty_flags |= MTL_PIPELINE_STATE_PSO_FLAG; +} + void MTLStateManager::set_clip_distances(const int new_dist_len, const int old_dist_len) { - /* TODO(Metal): Support Clip distances in METAL. Clip distance - * assignment via shader is supported, but global clip-states require - * support. */ + BLI_assert(new_dist_len <= 6); + BLI_assert(old_dist_len <= 6); + for (uint i = 0; i < new_dist_len; i++) { + mtl_clip_plane_enable(i); + } + for (uint i = new_dist_len; i < old_dist_len; i++) { + mtl_clip_plane_disable(i); + } } void MTLStateManager::set_logic_op(const bool enable) diff --git a/source/blender/gpu/shaders/metal/mtl_shader_common.msl b/source/blender/gpu/shaders/metal/mtl_shader_common.msl index c504cdbacb1..9ed320335c7 100644 --- a/source/blender/gpu/shaders/metal/mtl_shader_common.msl +++ b/source/blender/gpu/shaders/metal/mtl_shader_common.msl @@ -42,6 +42,22 @@ constant int MTL_AttributeConvert15 [[function_constant(17)]]; * Unused if function constant not set. */ constant int MTL_transform_feedback_buffer_index [[function_constant(18)]]; +/** Clip distance enablement. */ +/* General toggle to control whether any clipping distanes are written at all. + * This is an optimization to avoid having the clipping distance shader output + * paramter if it is not needed. */ +constant int MTL_clip_distances_enabled [[function_constant(19)]]; + +/* If clipping planes are enabled at all, then we require an enablement + * flag per clipping plane. If enabled, then gl_ClipDistances[N] will + * control clipping for a given plane, otherwise the value is ignored. */ +constant int MTL_clip_distance_enabled0 [[function_constant(20)]]; +constant int MTL_clip_distance_enabled1 [[function_constant(21)]]; +constant int MTL_clip_distance_enabled2 [[function_constant(22)]]; +constant int MTL_clip_distance_enabled3 [[function_constant(23)]]; +constant int MTL_clip_distance_enabled4 [[function_constant(24)]]; +constant int MTL_clip_distance_enabled5 [[function_constant(25)]]; + /** Internal attribute conversion functionality. */ /* Following descriptions in mtl_shader.hh, Metal only supports some implicit * attribute type conversions. These conversions occur when there is a difference From 3efb31ee310b465f741cd2d0a1bca98d378409e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 20 Dec 2022 14:17:30 +0100 Subject: [PATCH 0227/1522] Cleanup: add some deformation-related comments Add documentation for `BKE_id_defgroup_list_get()` and document that `CD_MDEFORMVERT` mesh layers contain `MDeformVert` structs. No functional changes. --- source/blender/blenkernel/BKE_deform.h | 5 +++++ source/blender/makesdna/DNA_customdata_types.h | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h index 4023d6829d4..995a17c4f71 100644 --- a/source/blender/blenkernel/BKE_deform.h +++ b/source/blender/blenkernel/BKE_deform.h @@ -37,6 +37,11 @@ int BKE_object_defgroup_active_index_get(const struct Object *ob); */ void BKE_object_defgroup_active_index_set(struct Object *ob, int new_index); +/** + * Return the ID's vertex group names. + * Supports Mesh (ME), Lattice (LT), and GreasePencil (GD) IDs. + * \return ListBase of bDeformGroup pointers. + */ const struct ListBase *BKE_id_defgroup_list_get(const struct ID *id); struct ListBase *BKE_id_defgroup_list_get_mutable(struct ID *id); int BKE_id_defgroup_name_index(const struct ID *id, const char *name); diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 5a534fa7904..3bff2f4316c 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -92,7 +92,7 @@ typedef enum eCustomDataType { #ifdef DNA_DEPRECATED_ALLOW CD_MSTICKY = 1, /* DEPRECATED */ #endif - CD_MDEFORMVERT = 2, + CD_MDEFORMVERT = 2, /* Array of `MDeformVert`. */ CD_MEDGE = 3, CD_MFACE = 4, CD_MTFACE = 5, From dedca2c9948af7a65dd78263e37f77052fc03de7 Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Tue, 20 Dec 2022 14:18:13 +0100 Subject: [PATCH 0228/1522] Fix T103313: Resolve shader compilation failures when enabling GPU workarounds. A number of paths resulted in compilation errors after porting EEVEE to use Create-Info. Namely the fallback path for cubemap support. A number of other strict compilation failures regarding format comparison also required fixing when this mode is enabled. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Maniphest Tasks: T96261, T103313 Differential Revision: https://developer.blender.org/D16819 --- .../engines/eevee/shaders/cubemap_lib.glsl | 11 +++-------- .../engines/eevee/shaders/shadow_vert.glsl | 2 +- .../engines/eevee/shaders/surface_vert.glsl | 2 +- .../shaders/eevee_attributes_lib.glsl | 2 +- .../shaders/overlay_edit_mesh_common_lib.glsl | 6 +++--- .../shaders/overlay_edit_mesh_vert.glsl | 4 ++-- .../shaders/overlay_edit_uv_edges_vert.glsl | 4 ++-- .../shaders/overlay_edit_uv_faces_vert.glsl | 4 ++-- .../shaders/overlay_edit_uv_verts_vert.glsl | 4 ++-- .../overlay_motion_path_point_vert.glsl | 2 +- .../shaders/gpu_shader_2D_nodelink_vert.glsl | 8 ++++---- .../gpu_shader_keyframe_shape_frag.glsl | 18 +++++++++--------- .../gpu/shaders/metal/mtl_shader_defines.msl | 3 +++ .../shaders/opengl/glsl_shader_defines.glsl | 7 +++++++ 14 files changed, 41 insertions(+), 36 deletions(-) diff --git a/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl b/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl index cde52af39e0..30e11d57c9b 100644 --- a/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/cubemap_lib.glsl @@ -1,12 +1,7 @@ -#ifdef GPU_ARB_texture_cube_map_array - -# define textureLod_cubemapArray(tex, co, lod) textureLod(tex, co, lod) - -#else - -/* Fallback implementation for hardware not supporting cubemap arrays. */ -# define samplerCubeArray sampler2DArray +/* Fallback implementation for hardware not supporting cubemap arrays. + * `samplerCubeArray` fallback declaration as sampler2DArray in `glsl_shader_defines.glsl`*/ +#ifndef GPU_ARB_texture_cube_map_array float cubemap_face_index(vec3 P) { diff --git a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl index 92be7294a11..8a99f2cc5e2 100644 --- a/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/shadow_vert.glsl @@ -70,7 +70,7 @@ int g_curves_attr_id = 0; int curves_attribute_element_id() { int id = hairStrandID; - if (drw_curves.is_point_attribute[g_curves_attr_id][0] != 0) { + if (drw_curves.is_point_attribute[g_curves_attr_id][0] != 0u) { id = hair_get_base_id(); } diff --git a/source/blender/draw/engines/eevee/shaders/surface_vert.glsl b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl index 212208728a0..a0eddc583b7 100644 --- a/source/blender/draw/engines/eevee/shaders/surface_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/surface_vert.glsl @@ -77,7 +77,7 @@ int g_curves_attr_id = 0; int curves_attribute_element_id() { int id = hairStrandID; - if (drw_curves.is_point_attribute[g_curves_attr_id][0] != 0) { + if (drw_curves.is_point_attribute[g_curves_attr_id][0] != 0u) { id = hair_get_base_id(); } diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl index ea1b02e56b3..f3bb1e2f490 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_attributes_lib.glsl @@ -133,7 +133,7 @@ int g_curves_attr_id = 0; int curves_attribute_element_id() { int id = interp.curves_strand_id; - if (drw_curves.is_point_attribute[g_curves_attr_id][0] != 0) { + if (drw_curves.is_point_attribute[g_curves_attr_id][0] != 0u) { # ifdef COMMON_HAIR_LIB id = hair_get_base_id(); # endif diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_common_lib.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_common_lib.glsl index 88a976931cc..358a18c88d0 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_common_lib.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_common_lib.glsl @@ -17,7 +17,7 @@ vec4 EDIT_MESH_edge_color_inner(uint edge_flag) color = ((edge_flag & EDGE_SELECTED) != 0u) ? color_select : color; color = ((edge_flag & EDGE_ACTIVE) != 0u) ? colorEditMeshActive : color; - color.a = (selectEdges || (edge_flag & (EDGE_SELECTED | EDGE_ACTIVE)) != 0) ? 1.0 : 0.7; + color.a = (selectEdges || (edge_flag & (EDGE_SELECTED | EDGE_ACTIVE)) != 0u) ? 1.0 : 0.7; return color; } @@ -35,7 +35,7 @@ vec4 EDIT_MESH_edge_vertex_color(uint vertex_flag) vec4 EDIT_MESH_vertex_color(uint vertex_flag, float vertex_crease) { - if ((vertex_flag & VERT_ACTIVE) != 0) { + if ((vertex_flag & VERT_ACTIVE) != 0u) { return vec4(colorEditMeshActive.xyz, 1.0); } else if ((vertex_flag & VERT_SELECTED) != 0u) { @@ -57,7 +57,7 @@ vec4 EDIT_MESH_face_color(uint face_flag) color = ((face_flag & FACE_FREESTYLE) != 0u) ? colorFaceFreestyle : color; color = ((face_flag & FACE_SELECTED) != 0u) ? colorFaceSelect : color; color = ((face_flag & FACE_ACTIVE) != 0u) ? color_active : color; - color.a *= ((face_flag & (FACE_FREESTYLE | FACE_SELECTED | FACE_ACTIVE)) == 0 || selectFaces) ? + color.a *= ((face_flag & (FACE_FREESTYLE | FACE_SELECTED | FACE_ACTIVE)) == 0u || selectFaces) ? 1.0 : 0.5; return color; diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert.glsl index be90399d6b7..2aa9b4e3ac0 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_mesh_vert.glsl @@ -38,10 +38,10 @@ void main() finalColor = EDIT_MESH_vertex_color(m_data.y, vertexCrease); gl_PointSize = sizeVertex * ((vertexCrease > 0.0) ? 3.0 : 2.0); /* Make selected and active vertex always on top. */ - if ((data.x & VERT_SELECTED) != 0) { + if ((data.x & VERT_SELECTED) != 0u) { gl_Position.z -= 5e-7 * abs(gl_Position.w); } - if ((data.x & VERT_ACTIVE) != 0) { + if ((data.x & VERT_ACTIVE) != 0u) { gl_Position.z -= 5e-7 * abs(gl_Position.w); } diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl index fdec1421b66..8f9f416f822 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_edges_vert.glsl @@ -11,9 +11,9 @@ void main() half_pixel_offset; #ifdef USE_EDGE_SELECT - bool is_select = (flag & int(EDGE_UV_SELECT)) != 0u; + bool is_select = (flag & int(EDGE_UV_SELECT)) != 0; #else - bool is_select = (flag & int(VERT_UV_SELECT)) != 0u; + bool is_select = (flag & int(VERT_UV_SELECT)) != 0; #endif geom_in.selectionFac = is_select ? 1.0 : 0.0; /* Move selected edges to the top diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_faces_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_faces_vert.glsl index 80ea6228675..ca5f83501a4 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_faces_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_faces_vert.glsl @@ -5,8 +5,8 @@ void main() vec3 world_pos = point_object_to_world(vec3(au, 0.0)); gl_Position = point_world_to_ndc(world_pos); - bool is_selected = (flag & FACE_UV_SELECT) != 0; - bool is_active = (flag & FACE_UV_ACTIVE) != 0; + bool is_selected = (flag & FACE_UV_SELECT) != 0u; + bool is_active = (flag & FACE_UV_ACTIVE) != 0u; finalColor = (is_selected) ? colorFaceSelect : colorFace; finalColor = (is_active) ? colorEditMeshActive : finalColor; diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_verts_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_verts_vert.glsl index 9f9b02ce19d..2a59a623995 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_verts_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_verts_vert.glsl @@ -5,8 +5,8 @@ const vec4 pinned_col = vec4(1.0, 0.0, 0.0, 1.0); void main() { - bool is_selected = (flag & (VERT_UV_SELECT | FACE_UV_SELECT)) != 0; - bool is_pinned = (flag & VERT_UV_PINNED) != 0; + bool is_selected = (flag & (VERT_UV_SELECT | FACE_UV_SELECT)) != 0u; + bool is_pinned = (flag & VERT_UV_PINNED) != 0u; vec4 deselect_col = (is_pinned) ? pinned_col : vec4(color.rgb, 1.0); fillColor = (is_selected) ? colorVertexSelect : deselect_col; outlineColor = (is_pinned) ? pinned_col : vec4(fillColor.rgb, 0.0); diff --git a/source/blender/draw/engines/overlay/shaders/overlay_motion_path_point_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_point_vert.glsl index 7305d00c052..e07f0bf3ee9 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_motion_path_point_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_motion_path_point_vert.glsl @@ -24,7 +24,7 @@ void main() } if (showKeyFrames) { - if ((flag & MOTIONPATH_VERT_KEY) != 0) { + if ((flag & MOTIONPATH_VERT_KEY) != 0u) { gl_PointSize = float(pointSize + 5); finalColor = colorVertexSelect; /* Bias more to get these on top of regular points */ diff --git a/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl index 794af5b69a5..75caf81f9fe 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_nodelink_vert.glsl @@ -16,11 +16,11 @@ void main(void) const float end_gradient_threshold = 0.65; #ifdef USE_INSTANCE -# define colStart (colid_doarrow[0] < 3 ? start_color : node_link_data.colors[colid_doarrow[0]]) -# define colEnd (colid_doarrow[1] < 3 ? end_color : node_link_data.colors[colid_doarrow[1]]) +# define colStart (colid_doarrow[0] < 3u ? start_color : node_link_data.colors[colid_doarrow[0]]) +# define colEnd (colid_doarrow[1] < 3u ? end_color : node_link_data.colors[colid_doarrow[1]]) # define colShadow node_link_data.colors[colid_doarrow[2]] -# define doArrow (colid_doarrow[3] != 0) -# define doMuted (domuted[0] != 0) +# define doArrow (colid_doarrow[3] != 0u) +# define doMuted (domuted[0] != 0u) #else vec2 P0 = node_link_data.bezierPts[0].xy; vec2 P1 = node_link_data.bezierPts[1].xy; diff --git a/source/blender/gpu/shaders/gpu_shader_keyframe_shape_frag.glsl b/source/blender/gpu/shaders/gpu_shader_keyframe_shape_frag.glsl index 0b1683e93cd..3690dd8d1d2 100644 --- a/source/blender/gpu/shaders/gpu_shader_keyframe_shape_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_keyframe_shape_frag.glsl @@ -1,13 +1,13 @@ /* Values in GPU_shader.h. */ -#define GPU_KEYFRAME_SHAPE_DIAMOND (1 << 0) -#define GPU_KEYFRAME_SHAPE_CIRCLE (1 << 1) -#define GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL (1 << 2) -#define GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL (1 << 3) -#define GPU_KEYFRAME_SHAPE_INNER_DOT (1 << 4) -#define GPU_KEYFRAME_SHAPE_ARROW_END_MAX (1 << 8) -#define GPU_KEYFRAME_SHAPE_ARROW_END_MIN (1 << 9) -#define GPU_KEYFRAME_SHAPE_ARROW_END_MIXED (1 << 10) +#define GPU_KEYFRAME_SHAPE_DIAMOND (1u << 0) +#define GPU_KEYFRAME_SHAPE_CIRCLE (1u << 1) +#define GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL (1u << 2) +#define GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL (1u << 3) +#define GPU_KEYFRAME_SHAPE_INNER_DOT (1u << 4) +#define GPU_KEYFRAME_SHAPE_ARROW_END_MAX (1u << 8) +#define GPU_KEYFRAME_SHAPE_ARROW_END_MIN (1u << 9) +#define GPU_KEYFRAME_SHAPE_ARROW_END_MIXED (1u << 10) #define GPU_KEYFRAME_SHAPE_SQUARE \ (GPU_KEYFRAME_SHAPE_CLIPPED_VERTICAL | GPU_KEYFRAME_SHAPE_CLIPPED_HORIZONTAL) @@ -18,7 +18,7 @@ const float minmax_scale = sqrt(1.0 / (1.0 + 1.0 / minmax_bias)); bool test(uint bit) { - return (finalFlags & bit) != 0; + return (finalFlags & bit) != 0u; } void main() diff --git a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl index 2fce054c2f1..68ad8fb5f49 100644 --- a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl +++ b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl @@ -153,6 +153,9 @@ struct SStruct { /* Texture-write functions. */ #define imageStore(_tex, _coord, _value) _texture_write_internal(_tex, _coord, _value) +/* Cubemap support always available when using Metal. */ +#define textureLod_cubemapArray(tex, co, lod) textureLod(tex, co, lod) + /* Singular return values from texture functions of type DEPTH are often indexed with either .r or * .x. This is a lightweight wrapper type for handling this syntax. */ union _msl_return_float { diff --git a/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl b/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl index 706bae3e940..f2d972ea574 100644 --- a/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl +++ b/source/blender/gpu/shaders/opengl/glsl_shader_defines.glsl @@ -1,4 +1,11 @@ +/* Cubemap support and fallback implementation declarations. */ +#ifdef GPU_ARB_texture_cube_map_array +# define textureLod_cubemapArray(tex, co, lod) textureLod(tex, co, lod) +#else +# define samplerCubeArray sampler2DArray +#endif + /* Texture format tokens -- Type explicitness required by other Graphics APIs. */ #define depth2D sampler2D #define depth2DArray sampler2DArray From ddd24186d9e994e445e2bc6c872fcd340db89f10 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 20 Dec 2022 14:36:00 +0100 Subject: [PATCH 0229/1522] Geometry Nodes: avoid some overhead during field inferencing Previously, the same `FieldInferencingInterface` was build for every node multiple times. Now only once during the inferencing. Going forward, it would be even better to store the inferencing interface as part of the node declaration to avoid building it during inferencing at all. --- .../intern/node_tree_field_inferencing.cc | 71 +++++++++++++------ 1 file changed, 49 insertions(+), 22 deletions(-) diff --git a/source/blender/blenkernel/intern/node_tree_field_inferencing.cc b/source/blender/blenkernel/intern/node_tree_field_inferencing.cc index 88fd3636633..5c527e29131 100644 --- a/source/blender/blenkernel/intern/node_tree_field_inferencing.cc +++ b/source/blender/blenkernel/intern/node_tree_field_inferencing.cc @@ -5,6 +5,7 @@ #include "NOD_node_declaration.hh" +#include "BLI_resource_scope.hh" #include "BLI_set.hh" #include "BLI_stack.hh" @@ -91,9 +92,10 @@ static OutputFieldDependency get_interface_output_field_dependency(const bNode & return socket_decl.output_field_dependency(); } -static FieldInferencingInterface get_dummy_field_inferencing_interface(const bNode &node) +static const FieldInferencingInterface &get_dummy_field_inferencing_interface(const bNode &node, + ResourceScope &scope) { - FieldInferencingInterface inferencing_interface; + auto &inferencing_interface = scope.construct(); inferencing_interface.inputs.append_n_times(InputSocketFieldType::None, node.input_sockets().size()); inferencing_interface.outputs.append_n_times(OutputFieldDependency::ForDataSource(), @@ -106,17 +108,19 @@ static FieldInferencingInterface get_dummy_field_inferencing_interface(const bNo * In the future, this information can be stored in the node declaration. This would allow this * function to return a reference, making it more efficient. */ -static FieldInferencingInterface get_node_field_inferencing_interface(const bNode &node) +static const FieldInferencingInterface &get_node_field_inferencing_interface(const bNode &node, + ResourceScope &scope) { /* Node groups already reference all required information, so just return that. */ if (node.is_group()) { bNodeTree *group = (bNodeTree *)node.id; if (group == nullptr) { - return FieldInferencingInterface(); + static const FieldInferencingInterface empty_interface; + return empty_interface; } if (!ntreeIsRegistered(group)) { /* This can happen when there is a linked node group that was not found (see T92799). */ - return get_dummy_field_inferencing_interface(node); + return get_dummy_field_inferencing_interface(node, scope); } if (!group->runtime->field_inferencing_interface) { /* This shouldn't happen because referenced node groups should always be updated first. */ @@ -125,7 +129,7 @@ static FieldInferencingInterface get_node_field_inferencing_interface(const bNod return *group->runtime->field_inferencing_interface; } - FieldInferencingInterface inferencing_interface; + auto &inferencing_interface = scope.construct(); for (const bNodeSocket *input_socket : node.input_sockets()) { inferencing_interface.inputs.append(get_interface_input_field_type(node, *input_socket)); } @@ -185,7 +189,9 @@ static Vector gather_input_socket_dependencies( * to figure out if it is always a field or if it depends on any group inputs. */ static OutputFieldDependency find_group_output_dependencies( - const bNodeSocket &group_output_socket, const Span field_state_by_socket_id) + const bNodeSocket &group_output_socket, + const Span interface_by_node, + const Span field_state_by_socket_id) { if (!is_field_socket_type(group_output_socket)) { return OutputFieldDependency::ForDataSource(); @@ -227,8 +233,8 @@ static OutputFieldDependency find_group_output_dependencies( } } else if (!origin_state.is_single) { - const FieldInferencingInterface inferencing_interface = - get_node_field_inferencing_interface(origin_node); + const FieldInferencingInterface &inferencing_interface = + *interface_by_node[origin_node.index()]; const OutputFieldDependency &field_dependency = inferencing_interface.outputs[origin_socket->index()]; @@ -251,13 +257,14 @@ static OutputFieldDependency find_group_output_dependencies( } static void propagate_data_requirements_from_right_to_left( - const bNodeTree &tree, const MutableSpan field_state_by_socket_id) + const bNodeTree &tree, + const Span interface_by_node, + const MutableSpan field_state_by_socket_id) { const Span toposort_result = tree.toposort_right_to_left(); for (const bNode *node : toposort_result) { - const FieldInferencingInterface inferencing_interface = get_node_field_inferencing_interface( - *node); + const FieldInferencingInterface &inferencing_interface = *interface_by_node[node->index()]; for (const bNodeSocket *output_socket : node->output_sockets()) { SocketFieldState &state = field_state_by_socket_id[output_socket->index_in_tree()]; @@ -369,7 +376,9 @@ static void determine_group_input_states( } static void propagate_field_status_from_left_to_right( - const bNodeTree &tree, const MutableSpan field_state_by_socket_id) + const bNodeTree &tree, + const Span interface_by_node, + const MutableSpan field_state_by_socket_id) { const Span toposort_result = tree.toposort_left_to_right(); @@ -378,8 +387,7 @@ static void propagate_field_status_from_left_to_right( continue; } - const FieldInferencingInterface inferencing_interface = get_node_field_inferencing_interface( - *node); + const FieldInferencingInterface &inferencing_interface = *interface_by_node[node->index()]; /* Update field state of input sockets, also taking into account linked origin sockets. */ for (const bNodeSocket *input_socket : node->input_sockets()) { @@ -440,9 +448,11 @@ static void propagate_field_status_from_left_to_right( } } -static void determine_group_output_states(const bNodeTree &tree, - FieldInferencingInterface &new_inferencing_interface, - const Span field_state_by_socket_id) +static void determine_group_output_states( + const bNodeTree &tree, + FieldInferencingInterface &new_inferencing_interface, + const Span interface_by_node, + const Span field_state_by_socket_id) { const bNode *group_output_node = tree.group_output_node(); if (!group_output_node) { @@ -451,7 +461,7 @@ static void determine_group_output_states(const bNodeTree &tree, for (const bNodeSocket *group_output_socket : group_output_node->input_sockets().drop_back(1)) { OutputFieldDependency field_dependency = find_group_output_dependencies( - *group_output_socket, field_state_by_socket_id); + *group_output_socket, interface_by_node, field_state_by_socket_id); new_inferencing_interface.outputs[group_output_socket->index()] = std::move(field_dependency); } } @@ -486,10 +496,25 @@ static void update_socket_shapes(const bNodeTree &tree, } } +static void prepare_inferencing_interfaces( + const Span nodes, + MutableSpan interface_by_node, + ResourceScope &scope) +{ + for (const int i : nodes.index_range()) { + interface_by_node[i] = &get_node_field_inferencing_interface(*nodes[i], scope); + } +} + bool update_field_inferencing(const bNodeTree &tree) { tree.ensure_topology_cache(); + const Span nodes = tree.all_nodes(); + ResourceScope scope; + Array interface_by_node(nodes.size()); + prepare_inferencing_interfaces(nodes, interface_by_node, scope); + /* Create new inferencing interface for this node group. */ std::unique_ptr new_inferencing_interface = std::make_unique(); @@ -501,10 +526,12 @@ bool update_field_inferencing(const bNodeTree &tree) /* Keep track of the state of all sockets. The index into this array is #SocketRef::id(). */ Array field_state_by_socket_id(tree.all_sockets().size()); - propagate_data_requirements_from_right_to_left(tree, field_state_by_socket_id); + propagate_data_requirements_from_right_to_left( + tree, interface_by_node, field_state_by_socket_id); determine_group_input_states(tree, *new_inferencing_interface, field_state_by_socket_id); - propagate_field_status_from_left_to_right(tree, field_state_by_socket_id); - determine_group_output_states(tree, *new_inferencing_interface, field_state_by_socket_id); + propagate_field_status_from_left_to_right(tree, interface_by_node, field_state_by_socket_id); + determine_group_output_states( + tree, *new_inferencing_interface, interface_by_node, field_state_by_socket_id); update_socket_shapes(tree, field_state_by_socket_id); /* Update the previous group interface. */ From adc92cc23e74ce10cff95f58fd517ed7c23d3779 Mon Sep 17 00:00:00 2001 From: Amelie Fondevilla Date: Tue, 20 Dec 2022 13:14:21 +0100 Subject: [PATCH 0230/1522] Fix T103357: Grease pencil layer color not displayed in main dopesheet backdrop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed By: Sybren A. Stüvel Differential Revision: https://developer.blender.org/D16822 --- source/blender/editors/space_action/action_draw.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c index 343975919e2..de3d306a0be 100644 --- a/source/blender/editors/space_action/action_draw.c +++ b/source/blender/editors/space_action/action_draw.c @@ -272,6 +272,20 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region } break; } + case ANIMTYPE_GPLAYER: { + if (show_group_colors) { + uchar gpl_col[4]; + bGPDlayer *gpl = (bGPDlayer *)ale->data; + rgb_float_to_uchar(gpl_col, gpl->color); + gpl_col[3] = col1[3]; + + immUniformColor4ubv(sel ? col1 : gpl_col); + } + else { + immUniformColor4ubv(sel ? col1 : col2); + } + break; + } default: { immUniformColor4ubv(sel ? col1 : col2); } From 7907803694c50184539b7ed35a6337caa93d2af3 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 20 Dec 2022 10:39:27 -0600 Subject: [PATCH 0231/1522] Tests: Remove random shuffling from modifiers test These are meant to be regression tests, not fuzz tests. The "random" shuffling made debugging quite annoying, even though the random order was the same every time. Instead, hard-code the two lists to make things more obvious. The resulting list doesn't make much sense (for example, the multires modifier has to be first in the stack), but for now avoid changing things further. Also remove some comments that weren't helpful. --- tests/python/modifiers.py | 76 +++++++++++++++------------------------ 1 file changed, 28 insertions(+), 48 deletions(-) diff --git a/tests/python/modifiers.py b/tests/python/modifiers.py index 93448841dfd..f16d91d41f9 100644 --- a/tests/python/modifiers.py +++ b/tests/python/modifiers.py @@ -13,68 +13,48 @@ from modules.mesh_test import RunTest, ModifierSpec, SpecMeshTest seed(0) -def get_generate_modifiers_list(test_object_name, randomize=False): - """ - Construct a list of 'Generate' modifiers with default parameters. - :arg test_object_name: Name of test object. Some modifiers like boolean need an extra parameter beside - the default one. E.g. boolean needs object, mask needs vertex group etc... - The extra parameter name will be _ - :type test_object_name: str - :arg randomize: If True shuffle the list of modifiers. - :type randomize: bool - :return: list of 'Generate' modifiers with default parameters. - """ - - boolean_test_object = bpy.data.objects[test_object_name + "_boolean"] - +def cube_mask_first_modifier_list(): generate_modifiers = [ - ModifierSpec('array', 'ARRAY', {}), - ModifierSpec('bevel', 'BEVEL', {'width': 0.1, 'limit_method': 'NONE'}), - ModifierSpec('boolean', 'BOOLEAN', {'object': boolean_test_object, 'solver': 'FAST'}), - ModifierSpec('build', 'BUILD', {'frame_start': 1, 'frame_duration': 1}, 2), - ModifierSpec('decimate', 'DECIMATE', {}), - ModifierSpec('edge split', 'EDGE_SPLIT', {}), - - # mask can effectively delete the mesh since the vertex group need to be updated after each - # applied modifier. Needs to be tested separately. - # ModifierSpec('mask', 'MASK', {'vertex_group': mask_vertex_group}, False), - - ModifierSpec('mirror', 'MIRROR', {}), - ModifierSpec('multires', 'MULTIRES', {}), - - # remesh can also generate an empty mesh. Skip. - # ModifierSpec('remesh', 'REMESH', {}), - - # ModifierSpec('screw', 'SCREW', {}), # screw can make the test very slow. Skipping for now. - + ModifierSpec('mask', 'MASK', {'vertex_group': "testCubeMaskFirst_mask"}), ModifierSpec('solidify', 'SOLIDIFY', {}), - # Opensubdiv results might differ slightly when compiled with different optimization flags. - #ModifierSpec('subsurf', 'SUBSURF', {}), ModifierSpec('triangulate', 'TRIANGULATE', {}), - ModifierSpec('wireframe', 'WIREFRAME', {}) - + ModifierSpec('bevel', 'BEVEL', {'width': 0.1, 'limit_method': 'NONE'}), + ModifierSpec('boolean', 'BOOLEAN', {'object': bpy.data.objects["testCubeMaskFirst_boolean"], 'solver': 'FAST'}), + ModifierSpec('edge split', 'EDGE_SPLIT', {}), + ModifierSpec('build', 'BUILD', {'frame_start': 1, 'frame_duration': 1}, 2), + ModifierSpec('multires', 'MULTIRES', {}), + ModifierSpec('decimate', 'DECIMATE', {}), + ModifierSpec('array', 'ARRAY', {}), + ModifierSpec('wireframe', 'WIREFRAME', {}), + ModifierSpec('mirror', 'MIRROR', {}), ] - - if randomize: - shuffle(generate_modifiers) - return generate_modifiers +def cube_random_modifier_list(): + generate_modifiers = [ + ModifierSpec('edge split', 'EDGE_SPLIT', {}), + ModifierSpec('decimate', 'DECIMATE', {}), + ModifierSpec('wireframe', 'WIREFRAME', {}), + ModifierSpec('mirror', 'MIRROR', {}), + ModifierSpec('array', 'ARRAY', {}), + ModifierSpec('bevel', 'BEVEL', {'width': 0.1, 'limit_method': 'NONE'}), + ModifierSpec('multires', 'MULTIRES', {}), + ModifierSpec('boolean', 'BOOLEAN', {'object': bpy.data.objects["testCubeRandom_boolean"], 'solver': 'FAST'}), + ModifierSpec('solidify', 'SOLIDIFY', {}), + ModifierSpec('build', 'BUILD', {'frame_start': 1, 'frame_duration': 1}, 2), + ModifierSpec('triangulate', 'TRIANGULATE', {}), + ] + return generate_modifiers def main(): - mask_first_list = get_generate_modifiers_list("testCubeMaskFirst", randomize=True) - mask_vertex_group = "testCubeMaskFirst" + "_mask" - mask_first_list.insert(0, ModifierSpec('mask', 'MASK', {'vertex_group': mask_vertex_group})) tests = [ ############################### # List of 'Generate' modifiers on a cube ############################### # 0 - # SpecMeshTest("testCube", "expectedCube", get_generate_modifiers_list("testCube")), - SpecMeshTest("CubeRandom", "testCubeRandom", "expectedCubeRandom", - get_generate_modifiers_list("testCubeRandom", randomize=True)), - SpecMeshTest("CubeMaskFirst", "testCubeMaskFirst", "expectedCubeMaskFirst", mask_first_list), + SpecMeshTest("CubeRandom", "testCubeRandom", "expectedCubeRandom", cube_random_modifier_list()), + SpecMeshTest("CubeMaskFirst", "testCubeMaskFirst", "expectedCubeMaskFirst", cube_mask_first_modifier_list()), SpecMeshTest("CollapseDecimate", "testCollapseDecimate", "expectedCollapseDecimate", [ModifierSpec('decimate', 'DECIMATE', From 99fcfdd9fb913e03b2e6e4cd0764a88cbca88902 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 20 Dec 2022 12:02:05 -0600 Subject: [PATCH 0232/1522] Tests: Print when mesh test starts, to help debugging crashes --- tests/python/modules/mesh_test.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/python/modules/mesh_test.py b/tests/python/modules/mesh_test.py index b698540c367..1fc685023cb 100644 --- a/tests/python/modules/mesh_test.py +++ b/tests/python/modules/mesh_test.py @@ -238,6 +238,7 @@ class MeshTest(ABC): """ Runs a single test, runs it again if test file is updated. """ + print("\nSTART {} test.".format(self.test_name)) self.create_evaluated_object() self.apply_operations(self.evaluated_object.name) @@ -289,14 +290,14 @@ class MeshTest(ABC): """ Print results for failed test. """ - print("\nFAILED {} test with the following: ".format(self.test_name)) + print("FAILED {} test with the following: ".format(self.test_name)) self._print_result(result) def print_passed_test_result(self, result): """ Print results for passing test. """ - print("\nPASSED {} test successfully.".format(self.test_name)) + print("PASSED {} test successfully.".format(self.test_name)) self._print_result(result) def do_selection(self, mesh: bpy.types.Mesh, select_mode: str, selection, select_history: bool): From cc139344425e91bb4262698c0a94d4171db7ff1a Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Tue, 20 Dec 2022 15:08:18 -0300 Subject: [PATCH 0233/1522] Cleanup: convert 'MOD_mirror.c' to C++ It will be useful to use the merge verts API in C++. Reviewed By: HooglyBoogly Differential Revision: https://developer.blender.org/D16823 --- source/blender/modifiers/CMakeLists.txt | 2 +- .../intern/{MOD_mirror.c => MOD_mirror.cc} | 44 +++++++++---------- 2 files changed, 23 insertions(+), 23 deletions(-) rename source/blender/modifiers/intern/{MOD_mirror.c => MOD_mirror.cc} (89%) diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index 63be9581175..910876fa361 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -62,7 +62,7 @@ set(SRC intern/MOD_meshcache_util.c intern/MOD_meshdeform.c intern/MOD_meshsequencecache.cc - intern/MOD_mirror.c + intern/MOD_mirror.cc intern/MOD_multires.cc intern/MOD_nodes.cc intern/MOD_none.c diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.cc similarity index 89% rename from source/blender/modifiers/intern/MOD_mirror.c rename to source/blender/modifiers/intern/MOD_mirror.cc index f1a36c04453..9e99a6b9a5e 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.cc @@ -60,7 +60,7 @@ static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *u static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { MirrorModifierData *mmd = (MirrorModifierData *)md; - if (mmd->mirror_ob != NULL) { + if (mmd->mirror_ob != nullptr) { DEG_add_object_relation(ctx->node, mmd->mirror_ob, DEG_OB_COMP_TRANSFORM, "Mirror Modifier"); DEG_add_depends_on_transform_relation(ctx->node, "Mirror Modifier"); } @@ -82,7 +82,7 @@ static Mesh *mirrorModifier__doMirror(MirrorModifierData *mmd, Object *ob, Mesh mmd, ob, result, 1, use_correct_order_on_merge); if (tmp != mesh) { /* free intermediate results */ - BKE_id_free(NULL, tmp); + BKE_id_free(nullptr, tmp); } } if (mmd->flag & MOD_MIR_AXIS_Z) { @@ -91,7 +91,7 @@ static Mesh *mirrorModifier__doMirror(MirrorModifierData *mmd, Object *ob, Mesh mmd, ob, result, 2, use_correct_order_on_merge); if (tmp != mesh) { /* free intermediate results */ - BKE_id_free(NULL, tmp); + BKE_id_free(nullptr, tmp); } } @@ -108,7 +108,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * return result; } -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *row, *col, *sub; uiLayout *layout = panel->layout; @@ -141,7 +141,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemS(col); - uiItemR(col, ptr, "mirror_object", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "mirror_object", 0, nullptr, ICON_NONE); uiItemR(col, ptr, "use_clip", 0, IFACE_("Clipping"), ICON_NONE); @@ -161,12 +161,12 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) modifier_panel_end(layout, ptr); } -static void data_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void data_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col, *row, *sub; uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiLayoutSetPropSep(layout, true); @@ -200,7 +200,7 @@ static void data_panel_draw(const bContext *UNUSED(C), Panel *panel) static void panelRegister(ARegionType *region_type) { PanelType *panel_type = modifier_panel_register(region_type, eModifierType_Mirror, panel_draw); - modifier_subpanel_register(region_type, "data", "Data", NULL, data_panel_draw, panel_type); + modifier_subpanel_register(region_type, "data", "Data", nullptr, data_panel_draw, panel_type); } ModifierTypeInfo modifierType_Mirror = { @@ -218,24 +218,24 @@ ModifierTypeInfo modifierType_Mirror = { /* copyData */ BKE_modifier_copydata_generic, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, + /* deformVerts */ nullptr, + /* deformMatrices */ nullptr, + /* deformVertsEM */ nullptr, + /* deformMatricesEM */ nullptr, /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /* modifyGeometrySet */ nullptr, /* initData */ initData, - /* requiredDataMask */ NULL, - /* freeData */ NULL, - /* isDisabled */ NULL, + /* requiredDataMask */ nullptr, + /* freeData */ nullptr, + /* isDisabled */ nullptr, /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, + /* dependsOnTime */ nullptr, + /* dependsOnNormals */ nullptr, /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, + /* foreachTexLink */ nullptr, + /* freeRuntimeData */ nullptr, /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /* blendWrite */ nullptr, + /* blendRead */ nullptr, }; From 6383ed9956cc661cff0ecb16d37e042503b66bfa Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 20 Dec 2022 14:07:14 -0600 Subject: [PATCH 0234/1522] Fix: Assert failure in mirror modifier This was harmless because the function would just return null in release builds, which was checked. Theoretically this vertex group mapping shouldn't depend on the object type, but the vertex group API would have to move away from the object-level first. --- .../blender/blenkernel/intern/mesh_mirror.cc | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_mirror.cc b/source/blender/blenkernel/intern/mesh_mirror.cc index 8830139a697..26a84d4d2b9 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.cc +++ b/source/blender/blenkernel/intern/mesh_mirror.cc @@ -445,27 +445,27 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, } /* handle vgroup stuff */ - if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&result->vdata, CD_MDEFORMVERT)) { - MDeformVert *dvert = BKE_mesh_deform_verts_for_write(result) + maxVerts; - int *flip_map = nullptr, flip_map_len = 0; + if (BKE_object_supports_vertex_groups(ob)) { + if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&result->vdata, CD_MDEFORMVERT)) { + MDeformVert *dvert = BKE_mesh_deform_verts_for_write(result) + maxVerts; + int flip_map_len = 0; + int *flip_map = BKE_object_defgroup_flip_map(ob, false, &flip_map_len); + if (flip_map) { + for (i = 0; i < maxVerts; dvert++, i++) { + /* merged vertices get both groups, others get flipped */ + if (use_correct_order_on_merge && do_vtargetmap && (vtargetmap[i + maxVerts] != -1)) { + BKE_defvert_flip_merged(dvert - maxVerts, flip_map, flip_map_len); + } + else if (!use_correct_order_on_merge && do_vtargetmap && (vtargetmap[i] != -1)) { + BKE_defvert_flip_merged(dvert, flip_map, flip_map_len); + } + else { + BKE_defvert_flip(dvert, flip_map, flip_map_len); + } + } - flip_map = BKE_object_defgroup_flip_map(ob, false, &flip_map_len); - - if (flip_map) { - for (i = 0; i < maxVerts; dvert++, i++) { - /* merged vertices get both groups, others get flipped */ - if (use_correct_order_on_merge && do_vtargetmap && (vtargetmap[i + maxVerts] != -1)) { - BKE_defvert_flip_merged(dvert - maxVerts, flip_map, flip_map_len); - } - else if (!use_correct_order_on_merge && do_vtargetmap && (vtargetmap[i] != -1)) { - BKE_defvert_flip_merged(dvert, flip_map, flip_map_len); - } - else { - BKE_defvert_flip(dvert, flip_map, flip_map_len); - } + MEM_freeN(flip_map); } - - MEM_freeN(flip_map); } } From fb7f12dc40780106fb159786fd3064bf80432a17 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Tue, 20 Dec 2022 15:51:47 -0300 Subject: [PATCH 0235/1522] Cleanup: hide 'UNUSED' macro definition for C++ This may allow the `C4100` warning to be re-enabled in the MSVC for C++. Differential Revision: https://developer.blender.org/D16828 --- source/blender/blenkernel/BKE_ccg.h | 7 ++++- source/blender/blenkernel/intern/cloth.cc | 2 +- .../blenkernel/intern/data_transfer.cc | 6 ++-- source/blender/blenkernel/intern/key.cc | 9 ++---- source/blender/blenkernel/intern/layer.cc | 20 ++++++------- source/blender/blenkernel/intern/linestyle.cc | 8 ++--- source/blender/blenkernel/intern/material.cc | 2 +- source/blender/blenkernel/intern/texture.cc | 2 +- source/blender/blenlib/BLI_utildefines.h | 10 ++++--- .../bmesh/intern/bmesh_mesh_normals.cc | 18 +++++------ .../blender/compositor/intern/COM_MetaData.h | 2 +- .../draw/engines/eevee/eevee_shaders.cc | 6 ++-- .../draw/engines/image/image_space_image.hh | 2 +- .../draw/intern/draw_cache_impl_curves.cc | 4 +-- .../draw/intern/draw_cache_impl_gpencil.cc | 16 +++++----- .../editors/geometry/geometry_attributes.cc | 2 +- .../interface/interface_context_menu.cc | 4 +-- .../editors/interface/interface_icons.cc | 20 ++++++------- .../editors/sculpt_paint/paint_cursor.cc | 4 +-- .../editors/sculpt_paint/paint_image_proj.cc | 8 ++--- .../editors/space_buttons/buttons_texture.cc | 4 +-- .../editors/space_clip/tracking_ops_orient.cc | 6 ++-- .../editors/transform/transform_snap.cc | 18 +++++------ source/blender/gpu/intern/gpu_codegen.cc | 3 +- .../blender/modifiers/intern/MOD_displace.cc | 8 ++--- .../modifiers/intern/MOD_triangulate.cc | 4 +-- .../geometry/nodes/node_geo_blur_attribute.cc | 4 +-- source/blender/nodes/intern/node_util.cc | 30 +++++++++---------- .../nodes/texture/node_texture_tree.cc | 17 +++++------ .../nodes/texture/node_texture_util.cc | 4 +-- .../nodes/texture/nodes/node_texture_at.cc | 4 +-- .../texture/nodes/node_texture_bricks.cc | 4 +-- .../texture/nodes/node_texture_checker.cc | 4 +-- .../nodes/node_texture_combine_color.cc | 4 +-- .../texture/nodes/node_texture_compose.cc | 4 +-- .../nodes/texture/nodes/node_texture_coord.cc | 4 +-- .../texture/nodes/node_texture_curves.cc | 10 +++---- .../texture/nodes/node_texture_decompose.cc | 10 +++---- .../texture/nodes/node_texture_distance.cc | 4 +-- .../texture/nodes/node_texture_hueSatVal.cc | 4 +-- .../nodes/texture/nodes/node_texture_image.cc | 7 ++--- .../texture/nodes/node_texture_invert.cc | 4 +-- .../nodes/texture/nodes/node_texture_math.cc | 2 +- .../texture/nodes/node_texture_mixRgb.cc | 2 +- .../texture/nodes/node_texture_output.cc | 8 ++--- .../nodes/texture/nodes/node_texture_proc.cc | 6 ++-- .../texture/nodes/node_texture_rotate.cc | 4 +-- .../nodes/texture/nodes/node_texture_scale.cc | 4 +-- .../nodes/node_texture_separate_color.cc | 6 ++-- .../texture/nodes/node_texture_texture.cc | 2 +- .../texture/nodes/node_texture_translate.cc | 4 +-- .../texture/nodes/node_texture_valToNor.cc | 4 +-- .../texture/nodes/node_texture_valToRgb.cc | 8 ++--- .../texture/nodes/node_texture_viewer.cc | 8 ++--- source/blender/render/intern/engine.cc | 4 +-- source/blender/render/intern/multires_bake.cc | 12 ++++---- 56 files changed, 189 insertions(+), 198 deletions(-) diff --git a/source/blender/blenkernel/BKE_ccg.h b/source/blender/blenkernel/BKE_ccg.h index 786b84a0469..64b9870a8ea 100644 --- a/source/blender/blenkernel/BKE_ccg.h +++ b/source/blender/blenkernel/BKE_ccg.h @@ -83,7 +83,12 @@ BLI_INLINE CCGElem *CCG_elem_next(const CCGKey *key, CCGElem *elem); /* inline definitions follow */ -BLI_INLINE float *CCG_elem_co(const CCGKey *UNUSED(key), CCGElem *elem) +BLI_INLINE float *CCG_elem_co(const CCGKey * +#ifndef __cplusplus + UNUSED(key) +#endif + , + CCGElem *elem) { return (float *)elem; } diff --git a/source/blender/blenkernel/intern/cloth.cc b/source/blender/blenkernel/intern/cloth.cc index ecd21dcb570..73cf7e1f805 100644 --- a/source/blender/blenkernel/intern/cloth.cc +++ b/source/blender/blenkernel/intern/cloth.cc @@ -713,7 +713,7 @@ static float cloth_shrink_factor(ClothModifierData *clmd, ClothVertex *verts, in } static bool cloth_from_object( - Object *ob, ClothModifierData *clmd, Mesh *mesh, float UNUSED(framenr), int first) + Object *ob, ClothModifierData *clmd, Mesh *mesh, float /*framenr*/, int first) { int i = 0; ClothVertex *verts = nullptr; diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index 382736ae502..2c9ff52e0a4 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -307,9 +307,9 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src, } } -static void data_transfer_dtdata_type_postprocess(Object *UNUSED(ob_src), - Object *UNUSED(ob_dst), - Mesh *UNUSED(me_src), +static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/, + Object * /*ob_dst*/, + Mesh * /*me_src*/, Mesh *me_dst, const int dtdata_type, const bool changed) diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 99010c70e90..388dcff5229 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -51,10 +51,7 @@ #include "BLO_read_write.h" -static void shapekey_copy_data(Main *UNUSED(bmain), - ID *id_dst, - const ID *id_src, - const int UNUSED(flag)) +static void shapekey_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, const int /*flag*/) { Key *key_dst = (Key *)id_dst; const Key *key_src = (const Key *)id_src; @@ -2064,7 +2061,7 @@ int BKE_keyblock_curve_element_count(const ListBase *nurb) return tot; } -void BKE_keyblock_update_from_curve(const Curve *UNUSED(cu), KeyBlock *kb, const ListBase *nurb) +void BKE_keyblock_update_from_curve(const Curve * /*cu*/, KeyBlock *kb, const ListBase *nurb) { Nurb *nu; BezTriple *bezt; @@ -2178,7 +2175,7 @@ static void keyblock_data_convert_to_curve(const float *fp, ListBase *nurb, int } } -void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb) +void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve * /*cu*/, ListBase *nurb) { const float *fp = static_cast(kb->data); const int tot = min_ii(kb->totelem, BKE_keyblock_curve_element_count(nurb)); diff --git a/source/blender/blenkernel/intern/layer.cc b/source/blender/blenkernel/intern/layer.cc index 4dfe507e02e..971cf85812a 100644 --- a/source/blender/blenkernel/intern/layer.cc +++ b/source/blender/blenkernel/intern/layer.cc @@ -489,7 +489,7 @@ static void layer_collections_copy_data(ViewLayer *view_layer_dst, } void BKE_view_layer_copy_data(Scene *scene_dst, - const Scene *UNUSED(scene_src), + const Scene * /*scene_src*/, ViewLayer *view_layer_dst, const ViewLayer *view_layer_src, const int flag) @@ -1257,8 +1257,8 @@ static bool view_layer_objects_base_cache_validate(ViewLayer *view_layer, LayerC return is_valid; } #else -static bool view_layer_objects_base_cache_validate(ViewLayer *UNUSED(view_layer), - LayerCollection *UNUSED(layer)) +static bool view_layer_objects_base_cache_validate(ViewLayer * /*view_layer*/, + LayerCollection * /*layer*/) { return true; } @@ -1650,7 +1650,7 @@ static void layer_collection_flag_unset_recursive(LayerCollection *lc, const int } } -void BKE_layer_collection_isolate_global(Scene *UNUSED(scene), +void BKE_layer_collection_isolate_global(Scene * /*scene*/, ViewLayer *view_layer, LayerCollection *lc, bool extend) @@ -2266,7 +2266,7 @@ void BKE_view_layer_bases_in_mode_iterator_next(BLI_Iterator *iter) iter->valid = false; } -void BKE_view_layer_bases_in_mode_iterator_end(BLI_Iterator *UNUSED(iter)) +void BKE_view_layer_bases_in_mode_iterator_end(BLI_Iterator * /*iter*/) { /* do nothing */ } @@ -2535,12 +2535,12 @@ void BKE_view_layer_set_active_aov(ViewLayer *view_layer, ViewLayerAOV *aov) } static void bke_view_layer_verify_aov_cb(void *userdata, - Scene *UNUSED(scene), - ViewLayer *UNUSED(view_layer), + Scene * /*scene*/, + ViewLayer * /*view_layer*/, const char *name, - int UNUSED(channels), - const char *UNUSED(chanid), - eNodeSocketDatatype UNUSED(type)) + int /*channels*/, + const char * /*chanid*/, + eNodeSocketDatatype /*type*/) { GHash *name_count = static_cast(userdata); void **value_p; diff --git a/source/blender/blenkernel/intern/linestyle.cc b/source/blender/blenkernel/intern/linestyle.cc index 14e4453955c..3040f0f5cd5 100644 --- a/source/blender/blenkernel/intern/linestyle.cc +++ b/source/blender/blenkernel/intern/linestyle.cc @@ -628,8 +628,8 @@ static void direct_link_linestyle_thickness_modifier(BlendDataReader *reader, } } -static void direct_link_linestyle_geometry_modifier(BlendDataReader *UNUSED(reader), - LineStyleModifier *UNUSED(modifier)) +static void direct_link_linestyle_geometry_modifier(BlendDataReader * /*reader*/, + LineStyleModifier * /*modifier*/) { } @@ -1147,7 +1147,7 @@ LineStyleModifier *BKE_linestyle_alpha_modifier_add(FreestyleLineStyle *linestyl LineStyleModifier *BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m, - const int UNUSED(flag)) + const int /*flag*/) { LineStyleModifier *new_m; @@ -1735,7 +1735,7 @@ LineStyleModifier *BKE_linestyle_geometry_modifier_add(FreestyleLineStyle *lines LineStyleModifier *BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m, - const int UNUSED(flag)) + const int /*flag*/) { LineStyleModifier *new_m; diff --git a/source/blender/blenkernel/intern/material.cc b/source/blender/blenkernel/intern/material.cc index 4b0508ddf20..0eb0209cc44 100644 --- a/source/blender/blenkernel/intern/material.cc +++ b/source/blender/blenkernel/intern/material.cc @@ -1411,7 +1411,7 @@ static bool ntree_foreach_texnode_recursive(bNodeTree *nodetree, return true; } -static bool count_texture_nodes_cb(bNode *UNUSED(node), void *userdata) +static bool count_texture_nodes_cb(bNode * /*node*/, void *userdata) { (*((int *)userdata))++; return true; diff --git a/source/blender/blenkernel/intern/texture.cc b/source/blender/blenkernel/intern/texture.cc index 712ede61160..1fb4fdf3d83 100644 --- a/source/blender/blenkernel/intern/texture.cc +++ b/source/blender/blenkernel/intern/texture.cc @@ -626,7 +626,7 @@ PointDensity *BKE_texture_pointdensity_add(void) return pd; } -PointDensity *BKE_texture_pointdensity_copy(const PointDensity *pd, const int UNUSED(flag)) +PointDensity *BKE_texture_pointdensity_copy(const PointDensity *pd, const int /*flag*/) { PointDensity *pdn; diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 98177876f87..5cc91a22944 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -664,11 +664,13 @@ extern bool BLI_memory_is_zero(const void *arr, size_t arr_size); /** \name Unused Function/Argument Macros * \{ */ +#ifndef __cplusplus /* UNUSED macro, for function argument */ -#if defined(__GNUC__) || defined(__clang__) -# define UNUSED(x) UNUSED_##x __attribute__((__unused__)) -#else -# define UNUSED(x) UNUSED_##x +# if defined(__GNUC__) || defined(__clang__) +# define UNUSED(x) UNUSED_##x __attribute__((__unused__)) +# else +# define UNUSED(x) UNUSED_##x +# endif #endif /** diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.cc b/source/blender/bmesh/intern/bmesh_mesh_normals.cc index 91658b1a87b..5d906e0a73f 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_normals.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_normals.cc @@ -139,9 +139,9 @@ static void bm_vert_calc_normals_impl(BMVert *v) normalize_v3_v3(v_no, v->co); } -static void bm_vert_calc_normals_cb(void *UNUSED(userdata), +static void bm_vert_calc_normals_cb(void * /*userdata*/, MempoolIterData *mp_v, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { BMVert *v = (BMVert *)mp_v; bm_vert_calc_normals_impl(v); @@ -192,7 +192,7 @@ static void bm_vert_calc_normals_with_coords(BMVert *v, BMVertsCalcNormalsWithCo static void bm_vert_calc_normals_with_coords_cb(void *userdata, MempoolIterData *mp_v, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { BMVertsCalcNormalsWithCoordsData *data = static_cast( userdata); @@ -224,9 +224,9 @@ static void bm_mesh_verts_calc_normals(BMesh *bm, } } -static void bm_face_calc_normals_cb(void *UNUSED(userdata), +static void bm_face_calc_normals_cb(void * /*userdata*/, MempoolIterData *mp_f, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { BMFace *f = (BMFace *)mp_f; @@ -262,20 +262,20 @@ void BM_mesh_normals_update(BMesh *bm) * \{ */ static void bm_partial_faces_parallel_range_calc_normals_cb( - void *userdata, const int iter, const TaskParallelTLS *__restrict UNUSED(tls)) + void *userdata, const int iter, const TaskParallelTLS *__restrict /*tls*/) { BMFace *f = ((BMFace **)userdata)[iter]; BM_face_calc_normal(f, f->no); } static void bm_partial_verts_parallel_range_calc_normal_cb( - void *userdata, const int iter, const TaskParallelTLS *__restrict UNUSED(tls)) + void *userdata, const int iter, const TaskParallelTLS *__restrict /*tls*/) { BMVert *v = ((BMVert **)userdata)[iter]; bm_vert_calc_normals_impl(v); } -void BM_mesh_normals_update_with_partial_ex(BMesh *UNUSED(bm), +void BM_mesh_normals_update_with_partial_ex(BMesh * /*bm*/, const BMPartialUpdate *bmpinfo, const struct BMeshNormalsUpdate_Params *params) { @@ -1192,7 +1192,7 @@ static void bm_mesh_loops_calc_normals_for_vert_init_fn(const void *__restrict u } static void bm_mesh_loops_calc_normals_for_vert_reduce_fn(const void *__restrict userdata, - void *__restrict UNUSED(chunk_join), + void *__restrict /*chunk_join*/, void *__restrict chunk) { auto *data = static_cast(userdata); diff --git a/source/blender/compositor/intern/COM_MetaData.h b/source/blender/compositor/intern/COM_MetaData.h index de09d9995db..461894e7744 100644 --- a/source/blender/compositor/intern/COM_MetaData.h +++ b/source/blender/compositor/intern/COM_MetaData.h @@ -60,7 +60,7 @@ struct MetaDataExtractCallbackData { static void extract_cryptomatte_meta_data(void *_data, const char *propname, char *propvalue, - int UNUSED(len)); + int /*len*/); }; } // namespace blender::compositor diff --git a/source/blender/draw/engines/eevee/eevee_shaders.cc b/source/blender/draw/engines/eevee/eevee_shaders.cc index d7901a9fac4..3b3ff33308c 100644 --- a/source/blender/draw/engines/eevee/eevee_shaders.cc +++ b/source/blender/draw/engines/eevee/eevee_shaders.cc @@ -1319,9 +1319,7 @@ static char *eevee_get_defines(int options) return str; } -static void eevee_material_post_eval(void *UNUSED(thunk), - GPUMaterial *mat, - GPUCodegenOutput *codegen) +static void eevee_material_post_eval(void * /*thunk*/, GPUMaterial *mat, GPUCodegenOutput *codegen) { /* Fetch material-specific Create-info's and source. */ uint64_t options = GPU_material_uuid_get(mat); @@ -1344,7 +1342,7 @@ static void eevee_material_post_eval(void *UNUSED(thunk), } static struct GPUMaterial *eevee_material_get_ex( - struct Scene *UNUSED(scene), Material *ma, World *wo, int options, bool deferred) + struct Scene * /*scene*/, Material *ma, World *wo, int options, bool deferred) { BLI_assert(ma || wo); const bool is_volume = (options & VAR_MAT_VOLUME) != 0; diff --git a/source/blender/draw/engines/image/image_space_image.hh b/source/blender/draw/engines/image/image_space_image.hh index 0356e1213f6..e2c5d8bdb65 100644 --- a/source/blender/draw/engines/image/image_space_image.hh +++ b/source/blender/draw/engines/image/image_space_image.hh @@ -88,7 +88,7 @@ class SpaceImageAccessor : public AbstractSpaceAccessor { } void init_ss_to_texture_matrix(const ARegion *region, - const float UNUSED(image_resolution[2]), + const float /*image_resolution*/[2], float r_uv_to_texture[4][4]) const override { unit_m4(r_uv_to_texture); diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index 10ca2ef0c26..43ce533f8d1 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -271,7 +271,7 @@ static void curves_batch_cache_fill_segments_proc_pos( static void curves_batch_cache_ensure_procedural_pos(const Curves &curves, CurvesEvalCache &cache, - GPUMaterial *UNUSED(gpu_material)) + GPUMaterial * /*gpu_material*/) { if (cache.proc_point_buf == nullptr || DRW_vbo_requested(cache.proc_point_buf)) { /* Initialize vertex format. */ @@ -391,7 +391,7 @@ static void curves_batch_cache_ensure_procedural_final_attr(CurvesEvalCache &cac const GPUVertFormat *format, const int subdiv, const int index, - const char *UNUSED(name)) + const char * /*name*/) { CurvesEvalFinalCache &final_cache = cache.final[subdiv]; final_cache.attributes_buf[index] = GPU_vertbuf_create_with_format_ex( diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.cc b/source/blender/draw/intern/draw_cache_impl_gpencil.cc index cc4708c8e7e..b7fc315595d 100644 --- a/source/blender/draw/intern/draw_cache_impl_gpencil.cc +++ b/source/blender/draw/intern/draw_cache_impl_gpencil.cc @@ -386,8 +386,8 @@ static void gpencil_buffer_add_fill(GPUIndexBufBuilder *ibo, const bGPDstroke *g } } -static void gpencil_stroke_iter_cb(bGPDlayer *UNUSED(gpl), - bGPDframe *UNUSED(gpf), +static void gpencil_stroke_iter_cb(bGPDlayer * /*gpl*/, + bGPDframe * /*gpf*/, bGPDstroke *gps, void *thunk) { @@ -398,8 +398,8 @@ static void gpencil_stroke_iter_cb(bGPDlayer *UNUSED(gpl), gpencil_buffer_add_stroke(&iter->ibo, iter->verts, iter->cols, gps); } -static void gpencil_object_verts_count_cb(bGPDlayer *UNUSED(gpl), - bGPDframe *UNUSED(gpf), +static void gpencil_object_verts_count_cb(bGPDlayer * /*gpl*/, + bGPDframe * /*gpf*/, bGPDstroke *gps, void *thunk) { @@ -503,8 +503,8 @@ GPUVertBuf *DRW_cache_gpencil_color_buffer_get(Object *ob, int cfra) return cache->vbo_col; } -static void gpencil_lines_indices_cb(bGPDlayer *UNUSED(gpl), - bGPDframe *UNUSED(gpf), +static void gpencil_lines_indices_cb(bGPDlayer * /*gpl*/, + bGPDframe * /*gpf*/, bGPDstroke *gps, void *thunk) { @@ -785,7 +785,7 @@ static void gpencil_edit_stroke_iter_cb(bGPDlayer *gpl, } static void gpencil_edit_curve_stroke_count_cb(bGPDlayer *gpl, - bGPDframe *UNUSED(gpf), + bGPDframe * /*gpf*/, bGPDstroke *gps, void *thunk) { @@ -821,7 +821,7 @@ static uint32_t gpencil_beztriple_vflag_get(char flag, } static void gpencil_edit_curve_stroke_iter_cb(bGPDlayer *gpl, - bGPDframe *UNUSED(gpf), + bGPDframe * /*gpf*/, bGPDstroke *gps, void *thunk) { diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index c4cf34b3b94..1ffc047fe2c 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -646,7 +646,7 @@ static int geometry_color_attribute_convert_invoke(bContext *C, return WM_operator_props_dialog_popup(C, op, 300); } -static void geometry_color_attribute_convert_ui(bContext *UNUSED(C), wmOperator *op) +static void geometry_color_attribute_convert_ui(bContext * /*C*/, wmOperator *op) { uiLayout *layout = op->layout; uiLayoutSetPropSep(layout, true); diff --git a/source/blender/editors/interface/interface_context_menu.cc b/source/blender/editors/interface/interface_context_menu.cc index 4032fb4539f..5c31194fb92 100644 --- a/source/blender/editors/interface/interface_context_menu.cc +++ b/source/blender/editors/interface/interface_context_menu.cc @@ -115,7 +115,7 @@ static void shortcut_free_operator_property(IDProperty *prop) } } -static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event)) +static void but_shortcut_name_func(bContext *C, void *arg1, int /*event*/) { uiBut *but = (uiBut *)arg1; char shortcut_str[128]; @@ -419,7 +419,7 @@ static void popup_user_menu_add_or_replace_func(bContext *C, void *arg1, void * ui_but_user_menu_add(C, but, um); } -static void popup_user_menu_remove_func(bContext *UNUSED(C), void *arg1, void *arg2) +static void popup_user_menu_remove_func(bContext * /*C*/, void *arg1, void *arg2) { bUserMenu *um = static_cast(arg1); bUserMenuItem *umi = static_cast(arg2); diff --git a/source/blender/editors/interface/interface_icons.cc b/source/blender/editors/interface/interface_icons.cc index 8f6b46aa717..de5e72767a5 100644 --- a/source/blender/editors/interface/interface_icons.cc +++ b/source/blender/editors/interface/interface_icons.cc @@ -344,7 +344,7 @@ static void vicon_handletype_auto_clamp_draw(int x, int y, int w, int h, float a vicon_keytype_draw_wrapper(x, y, w, h, alpha, BEZT_KEYTYPE_KEYFRAME, KEYFRAME_HANDLE_AUTO_CLAMP); } -static void vicon_colorset_draw(int index, int x, int y, int w, int h, float UNUSED(alpha)) +static void vicon_colorset_draw(int index, int x, int y, int w, int h, float /*alpha*/) { bTheme *btheme = UI_GetTheme(); const ThemeWireColor *cs = &btheme->tarm[index]; @@ -408,7 +408,7 @@ DEF_ICON_VECTOR_COLORSET_DRAW_NTH(20, 19) # undef DEF_ICON_VECTOR_COLORSET_DRAW_NTH static void vicon_collection_color_draw( - short color_tag, int x, int y, int w, int UNUSED(h), float UNUSED(alpha)) + short color_tag, int x, int y, int w, int /*h*/, float /*alpha*/) { bTheme *btheme = UI_GetTheme(); const ThemeCollectionColor *collection_color = &btheme->collection_color[color_tag]; @@ -444,7 +444,7 @@ DEF_ICON_COLLECTION_COLOR_DRAW(08, COLLECTION_COLOR_08); # undef DEF_ICON_COLLECTION_COLOR_DRAW static void vicon_strip_color_draw( - short color_tag, int x, int y, int w, int UNUSED(h), float UNUSED(alpha)) + short color_tag, int x, int y, int w, int /*h*/, float /*alpha*/) { bTheme *btheme = UI_GetTheme(); const ThemeStripColor *strip_color = &btheme->strip_color[color_tag]; @@ -476,7 +476,7 @@ DEF_ICON_STRIP_COLOR_DRAW(09, SEQUENCE_COLOR_09); # define ICON_INDIRECT_DATA_ALPHA 0.6f static void vicon_strip_color_draw_library_data_indirect( - int x, int y, int w, int UNUSED(h), float alpha) + int x, int y, int w, int /*h*/, float alpha) { const float aspect = float(ICON_DEFAULT_WIDTH) / float(w); @@ -492,7 +492,7 @@ static void vicon_strip_color_draw_library_data_indirect( } static void vicon_strip_color_draw_library_data_override_noneditable( - int x, int y, int w, int UNUSED(h), float alpha) + int x, int y, int w, int /*h*/, float alpha) { const float aspect = float(ICON_DEFAULT_WIDTH) / float(w); @@ -1310,9 +1310,9 @@ static void ui_id_preview_image_render_size( const bContext *C, Scene *scene, ID *id, PreviewImage *pi, int size, const bool use_job); static void ui_studiolight_icon_job_exec(void *customdata, - bool *UNUSED(stop), - bool *UNUSED(do_update), - float *UNUSED(progress)) + bool * /*stop*/, + bool * /*do_update*/, + float * /*progress*/) { Icon **tmp = (Icon **)customdata; Icon *icon = *tmp; @@ -1520,7 +1520,7 @@ static void icon_draw_rect(float x, float y, int w, int h, - float UNUSED(aspect), + float /*aspect*/, int rw, int rh, uint *rect, @@ -1689,7 +1689,7 @@ static void icon_draw_texture_cached(float x, float h, int ix, int iy, - int UNUSED(iw), + int /*iw*/, int ih, float alpha, const float rgb[3], diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index deb1fff946b..d3cea0e5573 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -363,7 +363,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima static void load_tex_cursor_task_cb(void *__restrict userdata, const int j, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { LoadTexData *data = static_cast(userdata); Brush *br = data->br; @@ -1900,7 +1900,7 @@ static void paint_cursor_restore_drawing_state(void) GPU_line_smooth(false); } -static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) +static void paint_draw_cursor(bContext *C, int x, int y, void * /*unused*/) { PaintCursorContext pcontext; if (!paint_cursor_context_init(C, x, y, &pcontext)) { diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.cc b/source/blender/editors/sculpt_paint/paint_image_proj.cc index 7c7ebbbb9fc..1a60424869d 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.cc +++ b/source/blender/editors/sculpt_paint/paint_image_proj.cc @@ -5169,7 +5169,7 @@ static void copy_original_alpha_channel(ProjPixel *pixel, bool is_floatbuf) } /* Run this for single and multi-threaded painting. */ -static void do_projectpaint_thread(TaskPool *__restrict UNUSED(pool), void *ph_v) +static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v) { /* First unpack args from the struct */ ProjPaintState *ps = ((ProjectHandle *)ph_v)->ps; @@ -5733,7 +5733,7 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po return touch_any; } -static void paint_proj_stroke_ps(const bContext *UNUSED(C), +static void paint_proj_stroke_ps(const bContext * /*C*/, void *ps_handle_p, const float prev_pos[2], const float pos[2], @@ -6805,7 +6805,7 @@ static void get_default_texture_layer_name_for_object(Object *ob, static int texture_paint_add_texture_paint_slot_invoke(bContext *C, wmOperator *op, - const wmEvent *UNUSED(event)) + const wmEvent * /*event*/) { Object *ob = ED_object_active_context(C); Material *ma = BKE_object_material_get(ob, ob->actcol); @@ -6958,7 +6958,7 @@ void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot) "Type of data stored in attribute"); } -static int add_simple_uvs_exec(bContext *C, wmOperator *UNUSED(op)) +static int add_simple_uvs_exec(bContext *C, wmOperator * /*op*/) { /* no checks here, poll function does them for us */ Main *bmain = CTX_data_main(C); diff --git a/source/blender/editors/space_buttons/buttons_texture.cc b/source/blender/editors/space_buttons/buttons_texture.cc index 0557b5e9ca2..e10371d6f80 100644 --- a/source/blender/editors/space_buttons/buttons_texture.cc +++ b/source/blender/editors/space_buttons/buttons_texture.cc @@ -422,7 +422,7 @@ void buttons_texture_context_compute(const bContext *C, SpaceProperties *sbuts) } } -static void template_texture_select(bContext *C, void *user_p, void *UNUSED(arg)) +static void template_texture_select(bContext *C, void *user_p, void * /*arg*/) { /* callback when selecting a texture user in the menu */ SpaceProperties *sbuts = find_space_properties(C); @@ -475,7 +475,7 @@ static void template_texture_select(bContext *C, void *user_p, void *UNUSED(arg) ct->index = user->index; } -static void template_texture_user_menu(bContext *C, uiLayout *layout, void *UNUSED(arg)) +static void template_texture_user_menu(bContext *C, uiLayout *layout, void * /*arg*/) { /* callback when opening texture user selection menu, to create buttons. */ SpaceProperties *sbuts = CTX_wm_space_properties(C); diff --git a/source/blender/editors/space_clip/tracking_ops_orient.cc b/source/blender/editors/space_clip/tracking_ops_orient.cc index 2a59a08ea2f..25c380b20cf 100644 --- a/source/blender/editors/space_clip/tracking_ops_orient.cc +++ b/source/blender/editors/space_clip/tracking_ops_orient.cc @@ -679,7 +679,7 @@ static int set_scale_exec(bContext *C, wmOperator *op) return do_set_scale(C, op, false, false); } -static int set_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int set_scale_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); @@ -739,7 +739,7 @@ static int set_solution_scale_exec(bContext *C, wmOperator *op) return do_set_scale(C, op, true, false); } -static int set_solution_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int set_solution_scale_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); @@ -801,7 +801,7 @@ static int apply_solution_scale_exec(bContext *C, wmOperator *op) return do_set_scale(C, op, false, true); } -static int apply_solution_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int apply_solution_scale_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); diff --git a/source/blender/editors/transform/transform_snap.cc b/source/blender/editors/transform/transform_snap.cc index 0157f478b57..bf7848b6972 100644 --- a/source/blender/editors/transform/transform_snap.cc +++ b/source/blender/editors/transform/transform_snap.cc @@ -582,7 +582,7 @@ bool validSnappingNormal(const TransInfo *t) return false; } -static bool bm_edge_is_snap_target(BMEdge *e, void *UNUSED(user_data)) +static bool bm_edge_is_snap_target(BMEdge *e, void * /*user_data*/) { if (BM_elem_flag_test(e, BM_ELEM_SELECT | BM_ELEM_HIDDEN) || BM_elem_flag_test(e->v1, BM_ELEM_SELECT) || BM_elem_flag_test(e->v2, BM_ELEM_SELECT)) { @@ -592,7 +592,7 @@ static bool bm_edge_is_snap_target(BMEdge *e, void *UNUSED(user_data)) return true; } -static bool bm_face_is_snap_target(BMFace *f, void *UNUSED(user_data)) +static bool bm_face_is_snap_target(BMFace *f, void * /*user_data*/) { if (BM_elem_flag_test(f, BM_ELEM_SELECT | BM_ELEM_HIDDEN)) { return false; @@ -1043,7 +1043,7 @@ void getSnapPoint(const TransInfo *t, float vec[3]) /** \name Calc Snap * \{ */ -static void snap_calc_view3d_fn(TransInfo *t, float *UNUSED(vec)) +static void snap_calc_view3d_fn(TransInfo *t, float * /*vec*/) { BLI_assert(t->spacetype == SPACE_VIEW3D); float loc[3]; @@ -1083,7 +1083,7 @@ static void snap_calc_view3d_fn(TransInfo *t, float *UNUSED(vec)) t->tsnap.snapElem = snap_elem; } -static void snap_calc_uv_fn(TransInfo *t, float *UNUSED(vec)) +static void snap_calc_uv_fn(TransInfo *t, float * /*vec*/) { BLI_assert(t->spacetype == SPACE_IMAGE); if (t->tsnap.mode & SCE_SNAP_MODE_VERTEX) { @@ -1112,7 +1112,7 @@ static void snap_calc_uv_fn(TransInfo *t, float *UNUSED(vec)) } } -static void snap_calc_node_fn(TransInfo *t, float *UNUSED(vec)) +static void snap_calc_node_fn(TransInfo *t, float * /*vec*/) { BLI_assert(t->spacetype == SPACE_NODE); if (t->tsnap.mode & (SCE_SNAP_MODE_NODE_X | SCE_SNAP_MODE_NODE_Y)) { @@ -1132,7 +1132,7 @@ static void snap_calc_node_fn(TransInfo *t, float *UNUSED(vec)) } } -static void snap_calc_sequencer_fn(TransInfo *t, float *UNUSED(vec)) +static void snap_calc_sequencer_fn(TransInfo *t, float * /*vec*/) { BLI_assert(t->spacetype == SPACE_SEQ); if (transform_snap_sequencer_calc(t)) { @@ -1477,7 +1477,7 @@ static NodeBorder snapNodeBorder(eSnapMode snap_node_mode) } static bool snapNode(ToolSettings *ts, - SpaceNode *UNUSED(snode), + SpaceNode * /*snode*/, ARegion *region, bNode *node, const int mval[2], @@ -1579,7 +1579,7 @@ bool snapNodesTransform( /** \name snap Grid * \{ */ -static void snap_increment_apply_ex(const TransInfo *UNUSED(t), +static void snap_increment_apply_ex(const TransInfo * /*t*/, const int max_index, const float increment_val, const float aspect[3], @@ -1678,7 +1678,7 @@ float transform_snap_increment_get(const TransInfo *t) /** \name Generic callbacks * \{ */ -float transform_snap_distance_len_squared_fn(TransInfo *UNUSED(t), +float transform_snap_distance_len_squared_fn(TransInfo * /*t*/, const float p1[3], const float p2[3]) { diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index 465a621e864..c4c0e403af1 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -211,8 +211,7 @@ static std::ostream &operator<<(std::ostream &stream, const GPUOutput *output) } /* Trick type to change overload and keep a somewhat nice syntax. */ -struct GPUConstant : public GPUInput { -}; +struct GPUConstant : public GPUInput {}; /* Print data constructor (i.e: vec2(1.0f, 1.0f)). */ static std::ostream &operator<<(std::ostream &stream, const GPUConstant *input) diff --git a/source/blender/modifiers/intern/MOD_displace.cc b/source/blender/modifiers/intern/MOD_displace.cc index 527bbeae0e5..7f4b308017b 100644 --- a/source/blender/modifiers/intern/MOD_displace.cc +++ b/source/blender/modifiers/intern/MOD_displace.cc @@ -78,7 +78,7 @@ static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_ma } } -static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *md) +static bool dependsOnTime(struct Scene * /*scene*/, ModifierData *md) { DisplaceModifierData *dmd = (DisplaceModifierData *)md; @@ -108,9 +108,7 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void walk(userData, ob, md, "texture"); } -static bool isDisabled(const struct Scene *UNUSED(scene), - ModifierData *md, - bool UNUSED(useRenderParams)) +static bool isDisabled(const struct Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/) { DisplaceModifierData *dmd = (DisplaceModifierData *)md; return ((!dmd->texture && dmd->direction == MOD_DISP_DIR_RGB_XYZ) || dmd->strength == 0.0f); @@ -164,7 +162,7 @@ typedef struct DisplaceUserdata { static void displaceModifier_do_task(void *__restrict userdata, const int iter, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { DisplaceUserdata *data = (DisplaceUserdata *)userdata; DisplaceModifierData *dmd = data->dmd; diff --git a/source/blender/modifiers/intern/MOD_triangulate.cc b/source/blender/modifiers/intern/MOD_triangulate.cc index c8543473a9a..993ce852129 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.cc +++ b/source/blender/modifiers/intern/MOD_triangulate.cc @@ -107,7 +107,7 @@ static void initData(ModifierData *md) md->mode |= eModifierMode_Editmode; } -static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext * /*ctx*/, Mesh *mesh) { TriangulateModifierData *tmd = (TriangulateModifierData *)md; Mesh *result; @@ -119,7 +119,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) return result; } -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc index ca373cdf4d9..23c39748cf9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc @@ -64,12 +64,12 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output(N_("Value"), "Value_Color").field_source().dependent_field(); } -static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) { uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE); } -static void node_init(bNodeTree *UNUSED(tree), bNode *node) +static void node_init(bNodeTree * /*tree*/, bNode *node) { node->custom1 = CD_PROP_FLOAT; } diff --git a/source/blender/nodes/intern/node_util.cc b/source/blender/nodes/intern/node_util.cc index 076e48166ae..e3c261d3cc4 100644 --- a/source/blender/nodes/intern/node_util.cc +++ b/source/blender/nodes/intern/node_util.cc @@ -48,21 +48,19 @@ void node_free_standard_storage(bNode *node) } } -void node_copy_curves(bNodeTree *UNUSED(dest_ntree), bNode *dest_node, const bNode *src_node) +void node_copy_curves(bNodeTree * /*dest_ntree*/, bNode *dest_node, const bNode *src_node) { dest_node->storage = BKE_curvemapping_copy(static_cast(src_node->storage)); } -void node_copy_standard_storage(bNodeTree *UNUSED(dest_ntree), +void node_copy_standard_storage(bNodeTree * /*dest_ntree*/, bNode *dest_node, const bNode *src_node) { dest_node->storage = MEM_dupallocN(src_node->storage); } -void *node_initexec_curves(bNodeExecContext *UNUSED(context), - bNode *node, - bNodeInstanceKey UNUSED(key)) +void *node_initexec_curves(bNodeExecContext * /*context*/, bNode *node, bNodeInstanceKey /*key*/) { BKE_curvemapping_init(static_cast(node->storage)); return nullptr; /* unused return */ @@ -177,7 +175,7 @@ void node_math_update(bNodeTree *ntree, bNode *node) /** \name Labels * \{ */ -void node_blend_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen) +void node_blend_label(const bNodeTree * /*ntree*/, const bNode *node, char *label, int maxlen) { const char *name; bool enum_label = RNA_enum_name(rna_enum_ramp_blend_items, node->custom1, &name); @@ -187,14 +185,14 @@ void node_blend_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *l BLI_strncpy(label, IFACE_(name), maxlen); } -void node_image_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen) +void node_image_label(const bNodeTree * /*ntree*/, const bNode *node, char *label, int maxlen) { /* If there is no loaded image, return an empty string, * and let nodeLabel() fill in the proper type translation. */ BLI_strncpy(label, (node->id) ? node->id->name + 2 : "", maxlen); } -void node_math_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen) +void node_math_label(const bNodeTree * /*ntree*/, const bNode *node, char *label, int maxlen) { const char *name; bool enum_label = RNA_enum_name(rna_enum_node_math_items, node->custom1, &name); @@ -204,7 +202,7 @@ void node_math_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *la BLI_strncpy(label, CTX_IFACE_(BLT_I18NCONTEXT_ID_NODETREE, name), maxlen); } -void node_vector_math_label(const bNodeTree *UNUSED(ntree), +void node_vector_math_label(const bNodeTree * /*ntree*/, const bNode *node, char *label, int maxlen) @@ -217,7 +215,7 @@ void node_vector_math_label(const bNodeTree *UNUSED(ntree), BLI_strncpy(label, IFACE_(name), maxlen); } -void node_filter_label(const bNodeTree *UNUSED(ntree), const bNode *node, char *label, int maxlen) +void node_filter_label(const bNodeTree * /*ntree*/, const bNode *node, char *label, int maxlen) { const char *name; bool enum_label = RNA_enum_name(rna_enum_node_filter_items, node->custom1, &name); @@ -365,21 +363,21 @@ void node_insert_link_default(bNodeTree *ntree, bNode *node, bNodeLink *link) /** \name Default value RNA access * \{ */ -float node_socket_get_float(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock) +float node_socket_get_float(bNodeTree *ntree, bNode * /*node*/, bNodeSocket *sock) { PointerRNA ptr; RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); return RNA_float_get(&ptr, "default_value"); } -void node_socket_set_float(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, float value) +void node_socket_set_float(bNodeTree *ntree, bNode * /*node*/, bNodeSocket *sock, float value) { PointerRNA ptr; RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); RNA_float_set(&ptr, "default_value", value); } -void node_socket_get_color(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, float *value) +void node_socket_get_color(bNodeTree *ntree, bNode * /*node*/, bNodeSocket *sock, float *value) { PointerRNA ptr; RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); @@ -387,7 +385,7 @@ void node_socket_get_color(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *s } void node_socket_set_color(bNodeTree *ntree, - bNode *UNUSED(node), + bNode * /*node*/, bNodeSocket *sock, const float *value) { @@ -396,7 +394,7 @@ void node_socket_set_color(bNodeTree *ntree, RNA_float_set_array(&ptr, "default_value", value); } -void node_socket_get_vector(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, float *value) +void node_socket_get_vector(bNodeTree *ntree, bNode * /*node*/, bNodeSocket *sock, float *value) { PointerRNA ptr; RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &ptr); @@ -404,7 +402,7 @@ void node_socket_get_vector(bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket * } void node_socket_set_vector(bNodeTree *ntree, - bNode *UNUSED(node), + bNode * /*node*/, bNodeSocket *sock, const float *value) { diff --git a/source/blender/nodes/texture/node_texture_tree.cc b/source/blender/nodes/texture/node_texture_tree.cc index 31af0e92131..3b26fe9dc14 100644 --- a/source/blender/nodes/texture/node_texture_tree.cc +++ b/source/blender/nodes/texture/node_texture_tree.cc @@ -38,11 +38,8 @@ #include "UI_resources.h" -static void texture_get_from_context(const bContext *C, - bNodeTreeType *UNUSED(treetype), - bNodeTree **r_ntree, - ID **r_id, - ID **r_from) +static void texture_get_from_context( + const bContext *C, bNodeTreeType * /*treetype*/, bNodeTree **r_ntree, ID **r_id, ID **r_from) { SpaceNode *snode = CTX_wm_space_node(C); Scene *scene = CTX_data_scene(C); @@ -83,7 +80,7 @@ static void texture_get_from_context(const bContext *C, } } -static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCallback func) +static void foreach_nodeclass(Scene * /*scene*/, void *calldata, bNodeClassCallback func) { func(calldata, NODE_CLASS_INPUT, N_("Input")); func(calldata, NODE_CLASS_OUTPUT, N_("Output")); @@ -101,7 +98,7 @@ static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCa * it works here, but disabled for consistency */ #if 1 -static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree)) +static void localize(bNodeTree *localtree, bNodeTree * /*ntree*/) { bNode *node, *node_next; @@ -116,7 +113,7 @@ static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree)) } } #else -static void localize(bNodeTree *UNUSED(localtree), bNodeTree *UNUSED(ntree)) +static void localize(bNodeTree * /*localtree*/, bNodeTree * /*ntree*/) { } #endif @@ -126,7 +123,7 @@ static void update(bNodeTree *ntree) ntree_update_reroute_nodes(ntree); } -static bool texture_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype), +static bool texture_node_tree_socket_type_valid(bNodeTreeType * /*ntreetype*/, bNodeSocketType *socket_type) { return nodeIsStaticSocketType(socket_type) && @@ -322,7 +319,7 @@ int ntreeTexExecTree(bNodeTree *ntree, float dyt[3], int osatex, const short thread, - const Tex *UNUSED(tex), + const Tex * /*tex*/, short which_output, int cfra, int preview, diff --git a/source/blender/nodes/texture/node_texture_util.cc b/source/blender/nodes/texture/node_texture_util.cc index 78037c24583..1174c4f4ce9 100644 --- a/source/blender/nodes/texture/node_texture_util.cc +++ b/source/blender/nodes/texture/node_texture_util.cc @@ -23,9 +23,7 @@ #include "node_texture_util.hh" -bool tex_node_poll_default(bNodeType *UNUSED(ntype), - bNodeTree *ntree, - const char **r_disabled_hint) +bool tex_node_poll_default(bNodeType * /*ntype*/, bNodeTree *ntree, const char **r_disabled_hint) { if (!STREQ(ntree->idname, "TextureNodeTree")) { *r_disabled_hint = TIP_("Not a texture node tree"); diff --git a/source/blender/nodes/texture/nodes/node_texture_at.cc b/source/blender/nodes/texture/nodes/node_texture_at.cc index 65e6a2eb5d7..0b486e365b6 100644 --- a/source/blender/nodes/texture/nodes/node_texture_at.cc +++ b/source/blender/nodes/texture/nodes/node_texture_at.cc @@ -18,7 +18,7 @@ static bNodeSocketTemplate outputs[] = { {-1, ""}, }; -static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void colorfn(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { TexParams np = *p; float new_co[3]; @@ -29,7 +29,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack ** } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_bricks.cc b/source/blender/nodes/texture/nodes/node_texture_bricks.cc index 4852461ac01..40b5e48569b 100644 --- a/source/blender/nodes/texture/nodes/node_texture_bricks.cc +++ b/source/blender/nodes/texture/nodes/node_texture_bricks.cc @@ -25,7 +25,7 @@ static bNodeSocketTemplate outputs[] = { {-1, ""}, }; -static void init(bNodeTree *UNUSED(ntree), bNode *node) +static void init(bNodeTree * /*ntree*/, bNode *node) { node->custom3 = 0.5; /* offset */ node->custom4 = 1.0; /* squash */ @@ -90,7 +90,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_checker.cc b/source/blender/nodes/texture/nodes/node_texture_checker.cc index c920ec77725..96d48b94275 100644 --- a/source/blender/nodes/texture/nodes/node_texture_checker.cc +++ b/source/blender/nodes/texture/nodes/node_texture_checker.cc @@ -20,7 +20,7 @@ static bNodeSocketTemplate outputs[] = { {-1, ""}, }; -static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void colorfn(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { float x = p->co[0]; float y = p->co[1]; @@ -41,7 +41,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack ** } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_combine_color.cc b/source/blender/nodes/texture/nodes/node_texture_combine_color.cc index 7b3510766c8..d63cb2172b8 100644 --- a/source/blender/nodes/texture/nodes/node_texture_combine_color.cc +++ b/source/blender/nodes/texture/nodes/node_texture_combine_color.cc @@ -48,13 +48,13 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } } -static void update(bNodeTree *UNUSED(ntree), bNode *node) +static void update(bNodeTree * /*ntree*/, bNode *node) { node_combsep_color_label(&node->inputs, (NodeCombSepColorMode)node->custom1); } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_compose.cc b/source/blender/nodes/texture/nodes/node_texture_compose.cc index b63e7536ea2..7ec1742a4f1 100644 --- a/source/blender/nodes/texture/nodes/node_texture_compose.cc +++ b/source/blender/nodes/texture/nodes/node_texture_compose.cc @@ -20,7 +20,7 @@ static bNodeSocketTemplate outputs[] = { {-1, ""}, }; -static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void colorfn(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { int i; for (i = 0; i < 4; i++) { @@ -29,7 +29,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack ** } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_coord.cc b/source/blender/nodes/texture/nodes/node_texture_coord.cc index 4db157126fa..b8b9b0a369d 100644 --- a/source/blender/nodes/texture/nodes/node_texture_coord.cc +++ b/source/blender/nodes/texture/nodes/node_texture_coord.cc @@ -14,13 +14,13 @@ static bNodeSocketTemplate outputs[] = { }; static void vectorfn( - float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **UNUSED(in), short UNUSED(thread)) + float *out, TexParams *p, bNode * /*node*/, bNodeStack ** /*in*/, short /*thread*/) { copy_v3_v3(out, p->co); } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_curves.cc b/source/blender/nodes/texture/nodes/node_texture_curves.cc index c2cdaf7eab7..3d93ae8b418 100644 --- a/source/blender/nodes/texture/nodes/node_texture_curves.cc +++ b/source/blender/nodes/texture/nodes/node_texture_curves.cc @@ -14,7 +14,7 @@ static bNodeSocketTemplate time_outputs[] = {{SOCK_FLOAT, N_("Value")}, {-1, ""}}; static void time_colorfn( - float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(in), short UNUSED(thread)) + float *out, TexParams *p, bNode *node, bNodeStack ** /*in*/, short /*thread*/) { /* stack order output: fac */ float fac = 0.0f; @@ -30,7 +30,7 @@ static void time_colorfn( } static void time_exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, @@ -39,7 +39,7 @@ static void time_exec(void *data, tex_output(node, execdata, in, out[0], &time_colorfn, static_cast(data)); } -static void time_init(bNodeTree *UNUSED(ntree), bNode *node) +static void time_init(bNodeTree * /*ntree*/, bNode *node) { node->custom1 = 1; node->custom2 = 250; @@ -82,7 +82,7 @@ static void rgb_colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, } static void rgb_exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, @@ -91,7 +91,7 @@ static void rgb_exec(void *data, tex_output(node, execdata, in, out[0], &rgb_colorfn, static_cast(data)); } -static void rgb_init(bNodeTree *UNUSED(ntree), bNode *node) +static void rgb_init(bNodeTree * /*ntree*/, bNode *node) { node->storage = BKE_curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); } diff --git a/source/blender/nodes/texture/nodes/node_texture_decompose.cc b/source/blender/nodes/texture/nodes/node_texture_decompose.cc index 918649cad31..b10e7022396 100644 --- a/source/blender/nodes/texture/nodes/node_texture_decompose.cc +++ b/source/blender/nodes/texture/nodes/node_texture_decompose.cc @@ -21,32 +21,32 @@ static bNodeSocketTemplate outputs[] = { {-1, ""}, }; -static void valuefn_r(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void valuefn_r(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { tex_input_rgba(out, in[0], p, thread); *out = out[0]; } -static void valuefn_g(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void valuefn_g(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { tex_input_rgba(out, in[0], p, thread); *out = out[1]; } -static void valuefn_b(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void valuefn_b(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { tex_input_rgba(out, in[0], p, thread); *out = out[2]; } -static void valuefn_a(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void valuefn_a(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { tex_input_rgba(out, in[0], p, thread); *out = out[3]; } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_distance.cc b/source/blender/nodes/texture/nodes/node_texture_distance.cc index f7f377defa7..c99ea6bb83f 100644 --- a/source/blender/nodes/texture/nodes/node_texture_distance.cc +++ b/source/blender/nodes/texture/nodes/node_texture_distance.cc @@ -20,7 +20,7 @@ static bNodeSocketTemplate outputs[] = { {-1, ""}, }; -static void valuefn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void valuefn(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { float co1[3], co2[3]; @@ -31,7 +31,7 @@ static void valuefn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack ** } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_hueSatVal.cc b/source/blender/nodes/texture/nodes/node_texture_hueSatVal.cc index 1500959d7b8..9a27ac5f19d 100644 --- a/source/blender/nodes/texture/nodes/node_texture_hueSatVal.cc +++ b/source/blender/nodes/texture/nodes/node_texture_hueSatVal.cc @@ -22,7 +22,7 @@ static bNodeSocketTemplate outputs[] = { }; static void do_hue_sat_fac( - bNode *UNUSED(node), float *out, float hue, float sat, float val, float *in, float fac) + bNode * /*node*/, float *out, float hue, float sat, float val, float *in, float fac) { if (fac != 0 && (hue != 0.5f || sat != 1 || val != 1)) { float col[3], hsv[3], mfac = 1.0f - fac; @@ -78,7 +78,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_image.cc b/source/blender/nodes/texture/nodes/node_texture_image.cc index 6575369f541..c1b238b6a00 100644 --- a/source/blender/nodes/texture/nodes/node_texture_image.cc +++ b/source/blender/nodes/texture/nodes/node_texture_image.cc @@ -13,8 +13,7 @@ static bNodeSocketTemplate outputs[] = { {-1, ""}, }; -static void colorfn( - float *out, TexParams *p, bNode *node, bNodeStack **UNUSED(in), short UNUSED(thread)) +static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack ** /*in*/, short /*thread*/) { float x = p->co[0]; float y = p->co[1]; @@ -71,7 +70,7 @@ static void colorfn( } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, @@ -80,7 +79,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[0], &colorfn, static_cast(data)); } -static void init(bNodeTree *UNUSED(ntree), bNode *node) +static void init(bNodeTree * /*ntree*/, bNode *node) { ImageUser *iuser = MEM_cnew("node image user"); node->storage = iuser; diff --git a/source/blender/nodes/texture/nodes/node_texture_invert.cc b/source/blender/nodes/texture/nodes/node_texture_invert.cc index c28b071be82..fb54edfdbcc 100644 --- a/source/blender/nodes/texture/nodes/node_texture_invert.cc +++ b/source/blender/nodes/texture/nodes/node_texture_invert.cc @@ -19,7 +19,7 @@ static bNodeSocketTemplate outputs[] = { {-1, ""}, }; -static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void colorfn(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { float col[4]; @@ -34,7 +34,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack ** } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_math.cc b/source/blender/nodes/texture/nodes/node_texture_math.cc index 97fa9ac7793..484cc2c3afc 100644 --- a/source/blender/nodes/texture/nodes/node_texture_math.cc +++ b/source/blender/nodes/texture/nodes/node_texture_math.cc @@ -306,7 +306,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_mixRgb.cc b/source/blender/nodes/texture/nodes/node_texture_mixRgb.cc index 539dcc4ebb4..0bc74238344 100644 --- a/source/blender/nodes/texture/nodes/node_texture_mixRgb.cc +++ b/source/blender/nodes/texture/nodes/node_texture_mixRgb.cc @@ -40,7 +40,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_output.cc b/source/blender/nodes/texture/nodes/node_texture_output.cc index b6ea187358d..b17365c4d97 100644 --- a/source/blender/nodes/texture/nodes/node_texture_output.cc +++ b/source/blender/nodes/texture/nodes/node_texture_output.cc @@ -18,11 +18,11 @@ static bNodeSocketTemplate inputs[] = { /* applies to render pipeline */ static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, - bNodeExecData *UNUSED(execdata), + bNodeExecData * /*execdata*/, bNodeStack **in, - bNodeStack **UNUSED(out)) + bNodeStack ** /*out*/) { TexCallData *cdata = (TexCallData *)data; TexResult *target = cdata->target; @@ -114,7 +114,7 @@ check_index: node->custom1 = index; } -static void init(bNodeTree *UNUSED(ntree), bNode *node) +static void init(bNodeTree * /*ntree*/, bNode *node) { TexNodeOutput *tno = MEM_cnew("TEX_output"); node->storage = tno; diff --git a/source/blender/nodes/texture/nodes/node_texture_proc.cc b/source/blender/nodes/texture/nodes/node_texture_proc.cc index 297affd671c..c5f3c9369fe 100644 --- a/source/blender/nodes/texture/nodes/node_texture_proc.cc +++ b/source/blender/nodes/texture/nodes/node_texture_proc.cc @@ -79,7 +79,7 @@ static int count_outputs(bNode *node) #define ProcNoInputs(name) \ static void name##_map_inputs( \ - Tex *UNUSED(tex), bNodeStack **UNUSED(in), TexParams *UNUSED(p), short UNUSED(thread)) \ + Tex * /*tex*/, bNodeStack ** /*in*/, TexParams * /*p*/, short /*thread*/) \ { \ } @@ -90,7 +90,7 @@ static int count_outputs(bNode *node) texfn(result, p, node, in, &name##_map_inputs, thread); \ } \ static void name##_exec(void *data, \ - int UNUSED(thread), \ + int /*thread*/, \ bNode *node, \ bNodeExecData *execdata, \ bNodeStack **in, \ @@ -232,7 +232,7 @@ ProcDef(stucci); /* --- */ -static void init(bNodeTree *UNUSED(ntree), bNode *node) +static void init(bNodeTree * /*ntree*/, bNode *node) { Tex *tex = static_cast(MEM_callocN(sizeof(Tex), "Tex")); node->storage = tex; diff --git a/source/blender/nodes/texture/nodes/node_texture_rotate.cc b/source/blender/nodes/texture/nodes/node_texture_rotate.cc index 2b61150cbde..b711d5445fe 100644 --- a/source/blender/nodes/texture/nodes/node_texture_rotate.cc +++ b/source/blender/nodes/texture/nodes/node_texture_rotate.cc @@ -44,7 +44,7 @@ static void rotate(float new_co[3], float a, const float ax[3], const float co[3 new_co[2] = para[2] + perp[2] + cp[2]; } -static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void colorfn(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { float new_co[3], new_dxt[3], new_dyt[3], a, ax[3]; @@ -66,7 +66,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack ** } } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_scale.cc b/source/blender/nodes/texture/nodes/node_texture_scale.cc index ee7f810bf52..5cf986d855e 100644 --- a/source/blender/nodes/texture/nodes/node_texture_scale.cc +++ b/source/blender/nodes/texture/nodes/node_texture_scale.cc @@ -19,7 +19,7 @@ static bNodeSocketTemplate outputs[] = { {-1, ""}, }; -static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void colorfn(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { float scale[3], new_co[3], new_dxt[3], new_dyt[3]; TexParams np = *p; @@ -39,7 +39,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack ** tex_input_rgba(out, in[0], &np, thread); } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_separate_color.cc b/source/blender/nodes/texture/nodes/node_texture_separate_color.cc index 74ba348b47c..e56999d1b2c 100644 --- a/source/blender/nodes/texture/nodes/node_texture_separate_color.cc +++ b/source/blender/nodes/texture/nodes/node_texture_separate_color.cc @@ -65,19 +65,19 @@ static void valuefn_b(float *out, TexParams *p, bNode *node, bNodeStack **in, sh *out = out[2]; } -static void valuefn_a(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void valuefn_a(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { tex_input_rgba(out, in[0], p, thread); *out = out[3]; } -static void update(bNodeTree *UNUSED(ntree), bNode *node) +static void update(bNodeTree * /*ntree*/, bNode *node) { node_combsep_color_label(&node->outputs, (NodeCombSepColorMode)node->custom1); } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_texture.cc b/source/blender/nodes/texture/nodes/node_texture_texture.cc index 7846ff3faa2..f2447777c3e 100644 --- a/source/blender/nodes/texture/nodes/node_texture_texture.cc +++ b/source/blender/nodes/texture/nodes/node_texture_texture.cc @@ -64,7 +64,7 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_translate.cc b/source/blender/nodes/texture/nodes/node_texture_translate.cc index d71df6ad0bf..69716f6b7f4 100644 --- a/source/blender/nodes/texture/nodes/node_texture_translate.cc +++ b/source/blender/nodes/texture/nodes/node_texture_translate.cc @@ -20,7 +20,7 @@ static bNodeSocketTemplate outputs[] = { {-1, ""}, }; -static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void colorfn(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { float offset[3], new_co[3]; TexParams np = *p; @@ -35,7 +35,7 @@ static void colorfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack ** tex_input_rgba(out, in[0], &np, thread); } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_valToNor.cc b/source/blender/nodes/texture/nodes/node_texture_valToNor.cc index b965669564c..c857847fa00 100644 --- a/source/blender/nodes/texture/nodes/node_texture_valToNor.cc +++ b/source/blender/nodes/texture/nodes/node_texture_valToNor.cc @@ -19,7 +19,7 @@ static bNodeSocketTemplate outputs[] = { {-1, ""}, }; -static void normalfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) +static void normalfn(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { float new_co[3]; const float *co = p->co; @@ -51,7 +51,7 @@ static void normalfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack * out[2] = val - nor[2]; } static void exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_valToRgb.cc b/source/blender/nodes/texture/nodes/node_texture_valToRgb.cc index 1e5340549cf..4fbf3db0ff2 100644 --- a/source/blender/nodes/texture/nodes/node_texture_valToRgb.cc +++ b/source/blender/nodes/texture/nodes/node_texture_valToRgb.cc @@ -29,7 +29,7 @@ static void valtorgb_colorfn(float *out, TexParams *p, bNode *node, bNodeStack * } static void valtorgb_exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, @@ -38,7 +38,7 @@ static void valtorgb_exec(void *data, tex_output(node, execdata, in, out[0], &valtorgb_colorfn, static_cast(data)); } -static void valtorgb_init(bNodeTree *UNUSED(ntree), bNode *node) +static void valtorgb_init(bNodeTree * /*ntree*/, bNode *node) { node->storage = BKE_colorband_add(true); } @@ -68,7 +68,7 @@ static bNodeSocketTemplate rgbtobw_out[] = { }; static void rgbtobw_valuefn( - float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) + float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, short thread) { float cin[4]; tex_input_rgba(cin, in[0], p, thread); @@ -76,7 +76,7 @@ static void rgbtobw_valuefn( } static void rgbtobw_exec(void *data, - int UNUSED(thread), + int /*thread*/, bNode *node, bNodeExecData *execdata, bNodeStack **in, diff --git a/source/blender/nodes/texture/nodes/node_texture_viewer.cc b/source/blender/nodes/texture/nodes/node_texture_viewer.cc index ff1b525532a..2e4b149f950 100644 --- a/source/blender/nodes/texture/nodes/node_texture_viewer.cc +++ b/source/blender/nodes/texture/nodes/node_texture_viewer.cc @@ -15,11 +15,11 @@ static bNodeSocketTemplate inputs[] = { }; static void exec(void *data, - int UNUSED(thread), - bNode *UNUSED(node), - bNodeExecData *UNUSED(execdata), + int /*thread*/, + bNode * /*node*/, + bNodeExecData * /*execdata*/, bNodeStack **in, - bNodeStack **UNUSED(out)) + bNodeStack ** /*out*/) { TexCallData *cdata = (TexCallData *)data; diff --git a/source/blender/render/intern/engine.cc b/source/blender/render/intern/engine.cc index 7d78f957e31..daca91eec4f 100644 --- a/source/blender/render/intern/engine.cc +++ b/source/blender/render/intern/engine.cc @@ -973,12 +973,12 @@ static void engine_render_view_layer(Render *re, /* Callback function for engine_render_create_result to add all render passes to the result. */ static void engine_render_add_result_pass_cb(void *user_data, - struct Scene *UNUSED(scene), + struct Scene * /*scene*/, struct ViewLayer *view_layer, const char *name, int channels, const char *chanid, - eNodeSocketDatatype UNUSED(type)) + eNodeSocketDatatype /*type*/) { RenderResult *rr = (RenderResult *)user_data; RE_create_render_pass(rr, name, channels, chanid, view_layer->name, RR_ALL_VIEWS, false); diff --git a/source/blender/render/intern/multires_bake.cc b/source/blender/render/intern/multires_bake.cc index 7f3c9c5db50..d1d302aa369 100644 --- a/source/blender/render/intern/multires_bake.cc +++ b/source/blender/render/intern/multires_bake.cc @@ -831,7 +831,7 @@ static void apply_heights_callback(DerivedMesh *lores_dm, const int tri_index, const int lvl, const float st[2], - float UNUSED(tangmat[3][3]), + float /*tangmat*/[3][3], const int x, const int y) { @@ -910,7 +910,7 @@ static void apply_heights_callback(DerivedMesh *lores_dm, /* **************** Normal Maps Baker **************** */ -static void *init_normal_data(MultiresBakeRender *bkr, ImBuf *UNUSED(ibuf)) +static void *init_normal_data(MultiresBakeRender *bkr, ImBuf * /*ibuf*/) { MNormalBakeData *normal_data; DerivedMesh *lodm = bkr->lores_dm; @@ -940,7 +940,7 @@ static void free_normal_data(void *bake_data) */ static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, - void *UNUSED(thread_data), + void * /*thread_data*/, void *bake_data, ImBuf *ibuf, const int tri_index, @@ -1107,7 +1107,7 @@ static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data) RE_rayobject_done(raytree); } -static void *init_ao_data(MultiresBakeRender *bkr, ImBuf *UNUSED(ibuf)) +static void *init_ao_data(MultiresBakeRender *bkr, ImBuf */*ibuf*/) { MAOBakeData *ao_data; DerivedMesh *lodm = bkr->lores_dm; @@ -1201,13 +1201,13 @@ static int trace_ao_ray(MAOBakeData *ao_data, float ray_start[3], float ray_dire static void apply_ao_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, - void *UNUSED(thread_data), + void */*thread_data*/, void *bake_data, ImBuf *ibuf, const int tri_index, const int lvl, const float st[2], - float UNUSED(tangmat[3][3]), + float /*tangmat[3][3]*/, const int x, const int y) { From 40e5954e3967140644e974e51ee729da5891be0e Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Tue, 13 Dec 2022 23:24:15 -0500 Subject: [PATCH 0236/1522] Cleanup: Use ampersand instead of "and" for labels UI guideline is use '&' for labels, use "and" for descriptions. --- source/blender/makesrna/intern/rna_modifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index d1e5fc913eb..24db2136af9 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -6951,7 +6951,7 @@ static void rna_def_modifier_weightednormal(BlenderRNA *brna) {MOD_WEIGHTEDNORMAL_MODE_FACE_ANGLE, "FACE_AREA_WITH_ANGLE", 0, - "Face Area And Angle", + "Face Area & Angle", "Generated normals weighted by both face area and angle"}, {0, NULL, 0, NULL, NULL}, }; From 4c295276f001ff9729496fe024ddf96d5ab51d31 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Wed, 21 Dec 2022 04:24:22 +0100 Subject: [PATCH 0237/1522] Cycles: Fix Metal kernel compilation --- intern/cycles/kernel/integrator/init_from_bake.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intern/cycles/kernel/integrator/init_from_bake.h b/intern/cycles/kernel/integrator/init_from_bake.h index 308f708380f..0d25c6493fe 100644 --- a/intern/cycles/kernel/integrator/init_from_bake.h +++ b/intern/cycles/kernel/integrator/init_from_bake.h @@ -27,8 +27,8 @@ CCL_NAMESPACE_BEGIN * For triangles that are smaller than a texel, this might take too many attempts, so eventually * we just give up and don't jitter in that case. * This is not a particularly elegant solution, but it's probably the best we can do. */ -ccl_device_inline void bake_jitter_barycentric(float &u, - float &v, +ccl_device_inline void bake_jitter_barycentric(ccl_private float &u, + ccl_private float &v, float2 rand_filter, const float dudx, const float dudy, From fcddb7cda7668ca36bb29a4256a31624ff00b645 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 20 Dec 2022 23:36:29 +0900 Subject: [PATCH 0238/1522] Small refactor of some of the RNA diffing API. Propagate `eRNAOverrideMatchResult` 'return' flags at higher level into BKE API, instead of just returning a boolean true when new override rules have been created. NOTE: This is an intermediary step towards fixing T102766. Differential Revision: https://developer.blender.org/D16761 --- source/blender/blenkernel/BKE_lib_override.h | 12 ++++- source/blender/blenkernel/intern/blendfile.c | 2 +- .../blenkernel/intern/blendfile_link_append.c | 4 +- .../blender/blenkernel/intern/lib_override.cc | 50 ++++++++++--------- .../blender/blenkernel/intern/undo_system.c | 6 ++- source/blender/makesrna/RNA_access.h | 2 + source/blender/makesrna/intern/rna_ID.c | 2 +- .../blender/windowmanager/intern/wm_files.c | 2 +- 8 files changed, 48 insertions(+), 32 deletions(-) diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index 963e2d09b17..a98984250b9 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -401,6 +401,8 @@ bool BKE_lib_override_library_status_check_reference(struct Main *bmain, struct * Compare local and reference data-blocks and create new override operations as needed, * or reset to reference values if overriding is not allowed. * + * \param r_report_flags #eRNAOverrideMatchResult flags giving info about the result of this call. + * * \note Defining override operations is only mandatory before saving a `.blend` file on disk * (not for undo!). * Knowing that info at runtime is only useful for UI/UX feedback. @@ -411,11 +413,17 @@ bool BKE_lib_override_library_status_check_reference(struct Main *bmain, struct * * \return true if any library operation was created. */ -bool BKE_lib_override_library_operations_create(struct Main *bmain, struct ID *local); +void BKE_lib_override_library_operations_create(struct Main *bmain, + struct ID *local, + int *r_report_flags); /** * Check all overrides from given \a bmain and create/update overriding operations as needed. + * + * \param r_report_flags #eRNAOverrideMatchResult flags giving info about the result of this call. */ -bool BKE_lib_override_library_main_operations_create(struct Main *bmain, bool force_auto); +void BKE_lib_override_library_main_operations_create(struct Main *bmain, + bool force_auto, + int *r_report_flags); /** * Reset all overrides in given \a id_root, while preserving ID relations. diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c index fb50de47881..7aa3fd4b9c5 100644 --- a/source/blender/blenkernel/intern/blendfile.c +++ b/source/blender/blenkernel/intern/blendfile.c @@ -435,7 +435,7 @@ static void setup_app_data(bContext *C, reports->duration.lib_overrides_resync; /* We need to rebuild some of the deleted override rules (for UI feedback purpose). */ - BKE_lib_override_library_main_operations_create(bmain, true); + BKE_lib_override_library_main_operations_create(bmain, true, NULL); } } diff --git a/source/blender/blenkernel/intern/blendfile_link_append.c b/source/blender/blenkernel/intern/blendfile_link_append.c index 409ae39f6be..3f3c1028d10 100644 --- a/source/blender/blenkernel/intern/blendfile_link_append.c +++ b/source/blender/blenkernel/intern/blendfile_link_append.c @@ -1424,7 +1424,7 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context, /* All override rules need to be up to date, since there will be no do_version here, otherwise * older, now-invalid rules might be applied and likely fail, or some changes might be missing, * etc. See T93353. */ - BKE_lib_override_library_main_operations_create(bmain, true); + BKE_lib_override_library_main_operations_create(bmain, true, NULL); /* Remove all IDs to be reloaded from Main. */ lba_idx = set_listbasepointers(bmain, lbarray); @@ -1634,7 +1634,7 @@ void BKE_blendfile_library_relocate(BlendfileLinkAppendContext *lapp_context, .reports = reports, }); /* We need to rebuild some of the deleted override rules (for UI feedback purpose). */ - BKE_lib_override_library_main_operations_create(bmain, true); + BKE_lib_override_library_main_operations_create(bmain, true, NULL); } BKE_main_collection_sync(bmain); diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index 07eb4741b1f..ce7abe63eac 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -1427,7 +1427,7 @@ bool BKE_lib_override_library_create(Main *bmain, BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); /* We need to rebuild some of the deleted override rules (for UI feedback purpose). */ - BKE_lib_override_library_main_operations_create(bmain, true); + BKE_lib_override_library_main_operations_create(bmain, true, nullptr); return success; } @@ -3297,19 +3297,18 @@ bool BKE_lib_override_library_status_check_reference(Main *bmain, ID *local) return true; } -bool BKE_lib_override_library_operations_create(Main *bmain, ID *local) +void BKE_lib_override_library_operations_create(Main *bmain, ID *local, int *r_report_flags) { BLI_assert(!ID_IS_LINKED(local)); BLI_assert(local->override_library != nullptr); const bool is_template = (local->override_library->reference == nullptr); - bool created = false; if (!is_template) { /* Do not attempt to generate overriding rules from an empty place-holder generated by link * code when it cannot find the actual library/ID. Much better to keep the local data-block as * is in the file in that case, until broken lib is fixed. */ if (ID_MISSING(local->override_library->reference)) { - return created; + return; } if (GS(local->name) == ID_OB) { @@ -3330,7 +3329,7 @@ bool BKE_lib_override_library_operations_create(Main *bmain, ID *local) RNA_id_pointer_create(local, &rnaptr_local); RNA_id_pointer_create(local->override_library->reference, &rnaptr_reference); - eRNAOverrideMatchResult report_flags = (eRNAOverrideMatchResult)0; + eRNAOverrideMatchResult local_report_flags = RNA_OVERRIDE_MATCH_RESULT_INIT; RNA_struct_override_matches( bmain, &rnaptr_local, @@ -3339,28 +3338,27 @@ bool BKE_lib_override_library_operations_create(Main *bmain, ID *local) 0, local->override_library, (eRNAOverrideMatch)(RNA_OVERRIDE_COMPARE_CREATE | RNA_OVERRIDE_COMPARE_RESTORE), - &report_flags); + &local_report_flags); - if (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) { - created = true; - } - - if (report_flags & RNA_OVERRIDE_MATCH_RESULT_RESTORED) { + if (local_report_flags & RNA_OVERRIDE_MATCH_RESULT_RESTORED) { CLOG_INFO(&LOG, 2, "We did restore some properties of %s from its reference", local->name); } - if (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) { + if (local_report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) { CLOG_INFO(&LOG, 2, "We did generate library override rules for %s", local->name); } else { CLOG_INFO(&LOG, 2, "No new library override rules for %s", local->name); } + + if (r_report_flags != nullptr) { + *r_report_flags |= local_report_flags; + } } - return created; } struct LibOverrideOpCreateData { Main *bmain; - bool changed; + eRNAOverrideMatchResult report_flags; }; static void lib_override_library_operations_create_cb(TaskPool *__restrict pool, void *taskdata) @@ -3369,14 +3367,16 @@ static void lib_override_library_operations_create_cb(TaskPool *__restrict pool, BLI_task_pool_user_data(pool)); ID *id = static_cast(taskdata); - if (BKE_lib_override_library_operations_create(create_data->bmain, id)) { - /* Technically no need for atomic, all jobs write the same value and we only care if one did - * it. But play safe and avoid implicit assumptions. */ - atomic_fetch_and_or_uint8(reinterpret_cast(&create_data->changed), true); - } + eRNAOverrideMatchResult report_flags = RNA_OVERRIDE_MATCH_RESULT_INIT; + BKE_lib_override_library_operations_create( + create_data->bmain, id, reinterpret_cast(&report_flags)); + atomic_fetch_and_or_uint32(reinterpret_cast(&create_data->report_flags), + report_flags); } -bool BKE_lib_override_library_main_operations_create(Main *bmain, const bool force_auto) +void BKE_lib_override_library_main_operations_create(Main *bmain, + const bool force_auto, + int *r_report_flags) { ID *id; @@ -3403,7 +3403,7 @@ bool BKE_lib_override_library_main_operations_create(Main *bmain, const bool for LibOverrideOpCreateData create_pool_data{}; create_pool_data.bmain = bmain; - create_pool_data.changed = false; + create_pool_data.report_flags = RNA_OVERRIDE_MATCH_RESULT_INIT; TaskPool *task_pool = BLI_task_pool_create(&create_pool_data, TASK_PRIORITY_HIGH); FOREACH_MAIN_ID_BEGIN (bmain, id) { @@ -3443,6 +3443,10 @@ bool BKE_lib_override_library_main_operations_create(Main *bmain, const bool for BLI_task_pool_free(task_pool); + if (r_report_flags != nullptr) { + *r_report_flags |= create_pool_data.report_flags; + } + if (force_auto) { BKE_lib_override_library_main_unused_cleanup(bmain); } @@ -3450,8 +3454,6 @@ bool BKE_lib_override_library_main_operations_create(Main *bmain, const bool for #ifdef DEBUG_OVERRIDE_TIMEIT TIMEIT_END_AVERAGED(BKE_lib_override_library_main_operations_create); #endif - - return create_pool_data.changed; } static bool lib_override_library_id_reset_do(Main *bmain, @@ -3906,7 +3908,7 @@ ID *BKE_lib_override_library_operations_store_start(Main *bmain, UNUSED_VARS_NDEBUG(override_storage); /* Forcefully ensure we know about all needed override operations. */ - BKE_lib_override_library_operations_create(bmain, local); + BKE_lib_override_library_operations_create(bmain, local, nullptr); ID *storage_id; #ifdef DEBUG_OVERRIDE_TIMEIT diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.c index db2a6b658fa..0c0de957773 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.c @@ -27,6 +27,8 @@ #include "BKE_main.h" #include "BKE_undo_system.h" +#include "RNA_access.h" + #include "MEM_guardedalloc.h" #define undo_stack _wm_undo_stack_disallow /* pass in as a variable always. */ @@ -494,7 +496,9 @@ eUndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack, /* Might not be final place for this to be called - probably only want to call it from some * undo handlers, not all of them? */ - if (BKE_lib_override_library_main_operations_create(G_MAIN, false)) { + eRNAOverrideMatchResult report_flags = RNA_OVERRIDE_MATCH_RESULT_INIT; + BKE_lib_override_library_main_operations_create(G_MAIN, false, (int *)&report_flags); + if (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) { retval |= UNDO_PUSH_RET_OVERRIDE_CHANGED; } diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index a7eacb03a63..97bef9d4965 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -803,6 +803,8 @@ typedef enum eRNAOverrideMatch { } eRNAOverrideMatch; typedef enum eRNAOverrideMatchResult { + RNA_OVERRIDE_MATCH_RESULT_INIT = 0, + /** * Some new property overrides were created to take into account * differences between local and reference. diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 7a13d840c9a..5e9318b65dd 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -821,7 +821,7 @@ static void rna_ID_override_library_operations_update(ID *id, return; } - BKE_lib_override_library_operations_create(bmain, id); + BKE_lib_override_library_operations_create(bmain, id, NULL); WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL); } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 2324426538b..7b1fcf2a231 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -1786,7 +1786,7 @@ static bool wm_file_write(bContext *C, ED_assets_pre_save(bmain); /* Enforce full override check/generation on file save. */ - BKE_lib_override_library_main_operations_create(bmain, true); + BKE_lib_override_library_main_operations_create(bmain, true, NULL); /* NOTE: Ideally we would call `WM_redraw_windows` here to remove any open menus. * But we can crash if saving from a script, see T92704 & T97627. From fd9a1d62f592a2ed104b8949ce5122d85d295603 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 21 Dec 2022 15:58:03 +0900 Subject: [PATCH 0239/1522] install_deps: Enable building OIIO tools. These tools are needed by some unittests doing image comparison e.g. --- build_files/build_environment/install_deps.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index c7b4c5930af..ed18e563f14 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -2243,7 +2243,7 @@ compile_OIIO() { fi # To be changed each time we make edits that would modify the compiled result! - oiio_magic=18 + oiio_magic=19 _init_oiio # Force having own builds for the dependencies. @@ -2323,7 +2323,7 @@ compile_OIIO() { cmake_d="$cmake_d -D USE_OPENVDB=OFF" cmake_d="$cmake_d -D BUILD_TESTING=OFF" cmake_d="$cmake_d -D OIIO_BUILD_TESTS=OFF" - cmake_d="$cmake_d -D OIIO_BUILD_TOOLS=OFF" + cmake_d="$cmake_d -D OIIO_BUILD_TOOLS=ON" cmake_d="$cmake_d -D TXT2MAN=" #cmake_d="$cmake_d -D CMAKE_EXPORT_COMPILE_COMMANDS=ON" #cmake_d="$cmake_d -D CMAKE_VERBOSE_MAKEFILE=ON" From b015fc4247af95a2fb4f0d77d5e37aa96d88e10a Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Wed, 21 Dec 2022 08:42:19 +0100 Subject: [PATCH 0240/1522] Cleanup: Use single declaration of TileNumber. We used int and int32_t. --- source/blender/blenkernel/BKE_image_partial_update.hh | 3 ++- source/blender/blenkernel/BKE_image_wrappers.hh | 9 ++++++--- source/blender/blenkernel/intern/image_partial_update.cc | 1 - 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/BKE_image_partial_update.hh b/source/blender/blenkernel/BKE_image_partial_update.hh index b9b748880bb..6c7776c091c 100644 --- a/source/blender/blenkernel/BKE_image_partial_update.hh +++ b/source/blender/blenkernel/BKE_image_partial_update.hh @@ -18,6 +18,8 @@ #include "BLI_rect.h" +#include "BKE_image_wrappers.hh" + #include "DNA_image_types.h" extern "C" { @@ -27,7 +29,6 @@ struct PartialUpdateUser; namespace blender::bke::image { -using TileNumber = int; namespace partial_update { diff --git a/source/blender/blenkernel/BKE_image_wrappers.hh b/source/blender/blenkernel/BKE_image_wrappers.hh index 344edd952f8..b3e81571e05 100644 --- a/source/blender/blenkernel/BKE_image_wrappers.hh +++ b/source/blender/blenkernel/BKE_image_wrappers.hh @@ -13,13 +13,16 @@ namespace blender::bke::image { +/** Type to use for UDIM tile numbers (1001). */ +using TileNumber = int32_t; + struct ImageTileWrapper { ImageTile *image_tile; ImageTileWrapper(ImageTile *image_tile) : image_tile(image_tile) { } - int get_tile_number() const + TileNumber get_tile_number() const { return image_tile->tile_number; } @@ -31,13 +34,13 @@ struct ImageTileWrapper { int get_tile_x_offset() const { - int tile_number = get_tile_number(); + TileNumber tile_number = get_tile_number(); return (tile_number - 1001) % 10; } int get_tile_y_offset() const { - int tile_number = get_tile_number(); + TileNumber tile_number = get_tile_number(); return (tile_number - 1001) / 10; } }; diff --git a/source/blender/blenkernel/intern/image_partial_update.cc b/source/blender/blenkernel/intern/image_partial_update.cc index 6ffd323cc1e..ecf55d6b694 100644 --- a/source/blender/blenkernel/intern/image_partial_update.cc +++ b/source/blender/blenkernel/intern/image_partial_update.cc @@ -125,7 +125,6 @@ static PartialUpdateRegisterImpl *unwrap(struct PartialUpdateRegister *partial_u return static_cast(static_cast(partial_update_register)); } -using TileNumber = int32_t; using ChangesetID = int64_t; constexpr ChangesetID UnknownChangesetID = -1; From 7ff47f7a944cb3107af127cf0545d3c0f04b3555 Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Wed, 21 Dec 2022 14:07:19 +0100 Subject: [PATCH 0241/1522] Metal: Add missing MIP_SWIZZLE texture usage flags. Fix compilation warnings. Authored by Apple: Michael Parkin-White Ref T96261 Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D16824 --- source/blender/draw/intern/draw_cache_impl_volume.cc | 3 ++- source/blender/draw/intern/draw_fluid.c | 3 ++- source/blender/editors/sculpt_paint/paint_cursor.cc | 6 ++++-- source/blender/gpu/metal/mtl_context.hh | 2 +- source/blender/windowmanager/intern/wm_operators.c | 3 ++- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/source/blender/draw/intern/draw_cache_impl_volume.cc b/source/blender/draw/intern/draw_cache_impl_volume.cc index b22831bf94b..dd89e84ed71 100644 --- a/source/blender/draw/intern/draw_cache_impl_volume.cc +++ b/source/blender/draw/intern/draw_cache_impl_volume.cc @@ -312,7 +312,8 @@ static DRWVolumeGrid *volume_grid_cache_get(const Volume *volume, 1, format, GPU_DATA_FLOAT, - GPU_TEXTURE_USAGE_SHADER_READ, + GPU_TEXTURE_USAGE_SHADER_READ | + GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW, dense_grid.voxels); /* The texture can be null if the resolution along one axis is larger than * GL_MAX_3D_TEXTURE_SIZE. */ diff --git a/source/blender/draw/intern/draw_fluid.c b/source/blender/draw/intern/draw_fluid.c index 8975e955530..8fbdb7eec13 100644 --- a/source/blender/draw/intern/draw_fluid.c +++ b/source/blender/draw/intern/draw_fluid.c @@ -184,7 +184,8 @@ static GPUTexture *create_volume_texture(const int dim[3], 1, texture_format, data_format, - GPU_TEXTURE_USAGE_SHADER_READ, + GPU_TEXTURE_USAGE_SHADER_READ | + GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW, NULL); if (tex != NULL) { diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index d3cea0e5573..43e59aaf4f7 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -334,7 +334,8 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima if (!target->overlay_texture) { eGPUTextureFormat format = col ? GPU_RGBA8 : GPU_R8; - eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT; + eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT | + GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW; target->overlay_texture = GPU_texture_create_2d_ex( "paint_cursor_overlay", size, size, 1, format, usage, nullptr); GPU_texture_update(target->overlay_texture, GPU_DATA_UBYTE, buffer); @@ -453,7 +454,8 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom) BLI_task_parallel_range(0, size, &data, load_tex_cursor_task_cb, &settings); if (!cursor_snap.overlay_texture) { - eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT; + eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT | + GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW; cursor_snap.overlay_texture = GPU_texture_create_2d_ex( "cursor_snap_overaly", size, size, 1, GPU_R8, usage, nullptr); GPU_texture_update(cursor_snap.overlay_texture, GPU_DATA_UBYTE, buffer); diff --git a/source/blender/gpu/metal/mtl_context.hh b/source/blender/gpu/metal/mtl_context.hh index a26e31aadde..e2789dbf9a7 100644 --- a/source/blender/gpu/metal/mtl_context.hh +++ b/source/blender/gpu/metal/mtl_context.hh @@ -658,7 +658,7 @@ class MTLContext : public Context { /** Dummy Resources */ /* Maximum of 32 texture types. Though most combinations invalid. */ - gpu::MTLTexture *dummy_textures_[GPU_SAMPLER_TYPE_MAX][GPU_TEXTURE_BUFFER] = {nullptr}; + gpu::MTLTexture *dummy_textures_[GPU_SAMPLER_TYPE_MAX][GPU_TEXTURE_BUFFER] = {{nullptr}}; GPUVertFormat dummy_vertformat_[GPU_SAMPLER_TYPE_MAX]; GPUVertBuf *dummy_verts_[GPU_SAMPLER_TYPE_MAX] = {nullptr}; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 8fbf528b8bb..f43b6722550 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -2300,7 +2300,8 @@ static void radial_control_set_tex(RadialControl *rc) ibuf->y, 1, GPU_R8, - GPU_TEXTURE_USAGE_SHADER_READ, + GPU_TEXTURE_USAGE_SHADER_READ | + GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW, ibuf->rect_float); GPU_texture_filter_mode(rc->texture, true); From 3535670ff1a1dd735475303c885e01a07a5f4b54 Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Wed, 21 Dec 2022 14:11:20 +0100 Subject: [PATCH 0242/1522] Metal: Optimize local shader memory usage. Global scope arrays can incur suboptimal per-shader-thread memory allocations, resulting in excessive usage of limited local memory resources. These changes ensure that any arrays are limited to the closest scope in which they are required and thus will get correctly optimized by the compiler. A number of constants have also been replaced with Macro's as these can result in better runtime performance for complex shader code. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D16825 --- .../eevee/shaders/common_utiltex_lib.glsl | 4 +- .../shaders/effect_dof_dilate_tiles_frag.glsl | 4 +- .../shaders/effect_dof_downsample_frag.glsl | 1 + .../effect_dof_flatten_tiles_frag.glsl | 2 +- .../eevee/shaders/effect_dof_gather_frag.glsl | 4 +- .../engines/eevee/shaders/effect_dof_lib.glsl | 55 ++++++++++--------- .../eevee/shaders/effect_dof_reduce_frag.glsl | 2 + .../shaders/effect_dof_scatter_frag.glsl | 1 + .../shaders/effect_dof_scatter_vert.glsl | 1 + .../eevee/shaders/effect_dof_setup_frag.glsl | 1 + .../eevee/shaders/effect_reflection_lib.glsl | 51 +---------------- .../effect_reflection_resolve_frag.glsl | 52 ++++++++++++++++++ .../shaders/workbench_volume_frag.glsl | 10 ++-- 13 files changed, 101 insertions(+), 87 deletions(-) diff --git a/source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl b/source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl index 645f2798937..d2ad6eb3711 100644 --- a/source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/common_utiltex_lib.glsl @@ -23,8 +23,8 @@ uniform sampler2DArray utilTex; #define LTC_DISK_LAYER 3 /* UNUSED */ /* Layers 4 to 20 are for BTDF Lut. */ -const float lut_btdf_layer_first = 4.0; -const float lut_btdf_layer_count = 16.0; +#define lut_btdf_layer_first 4.0 +#define lut_btdf_layer_count 16.0 /** * Reminder: The 4 noise values are based of 3 uncorrelated blue noises: diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_dilate_tiles_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_dilate_tiles_frag.glsl index 1b75ca3e62a..c8c99737006 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_dilate_tiles_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_dilate_tiles_frag.glsl @@ -6,10 +6,10 @@ #pragma BLENDER_REQUIRE(effect_dof_lib.glsl) -const float tile_to_fullres_factor = float(DOF_TILE_DIVISOR); +#define tile_to_fullres_factor float(DOF_TILE_DIVISOR) /* Error introduced by the random offset of the gathering kernel's center. */ -const float bluring_radius_error = 1.0 + 1.0 / (gather_ring_count + 0.5); +#define bluring_radius_error (1.0 + 1.0 / (gather_ring_count + 0.5)) void main() { diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_downsample_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_downsample_frag.glsl index a5125a87fe7..14801192372 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_downsample_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_downsample_frag.glsl @@ -10,6 +10,7 @@ void main() { + DEFINE_DOF_QUAD_OFFSETS vec2 halfres_texel_size = 1.0 / vec2(textureSize(colorBuffer, 0).xy); /* Center uv around the 4 halfres pixels. */ vec2 quad_center = (floor(gl_FragCoord.xy) * 2.0 + 1.0) * halfres_texel_size; diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_flatten_tiles_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_flatten_tiles_frag.glsl index 21736dcc2f1..007de142f92 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_flatten_tiles_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_flatten_tiles_frag.glsl @@ -9,7 +9,7 @@ #pragma BLENDER_REQUIRE(effect_dof_lib.glsl) -const int halfres_tile_divisor = DOF_TILE_DIVISOR / 2; +#define halfres_tile_divisor (DOF_TILE_DIVISOR / 2) void main() { diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_gather_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_gather_frag.glsl index 7bba9b20224..03837b97cb6 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_gather_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_gather_frag.glsl @@ -18,9 +18,9 @@ vec2 outOcclusion; #endif #ifdef DOF_FOREGROUND_PASS -const bool is_foreground = true; +# define is_foreground true #else /* DOF_BACKGROUND_PASS */ -const bool is_foreground = false; +# define is_foreground false #endif const float unit_ring_radius = 1.0 / float(gather_ring_count); diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl index a0f885d69ae..dc382e68d22 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl @@ -12,38 +12,41 @@ // #define DOF_DEBUG_GATHER_PERF // #define DOF_DEBUG_SCATTER_PERF -const bool no_smooth_intersection = false; -const bool no_gather_occlusion = false; -const bool no_gather_mipmaps = false; -const bool no_gather_random = false; -const bool no_gather_filtering = false; -const bool no_scatter_occlusion = false; -const bool no_scatter_pass = false; -const bool no_foreground_pass = false; -const bool no_background_pass = false; -const bool no_slight_focus_pass = false; -const bool no_focus_pass = false; -const bool no_holefill_pass = false; +#define no_smooth_intersection false +#define no_gather_occlusion false +#define no_gather_mipmaps false +#define no_gather_random false +#define no_gather_filtering false +#define no_scatter_occlusion false +#define no_scatter_pass false +#define no_foreground_pass false +#define no_background_pass false +#define no_slight_focus_pass false +#define no_focus_pass false +#define no_holefill_pass false /* -------------- Quality Defines ------------- */ #ifdef DOF_HOLEFILL_PASS /* No need for very high density for holefill. */ -const int gather_ring_count = 3; -const int gather_ring_density = 3; -const int gather_max_density_change = 0; -const int gather_density_change_ring = 1; +# define gather_ring_count 3 +# define gather_ring_density 3 +# define gather_max_density_change 0 +# define gather_density_change_ring 1 #else -const int gather_ring_count = DOF_GATHER_RING_COUNT; -const int gather_ring_density = 3; -const int gather_max_density_change = 50; /* Dictates the maximum good quality blur. */ -const int gather_density_change_ring = 1; +# define gather_ring_count DOF_GATHER_RING_COUNT +# define gather_ring_density 3 +# define gather_max_density_change 50 /* Dictates the maximum good quality blur. */ +# define gather_density_change_ring 1 #endif /* -------------- Utils ------------- */ - -const vec2 quad_offsets[4] = vec2[4]( - vec2(-0.5, 0.5), vec2(0.5, 0.5), vec2(0.5, -0.5), vec2(-0.5, -0.5)); +/* For performance on macOS, constants declared within function scope utilize constant uniform + register space rather than per-thread, reducing spill and incrasing + thread execution width - and thus performance */ +#define DEFINE_DOF_QUAD_OFFSETS \ + const vec2 quad_offsets[4] = vec2[4]( \ + vec2(-0.5, 0.5), vec2(0.5, 0.5), vec2(0.5, -0.5), vec2(-0.5, -0.5)); /* Divide by sensor size to get the normalized size. */ #define calculate_coc_persp(zdepth) (cocMul / zdepth - cocBias) @@ -128,11 +131,11 @@ float dof_load_gather_coc(sampler2D gather_input_coc_buffer, vec2 uv, float lod) } /* Distribute weights between near/slightfocus/far fields (slide 117). */ -const float layer_threshold = 4.0; +#define layer_threshold 4.0 /* Make sure it overlaps. */ -const float layer_offset_fg = 0.5 + 1.0; +#define layer_offset_fg (0.5 + 1.0) /* Extra offset for convolution layers to avoid light leaking from background. */ -const float layer_offset = 0.5 + 0.5; +#define layer_offset (0.5 + 0.5) #define DOF_MAX_SLIGHT_FOCUS_RADIUS 16 diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_reduce_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_reduce_frag.glsl index 9fd2abfc148..eed52815a6e 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_reduce_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_reduce_frag.glsl @@ -11,6 +11,7 @@ /* NOTE: Do not compare alpha as it is not scattered by the scatter pass. */ float dof_scatter_neighborhood_rejection(vec3 color) { + DEFINE_DOF_QUAD_OFFSETS; color = min(vec3(scatterColorNeighborMax), color); float validity = 0.0; @@ -132,6 +133,7 @@ void main() /* Downsample pass done for each mip starting from mip1. */ void main() { + DEFINE_DOF_QUAD_OFFSETS vec2 input_texel_size = 1.0 / vec2(textureSize(colorBuffer, 0).xy); /* Center uv around the 4 pixels of the previous mip. */ vec2 quad_center = (floor(gl_FragCoord.xy) * 2.0 + 1.0) * input_texel_size; diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_frag.glsl index f73c85cf690..5038dff87d8 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_frag.glsl @@ -29,6 +29,7 @@ float bokeh_shape(vec2 center) void main(void) { + DEFINE_DOF_QUAD_OFFSETS vec4 shapes; for (int i = 0; i < 4; i++) { shapes[i] = bokeh_shape(spritepos + quad_offsets[i]); diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl index 6b1eac50645..6b38fbeb705 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl @@ -37,6 +37,7 @@ void vertex_discard() void main() { + DEFINE_DOF_QUAD_OFFSETS ivec2 tex_size = textureSize(cocBuffer, 0); int t_id = gl_VertexID / 3; /* Triangle Id */ diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_setup_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_setup_frag.glsl index 46c2beaa72a..3b996280e78 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_setup_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_setup_frag.glsl @@ -10,6 +10,7 @@ void main() { + DEFINE_DOF_QUAD_OFFSETS vec2 fullres_texel_size = 1.0 / vec2(textureSize(colorBuffer, 0).xy); /* Center uv around the 4 fullres pixels. */ vec2 quad_center = (floor(gl_FragCoord.xy) * 2.0 + 1.0) * fullres_texel_size; diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl index 3b99acb9c31..7097d56fe54 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_lib.glsl @@ -47,53 +47,4 @@ HitData decode_hit_data(vec4 hit_data, float hit_depth) /* Blue noise categorized into 4 sets of samples. * See "Stochastic all the things" presentation slide 32-37. */ -const int resolve_samples_count = 9; -const vec2 resolve_sample_offsets[36] = vec2[36]( - /* Set 1. */ - /* First Ring (2x2). */ - vec2(0, 0), - /* Second Ring (6x6). */ - vec2(-1, 3), - vec2(1, 3), - vec2(-1, 1), - vec2(3, 1), - vec2(-2, 0), - vec2(3, 0), - vec2(2, -1), - vec2(1, -2), - /* Set 2. */ - /* First Ring (2x2). */ - vec2(1, 1), - /* Second Ring (6x6). */ - vec2(-2, 3), - vec2(3, 3), - vec2(0, 2), - vec2(2, 2), - vec2(-2, -1), - vec2(1, -1), - vec2(0, -2), - vec2(3, -2), - /* Set 3. */ - /* First Ring (2x2). */ - vec2(0, 1), - /* Second Ring (6x6). */ - vec2(0, 3), - vec2(3, 2), - vec2(-2, 1), - vec2(2, 1), - vec2(-1, 0), - vec2(-2, -2), - vec2(0, -1), - vec2(2, -2), - /* Set 4. */ - /* First Ring (2x2). */ - vec2(1, 0), - /* Second Ring (6x6). */ - vec2(2, 3), - vec2(-2, 2), - vec2(-1, 2), - vec2(1, 2), - vec2(2, 0), - vec2(-1, -1), - vec2(3, -1), - vec2(-1, -2)); +#define resolve_samples_count 9 \ No newline at end of file diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl index 6fa64c1671d..4776475f9ea 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_resolve_frag.glsl @@ -102,6 +102,58 @@ void raytrace_resolve(ClosureInputGlossy cl_in, inout ClosureEvalCommon cl_common, inout ClosureOutputGlossy cl_out) { + /* Note: Reflection samples declared in function scope to avoid per-thread memory pressure on + * tile-based GPUs e.g. Apple Silicon. */ + const vec2 resolve_sample_offsets[36] = vec2[36]( + /* Set 1. */ + /* First Ring (2x2). */ + vec2(0, 0), + /* Second Ring (6x6). */ + vec2(-1, 3), + vec2(1, 3), + vec2(-1, 1), + vec2(3, 1), + vec2(-2, 0), + vec2(3, 0), + vec2(2, -1), + vec2(1, -2), + /* Set 2. */ + /* First Ring (2x2). */ + vec2(1, 1), + /* Second Ring (6x6). */ + vec2(-2, 3), + vec2(3, 3), + vec2(0, 2), + vec2(2, 2), + vec2(-2, -1), + vec2(1, -1), + vec2(0, -2), + vec2(3, -2), + /* Set 3. */ + /* First Ring (2x2). */ + vec2(0, 1), + /* Second Ring (6x6). */ + vec2(0, 3), + vec2(3, 2), + vec2(-2, 1), + vec2(2, 1), + vec2(-1, 0), + vec2(-2, -2), + vec2(0, -1), + vec2(2, -2), + /* Set 4. */ + /* First Ring (2x2). */ + vec2(1, 0), + /* Second Ring (6x6). */ + vec2(2, 3), + vec2(-2, 2), + vec2(-1, 2), + vec2(1, 2), + vec2(2, 0), + vec2(-1, -1), + vec2(3, -1), + vec2(-1, -2)); + float roughness = cl_in.roughness; vec4 ssr_accum = vec4(0.0); diff --git a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl index 133fe7f4b0f..80190ede5c9 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_volume_frag.glsl @@ -182,13 +182,15 @@ void eval_volume_step(inout vec3 Lscat, float extinction, float step_len, out fl } #define P(x) ((x + 0.5) * (1.0 / 16.0)) -const vec4 dither_mat[4] = vec4[4](vec4(P(0.0), P(8.0), P(2.0), P(10.0)), - vec4(P(12.0), P(4.0), P(14.0), P(6.0)), - vec4(P(3.0), P(11.0), P(1.0), P(9.0)), - vec4(P(15.0), P(7.0), P(13.0), P(5.0))); vec4 volume_integration(vec3 ray_ori, vec3 ray_dir, float ray_inc, float ray_max, float step_len) { + /* Note: Constant array declared inside function scope to reduce shader core thread memory + * pressure on Apple Silicon. */ + const vec4 dither_mat[4] = vec4[4](vec4(P(0.0), P(8.0), P(2.0), P(10.0)), + vec4(P(12.0), P(4.0), P(14.0), P(6.0)), + vec4(P(3.0), P(11.0), P(1.0), P(9.0)), + vec4(P(15.0), P(7.0), P(13.0), P(5.0))); /* Start with full transmittance and no scattered light. */ vec3 final_scattering = vec3(0.0); float final_transmittance = 1.0; From 51e2ce7df5b566b526babc750a7288eab4ccd4e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Wed, 21 Dec 2022 16:03:20 +0100 Subject: [PATCH 0243/1522] Metal: Turn Metal backend build option ON by default This enable building the metal backend by default on Apple hardware. This is needed for further testing and the new backend selector D16774. Ref T96261 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a6683ce40b1..8aa8bffe08f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -593,7 +593,7 @@ mark_as_advanced( # Metal if(APPLE) - option(WITH_METAL_BACKEND "Use Metal for graphics instead of (or as well as) OpenGL on macOS." OFF) + option(WITH_METAL_BACKEND "Use Metal for graphics instead of (or as well as) OpenGL on macOS." ON) mark_as_advanced(WITH_METAL_BACKEND) else() set(WITH_METAL_BACKEND OFF) From d0348bcb8a560f3a5526fc2ad97e4211144c277e Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 20 Dec 2022 16:30:11 -0600 Subject: [PATCH 0244/1522] Fix: Crash when grouping frame node but not its children Most likely caused by ab4926bcffeef20cfb9225d --- source/blender/editors/space_node/node_group.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc index 2c28a8fae34..45aeaa41ad5 100644 --- a/source/blender/editors/space_node/node_group.cc +++ b/source/blender/editors/space_node/node_group.cc @@ -833,7 +833,7 @@ static void node_group_make_insert_selected(const bContext &C, if (node->parent == nullptr) { continue; } - if (nodes_to_move.contains(node->parent) && nodes_to_move.contains(node)) { + if (nodes_to_move.contains(node->parent) && !nodes_to_move.contains(node)) { nodeDetachNode(&ntree, node); } } From 8bbf823716214f2f3aeed1f0bfc6cf802ecb2edb Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 20 Dec 2022 17:14:34 -0600 Subject: [PATCH 0245/1522] Cleanup: Simplify arguments to deselect all nodes function Take the node tree as an argument directly instead of retrieving it from the editor struct. Then use the utility function in two more places. --- .../editors/space_node/add_node_search.cc | 2 +- .../editors/space_node/link_drag_search.cc | 9 ++-- source/blender/editors/space_node/node_add.cc | 21 +++++---- .../blender/editors/space_node/node_edit.cc | 2 +- .../blender/editors/space_node/node_group.cc | 10 +---- .../blender/editors/space_node/node_intern.hh | 6 +-- .../editors/space_node/node_relationships.cc | 7 +-- .../blender/editors/space_node/node_select.cc | 44 +++++++++---------- 8 files changed, 50 insertions(+), 51 deletions(-) diff --git a/source/blender/editors/space_node/add_node_search.cc b/source/blender/editors/space_node/add_node_search.cc index ba060ab3925..78e52c82517 100644 --- a/source/blender/editors/space_node/add_node_search.cc +++ b/source/blender/editors/space_node/add_node_search.cc @@ -247,7 +247,7 @@ static void add_node_search_exec_fn(bContext *C, void *arg1, void *arg2) return; } - node_deselect_all(snode); + node_deselect_all(node_tree); bNode *new_node = nodeAddNode(C, &node_tree, item->identifier.c_str()); BLI_assert(new_node != nullptr); diff --git a/source/blender/editors/space_node/link_drag_search.cc b/source/blender/editors/space_node/link_drag_search.cc index 8e156f409af..08d9f6ecc4f 100644 --- a/source/blender/editors/space_node/link_drag_search.cc +++ b/source/blender/editors/space_node/link_drag_search.cc @@ -349,17 +349,18 @@ static void link_drag_search_exec_fn(bContext *C, void *arg1, void *arg2) { Main &bmain = *CTX_data_main(C); SpaceNode &snode = *CTX_wm_space_node(C); + bNodeTree &node_tree = *snode.edittree; LinkDragSearchStorage &storage = *static_cast(arg1); SocketLinkOperation *item = static_cast(arg2); if (item == nullptr) { return; } - node_deselect_all(snode); + node_deselect_all(node_tree); Vector new_nodes; nodes::LinkSearchOpParams params{ - *C, *snode.edittree, storage.from_node, storage.from_socket, new_nodes}; + *C, node_tree, storage.from_node, storage.from_socket, new_nodes}; item->fn(params); if (new_nodes.is_empty()) { return; @@ -376,11 +377,11 @@ static void link_drag_search_exec_fn(bContext *C, void *arg1, void *arg2) } nodeSetSelected(new_node, true); - nodeSetActive(snode.edittree, new_node); + nodeSetActive(&node_tree, new_node); /* Ideally it would be possible to tag the node tree in some way so it updates only after the * translate operation is finished, but normally moving nodes around doesn't cause updates. */ - ED_node_tree_propagate_change(C, &bmain, snode.edittree); + ED_node_tree_propagate_change(C, &bmain, &node_tree); /* Start translation operator with the new node. */ wmOperatorType *ot = WM_operatortype_find("NODE_OT_translate_attach_remove_on_cancel", true); diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc index 4bb550a553f..ce1fe118281 100644 --- a/source/blender/editors/space_node/node_add.cc +++ b/source/blender/editors/space_node/node_add.cc @@ -63,20 +63,21 @@ bNode *add_node(const bContext &C, const StringRef idname, const float2 &locatio { SpaceNode &snode = *CTX_wm_space_node(&C); Main &bmain = *CTX_data_main(&C); + bNodeTree &node_tree = *snode.edittree; - node_deselect_all(snode); + node_deselect_all(node_tree); const std::string idname_str = idname; - bNode *node = nodeAddNode(&C, snode.edittree, idname_str.c_str()); + bNode *node = nodeAddNode(&C, &node_tree, idname_str.c_str()); BLI_assert(node && node->typeinfo); position_node_based_on_mouse(*node, location); nodeSetSelected(node, true); - ED_node_set_active(&bmain, &snode, snode.edittree, node, nullptr); + ED_node_set_active(&bmain, &snode, &node_tree, node, nullptr); - ED_node_tree_propagate_change(&C, &bmain, snode.edittree); + ED_node_tree_propagate_change(&C, &bmain, &node_tree); return node; } @@ -84,18 +85,19 @@ bNode *add_static_node(const bContext &C, int type, const float2 &location) { SpaceNode &snode = *CTX_wm_space_node(&C); Main &bmain = *CTX_data_main(&C); + bNodeTree &node_tree = *snode.edittree; - node_deselect_all(snode); + node_deselect_all(node_tree); - bNode *node = nodeAddStaticNode(&C, snode.edittree, type); + bNode *node = nodeAddStaticNode(&C, &node_tree, type); BLI_assert(node && node->typeinfo); position_node_based_on_mouse(*node, location); nodeSetSelected(node, true); - ED_node_set_active(&bmain, &snode, snode.edittree, node, nullptr); + ED_node_set_active(&bmain, &snode, &node_tree, node, nullptr); - ED_node_tree_propagate_change(&C, &bmain, snode.edittree); + ED_node_tree_propagate_change(&C, &bmain, &node_tree); return node; } @@ -152,11 +154,12 @@ static int add_reroute_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } + node_deselect_all(ntree); + ntree.ensure_topology_cache(); const Vector frame_nodes = ntree.nodes_by_type("NodeFrame"); ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); - node_deselect_all(snode); /* All link "cuts" that start at a particular output socket. Deduplicating new reroutes per * output socket is useful because it allows reusing reroutes for connected intersections. diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 1bf5b938ee3..7fdc2db9fdb 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -2335,7 +2335,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); /* deselect old nodes */ - node_deselect_all(*snode); + node_deselect_all(*ntree); /* calculate "barycenter" for placing on mouse cursor */ float2 center = {0.0f, 0.0f}; diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc index 45aeaa41ad5..6fb8ff54988 100644 --- a/source/blender/editors/space_node/node_group.cc +++ b/source/blender/editors/space_node/node_group.cc @@ -441,10 +441,7 @@ void NODE_OT_group_ungroup(wmOperatorType *ot) static bool node_group_separate_selected( Main &bmain, bNodeTree &ntree, bNodeTree &ngroup, const float2 &offset, const bool make_copy) { - /* deselect all nodes in the target tree */ - for (bNode *node : ntree.all_nodes()) { - nodeSetSelected(node, false); - } + node_deselect_all(ntree); ListBase anim_basepaths = {nullptr, nullptr}; @@ -809,10 +806,7 @@ static void node_group_make_insert_selected(const bContext &C, static const float offsetx = 200; static const float offsety = 0.0f; - /* deselect all nodes in the target tree */ - for (bNode *node : ngroup->all_nodes()) { - nodeSetSelected(node, false); - } + node_deselect_all(*ngroup); /* auto-add interface for "solo" nodes */ const bool expose_visible = nodes_to_move.size() == 1; diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index a4eb0c12713..9b2d55ab107 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -182,11 +182,11 @@ void node_keymap(wmKeyConfig *keyconf); rctf node_frame_rect_inside(const bNode &node); bool node_or_socket_isect_event(const bContext &C, const wmEvent &event); -void node_deselect_all(SpaceNode &snode); +void node_deselect_all(bNodeTree &node_tree); void node_socket_select(bNode *node, bNodeSocket &sock); void node_socket_deselect(bNode *node, bNodeSocket &sock, bool deselect_node); -void node_deselect_all_input_sockets(SpaceNode &snode, bool deselect_nodes); -void node_deselect_all_output_sockets(SpaceNode &snode, bool deselect_nodes); +void node_deselect_all_input_sockets(bNodeTree &node_tree, bool deselect_nodes); +void node_deselect_all_output_sockets(bNodeTree &node_tree, bool deselect_nodes); void node_select_single(bContext &C, bNode &node); void NODE_OT_select(wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 360f713e1a7..08b054f3d7d 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -1261,6 +1261,7 @@ static int node_make_link_exec(bContext *C, wmOperator *op) { Main &bmain = *CTX_data_main(C); SpaceNode &snode = *CTX_wm_space_node(C); + bNodeTree &node_tree = *snode.edittree; const bool replace = RNA_boolean_get(op->ptr, "replace"); ED_preview_kill_jobs(CTX_wm_manager(C), &bmain); @@ -1268,10 +1269,10 @@ static int node_make_link_exec(bContext *C, wmOperator *op) snode_autoconnect(snode, true, replace); /* deselect sockets after linking */ - node_deselect_all_input_sockets(snode, false); - node_deselect_all_output_sockets(snode, false); + node_deselect_all_input_sockets(node_tree, false); + node_deselect_all_output_sockets(node_tree, false); - ED_node_tree_propagate_change(C, &bmain, snode.edittree); + ED_node_tree_propagate_change(C, &bmain, &node_tree); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index 7ecacde3874..67ed9a34c7d 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -246,21 +246,21 @@ static void node_socket_toggle(bNode *node, bNodeSocket &sock, bool deselect_nod } } -void node_deselect_all(SpaceNode &snode) +void node_deselect_all(bNodeTree &node_tree) { - for (bNode *node : snode.edittree->all_nodes()) { + for (bNode *node : node_tree.all_nodes()) { nodeSetSelected(node, false); } } -void node_deselect_all_input_sockets(SpaceNode &snode, const bool deselect_nodes) +void node_deselect_all_input_sockets(bNodeTree &node_tree, const bool deselect_nodes) { /* XXX not calling node_socket_deselect here each time, because this does iteration * over all node sockets internally to check if the node stays selected. * We can do that more efficiently here. */ - for (bNode *node : snode.edittree->all_nodes()) { + for (bNode *node : node_tree.all_nodes()) { bool sel = false; LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) { @@ -283,14 +283,14 @@ void node_deselect_all_input_sockets(SpaceNode &snode, const bool deselect_nodes } } -void node_deselect_all_output_sockets(SpaceNode &snode, const bool deselect_nodes) +void node_deselect_all_output_sockets(bNodeTree &node_tree, const bool deselect_nodes) { /* XXX not calling node_socket_deselect here each time, because this does iteration * over all node sockets internally to check if the node stays selected. * We can do that more efficiently here. */ - for (bNode *node : snode.edittree->all_nodes()) { + for (bNode *node : node_tree.all_nodes()) { bool sel = false; LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) { @@ -422,7 +422,7 @@ static int node_select_grouped_exec(bContext *C, wmOperator *op) const int type = RNA_enum_get(op->ptr, "type"); if (!extend) { - node_deselect_all(snode); + node_deselect_all(node_tree); } nodeSetSelected(node_act, true); @@ -527,11 +527,12 @@ static bool node_mouse_select(bContext *C, { Main &bmain = *CTX_data_main(C); SpaceNode &snode = *CTX_wm_space_node(C); + bNodeTree &node_tree = *snode.edittree; ARegion ®ion = *CTX_wm_region(C); const Object *ob = CTX_data_active_object(C); const Scene *scene = CTX_data_scene(C); const wmWindowManager *wm = CTX_wm_manager(C); - bNode *node, *tnode; + bNode *node; bNodeSocket *sock = nullptr; bNodeSocket *tsock; @@ -582,7 +583,7 @@ static bool node_mouse_select(bContext *C, } } if (!extend) { - for (tnode = (bNode *)snode.edittree->nodes.first; tnode; tnode = tnode->next) { + for (bNode *tnode : node_tree.all_nodes()) { if (tnode == node) { continue; } @@ -601,7 +602,7 @@ static bool node_mouse_select(bContext *C, if (!sock) { /* find the closest visible node */ - node = node_under_mouse_select(*snode.edittree, cursor); + node = node_under_mouse_select(node_tree, cursor); found = (node != nullptr); node_was_selected = node && (node->flag & SELECT); @@ -611,7 +612,7 @@ static bool node_mouse_select(bContext *C, } else if (found || params->deselect_all) { /* Deselect everything. */ - node_deselect_all(snode); + node_deselect_all(node_tree); changed = true; } } @@ -669,7 +670,7 @@ static bool node_mouse_select(bContext *C, viewer_path::activate_geometry_node(bmain, snode, *node); } ED_node_set_active_viewer_key(&snode); - node_sort(*snode.edittree); + node_sort(node_tree); if ((active_texture_changed && has_workbench_in_texture_color(wm, scene, ob)) || viewer_node_changed) { DEG_id_tag_update(&snode.edittree->id, ID_RECALC_COPY_ON_WRITE); @@ -769,7 +770,7 @@ static int node_box_select_exec(bContext *C, wmOperator *op) const eSelectOp sel_op = (eSelectOp)RNA_enum_get(op->ptr, "mode"); const bool select = (sel_op != SEL_OP_SUB); if (SEL_OP_USE_PRE_DESELECT(sel_op)) { - node_deselect_all(snode); + node_deselect_all(node_tree); } for (bNode *node : node_tree.all_nodes()) { @@ -855,7 +856,7 @@ static int node_circleselect_exec(bContext *C, wmOperator *op) { SpaceNode *snode = CTX_wm_space_node(C); ARegion *region = CTX_wm_region(C); - bNode *node; + bNodeTree &node_tree = *snode->edittree; int x, y, radius; float2 offset; @@ -867,7 +868,7 @@ static int node_circleselect_exec(bContext *C, wmOperator *op) WM_gesture_is_modal_first((const wmGesture *)op->customdata)); const bool select = (sel_op != SEL_OP_SUB); if (SEL_OP_USE_PRE_DESELECT(sel_op)) { - node_deselect_all(*snode); + node_deselect_all(node_tree); } /* get operator properties */ @@ -877,7 +878,7 @@ static int node_circleselect_exec(bContext *C, wmOperator *op) UI_view2d_region_to_view(®ion->v2d, x, y, &offset.x, &offset.y); - for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) { + for (bNode *node : node_tree.all_nodes()) { switch (node->type) { case NODE_FRAME: { /* Frame nodes are selectable by their borders (including their whole rect - as for other @@ -950,7 +951,7 @@ static bool do_lasso_select_node(bContext *C, eSelectOp sel_op) { SpaceNode *snode = CTX_wm_space_node(C); - bNode *node; + bNodeTree &node_tree = *snode->edittree; ARegion *region = CTX_wm_region(C); @@ -959,7 +960,7 @@ static bool do_lasso_select_node(bContext *C, const bool select = (sel_op != SEL_OP_SUB); if (SEL_OP_USE_PRE_DESELECT(sel_op)) { - node_deselect_all(*snode); + node_deselect_all(node_tree); changed = true; } @@ -967,8 +968,7 @@ static bool do_lasso_select_node(bContext *C, BLI_lasso_boundbox(&rect, mcoords, mcoords_len); /* do actual selection */ - for (node = (bNode *)snode->edittree->nodes.first; node; node = node->next) { - + for (bNode *node : node_tree.all_nodes()) { if (select && (node->flag & NODE_SELECT)) { continue; } @@ -1098,7 +1098,7 @@ static int node_select_all_exec(bContext *C, wmOperator *op) } break; case SEL_DESELECT: - node_deselect_all(snode); + node_deselect_all(node_tree); break; case SEL_INVERT: for (bNode *node : node_tree.all_nodes()) { @@ -1107,7 +1107,7 @@ static int node_select_all_exec(bContext *C, wmOperator *op) break; } - node_sort(*snode.edittree); + node_sort(node_tree); WM_event_add_notifier(C, NC_NODE | NA_SELECTED, nullptr); return OPERATOR_FINISHED; From 688086e01f2d7b53fa489e9f6c3dc63889e59f64 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 20 Dec 2022 17:19:47 -0600 Subject: [PATCH 0246/1522] Cleanup: Simplify node duplicate operator Use the map created for copying nodes more instead of iterating over all nodes unnecessarily a few times. Use the map empty check instead of a separate boolean variable. Use a utility function to retrieve a separate buffer of selected nodes in case the nodes by id Vector is reallocated (that part is technically a fix). --- .../blender/editors/space_node/node_edit.cc | 75 +++++++------------ 1 file changed, 27 insertions(+), 48 deletions(-) diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 7fdc2db9fdb..9bab9eaa2bf 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -40,7 +40,8 @@ #include "RE_pipeline.h" #include "ED_image.h" -#include "ED_node.h" /* own include */ +#include "ED_node.h" /* own include */ +#include "ED_node.hh" /* own include */ #include "ED_render.h" #include "ED_screen.h" #include "ED_select_utils.h" @@ -1313,7 +1314,7 @@ bool node_link_is_hidden_or_dimmed(const View2D &v2d, const bNodeLink &link) * \{ */ static void node_duplicate_reparent_recursive(bNodeTree *ntree, - const Map &node_map, + const Map &node_map, bNode *node) { bNode *parent; @@ -1344,42 +1345,32 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) const bool keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs"); bool linked = RNA_boolean_get(op->ptr, "linked") || ((U.dupflag & USER_DUP_NTREE) == 0); const bool dupli_node_tree = !linked; - bool changed = false; ED_preview_kill_jobs(CTX_wm_manager(C), bmain); - Map node_map; + Map node_map; Map socket_map; Map duplicated_node_groups; - bNode *lastnode = (bNode *)ntree->nodes.last; - for (bNode *node : ntree->all_nodes()) { - if (node->flag & SELECT) { - bNode *new_node = bke::node_copy_with_mapping( - ntree, *node, LIB_ID_COPY_DEFAULT, true, socket_map); - node_map.add_new(node, new_node); + for (bNode *node : get_selected_nodes(*ntree)) { + bNode *new_node = bke::node_copy_with_mapping( + ntree, *node, LIB_ID_COPY_DEFAULT, true, socket_map); + node_map.add_new(node, new_node); - if (node->id && dupli_node_tree) { - ID *new_group = duplicated_node_groups.lookup_or_add_cb(node->id, [&]() { - ID *new_group = BKE_id_copy(bmain, node->id); - /* Remove user added by copying. */ - id_us_min(new_group); - return new_group; - }); - id_us_plus(new_group); - id_us_min(new_node->id); - new_node->id = new_group; - } - changed = true; - } - - /* make sure we don't copy new nodes again! */ - if (node == lastnode) { - break; + if (node->id && dupli_node_tree) { + ID *new_group = duplicated_node_groups.lookup_or_add_cb(node->id, [&]() { + ID *new_group = BKE_id_copy(bmain, node->id); + /* Remove user added by copying. */ + id_us_min(new_group); + return new_group; + }); + id_us_plus(new_group); + id_us_min(new_node->id); + new_node->id = new_group; } } - if (!changed) { + if (node_map.is_empty()) { return OPERATOR_CANCELLED; } @@ -1424,32 +1415,20 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) node->flag &= ~NODE_TEST; } /* reparent copied nodes */ - for (bNode *node : ntree->all_nodes()) { - if ((node->flag & SELECT) && !(node->flag & NODE_TEST)) { + for (bNode *node : node_map.keys()) { + if (!(node->flag & NODE_TEST)) { node_duplicate_reparent_recursive(ntree, node_map, node); } - - /* only has to check old nodes */ - if (node == lastnode) { - break; - } } /* deselect old nodes, select the copies instead */ - for (bNode *node : ntree->all_nodes()) { - if (node->flag & SELECT) { - /* has been set during copy above */ - bNode *newnode = node_map.lookup(node); + for (const auto item : node_map.items()) { + bNode *src_node = item.key; + bNode *dst_node = item.value; - nodeSetSelected(node, false); - node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_TEXTURE); - nodeSetSelected(newnode, true); - } - - /* make sure we don't copy new nodes again! */ - if (node == lastnode) { - break; - } + nodeSetSelected(src_node, false); + src_node->flag &= ~(NODE_ACTIVE | NODE_ACTIVE_TEXTURE); + nodeSetSelected(dst_node, true); } ED_node_tree_propagate_change(C, bmain, snode->edittree); From 8fe1499796647d6d053a04158767c91f9f9f022d Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 20 Dec 2022 22:42:59 -0600 Subject: [PATCH 0247/1522] Cleanup: Use const arguments for node interface socket functions --- source/blender/blenkernel/BKE_node.h | 16 ++++++++-------- source/blender/blenkernel/intern/node.cc | 12 ++++++------ source/blender/makesrna/intern/rna_nodetree.c | 8 ++++---- source/blender/nodes/intern/node_socket.cc | 4 ++-- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 5a1198791fb..ff1128246f3 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -183,8 +183,8 @@ typedef struct bNodeSocketType { const char *data_path); void (*interface_from_socket)(struct bNodeTree *ntree, struct bNodeSocket *interface_socket, - struct bNode *node, - struct bNodeSocket *sock); + const struct bNode *node, + const struct bNodeSocket *sock); /* RNA integration */ ExtensionRNA ext_socket; @@ -563,17 +563,17 @@ struct bNodeSocket *ntreeInsertSocketInterface(struct bNodeTree *ntree, struct bNodeSocket *next_sock, const char *name); struct bNodeSocket *ntreeAddSocketInterfaceFromSocket(struct bNodeTree *ntree, - struct bNode *from_node, - struct bNodeSocket *from_sock); + const struct bNode *from_node, + const struct bNodeSocket *from_sock); struct bNodeSocket *ntreeAddSocketInterfaceFromSocketWithName(struct bNodeTree *ntree, - struct bNode *from_node, - struct bNodeSocket *from_sock, + const struct bNode *from_node, + const struct bNodeSocket *from_sock, const char *idname, const char *name); struct bNodeSocket *ntreeInsertSocketInterfaceFromSocket(struct bNodeTree *ntree, struct bNodeSocket *next_sock, - struct bNode *from_node, - struct bNodeSocket *from_sock); + const struct bNode *from_node, + const struct bNodeSocket *from_sock); void ntreeRemoveSocketInterface(struct bNodeTree *ntree, struct bNodeSocket *sock); /** \} */ diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 66c90745110..9488d3a40ef 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3388,16 +3388,16 @@ bNodeSocket *ntreeInsertSocketInterface(bNodeTree *ntree, } bNodeSocket *ntreeAddSocketInterfaceFromSocket(bNodeTree *ntree, - bNode *from_node, - bNodeSocket *from_sock) + const bNode *from_node, + const bNodeSocket *from_sock) { return ntreeAddSocketInterfaceFromSocketWithName( ntree, from_node, from_sock, from_sock->idname, from_sock->name); } bNodeSocket *ntreeAddSocketInterfaceFromSocketWithName(bNodeTree *ntree, - bNode *from_node, - bNodeSocket *from_sock, + const bNode *from_node, + const bNodeSocket *from_sock, const char *idname, const char *name) { @@ -3413,8 +3413,8 @@ bNodeSocket *ntreeAddSocketInterfaceFromSocketWithName(bNodeTree *ntree, bNodeSocket *ntreeInsertSocketInterfaceFromSocket(bNodeTree *ntree, bNodeSocket *next_sock, - bNode *from_node, - bNodeSocket *from_sock) + const bNode *from_node, + const bNodeSocket *from_sock) { bNodeSocket *iosock = ntreeInsertSocketInterface( ntree, diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 7e12483a543..fbc13229a3d 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2983,8 +2983,8 @@ static void rna_NodeSocketInterface_init_socket(bNodeTree *ntree, static void rna_NodeSocketInterface_from_socket(bNodeTree *ntree, bNodeSocket *interface_socket, - bNode *node, - bNodeSocket *sock) + const bNode *node, + const bNodeSocket *sock) { extern FunctionRNA rna_NodeSocketInterface_from_socket_func; @@ -2997,8 +2997,8 @@ static void rna_NodeSocketInterface_from_socket(bNodeTree *ntree, } RNA_pointer_create((ID *)ntree, &RNA_NodeSocketInterface, interface_socket, &ptr); - RNA_pointer_create((ID *)ntree, &RNA_Node, node, &node_ptr); - RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, sock, &sock_ptr); + RNA_pointer_create((ID *)ntree, &RNA_Node, (bNode *)node, &node_ptr); + RNA_pointer_create((ID *)ntree, &RNA_NodeSocket, (bNodeSocket *)sock, &sock_ptr); // RNA_struct_find_function(&ptr, "from_socket"); func = &rna_NodeSocketInterface_from_socket_func; diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index 02611bb675f..5098e55ea65 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -595,8 +595,8 @@ static void standard_node_socket_interface_verify_socket(bNodeTree * /*ntree*/, static void standard_node_socket_interface_from_socket(bNodeTree * /*ntree*/, bNodeSocket *stemp, - bNode * /*node*/, - bNodeSocket *sock) + const bNode * /*node*/, + const bNodeSocket *sock) { /* initialize settings */ stemp->type = stemp->typeinfo->type; From 908c539219c30238668e3d42d20fb1e1268bf95b Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 20 Dec 2022 22:51:13 -0600 Subject: [PATCH 0248/1522] Nodes: Add non-const access to cached group output node pointer --- source/blender/blenkernel/BKE_node_runtime.hh | 6 ++++++ source/blender/makesdna/DNA_node_types.h | 1 + 2 files changed, 7 insertions(+) diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 4ecc82b7fc3..2c9f05c08a6 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -417,6 +417,12 @@ inline bool bNodeTree::has_undefined_nodes_or_sockets() const return this->runtime->has_undefined_nodes_or_sockets; } +inline bNode *bNodeTree::group_output_node() +{ + BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this)); + return this->runtime->group_output_node; +} + inline const bNode *bNodeTree::group_output_node() const { BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this)); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 97505fdf5fe..5a50e53ba98 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -632,6 +632,7 @@ typedef struct bNodeTree { */ bool has_undefined_nodes_or_sockets() const; /** Get the active group output node. */ + bNode *group_output_node(); const bNode *group_output_node() const; /** Get all input nodes of the node group. */ blender::Span group_input_nodes() const; From fa3ca9afdb6f1ea1b709226af3f085133e5ddc2f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 21 Dec 2022 12:26:09 -0600 Subject: [PATCH 0249/1522] Nodes: Rewrite group creation operator Separate the "insert nodes into group" operation into more distinct phases. This helps to clarify what is actually happening, to avoid redundant updates to group nodes every time a new socket is discovered, and to make use of the topology cache to avoid the "accidentally quadratic" alrogithms that we have slowly been removing from node editing. The change is motivated by the desire to use dynamic node declarations for group nodes and group input/output nodes, where it is helpful to avoid updating the declaration and sockets multiple times. --- source/blender/blenkernel/intern/node.cc | 2 + .../blender/editors/space_node/node_group.cc | 452 +++++++++--------- source/blender/nodes/NOD_socket.h | 5 - source/blender/nodes/intern/node_socket.cc | 47 -- 4 files changed, 215 insertions(+), 291 deletions(-) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 9488d3a40ef..9fc2cbde1d5 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -2369,6 +2369,8 @@ bNodeLink *nodeAddLink( { BLI_assert(fromnode); BLI_assert(tonode); + BLI_assert(ntree->all_nodes().contains(fromnode)); + BLI_assert(ntree->all_nodes().contains(tonode)); bNodeLink *link = nullptr; if (fromsock->in_out == SOCK_OUT && tosock->in_out == SOCK_IN) { diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc index 6fb8ff54988..7666502b447 100644 --- a/source/blender/editors/space_node/node_group.cc +++ b/source/blender/editors/space_node/node_group.cc @@ -16,6 +16,7 @@ #include "BLI_listbase.h" #include "BLI_map.hh" #include "BLI_math_vec_types.hh" +#include "BLI_set.hh" #include "BLI_string.h" #include "BLI_vector.hh" @@ -726,71 +727,53 @@ static void get_min_max_of_nodes(const Span nodes, } /** - * Redirect a link that are connecting a non-selected node to selected one. - * Create new socket or reuse an existing one that was connected from the same input. + * Skip reroute nodes when finding the the socket to use as an example for a new group interface + * item. This moves "inward" into nodes selected for grouping to find properties like whether a + * connected socket has a hidden value. It only works in trivial situations-- a single line of + * connected reroutes with no branching. + */ +static const bNodeSocket &find_socket_to_use_for_interface(const bNodeTree &node_tree, + const bNodeSocket &socket) +{ + if (node_tree.has_available_link_cycle()) { + return socket; + } + const bNode &node = socket.owner_node(); + if (!node.is_reroute()) { + return socket; + } + const bNodeSocket &other_socket = socket.in_out == SOCK_IN ? node.output_socket(0) : + node.input_socket(0); + if (!other_socket.is_logically_linked()) { + return socket; + } + return *other_socket.logically_linked_sockets().first(); +} + +/** * The output sockets of group nodes usually have consciously given names so they have * precedence over socket names the link points to. - * - * \param ntree: The node tree that the node group is being created from. - * \param ngroup: The node tree of the new node group. - * \param gnode: The new group node in the original tree. - * \param input_node: The input node of the new node group. - * \param link: The incoming link that needs to be altered. - * \param reusable_sockets: Map for input socket interface lookup. */ -static void node_group_make_redirect_incoming_link( - bNodeTree &ntree, - bNodeTree *ngroup, - bNode *gnode, - bNode *input_node, - bNodeLink *link, - Map &reusable_sockets) +static bool prefer_node_for_interface_name(const bNode &node) { - bNodeSocket *input_socket = reusable_sockets.lookup_default(link->fromsock, nullptr); - if (input_socket) { - /* The incoming link is from a socket that has already been linked to - * a socket interface of the input node. - * Change the source of the link to the previously created socket interface. - * Move the link into the node tree of the new group. */ - link->fromnode = input_node; - link->fromsock = input_socket; - BLI_remlink(&ntree.links, link); - BLI_addtail(&ngroup->links, link); - } - else { - bNode *node_for_typeinfo = nullptr; - bNodeSocket *socket_for_typeinfo = nullptr; - /* Find a socket where typeinfo and name may come from. */ - node_socket_skip_reroutes( - &ntree.links, link->tonode, link->tosock, &node_for_typeinfo, &socket_for_typeinfo); - bNodeSocket *socket_for_naming = socket_for_typeinfo; + return node.is_group() || node.is_group_input() || node.is_group_output(); +} - /* Use the name of group node output sockets. */ - if (ELEM(link->fromnode->type, NODE_GROUP_INPUT, NODE_GROUP, NODE_CUSTOM_GROUP)) { - socket_for_naming = link->fromsock; - } - - bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocketWithName(ngroup, - node_for_typeinfo, - socket_for_typeinfo, - socket_for_naming->idname, - socket_for_naming->name); - - /* Update the group node and interface sockets so the new interface socket can be linked. */ - node_group_update(&ntree, gnode); - node_group_input_update(ngroup, input_node); - - /* Create new internal link. */ - bNodeSocket *input_sock = node_group_input_find_socket(input_node, iosock->identifier); - nodeAddLink(ngroup, input_node, input_sock, link->tonode, link->tosock); - - /* Redirect external link. */ - link->tonode = gnode; - link->tosock = node_group_find_input_socket(gnode, iosock->identifier); - - /* Remember which interface socket the link has been redirected to. */ - reusable_sockets.add_new(link->fromsock, input_sock); - } +static bNodeSocket *add_interface_from_socket(const bNodeTree &original_tree, + bNodeTree &tree_for_interface, + const bNodeSocket &socket) +{ + /* The "example socket" has to have the same `in_out` status as the new interface socket. */ + const bNodeSocket &socket_for_io = find_socket_to_use_for_interface(original_tree, socket); + const bNode &node_for_io = socket_for_io.owner_node(); + const bNodeSocket &socket_for_name = prefer_node_for_interface_name(socket.owner_node()) ? + socket : + socket_for_io; + return ntreeAddSocketInterfaceFromSocketWithName(&tree_for_interface, + &node_for_io, + &socket_for_io, + socket_for_io.idname, + socket_for_name.name); } static void node_group_make_insert_selected(const bContext &C, @@ -799,170 +782,160 @@ static void node_group_make_insert_selected(const bContext &C, const VectorSet &nodes_to_move) { Main *bmain = CTX_data_main(&C); - bNodeTree *ngroup = (bNodeTree *)gnode->id; + bNodeTree &group = *reinterpret_cast(gnode->id); BLI_assert(!nodes_to_move.contains(gnode)); - /* XXX rough guess, not nice but we don't have access to UI constants here ... */ - static const float offsetx = 200; - static const float offsety = 0.0f; + node_deselect_all(group); - node_deselect_all(*ngroup); - - /* auto-add interface for "solo" nodes */ - const bool expose_visible = nodes_to_move.size() == 1; - - float2 center, min, max; + float2 min, max; get_min_max_of_nodes(nodes_to_move, false, min, max); - add_v2_v2v2(center, min, max); - mul_v2_fl(center, 0.5f); + const float2 center = math::midpoint(min, max); float2 real_min, real_max; get_min_max_of_nodes(nodes_to_move, true, real_min, real_max); - ListBase anim_basepaths = {nullptr, nullptr}; - - /* Detach unselected nodes inside frames when the frame is put into the group. Otherwise the - * `parent` pointer becomes dangling. */ - for (bNode *node : ntree.all_nodes()) { - if (node->parent == nullptr) { - continue; + /* Reuse an existing output node or create a new one. */ + group.ensure_topology_cache(); + bNode *output_node = [&]() { + if (bNode *node = group.group_output_node()) { + return node; } - if (nodes_to_move.contains(node->parent) && !nodes_to_move.contains(node)) { + bNode *output_node = nodeAddStaticNode(&C, &group, NODE_GROUP_OUTPUT); + output_node->locx = real_max[0] - center[0] + 50.0f; + return output_node; + }(); + + /* Create new group input node for easier organization of the new nodes inside the group. */ + bNode *input_node = nodeAddStaticNode(&C, &group, NODE_GROUP_INPUT); + input_node->locx = real_min[0] - center[0] - 200.0f; + + struct InputSocketInfo { + /* The unselected node the original link came from. */ + bNode *from_node; + /* All the links that came from the socket on the unselected node. */ + Vector links; + const bNodeSocket *interface_socket; + }; + + struct OutputLinkInfo { + bNodeLink *link; + const bNodeSocket *interface_socket; + }; + + /* Map from single non-selected output sockets to potentially many selected input sockets. */ + Map input_links; + Vector output_links; + Set internal_links_to_move; + Set links_to_remove; + + ntree.ensure_topology_cache(); + for (bNode *node : nodes_to_move) { + for (bNodeSocket *input_socket : node->input_sockets()) { + for (bNodeLink *link : input_socket->directly_linked_links()) { + if (nodeLinkIsHidden(link)) { + links_to_remove.add(link); + continue; + } + if (nodes_to_move.contains(link->fromnode)) { + internal_links_to_move.add(link); + } + else { + InputSocketInfo &info = input_links.lookup_or_add_default(link->fromsock); + info.from_node = link->fromnode; + info.links.append(link); + if (!info.interface_socket) { + info.interface_socket = add_interface_from_socket(ntree, group, *link->tosock); + } + } + } + } + for (bNodeSocket *output_socket : node->output_sockets()) { + for (bNodeLink *link : output_socket->directly_linked_links()) { + if (nodeLinkIsHidden(link)) { + links_to_remove.add(link); + continue; + } + if (nodes_to_move.contains(link->tonode)) { + internal_links_to_move.add(link); + } + else { + output_links.append({link, add_interface_from_socket(ntree, group, *link->fromsock)}); + } + } + } + } + + struct NewInternalLinkInfo { + bNode *node; + bNodeSocket *socket; + const bNodeSocket *interface_socket; + }; + + const bool expose_visible = nodes_to_move.size() == 1; + Vector new_internal_links; + if (expose_visible) { + for (bNode *node : nodes_to_move) { + auto expose_sockets = [&](const Span sockets) { + for (bNodeSocket *socket : sockets) { + if (!socket->is_available() || socket->is_hidden()) { + continue; + } + if (socket->is_directly_linked()) { + continue; + } + const bNodeSocket *io_socket = ntreeAddSocketInterfaceFromSocket(&group, node, socket); + new_internal_links.append({node, socket, io_socket}); + } + }; + expose_sockets(node->input_sockets()); + expose_sockets(node->output_sockets()); + } + } + + /* Un-parent nodes when only the parent or child moves into the group. */ + for (bNode *node : ntree.all_nodes()) { + if (node->parent && nodes_to_move.contains(node->parent) && !nodes_to_move.contains(node)) { + nodeDetachNode(&ntree, node); + } + } + for (bNode *node : nodes_to_move) { + if (node->parent && !nodes_to_move.contains(node->parent)) { nodeDetachNode(&ntree, node); } } - /* move nodes over */ - for (bNode *node : nodes_to_move) { - /* Keep track of this node's RNA "base" path (the part of the pat identifying the node) - * if the old node-tree has animation data which potentially covers this node. */ - if (ntree.adt) { + /* Move animation data from the parent tree to the group. */ + if (ntree.adt) { + ListBase anim_basepaths = {nullptr, nullptr}; + for (bNode *node : nodes_to_move) { PointerRNA ptr; - char *path; - RNA_pointer_create(&ntree.id, &RNA_Node, node, &ptr); - path = RNA_path_from_ID_to_struct(&ptr); - - if (path) { + if (char *path = RNA_path_from_ID_to_struct(&ptr)) { BLI_addtail(&anim_basepaths, animation_basepath_change_new(path, path)); } } + BKE_animdata_transfer_by_basepath(bmain, &ntree.id, &group.id, &anim_basepaths); - /* ensure valid parent pointers, detach if parent stays outside the group */ - if (node->parent && !(node->parent->flag & NODE_SELECT)) { - nodeDetachNode(&ntree, node); - } - - /* change node-collection membership */ - BLI_remlink(&ntree.nodes, node); - BLI_addtail(&ngroup->nodes, node); - nodeUniqueID(ngroup, node); - nodeUniqueName(ngroup, node); - - BKE_ntree_update_tag_node_removed(&ntree); - BKE_ntree_update_tag_node_new(ngroup, node); - } - nodeRebuildIDVector(&ntree); - - /* move animation data over */ - if (ntree.adt) { - BKE_animdata_transfer_by_basepath(bmain, &ntree.id, &ngroup->id, &anim_basepaths); - - /* paths + their wrappers need to be freed */ LISTBASE_FOREACH_MUTABLE (AnimationBasePathChange *, basepath_change, &anim_basepaths) { animation_basepath_change_free(basepath_change); } } - /* create input node */ - bNode *input_node = nodeAddStaticNode(&C, ngroup, NODE_GROUP_INPUT); - input_node->locx = real_min[0] - center[0] - offsetx; - input_node->locy = -offsety; + /* Move nodes into the group. */ + for (bNode *node : nodes_to_move) { + BLI_remlink(&ntree.nodes, node); + BLI_addtail(&group.nodes, node); + nodeUniqueID(&group, node); + nodeUniqueName(&group, node); - /* create output node */ - bNode *output_node = nodeAddStaticNode(&C, ngroup, NODE_GROUP_OUTPUT); - output_node->locx = real_max[0] - center[0] + offsetx * 0.25f; - output_node->locy = -offsety; - - /* relink external sockets */ - - /* A map from link sources to input sockets already connected. */ - Map reusable_sockets; - - LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) { - const bool fromselect = nodes_to_move.contains(link->fromnode); - const bool toselect = nodes_to_move.contains(link->tonode); - - if ((fromselect && link->tonode == gnode) || (toselect && link->fromnode == gnode)) { - /* remove all links to/from the gnode. - * this can remove link information, but there's no general way to preserve it. - */ - nodeRemLink(&ntree, link); - } - else if (toselect && !fromselect) { - /* Remove hidden links to not create unconnected sockets in the interface. */ - if (nodeLinkIsHidden(link)) { - nodeRemLink(&ntree, link); - continue; - } - - node_group_make_redirect_incoming_link( - ntree, ngroup, gnode, input_node, link, reusable_sockets); - } - else if (fromselect && !toselect) { - /* Remove hidden links to not create unconnected sockets in the interface. */ - if (nodeLinkIsHidden(link)) { - nodeRemLink(&ntree, link); - continue; - } - - /* First check whether the source of this link is already connected to an output. - * If yes, reuse that output instead of duplicating it. */ - bool connected = false; - LISTBASE_FOREACH (bNodeLink *, olink, &ngroup->links) { - if (olink->fromsock == link->fromsock && olink->tonode == output_node) { - bNodeSocket *output_sock = node_group_find_output_socket(gnode, - olink->tosock->identifier); - link->fromnode = gnode; - link->fromsock = output_sock; - connected = true; - } - } - - if (!connected) { - bNodeSocket *link_sock; - bNode *link_node; - node_socket_skip_reroutes( - &ntree.links, link->fromnode, link->fromsock, &link_node, &link_sock); - bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, link_node, link_sock); - - /* update the group node and interface node sockets, - * so the new interface socket can be linked. - */ - node_group_update(&ntree, gnode); - node_group_output_update(ngroup, output_node); - - /* create new internal link */ - bNodeSocket *output_sock = node_group_output_find_socket(output_node, iosock->identifier); - nodeAddLink(ngroup, link->fromnode, link->fromsock, output_node, output_sock); - - /* redirect external link */ - link->fromnode = gnode; - link->fromsock = node_group_find_output_socket(gnode, iosock->identifier); - } - } + BKE_ntree_update_tag_node_removed(&ntree); + BKE_ntree_update_tag_node_new(&group, node); } + nodeRebuildIDVector(&ntree); - /* move internal links */ - LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) { - const bool fromselect = nodes_to_move.contains(link->fromnode); - const bool toselect = nodes_to_move.contains(link->tonode); - - if (fromselect && toselect) { - BLI_remlink(&ntree.links, link); - BLI_addtail(&ngroup->links, link); - } - } + node_group_update(&ntree, gnode); + node_group_input_update(&group, input_node); + node_group_output_update(&group, output_node); /* move nodes in the group to the center */ for (bNode *node : nodes_to_move) { @@ -972,55 +945,56 @@ static void node_group_make_insert_selected(const bContext &C, } } - /* Expose all unlinked sockets too but only the visible ones. */ - if (expose_visible) { - for (bNode *node : nodes_to_move) { - LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { - bool skip = false; - LISTBASE_FOREACH (bNodeLink *, link, &ngroup->links) { - if (link->tosock == sock) { - skip = true; - break; - } - } - if (sock->flag & (SOCK_HIDDEN | SOCK_UNAVAIL)) { - skip = true; - } - if (skip) { - continue; - } + for (bNodeLink *link : internal_links_to_move) { + BLI_remlink(&ntree.links, link); + BLI_addtail(&group.links, link); + BKE_ntree_update_tag_link_removed(&ntree); + BKE_ntree_update_tag_link_added(&group, link); + } - bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, node, sock); + for (bNodeLink *link : links_to_remove) { + nodeRemLink(&ntree, link); + } - node_group_input_update(ngroup, input_node); + for (const auto item : input_links.items()) { + const char *interface_identifier = item.value.interface_socket->identifier; + bNodeSocket *input_socket = node_group_input_find_socket(input_node, interface_identifier); - /* create new internal link */ - bNodeSocket *input_sock = node_group_input_find_socket(input_node, iosock->identifier); - nodeAddLink(ngroup, input_node, input_sock, node, sock); - } + for (bNodeLink *link : item.value.links) { + /* Move the link into the new group, connected from the input node to the original socket. */ + BLI_remlink(&ntree.links, link); + BLI_addtail(&group.links, link); + BKE_ntree_update_tag_link_removed(&ntree); + BKE_ntree_update_tag_link_added(&group, link); + link->fromnode = input_node; + link->fromsock = input_socket; + } - LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { - bool skip = false; - LISTBASE_FOREACH (bNodeLink *, link, &ngroup->links) { - if (link->fromsock == sock) { - skip = true; - } - } - if (sock->flag & (SOCK_HIDDEN | SOCK_UNAVAIL)) { - skip = true; - } - if (skip) { - continue; - } + /* Add a new link outside of the group. */ + bNodeSocket *group_node_socket = node_group_find_input_socket(gnode, interface_identifier); + nodeAddLink(&ntree, item.value.from_node, item.key, gnode, group_node_socket); + } - bNodeSocket *iosock = ntreeAddSocketInterfaceFromSocket(ngroup, node, sock); + for (const OutputLinkInfo &info : output_links) { + /* Create a new link inside of the group. */ + const char *io_identifier = info.interface_socket->identifier; + bNodeSocket *output_sock = node_group_output_find_socket(output_node, io_identifier); + nodeAddLink(&group, info.link->fromnode, info.link->fromsock, output_node, output_sock); - node_group_output_update(ngroup, output_node); + /* Reconnect the link to the group node instead of the node now inside the group. */ + info.link->fromnode = gnode; + info.link->fromsock = node_group_find_output_socket(gnode, io_identifier); + } - /* create new internal link */ - bNodeSocket *output_sock = node_group_output_find_socket(output_node, iosock->identifier); - nodeAddLink(ngroup, node, sock, output_node, output_sock); - } + for (const NewInternalLinkInfo &info : new_internal_links) { + const char *io_identifier = info.interface_socket->identifier; + if (info.socket->in_out == SOCK_IN) { + bNodeSocket *input_socket = node_group_input_find_socket(input_node, io_identifier); + nodeAddLink(&group, input_node, input_socket, info.node, info.socket); + } + else { + bNodeSocket *output_socket = node_group_output_find_socket(output_node, io_identifier); + nodeAddLink(&group, info.node, info.socket, output_node, output_socket); } } } diff --git a/source/blender/nodes/NOD_socket.h b/source/blender/nodes/NOD_socket.h index e4f675135bd..b456797031c 100644 --- a/source/blender/nodes/NOD_socket.h +++ b/source/blender/nodes/NOD_socket.h @@ -31,11 +31,6 @@ void node_verify_sockets(struct bNodeTree *ntree, struct bNode *node, bool do_id void node_socket_init_default_value(struct bNodeSocket *sock); void node_socket_copy_default_value(struct bNodeSocket *to, const struct bNodeSocket *from); -void node_socket_skip_reroutes(struct ListBase *links, - struct bNode *node, - struct bNodeSocket *socket, - struct bNode **r_node, - struct bNodeSocket **r_socket); void register_standard_node_socket_types(void); #ifdef __cplusplus diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index 5098e55ea65..e179740aafb 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -482,53 +482,6 @@ void node_socket_copy_default_value(bNodeSocket *to, const bNodeSocket *from) to->flag |= (from->flag & SOCK_HIDE_VALUE); } -void node_socket_skip_reroutes( - ListBase *links, bNode *node, bNodeSocket *socket, bNode **r_node, bNodeSocket **r_socket) -{ - const int loop_limit = 100; /* Limit in case there is a connection cycle. */ - - if (socket->in_out == SOCK_IN) { - bNodeLink *first_link = (bNodeLink *)links->first; - - for (int i = 0; node->type == NODE_REROUTE && i < loop_limit; i++) { - bNodeLink *link = first_link; - - for (; link; link = link->next) { - if (link->fromnode == node && link->tonode != node) { - break; - } - } - - if (link) { - node = link->tonode; - socket = link->tosock; - } - else { - break; - } - } - } - else { - for (int i = 0; node->type == NODE_REROUTE && i < loop_limit; i++) { - bNodeSocket *input = (bNodeSocket *)node->inputs.first; - - if (input && input->link) { - node = input->link->fromnode; - socket = input->link->fromsock; - } - else { - break; - } - } - } - - if (r_node) { - *r_node = node; - } - if (r_socket) { - *r_socket = socket; - } -} static void standard_node_socket_interface_init_socket(bNodeTree * /*ntree*/, const bNodeSocket *interface_socket, From b492dc3579c10eddcbdb46edff4e37dc8aed193f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 21 Dec 2022 13:10:51 -0600 Subject: [PATCH 0250/1522] Cleanup: Remove unused modifier and BMesh includes --- source/blender/editors/sculpt_paint/sculpt_boundary.c | 2 -- source/blender/editors/sculpt_paint/sculpt_filter_color.c | 2 -- .../blender/io/wavefront_obj/exporter/obj_export_mesh.cc | 3 +++ .../blender/io/wavefront_obj/exporter/obj_export_mesh.hh | 3 --- source/blender/makesrna/intern/rna_sculpt_paint.c | 2 -- source/blender/modifiers/intern/MOD_armature.c | 3 --- source/blender/modifiers/intern/MOD_mirror.cc | 8 -------- source/blender/modifiers/intern/MOD_simpledeform.c | 4 +--- source/blender/modifiers/intern/MOD_util.cc | 1 - source/blender/modifiers/intern/MOD_weighted_normal.cc | 2 +- source/blender/modifiers/intern/MOD_weld.cc | 4 ---- 11 files changed, 5 insertions(+), 29 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c index 355f260ae11..2bf6110dca0 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.c +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c @@ -28,8 +28,6 @@ #include "GPU_immediate.h" #include "GPU_state.h" -#include "bmesh.h" - #include #include diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c index 89cb67a875f..e222e0d917f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c @@ -30,8 +30,6 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "bmesh.h" - #include #include diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc index 181180267db..e0a5811ae76 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc @@ -27,6 +27,9 @@ #include "obj_export_mesh.hh" +#include "bmesh.h" +#include "bmesh_tools.h" + namespace blender::io::obj { OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Object *mesh_object) { diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh index b74dca4a47e..9869469e616 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh @@ -12,9 +12,6 @@ #include "BLI_utility_mixins.hh" #include "BLI_vector.hh" -#include "bmesh.h" -#include "bmesh_tools.h" - #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index c5e7c6a6e91..a57f3c5a1a6 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -32,8 +32,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "bmesh.h" - extern const EnumPropertyItem RNA_automasking_flags[]; const EnumPropertyItem rna_enum_particle_edit_hair_brush_items[] = { diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 8e627f9964d..e8aac290dd5 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -40,9 +40,6 @@ #include "DEG_depsgraph_query.h" -#include "bmesh.h" -#include "bmesh_tools.h" - #include "MEM_guardedalloc.h" #include "MOD_ui_common.h" diff --git a/source/blender/modifiers/intern/MOD_mirror.cc b/source/blender/modifiers/intern/MOD_mirror.cc index 9e99a6b9a5e..ca65afb7176 100644 --- a/source/blender/modifiers/intern/MOD_mirror.cc +++ b/source/blender/modifiers/intern/MOD_mirror.cc @@ -5,21 +5,16 @@ * \ingroup modifiers */ -#include "BLI_math.h" - #include "BLT_translation.h" #include "DNA_defaults.h" #include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_screen_types.h" #include "BKE_context.h" -#include "BKE_deform.h" #include "BKE_lib_id.h" #include "BKE_lib_query.h" -#include "BKE_mesh.h" #include "BKE_mesh_mirror.h" #include "BKE_modifier.h" #include "BKE_screen.h" @@ -30,9 +25,6 @@ #include "RNA_access.h" #include "RNA_prototypes.h" -#include "bmesh.h" -#include "bmesh_tools.h" - #include "MEM_guardedalloc.h" #include "DEG_depsgraph_build.h" diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 0de89850bc9..c08853d06a7 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -5,7 +5,7 @@ * \ingroup modifiers */ -#include "BLI_math.h" +#include "BLI_math_vector.h" #include "BLI_task.h" #include "BLI_utildefines.h" #include "BLT_translation.h" @@ -37,8 +37,6 @@ #include "MOD_ui_common.h" #include "MOD_util.h" -#include "bmesh.h" - #define BEND_EPS 0.000001f ALIGN_STRUCT struct DeformUserData { diff --git a/source/blender/modifiers/intern/MOD_util.cc b/source/blender/modifiers/intern/MOD_util.cc index a94fc6732a0..6b7072db121 100644 --- a/source/blender/modifiers/intern/MOD_util.cc +++ b/source/blender/modifiers/intern/MOD_util.cc @@ -40,7 +40,6 @@ #include "MEM_guardedalloc.h" -#include "bmesh.h" void MOD_init_texture(MappingInfoModifierData *dmd, const ModifierEvalContext *ctx) { diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.cc b/source/blender/modifiers/intern/MOD_weighted_normal.cc index 76d8d27b899..2f68f00ce07 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.cc +++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc @@ -8,7 +8,7 @@ #include "BLI_bitmap.h" #include "BLI_linklist.h" -#include "BLI_math.h" +#include "BLI_math_vector.h" #include "BLT_translation.h" diff --git a/source/blender/modifiers/intern/MOD_weld.cc b/source/blender/modifiers/intern/MOD_weld.cc index bbd440f377e..dc9d361c838 100644 --- a/source/blender/modifiers/intern/MOD_weld.cc +++ b/source/blender/modifiers/intern/MOD_weld.cc @@ -28,10 +28,6 @@ #include "DNA_modifier_types.h" #include "DNA_screen_types.h" -#ifdef USE_BVHTREEKDOP -# include "BKE_bvhutils.h" -#endif - #include "BKE_context.h" #include "BKE_deform.h" #include "BKE_modifier.h" From f4b03031e84f727df6eb21c28125b3a4ef98f1c0 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Wed, 21 Dec 2022 20:54:36 +0100 Subject: [PATCH 0251/1522] GPU: Select GPU Backend from Preferences. (MacOS) only: In the System tab of the user preferences the user has the ability to select a GPU backend that Blender will use. After changing the GPU backend setting, the user has to restart Blender before the setting is used. It was added to start collecting feedback on the Metal backend without using the command lines. By default Blender will select OpenGL as backend. When Metal is selected (via `--gpu-backend metal` or via user preferences) OpenGL will be used as fallback when the platform isn't capable of running Metal. --- release/datafiles/userdef/userdef_default.c | 3 ++ .../scripts/startup/bl_ui/space_userpref.py | 22 ++++++++ .../blender/blenkernel/BKE_blender_version.h | 2 +- source/blender/blenloader/CMakeLists.txt | 1 + .../blenloader/intern/versioning_userdef.c | 7 +++ source/blender/gpu/GPU_context.h | 24 +++++++++ source/blender/gpu/intern/gpu_context.cc | 50 ++++++++++++++++++- source/blender/makesdna/DNA_userdef_types.h | 5 +- source/blender/makesrna/intern/rna_userdef.c | 46 +++++++++++++++++ .../blender/windowmanager/intern/wm_files.c | 16 ++++++ source/creator/creator_args.c | 6 +-- 11 files changed, 174 insertions(+), 8 deletions(-) diff --git a/release/datafiles/userdef/userdef_default.c b/release/datafiles/userdef/userdef_default.c index b4a1ab6d5f8..24e093833c4 100644 --- a/release/datafiles/userdef/userdef_default.c +++ b/release/datafiles/userdef/userdef_default.c @@ -14,6 +14,8 @@ #include "BKE_blender_version.h" +#include "GPU_platform.h" + #include "BLO_readfile.h" /* own include */ const UserDef U_default = { @@ -99,6 +101,7 @@ const UserDef U_default = { .gp_euclideandist = 2, .gp_eraser = 25, .gp_settings = 0, + .gpu_backend = GPU_BACKEND_OPENGL, /** Initialized by: #BKE_studiolight_default. */ .light_param = {{0}}, diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 759b222c562..44bc807c7dd 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -604,6 +604,27 @@ class USERPREF_PT_system_cycles_devices(SystemPanel, CenterAlignMixIn, Panel): del addon +class USERPREF_PT_system_gpu_backend(SystemPanel, CenterAlignMixIn, Panel): + bl_label = "GPU Backend" + + @classmethod + def poll(cls, _context): + # Only for Apple so far + import sys + return sys.platform == "darwin" + + def draw_centered(self, context, layout): + import gpu + prefs = context.preferences + system = prefs.system + + col = layout.column() + col.prop(system, "gpu_backend") + + if system.gpu_backend != gpu.platform.backend_type_get(): + layout.label(text="Requires a restart of Blender to take effect.", icon='INFO') + + class USERPREF_PT_system_os_settings(SystemPanel, CenterAlignMixIn, Panel): bl_label = "Operating System Settings" @@ -2406,6 +2427,7 @@ classes = ( USERPREF_PT_animation_fcurves, USERPREF_PT_system_cycles_devices, + USERPREF_PT_system_gpu_backend, USERPREF_PT_system_os_settings, USERPREF_PT_system_memory, USERPREF_PT_system_video_sequencer, diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 91a458e347f..7c241a4fa12 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,7 +25,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 4 +#define BLENDER_FILE_SUBVERSION 5 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index 86793d38b0b..a7e99e7df2e 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -10,6 +10,7 @@ set(INC ../depsgraph ../draw ../editors/include + ../gpu ../imbuf ../makesdna ../makesrna diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c index b4890131861..10a21356c8f 100644 --- a/source/blender/blenloader/intern/versioning_userdef.c +++ b/source/blender/blenloader/intern/versioning_userdef.c @@ -31,6 +31,8 @@ #include "BLO_readfile.h" +#include "GPU_platform.h" + #include "readfile.h" /* Own include. */ #include "WM_types.h" @@ -766,6 +768,11 @@ void blo_do_versions_userdef(UserDef *userdef) userdef->dupflag |= USER_DUP_CURVES | USER_DUP_POINTCLOUD; } + /* Set GPU backend to OpenGL. */ + if (!USER_VERSION_ATLEAST(305, 5)) { + userdef->gpu_backend = GPU_BACKEND_OPENGL; + } + /** * Versioning code until next subversion bump goes here. * diff --git a/source/blender/gpu/GPU_context.h b/source/blender/gpu/GPU_context.h index ac82774039a..fd20283380f 100644 --- a/source/blender/gpu/GPU_context.h +++ b/source/blender/gpu/GPU_context.h @@ -25,6 +25,30 @@ void GPU_backend_type_selection_set(const eGPUBackendType backend); eGPUBackendType GPU_backend_type_selection_get(void); eGPUBackendType GPU_backend_get_type(void); +/** + * Detect the most suited eGPUBackendType. + * + * - The detected backend will be set in `GPU_backend_type_selection_set`. + * - When GPU_backend_type_selection_is_overridden it checks the overridden backend. + * When not overridden it checks a default list. + * - OpenGL backend will be checked as fallback for Metal. + * + * Returns true when detection found a supported backend, otherwise returns false. + * When no supported backend is found GPU_backend_type_selection_set is called with + * GPU_BACKEND_NONE. + */ +bool GPU_backend_type_selection_detect(void); + +/** + * Alter the GPU_backend_type_selection_detect to only test a specific backend + */ +void GPU_backend_type_selection_set_override(eGPUBackendType backend_type); + +/** + * Check if the GPU_backend_type_selection_detect is overridden to only test a specific backend. + */ +bool GPU_backend_type_selection_is_overridden(void); + /** Opaque type hiding blender::gpu::Context. */ typedef struct GPUContext GPUContext; diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc index 0443417a32a..101542802e6 100644 --- a/source/blender/gpu/intern/gpu_context.cc +++ b/source/blender/gpu/intern/gpu_context.cc @@ -227,11 +227,14 @@ void GPU_render_step() * Until a global switch is added, Metal also needs to be enabled in GHOST_ContextCGL: * `m_useMetalForRendering = true`. */ static eGPUBackendType g_backend_type = GPU_BACKEND_OPENGL; +static std::optional g_backend_type_override = std::nullopt; +static std::optional g_backend_type_supported = std::nullopt; static GPUBackend *g_backend = nullptr; void GPU_backend_type_selection_set(const eGPUBackendType backend) { g_backend_type = backend; + g_backend_type_supported = std::nullopt; } eGPUBackendType GPU_backend_type_selection_get() @@ -239,7 +242,44 @@ eGPUBackendType GPU_backend_type_selection_get() return g_backend_type; } -bool GPU_backend_supported(void) +void GPU_backend_type_selection_set_override(const eGPUBackendType backend_type) +{ + g_backend_type_override = backend_type; +} + +bool GPU_backend_type_selection_is_overridden(void) +{ + return g_backend_type_override.has_value(); +} + +bool GPU_backend_type_selection_detect(void) +{ + blender::Vector backends_to_check; + if (GPU_backend_type_selection_is_overridden()) { + backends_to_check.append(*g_backend_type_override); + } + else { + backends_to_check.append(GPU_BACKEND_OPENGL); + } + + /* Add fallback to OpenGL when Metal backend is requested on a platform that doens't support + * metal. */ + if (backends_to_check[0] == GPU_BACKEND_METAL) { + backends_to_check.append(GPU_BACKEND_OPENGL); + } + + for (const eGPUBackendType backend_type : backends_to_check) { + GPU_backend_type_selection_set(backend_type); + if (GPU_backend_supported()) { + return true; + } + } + + GPU_backend_type_selection_set(GPU_BACKEND_NONE); + return false; +} + +static bool gpu_backend_supported() { switch (g_backend_type) { case GPU_BACKEND_OPENGL: @@ -266,6 +306,14 @@ bool GPU_backend_supported(void) } } +bool GPU_backend_supported() +{ + if (!g_backend_type_supported.has_value()) { + g_backend_type_supported = gpu_backend_supported(); + } + return *g_backend_type_supported; +} + static void gpu_backend_create() { BLI_assert(g_backend == nullptr); diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 8a644803fd7..18c4508efae 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -828,7 +828,10 @@ typedef struct UserDef { /** Seconds to zoom around current frame. */ float view_frame_seconds; - char _pad7[6]; + /** #eGPUBackendType */ + short gpu_backend; + + char _pad7[4]; /** Private, defaults to 20 for 72 DPI setting. */ short widget_unit; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index b93983d0a87..db12ac82f38 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -29,6 +29,8 @@ #include "RNA_define.h" #include "RNA_enum_types.h" +#include "GPU_platform.h" + #include "UI_interface_icons.h" #include "rna_internal.h" @@ -138,6 +140,13 @@ static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = { {0, NULL, 0, NULL, NULL}, }; +const EnumPropertyItem rna_enum_preference_gpu_backend_items[] = { + {GPU_BACKEND_OPENGL, "OPENGL", 0, "OpenGL", "Use OpenGL backend"}, + {GPU_BACKEND_METAL, "METAL", 0, "Metal", "Use Metal backend"}, + {GPU_BACKEND_VULKAN, "VULKAN", 0, "Vulkan", "Use Vulkan backend"}, + {0, NULL, 0, NULL, NULL}, +}; + #ifdef RNA_RUNTIME # include "BLI_math_vector.h" @@ -1031,6 +1040,33 @@ int rna_show_statusbar_vram_editable(struct PointerRNA *UNUSED(ptr), const char return GPU_mem_stats_supported() ? PROP_EDITABLE : 0; } +static const EnumPropertyItem *rna_preference_gpu_backend_itemf(struct bContext *UNUSED(C), + PointerRNA *UNUSED(ptr), + PropertyRNA *UNUSED(prop), + bool *r_free) +{ + int totitem = 0; + EnumPropertyItem *result = NULL; + for (int i = 0; rna_enum_preference_gpu_backend_items[i].identifier != NULL; i++) { + const EnumPropertyItem *item = &rna_enum_preference_gpu_backend_items[i]; +# ifndef WITH_METAL_BACKEND + if (item->value == GPU_BACKEND_METAL) { + continue; + } +# endif +# ifndef WITH_VULKAN_BACKEND + if (item->value == GPU_BACKEND_VULKAN) { + continue; + } +# endif + RNA_enum_item_add(&result, &totitem, item); + } + + RNA_enum_item_end(&result, &totitem); + *r_free = true; + return result; +} + #else # define USERDEF_TAG_DIRTY_PROPERTY_UPDATE_ENABLE \ @@ -5604,6 +5640,16 @@ static void rna_def_userdef_system(BlenderRNA *brna) "modifiers in the stack"); RNA_def_property_update(prop, 0, "rna_UserDef_subdivision_update"); + /* GPU backend selection */ + prop = RNA_def_property(srna, "gpu_backend", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "gpu_backend"); + RNA_def_property_enum_items(prop, rna_enum_preference_gpu_backend_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_preference_gpu_backend_itemf"); + RNA_def_property_ui_text( + prop, + "GPU Backend", + "GPU backend to use. (Requires restarting Blender for changes to take effect)"); + /* Audio */ prop = RNA_def_property(srna, "audio_mixing_buffer", PROP_ENUM, PROP_NONE); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 7b1fcf2a231..712bee6ef8b 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -107,6 +107,8 @@ #include "GHOST_C-api.h" #include "GHOST_Path-api.h" +#include "GPU_context.h" + #include "UI_interface.h" #include "UI_resources.h" #include "UI_view2d.h" @@ -442,6 +444,17 @@ static void wm_window_match_do(bContext *C, /** \name Preferences Initialization & Versioning * \{ */ +static void wm_gpu_backend_override_from_userdef(void) +{ + /* Check if GPU backend is already set from the command line arguments. The command line + * arguments have higher priority than user preferences. */ + if (GPU_backend_type_selection_is_overridden()) { + return; + } + + GPU_backend_type_selection_set_override(U.gpu_backend); +} + /** * In case #UserDef was read, re-initialize values that depend on it. */ @@ -475,6 +488,9 @@ static void wm_init_userdef(Main *bmain) WM_init_input_devices(); BLO_sanitize_experimental_features_userpref_blend(&U); + + wm_gpu_backend_override_from_userdef(); + GPU_backend_type_selection_detect(); } /* return codes */ diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index 2ebdcdb35ba..e942c0d18ee 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -1150,11 +1150,7 @@ static int arg_handle_gpu_backend_set(int argc, const char **argv, void *UNUSED( return 0; } - GPU_backend_type_selection_set(gpu_backend); - if (!GPU_backend_supported()) { - printf("\nError: GPU backend not supported.\n"); - return 0; - } + GPU_backend_type_selection_set_override(gpu_backend); return 1; } From b62148365996afe177a7c1b732f0167a920e16a4 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Wed, 21 Dec 2022 21:19:23 +0100 Subject: [PATCH 0252/1522] GPU: Fix incorrect attribute usage in vk_shader. Detected when reviewing the code. Just wanted it to be in master before holiday season starts. --- source/blender/gpu/vulkan/vk_shader.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/vulkan/vk_shader.cc b/source/blender/gpu/vulkan/vk_shader.cc index 40408759679..cf05cf13d23 100644 --- a/source/blender/gpu/vulkan/vk_shader.cc +++ b/source/blender/gpu/vulkan/vk_shader.cc @@ -610,7 +610,7 @@ void VKShader::build_shader_module(MutableSpan sources, "Only forced ShaderC shader kinds are supported."); sources[0] = glsl_patch_get(); Vector spirv_module = compile_glsl_to_spirv(sources, stage); - build_shader_module(spirv_module, &compute_module_); + build_shader_module(spirv_module, r_shader_module); } void VKShader::vertex_shader_from_glsl(MutableSpan sources) @@ -674,7 +674,7 @@ bool VKShader::finalize(const shader::ShaderCreateInfo * /*info*/) VkPipelineShaderStageCreateInfo compute_stage_info = {}; compute_stage_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; compute_stage_info.stage = VK_SHADER_STAGE_GEOMETRY_BIT; - compute_stage_info.module = geometry_module_; + compute_stage_info.module = compute_module_; compute_stage_info.pName = "main"; pipeline_infos_.append(compute_stage_info); } From cef5841e124b8f1667d96b8338e6e2ac85d7c4c6 Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Wed, 21 Dec 2022 13:25:02 -0700 Subject: [PATCH 0253/1522] Cmake: Fix building with WITH_WINDOWS_BUNDLE_CRT Off When building without WITH_WINDOWS_BUNDLE_CRT the manifest did not contain the blender.shared dependentAssembly leading to missing dll errors at blender startup. --- build_files/cmake/platform/platform_win32.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake index da418a27274..82bfa53b5a3 100644 --- a/build_files/cmake/platform/platform_win32.cmake +++ b/build_files/cmake/platform/platform_win32.cmake @@ -140,8 +140,8 @@ if(WITH_WINDOWS_BUNDLE_CRT) install(FILES ${CMAKE_BINARY_DIR}/blender.crt.manifest DESTINATION ./blender.crt) set(BUNDLECRT "") - set(BUNDLECRT "${BUNDLECRT}") endif() +set(BUNDLECRT "${BUNDLECRT}") configure_file(${CMAKE_SOURCE_DIR}/release/windows/manifest/blender.exe.manifest.in ${CMAKE_CURRENT_BINARY_DIR}/blender.exe.manifest @ONLY) From 0bcfe2788df225ae948c31815535532a8b02b894 Mon Sep 17 00:00:00 2001 From: Amelie Fondevilla Date: Wed, 21 Dec 2022 11:54:44 +0100 Subject: [PATCH 0254/1522] Fix T103376: Grease pencil frames selected from python are not updated in the dopesheet Differential Revision: https://developer.blender.org/D16832 --- source/blender/makesrna/intern/rna_gpencil.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index cf02b8fe61c..a9dc4f4dc12 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -1825,6 +1825,7 @@ static void rna_def_gpencil_frame(BlenderRNA *brna) prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_FRAME_SELECT); RNA_def_property_ui_text(prop, "Select", "Frame is selected for editing in the Dope Sheet"); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); /* API */ func = RNA_def_function(srna, "clear", "rna_GPencil_frame_clear"); From b617ddc0049e5af4477af8a8cd45aa2a5692bcf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 22 Dec 2022 11:10:35 +0100 Subject: [PATCH 0255/1522] Anim: rearrange the motion paths panel Move the "Calculation Range" property above the "Frame Range" properties, as you have to select the former before adjusting the latter. --- release/scripts/startup/bl_ui/properties_animviz.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py index aa16a7c9bb8..131f7cba2b8 100644 --- a/release/scripts/startup/bl_ui/properties_animviz.py +++ b/release/scripts/startup/bl_ui/properties_animviz.py @@ -18,13 +18,15 @@ class MotionPathButtonsPanel: mps = avs.motion_path - # Display Range layout.use_property_split = True layout.use_property_decorate = False - # Display Range col = layout.column(align=True) col.prop(mps, "type") + range_group = col.column(align=True) + range_group.active = mps.type == 'RANGE' + range_group.prop(mps, "range", text="Calculation Range") + if mps.type == 'CURRENT_FRAME': col = layout.column(align=True) col.prop(mps, "frame_before", text="Frame Range Before") @@ -38,10 +40,6 @@ class MotionPathButtonsPanel: start_end_group.prop(mps, "frame_end", text="End") col.prop(mps, "frame_step", text="Step") - # Calculation Range - col = layout.column(align=True) - col.prop(mps, "range", text="Calculation Range") - if mpath: col = layout.column(align=True) row = col.row(align=True) From e4e17cf1dfc036ab3061afd8ed18cded28b0fd01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 22 Dec 2022 12:08:56 +0100 Subject: [PATCH 0256/1522] Anim: change wording of Clear Motion Paths operator Change the wording of `OBJECT_OT_paths_clear` and `POSE_OT_paths_clear` tooltips, so that they mention "motion path" instead of "path cache". --- source/blender/editors/armature/pose_edit.c | 9 ++++++--- source/blender/editors/object/object_edit.c | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index 14cd731f142..e11558722af 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -441,7 +441,7 @@ void POSE_OT_paths_clear(wmOperatorType *ot) /* identifiers */ ot->name = "Clear Bone Paths"; ot->idname = "POSE_OT_paths_clear"; - ot->description = "Clear path caches for all bones, hold Shift key for selected bones only"; + ot->description = "Clear motion paths for all bones, hold Shift key for selected bones only"; /* api callbacks */ ot->invoke = pose_clear_paths_invoke; @@ -452,8 +452,11 @@ void POSE_OT_paths_clear(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = RNA_def_boolean( - ot->srna, "only_selected", false, "Only Selected", "Only clear paths from selected bones"); + ot->prop = RNA_def_boolean(ot->srna, + "only_selected", + false, + "Only Selected", + "Only clear motion paths of selected bones"); RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index bc4e5668b42..86ea1d3be43 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1453,7 +1453,7 @@ void OBJECT_OT_paths_clear(wmOperatorType *ot) /* identifiers */ ot->name = "Clear Object Paths"; ot->idname = "OBJECT_OT_paths_clear"; - ot->description = "Clear path caches for all objects, hold Shift key for selected objects only"; + ot->description = "Clear motion paths for all objects, hold Shift key for selected objects only"; /* api callbacks */ ot->invoke = object_clear_paths_invoke; @@ -1464,8 +1464,11 @@ void OBJECT_OT_paths_clear(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = RNA_def_boolean( - ot->srna, "only_selected", false, "Only Selected", "Only clear paths from selected objects"); + ot->prop = RNA_def_boolean(ot->srna, + "only_selected", + false, + "Only Selected", + "Only clear motion paths of selected objects"); RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); } From 4d22a517c9b111c8ae0a163286845eb430d07193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 22 Dec 2022 12:34:08 +0100 Subject: [PATCH 0257/1522] Cleanup: animation, refactor motion paths UI code Simplify the UI code for the motion paths properties panel. No functional changes. --- .../startup/bl_ui/properties_animviz.py | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py index 131f7cba2b8..9608c008a99 100644 --- a/release/scripts/startup/bl_ui/properties_animviz.py +++ b/release/scripts/startup/bl_ui/properties_animviz.py @@ -40,6 +40,13 @@ class MotionPathButtonsPanel: start_end_group.prop(mps, "frame_end", text="End") col.prop(mps, "frame_step", text="Step") + if bones: + op_category = "pose" + icon = 'BONE_DATA' + else: + op_category = "object" + icon = 'OBJECT_DATA' + if mpath: col = layout.column(align=True) row = col.row(align=True) @@ -47,32 +54,20 @@ class MotionPathButtonsPanel: row.prop(mpath, "frame_start", text="Cached Range") row.prop(mpath, "frame_end", text="") + # Update Selected. col = layout.column(align=True) - if bones: - col.operator("pose.paths_update", text="Update Path", icon='BONE_DATA') - row = col.row(align=True) - row.operator("object.paths_update_visible", text="Update All Paths", icon='WORLD') - row.operator("pose.paths_clear", text="", icon='X') - else: - col.operator("object.paths_update", text="Update Path", icon='OBJECT_DATA') - row = col.row(align=True) - row.operator("object.paths_update_visible", text="Update All Paths", icon='WORLD') - row.operator("object.paths_clear", text="", icon='X') + col.operator(f"{op_category}.paths_update", text="Update Path", icon=icon) else: + # Calculate. col = layout.column(align=True) col.label(text="Nothing to show yet...", icon='ERROR') + col.operator(f"{op_category}.paths_calculate", text="Calculate...", icon=icon) - if bones: - col.operator("pose.paths_calculate", text="Calculate...", icon='BONE_DATA') - else: - col.operator("object.paths_calculate", text="Calculate...", icon='OBJECT_DATA') - - row = col.row(align=True) - row.operator("object.paths_update_visible", text="Update All Paths", icon='WORLD') - if bones: - row.operator("pose.paths_clear", text="", icon='X') - else: - row.operator("object.paths_clear", text="", icon='X') + # Update All & Clear All. + # Note that 'col' is from inside the preceeding `if` or `else` block. + row = col.row(align=True) + row.operator("object.paths_update_visible", text="Update All Paths", icon='WORLD') + row.operator(f"{op_category}.paths_clear", text="", icon='X') class MotionPathButtonsPanel_display: From dc30c9971d77383f61346b9fc22eb978380d0d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 22 Dec 2022 12:46:19 +0100 Subject: [PATCH 0258/1522] Anim: clarify the "Clear Motion Paths" operators Make the "Clear Motion Paths" operators more intuitive. Previously, the only way to clear the motion path of the selected object/bone would be to shift-click the "Clear ALL Motion Paths" button. Now there are two "X" buttons, one for "selected" and one for "all". The "Clear Selected" and "Clear All" buttons align with the corresponding "Update Selected" and "Update All" buttons. --- .../scripts/startup/bl_ui/properties_animviz.py | 6 ++++-- source/blender/editors/armature/pose_edit.c | 17 ++++++++++------- source/blender/editors/object/object_edit.c | 15 ++++++++------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py index 9608c008a99..73a2f947958 100644 --- a/release/scripts/startup/bl_ui/properties_animviz.py +++ b/release/scripts/startup/bl_ui/properties_animviz.py @@ -56,7 +56,9 @@ class MotionPathButtonsPanel: # Update Selected. col = layout.column(align=True) - col.operator(f"{op_category}.paths_update", text="Update Path", icon=icon) + row = col.row(align=True) + row.operator(f"{op_category}.paths_update", text="Update Path", icon=icon) + row.operator(f"{op_category}.paths_clear", text="", icon='X').only_selected = True else: # Calculate. col = layout.column(align=True) @@ -67,7 +69,7 @@ class MotionPathButtonsPanel: # Note that 'col' is from inside the preceeding `if` or `else` block. row = col.row(align=True) row.operator("object.paths_update_visible", text="Update All Paths", icon='WORLD') - row.operator(f"{op_category}.paths_clear", text="", icon='X') + row.operator(f"{op_category}.paths_clear", text="", icon='X').only_selected = False class MotionPathButtonsPanel_display: diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index e11558722af..0dc6f3e609a 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -11,6 +11,8 @@ #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLT_translation.h" + #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_object_types.h" @@ -427,13 +429,15 @@ static int pose_clear_paths_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -/* operator callback/wrapper */ -static int pose_clear_paths_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static char *pose_clear_paths_description(struct bContext *UNUSED(C), + struct wmOperatorType *UNUSED(ot), + struct PointerRNA *ptr) { - if ((event->modifier & KM_SHIFT) && !RNA_struct_property_is_set(op->ptr, "only_selected")) { - RNA_boolean_set(op->ptr, "only_selected", true); + const bool only_selected = RNA_boolean_get(ptr, "only_selected"); + if (only_selected) { + return BLI_strdup(TIP_("Clear motion paths of selected bones")); } - return pose_clear_paths_exec(C, op); + return BLI_strdup(TIP_("Clear motion paths of all bones")); } void POSE_OT_paths_clear(wmOperatorType *ot) @@ -441,12 +445,11 @@ void POSE_OT_paths_clear(wmOperatorType *ot) /* identifiers */ ot->name = "Clear Bone Paths"; ot->idname = "POSE_OT_paths_clear"; - ot->description = "Clear motion paths for all bones, hold Shift key for selected bones only"; /* api callbacks */ - ot->invoke = pose_clear_paths_invoke; ot->exec = pose_clear_paths_exec; ot->poll = ED_operator_posemode_exclusive; + ot->get_description = pose_clear_paths_description; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 86ea1d3be43..e9b176daf4a 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1439,13 +1439,15 @@ static int object_clear_paths_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -/* operator callback/wrapper */ -static int object_clear_paths_invoke(bContext *C, wmOperator *op, const wmEvent *event) +static char *object_clear_paths_description(struct bContext *UNUSED(C), + struct wmOperatorType *UNUSED(ot), + struct PointerRNA *ptr) { - if ((event->modifier & KM_SHIFT) && !RNA_struct_property_is_set(op->ptr, "only_selected")) { - RNA_boolean_set(op->ptr, "only_selected", true); + const bool only_selected = RNA_boolean_get(ptr, "only_selected"); + if (only_selected) { + return BLI_strdup(TIP_("Clear motion paths of selected objects")); } - return object_clear_paths_exec(C, op); + return BLI_strdup(TIP_("Clear motion paths of all objects")); } void OBJECT_OT_paths_clear(wmOperatorType *ot) @@ -1453,12 +1455,11 @@ void OBJECT_OT_paths_clear(wmOperatorType *ot) /* identifiers */ ot->name = "Clear Object Paths"; ot->idname = "OBJECT_OT_paths_clear"; - ot->description = "Clear motion paths for all objects, hold Shift key for selected objects only"; /* api callbacks */ - ot->invoke = object_clear_paths_invoke; ot->exec = object_clear_paths_exec; ot->poll = ED_operator_object_active_editable; + ot->get_description = object_clear_paths_description; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; From 7d2dbe7849f78221e0d8970a7ecda4bb0e99f3c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 22 Dec 2022 14:19:58 +0100 Subject: [PATCH 0259/1522] DRW: Pass: Add bind_ssbo for indexbuf This is a simple wrapper to GPU_indexbuf_bind_as_ssbo. Add simple recording test for and fix other test. --- source/blender/draw/intern/draw_command.cc | 10 +++++-- source/blender/draw/intern/draw_command.hh | 7 +++++ source/blender/draw/intern/draw_pass.hh | 26 ++++++++++++++++ source/blender/draw/tests/draw_pass_test.cc | 33 ++++++++++++++------- 4 files changed, 64 insertions(+), 12 deletions(-) diff --git a/source/blender/draw/intern/draw_command.cc b/source/blender/draw/intern/draw_command.cc index 7a91ecdc108..58bca3b9792 100644 --- a/source/blender/draw/intern/draw_command.cc +++ b/source/blender/draw/intern/draw_command.cc @@ -62,6 +62,9 @@ void ResourceBind::execute() const case ResourceBind::Type::VertexAsStorageBuf: GPU_vertbuf_bind_as_ssbo(is_reference ? *vertex_buf_ref : vertex_buf, slot); break; + case ResourceBind::Type::IndexAsStorageBuf: + GPU_indexbuf_bind_as_ssbo(is_reference ? *index_buf_ref : index_buf, slot); + break; } } @@ -278,6 +281,9 @@ std::string ResourceBind::serialize() const case Type::VertexAsStorageBuf: return std::string(".bind_vertbuf_as_ssbo") + (is_reference ? "_ref" : "") + "(" + std::to_string(slot) + ")"; + case Type::IndexAsStorageBuf: + return std::string(".bind_indexbuf_as_ssbo") + (is_reference ? "_ref" : "") + "(" + + std::to_string(slot) + ")"; default: BLI_assert_unreachable(); return ""; @@ -513,8 +519,8 @@ std::string StateSet::serialize() const std::string StencilSet::serialize() const { std::stringstream ss; - ss << ".stencil_set(write_mask=0b" << std::bitset<8>(write_mask) << ", compare_mask=0b" - << std::bitset<8>(compare_mask) << ", reference=0b" << std::bitset<8>(reference); + ss << ".stencil_set(write_mask=0b" << std::bitset<8>(write_mask) << ", reference=0b" + << std::bitset<8>(reference) << ", compare_mask=0b" << std::bitset<8>(compare_mask) << ")"; return ss.str(); } diff --git a/source/blender/draw/intern/draw_command.hh b/source/blender/draw/intern/draw_command.hh index 1545b02011a..760531899f4 100644 --- a/source/blender/draw/intern/draw_command.hh +++ b/source/blender/draw/intern/draw_command.hh @@ -140,6 +140,7 @@ struct ResourceBind { StorageBuf, UniformAsStorageBuf, VertexAsStorageBuf, + IndexAsStorageBuf, } type; union { @@ -154,6 +155,8 @@ struct ResourceBind { GPUTexture **texture_ref; GPUVertBuf *vertex_buf; GPUVertBuf **vertex_buf_ref; + GPUIndexBuf *index_buf; + GPUIndexBuf **index_buf_ref; }; ResourceBind() = default; @@ -174,6 +177,10 @@ struct ResourceBind { : slot(slot_), is_reference(false), type(Type::VertexAsStorageBuf), vertex_buf(res){}; ResourceBind(int slot_, GPUVertBuf **res, Type /* type */) : slot(slot_), is_reference(true), type(Type::VertexAsStorageBuf), vertex_buf_ref(res){}; + ResourceBind(int slot_, GPUIndexBuf *res, Type /* type */) + : slot(slot_), is_reference(false), type(Type::IndexAsStorageBuf), index_buf(res){}; + ResourceBind(int slot_, GPUIndexBuf **res, Type /* type */) + : slot(slot_), is_reference(true), type(Type::IndexAsStorageBuf), index_buf_ref(res){}; ResourceBind(int slot_, draw::Image *res) : slot(slot_), is_reference(false), type(Type::Image), texture(draw::as_texture(res)){}; ResourceBind(int slot_, draw::Image **res) diff --git a/source/blender/draw/intern/draw_pass.hh b/source/blender/draw/intern/draw_pass.hh index 5f3b7ccb116..8523b9ae5e6 100644 --- a/source/blender/draw/intern/draw_pass.hh +++ b/source/blender/draw/intern/draw_pass.hh @@ -297,6 +297,10 @@ class PassBase { void bind_ssbo(const char *name, GPUVertBuf **buffer); void bind_ssbo(int slot, GPUVertBuf *buffer); void bind_ssbo(int slot, GPUVertBuf **buffer); + void bind_ssbo(const char *name, GPUIndexBuf *buffer); + void bind_ssbo(const char *name, GPUIndexBuf **buffer); + void bind_ssbo(int slot, GPUIndexBuf *buffer); + void bind_ssbo(int slot, GPUIndexBuf **buffer); void bind_ubo(const char *name, GPUUniformBuf *buffer); void bind_ubo(const char *name, GPUUniformBuf **buffer); void bind_ubo(int slot, GPUUniformBuf *buffer); @@ -869,6 +873,16 @@ template inline void PassBase::bind_ssbo(const char *name, GPUVertBu this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer); } +template inline void PassBase::bind_ssbo(const char *name, GPUIndexBuf *buffer) +{ + this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer); +} + +template inline void PassBase::bind_ssbo(const char *name, GPUIndexBuf **buffer) +{ + this->bind_ssbo(GPU_shader_get_ssbo(shader_, name), buffer); +} + template inline void PassBase::bind_ubo(const char *name, GPUUniformBuf *buffer) { this->bind_ubo(GPU_shader_get_uniform_block_binding(shader_, name), buffer); @@ -926,6 +940,18 @@ template inline void PassBase::bind_ssbo(int slot, GPUVertBuf **buff slot, buffer, ResourceBind::Type::VertexAsStorageBuf}; } +template inline void PassBase::bind_ssbo(int slot, GPUIndexBuf *buffer) +{ + create_command(Type::ResourceBind).resource_bind = { + slot, buffer, ResourceBind::Type::IndexAsStorageBuf}; +} + +template inline void PassBase::bind_ssbo(int slot, GPUIndexBuf **buffer) +{ + create_command(Type::ResourceBind).resource_bind = { + slot, buffer, ResourceBind::Type::IndexAsStorageBuf}; +} + template inline void PassBase::bind_ubo(int slot, GPUUniformBuf *buffer) { create_command(Type::ResourceBind).resource_bind = {slot, buffer}; diff --git a/source/blender/draw/tests/draw_pass_test.cc b/source/blender/draw/tests/draw_pass_test.cc index 95ab8fa2ef1..cf05e332d02 100644 --- a/source/blender/draw/tests/draw_pass_test.cc +++ b/source/blender/draw/tests/draw_pass_test.cc @@ -22,6 +22,10 @@ static void test_draw_pass_all_commands() StorageBuffer ssbo; ssbo.push_update(); + /* Won't be dereferenced. */ + GPUVertBuf *vbo = (GPUVertBuf *)1; + GPUIndexBuf *ibo = (GPUIndexBuf *)1; + float4 color(1.0f, 1.0f, 1.0f, 0.0f); int3 dispatch_size(1); @@ -33,12 +37,16 @@ static void test_draw_pass_all_commands() pass.shader_set(GPU_shader_get_builtin_shader(GPU_SHADER_3D_IMAGE_COLOR)); pass.bind_texture("image", tex); pass.bind_texture("image", &tex); - pass.bind_image("missing_image", tex); /* Should not crash. */ - pass.bind_image("missing_image", &tex); /* Should not crash. */ - pass.bind_ubo("missing_ubo", ubo); /* Should not crash. */ - pass.bind_ubo("missing_ubo", &ubo); /* Should not crash. */ - pass.bind_ssbo("missing_ssbo", ssbo); /* Should not crash. */ - pass.bind_ssbo("missing_ssbo", &ssbo); /* Should not crash. */ + pass.bind_image("missing_image", tex); /* Should not crash. */ + pass.bind_image("missing_image", &tex); /* Should not crash. */ + pass.bind_ubo("missing_ubo", ubo); /* Should not crash. */ + pass.bind_ubo("missing_ubo", &ubo); /* Should not crash. */ + pass.bind_ssbo("missing_ssbo", ssbo); /* Should not crash. */ + pass.bind_ssbo("missing_ssbo", &ssbo); /* Should not crash. */ + pass.bind_ssbo("missing_vbo_as_ssbo", vbo); /* Should not crash. */ + pass.bind_ssbo("missing_vbo_as_ssbo", &vbo); /* Should not crash. */ + pass.bind_ssbo("missing_ibo_as_ssbo", ibo); /* Should not crash. */ + pass.bind_ssbo("missing_ibo_as_ssbo", &ibo); /* Should not crash. */ pass.push_constant("color", color); pass.push_constant("color", &color); pass.push_constant("ModelViewProjectionMatrix", float4x4::identity()); @@ -61,8 +69,9 @@ static void test_draw_pass_all_commands() expected << " .state_set(6)" << std::endl; expected << " .clear(color=(0.25, 0.5, 100, -2000), depth=0.5, stencil=0b11110000))" << std::endl; - expected << " .stencil_set(write_mask=0b10000000, compare_mask=0b00001111, reference=0b10001111" - << std::endl; + expected + << " .stencil_set(write_mask=0b10000000, reference=0b00001111, compare_mask=0b10001111)" + << std::endl; expected << " .shader_bind(gpu_shader_3D_image_color)" << std::endl; expected << " .bind_texture(0)" << std::endl; expected << " .bind_texture_ref(0)" << std::endl; @@ -72,8 +81,12 @@ static void test_draw_pass_all_commands() expected << " .bind_uniform_buf_ref(-1)" << std::endl; expected << " .bind_storage_buf(-1)" << std::endl; expected << " .bind_storage_buf_ref(-1)" << std::endl; - expected << " .push_constant(1, data=(1, 1, 1, 0))" << std::endl; - expected << " .push_constant(1, data=(1, 1, 1, 1))" << std::endl; + expected << " .bind_vertbuf_as_ssbo(-1)" << std::endl; + expected << " .bind_vertbuf_as_ssbo_ref(-1)" << std::endl; + expected << " .bind_indexbuf_as_ssbo(-1)" << std::endl; + expected << " .bind_indexbuf_as_ssbo_ref(-1)" << std::endl; + expected << " .push_constant(2, data=(1, 1, 1, 0))" << std::endl; + expected << " .push_constant(2, data=(1, 1, 1, 1))" << std::endl; expected << " .push_constant(0, data=(" << std::endl; expected << "( 1.000000, 0.000000, 0.000000, 0.000000)" << std::endl; expected << "( 0.000000, 1.000000, 0.000000, 0.000000)" << std::endl; From a7ad2dea62b660dcac03d3aeffd7b63b03d4da8c Mon Sep 17 00:00:00 2001 From: Eimear Crotty Date: Thu, 22 Dec 2022 14:22:39 +0100 Subject: [PATCH 0260/1522] Fix T97394: single points are brighter than stroke in 3D viewport Convert 3D point shader fragment color from sRGB space to framebuffer space to match 3D line shader. Reviewed By: fclem Maniphest Tasks: T97394 Differential Revision: https://developer.blender.org/D16831 --- .../gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl | 3 ++- source/blender/gpu/shaders/infos/gpu_shader_3D_point_info.hh | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl index fddd92b1174..a7d5294b8c4 100644 --- a/source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_point_uniform_color_aa_frag.glsl @@ -1,3 +1,4 @@ +#pragma BLENDER_REQUIRE(gpu_shader_colorspace_lib.glsl) void main() { @@ -11,7 +12,7 @@ void main() * ... * dist = 0 at center of point */ - fragColor.rgb = color.rgb; + fragColor = blender_srgb_to_framebuffer_space(color); fragColor.a = mix(color.a, 0.0, smoothstep(radii[1], radii[0], dist)); if (fragColor.a == 0.0) { diff --git a/source/blender/gpu/shaders/infos/gpu_shader_3D_point_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_3D_point_info.hh index 895787e4f1e..c71d7cf632a 100644 --- a/source/blender/gpu/shaders/infos/gpu_shader_3D_point_info.hh +++ b/source/blender/gpu/shaders/infos/gpu_shader_3D_point_info.hh @@ -37,6 +37,7 @@ GPU_SHADER_CREATE_INFO(gpu_shader_3D_point_uniform_size_uniform_color_aa) .push_constant(Type::FLOAT, "size") .vertex_source("gpu_shader_3D_point_uniform_size_aa_vert.glsl") .fragment_source("gpu_shader_point_uniform_color_aa_frag.glsl") + .additional_info("gpu_srgb_to_framebuffer_space") .do_static_compilation(true); GPU_SHADER_CREATE_INFO(gpu_shader_3D_point_uniform_size_uniform_color_aa_clipped) From d9510f02c8f3b5ff9b692bb03359bd962a800ba4 Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Thu, 22 Dec 2022 16:52:17 +0100 Subject: [PATCH 0261/1522] Animation: separate constraint owner space descriptions for objects Until now the owner spaces in the object constraint properties used the same descriptions as the target spaces, unlike bone constraints. For instance, if you chose World Space as owner space, you'd get the description: "The transformation of the target is evaluated relative to the world coordinate system". Reuse the existing descriptions from the bone constraints instead, so now you get: "The constraint is applied relative to the world coordinate system". Reviewed By: sybren Maniphest Tasks: T43295 Differential Revision: https://developer.blender.org/D16747 --- .../blender/makesrna/intern/rna_constraint.c | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 719c7441174..671286be052 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -279,7 +279,26 @@ static const EnumPropertyItem euler_order_items[] = { #ifdef RNA_RUNTIME -static const EnumPropertyItem space_object_items[] = { +static const EnumPropertyItem owner_space_object_items[] = { + {CONSTRAINT_SPACE_WORLD, + "WORLD", + 0, + "World Space", + "The constraint is applied relative to the world coordinate system"}, + {CONSTRAINT_SPACE_CUSTOM, + "CUSTOM", + 0, + "Custom Space", + "The constraint is applied in local space of a custom object/bone/vertex group"}, + {CONSTRAINT_SPACE_LOCAL, + "LOCAL", + 0, + "Local Space", + "The constraint is applied relative to the local coordinate system of the object"}, + {0, NULL, 0, NULL, NULL}, +}; + +static const EnumPropertyItem target_space_object_items[] = { {CONSTRAINT_SPACE_WORLD, "WORLD", 0, @@ -588,7 +607,7 @@ static const EnumPropertyItem *rna_Constraint_owner_space_itemf(bContext *UNUSED } else { /* object */ - return space_object_items; + return owner_space_object_items; } } @@ -615,7 +634,7 @@ static const EnumPropertyItem *rna_Constraint_target_space_itemf(bContext *UNUSE } } - return space_object_items; + return target_space_object_items; } static bConstraintTarget *rna_ArmatureConstraint_target_new(ID *id, bConstraint *con, Main *bmain) From 15c433d7d56414faa69fe923e1831db546c2d4f7 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Thu, 22 Dec 2022 16:14:15 -0500 Subject: [PATCH 0262/1522] Fix: Missing UI context members after recent refactor Caused by 7d7e90ca685954409ece00. When accessing context members from the windowmanager context (`C->wm.store` which is mainly used for UI related stuff) the above commit broke behavior in `CTX_store_ptr_lookup` in that it changed and would **always** return NULL if no type is passed in. The call to `CTX_store_ptr_lookup` from `ctx_data_get` **always** passes in NULL though. Accessing other context members survived since they take a different code path in `ctx_data_get` and dont use `CTX_store_ptr_lookup`. Now also return the entry if a NULL type was passed as it was before. Fixes T103370, T103405, T103417 Differential Revision: https://developer.blender.org/D16840 --- source/blender/blenkernel/intern/context.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/context.cc b/source/blender/blenkernel/intern/context.cc index df18cf1795c..090624a289b 100644 --- a/source/blender/blenkernel/intern/context.cc +++ b/source/blender/blenkernel/intern/context.cc @@ -190,7 +190,7 @@ const PointerRNA *CTX_store_ptr_lookup(const bContextStore *store, { for (auto entry = store->entries.rbegin(); entry != store->entries.rend(); ++entry) { if (entry->name == name) { - if (type && RNA_struct_is_a(entry->ptr.type, type)) { + if (!type ||(type && RNA_struct_is_a(entry->ptr.type, type))) { return &entry->ptr; } } From f803a0a95b6769145528914d21910c10ce24c861 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 22 Dec 2022 16:52:44 -0800 Subject: [PATCH 0263/1522] Sculpt: Fix T103341: Move sculpt overlay flags to View3DOverlay.flag "Show mask" and "Show face sets" were being stored in `Sculpt`, yet their opacities are in `View3dOverlay`. Now `View3DOverlay` has the flags too. --- release/scripts/startup/bl_ui/space_view3d.py | 8 ++--- .../blender/blenkernel/BKE_blender_version.h | 2 +- source/blender/blenkernel/BKE_paint.h | 2 -- source/blender/blenkernel/intern/paint.cc | 12 -------- source/blender/blenkernel/intern/pbvh.c | 10 ------- .../blender/blenkernel/intern/pbvh_intern.h | 2 -- .../blenloader/intern/versioning_300.cc | 13 ++++++++ .../draw/engines/overlay/overlay_engine.cc | 4 +-- source/blender/makesdna/DNA_scene_types.h | 7 +---- source/blender/makesdna/DNA_view3d_defaults.h | 2 +- source/blender/makesdna/DNA_view3d_types.h | 2 ++ .../makesrna/intern/rna_sculpt_paint.c | 30 ------------------- source/blender/makesrna/intern/rna_space.c | 10 +++++++ 13 files changed, 34 insertions(+), 70 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 263a323bb63..4feb92e71df 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -6741,15 +6741,15 @@ class VIEW3D_PT_overlay_sculpt(Panel): overlay = view.overlay row = layout.row(align=True) - row.prop(sculpt, "show_mask", text="") + row.prop(overlay, "sculpt_show_mask", text="") sub = row.row() - sub.active = sculpt.show_mask + sub.active = overlay.sculpt_show_mask sub.prop(overlay, "sculpt_mode_mask_opacity", text="Mask") row = layout.row(align=True) - row.prop(sculpt, "show_face_sets", text="") + row.prop(overlay, "sculpt_show_face_sets", text="") sub = row.row() - sub.active = sculpt.show_face_sets + sub.active = overlay.sculpt_show_face_sets row.prop(overlay, "sculpt_mode_face_sets_opacity", text="Face Sets") diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 7c241a4fa12..2ddda93c93b 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,7 +25,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 5 +#define BLENDER_FILE_SUBVERSION 6 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 5c878486c68..ba631bd92a0 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -632,8 +632,6 @@ typedef struct SculptSession { /* PBVH acceleration structure */ struct PBVH *pbvh; - bool show_mask; - bool show_face_sets; /* Painting on deformed mesh */ bool deform_modifiers_active; /* Object is deformed with some modifiers. */ diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index ebbe3c2c4fa..acc6a32b0eb 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -1675,8 +1675,6 @@ static void sculpt_update_object( ss->depsgraph = depsgraph; ss->deform_modifiers_active = sculpt_modifiers_active(scene, sd, ob); - ss->show_mask = (sd->flags & SCULPT_HIDE_MASK) == 0; - ss->show_face_sets = (sd->flags & SCULPT_HIDE_FACE_SETS) == 0; ss->building_vp_handle = false; @@ -1775,9 +1773,6 @@ static void sculpt_update_object( } } - pbvh_show_mask_set(ss->pbvh, ss->show_mask); - pbvh_show_face_sets_set(ss->pbvh, ss->show_face_sets); - if (ss->deform_modifiers_active) { /* Painting doesn't need crazyspace, use already evaluated mesh coordinates if possible. */ bool used_me_eval = false; @@ -2173,8 +2168,6 @@ static PBVH *build_pbvh_for_dynamic_topology(Object *ob) ob->sculpt->bm_log, ob->sculpt->attrs.dyntopo_node_id_vertex->bmesh_cd_offset, ob->sculpt->attrs.dyntopo_node_id_face->bmesh_cd_offset); - pbvh_show_mask_set(pbvh, ob->sculpt->show_mask); - pbvh_show_face_sets_set(pbvh, false); return pbvh; } @@ -2207,9 +2200,6 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool looptri, looptris_num); - pbvh_show_mask_set(pbvh, ob->sculpt->show_mask); - pbvh_show_face_sets_set(pbvh, ob->sculpt->show_face_sets); - const bool is_deformed = check_sculpt_object_deformed(ob, true); if (is_deformed && me_eval_deform != nullptr) { int totvert; @@ -2240,8 +2230,6 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg, bool respect subdiv_ccg->grid_hidden, base_mesh, subdiv_ccg); - pbvh_show_mask_set(pbvh, ob->sculpt->show_mask); - pbvh_show_face_sets_set(pbvh, ob->sculpt->show_face_sets); return pbvh; } diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index ca0039d1a58..a6a362b1daf 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -3419,16 +3419,6 @@ bool pbvh_has_face_sets(PBVH *pbvh) return false; } -void pbvh_show_mask_set(PBVH *pbvh, bool show_mask) -{ - pbvh->show_mask = show_mask; -} - -void pbvh_show_face_sets_set(PBVH *pbvh, bool show_face_sets) -{ - pbvh->show_face_sets = show_face_sets; -} - void BKE_pbvh_set_frustum_planes(PBVH *pbvh, PBVHFrustumPlanes *planes) { pbvh->num_planes = planes->num_planes; diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index e465e8be002..ee728a698dd 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -191,8 +191,6 @@ struct PBVH { /* flag are verts/faces deformed */ bool deformed; - bool show_mask; - bool show_face_sets; bool respect_hide; /* Dynamic topology */ diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 79b1164c0dd..90bca21cbe3 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3822,6 +3822,19 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_ATLEAST(bmain, 305, 6)) { + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + v3d->overlay.flag |= (int)(V3D_OVERLAY_SCULPT_SHOW_MASK | + V3D_OVERLAY_SCULPT_SHOW_FACE_SETS); + } + } + } + } + } /** * Versioning code until next subversion bump goes here. * diff --git a/source/blender/draw/engines/overlay/overlay_engine.cc b/source/blender/draw/engines/overlay/overlay_engine.cc index c41cfc790fa..2eea0ad2f65 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.cc +++ b/source/blender/draw/engines/overlay/overlay_engine.cc @@ -92,10 +92,10 @@ static void OVERLAY_engine_init(void *vedata) } if (ts->sculpt) { - if (ts->sculpt->flags & SCULPT_HIDE_FACE_SETS) { + if (!(v3d->overlay.flag & (int)V3D_OVERLAY_SCULPT_SHOW_FACE_SETS)) { pd->overlay.sculpt_mode_face_sets_opacity = 0.0f; } - if (ts->sculpt->flags & SCULPT_HIDE_MASK) { + if (!(v3d->overlay.flag & (int)V3D_OVERLAY_SCULPT_SHOW_MASK)) { pd->overlay.sculpt_mode_mask_opacity = 0.0f; } } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 5f68b2d0c78..e81d8d8ed55 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2470,13 +2470,8 @@ typedef enum eSculptFlags { /** If set, dynamic-topology detail size will be constant in object space. */ SCULPT_DYNTOPO_DETAIL_CONSTANT = (1 << 13), SCULPT_DYNTOPO_DETAIL_BRUSH = (1 << 14), + /* unused = (1 << 15), */ SCULPT_DYNTOPO_DETAIL_MANUAL = (1 << 16), - - /** Don't display mask in viewport, but still use it for strokes. */ - SCULPT_HIDE_MASK = (1 << 15), - - /** Don't display face sets in viewport. */ - SCULPT_HIDE_FACE_SETS = (1 << 17), } eSculptFlags; /** #Sculpt.transform_mode */ diff --git a/source/blender/makesdna/DNA_view3d_defaults.h b/source/blender/makesdna/DNA_view3d_defaults.h index f124bdd5d94..0c0ed210a2b 100644 --- a/source/blender/makesdna/DNA_view3d_defaults.h +++ b/source/blender/makesdna/DNA_view3d_defaults.h @@ -36,7 +36,7 @@ #define _DNA_DEFAULT_View3DOverlay \ { \ - .flag = V3D_OVERLAY_VIEWER_ATTRIBUTE, \ + .flag = V3D_OVERLAY_VIEWER_ATTRIBUTE | V3D_OVERLAY_SCULPT_SHOW_MASK | V3D_OVERLAY_SCULPT_SHOW_FACE_SETS, \ .wireframe_threshold = 1.0f, \ .wireframe_opacity = 1.0f, \ .viewer_attribute_opacity = 1.0f, \ diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 8e44588bb34..0b7c483b7d0 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -546,6 +546,8 @@ enum { V3D_OVERLAY_STATS = (1 << 11), V3D_OVERLAY_FADE_INACTIVE = (1 << 12), V3D_OVERLAY_VIEWER_ATTRIBUTE = (1 << 13), + V3D_OVERLAY_SCULPT_SHOW_MASK = (1 << 14), + V3D_OVERLAY_SCULPT_SHOW_FACE_SETS = (1 << 15), }; /** #View3DOverlay.edit_flag */ diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index a57f3c5a1a6..003e26333d2 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -393,24 +393,6 @@ static void rna_Sculpt_update(bContext *C, PointerRNA *UNUSED(ptr)) } } -static void rna_Sculpt_ShowMask_update(bContext *C, PointerRNA *UNUSED(ptr)) -{ - Scene *scene = CTX_data_scene(C); - ViewLayer *view_layer = CTX_data_view_layer(C); - BKE_view_layer_synced_ensure(scene, view_layer); - Object *object = BKE_view_layer_active_object_get(view_layer); - if (object == NULL || object->sculpt == NULL) { - return; - } - Sculpt *sd = scene->toolsettings->sculpt; - object->sculpt->show_mask = ((sd->flags & SCULPT_HIDE_MASK) == 0); - if (object->sculpt->pbvh != NULL) { - pbvh_show_mask_set(object->sculpt->pbvh, object->sculpt->show_mask); - } - DEG_id_tag_update(&object->id, ID_RECALC_GEOMETRY); - WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, object); -} - static char *rna_Sculpt_path(const PointerRNA *UNUSED(ptr)) { return BLI_strdup("tool_settings.sculpt"); @@ -848,18 +830,6 @@ static void rna_def_sculpt(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_update"); - prop = RNA_def_property(srna, "show_mask", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flags", SCULPT_HIDE_MASK); - RNA_def_property_ui_text(prop, "Show Mask", "Show mask as overlay on object"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_ShowMask_update"); - - prop = RNA_def_property(srna, "show_face_sets", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flags", SCULPT_HIDE_FACE_SETS); - RNA_def_property_ui_text(prop, "Show Face Sets", "Show Face Sets as overlay on object"); - RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_ShowMask_update"); - prop = RNA_def_property(srna, "detail_size", PROP_FLOAT, PROP_PIXEL); RNA_def_property_ui_range(prop, 0.5, 40.0, 0.1, 2); RNA_def_property_ui_scale_type(prop, PROP_SCALE_CUBIC); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 662ed6514d8..75fc0e6e1e5 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -4720,6 +4720,16 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna) RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "sculpt_show_mask", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_SCULPT_SHOW_MASK); + RNA_def_property_ui_text(prop, "Sculpt Show Mask", ""); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "sculpt_show_face_sets", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_SCULPT_SHOW_FACE_SETS); + RNA_def_property_ui_text(prop, "Sculpt Show Face Sets", ""); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + /* grease pencil paper settings */ prop = RNA_def_property(srna, "show_annotation", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_ANNOTATION); From fb8778a28c932a78b4f680e4b6eccd3441b38752 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Thu, 22 Dec 2022 15:13:08 +0100 Subject: [PATCH 0264/1522] Fix T103394: default/active color status lost after remeshing Caused by rB6514bb05ea5a. For the remeshing, we have to make sure these names are brought over each time a mesh is made from another in the process. This happens when reprojecting the colors in `BKE_remesh_reproject_vertex_paint` and also again in `BKE_mesh_nomain_to_mesh`. A bit unsure if this should happen as deep as in `BKE_mesh_nomain_to_mesh` (if not, this can be isolated to `voxel_remesh_exec`), but I would assume other callers of `BKE_mesh_nomain_to_mesh` would actually benefit from it, too? Maniphest Tasks: T103394 Differential Revision: https://developer.blender.org/D16847 --- source/blender/blenkernel/intern/mesh_convert.cc | 10 ++++++++++ source/blender/blenkernel/intern/mesh_remesh_voxel.cc | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 8354de20e20..9f9548a5e4c 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -1191,6 +1191,16 @@ void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob) CustomData_copy(&mesh_src->pdata, &mesh_dst->pdata, mask.pmask, CD_ASSIGN, mesh_src->totpoly); CustomData_copy(&mesh_src->ldata, &mesh_dst->ldata, mask.lmask, CD_ASSIGN, mesh_src->totloop); + /* Make sure active/default color attribute (names) are brought over. */ + if (mesh_src->active_color_attribute) { + MEM_SAFE_FREE(mesh_dst->active_color_attribute); + mesh_dst->active_color_attribute = BLI_strdup(mesh_src->active_color_attribute); + } + if (mesh_src->default_color_attribute) { + MEM_SAFE_FREE(mesh_dst->default_color_attribute); + mesh_dst->default_color_attribute = BLI_strdup(mesh_src->default_color_attribute); + } + BLI_freelistN(&mesh_dst->vertex_group_names); mesh_dst->vertex_group_names = mesh_src->vertex_group_names; BLI_listbase_clear(&mesh_src->vertex_group_names); diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index a2916c75d51..ddc0625ba6b 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -489,6 +489,16 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source) } } + /* Make sure active/default color attribute (names) are brought over. */ + if (source->active_color_attribute) { + MEM_SAFE_FREE(target->active_color_attribute); + target->active_color_attribute = BLI_strdup(source->active_color_attribute); + } + if (source->default_color_attribute) { + MEM_SAFE_FREE(target->default_color_attribute); + target->default_color_attribute = BLI_strdup(source->default_color_attribute); + } + MEM_SAFE_FREE(source_lmap); MEM_SAFE_FREE(source_lmap_mem); MEM_SAFE_FREE(target_lmap); From 834ca5d682da3e0ac40b95fa44a014633b17db33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Fri, 23 Dec 2022 11:18:54 +0100 Subject: [PATCH 0265/1522] GPU: Fix Shader Builder stubs after removal of UNUSED macro in C++ This was introduced by rBfb7f12dc4078 --- .../gpu/intern/gpu_shader_builder_stubs.cc | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc index cebdab2c415..ebb06ee55b9 100644 --- a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc +++ b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc @@ -61,17 +61,17 @@ struct ImBuf *IMB_allocImBuf(unsigned int /*x*/, /** \name Stubs of UI_resources.h * \{ */ -void UI_GetThemeColor4fv(int /*colorid*/, float UNUSED(col[4])) +void UI_GetThemeColor4fv(int /*colorid*/, float[4] /*col*/) { BLI_assert_unreachable(); } -void UI_GetThemeColor3fv(int /*colorid*/, float UNUSED(col[3])) +void UI_GetThemeColor3fv(int /*colorid*/, float[3] /*col*/) { BLI_assert_unreachable(); } -void UI_GetThemeColorShade4fv(int /*colorid*/, int /*offset*/, float UNUSED(col[4])) +void UI_GetThemeColorShade4fv(int /*colorid*/, int /*offset*/, float[4] /*col*/) { BLI_assert_unreachable(); } @@ -79,20 +79,17 @@ void UI_GetThemeColorShade4fv(int /*colorid*/, int /*offset*/, float UNUSED(col[ void UI_GetThemeColorShadeAlpha4fv(int /*colorid*/, int /*coloffset*/, int /*alphaoffset*/, - float UNUSED(col[4])) + float[4] /*col*/) { BLI_assert_unreachable(); } void UI_GetThemeColorBlendShade4fv( - int /*colorid1*/, int /*colorid2*/, float /*fac*/, int /*offset*/, float UNUSED(col[4])) + int /*colorid1*/, int /*colorid2*/, float /*fac*/, int /*offset*/, float[4] /*col*/) { BLI_assert_unreachable(); } -void UI_GetThemeColorBlend3ubv(int /*colorid1*/, - int /*colorid2*/, - float /*fac*/, - uchar UNUSED(col[3])) +void UI_GetThemeColorBlend3ubv(int /*colorid1*/, int /*colorid2*/, float /*fac*/, uchar[3] /*col*/) { BLI_assert_unreachable(); } @@ -100,7 +97,7 @@ void UI_GetThemeColorBlend3ubv(int /*colorid1*/, void UI_GetThemeColorShadeAlpha4ubv(int /*colorid*/, int /*coloffset*/, int /*alphaoffset*/, - uchar UNUSED(col[4])) + uchar[4] /*col*/) { BLI_assert_unreachable(); } @@ -130,7 +127,7 @@ bool paint_is_face_hidden(const struct MLoopTri * /*lt*/, const bool * /*hide_po void BKE_paint_face_set_overlay_color_get(const int /*face_set*/, const int /*seed*/, - uchar UNUSED(r_color[4])) + uchar[4] /*col*/) { BLI_assert_unreachable(); } @@ -152,7 +149,7 @@ bool paint_is_grid_face_hidden(const uint * /*grid_hidden*/, void BKE_mesh_calc_poly_normal(const struct MPoly * /*mpoly*/, const struct MLoop * /*loopstart*/, const struct MVert * /*mvarray*/, - float UNUSED(r_no[3])) + float[3] /*col*/) { BLI_assert_unreachable(); } @@ -160,7 +157,7 @@ void BKE_mesh_calc_poly_normal(const struct MPoly * /*mpoly*/, void BKE_mesh_looptri_get_real_edges(const struct MEdge * /*edges*/, const struct MLoop * /*loops*/, const struct MLoopTri * /*looptri*/, - int UNUSED(r_edges[3])) + int[3] /*col*/) { BLI_assert_unreachable(); } @@ -275,7 +272,7 @@ void ntreeFreeLocalTree(struct bNodeTree * /*ntree*/) /* -------------------------------------------------------------------- */ /** \name Stubs of bmesh.h * \{ */ -void BM_face_as_array_vert_tri(BMFace * /*f*/, BMVert *UNUSED(r_verts[3])) +void BM_face_as_array_vert_tri(BMFace * /*f*/, BMVert *[3] /*r_verts*/) { BLI_assert_unreachable(); } From a8aae66f0e8067280fff0db0cefe3d2a6ee2c41a Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Tue, 20 Dec 2022 13:05:40 +0100 Subject: [PATCH 0266/1522] Asset Browser: New catalog menu This replaces the old Edit menu, creating a menu only for catalog operators. The Undo/Redo were already working only for catalogs, so now this is more clear. The menu also contains the Save and New catalog operators. Differential Revision: https://developer.blender.org/D16820 --- release/scripts/startup/bl_ui/space_filebrowser.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index b2eeb4e6cf0..a7e9663d186 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -644,7 +644,7 @@ class ASSETBROWSER_MT_editor_menus(AssetBrowserMenu, Menu): layout.menu("ASSETBROWSER_MT_view") layout.menu("ASSETBROWSER_MT_select") - layout.menu("ASSETBROWSER_MT_edit") + layout.menu("ASSETBROWSER_MT_catalog") class ASSETBROWSER_MT_view(AssetBrowserMenu, Menu): @@ -683,8 +683,8 @@ class ASSETBROWSER_MT_select(AssetBrowserMenu, Menu): layout.operator("file.select_box") -class ASSETBROWSER_MT_edit(AssetBrowserMenu, Menu): - bl_label = "Edit" +class ASSETBROWSER_MT_catalog(AssetBrowserMenu, Menu): + bl_label = "Catalog" def draw(self, _context): layout = self.layout @@ -692,6 +692,10 @@ class ASSETBROWSER_MT_edit(AssetBrowserMenu, Menu): layout.operator("asset.catalog_undo", text="Undo") layout.operator("asset.catalog_redo", text="Redo") + layout.separator() + layout.operator("asset.catalogs_save") + layout.operator("asset.catalog_new").parent_path = "" + class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel): bl_region_type = 'TOOL_PROPS' @@ -844,7 +848,7 @@ classes = ( ASSETBROWSER_MT_editor_menus, ASSETBROWSER_MT_view, ASSETBROWSER_MT_select, - ASSETBROWSER_MT_edit, + ASSETBROWSER_MT_catalog, ASSETBROWSER_MT_metadata_preview_menu, ASSETBROWSER_PT_metadata, ASSETBROWSER_PT_metadata_preview, From a521960fddf2544b1eeab1f29e03c8d9d4abf86b Mon Sep 17 00:00:00 2001 From: Eimear Crotty Date: Fri, 23 Dec 2022 11:19:43 +0100 Subject: [PATCH 0267/1522] Fix T103426: Crash on Insert Keyframe Add required additional_info to shader using gpu_shader_point_uniform_color_aa_frag.glsl. This is the only other reference to the shader which requires the additional_info to be added. {F14085803} Reviewed By: #eevee_viewport, fclem Maniphest Tasks: T103426 Differential Revision: https://developer.blender.org/D16853 --- .../gpu_shader_2D_point_uniform_size_uniform_color_aa_info.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/gpu/shaders/infos/gpu_shader_2D_point_uniform_size_uniform_color_aa_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_2D_point_uniform_size_uniform_color_aa_info.hh index 1b5c9beed48..6d4806580e5 100644 --- a/source/blender/gpu/shaders/infos/gpu_shader_2D_point_uniform_size_uniform_color_aa_info.hh +++ b/source/blender/gpu/shaders/infos/gpu_shader_2D_point_uniform_size_uniform_color_aa_info.hh @@ -17,4 +17,5 @@ GPU_SHADER_CREATE_INFO(gpu_shader_2D_point_uniform_size_uniform_color_aa) .push_constant(Type::FLOAT, "size") .vertex_source("gpu_shader_2D_point_uniform_size_aa_vert.glsl") .fragment_source("gpu_shader_point_uniform_color_aa_frag.glsl") + .additional_info("gpu_srgb_to_framebuffer_space") .do_static_compilation(true); From 2838d9324d031a8b2024587031ddd4cce213f12b Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 23 Dec 2022 12:04:56 +0100 Subject: [PATCH 0268/1522] Cleanup: clang format Missed in rB15c433d7d564. --- source/blender/blenkernel/intern/context.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/context.cc b/source/blender/blenkernel/intern/context.cc index 090624a289b..79f4f56b325 100644 --- a/source/blender/blenkernel/intern/context.cc +++ b/source/blender/blenkernel/intern/context.cc @@ -190,7 +190,7 @@ const PointerRNA *CTX_store_ptr_lookup(const bContextStore *store, { for (auto entry = store->entries.rbegin(); entry != store->entries.rend(); ++entry) { if (entry->name == name) { - if (!type ||(type && RNA_struct_is_a(entry->ptr.type, type))) { + if (!type || (type && RNA_struct_is_a(entry->ptr.type, type))) { return &entry->ptr; } } From b024577452f5760b73d2c510cebcfe5459e81bf0 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 23 Dec 2022 13:16:42 +0100 Subject: [PATCH 0269/1522] Fix: dangling attribute name pointer --- source/blender/editors/object/object_modifier.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 3a98108989e..523be5eda13 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -867,7 +867,7 @@ static void remove_invalid_attribute_strings(Mesh &mesh) mesh.active_color_attribute); if (!meta_data || !(meta_data->domain & ATTR_DOMAIN_MASK_COLOR) || !(meta_data->data_type & CD_MASK_COLOR_ALL)) { - MEM_freeN(mesh.active_color_attribute); + MEM_SAFE_FREE(mesh.active_color_attribute); } } if (mesh.default_color_attribute) { @@ -875,7 +875,7 @@ static void remove_invalid_attribute_strings(Mesh &mesh) mesh.default_color_attribute); if (!meta_data || !(meta_data->domain & ATTR_DOMAIN_MASK_COLOR) || !(meta_data->data_type & CD_MASK_COLOR_ALL)) { - MEM_freeN(mesh.default_color_attribute); + MEM_SAFE_FREE(mesh.default_color_attribute); } } } From a44c1284823a1017283cec5ff58f099956e03abd Mon Sep 17 00:00:00 2001 From: Sietse Brouwer Date: Fri, 23 Dec 2022 16:02:01 +0100 Subject: [PATCH 0270/1522] GPencil: show brush size in Draw tool cursor When drawing strokes in Grease Pencil, it was always a bit hard to predict how thick the strokes would be, because there was no visual reference of the thickness in the cursor. This patch adds that visual reference. It shows the brush size as a circle in the draw cursor. Showing the brush size can be toggled in the Cursor menu of the Grease Pencil draw tool. Request in RCS with 26 upvotes for this option: https://blender.community/c/rightclickselect/0zfbbc On the technical side: the brush size is calculated in 3D space and takes zoom level into account, as well as object/layer transfrom, layer thickness change (gpl->line_change) and thickness scale (gpd->pixfactor). Reviewed By: mendio, antoniov Differential Revision: https://developer.blender.org/D16851 --- .../bl_ui/properties_grease_pencil_common.py | 10 ++-- .../blender/editors/gpencil/gpencil_utils.c | 58 +++++++++++++++++-- source/blender/makesdna/DNA_brush_enums.h | 2 + source/blender/makesrna/intern/rna_brush.c | 6 ++ 4 files changed, 66 insertions(+), 10 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 3aa8879c594..1e68b2df97d 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -117,11 +117,13 @@ class GreasePencilDisplayPanel: row = layout.row(align=True) row.prop(settings, "show_brush", text="Display Cursor") - col = layout.column(align=True) - col.active = settings.show_brush - if brush.gpencil_tool == 'DRAW': - col.prop(gp_settings, "show_lasso", text="Show Fill Color While Drawing") + row = layout.row(align=True) + row.active = settings.show_brush + row.prop(gp_settings, "show_brush_size", text="Show Brush Size") + row = layout.row(align=True) + row.active = settings.show_brush + row.prop(gp_settings, "show_lasso", text="Show Fill Color While Drawing") elif ob.mode == 'SCULPT_GPENCIL': col = layout.column(align=True) diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 7516e84805c..3abb04c6360 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -1750,6 +1750,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat float color[3] = {1.0f, 1.0f, 1.0f}; float darkcolor[3]; float radius = 3.0f; + bool fixed_radius = true; const int mval_i[2] = {x, y}; /* Check if cursor is in drawing region and has valid data-block. */ @@ -1787,16 +1788,61 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat if (ma) { gp_style = ma->gp_style; - /* after some testing, display the size of the brush is not practical because - * is too disruptive and the size of cursor does not change with zoom factor. - * The decision was to use a fix size, instead of brush->thickness value. + /* Follow user settings for the size of the draw cursor: + * - Fixed size, or + * - Brush size (i.e. stroke thickness) */ if ((gp_style) && GPENCIL_PAINT_MODE(gpd) && ((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) && ((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) && (brush->gpencil_tool == GPAINT_TOOL_DRAW)) { - radius = 2.0f; - copy_v3_v3(color, gp_style->stroke_rgba); + + /* Check user setting for cursor size. */ + fixed_radius = ((brush->gpencil_settings->flag & GP_BRUSH_SHOW_DRAW_SIZE) == 0); + + if (fixed_radius) { + /* Show fixed radius. */ + radius = 2.0f; + copy_v3_v3(color, gp_style->stroke_rgba); + } + else { + /* Show brush size. */ + tGPspoint point2D; + float p1[3]; + float p2[3]; + float distance; + + /* Strokes in screen space or world space? */ + if ((gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS) != 0) { + /* In screen space the cursor radius matches the brush size. */ + radius = (float)brush->size * 0.5f; + } + else { + /* To calculate the brush size in world space, we have to establish the zoom level. + * For this we take two 2D screen coordinates with a fixed offset, + * convert them to 3D coordinates and measure the offset distance in 3D. + * A small distance means a high zoom level. */ + point2D.m_xy[0] = (float)x; + point2D.m_xy[1] = (float)y; + gpencil_stroke_convertcoords_tpoint(scene, region, ob, &point2D, NULL, p1); + point2D.m_xy[0] = (float)(x + 64); + gpencil_stroke_convertcoords_tpoint(scene, region, ob, &point2D, NULL, p2); + /* Clip extreme zoom level (and avoid division by zero). */ + distance = MAX2(len_v3v3(p1, p2), 0.001f); + + /* Handle layer thickness change. */ + float brush_size = (float)brush->size; + bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd); + if (gpl != NULL) { + brush_size = MAX2(1.0f, brush_size + gpl->line_change); + } + + /* Convert the 3D offset distance to a brush radius. */ + radius = (1 / distance) * 2.0f * gpd->pixfactor * (brush_size / 64); + } + + copy_v3_v3(color, brush->rgb); + } } else { /* Only Tint tool must show big cursor. */ @@ -1876,7 +1922,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat /* Inner Ring: Color from UI panel */ immUniformColor4f(color[0], color[1], color[2], 0.8f); - if ((gp_style) && GPENCIL_PAINT_MODE(gpd) && + if ((gp_style) && GPENCIL_PAINT_MODE(gpd) && (fixed_radius) && ((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) && ((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) && (brush->gpencil_tool == GPAINT_TOOL_DRAW)) { diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h index 72357ea6734..ce90a8e05c1 100644 --- a/source/blender/makesdna/DNA_brush_enums.h +++ b/source/blender/makesdna/DNA_brush_enums.h @@ -91,6 +91,8 @@ typedef enum eGPDbrush_Flag { GP_BRUSH_OUTLINE_STROKE = (1 << 17), /* Collide with stroke. */ GP_BRUSH_FILL_STROKE_COLLIDE = (1 << 18), + /* Show brush size */ + GP_BRUSH_SHOW_DRAW_SIZE = (1 << 19), } eGPDbrush_Flag; typedef enum eGPDbrush_Flag2 { diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index ce51b52de39..1d2adc386cf 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -2005,6 +2005,12 @@ static void rna_def_gpencil_options(BlenderRNA *brna) prop, "Show Lasso", "Do not display fill color while drawing the stroke"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + prop = RNA_def_property(srna, "show_brush_size", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_SHOW_DRAW_SIZE); + RNA_def_property_boolean_default(prop, true); + RNA_def_property_ui_text(prop, "Show Brush Size", "Show the real size of the draw brush"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + prop = RNA_def_property(srna, "use_occlude_eraser", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_OCCLUDE_ERASER); RNA_def_property_ui_text(prop, "Occlude Eraser", "Erase only strokes visible and not occluded"); From fea60eccbf49563187ca7025aa68e8547fc2902e Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Fri, 23 Dec 2022 18:58:16 -0500 Subject: [PATCH 0271/1522] UI: Remove unused light object panel This panel showed a duplication of options that were in the main light panel and only mistakenly shows up in the workbench engine where lights should have no options. This panel was also used by the POV-Ray add-on but that was removed recently. --- .../startup/bl_ui/properties_data_light.py | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_light.py b/release/scripts/startup/bl_ui/properties_data_light.py index 2980592ee0b..b313ae4dcb9 100644 --- a/release/scripts/startup/bl_ui/properties_data_light.py +++ b/release/scripts/startup/bl_ui/properties_data_light.py @@ -227,32 +227,6 @@ class DATA_PT_EEVEE_shadow_contact(DataButtonsPanel, Panel): col.prop(light, "contact_shadow_thickness", text="Thickness") -class DATA_PT_area(DataButtonsPanel, Panel): - bl_label = "Area Shape" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_WORKBENCH'} - - @classmethod - def poll(cls, context): - light = context.light - engine = context.engine - return (light and light.type == 'AREA') and (engine in cls.COMPAT_ENGINES) - - def draw(self, context): - layout = self.layout - - light = context.light - - col = layout.column() - col.row().prop(light, "shape", expand=True) - sub = col.row(align=True) - - if light.shape in {'SQUARE', 'DISK'}: - sub.prop(light, "size") - elif light.shape in {'RECTANGLE', 'ELLIPSE'}: - sub.prop(light, "size", text="Size X") - sub.prop(light, "size_y", text="Size Y") - - class DATA_PT_spot(DataButtonsPanel, Panel): bl_label = "Spot Shape" bl_parent_id = "DATA_PT_EEVEE_light" @@ -315,7 +289,6 @@ classes = ( DATA_PT_EEVEE_shadow, DATA_PT_EEVEE_shadow_cascaded_shadow_map, DATA_PT_EEVEE_shadow_contact, - DATA_PT_area, DATA_PT_spot, DATA_PT_falloff_curve, DATA_PT_custom_props_light, From 014d0a8edee42fd3f2c30d55901a3459f41c31bb Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Fri, 23 Dec 2022 19:00:02 -0500 Subject: [PATCH 0272/1522] Update RNA to User manual mappings --- .../scripts/modules/rna_manual_reference.py | 161 ++++++++++++++---- 1 file changed, 124 insertions(+), 37 deletions(-) diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index dfebf9132d2..7dc62e6270b 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -49,16 +49,17 @@ url_manual_mapping = ( ("bpy.types.movietrackingsettings.refine_intrinsics_principal_point*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-principal-point"), ("bpy.types.cyclesobjectsettings.shadow_terminator_geometry_offset*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-shadow-terminator-geometry-offset"), ("bpy.types.sequencertoolsettings.use_snap_current_frame_to_strips*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-use-snap-current-frame-to-strips"), + ("bpy.types.clothcollisionsettings.vertex_group_object_collisions*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-vertex-group-object-collisions"), ("bpy.types.cycleslightsettings.use_multiple_importance_sampling*", "render/cycles/light_settings.html#bpy-types-cycleslightsettings-use-multiple-importance-sampling"), ("bpy.types.fluiddomainsettings.sndparticle_potential_max_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-energy"), ("bpy.types.fluiddomainsettings.sndparticle_potential_min_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-energy"), ("bpy.types.lineartgpencilmodifier.use_overlap_edge_type_support*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-overlap-edge-type-support"), ("bpy.types.movietrackingsettings.refine_intrinsics_focal_length*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-refine-intrinsics-focal-length"), ("bpy.types.rigidbodyconstraint.rigidbodyconstraint.use_breaking*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-rigidbodyconstraint-use-breaking"), + ("bpy.types.clothcollisionsettings.vertex_group_self_collisions*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-vertex-group-self-collisions"), ("bpy.types.cyclesrendersettings.preview_denoising_input_passes*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-input-passes"), ("bpy.types.cyclesrendersettings.preview_denoising_start_sample*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-start-sample"), ("bpy.types.fluiddomainsettings.sndparticle_sampling_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-trappedair"), - ("bpy.types.brush.automasking_boundary_edges_propagation_steps*", "sculpt_paint/sculpting/controls.html#bpy-types-brush-automasking-boundary-edges-propagation-steps"), ("bpy.types.fluiddomainsettings.sndparticle_sampling_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-wavecrest"), ("bpy.types.lineartgpencilmodifier.use_image_boundary_trimming*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-image-boundary-trimming"), ("bpy.types.materiallineart.use_intersection_priority_override*", "render/materials/line_art.html#bpy-types-materiallineart-use-intersection-priority-override"), @@ -70,11 +71,13 @@ url_manual_mapping = ( ("bpy.types.lineartgpencilmodifier.use_face_mark_keep_contour*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-face-mark-keep-contour"), ("bpy.types.rendersettings.use_sequencer_override_scene_strip*", "editors/video_sequencer/preview/sidebar.html#bpy-types-rendersettings-use-sequencer-override-scene-strip"), ("bpy.types.toolsettings.use_transform_correct_keep_connected*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-use-transform-correct-keep-connected"), + ("bpy.types.clothsettings.internal_compression_stiffness_max*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-compression-stiffness-max"), ("bpy.types.cyclesrendersettings.preview_denoising_prefilter*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-prefilter"), ("bpy.types.cyclesrendersettings.preview_scrambling_distance*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-scrambling-distance"), ("bpy.types.fluiddomainsettings.sndparticle_potential_radius*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-radius"), ("bpy.types.objectlineart.use_intersection_priority_override*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-use-intersection-priority-override"), ("bpy.types.brushgpencilsettings.use_stroke_random_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-strength"), + ("bpy.types.clothsettings.vertex_group_structural_stiffness*", "physics/cloth/settings/property_weights.html#bpy-types-clothsettings-vertex-group-structural-stiffness"), ("bpy.types.cyclesrendersettings.film_transparent_roughness*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-film-transparent-roughness"), ("bpy.types.cyclesrendersettings.preview_adaptive_threshold*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-adaptive-threshold"), ("bpy.types.fluiddomainsettings.openvdb_cache_compress_type*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-openvdb-cache-compress-type"), @@ -101,6 +104,7 @@ url_manual_mapping = ( ("bpy.types.cyclesobjectsettings.shadow_terminator_offset*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-shadow-terminator-offset"), ("bpy.types.cyclesobjectsettings.use_adaptive_subdivision*", "render/cycles/object_settings/adaptive_subdiv.html#bpy-types-cyclesobjectsettings-use-adaptive-subdivision"), ("bpy.types.cyclesrendersettings.debug_use_spatial_splits*", "render/cycles/render_settings/performance.html#bpy-types-cyclesrendersettings-debug-use-spatial-splits"), + ("bpy.types.cyclesrendersettings.guiding_training_samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-guiding-training-samples"), ("bpy.types.cyclesrendersettings.light_sampling_threshold*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-light-sampling-threshold"), ("bpy.types.cyclesrendersettings.rolling_shutter_duration*", "render/cycles/render_settings/motion_blur.html#bpy-types-cyclesrendersettings-rolling-shutter-duration"), ("bpy.types.cyclesrendersettings.volume_preview_step_rate*", "render/cycles/render_settings/volumes.html#bpy-types-cyclesrendersettings-volume-preview-step-rate"), @@ -113,6 +117,8 @@ url_manual_mapping = ( ("bpy.types.brushgpencilsettings.eraser_thickness_factor*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-thickness-factor"), ("bpy.types.brushgpencilsettings.use_random_press_radius*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-radius"), ("bpy.types.brushgpencilsettings.use_settings_stabilizer*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-stabilizer"), + ("bpy.types.clothsettings.internal_compression_stiffness*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-compression-stiffness"), + ("bpy.types.clothsettings.internal_tension_stiffness_max*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-tension-stiffness-max"), ("bpy.types.collection.use_lineart_intersection_priority*", "scene_layout/collections/collections.html#bpy-types-collection-use-lineart-intersection-priority"), ("bpy.types.colormanagedsequencercolorspacesettings.name*", "render/color_management.html#bpy-types-colormanagedsequencercolorspacesettings-name"), ("bpy.types.cyclesrendersettings.max_transparent_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-max-transparent-bounces"), @@ -133,6 +139,7 @@ url_manual_mapping = ( ("bpy.types.brush.show_multiplane_scrape_planes_preview*", "sculpt_paint/sculpting/tools/multiplane_scrape.html#bpy-types-brush-show-multiplane-scrape-planes-preview"), ("bpy.types.brushcurvessculptsettings.interpolate_shape*", "sculpt_paint/curves_sculpting/tools/add_curves.html#bpy-types-brushcurvessculptsettings-interpolate-shape"), ("bpy.types.brushgpencilsettings.eraser_strength_factor*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-strength-factor"), + ("bpy.types.clothsettings.internal_spring_max_diversion*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-spring-max-diversion"), ("bpy.types.cyclesmaterialsettings.volume_interpolation*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-volume-interpolation"), ("bpy.types.cyclesrendersettings.denoising_input_passes*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-denoising-input-passes"), ("bpy.types.cyclesrendersettings.film_transparent_glass*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-film-transparent-glass"), @@ -154,6 +161,8 @@ url_manual_mapping = ( ("bpy.types.brushgpencilsettings.use_stroke_random_hue*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-hue"), ("bpy.types.brushgpencilsettings.use_stroke_random_sat*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-sat"), ("bpy.types.brushgpencilsettings.use_stroke_random_val*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-val"), + ("bpy.types.clothsettings.internal_spring_normal_check*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-spring-normal-check"), + ("bpy.types.clothsettings.vertex_group_shear_stiffness*", "physics/cloth/settings/property_weights.html#bpy-types-clothsettings-vertex-group-shear-stiffness"), ("bpy.types.colormanageddisplaysettings.display_device*", "render/color_management.html#bpy-types-colormanageddisplaysettings-display-device"), ("bpy.types.colormanagedviewsettings.use_curve_mapping*", "render/color_management.html#bpy-types-colormanagedviewsettings-use-curve-mapping"), ("bpy.types.cyclesrendersettings.sample_clamp_indirect*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-sample-clamp-indirect"), @@ -182,6 +191,8 @@ url_manual_mapping = ( ("bpy.types.brushgpencilsettings.use_random_press_val*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-val"), ("bpy.types.brushgpencilsettings.use_settings_outline*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-outline"), ("bpy.types.brushgpencilsettings.use_stroke_random_uv*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-stroke-random-uv"), + ("bpy.types.clothcollisionsettings.self_impulse_clamp*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-self-impulse-clamp"), + ("bpy.types.clothcollisionsettings.use_self_collision*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-use-self-collision"), ("bpy.types.cyclesmaterialsettings.homogeneous_volume*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-homogeneous-volume"), ("bpy.types.cyclesobjectsettings.is_caustics_receiver*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-is-caustics-receiver"), ("bpy.types.cyclesrendersettings.adaptive_min_samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-adaptive-min-samples"), @@ -212,20 +223,26 @@ url_manual_mapping = ( ("bpy.types.animvizmotionpaths.show_keyframe_numbers*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-keyframe-numbers"), ("bpy.types.brush.cloth_constraint_softbody_strength*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-constraint-softbody-strength"), ("bpy.types.brush.elastic_deform_volume_preservation*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-volume-preservation"), - ("bpy.types.brush.use_automasking_boundary_face_sets*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-use-automasking-boundary-face-sets"), ("bpy.types.brushcurvessculptsettings.minimum_length*", "sculpt_paint/curves_sculpting/tools/grow_shrink_curves.html#bpy-types-brushcurvessculptsettings-minimum-length"), ("bpy.types.brushgpencilsettings.fill_simplify_level*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-simplify-level"), ("bpy.types.brushgpencilsettings.random_value_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-value-factor"), + ("bpy.types.brushgpencilsettings.use_collide_strokes*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-use-collide-strokes"), ("bpy.types.brushgpencilsettings.use_jitter_pressure*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-jitter-pressure"), ("bpy.types.brushgpencilsettings.use_random_press_uv*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-random-press-uv"), ("bpy.types.brushgpencilsettings.use_settings_random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-settings-random"), + ("bpy.types.clothcollisionsettings.collision_quality*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-collision-quality"), + ("bpy.types.clothcollisionsettings.self_distance_min*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-self-distance-min"), + ("bpy.types.clothsettings.internal_spring_max_length*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-spring-max-length"), + ("bpy.types.clothsettings.internal_tension_stiffness*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-tension-stiffness"), ("bpy.types.collection.lineart_intersection_priority*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-intersection-priority"), ("bpy.types.collection.lineart_use_intersection_mask*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-use-intersection-mask"), ("bpy.types.colormanagedinputcolorspacesettings.name*", "editors/image/image_settings.html#bpy-types-colormanagedinputcolorspacesettings-name"), + ("bpy.types.cyclesmaterialsettings.emission_sampling*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-emission-sampling"), ("bpy.types.cyclesrendersettings.denoising_prefilter*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-denoising-prefilter"), ("bpy.types.cyclesrendersettings.preview_dicing_rate*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-preview-dicing-rate"), ("bpy.types.cyclesrendersettings.sample_clamp_direct*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-sample-clamp-direct"), ("bpy.types.cyclesrendersettings.scrambling_distance*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-scrambling-distance"), + ("bpy.types.cyclesrendersettings.use_surface_guiding*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-surface-guiding"), ("bpy.types.cyclesworldsettings.volume_interpolation*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-volume-interpolation"), ("bpy.types.fluiddomainsettings.mesh_particle_radius*", "physics/fluid/type/domain/liquid/mesh.html#bpy-types-fluiddomainsettings-mesh-particle-radius"), ("bpy.types.fluiddomainsettings.sndparticle_boundary*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-boundary"), @@ -253,6 +270,7 @@ url_manual_mapping = ( ("bpy.types.brushcurvessculptsettings.scale_uniform*", "sculpt_paint/curves_sculpting/tools/grow_shrink_curves.html#bpy-types-brushcurvessculptsettings-scale-uniform"), ("bpy.types.brushgpencilsettings.show_fill_boundary*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-show-fill-boundary"), ("bpy.types.brushgpencilsettings.use_default_eraser*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-use-default-eraser"), + ("bpy.types.clothsettings.compression_stiffness_max*", "physics/cloth/settings/property_weights.html#bpy-types-clothsettings-compression-stiffness-max"), ("bpy.types.colormanagedsequencercolorspacesettings*", "render/color_management.html#bpy-types-colormanagedsequencercolorspacesettings"), ("bpy.types.colormanagedviewsettings.view_transform*", "render/color_management.html#bpy-types-colormanagedviewsettings-view-transform"), ("bpy.types.cyclesmaterialsettings.volume_step_rate*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-volume-step-rate"), @@ -260,6 +278,7 @@ url_manual_mapping = ( ("bpy.types.cyclesrendersettings.adaptive_threshold*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-adaptive-threshold"), ("bpy.types.cyclesrendersettings.camera_cull_margin*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-camera-cull-margin"), ("bpy.types.cyclesrendersettings.debug_use_hair_bvh*", "render/cycles/render_settings/performance.html#bpy-types-cyclesrendersettings-debug-use-hair-bvh"), + ("bpy.types.cyclesrendersettings.use_volume_guiding*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-volume-guiding"), ("bpy.types.fileassetselectparams.asset_library_ref*", "editors/asset_browser.html#bpy-types-fileassetselectparams-asset-library-ref"), ("bpy.types.fluiddomainsettings.export_manta_script*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-export-manta-script"), ("bpy.types.fluiddomainsettings.fractions_threshold*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-fractions-threshold"), @@ -283,6 +302,7 @@ url_manual_mapping = ( ("bpy.types.movietrackingsettings.use_tripod_solver*", "movie_clip/tracking/clip/toolbar/solve.html#bpy-types-movietrackingsettings-use-tripod-solver"), ("bpy.types.rendersettings.simplify_child_particles*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-child-particles"), ("bpy.types.rendersettings.use_high_quality_normals*", "render/eevee/render_settings/performance.html#bpy-types-rendersettings-use-high-quality-normals"), + ("bpy.types.sculpt.automasking_start_normal_falloff*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-automasking-start-normal-falloff"), ("bpy.types.sequencerpreviewoverlay.show_annotation*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-annotation"), ("bpy.types.sequencerpreviewoverlay.show_safe_areas*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-safe-areas"), ("bpy.types.sequencertoolsettings.snap_ignore_muted*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-snap-ignore-muted"), @@ -302,7 +322,6 @@ url_manual_mapping = ( ("bpy.types.brushgpencilsettings.pen_smooth_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-smooth-factor"), ("bpy.types.brushgpencilsettings.random_hue_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-hue-factor"), ("bpy.types.cyclescurverendersettings.subdivisions*", "render/cycles/render_settings/hair.html#bpy-types-cyclescurverendersettings-subdivisions"), - ("bpy.types.cyclesmaterialsettings.sample_as_light*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-sample-as-light"), ("bpy.types.cyclesmaterialsettings.volume_sampling*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-volume-sampling"), ("bpy.types.cyclesobjectsettings.use_deform_motion*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-use-deform-motion"), ("bpy.types.cyclesobjectsettings.use_distance_cull*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-use-distance-cull"), @@ -333,6 +352,7 @@ url_manual_mapping = ( ("bpy.types.movietrackingdopesheet.use_invert_sort*", "movie_clip/tracking/dope_sheet.html#bpy-types-movietrackingdopesheet-use-invert-sort"), ("bpy.types.rendersettings_simplify_gpencil_onplay*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-onplay"), ("bpy.types.rigidbodyconstraint.breaking_threshold*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-breaking-threshold"), + ("bpy.types.sculpt.use_automasking_cavity_inverted*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-cavity-inverted"), ("bpy.types.spaceclipeditor.use_manual_calibration*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-manual-calibration"), ("bpy.types.spacedopesheeteditor.show_pose_markers*", "animation/markers.html#bpy-types-spacedopesheeteditor-show-pose-markers"), ("bpy.types.spaceimageoverlay.show_grid_background*", "editors/uv/overlays.html#bpy-types-spaceimageoverlay-show-grid-background"), @@ -349,6 +369,7 @@ url_manual_mapping = ( ("bpy.types.toolsettings.use_snap_uv_grid_absolute*", "editors/uv/controls/snapping.html#bpy-types-toolsettings-use-snap-uv-grid-absolute"), ("bpy.types.toolsettings.use_transform_data_origin*", "scene_layout/object/tools/tool_settings.html#bpy-types-toolsettings-use-transform-data-origin"), ("bpy.types.view3doverlay.sculpt_mode_mask_opacity*", "sculpt_paint/sculpting/editing/mask.html#bpy-types-view3doverlay-sculpt-mode-mask-opacity"), + ("bpy.types.view3doverlay.viewer_attribute_opacity*", "modeling/geometry_nodes/output/viewer.html#bpy-types-view3doverlay-viewer-attribute-opacity"), ("bpy.ops.mesh.customdata_bevel_weight_edge_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-bevel-weight-edge-clear"), ("bpy.ops.mesh.customdata_bevel_weight_vertex_add*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-bevel-weight-vertex-add"), ("bpy.ops.mesh.customdata_custom_splitnormals_add*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-custom-splitnormals-add"), @@ -357,13 +378,14 @@ url_manual_mapping = ( ("bpy.types.brushgpencilsettings.fill_extend_mode*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-extend-mode"), ("bpy.types.brushgpencilsettings.pen_smooth_steps*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-smooth-steps"), ("bpy.types.brushgpencilsettings.show_fill_extend*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-show-fill-extend"), + ("bpy.types.brushgpencilsettings.use_collide_only*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-use-collide-only"), ("bpy.types.cycleslightsettings.is_caustics_light*", "render/cycles/light_settings.html#bpy-types-cycleslightsettings-is-caustics-light"), ("bpy.types.cyclesrendersettings.max_subdivisions*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-max-subdivisions"), ("bpy.types.cyclesrendersettings.preview_denoiser*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoiser"), - ("bpy.types.cyclesrendersettings.sampling_pattern*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-sampling-pattern"), ("bpy.types.cyclesrendersettings.volume_max_steps*", "render/cycles/render_settings/volumes.html#bpy-types-cyclesrendersettings-volume-max-steps"), ("bpy.types.cyclesrendersettings.volume_step_rate*", "render/cycles/render_settings/volumes.html#bpy-types-cyclesrendersettings-volume-step-rate"), ("bpy.types.cyclesworldsettings.is_caustics_light*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-is-caustics-light"), + ("bpy.types.dynamicpaintbrushsettings.wave_factor*", "physics/dynamic_paint/brush.html#bpy-types-dynamicpaintbrushsettings-wave-factor"), ("bpy.types.editbone.bbone_handle_use_scale_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-scale-start"), ("bpy.types.fluiddomainsettings.cache_data_format*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-data-format"), ("bpy.types.fluiddomainsettings.cache_frame_start*", "physics/fluid/type/domain/cache.html#bpy-types-fluiddomainsettings-cache-frame-start"), @@ -392,6 +414,7 @@ url_manual_mapping = ( ("bpy.types.movietrackingplanetrack.image_opacity*", "movie_clip/tracking/clip/sidebar/track/plane_track.html#bpy-types-movietrackingplanetrack-image-opacity"), ("bpy.types.particlesettings.use_parent_particles*", "physics/particles/emitter/render.html#bpy-types-particlesettings-use-parent-particles"), ("bpy.types.rigidbodyconstraint.solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-solver-iterations"), + ("bpy.types.sculpt.automasking_start_normal_limit*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-automasking-start-normal-limit"), ("bpy.types.sculpt.use_automasking_boundary_edges*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-boundary-edges"), ("bpy.types.sequenceeditor.use_overlay_frame_lock*", "editors/video_sequencer/preview/sidebar.html#bpy-types-sequenceeditor-use-overlay-frame-lock"), ("bpy.types.sequencerpreviewoverlay.show_metadata*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-metadata"), @@ -407,11 +430,14 @@ url_manual_mapping = ( ("bpy.types.viewlayer.use_pass_cryptomatte_object*", "render/layers/passes.html#bpy-types-viewlayer-use-pass-cryptomatte-object"), ("bpy.ops.armature.rigify_apply_selection_colors*", "addons/rigging/rigify/metarigs.html#bpy-ops-armature-rigify-apply-selection-colors"), ("bpy.ops.ed.lib_id_generate_preview_from_object*", "editors/asset_browser.html#bpy-ops-ed-lib-id-generate-preview-from-object"), - ("bpy.types.brush.use_automasking_boundary_edges*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-use-automasking-boundary-edges"), ("bpy.types.brushcurvessculptsettings.add_amount*", "sculpt_paint/curves_sculpting/tools/add_curves.html#bpy-types-brushcurvessculptsettings-add-amount"), ("bpy.types.brushgpencilsettings.fill_layer_mode*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-layer-mode"), ("bpy.types.brushgpencilsettings.random_strength*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random-strength"), ("bpy.types.brushgpencilsettings.simplify_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-simplify-factor"), + ("bpy.types.clothcollisionsettings.impulse_clamp*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-impulse-clamp"), + ("bpy.types.clothcollisionsettings.self_friction*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-self-friction"), + ("bpy.types.clothcollisionsettings.use_collision*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-use-collision"), + ("bpy.types.clothsettings.uniform_pressure_force*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-uniform-pressure-force"), ("bpy.types.collection.lineart_intersection_mask*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-intersection-mask"), ("bpy.types.cyclesobjectsettings.use_camera_cull*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-use-camera-cull"), ("bpy.types.cyclesobjectsettings.use_motion_blur*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-use-motion-blur"), @@ -419,6 +445,7 @@ url_manual_mapping = ( ("bpy.types.cyclesrendersettings.preview_samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-samples"), ("bpy.types.cyclesrendersettings.use_camera_cull*", "render/cycles/render_settings/simplify.html#bpy-types-cyclesrendersettings-use-camera-cull"), ("bpy.types.cyclesworldsettings.volume_step_size*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-volume-step-size"), + ("bpy.types.dynamicpaintbrushsettings.wave_clamp*", "physics/dynamic_paint/brush.html#bpy-types-dynamicpaintbrushsettings-wave-clamp"), ("bpy.types.editbone.bbone_handle_use_ease_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-ease-start"), ("bpy.types.fluiddomainsettings.color_ramp_field*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-color-ramp-field"), ("bpy.types.fluiddomainsettings.guide_vel_factor*", "physics/fluid/type/domain/guides.html#bpy-types-fluiddomainsettings-guide-vel-factor"), @@ -430,6 +457,7 @@ url_manual_mapping = ( ("bpy.types.freestylelinestyle.use_split_pattern*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-split-pattern"), ("bpy.types.freestylesettings.use_view_map_cache*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-view-map-cache"), ("bpy.types.geometrynodecurvehandletypeselection*", "modeling/geometry_nodes/curve/handle_type_selection.html#bpy-types-geometrynodecurvehandletypeselection"), + ("bpy.types.geometrynodedistributepointsinvolume*", "modeling/geometry_nodes/point/distribute_points_in_volume.html#bpy-types-geometrynodedistributepointsinvolume"), ("bpy.types.geometrynodeinputmeshvertexneighbors*", "modeling/geometry_nodes/mesh/vertex_neighbors.html#bpy-types-geometrynodeinputmeshvertexneighbors"), ("bpy.types.greasepencil.curve_edit_corner_angle*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-corner-angle"), ("bpy.types.imageformatsettings.color_management*", "render/output/properties/output.html#bpy-types-imageformatsettings-color-management"), @@ -466,13 +494,19 @@ url_manual_mapping = ( ("bpy.types.brushgpencilsettings.fill_draw_mode*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-draw-mode"), ("bpy.types.brushgpencilsettings.fill_threshold*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-threshold"), ("bpy.types.brushgpencilsettings.use_fill_limit*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-use-fill-limit"), + ("bpy.types.clothcollisionsettings.distance_min*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-distance-min"), + ("bpy.types.clothsettings.bending_stiffness_max*", "physics/cloth/settings/property_weights.html#bpy-types-clothsettings-bending-stiffness-max"), + ("bpy.types.clothsettings.compression_stiffness*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-compression-stiffness"), + ("bpy.types.clothsettings.tension_stiffness_max*", "physics/cloth/settings/property_weights.html#bpy-types-clothsettings-tension-stiffness-max"), ("bpy.types.clothsettings.vertex_group_pressure*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-vertex-group-pressure"), ("bpy.types.cyclesmaterialsettings.displacement*", "render/cycles/material_settings.html#bpy-types-cyclesmaterialsettings-displacement"), ("bpy.types.cyclesrendersettings.fast_gi_method*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-fast-gi-method"), ("bpy.types.cyclesrendersettings.glossy_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-glossy-bounces"), + ("bpy.types.cyclesrendersettings.use_light_tree*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-light-tree"), ("bpy.types.cyclesrendersettings.volume_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-volume-bounces"), ("bpy.types.cyclesworldsettings.sampling_method*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-sampling-method"), ("bpy.types.cyclesworldsettings.volume_sampling*", "render/cycles/world_settings.html#bpy-types-cyclesworldsettings-volume-sampling"), + ("bpy.types.dynamicpaintbrushsettings.wave_type*", "physics/dynamic_paint/brush.html#bpy-types-dynamicpaintbrushsettings-wave-type"), ("bpy.types.editbone.bbone_handle_use_scale_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-use-scale-end"), ("bpy.types.ffmpegsettings.constant_rate_factor*", "render/output/properties/output.html#bpy-types-ffmpegsettings-constant-rate-factor"), ("bpy.types.fieldsettings.use_guide_path_weight*", "physics/forces/force_fields/types/curve_guide.html#bpy-types-fieldsettings-use-guide-path-weight"), @@ -504,6 +538,7 @@ url_manual_mapping = ( ("bpy.types.particlesettings.use_modifier_stack*", "physics/particles/emitter/emission.html#bpy-types-particlesettings-use-modifier-stack"), ("bpy.types.rendersettings.sequencer_gl_preview*", "editors/video_sequencer/preview/sidebar.html#bpy-types-rendersettings-sequencer-gl-preview"), ("bpy.types.rendersettings.simplify_subdivision*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-subdivision"), + ("bpy.types.sculpt.use_automasking_start_normal*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-start-normal"), ("bpy.types.sequencerpreviewoverlay.show_cursor*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-cursor"), ("bpy.types.spacegrapheditor.show_extrapolation*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-extrapolation"), ("bpy.types.spaceoutliner.use_filter_collection*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-collection"), @@ -516,6 +551,7 @@ url_manual_mapping = ( ("bpy.types.spacespreadsheetrowfilter.threshold*", "editors/spreadsheet.html#bpy-types-spacespreadsheetrowfilter-threshold"), ("bpy.types.toolsettings.use_snap_grid_absolute*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-grid-absolute"), ("bpy.types.view3doverlay.show_face_orientation*", "editors/3dview/display/overlays.html#bpy-types-view3doverlay-show-face-orientation"), + ("bpy.types.view3doverlay.show_viewer_attribute*", "modeling/geometry_nodes/output/viewer.html#bpy-types-view3doverlay-show-viewer-attribute"), ("bpy.ops.gpencil.bake_grease_pencil_animation*", "grease_pencil/animation/tools.html#bpy-ops-gpencil-bake-grease-pencil-animation"), ("bpy.ops.object.multires_higher_levels_delete*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-higher-levels-delete"), ("bpy.ops.object.vertex_group_copy_to_selected*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-copy-to-selected"), @@ -523,7 +559,8 @@ url_manual_mapping = ( ("bpy.ops.view3d.edit_mesh_extrude_move_normal*", "modeling/meshes/editing/face/extrude_faces.html#bpy-ops-view3d-edit-mesh-extrude-move-normal"), ("bpy.types.bakesettings.use_pass_transmission*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-transmission"), ("bpy.types.brushgpencilsettings.input_samples*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-input-samples"), - ("bpy.types.clothsettings.internal_compression*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-compression"), + ("bpy.types.clothsettings.use_internal_springs*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-internal-springs"), + ("bpy.types.clothsettings.vertex_group_bending*", "physics/cloth/settings/property_weights.html#bpy-types-clothsettings-vertex-group-bending"), ("bpy.types.cyclescamerasettings.panorama_type*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-panorama-type"), ("bpy.types.cyclesrendersettings.dicing_camera*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-dicing-camera"), ("bpy.types.cyclesrendersettings.film_exposure*", "render/cycles/render_settings/film.html#bpy-types-cyclesrendersettings-film-exposure"), @@ -569,9 +606,11 @@ url_manual_mapping = ( ("bpy.types.movietrackingdopesheet.sort_method*", "movie_clip/tracking/dope_sheet.html#bpy-types-movietrackingdopesheet-sort-method"), ("bpy.types.movietrackingtrack.use_red_channel*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-use-red-channel"), ("bpy.types.nodesocketinterface*.default_value*", "interface/controls/nodes/groups.html#bpy-types-nodesocketinterface-default-value"), + ("bpy.types.object.add_rest_position_attribute*", "animation/shape_keys/shape_keys_panel.html#bpy-types-object-add-rest-position-attribute"), ("bpy.types.rendersettings.line_thickness_mode*", "render/freestyle/render.html#bpy-types-rendersettings-line-thickness-mode"), ("bpy.types.rendersettings.motion_blur_shutter*", "render/cycles/render_settings/motion_blur.html#bpy-types-rendersettings-motion-blur-shutter"), ("bpy.types.rendersettings.use_persistent_data*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-use-persistent-data"), + ("bpy.types.sculpt.use_automasking_view_normal*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-view-normal"), ("bpy.types.sequencertimelineoverlay.show_grid*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-grid"), ("bpy.types.sequencertoolsettings.overlap_mode*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-overlap-mode"), ("bpy.types.spaceclipeditor.show_green_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-green-channel"), @@ -580,6 +619,7 @@ url_manual_mapping = ( ("bpy.types.spacesequenceeditor.use_clamp_view*", "editors/video_sequencer/sequencer/navigating.html#bpy-types-spacesequenceeditor-use-clamp-view"), ("bpy.types.spacespreadsheet.object_eval_state*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-object-eval-state"), ("bpy.types.spaceuveditor.display_stretch_type*", "editors/uv/overlays.html#bpy-types-spaceuveditor-display-stretch-type"), + ("bpy.types.spaceuveditor.show_grid_over_image*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-grid-over-image"), ("bpy.types.toolsettings.transform_pivot_point*", "editors/3dview/controls/pivot_point/index.html#bpy-types-toolsettings-transform-pivot-point"), ("bpy.types.toolsettings.use_proportional_edit*", "editors/3dview/controls/proportional_editing.html#bpy-types-toolsettings-use-proportional-edit"), ("bpy.types.toolsettings.uv_sticky_select_mode*", "editors/uv/selecting.html#bpy-types-toolsettings-uv-sticky-select-mode"), @@ -589,8 +629,12 @@ url_manual_mapping = ( ("bpy.types.brush.html#bpy.types.brush.jitter*", "sculpt_paint/brush/stroke.html#bpy-types-brush-html-bpy-types-brush-jitter"), ("bpy.types.brushgpencilsettings.angle_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle-factor"), ("bpy.types.brushgpencilsettings.pen_strength*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-pen-strength"), + ("bpy.types.clothcollisionsettings.collection*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-collection"), + ("bpy.types.clothsettings.compression_damping*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-compression-damping"), + ("bpy.types.clothsettings.shear_stiffness_max*", "physics/cloth/settings/property_weights.html#bpy-types-clothsettings-shear-stiffness-max"), ("bpy.types.clothsettings.use_pressure_volume*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-pressure-volume"), ("bpy.types.clothsettings.vertex_group_intern*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-vertex-group-intern"), + ("bpy.types.clothsettings.vertex_group_shrink*", "physics/cloth/settings/property_weights.html#bpy-types-clothsettings-vertex-group-shrink"), ("bpy.types.colormanagedviewsettings.exposure*", "render/color_management.html#bpy-types-colormanagedviewsettings-exposure"), ("bpy.types.cyclescamerasettings.fisheye_lens*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-fisheye-lens"), ("bpy.types.cyclesobjectsettings.motion_steps*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-motion-steps"), @@ -654,6 +698,7 @@ url_manual_mapping = ( ("bpy.types.brush.cloth_simulation_area_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-simulation-area-type"), ("bpy.types.brushgpencilsettings.eraser_mode*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-eraser-mode"), ("bpy.types.brushgpencilsettings.fill_factor*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-fill-factor"), + ("bpy.types.clothsettings.use_sewing_springs*", "physics/cloth/settings/shape.html#bpy-types-clothsettings-use-sewing-springs"), ("bpy.types.curve.bevel_factor_mapping_start*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-mapping-start"), ("bpy.types.cyclescamerasettings.fisheye_fov*", "render/cycles/object_settings/cameras.html#bpy-types-cyclescamerasettings-fisheye-fov"), ("bpy.types.cyclesobjectsettings.ao_distance*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-ao-distance"), @@ -662,6 +707,7 @@ url_manual_mapping = ( ("bpy.types.cyclesrendersettings.dicing_rate*", "render/cycles/render_settings/subdivision.html#bpy-types-cyclesrendersettings-dicing-rate"), ("bpy.types.cyclesrendersettings.max_bounces*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-max-bounces"), ("bpy.types.cyclesrendersettings.use_fast_gi*", "render/cycles/render_settings/light_paths.html#bpy-types-cyclesrendersettings-use-fast-gi"), + ("bpy.types.cyclesrendersettings.use_guiding*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-use-guiding"), ("bpy.types.editbone.bbone_custom_handle_end*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-custom-handle-end"), ("bpy.types.editbone.bbone_handle_type_start*", "animation/armatures/bones/properties/bendy_bones.html#bpy-types-editbone-bbone-handle-type-start"), ("bpy.types.fieldsettings.guide_clump_amount*", "physics/forces/force_fields/types/curve_guide.html#bpy-types-fieldsettings-guide-clump-amount"), @@ -687,6 +733,7 @@ url_manual_mapping = ( ("bpy.types.geometrynodecurveprimitivecircle*", "modeling/geometry_nodes/curve_primitives/curve_circle.html#bpy-types-geometrynodecurveprimitivecircle"), ("bpy.types.geometrynodecurvequadraticbezier*", "modeling/geometry_nodes/curve_primitives/quadratic_bezier.html#bpy-types-geometrynodecurvequadraticbezier"), ("bpy.types.geometrynoderemovenamedattribute*", "modeling/geometry_nodes/attribute/remove_named_attribute.html#bpy-types-geometrynoderemovenamedattribute"), + ("bpy.types.geometrynodesamplenearestsurface*", "modeling/geometry_nodes/mesh/sample_nearest_surface.html#bpy-types-geometrynodesamplenearestsurface"), ("bpy.types.gpencillayer.use_viewlayer_masks*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-viewlayer-masks"), ("bpy.types.greasepencil.onion_keyframe_type*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-keyframe-type"), ("bpy.types.lineartgpencilmodifier.use_cache*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-cache"), @@ -718,16 +765,18 @@ url_manual_mapping = ( ("bpy.ops.object.vertex_group_normalize_all*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-normalize-all"), ("bpy.ops.outliner.collection_color_tag_set*", "editors/outliner/editing.html#bpy-ops-outliner-collection-color-tag-set"), ("bpy.ops.outliner.collection_enable_render*", "editors/outliner/editing.html#bpy-ops-outliner-collection-enable-render"), - ("bpy.ops.outliner.collection_exclude_clear*", "render/layers/introduction.html#bpy-ops-outliner-collection-exclude-clear"), + ("bpy.ops.outliner.collection_exclude_clear*", "editors/outliner/editing.html#bpy-ops-outliner-collection-exclude-clear"), ("bpy.ops.outliner.collection_holdout_clear*", "render/layers/introduction.html#bpy-ops-outliner-collection-holdout-clear"), ("bpy.ops.sculpt.face_set_change_visibility*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-set-change-visibility"), ("bpy.ops.sculpt.face_sets_randomize_colors*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-face-sets-randomize-colors"), ("bpy.types.animvizmotionpaths.frame_before*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-before"), ("bpy.types.brush.disconnected_distance_max*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-disconnected-distance-max"), ("bpy.types.brush.surface_smooth_iterations*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-surface-smooth-iterations"), - ("bpy.types.brush.use_automasking_face_sets*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-use-automasking-face-sets"), ("bpy.types.brushgpencilsettings.pen_jitter*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-pen-jitter"), ("bpy.types.brushgpencilsettings.show_lasso*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-show-lasso"), + ("bpy.types.clothsettings.bending_stiffness*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-bending-stiffness"), + ("bpy.types.clothsettings.tension_stiffness*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-tension-stiffness"), + ("bpy.types.clothsettings.vertex_group_mass*", "physics/cloth/settings/shape.html#bpy-types-clothsettings-vertex-group-mass"), ("bpy.types.compositornodeconvertcolorspace*", "compositing/types/converter/color_space.html#bpy-types-compositornodeconvertcolorspace"), ("bpy.types.cyclescurverendersettings.shape*", "render/cycles/render_settings/hair.html#bpy-types-cyclescurverendersettings-shape"), ("bpy.types.cycleslightsettings.cast_shadow*", "render/cycles/light_settings.html#bpy-types-cycleslightsettings-cast-shadow"), @@ -785,6 +834,7 @@ url_manual_mapping = ( ("bpy.types.spaceoutliner.use_filter_object*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object"), ("bpy.types.spacesequenceeditor.use_proxies*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-use-proxies"), ("bpy.types.spaceuveditor.edge_display_type*", "editors/uv/overlays.html#bpy-types-spaceuveditor-edge-display-type"), + ("bpy.types.spaceuveditor.grid_shape_source*", "editors/uv/overlays.html#bpy-types-spaceuveditor-grid-shape-source"), ("bpy.types.spaceuveditor.show_pixel_coords*", "editors/uv/sidebar.html#bpy-types-spaceuveditor-show-pixel-coords"), ("bpy.types.spaceview3d.show_reconstruction*", "editors/3dview/display/overlays.html#bpy-types-spaceview3d-show-reconstruction"), ("bpy.types.toolsettings.gpencil_selectmode*", "grease_pencil/selecting.html#bpy-types-toolsettings-gpencil-selectmode"), @@ -801,17 +851,17 @@ url_manual_mapping = ( ("bpy.ops.object.anim_transforms_to_deltas*", "scene_layout/object/editing/apply.html#bpy-ops-object-anim-transforms-to-deltas"), ("bpy.ops.object.modifier_copy_to_selected*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-copy-to-selected"), ("bpy.ops.preferences.app_template_install*", "advanced/app_templates.html#bpy-ops-preferences-app-template-install"), - ("bpy.types.actionposemarkers.active_index*", "animation/armatures/properties/pose_library.html#bpy-types-actionposemarkers-active-index"), ("bpy.types.animvizmotionpaths.frame_after*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-after"), ("bpy.types.animvizmotionpaths.frame_start*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-frame-start"), ("bpy.types.bakesettings.use_pass_indirect*", "render/cycles/baking.html#bpy-types-bakesettings-use-pass-indirect"), ("bpy.types.brush.cloth_force_falloff_type*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-force-falloff-type"), - ("bpy.types.brush.use_automasking_topology*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-use-automasking-topology"), + ("bpy.types.brush.use_automasking_topology*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-use-automasking-topology"), ("bpy.types.brushgpencilsettings.caps_type*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-caps-type"), ("bpy.types.brushgpencilsettings.show_fill*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-show-fill"), ("bpy.types.brushgpencilsettings.uv_random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-uv-random"), - ("bpy.types.brushtextureslot.mask_map_mode*", "sculpt_paint/brush/texture_mask.html#bpy-types-brushtextureslot-mask-map-mode"), - ("bpy.types.clothsettings.internal_tension*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-tension"), + ("bpy.types.brushtextureslot.mask_map_mode*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-mask-map-mode"), + ("bpy.types.clothsettings.sewing_force_max*", "physics/cloth/settings/shape.html#bpy-types-clothsettings-sewing-force-max"), + ("bpy.types.clothsettings.use_dynamic_mesh*", "physics/cloth/settings/shape.html#bpy-types-clothsettings-use-dynamic-mesh"), ("bpy.types.colormanagedviewsettings.gamma*", "render/color_management.html#bpy-types-colormanagedviewsettings-gamma"), ("bpy.types.compositornodeplanetrackdeform*", "compositing/types/distort/plane_track_deform.html#bpy-types-compositornodeplanetrackdeform"), ("bpy.types.curve.bevel_factor_mapping_end*", "modeling/curves/properties/geometry.html#bpy-types-curve-bevel-factor-mapping-end"), @@ -842,6 +892,8 @@ url_manual_mapping = ( ("bpy.types.geometrynodeinputinstancescale*", "modeling/geometry_nodes/instances/instance_scale.html#bpy-types-geometrynodeinputinstancescale"), ("bpy.types.geometrynodeinputmaterialindex*", "modeling/geometry_nodes/material/material_index.html#bpy-types-geometrynodeinputmaterialindex"), ("bpy.types.geometrynodeinputmeshedgeangle*", "modeling/geometry_nodes/mesh/edge_angle.html#bpy-types-geometrynodeinputmeshedgeangle"), + ("bpy.types.geometrynodeoffsetcornerinface*", "modeling/geometry_nodes/mesh_topology/offset_corner_in_face.html#bpy-types-geometrynodeoffsetcornerinface"), + ("bpy.types.geometrynodeoffsetpointincurve*", "modeling/geometry_nodes/curve_topology/offset_point_in_curve.html#bpy-types-geometrynodeoffsetpointincurve"), ("bpy.types.geometrynodeseparatecomponents*", "modeling/geometry_nodes/geometry/separate_components.html#bpy-types-geometrynodeseparatecomponents"), ("bpy.types.geometrynodesubdivisionsurface*", "modeling/geometry_nodes/mesh/subdivision_surface.html#bpy-types-geometrynodesubdivisionsurface"), ("bpy.types.geometrynodetranslateinstances*", "modeling/geometry_nodes/instances/translate_instances.html#bpy-types-geometrynodetranslateinstances"), @@ -887,7 +939,7 @@ url_manual_mapping = ( ("bpy.ops.object.assign_property_defaults*", "animation/armatures/posing/editing/apply.html#bpy-ops-object-assign-property-defaults"), ("bpy.ops.object.vertex_group_limit_total*", "sculpt_paint/weight_paint/editing.html#bpy-ops-object-vertex-group-limit-total"), ("bpy.ops.object.vertex_group_remove_from*", "modeling/meshes/properties/vertex_groups/vertex_groups.html#bpy-ops-object-vertex-group-remove-from"), - ("bpy.ops.outliner.collection_exclude_set*", "render/layers/introduction.html#bpy-ops-outliner-collection-exclude-set"), + ("bpy.ops.outliner.collection_exclude_set*", "editors/outliner/editing.html#bpy-ops-outliner-collection-exclude-set"), ("bpy.ops.outliner.collection_hide_inside*", "editors/outliner/editing.html#bpy-ops-outliner-collection-hide-inside"), ("bpy.ops.outliner.collection_holdout_set*", "render/layers/introduction.html#bpy-ops-outliner-collection-holdout-set"), ("bpy.ops.outliner.collection_show_inside*", "editors/outliner/editing.html#bpy-ops-outliner-collection-show-inside"), @@ -906,8 +958,10 @@ url_manual_mapping = ( ("bpy.types.brushgpencilsettings.hardness*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-hardness"), ("bpy.types.brushgpencilsettings.use_trim*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-use-trim"), ("bpy.types.brushtextureslot.random_angle*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-random-angle"), - ("bpy.types.clothsettings.internal_spring*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-internal-spring"), + ("bpy.types.clothsettings.bending_damping*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-bending-damping"), ("bpy.types.clothsettings.pressure_factor*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-pressure-factor"), + ("bpy.types.clothsettings.shear_stiffness*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-shear-stiffness"), + ("bpy.types.clothsettings.tension_damping*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-tension-damping"), ("bpy.types.colormanagedviewsettings.look*", "render/color_management.html#bpy-types-colormanagedviewsettings-look"), ("bpy.types.compositornodecolorcorrection*", "compositing/types/color/color_correction.html#bpy-types-compositornodecolorcorrection"), ("bpy.types.compositornodemoviedistortion*", "compositing/types/distort/movie_distortion.html#bpy-types-compositornodemoviedistortion"), @@ -935,7 +989,6 @@ url_manual_mapping = ( ("bpy.types.freestylelinestyle.sort_order*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-sort-order"), ("bpy.types.freestylelinestyle.split_dash*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-split-dash"), ("bpy.types.freestylesettings.use_culling*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-culling"), - ("bpy.types.geometrynodeattributetransfer*", "modeling/geometry_nodes/attribute/transfer_attribute.html#bpy-types-geometrynodeattributetransfer"), ("bpy.types.geometrynodeduplicateelements*", "modeling/geometry_nodes/geometry/duplicate_elements.html#bpy-types-geometrynodeduplicateelements"), ("bpy.types.geometrynodeinputmeshfacearea*", "modeling/geometry_nodes/mesh/face_area.html#bpy-types-geometrynodeinputmeshfacearea"), ("bpy.types.geometrynodeinputsplinecyclic*", "modeling/geometry_nodes/curve/is_spline_cyclic.html#bpy-types-geometrynodeinputsplinecyclic"), @@ -956,6 +1009,7 @@ url_manual_mapping = ( ("bpy.types.rendersettings.pixel_aspect_y*", "render/output/properties/format.html#bpy-types-rendersettings-pixel-aspect-y"), ("bpy.types.rigidbodyconstraint.use_limit*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-limit"), ("bpy.types.sceneeevee.taa_render_samples*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-taa-render-samples"), + ("bpy.types.sculpt.use_automasking_cavity*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-cavity"), ("bpy.types.sequence.frame_final_duration*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequence-frame-final-duration"), ("bpy.types.spaceoutliner.use_sync_select*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-sync-select"), ("bpy.types.spaceproperties.outliner_sync*", "editors/properties_editor.html#bpy-types-spaceproperties-outliner-sync"), @@ -964,8 +1018,8 @@ url_manual_mapping = ( ("bpy.types.spacetexteditor.margin_column*", "editors/text_editor.html#bpy-types-spacetexteditor-margin-column"), ("bpy.types.spacetexteditor.use_find_wrap*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-wrap"), ("bpy.types.spaceuveditor.tile_grid_shape*", "editors/uv/overlays.html#bpy-types-spaceuveditor-tile-grid-shape"), - ("bpy.types.spaceuveditor.use_custom_grid*", "editors/uv/overlays.html#bpy-types-spaceuveditor-use-custom-grid"), ("bpy.types.spaceuveditor.use_live_unwrap*", "modeling/meshes/uv/editing.html#bpy-types-spaceuveditor-use-live-unwrap"), + ("bpy.types.spaceview3d.use_render_border*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-use-render-border"), ("bpy.types.toolsettings.double_threshold*", "modeling/meshes/tools/tool_settings.html#bpy-types-toolsettings-double-threshold"), ("bpy.types.toolsettings.lock_object_mode*", "interface/window_system/topbar.html#bpy-types-toolsettings-lock-object-mode"), ("bpy.types.toolsettings.mesh_select_mode*", "modeling/meshes/selecting/introduction.html#bpy-types-toolsettings-mesh-select-mode"), @@ -995,6 +1049,7 @@ url_manual_mapping = ( ("bpy.types.brush.snake_hook_deform_type*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-snake-hook-deform-type"), ("bpy.types.brush.use_grab_active_vertex*", "sculpt_paint/sculpting/tools/grab.html#bpy-types-brush-use-grab-active-vertex"), ("bpy.types.brush.use_pose_lock_rotation*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-pose-lock-rotation"), + ("bpy.types.clothsettings.rest_shape_key*", "physics/cloth/settings/shape.html#bpy-types-clothsettings-rest-shape-key"), ("bpy.types.compositornodebrightcontrast*", "compositing/types/color/bright_contrast.html#bpy-types-compositornodebrightcontrast"), ("bpy.types.compositornodedoubleedgemask*", "compositing/types/matte/double_edge_mask.html#bpy-types-compositornodedoubleedgemask"), ("bpy.types.cyclesrendersettings.samples*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-samples"), @@ -1048,6 +1103,7 @@ url_manual_mapping = ( ("bpy.types.spacepreferences.filter_type*", "editors/preferences/keymap.html#bpy-types-spacepreferences-filter-type"), ("bpy.types.spacetexteditor.replace_text*", "editors/text_editor.html#bpy-types-spacetexteditor-replace-text"), ("bpy.types.spacetexteditor.use_find_all*", "editors/text_editor.html#bpy-types-spacetexteditor-use-find-all"), + ("bpy.types.spaceview3d.use_local_camera*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-use-local-camera"), ("bpy.types.toolsettings.snap_uv_element*", "editors/uv/controls/snapping.html#bpy-types-toolsettings-snap-uv-element"), ("bpy.types.toolsettings.use_snap_rotate*", "editors/3dview/controls/snapping.html#bpy-types-toolsettings-use-snap-rotate"), ("bpy.types.toolsettings.uv_relax_method*", "modeling/meshes/uv/tools/relax.html#bpy-types-toolsettings-uv-relax-method"), @@ -1090,6 +1146,10 @@ url_manual_mapping = ( ("bpy.types.brushgpencilsettings.dilate*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-dilate"), ("bpy.types.brushgpencilsettings.random*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-random"), ("bpy.types.brushtextureslot.use_random*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-use-random"), + ("bpy.types.clothsettings.bending_model*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-bending-model"), + ("bpy.types.clothsettings.fluid_density*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-fluid-density"), + ("bpy.types.clothsettings.pin_stiffness*", "physics/cloth/settings/shape.html#bpy-types-clothsettings-pin-stiffness"), + ("bpy.types.clothsettings.shear_damping*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-shear-damping"), ("bpy.types.clothsettings.target_volume*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-target-volume"), ("bpy.types.colormanageddisplaysettings*", "render/color_management.html#bpy-types-colormanageddisplaysettings"), ("bpy.types.colorramp.hue_interpolation*", "interface/controls/templates/color_ramp.html#bpy-types-colorramp-hue-interpolation"), @@ -1113,12 +1173,14 @@ url_manual_mapping = ( ("bpy.types.freestylelinestyle.chaining*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-chaining"), ("bpy.types.freestylelinestyle.sort_key*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-sort-key"), ("bpy.types.geometrynodeaccumulatefield*", "modeling/geometry_nodes/utilities/accumulate_field.html#bpy-types-geometrynodeaccumulatefield"), + ("bpy.types.geometrynodecornersofvertex*", "modeling/geometry_nodes/mesh_topology/corners_of_vertex.html#bpy-types-geometrynodecornersofvertex"), ("bpy.types.geometrynodecurvesethandles*", "modeling/geometry_nodes/curve/set_handle_type.html#bpy-types-geometrynodecurvesethandles"), ("bpy.types.geometrynodecurvesplinetype*", "modeling/geometry_nodes/curve/set_spline_type.html#bpy-types-geometrynodecurvesplinetype"), ("bpy.types.geometrynodeinputmeshisland*", "modeling/geometry_nodes/mesh/mesh_island.html#bpy-types-geometrynodeinputmeshisland"), ("bpy.types.geometrynodemergebydistance*", "modeling/geometry_nodes/geometry/merge_by_distance.html#bpy-types-geometrynodemergebydistance"), ("bpy.types.geometrynodereplacematerial*", "modeling/geometry_nodes/material/replace_material.html#bpy-types-geometrynodereplacematerial"), ("bpy.types.geometrynoderotateinstances*", "modeling/geometry_nodes/instances/rotate_instances.html#bpy-types-geometrynoderotateinstances"), + ("bpy.types.geometrynodesampleuvsurface*", "modeling/geometry_nodes/mesh/sample_uv_surface.html#bpy-types-geometrynodesampleuvsurface"), ("bpy.types.geometrynodesetsplinecyclic*", "modeling/geometry_nodes/curve/set_spline_cyclic.html#bpy-types-geometrynodesetsplinecyclic"), ("bpy.types.geometrynodesplineparameter*", "modeling/geometry_nodes/curve/spline_parameter.html#bpy-types-geometrynodesplineparameter"), ("bpy.types.gpencillayer.use_mask_layer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-mask-layer"), @@ -1183,12 +1245,12 @@ url_manual_mapping = ( ("bpy.types.bone.use_envelope_multiply*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-use-envelope-multiply"), ("bpy.types.brush.boundary_deform_type*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-deform-type"), ("bpy.types.brush.cursor_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-overlay-alpha"), - ("bpy.types.brush.normal_radius_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-normal-radius-factor"), + ("bpy.types.brush.normal_radius_factor*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-normal-radius-factor"), ("bpy.types.brush.smooth_stroke_factor*", "sculpt_paint/brush/stroke.html#bpy-types-brush-smooth-stroke-factor"), ("bpy.types.brush.smooth_stroke_radius*", "sculpt_paint/brush/stroke.html#bpy-types-brush-smooth-stroke-radius"), - ("bpy.types.brush.topology_rake_factor*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-brush-topology-rake-factor"), + ("bpy.types.brush.topology_rake_factor*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-topology-rake-factor"), ("bpy.types.brush.use_pose_ik_anchored*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-pose-ik-anchored"), - ("bpy.types.brush.use_pressure_masking*", "sculpt_paint/brush/texture_mask.html#bpy-types-brush-use-pressure-masking"), + ("bpy.types.brush.use_pressure_masking*", "sculpt_paint/brush/texture.html#bpy-types-brush-use-pressure-masking"), ("bpy.types.brush.use_pressure_spacing*", "sculpt_paint/brush/stroke.html#bpy-types-brush-use-pressure-spacing"), ("bpy.types.brushgpencilsettings.angle*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle"), ("bpy.types.clothsettings.use_pressure*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-use-pressure"), @@ -1212,11 +1274,13 @@ url_manual_mapping = ( ("bpy.types.geometrynodenamedattribute*", "modeling/geometry_nodes/input/named_attribute.html#bpy-types-geometrynodenamedattribute"), ("bpy.types.geometrynodepointstovolume*", "modeling/geometry_nodes/point/points_to_volume.html#bpy-types-geometrynodepointstovolume"), ("bpy.types.geometrynodescaleinstances*", "modeling/geometry_nodes/instances/scale_instances.html#bpy-types-geometrynodescaleinstances"), + ("bpy.types.geometrynodesetcurvenormal*", "modeling/geometry_nodes/curve/set_curve_normal.html#bpy-types-geometrynodesetcurvenormal"), ("bpy.types.geometrynodesetcurveradius*", "modeling/geometry_nodes/curve/set_curve_radius.html#bpy-types-geometrynodesetcurveradius"), ("bpy.types.geometrynodesetpointradius*", "modeling/geometry_nodes/point/set_point_radius.html#bpy-types-geometrynodesetpointradius"), ("bpy.types.geometrynodesetshadesmooth*", "modeling/geometry_nodes/mesh/set_shade_smooth.html#bpy-types-geometrynodesetshadesmooth"), ("bpy.types.geometrynodestringtocurves*", "modeling/geometry_nodes/text/string_to_curves.html#bpy-types-geometrynodestringtocurves"), ("bpy.types.geometrynodesubdividecurve*", "modeling/geometry_nodes/curve/subdivide_curve.html#bpy-types-geometrynodesubdividecurve"), + ("bpy.types.geometrynodevertexofcorner*", "modeling/geometry_nodes/mesh_topology/vertex_of_corner.html#bpy-types-geometrynodevertexofcorner"), ("bpy.types.gpencillayer.channel_color*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-channel-color"), ("bpy.types.gpencillayer.use_solo_mode*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-solo-mode"), ("bpy.types.greasepencil.use_multiedit*", "grease_pencil/multiframe.html#bpy-types-greasepencil-use-multiedit"), @@ -1283,13 +1347,14 @@ url_manual_mapping = ( ("bpy.types.brush.texture_sample_bias*", "sculpt_paint/brush/texture.html#bpy-types-brush-texture-sample-bias"), ("bpy.types.brush.use_cloth_collision*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-use-cloth-collision"), ("bpy.types.brush.use_grab_silhouette*", "sculpt_paint/sculpting/tools/grab.html#bpy-types-brush-use-grab-silhouette"), - ("bpy.types.brush.use_original_normal*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-use-original-normal"), + ("bpy.types.brush.use_original_normal*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-use-original-normal"), ("bpy.types.brush.use_pressure_jitter*", "sculpt_paint/brush/stroke.html#bpy-types-brush-use-pressure-jitter"), ("bpy.types.brush.use_primary_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-primary-overlay"), ("bpy.types.brushcurvessculptsettings*", "sculpt_paint/curves_sculpting/index.html#bpy-types-brushcurvessculptsettings"), ("bpy.types.brushtextureslot.map_mode*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-map-mode"), ("bpy.types.brushtextureslot.use_rake*", "sculpt_paint/brush/texture.html#bpy-types-brushtextureslot-use-rake"), ("bpy.types.camera.passepartout_alpha*", "render/cameras.html#bpy-types-camera-passepartout-alpha"), + ("bpy.types.clothsettings.air_damping*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-air-damping"), ("bpy.types.colorrampelement.position*", "interface/controls/templates/color_ramp.html#bpy-types-colorrampelement-position"), ("bpy.types.compositornodechromamatte*", "compositing/types/matte/chroma_key.html#bpy-types-compositornodechromamatte"), ("bpy.types.compositornodecryptomatte*", "compositing/types/matte/cryptomatte_legacy.html#bpy-types-compositornodecryptomatte"), @@ -1314,11 +1379,15 @@ url_manual_mapping = ( ("bpy.types.functionnodeseparatecolor*", "modeling/geometry_nodes/color/separate_color.html#bpy-types-functionnodeseparatecolor"), ("bpy.types.functionnodevaluetostring*", "modeling/geometry_nodes/text/value_to_string.html#bpy-types-functionnodevaluetostring"), ("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/curve_to_points.html#bpy-types-geometrynodecurvetopoints"), + ("bpy.types.geometrynodeedgesofcorner*", "modeling/geometry_nodes/mesh_topology/edges_of_corner.html#bpy-types-geometrynodeedgesofcorner"), + ("bpy.types.geometrynodeedgesofvertex*", "modeling/geometry_nodes/mesh_topology/edges_of_vertex.html#bpy-types-geometrynodeedgesofvertex"), ("bpy.types.geometrynodefieldondomain*", "modeling/geometry_nodes/utilities/interpolate_domain.html#bpy-types-geometrynodefieldondomain"), ("bpy.types.geometrynodeinputmaterial*", "modeling/geometry_nodes/input/material.html#bpy-types-geometrynodeinputmaterial"), ("bpy.types.geometrynodeinputposition*", "modeling/geometry_nodes/input/position.html#bpy-types-geometrynodeinputposition"), ("bpy.types.geometrynodemeshicosphere*", "modeling/geometry_nodes/mesh_primitives/icosphere.html#bpy-types-geometrynodemeshicosphere"), + ("bpy.types.geometrynodepointsofcurve*", "modeling/geometry_nodes/curve_topology/points_of_curve.html#bpy-types-geometrynodepointsofcurve"), ("bpy.types.geometrynoderesamplecurve*", "modeling/geometry_nodes/curve/resample_curve.html#bpy-types-geometrynoderesamplecurve"), + ("bpy.types.geometrynodesamplenearest*", "modeling/geometry_nodes/geometry/sample_nearest.html#bpy-types-geometrynodesamplenearest"), ("bpy.types.geometrynodescaleelements*", "modeling/geometry_nodes/mesh/scale_elements.html#bpy-types-geometrynodescaleelements"), ("bpy.types.geometrynodesubdividemesh*", "modeling/geometry_nodes/mesh/subdivide_mesh.html#bpy-types-geometrynodesubdividemesh"), ("bpy.types.geometrynodeuvpackislands*", "modeling/geometry_nodes/uv/pack_uv_islands.html#bpy-types-geometrynodeuvpackislands"), @@ -1375,6 +1444,7 @@ url_manual_mapping = ( ("bpy.ops.mesh.select_interior_faces*", "modeling/meshes/selecting/all_by_trait.html#bpy-ops-mesh-select-interior-faces"), ("bpy.ops.mesh.select_similar_region*", "modeling/meshes/selecting/similar.html#bpy-ops-mesh-select-similar-region"), ("bpy.ops.mesh.tris_convert_to_quads*", "modeling/meshes/editing/face/triangles_quads.html#bpy-ops-mesh-tris-convert-to-quads"), + ("bpy.ops.node.duplicate_move_linked*", "interface/controls/nodes/editing.html#bpy-ops-node-duplicate-move-linked"), ("bpy.ops.object.datalayout_transfer*", "scene_layout/object/editing/link_transfer/transfer_mesh_data_layout.html#bpy-ops-object-datalayout-transfer"), ("bpy.ops.object.multires_base_apply*", "modeling/modifiers/generate/multiresolution.html#bpy-ops-object-multires-base-apply"), ("bpy.ops.object.randomize_transform*", "scene_layout/object/editing/transform/randomize.html#bpy-ops-object-randomize-transform"), @@ -1386,7 +1456,6 @@ url_manual_mapping = ( ("bpy.ops.outliner.collection_enable*", "editors/outliner/editing.html#bpy-ops-outliner-collection-enable"), ("bpy.ops.palette.extract_from_image*", "editors/image/editing.html#bpy-ops-palette-extract-from-image"), ("bpy.ops.pose.user_transforms_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-user-transforms-clear"), - ("bpy.ops.poselib.browse_interactive*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-browse-interactive"), ("bpy.ops.screen.region_context_menu*", "interface/controls/buttons/menus.html#bpy-ops-screen-region-context-menu"), ("bpy.ops.sculpt.set_persistent_base*", "sculpt_paint/sculpting/tools/layer.html#bpy-ops-sculpt-set-persistent-base"), ("bpy.ops.sequencer.crossfade_sounds*", "video_editing/edit/montage/strips/transitions/sound_crossfade.html#bpy-ops-sequencer-crossfade-sounds"), @@ -1399,12 +1468,15 @@ url_manual_mapping = ( ("bpy.types.bakesettings.cage_object*", "render/cycles/baking.html#bpy-types-bakesettings-cage-object"), ("bpy.types.bakesettings.margin_type*", "render/cycles/baking.html#bpy-types-bakesettings-margin-type"), ("bpy.types.bone.use_relative_parent*", "animation/armatures/bones/properties/relations.html#bpy-types-bone-use-relative-parent"), - ("bpy.types.brush.auto_smooth_factor*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-auto-smooth-factor"), + ("bpy.types.brush.auto_smooth_factor*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-auto-smooth-factor"), ("bpy.types.brush.smooth_deform_type*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-smooth-deform-type"), ("bpy.types.brush.use_connected_only*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-connected-only"), ("bpy.types.brush.use_cursor_overlay*", "sculpt_paint/brush/cursor.html#bpy-types-brush-use-cursor-overlay"), - ("bpy.types.brush.use_original_plane*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-use-original-plane"), + ("bpy.types.brush.use_original_plane*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-use-original-plane"), ("bpy.types.camera.show_passepartout*", "render/cameras.html#bpy-types-camera-show-passepartout"), + ("bpy.types.clothsettings.shrink_max*", "physics/cloth/settings/property_weights.html#bpy-types-clothsettings-shrink-max"), + ("bpy.types.clothsettings.shrink_min*", "physics/cloth/settings/shape.html#bpy-types-clothsettings-shrink-min"), + ("bpy.types.clothsettings.time_scale*", "physics/cloth/settings/index.html#bpy-types-clothsettings-time-scale"), ("bpy.types.collection.lineart_usage*", "scene_layout/collections/collections.html#bpy-types-collection-lineart-usage"), ("bpy.types.colormanagedviewsettings*", "render/color_management.html#bpy-types-colormanagedviewsettings"), ("bpy.types.compositornodebokehimage*", "compositing/types/input/bokeh_image.html#bpy-types-compositornodebokehimage"), @@ -1425,6 +1497,8 @@ url_manual_mapping = ( ("bpy.types.freestylelinestyle.color*", "render/freestyle/view_layer/line_style/color.html#bpy-types-freestylelinestyle-color"), ("bpy.types.functionnodecombinecolor*", "modeling/geometry_nodes/color/combine_color.html#bpy-types-functionnodecombinecolor"), ("bpy.types.functionnodestringlength*", "modeling/geometry_nodes/text/string_length.html#bpy-types-functionnodestringlength"), + ("bpy.types.geometrynodecurveofpoint*", "modeling/geometry_nodes/curve_topology/curve_of_point.html#bpy-types-geometrynodecurveofpoint"), + ("bpy.types.geometrynodefaceofcorner*", "modeling/geometry_nodes/mesh_topology/face_of_corner.html#bpy-types-geometrynodefaceofcorner"), ("bpy.types.geometrynodefieldatindex*", "modeling/geometry_nodes/utilities/field_at_index.html#bpy-types-geometrynodefieldatindex"), ("bpy.types.geometrynodeimagetexture*", "modeling/geometry_nodes/texture/image.html#bpy-types-geometrynodeimagetexture"), ("bpy.types.geometrynodeinputtangent*", "modeling/geometry_nodes/curve/curve_tangent.html#bpy-types-geometrynodeinputtangent"), @@ -1566,6 +1640,7 @@ url_manual_mapping = ( ("bpy.types.geometrynodemeshboolean*", "modeling/geometry_nodes/mesh/mesh_boolean.html#bpy-types-geometrynodemeshboolean"), ("bpy.types.geometrynodemeshtocurve*", "modeling/geometry_nodes/mesh/mesh_to_curve.html#bpy-types-geometrynodemeshtocurve"), ("bpy.types.geometrynodesamplecurve*", "modeling/geometry_nodes/curve/sample_curve.html#bpy-types-geometrynodesamplecurve"), + ("bpy.types.geometrynodesampleindex*", "modeling/geometry_nodes/geometry/sample_index.html#bpy-types-geometrynodesampleindex"), ("bpy.types.geometrynodesetmaterial*", "modeling/geometry_nodes/material/set_material.html#bpy-types-geometrynodesetmaterial"), ("bpy.types.geometrynodesetposition*", "modeling/geometry_nodes/geometry/set_position.html#bpy-types-geometrynodesetposition"), ("bpy.types.geometrynodetriangulate*", "modeling/geometry_nodes/mesh/triangulate.html#bpy-types-geometrynodetriangulate"), @@ -1601,6 +1676,10 @@ url_manual_mapping = ( ("bpy.types.shadernodevolumescatter*", "render/shader_nodes/shader/volume_scatter.html#bpy-types-shadernodevolumescatter"), ("bpy.types.simplifygpencilmodifier*", "grease_pencil/modifiers/generate/simplify.html#bpy-types-simplifygpencilmodifier"), ("bpy.types.spacegrapheditor.cursor*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-cursor"), + ("bpy.types.spaceview3d.lock_camera*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-lock-camera"), + ("bpy.types.spaceview3d.lock_cursor*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-lock-cursor"), + ("bpy.types.spaceview3d.lock_object*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-lock-object"), + ("bpy.types.spaceview3d.show_viewer*", "modeling/geometry_nodes/output/viewer.html#bpy-types-spaceview3d-show-viewer"), ("bpy.types.texturenodecombinecolor*", "editors/texture_node/types/color/combine_color.html#bpy-types-texturenodecombinecolor"), ("bpy.types.texturenodetexdistnoise*", "editors/texture_node/types/textures/distorted_noise.html#bpy-types-texturenodetexdistnoise"), ("bpy.types.vertexweightmixmodifier*", "modeling/modifiers/modify/weight_mix.html#bpy-types-vertexweightmixmodifier"), @@ -1651,10 +1730,12 @@ url_manual_mapping = ( ("bpy.ops.sequencer.select_handles*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-handles"), ("bpy.ops.ui.copy_data_path_button*", "interface/controls/buttons/menus.html#bpy-ops-ui-copy-data-path-button"), ("bpy.ops.uv.average_islands_scale*", "modeling/meshes/uv/editing.html#bpy-ops-uv-average-islands-scale"), + ("bpy.ops.wm.read_factory_settings*", "interface/window_system/topbar.html#bpy-ops-wm-read-factory-settings"), ("bpy.types.action.use_frame_range*", "animation/actions.html#bpy-types-action-use-frame-range"), ("bpy.types.armature.axes_position*", "animation/armatures/properties/display.html#bpy-types-armature-axes-position"), ("bpy.types.armature.pose_position*", "animation/armatures/properties/skeleton.html#bpy-types-armature-pose-position"), ("bpy.types.bakesettings.use_clear*", "render/cycles/baking.html#bpy-types-bakesettings-use-clear"), + ("bpy.types.bakesettings.view_from*", "render/cycles/baking.html#bpy-types-bakesettings-view-from"), ("bpy.types.bone.envelope_distance*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-envelope-distance"), ("bpy.types.brightcontrastmodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-brightcontrastmodifier"), ("bpy.types.brush.cursor_color_add*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-color-add"), @@ -1704,6 +1785,7 @@ url_manual_mapping = ( ("bpy.types.geometrynodeisviewport*", "modeling/geometry_nodes/input/is_viewport.html#bpy-types-geometrynodeisviewport"), ("bpy.types.geometrynodemeshcircle*", "modeling/geometry_nodes/mesh_primitives/mesh_circle.html#bpy-types-geometrynodemeshcircle"), ("bpy.types.geometrynodeobjectinfo*", "modeling/geometry_nodes/input/object_info.html#bpy-types-geometrynodeobjectinfo"), + ("bpy.types.geometrynodeselfobject*", "modeling/geometry_nodes/input/self_object.html#bpy-types-geometrynodeselfobject"), ("bpy.types.geometrynodesplitedges*", "modeling/geometry_nodes/mesh/split_edges.html#bpy-types-geometrynodesplitedges"), ("bpy.types.geometrynodestringjoin*", "modeling/geometry_nodes/text/join_strings.html#bpy-types-geometrynodestringjoin"), ("bpy.types.geometrynodevolumecube*", "modeling/geometry_nodes/volume/volume_cube.html#bpy-types-geometrynodevolumecube"), @@ -1738,6 +1820,7 @@ url_manual_mapping = ( ("bpy.types.shadernodevectorrotate*", "render/shader_nodes/vector/vector_rotate.html#bpy-types-shadernodevectorrotate"), ("bpy.types.shapekey.interpolation*", "animation/shape_keys/shape_keys_panel.html#bpy-types-shapekey-interpolation"), ("bpy.types.sound.use_memory_cache*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sound-use-memory-cache"), + ("bpy.types.spaceview3d.clip_start*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-clip-start"), ("bpy.types.spaceview3d.show_gizmo*", "editors/3dview/display/gizmo.html#bpy-types-spaceview3d-show-gizmo"), ("bpy.types.texturegpencilmodifier*", "grease_pencil/modifiers/modify/texture_mapping.html#bpy-types-texturegpencilmodifier"), ("bpy.types.texturenodecoordinates*", "editors/texture_node/types/input/coordinates.html#bpy-types-texturenodecoordinates"), @@ -1794,11 +1877,10 @@ url_manual_mapping = ( ("bpy.ops.outliner.collection_new*", "editors/outliner/editing.html#bpy-ops-outliner-collection-new"), ("bpy.ops.outliner.show_hierarchy*", "editors/outliner/editing.html#bpy-ops-outliner-show-hierarchy"), ("bpy.ops.outliner.show_one_level*", "editors/outliner/editing.html#bpy-ops-outliner-show-one-level"), - ("bpy.ops.paint.brush_colors_flip*", "sculpt_paint/texture_paint/tool_settings/brush_settings.html#bpy-ops-paint-brush-colors-flip"), + ("bpy.ops.paint.brush_colors_flip*", "sculpt_paint/brush/brush_settings.html#bpy-ops-paint-brush-colors-flip"), ("bpy.ops.paint.weight_from_bones*", "sculpt_paint/weight_paint/editing.html#bpy-ops-paint-weight-from-bones"), ("bpy.ops.paintcurve.delete_point*", "sculpt_paint/brush/stroke.html#bpy-ops-paintcurve-delete-point"), ("bpy.ops.pose.paths_range_update*", "animation/motion_paths.html#bpy-ops-pose-paths-range-update"), - ("bpy.ops.poselib.action_sanitize*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-action-sanitize"), ("bpy.ops.preferences.studiolight*", "editors/preferences/lights.html#bpy-ops-preferences-studiolight"), ("bpy.ops.scene.view_layer_remove*", "render/layers/introduction.html#bpy-ops-scene-view-layer-remove"), ("bpy.ops.screen.screen_full_area*", "interface/window_system/areas.html#bpy-ops-screen-screen-full-area"), @@ -1823,8 +1905,8 @@ url_manual_mapping = ( ("bpy.types.brush.boundary_offset*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-offset"), ("bpy.types.brush.cloth_sim_limit*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-sim-limit"), ("bpy.types.brush.use_custom_icon*", "sculpt_paint/brush/brush.html#bpy-types-brush-use-custom-icon"), - ("bpy.types.brushtextureslot.mask*", "sculpt_paint/brush/texture_mask.html#bpy-types-brushtextureslot-mask"), ("bpy.types.camerabackgroundimage*", "render/cameras.html#bpy-types-camerabackgroundimage"), + ("bpy.types.clothsettings.quality*", "physics/cloth/settings/index.html#bpy-types-clothsettings-quality"), ("bpy.types.compositornodeboxmask*", "compositing/types/matte/box_mask.html#bpy-types-compositornodeboxmask"), ("bpy.types.compositornodedefocus*", "compositing/types/filter/defocus.html#bpy-types-compositornodedefocus"), ("bpy.types.compositornodedenoise*", "compositing/types/filter/denoise.html#bpy-types-compositornodedenoise"), @@ -1847,11 +1929,13 @@ url_manual_mapping = ( ("bpy.types.fluideffectorsettings*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings"), ("bpy.types.followtrackconstraint*", "animation/constraints/motion_tracking/follow_track.html#bpy-types-followtrackconstraint"), ("bpy.types.functionnodeinputbool*", "modeling/geometry_nodes/input/boolean.html#bpy-types-functionnodeinputbool"), + ("bpy.types.geometrycornersofface*", "modeling/geometry_nodes/mesh_topology/corners_of_face.html#bpy-types-geometrycornersofface"), ("bpy.types.geometrynodecurvestar*", "modeling/geometry_nodes/curve_primitives/star.html#bpy-types-geometrynodecurvestar"), ("bpy.types.geometrynodefillcurve*", "modeling/geometry_nodes/curve/fill_curve.html#bpy-types-geometrynodefillcurve"), ("bpy.types.geometrynodeflipfaces*", "modeling/geometry_nodes/mesh/flip_faces.html#bpy-types-geometrynodeflipfaces"), + ("bpy.types.geometrynodeimageinfo*", "modeling/geometry_nodes/input/image_info.html#bpy-types-geometrynodeimageinfo"), ("bpy.types.geometrynodeproximity*", "modeling/geometry_nodes/geometry/geometry_proximity.html#bpy-types-geometrynodeproximity"), - ("bpy.types.geometrynodetransform*", "modeling/geometry_nodes/geometry/transform.html#bpy-types-geometrynodetransform"), + ("bpy.types.geometrynodetransform*", "modeling/geometry_nodes/geometry/transform_geometry.html#bpy-types-geometrynodetransform"), ("bpy.types.geometrynodetrimcurve*", "modeling/geometry_nodes/curve/trim_curve.html#bpy-types-geometrynodetrimcurve"), ("bpy.types.gpencillayer.location*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-location"), ("bpy.types.gpencillayer.rotation*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-rotation"), @@ -2009,6 +2093,7 @@ url_manual_mapping = ( ("bpy.types.soundsequence.volume*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-soundsequence-volume"), ("bpy.types.spaceclipeditor.show*", "editors/clip/display/index.html#bpy-types-spaceclipeditor-show"), ("bpy.types.spacedopesheeteditor*", "editors/dope_sheet/index.html#bpy-types-spacedopesheeteditor"), + ("bpy.types.spaceview3d.clip_end*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-clip-end"), ("bpy.types.speedcontrolsequence*", "video_editing/edit/montage/strips/effects/speed_control.html#bpy-types-speedcontrolsequence"), ("bpy.types.texturenodecurvetime*", "editors/texture_node/types/input/time.html#bpy-types-texturenodecurvetime"), ("bpy.types.texturenodetexclouds*", "editors/texture_node/types/textures/clouds.html#bpy-types-texturenodetexclouds"), @@ -2119,7 +2204,7 @@ url_manual_mapping = ( ("bpy.types.kinematicconstraint*", "animation/constraints/tracking/ik_solver.html#bpy-types-kinematicconstraint"), ("bpy.types.material.line_color*", "render/freestyle/material.html#bpy-types-material-line-color"), ("bpy.types.material.pass_index*", "render/materials/settings.html#bpy-types-material-pass-index"), - ("bpy.types.mesh.use_paint_mask*", "sculpt_paint/brush/introduction.html#bpy-types-mesh-use-paint-mask"), + ("bpy.types.mesh.use_paint_mask*", "sculpt_paint/selection_visibility.html#bpy-types-mesh-use-paint-mask"), ("bpy.types.object.display_type*", "scene_layout/object/properties/display.html#bpy-types-object-display-type"), ("bpy.types.objectlineart.usage*", "scene_layout/object/properties/line_art.html#bpy-types-objectlineart-usage"), ("bpy.types.paint.input_samples*", "sculpt_paint/brush/stroke.html#bpy-types-paint-input-samples"), @@ -2235,7 +2320,8 @@ url_manual_mapping = ( ("bpy.types.armature.show_axes*", "animation/armatures/properties/display.html#bpy-types-armature-show-axes"), ("bpy.types.armatureconstraint*", "animation/constraints/relationship/armature.html#bpy-types-armatureconstraint"), ("bpy.types.brush.dash_samples*", "sculpt_paint/brush/stroke.html#bpy-types-brush-dash-samples"), - ("bpy.types.brush.sculpt_plane*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-sculpt-plane"), + ("bpy.types.brush.sculpt_plane*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-sculpt-plane"), + ("bpy.types.clothsettings.mass*", "physics/cloth/settings/physical_properties.html#bpy-types-clothsettings-mass"), ("bpy.types.compositornodeblur*", "compositing/types/filter/blur_node.html#bpy-types-compositornodeblur"), ("bpy.types.compositornodecrop*", "compositing/types/distort/crop.html#bpy-types-compositornodecrop"), ("bpy.types.compositornodeflip*", "compositing/types/distort/flip.html#bpy-types-compositornodeflip"), @@ -2290,6 +2376,7 @@ url_manual_mapping = ( ("bpy.types.shadernodetexmagic*", "render/shader_nodes/textures/magic.html#bpy-types-shadernodetexmagic"), ("bpy.types.shadernodetexnoise*", "render/shader_nodes/textures/noise.html#bpy-types-shadernodetexnoise"), ("bpy.types.shrinkwrapmodifier*", "modeling/modifiers/deform/shrinkwrap.html#bpy-types-shrinkwrapmodifier"), + ("bpy.types.spaceview3d.camera*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-camera"), ("bpy.types.splineikconstraint*", "animation/constraints/tracking/spline_ik.html#bpy-types-splineikconstraint"), ("bpy.types.texturenodechecker*", "editors/texture_node/types/patterns/checker.html#bpy-types-texturenodechecker"), ("bpy.types.texturenodetexture*", "editors/texture_node/types/input/texture.html#bpy-types-texturenodetexture"), @@ -2353,8 +2440,6 @@ url_manual_mapping = ( ("bpy.ops.pose.group_deselect*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-deselect"), ("bpy.ops.pose.group_unassign*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-unassign"), ("bpy.ops.pose.select_grouped*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-grouped"), - ("bpy.ops.poselib.pose_remove*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-remove"), - ("bpy.ops.poselib.pose_rename*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-rename"), ("bpy.ops.preferences.keyitem*", "editors/preferences/keymap.html#bpy-ops-preferences-keyitem"), ("bpy.ops.screen.area_options*", "interface/window_system/areas.html#bpy-ops-screen-area-options"), ("bpy.ops.screen.region_blend*", "interface/window_system/regions.html#bpy-ops-screen-region-blend"), @@ -2480,7 +2565,6 @@ url_manual_mapping = ( ("bpy.ops.object.track_clear*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-clear"), ("bpy.ops.pose.select_linked*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-linked"), ("bpy.ops.pose.select_mirror*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-mirror"), - ("bpy.ops.poselib.apply_pose*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-apply-pose"), ("bpy.ops.screen.marker_jump*", "animation/markers.html#bpy-ops-screen-marker-jump"), ("bpy.ops.screen.repeat_last*", "interface/undo_redo.html#bpy-ops-screen-repeat-last"), ("bpy.ops.sculpt.mask_expand*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-mask-expand"), @@ -2553,7 +2637,7 @@ url_manual_mapping = ( ("bpy.types.spaceimageeditor*", "editors/image/index.html#bpy-types-spaceimageeditor"), ("bpy.types.spacepreferences*", "editors/preferences/index.html#bpy-types-spacepreferences"), ("bpy.types.spacespreadsheet*", "editors/spreadsheet.html#bpy-types-spacespreadsheet"), - ("bpy.types.spaceview3d.lock*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-lock"), + ("bpy.types.spaceview3d.lens*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-lens"), ("bpy.types.spaceview3d.show*", "editors/3dview/display/index.html#bpy-types-spaceview3d-show"), ("bpy.types.sphfluidsettings*", "physics/particles/emitter/physics/fluid.html#bpy-types-sphfluidsettings"), ("bpy.types.subtractsequence*", "video_editing/edit/montage/strips/effects/subtract.html#bpy-types-subtractsequence"), @@ -2602,7 +2686,6 @@ url_manual_mapping = ( ("bpy.ops.pose.group_assign*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-assign"), ("bpy.ops.pose.group_select*", "animation/armatures/properties/bone_groups.html#bpy-ops-pose-group-select"), ("bpy.ops.pose.paths_update*", "animation/motion_paths.html#bpy-ops-pose-paths-update"), - ("bpy.ops.poselib.pose_move*", "animation/armatures/properties/pose_library.html#bpy-ops-poselib-pose-move"), ("bpy.ops.preferences.addon*", "editors/preferences/addons.html#bpy-ops-preferences-addon"), ("bpy.ops.scene.light_cache*", "render/eevee/render_settings/indirect_lighting.html#bpy-ops-scene-light-cache"), ("bpy.ops.screen.actionzone*", "interface/window_system/areas.html#bpy-ops-screen-actionzone"), @@ -2612,6 +2695,7 @@ url_manual_mapping = ( ("bpy.ops.sculpt.dirty_mask*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-dirty-mask"), ("bpy.ops.sculpt.reveal_all*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-ops-sculpt-reveal-all"), ("bpy.ops.sculpt.symmetrize*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-ops-sculpt-symmetrize"), + ("bpy.ops.uv.align_rotation*", "modeling/meshes/uv/editing.html#bpy-ops-uv-align-rotation"), ("bpy.ops.uv.remove_doubles*", "modeling/meshes/uv/editing.html#bpy-ops-uv-remove-doubles"), ("bpy.ops.uv.select_similar*", "editors/uv/selecting.html#bpy-ops-uv-select-similar"), ("bpy.ops.uv.sphere_project*", "modeling/meshes/editing/uv.html#bpy-ops-uv-sphere-project"), @@ -2689,7 +2773,6 @@ url_manual_mapping = ( ("bpy.ops.object.track_set*", "animation/constraints/interface/adding_removing.html#bpy-ops-object-track-set"), ("bpy.ops.pose.paths_clear*", "animation/motion_paths.html#bpy-ops-pose-paths-clear"), ("bpy.ops.pose.scale_clear*", "animation/armatures/posing/editing/clear.html#bpy-ops-pose-scale-clear"), - ("bpy.ops.poselib.pose_add*", "animation/armatures/posing/editing/pose_library.html#bpy-ops-poselib-pose-add"), ("bpy.ops.scene.view_layer*", "render/layers/introduction.html#bpy-ops-scene-view-layer"), ("bpy.ops.screen.area_join*", "interface/window_system/areas.html#bpy-ops-screen-area-join"), ("bpy.ops.screen.area_move*", "interface/window_system/areas.html#bpy-ops-screen-area-move"), @@ -2711,9 +2794,10 @@ url_manual_mapping = ( ("bpy.ops.view3d.view_roll*", "editors/3dview/navigate/navigation.html#bpy-ops-view3d-view-roll"), ("bpy.ops.wm.open_mainfile*", "files/blend/open_save.html#bpy-ops-wm-open-mainfile"), ("bpy.ops.wm.owner_disable*", "interface/window_system/workspaces.html#bpy-ops-wm-owner-disable"), + ("bpy.ops.wm.save_homefile*", "interface/window_system/topbar.html#bpy-ops-wm-save-homefile"), ("bpy.ops.wm.save_mainfile*", "files/blend/open_save.html#bpy-ops-wm-save-mainfile"), ("bpy.types.bone.show_wire*", "animation/armatures/bones/properties/display.html#bpy-types-bone-show-wire"), - ("bpy.types.brush.hardness*", "sculpt_paint/sculpting/tool_settings/brush_settings.html#bpy-types-brush-hardness"), + ("bpy.types.brush.hardness*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-hardness"), ("bpy.types.curves.surface*", "modeling/curves/primitives.html#bpy-types-curves-surface"), ("bpy.types.curvesmodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-curvesmodifier"), ("bpy.types.ffmpegsettings*", "render/output/properties/output.html#bpy-types-ffmpegsettings"), @@ -2783,6 +2867,7 @@ url_manual_mapping = ( ("bpy.ops.object.armature*", "animation/armatures/index.html#bpy-ops-object-armature"), ("bpy.ops.object.face_map*", "modeling/meshes/properties/object_data.html#bpy-ops-object-face-map"), ("bpy.ops.object.join_uvs*", "scene_layout/object/editing/link_transfer/copy_uvmaps.html#bpy-ops-object-join-uvs"), + ("bpy.ops.object.mode_set*", "editors/3dview/modes.html#bpy-ops-object-mode-set"), ("bpy.ops.outliner.delete*", "editors/outliner/editing.html#bpy-ops-outliner-delete"), ("bpy.ops.paintcurve.draw*", "sculpt_paint/brush/stroke.html#bpy-ops-paintcurve-draw"), ("bpy.ops.pose.relax_rest*", "animation/armatures/posing/editing/in_betweens.html#bpy-ops-pose-relax-rest"), @@ -3106,7 +3191,7 @@ url_manual_mapping = ( ("bpy.ops.marker.add*", "animation/markers.html#bpy-ops-marker-add"), ("bpy.ops.mesh.bevel*", "modeling/meshes/editing/edge/bevel.html#bpy-ops-mesh-bevel"), ("bpy.ops.mesh.inset*", "modeling/meshes/editing/face/inset_faces.html#bpy-ops-mesh-inset"), - ("bpy.ops.mesh.knife*", "modeling/meshes/tools/knife.html#bpy-ops-mesh-knife"), + ("bpy.ops.mesh.knife*", "modeling/meshes/editing/mesh/knife_topology_tool.html#bpy-ops-mesh-knife"), ("bpy.ops.mesh.merge*", "modeling/meshes/editing/mesh/merge.html#bpy-ops-mesh-merge"), ("bpy.ops.mesh.relax*", "addons/mesh/edit_mesh_tools.html#bpy-ops-mesh-relax"), ("bpy.ops.mesh.screw*", "modeling/meshes/editing/edge/screw.html#bpy-ops-mesh-screw"), @@ -3172,6 +3257,7 @@ url_manual_mapping = ( ("bpy.ops.outliner*", "editors/outliner/index.html#bpy-ops-outliner"), ("bpy.ops.particle*", "physics/particles/index.html#bpy-ops-particle"), ("bpy.ops.uv.align*", "modeling/meshes/uv/editing.html#bpy-ops-uv-align"), + ("bpy.ops.uv.paste*", "modeling/meshes/uv/editing.html#bpy-ops-uv-paste"), ("bpy.ops.uv.reset*", "modeling/meshes/editing/uv.html#bpy-ops-uv-reset"), ("bpy.ops.wm.addon*", "editors/preferences/addons.html#bpy-ops-wm-addon"), ("bpy.types.action*", "animation/actions.html#bpy-types-action"), @@ -3199,6 +3285,7 @@ url_manual_mapping = ( ("bpy.ops.ptcache*", "physics/baking.html#bpy-ops-ptcache"), ("bpy.ops.surface*", "modeling/surfaces/index.html#bpy-ops-surface"), ("bpy.ops.texture*", "render/materials/legacy_textures/index.html#bpy-ops-texture"), + ("bpy.ops.uv.copy*", "modeling/meshes/uv/editing.html#bpy-ops-uv-copy"), ("bpy.ops.uv.hide*", "modeling/meshes/uv/editing.html#bpy-ops-uv-hide"), ("bpy.ops.uv.weld*", "modeling/meshes/uv/editing.html#bpy-ops-uv-weld"), ("bpy.ops.wm.link*", "files/linked_libraries/link_append.html#bpy-ops-wm-link"), From 4701421dbe239e5d02a5ee367c442b14660c49c0 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Fri, 23 Dec 2022 19:06:29 -0500 Subject: [PATCH 0273/1522] UI: Remove unused light object panel (Correction) This panel showed a duplication of options that were in the main light panel and only mistakenly shows up in the workbench engine where lights should have no options. This panel was also used by the POV-Ray add-on but that was removed recently. --- intern/cycles/blender/addon/ui.py | 1 - 1 file changed, 1 deletion(-) diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 6ac97a32f61..102e014297f 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -2360,7 +2360,6 @@ def draw_pause(self, context): def get_panels(): exclude_panels = { - 'DATA_PT_area', 'DATA_PT_camera_dof', 'DATA_PT_falloff_curve', 'DATA_PT_light', From 14667de65bd139c13e1b19cc8a0621ab7147d7c2 Mon Sep 17 00:00:00 2001 From: Martijn Versteegh Date: Fri, 23 Dec 2022 12:01:59 +0100 Subject: [PATCH 0274/1522] Fix uninitialized ColorSceneLinear4f occuring in certain situations. On gcc 11.3, Ubuntu 22.04 the default constructor for ColorSceneLinear4f did not zero the r,g,b,a member variables. Replacing the empty constructor with a default constructor circumvents this problem (compiler bug? ) even though it *should* be more or less equivalent. --- source/blender/blenlib/BLI_color.hh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/blender/blenlib/BLI_color.hh b/source/blender/blenlib/BLI_color.hh index b1b9aeb17f1..0256cec667c 100644 --- a/source/blender/blenlib/BLI_color.hh +++ b/source/blender/blenlib/BLI_color.hh @@ -152,9 +152,7 @@ BLI_INLINE ColorTheme4 BLI_color_convert_to_theme4b(const ColorTheme4 class ColorSceneLinear4f final : public ColorRGBA { public: - constexpr ColorSceneLinear4f() : ColorRGBA() - { - } + constexpr ColorSceneLinear4f() = default; constexpr ColorSceneLinear4f(const float *rgba) : ColorRGBA(rgba) From e1180bfdb2965ba76daef223efdf5600bddba0ca Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Sat, 24 Dec 2022 11:37:13 +0100 Subject: [PATCH 0275/1522] GPencil: Use Material or Vertex Color for Brush cursor The color of the brush cursor is changed depending of the mode selected. If the mode is stroke vertex color, use vertex color, otherwise it uses material stroke color. --- source/blender/editors/gpencil/gpencil_utils.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 3abb04c6360..9f6b17b66e2 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -1736,6 +1736,7 @@ static bool gpencil_brush_cursor_poll(bContext *C) static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdata) { Scene *scene = CTX_data_scene(C); + ToolSettings *ts = scene->toolsettings; Object *ob = CTX_data_active_object(C); ARegion *region = CTX_wm_region(C); Paint *paint = BKE_paint_get_active_from_context(C); @@ -1800,10 +1801,16 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat /* Check user setting for cursor size. */ fixed_radius = ((brush->gpencil_settings->flag & GP_BRUSH_SHOW_DRAW_SIZE) == 0); + const bool is_vertex_stroke = + (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) && + (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) || + (!GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) && + (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR)); + if (fixed_radius) { /* Show fixed radius. */ radius = 2.0f; - copy_v3_v3(color, gp_style->stroke_rgba); + copy_v3_v3(color, is_vertex_stroke ? brush->rgb : gp_style->stroke_rgba); } else { /* Show brush size. */ @@ -1841,7 +1848,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat radius = (1 / distance) * 2.0f * gpd->pixfactor * (brush_size / 64); } - copy_v3_v3(color, brush->rgb); + copy_v3_v3(color, is_vertex_stroke ? brush->rgb : gp_style->stroke_rgba); } } else { From 8fab53c023ef3ddad1c3b1125eb9b932c95cd05f Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 24 Dec 2022 14:00:46 +0100 Subject: [PATCH 0276/1522] BLI: add last time to scoped averaged time --- source/blender/blenlib/intern/timeit.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/blenlib/intern/timeit.cc b/source/blender/blenlib/intern/timeit.cc index 7a8cf8da038..7d4b1118b2b 100644 --- a/source/blender/blenlib/intern/timeit.cc +++ b/source/blender/blenlib/intern/timeit.cc @@ -42,6 +42,8 @@ ScopedTimerAveraged::~ScopedTimerAveraged() print_duration(total_time_ / total_count_); std::cout << ", Min: "; print_duration(min_time_); + std::cout << ", Last: "; + print_duration(duration); std::cout << ")\n"; } From 00b3f863b8c4493fb7c93c799c3cdc6f11abb6de Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sat, 24 Dec 2022 16:09:16 -0500 Subject: [PATCH 0277/1522] Curves: Remove option to disable selection Remove the redundant option to disable selection in order to simplify the tools and UI, both conceptually and internally. It was possible to disable curves selection completely by clicking on the active selection domain. However, that was redundant compared to just selecting everything by pressing "A". The remaining potential use could have been saving a selection for later, but that can be done with more complete attribute editing tools in the future. --- .../keyconfig/keymap_data/blender_default.py | 2 -- release/scripts/startup/bl_ui/space_view3d.py | 13 ++----- .../blenloader/intern/versioning_300.cc | 4 +++ .../engines/overlay/overlay_sculpt_curves.cc | 4 --- .../editors/curves/intern/curves_ops.cc | 36 +------------------ .../sculpt_paint/curves_sculpt_selection.cc | 12 ------- .../curves_sculpt_selection_paint.cc | 1 - source/blender/makesdna/DNA_curves_types.h | 1 - source/blender/makesrna/intern/rna_curves.c | 6 ---- 9 files changed, 7 insertions(+), 72 deletions(-) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index e6b8cc12b29..7712f75fc64 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5621,8 +5621,6 @@ def km_sculpt_curves(params): {"properties": [("mode", 'SMOOTH')]}), ("curves.set_selection_domain", {"type": 'ONE', "value": 'PRESS'}, {"properties": [("domain", 'POINT')]}), ("curves.set_selection_domain", {"type": 'TWO', "value": 'PRESS'}, {"properties": [("domain", 'CURVE')]}), - ("curves.disable_selection", {"type": 'ONE', "value": 'PRESS', "alt": True}, None), - ("curves.disable_selection", {"type": 'TWO', "value": 'PRESS', "alt": True}, None), *_template_paint_radial_control("curves_sculpt"), *_template_items_select_actions(params, "sculpt_curves.select_all"), ("sculpt_curves.min_distance_edit", {"type": 'R', "value": 'PRESS', "shift": True}, {}), diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 4feb92e71df..0eba15e4267 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -721,18 +721,9 @@ class VIEW3D_HT_header(Header): curves = obj.data row = layout.row(align=True) - - # Combine the "use selection" toggle with the "set domain" operators - # to allow turning selection off directly. domain = curves.selection_domain - if domain == 'POINT': - row.prop(curves, "use_sculpt_selection", text="", icon='CURVE_BEZCIRCLE') - else: - row.operator("curves.set_selection_domain", text="", icon='CURVE_BEZCIRCLE').domain = 'POINT' - if domain == 'CURVE': - row.prop(curves, "use_sculpt_selection", text="", icon='CURVE_PATH') - else: - row.operator("curves.set_selection_domain", text="", icon='CURVE_PATH').domain = 'CURVE' + row.operator("curves.set_selection_domain", text="", icon='CURVE_BEZCIRCLE', depress=(domain == 'POINT')).domain = 'POINT' + row.operator("curves.set_selection_domain", text="", icon='CURVE_PATH', depress=(domain == 'CURVE')).domain = 'CURVE' # Grease Pencil if obj and obj.type == 'GPENCIL' and context.gpencil_data: diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 90bca21cbe3..11392d04991 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3846,5 +3846,9 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) */ { /* Keep this block, even when empty. */ + const int CV_SCULPT_SELECTION_ENABLED = (1 << 1); + LISTBASE_FOREACH (Curves *, curves_id, &bmain->hair_curves) { + curves_id->flag &= ~CV_SCULPT_SELECTION_ENABLED; + } } } diff --git a/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc index 68de5dcd11d..73edf9dc5d3 100644 --- a/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc +++ b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc @@ -31,10 +31,6 @@ void OVERLAY_sculpt_curves_cache_init(OVERLAY_Data *vedata) static bool everything_selected(const Curves &curves_id) { - if (!(curves_id.flag & CV_SCULPT_SELECTION_ENABLED)) { - /* When the selection is disabled, conceptually everything is selected. */ - return true; - } const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap( curves_id.geometry); blender::VArray selection; diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 01909c304cd..880470ea66f 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -744,13 +744,12 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op) const eAttrDomain domain = eAttrDomain(RNA_enum_get(op->ptr, "domain")); for (Curves *curves_id : get_unique_editable_curves(*C)) { - if (curves_id->selection_domain == domain && (curves_id->flag & CV_SCULPT_SELECTION_ENABLED)) { + if (curves_id->selection_domain == domain) { continue; } const eAttrDomain old_domain = eAttrDomain(curves_id->selection_domain); curves_id->selection_domain = domain; - curves_id->flag |= CV_SCULPT_SELECTION_ENABLED; CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry); bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); @@ -802,38 +801,6 @@ static void CURVES_OT_set_selection_domain(wmOperatorType *ot) RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE)); } -namespace disable_selection { - -static int curves_disable_selection_exec(bContext *C, wmOperator * /*op*/) -{ - for (Curves *curves_id : get_unique_editable_curves(*C)) { - curves_id->flag &= ~CV_SCULPT_SELECTION_ENABLED; - - /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic - * attribute for now. */ - DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id); - } - - WM_main_add_notifier(NC_SPACE | ND_SPACE_VIEW3D, nullptr); - - return OPERATOR_FINISHED; -} - -} // namespace disable_selection - -static void CURVES_OT_disable_selection(wmOperatorType *ot) -{ - ot->name = "Disable Selection"; - ot->idname = __func__; - ot->description = "Disable the drawing of influence of selection in sculpt mode"; - - ot->exec = disable_selection::curves_disable_selection_exec; - ot->poll = editable_curves_poll; - - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - static bool varray_contains_nonzero(const VArray &data) { bool contains_nonzero = false; @@ -1035,6 +1002,5 @@ void ED_operatortypes_curves() WM_operatortype_append(CURVES_OT_snap_curves_to_surface); WM_operatortype_append(CURVES_OT_set_selection_domain); WM_operatortype_append(SCULPT_CURVES_OT_select_all); - WM_operatortype_append(CURVES_OT_disable_selection); WM_operatortype_append(CURVES_OT_surface_set); } diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc index a955a074df2..7ae92a99919 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc @@ -26,9 +26,6 @@ static VArray get_curves_selection(const CurvesGeometry &curves, const eA VArray get_curves_selection(const Curves &curves_id) { - if (!(curves_id.flag & CV_SCULPT_SELECTION_ENABLED)) { - return VArray::ForSingle(1.0f, CurvesGeometry::wrap(curves_id.geometry).curves_num()); - } return get_curves_selection(CurvesGeometry::wrap(curves_id.geometry), eAttrDomain(curves_id.selection_domain)); } @@ -49,9 +46,6 @@ static VArray get_point_selection(const CurvesGeometry &curves, const eAt VArray get_point_selection(const Curves &curves_id) { - if (!(curves_id.flag & CV_SCULPT_SELECTION_ENABLED)) { - return VArray::ForSingle(1.0f, CurvesGeometry::wrap(curves_id.geometry).points_num()); - } return get_point_selection(CurvesGeometry::wrap(curves_id.geometry), eAttrDomain(curves_id.selection_domain)); } @@ -97,9 +91,6 @@ static IndexMask retrieve_selected_curves(const CurvesGeometry &curves, IndexMask retrieve_selected_curves(const Curves &curves_id, Vector &r_indices) { - if (!(curves_id.flag & CV_SCULPT_SELECTION_ENABLED)) { - return CurvesGeometry::wrap(curves_id.geometry).curves_range(); - } return retrieve_selected_curves(CurvesGeometry::wrap(curves_id.geometry), eAttrDomain(curves_id.selection_domain), r_indices); @@ -142,9 +133,6 @@ static IndexMask retrieve_selected_points(const CurvesGeometry &curves, IndexMask retrieve_selected_points(const Curves &curves_id, Vector &r_indices) { - if (!(curves_id.flag & CV_SCULPT_SELECTION_ENABLED)) { - return CurvesGeometry::wrap(curves_id.geometry).points_range(); - } return retrieve_selected_points(CurvesGeometry::wrap(curves_id.geometry), eAttrDomain(curves_id.selection_domain), r_indices); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc b/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc index cc5a5e7ae8a..3e2803ae5b7 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc @@ -81,7 +81,6 @@ struct SelectionPaintOperationExecutor { curves_id_ = static_cast(object_->data); curves_ = &CurvesGeometry::wrap(curves_id_->geometry); - curves_id_->flag |= CV_SCULPT_SELECTION_ENABLED; if (curves_->curves_num() == 0) { return; } diff --git a/source/blender/makesdna/DNA_curves_types.h b/source/blender/makesdna/DNA_curves_types.h index 847a4b8a02c..fea994e2739 100644 --- a/source/blender/makesdna/DNA_curves_types.h +++ b/source/blender/makesdna/DNA_curves_types.h @@ -180,7 +180,6 @@ typedef struct Curves { /** #Curves.flag */ enum { HA_DS_EXPAND = (1 << 0), - CV_SCULPT_SELECTION_ENABLED = (1 << 1), }; /** #Curves.symmetry */ diff --git a/source/blender/makesrna/intern/rna_curves.c b/source/blender/makesrna/intern/rna_curves.c index bd4575a1740..f19f632519f 100644 --- a/source/blender/makesrna/intern/rna_curves.c +++ b/source/blender/makesrna/intern/rna_curves.c @@ -414,12 +414,6 @@ static void rna_def_curves(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, 0, "rna_Curves_update_data"); - prop = RNA_def_property(srna, "use_sculpt_selection", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", CV_SCULPT_SELECTION_ENABLED); - RNA_def_property_ui_text(prop, "Use Sculpt Selection", ""); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, 0, "rna_Curves_update_draw"); - /* attributes */ rna_def_attributes_common(srna); From 09ba00974f8f8a83c801324062795f3dfb78c1b8 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sun, 25 Dec 2022 20:01:59 +0900 Subject: [PATCH 0278/1522] Fix recent liboverride diff report refactor. In rBfcddb7cda766 I forgot to update part of the whole diffing chain, effectively breaking the report flags propagation from any sub-structs of RNA IDs structs. --- .../intern/rna_access_compare_override.c | 15 +----- source/blender/makesrna/intern/rna_internal.h | 2 +- .../makesrna/intern/rna_internal_types.h | 3 +- source/blender/makesrna/intern/rna_rna.c | 50 +++++++++---------- 4 files changed, 28 insertions(+), 42 deletions(-) diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c index 0b8412367bf..ca133320cb6 100644 --- a/source/blender/makesrna/intern/rna_access_compare_override.c +++ b/source/blender/makesrna/intern/rna_access_compare_override.c @@ -413,25 +413,14 @@ static int rna_property_override_diff(Main *bmain, return 1; } - bool override_changed = false; eRNAOverrideMatch diff_flags = flags; if (!RNA_property_overridable_get(&prop_a->ptr, prop_a->rawprop) || (!ELEM(RNA_property_type(prop_a->rawprop), PROP_POINTER, PROP_COLLECTION) && !RNA_property_editable_flag(&prop_a->ptr, prop_a->rawprop))) { diff_flags &= ~RNA_OVERRIDE_COMPARE_CREATE; } - const int diff = override_diff(bmain, - prop_a, - prop_b, - mode, - override, - rna_path, - rna_path_len, - diff_flags, - &override_changed); - if (override_changed && r_report_flags) { - *r_report_flags |= RNA_OVERRIDE_MATCH_RESULT_CREATED; - } + const int diff = override_diff( + bmain, prop_a, prop_b, mode, override, rna_path, rna_path_len, diff_flags, r_report_flags); return diff; } diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index ea829e5cd86..57aea23024f 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -552,7 +552,7 @@ int rna_property_override_diff_default(struct Main *bmain, const char *rna_path, size_t rna_path_len, int flags, - bool *r_override_changed); + eRNAOverrideMatchResult *r_report_flag); bool rna_property_override_store_default(struct Main *bmain, struct PointerRNA *ptr_local, diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h index a5b06cabade..3e621910ec7 100644 --- a/source/blender/makesrna/intern/rna_internal_types.h +++ b/source/blender/makesrna/intern/rna_internal_types.h @@ -8,6 +8,7 @@ #include "DNA_listBase.h" +#include "RNA_access.h" #include "RNA_types.h" struct BlenderRNA; @@ -205,7 +206,7 @@ typedef int (*RNAPropOverrideDiff)(struct Main *bmain, const char *rna_path, size_t rna_path_len, int flags, - bool *r_override_changed); + eRNAOverrideMatchResult *r_report_flag); /** * Only used for differential override (add, sub, etc.). diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c index 54ccba24247..f3249e5c1ee 100644 --- a/source/blender/makesrna/intern/rna_rna.c +++ b/source/blender/makesrna/intern/rna_rna.c @@ -1340,7 +1340,7 @@ static int rna_property_override_diff_propptr(Main *bmain, const int rna_itemindex_a, const int rna_itemindex_b, const int flags, - bool *r_override_changed) + eRNAOverrideMatchResult *r_report_flag) { BLI_assert(ELEM(property_type, PROP_POINTER, PROP_COLLECTION)); @@ -1418,8 +1418,8 @@ static int rna_property_override_diff_propptr(Main *bmain, * as used all of its operations. */ op->tag &= ~IDOVERRIDE_LIBRARY_TAG_UNUSED; opop->tag &= ~IDOVERRIDE_LIBRARY_TAG_UNUSED; - if (r_override_changed) { - *r_override_changed = created; + if (r_report_flag && created) { + *r_report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED; } } else { @@ -1547,7 +1547,6 @@ static int rna_property_override_diff_propptr(Main *bmain, } } - eRNAOverrideMatchResult report_flags = 0; const bool match = RNA_struct_override_matches(bmain, propptr_a, propptr_b, @@ -1555,10 +1554,7 @@ static int rna_property_override_diff_propptr(Main *bmain, extended_rna_path_len, override, flags, - &report_flags); - if (r_override_changed && (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) != 0) { - *r_override_changed = true; - } + r_report_flag); if (!ELEM(extended_rna_path, extended_rna_path_buffer, rna_path)) { MEM_freeN(extended_rna_path); @@ -1596,7 +1592,7 @@ int rna_property_override_diff_default(Main *bmain, const char *rna_path, const size_t rna_path_len, const int flags, - bool *r_override_changed) + eRNAOverrideMatchResult *r_report_flag) { PointerRNA *ptr_a = &prop_a->ptr; PointerRNA *ptr_b = &prop_b->ptr; @@ -1648,8 +1644,8 @@ int rna_property_override_diff_default(Main *bmain, if (op != NULL && created) { BKE_lib_override_library_property_operation_get( op, IDOVERRIDE_LIBRARY_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL); - if (r_override_changed) { - *r_override_changed = created; + if (*r_report_flag) { + *r_report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED; } } else { @@ -1677,8 +1673,8 @@ int rna_property_override_diff_default(Main *bmain, if (op != NULL && created) { /* If not yet overridden... */ BKE_lib_override_library_property_operation_get( op, IDOVERRIDE_LIBRARY_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL); - if (r_override_changed) { - *r_override_changed = created; + if (r_report_flag) { + *r_report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED; } } } @@ -1709,8 +1705,8 @@ int rna_property_override_diff_default(Main *bmain, if (op != NULL && created) { BKE_lib_override_library_property_operation_get( op, IDOVERRIDE_LIBRARY_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL); - if (r_override_changed) { - *r_override_changed = created; + if (r_report_flag && created) { + *r_report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED; } } else { @@ -1738,8 +1734,8 @@ int rna_property_override_diff_default(Main *bmain, if (op != NULL && created) { /* If not yet overridden... */ BKE_lib_override_library_property_operation_get( op, IDOVERRIDE_LIBRARY_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL); - if (r_override_changed) { - *r_override_changed = created; + if (r_report_flag) { + *r_report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED; } } } @@ -1770,8 +1766,8 @@ int rna_property_override_diff_default(Main *bmain, if (op != NULL && created) { BKE_lib_override_library_property_operation_get( op, IDOVERRIDE_LIBRARY_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL); - if (r_override_changed) { - *r_override_changed = created; + if (r_report_flag) { + *r_report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED; } } else { @@ -1799,8 +1795,8 @@ int rna_property_override_diff_default(Main *bmain, if (op != NULL && created) { /* If not yet overridden... */ BKE_lib_override_library_property_operation_get( op, IDOVERRIDE_LIBRARY_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL); - if (r_override_changed) { - *r_override_changed = created; + if (r_report_flag) { + *r_report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED; } } } @@ -1820,8 +1816,8 @@ int rna_property_override_diff_default(Main *bmain, if (op != NULL && created) { /* If not yet overridden... */ BKE_lib_override_library_property_operation_get( op, IDOVERRIDE_LIBRARY_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL); - if (r_override_changed) { - *r_override_changed = created; + if (r_report_flag) { + *r_report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED; } } } @@ -1852,8 +1848,8 @@ int rna_property_override_diff_default(Main *bmain, if (op != NULL && created) { /* If not yet overridden... */ BKE_lib_override_library_property_operation_get( op, IDOVERRIDE_LIBRARY_OP_REPLACE, NULL, NULL, -1, -1, true, NULL, NULL); - if (r_override_changed) { - *r_override_changed = created; + if (r_report_flag) { + *r_report_flag |= RNA_OVERRIDE_MATCH_RESULT_CREATED; } } } @@ -1898,7 +1894,7 @@ int rna_property_override_diff_default(Main *bmain, -1, -1, flags, - r_override_changed); + r_report_flag); } break; } @@ -2063,7 +2059,7 @@ int rna_property_override_diff_default(Main *bmain, idx_a, idx_b, flags, - r_override_changed); + r_report_flag); equals = equals && (comp == 0); } } From 32b1947be240111e6ccaa933d354c8a4855cd810 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 26 Dec 2022 16:22:50 +0900 Subject: [PATCH 0279/1522] Fix T103389: Invalid flags in default_material_surface->nodetree->tag. There are still codepaths that can create embedded IDs with `NO_MAIN` tag. Related to T88555 TODO. --- source/blender/blenloader/intern/readfile.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 87d3255056b..3481611298d 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -2026,8 +2026,10 @@ static void direct_link_id_common( } /* No-main and other types of special IDs should never be written in .blend files. */ - BLI_assert((id->tag & (LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT | LIB_TAG_NOT_ALLOCATED)) == - 0); + /* NOTE: `NO_MAIN` is commented for now as some code paths may still generate embedded IDs with + * this tag, see T103389. Related to T88555. */ + BLI_assert( + (id->tag & (/*LIB_TAG_NO_MAIN |*/ LIB_TAG_NO_USER_REFCOUNT | LIB_TAG_NOT_ALLOCATED)) == 0); if ((tag & LIB_TAG_TEMP_MAIN) == 0) { BKE_lib_libblock_session_uuid_ensure(id); From 9e0feec0d36a5d331bda303b27d7b4d66315e62e Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 26 Dec 2022 16:31:25 +0900 Subject: [PATCH 0280/1522] Fix T103421: Library weak reference generates "Could not find .blend" errors when "Find Missing Files". Do not consider weak references in `BKE_bpath_missing_files_find`, just as already done in `BKE_bpath_missing_files_check`. --- source/blender/blenkernel/intern/bpath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c index 95d6121fc13..8accf6b1c9b 100644 --- a/source/blender/blenkernel/intern/bpath.c +++ b/source/blender/blenkernel/intern/bpath.c @@ -387,7 +387,7 @@ void BKE_bpath_missing_files_find(Main *bmain, { struct BPathFind_Data data = {NULL}; const int flag = BKE_BPATH_FOREACH_PATH_ABSOLUTE | BKE_BPATH_FOREACH_PATH_RELOAD_EDITED | - BKE_BPATH_FOREACH_PATH_RESOLVE_TOKEN; + BKE_BPATH_FOREACH_PATH_RESOLVE_TOKEN | BKE_BPATH_TRAVERSE_SKIP_WEAK_REFERENCES; data.basedir = BKE_main_blendfile_path(bmain); data.reports = reports; From 87cf495860a8c00e345a9ee5574a8c1befb393b7 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sun, 25 Dec 2022 18:29:41 +0200 Subject: [PATCH 0281/1522] Fix cloth regression after removing mvert pointers in Mesh. This is an obvious editing mistake introduced in 05952aa94d33eeb, resulting in incorrect vertex coordinates used when raycasting for internal springs with a rest shape key. --- source/blender/blenkernel/intern/cloth.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/cloth.cc b/source/blender/blenkernel/intern/cloth.cc index 73cf7e1f805..23bbaaf58b2 100644 --- a/source/blender/blenkernel/intern/cloth.cc +++ b/source/blender/blenkernel/intern/cloth.cc @@ -1168,7 +1168,7 @@ static Mesh *cloth_make_rest_mesh(ClothModifierData *clmd, Mesh *mesh) { Mesh *new_mesh = BKE_mesh_copy_for_eval(mesh, false); ClothVertex *verts = clmd->clothObject->verts; - MVert *mvert = BKE_mesh_verts_for_write(mesh); + MVert *mvert = BKE_mesh_verts_for_write(new_mesh); /* vertex count is already ensured to match */ for (uint i = 0; i < mesh->totvert; i++, verts++) { From cb93433a566a069de7683a5eeb3541f8292d5db2 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 26 Dec 2022 20:24:16 +0900 Subject: [PATCH 0282/1522] Band-aid fix crash when appending an overridden collection from T103062. This commit addresses that specific case related to Collection ID type, using a band-aid fix which is hopefully safe enough. T103062 will remain open as a TODO task for a proper fix later. --- source/blender/blenloader/intern/readfile.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 3481611298d..953beee6fbd 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -3921,6 +3921,11 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) BKE_lib_override_library_main_validate(bfd->main, fd->reports->reports); BKE_lib_override_library_main_update(bfd->main); + /* FIXME Temporary 'fix' to a problem in how temp ID are copied in + * `BKE_lib_override_library_main_update`, see T103062. + * Proper fix involves first addressing T90610. */ + BKE_main_collections_parent_relations_rebuild(bfd->main); + fd->reports->duration.lib_overrides = PIL_check_seconds_timer() - fd->reports->duration.lib_overrides; } @@ -4543,6 +4548,11 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag) BKE_main_id_tag_all(mainvar, LIB_TAG_NEW, false); + /* FIXME Temporary 'fix' to a problem in how temp ID are copied in + * `BKE_lib_override_library_main_update`, see T103062. + * Proper fix involves first addressing T90610. */ + BKE_main_collections_parent_relations_rebuild(mainvar); + /* Make all relative paths, relative to the open blend file. */ fix_relpaths_library(BKE_main_blendfile_path(mainvar), mainvar); From 7be5ca63aee8de3cfeabdb9bdd8bb5613defd824 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Mon, 26 Dec 2022 14:42:01 +0200 Subject: [PATCH 0283/1522] Python API Docs: explain the CANCELLED return code of operators. The effect of CANCELLED on the undo stack is quite obscure, and mistakenly using it after doing some changes causes confusing behavior. It's better to describe it explicitly in the docs. --- doc/python_api/examples/bpy.ops.py | 5 +++-- doc/python_api/examples/bpy.types.Operator.5.py | 1 + doc/python_api/examples/bpy.types.Operator.py | 7 +++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/python_api/examples/bpy.ops.py b/doc/python_api/examples/bpy.ops.py index e8d545fc855..aa51c6c5162 100644 --- a/doc/python_api/examples/bpy.ops.py +++ b/doc/python_api/examples/bpy.ops.py @@ -10,8 +10,9 @@ Only keyword arguments can be used to pass operator properties. Operators don't have return values as you might expect, instead they return a set() which is made up of: ``{'RUNNING_MODAL', 'CANCELLED', 'FINISHED', 'PASS_THROUGH'}``. -Common return values are ``{'FINISHED'}`` and ``{'CANCELLED'}``. - +Common return values are ``{'FINISHED'}`` and ``{'CANCELLED'}``, the latter +meaning that the operator execution was aborted without making any changes or +saving an undo history entry. Calling an operator in the wrong context will raise a ``RuntimeError``, there is a poll() method to avoid this problem. diff --git a/doc/python_api/examples/bpy.types.Operator.5.py b/doc/python_api/examples/bpy.types.Operator.5.py index 0b6035fc3da..6f912f863f1 100644 --- a/doc/python_api/examples/bpy.types.Operator.5.py +++ b/doc/python_api/examples/bpy.types.Operator.5.py @@ -44,6 +44,7 @@ class ModalOperator(bpy.types.Operator): elif event.type == 'LEFTMOUSE': # Confirm return {'FINISHED'} elif event.type in {'RIGHTMOUSE', 'ESC'}: # Cancel + # Revert all changes that have been made context.object.location.x = self.init_loc_x return {'CANCELLED'} diff --git a/doc/python_api/examples/bpy.types.Operator.py b/doc/python_api/examples/bpy.types.Operator.py index 41b96ac402f..19cd08b018f 100644 --- a/doc/python_api/examples/bpy.types.Operator.py +++ b/doc/python_api/examples/bpy.types.Operator.py @@ -7,9 +7,16 @@ This script shows simple operator which prints a message. Since the operator only has an :class:`Operator.execute` function it takes no user input. +The function should return ``{'FINISHED'}`` or ``{'CANCELLED'}``, the latter +meaning that operator execution was aborted without making any changes, and +saving an undo entry isn't neccesary. If an error is detected after some changes +have already been made, use the ``{'FINISHED'}`` return code, or the behavior +of undo will be confusing for the user. + .. note:: Operator subclasses must be registered before accessing them from blender. + """ import bpy From 6b9825e6f792018049b38d17e9f1123ef814d87f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 26 Dec 2022 10:17:51 -0500 Subject: [PATCH 0284/1522] Fix T103463: Repeat last crashes in node editor ae886596a0f1a220372 tried to retrieve keymap data from a null pointer. --- source/blender/editors/transform/transform.c | 37 ++++++++++---------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index cdbd85e85a1..ff93bcaf8ca 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1871,25 +1871,26 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } } } - } - if (t->data_type == &TransConvertType_Node) { - /* Set the initial auto-attach flag based on whether the chosen keymap key is pressed at the - * start of the operator. */ - t->modifiers |= MOD_NODE_ATTACH; - LISTBASE_FOREACH (const wmKeyMapItem *, kmi, &t->keymap->items) { - if (kmi->flag & KMI_INACTIVE) { - continue; - } - - if (kmi->propvalue == TFM_MODAL_NODE_ATTACH_OFF && kmi->val == KM_PRESS) { - if ((ELEM(kmi->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY) && (event->modifier & KM_CTRL)) || - (ELEM(kmi->type, EVT_LEFTSHIFTKEY, EVT_RIGHTSHIFTKEY) && - (event->modifier & KM_SHIFT)) || - (ELEM(kmi->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY) && (event->modifier & KM_ALT)) || - ((kmi->type == EVT_OSKEY) && (event->modifier & KM_OSKEY))) { - t->modifiers &= ~MOD_NODE_ATTACH; + if (t->data_type == &TransConvertType_Node) { + /* Set the initial auto-attach flag based on whether the chosen keymap key is pressed at the + * start of the operator. */ + t->modifiers |= MOD_NODE_ATTACH; + LISTBASE_FOREACH (const wmKeyMapItem *, kmi, &t->keymap->items) { + if (kmi->flag & KMI_INACTIVE) { + continue; + } + + if (kmi->propvalue == TFM_MODAL_NODE_ATTACH_OFF && kmi->val == KM_PRESS) { + if ((ELEM(kmi->type, EVT_LEFTCTRLKEY, EVT_RIGHTCTRLKEY) && + (event->modifier & KM_CTRL)) || + (ELEM(kmi->type, EVT_LEFTSHIFTKEY, EVT_RIGHTSHIFTKEY) && + (event->modifier & KM_SHIFT)) || + (ELEM(kmi->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY) && (event->modifier & KM_ALT)) || + ((kmi->type == EVT_OSKEY) && (event->modifier & KM_OSKEY))) { + t->modifiers &= ~MOD_NODE_ATTACH; + } + break; } - break; } } } From 7911954b403efe1c93bf5f94961520e7b96c50ec Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 26 Dec 2022 10:49:21 -0500 Subject: [PATCH 0285/1522] Fix T103452: Active & default color attributes reset on modifier apply I missed adding the "convert type/domain to mask" macros. Also refactor slightly to split the matching attribute test to a separate function to ease debugging and reduce duplication. --- .../blender/editors/object/object_modifier.cc | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 523be5eda13..e8da35c25f4 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -858,25 +858,35 @@ static bool modifier_apply_shape(Main *bmain, return true; } +static bool meta_data_matches(const std::optional meta_data, + const eAttrDomainMask domains, + const eCustomDataMask types) +{ + if (!meta_data) { + return false; + } + if (!(ATTR_DOMAIN_AS_MASK(meta_data->domain) & domains)) { + return false; + } + if (!(CD_TYPE_AS_MASK(meta_data->data_type) & types)) { + return false; + } + return true; +} + static void remove_invalid_attribute_strings(Mesh &mesh) { using namespace blender; bke::AttributeAccessor attributes = mesh.attributes(); - if (mesh.active_color_attribute) { - const std::optional meta_data = attributes.lookup_meta_data( - mesh.active_color_attribute); - if (!meta_data || !(meta_data->domain & ATTR_DOMAIN_MASK_COLOR) || - !(meta_data->data_type & CD_MASK_COLOR_ALL)) { - MEM_SAFE_FREE(mesh.active_color_attribute); - } + if (!meta_data_matches(attributes.lookup_meta_data(mesh.active_color_attribute), + ATTR_DOMAIN_MASK_COLOR, + CD_MASK_COLOR_ALL)) { + MEM_SAFE_FREE(mesh.active_color_attribute); } - if (mesh.default_color_attribute) { - const std::optional meta_data = attributes.lookup_meta_data( - mesh.default_color_attribute); - if (!meta_data || !(meta_data->domain & ATTR_DOMAIN_MASK_COLOR) || - !(meta_data->data_type & CD_MASK_COLOR_ALL)) { - MEM_SAFE_FREE(mesh.default_color_attribute); - } + if (!meta_data_matches(attributes.lookup_meta_data(mesh.default_color_attribute), + ATTR_DOMAIN_MASK_COLOR, + CD_MASK_COLOR_ALL)) { + MEM_SAFE_FREE(mesh.default_color_attribute); } } From a7cec5a4dbfb30ba0aa709e6765c1927faaba340 Mon Sep 17 00:00:00 2001 From: Jamell Moore Date: Mon, 26 Dec 2022 14:43:32 -0500 Subject: [PATCH 0286/1522] Fix T103011: Exact boolean skips copying edge custom data layers When converting from imesh to mesh for the final result, custom data should be copied from ALL operands including the main mesh. Differential Revision: https://developer.blender.org/D16854 --- source/blender/blenkernel/intern/mesh_boolean_convert.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index 1252e90e11c..3d98fc7c958 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -689,7 +689,7 @@ static void merge_vertex_loop_poly_customdata_layers(Mesh *target, MeshesToIMesh static void merge_edge_customdata_layers(Mesh *target, MeshesToIMeshInfo &mim) { - for (int mesh_index = 1; mesh_index < mim.meshes.size(); ++mesh_index) { + for (int mesh_index = 0; mesh_index < mim.meshes.size(); ++mesh_index) { const Mesh *me = mim.meshes[mesh_index]; if (me->totedge) { CustomData_merge( From 5206d72dca6977e4d6ec3d849e4e1f899317e975 Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Mon, 26 Dec 2022 14:46:21 -0500 Subject: [PATCH 0287/1522] Cleanup: Remove boolean template instantiation in Blur node The node doesn't support blurring boolean attributes, so avoid compiling an implementation for boolean data. Differential Revision: https://developer.blender.org/D16867 --- .../geometry/nodes/node_geo_blur_attribute.cc | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc index 23c39748cf9..c2250019a30 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc @@ -278,11 +278,13 @@ static void blur_on_mesh(const Mesh &mesh, } attribute_math::convert_to_static_type(main_buffer.type(), [&](auto dummy) { using T = decltype(dummy); - blur_on_mesh_exec(neighbor_weights, - neighbors_map, - iterations, - main_buffer.typed(), - tmp_buffer.typed()); + if constexpr (!std::is_same_v) { + blur_on_mesh_exec(neighbor_weights, + neighbors_map, + iterations, + main_buffer.typed(), + tmp_buffer.typed()); + } }); } @@ -362,8 +364,10 @@ static void blur_on_curves(const bke::CurvesGeometry &curves, { attribute_math::convert_to_static_type(main_buffer.type(), [&](auto dummy) { using T = decltype(dummy); - blur_on_curve_exec( - curves, neighbor_weights, iterations, main_buffer.typed(), tmp_buffer.typed()); + if constexpr (!std::is_same_v) { + blur_on_curve_exec( + curves, neighbor_weights, iterations, main_buffer.typed(), tmp_buffer.typed()); + } }); } From 997eb77fd4ab69252c2c8bb03a9b348878faaf24 Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Mon, 26 Dec 2022 14:49:20 -0500 Subject: [PATCH 0288/1522] Fix T103453: Don't allow call Attribute Convert operator in edit mode Don't allow calling Attribute Convert operator in edit mode. Right now BMesh does not support attribute operations. Differential Revision: https://developer.blender.org/D16864 --- source/blender/editors/geometry/geometry_attributes.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index 1ffc047fe2c..696397bd12a 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -599,15 +599,22 @@ static bool geometry_color_attribute_convert_poll(bContext *C) return false; } + if (CTX_data_edit_object(C) != nullptr) { + CTX_wm_operator_poll_msg_set(C, "Operation is not allowed in edit mode"); + return false; + } + Object *ob = ED_object_context(C); ID *id = static_cast(ob->data); if (GS(id->name) != ID_ME) { return false; } + CustomDataLayer *layer = BKE_id_attributes_active_color_get(id); if (layer == nullptr) { return false; } + return true; } From 204de8c6db646fd08b393a17a3b25a5de76611e4 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Mon, 26 Dec 2022 21:03:26 -0800 Subject: [PATCH 0289/1522] Sculpt: fix T103156: Scale square brush uvs by sqrt2. Scale texture coordiantes for square brushes by sqrt2, proportionally to how square they are (how close tip_roundness is to zero). Note: this is done in `calc_brush_local_mat()`, the result of which appears to be used exclusively for texture mapping. --- source/blender/editors/sculpt_paint/sculpt.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 9cb30c9f83d..899044145d3 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2908,8 +2908,15 @@ static void calc_brush_local_mat(const MTex *mtex, Object *ob, float local_mat[4 copy_v3_v3(mat[3], cache->location); /* Scale by brush radius. */ + float radius = cache->radius; + + /* Square tips should scale by square root of 2. */ + if (sculpt_tool_has_cube_tip(cache->brush->sculpt_tool)) { + radius += (radius * M_SQRT2 - radius) * (1.0f - cache->brush->tip_roundness); + } + normalize_m4(mat); - scale_m4_fl(scale, cache->radius); + scale_m4_fl(scale, radius); mul_m4_m4m4(tmat, mat, scale); /* Return inverse (for converting from model-space coords to local area coords). */ From a9cb66b856e80d0542a9ad3fec0b0fb47d28f805 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Mon, 26 Dec 2022 21:43:08 -0800 Subject: [PATCH 0290/1522] Sculpt: Fix expand invert mode * Invert mode now properly subtracts from mask * Added an "auto-create" mode to automatically fill in the mask if everything is unmasked. --- .../editors/sculpt_paint/sculpt_expand.c | 48 ++++++++++++++++++- .../editors/sculpt_paint/sculpt_intern.h | 3 ++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index a8496712c41..b90488f6df4 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -1260,7 +1260,12 @@ static void sculpt_expand_mask_update_task_cb(void *__restrict userdata, } if (expand_cache->preserve) { - new_mask = max_ff(new_mask, expand_cache->original_mask[vd.index]); + if (expand_cache->invert) { + new_mask = min_ff(new_mask, expand_cache->original_mask[vd.index]); + } + else { + new_mask = max_ff(new_mask, expand_cache->original_mask[vd.index]); + } } if (new_mask == initial_mask) { @@ -2033,6 +2038,7 @@ static void sculpt_expand_cache_initial_config_set(bContext *C, /* RNA properties. */ expand_cache->invert = RNA_boolean_get(op->ptr, "invert"); expand_cache->preserve = RNA_boolean_get(op->ptr, "use_mask_preserve"); + expand_cache->auto_mask = RNA_boolean_get(op->ptr, "use_auto_mask"); expand_cache->falloff_gradient = RNA_boolean_get(op->ptr, "use_falloff_gradient"); expand_cache->target = RNA_enum_get(op->ptr, "target"); expand_cache->modify_active_face_set = RNA_boolean_get(op->ptr, "use_modify_active"); @@ -2115,6 +2121,41 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even if (ss->expand_cache->target == SCULPT_EXPAND_TARGET_MASK) { MultiresModifierData *mmd = BKE_sculpt_multires_active(ss->scene, ob); BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd); + + if (RNA_boolean_get(op->ptr, "use_auto_mask")) { + int verts_num = SCULPT_vertex_count_get(ss); + bool ok = true; + + for (int i = 0; i < verts_num; i++) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + if (SCULPT_vertex_mask_get(ss, vertex) != 0.0f) { + ok = false; + break; + } + } + + if (ok) { + int nodes_num; + PBVHNode **nodes; + + /* TODO: implement SCULPT_vertex_mask_set and use it here. */ + + BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &nodes_num); + for (int i = 0; i < nodes_num; i++) { + PBVHVertexIter vd; + bool update = false; + + BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[i], vd, PBVH_ITER_UNIQUE) { + *vd.mask = 1.0f; + update = true; + } + BKE_pbvh_vertex_iter_end; + + BKE_pbvh_node_mark_update_mask(nodes[i]); + } + } + } } BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, needs_colors); @@ -2338,4 +2379,9 @@ void SCULPT_OT_expand(wmOperatorType *ot) "than this value, the falloff will be set to spherical when moving", 0, 1000000); + ot->prop = RNA_def_boolean(ot->srna, + "use_auto_mask", + false, + "Auto Create", + "Fill in mask if nothing is already masked."); } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index e660e8fa8ac..ae23983e6c9 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -795,6 +795,9 @@ typedef struct ExpandCache { * after finishing the operation. */ bool reposition_pivot; + /* If nothing is masked set mask of every vertex to 0. */ + bool auto_mask; + /* Color target data type related data. */ float fill_color[4]; short blend_mode; From dce7917717cd9f07466651cdb9659a247f1a19ee Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Mon, 26 Dec 2022 21:46:33 -0800 Subject: [PATCH 0291/1522] Sculpt: Invert Expand behavior for masking consistency This patch makes sure that each of the expand keymap entries will use consistent "invert" and "use_mask_preserve" properties. Based on previous discussions we decided to flip the default Mask Expand behavior. This has multiple benefited: - The mask creation is more consistent with other masking tools (Always add to existing mask. Mask selected areas) - It's easier to use expanding for masking face sets (Snapping with `Ctrl`) or building a mask from repeated operations - It's less likely to mask certain areas unintentionally (Loose mesh islands) - If the current behavior is desired for an expand operation the user can use `E` & `F` in the modal keymap (Which is less often the case). If we want to revisit the original design of inverted masking again in the future we should do this via {T97903}. Reviewed By: Joseph Eagar Differential Revision https://developer.blender.org/D16434 Ref D16434 --- .../keyconfig/keymap_data/blender_default.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 7712f75fc64..d9e17302177 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5049,20 +5049,31 @@ def km_sculpt(params): {"properties": [("mode", 'SMOOTH')]}), # Expand ("sculpt.expand", {"type": 'A', "value": 'PRESS', "shift": True}, - {"properties": [("target", "MASK"), ("falloff_type", "GEODESIC"), ("invert", True)]}), + {"properties": [ + ("target", "MASK"), + ("falloff_type", "GEODESIC"), + ("invert", True), + ("use_auto_mask", True), + ("use_mask_preserve" , True)]}), ("sculpt.expand", {"type": 'A', "value": 'PRESS', "shift": True, "alt": True}, - {"properties": [("target", "MASK"), ("falloff_type", "NORMALS"), ("invert", False)]}), + {"properties": [ + ("target", "MASK"), + ("falloff_type", "NORMALS"), + ("invert", False), + ("use_mask_preserve" , True)]}), ("sculpt.expand", {"type": 'W', "value": 'PRESS', "shift": True}, {"properties": [ ("target", "FACE_SETS"), ("falloff_type", "GEODESIC"), ("invert", False), + ("use_mask_preserve" , False), ("use_modify_active", False)]}), ("sculpt.expand", {"type": 'W', "value": 'PRESS', "shift": True, "alt": True}, {"properties": [ ("target", "FACE_SETS"), ("falloff_type", "BOUNDARY_FACE_SET"), ("invert", False), + ("use_mask_preserve" , False), ("use_modify_active", True), ]}), # Partial Visibility Show/hide From 3adbe82e079c0c07425fddf4c0fffc50feb2645f Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Tue, 27 Dec 2022 10:01:37 +0100 Subject: [PATCH 0292/1522] GPencil: Extract function to calculate cursor size This function will be used in other areas of Blender. --- .../blender/editors/gpencil/gpencil_utils.c | 78 ++++++++++++------- source/blender/editors/include/ED_gpencil.h | 5 ++ 2 files changed, 56 insertions(+), 27 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 9f6b17b66e2..f8e2a8fd080 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -1730,6 +1730,56 @@ static bool gpencil_brush_cursor_poll(bContext *C) return false; } +float ED_gpencil_cursor_radius(bContext *C, int x, int y) +{ + Scene *scene = CTX_data_scene(C); + Object *ob = CTX_data_active_object(C); + ARegion *region = CTX_wm_region(C); + Brush *brush = brush = scene->toolsettings->gp_paint->paint.brush; + bGPdata *gpd = ED_gpencil_data_get_active(C); + + /* Show brush size. */ + tGPspoint point2D; + float p1[3]; + float p2[3]; + float distance; + float radius = 2.0f; + + if (ELEM(NULL, gpd, brush)) { + return radius; + } + + /* Strokes in screen space or world space? */ + if ((gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS) != 0) { + /* In screen space the cursor radius matches the brush size. */ + radius = (float)brush->size * 0.5f; + } + else { + /* To calculate the brush size in world space, we have to establish the zoom level. + * For this we take two 2D screen coordinates with a fixed offset, + * convert them to 3D coordinates and measure the offset distance in 3D. + * A small distance means a high zoom level. */ + point2D.m_xy[0] = (float)x; + point2D.m_xy[1] = (float)y; + gpencil_stroke_convertcoords_tpoint(scene, region, ob, &point2D, NULL, p1); + point2D.m_xy[0] = (float)(x + 64); + gpencil_stroke_convertcoords_tpoint(scene, region, ob, &point2D, NULL, p2); + /* Clip extreme zoom level (and avoid division by zero). */ + distance = MAX2(len_v3v3(p1, p2), 0.001f); + + /* Handle layer thickness change. */ + float brush_size = (float)brush->size; + bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd); + if (gpl != NULL) { + brush_size = MAX2(1.0f, brush_size + gpl->line_change); + } + + /* Convert the 3D offset distance to a brush radius. */ + radius = (1 / distance) * 2.0f * gpd->pixfactor * (brush_size / 64); + } + return radius; +} + /** * Helper callback for drawing the cursor itself. */ @@ -1813,39 +1863,13 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat copy_v3_v3(color, is_vertex_stroke ? brush->rgb : gp_style->stroke_rgba); } else { - /* Show brush size. */ - tGPspoint point2D; - float p1[3]; - float p2[3]; - float distance; - /* Strokes in screen space or world space? */ if ((gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS) != 0) { /* In screen space the cursor radius matches the brush size. */ radius = (float)brush->size * 0.5f; } else { - /* To calculate the brush size in world space, we have to establish the zoom level. - * For this we take two 2D screen coordinates with a fixed offset, - * convert them to 3D coordinates and measure the offset distance in 3D. - * A small distance means a high zoom level. */ - point2D.m_xy[0] = (float)x; - point2D.m_xy[1] = (float)y; - gpencil_stroke_convertcoords_tpoint(scene, region, ob, &point2D, NULL, p1); - point2D.m_xy[0] = (float)(x + 64); - gpencil_stroke_convertcoords_tpoint(scene, region, ob, &point2D, NULL, p2); - /* Clip extreme zoom level (and avoid division by zero). */ - distance = MAX2(len_v3v3(p1, p2), 0.001f); - - /* Handle layer thickness change. */ - float brush_size = (float)brush->size; - bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd); - if (gpl != NULL) { - brush_size = MAX2(1.0f, brush_size + gpl->line_change); - } - - /* Convert the 3D offset distance to a brush radius. */ - radius = (1 / distance) * 2.0f * gpd->pixfactor * (brush_size / 64); + radius = ED_gpencil_cursor_radius(C, x, y); } copy_v3_v3(color, is_vertex_stroke ? brush->rgb : gp_style->stroke_rgba); diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 45e61592424..129229a8861 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -641,6 +641,11 @@ struct bGPDstroke *ED_gpencil_stroke_join_and_trim(struct bGPdata *gpd, */ void ED_gpencil_stroke_close_by_distance(struct bGPDstroke *gps, float threshold); +/** + * Calculate the brush cursor size in world space. + */ +float ED_gpencil_cursor_radius(struct bContext *C, int x, int y); + #ifdef __cplusplus } #endif From a2cf9a8647fda2b9b2e51e23c04f0b1e74922bbc Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Tue, 27 Dec 2022 10:25:54 +0100 Subject: [PATCH 0293/1522] GPencil: Display real brush cursor size always Remove the option to display the real size of the cursor and set as default. Now the cursor is displayed or not using show_cursor option, but if it's displayed always use the real size. --- .../bl_ui/properties_grease_pencil_common.py | 3 -- .../blender/editors/gpencil/gpencil_utils.c | 35 +++++-------------- source/blender/makesdna/DNA_brush_enums.h | 2 -- source/blender/makesrna/intern/rna_brush.c | 6 ---- 4 files changed, 8 insertions(+), 38 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 1e68b2df97d..a3a69835a19 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -118,9 +118,6 @@ class GreasePencilDisplayPanel: row.prop(settings, "show_brush", text="Display Cursor") if brush.gpencil_tool == 'DRAW': - row = layout.row(align=True) - row.active = settings.show_brush - row.prop(gp_settings, "show_brush_size", text="Show Brush Size") row = layout.row(align=True) row.active = settings.show_brush row.prop(gp_settings, "show_lasso", text="Show Fill Color While Drawing") diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index f8e2a8fd080..e378c35516e 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -1801,7 +1801,6 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat float color[3] = {1.0f, 1.0f, 1.0f}; float darkcolor[3]; float radius = 3.0f; - bool fixed_radius = true; const int mval_i[2] = {x, y}; /* Check if cursor is in drawing region and has valid data-block. */ @@ -1848,32 +1847,22 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat ((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) && (brush->gpencil_tool == GPAINT_TOOL_DRAW)) { - /* Check user setting for cursor size. */ - fixed_radius = ((brush->gpencil_settings->flag & GP_BRUSH_SHOW_DRAW_SIZE) == 0); - const bool is_vertex_stroke = (GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) && (brush->gpencil_settings->brush_draw_mode != GP_BRUSH_MODE_MATERIAL)) || (!GPENCIL_USE_VERTEX_COLOR_STROKE(ts, brush) && (brush->gpencil_settings->brush_draw_mode == GP_BRUSH_MODE_VERTEXCOLOR)); - if (fixed_radius) { - /* Show fixed radius. */ - radius = 2.0f; - copy_v3_v3(color, is_vertex_stroke ? brush->rgb : gp_style->stroke_rgba); + /* Strokes in screen space or world space? */ + if ((gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS) != 0) { + /* In screen space the cursor radius matches the brush size. */ + radius = (float)brush->size * 0.5f; } else { - /* Strokes in screen space or world space? */ - if ((gpd->flag & GP_DATA_STROKE_KEEPTHICKNESS) != 0) { - /* In screen space the cursor radius matches the brush size. */ - radius = (float)brush->size * 0.5f; - } - else { - radius = ED_gpencil_cursor_radius(C, x, y); - } - - copy_v3_v3(color, is_vertex_stroke ? brush->rgb : gp_style->stroke_rgba); + radius = ED_gpencil_cursor_radius(C, x, y); } + + copy_v3_v3(color, is_vertex_stroke ? brush->rgb : gp_style->stroke_rgba); } else { /* Only Tint tool must show big cursor. */ @@ -1953,15 +1942,7 @@ static void gpencil_brush_cursor_draw(bContext *C, int x, int y, void *customdat /* Inner Ring: Color from UI panel */ immUniformColor4f(color[0], color[1], color[2], 0.8f); - if ((gp_style) && GPENCIL_PAINT_MODE(gpd) && (fixed_radius) && - ((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE) == 0) && - ((brush->gpencil_settings->flag & GP_BRUSH_STABILIZE_MOUSE_TEMP) == 0) && - (brush->gpencil_tool == GPAINT_TOOL_DRAW)) { - imm_draw_circle_fill_2d(pos, x, y, radius, 40); - } - else { - imm_draw_circle_wire_2d(pos, x, y, radius, 40); - } + imm_draw_circle_wire_2d(pos, x, y, radius, 40); /* Outer Ring: Dark color for contrast on light backgrounds (e.g. gray on white) */ mul_v3_v3fl(darkcolor, color, 0.40f); diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h index ce90a8e05c1..72357ea6734 100644 --- a/source/blender/makesdna/DNA_brush_enums.h +++ b/source/blender/makesdna/DNA_brush_enums.h @@ -91,8 +91,6 @@ typedef enum eGPDbrush_Flag { GP_BRUSH_OUTLINE_STROKE = (1 << 17), /* Collide with stroke. */ GP_BRUSH_FILL_STROKE_COLLIDE = (1 << 18), - /* Show brush size */ - GP_BRUSH_SHOW_DRAW_SIZE = (1 << 19), } eGPDbrush_Flag; typedef enum eGPDbrush_Flag2 { diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 1d2adc386cf..ce51b52de39 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -2005,12 +2005,6 @@ static void rna_def_gpencil_options(BlenderRNA *brna) prop, "Show Lasso", "Do not display fill color while drawing the stroke"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - prop = RNA_def_property(srna, "show_brush_size", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_SHOW_DRAW_SIZE); - RNA_def_property_boolean_default(prop, true); - RNA_def_property_ui_text(prop, "Show Brush Size", "Show the real size of the draw brush"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - prop = RNA_def_property(srna, "use_occlude_eraser", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BRUSH_OCCLUDE_ERASER); RNA_def_property_ui_text(prop, "Occlude Eraser", "Erase only strokes visible and not occluded"); From b6a11ae7d59acd17c56e2d46eaab928bdce3d984 Mon Sep 17 00:00:00 2001 From: Pratik Borhade Date: Tue, 27 Dec 2022 15:40:13 +0530 Subject: [PATCH 0294/1522] Cleanup: Warning in debug console due to full stop in description Fix warning generated due to the full-stop in the description message of the property `use_auto_mask` Property added in: rBa9cb66b856e80d0542a9ad3fec0b0fb47d28f805 --- source/blender/editors/sculpt_paint/sculpt_expand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index b90488f6df4..1a9abb04ba8 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -2383,5 +2383,5 @@ void SCULPT_OT_expand(wmOperatorType *ot) "use_auto_mask", false, "Auto Create", - "Fill in mask if nothing is already masked."); + "Fill in mask if nothing is already masked"); } From 87594726abb3090e228aef4cf3b7cfc5fef5182f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 27 Dec 2022 10:31:40 -0500 Subject: [PATCH 0295/1522] Cleanup: Improve documentation in Curves DNA header --- source/blender/makesdna/DNA_curves_types.h | 25 ++++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/source/blender/makesdna/DNA_curves_types.h b/source/blender/makesdna/DNA_curves_types.h index fea994e2739..5ecc816f4ea 100644 --- a/source/blender/makesdna/DNA_curves_types.h +++ b/source/blender/makesdna/DNA_curves_types.h @@ -78,17 +78,23 @@ typedef enum KnotsMode { /** Method used to calculate the normals of a curve's evaluated points. */ typedef enum NormalMode { + /** Calculate normals with the smallest twist around the curve tangent across the whole curve. */ NORMAL_MODE_MINIMUM_TWIST = 0, + /** + * Calculate normals perpendicular to the Z axis and the curve tangent. If a series of points + * is vertical, the X axis is used. + */ NORMAL_MODE_Z_UP = 1, } NormalMode; /** * A reusable data structure for geometry consisting of many curves. All control point data is - * stored contiguously for better efficiency. Data for each curve is stored as a slice of the - * main #point_data array. + * stored contiguously for better efficiency when there are many curves. Multiple curve types are + * supported, as described in #CurveType. Data for each curve is accessed by slicing the main + * #point_data arrays. * * The data structure is meant to separate geometry data storage and processing from Blender - * focussed ID data-block handling. The struct can also be embedded to allow reusing it. + * focused ID data-block handling. The struct can also be embedded to allow reusing it. */ typedef struct CurvesGeometry { /** @@ -120,7 +126,7 @@ typedef struct CurvesGeometry { */ int point_num; /** - * The number of curves in the data-block. + * The number of curves. */ int curve_num; @@ -130,6 +136,11 @@ typedef struct CurvesGeometry { CurvesGeometryRuntimeHandle *runtime; } CurvesGeometry; +/** + * A data-block corresponding to a number of curves of various types with various attributes. + * Geometry data (as opposed to pointers to other data-blocks and higher level data for user + * interaction) is embedded in the #CurvesGeometry struct. + */ typedef struct Curves { ID id; /** Animation data (must be immediately after #id). */ @@ -151,8 +162,8 @@ typedef struct Curves { */ char symmetry; /** - * #eAttrDomain. The active selection mode domain. At most one selection mode can be active - * at a time. + * #eAttrDomain. The active domain for edit/sculpt mode selection. Only one selection mode can + * be active at a time. */ char selection_domain; char _pad[4]; @@ -168,7 +179,7 @@ typedef struct Curves { /** * The name of the attribute on the surface #Mesh used to give meaning to the UV attachment - * coordinates stored on each curve. Expected to be a 2D vector attribute on the face corner + * coordinates stored for each curve. Expected to be a 2D vector attribute on the face corner * domain. */ char *surface_uv_map; From 6aad3c7297aff43d623623bbf5fadc3ba8570871 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Tue, 27 Dec 2022 16:45:09 +0100 Subject: [PATCH 0296/1522] GPencil: Show Display Cursor popover for Eraser The Eraser tool was not showing the display cursor popover. This commit fixes this inconsistency. --- .../startup/bl_ui/properties_grease_pencil_common.py | 7 ++----- .../scripts/startup/bl_ui/properties_paint_common.py | 3 --- release/scripts/startup/bl_ui/space_view3d.py | 11 ++++++----- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index a3a69835a19..3b8da6d0e8d 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -69,11 +69,8 @@ class GreasePencilDisplayPanel: ob = context.active_object brush = context.tool_settings.gpencil_paint.brush if ob and ob.type == 'GPENCIL' and brush: - if context.mode == 'PAINT_GPENCIL': - return brush.gpencil_tool != 'ERASE' - else: - # GP Sculpt, Vertex and Weight Paint always have Brush Tip panel. - return True + return True + return False def draw_header(self, context): diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 6c060d57a6b..c912de8f3e4 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -1287,9 +1287,6 @@ def brush_basic_gpencil_paint_settings(layout, context, brush, *, compact=False) row = layout.row(align=True) row.prop(gp_settings, "eraser_thickness_factor") - row = layout.row(align=True) - row.prop(settings, "show_brush", text="Display Cursor") - # FIXME: tools must use their own UI drawing! elif brush.gpencil_tool == 'FILL': use_property_split_prev = layout.use_property_split diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 0eba15e4267..311fe6076db 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -99,12 +99,13 @@ class VIEW3D_HT_tool_header(Header): elif tool_mode == 'PAINT_GPENCIL': if is_valid_context: brush = context.tool_settings.gpencil_paint.brush - if brush and brush.gpencil_tool != 'ERASE': - if brush.gpencil_tool != 'TINT': - layout.popover("VIEW3D_PT_tools_grease_pencil_brush_advanced") + if brush: + if brush.gpencil_tool != 'ERASE': + if brush.gpencil_tool != 'TINT': + layout.popover("VIEW3D_PT_tools_grease_pencil_brush_advanced") - if brush.gpencil_tool not in {'FILL', 'TINT'}: - layout.popover("VIEW3D_PT_tools_grease_pencil_brush_stroke") + if brush.gpencil_tool not in {'FILL', 'TINT'}: + layout.popover("VIEW3D_PT_tools_grease_pencil_brush_stroke") layout.popover("VIEW3D_PT_tools_grease_pencil_paint_appearance") elif tool_mode == 'SCULPT_GPENCIL': From d7dad425c0d0c95ac35b4bf705b2ea6e8dc69eb2 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 27 Dec 2022 11:50:17 -0500 Subject: [PATCH 0297/1522] Nodes: Make socket declaration member variables public This is the best way I found to make building socket declarations without the builder helper class work. Besides a vague hope for non-leaky abstractions, I don't think there's any reason for these fields not to be accessible directly. Ref D16850 --- .../blender/nodes/NOD_socket_declarations.hh | 87 +++++++++---------- .../nodes/intern/node_socket_declarations.cc | 78 ++++++++--------- 2 files changed, 79 insertions(+), 86 deletions(-) diff --git a/source/blender/nodes/NOD_socket_declarations.hh b/source/blender/nodes/NOD_socket_declarations.hh index 503327ac4da..f3a9ba25ca1 100644 --- a/source/blender/nodes/NOD_socket_declarations.hh +++ b/source/blender/nodes/NOD_socket_declarations.hh @@ -14,15 +14,14 @@ namespace blender::nodes::decl { class FloatBuilder; class Float : public SocketDeclaration { - private: - float default_value_ = 0.0f; - float soft_min_value_ = -FLT_MAX; - float soft_max_value_ = FLT_MAX; - PropertySubType subtype_ = PROP_NONE; + public: + float default_value = 0.0f; + float soft_min_value = -FLT_MAX; + float soft_max_value = FLT_MAX; + PropertySubType subtype = PROP_NONE; friend FloatBuilder; - public: using Builder = FloatBuilder; bNodeSocket &build(bNodeTree &ntree, bNode &node) const override; @@ -42,15 +41,14 @@ class FloatBuilder : public SocketDeclarationBuilder { class IntBuilder; class Int : public SocketDeclaration { - private: - int default_value_ = 0; - int soft_min_value_ = INT32_MIN; - int soft_max_value_ = INT32_MAX; - PropertySubType subtype_ = PROP_NONE; + public: + int default_value = 0; + int soft_min_value = INT32_MIN; + int soft_max_value = INT32_MAX; + PropertySubType subtype = PROP_NONE; friend IntBuilder; - public: using Builder = IntBuilder; bNodeSocket &build(bNodeTree &ntree, bNode &node) const override; @@ -70,15 +68,14 @@ class IntBuilder : public SocketDeclarationBuilder { class VectorBuilder; class Vector : public SocketDeclaration { - private: - float3 default_value_ = {0, 0, 0}; - float soft_min_value_ = -FLT_MAX; - float soft_max_value_ = FLT_MAX; - PropertySubType subtype_ = PROP_NONE; + public: + float3 default_value = {0, 0, 0}; + float soft_min_value = -FLT_MAX; + float soft_max_value = FLT_MAX; + PropertySubType subtype = PROP_NONE; friend VectorBuilder; - public: using Builder = VectorBuilder; bNodeSocket &build(bNodeTree &ntree, bNode &node) const override; @@ -99,11 +96,10 @@ class VectorBuilder : public SocketDeclarationBuilder { class BoolBuilder; class Bool : public SocketDeclaration { - private: - bool default_value_ = false; + public: + bool default_value = false; friend BoolBuilder; - public: using Builder = BoolBuilder; bNodeSocket &build(bNodeTree &ntree, bNode &node) const override; @@ -119,12 +115,11 @@ class BoolBuilder : public SocketDeclarationBuilder { class ColorBuilder; class Color : public SocketDeclaration { - private: - ColorGeometry4f default_value_; + public: + ColorGeometry4f default_value; friend ColorBuilder; - public: using Builder = ColorBuilder; bNodeSocket &build(bNodeTree &ntree, bNode &node) const override; @@ -140,12 +135,11 @@ class ColorBuilder : public SocketDeclarationBuilder { class StringBuilder; class String : public SocketDeclaration { - private: - std::string default_value_; + public: + std::string default_value; friend StringBuilder; - public: using Builder = StringBuilder; bNodeSocket &build(bNodeTree &ntree, bNode &node) const override; @@ -159,8 +153,8 @@ class StringBuilder : public SocketDeclarationBuilder { }; class IDSocketDeclaration : public SocketDeclaration { - private: - const char *idname_; + public: + const char *idname; public: IDSocketDeclaration(const char *idname); @@ -209,10 +203,9 @@ class Image : public IDSocketDeclaration { class ShaderBuilder; class Shader : public SocketDeclaration { - private: + public: friend ShaderBuilder; - public: using Builder = ShaderBuilder; bNodeSocket &build(bNodeTree &ntree, bNode &node) const override; @@ -229,25 +222,25 @@ class ShaderBuilder : public SocketDeclarationBuilder { inline FloatBuilder &FloatBuilder::min(const float value) { - decl_->soft_min_value_ = value; + decl_->soft_min_value = value; return *this; } inline FloatBuilder &FloatBuilder::max(const float value) { - decl_->soft_max_value_ = value; + decl_->soft_max_value = value; return *this; } inline FloatBuilder &FloatBuilder::default_value(const float value) { - decl_->default_value_ = value; + decl_->default_value = value; return *this; } inline FloatBuilder &FloatBuilder::subtype(PropertySubType subtype) { - decl_->subtype_ = subtype; + decl_->subtype = subtype; return *this; } @@ -259,25 +252,25 @@ inline FloatBuilder &FloatBuilder::subtype(PropertySubType subtype) inline IntBuilder &IntBuilder::min(const int value) { - decl_->soft_min_value_ = value; + decl_->soft_min_value = value; return *this; } inline IntBuilder &IntBuilder::max(const int value) { - decl_->soft_max_value_ = value; + decl_->soft_max_value = value; return *this; } inline IntBuilder &IntBuilder::default_value(const int value) { - decl_->default_value_ = value; + decl_->default_value = value; return *this; } inline IntBuilder &IntBuilder::subtype(PropertySubType subtype) { - decl_->subtype_ = subtype; + decl_->subtype = subtype; return *this; } @@ -289,25 +282,25 @@ inline IntBuilder &IntBuilder::subtype(PropertySubType subtype) inline VectorBuilder &VectorBuilder::default_value(const float3 value) { - decl_->default_value_ = value; + decl_->default_value = value; return *this; } inline VectorBuilder &VectorBuilder::subtype(PropertySubType subtype) { - decl_->subtype_ = subtype; + decl_->subtype = subtype; return *this; } inline VectorBuilder &VectorBuilder::min(const float min) { - decl_->soft_min_value_ = min; + decl_->soft_min_value = min; return *this; } inline VectorBuilder &VectorBuilder::max(const float max) { - decl_->soft_max_value_ = max; + decl_->soft_max_value = max; return *this; } @@ -325,7 +318,7 @@ inline VectorBuilder &VectorBuilder::compact() inline BoolBuilder &BoolBuilder::default_value(const bool value) { - decl_->default_value_ = value; + decl_->default_value = value; return *this; } @@ -337,7 +330,7 @@ inline BoolBuilder &BoolBuilder::default_value(const bool value) inline ColorBuilder &ColorBuilder::default_value(const ColorGeometry4f value) { - decl_->default_value_ = value; + decl_->default_value = value; return *this; } @@ -349,7 +342,7 @@ inline ColorBuilder &ColorBuilder::default_value(const ColorGeometry4f value) inline StringBuilder &StringBuilder::default_value(std::string value) { - decl_->default_value_ = std::move(value); + decl_->default_value = std::move(value); return *this; } @@ -359,7 +352,7 @@ inline StringBuilder &StringBuilder::default_value(std::string value) /** \name #IDSocketDeclaration and Children Inline Methods * \{ */ -inline IDSocketDeclaration::IDSocketDeclaration(const char *idname) : idname_(idname) +inline IDSocketDeclaration::IDSocketDeclaration(const char *idname) : idname(idname) { } diff --git a/source/blender/nodes/intern/node_socket_declarations.cc b/source/blender/nodes/intern/node_socket_declarations.cc index a7d281bcf52..44f02822ee1 100644 --- a/source/blender/nodes/intern/node_socket_declarations.cc +++ b/source/blender/nodes/intern/node_socket_declarations.cc @@ -71,12 +71,12 @@ static void modify_subtype_except_for_storage(bNodeSocket &socket, int new_subty bNodeSocket &Float::build(bNodeTree &ntree, bNode &node) const { bNodeSocket &socket = *nodeAddStaticSocket( - &ntree, &node, in_out_, SOCK_FLOAT, subtype_, identifier_.c_str(), name_.c_str()); + &ntree, &node, in_out_, SOCK_FLOAT, this->subtype, identifier_.c_str(), name_.c_str()); this->set_common_flags(socket); bNodeSocketValueFloat &value = *(bNodeSocketValueFloat *)socket.default_value; - value.min = soft_min_value_; - value.max = soft_max_value_; - value.value = default_value_; + value.min = this->soft_min_value; + value.max = this->soft_max_value; + value.value = this->default_value; return socket; } @@ -88,14 +88,14 @@ bool Float::matches(const bNodeSocket &socket) const if (socket.type != SOCK_FLOAT) { return false; } - if (socket.typeinfo->subtype != subtype_) { + if (socket.typeinfo->subtype != this->subtype) { return false; } bNodeSocketValueFloat &value = *(bNodeSocketValueFloat *)socket.default_value; - if (value.min != soft_min_value_) { + if (value.min != this->soft_min_value) { return false; } - if (value.max != soft_max_value_) { + if (value.max != this->soft_max_value) { return false; } return true; @@ -115,14 +115,14 @@ bNodeSocket &Float::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket & BLI_assert(socket.in_out == in_out_); return this->build(ntree, node); } - if (socket.typeinfo->subtype != subtype_) { - modify_subtype_except_for_storage(socket, subtype_); + if (socket.typeinfo->subtype != this->subtype) { + modify_subtype_except_for_storage(socket, this->subtype); } this->set_common_flags(socket); bNodeSocketValueFloat &value = *(bNodeSocketValueFloat *)socket.default_value; - value.min = soft_min_value_; - value.max = soft_max_value_; - value.subtype = subtype_; + value.min = this->soft_min_value; + value.max = this->soft_max_value; + value.subtype = this->subtype; return socket; } @@ -135,12 +135,12 @@ bNodeSocket &Float::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket & bNodeSocket &Int::build(bNodeTree &ntree, bNode &node) const { bNodeSocket &socket = *nodeAddStaticSocket( - &ntree, &node, in_out_, SOCK_INT, subtype_, identifier_.c_str(), name_.c_str()); + &ntree, &node, in_out_, SOCK_INT, this->subtype, identifier_.c_str(), name_.c_str()); this->set_common_flags(socket); bNodeSocketValueInt &value = *(bNodeSocketValueInt *)socket.default_value; - value.min = soft_min_value_; - value.max = soft_max_value_; - value.value = default_value_; + value.min = this->soft_min_value; + value.max = this->soft_max_value; + value.value = this->default_value; return socket; } @@ -152,14 +152,14 @@ bool Int::matches(const bNodeSocket &socket) const if (socket.type != SOCK_INT) { return false; } - if (socket.typeinfo->subtype != subtype_) { + if (socket.typeinfo->subtype != this->subtype) { return false; } bNodeSocketValueInt &value = *(bNodeSocketValueInt *)socket.default_value; - if (value.min != soft_min_value_) { + if (value.min != this->soft_min_value) { return false; } - if (value.max != soft_max_value_) { + if (value.max != this->soft_max_value) { return false; } return true; @@ -179,14 +179,14 @@ bNodeSocket &Int::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &so BLI_assert(socket.in_out == in_out_); return this->build(ntree, node); } - if (socket.typeinfo->subtype != subtype_) { - modify_subtype_except_for_storage(socket, subtype_); + if (socket.typeinfo->subtype != this->subtype) { + modify_subtype_except_for_storage(socket, this->subtype); } this->set_common_flags(socket); bNodeSocketValueInt &value = *(bNodeSocketValueInt *)socket.default_value; - value.min = soft_min_value_; - value.max = soft_max_value_; - value.subtype = subtype_; + value.min = this->soft_min_value; + value.max = this->soft_max_value; + value.subtype = this->subtype; return socket; } @@ -199,12 +199,12 @@ bNodeSocket &Int::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &so bNodeSocket &Vector::build(bNodeTree &ntree, bNode &node) const { bNodeSocket &socket = *nodeAddStaticSocket( - &ntree, &node, in_out_, SOCK_VECTOR, subtype_, identifier_.c_str(), name_.c_str()); + &ntree, &node, in_out_, SOCK_VECTOR, this->subtype, identifier_.c_str(), name_.c_str()); this->set_common_flags(socket); bNodeSocketValueVector &value = *(bNodeSocketValueVector *)socket.default_value; - copy_v3_v3(value.value, default_value_); - value.min = soft_min_value_; - value.max = soft_max_value_; + copy_v3_v3(value.value, this->default_value); + value.min = this->soft_min_value; + value.max = this->soft_max_value; return socket; } @@ -216,7 +216,7 @@ bool Vector::matches(const bNodeSocket &socket) const if (socket.type != SOCK_VECTOR) { return false; } - if (socket.typeinfo->subtype != subtype_) { + if (socket.typeinfo->subtype != this->subtype) { return false; } return true; @@ -236,12 +236,12 @@ bNodeSocket &Vector::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket BLI_assert(socket.in_out == in_out_); return this->build(ntree, node); } - if (socket.typeinfo->subtype != subtype_) { - modify_subtype_except_for_storage(socket, subtype_); + if (socket.typeinfo->subtype != this->subtype) { + modify_subtype_except_for_storage(socket, this->subtype); } this->set_common_flags(socket); bNodeSocketValueVector &value = *(bNodeSocketValueVector *)socket.default_value; - value.subtype = subtype_; + value.subtype = this->subtype; STRNCPY(socket.name, name_.c_str()); return socket; } @@ -258,7 +258,7 @@ bNodeSocket &Bool::build(bNodeTree &ntree, bNode &node) const &ntree, &node, in_out_, SOCK_BOOLEAN, PROP_NONE, identifier_.c_str(), name_.c_str()); this->set_common_flags(socket); bNodeSocketValueBoolean &value = *(bNodeSocketValueBoolean *)socket.default_value; - value.value = default_value_; + value.value = this->default_value; return socket; } @@ -293,7 +293,7 @@ bNodeSocket &Color::build(bNodeTree &ntree, bNode &node) const &ntree, &node, in_out_, SOCK_RGBA, PROP_NONE, identifier_.c_str(), name_.c_str()); this->set_common_flags(socket); bNodeSocketValueRGBA &value = *(bNodeSocketValueRGBA *)socket.default_value; - copy_v4_v4(value.value, default_value_); + copy_v4_v4(value.value, this->default_value); return socket; } @@ -331,7 +331,7 @@ bNodeSocket &String::build(bNodeTree &ntree, bNode &node) const { bNodeSocket &socket = *nodeAddStaticSocket( &ntree, &node, in_out_, SOCK_STRING, PROP_NONE, identifier_.c_str(), name_.c_str()); - STRNCPY(((bNodeSocketValueString *)socket.default_value)->value, default_value_.c_str()); + STRNCPY(((bNodeSocketValueString *)socket.default_value)->value, this->default_value.c_str()); this->set_common_flags(socket); return socket; } @@ -361,7 +361,7 @@ bool String::can_connect(const bNodeSocket &socket) const bNodeSocket &IDSocketDeclaration::build(bNodeTree &ntree, bNode &node) const { bNodeSocket &socket = *nodeAddSocket( - &ntree, &node, in_out_, idname_, identifier_.c_str(), name_.c_str()); + &ntree, &node, in_out_, this->idname, identifier_.c_str(), name_.c_str()); this->set_common_flags(socket); return socket; } @@ -371,7 +371,7 @@ bool IDSocketDeclaration::matches(const bNodeSocket &socket) const if (!this->matches_common_data(socket)) { return false; } - if (!STREQ(socket.idname, idname_)) { + if (!STREQ(socket.idname, this->idname)) { return false; } return true; @@ -379,14 +379,14 @@ bool IDSocketDeclaration::matches(const bNodeSocket &socket) const bool IDSocketDeclaration::can_connect(const bNodeSocket &socket) const { - return sockets_can_connect(*this, socket) && STREQ(socket.idname, idname_); + return sockets_can_connect(*this, socket) && STREQ(socket.idname, this->idname); } bNodeSocket &IDSocketDeclaration::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const { - if (StringRef(socket.idname) != idname_) { + if (StringRef(socket.idname) != this->idname) { BLI_assert(socket.in_out == in_out_); return this->build(ntree, node); } From 8c6fe60844f2f970c46500efa27fe9755b91b76d Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 28 Dec 2022 20:15:41 -0500 Subject: [PATCH 0298/1522] Cleanup: Use const parameters for node poll functions This requires a const cast in RNA, but it really is wrong to change the nodes and node trees in these callbacks. --- source/blender/blenkernel/BKE_node.h | 8 +++++--- source/blender/blenkernel/intern/node.cc | 8 +++++--- source/blender/makesrna/intern/rna_nodetree.c | 14 ++++++++------ .../blender/nodes/composite/node_composite_util.cc | 4 +++- .../blender/nodes/composite/node_composite_util.hh | 4 ++-- .../composite/nodes/node_composite_cryptomatte.cc | 4 ++-- .../nodes/composite/nodes/node_composite_image.cc | 4 ++-- .../blender/nodes/function/node_function_util.cc | 4 ++-- .../blender/nodes/geometry/node_geometry_util.cc | 4 +++- .../blender/nodes/geometry/node_geometry_util.hh | 4 ++-- source/blender/nodes/intern/node_common.cc | 6 ++++-- source/blender/nodes/intern/node_common.h | 4 ++-- source/blender/nodes/intern/node_register.cc | 4 ++-- source/blender/nodes/shader/node_shader_util.cc | 8 +++++--- source/blender/nodes/shader/node_shader_util.hh | 4 ++-- source/blender/nodes/texture/node_texture_util.cc | 2 +- source/blender/nodes/texture/node_texture_util.hh | 4 ++-- 17 files changed, 52 insertions(+), 38 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index ff1128246f3..d247ee5eea0 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -299,12 +299,14 @@ typedef struct bNodeType { * when it's not just a dummy, that is, if it actually wants to access * the returned disabled-hint (null-check needed!). */ - bool (*poll)(struct bNodeType *ntype, struct bNodeTree *nodetree, const char **r_disabled_hint); + bool (*poll)(const struct bNodeType *ntype, + const struct bNodeTree *nodetree, + const char **r_disabled_hint); /** Can this node be added to a node tree? * \param r_disabled_hint: See `poll()`. */ - bool (*poll_instance)(struct bNode *node, - struct bNodeTree *nodetree, + bool (*poll_instance)(const struct bNode *node, + const struct bNodeTree *nodetree, const char **r_disabled_hint); /* optional handling of link insertion */ diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 9fc2cbde1d5..097d14ae7b9 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -4034,14 +4034,16 @@ static void node_type_base_defaults(bNodeType *ntype) } /* allow this node for any tree type */ -static bool node_poll_default(bNodeType * /*ntype*/, - bNodeTree * /*ntree*/, +static bool node_poll_default(const bNodeType * /*ntype*/, + const bNodeTree * /*ntree*/, const char ** /*disabled_hint*/) { return true; } -static bool node_poll_instance_default(bNode *node, bNodeTree *ntree, const char **disabled_hint) +static bool node_poll_instance_default(const bNode *node, + const bNodeTree *ntree, + const char **disabled_hint) { return node->typeinfo->poll(node->typeinfo, ntree, disabled_hint); } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index fbc13229a3d..aa42e9422e2 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1659,7 +1659,9 @@ char *rna_Node_ImageUser_path(const PointerRNA *ptr) return NULL; } -static bool rna_Node_poll(bNodeType *ntype, bNodeTree *ntree, const char **UNUSED(r_disabled_hint)) +static bool rna_Node_poll(const bNodeType *ntype, + const bNodeTree *ntree, + const char **UNUSED(r_disabled_hint)) { extern FunctionRNA rna_Node_poll_func; @@ -1684,8 +1686,8 @@ static bool rna_Node_poll(bNodeType *ntype, bNodeTree *ntree, const char **UNUSE return visible; } -static bool rna_Node_poll_instance(bNode *node, - bNodeTree *ntree, +static bool rna_Node_poll_instance(const bNode *node, + const bNodeTree *ntree, const char **UNUSED(disabled_info)) { extern FunctionRNA rna_Node_poll_instance_func; @@ -1696,7 +1698,7 @@ static bool rna_Node_poll_instance(bNode *node, void *ret; bool visible; - RNA_pointer_create(NULL, node->typeinfo->rna_ext.srna, node, &ptr); /* dummy */ + RNA_pointer_create(NULL, node->typeinfo->rna_ext.srna, (bNode *)node, &ptr); /* dummy */ func = &rna_Node_poll_instance_func; /* RNA_struct_find_function(&ptr, "poll_instance"); */ RNA_parameter_list_create(&list, &ptr, func); @@ -1711,8 +1713,8 @@ static bool rna_Node_poll_instance(bNode *node, return visible; } -static bool rna_Node_poll_instance_default(bNode *node, - bNodeTree *ntree, +static bool rna_Node_poll_instance_default(const bNode *node, + const bNodeTree *ntree, const char **disabled_info) { /* use the basic poll function */ diff --git a/source/blender/nodes/composite/node_composite_util.cc b/source/blender/nodes/composite/node_composite_util.cc index afe11de059d..219976e85c0 100644 --- a/source/blender/nodes/composite/node_composite_util.cc +++ b/source/blender/nodes/composite/node_composite_util.cc @@ -11,7 +11,9 @@ #include "node_composite_util.hh" -bool cmp_node_poll_default(bNodeType * /*ntype*/, bNodeTree *ntree, const char **r_disabled_hint) +bool cmp_node_poll_default(const bNodeType * /*ntype*/, + const bNodeTree *ntree, + const char **r_disabled_hint) { if (!STREQ(ntree->idname, "CompositorNodeTree")) { *r_disabled_hint = TIP_("Not a compositor node tree"); diff --git a/source/blender/nodes/composite/node_composite_util.hh b/source/blender/nodes/composite/node_composite_util.hh index 46330c67996..9049834100e 100644 --- a/source/blender/nodes/composite/node_composite_util.hh +++ b/source/blender/nodes/composite/node_composite_util.hh @@ -21,8 +21,8 @@ #define CMP_SCALE_MAX 12000 -bool cmp_node_poll_default(struct bNodeType *ntype, - struct bNodeTree *ntree, +bool cmp_node_poll_default(const struct bNodeType *ntype, + const struct bNodeTree *ntree, const char **r_disabled_hint); void cmp_node_update_default(struct bNodeTree *ntree, struct bNode *node); void cmp_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass); diff --git a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc index fd4ef63879e..ad170984cd7 100644 --- a/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc +++ b/source/blender/nodes/composite/nodes/node_composite_cryptomatte.cc @@ -277,8 +277,8 @@ static void node_copy_cryptomatte(bNodeTree * /*dst_ntree*/, dest_node->storage = dest_nc; } -static bool node_poll_cryptomatte(bNodeType * /*ntype*/, - bNodeTree *ntree, +static bool node_poll_cryptomatte(const bNodeType * /*ntype*/, + const bNodeTree *ntree, const char **r_disabled_hint) { if (STREQ(ntree->idname, "CompositorNodeTree")) { diff --git a/source/blender/nodes/composite/nodes/node_composite_image.cc b/source/blender/nodes/composite/nodes/node_composite_image.cc index 9bfb150205b..e743c003701 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.cc +++ b/source/blender/nodes/composite/nodes/node_composite_image.cc @@ -712,8 +712,8 @@ static void node_composit_init_rlayers(const bContext *C, PointerRNA *ptr) } } -static bool node_composit_poll_rlayers(bNodeType * /*ntype*/, - bNodeTree *ntree, +static bool node_composit_poll_rlayers(const bNodeType * /*ntype*/, + const bNodeTree *ntree, const char **r_disabled_hint) { if (!STREQ(ntree->idname, "CompositorNodeTree")) { diff --git a/source/blender/nodes/function/node_function_util.cc b/source/blender/nodes/function/node_function_util.cc index 82459815b77..2be0d639bdf 100644 --- a/source/blender/nodes/function/node_function_util.cc +++ b/source/blender/nodes/function/node_function_util.cc @@ -5,8 +5,8 @@ #include "NOD_socket_search_link.hh" -static bool fn_node_poll_default(bNodeType * /*ntype*/, - bNodeTree *ntree, +static bool fn_node_poll_default(const bNodeType * /*ntype*/, + const bNodeTree *ntree, const char **r_disabled_hint) { /* Function nodes are only supported in simulation node trees so far. */ diff --git a/source/blender/nodes/geometry/node_geometry_util.cc b/source/blender/nodes/geometry/node_geometry_util.cc index 8b962d39b3c..3c830f978d1 100644 --- a/source/blender/nodes/geometry/node_geometry_util.cc +++ b/source/blender/nodes/geometry/node_geometry_util.cc @@ -41,7 +41,9 @@ std::optional node_socket_to_custom_data_type(const bNodeSocket } // namespace blender::nodes -bool geo_node_poll_default(bNodeType * /*ntype*/, bNodeTree *ntree, const char **r_disabled_hint) +bool geo_node_poll_default(const bNodeType * /*ntype*/, + const bNodeTree *ntree, + const char **r_disabled_hint) { if (!STREQ(ntree->idname, "GeometryNodeTree")) { *r_disabled_hint = TIP_("Not a geometry node tree"); diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh index d1aeff2cd7a..d99b4c01ed7 100644 --- a/source/blender/nodes/geometry/node_geometry_util.hh +++ b/source/blender/nodes/geometry/node_geometry_util.hh @@ -28,8 +28,8 @@ struct BVHTreeFromMesh; void geo_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass); -bool geo_node_poll_default(struct bNodeType *ntype, - struct bNodeTree *ntree, +bool geo_node_poll_default(const struct bNodeType *ntype, + const struct bNodeTree *ntree, const char **r_disabled_hint); namespace blender::nodes { diff --git a/source/blender/nodes/intern/node_common.cc b/source/blender/nodes/intern/node_common.cc index b5feea220d1..509921837cc 100644 --- a/source/blender/nodes/intern/node_common.cc +++ b/source/blender/nodes/intern/node_common.cc @@ -70,10 +70,12 @@ void node_group_label(const bNodeTree * /*ntree*/, const bNode *node, char *labe BLI_strncpy(label, (node->id) ? node->id->name + 2 : IFACE_("Missing Data-Block"), maxlen); } -bool node_group_poll_instance(bNode *node, bNodeTree *nodetree, const char **disabled_hint) +bool node_group_poll_instance(const bNode *node, + const bNodeTree *nodetree, + const char **disabled_hint) { if (node->typeinfo->poll(node->typeinfo, nodetree, disabled_hint)) { - bNodeTree *grouptree = (bNodeTree *)node->id; + const bNodeTree *grouptree = (const bNodeTree *)node->id; if (grouptree) { return nodeGroupPoll(nodetree, grouptree, disabled_hint); } diff --git a/source/blender/nodes/intern/node_common.h b/source/blender/nodes/intern/node_common.h index 5ddf0800d8c..e53697be076 100644 --- a/source/blender/nodes/intern/node_common.h +++ b/source/blender/nodes/intern/node_common.h @@ -20,8 +20,8 @@ void node_group_label(const struct bNodeTree *ntree, const struct bNode *node, char *label, int maxlen); -bool node_group_poll_instance(struct bNode *node, - struct bNodeTree *nodetree, +bool node_group_poll_instance(const struct bNode *node, + const struct bNodeTree *nodetree, const char **r_disabled_hint); /** diff --git a/source/blender/nodes/intern/node_register.cc b/source/blender/nodes/intern/node_register.cc index 49ee69ed268..69a20098514 100644 --- a/source/blender/nodes/intern/node_register.cc +++ b/source/blender/nodes/intern/node_register.cc @@ -11,8 +11,8 @@ #include "RNA_access.h" -static bool node_undefined_poll(bNodeType * /*ntype*/, - bNodeTree * /*nodetree*/, +static bool node_undefined_poll(const bNodeType * /*ntype*/, + const bNodeTree * /*nodetree*/, const char ** /*r_disabled_hint*/) { /* this type can not be added deliberately, it's just a placeholder */ diff --git a/source/blender/nodes/shader/node_shader_util.cc b/source/blender/nodes/shader/node_shader_util.cc index b1617a779ea..db32495aba4 100644 --- a/source/blender/nodes/shader/node_shader_util.cc +++ b/source/blender/nodes/shader/node_shader_util.cc @@ -15,7 +15,9 @@ #include "node_exec.h" -bool sh_node_poll_default(bNodeType * /*ntype*/, bNodeTree *ntree, const char **r_disabled_hint) +bool sh_node_poll_default(const bNodeType * /*ntype*/, + const bNodeTree *ntree, + const char **r_disabled_hint) { if (!STREQ(ntree->idname, "ShaderNodeTree")) { *r_disabled_hint = TIP_("Not a shader node tree"); @@ -24,8 +26,8 @@ bool sh_node_poll_default(bNodeType * /*ntype*/, bNodeTree *ntree, const char ** return true; } -static bool sh_fn_poll_default(bNodeType * /*ntype*/, - bNodeTree *ntree, +static bool sh_fn_poll_default(const bNodeType * /*ntype*/, + const bNodeTree *ntree, const char **r_disabled_hint) { if (!STR_ELEM(ntree->idname, "ShaderNodeTree", "GeometryNodeTree")) { diff --git a/source/blender/nodes/shader/node_shader_util.hh b/source/blender/nodes/shader/node_shader_util.hh index d69dc0e52b2..d58a09ce934 100644 --- a/source/blender/nodes/shader/node_shader_util.hh +++ b/source/blender/nodes/shader/node_shader_util.hh @@ -63,8 +63,8 @@ #include "RNA_access.h" -bool sh_node_poll_default(struct bNodeType *ntype, - struct bNodeTree *ntree, +bool sh_node_poll_default(const struct bNodeType *ntype, + const struct bNodeTree *ntree, const char **r_disabled_hint); void sh_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass); void sh_fn_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass); diff --git a/source/blender/nodes/texture/node_texture_util.cc b/source/blender/nodes/texture/node_texture_util.cc index 1174c4f4ce9..2c2f14d0316 100644 --- a/source/blender/nodes/texture/node_texture_util.cc +++ b/source/blender/nodes/texture/node_texture_util.cc @@ -23,7 +23,7 @@ #include "node_texture_util.hh" -bool tex_node_poll_default(bNodeType * /*ntype*/, bNodeTree *ntree, const char **r_disabled_hint) +bool tex_node_poll_default(const bNodeType * /*ntype*/, const bNodeTree *ntree, const char **r_disabled_hint) { if (!STREQ(ntree->idname, "TextureNodeTree")) { *r_disabled_hint = TIP_("Not a texture node tree"); diff --git a/source/blender/nodes/texture/node_texture_util.hh b/source/blender/nodes/texture/node_texture_util.hh index c9a2060172d..529a48951dc 100644 --- a/source/blender/nodes/texture/node_texture_util.hh +++ b/source/blender/nodes/texture/node_texture_util.hh @@ -92,8 +92,8 @@ typedef struct TexDelegate { int type; } TexDelegate; -bool tex_node_poll_default(struct bNodeType *ntype, - struct bNodeTree *ntree, +bool tex_node_poll_default(const struct bNodeType *ntype, + const struct bNodeTree *ntree, const char **r_disabled_hint); void tex_node_type_base(struct bNodeType *ntype, int type, const char *name, short nclass); From 3176b113e4087d771fa6ae90699c42de963fb685 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 28 Dec 2022 20:37:16 -0500 Subject: [PATCH 0299/1522] Geometry Nodes: Reduce socket logging overhead Use socket indices to keep track of logged values instead of their identifiers. This decreases memory pressure when there are many sockets. In cases with many cheap nodes, this can give a relatively large improvement to overall performance. We observed a 15% increase in a case with many math nodes and a larger increase in an experimental softbody node setup. The log is invalidated when we add/remove/move sockets anyway. --- source/blender/nodes/NOD_geometry_nodes_log.hh | 8 ++++---- source/blender/nodes/intern/geometry_nodes_log.cc | 13 +++++-------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/source/blender/nodes/NOD_geometry_nodes_log.hh b/source/blender/nodes/NOD_geometry_nodes_log.hh index e2207338823..cfcecc31276 100644 --- a/source/blender/nodes/NOD_geometry_nodes_log.hh +++ b/source/blender/nodes/NOD_geometry_nodes_log.hh @@ -180,7 +180,7 @@ class GeoTreeLogger { }; struct SocketValueLog { int32_t node_id; - StringRefNull socket_identifier; + int socket_index; destruct_ptr value; }; struct NodeExecutionTime { @@ -234,9 +234,9 @@ class GeoNodeLog { * inside. */ std::chrono::nanoseconds run_time{0}; - /** Maps from socket identifiers to their values. */ - Map input_values_; - Map output_values_; + /** Maps from socket indices to their values. */ + Map input_values_; + Map output_values_; /** Maps from attribute name to their usage flags. */ Map used_named_attributes; /** Messages that are used for debugging purposes during development. */ diff --git a/source/blender/nodes/intern/geometry_nodes_log.cc b/source/blender/nodes/intern/geometry_nodes_log.cc index e8b65a3d319..eb2e9bd9015 100644 --- a/source/blender/nodes/intern/geometry_nodes_log.cc +++ b/source/blender/nodes/intern/geometry_nodes_log.cc @@ -151,8 +151,7 @@ void GeoTreeLogger::log_value(const bNode &node, const bNodeSocket &socket, cons auto store_logged_value = [&](destruct_ptr value_log) { auto &socket_values = socket.in_out == SOCK_IN ? this->input_socket_values : this->output_socket_values; - socket_values.append( - {node.identifier, this->allocator->copy_string(socket.identifier), std::move(value_log)}); + socket_values.append({node.identifier, socket.index(), std::move(value_log)}); }; auto log_generic_value = [&](const CPPType &type, const void *value) { @@ -252,11 +251,11 @@ void GeoTreeLog::ensure_socket_values() for (GeoTreeLogger *tree_logger : tree_loggers_) { for (const GeoTreeLogger::SocketValueLog &value_log_data : tree_logger->input_socket_values) { this->nodes.lookup_or_add_as(value_log_data.node_id) - .input_values_.add(value_log_data.socket_identifier, value_log_data.value.get()); + .input_values_.add(value_log_data.socket_index, value_log_data.value.get()); } for (const GeoTreeLogger::SocketValueLog &value_log_data : tree_logger->output_socket_values) { this->nodes.lookup_or_add_as(value_log_data.node_id) - .output_values_.add(value_log_data.socket_identifier, value_log_data.value.get()); + .output_values_.add(value_log_data.socket_index, value_log_data.value.get()); } } reduced_socket_values_ = true; @@ -376,10 +375,8 @@ ValueLog *GeoTreeLog::find_socket_value_log(const bNodeSocket &query_socket) const bNode &node = socket.owner_node(); if (GeoNodeLog *node_log = this->nodes.lookup_ptr(node.identifier)) { ValueLog *value_log = socket.is_input() ? - node_log->input_values_.lookup_default(socket.identifier, - nullptr) : - node_log->output_values_.lookup_default(socket.identifier, - nullptr); + node_log->input_values_.lookup_default(socket.index(), nullptr) : + node_log->output_values_.lookup_default(socket.index(), nullptr); if (value_log != nullptr) { return value_log; } From c9b06505d8d56e2b599cf60f47ee3baa413c31fa Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 28 Dec 2022 20:39:14 -0500 Subject: [PATCH 0300/1522] Cleanup: Grammar in comments "spend" is a verb, not a noun. --- source/blender/blenkernel/BKE_subdiv.h | 4 ++-- source/blender/depsgraph/intern/node/deg_node.h | 2 +- source/blender/nodes/NOD_geometry_nodes_log.hh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h index 5a6e8cbb64a..97bcab8a3a2 100644 --- a/source/blender/blenkernel/BKE_subdiv.h +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -88,9 +88,9 @@ typedef enum eSubdivStatsValue { typedef struct SubdivStats { union { struct { - /* Time spend on creating topology refiner, which includes time + /* Time spent on creating topology refiner, which includes time * spend on conversion from Blender data to OpenSubdiv data, and - * time spend on topology orientation on OpenSubdiv C-API side. */ + * time spent on topology orientation on OpenSubdiv C-API side. */ double topology_refiner_creation_time; /* Total time spent in BKE_subdiv_to_mesh(). */ double subdiv_to_mesh_time; diff --git a/source/blender/depsgraph/intern/node/deg_node.h b/source/blender/depsgraph/intern/node/deg_node.h index e31c1769a2a..c28897a5ad4 100644 --- a/source/blender/depsgraph/intern/node/deg_node.h +++ b/source/blender/depsgraph/intern/node/deg_node.h @@ -161,7 +161,7 @@ struct Node { /* Reset counters needed for the current graph evaluation, does not * touch averaging accumulators. */ void reset_current(); - /* Time spend on this node during current graph evaluation. */ + /* Time spent on this node during current graph evaluation. */ double current_time; }; /* Relationships between nodes diff --git a/source/blender/nodes/NOD_geometry_nodes_log.hh b/source/blender/nodes/NOD_geometry_nodes_log.hh index cfcecc31276..d99dff21c6d 100644 --- a/source/blender/nodes/NOD_geometry_nodes_log.hh +++ b/source/blender/nodes/NOD_geometry_nodes_log.hh @@ -230,7 +230,7 @@ class GeoNodeLog { /** Warnings generated for that node. */ Vector warnings; /** - * Time spend in that node. For node groups this is the sum of the run times of the nodes + * Time spent in this node. For node groups this is the sum of the run times of the nodes * inside. */ std::chrono::nanoseconds run_time{0}; From 6347562fb0177eb5b3d4890d3719a91c4e783d8d Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 29 Dec 2022 11:03:51 +0900 Subject: [PATCH 0301/1522] install_deps.sh: Update python, numpy and boost for 3.5. - Python: 3.10.9 - NumPy: 1.23.5 - Boost: 1.80.0 Re. T99618 --- build_files/build_environment/install_deps.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index ed18e563f14..7aefa175f6c 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -394,7 +394,7 @@ CLANG_FORMAT_VERSION="10.0" CLANG_FORMAT_VERSION_MIN="6.0" CLANG_FORMAT_VERSION_MEX="14.0" -PYTHON_VERSION="3.10.8" +PYTHON_VERSION="3.10.9" PYTHON_VERSION_SHORT="3.10" PYTHON_VERSION_MIN="3.10" PYTHON_VERSION_MEX="3.12" @@ -434,7 +434,7 @@ PYTHON_ZSTANDARD_VERSION_MIN="0.15.2" PYTHON_ZSTANDARD_VERSION_MEX="0.20.0" PYTHON_ZSTANDARD_NAME="zstandard" -PYTHON_NUMPY_VERSION="1.22.0" +PYTHON_NUMPY_VERSION="1.23.5" PYTHON_NUMPY_VERSION_MIN="1.14" PYTHON_NUMPY_VERSION_MEX="2.0" PYTHON_NUMPY_NAME="numpy" @@ -462,8 +462,8 @@ PYTHON_MODULES_PIP=( ) -BOOST_VERSION="1.78.0" -BOOST_VERSION_SHORT="1.78" +BOOST_VERSION="1.80.0" +BOOST_VERSION_SHORT="1.80" BOOST_VERSION_MIN="1.49" BOOST_VERSION_MEX="2.0" BOOST_FORCE_BUILD=false From 9e332b113bf8ce893d1d85f8f6f4fbaaae46081c Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 29 Dec 2022 12:56:46 +0900 Subject: [PATCH 0302/1522] install_deps.sh: Update OIIO, OpenVDB, OSD and OCIO for Blender 3.5. OIIO: 2.4.6.0 OpenVDB: 10.0.0 OSD: 3.5.0 OCIO: 2.2.0 NOTE: Had to fight OpenVDB to force it to use 'deprecated' TBB 2020, it really wants to use oneTBB when it can find it. Re. T99618. --- build_files/build_environment/install_deps.sh | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 7aefa175f6c..cbb7e20cda6 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -479,8 +479,8 @@ TBB_FORCE_BUILD=false TBB_FORCE_REBUILD=false TBB_SKIP=false -OCIO_VERSION="2.1.1" -OCIO_VERSION_SHORT="2.1" +OCIO_VERSION="2.2.0" +OCIO_VERSION_SHORT="2.2" OCIO_VERSION_MIN="2.0" OCIO_VERSION_MEX="3.0" OCIO_FORCE_BUILD=false @@ -505,10 +505,10 @@ OPENEXR_FORCE_REBUILD=false OPENEXR_SKIP=false _with_built_openexr=false -OIIO_VERSION="2.3.20.0" -OIIO_VERSION_SHORT="2.3" -OIIO_VERSION_MIN="2.1.12" -OIIO_VERSION_MEX="2.4.0" +OIIO_VERSION="2.4.6.0" +OIIO_VERSION_SHORT="2.4" +OIIO_VERSION_MIN="2.2.0" +OIIO_VERSION_MEX="2.5.0" OIIO_FORCE_BUILD=false OIIO_FORCE_REBUILD=false OIIO_SKIP=false @@ -532,9 +532,9 @@ OSL_FORCE_REBUILD=false OSL_SKIP=false # OpenSubdiv needs to be compiled for now -OSD_VERSION="3.4.4" -OSD_VERSION_SHORT="3.4" -OSD_VERSION_MIN="3.4" +OSD_VERSION="3.5.0" +OSD_VERSION_SHORT="3.5" +OSD_VERSION_MIN="3.5" OSD_VERSION_MEX="4.0" OSD_FORCE_BUILD=false OSD_FORCE_REBUILD=false @@ -543,10 +543,10 @@ OSD_SKIP=false # OpenVDB needs to be compiled for now OPENVDB_BLOSC_VERSION="1.21.1" -OPENVDB_VERSION="9.0.0" -OPENVDB_VERSION_SHORT="9.0" -OPENVDB_VERSION_MIN="9.0" -OPENVDB_VERSION_MEX="9.1" +OPENVDB_VERSION="10.0.0" +OPENVDB_VERSION_SHORT="10.0" +OPENVDB_VERSION_MIN="10.0" +OPENVDB_VERSION_MEX="11.0" OPENVDB_FORCE_BUILD=false OPENVDB_FORCE_REBUILD=false OPENVDB_SKIP=false @@ -2969,6 +2969,9 @@ compile_OPENVDB() { fi if [ -d $INST/tbb ]; then cmake_d="$cmake_d -D TBB_ROOT=$INST/tbb" + # Work around until we use oneTBB, otherwise OpenVDB forcefully + # uses oneTBB if it can find it on the system. + cmake_d="$cmake_d -D Tbb_INCLUDE_DIR=$INST/tbb/include" fi if [ "$_with_built_imath" = true ]; then From 4e027fdde6ea0940be97b4e64317980ebf5cc175 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 29 Dec 2022 15:33:42 +0900 Subject: [PATCH 0303/1522] update_deps.sh: Update OSL and USD for Blender 3.5.\ OSL: 1.13-dev-1a7670600c8b08c2443a78d03c8c27e9a1149140 USD: 22.11 Re. T99618. --- build_files/build_environment/install_deps.sh | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index cbb7e20cda6..c876bdd63e2 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -523,8 +523,8 @@ LLVM_FORCE_REBUILD=false LLVM_SKIP=false # OSL needs to be compiled for now! -OSL_VERSION="1.12.6.2" -OSL_VERSION_SHORT="1.12" +OSL_VERSION="1.13.0.2" +OSL_VERSION_SHORT="1.13" OSL_VERSION_MIN="1.11" OSL_VERSION_MEX="2.0" OSL_FORCE_BUILD=false @@ -560,8 +560,8 @@ ALEMBIC_FORCE_BUILD=false ALEMBIC_FORCE_REBUILD=false ALEMBIC_SKIP=false -USD_VERSION="22.03" -USD_VERSION_SHORT="22.03" +USD_VERSION="22.11" +USD_VERSION_SHORT="22.11" USD_VERSION_MIN="20.05" USD_VERSION_MEX="23.00" USD_FORCE_BUILD=false @@ -1138,17 +1138,11 @@ _LLVM_SOURCE_ROOT="https://github.com/llvm/llvm-project/releases/download/llvmor LLVM_SOURCE=( "$_LLVM_SOURCE_ROOT/llvm-$LLVM_VERSION.src.tar.xz" ) LLVM_CLANG_SOURCE=( "$_LLVM_SOURCE_ROOT/clang-$LLVM_VERSION.src.tar.xz" "$_LLVM_SOURCE_ROOT/cfe-$LLVM_VERSION.src.tar.xz" ) -OSL_USE_REPO=false +OSL_USE_REPO=true OSL_SOURCE=( "https://github.com/imageworks/OpenShadingLanguage/archive/v$OSL_VERSION.tar.gz" ) -#~ OSL_SOURCE_REPO=( "https://github.com/imageworks/OpenShadingLanguage.git" ) -#~ OSL_SOURCE_REPO_BRANCH="master" -#~ OSL_SOURCE_REPO_UID="85179714e1bc69cd25ecb6bb711c1a156685d395" -#~ OSL_SOURCE=( "https://github.com/Nazg-Gul/OpenShadingLanguage/archive/Release-1.5.11.tar.gz" ) -#~ OSL_SOURCE_REPO=( "https://github.com/mont29/OpenShadingLanguage.git" ) -#~ OSL_SOURCE_REPO_UID="85179714e1bc69cd25ecb6bb711c1a156685d395" -#~ OSL_SOURCE_REPO=( "https://github.com/Nazg-Gul/OpenShadingLanguage.git" ) -#~ OSL_SOURCE_REPO_UID="7d40ff5fe8e47b030042afb92d0e955f5aa96f48" -#~ OSL_SOURCE_REPO_BRANCH="blender-fixes" +OSL_SOURCE_REPO=( "https://github.com/AcademySoftwareFoundation/OpenShadingLanguage.git" ) +OSL_SOURCE_REPO_BRANCH="main" +OSL_SOURCE_REPO_UID="1a7670600c8b08c2443a78d03c8c27e9a1149140" OSD_USE_REPO=false # Script foo to make the version string compliant with the archive name: From 8c194e1ba6aefa0cffafcc7edccb47f8ba8589c0 Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Thu, 29 Dec 2022 20:49:08 +1300 Subject: [PATCH 0304/1522] Cleanup: format --- source/blender/blenkernel/BKE_image_partial_update.hh | 1 - source/blender/editors/mesh/editmesh_mask_extract.c | 2 +- .../gpencil_modifiers/intern/lineart/lineart_shadow.c | 2 +- source/blender/gpu/intern/gpu_codegen.cc | 3 ++- source/blender/modifiers/intern/MOD_util.cc | 1 - source/blender/nodes/intern/node_socket.cc | 1 - source/blender/nodes/texture/node_texture_util.cc | 4 +++- tests/python/bl_blendfile_io.py | 6 +++--- tests/python/modifiers.py | 2 ++ 9 files changed, 12 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/BKE_image_partial_update.hh b/source/blender/blenkernel/BKE_image_partial_update.hh index 6c7776c091c..8f962ace268 100644 --- a/source/blender/blenkernel/BKE_image_partial_update.hh +++ b/source/blender/blenkernel/BKE_image_partial_update.hh @@ -29,7 +29,6 @@ struct PartialUpdateUser; namespace blender::bke::image { - namespace partial_update { /* --- image_partial_update.cc --- */ diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c index bb4d745a677..9988bdcb367 100644 --- a/source/blender/editors/mesh/editmesh_mask_extract.c +++ b/source/blender/editors/mesh/editmesh_mask_extract.c @@ -293,7 +293,7 @@ static int paint_mask_extract_exec(bContext *C, wmOperator *op) * Note: A second push happens after the operator due to * the OPTYPE_UNDO flag; having an initial undo step here * is just needed to preserve the active object pointer. - * + * * Fixes T103261. */ ED_undo_push_op(C, op); diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c index 7ac1ecb3796..26352f8ed54 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c @@ -588,7 +588,7 @@ static void lineart_shadow_edge_cut(LineartData *ld, new_seg_2->ratio = end; } - double r_fb_co_1[4]={0}, r_fb_co_2[4]={0}, r_gloc_1[3]={0}, r_gloc_2[3]={0}; + double r_fb_co_1[4] = {0}, r_fb_co_2[4] = {0}, r_gloc_1[3] = {0}, r_gloc_2[3] = {0}; double r_new_in_the_middle[4], r_new_in_the_middle_global[3], r_new_at; double *s1_fb_co_1, *s1_fb_co_2, *s1_gloc_1, *s1_gloc_2; diff --git a/source/blender/gpu/intern/gpu_codegen.cc b/source/blender/gpu/intern/gpu_codegen.cc index c4c0e403af1..465a621e864 100644 --- a/source/blender/gpu/intern/gpu_codegen.cc +++ b/source/blender/gpu/intern/gpu_codegen.cc @@ -211,7 +211,8 @@ static std::ostream &operator<<(std::ostream &stream, const GPUOutput *output) } /* Trick type to change overload and keep a somewhat nice syntax. */ -struct GPUConstant : public GPUInput {}; +struct GPUConstant : public GPUInput { +}; /* Print data constructor (i.e: vec2(1.0f, 1.0f)). */ static std::ostream &operator<<(std::ostream &stream, const GPUConstant *input) diff --git a/source/blender/modifiers/intern/MOD_util.cc b/source/blender/modifiers/intern/MOD_util.cc index 6b7072db121..844e2d19a58 100644 --- a/source/blender/modifiers/intern/MOD_util.cc +++ b/source/blender/modifiers/intern/MOD_util.cc @@ -40,7 +40,6 @@ #include "MEM_guardedalloc.h" - void MOD_init_texture(MappingInfoModifierData *dmd, const ModifierEvalContext *ctx) { Tex *tex = dmd->texture; diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index e179740aafb..8f2c36152c5 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -482,7 +482,6 @@ void node_socket_copy_default_value(bNodeSocket *to, const bNodeSocket *from) to->flag |= (from->flag & SOCK_HIDE_VALUE); } - static void standard_node_socket_interface_init_socket(bNodeTree * /*ntree*/, const bNodeSocket *interface_socket, bNode * /*node*/, diff --git a/source/blender/nodes/texture/node_texture_util.cc b/source/blender/nodes/texture/node_texture_util.cc index 2c2f14d0316..46d8417bfce 100644 --- a/source/blender/nodes/texture/node_texture_util.cc +++ b/source/blender/nodes/texture/node_texture_util.cc @@ -23,7 +23,9 @@ #include "node_texture_util.hh" -bool tex_node_poll_default(const bNodeType * /*ntype*/, const bNodeTree *ntree, const char **r_disabled_hint) +bool tex_node_poll_default(const bNodeType * /*ntype*/, + const bNodeTree *ntree, + const char **r_disabled_hint) { if (!STREQ(ntree->idname, "TextureNodeTree")) { *r_disabled_hint = TIP_("Not a texture node tree"); diff --git a/tests/python/bl_blendfile_io.py b/tests/python/bl_blendfile_io.py index ae49afdfadb..8495c8a7ad6 100644 --- a/tests/python/bl_blendfile_io.py +++ b/tests/python/bl_blendfile_io.py @@ -65,7 +65,7 @@ class TestIdRuntimeTag(TestHelper): obj = bpy.data.objects['Cube'] assert obj.is_runtime_data == False - assert bpy.context.view_layer.depsgraph.ids['Cube'].is_runtime_data == True + assert bpy.context.view_layer.depsgraph.ids['Cube'].is_runtime_data output_work_path = os.path.join(output_dir, self.unique_blendfile_name("blendfile")) bpy.ops.wm.save_as_mainfile(filepath=output_work_path, check_existing=False, compress=False) @@ -75,7 +75,7 @@ class TestIdRuntimeTag(TestHelper): assert obj.is_runtime_data == False obj.is_runtime_data = True - assert obj.is_runtime_data == True + assert obj.is_runtime_data bpy.ops.wm.save_as_mainfile(filepath=output_work_path, check_existing=False, compress=False) bpy.ops.wm.open_mainfile(filepath=output_work_path, load_ui=False) @@ -116,7 +116,7 @@ class TestIdRuntimeTag(TestHelper): # Only usage of this linked material is a runtime ID (object), # so writing .blend file will have properly reset its tag to indirectly linked data. - assert linked_material.is_library_indirect == True + assert linked_material.is_library_indirect bpy.ops.wm.open_mainfile(filepath=output_work_path, load_ui=False) diff --git a/tests/python/modifiers.py b/tests/python/modifiers.py index f16d91d41f9..a4196b44fd4 100644 --- a/tests/python/modifiers.py +++ b/tests/python/modifiers.py @@ -30,6 +30,7 @@ def cube_mask_first_modifier_list(): ] return generate_modifiers + def cube_random_modifier_list(): generate_modifiers = [ ModifierSpec('edge split', 'EDGE_SPLIT', {}), @@ -46,6 +47,7 @@ def cube_random_modifier_list(): ] return generate_modifiers + def main(): tests = [ From 72b4f9191462215ec66ba699a7cd1e797e7032b7 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 29 Dec 2022 14:19:50 +0100 Subject: [PATCH 0305/1522] Fix T103526: crash when subsurface connects to Shader to RGB This was caused by {rB7b82d8f029cd1088efd5fbb8bf}. --- source/blender/nodes/shader/node_shader_tree.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/nodes/shader/node_shader_tree.cc b/source/blender/nodes/shader/node_shader_tree.cc index 66bff5a2ada..691ffc936a7 100644 --- a/source/blender/nodes/shader/node_shader_tree.cc +++ b/source/blender/nodes/shader/node_shader_tree.cc @@ -588,6 +588,7 @@ static bNode *ntree_shader_copy_branch(bNodeTree *ntree, nodeUniqueID(ntree, nodes_copy[id]); nodes_copy[id]->runtime->tmp_flag = -2; /* Copy */ + nodes_copy[id]->runtime->original = node->runtime->original; /* Make sure to clear all sockets links as they are invalid. */ LISTBASE_FOREACH (bNodeSocket *, sock, &nodes_copy[id]->inputs) { sock->link = nullptr; From cc48610d2c55a001bcd3af57ad11f7951602936d Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 29 Dec 2022 14:59:48 +0100 Subject: [PATCH 0306/1522] BLI: improve support for using vectors as hash table keys To support this, I had to add comparison and hashing functions for vectors or sequences more generally. --- source/blender/blenlib/BLI_hash_tables.hh | 18 ++++++++++++++++++ source/blender/blenlib/BLI_span.hh | 11 +++++++++++ source/blender/blenlib/BLI_vector.hh | 16 ++++++++++++++++ source/blender/blenlib/tests/BLI_map_test.cc | 18 ++++++++++++++++++ 4 files changed, 63 insertions(+) diff --git a/source/blender/blenlib/BLI_hash_tables.hh b/source/blender/blenlib/BLI_hash_tables.hh index fff2411f94c..6e453820ec9 100644 --- a/source/blender/blenlib/BLI_hash_tables.hh +++ b/source/blender/blenlib/BLI_hash_tables.hh @@ -353,4 +353,22 @@ template struct DefaultEquality> : public Pointer template struct DefaultEquality> : public PointerComparison { }; +struct SequenceComparison { + template bool operator()(const T1 &a, const T2 &b) const + { + const auto a_begin = a.begin(); + const auto a_end = a.end(); + const auto b_begin = b.begin(); + const auto b_end = b.end(); + if (a_end - a_begin != b_end - b_begin) { + return false; + } + return std::equal(a_begin, a_end, b_begin); + } +}; + +template +struct DefaultEquality> : public SequenceComparison { +}; + } // namespace blender diff --git a/source/blender/blenlib/BLI_span.hh b/source/blender/blenlib/BLI_span.hh index 84a5c87d423..a276bbd8f68 100644 --- a/source/blender/blenlib/BLI_span.hh +++ b/source/blender/blenlib/BLI_span.hh @@ -66,6 +66,8 @@ namespace blender { +template uint64_t get_default_hash(const T &v); + /** * References an array of type T that is owned by someone else. The data in the array cannot be * modified. @@ -418,6 +420,15 @@ template class Span { return IndexRange(size_); } + constexpr uint64_t hash() const + { + uint64_t hash = 0; + for (const T &value : *this) { + hash = hash * 33 ^ get_default_hash(value); + } + return hash; + } + /** * Returns a new Span to the same underlying memory buffer. No conversions are done. */ diff --git a/source/blender/blenlib/BLI_vector.hh b/source/blender/blenlib/BLI_vector.hh index 8860bb05127..09486b32480 100644 --- a/source/blender/blenlib/BLI_vector.hh +++ b/source/blender/blenlib/BLI_vector.hh @@ -157,6 +157,12 @@ class Vector { this->increase_size_by_unchecked(size); } + template))> + explicit Vector(MutableSpan values, Allocator allocator = {}) + : Vector(values.as_span(), allocator) + { + } + /** * Create a vector that contains copies of the values in the initialized list. * @@ -937,6 +943,16 @@ class Vector { return IndexRange(this->size()); } + uint64_t hash() const + { + return this->as_span().hash(); + } + + static uint64_t hash_as(const Span values) + { + return values.hash(); + } + friend bool operator==(const Vector &a, const Vector &b) { return a.as_span() == b.as_span(); diff --git a/source/blender/blenlib/tests/BLI_map_test.cc b/source/blender/blenlib/tests/BLI_map_test.cc index 69ae82d6f05..2662d547ee9 100644 --- a/source/blender/blenlib/tests/BLI_map_test.cc +++ b/source/blender/blenlib/tests/BLI_map_test.cc @@ -671,6 +671,24 @@ TEST(map, LookupKey) EXPECT_EQ(map.lookup_key_ptr("a"), map.lookup_key_ptr_as("a")); } +TEST(map, VectorKey) +{ + Map, int> map; + map.add({1, 2, 3}, 100); + map.add({3, 2, 1}, 200); + + EXPECT_EQ(map.size(), 2); + EXPECT_EQ(map.lookup({1, 2, 3}), 100); + EXPECT_EQ(map.lookup({3, 2, 1}), 200); + EXPECT_FALSE(map.contains({1, 2})); + + std::array array = {1, 2, 3}; + EXPECT_EQ(map.lookup_as(array), 100); + + map.remove_as(Vector({1, 2, 3}).as_mutable_span()); + EXPECT_EQ(map.size(), 1); +} + /** * Set this to 1 to activate the benchmark. It is disabled by default, because it prints a lot. */ From 7e4f9880722a82b59acf1c18ae234935bed02aff Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 29 Dec 2022 15:09:52 +0100 Subject: [PATCH 0307/1522] BLI: improve node graph export in dot format This makes it bit easier to export node graphs and also allows for more customization of links and sockets. --- source/blender/blenlib/BLI_dot_export.hh | 47 +++++++++++++++---- source/blender/blenlib/intern/dot_export.cc | 43 +++++++++-------- .../functions/FN_lazy_function_graph.hh | 19 +++++++- .../functions/intern/lazy_function_graph.cc | 37 +++++++++++---- .../blender/nodes/intern/derived_node_tree.cc | 15 +++--- 5 files changed, 117 insertions(+), 44 deletions(-) diff --git a/source/blender/blenlib/BLI_dot_export.hh b/source/blender/blenlib/BLI_dot_export.hh index 454f3c8412c..cc30d9425ee 100644 --- a/source/blender/blenlib/BLI_dot_export.hh +++ b/source/blender/blenlib/BLI_dot_export.hh @@ -184,10 +184,13 @@ class NodePort { private: Node *node_; std::optional port_name_; + std::optional port_position_; public: - NodePort(Node &node, std::optional port_name = {}) - : node_(&node), port_name_(std::move(port_name)) + NodePort(Node &node, + std::optional port_name = {}, + std::optional port_position = {}) + : node_(&node), port_name_(std::move(port_name)), port_position_(std::move(port_position)) { } @@ -248,15 +251,43 @@ class UndirectedEdge : public Edge { std::string color_attr_from_hsv(float h, float s, float v); +struct NodeWithSockets { + struct Socket { + std::string name; + std::optional fontcolor; + }; + struct Input : public Socket { + }; + struct Output : public Socket { + }; + + std::string node_name; + Vector inputs; + Vector outputs; + + Input &add_input(std::string name) + { + this->inputs.append({}); + Input &input = this->inputs.last(); + input.name = std::move(name); + return input; + } + + Output &add_output(std::string name) + { + this->outputs.append({}); + Output &output = this->outputs.last(); + output.name = std::move(name); + return output; + } +}; + class NodeWithSocketsRef { private: Node *node_; public: - NodeWithSocketsRef(Node &node, - StringRef name, - Span input_names, - Span output_names); + NodeWithSocketsRef(Node &node, const NodeWithSockets &data); Node &node() { @@ -266,13 +297,13 @@ class NodeWithSocketsRef { NodePort input(int index) const { std::string port = "\"in" + std::to_string(index) + "\""; - return NodePort(*node_, port); + return NodePort(*node_, port, "w"); } NodePort output(int index) const { std::string port = "\"out" + std::to_string(index) + "\""; - return NodePort(*node_, port); + return NodePort(*node_, port, "e"); } }; diff --git a/source/blender/blenlib/intern/dot_export.cc b/source/blender/blenlib/intern/dot_export.cc index d577de9bc34..8d2bf3f9a5f 100644 --- a/source/blender/blenlib/intern/dot_export.cc +++ b/source/blender/blenlib/intern/dot_export.cc @@ -244,6 +244,9 @@ void NodePort::to_dot_string(std::stringstream &ss) const if (port_name_.has_value()) { ss << ":" << *port_name_; } + if (port_position_.has_value()) { + ss << ":" << *port_position_; + } } std::string color_attr_from_hsv(float h, float s, float v) @@ -253,11 +256,7 @@ std::string color_attr_from_hsv(float h, float s, float v) return ss.str(); } -NodeWithSocketsRef::NodeWithSocketsRef(Node &node, - StringRef name, - Span input_names, - Span output_names) - : node_(&node) +NodeWithSocketsRef::NodeWithSocketsRef(Node &node, const NodeWithSockets &data) : node_(&node) { std::stringstream ss; @@ -265,33 +264,39 @@ NodeWithSocketsRef::NodeWithSocketsRef(Node &node, /* Header */ ss << R"()"; - ss << ((name.size() == 0) ? "No Name" : name); + ss << (data.node_name.empty() ? "No Name" : data.node_name); ss << ""; /* Sockets */ - int socket_max_amount = std::max(input_names.size(), output_names.size()); + int socket_max_amount = std::max(data.inputs.size(), data.outputs.size()); for (int i = 0; i < socket_max_amount; i++) { ss << ""; - if (i < input_names.size()) { - StringRef name = input_names[i]; - if (name.size() == 0) { - name = "No Name"; - } + if (i < data.inputs.size()) { + const NodeWithSockets::Input &input = data.inputs[i]; ss << R"("; - ss << name; + if (input.fontcolor) { + ss << R"("; + } + ss << (input.name.empty() ? "No Name" : input.name); + if (input.fontcolor) { + ss << ""; + } ss << ""; } else { ss << ""; } ss << ""; - if (i < output_names.size()) { - StringRef name = output_names[i]; - if (name.size() == 0) { - name = "No Name"; - } + if (i < data.outputs.size()) { + const NodeWithSockets::Output &output = data.outputs[i]; ss << R"("; - ss << name; + if (output.fontcolor) { + ss << R"("; + } + ss << (output.name.empty() ? "No Name" : output.name); + if (output.fontcolor) { + ss << ""; + } ss << ""; } else { diff --git a/source/blender/functions/FN_lazy_function_graph.hh b/source/blender/functions/FN_lazy_function_graph.hh index 7352004b7fe..460e858774f 100644 --- a/source/blender/functions/FN_lazy_function_graph.hh +++ b/source/blender/functions/FN_lazy_function_graph.hh @@ -19,6 +19,10 @@ #include "FN_lazy_function.hh" +namespace blender::dot { +class DirectedEdge; +} + namespace blender::fn::lazy_function { class Socket; @@ -238,10 +242,23 @@ class Graph : NonCopyable, NonMovable { */ bool node_indices_are_valid() const; + /** + * Optional configuration options for the dot graph generation. This allows creating + * visualizations for specific purposes. + */ + class ToDotOptions { + public: + virtual std::string socket_name(const Socket &socket) const; + virtual std::optional socket_font_color(const Socket &socket) const; + virtual void add_edge_attributes(const OutputSocket &from, + const InputSocket &to, + dot::DirectedEdge &dot_edge) const; + }; + /** * Utility to generate a dot graph string for the graph. This can be used for debugging. */ - std::string to_dot() const; + std::string to_dot(const ToDotOptions &options = {}) const; }; /* -------------------------------------------------------------------- */ diff --git a/source/blender/functions/intern/lazy_function_graph.cc b/source/blender/functions/intern/lazy_function_graph.cc index 60605a4e64c..e8a20fbf9a3 100644 --- a/source/blender/functions/intern/lazy_function_graph.cc +++ b/source/blender/functions/intern/lazy_function_graph.cc @@ -152,7 +152,23 @@ std::string DummyDebugInfo::output_name(const int /*i*/) const return fallback_name; } -std::string Graph::to_dot() const +std::string Graph::ToDotOptions::socket_name(const Socket &socket) const +{ + return socket.name(); +} + +std::optional Graph::ToDotOptions::socket_font_color(const Socket & /*socket*/) const +{ + return std::nullopt; +} + +void Graph::ToDotOptions::add_edge_attributes(const OutputSocket & /*from*/, + const InputSocket & /*to*/, + dot::DirectedEdge & /*dot_edge*/) const +{ +} + +std::string Graph::to_dot(const ToDotOptions &options) const { dot::DirectedGraph digraph; digraph.set_rankdir(dot::Attr_rankdir::LeftToRight); @@ -168,17 +184,20 @@ std::string Graph::to_dot() const dot_node.set_background_color("white"); } - Vector input_names; - Vector output_names; + dot::NodeWithSockets dot_node_with_sockets; + dot_node_with_sockets.node_name = node->name(); for (const InputSocket *socket : node->inputs()) { - input_names.append(socket->name()); + dot::NodeWithSockets::Input &dot_input = dot_node_with_sockets.add_input( + options.socket_name(*socket)); + dot_input.fontcolor = options.socket_font_color(*socket); } for (const OutputSocket *socket : node->outputs()) { - output_names.append(socket->name()); + dot::NodeWithSockets::Output &dot_output = dot_node_with_sockets.add_output( + options.socket_name(*socket)); + dot_output.fontcolor = options.socket_font_color(*socket); } - dot_nodes.add_new(node, - dot::NodeWithSocketsRef(dot_node, node->name(), input_names, output_names)); + dot_nodes.add_new(node, dot::NodeWithSocketsRef(dot_node, dot_node_with_sockets)); } for (const Node *node : nodes_) { @@ -188,7 +207,9 @@ std::string Graph::to_dot() const if (const OutputSocket *origin = socket->origin()) { dot::NodeWithSocketsRef &from_dot_node = dot_nodes.lookup(&origin->node()); - digraph.new_edge(from_dot_node.output(origin->index()), to_dot_port); + dot::DirectedEdge &dot_edge = digraph.new_edge(from_dot_node.output(origin->index()), + to_dot_port); + options.add_edge_attributes(*origin, *socket, dot_edge); } else if (const void *default_value = socket->default_value()) { const CPPType &type = socket->type(); diff --git a/source/blender/nodes/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc index ece60ffe4ab..9b8a9f2401a 100644 --- a/source/blender/nodes/intern/derived_node_tree.cc +++ b/source/blender/nodes/intern/derived_node_tree.cc @@ -344,27 +344,26 @@ std::string DerivedNodeTree::to_dot() const dot_node.set_parent_cluster(cluster); dot_node.set_background_color("white"); - Vector input_names; - Vector output_names; + dot::NodeWithSockets dot_node_with_sockets; for (const bNodeSocket *socket : node->input_sockets()) { if (socket->is_available()) { - input_names.append(socket->name); + dot_node_with_sockets.add_input(socket->name); } } for (const bNodeSocket *socket : node->output_sockets()) { if (socket->is_available()) { - output_names.append(socket->name); + dot_node_with_sockets.add_output(socket->name); } } - dot::NodeWithSocketsRef dot_node_with_sockets = dot::NodeWithSocketsRef( - dot_node, node->name, input_names, output_names); + dot::NodeWithSocketsRef dot_node_with_sockets_ref = dot::NodeWithSocketsRef( + dot_node, dot_node_with_sockets); int input_index = 0; for (const bNodeSocket *socket : node->input_sockets()) { if (socket->is_available()) { dot_input_sockets.add_new(DInputSocket{node.context(), socket}, - dot_node_with_sockets.input(input_index)); + dot_node_with_sockets_ref.input(input_index)); input_index++; } } @@ -372,7 +371,7 @@ std::string DerivedNodeTree::to_dot() const for (const bNodeSocket *socket : node->output_sockets()) { if (socket->is_available()) { dot_output_sockets.add_new(DOutputSocket{node.context(), socket}, - dot_node_with_sockets.output(output_index)); + dot_node_with_sockets_ref.output(output_index)); output_index++; } } From f53bb93af93742861aa23674b2b33f810a5539d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Jelov=C4=8Dan?= Date: Thu, 29 Dec 2022 16:03:49 +0100 Subject: [PATCH 0308/1522] GPencil: Rename popup on Change active layer -> New Layer This patch adds rename popup when using Y key to switch active layer and choosing New layer in Draw mode. It follows https://developer.blender.org/D15092, which introduced this for moving selected strokes to layers in Edit mode. Reviewed By: antoniov Differential Revision: https://developer.blender.org/D16877 --- .../bl_ui/properties_grease_pencil_common.py | 2 +- source/blender/editors/gpencil/gpencil_data.c | 36 ++++++++++++++++-- source/blender/editors/gpencil/gpencil_edit.c | 37 +++---------------- .../blender/editors/gpencil/gpencil_intern.h | 2 + .../blender/editors/gpencil/gpencil_utils.c | 35 ++++++++++++++++++ 5 files changed, 76 insertions(+), 36 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 3b8da6d0e8d..e70c75a53ca 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -252,7 +252,7 @@ class GPENCIL_MT_layer_active(Menu): gpd = context.gpencil_data if gpd: - layout.operator("gpencil.layer_add", text="New Layer", icon='ADD') + layout.operator("gpencil.layer_add", text="New Layer", icon='ADD').layer = -1 layout.separator() diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 0417694d7bd..8f011f31a7d 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -223,7 +223,17 @@ static int gpencil_layer_add_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); if ((ob != NULL) && (ob->type == OB_GPENCIL)) { gpd = (bGPdata *)ob->data; - bGPDlayer *gpl = BKE_gpencil_layer_addnew(gpd, DATA_("GP_Layer"), true, false); + PropertyRNA *prop; + char name[128]; + prop = RNA_struct_find_property(op->ptr, "new_layer_name"); + if (RNA_property_is_set(op->ptr, prop)) { + RNA_property_string_get(op->ptr, prop, name); + } + else { + strcpy(name, "GP_Layer"); + } + bGPDlayer *gpl = BKE_gpencil_layer_addnew(gpd, name, true, false); + /* Add a new frame to make it visible in Dopesheet. */ if (gpl != NULL) { gpl->actframe = BKE_gpencil_layer_frame_get(gpl, scene->r.cfra, GP_GETFRAME_ADD_NEW); @@ -240,19 +250,37 @@ static int gpencil_layer_add_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } - +static int gpencil_layer_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + int tmp = create_new_layer_dialog(C, op); + if (tmp != 0) { + return tmp; + } + else { + return gpencil_layer_add_exec(C, op); + } +} void GPENCIL_OT_layer_add(wmOperatorType *ot) { + PropertyRNA *prop; /* identifiers */ ot->name = "Add New Layer"; ot->idname = "GPENCIL_OT_layer_add"; ot->description = "Add new layer or note for the active data-block"; - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - /* callbacks */ ot->exec = gpencil_layer_add_exec; + ot->invoke = gpencil_layer_add_invoke; ot->poll = gpencil_add_poll; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + prop = RNA_def_int(ot->srna, "layer", 0, -1, INT_MAX, "Grease Pencil Layer", "", -1, INT_MAX); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + + prop = RNA_def_string( + ot->srna, "new_layer_name", NULL, MAX_NAME, "Name", "Name of the newly added layer"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + ot->prop = prop; } static bool gpencil_add_annotation_poll(bContext *C) diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index f9b40a4c79b..213ff7f7fb4 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -1903,40 +1903,15 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static void layer_new_name_get(bGPdata *gpd, char *rname) -{ - int index = 0; - LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { - if (strstr(gpl->info, "GP_Layer")) { - index++; - } - } - - if (index == 0) { - BLI_strncpy(rname, "GP_Layer", 128); - return; - } - char *name = BLI_sprintfN("%.*s.%03d", 128, "GP_Layer", index); - BLI_strncpy(rname, name, 128); - MEM_freeN(name); -} - static int gpencil_move_to_layer_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - Object *ob = CTX_data_active_object(C); - PropertyRNA *prop; - if (RNA_int_get(op->ptr, "layer") == -1) { - prop = RNA_struct_find_property(op->ptr, "new_layer_name"); - if (!RNA_property_is_set(op->ptr, prop)) { - char name[MAX_NAME]; - bGPdata *gpd = ob->data; - layer_new_name_get(gpd, name); - RNA_property_string_set(op->ptr, prop, name); - return WM_operator_props_dialog_popup(C, op, 200); - } + int tmp = create_new_layer_dialog(C, op); + if (tmp != 0) { + return tmp; + } + else { + return gpencil_move_to_layer_exec(C, op); } - - return gpencil_move_to_layer_exec(C, op); } void GPENCIL_OT_move_to_layer(wmOperatorType *ot) diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 4847e3eabf3..8bdd37a994b 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -368,6 +368,8 @@ bool gpencil_active_layer_poll(struct bContext *C); bool gpencil_active_brush_poll(struct bContext *C); bool gpencil_brush_create_presets_poll(bContext *C); +int create_new_layer_dialog(bContext *C, wmOperator *op); + /* Copy/Paste Buffer --------------------------------- */ /* gpencil_edit.c */ diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index e378c35516e..2116d350482 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -3355,3 +3355,38 @@ void ED_gpencil_layer_merge(bGPdata *gpd, BKE_gpencil_layer_mask_sort(gpd, gpl_dst); } } + +void layer_new_name_get(bGPdata *gpd, char *rname) +{ + int index = 0; + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { + if (strstr(gpl->info, "GP_Layer")) { + index++; + } + } + + if (index == 0) { + BLI_strncpy(rname, "GP_Layer", 128); + return; + } + char *name = BLI_sprintfN("%.*s.%03d", 128, "GP_Layer", index); + BLI_strncpy(rname, name, 128); + MEM_freeN(name); +} + +int create_new_layer_dialog(bContext *C, wmOperator *op) +{ + Object *ob = CTX_data_active_object(C); + PropertyRNA *prop; + if (RNA_int_get(op->ptr, "layer") == -1) { + prop = RNA_struct_find_property(op->ptr, "new_layer_name"); + if (!RNA_property_is_set(op->ptr, prop)) { + char name[MAX_NAME]; + bGPdata *gpd = ob->data; + layer_new_name_get(gpd, name); + RNA_property_string_set(op->ptr, prop, name); + return WM_operator_props_dialog_popup(C, op, 200); + } + } + return 0; +} From 2bd8c67d10906e2d2c933e2241a75f70cfcdfcf9 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Thu, 29 Dec 2022 16:09:37 +0100 Subject: [PATCH 0309/1522] Cleanup: Rename function `create_new_layer_dialog` * Renamed function to include `ED_gpencil_` prefix. * Removed redundant `else`. --- source/blender/editors/gpencil/gpencil_data.c | 6 ++---- source/blender/editors/gpencil/gpencil_edit.c | 6 ++---- source/blender/editors/gpencil/gpencil_intern.h | 2 +- source/blender/editors/gpencil/gpencil_utils.c | 6 +++--- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 8f011f31a7d..5f21ca69baf 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -252,13 +252,11 @@ static int gpencil_layer_add_exec(bContext *C, wmOperator *op) } static int gpencil_layer_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - int tmp = create_new_layer_dialog(C, op); + const int tmp = ED_gpencil_new_layer_dialog(C, op); if (tmp != 0) { return tmp; } - else { - return gpencil_layer_add_exec(C, op); - } + return gpencil_layer_add_exec(C, op); } void GPENCIL_OT_layer_add(wmOperatorType *ot) { diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 213ff7f7fb4..aeed43a34bd 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -1905,13 +1905,11 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op) static int gpencil_move_to_layer_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { - int tmp = create_new_layer_dialog(C, op); + const int tmp = ED_gpencil_new_layer_dialog(C, op); if (tmp != 0) { return tmp; } - else { - return gpencil_move_to_layer_exec(C, op); - } + return gpencil_move_to_layer_exec(C, op); } void GPENCIL_OT_move_to_layer(wmOperatorType *ot) diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h index 8bdd37a994b..0614f2a748a 100644 --- a/source/blender/editors/gpencil/gpencil_intern.h +++ b/source/blender/editors/gpencil/gpencil_intern.h @@ -368,7 +368,7 @@ bool gpencil_active_layer_poll(struct bContext *C); bool gpencil_active_brush_poll(struct bContext *C); bool gpencil_brush_create_presets_poll(bContext *C); -int create_new_layer_dialog(bContext *C, wmOperator *op); +int ED_gpencil_new_layer_dialog(bContext *C, wmOperator *op); /* Copy/Paste Buffer --------------------------------- */ /* gpencil_edit.c */ diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 2116d350482..f91480b72e7 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -3356,7 +3356,7 @@ void ED_gpencil_layer_merge(bGPdata *gpd, } } -void layer_new_name_get(bGPdata *gpd, char *rname) +void gpencil_layer_new_name_get(bGPdata *gpd, char *rname) { int index = 0; LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { @@ -3374,7 +3374,7 @@ void layer_new_name_get(bGPdata *gpd, char *rname) MEM_freeN(name); } -int create_new_layer_dialog(bContext *C, wmOperator *op) +int ED_gpencil_new_layer_dialog(bContext *C, wmOperator *op) { Object *ob = CTX_data_active_object(C); PropertyRNA *prop; @@ -3383,7 +3383,7 @@ int create_new_layer_dialog(bContext *C, wmOperator *op) if (!RNA_property_is_set(op->ptr, prop)) { char name[MAX_NAME]; bGPdata *gpd = ob->data; - layer_new_name_get(gpd, name); + gpencil_layer_new_name_get(gpd, name); RNA_property_string_set(op->ptr, prop, name); return WM_operator_props_dialog_popup(C, op, 200); } From 887105c4c9df5df26f2553f71530c4cce058dddb Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 29 Dec 2022 10:27:27 -0500 Subject: [PATCH 0310/1522] Cleanup: Use inline function for node socket visibility This may very slightly improve performance too, the old function was showing up in profiles when it shouldn't, since it's so small. --- source/blender/blenkernel/BKE_node.h | 1 - source/blender/blenkernel/BKE_node_runtime.hh | 5 +++++ source/blender/blenkernel/intern/node.cc | 7 ++---- .../blenloader/intern/versioning_250.c | 5 +++-- .../blender/editors/space_node/node_draw.cc | 22 +++++++++---------- .../blender/editors/space_node/node_edit.cc | 4 ++-- .../editors/space_node/node_relationships.cc | 8 +++---- source/blender/makesdna/DNA_node_types.h | 1 + source/blender/nodes/intern/node_util.cc | 2 +- 9 files changed, 29 insertions(+), 26 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index d247ee5eea0..266ee0d2988 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -843,7 +843,6 @@ struct bNode *nodeGetActivePaintCanvas(struct bNodeTree *ntree); */ bool nodeSupportsActiveFlag(const struct bNode *node, int sub_active); -int nodeSocketIsHidden(const struct bNodeSocket *sock); void nodeSetSocketAvailability(struct bNodeTree *ntree, struct bNodeSocket *sock, bool is_available); diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 2c9f05c08a6..cedb3a6fd8c 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -680,6 +680,11 @@ inline bool bNodeSocket::is_available() const return (this->flag & SOCK_UNAVAIL) == 0; } +inline bool bNodeSocket::is_visible() const +{ + return !this->is_hidden() && this->is_available(); +} + inline bNode &bNodeSocket::owner_node() { BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this)); diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 097d14ae7b9..8bae267d1b8 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -2443,7 +2443,7 @@ void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock) bool nodeLinkIsHidden(const bNodeLink *link) { - return nodeSocketIsHidden(link->fromsock) || nodeSocketIsHidden(link->tosock); + return !(link->fromsock->is_visible() && link->tosock->is_visible()); } bool nodeLinkIsSelected(const bNodeLink *link) @@ -3555,10 +3555,7 @@ void nodeSetActive(bNodeTree *ntree, bNode *node) node->flag |= flags_to_set; } -int nodeSocketIsHidden(const bNodeSocket *sock) -{ - return ((sock->flag & (SOCK_HIDDEN | SOCK_UNAVAIL)) != 0); -} + void nodeSetSocketAvailability(bNodeTree *ntree, bNodeSocket *sock, bool is_available) { diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 5dd64051881..b01d1917f6d 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -1987,7 +1987,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) /* add ntree->inputs/ntree->outputs sockets for all unlinked sockets in the group tree. */ for (node = ntree->nodes.first; node; node = node->next) { for (sock = node->inputs.first; sock; sock = sock->next) { - if (!sock->link && !nodeSocketIsHidden(sock)) { + if (!sock->link && !((sock->flag & (SOCK_HIDDEN | SOCK_UNAVAIL)) != 0)) { gsock = do_versions_node_group_add_socket_2_56_2( ntree, sock->name, sock->type, SOCK_IN); @@ -2012,7 +2012,8 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) } } for (sock = node->outputs.first; sock; sock = sock->next) { - if (nodeCountSocketLinks(ntree, sock) == 0 && !nodeSocketIsHidden(sock)) { + if (nodeCountSocketLinks(ntree, sock) == 0 && + !((sock->flag & (SOCK_HIDDEN | SOCK_UNAVAIL)) != 0)) { gsock = do_versions_node_group_add_socket_2_56_2( ntree, sock->name, sock->type, SOCK_OUT); diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 4d551557bac..a77b6dd2787 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -351,7 +351,7 @@ static void node_update_basis(const bContext &C, int buty; LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) { - if (nodeSocketIsHidden(socket)) { + if (!socket->is_visible()) { continue; } @@ -474,7 +474,7 @@ static void node_update_basis(const bContext &C, /* Input sockets. */ LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) { - if (nodeSocketIsHidden(socket)) { + if (!socket->is_visible()) { continue; } @@ -567,12 +567,12 @@ static void node_update_hidden(bNode &node, uiBlock &block) /* Calculate minimal radius. */ LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) { - if (!nodeSocketIsHidden(socket)) { + if (socket->is_visible()) { totin++; } } LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) { - if (!nodeSocketIsHidden(socket)) { + if (socket->is_visible()) { totout++; } } @@ -593,7 +593,7 @@ static void node_update_hidden(bNode &node, uiBlock &block) float drad = rad; LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) { - if (!nodeSocketIsHidden(socket)) { + if (socket->is_visible()) { /* Round the socket location to stop it from jiggling. */ socket->runtime->locx = round(node.runtime->totr.xmax - hiddenrad + sinf(rad) * hiddenrad); socket->runtime->locy = round(node.runtime->totr.ymin + hiddenrad + cosf(rad) * hiddenrad); @@ -605,7 +605,7 @@ static void node_update_hidden(bNode &node, uiBlock &block) rad = drad = -float(M_PI) / (1.0f + float(totin)); LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) { - if (!nodeSocketIsHidden(socket)) { + if (socket->is_visible()) { /* Round the socket location to stop it from jiggling. */ socket->runtime->locx = round(node.runtime->totr.xmin + hiddenrad + sinf(rad) * hiddenrad); socket->runtime->locy = round(node.runtime->totr.ymin + hiddenrad + cosf(rad) * hiddenrad); @@ -1429,7 +1429,7 @@ static void node_draw_sockets(const View2D &v2d, /* Socket inputs. */ short selected_input_len = 0; LISTBASE_FOREACH (bNodeSocket *, sock, &node.inputs) { - if (nodeSocketIsHidden(sock)) { + if (!sock->is_visible()) { continue; } if (select_all || (sock->flag & SELECT)) { @@ -1462,7 +1462,7 @@ static void node_draw_sockets(const View2D &v2d, short selected_output_len = 0; if (draw_outputs) { LISTBASE_FOREACH (bNodeSocket *, sock, &node.outputs) { - if (nodeSocketIsHidden(sock)) { + if (!sock->is_visible()) { continue; } if (select_all || (sock->flag & SELECT)) { @@ -1500,7 +1500,7 @@ static void node_draw_sockets(const View2D &v2d, if (selected_input_len) { /* Socket inputs. */ LISTBASE_FOREACH (bNodeSocket *, sock, &node.inputs) { - if (nodeSocketIsHidden(sock)) { + if (!sock->is_visible()) { continue; } /* Don't draw multi-input sockets here since they are drawn in a different batch. */ @@ -1530,7 +1530,7 @@ static void node_draw_sockets(const View2D &v2d, if (selected_output_len) { /* Socket outputs. */ LISTBASE_FOREACH (bNodeSocket *, sock, &node.outputs) { - if (nodeSocketIsHidden(sock)) { + if (!sock->is_visible()) { continue; } if (select_all || (sock->flag & SELECT)) { @@ -1564,7 +1564,7 @@ static void node_draw_sockets(const View2D &v2d, /* Draw multi-input sockets after the others because they are drawn with `UI_draw_roundbox` * rather than with `GL_POINT`. */ LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) { - if (nodeSocketIsHidden(socket)) { + if (!socket->is_visible()) { continue; } if (!(socket->flag & SOCK_MULTI_INPUT)) { diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 9bab9eaa2bf..9849a5385ba 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -1236,7 +1236,7 @@ bool node_find_indicated_socket(SpaceNode &snode, if (in_out & SOCK_IN) { LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { - if (!nodeSocketIsHidden(sock)) { + if (sock->is_visible()) { const float2 location(sock->runtime->locx, sock->runtime->locy); if (sock->flag & SOCK_MULTI_INPUT && !(node->flag & NODE_HIDDEN)) { if (cursor_isect_multi_input_socket(cursor, *sock)) { @@ -1259,7 +1259,7 @@ bool node_find_indicated_socket(SpaceNode &snode, } if (in_out & SOCK_OUT) { LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { - if (!nodeSocketIsHidden(sock)) { + if (sock->is_visible()) { const float2 location(sock->runtime->locx, sock->runtime->locy); if (BLI_rctf_isect_pt(&rect, location.x, location.y)) { if (!socket_is_occluded(location, *node, snode)) { diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 08b054f3d7d..2d136c58edc 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -172,7 +172,7 @@ static void pick_input_link_by_link_intersect(const bContext &C, static bool socket_is_available(bNodeTree * /*ntree*/, bNodeSocket *sock, const bool allow_used) { - if (nodeSocketIsHidden(sock)) { + if (!sock->is_visible()) { return false; } @@ -424,7 +424,7 @@ namespace viewer_linking { /* Depending on the node tree type, different socket types are supported by viewer nodes. */ static bool socket_can_be_viewed(const bNodeSocket &socket) { - if (nodeSocketIsHidden(&socket)) { + if (!socket.is_visible()) { return false; } if (STREQ(socket.idname, "NodeSocketVirtual")) { @@ -2076,7 +2076,7 @@ bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_ int index; LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, sockets, index) { const nodes::SocketDeclaration &socket_decl = *socket_decls[index]; - if (nodeSocketIsHidden(socket)) { + if (!socket->is_visible()) { continue; } if (socket_decl.is_default_link_socket()) { @@ -2097,7 +2097,7 @@ bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_ /* try all priorities, starting from 'highest' */ for (int priority = maxpriority; priority >= 0; priority--) { LISTBASE_FOREACH (bNodeSocket *, sock, sockets) { - if (!nodeSocketIsHidden(sock) && priority == get_main_socket_priority(sock)) { + if (!!sock->is_visible() && priority == get_main_socket_priority(sock)) { return sock; } } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 5a50e53ba98..d46d38a4f87 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -172,6 +172,7 @@ typedef struct bNodeSocket { #ifdef __cplusplus bool is_hidden() const; bool is_available() const; + bool is_visible() const; bool is_multi_input() const; bool is_input() const; bool is_output() const; diff --git a/source/blender/nodes/intern/node_util.cc b/source/blender/nodes/intern/node_util.cc index e3c261d3cc4..73bf20c6836 100644 --- a/source/blender/nodes/intern/node_util.cc +++ b/source/blender/nodes/intern/node_util.cc @@ -311,7 +311,7 @@ static bNodeSocket *node_find_linkable_socket(bNodeTree *ntree, /* Wrap around the list end. */ bNodeSocket *socket_iter = to_socket->next ? to_socket->next : first; while (socket_iter != to_socket) { - if (!nodeSocketIsHidden(socket_iter) && node_link_socket_match(socket_iter, to_socket)) { + if (socket_iter->is_visible() && node_link_socket_match(socket_iter, to_socket)) { const int link_count = node_count_links(ntree, socket_iter); /* Add one to account for the new link being added. */ if (link_count + 1 <= nodeSocketLinkLimit(socket_iter)) { From 47b9ed24090d5badd8a93fd890488afc821530c8 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 29 Dec 2022 10:28:29 -0500 Subject: [PATCH 0311/1522] Cleanup: Rename flag for node socket link status "Is linked" is much clearer than "in use" --- source/blender/blenkernel/intern/node_tree_update.cc | 4 ++-- source/blender/blenloader/intern/versioning_260.c | 12 ++++++------ .../blender/blenloader/intern/versioning_common.cc | 8 ++++---- source/blender/blenloader/intern/versioning_common.h | 2 +- source/blender/blenloader/intern/versioning_cycles.c | 4 ++-- source/blender/editors/space_node/drawnode.cc | 2 +- .../blender/editors/space_node/node_relationships.cc | 2 +- source/blender/makesdna/DNA_node_types.h | 2 +- source/blender/makesrna/intern/rna_nodetree.c | 4 ++-- 9 files changed, 20 insertions(+), 20 deletions(-) diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc index 2750d6ce0c8..d01cbd1d62d 100644 --- a/source/blender/blenkernel/intern/node_tree_update.cc +++ b/source/blender/blenkernel/intern/node_tree_update.cc @@ -523,10 +523,10 @@ class NodeTreeMainUpdater { { tree.ensure_topology_cache(); for (bNodeSocket *socket : tree.all_sockets()) { - socket->flag &= ~SOCK_IN_USE; + socket->flag &= ~SOCK_IS_LINKED; for (const bNodeLink *link : socket->directly_linked_links()) { if (!link->is_muted()) { - socket->flag |= SOCK_IN_USE; + socket->flag |= SOCK_IS_LINKED; break; } } diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c index ad7d08270c2..8cfd66576ff 100644 --- a/source/blender/blenloader/intern/versioning_260.c +++ b/source/blender/blenloader/intern/versioning_260.c @@ -225,22 +225,22 @@ static void do_versions_nodetree_socket_use_flags_2_62(bNodeTree *ntree) for (node = ntree->nodes.first; node; node = node->next) { for (sock = node->inputs.first; sock; sock = sock->next) { - sock->flag &= ~SOCK_IN_USE; + sock->flag &= ~SOCK_IS_LINKED; } for (sock = node->outputs.first; sock; sock = sock->next) { - sock->flag &= ~SOCK_IN_USE; + sock->flag &= ~SOCK_IS_LINKED; } } for (sock = ntree->inputs.first; sock; sock = sock->next) { - sock->flag &= ~SOCK_IN_USE; + sock->flag &= ~SOCK_IS_LINKED; } for (sock = ntree->outputs.first; sock; sock = sock->next) { - sock->flag &= ~SOCK_IN_USE; + sock->flag &= ~SOCK_IS_LINKED; } for (link = ntree->links.first; link; link = link->next) { - link->fromsock->flag |= SOCK_IN_USE; - link->tosock->flag |= SOCK_IN_USE; + link->fromsock->flag |= SOCK_IS_LINKED; + link->tosock->flag |= SOCK_IS_LINKED; } } diff --git a/source/blender/blenloader/intern/versioning_common.cc b/source/blender/blenloader/intern/versioning_common.cc index 0bc3d7ee8ce..7bbcfa8a203 100644 --- a/source/blender/blenloader/intern/versioning_common.cc +++ b/source/blender/blenloader/intern/versioning_common.cc @@ -219,15 +219,15 @@ void version_socket_update_is_used(bNodeTree *ntree) { for (bNode *node : ntree->all_nodes()) { LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) { - socket->flag &= ~SOCK_IN_USE; + socket->flag &= ~SOCK_IS_LINKED; } LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) { - socket->flag &= ~SOCK_IN_USE; + socket->flag &= ~SOCK_IS_LINKED; } } LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { - link->fromsock->flag |= SOCK_IN_USE; - link->tosock->flag |= SOCK_IN_USE; + link->fromsock->flag |= SOCK_IS_LINKED; + link->tosock->flag |= SOCK_IS_LINKED; } } diff --git a/source/blender/blenloader/intern/versioning_common.h b/source/blender/blenloader/intern/versioning_common.h index a8844d076b3..c99fb60be30 100644 --- a/source/blender/blenloader/intern/versioning_common.h +++ b/source/blender/blenloader/intern/versioning_common.h @@ -88,7 +88,7 @@ struct bNodeSocket *version_node_add_socket_if_not_exist(struct bNodeTree *ntree const char *name); /** - * The versioning code generally expects `SOCK_IN_USE` to be set correctly. This function updates + * The versioning code generally expects `SOCK_IS_LINKED` to be set correctly. This function updates * the flag on all sockets after changes to the node tree. */ void version_socket_update_is_used(bNodeTree *ntree); diff --git a/source/blender/blenloader/intern/versioning_cycles.c b/source/blender/blenloader/intern/versioning_cycles.c index 0a9d40e161a..67772140466 100644 --- a/source/blender/blenloader/intern/versioning_cycles.c +++ b/source/blender/blenloader/intern/versioning_cycles.c @@ -40,7 +40,7 @@ static bool socket_is_used(bNodeSocket *sock) { - return sock->flag & SOCK_IN_USE; + return sock->flag & SOCK_IS_LINKED; } static float *cycles_node_socket_float_value(bNodeSocket *socket) @@ -371,7 +371,7 @@ static void light_emission_node_to_energy(Light *light, float *energy, float col bNodeSocket *strength_socket = nodeFindSocket(emission_node, SOCK_IN, "Strength"); bNodeSocket *color_socket = nodeFindSocket(emission_node, SOCK_IN, "Color"); - if ((strength_socket->flag & SOCK_IN_USE) || (color_socket->flag & SOCK_IN_USE)) { + if ((strength_socket->flag & SOCK_IS_LINKED) || (color_socket->flag & SOCK_IS_LINKED)) { return; } diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 16771ef7347..7cca456a46f 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -1293,7 +1293,7 @@ static void std_node_socket_draw( return; } - if ((sock->in_out == SOCK_OUT) || (sock->flag & SOCK_IN_USE) || (sock->flag & SOCK_HIDE_VALUE)) { + if ((sock->in_out == SOCK_OUT) || (sock->flag & SOCK_IS_LINKED) || (sock->flag & SOCK_HIDE_VALUE)) { node_socket_button_label(C, layout, ptr, node_ptr, text); return; } diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 2d136c58edc..222fae7cbc2 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -176,7 +176,7 @@ static bool socket_is_available(bNodeTree * /*ntree*/, bNodeSocket *sock, const return false; } - if (!allow_used && (sock->flag & SOCK_IN_USE)) { + if (!allow_used && (sock->flag & SOCK_IS_LINKED)) { /* Multi input sockets are available (even if used). */ if (!(sock->flag & SOCK_MULTI_INPUT)) { return false; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index d46d38a4f87..cdc69662534 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -256,7 +256,7 @@ typedef enum eNodeSocketFlag { /** Hidden is user defined, to hide unused sockets. */ SOCK_HIDDEN = (1 << 1), /** For quick check if socket is linked. */ - SOCK_IN_USE = (1 << 2), + SOCK_IS_LINKED = (1 << 2), /** Unavailable is for dynamic sockets. */ SOCK_UNAVAIL = (1 << 3), // /** DEPRECATED dynamic socket (can be modified by user) */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index aa42e9422e2..300bca9e369 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2892,7 +2892,7 @@ static void rna_NodeSocket_hide_set(PointerRNA *ptr, bool value) bNodeSocket *sock = (bNodeSocket *)ptr->data; /* don't hide linked sockets */ - if (sock->flag & SOCK_IN_USE) { + if (sock->flag & SOCK_IS_LINKED) { return; } @@ -11057,7 +11057,7 @@ static void rna_def_node_socket(BlenderRNA *brna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, NULL); prop = RNA_def_property(srna, "is_linked", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SOCK_IN_USE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", SOCK_IS_LINKED); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Linked", "True if the socket is connected"); From b6ca942e47730a2ca4ca620e5c82df9f85d8b266 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 29 Dec 2022 16:38:18 +0100 Subject: [PATCH 0312/1522] Functions: support cycles in lazy-function graph Lazy-function graphs are now evaluated properly even if they contain cycles. Note that cycles are only ok if there is no data dependency cycle. For example, a node might output something that is fed back into itself. As long as the output can be computed without the input that it feeds into, everything is ok. The code that builds the graph is responsible for making sure that there are no actual data dependencies. --- source/blender/functions/FN_lazy_function.hh | 38 +++++++++-- .../functions/FN_lazy_function_execute.hh | 3 + .../blender/functions/intern/lazy_function.cc | 14 ++++ .../intern/lazy_function_graph_executor.cc | 14 +++- .../functions/tests/FN_lazy_function_test.cc | 64 +++++++++++++++++++ 5 files changed, 126 insertions(+), 7 deletions(-) diff --git a/source/blender/functions/FN_lazy_function.hh b/source/blender/functions/FN_lazy_function.hh index 4a539e7cbd1..bc85c155c2e 100644 --- a/source/blender/functions/FN_lazy_function.hh +++ b/source/blender/functions/FN_lazy_function.hh @@ -39,6 +39,7 @@ */ #include "BLI_cpp_type.hh" +#include "BLI_function_ref.hh" #include "BLI_generic_pointer.hh" #include "BLI_linear_allocator.hh" #include "BLI_vector.hh" @@ -165,7 +166,8 @@ class Params { * Typed utility methods that wrap the methods above. */ template T extract_input(int index); - template const T &get_input(int index) const; + template T &get_input(int index) const; + template T *try_get_input_data_ptr(int index) const; template T *try_get_input_data_ptr_or_request(int index); template void set_output(int index, T &&value); @@ -253,6 +255,10 @@ class LazyFunction { const char *debug_name_ = ""; Vector inputs_; Vector outputs_; + /** + * Allow executing the function even if previously requested values are not yet available. + */ + bool allow_missing_requested_inputs_ = false; public: virtual ~LazyFunction() = default; @@ -277,6 +283,13 @@ class LazyFunction { */ virtual void destruct_storage(void *storage) const; + /** + * Calls `fn` with the input indices that the given `output_index` may depend on. By default + * every output depends on every input. + */ + virtual void possible_output_dependencies(int output_index, + FunctionRef)> fn) const; + /** * Inputs of the function. */ @@ -298,6 +311,17 @@ class LazyFunction { */ bool always_used_inputs_available(const Params ¶ms) const; + /** + * If true, the function can be executed even when some requested inputs are not available yet. + * This allows the function to make some progress and maybe to compute some outputs that are + * passed into this function again (lazy-function graphs may contain cycles as long as there + * aren't actually data dependencies). + */ + bool allow_missing_requested_inputs() const + { + return allow_missing_requested_inputs_; + } + private: /** * Needs to be implemented by subclasses. This is separate from #execute so that additional @@ -391,11 +415,17 @@ template inline T Params::extract_input(const int index) return return_value; } -template inline const T &Params::get_input(const int index) const +template inline T &Params::get_input(const int index) const { - const void *data = this->try_get_input_data_ptr(index); + void *data = this->try_get_input_data_ptr(index); BLI_assert(data != nullptr); - return *static_cast(data); + return *static_cast(data); +} + +template inline T *Params::try_get_input_data_ptr(const int index) const +{ + this->assert_valid_thread(); + return static_cast(this->try_get_input_data_ptr(index)); } template inline T *Params::try_get_input_data_ptr_or_request(const int index) diff --git a/source/blender/functions/FN_lazy_function_execute.hh b/source/blender/functions/FN_lazy_function_execute.hh index 31bbddf5baf..1d82ac94ee8 100644 --- a/source/blender/functions/FN_lazy_function_execute.hh +++ b/source/blender/functions/FN_lazy_function_execute.hh @@ -93,6 +93,9 @@ inline void execute_lazy_function_eagerly_impl( fn, input_pointers, output_pointers, input_usages, output_usages, set_outputs}; fn.execute(params, context); fn.destruct_storage(context.storage); + + /* Make sure all outputs have been computed. */ + BLI_assert(!Span(set_outputs).contains(false)); } } // namespace detail diff --git a/source/blender/functions/intern/lazy_function.cc b/source/blender/functions/intern/lazy_function.cc index f1c53a04b3f..d42b1889160 100644 --- a/source/blender/functions/intern/lazy_function.cc +++ b/source/blender/functions/intern/lazy_function.cc @@ -36,8 +36,22 @@ void LazyFunction::destruct_storage(void *storage) const UNUSED_VARS_NDEBUG(storage); } +void LazyFunction::possible_output_dependencies(const int /*output_index*/, + const FunctionRef)> fn) const +{ + /* The output depends on all inputs by default. */ + Vector indices(inputs_.size()); + for (const int i : inputs_.index_range()) { + indices[i] = i; + } + fn(indices); +} + bool LazyFunction::always_used_inputs_available(const Params ¶ms) const { + if (allow_missing_requested_inputs_) { + return true; + } for (const int i : inputs_.index_range()) { const Input &fn_input = inputs_[i]; if (fn_input.usage == ValueUsage::Used) { diff --git a/source/blender/functions/intern/lazy_function_graph_executor.cc b/source/blender/functions/intern/lazy_function_graph_executor.cc index a5764e23468..21040bd4550 100644 --- a/source/blender/functions/intern/lazy_function_graph_executor.cc +++ b/source/blender/functions/intern/lazy_function_graph_executor.cc @@ -762,8 +762,10 @@ class Executor { input_state.was_ready_for_execution = true; continue; } - if (input_state.usage == ValueUsage::Used) { - return; + if (!fn.allow_missing_requested_inputs()) { + if (input_state.usage == ValueUsage::Used) { + return; + } } } @@ -1031,7 +1033,10 @@ class Executor { if (input_state.usage == ValueUsage::Used) { node_state.missing_required_inputs -= 1; - if (node_state.missing_required_inputs == 0) { + if (node_state.missing_required_inputs == 0 || + (locked_node.node.is_function() && static_cast(locked_node.node) + .function() + .allow_missing_requested_inputs())) { this->schedule_node(locked_node, current_task); } } @@ -1248,6 +1253,9 @@ GraphExecutor::GraphExecutor(const Graph &graph, logger_(logger), side_effect_provider_(side_effect_provider) { + /* The graph executor can handle partial execution when there are still missing inputs. */ + allow_missing_requested_inputs_ = true; + for (const OutputSocket *socket : graph_inputs_) { BLI_assert(socket->node().is_dummy()); inputs_.append({"In", socket->type(), ValueUsage::Maybe}); diff --git a/source/blender/functions/tests/FN_lazy_function_test.cc b/source/blender/functions/tests/FN_lazy_function_test.cc index dc1c698598d..54e1df00cdf 100644 --- a/source/blender/functions/tests/FN_lazy_function_test.cc +++ b/source/blender/functions/tests/FN_lazy_function_test.cc @@ -112,4 +112,68 @@ TEST(lazy_function, SideEffects) EXPECT_EQ(dst2, 105); } +class PartialEvaluationTestFunction : public LazyFunction { + public: + PartialEvaluationTestFunction() + { + debug_name_ = "Partial Evaluation"; + allow_missing_requested_inputs_ = true; + + inputs_.append_as("A", CPPType::get(), ValueUsage::Used); + inputs_.append_as("B", CPPType::get(), ValueUsage::Used); + + outputs_.append_as("A*2", CPPType::get()); + outputs_.append_as("B*5", CPPType::get()); + } + + void execute_impl(Params ¶ms, const Context & /*context*/) const override + { + if (!params.output_was_set(0)) { + if (int *a = params.try_get_input_data_ptr(0)) { + params.set_output(0, *a * 2); + } + } + if (!params.output_was_set(1)) { + if (int *b = params.try_get_input_data_ptr(1)) { + params.set_output(1, *b * 5); + } + } + } + + void possible_output_dependencies(const int output_index, + FunctionRef)> fn) const override + { + /* Each output only depends on the input with the same index. */ + const int input_index = output_index; + fn({input_index}); + } +}; + +TEST(lazy_function, GraphWithCycle) +{ + const PartialEvaluationTestFunction fn; + + Graph graph; + FunctionNode &fn_node = graph.add_function(fn); + + DummyNode &input_node = graph.add_dummy({}, {&CPPType::get()}); + DummyNode &output_node = graph.add_dummy({&CPPType::get()}, {}); + + graph.add_link(input_node.output(0), fn_node.input(0)); + /* Note: This creates a cycle in the graph. However, it should still be possible to evaluate it, + * because there is no actual data dependency in the cycle. */ + graph.add_link(fn_node.output(0), fn_node.input(1)); + graph.add_link(fn_node.output(1), output_node.input(0)); + + graph.update_node_indices(); + + GraphExecutor executor_fn{ + graph, {&input_node.output(0)}, {&output_node.input(0)}, nullptr, nullptr}; + int result = 0; + execute_lazy_function_eagerly( + executor_fn, nullptr, std::make_tuple(10), std::make_tuple(&result)); + + EXPECT_EQ(result, 10 * 2 * 5); +} + } // namespace blender::fn::lazy_function::tests From 31f22426915947f09751af8b5b92a2484de42163 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 29 Dec 2022 10:58:47 -0500 Subject: [PATCH 0313/1522] Fix T103520: Incorrect selection in paint mode operators Read the selection attribute on the proper domain using implicit interpolation rather than just using its oiginal domain that might not match the domain of the color attribute. --- source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc index bb8a298503c..49fbff114f1 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex_color_ops.cc @@ -161,13 +161,13 @@ static IndexMask get_selected_indices(const Mesh &mesh, if (mesh.editflag & ME_EDIT_PAINT_FACE_SEL) { const VArray selection = attributes.lookup_or_default( - ".select_poly", ATTR_DOMAIN_FACE, false); + ".select_poly", domain, false); return index_mask_ops::find_indices_from_virtual_array( selection.index_range(), selection, 4096, indices); } if (mesh.editflag & ME_EDIT_PAINT_VERT_SEL) { const VArray selection = attributes.lookup_or_default( - ".select_vert", ATTR_DOMAIN_POINT, false); + ".select_vert", domain, false); return index_mask_ops::find_indices_from_virtual_array( selection.index_range(), selection, 4096, indices); } From 2652029f3beee160695194b825a4c0c11dd9f680 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 29 Dec 2022 12:01:32 -0500 Subject: [PATCH 0314/1522] Cleanup: Clang tidy Addressed almost all warnings except for replacing defines with enums and variable assignment in if statements. --- .../blendthumb/src/blender_thumbnailer.cc | 2 +- .../blenkernel/intern/data_transfer.cc | 2 +- source/blender/blenkernel/intern/key.cc | 10 +- source/blender/blenkernel/intern/layer.cc | 58 +++---- source/blender/blenkernel/intern/linestyle.cc | 6 +- source/blender/blenkernel/intern/material.cc | 12 +- .../blenkernel/intern/mesh_legacy_convert.cc | 4 +- .../blender/blenkernel/intern/mesh_mirror.cc | 4 +- source/blender/blenkernel/intern/multires.cc | 6 +- .../blender/blenkernel/intern/object_dupli.cc | 6 +- .../blenkernel/intern/pbvh_uv_islands.cc | 7 +- .../blenkernel/intern/pbvh_uv_islands.hh | 4 +- .../blender/blenkernel/intern/shrinkwrap.cc | 4 +- source/blender/blenkernel/intern/texture.cc | 8 +- source/blender/blenlib/BLI_blenlib.h | 2 +- source/blender/blenlib/intern/listbase.cc | 4 +- source/blender/blenloader/intern/undofile.cc | 10 +- .../draw/engines/overlay/overlay_shader.cc | 10 +- .../draw/intern/draw_cache_impl_gpencil.cc | 42 ++--- source/blender/editors/gpencil/gpencil_fill.c | 2 +- .../editors/interface/interface_handlers.cc | 8 +- .../editors/interface/interface_icons.cc | 157 +++++++++--------- .../editors/interface/interface_layout.cc | 38 ++--- .../editors/interface/interface_query.cc | 2 +- .../editors/interface/interface_style.cc | 2 +- .../editors/interface/interface_templates.cc | 4 +- .../editors/interface/interface_undo.cc | 2 +- .../editors/interface/interface_widgets.cc | 18 +- .../editors/sculpt_paint/paint_cursor.cc | 33 ++-- .../editors/sculpt_paint/paint_image_proj.cc | 121 +++++++------- .../editors/space_buttons/buttons_texture.cc | 4 +- .../editors/space_clip/tracking_ops_orient.cc | 71 ++++---- source/blender/editors/space_file/filelist.cc | 78 ++++----- .../blender/editors/space_node/node_draw.cc | 12 +- .../editors/space_outliner/outliner_ops.cc | 2 +- .../editors/transform/transform_snap.cc | 8 +- source/blender/editors/util/ed_util.c | 2 +- .../intern/python/BPy_ContextFunctions.cpp | 8 +- .../freestyle/intern/python/BPy_Freestyle.cpp | 8 +- .../intern/python/BPy_IntegrationType.cpp | 8 +- .../freestyle/intern/python/BPy_Nature.cpp | 4 +- .../intern/lineart/MOD_lineart.h | 9 +- .../intern/lineart/lineart_cpu.cc | 64 +++---- source/blender/gpu/GPU_texture.h | 14 +- source/blender/gpu/intern/gpu_node_graph.cc | 6 +- source/blender/gpu/intern/gpu_node_graph.h | 2 +- source/blender/gpu/opengl/gl_state.cc | 6 +- source/blender/gpu/opengl/gl_texture.cc | 8 +- source/blender/imbuf/IMB_thumbs.h | 2 +- source/blender/makesrna/intern/rna_ui_api.c | 6 +- .../makesrna/intern/rna_wm_gizmo_api.c | 2 +- .../blender/modifiers/intern/MOD_displace.cc | 16 +- source/blender/modifiers/intern/MOD_screw.cc | 16 +- .../modifiers/intern/MOD_triangulate.cc | 2 +- source/blender/modifiers/intern/MOD_util.cc | 2 +- .../intern/geometry_nodes_lazy_function.cc | 2 +- source/blender/nodes/intern/node_util.cc | 6 +- .../nodes/texture/node_texture_tree.cc | 4 +- .../nodes/texture/nodes/node_texture_at.cc | 2 +- .../texture/nodes/node_texture_bricks.cc | 4 +- .../texture/nodes/node_texture_checker.cc | 4 +- .../nodes/node_texture_combine_color.cc | 2 +- .../texture/nodes/node_texture_compose.cc | 2 +- .../nodes/texture/nodes/node_texture_coord.cc | 2 +- .../texture/nodes/node_texture_curves.cc | 4 +- .../texture/nodes/node_texture_decompose.cc | 4 +- .../texture/nodes/node_texture_hueSatVal.cc | 2 +- .../nodes/texture/nodes/node_texture_image.cc | 2 +- .../texture/nodes/node_texture_invert.cc | 2 +- .../nodes/texture/nodes/node_texture_math.cc | 2 +- .../texture/nodes/node_texture_rotate.cc | 4 +- .../nodes/texture/nodes/node_texture_scale.cc | 4 +- .../nodes/node_texture_separate_color.cc | 4 +- source/blender/render/intern/bake.cc | 20 +-- source/blender/render/intern/engine.cc | 1 - source/blender/render/intern/multires_bake.cc | 62 +++---- .../blender/windowmanager/intern/wm_keymap.c | 2 +- 77 files changed, 542 insertions(+), 547 deletions(-) diff --git a/source/blender/blendthumb/src/blender_thumbnailer.cc b/source/blender/blendthumb/src/blender_thumbnailer.cc index 93a3d1530fc..807878c8233 100644 --- a/source/blender/blendthumb/src/blender_thumbnailer.cc +++ b/source/blender/blendthumb/src/blender_thumbnailer.cc @@ -73,7 +73,7 @@ static eThumbStatus extract_png_from_blend_file(const char *src_blend, const cha std::optional> png_buf_opt = blendthumb_create_png_data_from_thumb( &thumb); - if (png_buf_opt == std::nullopt) { + if (!png_buf_opt) { err = BT_ERROR; } else { diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index 2c9ff52e0a4..4220d106095 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -1258,7 +1258,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, float *weights[DATAMAX] = {nullptr}; MeshPairRemap geom_map[DATAMAX] = {{0}}; - bool geom_map_init[DATAMAX] = {0}; + bool geom_map_init[DATAMAX] = {false}; ListBase lay_map = {nullptr}; bool changed = false; bool is_modifier = false; diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 388dcff5229..e0af320ac48 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -5,9 +5,9 @@ * \ingroup bke */ -#include -#include -#include +#include +#include +#include #include "MEM_guardedalloc.h" @@ -231,10 +231,10 @@ IDTypeInfo IDType_ID_KE = { #define KEY_MODE_BEZTRIPLE 2 /* Internal use only. */ -typedef struct WeightsArrayCache { +struct WeightsArrayCache { int num_defgroup_weights; float **defgroup_weights; -} WeightsArrayCache; +}; void BKE_key_free_data(Key *key) { diff --git a/source/blender/blenkernel/intern/layer.cc b/source/blender/blenkernel/intern/layer.cc index 971cf85812a..198ad5b196f 100644 --- a/source/blender/blenkernel/intern/layer.cc +++ b/source/blender/blenkernel/intern/layer.cc @@ -7,7 +7,7 @@ /* Allow using deprecated functionality for .blend file I/O. */ #define DNA_DEPRECATED_ALLOW -#include +#include #include "CLG_log.h" @@ -400,7 +400,7 @@ void BKE_view_layer_base_deselect_all(const Scene *scene, ViewLayer *view_layer) } } -void BKE_view_layer_base_select_and_set_active(struct ViewLayer *view_layer, Base *selbase) +void BKE_view_layer_base_select_and_set_active(ViewLayer *view_layer, Base *selbase) { view_layer->basact = selbase; if ((selbase->flag & BASE_SELECTABLE) != 0) { @@ -780,12 +780,12 @@ void BKE_layer_collection_resync_allow(void) no_resync = false; } -typedef struct LayerCollectionResync { - struct LayerCollectionResync *prev, *next; +struct LayerCollectionResync { + LayerCollectionResync *prev, *next; /* Temp data used to generate a queue during valid layer search. See * #layer_collection_resync_find. */ - struct LayerCollectionResync *queue_next; + LayerCollectionResync *queue_next; /* LayerCollection and Collection wrapped by this data. */ LayerCollection *layer; @@ -793,7 +793,7 @@ typedef struct LayerCollectionResync { /* Hierarchical relationships in the old, existing ViewLayer state (except for newly created * layers). */ - struct LayerCollectionResync *parent_layer_resync; + LayerCollectionResync *parent_layer_resync; ListBase children_layer_resync; /* This layer still points to a valid collection. */ @@ -809,7 +809,7 @@ typedef struct LayerCollectionResync { * OR * This layer has already been re-used to match the new collections hierarchy. */ bool is_used; -} LayerCollectionResync; +}; static LayerCollectionResync *layer_collection_resync_create_recurse( LayerCollectionResync *parent_layer_resync, LayerCollection *layer, BLI_mempool *mempool) @@ -969,12 +969,12 @@ static void layer_collection_resync_unused_layers_free(ViewLayer *view_layer, } } -void BKE_view_layer_need_resync_tag(struct ViewLayer *view_layer) +void BKE_view_layer_need_resync_tag(ViewLayer *view_layer) { view_layer->flag |= VIEW_LAYER_OUT_OF_SYNC; } -void BKE_view_layer_synced_ensure(const Scene *scene, struct ViewLayer *view_layer) +void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer) { if (view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) { BKE_layer_collection_sync(scene, view_layer); @@ -1599,7 +1599,7 @@ bool BKE_base_is_visible(const View3D *v3d, const Base *base) return base->flag & BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT; } -bool BKE_object_is_visible_in_viewport(const View3D *v3d, const struct Object *ob) +bool BKE_object_is_visible_in_viewport(const View3D *v3d, const Object *ob) { BLI_assert(v3d != nullptr); @@ -1988,10 +1988,10 @@ bool BKE_scene_has_object(Scene *scene, Object *ob) /** \name Private Iterator Helpers * \{ */ -typedef struct LayerObjectBaseIteratorData { +struct LayerObjectBaseIteratorData { const View3D *v3d; Base *base; -} LayerObjectBaseIteratorData; +}; static bool object_bases_iterator_is_valid(const View3D *v3d, Base *base, const int flag) { @@ -2207,7 +2207,7 @@ void BKE_view_layer_visible_bases_iterator_end(BLI_Iterator *iter) /** \name BKE_view_layer_bases_in_mode_iterator * \{ */ -static bool base_is_in_mode(struct ObjectsInModeIteratorData *data, Base *base) +static bool base_is_in_mode(ObjectsInModeIteratorData *data, Base *base) { return (base->object->type == data->object_type) && (base->object->mode & data->object_mode) != 0; @@ -2215,7 +2215,7 @@ static bool base_is_in_mode(struct ObjectsInModeIteratorData *data, Base *base) void BKE_view_layer_bases_in_mode_iterator_begin(BLI_Iterator *iter, void *data_in) { - struct ObjectsInModeIteratorData *data = static_cast(data_in); + ObjectsInModeIteratorData *data = static_cast(data_in); Base *base = data->base_active; /* In this case the result will always be empty, the caller must check for no mode. */ @@ -2241,7 +2241,7 @@ void BKE_view_layer_bases_in_mode_iterator_begin(BLI_Iterator *iter, void *data_ void BKE_view_layer_bases_in_mode_iterator_next(BLI_Iterator *iter) { - struct ObjectsInModeIteratorData *data = static_cast(iter->data); + ObjectsInModeIteratorData *data = static_cast(iter->data); Base *base = static_cast(iter->current); if (base == data->base_active) { @@ -2309,9 +2309,7 @@ void BKE_base_eval_flags(Base *base) } } -static void layer_eval_view_layer(struct Depsgraph *depsgraph, - struct Scene *scene, - ViewLayer *view_layer) +static void layer_eval_view_layer(Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer) { DEG_debug_print_eval(depsgraph, __func__, view_layer->name, view_layer); @@ -2327,9 +2325,7 @@ static void layer_eval_view_layer(struct Depsgraph *depsgraph, } } -void BKE_layer_eval_view_layer_indexed(struct Depsgraph *depsgraph, - struct Scene *scene, - int view_layer_index) +void BKE_layer_eval_view_layer_indexed(Depsgraph *depsgraph, Scene *scene, int view_layer_index) { BLI_assert(view_layer_index >= 0); ViewLayer *view_layer = static_cast( @@ -2502,7 +2498,7 @@ static void viewlayer_aov_active_set(ViewLayer *view_layer, ViewLayerAOV *aov) } } -struct ViewLayerAOV *BKE_view_layer_add_aov(struct ViewLayer *view_layer) +ViewLayerAOV *BKE_view_layer_add_aov(ViewLayer *view_layer) { ViewLayerAOV *aov; aov = MEM_cnew(__func__); @@ -2557,9 +2553,7 @@ static void bke_view_layer_verify_aov_cb(void *userdata, } } -void BKE_view_layer_verify_aov(struct RenderEngine *engine, - struct Scene *scene, - struct ViewLayer *view_layer) +void BKE_view_layer_verify_aov(RenderEngine *engine, Scene *scene, ViewLayer *view_layer) { viewlayer_aov_make_name_unique(view_layer); @@ -2584,7 +2578,7 @@ bool BKE_view_layer_has_valid_aov(ViewLayer *view_layer) return false; } -ViewLayer *BKE_view_layer_find_with_aov(struct Scene *scene, struct ViewLayerAOV *aov) +ViewLayer *BKE_view_layer_find_with_aov(Scene *scene, ViewLayerAOV *aov) { LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { if (BLI_findindex(&view_layer->aovs, aov) != -1) { @@ -2625,8 +2619,7 @@ static void viewlayer_lightgroup_active_set(ViewLayer *view_layer, ViewLayerLigh } } -struct ViewLayerLightgroup *BKE_view_layer_add_lightgroup(struct ViewLayer *view_layer, - const char *name) +ViewLayerLightgroup *BKE_view_layer_add_lightgroup(ViewLayer *view_layer, const char *name) { ViewLayerLightgroup *lightgroup; lightgroup = MEM_cnew(__func__); @@ -2662,8 +2655,7 @@ void BKE_view_layer_set_active_lightgroup(ViewLayer *view_layer, ViewLayerLightg viewlayer_lightgroup_active_set(view_layer, lightgroup); } -ViewLayer *BKE_view_layer_find_with_lightgroup(struct Scene *scene, - struct ViewLayerLightgroup *lightgroup) +ViewLayer *BKE_view_layer_find_with_lightgroup(Scene *scene, ViewLayerLightgroup *lightgroup) { LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { if (BLI_findindex(&view_layer->lightgroups, lightgroup) != -1) { @@ -2706,7 +2698,7 @@ void BKE_view_layer_rename_lightgroup(Scene *scene, } } -void BKE_lightgroup_membership_get(struct LightgroupMembership *lgm, char *name) +void BKE_lightgroup_membership_get(LightgroupMembership *lgm, char *name) { if (lgm != nullptr) { BLI_strncpy(name, lgm->name, sizeof(lgm->name)); @@ -2716,7 +2708,7 @@ void BKE_lightgroup_membership_get(struct LightgroupMembership *lgm, char *name) } } -int BKE_lightgroup_membership_length(struct LightgroupMembership *lgm) +int BKE_lightgroup_membership_length(LightgroupMembership *lgm) { if (lgm != nullptr) { return strlen(lgm->name); @@ -2724,7 +2716,7 @@ int BKE_lightgroup_membership_length(struct LightgroupMembership *lgm) return 0; } -void BKE_lightgroup_membership_set(struct LightgroupMembership **lgm, const char *name) +void BKE_lightgroup_membership_set(LightgroupMembership **lgm, const char *name) { if (name[0] != '\0') { if (*lgm == nullptr) { diff --git a/source/blender/blenkernel/intern/linestyle.cc b/source/blender/blenkernel/intern/linestyle.cc index 3040f0f5cd5..3976331d599 100644 --- a/source/blender/blenkernel/intern/linestyle.cc +++ b/source/blender/blenkernel/intern/linestyle.cc @@ -5,9 +5,9 @@ * \ingroup bke */ -#include -#include -#include +#include +#include +#include #include "MEM_guardedalloc.h" diff --git a/source/blender/blenkernel/intern/material.cc b/source/blender/blenkernel/intern/material.cc index 0eb0209cc44..58478dce847 100644 --- a/source/blender/blenkernel/intern/material.cc +++ b/source/blender/blenkernel/intern/material.cc @@ -5,9 +5,9 @@ * \ingroup bke */ -#include -#include -#include +#include +#include +#include #include "CLG_log.h" @@ -1374,13 +1374,13 @@ static bNode *nodetree_uv_node_recursive(bNode *node) } /** Bitwise filter for updating paint slots. */ -typedef enum ePaintSlotFilter { +enum ePaintSlotFilter { PAINT_SLOT_IMAGE = 1 << 0, PAINT_SLOT_COLOR_ATTRIBUTE = 1 << 1, -} ePaintSlotFilter; +}; ENUM_OPERATORS(ePaintSlotFilter, PAINT_SLOT_COLOR_ATTRIBUTE) -typedef bool (*ForEachTexNodeCallback)(bNode *node, void *userdata); +using ForEachTexNodeCallback = bool (*)(bNode *node, void *userdata); static bool ntree_foreach_texnode_recursive(bNodeTree *nodetree, ForEachTexNodeCallback callback, void *userdata, diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 5c9c74c6dc8..7d4f0f8f7f8 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -545,12 +545,12 @@ static void update_active_fdata_layers(Mesh &mesh, CustomData *fdata, CustomData } if (CustomData_has_layer(ldata, CD_PROP_BYTE_COLOR)) { - if (mesh.active_color_attribute != NULL) { + if (mesh.active_color_attribute != nullptr) { act = CustomData_get_named_layer(ldata, CD_PROP_BYTE_COLOR, mesh.active_color_attribute); CustomData_set_layer_active(fdata, CD_MCOL, act); } - if (mesh.default_color_attribute != NULL) { + if (mesh.default_color_attribute != nullptr) { act = CustomData_get_named_layer(ldata, CD_PROP_BYTE_COLOR, mesh.default_color_attribute); CustomData_set_layer_render(fdata, CD_MCOL, act); } diff --git a/source/blender/blenkernel/intern/mesh_mirror.cc b/source/blender/blenkernel/intern/mesh_mirror.cc index 26a84d4d2b9..7d875ba799b 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.cc +++ b/source/blender/blenkernel/intern/mesh_mirror.cc @@ -42,7 +42,7 @@ Mesh *BKE_mesh_mirror_bisect_on_mirror_plane_for_modifier(MirrorModifierData *mm BMIter viter; BMVert *v, *v_next; - BMeshCreateParams bmesh_create_params{0}; + BMeshCreateParams bmesh_create_params{false}; BMeshFromMeshParams bmesh_from_mesh_params{}; bmesh_from_mesh_params.calc_face_normal = true; @@ -89,7 +89,7 @@ void BKE_mesh_mirror_apply_mirror_on_axis(struct Main *bmain, const float dist) { BMeshCreateParams bmesh_create_params{}; - bmesh_create_params.use_toolflags = 1; + bmesh_create_params.use_toolflags = true; BMeshFromMeshParams bmesh_from_mesh_params{}; bmesh_from_mesh_params.calc_face_normal = true; diff --git a/source/blender/blenkernel/intern/multires.cc b/source/blender/blenkernel/intern/multires.cc index 8ba8b657a16..aca392d7c19 100644 --- a/source/blender/blenkernel/intern/multires.cc +++ b/source/blender/blenkernel/intern/multires.cc @@ -500,7 +500,7 @@ static int get_levels_from_disps(Object *ob) continue; } - while (1) { + while (true) { int side = (1 << (totlvl - 1)) + 1; int lvl_totdisp = side * side; if (md->totdisp == lvl_totdisp) { @@ -1079,7 +1079,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene) cddm, totlvl, false, - 0, + false, mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE, has_mask, false, @@ -1156,7 +1156,7 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm, Scene *scene) cddm, mmd->totlvl, false, - 0, + false, mmd->uv_smooth == SUBSURF_UV_SMOOTH_NONE, has_mask, false, diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index 16efa05d3e2..e7f62c339cd 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -1784,10 +1784,8 @@ ListBase *object_duplilist_preview(Depsgraph *depsgraph, if (nmd_orig->runtime_eval_log == nullptr) { continue; } - geo_log::GeoModifierLog *log = static_cast( - nmd_orig->runtime_eval_log); - if (const geo_log::ViewerNodeLog *viewer_log = log->find_viewer_node_log_for_path( - *viewer_path)) { + if (const geo_log::ViewerNodeLog *viewer_log = + geo_log::GeoModifierLog::find_viewer_node_log_for_path(*viewer_path)) { ctx.preview_base_geometry = &viewer_log->geometry; make_duplis_geometry_set_impl( &ctx, viewer_log->geometry, ob_eval->object_to_world, true, ob_eval->type == OB_CURVES); diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index 21645e50e7e..2f04ae63df4 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -67,7 +67,7 @@ static const MeshUVVert &get_uv_vert(const MeshPrimitive &mesh_primitive, const return mesh_primitive.vertices[0]; } -static const bool has_vertex(const MeshPrimitive &mesh_primitive, const MeshVertex &mesh_vertex) +static bool has_vertex(const MeshPrimitive &mesh_primitive, const MeshVertex &mesh_vertex) { for (int i = 0; i < 3; i++) { if (mesh_primitive.vertices[i].vertex == &mesh_vertex) { @@ -1162,7 +1162,7 @@ UVEdge *UVPrimitive::get_uv_edge(const MeshVertex *v1, const MeshVertex *v2) con return nullptr; } -const bool UVPrimitive::contains_uv_vertex(const UVVertex *uv_vertex) const +bool UVPrimitive::contains_uv_vertex(const UVVertex *uv_vertex) const { for (UVEdge *edge : edges) { if (std::find(edge->vertices.begin(), edge->vertices.end(), uv_vertex) != @@ -1303,7 +1303,7 @@ static void add_uv_island(UVIslandsMask::Tile &tile, const UVIsland &uv_island, int16_t island_index) { - for (const VectorList::UsedVector &uv_primitives : uv_island.uv_primitives) + for (const VectorList::UsedVector &uv_primitives : uv_island.uv_primitives) { for (const UVPrimitive &uv_primitive : uv_primitives) { const MeshPrimitive *mesh_primitive = uv_primitive.primitive; @@ -1338,6 +1338,7 @@ static void add_uv_island(UVIslandsMask::Tile &tile, } } } + } } void UVIslandsMask::add(const UVIslands &uv_islands) diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.hh b/source/blender/blenkernel/intern/pbvh_uv_islands.hh index 4d81f5da00c..7774c43609c 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.hh +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.hh @@ -168,7 +168,7 @@ struct UVPrimitive { UVEdge *get_uv_edge(const float2 uv1, const float2 uv2) const; UVEdge *get_uv_edge(const MeshVertex *v1, const MeshVertex *v2) const; - const bool contains_uv_vertex(const UVVertex *uv_vertex) const; + bool contains_uv_vertex(const UVVertex *uv_vertex) const; const UVVertex *get_other_uv_vertex(const UVVertex *v1, const UVVertex *v2) const; UVBorder extract_border() const; @@ -232,7 +232,7 @@ struct UVBorder { /** * Calculate the outside angle of the given vert. */ - float outside_angle(const UVBorderEdge &vert) const; + float outside_angle(const UVBorderEdge &edge) const; void update_indexes(uint64_t border_index); diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index b8288160b82..d196f044c58 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -1525,7 +1525,7 @@ void BKE_shrinkwrap_mesh_nearest_surface_deform(bContext *C, Object *ob_source, { Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); Scene *sce = CTX_data_scene(C); - ShrinkwrapModifierData ssmd = {{0}}; + ShrinkwrapModifierData ssmd = {{nullptr}}; ModifierEvalContext ctx = {depsgraph, ob_source, ModifierApplyFlag(0)}; int totvert; @@ -1546,7 +1546,7 @@ void BKE_shrinkwrap_mesh_nearest_surface_deform(bContext *C, Object *ob_source, void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object *ob_target) { - ShrinkwrapModifierData ssmd = {{0}}; + ShrinkwrapModifierData ssmd = {{nullptr}}; int totvert; ssmd.target = ob_target; diff --git a/source/blender/blenkernel/intern/texture.cc b/source/blender/blenkernel/intern/texture.cc index 1fb4fdf3d83..d2cecb372a0 100644 --- a/source/blender/blenkernel/intern/texture.cc +++ b/source/blender/blenkernel/intern/texture.cc @@ -5,10 +5,10 @@ * \ingroup bke */ -#include -#include -#include -#include +#include +#include +#include +#include #include "MEM_guardedalloc.h" diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h index 2a78a990a2a..e7f7b575166 100644 --- a/source/blender/blenlib/BLI_blenlib.h +++ b/source/blender/blenlib/BLI_blenlib.h @@ -4,7 +4,7 @@ /** \file * \ingroup bli * - * \section aboutbli Blender LIbrary external interface + * \section aboutbli Blender Library external interface * * \subsection about About the BLI module * diff --git a/source/blender/blenlib/intern/listbase.cc b/source/blender/blenlib/intern/listbase.cc index ee0c6fcd5c3..0d5f2d2537a 100644 --- a/source/blender/blenlib/intern/listbase.cc +++ b/source/blender/blenlib/intern/listbase.cc @@ -9,8 +9,8 @@ * For single linked lists see 'BLI_linklist.h' */ -#include -#include +#include +#include #include "MEM_guardedalloc.h" diff --git a/source/blender/blenloader/intern/undofile.cc b/source/blender/blenloader/intern/undofile.cc index 99d1ca336fe..5db5b465b96 100644 --- a/source/blender/blenloader/intern/undofile.cc +++ b/source/blender/blenloader/intern/undofile.cc @@ -5,12 +5,12 @@ * \ingroup blenloader */ -#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include /* open/close */ #ifndef _WIN32 diff --git a/source/blender/draw/engines/overlay/overlay_shader.cc b/source/blender/draw/engines/overlay/overlay_shader.cc index b7e5e8c56b7..9e33d713a9a 100644 --- a/source/blender/draw/engines/overlay/overlay_shader.cc +++ b/source/blender/draw/engines/overlay/overlay_shader.cc @@ -13,7 +13,7 @@ #include "overlay_private.hh" -typedef struct OVERLAY_Shaders { +struct OVERLAY_Shaders { GPUShader *antialiasing; GPUShader *armature_dof_wire; GPUShader *armature_dof_solid; @@ -107,7 +107,7 @@ typedef struct OVERLAY_Shaders { GPUShader *wireframe_select; GPUShader *wireframe[2]; GPUShader *xray_fade; -} OVERLAY_Shaders; +}; static struct { OVERLAY_Shaders sh_data[GPU_SHADER_CFG_LEN]; @@ -555,7 +555,7 @@ GPUShader *OVERLAY_shader_gpencil_canvas(void) /* TODO(fclem): Support Clipping? Everything is already setup but don't want to change behavior * without agreement of all gpencil module. */ sh_data->gpencil_canvas = GPU_shader_create_from_info_name( - 0 ? "overlay_gpencil_canvas_clipped" : "overlay_gpencil_canvas"); + false ? "overlay_gpencil_canvas_clipped" : "overlay_gpencil_canvas"); } return sh_data->gpencil_canvas; } @@ -612,8 +612,8 @@ GPUShader *OVERLAY_shader_image(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->image) { /* TODO(fclem): Do we want to allow clipping reference images? */ - sh_data->image = GPU_shader_create_from_info_name(0 ? "overlay_image_clipped" : - "overlay_image"); + sh_data->image = GPU_shader_create_from_info_name(false ? "overlay_image_clipped" : + "overlay_image"); } return sh_data->image; } diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.cc b/source/blender/draw/intern/draw_cache_impl_gpencil.cc index b7fc315595d..16e90994791 100644 --- a/source/blender/draw/intern/draw_cache_impl_gpencil.cc +++ b/source/blender/draw/intern/draw_cache_impl_gpencil.cc @@ -39,7 +39,7 @@ /** \name Internal Types * \{ */ -typedef struct GpencilBatchCache { +struct GpencilBatchCache { /** Instancing Data */ GPUVertBuf *vbo; GPUVertBuf *vbo_col; @@ -65,7 +65,7 @@ typedef struct GpencilBatchCache { bool is_dirty; /** Last cache frame */ int cache_frame; -} GpencilBatchCache; +}; /** \} */ @@ -175,16 +175,16 @@ void DRW_gpencil_batch_cache_free(bGPdata *gpd) * \{ */ /* MUST match the format below. */ -typedef struct gpStrokeVert { +struct gpStrokeVert { /** Position and thickness packed in the same attribute. */ float pos[3], thickness; /** Material Index, Stroke Index, Point Index, Packed aspect + hardness + rotation. */ int32_t mat, stroke_id, point_id, packed_asp_hard_rot; /** UV and strength packed in the same attribute. */ float uv_fill[2], u_stroke, strength; -} gpStrokeVert; +}; -static GPUVertFormat *gpencil_stroke_format(void) +static GPUVertFormat *gpencil_stroke_format() { static GPUVertFormat format = {0}; if (format.attr_len == 0) { @@ -196,12 +196,12 @@ static GPUVertFormat *gpencil_stroke_format(void) } /* MUST match the format below. */ -typedef struct gpEditVert { +struct gpEditVert { uint vflag; float weight; -} gpEditVert; +}; -static GPUVertFormat *gpencil_edit_stroke_format(void) +static GPUVertFormat *gpencil_edit_stroke_format() { static GPUVertFormat format = {0}; if (format.attr_len == 0) { @@ -212,12 +212,12 @@ static GPUVertFormat *gpencil_edit_stroke_format(void) } /* MUST match the format below. */ -typedef struct gpEditCurveVert { +struct gpEditCurveVert { float pos[3]; uint32_t data; -} gpEditCurveVert; +}; -static GPUVertFormat *gpencil_edit_curve_format(void) +static GPUVertFormat *gpencil_edit_curve_format() { static GPUVertFormat format = {0}; if (format.attr_len == 0) { @@ -229,12 +229,12 @@ static GPUVertFormat *gpencil_edit_curve_format(void) } /* MUST match the format below. */ -typedef struct gpColorVert { +struct gpColorVert { float vcol[4]; /* Vertex color */ float fcol[4]; /* Fill color */ -} gpColorVert; +}; -static GPUVertFormat *gpencil_color_format(void) +static GPUVertFormat *gpencil_color_format() { static GPUVertFormat format = {0}; if (format.attr_len == 0) { @@ -250,7 +250,7 @@ static GPUVertFormat *gpencil_color_format(void) /** \name Vertex Buffers * \{ */ -typedef struct gpIterData { +struct gpIterData { bGPdata *gpd; gpStrokeVert *verts; gpColorVert *cols; @@ -258,9 +258,9 @@ typedef struct gpIterData { int vert_len; int tri_len; int curve_len; -} gpIterData; +}; -static GPUVertBuf *gpencil_dummy_buffer_get(void) +static GPUVertBuf *gpencil_dummy_buffer_get() { GPUBatch *batch = DRW_gpencil_dummy_buffer_get(); return batch->verts[0]; @@ -726,15 +726,15 @@ void DRW_cache_gpencil_sbuffer_clear(Object *ob) #define GP_EDIT_STROKE_END (1 << 4) #define GP_EDIT_POINT_DIMMED (1 << 5) -typedef struct gpEditIterData { +struct gpEditIterData { gpEditVert *verts; int vgindex; -} gpEditIterData; +}; -typedef struct gpEditCurveIterData { +struct gpEditCurveIterData { gpEditCurveVert *verts; int vgindex; -} gpEditCurveIterData; +}; static uint32_t gpencil_point_edit_flag(const bool layer_lock, const bGPDspoint *pt, diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 65bd8da452a..d08c95cd5ae 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -932,7 +932,7 @@ static void gpencil_draw_basic_stroke(tGPDfill *tgpf, /* Help strokes are for display only and shouldn't render. */ return; } - else if (is_help) { + if (is_help) { /* Color help strokes that won't affect fill or render separately from * extended strokes, as they will affect them. */ copy_v4_v4(col, help_col); diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index 0144126f802..b1424b42065 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -739,7 +739,7 @@ static void ui_color_snap_hue(const enum eSnapType snap, float *r_hue) static ListBase UIAfterFuncs = {nullptr, nullptr}; -static uiAfterFunc *ui_afterfunc_new(void) +static uiAfterFunc *ui_afterfunc_new() { uiAfterFunc *after = MEM_cnew(__func__); @@ -2795,7 +2795,7 @@ static void ui_but_copy(bContext *C, uiBut *but, const bool copy_array) } if (is_buf_set) { - WM_clipboard_text_set(buf, 0); + WM_clipboard_text_set(buf, false); } } @@ -2864,7 +2864,7 @@ static void ui_but_paste(bContext *C, uiBut *but, uiHandleButtonData *data, cons MEM_freeN((void *)buf_paste); } -void ui_but_clipboard_free(void) +void ui_but_clipboard_free() { BKE_curvemapping_free_data(&but_copypaste_curve); BKE_curveprofile_free_data(&but_copypaste_profile); @@ -3301,7 +3301,7 @@ static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const in MEM_mallocN(sizeof(char) * (sellen + 1), "ui_textedit_copypaste")); BLI_strncpy(buf, data->str + but->selsta, sellen + 1); - WM_clipboard_text_set(buf, 0); + WM_clipboard_text_set(buf, false); MEM_freeN(buf); /* for cut only, delete the selection afterwards */ diff --git a/source/blender/editors/interface/interface_icons.cc b/source/blender/editors/interface/interface_icons.cc index de5e72767a5..eaf4361a7e6 100644 --- a/source/blender/editors/interface/interface_icons.cc +++ b/source/blender/editors/interface/interface_icons.cc @@ -142,8 +142,8 @@ struct IconType { /* ******************* STATIC LOCAL VARS ******************* */ /* Static here to cache results of icon directory scan, so it's not * scanning the file-system each time the menu is drawn. */ -static ListBase iconfilelist = {NULL, NULL}; -static IconTexture icongltex = {{NULL, NULL}, 0, 0, 0, 0.0f, 0.0f}; +static ListBase iconfilelist = {nullptr, nullptr}; +static IconTexture icongltex = {{nullptr, nullptr}, 0, 0, 0, 0.0f, 0.0f}; #ifndef WITH_HEADLESS @@ -170,7 +170,7 @@ static DrawInfo *def_internal_icon( { Icon *new_icon = MEM_cnew(__func__); - new_icon->obj = NULL; /* icon is not for library object */ + new_icon->obj = nullptr; /* icon is not for library object */ new_icon->id_type = 0; DrawInfo *di = MEM_cnew(__func__); @@ -222,14 +222,14 @@ static void def_internal_vicon(int icon_id, VectorDrawFunc drawFunc) { Icon *new_icon = MEM_cnew("texicon"); - new_icon->obj = NULL; /* icon is not for library object */ + new_icon->obj = nullptr; /* icon is not for library object */ new_icon->id_type = 0; DrawInfo *di = MEM_cnew("drawinfo"); di->type = ICON_TYPE_VECTOR; di->data.vector.func = drawFunc; - new_icon->drawinfo_free = NULL; + new_icon->drawinfo_free = nullptr; new_icon->drawinfo = di; BKE_icon_set(icon_id, new_icon); @@ -486,7 +486,7 @@ static void vicon_strip_color_draw_library_data_indirect( aspect, ICON_INDIRECT_DATA_ALPHA * alpha, 0.0f, - NULL, + nullptr, false, UI_NO_ICON_OVERLAY_TEXT); } @@ -502,7 +502,7 @@ static void vicon_strip_color_draw_library_data_override_noneditable( aspect, ICON_INDIRECT_DATA_ALPHA * alpha * 0.75f, 0.0f, - NULL, + nullptr, false, UI_NO_ICON_OVERLAY_TEXT); } @@ -529,7 +529,7 @@ static void vicon_gplayer_color_draw(Icon *icon, int x, int y, int w, int h) immUnbindProgram(); } -static void init_brush_icons(void) +static void init_brush_icons() { # define INIT_BRUSH_ICON(icon_id, name) \ @@ -538,7 +538,7 @@ static void init_brush_icons(void) const int size = datatoc_##name##_png_size; \ DrawInfo *di; \ \ - di = def_internal_icon(NULL, icon_id, 0, 0, w, ICON_TYPE_BUFFER, 0); \ + di = def_internal_icon(nullptr, icon_id, 0, 0, w, ICON_TYPE_BUFFER, 0); \ di->data.buffer.image->datatoc_rect = rect; \ di->data.buffer.image->datatoc_size = size; \ } \ @@ -617,7 +617,7 @@ static void init_brush_icons(void) # undef INIT_BRUSH_ICON } -static DrawInfo *g_di_event_list = NULL; +static DrawInfo *g_di_event_list = nullptr; int UI_icon_from_event_type(short event_type, short event_value) { @@ -672,13 +672,13 @@ int UI_icon_from_keymap_item(const wmKeyMapItem *kmi, int r_icon_mod[4]) return UI_icon_from_event_type(kmi->type, kmi->val); } -static void init_event_icons(void) +static void init_event_icons() { - DrawInfo *di_next = NULL; + DrawInfo *di_next = nullptr; # define INIT_EVENT_ICON(icon_id, type, value) \ { \ - DrawInfo *di = def_internal_icon(NULL, icon_id, 0, 0, w, ICON_TYPE_EVENT, 0); \ + DrawInfo *di = def_internal_icon(nullptr, icon_id, 0, 0, w, ICON_TYPE_EVENT, 0); \ di->data.input.event_type = type; \ di->data.input.event_value = value; \ di->data.input.icon = icon_id; \ @@ -753,14 +753,14 @@ static void icon_verify_datatoc(IconImage *iimg) if (iimg->datatoc_rect) { ImBuf *bbuf = IMB_ibImageFromMemory( - iimg->datatoc_rect, iimg->datatoc_size, IB_rect, NULL, ""); + iimg->datatoc_rect, iimg->datatoc_size, IB_rect, nullptr, ""); /* w and h were set on initialize */ if (bbuf->x != iimg->h && bbuf->y != iimg->w) { IMB_scaleImBuf(bbuf, iimg->w, iimg->h); } iimg->rect = bbuf->rect; - bbuf->rect = NULL; + bbuf->rect = nullptr; IMB_freeImBuf(bbuf); } } @@ -847,31 +847,31 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf, return result; } -static void free_icons_textures(void) +static void free_icons_textures() { if (icongltex.num_textures > 0) { for (int i = 0; i < 2; i++) { if (icongltex.tex[i]) { GPU_texture_free(icongltex.tex[i]); - icongltex.tex[i] = NULL; + icongltex.tex[i] = nullptr; } } icongltex.num_textures = 0; } } -void UI_icons_reload_internal_textures(void) +void UI_icons_reload_internal_textures() { bTheme *btheme = UI_GetTheme(); - ImBuf *b16buf = NULL, *b32buf = NULL, *b16buf_border = NULL, *b32buf_border = NULL; + ImBuf *b16buf = nullptr, *b32buf = nullptr, *b16buf_border = nullptr, *b32buf_border = nullptr; const float icon_border_intensity = btheme->tui.icon_border_intensity; const bool need_icons_with_border = icon_border_intensity > 0.0f; - if (b16buf == NULL) { + if (b16buf == nullptr) { b16buf = IMB_ibImageFromMemory((const uchar *)datatoc_blender_icons16_png, datatoc_blender_icons16_png_size, IB_rect, - NULL, + nullptr, ""); } if (b16buf) { @@ -882,11 +882,11 @@ void UI_icons_reload_internal_textures(void) IMB_premultiply_alpha(b16buf); } - if (b32buf == NULL) { + if (b32buf == nullptr) { b32buf = IMB_ibImageFromMemory((const uchar *)datatoc_blender_icons32_png, datatoc_blender_icons32_png_size, IB_rect, - NULL, + nullptr, ""); } if (b32buf) { @@ -906,26 +906,26 @@ void UI_icons_reload_internal_textures(void) /* Note the filter and LOD bias were tweaked to better preserve icon * sharpness at different UI scales. */ - if (icongltex.tex[0] == NULL) { + if (icongltex.tex[0] == nullptr) { icongltex.w = b32buf->x; icongltex.h = b32buf->y; icongltex.invw = 1.0f / b32buf->x; icongltex.invh = 1.0f / b32buf->y; icongltex.tex[0] = GPU_texture_create_2d_ex( - "icons", b32buf->x, b32buf->y, 2, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, NULL); + "icons", b32buf->x, b32buf->y, 2, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, nullptr); GPU_texture_update_mipmap(icongltex.tex[0], 0, GPU_DATA_UBYTE, b32buf->rect); GPU_texture_update_mipmap(icongltex.tex[0], 1, GPU_DATA_UBYTE, b16buf->rect); } - if (need_icons_with_border && icongltex.tex[1] == NULL) { + if (need_icons_with_border && icongltex.tex[1] == nullptr) { icongltex.tex[1] = GPU_texture_create_2d_ex("icons_border", b32buf_border->x, b32buf_border->y, 2, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, - NULL); + nullptr); GPU_texture_update_mipmap(icongltex.tex[1], 0, GPU_DATA_UBYTE, b32buf_border->rect); GPU_texture_update_mipmap(icongltex.tex[1], 1, GPU_DATA_UBYTE, b16buf_border->rect); } @@ -937,18 +937,18 @@ void UI_icons_reload_internal_textures(void) IMB_freeImBuf(b32buf_border); } -static void init_internal_icons(void) +static void init_internal_icons() { # if 0 /* temp disabled */ - if ((btheme != NULL) && btheme->tui.iconfile[0]) { + if ((btheme != nullptr) && btheme->tui.iconfile[0]) { char *icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons"); char iconfilestr[FILE_MAX]; if (icondir) { BLI_path_join(iconfilestr, sizeof(iconfilestr), icondir, btheme->tui.iconfile); - /* if the image is missing bbuf will just be NULL */ - bbuf = IMB_loadiffname(iconfilestr, IB_rect, NULL); + /* if the image is missing bbuf will just be nullptr */ + bbuf = IMB_loadiffname(iconfilestr, IB_rect, nullptr); if (bbuf && (bbuf->x < ICON_IMAGE_W || bbuf->y < ICON_IMAGE_H)) { printf( @@ -957,7 +957,7 @@ static void init_internal_icons(void) "Using built-in Icons instead\n", iconfilestr); IMB_freeImBuf(bbuf); - bbuf = NULL; + bbuf = nullptr; } } else { @@ -975,7 +975,7 @@ static void init_internal_icons(void) continue; } - def_internal_icon(NULL, + def_internal_icon(nullptr, BIFICONID_FIRST + y * ICON_GRID_COLS + x, x * (ICON_GRID_W + ICON_GRID_MARGIN) + ICON_GRID_MARGIN, y * (ICON_GRID_H + ICON_GRID_MARGIN) + ICON_GRID_MARGIN, @@ -1047,7 +1047,7 @@ static void init_iconfile_list(ListBase *list) BLI_listbase_clear(list); const char *icondir = BKE_appdir_folder_id(BLENDER_DATAFILES, "icons"); - if (icondir == NULL) { + if (icondir == nullptr) { return; } @@ -1065,7 +1065,7 @@ static void init_iconfile_list(ListBase *list) # if 0 int ifilex, ifiley; char iconfilestr[FILE_MAX + 16]; /* allow 256 chars for file+dir */ - ImBuf *bbuf = NULL; + ImBuf *bbuf = nullptr; /* check to see if the image is the right size, continue if not */ /* copying strings here should go ok, assuming that we never get back * a complete path to file longer than 256 chars */ @@ -1102,7 +1102,7 @@ static void init_iconfile_list(ListBase *list) } BLI_filelist_free(dir, totfile); - dir = NULL; + dir = nullptr; } static void free_iconfile_list(ListBase *list) @@ -1114,7 +1114,7 @@ static void free_iconfile_list(ListBase *list) #else -void UI_icons_reload_internal_textures(void) +void UI_icons_reload_internal_textures() { } @@ -1131,14 +1131,14 @@ int UI_iconfile_get_index(const char *filename) return 0; } -ListBase *UI_iconfile_list(void) +ListBase *UI_iconfile_list() { ListBase *list = &(iconfilelist); return list; } -void UI_icons_free(void) +void UI_icons_free() { #ifndef WITH_HEADLESS free_icons_textures(); @@ -1151,7 +1151,7 @@ void UI_icons_free_drawinfo(void *drawinfo) { DrawInfo *di = static_cast(drawinfo); - if (di == NULL) { + if (di == nullptr) { return; } @@ -1218,7 +1218,7 @@ int UI_icon_get_width(int icon_id) { Icon *icon = BKE_icon_get(icon_id); - if (icon == NULL) { + if (icon == nullptr) { if (G.debug & G_DEBUG) { printf("%s: Internal error, no icon for icon ID: %d\n", __func__, icon_id); } @@ -1236,7 +1236,7 @@ int UI_icon_get_width(int icon_id) int UI_icon_get_height(int icon_id) { Icon *icon = BKE_icon_get(icon_id); - if (icon == NULL) { + if (icon == nullptr) { if (G.debug & G_DEBUG) { printf("%s: Internal error, no icon for icon ID: %d\n", __func__, icon_id); } @@ -1254,7 +1254,7 @@ int UI_icon_get_height(int icon_id) bool UI_icon_get_theme_color(int icon_id, uchar color[4]) { Icon *icon = BKE_icon_get(icon_id); - if (icon == NULL) { + if (icon == nullptr) { return false; } @@ -1325,7 +1325,7 @@ static void ui_studiolight_kill_icon_preview_job(wmWindowManager *wm, int icon_i { Icon *icon = BKE_icon_get(icon_id); WM_jobs_kill_type(wm, icon, WM_JOB_TYPE_STUDIOLIGHT); - icon->obj = NULL; + icon->obj = nullptr; } static void ui_studiolight_free_function(StudioLight *sl, void *data) @@ -1333,7 +1333,7 @@ static void ui_studiolight_free_function(StudioLight *sl, void *data) wmWindowManager *wm = static_cast(data); /* Happens if job was canceled or already finished. */ - if (wm == NULL) { + if (wm == nullptr) { return; } @@ -1357,26 +1357,26 @@ static void ui_studiolight_icon_job_end(void *customdata) Icon **tmp = (Icon **)customdata; Icon *icon = *tmp; StudioLight *sl = static_cast(icon->obj); - BKE_studiolight_set_free_function(sl, &ui_studiolight_free_function, NULL); + BKE_studiolight_set_free_function(sl, &ui_studiolight_free_function, nullptr); } void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool big) { Icon *icon = BKE_icon_get(icon_id); - if (icon == NULL) { + if (icon == nullptr) { return; } DrawInfo *di = icon_ensure_drawinfo(icon); - if (di == NULL) { + if (di == nullptr) { return; } switch (di->type) { case ICON_TYPE_PREVIEW: { - ID *id = (icon->id_type != 0) ? static_cast(icon->obj) : NULL; + ID *id = (icon->id_type != 0) ? static_cast(icon->obj) : nullptr; PreviewImage *prv = id ? BKE_previewimg_id_ensure(id) : static_cast(icon->obj); /* Using jobs for screen previews crashes due to off-screen rendering. @@ -1387,14 +1387,14 @@ void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool bi const int size = big ? ICON_SIZE_PREVIEW : ICON_SIZE_ICON; if (id || (prv->tag & PRV_TAG_DEFFERED) != 0) { - ui_id_preview_image_render_size(C, NULL, id, prv, size, use_jobs); + ui_id_preview_image_render_size(C, nullptr, id, prv, size, use_jobs); } } break; } case ICON_TYPE_BUFFER: { if (icon->obj_type == ICON_DATA_STUDIOLIGHT) { - if (di->data.buffer.image == NULL) { + if (di->data.buffer.image == nullptr) { wmWindowManager *wm = CTX_wm_manager(C); StudioLight *sl = static_cast(icon->obj); BKE_studiolight_set_free_function(sl, &ui_studiolight_free_function, wm); @@ -1418,7 +1418,7 @@ void ui_icon_ensure_deferred(const bContext *C, const int icon_id, const bool bi WM_jobs_customdata_set(wm_job, tmp, MEM_freeN); WM_jobs_timer(wm_job, 0.01, 0, NC_WINDOW); WM_jobs_callbacks( - wm_job, ui_studiolight_icon_job_exec, NULL, NULL, ui_studiolight_icon_job_end); + wm_job, ui_studiolight_icon_job_exec, nullptr, nullptr, ui_studiolight_icon_job_end); WM_jobs_start(CTX_wm_manager(C), wm_job); } } @@ -1452,7 +1452,7 @@ static void icon_set_image(const bContext *C, return; } - const bool delay = prv_img->rect[size] != NULL; + const bool delay = prv_img->rect[size] != nullptr; icon_create_rect(prv_img, size); if (use_job && (!id || BKE_previewimg_id_supports_jobs(id))) { @@ -1472,14 +1472,14 @@ PreviewImage *UI_icon_to_preview(int icon_id) { Icon *icon = BKE_icon_get(icon_id); - if (icon == NULL) { - return NULL; + if (icon == nullptr) { + return nullptr; } DrawInfo *di = (DrawInfo *)icon->drawinfo; - if (di == NULL) { - return NULL; + if (di == nullptr) { + return nullptr; } if (di->type == ICON_TYPE_PREVIEW) { @@ -1496,7 +1496,7 @@ PreviewImage *UI_icon_to_preview(int icon_id) bbuf = IMB_ibImageFromMemory(di->data.buffer.image->datatoc_rect, di->data.buffer.image->datatoc_size, IB_rect, - NULL, + nullptr, __func__); if (bbuf) { PreviewImage *prv = BKE_previewimg_create(); @@ -1506,14 +1506,14 @@ PreviewImage *UI_icon_to_preview(int icon_id) prv->w[0] = bbuf->x; prv->h[0] = bbuf->y; - bbuf->rect = NULL; + bbuf->rect = nullptr; IMB_freeImBuf(bbuf); return prv; } } - return NULL; + return nullptr; } static void icon_draw_rect(float x, @@ -1604,7 +1604,7 @@ static struct { bool enabled; } g_icon_draw_cache = {{{{{0}}}}}; -void UI_icon_draw_cache_begin(void) +void UI_icon_draw_cache_begin() { BLI_assert(g_icon_draw_cache.enabled == false); g_icon_draw_cache.enabled = true; @@ -1668,7 +1668,7 @@ static void icon_draw_cache_flush_ex(bool only_full_caches) } } -void UI_icon_draw_cache_end(void) +void UI_icon_draw_cache_end() { BLI_assert(g_icon_draw_cache.enabled == true); g_icon_draw_cache.enabled = false; @@ -1860,7 +1860,7 @@ static void icon_draw_size(float x, Icon *icon = BKE_icon_get(icon_id); alpha *= btheme->tui.icon_alpha; - if (icon == NULL) { + if (icon == nullptr) { if (G.debug & G_DEBUG) { printf("%s: Internal error, no icon for icon ID: %d\n", __func__, icon_id); } @@ -1907,7 +1907,7 @@ static void icon_draw_size(float x, /* This could re-generate often if rendered at different sizes in the one interface. * TODO(@campbellbarton): support caching multiple sizes. */ ImBuf *ibuf = di->data.geom.image_cache; - if ((ibuf == NULL) || (ibuf->x != w) || (ibuf->y != h) || (invert != geom_inverted)) { + if ((ibuf == nullptr) || (ibuf->x != w) || (ibuf->y != h) || (invert != geom_inverted)) { if (ibuf) { IMB_freeImBuf(ibuf); } @@ -1939,7 +1939,7 @@ static void icon_draw_size(float x, di->data.texture.w, di->data.texture.h, alpha, - NULL, + nullptr, false, text_overlay); } @@ -2011,7 +2011,7 @@ static void icon_draw_size(float x, } } else if (di->type == ICON_TYPE_GPLAYER) { - BLI_assert(icon->obj != NULL); + BLI_assert(icon->obj != nullptr); /* Just draw a colored rect - Like for vicon_colorset_draw() */ #ifndef WITH_HEADLESS @@ -2046,7 +2046,7 @@ void UI_icon_render_id( const bContext *C, Scene *scene, ID *id, const enum eIconSizes size, const bool use_job) { PreviewImage *pi = BKE_previewimg_id_ensure(id); - if (pi == NULL) { + if (pi == nullptr) { return; } @@ -2076,7 +2076,7 @@ static void ui_id_icon_render(const bContext *C, ID *id, bool use_jobs) } for (int i = 0; i < NUM_ICON_SIZES; i++) { - ui_id_preview_image_render_size(C, NULL, id, pi, i, use_jobs); + ui_id_preview_image_render_size(C, nullptr, id, pi, i, use_jobs); } } @@ -2090,7 +2090,7 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id) } else { Object *ob = CTX_data_active_object(C); - const EnumPropertyItem *items = NULL; + const EnumPropertyItem *items = nullptr; ePaintMode paint_mode = PAINT_MODE_INVALID; ScrArea *area = CTX_wm_area(C); char space_type = area->spacetype; @@ -2130,7 +2130,8 @@ static int ui_id_brush_get_icon(const bContext *C, ID *id) } /* reset the icon */ - if ((ob != NULL) && (ob->mode & OB_MODE_ALL_PAINT_GPENCIL) && (br->gpencil_settings != NULL)) { + if ((ob != nullptr) && (ob->mode & OB_MODE_ALL_PAINT_GPENCIL) && + (br->gpencil_settings != nullptr)) { switch (br->gpencil_settings->icon_id) { case GP_BRUSH_ICON_PENCIL: br->id.icon_id = ICON_GPBRUSH_PENCIL; @@ -2264,7 +2265,7 @@ int ui_id_icon_get(const bContext *C, ID *id, const bool big) case ID_LA: /* fall through */ iconid = BKE_icon_id_ensure(id); /* checks if not exists, or changed */ - UI_icon_render_id(C, NULL, id, big ? ICON_SIZE_PREVIEW : ICON_SIZE_ICON, true); + UI_icon_render_id(C, nullptr, id, big ? ICON_SIZE_PREVIEW : ICON_SIZE_ICON, true); break; case ID_SCR: iconid = ui_id_screen_get_icon(C, id); @@ -2306,7 +2307,7 @@ int UI_icon_from_library(const ID *id) int UI_icon_from_rnaptr(const bContext *C, PointerRNA *ptr, int rnaicon, const bool big) { - ID *id = NULL; + ID *id = nullptr; if (!ptr->data) { return rnaicon; @@ -2490,12 +2491,14 @@ int UI_icon_color_from_collection(const Collection *collection) void UI_icon_draw(float x, float y, int icon_id) { - UI_icon_draw_ex(x, y, icon_id, U.inv_dpi_fac, 1.0f, 0.0f, NULL, false, UI_NO_ICON_OVERLAY_TEXT); + UI_icon_draw_ex( + x, y, icon_id, U.inv_dpi_fac, 1.0f, 0.0f, nullptr, false, UI_NO_ICON_OVERLAY_TEXT); } void UI_icon_draw_alpha(float x, float y, int icon_id, float alpha) { - UI_icon_draw_ex(x, y, icon_id, U.inv_dpi_fac, alpha, 0.0f, NULL, false, UI_NO_ICON_OVERLAY_TEXT); + UI_icon_draw_ex( + x, y, icon_id, U.inv_dpi_fac, alpha, 0.0f, nullptr, false, UI_NO_ICON_OVERLAY_TEXT); } void UI_icon_draw_preview(float x, float y, int icon_id, float aspect, float alpha, int size) @@ -2508,7 +2511,7 @@ void UI_icon_draw_preview(float x, float y, int icon_id, float aspect, float alp ICON_SIZE_PREVIEW, size, false, - NULL, + nullptr, false, UI_NO_ICON_OVERLAY_TEXT); } @@ -2554,7 +2557,7 @@ ImBuf *UI_icon_alert_imbuf_get(eAlertIcon icon) { #ifdef WITH_HEADLESS UNUSED_VARS(icon); - return NULL; + return nullptr; #else const int ALERT_IMG_SIZE = 256; icon = eAlertIcon(MIN2(icon, ALERT_ICON_MAX - 1)); @@ -2563,7 +2566,7 @@ ImBuf *UI_icon_alert_imbuf_get(eAlertIcon icon) ImBuf *ibuf = IMB_ibImageFromMemory((const uchar *)datatoc_alert_icons_png, datatoc_alert_icons_png_size, IB_rect, - NULL, + nullptr, "alert_icon"); IMB_rect_crop(ibuf, &crop); IMB_premultiply_alpha(ibuf); diff --git a/source/blender/editors/interface/interface_layout.cc b/source/blender/editors/interface/interface_layout.cc index 9d755ac022a..968ad8e11f4 100644 --- a/source/blender/editors/interface/interface_layout.cc +++ b/source/blender/editors/interface/interface_layout.cc @@ -489,7 +489,7 @@ static void ui_layer_but_cb(bContext *C, void *arg_but, void *arg_index) for (int i = 0; i < len; i++) { if (i != index) { - RNA_property_boolean_set_index(ptr, prop, i, 0); + RNA_property_boolean_set_index(ptr, prop, i, false); } } @@ -526,7 +526,7 @@ static void ui_item_array(uiLayout *layout, const PropertyType type = RNA_property_type(prop); const PropertySubType subtype = RNA_property_subtype(prop); - uiLayout *sub = ui_item_local_sublayout(layout, layout, 1); + uiLayout *sub = ui_item_local_sublayout(layout, layout, true); UI_block_layout_set_current(block, sub); /* create label */ @@ -773,7 +773,7 @@ static void ui_item_enum_expand_elem_exec(uiLayout *layout, const char *name = (!uiname || uiname[0]) ? item->name : ""; const int icon = item->icon; const int value = item->value; - const int itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, 0); + const int itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, false); uiBut *but; if (icon && name[0] && !icon_only) { @@ -863,7 +863,7 @@ static void ui_item_enum_expand_exec(uiLayout *layout, UI_block_layout_set_current(block, layout); } else { - UI_block_layout_set_current(block, ui_item_local_sublayout(layout, layout, 1)); + UI_block_layout_set_current(block, ui_item_local_sublayout(layout, layout, true)); } for (const EnumPropertyItem *item = item_array; item->identifier; item++) { @@ -1186,7 +1186,7 @@ static void ui_item_disabled(uiLayout *layout, const char *name) name = ""; } - const int w = ui_text_icon_width(layout, name, 0, 0); + const int w = ui_text_icon_width(layout, name, 0, false); uiBut *but = uiDefBut( block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, nullptr, 0.0, 0.0, 0, 0, ""); @@ -1226,7 +1226,7 @@ static uiBut *uiItemFullO_ptr_ex(uiLayout *layout, UI_block_layout_set_current(block, layout); ui_block_new_button_group(block, uiButtonGroupFlag(0)); - const int w = ui_text_icon_width(layout, name, icon, 0); + const int w = ui_text_icon_width(layout, name, icon, false); const eUIEmbossType prev_emboss = layout->emboss; if (flag & UI_ITEM_R_NO_BG) { @@ -1365,7 +1365,7 @@ void uiItemFullO(uiLayout *layout, int flag, PointerRNA *r_opptr) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + wmOperatorType *ot = WM_operatortype_find(opname, false); /* print error next */ UI_OPERATOR_ERROR_RET(ot, opname, { if (r_opptr) { @@ -1440,7 +1440,7 @@ void uiItemEnumO(uiLayout *layout, const char *propname, int value) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + wmOperatorType *ot = WM_operatortype_find(opname, false); /* print error next */ if (ot) { uiItemEnumO_ptr(layout, ot, name, icon, propname, value); @@ -1620,7 +1620,7 @@ void uiItemsFullEnumO(uiLayout *layout, wmOperatorCallContext context, int flag) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + wmOperatorType *ot = WM_operatortype_find(opname, false); /* print error next */ if (!ot || !ot->srna) { ui_item_disabled(layout, opname); @@ -1694,7 +1694,7 @@ void uiItemEnumO_value(uiLayout *layout, const char *propname, int value) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + wmOperatorType *ot = WM_operatortype_find(opname, false); /* print error next */ UI_OPERATOR_ERROR_RET(ot, opname, return ); PointerRNA ptr; @@ -1731,7 +1731,7 @@ void uiItemEnumO_string(uiLayout *layout, const char *propname, const char *value_str) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + wmOperatorType *ot = WM_operatortype_find(opname, false); /* print error next */ UI_OPERATOR_ERROR_RET(ot, opname, return ); PointerRNA ptr; @@ -1787,7 +1787,7 @@ void uiItemBooleanO(uiLayout *layout, const char *propname, int value) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + wmOperatorType *ot = WM_operatortype_find(opname, false); /* print error next */ UI_OPERATOR_ERROR_RET(ot, opname, return ); PointerRNA ptr; @@ -1811,7 +1811,7 @@ void uiItemIntO(uiLayout *layout, const char *propname, int value) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + wmOperatorType *ot = WM_operatortype_find(opname, false); /* print error next */ UI_OPERATOR_ERROR_RET(ot, opname, return ); PointerRNA ptr; @@ -1835,7 +1835,7 @@ void uiItemFloatO(uiLayout *layout, const char *propname, float value) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + wmOperatorType *ot = WM_operatortype_find(opname, false); /* print error next */ UI_OPERATOR_ERROR_RET(ot, opname, return ); @@ -1860,7 +1860,7 @@ void uiItemStringO(uiLayout *layout, const char *propname, const char *value) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + wmOperatorType *ot = WM_operatortype_find(opname, false); /* print error next */ UI_OPERATOR_ERROR_RET(ot, opname, return ); @@ -2922,7 +2922,7 @@ void uiItemPointerR_prop(uiLayout *layout, uiBlock *block = uiLayoutGetBlock(layout); int w, h; - ui_item_rna_size(layout, name, icon, ptr, prop, 0, 0, false, &w, &h); + ui_item_rna_size(layout, name, icon, ptr, prop, 0, false, false, &w, &h); w += UI_UNIT_X; /* X icon needs more space */ uiBut *but = ui_item_with_label(layout, block, name, icon, ptr, prop, 0, 0, 0, w, h, 0); @@ -3401,7 +3401,7 @@ void uiItemV(uiLayout *layout, const char *name, int icon, int argval) icon = ICON_BLANK1; } - const int w = ui_text_icon_width(layout, name, icon, 0); + const int w = ui_text_icon_width(layout, name, icon, false); if (icon && name[0]) { uiDefIconTextButI(block, @@ -3592,7 +3592,7 @@ void uiItemMenuEnumFullO(uiLayout *layout, int icon, PointerRNA *r_opptr) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + wmOperatorType *ot = WM_operatortype_find(opname, false); /* print error next */ UI_OPERATOR_ERROR_RET(ot, opname, return ); @@ -4891,7 +4891,7 @@ uiLayout *uiLayoutRadial(uiLayout *layout) { /* radial layouts are only valid for radial menus */ if (layout->root->type != UI_LAYOUT_PIEMENU) { - return ui_item_local_sublayout(layout, layout, 0); + return ui_item_local_sublayout(layout, layout, false); } /* only one radial wheel per root layout is allowed, so check and return that, if it exists */ diff --git a/source/blender/editors/interface/interface_query.cc b/source/blender/editors/interface/interface_query.cc index 5ef9fdb3acf..84e2b488ccb 100644 --- a/source/blender/editors/interface/interface_query.cc +++ b/source/blender/editors/interface/interface_query.cc @@ -815,7 +815,7 @@ ARegion *ui_screen_region_find_mouse_over(bScreen *screen, const wmEvent *event) /** \name Manage Internal State * \{ */ -void ui_interface_tag_script_reload_queries(void) +void ui_interface_tag_script_reload_queries() { g_ot_tool_set_by_id = nullptr; } diff --git a/source/blender/editors/interface/interface_style.cc b/source/blender/editors/interface/interface_style.cc index 95d8638481e..0df382a0d9e 100644 --- a/source/blender/editors/interface/interface_style.cc +++ b/source/blender/editors/interface/interface_style.cc @@ -363,7 +363,7 @@ int UI_fontstyle_height_max(const uiFontStyle *fs) /* ************** init exit ************************ */ -void uiStyleInit(void) +void uiStyleInit() { const uiStyle *style = static_cast(U.uistyles.first); diff --git a/source/blender/editors/interface/interface_templates.cc b/source/blender/editors/interface/interface_templates.cc index 2e4c0e1c1b0..2374d1dece7 100644 --- a/source/blender/editors/interface/interface_templates.cc +++ b/source/blender/editors/interface/interface_templates.cc @@ -137,7 +137,7 @@ static int template_search_textbut_width(PointerRNA *ptr, PropertyRNA *name_prop estimated_width, TEMPLATE_SEARCH_TEXTBUT_MIN_WIDTH, TEMPLATE_SEARCH_TEXTBUT_MIN_WIDTH * 3); } -static int template_search_textbut_height(void) +static int template_search_textbut_height() { return TEMPLATE_SEARCH_TEXTBUT_HEIGHT; } @@ -6681,7 +6681,7 @@ static uiBlock *component_menu(bContext *C, ARegion *region, void *args_v) UI_UNIT_Y, 0, UI_style_get()), - 0); + false); uiItemR(layout, &args->ptr, args->propname, UI_ITEM_R_EXPAND, "", ICON_NONE); diff --git a/source/blender/editors/interface/interface_undo.cc b/source/blender/editors/interface/interface_undo.cc index 05fbb46bcee..380f385e598 100644 --- a/source/blender/editors/interface/interface_undo.cc +++ b/source/blender/editors/interface/interface_undo.cc @@ -95,7 +95,7 @@ void ui_textedit_undo_push(uiUndoStack_Text *stack, const char *text, int cursor BLI_addtail(&stack->states, stack->current); } -uiUndoStack_Text *ui_textedit_undo_stack_create(void) +uiUndoStack_Text *ui_textedit_undo_stack_create() { uiUndoStack_Text *stack = MEM_new(__func__); stack->current = nullptr; diff --git a/source/blender/editors/interface/interface_widgets.cc b/source/blender/editors/interface/interface_widgets.cc index 26b7d59dc94..690a32cd1e4 100644 --- a/source/blender/editors/interface/interface_widgets.cc +++ b/source/blender/editors/interface/interface_widgets.cc @@ -403,9 +403,9 @@ static struct { /* TODO: remove. */ GPUVertFormat format; uint vflag_id; -} g_ui_batch_cache = {0}; +} g_ui_batch_cache = {nullptr}; -static GPUVertFormat *vflag_format(void) +static GPUVertFormat *vflag_format() { if (g_ui_batch_cache.format.attr_len == 0) { GPUVertFormat *format = &g_ui_batch_cache.format; @@ -444,7 +444,7 @@ static uint32_t set_roundbox_vertex(GPUVertBufRaw *vflag_step, return *data; } -GPUBatch *ui_batch_roundbox_widget_get(void) +GPUBatch *ui_batch_roundbox_widget_get() { if (g_ui_batch_cache.roundbox_widget == nullptr) { GPUVertBuf *vbo = GPU_vertbuf_create_with_format(vflag_format()); @@ -470,7 +470,7 @@ GPUBatch *ui_batch_roundbox_widget_get(void) return g_ui_batch_cache.roundbox_widget; } -GPUBatch *ui_batch_roundbox_shadow_get(void) +GPUBatch *ui_batch_roundbox_shadow_get() { if (g_ui_batch_cache.roundbox_shadow == nullptr) { uint32_t last_data; @@ -1132,7 +1132,7 @@ static struct { bool enabled; } g_widget_base_batch = {{{{0}}}}; -void UI_widgetbase_draw_cache_flush(void) +void UI_widgetbase_draw_cache_flush() { const float checker_params[3] = { UI_ALPHA_CHECKER_DARK / 255.0f, UI_ALPHA_CHECKER_LIGHT / 255.0f, 8.0f}; @@ -1162,13 +1162,13 @@ void UI_widgetbase_draw_cache_flush(void) g_widget_base_batch.count = 0; } -void UI_widgetbase_draw_cache_begin(void) +void UI_widgetbase_draw_cache_begin() { BLI_assert(g_widget_base_batch.enabled == false); g_widget_base_batch.enabled = true; } -void UI_widgetbase_draw_cache_end(void) +void UI_widgetbase_draw_cache_end() { BLI_assert(g_widget_base_batch.enabled == true); g_widget_base_batch.enabled = false; @@ -1183,7 +1183,7 @@ void UI_widgetbase_draw_cache_end(void) /* Disable cached/instanced drawing and enforce single widget drawing pipeline. * Works around interface artifacts happening on certain driver and hardware * configurations. */ -static bool draw_widgetbase_batch_skip_draw_cache(void) +static bool draw_widgetbase_batch_skip_draw_cache() { /* MacOS is known to have issues on Mac Mini and MacBook Pro with Intel Iris GPU. * For example, T78307. */ @@ -5257,7 +5257,7 @@ void ui_draw_pie_center(uiBlock *block) GPU_matrix_pop(); } -const uiWidgetColors *ui_tooltip_get_theme(void) +const uiWidgetColors *ui_tooltip_get_theme() { uiWidgetType *wt = widget_type(UI_WTYPE_TOOLTIP); return wt->wcol_theme; diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index 43e59aaf4f7..37f6d4c3037 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -82,9 +82,9 @@ struct CursorSnapshot { int curve_preset; }; -static TexSnapshot primary_snap = {0}; -static TexSnapshot secondary_snap = {0}; -static CursorSnapshot cursor_snap = {0}; +static TexSnapshot primary_snap = {nullptr}; +static TexSnapshot secondary_snap = {nullptr}; +static CursorSnapshot cursor_snap = {nullptr}; void paint_cursor_delete_textures(void) { @@ -124,7 +124,7 @@ static void make_tex_snap(TexSnapshot *snap, ViewContext *vc, float zoom) snap->winy = vc->region->winy; } -typedef struct LoadTexData { +struct LoadTexData { Brush *br; ViewContext *vc; @@ -132,11 +132,11 @@ typedef struct LoadTexData { uchar *buffer; bool col; - struct ImagePool *pool; + ImagePool *pool; int size; float rotation; float radius; -} LoadTexData; +}; static void load_tex_task_cb_ex(void *__restrict userdata, const int j, @@ -150,13 +150,13 @@ static void load_tex_task_cb_ex(void *__restrict userdata, uchar *buffer = data->buffer; const bool col = data->col; - struct ImagePool *pool = data->pool; + ImagePool *pool = data->pool; const int size = data->size; const float rotation = data->rotation; const float radius = data->radius; bool convert_to_linear = false; - struct ColorSpace *colorspace = nullptr; + ColorSpace *colorspace = nullptr; const int thread_id = BLI_task_parallel_thread_id(tls); @@ -253,10 +253,10 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima refresh = !target->overlay_texture || (invalid != 0) || !same_tex_snap(target, mtex, vc, col, zoom); - init = (target->overlay_texture != 0); + init = (target->overlay_texture != nullptr); if (refresh) { - struct ImagePool *pool = nullptr; + ImagePool *pool = nullptr; /* Stencil is rotated later. */ const float rotation = (mtex->brush_map_mode != MTEX_MAP_MODE_STENCIL) ? -mtex->rot : 0.0f; const float radius = BKE_brush_size_get(vc->scene, br) * zoom; @@ -406,7 +406,7 @@ static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom) (overlay_flags & PAINT_OVERLAY_INVALID_CURVE) || cursor_snap.zoom != zoom || cursor_snap.curve_preset != br->curve_preset; - init = (cursor_snap.overlay_texture != 0); + init = (cursor_snap.overlay_texture != nullptr); if (refresh) { int s, r; @@ -1194,13 +1194,13 @@ static bool paint_use_2d_cursor(ePaintMode mode) return false; } -typedef enum PaintCursorDrawingType { +enum PaintCursorDrawingType { PAINT_CURSOR_CURVE, PAINT_CURSOR_2D, PAINT_CURSOR_3D, -} PaintCursorDrawingType; +}; -typedef struct PaintCursorContext { +struct PaintCursorContext { bContext *C; ARegion *region; wmWindow *win; @@ -1246,8 +1246,7 @@ typedef struct PaintCursorContext { float final_radius; int pixel_radius; - -} PaintCursorContext; +}; static bool paint_cursor_context_init(bContext *C, const int x, @@ -1895,7 +1894,7 @@ static void paint_cursor_setup_3D_drawing(PaintCursorContext *pcontext) immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); } -static void paint_cursor_restore_drawing_state(void) +static void paint_cursor_restore_drawing_state() { immUnbindProgram(); GPU_blend(GPU_BLEND_NONE); diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.cc b/source/blender/editors/sculpt_paint/paint_image_proj.cc index 1a60424869d..3d23cb46856 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.cc +++ b/source/blender/editors/sculpt_paint/paint_image_proj.cc @@ -6,11 +6,11 @@ * \brief Functions to paint images in 2D and 3D. */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include "MEM_guardedalloc.h" @@ -194,7 +194,7 @@ BLI_INLINE uchar f_to_char(const float val) * their imbufs, etc, in 1 array, When using threads this array is copied for each thread * because 'partRedrawRect' and 'touch' values would not be thread safe. */ -typedef struct ProjPaintImage { +struct ProjPaintImage { Image *ima; ImageUser iuser; ImBuf *ibuf; @@ -207,12 +207,12 @@ typedef struct ProjPaintImage { /** Store flag to enforce validation of undo rectangle. */ bool **valid; bool touch; -} ProjPaintImage; +}; /** * Handle for stroke (operator customdata) */ -typedef struct ProjStrokeHandle { +struct ProjStrokeHandle { /* Support for painting from multiple views at once, * currently used to implement symmetry painting, * we can assume at least the first is set while painting. */ @@ -230,16 +230,16 @@ typedef struct ProjStrokeHandle { /* In ProjPaintState, only here for convenience */ Scene *scene; Brush *brush; -} ProjStrokeHandle; +}; -typedef struct LoopSeamData { +struct LoopSeamData { float seam_uvs[2][2]; float seam_puvs[2][2]; float corner_dist_sq[2]; -} LoopSeamData; +}; /* Main projection painting struct passed to all projection painting functions */ -typedef struct ProjPaintState { +struct ProjPaintState { View3D *v3d; RegionView3D *rv3d; ARegion *region; @@ -368,7 +368,7 @@ typedef struct ProjPaintState { /** must lock threads while accessing these. */ int context_bucket_index; - struct CurveMapping *cavity_curve; + CurveMapping *cavity_curve; BlurKernel *blurkernel; /* -------------------------------------------------------------------- */ @@ -436,23 +436,23 @@ typedef struct ProjPaintState { Material **mat_array; bool use_colormanagement; -} ProjPaintState; +}; -typedef union pixelPointer { +union PixelPointer { /** float buffer. */ float *f_pt; /** 2 ways to access a char buffer. */ uint *uint_pt; uchar *ch_pt; -} PixelPointer; +}; -typedef union pixelStore { +union PixelStore { uchar ch[4]; uint uint_; float f[4]; -} PixelStore; +}; -typedef struct ProjPixel { +struct ProjPixel { /** the floating point screen projection of this pixel. */ float projCoSS[2]; float worldCoSS[3]; @@ -479,30 +479,30 @@ typedef struct ProjPixel { PixelPointer origColor; PixelStore newColor; PixelPointer pixel; -} ProjPixel; +}; -typedef struct ProjPixelClone { +struct ProjPixelClone { struct ProjPixel __pp; PixelStore clonepx; -} ProjPixelClone; +}; /* undo tile pushing */ -typedef struct { +struct TileInfo { SpinLock *lock; bool masked; ushort tile_width; ImBuf **tmpibuf; ProjPaintImage *pjima; -} TileInfo; +}; -typedef struct VertSeam { +struct VertSeam { struct VertSeam *next, *prev; int tri; uint loop; float angle; bool normal_cw; float uv[2]; -} VertSeam; +}; /* -------------------------------------------------------------------- */ /** \name MLoopTri accessor functions. @@ -2030,14 +2030,14 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps, * the faces are already initialized in project_paint_delayed_face_init(...) */ if (ibuf->rect_float) { if (!project_paint_PickColor( - ps, co, ((ProjPixelClone *)projPixel)->clonepx.f, nullptr, 1)) { + ps, co, ((ProjPixelClone *)projPixel)->clonepx.f, nullptr, true)) { /* zero alpha - ignore */ ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0; } } else { if (!project_paint_PickColor( - ps, co, nullptr, ((ProjPixelClone *)projPixel)->clonepx.ch, 1)) { + ps, co, nullptr, ((ProjPixelClone *)projPixel)->clonepx.ch, true)) { /* zero alpha - ignore */ ((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0; } @@ -3738,7 +3738,7 @@ static void proj_paint_state_viewport_init(ProjPaintState *ps, const char symmet if (ps->source == PROJ_SRC_IMAGE_VIEW) { /* image stores camera data, tricky */ - IDProperty *idgroup = IDP_GetProperties(&ps->reproject_image->id, 0); + IDProperty *idgroup = IDP_GetProperties(&ps->reproject_image->id, false); IDProperty *view_data = IDP_GetPropertyFromGroup(idgroup, PROJ_VIEW_DATA_ID); const float *array = (float *)IDP_Array(view_data); @@ -3750,7 +3750,7 @@ static void proj_paint_state_viewport_init(ProjPaintState *ps, const char symmet array += sizeof(viewmat) / sizeof(float); ps->clip_start = array[0]; ps->clip_end = array[1]; - ps->is_ortho = array[2] ? 1 : 0; + ps->is_ortho = bool(array[2]); invert_m4_m4(viewinv, viewmat); } @@ -4104,11 +4104,11 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p return true; } -typedef struct { +struct ProjPaintLayerClone { const MLoopUV *mloopuv_clone_base; const TexPaintSlot *slot_last_clone; const TexPaintSlot *slot_clone; -} ProjPaintLayerClone; +}; static void proj_paint_layer_clone_init(ProjPaintState *ps, ProjPaintLayerClone *layer_clone) { @@ -4173,11 +4173,11 @@ static bool project_paint_clone_face_skip(ProjPaintState *ps, return false; } -typedef struct { +struct ProjPaintFaceLookup { const bool *select_poly_orig; const int *index_mp_to_orig; -} ProjPaintFaceLookup; +}; static void proj_paint_face_lookup_init(const ProjPaintState *ps, ProjPaintFaceLookup *face_lookup) { @@ -4208,11 +4208,11 @@ static bool project_paint_check_face_sel(const ProjPaintState *ps, return true; } -typedef struct { +struct ProjPaintFaceCoSS { const float *v1; const float *v2; const float *v3; -} ProjPaintFaceCoSS; +}; static void proj_paint_face_coSS_init(const ProjPaintState *ps, const MLoopTri *lt, @@ -4255,11 +4255,11 @@ static bool project_paint_winclip(const ProjPaintState *ps, const ProjPaintFaceC } #endif /* PROJ_DEBUG_WINCLIP */ -typedef struct PrepareImageEntry { +struct PrepareImageEntry { struct PrepareImageEntry *next, *prev; Image *ima; ImageUser iuser; -} PrepareImageEntry; +}; static void project_paint_build_proj_ima(ProjPaintState *ps, MemArena *arena, @@ -4278,7 +4278,7 @@ static void project_paint_build_proj_ima(ProjPaintState *ps, projIma->iuser = entry->iuser; int size; projIma->ima = entry->ima; - projIma->touch = 0; + projIma->touch = false; projIma->ibuf = BKE_image_acquire_ibuf(projIma->ima, &projIma->iuser, nullptr); if (projIma->ibuf == nullptr) { projIma->iuser.tile = 0; @@ -4730,7 +4730,7 @@ static bool project_image_refresh_tagged(ProjPaintState *ps) } /* clear for reuse */ - projIma->touch = 0; + projIma->touch = false; } } @@ -4810,7 +4810,7 @@ static bool project_bucket_iter_next(ProjPaintState *ps, } /* Each thread gets one of these, also used as an argument to pass to project_paint_op */ -typedef struct ProjectHandle { +struct ProjectHandle { /* args */ ProjPaintState *ps; float prevmval[2]; @@ -4826,7 +4826,7 @@ typedef struct ProjectHandle { int thread_index; struct ImagePool *pool; -} ProjectHandle; +}; static void do_projectpaint_clone(ProjPaintState *ps, ProjPixel *projPixel, float mask) { @@ -5177,7 +5177,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v) const float *lastpos = ((ProjectHandle *)ph_v)->prevmval; const float *pos = ((ProjectHandle *)ph_v)->mval; const int thread_index = ((ProjectHandle *)ph_v)->thread_index; - struct ImagePool *pool = ((ProjectHandle *)ph_v)->pool; + ImagePool *pool = ((ProjectHandle *)ph_v)->pool; /* Done with args from ProjectHandle */ LinkNode *node; @@ -5257,7 +5257,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v) last_index = projPixel->image_index; last_projIma = projImages + last_index; - last_projIma->touch = 1; + last_projIma->touch = true; is_floatbuf = (last_projIma->ibuf->rect_float != nullptr); } /* end copy */ @@ -5484,7 +5484,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v) last_index = projPixel->image_index; last_projIma = projImages + last_index; - last_projIma->touch = 1; + last_projIma->touch = true; is_floatbuf = (last_projIma->ibuf->rect_float != nullptr); } /* end copy */ @@ -5606,7 +5606,7 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po TaskPool *task_pool = nullptr; int a, i; - struct ImagePool *image_pool; + ImagePool *image_pool; if (!project_bucket_iter_init(ps, pos)) { return touch_any; @@ -5691,7 +5691,7 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po /* move threaded bounds back into ps->projectPartialRedraws */ for (i = 0; i < ps->image_tot; i++) { - int touch = 0; + int touch = false; for (a = 0; a < ps->thread_tot; a++) { touch |= int(partial_redraw_array_merge(ps->projImages[i].partRedrawRect, handles[a].projImages[i].partRedrawRect, @@ -5699,7 +5699,7 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po } if (touch) { - ps->projImages[i].touch = 1; + ps->projImages[i].touch = true; touch_any = 1; } } @@ -5801,7 +5801,7 @@ void paint_proj_stroke(const bContext *C, /* clone gets special treatment here to avoid going through image initialization */ if (ps_handle->is_clone_cursor_pick) { Scene *scene = ps_handle->scene; - struct Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); View3D *v3d = CTX_wm_view3d(C); ARegion *region = CTX_wm_region(C); float *cursor = scene->cursor.location; @@ -5880,21 +5880,21 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int ps->canvas_ima = (!ps->do_material_slots) ? settings->imapaint.canvas : nullptr; ps->clone_ima = (!ps->do_material_slots) ? settings->imapaint.clone : nullptr; - ps->do_mask_cavity = (settings->imapaint.paint.flags & PAINT_USE_CAVITY_MASK) ? true : false; + ps->do_mask_cavity = (settings->imapaint.paint.flags & PAINT_USE_CAVITY_MASK); ps->cavity_curve = settings->imapaint.paint.cavity_curve; /* setup projection painting data */ if (ps->tool != PAINT_TOOL_FILL) { - ps->do_backfacecull = (settings->imapaint.flag & IMAGEPAINT_PROJECT_BACKFACE) ? false : true; - ps->do_occlude = (settings->imapaint.flag & IMAGEPAINT_PROJECT_XRAY) ? false : true; - ps->do_mask_normal = (settings->imapaint.flag & IMAGEPAINT_PROJECT_FLAT) ? false : true; + ps->do_backfacecull = !(settings->imapaint.flag & IMAGEPAINT_PROJECT_BACKFACE); + ps->do_occlude = !(settings->imapaint.flag & IMAGEPAINT_PROJECT_XRAY); + ps->do_mask_normal = !(settings->imapaint.flag & IMAGEPAINT_PROJECT_FLAT); } else { ps->do_backfacecull = ps->do_occlude = ps->do_mask_normal = 0; } if (ps->tool == PAINT_TOOL_CLONE) { - ps->do_layer_clone = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE) ? 1 : 0; + ps->do_layer_clone = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE); } ps->do_stencil_brush = (ps->brush && ps->brush->imagepaint_tool == PAINT_TOOL_MASK); @@ -6124,7 +6124,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - idgroup = IDP_GetProperties(&image->id, 0); + idgroup = IDP_GetProperties(&image->id, false); if (idgroup) { view_data = IDP_GetPropertyTypeFromGroup(idgroup, PROJ_VIEW_DATA_ID, IDP_ARRAY); @@ -6316,7 +6316,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) /* now for the trickiness. store the view projection here! * re-projection will reuse this */ IDPropertyTemplate val; - IDProperty *idgroup = IDP_GetProperties(&image->id, 1); + IDProperty *idgroup = IDP_GetProperties(&image->id, true); IDProperty *view_data; bool is_ortho; float *array; @@ -6363,7 +6363,7 @@ void PAINT_OT_image_from_view(wmOperatorType *ot) * Data generation for projective texturing * * *******************************************/ -void ED_paint_data_warning(struct ReportList *reports, bool uvs, bool mat, bool tex, bool stencil) +void ED_paint_data_warning(ReportList *reports, bool uvs, bool mat, bool tex, bool stencil) { BKE_reportf(reports, RPT_WARNING, @@ -6939,8 +6939,11 @@ void PAINT_OT_add_texture_paint_slot(wmOperatorType *ot) "Generated Type", "Fill the image with a grid for UV map testing"); - RNA_def_boolean( - ot->srna, "float", 0, "32-bit Float", "Create image with 32-bit floating-point bit depth"); + RNA_def_boolean(ot->srna, + "float", + false, + "32-bit Float", + "Create image with 32-bit floating-point bit depth"); /* Color Attribute Properties */ RNA_def_enum(ot->srna, diff --git a/source/blender/editors/space_buttons/buttons_texture.cc b/source/blender/editors/space_buttons/buttons_texture.cc index e10371d6f80..277402f1572 100644 --- a/source/blender/editors/space_buttons/buttons_texture.cc +++ b/source/blender/editors/space_buttons/buttons_texture.cc @@ -5,8 +5,8 @@ * \ingroup spbuttons */ -#include -#include +#include +#include #include "MEM_guardedalloc.h" diff --git a/source/blender/editors/space_clip/tracking_ops_orient.cc b/source/blender/editors/space_clip/tracking_ops_orient.cc index 25c380b20cf..afb83d5f363 100644 --- a/source/blender/editors/space_clip/tracking_ops_orient.cc +++ b/source/blender/editors/space_clip/tracking_ops_orient.cc @@ -41,7 +41,7 @@ static Object *get_camera_with_movieclip(Scene *scene, const MovieClip *clip) { Object *camera = scene->camera; - if (camera != NULL && BKE_object_movieclip_get(scene, camera, false) == clip) { + if (camera != nullptr && BKE_object_movieclip_get(scene, camera, false) == clip) { return camera; } @@ -66,7 +66,7 @@ static Object *get_orientation_object(bContext *C) MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); - Object *object = NULL; + Object *object = nullptr; if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { object = get_camera_with_movieclip(scene, clip); @@ -76,7 +76,7 @@ static Object *get_orientation_object(bContext *C) object = BKE_view_layer_active_object_get(view_layer); } - if (object != NULL && object->parent != NULL) { + if (object != nullptr && object->parent != nullptr) { object = object->parent; } @@ -86,18 +86,18 @@ static Object *get_orientation_object(bContext *C) static bool set_orientation_poll(bContext *C) { SpaceClip *sc = CTX_wm_space_clip(C); - if (sc != NULL) { + if (sc != nullptr) { const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); MovieClip *clip = ED_space_clip_get_clip(sc); - if (clip != NULL) { + if (clip != nullptr) { MovieTracking *tracking = &clip->tracking; MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { return true; } BKE_view_layer_synced_ensure(scene, view_layer); - return BKE_view_layer_active_object_get(view_layer) != NULL; + return BKE_view_layer_active_object_get(view_layer) != nullptr; } } return false; @@ -122,7 +122,7 @@ static void object_solver_inverted_matrix(Scene *scene, Object *ob, float invmat bool found = false; LISTBASE_FOREACH (bConstraint *, con, &ob->constraints) { const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - if (cti == NULL) { + if (cti == nullptr) { continue; } if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) { @@ -147,15 +147,15 @@ static Object *object_solver_camera(Scene *scene, Object *ob) { LISTBASE_FOREACH (bConstraint *, con, &ob->constraints) { const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - if (cti == NULL) { + if (cti == nullptr) { continue; } if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) { bObjectSolverConstraint *data = (bObjectSolverConstraint *)con->data; - return (data->camera != NULL) ? data->camera : scene->camera; + return (data->camera != nullptr) ? data->camera : scene->camera; } } - return NULL; + return nullptr; } static int set_origin_exec(bContext *C, wmOperator *op) @@ -177,7 +177,7 @@ static int set_origin_exec(bContext *C, wmOperator *op) } Object *object = get_orientation_object(C); - if (object == NULL) { + if (object == nullptr) { BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); return OPERATOR_CANCELLED; } @@ -210,7 +210,7 @@ static int set_origin_exec(bContext *C, wmOperator *op) DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, nullptr); return OPERATOR_FINISHED; } @@ -231,8 +231,11 @@ void CLIP_OT_set_origin(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_boolean( - ot->srna, "use_median", 0, "Use Median", "Set origin to median point of selected bundles"); + RNA_def_boolean(ot->srna, + "use_median", + false, + "Use Median", + "Set origin to median point of selected bundles"); } /********************** set floor operator *********************/ @@ -366,7 +369,7 @@ static void set_axis(Scene *scene, } } - BKE_object_apply_mat4(ob, mat, 0, 0); + BKE_object_apply_mat4(ob, mat, false, false); } static int set_plane_exec(bContext *C, wmOperator *op) @@ -375,7 +378,7 @@ static int set_plane_exec(bContext *C, wmOperator *op) MovieClip *clip = ED_space_clip_get_clip(sc); Scene *scene = CTX_data_scene(C); MovieTracking *tracking = &clip->tracking; - const MovieTrackingTrack *axis_track = NULL; + const MovieTrackingTrack *axis_track = nullptr; Object *camera = get_camera_with_movieclip(scene, clip); int tot = 0; float vec[3][3], mat[4][4], obmat[4][4], newmat[4][4], orig[3] = {0.0f, 0.0f, 0.0f}; @@ -396,7 +399,7 @@ static int set_plane_exec(bContext *C, wmOperator *op) const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); Object *object = get_orientation_object(C); - if (object == NULL) { + if (object == nullptr) { BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); return OPERATOR_CANCELLED; } @@ -453,17 +456,17 @@ static int set_plane_exec(bContext *C, wmOperator *op) BKE_object_to_mat4(object, obmat); mul_m4_m4m4(mat, mat, obmat); mul_m4_m4m4(newmat, rot, mat); - BKE_object_apply_mat4(object, newmat, 0, 0); + BKE_object_apply_mat4(object, newmat, false, false); /* Make camera have positive z-coordinate. */ if (object->loc[2] < 0) { invert_m4(rot); mul_m4_m4m4(newmat, rot, mat); - BKE_object_apply_mat4(object, newmat, 0, 0); + BKE_object_apply_mat4(object, newmat, false, false); } } else { - BKE_object_apply_mat4(object, mat, 0, 0); + BKE_object_apply_mat4(object, mat, false, false); } Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); @@ -479,7 +482,7 @@ static int set_plane_exec(bContext *C, wmOperator *op) DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, nullptr); return OPERATOR_FINISHED; } @@ -489,7 +492,7 @@ void CLIP_OT_set_plane(wmOperatorType *ot) static const EnumPropertyItem plane_items[] = { {0, "FLOOR", 0, "Floor", "Set floor plane"}, {1, "WALL", 0, "Wall", "Set wall plane"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; /* identifiers */ @@ -529,7 +532,7 @@ static int set_axis_exec(bContext *C, wmOperator *op) } object = get_orientation_object(C); - if (object == NULL) { + if (object == nullptr) { BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); return OPERATOR_CANCELLED; } @@ -549,7 +552,7 @@ static int set_axis_exec(bContext *C, wmOperator *op) DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, nullptr); return OPERATOR_FINISHED; } @@ -559,7 +562,7 @@ void CLIP_OT_set_axis(wmOperatorType *ot) static const EnumPropertyItem axis_actions[] = { {0, "X", 0, "X", "Align bundle align X axis"}, {1, "Y", 0, "Y", "Align bundle align Y axis"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; /* identifiers */ @@ -590,7 +593,7 @@ static int do_set_scale(bContext *C, wmOperator *op, bool scale_solution, bool a MovieTracking *tracking = &clip->tracking; MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); Scene *scene = CTX_data_scene(C); - Object *object = NULL; + Object *object = nullptr; Object *camera = get_camera_with_movieclip(scene, clip); int tot = 0; float vec[2][3], mat[4][4], scale; @@ -603,7 +606,7 @@ static int do_set_scale(bContext *C, wmOperator *op, bool scale_solution, bool a if (!scale_solution && !apply_scale) { object = get_orientation_object(C); - if (object == NULL) { + if (object == nullptr) { BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); return OPERATOR_CANCELLED; } @@ -638,7 +641,7 @@ static int do_set_scale(bContext *C, wmOperator *op, bool scale_solution, bool a } WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, nullptr); } else { if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { @@ -667,7 +670,7 @@ static int do_set_scale(bContext *C, wmOperator *op, bool scale_solution, bool a } WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, nullptr); } } @@ -723,9 +726,9 @@ void CLIP_OT_set_scale(wmOperatorType *ot) static bool set_solution_scale_poll(bContext *C) { SpaceClip *sc = CTX_wm_space_clip(C); - if (sc != NULL) { + if (sc != nullptr) { MovieClip *clip = ED_space_clip_get_clip(sc); - if (clip != NULL) { + if (clip != nullptr) { MovieTracking *tracking = &clip->tracking; MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); return (tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0; @@ -785,15 +788,15 @@ void CLIP_OT_set_solution_scale(wmOperatorType *ot) static bool apply_solution_scale_poll(bContext *C) { SpaceClip *sc = CTX_wm_space_clip(C); - if (sc != NULL) { + if (sc != nullptr) { MovieClip *clip = ED_space_clip_get_clip(sc); - if (clip != NULL) { + if (clip != nullptr) { MovieTracking *tracking = &clip->tracking; MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); return (tracking_object->flag & TRACKING_OBJECT_CAMERA) != 0; } } - return 0; + return false; } static int apply_solution_scale_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc index c40ba5d016b..cd1c3f8280b 100644 --- a/source/blender/editors/space_file/filelist.cc +++ b/source/blender/editors/space_file/filelist.cc @@ -249,15 +249,15 @@ struct FileList { /* Set given path as root directory, * if last bool is true may change given string in place to a valid value. * Returns True if valid dir. */ - bool (*check_dir_fn)(struct FileList *, char *, const bool); + bool (*check_dir_fn)(FileList *, char *, const bool); /* Fill filelist (to be called by read job). */ - void (*read_job_fn)(struct FileListReadJob *, bool *, bool *, float *); + void (*read_job_fn)(FileListReadJob *, bool *, bool *, float *); /* Filter an entry of current filelist. */ - bool (*filter_fn)(struct FileListInternEntry *, const char *, FileListFilter *); + bool (*filter_fn)(FileListInternEntry *, const char *, FileListFilter *); /* Executed before filtering individual items, to set up additional filter data. */ - void (*prepare_filter_fn)(const struct FileList *, FileListFilter *); + void (*prepare_filter_fn)(const FileList *, FileListFilter *); short tags; /* FileListTags */ }; @@ -557,7 +557,7 @@ static int compare_extension(void *user_data, const void *a1, const void *a2) return compare_apply_inverted(compare_tiebreaker(entry1, entry2), sort_data); } -void filelist_sort(struct FileList *filelist) +void filelist_sort(FileList *filelist) { if (filelist->flags & FL_NEED_SORTING) { int (*sort_cb)(void *, const void *, const void *) = nullptr; @@ -590,7 +590,7 @@ void filelist_sort(struct FileList *filelist) } } -void filelist_setsorting(struct FileList *filelist, const short sort, bool invert_sort) +void filelist_setsorting(FileList *filelist, const short sort, bool invert_sort) { const bool was_invert_sort = filelist->flags & FL_SORT_INVERT; @@ -1139,14 +1139,14 @@ void filelist_file_get_full_path(const FileList *filelist, const FileDirEntry *f BLI_path_join(r_path, FILE_MAX_LIBEXTRA, root, file->relpath); } -static FileDirEntry *filelist_geticon_get_file(struct FileList *filelist, const int index) +static FileDirEntry *filelist_geticon_get_file(FileList *filelist, const int index) { BLI_assert(G.background == false); return filelist_file(filelist, index); } -ImBuf *filelist_getimage(struct FileList *filelist, const int index) +ImBuf *filelist_getimage(FileList *filelist, const int index) { FileDirEntry *file = filelist_geticon_get_file(filelist, index); @@ -1177,7 +1177,7 @@ ImBuf *filelist_geticon_image_ex(const FileDirEntry *file) return ibuf; } -ImBuf *filelist_geticon_image(struct FileList *filelist, const int index) +ImBuf *filelist_geticon_image(FileList *filelist, const int index) { FileDirEntry *file = filelist_geticon_get_file(filelist, index); return filelist_geticon_image_ex(file); @@ -1208,7 +1208,7 @@ static int filelist_geticon_ex(const FileList *filelist, } /* If this path is in System list or path cache then use that icon. */ - struct FSMenu *fsmenu = ED_fsmenu_get(); + FSMenu *fsmenu = ED_fsmenu_get(); FSMenuCategory categories[] = { FS_CATEGORY_SYSTEM, FS_CATEGORY_SYSTEM_BOOKMARKS, @@ -1299,7 +1299,7 @@ static int filelist_geticon_ex(const FileList *filelist, return is_main ? ICON_FILE_BLANK : ICON_NONE; } -int filelist_geticon(struct FileList *filelist, const int index, const bool is_main) +int filelist_geticon(FileList *filelist, const int index, const bool is_main) { FileDirEntry *file = filelist_geticon_get_file(filelist, index); @@ -1330,9 +1330,7 @@ static void parent_dir_until_exists_or_default_root(char *dir) } } -static bool filelist_checkdir_dir(struct FileList * /*filelist*/, - char *r_dir, - const bool do_change) +static bool filelist_checkdir_dir(FileList * /*filelist*/, char *r_dir, const bool do_change) { if (do_change) { parent_dir_until_exists_or_default_root(r_dir); @@ -1341,9 +1339,7 @@ static bool filelist_checkdir_dir(struct FileList * /*filelist*/, return BLI_is_dir(r_dir); } -static bool filelist_checkdir_lib(struct FileList * /*filelist*/, - char *r_dir, - const bool do_change) +static bool filelist_checkdir_lib(FileList * /*filelist*/, char *r_dir, const bool do_change) { char tdir[FILE_MAX_LIBEXTRA]; char *name; @@ -1360,13 +1356,13 @@ static bool filelist_checkdir_lib(struct FileList * /*filelist*/, return is_valid; } -static bool filelist_checkdir_main(struct FileList *filelist, char *r_dir, const bool do_change) +static bool filelist_checkdir_main(FileList *filelist, char *r_dir, const bool do_change) { /* TODO */ return filelist_checkdir_lib(filelist, r_dir, do_change); } -static bool filelist_checkdir_main_assets(struct FileList * /*filelist*/, +static bool filelist_checkdir_main_assets(FileList * /*filelist*/, char * /*r_dir*/, const bool /*do_change*/) { @@ -1796,7 +1792,7 @@ static void filelist_clear_asset_library(FileList *filelist) file_delete_asset_catalog_filter_settings(&filelist->filter_data.asset_catalog_filter); } -void filelist_clear_ex(struct FileList *filelist, +void filelist_clear_ex(FileList *filelist, const bool do_asset_library, const bool do_cache, const bool do_selection) @@ -1873,7 +1869,7 @@ void filelist_clear_from_reset_tag(FileList *filelist) } } -void filelist_free(struct FileList *filelist) +void filelist_free(FileList *filelist) { if (!filelist) { printf("Attempting to delete empty filelist.\n"); @@ -1901,7 +1897,7 @@ AssetLibrary *filelist_asset_library(FileList *filelist) return reinterpret_cast<::AssetLibrary *>(filelist->asset_library); } -void filelist_freelib(struct FileList *filelist) +void filelist_freelib(FileList *filelist) { if (filelist->libfiledata) { BLO_blendhandle_close(filelist->libfiledata); @@ -1909,7 +1905,7 @@ void filelist_freelib(struct FileList *filelist) filelist->libfiledata = nullptr; } -BlendHandle *filelist_lib(struct FileList *filelist) +BlendHandle *filelist_lib(FileList *filelist) { return filelist->libfiledata; } @@ -1964,12 +1960,12 @@ const char *filelist_dir(const FileList *filelist) return filelist->filelist.root; } -bool filelist_is_dir(struct FileList *filelist, const char *path) +bool filelist_is_dir(FileList *filelist, const char *path) { return filelist->check_dir_fn(filelist, (char *)path, false); } -void filelist_setdir(struct FileList *filelist, char *r_dir) +void filelist_setdir(FileList *filelist, char *r_dir) { const bool allow_invalid = filelist->asset_library_ref != nullptr; BLI_assert(strlen(r_dir) < FILE_MAX_LIBEXTRA); @@ -1985,7 +1981,7 @@ void filelist_setdir(struct FileList *filelist, char *r_dir) } } -void filelist_setrecursion(struct FileList *filelist, const int recursion_level) +void filelist_setrecursion(FileList *filelist, const int recursion_level) { if (filelist->max_recursion != recursion_level) { filelist->max_recursion = recursion_level; @@ -2011,12 +2007,12 @@ void filelist_tag_force_reset_mainfiles(FileList *filelist) filelist->flags |= FL_FORCE_RESET_MAIN_FILES; } -bool filelist_is_ready(struct FileList *filelist) +bool filelist_is_ready(FileList *filelist) { return (filelist->flags & FL_IS_READY) != 0; } -bool filelist_pending(struct FileList *filelist) +bool filelist_pending(FileList *filelist) { return (filelist->flags & FL_IS_PENDING) != 0; } @@ -2085,7 +2081,7 @@ static void filelist_file_release_entry(FileList *filelist, FileDirEntry *entry) filelist_entry_free(entry); } -FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index, const bool use_request) +FileDirEntry *filelist_file_ex(FileList *filelist, const int index, const bool use_request) { FileDirEntry *ret = nullptr, *old; FileListEntryCache *cache = &filelist->filelist_cache; @@ -2135,12 +2131,12 @@ FileDirEntry *filelist_file_ex(struct FileList *filelist, const int index, const return ret; } -FileDirEntry *filelist_file(struct FileList *filelist, int index) +FileDirEntry *filelist_file(FileList *filelist, int index) { return filelist_file_ex(filelist, index, true); } -int filelist_file_find_path(struct FileList *filelist, const char *filename) +int filelist_file_find_path(FileList *filelist, const char *filename) { if (filelist->filelist.entries_filtered_num == FILEDIR_NBR_ENTRIES_UNSET) { return -1; @@ -2247,9 +2243,7 @@ static bool filelist_file_cache_block_create(FileList *filelist, return false; } -static void filelist_file_cache_block_release(struct FileList *filelist, - const int size, - int cursor) +static void filelist_file_cache_block_release(FileList *filelist, const int size, int cursor) { FileListEntryCache *cache = &filelist->filelist_cache; @@ -2272,7 +2266,7 @@ static void filelist_file_cache_block_release(struct FileList *filelist, } } -bool filelist_file_cache_block(struct FileList *filelist, const int index) +bool filelist_file_cache_block(FileList *filelist, const int index) { FileListEntryCache *cache = &filelist->filelist_cache; const size_t cache_size = cache->size; @@ -2856,7 +2850,7 @@ void filelist_entry_parent_select_set(FileList *filelist, } } -bool filelist_islibrary(struct FileList *filelist, char *dir, char **r_group) +bool filelist_islibrary(FileList *filelist, char *dir, char **r_group) { return BLO_library_path_explode(filelist->filelist.root, dir, r_group, nullptr); } @@ -2952,7 +2946,7 @@ static int filelist_readjob_list_dir(FileListReadJob *job_params, const char *main_name, const bool skip_currpar) { - struct direntry *files; + direntry *files; int entries_num = 0; /* Full path of the item. */ char full_path[FILE_MAX]; @@ -3119,7 +3113,7 @@ static void filelist_readjob_list_lib_add_datablocks(FileListReadJob *job_params const char *group_name) { for (LinkNode *ln = datablock_infos; ln; ln = ln->next) { - struct BLODataBlockInfo *datablock_info = static_cast(ln->link); + BLODataBlockInfo *datablock_info = static_cast(ln->link); filelist_readjob_list_lib_add_datablock( job_params, entries, datablock_info, prefix_relpath_with_group_name, idcode, group_name); } @@ -3155,14 +3149,14 @@ static FileListInternEntry *filelist_readjob_list_lib_navigate_to_parent_entry_c /** * Structure to keep the file indexer and its user data together. */ -typedef struct FileIndexer { +struct FileIndexer { const FileIndexerType *callbacks; /** * User data. Contains the result of `callbacks.init_user_data`. */ void *user_data; -} FileIndexer; +}; static int filelist_readjob_list_lib_populate_from_index(FileListReadJob *job_params, ListBase *entries, @@ -3196,7 +3190,7 @@ static std::optional filelist_readjob_list_lib(FileListReadJob *job_params, char dir[FILE_MAX_LIBEXTRA], *group; - struct BlendHandle *libfiledata = nullptr; + BlendHandle *libfiledata = nullptr; /* Check if the given root is actually a library. All folders are passed to * `filelist_readjob_list_lib` and based on the number of found entries `filelist_readjob_do` @@ -3732,7 +3726,7 @@ static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params, FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */ FileListInternEntry *entry; - ListBase tmp_entries = {0}; + ListBase tmp_entries = {nullptr}; ID *id_iter; int entries_num = 0; diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index a77b6dd2787..669961351cb 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -810,23 +810,23 @@ static void create_inspection_string_for_generic_value(const bNodeSocket &socket id_to_inspection_string(*static_cast(buffer), ID_OB); return; } - else if (value_type.is()) { + if (value_type.is()) { id_to_inspection_string(*static_cast(buffer), ID_MA); return; } - else if (value_type.is()) { + if (value_type.is()) { id_to_inspection_string(*static_cast(buffer), ID_TE); return; } - else if (value_type.is()) { + if (value_type.is()) { id_to_inspection_string(*static_cast(buffer), ID_IM); return; } - else if (value_type.is()) { + if (value_type.is()) { id_to_inspection_string(*static_cast(buffer), ID_GR); return; } - else if (value_type.is()) { + if (value_type.is()) { ss << *static_cast(buffer) << TIP_(" (String)"); return; } @@ -1738,7 +1738,7 @@ static std::optional node_get_execution_time( if (node.type == NODE_GROUP_OUTPUT) { return tree_log->run_time_sum; } - else if (node.is_frame()) { + if (node.is_frame()) { /* Could be cached in the future if this recursive code turns out to be slow. */ std::chrono::nanoseconds run_time{0}; bool found_node = false; diff --git a/source/blender/editors/space_outliner/outliner_ops.cc b/source/blender/editors/space_outliner/outliner_ops.cc index cf9c4834667..0a51d62bdeb 100644 --- a/source/blender/editors/space_outliner/outliner_ops.cc +++ b/source/blender/editors/space_outliner/outliner_ops.cc @@ -16,7 +16,7 @@ namespace blender::ed::outliner { /** \name Registration * \{ */ -void outliner_operatortypes(void) +void outliner_operatortypes() { WM_operatortype_append(OUTLINER_OT_highlight_update); WM_operatortype_append(OUTLINER_OT_item_activate); diff --git a/source/blender/editors/transform/transform_snap.cc b/source/blender/editors/transform/transform_snap.cc index bf7848b6972..ab7318cbc67 100644 --- a/source/blender/editors/transform/transform_snap.cc +++ b/source/blender/editors/transform/transform_snap.cc @@ -5,7 +5,7 @@ * \ingroup edtransform */ -#include +#include #include "PIL_time.h" @@ -398,7 +398,7 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td nullptr, mval_fl, nullptr, - 0, + nullptr, loc, no); if (hit != SCE_SNAP_MODE_FACE_RAYCAST) { @@ -467,7 +467,7 @@ static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td init_loc, nullptr, prev_loc, - 0, + nullptr, snap_loc, snap_no); @@ -1382,7 +1382,7 @@ bool peelObjectsTransform(TransInfo *t, snap_object_params.snap_target_select = t->tsnap.target_select; snap_object_params.edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL; - ListBase depths_peel = {0}; + ListBase depths_peel = {nullptr}; ED_transform_snap_object_project_all_view3d_ex(t->tsnap.object_context, t->depsgraph, t->region, diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index a86098aa1d4..8bc4f79a9df 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -364,7 +364,7 @@ void unpack_menu(bContext *C, uiPopupMenu *pup; uiLayout *layout; char line[FILE_MAX + 100]; - wmOperatorType *ot = WM_operatortype_find(opname, 1); + wmOperatorType *ot = WM_operatortype_find(opname, true); const char *blendfile_path = BKE_main_blendfile_path(bmain); pup = UI_popup_menu_begin(C, IFACE_("Unpack File"), ICON_NONE); diff --git a/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp b/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp index a4b83b840f3..e076234f429 100644 --- a/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp +++ b/source/blender/freestyle/intern/python/BPy_ContextFunctions.cpp @@ -284,10 +284,10 @@ static PyModuleDef module_definition = { /*m_doc*/ module_docstring, /*m_size*/ -1, /*m_methods*/ module_functions, - /*m_slots*/ NULL, - /*m_traverse*/ NULL, - /*m_clear*/ NULL, - /*m_free*/ NULL, + /*m_slots*/ nullptr, + /*m_traverse*/ nullptr, + /*m_clear*/ nullptr, + /*m_free*/ nullptr, }; //------------------- MODULE INITIALIZATION -------------------------------- diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp index 402acd28602..60b924f0eb3 100644 --- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp +++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp @@ -516,10 +516,10 @@ static PyModuleDef module_definition = { /*m_doc*/ module_docstring, /*m_size*/ -1, /*m_methods*/ module_functions, - /*m_slots*/ NULL, - /*m_traverse*/ NULL, - /*m_clear*/ NULL, - /*m_free*/ NULL, + /*m_slots*/ nullptr, + /*m_traverse*/ nullptr, + /*m_clear*/ nullptr, + /*m_free*/ nullptr, }; //-------------------MODULE INITIALIZATION-------------------------------- diff --git a/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp b/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp index c862b226271..b70058a0b66 100644 --- a/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp +++ b/source/blender/freestyle/intern/python/BPy_IntegrationType.cpp @@ -116,10 +116,10 @@ static PyModuleDef module_definition = { /*m_doc*/ module_docstring, /*m_size*/ -1, /*m_methods*/ module_functions, - /*m_slots*/ NULL, - /*m_traverse*/ NULL, - /*m_clear*/ NULL, - /*m_free*/ NULL, + /*m_slots*/ nullptr, + /*m_traverse*/ nullptr, + /*m_clear*/ nullptr, + /*m_free*/ nullptr, }; /*-----------------------BPy_IntegrationType type definition ------------------------------*/ diff --git a/source/blender/freestyle/intern/python/BPy_Nature.cpp b/source/blender/freestyle/intern/python/BPy_Nature.cpp index c06e6859514..fbabcd110a3 100644 --- a/source/blender/freestyle/intern/python/BPy_Nature.cpp +++ b/source/blender/freestyle/intern/python/BPy_Nature.cpp @@ -57,8 +57,8 @@ static PyNumberMethods nature_as_number = { /*nb_inplace_floor_divide*/ nullptr, /*nb_inplace_true_divide*/ nullptr, /*nb_index*/ nullptr, - /*nb_matrix_multiply*/ NULL, - /*nb_inplace_matrix_multiply*/ NULL, + /*nb_matrix_multiply*/ nullptr, + /*nb_inplace_matrix_multiply*/ nullptr, }; /*-----------------------BPy_Nature docstring ------------------------------------*/ diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h index 97a3a782131..9cd88e2d523 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h +++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h @@ -848,6 +848,8 @@ BLI_INLINE int lineart_line_isec_2d_ignore_line2pos(const double a1[2], #endif } +struct bGPDframe; +struct bGPDlayer; struct Depsgraph; struct LineartGpencilModifierData; struct LineartData; @@ -886,9 +888,7 @@ void MOD_lineart_finalize_chains(LineartData *ld); bool MOD_lineart_compute_feature_lines(struct Depsgraph *depsgraph, struct LineartGpencilModifierData *lmd, struct LineartCache **cached_result, - bool enable_stroke_offset); - -struct Scene; + bool enable_stroke_depth_offset); /** * This only gets initial "biggest" tile. @@ -900,9 +900,6 @@ LineartBoundingArea *MOD_lineart_get_parent_bounding_area(LineartData *ld, doubl */ LineartBoundingArea *MOD_lineart_get_bounding_area(LineartData *ld, double x, double y); -struct bGPDframe; -struct bGPDlayer; - /** * Wrapper for external calls. */ diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index c7a83efefdc..cd3c253a7de 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -111,7 +111,7 @@ static void lineart_free_bounding_area_memory(LineartBoundingArea *ba, bool recu static void lineart_free_bounding_area_memories(LineartData *ld); -static LineartCache *lineart_init_cache(void); +static LineartCache *lineart_init_cache(); static void lineart_discard_segment(LineartData *ld, LineartEdgeSegment *es) { @@ -156,8 +156,8 @@ void lineart_edge_cut(LineartData *ld, uint32_t shadow_bits) { LineartEdgeSegment *i_seg, *prev_seg; - LineartEdgeSegment *cut_start_before = 0, *cut_end_before = 0; - LineartEdgeSegment *new_seg1 = 0, *new_seg2 = 0; + LineartEdgeSegment *cut_start_before = nullptr, *cut_end_before = nullptr; + LineartEdgeSegment *new_seg1 = nullptr, *new_seg2 = nullptr; int untouched = 0; /* If for some reason the occlusion function may give a result that has zero length, or reversed @@ -169,10 +169,10 @@ void lineart_edge_cut(LineartData *ld, return; } if (UNLIKELY(start != start)) { - start = 0; + start = 0.0; } if (UNLIKELY(end != end)) { - end = 0; + end = 0.0; } if (start > end) { @@ -472,7 +472,7 @@ void lineart_main_occlusion_begin(LineartData *ld) for (i = 0; i < thread_count; i++) { rti[i].thread_id = i; rti[i].ld = ld; - BLI_task_pool_push(tp, (TaskRunFunction)lineart_occlusion_worker, &rti[i], 0, nullptr); + BLI_task_pool_push(tp, (TaskRunFunction)lineart_occlusion_worker, &rti[i], false, nullptr); } BLI_task_pool_work_and_wait(tp); BLI_task_pool_free(tp); @@ -2069,7 +2069,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, edge_feat_settings.userdata_chunk_size = sizeof(EdgeFeatReduceData); edge_feat_settings.func_reduce = feat_data_sum_reduce; - EdgeFeatData edge_feat_data = {0}; + EdgeFeatData edge_feat_data = {nullptr}; edge_feat_data.ld = la_data; edge_feat_data.me = me; edge_feat_data.ob_eval = ob_info->original_ob_eval; @@ -2553,7 +2553,7 @@ void lineart_main_load_geometries(Depsgraph *depsgraph, flags |= DEG_ITER_OBJECT_FLAG_DUPLI; } - DEGObjectIterSettings deg_iter_settings = {0}; + DEGObjectIterSettings deg_iter_settings = {nullptr}; deg_iter_settings.depsgraph = depsgraph; deg_iter_settings.flags = flags; @@ -2599,7 +2599,7 @@ void lineart_main_load_geometries(Depsgraph *depsgraph, olti[i].ld = ld; olti[i].shadow_elns = shadow_elns; olti[i].thread_id = i; - BLI_task_pool_push(tp, (TaskRunFunction)lineart_object_load_worker, &olti[i], 0, nullptr); + BLI_task_pool_push(tp, (TaskRunFunction)lineart_object_load_worker, &olti[i], false, nullptr); } BLI_task_pool_work_and_wait(tp); BLI_task_pool_free(tp); @@ -2863,7 +2863,7 @@ static bool lineart_triangle_edge_image_space_occlusion(const LineartTriangle *t if (!isec_e1 && !isec_e2 && !isec_e3) { /* And if both end point from the edge is outside of the triangle... */ if ((!state_v1) && (!state_v2)) { - return 0; /* We don't have any occlusion. */ + return false; /* We don't have any occlusion. */ } } @@ -3190,9 +3190,9 @@ static bool lineart_triangle_intersect_math(LineartTriangle *tri, copy_v3_v3_db(v1, share->gloc); - if (!lineart_triangle_2v_intersection_math(sv1, sv2, t2, 0, v2)) { + if (!lineart_triangle_2v_intersection_math(sv1, sv2, t2, nullptr, v2)) { lineart_triangle_get_other_verts(t2, share, &sv1, &sv2); - if (lineart_triangle_2v_intersection_math(sv1, sv2, tri, 0, v2)) { + if (lineart_triangle_2v_intersection_math(sv1, sv2, tri, nullptr, v2)) { return true; } } @@ -3200,7 +3200,7 @@ static bool lineart_triangle_intersect_math(LineartTriangle *tri, else { /* If not sharing any points, then we need to try all the possibilities. */ - if (lineart_triangle_2v_intersection_math(tri->v[0], tri->v[1], t2, 0, v1)) { + if (lineart_triangle_2v_intersection_math(tri->v[0], tri->v[1], t2, nullptr, v1)) { next = v2; last = v1; } @@ -3503,7 +3503,7 @@ void MOD_lineart_destroy_render_data(LineartGpencilModifierData *lmd) } } -static LineartCache *lineart_init_cache(void) +static LineartCache *lineart_init_cache() { LineartCache *lc = static_cast( MEM_callocN(sizeof(LineartCache), "Lineart Cache")); @@ -4425,7 +4425,7 @@ LineartBoundingArea *MOD_lineart_get_parent_bounding_area(LineartData *ld, doubl int col, row; if (x > 1 || x < -1 || y > 1 || y < -1) { - return 0; + return nullptr; } col = int((x + 1.0) / sp_w); @@ -4519,8 +4519,14 @@ static void lineart_add_triangles_worker(TaskPool *__restrict /*pool*/, LineartI _dir_control++; for (co = x1; co <= x2; co++) { for (r = y1; r <= y2; r++) { - lineart_bounding_area_link_triangle( - ld, &ld->qtree.initials[r * ld->qtree.count_x + co], tri, 0, 1, 0, 1, th); + lineart_bounding_area_link_triangle(ld, + &ld->qtree.initials[r * ld->qtree.count_x + co], + tri, + nullptr, + 1, + 0, + true, + th); } } } /* Else throw away. */ @@ -4652,13 +4658,13 @@ void lineart_main_add_triangles(LineartData *ld) /* Initialize per-thread data for thread task scheduling information and storing intersection * results. */ - LineartIsecData d = {0}; + LineartIsecData d = {nullptr}; lineart_init_isec_thread(&d, ld, ld->thread_count); TaskPool *tp = BLI_task_pool_create(nullptr, TASK_PRIORITY_HIGH); for (int i = 0; i < ld->thread_count; i++) { BLI_task_pool_push( - tp, (TaskRunFunction)lineart_add_triangles_worker, &d.threads[i], 0, nullptr); + tp, (TaskRunFunction)lineart_add_triangles_worker, &d.threads[i], false, nullptr); } BLI_task_pool_work_and_wait(tp); BLI_task_pool_free(tp); @@ -4740,7 +4746,7 @@ LineartBoundingArea *lineart_bounding_area_next(LineartBoundingArea *self, r1 = ratiod(fbcoord1[0], fbcoord2[0], rx); r2 = ratiod(fbcoord1[0], fbcoord2[0], ux); if (MIN2(r1, r2) > 1) { - return 0; + return nullptr; } /* We reached the right side before the top side. */ @@ -4773,7 +4779,7 @@ LineartBoundingArea *lineart_bounding_area_next(LineartBoundingArea *self, r1 = ratiod(fbcoord1[0], fbcoord2[0], rx); r2 = ratiod(fbcoord1[0], fbcoord2[0], bx); if (MIN2(r1, r2) > 1) { - return 0; + return nullptr; } if (r1 <= r2) { LISTBASE_FOREACH (LinkData *, lip, &self->rp) { @@ -4800,7 +4806,7 @@ LineartBoundingArea *lineart_bounding_area_next(LineartBoundingArea *self, else { r1 = ratiod(fbcoord1[0], fbcoord2[0], self->r); if (r1 > 1) { - return 0; + return nullptr; } LISTBASE_FOREACH (LinkData *, lip, &self->rp) { ba = static_cast(lip->data); @@ -4825,7 +4831,7 @@ LineartBoundingArea *lineart_bounding_area_next(LineartBoundingArea *self, r1 = ratiod(fbcoord1[0], fbcoord2[0], lx); r2 = ratiod(fbcoord1[0], fbcoord2[0], ux); if (MIN2(r1, r2) > 1) { - return 0; + return nullptr; } if (r1 <= r2) { LISTBASE_FOREACH (LinkData *, lip, &self->lp) { @@ -4856,7 +4862,7 @@ LineartBoundingArea *lineart_bounding_area_next(LineartBoundingArea *self, r1 = ratiod(fbcoord1[0], fbcoord2[0], lx); r2 = ratiod(fbcoord1[0], fbcoord2[0], bx); if (MIN2(r1, r2) > 1) { - return 0; + return nullptr; } if (r1 <= r2) { LISTBASE_FOREACH (LinkData *, lip, &self->lp) { @@ -4883,7 +4889,7 @@ LineartBoundingArea *lineart_bounding_area_next(LineartBoundingArea *self, else { r1 = ratiod(fbcoord1[0], fbcoord2[0], self->l); if (r1 > 1) { - return 0; + return nullptr; } LISTBASE_FOREACH (LinkData *, lip, &self->lp) { ba = static_cast(lip->data); @@ -4900,7 +4906,7 @@ LineartBoundingArea *lineart_bounding_area_next(LineartBoundingArea *self, if (positive_y > 0) { r1 = ratiod(fbcoord1[1], fbcoord2[1], self->u); if (r1 > 1) { - return 0; + return nullptr; } LISTBASE_FOREACH (LinkData *, lip, &self->up) { ba = static_cast(lip->data); @@ -4914,7 +4920,7 @@ LineartBoundingArea *lineart_bounding_area_next(LineartBoundingArea *self, else if (positive_y < 0) { r1 = ratiod(fbcoord1[1], fbcoord2[1], self->b); if (r1 > 1) { - return 0; + return nullptr; } LISTBASE_FOREACH (LinkData *, lip, &self->bp) { ba = static_cast(lip->data); @@ -4927,10 +4933,10 @@ LineartBoundingArea *lineart_bounding_area_next(LineartBoundingArea *self, } else { /* Segment has no length. */ - return 0; + return nullptr; } } - return 0; + return nullptr; } /** diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 17639d19e61..5f02f4ed1c0 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -239,21 +239,21 @@ GPUTexture *GPU_texture_create_1d_ex(const char *name, int w, int mip_len, eGPUTextureFormat format, - eGPUTextureUsage usage_flags, + eGPUTextureUsage usage, const float *data); GPUTexture *GPU_texture_create_1d_array_ex(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, - eGPUTextureUsage usage_flags, + eGPUTextureUsage usage, const float *data); GPUTexture *GPU_texture_create_2d_ex(const char *name, int w, int h, int mips, eGPUTextureFormat format, - eGPUTextureUsage usage_flags, + eGPUTextureUsage usage, const float *data); GPUTexture *GPU_texture_create_2d_array_ex(const char *name, int w, @@ -261,7 +261,7 @@ GPUTexture *GPU_texture_create_2d_array_ex(const char *name, int d, int mip_len, eGPUTextureFormat format, - eGPUTextureUsage usage_flags, + eGPUTextureUsage usage, const float *data); GPUTexture *GPU_texture_create_3d_ex(const char *name, int w, @@ -270,20 +270,20 @@ GPUTexture *GPU_texture_create_3d_ex(const char *name, int mip_len, eGPUTextureFormat texture_format, eGPUDataFormat data_format, - eGPUTextureUsage usage_flags, + eGPUTextureUsage usage, const void *data); GPUTexture *GPU_texture_create_cube_ex(const char *name, int w, int mip_len, eGPUTextureFormat format, - eGPUTextureUsage usage_flags, + eGPUTextureUsage usage, const float *data); GPUTexture *GPU_texture_create_cube_array_ex(const char *name, int w, int d, int mip_len, eGPUTextureFormat format, - eGPUTextureUsage usage_flags, + eGPUTextureUsage usage, const float *data); /* Standard texture functions. */ diff --git a/source/blender/gpu/intern/gpu_node_graph.cc b/source/blender/gpu/intern/gpu_node_graph.cc index 72c1867416c..8f51a6b91aa 100644 --- a/source/blender/gpu/intern/gpu_node_graph.cc +++ b/source/blender/gpu/intern/gpu_node_graph.cc @@ -7,8 +7,8 @@ * Intermediate node graph for generating GLSL shaders. */ -#include -#include +#include +#include #include "MEM_guardedalloc.h" @@ -27,7 +27,7 @@ /* Node Link Functions */ -static GPUNodeLink *gpu_node_link_create(void) +static GPUNodeLink *gpu_node_link_create() { GPUNodeLink *link = MEM_cnew("GPUNodeLink"); link->users++; diff --git a/source/blender/gpu/intern/gpu_node_graph.h b/source/blender/gpu/intern/gpu_node_graph.h index 9f919f04160..6e3f71744e7 100644 --- a/source/blender/gpu/intern/gpu_node_graph.h +++ b/source/blender/gpu/intern/gpu_node_graph.h @@ -213,7 +213,7 @@ struct GPUTexture **gpu_material_ramp_texture_row_set(struct GPUMaterial *mat, * Returns the address of the future pointer to sky_tex */ struct GPUTexture **gpu_material_sky_texture_layer_set( - struct GPUMaterial *mat, int width, int height, const float *pixels, float *layer); + struct GPUMaterial *mat, int width, int height, const float *pixels, float *row); #ifdef __cplusplus } diff --git a/source/blender/gpu/opengl/gl_state.cc b/source/blender/gpu/opengl/gl_state.cc index fdeee725a2b..6cc02dac53b 100644 --- a/source/blender/gpu/opengl/gl_state.cc +++ b/source/blender/gpu/opengl/gl_state.cc @@ -643,9 +643,9 @@ void GLStateManager::issue_barrier(eGPUBarrier barrier_bits) GLFence::~GLFence() { - if (gl_sync_ != 0) { + if (gl_sync_ != nullptr) { glDeleteSync(gl_sync_); - gl_sync_ = 0; + gl_sync_ = nullptr; } } @@ -663,7 +663,7 @@ void GLFence::signal() void GLFence::wait() { /* Do not wait if fence does not yet exist. */ - if (gl_sync_ == 0) { + if (gl_sync_ == nullptr) { return; } glWaitSync(gl_sync_, 0, GL_TIMEOUT_IGNORED); diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index 6ec079f44b8..8802f6184cb 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -326,13 +326,13 @@ void GLTexture::update_sub(int offset[3], switch (dimensions) { default: case 1: - glTexSubImage1D(target_, 0, offset[0], extent[0], gl_format, gl_type, 0); + glTexSubImage1D(target_, 0, offset[0], extent[0], gl_format, gl_type, nullptr); break; case 2: - glTexSubImage2D(target_, 0, UNPACK2(offset), UNPACK2(extent), gl_format, gl_type, 0); + glTexSubImage2D(target_, 0, UNPACK2(offset), UNPACK2(extent), gl_format, gl_type, nullptr); break; case 3: - glTexSubImage3D(target_, 0, UNPACK3(offset), UNPACK3(extent), gl_format, gl_type, 0); + glTexSubImage3D(target_, 0, UNPACK3(offset), UNPACK3(extent), gl_format, gl_type, nullptr); break; } @@ -794,7 +794,7 @@ GLPixelBuffer::GLPixelBuffer(uint size) : PixelBuffer(size) size = max_ii(size, 32); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, gl_id_); - glBufferData(GL_PIXEL_UNPACK_BUFFER, size, 0, GL_DYNAMIC_DRAW); + glBufferData(GL_PIXEL_UNPACK_BUFFER, size, nullptr, GL_DYNAMIC_DRAW); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h index ac287856fa9..cb7ea707d20 100644 --- a/source/blender/imbuf/IMB_thumbs.h +++ b/source/blender/imbuf/IMB_thumbs.h @@ -85,7 +85,7 @@ struct ImBuf *IMB_thumb_load_blend(const char *blen_path, /** * Special function for previewing fonts. */ -struct ImBuf *IMB_thumb_load_font(const char *filepath, unsigned int x, unsigned int y); +struct ImBuf *IMB_thumb_load_font(const char *filename, unsigned int x, unsigned int y); bool IMB_thumb_load_font_get_hash(char *r_hash); /* Threading */ diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index eac29ac5e61..9a75be07cf4 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -312,7 +312,7 @@ static PointerRNA rna_uiItemO(uiLayout *layout, { wmOperatorType *ot; - ot = WM_operatortype_find(opname, 0); /* print error next */ + ot = WM_operatortype_find(opname, false); /* print error next */ if (!ot || !ot->srna) { RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname); return PointerRNA_NULL; @@ -343,7 +343,7 @@ static PointerRNA rna_uiItemOMenuHold(uiLayout *layout, int icon_value, const char *menu) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + wmOperatorType *ot = WM_operatortype_find(opname, false); /* print error next */ if (!ot || !ot->srna) { RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname); return PointerRNA_NULL; @@ -381,7 +381,7 @@ static PointerRNA rna_uiItemMenuEnumO(uiLayout *layout, bool translate, int icon) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); /* print error next */ + wmOperatorType *ot = WM_operatortype_find(opname, false); /* print error next */ if (!ot || !ot->srna) { RNA_warning("%s '%s'", ot ? "unknown operator" : "operator missing srna", opname); diff --git a/source/blender/makesrna/intern/rna_wm_gizmo_api.c b/source/blender/makesrna/intern/rna_wm_gizmo_api.c index 760121d2279..0fded614d73 100644 --- a/source/blender/makesrna/intern/rna_wm_gizmo_api.c +++ b/source/blender/makesrna/intern/rna_wm_gizmo_api.c @@ -147,7 +147,7 @@ static PointerRNA rna_gizmo_target_set_operator(wmGizmo *gz, { wmOperatorType *ot; - ot = WM_operatortype_find(opname, 0); /* print error next */ + ot = WM_operatortype_find(opname, false); /* print error next */ if (!ot || !ot->srna) { BKE_reportf( reports, RPT_ERROR, "%s '%s'", ot ? "unknown operator" : "operator missing srna", opname); diff --git a/source/blender/modifiers/intern/MOD_displace.cc b/source/blender/modifiers/intern/MOD_displace.cc index 7f4b308017b..db90242fd55 100644 --- a/source/blender/modifiers/intern/MOD_displace.cc +++ b/source/blender/modifiers/intern/MOD_displace.cc @@ -78,7 +78,7 @@ static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_ma } } -static bool dependsOnTime(struct Scene * /*scene*/, ModifierData *md) +static bool dependsOnTime(Scene * /*scene*/, ModifierData *md) { DisplaceModifierData *dmd = (DisplaceModifierData *)md; @@ -108,7 +108,7 @@ static void foreachTexLink(ModifierData *md, Object *ob, TexWalkFunc walk, void walk(userData, ob, md, "texture"); } -static bool isDisabled(const struct Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/) +static bool isDisabled(const Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/) { DisplaceModifierData *dmd = (DisplaceModifierData *)md; return ((!dmd->texture && dmd->direction == MOD_DISP_DIR_RGB_XYZ) || dmd->strength == 0.0f); @@ -142,10 +142,10 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte } } -typedef struct DisplaceUserdata { +struct DisplaceUserdata { /*const*/ DisplaceModifierData *dmd; - struct Scene *scene; - struct ImagePool *pool; + Scene *scene; + ImagePool *pool; const MDeformVert *dvert; float weight; int defgrp_index; @@ -158,7 +158,7 @@ typedef struct DisplaceUserdata { MVert *mvert; const float (*vert_normals)[3]; float (*vert_clnors)[3]; -} DisplaceUserdata; +}; static void displaceModifier_do_task(void *__restrict userdata, const int iter, @@ -381,7 +381,7 @@ static void deformVerts(ModifierData *md, static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, - struct BMEditMesh *editData, + BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], int verts_num) @@ -444,7 +444,7 @@ static void panel_draw(const bContext *C, Panel *panel) uiItemS(layout); col = uiLayoutColumn(layout, false); - uiItemR(col, ptr, "direction", 0, 0, ICON_NONE); + uiItemR(col, ptr, "direction", 0, nullptr, ICON_NONE); if (ELEM(RNA_enum_get(ptr, "direction"), MOD_DISP_DIR_X, MOD_DISP_DIR_Y, diff --git a/source/blender/modifiers/intern/MOD_screw.cc b/source/blender/modifiers/intern/MOD_screw.cc index 930fa0c1aab..5d9e6a84422 100644 --- a/source/blender/modifiers/intern/MOD_screw.cc +++ b/source/blender/modifiers/intern/MOD_screw.cc @@ -350,7 +350,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * gives problems with float precision so its never closed. */ if (fabsf(screw_ofs) <= (FLT_EPSILON * 100.0f) && fabsf(fabsf(angle) - (float(M_PI) * 2.0f)) <= (FLT_EPSILON * 100.0f) && step_tot > 3) { - close = 1; + close = true; step_tot--; maxVerts = totvert * step_tot; /* -1 because we're joining back up */ @@ -361,7 +361,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * screw_ofs = 0.0f; } else { - close = 0; + close = false; if (step_tot < 2) { step_tot = 2; } @@ -644,10 +644,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * vf_best = vc_tmp->co[ltmd->axis]; if (vf_1 < vf_best && vf_best < vf_2) { - ed_loop_flip = 0; + ed_loop_flip = false; } else if (vf_1 > vf_best && vf_best > vf_2) { - ed_loop_flip = 1; + ed_loop_flip = true; } else { /* not so simple to work out which edge is higher */ @@ -657,20 +657,20 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * normalize_v3(tmp_vec2); if (tmp_vec1[ltmd->axis] < tmp_vec2[ltmd->axis]) { - ed_loop_flip = 1; + ed_loop_flip = true; } else { - ed_loop_flip = 0; + ed_loop_flip = false; } } } else if (SV_IS_VALID(vc_tmp->v[0])) { /* Vertex only connected on 1 side. */ // printf("Verts on ONE side (%i %i)\n", vc_tmp->v[0], vc_tmp->v[1]); if (tmpf1[ltmd->axis] < vc_tmp->co[ltmd->axis]) { /* best is above */ - ed_loop_flip = 1; + ed_loop_flip = true; } else { /* best is below or even... in even case we can't know what to do. */ - ed_loop_flip = 0; + ed_loop_flip = false; } } #if 0 diff --git a/source/blender/modifiers/intern/MOD_triangulate.cc b/source/blender/modifiers/intern/MOD_triangulate.cc index 993ce852129..73ec3e25afe 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.cc +++ b/source/blender/modifiers/intern/MOD_triangulate.cc @@ -4,7 +4,7 @@ * \ingroup modifiers */ -#include +#include #include "MEM_guardedalloc.h" diff --git a/source/blender/modifiers/intern/MOD_util.cc b/source/blender/modifiers/intern/MOD_util.cc index 844e2d19a58..9e8bbc477b7 100644 --- a/source/blender/modifiers/intern/MOD_util.cc +++ b/source/blender/modifiers/intern/MOD_util.cc @@ -186,7 +186,7 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob, &mesh_prior_modifiers->id, nullptr, (LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_CD_REFERENCE)); - mesh->runtime->deformed_only = 1; + mesh->runtime->deformed_only = true; } if (em != nullptr) { diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 9ded1827ccc..c537fe67422 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -717,7 +717,7 @@ class GroupOutputDebugInfo : public lf::DummyDebugInfo { public: Vector socket_names; - std::string node_name() const + std::string node_name() const override { return "Group Output"; } diff --git a/source/blender/nodes/intern/node_util.cc b/source/blender/nodes/intern/node_util.cc index 73bf20c6836..61ff81fa346 100644 --- a/source/blender/nodes/intern/node_util.cc +++ b/source/blender/nodes/intern/node_util.cc @@ -5,9 +5,9 @@ * \ingroup nodes */ -#include -#include -#include +#include +#include +#include #include "DNA_node_types.h" diff --git a/source/blender/nodes/texture/node_texture_tree.cc b/source/blender/nodes/texture/node_texture_tree.cc index 3b26fe9dc14..5a814728897 100644 --- a/source/blender/nodes/texture/node_texture_tree.cc +++ b/source/blender/nodes/texture/node_texture_tree.cc @@ -5,7 +5,7 @@ * \ingroup nodes */ -#include +#include #include "DNA_node_types.h" #include "DNA_space_types.h" @@ -132,7 +132,7 @@ static bool texture_node_tree_socket_type_valid(bNodeTreeType * /*ntreetype*/, bNodeTreeType *ntreeType_Texture; -void register_node_tree_type_tex(void) +void register_node_tree_type_tex() { bNodeTreeType *tt = ntreeType_Texture = MEM_cnew("texture node tree type"); diff --git a/source/blender/nodes/texture/nodes/node_texture_at.cc b/source/blender/nodes/texture/nodes/node_texture_at.cc index 0b486e365b6..e7b4e600df8 100644 --- a/source/blender/nodes/texture/nodes/node_texture_at.cc +++ b/source/blender/nodes/texture/nodes/node_texture_at.cc @@ -38,7 +38,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[0], &colorfn, static_cast(data)); } -void register_node_type_tex_at(void) +void register_node_type_tex_at() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_bricks.cc b/source/blender/nodes/texture/nodes/node_texture_bricks.cc index 40b5e48569b..123f3d09c19 100644 --- a/source/blender/nodes/texture/nodes/node_texture_bricks.cc +++ b/source/blender/nodes/texture/nodes/node_texture_bricks.cc @@ -8,7 +8,7 @@ #include "NOD_texture.h" #include "node_texture_util.hh" -#include +#include static bNodeSocketTemplate inputs[] = { {SOCK_RGBA, N_("Bricks 1"), 0.596f, 0.282f, 0.0f, 1.0f}, @@ -99,7 +99,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[0], &colorfn, static_cast(data)); } -void register_node_type_tex_bricks(void) +void register_node_type_tex_bricks() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_checker.cc b/source/blender/nodes/texture/nodes/node_texture_checker.cc index 96d48b94275..c3a6bf34d39 100644 --- a/source/blender/nodes/texture/nodes/node_texture_checker.cc +++ b/source/blender/nodes/texture/nodes/node_texture_checker.cc @@ -7,7 +7,7 @@ #include "NOD_texture.h" #include "node_texture_util.hh" -#include +#include static bNodeSocketTemplate inputs[] = { {SOCK_RGBA, N_("Color1"), 1.0f, 0.0f, 0.0f, 1.0f}, @@ -50,7 +50,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[0], &colorfn, static_cast(data)); } -void register_node_type_tex_checker(void) +void register_node_type_tex_checker() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_combine_color.cc b/source/blender/nodes/texture/nodes/node_texture_combine_color.cc index d63cb2172b8..9b9ad4724fb 100644 --- a/source/blender/nodes/texture/nodes/node_texture_combine_color.cc +++ b/source/blender/nodes/texture/nodes/node_texture_combine_color.cc @@ -63,7 +63,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[0], &colorfn, static_cast(data)); } -void register_node_type_tex_combine_color(void) +void register_node_type_tex_combine_color() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_compose.cc b/source/blender/nodes/texture/nodes/node_texture_compose.cc index 7ec1742a4f1..06b45125738 100644 --- a/source/blender/nodes/texture/nodes/node_texture_compose.cc +++ b/source/blender/nodes/texture/nodes/node_texture_compose.cc @@ -38,7 +38,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[0], &colorfn, static_cast(data)); } -void register_node_type_tex_compose(void) +void register_node_type_tex_compose() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_coord.cc b/source/blender/nodes/texture/nodes/node_texture_coord.cc index b8b9b0a369d..36d39c11f28 100644 --- a/source/blender/nodes/texture/nodes/node_texture_coord.cc +++ b/source/blender/nodes/texture/nodes/node_texture_coord.cc @@ -29,7 +29,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[0], &vectorfn, static_cast(data)); } -void register_node_type_tex_coord(void) +void register_node_type_tex_coord() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_curves.cc b/source/blender/nodes/texture/nodes/node_texture_curves.cc index 3d93ae8b418..b1554c03e51 100644 --- a/source/blender/nodes/texture/nodes/node_texture_curves.cc +++ b/source/blender/nodes/texture/nodes/node_texture_curves.cc @@ -46,7 +46,7 @@ static void time_init(bNodeTree * /*ntree*/, bNode *node) node->storage = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); } -void register_node_type_tex_curve_time(void) +void register_node_type_tex_curve_time() { static bNodeType ntype; @@ -96,7 +96,7 @@ static void rgb_init(bNodeTree * /*ntree*/, bNode *node) node->storage = BKE_curvemapping_add(4, 0.0f, 0.0f, 1.0f, 1.0f); } -void register_node_type_tex_curve_rgb(void) +void register_node_type_tex_curve_rgb() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_decompose.cc b/source/blender/nodes/texture/nodes/node_texture_decompose.cc index b10e7022396..1904614899d 100644 --- a/source/blender/nodes/texture/nodes/node_texture_decompose.cc +++ b/source/blender/nodes/texture/nodes/node_texture_decompose.cc @@ -7,7 +7,7 @@ #include "NOD_texture.h" #include "node_texture_util.hh" -#include +#include static bNodeSocketTemplate inputs[] = { {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f}, @@ -59,7 +59,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[3], &valuefn_a, tex_call_data); } -void register_node_type_tex_decompose(void) +void register_node_type_tex_decompose() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_hueSatVal.cc b/source/blender/nodes/texture/nodes/node_texture_hueSatVal.cc index 9a27ac5f19d..d78d4243f18 100644 --- a/source/blender/nodes/texture/nodes/node_texture_hueSatVal.cc +++ b/source/blender/nodes/texture/nodes/node_texture_hueSatVal.cc @@ -87,7 +87,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[0], &colorfn, static_cast(data)); } -void register_node_type_tex_hue_sat(void) +void register_node_type_tex_hue_sat() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_image.cc b/source/blender/nodes/texture/nodes/node_texture_image.cc index c1b238b6a00..ff348d934de 100644 --- a/source/blender/nodes/texture/nodes/node_texture_image.cc +++ b/source/blender/nodes/texture/nodes/node_texture_image.cc @@ -87,7 +87,7 @@ static void init(bNodeTree * /*ntree*/, bNode *node) iuser->flag |= IMA_ANIM_ALWAYS; } -void register_node_type_tex_image(void) +void register_node_type_tex_image() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_invert.cc b/source/blender/nodes/texture/nodes/node_texture_invert.cc index fb54edfdbcc..3cd386cfacb 100644 --- a/source/blender/nodes/texture/nodes/node_texture_invert.cc +++ b/source/blender/nodes/texture/nodes/node_texture_invert.cc @@ -43,7 +43,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[0], &colorfn, static_cast(data)); } -void register_node_type_tex_invert(void) +void register_node_type_tex_invert() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_math.cc b/source/blender/nodes/texture/nodes/node_texture_math.cc index 484cc2c3afc..61ba126cf07 100644 --- a/source/blender/nodes/texture/nodes/node_texture_math.cc +++ b/source/blender/nodes/texture/nodes/node_texture_math.cc @@ -315,7 +315,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[0], &valuefn, static_cast(data)); } -void register_node_type_tex_math(void) +void register_node_type_tex_math() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_rotate.cc b/source/blender/nodes/texture/nodes/node_texture_rotate.cc index b711d5445fe..18398ec5807 100644 --- a/source/blender/nodes/texture/nodes/node_texture_rotate.cc +++ b/source/blender/nodes/texture/nodes/node_texture_rotate.cc @@ -5,7 +5,7 @@ * \ingroup texnodes */ -#include +#include #include "NOD_texture.h" #include "node_texture_util.hh" @@ -75,7 +75,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[0], &colorfn, static_cast(data)); } -void register_node_type_tex_rotate(void) +void register_node_type_tex_rotate() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_scale.cc b/source/blender/nodes/texture/nodes/node_texture_scale.cc index 5cf986d855e..d7deb0f81fe 100644 --- a/source/blender/nodes/texture/nodes/node_texture_scale.cc +++ b/source/blender/nodes/texture/nodes/node_texture_scale.cc @@ -6,7 +6,7 @@ */ #include "node_texture_util.hh" -#include +#include static bNodeSocketTemplate inputs[] = { {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f}, @@ -48,7 +48,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[0], &colorfn, static_cast(data)); } -void register_node_type_tex_scale(void) +void register_node_type_tex_scale() { static bNodeType ntype; diff --git a/source/blender/nodes/texture/nodes/node_texture_separate_color.cc b/source/blender/nodes/texture/nodes/node_texture_separate_color.cc index e56999d1b2c..6d10f6e378b 100644 --- a/source/blender/nodes/texture/nodes/node_texture_separate_color.cc +++ b/source/blender/nodes/texture/nodes/node_texture_separate_color.cc @@ -8,7 +8,7 @@ #include "BLI_listbase.h" #include "NOD_texture.h" #include "node_texture_util.hh" -#include +#include static bNodeSocketTemplate inputs[] = { {SOCK_RGBA, N_("Color"), 0.0f, 0.0f, 0.0f, 1.0f}, @@ -90,7 +90,7 @@ static void exec(void *data, tex_output(node, execdata, in, out[3], &valuefn_a, tex_call_data); } -void register_node_type_tex_separate_color(void) +void register_node_type_tex_separate_color() { static bNodeType ntype; diff --git a/source/blender/render/intern/bake.cc b/source/blender/render/intern/bake.cc index 5a66b5b4dca..e88dbcc3778 100644 --- a/source/blender/render/intern/bake.cc +++ b/source/blender/render/intern/bake.cc @@ -47,7 +47,7 @@ * For a complete implementation example look at the Cycles Bake commit. */ -#include +#include #include "MEM_guardedalloc.h" @@ -74,31 +74,31 @@ /* local include */ #include "zbuf.h" -typedef struct BakeDataZSpan { +struct BakeDataZSpan { BakePixel *pixel_array; int primitive_id; BakeImage *bk_image; ZSpan *zspan; float du_dx, du_dy; float dv_dx, dv_dy; -} BakeDataZSpan; +}; /** * struct wrapping up tangent space data */ -typedef struct TSpace { +struct TSpace { float tangent[3]; float sign; -} TSpace; +}; -typedef struct TriTessFace { +struct TriTessFace { const MVert *mverts[3]; const float *vert_normals[3]; const TSpace *tspace[3]; const float *loop_normal[3]; float normal[3]; /* for flat faces */ bool is_smooth; -} TriTessFace; +}; static void store_bake_pixel(void *handle, int x, int y, float u, float v) { @@ -536,7 +536,7 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval return triangles; } -bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, +bool RE_bake_pixels_populate_from_objects(Mesh *me_low, BakePixel pixel_array_from[], BakePixel pixel_array_to[], BakeHighPolyData highpoly[], @@ -547,7 +547,7 @@ bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, const float max_ray_distance, float mat_low[4][4], float mat_cage[4][4], - struct Mesh *me_cage) + Mesh *me_cage) { size_t i; int primitive_id; @@ -968,7 +968,7 @@ void RE_bake_normal_world_to_object(const BakePixel pixel_array[], const size_t pixels_num, const int depth, float result[], - struct Object *ob, + Object *ob, const eBakeNormalSwizzle normal_swizzle[3]) { size_t i; diff --git a/source/blender/render/intern/engine.cc b/source/blender/render/intern/engine.cc index daca91eec4f..77b1e240cda 100644 --- a/source/blender/render/intern/engine.cc +++ b/source/blender/render/intern/engine.cc @@ -48,7 +48,6 @@ #include "DRW_engine.h" -#include "GPU_context.h" #include "WM_api.h" #include "pipeline.h" diff --git a/source/blender/render/intern/multires_bake.cc b/source/blender/render/intern/multires_bake.cc index d1d302aa369..155096d890c 100644 --- a/source/blender/render/intern/multires_bake.cc +++ b/source/blender/render/intern/multires_bake.cc @@ -5,7 +5,7 @@ * \ingroup render */ -#include +#include #include "MEM_guardedalloc.h" @@ -40,26 +40,26 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -typedef void (*MPassKnownData)(DerivedMesh *lores_dm, - DerivedMesh *hires_dm, - void *thread_data, - void *bake_data, - ImBuf *ibuf, - const int face_index, - const int lvl, - const float st[2], - float tangmat[3][3], - const int x, - const int y); +using MPassKnownData = void (*)(DerivedMesh *lores_dm, + DerivedMesh *hires_dm, + void *thread_data, + void *bake_data, + ImBuf *ibuf, + const int face_index, + const int lvl, + const float st[2], + float tangmat[3][3], + const int x, + const int y); -typedef void *(*MInitBakeData)(MultiresBakeRender *bkr, ImBuf *ibuf); -typedef void (*MFreeBakeData)(void *bake_data); +using MInitBakeData = void *(*)(MultiresBakeRender *bkr, ImBuf *ibuf); +using MFreeBakeData = void (*)(void *bake_data); -typedef struct MultiresBakeResult { +struct MultiresBakeResult { float height_min, height_max; -} MultiresBakeResult; +}; -typedef struct { +struct MResolvePixelData { MVert *mvert; const float (*vert_normals)[3]; MPoly *mpoly; @@ -80,32 +80,32 @@ typedef struct { MPassKnownData pass_data; /* material aligned UV array */ Image **image_array; -} MResolvePixelData; +}; -typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y); +using MFlushPixel = void (*)(const MResolvePixelData *data, const int x, const int y); -typedef struct { +struct MBakeRast { int w, h; char *texels; const MResolvePixelData *data; MFlushPixel flush_pixel; bool *do_update; -} MBakeRast; +}; -typedef struct { +struct MHeightBakeData { float *heights; DerivedMesh *ssdm; const int *orig_index_mp_to_orig; -} MHeightBakeData; +}; -typedef struct { +struct MNormalBakeData { const int *orig_index_mp_to_orig; -} MNormalBakeData; +}; -typedef struct BakeImBufuserData { +struct BakeImBufuserData { float *displacement_buffer; char *mask_buffer; -} BakeImBufuserData; +}; static void multiresbake_get_normal(const MResolvePixelData *data, const int tri_num, @@ -334,13 +334,13 @@ static int multiresbake_test_break(MultiresBakeRender *bkr) /* **** Threading routines **** */ -typedef struct MultiresBakeQueue { +struct MultiresBakeQueue { int cur_tri; int tot_tri; SpinLock spin; -} MultiresBakeQueue; +}; -typedef struct MultiresBakeThread { +struct MultiresBakeThread { /* this data is actually shared between all the threads */ MultiresBakeQueue *queue; MultiresBakeRender *bkr; @@ -353,7 +353,7 @@ typedef struct MultiresBakeThread { /* displacement-specific data */ float height_min, height_max; -} MultiresBakeThread; +}; static int multires_bake_queue_next_tri(MultiresBakeQueue *queue) { diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index acacbd77f9e..9c724916dd5 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -984,7 +984,7 @@ const wmKeyMapItem *WM_modalkeymap_find_propvalue(const wmKeyMap *km, const int void WM_modalkeymap_assign(wmKeyMap *km, const char *opname) { - wmOperatorType *ot = WM_operatortype_find(opname, 0); + wmOperatorType *ot = WM_operatortype_find(opname, false); if (ot) { ot->modalkeymap = km; From 363e5e28ee87ae6d15fbc65abc104ee5a815dbe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 29 Dec 2022 18:20:48 +0100 Subject: [PATCH 0315/1522] DRW: Fix issues with multiview Resource ids buf must be allocated for the worst case scenario. Also fix issue with non procedural data overriding procedural view. --- source/blender/draw/intern/draw_command.cc | 2 +- source/blender/draw/intern/draw_view.cc | 2 +- source/blender/draw/intern/draw_view.hh | 5 +++-- .../draw/intern/shaders/draw_command_generate_comp.glsl | 4 +++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/source/blender/draw/intern/draw_command.cc b/source/blender/draw/intern/draw_command.cc index 58bca3b9792..8c89c28a628 100644 --- a/source/blender/draw/intern/draw_command.cc +++ b/source/blender/draw/intern/draw_command.cc @@ -597,7 +597,7 @@ void DrawMultiBuf::bind(RecordingState &state, for (DrawGroup &group : MutableSpan(group_buf_.data(), group_count_)) { /* Compute prefix sum of all instance of previous group. */ group.start = resource_id_count_; - resource_id_count_ += group.len; + resource_id_count_ += group.len * view_len; int batch_inst_len; /* Now that GPUBatches are guaranteed to be finished, extract their parameters. */ diff --git a/source/blender/draw/intern/draw_view.cc b/source/blender/draw/intern/draw_view.cc index 28e8bef912b..2e303aa9295 100644 --- a/source/blender/draw/intern/draw_view.cc +++ b/source/blender/draw/intern/draw_view.cc @@ -205,7 +205,7 @@ void View::frustum_culling_sphere_calc(const BoundBox &bbox, BoundSphere &bspher void View::bind() { - if (dirty_) { + if (dirty_ && !procedural_) { dirty_ = false; data_.push_update(); culling_.push_update(); diff --git a/source/blender/draw/intern/draw_view.hh b/source/blender/draw/intern/draw_view.hh index 5c5f20df1c3..cded44e5a56 100644 --- a/source/blender/draw/intern/draw_view.hh +++ b/source/blender/draw/intern/draw_view.hh @@ -51,10 +51,11 @@ class View { bool do_visibility_ = true; bool dirty_ = true; bool frozen_ = false; + bool procedural_ = false; public: - View(const char *name, int view_len = 1) - : visibility_buf_(name), debug_name_(name), view_len_(view_len) + View(const char *name, int view_len = 1, bool procedural = false) + : visibility_buf_(name), debug_name_(name), view_len_(view_len), procedural_(procedural) { BLI_assert(view_len < DRW_VIEW_MAX); } diff --git a/source/blender/draw/intern/shaders/draw_command_generate_comp.glsl b/source/blender/draw/intern/shaders/draw_command_generate_comp.glsl index b08c5a4d314..ddb4baf8f5b 100644 --- a/source/blender/draw/intern/shaders/draw_command_generate_comp.glsl +++ b/source/blender/draw/intern/shaders/draw_command_generate_comp.glsl @@ -51,6 +51,8 @@ void main() if (visibility_word_per_draw > 0) { uint visibility_word = resource_index * visibility_word_per_draw; for (uint i = 0; i < visibility_word_per_draw; i++, visibility_word++) { + /* \note: This assumes proto.instance_len is 1. */ + /* TODO: Assert. */ visible_instance_len += bitCount(visibility_buf[visibility_word]); } } @@ -89,7 +91,7 @@ void main() } } - /* Fill resource_id buffer for each instance of this draw */ + /* Fill resource_id buffer for each instance of this draw. */ if (visibility_word_per_draw > 0) { uint visibility_word = resource_index * visibility_word_per_draw; for (uint i = 0; i < visibility_word_per_draw; i++, visibility_word++) { From 4d39b6b3f4911123290c776fbaee7b0bcb4e3011 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 29 Dec 2022 19:36:15 +0100 Subject: [PATCH 0316/1522] Geometry Nodes: skip logging socket values for invisible trees Geometry nodes used to log all socket values during evaluation. This allowed the user to hover over any socket (that was evaluated) to see its last value. The problem is that in large (nested) node trees, the number of sockets becomes huge, causing a lot of performance and memory overhead (in extreme cases, more than 70% of the total execution time). This patch changes it so, that only socket values are logged that the user is likely to investigate. The simple heuristic is that socket values of the currently visible node tree are logged. The downside is that when the user changes the visible node tree, it won't have any logged values until it is reevaluated. I updated the tooltip message for that case to be a bit more precise. If user feedback suggests that this new behavior is too annoying, we can always add a UI option to log all socket values again. That shouldn't be done without an actual need though because it takes up UI space. Differential Revision: https://developer.blender.org/D16884 --- .../blender/editors/space_node/node_draw.cc | 4 ++- source/blender/modifiers/intern/MOD_nodes.cc | 30 ++++++++++++++++ .../nodes/NOD_geometry_nodes_lazy_function.hh | 14 +++++++- .../blender/nodes/NOD_geometry_nodes_log.hh | 2 ++ .../intern/geometry_nodes_lazy_function.cc | 18 +++++++--- .../nodes/intern/geometry_nodes_log.cc | 34 ++++++++++++------- 6 files changed, 83 insertions(+), 19 deletions(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 669961351cb..bb9c16ada54 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -1117,7 +1117,9 @@ static char *node_socket_get_tooltip(const bContext *C, output << *socket_inspection_str; } else { - output << TIP_("The socket value has not been computed yet"); + output << TIP_( + "Unknown socket value. Either the socket was not used or its value was not logged " + "during the last evaluation"); } } diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 258971c3565..ebd5bf351ea 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -923,6 +923,31 @@ static void find_side_effect_nodes( } } +static void find_socket_log_contexts(const NodesModifierData &nmd, + const ModifierEvalContext &ctx, + Set &r_socket_log_contexts) +{ + Main *bmain = DEG_get_bmain(ctx.depsgraph); + wmWindowManager *wm = (wmWindowManager *)bmain->wm.first; + if (wm == nullptr) { + return; + } + LISTBASE_FOREACH (const wmWindow *, window, &wm->windows) { + const bScreen *screen = BKE_workspace_active_screen_get(window->workspace_hook); + LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) { + const SpaceLink *sl = static_cast(area->spacedata.first); + if (sl->spacetype == SPACE_NODE) { + const SpaceNode &snode = *reinterpret_cast(sl); + if (const std::optional hash = blender::nodes::geo_eval_log:: + GeoModifierLog::get_compute_context_hash_for_node_editor(snode, + nmd.modifier.name)) { + r_socket_log_contexts.add(*hash); + } + } + } + } +} + static void clear_runtime_data(NodesModifierData *nmd) { if (nmd->runtime_eval_log != nullptr) { @@ -1122,8 +1147,13 @@ static GeometrySet compute_geometry( geo_nodes_modifier_data.depsgraph = ctx->depsgraph; geo_nodes_modifier_data.self_object = ctx->object; auto eval_log = std::make_unique(); + + Set socket_log_contexts; if (logging_enabled(ctx)) { geo_nodes_modifier_data.eval_log = eval_log.get(); + + find_socket_log_contexts(*nmd, *ctx, socket_log_contexts); + geo_nodes_modifier_data.socket_log_contexts = &socket_log_contexts; } MultiValueMap r_side_effect_nodes; find_side_effect_nodes(*nmd, *ctx, r_side_effect_nodes); diff --git a/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh b/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh index f21100414b3..84c264f4976 100644 --- a/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh +++ b/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh @@ -48,7 +48,15 @@ struct GeoNodesModifierData { * Some nodes should be executed even when their output is not used (e.g. active viewer nodes and * the node groups they are contained in). */ - const MultiValueMap *side_effect_nodes; + const MultiValueMap *side_effect_nodes = nullptr; + /** + * Controls in which compute contexts we want to log socket values. Logging them in all contexts + * can result in slowdowns. In the majority of cases, the logged socket values are freed without + * being looked at anyway. + * + * If this is null, all socket values will be logged. + */ + const Set *socket_log_contexts = nullptr; }; /** @@ -64,6 +72,10 @@ struct GeoNodesLFUserData : public lf::UserData { * evaluated. */ const ComputeContext *compute_context = nullptr; + /** + * Log socket values in the current compute context. Child contexts might use logging again. + */ + bool log_socket_values = true; }; /** diff --git a/source/blender/nodes/NOD_geometry_nodes_log.hh b/source/blender/nodes/NOD_geometry_nodes_log.hh index d99dff21c6d..95e54f1b9a5 100644 --- a/source/blender/nodes/NOD_geometry_nodes_log.hh +++ b/source/blender/nodes/NOD_geometry_nodes_log.hh @@ -332,6 +332,8 @@ class GeoModifierLog { /** * Utility accessor to logged data. */ + static std::optional get_compute_context_hash_for_node_editor( + const SpaceNode &snode, StringRefNull modifier_name); static GeoTreeLog *get_tree_log_for_node_editor(const SpaceNode &snode); static const ViewerNodeLog *find_viewer_node_log_for_path(const ViewerPath &viewer_path); }; diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index c537fe67422..57033e89bf7 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -667,6 +667,10 @@ class LazyFunctionForGroupNode : public LazyFunction { group_node_.identifier}; GeoNodesLFUserData group_user_data = *user_data; group_user_data.compute_context = &compute_context; + if (user_data->modifier_data->socket_log_contexts) { + group_user_data.log_socket_values = user_data->modifier_data->socket_log_contexts->contains( + compute_context.hash()); + } lf::Context group_context = context; group_context.user_data = &group_user_data; @@ -1305,17 +1309,21 @@ void GeometryNodesLazyFunctionLogger::log_socket_value( const GPointer value, const fn::lazy_function::Context &context) const { + GeoNodesLFUserData *user_data = dynamic_cast(context.user_data); + BLI_assert(user_data != nullptr); + if (!user_data->log_socket_values) { + return; + } + if (user_data->modifier_data->eval_log == nullptr) { + return; + } + const Span bsockets = lf_graph_info_.mapping.bsockets_by_lf_socket_map.lookup(&lf_socket); if (bsockets.is_empty()) { return; } - GeoNodesLFUserData *user_data = dynamic_cast(context.user_data); - BLI_assert(user_data != nullptr); - if (user_data->modifier_data->eval_log == nullptr) { - return; - } geo_eval_log::GeoTreeLogger &tree_logger = user_data->modifier_data->eval_log->get_local_tree_logger(*user_data->compute_context); for (const bNodeSocket *bsocket : bsockets) { diff --git a/source/blender/nodes/intern/geometry_nodes_log.cc b/source/blender/nodes/intern/geometry_nodes_log.cc index eb2e9bd9015..660f878c1f7 100644 --- a/source/blender/nodes/intern/geometry_nodes_log.cc +++ b/source/blender/nodes/intern/geometry_nodes_log.cc @@ -513,6 +513,23 @@ static std::optional get_modifier_for_node_editor(const Space return ObjectAndModifier{object, used_modifier}; } +std::optional GeoModifierLog::get_compute_context_hash_for_node_editor( + const SpaceNode &snode, const StringRefNull modifier_name) +{ + Vector tree_path = snode.treepath; + if (tree_path.is_empty()) { + return std::nullopt; + } + ComputeContextBuilder compute_context_builder; + compute_context_builder.push(modifier_name); + for (const int i : tree_path.index_range().drop_back(1)) { + /* The tree path contains the name of the node but not its ID. */ + const bNode *node = nodeFindNodebyName(tree_path[i]->nodetree, tree_path[i + 1]->node_name); + compute_context_builder.push(*node); + } + return compute_context_builder.hash(); +} + GeoTreeLog *GeoModifierLog::get_tree_log_for_node_editor(const SpaceNode &snode) { std::optional object_and_modifier = get_modifier_for_node_editor(snode); @@ -524,19 +541,12 @@ GeoTreeLog *GeoModifierLog::get_tree_log_for_node_editor(const SpaceNode &snode) if (modifier_log == nullptr) { return nullptr; } - Vector tree_path = snode.treepath; - if (tree_path.is_empty()) { - return nullptr; + if (const std::optional hash = + GeoModifierLog::get_compute_context_hash_for_node_editor( + snode, object_and_modifier->nmd->modifier.name)) { + return &modifier_log->get_tree_log(*hash); } - ComputeContextBuilder compute_context_builder; - compute_context_builder.push( - object_and_modifier->nmd->modifier.name); - for (const int i : tree_path.index_range().drop_back(1)) { - /* The tree path contains the name of the node but not its ID. */ - const bNode *node = nodeFindNodebyName(tree_path[i]->nodetree, tree_path[i + 1]->node_name); - compute_context_builder.push(*node); - } - return &modifier_log->get_tree_log(compute_context_builder.hash()); + return nullptr; } const ViewerNodeLog *GeoModifierLog::find_viewer_node_log_for_path(const ViewerPath &viewer_path) From 5dcce58510798137dd3a9af5193d05d47f583e7d Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 29 Dec 2022 14:09:58 -0500 Subject: [PATCH 0317/1522] Cleanup: Use simpler vector for dragged node links Use a vector of node links instead of pointers to node links allocated separately. Only allocate a link if it's added (back) to the tree. --- .../blender/editors/space_node/node_draw.cc | 10 +- .../blender/editors/space_node/node_intern.hh | 2 +- .../editors/space_node/node_relationships.cc | 140 +++++++++--------- 3 files changed, 73 insertions(+), 79 deletions(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index bb9c16ada54..6933646836d 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -2645,9 +2645,9 @@ static void count_multi_input_socket_links(bNodeTree &ntree, SpaceNode &snode) } /* Count temporary links going into this socket. */ if (snode.runtime->linkdrag) { - for (const bNodeLink *link : snode.runtime->linkdrag->links) { - if (link->tosock && (link->tosock->flag & SOCK_MULTI_INPUT)) { - int &count = counts.lookup_or_add(link->tosock, 0); + for (const bNodeLink &link : snode.runtime->linkdrag->links) { + if (link.tosock && (link.tosock->flag & SOCK_MULTI_INPUT)) { + int &count = counts.lookup_or_add(link.tosock, 0); count++; } } @@ -3277,8 +3277,8 @@ void node_draw_space(const bContext &C, ARegion ®ion) GPU_blend(GPU_BLEND_ALPHA); GPU_line_smooth(true); if (snode.runtime->linkdrag) { - for (const bNodeLink *link : snode.runtime->linkdrag->links) { - node_draw_link_dragged(C, v2d, snode, *link); + for (const bNodeLink &link : snode.runtime->linkdrag->links) { + node_draw_link_dragged(C, v2d, snode, link); } } GPU_line_smooth(false); diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index 9b2d55ab107..65174edbdbe 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -43,7 +43,7 @@ struct AssetItemTree; /** Temporary data used in node link drag modal operator. */ struct bNodeLinkDrag { /** Links dragged by the operator. */ - Vector links; + Vector links; eNodeSocketInOut in_out; /** Draw handler for the "+" icon when dragging a link in empty space. */ diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 222fae7cbc2..ca9ee0c245e 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -79,18 +79,18 @@ static void clear_picking_highlight(ListBase *links) /** \name Add Node * \{ */ -static bNodeLink *create_drag_link(bNode &node, bNodeSocket &sock) +static bNodeLink create_drag_link(bNode &node, bNodeSocket &socket) { - bNodeLink *oplink = MEM_cnew(__func__); - if (sock.in_out == SOCK_OUT) { - oplink->fromnode = &node; - oplink->fromsock = &sock; + bNodeLink oplink{}; + if (socket.in_out == SOCK_OUT) { + oplink.fromnode = &node; + oplink.fromsock = &socket; } else { - oplink->tonode = &node; - oplink->tosock = &sock; + oplink.tonode = &node; + oplink.tosock = &socket; } - oplink->flag |= NODE_LINK_VALID; + oplink.flag |= NODE_LINK_VALID; return oplink; } @@ -101,7 +101,7 @@ static void pick_link(bNodeLinkDrag &nldrag, { clear_picking_highlight(&snode.edittree->links); - bNodeLink *link = create_drag_link(*link_to_pick.fromnode, *link_to_pick.fromsock); + bNodeLink link = create_drag_link(*link_to_pick.fromnode, *link_to_pick.fromsock); nldrag.links.append(link); nodeRemLink(snode.edittree, &link_to_pick); @@ -764,15 +764,15 @@ void NODE_OT_link_viewer(wmOperatorType *ot) static bool dragged_links_are_detached(const bNodeLinkDrag &nldrag) { if (nldrag.in_out == SOCK_OUT) { - for (const bNodeLink *link : nldrag.links) { - if (link->tonode && link->tosock) { + for (const bNodeLink &link : nldrag.links) { + if (link.tonode && link.tosock) { return false; } } } else { - for (const bNodeLink *link : nldrag.links) { - if (link->fromnode && link->fromsock) { + for (const bNodeLink &link : nldrag.links) { + if (link.fromnode && link.fromsock) { return false; } } @@ -835,7 +835,7 @@ static void draw_draglink_tooltip_deactivate(const ARegion ®ion, bNodeLinkDra } } -static void node_link_update_header(bContext *C, bNodeLinkDrag * /*nldrag*/) +static void node_link_update_header(bContext *C, bNodeLinkDrag & /*nldrag*/) { char header[UI_MAX_DRAW_STR]; @@ -901,28 +901,27 @@ static void add_dragged_links_to_tree(bContext &C, bNodeLinkDrag &nldrag) SpaceNode &snode = *CTX_wm_space_node(&C); bNodeTree &ntree = *snode.edittree; - for (bNodeLink *link : nldrag.links) { - if (!link->tosock || !link->fromsock) { - MEM_freeN(link); + for (const bNodeLink &link : nldrag.links) { + if (!link.tosock || !link.fromsock) { continue; } - /* before actually adding the link, * let nodes perform special link insertion handling */ - if (link->fromnode->typeinfo->insert_link) { - link->fromnode->typeinfo->insert_link(&ntree, link->fromnode, link); + bNodeLink *new_link = MEM_new(__func__, link); + if (link.fromnode->typeinfo->insert_link) { + link.fromnode->typeinfo->insert_link(&ntree, link.fromnode, new_link); } - if (link->tonode->typeinfo->insert_link) { - link->tonode->typeinfo->insert_link(&ntree, link->tonode, link); + if (link.tonode->typeinfo->insert_link) { + link.tonode->typeinfo->insert_link(&ntree, link.tonode, new_link); } /* add link to the node tree */ - BLI_addtail(&ntree.links, link); - BKE_ntree_update_tag_link_added(&ntree, link); + BLI_addtail(&ntree.links, new_link); + BKE_ntree_update_tag_link_added(&ntree, new_link); /* we might need to remove a link */ - node_remove_extra_links(snode, *link); + node_remove_extra_links(snode, *new_link); } ED_node_tree_propagate_change(&C, bmain, &ntree); @@ -943,9 +942,6 @@ static void node_link_cancel(bContext *C, wmOperator *op) bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op->customdata; draw_draglink_tooltip_deactivate(*CTX_wm_region(C), *nldrag); UI_view2d_edge_pan_cancel(C, &nldrag->pan_data); - for (bNodeLink *link : nldrag->links) { - MEM_freeN(link); - } snode->runtime->linkdrag.reset(); clear_picking_highlight(&snode->edittree->links); } @@ -953,50 +949,50 @@ static void node_link_cancel(bContext *C, wmOperator *op) static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cursor) { SpaceNode &snode = *CTX_wm_space_node(&C); - bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op.customdata; + bNodeLinkDrag &nldrag = *static_cast(op.customdata); - if (nldrag->in_out == SOCK_OUT) { + if (nldrag.in_out == SOCK_OUT) { bNode *tnode; bNodeSocket *tsock = nullptr; snode.edittree->ensure_topology_cache(); if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_IN)) { - for (bNodeLink *link : nldrag->links) { + for (bNodeLink &link : nldrag.links) { /* skip if socket is on the same node as the fromsock */ - if (tnode && link->fromnode == tnode) { + if (tnode && link.fromnode == tnode) { continue; } /* Skip if tsock is already linked with this output. */ bNodeLink *existing_link_connected_to_fromsock = nullptr; LISTBASE_FOREACH (bNodeLink *, existing_link, &snode.edittree->links) { - if (existing_link->fromsock == link->fromsock && existing_link->tosock == tsock) { + if (existing_link->fromsock == link.fromsock && existing_link->tosock == tsock) { existing_link_connected_to_fromsock = existing_link; break; } } /* attach links to the socket */ - link->tonode = tnode; - link->tosock = tsock; - nldrag->last_node_hovered_while_dragging_a_link = tnode; + link.tonode = tnode; + link.tosock = tsock; + nldrag.last_node_hovered_while_dragging_a_link = tnode; if (existing_link_connected_to_fromsock) { - link->multi_input_socket_index = + link.multi_input_socket_index = existing_link_connected_to_fromsock->multi_input_socket_index; continue; } - if (link->tosock && link->tosock->flag & SOCK_MULTI_INPUT) { - sort_multi_input_socket_links_with_drag(*tnode, *link, cursor); + if (link.tosock && link.tosock->flag & SOCK_MULTI_INPUT) { + sort_multi_input_socket_links_with_drag(*tnode, link, cursor); } } } else { - for (bNodeLink *link : nldrag->links) { - link->tonode = nullptr; - link->tosock = nullptr; + for (bNodeLink &link : nldrag.links) { + link.tonode = nullptr; + link.tosock = nullptr; } - if (nldrag->last_node_hovered_while_dragging_a_link) { + if (nldrag.last_node_hovered_while_dragging_a_link) { update_multi_input_indices_for_removed_links( - *nldrag->last_node_hovered_while_dragging_a_link); + *nldrag.last_node_hovered_while_dragging_a_link); } } } @@ -1004,25 +1000,25 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur bNode *tnode; bNodeSocket *tsock = nullptr; if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_OUT)) { - for (bNodeLink *link : nldrag->links) { + for (bNodeLink &link : nldrag.links) { /* skip if this is already the target socket */ - if (link->fromsock == tsock) { + if (link.fromsock == tsock) { continue; } /* skip if socket is on the same node as the fromsock */ - if (tnode && link->tonode == tnode) { + if (tnode && link.tonode == tnode) { continue; } /* attach links to the socket */ - link->fromnode = tnode; - link->fromsock = tsock; + link.fromnode = tnode; + link.fromsock = tsock; } } else { - for (bNodeLink *link : nldrag->links) { - link->fromnode = nullptr; - link->fromsock = nullptr; + for (bNodeLink &link : nldrag.links) { + link.fromnode = nullptr; + link.fromsock = nullptr; } } } @@ -1030,21 +1026,21 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event) { - bNodeLinkDrag *nldrag = (bNodeLinkDrag *)op->customdata; + bNodeLinkDrag &nldrag = *static_cast(op->customdata); SpaceNode &snode = *CTX_wm_space_node(C); ARegion *region = CTX_wm_region(C); - UI_view2d_edge_pan_apply_event(C, &nldrag->pan_data, event); + UI_view2d_edge_pan_apply_event(C, &nldrag.pan_data, event); float2 cursor; UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &cursor.x, &cursor.y); - nldrag->cursor[0] = event->mval[0]; - nldrag->cursor[1] = event->mval[1]; + nldrag.cursor[0] = event->mval[0]; + nldrag.cursor[1] = event->mval[1]; switch (event->type) { case MOUSEMOVE: - if (nldrag->start_socket->is_multi_input() && nldrag->links.is_empty()) { - pick_input_link_by_link_intersect(*C, *op, *nldrag, cursor); + if (nldrag.start_socket->is_multi_input() && nldrag.links.is_empty()) { + pick_input_link_by_link_intersect(*C, *op, nldrag, cursor); } else { node_link_find_socket(*C, *op, cursor); @@ -1053,19 +1049,19 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event) ED_region_tag_redraw(region); } - if (should_create_drag_link_search_menu(*snode.edittree, *nldrag)) { - draw_draglink_tooltip_activate(*region, *nldrag); + if (should_create_drag_link_search_menu(*snode.edittree, nldrag)) { + draw_draglink_tooltip_activate(*region, nldrag); } else { - draw_draglink_tooltip_deactivate(*region, *nldrag); + draw_draglink_tooltip_deactivate(*region, nldrag); } break; case LEFTMOUSE: if (event->val == KM_RELEASE) { /* Add a search menu for compatible sockets if the drag released on empty space. */ - if (should_create_drag_link_search_menu(*snode.edittree, *nldrag)) { - bNodeLink &link = *nldrag->links.first(); - if (nldrag->in_out == SOCK_OUT) { + if (should_create_drag_link_search_menu(*snode.edittree, nldrag)) { + bNodeLink &link = nldrag.links.first(); + if (nldrag.in_out == SOCK_OUT) { invoke_node_link_drag_add_menu(*C, *link.fromnode, *link.fromsock, cursor); } else { @@ -1073,7 +1069,7 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event) } } - add_dragged_links_to_tree(*C, *nldrag); + add_dragged_links_to_tree(*C, nldrag); return OPERATOR_FINISHED; } break; @@ -1113,10 +1109,9 @@ static std::unique_ptr node_link_init(SpaceNode &snode, /* detach current links and store them in the operator data */ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &snode.edittree->links) { if (link->fromsock == sock) { - bNodeLink *oplink = MEM_cnew("drag link op link"); - *oplink = *link; - oplink->next = oplink->prev = nullptr; - oplink->flag |= NODE_LINK_VALID; + bNodeLink oplink = *link; + oplink.next = oplink.prev = nullptr; + oplink.flag |= NODE_LINK_VALID; nldrag->links.append(oplink); nodeRemLink(snode.edittree, link); @@ -1151,10 +1146,9 @@ static std::unique_ptr node_link_init(SpaceNode &snode, } if (link_to_pick != nullptr && !nldrag->start_socket->is_multi_input()) { - bNodeLink *oplink = MEM_cnew("drag link op link"); - *oplink = *link_to_pick; - oplink->next = oplink->prev = nullptr; - oplink->flag |= NODE_LINK_VALID; + bNodeLink oplink = *link_to_pick; + oplink.next = oplink.prev = nullptr; + oplink.flag |= NODE_LINK_VALID; nldrag->links.append(oplink); nodeRemLink(snode.edittree, link_to_pick); From a09accb496d3b0f0fb11f5e36a95c607d62ba4c6 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 29 Dec 2022 20:45:51 +0100 Subject: [PATCH 0318/1522] Geometry Nodes: speedup compute context hash generation Whenever a node group is entered during evaluation, a new compute context is entered which has a corresponding hash. When node groups are entered and exited a lot, this can have some overhead. In my test file with ~100.000 node group invocations, this patch improves performance by about 7%. The speedup is achieved in two ways: * Avoid computing the same hash twice by caching it. * Invoke the hashing algorithm (md5 currently) only once instead of twice. --- .../blenkernel/BKE_compute_contexts.hh | 6 ++++- .../blenkernel/intern/compute_contexts.cc | 21 ++++++++++++++--- .../intern/geometry_nodes_lazy_function.cc | 23 +++++++++++++++---- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/BKE_compute_contexts.hh b/source/blender/blenkernel/BKE_compute_contexts.hh index 8e4bbbba524..92a6a06433c 100644 --- a/source/blender/blenkernel/BKE_compute_contexts.hh +++ b/source/blender/blenkernel/BKE_compute_contexts.hh @@ -6,6 +6,8 @@ * This file implements some specific compute contexts for concepts in Blender. */ +#include + #include "BLI_compute_context.hh" struct bNode; @@ -41,7 +43,9 @@ class NodeGroupComputeContext : public ComputeContext { #endif public: - NodeGroupComputeContext(const ComputeContext *parent, int32_t node_id); + NodeGroupComputeContext(const ComputeContext *parent, + int32_t node_id, + const std::optional &cached_hash = {}); NodeGroupComputeContext(const ComputeContext *parent, const bNode &node); int32_t node_id() const diff --git a/source/blender/blenkernel/intern/compute_contexts.cc b/source/blender/blenkernel/intern/compute_contexts.cc index 4d0fba49f85..2fc4a31f6c9 100644 --- a/source/blender/blenkernel/intern/compute_contexts.cc +++ b/source/blender/blenkernel/intern/compute_contexts.cc @@ -19,11 +19,26 @@ void ModifierComputeContext::print_current_in_line(std::ostream &stream) const stream << "Modifier: " << modifier_name_; } -NodeGroupComputeContext::NodeGroupComputeContext(const ComputeContext *parent, const int node_id) +NodeGroupComputeContext::NodeGroupComputeContext( + const ComputeContext *parent, + const int node_id, + const std::optional &cached_hash) : ComputeContext(s_static_type, parent), node_id_(node_id) { - hash_.mix_in(s_static_type, strlen(s_static_type)); - hash_.mix_in(&node_id_, sizeof(int32_t)); + if (cached_hash.has_value()) { + hash_ = *cached_hash; + } + else { + /* Mix static type and node id into a single buffer so that only a single call to #mix_in is + * necessary. */ + const int type_size = strlen(s_static_type); + const int buffer_size = type_size + 1 + sizeof(int32_t); + DynamicStackBuffer<64, 8> buffer_owner(buffer_size, 8); + char *buffer = static_cast(buffer_owner.buffer()); + memcpy(buffer, s_static_type, type_size + 1); + memcpy(buffer + type_size + 1, &node_id_, sizeof(int32_t)); + hash_.mix_in(buffer, buffer_size); + } } NodeGroupComputeContext::NodeGroupComputeContext(const ComputeContext *parent, const bNode &node) diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 57033e89bf7..a8eb532ab3f 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -601,6 +601,12 @@ class LazyFunctionForGroupNode : public LazyFunction { std::optional lf_side_effect_provider_; std::optional graph_executor_; + struct Storage { + void *graph_executor_storage = nullptr; + /* To avoid computing the hash more than once. */ + std::optional context_hash_cache; + }; + public: LazyFunctionForGroupNode(const bNode &group_node, const GeometryNodesLazyFunctionGraphInfo &lf_graph_info, @@ -662,9 +668,13 @@ class LazyFunctionForGroupNode : public LazyFunction { params.set_default_remaining_outputs(); } + Storage *storage = static_cast(context.storage); + /* The compute context changes when entering a node group. */ - bke::NodeGroupComputeContext compute_context{user_data->compute_context, - group_node_.identifier}; + bke::NodeGroupComputeContext compute_context{ + user_data->compute_context, group_node_.identifier, storage->context_hash_cache}; + storage->context_hash_cache = compute_context.hash(); + GeoNodesLFUserData group_user_data = *user_data; group_user_data.compute_context = &compute_context; if (user_data->modifier_data->socket_log_contexts) { @@ -674,18 +684,23 @@ class LazyFunctionForGroupNode : public LazyFunction { lf::Context group_context = context; group_context.user_data = &group_user_data; + group_context.storage = storage->graph_executor_storage; graph_executor_->execute(params, group_context); } void *init_storage(LinearAllocator<> &allocator) const override { - return graph_executor_->init_storage(allocator); + Storage *s = allocator.construct().release(); + s->graph_executor_storage = graph_executor_->init_storage(allocator); + return s; } void destruct_storage(void *storage) const override { - graph_executor_->destruct_storage(storage); + Storage *s = static_cast(storage); + graph_executor_->destruct_storage(s->graph_executor_storage); + std::destroy_at(s); } }; From c744d5453fdccf18e6d0ef4d283613c6ef238026 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 29 Dec 2022 14:55:27 -0500 Subject: [PATCH 0319/1522] Nodes: Make more node and socket declaration fields public When these declarations are built without the help of the special builder class, it's much more convenient to set them directly rather than with a constructor, etc. In most other situations the declarations should be const anyway, so theoretically this doesn't affect safety too much. Most construction of declarations should still use the builder. --- source/blender/blenkernel/intern/node.cc | 4 +- .../intern/node_tree_field_inferencing.cc | 8 +- .../realtime_compositor/intern/utilities.cc | 4 +- source/blender/editors/space_node/drawnode.cc | 2 +- .../blender/editors/space_node/node_draw.cc | 6 +- .../editors/space_node/node_relationships.cc | 6 +- .../editors/space_node/node_templates.cc | 6 +- source/blender/nodes/NOD_node_declaration.hh | 140 +++++------------- .../blender/nodes/NOD_socket_declarations.hh | 2 +- .../function/nodes/node_fn_random_value.cc | 2 +- .../nodes/node_geo_attribute_capture.cc | 4 +- .../nodes/node_geo_attribute_statistic.cc | 2 +- .../geometry/nodes/node_geo_blur_attribute.cc | 2 +- .../node_geo_curve_primitive_quadrilateral.cc | 2 +- .../geometry/nodes/node_geo_curve_sample.cc | 4 +- .../geometry/nodes/node_geo_curve_trim.cc | 4 +- .../geometry/nodes/node_geo_field_at_index.cc | 2 +- .../nodes/node_geo_input_named_attribute.cc | 2 +- .../nodes/node_geo_mesh_primitive_line.cc | 2 +- .../nodes/geometry/nodes/node_geo_raycast.cc | 6 +- .../geometry/nodes/node_geo_sample_index.cc | 4 +- .../nodes/node_geo_sample_nearest_surface.cc | 4 +- .../nodes/node_geo_sample_uv_surface.cc | 6 +- .../nodes/node_geo_store_named_attribute.cc | 4 +- .../intern/geometry_nodes_lazy_function.cc | 2 +- .../blender/nodes/intern/node_declaration.cc | 42 +++--- source/blender/nodes/intern/node_socket.cc | 10 +- .../nodes/intern/node_socket_declarations.cc | 96 ++++++++---- .../nodes/intern/socket_search_link.cc | 8 +- .../nodes/shader/nodes/node_shader_tex_sky.cc | 2 +- 30 files changed, 181 insertions(+), 207 deletions(-) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 8bae267d1b8..eb744f1fd66 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3599,8 +3599,8 @@ static void update_socket_declarations(ListBase *sockets, void nodeSocketDeclarationsUpdate(bNode *node) { BLI_assert(node->runtime->declaration != nullptr); - update_socket_declarations(&node->inputs, node->runtime->declaration->inputs()); - update_socket_declarations(&node->outputs, node->runtime->declaration->outputs()); + update_socket_declarations(&node->inputs, node->runtime->declaration->inputs); + update_socket_declarations(&node->outputs, node->runtime->declaration->outputs); } bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree * /*ntree*/, bNode *node) diff --git a/source/blender/blenkernel/intern/node_tree_field_inferencing.cc b/source/blender/blenkernel/intern/node_tree_field_inferencing.cc index 5c527e29131..af282485671 100644 --- a/source/blender/blenkernel/intern/node_tree_field_inferencing.cc +++ b/source/blender/blenkernel/intern/node_tree_field_inferencing.cc @@ -55,8 +55,8 @@ static InputSocketFieldType get_interface_input_field_type(const bNode &node, BLI_assert(node_decl != nullptr); /* Get the field type from the declaration. */ - const SocketDeclaration &socket_decl = *node_decl->inputs()[socket.index()]; - const InputSocketFieldType field_type = socket_decl.input_field_type(); + const SocketDeclaration &socket_decl = *node_decl->inputs[socket.index()]; + const InputSocketFieldType field_type = socket_decl.input_field_type; return field_type; } @@ -88,8 +88,8 @@ static OutputFieldDependency get_interface_output_field_dependency(const bNode & BLI_assert(node_decl != nullptr); /* Use the socket declaration. */ - const SocketDeclaration &socket_decl = *node_decl->outputs()[socket.index()]; - return socket_decl.output_field_dependency(); + const SocketDeclaration &socket_decl = *node_decl->outputs[socket.index()]; + return socket_decl.output_field_dependency; } static const FieldInferencingInterface &get_dummy_field_inferencing_interface(const bNode &node, diff --git a/source/blender/compositor/realtime_compositor/intern/utilities.cc b/source/blender/compositor/realtime_compositor/intern/utilities.cc index 25472d6ed50..711402ad97f 100644 --- a/source/blender/compositor/realtime_compositor/intern/utilities.cc +++ b/source/blender/compositor/realtime_compositor/intern/utilities.cc @@ -109,12 +109,12 @@ InputDescriptor input_descriptor_from_input_socket(const bNodeSocket *socket) InputDescriptor input_descriptor; input_descriptor.type = get_node_socket_result_type(socket); const NodeDeclaration *node_declaration = socket->owner_node().declaration(); - /* Not every node have a declaration, in which case, we assume the default values for the rest of + /* Not every node has a declaration, in which case we assume the default values for the rest of * the properties. */ if (!node_declaration) { return input_descriptor; } - const SocketDeclarationPtr &socket_declaration = node_declaration->inputs()[socket->index()]; + const SocketDeclarationPtr &socket_declaration = node_declaration->inputs[socket->index()]; input_descriptor.domain_priority = socket_declaration->compositor_domain_priority(); input_descriptor.skip_realization = socket_declaration->compositor_skip_realization(); input_descriptor.expects_single_value = socket_declaration->compositor_expects_single_value(); diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 7cca456a46f..efe7c2e91b6 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -1276,7 +1276,7 @@ static bool socket_needs_attribute_search(bNode &node, bNodeSocket &socket) return false; } const int socket_index = BLI_findindex(&node.inputs, &socket); - return node.runtime->declaration->inputs()[socket_index]->is_attribute_name(); + return node.declaration()->inputs[socket_index]->is_attribute_name; } static void std_node_socket_draw( diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 6933646836d..cf71d5c05e0 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -991,7 +991,7 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn /* If the geometry declaration is null, as is the case for input to group output, * or it is an output socket don't show supported types. */ - if (socket_decl == nullptr || socket_decl->in_out() == SOCK_OUT) { + if (socket_decl == nullptr || socket_decl->in_out == SOCK_OUT) { return; } @@ -1078,7 +1078,7 @@ static bool node_socket_has_tooltip(const bNodeTree &ntree, const bNodeSocket &s if (socket.runtime->declaration != nullptr) { const nodes::SocketDeclaration &socket_decl = *socket.runtime->declaration; - return !socket_decl.description().is_empty(); + return !socket_decl.description.empty(); } return false; @@ -1100,7 +1100,7 @@ static char *node_socket_get_tooltip(const bContext *C, std::stringstream output; if (socket->runtime->declaration != nullptr) { const blender::nodes::SocketDeclaration &socket_decl = *socket->runtime->declaration; - blender::StringRef description = socket_decl.description(); + blender::StringRef description = socket_decl.description; if (!description.is_empty()) { output << TIP_(description.data()); } diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index ca9ee0c245e..b21f69259de 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -2065,15 +2065,15 @@ bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_ nodeDeclarationEnsure(&ntree, &node); const nodes::NodeDeclaration *node_decl = node.declaration(); if (node_decl != nullptr) { - Span socket_decls = (in_out == SOCK_IN) ? node_decl->inputs() : - node_decl->outputs(); + Span socket_decls = (in_out == SOCK_IN) ? node_decl->inputs : + node_decl->outputs; int index; LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, sockets, index) { const nodes::SocketDeclaration &socket_decl = *socket_decls[index]; if (!socket->is_visible()) { continue; } - if (socket_decl.is_default_link_socket()) { + if (socket_decl.is_default_link_socket) { return socket; } } diff --git a/source/blender/editors/space_node/node_templates.cc b/source/blender/editors/space_node/node_templates.cc index c16e09f4b2f..75a7f5f0dd7 100644 --- a/source/blender/editors/space_node/node_templates.cc +++ b/source/blender/editors/space_node/node_templates.cc @@ -362,8 +362,8 @@ static Vector ui_node_link_items(NodeLinkArg *arg, r_node_decl.emplace(NodeDeclaration()); blender::nodes::build_node_declaration(*arg->node_type, *r_node_decl); - Span socket_decls = (in_out == SOCK_IN) ? r_node_decl->inputs() : - r_node_decl->outputs(); + Span socket_decls = (in_out == SOCK_IN) ? r_node_decl->inputs : + r_node_decl->outputs; int index = 0; for (const SocketDeclarationPtr &socket_decl_ptr : socket_decls) { const SocketDeclaration &socket_decl = *socket_decl_ptr; @@ -408,7 +408,7 @@ static Vector ui_node_link_items(NodeLinkArg *arg, else { item.socket_type = SOCK_CUSTOM; } - item.socket_name = socket_decl.name().c_str(); + item.socket_name = socket_decl.name.c_str(); item.node_name = arg->node_type->ui_name; items.append(item); } diff --git a/source/blender/nodes/NOD_node_declaration.hh b/source/blender/nodes/NOD_node_declaration.hh index 975cc96131c..7753e8092d8 100644 --- a/source/blender/nodes/NOD_node_declaration.hh +++ b/source/blender/nodes/NOD_node_declaration.hh @@ -71,24 +71,24 @@ using ImplicitInputValueFn = std::functionhide_label_ = value; + decl_->hide_label = value; return *(Self *)this; } Self &hide_value(bool value = true) { - decl_->hide_value_ = value; + decl_->hide_value = value; return *(Self *)this; } Self &multi_input(bool value = true) { - decl_->is_multi_input_ = value; + decl_->is_multi_input = value; return *(Self *)this; } Self &description(std::string value = "") { - decl_->description_ = std::move(value); + decl_->description = std::move(value); return *(Self *)this; } Self &no_muted_links(bool value = true) { - decl_->no_mute_links_ = value; + decl_->no_mute_links = value; return *(Self *)this; } @@ -212,26 +202,26 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder { */ Self &unavailable(bool value = true) { - decl_->is_unavailable_ = value; + decl_->is_unavailable = value; return *(Self *)this; } Self &is_attribute_name(bool value = true) { - decl_->is_attribute_name_ = value; + decl_->is_attribute_name = value; return *(Self *)this; } Self &is_default_link_socket(bool value = true) { - decl_->is_default_link_socket_ = value; + decl_->is_default_link_socket = value; return *(Self *)this; } /** The input socket allows passing in a field. */ Self &supports_field() { - decl_->input_field_type_ = InputSocketFieldType::IsSupported; + decl_->input_field_type = InputSocketFieldType::IsSupported; return *(Self *)this; } @@ -239,7 +229,7 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder { Self &implicit_field(ImplicitInputValueFn fn) { this->hide_value(); - decl_->input_field_type_ = InputSocketFieldType::Implicit; + decl_->input_field_type = InputSocketFieldType::Implicit; decl_->implicit_input_fn_ = std::make_unique(std::move(fn)); return *(Self *)this; } @@ -247,21 +237,21 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder { /** The output is always a field, regardless of any inputs. */ Self &field_source() { - decl_->output_field_dependency_ = OutputFieldDependency::ForFieldSource(); + decl_->output_field_dependency = OutputFieldDependency::ForFieldSource(); return *(Self *)this; } /** The output is a field if any of the inputs is a field. */ Self &dependent_field() { - decl_->output_field_dependency_ = OutputFieldDependency::ForDependentField(); + decl_->output_field_dependency = OutputFieldDependency::ForDependentField(); return *(Self *)this; } /** The output is a field if any of the inputs with indices in the given list is a field. */ Self &dependent_field(Vector input_dependencies) { - decl_->output_field_dependency_ = OutputFieldDependency::ForPartiallyDependentField( + decl_->output_field_dependency = OutputFieldDependency::ForPartiallyDependentField( std::move(input_dependencies)); return *(Self *)this; } @@ -306,17 +296,13 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder { using SocketDeclarationPtr = std::unique_ptr; class NodeDeclaration { - private: - Vector inputs_; - Vector outputs_; + public: + Vector inputs; + Vector outputs; friend NodeDeclarationBuilder; - public: bool matches(const bNode &node) const; - - Span inputs() const; - Span outputs() const; Span sockets(eNodeSocketInOut in_out) const; MEM_CXX_CLASS_ALLOC_FUNCS("NodeDeclaration") @@ -443,46 +429,6 @@ inline bool operator!=(const FieldInferencingInterface &a, const FieldInferencin /** \name #SocketDeclaration Inline Methods * \{ */ -inline StringRefNull SocketDeclaration::name() const -{ - return name_; -} - -inline StringRefNull SocketDeclaration::identifier() const -{ - return identifier_; -} - -inline eNodeSocketInOut SocketDeclaration::in_out() const -{ - return in_out_; -} - -inline StringRefNull SocketDeclaration::description() const -{ - return description_; -} - -inline bool SocketDeclaration::is_attribute_name() const -{ - return is_attribute_name_; -} - -inline bool SocketDeclaration::is_default_link_socket() const -{ - return is_default_link_socket_; -} - -inline InputSocketFieldType SocketDeclaration::input_field_type() const -{ - return input_field_type_; -} - -inline const OutputFieldDependency &SocketDeclaration::output_field_dependency() const -{ - return output_field_dependency_; -} - inline int SocketDeclaration::compositor_domain_priority() const { return compositor_domain_priority_; @@ -538,15 +484,15 @@ inline typename DeclType::Builder &NodeDeclarationBuilder::add_socket(StringRef static_assert(std::is_base_of_v); using Builder = typename DeclType::Builder; - Vector &declarations = in_out == SOCK_IN ? declaration_.inputs_ : - declaration_.outputs_; + Vector &declarations = in_out == SOCK_IN ? declaration_.inputs : + declaration_.outputs; std::unique_ptr socket_decl = std::make_unique(); std::unique_ptr socket_decl_builder = std::make_unique(); socket_decl_builder->decl_ = &*socket_decl; - socket_decl->name_ = name; - socket_decl->identifier_ = identifier.is_empty() ? name : identifier; - socket_decl->in_out_ = in_out; + socket_decl->name = name; + socket_decl->identifier = identifier.is_empty() ? name : identifier; + socket_decl->in_out = in_out; declarations.append(std::move(socket_decl)); Builder &socket_decl_builder_ref = *socket_decl_builder; builders_.append(std::move(socket_decl_builder)); @@ -559,22 +505,12 @@ inline typename DeclType::Builder &NodeDeclarationBuilder::add_socket(StringRef /** \name #NodeDeclaration Inline Methods * \{ */ -inline Span NodeDeclaration::inputs() const -{ - return inputs_; -} - -inline Span NodeDeclaration::outputs() const -{ - return outputs_; -} - inline Span NodeDeclaration::sockets(eNodeSocketInOut in_out) const { if (in_out == SOCK_IN) { - return inputs_; + return inputs; } - return outputs_; + return outputs; } /** \} */ diff --git a/source/blender/nodes/NOD_socket_declarations.hh b/source/blender/nodes/NOD_socket_declarations.hh index f3a9ba25ca1..65ca350a479 100644 --- a/source/blender/nodes/NOD_socket_declarations.hh +++ b/source/blender/nodes/NOD_socket_declarations.hh @@ -306,7 +306,7 @@ inline VectorBuilder &VectorBuilder::max(const float max) inline VectorBuilder &VectorBuilder::compact() { - decl_->compact_ = true; + decl_->compact = true; return *this; } diff --git a/source/blender/nodes/function/nodes/node_fn_random_value.cc b/source/blender/nodes/function/nodes/node_fn_random_value.cc index e4633696ee4..b021ff07f04 100644 --- a/source/blender/nodes/function/nodes/node_fn_random_value.cc +++ b/source/blender/nodes/function/nodes/node_fn_random_value.cc @@ -123,7 +123,7 @@ static void node_gather_link_search_ops(GatherLinkSearchOpParams ¶ms) params.update_and_connect_available_socket(node, "Max"); }); } - search_link_ops_for_declarations(params, declaration.inputs().take_back(3)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(3)); } else { params.add_item(IFACE_("Value"), [type](LinkSearchOpParams ¶ms) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc index 1a0cb14f451..76709f0463d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc @@ -82,8 +82,8 @@ static void node_update(bNodeTree *ntree, bNode *node) static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - search_link_ops_for_declarations(params, declaration.inputs().take_front(1)); - search_link_ops_for_declarations(params, declaration.outputs().take_front(1)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1)); + search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(1)); const bNodeType &node_type = params.node_type(); const std::optional type = node_data_type_to_custom_data_type( diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc index e381133af30..090ff6aff30 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc @@ -119,7 +119,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const bNodeType &node_type = params.node_type(); const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - search_link_ops_for_declarations(params, declaration.inputs().take_front(2)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(2)); const std::optional type = node_type_from_other_socket(params.other_socket()); if (!type) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc index c2250019a30..ef6ec91922a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc @@ -77,7 +77,7 @@ static void node_init(bNodeTree * /*tree*/, bNode *node) static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - search_link_ops_for_declarations(params, declaration.inputs().take_back(2)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(2)); const bNodeType &node_type = params.node_type(); const std::optional type = node_data_type_to_custom_data_type( diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc index d4e37a98372..b1bc8379ff2 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_quadrilateral.cc @@ -136,7 +136,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; if (params.in_out() == SOCK_OUT) { - search_link_ops_for_declarations(params, declaration.outputs()); + search_link_ops_for_declarations(params, declaration.outputs); } else if (params.node_tree().typeinfo->validate_link( eNodeSocketDatatype(params.other_socket().type), SOCK_FLOAT)) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc index de9691cb56e..2798089197a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc @@ -113,8 +113,8 @@ static void node_update(bNodeTree *ntree, bNode *node) static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - search_link_ops_for_declarations(params, declaration.inputs().take_front(4)); - search_link_ops_for_declarations(params, declaration.outputs().take_front(3)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(4)); + search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(3)); const std::optional type = node_data_type_to_custom_data_type( eNodeSocketDatatype(params.other_socket().type)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc index b0c2f3117fa..6b8c0c6b967 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc @@ -92,8 +92,8 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - search_link_ops_for_declarations(params, declaration.outputs()); - search_link_ops_for_declarations(params, declaration.inputs().take_front(1)); + search_link_ops_for_declarations(params, declaration.outputs); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1)); if (params.in_out() == SOCK_IN) { if (params.node_tree().typeinfo->validate_link(eNodeSocketDatatype(params.other_socket().type), diff --git a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc index fc1e2cb2503..a6820444f73 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc @@ -132,7 +132,7 @@ static void node_update(bNodeTree *ntree, bNode *node) static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - search_link_ops_for_declarations(params, declaration.inputs().take_front(1)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1)); const bNodeType &node_type = params.node_type(); const std::optional type = node_data_type_to_custom_data_type( diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc index 5d4a90c09cd..c314d9499b0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_named_attribute.cc @@ -57,7 +57,7 @@ static void node_update(bNodeTree *ntree, bNode *node) static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - search_link_ops_for_declarations(params, declaration.inputs()); + search_link_ops_for_declarations(params, declaration.inputs); const bNodeType &node_type = params.node_type(); if (params.in_out() == SOCK_OUT) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc index e5063d172a0..0de0bb80826 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc @@ -93,7 +93,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; if (params.in_out() == SOCK_OUT) { - search_link_ops_for_declarations(params, declaration.outputs()); + search_link_ops_for_declarations(params, declaration.outputs); return; } else if (params.node_tree().typeinfo->validate_link( diff --git a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc index 61fa75cbdda..ed1cb707d86 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc @@ -100,9 +100,9 @@ static void node_update(bNodeTree *ntree, bNode *node) static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - search_link_ops_for_declarations(params, declaration.inputs().take_front(1)); - search_link_ops_for_declarations(params, declaration.inputs().take_back(3)); - search_link_ops_for_declarations(params, declaration.outputs().take_front(4)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(3)); + search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(4)); const std::optional type = node_data_type_to_custom_data_type( (eNodeSocketDatatype)params.other_socket().type); diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc index 832c40114d9..dfb0c17e4d5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc @@ -88,8 +88,8 @@ static void node_update(bNodeTree *ntree, bNode *node) static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - search_link_ops_for_declarations(params, declaration.inputs().take_back(1)); - search_link_ops_for_declarations(params, declaration.inputs().take_front(1)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(1)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1)); const std::optional type = node_data_type_to_custom_data_type( (eNodeSocketDatatype)params.other_socket().type); diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc index b588909a5ff..d0eeb702d40 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc @@ -81,8 +81,8 @@ static void node_update(bNodeTree *ntree, bNode *node) static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - search_link_ops_for_declarations(params, declaration.inputs().take_back(2)); - search_link_ops_for_declarations(params, declaration.inputs().take_front(1)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(2)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1)); const std::optional type = node_data_type_to_custom_data_type( (eNodeSocketDatatype)params.other_socket().type); diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc index 0e6e68036d9..2c8d39f7aef 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc @@ -89,9 +89,9 @@ static void node_update(bNodeTree *ntree, bNode *node) static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - search_link_ops_for_declarations(params, declaration.inputs().take_back(2)); - search_link_ops_for_declarations(params, declaration.inputs().take_front(1)); - search_link_ops_for_declarations(params, declaration.outputs().take_back(1)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(2)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1)); + search_link_ops_for_declarations(params, declaration.outputs.as_span().take_back(1)); const std::optional type = node_data_type_to_custom_data_type( eNodeSocketDatatype(params.other_socket().type)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc index 4970a926445..b15c156a19b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc @@ -70,8 +70,8 @@ static void node_update(bNodeTree *ntree, bNode *node) static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - search_link_ops_for_declarations(params, declaration.inputs().take_front(2)); - search_link_ops_for_declarations(params, declaration.outputs().take_front(1)); + search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(2)); + search_link_ops_for_declarations(params, declaration.outputs.as_span().take_front(1)); if (params.in_out() == SOCK_IN) { const std::optional type = node_data_type_to_custom_data_type( diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index a8eb532ab3f..c18c90fed82 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -1252,7 +1252,7 @@ struct GeometryNodesLazyFunctionGraphBuilder { if (socket_decl == nullptr) { return false; } - if (socket_decl->input_field_type() != InputSocketFieldType::Implicit) { + if (socket_decl->input_field_type != InputSocketFieldType::Implicit) { return false; } const ImplicitInputValueFn *implicit_input_fn = socket_decl->implicit_input_fn(); diff --git a/source/blender/nodes/intern/node_declaration.cc b/source/blender/nodes/intern/node_declaration.cc index 0811bfeb516..449d8d05a04 100644 --- a/source/blender/nodes/intern/node_declaration.cc +++ b/source/blender/nodes/intern/node_declaration.cc @@ -17,13 +17,13 @@ void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declar void NodeDeclarationBuilder::finalize() { if (is_function_node_) { - for (SocketDeclarationPtr &socket_decl : declaration_.inputs_) { - if (socket_decl->input_field_type_ != InputSocketFieldType::Implicit) { - socket_decl->input_field_type_ = InputSocketFieldType::IsSupported; + for (SocketDeclarationPtr &socket_decl : declaration_.inputs) { + if (socket_decl->input_field_type != InputSocketFieldType::Implicit) { + socket_decl->input_field_type = InputSocketFieldType::IsSupported; } } - for (SocketDeclarationPtr &socket_decl : declaration_.outputs_) { - socket_decl->output_field_dependency_ = OutputFieldDependency::ForDependentField(); + for (SocketDeclarationPtr &socket_decl : declaration_.outputs) { + socket_decl->output_field_dependency = OutputFieldDependency::ForDependentField(); } } } @@ -45,10 +45,10 @@ bool NodeDeclaration::matches(const bNode &node) const return true; }; - if (!check_sockets(node.inputs, inputs_)) { + if (!check_sockets(node.inputs, inputs)) { return false; } - if (!check_sockets(node.outputs, outputs_)) { + if (!check_sockets(node.outputs, outputs)) { return false; } return true; @@ -66,38 +66,38 @@ bNodeSocket &SocketDeclaration::update_or_build(bNodeTree &ntree, void SocketDeclaration::set_common_flags(bNodeSocket &socket) const { - SET_FLAG_FROM_TEST(socket.flag, compact_, SOCK_COMPACT); - SET_FLAG_FROM_TEST(socket.flag, hide_value_, SOCK_HIDE_VALUE); - SET_FLAG_FROM_TEST(socket.flag, hide_label_, SOCK_HIDE_LABEL); - SET_FLAG_FROM_TEST(socket.flag, is_multi_input_, SOCK_MULTI_INPUT); - SET_FLAG_FROM_TEST(socket.flag, no_mute_links_, SOCK_NO_INTERNAL_LINK); - SET_FLAG_FROM_TEST(socket.flag, is_unavailable_, SOCK_UNAVAIL); + SET_FLAG_FROM_TEST(socket.flag, compact, SOCK_COMPACT); + SET_FLAG_FROM_TEST(socket.flag, hide_value, SOCK_HIDE_VALUE); + SET_FLAG_FROM_TEST(socket.flag, hide_label, SOCK_HIDE_LABEL); + SET_FLAG_FROM_TEST(socket.flag, is_multi_input, SOCK_MULTI_INPUT); + SET_FLAG_FROM_TEST(socket.flag, no_mute_links, SOCK_NO_INTERNAL_LINK); + SET_FLAG_FROM_TEST(socket.flag, is_unavailable, SOCK_UNAVAIL); } bool SocketDeclaration::matches_common_data(const bNodeSocket &socket) const { - if (socket.name != name_) { + if (socket.name != this->name) { return false; } - if (socket.identifier != identifier_) { + if (socket.identifier != this->identifier) { return false; } - if (((socket.flag & SOCK_COMPACT) != 0) != compact_) { + if (((socket.flag & SOCK_COMPACT) != 0) != this->compact) { return false; } - if (((socket.flag & SOCK_HIDE_VALUE) != 0) != hide_value_) { + if (((socket.flag & SOCK_HIDE_VALUE) != 0) != this->hide_value) { return false; } - if (((socket.flag & SOCK_HIDE_LABEL) != 0) != hide_label_) { + if (((socket.flag & SOCK_HIDE_LABEL) != 0) != this->hide_label) { return false; } - if (((socket.flag & SOCK_MULTI_INPUT) != 0) != is_multi_input_) { + if (((socket.flag & SOCK_MULTI_INPUT) != 0) != this->is_multi_input) { return false; } - if (((socket.flag & SOCK_NO_INTERNAL_LINK) != 0) != no_mute_links_) { + if (((socket.flag & SOCK_NO_INTERNAL_LINK) != 0) != this->no_mute_links) { return false; } - if (((socket.flag & SOCK_UNAVAIL) != 0) != is_unavailable_) { + if (((socket.flag & SOCK_UNAVAIL) != 0) != this->is_unavailable) { return false; } return true; diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index 8f2c36152c5..c608bfc383f 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -184,7 +184,7 @@ static void refresh_socket_list(bNodeTree &ntree, bNodeSocket *old_socket_with_same_identifier = nullptr; for (const int i : old_sockets.index_range()) { bNodeSocket &old_socket = *old_sockets[i]; - if (old_socket.identifier == socket_decl->identifier()) { + if (old_socket.identifier == socket_decl->identifier) { old_sockets.remove_and_reorder(i); old_socket_with_same_identifier = &old_socket; break; @@ -196,7 +196,7 @@ static void refresh_socket_list(bNodeTree &ntree, new_socket = &socket_decl->build(ntree, node); } else { - STRNCPY(old_socket_with_same_identifier->name, socket_decl->name().c_str()); + STRNCPY(old_socket_with_same_identifier->name, socket_decl->name.c_str()); if (socket_decl->matches(*old_socket_with_same_identifier)) { /* The existing socket matches exactly, just use it. */ new_socket = old_socket_with_same_identifier; @@ -208,7 +208,7 @@ static void refresh_socket_list(bNodeTree &ntree, if (new_socket == old_socket_with_same_identifier) { /* The existing socket has been updated, set the correct identifier again. */ - STRNCPY(new_socket->identifier, socket_decl->identifier().c_str()); + STRNCPY(new_socket->identifier, socket_decl->identifier.c_str()); } else { /* Move links to new socket with same identifier. */ @@ -249,8 +249,8 @@ static void refresh_node(bNodeTree &ntree, blender::nodes::NodeDeclaration &node_decl, bool do_id_user) { - refresh_socket_list(ntree, node, node.inputs, node_decl.inputs(), do_id_user); - refresh_socket_list(ntree, node, node.outputs, node_decl.outputs(), do_id_user); + refresh_socket_list(ntree, node, node.inputs, node_decl.inputs, do_id_user); + refresh_socket_list(ntree, node, node.outputs, node_decl.outputs, do_id_user); } void node_verify_sockets(bNodeTree *ntree, bNode *node, bool do_id_user) diff --git a/source/blender/nodes/intern/node_socket_declarations.cc b/source/blender/nodes/intern/node_socket_declarations.cc index 44f02822ee1..5d722ea28da 100644 --- a/source/blender/nodes/intern/node_socket_declarations.cc +++ b/source/blender/nodes/intern/node_socket_declarations.cc @@ -18,8 +18,8 @@ namespace blender::nodes::decl { static bool field_types_are_compatible(const SocketDeclaration &input, const SocketDeclaration &output) { - if (output.output_field_dependency().field_type() == OutputSocketFieldType::FieldSource) { - if (input.input_field_type() == InputSocketFieldType::None) { + if (output.output_field_dependency.field_type() == OutputSocketFieldType::FieldSource) { + if (input.input_field_type == InputSocketFieldType::None) { return false; } } @@ -30,12 +30,12 @@ static bool sockets_can_connect(const SocketDeclaration &socket_decl, const bNodeSocket &other_socket) { /* Input sockets cannot connect to input sockets, outputs cannot connect to outputs. */ - if (socket_decl.in_out() == other_socket.in_out) { + if (socket_decl.in_out == other_socket.in_out) { return false; } if (other_socket.runtime->declaration) { - if (socket_decl.in_out() == SOCK_IN) { + if (socket_decl.in_out == SOCK_IN) { if (!field_types_are_compatible(socket_decl, *other_socket.runtime->declaration)) { return false; } @@ -70,8 +70,13 @@ static void modify_subtype_except_for_storage(bNodeSocket &socket, int new_subty bNodeSocket &Float::build(bNodeTree &ntree, bNode &node) const { - bNodeSocket &socket = *nodeAddStaticSocket( - &ntree, &node, in_out_, SOCK_FLOAT, this->subtype, identifier_.c_str(), name_.c_str()); + bNodeSocket &socket = *nodeAddStaticSocket(&ntree, + &node, + this->in_out, + SOCK_FLOAT, + this->subtype, + this->identifier.c_str(), + this->name.c_str()); this->set_common_flags(socket); bNodeSocketValueFloat &value = *(bNodeSocketValueFloat *)socket.default_value; value.min = this->soft_min_value; @@ -112,7 +117,7 @@ bool Float::can_connect(const bNodeSocket &socket) const bNodeSocket &Float::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const { if (socket.type != SOCK_FLOAT) { - BLI_assert(socket.in_out == in_out_); + BLI_assert(socket.in_out == this->in_out); return this->build(ntree, node); } if (socket.typeinfo->subtype != this->subtype) { @@ -134,8 +139,13 @@ bNodeSocket &Float::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket & bNodeSocket &Int::build(bNodeTree &ntree, bNode &node) const { - bNodeSocket &socket = *nodeAddStaticSocket( - &ntree, &node, in_out_, SOCK_INT, this->subtype, identifier_.c_str(), name_.c_str()); + bNodeSocket &socket = *nodeAddStaticSocket(&ntree, + &node, + this->in_out, + SOCK_INT, + this->subtype, + this->identifier.c_str(), + this->name.c_str()); this->set_common_flags(socket); bNodeSocketValueInt &value = *(bNodeSocketValueInt *)socket.default_value; value.min = this->soft_min_value; @@ -176,7 +186,7 @@ bool Int::can_connect(const bNodeSocket &socket) const bNodeSocket &Int::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const { if (socket.type != SOCK_INT) { - BLI_assert(socket.in_out == in_out_); + BLI_assert(socket.in_out == this->in_out); return this->build(ntree, node); } if (socket.typeinfo->subtype != this->subtype) { @@ -198,8 +208,13 @@ bNodeSocket &Int::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &so bNodeSocket &Vector::build(bNodeTree &ntree, bNode &node) const { - bNodeSocket &socket = *nodeAddStaticSocket( - &ntree, &node, in_out_, SOCK_VECTOR, this->subtype, identifier_.c_str(), name_.c_str()); + bNodeSocket &socket = *nodeAddStaticSocket(&ntree, + &node, + this->in_out, + SOCK_VECTOR, + this->subtype, + this->identifier.c_str(), + this->name.c_str()); this->set_common_flags(socket); bNodeSocketValueVector &value = *(bNodeSocketValueVector *)socket.default_value; copy_v3_v3(value.value, this->default_value); @@ -233,7 +248,7 @@ bool Vector::can_connect(const bNodeSocket &socket) const bNodeSocket &Vector::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const { if (socket.type != SOCK_VECTOR) { - BLI_assert(socket.in_out == in_out_); + BLI_assert(socket.in_out == this->in_out); return this->build(ntree, node); } if (socket.typeinfo->subtype != this->subtype) { @@ -242,7 +257,7 @@ bNodeSocket &Vector::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket this->set_common_flags(socket); bNodeSocketValueVector &value = *(bNodeSocketValueVector *)socket.default_value; value.subtype = this->subtype; - STRNCPY(socket.name, name_.c_str()); + STRNCPY(socket.name, this->name.c_str()); return socket; } @@ -254,8 +269,13 @@ bNodeSocket &Vector::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket bNodeSocket &Bool::build(bNodeTree &ntree, bNode &node) const { - bNodeSocket &socket = *nodeAddStaticSocket( - &ntree, &node, in_out_, SOCK_BOOLEAN, PROP_NONE, identifier_.c_str(), name_.c_str()); + bNodeSocket &socket = *nodeAddStaticSocket(&ntree, + &node, + this->in_out, + SOCK_BOOLEAN, + PROP_NONE, + this->identifier.c_str(), + this->name.c_str()); this->set_common_flags(socket); bNodeSocketValueBoolean &value = *(bNodeSocketValueBoolean *)socket.default_value; value.value = this->default_value; @@ -289,8 +309,13 @@ bool Bool::can_connect(const bNodeSocket &socket) const bNodeSocket &Color::build(bNodeTree &ntree, bNode &node) const { - bNodeSocket &socket = *nodeAddStaticSocket( - &ntree, &node, in_out_, SOCK_RGBA, PROP_NONE, identifier_.c_str(), name_.c_str()); + bNodeSocket &socket = *nodeAddStaticSocket(&ntree, + &node, + this->in_out, + SOCK_RGBA, + PROP_NONE, + this->identifier.c_str(), + this->name.c_str()); this->set_common_flags(socket); bNodeSocketValueRGBA &value = *(bNodeSocketValueRGBA *)socket.default_value; copy_v4_v4(value.value, this->default_value); @@ -300,10 +325,10 @@ bNodeSocket &Color::build(bNodeTree &ntree, bNode &node) const bool Color::matches(const bNodeSocket &socket) const { if (!this->matches_common_data(socket)) { - if (socket.name != name_) { + if (socket.name != this->name) { return false; } - if (socket.identifier != identifier_) { + if (socket.identifier != this->identifier) { return false; } } @@ -329,8 +354,13 @@ bool Color::can_connect(const bNodeSocket &socket) const bNodeSocket &String::build(bNodeTree &ntree, bNode &node) const { - bNodeSocket &socket = *nodeAddStaticSocket( - &ntree, &node, in_out_, SOCK_STRING, PROP_NONE, identifier_.c_str(), name_.c_str()); + bNodeSocket &socket = *nodeAddStaticSocket(&ntree, + &node, + this->in_out, + SOCK_STRING, + PROP_NONE, + this->identifier.c_str(), + this->name.c_str()); STRNCPY(((bNodeSocketValueString *)socket.default_value)->value, this->default_value.c_str()); this->set_common_flags(socket); return socket; @@ -361,7 +391,7 @@ bool String::can_connect(const bNodeSocket &socket) const bNodeSocket &IDSocketDeclaration::build(bNodeTree &ntree, bNode &node) const { bNodeSocket &socket = *nodeAddSocket( - &ntree, &node, in_out_, this->idname, identifier_.c_str(), name_.c_str()); + &ntree, &node, this->in_out, this->idname, this->identifier.c_str(), this->name.c_str()); this->set_common_flags(socket); return socket; } @@ -387,7 +417,7 @@ bNodeSocket &IDSocketDeclaration::update_or_build(bNodeTree &ntree, bNodeSocket &socket) const { if (StringRef(socket.idname) != this->idname) { - BLI_assert(socket.in_out == in_out_); + BLI_assert(socket.in_out == this->in_out); return this->build(ntree, node); } this->set_common_flags(socket); @@ -402,8 +432,12 @@ bNodeSocket &IDSocketDeclaration::update_or_build(bNodeTree &ntree, bNodeSocket &Geometry::build(bNodeTree &ntree, bNode &node) const { - bNodeSocket &socket = *nodeAddSocket( - &ntree, &node, in_out_, "NodeSocketGeometry", identifier_.c_str(), name_.c_str()); + bNodeSocket &socket = *nodeAddSocket(&ntree, + &node, + this->in_out, + "NodeSocketGeometry", + this->identifier.c_str(), + this->name.c_str()); this->set_common_flags(socket); return socket; } @@ -472,8 +506,12 @@ GeometryBuilder &GeometryBuilder::only_instances(bool value) bNodeSocket &Shader::build(bNodeTree &ntree, bNode &node) const { - bNodeSocket &socket = *nodeAddSocket( - &ntree, &node, in_out_, "NodeSocketShader", identifier_.c_str(), name_.c_str()); + bNodeSocket &socket = *nodeAddSocket(&ntree, + &node, + this->in_out, + "NodeSocketShader", + this->identifier.c_str(), + this->name.c_str()); this->set_common_flags(socket); return socket; } @@ -495,7 +533,7 @@ bool Shader::can_connect(const bNodeSocket &socket) const return false; } /* Basic types can convert to shaders, but not the other way around. */ - if (in_out_ == SOCK_IN) { + if (this->in_out == SOCK_IN) { return ELEM( socket.type, SOCK_VECTOR, SOCK_RGBA, SOCK_FLOAT, SOCK_INT, SOCK_BOOLEAN, SOCK_SHADER); } diff --git a/source/blender/nodes/intern/socket_search_link.cc b/source/blender/nodes/intern/socket_search_link.cc index b440952b503..907dd987400 100644 --- a/source/blender/nodes/intern/socket_search_link.cc +++ b/source/blender/nodes/intern/socket_search_link.cc @@ -91,7 +91,7 @@ void search_link_ops_for_declarations(GatherLinkSearchOpParams ¶ms, Set socket_names; for (const int i : declarations.index_range()) { const SocketDeclaration &socket = *declarations[i]; - if (!socket_names.add(socket.name())) { + if (!socket_names.add(socket.name)) { /* Don't add sockets with the same name to the search. Needed to support being called from * #search_link_ops_for_basic_node, which should have "okay" behavior for nodes with * duplicate socket names. */ @@ -100,7 +100,7 @@ void search_link_ops_for_declarations(GatherLinkSearchOpParams ¶ms, if (!socket.can_connect(params.other_socket())) { continue; } - if (socket.is_default_link_socket() || main_socket == nullptr) { + if (socket.is_default_link_socket || main_socket == nullptr) { /* Either the first connectable or explicitly tagged socket is the main socket. */ main_socket = &socket; } @@ -115,11 +115,11 @@ void search_link_ops_for_declarations(GatherLinkSearchOpParams ¶ms, * sockets. */ const int weight = (&socket == main_socket) ? 0 : -1 - i; params.add_item( - IFACE_(socket.name().c_str()), + IFACE_(socket.name.c_str()), [&node_type, &socket](LinkSearchOpParams ¶ms) { bNode &node = params.add_node(node_type); socket.make_available(node); - params.update_and_connect_available_socket(node, socket.name()); + params.update_and_connect_available_socket(node, socket.name); }, weight); } diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc b/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc index faa0c0f0888..5e10ae864ad 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_sky.cc @@ -281,7 +281,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { const NodeDeclaration &declaration = *params.node_type().fixed_declaration; if (params.in_out() == SOCK_OUT) { - search_link_ops_for_declarations(params, declaration.outputs()); + search_link_ops_for_declarations(params, declaration.outputs); return; } if (params.node_tree().typeinfo->validate_link( From dba2d828462ae22de53f20f734bda6eb4d65171e Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 29 Dec 2022 21:05:41 +0100 Subject: [PATCH 0320/1522] Geometry Nodes: avoid using enumerable thread specific on single thread The geometry nodes evaluator supports "lazy threading", i.e. it starts out single-threaded. But when it determines that multi-threading can be benefitial, it switches to multi-threaded mode. Now it only creates an enumerable-thread-specific if it is actually using multiple threads. This results in a 6% speedup in my test file with many node groups and math nodes. --- .../intern/lazy_function_graph_executor.cc | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/source/blender/functions/intern/lazy_function_graph_executor.cc b/source/blender/functions/intern/lazy_function_graph_executor.cc index 21040bd4550..83b14952829 100644 --- a/source/blender/functions/intern/lazy_function_graph_executor.cc +++ b/source/blender/functions/intern/lazy_function_graph_executor.cc @@ -245,8 +245,11 @@ class Executor { * A separate linear allocator for every thread. We could potentially reuse some memory, but that * doesn't seem worth it yet. */ - threading::EnumerableThreadSpecific> local_allocators_; - LinearAllocator<> *main_local_allocator_ = nullptr; + struct ThreadLocalData { + LinearAllocator<> allocator; + }; + std::unique_ptr> thread_locals_; + LinearAllocator<> main_allocator_; /** * Set to false when the first execution ends. */ @@ -259,7 +262,6 @@ class Executor { { /* The indices are necessary, because they are used as keys in #node_states_. */ BLI_assert(self_.graph_.node_indices_are_valid()); - main_local_allocator_ = &local_allocators_.local(); } ~Executor() @@ -338,16 +340,25 @@ class Executor { Span nodes = self_.graph_.nodes(); node_states_.reinitialize(nodes.size()); - /* Construct all node states in parallel. */ - threading::parallel_for(nodes.index_range(), 256, [&](const IndexRange range) { - LinearAllocator<> &allocator = local_allocators_.local(); + auto construct_node_range = [&](const IndexRange range, LinearAllocator<> &allocator) { for (const int i : range) { const Node &node = *nodes[i]; NodeState &node_state = *allocator.construct().release(); node_states_[i] = &node_state; this->construct_initial_node_state(allocator, node, node_state); } - }); + }; + if (nodes.size() <= 256) { + construct_node_range(nodes.index_range(), main_allocator_); + } + else { + this->ensure_thread_locals(); + /* Construct all node states in parallel. */ + threading::parallel_for(nodes.index_range(), 256, [&](const IndexRange range) { + LinearAllocator<> &allocator = this->get_main_or_local_allocator(); + construct_node_range(range, allocator); + }); + } } void construct_initial_node_state(LinearAllocator<> &allocator, @@ -1067,10 +1078,23 @@ class Executor { if (BLI_system_thread_count() <= 1) { return false; } + this->ensure_thread_locals(); task_pool_.store(BLI_task_pool_create(this, TASK_PRIORITY_HIGH)); return true; } + void ensure_thread_locals() + { +#ifdef FN_LAZY_FUNCTION_DEBUG_THREADS + if (current_main_thread_ != std::this_thread::get_id()) { + BLI_assert_unreachable(); + } +#endif + if (!thread_locals_) { + thread_locals_ = std::make_unique>(); + } + } + /** * Allow other threads to steal all the nodes that are currently scheduled on this thread. */ @@ -1109,9 +1133,9 @@ class Executor { LinearAllocator<> &get_main_or_local_allocator() { if (this->use_multi_threading()) { - return local_allocators_.local(); + return thread_locals_->local().allocator; } - return *main_local_allocator_; + return main_allocator_; } }; From 83b103fd2f789f1c52a7e9ab7b19368dd784f1e5 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 29 Dec 2022 21:13:52 +0100 Subject: [PATCH 0321/1522] Geometry Nodes: use static instead of dynamic cast In my (fairly extreme) test file this results in a 6% speedup. The assumption that the dynamic cast would succeed was in place before already. --- source/blender/nodes/intern/geometry_nodes_lazy_function.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index c18c90fed82..454fe4da23b 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -1324,8 +1324,9 @@ void GeometryNodesLazyFunctionLogger::log_socket_value( const GPointer value, const fn::lazy_function::Context &context) const { - GeoNodesLFUserData *user_data = dynamic_cast(context.user_data); - BLI_assert(user_data != nullptr); + /* In this context we expect only a single kind of user data, so use `static_cast`. */ + GeoNodesLFUserData *user_data = static_cast(context.user_data); + BLI_assert(dynamic_cast(context.user_data) != nullptr); if (!user_data->log_socket_values) { return; } From 81935098f185e9c7139f4fb74e56968c3054c7bb Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 29 Dec 2022 15:36:33 -0500 Subject: [PATCH 0322/1522] Fix: Debug build failure after recent variable name change --- source/blender/nodes/intern/node_declaration.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/intern/node_declaration.cc b/source/blender/nodes/intern/node_declaration.cc index 449d8d05a04..f9921db3230 100644 --- a/source/blender/nodes/intern/node_declaration.cc +++ b/source/blender/nodes/intern/node_declaration.cc @@ -59,7 +59,7 @@ bNodeSocket &SocketDeclaration::update_or_build(bNodeTree &ntree, bNodeSocket &socket) const { /* By default just rebuild. */ - BLI_assert(socket.in_out == in_out_); + BLI_assert(socket.in_out == this->in_out); UNUSED_VARS_NDEBUG(socket); return this->build(ntree, node); } From c8741a3c0336e9d92d1140a6b7a0815ca572c7aa Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 29 Dec 2022 16:40:29 -0500 Subject: [PATCH 0323/1522] Cleanup: Simplify node clipboard, use Vector instead of ListBase - Move from blenkernel to the node editor, the only place it was used - Use two vectors instead of ListBase - Remove define for validating the clipboard, which shouldn't be skipped - Comment formatting, other small cleanups to whitespace Differential Revision: https://developer.blender.org/D16880 --- source/blender/blenkernel/BKE_node.h | 16 +- source/blender/blenkernel/intern/node.cc | 156 +-------- source/blender/editors/include/ED_node.h | 4 + .../blender/editors/space_node/CMakeLists.txt | 1 + .../blender/editors/space_node/clipboard.cc | 301 ++++++++++++++++++ .../blender/editors/space_node/node_edit.cc | 210 ------------ .../windowmanager/intern/wm_init_exit.c | 2 +- 7 files changed, 317 insertions(+), 373 deletions(-) create mode 100644 source/blender/editors/space_node/clipboard.cc diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 266ee0d2988..acf52a5b965 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -713,6 +713,8 @@ bNode *node_copy_with_mapping(bNodeTree *dst_tree, bNode *node_copy(bNodeTree *dst_tree, const bNode &src_node, int flag, bool use_unique); +void node_free_node(bNodeTree *tree, bNode *node); + } // namespace blender::bke #endif @@ -865,20 +867,6 @@ bool nodeDeclarationEnsureOnOutdatedNode(struct bNodeTree *ntree, struct bNode * */ void nodeSocketDeclarationsUpdate(struct bNode *node); -/** - * Node Clipboard. - */ -void BKE_node_clipboard_clear(void); -void BKE_node_clipboard_free(void); -/** - * Return false when one or more ID's are lost. - */ -bool BKE_node_clipboard_validate(void); -void BKE_node_clipboard_add_node(struct bNode *node); -void BKE_node_clipboard_add_link(struct bNodeLink *link); -const struct ListBase *BKE_node_clipboard_get_nodes(void); -const struct ListBase *BKE_node_clipboard_get_links(void); - /** * Node Instance Hash. */ diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index eb744f1fd66..3cd0cf2f7ca 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -118,7 +118,6 @@ static CLG_LogRef LOG = {"bke.node"}; static void ntree_set_typeinfo(bNodeTree *ntree, bNodeTreeType *typeinfo); static void node_socket_copy(bNodeSocket *sock_dst, const bNodeSocket *sock_src, const int flag); static void free_localized_node_groups(bNodeTree *ntree); -static void node_free_node(bNodeTree *ntree, bNode *node); static void node_socket_interface_free(bNodeTree * /*ntree*/, bNodeSocket *sock, const bool do_id_user); @@ -243,7 +242,7 @@ static void ntree_free_data(ID *id) BLI_freelistN(&ntree->links); LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) { - node_free_node(ntree, node); + blender::bke::node_free_node(ntree, node); } /* free interface sockets */ @@ -2951,12 +2950,14 @@ void nodeRebuildIDVector(bNodeTree *node_tree) } } +namespace blender::bke { + /** * Free the node itself. * * \note: ID user refcounting and changing the `nodes_by_id` vector are up to the caller. */ -static void node_free_node(bNodeTree *ntree, bNode *node) +void node_free_node(bNodeTree *ntree, bNode *node) { /* since it is called while free database, node->id is undefined */ @@ -3011,6 +3012,8 @@ static void node_free_node(bNodeTree *ntree, bNode *node) } } +} // namespace blender::bke + void ntreeFreeLocalNode(bNodeTree *ntree, bNode *node) { /* For removing nodes while editing localized node trees. */ @@ -3021,7 +3024,7 @@ void ntreeFreeLocalNode(bNodeTree *ntree, bNode *node) nodeUnlinkNode(ntree, node); node_unlink_attached(ntree, node); - node_free_node(ntree, node); + blender::bke::node_free_node(ntree, node); nodeRebuildIDVector(ntree); } @@ -3081,7 +3084,7 @@ void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user) node_unlink_attached(ntree, node); /* Free node itself. */ - node_free_node(ntree, node); + blender::bke::node_free_node(ntree, node); nodeRebuildIDVector(ntree); } @@ -3649,149 +3652,6 @@ void nodeInternalLinks(bNode *node, bNodeLink ***r_links, int *r_len) *r_len = node->runtime->internal_links.size(); } -/* ************** Node Clipboard *********** */ - -#define USE_NODE_CB_VALIDATE - -#ifdef USE_NODE_CB_VALIDATE -/** - * This data structure is to validate the node on creation, - * otherwise we may reference missing data. - * - * Currently its only used for ID's, but nodes may one day - * reference other pointers which need validation. - */ -struct bNodeClipboardExtraInfo { - struct bNodeClipboardExtraInfo *next, *prev; - ID *id; - char id_name[MAX_ID_NAME]; - char library_name[FILE_MAX]; -}; -#endif /* USE_NODE_CB_VALIDATE */ - -struct bNodeClipboard { - ListBase nodes; - -#ifdef USE_NODE_CB_VALIDATE - ListBase nodes_extra_info; -#endif - - ListBase links; -}; - -static bNodeClipboard node_clipboard = {{nullptr}}; - -void BKE_node_clipboard_clear() -{ - LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &node_clipboard.links) { - nodeRemLink(nullptr, link); - } - BLI_listbase_clear(&node_clipboard.links); - - LISTBASE_FOREACH_MUTABLE (bNode *, node, &node_clipboard.nodes) { - node_free_node(nullptr, node); - } - BLI_listbase_clear(&node_clipboard.nodes); - -#ifdef USE_NODE_CB_VALIDATE - BLI_freelistN(&node_clipboard.nodes_extra_info); -#endif -} - -bool BKE_node_clipboard_validate() -{ - bool ok = true; - -#ifdef USE_NODE_CB_VALIDATE - bNodeClipboardExtraInfo *node_info; - bNode *node; - - /* lists must be aligned */ - BLI_assert(BLI_listbase_count(&node_clipboard.nodes) == - BLI_listbase_count(&node_clipboard.nodes_extra_info)); - - for (node = (bNode *)node_clipboard.nodes.first, - node_info = (bNodeClipboardExtraInfo *)node_clipboard.nodes_extra_info.first; - node; - node = (bNode *)node->next, node_info = (bNodeClipboardExtraInfo *)node_info->next) { - /* validate the node against the stored node info */ - - /* re-assign each loop since we may clear, - * open a new file where the ID is valid, and paste again */ - node->id = node_info->id; - - /* currently only validate the ID */ - if (node->id) { - /* We want to search into current blend file, so using G_MAIN is valid here too. */ - ListBase *lb = which_libbase(G_MAIN, GS(node_info->id_name)); - BLI_assert(lb != nullptr); - - if (BLI_findindex(lb, node_info->id) == -1) { - /* May assign null. */ - node->id = (ID *)BLI_findstring(lb, node_info->id_name + 2, offsetof(ID, name) + 2); - - if (node->id == nullptr) { - ok = false; - } - } - } - } -#endif /* USE_NODE_CB_VALIDATE */ - - return ok; -} - -void BKE_node_clipboard_add_node(bNode *node) -{ -#ifdef USE_NODE_CB_VALIDATE - /* add extra info */ - bNodeClipboardExtraInfo *node_info = (bNodeClipboardExtraInfo *)MEM_mallocN( - sizeof(bNodeClipboardExtraInfo), __func__); - - node_info->id = node->id; - if (node->id) { - BLI_strncpy(node_info->id_name, node->id->name, sizeof(node_info->id_name)); - if (ID_IS_LINKED(node->id)) { - BLI_strncpy( - node_info->library_name, node->id->lib->filepath_abs, sizeof(node_info->library_name)); - } - else { - node_info->library_name[0] = '\0'; - } - } - else { - node_info->id_name[0] = '\0'; - node_info->library_name[0] = '\0'; - } - BLI_addtail(&node_clipboard.nodes_extra_info, node_info); - /* end extra info */ -#endif /* USE_NODE_CB_VALIDATE */ - - /* add node */ - BLI_addtail(&node_clipboard.nodes, node); -} - -void BKE_node_clipboard_add_link(bNodeLink *link) -{ - BLI_addtail(&node_clipboard.links, link); -} - -const ListBase *BKE_node_clipboard_get_nodes() -{ - return &node_clipboard.nodes; -} - -const ListBase *BKE_node_clipboard_get_links() -{ - return &node_clipboard.links; -} - -void BKE_node_clipboard_free() -{ - BKE_node_clipboard_validate(); - BKE_node_clipboard_clear(); -} - /* Node Instance Hash */ const bNodeInstanceKey NODE_INSTANCE_KEY_BASE = {5381}; diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index 3ce972943b5..dc35ac74524 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -42,6 +42,10 @@ ENUM_OPERATORS(NodeBorder, NODE_RIGHT) #define NODE_EDGE_PAN_DELAY 0.5f #define NODE_EDGE_PAN_ZOOM_INFLUENCE 0.5f +/* clipboard.cc */ + +void ED_node_clipboard_free(void); + /* space_node.cc */ void ED_node_cursor_location_get(const struct SpaceNode *snode, float value[2]); diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index 3236082c0d2..4e2c4f8b8af 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -31,6 +31,7 @@ set(INC set(SRC add_menu_assets.cc add_node_search.cc + clipboard.cc drawnode.cc link_drag_search.cc node_add.cc diff --git a/source/blender/editors/space_node/clipboard.cc b/source/blender/editors/space_node/clipboard.cc new file mode 100644 index 00000000000..fa82f80d1a9 --- /dev/null +++ b/source/blender/editors/space_node/clipboard.cc @@ -0,0 +1,301 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "DNA_space_types.h" + +#include "BKE_context.h" +#include "BKE_global.h" +#include "BKE_lib_id.h" +#include "BKE_main.h" +#include "BKE_node.h" +#include "BKE_node_runtime.hh" +#include "BKE_node_tree_update.h" +#include "BKE_report.h" + +#include "ED_node.h" +#include "ED_node.hh" +#include "ED_render.h" +#include "ED_screen.h" + +#include "DEG_depsgraph_build.h" + +#include "node_intern.hh" + +namespace blender::ed::space_node { + +struct NodeClipboardItem { + bNode *node; + + /* Extra info to validate the node on creation. Otherwise we may reference missing data. */ + ID *id; + std::string id_name; + std::string library_name; +}; + +struct NodeClipboard { + Vector nodes; + Vector links; + + void clear() + { + for (NodeClipboardItem &item : this->nodes) { + bke::node_free_node(nullptr, item.node); + } + this->nodes.clear_and_shrink(); + this->links.clear_and_shrink(); + } + + /** + * Replace node IDs that are no longer available in the current file. Return false when one or + * more IDs are lost. + */ + bool validate() + { + bool ok = true; + + for (NodeClipboardItem &item : this->nodes) { + bNode &node = *item.node; + /* Reassign each loop since we may clear, open a new file where the ID is valid, and paste + * again. */ + node.id = item.id; + + if (node.id) { + const ListBase *lb = which_libbase(G_MAIN, GS(item.id_name.c_str())); + if (BLI_findindex(lb, item.id) == -1) { + /* May assign null. */ + node.id = static_cast( + BLI_findstring(lb, item.id_name.c_str() + 2, offsetof(ID, name) + 2)); + if (!node.id) { + ok = false; + } + } + } + } + + return ok; + } + + void add_node(bNode *node) + { + NodeClipboardItem item; + item.node = node; + item.id = node->id; + if (item.id) { + item.id_name = node->id->name; + if (ID_IS_LINKED(node->id)) { + item.library_name = node->id->lib->filepath_abs; + } + } + this->nodes.append(std::move(item)); + } +}; + +static NodeClipboard &get_node_clipboard() +{ + static NodeClipboard clipboard; + return clipboard; +} + +/* -------------------------------------------------------------------- */ +/** \name Copy + * \{ */ + +static int node_clipboard_copy_exec(bContext *C, wmOperator * /*op*/) +{ + SpaceNode &snode = *CTX_wm_space_node(C); + bNodeTree &tree = *snode.edittree; + NodeClipboard &clipboard = get_node_clipboard(); + + clipboard.clear(); + + Map node_map; + Map socket_map; + + for (bNode *node : tree.all_nodes()) { + if (node->flag & SELECT) { + /* No ID reference counting, this node is virtual, detached from any actual Blender data. */ + bNode *new_node = bke::node_copy_with_mapping(nullptr, + *node, + LIB_ID_CREATE_NO_USER_REFCOUNT | + LIB_ID_CREATE_NO_MAIN, + false, + socket_map); + node_map.add_new(node, new_node); + } + } + + for (bNode *new_node : node_map.values()) { + clipboard.add_node(new_node); + + /* Parent pointer must be redirected to new node or detached if parent is not copied. */ + if (new_node->parent) { + if (node_map.contains(new_node->parent)) { + new_node->parent = node_map.lookup(new_node->parent); + } + else { + nodeDetachNode(&tree, new_node); + } + } + } + + /* Copy links between selected nodes. */ + LISTBASE_FOREACH (bNodeLink *, link, &tree.links) { + BLI_assert(link->tonode); + BLI_assert(link->fromnode); + if (link->tonode->flag & NODE_SELECT && link->fromnode->flag & NODE_SELECT) { + bNodeLink new_link{}; + new_link.flag = link->flag; + new_link.tonode = node_map.lookup(link->tonode); + new_link.tosock = socket_map.lookup(link->tosock); + new_link.fromnode = node_map.lookup(link->fromnode); + new_link.fromsock = socket_map.lookup(link->fromsock); + new_link.multi_input_socket_index = link->multi_input_socket_index; + clipboard.links.append(new_link); + } + } + + return OPERATOR_FINISHED; +} + +void NODE_OT_clipboard_copy(wmOperatorType *ot) +{ + ot->name = "Copy to Clipboard"; + ot->description = "Copies selected nodes to the clipboard"; + ot->idname = "NODE_OT_clipboard_copy"; + + ot->exec = node_clipboard_copy_exec; + ot->poll = ED_operator_node_active; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Paste + * \{ */ + +static int node_clipboard_paste_exec(bContext *C, wmOperator *op) +{ + SpaceNode &snode = *CTX_wm_space_node(C); + bNodeTree &tree = *snode.edittree; + NodeClipboard &clipboard = get_node_clipboard(); + + const bool is_valid = clipboard.validate(); + + if (clipboard.nodes.is_empty()) { + BKE_report(op->reports, RPT_ERROR, "Clipboard is empty"); + return OPERATOR_CANCELLED; + } + + if (!is_valid) { + BKE_report(op->reports, + RPT_WARNING, + "Some nodes references could not be restored, will be left empty"); + } + + ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); + + node_deselect_all(tree); + + /* calculate "barycenter" for placing on mouse cursor */ + float2 center = {0.0f, 0.0f}; + for (const NodeClipboardItem &item : clipboard.nodes) { + center.x += BLI_rctf_cent_x(&item.node->runtime->totr); + center.y += BLI_rctf_cent_y(&item.node->runtime->totr); + } + center /= clipboard.nodes.size(); + + Map node_map; + Map socket_map; + + /* copy valid nodes from clipboard */ + for (NodeClipboardItem &item : clipboard.nodes) { + const bNode &node = *item.node; + const char *disabled_hint = nullptr; + if (node.typeinfo->poll_instance && + node.typeinfo->poll_instance(&node, &tree, &disabled_hint)) { + bNode *new_node = bke::node_copy_with_mapping( + &tree, node, LIB_ID_COPY_DEFAULT, true, socket_map); + node_map.add_new(&node, new_node); + } + else { + if (disabled_hint) { + BKE_reportf(op->reports, + RPT_ERROR, + "Cannot add node %s into node tree %s: %s", + node.name, + tree.id.name + 2, + disabled_hint); + } + else { + BKE_reportf(op->reports, + RPT_ERROR, + "Cannot add node %s into node tree %s", + node.name, + tree.id.name + 2); + } + } + } + + for (bNode *new_node : node_map.values()) { + nodeSetSelected(new_node, true); + + /* The parent pointer must be redirected to new node. */ + if (new_node->parent) { + if (node_map.contains(new_node->parent)) { + new_node->parent = node_map.lookup(new_node->parent); + } + } + } + + /* Add links between existing nodes. */ + for (const bNodeLink &link : clipboard.links) { + const bNode *fromnode = link.fromnode; + const bNode *tonode = link.tonode; + if (node_map.lookup_key_ptr(fromnode) && node_map.lookup_key_ptr(tonode)) { + bNodeLink *new_link = nodeAddLink(&tree, + node_map.lookup(fromnode), + socket_map.lookup(link.fromsock), + node_map.lookup(tonode), + socket_map.lookup(link.tosock)); + new_link->multi_input_socket_index = link.multi_input_socket_index; + } + } + + tree.ensure_topology_cache(); + for (bNode *new_node : node_map.values()) { + /* Update multi input socket indices in case all connected nodes weren't copied. */ + update_multi_input_indices_for_removed_links(*new_node); + } + + Main *bmain = CTX_data_main(C); + ED_node_tree_propagate_change(C, bmain, &tree); + /* Pasting nodes can create arbitrary new relations because nodes can reference IDs. */ + DEG_relations_tag_update(bmain); + + return OPERATOR_FINISHED; +} + +void NODE_OT_clipboard_paste(wmOperatorType *ot) +{ + ot->name = "Paste from Clipboard"; + ot->description = "Pastes nodes from the clipboard to the active node tree"; + ot->idname = "NODE_OT_clipboard_paste"; + + ot->exec = node_clipboard_paste_exec; + ot->poll = ED_operator_node_editable; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/** \} */ + +} // namespace blender::ed::space_node + +void ED_node_clipboard_free() +{ + using namespace blender::ed::space_node; + NodeClipboard &clipboard = get_node_clipboard(); + clipboard.validate(); + clipboard.clear(); +} diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 9849a5385ba..1d132c99ec1 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -2203,216 +2203,6 @@ void NODE_OT_node_copy_color(wmOperatorType *ot) /** \} */ -/* -------------------------------------------------------------------- */ -/** \name Node Copy to Clipboard Operator - * \{ */ - -static int node_clipboard_copy_exec(bContext *C, wmOperator * /*op*/) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNodeTree *ntree = snode->edittree; - - ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); - - /* clear current clipboard */ - BKE_node_clipboard_clear(); - - Map node_map; - Map socket_map; - - for (bNode *node : ntree->all_nodes()) { - if (node->flag & SELECT) { - /* No ID refcounting, this node is virtual, - * detached from any actual Blender data currently. */ - bNode *new_node = bke::node_copy_with_mapping(nullptr, - *node, - LIB_ID_CREATE_NO_USER_REFCOUNT | - LIB_ID_CREATE_NO_MAIN, - false, - socket_map); - node_map.add_new(node, new_node); - } - } - - for (bNode *new_node : node_map.values()) { - BKE_node_clipboard_add_node(new_node); - - /* Parent pointer must be redirected to new node or detached if parent is not copied. */ - if (new_node->parent) { - if (node_map.contains(new_node->parent)) { - new_node->parent = node_map.lookup(new_node->parent); - } - else { - nodeDetachNode(ntree, new_node); - } - } - } - - /* Copy links between selected nodes. */ - LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { - BLI_assert(link->tonode); - BLI_assert(link->fromnode); - if (link->tonode->flag & NODE_SELECT && link->fromnode->flag & NODE_SELECT) { - bNodeLink *newlink = MEM_cnew(__func__); - newlink->flag = link->flag; - newlink->tonode = node_map.lookup(link->tonode); - newlink->tosock = socket_map.lookup(link->tosock); - newlink->fromnode = node_map.lookup(link->fromnode); - newlink->fromsock = socket_map.lookup(link->fromsock); - newlink->multi_input_socket_index = link->multi_input_socket_index; - - BKE_node_clipboard_add_link(newlink); - } - } - - return OPERATOR_FINISHED; -} - -void NODE_OT_clipboard_copy(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Copy to Clipboard"; - ot->description = "Copies selected nodes to the clipboard"; - ot->idname = "NODE_OT_clipboard_copy"; - - /* api callbacks */ - ot->exec = node_clipboard_copy_exec; - ot->poll = ED_operator_node_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Node Paste from Clipboard - * \{ */ - -static int node_clipboard_paste_exec(bContext *C, wmOperator *op) -{ - SpaceNode *snode = CTX_wm_space_node(C); - bNodeTree *ntree = snode->edittree; - - /* validate pointers in the clipboard */ - bool is_clipboard_valid = BKE_node_clipboard_validate(); - const ListBase *clipboard_nodes_lb = BKE_node_clipboard_get_nodes(); - const ListBase *clipboard_links_lb = BKE_node_clipboard_get_links(); - - if (BLI_listbase_is_empty(clipboard_nodes_lb)) { - BKE_report(op->reports, RPT_ERROR, "Clipboard is empty"); - return OPERATOR_CANCELLED; - } - - /* only warn */ - if (is_clipboard_valid == false) { - BKE_report(op->reports, - RPT_WARNING, - "Some nodes references could not be restored, will be left empty"); - } - - ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); - - /* deselect old nodes */ - node_deselect_all(*ntree); - - /* calculate "barycenter" for placing on mouse cursor */ - float2 center = {0.0f, 0.0f}; - int num_nodes = 0; - LISTBASE_FOREACH_INDEX (bNode *, node, clipboard_nodes_lb, num_nodes) { - center.x += BLI_rctf_cent_x(&node->runtime->totr); - center.y += BLI_rctf_cent_y(&node->runtime->totr); - } - mul_v2_fl(center, 1.0 / num_nodes); - - Map node_map; - Map socket_map; - - /* copy valid nodes from clipboard */ - LISTBASE_FOREACH (bNode *, node, clipboard_nodes_lb) { - const char *disabled_hint = nullptr; - if (node->typeinfo->poll_instance && - node->typeinfo->poll_instance(node, ntree, &disabled_hint)) { - bNode *new_node = bke::node_copy_with_mapping( - ntree, *node, LIB_ID_COPY_DEFAULT, true, socket_map); - node_map.add_new(node, new_node); - } - else { - if (disabled_hint) { - BKE_reportf(op->reports, - RPT_ERROR, - "Cannot add node %s into node tree %s: %s", - node->name, - ntree->id.name + 2, - disabled_hint); - } - else { - BKE_reportf(op->reports, - RPT_ERROR, - "Cannot add node %s into node tree %s", - node->name, - ntree->id.name + 2); - } - } - } - - for (bNode *new_node : node_map.values()) { - /* pasted nodes are selected */ - nodeSetSelected(new_node, true); - - /* The parent pointer must be redirected to new node. */ - if (new_node->parent) { - if (node_map.contains(new_node->parent)) { - new_node->parent = node_map.lookup(new_node->parent); - } - } - } - - /* Add links between existing nodes. */ - LISTBASE_FOREACH (bNodeLink *, link, clipboard_links_lb) { - const bNode *fromnode = link->fromnode; - const bNode *tonode = link->tonode; - if (node_map.lookup_key_ptr(fromnode) && node_map.lookup_key_ptr(tonode)) { - bNodeLink *new_link = nodeAddLink(ntree, - node_map.lookup(fromnode), - socket_map.lookup(link->fromsock), - node_map.lookup(tonode), - socket_map.lookup(link->tosock)); - new_link->multi_input_socket_index = link->multi_input_socket_index; - } - } - ntree->ensure_topology_cache(); - - for (bNode *new_node : node_map.values()) { - /* Update multi input socket indices in case all connected nodes weren't copied. */ - update_multi_input_indices_for_removed_links(*new_node); - } - - Main *bmain = CTX_data_main(C); - ED_node_tree_propagate_change(C, bmain, snode->edittree); - /* Pasting nodes can create arbitrary new relations, because nodes can reference IDs. */ - DEG_relations_tag_update(bmain); - - return OPERATOR_FINISHED; -} - -void NODE_OT_clipboard_paste(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Paste from Clipboard"; - ot->description = "Pastes nodes from the clipboard to the active node tree"; - ot->idname = "NODE_OT_clipboard_paste"; - - /* api callbacks */ - ot->exec = node_clipboard_paste_exec; - ot->poll = ED_operator_node_editable; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/** \} */ - /* -------------------------------------------------------------------- */ /** \name Node-Tree Add Interface Socket Operator * \{ */ diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index f7b24c998e6..8e1f3c14208 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -537,7 +537,7 @@ void WM_exit_ex(bContext *C, const bool do_python) BKE_tracking_clipboard_free(); BKE_mask_clipboard_free(); BKE_vfont_clipboard_free(); - BKE_node_clipboard_free(); + ED_node_clipboard_free(); UV_clipboard_free(); #ifdef WITH_COMPOSITOR_CPU From 9cef74f58b95ca93c87d33767b401404b78f6faa Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 30 Dec 2022 14:40:23 +0900 Subject: [PATCH 0324/1522] install_deps.sh: Enable NVPTX backend for LLVM (and OSL). Based on suggestion from Ray molenkamp (@LazyDodo), thanks. Also fix patching of OSL code, would not work properly when using repo checkout instead of archive download. Re. T99618. --- build_files/build_environment/install_deps.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index c876bdd63e2..81e9b0f371c 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -2398,7 +2398,7 @@ compile_LLVM() { fi # To be changed each time we make edits that would modify the compiled result! - llvm_magic=3 + llvm_magic=4 _init_llvm # Force having own builds for the dependencies. @@ -2447,9 +2447,9 @@ compile_LLVM() { mkdir build cd build - LLVM_TARGETS="X86" + LLVM_TARGETS="X86;NVPTX" if [ $(uname -m) == "aarch64" ]; then - LLVM_TARGETS="AArch64" + LLVM_TARGETS="AArch64;NVPTX" fi cmake_d="-D CMAKE_BUILD_TYPE=Release" @@ -2516,7 +2516,7 @@ compile_OSL() { fi # To be changed each time we make edits that would modify the compiled result! - osl_magic=21 + osl_magic=22 _init_osl # Force having own builds for the dependencies. @@ -2547,8 +2547,9 @@ compile_OSL() { INFO "Unpacking OpenShadingLanguage-$OSL_VERSION" tar -C $SRC --transform "s,(.*/?)OpenShadingLanguage-[^/]*(.*),\1OpenShadingLanguage-$OSL_VERSION\2,x" \ -xf $_src.tar.gz + + patch -d $_src -p1 < $SCRIPT_DIR/patches/osl.diff fi - patch -d $_src -p1 < $SCRIPT_DIR/patches/osl.diff fi cd $_src @@ -2560,6 +2561,8 @@ compile_OSL() { # Stick to same rev as windows' libs... git checkout $OSL_SOURCE_REPO_UID git reset --hard + + patch -d $_src -p1 < $SCRIPT_DIR/patches/osl.diff fi # Always refresh the whole build! From 3340cc81020309afc0db3fb42a36dfb1ec15fcec Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 30 Dec 2022 14:35:15 +0100 Subject: [PATCH 0325/1522] Nodes: add asserts to detect invalid links earlier --- source/blender/blenkernel/intern/node_runtime.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/blenkernel/intern/node_runtime.cc b/source/blender/blenkernel/intern/node_runtime.cc index 642dfcc0490..d3b16d4c1a5 100644 --- a/source/blender/blenkernel/intern/node_runtime.cc +++ b/source/blender/blenkernel/intern/node_runtime.cc @@ -51,6 +51,10 @@ static void update_link_vector(const bNodeTree &ntree) bNodeTreeRuntime &tree_runtime = *ntree.runtime; tree_runtime.links.clear(); LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { + /* Check that the link connects nodes within this tree. */ + BLI_assert(tree_runtime.nodes_by_id.contains(link->fromnode)); + BLI_assert(tree_runtime.nodes_by_id.contains(link->tonode)); + tree_runtime.links.append(link); } } From f891ddd98dc4b03a62647f7a1d772ea56d3b5747 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 30 Dec 2022 23:52:44 -0500 Subject: [PATCH 0326/1522] Cleanup: Use indices in curve to mesh, decrease variable scope --- .../blender/blenkernel/intern/mesh_convert.cc | 118 +++++++++--------- 1 file changed, 57 insertions(+), 61 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 9f9548a5e4c..0a66bacd004 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -143,9 +143,7 @@ static void make_edges_mdata_extend(Mesh &mesh) static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispbase) { using namespace blender::bke; - const float *data; - int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totpoly = 0; - int p1, p2, p3, p4, *index; + int a, b, ofs; const bool conv_polys = ( /* 2D polys are filled with #DispList.type == #DL_INDEX3. */ (CU_DO_2DFILL(cu) == false) || @@ -153,6 +151,10 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba BKE_curve_type_get(cu) == OB_SURF); /* count */ + int totvert = 0; + int totedge = 0; + int totpoly = 0; + int totloop = 0; LISTBASE_FOREACH (const DispList *, dl, dispbase) { if (dl->type == DL_SEGM) { totvert += dl->parts * dl->nr; @@ -193,117 +195,110 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); - MVert *mvert = verts.data(); - MEdge *medge = edges.data(); - MPoly *mpoly = polys.data(); - MLoop *mloop = loops.data(); MutableAttributeAccessor attributes = mesh->attributes_for_write(); SpanAttributeWriter material_indices = attributes.lookup_or_add_for_write_only_span( "material_index", ATTR_DOMAIN_FACE); MLoopUV *mloopuv = static_cast(CustomData_add_layer_named( &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, DATA_("UVMap"))); - /* verts and faces */ - vertcount = 0; - + int dst_vert = 0; + int dst_edge = 0; + int dst_poly = 0; + int dst_loop = 0; LISTBASE_FOREACH (const DispList *, dl, dispbase) { const bool is_smooth = (dl->rt & CU_SMOOTH) != 0; if (dl->type == DL_SEGM) { - startvert = vertcount; + const int startvert = dst_vert; a = dl->parts * dl->nr; - data = dl->verts; + const float *data = dl->verts; while (a--) { - copy_v3_v3(mvert->co, data); + copy_v3_v3(verts[dst_vert].co, data); data += 3; - vertcount++; - mvert++; + dst_vert++; } for (a = 0; a < dl->parts; a++) { ofs = a * dl->nr; for (b = 1; b < dl->nr; b++) { - medge->v1 = startvert + ofs + b - 1; - medge->v2 = startvert + ofs + b; - medge->flag = ME_EDGEDRAW; + edges[dst_edge].v1 = startvert + ofs + b - 1; + edges[dst_edge].v2 = startvert + ofs + b; + edges[dst_edge].flag = ME_EDGEDRAW; - medge++; + dst_edge++; } } } else if (dl->type == DL_POLY) { if (conv_polys) { - startvert = vertcount; + const int startvert = dst_vert; a = dl->parts * dl->nr; - data = dl->verts; + const float *data = dl->verts; while (a--) { - copy_v3_v3(mvert->co, data); + copy_v3_v3(verts[dst_vert].co, data); data += 3; - vertcount++; - mvert++; + dst_vert++; } for (a = 0; a < dl->parts; a++) { ofs = a * dl->nr; for (b = 0; b < dl->nr; b++) { - medge->v1 = startvert + ofs + b; + edges[dst_edge].v1 = startvert + ofs + b; if (b == dl->nr - 1) { - medge->v2 = startvert + ofs; + edges[dst_edge].v2 = startvert + ofs; } else { - medge->v2 = startvert + ofs + b + 1; + edges[dst_edge].v2 = startvert + ofs + b + 1; } - medge->flag = ME_EDGEDRAW; - medge++; + edges[dst_edge].flag = ME_EDGEDRAW; + dst_edge++; } } } } else if (dl->type == DL_INDEX3) { - startvert = vertcount; + const int startvert = dst_vert; a = dl->nr; - data = dl->verts; + const float *data = dl->verts; while (a--) { - copy_v3_v3(mvert->co, data); + copy_v3_v3(verts[dst_vert].co, data); data += 3; - vertcount++; - mvert++; + dst_vert++; } a = dl->parts; - index = dl->index; + const int *index = dl->index; while (a--) { - mloop[0].v = startvert + index[0]; - mloop[1].v = startvert + index[2]; - mloop[2].v = startvert + index[1]; - mpoly->loopstart = int(mloop - loops.data()); - mpoly->totloop = 3; - material_indices.span[mpoly - polys.data()] = dl->col; + loops[dst_loop + 0].v = startvert + index[0]; + loops[dst_loop + 1].v = startvert + index[2]; + loops[dst_loop + 2].v = startvert + index[1]; + polys[dst_poly].loopstart = dst_loop; + polys[dst_poly].totloop = 3; + material_indices.span[dst_poly] = dl->col; if (mloopuv) { for (int i = 0; i < 3; i++, mloopuv++) { - mloopuv->uv[0] = (mloop[i].v - startvert) / float(dl->nr - 1); + mloopuv->uv[0] = (loops[dst_loop + i].v - startvert) / float(dl->nr - 1); mloopuv->uv[1] = 0.0f; } } if (is_smooth) { - mpoly->flag |= ME_SMOOTH; + polys[dst_poly].flag |= ME_SMOOTH; } - mpoly++; - mloop += 3; + dst_poly++; + dst_loop += 3; index += 3; } } else if (dl->type == DL_SURF) { - startvert = vertcount; + const int startvert = dst_vert; a = dl->parts * dl->nr; - data = dl->verts; + const float *data = dl->verts; while (a--) { - copy_v3_v3(mvert->co, data); + copy_v3_v3(verts[dst_vert].co, data); data += 3; - vertcount++; - mvert++; + dst_vert++; } for (a = 0; a < dl->parts; a++) { @@ -312,6 +307,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba break; } + int p1, p2, p3, p4; if (dl->flag & DL_CYCL_U) { /* p2 -> p1 -> */ p1 = startvert + dl->nr * a; /* p4 -> p3 -> */ p2 = p1 + dl->nr - 1; /* -----> next row */ @@ -332,13 +328,13 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba } for (; b < dl->nr; b++) { - mloop[0].v = p1; - mloop[1].v = p3; - mloop[2].v = p4; - mloop[3].v = p2; - mpoly->loopstart = int(mloop - loops.data()); - mpoly->totloop = 4; - material_indices.span[mpoly - polys.data()] = dl->col; + loops[dst_loop + 0].v = p1; + loops[dst_loop + 1].v = p3; + loops[dst_loop + 2].v = p4; + loops[dst_loop + 3].v = p2; + polys[dst_poly].loopstart = dst_loop; + polys[dst_poly].totloop = 4; + material_indices.span[dst_poly] = dl->col; if (mloopuv) { int orco_sizeu = dl->nr - 1; @@ -357,7 +353,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba for (int i = 0; i < 4; i++, mloopuv++) { /* find uv based on vertex index into grid array */ - int v = mloop[i].v - startvert; + int v = loops[dst_loop + i].v - startvert; mloopuv->uv[0] = (v / dl->nr) / float(orco_sizev); mloopuv->uv[1] = (v % dl->nr) / float(orco_sizeu); @@ -373,10 +369,10 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba } if (is_smooth) { - mpoly->flag |= ME_SMOOTH; + polys[dst_poly].flag |= ME_SMOOTH; } - mpoly++; - mloop += 4; + dst_poly++; + dst_loop += 4; p4 = p3; p3++; From 17d66fe79ed20abef12000b79de20013e749569c Mon Sep 17 00:00:00 2001 From: "Kevin C. Burke" Date: Sat, 31 Dec 2022 16:24:44 +0100 Subject: [PATCH 0327/1522] GPencil: 'Delete Duplicate Keyframes' in GPENCIL_MT_cleanup Menu The command text 'Delete Duplicated Frames' used in the `GPENCIL_MT_cleanup` menu is not correct grammar for what the command does. Keyframes removed by this command may be duplicate keys without having been duplicated. It also does not match the name of the command in `DOPESHEET_MT_context_menu`. [[ https://developer.blender.org/diffusion/B/browse/master/release/scripts/startup/bl_ui/space_dopesheet.py$676 | space_dopesheet.py ]] This patch fixes the grammar, gets the command's text to match the `DOPESHEET_MT_context_menu`, and corrects the description in the [[ https://docs.blender.org/api/current/bpy.ops.gpencil.html#bpy.ops.gpencil.frame_clean_duplicate | Python API documentation ]]. Reviewed By: antoniov Differential Revision: https://developer.blender.org/D16887 --- .../startup/bl_ui/properties_grease_pencil_common.py | 2 +- source/blender/editors/gpencil/gpencil_data.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index e70c75a53ca..e0f5d65db16 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -326,7 +326,7 @@ class GPENCIL_MT_cleanup(Menu): layout.separator() - layout.operator("gpencil.frame_clean_duplicate", text="Delete Duplicated Frames") + layout.operator("gpencil.frame_clean_duplicate", text="Delete Duplicate Frames") layout.operator("gpencil.recalc_geometry", text="Recalculate Geometry") if ob.mode != 'PAINT_GPENCIL': layout.operator("gpencil.reproject") diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 5f21ca69baf..4f61016215a 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -881,7 +881,7 @@ void GPENCIL_OT_frame_clean_loose(wmOperatorType *ot) INT_MAX); } -/* ********************* Clean Duplicated Frames ************************** */ +/* ********************* Clean Duplicate Frames ************************** */ static bool gpencil_frame_is_equal(const bGPDframe *gpf_a, const bGPDframe *gpf_b) { if ((gpf_a == NULL) || (gpf_b == NULL)) { @@ -1015,9 +1015,9 @@ void GPENCIL_OT_frame_clean_duplicate(wmOperatorType *ot) }; /* identifiers */ - ot->name = "Clean Duplicated Frames"; + ot->name = "Clean Duplicate Frames"; ot->idname = "GPENCIL_OT_frame_clean_duplicate"; - ot->description = "Remove any duplicated frame"; + ot->description = "Remove duplicate keyframes"; /* callbacks */ ot->exec = gpencil_frame_clean_duplicate_exec; From 614704f90c32e7649d3d725495b9964af35e88e5 Mon Sep 17 00:00:00 2001 From: "Kevin C. Burke" Date: Sat, 31 Dec 2022 16:26:27 +0100 Subject: [PATCH 0328/1522] GPencil: Removing 'Only Show Selected' Requirement for DOPESHEET_HT_editor_buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's confusing for users when the Dopesheet's Editor Buttons for Grease Pencil are greyed out. {F14099985} [[ https://blenderartists.org/t/cant-create-new-layers-in-grease-pencil-dopesheet/1353882 | Can’t create new layers in grease pencil dopesheet ]] This is often because the 'Only Show Selected' filter is disabled. This 'requirement' does not seem to be necessary since the Dopesheet is already in Grease Pencil mode and there is an active Grease Pencil Object. It is also not apparent as to why so many Operators depend on it and unintuitive that it controls their function. The 'Only Show Selected' filter button is far away from the Operator buttons in the User Interface Header, so it's difficult to make the association. If the 'Only Show Selected' IS absolutely required, I believe it should be closer to the DOPESHEET_HT_editor_buttons. Otherwise, I think the requirement should be removed. Reviewed By: antoniov Differential Revision: https://developer.blender.org/D16885 --- release/scripts/startup/bl_ui/space_dopesheet.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index f95650ccc23..1913c809ec5 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -238,8 +238,7 @@ class DOPESHEET_HT_editor_buttons: # Layer management if st.mode == 'GPENCIL': ob = context.active_object - selected = st.dopesheet.show_only_selected - enable_but = selected and ob is not None and ob.type == 'GPENCIL' + enable_but = ob is not None and ob.type == 'GPENCIL' row = layout.row(align=True) row.enabled = enable_but From 8007f7e74f5085693c5b5f83d3f9f19a173bab75 Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Sun, 1 Jan 2023 19:14:37 +0200 Subject: [PATCH 0329/1522] Fix T103212: ignore OBJ UV indices if no UVs are present Similar to T98782 that was about normal indices: some files out there are technically "wrong" since they refer to UV indices, without ever defining any UVs. If the file does not have any UVs, simply ignore UV indices in the OBJ face definitions. Fixes T103212. --- .../io/wavefront_obj/importer/obj_import_file_reader.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc index 7d5f023af4b..a46b3397891 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc @@ -222,7 +222,8 @@ static void geom_add_polygon(Geometry *geom, else { geom->track_vertex_index(corner.vert_index); } - if (got_uv) { + /* Ignore UV index, if the geometry does not have any UVs (T103212). */ + if (got_uv && !global_vertices.uv_vertices.is_empty()) { corner.uv_vert_index += corner.uv_vert_index < 0 ? global_vertices.uv_vertices.size() : -1; if (corner.uv_vert_index < 0 || corner.uv_vert_index >= global_vertices.uv_vertices.size()) { fprintf(stderr, From 3277879085ed42a4524a7c43110c37dd0d4ebb84 Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Sun, 1 Jan 2023 19:30:20 +0200 Subject: [PATCH 0330/1522] Fix T103441: make OBJ importer ignore any unrecognized trailing per-face index data. Some files out there (e.g. in T103441) contain face definitions with four indices, which the importer code was not expecting. The OBJ standard spells out up to three indices per face corner; the file in there must be using some sort of non-standard OBJ syntax extension. Now the code simply ignores any trailing per-face-corner data. --- .../blender/io/wavefront_obj/importer/obj_import_file_reader.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc index a46b3397891..1a3a333d957 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc @@ -252,6 +252,8 @@ static void geom_add_polygon(Geometry *geom, geom->face_corners_.append(corner); curr_face.corner_count_++; + /* Some files contain extra stuff per face (e.g. 4 indices); skip any remainder (T103441). */ + p = drop_non_whitespace(p, end); /* Skip whitespace to get to the next face corner. */ p = drop_whitespace(p, end); } From 4924f8cffd4522f46161258ff33cf036a5a11eae Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Mon, 2 Jan 2023 11:53:40 +1300 Subject: [PATCH 0331/1522] Cleanup: format --- source/blender/blenkernel/intern/node.cc | 2 -- source/blender/blenloader/intern/versioning_common.h | 4 ++-- source/blender/editors/space_node/drawnode.cc | 3 ++- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 3cd0cf2f7ca..69d2b2a12e6 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3558,8 +3558,6 @@ void nodeSetActive(bNodeTree *ntree, bNode *node) node->flag |= flags_to_set; } - - void nodeSetSocketAvailability(bNodeTree *ntree, bNodeSocket *sock, bool is_available) { const bool was_available = (sock->flag & SOCK_UNAVAIL) == 0; diff --git a/source/blender/blenloader/intern/versioning_common.h b/source/blender/blenloader/intern/versioning_common.h index c99fb60be30..40f383a27b2 100644 --- a/source/blender/blenloader/intern/versioning_common.h +++ b/source/blender/blenloader/intern/versioning_common.h @@ -88,8 +88,8 @@ struct bNodeSocket *version_node_add_socket_if_not_exist(struct bNodeTree *ntree const char *name); /** - * The versioning code generally expects `SOCK_IS_LINKED` to be set correctly. This function updates - * the flag on all sockets after changes to the node tree. + * The versioning code generally expects `SOCK_IS_LINKED` to be set correctly. This function + * updates the flag on all sockets after changes to the node tree. */ void version_socket_update_is_used(bNodeTree *ntree); ARegion *do_versions_add_region(int regiontype, const char *name); diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index efe7c2e91b6..7c2e7c003a3 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -1293,7 +1293,8 @@ static void std_node_socket_draw( return; } - if ((sock->in_out == SOCK_OUT) || (sock->flag & SOCK_IS_LINKED) || (sock->flag & SOCK_HIDE_VALUE)) { + if ((sock->in_out == SOCK_OUT) || (sock->flag & SOCK_IS_LINKED) || + (sock->flag & SOCK_HIDE_VALUE)) { node_socket_button_label(C, layout, ptr, node_ptr, text); return; } From 7e5a7928ca2ae5f38c8d2ce11b79cc198527c725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 2 Jan 2023 11:13:40 +0100 Subject: [PATCH 0332/1522] Cleanup: resolve 'no previous prototype' warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve `warning: no previous prototype for ‘gpencil_layer_new_name_get’` by marking it as `static`. No functional changes. --- source/blender/editors/gpencil/gpencil_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index f91480b72e7..c0024052d82 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -3356,7 +3356,7 @@ void ED_gpencil_layer_merge(bGPdata *gpd, } } -void gpencil_layer_new_name_get(bGPdata *gpd, char *rname) +static void gpencil_layer_new_name_get(bGPdata *gpd, char *rname) { int index = 0; LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { From a4e843c25024eb1e3a988e74d2f0efd887eb2588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 2 Jan 2023 11:14:14 +0100 Subject: [PATCH 0333/1522] =?UTF-8?q?Cleanup:=20resolve=20`variable=20?= =?UTF-8?q?=E2=80=98update=E2=80=99=20set=20but=20not=20used`=20warning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve `variable ‘update’ set but not used` compiler warning, by removing the variable altogether. No functional changes. --- source/blender/editors/sculpt_paint/sculpt_expand.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index 1a9abb04ba8..a05dc8c7c66 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -2144,11 +2144,9 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &nodes_num); for (int i = 0; i < nodes_num; i++) { PBVHVertexIter vd; - bool update = false; BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[i], vd, PBVH_ITER_UNIQUE) { *vd.mask = 1.0f; - update = true; } BKE_pbvh_vertex_iter_end; From 68906c605f34ff82c840de09c0b85bd84b9d4410 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 2 Jan 2023 12:44:10 +0100 Subject: [PATCH 0334/1522] Fix T103080: Regression: Setup tracking scene is disabled There are two underlying issues which got uncovered by the report: First, is that the poll() function for the operator was using legacy API which is on its way of removal in the next major version release. This part is fixed in this patch based on a patch provided by Philipp Oeser (P3389) with the modification that the `clip` is not accessed prior to None check. Ended up in a bit annoying one-liner, the entire function could be refactored to use early returns. The second issue is that the Python access to the legacy property was wrong: need to access camera reconstruction instead of accessing deprecated DNA field. --- release/scripts/startup/bl_operators/clip.py | 2 +- source/blender/makesrna/intern/rna_tracking.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index 4e018ffc457..4bdf20d207c 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -540,7 +540,7 @@ class CLIP_OT_setup_tracking_scene(Operator): sc = context.space_data if sc and sc.type == 'CLIP_EDITOR': clip = sc.clip - if clip and clip.tracking.reconstruction.is_valid: + if clip and clip.tracking.objects.active.reconstruction.is_valid: return True return False diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index f08cd2fe95d..a4c3dab4b5d 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -101,6 +101,15 @@ static void rna_trackingPlaneTracks_begin(CollectionPropertyIterator *iter, Poin rna_iterator_listbase_begin(iter, &tracking_camera_object->plane_tracks, NULL); } +static PointerRNA rna_trackingReconstruction_get(PointerRNA *ptr) +{ + MovieClip *clip = (MovieClip *)ptr->owner_id; + MovieTrackingObject *tracking_camera_object = BKE_tracking_object_get_camera(&clip->tracking); + + return rna_pointer_inherit_refine( + ptr, &RNA_MovieTrackingReconstruction, &tracking_camera_object->reconstruction); +} + static void rna_trackingObjects_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { MovieClip *clip = (MovieClip *)ptr->owner_id; @@ -2609,6 +2618,7 @@ static void rna_def_tracking(BlenderRNA *brna) /* reconstruction */ prop = RNA_def_property(srna, "reconstruction", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "reconstruction_legacy"); + RNA_def_property_pointer_funcs(prop, "rna_trackingReconstruction_get", NULL, NULL, NULL); RNA_def_property_struct_type(prop, "MovieTrackingReconstruction"); /* objects */ From 153e1dc31a518fc307c7d87bb5bd700688e438f9 Mon Sep 17 00:00:00 2001 From: Patrick Mours Date: Mon, 2 Jan 2023 13:52:59 +0100 Subject: [PATCH 0335/1522] Fix T103513: Images lose their alpha channel when OSL is enabled for GPU Compute The "osl_texture" intrinsic was not implemented correctly. It should handle alpha separately from color, the number of channels input parameter only counts color channels. --- intern/cycles/kernel/osl/services_gpu.h | 27 ++++++++++++++----------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/intern/cycles/kernel/osl/services_gpu.h b/intern/cycles/kernel/osl/services_gpu.h index 744c7103b28..b9ffd959f1a 100644 --- a/intern/cycles/kernel/osl/services_gpu.h +++ b/intern/cycles/kernel/osl/services_gpu.h @@ -1532,7 +1532,7 @@ ccl_device_extern void osl_texture_set_missingcolor_alpha(ccl_private OSLTexture ccl_device_extern bool osl_texture(ccl_private ShaderGlobals *sg, DeviceString filename, ccl_private void *texture_handle, - OSLTextureOptions *opt, + ccl_private OSLTextureOptions *opt, float s, float t, float dsdx, @@ -1557,13 +1557,14 @@ ccl_device_extern bool osl_texture(ccl_private ShaderGlobals *sg, const float4 rgba = kernel_tex_image_interp(nullptr, id, s, 1.0f - t); - result[0] = rgba.x; + if (nchannels > 0) + result[0] = rgba.x; if (nchannels > 1) result[1] = rgba.y; if (nchannels > 2) result[2] = rgba.z; - if (nchannels > 3) - result[3] = rgba.w; + if (alpha) + *alpha = rgba.w; return true; } @@ -1571,7 +1572,7 @@ ccl_device_extern bool osl_texture(ccl_private ShaderGlobals *sg, ccl_device_extern bool osl_texture3d(ccl_private ShaderGlobals *sg, DeviceString filename, ccl_private void *texture_handle, - OSLTextureOptions *opt, + ccl_private OSLTextureOptions *opt, ccl_private const float3 *P, ccl_private const float3 *dPdx, ccl_private const float3 *dPdy, @@ -1594,13 +1595,14 @@ ccl_device_extern bool osl_texture3d(ccl_private ShaderGlobals *sg, const float4 rgba = kernel_tex_image_interp_3d(nullptr, id, *P, INTERPOLATION_NONE); - result[0] = rgba.x; + if (nchannels > 0) + result[0] = rgba.x; if (nchannels > 1) result[1] = rgba.y; if (nchannels > 2) result[2] = rgba.z; - if (nchannels > 3) - result[3] = rgba.w; + if (alpha) + *alpha = rgba.w; return true; } @@ -1608,7 +1610,7 @@ ccl_device_extern bool osl_texture3d(ccl_private ShaderGlobals *sg, ccl_device_extern bool osl_environment(ccl_private ShaderGlobals *sg, DeviceString filename, ccl_private void *texture_handle, - OSLTextureOptions *opt, + ccl_private OSLTextureOptions *opt, ccl_private const float3 *R, ccl_private const float3 *dRdx, ccl_private const float3 *dRdy, @@ -1621,13 +1623,14 @@ ccl_device_extern bool osl_environment(ccl_private ShaderGlobals *sg, ccl_private float *dalphay, ccl_private void *errormessage) { - result[0] = 1.0f; + if (nchannels > 0) + result[0] = 1.0f; if (nchannels > 1) result[1] = 0.0f; if (nchannels > 2) result[2] = 1.0f; - if (nchannels > 3) - result[3] = 1.0f; + if (alpha) + *alpha = 1.0f; return false; } From 9d2ab1f8d33b7cc039708a5e51375373f4c397c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 2 Jan 2023 14:39:17 +0100 Subject: [PATCH 0336/1522] Refactor: anim, move pose backup code from editors into blenkernel Move `pose_backup.cc` from `editors/armature` to `blenkernel`. This is in preparation of an upcoming change where the pose backup is going to be owned by the `Object`. This will need to be automatically cleared when the object is freed, which means that `blenkernel` needs the corresponding logic. Technically only the freeing code could be moved, but I felt it made more sense to keep the related code together. No functional changes. --- source/blender/blenkernel/BKE_pose_backup.h | 36 +++++++++++++++++++ source/blender/blenkernel/CMakeLists.txt | 1 + .../intern}/pose_backup.cc | 14 ++++---- .../blender/editors/armature/CMakeLists.txt | 1 - source/blender/editors/armature/pose_lib_2.c | 12 +++---- source/blender/editors/include/ED_armature.h | 13 ------- .../blender/editors/render/render_preview.cc | 8 ++--- 7 files changed, 54 insertions(+), 31 deletions(-) create mode 100644 source/blender/blenkernel/BKE_pose_backup.h rename source/blender/{editors/armature => blenkernel/intern}/pose_backup.cc (89%) diff --git a/source/blender/blenkernel/BKE_pose_backup.h b/source/blender/blenkernel/BKE_pose_backup.h new file mode 100644 index 00000000000..72068a94405 --- /dev/null +++ b/source/blender/blenkernel/BKE_pose_backup.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup bke + * + * Pose Backups can be created from the current pose, and later restored. The + * backup is restricted to those bones animated by a given Action, so that + * operations are as fast as possible. + */ + +#pragma once + +#include + +#include "BLI_listbase.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct PoseBackup; + +/** + * Create a backup of those bones that are animated in the given action. + */ +struct PoseBackup *BKE_pose_backup_create_selected_bones( + const struct Object *ob, const struct bAction *action) ATTR_WARN_UNUSED_RESULT; +struct PoseBackup *BKE_pose_backup_create_all_bones( + const struct Object *ob, const struct bAction *action) ATTR_WARN_UNUSED_RESULT; +bool BKE_pose_backup_is_selection_relevant(const struct PoseBackup *pose_backup); +void BKE_pose_backup_restore(const struct PoseBackup *pbd); +void BKE_pose_backup_free(struct PoseBackup *pbd); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index c12c0c06ed8..ec5c5a88b07 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -254,6 +254,7 @@ set(SRC intern/pbvh_uv_islands.cc intern/pointcache.c intern/pointcloud.cc + intern/pose_backup.cc intern/preferences.c intern/report.c intern/rigidbody.c diff --git a/source/blender/editors/armature/pose_backup.cc b/source/blender/blenkernel/intern/pose_backup.cc similarity index 89% rename from source/blender/editors/armature/pose_backup.cc rename to source/blender/blenkernel/intern/pose_backup.cc index fbcd3a82311..b5c5aeef4c2 100644 --- a/source/blender/editors/armature/pose_backup.cc +++ b/source/blender/blenkernel/intern/pose_backup.cc @@ -1,10 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /** \file - * \ingroup edarmature + * \ingroup bke */ -#include "ED_armature.h" +#include "BKE_pose_backup.h" #include @@ -86,24 +86,24 @@ static PoseBackup *pose_backup_create(const Object *ob, return pose_backup; } -PoseBackup *ED_pose_backup_create_all_bones(const Object *ob, const bAction *action) +PoseBackup *BKE_pose_backup_create_all_bones(const Object *ob, const bAction *action) { return pose_backup_create(ob, action, BoneNameSet()); } -PoseBackup *ED_pose_backup_create_selected_bones(const Object *ob, const bAction *action) +PoseBackup *BKE_pose_backup_create_selected_bones(const Object *ob, const bAction *action) { const bArmature *armature = static_cast(ob->data); const BoneNameSet selected_bone_names = BKE_armature_find_selected_bone_names(armature); return pose_backup_create(ob, action, selected_bone_names); } -bool ED_pose_backup_is_selection_relevant(const struct PoseBackup *pose_backup) +bool BKE_pose_backup_is_selection_relevant(const struct PoseBackup *pose_backup) { return pose_backup->is_bone_selection_relevant; } -void ED_pose_backup_restore(const PoseBackup *pbd) +void BKE_pose_backup_restore(const PoseBackup *pbd) { LISTBASE_FOREACH (PoseChannelBackup *, chan_bak, &pbd->backups) { memcpy(chan_bak->pchan, &chan_bak->olddata, sizeof(chan_bak->olddata)); @@ -117,7 +117,7 @@ void ED_pose_backup_restore(const PoseBackup *pbd) } } -void ED_pose_backup_free(PoseBackup *pbd) +void BKE_pose_backup_free(PoseBackup *pbd) { LISTBASE_FOREACH_MUTABLE (PoseChannelBackup *, chan_bak, &pbd->backups) { if (chan_bak->oldprops) { diff --git a/source/blender/editors/armature/CMakeLists.txt b/source/blender/editors/armature/CMakeLists.txt index 5ca4290790e..23e446f98da 100644 --- a/source/blender/editors/armature/CMakeLists.txt +++ b/source/blender/editors/armature/CMakeLists.txt @@ -30,7 +30,6 @@ set(SRC armature_utils.c editarmature_undo.c meshlaplacian.c - pose_backup.cc pose_edit.c pose_group.c pose_lib_2.c diff --git a/source/blender/editors/armature/pose_lib_2.c b/source/blender/editors/armature/pose_lib_2.c index 1e69d9d0fc2..d11486eb405 100644 --- a/source/blender/editors/armature/pose_lib_2.c +++ b/source/blender/editors/armature/pose_lib_2.c @@ -24,6 +24,7 @@ #include "BKE_context.h" #include "BKE_lib_id.h" #include "BKE_object.h" +#include "BKE_pose_backup.h" #include "BKE_report.h" #include "DEG_depsgraph.h" @@ -37,7 +38,6 @@ #include "UI_interface.h" -#include "ED_armature.h" #include "ED_asset.h" #include "ED_keyframing.h" #include "ED_screen.h" @@ -86,7 +86,7 @@ typedef struct PoseBlendData { /* Makes a copy of the current pose for restoration purposes - doesn't do constraints currently */ static void poselib_backup_posecopy(PoseBlendData *pbd) { - pbd->pose_backup = ED_pose_backup_create_selected_bones(pbd->ob, pbd->act); + pbd->pose_backup = BKE_pose_backup_create_selected_bones(pbd->ob, pbd->act); if (pbd->state == POSE_BLEND_INIT) { /* Ready for blending now. */ @@ -125,7 +125,7 @@ static void poselib_keytag_pose(bContext *C, Scene *scene, PoseBlendData *pbd) continue; } - if (ED_pose_backup_is_selection_relevant(pbd->pose_backup) && + if (BKE_pose_backup_is_selection_relevant(pbd->pose_backup) && !PBONE_SELECTED(armature, pchan->bone)) { continue; } @@ -152,7 +152,7 @@ static void poselib_blend_apply(bContext *C, wmOperator *op) } pbd->needs_redraw = false; - ED_pose_backup_restore(pbd->pose_backup); + BKE_pose_backup_restore(pbd->pose_backup); /* The pose needs updating, whether it's for restoring the original pose or for showing the * result of the blend. */ @@ -381,7 +381,7 @@ static void poselib_blend_cleanup(bContext *C, wmOperator *op) BKE_report(op->reports, RPT_ERROR, "Internal pose library error, canceling operator"); ATTR_FALLTHROUGH; case POSE_BLEND_CANCEL: - ED_pose_backup_restore(pbd->pose_backup); + BKE_pose_backup_restore(pbd->pose_backup); break; } @@ -406,7 +406,7 @@ static void poselib_blend_free(wmOperator *op) poselib_tempload_exit(pbd); /* Free temp data for operator */ - ED_pose_backup_free(pbd->pose_backup); + BKE_pose_backup_free(pbd->pose_backup); pbd->pose_backup = NULL; MEM_SAFE_FREE(op->customdata); diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 8e7f728a3e7..fb1c1912801 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -369,19 +369,6 @@ void ED_mesh_deform_bind_callback(struct Object *object, int verts_num, float cagemat[4][4]); -/* Pose backups, pose_backup.c */ -struct PoseBackup; -/** - * Create a backup of those bones that are animated in the given action. - */ -struct PoseBackup *ED_pose_backup_create_selected_bones( - const struct Object *ob, const struct bAction *action) ATTR_WARN_UNUSED_RESULT; -struct PoseBackup *ED_pose_backup_create_all_bones( - const struct Object *ob, const struct bAction *action) ATTR_WARN_UNUSED_RESULT; -bool ED_pose_backup_is_selection_relevant(const struct PoseBackup *pose_backup); -void ED_pose_backup_restore(const struct PoseBackup *pbd); -void ED_pose_backup_free(struct PoseBackup *pbd); - #ifdef __cplusplus } #endif diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc index ecc29c56836..18bfad0d042 100644 --- a/source/blender/editors/render/render_preview.cc +++ b/source/blender/editors/render/render_preview.cc @@ -57,6 +57,7 @@ #include "BKE_material.h" #include "BKE_node.h" #include "BKE_object.h" +#include "BKE_pose_backup.h" #include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_texture.h" @@ -81,7 +82,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "ED_armature.h" #include "ED_datafiles.h" #include "ED_render.h" #include "ED_screen.h" @@ -955,7 +955,7 @@ static struct PoseBackup *action_preview_render_prepare(IconPreview *preview) /* Create a backup of the current pose. */ struct bAction *action = (struct bAction *)preview->id; - struct PoseBackup *pose_backup = ED_pose_backup_create_all_bones(object, action); + struct PoseBackup *pose_backup = BKE_pose_backup_create_all_bones(object, action); /* Apply the Action as pose, so that it can be rendered. This assumes the Action represents a * single pose, and that thus the evaluation time doesn't matter. */ @@ -974,8 +974,8 @@ static void action_preview_render_cleanup(IconPreview *preview, struct PoseBacku if (pose_backup == nullptr) { return; } - ED_pose_backup_restore(pose_backup); - ED_pose_backup_free(pose_backup); + BKE_pose_backup_restore(pose_backup); + BKE_pose_backup_free(pose_backup); DEG_id_tag_update(&preview->active_object->id, ID_RECALC_GEOMETRY); } From 46c1cddabdbbbe19db9184e4f0487483ead44041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 2 Jan 2023 15:00:58 +0100 Subject: [PATCH 0337/1522] Cleanup: anim, add some more documentation to the pose backup code Just some more docs, to be clear about functionality and, most importantly, pointer ownership. No functional changes. --- source/blender/blenkernel/BKE_pose_backup.h | 10 +++++++++- source/blender/blenkernel/intern/pose_backup.cc | 8 ++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_pose_backup.h b/source/blender/blenkernel/BKE_pose_backup.h index 72068a94405..94bbe8d8deb 100644 --- a/source/blender/blenkernel/BKE_pose_backup.h +++ b/source/blender/blenkernel/BKE_pose_backup.h @@ -21,10 +21,18 @@ extern "C" { struct PoseBackup; /** - * Create a backup of those bones that are animated in the given action. + * Create a backup of those bones that are selected AND animated in the given action. + * + * The backup is owned by the caller, and should be freed with `BKE_pose_backup_free()`. */ struct PoseBackup *BKE_pose_backup_create_selected_bones( const struct Object *ob, const struct bAction *action) ATTR_WARN_UNUSED_RESULT; + +/** + * Create a backup of those bones that are animated in the given action. + * + * The backup is owned by the caller, and should be freed with `BKE_pose_backup_free()`. + */ struct PoseBackup *BKE_pose_backup_create_all_bones( const struct Object *ob, const struct bAction *action) ATTR_WARN_UNUSED_RESULT; bool BKE_pose_backup_is_selection_relevant(const struct PoseBackup *pose_backup); diff --git a/source/blender/blenkernel/intern/pose_backup.cc b/source/blender/blenkernel/intern/pose_backup.cc index b5c5aeef4c2..a19244f1802 100644 --- a/source/blender/blenkernel/intern/pose_backup.cc +++ b/source/blender/blenkernel/intern/pose_backup.cc @@ -38,6 +38,14 @@ struct PoseBackup { ListBase /* PoseChannelBackup* */ backups; }; +/** + * Create a backup of the pose, for only those bones that are animated in the + * given Action. If `selected_bone_names` is not empty, the set of bones to back + * up is intersected with these bone names such that only the selected subset is + * backed up. + * + * The returned pointer is owned by the caller. + */ static PoseBackup *pose_backup_create(const Object *ob, const bAction *action, const BoneNameSet &selected_bone_names) From eaef8d50bc9acf35b279a25a93f9756da30a05ae Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Mon, 2 Jan 2023 16:12:17 +0200 Subject: [PATCH 0338/1522] Fix T102672: OBJ exporter "material groups" option wrong for objects with >32k faces Turns out, using the wrong output buffer (global one, instead of per-thread one) puts the data into the wrong buffer! Fixes T102672 --- .../blender/io/wavefront_obj/exporter/obj_export_file_writer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc index 909c179dda3..ec09a145f1b 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc @@ -392,7 +392,7 @@ void OBJWriter::write_poly_elements(FormatHandler &fh, if (export_params_.export_material_groups) { std::string object_name = obj_mesh_data.get_object_name(); spaces_to_underscores(object_name); - fh.write_obj_group(object_name + "_" + mat_name); + buf.write_obj_group(object_name + "_" + mat_name); } buf.write_obj_usemtl(mat_name); } From da4e2fe7fe8fb006ce4574d1a642c9129eaa549a Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Mon, 2 Jan 2023 16:14:51 +0200 Subject: [PATCH 0339/1522] OBJ: in exporter faces loop, move material index accessor outside of the loop While the cost of creating AttributeAccessor and finding the "material_index" attribute is not large, there's really no need to do that for each polygon. Move the access outside of the per-polygon loop. --- .../io/wavefront_obj/exporter/obj_export_file_writer.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc index ec09a145f1b..6957e07dadd 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc @@ -337,6 +337,9 @@ void OBJWriter::write_poly_elements(FormatHandler &fh, const int tot_polygons = obj_mesh_data.tot_polygons(); const int tot_deform_groups = obj_mesh_data.tot_deform_groups(); threading::EnumerableThreadSpecific> group_weights; + const bke::AttributeAccessor attributes = obj_mesh_data.get_mesh()->attributes(); + const VArray material_indices = attributes.lookup_or_default( + "material_index", ATTR_DOMAIN_FACE, 0); obj_parallel_chunked_output(fh, tot_polygons, [&](FormatHandler &buf, int idx) { /* Polygon order for writing into the file is not necessarily the same @@ -372,10 +375,6 @@ void OBJWriter::write_poly_elements(FormatHandler &fh, } } - const bke::AttributeAccessor attributes = obj_mesh_data.get_mesh()->attributes(); - const VArray material_indices = attributes.lookup_or_default( - "material_index", ATTR_DOMAIN_FACE, 0); - /* Write material name and material group if different from previous. */ if (export_params_.export_materials && obj_mesh_data.tot_materials() > 0) { const int16_t prev_mat = idx == 0 ? NEGATIVE_INIT : std::max(0, material_indices[prev_i]); From 94155fb6ff141facde8fb40868f8c70659ead338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 2 Jan 2023 16:39:51 +0100 Subject: [PATCH 0340/1522] Anim: expose pose blending & backup system to RNA Expose `BKE_pose_apply_action_blend` and a simplified pose backup system to RNA. This will make it possible to easily create some interactive tools in Python for pose blending. When creating a backup via this API, it is stored on the `Object::runtime` struct. Any backup that was there before is freed first. This way the Python code doesn't need access to the actual `PoseBackup *`, simplifying memory management. The limitation of having only a single backup shouldn't be too problematic, as it is meant for things like interactive manipulation of the current pose. Typical use looks like: - Interactive operator starts, and creates a backup of the current pose. - While the operator is running: - The pose backup is restored, so that the next steps always use the same reference pose. - Depending on user input, determine a blend factor. - Blend some pose from the pose library into the current pose. - On confirmation, leave the pose as-is. - On cancellation, restore the backup. - Free the backup. `BKE_pose_apply_action_blend` is exposed to RNA to make the above possible. An alternative approach would be to rely on the operator redo system. However, since for poses this would use the global undo, it can get prohibitively slow. This change is to make it easier to prototype things; further into the future the undo system for poses should be improved, but that's an entire project on its own. Reviewed By: sergey Differential Revision: https://developer.blender.org/D16900 --- source/blender/blenkernel/BKE_pose_backup.h | 22 ++++ source/blender/blenkernel/intern/object.cc | 3 + .../blender/blenkernel/intern/pose_backup.cc | 26 ++++ source/blender/makesdna/DNA_object_types.h | 9 ++ source/blender/makesrna/intern/rna_pose_api.c | 114 +++++++++++++++++- 5 files changed, 172 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_pose_backup.h b/source/blender/blenkernel/BKE_pose_backup.h index 94bbe8d8deb..5c8f1d2a4c7 100644 --- a/source/blender/blenkernel/BKE_pose_backup.h +++ b/source/blender/blenkernel/BKE_pose_backup.h @@ -39,6 +39,28 @@ bool BKE_pose_backup_is_selection_relevant(const struct PoseBackup *pose_backup) void BKE_pose_backup_restore(const struct PoseBackup *pbd); void BKE_pose_backup_free(struct PoseBackup *pbd); +/** + * Create a backup of those bones that are animated in the given action. + * + * The backup is owned by the Object, and there can be only one backup at a time. + * It should be freed with `BKE_pose_backup_clear(ob)`. + */ +void BKE_pose_backup_create_on_object(struct Object *ob, const struct bAction *action); + +/** + * Restore the pose backup owned by this OBject. + * + * \return true on success, false if there was no pose backup to restore. + * + * \see #BKE_pose_backup_create_on_object + */ +bool BKE_pose_backup_restore_on_object(struct Object *ob); + +/** + * Free the pose backup that was stored on this object's runtime data. + */ +void BKE_pose_backup_clear(struct Object *ob); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index f4911663942..507d8f2a695 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -117,6 +117,7 @@ #include "BKE_pbvh.h" #include "BKE_pointcache.h" #include "BKE_pointcloud.h" +#include "BKE_pose_backup.h" #include "BKE_rigidbody.h" #include "BKE_scene.h" #include "BKE_shader_fx.h" @@ -1814,6 +1815,7 @@ void BKE_object_free_derived_caches(Object *ob) } BKE_object_to_mesh_clear(ob); + BKE_pose_backup_clear(ob); BKE_object_to_curve_clear(ob); BKE_object_free_curve_cache(ob); @@ -5132,6 +5134,7 @@ void BKE_object_runtime_reset_on_copy(Object *object, const int /*flag*/) runtime->mesh_deform_eval = nullptr; runtime->curve_cache = nullptr; runtime->object_as_temp_mesh = nullptr; + runtime->pose_backup = nullptr; runtime->object_as_temp_curve = nullptr; runtime->geometry_set_eval = nullptr; diff --git a/source/blender/blenkernel/intern/pose_backup.cc b/source/blender/blenkernel/intern/pose_backup.cc index a19244f1802..7d0740a22b7 100644 --- a/source/blender/blenkernel/intern/pose_backup.cc +++ b/source/blender/blenkernel/intern/pose_backup.cc @@ -135,3 +135,29 @@ void BKE_pose_backup_free(PoseBackup *pbd) } MEM_freeN(pbd); } + +void BKE_pose_backup_create_on_object(Object *ob, const bAction *action) +{ + BKE_pose_backup_clear(ob); + PoseBackup *pose_backup = BKE_pose_backup_create_all_bones(ob, action); + ob->runtime.pose_backup = pose_backup; +} + +bool BKE_pose_backup_restore_on_object(struct Object *ob) +{ + if (ob->runtime.pose_backup == nullptr) { + return false; + } + BKE_pose_backup_restore(ob->runtime.pose_backup); + return true; +} + +void BKE_pose_backup_clear(Object *ob) +{ + if (ob->runtime.pose_backup == nullptr) { + return; + } + + BKE_pose_backup_free(ob->runtime.pose_backup); + ob->runtime.pose_backup = nullptr; +} diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 21bcd0ed532..889f154c1b8 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -192,6 +192,14 @@ typedef struct Object_Runtime { */ struct Mesh *object_as_temp_mesh; + /** + * Backup of the object's pose (might be a subset, i.e. not contain all bones). + * + * Created by `BKE_pose_backup_create_on_object()`. This memory is owned by the Object. + * It is freed along with the object, or when `BKE_pose_backup_clear()` is called. + */ + struct PoseBackup *pose_backup; + /** * This is a curve representation of corresponding object. * It created when Python calls `object.to_curve()`. @@ -200,6 +208,7 @@ typedef struct Object_Runtime { /** Runtime evaluated curve-specific data, not stored in the file. */ struct CurveCache *curve_cache; + void *_pad4; unsigned short local_collections_bits; short _pad2[3]; diff --git a/source/blender/makesrna/intern/rna_pose_api.c b/source/blender/makesrna/intern/rna_pose_api.c index c9b7ab6240d..64d044717ce 100644 --- a/source/blender/makesrna/intern/rna_pose_api.c +++ b/source/blender/makesrna/intern/rna_pose_api.c @@ -25,6 +25,7 @@ # include "BKE_animsys.h" # include "BKE_armature.h" # include "BKE_context.h" +# include "BKE_pose_backup.h" # include "DNA_action_types.h" # include "DNA_anim_types.h" @@ -108,6 +109,56 @@ static void rna_Pose_apply_pose_from_action(ID *pose_owner, WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pose_owner); } +static void rna_Pose_blend_pose_from_action(ID *pose_owner, + bContext *C, + bAction *action, + const float blend_factor, + const float evaluation_time) +{ + BLI_assert(GS(pose_owner->name) == ID_OB); + Object *pose_owner_ob = (Object *)pose_owner; + + AnimationEvalContext anim_eval_context = {CTX_data_depsgraph_pointer(C), evaluation_time}; + BKE_pose_apply_action_blend(pose_owner_ob, action, &anim_eval_context, blend_factor); + + /* Do NOT tag with ID_RECALC_ANIMATION, as that would overwrite the just-applied pose. */ + DEG_id_tag_update(pose_owner, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pose_owner); +} + +static void rna_Pose_backup_create(ID *pose_owner, bAction *action) +{ + BLI_assert(GS(pose_owner->name) == ID_OB); + Object *pose_owner_ob = (Object *)pose_owner; + + BKE_pose_backup_create_on_object(pose_owner_ob, action); +} + +static bool rna_Pose_backup_restore(ID *pose_owner, bContext *C) +{ + BLI_assert(GS(pose_owner->name) == ID_OB); + Object *pose_owner_ob = (Object *)pose_owner; + + const bool success = BKE_pose_backup_restore_on_object(pose_owner_ob); + if (!success) { + return false; + } + + /* Do NOT tag with ID_RECALC_ANIMATION, as that would overwrite the just-applied pose. */ + DEG_id_tag_update(pose_owner, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_OBJECT | ND_POSE, pose_owner); + + return true; +} + +static void rna_Pose_backup_clear(ID *pose_owner) +{ + BLI_assert(GS(pose_owner->name) == ID_OB); + Object *pose_owner_ob = (Object *)pose_owner; + + BKE_pose_backup_clear(pose_owner_ob); +} + #else void RNA_api_pose(StructRNA *srna) @@ -121,10 +172,8 @@ void RNA_api_pose(StructRNA *srna) func, "Apply the given action to this pose by evaluating it at a specific time. Only updates the " "pose of selected bones, or all bones if none are selected."); - parm = RNA_def_pointer(func, "action", "Action", "Action", "The Action containing the pose"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); - parm = RNA_def_float(func, "evaluation_time", 0.0f, @@ -134,6 +183,67 @@ void RNA_api_pose(StructRNA *srna) "Time at which the given action is evaluated to obtain the pose", -FLT_MAX, FLT_MAX); + + func = RNA_def_function(srna, "blend_pose_from_action", "rna_Pose_blend_pose_from_action"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_NO_SELF | FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, + "Blend the given action into this pose by evaluating it at a " + "specific time. Only updates the " + "pose of selected bones, or all bones if none are selected."); + parm = RNA_def_pointer(func, "action", "Action", "Action", "The Action containing the pose"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_float(func, + "blend_factor", + 1.0f, + 0.0f, + 1.0f, + "Blend Factor", + "How much the given Action affects the final pose", + 0.0f, + 1.0f); + parm = RNA_def_float(func, + "evaluation_time", + 0.0f, + -FLT_MAX, + FLT_MAX, + "Evaluation Time", + "Time at which the given action is evaluated to obtain the pose", + -FLT_MAX, + FLT_MAX); + + func = RNA_def_function(srna, "backup_create", "rna_Pose_backup_create"); + RNA_def_function_ui_description( + func, + "Create a backup of the current pose. Only those bones that are animated in the Action are " + "backed up. The object owns the backup, and each object can have only one backup at a time. " + "When you no longer need it, it must be freed use `backup_clear()`."); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_NO_SELF); + parm = RNA_def_pointer(func, + "action", + "Action", + "Action", + "An Action with animation data for the bones. Only the animated bones " + "will be included in the backup."); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + + func = RNA_def_function(srna, "backup_restore", "rna_Pose_backup_restore"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_NO_SELF | FUNC_USE_CONTEXT); + RNA_def_function_ui_description(func, + "Restore the previously made pose backup. This can be called " + "multiple times. See `Pose.backup_create()` for more info."); + /* return value */ + parm = RNA_def_boolean( + func, + "success", + false, + "", + "`True` when the backup was restored, `False` if there was no backup to restore."); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "backup_clear", "rna_Pose_backup_clear"); + RNA_def_function_ui_description( + func, "Free a previously made pose backup. See `Pose.backup_create()` for more info."); + RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_NO_SELF); } void RNA_api_pose_channel(StructRNA *srna) From 4ae8c52a951badc30d3868c0984ea022606546c8 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 2 Jan 2023 10:39:55 -0500 Subject: [PATCH 0341/1522] Fix: Set active color attribute copy & paste mistake --- source/blender/makesrna/intern/rna_attribute.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c index 98b3fa8553e..f2afbdcce2b 100644 --- a/source/blender/makesrna/intern/rna_attribute.c +++ b/source/blender/makesrna/intern/rna_attribute.c @@ -712,9 +712,9 @@ static void rna_AttributeGroup_active_color_name_set(PointerRNA *ptr, const char ID *id = ptr->owner_id; if (GS(id->name) == ID_ME) { Mesh *mesh = (Mesh *)id; - MEM_SAFE_FREE(mesh->default_color_attribute); + MEM_SAFE_FREE(mesh->active_color_attribute); if (value[0]) { - mesh->default_color_attribute = BLI_strdup(value); + mesh->active_color_attribute = BLI_strdup(value); } } } From adb4dd911b9183e1fb903e553f75a4a0df2d6717 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 2 Jan 2023 10:49:57 -0500 Subject: [PATCH 0342/1522] Point Cloud: Support set origin and apply scale operators Move some functions for transforming a span of vectors to a header and call them from these functions, just like was done for curves objects recently. Resolves T102027, T102026 Differential Revision: https://developer.blender.org/D16883 --- .../editors/object/object_transform.cc | 83 ++++++++++++++++++- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/object/object_transform.cc b/source/blender/editors/object/object_transform.cc index 672c04d8db6..539260cd27f 100644 --- a/source/blender/editors/object/object_transform.cc +++ b/source/blender/editors/object/object_transform.cc @@ -19,6 +19,7 @@ #include "DNA_mesh_types.h" #include "DNA_meta_types.h" #include "DNA_object_types.h" +#include "DNA_pointcloud_types.h" #include "DNA_scene_types.h" #include "BLI_array.hh" @@ -44,6 +45,7 @@ #include "BKE_mesh.h" #include "BKE_multires.h" #include "BKE_object.h" +#include "BKE_pointcloud.h" #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_tracking.h" @@ -639,6 +641,17 @@ static bool apply_objects_internal_need_single_user(bContext *C) return (ID_REAL_USERS(ob->data) > CTX_DATA_COUNT(C, selected_editable_objects)); } +static void transform_positions(blender::MutableSpan positions, + const blender::float4x4 &matrix) +{ + using namespace blender; + threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) { + for (float3 &position : positions.slice(range)) { + position = matrix * position; + } + }); +} + static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_loc, @@ -647,6 +660,7 @@ static int apply_objects_internal(bContext *C, bool do_props, bool do_single_user) { + using namespace blender; Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); @@ -696,7 +710,8 @@ static int apply_objects_internal(bContext *C, OB_SURF, OB_FONT, OB_GPENCIL, - OB_CURVES)) { + OB_CURVES, + OB_POINTCLOUD)) { ID *obdata = static_cast(ob->data); if (!do_multi_user && ID_REAL_USERS(obdata) > 1) { BKE_reportf(reports, @@ -932,6 +947,14 @@ static int apply_objects_internal(bContext *C, blender::bke::CurvesGeometry::wrap(curves.geometry).transform(mat); blender::bke::CurvesGeometry::wrap(curves.geometry).calculate_bezier_auto_handles(); } + else if (ob->type == OB_POINTCLOUD) { + PointCloud &pointcloud = *static_cast(ob->data); + bke::MutableAttributeAccessor attributes = pointcloud.attributes_for_write(); + bke::SpanAttributeWriter position = attributes.lookup_or_add_for_write_span( + "position", ATTR_DOMAIN_POINT); + transform_positions(position.span, float4x4(mat)); + position.finish(); + } else if (ob->type == OB_CAMERA) { MovieClip *clip = BKE_object_movieclip_get(scene, ob, false); @@ -1230,8 +1253,29 @@ enum { ORIGIN_TO_CENTER_OF_MASS_VOLUME, }; +static float3 calculate_mean(const blender::Span values) +{ + if (values.is_empty()) { + return float3(0); + } + /* TODO: Use a method that avoids overflow. */ + return std::accumulate(values.begin(), values.end(), float3(0)) / values.size(); +} + +static void translate_positions(blender::MutableSpan positions, + const blender::float3 &translation) +{ + using namespace blender; + threading::parallel_for(positions.index_range(), 2048, [&](const IndexRange range) { + for (float3 &position : positions.slice(range)) { + position += translation; + } + }); +} + static int object_origin_set_exec(bContext *C, wmOperator *op) { + using namespace blender; Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Object *obact = CTX_data_active_object(C); @@ -1653,9 +1697,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) } } else if (around == V3D_AROUND_CENTER_MEDIAN) { - Span positions = curves.positions(); - cent = std::accumulate(positions.begin(), positions.end(), float3(0)) / - curves.points_num(); + cent = calculate_mean(curves.positions()); } tot_change++; @@ -1663,6 +1705,39 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) curves_id.id.tag |= LIB_TAG_DOIT; do_inverse_offset = true; } + else if (ob->type == OB_POINTCLOUD) { + PointCloud &pointcloud = *static_cast(ob->data); + bke::MutableAttributeAccessor attributes = pointcloud.attributes_for_write(); + bke::SpanAttributeWriter positions = attributes.lookup_or_add_for_write_span( + "position", ATTR_DOMAIN_POINT); + if (ELEM(centermode, ORIGIN_TO_CENTER_OF_MASS_SURFACE, ORIGIN_TO_CENTER_OF_MASS_VOLUME) || + !ELEM(around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEDIAN)) { + BKE_report(op->reports, + RPT_WARNING, + "Point cloud object does not support this set origin operation"); + continue; + } + + if (centermode == ORIGIN_TO_CURSOR) { + /* Done. */ + } + else if (around == V3D_AROUND_CENTER_BOUNDS) { + float3 min(std::numeric_limits::max()); + float3 max(-std::numeric_limits::max()); + if (pointcloud.bounds_min_max(min, max)) { + cent = math::midpoint(min, max); + } + } + else if (around == V3D_AROUND_CENTER_MEDIAN) { + cent = calculate_mean(positions.span); + } + + tot_change++; + translate_positions(positions.span, -cent); + positions.finish(); + pointcloud.id.tag |= LIB_TAG_DOIT; + do_inverse_offset = true; + } /* offset other selected objects */ if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) { From 0efb79fb749ec1967a46b9fcec755aad9ee2d403 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 2 Jan 2023 11:16:37 -0500 Subject: [PATCH 0343/1522] Geometry Nodes: Multithread transforming instances and point clouds Add multithreading when transforming and translating instances and point clouds in the Transform Geometry node. --- .../nodes/node_geo_transform_geometry.cc | 42 +++++++++++++------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc index 0f2c9a02be4..aa674e760c9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc @@ -34,6 +34,24 @@ static bool use_translate(const float3 rotation, const float3 scale) return true; } +static void translate_positions(MutableSpan positions, const float3 &translation) +{ + threading::parallel_for(positions.index_range(), 2048, [&](const IndexRange range) { + for (float3 &position : positions.slice(range)) { + position += translation; + } + }); +} + +static void transform_positions(MutableSpan positions, const float4x4 &matrix) +{ + threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) { + for (float3 &position : positions.slice(range)) { + position = matrix * position; + } + }); +} + static void translate_mesh(Mesh &mesh, const float3 translation) { if (!math::is_zero(translation)) { @@ -51,9 +69,7 @@ static void translate_pointcloud(PointCloud &pointcloud, const float3 translatio MutableAttributeAccessor attributes = pointcloud.attributes_for_write(); SpanAttributeWriter position = attributes.lookup_or_add_for_write_span( "position", ATTR_DOMAIN_POINT); - for (const int i : position.span.index_range()) { - position.span[i] += translation; - } + translate_positions(position.span, translation); position.finish(); } @@ -62,26 +78,28 @@ static void transform_pointcloud(PointCloud &pointcloud, const float4x4 &transfo MutableAttributeAccessor attributes = pointcloud.attributes_for_write(); SpanAttributeWriter position = attributes.lookup_or_add_for_write_span( "position", ATTR_DOMAIN_POINT); - for (const int i : position.span.index_range()) { - position.span[i] = transform * position.span[i]; - } + transform_positions(position.span, transform); position.finish(); } static void translate_instances(bke::Instances &instances, const float3 translation) { MutableSpan transforms = instances.transforms(); - for (float4x4 &transform : transforms) { - add_v3_v3(transform.ptr()[3], translation); - } + threading::parallel_for(transforms.index_range(), 1024, [&](const IndexRange range) { + for (float4x4 &instance_transform : transforms.slice(range)) { + add_v3_v3(instance_transform.ptr()[3], translation); + } + }); } static void transform_instances(bke::Instances &instances, const float4x4 &transform) { MutableSpan transforms = instances.transforms(); - for (float4x4 &instance_transform : transforms) { - instance_transform = transform * instance_transform; - } + threading::parallel_for(transforms.index_range(), 1024, [&](const IndexRange range) { + for (float4x4 &instance_transform : transforms.slice(range)) { + instance_transform = transform * instance_transform; + } + }); } static void transform_volume(GeoNodeExecParams ¶ms, From ebec9eb75ead22edd4fe66157241f825bb3dd1cd Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Tue, 27 Dec 2022 17:31:37 +0200 Subject: [PATCH 0344/1522] Fix T103118: depsgraph issues for bbone property drivers on non-bbones. The BONE_SEGMENTS operation node is only created if the bone is actually a B-Bone. One location in the code wasn't checking that before trying to create a relation. --- .../depsgraph/intern/builder/deg_builder_relations.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 53d56c3db36..0c5dfdf5ced 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -1675,8 +1675,11 @@ void DepsgraphRelationBuilder::build_driver_data(ID *id, FCurve *fcu) continue; } - OperationCode target_op = driver_targets_bbone ? OperationCode::BONE_SEGMENTS : - OperationCode::BONE_LOCAL; + OperationCode target_op = OperationCode::BONE_LOCAL; + if (driver_targets_bbone) { + target_op = check_pchan_has_bbone_segments(object, pchan) ? OperationCode::BONE_SEGMENTS : + OperationCode::BONE_DONE; + } OperationKey bone_key(&object->id, NodeType::BONE, pchan->name, target_op); add_relation(driver_key, bone_key, "Arm Bone -> Driver -> Bone"); } From 90f194616b51d3c5df32cb947de83616aa3dcbde Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Mon, 26 Dec 2022 19:39:41 +0200 Subject: [PATCH 0345/1522] Depsgraph: clear update flags when skipping through no-op nodes. As an optimization, dependency graph evaluation skips through no-op nodes at the scheduling stage. However, that leaves update flags enabled on the node, and the most problematic one is the USER_MODIFIED flag, which get flushed to children every time the no-op node is tagged. This in turn can cause simulation caches downstream to be permanently stuck in an outdated state until the depsgraph is rebuilt and the stuck flag cleared out. Differential Revision: https://developer.blender.org/D16868 --- source/blender/depsgraph/intern/eval/deg_eval.cc | 7 +++++-- source/blender/depsgraph/intern/node/deg_node_operation.h | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 5ca32d00ba5..3bdc33b8d01 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -105,8 +105,7 @@ void evaluate_node(const DepsgraphEvalState *state, OperationNode *operation_nod * times. * This is a thread-safe modification as the node's flags are only read for a non-scheduled nodes * and this node has been scheduled. */ - operation_node->flag &= ~(DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE | - DEPSOP_FLAG_USER_MODIFIED); + operation_node->flag &= ~DEPSOP_FLAG_CLEAR_ON_EVAL; } void deg_task_run_func(TaskPool *pool, void *taskdata) @@ -270,6 +269,10 @@ void schedule_node(DepsgraphEvalState *state, bool is_scheduled = atomic_fetch_and_or_uint8((uint8_t *)&node->scheduled, uint8_t(true)); if (!is_scheduled) { if (node->is_noop()) { + /* Clear flags to avoid affecting subsequent update propagation. + * For normal nodes these are cleared when it is evaluated. */ + node->flag &= ~DEPSOP_FLAG_CLEAR_ON_EVAL; + /* skip NOOP node, schedule children right away */ schedule_children(state, node, schedule_fn); } diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h index 1bc4b36141e..df4a157d486 100644 --- a/source/blender/depsgraph/intern/node/deg_node_operation.h +++ b/source/blender/depsgraph/intern/node/deg_node_operation.h @@ -224,6 +224,10 @@ enum OperationFlag { /* Set of flags which gets flushed along the relations. */ DEPSOP_FLAG_FLUSH = (DEPSOP_FLAG_USER_MODIFIED), + + /* Set of flags which get cleared upon evaluation. */ + DEPSOP_FLAG_CLEAR_ON_EVAL = (DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE | + DEPSOP_FLAG_USER_MODIFIED), }; /* Atomic Operation - Base type for all operations */ From c74acb62b9a1c8bda0c305ae0177238c3defd1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 2 Jan 2023 17:49:45 +0100 Subject: [PATCH 0346/1522] Cleanup: remove outdated TODO comment --- source/blender/editors/armature/pose_lib_2.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/editors/armature/pose_lib_2.c b/source/blender/editors/armature/pose_lib_2.c index d11486eb405..eef01d9847d 100644 --- a/source/blender/editors/armature/pose_lib_2.c +++ b/source/blender/editors/armature/pose_lib_2.c @@ -224,8 +224,6 @@ static int poselib_blend_handle_event(bContext *UNUSED(C), wmOperator *op, const pbd->state = pbd->state == POSE_BLEND_BLENDING ? POSE_BLEND_ORIGINAL : POSE_BLEND_BLENDING; pbd->needs_redraw = true; break; - - /* TODO(Sybren): use better UI for slider. */ } return OPERATOR_RUNNING_MODAL; From 6eb1c98b15bb7ea6cf184b08617f24c7afb91b6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 2 Jan 2023 18:02:36 +0100 Subject: [PATCH 0347/1522] Pose Library: press F while blending to flip the pose While blending poses from the pose library, press {key F} to flip the pose. Since rBc164c5d86655 removed the "Flip Pose" checkbox, there was no more way to blend poses flipped. Note that this is a bit of a stop-gap measure. The goal is to have a bidirectional blend slider, where dragging to the left flips the pose, and dragging to the right blends it normally. --- source/blender/editors/armature/pose_lib_2.c | 30 ++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/armature/pose_lib_2.c b/source/blender/editors/armature/pose_lib_2.c index eef01d9847d..294846bc41c 100644 --- a/source/blender/editors/armature/pose_lib_2.c +++ b/source/blender/editors/armature/pose_lib_2.c @@ -83,6 +83,8 @@ typedef struct PoseBlendData { char headerstr[UI_MAX_DRAW_STR]; } PoseBlendData; +static void poselib_blend_flip_pose(bContext *C, wmOperator *op); + /* Makes a copy of the current pose for restoration purposes - doesn't do constraints currently */ static void poselib_backup_posecopy(PoseBlendData *pbd) { @@ -178,7 +180,7 @@ static void poselib_blend_set_factor(PoseBlendData *pbd, const float new_factor) } /* Return operator return value. */ -static int poselib_blend_handle_event(bContext *UNUSED(C), wmOperator *op, const wmEvent *event) +static int poselib_blend_handle_event(bContext *C, wmOperator *op, const wmEvent *event) { PoseBlendData *pbd = op->customdata; @@ -224,6 +226,10 @@ static int poselib_blend_handle_event(bContext *UNUSED(C), wmOperator *op, const pbd->state = pbd->state == POSE_BLEND_BLENDING ? POSE_BLEND_ORIGINAL : POSE_BLEND_BLENDING; pbd->needs_redraw = true; break; + + case EVT_FKEY: + poselib_blend_flip_pose(C, op); + break; } return OPERATOR_RUNNING_MODAL; @@ -274,6 +280,22 @@ static bAction *flip_pose(bContext *C, Object *ob, bAction *action) return action_copy; } +/* Flip the target pose the interactive blend operator is currently using. */ +static void poselib_blend_flip_pose(bContext *C, wmOperator *op) +{ + PoseBlendData *pbd = op->customdata; + bAction *old_action = pbd->act; + bAction *new_action = flip_pose(C, pbd->ob, old_action); + + if (pbd->free_action) { + BKE_id_free(NULL, old_action); + } + + pbd->free_action = true; + pbd->act = new_action; + pbd->needs_redraw = true; +} + /* Return true on success, false if the context isn't suitable. */ static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent *event) { @@ -459,7 +481,11 @@ static int poselib_blend_modal(bContext *C, wmOperator *op, const wmEvent *event strcpy(tab_string, TIP_("[Tab] - Show blended pose")); } - BLI_snprintf(status_string, sizeof(status_string), "%s | %s", tab_string, slider_string); + BLI_snprintf(status_string, + sizeof(status_string), + "[F] - Flip pose | %s | %s", + tab_string, + slider_string); ED_workspace_status_text(C, status_string); poselib_blend_apply(C, op); From b386932dbbb2376997428eaac95204d697369acf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 2 Jan 2023 18:07:22 +0100 Subject: [PATCH 0348/1522] Cleanup: clarify overshoot options of `tSlider` Just some extra comments, no functional changes. --- source/blender/editors/util/ed_draw.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/util/ed_draw.c b/source/blender/editors/util/ed_draw.c index 62eedefe394..4c376363d85 100644 --- a/source/blender/editors/util/ed_draw.c +++ b/source/blender/editors/util/ed_draw.c @@ -75,10 +75,13 @@ typedef struct tSlider { /** Last mouse cursor position used for mouse movement delta calculation. */ float last_cursor[2]; - /** Enable range beyond 0-100%. */ + /** Enable range beyond 0-100%. + * This is set by the code that uses the slider, as not all operations support + * extrapolation. */ bool allow_overshoot; - /** Allow overshoot or clamp between 0% and 100%. */ + /** Allow overshoot or clamp between 0% and 100%. + * This is set by the artist while using the slider. */ bool overshoot; /** Move factor in 10% steps. */ From 9144b110ee7081d055a64f74d753aec4c9e737e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Mon, 2 Jan 2023 18:29:35 +0100 Subject: [PATCH 0349/1522] Pose Library: recreate pose backup when flipping pose During pose blending, when flipping the pose with {key F}, the pose backup needs to be recreated. Without this, the blending wouldn't be done properly. F-for-flipping was introduced in rB6eb1c98b15bb7ea6cf184b08617f24 --- source/blender/editors/armature/pose_lib_2.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/blender/editors/armature/pose_lib_2.c b/source/blender/editors/armature/pose_lib_2.c index 294846bc41c..8167ac563f6 100644 --- a/source/blender/editors/armature/pose_lib_2.c +++ b/source/blender/editors/armature/pose_lib_2.c @@ -287,6 +287,11 @@ static void poselib_blend_flip_pose(bContext *C, wmOperator *op) bAction *old_action = pbd->act; bAction *new_action = flip_pose(C, pbd->ob, old_action); + /* Before flipping over to the other side, this side needs to be restored. */ + BKE_pose_backup_restore(pbd->pose_backup); + BKE_pose_backup_free(pbd->pose_backup); + pbd->pose_backup = NULL; + if (pbd->free_action) { BKE_id_free(NULL, old_action); } @@ -294,6 +299,9 @@ static void poselib_blend_flip_pose(bContext *C, wmOperator *op) pbd->free_action = true; pbd->act = new_action; pbd->needs_redraw = true; + + /* Refresh the pose backup to use the flipped bones. */ + poselib_backup_posecopy(pbd); } /* Return true on success, false if the context isn't suitable. */ From 0bc0e3f9f7c90e290ddf254407d56ad1655365d3 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 2 Jan 2023 18:33:48 +0100 Subject: [PATCH 0350/1522] Fix: geometry nodes crashes with large trees This was an oversight in rBdba2d828462ae22de5. The evaluator uses multiple threads to initialize node states but it is still in single threaded mode. `get_main_or_local_allocator` did not return the right allocator in this case. --- source/blender/functions/intern/lazy_function_graph_executor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/functions/intern/lazy_function_graph_executor.cc b/source/blender/functions/intern/lazy_function_graph_executor.cc index 83b14952829..b9cf3a82bcb 100644 --- a/source/blender/functions/intern/lazy_function_graph_executor.cc +++ b/source/blender/functions/intern/lazy_function_graph_executor.cc @@ -355,7 +355,7 @@ class Executor { this->ensure_thread_locals(); /* Construct all node states in parallel. */ threading::parallel_for(nodes.index_range(), 256, [&](const IndexRange range) { - LinearAllocator<> &allocator = this->get_main_or_local_allocator(); + LinearAllocator<> &allocator = thread_locals_->local().allocator; construct_node_range(range, allocator); }); } From 13ad68d1000f1576dd3835c52fe011ae59364f4a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 2 Jan 2023 16:45:49 -0500 Subject: [PATCH 0351/1522] Node Editor: Avoid allocations for socket tooltip button arguments Small memory allocations are a bottleneck when drawing large node trees. Avoid them by passing the socket index in the whole tree and getting the tree from the context rather than allocating structs for the tree, node, and socket. The performance improvement will be a few percent at most. --- .../blender/editors/space_node/node_draw.cc | 108 +++++++++--------- .../blender/editors/space_node/node_intern.hh | 5 +- .../editors/space_node/node_templates.cc | 2 +- 3 files changed, 57 insertions(+), 58 deletions(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index cf71d5c05e0..4850ad5fe3d 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -182,11 +182,9 @@ void ED_node_tag_update_id(ID *id) namespace blender::ed::space_node { -static void node_socket_add_tooltip_in_node_editor(TreeDrawContext * /*tree_draw_ctx*/, - const bNodeTree *ntree, - const bNode *node, - const bNodeSocket *sock, - uiLayout *layout); +static void node_socket_add_tooltip_in_node_editor(const bNodeTree &ntree, + const bNodeSocket &sock, + uiLayout &layout); /** Return true when \a a should be behind \a b and false otherwise. */ static bool compare_node_depth(const bNode *a, const bNode *b) @@ -318,7 +316,7 @@ float2 node_from_view(const bNode &node, const float2 &co) * Based on settings and sockets in node, set drawing rect info. */ static void node_update_basis(const bContext &C, - TreeDrawContext &tree_draw_ctx, + TreeDrawContext & /*tree_draw_ctx*/, bNodeTree &ntree, bNode &node, uiBlock &block) @@ -382,7 +380,7 @@ static void node_update_basis(const bContext &C, const char *socket_label = nodeSocketLabel(socket); socket->typeinfo->draw((bContext *)&C, row, &sockptr, &nodeptr, IFACE_(socket_label)); - node_socket_add_tooltip_in_node_editor(&tree_draw_ctx, &ntree, &node, socket, row); + node_socket_add_tooltip_in_node_editor(ntree, *socket, *row); UI_block_align_end(&block); UI_block_layout_resolve(&block, nullptr, &buty); @@ -515,7 +513,7 @@ static void node_update_basis(const bContext &C, const char *socket_label = nodeSocketLabel(socket); socket->typeinfo->draw((bContext *)&C, row, &sockptr, &nodeptr, IFACE_(socket_label)); - node_socket_add_tooltip_in_node_editor(&tree_draw_ctx, &ntree, &node, socket, row); + node_socket_add_tooltip_in_node_editor(ntree, *socket, *row); UI_block_align_end(&block); UI_block_layout_resolve(&block, nullptr, &buty); @@ -789,12 +787,6 @@ void node_socket_color_get(const bContext &C, sock.typeinfo->draw_color((bContext *)&C, &ptr, &node_ptr, r_color); } -struct SocketTooltipData { - const bNodeTree *ntree; - const bNode *node; - const bNodeSocket *socket; -}; - static void create_inspection_string_for_generic_value(const bNodeSocket &socket, const GPointer value, std::stringstream &ss) @@ -1084,35 +1076,33 @@ static bool node_socket_has_tooltip(const bNodeTree &ntree, const bNodeSocket &s return false; } -static char *node_socket_get_tooltip(const bContext *C, - const bNodeTree *ntree, - const bNode * /*node*/, - const bNodeSocket *socket) +static char *node_socket_get_tooltip(const SpaceNode *snode, + const bNodeTree &ntree, + const bNodeSocket &socket) { - SpaceNode *snode = CTX_wm_space_node(C); TreeDrawContext tree_draw_ctx; if (snode != nullptr) { - if (ntree->type == NTREE_GEOMETRY) { + if (ntree.type == NTREE_GEOMETRY) { tree_draw_ctx.geo_tree_log = geo_log::GeoModifierLog::get_tree_log_for_node_editor(*snode); } } std::stringstream output; - if (socket->runtime->declaration != nullptr) { - const blender::nodes::SocketDeclaration &socket_decl = *socket->runtime->declaration; + if (socket.runtime->declaration != nullptr) { + const blender::nodes::SocketDeclaration &socket_decl = *socket.runtime->declaration; blender::StringRef description = socket_decl.description; if (!description.is_empty()) { output << TIP_(description.data()); } } - if (ntree->type == NTREE_GEOMETRY && tree_draw_ctx.geo_tree_log != nullptr) { + if (ntree.type == NTREE_GEOMETRY && tree_draw_ctx.geo_tree_log != nullptr) { if (!output.str().empty()) { output << ".\n\n"; } std::optional socket_inspection_str = create_socket_inspection_string( - tree_draw_ctx, *socket); + tree_draw_ctx, socket); if (socket_inspection_str.has_value()) { output << *socket_inspection_str; } @@ -1124,46 +1114,60 @@ static char *node_socket_get_tooltip(const bContext *C, } if (output.str().empty()) { - output << nodeSocketLabel(socket); + output << nodeSocketLabel(&socket); } return BLI_strdup(output.str().c_str()); } -static void node_socket_add_tooltip_in_node_editor(TreeDrawContext * /*tree_draw_ctx*/, - const bNodeTree *ntree, - const bNode *node, - const bNodeSocket *sock, - uiLayout *layout) +static void node_socket_add_tooltip_in_node_editor(const bNodeTree &ntree, + const bNodeSocket &sock, + uiLayout &layout) { - if (!node_socket_has_tooltip(*ntree, *sock)) { + if (!node_socket_has_tooltip(ntree, sock)) { + return; + } + uiLayoutSetTooltipFunc( + &layout, + [](bContext *C, void *argN, const char * /*tip*/) { + const SpaceNode &snode = *CTX_wm_space_node(C); + const bNodeTree &ntree = *snode.edittree; + const int index_in_tree = POINTER_AS_INT(argN); + ntree.ensure_topology_cache(); + return node_socket_get_tooltip(&snode, ntree, *ntree.all_sockets()[index_in_tree]); + }, + POINTER_FROM_INT(sock.index_in_tree()), + nullptr, + nullptr); +} + +void node_socket_add_tooltip(const bNodeTree &ntree, const bNodeSocket &sock, uiLayout &layout) +{ + if (!node_socket_has_tooltip(ntree, sock)) { return; } + struct SocketTooltipData { + const bNodeTree *ntree; + const bNodeSocket *socket; + }; + SocketTooltipData *data = MEM_cnew(__func__); - data->ntree = ntree; - data->node = node; - data->socket = sock; + data->ntree = &ntree; + data->socket = &sock; uiLayoutSetTooltipFunc( - layout, + &layout, [](bContext *C, void *argN, const char * /*tip*/) { SocketTooltipData *data = static_cast(argN); - return node_socket_get_tooltip(C, data->ntree, data->node, data->socket); + const SpaceNode *snode = CTX_wm_space_node(C); + return node_socket_get_tooltip(snode, *data->ntree, *data->socket); }, data, MEM_dupallocN, MEM_freeN); } -void node_socket_add_tooltip(const bNodeTree &ntree, - const bNode &node, - const bNodeSocket &sock, - uiLayout &layout) -{ - node_socket_add_tooltip_in_node_editor(nullptr, &ntree, &node, &sock, &layout); -} - static void node_socket_draw_nested(const bContext &C, bNodeTree &ntree, PointerRNA &node_ptr, @@ -1219,19 +1223,17 @@ static void node_socket_draw_nested(const bContext &C, 0, nullptr); - SocketTooltipData *data = MEM_new(__func__); - data->ntree = &ntree; - data->node = static_cast(node_ptr.data); - data->socket = &sock; - UI_but_func_tooltip_set( but, [](bContext *C, void *argN, const char * /*tip*/) { - SocketTooltipData *data = (SocketTooltipData *)argN; - return node_socket_get_tooltip(C, data->ntree, data->node, data->socket); + const SpaceNode &snode = *CTX_wm_space_node(C); + const bNodeTree &ntree = *snode.edittree; + const int index_in_tree = POINTER_AS_INT(argN); + ntree.ensure_topology_cache(); + return node_socket_get_tooltip(&snode, ntree, *ntree.all_sockets()[index_in_tree]); }, - data, - MEM_freeN); + POINTER_FROM_INT(sock.index_in_tree()), + nullptr); /* Disable the button so that clicks on it are ignored the link operator still works. */ UI_but_flag_enable(but, UI_BUT_DISABLED); UI_block_emboss_set(&block, old_emboss); diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index 65174edbdbe..5e2fcfeb87c 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -155,10 +155,7 @@ void node_socket_color_get(const bContext &C, void node_draw_space(const bContext &C, ARegion ®ion); -void node_socket_add_tooltip(const bNodeTree &ntree, - const bNode &node, - const bNodeSocket &sock, - uiLayout &layout); +void node_socket_add_tooltip(const bNodeTree &ntree, const bNodeSocket &sock, uiLayout &layout); /** * Sort nodes by selection: unselected nodes first, then selected, diff --git a/source/blender/editors/space_node/node_templates.cc b/source/blender/editors/space_node/node_templates.cc index 75a7f5f0dd7..cb69800e515 100644 --- a/source/blender/editors/space_node/node_templates.cc +++ b/source/blender/editors/space_node/node_templates.cc @@ -897,7 +897,7 @@ static void ui_node_draw_input( uiItemDecoratorR(split_wrapper.decorate_column, nullptr, nullptr, 0); } - node_socket_add_tooltip(ntree, node, input, *row); + node_socket_add_tooltip(ntree, input, *row); /* clear */ node.flag &= ~NODE_TEST; From e550d8c8fda94cf5ca2ef77f3083d16b9d5d0843 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 2 Jan 2023 17:37:26 -0500 Subject: [PATCH 0352/1522] Cleanup: Use const variables in node tree drawing --- .../blender/editors/space_node/node_draw.cc | 67 ++++++++++++------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 4850ad5fe3d..cf8a8a1e40a 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -271,7 +271,7 @@ void node_sort(bNodeTree &ntree) } } -static Array node_uiblocks_init(const bContext &C, Span nodes) +static Array node_uiblocks_init(const bContext &C, const Span nodes) { Array blocks(nodes.size()); /* Add node uiBlocks in drawing order - prevents events going to overlapping nodes. */ @@ -316,7 +316,7 @@ float2 node_from_view(const bNode &node, const float2 &co) * Based on settings and sockets in node, set drawing rect info. */ static void node_update_basis(const bContext &C, - TreeDrawContext & /*tree_draw_ctx*/, + const TreeDrawContext & /*tree_draw_ctx*/, bNodeTree &ntree, bNode &node, uiBlock &block) @@ -782,7 +782,8 @@ void node_socket_color_get(const bContext &C, { PointerRNA ptr; BLI_assert(RNA_struct_is_a(node_ptr.type, &RNA_Node)); - RNA_pointer_create((ID *)&ntree, &RNA_NodeSocket, &const_cast(sock), &ptr); + RNA_pointer_create( + &const_cast(ntree.id), &RNA_NodeSocket, &const_cast(sock), &ptr); sock.typeinfo->draw_color((bContext *)&C, &ptr, &node_ptr, r_color); } @@ -1169,10 +1170,10 @@ void node_socket_add_tooltip(const bNodeTree &ntree, const bNodeSocket &sock, ui } static void node_socket_draw_nested(const bContext &C, - bNodeTree &ntree, + const bNodeTree &ntree, PointerRNA &node_ptr, uiBlock &block, - bNodeSocket &sock, + const bNodeSocket &sock, const uint pos_id, const uint col_id, const uint shape_id, @@ -1367,11 +1368,13 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv) /* Common handle function for operator buttons that need to select the node first. */ static void node_toggle_button_cb(bContext *C, void *node_argv, void *op_argv) { - bNode *node = (bNode *)node_argv; + SpaceNode &snode = *CTX_wm_space_node(C); + bNodeTree &node_tree = *snode.edittree; + bNode &node = *node_tree.node_by_id(POINTER_AS_INT(node_argv)); const char *opname = (const char *)op_argv; /* Select & activate only the button's node. */ - node_select_single(*C, *node); + node_select_single(*C, node); WM_operator_name_call(C, opname, WM_OP_INVOKE_DEFAULT, nullptr, nullptr); } @@ -1388,8 +1391,8 @@ static void node_draw_shadow(const SpaceNode &snode, static void node_draw_sockets(const View2D &v2d, const bContext &C, - bNodeTree &ntree, - bNode &node, + const bNodeTree &ntree, + const bNode &node, uiBlock &block, const bool draw_outputs, const bool select_all) @@ -1402,7 +1405,8 @@ static void node_draw_sockets(const View2D &v2d, } PointerRNA node_ptr; - RNA_pointer_create((ID *)&ntree, &RNA_Node, &node, &node_ptr); + RNA_pointer_create( + &const_cast(ntree.id), &RNA_Node, &const_cast(node), &node_ptr); bool selected = false; @@ -1659,7 +1663,7 @@ static char *node_errors_tooltip_fn(bContext * /*C*/, void *argN, const char * / #define NODE_HEADER_ICON_SIZE (0.8f * U.widget_unit) -static void node_add_unsupported_compositor_operation_error_message_button(bNode &node, +static void node_add_unsupported_compositor_operation_error_message_button(const bNode &node, uiBlock &block, const rctf &rect, float &icon_offset) @@ -1683,8 +1687,8 @@ static void node_add_unsupported_compositor_operation_error_message_button(bNode UI_block_emboss_set(&block, UI_EMBOSS); } -static void node_add_error_message_button(TreeDrawContext &tree_draw_ctx, - bNode &node, +static void node_add_error_message_button(const TreeDrawContext &tree_draw_ctx, + const bNode &node, uiBlock &block, const rctf &rect, float &icon_offset) @@ -1733,7 +1737,7 @@ static void node_add_error_message_button(TreeDrawContext &tree_draw_ctx, } static std::optional node_get_execution_time( - TreeDrawContext &tree_draw_ctx, const bNodeTree &ntree, const bNode &node) + const TreeDrawContext &tree_draw_ctx, const bNodeTree &ntree, const bNode &node) { const geo_log::GeoTreeLog *tree_log = tree_draw_ctx.geo_tree_log; if (tree_log == nullptr) { @@ -2092,7 +2096,7 @@ static void node_draw_basis(const bContext &C, const View2D &v2d, const SpaceNode &snode, bNodeTree &ntree, - bNode &node, + const bNode &node, uiBlock &block, bNodeInstanceKey key) { @@ -2159,7 +2163,10 @@ static void node_draw_basis(const bContext &C, 0, 0, ""); - UI_but_func_set(but, node_toggle_button_cb, &node, (void *)"NODE_OT_preview_toggle"); + UI_but_func_set(but, + node_toggle_button_cb, + POINTER_FROM_INT(node.identifier), + (void *)"NODE_OT_preview_toggle"); /* XXX this does not work when node is activated and the operator called right afterwards, * since active ID is not updated yet (needs to process the notifier). * This can only work as visual indicator! */ @@ -2185,7 +2192,10 @@ static void node_draw_basis(const bContext &C, 0, 0, ""); - UI_but_func_set(but, node_toggle_button_cb, &node, (void *)"NODE_OT_group_edit"); + UI_but_func_set(but, + node_toggle_button_cb, + POINTER_FROM_INT(node.identifier), + (void *)"NODE_OT_group_edit"); if (node.id) { UI_but_icon_indicator_number_set(but, ID_REAL_USERS(node.id)); } @@ -2230,7 +2240,8 @@ static void node_draw_basis(const bContext &C, ""); /* Selection implicitly activates the node. */ const char *operator_idname = is_active ? "NODE_OT_deactivate_viewer" : "NODE_OT_select"; - UI_but_func_set(but, node_toggle_button_cb, &node, (void *)operator_idname); + UI_but_func_set( + but, node_toggle_button_cb, POINTER_FROM_INT(node.identifier), (void *)operator_idname); UI_block_emboss_set(&block, UI_EMBOSS); } @@ -2264,7 +2275,10 @@ static void node_draw_basis(const bContext &C, 0.0f, ""); - UI_but_func_set(but, node_toggle_button_cb, &node, (void *)"NODE_OT_hide_toggle"); + UI_but_func_set(but, + node_toggle_button_cb, + POINTER_FROM_INT(node.identifier), + (void *)"NODE_OT_hide_toggle"); UI_block_emboss_set(&block, UI_EMBOSS); } @@ -2492,7 +2506,10 @@ static void node_draw_hidden(const bContext &C, 0.0f, ""); - UI_but_func_set(but, node_toggle_button_cb, &node, (void *)"NODE_OT_hide_toggle"); + UI_but_func_set(but, + node_toggle_button_cb, + POINTER_FROM_INT(node.identifier), + (void *)"NODE_OT_hide_toggle"); UI_block_emboss_set(&block, UI_EMBOSS); } @@ -3027,14 +3044,14 @@ static void node_draw_nodetree(const bContext &C, GPU_blend(GPU_BLEND_ALPHA); nodelink_batch_start(snode); - LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { + LISTBASE_FOREACH (const bNodeLink *, link, &ntree.links) { if (!nodeLinkIsHidden(link) && !nodeLinkIsSelected(link)) { node_draw_link(C, region.v2d, snode, *link, false); } } /* Draw selected node links after the unselected ones, so they are shown on top. */ - LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { + LISTBASE_FOREACH (const bNodeLink *, link, &ntree.links) { if (!nodeLinkIsHidden(link) && nodeLinkIsSelected(link)) { node_draw_link(C, region.v2d, snode, *link, true); } @@ -3112,9 +3129,9 @@ static bool realtime_compositor_is_in_use(const bContext &context) } const Main *main = CTX_data_main(&context); - LISTBASE_FOREACH (bScreen *, screen, &main->screens) { - LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { - LISTBASE_FOREACH (SpaceLink *, space, &area->spacedata) { + LISTBASE_FOREACH (const bScreen *, screen, &main->screens) { + LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) { + LISTBASE_FOREACH (const SpaceLink *, space, &area->spacedata) { if (space->spacetype != SPACE_VIEW3D) { continue; } From 0c30873d822f44d40d7ebb5aa2bd667fe9c96beb Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 2 Jan 2023 17:55:32 -0500 Subject: [PATCH 0353/1522] Node Editor: Use the topology cache more when drawing node tree Partly a cleanup, but also iterating over spans can be faster than linked lists. Also rewrite the multi-input socket link counting to avoid the need for a temporary map. Overall, on my setup the changes save about 5% (3ms) when drawing a large node tree (the mouse house file). --- source/blender/blenkernel/BKE_node_runtime.hh | 5 +- .../blender/editors/space_node/node_draw.cc | 69 ++++++++----------- 2 files changed, 32 insertions(+), 42 deletions(-) diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index cedb3a6fd8c..a577630678f 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -169,7 +169,10 @@ class bNodeSocketRuntime : NonCopyable, NonMovable { float locx = 0; float locy = 0; - /* Runtime-only cache of the number of input links, for multi-input sockets. */ + /** + * Runtime-only cache of the number of input links, for multi-input sockets, + * including dragged node links that aren't actually in the tree. + */ short total_inputs = 0; /** Only valid when #topology_cache_is_dirty is false. */ diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index cf8a8a1e40a..fdc82307ce0 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -348,7 +348,7 @@ static void node_update_basis(const bContext &C, bool add_output_space = false; int buty; - LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) { + for (bNodeSocket *socket : node.output_sockets()) { if (!socket->is_visible()) { continue; } @@ -471,7 +471,7 @@ static void node_update_basis(const bContext &C, } /* Input sockets. */ - LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) { + for (bNodeSocket *socket : node.input_sockets()) { if (!socket->is_visible()) { continue; } @@ -564,12 +564,12 @@ static void node_update_hidden(bNode &node, uiBlock &block) loc.y = round(loc.y); /* Calculate minimal radius. */ - LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) { + for (const bNodeSocket *socket : node.input_sockets()) { if (socket->is_visible()) { totin++; } } - LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) { + for (const bNodeSocket *socket : node.output_sockets()) { if (socket->is_visible()) { totout++; } @@ -590,7 +590,7 @@ static void node_update_hidden(bNode &node, uiBlock &block) float rad = float(M_PI) / (1.0f + float(totout)); float drad = rad; - LISTBASE_FOREACH (bNodeSocket *, socket, &node.outputs) { + for (bNodeSocket *socket : node.output_sockets()) { if (socket->is_visible()) { /* Round the socket location to stop it from jiggling. */ socket->runtime->locx = round(node.runtime->totr.xmax - hiddenrad + sinf(rad) * hiddenrad); @@ -602,7 +602,7 @@ static void node_update_hidden(bNode &node, uiBlock &block) /* Input sockets. */ rad = drad = -float(M_PI) / (1.0f + float(totin)); - LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) { + for (bNodeSocket *socket : node.input_sockets()) { if (socket->is_visible()) { /* Round the socket location to stop it from jiggling. */ socket->runtime->locx = round(node.runtime->totr.xmin + hiddenrad + sinf(rad) * hiddenrad); @@ -1397,10 +1397,7 @@ static void node_draw_sockets(const View2D &v2d, const bool draw_outputs, const bool select_all) { - const uint total_input_len = BLI_listbase_count(&node.inputs); - const uint total_output_len = BLI_listbase_count(&node.outputs); - - if (total_input_len + total_output_len == 0) { + if (node.input_sockets().is_empty() && node.output_sockets().is_empty()) { return; } @@ -1431,12 +1428,12 @@ static void node_draw_sockets(const View2D &v2d, scale *= socket_draw_size; if (!select_all) { - immBeginAtMost(GPU_PRIM_POINTS, total_input_len + total_output_len); + immBeginAtMost(GPU_PRIM_POINTS, node.input_sockets().size() + node.output_sockets().size()); } /* Socket inputs. */ - short selected_input_len = 0; - LISTBASE_FOREACH (bNodeSocket *, sock, &node.inputs) { + int selected_input_len = 0; + for (const bNodeSocket *sock : node.input_sockets()) { if (!sock->is_visible()) { continue; } @@ -1467,9 +1464,9 @@ static void node_draw_sockets(const View2D &v2d, } /* Socket outputs. */ - short selected_output_len = 0; + int selected_output_len = 0; if (draw_outputs) { - LISTBASE_FOREACH (bNodeSocket *, sock, &node.outputs) { + for (const bNodeSocket *sock : node.output_sockets()) { if (!sock->is_visible()) { continue; } @@ -1507,7 +1504,7 @@ static void node_draw_sockets(const View2D &v2d, if (selected_input_len) { /* Socket inputs. */ - LISTBASE_FOREACH (bNodeSocket *, sock, &node.inputs) { + for (const bNodeSocket *sock : node.input_sockets()) { if (!sock->is_visible()) { continue; } @@ -1537,7 +1534,7 @@ static void node_draw_sockets(const View2D &v2d, if (selected_output_len) { /* Socket outputs. */ - LISTBASE_FOREACH (bNodeSocket *, sock, &node.outputs) { + for (const bNodeSocket *sock : node.output_sockets()) { if (!sock->is_visible()) { continue; } @@ -1571,7 +1568,7 @@ static void node_draw_sockets(const View2D &v2d, /* Draw multi-input sockets after the others because they are drawn with `UI_draw_roundbox` * rather than with `GL_POINT`. */ - LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) { + for (const bNodeSocket *socket : node.input_sockets()) { if (!socket->is_visible()) { continue; } @@ -1905,7 +1902,7 @@ static std::optional node_get_accessed_attributes_row( GEO_NODE_REMOVE_ATTRIBUTE, GEO_NODE_INPUT_NAMED_ATTRIBUTE)) { /* Only show the overlay when the name is passed in from somewhere else. */ - LISTBASE_FOREACH (bNodeSocket *, socket, &node.inputs) { + for (const bNodeSocket *socket : node.input_sockets()) { if (STREQ(socket->name, "Name")) { if (!socket->is_directly_linked()) { return std::nullopt; @@ -2037,7 +2034,6 @@ static void node_draw_extra_info_panel(TreeDrawContext &tree_draw_ctx, uiBlock &block) { Vector extra_info_rows = node_get_extra_info(tree_draw_ctx, snode, node); - if (extra_info_rows.size() == 0) { return; } @@ -2048,7 +2044,7 @@ static void node_draw_extra_info_panel(TreeDrawContext &tree_draw_ctx, const float width = (node.width - 6.0f) * U.dpi_fac; - if (node.type == NODE_FRAME) { + if (node.is_frame()) { extra_info_rect.xmin = rct.xmin; extra_info_rect.xmax = rct.xmin + 95.0f * U.dpi_fac; extra_info_rect.ymin = rct.ymin + 2.0f * U.dpi_fac; @@ -2655,27 +2651,18 @@ void node_set_cursor(wmWindow &win, SpaceNode &snode, const float2 &cursor) static void count_multi_input_socket_links(bNodeTree &ntree, SpaceNode &snode) { - Map counts; - LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { - if (link->tosock->flag & SOCK_MULTI_INPUT) { - int &count = counts.lookup_or_add(link->tosock, 0); - count++; + for (bNode *node : ntree.all_nodes()) { + for (bNodeSocket *socket : node->input_sockets()) { + if (socket->is_multi_input()) { + socket->runtime->total_inputs = socket->directly_linked_links().size(); + } } } /* Count temporary links going into this socket. */ if (snode.runtime->linkdrag) { for (const bNodeLink &link : snode.runtime->linkdrag->links) { if (link.tosock && (link.tosock->flag & SOCK_MULTI_INPUT)) { - int &count = counts.lookup_or_add(link.tosock, 0); - count++; - } - } - } - - for (bNode *node : ntree.all_nodes()) { - LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) { - if (socket->flag & SOCK_MULTI_INPUT) { - socket->runtime->total_inputs = counts.lookup_default(socket, 0); + link.tosock->runtime->total_inputs++; } } } @@ -2768,12 +2755,12 @@ static void node_update_nodetree(const bContext &C, for (const int i : nodes.index_range()) { bNode &node = *nodes[i]; uiBlock &block = *blocks[i]; - if (node.type == NODE_FRAME) { + if (node.is_frame()) { /* Frame sizes are calculated after all other nodes have calculating their #totr. */ continue; } - if (node.type == NODE_REROUTE) { + if (node.is_reroute()) { reroute_node_prepare_for_draw(node); } else { @@ -2789,7 +2776,7 @@ static void node_update_nodetree(const bContext &C, /* Now calculate the size of frame nodes, which can depend on the size of other nodes. * Update nodes in reverse, so children sizes get updated before parents. */ for (int i = nodes.size() - 1; i >= 0; i--) { - if (nodes[i]->type == NODE_FRAME) { + if (nodes[i]->is_frame()) { frame_node_prepare_for_draw(*nodes[i], nodes); } } @@ -2992,10 +2979,10 @@ static void node_draw(const bContext &C, uiBlock &block, bNodeInstanceKey key) { - if (node.type == NODE_FRAME) { + if (node.is_frame()) { frame_node_draw(C, tree_draw_ctx, region, snode, ntree, node, block); } - else if (node.type == NODE_REROUTE) { + else if (node.is_reroute()) { reroute_node_draw(C, region, ntree, node, block); } else { From bc2220733aeeaeeaa3e767511ed19ba00c4834ef Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 3 Jan 2023 10:19:27 +1100 Subject: [PATCH 0354/1522] Cleanup: spelling in comments --- source/blender/blenkernel/intern/action.c | 2 +- source/blender/blenkernel/intern/blendfile.c | 6 ++--- source/blender/blenkernel/intern/context.cc | 4 ++-- source/blender/blenkernel/intern/lib_id.c | 4 ++-- source/blender/blenkernel/intern/lib_query.c | 2 +- .../blender/blenkernel/intern/mesh_convert.cc | 2 +- source/blender/blenkernel/intern/node.cc | 4 ++-- .../editors/sculpt_paint/paint_intern.h | 2 +- source/blender/gpu/intern/gpu_context.cc | 2 +- .../blender/gpu/metal/mtl_shader_interface.mm | 2 +- source/blender/makesdna/DNA_ID.h | 6 ++--- source/blender/makesrna/intern/rna_fcurve.c | 2 +- source/blender/makesrna/intern/rna_mask.c | 2 +- source/blender/makesrna/intern/rna_space.c | 2 +- .../composite/nodes/node_composite_glare.cc | 22 +++++++++---------- 15 files changed, 32 insertions(+), 32 deletions(-) diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 8f6bd812d8e..dcd0c25967b 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -108,7 +108,7 @@ static void action_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, /* Duplicate F-Curve. */ /* XXX TODO: pass subdata flag? - * But surprisingly does not seem to be doing any ID refcounting... */ + * But surprisingly does not seem to be doing any ID reference-counting. */ fcurve_dst = BKE_fcurve_copy(fcurve_src); BLI_addtail(&action_dst->curves, fcurve_dst); diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c index 7aa3fd4b9c5..f4421fc0d1c 100644 --- a/source/blender/blenkernel/intern/blendfile.c +++ b/source/blender/blenkernel/intern/blendfile.c @@ -416,9 +416,9 @@ static void setup_app_data(bContext *C, * means that we do not reset their user count, however we do increase that one when doing * lib_link on local IDs using linked ones. * There is no real way to predict amount of changes here, so we have to fully redo - * refcounting. - * Now that we re-use (and do not liblink in readfile.c) most local datablocks as well, we have - * to recompute refcount for all local IDs too. */ + * reference-counting. + * Now that we re-use (and do not liblink in readfile.c) most local data-blocks as well, + * we have to recompute reference-counts for all local IDs too. */ BKE_main_id_refcount_recompute(bmain, false); } diff --git a/source/blender/blenkernel/intern/context.cc b/source/blender/blenkernel/intern/context.cc index 79f4f56b325..114ed1a49c8 100644 --- a/source/blender/blenkernel/intern/context.cc +++ b/source/blender/blenkernel/intern/context.cc @@ -1511,8 +1511,8 @@ Depsgraph *CTX_data_expect_evaluated_depsgraph(const bContext *C) { Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); /* TODO(sergey): Assert that the dependency graph is fully evaluated. - * Note that first the depsgraph and scene post-eval hooks needs to run extra round of updates - * first to make check here really reliable. */ + * Note that first the depsgraph and scene post-evaluation hooks needs to run extra round of + * updates first to make check here really reliable. */ return depsgraph; } diff --git a/source/blender/blenkernel/intern/lib_id.c b/source/blender/blenkernel/intern/lib_id.c index 11ebd4c93c0..fcf585dfcfc 100644 --- a/source/blender/blenkernel/intern/lib_id.c +++ b/source/blender/blenkernel/intern/lib_id.c @@ -322,8 +322,8 @@ void id_us_min(ID *id) if (id->us <= limit) { if (!ID_TYPE_IS_DEPRECATED(GS(id->name))) { - /* Do not assert on deprecated ID types, we cannot really ensure that their ID refcounting - * is valid... */ + /* Do not assert on deprecated ID types, we cannot really ensure that their ID + * reference-counting is valid. */ CLOG_ERROR(&LOG, "ID user decrement error: %s (from '%s'): %d <= %d", id->name, diff --git a/source/blender/blenkernel/intern/lib_query.c b/source/blender/blenkernel/intern/lib_query.c index e6b3ef97b6e..e655ae88c30 100644 --- a/source/blender/blenkernel/intern/lib_query.c +++ b/source/blender/blenkernel/intern/lib_query.c @@ -261,7 +261,7 @@ static bool library_foreach_ID_link(Main *bmain, * (the node tree), but re-use those generated for the 'owner' ID (the material). */ if (inherit_data == NULL) { data.cb_flag = ID_IS_LINKED(id) ? IDWALK_CB_INDIRECT_USAGE : 0; - /* When an ID is defined as not refcounting its ID usages, it should never do it. */ + /* When an ID is defined as not reference-counting its ID usages, it should never do it. */ data.cb_flag_clear = (id->tag & LIB_TAG_NO_USER_REFCOUNT) ? IDWALK_CB_USER | IDWALK_CB_USER_ONE : 0; diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 0a66bacd004..c59210d9d47 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -1062,7 +1062,7 @@ Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain, * everything is only allowed to reference original data-blocks. * * Note that user-count updates has to be done *after* mesh has been transferred to Main database - * (since doing refcounting on non-Main IDs is forbidden). */ + * (since doing reference-counting on non-Main IDs is forbidden). */ BKE_library_foreach_ID_link( nullptr, &mesh->id, foreach_libblock_make_original_callback, nullptr, IDWALK_NOP); diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 69d2b2a12e6..ff7e474b36a 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -2955,7 +2955,7 @@ namespace blender::bke { /** * Free the node itself. * - * \note: ID user refcounting and changing the `nodes_by_id` vector are up to the caller. + * \note: ID user reference-counting and changing the `nodes_by_id` vector are up to the caller. */ void node_free_node(bNodeTree *ntree, bNode *node) { @@ -3031,7 +3031,7 @@ void ntreeFreeLocalNode(bNodeTree *ntree, bNode *node) void nodeRemoveNode(Main *bmain, bNodeTree *ntree, bNode *node, bool do_id_user) { /* This function is not for localized node trees, we do not want - * do to ID user refcounting and removal of animdation data then. */ + * do to ID user reference-counting and removal of animdation data then. */ BLI_assert((ntree->id.tag & LIB_TAG_LOCALIZED) == 0); bool node_has_id = false; diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index a3449e52225..fbb69b1fc5b 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -517,7 +517,7 @@ enum eBlurKernelType; BlurKernel *paint_new_blur_kernel(struct Brush *br, bool proj); void paint_delete_blur_kernel(BlurKernel *); -/* Initialize viewport pivot from evaulated bounding box center of ob. */ +/** Initialize viewport pivot from evaluated bounding box center of `ob`. */ void paint_init_pivot(struct Object *ob, struct Scene *scene); /* paint curve defines */ diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc index 101542802e6..587e4e74dc6 100644 --- a/source/blender/gpu/intern/gpu_context.cc +++ b/source/blender/gpu/intern/gpu_context.cc @@ -262,7 +262,7 @@ bool GPU_backend_type_selection_detect(void) backends_to_check.append(GPU_BACKEND_OPENGL); } - /* Add fallback to OpenGL when Metal backend is requested on a platform that doens't support + /* Add fallback to OpenGL when Metal backend is requested on a platform that doesn't support * metal. */ if (backends_to_check[0] == GPU_BACKEND_METAL) { backends_to_check.append(GPU_BACKEND_OPENGL); diff --git a/source/blender/gpu/metal/mtl_shader_interface.mm b/source/blender/gpu/metal/mtl_shader_interface.mm index 317d0f49763..126279a39a8 100644 --- a/source/blender/gpu/metal/mtl_shader_interface.mm +++ b/source/blender/gpu/metal/mtl_shader_interface.mm @@ -286,7 +286,7 @@ void MTLShaderInterface::prepare_common_shader_inputs() MTLShaderInputAttribute &shd_attr = attributes_[attr_index]; current_input->name_offset = shd_attr.name_offset; current_input->name_hash = BLI_hash_string(this->get_name_at_offset(shd_attr.name_offset)); - /* For Metal, we flatten the vertex attribute indices within the shader in order to minimise + /* For Metal, we flatten the vertex attribute indices within the shader in order to minimize * complexity. ShaderInput "Location" contains the original attribute location, as can be * fetched using `GPU_shader_get_attribute_info`. ShaderInput binding contains the array index * into the MTLShaderInterface `attributes_` array. */ diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 90d44d95139..c416d465ebb 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -812,7 +812,7 @@ enum { * ID is considered as runtime, and should not be saved when writing .blend file, nor influence * (in)direct status of linked data. * - * Only meaningful for IDs belonging to regular Main database, all other cases are implicitely + * Only meaningful for IDs belonging to regular Main database, all other cases are implicitly * considered runtime-only. * * RESET_NEVER @@ -860,10 +860,10 @@ enum { /** * Most of ID tags are cleared on file write (i.e. also when storing undo steps), since they - * either have of very short lifetime (not expected to exist accross undo steps), or are info that + * either have of very short lifetime (not expected to exist across undo steps), or are info that * will be re-generated when reading undo steps. * - * However a few of these need to be explicitely preserved accross undo steps. + * However a few of these need to be explicitly preserved across undo steps. */ #define LIB_TAG_KEEP_ON_UNDO (LIB_TAG_EXTRAUSER | LIB_TAG_MISSING | LIB_TAG_RUNTIME) diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index 9fe7dda0e20..e19c569bca0 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -267,7 +267,7 @@ static void rna_DriverTarget_update_name(Main *bmain, Scene *scene, PointerRNA * /* ----------- */ -/* NOTE: this function exists only to avoid id refcounting. */ +/* NOTE: this function exists only to avoid id reference-counting. */ static void rna_DriverTarget_id_set(PointerRNA *ptr, PointerRNA value, struct ReportList *UNUSED(reports)) diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index 3dd2f5626c0..5b53c3c8498 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -103,7 +103,7 @@ static void rna_Mask_update_parent(Main *bmain, Scene *scene, PointerRNA *ptr) rna_Mask_update_data(bmain, scene, ptr); } -/* NOTE: this function exists only to avoid id refcounting. */ +/* NOTE: this function exists only to avoid id reference-counting. */ static void rna_MaskParent_id_set(PointerRNA *ptr, PointerRNA value, struct ReportList *UNUSED(reports)) diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 75fc0e6e1e5..15ed20ce354 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1966,7 +1966,7 @@ static void rna_SpaceTextEditor_updateEdited(Main *UNUSED(bmain), /* Space Properties */ -/* NOTE: this function exists only to avoid id refcounting. */ +/* NOTE: this function exists only to avoid id reference-counting. */ static void rna_SpaceProperties_pin_id_set(PointerRNA *ptr, PointerRNA value, struct ReportList *UNUSED(reports)) diff --git a/source/blender/nodes/composite/nodes/node_composite_glare.cc b/source/blender/nodes/composite/nodes/node_composite_glare.cc index b02d9e6166b..7209c13aa51 100644 --- a/source/blender/nodes/composite/nodes/node_composite_glare.cc +++ b/source/blender/nodes/composite/nodes/node_composite_glare.cc @@ -459,29 +459,29 @@ class GlareOperation : public NodeOperation { return 1.0f - std::pow(get_color_modulation_factor(), iteration + 1); } - /* Streaks are computed by iteratively applying a filter that samples 3 neighbouring pixels in - * the direction of the streak. Those neighbouring pixels are then combined using a weighted sum. - * The weights of the neighbours are the fade factors computed by this method. Farther neighbours + /* Streaks are computed by iteratively applying a filter that samples 3 neighboring pixels in + * the direction of the streak. Those neighboring pixels are then combined using a weighted sum. + * The weights of the neighbors are the fade factors computed by this method. Farther neighbors * are expected to have lower weights because they contribute less to the combined result. Since - * the iteration magnitude represents how far the neighbours are, as noted in the description of - * the compute_streak_iteration_magnitude method, the fade factor for the closest neighbour is + * the iteration magnitude represents how far the neighbors are, as noted in the description of + * the compute_streak_iteration_magnitude method, the fade factor for the closest neighbor is * computed as the user supplied fade parameter raised to the power of the magnitude, noting that * the fade value is in the [0, 1] range while the magnitude is larger than or equal one, so the - * higher the power the lower the resulting fade factor. Furthermore, the other two neighbours - * are just squared and cubed versions of the fade factor for the closest neighbour to get even - * lower fade factors for those farther neighbours. */ + * higher the power the lower the resulting fade factor. Furthermore, the other two neighbors + * are just squared and cubed versions of the fade factor for the closest neighbor to get even + * lower fade factors for those farther neighbors. */ float3 compute_streak_fade_factors(float iteration_magnitude) { const float fade_factor = std::pow(node_storage(bnode()).fade, iteration_magnitude); return float3(fade_factor, std::pow(fade_factor, 2.0f), std::pow(fade_factor, 3.0f)); } - /* Streaks are computed by iteratively applying a filter that samples the neighbouring pixels in + /* Streaks are computed by iteratively applying a filter that samples the neighboring pixels in * the direction of the streak. Each higher iteration samples pixels that are farther away, the - * magnitude computed by this method describes how farther away the neighbours are sampled. The + * magnitude computed by this method describes how farther away the neighbors are sampled. The * magnitude exponentially increase with the iteration. A base of 4, was chosen as compromise * between better quality and performance, since a lower base corresponds to more tightly spaced - * neighbours but would require more iterations to produce a streak of the same length. */ + * neighbors but would require more iterations to produce a streak of the same length. */ float compute_streak_iteration_magnitude(int iteration) { return std::pow(4.0f, iteration); From 0e5dab08313c66f70dec9f1dc3637a3b51780310 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 3 Jan 2023 10:22:19 +1100 Subject: [PATCH 0355/1522] Cleanup: move doc-string into header --- source/blender/blenkernel/BKE_node.h | 5 +++++ source/blender/blenkernel/intern/node.cc | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index acf52a5b965..675328b15c4 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -713,6 +713,11 @@ bNode *node_copy_with_mapping(bNodeTree *dst_tree, bNode *node_copy(bNodeTree *dst_tree, const bNode &src_node, int flag, bool use_unique); +/** + * Free the node itself. + * + * \note ID user reference-counting and changing the `nodes_by_id` vector are up to the caller. + */ void node_free_node(bNodeTree *tree, bNode *node); } // namespace blender::bke diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index ff7e474b36a..eeba322e30d 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -2952,11 +2952,6 @@ void nodeRebuildIDVector(bNodeTree *node_tree) namespace blender::bke { -/** - * Free the node itself. - * - * \note: ID user reference-counting and changing the `nodes_by_id` vector are up to the caller. - */ void node_free_node(bNodeTree *ntree, bNode *node) { /* since it is called while free database, node->id is undefined */ From 9a18a9bfce4eb9a6cfd0d3172f7931b31f0d9414 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 3 Jan 2023 10:25:38 +1100 Subject: [PATCH 0356/1522] Cleanup: warnings from descriptions ending with a full-stop --- source/blender/makesrna/intern/rna_pose_api.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/source/blender/makesrna/intern/rna_pose_api.c b/source/blender/makesrna/intern/rna_pose_api.c index 64d044717ce..6a79bd9bad3 100644 --- a/source/blender/makesrna/intern/rna_pose_api.c +++ b/source/blender/makesrna/intern/rna_pose_api.c @@ -216,28 +216,29 @@ void RNA_api_pose(StructRNA *srna) func, "Create a backup of the current pose. Only those bones that are animated in the Action are " "backed up. The object owns the backup, and each object can have only one backup at a time. " - "When you no longer need it, it must be freed use `backup_clear()`."); + "When you no longer need it, it must be freed use `backup_clear()`"); RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_NO_SELF); parm = RNA_def_pointer(func, "action", "Action", "Action", - "An Action with animation data for the bones. Only the animated bones " - "will be included in the backup."); + "An Action with animation data for the bones. " + "Only the animated bones will be included in the backup"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); func = RNA_def_function(srna, "backup_restore", "rna_Pose_backup_restore"); RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_NO_SELF | FUNC_USE_CONTEXT); - RNA_def_function_ui_description(func, - "Restore the previously made pose backup. This can be called " - "multiple times. See `Pose.backup_create()` for more info."); + RNA_def_function_ui_description( + func, + "Restore the previously made pose backup. " + "This can be called multiple times. See `Pose.backup_create()` for more info"); /* return value */ parm = RNA_def_boolean( func, "success", false, "", - "`True` when the backup was restored, `False` if there was no backup to restore."); + "`True` when the backup was restored, `False` if there was no backup to restore"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "backup_clear", "rna_Pose_backup_clear"); From 75cd1fdc0a16630dfe33a42d0c4026bbbfb3c29c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 3 Jan 2023 11:03:50 +1100 Subject: [PATCH 0357/1522] Cleanup: format --- .../keyconfig/keymap_data/blender_default.py | 27 ++++++++++--------- release/scripts/startup/bl_ui/space_view3d.py | 14 ++++++++-- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index d9e17302177..b02454cfa86 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5050,30 +5050,33 @@ def km_sculpt(params): # Expand ("sculpt.expand", {"type": 'A', "value": 'PRESS', "shift": True}, {"properties": [ - ("target", "MASK"), - ("falloff_type", "GEODESIC"), - ("invert", True), - ("use_auto_mask", True), - ("use_mask_preserve" , True)]}), + ("target", "MASK"), + ("falloff_type", "GEODESIC"), + ("invert", True), + ("use_auto_mask", True), + ("use_mask_preserve", True), + ]}), ("sculpt.expand", {"type": 'A', "value": 'PRESS', "shift": True, "alt": True}, {"properties": [ - ("target", "MASK"), - ("falloff_type", "NORMALS"), - ("invert", False), - ("use_mask_preserve" , True)]}), + ("target", "MASK"), + ("falloff_type", "NORMALS"), + ("invert", False), + ("use_mask_preserve", True), + ]}), ("sculpt.expand", {"type": 'W', "value": 'PRESS', "shift": True}, {"properties": [ ("target", "FACE_SETS"), ("falloff_type", "GEODESIC"), ("invert", False), - ("use_mask_preserve" , False), - ("use_modify_active", False)]}), + ("use_mask_preserve", False), + ("use_modify_active", False), + ]}), ("sculpt.expand", {"type": 'W', "value": 'PRESS', "shift": True, "alt": True}, {"properties": [ ("target", "FACE_SETS"), ("falloff_type", "BOUNDARY_FACE_SET"), ("invert", False), - ("use_mask_preserve" , False), + ("use_mask_preserve", False), ("use_modify_active", True), ]}), # Partial Visibility Show/hide diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 311fe6076db..3e0dafac887 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -723,8 +723,18 @@ class VIEW3D_HT_header(Header): row = layout.row(align=True) domain = curves.selection_domain - row.operator("curves.set_selection_domain", text="", icon='CURVE_BEZCIRCLE', depress=(domain == 'POINT')).domain = 'POINT' - row.operator("curves.set_selection_domain", text="", icon='CURVE_PATH', depress=(domain == 'CURVE')).domain = 'CURVE' + row.operator( + "curves.set_selection_domain", + text="", + icon='CURVE_BEZCIRCLE', + depress=(domain == 'POINT'), + ).domain = 'POINT' + row.operator( + "curves.set_selection_domain", + text="", + icon='CURVE_PATH', + depress=(domain == 'CURVE'), + ).domain = 'CURVE' # Grease Pencil if obj and obj.type == 'GPENCIL' and context.gpencil_data: From e39ca9d1e3c584a7ee1805a5d18332b6517384af Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 3 Jan 2023 11:04:16 +1100 Subject: [PATCH 0358/1522] Cleanup: use function style casts for integer types in C++ Also remove redundant parenthesis. --- source/blender/blenkernel/intern/cloth.cc | 6 +- source/blender/blenkernel/intern/key.cc | 12 +-- source/blender/blenkernel/intern/layer.cc | 2 +- .../blender/blenkernel/intern/mesh_remap.cc | 4 +- .../blenloader/intern/versioning_300.cc | 6 +- .../bmesh/intern/bmesh_mesh_normals.cc | 2 +- .../draw/engines/overlay/overlay_engine.cc | 4 +- .../draw/intern/draw_cache_impl_gpencil.cc | 10 +-- .../interface/eyedroppers/eyedropper_color.cc | 4 +- .../editors/interface/interface_draw.cc | 10 +-- .../editors/interface/interface_icons.cc | 10 +-- .../editors/interface/interface_layout.cc | 30 +++---- .../editors/interface/interface_templates.cc | 10 +-- .../editors/interface/interface_widgets.cc | 62 ++++++------- source/blender/editors/interface/resources.cc | 36 ++++---- .../editors/sculpt_paint/paint_cursor.cc | 4 +- .../editors/sculpt_paint/paint_image_proj.cc | 88 +++++++++---------- .../editors/space_node/add_node_search.cc | 2 +- .../blender/editors/uvedit/uvedit_islands.cc | 8 +- .../intern/lineart/lineart_cpu.cc | 2 +- source/blender/gpu/opengl/gl_texture.cc | 2 +- .../io/alembic/intern/abc_customdata.cc | 2 +- .../gpencil/intern/gpencil_io_export_pdf.cc | 2 +- .../gpencil/intern/gpencil_io_export_svg.cc | 2 +- source/blender/modifiers/intern/MOD_array.cc | 8 +- .../nodes/node_composite_bokehblur.cc | 2 +- .../texture/nodes/node_texture_bricks.cc | 8 +- .../texture/nodes/node_texture_checker.cc | 6 +- .../texture/nodes/node_texture_curves.cc | 2 +- .../nodes/texture/nodes/node_texture_image.cc | 4 +- .../nodes/texture/nodes/node_texture_math.cc | 2 +- source/blender/render/intern/multires_bake.cc | 10 +-- 32 files changed, 180 insertions(+), 182 deletions(-) diff --git a/source/blender/blenkernel/intern/cloth.cc b/source/blender/blenkernel/intern/cloth.cc index 23bbaaf58b2..4f28bf5157c 100644 --- a/source/blender/blenkernel/intern/cloth.cc +++ b/source/blender/blenkernel/intern/cloth.cc @@ -1460,9 +1460,9 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) Cloth *cloth = clmd->clothObject; ClothSpring *spring = nullptr, *tspring = nullptr, *tspring2 = nullptr; uint struct_springs = 0, shear_springs = 0, bend_springs = 0, struct_springs_real = 0; - uint mvert_num = (uint)mesh->totvert; + uint mvert_num = uint(mesh->totvert); uint numedges = uint(mesh->totedge); - uint numpolys = (uint)mesh->totpoly; + uint numpolys = uint(mesh->totpoly); float shrink_factor; const MEdge *medge = BKE_mesh_edges(mesh); const MPoly *mpoly = BKE_mesh_polys(mesh); @@ -1647,7 +1647,7 @@ static bool cloth_build_springs(ClothModifierData *clmd, Mesh *mesh) for (int i = 0; i < mvert_num; i++) { if (cloth->verts[i].spring_count > 0) { cloth->verts[i].avg_spring_len = cloth->verts[i].avg_spring_len * 0.49f / - (float(cloth->verts[i].spring_count)); + float(cloth->verts[i].spring_count); } } diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index e0af320ac48..b19ad6a3e97 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -732,7 +732,7 @@ static void cp_key(const int start, if (flagflo) { ktot += start * kd; - a = (int)floor(ktot); + a = int(floor(ktot)); if (a) { ktot -= a; k1 += a * key->elemsize; @@ -1078,7 +1078,7 @@ static void do_key(const int start, if (flagdo & 1) { if (flagflo & 1) { k1tot += start * k1d; - a = (int)floor(k1tot); + a = int(floor(k1tot)); if (a) { k1tot -= a; k1 += a * key->elemsize; @@ -1091,7 +1091,7 @@ static void do_key(const int start, if (flagdo & 2) { if (flagflo & 2) { k2tot += start * k2d; - a = (int)floor(k2tot); + a = int(floor(k2tot)); if (a) { k2tot -= a; k2 += a * key->elemsize; @@ -1104,7 +1104,7 @@ static void do_key(const int start, if (flagdo & 4) { if (flagflo & 4) { k3tot += start * k3d; - a = (int)floor(k3tot); + a = int(floor(k3tot)); if (a) { k3tot -= a; k3 += a * key->elemsize; @@ -1117,7 +1117,7 @@ static void do_key(const int start, if (flagdo & 8) { if (flagflo & 8) { k4tot += start * k4d; - a = (int)floor(k4tot); + a = int(floor(k4tot)); if (a) { k4tot -= a; k4 += a * key->elemsize; @@ -1661,7 +1661,7 @@ int BKE_keyblock_element_count(const Key *key) size_t BKE_keyblock_element_calc_size_from_shape(const Key *key, const int shape_index) { - return (size_t)BKE_keyblock_element_count_from_shape(key, shape_index) * key->elemsize; + return size_t(BKE_keyblock_element_count_from_shape(key, shape_index)) * key->elemsize; } size_t BKE_keyblock_element_calc_size(const Key *key) diff --git a/source/blender/blenkernel/intern/layer.cc b/source/blender/blenkernel/intern/layer.cc index 198ad5b196f..95c341212d1 100644 --- a/source/blender/blenkernel/intern/layer.cc +++ b/source/blender/blenkernel/intern/layer.cc @@ -1057,7 +1057,7 @@ static void layer_collection_objects_sync(ViewLayer *view_layer, } /* Holdout and indirect only */ - if ((layer->flag & LAYER_COLLECTION_HOLDOUT)) { + if (layer->flag & LAYER_COLLECTION_HOLDOUT) { base->flag_from_collection |= BASE_HOLDOUT; } if (layer->flag & LAYER_COLLECTION_INDIRECT_ONLY) { diff --git a/source/blender/blenkernel/intern/mesh_remap.cc b/source/blender/blenkernel/intern/mesh_remap.cc index 142968de666..f66570bdcc7 100644 --- a/source/blender/blenkernel/intern/mesh_remap.cc +++ b/source/blender/blenkernel/intern/mesh_remap.cc @@ -1592,7 +1592,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, } } - if ((size_t)mp_dst->totloop > islands_res_buff_size) { + if (size_t(mp_dst->totloop) > islands_res_buff_size) { islands_res_buff_size = size_t(mp_dst->totloop) + MREMAP_DEFAULT_BUFSIZE; for (tindex = 0; tindex < num_trees; tindex++) { islands_res[tindex] = static_cast( @@ -2257,7 +2257,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, */ RNG *rng = BLI_rng_new(0); - const size_t numpolys_src = (size_t)me_src->totpoly; + const size_t numpolys_src = size_t(me_src->totpoly); /* Here it's simpler to just allocate for all polys :/ */ int *indices = static_cast(MEM_mallocN(sizeof(*indices) * numpolys_src, __func__)); diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 11392d04991..adc88a7caf5 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3789,7 +3789,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) LISTBASE_FOREACH (MovieClip *, clip, &bmain->movieclips) { MovieTracking *tracking = &clip->tracking; - const float frame_center_x = (float(clip->lastsize[0])) / 2; + const float frame_center_x = float(clip->lastsize[0]) / 2; const float frame_center_y = float(clip->lastsize[1]) / 2; tracking->camera.principal_point[0] = (tracking->camera.principal_legacy[0] - @@ -3828,8 +3828,8 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { View3D *v3d = (View3D *)sl; - v3d->overlay.flag |= (int)(V3D_OVERLAY_SCULPT_SHOW_MASK | - V3D_OVERLAY_SCULPT_SHOW_FACE_SETS); + v3d->overlay.flag |= int(V3D_OVERLAY_SCULPT_SHOW_MASK | + V3D_OVERLAY_SCULPT_SHOW_FACE_SETS); } } } diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.cc b/source/blender/bmesh/intern/bmesh_mesh_normals.cc index 5d906e0a73f..41203f25b6b 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_normals.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_normals.cc @@ -919,7 +919,7 @@ static void bm_mesh_loops_calc_normals_for_vert_with_clnors(BMesh *bm, BLI_linklist_prepend_alloca(&loops_of_vert, l_curr); loops_of_vert_count += 1; - const uint index_test = (uint)BM_elem_index_get(l_curr); + const uint index_test = uint(BM_elem_index_get(l_curr)); if (index_best > index_test) { index_best = index_test; link_best = loops_of_vert; diff --git a/source/blender/draw/engines/overlay/overlay_engine.cc b/source/blender/draw/engines/overlay/overlay_engine.cc index 2eea0ad2f65..e8300e81f2f 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.cc +++ b/source/blender/draw/engines/overlay/overlay_engine.cc @@ -92,10 +92,10 @@ static void OVERLAY_engine_init(void *vedata) } if (ts->sculpt) { - if (!(v3d->overlay.flag & (int)V3D_OVERLAY_SCULPT_SHOW_FACE_SETS)) { + if (!(v3d->overlay.flag & int(V3D_OVERLAY_SCULPT_SHOW_FACE_SETS))) { pd->overlay.sculpt_mode_face_sets_opacity = 0.0f; } - if (!(v3d->overlay.flag & (int)V3D_OVERLAY_SCULPT_SHOW_MASK)) { + if (!(v3d->overlay.flag & int(V3D_OVERLAY_SCULPT_SHOW_MASK))) { pd->overlay.sculpt_mode_mask_opacity = 0.0f; } } diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.cc b/source/blender/draw/intern/draw_cache_impl_gpencil.cc index 16e90994791..a877f43561a 100644 --- a/source/blender/draw/intern/draw_cache_impl_gpencil.cc +++ b/source/blender/draw/intern/draw_cache_impl_gpencil.cc @@ -276,7 +276,7 @@ BLI_INLINE int32_t pack_rotation_aspect_hardness(float rot, float asp, float har int32_t packed = 0; /* Aspect uses 9 bits */ float asp_normalized = (asp > 1.0f) ? (1.0f / asp) : asp; - packed |= (int32_t)unit_float_to_uchar_clamp(asp_normalized); + packed |= int32_t(unit_float_to_uchar_clamp(asp_normalized)); /* Store if inversed in the 9th bit. */ if (asp > 1.0f) { packed |= 1 << 8; @@ -284,13 +284,13 @@ BLI_INLINE int32_t pack_rotation_aspect_hardness(float rot, float asp, float har /* Rotation uses 9 bits */ /* Rotation are in [-90°..90°] range, so we can encode the sign of the angle + the cosine * because the cosine will always be positive. */ - packed |= (int32_t)unit_float_to_uchar_clamp(cosf(rot)) << 9; + packed |= int32_t(unit_float_to_uchar_clamp(cosf(rot))) << 9; /* Store sine sign in 9th bit. */ if (rot < 0.0f) { packed |= 1 << 17; } /* Hardness uses 8 bits */ - packed |= (int32_t)unit_float_to_uchar_clamp(hard) << 18; + packed |= int32_t(unit_float_to_uchar_clamp(hard)) << 18; return packed; } @@ -315,7 +315,7 @@ static void gpencil_buffer_add_point(GPUIndexBufBuilder *ibo, /* Encode fill opacity defined by opacity modifier in vertex color alpha. If * no opacity modifier, the value will be always 1.0f. The opacity factor can be any * value between 0.0f and 2.0f */ - col->fcol[3] = ((int)(col->fcol[3] * 10000.0f) * 10.0f) + gps->fill_opacity_fac; + col->fcol[3] = (int(col->fcol[3] * 10000.0f) * 10.0f) + gps->fill_opacity_fac; vert->strength = (round_cap0) ? pt->strength : -pt->strength; vert->u_stroke = pt->uv_fac; @@ -579,7 +579,7 @@ bGPDstroke *DRW_cache_gpencil_sbuffer_stroke_data_get(Object *ob) gps->runtime.stroke_start = 0; copy_v4_v4(gps->vert_color_fill, gpd->runtime.vert_color_fill); /* Caps. */ - gps->caps[0] = gps->caps[1] = (short)brush->gpencil_settings->caps_type; + gps->caps[0] = gps->caps[1] = short(brush->gpencil_settings->caps_type); gpd->runtime.sbuffer_gps = gps; } diff --git a/source/blender/editors/interface/eyedroppers/eyedropper_color.cc b/source/blender/editors/interface/eyedroppers/eyedropper_color.cc index ed93eacc302..94200e0ab4c 100644 --- a/source/blender/editors/interface/eyedroppers/eyedropper_color.cc +++ b/source/blender/editors/interface/eyedroppers/eyedropper_color.cc @@ -175,8 +175,8 @@ static bool eyedropper_cryptomatte_sample_renderlayer_fl(RenderLayer *render_lay if (STRPREFIX(render_pass->name, render_pass_name_prefix) && !STREQLEN(render_pass->name, render_pass_name_prefix, sizeof(render_pass->name))) { BLI_assert(render_pass->channels == 4); - const int x = (int)(fpos[0] * render_pass->rectx); - const int y = (int)(fpos[1] * render_pass->recty); + const int x = int(fpos[0] * render_pass->rectx); + const int y = int(fpos[1] * render_pass->recty); const int offset = 4 * (y * render_pass->rectx + x); zero_v3(r_col); r_col[0] = render_pass->rect[offset]; diff --git a/source/blender/editors/interface/interface_draw.cc b/source/blender/editors/interface/interface_draw.cc index 973f92a5d0b..53a7d896427 100644 --- a/source/blender/editors/interface/interface_draw.cc +++ b/source/blender/editors/interface/interface_draw.cc @@ -115,10 +115,10 @@ void UI_draw_roundbox_3ub_alpha( const rctf *rect, bool filled, float rad, const uchar col[3], uchar alpha) { const float colv[4] = { - (float(col[0])) / 255.0f, - (float(col[1])) / 255.0f, - (float(col[2])) / 255.0f, - (float(alpha)) / 255.0f, + float(col[0]) / 255.0f, + float(col[1]) / 255.0f, + float(col[2]) / 255.0f, + float(alpha) / 255.0f, }; UI_draw_roundbox_4fv_ex(rect, (filled) ? colv : nullptr, nullptr, 1.0f, colv, U.pixelsize, rad); } @@ -1791,7 +1791,7 @@ void ui_draw_but_CURVEPROFILE(ARegion *region, /* Create array of the positions of the table's points. */ float(*table_coords)[2] = static_cast( MEM_mallocN(sizeof(*table_coords) * tot_points, __func__)); - for (uint i = 0; i < (uint)BKE_curveprofile_table_size(profile); i++) { + for (uint i = 0; i < uint(BKE_curveprofile_table_size(profile)); i++) { /* Only add the points from the table here. */ table_coords[i][0] = pts[i].x; table_coords[i][1] = pts[i].y; diff --git a/source/blender/editors/interface/interface_icons.cc b/source/blender/editors/interface/interface_icons.cc index eaf4361a7e6..93be39c9930 100644 --- a/source/blender/editors/interface/interface_icons.cc +++ b/source/blender/editors/interface/interface_icons.cc @@ -837,7 +837,7 @@ static ImBuf *create_mono_icon_with_border(ImBuf *buf, blend_color_interpolate_float(dest_rgba, orig_rgba, border_rgba, 1.0 - orig_rgba[3]); linearrgb_to_srgb_v4(dest_srgb, dest_rgba); - const uint alpha_mask = (uint)(dest_srgb[3] * 255) << 24; + const uint alpha_mask = uint(dest_srgb[3] * 255) << 24; const uint cpack = rgb_to_cpack(dest_srgb[0], dest_srgb[1], dest_srgb[2]) | alpha_mask; result->rect[offset_write] = cpack; } @@ -1549,11 +1549,11 @@ static void icon_draw_rect(float x, /* preserve aspect ratio and center */ if (rw > rh) { draw_w = w; - draw_h = (int)((float(rh) / float(rw)) * float(w)); + draw_h = int((float(rh) / float(rw)) * float(w)); draw_y += (h - draw_h) / 2; } else if (rw < rh) { - draw_w = (int)((float(rw) / float(rh)) * float(h)); + draw_w = int((float(rw) / float(rh)) * float(h)); draw_h = h; draw_x += (w - draw_w) / 2; } @@ -1772,7 +1772,7 @@ static void icon_draw_texture(float x, sizeof(text_overlay->text), text_color, ¶ms); - text_width = (float)UI_fontstyle_string_width(&fstyle_small, text_overlay->text) / UI_UNIT_X / + text_width = float(UI_fontstyle_string_width(&fstyle_small, text_overlay->text)) / UI_UNIT_X / zoom_factor; } @@ -1868,7 +1868,7 @@ static void icon_draw_size(float x, } /* scale width and height according to aspect */ - int w = (int)(fdraw_size / aspect + 0.5f); + int w = int(fdraw_size / aspect + 0.5f); int h = int(fdraw_size / aspect + 0.5f); DrawInfo *di = icon_ensure_drawinfo(icon); diff --git a/source/blender/editors/interface/interface_layout.cc b/source/blender/editors/interface/interface_layout.cc index 968ad8e11f4..f4b96899545 100644 --- a/source/blender/editors/interface/interface_layout.cc +++ b/source/blender/editors/interface/interface_layout.cc @@ -335,7 +335,7 @@ static int ui_text_icon_width_ex(uiLayout *layout, const float aspect = layout->root->block->aspect; const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; return UI_fontstyle_string_width_with_block_aspect(fstyle, name, aspect) + - (int)ceilf(unit_x * margin); + int(ceilf(unit_x * margin)); } return unit_x * 10; } @@ -4315,7 +4315,7 @@ static void ui_litem_grid_flow_compute(ListBase *items, int item_w, item_h; ui_item_size(item, &item_w, &item_h); - global_avg_w += (float)(item_w * item_w); + global_avg_w += float(item_w * item_w); global_totweight_w += float(item_w); global_max_h = max_ii(global_max_h, item_h); @@ -4361,8 +4361,8 @@ static void ui_litem_grid_flow_compute(ListBase *items, /* Compute positions and sizes of all cells. */ if (results->cos_x_array != nullptr && results->widths_array != nullptr) { /* We enlarge/narrow columns evenly to match available width. */ - const float wfac = (float)(parameters->litem_w - - (parameters->tot_columns - 1) * parameters->space_x) / + const float wfac = float(parameters->litem_w - + (parameters->tot_columns - 1) * parameters->space_x) / tot_w; for (int col = 0; col < parameters->tot_columns; col++) { @@ -4382,7 +4382,7 @@ static void ui_litem_grid_flow_compute(ListBase *items, (results->cos_x_array[col] - parameters->litem_x); } else { - results->widths_array[col] = (int)(avg_w[col] * wfac); + results->widths_array[col] = int(avg_w[col] * wfac); } } } @@ -4460,10 +4460,10 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem) gflow->tot_columns = 1; } else { - gflow->tot_columns = min_ii(max_ii((int)(litem->w / avg_w), 1), gflow->tot_items); + gflow->tot_columns = min_ii(max_ii(int(litem->w / avg_w), 1), gflow->tot_items); } } - gflow->tot_rows = (int)ceilf(float(gflow->tot_items) / gflow->tot_columns); + gflow->tot_rows = int(ceilf(float(gflow->tot_items) / gflow->tot_columns)); /* Try to tweak number of columns and rows to get better filling of last column or row, * and apply 'modulo' value to number of columns or rows. @@ -4479,9 +4479,9 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem) gflow->tot_columns = gflow->tot_columns - (gflow->tot_columns % modulo); } /* Find smallest number of columns conserving computed optimal number of rows. */ - for (gflow->tot_rows = (int)ceilf(float(gflow->tot_items) / gflow->tot_columns); + for (gflow->tot_rows = int(ceilf(float(gflow->tot_items) / gflow->tot_columns)); (gflow->tot_columns - step) > 0 && - (int)ceilf(float(gflow->tot_items) / (gflow->tot_columns - step)) <= gflow->tot_rows; + int(ceilf(float(gflow->tot_items) / (gflow->tot_columns - step))) <= gflow->tot_rows; gflow->tot_columns -= step) { /* pass */ } @@ -4493,9 +4493,9 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem) gflow->tot_items); } /* Find smallest number of rows conserving computed optimal number of columns. */ - for (gflow->tot_columns = (int)ceilf(float(gflow->tot_items) / gflow->tot_rows); + for (gflow->tot_columns = int(ceilf(float(gflow->tot_items) / gflow->tot_rows)); (gflow->tot_rows - step) > 0 && - (int)ceilf(float(gflow->tot_items) / (gflow->tot_rows - step)) <= gflow->tot_columns; + int(ceilf(float(gflow->tot_items) / (gflow->tot_rows - step))) <= gflow->tot_columns; gflow->tot_rows -= step) { /* pass */ } @@ -4505,8 +4505,8 @@ static void ui_litem_estimate_grid_flow(uiLayout *litem) /* Set evenly-spaced axes size * (quick optimization in case we have even columns and rows). */ if (gflow->even_columns && gflow->even_rows) { - litem->w = (int)(gflow->tot_columns * avg_w) + space_x * (gflow->tot_columns - 1); - litem->h = (int)(gflow->tot_rows * max_h) + space_y * (gflow->tot_rows - 1); + litem->w = int(gflow->tot_columns * avg_w) + space_x * (gflow->tot_columns - 1); + litem->h = int(gflow->tot_rows * max_h) + space_y * (gflow->tot_rows - 1); return; } } @@ -4714,7 +4714,7 @@ static void ui_litem_layout_split(uiLayout *litem) x += colw; if (item->next) { - const float width = extra_pixel + (w - (int)(w * percentage)) / (float(tot) - 1); + const float width = extra_pixel + (w - int(w * percentage)) / (float(tot) - 1); extra_pixel = width - int(width); colw = int(width); colw = MAX2(colw, 0); @@ -6135,7 +6135,7 @@ uiLayout *uiItemsAlertBox(uiBlock *block, const int size, const eAlertIcon icon) const float icon_padding = 5.0f * U.dpi_fac; /* Calculate the factor of the fixed icon column depending on the block width. */ const float split_factor = (float(icon_size) + icon_padding) / - (float)(dialog_width - style->columnspace); + float(dialog_width - style->columnspace); uiLayout *block_layout = UI_block_layout( block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, dialog_width, 0, 0, style); diff --git a/source/blender/editors/interface/interface_templates.cc b/source/blender/editors/interface/interface_templates.cc index 2374d1dece7..4a0999e26df 100644 --- a/source/blender/editors/interface/interface_templates.cc +++ b/source/blender/editors/interface/interface_templates.cc @@ -3183,7 +3183,7 @@ void uiTemplatePreview(uiLayout *layout, if (!ui_preview) { ui_preview = MEM_cnew(__func__); BLI_strncpy(ui_preview->preview_id, preview_id, sizeof(ui_preview->preview_id)); - ui_preview->height = (short)(UI_UNIT_Y * 7.6f); + ui_preview->height = short(UI_UNIT_Y * 7.6f); BLI_addtail(®ion->ui_previews, ui_preview); } @@ -3225,7 +3225,7 @@ void uiTemplatePreview(uiLayout *layout, 0, 0, UI_UNIT_X * 10, - (short)(UI_UNIT_Y * 0.3f), + short(UI_UNIT_Y * 0.3f), &ui_preview->height, UI_UNIT_Y, UI_UNIT_Y * 50.0f, @@ -4028,7 +4028,7 @@ void uiTemplateHistogram(uiLayout *layout, PointerRNA *ptr, const char *propname 0, 0, UI_UNIT_X * 10, - (short)(UI_UNIT_Y * 0.3f), + short(UI_UNIT_Y * 0.3f), &hist->height, UI_UNIT_Y, UI_UNIT_Y * 20.0f, @@ -4090,7 +4090,7 @@ void uiTemplateWaveform(uiLayout *layout, PointerRNA *ptr, const char *propname) 0, 0, UI_UNIT_X * 10, - (short)(UI_UNIT_Y * 0.3f), + short(UI_UNIT_Y * 0.3f), &scopes->wavefrm_height, UI_UNIT_Y, UI_UNIT_Y * 20.0f, @@ -4152,7 +4152,7 @@ void uiTemplateVectorscope(uiLayout *layout, PointerRNA *ptr, const char *propna 0, 0, UI_UNIT_X * 10, - (short)(UI_UNIT_Y * 0.3f), + short(UI_UNIT_Y * 0.3f), &scopes->vecscope_height, UI_UNIT_Y, UI_UNIT_Y * 20.0f, diff --git a/source/blender/editors/interface/interface_widgets.cc b/source/blender/editors/interface/interface_widgets.cc index 690a32cd1e4..ea9bdc8a0d9 100644 --- a/source/blender/editors/interface/interface_widgets.cc +++ b/source/blender/editors/interface/interface_widgets.cc @@ -133,9 +133,9 @@ static const uiWidgetStateInfo STATE_INFO_NULL = {0}; static void color_blend_v3_v3(uchar cp[3], const uchar cpstate[3], const float fac) { if (fac != 0.0f) { - cp[0] = (int)((1.0f - fac) * cp[0] + fac * cpstate[0]); - cp[1] = (int)((1.0f - fac) * cp[1] + fac * cpstate[1]); - cp[2] = (int)((1.0f - fac) * cp[2] + fac * cpstate[2]); + cp[0] = int((1.0f - fac) * cp[0] + fac * cpstate[0]); + cp[1] = int((1.0f - fac) * cp[1] + fac * cpstate[1]); + cp[2] = int((1.0f - fac) * cp[2] + fac * cpstate[2]); } } @@ -880,7 +880,7 @@ static void shape_preset_init_trias_ex(uiWidgetTrias *tria, const float minsize = ELEM(where, 'r', 'l') ? BLI_rcti_size_y(rect) : BLI_rcti_size_x(rect); /* center position and size */ - float centx = (float)rect->xmin + 0.4f * minsize; + float centx = float(rect->xmin) + 0.4f * minsize; float centy = float(rect->ymin) + 0.5f * minsize; tria->size = sizex = sizey = -0.5f * triasize * minsize; @@ -1448,8 +1448,8 @@ static void widget_draw_submenu_tria(const uiBut *but, const uiWidgetColors *wcol) { const float aspect = but->block->aspect * U.inv_dpi_fac; - const int tria_height = (int)(ICON_DEFAULT_HEIGHT / aspect); - const int tria_width = (int)(ICON_DEFAULT_WIDTH / aspect) - 2 * U.pixelsize; + const int tria_height = int(ICON_DEFAULT_HEIGHT / aspect); + const int tria_width = int(ICON_DEFAULT_WIDTH / aspect) - 2 * U.pixelsize; const int xs = rect->xmax - tria_width; const int ys = (rect->ymin + rect->ymax - tria_height) / 2.0f; @@ -1507,7 +1507,7 @@ static void ui_text_clip_right_ex(const uiFontStyle *fstyle, /* At least one character, so clip and add the ellipsis. */ memcpy(str + l_end, sep, sep_len + 1); /* +1 for trailing '\0'. */ if (r_final_len) { - *r_final_len = (size_t)(l_end) + sep_len; + *r_final_len = size_t(l_end) + sep_len; } } else { @@ -1602,7 +1602,7 @@ float UI_text_clip_middle_ex(const uiFontStyle *fstyle, memmove(str + l_end + sep_len, str + r_offset, r_len); memcpy(str + l_end, sep, sep_len); /* -1 to remove trailing '\0'! */ - final_lpart_len = (size_t)(l_end + sep_len + r_len - 1); + final_lpart_len = size_t(l_end + sep_len + r_len - 1); while (BLF_width(fstyle->uifont_id, str, max_len) > okwidth) { /* This will happen because a lot of string width processing is done in integer pixels, @@ -1638,10 +1638,10 @@ static void ui_text_clip_middle(const uiFontStyle *fstyle, uiBut *but, const rct /* No margin for labels! */ const int border = ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_MENU, UI_BTYPE_POPOVER) ? 0 : - (int)(UI_TEXT_CLIP_MARGIN + 0.5f); - const float okwidth = (float)max_ii(BLI_rcti_size_x(rect) - border, 0); + int(UI_TEXT_CLIP_MARGIN + 0.5f); + const float okwidth = float(max_ii(BLI_rcti_size_x(rect) - border, 0)); const size_t max_len = sizeof(but->drawstr); - const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f; + const float minwidth = float(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f; but->ofs = 0; but->strwidth = UI_text_clip_middle_ex(fstyle, but->drawstr, okwidth, minwidth, max_len, '\0'); @@ -1661,10 +1661,10 @@ static void ui_text_clip_middle_protect_right(const uiFontStyle *fstyle, /* No margin for labels! */ const int border = ELEM(but->type, UI_BTYPE_LABEL, UI_BTYPE_MENU, UI_BTYPE_POPOVER) ? 0 : - (int)(UI_TEXT_CLIP_MARGIN + 0.5f); - const float okwidth = (float)max_ii(BLI_rcti_size_x(rect) - border, 0); + int(UI_TEXT_CLIP_MARGIN + 0.5f); + const float okwidth = float(max_ii(BLI_rcti_size_x(rect) - border, 0)); const size_t max_len = sizeof(but->drawstr); - const float minwidth = (float)(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f; + const float minwidth = float(UI_DPI_ICON_SIZE) / but->block->aspect * 2.0f; but->ofs = 0; but->strwidth = UI_text_clip_middle_ex(fstyle, but->drawstr, okwidth, minwidth, max_len, rsep); @@ -1675,7 +1675,7 @@ static void ui_text_clip_middle_protect_right(const uiFontStyle *fstyle, */ static void ui_text_clip_cursor(const uiFontStyle *fstyle, uiBut *but, const rcti *rect) { - const int border = (int)(UI_TEXT_CLIP_MARGIN + 0.5f); + const int border = int(UI_TEXT_CLIP_MARGIN + 0.5f); const int okwidth = max_ii(BLI_rcti_size_x(rect) - border, 0); BLI_assert(but->editstr && but->pos >= 0); @@ -2119,7 +2119,7 @@ static void widget_draw_text(const uiFontStyle *fstyle, for (int i = 0; i < ARRAY_SIZE(keys); i++) { const char *drawstr_menu = strchr(drawstr_ofs, keys[i]); if (drawstr_menu != nullptr && drawstr_menu < drawstr_end) { - ul_index = (int)(drawstr_menu - drawstr_ofs); + ul_index = int(drawstr_menu - drawstr_ofs); break; } } @@ -2814,7 +2814,7 @@ void ui_hsvcircle_vals_from_pos( /* duplication of code... well, simple is better now */ const float centx = BLI_rcti_cent_x_fl(rect); const float centy = BLI_rcti_cent_y_fl(rect); - const float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f; + const float radius = float(min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect))) / 2.0f; const float m_delta[2] = {mx - centx, my - centy}; const float dist_sq = len_squared_v2(m_delta); @@ -2828,7 +2828,7 @@ void ui_hsvcircle_pos_from_vals( /* duplication of code... well, simple is better now */ const float centx = BLI_rcti_cent_x_fl(rect); const float centy = BLI_rcti_cent_y_fl(rect); - const float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f; + const float radius = float(min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect))) / 2.0f; const float ang = 2.0f * float(M_PI) * hsv[0] + float(M_PI_2); @@ -2853,7 +2853,7 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, const uiWidgetColors *wcol, const const float radstep = 2.0f * float(M_PI) / float(tot); const float centx = BLI_rcti_cent_x_fl(rect); const float centy = BLI_rcti_cent_y_fl(rect); - const float radius = (float)min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect)) / 2.0f; + const float radius = float(min_ii(BLI_rcti_size_x(rect), BLI_rcti_size_y(rect))) / 2.0f; ColorPicker *cpicker = static_cast(but->custom_data); float rgb[3], hsv[3], rgb_center[3]; @@ -3086,7 +3086,7 @@ void ui_draw_gradient(const rcti *rect, sx1 = rect->xmin + dx * BLI_rcti_size_x(rect); sx2 = rect->xmin + dx_next * BLI_rcti_size_x(rect); sy = rect->ymin; - dy = (float)BLI_rcti_size_y(rect) / 3.0f; + dy = float(BLI_rcti_size_y(rect)) / 3.0f; for (a = 0; a < 3; a++, sy += dy) { immAttr4f(col, col0[a][0], col0[a][1], col0[a][2], alpha); @@ -3551,7 +3551,7 @@ static void widget_scroll(uiBut *but, const float /*zoom*/) { /* calculate slider part */ - const float value = (float)ui_but_value_get(but); + const float value = float(ui_but_value_get(but)); const float size = max_ff((but->softmax + but->a1 - but->softmin), 2.0f); @@ -3726,7 +3726,7 @@ static void widget_numslider(uiBut *but, rcti rect1 = *rect; float factor, factor_ui; float factor_discard = 1.0f; /* No discard. */ - const float value = (float)ui_but_value_get(but); + const float value = float(ui_but_value_get(but)); const float softmin = but->softmin; const float softmax = but->softmax; const float softrange = softmax - softmin; @@ -3758,7 +3758,7 @@ static void widget_numslider(uiBut *but, } } - const float width = (float)BLI_rcti_size_x(rect); + const float width = float(BLI_rcti_size_x(rect)); factor_ui = factor * width; /* The rectangle width needs to be at least twice the corner radius for the round corners * to be drawn properly. */ @@ -4979,9 +4979,9 @@ static void ui_draw_clip_tri(uiBlock *block, rcti *rect, uiWidgetType *wt) float draw_color[4]; const uchar *color = wt->wcol.text; - draw_color[0] = (float(color[0])) / 255.0f; - draw_color[1] = (float(color[1])) / 255.0f; - draw_color[2] = (float(color[2])) / 255.0f; + draw_color[0] = float(color[0]) / 255.0f; + draw_color[1] = float(color[1]) / 255.0f; + draw_color[2] = float(color[2]) / 255.0f; draw_color[3] = 1.0f; if (block->flag & UI_BLOCK_CLIPTOP) { @@ -5129,7 +5129,7 @@ static void draw_disk_shaded(float start, immBegin(GPU_PRIM_TRI_STRIP, subd * 2); for (int i = 0; i < subd; i++) { - const float a = start + ((i) / (float)(subd - 1)) * angle; + const float a = start + ((i) / float(subd - 1)) * angle; const float s = sinf(a); const float c = cosf(a); const float y1 = s * radius_int; @@ -5380,9 +5380,9 @@ void ui_draw_menu_item(const uiFontStyle *fstyle, { char drawstr[UI_MAX_DRAW_STR]; - const float okwidth = (float)BLI_rcti_size_x(rect); + const float okwidth = float(BLI_rcti_size_x(rect)); const size_t max_len = sizeof(drawstr); - const float minwidth = (float)(UI_DPI_ICON_SIZE); + const float minwidth = float(UI_DPI_ICON_SIZE); BLI_strncpy(drawstr, name, sizeof(drawstr)); if (drawstr[0]) { @@ -5431,7 +5431,7 @@ void ui_draw_menu_item(const uiFontStyle *fstyle, char hint_drawstr[UI_MAX_DRAW_STR]; { const size_t max_len = sizeof(hint_drawstr); - const float minwidth = (float)(UI_DPI_ICON_SIZE); + const float minwidth = float(UI_DPI_ICON_SIZE); BLI_strncpy(hint_drawstr, cpoin + 1, sizeof(hint_drawstr)); if (hint_drawstr[0] && (max_hint_width < INT_MAX)) { @@ -5484,7 +5484,7 @@ void ui_draw_preview_item_stateless(const uiFontStyle *fstyle, { char drawstr[UI_MAX_DRAW_STR]; - const float okwidth = (float)BLI_rcti_size_x(&trect); + const float okwidth = float(BLI_rcti_size_x(&trect)); const size_t max_len = sizeof(drawstr); const float minwidth = float(UI_DPI_ICON_SIZE); diff --git a/source/blender/editors/interface/resources.cc b/source/blender/editors/interface/resources.cc index 74590dccec4..606f9d5a11f 100644 --- a/source/blender/editors/interface/resources.cc +++ b/source/blender/editors/interface/resources.cc @@ -1141,51 +1141,51 @@ void UI_FontThemeColor(int fontid, int colorid) float UI_GetThemeValuef(int colorid) { const uchar *cp = UI_ThemeGetColorPtr(g_theme_state.theme, g_theme_state.spacetype, colorid); - return (float(cp[0])); + return float(cp[0]); } int UI_GetThemeValue(int colorid) { const uchar *cp = UI_ThemeGetColorPtr(g_theme_state.theme, g_theme_state.spacetype, colorid); - return (int(cp[0])); + return int(cp[0]); } float UI_GetThemeValueTypef(int colorid, int spacetype) { const uchar *cp = UI_ThemeGetColorPtr(g_theme_state.theme, spacetype, colorid); - return (float(cp[0])); + return float(cp[0]); } int UI_GetThemeValueType(int colorid, int spacetype) { const uchar *cp = UI_ThemeGetColorPtr(g_theme_state.theme, spacetype, colorid); - return (int(cp[0])); + return int(cp[0]); } void UI_GetThemeColor3fv(int colorid, float col[3]) { const uchar *cp = UI_ThemeGetColorPtr(g_theme_state.theme, g_theme_state.spacetype, colorid); - col[0] = (float(cp[0])) / 255.0f; - col[1] = (float(cp[1])) / 255.0f; - col[2] = (float(cp[2])) / 255.0f; + col[0] = float(cp[0]) / 255.0f; + col[1] = float(cp[1]) / 255.0f; + col[2] = float(cp[2]) / 255.0f; } void UI_GetThemeColor4fv(int colorid, float col[4]) { const uchar *cp = UI_ThemeGetColorPtr(g_theme_state.theme, g_theme_state.spacetype, colorid); - col[0] = (float(cp[0])) / 255.0f; - col[1] = (float(cp[1])) / 255.0f; - col[2] = (float(cp[2])) / 255.0f; - col[3] = (float(cp[3])) / 255.0f; + col[0] = float(cp[0]) / 255.0f; + col[1] = float(cp[1]) / 255.0f; + col[2] = float(cp[2]) / 255.0f; + col[3] = float(cp[3]) / 255.0f; } void UI_GetThemeColorType4fv(int colorid, int spacetype, float col[4]) { const uchar *cp = UI_ThemeGetColorPtr(g_theme_state.theme, spacetype, colorid); - col[0] = (float(cp[0])) / 255.0f; - col[1] = (float(cp[1])) / 255.0f; - col[2] = (float(cp[2])) / 255.0f; - col[3] = (float(cp[3])) / 255.0f; + col[0] = float(cp[0]) / 255.0f; + col[1] = float(cp[1]) / 255.0f; + col[2] = float(cp[2]) / 255.0f; + col[3] = float(cp[3]) / 255.0f; } void UI_GetThemeColorShade3fv(int colorid, int offset, float col[3]) @@ -1361,9 +1361,9 @@ void UI_GetThemeColor4ubv(int colorid, uchar col[4]) void UI_GetThemeColorType3fv(int colorid, int spacetype, float col[3]) { const uchar *cp = UI_ThemeGetColorPtr(g_theme_state.theme, spacetype, colorid); - col[0] = (float(cp[0])) / 255.0f; - col[1] = (float(cp[1])) / 255.0f; - col[2] = (float(cp[2])) / 255.0f; + col[0] = float(cp[0]) / 255.0f; + col[1] = float(cp[1]) / 255.0f; + col[2] = float(cp[2]) / 255.0f; } void UI_GetThemeColorType3ubv(int colorid, int spacetype, uchar col[3]) diff --git a/source/blender/editors/sculpt_paint/paint_cursor.cc b/source/blender/editors/sculpt_paint/paint_cursor.cc index 37f6d4c3037..63535a2bbe9 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.cc +++ b/source/blender/editors/sculpt_paint/paint_cursor.cc @@ -217,7 +217,7 @@ static void load_tex_task_cb_ex(void *__restrict userdata, /* Clamp to avoid precision overflow. */ CLAMP(avg, 0.0f, 1.0f); - buffer[index] = 255 - (uchar)(255 * avg); + buffer[index] = 255 - uchar(255 * avg); } } else { @@ -386,7 +386,7 @@ static void load_tex_cursor_task_cb(void *__restrict userdata, /* Falloff curve. */ float avg = BKE_brush_curve_strength_clamped(br, len, 1.0f); - buffer[index] = (uchar)(255 * avg); + buffer[index] = uchar(255 * avg); } else { buffer[index] = 0; diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.cc b/source/blender/editors/sculpt_paint/paint_image_proj.cc index 3d23cb46856..61aa984c1af 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.cc +++ b/source/blender/editors/sculpt_paint/paint_image_proj.cc @@ -604,8 +604,8 @@ static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[ * * Second multiplication does similar but for vertical offset */ - return (int)(((projCoSS[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + - ((int)(((projCoSS[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) * + return int(((projCoSS[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + + (int(((projCoSS[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) * ps->buckets_x); } @@ -787,8 +787,8 @@ static bool project_paint_PickColor( } } else { - // xi = (int)((uv[0]*ibuf->x) + 0.5f); - // yi = (int)((uv[1]*ibuf->y) + 0.5f); + // xi = int((uv[0]*ibuf->x) + 0.5f); + // yi = int((uv[1]*ibuf->y) + 0.5f); // if (xi < 0 || xi >= ibuf->x || yi < 0 || yi >= ibuf->y) return false; /* wrap */ @@ -1080,11 +1080,11 @@ static bool pixel_bounds_uv(const float uv_quad[4][2], minmax_v2v2_v2(min_uv, max_uv, uv_quad[2]); minmax_v2v2_v2(min_uv, max_uv, uv_quad[3]); - bounds_px->xmin = (int)(ibuf_x * min_uv[0]); - bounds_px->ymin = (int)(ibuf_y * min_uv[1]); + bounds_px->xmin = int(ibuf_x * min_uv[0]); + bounds_px->ymin = int(ibuf_y * min_uv[1]); - bounds_px->xmax = (int)(ibuf_x * max_uv[0]) + 1; - bounds_px->ymax = (int)(ibuf_y * max_uv[1]) + 1; + bounds_px->xmax = int(ibuf_x * max_uv[0]) + 1; + bounds_px->ymax = int(ibuf_y * max_uv[1]) + 1; // printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]); @@ -1110,11 +1110,11 @@ static bool pixel_bounds_array( uv++; } - bounds_px->xmin = (int)(ibuf_x * min_uv[0]); - bounds_px->ymin = (int)(ibuf_y * min_uv[1]); + bounds_px->xmin = int(ibuf_x * min_uv[0]); + bounds_px->ymin = int(ibuf_y * min_uv[1]); - bounds_px->xmax = (int)(ibuf_x * max_uv[0]) + 1; - bounds_px->ymax = (int)(ibuf_y * max_uv[1]) + 1; + bounds_px->xmax = int(ibuf_x * max_uv[0]) + 1; + bounds_px->ymax = int(ibuf_y * max_uv[1]) + 1; // printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]); @@ -1945,7 +1945,7 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps, projPixel->x_px = x_px; projPixel->y_px = y_px; - projPixel->mask = (ushort)(mask * 65535); + projPixel->mask = ushort(mask * 65535); if (ps->do_masking) { projPixel->mask_accum = projima->maskRect[tile_index] + tile_offset; } @@ -1954,8 +1954,8 @@ static ProjPixel *project_paint_uvpixel_init(const ProjPaintState *ps, } /* which bounding box cell are we in?, needed for undo */ - projPixel->bb_cell_index = (int)((float(x_px) / float(ibuf->x)) * PROJ_BOUNDBOX_DIV) + - (int)((float(y_px) / float(ibuf->y)) * PROJ_BOUNDBOX_DIV) * + projPixel->bb_cell_index = int((float(x_px) / float(ibuf->x)) * PROJ_BOUNDBOX_DIV) + + int((float(y_px) / float(ibuf->y)) * PROJ_BOUNDBOX_DIV) * PROJ_BOUNDBOX_DIV; /* done with view3d_project_float inline */ @@ -3112,13 +3112,13 @@ static void project_paint_face_init(const ProjPaintState *ps, has_isect = 0; for (y = bounds_px.ymin; y < bounds_px.ymax; y++) { - // uv[1] = (((float)y) + 0.5f) / (float)ibuf->y; + // uv[1] = (float(y) + 0.5f) / float(ibuf->y); /* use pixel offset UV coords instead */ uv[1] = float(y) / ibuf_yf; has_x_isect = 0; for (x = bounds_px.xmin; x < bounds_px.xmax; x++) { - // uv[0] = (((float)x) + 0.5f) / ibuf->x; + // uv[0] = (float(x) + 0.5f) / float(ibuf->x); /* use pixel offset UV coords instead */ uv[0] = float(x) / ibuf_xf; @@ -3322,7 +3322,7 @@ static void project_paint_face_init(const ProjPaintState *ps, has_isect = 0; for (y = bounds_px.ymin; y < bounds_px.ymax; y++) { - // uv[1] = (((float)y) + 0.5f) / (float)ibuf->y; + // uv[1] = (float(y) + 0.5f) / float(ibuf->y); /* use offset uvs instead */ uv[1] = float(y) / ibuf_yf; @@ -3330,7 +3330,7 @@ static void project_paint_face_init(const ProjPaintState *ps, for (x = bounds_px.xmin; x < bounds_px.xmax; x++) { const float puv[2] = {float(x), float(y)}; bool in_bounds; - // uv[0] = (((float)x) + 0.5f) / (float)ibuf->x; + // uv[0] = (float(x) + 0.5f) / float(ibuf->x); /* use offset uvs instead */ uv[0] = float(x) / ibuf_xf; @@ -3379,7 +3379,7 @@ static void project_paint_face_init(const ProjPaintState *ps, pixel_on_edge[3] = 1.0f; /* cast because of const */ mul_m4_v4((float(*)[4])ps->projectMat, pixel_on_edge); - pixel_on_edge[0] = (float)(ps->winx * 0.5f) + + pixel_on_edge[0] = float(ps->winx * 0.5f) + (ps->winx * 0.5f) * pixel_on_edge[0] / pixel_on_edge[3]; pixel_on_edge[1] = float(ps->winy * 0.5f) + (ps->winy * 0.5f) * pixel_on_edge[1] / pixel_on_edge[3]; @@ -3455,17 +3455,15 @@ static void project_paint_bucket_bounds(const ProjPaintState *ps, * is always truncated to 1, is this really correct? */ /* these offsets of 0.5 and 1.5 seem odd but they are correct */ - bucketMin[0] = - (int)((int)(((float)(min[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 0.5f); - bucketMin[1] = (int)((int)(((float)(min[1] - ps->screenMin[1]) / ps->screen_height) * - ps->buckets_y) + - 0.5f); + bucketMin[0] = int(int((float(min[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + + 0.5f); + bucketMin[1] = int(int((float(min[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + + 0.5f); - bucketMax[0] = - (int)((int)(((float)(max[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 1.5f); - bucketMax[1] = (int)((int)(((float)(max[1] - ps->screenMin[1]) / ps->screen_height) * - ps->buckets_y) + - 1.5f); + bucketMax[0] = int(int((float(max[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + + 1.5f); + bucketMax[1] = int(int((float(max[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + + 1.5f); /* in case the rect is outside the mesh 2d bounds */ CLAMP(bucketMin[0], 0, ps->buckets_x); @@ -3821,8 +3819,8 @@ static void proj_paint_state_screen_coords_init(ProjPaintState *ps, const int di mul_v3_m4v3(projScreenCo, ps->projectMat, mv->co); /* screen space, not clamped */ - projScreenCo[0] = (float)(ps->winx * 0.5f) + (ps->winx * 0.5f) * projScreenCo[0]; - projScreenCo[1] = (float)(ps->winy * 0.5f) + (ps->winy * 0.5f) * projScreenCo[1]; + projScreenCo[0] = float(ps->winx * 0.5f) + (ps->winx * 0.5f) * projScreenCo[0]; + projScreenCo[1] = float(ps->winy * 0.5f) + (ps->winy * 0.5f) * projScreenCo[1]; minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo); } } @@ -3835,9 +3833,9 @@ static void proj_paint_state_screen_coords_init(ProjPaintState *ps, const int di if (projScreenCo[3] > ps->clip_start) { /* screen space, not clamped */ - projScreenCo[0] = (float)(ps->winx * 0.5f) + + projScreenCo[0] = float(ps->winx * 0.5f) + (ps->winx * 0.5f) * projScreenCo[0] / projScreenCo[3]; - projScreenCo[1] = (float)(ps->winy * 0.5f) + + projScreenCo[1] = float(ps->winy * 0.5f) + (ps->winy * 0.5f) * projScreenCo[1] / projScreenCo[3]; /* Use the depth for bucket point occlusion */ projScreenCo[2] = projScreenCo[2] / projScreenCo[3]; @@ -4546,7 +4544,7 @@ static void project_paint_begin(const bContext *C, ps->screen_width = ps->screenMax[0] - ps->screenMin[0]; ps->screen_height = ps->screenMax[1] - ps->screenMin[1]; - ps->buckets_x = (int)(ps->screen_width / ((float(diameter)) / PROJ_BUCKET_BRUSH_DIV)); + ps->buckets_x = int(ps->screen_width / (float(diameter) / PROJ_BUCKET_BRUSH_DIV)); ps->buckets_y = int(ps->screen_height / (float(diameter) / PROJ_BUCKET_BRUSH_DIV)); // printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); @@ -4590,9 +4588,9 @@ static void paint_proj_begin_clone(ProjPaintState *ps, const float mouse[2]) projCo[3] = 1.0f; mul_m4_v4(ps->projectMat, projCo); ps->cloneOffset[0] = mouse[0] - - ((float)(ps->winx * 0.5f) + (ps->winx * 0.5f) * projCo[0] / projCo[3]); + (float(ps->winx * 0.5f) + (ps->winx * 0.5f) * projCo[0] / projCo[3]); ps->cloneOffset[1] = mouse[1] - - ((float)(ps->winy * 0.5f) + (ps->winy * 0.5f) * projCo[1] / projCo[3]); + (float(ps->winy * 0.5f) + (ps->winy * 0.5f) * projCo[1] / projCo[3]); } } @@ -4798,7 +4796,7 @@ static bool project_bucket_iter_next(ProjPaintState *ps, project_bucket_bounds(ps, bucket_x, bucket_y, bucket_bounds); if ((ps->source != PROJ_SRC_VIEW) || - project_bucket_isect_circle(mval, (float)(diameter * diameter), bucket_bounds)) { + project_bucket_isect_circle(mval, float(diameter * diameter), bucket_bounds)) { *bucket_index = bidx; return true; @@ -4838,7 +4836,7 @@ static void do_projectpaint_clone(ProjPaintState *ps, ProjPixel *projPixel, floa clone_rgba[0] = clone_pt[0]; clone_rgba[1] = clone_pt[1]; clone_rgba[2] = clone_pt[2]; - clone_rgba[3] = (uchar)(clone_pt[3] * mask); + clone_rgba[3] = uchar(clone_pt[3] * mask); if (ps->do_masking) { IMB_blend_color_byte(projPixel->pixel.ch_pt, @@ -5292,7 +5290,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v) } } BKE_colorband_evaluate(brush->gradient, f, color_f); - color_f[3] *= (float(projPixel->mask)) * (1.0f / 65535.0f) * brush_alpha; + color_f[3] *= float(projPixel->mask) * (1.0f / 65535.0f) * brush_alpha; if (is_floatbuf) { /* Convert to premutliplied. */ @@ -5322,7 +5320,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v) else { if (is_floatbuf) { float newColor_f[4]; - newColor_f[3] = (float(projPixel->mask)) * (1.0f / 65535.0f) * brush_alpha; + newColor_f[3] = float(projPixel->mask) * (1.0f / 65535.0f) * brush_alpha; copy_v3_v3(newColor_f, ps->paint_color_linear); IMB_blend_color_float(projPixel->pixel.f_pt, @@ -5359,7 +5357,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v) projPixel->projCoSS[0], projPixel->projCoSS[1]); if (projPixel->newColor.f[3]) { - float mask = (float(projPixel->mask)) * (1.0f / 65535.0f); + float mask = float(projPixel->mask) * (1.0f / 65535.0f); mul_v4_v4fl(projPixel->newColor.f, projPixel->newColor.f, mask); @@ -5376,7 +5374,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v) projPixel->projCoSS[0], projPixel->projCoSS[1]); if (projPixel->newColor.ch[3]) { - float mask = (float(projPixel->mask)) * (1.0f / 65535.0f); + float mask = float(projPixel->mask) * (1.0f / 65535.0f); projPixel->newColor.ch[3] *= mask; blend_color_mix_byte( @@ -5406,7 +5404,7 @@ static void do_projectpaint_thread(TaskPool *__restrict /*pool*/, void *ph_v) float mask; /* Extra mask for normal, layer stencil, etc. */ - float custom_mask = (float(projPixel->mask)) * (1.0f / 65535.0f); + float custom_mask = float(projPixel->mask) * (1.0f / 65535.0f); /* Mask texture. */ if (ps->is_maskbrush) { @@ -5805,7 +5803,7 @@ void paint_proj_stroke(const bContext *C, View3D *v3d = CTX_wm_view3d(C); ARegion *region = CTX_wm_region(C); float *cursor = scene->cursor.location; - const int mval_i[2] = {(int)pos[0], int(pos[1])}; + const int mval_i[2] = {int(pos[0]), int(pos[1])}; view3d_operator_needs_opengl(C); diff --git a/source/blender/editors/space_node/add_node_search.cc b/source/blender/editors/space_node/add_node_search.cc index 78e52c82517..26f99238a0d 100644 --- a/source/blender/editors/space_node/add_node_search.cc +++ b/source/blender/editors/space_node/add_node_search.cc @@ -178,7 +178,7 @@ static void gather_add_node_operations(const bContext &C, if (!(node_type->poll && node_type->poll(node_type, &node_tree, &disabled_hint))) { continue; } - if ((StringRefNull(node_tree.typeinfo->group_idname) == node_type->idname)) { + if (StringRefNull(node_tree.typeinfo->group_idname) == node_type->idname) { /* Skip the empty group type. */ continue; } diff --git a/source/blender/editors/uvedit/uvedit_islands.cc b/source/blender/editors/uvedit/uvedit_islands.cc index 893fd22a405..dc572b9f88e 100644 --- a/source/blender/editors/uvedit/uvedit_islands.cc +++ b/source/blender/editors/uvedit/uvedit_islands.cc @@ -42,11 +42,11 @@ static void mul_v2_m2_add_v2v2(float r[2], const float b[2]) { /* Compute `r = mat * (a + b)` with high precision. */ - const double x = static_cast(a[0]) + double(b[0]); - const double y = static_cast(a[1]) + double(b[1]); + const double x = double(a[0]) + double(b[0]); + const double y = double(a[1]) + double(b[1]); - r[0] = static_cast(mat[0][0] * x + mat[1][0] * y); - r[1] = static_cast(mat[0][1] * x + mat[1][1] * y); + r[0] = float(mat[0][0] * x + mat[1][0] * y); + r[1] = float(mat[0][1] * x + mat[1][1] * y); } static void island_uv_transform(FaceIsland *island, diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index cd3c253a7de..1ae91ab29c2 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -4609,7 +4609,7 @@ static void lineart_create_edges_from_isec_data(LineartIsecData *d) e->t1 = is->tri1; e->t2 = is->tri2; /* This is so we can also match intersection edges from shadow to later viewing stage. */ - e->edge_identifier = ((uint64_t(e->t1->target_reference)) << 32) | e->t2->target_reference; + e->edge_identifier = (uint64_t(e->t1->target_reference) << 32) | e->t2->target_reference; e->flags = LRT_EDGE_FLAG_INTERSECTION; e->intersection_mask = (is->tri1->intersection_mask | is->tri2->intersection_mask); BLI_addtail(&e->segments, es); diff --git a/source/blender/gpu/opengl/gl_texture.cc b/source/blender/gpu/opengl/gl_texture.cc index 8802f6184cb..1410dad8a2f 100644 --- a/source/blender/gpu/opengl/gl_texture.cc +++ b/source/blender/gpu/opengl/gl_texture.cc @@ -827,7 +827,7 @@ void GLPixelBuffer::unmap() int64_t GLPixelBuffer::get_native_handle() { - return (int64_t)gl_id_; + return int64_t(gl_id_); } uint GLPixelBuffer::get_size() diff --git a/source/blender/io/alembic/intern/abc_customdata.cc b/source/blender/io/alembic/intern/abc_customdata.cc index 2cd14bae527..81ac0f9fd52 100644 --- a/source/blender/io/alembic/intern/abc_customdata.cc +++ b/source/blender/io/alembic/intern/abc_customdata.cc @@ -596,7 +596,7 @@ AbcUvScope get_uv_scope(const Alembic::AbcGeom::GeometryScope scope, /* kVaryingScope is sometimes used for vertex scopes as the values vary across the vertices. To * be sure, one has to check the size of the data against the number of vertices, as it could * also be a varying attribute across the faces (i.e. one value per face). */ - if ((ELEM(scope, kVaryingScope, kVertexScope)) && indices->size() == config.totvert) { + if (ELEM(scope, kVaryingScope, kVertexScope) && indices->size() == config.totvert) { return ABC_UV_SCOPE_VERTEX; } diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc index 23fea9b6460..80695b6296f 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_export_pdf.cc @@ -178,7 +178,7 @@ void GpencilExporterPDF::export_gpencil_layers() gps_duplicate->thickness += gpl->line_change; /* Apply object scale to thickness. */ const float scalef = mat4_to_scale(ob->object_to_world); - gps_duplicate->thickness = ceilf((float)gps_duplicate->thickness * scalef); + gps_duplicate->thickness = ceilf(float(gps_duplicate->thickness) * scalef); CLAMP_MIN(gps_duplicate->thickness, 1.0f); /* Fill. */ if ((is_fill) && (params_.flag & GP_EXPORT_FILL)) { diff --git a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc index 2c4c09ce1a0..90aa3e6484b 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_export_svg.cc @@ -199,7 +199,7 @@ void GpencilExporterSVG::export_gpencil_layers() gps_duplicate->thickness += gpl->line_change; /* Apply object scale to thickness. */ const float scalef = mat4_to_scale(ob->object_to_world); - gps_duplicate->thickness = ceilf((float)gps_duplicate->thickness * scalef); + gps_duplicate->thickness = ceilf(float(gps_duplicate->thickness) * scalef); CLAMP_MIN(gps_duplicate->thickness, 1.0f); const bool is_normalized = ((params_.flag & GP_EXPORT_NORM_THICKNESS) != 0) || diff --git a/source/blender/modifiers/intern/MOD_array.cc b/source/blender/modifiers/intern/MOD_array.cc index 1478ca0ecc5..0acba6dd3f9 100644 --- a/source/blender/modifiers/intern/MOD_array.cc +++ b/source/blender/modifiers/intern/MOD_array.cc @@ -498,8 +498,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* Ensure we keep things to a reasonable level, in terms of rough total amount of generated * vertices. */ - if (((size_t)count * (size_t)chunk_nverts + (size_t)start_cap_nverts + - (size_t)end_cap_nverts) > max_verts_num) { + if ((size_t(count) * size_t(chunk_nverts) + size_t(start_cap_nverts) + + size_t(end_cap_nverts)) > max_verts_num) { count = 1; offset_is_too_small = true; } @@ -520,8 +520,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* Ensure we keep things to a reasonable level, in terms of rough total amount of generated * vertices. */ - else if (((size_t)count * (size_t)chunk_nverts + (size_t)start_cap_nverts + - (size_t)end_cap_nverts) > max_verts_num) { + else if ((size_t(count) * size_t(chunk_nverts) + size_t(start_cap_nverts) + + size_t(end_cap_nverts)) > max_verts_num) { count = 1; BKE_modifier_set_error(ctx->object, &amd->modifier, diff --git a/source/blender/nodes/composite/nodes/node_composite_bokehblur.cc b/source/blender/nodes/composite/nodes/node_composite_bokehblur.cc index f09bf1f5afd..e35974e9d81 100644 --- a/source/blender/nodes/composite/nodes/node_composite_bokehblur.cc +++ b/source/blender/nodes/composite/nodes/node_composite_bokehblur.cc @@ -195,7 +195,7 @@ class BokehBlurOperation : public NodeOperation { int get_max_size() { - return static_cast(bnode().custom4); + return int(bnode().custom4); } }; diff --git a/source/blender/nodes/texture/nodes/node_texture_bricks.cc b/source/blender/nodes/texture/nodes/node_texture_bricks.cc index 123f3d09c19..a1e906df9d0 100644 --- a/source/blender/nodes/texture/nodes/node_texture_bricks.cc +++ b/source/blender/nodes/texture/nodes/node_texture_bricks.cc @@ -64,14 +64,14 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor tex_input_rgba(bricks2, in[1], p, thread); tex_input_rgba(mortar, in[2], p, thread); - rownum = (int)floor(y / row_height); + rownum = int(floor(y / row_height)); if (node->custom1 && node->custom2) { - brick_width *= ((int)(rownum) % node->custom2) ? 1.0f : node->custom4; /* squash */ - offset = ((int)(rownum) % node->custom1) ? 0 : (brick_width * node->custom3); /* offset */ + brick_width *= (int(rownum) % node->custom2) ? 1.0f : node->custom4; /* squash */ + offset = (int(rownum) % node->custom1) ? 0 : (brick_width * node->custom3); /* offset */ } - bricknum = (int)floor((x + offset) / brick_width); + bricknum = int(floor((x + offset) / brick_width)); ins_x = (x + offset) - brick_width * bricknum; ins_y = y - row_height * rownum; diff --git a/source/blender/nodes/texture/nodes/node_texture_checker.cc b/source/blender/nodes/texture/nodes/node_texture_checker.cc index c3a6bf34d39..1b8c598a56f 100644 --- a/source/blender/nodes/texture/nodes/node_texture_checker.cc +++ b/source/blender/nodes/texture/nodes/node_texture_checker.cc @@ -28,9 +28,9 @@ static void colorfn(float *out, TexParams *p, bNode * /*node*/, bNodeStack **in, float sz = tex_input_value(in[2], p, thread); /* 0.00001 because of unit sized stuff */ - int xi = (int)fabs(floor(0.00001f + x / sz)); - int yi = (int)fabs(floor(0.00001f + y / sz)); - int zi = (int)fabs(floor(0.00001f + z / sz)); + int xi = int(fabs(floor(0.00001f + x / sz))); + int yi = int(fabs(floor(0.00001f + y / sz))); + int zi = int(fabs(floor(0.00001f + z / sz))); if ((xi % 2 == yi % 2) == (zi % 2)) { tex_input_rgba(out, in[0], p, thread); diff --git a/source/blender/nodes/texture/nodes/node_texture_curves.cc b/source/blender/nodes/texture/nodes/node_texture_curves.cc index b1554c03e51..56df9b52f87 100644 --- a/source/blender/nodes/texture/nodes/node_texture_curves.cc +++ b/source/blender/nodes/texture/nodes/node_texture_curves.cc @@ -20,7 +20,7 @@ static void time_colorfn( float fac = 0.0f; if (node->custom1 < node->custom2) { - fac = (p->cfra - node->custom1) / (float)(node->custom2 - node->custom1); + fac = (p->cfra - node->custom1) / float(node->custom2 - node->custom1); } CurveMapping *mapping = static_cast(node->storage); diff --git a/source/blender/nodes/texture/nodes/node_texture_image.cc b/source/blender/nodes/texture/nodes/node_texture_image.cc index ff348d934de..56edae9c023 100644 --- a/source/blender/nodes/texture/nodes/node_texture_image.cc +++ b/source/blender/nodes/texture/nodes/node_texture_image.cc @@ -33,8 +33,8 @@ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack ** /*in*/, ysize = ibuf->y / 2; xoff = yoff = -1; - px = (int)((x - xoff) * xsize); - py = (int)((y - yoff) * ysize); + px = int((x - xoff) * xsize); + py = int((y - yoff) * ysize); if ((!xsize) || (!ysize)) { return; diff --git a/source/blender/nodes/texture/nodes/node_texture_math.cc b/source/blender/nodes/texture/nodes/node_texture_math.cc index 61ba126cf07..ffda5511c7f 100644 --- a/source/blender/nodes/texture/nodes/node_texture_math.cc +++ b/source/blender/nodes/texture/nodes/node_texture_math.cc @@ -140,7 +140,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor break; } case NODE_MATH_ROUND: { - *out = (in0 < 0) ? (int)(in0 - 0.5f) : (int)(in0 + 0.5f); + *out = (in0 < 0) ? int(in0 - 0.5f) : int(in0 + 0.5f); break; } diff --git a/source/blender/render/intern/multires_bake.cc b/source/blender/render/intern/multires_bake.cc index 155096d890c..4ef71dc39a3 100644 --- a/source/blender/render/intern/multires_bake.cc +++ b/source/blender/render/intern/multires_bake.cc @@ -262,8 +262,8 @@ static void rasterize_half(const MBakeRast *bake_rast, SWAP(float, x_l, x_r); } - iXl = (int)ceilf(x_l); - iXr = (int)ceilf(x_r); + iXl = int(ceilf(x_l)); + iXr = int(ceilf(x_r)); if (iXr > 0 && iXl < w) { iXl = iXl < 0 ? 0 : iXl; @@ -313,9 +313,9 @@ static void bake_rasterize(const MBakeRast *bake_rast, /* check if mid point is to the left or to the right of the lo-hi edge */ is_mid_right = (-(shi - slo) * (tmi - thi) + (thi - tlo) * (smi - shi)) > 0 ? 1 : 0; - ylo = (int)ceilf(tlo); - yhi_beg = (int)ceilf(tmi); - yhi = (int)ceilf(thi); + ylo = int(ceilf(tlo)); + yhi_beg = int(ceilf(tmi)); + yhi = int(ceilf(thi)); // if (fTmi>ceilf(fTlo)) rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right); From fd068e92f1f4d6033c5f88a64b1ebef296e6d061 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 3 Jan 2023 11:14:55 +1100 Subject: [PATCH 0359/1522] Cleanup: use the ELEM macro --- source/blender/blenkernel/intern/mesh_normals.cc | 2 +- source/blender/blenkernel/intern/pbvh_uv_islands.cc | 2 +- source/blender/editors/transform/transform_mode_shear.c | 2 +- source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index 3db34786661..7d486a99406 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -972,7 +972,7 @@ static void loop_manifold_fan_around_vert_next(const Span loops, const uint vert_fan_next = loops[*r_mlfan_curr_index].v; const MPoly &mpfan_next = polys[*r_mpfan_curr_index]; if ((vert_fan_orig == vert_fan_next && vert_fan_orig == mv_pivot_index) || - (vert_fan_orig != vert_fan_next && vert_fan_orig != mv_pivot_index)) { + (!ELEM(vert_fan_orig, vert_fan_next, mv_pivot_index))) { /* We need the previous loop, but current one is our vertex's loop. */ *r_mlfan_vert_index = *r_mlfan_curr_index; if (--(*r_mlfan_curr_index) < mpfan_next.loopstart) { diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index 2f04ae63df4..15397170525 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -36,7 +36,7 @@ MeshUVVert *MeshPrimitive::get_other_uv_vertex(const MeshVertex *v1, const MeshV BLI_assert(vertices[0].vertex == v1 || vertices[1].vertex == v1 || vertices[2].vertex == v1); BLI_assert(vertices[0].vertex == v2 || vertices[1].vertex == v2 || vertices[2].vertex == v2); for (MeshUVVert &uv_vertex : vertices) { - if (uv_vertex.vertex != v1 && uv_vertex.vertex != v2) { + if (!ELEM(uv_vertex.vertex, v1, v2)) { return &uv_vertex; } } diff --git a/source/blender/editors/transform/transform_mode_shear.c b/source/blender/editors/transform/transform_mode_shear.c index ed49af4640d..edbeafc3ac7 100644 --- a/source/blender/editors/transform/transform_mode_shear.c +++ b/source/blender/editors/transform/transform_mode_shear.c @@ -263,7 +263,7 @@ static bool clip_uv_transform_shear(const TransInfo *t, float *vec, float *vec_i for (int i = 0; i < max_i; i++) { /* Binary search. */ const float value_mid = (value_inside_bounds + value) / 2.0f; - if (value_mid == value_inside_bounds || value_mid == value) { + if (ELEM(value_mid, value_inside_bounds, value)) { break; /* float precision reached. */ } if (uv_shear_in_clip_bounds_test(t, value_mid)) { diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c index b04fdeb0a83..68773886cf4 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c @@ -372,7 +372,7 @@ static void custom_range_header_draw(const bContext *UNUSED(C), Panel *panel) int mode = RNA_enum_get(ptr, "mode"); - uiLayoutSetActive(layout, (mode != GP_TIME_MODE_FIX && mode != GP_TIME_MODE_CHAIN)); + uiLayoutSetActive(layout, !ELEM(mode, GP_TIME_MODE_FIX, GP_TIME_MODE_CHAIN)); uiItemR(layout, ptr, "use_custom_frame_range", 0, NULL, ICON_NONE); } @@ -388,7 +388,7 @@ static void custom_range_panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); uiLayoutSetActive(layout, - (mode != GP_TIME_MODE_FIX && mode != GP_TIME_MODE_CHAIN) && + (!ELEM(mode, GP_TIME_MODE_FIX, GP_TIME_MODE_CHAIN)) && RNA_boolean_get(ptr, "use_custom_frame_range")); col = uiLayoutColumn(layout, true); From 0f2b1f9ec9013369beb73d95a02b1e5518a05b0e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 3 Jan 2023 11:37:51 +1100 Subject: [PATCH 0360/1522] Cleanup: add missing header to CMake --- source/blender/blenkernel/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index ec5c5a88b07..bfd9eaaa23e 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -452,6 +452,7 @@ set(SRC BKE_pbvh_pixels.hh BKE_pointcache.h BKE_pointcloud.h + BKE_pose_backup.h BKE_preferences.h BKE_report.h BKE_rigidbody.h From aad8f1a41bf3c50e657788c39020111c09683253 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 3 Jan 2023 11:51:40 +1100 Subject: [PATCH 0361/1522] Cleanup: use compliant YAML for '.clang-format' While clang-format could read the configuration file, it failed to load in `pyyaml` for e.g. --- .clang-format | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.clang-format b/.clang-format index 4c140988720..7e67aae1111 100644 --- a/.clang-format +++ b/.clang-format @@ -61,17 +61,17 @@ ContinuationIndentWidth: 4 # This tries to match Blender's style as much as possible. One BreakBeforeBraces: Custom BraceWrapping: { - AfterClass: 'false' - AfterControlStatement: 'false' - AfterEnum : 'false' - AfterFunction : 'true' - AfterNamespace : 'false' - AfterStruct : 'false' - AfterUnion : 'false' - BeforeCatch : 'true' - BeforeElse : 'true' - IndentBraces : 'false' - AfterObjCDeclaration: 'true' + AfterClass: 'false', + AfterControlStatement: 'false', + AfterEnum : 'false', + AfterFunction : 'true', + AfterNamespace : 'false', + AfterStruct : 'false', + AfterUnion : 'false', + BeforeCatch : 'true', + BeforeElse : 'true', + IndentBraces : 'false', + AfterObjCDeclaration: 'true', } # For switch statements, indent the cases. From 896ad9d5d0dba73a27664988497f97b8b087f257 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 3 Jan 2023 13:24:53 +1100 Subject: [PATCH 0362/1522] Cleanup: avoid F-string use in startup scripts --- release/scripts/startup/bl_ui/properties_animviz.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py index 73a2f947958..655f80b9c7c 100644 --- a/release/scripts/startup/bl_ui/properties_animviz.py +++ b/release/scripts/startup/bl_ui/properties_animviz.py @@ -57,19 +57,19 @@ class MotionPathButtonsPanel: # Update Selected. col = layout.column(align=True) row = col.row(align=True) - row.operator(f"{op_category}.paths_update", text="Update Path", icon=icon) - row.operator(f"{op_category}.paths_clear", text="", icon='X').only_selected = True + row.operator(op_category + ".paths_update", text="Update Path", icon=icon) + row.operator(op_category + ".paths_clear", text="", icon='X').only_selected = True else: # Calculate. col = layout.column(align=True) col.label(text="Nothing to show yet...", icon='ERROR') - col.operator(f"{op_category}.paths_calculate", text="Calculate...", icon=icon) + col.operator(op_category + ".paths_calculate", text="Calculate...", icon=icon) # Update All & Clear All. # Note that 'col' is from inside the preceeding `if` or `else` block. row = col.row(align=True) row.operator("object.paths_update_visible", text="Update All Paths", icon='WORLD') - row.operator(f"{op_category}.paths_clear", text="", icon='X').only_selected = False + row.operator(op_category + ".paths_clear", text="", icon='X').only_selected = False class MotionPathButtonsPanel_display: From 2e0cf17f94dcf6dc10f0d55d933c011534dc8421 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Tue, 3 Jan 2023 06:19:02 +0100 Subject: [PATCH 0363/1522] Fix T103601: Crash on making Contactsheet Python API for moving strips to and from meta strips did not invalidate strip lookup cache. Because of that, `SEQ_get_seqbase_by_seq()` failed to lookup origin of strip, which resulted in crash on NULL dereference. Invalidateion was added to functions `SEQ_edit_move_strip_to_meta()` and `SEQ_add_meta_strip()`. --- source/blender/makesrna/intern/rna_sequencer_api.c | 4 +++- source/blender/sequencer/intern/strip_add.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index ae241c11522..e1ccffdd2c1 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -22,7 +22,7 @@ #ifdef RNA_RUNTIME -//#include "DNA_anim_types.h" +// #include "DNA_anim_types.h" # include "DNA_image_types.h" # include "DNA_mask_types.h" # include "DNA_sound_types.h" @@ -83,6 +83,8 @@ static void rna_Sequences_move_strip_to_meta( DEG_relations_tag_update(bmain); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); + SEQ_sequence_lookup_tag(scene, SEQ_LOOKUP_TAG_INVALID); + WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, scene); } diff --git a/source/blender/sequencer/intern/strip_add.c b/source/blender/sequencer/intern/strip_add.c index d98a00aa9a5..7744bc4ce1c 100644 --- a/source/blender/sequencer/intern/strip_add.c +++ b/source/blender/sequencer/intern/strip_add.c @@ -367,6 +367,8 @@ Sequence *SEQ_add_meta_strip(Scene *scene, ListBase *seqbase, SeqLoadData *load_ seqm->start = load_data->start_frame; seqm->len = 1; + seq_add_generic_update(scene, seqm); + return seqm; } From e438e8e04ee83c194c4be9dea8560c53b3aee429 Mon Sep 17 00:00:00 2001 From: Pratik Borhade Date: Tue, 3 Jan 2023 14:56:11 +0530 Subject: [PATCH 0364/1522] Fix T102993: Incorrect icon displaying of Weighted Normal modifier in the outliner Mistake in {rBd15e8bdaa3343cf97a74f918b2570e66fb7abfa0} Reviewed by: JacquesLucke Differential Revision: https://developer.blender.org/D16890 --- source/blender/modifiers/intern/MOD_weighted_normal.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.cc b/source/blender/modifiers/intern/MOD_weighted_normal.cc index 2f68f00ce07..a7278d13093 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.cc +++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc @@ -738,7 +738,7 @@ ModifierTypeInfo modifierType_WeightedNormal = { /* type */ eModifierTypeType_Constructive, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* icon */ ICON_MOD_VERTEX_WEIGHT, + /* icon */ ICON_MOD_NORMALEDIT, /* copyData */ BKE_modifier_copydata_generic, From 101d04f41ffbb72bf20e7c2b15f1bb868328cd03 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Mon, 2 Jan 2023 15:27:00 +0100 Subject: [PATCH 0365/1522] Fix T103564: creating a color attribute doesn't make it active This was the case when done via the py-API. Now also set active_color_attribute / default_color_attribute on newly created attributes (in case none exist yet). Maniphest Tasks: T103564 Differential Revision: https://developer.blender.org/D16898 --- source/blender/makesrna/intern/rna_attribute.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c index f2afbdcce2b..67d0e8adef5 100644 --- a/source/blender/makesrna/intern/rna_attribute.c +++ b/source/blender/makesrna/intern/rna_attribute.c @@ -389,6 +389,17 @@ static PointerRNA rna_AttributeGroup_new( ID *id, ReportList *reports, const char *name, const int type, const int domain) { CustomDataLayer *layer = BKE_id_attribute_new(id, name, type, domain, reports); + + if ((GS(id->name) == ID_ME) && ELEM(layer->type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) { + Mesh *mesh = (Mesh *)id; + if (!mesh->active_color_attribute) { + mesh->active_color_attribute = BLI_strdup(layer->name); + } + if (!mesh->default_color_attribute) { + mesh->default_color_attribute = BLI_strdup(layer->name); + } + } + DEG_id_tag_update(id, ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, id); From 0f8487f640edd754de21cffec2dc6c9a1db7234c Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 3 Jan 2023 12:24:00 +0100 Subject: [PATCH 0366/1522] Geometry Nodes: add more details about field handling to node declaration This is part of D16858 but is also useful for other purposes. The changes to the node declaration in this commit allow us to figure out which fields might be evaluated on which geometries statically (without executing the node tree). This allows for deterministic anonymous attribute handling, which will be committed separately. Furthermore, this is necessary for usability features that help the user to avoid creating links that don't make sense (e.g. because a field can't be evaluated on a certain geometry). This also allows us to better separate fields which depend or don't depend on anonymous attributes. The main idea is that each node defines some relations between its sockets. There are four relations: * Propagate relation: Indicates that attributes on a geometry input can be propagated to a geometry output. * Reference relation: Indicates that an output field references an inputs field. So if the input field depends on an anonymous attribute, the output field does as well. * Eval relation: Indicates that an input field is evaluated on an input geometry. * Available relation: Indicates that an output field has anonymous attributes that are available on an output geometry. These relations can also be computed for node groups automatically, but that is not part of this commit. --- source/blender/nodes/NOD_node_declaration.hh | 224 +++++++++++++++++- .../nodes/node_geo_accumulate_field.cc | 18 +- .../nodes/node_geo_attribute_capture.cc | 22 +- .../nodes/node_geo_attribute_statistic.cc | 6 +- .../geometry/nodes/node_geo_blur_attribute.cc | 14 +- .../nodes/geometry/nodes/node_geo_boolean.cc | 4 +- .../node_geo_curve_endpoint_selection.cc | 2 +- .../geometry/nodes/node_geo_curve_fillet.cc | 6 +- .../nodes/node_geo_curve_primitive_star.cc | 2 +- .../geometry/nodes/node_geo_curve_resample.cc | 8 +- .../geometry/nodes/node_geo_curve_reverse.cc | 4 +- .../geometry/nodes/node_geo_curve_sample.cc | 16 +- .../nodes/node_geo_curve_set_handle_type.cc | 4 +- .../nodes/node_geo_curve_spline_type.cc | 4 +- .../nodes/node_geo_curve_subdivide.cc | 4 +- .../geometry/nodes/node_geo_curve_to_mesh.cc | 2 +- .../nodes/node_geo_curve_to_points.cc | 8 +- .../node_geo_curve_topology_curve_of_point.cc | 4 +- ...node_geo_curve_topology_points_of_curve.cc | 5 +- .../geometry/nodes/node_geo_curve_trim.cc | 10 +- .../node_geo_deform_curves_on_surface.cc | 2 +- .../nodes/node_geo_delete_geometry.cc | 4 +- .../node_geo_distribute_points_in_volume.cc | 2 +- .../node_geo_distribute_points_on_faces.cc | 12 +- .../geometry/nodes/node_geo_dual_mesh.cc | 2 +- .../nodes/node_geo_duplicate_elements.cc | 7 +- .../nodes/node_geo_edge_paths_to_curves.cc | 6 +- .../nodes/node_geo_edge_paths_to_selection.cc | 2 +- .../geometry/nodes/node_geo_edge_split.cc | 4 +- .../geometry/nodes/node_geo_extrude_mesh.cc | 10 +- .../geometry/nodes/node_geo_field_at_index.cc | 10 +- .../geometry/nodes/node_geo_flip_faces.cc | 4 +- .../nodes/node_geo_geometry_to_instance.cc | 2 +- .../geometry/nodes/node_geo_image_texture.cc | 4 +- .../nodes/node_geo_input_curve_handles.cc | 4 +- .../nodes/node_geo_instance_on_points.cc | 12 +- .../nodes/node_geo_instances_to_points.cc | 8 +- .../nodes/node_geo_interpolate_domain.cc | 10 +- .../geometry/nodes/node_geo_join_geometry.cc | 2 +- .../nodes/node_geo_material_replace.cc | 2 +- .../nodes/node_geo_merge_by_distance.cc | 4 +- .../node_geo_mesh_face_set_boundaries.cc | 2 +- .../nodes/node_geo_mesh_primitive_cone.cc | 8 +- .../nodes/node_geo_mesh_primitive_cube.cc | 2 +- .../nodes/node_geo_mesh_primitive_cylinder.cc | 8 +- .../nodes/node_geo_mesh_primitive_grid.cc | 2 +- .../node_geo_mesh_primitive_ico_sphere.cc | 2 +- .../node_geo_mesh_primitive_uv_sphere.cc | 2 +- .../geometry/nodes/node_geo_mesh_subdivide.cc | 2 +- .../geometry/nodes/node_geo_mesh_to_curve.cc | 4 +- .../geometry/nodes/node_geo_mesh_to_points.cc | 6 +- .../node_geo_mesh_topology_corners_of_face.cc | 5 +- ...ode_geo_mesh_topology_corners_of_vertex.cc | 5 +- .../node_geo_mesh_topology_edges_of_corner.cc | 4 +- .../node_geo_mesh_topology_edges_of_vertex.cc | 5 +- .../node_geo_mesh_topology_face_of_corner.cc | 4 +- ...geo_mesh_topology_offset_corner_in_face.cc | 2 +- ...node_geo_mesh_topology_vertex_of_corner.cc | 2 +- .../nodes/node_geo_offset_point_in_curve.cc | 4 +- .../nodes/node_geo_points_to_vertices.cc | 4 +- .../nodes/node_geo_points_to_volume.cc | 2 +- .../geometry/nodes/node_geo_proximity.cc | 4 +- .../nodes/geometry/nodes/node_geo_raycast.cc | 10 +- .../nodes/node_geo_realize_instances.cc | 2 +- .../nodes/node_geo_remove_attribute.cc | 2 +- .../nodes/node_geo_rotate_instances.cc | 10 +- .../geometry/nodes/node_geo_sample_index.cc | 10 +- .../nodes/node_geo_sample_nearest_surface.cc | 10 +- .../nodes/node_geo_sample_uv_surface.cc | 12 +- .../geometry/nodes/node_geo_scale_elements.cc | 10 +- .../nodes/node_geo_scale_instances.cc | 13 +- .../nodes/node_geo_separate_components.cc | 10 +- .../nodes/node_geo_separate_geometry.cc | 4 +- .../nodes/node_geo_set_curve_handles.cc | 18 +- .../nodes/node_geo_set_curve_normal.cc | 4 +- .../nodes/node_geo_set_curve_radius.cc | 4 +- .../geometry/nodes/node_geo_set_curve_tilt.cc | 6 +- .../nodes/geometry/nodes/node_geo_set_id.cc | 6 +- .../geometry/nodes/node_geo_set_material.cc | 4 +- .../nodes/node_geo_set_material_index.cc | 6 +- .../nodes/node_geo_set_point_radius.cc | 6 +- .../geometry/nodes/node_geo_set_position.cc | 8 +- .../nodes/node_geo_set_shade_smooth.cc | 6 +- .../nodes/node_geo_set_spline_cyclic.cc | 6 +- .../nodes/node_geo_set_spline_resolution.cc | 6 +- .../nodes/node_geo_store_named_attribute.cc | 12 +- .../nodes/node_geo_string_to_curves.cc | 4 +- .../nodes/node_geo_subdivision_surface.cc | 6 +- .../nodes/geometry/nodes/node_geo_switch.cc | 14 +- .../nodes/node_geo_transform_geometry.cc | 2 +- .../nodes/node_geo_translate_instances.cc | 8 +- .../geometry/nodes/node_geo_triangulate.cc | 4 +- .../nodes/node_geo_uv_pack_islands.cc | 2 +- .../geometry/nodes/node_geo_uv_unwrap.cc | 2 +- .../nodes/geometry/nodes/node_geo_viewer.cc | 10 +- .../blender/nodes/intern/node_declaration.cc | 108 ++++++++- 96 files changed, 615 insertions(+), 289 deletions(-) diff --git a/source/blender/nodes/NOD_node_declaration.hh b/source/blender/nodes/NOD_node_declaration.hh index 7753e8092d8..080f3e5e855 100644 --- a/source/blender/nodes/NOD_node_declaration.hh +++ b/source/blender/nodes/NOD_node_declaration.hh @@ -65,6 +65,76 @@ struct FieldInferencingInterface { Vector outputs; }; +namespace anonymous_attribute_lifetime { + +/** + * Attributes can be propagated from an input geometry to an output geometry. + */ +struct PropagateRelation { + int from_geometry_input; + int to_geometry_output; + + friend bool operator==(const PropagateRelation &a, const PropagateRelation &b) + { + return a.from_geometry_input == b.from_geometry_input && + a.to_geometry_output == b.to_geometry_output; + } +}; + +/** + * References to attributes can be propagated from an input field to an output field. + */ +struct ReferenceRelation { + int from_field_input; + int to_field_output; + + friend bool operator==(const ReferenceRelation &a, const ReferenceRelation &b) + { + return a.from_field_input == b.from_field_input && a.to_field_output == b.to_field_output; + } +}; + +/** + * An input field is evaluated on an input geometry. + */ +struct EvalRelation { + int field_input; + int geometry_input; + + friend bool operator==(const EvalRelation &a, const EvalRelation &b) + { + return a.field_input == b.field_input && a.geometry_input == b.geometry_input; + } +}; + +/** + * An output field is available on an output geometry. + */ +struct AvailableRelation { + int field_output; + int geometry_output; + + friend bool operator==(const AvailableRelation &a, const AvailableRelation &b) + { + return a.field_output == b.field_output && a.geometry_output == b.geometry_output; + } +}; + +struct RelationsInNode { + Vector propagate_relations; + Vector reference_relations; + Vector eval_relations; + Vector available_relations; + Vector available_on_none; +}; + +bool operator==(const RelationsInNode &a, const RelationsInNode &b); +bool operator!=(const RelationsInNode &a, const RelationsInNode &b); +std::ostream &operator<<(std::ostream &stream, const RelationsInNode &relations); + +} // namespace anonymous_attribute_lifetime +namespace aal = anonymous_attribute_lifetime; + using ImplicitInputValueFn = std::function; /** @@ -146,9 +216,23 @@ class SocketDeclaration { bool matches_common_data(const bNodeSocket &socket) const; }; +class NodeDeclarationBuilder; + class BaseSocketDeclarationBuilder { + protected: + int index_ = -1; + bool reference_pass_all_ = false; + bool field_on_all_ = false; + bool propagate_from_all_ = false; + NodeDeclarationBuilder *node_decl_builder_ = nullptr; + + friend class NodeDeclarationBuilder; + public: virtual ~BaseSocketDeclarationBuilder() = default; + + protected: + virtual SocketDeclaration *declaration() = 0; }; /** @@ -225,6 +309,26 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder { return *(Self *)this; } + /** + * For inputs this means that the input field is evaluated on all geometry inputs. For outputs + * it means that this contains an anonymous attribute reference that is available on all geometry + * outputs. + */ + Self &field_on_all() + { + if (decl_->in_out == SOCK_IN) { + this->supports_field(); + } + else { + this->field_source(); + } + field_on_all_ = true; + return *(Self *)this; + } + + /** For inputs that are evaluated or available on a subset of the geometry sockets. */ + Self &field_on(Span indices); + /** The input supports a field and is a field by default when nothing is connected. */ Self &implicit_field(ImplicitInputValueFn fn) { @@ -234,6 +338,22 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder { return *(Self *)this; } + /** The input is an implicit field that is evaluated on all geometry inputs. */ + Self &implicit_field_on_all(ImplicitInputValueFn fn) + { + this->implicit_field(fn); + field_on_all_ = true; + return *(Self *)this; + } + + /** The input is evaluated on a subset of the geometry inputs. */ + Self &implicit_field_on(ImplicitInputValueFn fn, const Span input_indices) + { + this->implicit_field(fn); + this->field_on(input_indices); + return *(Self *)this; + } + /** The output is always a field, regardless of any inputs. */ Self &field_source() { @@ -241,21 +361,55 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder { return *(Self *)this; } - /** The output is a field if any of the inputs is a field. */ + /** The output is a field if any of the inputs are a field. */ Self &dependent_field() { decl_->output_field_dependency = OutputFieldDependency::ForDependentField(); + this->reference_pass_all(); return *(Self *)this; } /** The output is a field if any of the inputs with indices in the given list is a field. */ Self &dependent_field(Vector input_dependencies) { + this->reference_pass(input_dependencies); decl_->output_field_dependency = OutputFieldDependency::ForPartiallyDependentField( std::move(input_dependencies)); return *(Self *)this; } + /** + * For outputs that combine all input fields into a new field. The output is a field even if none + * of the inputs is a field. + */ + Self &field_source_reference_all() + { + this->field_source(); + this->reference_pass_all(); + return *(Self *)this; + } + + /** + * For outputs that combine a subset of input fields into a new field. + */ + Self &reference_pass(Span input_indices); + + /** + * For outputs that combine all input fields into a new field. + */ + Self &reference_pass_all() + { + reference_pass_all_ = true; + return *(Self *)this; + } + + /** Attributes from the all geometry inputs can be propagated. */ + Self &propagate_all() + { + propagate_from_all_ = true; + return *(Self *)this; + } + /** The priority of the input for determining the domain of the node. See * realtime_compositor::InputDescriptor for more information. */ Self &compositor_domain_priority(int priority) @@ -291,6 +445,12 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder { decl_->make_available_fn_ = std::move(fn); return *(Self *)this; } + + protected: + SocketDeclaration *declaration() override + { + return decl_; + } }; using SocketDeclarationPtr = std::unique_ptr; @@ -299,19 +459,26 @@ class NodeDeclaration { public: Vector inputs; Vector outputs; + std::unique_ptr anonymous_attribute_relations_; friend NodeDeclarationBuilder; bool matches(const bNode &node) const; Span sockets(eNodeSocketInOut in_out) const; + const aal::RelationsInNode *anonymous_attribute_relations() const + { + return anonymous_attribute_relations_.get(); + } + MEM_CXX_CLASS_ALLOC_FUNCS("NodeDeclaration") }; class NodeDeclarationBuilder { private: NodeDeclaration &declaration_; - Vector> builders_; + Vector> input_builders_; + Vector> output_builders_; bool is_function_node_ = false; public: @@ -333,6 +500,14 @@ class NodeDeclarationBuilder { template typename DeclType::Builder &add_output(StringRef name, StringRef identifier = ""); + aal::RelationsInNode &get_anonymous_attribute_relations() + { + if (!declaration_.anonymous_attribute_relations_) { + declaration_.anonymous_attribute_relations_ = std::make_unique(); + } + return *declaration_.anonymous_attribute_relations_; + } + private: template typename DeclType::Builder &add_socket(StringRef name, @@ -349,6 +524,44 @@ void id_or_index(const bNode &node, void *r_value); void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declaration); +template +typename SocketDeclarationBuilder::Self &SocketDeclarationBuilder< + SocketDecl>::reference_pass(const Span input_indices) +{ + aal::RelationsInNode &relations = node_decl_builder_->get_anonymous_attribute_relations(); + for (const int from_input : input_indices) { + aal::ReferenceRelation relation; + relation.from_field_input = from_input; + relation.to_field_output = index_; + relations.reference_relations.append(relation); + } + return *(Self *)this; +} + +template +typename SocketDeclarationBuilder::Self &SocketDeclarationBuilder< + SocketDecl>::field_on(const Span indices) +{ + aal::RelationsInNode &relations = node_decl_builder_->get_anonymous_attribute_relations(); + if (decl_->in_out == SOCK_IN) { + for (const int input_index : indices) { + aal::EvalRelation relation; + relation.field_input = index_; + relation.geometry_input = input_index; + relations.eval_relations.append(relation); + } + } + else { + for (const int output_index : indices) { + aal::AvailableRelation relation; + relation.field_output = index_; + relation.geometry_output = output_index; + relations.available_relations.append(relation); + } + } + return *(Self *)this; +} + /* -------------------------------------------------------------------- */ /** \name #OutputFieldDependency Inline Methods * \{ */ @@ -490,12 +703,15 @@ inline typename DeclType::Builder &NodeDeclarationBuilder::add_socket(StringRef std::unique_ptr socket_decl = std::make_unique(); std::unique_ptr socket_decl_builder = std::make_unique(); socket_decl_builder->decl_ = &*socket_decl; + + socket_decl_builder->node_decl_builder_ = this; socket_decl->name = name; socket_decl->identifier = identifier.is_empty() ? name : identifier; socket_decl->in_out = in_out; - declarations.append(std::move(socket_decl)); + socket_decl_builder->index_ = declarations.append_and_get_index(std::move(socket_decl)); Builder &socket_decl_builder_ref = *socket_decl_builder; - builders_.append(std::move(socket_decl_builder)); + ((in_out == SOCK_IN) ? input_builders_ : output_builders_) + .append(std::move(socket_decl_builder)); return socket_decl_builder_ref; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc b/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc index 33a58cada1b..1293dd9c0d2 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc @@ -40,33 +40,33 @@ static void node_declare(NodeDeclarationBuilder &b) N_("An index used to group values together for multiple separate accumulations")); b.add_output(N_("Leading"), "Leading Vector") - .field_source() + .field_source_reference_all() .description(N_(leading_out_description)); b.add_output(N_("Leading"), "Leading Float") - .field_source() + .field_source_reference_all() .description(N_(leading_out_description)); b.add_output(N_("Leading"), "Leading Int") - .field_source() + .field_source_reference_all() .description(N_(leading_out_description)); b.add_output(N_("Trailing"), "Trailing Vector") - .field_source() + .field_source_reference_all() .description(N_(trailing_out_description)); b.add_output(N_("Trailing"), "Trailing Float") - .field_source() + .field_source_reference_all() .description(N_(trailing_out_description)); b.add_output(N_("Trailing"), "Trailing Int") - .field_source() + .field_source_reference_all() .description(N_(trailing_out_description)); b.add_output(N_("Total"), "Total Vector") - .field_source() + .field_source_reference_all() .description(N_(total_out_description)); b.add_output(N_("Total"), "Total Float") - .field_source() + .field_source_reference_all() .description(N_(total_out_description)); b.add_output(N_("Total"), "Total Int") - .field_source() + .field_source_reference_all() .description(N_(total_out_description)); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc index 76709f0463d..826f08e4c8d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc @@ -16,18 +16,18 @@ NODE_STORAGE_FUNCS(NodeGeometryAttributeCapture) static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")); - b.add_input(N_("Value")).supports_field(); - b.add_input(N_("Value"), "Value_001").supports_field(); - b.add_input(N_("Value"), "Value_002").supports_field(); - b.add_input(N_("Value"), "Value_003").supports_field(); - b.add_input(N_("Value"), "Value_004").supports_field(); + b.add_input(N_("Value")).field_on_all(); + b.add_input(N_("Value"), "Value_001").field_on_all(); + b.add_input(N_("Value"), "Value_002").field_on_all(); + b.add_input(N_("Value"), "Value_003").field_on_all(); + b.add_input(N_("Value"), "Value_004").field_on_all(); - b.add_output(N_("Geometry")); - b.add_output(N_("Attribute")).field_source(); - b.add_output(N_("Attribute"), "Attribute_001").field_source(); - b.add_output(N_("Attribute"), "Attribute_002").field_source(); - b.add_output(N_("Attribute"), "Attribute_003").field_source(); - b.add_output(N_("Attribute"), "Attribute_004").field_source(); + b.add_output(N_("Geometry")).propagate_all(); + b.add_output(N_("Attribute")).field_on_all(); + b.add_output(N_("Attribute"), "Attribute_001").field_on_all(); + b.add_output(N_("Attribute"), "Attribute_002").field_on_all(); + b.add_output(N_("Attribute"), "Attribute_003").field_on_all(); + b.add_output(N_("Attribute"), "Attribute_004").field_on_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc index 090ff6aff30..4275b684a23 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_statistic.cc @@ -17,9 +17,9 @@ namespace blender::nodes::node_geo_attribute_statistic_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")); - b.add_input(N_("Selection")).default_value(true).supports_field().hide_value(); - b.add_input(N_("Attribute")).hide_value().supports_field(); - b.add_input(N_("Attribute"), "Attribute_001").hide_value().supports_field(); + b.add_input(N_("Selection")).default_value(true).field_on_all().hide_value(); + b.add_input(N_("Attribute")).hide_value().field_on_all(); + b.add_input(N_("Attribute"), "Attribute_001").hide_value().field_on_all(); b.add_output(N_("Mean")); b.add_output(N_("Median")); diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc index ef6ec91922a..661ed933650 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc @@ -58,10 +58,16 @@ static void node_declare(NodeDeclarationBuilder &b) .supports_field() .description(N_("Relative mix weight of neighboring elements")); - b.add_output(N_("Value"), "Value_Float").field_source().dependent_field(); - b.add_output(N_("Value"), "Value_Int").field_source().dependent_field(); - b.add_output(N_("Value"), "Value_Vector").field_source().dependent_field(); - b.add_output(N_("Value"), "Value_Color").field_source().dependent_field(); + b.add_output(N_("Value"), "Value_Float") + .field_source_reference_all() + .dependent_field(); + b.add_output(N_("Value"), "Value_Int").field_source_reference_all().dependent_field(); + b.add_output(N_("Value"), "Value_Vector") + .field_source_reference_all() + .dependent_field(); + b.add_output(N_("Value"), "Value_Color") + .field_source_reference_all() + .dependent_field(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc index dcae073acdd..a1c4af79851 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc @@ -20,8 +20,8 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input(N_("Mesh 2")).multi_input().supported_type(GEO_COMPONENT_TYPE_MESH); b.add_input(N_("Self Intersection")); b.add_input(N_("Hole Tolerant")); - b.add_output(N_("Mesh")); - b.add_output(N_("Intersecting Edges")).field_source(); + b.add_output(N_("Mesh")).propagate_all(); + b.add_output(N_("Intersecting Edges")).field_on_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc index 4161ec7e7ad..25bb5473843 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc @@ -22,7 +22,7 @@ static void node_declare(NodeDeclarationBuilder &b) .supports_field() .description(N_("The amount of points to select from the end of each spline")); b.add_output(N_("Selection")) - .field_source() + .field_source_reference_all() .description( N_("The selection from the start and end of the splines based on the input sizes")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc index 7a6fa799013..ef839bf2acb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc @@ -18,18 +18,18 @@ static void node_declare(NodeDeclarationBuilder &b) .default_value(1) .min(1) .max(1000) - .supports_field() + .field_on_all() .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_FILLET_POLY; }); b.add_input(N_("Radius")) .min(0.0f) .max(FLT_MAX) .subtype(PropertySubType::PROP_DISTANCE) .default_value(0.25f) - .supports_field(); + .field_on_all(); b.add_input(N_("Limit Radius")) .description( N_("Limit the maximum value of the radius in order to avoid overlapping fillets")); - b.add_output(N_("Curve")); + b.add_output(N_("Curve")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc index 286d9993d0e..13353553379 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc @@ -29,7 +29,7 @@ static void node_declare(NodeDeclarationBuilder &b) .description(N_("The counterclockwise rotation of the inner set of points")); b.add_output(N_("Curve")); b.add_output(N_("Outer Points")) - .field_source() + .field_on_all() .description(N_("An attribute field with a selection of the outer points")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc index 23a71af448d..7d54f33d555 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_resample.cc @@ -16,14 +16,14 @@ NODE_STORAGE_FUNCS(NodeGeometryCurveResample) static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE); - b.add_input(N_("Selection")).default_value(true).supports_field().hide_value(); - b.add_input(N_("Count")).default_value(10).min(1).max(100000).supports_field(); + b.add_input(N_("Selection")).default_value(true).field_on_all().hide_value(); + b.add_input(N_("Count")).default_value(10).min(1).max(100000).field_on_all(); b.add_input(N_("Length")) .default_value(0.1f) .min(0.01f) - .supports_field() + .field_on_all() .subtype(PROP_DISTANCE); - b.add_output(N_("Curve")); + b.add_output(N_("Curve")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc index 040ebf55ec5..311f2353391 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_reverse.cc @@ -11,8 +11,8 @@ namespace blender::nodes::node_geo_curve_reverse_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_output(N_("Curve")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_output(N_("Curve")).propagate_all(); } static void node_geo_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc index 2798089197a..77952938827 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc @@ -23,24 +23,24 @@ static void node_declare(NodeDeclarationBuilder &b) .only_realized_data() .supported_type(GEO_COMPONENT_TYPE_CURVE); - b.add_input(N_("Value"), "Value_Float").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Int").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Vector").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Color").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Bool").hide_value().supports_field(); + b.add_input(N_("Value"), "Value_Float").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Int").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Vector").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Color").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Bool").hide_value().field_on_all(); b.add_input(N_("Factor")) .min(0.0f) .max(1.0f) .subtype(PROP_FACTOR) - .supports_field() + .field_on_all() .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_FACTOR; }); b.add_input(N_("Length")) .min(0.0f) .subtype(PROP_DISTANCE) - .supports_field() + .field_on_all() .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_LENGTH; }); - b.add_input(N_("Curve Index")).supports_field().make_available([](bNode &node) { + b.add_input(N_("Curve Index")).field_on_all().make_available([](bNode &node) { node_storage(node).use_all_curves = false; }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc index 46377329fb4..6a6e12642c5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_set_handle_type.cc @@ -16,8 +16,8 @@ NODE_STORAGE_FUNCS(NodeGeometryCurveSetHandles) static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_output(N_("Curve")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_output(N_("Curve")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc index 4b8251aadd3..3d8d14473db 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc @@ -16,8 +16,8 @@ NODE_STORAGE_FUNCS(NodeGeometryCurveSplineType) static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_output(N_("Curve")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_output(N_("Curve")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc index 5a1d2461c72..b01dd2e5361 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc @@ -18,10 +18,10 @@ static void node_declare(NodeDeclarationBuilder &b) .default_value(1) .min(0) .max(1000) - .supports_field() + .field_on_all() .description( N_("The number of control points to create on the segment following each point")); - b.add_output(N_("Curve")); + b.add_output(N_("Curve")).propagate_all(); } static void node_geo_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc index bee30c1fd99..057496144d5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc @@ -20,7 +20,7 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input(N_("Fill Caps")) .description( N_("If the profile spline is cyclic, fill the ends of the generated mesh with N-gons")); - b.add_output(N_("Mesh")); + b.add_output(N_("Mesh")).propagate_all(); } static void geometry_set_curve_to_mesh(GeometrySet &geometry_set, diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc index 268c927f782..4442dfa0fdb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc @@ -34,10 +34,10 @@ static void node_declare(NodeDeclarationBuilder &b) .subtype(PROP_DISTANCE) .make_available( [](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_RESAMPLE_LENGTH; }); - b.add_output(N_("Points")); - b.add_output(N_("Tangent")).field_source(); - b.add_output(N_("Normal")).field_source(); - b.add_output(N_("Rotation")).field_source(); + b.add_output(N_("Points")).propagate_all(); + b.add_output(N_("Tangent")).field_on_all(); + b.add_output(N_("Normal")).field_on_all(); + b.add_output(N_("Rotation")).field_on_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc index 459f45ef8fb..e771f11e43d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_curve_of_point.cc @@ -12,10 +12,10 @@ static void node_declare(NodeDeclarationBuilder &b) .implicit_field(implicit_field_inputs::index) .description(N_("The control point to retrieve data from")); b.add_output(N_("Curve Index")) - .dependent_field() + .field_source_reference_all() .description(N_("The curve the control point is part of")); b.add_output(N_("Index in Curve")) - .dependent_field() + .field_source_reference_all() .description(N_("How far along the control point is along its curve")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc index 7f69503831f..df917f6f831 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc @@ -22,10 +22,11 @@ static void node_declare(NodeDeclarationBuilder &b) .supports_field() .description(N_("Which of the sorted points to output")); b.add_output(N_("Point Index")) - .dependent_field() + .field_source_reference_all() .description(N_("A point of the curve, chosen by the sort index")); b.add_output(N_("Total")) - .dependent_field() + .field_source() + .reference_pass({0}) .description(N_("The number of points in the curve")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc index 6b8c0c6b967..97b72838b39 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc @@ -25,26 +25,26 @@ static void node_declare(NodeDeclarationBuilder &b) .max(1.0f) .subtype(PROP_FACTOR) .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_FACTOR; }) - .supports_field(); + .field_on_all(); b.add_input(N_("End")) .min(0.0f) .max(1.0f) .default_value(1.0f) .subtype(PROP_FACTOR) .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_FACTOR; }) - .supports_field(); + .field_on_all(); b.add_input(N_("Start"), "Start_001") .min(0.0f) .subtype(PROP_DISTANCE) .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_LENGTH; }) - .supports_field(); + .field_on_all(); b.add_input(N_("End"), "End_001") .min(0.0f) .default_value(1.0f) .subtype(PROP_DISTANCE) .make_available([](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_SAMPLE_LENGTH; }) - .supports_field(); - b.add_output(N_("Curve")); + .field_on_all(); + b.add_output(N_("Curve")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc index d926e7e4e30..4e38cbf2a28 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc @@ -38,7 +38,7 @@ NODE_STORAGE_FUNCS(NodeGeometryCurveTrim) static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Curves")).supported_type(GEO_COMPONENT_TYPE_CURVE); - b.add_output(N_("Curves")); + b.add_output(N_("Curves")).propagate_all(); } static void deform_curves(const CurvesGeometry &curves, diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc index a9f1de12672..92937482116 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc @@ -1130,9 +1130,9 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input(N_("Selection")) .default_value(true) .hide_value() - .supports_field() + .field_on_all() .description(N_("The parts of the geometry to be deleted")); - b.add_output(N_("Geometry")); + b.add_output(N_("Geometry")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc index b0c46c94396..972be612339 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_in_volume.cc @@ -46,7 +46,7 @@ static void node_declare(NodeDeclarationBuilder &b) .min(0.0f) .max(FLT_MAX) .description(N_("Minimum density of a volume cell to contain a grid point")); - b.add_output(N_("Points")); + b.add_output(N_("Points")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc index 7c9501608a3..a5bdc989a04 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc @@ -34,7 +34,7 @@ static void node_declare(NodeDeclarationBuilder &b) }; b.add_input(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); b.add_input(N_("Distance Min")) .min(0.0f) .subtype(PROP_DISTANCE) @@ -46,20 +46,20 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input(N_("Density")) .default_value(10.0f) .min(0.0f) - .supports_field() + .field_on_all() .make_available(enable_random); b.add_input(N_("Density Factor")) .default_value(1.0f) .min(0.0f) .max(1.0f) .subtype(PROP_FACTOR) - .supports_field() + .field_on_all() .make_available(enable_poisson); b.add_input(N_("Seed")); - b.add_output(N_("Points")); - b.add_output(N_("Normal")).field_source(); - b.add_output(N_("Rotation")).subtype(PROP_EULER).field_source(); + b.add_output(N_("Points")).propagate_all(); + b.add_output(N_("Normal")).field_on_all(); + b.add_output(N_("Rotation")).subtype(PROP_EULER).field_on_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc index e692ca69cf0..bb48db48559 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc @@ -22,7 +22,7 @@ static void node_declare(NodeDeclarationBuilder &b) .description( "Keep non-manifold boundaries of the input mesh in place by avoiding the dual " "transformation there"); - b.add_output("Dual Mesh"); + b.add_output("Dual Mesh").propagate_all(); } enum class EdgeType : int8_t { diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index 7e91c65c78f..a53f92e3b9f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -28,17 +28,18 @@ NODE_STORAGE_FUNCS(NodeGeometryDuplicateElements); static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")); - b.add_input(N_("Selection")).hide_value().default_value(true).supports_field(); + b.add_input(N_("Selection")).hide_value().default_value(true).field_on_all(); b.add_input(N_("Amount")) .min(0) .default_value(1) - .supports_field() + .field_on_all() .description(N_("The number of duplicates to create for each element")); b.add_output(N_("Geometry")) + .propagate_all() .description(N_("The duplicated geometry, not including the original geometry")); b.add_output(N_("Duplicate Index")) - .field_source() + .field_on_all() .description(N_("The indices of the duplicates for each element")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc index ba09acf0bf0..c70d45ce334 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc @@ -13,9 +13,9 @@ namespace blender::nodes::node_geo_edge_paths_to_curves_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Start Vertices")).default_value(true).hide_value().supports_field(); - b.add_input(N_("Next Vertex Index")).default_value(-1).hide_value().supports_field(); - b.add_output(N_("Curves")); + b.add_input(N_("Start Vertices")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("Next Vertex Index")).default_value(-1).hide_value().field_on_all(); + b.add_output(N_("Curves")).propagate_all(); } static Curves *edge_paths_to_curves_convert(const Mesh &mesh, diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc index f0bd01a012b..5cfb0639813 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc @@ -17,7 +17,7 @@ static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Start Vertices")).default_value(true).hide_value().supports_field(); b.add_input(N_("Next Vertex Index")).default_value(-1).hide_value().supports_field(); - b.add_output(N_("Selection")).field_source(); + b.add_output(N_("Selection")).field_source_reference_all(); } static void edge_paths_to_selection(const Mesh &src_mesh, diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc index 88ec358d9ac..057c09c9936 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc @@ -11,8 +11,8 @@ namespace blender::nodes::node_geo_edge_split_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_output(N_("Mesh")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_output(N_("Mesh")).propagate_all(); } static void node_geo_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index d390a33245d..a36413e49b2 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -24,16 +24,16 @@ NODE_STORAGE_FUNCS(NodeGeometryExtrudeMesh) static void node_declare(NodeDeclarationBuilder &b) { b.add_input("Mesh").supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Selection")).default_value(true).supports_field().hide_value(); + b.add_input(N_("Selection")).default_value(true).field_on_all().hide_value(); b.add_input(N_("Offset")) .subtype(PROP_TRANSLATION) .implicit_field(implicit_field_inputs::normal) .hide_value(); - b.add_input(N_("Offset Scale")).default_value(1.0f).supports_field(); + b.add_input(N_("Offset Scale")).default_value(1.0f).field_on_all(); b.add_input(N_("Individual")).default_value(true); - b.add_output("Mesh"); - b.add_output(N_("Top")).field_source(); - b.add_output(N_("Side")).field_source(); + b.add_output("Mesh").propagate_all(); + b.add_output(N_("Top")).field_on_all(); + b.add_output(N_("Side")).field_on_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc index a6820444f73..99554c4d10c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc @@ -80,11 +80,11 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input(N_("Value"), "Value_Color").hide_value().supports_field(); b.add_input(N_("Value"), "Value_Bool").hide_value().supports_field(); - b.add_output(N_("Value"), "Value_Float").field_source(); - b.add_output(N_("Value"), "Value_Int").field_source(); - b.add_output(N_("Value"), "Value_Vector").field_source(); - b.add_output(N_("Value"), "Value_Color").field_source(); - b.add_output(N_("Value"), "Value_Bool").field_source(); + b.add_output(N_("Value"), "Value_Float").field_source_reference_all(); + b.add_output(N_("Value"), "Value_Int").field_source_reference_all(); + b.add_output(N_("Value"), "Value_Vector").field_source_reference_all(); + b.add_output(N_("Value"), "Value_Color").field_source_reference_all(); + b.add_output(N_("Value"), "Value_Bool").field_source_reference_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc index 95a0013a9e1..e88ade18764 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc @@ -15,8 +15,8 @@ namespace blender::nodes::node_geo_flip_faces_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_output(N_("Mesh")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_output(N_("Mesh")).propagate_all(); } static void mesh_flip_faces(Mesh &mesh, const Field &selection_field) diff --git a/source/blender/nodes/geometry/nodes/node_geo_geometry_to_instance.cc b/source/blender/nodes/geometry/nodes/node_geo_geometry_to_instance.cc index 45808ff9996..ac415d079f2 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_geometry_to_instance.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_geometry_to_instance.cc @@ -9,7 +9,7 @@ namespace blender::nodes::node_geo_geometry_to_instance_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")).multi_input(); - b.add_output(N_("Instances")); + b.add_output(N_("Instances")).propagate_all(); } static void node_geo_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc index 6a2ff2e1ead..499d8d689c6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc @@ -27,8 +27,8 @@ static void node_declare(NodeDeclarationBuilder &b) .implicit_field(implicit_field_inputs::position) .description("Texture coordinates from 0 to 1"); b.add_input(N_("Frame")).min(0).max(MAXFRAMEF); - b.add_output(N_("Color")).no_muted_links().dependent_field(); - b.add_output(N_("Alpha")).no_muted_links().dependent_field(); + b.add_output(N_("Color")).no_muted_links().dependent_field().reference_pass_all(); + b.add_output(N_("Alpha")).no_muted_links().dependent_field().reference_pass_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc index 2979d0e4639..2e3d5b42bec 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc @@ -13,8 +13,8 @@ static void node_declare(NodeDeclarationBuilder &b) .supports_field() .description(N_("Output the handle positions relative to the corresponding control point " "instead of in the local space of the geometry")); - b.add_output(N_("Left")).field_source(); - b.add_output(N_("Right")).field_source(); + b.add_output(N_("Left")).field_source_reference_all(); + b.add_output(N_("Right")).field_source_reference_all(); } class HandlePositionFieldInput final : public bke::CurvesFieldInput { diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc index 898a2d71ca7..44172cfee60 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc @@ -19,29 +19,29 @@ namespace blender::nodes::node_geo_instance_on_points_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Points")).description(N_("Points to instance on")); - b.add_input(N_("Selection")).default_value(true).supports_field().hide_value(); + b.add_input(N_("Selection")).default_value(true).field_on({0}).hide_value(); b.add_input(N_("Instance")) .description(N_("Geometry that is instanced on the points")); b.add_input(N_("Pick Instance")) - .supports_field() + .field_on({0}) .description(N_("Choose instances from the \"Instance\" input at each point instead of " "instancing the entire geometry")); b.add_input(N_("Instance Index")) - .implicit_field(implicit_field_inputs::id_or_index) + .implicit_field_on(implicit_field_inputs::id_or_index, {0}) .description( N_("Index of the instance used for each point. This is only used when Pick Instances " "is on. By default the point index is used")); b.add_input(N_("Rotation")) .subtype(PROP_EULER) - .supports_field() + .field_on({0}) .description(N_("Rotation of the instances")); b.add_input(N_("Scale")) .default_value({1.0f, 1.0f, 1.0f}) .subtype(PROP_XYZ) - .supports_field() + .field_on({0}) .description(N_("Scale of the instances")); - b.add_output(N_("Instances")); + b.add_output(N_("Instances")).propagate_all(); } static void add_instances_from_component( diff --git a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc index acd00d119ab..e43aac9d3ad 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc @@ -13,14 +13,14 @@ namespace blender::nodes::node_geo_instances_to_points_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Instances")).only_instances(); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_input(N_("Position")).implicit_field(implicit_field_inputs::position); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("Position")).implicit_field_on_all(implicit_field_inputs::position); b.add_input(N_("Radius")) .default_value(0.05f) .min(0.0f) .subtype(PROP_DISTANCE) - .supports_field(); - b.add_output(N_("Points")); + .field_on_all(); + b.add_output(N_("Points")).propagate_all(); } static void convert_instances_to_points(GeometrySet &geometry_set, diff --git a/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc b/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc index 13636b67c9b..43bc3925991 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc @@ -21,11 +21,11 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input(N_("Value"), "Value_Color").supports_field(); b.add_input(N_("Value"), "Value_Bool").supports_field(); - b.add_output(N_("Value"), "Value_Float").field_source(); - b.add_output(N_("Value"), "Value_Int").field_source(); - b.add_output(N_("Value"), "Value_Vector").field_source(); - b.add_output(N_("Value"), "Value_Color").field_source(); - b.add_output(N_("Value"), "Value_Bool").field_source(); + b.add_output(N_("Value"), "Value_Float").field_source_reference_all(); + b.add_output(N_("Value"), "Value_Int").field_source_reference_all(); + b.add_output(N_("Value"), "Value_Vector").field_source_reference_all(); + b.add_output(N_("Value"), "Value_Color").field_source_reference_all(); + b.add_output(N_("Value"), "Value_Bool").field_source_reference_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc index ea2646a9786..03ecb7c4c2f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc @@ -11,7 +11,7 @@ namespace blender::nodes::node_geo_join_geometry_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")).multi_input(); - b.add_output(N_("Geometry")); + b.add_output(N_("Geometry")).propagate_all(); } template diff --git a/source/blender/nodes/geometry/nodes/node_geo_material_replace.cc b/source/blender/nodes/geometry/nodes/node_geo_material_replace.cc index 546982b11af..3b2cd8d7744 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_material_replace.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_material_replace.cc @@ -17,7 +17,7 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input(N_("Geometry")).supported_type(GEO_COMPONENT_TYPE_MESH); b.add_input(N_("Old")); b.add_input(N_("New")); - b.add_output(N_("Geometry")); + b.add_output(N_("Geometry")).propagate_all(); } static void node_geo_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc index 8ab8c4afaa9..04c48a82e42 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc @@ -19,9 +19,9 @@ static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")) .supported_type({GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_MESH}); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); b.add_input(N_("Distance")).default_value(0.001f).min(0.0f).subtype(PROP_DISTANCE); - b.add_output(N_("Geometry")); + b.add_output(N_("Geometry")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc index 1b9852cf7b9..a1d222a0a53 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc @@ -18,7 +18,7 @@ static void node_declare(NodeDeclarationBuilder &b) .description(N_("An identifier for the group of each face. All contiguous faces with the " "same value are in the same region")); b.add_output(N_("Boundary Edges")) - .field_source() + .field_source_reference_all() .description(N_("The edges that lie on the boundaries between the different face sets")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc index 13c7c6a7a24..8f261ad9e66 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc @@ -748,10 +748,10 @@ static void node_declare(NodeDeclarationBuilder &b) .subtype(PROP_DISTANCE) .description(N_("Height of the generated cone")); b.add_output(N_("Mesh")); - b.add_output(N_("Top")).field_source(); - b.add_output(N_("Bottom")).field_source(); - b.add_output(N_("Side")).field_source(); - b.add_output(N_("UV Map")).field_source(); + b.add_output(N_("Top")).field_on_all(); + b.add_output(N_("Bottom")).field_on_all(); + b.add_output(N_("Side")).field_on_all(); + b.add_output(N_("UV Map")).field_on_all(); } static void node_init(bNodeTree * /*tree*/, bNode *node) diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc index 53ae33fbd21..879de80e73d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc @@ -35,7 +35,7 @@ static void node_declare(NodeDeclarationBuilder &b) .max(1000) .description(N_("Number of vertices for the Z side of the shape")); b.add_output(N_("Mesh")); - b.add_output(N_("UV Map")).field_source(); + b.add_output(N_("UV Map")).field_on_all(); } static Mesh *create_cuboid_mesh(const float3 &size, diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc index f27ec076ab2..b0e857feb64 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc @@ -43,10 +43,10 @@ static void node_declare(NodeDeclarationBuilder &b) .subtype(PROP_DISTANCE) .description(N_("The height of the cylinder")); b.add_output(N_("Mesh")); - b.add_output(N_("Top")).field_source(); - b.add_output(N_("Side")).field_source(); - b.add_output(N_("Bottom")).field_source(); - b.add_output(N_("UV Map")).field_source(); + b.add_output(N_("Top")).field_on_all(); + b.add_output(N_("Side")).field_on_all(); + b.add_output(N_("Bottom")).field_on_all(); + b.add_output(N_("UV Map")).field_on_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc index aa085ae903d..98ff797addc 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc @@ -180,7 +180,7 @@ static void node_declare(NodeDeclarationBuilder &b) .max(1000) .description(N_("Number of vertices in the Y direction")); b.add_output(N_("Mesh")); - b.add_output(N_("UV Map")).field_source(); + b.add_output(N_("UV Map")).field_on_all(); } static void node_geo_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc index 1fa85fc8d56..cd8c6a19612 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc @@ -25,7 +25,7 @@ static void node_declare(NodeDeclarationBuilder &b) .max(7) .description(N_("Number of subdivisions on top of the basic icosahedron")); b.add_output(N_("Mesh")); - b.add_output(N_("UV Map")).field_source(); + b.add_output(N_("UV Map")).field_on_all(); } static Mesh *create_ico_sphere_mesh(const int subdivisions, diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc index 6be03be63f5..5b424534d7b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc @@ -33,7 +33,7 @@ static void node_declare(NodeDeclarationBuilder &b) .subtype(PROP_DISTANCE) .description(N_("Distance from the generated points to the origin")); b.add_output(N_("Mesh")); - b.add_output(N_("UV Map")).field_source(); + b.add_output(N_("UV Map")).field_on_all(); } static int sphere_vert_total(const int segments, const int rings) diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc index 3c0ccb01673..0fd3db6c1a7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_subdivide.cc @@ -15,7 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH); b.add_input(N_("Level")).default_value(1).min(0).max(6); - b.add_output(N_("Mesh")); + b.add_output(N_("Mesh")).propagate_all(); } static void geometry_set_mesh_subdivide(GeometrySet &geometry_set, const int level) diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc index 4d08fa40a29..40626a1c2c5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc @@ -11,8 +11,8 @@ namespace blender::nodes::node_geo_mesh_to_curve_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_output(N_("Curve")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_output(N_("Curve")).propagate_all(); } static void node_geo_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc index d47e0c0f101..790f0ceda9c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc @@ -23,14 +23,14 @@ NODE_STORAGE_FUNCS(NodeGeometryMeshToPoints) static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Selection")).default_value(true).supports_field().hide_value(); + b.add_input(N_("Selection")).default_value(true).field_on_all().hide_value(); b.add_input(N_("Position")).implicit_field(implicit_field_inputs::position); b.add_input(N_("Radius")) .default_value(0.05f) .min(0.0f) .subtype(PROP_DISTANCE) - .supports_field(); - b.add_output(N_("Points")); + .field_on_all(); + b.add_output(N_("Points")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc index b464832409c..93b81761831 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc @@ -22,10 +22,11 @@ static void node_declare(NodeDeclarationBuilder &b) .supports_field() .description(N_("Which of the sorted corners to output")); b.add_output(N_("Corner Index")) - .dependent_field() + .field_source_reference_all() .description(N_("A corner of the face, chosen by the sort index")); b.add_output(N_("Total")) - .dependent_field() + .field_source() + .reference_pass({0}) .description(N_("The number of corners in the face")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc index c01c4149864..13c0ca0c441 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc @@ -25,10 +25,11 @@ static void node_declare(NodeDeclarationBuilder &b) .supports_field() .description(N_("Which of the sorted corners to output")); b.add_output(N_("Corner Index")) - .dependent_field() + .field_source_reference_all() .description(N_("A corner connected to the face, chosen by the sort index")); b.add_output(N_("Total")) - .dependent_field() + .field_source() + .reference_pass({0}) .description(N_("The number of faces or corners connected to each vertex")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc index 08085d2619a..833f5f26f6c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_corner.cc @@ -16,11 +16,11 @@ static void node_declare(NodeDeclarationBuilder &b) .description( N_("The corner to retrieve data from. Defaults to the corner from the context")); b.add_output(N_("Next Edge Index")) - .dependent_field() + .field_source_reference_all() .description( N_("The edge after the corner in the face, in the direction of increasing indices")); b.add_output(N_("Previous Edge Index")) - .dependent_field() + .field_source_reference_all() .description( N_("The edge before the corner in the face, in the direction of decreasing indices")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc index 7aadc15f7f8..324f799ca89 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc @@ -25,10 +25,11 @@ static void node_declare(NodeDeclarationBuilder &b) .supports_field() .description(N_("Which of the sorted edges to output")); b.add_output(N_("Edge Index")) - .dependent_field() + .field_source_reference_all() .description(N_("An edge connected to the face, chosen by the sort index")); b.add_output(N_("Total")) - .dependent_field() + .field_source() + .reference_pass({0}) .description(N_("The number of edges connected to each vertex")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc index 2cf7ed2c687..4a7b1bbfbdb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_face_of_corner.cc @@ -14,10 +14,10 @@ static void node_declare(NodeDeclarationBuilder &b) .description( N_("The corner to retrieve data from. Defaults to the corner from the context")); b.add_output(N_("Face Index")) - .dependent_field() + .field_source_reference_all() .description(N_("The index of the face the corner is a part of")); b.add_output(N_("Index in Face")) - .dependent_field() + .field_source_reference_all() .description(N_("The index of the corner starting from the first corner in the face")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc index ef5c9a445f2..de1eeeb28fc 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc @@ -20,7 +20,7 @@ static void node_declare(NodeDeclarationBuilder &b) .description(N_("The number of corners to move around the face before finding the result, " "circling around the start of the face if necessary")); b.add_output(N_("Corner Index")) - .dependent_field() + .field_source_reference_all() .description(N_("The index of the offset corner")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc index 9f730367931..8f631c87311 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_vertex_of_corner.cc @@ -15,7 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b) .description( N_("The corner to retrieve data from. Defaults to the corner from the context")); b.add_output(N_("Vertex Index")) - .dependent_field() + .field_source_reference_all() .description(N_("The vertex the corner is attached to")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc index 52a73cfdb25..b878d24870d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc @@ -34,11 +34,11 @@ static void node_declare(NodeDeclarationBuilder &b) .supports_field() .description(N_("The number of control points along the curve to traverse")); b.add_output(N_("Is Valid Offset")) - .dependent_field() + .field_source_reference_all() .description(N_("Whether the input control point plus the offset is a valid index of the " "original curve")); b.add_output(N_("Point Index")) - .dependent_field() + .field_source_reference_all() .description(N_("The index of the control point plus the offset within the entire " "curves data-block")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc index 2646e0d826d..2e9d5037c00 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc @@ -16,8 +16,8 @@ using blender::Array; static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Points")).supported_type(GEO_COMPONENT_TYPE_POINT_CLOUD); - b.add_input(N_("Selection")).default_value(true).supports_field().hide_value(); - b.add_output(N_("Mesh")); + b.add_input(N_("Selection")).default_value(true).field_on_all().hide_value(); + b.add_output(N_("Mesh")).propagate_all(); } /* One improvement would be to move the attribute arrays directly to the mesh when possible. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc index fad71adae3d..9d666f64d67 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_volume.cc @@ -41,7 +41,7 @@ static void node_declare(NodeDeclarationBuilder &b) .default_value(0.5f) .min(0.0f) .subtype(PROP_DISTANCE) - .supports_field(); + .field_on_all(); b.add_output(N_("Volume")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc index 50e5ac1885b..c3c776e9067 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc @@ -23,8 +23,8 @@ static void node_declare(NodeDeclarationBuilder &b) .only_realized_data() .supported_type({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD}); b.add_input(N_("Source Position")).implicit_field(implicit_field_inputs::position); - b.add_output(N_("Position")).dependent_field(); - b.add_output(N_("Distance")).dependent_field(); + b.add_output(N_("Position")).dependent_field().reference_pass_all(); + b.add_output(N_("Distance")).dependent_field().reference_pass_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc index ed1cb707d86..dbaabbea799 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc @@ -25,11 +25,11 @@ static void node_declare(NodeDeclarationBuilder &b) .only_realized_data() .supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Attribute")).hide_value().supports_field(); - b.add_input(N_("Attribute"), "Attribute_001").hide_value().supports_field(); - b.add_input(N_("Attribute"), "Attribute_002").hide_value().supports_field(); - b.add_input(N_("Attribute"), "Attribute_003").hide_value().supports_field(); - b.add_input(N_("Attribute"), "Attribute_004").hide_value().supports_field(); + b.add_input(N_("Attribute")).hide_value().field_on_all(); + b.add_input(N_("Attribute"), "Attribute_001").hide_value().field_on_all(); + b.add_input(N_("Attribute"), "Attribute_002").hide_value().field_on_all(); + b.add_input(N_("Attribute"), "Attribute_003").hide_value().field_on_all(); + b.add_input(N_("Attribute"), "Attribute_004").hide_value().field_on_all(); b.add_input(N_("Source Position")).implicit_field(implicit_field_inputs::position); b.add_input(N_("Ray Direction")) diff --git a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc index 3ccc8afb0a7..920d3f77666 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc @@ -12,7 +12,7 @@ namespace blender::nodes::node_geo_realize_instances_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")); - b.add_output(N_("Geometry")); + b.add_output(N_("Geometry")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc index 1b398f63691..b9d0b8b5d28 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_remove_attribute.cc @@ -10,7 +10,7 @@ static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")); b.add_input(N_("Name")).is_attribute_name(); - b.add_output(N_("Geometry")); + b.add_output(N_("Geometry")).propagate_all(); } static void node_geo_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc index fac92a7500c..33ec8938267 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_rotate_instances.cc @@ -11,11 +11,11 @@ namespace blender::nodes::node_geo_rotate_instances_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Instances")).only_instances(); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_input(N_("Rotation")).subtype(PROP_EULER).supports_field(); - b.add_input(N_("Pivot Point")).subtype(PROP_TRANSLATION).supports_field(); - b.add_input(N_("Local Space")).default_value(true).supports_field(); - b.add_output(N_("Instances")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("Rotation")).subtype(PROP_EULER).field_on_all(); + b.add_input(N_("Pivot Point")).subtype(PROP_TRANSLATION).field_on_all(); + b.add_input(N_("Local Space")).default_value(true).field_on_all(); + b.add_output(N_("Instances")).propagate_all(); } static void rotate_instances(GeoNodeExecParams ¶ms, bke::Instances &instances) diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc index dfb0c17e4d5..3dd47d37ea8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc @@ -23,11 +23,11 @@ static void node_declare(NodeDeclarationBuilder &b) GEO_COMPONENT_TYPE_CURVE, GEO_COMPONENT_TYPE_INSTANCES}); - b.add_input(N_("Value"), "Value_Float").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Int").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Vector").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Color").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Bool").hide_value().supports_field(); + b.add_input(N_("Value"), "Value_Float").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Int").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Vector").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Color").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Bool").hide_value().field_on_all(); b.add_input(N_("Index")) .supports_field() .description(N_("Which element to retrieve a value from on the geometry")); diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc index d0eeb702d40..2628fcf3321 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc @@ -23,11 +23,11 @@ static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Value"), "Value_Float").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Int").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Vector").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Color").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Bool").hide_value().supports_field(); + b.add_input(N_("Value"), "Value_Float").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Int").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Vector").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Color").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Bool").hide_value().field_on_all(); b.add_input(N_("Sample Position")).implicit_field(implicit_field_inputs::position); diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc index 2c8d39f7aef..7fb4596dfbe 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc @@ -21,15 +21,15 @@ static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Value"), "Value_Float").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Int").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Vector").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Color").hide_value().supports_field(); - b.add_input(N_("Value"), "Value_Bool").hide_value().supports_field(); + b.add_input(N_("Value"), "Value_Float").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Int").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Vector").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Color").hide_value().field_on_all(); + b.add_input(N_("Value"), "Value_Bool").hide_value().field_on_all(); b.add_input(N_("Source UV Map")) .hide_value() - .supports_field() + .field_on_all() .description(N_("The mesh UV map to sample. Should not have overlapping faces")); b.add_input(N_("Sample UV")) .supports_field() diff --git a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc index 3cfdafa76c0..da9b04c06c0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc @@ -21,19 +21,19 @@ namespace blender::nodes::node_geo_scale_elements_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")).supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_input(N_("Scale"), "Scale").default_value(1.0f).min(0.0f).supports_field(); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("Scale"), "Scale").default_value(1.0f).min(0.0f).field_on_all(); b.add_input(N_("Center")) .subtype(PROP_TRANSLATION) - .implicit_field(implicit_field_inputs::position) + .implicit_field_on_all(implicit_field_inputs::position) .description(N_("Origin of the scaling for each element. If multiple elements are " "connected, their center is averaged")); b.add_input(N_("Axis")) .default_value({1.0f, 0.0f, 0.0f}) - .supports_field() + .field_on_all() .description(N_("Direction in which to scale the element")) .make_available([](bNode &node) { node.custom2 = GEO_NODE_SCALE_ELEMENTS_SINGLE_AXIS; }); - b.add_output(N_("Geometry")); + b.add_output(N_("Geometry")).propagate_all(); }; static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc index dacb130337f..95604fdcb61 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_scale_instances.cc @@ -11,14 +11,11 @@ namespace blender::nodes::node_geo_scale_instances_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Instances")).only_instances(); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_input(N_("Scale")) - .subtype(PROP_XYZ) - .default_value({1, 1, 1}) - .supports_field(); - b.add_input(N_("Center")).subtype(PROP_TRANSLATION).supports_field(); - b.add_input(N_("Local Space")).default_value(true).supports_field(); - b.add_output(N_("Instances")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("Scale")).subtype(PROP_XYZ).default_value({1, 1, 1}).field_on_all(); + b.add_input(N_("Center")).subtype(PROP_TRANSLATION).field_on_all(); + b.add_input(N_("Local Space")).default_value(true).field_on_all(); + b.add_output(N_("Instances")).propagate_all(); } static void scale_instances(GeoNodeExecParams ¶ms, bke::Instances &instances) diff --git a/source/blender/nodes/geometry/nodes/node_geo_separate_components.cc b/source/blender/nodes/geometry/nodes/node_geo_separate_components.cc index b29ebd0d4d4..5740bd68539 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_separate_components.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_separate_components.cc @@ -7,11 +7,11 @@ namespace blender::nodes::node_geo_separate_components_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")); - b.add_output(N_("Mesh")); - b.add_output(N_("Point Cloud")); - b.add_output(N_("Curve")); - b.add_output(N_("Volume")); - b.add_output(N_("Instances")); + b.add_output(N_("Mesh")).propagate_all(); + b.add_output(N_("Point Cloud")).propagate_all(); + b.add_output(N_("Curve")).propagate_all(); + b.add_output(N_("Volume")).propagate_all(); + b.add_output(N_("Instances")).propagate_all(); } static void node_geo_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc index d4da5dda647..8b01e147d0d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc @@ -15,11 +15,13 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input(N_("Selection")) .default_value(true) .hide_value() - .supports_field() + .field_on_all() .description(N_("The parts of the geometry that go into the first output")); b.add_output(N_("Selection")) + .propagate_all() .description(N_("The parts of the geometry in the selection")); b.add_output(N_("Inverted")) + .propagate_all() .description(N_("The parts of the geometry not in the selection")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc index 48be899bec9..3e5eb482d9f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_handles.cc @@ -16,14 +16,16 @@ NODE_STORAGE_FUNCS(NodeGeometrySetCurveHandlePositions) static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_input(N_("Position")).implicit_field([](const bNode &node, void *r_value) { - const StringRef side = node_storage(node).mode == GEO_NODE_CURVE_HANDLE_LEFT ? "handle_left" : - "handle_right"; - new (r_value) ValueOrField(bke::AttributeFieldInput::Create(side)); - }); - b.add_input(N_("Offset")).default_value(float3(0.0f, 0.0f, 0.0f)).supports_field(); - b.add_output(N_("Curve")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("Position")) + .implicit_field_on_all([](const bNode &node, void *r_value) { + const StringRef side = node_storage(node).mode == GEO_NODE_CURVE_HANDLE_LEFT ? + "handle_left" : + "handle_right"; + new (r_value) ValueOrField(bke::AttributeFieldInput::Create(side)); + }); + b.add_input(N_("Offset")).default_value(float3(0.0f, 0.0f, 0.0f)).field_on_all(); + b.add_output(N_("Curve")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_normal.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_normal.cc index 287c5920134..19e9d18dd54 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_normal.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_normal.cc @@ -12,8 +12,8 @@ namespace blender::nodes::node_geo_set_curve_normal_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_output(N_("Curve")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_output(N_("Curve")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc index 0d361090068..f03f5aa0413 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_radius.cc @@ -9,13 +9,13 @@ namespace blender::nodes::node_geo_set_curve_radius_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); b.add_input(N_("Radius")) .min(0.0f) .default_value(0.005f) .supports_field() .subtype(PROP_DISTANCE); - b.add_output(N_("Curve")); + b.add_output(N_("Curve")).propagate_all(); } static void set_radius(bke::CurvesGeometry &curves, diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc b/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc index 8c1fb883f46..2887800995f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_curve_tilt.cc @@ -9,9 +9,9 @@ namespace blender::nodes::node_geo_set_curve_tilt_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Curve")).supported_type(GEO_COMPONENT_TYPE_CURVE); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_input(N_("Tilt")).subtype(PROP_ANGLE).supports_field(); - b.add_output(N_("Curve")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("Tilt")).subtype(PROP_ANGLE).field_on_all(); + b.add_output(N_("Curve")).propagate_all(); } static void set_tilt(bke::CurvesGeometry &curves, diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_id.cc b/source/blender/nodes/geometry/nodes/node_geo_set_id.cc index e308371b1c2..fa72d3d8efa 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_id.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_id.cc @@ -7,9 +7,9 @@ namespace blender::nodes::node_geo_set_id_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_input(N_("ID")).implicit_field(implicit_field_inputs::index); - b.add_output(N_("Geometry")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("ID")).implicit_field_on_all(implicit_field_inputs::index); + b.add_output(N_("Geometry")).propagate_all(); } static void set_id_in_component(GeometryComponent &component, diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_material.cc b/source/blender/nodes/geometry/nodes/node_geo_set_material.cc index 8d00d82664b..e6e3eadff03 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_material.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_material.cc @@ -23,9 +23,9 @@ static void node_declare(NodeDeclarationBuilder &b) GEO_COMPONENT_TYPE_VOLUME, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE}); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); b.add_input(N_("Material")).hide_label(); - b.add_output(N_("Geometry")); + b.add_output(N_("Geometry")).propagate_all(); } static void assign_material_to_faces(Mesh &mesh, const IndexMask selection, Material *material) diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc b/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc index bb9ac9b5d4c..0c919340709 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_material_index.cc @@ -7,9 +7,9 @@ namespace blender::nodes::node_geo_set_material_index_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")).supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_input(N_("Material Index")).supports_field().min(0); - b.add_output(N_("Geometry")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("Material Index")).field_on_all().min(0); + b.add_output(N_("Geometry")).propagate_all(); } static void set_material_index_in_component(GeometryComponent &component, diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc b/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc index 28d07b31218..0034fc4a292 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_point_radius.cc @@ -9,13 +9,13 @@ namespace blender::nodes::node_geo_set_point_radius_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Points")).supported_type(GEO_COMPONENT_TYPE_POINT_CLOUD); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); b.add_input(N_("Radius")) .default_value(0.05f) .min(0.0f) - .supports_field() + .field_on_all() .subtype(PROP_DISTANCE); - b.add_output(N_("Points")); + b.add_output(N_("Points")).propagate_all(); } static void set_radius_in_component(PointCloud &pointcloud, diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index 2a56152a2b4..4a76e230af7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -17,10 +17,10 @@ namespace blender::nodes::node_geo_set_position_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_input(N_("Position")).implicit_field(implicit_field_inputs::position); - b.add_input(N_("Offset")).supports_field().subtype(PROP_TRANSLATION); - b.add_output(N_("Geometry")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("Position")).implicit_field_on_all(implicit_field_inputs::position); + b.add_input(N_("Offset")).field_on_all().subtype(PROP_TRANSLATION); + b.add_output(N_("Geometry")).propagate_all(); } static void set_computed_position_and_offset(GeometryComponent &component, diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc index 0df51e49827..7dd721288ac 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_shade_smooth.cc @@ -9,9 +9,9 @@ namespace blender::nodes::node_geo_set_shade_smooth_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")).supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_input(N_("Shade Smooth")).supports_field().default_value(true); - b.add_output(N_("Geometry")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("Shade Smooth")).field_on_all().default_value(true); + b.add_output(N_("Geometry")).propagate_all(); } static void set_smooth(Mesh &mesh, diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc b/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc index d8faa154477..962937b4aca 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_spline_cyclic.cc @@ -9,9 +9,9 @@ namespace blender::nodes::node_geo_set_spline_cyclic_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")).supported_type(GEO_COMPONENT_TYPE_CURVE); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_input(N_("Cyclic")).supports_field(); - b.add_output(N_("Geometry")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("Cyclic")).field_on_all(); + b.add_output(N_("Geometry")).propagate_all(); } static void set_cyclic(bke::CurvesGeometry &curves, diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc index dcd910b8ad2..df9363c233c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_spline_resolution.cc @@ -9,9 +9,9 @@ namespace blender::nodes::node_geo_set_spline_resolution_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")).supported_type(GEO_COMPONENT_TYPE_CURVE); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_input(N_("Resolution")).min(1).default_value(12).supports_field(); - b.add_output(N_("Geometry")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("Resolution")).min(1).default_value(12).field_on_all(); + b.add_output(N_("Geometry")).propagate_all(); } static void set_resolution(bke::CurvesGeometry &curves, diff --git a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc index b15c156a19b..d42793d474f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc @@ -21,13 +21,13 @@ static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")); b.add_input(N_("Name")).is_attribute_name(); - b.add_input(N_("Value"), "Value_Vector").supports_field(); - b.add_input(N_("Value"), "Value_Float").supports_field(); - b.add_input(N_("Value"), "Value_Color").supports_field(); - b.add_input(N_("Value"), "Value_Bool").supports_field(); - b.add_input(N_("Value"), "Value_Int").supports_field(); + b.add_input(N_("Value"), "Value_Vector").field_on_all(); + b.add_input(N_("Value"), "Value_Float").field_on_all(); + b.add_input(N_("Value"), "Value_Color").field_on_all(); + b.add_input(N_("Value"), "Value_Bool").field_on_all(); + b.add_input(N_("Value"), "Value_Int").field_on_all(); - b.add_output(N_("Geometry")); + b.add_output(N_("Geometry")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc index 5025feed7c4..93dcdd37ed2 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc @@ -54,8 +54,8 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output(N_("Remainder")).make_available([](bNode &node) { node_storage(node).overflow = GEO_NODE_STRING_TO_CURVES_MODE_TRUNCATE; }); - b.add_output(N_("Line")).field_source(); - b.add_output(N_("Pivot Point")).field_source(); + b.add_output(N_("Line")).field_on_all(); + b.add_output(N_("Pivot Point")).field_on_all(); } static void node_layout(uiLayout *layout, struct bContext *C, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc index 0abfaa7305f..40b49055949 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc @@ -28,15 +28,15 @@ static void node_declare(NodeDeclarationBuilder &b) .default_value(0.0f) .min(0.0f) .max(1.0f) - .supports_field() + .field_on_all() .subtype(PROP_FACTOR); b.add_input(N_("Vertex Crease")) .default_value(0.0f) .min(0.0f) .max(1.0f) - .supports_field() + .field_on_all() .subtype(PROP_FACTOR); - b.add_output(N_("Mesh")); + b.add_output(N_("Mesh")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_switch.cc b/source/blender/nodes/geometry/nodes/node_geo_switch.cc index e286d5bd364..75136013e7e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_switch.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_switch.cc @@ -59,13 +59,13 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input(N_("False"), "False_011"); b.add_input(N_("True"), "True_011"); - b.add_output(N_("Output")).dependent_field(); - b.add_output(N_("Output"), "Output_001").dependent_field(); - b.add_output(N_("Output"), "Output_002").dependent_field(); - b.add_output(N_("Output"), "Output_003").dependent_field(); - b.add_output(N_("Output"), "Output_004").dependent_field(); - b.add_output(N_("Output"), "Output_005").dependent_field(); - b.add_output(N_("Output"), "Output_006"); + b.add_output(N_("Output")).dependent_field().reference_pass_all(); + b.add_output(N_("Output"), "Output_001").dependent_field().reference_pass_all(); + b.add_output(N_("Output"), "Output_002").dependent_field().reference_pass_all(); + b.add_output(N_("Output"), "Output_003").dependent_field().reference_pass_all(); + b.add_output(N_("Output"), "Output_004").dependent_field().reference_pass_all(); + b.add_output(N_("Output"), "Output_005").dependent_field().reference_pass_all(); + b.add_output(N_("Output"), "Output_006").propagate_all(); b.add_output(N_("Output"), "Output_007"); b.add_output(N_("Output"), "Output_008"); b.add_output(N_("Output"), "Output_009"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc index aa674e760c9..425546c3406 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc @@ -256,7 +256,7 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input(N_("Translation")).subtype(PROP_TRANSLATION); b.add_input(N_("Rotation")).subtype(PROP_EULER); b.add_input(N_("Scale")).default_value({1, 1, 1}).subtype(PROP_XYZ); - b.add_output(N_("Geometry")); + b.add_output(N_("Geometry")).propagate_all(); } static void node_geo_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc index 23052abddc4..5a278ac8547 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_translate_instances.cc @@ -11,10 +11,10 @@ namespace blender::nodes::node_geo_translate_instances_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Instances")).only_instances(); - b.add_input(N_("Selection")).default_value(true).hide_value().supports_field(); - b.add_input(N_("Translation")).subtype(PROP_TRANSLATION).supports_field(); - b.add_input(N_("Local Space")).default_value(true).supports_field(); - b.add_output(N_("Instances")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); + b.add_input(N_("Translation")).subtype(PROP_TRANSLATION).field_on_all(); + b.add_input(N_("Local Space")).default_value(true).field_on_all(); + b.add_output(N_("Instances")).propagate_all(); } static void translate_instances(GeoNodeExecParams ¶ms, bke::Instances &instances) diff --git a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc index 5cb78b3abe8..52c7dbf0605 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_triangulate.cc @@ -18,9 +18,9 @@ namespace blender::nodes::node_geo_triangulate_cc { static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH); - b.add_input(N_("Selection")).default_value(true).supports_field().hide_value(); + b.add_input(N_("Selection")).default_value(true).field_on_all().hide_value(); b.add_input(N_("Minimum Vertices")).default_value(4).min(4).max(10000); - b.add_output(N_("Mesh")); + b.add_output(N_("Mesh")).propagate_all(); } static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc index c2d27cffa93..de275f3e857 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc @@ -27,7 +27,7 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input(N_("Rotate")) .default_value(true) .description(N_("Rotate islands for best fit")); - b.add_output(N_("UV")).field_source(); + b.add_output(N_("UV")).field_source_reference_all(); } static VArray construct_uv_gvarray(const Mesh &mesh, diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc index eff3b969250..075be8fa010 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc @@ -36,7 +36,7 @@ static void node_declare(NodeDeclarationBuilder &b) .default_value(true) .description(N_("Virtually fill holes in mesh before unwrapping, to better avoid overlaps " "and preserve symmetry")); - b.add_output(N_("UV")).field_source().description( + b.add_output(N_("UV")).field_source_reference_all().description( N_("UV coordinates between 0 and 1 for each face corner in the selected faces")); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_viewer.cc b/source/blender/nodes/geometry/nodes/node_geo_viewer.cc index 53a8cd79f52..dd6bd6a0ebd 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_viewer.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_viewer.cc @@ -19,11 +19,11 @@ NODE_STORAGE_FUNCS(NodeGeometryViewer) static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")); - b.add_input(N_("Value")).supports_field().hide_value(); - b.add_input(N_("Value"), "Value_001").supports_field().hide_value(); - b.add_input(N_("Value"), "Value_002").supports_field().hide_value(); - b.add_input(N_("Value"), "Value_003").supports_field().hide_value(); - b.add_input(N_("Value"), "Value_004").supports_field().hide_value(); + b.add_input(N_("Value")).field_on_all().hide_value(); + b.add_input(N_("Value"), "Value_001").field_on_all().hide_value(); + b.add_input(N_("Value"), "Value_002").field_on_all().hide_value(); + b.add_input(N_("Value"), "Value_003").field_on_all().hide_value(); + b.add_input(N_("Value"), "Value_004").field_on_all().hide_value(); } static void node_init(bNodeTree * /*tree*/, bNode *node) diff --git a/source/blender/nodes/intern/node_declaration.cc b/source/blender/nodes/intern/node_declaration.cc index f9921db3230..3538710bb3a 100644 --- a/source/blender/nodes/intern/node_declaration.cc +++ b/source/blender/nodes/intern/node_declaration.cc @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "NOD_node_declaration.hh" +#include "NOD_socket_declarations.hh" +#include "NOD_socket_declarations_geometry.hh" #include "BKE_geometry_fields.hh" #include "BKE_node.h" @@ -17,17 +19,113 @@ void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declar void NodeDeclarationBuilder::finalize() { if (is_function_node_) { - for (SocketDeclarationPtr &socket_decl : declaration_.inputs) { - if (socket_decl->input_field_type != InputSocketFieldType::Implicit) { - socket_decl->input_field_type = InputSocketFieldType::IsSupported; + for (std::unique_ptr &socket_builder : input_builders_) { + SocketDeclaration &socket_decl = *socket_builder->declaration(); + if (socket_decl.input_field_type != InputSocketFieldType::Implicit) { + socket_decl.input_field_type = InputSocketFieldType::IsSupported; } } - for (SocketDeclarationPtr &socket_decl : declaration_.outputs) { - socket_decl->output_field_dependency = OutputFieldDependency::ForDependentField(); + for (std::unique_ptr &socket_builder : output_builders_) { + SocketDeclaration &socket_decl = *socket_builder->declaration(); + socket_decl.output_field_dependency = OutputFieldDependency::ForDependentField(); + socket_builder->reference_pass_all_ = true; + } + } + + Vector geometry_inputs; + for (const int i : declaration_.inputs.index_range()) { + if (dynamic_cast(declaration_.inputs[i].get())) { + geometry_inputs.append(i); + } + } + Vector geometry_outputs; + for (const int i : declaration_.outputs.index_range()) { + if (dynamic_cast(declaration_.outputs[i].get())) { + geometry_outputs.append(i); + } + } + + for (std::unique_ptr &socket_builder : input_builders_) { + if (socket_builder->field_on_all_) { + aal::RelationsInNode &relations = this->get_anonymous_attribute_relations(); + const int field_input = socket_builder->index_; + for (const int geometry_input : geometry_inputs) { + relations.eval_relations.append({field_input, geometry_input}); + } + } + } + for (std::unique_ptr &socket_builder : output_builders_) { + if (socket_builder->field_on_all_) { + aal::RelationsInNode &relations = this->get_anonymous_attribute_relations(); + const int field_output = socket_builder->index_; + for (const int geometry_output : geometry_outputs) { + relations.available_relations.append({field_output, geometry_output}); + } + } + if (socket_builder->reference_pass_all_) { + aal::RelationsInNode &relations = this->get_anonymous_attribute_relations(); + const int field_output = socket_builder->index_; + for (const int input_i : declaration_.inputs.index_range()) { + SocketDeclaration &input_socket_decl = *declaration_.inputs[input_i]; + if (input_socket_decl.input_field_type != InputSocketFieldType::None) { + relations.reference_relations.append({input_i, field_output}); + } + } + } + if (socket_builder->propagate_from_all_) { + aal::RelationsInNode &relations = this->get_anonymous_attribute_relations(); + const int geometry_output = socket_builder->index_; + for (const int geometry_input : geometry_inputs) { + relations.propagate_relations.append({geometry_input, geometry_output}); + } } } } +namespace anonymous_attribute_lifetime { + +bool operator==(const RelationsInNode &a, const RelationsInNode &b) +{ + return a.propagate_relations == b.propagate_relations && + a.reference_relations == b.reference_relations && a.eval_relations == b.eval_relations && + a.available_relations == b.available_relations && + a.available_on_none == b.available_on_none; +} + +bool operator!=(const RelationsInNode &a, const RelationsInNode &b) +{ + return !(a == b); +} + +std::ostream &operator<<(std::ostream &stream, const RelationsInNode &relations) +{ + stream << "Propagate Relations: " << relations.propagate_relations.size() << "\n"; + for (const PropagateRelation &relation : relations.propagate_relations) { + stream << " " << relation.from_geometry_input << " -> " << relation.to_geometry_output + << "\n"; + } + stream << "Reference Relations: " << relations.reference_relations.size() << "\n"; + for (const ReferenceRelation &relation : relations.reference_relations) { + stream << " " << relation.from_field_input << " -> " << relation.to_field_output << "\n"; + } + stream << "Eval Relations: " << relations.eval_relations.size() << "\n"; + for (const EvalRelation &relation : relations.eval_relations) { + stream << " eval " << relation.field_input << " on " << relation.geometry_input << "\n"; + } + stream << "Available Relations: " << relations.available_relations.size() << "\n"; + for (const AvailableRelation &relation : relations.available_relations) { + stream << " " << relation.field_output << " available on " << relation.geometry_output + << "\n"; + } + stream << "Available on None: " << relations.available_on_none.size() << "\n"; + for (const int i : relations.available_on_none) { + stream << " output " << i << " available on none\n"; + } + return stream; +} + +} // namespace anonymous_attribute_lifetime + bool NodeDeclaration::matches(const bNode &node) const { auto check_sockets = [&](ListBase sockets, Span socket_decls) { From 30753f76927dd91a2d583b1ec427b92a02bcf3d6 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 3 Jan 2023 12:37:18 +0100 Subject: [PATCH 0367/1522] Functions: add method to iterate over all inputs of a field This is part of D16858. Iterating over all field inputs allows us to extract all anonymous attributes used by a field relatively easily which is necessary for D16858. This could potentially be used for better field tooltips for nested fields, but that needs further investigation. --- source/blender/functions/FN_field.hh | 6 ++++++ source/blender/functions/intern/field.cc | 12 ++++++++++++ .../nodes/geometry/nodes/node_geo_blur_attribute.cc | 6 ++++++ .../nodes/node_geo_curve_endpoint_selection.cc | 6 ++++++ .../nodes/node_geo_curve_topology_points_of_curve.cc | 7 +++++++ .../nodes/node_geo_edge_paths_to_selection.cc | 6 ++++++ .../geometry/nodes/node_geo_input_curve_handles.cc | 5 +++++ .../nodes/node_geo_input_mesh_face_is_planar.cc | 5 +++++ .../nodes/node_geo_input_shortest_edge_paths.cc | 6 ++++++ .../geometry/nodes/node_geo_interpolate_domain.cc | 5 +++++ .../nodes/node_geo_mesh_face_set_boundaries.cc | 11 ++++++++--- .../nodes/node_geo_mesh_topology_corners_of_face.cc | 7 +++++++ .../node_geo_mesh_topology_corners_of_vertex.cc | 7 +++++++ .../nodes/node_geo_mesh_topology_edges_of_vertex.cc | 7 +++++++ .../node_geo_mesh_topology_offset_corner_in_face.cc | 6 ++++++ .../geometry/nodes/node_geo_offset_point_in_curve.cc | 12 ++++++++++++ .../nodes/geometry/nodes/node_geo_uv_pack_islands.cc | 6 ++++++ .../nodes/geometry/nodes/node_geo_uv_unwrap.cc | 6 ++++++ 18 files changed, 123 insertions(+), 3 deletions(-) diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh index bff9c77ef7d..7f940294113 100644 --- a/source/blender/functions/FN_field.hh +++ b/source/blender/functions/FN_field.hh @@ -84,6 +84,12 @@ class FieldNode { virtual uint64_t hash() const; virtual bool is_equal_to(const FieldNode &other) const; + + /** + * Calls the callback for every field input that the current field depends on. This is recursive, + * so if a field input depends on other field inputs, those are taken into account as well. + */ + virtual void for_each_field_input_recursive(FunctionRef fn) const; }; /** diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc index 754860f2682..a9d26fa09f1 100644 --- a/source/blender/functions/intern/field.cc +++ b/source/blender/functions/intern/field.cc @@ -579,6 +579,18 @@ bool IndexFieldInput::is_equal_to(const fn::FieldNode &other) const /* Avoid generating the destructor in every translation unit. */ FieldNode::~FieldNode() = default; +void FieldNode::for_each_field_input_recursive(FunctionRef fn) const +{ + if (field_inputs_) { + for (const FieldInput &field_input : field_inputs_->deduplicated_nodes) { + fn(field_input); + if (&field_input != this) { + field_input.for_each_field_input_recursive(fn); + } + } + } +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc index 661ed933650..174c6c8c509 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc @@ -440,6 +440,12 @@ class BlurAttributeFieldInput final : public bke::GeometryFieldInput { return GVArray::ForGArray(std::move(main_buffer)); } + void for_each_field_input_recursive(FunctionRef fn) const + { + weight_field_.node().for_each_field_input_recursive(fn); + value_field_.node().for_each_field_input_recursive(fn); + } + uint64_t hash() const override { return get_default_hash_3(iterations_, weight_field_, value_field_); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc index 25bb5473843..3b48abfbd7d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc @@ -77,6 +77,12 @@ class EndpointFieldInput final : public bke::CurvesFieldInput { return VArray::ForContainer(std::move(selection)); }; + void for_each_field_input_recursive(FunctionRef fn) const + { + start_size_.node().for_each_field_input_recursive(fn); + end_size_.node().for_each_field_input_recursive(fn); + } + uint64_t hash() const override { return get_default_hash_2(start_size_, end_size_); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc index df917f6f831..ceb5c12fe5d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc @@ -101,6 +101,13 @@ class PointsOfCurveInput final : public bke::CurvesFieldInput { return VArray::ForContainer(std::move(point_of_curve)); } + void for_each_field_input_recursive(FunctionRef fn) const + { + curve_index_.node().for_each_field_input_recursive(fn); + sort_index_.node().for_each_field_input_recursive(fn); + sort_weight_.node().for_each_field_input_recursive(fn); + } + uint64_t hash() const override { return 26978695677882; diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc index 5cfb0639813..5d6d5cb68e5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc @@ -92,6 +92,12 @@ class PathToEdgeSelectionFieldInput final : public bke::MeshFieldInput { VArray::ForContainer(std::move(selection)), ATTR_DOMAIN_EDGE, domain); } + void for_each_field_input_recursive(FunctionRef fn) const + { + start_vertices_.node().for_each_field_input_recursive(fn); + next_vertex_.node().for_each_field_input_recursive(fn); + } + uint64_t hash() const override { return get_default_hash_2(start_vertices_, next_vertex_); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc index 2e3d5b42bec..c3cc07f6edb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc @@ -71,6 +71,11 @@ class HandlePositionFieldInput final : public bke::CurvesFieldInput { VArray::ForContainer(std::move(output)), ATTR_DOMAIN_POINT, domain); } + void for_each_field_input_recursive(FunctionRef fn) const + { + relative_.node().for_each_field_input_recursive(fn); + } + uint64_t hash() const override { return get_default_hash_2(relative_, left_); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc index be98f53d161..859cbf360d4 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc @@ -76,6 +76,11 @@ class PlanarFieldInput final : public bke::MeshFieldInput { VArray::ForFunc(polys.size(), planar_fn), ATTR_DOMAIN_FACE, domain); } + void for_each_field_input_recursive(FunctionRef fn) const + { + threshold_.node().for_each_field_input_recursive(fn); + } + uint64_t hash() const override { /* Some random constant hash. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc b/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc index 00c92e30443..d9147d5e3ad 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc @@ -129,6 +129,12 @@ class ShortestEdgePathsNextVertFieldInput final : public bke::MeshFieldInput { VArray::ForContainer(std::move(next_index)), ATTR_DOMAIN_POINT, domain); } + void for_each_field_input_recursive(FunctionRef fn) const + { + end_selection_.node().for_each_field_input_recursive(fn); + cost_.node().for_each_field_input_recursive(fn); + } + uint64_t hash() const override { /* Some random constant hash. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc b/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc index 43bc3925991..df8b2bbd922 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc @@ -112,6 +112,11 @@ class InterpolateDomain final : public bke::GeometryFieldInput { GVArray::ForGArray(std::move(values)), src_domain_, context.domain()); } + void for_each_field_input_recursive(FunctionRef fn) const + { + src_field_.node().for_each_field_input_recursive(fn); + } + std::optional preferred_domain( const GeometryComponent & /*component*/) const override { diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc index a1d222a0a53..23d95e87bae 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc @@ -24,11 +24,11 @@ static void node_declare(NodeDeclarationBuilder &b) class BoundaryFieldInput final : public bke::MeshFieldInput { private: - const Field face_set; + const Field face_set_; public: BoundaryFieldInput(const Field face_set) - : bke::MeshFieldInput(CPPType::get(), "Boundary Field"), face_set(face_set) + : bke::MeshFieldInput(CPPType::get(), "Boundary Field"), face_set_(face_set) { category_ = Category::Generated; } @@ -39,7 +39,7 @@ class BoundaryFieldInput final : public bke::MeshFieldInput { { const bke::MeshFieldContext face_context{mesh, ATTR_DOMAIN_FACE}; FieldEvaluator face_evaluator{face_context, mesh.totpoly}; - face_evaluator.add(face_set); + face_evaluator.add(face_set_); face_evaluator.evaluate(); const VArray face_set = face_evaluator.get_evaluated(0); @@ -66,6 +66,11 @@ class BoundaryFieldInput final : public bke::MeshFieldInput { VArray::ForContainer(std::move(boundary)), ATTR_DOMAIN_EDGE, domain); } + void for_each_field_input_recursive(FunctionRef fn) const + { + face_set_.node().for_each_field_input_recursive(fn); + } + std::optional preferred_domain(const Mesh & /*mesh*/) const override { return ATTR_DOMAIN_EDGE; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc index 93b81761831..89374ccecb4 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc @@ -105,6 +105,13 @@ class CornersOfFaceInput final : public bke::MeshFieldInput { return VArray::ForContainer(std::move(corner_of_face)); } + void for_each_field_input_recursive(FunctionRef fn) const + { + face_index_.node().for_each_field_input_recursive(fn); + sort_index_.node().for_each_field_input_recursive(fn); + sort_weight_.node().for_each_field_input_recursive(fn); + } + uint64_t hash() const final { return 6927982716657; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc index 13c0ca0c441..43b26785ec7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc @@ -126,6 +126,13 @@ class CornersOfVertInput final : public bke::MeshFieldInput { return VArray::ForContainer(std::move(corner_of_vertex)); } + void for_each_field_input_recursive(FunctionRef fn) const + { + vert_index_.node().for_each_field_input_recursive(fn); + sort_index_.node().for_each_field_input_recursive(fn); + sort_weight_.node().for_each_field_input_recursive(fn); + } + uint64_t hash() const final { return 3541871368173645; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc index 324f799ca89..28798484573 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc @@ -126,6 +126,13 @@ class EdgesOfVertInput final : public bke::MeshFieldInput { return VArray::ForContainer(std::move(edge_of_vertex)); } + void for_each_field_input_recursive(FunctionRef fn) const + { + vert_index_.node().for_each_field_input_recursive(fn); + sort_index_.node().for_each_field_input_recursive(fn); + sort_weight_.node().for_each_field_input_recursive(fn); + } + uint64_t hash() const final { return 98762349875636; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc index de1eeeb28fc..a9ead39fdbe 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc @@ -73,6 +73,12 @@ class OffsetCornerInFaceFieldInput final : public bke::MeshFieldInput { return VArray::ForContainer(std::move(offset_corners)); } + void for_each_field_input_recursive(FunctionRef fn) const + { + corner_index_.node().for_each_field_input_recursive(fn); + offset_.node().for_each_field_input_recursive(fn); + } + uint64_t hash() const final { return get_default_hash(offset_); diff --git a/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc index b878d24870d..cd367923254 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc @@ -89,6 +89,12 @@ class ControlPointNeighborFieldInput final : public bke::CurvesFieldInput { return VArray::ForContainer(std::move(output)); } + + void for_each_field_input_recursive(FunctionRef fn) const + { + index_.node().for_each_field_input_recursive(fn); + offset_.node().for_each_field_input_recursive(fn); + } }; class OffsetValidFieldInput final : public bke::CurvesFieldInput { @@ -138,6 +144,12 @@ class OffsetValidFieldInput final : public bke::CurvesFieldInput { }; return VArray::ForContainer(std::move(output)); } + + void for_each_field_input_recursive(FunctionRef fn) const + { + index_.node().for_each_field_input_recursive(fn); + offset_.node().for_each_field_input_recursive(fn); + } }; static void node_geo_exec(GeoNodeExecParams params) diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc index de275f3e857..47ab0de3814 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc @@ -119,6 +119,12 @@ class PackIslandsFieldInput final : public bke::MeshFieldInput { return construct_uv_gvarray(mesh, selection_field, uv_field, rotate, margin, domain); } + void for_each_field_input_recursive(FunctionRef fn) const + { + selection_field.node().for_each_field_input_recursive(fn); + uv_field.node().for_each_field_input_recursive(fn); + } + std::optional preferred_domain(const Mesh & /*mesh*/) const override { return ATTR_DOMAIN_CORNER; diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc index 075be8fa010..eeca22517e3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc @@ -161,6 +161,12 @@ class UnwrapFieldInput final : public bke::MeshFieldInput { return construct_uv_gvarray(mesh, selection, seam, fill_holes, margin, method, domain); } + void for_each_field_input_recursive(FunctionRef fn) const + { + selection.node().for_each_field_input_recursive(fn); + seam.node().for_each_field_input_recursive(fn); + } + std::optional preferred_domain(const Mesh & /*mesh*/) const override { return ATTR_DOMAIN_CORNER; From 1a9cf9c745f1fde4b836cbd402b0732c5a544d3f Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 3 Jan 2023 12:40:17 +0100 Subject: [PATCH 0368/1522] Cleanup: add missing trailing underscores for private data members --- .../nodes/node_geo_uv_pack_islands.cc | 22 ++++++++-------- .../geometry/nodes/node_geo_uv_unwrap.cc | 26 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc index 47ab0de3814..a0f7f58c03b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc @@ -93,10 +93,10 @@ static VArray construct_uv_gvarray(const Mesh &mesh, class PackIslandsFieldInput final : public bke::MeshFieldInput { private: - const Field selection_field; - const Field uv_field; - const bool rotate; - const float margin; + const Field selection_field_; + const Field uv_field_; + const bool rotate_; + const float margin_; public: PackIslandsFieldInput(const Field selection_field, @@ -104,10 +104,10 @@ class PackIslandsFieldInput final : public bke::MeshFieldInput { const bool rotate, const float margin) : bke::MeshFieldInput(CPPType::get(), "Pack UV Islands Field"), - selection_field(selection_field), - uv_field(uv_field), - rotate(rotate), - margin(margin) + selection_field_(selection_field), + uv_field_(uv_field), + rotate_(rotate), + margin_(margin) { category_ = Category::Generated; } @@ -116,13 +116,13 @@ class PackIslandsFieldInput final : public bke::MeshFieldInput { const eAttrDomain domain, const IndexMask /*mask*/) const final { - return construct_uv_gvarray(mesh, selection_field, uv_field, rotate, margin, domain); + return construct_uv_gvarray(mesh, selection_field_, uv_field_, rotate_, margin_, domain); } void for_each_field_input_recursive(FunctionRef fn) const { - selection_field.node().for_each_field_input_recursive(fn); - uv_field.node().for_each_field_input_recursive(fn); + selection_field_.node().for_each_field_input_recursive(fn); + uv_field_.node().for_each_field_input_recursive(fn); } std::optional preferred_domain(const Mesh & /*mesh*/) const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc index eeca22517e3..9ababee3f98 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc @@ -132,11 +132,11 @@ static VArray construct_uv_gvarray(const Mesh &mesh, class UnwrapFieldInput final : public bke::MeshFieldInput { private: - const Field selection; - const Field seam; - const bool fill_holes; - const float margin; - const GeometryNodeUVUnwrapMethod method; + const Field selection_; + const Field seam_; + const bool fill_holes_; + const float margin_; + const GeometryNodeUVUnwrapMethod method_; public: UnwrapFieldInput(const Field selection, @@ -145,11 +145,11 @@ class UnwrapFieldInput final : public bke::MeshFieldInput { const float margin, const GeometryNodeUVUnwrapMethod method) : bke::MeshFieldInput(CPPType::get(), "UV Unwrap Field"), - selection(selection), - seam(seam), - fill_holes(fill_holes), - margin(margin), - method(method) + selection_(selection), + seam_(seam), + fill_holes_(fill_holes), + margin_(margin), + method_(method) { category_ = Category::Generated; } @@ -158,13 +158,13 @@ class UnwrapFieldInput final : public bke::MeshFieldInput { const eAttrDomain domain, const IndexMask /*mask*/) const final { - return construct_uv_gvarray(mesh, selection, seam, fill_holes, margin, method, domain); + return construct_uv_gvarray(mesh, selection_, seam_, fill_holes_, margin_, method_, domain); } void for_each_field_input_recursive(FunctionRef fn) const { - selection.node().for_each_field_input_recursive(fn); - seam.node().for_each_field_input_recursive(fn); + selection_.node().for_each_field_input_recursive(fn); + seam_.node().for_each_field_input_recursive(fn); } std::optional preferred_domain(const Mesh & /*mesh*/) const override From 8dbfbac92821b3d17cfb109b2a9f0b0b1251b62d Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 3 Jan 2023 12:52:44 +0100 Subject: [PATCH 0369/1522] Nodes: add utility methods for bNodeLink and bNodeSocket This was part of D16858. --- source/blender/blenkernel/BKE_node_runtime.hh | 19 +++++++++++++++++++ source/blender/makesdna/DNA_node_types.h | 6 ++++++ 2 files changed, 25 insertions(+) diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index a577630678f..6941bcb023a 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -655,6 +655,11 @@ inline bool bNodeLink::is_available() const return this->fromsock->is_available() && this->tosock->is_available(); } +inline bool bNodeLink::is_used() const +{ + return !this->is_muted() && this->is_available(); +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -673,6 +678,20 @@ inline int bNodeSocket::index_in_tree() const return this->runtime->index_in_all_sockets; } +inline int bNodeSocket::index_in_all_inputs() const +{ + BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this)); + BLI_assert(this->is_input()); + return this->runtime->index_in_inout_sockets; +} + +inline int bNodeSocket::index_in_all_outputs() const +{ + BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this)); + BLI_assert(this->is_output()); + return this->runtime->index_in_inout_sockets; +} + inline bool bNodeSocket::is_hidden() const { return (this->flag & SOCK_HIDDEN) != 0; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index cdc69662534..a003947cabe 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -187,6 +187,10 @@ typedef struct bNodeSocket { int index() const; /** Socket index in the entire node tree. Inputs and outputs share the same index space. */ int index_in_tree() const; + /** Socket index in the entire node tree. All inputs share the same index space. */ + int index_in_all_inputs() const; + /** Socket index in the entire node tree. All outputs share the same index space. */ + int index_in_all_outputs() const; /** Node this socket belongs to. */ bNode &owner_node(); const bNode &owner_node() const; @@ -490,6 +494,8 @@ typedef struct bNodeLink { #ifdef __cplusplus bool is_muted() const; bool is_available() const; + /** Both linked sockets are available and the link is not muted. */ + bool is_used() const; #endif } bNodeLink; From 88748e5cbcf21539af37d16f689c0a68a6648a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 3 Jan 2023 11:45:58 +0100 Subject: [PATCH 0370/1522] Editors: Add 'is bidirectional' option to sliders Add a field `is_bidirectional` to sliders (`tSlider`). By defafult this is `false`; when set to `true` the slider allows negative values. The allowed ranges are now: - No overshoot, no bidirectional: `[0, 1]` - No overshoot, bidirectional: `[-1, 1]` - Overshoot, no bidirectional: `[0, infinity)` - Overshoot, bidirectional: `(-infinity, infinity)` This will be used for the pose library blending operator, where sliding to the right (postitive) blends as normal, and sliding to the left (negative) flips the pose before blending. --- source/blender/editors/include/ED_util.h | 3 +++ source/blender/editors/util/ed_draw.c | 30 +++++++++++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index f235f696ccc..9b19116b1fe 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -98,6 +98,9 @@ void ED_slider_factor_set(struct tSlider *slider, float factor); bool ED_slider_allow_overshoot_get(struct tSlider *slider); void ED_slider_allow_overshoot_set(struct tSlider *slider, bool value); +bool ED_slider_is_bidirectional_get(struct tSlider *slider); +void ED_slider_is_bidirectional_set(struct tSlider *slider, bool value); + /* ************** XXX OLD CRUFT WARNING ************* */ /** diff --git a/source/blender/editors/util/ed_draw.c b/source/blender/editors/util/ed_draw.c index 4c376363d85..011d7862071 100644 --- a/source/blender/editors/util/ed_draw.c +++ b/source/blender/editors/util/ed_draw.c @@ -75,6 +75,11 @@ typedef struct tSlider { /** Last mouse cursor position used for mouse movement delta calculation. */ float last_cursor[2]; + /** Allow negative values as well. + * This is set by the code that uses the slider, as not all operations support + * negative values. */ + bool is_bidirectional; + /** Enable range beyond 0-100%. * This is set by the code that uses the slider, as not all operations support * extrapolation. */ @@ -89,6 +94,7 @@ typedef struct tSlider { /** Reduces factor delta from mouse movement. */ bool precision; + } tSlider; static void draw_overshoot_triangle(const uint8_t color[4], @@ -279,14 +285,19 @@ static void slider_draw(const struct bContext *UNUSED(C), ARegion *region, void .ymax = line_y + line_width / 2, }; float line_start_factor = 0; - int handle_pos_x = main_line_rect.xmin + SLIDE_PIXEL_DISTANCE * slider->factor; - + int handle_pos_x; if (slider->overshoot) { main_line_rect.xmin = main_line_rect.xmin - SLIDE_PIXEL_DISTANCE * OVERSHOOT_RANGE_DELTA; main_line_rect.xmax = main_line_rect.xmax + SLIDE_PIXEL_DISTANCE * OVERSHOOT_RANGE_DELTA; line_start_factor = slider->factor - 0.5f - OVERSHOOT_RANGE_DELTA; handle_pos_x = region->winx / 2; } + else if (slider->is_bidirectional) { + handle_pos_x = main_line_rect.xmin + SLIDE_PIXEL_DISTANCE * (slider->factor / 2 + 0.5f); + } + else { + handle_pos_x = main_line_rect.xmin + SLIDE_PIXEL_DISTANCE * slider->factor; + } draw_backdrop(fontid, &main_line_rect, color_bg, slider->region_header->winy, base_tick_height); @@ -350,7 +361,10 @@ static void slider_update_factor(tSlider *slider, const wmEvent *event) copy_v2fl_v2i(slider->last_cursor, event->xy); if (!slider->overshoot) { - slider->factor = clamp_f(slider->factor, 0, 1); + slider->factor = clamp_f(slider->factor, -1, 1); + } + if (!slider->is_bidirectional) { + slider->factor = max_ff(slider->factor, 0); } if (slider->increments) { @@ -504,6 +518,16 @@ void ED_slider_allow_overshoot_set(struct tSlider *slider, const bool value) slider->allow_overshoot = value; } +bool ED_slider_is_bidirectional_get(struct tSlider *slider) +{ + return slider->is_bidirectional; +} + +void ED_slider_is_bidirectional_set(struct tSlider *slider, const bool value) +{ + slider->is_bidirectional = value; +} + /** \} */ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *region, void *arg_info) From c82311bb8efd24abec6f50a18256c636b78ef626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 3 Jan 2023 12:31:05 +0100 Subject: [PATCH 0371/1522] Pose Library: allow negative blend factors to flip the pose Interactive blending of poses can now use negative factors (i.e. drag to the left) to blend in the flipped pose. This reverts rB6eb1c98b15bb7ea6cf184b08617f24c7afb91b6c where the F key was used to flip the pose. That was already described as stop-gap measure, and the new behaviour is more intuitive & direct. Functionality over-the-shoulder reviewed by @hjalti. --- source/blender/editors/armature/pose_lib_2.c | 136 +++++++++---------- 1 file changed, 67 insertions(+), 69 deletions(-) diff --git a/source/blender/editors/armature/pose_lib_2.c b/source/blender/editors/armature/pose_lib_2.c index 8167ac563f6..29e6ec77ede 100644 --- a/source/blender/editors/armature/pose_lib_2.c +++ b/source/blender/editors/armature/pose_lib_2.c @@ -66,13 +66,14 @@ typedef struct PoseBlendData { /* For temp-loading the Action from the pose library. */ AssetTempIDConsumer *temp_id_consumer; - /* Blend factor, interval [0, 1] for interpolating between current and given pose. */ + /* Blend factor, interval [-1, 1] for interpolating between current and given pose. + * Positive factors will blend in `act`, whereas negative factors will blend in `act_flipped`. */ float blend_factor; struct PoseBackup *pose_backup; - Object *ob; /* Object to work on. */ - bAction *act; /* Pose to blend into the current pose. */ - bool free_action; + Object *ob; /* Object to work on. */ + bAction *act; /* Pose to blend into the current pose. */ + bAction *act_flipped; /* Flipped copy of `act`. */ Scene *scene; /* For auto-keying. */ ScrArea *area; /* For drawing status text. */ @@ -83,12 +84,19 @@ typedef struct PoseBlendData { char headerstr[UI_MAX_DRAW_STR]; } PoseBlendData; -static void poselib_blend_flip_pose(bContext *C, wmOperator *op); +/** Return the bAction that should be blended. + * This is either pbd->act or pbd->act_flipped, depending on the sign of the blend factor. + */ +static bAction *poselib_action_to_blend(PoseBlendData *pbd) +{ + return (pbd->blend_factor >= 0) ? pbd->act : pbd->act_flipped; +} /* Makes a copy of the current pose for restoration purposes - doesn't do constraints currently */ static void poselib_backup_posecopy(PoseBlendData *pbd) { - pbd->pose_backup = BKE_pose_backup_create_selected_bones(pbd->ob, pbd->act); + const bAction *action = poselib_action_to_blend(pbd); + pbd->pose_backup = BKE_pose_backup_create_selected_bones(pbd->ob, action); if (pbd->state == POSE_BLEND_INIT) { /* Ready for blending now. */ @@ -168,19 +176,32 @@ static void poselib_blend_apply(bContext *C, wmOperator *op) /* Perform the actual blending. */ struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, 0.0f); - BKE_pose_apply_action_blend(pbd->ob, pbd->act, &anim_eval_context, pbd->blend_factor); + bAction *to_blend = poselib_action_to_blend(pbd); + BKE_pose_apply_action_blend(pbd->ob, to_blend, &anim_eval_context, fabs(pbd->blend_factor)); } /* ---------------------------- */ static void poselib_blend_set_factor(PoseBlendData *pbd, const float new_factor) { - pbd->blend_factor = CLAMPIS(new_factor, 0.0f, 1.0f); + const bool sign_changed = signf(new_factor) != signf(pbd->blend_factor); + if (sign_changed) { + /* The zero point was crossed, meaning that the pose will be flipped. This means the pose + * backup has to change, as it only contains the bones for one side. */ + BKE_pose_backup_restore(pbd->pose_backup); + BKE_pose_backup_free(pbd->pose_backup); + } + + pbd->blend_factor = CLAMPIS(new_factor, -1.0f, 1.0f); pbd->needs_redraw = true; + + if (sign_changed) { + poselib_backup_posecopy(pbd); + } } /* Return operator return value. */ -static int poselib_blend_handle_event(bContext *C, wmOperator *op, const wmEvent *event) +static int poselib_blend_handle_event(bContext *UNUSED(C), wmOperator *op, const wmEvent *event) { PoseBlendData *pbd = op->customdata; @@ -226,10 +247,6 @@ static int poselib_blend_handle_event(bContext *C, wmOperator *op, const wmEvent pbd->state = pbd->state == POSE_BLEND_BLENDING ? POSE_BLEND_ORIGINAL : POSE_BLEND_BLENDING; pbd->needs_redraw = true; break; - - case EVT_FKEY: - poselib_blend_flip_pose(C, op); - break; } return OPERATOR_RUNNING_MODAL; @@ -280,30 +297,6 @@ static bAction *flip_pose(bContext *C, Object *ob, bAction *action) return action_copy; } -/* Flip the target pose the interactive blend operator is currently using. */ -static void poselib_blend_flip_pose(bContext *C, wmOperator *op) -{ - PoseBlendData *pbd = op->customdata; - bAction *old_action = pbd->act; - bAction *new_action = flip_pose(C, pbd->ob, old_action); - - /* Before flipping over to the other side, this side needs to be restored. */ - BKE_pose_backup_restore(pbd->pose_backup); - BKE_pose_backup_free(pbd->pose_backup); - pbd->pose_backup = NULL; - - if (pbd->free_action) { - BKE_id_free(NULL, old_action); - } - - pbd->free_action = true; - pbd->act = new_action; - pbd->needs_redraw = true; - - /* Refresh the pose backup to use the flipped bones. */ - poselib_backup_posecopy(pbd); -} - /* Return true on success, false if the context isn't suitable. */ static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent *event) { @@ -320,18 +313,21 @@ static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent * PoseBlendData *pbd; op->customdata = pbd = MEM_callocN(sizeof(PoseBlendData), "PoseLib Preview Data"); - bAction *action = poselib_blend_init_get_action(C, op); - if (action == NULL) { + pbd->act = poselib_blend_init_get_action(C, op); + if (pbd->act == NULL) { return false; } - /* Maybe flip the Action. */ + /* Passing `flipped=True` is the same as flipping the sign of the blend factor. */ const bool apply_flipped = RNA_boolean_get(op->ptr, "flipped"); - if (apply_flipped) { - action = flip_pose(C, ob, action); - pbd->free_action = true; + const float multiply_factor = apply_flipped ? -1.0f : 1.0f; + pbd->blend_factor = multiply_factor * RNA_float_get(op->ptr, "blend_factor"); + + /* Only construct the flipped pose if there is a chance it's actually needed. */ + const bool is_interactive = (event != NULL); + if (is_interactive || pbd->blend_factor < 0) { + pbd->act_flipped = flip_pose(C, ob, pbd->act); } - pbd->act = action; /* Get the basic data. */ pbd->ob = ob; @@ -342,12 +338,12 @@ static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent * pbd->state = POSE_BLEND_INIT; pbd->needs_redraw = true; - pbd->blend_factor = RNA_float_get(op->ptr, "blend_factor"); + /* Just to avoid a clang-analyzer warning (false positive), it's set properly below. */ pbd->release_confirm_info.use_release_confirm = false; /* Release confirm data. Only available if there's an event to work with. */ - if (event != NULL) { + if (is_interactive) { PropertyRNA *release_confirm_prop = RNA_struct_find_property(op->ptr, "release_confirm"); pbd->release_confirm_info.use_release_confirm = (release_confirm_prop != NULL) && RNA_property_boolean_get(op->ptr, @@ -356,10 +352,11 @@ static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent * ED_slider_init(pbd->slider, event); ED_slider_factor_set(pbd->slider, pbd->blend_factor); ED_slider_allow_overshoot_set(pbd->slider, false); + ED_slider_is_bidirectional_set(pbd->slider, true); } if (pbd->release_confirm_info.use_release_confirm) { - BLI_assert(event != NULL); + BLI_assert(is_interactive); pbd->release_confirm_info.init_event_type = WM_userdef_event_type_from_keymap_type( event->type); } @@ -397,7 +394,8 @@ static void poselib_blend_cleanup(bContext *C, wmOperator *op) poselib_keytag_pose(C, scene, pbd); /* Ensure the redo panel has the actually-used value, instead of the initial value. */ - RNA_float_set(op->ptr, "blend_factor", pbd->blend_factor); + RNA_float_set(op->ptr, "blend_factor", fabs(pbd->blend_factor)); + RNA_boolean_set(op->ptr, "flipped", pbd->blend_factor < 0); break; } @@ -426,10 +424,8 @@ static void poselib_blend_free(wmOperator *op) return; } - if (pbd->free_action) { - /* Run before #poselib_tempload_exit to avoid any problems from indirectly - * referenced ID pointers. */ - BKE_id_free(NULL, pbd->act); + if (pbd->act_flipped) { + BKE_id_free(NULL, pbd->act_flipped); } poselib_tempload_exit(pbd); @@ -489,11 +485,7 @@ static int poselib_blend_modal(bContext *C, wmOperator *op, const wmEvent *event strcpy(tab_string, TIP_("[Tab] - Show blended pose")); } - BLI_snprintf(status_string, - sizeof(status_string), - "[F] - Flip pose | %s | %s", - tab_string, - slider_string); + BLI_snprintf(status_string, sizeof(status_string), "%s | %s", tab_string, slider_string); ED_workspace_status_text(C, status_string); poselib_blend_apply(C, op); @@ -574,17 +566,19 @@ void POSELIB_OT_apply_pose_asset(wmOperatorType *ot) RNA_def_float_factor(ot->srna, "blend_factor", 1.0f, - 0.0f, + -1.0f, 1.0f, "Blend Factor", - "Amount that the pose is applied on top of the existing poses", - 0.0f, + "Amount that the pose is applied on top of the existing poses. A negative " + "value will apply the pose flipped over the X-axis", + -1.0f, 1.0f); RNA_def_boolean(ot->srna, "flipped", false, "Apply Flipped", - "When enabled, applies the pose flipped over the X-axis"); + "When enabled, applies the pose flipped over the X-axis. This is the same as " + "passing a negative `blend_factor`"); } void POSELIB_OT_blend_pose_asset(wmOperatorType *ot) @@ -610,22 +604,26 @@ void POSELIB_OT_blend_pose_asset(wmOperatorType *ot) prop = RNA_def_float_factor(ot->srna, "blend_factor", 0.0f, - 0.0f, + -1.0f, 1.0f, "Blend Factor", - "Amount that the pose is applied on top of the existing poses", - 0.0f, + "Amount that the pose is applied on top of the existing poses. A " + "negative value will apply the pose flipped over the X-axis", + -1.0f, 1.0f); /* Blending should always start at 0%, and not at whatever percentage was last used. This RNA * property just exists for symmetry with the Apply operator (and thus simplicity of the rest of * the code, which can assume this property exists). */ RNA_def_property_flag(prop, PROP_SKIP_SAVE); - RNA_def_boolean(ot->srna, - "flipped", - false, - "Apply Flipped", - "When enabled, applies the pose flipped over the X-axis"); + prop = RNA_def_boolean(ot->srna, + "flipped", + false, + "Apply Flipped", + "When enabled, applies the pose flipped over the X-axis. This is the " + "same as passing a negative `blend_factor`"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "release_confirm", false, From 0c0cdb8010a390f3eaa1b43fa0e8afaf52b1ff61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 3 Jan 2023 14:42:08 +0100 Subject: [PATCH 0372/1522] Pose library: avoid saving the 'flipped' operator property Avoid saving the 'flipped' operator property of the "apply pose asset" (`POSELIB_OT_apply_pose_asset`) operator. This caused problems: when choosing "Apply Pose Flipped" in the asset browser, double-clicking a pose would cause it to always be flipped. --- source/blender/editors/armature/pose_lib_2.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/armature/pose_lib_2.c b/source/blender/editors/armature/pose_lib_2.c index 29e6ec77ede..1ea8bc275e9 100644 --- a/source/blender/editors/armature/pose_lib_2.c +++ b/source/blender/editors/armature/pose_lib_2.c @@ -550,6 +550,8 @@ static bool poselib_blend_poll(bContext *C) void POSELIB_OT_apply_pose_asset(wmOperatorType *ot) { + PropertyRNA *prop; + /* Identifiers: */ ot->name = "Apply Pose Asset"; ot->idname = "POSELIB_OT_apply_pose_asset"; @@ -573,12 +575,14 @@ void POSELIB_OT_apply_pose_asset(wmOperatorType *ot) "value will apply the pose flipped over the X-axis", -1.0f, 1.0f); - RNA_def_boolean(ot->srna, - "flipped", - false, - "Apply Flipped", - "When enabled, applies the pose flipped over the X-axis. This is the same as " - "passing a negative `blend_factor`"); + prop = RNA_def_boolean( + ot->srna, + "flipped", + false, + "Apply Flipped", + "When enabled, applies the pose flipped over the X-axis. This is the same as " + "passing a negative `blend_factor`"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } void POSELIB_OT_blend_pose_asset(wmOperatorType *ot) From 380132300e91c4e77a60edf4fea923d9e8eb31ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 3 Jan 2023 15:17:26 +0100 Subject: [PATCH 0373/1522] Editors: Slider, always hide the area header contents Always hide the area header contents when the slider UI component is used. This prevents the slider from being drawn semi-transparently on top of other UI elements. --- source/blender/editors/util/ed_draw.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/editors/util/ed_draw.c b/source/blender/editors/util/ed_draw.c index 011d7862071..1ae9608b8e6 100644 --- a/source/blender/editors/util/ed_draw.c +++ b/source/blender/editors/util/ed_draw.c @@ -397,6 +397,9 @@ tSlider *ED_slider_create(struct bContext *C) } } + /* Hide the area menu bar contents, as the slider will be drawn on top. */ + ED_area_status_text(slider->area, ""); + return slider; } From 760f2636c08c680cf749c31efb8fdb555b156c6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 3 Jan 2023 15:19:16 +0100 Subject: [PATCH 0374/1522] Cleanup: improve documentation of `ED_area_status_text` Improve the documentation of `ED_area_status_text` by actually mentioning what it does. Previously it only described how to disable its effects. --- source/blender/editors/include/ED_screen.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index e1fd53ccdee..6dfaab663f6 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -217,7 +217,8 @@ void ED_area_tag_refresh(ScrArea *area); void ED_area_do_refresh(struct bContext *C, ScrArea *area); struct AZone *ED_area_azones_update(ScrArea *area, const int mouse_xy[2]); /** - * Use NULL to disable it. + * Show the given text in the area's header, instead of its regular contents. + * Use NULL to disable this and show the regular header contents again. */ void ED_area_status_text(ScrArea *area, const char *str); /** From ecd45336156b7b0c172023f3915617e6841b7389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Tue, 3 Jan 2023 17:48:46 +0100 Subject: [PATCH 0375/1522] GPU: Texture: Fix missing cases in `validate_data_format()` This was preventing some correct API usage. --- source/blender/gpu/intern/gpu_texture_private.hh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh index fc5e39a3534..35e0bf7b953 100644 --- a/source/blender/gpu/intern/gpu_texture_private.hh +++ b/source/blender/gpu/intern/gpu_texture_private.hh @@ -491,18 +491,28 @@ inline bool validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat da case GPU_DEPTH24_STENCIL8: case GPU_DEPTH32F_STENCIL8: return ELEM(data_format, GPU_DATA_UINT_24_8, GPU_DATA_UINT); - case GPU_R8UI: case GPU_R16UI: case GPU_RG16UI: + case GPU_RGBA16UI: case GPU_R32UI: + case GPU_RG32UI: + case GPU_RGBA32UI: return data_format == GPU_DATA_UINT; - case GPU_R32I: - case GPU_RG16I: + case GPU_R8I: + case GPU_RG8I: + case GPU_RGBA8I: case GPU_R16I: + case GPU_RG16I: + case GPU_RGBA16I: + case GPU_R32I: + case GPU_RG32I: + case GPU_RGBA32I: return data_format == GPU_DATA_INT; case GPU_R8: case GPU_RG8: case GPU_RGBA8: + case GPU_R8UI: + case GPU_RG8UI: case GPU_RGBA8UI: case GPU_SRGB8_A8: return ELEM(data_format, GPU_DATA_UBYTE, GPU_DATA_FLOAT); From a6355a4542db6689b269b51b11aaaa6425471a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Tue, 3 Jan 2023 17:54:01 +0100 Subject: [PATCH 0376/1522] Metal: Add support for all matrix types * Add missing constructor for squared matrix types. * Use using instead of define for typenames. * Add `==, !=, unary-` operators * Catch all functional style constructors inside the regex --- .../blender/gpu/metal/mtl_shader_generator.mm | 8 +- .../gpu/shaders/metal/mtl_shader_defines.msl | 298 +++++++++++++----- 2 files changed, 224 insertions(+), 82 deletions(-) diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm index b938f3fd228..9ed1461f857 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.mm +++ b/source/blender/gpu/metal/mtl_shader_generator.mm @@ -519,8 +519,8 @@ char *MSLGeneratorInterface::msl_patch_default_get() } std::stringstream ss_patch; - ss_patch << datatoc_mtl_shader_shared_h << std::endl; ss_patch << datatoc_mtl_shader_defines_msl << std::endl; + ss_patch << datatoc_mtl_shader_shared_h << std::endl; size_t len = strlen(ss_patch.str().c_str()); msl_patch_default = (char *)malloc(len * sizeof(char)); @@ -607,7 +607,7 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info) /*** Regex Commands ***/ /* Source cleanup and syntax replacement. */ static std::regex remove_excess_newlines("\\n+"); - static std::regex replace_mat3("mat3\\s*\\("); + static std::regex replace_matrix_construct("mat([234](x[234])?)\\s*\\("); /* Special condition - mat3 and array constructor replacement. * Also replace excessive new lines to ensure cases are not missed. @@ -615,14 +615,14 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info) shd_builder_->glsl_vertex_source_ = std::regex_replace( shd_builder_->glsl_vertex_source_, remove_excess_newlines, "\n"); shd_builder_->glsl_vertex_source_ = std::regex_replace( - shd_builder_->glsl_vertex_source_, replace_mat3, "MAT3("); + shd_builder_->glsl_vertex_source_, replace_matrix_construct, "MAT$1("); replace_array_initializers_func(shd_builder_->glsl_vertex_source_); if (!msl_iface.uses_transform_feedback) { shd_builder_->glsl_fragment_source_ = std::regex_replace( shd_builder_->glsl_fragment_source_, remove_excess_newlines, "\n"); shd_builder_->glsl_fragment_source_ = std::regex_replace( - shd_builder_->glsl_fragment_source_, replace_mat3, "MAT3("); + shd_builder_->glsl_fragment_source_, replace_matrix_construct, "MAT$1("); replace_array_initializers_func(shd_builder_->glsl_fragment_source_); } diff --git a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl index 68ad8fb5f49..93efa16bb02 100644 --- a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl +++ b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl @@ -3,7 +3,7 @@ /** Special header for mapping commonly defined tokens to API-specific variations. * Where possible, this will adhere closely to base GLSL, where semantics are the same. * However, host code shader code may need modifying to support types where necessary variations - * exist between APIs but are not expressed through the source. (e.g. distinctio between depth2d + * exist between APIs but are not expressed through the source. (e.g. distinction between depth2d * and texture2d types in metal). */ @@ -16,19 +16,27 @@ #define DFDY_SIGN 1.0 /* Type definitions. */ -#define vec2 float2 -#define vec3 float3 -#define vec4 float4 -#define mat2 float2x2 -#define mat2x2 float2x2 -#define mat3 float3x3 -#define mat4 float4x4 -#define ivec2 int2 -#define ivec3 int3 -#define ivec4 int4 -#define uvec2 uint2 -#define uvec3 uint3 -#define uvec4 uint4 +using vec2 = float2; +using vec3 = float3; +using vec4 = float4; +using mat2x2 = float2x2; +using mat2x3 = float2x3; +using mat2x4 = float2x4; +using mat3x2 = float3x2; +using mat3x3 = float3x3; +using mat3x4 = float3x4; +using mat4x2 = float4x2; +using mat4x3 = float4x3; +using mat4x4 = float4x4; +using mat2 = float2x2; +using mat3 = float3x3; +using mat4 = float4x4; +using ivec2 = int2; +using ivec3 = int3; +using ivec4 = int4; +using uvec2 = uint2; +using uvec3 = uint3; +using uvec4 = uint4; /* MTLBOOL is used for native boolean's generated by the Metal backend, to avoid type-emulation * for GLSL bools, which are treated as integers. */ #define MTLBOOL bool @@ -687,6 +695,76 @@ inline void _texture_write_internal(thread _mtl_combined_image_sampler_3d } } +/* Matrix compare operators. */ +/** TODO(fclem): Template. */ +inline bool operator==(float4x4 a, float4x4 b) +{ + for (int i = 0; i < 4; i++) { + if (any(a[i] != b[i])) { + return false; + } + } + return true; +} +inline bool operator==(float3x3 a, float3x3 b) +{ + for (int i = 0; i < 3; i++) { + if (any(a[i] != b[i])) { + return false; + } + } + return true; +} +inline bool operator==(float2x2 a, float2x2 b) +{ + for (int i = 0; i < 2; i++) { + if (any(a[i] != b[i])) { + return false; + } + } + return true; +} + +inline bool operator!=(float4x4 a, float4x4 b) +{ + return !(a == b); +} +inline bool operator!=(float3x3 a, float3x3 b) +{ + return !(a == b); +} +inline bool operator!=(float2x2 a, float2x2 b) +{ + return !(a == b); +} + +/* Matrix unary minus operator. */ + +inline float4x4 operator-(float4x4 a) +{ + float4x4 b; + for (int i = 0; i < 4; i++) { + b[i] = -a[i]; + } + return b; +} +inline float3x3 operator-(float3x3 a) +{ + float3x3 b; + for (int i = 0; i < 3; i++) { + b[i] = -a[i]; + } + return b; +} +inline float2x2 operator-(float2x2 a) +{ + float2x2 b; + for (int i = 0; i < 2; i++) { + b[i] = -a[i]; + } + return b; +} + /* SSBO Vertex Fetch Mode. */ #ifdef MTL_SSBO_VERTEX_FETCH /* Enabled when geometry is passed via raw buffer bindings, rather than using @@ -997,47 +1075,59 @@ float4x4 inverse(float4x4 a) float b10 = a[2][1] * a[3][3] - a[2][3] * a[3][1]; float b11 = a[2][2] * a[3][3] - a[2][3] * a[3][2]; - float invdet = 1.0 / (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06); + float inv_det = 1.0 / (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06); - return float4x4(a[1][1] * b11 - a[1][2] * b10 + a[1][3] * b09, - a[0][2] * b10 - a[0][1] * b11 - a[0][3] * b09, - a[3][1] * b05 - a[3][2] * b04 + a[3][3] * b03, - a[2][2] * b04 - a[2][1] * b05 - a[2][3] * b03, - a[1][2] * b08 - a[1][0] * b11 - a[1][3] * b07, - a[0][0] * b11 - a[0][2] * b08 + a[0][3] * b07, - a[3][2] * b02 - a[3][0] * b05 - a[3][3] * b01, - a[2][0] * b05 - a[2][2] * b02 + a[2][3] * b01, - a[1][0] * b10 - a[1][1] * b08 + a[1][3] * b06, - a[0][1] * b08 - a[0][0] * b10 - a[0][3] * b06, - a[3][0] * b04 - a[3][1] * b02 + a[3][3] * b00, - a[2][1] * b02 - a[2][0] * b04 - a[2][3] * b00, - a[1][1] * b07 - a[1][0] * b09 - a[1][2] * b06, - a[0][0] * b09 - a[0][1] * b07 + a[0][2] * b06, - a[3][1] * b01 - a[3][0] * b03 - a[3][2] * b00, - a[2][0] * b03 - a[2][1] * b01 + a[2][2] * b00) * - invdet; + float4x4 adjoint{}; + adjoint[0][0] = a[1][1] * b11 - a[1][2] * b10 + a[1][3] * b09; + adjoint[0][1] = a[0][2] * b10 - a[0][1] * b11 - a[0][3] * b09; + adjoint[0][2] = a[3][1] * b05 - a[3][2] * b04 + a[3][3] * b03; + adjoint[0][3] = a[2][2] * b04 - a[2][1] * b05 - a[2][3] * b03; + adjoint[1][0] = a[1][2] * b08 - a[1][0] * b11 - a[1][3] * b07; + adjoint[1][1] = a[0][0] * b11 - a[0][2] * b08 + a[0][3] * b07; + adjoint[1][2] = a[3][2] * b02 - a[3][0] * b05 - a[3][3] * b01; + adjoint[1][3] = a[2][0] * b05 - a[2][2] * b02 + a[2][3] * b01; + adjoint[2][0] = a[1][0] * b10 - a[1][1] * b08 + a[1][3] * b06; + adjoint[2][1] = a[0][1] * b08 - a[0][0] * b10 - a[0][3] * b06; + adjoint[2][2] = a[3][0] * b04 - a[3][1] * b02 + a[3][3] * b00; + adjoint[2][3] = a[2][1] * b02 - a[2][0] * b04 - a[2][3] * b00; + adjoint[3][0] = a[1][1] * b07 - a[1][0] * b09 - a[1][2] * b06; + adjoint[3][1] = a[0][0] * b09 - a[0][1] * b07 + a[0][2] * b06; + adjoint[3][2] = a[3][1] * b01 - a[3][0] * b03 - a[3][2] * b00; + adjoint[3][3] = a[2][0] * b03 - a[2][1] * b01 + a[2][2] * b00; + return adjoint * inv_det; } float3x3 inverse(float3x3 m) { + float b00 = m[1][1] * m[2][2] - m[2][1] * m[1][2]; + float b01 = m[0][1] * m[2][2] - m[2][1] * m[0][2]; + float b02 = m[0][1] * m[1][2] - m[1][1] * m[0][2]; - float invdet = 1.0 / (m[0][0] * (m[1][1] * m[2][2] - m[2][1] * m[1][2]) - - m[1][0] * (m[0][1] * m[2][2] - m[2][1] * m[0][2]) + - m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2])); + float inv_det = 1.0 / (m[0][0] * b00 - m[1][0] * b01 + m[2][0] * b02); - float3x3 inverse(0); - inverse[0][0] = +(m[1][1] * m[2][2] - m[2][1] * m[1][2]); - inverse[1][0] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]); - inverse[2][0] = +(m[1][0] * m[2][1] - m[2][0] * m[1][1]); - inverse[0][1] = -(m[0][1] * m[2][2] - m[2][1] * m[0][2]); - inverse[1][1] = +(m[0][0] * m[2][2] - m[2][0] * m[0][2]); - inverse[2][1] = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]); - inverse[0][2] = +(m[0][1] * m[1][2] - m[1][1] * m[0][2]); - inverse[1][2] = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]); - inverse[2][2] = +(m[0][0] * m[1][1] - m[1][0] * m[0][1]); - inverse = inverse * invdet; + float3x3 adjoint{}; + adjoint[0][0] = +b00; + adjoint[0][1] = -b01; + adjoint[0][2] = +b02; + adjoint[1][0] = -(m[1][0] * m[2][2] - m[2][0] * m[1][2]); + adjoint[1][1] = +(m[0][0] * m[2][2] - m[2][0] * m[0][2]); + adjoint[1][2] = -(m[0][0] * m[1][2] - m[1][0] * m[0][2]); + adjoint[2][0] = +(m[1][0] * m[2][1] - m[2][0] * m[1][1]); + adjoint[2][1] = -(m[0][0] * m[2][1] - m[2][0] * m[0][1]); + adjoint[2][2] = +(m[0][0] * m[1][1] - m[1][0] * m[0][1]); + return adjoint * inv_det; +} - return inverse; +float2x2 inverse(float2x2 m) +{ + float inv_det = 1.0 / (m[0][0] * m[1][1] - m[1][0] * m[0][1]); + + float2x2 adjoint{}; + adjoint[0][0] = +m[1][1]; + adjoint[1][0] = -m[1][0]; + adjoint[0][1] = -m[0][1]; + adjoint[1][1] = +m[0][0]; + return adjoint * inv_det; } /* Additional overloads for builtin functions. */ @@ -1110,44 +1200,96 @@ template bool is_zero(vec a) return true; } -/* Matrix conversion fallback. */ -mat3 MAT3(vec3 a, vec3 b, vec3 c) +/** + * Matrix conversion fallback for functional style casting & constructors. + * To avoid name collision with the types, they are replaced with uppercase version + * before compilation. + */ + +mat2 MAT2x2(vec2 a, vec2 b) +{ + return mat2(a, b); +} +mat2 MAT2x2(float a1, float a2, float b1, float b2) +{ + return mat2(vec2(a1, a2), vec2(b1, b2)); +} +mat2 MAT2x2(float f) +{ + return mat2(f); +} +mat2 MAT2x2(mat3 m) +{ + return mat2(m[0].xy, m[1].xy); +} +mat2 MAT2x2(mat4 m) +{ + return mat2(m[0].xy, m[1].xy); +} + +mat3 MAT3x3(vec3 a, vec3 b, vec3 c) { return mat3(a, b, c); } -mat3 MAT3(vec3 a, vec3 b, float c1, float c2, float c3) -{ - return mat3(a, b, vec3(c1, c2, c3)); -} -mat3 MAT3(vec3 a, float b1, float b2, float b3, vec3 c) -{ - return mat3(a, vec3(b1, b2, b3), c); -} -mat3 MAT3(vec3 a, float b1, float b2, float b3, float c1, float c2, float c3) -{ - return mat3(a, vec3(b1, b2, b3), vec3(c1, c2, c3)); -} -mat3 MAT3(float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3) +mat3 MAT3x3( + float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3) { return mat3(vec3(a1, a2, a3), vec3(b1, b2, b3), vec3(c1, c2, c3)); } -mat3 MAT3(float a1, float a2, float a3, vec3 b, vec3 c) -{ - return mat3(vec3(a1, a2, a3), b, c); -} -mat3 MAT3(float a1, float a2, float a3, vec3 b, float c1, float c2, float c3) -{ - return mat3(vec3(a1, a2, a3), b, vec3(c1, c2, c3)); -} -mat3 MAT3(float a1, float a2, float a3, float b1, float b2, float b3, vec3 c) -{ - return mat3(vec3(a1, a2, a3), vec3(b1, b2, b3), c); -} -mat3 MAT3(float f) +mat3 MAT3x3(float f) { return mat3(f); } -mat3 MAT3(mat4 m) +mat3 MAT3x3(mat4 m) { - return mat4_to_mat3(m); -} \ No newline at end of file + return mat3(m[0].xyz, m[1].xyz, m[2].xyz); +} +mat3 MAT3x3(mat2 m) +{ + return mat3(vec3(m[0].xy, 0.0), vec3(m[1].xy, 0.0), vec3(0.0, 0.0, 1.0)); +} + +mat4 MAT4x4(vec4 a, vec4 b, vec4 c, vec4 d) +{ + return mat4(a, b, c, d); +} +mat4 MAT4x4(float a1, + float a2, + float a3, + float a4, + float b1, + float b2, + float b3, + float b4, + float c1, + float c2, + float c3, + float c4, + float d1, + float d2, + float d3, + float d4) +{ + return mat4( + vec4(a1, a2, a3, a4), vec4(b1, b2, b3, b4), vec4(c1, c2, c3, c4), vec4(d1, d2, d3, d4)); +} +mat4 MAT4x4(float f) +{ + return mat4(f); +} +mat4 MAT4x4(mat3 m) +{ + return mat4( + vec4(m[0].xyz, 0.0), vec4(m[1].xyz, 0.0), vec4(m[2].xyz, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); +} +mat4 MAT4x4(mat2 m) +{ + return mat4(vec4(m[0].xy, 0.0, 0.0), + vec4(m[1].xy, 0.0, 0.0), + vec4(0.0, 0.0, 1.0, 0.0), + vec4(0.0, 0.0, 0.0, 1.0)); +} + +#define MAT2 MAT2x2 +#define MAT3 MAT3x3 +#define MAT4 MAT4x4 From e091291b5b5f525cd8d38898c38cd12e4f6ec670 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 3 Jan 2023 13:34:51 -0500 Subject: [PATCH 0377/1522] Cleanup: Simplify node editor socket picking The main change is returning a socket pointer instead of using two return arguments. Also use the topology cache instead of linked lists, references over pointers, and slightly adjust whitespace. --- .../blender/editors/space_node/node_draw.cc | 56 +++++++------- .../blender/editors/space_node/node_edit.cc | 47 +++++------ .../blender/editors/space_node/node_intern.hh | 9 +-- .../editors/space_node/node_relationships.cc | 77 ++++++++----------- .../blender/editors/space_node/node_select.cc | 64 ++++++++------- source/blender/makesdna/DNA_node_types.h | 1 + 6 files changed, 118 insertions(+), 136 deletions(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index fdc82307ce0..7c12a1114ec 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -2610,6 +2610,18 @@ int node_get_resize_cursor(NodeResizeDirection directions) return WM_CURSOR_EDIT; } +static const bNode *find_node_under_cursor(SpaceNode &snode, const float2 &cursor) +{ + /* Check nodes front to back. */ + const Span nodes = snode.edittree->all_nodes(); + for (int i = nodes.index_range().last(); i > 0; i--) { + if (BLI_rctf_isect_pt(&nodes[i]->runtime->totr, cursor[0], cursor[1])) { + return nodes[i]; + } + } + return nullptr; +} + void node_set_cursor(wmWindow &win, SpaceNode &snode, const float2 &cursor) { const bNodeTree *ntree = snode.edittree; @@ -2617,36 +2629,28 @@ void node_set_cursor(wmWindow &win, SpaceNode &snode, const float2 &cursor) WM_cursor_set(&win, WM_CURSOR_DEFAULT); return; } - - bNode *node; - bNodeSocket *sock; - int wmcursor = WM_CURSOR_DEFAULT; - - if (node_find_indicated_socket( - snode, &node, &sock, cursor, (eNodeSocketInOut)(SOCK_IN | SOCK_OUT))) { + if (node_find_indicated_socket(snode, cursor, SOCK_IN | SOCK_OUT)) { + WM_cursor_set(&win, WM_CURSOR_DEFAULT); + return; + } + const bNode *node = find_node_under_cursor(snode, cursor); + if (!node) { + WM_cursor_set(&win, WM_CURSOR_DEFAULT); + return; + } + const NodeResizeDirection dir = node_get_resize_direction(node, cursor[0], cursor[1]); + if (node->is_frame() && dir == NODE_RESIZE_NONE) { + /* Indicate that frame nodes can be moved/selected on their borders. */ + const rctf frame_inside = node_frame_rect_inside(*node); + if (!BLI_rctf_isect_pt(&frame_inside, cursor[0], cursor[1])) { + WM_cursor_set(&win, WM_CURSOR_NSEW_SCROLL); + return; + } WM_cursor_set(&win, WM_CURSOR_DEFAULT); return; } - /* Check nodes front to back. */ - for (node = (bNode *)ntree->nodes.last; node; node = node->prev) { - if (BLI_rctf_isect_pt(&node->runtime->totr, cursor[0], cursor[1])) { - break; /* First hit on node stops. */ - } - } - if (node) { - NodeResizeDirection dir = node_get_resize_direction(node, cursor[0], cursor[1]); - wmcursor = node_get_resize_cursor(dir); - /* We want to indicate that Frame nodes can be moved/selected on their borders. */ - if (node->type == NODE_FRAME && dir == NODE_RESIZE_NONE) { - const rctf frame_inside = node_frame_rect_inside(*node); - if (!BLI_rctf_isect_pt(&frame_inside, cursor[0], cursor[1])) { - wmcursor = WM_CURSOR_NSEW_SCROLL; - } - } - } - - WM_cursor_set(&win, wmcursor); + WM_cursor_set(&win, node_get_resize_cursor(dir)); } static void count_multi_input_socket_links(bNodeTree &ntree, SpaceNode &snode) diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 1d132c99ec1..940216db9a3 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -1205,24 +1205,21 @@ static bool cursor_isect_multi_input_socket(const float2 &cursor, const bNodeSoc return false; } -bool node_find_indicated_socket(SpaceNode &snode, - bNode **nodep, - bNodeSocket **sockp, - const float2 &cursor, - const eNodeSocketInOut in_out) +bNodeSocket *node_find_indicated_socket(SpaceNode &snode, + const float2 &cursor, + const eNodeSocketInOut in_out) { rctf rect; - const float size_sock_padded = NODE_SOCKSIZE + 4; - *nodep = nullptr; - *sockp = nullptr; + snode.edittree->ensure_topology_cache(); + + const Span nodes = snode.edittree->all_nodes(); + for (int i = nodes.index_range().last(); i > 0; i--) { + bNode &node = *nodes[i]; - /* check if we click in a socket */ - LISTBASE_FOREACH_BACKWARD (bNode *, node, &snode.edittree->nodes) { BLI_rctf_init_pt_radius(&rect, cursor, size_sock_padded); - - if (!(node->flag & NODE_HIDDEN)) { + if (!(node.flag & NODE_HIDDEN)) { /* extra padding inside and out - allow dragging on the text areas too */ if (in_out == SOCK_IN) { rect.xmax += NODE_SOCKSIZE; @@ -1235,37 +1232,31 @@ bool node_find_indicated_socket(SpaceNode &snode, } if (in_out & SOCK_IN) { - LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { + for (bNodeSocket *sock : node.input_sockets()) { if (sock->is_visible()) { const float2 location(sock->runtime->locx, sock->runtime->locy); - if (sock->flag & SOCK_MULTI_INPUT && !(node->flag & NODE_HIDDEN)) { + if (sock->flag & SOCK_MULTI_INPUT && !(node.flag & NODE_HIDDEN)) { if (cursor_isect_multi_input_socket(cursor, *sock)) { - if (!socket_is_occluded(location, *node, snode)) { - *nodep = node; - *sockp = sock; - return true; + if (!socket_is_occluded(location, node, snode)) { + return sock; } } } else if (BLI_rctf_isect_pt(&rect, location.x, location.y)) { - if (!socket_is_occluded(location, *node, snode)) { - *nodep = node; - *sockp = sock; - return true; + if (!socket_is_occluded(location, node, snode)) { + return sock; } } } } } if (in_out & SOCK_OUT) { - LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { + for (bNodeSocket *sock : node.output_sockets()) { if (sock->is_visible()) { const float2 location(sock->runtime->locx, sock->runtime->locy); if (BLI_rctf_isect_pt(&rect, location.x, location.y)) { - if (!socket_is_occluded(location, *node, snode)) { - *nodep = node; - *sockp = sock; - return true; + if (!socket_is_occluded(location, node, snode)) { + return sock; } } } @@ -1273,7 +1264,7 @@ bool node_find_indicated_socket(SpaceNode &snode, } } - return false; + return nullptr; } /** \} */ diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index 5e2fcfeb87c..74ee9f6b3ad 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -311,12 +311,9 @@ bool composite_node_editable(bContext *C); bool node_has_hidden_sockets(bNode *node); void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set); int node_render_changed_exec(bContext *, wmOperator *); -/** Type is #SOCK_IN and/or #SOCK_OUT. */ -bool node_find_indicated_socket(SpaceNode &snode, - bNode **nodep, - bNodeSocket **sockp, - const float2 &cursor, - eNodeSocketInOut in_out); +bNodeSocket *node_find_indicated_socket(SpaceNode &snode, + const float2 &cursor, + eNodeSocketInOut in_out); float node_link_dim_factor(const View2D &v2d, const bNodeLink &link); bool node_link_is_hidden_or_dimmed(const View2D &v2d, const bNodeLink &link); diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index b21f69259de..1025c1b2edf 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -124,27 +124,24 @@ static void pick_input_link_by_link_intersect(const bContext &C, float2 drag_start; RNA_float_get_array(op.ptr, "drag_start", drag_start); - bNode *node; - bNodeSocket *socket; - node_find_indicated_socket(*snode, &node, &socket, drag_start, SOCK_IN); + bNodeSocket *socket = node_find_indicated_socket(*snode, drag_start, SOCK_IN); + bNode &node = socket->owner_node(); /* Distance to test overlapping of cursor on link. */ const float cursor_link_touch_distance = 12.5f * UI_DPI_FAC; bNodeLink *link_to_pick = nullptr; clear_picking_highlight(&snode->edittree->links); - LISTBASE_FOREACH (bNodeLink *, link, &snode->edittree->links) { - if (link->tosock == socket) { - /* Test if the cursor is near a link. */ - std::array coords; - node_link_bezier_points_evaluated(*link, coords); + for (bNodeLink *link : socket->directly_linked_links()) { + /* Test if the cursor is near a link. */ + std::array coords; + node_link_bezier_points_evaluated(*link, coords); - for (const int i : IndexRange(coords.size() - 1)) { - const float distance = dist_squared_to_line_segment_v2(cursor, coords[i], coords[i + 1]); - if (distance < cursor_link_touch_distance) { - link_to_pick = link; - nldrag.last_picked_multi_input_socket_link = link_to_pick; - } + for (const int i : IndexRange(coords.size() - 1)) { + const float distance = dist_squared_to_line_segment_v2(cursor, coords[i], coords[i + 1]); + if (distance < cursor_link_touch_distance) { + link_to_pick = link; + nldrag.last_picked_multi_input_socket_link = link_to_pick; } } } @@ -164,8 +161,8 @@ static void pick_input_link_by_link_intersect(const bContext &C, link_to_pick->flag |= NODE_LINK_TEMP_HIGHLIGHT; ED_area_tag_redraw(CTX_wm_area(&C)); - if (!node_find_indicated_socket(*snode, &node, &socket, cursor, SOCK_IN)) { - pick_link(nldrag, *snode, node, *link_to_pick); + if (!node_find_indicated_socket(*snode, cursor, SOCK_IN)) { + pick_link(nldrag, *snode, &node, *link_to_pick); } } } @@ -952,13 +949,11 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur bNodeLinkDrag &nldrag = *static_cast(op.customdata); if (nldrag.in_out == SOCK_OUT) { - bNode *tnode; - bNodeSocket *tsock = nullptr; - snode.edittree->ensure_topology_cache(); - if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_IN)) { + if (bNodeSocket *tsock = node_find_indicated_socket(snode, cursor, SOCK_IN)) { + bNode &tnode = tsock->owner_node(); for (bNodeLink &link : nldrag.links) { /* skip if socket is on the same node as the fromsock */ - if (tnode && link.fromnode == tnode) { + if (link.fromnode == &tnode) { continue; } @@ -972,16 +967,16 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur } /* attach links to the socket */ - link.tonode = tnode; + link.tonode = &tnode; link.tosock = tsock; - nldrag.last_node_hovered_while_dragging_a_link = tnode; + nldrag.last_node_hovered_while_dragging_a_link = &tnode; if (existing_link_connected_to_fromsock) { link.multi_input_socket_index = existing_link_connected_to_fromsock->multi_input_socket_index; continue; } if (link.tosock && link.tosock->flag & SOCK_MULTI_INPUT) { - sort_multi_input_socket_links_with_drag(*tnode, link, cursor); + sort_multi_input_socket_links_with_drag(tnode, link, cursor); } } } @@ -997,21 +992,20 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur } } else { - bNode *tnode; - bNodeSocket *tsock = nullptr; - if (node_find_indicated_socket(snode, &tnode, &tsock, cursor, SOCK_OUT)) { + if (bNodeSocket *tsock = node_find_indicated_socket(snode, cursor, SOCK_OUT)) { + bNode &node = tsock->owner_node(); for (bNodeLink &link : nldrag.links) { /* skip if this is already the target socket */ if (link.fromsock == tsock) { continue; } /* skip if socket is on the same node as the fromsock */ - if (tnode && link.tonode == tnode) { + if (link.tonode == &node) { continue; } /* attach links to the socket */ - link.fromnode = tnode; + link.fromnode = &node; link.fromsock = tsock; } } @@ -1094,12 +1088,11 @@ static std::unique_ptr node_link_init(SpaceNode &snode, const float2 cursor, const bool detach) { - /* output indicated? */ - bNode *node; - bNodeSocket *sock; - if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_OUT)) { + if (bNodeSocket *sock = node_find_indicated_socket(snode, cursor, SOCK_OUT)) { + bNode &node = sock->owner_node(); + std::unique_ptr nldrag = std::make_unique(); - nldrag->start_node = node; + nldrag->start_node = &node; nldrag->start_socket = sock; nldrag->start_link_count = nodeCountSocketLinks(snode.edittree, sock); int link_limit = nodeSocketLinkLimit(sock); @@ -1121,16 +1114,16 @@ static std::unique_ptr node_link_init(SpaceNode &snode, else { /* dragged links are fixed on output side */ nldrag->in_out = SOCK_OUT; - nldrag->links.append(create_drag_link(*node, *sock)); + nldrag->links.append(create_drag_link(node, *sock)); } return nldrag; } - /* or an input? */ - if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN)) { + if (bNodeSocket *sock = node_find_indicated_socket(snode, cursor, SOCK_IN)) { + bNode &node = sock->owner_node(); std::unique_ptr nldrag = std::make_unique(); - nldrag->last_node_hovered_while_dragging_a_link = node; - nldrag->start_node = node; + nldrag->last_node_hovered_while_dragging_a_link = &node; + nldrag->start_node = &node; nldrag->start_socket = sock; nldrag->start_link_count = nodeCountSocketLinks(snode.edittree, sock); @@ -1154,15 +1147,13 @@ static std::unique_ptr node_link_init(SpaceNode &snode, nodeRemLink(snode.edittree, link_to_pick); /* send changed event to original link->tonode */ - if (node) { - BKE_ntree_update_tag_node_property(snode.edittree, node); - } + BKE_ntree_update_tag_node_property(snode.edittree, &node); } } else { /* dragged links are fixed on input side */ nldrag->in_out = SOCK_IN; - nldrag->links.append(create_drag_link(*node, *sock)); + nldrag->links.append(create_drag_link(node, *sock)); } return nldrag; } diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index 67ed9a34c7d..9f133f10c1f 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -175,14 +175,9 @@ static bool is_position_over_node_or_socket(SpaceNode &snode, const float2 &mous if (node_under_mouse_tweak(*snode.edittree, mouse)) { return true; } - - bNode *node; - bNodeSocket *sock; - if (node_find_indicated_socket( - snode, &node, &sock, mouse, (eNodeSocketInOut)(SOCK_IN | SOCK_OUT))) { + if (node_find_indicated_socket(snode, mouse, SOCK_IN | SOCK_OUT)) { return true; } - return false; } @@ -532,9 +527,8 @@ static bool node_mouse_select(bContext *C, const Object *ob = CTX_data_active_object(C); const Scene *scene = CTX_data_scene(C); const wmWindowManager *wm = CTX_wm_manager(C); - bNode *node; + bNode *node = nullptr; bNodeSocket *sock = nullptr; - bNodeSocket *tsock; /* always do socket_select when extending selection. */ const bool socket_select = (params->sel_op == SEL_OP_XOR) || @@ -551,7 +545,9 @@ static bool node_mouse_select(bContext *C, if (socket_select) { /* NOTE: unlike nodes #SelectPick_Params isn't fully supported. */ const bool extend = (params->sel_op == SEL_OP_XOR); - if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_IN)) { + sock = node_find_indicated_socket(snode, cursor, SOCK_IN); + if (sock) { + node = &sock->owner_node(); found = true; node_was_selected = node->flag & SELECT; @@ -560,41 +556,43 @@ static bool node_mouse_select(bContext *C, node_socket_toggle(node, *sock, true); changed = true; } - else if (node_find_indicated_socket(snode, &node, &sock, cursor, SOCK_OUT)) { - found = true; - node_was_selected = node->flag & SELECT; + if (!changed) { + sock = node_find_indicated_socket(snode, cursor, SOCK_OUT); + if (sock) { + node = &sock->owner_node(); + found = true; + node_was_selected = node->flag & SELECT; - if (sock->flag & SELECT) { - if (extend) { - node_socket_deselect(node, *sock, true); - changed = true; + if (sock->flag & SELECT) { + if (extend) { + node_socket_deselect(node, *sock, true); + changed = true; + } } - } - else { - /* Only allow one selected output per node, for sensible linking. - * Allow selecting outputs from different nodes though, if extend is true. */ - if (node) { - for (tsock = (bNodeSocket *)node->outputs.first; tsock; tsock = tsock->next) { + else { + /* Only allow one selected output per node, for sensible linking. + * Allow selecting outputs from different nodes though, if extend is true. */ + for (bNodeSocket *tsock : node->output_sockets()) { if (tsock == sock) { continue; } node_socket_deselect(node, *tsock, true); changed = true; } - } - if (!extend) { - for (bNode *tnode : node_tree.all_nodes()) { - if (tnode == node) { - continue; - } - for (tsock = (bNodeSocket *)tnode->outputs.first; tsock; tsock = tsock->next) { - node_socket_deselect(tnode, *tsock, true); - changed = true; + if (!extend) { + for (bNode *tnode : node_tree.all_nodes()) { + if (tnode == node) { + continue; + } + for (bNodeSocket *tsock : tnode->output_sockets()) { + node_socket_deselect(tnode, *tsock, true); + changed = true; + } } } + node_socket_select(node, *sock); + changed = true; } - node_socket_select(node, *sock); - changed = true; } } } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index a003947cabe..7053836f7ff 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -254,6 +254,7 @@ typedef enum eNodeSocketInOut { SOCK_IN = 1 << 0, SOCK_OUT = 1 << 1, } eNodeSocketInOut; +ENUM_OPERATORS(eNodeSocketInOut, SOCK_OUT); /** #bNodeSocket.flag, first bit is selection. */ typedef enum eNodeSocketFlag { From 7355d64f2be5cb69b60d29bf0c176f6cdf1858d3 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 3 Jan 2023 14:27:57 -0500 Subject: [PATCH 0378/1522] Node Editor: Paste nodes on mouse position When pasting nodes with the shortcut or the context menu, place the center of the selected nodes at the same position as the mouse cursor. This should save time, and is more intuitive because the new nodes are actually visible. Based on a patch by Juanfran Matheu (@jfmatheu). Differential Revision: https://developer.blender.org/D10787 --- release/scripts/startup/bl_ui/space_node.py | 4 +- .../blender/editors/space_node/clipboard.cc | 95 ++++++++++++++----- 2 files changed, 73 insertions(+), 26 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 103afa783be..010dbf5b099 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -318,7 +318,9 @@ class NODE_MT_node(Menu): layout.separator() layout.operator("node.clipboard_copy", text="Copy") - layout.operator("node.clipboard_paste", text="Paste") + row = layout.row() + row.operator_context = 'EXEC_DEFAULT' + row.operator("node.clipboard_paste", text="Paste") layout.operator("node.duplicate_move") layout.operator("node.duplicate_move_linked") layout.operator("node.delete") diff --git a/source/blender/editors/space_node/clipboard.cc b/source/blender/editors/space_node/clipboard.cc index fa82f80d1a9..aa601cc4322 100644 --- a/source/blender/editors/space_node/clipboard.cc +++ b/source/blender/editors/space_node/clipboard.cc @@ -16,6 +16,9 @@ #include "ED_render.h" #include "ED_screen.h" +#include "RNA_access.h" +#include "RNA_define.h" + #include "DEG_depsgraph_build.h" #include "node_intern.hh" @@ -24,6 +27,11 @@ namespace blender::ed::space_node { struct NodeClipboardItem { bNode *node; + /** + * The offset and size of the node from when it was drawn. Stored here since it doesn't remain + * valid for the nodes in the clipboard. + */ + rctf draw_rect; /* Extra info to validate the node on creation. Otherwise we may reference missing data. */ ID *id; @@ -74,15 +82,24 @@ struct NodeClipboard { return ok; } - void add_node(bNode *node) + void add_node(const bNode &node, + Map &node_map, + Map &socket_map) { + /* No ID refcounting, this node is virtual, + * detached from any actual Blender data currently. */ + bNode *new_node = bke::node_copy_with_mapping( + nullptr, node, LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_MAIN, false, socket_map); + node_map.add_new(&node, new_node); + NodeClipboardItem item; - item.node = node; - item.id = node->id; + item.draw_rect = node.runtime->totr; + item.node = new_node; + item.id = new_node->id; if (item.id) { - item.id_name = node->id->name; - if (ID_IS_LINKED(node->id)) { - item.library_name = node->id->lib->filepath_abs; + item.id_name = new_node->id->name; + if (ID_IS_LINKED(new_node->id)) { + item.library_name = new_node->id->lib->filepath_abs; } } this->nodes.append(std::move(item)); @@ -110,22 +127,13 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator * /*op*/) Map node_map; Map socket_map; - for (bNode *node : tree.all_nodes()) { + for (const bNode *node : tree.all_nodes()) { if (node->flag & SELECT) { - /* No ID reference counting, this node is virtual, detached from any actual Blender data. */ - bNode *new_node = bke::node_copy_with_mapping(nullptr, - *node, - LIB_ID_CREATE_NO_USER_REFCOUNT | - LIB_ID_CREATE_NO_MAIN, - false, - socket_map); - node_map.add_new(node, new_node); + clipboard.add_node(*node, node_map, socket_map); } } for (bNode *new_node : node_map.values()) { - clipboard.add_node(new_node); - /* Parent pointer must be redirected to new node or detached if parent is not copied. */ if (new_node->parent) { if (node_map.contains(new_node->parent)) { @@ -197,14 +205,6 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) node_deselect_all(tree); - /* calculate "barycenter" for placing on mouse cursor */ - float2 center = {0.0f, 0.0f}; - for (const NodeClipboardItem &item : clipboard.nodes) { - center.x += BLI_rctf_cent_x(&item.node->runtime->totr); - center.y += BLI_rctf_cent_y(&item.node->runtime->totr); - } - center /= clipboard.nodes.size(); - Map node_map; Map socket_map; @@ -248,6 +248,27 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) } } + PropertyRNA *offset_prop = RNA_struct_find_property(op->ptr, "offset"); + if (RNA_property_is_set(op->ptr, offset_prop)) { + float2 center(0); + for (NodeClipboardItem &item : clipboard.nodes) { + center.x += BLI_rctf_cent_x(&item.draw_rect); + center.y += BLI_rctf_cent_y(&item.draw_rect); + } + /* DPI factor needs to be removed when computing a View2D offset from drawing rects. */ + center /= clipboard.nodes.size(); + center /= UI_DPI_FAC; + + float2 mouse_location; + RNA_property_float_get_array(op->ptr, offset_prop, mouse_location); + const float2 offset = mouse_location - center; + + for (bNode *new_node : node_map.values()) { + new_node->locx += offset.x; + new_node->locy += offset.y; + } + } + /* Add links between existing nodes. */ for (const bNodeLink &link : clipboard.links) { const bNode *fromnode = link.fromnode; @@ -276,16 +297,40 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int node_clipboard_paste_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + const ARegion *region = CTX_wm_region(C); + float2 cursor; + UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &cursor.x, &cursor.y); + RNA_float_set_array(op->ptr, "offset", cursor); + return node_clipboard_paste_exec(C, op); +} + void NODE_OT_clipboard_paste(wmOperatorType *ot) { ot->name = "Paste from Clipboard"; ot->description = "Pastes nodes from the clipboard to the active node tree"; ot->idname = "NODE_OT_clipboard_paste"; + ot->invoke = node_clipboard_paste_invoke; ot->exec = node_clipboard_paste_exec; ot->poll = ED_operator_node_editable; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + PropertyRNA *prop = RNA_def_float_array( + ot->srna, + "offset", + 2, + nullptr, + -FLT_MAX, + FLT_MAX, + "Location", + "The 2D view location for the center of the new nodes, or unchanged if not set", + -FLT_MAX, + FLT_MAX); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PROP_HIDDEN); } /** \} */ From 858fffc2df8fe124664c75796aa39fab4bc93af1 Mon Sep 17 00:00:00 2001 From: Nikita Sirgienko Date: Tue, 3 Jan 2023 20:45:57 +0100 Subject: [PATCH 0379/1522] Cycles: oneAPI: add support for SYCL host task This functionality is related only to debugging of SYCL implementation via single-threaded CPU execution and is disabled by default. Host device has been deprecated in SYCL 2020 spec and we removed it in 305b92e05f748a0fd9cb62b9829791d717ba2d57. Since this is still very useful for debugging, we're restoring a similar functionality here through SYCL 2020 Host Task. --- CMakeLists.txt | 2 + intern/cycles/device/CMakeLists.txt | 3 + intern/cycles/device/oneapi/device_impl.cpp | 19 ++++- intern/cycles/kernel/CMakeLists.txt | 7 +- .../kernel/device/gpu/parallel_active_index.h | 10 +++ intern/cycles/kernel/device/oneapi/compat.h | 76 +++++++++++++++---- intern/cycles/kernel/device/oneapi/globals.h | 9 +++ intern/cycles/kernel/device/oneapi/kernel.cpp | 6 ++ 8 files changed, 115 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8aa8bffe08f..acfab6ffc60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -501,12 +501,14 @@ endif() if(NOT APPLE) option(WITH_CYCLES_DEVICE_ONEAPI "Enable Cycles oneAPI compute support" OFF) option(WITH_CYCLES_ONEAPI_BINARIES "Enable Ahead-Of-Time compilation for Cycles oneAPI device" OFF) + option(WITH_CYCLES_ONEAPI_HOST_TASK_EXECUTION "Switch target of oneAPI implementation from SYCL devices to Host Task (single thread on CPU). This option is only for debugging purposes." OFF) # https://www.intel.com/content/www/us/en/develop/documentation/oneapi-dpcpp-cpp-compiler-dev-guide-and-reference/top/compilation/ahead-of-time-compilation.html # acm-g10 is the target for the first Intel Arc Alchemist GPUs. set(CYCLES_ONEAPI_SPIR64_GEN_DEVICES "acm-g10" CACHE STRING "oneAPI Intel GPU architectures to build binaries for") set(CYCLES_ONEAPI_SYCL_TARGETS spir64 spir64_gen CACHE STRING "oneAPI targets to build AOT binaries for") + mark_as_advanced(WITH_CYCLES_ONEAPI_HOST_TASK_EXECUTION) mark_as_advanced(CYCLES_ONEAPI_SPIR64_GEN_DEVICES) mark_as_advanced(CYCLES_ONEAPI_SYCL_TARGETS) endif() diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt index c7e95d44d9b..8ec15c6f304 100644 --- a/intern/cycles/device/CMakeLists.txt +++ b/intern/cycles/device/CMakeLists.txt @@ -163,6 +163,9 @@ if(WITH_CYCLES_DEVICE_METAL) endif() if(WITH_CYCLES_DEVICE_ONEAPI) + if(WITH_CYCLES_ONEAPI_HOST_TASK_EXECUTION) + add_definitions(-DWITH_ONEAPI_SYCL_HOST_TASK) + endif() if(WITH_CYCLES_ONEAPI_BINARIES) set(cycles_kernel_oneapi_lib_suffix "_aot") else() diff --git a/intern/cycles/device/oneapi/device_impl.cpp b/intern/cycles/device/oneapi/device_impl.cpp index bf8de8b5a12..edffd9525b1 100644 --- a/intern/cycles/device/oneapi/device_impl.cpp +++ b/intern/cycles/device/oneapi/device_impl.cpp @@ -429,7 +429,12 @@ void OneapiDevice::check_usm(SyclQueue *queue_, const void *usm_ptr, bool allow_ queue->get_device().get_info(); sycl::usm::alloc usm_type = get_pointer_type(usm_ptr, queue->get_context()); (void)usm_type; - assert(usm_type == sycl::usm::alloc::device || +# ifndef WITH_ONEAPI_SYCL_HOST_TASK + const sycl::usm::alloc main_memory_type = sycl::usm::alloc::device; +# else + const sycl::usm::alloc main_memory_type = sycl::usm::alloc::host; +# endif + assert(usm_type == main_memory_type || (usm_type == sycl::usm::alloc::host && (allow_host || device_type == sycl::info::device_type::cpu)) || usm_type == sycl::usm::alloc::unknown); @@ -478,7 +483,11 @@ void *OneapiDevice::usm_alloc_device(SyclQueue *queue_, size_t memory_size) { assert(queue_); sycl::queue *queue = reinterpret_cast(queue_); +# ifndef WITH_ONEAPI_SYCL_HOST_TASK return sycl::malloc_device(memory_size, *queue); +# else + return sycl::malloc_host(memory_size, *queue); +# endif } void OneapiDevice::usm_free(SyclQueue *queue_, void *usm_ptr) @@ -736,7 +745,11 @@ char *OneapiDevice::device_capabilities() const std::vector &oneapi_devices = available_devices(); for (const sycl::device &device : oneapi_devices) { +# ifndef WITH_ONEAPI_SYCL_HOST_TASK const std::string &name = device.get_info(); +# else + const std::string &name = "SYCL Host Task (Debug)"; +# endif capabilities << std::string("\t") << name << "\n"; # define WRITE_ATTR(attribute_name, attribute_variable) \ @@ -813,7 +826,11 @@ void OneapiDevice::iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_p for (sycl::device &device : devices) { const std::string &platform_name = device.get_platform().get_info(); +# ifndef WITH_ONEAPI_SYCL_HOST_TASK std::string name = device.get_info(); +# else + std::string name = "SYCL Host Task (Debug)"; +# endif std::string id = "ONEAPI_" + platform_name + "_" + name; if (device.has(sycl::aspect::ext_intel_pci_address)) { id.append("_" + device.get_info()); diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index a7a6c0a6007..5ba1b683d6b 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -752,6 +752,10 @@ if(WITH_CYCLES_DEVICE_ONEAPI) ${SYCL_CPP_FLAGS} ) + if (WITH_CYCLES_ONEAPI_HOST_TASK_EXECUTION) + list(APPEND sycl_compiler_flags -DWITH_ONEAPI_SYCL_HOST_TASK) + endif() + # Set defaults for spir64 and spir64_gen options if(NOT DEFINED CYCLES_ONEAPI_SYCL_OPTIONS_spir64) set(CYCLES_ONEAPI_SYCL_OPTIONS_spir64 "-options '-ze-opt-large-register-file -ze-opt-regular-grf-kernel integrator_intersect'") @@ -763,7 +767,8 @@ if(WITH_CYCLES_DEVICE_ONEAPI) string(PREPEND CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "--format zebin ") string(PREPEND CYCLES_ONEAPI_SYCL_OPTIONS_spir64_gen "-device ${CYCLES_ONEAPI_SPIR64_GEN_DEVICES} ") - if(WITH_CYCLES_ONEAPI_BINARIES) + # Host execution won't use GPU binaries, no need to compile them. + if(WITH_CYCLES_ONEAPI_BINARIES AND NOT WITH_CYCLES_ONEAPI_HOST_TASK_EXECUTION) # AoT binaries aren't currently reused when calling sycl::build. list(APPEND sycl_compiler_flags -DSYCL_SKIP_KERNELS_PRELOAD) # Iterate over all targest and their options diff --git a/intern/cycles/kernel/device/gpu/parallel_active_index.h b/intern/cycles/kernel/device/gpu/parallel_active_index.h index 1d47211604b..c876c35465c 100644 --- a/intern/cycles/kernel/device/gpu/parallel_active_index.h +++ b/intern/cycles/kernel/device/gpu/parallel_active_index.h @@ -30,6 +30,16 @@ void gpu_parallel_active_index_array_impl(const uint num_states, ccl_global int *ccl_restrict num_indices, IsActiveOp is_active_op) { +# ifdef WITH_ONEAPI_SYCL_HOST_TASK + int write_index = 0; + for (int state_index = 0; state_index < num_states; state_index++) { + if (is_active_op(state_index)) + indices[write_index++] = state_index; + } + *num_indices = write_index; + return; +# endif /* WITH_ONEAPI_SYCL_HOST_TASK */ + const sycl::nd_item<1> &item_id = sycl::ext::oneapi::experimental::this_nd_item<1>(); const uint blocksize = item_id.get_local_range(0); diff --git a/intern/cycles/kernel/device/oneapi/compat.h b/intern/cycles/kernel/device/oneapi/compat.h index b83512180d7..0691c01b3b5 100644 --- a/intern/cycles/kernel/device/oneapi/compat.h +++ b/intern/cycles/kernel/device/oneapi/compat.h @@ -56,7 +56,8 @@ #define ccl_gpu_kernel(block_num_threads, thread_num_registers) #define ccl_gpu_kernel_threads(block_num_threads) -#define ccl_gpu_kernel_signature(name, ...) \ +#ifndef WITH_ONEAPI_SYCL_HOST_TASK +# define ccl_gpu_kernel_signature(name, ...) \ void oneapi_kernel_##name(KernelGlobalsGPU *ccl_restrict kg, \ size_t kernel_global_size, \ size_t kernel_local_size, \ @@ -67,9 +68,37 @@ void oneapi_kernel_##name(KernelGlobalsGPU *ccl_restrict kg, \ sycl::nd_range<1>(kernel_global_size, kernel_local_size), \ [=](sycl::nd_item<1> item) { -#define ccl_gpu_kernel_postfix \ +# define ccl_gpu_kernel_postfix \ }); \ } +#else +/* Additional anonymous lambda is required to handle all "return" statements in the kernel code */ +# define ccl_gpu_kernel_signature(name, ...) \ +void oneapi_kernel_##name(KernelGlobalsGPU *ccl_restrict kg, \ + size_t kernel_global_size, \ + size_t kernel_local_size, \ + sycl::handler &cgh, \ + __VA_ARGS__) { \ + (kg); \ + (kernel_local_size); \ + cgh.host_task( \ + [=]() {\ + for (size_t gid = (size_t)0; gid < kernel_global_size; gid++) { \ + kg->nd_item_local_id_0 = 0; \ + kg->nd_item_local_range_0 = 1; \ + kg->nd_item_group_id_0 = gid; \ + kg->nd_item_group_range_0 = kernel_global_size; \ + kg->nd_item_global_id_0 = gid; \ + kg->nd_item_global_range_0 = kernel_global_size; \ + auto kernel = [=]() { + +# define ccl_gpu_kernel_postfix \ + }; \ + kernel(); \ + } \ + }); \ +} +#endif #define ccl_gpu_kernel_call(x) ((ONEAPIKernelContext*)kg)->x @@ -83,23 +112,40 @@ void oneapi_kernel_##name(KernelGlobalsGPU *ccl_restrict kg, \ } ccl_gpu_kernel_lambda_pass((ONEAPIKernelContext *)kg) /* GPU thread, block, grid size and index */ -#define ccl_gpu_thread_idx_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_local_id(0)) -#define ccl_gpu_block_dim_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_local_range(0)) -#define ccl_gpu_block_idx_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_group(0)) -#define ccl_gpu_grid_dim_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_group_range(0)) -#define ccl_gpu_warp_size (sycl::ext::oneapi::experimental::this_sub_group().get_local_range()[0]) -#define ccl_gpu_thread_mask(thread_warp) uint(0xFFFFFFFF >> (ccl_gpu_warp_size - thread_warp)) -#define ccl_gpu_global_id_x() (sycl::ext::oneapi::experimental::this_nd_item<1>().get_global_id(0)) -#define ccl_gpu_global_size_x() (sycl::ext::oneapi::experimental::this_nd_item<1>().get_global_range(0)) +#ifndef WITH_ONEAPI_SYCL_HOST_TASK +# define ccl_gpu_thread_idx_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_local_id(0)) +# define ccl_gpu_block_dim_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_local_range(0)) +# define ccl_gpu_block_idx_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_group(0)) +# define ccl_gpu_grid_dim_x (sycl::ext::oneapi::experimental::this_nd_item<1>().get_group_range(0)) +# define ccl_gpu_warp_size (sycl::ext::oneapi::experimental::this_sub_group().get_local_range()[0]) +# define ccl_gpu_thread_mask(thread_warp) uint(0xFFFFFFFF >> (ccl_gpu_warp_size - thread_warp)) + +# define ccl_gpu_global_id_x() (sycl::ext::oneapi::experimental::this_nd_item<1>().get_global_id(0)) +# define ccl_gpu_global_size_x() (sycl::ext::oneapi::experimental::this_nd_item<1>().get_global_range(0)) /* GPU warp synchronization */ -#define ccl_gpu_syncthreads() sycl::ext::oneapi::experimental::this_nd_item<1>().barrier() -#define ccl_gpu_local_syncthreads() sycl::ext::oneapi::experimental::this_nd_item<1>().barrier(sycl::access::fence_space::local_space) -#ifdef __SYCL_DEVICE_ONLY__ - #define ccl_gpu_ballot(predicate) (sycl::ext::oneapi::group_ballot(sycl::ext::oneapi::experimental::this_sub_group(), predicate).count()) +# define ccl_gpu_syncthreads() sycl::ext::oneapi::experimental::this_nd_item<1>().barrier() +# define ccl_gpu_local_syncthreads() sycl::ext::oneapi::experimental::this_nd_item<1>().barrier(sycl::access::fence_space::local_space) +# ifdef __SYCL_DEVICE_ONLY__ +# define ccl_gpu_ballot(predicate) (sycl::ext::oneapi::group_ballot(sycl::ext::oneapi::experimental::this_sub_group(), predicate).count()) +# else +# define ccl_gpu_ballot(predicate) (predicate ? 1 : 0) +# endif #else - #define ccl_gpu_ballot(predicate) (predicate ? 1 : 0) +# define ccl_gpu_thread_idx_x (kg->nd_item_local_id_0) +# define ccl_gpu_block_dim_x (kg->nd_item_local_range_0) +# define ccl_gpu_block_idx_x (kg->nd_item_group_id_0) +# define ccl_gpu_grid_dim_x (kg->nd_item_group_range_0) +# define ccl_gpu_warp_size (1) +# define ccl_gpu_thread_mask(thread_warp) uint(0xFFFFFFFF >> (ccl_gpu_warp_size - thread_warp)) + +# define ccl_gpu_global_id_x() (kg->nd_item_global_id_0) +# define ccl_gpu_global_size_x() (kg->nd_item_global_range_0) + +# define ccl_gpu_syncthreads() +# define ccl_gpu_local_syncthreads() +# define ccl_gpu_ballot(predicate) (predicate ? 1 : 0) #endif /* Debug defines */ diff --git a/intern/cycles/kernel/device/oneapi/globals.h b/intern/cycles/kernel/device/oneapi/globals.h index 116620eb725..87932deb2f0 100644 --- a/intern/cycles/kernel/device/oneapi/globals.h +++ b/intern/cycles/kernel/device/oneapi/globals.h @@ -23,6 +23,15 @@ typedef struct KernelGlobalsGPU { #undef KERNEL_DATA_ARRAY IntegratorStateGPU *integrator_state; const KernelData *__data; + +#ifdef WITH_ONEAPI_SYCL_HOST_TASK + size_t nd_item_local_id_0; + size_t nd_item_local_range_0; + size_t nd_item_group_id_0; + size_t nd_item_group_range_0; + size_t nd_item_global_id_0; + size_t nd_item_global_range_0; +#endif } KernelGlobalsGPU; typedef ccl_global KernelGlobalsGPU *ccl_restrict KernelGlobals; diff --git a/intern/cycles/kernel/device/oneapi/kernel.cpp b/intern/cycles/kernel/device/oneapi/kernel.cpp index 525ae288f0c..56c1e7ca47c 100644 --- a/intern/cycles/kernel/device/oneapi/kernel.cpp +++ b/intern/cycles/kernel/device/oneapi/kernel.cpp @@ -230,6 +230,12 @@ bool oneapi_enqueue_kernel(KernelContext *kernel_context, /* NOTE(@nsirgien): As for now non-uniform work-groups don't work on most oneAPI devices, * we extend work size to fit uniformity requirements. */ global_size = groups_count * local_size; + +# ifdef WITH_ONEAPI_SYCL_HOST_TASK + /* Path array implementation is serial in case of SYCL Host Task execution. */ + global_size = 1; + local_size = 1; +# endif } /* Let the compiler throw an error if there are any kernels missing in this implementation. */ From 8b1edff6b50e1a46a2e801064d59b6b9858917db Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 3 Jan 2023 17:28:00 -0500 Subject: [PATCH 0380/1522] UI: Skip expensive view button searching when drawing Finding the active view item button should only happen when it's actually necessary, since looping through all buttons and blocks is an expensive operation. This patch limits the search a bit more, to left clicks (the only case that is actually handled). This improves drawing performance in the node editor slightly, where this was a bottleneck. Differential Revision: https://developer.blender.org/D16882 --- .../editors/interface/interface_handlers.cc | 15 ++++++++------- source/blender/editors/space_node/node_draw.cc | 1 + 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index b1424b42065..1055f18d4a0 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -9684,11 +9684,15 @@ static int ui_handle_view_items_hover(const wmEvent *event, const ARegion *regio static int ui_handle_view_item_event(bContext *C, const wmEvent *event, - ARegion *region, - uiBut *view_but) + uiBut *active_but, + ARegion *region) { - BLI_assert(view_but->type == UI_BTYPE_VIEW_ITEM); if (event->type == LEFTMOUSE) { + /* Only bother finding the active view item button if the active button isn't already a view + * item. */ + uiBut *view_but = active_but->type == UI_BTYPE_VIEW_ITEM ? + active_but : + ui_view_item_find_mouse_over(region, event->xy); /* Will free active button if there already is one. */ ui_handle_button_activate(C, region, view_but, BUTTON_ACTIVATE_OVER); return ui_do_button(C, view_but->block, view_but, event); @@ -11302,10 +11306,7 @@ static int ui_region_handler(bContext *C, const wmEvent *event, void * /*userdat * nested in the item (it's an overlapping layout). */ ui_handle_view_items_hover(event, region); if (retval == WM_UI_HANDLER_CONTINUE) { - uiBut *view_item = ui_view_item_find_mouse_over(region, event->xy); - if (view_item) { - retval = ui_handle_view_item_event(C, event, region, view_item); - } + retval = ui_handle_view_item_event(C, event, but, region); } /* delayed apply callbacks */ diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 7c12a1114ec..fcb1d854fa0 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -3199,6 +3199,7 @@ static void draw_background_color(const SpaceNode &snode) void node_draw_space(const bContext &C, ARegion ®ion) { + SCOPED_TIMER_AVERAGED(__func__); wmWindow *win = CTX_wm_window(&C); SpaceNode &snode = *CTX_wm_space_node(&C); View2D &v2d = region.v2d; From 1d636f5e057e14806fcfb2bedc584544a7fb44a8 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 3 Jan 2023 20:02:01 -0500 Subject: [PATCH 0381/1522] Cleanup: Comment formatting in node editor Also remove an accidentally committed timing print. --- source/blender/editors/include/ED_node.h | 9 -- source/blender/editors/include/ED_node.hh | 8 ++ .../editors/interface/interface_widgets.cc | 5 +- source/blender/editors/space_node/node_add.cc | 12 +- .../blender/editors/space_node/node_draw.cc | 77 ++++------- .../blender/editors/space_node/node_edit.cc | 128 ++++++++---------- .../editors/space_node/node_relationships.cc | 125 ++++++++--------- .../blender/editors/space_node/node_select.cc | 36 +++-- 8 files changed, 176 insertions(+), 224 deletions(-) diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index dc35ac74524..f996a9f4591 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -78,15 +78,6 @@ void ED_node_draw_snap( /* node_draw.cc */ -/** - * Draw a single node socket at default size. - * \note this is only called from external code, internally #node_socket_draw_nested() is used for - * optimized drawing of multiple/all sockets of a node. - */ -void ED_node_socket_draw(struct bNodeSocket *sock, - const struct rcti *rect, - const float color[4], - float scale); void ED_node_tree_update(const struct bContext *C); void ED_node_tag_update_id(struct ID *id); diff --git a/source/blender/editors/include/ED_node.hh b/source/blender/editors/include/ED_node.hh index 7b35bbf0b6e..ff88eedb5a4 100644 --- a/source/blender/editors/include/ED_node.hh +++ b/source/blender/editors/include/ED_node.hh @@ -9,6 +9,7 @@ struct SpaceNode; struct ARegion; struct Main; struct bNodeTree; +struct rcti; namespace blender::ed::space_node { @@ -22,4 +23,11 @@ void node_insert_on_link_flags_set(SpaceNode &snode, const ARegion ®ion); void node_insert_on_link_flags(Main &bmain, SpaceNode &snode); void node_insert_on_link_flags_clear(bNodeTree &node_tree); +/** + * Draw a single node socket at default size. + * \note this is only called from external code, internally #node_socket_draw_nested() is used for + * optimized drawing of multiple/all sockets of a node. + */ +void node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[4], float scale); + } // namespace blender::ed::space_node diff --git a/source/blender/editors/interface/interface_widgets.cc b/source/blender/editors/interface/interface_widgets.cc index ea9bdc8a0d9..3c0b5064d1f 100644 --- a/source/blender/editors/interface/interface_widgets.cc +++ b/source/blender/editors/interface/interface_widgets.cc @@ -26,7 +26,7 @@ #include "BLF_api.h" -#include "ED_node.h" +#include "ED_node.hh" #include "UI_interface.h" #include "UI_interface_icons.h" @@ -2213,7 +2213,8 @@ static void widget_draw_node_link_socket(const uiWidgetColors *wcol, UI_widgetbase_draw_cache_flush(); GPU_blend(GPU_BLEND_NONE); - ED_node_socket_draw(static_cast(but->custom_data), rect, col, scale); + blender::ed::space_node::node_socket_draw( + static_cast(but->custom_data), rect, col, scale); } else { widget_draw_icon(but, ICON_LAYER_USED, alpha, rect, wcol->text); diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc index ce1fe118281..097056b5464 100644 --- a/source/blender/editors/space_node/node_add.cc +++ b/source/blender/editors/space_node/node_add.cc @@ -699,8 +699,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op) } /* When adding new image file via drag-drop we need to load imbuf in order - * to get proper image source. - */ + * to get proper image source. */ if (RNA_struct_property_is_set(op->ptr, "filepath")) { BKE_image_signal(bmain, ima, nullptr, IMA_SIGNAL_RELOAD); WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima); @@ -717,7 +716,7 @@ static int node_add_file_invoke(bContext *C, wmOperator *op, const wmEvent *even ARegion *region = CTX_wm_region(C); SpaceNode *snode = CTX_wm_space_node(C); - /* convert mouse coordinates to v2d space */ + /* Convert mouse coordinates to `v2d` space. */ UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], @@ -860,13 +859,12 @@ static int new_node_tree_exec(bContext *C, wmOperator *op) ntree = ntreeAddTree(bmain, treename, idname); - /* hook into UI */ + /* Hook into UI. */ UI_context_active_but_prop_get_templateID(C, &ptr, &prop); if (prop) { - /* RNA_property_pointer_set increases the user count, - * fixed here as the editor is the initial user. - */ + /* #RNA_property_pointer_set increases the user count, fixed here as the editor is the initial + * user. */ id_us_min(&ntree->id); RNA_id_pointer_create(&ntree->id, &idptr); diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index fcb1d854fa0..12a1fcdebd0 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -59,6 +59,7 @@ #include "ED_gpencil.h" #include "ED_node.h" +#include "ED_node.hh" #include "ED_screen.h" #include "ED_space_api.h" #include "ED_viewer_path.hh" @@ -84,9 +85,6 @@ namespace geo_log = blender::nodes::geo_eval_log; -using blender::GPointer; -using blender::Vector; - /** * This is passed to many functions which draw the node editor. */ @@ -278,7 +276,7 @@ static Array node_uiblocks_init(const bContext &C, const Spanname); blocks[i] = UI_block_begin(&C, CTX_wm_region(&C), block_name.c_str(), UI_EMBOSS); - /* this cancels events for background nodes */ + /* This cancels events for background nodes. */ UI_block_flag_enable(blocks[i], UI_BLOCK_CLIP_EVENTS); } @@ -1240,12 +1238,8 @@ static void node_socket_draw_nested(const bContext &C, UI_block_emboss_set(&block, old_emboss); } -} // namespace blender::ed::space_node - -void ED_node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[4], float scale) +void node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[4], float scale) { - using namespace blender::ed::space_node; - const float size = NODE_SOCKSIZE_DRAW_MULIPLIER * NODE_SOCKSIZE * scale; rcti draw_rect = *rect; float outline_color[4] = {0}; @@ -1292,10 +1286,6 @@ void ED_node_socket_draw(bNodeSocket *sock, const rcti *rect, const float color[ GPU_blend(state); } -namespace blender::ed::space_node { - -/* ************** Socket callbacks *********** */ - static void node_draw_preview_background(rctf *rect) { GPUVertFormat *format = immVertexFormat(); @@ -1526,7 +1516,8 @@ static void node_draw_sockets(const View2D &v2d, scale, selected); if (--selected_input_len == 0) { - break; /* Stop as soon as last one is drawn. */ + /* Stop as soon as last one is drawn. */ + break; } } } @@ -1552,7 +1543,8 @@ static void node_draw_sockets(const View2D &v2d, scale, selected); if (--selected_output_len == 0) { - break; /* Stop as soon as last one is drawn. */ + /* Stop as soon as last one is drawn. */ + break; } } } @@ -2163,11 +2155,6 @@ static void node_draw_basis(const bContext &C, node_toggle_button_cb, POINTER_FROM_INT(node.identifier), (void *)"NODE_OT_preview_toggle"); - /* XXX this does not work when node is activated and the operator called right afterwards, - * since active ID is not updated yet (needs to process the notifier). - * This can only work as visual indicator! */ - // if (!(node.flag & (NODE_ACTIVE_ID|NODE_DO_OUTPUT))) - // UI_but_flag_enable(but, UI_BUT_DISABLED); UI_block_emboss_set(&block, UI_EMBOSS); } /* Group edit. */ @@ -2680,28 +2667,28 @@ static void frame_node_prepare_for_draw(bNode &node, Span nodes) const float margin = 1.5f * U.widget_unit; NodeFrame *data = (NodeFrame *)node.storage; - /* init rect from current frame size */ + /* Initialize rect from current frame size. */ rctf rect; node_to_updated_rect(node, rect); - /* frame can be resized manually only if shrinking is disabled or no children are attached */ + /* Frame can be resized manually only if shrinking is disabled or no children are attached. */ data->flag |= NODE_FRAME_RESIZEABLE; - /* for shrinking bbox, initialize the rect from first child node */ + /* For shrinking bounding box, initialize the rect from first child node. */ bool bbinit = (data->flag & NODE_FRAME_SHRINK); - /* fit bounding box to all children */ + /* Fit bounding box to all children. */ for (const bNode *tnode : nodes) { if (tnode->parent != &node) { continue; } - /* add margin to node rect */ + /* Add margin to node rect. */ rctf noderect = tnode->runtime->totr; noderect.xmin -= margin; noderect.xmax += margin; noderect.ymin -= margin; noderect.ymax += margin; - /* first child initializes frame */ + /* First child initializes frame. */ if (bbinit) { bbinit = false; rect = noderect; @@ -2712,7 +2699,7 @@ static void frame_node_prepare_for_draw(bNode &node, Span nodes) } } - /* now adjust the frame size from view-space bounding box */ + /* Now adjust the frame size from view-space bounding box. */ const float2 offset = node_from_view(node, {rect.xmin, rect.ymax}); node.offsetx = offset.x; node.offsety = offset.y; @@ -2725,10 +2712,9 @@ static void frame_node_prepare_for_draw(bNode &node, Span nodes) static void reroute_node_prepare_for_draw(bNode &node) { - /* get "global" coords */ const float2 loc = node_to_view(node, float2(0)); - /* reroute node has exactly one input and one output, both in the same place */ + /* Reroute node has exactly one input and one output, both in the same place. */ bNodeSocket *socket = (bNodeSocket *)node.outputs.first; socket->runtime->locx = loc.x; socket->runtime->locy = loc.y; @@ -2802,10 +2788,10 @@ static void frame_node_draw_label(TreeDrawContext &tree_draw_ctx, BLF_enable(fontid, BLF_ASPECT); BLF_aspect(fontid, aspect, aspect, 1.0f); - /* clamp otherwise it can suck up a LOT of memory */ + /* Clamp. Otherwise it can suck up a LOT of memory. */ BLF_size(fontid, MIN2(24.0f, font_size) * U.dpi_fac); - /* title color */ + /* Title color. */ int color_id = node_get_colorid(tree_draw_ctx, node); uchar color[3]; UI_GetThemeColorBlendShade3ubv(TH_TEXT, color_id, 0.4f, 10, color); @@ -2818,7 +2804,7 @@ static void frame_node_draw_label(TreeDrawContext &tree_draw_ctx, /* 'x' doesn't need aspect correction */ const rctf &rct = node.runtime->totr; - /* XXX a bit hacky, should use separate align values for x and y */ + /* XXX a bit hacky, should use separate align values for x and y. */ float x = BLI_rctf_cent_x(&rct) - (0.5f * width); float y = rct.ymax - label_height; @@ -2829,24 +2815,23 @@ static void frame_node_draw_label(TreeDrawContext &tree_draw_ctx, BLF_draw(fontid, label, sizeof(label)); } - /* draw text body */ + /* Draw text body. */ if (node.id) { const Text *text = (const Text *)node.id; const int line_height_max = BLF_height_max(fontid); const float line_spacing = (line_height_max * aspect); const float line_width = (BLI_rctf_size_x(&rct) - margin) / aspect; - /* 'x' doesn't need aspect correction */ + /* 'x' doesn't need aspect correction. */ x = rct.xmin + margin; y = rct.ymax - label_height - (has_label ? line_spacing : 0); - /* early exit */ int y_min = y + ((margin * 2) - (y - rct.ymin)); BLF_enable(fontid, BLF_CLIPPING | BLF_WORD_WRAP); BLF_clipping(fontid, rct.xmin, - /* round to avoid clipping half-way through a line */ + /* Round to avoid clipping half-way through a line. */ y - (floorf(((y - rct.ymin) - (margin * 2)) / line_spacing) * line_spacing), rct.xmin + line_width, rct.ymax); @@ -2882,7 +2867,7 @@ static void frame_node_draw(const bContext &C, bNode &node, uiBlock &block) { - /* skip if out of view */ + /* Skip if out of view. */ if (BLI_rctf_isect(&node.runtime->totr, ®ion.v2d.cur, nullptr) == false) { UI_block_end(&C, &block); return; @@ -2892,10 +2877,8 @@ static void frame_node_draw(const bContext &C, UI_GetThemeColor4fv(TH_NODE_FRAME, color); const float alpha = color[3]; - /* shadow */ node_draw_shadow(snode, node, BASIS_RAD, alpha); - /* body */ if (node.flag & NODE_CUSTOM_COLOR) { rgba_float_args_set(color, node.color[0], node.color[1], node.color[2], alpha); } @@ -2907,7 +2890,7 @@ static void frame_node_draw(const bContext &C, UI_draw_roundbox_corner_set(UI_CNR_ALL); UI_draw_roundbox_4fv(&rct, true, BASIS_RAD, color); - /* outline active and selected emphasis */ + /* Outline active and selected emphasis. */ if (node.flag & SELECT) { if (node.flag & NODE_ACTIVE) { UI_GetThemeColorShadeAlpha4fv(TH_ACTIVE, 0, -40, color); @@ -2919,7 +2902,7 @@ static void frame_node_draw(const bContext &C, UI_draw_roundbox_aa(&rct, false, BASIS_RAD, color); } - /* label and text */ + /* Label and text. */ frame_node_draw_label(tree_draw_ctx, ntree, node, snode); node_draw_extra_info_panel(tree_draw_ctx, snode, node, block); @@ -2931,7 +2914,7 @@ static void frame_node_draw(const bContext &C, static void reroute_node_draw( const bContext &C, ARegion ®ion, bNodeTree &ntree, bNode &node, uiBlock &block) { - /* skip if out of view */ + /* Skip if out of view. */ const rctf &rct = node.runtime->totr; if (rct.xmax < region.v2d.cur.xmin || rct.xmin > region.v2d.cur.xmax || rct.ymax < region.v2d.cur.ymin || node.runtime->totr.ymin > region.v2d.cur.ymax) { @@ -2940,7 +2923,7 @@ static void reroute_node_draw( } if (node.label[0] != '\0') { - /* draw title (node label) */ + /* Draw title (node label). */ char showname[128]; /* 128 used below */ BLI_strncpy(showname, node.label, sizeof(showname)); const short width = 512; @@ -2965,9 +2948,8 @@ static void reroute_node_draw( UI_but_drawflag_disable(label_but, UI_BUT_TEXT_LEFT); } - /* only draw input socket. as they all are placed on the same position. - * highlight also if node itself is selected, since we don't display the node body separately! - */ + /* Only draw input socket as they all are placed on the same position highlight + * if node itself is selected, since we don't display the node body separately. */ node_draw_sockets(region.v2d, C, ntree, node, block, false, node.flag & SELECT); UI_block_end(&C, &block); @@ -3098,9 +3080,7 @@ static void snode_setup_v2d(SpaceNode &snode, ARegion ®ion, const float2 &cen UI_view2d_center_set(&v2d, center[0], center[1]); UI_view2d_view_ortho(&v2d); - /* Aspect + font, set each time. */ snode.runtime->aspect = BLI_rctf_size_x(&v2d.cur) / float(region.winx); - // XXX snode->curfont = uiSetCurFont_ext(snode->aspect); } /* Similar to is_compositor_enabled() in draw_manager.c but checks all 3D views. */ @@ -3199,7 +3179,6 @@ static void draw_background_color(const SpaceNode &snode) void node_draw_space(const bContext &C, ARegion ®ion) { - SCOPED_TIMER_AVERAGED(__func__); wmWindow *win = CTX_wm_window(&C); SpaceNode &snode = *CTX_wm_space_node(&C); View2D &v2d = region.v2d; diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 940216db9a3..cb22e48350f 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -168,12 +168,12 @@ static int compo_get_recalc_flags(const bContext *C) return recalc_flags; } -/* called by compo, only to check job 'stop' value */ +/* Called by compositor, only to check job 'stop' value. */ static bool compo_breakjob(void *cjv) { CompoJob *cj = (CompoJob *)cjv; - /* without G.is_break 'ESC' won't quit - which annoys users */ + /* Without G.is_break 'ESC' won't quit - which annoys users. */ return (*(cj->stop) #ifdef USE_ESC_COMPO || G.is_break @@ -181,7 +181,7 @@ static bool compo_breakjob(void *cjv) ); } -/* called by compo, wmJob sends notifier */ +/* Called by compositor, #wmJob sends notifier. */ static void compo_statsdrawjob(void *cjv, const char * /*str*/) { CompoJob *cj = (CompoJob *)cjv; @@ -189,7 +189,7 @@ static void compo_statsdrawjob(void *cjv, const char * /*str*/) *(cj->do_update) = true; } -/* called by compo, wmJob sends notifier */ +/* Called by compositor, wmJob sends notifier. */ static void compo_redrawjob(void *cjv) { CompoJob *cj = (CompoJob *)cjv; @@ -210,8 +210,8 @@ static void compo_freejob(void *cjv) MEM_freeN(cj); } -/* only now we copy the nodetree, so adding many jobs while - * sliding buttons doesn't frustrate */ +/* Only now we copy the nodetree, so adding many jobs while + * sliding buttons doesn't frustrate. */ static void compo_initjob(void *cjv) { CompoJob *cj = (CompoJob *)cjv; @@ -236,7 +236,7 @@ static void compo_initjob(void *cjv) } } -/* called before redraw notifiers, it moves finished previews over */ +/* Called before redraw notifiers, it moves finished previews over. */ static void compo_updatejob(void * /*cjv*/) { WM_main_add_notifier(NC_SCENE | ND_COMPO_RESULT, nullptr); @@ -249,7 +249,7 @@ static void compo_progressjob(void *cjv, float progress) *(cj->progress) = progress; } -/* only this runs inside thread */ +/* Only this runs inside thread. */ static void compo_startjob(void *cjv, /* Cannot be const, this function implements wm_jobs_start_callback. * NOLINTNEXTLINE: readability-non-const-parameter. */ @@ -278,8 +278,6 @@ static void compo_startjob(void *cjv, ntree->runtime->update_draw = compo_redrawjob; ntree->runtime->udh = cj; - // XXX BIF_store_spare(); - /* 1 is do_previews */ BKE_callback_exec_id(cj->bmain, &scene->id, BKE_CB_EVT_COMPOSITE_PRE); if ((cj->scene->r.scemode & R_MULTIVIEW) == 0) { @@ -331,7 +329,7 @@ void ED_node_composite_job(const bContext *C, bNodeTree *nodetree, Scene *scene_ Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - /* to fix bug: T32272. */ + /* See T32272. */ if (G.is_rendering) { return; } @@ -351,14 +349,14 @@ void ED_node_composite_job(const bContext *C, bNodeTree *nodetree, Scene *scene_ WM_JOB_TYPE_COMPOSITE); CompoJob *cj = MEM_cnew("compo job"); - /* customdata for preview thread */ + /* Custom data for preview thread. */ cj->bmain = bmain; cj->scene = scene; cj->view_layer = view_layer; cj->ntree = nodetree; cj->recalc_flags = compo_get_recalc_flags(C); - /* setup job */ + /* Set up job. */ WM_jobs_customdata_set(wm_job, cj, compo_freejob); WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_COMPO_RESULT, NC_SCENE | ND_COMPO_RESULT); WM_jobs_callbacks_ex(wm_job, @@ -582,7 +580,7 @@ void ED_node_composit_default(const bContext *C, Scene *sce) in->locy = 400.0f; nodeSetActive(sce->nodetree, in); - /* links from color to color */ + /* Links from color to color. */ bNodeSocket *fromsock = (bNodeSocket *)in->outputs.first; bNodeSocket *tosock = (bNodeSocket *)out->inputs.first; nodeAddLink(sce->nodetree, in, fromsock, out, tosock); @@ -592,7 +590,6 @@ void ED_node_composit_default(const bContext *C, Scene *sce) void ED_node_texture_default(const bContext *C, Tex *tex) { - /* but lets check it anyway */ if (tex->nodetree) { if (G.debug & G_DEBUG) { printf("error in texture initialize\n"); @@ -631,16 +628,16 @@ void snode_set_context(const bContext &C) bNodeTree *ntree = snode->nodetree; ID *id = snode->id, *from = snode->from; - /* check the tree type */ + /* Check the tree type. */ if (!treetype || (treetype->poll && !treetype->poll(&C, treetype))) { - /* invalid tree type, skip + /* Invalid tree type, skip. * NOTE: not resetting the node path here, invalid #bNodeTreeType * may still be registered at a later point. */ return; } if (snode->nodetree && !STREQ(snode->nodetree->idname, snode->tree_idname)) { - /* current tree does not match selected type, clear tree path */ + /* Current tree does not match selected type, clear tree path. */ ntree = nullptr; id = nullptr; from = nullptr; @@ -648,7 +645,7 @@ void snode_set_context(const bContext &C) if (!(snode->flag & SNODE_PIN) || ntree == nullptr) { if (treetype->get_from_context) { - /* reset and update from context */ + /* Reset and update from context. */ ntree = nullptr; id = nullptr; from = nullptr; @@ -681,7 +678,7 @@ void ED_node_set_active( const bool was_output = (node->flag & NODE_DO_OUTPUT) != 0; bool do_update = false; - /* generic node group output: set node as active output */ + /* Generic node group output: set node as active output. */ if (node->type == NODE_GROUP_OUTPUT) { for (bNode *node_iter : ntree->all_nodes()) { if (node_iter->type == NODE_GROUP_OUTPUT) { @@ -696,7 +693,7 @@ void ED_node_set_active( } } - /* tree specific activate calls */ + /* Tree specific activate calls. */ if (ntree->type == NTREE_SHADER) { if (ELEM(node->type, SH_NODE_OUTPUT_MATERIAL, @@ -760,7 +757,7 @@ void ED_node_set_active( WM_main_add_notifier(NC_MATERIAL | ND_NODES, node->id); } else if (ntree->type == NTREE_COMPOSIT) { - /* make active viewer, currently only 1 supported... */ + /* Make active viewer, currently only one is supported. */ if (ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { for (bNode *node_iter : ntree->all_nodes()) { if (ELEM(node_iter->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { @@ -1022,7 +1019,7 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event) } } - /* height works the other way round ... */ + /* Height works the other way round. */ { float heightmin = UI_DPI_FAC * node->typeinfo->minheight; float heightmax = UI_DPI_FAC * node->typeinfo->maxheight; @@ -1039,9 +1036,8 @@ static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event) } } - /* XXX make callback? */ if (node->type == NODE_FRAME) { - /* keep the offset symmetric around center point */ + /* Keep the offset symmetric around center point. */ if (nsw->directions & NODE_RESIZE_LEFT) { node->locx = nsw->oldlocx + 0.5f * dx; node->offsetx = nsw->oldoffsetx + 0.5f * dx; @@ -1101,7 +1097,7 @@ static int node_resize_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } - /* convert mouse coordinates to v2d space */ + /* Convert mouse coordinates to `v2d` space. */ float2 cursor; int2 mval; WM_event_drag_start_mval(event, region, mval); @@ -1169,7 +1165,7 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set) } } else { - /* hide unused sockets */ + /* Hide unused sockets. */ LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { if (sock->link == nullptr) { sock->flag |= SOCK_HIDDEN; @@ -1183,7 +1179,6 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set) } } -/* checks snode->mouse position, and returns found node/socket */ static bool cursor_isect_multi_input_socket(const float2 &cursor, const bNodeSocket &socket) { const float node_socket_height = node_socket_calculate_height(socket); @@ -1220,7 +1215,7 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode, BLI_rctf_init_pt_radius(&rect, cursor, size_sock_padded); if (!(node.flag & NODE_HIDDEN)) { - /* extra padding inside and out - allow dragging on the text areas too */ + /* Extra padding inside and out - allow dragging on the text areas too. */ if (in_out == SOCK_IN) { rect.xmax += NODE_SOCKSIZE; rect.xmin -= NODE_SOCKSIZE * 4; @@ -1312,7 +1307,7 @@ static void node_duplicate_reparent_recursive(bNodeTree *ntree, node->flag |= NODE_TEST; - /* find first selected parent */ + /* Find first selected parent. */ for (parent = node->parent; parent; parent = parent->parent) { if (parent->flag & SELECT) { if (!(parent->flag & NODE_TEST)) { @@ -1321,7 +1316,7 @@ static void node_duplicate_reparent_recursive(bNodeTree *ntree, break; } } - /* reparent node copy to parent copy */ + /* Reparent node copy to parent copy. */ if (parent) { nodeDetachNode(ntree, node_map.lookup(node)); nodeAttachNode(ntree, node_map.lookup(node), node_map.lookup(parent)); @@ -1368,9 +1363,8 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) /* Copy links between selected nodes. */ bNodeLink *lastlink = (bNodeLink *)ntree->links.last; LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { - /* This creates new links between copied nodes. - * If keep_inputs is set, also copies input links from unselected (when fromnode==nullptr)! - */ + /* This creates new links between copied nodes. If keep_inputs is set, also copies input links + * from unselected (when fromnode is null)! */ if (link->tonode && (link->tonode->flag & NODE_SELECT) && (keep_inputs || (link->fromnode && (link->fromnode->flag & NODE_SELECT)))) { bNodeLink *newlink = MEM_cnew("bNodeLink"); @@ -1387,7 +1381,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) newlink->fromsock = socket_map.lookup(link->fromsock); } else { - /* input node not copied, this keeps the original input linked */ + /* Input node not copied, this keeps the original input linked. */ newlink->fromnode = link->fromnode; newlink->fromsock = link->fromsock; } @@ -1395,24 +1389,24 @@ static int node_duplicate_exec(bContext *C, wmOperator *op) BLI_addtail(&ntree->links, newlink); } - /* make sure we don't copy new links again! */ + /* Make sure we don't copy new links again. */ if (link == lastlink) { break; } } - /* clear flags for recursive depth-first iteration */ + /* Clear flags for recursive depth-first iteration. */ for (bNode *node : ntree->all_nodes()) { node->flag &= ~NODE_TEST; } - /* reparent copied nodes */ + /* Reparent copied nodes. */ for (bNode *node : node_map.keys()) { if (!(node->flag & NODE_TEST)) { node_duplicate_reparent_recursive(ntree, node_map, node); } } - /* deselect old nodes, select the copies instead */ + /* Deselect old nodes, select the copies instead. */ for (const auto item : node_map.items()) { bNode *src_node = item.key; bNode *dst_node = item.value; @@ -1453,9 +1447,7 @@ void NODE_OT_duplicate(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } -/* XXX: some code needing updating to operators. */ - -/* goes over all scenes, reads render layers */ +/* Goes over all scenes, reads render layers. */ static int node_read_viewlayers_exec(bContext *C, wmOperator * /*op*/) { Main *bmain = CTX_data_main(C); @@ -1492,7 +1484,6 @@ static int node_read_viewlayers_exec(bContext *C, wmOperator * /*op*/) void NODE_OT_read_viewlayers(wmOperatorType *ot) { - ot->name = "Read View Layers"; ot->idname = "NODE_OT_read_viewlayers"; ot->description = "Read all render layers of all used scenes"; @@ -1500,9 +1491,6 @@ void NODE_OT_read_viewlayers(wmOperatorType *ot) ot->exec = node_read_viewlayers_exec; ot->poll = composite_node_active; - - /* flags */ - ot->flag = 0; } int node_render_changed_exec(bContext *C, wmOperator * /*op*/) @@ -1563,15 +1551,14 @@ void NODE_OT_render_changed(wmOperatorType *ot) /** \name Node Hide Operator * \{ */ +/** + * Toggles the flag on all selected nodes. If the flag is set on all nodes it is unset. + * If the flag is not set on all nodes, it is set. + */ static void node_flag_toggle_exec(SpaceNode *snode, int toggle_flag) { int tot_eq = 0, tot_neq = 0; - /* Toggles the flag on all selected nodes. - * If the flag is set on all nodes it is unset. - * If the flag is not set on all nodes, it is set. - */ - for (bNode *node : snode->edittree->all_nodes()) { if (node->flag & SELECT) { @@ -1616,7 +1603,7 @@ static int node_hide_toggle_exec(bContext *C, wmOperator * /*op*/) { SpaceNode *snode = CTX_wm_space_node(C); - /* sanity checking (poll callback checks this already) */ + /* Sanity checking (poll callback checks this already). */ if ((snode == nullptr) || (snode->edittree == nullptr)) { return OPERATOR_CANCELLED; } @@ -1647,7 +1634,7 @@ static int node_preview_toggle_exec(bContext *C, wmOperator * /*op*/) { SpaceNode *snode = CTX_wm_space_node(C); - /* sanity checking (poll callback checks this already) */ + /* Sanity checking (poll callback checks this already). */ if ((snode == nullptr) || (snode->edittree == nullptr)) { return OPERATOR_CANCELLED; } @@ -1720,7 +1707,7 @@ static int node_options_toggle_exec(bContext *C, wmOperator * /*op*/) { SpaceNode *snode = CTX_wm_space_node(C); - /* sanity checking (poll callback checks this already) */ + /* Sanity checking (poll callback checks this already). */ if ((snode == nullptr) || (snode->edittree == nullptr)) { return OPERATOR_CANCELLED; } @@ -1751,7 +1738,7 @@ static int node_socket_toggle_exec(bContext *C, wmOperator * /*op*/) { SpaceNode *snode = CTX_wm_space_node(C); - /* sanity checking (poll callback checks this already) */ + /* Sanity checking (poll callback checks this already). */ if ((snode == nullptr) || (snode->edittree == nullptr)) { return OPERATOR_CANCELLED; } @@ -1899,7 +1886,7 @@ static int node_switch_view_exec(bContext *C, wmOperator * /*op*/) LISTBASE_FOREACH_MUTABLE (bNode *, node, &snode->edittree->nodes) { if (node->flag & SELECT) { - /* call the update function from the Switch View node */ + /* Call the update function from the Switch View node. */ node->runtime->update = NODE_UPDATE_OPERATOR; } } @@ -2224,7 +2211,7 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op) bNodeSocket *sock; if (active_sock) { - /* insert a copy of the active socket right after it */ + /* Insert a copy of the active socket right after it. */ sock = ntreeInsertSocketInterface( ntree, in_out, active_sock->idname, active_sock->next, active_sock->name); /* XXX this only works for actual sockets, not interface templates! */ @@ -2239,7 +2226,7 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op) LISTBASE_FOREACH (bNodeSocket *, socket_iter, sockets) { socket_iter->flag &= ~SELECT; } - /* make the new socket active */ + /* Make the new socket selected. */ sock->flag |= SELECT; ED_node_tree_propagate_change(C, CTX_data_main(C), snode->edittree); @@ -2284,11 +2271,11 @@ static int ntree_socket_remove_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - /* preferably next socket becomes active, otherwise try previous socket */ + /* Preferably next socket becomes active, otherwise try previous socket. */ bNodeSocket *active_sock = (iosock->next ? iosock->next : iosock->prev); ntreeRemoveSocketInterface(ntree, iosock); - /* set active socket */ + /* Set active socket. */ if (active_sock) { active_sock->flag |= SELECT; } @@ -2510,12 +2497,12 @@ static bool node_shader_script_update_poll(bContext *C) const RenderEngineType *type = RE_engines_find(scene->r.engine); SpaceNode *snode = CTX_wm_space_node(C); - /* test if we have a render engine that supports shaders scripts */ + /* Test if we have a render engine that supports shaders scripts. */ if (!(type && type->update_script_node)) { return false; } - /* see if we have a shader script node in context */ + /* See if we have a shader script node in context. */ bNode *node = (bNode *)CTX_data_pointer_get_type(C, "node", &RNA_ShaderNodeScript).data; if (!node && snode && snode->edittree) { @@ -2530,13 +2517,13 @@ static bool node_shader_script_update_poll(bContext *C) } } - /* see if we have a text datablock in context */ + /* See if we have a text datablock in context. */ Text *text = (Text *)CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data; if (text) { return true; } - /* we don't check if text datablock is actually in use, too slow for poll */ + /* We don't check if text datablock is actually in use, too slow for poll. */ return false; } @@ -2552,7 +2539,7 @@ static bool node_shader_script_update_text_recursive(RenderEngine *engine, done_trees.add_new(ntree); - /* update each script that is using this text datablock */ + /* Update each script that is using this text datablock. */ for (bNode *node : ntree->all_nodes()) { if (node->type == NODE_GROUP) { bNodeTree *ngroup = (bNodeTree *)node->id; @@ -2582,7 +2569,6 @@ static int node_shader_script_update_exec(bContext *C, wmOperator *op) RenderEngine *engine = RE_engine_create(type); engine->reports = op->reports; - /* get node */ bNodeTree *ntree_base = nullptr; bNode *node = nullptr; if (nodeptr.data) { @@ -2595,13 +2581,13 @@ static int node_shader_script_update_exec(bContext *C, wmOperator *op) } if (node) { - /* update single node */ + /* Update single node. */ type->update_script_node(engine, ntree_base, node); found = true; } else { - /* update all nodes using text datablock */ + /* Update all nodes using text datablock. */ Text *text = (Text *)CTX_data_pointer_get_type(C, "edit_text", &RNA_Text).data; if (text) { @@ -2683,17 +2669,17 @@ static int viewer_border_exec(bContext *C, wmOperator *op) rcti rect; rctf rectf; - /* get border from operator */ + /* Get border from operator. */ WM_operator_properties_border_to_rcti(op, &rect); - /* convert border to unified space within backdrop image */ + /* Convert border to unified space within backdrop image. */ viewer_border_corner_to_backdrop( snode, region, rect.xmin, rect.ymin, ibuf->x, ibuf->y, &rectf.xmin, &rectf.ymin); viewer_border_corner_to_backdrop( snode, region, rect.xmax, rect.ymax, ibuf->x, ibuf->y, &rectf.xmax, &rectf.ymax); - /* clamp coordinates */ + /* Clamp coordinates. */ rectf.xmin = max_ff(rectf.xmin, 0.0f); rectf.ymin = max_ff(rectf.ymin, 0.0f); rectf.xmax = min_ff(rectf.xmax, 1.0f); diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 1025c1b2edf..1ccebd18893 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -55,13 +55,13 @@ struct NodeInsertOfsData { bNodeTree *ntree; - bNode *insert; /* inserted node */ - bNode *prev, *next; /* prev/next node in the chain */ + bNode *insert; /* Inserted node. */ + bNode *prev, *next; /* Prev/next node in the chain. */ bNode *insert_parent; wmTimer *anim_timer; - float offset_x; /* offset to apply to node chain */ + float offset_x; /* Offset to apply to node chain. */ }; namespace blender::ed::space_node { @@ -188,7 +188,7 @@ static bNodeSocket *best_socket_output(bNodeTree *ntree, bNodeSocket *sock_target, const bool allow_multiple) { - /* first look for selected output */ + /* First look for selected output. */ LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { if (!socket_is_available(ntree, sock, allow_multiple)) { continue; @@ -199,13 +199,13 @@ static bNodeSocket *best_socket_output(bNodeTree *ntree, } } - /* try to find a socket with a matching name */ + /* Try to find a socket with a matching name. */ LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { if (!socket_is_available(ntree, sock, allow_multiple)) { continue; } - /* check for same types */ + /* Check for same types. */ if (sock->type == sock_target->type) { if (STREQ(sock->name, sock_target->name)) { return sock; @@ -213,13 +213,13 @@ static bNodeSocket *best_socket_output(bNodeTree *ntree, } } - /* otherwise settle for the first available socket of the right type */ + /* Otherwise settle for the first available socket of the right type. */ LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) { if (!socket_is_available(ntree, sock, allow_multiple)) { continue; } - /* check for same types */ + /* Check for same types. */ if (sock->type == sock_target->type) { return sock; } @@ -234,8 +234,8 @@ static bNodeSocket *best_socket_output(bNodeTree *ntree, return nullptr; } -/* this is a bit complicated, but designed to prioritize finding - * sockets of higher types, such as image, first */ +/* This is a bit complicated, but designed to prioritize finding + * sockets of higher types, such as image, first. */ static bNodeSocket *best_socket_input(bNodeTree *ntree, bNode *node, int num, int replace) { int maxtype = 0; @@ -243,7 +243,7 @@ static bNodeSocket *best_socket_input(bNodeTree *ntree, bNode *node, int num, in maxtype = max_ii(sock->type, maxtype); } - /* find sockets of higher 'types' first (i.e. image) */ + /* Find sockets of higher 'types' first (i.e. image). */ int a = 0; for (int socktype = maxtype; socktype >= 0; socktype--) { LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { @@ -253,8 +253,8 @@ static bNodeSocket *best_socket_input(bNodeTree *ntree, bNode *node, int num, in } if (sock->type == socktype) { - /* increment to make sure we don't keep finding - * the same socket on every attempt running this function */ + /* Increment to make sure we don't keep finding the same socket on every attempt running + * this function. */ a++; if (a > num) { return sock; @@ -275,7 +275,6 @@ static bool snode_autoconnect_input(SpaceNode &snode, { bNodeTree *ntree = snode.edittree; - /* then we can connect */ if (replace) { nodeRemSocketLinks(ntree, sock_to); } @@ -357,12 +356,12 @@ static void snode_autoconnect(SpaceNode &snode, const bool allow_multiple, const bNode *node_fr = sorted_nodes[i]; bNode *node_to = sorted_nodes[i + 1]; - /* corner case: input/output node aligned the wrong way around (T47729) */ + /* Corner case: input/output node aligned the wrong way around (T47729). */ if (BLI_listbase_is_empty(&node_to->inputs) || BLI_listbase_is_empty(&node_fr->outputs)) { SWAP(bNode *, node_fr, node_to); } - /* if there are selected sockets, connect those */ + /* If there are selected sockets, connect those. */ LISTBASE_FOREACH (bNodeSocket *, sock_to, &node_to->inputs) { if (sock_to->flag & SELECT) { has_selected_inputs = true; @@ -371,7 +370,7 @@ static void snode_autoconnect(SpaceNode &snode, const bool allow_multiple, const continue; } - /* check for an appropriate output socket to connect from */ + /* Check for an appropriate output socket to connect from. */ bNodeSocket *sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple); if (!sock_fr) { continue; @@ -384,18 +383,18 @@ static void snode_autoconnect(SpaceNode &snode, const bool allow_multiple, const } if (!has_selected_inputs) { - /* no selected inputs, connect by finding suitable match */ + /* No selected inputs, connect by finding suitable match. */ int num_inputs = BLI_listbase_count(&node_to->inputs); for (int i = 0; i < num_inputs; i++) { - /* find the best guess input socket */ + /* Find the best guess input socket. */ bNodeSocket *sock_to = best_socket_input(ntree, node_to, i, replace); if (!sock_to) { continue; } - /* check for an appropriate output socket to connect from */ + /* Check for an appropriate output socket to connect from. */ bNodeSocket *sock_fr = best_socket_output(ntree, node_fr, sock_to, allow_multiple); if (!sock_fr) { continue; @@ -902,9 +901,7 @@ static void add_dragged_links_to_tree(bContext &C, bNodeLinkDrag &nldrag) if (!link.tosock || !link.fromsock) { continue; } - /* before actually adding the link, - * let nodes perform special link insertion handling - */ + /* Before actually adding the link let nodes perform special link insertion handling. */ bNodeLink *new_link = MEM_new(__func__, link); if (link.fromnode->typeinfo->insert_link) { link.fromnode->typeinfo->insert_link(&ntree, link.fromnode, new_link); @@ -913,11 +910,11 @@ static void add_dragged_links_to_tree(bContext &C, bNodeLinkDrag &nldrag) link.tonode->typeinfo->insert_link(&ntree, link.tonode, new_link); } - /* add link to the node tree */ + /* Add link to the node tree. */ BLI_addtail(&ntree.links, new_link); BKE_ntree_update_tag_link_added(&ntree, new_link); - /* we might need to remove a link */ + /* We might need to remove a link. */ node_remove_extra_links(snode, *new_link); } @@ -952,7 +949,7 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur if (bNodeSocket *tsock = node_find_indicated_socket(snode, cursor, SOCK_IN)) { bNode &tnode = tsock->owner_node(); for (bNodeLink &link : nldrag.links) { - /* skip if socket is on the same node as the fromsock */ + /* Skip if socket is on the same node as the fromsock. */ if (link.fromnode == &tnode) { continue; } @@ -966,7 +963,7 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur } } - /* attach links to the socket */ + /* Attach links to the socket. */ link.tonode = &tnode; link.tosock = tsock; nldrag.last_node_hovered_while_dragging_a_link = &tnode; @@ -995,16 +992,16 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur if (bNodeSocket *tsock = node_find_indicated_socket(snode, cursor, SOCK_OUT)) { bNode &node = tsock->owner_node(); for (bNodeLink &link : nldrag.links) { - /* skip if this is already the target socket */ + /* Skip if this is already the target socket. */ if (link.fromsock == tsock) { continue; } - /* skip if socket is on the same node as the fromsock */ + /* Skip if socket is on the same node as the `fromsock`. */ if (link.tonode == &node) { continue; } - /* attach links to the socket */ + /* Attach links to the socket. */ link.fromnode = &node; link.fromsock = tsock; } @@ -1097,9 +1094,9 @@ static std::unique_ptr node_link_init(SpaceNode &snode, nldrag->start_link_count = nodeCountSocketLinks(snode.edittree, sock); int link_limit = nodeSocketLinkLimit(sock); if (nldrag->start_link_count > 0 && (nldrag->start_link_count >= link_limit || detach)) { - /* dragged links are fixed on input side */ + /* Dragged links are fixed on input side. */ nldrag->in_out = SOCK_IN; - /* detach current links and store them in the operator data */ + /* Detach current links and store them in the operator data. */ LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &snode.edittree->links) { if (link->fromsock == sock) { bNodeLink oplink = *link; @@ -1112,7 +1109,7 @@ static std::unique_ptr node_link_init(SpaceNode &snode, } } else { - /* dragged links are fixed on output side */ + /* Dragged links are fixed on output side. */ nldrag->in_out = SOCK_OUT; nldrag->links.append(create_drag_link(node, *sock)); } @@ -1128,9 +1125,9 @@ static std::unique_ptr node_link_init(SpaceNode &snode, nldrag->start_link_count = nodeCountSocketLinks(snode.edittree, sock); if (nldrag->start_link_count > 0) { - /* dragged links are fixed on output side */ + /* Dragged links are fixed on output side. */ nldrag->in_out = SOCK_OUT; - /* detach current links and store them in the operator data */ + /* Detach current links and store them in the operator data. */ bNodeLink *link_to_pick; LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &snode.edittree->links) { if (link->tosock == sock) { @@ -1146,12 +1143,12 @@ static std::unique_ptr node_link_init(SpaceNode &snode, nldrag->links.append(oplink); nodeRemLink(snode.edittree, link_to_pick); - /* send changed event to original link->tonode */ + /* Send changed event to original link->tonode. */ BKE_ntree_update_tag_node_property(snode.edittree, &node); } } else { - /* dragged links are fixed on input side */ + /* Dragged links are fixed on input side. */ nldrag->in_out = SOCK_IN; nldrag->links.append(create_drag_link(node, *sock)); } @@ -1207,7 +1204,6 @@ void NODE_OT_link(wmOperatorType *ot) /* api callbacks */ ot->invoke = node_link_invoke; ot->modal = node_link_modal; - // ot->exec = node_link_exec; ot->poll = ED_operator_node_editable; ot->cancel = node_link_cancel; @@ -1241,7 +1237,7 @@ void NODE_OT_link(wmOperatorType *ot) /** \name Make Link Operator * \{ */ -/* makes a link between selected output and input sockets */ +/* Makes a link between selected output and input sockets. */ static int node_make_link_exec(bContext *C, wmOperator *op) { Main &bmain = *CTX_data_main(C); @@ -1253,7 +1249,7 @@ static int node_make_link_exec(bContext *C, wmOperator *op) snode_autoconnect(snode, true, replace); - /* deselect sockets after linking */ + /* Deselect sockets after linking. */ node_deselect_all_input_sockets(node_tree, false); node_deselect_all_output_sockets(node_tree, false); @@ -1716,14 +1712,14 @@ static int node_attach_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *e } if (node->parent == nullptr) { - /* disallow moving a parent into its child */ + /* Disallow moving a parent into its child. */ if (nodeAttachNodeCheck(frame, node) == false) { - /* attach all unparented nodes */ + /* Attach all unparented nodes. */ nodeAttachNode(&ntree, node, frame); } } else { - /* attach nodes which share parent with the frame */ + /* Attach nodes which share parent with the frame. */ bNode *parent; for (parent = frame->parent; parent; parent = parent->parent) { if (parent == node->parent) { @@ -1732,7 +1728,7 @@ static int node_attach_invoke(bContext *C, wmOperator * /*op*/, const wmEvent *e } if (parent) { - /* disallow moving a parent into its child */ + /* Disallow moving a parent into its child. */ if (nodeAttachNodeCheck(frame, node) == false) { nodeDetachNode(&ntree, node); nodeAttachNode(&ntree, node, frame); @@ -1781,17 +1777,17 @@ static void node_detach_recursive(bNodeTree &ntree, detach_states[node->index()].done = true; if (node->parent) { - /* call recursively */ + /* Call recursively. */ if (!detach_states[node->parent->index()].done) { node_detach_recursive(ntree, detach_states, node->parent); } - /* in any case: if the parent is a descendant, so is the child */ + /* In any case: if the parent is a descendant, so is the child. */ if (detach_states[node->parent->index()].descendent) { detach_states[node->index()].descendent = true; } else if (node->flag & NODE_SELECT) { - /* if parent is not a descendant of a selected node, detach */ + /* If parent is not a descendant of a selected node, detach. */ nodeDetachNode(&ntree, node); detach_states[node->index()].descendent = true; } @@ -1801,7 +1797,7 @@ static void node_detach_recursive(bNodeTree &ntree, } } -/* detach the root nodes in the current selection */ +/* Detach the root nodes in the current selection. */ static int node_detach_exec(bContext *C, wmOperator * /*op*/) { SpaceNode &snode = *CTX_wm_space_node(C); @@ -1809,9 +1805,7 @@ static int node_detach_exec(bContext *C, wmOperator * /*op*/) Array detach_states(ntree.all_nodes().size(), NodeDetachstate{false, false}); - /* detach nodes recursively - * relative order is preserved here! - */ + /* Detach nodes recursively. Relative order is preserved here. */ for (bNode *node : ntree.all_nodes()) { if (!detach_states[node->index()].done) { node_detach_recursive(ntree, detach_states, node); @@ -1889,7 +1883,7 @@ void node_insert_on_link_flags_set(SpaceNode &snode, const ARegion ®ion) return; } - /* find link to select/highlight */ + /* Find link to select/highlight. */ bNodeLink *selink = nullptr; float dist_best = FLT_MAX; LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) { @@ -1901,23 +1895,22 @@ void node_insert_on_link_flags_set(SpaceNode &snode, const ARegion ®ion) node_link_bezier_points_evaluated(*link, coords); float dist = FLT_MAX; - /* loop over link coords to find shortest dist to - * upper left node edge of a intersected line segment */ + /* Loop over link coords to find shortest dist to upper left node edge of a intersected line + * segment. */ for (int i = 0; i < NODE_LINK_RESOL; i++) { /* Check if the node rectangle intersects the line from this point to next one. */ if (BLI_rctf_isect_segment(&node_to_insert->runtime->totr, coords[i], coords[i + 1])) { - /* store the shortest distance to the upper left edge - * of all intersections found so far */ + /* Store the shortest distance to the upper left edge of all intersections found so far. */ const float node_xy[] = {node_to_insert->runtime->totr.xmin, node_to_insert->runtime->totr.ymax}; - /* to be precise coords should be clipped by select->totr, - * but not done since there's no real noticeable difference */ + /* To be precise coords should be clipped by `select->totr`, but not done since there's no + * real noticeable difference. */ dist = min_ff(dist_squared_to_line_segment_v2(node_xy, coords[i], coords[i + 1]), dist); } } - /* we want the link with the shortest distance to node center */ + /* We want the link with the shortest distance to node center. */ if (dist < dist_best) { dist_best = dist; selink = link; @@ -2070,7 +2063,7 @@ bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_ } } - /* find priority range */ + /* Find priority range. */ int maxpriority = -1; LISTBASE_FOREACH (bNodeSocket *, sock, sockets) { if (sock->flag & SOCK_UNAVAIL) { @@ -2079,7 +2072,7 @@ bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_ maxpriority = max_ii(get_main_socket_priority(sock), maxpriority); } - /* try all priorities, starting from 'highest' */ + /* Try all priorities, starting from 'highest'. */ for (int priority = maxpriority; priority >= 0; priority--) { LISTBASE_FOREACH (bNodeSocket *, sock, sockets) { if (!!sock->is_visible() && priority == get_main_socket_priority(sock)) { @@ -2088,7 +2081,7 @@ bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_ } } - /* no visible sockets, unhide first of highest priority */ + /* No visible sockets, unhide first of highest priority. */ for (int priority = maxpriority; priority >= 0; priority--) { LISTBASE_FOREACH (bNodeSocket *, sock, sockets) { if (sock->flag & SOCK_UNAVAIL) { @@ -2236,13 +2229,13 @@ static void node_link_insert_offset_ntree(NodeInsertOfsData *iofsd, rctf totr_insert; node_to_updated_rect(insert, totr_insert); - /* frame attachment wasn't handled yet - * so we search the frame that the node will be attached to later */ + /* Frame attachment wasn't handled yet so we search the frame that the node will be attached to + * later. */ insert.parent = node_find_frame_to_attach(*region, *ntree, mouse_xy); - /* this makes sure nodes are also correctly offset when inserting a node on top of a frame + /* This makes sure nodes are also correctly offset when inserting a node on top of a frame * without actually making it a part of the frame (because mouse isn't intersecting it) - * - logic here is similar to node_find_frame_to_attach */ + * - logic here is similar to node_find_frame_to_attach. */ if (!insert.parent || (prev->parent && (prev->parent == next->parent) && (prev->parent != insert.parent))) { bNode *frame; diff --git a/source/blender/editors/space_node/node_select.cc b/source/blender/editors/space_node/node_select.cc index 9f133f10c1f..fbd625932dd 100644 --- a/source/blender/editors/space_node/node_select.cc +++ b/source/blender/editors/space_node/node_select.cc @@ -262,7 +262,7 @@ void node_deselect_all_input_sockets(bNodeTree &node_tree, const bool deselect_n socket->flag &= ~SELECT; } - /* if no selected sockets remain, also deselect the node */ + /* If no selected sockets remain, also deselect the node. */ if (deselect_nodes) { LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) { if (socket->flag & SELECT) { @@ -530,18 +530,18 @@ static bool node_mouse_select(bContext *C, bNode *node = nullptr; bNodeSocket *sock = nullptr; - /* always do socket_select when extending selection. */ + /* Always do socket_select when extending selection. */ const bool socket_select = (params->sel_op == SEL_OP_XOR) || RNA_boolean_get(op->ptr, "socket_select"); bool changed = false; bool found = false; bool node_was_selected = false; - /* get mouse coordinates in view2d space */ + /* Get mouse coordinates in view2d space. */ float2 cursor; UI_view2d_region_to_view(®ion.v2d, mval.x, mval.y, &cursor.x, &cursor.y); - /* first do socket selection, these generally overlap with nodes. */ + /* First do socket selection, these generally overlap with nodes. */ if (socket_select) { /* NOTE: unlike nodes #SelectPick_Params isn't fully supported. */ const bool extend = (params->sel_op == SEL_OP_XOR); @@ -599,7 +599,7 @@ static bool node_mouse_select(bContext *C, if (!sock) { - /* find the closest visible node */ + /* Find the closest visible node. */ node = node_under_mouse_select(node_tree, cursor); found = (node != nullptr); node_was_selected = node && (node->flag & SELECT); @@ -617,28 +617,25 @@ static bool node_mouse_select(bContext *C, if (found) { switch (params->sel_op) { - case SEL_OP_ADD: { + case SEL_OP_ADD: nodeSetSelected(node, true); break; - } - case SEL_OP_SUB: { + case SEL_OP_SUB: nodeSetSelected(node, false); break; - } case SEL_OP_XOR: { /* Check active so clicking on an inactive node activates it. */ bool is_selected = (node->flag & NODE_SELECT) && (node->flag & NODE_ACTIVE); nodeSetSelected(node, !is_selected); break; } - case SEL_OP_SET: { + case SEL_OP_SET: nodeSetSelected(node, true); break; - } - case SEL_OP_AND: { - BLI_assert_unreachable(); /* Doesn't make sense for picking. */ + case SEL_OP_AND: + /* Doesn't make sense for picking. */ + BLI_assert_unreachable(); break; - } } changed = true; @@ -681,20 +678,20 @@ static bool node_mouse_select(bContext *C, static int node_select_exec(bContext *C, wmOperator *op) { - /* get settings from RNA properties for operator */ + /* Get settings from RNA properties for operator. */ int2 mval; RNA_int_get_array(op->ptr, "location", mval); SelectPick_Params params = {}; ED_select_pick_params_from_operator(op->ptr, ¶ms); - /* perform the select */ + /* Perform the selection. */ const bool changed = node_mouse_select(C, op, mval, ¶ms); if (changed) { return OPERATOR_PASS_THROUGH | OPERATOR_FINISHED; } - /* Nothing selected, just passthrough. */ + /* Nothing selected, just pass through. */ return OPERATOR_PASS_THROUGH | OPERATOR_CANCELLED; } @@ -962,10 +959,9 @@ static bool do_lasso_select_node(bContext *C, changed = true; } - /* get rectangle from operator */ + /* Get rectangle from operator. */ BLI_lasso_boundbox(&rect, mcoords, mcoords_len); - /* do actual selection */ for (bNode *node : node_tree.all_nodes()) { if (select && (node->flag & NODE_SELECT)) { continue; @@ -1389,7 +1385,7 @@ static uiBlock *node_find_menu(bContext *C, ARegion *region, void *arg_op) but, nullptr, node_find_update_fn, op->type, false, nullptr, node_find_exec_fn, nullptr); UI_but_flag_enable(but, UI_BUT_ACTIVATE_ON_INIT); - /* fake button, it holds space for search items */ + /* Fake button holds space for search items. */ uiDefBut(block, UI_BTYPE_LABEL, 0, From 03abc386242303441a779fca5f968475b33b8fc3 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 3 Jan 2023 20:02:43 -0500 Subject: [PATCH 0382/1522] Cleanup: Remove unused code in node editor --- .../blender/editors/space_node/node_edit.cc | 80 ------------------- 1 file changed, 80 deletions(-) diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index cb22e48350f..7f6a04e4381 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -819,86 +819,6 @@ void ED_node_post_apply_transform(bContext * /*C*/, bNodeTree * /*ntree*/) namespace blender::ed::space_node { -/* -------------------------------------------------------------------- */ -/** \name Generic Operator Functions for Nodes - * \{ */ - -#if 0 /* UNUSED */ - -static bool edit_node_poll(bContext *C) -{ - return ED_operator_node_active(C); -} - -static void edit_node_properties(wmOperatorType *ot) -{ - /* XXX could node be a context pointer? */ - RNA_def_string(ot->srna, "node", nullptr, MAX_NAME, "Node", ""); - RNA_def_int(ot->srna, "socket", 0, 0, MAX_SOCKET, "Socket", "", 0, MAX_SOCKET); - RNA_def_enum(ot->srna, "in_out", rna_enum_node_socket_in_out_items, SOCK_IN, "Socket Side", ""); -} - -static int edit_node_invoke_properties(bContext *C, wmOperator *op) -{ - if (!RNA_struct_property_is_set(op->ptr, "node")) { - bNode *node = CTX_data_pointer_get_type(C, "node", &RNA_Node).data; - if (!node) { - return 0; - } - else { - RNA_string_set(op->ptr, "node", node->name); - } - } - - if (!RNA_struct_property_is_set(op->ptr, "in_out")) { - RNA_enum_set(op->ptr, "in_out", SOCK_IN); - } - - if (!RNA_struct_property_is_set(op->ptr, "socket")) { - RNA_int_set(op->ptr, "socket", 0); - } - - return 1; -} - -static void edit_node_properties_get( - wmOperator *op, bNodeTree *ntree, bNode **r_node, bNodeSocket **r_sock, int *r_in_out) -{ - bNode *node; - bNodeSocket *sock = nullptr; - char nodename[MAX_NAME]; - int sockindex; - int in_out; - - RNA_string_get(op->ptr, "node", nodename); - node = nodeFindNodebyName(ntree, nodename); - - in_out = RNA_enum_get(op->ptr, "in_out"); - - sockindex = RNA_int_get(op->ptr, "socket"); - switch (in_out) { - case SOCK_IN: - sock = BLI_findlink(&node->inputs, sockindex); - break; - case SOCK_OUT: - sock = BLI_findlink(&node->outputs, sockindex); - break; - } - - if (r_node) { - *r_node = node; - } - if (r_sock) { - *r_sock = sock; - } - if (r_in_out) { - *r_in_out = in_out; - } -} -#endif - -/** \} */ - /* -------------------------------------------------------------------- */ /** \name Node Generic * \{ */ From 80639a93a8efc9cb411672494ada277e91531de6 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 3 Jan 2023 20:28:56 -0500 Subject: [PATCH 0383/1522] Fix: Interface handlers crash after recent commit The view item handler would crash when there is no active button. --- source/blender/editors/interface/interface_handlers.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index 1055f18d4a0..dfd89dd2b38 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -9690,12 +9690,14 @@ static int ui_handle_view_item_event(bContext *C, if (event->type == LEFTMOUSE) { /* Only bother finding the active view item button if the active button isn't already a view * item. */ - uiBut *view_but = active_but->type == UI_BTYPE_VIEW_ITEM ? + uiBut *view_but = (active_but && active_but->type == UI_BTYPE_VIEW_ITEM) ? active_but : ui_view_item_find_mouse_over(region, event->xy); /* Will free active button if there already is one. */ - ui_handle_button_activate(C, region, view_but, BUTTON_ACTIVATE_OVER); - return ui_do_button(C, view_but->block, view_but, event); + if (view_but) { + ui_handle_button_activate(C, region, view_but, BUTTON_ACTIVATE_OVER); + return ui_do_button(C, view_but->block, view_but, event); + } } return WM_UI_HANDLER_CONTINUE; From c26616b2c1d69350cc75117c2bbc0bbc85138086 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 3 Jan 2023 22:59:25 -0500 Subject: [PATCH 0384/1522] Curves: Support boolean attribute selection type, simplifications Use the same `".selection"` attribute for both curve and point domains, instead of a different name for each. The attribute can now have either boolean or float type. Some tools create boolean selections. Other tools create float selections. Some tools "upgrade" the attribute from boolean to float. Edit mode tools that create selections from scratch can create boolean selections, but edit mode should generally be able to handle both selection types. Sculpt mode should be able to read boolean selections, but can also and write float values between zero and one. Theoretically we could just always use floats to store selections, but the type-agnosticism doesn't cost too much complexity given the existing APIs for dealing with it, and being able to use booleans is clearer in edit mode, and may allow future optimizations like more efficient ways to store boolean attributes. The attribute API is usually used directly for accessing the selection attribute. We rely on implicit type conversion and domain interpolation to simplify the rest of the code. Differential Revision: https://developer.blender.org/D16057 --- source/blender/blenkernel/BKE_curves.hh | 5 - .../blenkernel/intern/curves_geometry.cc | 22 --- source/blender/blenlib/BLI_array_utils.hh | 2 + source/blender/blenlib/intern/array_utils.cc | 9 + .../blenloader/intern/versioning_300.cc | 5 + .../engines/overlay/overlay_sculpt_curves.cc | 23 +-- .../draw/intern/draw_cache_impl_curves.cc | 6 +- source/blender/editors/curves/CMakeLists.txt | 1 + .../editors/curves/intern/curves_ops.cc | 133 +++++++++------ .../editors/curves/intern/curves_selection.cc | 117 +++++++++++++ source/blender/editors/include/ED_curves.h | 53 +++++- .../editors/include/ED_curves_sculpt.h | 23 --- .../editors/sculpt_paint/curves_sculpt_add.cc | 7 + .../sculpt_paint/curves_sculpt_comb.cc | 5 +- .../sculpt_paint/curves_sculpt_delete.cc | 2 +- .../sculpt_paint/curves_sculpt_density.cc | 9 +- .../sculpt_paint/curves_sculpt_grow_shrink.cc | 5 +- .../sculpt_paint/curves_sculpt_intern.hh | 13 +- .../editors/sculpt_paint/curves_sculpt_ops.cc | 155 ++++++++---------- .../sculpt_paint/curves_sculpt_pinch.cc | 5 +- .../sculpt_paint/curves_sculpt_puff.cc | 5 +- .../sculpt_paint/curves_sculpt_selection.cc | 140 +++------------- .../curves_sculpt_selection_paint.cc | 28 ++-- .../sculpt_paint/curves_sculpt_slide.cc | 5 +- .../sculpt_paint/curves_sculpt_smooth.cc | 5 +- .../sculpt_paint/curves_sculpt_snake_hook.cc | 5 +- .../spreadsheet_data_source_geometry.cc | 8 +- .../geometry/GEO_add_curves_on_mesh.hh | 2 + .../geometry/intern/add_curves_on_mesh.cc | 32 ++-- source/blender/modifiers/intern/MOD_mask.cc | 10 +- 30 files changed, 441 insertions(+), 399 deletions(-) create mode 100644 source/blender/editors/curves/intern/curves_selection.cc diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index 9382a912c02..31776676940 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -287,11 +287,6 @@ class CurvesGeometry : public ::CurvesGeometry { Span surface_uv_coords() const; MutableSpan surface_uv_coords_for_write(); - VArray selection_point_float() const; - MutableSpan selection_point_float_for_write(); - VArray selection_curve_float() const; - MutableSpan selection_curve_float_for_write(); - /** * Calculate the largest and smallest position values, only including control points * (rather than evaluated points). The existing values of `min` and `max` are taken into account. diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 5cbb0709c91..401dd113f2c 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -38,8 +38,6 @@ static const std::string ATTR_HANDLE_POSITION_RIGHT = "handle_right"; static const std::string ATTR_NURBS_ORDER = "nurbs_order"; static const std::string ATTR_NURBS_WEIGHT = "nurbs_weight"; static const std::string ATTR_NURBS_KNOTS_MODE = "knots_mode"; -static const std::string ATTR_SELECTION_POINT_FLOAT = ".selection_point_float"; -static const std::string ATTR_SELECTION_CURVE_FLOAT = ".selection_curve_float"; static const std::string ATTR_SURFACE_UV_COORDINATE = "surface_uv_coordinate"; /* -------------------------------------------------------------------- */ @@ -433,26 +431,6 @@ MutableSpan CurvesGeometry::surface_uv_coords_for_write() return get_mutable_attribute(*this, ATTR_DOMAIN_CURVE, ATTR_SURFACE_UV_COORDINATE); } -VArray CurvesGeometry::selection_point_float() const -{ - return get_varray_attribute(*this, ATTR_DOMAIN_POINT, ATTR_SELECTION_POINT_FLOAT, 1.0f); -} - -MutableSpan CurvesGeometry::selection_point_float_for_write() -{ - return get_mutable_attribute(*this, ATTR_DOMAIN_POINT, ATTR_SELECTION_POINT_FLOAT, 1.0f); -} - -VArray CurvesGeometry::selection_curve_float() const -{ - return get_varray_attribute(*this, ATTR_DOMAIN_CURVE, ATTR_SELECTION_CURVE_FLOAT, 1.0f); -} - -MutableSpan CurvesGeometry::selection_curve_float_for_write() -{ - return get_mutable_attribute(*this, ATTR_DOMAIN_CURVE, ATTR_SELECTION_CURVE_FLOAT, 1.0f); -} - /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/blenlib/BLI_array_utils.hh b/source/blender/blenlib/BLI_array_utils.hh index 264ac00e034..81ffa7eade8 100644 --- a/source/blender/blenlib/BLI_array_utils.hh +++ b/source/blender/blenlib/BLI_array_utils.hh @@ -112,4 +112,6 @@ inline void gather(const VArray &src, }); } +void invert_booleans(MutableSpan span); + } // namespace blender::array_utils diff --git a/source/blender/blenlib/intern/array_utils.cc b/source/blender/blenlib/intern/array_utils.cc index 2a231228dcb..1b5b071f0cd 100644 --- a/source/blender/blenlib/intern/array_utils.cc +++ b/source/blender/blenlib/intern/array_utils.cc @@ -33,4 +33,13 @@ void gather(const GSpan src, const IndexMask indices, GMutableSpan dst, const in gather(GVArray::ForSpan(src), indices, dst, grain_size); } +void invert_booleans(MutableSpan span) +{ + threading::parallel_for(span.index_range(), 4096, [&](IndexRange range) { + for (const int i : range) { + span[i] = !span[i]; + } + }); +} + } // namespace blender::array_utils diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index adc88a7caf5..4d9bbdfce77 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -50,6 +50,7 @@ #include "BKE_collection.h" #include "BKE_colortools.h" #include "BKE_curve.h" +#include "BKE_curves.hh" #include "BKE_data_transfer.h" #include "BKE_deform.h" #include "BKE_fcurve.h" @@ -3850,5 +3851,9 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) LISTBASE_FOREACH (Curves *, curves_id, &bmain->hair_curves) { curves_id->flag &= ~CV_SCULPT_SELECTION_ENABLED; } + LISTBASE_FOREACH (Curves *, curves_id, &bmain->hair_curves) { + BKE_id_attribute_rename(&curves_id->id, ".selection_point_float", ".selection", nullptr); + BKE_id_attribute_rename(&curves_id->id, ".selection_curve_float", ".selection", nullptr); + } } } diff --git a/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc index 73edf9dc5d3..40abfad12f5 100644 --- a/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc +++ b/source/blender/draw/engines/overlay/overlay_sculpt_curves.cc @@ -10,6 +10,7 @@ #include "draw_cache_impl.h" #include "overlay_private.hh" +#include "BKE_attribute.hh" #include "BKE_curves.hh" void OVERLAY_sculpt_curves_cache_init(OVERLAY_Data *vedata) @@ -31,18 +32,11 @@ void OVERLAY_sculpt_curves_cache_init(OVERLAY_Data *vedata) static bool everything_selected(const Curves &curves_id) { - const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap( - curves_id.geometry); - blender::VArray selection; - switch (curves_id.selection_domain) { - case ATTR_DOMAIN_POINT: - selection = curves.selection_point_float(); - break; - case ATTR_DOMAIN_CURVE: - selection = curves.selection_curve_float(); - break; - } - return selection.is_single() && selection.get_internal_single() == 1.0f; + using namespace blender; + const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); + const VArray selection = curves.attributes().lookup_or_default( + ".selection", ATTR_DOMAIN_POINT, true); + return selection.is_single() && selection.get_internal_single(); } void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *object) @@ -56,12 +50,9 @@ void OVERLAY_sculpt_curves_cache_populate(OVERLAY_Data *vedata, Object *object) } /* Retrieve the location of the texture. */ - const char *name = curves->selection_domain == ATTR_DOMAIN_POINT ? ".selection_point_float" : - ".selection_curve_float"; - bool is_point_domain; GPUVertBuf **texture = DRW_curves_texture_for_evaluated_attribute( - curves, name, &is_point_domain); + curves, ".selection", &is_point_domain); if (texture == nullptr) { return; } diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index 43ce533f8d1..4fb25113f57 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -11,6 +11,7 @@ #include "MEM_guardedalloc.h" +#include "BLI_devirtualize_parameters.hh" #include "BLI_listbase.h" #include "BLI_math_base.h" #include "BLI_math_vec_types.hh" @@ -334,17 +335,16 @@ static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id, GPU_vertbuf_init_with_format(cache.edit_points_data, &format_data); GPU_vertbuf_data_alloc(cache.edit_points_data, curves.points_num()); - VArray selection; + const VArray selection = curves.attributes().lookup_or_default( + ".selection", eAttrDomain(curves_id.selection_domain), true); switch (curves_id.selection_domain) { case ATTR_DOMAIN_POINT: - selection = curves.selection_point_float(); for (const int point_i : selection.index_range()) { const float point_selection = (selection[point_i] > 0.0f) ? 1.0f : 0.0f; GPU_vertbuf_attr_set(cache.edit_points_data, color, point_i, &point_selection); } break; case ATTR_DOMAIN_CURVE: - selection = curves.selection_curve_float(); for (const int curve_i : curves.curves_range()) { const float curve_selection = (selection[curve_i] > 0.0f) ? 1.0f : 0.0f; const IndexRange points = curves.points_for_curve(curve_i); diff --git a/source/blender/editors/curves/CMakeLists.txt b/source/blender/editors/curves/CMakeLists.txt index 945bba0a77c..4d81b4454ac 100644 --- a/source/blender/editors/curves/CMakeLists.txt +++ b/source/blender/editors/curves/CMakeLists.txt @@ -22,6 +22,7 @@ set(INC set(SRC intern/curves_add.cc intern/curves_ops.cc + intern/curves_selection.cc ) set(LIB diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 880470ea66f..924967aad8a 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -6,7 +6,9 @@ #include +#include "BLI_array_utils.hh" #include "BLI_devirtualize_parameters.hh" +#include "BLI_index_mask_ops.hh" #include "BLI_utildefines.h" #include "BLI_vector_set.hh" @@ -748,7 +750,6 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op) continue; } - const eAttrDomain old_domain = eAttrDomain(curves_id->selection_domain); curves_id->selection_domain = domain; CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry); @@ -756,18 +757,21 @@ static int curves_set_selection_domain_exec(bContext *C, wmOperator *op) if (curves.points_num() == 0) { continue; } - - if (old_domain == ATTR_DOMAIN_POINT && domain == ATTR_DOMAIN_CURVE) { - VArray curve_selection = curves.adapt_domain( - curves.selection_point_float(), ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE); - curve_selection.materialize(curves.selection_curve_float_for_write()); - attributes.remove(".selection_point_float"); + const GVArray src = attributes.lookup(".selection", domain); + if (src.is_empty()) { + continue; } - else if (old_domain == ATTR_DOMAIN_CURVE && domain == ATTR_DOMAIN_POINT) { - VArray point_selection = curves.adapt_domain( - curves.selection_curve_float(), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT); - point_selection.materialize(curves.selection_point_float_for_write()); - attributes.remove(".selection_curve_float"); + + const CPPType &type = src.type(); + void *dst = MEM_malloc_arrayN(attributes.domain_size(domain), type.size(), __func__); + src.materialize(dst); + + attributes.remove(".selection"); + if (!attributes.add(".selection", + domain, + bke::cpp_type_to_custom_data_type(type), + bke::AttributeInitMoveArray(dst))) { + MEM_freeN(dst); } /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic @@ -801,46 +805,54 @@ static void CURVES_OT_set_selection_domain(wmOperatorType *ot) RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE)); } -static bool varray_contains_nonzero(const VArray &data) +static bool contains(const VArray &varray, const bool value) { - bool contains_nonzero = false; - devirtualize_varray(data, [&](const auto array) { - for (const int i : data.index_range()) { - if (array[i] != 0.0f) { - contains_nonzero = true; - break; - } - } - }); - return contains_nonzero; + const CommonVArrayInfo info = varray.common_info(); + if (info.type == CommonVArrayInfo::Type::Single) { + return *static_cast(info.data) == value; + } + if (info.type == CommonVArrayInfo::Type::Span) { + const Span span(static_cast(info.data), varray.size()); + return threading::parallel_reduce( + span.index_range(), + 4096, + false, + [&](const IndexRange range, const bool init) { + return init || span.slice(range).contains(value); + }, + [&](const bool a, const bool b) { return a || b; }); + } + return threading::parallel_reduce( + varray.index_range(), + 2048, + false, + [&](const IndexRange range, const bool init) { + if (init) { + return init; + } + /* Alternatively, this could use #materialize to retrieve many values at once. */ + for (const int64_t i : range) { + if (varray[i] == value) { + return true; + } + } + return false; + }, + [&](const bool a, const bool b) { return a || b; }); } bool has_anything_selected(const Curves &curves_id) { const CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry); - switch (curves_id.selection_domain) { - case ATTR_DOMAIN_POINT: - return varray_contains_nonzero(curves.selection_point_float()); - case ATTR_DOMAIN_CURVE: - return varray_contains_nonzero(curves.selection_curve_float()); - } - BLI_assert_unreachable(); - return false; + const VArray selection = curves.attributes().lookup(".selection"); + return !selection || contains(selection, true); } -static bool any_point_selected(const CurvesGeometry &curves) +static bool has_anything_selected(const Span curves_ids) { - return varray_contains_nonzero(curves.selection_point_float()); -} - -static bool any_point_selected(const Span curves_ids) -{ - for (const Curves *curves_id : curves_ids) { - if (any_point_selected(CurvesGeometry::wrap(curves_id->geometry))) { - return true; - } - } - return false; + return std::any_of(curves_ids.begin(), curves_ids.end(), [](const Curves *curves_id) { + return has_anything_selected(*curves_id); + }); } namespace select_all { @@ -854,6 +866,16 @@ static void invert_selection(MutableSpan selection) }); } +static void invert_selection(GMutableSpan selection) +{ + if (selection.type().is()) { + array_utils::invert_booleans(selection.typed()); + } + else if (selection.type().is()) { + invert_selection(selection.typed()); + } +} + static int select_all_exec(bContext *C, wmOperator *op) { int action = RNA_enum_get(op->ptr, "action"); @@ -861,27 +883,34 @@ static int select_all_exec(bContext *C, wmOperator *op) VectorSet unique_curves = get_unique_editable_curves(*C); if (action == SEL_TOGGLE) { - action = any_point_selected(unique_curves) ? SEL_DESELECT : SEL_SELECT; + action = has_anything_selected(unique_curves) ? SEL_DESELECT : SEL_SELECT; } for (Curves *curves_id : unique_curves) { CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry); + bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); if (action == SEL_SELECT) { /* As an optimization, just remove the selection attributes when everything is selected. */ - bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); - attributes.remove(".selection_point_float"); - attributes.remove(".selection_curve_float"); + attributes.remove(".selection"); + } + else if (!attributes.contains(".selection")) { + BLI_assert(ELEM(action, SEL_INVERT, SEL_DESELECT)); + /* If the attribute doesn't exist and it's either deleted or inverted, create + * it with nothing selected, since that means everything was selected before. */ + attributes.add(".selection", + eAttrDomain(curves_id->selection_domain), + CD_PROP_BOOL, + bke::AttributeInitDefaultValue()); } else { - MutableSpan selection = curves_id->selection_domain == ATTR_DOMAIN_POINT ? - curves.selection_point_float_for_write() : - curves.selection_curve_float_for_write(); + bke::GSpanAttributeWriter selection = attributes.lookup_for_write_span(".selection"); if (action == SEL_DESELECT) { - selection.fill(0.0f); + fill_selection_false(selection.span); } else if (action == SEL_INVERT) { - invert_selection(selection); + invert_selection(selection.span); } + selection.finish(); } /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic diff --git a/source/blender/editors/curves/intern/curves_selection.cc b/source/blender/editors/curves/intern/curves_selection.cc new file mode 100644 index 00000000000..b36d18b5fbb --- /dev/null +++ b/source/blender/editors/curves/intern/curves_selection.cc @@ -0,0 +1,117 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup edcurves + */ + +#include "BLI_index_mask_ops.hh" + +#include "BKE_attribute.hh" +#include "BKE_curves.hh" + +#include "ED_curves.h" +#include "ED_object.h" + +namespace blender::ed::curves { + +static IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves, + Vector &r_indices) +{ + const IndexRange curves_range = curves.curves_range(); + const bke::AttributeAccessor attributes = curves.attributes(); + + /* Interpolate from points to curves manually as a performance improvement, since we are only + * interested in whether any point in each curve is selected. Retrieve meta data since + * #lookup_or_default from the attribute API doesn't give the domain of the attribute. */ + std::optional meta_data = attributes.lookup_meta_data(".selection"); + if (meta_data && meta_data->domain == ATTR_DOMAIN_POINT) { + /* Avoid the interpolation from interpolating the attribute to the + * curve domain by retrieving the point domain values directly. */ + const VArray selection = attributes.lookup_or_default( + ".selection", ATTR_DOMAIN_POINT, true); + if (selection.is_single()) { + return selection.get_internal_single() ? IndexMask(curves_range) : IndexMask(); + } + return index_mask_ops::find_indices_based_on_predicate( + curves_range, 512, r_indices, [&](const int64_t curve_i) { + const IndexRange points = curves.points_for_curve(curve_i); + /* The curve is selected if any of its points are selected. */ + Array point_selection(points.size()); + selection.materialize_compressed(points, point_selection); + return point_selection.as_span().contains(true); + }); + } + const VArray selection = attributes.lookup_or_default( + ".selection", ATTR_DOMAIN_CURVE, true); + return index_mask_ops::find_indices_from_virtual_array(curves_range, selection, 2048, r_indices); +} + +IndexMask retrieve_selected_curves(const Curves &curves_id, Vector &r_indices) +{ + const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); + return retrieve_selected_curves(curves, r_indices); +} + +static IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, + Vector &r_indices) +{ + return index_mask_ops::find_indices_from_virtual_array( + curves.points_range(), + curves.attributes().lookup_or_default(".selection", ATTR_DOMAIN_POINT, true), + 2048, + r_indices); +} + +IndexMask retrieve_selected_points(const Curves &curves_id, Vector &r_indices) +{ + const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); + return retrieve_selected_points(curves, r_indices); +} + +void ensure_selection_attribute(Curves &curves_id, const eCustomDataType create_type) +{ + bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); + bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); + if (attributes.contains(".selection")) { + return; + } + const eAttrDomain domain = eAttrDomain(curves_id.selection_domain); + const int domain_size = attributes.domain_size(domain); + switch (create_type) { + case CD_PROP_BOOL: + attributes.add(".selection", + domain, + CD_PROP_BOOL, + bke::AttributeInitVArray(VArray::ForSingle(true, domain_size))); + break; + case CD_PROP_FLOAT: + attributes.add(".selection", + domain, + CD_PROP_FLOAT, + bke::AttributeInitVArray(VArray::ForSingle(1.0f, domain_size))); + break; + default: + BLI_assert_unreachable(); + } +} + +void fill_selection_false(GMutableSpan selection) +{ + if (selection.type().is()) { + selection.typed().fill(false); + } + else if (selection.type().is()) { + selection.typed().fill(0.0f); + } +} +void fill_selection_true(GMutableSpan selection) +{ + if (selection.type().is()) { + selection.typed().fill(true); + } + else if (selection.type().is()) { + selection.typed().fill(1.0f); + } +} + +} // namespace blender::ed::curves diff --git a/source/blender/editors/include/ED_curves.h b/source/blender/editors/include/ED_curves.h index 00831ff7cc3..7d2bad635b5 100644 --- a/source/blender/editors/include/ED_curves.h +++ b/source/blender/editors/include/ED_curves.h @@ -20,20 +20,69 @@ void ED_operatortypes_curves(void); #ifdef __cplusplus -# include "BKE_curves.hh" +# include "BKE_attribute.hh" +# include "BLI_index_mask.hh" +# include "BLI_vector.hh" # include "BLI_vector_set.hh" +# include "BKE_curves.hh" + namespace blender::ed::curves { bke::CurvesGeometry primitive_random_sphere(int curves_size, int points_per_curve); -bool has_anything_selected(const Curves &curves_id); VectorSet get_unique_editable_curves(const bContext &C); void ensure_surface_deformation_node_exists(bContext &C, Object &curves_ob); +/* -------------------------------------------------------------------- */ +/** \name Poll Functions + * \{ */ + bool editable_curves_with_surface_poll(bContext *C); bool curves_with_surface_poll(bContext *C); bool editable_curves_poll(bContext *C); bool curves_poll(bContext *C); +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Selection + * + * Selection on curves can be stored on either attribute domain: either per-curve or per-point. It + * can be stored with a float or boolean data-type. The boolean data-type is faster, smaller, and + * corresponds better to edit-mode selections, but the float data type is useful for soft selection + * (like masking) in sculpt mode. + * + * The attribute API is used to do the necessary type and domain conversions when necessary, and + * can handle most interaction with the selection attribute, but these functions implement some + * helpful utilities on top of that. + * \{ */ + +void fill_selection_false(GMutableSpan span); +void fill_selection_true(GMutableSpan span); + +/** + * Return true if any element is selected, on either domain with either type. + */ +bool has_anything_selected(const Curves &curves_id); + +/** + * Find curves that have any point selected (a selection factor greater than zero), + * or curves that have their own selection factor greater than zero. + */ +IndexMask retrieve_selected_curves(const Curves &curves_id, Vector &r_indices); + +/** + * Find points that are selected (a selection factor greater than zero), + * or points in curves with a selection factor greater than zero). + */ +IndexMask retrieve_selected_points(const Curves &curves_id, Vector &r_indices); + +/** + * If the ".selection" attribute doesn't exist, create it with the requested type (bool or float). + */ +void ensure_selection_attribute(Curves &curves_id, const eCustomDataType create_type); + +/** \} */ + } // namespace blender::ed::curves #endif diff --git a/source/blender/editors/include/ED_curves_sculpt.h b/source/blender/editors/include/ED_curves_sculpt.h index b1c0b649d2b..66f57670cec 100644 --- a/source/blender/editors/include/ED_curves_sculpt.h +++ b/source/blender/editors/include/ED_curves_sculpt.h @@ -17,26 +17,3 @@ void ED_operatortypes_sculpt_curves(void); #ifdef __cplusplus } #endif - -#ifdef __cplusplus - -# include "BLI_index_mask.hh" -# include "BLI_vector.hh" - -namespace blender::ed::sculpt_paint { - -/** - * Find curves that have any point selected (a selection factor greater than zero), - * or curves that have their own selection factor greater than zero. - */ -IndexMask retrieve_selected_curves(const Curves &curves_id, Vector &r_indices); - -/** - * Find points that are selected (a selection factor greater than zero), - * or points in curves with a selection factor greater than zero). - */ -IndexMask retrieve_selected_points(const Curves &curves_id, Vector &r_indices); - -} // namespace blender::ed::sculpt_paint - -#endif diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc index fa9cf3d3a04..2da5a427aaa 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc @@ -241,6 +241,13 @@ struct AddOperationExecutor { const geometry::AddCurvesOnMeshOutputs add_outputs = geometry::add_curves_on_mesh( *curves_orig_, add_inputs); + bke::MutableAttributeAccessor attributes = curves_orig_->attributes_for_write(); + if (bke::GSpanAttributeWriter selection = attributes.lookup_for_write_span(".selection")) { + curves::fill_selection_true(selection.span.slice(selection.domain == ATTR_DOMAIN_POINT ? + add_outputs.new_points_range : + add_outputs.new_curves_range)); + selection.finish(); + } if (add_outputs.uv_error) { report_invalid_uv_map(stroke_extension.reports); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc index 52f2ddc6550..024e4ac3849 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc @@ -132,8 +132,9 @@ struct CombOperationExecutor { transforms_ = CurvesSurfaceTransforms(*curves_ob_orig_, curves_id_orig_->surface); - point_factors_ = get_point_selection(*curves_id_orig_); - curve_selection_ = retrieve_selected_curves(*curves_id_orig_, selected_curve_indices_); + point_factors_ = curves_orig_->attributes().lookup_or_default( + ".selection", ATTR_DOMAIN_POINT, 1.0f); + curve_selection_ = curves::retrieve_selected_curves(*curves_id_orig_, selected_curve_indices_); brush_pos_prev_re_ = self_->brush_pos_last_re_; brush_pos_re_ = stroke_extension.mouse_position; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc index a44499ce133..bad5b3ede71 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc @@ -97,7 +97,7 @@ struct DeleteOperationExecutor { curves_ = &CurvesGeometry::wrap(curves_id_->geometry); selected_curve_indices_.clear(); - curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_); + curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_); curves_sculpt_ = ctx_.scene->toolsettings->curves_sculpt; brush_ = BKE_paint_brush_for_read(&curves_sculpt_->paint); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc index 78eea553737..8d7c4a07574 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc @@ -286,6 +286,13 @@ struct DensityAddOperationExecutor { const geometry::AddCurvesOnMeshOutputs add_outputs = geometry::add_curves_on_mesh( *curves_orig_, add_inputs); + bke::MutableAttributeAccessor attributes = curves_orig_->attributes_for_write(); + if (bke::GSpanAttributeWriter selection = attributes.lookup_for_write_span(".selection")) { + curves::fill_selection_true(selection.span.slice(selection.domain == ATTR_DOMAIN_POINT ? + add_outputs.new_points_range : + add_outputs.new_curves_range)); + selection.finish(); + } if (add_outputs.uv_error) { report_invalid_uv_map(stroke_extension.reports); @@ -562,7 +569,7 @@ struct DensitySubtractOperationExecutor { minimum_distance_ = brush_->curves_sculpt_settings->minimum_distance; - curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_); + curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_); transforms_ = CurvesSurfaceTransforms(*object_, curves_id_->surface); const eBrushFalloffShape falloff_shape = static_cast( diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc index 2624d70ccf7..4e9bc2fba2c 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc @@ -280,8 +280,9 @@ struct CurvesEffectOperationExecutor { return; } - curve_selection_factors_ = get_curves_selection(*curves_id_); - curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_); + curve_selection_factors_ = curves_->attributes().lookup_or_default( + ".selection", ATTR_DOMAIN_CURVE, 1.0f); + curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_); const CurvesSculpt &curves_sculpt = *ctx_.scene->toolsettings->curves_sculpt; brush_ = BKE_paint_brush_for_read(&curves_sculpt.paint); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh index 61e2559f303..eb670d089e5 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/curves_sculpt_intern.hh @@ -11,10 +11,11 @@ #include "BLI_vector.hh" #include "BLI_virtual_array.hh" -#include "BKE_attribute.h" +#include "BKE_attribute.hh" #include "BKE_crazyspace.hh" #include "BKE_curves.hh" +#include "ED_curves.h" #include "ED_curves_sculpt.h" struct ARegion; @@ -92,15 +93,7 @@ std::optional sample_curves_3d_brush(const Depsgraph &depsgraph, Vector get_symmetry_brush_transforms(eCurvesSymmetryType symmetry); -/** - * Get the floating point selection on the curve domain, averaged from points if necessary. - */ -VArray get_curves_selection(const Curves &curves_id); - -/** - * Get the floating point selection on the curve domain, copied from curves if necessary. - */ -VArray get_point_selection(const Curves &curves_id); +bke::SpanAttributeWriter float_selection_ensure(Curves &curves_id); /** See #move_last_point_and_resample. */ struct MoveAndResampleBuffers { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc index d6c4d43d5fc..797b57dd0ca 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc @@ -363,12 +363,14 @@ static int select_random_exec(bContext *C, wmOperator *op) for (Curves *curves_id : unique_curves) { CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry); const bool was_anything_selected = curves::has_anything_selected(*curves_id); + + bke::SpanAttributeWriter attribute = float_selection_ensure(*curves_id); + MutableSpan selection = attribute.span; + if (!was_anything_selected) { + selection.fill(1.0f); + } switch (curves_id->selection_domain) { case ATTR_DOMAIN_POINT: { - MutableSpan selection = curves.selection_point_float_for_write(); - if (!was_anything_selected) { - selection.fill(1.0f); - } if (partial) { if (constant_per_curve) { for (const int curve_i : curves.curves_range()) { @@ -408,10 +410,6 @@ static int select_random_exec(bContext *C, wmOperator *op) break; } case ATTR_DOMAIN_CURVE: { - MutableSpan selection = curves.selection_curve_float_for_write(); - if (!was_anything_selected) { - selection.fill(1.0f); - } if (partial) { for (const int curve_i : curves.curves_range()) { const float random_value = next_partial_random_value(); @@ -429,9 +427,6 @@ static int select_random_exec(bContext *C, wmOperator *op) break; } } - MutableSpan selection = curves_id->selection_domain == ATTR_DOMAIN_POINT ? - curves.selection_point_float_for_write() : - curves.selection_curve_float_for_write(); const bool was_any_selected = std::any_of( selection.begin(), selection.end(), [](const float v) { return v > 0.0f; }); if (was_any_selected) { @@ -445,6 +440,8 @@ static int select_random_exec(bContext *C, wmOperator *op) } } + attribute.finish(); + /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic * attribute for now. */ DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY); @@ -541,22 +538,35 @@ static int select_end_exec(bContext *C, wmOperator *op) for (Curves *curves_id : unique_curves) { CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry); + bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); + const bool was_anything_selected = curves::has_anything_selected(*curves_id); - MutableSpan selection = curves.selection_point_float_for_write(); + curves::ensure_selection_attribute(*curves_id, CD_PROP_BOOL); + bke::GSpanAttributeWriter selection = attributes.lookup_for_write_span(".selection"); if (!was_anything_selected) { - selection.fill(1.0f); + curves::fill_selection_true(selection.span); } - threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) { - for (const int curve_i : range) { - const IndexRange points = curves.points_for_curve(curve_i); - if (end_points) { - selection.slice(points.drop_back(amount)).fill(0.0f); - } - else { - selection.slice(points.drop_front(amount)).fill(0.0f); - } + selection.span.type().to_static_type_tag([&](auto type_tag) { + using T = typename decltype(type_tag)::type; + if constexpr (std::is_void_v) { + BLI_assert_unreachable(); + } + else { + MutableSpan selection_typed = selection.span.typed(); + threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) { + for (const int curve_i : range) { + const IndexRange points = curves.points_for_curve(curve_i); + if (end_points) { + selection_typed.slice(points.drop_back(amount)).fill(T(0)); + } + else { + selection_typed.slice(points.drop_front(amount)).fill(T(0)); + } + } + }); } }); + selection.finish(); /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic * attribute for now. */ @@ -592,12 +602,14 @@ namespace select_grow { struct GrowOperatorDataPerCurve : NonCopyable, NonMovable { Curves *curves_id; - Vector selected_points; - Vector unselected_points; + Vector selected_point_indices; + Vector unselected_point_indices; + IndexMask selected_points; + IndexMask unselected_points; Array distances_to_selected; Array distances_to_unselected; - Array original_selection; + GArray<> original_selection; float pixel_to_distance_factor; }; @@ -621,7 +633,7 @@ static void update_points_selection(const GrowOperatorDataPerCurve &data, } }); threading::parallel_for(data.selected_points.index_range(), 512, [&](const IndexRange range) { - for (const int point_i : data.selected_points.as_span().slice(range)) { + for (const int point_i : data.selected_points.slice(range)) { points_selection[point_i] = 1.0f; } }); @@ -637,7 +649,7 @@ static void update_points_selection(const GrowOperatorDataPerCurve &data, }); threading::parallel_for( data.unselected_points.index_range(), 512, [&](const IndexRange range) { - for (const int point_i : data.unselected_points.as_span().slice(range)) { + for (const int point_i : data.unselected_points.slice(range)) { points_selection[point_i] = 0.0f; } }); @@ -653,18 +665,19 @@ static int select_grow_update(bContext *C, wmOperator *op, const float mouse_dif CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry); const float distance = curve_op_data->pixel_to_distance_factor * mouse_diff_x; + bke::SpanAttributeWriter selection = float_selection_ensure(curves_id); + /* Grow or shrink selection based on precomputed distances. */ - switch (curves_id.selection_domain) { + switch (selection.domain) { case ATTR_DOMAIN_POINT: { - MutableSpan points_selection = curves.selection_point_float_for_write(); - update_points_selection(*curve_op_data, distance, points_selection); + update_points_selection(*curve_op_data, distance, selection.span); break; } case ATTR_DOMAIN_CURVE: { Array new_points_selection(curves.points_num()); update_points_selection(*curve_op_data, distance, new_points_selection); /* Propagate grown point selection to the curve selection. */ - MutableSpan curves_selection = curves.selection_curve_float_for_write(); + MutableSpan curves_selection = selection.span; for (const int curve_i : curves.curves_range()) { const IndexRange points = curves.points_for_curve(curve_i); const Span points_selection = new_points_selection.as_span().slice(points); @@ -674,8 +687,12 @@ static int select_grow_update(bContext *C, wmOperator *op, const float mouse_dif } break; } + default: + BLI_assert_unreachable(); } + selection.finish(); + /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic * attribute for now. */ DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY); @@ -685,57 +702,28 @@ static int select_grow_update(bContext *C, wmOperator *op, const float mouse_dif return OPERATOR_FINISHED; } -static void select_grow_invoke_per_curve(Curves &curves_id, - Object &curves_ob, +static void select_grow_invoke_per_curve(const Curves &curves_id, + const Object &curves_ob, const ARegion ®ion, const View3D &v3d, const RegionView3D &rv3d, GrowOperatorDataPerCurve &curve_op_data) { - curve_op_data.curves_id = &curves_id; - CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry); + const CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry); const Span positions = curves.positions(); - /* Find indices of selected and unselected points. */ - switch (curves_id.selection_domain) { - case ATTR_DOMAIN_POINT: { - const VArray points_selection = curves.selection_point_float(); - curve_op_data.original_selection.reinitialize(points_selection.size()); - points_selection.materialize(curve_op_data.original_selection); - for (const int point_i : points_selection.index_range()) { - const float point_selection = points_selection[point_i]; - if (point_selection > 0.0f) { - curve_op_data.selected_points.append(point_i); - } - else { - curve_op_data.unselected_points.append(point_i); - } - } - - break; - } - case ATTR_DOMAIN_CURVE: { - const VArray curves_selection = curves.selection_curve_float(); - curve_op_data.original_selection.reinitialize(curves_selection.size()); - curves_selection.materialize(curve_op_data.original_selection); - for (const int curve_i : curves_selection.index_range()) { - const float curve_selection = curves_selection[curve_i]; - const IndexRange points = curves.points_for_curve(curve_i); - if (curve_selection > 0.0f) { - for (const int point_i : points) { - curve_op_data.selected_points.append(point_i); - } - } - else { - for (const int point_i : points) { - curve_op_data.unselected_points.append(point_i); - } - } - } - break; - } + if (const bke::GAttributeReader original_selection = curves.attributes().lookup(".selection")) { + curve_op_data.original_selection = GArray<>(original_selection.varray.type(), + original_selection.varray.size()); + original_selection.varray.materialize(curve_op_data.original_selection.data()); } + /* Find indices of selected and unselected points. */ + curve_op_data.selected_points = curves::retrieve_selected_points( + curves_id, curve_op_data.selected_point_indices); + curve_op_data.unselected_points = curve_op_data.selected_points.invert( + curves.points_range(), curve_op_data.unselected_point_indices); + threading::parallel_invoke( 1024 < curve_op_data.selected_points.size() + curve_op_data.unselected_points.size(), [&]() { @@ -838,6 +826,7 @@ static int select_grow_invoke(bContext *C, wmOperator *op, const wmEvent *event) Curves &curves_id = *static_cast(active_ob->data); auto curve_op_data = std::make_unique(); + curve_op_data->curves_id = &curves_id; select_grow_invoke_per_curve(curves_id, *active_ob, *region, *v3d, *rv3d, *curve_op_data); op_data->per_curve.append(std::move(curve_op_data)); @@ -865,17 +854,15 @@ static int select_grow_modal(bContext *C, wmOperator *op, const wmEvent *event) for (std::unique_ptr &curve_op_data : op_data.per_curve) { Curves &curves_id = *curve_op_data->curves_id; CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry); - switch (curves_id.selection_domain) { - case ATTR_DOMAIN_POINT: { - MutableSpan points_selection = curves.selection_point_float_for_write(); - points_selection.copy_from(curve_op_data->original_selection); - break; - } - case ATTR_DOMAIN_CURVE: { - MutableSpan curves_seletion = curves.selection_curve_float_for_write(); - curves_seletion.copy_from(curve_op_data->original_selection); - break; - } + bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); + + attributes.remove(".selection"); + if (!curve_op_data->original_selection.is_empty()) { + attributes.add( + ".selection", + eAttrDomain(curves_id.selection_domain), + bke::cpp_type_to_custom_data_type(curve_op_data->original_selection.type()), + bke::AttributeInitVArray(GVArray::ForSpan(curve_op_data->original_selection))); } /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc b/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc index 3e43b1a6361..1677a7499c6 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc @@ -105,8 +105,9 @@ struct PinchOperationExecutor { transforms_ = CurvesSurfaceTransforms(*object_, curves_id_->surface); - point_factors_ = get_point_selection(*curves_id_); - curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_); + point_factors_ = curves_->attributes().lookup_or_default( + ".selection", ATTR_DOMAIN_POINT, 1.0f); + curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_); brush_pos_re_ = stroke_extension.mouse_position; const eBrushFalloffShape falloff_shape = static_cast( diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc index b4e949106e7..5224385d4aa 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc @@ -102,8 +102,9 @@ struct PuffOperationExecutor { brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension); brush_pos_re_ = stroke_extension.mouse_position; - point_factors_ = get_point_selection(*curves_id_); - curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_); + point_factors_ = curves_->attributes().lookup_or_default( + ".selection", ATTR_DOMAIN_POINT, 1.0f); + curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_); falloff_shape_ = static_cast(brush_->falloff_shape); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc index 7ae92a99919..adc4f965102 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc @@ -10,132 +10,34 @@ namespace blender::ed::sculpt_paint { -static VArray get_curves_selection(const CurvesGeometry &curves, const eAttrDomain domain) +bke::SpanAttributeWriter float_selection_ensure(Curves &curves_id) { - switch (domain) { - case ATTR_DOMAIN_CURVE: - return curves.selection_curve_float(); - case ATTR_DOMAIN_POINT: - return curves.adapt_domain( - curves.selection_point_float(), ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE); - default: - BLI_assert_unreachable(); - return {}; - } -} + /* TODO: Use a generic attribute conversion utility instead of this function. */ + bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); + bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); -VArray get_curves_selection(const Curves &curves_id) -{ - return get_curves_selection(CurvesGeometry::wrap(curves_id.geometry), - eAttrDomain(curves_id.selection_domain)); -} + if (const auto meta_data = attributes.lookup_meta_data(".selection")) { + if (meta_data->data_type == CD_PROP_BOOL) { + const VArray selection = attributes.lookup(".selection"); + float *dst = static_cast( + MEM_malloc_arrayN(selection.size(), sizeof(float), __func__)); + selection.materialize({dst, selection.size()}); -static VArray get_point_selection(const CurvesGeometry &curves, const eAttrDomain domain) -{ - switch (domain) { - case ATTR_DOMAIN_CURVE: - return curves.adapt_domain( - curves.selection_curve_float(), ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT); - case ATTR_DOMAIN_POINT: - return curves.selection_point_float(); - default: - BLI_assert_unreachable(); - return {}; - } -} - -VArray get_point_selection(const Curves &curves_id) -{ - return get_point_selection(CurvesGeometry::wrap(curves_id.geometry), - eAttrDomain(curves_id.selection_domain)); -} - -static IndexMask retrieve_selected_curves(const CurvesGeometry &curves, - const eAttrDomain domain, - Vector &r_indices) -{ - switch (domain) { - case ATTR_DOMAIN_POINT: { - const VArray selection = curves.selection_point_float(); - if (selection.is_single()) { - return selection.get_internal_single() <= 0.0f ? IndexMask(0) : - IndexMask(curves.curves_num()); - } - const Span point_selection_span = selection.get_internal_span(); - return index_mask_ops::find_indices_based_on_predicate( - curves.curves_range(), 512, r_indices, [&](const int curve_i) { - for (const int i : curves.points_for_curve(curve_i)) { - if (point_selection_span[i] > 0.0f) { - return true; - } - } - return false; - }); + attributes.remove(".selection"); + attributes.add( + ".selection", meta_data->domain, CD_PROP_FLOAT, bke::AttributeInitMoveArray(dst)); } - case ATTR_DOMAIN_CURVE: { - const VArray selection = curves.selection_curve_float(); - if (selection.is_single()) { - return selection.get_internal_single() <= 0.0f ? IndexMask(0) : - IndexMask(curves.curves_num()); - } - return index_mask_ops::find_indices_based_on_predicate( - curves.curves_range(), 2048, r_indices, [&](const int i) { - return selection[i] > 0.0f; - }); - } - default: - BLI_assert_unreachable(); - return {}; } -} - -IndexMask retrieve_selected_curves(const Curves &curves_id, Vector &r_indices) -{ - return retrieve_selected_curves(CurvesGeometry::wrap(curves_id.geometry), - eAttrDomain(curves_id.selection_domain), - r_indices); -} - -static IndexMask retrieve_selected_points(const CurvesGeometry &curves, - const eAttrDomain domain, - Vector &r_indices) -{ - switch (domain) { - case ATTR_DOMAIN_POINT: { - const VArray selection = curves.selection_point_float(); - if (selection.is_single()) { - return selection.get_internal_single() <= 0.0f ? IndexMask(0) : - IndexMask(curves.points_num()); - } - return index_mask_ops::find_indices_based_on_predicate( - curves.points_range(), 2048, r_indices, [&](const int i) { - return selection[i] > 0.0f; - }); - } - case ATTR_DOMAIN_CURVE: { - const VArray selection = curves.selection_curve_float(); - if (selection.is_single()) { - return selection.get_internal_single() <= 0.0f ? IndexMask(0) : - IndexMask(curves.points_num()); - } - const VArray point_selection = curves.adapt_domain( - selection, ATTR_DOMAIN_CURVE, ATTR_DOMAIN_POINT); - return index_mask_ops::find_indices_based_on_predicate( - curves.points_range(), 2048, r_indices, [&](const int i) { - return point_selection[i] > 0.0f; - }); - } - default: - BLI_assert_unreachable(); - return {}; + else { + const eAttrDomain domain = eAttrDomain(curves_id.selection_domain); + const int64_t size = attributes.domain_size(domain); + attributes.add(".selection", + domain, + CD_PROP_FLOAT, + bke::AttributeInitVArray(VArray::ForSingle(size, 1.0f))); } -} -IndexMask retrieve_selected_points(const Curves &curves_id, Vector &r_indices) -{ - return retrieve_selected_points(CurvesGeometry::wrap(curves_id.geometry), - eAttrDomain(curves_id.selection_domain), - r_indices); + return curves.attributes_for_write().lookup_for_write_span(".selection"); } } // namespace blender::ed::sculpt_paint diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc b/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc index 3e2803ae5b7..c6fdb4a0926 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc @@ -8,6 +8,7 @@ #include "DNA_brush_types.h" +#include "BKE_attribute.hh" #include "BKE_brush.h" #include "BKE_context.h" #include "BKE_curves.hh" @@ -57,6 +58,8 @@ struct SelectionPaintOperationExecutor { Curves *curves_id_ = nullptr; CurvesGeometry *curves_ = nullptr; + bke::SpanAttributeWriter selection_; + const Brush *brush_ = nullptr; float brush_radius_base_re_; float brush_radius_factor_; @@ -84,6 +87,10 @@ struct SelectionPaintOperationExecutor { if (curves_->curves_num() == 0) { return; } + selection_ = float_selection_ensure(*curves_id_); + if (!selection_) { + return; + } brush_ = BKE_paint_brush_for_read(&ctx_.scene->toolsettings->curves_sculpt->paint); brush_radius_base_re_ = BKE_brush_size_get(ctx_.scene, brush_); @@ -94,12 +101,7 @@ struct SelectionPaintOperationExecutor { if (self.clear_selection_) { if (stroke_extension.is_first) { - if (curves_id_->selection_domain == ATTR_DOMAIN_POINT) { - curves_->selection_point_float_for_write().fill(0.0f); - } - else if (curves_id_->selection_domain == ATTR_DOMAIN_CURVE) { - curves_->selection_curve_float_for_write().fill(0.0f); - } + curves::fill_selection_false(selection_.span); } } @@ -116,25 +118,25 @@ struct SelectionPaintOperationExecutor { } } - if (curves_id_->selection_domain == ATTR_DOMAIN_POINT) { - MutableSpan selection = curves_->selection_point_float_for_write(); + if (selection_.domain == ATTR_DOMAIN_POINT) { if (falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { - this->paint_point_selection_projected_with_symmetry(selection); + this->paint_point_selection_projected_with_symmetry(selection_.span); } else if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { - this->paint_point_selection_spherical_with_symmetry(selection); + this->paint_point_selection_spherical_with_symmetry(selection_.span); } } else { - MutableSpan selection = curves_->selection_curve_float_for_write(); if (falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { - this->paint_curve_selection_projected_with_symmetry(selection); + this->paint_curve_selection_projected_with_symmetry(selection_.span); } else if (falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) { - this->paint_curve_selection_spherical_with_symmetry(selection); + this->paint_curve_selection_spherical_with_symmetry(selection_.span); } } + selection_.finish(); + /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because * selection is handled as a generic attribute for now. */ DEG_id_tag_update(&curves_id_->id, ID_RECALC_GEOMETRY); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc index 89110f72e4b..0ac70f51d8a 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc @@ -157,8 +157,9 @@ struct SlideOperationExecutor { brush_radius_factor_ = brush_radius_factor(*brush_, stroke_extension); brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension); - curve_factors_ = get_curves_selection(*curves_id_orig_); - curve_selection_ = retrieve_selected_curves(*curves_id_orig_, selected_curve_indices_); + curve_factors_ = curves_orig_->attributes().lookup_or_default( + ".selection", ATTR_DOMAIN_CURVE, 1.0f); + curve_selection_ = curves::retrieve_selected_curves(*curves_id_orig_, selected_curve_indices_); brush_pos_re_ = stroke_extension.mouse_position; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc b/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc index 37a7f1c83ed..9ef6333ad22 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc @@ -78,8 +78,9 @@ struct SmoothOperationExecutor { brush_strength_ = brush_strength_get(*ctx_.scene, *brush_, stroke_extension); brush_pos_re_ = stroke_extension.mouse_position; - point_factors_ = get_point_selection(*curves_id_); - curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_); + point_factors_ = curves_->attributes().lookup_or_default( + ".selection", ATTR_DOMAIN_POINT, 1.0f); + curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_); transforms_ = CurvesSurfaceTransforms(*object_, curves_id_->surface); const eBrushFalloffShape falloff_shape = static_cast( diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc index 67757ce5f4a..dbba292ecb3 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc @@ -125,8 +125,9 @@ struct SnakeHookOperatorExecutor { transforms_ = CurvesSurfaceTransforms(*object_, curves_id_->surface); - curve_factors_ = get_curves_selection(*curves_id_); - curve_selection_ = retrieve_selected_curves(*curves_id_, selected_curve_indices_); + curve_factors_ = curves_->attributes().lookup_or_default( + ".selection", ATTR_DOMAIN_CURVE, 1.0f); + curve_selection_ = curves::retrieve_selected_curves(*curves_id_, selected_curve_indices_); brush_pos_prev_re_ = self.last_mouse_position_re_; brush_pos_re_ = stroke_extension.mouse_position; diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index 024b140a426..9d7f2222d3d 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -25,7 +25,7 @@ #include "DEG_depsgraph_query.h" -#include "ED_curves_sculpt.h" +#include "ED_curves.h" #include "ED_spreadsheet.h" #include "NOD_geometry_nodes_lazy_function.hh" @@ -265,7 +265,7 @@ bool GeometryDataSource::has_selection_filter() const if (object_orig->type != OB_CURVES) { return false; } - if (object_orig->mode != OB_MODE_SCULPT_CURVES) { + if (!ELEM(object_orig->mode, OB_MODE_SCULPT_CURVES, OB_MODE_EDIT)) { return false; } return true; @@ -339,9 +339,9 @@ IndexMask GeometryDataSource::apply_selection_filter(Vector &indices) c const Curves &curves_id = *component.get_for_read(); switch (domain_) { case ATTR_DOMAIN_POINT: - return sculpt_paint::retrieve_selected_points(curves_id, indices); + return curves::retrieve_selected_points(curves_id, indices); case ATTR_DOMAIN_CURVE: - return sculpt_paint::retrieve_selected_curves(curves_id, indices); + return curves::retrieve_selected_curves(curves_id, indices); default: BLI_assert_unreachable(); } diff --git a/source/blender/geometry/GEO_add_curves_on_mesh.hh b/source/blender/geometry/GEO_add_curves_on_mesh.hh index d0f72deeb46..34959d13c7c 100644 --- a/source/blender/geometry/GEO_add_curves_on_mesh.hh +++ b/source/blender/geometry/GEO_add_curves_on_mesh.hh @@ -47,6 +47,8 @@ struct AddCurvesOnMeshInputs { struct AddCurvesOnMeshOutputs { bool uv_error = false; + IndexRange new_curves_range; + IndexRange new_points_range; }; /** diff --git a/source/blender/geometry/intern/add_curves_on_mesh.cc b/source/blender/geometry/intern/add_curves_on_mesh.cc index 1cc13a40fc4..0e9b89b35b4 100644 --- a/source/blender/geometry/intern/add_curves_on_mesh.cc +++ b/source/blender/geometry/intern/add_curves_on_mesh.cc @@ -303,6 +303,10 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, curves.resize(new_points_num, new_curves_num); MutableSpan positions_cu = curves.positions_for_write(); + /* The new elements are added at the end of the arrays. */ + outputs.new_points_range = curves.points_range().drop_front(old_points_num); + outputs.new_curves_range = curves.curves_range().drop_front(old_curves_num); + /* Initialize attachment information. */ MutableSpan surface_uv_coords = curves.surface_uv_coords_for_write(); surface_uv_coords.take_back(added_curves_num).copy_from(used_uvs); @@ -338,18 +342,6 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, } }); - /* Update selection arrays when available. */ - const VArray points_selection = curves.selection_point_float(); - if (points_selection.is_span()) { - MutableSpan points_selection_span = curves.selection_point_float_for_write(); - points_selection_span.drop_front(old_points_num).fill(1.0f); - } - const VArray curves_selection = curves.selection_curve_float(); - if (curves_selection.is_span()) { - MutableSpan curves_selection_span = curves.selection_curve_float_for_write(); - curves_selection_span.slice(new_curves_range).fill(1.0f); - } - /* Initialize position attribute. */ if (inputs.interpolate_shape) { interpolate_position_with_interpolation(curves, @@ -374,24 +366,20 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, curves.fill_curve_types(new_curves_range, CURVE_TYPE_CATMULL_ROM); - /* Explicitly set all other attributes besides those processed above to default values. */ bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); - Set attributes_to_skip{{"position", - "curve_type", - "surface_uv_coordinate", - ".selection_point_float", - ".selection_curve_float"}}; + + /* Explicitly set all other attributes besides those processed above to default values. */ + Set attributes_to_skip{{"position", "curve_type", "surface_uv_coordinate"}}; attributes.for_all( [&](const bke::AttributeIDRef &id, const bke::AttributeMetaData /*meta_data*/) { if (id.is_named() && attributes_to_skip.contains(id.name())) { return true; } bke::GSpanAttributeWriter attribute = attributes.lookup_for_write_span(id); - /* The new elements are added at the end of the array. */ - const int old_elements_num = attribute.domain == ATTR_DOMAIN_POINT ? old_points_num : - old_curves_num; const CPPType &type = attribute.span.type(); - GMutableSpan new_data = attribute.span.drop_front(old_elements_num); + GMutableSpan new_data = attribute.span.slice(attribute.domain == ATTR_DOMAIN_POINT ? + outputs.new_points_range : + outputs.new_curves_range); type.fill_assign_n(type.default_value(), new_data.data(), new_data.size()); attribute.finish(); return true; diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc index ae79ce5ee54..48f56eccd47 100644 --- a/source/blender/modifiers/intern/MOD_mask.cc +++ b/source/blender/modifiers/intern/MOD_mask.cc @@ -9,6 +9,7 @@ #include "BLI_utildefines.h" +#include "BLI_array_utils.hh" #include "BLI_ghash.h" #include "BLI_listbase.h" #include "BLI_math.h" @@ -134,13 +135,6 @@ static void compute_vertex_mask__vertex_group_mode(const MDeformVert *dvert, } } -static void invert_boolean_array(MutableSpan array) -{ - for (bool &value : array) { - value = !value; - } -} - static void compute_masked_verts(Span vertex_mask, MutableSpan r_vertex_map, uint *r_verts_masked_num) @@ -685,7 +679,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext * /*ctx*/, M } if (invert_mask) { - invert_boolean_array(vertex_mask); + blender::array_utils::invert_booleans(vertex_mask); } Array vertex_map(mesh->totvert); From 50dbedf0d899378407f52df4c3cd933041914ae9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 4 Jan 2023 15:49:12 +1100 Subject: [PATCH 0385/1522] GHOST/Wayland: add missing call to destroy xdg_output Match logic from SDL. --- intern/ghost/intern/GHOST_SystemWayland.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index efcbc79d5c2..8cd7cde79b9 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -4741,6 +4741,9 @@ static void gwl_registry_wl_output_remove(GWL_Display *display, /* While windows & cursors hold references to outputs, there is no need to manually remove * these references as the compositor will remove references via #wl_surface_listener.leave. */ GWL_Output *output = static_cast(user_data); + if (output->xdg_output) { + zxdg_output_v1_destroy(output->xdg_output); + } wl_output_destroy(output->wl_output); std::vector::iterator iter = std::find( display->outputs.begin(), display->outputs.end(), output); From cbd12e730af55d16dfcf3c9aa8ff5f3e6bc8d0ec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 4 Jan 2023 15:57:38 +1100 Subject: [PATCH 0386/1522] Fix T103586: Crash removing monitor under Wayland & WLROOTS compositors WLROOTS compositors don't run surface leave callbacks, while this may be considered a bug in WLROOTS, neither GTK/SDL crash so workaround the crash too. This also fixes a minor glitch where the cursor scale wasn't updated when changing monitor scale at run-time. --- intern/ghost/intern/GHOST_SystemWayland.cpp | 70 ++++++++++++++++----- intern/ghost/intern/GHOST_SystemWayland.h | 2 + 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 8cd7cde79b9..42e56aa74ab 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -4535,18 +4535,7 @@ static void output_handle_scale(void *data, struct wl_output * /*wl_output*/, co CLOG_INFO(LOG, 2, "scale"); GWL_Output *output = static_cast(data); output->scale = factor; - - GHOST_WindowManager *window_manager = output->system->getWindowManager(); - if (window_manager) { - for (GHOST_IWindow *iwin : window_manager->getWindows()) { - GHOST_WindowWayland *win = static_cast(iwin); - const std::vector &outputs = win->outputs(); - if (std::find(outputs.begin(), outputs.end(), output) == outputs.cend()) { - continue; - } - win->outputs_changed_update_scale(); - } - } + output->system->output_scale_update_maybe_leave(output, false); } static const struct wl_output_listener output_listener = { @@ -4736,11 +4725,21 @@ static void gwl_registry_wl_output_update(GWL_Display *display, } static void gwl_registry_wl_output_remove(GWL_Display *display, void *user_data, - const bool /*on_exit*/) + const bool on_exit) { /* While windows & cursors hold references to outputs, there is no need to manually remove - * these references as the compositor will remove references via #wl_surface_listener.leave. */ + * these references as the compositor will remove references via #wl_surface_listener.leave. + * + * WARNING: this is not the case for WLROOTS based compositors which have a (bug?) + * where surface leave events don't run. So `system->output_leave(..)` is needed + * until the issue is resolved in WLROOTS. */ GWL_Output *output = static_cast(user_data); + + if (!on_exit) { + /* Needed for WLROOTS, does nothing if surface leave callbacks have already run. */ + output->system->output_scale_update_maybe_leave(output, true); + } + if (output->xdg_output) { zxdg_output_v1_destroy(output->xdg_output); } @@ -6765,6 +6764,49 @@ void GHOST_SystemWayland::window_surface_unref(const wl_surface *wl_surface) #undef SURFACE_CLEAR_PTR } +void GHOST_SystemWayland::output_scale_update_maybe_leave(GWL_Output *output, bool leave) +{ + /* Update scale, optionally leaving the outputs beforehand. */ + GHOST_WindowManager *window_manager = output->system->getWindowManager(); + if (window_manager) { + for (GHOST_IWindow *iwin : window_manager->getWindows()) { + GHOST_WindowWayland *win = static_cast(iwin); + const std::vector &outputs = win->outputs(); + bool found = leave ? win->outputs_leave(output) : + !(std::find(outputs.begin(), outputs.end(), output) == outputs.cend()); + if (found) { + win->outputs_changed_update_scale(); + } + } + } + + for (GWL_Seat *seat : display_->seats) { + bool found; + + found = leave ? seat->pointer.outputs.erase(output) : seat->pointer.outputs.count(output); + if (found) { + if (seat->cursor.wl_surface_cursor != nullptr) { + update_cursor_scale( + seat->cursor, seat->system->wl_shm(), &seat->pointer, seat->cursor.wl_surface_cursor); + } + } + + found = leave ? seat->tablet.outputs.erase(output) : seat->tablet.outputs.count(output); + if (found) { + for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->tablet_tools) { + GWL_TabletTool *tablet_tool = static_cast( + zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2)); + if (tablet_tool->wl_surface_cursor != nullptr) { + update_cursor_scale(seat->cursor, + seat->system->wl_shm(), + &seat->pointer, + tablet_tool->wl_surface_cursor); + } + } + } + } +} + bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mode, const GHOST_TGrabCursorMode mode_current, int32_t init_grab_xy[2], diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h index c762b4817c6..c102a3d7a12 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.h +++ b/intern/ghost/intern/GHOST_SystemWayland.h @@ -194,6 +194,8 @@ class GHOST_SystemWayland : public GHOST_System { /** Set this seat to be active. */ void seat_active_set(const struct GWL_Seat *seat); + void output_scale_update_maybe_leave(GWL_Output *output, bool leave); + /** Clear all references to this surface to prevent accessing NULL pointers. */ void window_surface_unref(const wl_surface *wl_surface); From cdd07ddb9319b2760c14d08a3788ae423459899e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 4 Jan 2023 16:06:42 +1100 Subject: [PATCH 0387/1522] Cleanup: move doc-string to header --- intern/ghost/intern/GHOST_WindowWayland.cpp | 3 --- intern/ghost/intern/GHOST_WindowWayland.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index ffbb8370c46..5957e992436 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -1361,9 +1361,6 @@ GHOST_TSuccess GHOST_WindowWayland::notify_size() * Functionality only used for the WAYLAND implementation. * \{ */ -/** - * Return true when the windows scale or DPI changes. - */ bool GHOST_WindowWayland::outputs_changed_update_scale() { #ifdef USE_EVENT_BACKGROUND_THREAD diff --git a/intern/ghost/intern/GHOST_WindowWayland.h b/intern/ghost/intern/GHOST_WindowWayland.h index 528159a26cb..326c1d5e994 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.h +++ b/intern/ghost/intern/GHOST_WindowWayland.h @@ -156,6 +156,9 @@ class GHOST_WindowWayland : public GHOST_Window { bool outputs_enter(GWL_Output *output); bool outputs_leave(GWL_Output *output); + /** + * Return true when the windows scale or DPI changes. + */ bool outputs_changed_update_scale(); #ifdef USE_EVENT_BACKGROUND_THREAD From 77e8e73ed9a16e25eb92c6b549713a723bfa1373 Mon Sep 17 00:00:00 2001 From: Alaska Date: Wed, 4 Jan 2023 20:57:52 +1100 Subject: [PATCH 0388/1522] Fix T103555: File output node saving to the wrong folder Regression in [0], caused by reliance on BLI_join_dirfile adding a trailing slash when an empty file was passed in. [0]: 9f6a045e23cf4ab132ef78eeaf070bd53d0c509f Ref D16888 --- source/blender/compositor/nodes/COM_OutputFileNode.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/blender/compositor/nodes/COM_OutputFileNode.cc b/source/blender/compositor/nodes/COM_OutputFileNode.cc index 50989f73986..e591b4aed9e 100644 --- a/source/blender/compositor/nodes/COM_OutputFileNode.cc +++ b/source/blender/compositor/nodes/COM_OutputFileNode.cc @@ -104,7 +104,13 @@ void OutputFileNode::convert_to_operations(NodeConverter &converter, char path[FILE_MAX]; /* combine file path for the input */ - BLI_path_join(path, FILE_MAX, storage->base_path, sockdata->path); + if (sockdata->path[0]) { + BLI_path_join(path, FILE_MAX, storage->base_path, sockdata->path); + } + else { + BLI_strncpy(path, storage->base_path, FILE_MAX); + BLI_path_slash_ensure(path, FILE_MAX); + } NodeOperation *output_operation = nullptr; From bd2d7a4a815d814d39b770138cd8133f0b089694 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 4 Jan 2023 10:43:31 +0100 Subject: [PATCH 0389/1522] Fix build error in debug mode due to wrong code in assert --- source/blender/functions/FN_lazy_function_execute.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/functions/FN_lazy_function_execute.hh b/source/blender/functions/FN_lazy_function_execute.hh index 1d82ac94ee8..5785fddaa51 100644 --- a/source/blender/functions/FN_lazy_function_execute.hh +++ b/source/blender/functions/FN_lazy_function_execute.hh @@ -95,7 +95,7 @@ inline void execute_lazy_function_eagerly_impl( fn.destruct_storage(context.storage); /* Make sure all outputs have been computed. */ - BLI_assert(!Span(set_outputs).contains(false)); + BLI_assert(!Span(set_outputs).contains(false)); } } // namespace detail From 65d8da97b8b6f24a6503ad7ad74cc4381f5d85b4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 4 Jan 2023 10:26:03 +0100 Subject: [PATCH 0390/1522] Build: clear old linux centos7 cache variables instead of printing them More automatic and convenient to update existing configurations this way. Also move into platform_old_libs_update.cmake where similar logic was put already. --- CMakeLists.txt | 18 --------- build_files/cmake/macros.cmake | 37 ------------------- .../platform/platform_old_libs_update.cmake | 34 +++++++++++++++++ 3 files changed, 34 insertions(+), 55 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index acfab6ffc60..b68fd630748 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2009,24 +2009,6 @@ if(0) print_all_vars() endif() -set(LIBDIR_STALE) - -if(UNIX AND NOT APPLE) - # Only search for the path if it's found on the system. - if(EXISTS "../lib/linux_centos7_x86_64") - set(LIBDIR_STALE "/lib/linux_centos7_x86_64/") - endif() -endif() - -if(LIBDIR_STALE) - print_cached_vars_containing_value( - "${LIBDIR_STALE}" - "\nWARNING: found cached references to old library paths!\n" - "\nIt is *strongly* recommended to reference updated library paths!\n" - ) -endif() -unset(LIBDIR_STALE) - # Should be the last step of configuration. if(POSTCONFIGURE_SCRIPT) include(${POSTCONFIGURE_SCRIPT}) diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index b632cb9c551..9965f892395 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -1209,43 +1209,6 @@ function(print_all_vars) endforeach() endfunction() -# Print a list of all cached variables with values containing `contents`. -function(print_cached_vars_containing_value - contents - msg_header - msg_footer - ) - set(_list_info) - set(_found) - get_cmake_property(_vars VARIABLES) - foreach(_var ${_vars}) - if(DEFINED CACHE{${_var}}) - # Skip "_" prefixed variables, these are used for internal book-keeping, - # not under user control. - string(FIND "${_var}" "_" _found) - if(NOT (_found EQUAL 0)) - string(FIND "${${_var}}" "${contents}" _found) - if(NOT (_found EQUAL -1)) - if(_found) - list(APPEND _list_info "${_var}=${${_var}}") - endif() - endif() - endif() - endif() - endforeach() - unset(_var) - unset(_vars) - unset(_found) - if(_list_info) - message(${msg_header}) - foreach(_var ${_list_info}) - message(" * ${_var}") - endforeach() - message(${msg_footer}) - endif() - unset(_list_info) -endfunction() - macro(openmp_delayload projectname ) diff --git a/build_files/cmake/platform/platform_old_libs_update.cmake b/build_files/cmake/platform/platform_old_libs_update.cmake index c51029ab570..12ab9a44cf1 100644 --- a/build_files/cmake/platform/platform_old_libs_update.cmake +++ b/build_files/cmake/platform/platform_old_libs_update.cmake @@ -3,6 +3,7 @@ # Auto update existing CMake caches for new libraries +# Clear cached variables whose name matches `pattern`. function(unset_cache_variables pattern) get_cmake_property(_cache_variables CACHE_VARIABLES) foreach(_cache_variable ${_cache_variables}) @@ -12,6 +13,30 @@ function(unset_cache_variables pattern) endforeach() endfunction() +# Clear cached variables with values containing `contents`. +function(unset_cached_varables_containting contents msg) + get_cmake_property(_cache_variables CACHE_VARIABLES) + set(_found) + set(_print_msg) + foreach(_cache_variable ${_cache_variables}) + # Skip "_" prefixed variables, these are used for internal book-keeping, + # not under user control. + string(FIND "${_cache_variable}" "_" _found) + if(NOT (_found EQUAL 0)) + string(FIND "${${_cache_variable}}" "${contents}" _found) + if(NOT (_found EQUAL -1)) + if(_found) + unset(${_cache_variable} CACHE) + set(_print_msg ON) + endif() + endif() + endif() + endforeach() + if(_print_msg) + message(STATUS ${msg}) + endif() +endfunction() + # Detect update from 3.1 to 3.2 libs. if(UNIX AND DEFINED OPENEXR_VERSION AND @@ -63,3 +88,12 @@ if(UNIX AND unset_cache_variables("^TBB") unset_cache_variables("^USD") endif() + +if(UNIX AND (NOT APPLE) AND LIBDIR AND (EXISTS ${LIBDIR})) + # Only search for the path if it's found on the system. + set(LIBDIR_STALE "/lib/linux_centos7_x86_64/") + unset_cached_varables_containting( + "${LIBDIR_STALE}" + "Auto clearing old ${LIBDIR_STALE} paths from CMake configuration" + ) +endif() From eb7ac996cc2a00e05aaa5644a684cf32d3f288c7 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 16 Dec 2022 13:55:46 +0100 Subject: [PATCH 0391/1522] Build: install all shared libraries regardless of build options There are dependencies between shared libraries, and Python modules which are always installed on Linux and macOS can use these also. Instead of adding logic for dealing with dependencies and conditional Python module installs, just always install everything when using precompiled libraries. This does not affect compile time which would be the main reason to turn off build options, and it does not affect the case where system libraries are used. --- CMakeLists.txt | 24 +- .../cmake/platform/platform_apple.cmake | 25 +- .../cmake/platform/platform_unix.cmake | 51 +- source/creator/CMakeLists.txt | 479 +++++++++--------- 4 files changed, 253 insertions(+), 326 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b68fd630748..b3e9eb55c15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -832,27 +832,22 @@ endif() # enable boost for cycles, audaspace or i18n # otherwise if the user disabled -set_and_warn_dependency(WITH_BOOST WITH_CYCLES OFF) set_and_warn_dependency(WITH_BOOST WITH_INTERNATIONAL OFF) set_and_warn_dependency(WITH_BOOST WITH_OPENVDB OFF) -set_and_warn_dependency(WITH_BOOST WITH_OPENCOLORIO OFF) set_and_warn_dependency(WITH_BOOST WITH_QUADRIFLOW OFF) set_and_warn_dependency(WITH_BOOST WITH_USD OFF) -set_and_warn_dependency(WITH_BOOST WITH_ALEMBIC OFF) if(WITH_CYCLES) set_and_warn_dependency(WITH_PUGIXML WITH_CYCLES_OSL OFF) endif() -set_and_warn_dependency(WITH_PUGIXML WITH_OPENIMAGEIO OFF) -if(WITH_BOOST AND NOT (WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_INTERNATIONAL OR - WITH_OPENVDB OR WITH_OPENCOLORIO OR WITH_USD OR WITH_ALEMBIC)) +if(WITH_BOOST AND NOT (WITH_INTERNATIONAL OR WITH_OPENVDB OR + WITH_QUADRIFOLOW OR WITH_USD)) message(STATUS "No dependencies need 'WITH_BOOST' forcing WITH_BOOST=OFF") set(WITH_BOOST OFF) endif() set_and_warn_dependency(WITH_TBB WITH_CYCLES OFF) set_and_warn_dependency(WITH_TBB WITH_USD OFF) -set_and_warn_dependency(WITH_TBB WITH_OPENIMAGEDENOISE OFF) set_and_warn_dependency(WITH_TBB WITH_OPENVDB OFF) set_and_warn_dependency(WITH_TBB WITH_MOD_FLUID OFF) @@ -861,14 +856,10 @@ set_and_warn_dependency(WITH_OPENVDB WITH_NANOVDB OFF) # OpenVDB and OpenColorIO uses 'half' type from OpenEXR set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_OPENVDB OFF) -set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_OPENCOLORIO OFF) # Haru needs `TIFFFaxBlackCodes` & `TIFFFaxWhiteCodes` symbols from TIFF. set_and_warn_dependency(WITH_IMAGE_TIFF WITH_HARU OFF) -# USD needs OpenSubDiv, since that is used by the Cycles Hydra render delegate. -set_and_warn_dependency(WITH_OPENSUBDIV WITH_USD OFF) - # auto enable openimageio for cycles if(WITH_CYCLES) set(WITH_OPENIMAGEIO ON) @@ -882,17 +873,6 @@ else() set(WITH_CYCLES_OSL OFF) endif() -# auto enable openimageio linking dependencies -if(WITH_OPENIMAGEIO) - set(WITH_IMAGE_OPENEXR ON) - set(WITH_IMAGE_TIFF ON) -endif() - -# auto enable alembic linking dependencies -if(WITH_ALEMBIC) - set(WITH_IMAGE_OPENEXR ON) -endif() - # don't store paths to libs for portable distribution if(WITH_INSTALL_PORTABLE) set(CMAKE_SKIP_BUILD_RPATH TRUE) diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index b2101662969..e9e07229b2d 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -86,16 +86,14 @@ endif() if(WITH_USD) find_package(USD REQUIRED) - add_bundled_libraries(usd/lib) endif() +add_bundled_libraries(usd/lib) if(WITH_MATERIALX) find_package(MaterialX) set_and_warn_library_found("MaterialX" MaterialX_FOUND WITH_MATERIALX) - if(WITH_MATERIALX) - add_bundled_libraries(materialx/lib) - endif() endif() +add_bundled_libraries(materialx/lib) if(WITH_VULKAN_BACKEND) find_package(MoltenVK REQUIRED) @@ -117,8 +115,8 @@ endif() if(WITH_OPENSUBDIV) find_package(OpenSubdiv) - add_bundled_libraries(opensubdiv/lib) endif() +add_bundled_libraries(opensubdiv/lib) if(WITH_CODEC_SNDFILE) find_package(SndFile) @@ -156,9 +154,9 @@ list(APPEND FREETYPE_LIBRARIES if(WITH_IMAGE_OPENEXR) find_package(OpenEXR) - add_bundled_libraries(openexr/lib) - add_bundled_libraries(imath/lib) endif() +add_bundled_libraries(openexr/lib) +add_bundled_libraries(imath/lib) if(WITH_CODEC_FFMPEG) set(FFMPEG_ROOT_DIR ${LIBDIR}/ffmpeg) @@ -270,12 +268,11 @@ if(WITH_BOOST) set(BOOST_INCLUDE_DIR ${Boost_INCLUDE_DIRS}) set(BOOST_DEFINITIONS) - add_bundled_libraries(boost/lib) - mark_as_advanced(Boost_LIBRARIES) mark_as_advanced(Boost_INCLUDE_DIRS) unset(_boost_FIND_COMPONENTS) endif() +add_bundled_libraries(boost/lib) if(WITH_INTERNATIONAL OR WITH_CODEC_FFMPEG) string(APPEND PLATFORM_LINKFLAGS " -liconv") # boost_locale and ffmpeg needs it ! @@ -297,13 +294,13 @@ if(WITH_OPENIMAGEIO) ) set(OPENIMAGEIO_DEFINITIONS "-DOIIO_STATIC_BUILD") set(OPENIMAGEIO_IDIFF "${LIBDIR}/openimageio/bin/idiff") - add_bundled_libraries(openimageio/lib) endif() +add_bundled_libraries(openimageio/lib) if(WITH_OPENCOLORIO) find_package(OpenColorIO 2.0.0 REQUIRED) - add_bundled_libraries(opencolorio/lib) endif() +add_bundled_libraries(opencolorio/lib) if(WITH_OPENVDB) find_package(OpenVDB) @@ -314,8 +311,8 @@ if(WITH_OPENVDB) unset(BLOSC_LIBRARIES CACHE) endif() set(OPENVDB_DEFINITIONS) - add_bundled_libraries(openvdb/lib) endif() +add_bundled_libraries(openvdb/lib) if(WITH_NANOVDB) find_package(NanoVDB) @@ -363,8 +360,8 @@ endif() if(WITH_TBB) find_package(TBB REQUIRED) - add_bundled_libraries(tbb/lib) endif() +add_bundled_libraries(tbb/lib) if(WITH_POTRACE) find_package(Potrace REQUIRED) @@ -382,9 +379,9 @@ if(WITH_OPENMP) set(OpenMP_LIBRARY_DIR "${LIBDIR}/openmp/lib/") set(OpenMP_LINKER_FLAGS "-L'${OpenMP_LIBRARY_DIR}' -lomp") set(OpenMP_LIBRARY "${OpenMP_LIBRARY_DIR}/libomp.dylib") - add_bundled_libraries(openmp/lib) endif() endif() +add_bundled_libraries(openmp/lib) if(WITH_XR_OPENXR) find_package(XR_OpenXR_SDK REQUIRED) diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index bdf39d04d32..787d0f87002 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -166,11 +166,9 @@ endif() if(WITH_IMAGE_OPENEXR) find_package_wrapper(OpenEXR) # our own module set_and_warn_library_found("OpenEXR" OPENEXR_FOUND WITH_IMAGE_OPENEXR) - if(WITH_IMAGE_OPENEXR) - add_bundled_libraries(openexr/lib) - add_bundled_libraries(imath/lib) - endif() endif() +add_bundled_libraries(openexr/lib) +add_bundled_libraries(imath/lib) if(WITH_IMAGE_OPENJPEG) find_package_wrapper(OpenJPEG) @@ -328,11 +326,8 @@ endif() if(WITH_OPENVDB) find_package(OpenVDB) set_and_warn_library_found("OpenVDB" OPENVDB_FOUND WITH_OPENVDB) - - if(WITH_OPENVDB) - add_bundled_libraries(openvdb/lib) - endif() endif() +add_bundled_libraries(openvdb/lib) if(WITH_NANOVDB) find_package_wrapper(NanoVDB) @@ -351,18 +346,14 @@ endif() if(WITH_USD) find_package_wrapper(USD) set_and_warn_library_found("USD" USD_FOUND WITH_USD) - if(WITH_USD) - add_bundled_libraries(usd/lib) - endif() endif() +add_bundled_libraries(usd/lib) if(WITH_MATERIALX) find_package_wrapper(MaterialX) set_and_warn_library_found("MaterialX" MaterialX_FOUND WITH_MATERIALX) - if(WITH_MATERIALX) - add_bundled_libraries(materialx/lib) - endif() endif() +add_bundled_libraries(materialx/lib) if(WITH_BOOST) # uses in build instructions to override include and library variables @@ -418,9 +409,8 @@ if(WITH_BOOST) find_package(IcuLinux) list(APPEND BOOST_LIBRARIES ${ICU_LIBRARIES}) endif() - - add_bundled_libraries(boost/lib) endif() +add_bundled_libraries(boost/lib) if(WITH_PUGIXML) find_package_wrapper(PugiXML) @@ -455,21 +445,16 @@ if(WITH_OPENIMAGEIO) endif() set_and_warn_library_found("OPENIMAGEIO" OPENIMAGEIO_FOUND WITH_OPENIMAGEIO) - if(WITH_OPENIMAGEIO) - add_bundled_libraries(openimageio/lib) - endif() endif() +add_bundled_libraries(openimageio/lib) if(WITH_OPENCOLORIO) find_package_wrapper(OpenColorIO 2.0.0) set(OPENCOLORIO_DEFINITIONS) set_and_warn_library_found("OpenColorIO" OPENCOLORIO_FOUND WITH_OPENCOLORIO) - - if(WITH_OPENCOLORIO) - add_bundled_libraries(opencolorio/lib) - endif() endif() +add_bundled_libraries(opencolorio/lib) if(WITH_CYCLES AND WITH_CYCLES_EMBREE) find_package(Embree 3.8.0 REQUIRED) @@ -510,18 +495,14 @@ if(WITH_OPENSUBDIV) set(OPENSUBDIV_LIBPATH) # TODO, remove and reference the absolute path everywhere set_and_warn_library_found("OpenSubdiv" OPENSUBDIV_FOUND WITH_OPENSUBDIV) - if(WITH_OPENSUBDIV) - add_bundled_libraries(opensubdiv/lib) - endif() endif() +add_bundled_libraries(opensubdiv/lib) if(WITH_TBB) find_package_wrapper(TBB) set_and_warn_library_found("TBB" TBB_FOUND WITH_TBB) - if(WITH_TBB) - add_bundled_libraries(tbb/lib) - endif() endif() +add_bundled_libraries(tbb/lib) if(WITH_XR_OPENXR) find_package(XR_OpenXR_SDK) @@ -1013,18 +994,6 @@ endfunction() configure_atomic_lib_if_needed() -# Handle library inter-dependencies. -# FIXME: find a better place to handle inter-library dependencies. -# This is done near the end of the file to ensure bundled libraries are not added multiple times. -if(WITH_USD) - if(NOT WITH_OPENIMAGEIO) - add_bundled_libraries(openimageio/lib) - endif() - if(NOT WITH_OPENVDB) - add_bundled_libraries(openvdb/lib) - endif() -endif() - if(PLATFORM_BUNDLED_LIBRARIES) # For the installed Python module and installed Blender executable, we set the # rpath to the relative path where the install step will copy the shared libraries. diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 3570e9e8b4a..1cf908b4821 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -494,27 +494,27 @@ if(WITH_OPENCOLORIO) DIRECTORY ${CMAKE_SOURCE_DIR}/release/datafiles/colormanagement DESTINATION ${TARGETDIR_VER}/datafiles ) - if(WIN32) - if(EXISTS ${LIBDIR}/opencolorio/bin/opencolorio_2_2.dll) # 3.5 - windows_install_shared_manifest( - FILES ${LIBDIR}/opencolorio/bin/opencolorio_2_2.dll - RELEASE - ) - windows_install_shared_manifest( - FILES ${LIBDIR}/opencolorio/bin/opencolorio_d_2_2.dll - DEBUG - ) - install( - FILES ${LIBDIR}/opencolorio/lib/site-packages-debug/PyOpenColorIO_d.pyd - DESTINATION ${TARGETDIR_VER}/python/lib/site-packages - CONFIGURATIONS Debug - ) - install( - FILES ${LIBDIR}/opencolorio/lib/site-packages/PyOpenColorIO.pyd - DESTINATION ${TARGETDIR_VER}/python/lib/site-packages - CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel - ) - endif() +endif() +if(WIN32) + if(EXISTS ${LIBDIR}/opencolorio/bin/opencolorio_2_2.dll) # 3.5 + windows_install_shared_manifest( + FILES ${LIBDIR}/opencolorio/bin/opencolorio_2_2.dll + RELEASE + ) + windows_install_shared_manifest( + FILES ${LIBDIR}/opencolorio/bin/opencolorio_d_2_2.dll + DEBUG + ) + install( + FILES ${LIBDIR}/opencolorio/lib/site-packages-debug/PyOpenColorIO_d.pyd + DESTINATION ${TARGETDIR_VER}/python/lib/site-packages + CONFIGURATIONS Debug + ) + install( + FILES ${LIBDIR}/opencolorio/lib/site-packages/PyOpenColorIO.pyd + DESTINATION ${TARGETDIR_VER}/python/lib/site-packages + CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel + ) endif() endif() @@ -853,12 +853,10 @@ elseif(WIN32) ) endif() - if(WITH_FFTW3) - windows_install_shared_manifest( - FILES ${LIBDIR}/fftw3/lib/libfftw3-3.dll - ALL - ) - endif() + windows_install_shared_manifest( + FILES ${LIBDIR}/fftw3/lib/libfftw3-3.dll + ALL + ) if(MSVC_ASAN) # The ASAN DLL's can be found in the same folder as the compiler, # this is the easiest way to find these. @@ -882,60 +880,54 @@ elseif(WIN32) unset(ASAN_DLL) unset(ASAN_DEBUG_DLL) endif() - if(WITH_IMAGE_OPENEXR OR WITH_OPENIMAGEIO) - if(EXISTS ${LIBDIR}/openexr/bin/Iex.dll) - windows_install_shared_manifest( - FILES - ${LIBDIR}/openexr/bin/Iex.dll - ${LIBDIR}/openexr/bin/IlmThread.dll - ${LIBDIR}/openexr/bin/OpenEXRCore.dll - ${LIBDIR}/openexr/bin/OpenEXRUtil.dll - ${LIBDIR}/openexr/bin/OpenEXR.dll - ${LIBDIR}/imath/bin/imath.dll - RELEASE - ) - windows_install_shared_manifest( - FILES - ${LIBDIR}/openexr/bin/Iex_d.dll - ${LIBDIR}/openexr/bin/IlmThread_d.dll - ${LIBDIR}/openexr/bin/OpenEXRCore_d.dll - ${LIBDIR}/openexr/bin/OpenEXRUtil_d.dll - ${LIBDIR}/openexr/bin/OpenEXR_d.dll - ${LIBDIR}/imath/bin/imath_d.dll - DEBUG - ) - endif() - endif() - if(WITH_OPENIMAGEIO) - if(EXISTS ${LIBDIR}/openimageio/bin/openimageio.dll) - windows_install_shared_manifest( - FILES - ${LIBDIR}/openimageio/bin/openimageio.dll - ${LIBDIR}/openimageio/bin/openimageio_util.dll - RELEASE - ) - windows_install_shared_manifest( - FILES - ${LIBDIR}/openimageio/bin/openimageio_d.dll - ${LIBDIR}/openimageio/bin/openimageio_util_d.dll - DEBUG - ) - endif() - endif() - if(WITH_GMP) + if(EXISTS ${LIBDIR}/openexr/bin/Iex.dll) windows_install_shared_manifest( - FILES ${LIBDIR}/gmp/lib/libgmp-10.dll - ALL - ) - windows_install_shared_manifest( - FILES ${LIBDIR}/gmp/lib/libgmpxx.dll + FILES + ${LIBDIR}/openexr/bin/Iex.dll + ${LIBDIR}/openexr/bin/IlmThread.dll + ${LIBDIR}/openexr/bin/OpenEXRCore.dll + ${LIBDIR}/openexr/bin/OpenEXRUtil.dll + ${LIBDIR}/openexr/bin/OpenEXR.dll + ${LIBDIR}/imath/bin/imath.dll RELEASE ) windows_install_shared_manifest( - FILES ${LIBDIR}/gmp/lib/libgmpxx_d.dll + FILES + ${LIBDIR}/openexr/bin/Iex_d.dll + ${LIBDIR}/openexr/bin/IlmThread_d.dll + ${LIBDIR}/openexr/bin/OpenEXRCore_d.dll + ${LIBDIR}/openexr/bin/OpenEXRUtil_d.dll + ${LIBDIR}/openexr/bin/OpenEXR_d.dll + ${LIBDIR}/imath/bin/imath_d.dll DEBUG ) endif() + if(EXISTS ${LIBDIR}/openimageio/bin/openimageio.dll) + windows_install_shared_manifest( + FILES + ${LIBDIR}/openimageio/bin/openimageio.dll + ${LIBDIR}/openimageio/bin/openimageio_util.dll + RELEASE + ) + windows_install_shared_manifest( + FILES + ${LIBDIR}/openimageio/bin/openimageio_d.dll + ${LIBDIR}/openimageio/bin/openimageio_util_d.dll + DEBUG + ) + endif() + windows_install_shared_manifest( + FILES ${LIBDIR}/gmp/lib/libgmp-10.dll + ALL + ) + windows_install_shared_manifest( + FILES ${LIBDIR}/gmp/lib/libgmpxx.dll + RELEASE + ) + windows_install_shared_manifest( + FILES ${LIBDIR}/gmp/lib/libgmpxx_d.dll + DEBUG + ) if(WITH_WINDOWS_PDB) if(WITH_WINDOWS_STRIPPED_PDB) @@ -952,55 +944,51 @@ elseif(WIN32) endif() endif() - if(WITH_OPENVDB) - windows_install_shared_manifest( - FILES ${LIBDIR}/openvdb/bin/openvdb.dll - RELEASE - ) - windows_install_shared_manifest( - FILES ${LIBDIR}/openvdb/bin/openvdb_d.dll - DEBUG - ) + windows_install_shared_manifest( + FILES ${LIBDIR}/openvdb/bin/openvdb.dll + RELEASE + ) + windows_install_shared_manifest( + FILES ${LIBDIR}/openvdb/bin/openvdb_d.dll + DEBUG + ) - # This will not exist for 3.4 and earlier lib folders - # to ease the transition, support both 3.4 and 3.5 lib - # folders. - if(EXISTS ${LIBDIR}/openvdb/python/pyopenvdb_d.pyd) - install( - FILES ${LIBDIR}/openvdb/python/pyopenvdb_d.pyd - DESTINATION ${TARGETDIR_VER}/python/lib/site-packages - CONFIGURATIONS Debug - ) - install( - FILES ${LIBDIR}/openvdb/python/pyopenvdb.pyd - DESTINATION ${TARGETDIR_VER}/python/lib/site-packages - CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel - ) - endif() + # This will not exist for 3.4 and earlier lib folders + # to ease the transition, support both 3.4 and 3.5 lib + # folders. + if(EXISTS ${LIBDIR}/openvdb/python/pyopenvdb_d.pyd) + install( + FILES ${LIBDIR}/openvdb/python/pyopenvdb_d.pyd + DESTINATION ${TARGETDIR_VER}/python/lib/site-packages + CONFIGURATIONS Debug + ) + install( + FILES ${LIBDIR}/openvdb/python/pyopenvdb.pyd + DESTINATION ${TARGETDIR_VER}/python/lib/site-packages + CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel + ) endif() - if(WITH_MATERIALX) - windows_install_shared_manifest( - FILES - ${LIBDIR}/materialx/bin/MaterialXCore.dll - ${LIBDIR}/materialx/bin/MaterialXFormat.dll - ${LIBDIR}/materialx/bin/MaterialXGenGlsl.dll - ${LIBDIR}/materialx/bin/MaterialXGenMdl.dll - ${LIBDIR}/materialx/bin/MaterialXGenOsl.dll - ${LIBDIR}/materialx/bin/MaterialXGenShader.dll - RELEASE - ) - windows_install_shared_manifest( - FILES - ${LIBDIR}/materialx/bin/MaterialXCore_d.dll - ${LIBDIR}/materialx/bin/MaterialXFormat_d.dll - ${LIBDIR}/materialx/bin/MaterialXGenGlsl_d.dll - ${LIBDIR}/materialx/bin/MaterialXGenMdl_d.dll - ${LIBDIR}/materialx/bin/MaterialXGenOsl_d.dll - ${LIBDIR}/materialx/bin/MaterialXGenShader_d.dll - DEBUG - ) - endif() + windows_install_shared_manifest( + FILES + ${LIBDIR}/materialx/bin/MaterialXCore.dll + ${LIBDIR}/materialx/bin/MaterialXFormat.dll + ${LIBDIR}/materialx/bin/MaterialXGenGlsl.dll + ${LIBDIR}/materialx/bin/MaterialXGenMdl.dll + ${LIBDIR}/materialx/bin/MaterialXGenOsl.dll + ${LIBDIR}/materialx/bin/MaterialXGenShader.dll + RELEASE + ) + windows_install_shared_manifest( + FILES + ${LIBDIR}/materialx/bin/MaterialXCore_d.dll + ${LIBDIR}/materialx/bin/MaterialXFormat_d.dll + ${LIBDIR}/materialx/bin/MaterialXGenGlsl_d.dll + ${LIBDIR}/materialx/bin/MaterialXGenMdl_d.dll + ${LIBDIR}/materialx/bin/MaterialXGenOsl_d.dll + ${LIBDIR}/materialx/bin/MaterialXGenShader_d.dll + DEBUG + ) if(WITH_PYTHON) string(REPLACE "." "" _PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION}) @@ -1081,63 +1069,10 @@ elseif(WIN32) DESTINATION ${BLENDER_VERSION}/python/bin CONFIGURATIONS Debug ) - if(WITH_OPENIMAGEIO) - if(EXISTS ${LIBDIR}/openimageio/lib/python${PYTHON_VERSION}/site-packages) #this will only exist for 3.5+ - install( - DIRECTORY ${LIBDIR}/openimageio/lib/python${PYTHON_VERSION}/site-packages/ - DESTINATION ${TARGETDIR_VER}/python/lib/site-packages/ - CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel - PATTERN ".svn" EXCLUDE - PATTERN "__pycache__" EXCLUDE # * any cache * - PATTERN "*.pyc" EXCLUDE # * any cache * - PATTERN "*.pyo" EXCLUDE # * any cache * - ) - endif() - if(EXISTS ${LIBDIR}/openimageio/lib/python${PYTHON_VERSION}_debug/site-packages) - install( - DIRECTORY ${LIBDIR}/openimageio/lib/python${PYTHON_VERSION}_debug/site-packages/ - DESTINATION ${TARGETDIR_VER}/python/lib/site-packages/ - CONFIGURATIONS Debug - PATTERN ".svn" EXCLUDE - PATTERN "__pycache__" EXCLUDE # * any cache * - PATTERN "*.pyc" EXCLUDE # * any cache * - PATTERN "*.pyo" EXCLUDE # * any cache * - ) - endif() - endif() - if(WITH_USD) - # This will not exist for 3.4 and earlier lib folders - # to ease the transition, support both 3.4 and 3.5 lib - # folders. - if(EXISTS ${USD_LIBRARY_DIR}/python/) - install( - DIRECTORY ${USD_LIBRARY_DIR}/python/ - DESTINATION ${TARGETDIR_VER}/python/lib/site-packages - CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel - PATTERN ".svn" EXCLUDE - PATTERN "__pycache__" EXCLUDE # * any cache * - PATTERN "*.pyc" EXCLUDE # * any cache * - PATTERN "*.pyo" EXCLUDE # * any cache * - ) - endif() - if(EXISTS ${USD_LIBRARY_DIR}/debug/python/) - install( - DIRECTORY ${USD_LIBRARY_DIR}/debug/python/ - DESTINATION ${TARGETDIR_VER}/python/lib/site-packages - CONFIGURATIONS Debug - PATTERN ".svn" EXCLUDE - PATTERN "__pycache__" EXCLUDE # * any cache * - PATTERN "*.pyc" EXCLUDE # * any cache * - PATTERN "*.pyo" EXCLUDE # * any cache * - ) - endif() - endif() - if(WITH_MATERIALX) - # MaterialX python bindings - - install( - DIRECTORY ${LIBDIR}/materialx/python/Release/MaterialX + if(EXISTS ${LIBDIR}/openimageio/lib/python${PYTHON_VERSION}/site-packages) #this will only exist for 3.5+ + install( + DIRECTORY ${LIBDIR}/openimageio/lib/python${PYTHON_VERSION}/site-packages/ DESTINATION ${TARGETDIR_VER}/python/lib/site-packages/ CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel PATTERN ".svn" EXCLUDE @@ -1145,8 +1080,10 @@ elseif(WIN32) PATTERN "*.pyc" EXCLUDE # * any cache * PATTERN "*.pyo" EXCLUDE # * any cache * ) + endif() + if(EXISTS ${LIBDIR}/openimageio/lib/python${PYTHON_VERSION}_debug/site-packages) install( - DIRECTORY ${LIBDIR}/materialx/python/Debug/MaterialX + DIRECTORY ${LIBDIR}/openimageio/lib/python${PYTHON_VERSION}_debug/site-packages/ DESTINATION ${TARGETDIR_VER}/python/lib/site-packages/ CONFIGURATIONS Debug PATTERN ".svn" EXCLUDE @@ -1156,6 +1093,52 @@ elseif(WIN32) ) endif() + # This will not exist for 3.4 and earlier lib folders + # to ease the transition, support both 3.4 and 3.5 lib + # folders. + if(EXISTS ${USD_LIBRARY_DIR}/python/) + install( + DIRECTORY ${USD_LIBRARY_DIR}/python/ + DESTINATION ${TARGETDIR_VER}/python/lib/site-packages + CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel + PATTERN ".svn" EXCLUDE + PATTERN "__pycache__" EXCLUDE # * any cache * + PATTERN "*.pyc" EXCLUDE # * any cache * + PATTERN "*.pyo" EXCLUDE # * any cache * + ) + endif() + if(EXISTS ${USD_LIBRARY_DIR}/debug/python/) + install( + DIRECTORY ${USD_LIBRARY_DIR}/debug/python/ + DESTINATION ${TARGETDIR_VER}/python/lib/site-packages + CONFIGURATIONS Debug + PATTERN ".svn" EXCLUDE + PATTERN "__pycache__" EXCLUDE # * any cache * + PATTERN "*.pyc" EXCLUDE # * any cache * + PATTERN "*.pyo" EXCLUDE # * any cache * + ) + endif() + + # MaterialX python bindings + install( + DIRECTORY ${LIBDIR}/materialx/python/Release/MaterialX + DESTINATION ${TARGETDIR_VER}/python/lib/site-packages/ + CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel + PATTERN ".svn" EXCLUDE + PATTERN "__pycache__" EXCLUDE # * any cache * + PATTERN "*.pyc" EXCLUDE # * any cache * + PATTERN "*.pyo" EXCLUDE # * any cache * + ) + install( + DIRECTORY ${LIBDIR}/materialx/python/Debug/MaterialX + DESTINATION ${TARGETDIR_VER}/python/lib/site-packages/ + CONFIGURATIONS Debug + PATTERN ".svn" EXCLUDE + PATTERN "__pycache__" EXCLUDE # * any cache * + PATTERN "*.pyc" EXCLUDE # * any cache * + PATTERN "*.pyo" EXCLUDE # * any cache * + ) + if(WINDOWS_PYTHON_DEBUG) install( FILES @@ -1175,45 +1158,41 @@ elseif(WIN32) endif() - if(WITH_CODEC_FFMPEG) - # Filenames change slightly between FFMPEG versions check both 5.0 and fallback to 4.4 - # to ease the transition between versions. - if(EXISTS "${LIBDIR}/ffmpeg/lib/avcodec-59.dll") - windows_install_shared_manifest( - FILES - ${LIBDIR}/ffmpeg/lib/avcodec-59.dll - ${LIBDIR}/ffmpeg/lib/avformat-59.dll - ${LIBDIR}/ffmpeg/lib/avdevice-59.dll - ${LIBDIR}/ffmpeg/lib/avutil-57.dll - ${LIBDIR}/ffmpeg/lib/swscale-6.dll - ${LIBDIR}/ffmpeg/lib/swresample-4.dll - ALL - ) - else() - windows_install_shared_manifest( - FILES - ${LIBDIR}/ffmpeg/lib/avcodec-58.dll - ${LIBDIR}/ffmpeg/lib/avformat-58.dll - ${LIBDIR}/ffmpeg/lib/avdevice-58.dll - ${LIBDIR}/ffmpeg/lib/avutil-56.dll - ${LIBDIR}/ffmpeg/lib/swscale-5.dll - ${LIBDIR}/ffmpeg/lib/swresample-3.dll - ALL - ) - endif() - endif() - if(WITH_TBB) + # Filenames change slightly between FFMPEG versions check both 5.0 and fallback to 4.4 + # to ease the transition between versions. + if(EXISTS "${LIBDIR}/ffmpeg/lib/avcodec-59.dll") windows_install_shared_manifest( FILES - ${LIBDIR}/tbb/bin/tbb.dll - RELEASE + ${LIBDIR}/ffmpeg/lib/avcodec-59.dll + ${LIBDIR}/ffmpeg/lib/avformat-59.dll + ${LIBDIR}/ffmpeg/lib/avdevice-59.dll + ${LIBDIR}/ffmpeg/lib/avutil-57.dll + ${LIBDIR}/ffmpeg/lib/swscale-6.dll + ${LIBDIR}/ffmpeg/lib/swresample-4.dll + ALL ) + else() windows_install_shared_manifest( FILES - ${LIBDIR}/tbb/bin/tbb_debug.dll - DEBUG + ${LIBDIR}/ffmpeg/lib/avcodec-58.dll + ${LIBDIR}/ffmpeg/lib/avformat-58.dll + ${LIBDIR}/ffmpeg/lib/avdevice-58.dll + ${LIBDIR}/ffmpeg/lib/avutil-56.dll + ${LIBDIR}/ffmpeg/lib/swscale-5.dll + ${LIBDIR}/ffmpeg/lib/swresample-3.dll + ALL ) endif() + windows_install_shared_manifest( + FILES + ${LIBDIR}/tbb/bin/tbb.dll + RELEASE + ) + windows_install_shared_manifest( + FILES + ${LIBDIR}/tbb/bin/tbb_debug.dll + DEBUG + ) if(WITH_TBB_MALLOC_PROXY) windows_install_shared_manifest( FILES @@ -1230,27 +1209,21 @@ elseif(WIN32) list(APPEND LIB ${TBB_MALLOC_LIBRARIES}) endif() - if(WITH_CODEC_SNDFILE) - windows_install_shared_manifest( - FILES ${LIBDIR}/sndfile/lib/libsndfile-1.dll - ALL - ) - endif() + windows_install_shared_manifest( + FILES ${LIBDIR}/sndfile/lib/libsndfile-1.dll + ALL + ) - if(WITH_OPENAL) - windows_install_shared_manifest( - FILES - ${LIBDIR}/openal/lib/OpenAL32.dll - ALL - ) - endif() + windows_install_shared_manifest( + FILES + ${LIBDIR}/openal/lib/OpenAL32.dll + ALL + ) - if(WITH_SDL) - windows_install_shared_manifest( - FILES ${LIBDIR}/sdl/lib/SDL2.dll - ALL - ) - endif() + windows_install_shared_manifest( + FILES ${LIBDIR}/sdl/lib/SDL2.dll + ALL + ) if(WITH_SYSTEM_AUDASPACE) install( @@ -1522,30 +1495,36 @@ blender_target_include_dirs(blender ${INC}) if(WITH_USD) add_definitions(-DWITH_USD) absolute_include_dirs(../blender/io/usd) +endif() +# Always install USD shared library and datafiles regardless if Blender +# itself uses them, the bundled Python module still needs it. +if(LIBDIR AND TARGETDIR_LIB) # On windows the usd library sits in ./blender.shared copy the files # relative to the location of the USD dll, if the dll does not exist # assume we are linking against the static 3.5 lib. - if(WIN32 AND - ( - EXISTS ${LIBDIR}/usd/lib/usd_usd_ms.dll OR # USD 22.03 - EXISTS ${LIBDIR}/usd/lib/usd_ms.dll # USD 22.11 + if(WITH_USD) + if(WIN32 AND + ( + EXISTS ${LIBDIR}/usd/lib/usd_usd_ms.dll OR # USD 22.03 + EXISTS ${LIBDIR}/usd/lib/usd_ms.dll # USD 22.11 + ) ) - ) - install(DIRECTORY - ${USD_LIBRARY_DIR}/usd - DESTINATION "./blender.shared" - ) - elseif(USD_PYTHON_SUPPORT) - install(DIRECTORY - ${USD_LIBRARY_DIR}/usd - DESTINATION ${TARGETDIR_LIB} - ) - else() - install(DIRECTORY - ${USD_LIBRARY_DIR}/usd - DESTINATION "${TARGETDIR_VER}/datafiles" - ) + install(DIRECTORY + ${USD_LIBRARY_DIR}/usd + DESTINATION "./blender.shared" + ) + elseif(USD_PYTHON_SUPPORT) + install(DIRECTORY + ${USD_LIBRARY_DIR}/usd + DESTINATION ${TARGETDIR_LIB} + ) + else() + install(DIRECTORY + ${USD_LIBRARY_DIR}/usd + DESTINATION "${TARGETDIR_VER}/datafiles" + ) + endif() endif() if(WIN32) # If this file exists we are building against a 3.5 22.03 library folder @@ -1575,14 +1554,16 @@ if(WITH_USD) endif() endif() -if(WITH_MATERIALX AND TARGETDIR_LIB) +# Always install MaterialX files regardless if Blender itself uses them, the +# bundled Python module still needs it. +if(WITH_MATERIALX AND LIBDIR AND TARGETDIR_LIB) install( DIRECTORY ${LIBDIR}/materialx/libraries DESTINATION "${TARGETDIR_LIB}/materialx" ) endif() -if(WIN32 AND WITH_BOOST) +if(WIN32) set(BOOST_COMPONENTS atomic chrono date_time filesystem iostreams locale program_options regex serialization system thread wave wserialization From 32b861b14ac6e22ff93dec80ba6b4dd86d2c0611 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 20 Dec 2022 02:57:02 +0100 Subject: [PATCH 0392/1522] Cleanup: fix deprecation warnings after OpenImageIO upgrade --- intern/cycles/scene/image_oiio.cpp | 8 ++++++-- intern/cycles/session/denoising.cpp | 9 ++++++--- intern/cycles/session/merge.cpp | 5 +++-- intern/cycles/session/tile.cpp | 3 ++- source/blender/imbuf/intern/oiio/openimageio_api.cpp | 12 ++++++++++-- 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/intern/cycles/scene/image_oiio.cpp b/intern/cycles/scene/image_oiio.cpp index 5790c179d77..d0adef912be 100644 --- a/intern/cycles/scene/image_oiio.cpp +++ b/intern/cycles/scene/image_oiio.cpp @@ -113,14 +113,18 @@ static void oiio_load_pixels(const ImageMetaData &metadata, if (depth <= 1) { size_t scanlinesize = width * components * sizeof(StorageType); - in->read_image(FileFormat, + in->read_image(0, + 0, + 0, + components, + FileFormat, (uchar *)readpixels + (height - 1) * scanlinesize, AutoStride, -scanlinesize, AutoStride); } else { - in->read_image(FileFormat, (uchar *)readpixels); + in->read_image(0, 0, 0, components, FileFormat, (uchar *)readpixels); } if (components > 4) { diff --git a/intern/cycles/session/denoising.cpp b/intern/cycles/session/denoising.cpp index a9377d412e8..5086aa896d1 100644 --- a/intern/cycles/session/denoising.cpp +++ b/intern/cycles/session/denoising.cpp @@ -439,9 +439,12 @@ bool DenoiseImage::read_previous_pixels(const DenoiseImageLayer &layer, { /* Load pixels from neighboring frames, and copy them into device buffer * with channels reshuffled. */ - size_t num_pixels = (size_t)width * (size_t)height; + const size_t num_pixels = (size_t)width * (size_t)height; + const int num_channels = in_previous->spec().nchannels; + array neighbor_pixels(num_pixels * num_channels); - if (!in_previous->read_image(TypeDesc::FLOAT, neighbor_pixels.data())) { + + if (!in_previous->read_image(0, 0, 0, num_channels, TypeDesc::FLOAT, neighbor_pixels.data())) { return false; } @@ -491,7 +494,7 @@ bool DenoiseImage::load(const string &in_filepath, string &error) /* Read all channels into buffer. Reading all channels at once is faster * than individually due to interleaved EXR channel storage. */ - if (!in->read_image(TypeDesc::FLOAT, pixels.data())) { + if (!in->read_image(0, 0, 0, num_channels, TypeDesc::FLOAT, pixels.data())) { error = "Failed to read image: " + in_filepath; return false; } diff --git a/intern/cycles/session/merge.cpp b/intern/cycles/session/merge.cpp index 316f56630d6..e8e1dd62b4a 100644 --- a/intern/cycles/session/merge.cpp +++ b/intern/cycles/session/merge.cpp @@ -401,8 +401,8 @@ static bool merge_pixels(const vector &images, * faster than individually due to interleaved EXR channel storage. */ array pixels; alloc_pixels(image.in->spec(), pixels); - - if (!image.in->read_image(TypeDesc::FLOAT, pixels.data())) { + const int num_channels = image.in->spec().nchannels; + if (!image.in->read_image(0, 0, 0, num_channels, TypeDesc::FLOAT, pixels.data())) { error = "Failed to read image: " + image.filepath; return false; } @@ -538,6 +538,7 @@ static void read_layer_samples(vector &images, /* Load the "Debug Sample Count" pass and add the samples to the layer's sample count. */ array sample_count_buffer; sample_count_buffer.resize(in_spec.width * in_spec.height); + image.in->read_image(0, 0, layer.sample_pass_offset, diff --git a/intern/cycles/session/tile.cpp b/intern/cycles/session/tile.cpp index 071c72a2c17..ab858e6f192 100644 --- a/intern/cycles/session/tile.cpp +++ b/intern/cycles/session/tile.cpp @@ -646,7 +646,8 @@ bool TileManager::read_full_buffer_from_disk(const string_view filename, return false; } - if (!in->read_image(TypeDesc::FLOAT, buffers->buffer.data())) { + const int num_channels = in->spec().nchannels; + if (!in->read_image(0, 0, 0, num_channels, TypeDesc::FLOAT, buffers->buffer.data())) { LOG(ERROR) << "Error reading pixels from the tile file " << in->geterror(); return false; } diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.cpp b/source/blender/imbuf/intern/oiio/openimageio_api.cpp index f8d00b5222f..7ed084b7144 100644 --- a/source/blender/imbuf/intern/oiio/openimageio_api.cpp +++ b/source/blender/imbuf/intern/oiio/openimageio_api.cpp @@ -73,7 +73,11 @@ static ImBuf *imb_oiio_load_image( ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, flags | IB_rect); try { - if (!in->read_image(TypeDesc::UINT8, + if (!in->read_image(0, + 0, + 0, + components, + TypeDesc::UINT8, (uchar *)ibuf->rect + (height - 1) * scanlinesize, AutoStride, -scanlinesize, @@ -113,7 +117,11 @@ static ImBuf *imb_oiio_load_image_float( ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, flags | IB_rectfloat); try { - if (!in->read_image(TypeDesc::FLOAT, + if (!in->read_image(0, + 0, + 0, + components, + TypeDesc::FLOAT, (uchar *)ibuf->rect_float + (height - 1) * scanlinesize, AutoStride, -scanlinesize, From d28588f31e5881d7bc5ea22bb629baa9448e936d Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 20 Dec 2022 03:03:14 +0100 Subject: [PATCH 0393/1522] Cleanup: compiler warning on Arm with sse2neon Reorder includes to avoid BLI_simd.h redefining SSE2NEON_PRECISE macros. --- intern/cycles/blender/display_driver.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/intern/cycles/blender/display_driver.cpp b/intern/cycles/blender/display_driver.cpp index 60dd5e2c1d2..58f179d1824 100644 --- a/intern/cycles/blender/display_driver.cpp +++ b/intern/cycles/blender/display_driver.cpp @@ -1,12 +1,6 @@ /* SPDX-License-Identifier: Apache-2.0 * Copyright 2021-2022 Blender Foundation */ -#include "blender/display_driver.h" - -#include "device/device.h" -#include "util/log.h" -#include "util/math.h" - #include "GPU_context.h" #include "GPU_immediate.h" #include "GPU_shader.h" @@ -15,6 +9,12 @@ #include "RE_engine.h" +#include "blender/display_driver.h" + +#include "device/device.h" +#include "util/log.h" +#include "util/math.h" + CCL_NAMESPACE_BEGIN /* -------------------------------------------------------------------- From f9ddfffd6f323f67066e325205cf16df1a92569c Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 4 Jan 2023 10:37:58 +0100 Subject: [PATCH 0394/1522] Cleanup: compiler warnings --- build_files/cmake/platform/platform_old_libs_update.cmake | 7 ++++--- .../nodes/geometry/nodes/node_geo_blur_attribute.cc | 2 +- .../geometry/nodes/node_geo_curve_endpoint_selection.cc | 2 +- .../nodes/node_geo_curve_topology_points_of_curve.cc | 2 +- .../geometry/nodes/node_geo_edge_paths_to_selection.cc | 2 +- .../nodes/geometry/nodes/node_geo_input_curve_handles.cc | 2 +- .../geometry/nodes/node_geo_input_mesh_face_is_planar.cc | 2 +- .../geometry/nodes/node_geo_input_shortest_edge_paths.cc | 2 +- .../nodes/geometry/nodes/node_geo_interpolate_domain.cc | 2 +- .../geometry/nodes/node_geo_mesh_face_set_boundaries.cc | 2 +- .../nodes/node_geo_mesh_topology_corners_of_face.cc | 2 +- .../nodes/node_geo_mesh_topology_corners_of_vertex.cc | 2 +- .../nodes/node_geo_mesh_topology_edges_of_vertex.cc | 2 +- .../nodes/node_geo_mesh_topology_offset_corner_in_face.cc | 2 +- .../nodes/geometry/nodes/node_geo_offset_point_in_curve.cc | 4 ++-- .../nodes/geometry/nodes/node_geo_uv_pack_islands.cc | 2 +- source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc | 2 +- 17 files changed, 21 insertions(+), 20 deletions(-) diff --git a/build_files/cmake/platform/platform_old_libs_update.cmake b/build_files/cmake/platform/platform_old_libs_update.cmake index 12ab9a44cf1..ab27dd89385 100644 --- a/build_files/cmake/platform/platform_old_libs_update.cmake +++ b/build_files/cmake/platform/platform_old_libs_update.cmake @@ -91,9 +91,10 @@ endif() if(UNIX AND (NOT APPLE) AND LIBDIR AND (EXISTS ${LIBDIR})) # Only search for the path if it's found on the system. - set(LIBDIR_STALE "/lib/linux_centos7_x86_64/") + set(_libdir_stale "/lib/linux_centos7_x86_64/") unset_cached_varables_containting( - "${LIBDIR_STALE}" - "Auto clearing old ${LIBDIR_STALE} paths from CMake configuration" + "${_libdir_stale}" + "Auto clearing old ${_libdir_stale} paths from CMake configuration" ) + unset(_libdir_stale) endif() diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc index 174c6c8c509..891ac2614ef 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc @@ -440,7 +440,7 @@ class BlurAttributeFieldInput final : public bke::GeometryFieldInput { return GVArray::ForGArray(std::move(main_buffer)); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { weight_field_.node().for_each_field_input_recursive(fn); value_field_.node().for_each_field_input_recursive(fn); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc index 3b48abfbd7d..7eb958fe576 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc @@ -77,7 +77,7 @@ class EndpointFieldInput final : public bke::CurvesFieldInput { return VArray::ForContainer(std::move(selection)); }; - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { start_size_.node().for_each_field_input_recursive(fn); end_size_.node().for_each_field_input_recursive(fn); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc index ceb5c12fe5d..4ffada76497 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc @@ -101,7 +101,7 @@ class PointsOfCurveInput final : public bke::CurvesFieldInput { return VArray::ForContainer(std::move(point_of_curve)); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { curve_index_.node().for_each_field_input_recursive(fn); sort_index_.node().for_each_field_input_recursive(fn); diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc index 5d6d5cb68e5..d9a9b7fdcfe 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_selection.cc @@ -92,7 +92,7 @@ class PathToEdgeSelectionFieldInput final : public bke::MeshFieldInput { VArray::ForContainer(std::move(selection)), ATTR_DOMAIN_EDGE, domain); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { start_vertices_.node().for_each_field_input_recursive(fn); next_vertex_.node().for_each_field_input_recursive(fn); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc index c3cc07f6edb..05bc57d5ffb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_curve_handles.cc @@ -71,7 +71,7 @@ class HandlePositionFieldInput final : public bke::CurvesFieldInput { VArray::ForContainer(std::move(output)), ATTR_DOMAIN_POINT, domain); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { relative_.node().for_each_field_input_recursive(fn); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc index 859cbf360d4..69b84bcaf45 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc @@ -76,7 +76,7 @@ class PlanarFieldInput final : public bke::MeshFieldInput { VArray::ForFunc(polys.size(), planar_fn), ATTR_DOMAIN_FACE, domain); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { threshold_.node().for_each_field_input_recursive(fn); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc b/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc index d9147d5e3ad..78ec12508b2 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc @@ -129,7 +129,7 @@ class ShortestEdgePathsNextVertFieldInput final : public bke::MeshFieldInput { VArray::ForContainer(std::move(next_index)), ATTR_DOMAIN_POINT, domain); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { end_selection_.node().for_each_field_input_recursive(fn); cost_.node().for_each_field_input_recursive(fn); diff --git a/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc b/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc index df8b2bbd922..671bf71edf1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc @@ -112,7 +112,7 @@ class InterpolateDomain final : public bke::GeometryFieldInput { GVArray::ForGArray(std::move(values)), src_domain_, context.domain()); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { src_field_.node().for_each_field_input_recursive(fn); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc index 23d95e87bae..aedd77b0653 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc @@ -66,7 +66,7 @@ class BoundaryFieldInput final : public bke::MeshFieldInput { VArray::ForContainer(std::move(boundary)), ATTR_DOMAIN_EDGE, domain); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { face_set_.node().for_each_field_input_recursive(fn); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc index 89374ccecb4..d5b4b4869c1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc @@ -105,7 +105,7 @@ class CornersOfFaceInput final : public bke::MeshFieldInput { return VArray::ForContainer(std::move(corner_of_face)); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { face_index_.node().for_each_field_input_recursive(fn); sort_index_.node().for_each_field_input_recursive(fn); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc index 43b26785ec7..12310d6df15 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc @@ -126,7 +126,7 @@ class CornersOfVertInput final : public bke::MeshFieldInput { return VArray::ForContainer(std::move(corner_of_vertex)); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { vert_index_.node().for_each_field_input_recursive(fn); sort_index_.node().for_each_field_input_recursive(fn); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc index 28798484573..b16bbabfe0b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc @@ -126,7 +126,7 @@ class EdgesOfVertInput final : public bke::MeshFieldInput { return VArray::ForContainer(std::move(edge_of_vertex)); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { vert_index_.node().for_each_field_input_recursive(fn); sort_index_.node().for_each_field_input_recursive(fn); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc index a9ead39fdbe..d4e6aa6e4ef 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_offset_corner_in_face.cc @@ -73,7 +73,7 @@ class OffsetCornerInFaceFieldInput final : public bke::MeshFieldInput { return VArray::ForContainer(std::move(offset_corners)); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { corner_index_.node().for_each_field_input_recursive(fn); offset_.node().for_each_field_input_recursive(fn); diff --git a/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc index cd367923254..ff6df94ceba 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc @@ -90,7 +90,7 @@ class ControlPointNeighborFieldInput final : public bke::CurvesFieldInput { return VArray::ForContainer(std::move(output)); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { index_.node().for_each_field_input_recursive(fn); offset_.node().for_each_field_input_recursive(fn); @@ -145,7 +145,7 @@ class OffsetValidFieldInput final : public bke::CurvesFieldInput { return VArray::ForContainer(std::move(output)); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { index_.node().for_each_field_input_recursive(fn); offset_.node().for_each_field_input_recursive(fn); diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc index a0f7f58c03b..04ba2282439 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc @@ -119,7 +119,7 @@ class PackIslandsFieldInput final : public bke::MeshFieldInput { return construct_uv_gvarray(mesh, selection_field_, uv_field_, rotate_, margin_, domain); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { selection_field_.node().for_each_field_input_recursive(fn); uv_field_.node().for_each_field_input_recursive(fn); diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc index 9ababee3f98..8286e04172f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc @@ -161,7 +161,7 @@ class UnwrapFieldInput final : public bke::MeshFieldInput { return construct_uv_gvarray(mesh, selection_, seam_, fill_holes_, margin_, method_, domain); } - void for_each_field_input_recursive(FunctionRef fn) const + void for_each_field_input_recursive(FunctionRef fn) const override { selection_.node().for_each_field_input_recursive(fn); seam_.node().for_each_field_input_recursive(fn); From c9ab76db5c2c57a32a172c72a688de7916eed286 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 4 Jan 2023 12:31:59 +0100 Subject: [PATCH 0395/1522] Cleanup: don't use designated initializers in c++ This is a c++20 feature. --- intern/ghost/intern/GHOST_SystemWayland.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 42e56aa74ab..251466d9501 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -1223,13 +1223,12 @@ static void gwl_registry_entry_update_all(GWL_Display *display, const int interf continue; } - GWL_RegisteryUpdate_Params params = { - .name = reg->name, - .interface_slot = reg->interface_slot, - .version = reg->version, + GWL_RegisteryUpdate_Params params{}; + params.name = reg->name; + params.interface_slot = reg->interface_slot; + params.version = reg->version; + params.user_data = reg->user_data; - .user_data = reg->user_data, - }; handler->update_fn(display, ¶ms); } } @@ -5178,11 +5177,10 @@ static void global_handle_add(void *data, const GWL_RegistryEntry *registry_entry_prev = display->registry_entry; /* The interface name that is ensured not to be freed. */ - GWL_RegisteryAdd_Params params = { - .name = name, - .interface_slot = interface_slot, - .version = version, - }; + GWL_RegisteryAdd_Params params{}; + params.name = name; + params.interface_slot = interface_slot; + params.version = version; handler->add_fn(display, ¶ms); From 86a471efe71a84d807e682445fd73a247f196612 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 4 Jan 2023 12:34:41 +0100 Subject: [PATCH 0396/1522] Fix: field socket not showing as field socket This was a mistake in rB0f8487f640edd754de21cffec2dc6c9a1db7234c. --- source/blender/nodes/NOD_node_declaration.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/nodes/NOD_node_declaration.hh b/source/blender/nodes/NOD_node_declaration.hh index 080f3e5e855..c221c64442d 100644 --- a/source/blender/nodes/NOD_node_declaration.hh +++ b/source/blender/nodes/NOD_node_declaration.hh @@ -544,6 +544,7 @@ typename SocketDeclarationBuilder::Self &SocketDeclarationBuilder< { aal::RelationsInNode &relations = node_decl_builder_->get_anonymous_attribute_relations(); if (decl_->in_out == SOCK_IN) { + this->supports_field(); for (const int input_index : indices) { aal::EvalRelation relation; relation.field_input = index_; @@ -552,6 +553,7 @@ typename SocketDeclarationBuilder::Self &SocketDeclarationBuilder< } } else { + this->field_source(); for (const int output_index : indices) { aal::AvailableRelation relation; relation.field_output = index_; From 1beaec46b8e3fbb2bc6755ebd363637be6f540fe Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 4 Jan 2023 13:12:11 +0100 Subject: [PATCH 0397/1522] Fix: implicit field socket ignored Follow up to rB86a471efe71a84d807e682445fd73a247f196612. --- source/blender/nodes/NOD_node_declaration.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/NOD_node_declaration.hh b/source/blender/nodes/NOD_node_declaration.hh index c221c64442d..8a7606df777 100644 --- a/source/blender/nodes/NOD_node_declaration.hh +++ b/source/blender/nodes/NOD_node_declaration.hh @@ -349,8 +349,8 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder { /** The input is evaluated on a subset of the geometry inputs. */ Self &implicit_field_on(ImplicitInputValueFn fn, const Span input_indices) { - this->implicit_field(fn); this->field_on(input_indices); + this->implicit_field(fn); return *(Self *)this; } From 1c7c1480d1ac55227c7e7d65bc2675956bab3dd3 Mon Sep 17 00:00:00 2001 From: Jake Date: Wed, 4 Jan 2023 13:59:36 +0100 Subject: [PATCH 0398/1522] Fix T92988: keymap item expanding incorrectly "show_expanded" did not dirty the keymap diff cache, leading to old flags being written to the item when another item was edited. Differential Revision: https://developer.blender.org/D13418 --- source/blender/makesrna/intern/rna_wm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index 55ceee55684..f712097bb54 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -2804,6 +2804,7 @@ static void rna_def_keyconfig(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Expanded", "Show key map event and property details in the user interface"); RNA_def_property_ui_icon(prop, ICON_DISCLOSURE_TRI_RIGHT, 1); + RNA_def_property_update(prop, 0, "rna_KeyMapItem_update"); prop = RNA_def_property(srna, "propvalue", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "propvalue"); From 14d7cd46ba60f1f7f08ec3e4af2ecf53bdba5720 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 4 Jan 2023 14:32:29 +0100 Subject: [PATCH 0399/1522] Fix CMake configuration error with Cycles enabled and Boost diabled This is now only an indirect dependency on shared libraries, which means this combination is valid. Also remove mechanism that automatically disabled WITH_BOOST if no libraries are using it, this is no longer really helpful with shared boost libraries. --- CMakeLists.txt | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b3e9eb55c15..76779726e21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -837,15 +837,10 @@ set_and_warn_dependency(WITH_BOOST WITH_OPENVDB OFF) set_and_warn_dependency(WITH_BOOST WITH_QUADRIFLOW OFF) set_and_warn_dependency(WITH_BOOST WITH_USD OFF) if(WITH_CYCLES) + set_and_warn_dependency(WITH_BOOST WITH_CYCLES_OSL OFF) set_and_warn_dependency(WITH_PUGIXML WITH_CYCLES_OSL OFF) endif() -if(WITH_BOOST AND NOT (WITH_INTERNATIONAL OR WITH_OPENVDB OR - WITH_QUADRIFOLOW OR WITH_USD)) - message(STATUS "No dependencies need 'WITH_BOOST' forcing WITH_BOOST=OFF") - set(WITH_BOOST OFF) -endif() - set_and_warn_dependency(WITH_TBB WITH_CYCLES OFF) set_and_warn_dependency(WITH_TBB WITH_USD OFF) set_and_warn_dependency(WITH_TBB WITH_OPENVDB OFF) @@ -1075,14 +1070,6 @@ if(WITH_CYCLES) "Configure OIIO or disable WITH_CYCLES" ) endif() - if(NOT WITH_BOOST) - message( - FATAL_ERROR - "Cycles requires WITH_BOOST, the library may not have been found. " - "Configure BOOST or disable WITH_CYCLES" - ) - endif() - if(WITH_CYCLES_OSL) if(NOT WITH_LLVM) message( From 78f28b55d39288926634d0cc7ceaa005937cc528 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 4 Jan 2023 14:55:21 +0100 Subject: [PATCH 0400/1522] Allocator: improve multi-threaded allocation performance Both, the guarded and lockfree allocator, are keeping track of current and peak memory usage. Even the lockfree allocator used to use a global atomic variable for the memory usage. When multiple threads use the allocator at the same time, this variable is highly contended. This can result in significant slowdowns as presented in D16862. While specific cases could always be optimized by reducing the number of allocations, having this synchronization point in functions used by almost every part of Blender is not great. The solution is use thread-local memory counters which are only added together when the memory usage is actually requested. For more details see in-code comments and D16862. Differential Revision: https://developer.blender.org/D16862 --- intern/guardedalloc/CMakeLists.txt | 1 + intern/guardedalloc/intern/leak_detector.cc | 3 + intern/guardedalloc/intern/mallocn_intern.h | 8 + .../intern/mallocn_lockfree_impl.c | 51 +--- intern/guardedalloc/intern/memory_usage.cc | 258 ++++++++++++++++++ source/blender/makesdna/intern/CMakeLists.txt | 1 + source/blender/makesrna/intern/CMakeLists.txt | 1 + 7 files changed, 287 insertions(+), 36 deletions(-) create mode 100644 intern/guardedalloc/intern/memory_usage.cc diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt index 0d16879adb5..5d766d8543d 100644 --- a/intern/guardedalloc/CMakeLists.txt +++ b/intern/guardedalloc/CMakeLists.txt @@ -20,6 +20,7 @@ set(SRC ./intern/mallocn.c ./intern/mallocn_guarded_impl.c ./intern/mallocn_lockfree_impl.c + ./intern/memory_usage.cc MEM_guardedalloc.h ./intern/mallocn_inline.h diff --git a/intern/guardedalloc/intern/leak_detector.cc b/intern/guardedalloc/intern/leak_detector.cc index 5b565b15920..0213376682b 100644 --- a/intern/guardedalloc/intern/leak_detector.cc +++ b/intern/guardedalloc/intern/leak_detector.cc @@ -53,6 +53,9 @@ class MemLeakPrinter { void MEM_init_memleak_detection() { + /* Calling this ensures that the memory usage counters outlive the memory leak detection. */ + memory_usage_init(); + /** * This variable is constructed when this function is first called. This should happen as soon as * possible when the program starts. diff --git a/intern/guardedalloc/intern/mallocn_intern.h b/intern/guardedalloc/intern/mallocn_intern.h index 1e9883f42c8..c2e9f9117bc 100644 --- a/intern/guardedalloc/intern/mallocn_intern.h +++ b/intern/guardedalloc/intern/mallocn_intern.h @@ -89,6 +89,14 @@ void aligned_free(void *ptr); extern bool leak_detector_has_run; extern char free_after_leak_detection_message[]; +void memory_usage_init(void); +void memory_usage_block_alloc(size_t size); +void memory_usage_block_free(size_t size); +size_t memory_usage_block_num(void); +size_t memory_usage_current(void); +size_t memory_usage_peak(void); +void memory_usage_peak_reset(void); + /* Prototypes for counted allocator functions */ size_t MEM_lockfree_allocN_len(const void *vmemh) ATTR_WARN_UNUSED_RESULT; void MEM_lockfree_freeN(void *vmemh); diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c index 5a969186b19..2c4761c74f0 100644 --- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c +++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c @@ -30,8 +30,6 @@ typedef struct MemHeadAligned { size_t len; } MemHeadAligned; -static unsigned int totblock = 0; -static size_t mem_in_use = 0, peak_mem = 0; static bool malloc_debug_memset = false; static void (*error_callback)(const char *) = NULL; @@ -46,18 +44,6 @@ enum { #define MEMHEAD_IS_ALIGNED(memhead) ((memhead)->len & (size_t)MEMHEAD_ALIGN_FLAG) #define MEMHEAD_LEN(memhead) ((memhead)->len & ~((size_t)(MEMHEAD_ALIGN_FLAG))) -/* Uncomment this to have proper peak counter. */ -#define USE_ATOMIC_MAX - -MEM_INLINE void update_maximum(size_t *maximum_value, size_t value) -{ -#ifdef USE_ATOMIC_MAX - atomic_fetch_and_update_max_z(maximum_value, value); -#else - *maximum_value = value > *maximum_value ? value : *maximum_value; -#endif -} - #ifdef __GNUC__ __attribute__((format(printf, 1, 2))) #endif @@ -103,8 +89,7 @@ void MEM_lockfree_freeN(void *vmemh) MemHead *memh = MEMHEAD_FROM_PTR(vmemh); size_t len = MEMHEAD_LEN(memh); - atomic_sub_and_fetch_u(&totblock, 1); - atomic_sub_and_fetch_z(&mem_in_use, len); + memory_usage_block_free(len); if (UNLIKELY(malloc_debug_memset && len)) { memset(memh + 1, 255, len); @@ -224,16 +209,14 @@ void *MEM_lockfree_callocN(size_t len, const char *str) if (LIKELY(memh)) { memh->len = len; - atomic_add_and_fetch_u(&totblock, 1); - atomic_add_and_fetch_z(&mem_in_use, len); - update_maximum(&peak_mem, mem_in_use); + memory_usage_block_alloc(len); return PTR_FROM_MEMHEAD(memh); } print_error("Calloc returns null: len=" SIZET_FORMAT " in %s, total %u\n", SIZET_ARG(len), str, - (uint)mem_in_use); + (uint)memory_usage_current()); return NULL; } @@ -247,7 +230,7 @@ void *MEM_lockfree_calloc_arrayN(size_t len, size_t size, const char *str) SIZET_ARG(len), SIZET_ARG(size), str, - (unsigned int)mem_in_use); + (unsigned int)memory_usage_current()); abort(); return NULL; } @@ -269,16 +252,14 @@ void *MEM_lockfree_mallocN(size_t len, const char *str) } memh->len = len; - atomic_add_and_fetch_u(&totblock, 1); - atomic_add_and_fetch_z(&mem_in_use, len); - update_maximum(&peak_mem, mem_in_use); + memory_usage_block_alloc(len); return PTR_FROM_MEMHEAD(memh); } print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n", SIZET_ARG(len), str, - (uint)mem_in_use); + (uint)memory_usage_current()); return NULL; } @@ -292,7 +273,7 @@ void *MEM_lockfree_malloc_arrayN(size_t len, size_t size, const char *str) SIZET_ARG(len), SIZET_ARG(size), str, - (uint)mem_in_use); + (uint)memory_usage_current()); abort(); return NULL; } @@ -340,16 +321,14 @@ void *MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *str memh->len = len | (size_t)MEMHEAD_ALIGN_FLAG; memh->alignment = (short)alignment; - atomic_add_and_fetch_u(&totblock, 1); - atomic_add_and_fetch_z(&mem_in_use, len); - update_maximum(&peak_mem, mem_in_use); + memory_usage_block_alloc(len); return PTR_FROM_MEMHEAD(memh); } print_error("Malloc returns null: len=" SIZET_FORMAT " in %s, total %u\n", SIZET_ARG(len), str, - (uint)mem_in_use); + (uint)memory_usage_current()); return NULL; } @@ -369,8 +348,8 @@ void MEM_lockfree_callbackmemlist(void (*func)(void *)) void MEM_lockfree_printmemlist_stats(void) { - printf("\ntotal memory len: %.3f MB\n", (double)mem_in_use / (double)(1024 * 1024)); - printf("peak memory len: %.3f MB\n", (double)peak_mem / (double)(1024 * 1024)); + printf("\ntotal memory len: %.3f MB\n", (double)memory_usage_current() / (double)(1024 * 1024)); + printf("peak memory len: %.3f MB\n", (double)memory_usage_peak() / (double)(1024 * 1024)); printf( "\nFor more detailed per-block statistics run Blender with memory debugging command line " "argument.\n"); @@ -398,23 +377,23 @@ void MEM_lockfree_set_memory_debug(void) size_t MEM_lockfree_get_memory_in_use(void) { - return mem_in_use; + return memory_usage_current(); } uint MEM_lockfree_get_memory_blocks_in_use(void) { - return totblock; + return (uint)memory_usage_block_num(); } /* dummy */ void MEM_lockfree_reset_peak_memory(void) { - peak_mem = mem_in_use; + memory_usage_peak_reset(); } size_t MEM_lockfree_get_peak_memory(void) { - return peak_mem; + return memory_usage_peak(); } #ifndef NDEBUG diff --git a/intern/guardedalloc/intern/memory_usage.cc b/intern/guardedalloc/intern/memory_usage.cc new file mode 100644 index 00000000000..71987ac38d9 --- /dev/null +++ b/intern/guardedalloc/intern/memory_usage.cc @@ -0,0 +1,258 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" +#include "mallocn_intern.h" + +#include "../../source/blender/blenlib/BLI_strict_flags.h" + +namespace { + +/** + * This is stored per thread. Align to cache line size to avoid false sharing. + */ +struct alignas(64) Local { + /** Helps to find bugs during program shutdown. */ + bool destructed = false; + /** + * This is the first created #Local and on the main thread. When the main local data is + * destructed, we know that Blender is quitting and that we can't rely on thread locals being + * available still. + */ + bool is_main = false; + /** + * Number of bytes. This can be negative when e.g. one thread allocates a lot of memory, and + * another frees it. It has to be an atomic, because it may be accessed by other threads when the + * total memory usage is counted. + */ + std::atomic mem_in_use = 0; + /** + * Number of allocated blocks. Can be negative and is atomic for the same reason as above. + */ + std::atomic blocks_num = 0; + /** + * Amount of memory used when the peak was last updated. This is used so that we don't have to + * update the peak memory usage after every memory allocation. Instead it's only updated when "a + * lot" of new memory has been allocated. This makes the peak memory usage a little bit less + * accurate, but it's still good enough for practical purposes. + */ + std::atomic mem_in_use_during_peak_update = 0; + + Local(); + ~Local(); +}; + +/** + * This is a singleton that stores global data. + */ +struct Global { + /** + * Mutex that protects the vector below. + */ + std::mutex locals_mutex; + /** + * All currently constructed #Local. This must only be accessed when the mutex above is + * locked. Individual threads insert and remove themselves here. + */ + std::vector locals; + /** + * Number of bytes that are not tracked by #Local. This is necessary because when a thread exits, + * its #Local data is freed. The memory counts stored there would be lost. The memory counts may + * be non-zero during thread destruction, if the thread did an unequal amount of allocations and + * frees (which is perfectly valid behavior as long as other threads have the responsibility to + * free any memory that the thread allocated). + * + * To solve this, the memory counts are added to these global counters when the thread + * exists. The global counters are also used when the entire process starts to exit, because the + * #Local data of the main thread is already destructed when the leak detection happens (during + * destruction of static variables which happens after destruction of threadlocals). + */ + std::atomic mem_in_use_outside_locals = 0; + /** + * Number of blocks that are not tracked by #Local, for the same reason as above. + */ + std::atomic blocks_num_outside_locals = 0; + /** + * Peak memory usage since the last reset. + */ + std::atomic peak = 0; +}; + +} // namespace + +/** + * This is true for most of the lifetime of the program. Only when it starts exiting this becomes + * false indicating that global counters should be used for correctness. + */ +static std::atomic use_local_counters = true; +/** + * When a thread allocated this amount of memory, the peak memory usage is updated. An alternative + * would be to update the global peak memory after every allocation, but that would cause much more + * overhead with little benefit. + */ +static constexpr int64_t peak_update_threshold = 1024 * 1024; + +static Global &get_global() +{ + static Global global; + return global; +} + +static Local &get_local_data() +{ + static thread_local Local local; + assert(!local.destructed); + return local; +} + +Local::Local() +{ + Global &global = get_global(); + std::lock_guard lock{global.locals_mutex}; + + if (global.locals.empty()) { + /* This is the first thread creating #Local, it is therefore the main thread because it's + * created through #memory_usage_init. */ + this->is_main = true; + } + /* Register self in the global list. */ + global.locals.push_back(this); +} + +Local::~Local() +{ + Global &global = get_global(); + std::lock_guard lock{global.locals_mutex}; + + /* Unregister self from the global list. */ + global.locals.erase(std::find(global.locals.begin(), global.locals.end(), this)); + /* Don't forget the memory counts stored locally. */ + global.blocks_num_outside_locals.fetch_add(this->blocks_num, std::memory_order_relaxed); + global.mem_in_use_outside_locals.fetch_add(this->mem_in_use, std::memory_order_relaxed); + + if (this->is_main) { + /* The main thread started shutting down. Use global counters from now on to avoid accessing + * threadlocals after they have been destructed. */ + use_local_counters.store(false, std::memory_order_relaxed); + } + /* Helps to detect when thread locals are accidentally accessed after destruction. */ + this->destructed = true; +} + +/** Check if the current memory usage is higher than the peak and update it if yes. */ +static void update_global_peak() +{ + Global &global = get_global(); + /* Update peak. */ + global.peak = std::max(global.peak, memory_usage_current()); + + std::lock_guard lock{global.locals_mutex}; + + for (Local *local : global.locals) { + assert(!local->destructed); + /* Updating this makes sure that the peak is not updated too often, which would degrade + * performance. */ + local->mem_in_use_during_peak_update = local->mem_in_use.load(std::memory_order_relaxed); + } +} + +void memory_usage_init() +{ + /* Makes sure that the static and threadlocal variables on the main thread are initialized. */ + get_local_data(); +} + +void memory_usage_block_alloc(const size_t size) +{ + if (LIKELY(use_local_counters.load(std::memory_order_relaxed))) { + Local &local = get_local_data(); + /* Increase local memory counts. This does not cause thread synchronization in the majority of + * cases, because each thread has these counters on a separate cache line. It may only cause + * synchronization if another thread is computing the total current memory usage at the same + * time, which is very rare compared to doing allocations. */ + local.blocks_num.fetch_add(1, std::memory_order_relaxed); + local.mem_in_use.fetch_add(int64_t(size), std::memory_order_relaxed); + + /* If a certain amount of new memory has been allocated, update the peak. */ + if (local.mem_in_use - local.mem_in_use_during_peak_update > peak_update_threshold) { + update_global_peak(); + } + } + else { + Global &global = get_global(); + /* Increase global memory counts. */ + global.blocks_num_outside_locals.fetch_add(1, std::memory_order_relaxed); + global.mem_in_use_outside_locals.fetch_add(int64_t(size), std::memory_order_relaxed); + } +} + +void memory_usage_block_free(const size_t size) +{ + if (LIKELY(use_local_counters)) { + /* Decrease local memory counts. See comment in #memory_usage_block_alloc for details regarding + * thread synchronization. */ + Local &local = get_local_data(); + local.mem_in_use.fetch_sub(int64_t(size), std::memory_order_relaxed); + local.blocks_num.fetch_sub(1, std::memory_order_relaxed); + } + else { + Global &global = get_global(); + /* Decrease global memory counts. */ + global.blocks_num_outside_locals.fetch_sub(1, std::memory_order_relaxed); + global.mem_in_use_outside_locals.fetch_sub(int64_t(size), std::memory_order_relaxed); + } +} + +size_t memory_usage_block_num() +{ + Global &global = get_global(); + std::lock_guard lock{global.locals_mutex}; + + /* Count the number of active blocks. */ + int64_t blocks_num = global.blocks_num_outside_locals; + for (Local *local : global.locals) { + blocks_num += local->blocks_num; + } + return size_t(blocks_num); +} + +size_t memory_usage_current() +{ + Global &global = get_global(); + std::lock_guard lock{global.locals_mutex}; + + /* Count the memory that's currently in use. */ + int64_t mem_in_use = global.mem_in_use_outside_locals; + for (Local *local : global.locals) { + mem_in_use += local->mem_in_use; + } + return size_t(mem_in_use); +} + +/** + * Get the approximate peak memory usage since the last call to #memory_usage_peak_reset. + * This is approximate, because the peak usage is not updated after every allocation (see + * #peak_update_threshold). + * + * In the worst case, the peak memory usage is underestimated by + * `peak_update_threshold * #threads`. After large allocations (larger than the threshold), the + * peak usage is always updated so those allocations will always be taken into account. + */ +size_t memory_usage_peak() +{ + update_global_peak(); + Global &global = get_global(); + return global.peak; +} + +void memory_usage_peak_reset() +{ + Global &global = get_global(); + global.peak = memory_usage_current(); +} diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt index 2bf83d7abf0..a7164ddc959 100644 --- a/source/blender/makesdna/intern/CMakeLists.txt +++ b/source/blender/makesdna/intern/CMakeLists.txt @@ -55,6 +55,7 @@ set(SRC ../../../../intern/guardedalloc/intern/mallocn.c ../../../../intern/guardedalloc/intern/mallocn_guarded_impl.c ../../../../intern/guardedalloc/intern/mallocn_lockfree_impl.c + ../../../../intern/guardedalloc/intern/memory_usage.cc ${dna_header_include_file} ${dna_header_string_file} ) diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 20439e69f35..87dfb05366c 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -178,6 +178,7 @@ set(SRC ../../../../intern/guardedalloc/intern/mallocn.c ../../../../intern/guardedalloc/intern/mallocn_guarded_impl.c ../../../../intern/guardedalloc/intern/mallocn_lockfree_impl.c + ../../../../intern/guardedalloc/intern/memory_usage.cc # Needed for defaults. ../../../../release/datafiles/userdef/userdef_default.c From 79837c5ed4b57925bf6c6bb9e7c2248f6f52bbb0 Mon Sep 17 00:00:00 2001 From: Sebastian Parborg Date: Wed, 4 Jan 2023 15:23:26 +0100 Subject: [PATCH 0401/1522] Fix building with boost >= 1.81 In boost 1.81 they no longer implicitly include anymore. --- intern/locale/boost_locale_wrapper.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/intern/locale/boost_locale_wrapper.cpp b/intern/locale/boost_locale_wrapper.cpp index fb0e194352a..80e8d89799a 100644 --- a/intern/locale/boost_locale_wrapper.cpp +++ b/intern/locale/boost_locale_wrapper.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include "boost_locale_wrapper.h" From 22fec7b1a4affb2e1261508db54d63b1ffcc37c7 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 4 Jan 2023 11:22:57 -0300 Subject: [PATCH 0402/1522] Remove deprecated and long unused members of struct Light The members `soft`, `bleedbias`, `bleedexp` and `contact_spread` were deprecated in rBd8aaf25c23fa, and are no longer really used. `soft` is only used by Collada as an extra value for exporting and importing Blender files in collada. `bleedexp` and `contact_spread` are only used in versioning to initialize a default value. Reviewed By: brecht, fclem Differential Revision: https://developer.blender.org/D16834 --- source/blender/blenloader/intern/versioning_280.c | 7 ------- source/blender/io/collada/DocumentImporter.cpp | 1 - source/blender/io/collada/LightExporter.cpp | 1 - source/blender/makesdna/DNA_light_defaults.h | 3 --- source/blender/makesdna/DNA_light_types.h | 6 +----- 5 files changed, 1 insertion(+), 17 deletions(-) diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index ffb87949234..09292841e91 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1782,12 +1782,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 280, 1)) { - if (!DNA_struct_elem_find(fd->filesdna, "Lamp", "float", "bleedexp")) { - for (Light *la = bmain->lights.first; la; la = la->id.next) { - la->bleedexp = 2.5f; - } - } - if (!DNA_struct_elem_find(fd->filesdna, "GPUDOFSettings", "float", "ratio")) { for (Camera *ca = bmain->cameras.first; ca; ca = ca->id.next) { ca->gpu_dof.ratio = 1.0f; @@ -1820,7 +1814,6 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) for (Light *la = bmain->lights.first; la; la = la->id.next) { la->contact_dist = 0.2f; la->contact_bias = 0.03f; - la->contact_spread = 0.2f; la->contact_thickness = 0.2f; } } diff --git a/source/blender/io/collada/DocumentImporter.cpp b/source/blender/io/collada/DocumentImporter.cpp index dae1c4ba894..51744953491 100644 --- a/source/blender/io/collada/DocumentImporter.cpp +++ b/source/blender/io/collada/DocumentImporter.cpp @@ -1017,7 +1017,6 @@ bool DocumentImporter::writeLight(const COLLADAFW::Light *light) et->setData("clipsta", &(lamp->clipsta)); et->setData("clipend", &(lamp->clipend)); et->setData("bias", &(lamp->bias)); - et->setData("soft", &(lamp->soft)); et->setData("bufsize", &(lamp->bufsize)); et->setData("buffers", &(lamp->buffers)); et->setData("area_shape", &(lamp->area_shape)); diff --git a/source/blender/io/collada/LightExporter.cpp b/source/blender/io/collada/LightExporter.cpp index 33c041e790f..b5f9b56ba7c 100644 --- a/source/blender/io/collada/LightExporter.cpp +++ b/source/blender/io/collada/LightExporter.cpp @@ -129,7 +129,6 @@ bool LightsExporter::exportBlenderProfile(COLLADASW::Light &cla, Light *la) cla.addExtraTechniqueParameter("blender", "clipsta", la->clipsta); cla.addExtraTechniqueParameter("blender", "clipend", la->clipend); cla.addExtraTechniqueParameter("blender", "bias", la->bias); - cla.addExtraTechniqueParameter("blender", "soft", la->soft); cla.addExtraTechniqueParameter("blender", "bufsize", la->bufsize); cla.addExtraTechniqueParameter("blender", "samp", la->samp); cla.addExtraTechniqueParameter("blender", "buffers", la->buffers); diff --git a/source/blender/makesdna/DNA_light_defaults.h b/source/blender/makesdna/DNA_light_defaults.h index 7b03a51a727..b2cb7cfd686 100644 --- a/source/blender/makesdna/DNA_light_defaults.h +++ b/source/blender/makesdna/DNA_light_defaults.h @@ -28,10 +28,8 @@ .bufsize = 512, \ .clipsta = 0.05f, \ .clipend = 40.0f, \ - .bleedexp = 2.5f, \ .samp = 3, \ .bias = 1.0f, \ - .soft = 3.0f, \ .area_size = 0.25f, \ .area_sizey = 0.25f, \ .area_sizez = 0.25f, \ @@ -47,7 +45,6 @@ .cascade_fade = 0.1f, \ .contact_dist = 0.2f, \ .contact_bias = 0.03f, \ - .contact_spread = 0.2f, \ .contact_thickness = 0.2f, \ .diff_fac = 1.0f, \ .spec_fac = 1.0f, \ diff --git a/source/blender/makesdna/DNA_light_types.h b/source/blender/makesdna/DNA_light_types.h index f1bf0580b94..86042369539 100644 --- a/source/blender/makesdna/DNA_light_types.h +++ b/source/blender/makesdna/DNA_light_types.h @@ -48,9 +48,7 @@ typedef struct Light { float clipsta, clipend; float bias; - float soft; /* DEPRECATED kept for compatibility. */ - float bleedbias; /* DEPRECATED kept for compatibility. */ - float bleedexp; /* DEPRECATED kept for compatibility. */ + char _pad1[4]; short bufsize, samp, buffers, filtertype; char bufflag, buftype; @@ -66,7 +64,6 @@ typedef struct Light { /** Old animation system, deprecated for 2.5. */ struct Ipo *ipo DNA_DEPRECATED; short pr_texture, use_nodes; - char _pad6[4]; /* Eevee */ float cascade_max_dist; @@ -76,7 +73,6 @@ typedef struct Light { float contact_dist; float contact_bias; - float contact_spread; /* DEPRECATED kept for compatibility. */ float contact_thickness; float diff_fac, volume_fac; From 20b2d6fc71803a1b23604a42317fa173b71792e6 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 4 Jan 2023 10:06:10 -0500 Subject: [PATCH 0403/1522] Fix T103624: Last node is skipped for cursor and link picking I wrote the reverse iteration incorrectly in e091291b5b5f525cd8d38898c. --- source/blender/editors/space_node/node_draw.cc | 2 +- source/blender/editors/space_node/node_edit.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 12a1fcdebd0..dfa74f37058 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -2601,7 +2601,7 @@ static const bNode *find_node_under_cursor(SpaceNode &snode, const float2 &curso { /* Check nodes front to back. */ const Span nodes = snode.edittree->all_nodes(); - for (int i = nodes.index_range().last(); i > 0; i--) { + for (int i = nodes.index_range().last(); i >= 0; i--) { if (BLI_rctf_isect_pt(&nodes[i]->runtime->totr, cursor[0], cursor[1])) { return nodes[i]; } diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 7f6a04e4381..fb4173a9b6b 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -1130,7 +1130,7 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode, snode.edittree->ensure_topology_cache(); const Span nodes = snode.edittree->all_nodes(); - for (int i = nodes.index_range().last(); i > 0; i--) { + for (int i = nodes.index_range().last(); i >= 0; i--) { bNode &node = *nodes[i]; BLI_rctf_init_pt_radius(&rect, cursor, size_sock_padded); From fbc2c4c3317da40bc0c540fe31f41fe3f7802e48 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 4 Jan 2023 11:48:52 -0300 Subject: [PATCH 0404/1522] Fix T102853: radius of spot and point lamps shares same value with area lamp size If we change the radius of a point or spot lamp, we also change the area lamp size. As shown in T102853, this is bad for animating the lamp type. The solution is to make the property point to another member of the DNA struct `Light`. Differential Revision: https://developer.blender.org/D16669 --- source/blender/blenkernel/BKE_blender_version.h | 2 +- source/blender/blenkernel/intern/object.cc | 1 + source/blender/blenloader/intern/versioning_300.cc | 8 ++++++++ source/blender/draw/engines/eevee/eevee_lights.c | 4 ++-- source/blender/draw/engines/eevee_next/eevee_light.cc | 2 +- source/blender/draw/engines/overlay/overlay_extra.cc | 4 ++-- source/blender/io/collada/DocumentImporter.cpp | 1 + source/blender/io/collada/LightExporter.cpp | 1 + source/blender/io/usd/intern/usd_reader_light.cc | 4 ++-- source/blender/io/usd/intern/usd_writer_light.cc | 2 +- source/blender/makesdna/DNA_light_types.h | 2 +- source/blender/makesrna/intern/rna_light.c | 2 +- 12 files changed, 22 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index 2ddda93c93b..c95c3a1a934 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,7 +25,7 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 6 +#define BLENDER_FILE_SUBVERSION 7 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 507d8f2a695..0622007d97d 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -2891,6 +2891,7 @@ void BKE_object_obdata_size_init(struct Object *ob, const float size) case OB_LAMP: { Light *lamp = (Light *)ob->data; lamp->dist *= size; + lamp->radius *= size; lamp->area_size *= size; lamp->area_sizey *= size; lamp->area_sizez *= size; diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 4d9bbdfce77..38ecfaf41ea 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -28,6 +28,7 @@ #include "DNA_curves_types.h" #include "DNA_genfile.h" #include "DNA_gpencil_modifier_types.h" +#include "DNA_light_types.h" #include "DNA_lineart_types.h" #include "DNA_listBase.h" #include "DNA_mask_types.h" @@ -3836,6 +3837,13 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } } + + if (!MAIN_VERSION_ATLEAST(bmain, 305, 7)) { + LISTBASE_FOREACH (Light *, light, &bmain->lights) { + light->radius = light->area_size; + } + } + /** * Versioning code until next subversion bump goes here. * diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index f8250f9520d..f1fde3cc22e 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -45,7 +45,7 @@ static void light_shape_parameters_set(EEVEE_Light *evli, const Light *la, const evli->sizey = scale[1] / scale[2]; evli->spotsize = cosf(la->spotsize * 0.5f); evli->spotblend = (1.0f - evli->spotsize) * la->spotblend; - evli->radius = max_ff(0.001f, la->area_size); + evli->radius = max_ff(0.001f, la->radius); } else if (la->type == LA_AREA) { evli->sizex = max_ff(0.003f, la->area_size * scale[0] * 0.5f); @@ -62,7 +62,7 @@ static void light_shape_parameters_set(EEVEE_Light *evli, const Light *la, const evli->radius = max_ff(0.001f, tanf(min_ff(la->sun_angle, DEG2RADF(179.9f)) / 2.0f)); } else { - evli->radius = max_ff(0.001f, la->area_size); + evli->radius = max_ff(0.001f, la->radius); } } diff --git a/source/blender/draw/engines/eevee_next/eevee_light.cc b/source/blender/draw/engines/eevee_next/eevee_light.cc index aa8268dbaa7..1c0e17470d7 100644 --- a/source/blender/draw/engines/eevee_next/eevee_light.cc +++ b/source/blender/draw/engines/eevee_next/eevee_light.cc @@ -178,7 +178,7 @@ void Light::shape_parameters_set(const ::Light *la, const float scale[3]) _area_size_x = tanf(min_ff(la->sun_angle, DEG2RADF(179.9f)) / 2.0f); } else { - _area_size_x = la->area_size; + _area_size_x = la->radius; } _area_size_y = _area_size_x = max_ff(0.001f, _area_size_x); radius_squared = square_f(_area_size_x); diff --git a/source/blender/draw/engines/overlay/overlay_extra.cc b/source/blender/draw/engines/overlay/overlay_extra.cc index 3363a94a38f..9d46a0a274b 100644 --- a/source/blender/draw/engines/overlay/overlay_extra.cc +++ b/source/blender/draw/engines/overlay/overlay_extra.cc @@ -637,7 +637,7 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob) DRW_buffer_add_entry(cb->groundline, instdata.pos); if (la->type == LA_LOCAL) { - instdata.area_size_x = instdata.area_size_y = la->area_size; + instdata.area_size_x = instdata.area_size_y = la->radius; DRW_buffer_add_entry(cb->light_point, color, &instdata); } else if (la->type == LA_SUN) { @@ -661,7 +661,7 @@ void OVERLAY_light_cache_populate(OVERLAY_Data *vedata, Object *ob) instdata.spot_blend = sqrtf((-a - c * a) / (c - c * a)); instdata.spot_cosine = a; /* HACK: We pack the area size in alpha color. This is decoded by the shader. */ - color[3] = -max_ff(la->area_size, FLT_MIN); + color[3] = -max_ff(la->radius, FLT_MIN); DRW_buffer_add_entry(cb->light_spot, color, &instdata); if ((la->mode & LA_SHOW_CONE) && !DRW_state_is_select()) { diff --git a/source/blender/io/collada/DocumentImporter.cpp b/source/blender/io/collada/DocumentImporter.cpp index 51744953491..5c1b9a1a294 100644 --- a/source/blender/io/collada/DocumentImporter.cpp +++ b/source/blender/io/collada/DocumentImporter.cpp @@ -1019,6 +1019,7 @@ bool DocumentImporter::writeLight(const COLLADAFW::Light *light) et->setData("bias", &(lamp->bias)); et->setData("bufsize", &(lamp->bufsize)); et->setData("buffers", &(lamp->buffers)); + et->setData("radius", &(lamp->radius)); et->setData("area_shape", &(lamp->area_shape)); et->setData("area_size", &(lamp->area_size)); et->setData("area_sizey", &(lamp->area_sizey)); diff --git a/source/blender/io/collada/LightExporter.cpp b/source/blender/io/collada/LightExporter.cpp index b5f9b56ba7c..41b18bf2f0b 100644 --- a/source/blender/io/collada/LightExporter.cpp +++ b/source/blender/io/collada/LightExporter.cpp @@ -132,6 +132,7 @@ bool LightsExporter::exportBlenderProfile(COLLADASW::Light &cla, Light *la) cla.addExtraTechniqueParameter("blender", "bufsize", la->bufsize); cla.addExtraTechniqueParameter("blender", "samp", la->samp); cla.addExtraTechniqueParameter("blender", "buffers", la->buffers); + cla.addExtraTechniqueParameter("blender", "radius", la->radius); cla.addExtraTechniqueParameter("blender", "area_shape", la->area_shape); cla.addExtraTechniqueParameter("blender", "area_size", la->area_size); cla.addExtraTechniqueParameter("blender", "area_sizey", la->area_sizey); diff --git a/source/blender/io/usd/intern/usd_reader_light.cc b/source/blender/io/usd/intern/usd_reader_light.cc index 7204ea91896..8c6c950002d 100644 --- a/source/blender/io/usd/intern/usd_reader_light.cc +++ b/source/blender/io/usd/intern/usd_reader_light.cc @@ -175,7 +175,7 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime if (pxr::UsdAttribute radius_attr = sphere_light.GetRadiusAttr()) { float radius = 0.0f; if (radius_attr.Get(&radius, motionSampleTime)) { - blight->area_size = radius; + blight->radius = radius; } } } @@ -192,7 +192,7 @@ void USDLightReader::read_object_data(Main *bmain, const double motionSampleTime if (pxr::UsdAttribute radius_attr = sphere_light.GetRadiusAttr()) { float radius = 0.0f; if (radius_attr.Get(&radius, motionSampleTime)) { - blight->area_size = radius; + blight->radius = radius; } } diff --git a/source/blender/io/usd/intern/usd_writer_light.cc b/source/blender/io/usd/intern/usd_writer_light.cc index 982bc31d767..2f4f103f93d 100644 --- a/source/blender/io/usd/intern/usd_writer_light.cc +++ b/source/blender/io/usd/intern/usd_writer_light.cc @@ -80,7 +80,7 @@ void USDLightWriter::do_write(HierarchyContext &context) break; case LA_LOCAL: { pxr::UsdLuxSphereLight sphere_light = pxr::UsdLuxSphereLight::Define(stage, usd_path); - sphere_light.CreateRadiusAttr().Set(light->area_size, timecode); + sphere_light.CreateRadiusAttr().Set(light->radius, timecode); #if PXR_VERSION >= 2111 usd_light_api = sphere_light.LightAPI(); #else diff --git a/source/blender/makesdna/DNA_light_types.h b/source/blender/makesdna/DNA_light_types.h index 86042369539..9844b0e6106 100644 --- a/source/blender/makesdna/DNA_light_types.h +++ b/source/blender/makesdna/DNA_light_types.h @@ -48,7 +48,7 @@ typedef struct Light { float clipsta, clipend; float bias; - char _pad1[4]; + float radius; short bufsize, samp, buffers, filtertype; char bufflag, buftype; diff --git a/source/blender/makesrna/intern/rna_light.c b/source/blender/makesrna/intern/rna_light.c index 559fc1961a0..f429fd73cdb 100644 --- a/source/blender/makesrna/intern/rna_light.c +++ b/source/blender/makesrna/intern/rna_light.c @@ -336,7 +336,7 @@ static void rna_def_light_shadow(StructRNA *srna, bool sun) RNA_def_property_update(prop, 0, "rna_Light_update"); prop = RNA_def_property(srna, "shadow_soft_size", PROP_FLOAT, PROP_DISTANCE); - RNA_def_property_float_sdna(prop, NULL, "area_size"); + RNA_def_property_float_sdna(prop, NULL, "radius"); RNA_def_property_range(prop, 0.0f, FLT_MAX); RNA_def_property_ui_range(prop, 0, 100, 0.1, 3); RNA_def_property_ui_text( From 77c3e67d3d7d8055619491bf09f0e7626afe33f9 Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Wed, 4 Jan 2023 14:23:33 +0000 Subject: [PATCH 0405/1522] Cycles: Improved render start/stop responsiveness on Metal All kernel specialisation is now performed in the background regardless of kernel type, meaning that the first render will be visible a few seconds sooner. The only exception is during benchmark warm up, in which case we wait for all kernels to be cached. When stopping a render, we call a new `cancel()` method on the device which causes any outstanding compilation work to be cancelled, and we destroy the device in a detached thread so that any stale queued compilations can be safely purged without blocking the UI for longer than necessary. Reviewed By: brecht Differential Revision: https://developer.blender.org/D16371 --- intern/cycles/device/device.h | 11 + intern/cycles/device/metal/device_impl.h | 23 +- intern/cycles/device/metal/device_impl.mm | 220 +++++++++++----- intern/cycles/device/metal/kernel.h | 6 +- intern/cycles/device/metal/kernel.mm | 296 ++++++++++++---------- intern/cycles/device/metal/queue.mm | 12 + intern/cycles/integrator/path_trace.cpp | 3 + intern/cycles/session/session.cpp | 13 + 8 files changed, 390 insertions(+), 194 deletions(-) diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index b9308dc8949..959939ddbb7 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -167,6 +167,17 @@ class Device { return true; } + /* Request cancellation of any long-running work. */ + virtual void cancel() + { + } + + /* Return true if device is ready for rendering, or report status if not. */ + virtual bool is_ready(string &status) const + { + return true; + } + /* GPU device only functions. * These may not be used on CPU or multi-devices. */ diff --git a/intern/cycles/device/metal/device_impl.h b/intern/cycles/device/metal/device_impl.h index e57b8628023..526535ff132 100644 --- a/intern/cycles/device/metal/device_impl.h +++ b/intern/cycles/device/metal/device_impl.h @@ -76,7 +76,20 @@ class MetalDevice : public Device { bool use_metalrt = false; MetalPipelineType kernel_specialization_level = PSO_GENERIC; - std::atomic_bool async_compile_and_load = false; + + int device_id = 0; + + static thread_mutex existing_devices_mutex; + static std::map active_device_ids; + + static bool is_device_cancelled(int device_id); + + static MetalDevice *get_device_by_ID(int device_idID, + thread_scoped_lock &existing_devices_mutex_lock); + + virtual bool is_ready(string &status) const override; + + virtual void cancel() override; virtual BVHLayoutMask get_bvh_layout_mask() const override; @@ -92,14 +105,12 @@ class MetalDevice : public Device { bool use_adaptive_compilation(); + bool make_source_and_check_if_compile_needed(MetalPipelineType pso_type); + void make_source(MetalPipelineType pso_type, const uint kernel_features); virtual bool load_kernels(const uint kernel_features) override; - void reserve_local_memory(const uint kernel_features); - - void init_host_memory(); - void load_texture_info(); void erase_allocation(device_memory &mem); @@ -112,7 +123,7 @@ class MetalDevice : public Device { virtual void optimize_for_scene(Scene *scene) override; - bool compile_and_load(MetalPipelineType pso_type); + static void compile_and_load(int device_id, MetalPipelineType pso_type); /* ------------------------------------------------------------------ */ /* low-level memory management */ diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm index 95935ce2a3a..a6966bf167d 100644 --- a/intern/cycles/device/metal/device_impl.mm +++ b/intern/cycles/device/metal/device_impl.mm @@ -13,10 +13,32 @@ # include "util/path.h" # include "util/time.h" +# include + CCL_NAMESPACE_BEGIN class MetalDevice; +thread_mutex MetalDevice::existing_devices_mutex; +std::map MetalDevice::active_device_ids; + +/* Thread-safe device access for async work. Calling code must pass an appropriatelty scoped lock + * to existing_devices_mutex to safeguard against destruction of the returned instance. */ +MetalDevice *MetalDevice::get_device_by_ID(int ID, thread_scoped_lock &existing_devices_mutex_lock) +{ + auto it = active_device_ids.find(ID); + if (it != active_device_ids.end()) { + return it->second; + } + return nullptr; +} + +bool MetalDevice::is_device_cancelled(int ID) +{ + thread_scoped_lock lock(existing_devices_mutex); + return get_device_by_ID(ID, lock) == nullptr; +} + BVHLayoutMask MetalDevice::get_bvh_layout_mask() const { return use_metalrt ? BVH_LAYOUT_METAL : BVH_LAYOUT_BVH2; @@ -40,6 +62,15 @@ void MetalDevice::set_error(const string &error) MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profiler) : Device(info, stats, profiler), texture_info(this, "texture_info", MEM_GLOBAL) { + { + /* Assign an ID for this device which we can use to query whether async shader compilation + * requests are still relevant. */ + thread_scoped_lock lock(existing_devices_mutex); + static int existing_devices_counter = 1; + device_id = existing_devices_counter++; + active_device_ids[device_id] = this; + } + mtlDevId = info.num; /* select chosen device */ @@ -57,7 +88,6 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile if (@available(macos 11.0, *)) { if ([mtlDevice hasUnifiedMemory]) { default_storage_mode = MTLResourceStorageModeShared; - init_host_memory(); } } @@ -181,6 +211,13 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile MetalDevice::~MetalDevice() { + /* Cancel any async shader compilations that are in flight. */ + cancel(); + + /* This lock safeguards against destruction during use (see other uses of + * existing_devices_mutex). */ + thread_scoped_lock lock(existing_devices_mutex); + for (auto &tex : texture_slot_map) { if (tex) { [tex release]; @@ -326,21 +363,66 @@ bool MetalDevice::load_kernels(const uint _kernel_features) * active, but may still need to be rendered without motion blur if that isn't active as well. */ motion_blur = kernel_features & KERNEL_FEATURE_OBJECT_MOTION; - bool result = compile_and_load(PSO_GENERIC); + /* Only request generic kernels if they aren't cached in memory. */ + if (make_source_and_check_if_compile_needed(PSO_GENERIC)) { + /* If needed, load them asynchronously in order to responsively message progess to the user. */ + int this_device_id = this->device_id; + auto compile_kernels_fn = ^() { + compile_and_load(this_device_id, PSO_GENERIC); + }; - reserve_local_memory(kernel_features); - return result; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), + compile_kernels_fn); + } + + return true; } -bool MetalDevice::compile_and_load(MetalPipelineType pso_type) +bool MetalDevice::make_source_and_check_if_compile_needed(MetalPipelineType pso_type) { - make_source(pso_type, kernel_features); - - if (!MetalDeviceKernels::should_load_kernels(this, pso_type)) { - /* We already have a full set of matching pipelines which are cached or queued. */ - metal_printf("%s kernels already requested\n", kernel_type_as_string(pso_type)); - return true; + if (this->source[pso_type].empty()) { + make_source(pso_type, kernel_features); } + return MetalDeviceKernels::should_load_kernels(this, pso_type); +} + +void MetalDevice::compile_and_load(int device_id, MetalPipelineType pso_type) +{ + /* Thread-safe front-end compilation. Typically the MSL->AIR compilation can take a few seconds, + * so we avoid blocking device teardown if the user cancels a render immediately. + */ + + id mtlDevice; + string source; + MetalGPUVendor device_vendor; + + /* Safely gather any state required for the MSL->AIR compilation. */ + { + thread_scoped_lock lock(existing_devices_mutex); + + /* Check whether the device still exists. */ + MetalDevice *instance = get_device_by_ID(device_id, lock); + if (!instance) { + metal_printf("Ignoring %s compilation request - device no longer exists\n", + kernel_type_as_string(pso_type)); + return; + } + + if (!instance->make_source_and_check_if_compile_needed(pso_type)) { + /* We already have a full set of matching pipelines which are cached or queued. Return early + * to avoid redundant MTLLibrary compilation. */ + metal_printf("Ignoreing %s compilation request - kernels already requested\n", + kernel_type_as_string(pso_type)); + return; + } + + mtlDevice = instance->mtlDevice; + device_vendor = instance->device_vendor; + source = instance->source[pso_type]; + } + + /* Perform the actual compilation using our cached context. The MetalDevice can safely destruct + * in this time. */ MTLCompileOptions *options = [[MTLCompileOptions alloc] init]; @@ -359,20 +441,15 @@ bool MetalDevice::compile_and_load(MetalPipelineType pso_type) if (getenv("CYCLES_METAL_PROFILING") || getenv("CYCLES_METAL_DEBUG")) { path_write_text(path_cache_get(string_printf("%s.metal", kernel_type_as_string(pso_type))), - source[pso_type]); + source); } const double starttime = time_dt(); NSError *error = NULL; - mtlLibrary[pso_type] = [mtlDevice newLibraryWithSource:@(source[pso_type].c_str()) - options:options - error:&error]; - - if (!mtlLibrary[pso_type]) { - NSString *err = [error localizedDescription]; - set_error(string_printf("Failed to compile library:\n%s", [err UTF8String])); - } + id mtlLibrary = [mtlDevice newLibraryWithSource:@(source.c_str()) + options:options + error:&error]; metal_printf("Front-end compilation finished in %.1f seconds (%s)\n", time_dt() - starttime, @@ -380,17 +457,21 @@ bool MetalDevice::compile_and_load(MetalPipelineType pso_type) [options release]; - return MetalDeviceKernels::load(this, pso_type); -} - -void MetalDevice::reserve_local_memory(const uint kernel_features) -{ - /* METAL_WIP - implement this */ -} - -void MetalDevice::init_host_memory() -{ - /* METAL_WIP - implement this */ + /* Save the compiled MTLLibrary and trigger the AIR->PSO builds (if the MetalDevice still + * exists). */ + { + thread_scoped_lock lock(existing_devices_mutex); + if (MetalDevice *instance = get_device_by_ID(device_id, lock)) { + if (mtlLibrary) { + instance->mtlLibrary[pso_type] = mtlLibrary; + MetalDeviceKernels::load(instance, pso_type); + } + else { + NSString *err = [error localizedDescription]; + instance->set_error(string_printf("Failed to compile library:\n%s", [err UTF8String])); + } + } + } } void MetalDevice::load_texture_info() @@ -700,55 +781,74 @@ device_ptr MetalDevice::mem_alloc_sub_ptr(device_memory &mem, size_t offset, siz return 0; } +void MetalDevice::cancel() +{ + /* Remove this device's ID from the list of active devices. Any pending compilation requests + * originating from this session will be cancelled. */ + thread_scoped_lock lock(existing_devices_mutex); + if (device_id) { + active_device_ids.erase(device_id); + device_id = 0; + } +} + +bool MetalDevice::is_ready(string &status) const +{ + int num_loaded = MetalDeviceKernels::get_loaded_kernel_count(this, PSO_GENERIC); + if (num_loaded < DEVICE_KERNEL_NUM) { + status = string_printf("%d / %d render kernels loaded (may take a few minutes the first time)", + num_loaded, + DEVICE_KERNEL_NUM); + return false; + } + metal_printf("MetalDevice::is_ready(...) --> true\n"); + return true; +} + void MetalDevice::optimize_for_scene(Scene *scene) { MetalPipelineType specialization_level = kernel_specialization_level; - if (specialization_level < PSO_SPECIALIZED_INTERSECT) { - return; - } - - /* PSO_SPECIALIZED_INTERSECT kernels are fast to specialize, so we always load them - * synchronously. */ - compile_and_load(PSO_SPECIALIZED_INTERSECT); - - if (specialization_level < PSO_SPECIALIZED_SHADE) { - return; - } if (!scene->params.background) { - /* Don't load PSO_SPECIALIZED_SHADE kernels during viewport rendering as they are slower to - * build. */ - return; + /* In live viewport, don't specialize beyond intersection kernels for responsiveness. */ + specialization_level = (MetalPipelineType)min(specialization_level, PSO_SPECIALIZED_INTERSECT); } - /* PSO_SPECIALIZED_SHADE kernels are slower to specialize, so we load them asynchronously, and - * only if there isn't an existing load in flight. - */ - auto specialize_shade_fn = ^() { - compile_and_load(PSO_SPECIALIZED_SHADE); - async_compile_and_load = false; + /* For responsive rendering, specialize the kernels in the background, and only if there isn't an + * existing "optimize_for_scene" request in flight. */ + int this_device_id = this->device_id; + auto specialize_kernels_fn = ^() { + for (int level = 1; level <= int(specialization_level); level++) { + compile_and_load(this_device_id, MetalPipelineType(level)); + } }; - bool async_specialize_shade = true; + /* In normal use, we always compile the specialized kernels in the background. */ + bool specialize_in_background = true; /* Block if a per-kernel profiling is enabled (ensure steady rendering rate). */ if (getenv("CYCLES_METAL_PROFILING") != nullptr) { - async_specialize_shade = false; + specialize_in_background = false; } - if (async_specialize_shade) { - if (!async_compile_and_load) { - async_compile_and_load = true; + /* Block during benchmark warm-up to ensure kernels are cached prior to the observed run. */ + for (int i = 0; i < *_NSGetArgc(); i++) { + if (!strcmp((*_NSGetArgv())[i], "--warm-up")) { + specialize_in_background = false; + } + } + + if (specialize_in_background) { + if (!MetalDeviceKernels::any_specialization_happening_now()) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), - specialize_shade_fn); + specialize_kernels_fn); } else { - metal_printf( - "Async PSO_SPECIALIZED_SHADE load request already in progress - dropping request\n"); + metal_printf("\"optimize_for_scene\" request already in flight - dropping request\n"); } } else { - specialize_shade_fn(); + specialize_kernels_fn(); } } diff --git a/intern/cycles/device/metal/kernel.h b/intern/cycles/device/metal/kernel.h index 3e88d2daea7..c2b9f073b12 100644 --- a/intern/cycles/device/metal/kernel.h +++ b/intern/cycles/device/metal/kernel.h @@ -64,6 +64,8 @@ struct MetalKernelPipeline { void compile(); + int originating_device_id; + id mtlLibrary = nil; MetalPipelineType pso_type; string source_md5; @@ -94,7 +96,9 @@ struct MetalKernelPipeline { /* Cache of Metal kernels for each DeviceKernel. */ namespace MetalDeviceKernels { -bool should_load_kernels(MetalDevice *device, MetalPipelineType pso_type); +bool any_specialization_happening_now(); +int get_loaded_kernel_count(MetalDevice const *device, MetalPipelineType pso_type); +bool should_load_kernels(MetalDevice const *device, MetalPipelineType pso_type); bool load(MetalDevice *device, MetalPipelineType pso_type); const MetalKernelPipeline *get_best_pipeline(const MetalDevice *device, DeviceKernel kernel); diff --git a/intern/cycles/device/metal/kernel.mm b/intern/cycles/device/metal/kernel.mm index 86e5a78692e..97ac47dbdb8 100644 --- a/intern/cycles/device/metal/kernel.mm +++ b/intern/cycles/device/metal/kernel.mm @@ -86,23 +86,17 @@ struct ShaderCache { void load_kernel(DeviceKernel kernel, MetalDevice *device, MetalPipelineType pso_type); bool should_load_kernel(DeviceKernel device_kernel, - MetalDevice *device, + MetalDevice const *device, MetalPipelineType pso_type); void wait_for_all(); - private: friend ShaderCache *get_shader_cache(id mtlDevice); void compile_thread_func(int thread_index); using PipelineCollection = std::vector>; - struct PipelineRequest { - MetalKernelPipeline *pipeline = nullptr; - std::function completionHandler; - }; - struct OccupancyTuningParameters { int threads_per_threadgroup = 0; int num_threads_per_block = 0; @@ -113,13 +107,15 @@ struct ShaderCache { PipelineCollection pipelines[DEVICE_KERNEL_NUM]; id mtlDevice; - bool running = false; + static bool running; std::condition_variable cond_var; - std::deque request_queue; + std::deque request_queue; std::vector compile_threads; std::atomic_int incomplete_requests = 0; + std::atomic_int incomplete_specialization_requests = 0; }; +bool ShaderCache::running = true; std::mutex g_shaderCacheMutex; std::map, unique_ptr> g_shaderCache; @@ -137,11 +133,25 @@ ShaderCache *get_shader_cache(id mtlDevice) ShaderCache::~ShaderCache() { - metal_printf("ShaderCache shutting down with incomplete_requests = %d\n", - int(incomplete_requests)); - running = false; cond_var.notify_all(); + + int num_incomplete = int(incomplete_requests); + if (num_incomplete) { + /* Shutting down the app with incomplete shader compilation requests. Give 1 second's grace for + * clean shutdown. */ + metal_printf("ShaderCache busy (incomplete_requests = %d)...\n", num_incomplete); + std::this_thread::sleep_for(std::chrono::seconds(1)); + num_incomplete = int(incomplete_requests); + } + + if (num_incomplete) { + metal_printf("ShaderCache still busy (incomplete_requests = %d). Terminating...\n", + num_incomplete); + std::terminate(); + } + + metal_printf("ShaderCache idle. Shutting down.\n"); for (auto &thread : compile_threads) { thread.join(); } @@ -156,35 +166,69 @@ void ShaderCache::wait_for_all() void ShaderCache::compile_thread_func(int thread_index) { - while (1) { + while (running) { /* wait for / acquire next request */ - PipelineRequest request; + MetalKernelPipeline *pipeline; { thread_scoped_lock lock(cache_mutex); cond_var.wait(lock, [&] { return !running || !request_queue.empty(); }); - if (!running) { - break; + if (!running || request_queue.empty()) { + continue; } - if (!request_queue.empty()) { - request = request_queue.front(); - request_queue.pop_front(); - } + pipeline = request_queue.front(); + request_queue.pop_front(); } - /* service request */ - if (request.pipeline) { - request.pipeline->compile(); - incomplete_requests--; + /* Service the request. */ + DeviceKernel device_kernel = pipeline->device_kernel; + MetalPipelineType pso_type = pipeline->pso_type; + + if (MetalDevice::is_device_cancelled(pipeline->originating_device_id)) { + /* The originating MetalDevice is no longer active, so this request is obsolete. */ + metal_printf("Cancelling compilation of %s (%s)\n", + device_kernel_as_string(device_kernel), + kernel_type_as_string(pso_type)); + } + else { + /* Do the actual compilation. */ + pipeline->compile(); + + thread_scoped_lock lock(cache_mutex); + auto &collection = pipelines[device_kernel]; + + /* Cache up to 3 kernel variants with the same pso_type in memory, purging oldest first. */ + int max_entries_of_same_pso_type = 3; + for (int i = (int)collection.size() - 1; i >= 0; i--) { + if (collection[i]->pso_type == pso_type) { + max_entries_of_same_pso_type -= 1; + if (max_entries_of_same_pso_type == 0) { + metal_printf("Purging oldest %s:%s kernel from ShaderCache\n", + kernel_type_as_string(pso_type), + device_kernel_as_string(device_kernel)); + collection.erase(collection.begin() + i); + break; + } + } + } + collection.push_back(unique_ptr(pipeline)); + } + incomplete_requests--; + if (pso_type != PSO_GENERIC) { + incomplete_specialization_requests--; } } } bool ShaderCache::should_load_kernel(DeviceKernel device_kernel, - MetalDevice *device, + MetalDevice const *device, MetalPipelineType pso_type) { + if (!running) { + return false; + } + if (device_kernel == DEVICE_KERNEL_INTEGRATOR_MEGAKERNEL) { /* Skip megakernel. */ return false; @@ -240,7 +284,6 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel, /* create compiler threads on first run */ thread_scoped_lock lock(cache_mutex); if (compile_threads.empty()) { - running = true; for (int i = 0; i < max_mtlcompiler_threads; i++) { compile_threads.push_back(std::thread([&] { compile_thread_func(i); })); } @@ -252,53 +295,39 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel, } incomplete_requests++; + if (pso_type != PSO_GENERIC) { + incomplete_specialization_requests++; + } - PipelineRequest request; - request.pipeline = new MetalKernelPipeline; - memcpy(&request.pipeline->kernel_data_, - &device->launch_params.data, - sizeof(request.pipeline->kernel_data_)); - request.pipeline->pso_type = pso_type; - request.pipeline->mtlDevice = mtlDevice; - request.pipeline->source_md5 = device->source_md5[pso_type]; - request.pipeline->mtlLibrary = device->mtlLibrary[pso_type]; - request.pipeline->device_kernel = device_kernel; - request.pipeline->threads_per_threadgroup = device->max_threads_per_threadgroup; + MetalKernelPipeline *pipeline = new MetalKernelPipeline; + + /* Keep track of the originating device's ID so that we can cancel requests if the device ceases + * to be active. */ + pipeline->originating_device_id = device->device_id; + memcpy(&pipeline->kernel_data_, &device->launch_params.data, sizeof(pipeline->kernel_data_)); + pipeline->pso_type = pso_type; + pipeline->mtlDevice = mtlDevice; + pipeline->source_md5 = device->source_md5[pso_type]; + pipeline->mtlLibrary = device->mtlLibrary[pso_type]; + pipeline->device_kernel = device_kernel; + pipeline->threads_per_threadgroup = device->max_threads_per_threadgroup; if (occupancy_tuning[device_kernel].threads_per_threadgroup) { - request.pipeline->threads_per_threadgroup = + pipeline->threads_per_threadgroup = occupancy_tuning[device_kernel].threads_per_threadgroup; - request.pipeline->num_threads_per_block = + pipeline->num_threads_per_block = occupancy_tuning[device_kernel].num_threads_per_block; } /* metalrt options */ - request.pipeline->use_metalrt = device->use_metalrt; - request.pipeline->metalrt_features = device->use_metalrt ? - (device->kernel_features & METALRT_FEATURE_MASK) : - 0; + pipeline->use_metalrt = device->use_metalrt; + pipeline->metalrt_features = device->use_metalrt ? + (device->kernel_features & METALRT_FEATURE_MASK) : + 0; { thread_scoped_lock lock(cache_mutex); - auto &collection = pipelines[device_kernel]; - - /* Cache up to 3 kernel variants with the same pso_type, purging oldest first. */ - int max_entries_of_same_pso_type = 3; - for (int i = (int)collection.size() - 1; i >= 0; i--) { - if (collection[i]->pso_type == pso_type) { - max_entries_of_same_pso_type -= 1; - if (max_entries_of_same_pso_type == 0) { - metal_printf("Purging oldest %s:%s kernel from ShaderCache\n", - kernel_type_as_string(pso_type), - device_kernel_as_string(device_kernel)); - collection.erase(collection.begin() + i); - break; - } - } - } - - collection.push_back(unique_ptr(request.pipeline)); - request_queue.push_back(request); + request_queue.push_back(pipeline); } cond_var.notify_one(); } @@ -664,51 +693,61 @@ void MetalKernelPipeline::compile() double starttime = time_dt(); - MTLNewComputePipelineStateWithReflectionCompletionHandler completionHandler = ^( - id computePipelineState, - MTLComputePipelineReflection *reflection, - NSError *error) { - bool recreate_archive = false; - if (computePipelineState == nil && archive) { + /* Block on load to ensure we continue with a valid kernel function */ + if (creating_new_archive) { + starttime = time_dt(); + NSError *error; + if (![archive addComputePipelineFunctionsWithDescriptor:computePipelineStateDescriptor + error:&error]) { NSString *errStr = [error localizedDescription]; - metal_printf( - "Failed to create compute pipeline state \"%s\" from archive - attempting recreation... " - "(error: %s)\n", - device_kernel_as_string((DeviceKernel)device_kernel), - errStr ? [errStr UTF8String] : "nil"); - computePipelineState = [mtlDevice - newComputePipelineStateWithDescriptor:computePipelineStateDescriptor - options:MTLPipelineOptionNone - reflection:nullptr - error:&error]; - recreate_archive = true; + metal_printf("Failed to add PSO to archive:\n%s\n", errStr ? [errStr UTF8String] : "nil"); } + } - double duration = time_dt() - starttime; + pipeline = [mtlDevice newComputePipelineStateWithDescriptor:computePipelineStateDescriptor + options:pipelineOptions + reflection:nullptr + error:&error]; - if (computePipelineState == nil) { - NSString *errStr = [error localizedDescription]; - error_str = string_printf("Failed to create compute pipeline state \"%s\", error: \n", - device_kernel_as_string((DeviceKernel)device_kernel)); - error_str += (errStr ? [errStr UTF8String] : "nil"); - metal_printf("%16s | %2d | %-55s | %7.2fs | FAILED!\n", - kernel_type_as_string(pso_type), - device_kernel, - device_kernel_as_string((DeviceKernel)device_kernel), - duration); - return; - } + bool recreate_archive = false; + if (pipeline == nil && archive) { + NSString *errStr = [error localizedDescription]; + metal_printf( + "Failed to create compute pipeline state \"%s\" from archive - attempting recreation... " + "(error: %s)\n", + device_kernel_as_string((DeviceKernel)device_kernel), + errStr ? [errStr UTF8String] : "nil"); + pipeline = [mtlDevice newComputePipelineStateWithDescriptor:computePipelineStateDescriptor + options:MTLPipelineOptionNone + reflection:nullptr + error:&error]; + recreate_archive = true; + } - if (!num_threads_per_block) { - num_threads_per_block = round_down(computePipelineState.maxTotalThreadsPerThreadgroup, - computePipelineState.threadExecutionWidth); - num_threads_per_block = std::max(num_threads_per_block, - (int)computePipelineState.threadExecutionWidth); - } + double duration = time_dt() - starttime; - this->pipeline = computePipelineState; + if (pipeline == nil) { + NSString *errStr = [error localizedDescription]; + error_str = string_printf("Failed to create compute pipeline state \"%s\", error: \n", + device_kernel_as_string((DeviceKernel)device_kernel)); + error_str += (errStr ? [errStr UTF8String] : "nil"); + metal_printf("%16s | %2d | %-55s | %7.2fs | FAILED!\n", + kernel_type_as_string(pso_type), + device_kernel, + device_kernel_as_string((DeviceKernel)device_kernel), + duration); + return; + } - if (@available(macOS 11.0, *)) { + if (!num_threads_per_block) { + num_threads_per_block = round_down(pipeline.maxTotalThreadsPerThreadgroup, + pipeline.threadExecutionWidth); + num_threads_per_block = std::max(num_threads_per_block, + (int)pipeline.threadExecutionWidth); + } + + if (@available(macOS 11.0, *)) { + if (ShaderCache::running) { if (creating_new_archive || recreate_archive) { if (![archive serializeToURL:[NSURL fileURLWithPath:@(metalbin_path.c_str())] error:&error]) { @@ -720,24 +759,7 @@ void MetalKernelPipeline::compile() } } } - }; - - /* Block on load to ensure we continue with a valid kernel function */ - if (creating_new_archive) { - starttime = time_dt(); - NSError *error; - if (![archive addComputePipelineFunctionsWithDescriptor:computePipelineStateDescriptor - error:&error]) { - NSString *errStr = [error localizedDescription]; - metal_printf("Failed to add PSO to archive:\n%s\n", errStr ? [errStr UTF8String] : "nil"); - } } - id pipeline = [mtlDevice - newComputePipelineStateWithDescriptor:computePipelineStateDescriptor - options:pipelineOptions - reflection:nullptr - error:&error]; - completionHandler(pipeline, nullptr, error); this->loaded = true; [computePipelineStateDescriptor release]; @@ -763,8 +785,6 @@ void MetalKernelPipeline::compile() } } - double duration = time_dt() - starttime; - if (!use_binary_archive) { metal_printf("%16s | %2d | %-55s | %7.2fs\n", kernel_type_as_string(pso_type), @@ -791,24 +811,46 @@ bool MetalDeviceKernels::load(MetalDevice *device, MetalPipelineType pso_type) shader_cache->load_kernel((DeviceKernel)i, device, pso_type); } - shader_cache->wait_for_all(); - metal_printf("Back-end compilation finished in %.1f seconds (%s)\n", - time_dt() - starttime, - kernel_type_as_string(pso_type)); + if (getenv("CYCLES_METAL_PROFILING")) { + shader_cache->wait_for_all(); + metal_printf("Back-end compilation finished in %.1f seconds (%s)\n", + time_dt() - starttime, + kernel_type_as_string(pso_type)); + } return true; } -bool MetalDeviceKernels::should_load_kernels(MetalDevice *device, MetalPipelineType pso_type) +bool MetalDeviceKernels::any_specialization_happening_now() { - auto shader_cache = get_shader_cache(device->mtlDevice); - for (int i = 0; i < DEVICE_KERNEL_NUM; i++) { - if (shader_cache->should_load_kernel((DeviceKernel)i, device, pso_type)) { + /* Return true if any ShaderCaches have ongoing specialization requests (typically there will be + * only 1). */ + thread_scoped_lock lock(g_shaderCacheMutex); + for (auto &it : g_shaderCache) { + if (it.second->incomplete_specialization_requests > 0) { return true; } } return false; } +int MetalDeviceKernels::get_loaded_kernel_count(MetalDevice const *device, + MetalPipelineType pso_type) +{ + auto shader_cache = get_shader_cache(device->mtlDevice); + int loaded_count = DEVICE_KERNEL_NUM; + for (int i = 0; i < DEVICE_KERNEL_NUM; i++) { + if (shader_cache->should_load_kernel((DeviceKernel)i, device, pso_type)) { + loaded_count -= 1; + } + } + return loaded_count; +} + +bool MetalDeviceKernels::should_load_kernels(MetalDevice const *device, MetalPipelineType pso_type) +{ + return get_loaded_kernel_count(device, pso_type) != DEVICE_KERNEL_NUM; +} + const MetalKernelPipeline *MetalDeviceKernels::get_best_pipeline(const MetalDevice *device, DeviceKernel kernel) { diff --git a/intern/cycles/device/metal/queue.mm b/intern/cycles/device/metal/queue.mm index c0df2c8553f..b4afc3a2a28 100644 --- a/intern/cycles/device/metal/queue.mm +++ b/intern/cycles/device/metal/queue.mm @@ -702,6 +702,10 @@ bool MetalDeviceQueue::synchronize() void MetalDeviceQueue::zero_to_device(device_memory &mem) { + if (metal_device_->have_error()) { + return; + } + assert(mem.type != MEM_GLOBAL && mem.type != MEM_TEXTURE); if (mem.memory_size() == 0) { @@ -729,6 +733,10 @@ void MetalDeviceQueue::zero_to_device(device_memory &mem) void MetalDeviceQueue::copy_to_device(device_memory &mem) { + if (metal_device_->have_error()) { + return; + } + if (mem.memory_size() == 0) { return; } @@ -771,6 +779,10 @@ void MetalDeviceQueue::copy_to_device(device_memory &mem) void MetalDeviceQueue::copy_from_device(device_memory &mem) { + if (metal_device_->have_error()) { + return; + } + assert(mem.type != MEM_GLOBAL && mem.type != MEM_TEXTURE); if (mem.memory_size() == 0) { diff --git a/intern/cycles/integrator/path_trace.cpp b/intern/cycles/integrator/path_trace.cpp index 8e8fbd86be0..c17add4ed9b 100644 --- a/intern/cycles/integrator/path_trace.cpp +++ b/intern/cycles/integrator/path_trace.cpp @@ -390,6 +390,9 @@ void PathTrace::path_trace(RenderWork &render_work) const int num_samples = render_work.path_trace.num_samples; PathTraceWork *path_trace_work = path_trace_works_[i].get(); + if (path_trace_work->get_device()->have_error()) { + return; + } PathTraceWork::RenderStatistics statistics; path_trace_work->render_samples(statistics, diff --git a/intern/cycles/session/session.cpp b/intern/cycles/session/session.cpp index e5ece8dc0cb..9fa7f5da296 100644 --- a/intern/cycles/session/session.cpp +++ b/intern/cycles/session/session.cpp @@ -113,6 +113,9 @@ void Session::start() void Session::cancel(bool quick) { + /* Cancel any long running device operations (e.g. shader compilations). */ + device->cancel(); + /* Check if session thread is rendering. */ const bool rendering = is_session_thread_rendering(); @@ -401,6 +404,16 @@ RenderWork Session::run_update_for_next_iteration() path_trace_->load_kernels(); path_trace_->alloc_work_memory(); + /* Wait for device to be ready (e.g. finish any background compilations). */ + string device_status; + while (!device->is_ready(device_status)) { + progress.set_status(device_status); + if (progress.get_cancel()) { + break; + } + std::this_thread::sleep_for(std::chrono::milliseconds(200)); + } + progress.add_skip_time(update_timer, params.background); } From 2540a52f9135d31f1460761c79b915ecedec23a5 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 4 Jan 2023 17:30:55 +0100 Subject: [PATCH 0406/1522] Cleanup: quiet unused parameter warning --- intern/cycles/device/device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index 959939ddbb7..ad625fc5a47 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -173,7 +173,7 @@ class Device { } /* Return true if device is ready for rendering, or report status if not. */ - virtual bool is_ready(string &status) const + virtual bool is_ready(string & /*status*/) const { return true; } From 58f1e62871cc9f4be418c4f2397ae6bb86318d15 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 4 Jan 2023 12:19:58 -0500 Subject: [PATCH 0407/1522] Geometry Nodes: Parallelize deleting vertex group Since 78f28b55d39288926634, allocating on multiple threads is much faster, making it a nice improvement to parallelize vertex group operations. This patch adds multi-threading when removing a vertex group from the "Remove Named Attribute" node. On a Ryzen 3700x: Before: `(Average: 15.6 ms, Min: 15.0 ms)` After: `(Average: 8.1 ms, Min: 7.6 ms)` Differential Revision: https://developer.blender.org/D16916 --- .../intern/geometry_component_mesh.cc | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 87ddb76171e..ac19fb43568 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -1117,15 +1117,18 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider { return true; } - for (MDeformVert &dvert : mesh->deform_verts_for_write()) { - MDeformWeight *weight = BKE_defvert_find_index(&dvert, index); - BKE_defvert_remove_group(&dvert, weight); - for (MDeformWeight &weight : MutableSpan(dvert.dw, dvert.totweight)) { - if (weight.def_nr > index) { - weight.def_nr--; + MutableSpan dverts = mesh->deform_verts_for_write(); + threading::parallel_for(dverts.index_range(), 1024, [&](IndexRange range) { + for (MDeformVert &dvert : dverts.slice(range)) { + MDeformWeight *weight = BKE_defvert_find_index(&dvert, index); + BKE_defvert_remove_group(&dvert, weight); + for (MDeformWeight &weight : MutableSpan(dvert.dw, dvert.totweight)) { + if (weight.def_nr > index) { + weight.def_nr--; + } } } - } + }); return true; } From 83f519b7c18f68d5410610bdbcc90fe7b425f50a Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 4 Jan 2023 18:46:16 +0100 Subject: [PATCH 0408/1522] Functions: initialize node storage and default values on first execution Previously, this happened when the "node task" first runs, which might not actually execute the node if there are missing inputs. Deferring the allocation of storage and default inputs allows for better memory reuse later (currently the memory is not reused). --- .../intern/lazy_function_graph_executor.cc | 65 +++++++++++-------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/source/blender/functions/intern/lazy_function_graph_executor.cc b/source/blender/functions/intern/lazy_function_graph_executor.cc index b9cf3a82bcb..fc74b3cd213 100644 --- a/source/blender/functions/intern/lazy_function_graph_executor.cc +++ b/source/blender/functions/intern/lazy_function_graph_executor.cc @@ -151,9 +151,15 @@ struct NodeState { */ bool node_has_finished = false; /** - * Set to true once the node is done running for the first time. + * Set to true once the always required inputs have been requested. + * This happens the first time the node is run. */ - bool had_initialization = false; + bool always_used_inputs_requested = false; + /** + * Set to true when the storage and defaults have been initialized. + * This happens the first time the node function is executed. + */ + bool storage_and_defaults_initialized = false; /** * Nodes with side effects should always be executed when their required inputs have been * computed. @@ -729,39 +735,20 @@ class Executor { return; } - if (!node_state.had_initialization) { - /* Initialize storage. */ - node_state.storage = fn.init_storage(allocator); - - /* Load unlinked inputs. */ - for (const int input_index : node.inputs().index_range()) { - const InputSocket &input_socket = node.input(input_index); - if (input_socket.origin() != nullptr) { - continue; - } - InputState &input_state = node_state.inputs[input_index]; - const CPPType &type = input_socket.type(); - const void *default_value = input_socket.default_value(); - BLI_assert(default_value != nullptr); - if (self_.logger_ != nullptr) { - self_.logger_->log_socket_value(input_socket, {type, default_value}, *context_); - } - void *buffer = allocator.allocate(type.size(), type.alignment()); - type.copy_construct(default_value, buffer); - this->forward_value_to_input(locked_node, input_state, {type, buffer}, current_task); - } - + if (!node_state.always_used_inputs_requested) { /* Request linked inputs that are always needed. */ const Span fn_inputs = fn.inputs(); for (const int input_index : fn_inputs.index_range()) { const Input &fn_input = fn_inputs[input_index]; if (fn_input.usage == ValueUsage::Used) { const InputSocket &input_socket = node.input(input_index); - this->set_input_required(locked_node, input_socket); + if (input_socket.origin() != nullptr) { + this->set_input_required(locked_node, input_socket); + } } } - node_state.had_initialization = true; + node_state.always_used_inputs_requested = true; } for (const int input_index : node_state.inputs.index_range()) { @@ -784,6 +771,32 @@ class Executor { }); if (node_needs_execution) { + if (!node_state.storage_and_defaults_initialized) { + /* Initialize storage. */ + node_state.storage = fn.init_storage(allocator); + + /* Load unlinked inputs. */ + for (const int input_index : node.inputs().index_range()) { + const InputSocket &input_socket = node.input(input_index); + if (input_socket.origin() != nullptr) { + continue; + } + InputState &input_state = node_state.inputs[input_index]; + const CPPType &type = input_socket.type(); + const void *default_value = input_socket.default_value(); + BLI_assert(default_value != nullptr); + if (self_.logger_ != nullptr) { + self_.logger_->log_socket_value(input_socket, {type, default_value}, *context_); + } + BLI_assert(input_state.value == nullptr); + input_state.value = allocator.allocate(type.size(), type.alignment()); + type.copy_construct(default_value, input_state.value); + input_state.was_ready_for_execution = true; + } + + node_state.storage_and_defaults_initialized = true; + } + /* Importantly, the node must not be locked when it is executed. That would result in locks * being hold very long in some cases and results in multiple locks being hold by the same * thread in the same graph which can lead to deadlocks. */ From 224d26fd33d362c1e191f53e19a8c48372c621af Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 4 Jan 2023 16:25:01 -0500 Subject: [PATCH 0409/1522] Geometry Nodes: Parallelize reading and writing vertex groups Reading or writing a vertex group is expensive enough that it's worth parallelizing. On a Ryzen 3700x, in a grid of 250k vertices with 30 randomly assigned vertex groups (each to 10-50% of vertices), I observed a 4x improvement for writing to a group and a 3x improvement when reading their data. This significantly speeds up nodes that create a new mesh from a mesh that had vertex groups. --- .../intern/geometry_component_mesh.cc | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index ac19fb43568..b9702466d17 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -997,9 +997,11 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl { void set_all(Span src) override { - for (const int64_t index : src.index_range()) { - this->set(index, src[index]); - } + threading::parallel_for(src.index_range(), 4096, [&](const IndexRange range) { + for (const int64_t i : range) { + this->set(i, src[i]); + } + }); } void materialize(IndexMask mask, MutableSpan r_span) const override @@ -1007,14 +1009,16 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl { if (dverts_ == nullptr) { return r_span.fill_indices(mask, 0.0f); } - for (const int64_t index : mask) { - if (const MDeformWeight *weight = this->find_weight_at_index(index)) { - r_span[index] = weight->weight; + threading::parallel_for(mask.index_range(), 4096, [&](const IndexRange range) { + for (const int64_t i : mask.slice(range)) { + if (const MDeformWeight *weight = this->find_weight_at_index(i)) { + r_span[i] = weight->weight; + } + else { + r_span[i] = 0.0f; + } } - else { - r_span[index] = 0.0f; - } - } + }); } void materialize_to_uninitialized(IndexMask mask, MutableSpan r_span) const override From 433d436b84eacf43e7b9f2bc0c2e49fc29472ce6 Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Wed, 4 Jan 2023 16:37:32 -0500 Subject: [PATCH 0410/1522] Fix: sort link indices in multi input sockets incorrect For some reason I don't understand, the dragged link is sorted across all the node's multi-input sockets. This leads to problems when there are multiple sockets to sort. With this patch, I'm making the feature work more directional. Differential Revision: https://developer.blender.org/D16892 --- .../editors/space_node/node_relationships.cc | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 1ccebd18893..d7e73761667 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -288,32 +288,27 @@ struct LinkAndPosition { float2 multi_socket_position; }; -static void sort_multi_input_socket_links_with_drag(bNode &node, +static void sort_multi_input_socket_links_with_drag(bNodeSocket &socket, bNodeLink &drag_link, const float2 &cursor) { - for (bNodeSocket *socket : node.input_sockets()) { - if (!socket->is_multi_input()) { - continue; - } - const float2 &socket_location = {socket->runtime->locx, socket->runtime->locy}; + const float2 &socket_location = {socket.runtime->locx, socket.runtime->locy}; - Vector links; - for (bNodeLink *link : socket->directly_linked_links()) { - const float2 location = node_link_calculate_multi_input_position( - socket_location, link->multi_input_socket_index, link->tosock->runtime->total_inputs); - links.append({link, location}); - }; + Vector links; + for (bNodeLink *link : socket.directly_linked_links()) { + const float2 location = node_link_calculate_multi_input_position( + socket_location, link->multi_input_socket_index, link->tosock->runtime->total_inputs); + links.append({link, location}); + }; - links.append({&drag_link, cursor}); + links.append({&drag_link, cursor}); - std::sort(links.begin(), links.end(), [](const LinkAndPosition a, const LinkAndPosition b) { - return a.multi_socket_position.y < b.multi_socket_position.y; - }); + std::sort(links.begin(), links.end(), [](const LinkAndPosition a, const LinkAndPosition b) { + return a.multi_socket_position.y < b.multi_socket_position.y; + }); - for (const int i : links.index_range()) { - links[i].link->multi_input_socket_index = i; - } + for (const int i : links.index_range()) { + links[i].link->multi_input_socket_index = i; } } @@ -972,8 +967,8 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur existing_link_connected_to_fromsock->multi_input_socket_index; continue; } - if (link.tosock && link.tosock->flag & SOCK_MULTI_INPUT) { - sort_multi_input_socket_links_with_drag(tnode, link, cursor); + if (tsock && tsock->is_multi_input()) { + sort_multi_input_socket_links_with_drag(*tsock, link, cursor); } } } From 496d736adca5f38c589370246c1c2fe4c69243f6 Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Thu, 5 Jan 2023 11:21:51 +1300 Subject: [PATCH 0411/1522] Cleanup: format --- intern/cycles/device/metal/kernel.mm | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/intern/cycles/device/metal/kernel.mm b/intern/cycles/device/metal/kernel.mm index 97ac47dbdb8..ec2025e78fe 100644 --- a/intern/cycles/device/metal/kernel.mm +++ b/intern/cycles/device/metal/kernel.mm @@ -313,17 +313,15 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel, pipeline->threads_per_threadgroup = device->max_threads_per_threadgroup; if (occupancy_tuning[device_kernel].threads_per_threadgroup) { - pipeline->threads_per_threadgroup = - occupancy_tuning[device_kernel].threads_per_threadgroup; - pipeline->num_threads_per_block = - occupancy_tuning[device_kernel].num_threads_per_block; + pipeline->threads_per_threadgroup = occupancy_tuning[device_kernel].threads_per_threadgroup; + pipeline->num_threads_per_block = occupancy_tuning[device_kernel].num_threads_per_block; } /* metalrt options */ pipeline->use_metalrt = device->use_metalrt; pipeline->metalrt_features = device->use_metalrt ? - (device->kernel_features & METALRT_FEATURE_MASK) : - 0; + (device->kernel_features & METALRT_FEATURE_MASK) : + 0; { thread_scoped_lock lock(cache_mutex); @@ -742,8 +740,7 @@ void MetalKernelPipeline::compile() if (!num_threads_per_block) { num_threads_per_block = round_down(pipeline.maxTotalThreadsPerThreadgroup, pipeline.threadExecutionWidth); - num_threads_per_block = std::max(num_threads_per_block, - (int)pipeline.threadExecutionWidth); + num_threads_per_block = std::max(num_threads_per_block, (int)pipeline.threadExecutionWidth); } if (@available(macOS 11.0, *)) { From a7cc6e015cf98feca22cfc08c3356807b989a9fe Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Wed, 4 Jan 2023 16:01:24 +0000 Subject: [PATCH 0412/1522] Cycles: Additional Metal kernel specialisation exposed through UI This patch adds a new "Kernel Optimization Level" dropdown menu to control Metal kernel specialisation. Currently this defaults to "full" optimisation, on the assumption that the changes proposed in D16371 will address usability concerns around app responsiveness and shader cache housekeeping. Reviewed By: brecht Differential Revision: https://developer.blender.org/D16514 --- intern/cycles/blender/addon/properties.py | 19 +++- intern/cycles/blender/device.cpp | 14 ++- intern/cycles/blender/device.h | 3 +- intern/cycles/blender/python.cpp | 2 +- intern/cycles/blender/sync.cpp | 2 +- intern/cycles/device/device.h | 24 +++-- intern/cycles/device/metal/device_impl.mm | 44 ++++++-- intern/cycles/device/metal/kernel.h | 2 + intern/cycles/device/metal/kernel.mm | 122 +++++++++++++--------- intern/cycles/device/metal/queue.mm | 27 +++-- 10 files changed, 173 insertions(+), 86 deletions(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index eff6384c85e..a27a75e48fa 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1543,6 +1543,17 @@ class CyclesPreferences(bpy.types.AddonPreferences): default=False, ) + kernel_optimization_level: EnumProperty( + name="Kernel Optimization", + description="Kernels can be optimized based on scene content. Optimized kernels are requested at the start of a render. If optimized kernels are not available, rendering will proceed using generic kernels until the optimized set is available in the cache. This can result in additional CPU usage for a brief time (tens of seconds).", + default='FULL', + items=( + ('OFF', "Off", "Disable kernel optimization. Slowest rendering, no extra background CPU usage"), + ('INTERSECT', "Intersection only", "Optimize only intersection kernels. Faster rendering, negligible extra background CPU usage"), + ('FULL', "Full", "Optimize all kernels. Fastest rendering, may result in extra background CPU usage"), + ), + ) + def find_existing_device_entry(self, device): for device_entry in self.devices: if device_entry.id == device[2] and device_entry.type == device[1]: @@ -1711,10 +1722,12 @@ class CyclesPreferences(bpy.types.AddonPreferences): if compute_device_type == 'METAL': import platform # MetalRT only works on Apple Silicon at present, pending argument encoding fixes on AMD + # Kernel specialization is only viable on Apple Silicon at present due to relative compilation speed if platform.machine() == 'arm64': - row = layout.row() - row.use_property_split = True - row.prop(self, "use_metalrt") + col = layout.column() + col.use_property_split = True + col.prop(self, "kernel_optimization_level") + col.prop(self, "use_metalrt") def draw(self, context): self.draw_impl(self.layout, context) diff --git a/intern/cycles/blender/device.cpp b/intern/cycles/blender/device.cpp index 22beca898f1..96e7bdd03aa 100644 --- a/intern/cycles/blender/device.cpp +++ b/intern/cycles/blender/device.cpp @@ -30,7 +30,7 @@ int blender_device_threads(BL::Scene &b_scene) return 0; } -DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scene, bool background) +DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scene, bool background, bool preview) { PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); @@ -113,6 +113,18 @@ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scen device.use_metalrt = true; } + if (preview) { + /* Disable specialization for preview renders. */ + device.kernel_optimization_level = KERNEL_OPTIMIZATION_LEVEL_OFF; + } + else { + device.kernel_optimization_level = (KernelOptimizationLevel)get_enum( + cpreferences, + "kernel_optimization_level", + KERNEL_OPTIMIZATION_NUM_LEVELS, + KERNEL_OPTIMIZATION_LEVEL_FULL); + } + return device; } diff --git a/intern/cycles/blender/device.h b/intern/cycles/blender/device.h index 7a762261829..08655743eeb 100644 --- a/intern/cycles/blender/device.h +++ b/intern/cycles/blender/device.h @@ -19,7 +19,8 @@ int blender_device_threads(BL::Scene &b_scene); /* Convert Blender settings to device specification. */ DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scene, - bool background); + bool background, + bool preview); CCL_NAMESPACE_END diff --git a/intern/cycles/blender/python.cpp b/intern/cycles/blender/python.cpp index cfc7a78143c..96cb204be4b 100644 --- a/intern/cycles/blender/python.cpp +++ b/intern/cycles/blender/python.cpp @@ -754,7 +754,7 @@ static PyObject *denoise_func(PyObject * /*self*/, PyObject *args, PyObject *key RNA_id_pointer_create((ID *)PyLong_AsVoidPtr(pyscene), &sceneptr); BL::Scene b_scene(sceneptr); - DeviceInfo device = blender_device_info(b_preferences, b_scene, true); + DeviceInfo device = blender_device_info(b_preferences, b_scene, true, true); /* Get denoising parameters from view layer. */ PointerRNA viewlayerptr; diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp index d87d094dc56..45fe4334f06 100644 --- a/intern/cycles/blender/sync.cpp +++ b/intern/cycles/blender/sync.cpp @@ -866,7 +866,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine, /* Device */ params.threads = blender_device_threads(b_scene); - params.device = blender_device_info(b_preferences, b_scene, params.background); + params.device = blender_device_info(b_preferences, b_scene, params.background, b_engine.is_preview()); /* samples */ int samples = get_int(cscene, "samples"); diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index ad625fc5a47..3923698b1cd 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -57,6 +57,14 @@ enum DeviceTypeMask { #define DEVICE_MASK(type) (DeviceTypeMask)(1 << type) +enum KernelOptimizationLevel { + KERNEL_OPTIMIZATION_LEVEL_OFF = 0, + KERNEL_OPTIMIZATION_LEVEL_INTERSECT = 1, + KERNEL_OPTIMIZATION_LEVEL_FULL = 2, + + KERNEL_OPTIMIZATION_NUM_LEVELS +}; + class DeviceInfo { public: DeviceType type; @@ -66,13 +74,15 @@ class DeviceInfo { bool display_device; /* GPU is used as a display device. */ bool has_nanovdb; /* Support NanoVDB volumes. */ bool has_light_tree; /* Support light tree. */ - bool has_osl; /* Support Open Shading Language. */ - bool has_guiding; /* Support path guiding. */ - bool has_profiling; /* Supports runtime collection of profiling info. */ - bool has_peer_memory; /* GPU has P2P access to memory of another GPU. */ - bool has_gpu_queue; /* Device supports GPU queue. */ - bool use_metalrt; /* Use MetalRT to accelerate ray queries (Metal only). */ - DenoiserTypeMask denoisers; /* Supported denoiser types. */ + bool has_osl; /* Support Open Shading Language. */ + bool has_guiding; /* Support path guiding. */ + bool has_profiling; /* Supports runtime collection of profiling info. */ + bool has_peer_memory; /* GPU has P2P access to memory of another GPU. */ + bool has_gpu_queue; /* Device supports GPU queue. */ + bool use_metalrt; /* Use MetalRT to accelerate ray queries (Metal only). */ + KernelOptimizationLevel kernel_optimization_level; /* Optimization level applied to path tracing + kernels (Metal only). */ + DenoiserTypeMask denoisers; /* Supported denoiser types. */ int cpu_threads; vector multi_devices; string error_msg; diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm index a6966bf167d..01578155931 100644 --- a/intern/cycles/device/metal/device_impl.mm +++ b/intern/cycles/device/metal/device_impl.mm @@ -110,10 +110,6 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile case METAL_GPU_APPLE: { max_threads_per_threadgroup = 512; use_metalrt = info.use_metalrt; - - /* Specialize the intersection kernels on Apple GPUs by default as these can be built very - * quickly. */ - kernel_specialization_level = PSO_SPECIALIZED_INTERSECT; break; } } @@ -126,6 +122,22 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile capture_enabled = true; } + if (device_vendor == METAL_GPU_APPLE) { + /* Set kernel_specialization_level based on user prefs. */ + switch (info.kernel_optimization_level) { + case KERNEL_OPTIMIZATION_LEVEL_OFF: + kernel_specialization_level = PSO_GENERIC; + break; + default: + case KERNEL_OPTIMIZATION_LEVEL_INTERSECT: + kernel_specialization_level = PSO_SPECIALIZED_INTERSECT; + break; + case KERNEL_OPTIMIZATION_LEVEL_FULL: + kernel_specialization_level = PSO_SPECIALIZED_SHADE; + break; + } + } + if (auto envstr = getenv("CYCLES_METAL_SPECIALIZATION_LEVEL")) { kernel_specialization_level = (MetalPipelineType)atoi(envstr); } @@ -444,7 +456,7 @@ void MetalDevice::compile_and_load(int device_id, MetalPipelineType pso_type) source); } - const double starttime = time_dt(); + double starttime = time_dt(); NSError *error = NULL; id mtlLibrary = [mtlDevice newLibraryWithSource:@(source.c_str()) @@ -457,6 +469,12 @@ void MetalDevice::compile_and_load(int device_id, MetalPipelineType pso_type) [options release]; + bool blocking_pso_build = (getenv("CYCLES_METAL_PROFILING") || MetalDeviceKernels::is_benchmark_warmup()); + if (blocking_pso_build) { + MetalDeviceKernels::wait_for_all(); + starttime = 0.0; + } + /* Save the compiled MTLLibrary and trigger the AIR->PSO builds (if the MetalDevice still * exists). */ { @@ -464,6 +482,8 @@ void MetalDevice::compile_and_load(int device_id, MetalPipelineType pso_type) if (MetalDevice *instance = get_device_by_ID(device_id, lock)) { if (mtlLibrary) { instance->mtlLibrary[pso_type] = mtlLibrary; + + starttime = time_dt(); MetalDeviceKernels::load(instance, pso_type); } else { @@ -472,6 +492,14 @@ void MetalDevice::compile_and_load(int device_id, MetalPipelineType pso_type) } } } + + if (starttime && blocking_pso_build) { + MetalDeviceKernels::wait_for_all(); + + metal_printf("Back-end compilation finished in %.1f seconds (%s)\n", + time_dt() - starttime, + kernel_type_as_string(pso_type)); + } } void MetalDevice::load_texture_info() @@ -832,10 +860,8 @@ void MetalDevice::optimize_for_scene(Scene *scene) } /* Block during benchmark warm-up to ensure kernels are cached prior to the observed run. */ - for (int i = 0; i < *_NSGetArgc(); i++) { - if (!strcmp((*_NSGetArgv())[i], "--warm-up")) { - specialize_in_background = false; - } + if (MetalDeviceKernels::is_benchmark_warmup()) { + specialize_in_background = false; } if (specialize_in_background) { diff --git a/intern/cycles/device/metal/kernel.h b/intern/cycles/device/metal/kernel.h index c2b9f073b12..212671f52a0 100644 --- a/intern/cycles/device/metal/kernel.h +++ b/intern/cycles/device/metal/kernel.h @@ -101,6 +101,8 @@ int get_loaded_kernel_count(MetalDevice const *device, MetalPipelineType pso_typ bool should_load_kernels(MetalDevice const *device, MetalPipelineType pso_type); bool load(MetalDevice *device, MetalPipelineType pso_type); const MetalKernelPipeline *get_best_pipeline(const MetalDevice *device, DeviceKernel kernel); +void wait_for_all(); +bool is_benchmark_warmup(); } /* namespace MetalDeviceKernels */ diff --git a/intern/cycles/device/metal/kernel.mm b/intern/cycles/device/metal/kernel.mm index ec2025e78fe..7b26085c75f 100644 --- a/intern/cycles/device/metal/kernel.mm +++ b/intern/cycles/device/metal/kernel.mm @@ -116,19 +116,29 @@ struct ShaderCache { }; bool ShaderCache::running = true; -std::mutex g_shaderCacheMutex; -std::map, unique_ptr> g_shaderCache; + +const int MAX_POSSIBLE_GPUS_ON_SYSTEM = 8; +using DeviceShaderCache = std::pair, unique_ptr>; +int g_shaderCacheCount = 0; +DeviceShaderCache g_shaderCache[MAX_POSSIBLE_GPUS_ON_SYSTEM]; ShaderCache *get_shader_cache(id mtlDevice) { - thread_scoped_lock lock(g_shaderCacheMutex); - auto it = g_shaderCache.find(mtlDevice); - if (it != g_shaderCache.end()) { - return it->second.get(); + for (int i=0; i(mtlDevice); - return g_shaderCache[mtlDevice].get(); + static thread_mutex g_shaderCacheCountMutex; + g_shaderCacheCountMutex.lock(); + int index = g_shaderCacheCount++; + g_shaderCacheCountMutex.unlock(); + + assert(index < MAX_POSSIBLE_GPUS_ON_SYSTEM); + g_shaderCache[index].first = mtlDevice; + g_shaderCache[index].second = make_unique(mtlDevice); + return g_shaderCache[index].second.get(); } ShaderCache::~ShaderCache() @@ -145,7 +155,7 @@ ShaderCache::~ShaderCache() num_incomplete = int(incomplete_requests); } - if (num_incomplete) { + if (num_incomplete && !MetalDeviceKernels::is_benchmark_warmup()) { metal_printf("ShaderCache still busy (incomplete_requests = %d). Terminating...\n", num_incomplete); std::terminate(); @@ -332,12 +342,6 @@ void ShaderCache::load_kernel(DeviceKernel device_kernel, MetalKernelPipeline *ShaderCache::get_best_pipeline(DeviceKernel kernel, const MetalDevice *device) { - thread_scoped_lock lock(cache_mutex); - auto &collection = pipelines[kernel]; - if (collection.empty()) { - return nullptr; - } - /* metalrt options */ bool use_metalrt = device->use_metalrt; bool device_metalrt_hair = use_metalrt && device->kernel_features & KERNEL_FEATURE_HAIR; @@ -349,34 +353,43 @@ MetalKernelPipeline *ShaderCache::get_best_pipeline(DeviceKernel kernel, const M device->kernel_features & KERNEL_FEATURE_OBJECT_MOTION; MetalKernelPipeline *best_pipeline = nullptr; - for (auto &pipeline : collection) { - if (!pipeline->loaded) { - /* still loading - ignore */ - continue; - } + while(!best_pipeline) { + { + thread_scoped_lock lock(cache_mutex); + for (auto &pipeline : pipelines[kernel]) { + if (!pipeline->loaded) { + /* still loading - ignore */ + continue; + } - bool pipeline_metalrt_hair = pipeline->metalrt_features & KERNEL_FEATURE_HAIR; - bool pipeline_metalrt_hair_thick = pipeline->metalrt_features & KERNEL_FEATURE_HAIR_THICK; - bool pipeline_metalrt_pointcloud = pipeline->metalrt_features & KERNEL_FEATURE_POINTCLOUD; - bool pipeline_metalrt_motion = use_metalrt && - pipeline->metalrt_features & KERNEL_FEATURE_OBJECT_MOTION; + bool pipeline_metalrt_hair = pipeline->metalrt_features & KERNEL_FEATURE_HAIR; + bool pipeline_metalrt_hair_thick = pipeline->metalrt_features & KERNEL_FEATURE_HAIR_THICK; + bool pipeline_metalrt_pointcloud = pipeline->metalrt_features & KERNEL_FEATURE_POINTCLOUD; + bool pipeline_metalrt_motion = use_metalrt && + pipeline->metalrt_features & KERNEL_FEATURE_OBJECT_MOTION; - if (pipeline->use_metalrt != use_metalrt || pipeline_metalrt_hair != device_metalrt_hair || - pipeline_metalrt_hair_thick != device_metalrt_hair_thick || - pipeline_metalrt_pointcloud != device_metalrt_pointcloud || - pipeline_metalrt_motion != device_metalrt_motion) { - /* wrong combination of metalrt options */ - continue; - } + if (pipeline->use_metalrt != use_metalrt || pipeline_metalrt_hair != device_metalrt_hair || + pipeline_metalrt_hair_thick != device_metalrt_hair_thick || + pipeline_metalrt_pointcloud != device_metalrt_pointcloud || + pipeline_metalrt_motion != device_metalrt_motion) { + /* wrong combination of metalrt options */ + continue; + } - if (pipeline->pso_type != PSO_GENERIC) { - if (pipeline->source_md5 == device->source_md5[PSO_SPECIALIZED_INTERSECT] || - pipeline->source_md5 == device->source_md5[PSO_SPECIALIZED_SHADE]) { - best_pipeline = pipeline.get(); + if (pipeline->pso_type != PSO_GENERIC) { + if (pipeline->source_md5 == device->source_md5[PSO_SPECIALIZED_INTERSECT] || + pipeline->source_md5 == device->source_md5[PSO_SPECIALIZED_SHADE]) { + best_pipeline = pipeline.get(); + } + } + else if (!best_pipeline) { + best_pipeline = pipeline.get(); + } } } - else if (!best_pipeline) { - best_pipeline = pipeline.get(); + + if (!best_pipeline) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); } } @@ -802,28 +815,26 @@ void MetalKernelPipeline::compile() bool MetalDeviceKernels::load(MetalDevice *device, MetalPipelineType pso_type) { - const double starttime = time_dt(); auto shader_cache = get_shader_cache(device->mtlDevice); for (int i = 0; i < DEVICE_KERNEL_NUM; i++) { shader_cache->load_kernel((DeviceKernel)i, device, pso_type); } - - if (getenv("CYCLES_METAL_PROFILING")) { - shader_cache->wait_for_all(); - metal_printf("Back-end compilation finished in %.1f seconds (%s)\n", - time_dt() - starttime, - kernel_type_as_string(pso_type)); - } return true; } +void MetalDeviceKernels::wait_for_all() +{ + for (int i=0; iwait_for_all(); + } +} + bool MetalDeviceKernels::any_specialization_happening_now() { /* Return true if any ShaderCaches have ongoing specialization requests (typically there will be * only 1). */ - thread_scoped_lock lock(g_shaderCacheMutex); - for (auto &it : g_shaderCache) { - if (it.second->incomplete_specialization_requests > 0) { + for (int i=0; iincomplete_specialization_requests > 0) { return true; } } @@ -854,6 +865,19 @@ const MetalKernelPipeline *MetalDeviceKernels::get_best_pipeline(const MetalDevi return get_shader_cache(device->mtlDevice)->get_best_pipeline(kernel, device); } +bool MetalDeviceKernels::is_benchmark_warmup() +{ + NSArray *args = [[NSProcessInfo processInfo] arguments]; + for (int i = 0; i MetalDeviceQueue::get_compute_encoder(DeviceKernel if (@available(macos 10.14, *)) { if (timing_shared_event_) { /* Close the current encoder to ensure we're able to capture per-encoder timing data. */ - if (mtlComputeEncoder_) { - close_compute_encoder(); - } + close_compute_encoder(); } if (mtlComputeEncoder_) { @@ -897,9 +896,7 @@ id MetalDeviceQueue::get_blit_encoder() return mtlBlitEncoder_; } - if (mtlComputeEncoder_) { - close_compute_encoder(); - } + close_compute_encoder(); if (!mtlCommandBuffer_) { mtlCommandBuffer_ = [mtlCommandQueue_ commandBuffer]; @@ -913,12 +910,14 @@ id MetalDeviceQueue::get_blit_encoder() void MetalDeviceQueue::close_compute_encoder() { - [mtlComputeEncoder_ endEncoding]; - mtlComputeEncoder_ = nil; + if (mtlComputeEncoder_) { + [mtlComputeEncoder_ endEncoding]; + mtlComputeEncoder_ = nil; - if (@available(macos 10.14, *)) { - if (timing_shared_event_) { - [mtlCommandBuffer_ encodeSignalEvent:timing_shared_event_ value:timing_shared_event_id_++]; + if (@available(macos 10.14, *)) { + if (timing_shared_event_) { + [mtlCommandBuffer_ encodeSignalEvent:timing_shared_event_ value:timing_shared_event_id_++]; + } } } } From 168091a1d634092c38cd51b6df8f2696c0956812 Mon Sep 17 00:00:00 2001 From: YimingWu Date: Thu, 5 Jan 2023 11:01:32 +0800 Subject: [PATCH 0413/1522] Cleanup: Missing debug #ifdef for GPU_vertbuf_raw_step --- release/datafiles/locale | 2 +- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- source/blender/gpu/GPU_vertex_buffer.h | 2 ++ source/tools | 2 +- 5 files changed, 6 insertions(+), 4 deletions(-) diff --git a/release/datafiles/locale b/release/datafiles/locale index 4a581c54af9..7084c4ecd97 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 4a581c54af9b92cb670d750951b9382160f10f3e +Subproject commit 7084c4ecd97d93459d9d23fd90f81589b09be5df diff --git a/release/scripts/addons b/release/scripts/addons index 0b0052bd53a..a9d4443c244 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 0b0052bd53ad8249ed07dfb87705c338af698bde +Subproject commit a9d4443c244f89399ec4bcc427e05a07950528cc diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index 96143b1a8b0..bdcfdd47ec3 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit 96143b1a8b037ea3c81f065f557025db9fe1ace3 +Subproject commit bdcfdd47ec3451822b21d1cff2ea2db751093c9a diff --git a/source/blender/gpu/GPU_vertex_buffer.h b/source/blender/gpu/GPU_vertex_buffer.h index d3c1bd8145d..979b7cc06cf 100644 --- a/source/blender/gpu/GPU_vertex_buffer.h +++ b/source/blender/gpu/GPU_vertex_buffer.h @@ -141,7 +141,9 @@ GPU_INLINE void *GPU_vertbuf_raw_step(GPUVertBufRaw *a) { unsigned char *data = a->data; a->data += a->stride; +#ifdef DEBUG BLI_assert(data < a->_data_end); +#endif return (void *)data; } diff --git a/source/tools b/source/tools index fdfa2fcb949..e1744b9bd82 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit fdfa2fcb9495d87571f2dfe2ae9fa0e032536600 +Subproject commit e1744b9bd82527cf7e8af63362b61bd309b5711b From 93fc352cfaf0a38bd59d8bfb44c75bf5835ba3dd Mon Sep 17 00:00:00 2001 From: YimingWu Date: Thu, 5 Jan 2023 12:43:05 +0800 Subject: [PATCH 0414/1522] Fix T102612: Line art crash on loading due to references to other scenes. --- .../gpencil_modifiers/intern/lineart/lineart_cpu.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index 1ae91ab29c2..93c1571c613 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -2450,9 +2450,10 @@ static void lineart_object_load_single_instance(LineartData *ld, } if (ob->type == OB_MESH) { use_mesh = BKE_object_get_evaluated_mesh(ob); - if (use_mesh->edit_mesh) { + if ((!use_mesh) || use_mesh->edit_mesh) { /* If the object is being edited, then the mesh is not evaluated fully into the final - * result, do not load them. */ + * result, do not load them. This could be caused by incorrect evaluation order due to + * the way line art uses depsgraph.See T102612 for explaination of this workaround. */ return; } } @@ -2460,7 +2461,7 @@ static void lineart_object_load_single_instance(LineartData *ld, use_mesh = BKE_mesh_new_from_object(depsgraph, ob, true, true); } - /* In case we still can not get any mesh geometry data from the object */ + /* In case we still can not get any mesh geometry data from the object, same as above. */ if (!use_mesh) { return; } From 7690872ce4bc322c0fc209bd9e1aba0cb8789290 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Jan 2023 16:44:33 +1100 Subject: [PATCH 0415/1522] Cleanup: quiet missing-declaration warnings --- .../editors/uvedit/uvedit_unwrap_ops.c | 26 ++++++++++++++----- source/blender/makesrna/RNA_enum_items.h | 1 + source/blender/makesrna/intern/rna_brush.c | 4 +-- source/blender/makesrna/intern/rna_scene.c | 2 +- .../makesrna/intern/rna_sculpt_paint.c | 4 +-- source/blender/makesrna/intern/rna_userdef.c | 2 +- 6 files changed, 25 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 2dfc4d07d1f..18e920c55f4 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -1098,7 +1098,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -const EnumPropertyItem pack_margin_method[] = { +static const EnumPropertyItem pack_margin_method_items[] = { {ED_UVPACK_MARGIN_SCALED, "SCALED", 0, @@ -1139,8 +1139,12 @@ void UV_OT_pack_islands(wmOperatorType *ot) /* properties */ RNA_def_enum(ot->srna, "udim_source", pack_target, PACK_UDIM_SRC_CLOSEST, "Pack to", ""); RNA_def_boolean(ot->srna, "rotate", true, "Rotate", "Rotate islands for best fit"); - RNA_def_enum( - ot->srna, "margin_method", pack_margin_method, ED_UVPACK_MARGIN_SCALED, "Margin Method", ""); + RNA_def_enum(ot->srna, + "margin_method", + pack_margin_method_items, + ED_UVPACK_MARGIN_SCALED, + "Margin Method", + ""); RNA_def_float_factor( ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); } @@ -2077,8 +2081,12 @@ void UV_OT_unwrap(wmOperatorType *ot) 0, "Use Subdivision Surface", "Map UVs taking vertex position after Subdivision Surface modifier has been applied"); - RNA_def_enum( - ot->srna, "margin_method", pack_margin_method, ED_UVPACK_MARGIN_SCALED, "Margin Method", ""); + RNA_def_enum(ot->srna, + "margin_method", + pack_margin_method_items, + ED_UVPACK_MARGIN_SCALED, + "Margin Method", + ""); RNA_def_float_factor( ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); } @@ -2444,8 +2452,12 @@ void UV_OT_smart_project(wmOperatorType *ot) DEG2RADF(89.0f)); RNA_def_property_float_default(prop, DEG2RADF(66.0f)); - RNA_def_enum( - ot->srna, "margin_method", pack_margin_method, ED_UVPACK_MARGIN_SCALED, "Margin Method", ""); + RNA_def_enum(ot->srna, + "margin_method", + pack_margin_method_items, + ED_UVPACK_MARGIN_SCALED, + "Margin Method", + ""); RNA_def_float(ot->srna, "island_margin", 0.0f, diff --git a/source/blender/makesrna/RNA_enum_items.h b/source/blender/makesrna/RNA_enum_items.h index 1604bd97ed4..bc4d9282af0 100644 --- a/source/blender/makesrna/RNA_enum_items.h +++ b/source/blender/makesrna/RNA_enum_items.h @@ -101,6 +101,7 @@ DEF_ENUM(rna_enum_operator_type_flag_items) DEF_ENUM(rna_enum_operator_return_items) DEF_ENUM(rna_enum_operator_property_tags) +DEF_ENUM(rna_enum_brush_automasking_flag_items) DEF_ENUM(rna_enum_brush_sculpt_tool_items) DEF_ENUM(rna_enum_brush_uv_sculpt_tool_items) DEF_ENUM(rna_enum_brush_vertex_tool_items) diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index ce51b52de39..db38c3d4af7 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -94,7 +94,7 @@ static const EnumPropertyItem rna_enum_brush_texture_slot_map_texture_mode_items /* clang-format off */ /* Note: we don't actually turn these into a single enum bit-mask property, * instead we construct individual boolean properties. */ -const EnumPropertyItem RNA_automasking_flags[] = { +const EnumPropertyItem rna_enum_brush_automasking_flag_items[] = { {BRUSH_AUTOMASKING_TOPOLOGY, "use_automasking_topology", 0,"Topology", "Affect only vertices connected to the active vertex under the brush"}, {BRUSH_AUTOMASKING_FACE_SETS, "use_automasking_face_sets", 0,"Face Sets", "Affect only vertices that share Face Sets with the active vertex"}, {BRUSH_AUTOMASKING_BOUNDARY_EDGES, "use_automasking_boundary_edges", 0,"Mesh Boundary Auto-Masking", "Do not affect non manifold boundary edges"}, @@ -3204,7 +3204,7 @@ static void rna_def_brush(BlenderRNA *brna) "When locked keep using the plane origin of surface where stroke was initiated"); RNA_def_property_update(prop, 0, "rna_Brush_update"); - const EnumPropertyItem *entry = RNA_automasking_flags; + const EnumPropertyItem *entry = rna_enum_brush_automasking_flag_items; do { prop = RNA_def_property(srna, entry->identifier, PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", entry->value); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index d2cf80d8891..c1a61b0e2b6 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -476,7 +476,7 @@ const EnumPropertyItem rna_enum_bake_save_mode_items[] = { {0, NULL, 0, NULL, NULL}, }; -const EnumPropertyItem rna_enum_bake_view_from_items[] = { +static const EnumPropertyItem rna_enum_bake_view_from_items[] = { {R_BAKE_VIEW_FROM_ABOVE_SURFACE, "ABOVE_SURFACE", 0, diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 003e26333d2..7c1cae1c44d 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -32,8 +32,6 @@ #include "WM_api.h" #include "WM_types.h" -extern const EnumPropertyItem RNA_automasking_flags[]; - const EnumPropertyItem rna_enum_particle_edit_hair_brush_items[] = { {PE_BRUSH_COMB, "COMB", 0, "Comb", "Comb hairs"}, {PE_BRUSH_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth hairs"}, @@ -864,7 +862,7 @@ static void rna_def_sculpt(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_update"); - const EnumPropertyItem *entry = RNA_automasking_flags; + const EnumPropertyItem *entry = rna_enum_brush_automasking_flag_items; do { prop = RNA_def_property(srna, entry->identifier, PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", entry->value); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index db12ac82f38..fdc916a270c 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -140,7 +140,7 @@ static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = { {0, NULL, 0, NULL, NULL}, }; -const EnumPropertyItem rna_enum_preference_gpu_backend_items[] = { +static const EnumPropertyItem rna_enum_preference_gpu_backend_items[] = { {GPU_BACKEND_OPENGL, "OPENGL", 0, "OpenGL", "Use OpenGL backend"}, {GPU_BACKEND_METAL, "METAL", 0, "Metal", "Use Metal backend"}, {GPU_BACKEND_VULKAN, "VULKAN", 0, "Vulkan", "Use Vulkan backend"}, From 77c3e0895d004f8cdbfdfdb8b21432967701ab87 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Jan 2023 17:02:43 +1100 Subject: [PATCH 0416/1522] Cleanup: quiet -Wcomma warnings with clang --- source/blender/editors/curve/editcurve_pen.c | 6 +++-- .../interface/interface_region_tooltip.cc | 3 ++- .../transform_convert_sequencer_image.c | 9 +++++-- .../intern/lineart/lineart_shadow.c | 26 ++++++++++++++----- .../windowmanager/xr/intern/wm_xr_draw.c | 8 ++++-- 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/curve/editcurve_pen.c b/source/blender/editors/curve/editcurve_pen.c index b57ce6fc7cf..279614e8cfa 100644 --- a/source/blender/editors/curve/editcurve_pen.c +++ b/source/blender/editors/curve/editcurve_pen.c @@ -497,7 +497,8 @@ static bool get_closest_vertex_to_point_in_nurbs(const ViewContext *vc, int handle_display = vc->v3d->overlay.handle_display; if (handle_display == CURVE_HANDLE_NONE || (handle_display == CURVE_HANDLE_SELECTED && !BEZT_ISSEL_ANY(bezt))) { - start = 1, end = 2; + start = 1; + end = 2; } /* Loop over each of the 3 points of the #BezTriple and update data of closest bezt. */ @@ -1169,7 +1170,8 @@ static void move_segment(ViewContext *vc, MoveSegmentData *seg_data, const wmEve BezTriple *temp_bezt = bezt2; bezt2 = bezt1; bezt1 = temp_bezt; - h1 = 0, h2 = 2; + h1 = 0; + h2 = 2; } const float t = max_ff(min_ff(seg_data->t, 0.9f), 0.1f); diff --git a/source/blender/editors/interface/interface_region_tooltip.cc b/source/blender/editors/interface/interface_region_tooltip.cc index f0c01efa06f..edeeff868d6 100644 --- a/source/blender/editors/interface/interface_region_tooltip.cc +++ b/source/blender/editors/interface/interface_region_tooltip.cc @@ -135,7 +135,8 @@ static uiTooltipField *text_field_add(uiTooltipData *data, uiTooltipField *field = text_field_add_only(data); field->format = {}; field->format.style = style; - field->format.color_id = color, field->format.is_pad = is_pad; + field->format.color_id = color; + field->format.is_pad = is_pad; return field; } diff --git a/source/blender/editors/transform/transform_convert_sequencer_image.c b/source/blender/editors/transform/transform_convert_sequencer_image.c index 3d0c3ddaa4c..668cb719b2b 100644 --- a/source/blender/editors/transform/transform_convert_sequencer_image.c +++ b/source/blender/editors/transform/transform_convert_sequencer_image.c @@ -202,13 +202,18 @@ static void recalcData_sequencer_image(TransInfo *t) /* Origin. */ float origin[2]; copy_v2_v2(origin, td2d->loc); - i++, td++, td2d++; + i++; + td++; + td2d++; /* X and Y control points used to read scale and rotation. */ float handle_x[2]; copy_v2_v2(handle_x, td2d->loc); sub_v2_v2(handle_x, origin); - i++, td++, td2d++; + i++; + td++; + td2d++; + float handle_y[2]; copy_v2_v2(handle_y, td2d->loc); sub_v2_v2(handle_y, origin); diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c index 26352f8ed54..9d825a4e993 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c @@ -603,9 +603,15 @@ static void lineart_shadow_edge_cut(LineartData *ld, for (seg = cut_start_after; seg != cut_end_before; seg = nes) { nes = seg->next; - s1_fb_co_1 = seg->fbc2, s1_fb_co_2 = nes->fbc1; - s1_gloc_1 = seg->g2, s1_gloc_2 = nes->g1; - seg_1 = seg, seg_2 = nes; + s1_fb_co_1 = seg->fbc2; + s1_fb_co_2 = nes->fbc1; + + s1_gloc_1 = seg->g2; + s1_gloc_2 = nes->g1; + + seg_1 = seg; + seg_2 = nes; + if (seg == cut_start_after) { lineart_shadow_segment_slice_get(seg->fbc2, nes->fbc1, @@ -616,7 +622,9 @@ static void lineart_shadow_edge_cut(LineartData *ld, nes->ratio, m_fbc1, m_g1); - s1_fb_co_1 = m_fbc1, s1_gloc_1 = m_g1; + s1_fb_co_1 = m_fbc1; + s1_gloc_1 = m_g1; + seg_1 = new_seg_1; if (cut_start_after != new_seg_1) { BLI_insertlinkafter(&e->shadow_segments, cut_start_after, new_seg_1); @@ -634,7 +642,9 @@ static void lineart_shadow_edge_cut(LineartData *ld, nes->ratio, m_fbc2, m_g2); - s1_fb_co_2 = m_fbc2, s1_gloc_2 = m_g2; + s1_fb_co_2 = m_fbc2; + s1_gloc_2 = m_g2; + seg_2 = new_seg_2; if (cut_end_before != new_seg_2) { BLI_insertlinkbefore(&e->shadow_segments, cut_end_before, new_seg_2); @@ -821,13 +831,15 @@ static bool lineart_shadow_cast_onto_triangle(LineartData *ld, interp_v3_v3v3_db(t_gpos1, gpos1, gpos2, gat1); interp_v3_v3v3_db(t_fbc1, fbc1, fbc2, rat1); t_fbc1[3] = interpd(fbc2[3], fbc1[3], gat1); - at1 = 0, trimmed1 = true; + at1 = 0; + trimmed1 = true; } if (at2 > 1) { interp_v3_v3v3_db(t_gpos2, gpos1, gpos2, gat2); interp_v3_v3v3_db(t_fbc2, fbc1, fbc2, rat2); t_fbc2[3] = interpd(fbc2[3], fbc1[3], gat2); - at2 = 1, trimmed2 = true; + at2 = 1; + trimmed2 = true; } } if (trimmed1) { diff --git a/source/blender/windowmanager/xr/intern/wm_xr_draw.c b/source/blender/windowmanager/xr/intern/wm_xr_draw.c index 6e32c5a0aae..6cc9c8962dc 100644 --- a/source/blender/windowmanager/xr/intern/wm_xr_draw.c +++ b/source/blender/windowmanager/xr/intern/wm_xr_draw.c @@ -235,11 +235,15 @@ static void wm_xr_controller_model_draw(const XrSessionSettings *settings, switch (settings->controller_draw_style) { case XR_CONTROLLER_DRAW_DARK: case XR_CONTROLLER_DRAW_DARK_RAY: - color[0] = color[1] = color[2] = 0.0f, color[3] = 0.4f; + color[0] = color[1] = color[2] = 0.0f; + color[3] = 0.4f; break; case XR_CONTROLLER_DRAW_LIGHT: case XR_CONTROLLER_DRAW_LIGHT_RAY: - color[0] = 0.422f, color[1] = 0.438f, color[2] = 0.446f, color[3] = 0.4f; + color[0] = 0.422f; + color[1] = 0.438f; + color[2] = 0.446f; + color[3] = 0.4f; break; } From bfb0b1deccc2c66f9924a3686b5363144bd3e40c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 5 Jan 2023 18:10:11 +1100 Subject: [PATCH 0417/1522] Cleanup: pass matrix & vector by const reference instead of value --- source/blender/compositor/realtime_compositor/COM_domain.hh | 4 ++-- .../blender/compositor/realtime_compositor/intern/domain.cc | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/compositor/realtime_compositor/COM_domain.hh b/source/blender/compositor/realtime_compositor/COM_domain.hh index 99b40ae61cf..0e975afb1e2 100644 --- a/source/blender/compositor/realtime_compositor/COM_domain.hh +++ b/source/blender/compositor/realtime_compositor/COM_domain.hh @@ -143,9 +143,9 @@ class Domain { public: /* A size only constructor that sets the transformation to identity. */ - Domain(int2 size); + Domain(const int2 &size); - Domain(int2 size, float3x3 transformation); + Domain(const int2 &size, const float3x3 &transformation); /* Transform the domain by the given transformation. This effectively pre-multiply the given * transformation by the current transformation of the domain. */ diff --git a/source/blender/compositor/realtime_compositor/intern/domain.cc b/source/blender/compositor/realtime_compositor/intern/domain.cc index 31b297c212e..489e73d74ce 100644 --- a/source/blender/compositor/realtime_compositor/intern/domain.cc +++ b/source/blender/compositor/realtime_compositor/intern/domain.cc @@ -7,11 +7,12 @@ namespace blender::realtime_compositor { -Domain::Domain(int2 size) : size(size), transformation(float3x3::identity()) +Domain::Domain(const int2 &size) : size(size), transformation(float3x3::identity()) { } -Domain::Domain(int2 size, float3x3 transformation) : size(size), transformation(transformation) +Domain::Domain(const int2 &size, const float3x3 &transformation) + : size(size), transformation(transformation) { } From d7598c8081168b45bda70bee41003d8e5b622bed Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 5 Jan 2023 08:27:31 +0100 Subject: [PATCH 0418/1522] Metal: Fix crash when compiling compositor shaders. Although viewport compositor isn't supported yet on Apple deviced the shaderlibs are compiled. The compositor shaders uses mat3 constructor with a single vec3 and 6 floats. This constructor wasn't defined in metal so it failed the compilation. This patch adds the override to mat3. --- source/blender/gpu/shaders/metal/mtl_shader_defines.msl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl index 93efa16bb02..f1a8af63d72 100644 --- a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl +++ b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl @@ -1236,6 +1236,11 @@ mat3 MAT3x3( { return mat3(vec3(a1, a2, a3), vec3(b1, b2, b3), vec3(c1, c2, c3)); } +mat3 MAT3x3( + vec3 a, float b1, float b2, float b3, float c1, float c2, float c3) +{ + return mat3(a, vec3(b1, b2, b3), vec3(c1, c2, c3)); +} mat3 MAT3x3(float f) { return mat3(f); From 34fa369b48ac5fd46b58d432d185e0120499181e Mon Sep 17 00:00:00 2001 From: Damien Dh Date: Thu, 5 Jan 2023 09:20:40 +0100 Subject: [PATCH 0419/1522] Eevee: Mark Properties on Samples Panel Animatable. Eevee: Mark `Scene->Sampling->Render/Viewport` samples animatable. Mark Viewport Denoising also animatable Reviewed By: jbakker Differential Revision: https://developer.blender.org/D16827 --- source/blender/makesrna/intern/rna_scene.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index c1a61b0e2b6..61ba96c6d6e 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -7378,12 +7378,14 @@ static void rna_def_scene_eevee(BlenderRNA *brna) RNA_def_property_range(prop, 0, INT_MAX); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + RNA_def_property_flag(prop, PROP_ANIMATABLE); prop = RNA_def_property(srna, "taa_render_samples", PROP_INT, PROP_NONE); RNA_def_property_ui_text(prop, "Render Samples", "Number of samples per pixel for rendering"); RNA_def_property_range(prop, 1, INT_MAX); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + RNA_def_property_flag(prop, PROP_ANIMATABLE); prop = RNA_def_property(srna, "use_taa_reprojection", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SCE_EEVEE_TAA_REPROJECTION); @@ -7393,6 +7395,7 @@ static void rna_def_scene_eevee(BlenderRNA *brna) "(can leave some ghosting)"); RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY); RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + RNA_def_property_flag(prop, PROP_ANIMATABLE); /* Screen Space Subsurface Scattering */ prop = RNA_def_property(srna, "sss_samples", PROP_INT, PROP_NONE); From 76a68649c1c1f3db28b069397c71daf10f1c4ea4 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Thu, 5 Jan 2023 10:11:24 +0100 Subject: [PATCH 0420/1522] Animation: Graph Editor Ease operator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added a new operator that aligns selected keys on an exponential curve Revied by Reviewed by: Sybren A. Stüvel Differential Revision: https://developer.blender.org/D9479 Ref: D9479 --- release/scripts/startup/bl_ui/space_graph.py | 1 + .../editors/animation/keyframes_general.c | 34 +++++ .../editors/include/ED_keyframes_edit.h | 1 + .../editors/space_graph/graph_intern.h | 1 + .../blender/editors/space_graph/graph_ops.c | 1 + .../editors/space_graph/graph_slider_ops.c | 126 ++++++++++++++++++ 6 files changed, 164 insertions(+) diff --git a/release/scripts/startup/bl_ui/space_graph.py b/release/scripts/startup/bl_ui/space_graph.py index a5ad13ad5d8..b2c8822a75d 100644 --- a/release/scripts/startup/bl_ui/space_graph.py +++ b/release/scripts/startup/bl_ui/space_graph.py @@ -332,6 +332,7 @@ class GRAPH_MT_slider(Menu): layout.operator("graph.breakdown", text="Breakdown") layout.operator("graph.blend_to_neighbor", text="Blend to Neighbor") layout.operator("graph.blend_to_default", text="Blend to Default Value") + layout.operator("graph.ease", text="Ease") class GRAPH_MT_view_pie(Menu): diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index fbe65d6917e..f6b09e60e3c 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -377,6 +377,40 @@ void blend_to_default_fcurve(PointerRNA *id_ptr, FCurve *fcu, const float factor /* ---------------- */ +void ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor) +{ + const BezTriple left_key = fcurve_segment_start_get(fcu, segment->start_index); + const float left_x = left_key.vec[1][0]; + const float left_y = left_key.vec[1][1]; + + const BezTriple right_key = fcurve_segment_end_get(fcu, segment->start_index + segment->length); + + const float key_x_range = right_key.vec[1][0] - left_x; + const float key_y_range = right_key.vec[1][1] - left_y; + + /* In order to have a curve that favors the right key, the curve needs to be mirrored in x and y. + * Having an exponent that is a fraction of 1 would produce a similar but inferior result. */ + const bool inverted = factor > 0.5; + const float exponent = 1 + fabs(factor * 2 - 1) * 4; + + for (int i = segment->start_index; i < segment->start_index + segment->length; i++) { + /* For easy calculation of the curve, the values are normalized. */ + const float normalized_x = (fcu->bezt[i].vec[1][0] - left_x) / key_x_range; + + float normalized_y = 0; + if (inverted) { + normalized_y = 1 - pow(1 - normalized_x, exponent); + } + else { + normalized_y = pow(normalized_x, exponent); + } + + fcu->bezt[i].vec[1][1] = left_y + normalized_y * key_y_range; + } +} + +/* ---------------- */ + void breakdown_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor) { BezTriple left_bezt = fcurve_segment_start_get(fcu, segment->start_index); diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index e5bcdcdd282..f027a46b470 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -411,6 +411,7 @@ void blend_to_neighbor_fcurve_segment(struct FCurve *fcu, struct FCurveSegment *segment, float factor); void breakdown_fcurve_segment(struct FCurve *fcu, struct FCurveSegment *segment, float factor); +void ease_fcurve_segment(struct FCurve *fcu, struct FCurveSegment *segment, float factor); bool decimate_fcurve(struct bAnimListElem *ale, float remove_ratio, float error_sq_max); void blend_to_default_fcurve(struct PointerRNA *id_ptr, struct FCurve *fcu, float factor); /** diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index e6b4b9827d2..a685216db31 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -113,6 +113,7 @@ void GRAPH_OT_delete(struct wmOperatorType *ot); void GRAPH_OT_clean(struct wmOperatorType *ot); void GRAPH_OT_blend_to_neighbor(struct wmOperatorType *ot); void GRAPH_OT_breakdown(struct wmOperatorType *ot); +void GRAPH_OT_ease(struct wmOperatorType *ot); void GRAPH_OT_decimate(struct wmOperatorType *ot); void GRAPH_OT_blend_to_default(struct wmOperatorType *ot); void GRAPH_OT_sample(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index 8deea21318c..b178a3d3430 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -462,6 +462,7 @@ void graphedit_operatortypes(void) WM_operatortype_append(GRAPH_OT_decimate); WM_operatortype_append(GRAPH_OT_blend_to_neighbor); WM_operatortype_append(GRAPH_OT_breakdown); + WM_operatortype_append(GRAPH_OT_ease); WM_operatortype_append(GRAPH_OT_blend_to_default); WM_operatortype_append(GRAPH_OT_euler_filter); WM_operatortype_append(GRAPH_OT_delete); diff --git a/source/blender/editors/space_graph/graph_slider_ops.c b/source/blender/editors/space_graph/graph_slider_ops.c index 62aecf930d3..1bce22959ee 100644 --- a/source/blender/editors/space_graph/graph_slider_ops.c +++ b/source/blender/editors/space_graph/graph_slider_ops.c @@ -927,3 +927,129 @@ void GRAPH_OT_blend_to_default(wmOperatorType *ot) 1.0f); } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Ease Operator + * \{ */ + +static void ease_graph_keys(bAnimContext *ac, const float factor) +{ + ListBase anim_data = {NULL, NULL}; + + ANIM_animdata_filter(ac, &anim_data, OPERATOR_DATA_FILTER, ac->data, ac->datatype); + LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { + FCurve *fcu = (FCurve *)ale->key_data; + ListBase segments = find_fcurve_segments(fcu); + + LISTBASE_FOREACH (FCurveSegment *, segment, &segments) { + ease_fcurve_segment(fcu, segment, factor); + } + + ale->update |= ANIM_UPDATE_DEFAULT; + BLI_freelistN(&segments); + } + + ANIM_animdata_update(ac, &anim_data); + ANIM_animdata_freelist(&anim_data); +} + +static void ease_draw_status_header(bContext *C, tGraphSliderOp *gso) +{ + char status_str[UI_MAX_DRAW_STR]; + char mode_str[32]; + char slider_string[UI_MAX_DRAW_STR]; + + ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR); + + strcpy(mode_str, TIP_("Ease Keys")); + + if (hasNumInput(&gso->num)) { + char str_ofs[NUM_STR_REP_LEN]; + + outputNumInput(&gso->num, str_ofs, &gso->scene->unit); + + BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, str_ofs); + } + else { + BLI_snprintf(status_str, sizeof(status_str), "%s: %s", mode_str, slider_string); + } + + ED_workspace_status_text(C, status_str); +} + +static void ease_modal_update(bContext *C, wmOperator *op) +{ + tGraphSliderOp *gso = op->customdata; + + ease_draw_status_header(C, gso); + + /* Reset keyframes to the state at invoke. */ + reset_bezts(gso); + const float factor = slider_factor_get_and_remember(op); + ease_graph_keys(&gso->ac, factor); + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); +} + +static int ease_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + const int invoke_result = graph_slider_invoke(C, op, event); + + if (invoke_result == OPERATOR_CANCELLED) { + return invoke_result; + } + + tGraphSliderOp *gso = op->customdata; + gso->modal_update = ease_modal_update; + gso->factor_prop = RNA_struct_find_property(op->ptr, "factor"); + ease_draw_status_header(C, gso); + + return invoke_result; +} + +static int ease_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + + /* Get editor data. */ + if (ANIM_animdata_get_context(C, &ac) == 0) { + return OPERATOR_CANCELLED; + } + + const float factor = RNA_float_get(op->ptr, "factor"); + + ease_graph_keys(&ac, factor); + + /* Set notifier that keyframes have changed. */ + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +void GRAPH_OT_ease(wmOperatorType *ot) +{ + /* Identifiers. */ + ot->name = "Ease Keyframes"; + ot->idname = "GRAPH_OT_ease"; + ot->description = "Align keyframes on a ease-in or ease-out curve"; + + /* API callbacks. */ + ot->invoke = ease_invoke; + ot->modal = graph_slider_modal; + ot->exec = ease_exec; + ot->poll = graphop_editable_keyframes_poll; + + /* Flags. */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_float_factor(ot->srna, + "factor", + 0.5f, + -FLT_MAX, + FLT_MAX, + "Curve Bend", + "Control the bend of the curve", + 0.0f, + 1.0f); +} + +/** \} */ From 200a114e159695760cb5cb1d87fc5790b718971d Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Thu, 5 Jan 2023 10:39:39 +0100 Subject: [PATCH 0421/1522] Fix T87548: Propagate Pose, Next Keyframe MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change the logic for propagating poses such that it checks keyframes on all selected bones to determine the frame on which a pose should be propagated to. It then adds keyframes if they don't exist on whatever frame the pose should be propagated to. Reviewd by: Sybren A. Stüvel Differential Revision: https://developer.blender.org/D16654 Ref: D16654 --- source/blender/editors/armature/pose_slide.c | 349 ++++++++++--------- 1 file changed, 186 insertions(+), 163 deletions(-) diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c index 14b3451bd80..85af4e25454 100644 --- a/source/blender/editors/armature/pose_slide.c +++ b/source/blender/editors/armature/pose_slide.c @@ -48,6 +48,7 @@ #include "BKE_layer.h" #include "BKE_object.h" #include "BKE_report.h" +#include "BKE_scene.h" #include "BKE_screen.h" #include "BKE_unit.h" @@ -64,6 +65,7 @@ #include "ED_armature.h" #include "ED_keyframes_keylist.h" +#include "ED_keyframing.h" #include "ED_markers.h" #include "ED_numinput.h" #include "ED_screen.h" @@ -1768,18 +1770,6 @@ typedef enum ePosePropagate_Termination { POSE_PROPAGATE_SELECTED_MARKERS, } ePosePropagate_Termination; -/** - * Termination data needed for some modes - - * assumes only one of these entries will be needed at a time. - */ -typedef union tPosePropagate_ModeData { - /** Smart holds + before frame: frame number to stop on. */ - float end_frame; - - /** Selected markers: listbase for CfraElem's marking these frames. */ - ListBase sel_markers; -} tPosePropagate_ModeData; - /* --------------------------------- */ /** @@ -1862,80 +1852,11 @@ static float pose_propagate_get_boneHoldEndFrame(tPChanFCurveLink *pfl, float st return endFrame; } -/** - * Get reference value from F-Curve using RNA. - */ -static bool pose_propagate_get_refVal(Object *ob, FCurve *fcu, float *value) -{ - PointerRNA id_ptr, ptr; - PropertyRNA *prop; - bool found = false; - - /* Base pointer is always the `object -> id_ptr`. */ - RNA_id_pointer_create(&ob->id, &id_ptr); - - /* Resolve the property. */ - if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) { - if (RNA_property_array_check(prop)) { - /* Array. */ - if (fcu->array_index < RNA_property_array_length(&ptr, prop)) { - found = true; - switch (RNA_property_type(prop)) { - case PROP_BOOLEAN: - *value = (float)RNA_property_boolean_get_index(&ptr, prop, fcu->array_index); - break; - case PROP_INT: - *value = (float)RNA_property_int_get_index(&ptr, prop, fcu->array_index); - break; - case PROP_FLOAT: - *value = RNA_property_float_get_index(&ptr, prop, fcu->array_index); - break; - default: - found = false; - break; - } - } - } - else { - /* Not an array. */ - found = true; - switch (RNA_property_type(prop)) { - case PROP_BOOLEAN: - *value = (float)RNA_property_boolean_get(&ptr, prop); - break; - case PROP_INT: - *value = (float)RNA_property_int_get(&ptr, prop); - break; - case PROP_ENUM: - *value = (float)RNA_property_enum_get(&ptr, prop); - break; - case PROP_FLOAT: - *value = RNA_property_float_get(&ptr, prop); - break; - default: - found = false; - break; - } - } - } - - return found; -} - /** * Propagate just works along each F-Curve in turn. */ -static void pose_propagate_fcurve( - wmOperator *op, Object *ob, FCurve *fcu, float startFrame, tPosePropagate_ModeData modeData) +static void pose_propagate_fcurve(FCurve *fcu, float start_frame, const float end_frame) { - const int mode = RNA_enum_get(op->ptr, "mode"); - - BezTriple *bezt; - float refVal = 0.0f; - bool keyExists; - int i; - bool first = true; - /* Skip if no keyframes to edit. */ if ((fcu->bezt == NULL) || (fcu->totvert < 2)) { return; @@ -1944,74 +1865,32 @@ static void pose_propagate_fcurve( /* Find the reference value from bones directly, which means that the user * doesn't need to firstly keyframe the pose (though this doesn't mean that * they can't either). */ - if (!pose_propagate_get_refVal(ob, fcu, &refVal)) { - return; - } + float refVal = evaluate_fcurve(fcu, start_frame); /* Find the first keyframe to start propagating from: * - if there's a keyframe on the current frame, we probably want to save this value there too * since it may be as of yet un-keyed * - if starting before the starting frame, don't touch the key, as it may have had some valid * values - * - if only doing selected keyframes, start from the first one */ - if (mode != POSE_PROPAGATE_SELECTED_KEYS) { - const int match = BKE_fcurve_bezt_binarysearch_index( - fcu->bezt, startFrame, fcu->totvert, &keyExists); + bool keyExists; + const int match = BKE_fcurve_bezt_binarysearch_index( + fcu->bezt, start_frame, fcu->totvert, &keyExists); - if (fcu->bezt[match].vec[1][0] < startFrame) { - i = match + 1; - } - else { - i = match; - } + int i; + if (fcu->bezt[match].vec[1][0] < start_frame) { + i = match + 1; } else { - /* Selected - start from first keyframe. */ - i = 0; + i = match; } + BezTriple *bezt; for (bezt = &fcu->bezt[i]; i < fcu->totvert; i++, bezt++) { /* Additional termination conditions based on the operator 'mode' property go here. */ - if (ELEM(mode, POSE_PROPAGATE_BEFORE_FRAME, POSE_PROPAGATE_SMART_HOLDS)) { - /* Stop if keyframe is outside the accepted range. */ - if (bezt->vec[1][0] > modeData.end_frame) { - break; - } - } - else if (mode == POSE_PROPAGATE_NEXT_KEY) { - /* Stop after the first keyframe has been processed. */ - if (first == false) { - break; - } - } - else if (mode == POSE_PROPAGATE_LAST_KEY) { - /* Only affect this frame if it will be the last one. */ - if (i != (fcu->totvert - 1)) { - continue; - } - } - else if (mode == POSE_PROPAGATE_SELECTED_MARKERS) { - /* Only allow if there's a marker on this frame. */ - CfraElem *ce = NULL; - - /* Stop on matching marker if there is one. */ - for (ce = modeData.sel_markers.first; ce; ce = ce->next) { - if (ce->cfra == round_fl_to_int(bezt->vec[1][0])) { - break; - } - } - - /* Skip this keyframe if no marker. */ - if (ce == NULL) { - continue; - } - } - else if (mode == POSE_PROPAGATE_SELECTED_KEYS) { - /* Only allow if this keyframe is already selected - skip otherwise. */ - if (BEZT_ISSEL_ANY(bezt) == 0) { - continue; - } + /* Stop if keyframe is outside the accepted range. */ + if (bezt->vec[1][0] > end_frame) { + break; } /* Just flatten handles, since values will now be the same either side. */ @@ -2020,10 +1899,123 @@ static void pose_propagate_fcurve( /* Select keyframe to indicate that it's been changed. */ bezt->f2 |= SELECT; - first = false; } } +typedef struct FrameLink { + struct FrameLink *next, *prev; + float frame; +} FrameLink; + +static void propagate_curve_values(ListBase /*tPChanFCurveLink*/ *pflinks, + const float source_frame, + ListBase /*FrameLink*/ *target_frames) +{ + LISTBASE_FOREACH (tPChanFCurveLink *, pfl, pflinks) { + LISTBASE_FOREACH (LinkData *, ld, &pfl->fcurves) { + FCurve *fcu = (FCurve *)ld->data; + const float current_fcu_value = evaluate_fcurve(fcu, source_frame); + LISTBASE_FOREACH (FrameLink *, target_frame, target_frames) { + insert_vert_fcurve( + fcu, target_frame->frame, current_fcu_value, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NEEDED); + } + } + } +} + +static float find_next_key(ListBase *pflinks, const float start_frame) +{ + float target_frame = FLT_MAX; + LISTBASE_FOREACH (tPChanFCurveLink *, pfl, pflinks) { + LISTBASE_FOREACH (LinkData *, ld, &pfl->fcurves) { + FCurve *fcu = (FCurve *)ld->data; + bool replace; + int current_frame_index = BKE_fcurve_bezt_binarysearch_index( + fcu->bezt, start_frame, fcu->totvert, &replace); + if (replace) { + const int bezt_index = min_ii(current_frame_index + 1, fcu->totvert - 1); + target_frame = min_ff(target_frame, fcu->bezt[bezt_index].vec[1][0]); + } + else { + target_frame = min_ff(target_frame, fcu->bezt[current_frame_index].vec[1][0]); + } + } + } + + return target_frame; +} + +static float find_last_key(ListBase *pflinks) +{ + float target_frame = FLT_MIN; + LISTBASE_FOREACH (tPChanFCurveLink *, pfl, pflinks) { + LISTBASE_FOREACH (LinkData *, ld, &pfl->fcurves) { + FCurve *fcu = (FCurve *)ld->data; + target_frame = max_ff(target_frame, fcu->bezt[fcu->totvert - 1].vec[1][0]); + } + } + + return target_frame; +} + +static void get_selected_marker_positions(Scene *scene, ListBase /*FrameLink*/ *target_frames) +{ + ListBase selected_markers = {NULL, NULL}; + ED_markers_make_cfra_list(&scene->markers, &selected_markers, SELECT); + LISTBASE_FOREACH (CfraElem *, marker, &selected_markers) { + FrameLink *link = MEM_callocN(sizeof(FrameLink), "Marker Key Link"); + link->frame = marker->cfra; + BLI_addtail(target_frames, link); + } + BLI_freelistN(&selected_markers); +} + +static void get_keyed_frames_in_range(ListBase *pflinks, + const float start_frame, + const float end_frame, + ListBase /*FrameLink*/ *target_frames) +{ + struct AnimKeylist *keylist = ED_keylist_create(); + LISTBASE_FOREACH (tPChanFCurveLink *, pfl, pflinks) { + LISTBASE_FOREACH (LinkData *, ld, &pfl->fcurves) { + FCurve *fcu = (FCurve *)ld->data; + fcurve_to_keylist(NULL, fcu, keylist, 0); + } + } + LISTBASE_FOREACH (ActKeyColumn *, column, ED_keylist_listbase(keylist)) { + if (column->cfra <= start_frame) { + continue; + } + if (column->cfra > end_frame) { + break; + } + FrameLink *link = MEM_callocN(sizeof(FrameLink), "Marker Key Link"); + link->frame = column->cfra; + BLI_addtail(target_frames, link); + } + ED_keylist_free(keylist); +} + +static void get_selected_frames(ListBase *pflinks, ListBase /*FrameLink*/ *target_frames) +{ + struct AnimKeylist *keylist = ED_keylist_create(); + LISTBASE_FOREACH (tPChanFCurveLink *, pfl, pflinks) { + LISTBASE_FOREACH (LinkData *, ld, &pfl->fcurves) { + FCurve *fcu = (FCurve *)ld->data; + fcurve_to_keylist(NULL, fcu, keylist, 0); + } + } + LISTBASE_FOREACH (ActKeyColumn *, column, ED_keylist_listbase(keylist)) { + if (!column->sel) { + continue; + } + FrameLink *link = MEM_callocN(sizeof(FrameLink), "Marker Key Link"); + link->frame = column->cfra; + BLI_addtail(target_frames, link); + } + ED_keylist_free(keylist); +} + /* --------------------------------- */ static int pose_propagate_exec(bContext *C, wmOperator *op) @@ -2033,9 +2025,7 @@ static int pose_propagate_exec(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); ListBase pflinks = {NULL, NULL}; - tPChanFCurveLink *pfl; - tPosePropagate_ModeData modeData; const int mode = RNA_enum_get(op->ptr, "mode"); /* Isolate F-Curves related to the selected bones. */ @@ -2049,40 +2039,73 @@ static int pose_propagate_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - /* Mode-specific data preprocessing (requiring no access to curves). */ - if (mode == POSE_PROPAGATE_SELECTED_MARKERS) { - /* Get a list of selected markers. */ - ED_markers_make_cfra_list(&scene->markers, &modeData.sel_markers, SELECT); - } - else { - /* Assume everything else wants endFrame. */ - modeData.end_frame = RNA_float_get(op->ptr, "end_frame"); - } + const float end_frame = RNA_float_get(op->ptr, "end_frame"); + const float current_frame = BKE_scene_frame_get(scene); - /* For each bone, perform the copying required. */ - for (pfl = pflinks.first; pfl; pfl = pfl->next) { - LinkData *ld; + ListBase target_frames = {NULL, NULL}; - /* Mode-specific data preprocessing (requiring access to all curves). */ - if (mode == POSE_PROPAGATE_SMART_HOLDS) { - /* We store in endFrame the end frame of the "long keyframe" (i.e. a held value) starting - * from the keyframe that occurs after the current frame. */ - modeData.end_frame = pose_propagate_get_boneHoldEndFrame(pfl, (float)scene->r.cfra); + switch (mode) { + case POSE_PROPAGATE_NEXT_KEY: { + float target_frame = find_next_key(&pflinks, current_frame); + FrameLink *link = MEM_callocN(sizeof(FrameLink), "Next Key Link"); + link->frame = target_frame; + BLI_addtail(&target_frames, link); + propagate_curve_values(&pflinks, current_frame, &target_frames); + break; } - /* Go through propagating pose to keyframes, curve by curve. */ - for (ld = pfl->fcurves.first; ld; ld = ld->next) { - pose_propagate_fcurve(op, pfl->ob, (FCurve *)ld->data, (float)scene->r.cfra, modeData); + case POSE_PROPAGATE_LAST_KEY: { + float target_frame = find_last_key(&pflinks); + FrameLink *link = MEM_callocN(sizeof(FrameLink), "Last Key Link"); + link->frame = target_frame; + BLI_addtail(&target_frames, link); + propagate_curve_values(&pflinks, current_frame, &target_frames); + break; + } + + case POSE_PROPAGATE_SELECTED_MARKERS: { + get_selected_marker_positions(scene, &target_frames); + propagate_curve_values(&pflinks, current_frame, &target_frames); + break; + } + + case POSE_PROPAGATE_BEFORE_END: { + get_keyed_frames_in_range(&pflinks, current_frame, FLT_MAX, &target_frames); + propagate_curve_values(&pflinks, current_frame, &target_frames); + break; + } + case POSE_PROPAGATE_BEFORE_FRAME: { + get_keyed_frames_in_range(&pflinks, current_frame, end_frame, &target_frames); + propagate_curve_values(&pflinks, current_frame, &target_frames); + break; + } + case POSE_PROPAGATE_SELECTED_KEYS: { + get_selected_frames(&pflinks, &target_frames); + propagate_curve_values(&pflinks, current_frame, &target_frames); + break; + } + case POSE_PROPAGATE_SMART_HOLDS: { + /* For each bone, perform the copying required. */ + LISTBASE_FOREACH (tPChanFCurveLink *, pfl, &pflinks) { + /* Mode-specific data preprocessing (requiring access to all curves). */ + /* We store in endFrame the end frame of the "long keyframe" (i.e. a held value) + * starting from the keyframe that occurs after the current frame. */ + const int smart_end_frame = pose_propagate_get_boneHoldEndFrame(pfl, current_frame); + + /* Go through propagating pose to keyframes, curve by curve. */ + LISTBASE_FOREACH (LinkData *, ld, &pfl->fcurves) { + pose_propagate_fcurve((FCurve *)ld->data, current_frame, smart_end_frame); + } + } + break; } } + BLI_freelistN(&target_frames); + /* Free temp data. */ poseAnim_mapping_free(&pflinks); - if (mode == POSE_PROPAGATE_SELECTED_MARKERS) { - BLI_freelistN(&modeData.sel_markers); - } - /* Updates + notifiers. */ FOREACH_OBJECT_IN_MODE_BEGIN (scene, view_layer, v3d, OB_ARMATURE, OB_MODE_POSE, ob) { poseAnim_mapping_refresh(C, scene, ob); From 963600ddc08b9a8da3380c89ce31617d21dce46c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 5 Jan 2023 11:34:11 +0100 Subject: [PATCH 0422/1522] CMake: when compiler is too old, report found version To aid in debugging the case where your compiler is too old for Blender, actually log which version CMake found. Before, CMake would output: ``` CMake Error at CMakeLists.txt:121 (message): The minimum supported version of GCC is 11.0.0 ``` With the patch, it logs: ``` CMake Error at CMakeLists.txt:121 (message): The minimum supported version of GCC is 11.0.0, found 10.4.0 ``` This has been implemented for GCC and Clang. MSVC has been explicitly excluded, as the version numbers used for this comparison are internal versions and not directly usable/recognisable. Reviewed By: LazyDodo, brecht Differential Revision: https://developer.blender.org/D16849 --- CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 76779726e21..c957ce37df5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,14 +118,18 @@ enable_testing() if(CMAKE_COMPILER_IS_GNUCC) if("${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "11.0.0") - message(FATAL_ERROR "The minimum supported version of GCC is 11.0.0") + message(FATAL_ERROR "The minimum supported version of GCC is 11.0.0, found ${CMAKE_C_COMPILER_VERSION}") endif() elseif(CMAKE_C_COMPILER_ID MATCHES "Clang") if(CMAKE_COMPILER_IS_GNUCC AND ("${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "8.0")) - message(FATAL_ERROR "The minimum supported version of CLANG is 8.0") + message(FATAL_ERROR "The minimum supported version of CLANG is 8.0, found ${CMAKE_C_COMPILER_VERSION}") endif() elseif(CMAKE_CXX_COMPILER_ID MATCHES MSVC) if(MSVC_VERSION VERSION_LESS "1928") + # MSVC_VERSION is an internal version number, it doesn't map to something + # the end user would recognize as a version. Because of this, for MSVC we do + # not show the found number. When using our make.bat the actual VS version + # will be displayed on the console before starting the build, anyway. message(FATAL_ERROR "The minimum supported version of MSVC is 2019 (16.9.16)") endif() endif() From 58b6c91d36dfd0d5b0d81ebbdd76f648285c4967 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 5 Jan 2023 12:21:04 +0100 Subject: [PATCH 0423/1522] Cleanup: Remove unused runtime field from the MovieClip It is a part of old-standing TODO, and code which accesses the value was commented out for many years. Remove the field to help with an upcoming const-correctness improvements. --- source/blender/blenkernel/intern/movieclip.c | 13 +------------ source/blender/makesdna/DNA_movieclip_types.h | 3 +-- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 010dd4a01bf..2e95866d642 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -1344,7 +1344,6 @@ static ImBuf *movieclip_get_postprocessed_ibuf( } if (ibuf) { - clip->lastframe = framenr; real_ibuf_size(clip, user, ibuf, &clip->lastsize[0], &clip->lastsize[1]); /* Post-process frame and put to cache if needed. */ @@ -1566,17 +1565,7 @@ bool BKE_movieclip_has_frame(MovieClip *clip, MovieClipUser *user) void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, int *height) { -#if 0 - /* originally was needed to support image sequences with different image dimensions, - * which might be useful for such things as reconstruction of unordered image sequence, - * or painting/rotoscoping of non-equal-sized images, but this ended up in unneeded - * cache lookups and even unwanted non-proxied files loading when doing mask parenting, - * so let's disable this for now and assume image sequence consists of images with - * equal sizes (sergey) - * TODO(sergey): Support reading sequences of different resolution. - */ - if (user->framenr == clip->lastframe) { -#endif + /* TODO(sergey): Support reading sequences of different resolution. */ if (clip->lastsize[0] != 0 && clip->lastsize[1] != 0) { *width = clip->lastsize[0]; *height = clip->lastsize[1]; diff --git a/source/blender/makesdna/DNA_movieclip_types.h b/source/blender/makesdna/DNA_movieclip_types.h index a262baf6a2b..20da4a6253f 100644 --- a/source/blender/makesdna/DNA_movieclip_types.h +++ b/source/blender/makesdna/DNA_movieclip_types.h @@ -65,8 +65,7 @@ typedef struct MovieClip { /** Sequence or movie. */ int source; - /** Last accessed frame number. */ - int lastframe; + int _pad; /** Size of last accessed frame. */ int lastsize[2]; From fdc918c32c2ef9b392f3d6879485b571118c8db3 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 5 Jan 2023 12:33:55 +0100 Subject: [PATCH 0424/1522] Cleanup: Better const-correctness in MovieClip Mainly make MovieClipUser constant. --- source/blender/blenkernel/BKE_movieclip.h | 28 +++++----- source/blender/blenkernel/intern/movieclip.c | 55 ++++++++++++-------- 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h index 4667aa17131..fb68847f210 100644 --- a/source/blender/blenkernel/BKE_movieclip.h +++ b/source/blender/blenkernel/BKE_movieclip.h @@ -39,40 +39,42 @@ void BKE_movieclip_clear_proxy_cache(struct MovieClip *clip); */ void BKE_movieclip_convert_multilayer_ibuf(struct ImBuf *ibuf); -struct ImBuf *BKE_movieclip_get_ibuf(struct MovieClip *clip, struct MovieClipUser *user); +struct ImBuf *BKE_movieclip_get_ibuf(struct MovieClip *clip, const struct MovieClipUser *user); struct ImBuf *BKE_movieclip_get_postprocessed_ibuf(struct MovieClip *clip, - struct MovieClipUser *user, + const struct MovieClipUser *user, int postprocess_flag); struct ImBuf *BKE_movieclip_get_stable_ibuf(struct MovieClip *clip, - struct MovieClipUser *user, + const struct MovieClipUser *user, float loc[2], float *scale, float *angle, int postprocess_flag); struct ImBuf *BKE_movieclip_get_ibuf_flag(struct MovieClip *clip, - struct MovieClipUser *user, + const struct MovieClipUser *user, int flag, int cache_flag); void BKE_movieclip_get_size(struct MovieClip *clip, - struct MovieClipUser *user, + const struct MovieClipUser *user, int *width, int *height); -void BKE_movieclip_get_size_fl(struct MovieClip *clip, struct MovieClipUser *user, float size[2]); +void BKE_movieclip_get_size_fl(struct MovieClip *clip, + const struct MovieClipUser *user, + float size[2]); int BKE_movieclip_get_duration(struct MovieClip *clip); float BKE_movieclip_get_fps(struct MovieClip *clip); void BKE_movieclip_get_aspect(struct MovieClip *clip, float *aspx, float *aspy); -bool BKE_movieclip_has_frame(struct MovieClip *clip, struct MovieClipUser *user); +bool BKE_movieclip_has_frame(struct MovieClip *clip, const struct MovieClipUser *user); void BKE_movieclip_user_set_frame(struct MovieClipUser *user, int framenr); void BKE_movieclip_update_scopes(struct MovieClip *clip, - struct MovieClipUser *user, + const struct MovieClipUser *user, struct MovieClipScopes *scopes); /** * Get segments of cached frames. useful for debugging cache policies. */ void BKE_movieclip_get_cache_segments(struct MovieClip *clip, - struct MovieClipUser *user, + const struct MovieClipUser *user, int *r_totseg, int **r_points); @@ -105,7 +107,7 @@ float BKE_movieclip_remap_scene_to_clip_frame(const struct MovieClip *clip, floa float BKE_movieclip_remap_clip_to_scene_frame(const struct MovieClip *clip, float framenr); void BKE_movieclip_filename_for_frame(struct MovieClip *clip, - struct MovieClipUser *user, + const struct MovieClipUser *user, char *name); /** @@ -113,11 +115,11 @@ void BKE_movieclip_filename_for_frame(struct MovieClip *clip, * Used by a prefetch job which takes care of creating a local copy of the clip. */ struct ImBuf *BKE_movieclip_anim_ibuf_for_frame_no_lock(struct MovieClip *clip, - struct MovieClipUser *user); + const struct MovieClipUser *user); -bool BKE_movieclip_has_cached_frame(struct MovieClip *clip, struct MovieClipUser *user); +bool BKE_movieclip_has_cached_frame(struct MovieClip *clip, const struct MovieClipUser *user); bool BKE_movieclip_put_frame_if_possible(struct MovieClip *clip, - struct MovieClipUser *user, + const struct MovieClipUser *user, struct ImBuf *ibuf); struct GPUTexture *BKE_movieclip_get_gpu_texture(struct MovieClip *clip, diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 2e95866d642..726f5591703 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -884,7 +884,7 @@ static ImBuf *get_imbuf_cache(MovieClip *clip, const MovieClipUser *user, int fl return NULL; } -static bool has_imbuf_cache(MovieClip *clip, MovieClipUser *user, int flag) +static bool has_imbuf_cache(MovieClip *clip, const MovieClipUser *user, int flag) { if (clip->cache) { MovieClipImBufCacheKey key; @@ -1372,25 +1372,31 @@ static ImBuf *movieclip_get_postprocessed_ibuf( return ibuf; } -ImBuf *BKE_movieclip_get_ibuf(MovieClip *clip, MovieClipUser *user) +ImBuf *BKE_movieclip_get_ibuf(MovieClip *clip, const MovieClipUser *user) { return BKE_movieclip_get_ibuf_flag(clip, user, clip->flag, 0); } -ImBuf *BKE_movieclip_get_ibuf_flag(MovieClip *clip, MovieClipUser *user, int flag, int cache_flag) +ImBuf *BKE_movieclip_get_ibuf_flag(MovieClip *clip, + const MovieClipUser *user, + const int flag, + const int cache_flag) { return movieclip_get_postprocessed_ibuf(clip, user, flag, 0, cache_flag); } ImBuf *BKE_movieclip_get_postprocessed_ibuf(MovieClip *clip, - MovieClipUser *user, - int postprocess_flag) + const MovieClipUser *user, + const int postprocess_flag) { return movieclip_get_postprocessed_ibuf(clip, user, clip->flag, postprocess_flag, 0); } -static ImBuf *get_stable_cached_frame( - MovieClip *clip, MovieClipUser *user, ImBuf *reference_ibuf, int framenr, int postprocess_flag) +static ImBuf *get_stable_cached_frame(MovieClip *clip, + const MovieClipUser *user, + ImBuf *reference_ibuf, + const int framenr, + const int postprocess_flag) { MovieClipCache *cache = clip->cache; MovieTracking *tracking = &clip->tracking; @@ -1448,8 +1454,11 @@ static ImBuf *get_stable_cached_frame( return stableibuf; } -static ImBuf *put_stabilized_frame_to_cache( - MovieClip *clip, MovieClipUser *user, ImBuf *ibuf, int framenr, int postprocess_flag) +static ImBuf *put_stabilized_frame_to_cache(MovieClip *clip, + const MovieClipUser *user, + ImBuf *ibuf, + const int framenr, + const int postprocess_flag) { MovieClipCache *cache = clip->cache; MovieTracking *tracking = &clip->tracking; @@ -1491,11 +1500,11 @@ static ImBuf *put_stabilized_frame_to_cache( } ImBuf *BKE_movieclip_get_stable_ibuf(MovieClip *clip, - MovieClipUser *user, + const MovieClipUser *user, float loc[2], float *scale, float *angle, - int postprocess_flag) + const int postprocess_flag) { ImBuf *ibuf, *stableibuf = NULL; int framenr = user->framenr; @@ -1551,7 +1560,7 @@ ImBuf *BKE_movieclip_get_stable_ibuf(MovieClip *clip, return ibuf; } -bool BKE_movieclip_has_frame(MovieClip *clip, MovieClipUser *user) +bool BKE_movieclip_has_frame(MovieClip *clip, const MovieClipUser *user) { ImBuf *ibuf = BKE_movieclip_get_ibuf(clip, user); @@ -1563,7 +1572,7 @@ bool BKE_movieclip_has_frame(MovieClip *clip, MovieClipUser *user) return false; } -void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, int *height) +void BKE_movieclip_get_size(MovieClip *clip, const MovieClipUser *user, int *width, int *height) { /* TODO(sergey): Support reading sequences of different resolution. */ if (clip->lastsize[0] != 0 && clip->lastsize[1] != 0) { @@ -1586,7 +1595,7 @@ void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, in } } } -void BKE_movieclip_get_size_fl(MovieClip *clip, MovieClipUser *user, float size[2]) +void BKE_movieclip_get_size_fl(MovieClip *clip, const MovieClipUser *user, float size[2]) { int width, height; BKE_movieclip_get_size(clip, user, &width, &height); @@ -1630,7 +1639,7 @@ void BKE_movieclip_get_aspect(MovieClip *clip, float *aspx, float *aspy) } void BKE_movieclip_get_cache_segments(MovieClip *clip, - MovieClipUser *user, + const MovieClipUser *user, int *r_totseg, int **r_points) { @@ -1717,7 +1726,9 @@ void BKE_movieclip_reload(Main *bmain, MovieClip *clip) BKE_ntree_update_tag_id_changed(bmain, &clip->id); } -void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes) +void BKE_movieclip_update_scopes(MovieClip *clip, + const MovieClipUser *user, + MovieClipScopes *scopes) { if (scopes->ok) { return; @@ -1934,17 +1945,17 @@ bool BKE_movieclip_proxy_enabled(MovieClip *clip) return clip->flag & MCLIP_USE_PROXY; } -float BKE_movieclip_remap_scene_to_clip_frame(const MovieClip *clip, float framenr) +float BKE_movieclip_remap_scene_to_clip_frame(const MovieClip *clip, const float framenr) { return framenr - (float)clip->start_frame + 1.0f; } -float BKE_movieclip_remap_clip_to_scene_frame(const MovieClip *clip, float framenr) +float BKE_movieclip_remap_clip_to_scene_frame(const MovieClip *clip, const float framenr) { return framenr + (float)clip->start_frame - 1.0f; } -void BKE_movieclip_filename_for_frame(MovieClip *clip, MovieClipUser *user, char *name) +void BKE_movieclip_filename_for_frame(MovieClip *clip, const MovieClipUser *user, char *name) { if (clip->source == MCLIP_SRC_SEQUENCE) { int use_proxy; @@ -1966,7 +1977,7 @@ void BKE_movieclip_filename_for_frame(MovieClip *clip, MovieClipUser *user, char } } -ImBuf *BKE_movieclip_anim_ibuf_for_frame_no_lock(MovieClip *clip, MovieClipUser *user) +ImBuf *BKE_movieclip_anim_ibuf_for_frame_no_lock(MovieClip *clip, const MovieClipUser *user) { ImBuf *ibuf = NULL; @@ -1977,7 +1988,7 @@ ImBuf *BKE_movieclip_anim_ibuf_for_frame_no_lock(MovieClip *clip, MovieClipUser return ibuf; } -bool BKE_movieclip_has_cached_frame(MovieClip *clip, MovieClipUser *user) +bool BKE_movieclip_has_cached_frame(MovieClip *clip, const MovieClipUser *user) { bool has_frame = false; @@ -1988,7 +1999,7 @@ bool BKE_movieclip_has_cached_frame(MovieClip *clip, MovieClipUser *user) return has_frame; } -bool BKE_movieclip_put_frame_if_possible(MovieClip *clip, MovieClipUser *user, ImBuf *ibuf) +bool BKE_movieclip_put_frame_if_possible(MovieClip *clip, const MovieClipUser *user, ImBuf *ibuf) { bool result; From 4813c37ae245ba454fd66e42e4b7d5001ab7604d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 5 Jan 2023 12:38:42 +0100 Subject: [PATCH 0425/1522] Cleanup: Better const-correctness in the space clip --- source/blender/editors/include/ED_clip.h | 58 ++++++++++--------- .../blender/editors/space_clip/clip_editor.c | 50 +++++++++------- 2 files changed, 60 insertions(+), 48 deletions(-) diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h index 0f981e270a0..73dd05c0366 100644 --- a/source/blender/editors/include/ED_clip.h +++ b/source/blender/editors/include/ED_clip.h @@ -69,73 +69,79 @@ bool ED_space_clip_maskedit_mask_poll(struct bContext *C); * - Mask has visible and editable splines. */ bool ED_space_clip_maskedit_mask_visible_splines_poll(struct bContext *C); -void ED_space_clip_get_size(struct SpaceClip *sc, int *width, int *height); -void ED_space_clip_get_size_fl(struct SpaceClip *sc, float size[2]); -void ED_space_clip_get_zoom(struct SpaceClip *sc, - struct ARegion *region, +void ED_space_clip_get_size(const struct SpaceClip *sc, int *width, int *height); +void ED_space_clip_get_size_fl(const struct SpaceClip *sc, float size[2]); +void ED_space_clip_get_zoom(const struct SpaceClip *sc, + const struct ARegion *region, float *zoomx, float *zoomy); -void ED_space_clip_get_aspect(struct SpaceClip *sc, float *aspx, float *aspy); -void ED_space_clip_get_aspect_dimension_aware(struct SpaceClip *sc, float *aspx, float *aspy); +void ED_space_clip_get_aspect(const struct SpaceClip *sc, float *aspx, float *aspy); +void ED_space_clip_get_aspect_dimension_aware(const struct SpaceClip *sc, + float *aspx, + float *aspy); /** * Return current frame number in clip space. */ -int ED_space_clip_get_clip_frame_number(struct SpaceClip *sc); +int ED_space_clip_get_clip_frame_number(const struct SpaceClip *sc); -struct ImBuf *ED_space_clip_get_buffer(struct SpaceClip *sc); -struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, +struct ImBuf *ED_space_clip_get_buffer(const struct SpaceClip *sc); +struct ImBuf *ED_space_clip_get_stable_buffer(const struct SpaceClip *sc, float loc[2], float *scale, float *angle); -bool ED_space_clip_get_position(struct SpaceClip *sc, - struct ARegion *region, +bool ED_space_clip_get_position(const struct SpaceClip *sc, + const struct ARegion *region, int mval[2], float fpos[2]); /** * Returns color in linear space, matching #ED_space_image_color_sample(). */ -bool ED_space_clip_color_sample(struct SpaceClip *sc, - struct ARegion *region, +bool ED_space_clip_color_sample(const struct SpaceClip *sc, + const struct ARegion *region, const int mval[2], float r_col[3]); void ED_clip_update_frame(const struct Main *mainp, int cfra); -bool ED_clip_view_selection(const struct bContext *C, struct ARegion *region, bool fit); +bool ED_clip_view_selection(const struct bContext *C, const struct ARegion *region, bool fit); -void ED_clip_select_all(struct SpaceClip *sc, int action, bool *r_has_selection); +void ED_clip_select_all(const struct SpaceClip *sc, int action, bool *r_has_selection); bool ED_clip_can_select(struct bContext *C); -void ED_clip_point_undistorted_pos(struct SpaceClip *sc, const float co[2], float r_co[2]); -void ED_clip_point_stable_pos( - struct SpaceClip *sc, struct ARegion *region, float x, float y, float *xr, float *yr); +void ED_clip_point_undistorted_pos(const struct SpaceClip *sc, const float co[2], float r_co[2]); +void ED_clip_point_stable_pos(const struct SpaceClip *sc, + const struct ARegion *region, + float x, + float y, + float *xr, + float *yr); /** * \brief the reverse of #ED_clip_point_stable_pos(), gets the marker region coords. * better name here? view_to_track / track_to_view or so? */ -void ED_clip_point_stable_pos__reverse(struct SpaceClip *sc, - struct ARegion *region, +void ED_clip_point_stable_pos__reverse(const struct SpaceClip *sc, + const struct ARegion *region, const float co[2], float r_co[2]); /** * Takes `event->mval`. */ -void ED_clip_mouse_pos(struct SpaceClip *sc, - struct ARegion *region, +void ED_clip_mouse_pos(const struct SpaceClip *sc, + const struct ARegion *region, const int mval[2], float co[2]); -bool ED_space_clip_check_show_trackedit(struct SpaceClip *sc); -bool ED_space_clip_check_show_maskedit(struct SpaceClip *sc); +bool ED_space_clip_check_show_trackedit(const struct SpaceClip *sc); +bool ED_space_clip_check_show_maskedit(const struct SpaceClip *sc); -struct MovieClip *ED_space_clip_get_clip(struct SpaceClip *sc); +struct MovieClip *ED_space_clip_get_clip(const struct SpaceClip *sc); void ED_space_clip_set_clip(struct bContext *C, struct bScreen *screen, struct SpaceClip *sc, struct MovieClip *clip); -struct Mask *ED_space_clip_get_mask(struct SpaceClip *sc); +struct Mask *ED_space_clip_get_mask(const struct SpaceClip *sc); void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask); /* Locked state is used to preserve current clip editor viewport upon changes. Example usage: diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 3f28f409fd1..5ebc41d9cc7 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -143,7 +143,7 @@ bool ED_space_clip_maskedit_mask_visible_splines_poll(bContext *C) /** \name Common Editing Functions * \{ */ -void ED_space_clip_get_size(SpaceClip *sc, int *width, int *height) +void ED_space_clip_get_size(const SpaceClip *sc, int *width, int *height) { if (sc->clip) { BKE_movieclip_get_size(sc->clip, &sc->user, width, height); @@ -153,7 +153,7 @@ void ED_space_clip_get_size(SpaceClip *sc, int *width, int *height) } } -void ED_space_clip_get_size_fl(SpaceClip *sc, float size[2]) +void ED_space_clip_get_size_fl(const SpaceClip *sc, float size[2]) { int size_i[2]; ED_space_clip_get_size(sc, &size_i[0], &size_i[1]); @@ -161,7 +161,7 @@ void ED_space_clip_get_size_fl(SpaceClip *sc, float size[2]) size[1] = size_i[1]; } -void ED_space_clip_get_zoom(SpaceClip *sc, ARegion *region, float *zoomx, float *zoomy) +void ED_space_clip_get_zoom(const SpaceClip *sc, const ARegion *region, float *zoomx, float *zoomy) { int width, height; @@ -173,7 +173,7 @@ void ED_space_clip_get_zoom(SpaceClip *sc, ARegion *region, float *zoomx, float (BLI_rctf_size_y(®ion->v2d.cur) * height); } -void ED_space_clip_get_aspect(SpaceClip *sc, float *aspx, float *aspy) +void ED_space_clip_get_aspect(const SpaceClip *sc, float *aspx, float *aspy) { MovieClip *clip = ED_space_clip_get_clip(sc); @@ -194,7 +194,7 @@ void ED_space_clip_get_aspect(SpaceClip *sc, float *aspx, float *aspy) } } -void ED_space_clip_get_aspect_dimension_aware(SpaceClip *sc, float *aspx, float *aspy) +void ED_space_clip_get_aspect_dimension_aware(const SpaceClip *sc, float *aspx, float *aspy) { int w, h; @@ -228,7 +228,7 @@ void ED_space_clip_get_aspect_dimension_aware(SpaceClip *sc, float *aspx, float } } -int ED_space_clip_get_clip_frame_number(SpaceClip *sc) +int ED_space_clip_get_clip_frame_number(const SpaceClip *sc) { MovieClip *clip = ED_space_clip_get_clip(sc); @@ -236,7 +236,7 @@ int ED_space_clip_get_clip_frame_number(SpaceClip *sc) return BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr); } -ImBuf *ED_space_clip_get_buffer(SpaceClip *sc) +ImBuf *ED_space_clip_get_buffer(const SpaceClip *sc) { if (sc->clip) { ImBuf *ibuf; @@ -255,7 +255,10 @@ ImBuf *ED_space_clip_get_buffer(SpaceClip *sc) return NULL; } -ImBuf *ED_space_clip_get_stable_buffer(SpaceClip *sc, float loc[2], float *scale, float *angle) +ImBuf *ED_space_clip_get_stable_buffer(const SpaceClip *sc, + float loc[2], + float *scale, + float *angle) { if (sc->clip) { ImBuf *ibuf; @@ -275,8 +278,8 @@ ImBuf *ED_space_clip_get_stable_buffer(SpaceClip *sc, float loc[2], float *scale return NULL; } -bool ED_space_clip_get_position(struct SpaceClip *sc, - struct ARegion *region, +bool ED_space_clip_get_position(const SpaceClip *sc, + const ARegion *region, int mval[2], float fpos[2]) { @@ -292,7 +295,10 @@ bool ED_space_clip_get_position(struct SpaceClip *sc, return true; } -bool ED_space_clip_color_sample(SpaceClip *sc, ARegion *region, const int mval[2], float r_col[3]) +bool ED_space_clip_color_sample(const SpaceClip *sc, + const ARegion *region, + const int mval[2], + float r_col[3]) { ImBuf *ibuf; float fx, fy, co[2]; @@ -355,7 +361,7 @@ void ED_clip_update_frame(const Main *mainp, int cfra) } } -bool ED_clip_view_selection(const bContext *C, ARegion *UNUSED(region), bool fit) +bool ED_clip_view_selection(const bContext *C, const ARegion *UNUSED(region), bool fit) { float offset_x, offset_y; float zoom; @@ -371,7 +377,7 @@ bool ED_clip_view_selection(const bContext *C, ARegion *UNUSED(region), bool fit return true; } -void ED_clip_select_all(SpaceClip *sc, int action, bool *r_has_selection) +void ED_clip_select_all(const SpaceClip *sc, int action, bool *r_has_selection) { MovieClip *clip = ED_space_clip_get_clip(sc); const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(&clip->tracking); @@ -460,7 +466,7 @@ void ED_clip_select_all(SpaceClip *sc, int action, bool *r_has_selection) } } -void ED_clip_point_undistorted_pos(SpaceClip *sc, const float co[2], float r_co[2]) +void ED_clip_point_undistorted_pos(const SpaceClip *sc, const float co[2], float r_co[2]) { copy_v2_v2(r_co, co); @@ -482,7 +488,7 @@ void ED_clip_point_undistorted_pos(SpaceClip *sc, const float co[2], float r_co[ } void ED_clip_point_stable_pos( - SpaceClip *sc, ARegion *region, float x, float y, float *xr, float *yr) + const SpaceClip *sc, const ARegion *region, float x, float y, float *xr, float *yr) { int sx, sy, width, height; float zoomx, zoomy, pos[3], imat[4][4]; @@ -515,8 +521,8 @@ void ED_clip_point_stable_pos( } } -void ED_clip_point_stable_pos__reverse(SpaceClip *sc, - ARegion *region, +void ED_clip_point_stable_pos__reverse(const SpaceClip *sc, + const ARegion *region, const float co[2], float r_co[2]) { @@ -539,12 +545,12 @@ void ED_clip_point_stable_pos__reverse(SpaceClip *sc, r_co[1] = (pos[1] * height * zoomy) + (float)sy; } -void ED_clip_mouse_pos(SpaceClip *sc, ARegion *region, const int mval[2], float co[2]) +void ED_clip_mouse_pos(const SpaceClip *sc, const ARegion *region, const int mval[2], float co[2]) { ED_clip_point_stable_pos(sc, region, mval[0], mval[1], &co[0], &co[1]); } -bool ED_space_clip_check_show_trackedit(SpaceClip *sc) +bool ED_space_clip_check_show_trackedit(const SpaceClip *sc) { if (sc) { return sc->mode == SC_MODE_TRACKING; @@ -553,7 +559,7 @@ bool ED_space_clip_check_show_trackedit(SpaceClip *sc) return false; } -bool ED_space_clip_check_show_maskedit(SpaceClip *sc) +bool ED_space_clip_check_show_maskedit(const SpaceClip *sc) { if (sc) { return sc->mode == SC_MODE_MASKEDIT; @@ -568,7 +574,7 @@ bool ED_space_clip_check_show_maskedit(SpaceClip *sc) /** \name Clip Editing Functions * \{ */ -MovieClip *ED_space_clip_get_clip(SpaceClip *sc) +MovieClip *ED_space_clip_get_clip(const SpaceClip *sc) { return sc->clip; } @@ -629,7 +635,7 @@ void ED_space_clip_set_clip(bContext *C, bScreen *screen, SpaceClip *sc, MovieCl /** \name Masking Editing Functions * \{ */ -Mask *ED_space_clip_get_mask(SpaceClip *sc) +Mask *ED_space_clip_get_mask(const SpaceClip *sc) { return sc->mask_info.mask; } From 2ffd08e95249df2a068dd400cd3117cf8ca4a246 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 5 Jan 2023 14:05:30 +0100 Subject: [PATCH 0426/1522] Geometry Nodes: deterministic anonymous attribute lifetimes Previously, the lifetimes of anonymous attributes were determined by reference counts which were non-deterministic when multiple threads are used. Now the lifetimes of anonymous attributes are handled more explicitly and deterministically. This is a prerequisite for any kind of caching, because caching the output of nodes that do things non-deterministically and have "invisible inputs" (reference counts) doesn't really work. For more details for how deterministic lifetimes are achieved, see D16858. No functional changes are expected. Small performance changes are expected as well (within few percent, anything larger regressions should be reported as bugs). Differential Revision: https://developer.blender.org/D16858 --- .../blenkernel/BKE_anonymous_attribute.h | 29 - .../blenkernel/BKE_anonymous_attribute.hh | 155 -- .../blenkernel/BKE_anonymous_attribute_id.hh | 103 ++ source/blender/blenkernel/BKE_attribute.hh | 42 +- .../blender/blenkernel/BKE_curve_to_mesh.hh | 8 +- source/blender/blenkernel/BKE_curves.hh | 6 +- source/blender/blenkernel/BKE_customdata.h | 5 +- .../blender/blenkernel/BKE_geometry_fields.hh | 17 +- source/blender/blenkernel/BKE_geometry_set.hh | 3 +- source/blender/blenkernel/BKE_instances.hh | 3 +- source/blender/blenkernel/BKE_node_runtime.hh | 13 +- source/blender/blenkernel/CMakeLists.txt | 6 +- .../blenkernel/intern/anonymous_attribute.cc | 105 -- .../intern/anonymous_attribute_id.cc | 18 + .../blenkernel/intern/attribute_access.cc | 42 +- .../intern/attribute_access_intern.hh | 12 +- source/blender/blenkernel/intern/cpp_types.cc | 4 + .../intern/curve_to_mesh_convert.cc | 21 +- .../blenkernel/intern/curves_geometry.cc | 44 +- .../blender/blenkernel/intern/customdata.cc | 26 +- .../intern/geometry_component_mesh.cc | 6 +- .../blenkernel/intern/geometry_fields.cc | 5 +- .../blender/blenkernel/intern/geometry_set.cc | 4 +- source/blender/blenkernel/intern/instances.cc | 5 +- .../blender/blenkernel/intern/mesh_convert.cc | 4 +- source/blender/blenkernel/intern/node.cc | 5 + .../intern/node_tree_anonymous_attributes.cc | 452 +++++ .../blenkernel/intern/node_tree_update.cc | 3 + source/blender/editors/mesh/mesh_data.cc | 3 +- .../functions/FN_lazy_function_graph.hh | 54 + .../functions/intern/lazy_function_graph.cc | 37 + source/blender/geometry/GEO_fillet_curves.hh | 22 +- .../blender/geometry/GEO_mesh_split_edges.hh | 6 +- source/blender/geometry/GEO_mesh_to_curve.hh | 15 +- .../geometry/GEO_point_merge_by_distance.hh | 10 +- .../blender/geometry/GEO_realize_instances.hh | 2 + .../blender/geometry/GEO_resample_curves.hh | 2 +- source/blender/geometry/GEO_set_curve_type.hh | 3 +- .../blender/geometry/GEO_subdivide_curves.hh | 8 +- source/blender/geometry/GEO_trim_curves.hh | 3 +- .../geometry/intern/add_curves_on_mesh.cc | 2 +- .../blender/geometry/intern/fillet_curves.cc | 45 +- .../geometry/intern/mesh_split_edges.cc | 24 +- .../geometry/intern/mesh_to_curve_convert.cc | 19 +- .../intern/point_merge_by_distance.cc | 5 +- .../geometry/intern/realize_instances.cc | 21 +- .../geometry/intern/resample_curves.cc | 4 +- .../blender/geometry/intern/set_curve_type.cc | 21 +- .../geometry/intern/subdivide_curves.cc | 15 +- source/blender/geometry/intern/trim_curves.cc | 27 +- .../blender/makesdna/DNA_customdata_types.h | 18 +- source/blender/modifiers/intern/MOD_nodes.cc | 44 +- source/blender/nodes/NOD_geometry_exec.hh | 75 +- .../nodes/NOD_geometry_nodes_lazy_function.hh | 49 +- .../nodes/geometry/node_geometry_util.hh | 9 +- .../nodes/node_geo_attribute_capture.cc | 12 +- .../nodes/geometry/nodes/node_geo_boolean.cc | 7 +- .../geometry/nodes/node_geo_curve_fillet.cc | 12 +- .../nodes/node_geo_curve_primitive_star.cc | 12 +- .../nodes/node_geo_curve_spline_type.cc | 3 +- .../nodes/node_geo_curve_subdivide.cc | 2 +- .../geometry/nodes/node_geo_curve_to_mesh.cc | 12 +- .../nodes/node_geo_curve_to_points.cc | 19 +- .../geometry/nodes/node_geo_curve_trim.cc | 14 +- .../nodes/node_geo_delete_geometry.cc | 53 +- .../node_geo_distribute_points_on_faces.cc | 19 +- .../geometry/nodes/node_geo_dual_mesh.cc | 13 +- .../nodes/node_geo_duplicate_elements.cc | 126 +- .../nodes/node_geo_edge_paths_to_curves.cc | 15 +- .../geometry/nodes/node_geo_edge_split.cc | 3 +- .../geometry/nodes/node_geo_extrude_mesh.cc | 14 +- .../nodes/node_geo_instance_on_points.cc | 7 +- .../nodes/node_geo_instances_to_points.cc | 7 +- .../geometry/nodes/node_geo_join_geometry.cc | 23 +- .../nodes/node_geo_merge_by_distance.cc | 14 +- .../nodes/node_geo_mesh_primitive_cone.cc | 16 +- .../nodes/node_geo_mesh_primitive_cube.cc | 6 +- .../nodes/node_geo_mesh_primitive_cylinder.cc | 16 +- .../nodes/node_geo_mesh_primitive_grid.cc | 6 +- .../node_geo_mesh_primitive_ico_sphere.cc | 6 +- .../node_geo_mesh_primitive_uv_sphere.cc | 6 +- .../geometry/nodes/node_geo_mesh_to_curve.cc | 3 +- .../geometry/nodes/node_geo_mesh_to_points.cc | 47 +- .../nodes/node_geo_points_to_vertices.cc | 16 +- .../nodes/node_geo_realize_instances.cc | 1 + .../nodes/node_geo_separate_geometry.cc | 47 +- .../nodes/node_geo_string_to_curves.cc | 16 +- .../intern/geometry_nodes_lazy_function.cc | 1538 ++++++++++++++++- .../nodes/intern/geometry_nodes_log.cc | 2 +- .../nodes/intern/node_geometry_exec.cc | 23 + 90 files changed, 3003 insertions(+), 822 deletions(-) delete mode 100644 source/blender/blenkernel/BKE_anonymous_attribute.h delete mode 100644 source/blender/blenkernel/BKE_anonymous_attribute.hh create mode 100644 source/blender/blenkernel/BKE_anonymous_attribute_id.hh delete mode 100644 source/blender/blenkernel/intern/anonymous_attribute.cc create mode 100644 source/blender/blenkernel/intern/anonymous_attribute_id.cc create mode 100644 source/blender/blenkernel/intern/node_tree_anonymous_attributes.cc diff --git a/source/blender/blenkernel/BKE_anonymous_attribute.h b/source/blender/blenkernel/BKE_anonymous_attribute.h deleted file mode 100644 index ab26f2c6224..00000000000 --- a/source/blender/blenkernel/BKE_anonymous_attribute.h +++ /dev/null @@ -1,29 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -/** \file - * \ingroup bke - * - * An #AnonymousAttributeID is used to identify attributes that are not explicitly named. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct AnonymousAttributeID AnonymousAttributeID; - -AnonymousAttributeID *BKE_anonymous_attribute_id_new_weak(const char *debug_name); -AnonymousAttributeID *BKE_anonymous_attribute_id_new_strong(const char *debug_name); -bool BKE_anonymous_attribute_id_has_strong_references(const AnonymousAttributeID *anonymous_id); -void BKE_anonymous_attribute_id_increment_weak(const AnonymousAttributeID *anonymous_id); -void BKE_anonymous_attribute_id_increment_strong(const AnonymousAttributeID *anonymous_id); -void BKE_anonymous_attribute_id_decrement_weak(const AnonymousAttributeID *anonymous_id); -void BKE_anonymous_attribute_id_decrement_strong(const AnonymousAttributeID *anonymous_id); -const char *BKE_anonymous_attribute_id_debug_name(const AnonymousAttributeID *anonymous_id); -const char *BKE_anonymous_attribute_id_internal_name(const AnonymousAttributeID *anonymous_id); - -#ifdef __cplusplus -} -#endif diff --git a/source/blender/blenkernel/BKE_anonymous_attribute.hh b/source/blender/blenkernel/BKE_anonymous_attribute.hh deleted file mode 100644 index d9161bda572..00000000000 --- a/source/blender/blenkernel/BKE_anonymous_attribute.hh +++ /dev/null @@ -1,155 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#pragma once - -#include -#include - -#include "BLI_hash.hh" -#include "BLI_string_ref.hh" - -#include "BKE_anonymous_attribute.h" - -namespace blender::bke { - -/** - * Wrapper for #AnonymousAttributeID with RAII semantics. - * This class should typically not be used directly. Instead use #StrongAnonymousAttributeID or - * #WeakAnonymousAttributeID. - */ -template class OwnedAnonymousAttributeID { - private: - const AnonymousAttributeID *data_ = nullptr; - - template friend class OwnedAnonymousAttributeID; - - public: - OwnedAnonymousAttributeID() = default; - - /** Create a new anonymous attribute id. */ - explicit OwnedAnonymousAttributeID(StringRefNull debug_name) - { - if constexpr (IsStrongReference) { - data_ = BKE_anonymous_attribute_id_new_strong(debug_name.c_str()); - } - else { - data_ = BKE_anonymous_attribute_id_new_weak(debug_name.c_str()); - } - } - - /** - * This transfers ownership, so no incref is necessary. - * The caller has to make sure that it owned the anonymous id. - */ - explicit OwnedAnonymousAttributeID(const AnonymousAttributeID *anonymous_id) - : data_(anonymous_id) - { - } - - template - OwnedAnonymousAttributeID(const OwnedAnonymousAttributeID &other) - { - data_ = other.data_; - this->incref(); - } - - template - OwnedAnonymousAttributeID(OwnedAnonymousAttributeID &&other) - { - data_ = other.data_; - this->incref(); - other.decref(); - other.data_ = nullptr; - } - - ~OwnedAnonymousAttributeID() - { - this->decref(); - } - - template - OwnedAnonymousAttributeID &operator=(const OwnedAnonymousAttributeID &other) - { - if (this == &other) { - return *this; - } - this->~OwnedAnonymousAttributeID(); - new (this) OwnedAnonymousAttributeID(other); - return *this; - } - - template - OwnedAnonymousAttributeID &operator=(OwnedAnonymousAttributeID &&other) - { - if (this == &other) { - return *this; - } - this->~OwnedAnonymousAttributeID(); - new (this) OwnedAnonymousAttributeID(std::move(other)); - return *this; - } - - operator bool() const - { - return data_ != nullptr; - } - - StringRefNull debug_name() const - { - BLI_assert(data_ != nullptr); - return BKE_anonymous_attribute_id_debug_name(data_); - } - - bool has_strong_references() const - { - BLI_assert(data_ != nullptr); - return BKE_anonymous_attribute_id_has_strong_references(data_); - } - - /** Extract the ownership of the currently wrapped anonymous id. */ - const AnonymousAttributeID *extract() - { - const AnonymousAttributeID *extracted_data = data_; - /* Don't decref because the caller becomes the new owner. */ - data_ = nullptr; - return extracted_data; - } - - /** Get the wrapped anonymous id, without taking ownership. */ - const AnonymousAttributeID *get() const - { - return data_; - } - - private: - void incref() - { - if (data_ == nullptr) { - return; - } - if constexpr (IsStrongReference) { - BKE_anonymous_attribute_id_increment_strong(data_); - } - else { - BKE_anonymous_attribute_id_increment_weak(data_); - } - } - - void decref() - { - if (data_ == nullptr) { - return; - } - if constexpr (IsStrongReference) { - BKE_anonymous_attribute_id_decrement_strong(data_); - } - else { - BKE_anonymous_attribute_id_decrement_weak(data_); - } - } -}; - -using StrongAnonymousAttributeID = OwnedAnonymousAttributeID; -using WeakAnonymousAttributeID = OwnedAnonymousAttributeID; - -} // namespace blender::bke diff --git a/source/blender/blenkernel/BKE_anonymous_attribute_id.hh b/source/blender/blenkernel/BKE_anonymous_attribute_id.hh new file mode 100644 index 00000000000..f9b6e2ca543 --- /dev/null +++ b/source/blender/blenkernel/BKE_anonymous_attribute_id.hh @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include + +#include "BLI_set.hh" +#include "BLI_string_ref.hh" +#include "BLI_user_counter.hh" + +namespace blender::bke { + +/** + * An #AnonymousAttributeID contains information about a specific anonymous attribute. + * Like normal attributes, anonymous attributes are also identified by their name, so one should + * not have to compare #AnonymousAttributeID pointers. + * + * Anonymous attributes don't need additional information besides their name, with a few + * exceptions: + * - The name of anonymous attributes is generated automatically, so it is generally not human + * readable (just random characters). #AnonymousAttributeID can provide more context as where a + * specific anonymous attribute was created which can simplify debugging. + * - [Not yet supported.] When anonymous attributes are contained in on-disk caches, we have to map + * those back to anonymous attributes at run-time. The issue is that (for various reasons) we + * might change how anonymous attribute names are generated in the future, which would lead to a + * mis-match between stored and new attribute names. To work around it, we should cache + * additional information for anonymous attributes on disk (like which node created it). This + * information can then be used to map stored attributes to their run-time counterpart. + * + * Once created, #AnonymousAttributeID is immutable. Also it is intrinsicly reference counted so + * that it can have shared ownership. `std::shared_ptr` can't be used for that purpose here, + * because that is not available in C code. If possible, the #AutoAnonymousAttributeID wrapper + * should be used to avoid manual reference counting in C++ code. + */ +class AnonymousAttributeID { + private: + mutable std::atomic users_ = 1; + + protected: + std::string name_; + + public: + virtual ~AnonymousAttributeID() = default; + + StringRefNull name() const + { + return name_; + } + + void user_add() const + { + users_.fetch_add(1); + } + + void user_remove() const + { + const int new_users = users_.fetch_sub(1) - 1; + if (new_users == 0) { + MEM_delete(this); + } + } +}; + +/** Wrapper for #AnonymousAttributeID that avoids manual reference counting. */ +using AutoAnonymousAttributeID = UserCounter; + +/** + * A set of anonymous attribute names that is passed around in geometry nodes. + */ +class AnonymousAttributeSet { + public: + /** + * This uses `std::shared_ptr` because attributes sets are passed around by value during geometry + * nodes evaluation, and this makes it very small if there is no name. Also it makes copying very + * cheap. + */ + std::shared_ptr> names; +}; + +/** + * Can be passed to algorithms which propagate attributes. It can tell the algorithm which + * anonymous attributes should be propagated and can be skipped. + */ +class AnonymousAttributePropagationInfo { + public: + /** + * This uses `std::shared_ptr` because it's usually initialized from an #AnonymousAttributeSet + * and then the set doesn't have to be copied. + */ + std::shared_ptr> names; + + /** + * Propagate all anonymous attributes even if the set above is empty. + */ + bool propagate_all = true; + + /** + * Return true when the anonymous attribute should be propagated and false otherwise. + */ + bool propagate(const AnonymousAttributeID &anonymous_id) const; +}; + +} // namespace blender::bke diff --git a/source/blender/blenkernel/BKE_attribute.hh b/source/blender/blenkernel/BKE_attribute.hh index a4f9d73c31e..031a4bb86ea 100644 --- a/source/blender/blenkernel/BKE_attribute.hh +++ b/source/blender/blenkernel/BKE_attribute.hh @@ -11,7 +11,7 @@ #include "BLI_math_vec_types.hh" #include "BLI_set.hh" -#include "BKE_anonymous_attribute.hh" +#include "BKE_anonymous_attribute_id.hh" #include "BKE_attribute.h" struct Mesh; @@ -24,7 +24,7 @@ class GField; namespace blender::bke { /** - * Identifies an attribute that is either named or anonymous. + * Identifies an attribute with optional anonymous attribute information. * It does not own the identifier, so it is just a reference. */ class AttributeIDRef { @@ -38,15 +38,14 @@ class AttributeIDRef { AttributeIDRef(StringRefNull name); AttributeIDRef(const char *name); AttributeIDRef(const std::string &name); + AttributeIDRef(const AnonymousAttributeID &anonymous_id); AttributeIDRef(const AnonymousAttributeID *anonymous_id); operator bool() const; uint64_t hash() const; - bool is_named() const; bool is_anonymous() const; StringRef name() const; const AnonymousAttributeID &anonymous_id() const; - bool should_be_kept() const; friend bool operator==(const AttributeIDRef &a, const AttributeIDRef &b); friend std::ostream &operator<<(std::ostream &stream, const AttributeIDRef &attribute_id); @@ -749,6 +748,7 @@ Vector retrieve_attributes_for_transfer( const bke::AttributeAccessor src_attributes, bke::MutableAttributeAccessor dst_attributes, eAttrDomainMask domain_mask, + const AnonymousAttributePropagationInfo &propagation_info, const Set &skip = {}); /** @@ -762,6 +762,7 @@ void copy_attribute_domain(AttributeAccessor src_attributes, MutableAttributeAccessor dst_attributes, IndexMask selection, eAttrDomain domain, + const AnonymousAttributePropagationInfo &propagation_info, const Set &skip = {}); bool allow_procedural_attribute_access(StringRef attribute_name); @@ -852,29 +853,31 @@ inline AttributeIDRef::AttributeIDRef(const std::string &name) : name_(name) } /* The anonymous id is only borrowed, the caller has to keep a reference to it. */ -inline AttributeIDRef::AttributeIDRef(const AnonymousAttributeID *anonymous_id) - : anonymous_id_(anonymous_id) +inline AttributeIDRef::AttributeIDRef(const AnonymousAttributeID &anonymous_id) + : AttributeIDRef(anonymous_id.name()) { + anonymous_id_ = &anonymous_id; +} + +inline AttributeIDRef::AttributeIDRef(const AnonymousAttributeID *anonymous_id) + : AttributeIDRef(anonymous_id ? anonymous_id->name() : "") +{ + anonymous_id_ = anonymous_id; } inline bool operator==(const AttributeIDRef &a, const AttributeIDRef &b) { - return a.anonymous_id_ == b.anonymous_id_ && a.name_ == b.name_; + return a.name_ == b.name_; } inline AttributeIDRef::operator bool() const { - return this->is_named() || this->is_anonymous(); + return !name_.is_empty(); } inline uint64_t AttributeIDRef::hash() const { - return get_default_hash_2(name_, anonymous_id_); -} - -inline bool AttributeIDRef::is_named() const -{ - return !name_.is_empty(); + return get_default_hash(name_); } inline bool AttributeIDRef::is_anonymous() const @@ -884,7 +887,6 @@ inline bool AttributeIDRef::is_anonymous() const inline StringRef AttributeIDRef::name() const { - BLI_assert(this->is_named()); return name_; } @@ -894,14 +896,4 @@ inline const AnonymousAttributeID &AttributeIDRef::anonymous_id() const return *anonymous_id_; } -/** - * \return True if the attribute should not be removed automatically as an optimization during - * processing or copying. Anonymous attributes can be removed when they no longer have any - * references. - */ -inline bool AttributeIDRef::should_be_kept() const -{ - return this->is_named() || BKE_anonymous_attribute_id_has_strong_references(anonymous_id_); -} - } // namespace blender::bke diff --git a/source/blender/blenkernel/BKE_curve_to_mesh.hh b/source/blender/blenkernel/BKE_curve_to_mesh.hh index 6e657542e0f..0f67da2d8a5 100644 --- a/source/blender/blenkernel/BKE_curve_to_mesh.hh +++ b/source/blender/blenkernel/BKE_curve_to_mesh.hh @@ -11,6 +11,8 @@ struct Mesh; namespace blender::bke { +class AnonymousAttributePropagationInfo; + /** * Extrude all splines in the profile curve along the path of every spline in the curve input. * Transfer curve attributes to the mesh. @@ -23,11 +25,13 @@ namespace blender::bke { */ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, const CurvesGeometry &profile, - bool fill_caps); + bool fill_caps, + const AnonymousAttributePropagationInfo &propagation_info); /** * Create a loose-edge mesh based on the evaluated path of the curve's splines. * Transfer curve attributes to the mesh. */ -Mesh *curve_to_wire_mesh(const CurvesGeometry &curve); +Mesh *curve_to_wire_mesh(const CurvesGeometry &curve, + const AnonymousAttributePropagationInfo &propagation_info); } // namespace blender::bke diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index 31776676940..9f849584710 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -404,8 +404,10 @@ class CurvesGeometry : public ::CurvesGeometry { void calculate_bezier_auto_handles(); - void remove_points(IndexMask points_to_delete); - void remove_curves(IndexMask curves_to_delete); + void remove_points(IndexMask points_to_delete, + const AnonymousAttributePropagationInfo &propagation_info = {}); + void remove_curves(IndexMask curves_to_delete, + const AnonymousAttributePropagationInfo &propagation_info = {}); /** * Change the direction of selected curves (switch the start and end) without changing their diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 1cdd3c02d8d..582dd1b5a29 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -23,7 +23,6 @@ extern "C" { #endif -struct AnonymousAttributeID; struct BMesh; struct BlendDataReader; struct BlendWriter; @@ -227,7 +226,7 @@ void *CustomData_add_layer_anonymous(struct CustomData *data, eCDAllocType alloctype, void *layer, int totelem, - const struct AnonymousAttributeID *anonymous_id); + const AnonymousAttributeIDHandle *anonymous_id); /** * Frees the active or first data layer with the give type. @@ -275,8 +274,6 @@ void *CustomData_duplicate_referenced_layer_named(struct CustomData *data, int type, const char *name, int totelem); -void *CustomData_duplicate_referenced_layer_anonymous( - CustomData *data, int type, const struct AnonymousAttributeID *anonymous_id, int totelem); bool CustomData_is_referenced_layer(struct CustomData *data, int type); /** diff --git a/source/blender/blenkernel/BKE_geometry_fields.hh b/source/blender/blenkernel/BKE_geometry_fields.hh index 7b493ea5ca9..967bb912cc6 100644 --- a/source/blender/blenkernel/BKE_geometry_fields.hh +++ b/source/blender/blenkernel/BKE_geometry_fields.hh @@ -261,18 +261,14 @@ class NormalFieldInput : public GeometryFieldInput { class AnonymousAttributeFieldInput : public GeometryFieldInput { private: - /** - * A strong reference is required to make sure that the referenced attribute is not removed - * automatically. - */ - StrongAnonymousAttributeID anonymous_id_; + AutoAnonymousAttributeID anonymous_id_; std::string producer_name_; public: - AnonymousAttributeFieldInput(StrongAnonymousAttributeID anonymous_id, + AnonymousAttributeFieldInput(AutoAnonymousAttributeID anonymous_id, const CPPType &type, std::string producer_name) - : GeometryFieldInput(type, anonymous_id.debug_name()), + : GeometryFieldInput(type, anonymous_id->name()), anonymous_id_(std::move(anonymous_id)), producer_name_(producer_name) { @@ -280,7 +276,7 @@ class AnonymousAttributeFieldInput : public GeometryFieldInput { } template - static fn::Field Create(StrongAnonymousAttributeID anonymous_id, std::string producer_name) + static fn::Field Create(AutoAnonymousAttributeID anonymous_id, std::string producer_name) { const CPPType &type = CPPType::get(); auto field_input = std::make_shared( @@ -288,6 +284,11 @@ class AnonymousAttributeFieldInput : public GeometryFieldInput { return fn::Field{field_input}; } + const AutoAnonymousAttributeID &anonymous_id() const + { + return anonymous_id_; + } + GVArray get_varray_for_context(const GeometryFieldContext &context, IndexMask mask) const override; diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh index b488806c8e7..e6f55a8500f 100644 --- a/source/blender/blenkernel/BKE_geometry_set.hh +++ b/source/blender/blenkernel/BKE_geometry_set.hh @@ -19,7 +19,7 @@ #include "BLI_user_counter.hh" #include "BLI_vector_set.hh" -#include "BKE_anonymous_attribute.hh" +#include "BKE_anonymous_attribute_id.hh" #include "BKE_attribute.hh" #include "BKE_geometry_set.h" @@ -213,6 +213,7 @@ struct GeometrySet { blender::Span component_types, GeometryComponentType dst_component_type, bool include_instances, + const blender::bke::AnonymousAttributePropagationInfo &propagation_info, blender::Map &r_attributes) const; blender::Vector gather_component_types(bool include_instances, diff --git a/source/blender/blenkernel/BKE_instances.hh b/source/blender/blenkernel/BKE_instances.hh index f17ebba0dfa..3d44e3a4686 100644 --- a/source/blender/blenkernel/BKE_instances.hh +++ b/source/blender/blenkernel/BKE_instances.hh @@ -155,7 +155,8 @@ class Instances { * Remove the indices that are not contained in the mask input, and remove unused instance * references afterwards. */ - void remove(const blender::IndexMask mask); + void remove(const blender::IndexMask mask, + const blender::bke::AnonymousAttributePropagationInfo &propagation_info); /** * Get an id for every instance. These can be used for e.g. motion blur. */ diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 6941bcb023a..ca2fa5d0b01 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -7,6 +7,7 @@ #include "BLI_cache_mutex.hh" #include "BLI_multi_value_map.hh" +#include "BLI_resource_scope.hh" #include "BLI_utility_mixins.hh" #include "BLI_vector.hh" #include "BLI_vector_set.hh" @@ -24,6 +25,10 @@ namespace blender::nodes { struct FieldInferencingInterface; class NodeDeclaration; struct GeometryNodesLazyFunctionGraphInfo; +namespace anonymous_attribute_lifetime { +struct RelationsInNode; +} +namespace aal = anonymous_attribute_lifetime; } // namespace blender::nodes namespace blender { @@ -106,6 +111,8 @@ class bNodeTreeRuntime : NonCopyable, NonMovable { /** Information about how inputs and outputs of the node group interact with fields. */ std::unique_ptr field_inferencing_interface; + /** Information about usage of anonymous attributes within the group. */ + std::unique_ptr anonymous_attribute_relations; /** * For geometry nodes, a lazy function graph with some additional info is cached. This is used to @@ -330,7 +337,11 @@ inline bool topology_cache_is_available(const bNodeSocket &socket) namespace node_field_inferencing { bool update_field_inferencing(const bNodeTree &tree); } - +namespace anonymous_attribute_inferencing { +Array get_relations_by_node(const bNodeTree &tree, + ResourceScope &scope); +bool update_anonymous_attribute_relations(bNodeTree &tree); +} // namespace anonymous_attribute_inferencing } // namespace blender::bke /* -------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index bfd9eaaa23e..101baf1e983 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -64,7 +64,7 @@ set(SRC intern/anim_path.c intern/anim_sys.c intern/anim_visualization.c - intern/anonymous_attribute.cc + intern/anonymous_attribute_id.cc intern/appdir.c intern/armature.c intern/armature_deform.c @@ -229,6 +229,7 @@ set(SRC intern/nla.c intern/node.cc intern/node_runtime.cc + intern/node_tree_anonymous_attributes.cc intern/node_tree_field_inferencing.cc intern/node_tree_update.cc intern/object.cc @@ -315,8 +316,7 @@ set(SRC BKE_anim_path.h BKE_anim_visualization.h BKE_animsys.h - BKE_anonymous_attribute.h - BKE_anonymous_attribute.hh + BKE_anonymous_attribute_id.hh BKE_appdir.h BKE_armature.h BKE_armature.hh diff --git a/source/blender/blenkernel/intern/anonymous_attribute.cc b/source/blender/blenkernel/intern/anonymous_attribute.cc deleted file mode 100644 index 636e0af0edf..00000000000 --- a/source/blender/blenkernel/intern/anonymous_attribute.cc +++ /dev/null @@ -1,105 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "BKE_anonymous_attribute.hh" - -using namespace blender::bke; - -/** - * A struct that identifies an attribute. It's lifetime is managed by an atomic reference count. - * - * Additionally, this struct can be strongly or weakly owned. The difference is that strong - * ownership means that attributes with this id will be kept around. Weak ownership just makes sure - * that the struct itself stays alive, but corresponding attributes might still be removed - * automatically. - */ -struct AnonymousAttributeID { - /** - * Total number of references to this attribute id. Once this reaches zero, the struct can be - * freed. This includes strong and weak references. - */ - mutable std::atomic refcount_tot = 0; - - /** - * Number of strong references to this attribute id. When this is zero, the corresponding - * attributes can be removed from geometries automatically. - */ - mutable std::atomic refcount_strong = 0; - - /** - * Only used to identify this struct in a debugging session. - */ - std::string debug_name; - - /** - * Unique name of the this attribute id during the current session. - */ - std::string internal_name; -}; - -/** Every time this function is called, it outputs a different name. */ -static std::string get_new_internal_name() -{ - static std::atomic index = 0; - const int next_index = index.fetch_add(1); - return ".a_" + std::to_string(next_index); -} - -AnonymousAttributeID *BKE_anonymous_attribute_id_new_weak(const char *debug_name) -{ - AnonymousAttributeID *anonymous_id = new AnonymousAttributeID(); - anonymous_id->debug_name = debug_name; - anonymous_id->internal_name = get_new_internal_name(); - anonymous_id->refcount_tot.store(1); - return anonymous_id; -} - -AnonymousAttributeID *BKE_anonymous_attribute_id_new_strong(const char *debug_name) -{ - AnonymousAttributeID *anonymous_id = new AnonymousAttributeID(); - anonymous_id->debug_name = debug_name; - anonymous_id->internal_name = get_new_internal_name(); - anonymous_id->refcount_tot.store(1); - anonymous_id->refcount_strong.store(1); - return anonymous_id; -} - -bool BKE_anonymous_attribute_id_has_strong_references(const AnonymousAttributeID *anonymous_id) -{ - return anonymous_id->refcount_strong.load() >= 1; -} - -void BKE_anonymous_attribute_id_increment_weak(const AnonymousAttributeID *anonymous_id) -{ - anonymous_id->refcount_tot.fetch_add(1); -} - -void BKE_anonymous_attribute_id_increment_strong(const AnonymousAttributeID *anonymous_id) -{ - anonymous_id->refcount_tot.fetch_add(1); - anonymous_id->refcount_strong.fetch_add(1); -} - -void BKE_anonymous_attribute_id_decrement_weak(const AnonymousAttributeID *anonymous_id) -{ - const int new_refcount = anonymous_id->refcount_tot.fetch_sub(1) - 1; - if (new_refcount == 0) { - BLI_assert(anonymous_id->refcount_strong == 0); - delete anonymous_id; - } -} - -void BKE_anonymous_attribute_id_decrement_strong(const AnonymousAttributeID *anonymous_id) -{ - anonymous_id->refcount_strong.fetch_sub(1); - BKE_anonymous_attribute_id_decrement_weak(anonymous_id); -} - -const char *BKE_anonymous_attribute_id_debug_name(const AnonymousAttributeID *anonymous_id) -{ - return anonymous_id->debug_name.c_str(); -} - -const char *BKE_anonymous_attribute_id_internal_name(const AnonymousAttributeID *anonymous_id) -{ - return anonymous_id->internal_name.c_str(); -} diff --git a/source/blender/blenkernel/intern/anonymous_attribute_id.cc b/source/blender/blenkernel/intern/anonymous_attribute_id.cc new file mode 100644 index 00000000000..e15ea6b643c --- /dev/null +++ b/source/blender/blenkernel/intern/anonymous_attribute_id.cc @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BKE_anonymous_attribute_id.hh" + +namespace blender::bke { + +bool AnonymousAttributePropagationInfo::propagate(const AnonymousAttributeID &anonymous_id) const +{ + if (this->propagate_all) { + return true; + } + if (!this->names) { + return false; + } + return this->names->contains_as(anonymous_id.name()); +} + +} // namespace blender::bke diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index e5c43a3f90e..a5dbc4645fb 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -40,13 +40,9 @@ namespace blender::bke { std::ostream &operator<<(std::ostream &stream, const AttributeIDRef &attribute_id) { - if (attribute_id.is_named()) { + if (attribute_id) { stream << attribute_id.name(); } - else if (attribute_id.is_anonymous()) { - const AnonymousAttributeID &anonymous_id = attribute_id.anonymous_id(); - stream << "<" << BKE_anonymous_attribute_id_debug_name(&anonymous_id) << ">"; - } else { stream << ""; } @@ -153,7 +149,7 @@ eAttrDomain attribute_domain_highest_priority(Span domains) static AttributeIDRef attribute_id_from_custom_data_layer(const CustomDataLayer &layer) { if (layer.anonymous_id != nullptr) { - return layer.anonymous_id; + return *layer.anonymous_id; } return layer.name; } @@ -207,7 +203,7 @@ static void *add_generic_custom_data_layer(CustomData &custom_data, const int domain_num, const AttributeIDRef &attribute_id) { - if (attribute_id.is_named()) { + if (!attribute_id.is_anonymous()) { char attribute_name_c[MAX_NAME]; attribute_id.name().copy(attribute_name_c); return CustomData_add_layer_named( @@ -261,9 +257,6 @@ static bool custom_data_layer_matches_attribute_id(const CustomDataLayer &layer, if (!attribute_id) { return false; } - if (attribute_id.is_anonymous()) { - return layer.anonymous_id == &attribute_id.anonymous_id(); - } return layer.name == attribute_id.name(); } @@ -451,14 +444,8 @@ GAttributeWriter CustomDataAttributeProvider::try_get_for_write( if (!custom_data_layer_matches_attribute_id(layer, attribute_id)) { continue; } - if (attribute_id.is_named()) { - CustomData_duplicate_referenced_layer_named( - custom_data, layer.type, layer.name, element_num); - } - else { - CustomData_duplicate_referenced_layer_anonymous( - custom_data, layer.type, &attribute_id.anonymous_id(), element_num); - } + CustomData_duplicate_referenced_layer_named(custom_data, layer.type, layer.name, element_num); + const CPPType *type = custom_data_type_to_cpp_type((eCustomDataType)layer.type); if (type == nullptr) { continue; @@ -854,7 +841,7 @@ void MutableAttributeAccessor::remove_anonymous() } while (!anonymous_ids.is_empty()) { - this->remove(anonymous_ids.pop_last()); + this->remove(*anonymous_ids.pop_last()); } } @@ -883,12 +870,7 @@ GAttributeWriter MutableAttributeAccessor::lookup_for_write(const AttributeIDRef #ifdef DEBUG if (attribute) { auto checker = std::make_shared(); - if (attribute_id.is_named()) { - checker->name = attribute_id.name(); - } - else { - checker->name = BKE_anonymous_attribute_id_debug_name(&attribute_id.anonymous_id()); - } + checker->name = attribute_id.name(); checker->real_finish_fn = attribute.tag_modified_fn; attribute.tag_modified_fn = [checker]() { if (checker->real_finish_fn) { @@ -968,6 +950,7 @@ Vector retrieve_attributes_for_transfer( const bke::AttributeAccessor src_attributes, bke::MutableAttributeAccessor dst_attributes, const eAttrDomainMask domain_mask, + const AnonymousAttributePropagationInfo &propagation_info, const Set &skip) { Vector attributes; @@ -976,10 +959,10 @@ Vector retrieve_attributes_for_transfer( if (!(ATTR_DOMAIN_AS_MASK(meta_data.domain) & domain_mask)) { return true; } - if (id.is_named() && skip.contains(id.name())) { + if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) { return true; } - if (!id.should_be_kept()) { + if (skip.contains(id.name())) { return true; } @@ -999,6 +982,7 @@ void copy_attribute_domain(const AttributeAccessor src_attributes, MutableAttributeAccessor dst_attributes, const IndexMask selection, const eAttrDomain domain, + const AnonymousAttributePropagationInfo &propagation_info, const Set &skip) { src_attributes.for_all( @@ -1006,10 +990,10 @@ void copy_attribute_domain(const AttributeAccessor src_attributes, if (meta_data.domain != domain) { return true; } - if (id.is_named() && skip.contains(id.name())) { + if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) { return true; } - if (!id.should_be_kept()) { + if (skip.contains(id.name())) { return true; } diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh index 5ab7c6aadf3..ccf9ae83182 100644 --- a/source/blender/blenkernel/intern/attribute_access_intern.hh +++ b/source/blender/blenkernel/intern/attribute_access_intern.hh @@ -336,7 +336,7 @@ namespace attribute_accessor_functions { template inline bool is_builtin(const void * /*owner*/, const AttributeIDRef &attribute_id) { - if (!attribute_id.is_named()) { + if (attribute_id.is_anonymous()) { return false; } const StringRef name = attribute_id.name(); @@ -346,7 +346,7 @@ inline bool is_builtin(const void * /*owner*/, const AttributeIDRef &attribute_i template inline GAttributeReader lookup(const void *owner, const AttributeIDRef &attribute_id) { - if (attribute_id.is_named()) { + if (!attribute_id.is_anonymous()) { const StringRef name = attribute_id.name(); if (const BuiltinAttributeProvider *provider = providers.builtin_attribute_providers().lookup_default_as(name, nullptr)) { @@ -396,7 +396,7 @@ template inline AttributeValidator lookup_validator(const void * /*owner*/, const blender::bke::AttributeIDRef &attribute_id) { - if (!attribute_id.is_named()) { + if (attribute_id.is_anonymous()) { return {}; } const BuiltinAttributeProvider *provider = @@ -443,7 +443,7 @@ inline std::optional lookup_meta_data(const void *owner, template inline GAttributeWriter lookup_for_write(void *owner, const AttributeIDRef &attribute_id) { - if (attribute_id.is_named()) { + if (!attribute_id.is_anonymous()) { const StringRef name = attribute_id.name(); if (const BuiltinAttributeProvider *provider = providers.builtin_attribute_providers().lookup_default_as(name, nullptr)) { @@ -462,7 +462,7 @@ inline GAttributeWriter lookup_for_write(void *owner, const AttributeIDRef &attr template inline bool remove(void *owner, const AttributeIDRef &attribute_id) { - if (attribute_id.is_named()) { + if (!attribute_id.is_anonymous()) { const StringRef name = attribute_id.name(); if (const BuiltinAttributeProvider *provider = providers.builtin_attribute_providers().lookup_default_as(name, nullptr)) { @@ -487,7 +487,7 @@ inline bool add(void *owner, if (contains(owner, attribute_id)) { return false; } - if (attribute_id.is_named()) { + if (!attribute_id.is_anonymous()) { const StringRef name = attribute_id.name(); if (const BuiltinAttributeProvider *provider = providers.builtin_attribute_providers().lookup_default_as(name, nullptr)) { diff --git a/source/blender/blenkernel/intern/cpp_types.cc b/source/blender/blenkernel/intern/cpp_types.cc index e6b33dd5b1a..d1f2c5efa55 100644 --- a/source/blender/blenkernel/intern/cpp_types.cc +++ b/source/blender/blenkernel/intern/cpp_types.cc @@ -28,6 +28,8 @@ BLI_CPP_TYPE_MAKE(Material *, CPPTypeFlags::BasicType) BLI_CPP_TYPE_MAKE(MStringProperty, CPPTypeFlags::None); +BLI_CPP_TYPE_MAKE(blender::bke::AnonymousAttributeSet, CPPTypeFlags::None); + void BKE_cpp_types_init() { blender::register_cpp_types(); @@ -45,4 +47,6 @@ void BKE_cpp_types_init() BLI_CPP_TYPE_REGISTER(Material *); BLI_CPP_TYPE_REGISTER(MStringProperty); + + BLI_CPP_TYPE_REGISTER(blender::bke::AnonymousAttributeSet); } diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index e5cafd405df..14c41811505 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -331,18 +331,19 @@ static eAttrDomain get_attribute_domain_for_mesh(const AttributeAccessor &mesh_a static bool should_add_attribute_to_mesh(const AttributeAccessor &curve_attributes, const AttributeAccessor &mesh_attributes, const AttributeIDRef &id, - const AttributeMetaData &meta_data) + const AttributeMetaData &meta_data, + const AnonymousAttributePropagationInfo &propagation_info) { /* The position attribute has special non-generic evaluation. */ - if (id.is_named() && id.name() == "position") { + if (id.name() == "position") { return false; } /* Don't propagate built-in curves attributes that are not built-in on meshes. */ if (curve_attributes.is_builtin(id) && !mesh_attributes.is_builtin(id)) { return false; } - if (!id.should_be_kept()) { + if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) { return false; } if (meta_data.data_type == CD_PROP_STRING) { @@ -629,7 +630,8 @@ static void copy_curve_domain_attribute_to_mesh(const ResultOffsets &mesh_offset Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, const CurvesGeometry &profile, - const bool fill_caps) + const bool fill_caps, + const AnonymousAttributePropagationInfo &propagation_info) { const CurvesInfo curves_info = get_curves_info(main, profile); @@ -716,7 +718,8 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, MutableAttributeAccessor mesh_attributes = mesh->attributes_for_write(); main_attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) { - if (!should_add_attribute_to_mesh(main_attributes, mesh_attributes, id, meta_data)) { + if (!should_add_attribute_to_mesh( + main_attributes, mesh_attributes, id, meta_data, propagation_info)) { return true; } main_attributes_set.add_new(id); @@ -753,7 +756,8 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, if (main_attributes.contains(id)) { return true; } - if (!should_add_attribute_to_mesh(profile_attributes, mesh_attributes, id, meta_data)) { + if (!should_add_attribute_to_mesh( + profile_attributes, mesh_attributes, id, meta_data, propagation_info)) { return true; } const eAttrDomain src_domain = meta_data.domain; @@ -797,10 +801,11 @@ static CurvesGeometry get_curve_single_vert() return curves; } -Mesh *curve_to_wire_mesh(const CurvesGeometry &curve) +Mesh *curve_to_wire_mesh(const CurvesGeometry &curve, + const AnonymousAttributePropagationInfo &propagation_info) { static const CurvesGeometry vert_curve = get_curve_single_vert(); - return curve_to_mesh_sweep(curve, vert_curve, false); + return curve_to_mesh_sweep(curve, vert_curve, false, propagation_info); } } // namespace blender::bke diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 401dd113f2c..835b6728e99 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -1047,8 +1047,10 @@ static Array build_point_to_curve_map(const CurvesGeometry &curves) return point_to_curve_map; } -static CurvesGeometry copy_with_removed_points(const CurvesGeometry &curves, - const IndexMask points_to_delete) +static CurvesGeometry copy_with_removed_points( + const CurvesGeometry &curves, + const IndexMask points_to_delete, + const AnonymousAttributePropagationInfo &propagation_info) { /* Use a map from points to curves to facilitate using an #IndexMask input. */ const Array point_to_curve_map = build_point_to_curve_map(curves); @@ -1093,9 +1095,15 @@ static CurvesGeometry copy_with_removed_points(const CurvesGeometry &curves, CurvesGeometry new_curves{new_point_count, new_curve_count}; Vector point_attributes = bke::retrieve_attributes_for_transfer( - curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_POINT); + curves.attributes(), + new_curves.attributes_for_write(), + ATTR_DOMAIN_MASK_POINT, + propagation_info); Vector curve_attributes = bke::retrieve_attributes_for_transfer( - curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_CURVE); + curves.attributes(), + new_curves.attributes_for_write(), + ATTR_DOMAIN_MASK_CURVE, + propagation_info); threading::parallel_invoke( 256 < new_point_count * new_curve_count, @@ -1144,7 +1152,8 @@ static CurvesGeometry copy_with_removed_points(const CurvesGeometry &curves, return new_curves; } -void CurvesGeometry::remove_points(const IndexMask points_to_delete) +void CurvesGeometry::remove_points(const IndexMask points_to_delete, + const AnonymousAttributePropagationInfo &propagation_info) { if (points_to_delete.is_empty()) { return; @@ -1152,11 +1161,13 @@ void CurvesGeometry::remove_points(const IndexMask points_to_delete) if (points_to_delete.size() == this->points_num()) { *this = {}; } - *this = copy_with_removed_points(*this, points_to_delete); + *this = copy_with_removed_points(*this, points_to_delete, propagation_info); } -static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves, - const IndexMask curves_to_delete) +static CurvesGeometry copy_with_removed_curves( + const CurvesGeometry &curves, + const IndexMask curves_to_delete, + const AnonymousAttributePropagationInfo &propagation_info) { const Span old_offsets = curves.offsets(); const Vector old_curve_ranges = curves_to_delete.extract_ranges_invert( @@ -1178,9 +1189,15 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves, CurvesGeometry new_curves{new_tot_points, new_tot_curves}; Vector point_attributes = bke::retrieve_attributes_for_transfer( - curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_POINT); + curves.attributes(), + new_curves.attributes_for_write(), + ATTR_DOMAIN_MASK_POINT, + propagation_info); Vector curve_attributes = bke::retrieve_attributes_for_transfer( - curves.attributes(), new_curves.attributes_for_write(), ATTR_DOMAIN_MASK_CURVE); + curves.attributes(), + new_curves.attributes_for_write(), + ATTR_DOMAIN_MASK_CURVE, + propagation_info); threading::parallel_invoke( 256 < new_tot_points * new_tot_curves, @@ -1251,7 +1268,8 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves, return new_curves; } -void CurvesGeometry::remove_curves(const IndexMask curves_to_delete) +void CurvesGeometry::remove_curves(const IndexMask curves_to_delete, + const AnonymousAttributePropagationInfo &propagation_info) { if (curves_to_delete.is_empty()) { return; @@ -1260,7 +1278,7 @@ void CurvesGeometry::remove_curves(const IndexMask curves_to_delete) *this = {}; return; } - *this = copy_with_removed_curves(*this, curves_to_delete); + *this = copy_with_removed_curves(*this, curves_to_delete, propagation_info); } template @@ -1315,7 +1333,7 @@ void CurvesGeometry::reverse_curves(const IndexMask curves_to_reverse) if (meta_data.data_type == CD_PROP_STRING) { return true; } - if (id.is_named() && bezier_handle_names.contains(id.name())) { + if (bezier_handle_names.contains(id.name())) { return true; } diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index cb22f4a650c..60d38895a89 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -39,7 +39,7 @@ #include "BLT_translation.h" -#include "BKE_anonymous_attribute.h" +#include "BKE_anonymous_attribute_id.hh" #include "BKE_customdata.h" #include "BKE_customdata_file.h" #include "BKE_deform.h" @@ -2356,7 +2356,7 @@ bool CustomData_merge(const CustomData *source, layer->anonymous_id = nullptr; } else { - BKE_anonymous_attribute_id_increment_weak(layer->anonymous_id); + layer->anonymous_id->user_add(); } } if (alloctype == CD_ASSIGN) { @@ -2460,7 +2460,7 @@ static void customData_free_layer__internal(CustomDataLayer *layer, const int to const LayerTypeInfo *typeInfo; if (layer->anonymous_id != nullptr) { - BKE_anonymous_attribute_id_decrement_weak(layer->anonymous_id); + layer->anonymous_id->user_remove(); layer->anonymous_id = nullptr; } if (!(layer->flag & CD_FLAG_NOFREE) && layer->data) { @@ -2957,9 +2957,9 @@ void *CustomData_add_layer_anonymous(CustomData *data, const eCDAllocType alloctype, void *layerdata, const int totelem, - const AnonymousAttributeID *anonymous_id) + const AnonymousAttributeIDHandle *anonymous_id) { - const char *name = BKE_anonymous_attribute_id_internal_name(anonymous_id); + const char *name = anonymous_id->name().c_str(); CustomDataLayer *layer = customData_add_layer__internal( data, type, alloctype, layerdata, totelem, name); CustomData_update_typemap(data); @@ -2968,7 +2968,7 @@ void *CustomData_add_layer_anonymous(CustomData *data, return nullptr; } - BKE_anonymous_attribute_id_increment_weak(anonymous_id); + anonymous_id->user_add(); layer->anonymous_id = anonymous_id; return layer->data; } @@ -3147,20 +3147,6 @@ void *CustomData_duplicate_referenced_layer_named(CustomData *data, return customData_duplicate_referenced_layer_index(data, layer_index, totelem); } -void *CustomData_duplicate_referenced_layer_anonymous(CustomData *data, - const int /*type*/, - const AnonymousAttributeID *anonymous_id, - const int totelem) -{ - for (int i = 0; i < data->totlayer; i++) { - if (data->layers[i].anonymous_id == anonymous_id) { - return customData_duplicate_referenced_layer_index(data, i, totelem); - } - } - BLI_assert_unreachable(); - return nullptr; -} - void CustomData_duplicate_referenced_layers(CustomData *data, const int totelem) { for (int i = 0; i < data->totlayer; i++) { diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index b9702466d17..855d422251d 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -1055,7 +1055,7 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider { GAttributeReader try_get_for_read(const void *owner, const AttributeIDRef &attribute_id) const final { - if (!attribute_id.is_named()) { + if (attribute_id.is_anonymous()) { return {}; } const Mesh *mesh = static_cast(owner); @@ -1079,7 +1079,7 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider { GAttributeWriter try_get_for_write(void *owner, const AttributeIDRef &attribute_id) const final { - if (!attribute_id.is_named()) { + if (attribute_id.is_anonymous()) { return {}; } Mesh *mesh = static_cast(owner); @@ -1100,7 +1100,7 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider { bool try_delete(void *owner, const AttributeIDRef &attribute_id) const final { - if (!attribute_id.is_named()) { + if (attribute_id.is_anonymous()) { return false; } Mesh *mesh = static_cast(owner); diff --git a/source/blender/blenkernel/intern/geometry_fields.cc b/source/blender/blenkernel/intern/geometry_fields.cc index 82ffda57398..6fe822d6dc6 100644 --- a/source/blender/blenkernel/intern/geometry_fields.cc +++ b/source/blender/blenkernel/intern/geometry_fields.cc @@ -332,7 +332,7 @@ GVArray AnonymousAttributeFieldInput::get_varray_for_context(const GeometryField const IndexMask /*mask*/) const { const eCustomDataType data_type = cpp_type_to_custom_data_type(*type_); - return context.attributes()->lookup(anonymous_id_.get(), context.domain(), data_type); + return context.attributes()->lookup(*anonymous_id_, context.domain(), data_type); } std::string AnonymousAttributeFieldInput::socket_inspection_name() const @@ -363,8 +363,7 @@ std::optional AnonymousAttributeFieldInput::preferred_domain( if (!attributes.has_value()) { return std::nullopt; } - const std::optional meta_data = attributes->lookup_meta_data( - anonymous_id_.get()); + const std::optional meta_data = attributes->lookup_meta_data(*anonymous_id_); if (!meta_data.has_value()) { return std::nullopt; } diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc index 1e03b8d235a..8fff80e709f 100644 --- a/source/blender/blenkernel/intern/geometry_set.cc +++ b/source/blender/blenkernel/intern/geometry_set.cc @@ -581,6 +581,7 @@ void GeometrySet::gather_attributes_for_propagation( const Span component_types, const GeometryComponentType dst_component_type, bool include_instances, + const blender::bke::AnonymousAttributePropagationInfo &propagation_info, blender::Map &r_attributes) const { using namespace blender; @@ -605,7 +606,8 @@ void GeometrySet::gather_attributes_for_propagation( /* Propagating string attributes is not supported yet. */ return; } - if (!attribute_id.should_be_kept()) { + if (attribute_id.is_anonymous() && + !propagation_info.propagate(attribute_id.anonymous_id())) { return; } diff --git a/source/blender/blenkernel/intern/instances.cc b/source/blender/blenkernel/intern/instances.cc index a2c344e918b..d98ad27f02c 100644 --- a/source/blender/blenkernel/intern/instances.cc +++ b/source/blender/blenkernel/intern/instances.cc @@ -105,7 +105,8 @@ blender::Span Instances::references() const return references_; } -void Instances::remove(const IndexMask mask) +void Instances::remove(const IndexMask mask, + const AnonymousAttributePropagationInfo &propagation_info) { using namespace blender; if (mask.is_range() && mask.as_range().start() == 0) { @@ -132,7 +133,7 @@ void Instances::remove(const IndexMask mask) src_attributes.foreach_attribute( [&](const bke::AttributeIDRef &id, const bke::AttributeMetaData &meta_data) { - if (!id.should_be_kept()) { + if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) { return true; } diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index c59210d9d47..bbd70a9d152 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -839,7 +839,9 @@ static Mesh *mesh_new_from_evaluated_curve_type_object(const Object *evaluated_o return BKE_mesh_copy_for_eval(mesh, false); } if (const Curves *curves = get_evaluated_curves_from_object(evaluated_object)) { - return blender::bke::curve_to_wire_mesh(blender::bke::CurvesGeometry::wrap(curves->geometry)); + const blender::bke::AnonymousAttributePropagationInfo propagation_info; + return blender::bke::curve_to_wire_mesh(blender::bke::CurvesGeometry::wrap(curves->geometry), + propagation_info); } return nullptr; } diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index eeba322e30d..f72ba7a1378 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -207,6 +207,11 @@ static void ntree_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, cons dst_runtime.field_inferencing_interface = std::make_unique( *ntree_src->runtime->field_inferencing_interface); } + if (ntree_src->runtime->anonymous_attribute_relations) { + dst_runtime.anonymous_attribute_relations = + std::make_unique( + *ntree_src->runtime->anonymous_attribute_relations); + } if (flag & LIB_ID_COPY_NO_PREVIEW) { ntree_dst->preview = nullptr; diff --git a/source/blender/blenkernel/intern/node_tree_anonymous_attributes.cc b/source/blender/blenkernel/intern/node_tree_anonymous_attributes.cc new file mode 100644 index 00000000000..9ade129afb5 --- /dev/null +++ b/source/blender/blenkernel/intern/node_tree_anonymous_attributes.cc @@ -0,0 +1,452 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "NOD_node_declaration.hh" + +#include "BKE_node_runtime.hh" + +#include "BLI_multi_value_map.hh" +#include "BLI_resource_scope.hh" +#include "BLI_set.hh" +#include "BLI_stack.hh" +#include "BLI_timeit.hh" + +namespace blender::bke::anonymous_attribute_inferencing { +namespace aal = nodes::aal; +using nodes::NodeDeclaration; + +static const aal::RelationsInNode &get_relations_in_node(const bNode &node, ResourceScope &scope) +{ + if (node.is_group()) { + if (const bNodeTree *group = reinterpret_cast(node.id)) { + BLI_assert(group->runtime->anonymous_attribute_relations); + return *group->runtime->anonymous_attribute_relations; + } + } + if (const NodeDeclaration *node_decl = node.declaration()) { + if (const aal::RelationsInNode *relations = node_decl->anonymous_attribute_relations()) { + return *relations; + } + } + return scope.construct(); +} + +Array get_relations_by_node(const bNodeTree &tree, + ResourceScope &scope) +{ + const Span nodes = tree.all_nodes(); + Array relations_by_node(nodes.size()); + for (const int i : nodes.index_range()) { + relations_by_node[i] = &get_relations_in_node(*nodes[i], scope); + } + return relations_by_node; +} + +static bool socket_is_field(const bNodeSocket &socket) +{ + return socket.display_shape == SOCK_DISPLAY_SHAPE_DIAMOND; +} + +/** + * Start at a group output socket and find all linked group inputs. + */ +static Vector find_linked_group_inputs( + const bNodeTree &tree, + const bNodeSocket &group_output_socket, + const FunctionRef(const bNodeSocket &)> get_linked_node_inputs) +{ + Set found_sockets; + Stack sockets_to_check; + + Vector input_indices; + + found_sockets.add_new(&group_output_socket); + sockets_to_check.push(&group_output_socket); + + while (!sockets_to_check.is_empty()) { + const bNodeSocket &socket = *sockets_to_check.pop(); + if (socket.is_input()) { + for (const bNodeLink *link : socket.directly_linked_links()) { + if (link->is_used()) { + const bNodeSocket &from_socket = *link->fromsock; + if (found_sockets.add(&from_socket)) { + sockets_to_check.push(&from_socket); + } + } + } + } + else { + const bNode &node = socket.owner_node(); + for (const int input_index : get_linked_node_inputs(socket)) { + const bNodeSocket &input_socket = node.input_socket(input_index); + if (input_socket.is_available()) { + if (found_sockets.add(&input_socket)) { + sockets_to_check.push(&input_socket); + } + } + } + } + } + + for (const bNode *node : tree.group_input_nodes()) { + for (const bNodeSocket *socket : node->output_sockets()) { + if (found_sockets.contains(socket)) { + input_indices.append_non_duplicates(socket->index()); + } + } + } + + return input_indices; +} + +static void infer_propagate_relations(const bNodeTree &tree, + const Span relations_by_node, + const bNode &group_output_node, + aal::RelationsInNode &r_relations) +{ + for (const bNodeSocket *group_output_socket : group_output_node.input_sockets().drop_back(1)) { + if (group_output_socket->type != SOCK_GEOMETRY) { + continue; + } + const Vector input_indices = find_linked_group_inputs( + tree, *group_output_socket, [&](const bNodeSocket &output_socket) { + Vector indices; + for (const aal::PropagateRelation &relation : + relations_by_node[output_socket.owner_node().index()]->propagate_relations) { + if (relation.to_geometry_output == output_socket.index()) { + indices.append(relation.from_geometry_input); + } + } + return indices; + }); + for (const int input_index : input_indices) { + aal::PropagateRelation relation; + relation.from_geometry_input = input_index; + relation.to_geometry_output = group_output_socket->index(); + r_relations.propagate_relations.append(relation); + } + } +} + +static void infer_reference_relations(const bNodeTree &tree, + const Span relations_by_node, + const bNode &group_output_node, + aal::RelationsInNode &r_relations) +{ + for (const bNodeSocket *group_output_socket : group_output_node.input_sockets().drop_back(1)) { + if (!socket_is_field(*group_output_socket)) { + continue; + } + const Vector input_indices = find_linked_group_inputs( + tree, *group_output_socket, [&](const bNodeSocket &output_socket) { + Vector indices; + for (const aal::ReferenceRelation &relation : + relations_by_node[output_socket.owner_node().index()]->reference_relations) { + if (relation.to_field_output == output_socket.index()) { + indices.append(relation.from_field_input); + } + } + return indices; + }); + for (const int input_index : input_indices) { + if (tree.runtime->field_inferencing_interface->inputs[input_index] != + nodes::InputSocketFieldType::None) { + aal::ReferenceRelation relation; + relation.from_field_input = input_index; + relation.to_field_output = group_output_socket->index(); + r_relations.reference_relations.append(relation); + } + } + } +} + +/** + * Find group output geometries that contain anonymous attributes referenced by the field. + * If `nullopt` is returned, the field does not depend on any anonymous attribute created in this + * node tree. + */ +static std::optional> find_available_on_outputs( + const bNodeSocket &initial_group_output_socket, + const bNode &group_output_node, + const Span relations_by_node) +{ + Set geometry_sockets; + + { + /* Find the nodes that added anonymous attributes to the field. */ + Set found_sockets; + Stack sockets_to_check; + + found_sockets.add_new(&initial_group_output_socket); + sockets_to_check.push(&initial_group_output_socket); + + while (!sockets_to_check.is_empty()) { + const bNodeSocket &socket = *sockets_to_check.pop(); + if (socket.is_input()) { + for (const bNodeLink *link : socket.directly_linked_links()) { + if (link->is_used()) { + const bNodeSocket &from_socket = *link->fromsock; + if (found_sockets.add(&from_socket)) { + sockets_to_check.push(&from_socket); + } + } + } + } + else { + const bNode &node = socket.owner_node(); + const aal::RelationsInNode &relations = *relations_by_node[node.index()]; + for (const aal::AvailableRelation &relation : relations.available_relations) { + if (socket.index() == relation.field_output) { + const bNodeSocket &geometry_output = node.output_socket(relation.geometry_output); + if (geometry_output.is_available()) { + geometry_sockets.add(&geometry_output); + } + } + } + for (const aal::ReferenceRelation &relation : relations.reference_relations) { + if (socket.index() == relation.to_field_output) { + const bNodeSocket &field_input = node.input_socket(relation.from_field_input); + if (field_input.is_available()) { + if (found_sockets.add(&field_input)) { + sockets_to_check.push(&field_input); + } + } + } + } + } + } + } + + if (geometry_sockets.is_empty()) { + /* The field does not depend on any anonymous attribute created within this node tree. */ + return std::nullopt; + } + + /* Find the group output geometries that contain the anonymous attribute referenced by the field + * output. */ + Set found_sockets; + Stack sockets_to_check; + + for (const bNodeSocket *socket : geometry_sockets) { + found_sockets.add_new(socket); + sockets_to_check.push(socket); + } + + while (!sockets_to_check.is_empty()) { + const bNodeSocket &socket = *sockets_to_check.pop(); + if (socket.is_input()) { + const bNode &node = socket.owner_node(); + const aal::RelationsInNode &relations = *relations_by_node[node.index()]; + for (const aal::PropagateRelation &relation : relations.propagate_relations) { + if (socket.index() == relation.from_geometry_input) { + const bNodeSocket &output_socket = node.output_socket(relation.to_geometry_output); + if (output_socket.is_available()) { + if (found_sockets.add(&output_socket)) { + sockets_to_check.push(&output_socket); + } + } + } + } + } + else { + for (const bNodeLink *link : socket.directly_linked_links()) { + if (link->is_used()) { + const bNodeSocket &to_socket = *link->tosock; + if (found_sockets.add(&to_socket)) { + sockets_to_check.push(&to_socket); + } + } + } + } + } + + Vector output_indices; + for (const bNodeSocket *socket : group_output_node.input_sockets().drop_back(1)) { + if (found_sockets.contains(socket)) { + output_indices.append(socket->index()); + } + } + return output_indices; +} + +static void infer_available_relations(const Span relations_by_node, + const bNode &group_output_node, + aal::RelationsInNode &r_relations) +{ + for (const bNodeSocket *group_output_socket : group_output_node.input_sockets().drop_back(1)) { + if (!socket_is_field(*group_output_socket)) { + continue; + } + const std::optional> output_indices = find_available_on_outputs( + *group_output_socket, group_output_node, relations_by_node); + if (output_indices.has_value()) { + if (output_indices->is_empty()) { + r_relations.available_on_none.append(group_output_socket->index()); + } + else { + for (const int output_index : *output_indices) { + aal::AvailableRelation relation; + relation.field_output = group_output_socket->index(); + relation.geometry_output = output_index; + r_relations.available_relations.append(relation); + } + } + } + } +} + +/** + * Returns a list of all the geometry inputs that the field input may be evaluated on. + */ +static Vector find_eval_on_inputs(const bNodeTree &tree, + const int field_input_index, + const Span relations_by_node) +{ + const Span group_input_nodes = tree.group_input_nodes(); + Set geometry_sockets; + + { + /* Find all the nodes that evaluate the input field. */ + Set found_sockets; + Stack sockets_to_check; + + for (const bNode *node : group_input_nodes) { + const bNodeSocket &socket = node->output_socket(field_input_index); + found_sockets.add_new(&socket); + sockets_to_check.push(&socket); + } + + while (!sockets_to_check.is_empty()) { + const bNodeSocket &socket = *sockets_to_check.pop(); + if (socket.is_input()) { + const bNode &node = socket.owner_node(); + const aal::RelationsInNode &relations = *relations_by_node[node.index()]; + for (const aal::EvalRelation &relation : relations.eval_relations) { + if (socket.index() == relation.field_input) { + const bNodeSocket &geometry_input = node.input_socket(relation.geometry_input); + if (geometry_input.is_available()) { + geometry_sockets.add(&geometry_input); + } + } + } + for (const aal::ReferenceRelation &relation : relations.reference_relations) { + if (socket.index() == relation.from_field_input) { + const bNodeSocket &field_output = node.output_socket(relation.to_field_output); + if (field_output.is_available()) { + if (found_sockets.add(&field_output)) { + sockets_to_check.push(&field_output); + } + } + } + } + } + else { + for (const bNodeLink *link : socket.directly_linked_links()) { + if (link->is_used()) { + const bNodeSocket &to_socket = *link->tosock; + if (found_sockets.add(&to_socket)) { + sockets_to_check.push(&to_socket); + } + } + } + } + } + } + + if (geometry_sockets.is_empty()) { + return {}; + } + + /* Find the group input geometries whose attributes are propagated to the nodes that evaluate the + * field. */ + Set found_sockets; + Stack sockets_to_check; + + Vector geometry_input_indices; + + for (const bNodeSocket *socket : geometry_sockets) { + found_sockets.add_new(socket); + sockets_to_check.push(socket); + } + + while (!sockets_to_check.is_empty()) { + const bNodeSocket &socket = *sockets_to_check.pop(); + if (socket.is_input()) { + for (const bNodeLink *link : socket.directly_linked_links()) { + if (link->is_used()) { + const bNodeSocket &from_socket = *link->fromsock; + if (found_sockets.add(&from_socket)) { + sockets_to_check.push(&from_socket); + } + } + } + } + else { + const bNode &node = socket.owner_node(); + if (node.is_group_input()) { + geometry_input_indices.append_non_duplicates(socket.index()); + } + else { + const aal::RelationsInNode &relations = *relations_by_node[node.index()]; + for (const aal::PropagateRelation &relation : relations.propagate_relations) { + if (socket.index() == relation.to_geometry_output) { + const bNodeSocket &input_socket = node.input_socket(relation.from_geometry_input); + if (input_socket.is_available()) { + if (found_sockets.add(&input_socket)) { + sockets_to_check.push(&input_socket); + } + } + } + } + } + } + } + + return geometry_input_indices; +} + +static void infer_eval_relations(const bNodeTree &tree, + const Span relations_by_node, + aal::RelationsInNode &r_relations) +{ + for (const int input_index : tree.interface_inputs().index_range()) { + if (tree.runtime->field_inferencing_interface->inputs[input_index] == + nodes::InputSocketFieldType::None) { + continue; + } + const Vector geometry_input_indices = find_eval_on_inputs( + tree, input_index, relations_by_node); + for (const int geometry_input : geometry_input_indices) { + aal::EvalRelation relation; + relation.field_input = input_index; + relation.geometry_input = geometry_input; + r_relations.eval_relations.append(std::move(relation)); + } + } +} + +bool update_anonymous_attribute_relations(bNodeTree &tree) +{ + tree.ensure_topology_cache(); + + ResourceScope scope; + Array relations_by_node = get_relations_by_node(tree, scope); + + std::unique_ptr new_relations = std::make_unique(); + if (!tree.has_available_link_cycle()) { + if (const bNode *group_output_node = tree.group_output_node()) { + infer_propagate_relations(tree, relations_by_node, *group_output_node, *new_relations); + infer_reference_relations(tree, relations_by_node, *group_output_node, *new_relations); + infer_available_relations(relations_by_node, *group_output_node, *new_relations); + } + infer_eval_relations(tree, relations_by_node, *new_relations); + } + + const bool group_interface_changed = !tree.runtime->anonymous_attribute_relations || + *tree.runtime->anonymous_attribute_relations != + *new_relations; + tree.runtime->anonymous_attribute_relations = std::move(new_relations); + + return group_interface_changed; +} + +} // namespace blender::bke::anonymous_attribute_inferencing diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc index d01cbd1d62d..93e8f24787a 100644 --- a/source/blender/blenkernel/intern/node_tree_update.cc +++ b/source/blender/blenkernel/intern/node_tree_update.cc @@ -473,6 +473,9 @@ class NodeTreeMainUpdater { if (node_field_inferencing::update_field_inferencing(ntree)) { result.interface_changed = true; } + if (anonymous_attribute_inferencing::update_anonymous_attribute_relations(ntree)) { + result.interface_changed = true; + } } result.output_changed = this->check_if_output_changed(ntree); diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index a2310dddc61..204fb7012ab 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -1484,5 +1484,6 @@ void ED_mesh_split_faces(Mesh *mesh) return; } - geometry::split_edges(*mesh, split_mask); + const bke::AnonymousAttributePropagationInfo propagation_info; + geometry::split_edges(*mesh, split_mask, propagation_info); } diff --git a/source/blender/functions/FN_lazy_function_graph.hh b/source/blender/functions/FN_lazy_function_graph.hh index 460e858774f..6d66afafe82 100644 --- a/source/blender/functions/FN_lazy_function_graph.hh +++ b/source/blender/functions/FN_lazy_function_graph.hh @@ -53,6 +53,10 @@ class Socket : NonCopyable, NonMovable { * Index of the socket. E.g. 0 for the first input and the first output socket. */ int index_in_node_; + /** + * Index of the socket in the entire graph. Every socket has a different index. + */ + int index_in_graph_; friend Graph; @@ -61,6 +65,7 @@ class Socket : NonCopyable, NonMovable { bool is_output() const; int index() const; + int index_in_graph() const; InputSocket &as_input(); OutputSocket &as_output(); @@ -179,6 +184,20 @@ class DummyDebugInfo { virtual std::string output_name(const int i) const; }; +/** + * Just stores a string per socket in a dummy node. + */ +class SimpleDummyDebugInfo : public DummyDebugInfo { + public: + std::string name; + Vector input_names; + Vector output_names; + + std::string node_name() const override; + std::string input_name(const int i) const override; + std::string output_name(const int i) const override; +}; + /** * A #Node that does *not* correspond to a #LazyFunction. Instead it can be used to indicate inputs * and outputs of the entire graph. It can have an arbitrary number of inputs and outputs. @@ -205,6 +224,11 @@ class Graph : NonCopyable, NonMovable { * Contains all nodes in the graph so that it is efficient to iterate over them. */ Vector nodes_; + /** + * Number of sockets in the graph. Can be used as array size when indexing using + * `Socket::index_in_graph`. + */ + int socket_num_ = 0; public: ~Graph(); @@ -213,6 +237,7 @@ class Graph : NonCopyable, NonMovable { * Get all nodes in the graph. The index in the span corresponds to #Node::index_in_graph. */ Span nodes() const; + Span nodes(); /** * Add a new function node with sockets that match the passed in #LazyFunction. @@ -232,10 +257,24 @@ class Graph : NonCopyable, NonMovable { */ void add_link(OutputSocket &from, InputSocket &to); + /** + * If the socket is linked, remove the link. + */ + void clear_origin(InputSocket &socket); + /** * Make sure that #Node::index_in_graph is up to date. */ void update_node_indices(); + /** + * Make sure that #Socket::index_in_graph is up to date. + */ + void update_socket_indices(); + + /** + * Number of sockets in the graph. + */ + int socket_num() const; /** * Can be used to assert that #update_node_indices has been called. @@ -280,6 +319,11 @@ inline int Socket::index() const return index_in_node_; } +inline int Socket::index_in_graph() const +{ + return index_in_graph_; +} + inline InputSocket &Socket::as_input() { BLI_assert(this->is_input()); @@ -445,6 +489,16 @@ inline Span Graph::nodes() const return nodes_; } +inline Span Graph::nodes() +{ + return nodes_; +} + +inline int Graph::socket_num() const +{ + return socket_num_; +} + /** \} */ } // namespace blender::fn::lazy_function diff --git a/source/blender/functions/intern/lazy_function_graph.cc b/source/blender/functions/intern/lazy_function_graph.cc index e8a20fbf9a3..e07cce7204b 100644 --- a/source/blender/functions/intern/lazy_function_graph.cc +++ b/source/blender/functions/intern/lazy_function_graph.cc @@ -86,6 +86,14 @@ void Graph::add_link(OutputSocket &from, InputSocket &to) from.targets_.append(&to); } +void Graph::clear_origin(InputSocket &socket) +{ + if (socket.origin_ != nullptr) { + socket.origin_->targets_.remove_first_occurrence_and_reorder(&socket); + socket.origin_ = nullptr; + } +} + void Graph::update_node_indices() { for (const int i : nodes_.index_range()) { @@ -93,6 +101,20 @@ void Graph::update_node_indices() } } +void Graph::update_socket_indices() +{ + int socket_counter = 0; + for (const int i : nodes_.index_range()) { + for (InputSocket *socket : nodes_[i]->inputs()) { + socket->index_in_graph_ = socket_counter++; + } + for (OutputSocket *socket : nodes_[i]->outputs()) { + socket->index_in_graph_ = socket_counter++; + } + } + socket_num_ = socket_counter; +} + bool Graph::node_indices_are_valid() const { for (const int i : nodes_.index_range()) { @@ -152,6 +174,21 @@ std::string DummyDebugInfo::output_name(const int /*i*/) const return fallback_name; } +std::string SimpleDummyDebugInfo::node_name() const +{ + return this->name; +} + +std::string SimpleDummyDebugInfo::input_name(const int i) const +{ + return this->input_names[i]; +} + +std::string SimpleDummyDebugInfo::output_name(const int i) const +{ + return this->output_names[i]; +} + std::string Graph::ToDotOptions::socket_name(const Socket &socket) const { return socket.name(); diff --git a/source/blender/geometry/GEO_fillet_curves.hh b/source/blender/geometry/GEO_fillet_curves.hh index 1f832f8b6cc..8019e6bf7ed 100644 --- a/source/blender/geometry/GEO_fillet_curves.hh +++ b/source/blender/geometry/GEO_fillet_curves.hh @@ -9,15 +9,19 @@ namespace blender::geometry { -bke::CurvesGeometry fillet_curves_poly(const bke::CurvesGeometry &src_curves, - IndexMask curve_selection, - const VArray &radius, - const VArray &counts, - bool limit_radius); +bke::CurvesGeometry fillet_curves_poly( + const bke::CurvesGeometry &src_curves, + IndexMask curve_selection, + const VArray &radius, + const VArray &counts, + bool limit_radius, + const bke::AnonymousAttributePropagationInfo &propagation_info); -bke::CurvesGeometry fillet_curves_bezier(const bke::CurvesGeometry &src_curves, - IndexMask curve_selection, - const VArray &radius, - bool limit_radius); +bke::CurvesGeometry fillet_curves_bezier( + const bke::CurvesGeometry &src_curves, + IndexMask curve_selection, + const VArray &radius, + bool limit_radius, + const bke::AnonymousAttributePropagationInfo &propagation_info); } // namespace blender::geometry diff --git a/source/blender/geometry/GEO_mesh_split_edges.hh b/source/blender/geometry/GEO_mesh_split_edges.hh index f104a55ae4d..cb0e3de8bd1 100644 --- a/source/blender/geometry/GEO_mesh_split_edges.hh +++ b/source/blender/geometry/GEO_mesh_split_edges.hh @@ -4,10 +4,14 @@ #include "BLI_index_mask.hh" +#include "BKE_attribute.hh" + struct Mesh; namespace blender::geometry { -void split_edges(Mesh &mesh, IndexMask mask); +void split_edges(Mesh &mesh, + IndexMask mask, + const bke::AnonymousAttributePropagationInfo &propagation_info); } // namespace blender::geometry diff --git a/source/blender/geometry/GEO_mesh_to_curve.hh b/source/blender/geometry/GEO_mesh_to_curve.hh index b0f24853dbc..17eb311ccc2 100644 --- a/source/blender/geometry/GEO_mesh_to_curve.hh +++ b/source/blender/geometry/GEO_mesh_to_curve.hh @@ -19,11 +19,16 @@ namespace blender::geometry { * intersections of more than three edges will become breaks in curves. Attributes that * are not built-in on meshes and not curves are transferred to the result curve. */ -bke::CurvesGeometry mesh_to_curve_convert(const Mesh &mesh, const IndexMask selection); +bke::CurvesGeometry mesh_to_curve_convert( + const Mesh &mesh, + const IndexMask selection, + const bke::AnonymousAttributePropagationInfo &propagation_info); -bke::CurvesGeometry create_curve_from_vert_indices(const Mesh &mesh, - Span vert_indices, - Span curve_offsets, - IndexRange cyclic_curves); +bke::CurvesGeometry create_curve_from_vert_indices( + const Mesh &mesh, + Span vert_indices, + Span curve_offsets, + IndexRange cyclic_curves, + const bke::AnonymousAttributePropagationInfo &propagation_info); } // namespace blender::geometry diff --git a/source/blender/geometry/GEO_point_merge_by_distance.hh b/source/blender/geometry/GEO_point_merge_by_distance.hh index 92d871c62ab..054ecffd358 100644 --- a/source/blender/geometry/GEO_point_merge_by_distance.hh +++ b/source/blender/geometry/GEO_point_merge_by_distance.hh @@ -2,6 +2,8 @@ #include "BLI_index_mask.hh" +#include "BKE_attribute.hh" + #pragma once struct PointCloud; @@ -17,8 +19,10 @@ namespace blender::geometry { * Merge selected points into other selected points within the \a merge_distance. The merged * indices favor speed over accuracy, since the results will depend on the order of the points. */ -PointCloud *point_merge_by_distance(const PointCloud &src_points, - const float merge_distance, - const IndexMask selection); +PointCloud *point_merge_by_distance( + const PointCloud &src_points, + const float merge_distance, + const IndexMask selection, + const bke::AnonymousAttributePropagationInfo &propagation_info); } // namespace blender::geometry diff --git a/source/blender/geometry/GEO_realize_instances.hh b/source/blender/geometry/GEO_realize_instances.hh index 9c46de6fdca..b13d764c685 100644 --- a/source/blender/geometry/GEO_realize_instances.hh +++ b/source/blender/geometry/GEO_realize_instances.hh @@ -19,6 +19,8 @@ struct RealizeInstancesOptions { * instances. Otherwise, instance attributes are ignored. */ bool realize_instance_attributes = true; + + bke::AnonymousAttributePropagationInfo propagation_info; }; /** diff --git a/source/blender/geometry/GEO_resample_curves.hh b/source/blender/geometry/GEO_resample_curves.hh index 35365167eba..fd1e6b7dad3 100644 --- a/source/blender/geometry/GEO_resample_curves.hh +++ b/source/blender/geometry/GEO_resample_curves.hh @@ -4,7 +4,7 @@ #include "FN_field.hh" -#include "BKE_anonymous_attribute.hh" +#include "BKE_anonymous_attribute_id.hh" #include "BKE_curves.hh" namespace blender::geometry { diff --git a/source/blender/geometry/GEO_set_curve_type.hh b/source/blender/geometry/GEO_set_curve_type.hh index f38e63b1fc8..3860664c1c5 100644 --- a/source/blender/geometry/GEO_set_curve_type.hh +++ b/source/blender/geometry/GEO_set_curve_type.hh @@ -27,6 +27,7 @@ bool try_curves_conversion_in_place(IndexMask selection, */ bke::CurvesGeometry convert_curves(const bke::CurvesGeometry &src_curves, IndexMask selection, - CurveType dst_type); + CurveType dst_type, + const bke::AnonymousAttributePropagationInfo &propagation_info); } // namespace blender::geometry diff --git a/source/blender/geometry/GEO_subdivide_curves.hh b/source/blender/geometry/GEO_subdivide_curves.hh index ba55118baa4..46e63839056 100644 --- a/source/blender/geometry/GEO_subdivide_curves.hh +++ b/source/blender/geometry/GEO_subdivide_curves.hh @@ -17,8 +17,10 @@ namespace blender::geometry { * * \param selection: A selection of curves to consider when subdividing. */ -bke::CurvesGeometry subdivide_curves(const bke::CurvesGeometry &src_curves, - IndexMask selection, - const VArray &cuts); +bke::CurvesGeometry subdivide_curves( + const bke::CurvesGeometry &src_curves, + IndexMask selection, + const VArray &cuts, + const bke::AnonymousAttributePropagationInfo &propagation_info); } // namespace blender::geometry diff --git a/source/blender/geometry/GEO_trim_curves.hh b/source/blender/geometry/GEO_trim_curves.hh index 197ef79c25b..1cae65875e2 100644 --- a/source/blender/geometry/GEO_trim_curves.hh +++ b/source/blender/geometry/GEO_trim_curves.hh @@ -19,6 +19,7 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, IndexMask selection, const VArray &starts, const VArray &ends, - GeometryNodeCurveSampleMode mode); + GeometryNodeCurveSampleMode mode, + const bke::AnonymousAttributePropagationInfo &propagation_info); } // namespace blender::geometry diff --git a/source/blender/geometry/intern/add_curves_on_mesh.cc b/source/blender/geometry/intern/add_curves_on_mesh.cc index 0e9b89b35b4..55f0398fd3c 100644 --- a/source/blender/geometry/intern/add_curves_on_mesh.cc +++ b/source/blender/geometry/intern/add_curves_on_mesh.cc @@ -372,7 +372,7 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, Set attributes_to_skip{{"position", "curve_type", "surface_uv_coordinate"}}; attributes.for_all( [&](const bke::AttributeIDRef &id, const bke::AttributeMetaData /*meta_data*/) { - if (id.is_named() && attributes_to_skip.contains(id.name())) { + if (attributes_to_skip.contains(id.name())) { return true; } bke::GSpanAttributeWriter attribute = attributes.lookup_for_write_span(id); diff --git a/source/blender/geometry/intern/fillet_curves.cc b/source/blender/geometry/intern/fillet_curves.cc index cb513641a5f..5e4f2e35c67 100644 --- a/source/blender/geometry/intern/fillet_curves.cc +++ b/source/blender/geometry/intern/fillet_curves.cc @@ -397,12 +397,14 @@ static void calculate_bezier_handles_poly_mode(const Span src_handles_l, }); } -static bke::CurvesGeometry fillet_curves(const bke::CurvesGeometry &src_curves, - const IndexMask curve_selection, - const VArray &radius_input, - const VArray &counts, - const bool limit_radius, - const bool use_bezier_mode) +static bke::CurvesGeometry fillet_curves( + const bke::CurvesGeometry &src_curves, + const IndexMask curve_selection, + const VArray &radius_input, + const VArray &counts, + const bool limit_radius, + const bool use_bezier_mode, + const bke::AnonymousAttributePropagationInfo &propagation_info) { const Vector unselected_ranges = curve_selection.extract_ranges_invert( src_curves.curves_range()); @@ -520,6 +522,7 @@ static bke::CurvesGeometry fillet_curves(const bke::CurvesGeometry &src_curves, src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, + propagation_info, {"position", "handle_type_left", "handle_type_right", "handle_right", "handle_left"})) { duplicate_fillet_point_data( src_curves, dst_curves, curve_selection, point_offsets, attribute.src, attribute.dst.span); @@ -528,7 +531,7 @@ static bke::CurvesGeometry fillet_curves(const bke::CurvesGeometry &src_curves, if (!unselected_ranges.is_empty()) { for (auto &attribute : bke::retrieve_attributes_for_transfer( - src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT)) { + src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info)) { bke::curves::copy_point_data( src_curves, dst_curves, unselected_ranges, attribute.src, attribute.dst.span); attribute.dst.finish(); @@ -538,26 +541,32 @@ static bke::CurvesGeometry fillet_curves(const bke::CurvesGeometry &src_curves, return dst_curves; } -bke::CurvesGeometry fillet_curves_poly(const bke::CurvesGeometry &src_curves, - const IndexMask curve_selection, - const VArray &radius, - const VArray &count, - const bool limit_radius) +bke::CurvesGeometry fillet_curves_poly( + const bke::CurvesGeometry &src_curves, + const IndexMask curve_selection, + const VArray &radius, + const VArray &count, + const bool limit_radius, + const bke::AnonymousAttributePropagationInfo &propagation_info) { - return fillet_curves(src_curves, curve_selection, radius, count, limit_radius, false); + return fillet_curves( + src_curves, curve_selection, radius, count, limit_radius, false, propagation_info); } -bke::CurvesGeometry fillet_curves_bezier(const bke::CurvesGeometry &src_curves, - const IndexMask curve_selection, - const VArray &radius, - const bool limit_radius) +bke::CurvesGeometry fillet_curves_bezier( + const bke::CurvesGeometry &src_curves, + const IndexMask curve_selection, + const VArray &radius, + const bool limit_radius, + const bke::AnonymousAttributePropagationInfo &propagation_info) { return fillet_curves(src_curves, curve_selection, radius, VArray::ForSingle(1, src_curves.points_num()), limit_radius, - true); + true, + propagation_info); } } // namespace blender::geometry diff --git a/source/blender/geometry/intern/mesh_split_edges.cc b/source/blender/geometry/intern/mesh_split_edges.cc index 19db9cbfc03..5cf7d4bb935 100644 --- a/source/blender/geometry/intern/mesh_split_edges.cc +++ b/source/blender/geometry/intern/mesh_split_edges.cc @@ -3,6 +3,7 @@ #include "BLI_array_utils.hh" #include "BLI_devirtualize_parameters.hh" #include "BLI_index_mask.hh" +#include "BLI_user_counter.hh" #include "BKE_attribute.hh" #include "BKE_attribute_math.hh" @@ -59,35 +60,36 @@ static void add_new_vertices(Mesh &mesh, const Span new_to_old_verts_map) static void add_new_edges(Mesh &mesh, const Span new_edges, - const Span new_to_old_edges_map) + const Span new_to_old_edges_map, + const bke::AnonymousAttributePropagationInfo &propagation_info) { bke::MutableAttributeAccessor attributes = mesh.attributes_for_write(); /* Store a copy of the IDs locally since we will remove the existing attributes which * can also free the names, since the API does not provide pointer stability. */ Vector named_ids; - Vector anonymous_ids; + Vector> anonymous_ids; for (const bke::AttributeIDRef &id : attributes.all_ids()) { if (attributes.lookup_meta_data(id)->domain != ATTR_DOMAIN_EDGE) { continue; } - if (!id.should_be_kept()) { + if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) { continue; } - if (id.is_named()) { + if (!id.is_anonymous()) { named_ids.append(id.name()); } else { - anonymous_ids.append(bke::WeakAnonymousAttributeID(&id.anonymous_id())); - BKE_anonymous_attribute_id_increment_weak(&id.anonymous_id()); + anonymous_ids.append(&id.anonymous_id()); + id.anonymous_id().user_add(); } } Vector local_edge_ids; for (const StringRef name : named_ids) { local_edge_ids.append(name); } - for (const bke::WeakAnonymousAttributeID &id : anonymous_ids) { - local_edge_ids.append(id.get()); + for (const UserCounter &id : anonymous_ids) { + local_edge_ids.append(*id); } /* Build new arrays for the copied edge attributes. Unlike vertices, new edges aren't all at the @@ -348,7 +350,9 @@ static void split_edge_per_poly(const int edge_i, edge_to_loop_map[edge_i].resize(1); } -void split_edges(Mesh &mesh, const IndexMask mask) +void split_edges(Mesh &mesh, + const IndexMask mask, + const bke::AnonymousAttributePropagationInfo &propagation_info) { /* Flag vertices that need to be split. */ Array should_split_vert(mesh.totvert, false); @@ -483,7 +487,7 @@ void split_edges(Mesh &mesh, const IndexMask mask) /* Step 5: Resize the mesh to add the new vertices and rebuild the edges. */ add_new_vertices(mesh, new_to_old_verts_map); - add_new_edges(mesh, new_edges, new_to_old_edges_map); + add_new_edges(mesh, new_edges, new_to_old_edges_map, propagation_info); BKE_mesh_tag_edges_split(&mesh); } diff --git a/source/blender/geometry/intern/mesh_to_curve_convert.cc b/source/blender/geometry/intern/mesh_to_curve_convert.cc index c2a9b16c8b6..8047f1dc312 100644 --- a/source/blender/geometry/intern/mesh_to_curve_convert.cc +++ b/source/blender/geometry/intern/mesh_to_curve_convert.cc @@ -19,10 +19,12 @@ namespace blender::geometry { -bke::CurvesGeometry create_curve_from_vert_indices(const Mesh &mesh, - const Span vert_indices, - const Span curve_offsets, - const IndexRange cyclic_curves) +bke::CurvesGeometry create_curve_from_vert_indices( + const Mesh &mesh, + const Span vert_indices, + const Span curve_offsets, + const IndexRange cyclic_curves, + const bke::AnonymousAttributePropagationInfo &propagation_info) { bke::CurvesGeometry curves(vert_indices.size(), curve_offsets.size()); curves.offsets_for_write().drop_back(1).copy_from(curve_offsets); @@ -43,7 +45,7 @@ bke::CurvesGeometry create_curve_from_vert_indices(const Mesh &mesh, continue; } - if (!attribute_id.should_be_kept()) { + if (attribute_id.is_anonymous() && !propagation_info.propagate(attribute_id.anonymous_id())) { continue; } @@ -209,14 +211,17 @@ static Vector> get_selected_edges(const Mesh &mesh, const In return selected_edges; } -bke::CurvesGeometry mesh_to_curve_convert(const Mesh &mesh, const IndexMask selection) +bke::CurvesGeometry mesh_to_curve_convert( + const Mesh &mesh, + const IndexMask selection, + const bke::AnonymousAttributePropagationInfo &propagation_info) { Vector> selected_edges = get_selected_edges(mesh, selection); const Span verts = mesh.verts(); CurveFromEdgesOutput output = edges_to_curve_point_indices(verts, selected_edges); return create_curve_from_vert_indices( - mesh, output.vert_indices, output.curve_offsets, output.cyclic_curves); + mesh, output.vert_indices, output.curve_offsets, output.cyclic_curves, propagation_info); } } // namespace blender::geometry diff --git a/source/blender/geometry/intern/point_merge_by_distance.cc b/source/blender/geometry/intern/point_merge_by_distance.cc index 81f57f785a3..3387afc7279 100644 --- a/source/blender/geometry/intern/point_merge_by_distance.cc +++ b/source/blender/geometry/intern/point_merge_by_distance.cc @@ -15,7 +15,8 @@ namespace blender::geometry { PointCloud *point_merge_by_distance(const PointCloud &src_points, const float merge_distance, - const IndexMask selection) + const IndexMask selection, + const bke::AnonymousAttributePropagationInfo &propagation_info) { const bke::AttributeAccessor src_attributes = src_points.attributes(); VArraySpan positions = src_attributes.lookup_or_default( @@ -125,7 +126,7 @@ PointCloud *point_merge_by_distance(const PointCloud &src_points, /* Transfer all other attributes. */ for (const bke::AttributeIDRef &id : attribute_ids) { - if (!id.should_be_kept()) { + if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) { continue; } diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 57a4ae70b5f..9729d31779c 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -636,8 +636,11 @@ static OrderedAttributes gather_generic_pointcloud_attributes_to_propagate( } Map attributes_to_propagate; - in_geometry_set.gather_attributes_for_propagation( - src_component_types, GEO_COMPONENT_TYPE_POINT_CLOUD, true, attributes_to_propagate); + in_geometry_set.gather_attributes_for_propagation(src_component_types, + GEO_COMPONENT_TYPE_POINT_CLOUD, + true, + options.propagation_info, + attributes_to_propagate); attributes_to_propagate.remove("position"); r_create_id = attributes_to_propagate.pop_try("id").has_value(); r_create_radii = attributes_to_propagate.pop_try("radius").has_value(); @@ -829,8 +832,11 @@ static OrderedAttributes gather_generic_mesh_attributes_to_propagate( } Map attributes_to_propagate; - in_geometry_set.gather_attributes_for_propagation( - src_component_types, GEO_COMPONENT_TYPE_MESH, true, attributes_to_propagate); + in_geometry_set.gather_attributes_for_propagation(src_component_types, + GEO_COMPONENT_TYPE_MESH, + true, + options.propagation_info, + attributes_to_propagate); attributes_to_propagate.remove("position"); attributes_to_propagate.remove("normal"); attributes_to_propagate.remove("shade_smooth"); @@ -1149,8 +1155,11 @@ static OrderedAttributes gather_generic_curve_attributes_to_propagate( } Map attributes_to_propagate; - in_geometry_set.gather_attributes_for_propagation( - src_component_types, GEO_COMPONENT_TYPE_CURVE, true, attributes_to_propagate); + in_geometry_set.gather_attributes_for_propagation(src_component_types, + GEO_COMPONENT_TYPE_CURVE, + true, + options.propagation_info, + attributes_to_propagate); attributes_to_propagate.remove("position"); attributes_to_propagate.remove("radius"); attributes_to_propagate.remove("resolution"); diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc index c8f6e9a9226..cccf659ac5e 100644 --- a/source/blender/geometry/intern/resample_curves.cc +++ b/source/blender/geometry/intern/resample_curves.cc @@ -53,7 +53,7 @@ static fn::Field get_count_input_from_length(const fn::Field &length static bool interpolate_attribute_to_curves(const bke::AttributeIDRef &attribute_id, const std::array &type_counts) { - if (!attribute_id.is_named()) { + if (attribute_id.is_anonymous()) { return true; } if (ELEM(attribute_id.name(), @@ -81,7 +81,7 @@ static bool interpolate_attribute_to_poly_curve(const bke::AttributeIDRef &attri "handle_left", "nurbs_weight", }}; - return !(attribute_id.is_named() && no_interpolation.contains(attribute_id.name())); + return !no_interpolation.contains(attribute_id.name()); } /** diff --git a/source/blender/geometry/intern/set_curve_type.cc b/source/blender/geometry/intern/set_curve_type.cc index e069732ca9b..ab35f90b279 100644 --- a/source/blender/geometry/intern/set_curve_type.cc +++ b/source/blender/geometry/intern/set_curve_type.cc @@ -286,8 +286,10 @@ static void retrieve_curve_sizes(const bke::CurvesGeometry &curves, MutableSpan< }); } -static bke::CurvesGeometry convert_curves_to_bezier(const bke::CurvesGeometry &src_curves, - const IndexMask selection) +static bke::CurvesGeometry convert_curves_to_bezier( + const bke::CurvesGeometry &src_curves, + const IndexMask selection, + const bke::AnonymousAttributePropagationInfo &propagation_info) { const VArray src_knot_modes = src_curves.nurbs_knots_modes(); const VArray src_types = src_curves.curve_types(); @@ -315,6 +317,7 @@ static bke::CurvesGeometry convert_curves_to_bezier(const bke::CurvesGeometry &s src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, + propagation_info, {"position", "handle_type_left", "handle_type_right", @@ -460,8 +463,10 @@ static bke::CurvesGeometry convert_curves_to_bezier(const bke::CurvesGeometry &s return dst_curves; } -static bke::CurvesGeometry convert_curves_to_nurbs(const bke::CurvesGeometry &src_curves, - const IndexMask selection) +static bke::CurvesGeometry convert_curves_to_nurbs( + const bke::CurvesGeometry &src_curves, + const IndexMask selection, + const bke::AnonymousAttributePropagationInfo &propagation_info) { const VArray src_types = src_curves.curve_types(); const VArray src_cyclic = src_curves.cyclic(); @@ -487,6 +492,7 @@ static bke::CurvesGeometry convert_curves_to_nurbs(const bke::CurvesGeometry &sr src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, + propagation_info, {"position", "handle_type_left", "handle_type_right", @@ -639,16 +645,17 @@ static bke::CurvesGeometry convert_curves_trivial(const bke::CurvesGeometry &src bke::CurvesGeometry convert_curves(const bke::CurvesGeometry &src_curves, const IndexMask selection, - const CurveType dst_type) + const CurveType dst_type, + const bke::AnonymousAttributePropagationInfo &propagation_info) { switch (dst_type) { case CURVE_TYPE_CATMULL_ROM: case CURVE_TYPE_POLY: return convert_curves_trivial(src_curves, selection, dst_type); case CURVE_TYPE_BEZIER: - return convert_curves_to_bezier(src_curves, selection); + return convert_curves_to_bezier(src_curves, selection, propagation_info); case CURVE_TYPE_NURBS: - return convert_curves_to_nurbs(src_curves, selection); + return convert_curves_to_nurbs(src_curves, selection, propagation_info); } BLI_assert_unreachable(); return {}; diff --git a/source/blender/geometry/intern/subdivide_curves.cc b/source/blender/geometry/intern/subdivide_curves.cc index 021fa091364..e69a8398653 100644 --- a/source/blender/geometry/intern/subdivide_curves.cc +++ b/source/blender/geometry/intern/subdivide_curves.cc @@ -294,9 +294,11 @@ static void subdivide_bezier_positions(const Span src_positions, cyclic, dst_types_l, dst_types_r, dst_positions, dst_handles_l, dst_handles_r); } -bke::CurvesGeometry subdivide_curves(const bke::CurvesGeometry &src_curves, - const IndexMask selection, - const VArray &cuts) +bke::CurvesGeometry subdivide_curves( + const bke::CurvesGeometry &src_curves, + const IndexMask selection, + const VArray &cuts, + const bke::AnonymousAttributePropagationInfo &propagation_info) { const Vector unselected_ranges = selection.extract_ranges_invert( src_curves.curves_range()); @@ -338,7 +340,7 @@ bke::CurvesGeometry subdivide_curves(const bke::CurvesGeometry &src_curves, auto subdivide_catmull_rom = [&](IndexMask selection) { for (auto &attribute : bke::retrieve_attributes_for_transfer( - src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT)) { + src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info)) { subdivide_attribute_catmull_rom(src_curves, dst_curves, selection, @@ -352,7 +354,7 @@ bke::CurvesGeometry subdivide_curves(const bke::CurvesGeometry &src_curves, auto subdivide_poly = [&](IndexMask selection) { for (auto &attribute : bke::retrieve_attributes_for_transfer( - src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT)) { + src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info)) { subdivide_attribute_linear( src_curves, dst_curves, selection, point_offsets, attribute.src, attribute.dst.span); attribute.dst.finish(); @@ -396,6 +398,7 @@ bke::CurvesGeometry subdivide_curves(const bke::CurvesGeometry &src_curves, for (auto &attribute : bke::retrieve_attributes_for_transfer(src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, + propagation_info, {"position", "handle_type_left", "handle_type_right", @@ -421,7 +424,7 @@ bke::CurvesGeometry subdivide_curves(const bke::CurvesGeometry &src_curves, if (!unselected_ranges.is_empty()) { for (auto &attribute : bke::retrieve_attributes_for_transfer( - src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT)) { + src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info)) { bke::curves::copy_point_data( src_curves, dst_curves, unselected_ranges, attribute.src, attribute.dst.span); attribute.dst.finish(); diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc index 630ee8b8bab..53a22b581b5 100644 --- a/source/blender/geometry/intern/trim_curves.cc +++ b/source/blender/geometry/intern/trim_curves.cc @@ -929,7 +929,8 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, const IndexMask selection, const VArray &starts, const VArray &ends, - const GeometryNodeCurveSampleMode mode) + const GeometryNodeCurveSampleMode mode, + const bke::AnonymousAttributePropagationInfo &propagation_info) { BLI_assert(selection.size() > 0); BLI_assert(selection.last() <= src_curves.curves_num()); @@ -991,14 +992,19 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, transfer_curve_skip.remove("nurbs_order"); transfer_curve_skip.remove("knots_mode"); } - bke::copy_attribute_domain( - src_attributes, dst_attributes, selection, ATTR_DOMAIN_CURVE, transfer_curve_skip); + bke::copy_attribute_domain(src_attributes, + dst_attributes, + selection, + ATTR_DOMAIN_CURVE, + propagation_info, + transfer_curve_skip); /* Fetch custom point domain attributes for transfer (copy). */ Vector transfer_attributes = bke::retrieve_attributes_for_transfer( src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, + propagation_info, {"position", "handle_left", "handle_right", @@ -1063,8 +1069,12 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, /* Copy unselected */ if (!inverse_selection.is_empty()) { transfer_curve_skip.remove("cyclic"); - bke::copy_attribute_domain( - src_attributes, dst_attributes, inverse_selection, ATTR_DOMAIN_CURVE, transfer_curve_skip); + bke::copy_attribute_domain(src_attributes, + dst_attributes, + inverse_selection, + ATTR_DOMAIN_CURVE, + propagation_info, + transfer_curve_skip); /* Trim curves are no longer cyclic. If all curves are trimmed, this will be set implicitly. */ dst_curves.cyclic_for_write().fill_indices(selection, false); @@ -1075,8 +1085,11 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, } /* Copy point domain. */ - for (auto &attribute : bke::retrieve_attributes_for_transfer( - src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, copy_point_skip)) { + for (auto &attribute : bke::retrieve_attributes_for_transfer(src_attributes, + dst_attributes, + ATTR_DOMAIN_MASK_POINT, + propagation_info, + copy_point_skip)) { bke::curves::copy_point_data( src_curves, dst_curves, inverse_selection, attribute.src, attribute.dst.span); attribute.dst.finish(); diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 3bff2f4316c..0710ed6d30f 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -15,7 +15,15 @@ extern "C" { #endif -struct AnonymousAttributeID; +/** Workaround to forward-declare C++ type in C header. */ +#ifdef __cplusplus +namespace blender::bke { +class AnonymousAttributeID; +} // namespace blender::bke +using AnonymousAttributeIDHandle = blender::bke::AnonymousAttributeID; +#else +typedef struct AnonymousAttributeIDHandle AnonymousAttributeIDHandle; +#endif /** Descriptor and storage for a custom data layer. */ typedef struct CustomDataLayer { @@ -40,12 +48,10 @@ typedef struct CustomDataLayer { /** Layer data. */ void *data; /** - * Run-time identifier for this layer. If no one has a strong reference to this id anymore, - * the layer can be removed. The custom data layer only has a weak reference to the id, because - * otherwise there will always be a strong reference and the attribute can't be removed - * automatically. + * Run-time identifier for this layer. Can be used to retrieve information about where this + * attribute was created. */ - const struct AnonymousAttributeID *anonymous_id; + const AnonymousAttributeIDHandle *anonymous_id; } CustomDataLayer; #define MAX_CUSTOMDATA_LAYER_NAME 64 diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index ebd5bf351ea..93b61ad76ab 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -884,12 +884,12 @@ static void find_side_effect_nodes_for_viewer_path( /* Not only mark the viewer node as having side effects, but also all group nodes it is contained * in. */ - r_side_effect_nodes.add(compute_context_builder.hash(), - &find_viewer_lf_node(*found_viewer_node)); + r_side_effect_nodes.add_non_duplicates(compute_context_builder.hash(), + &find_viewer_lf_node(*found_viewer_node)); compute_context_builder.pop(); while (!compute_context_builder.is_empty()) { - r_side_effect_nodes.add(compute_context_builder.hash(), - &find_group_lf_node(*group_node_stack.pop())); + r_side_effect_nodes.add_non_duplicates(compute_context_builder.hash(), + &find_group_lf_node(*group_node_stack.pop())); compute_context_builder.pop(); } } @@ -1124,12 +1124,11 @@ static GeometrySet compute_geometry( { const blender::nodes::GeometryNodeLazyFunctionGraphMapping &mapping = lf_graph_info.mapping; - Span graph_inputs = mapping.group_input_sockets; - Vector graph_outputs; - for (const bNodeSocket *bsocket : output_node.input_sockets().drop_back(1)) { - const lf::InputSocket &socket = mapping.dummy_socket_map.lookup(bsocket)->as_input(); - graph_outputs.append(&socket); - } + Vector graph_inputs = mapping.group_input_sockets; + graph_inputs.extend(mapping.group_output_used_sockets); + graph_inputs.extend(mapping.attribute_set_by_geometry_output.values().begin(), + mapping.attribute_set_by_geometry_output.values().end()); + Vector graph_outputs = mapping.standard_group_output_sockets; Array param_inputs(graph_inputs.size()); Array param_outputs(graph_outputs.size()); @@ -1166,21 +1165,36 @@ static GeometrySet compute_geometry( blender::LinearAllocator<> allocator; Vector inputs_to_destruct; - int input_index; - LISTBASE_FOREACH_INDEX (bNodeSocket *, interface_socket, &btree.inputs, input_index) { - if (interface_socket->type == SOCK_GEOMETRY && input_index == 0) { + int input_index = -1; + for (const int i : btree.interface_inputs().index_range()) { + input_index++; + const bNodeSocket &interface_socket = *btree.interface_inputs()[i]; + if (interface_socket.type == SOCK_GEOMETRY && input_index == 0) { param_inputs[input_index] = &input_geometry_set; continue; } - const CPPType *type = interface_socket->typeinfo->geometry_nodes_cpp_type; + const CPPType *type = interface_socket.typeinfo->geometry_nodes_cpp_type; BLI_assert(type != nullptr); void *value = allocator.allocate(type->size(), type->alignment()); - initialize_group_input(*nmd, *interface_socket, input_index, value); + initialize_group_input(*nmd, interface_socket, i, value); param_inputs[input_index] = {type, value}; inputs_to_destruct.append({type, value}); } + Array output_used_inputs(btree.interface_outputs().size(), true); + for (const int i : btree.interface_outputs().index_range()) { + input_index++; + param_inputs[input_index] = &output_used_inputs[i]; + } + + Array attributes_to_propagate( + mapping.attribute_set_by_geometry_output.size()); + for (const int i : attributes_to_propagate.index_range()) { + input_index++; + param_inputs[input_index] = &attributes_to_propagate[i]; + } + for (const int i : graph_outputs.index_range()) { const lf::InputSocket &socket = *graph_outputs[i]; const CPPType &type = socket.type(); diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh index 73e82f741ab..60f58f4c215 100644 --- a/source/blender/nodes/NOD_geometry_exec.hh +++ b/source/blender/nodes/NOD_geometry_exec.hh @@ -19,6 +19,8 @@ struct ModifierData; namespace blender::nodes { using bke::AnonymousAttributeFieldInput; +using bke::AnonymousAttributeID; +using bke::AnonymousAttributePropagationInfo; using bke::AttributeAccessor; using bke::AttributeFieldInput; using bke::AttributeIDRef; @@ -26,13 +28,12 @@ using bke::AttributeKind; using bke::AttributeMetaData; using bke::AttributeReader; using bke::AttributeWriter; +using bke::AutoAnonymousAttributeID; using bke::GAttributeReader; using bke::GAttributeWriter; using bke::GSpanAttributeWriter; using bke::MutableAttributeAccessor; using bke::SpanAttributeWriter; -using bke::StrongAnonymousAttributeID; -using bke::WeakAnonymousAttributeID; using fn::Field; using fn::FieldContext; using fn::FieldEvaluator; @@ -43,15 +44,38 @@ using fn::ValueOrField; using geo_eval_log::NamedAttributeUsage; using geo_eval_log::NodeWarningType; +/** + * An anonymous attribute created by a node. + */ +class NodeAnonymousAttributeID : public AnonymousAttributeID { + std::string long_name_; + + public: + NodeAnonymousAttributeID(const Object &object, + const ComputeContext &compute_context, + const bNode &bnode, + const StringRef identifier); +}; + class GeoNodeExecParams { private: const bNode &node_; lf::Params ¶ms_; const lf::Context &lf_context_; + const Map &lf_input_for_output_bsocket_usage_; + const Map &lf_input_for_attribute_propagation_to_output_; public: - GeoNodeExecParams(const bNode &node, lf::Params ¶ms, const lf::Context &lf_context) - : node_(node), params_(params), lf_context_(lf_context) + GeoNodeExecParams(const bNode &node, + lf::Params ¶ms, + const lf::Context &lf_context, + const Map &lf_input_for_output_bsocket_usage, + const Map &lf_input_for_attribute_propagation_to_output) + : node_(node), + params_(params), + lf_context_(lf_context), + lf_input_for_output_bsocket_usage_(lf_input_for_output_bsocket_usage), + lf_input_for_attribute_propagation_to_output_(lf_input_for_attribute_propagation_to_output) { } @@ -245,6 +269,49 @@ class GeoNodeExecParams { void used_named_attribute(StringRef attribute_name, NamedAttributeUsage usage); + /** + * Return true when the anonymous attribute referenced by the given output should be created. + */ + bool anonymous_attribute_output_is_required(const StringRef output_identifier) + { + const int lf_index = lf_input_for_output_bsocket_usage_.lookup(output_identifier); + return params_.get_input(lf_index); + } + + /** + * Return a new anonymous attribute id for the given output. None is returned if the anonymous + * attribute is not needed. + */ + AutoAnonymousAttributeID get_output_anonymous_attribute_id_if_needed( + const StringRef output_identifier) + { + if (!this->anonymous_attribute_output_is_required(output_identifier)) { + return {}; + } + const GeoNodesLFUserData &user_data = *this->user_data(); + const ComputeContext &compute_context = *user_data.compute_context; + return MEM_new(__func__, + *user_data.modifier_data->self_object, + compute_context, + node_, + output_identifier); + } + + /** + * Get information about which anonymous attributes should be propagated to the given output. + */ + AnonymousAttributePropagationInfo get_output_propagation_info( + const StringRef output_identifier) const + { + const int lf_index = lf_input_for_attribute_propagation_to_output_.lookup(output_identifier); + const bke::AnonymousAttributeSet &set = params_.get_input( + lf_index); + AnonymousAttributePropagationInfo info; + info.names = set.names; + info.propagate_all = false; + return info; + } + private: /* Utilities for detecting common errors at when using this class. */ void check_input_access(StringRef identifier, const CPPType *requested_type = nullptr) const; diff --git a/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh b/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh index 84c264f4976..7f49d067061 100644 --- a/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh +++ b/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh @@ -78,6 +78,28 @@ struct GeoNodesLFUserData : public lf::UserData { bool log_socket_values = true; }; +/** + * In the general case, this is #DynamicSocket. That means that to determine if a node group will + * use a particular input, it has to be partially executed. + * + * In other cases, it's not necessary to look into the node group to determine if an input is + * necessary. + */ +enum class InputUsageHintType { + /** The input socket is never used. */ + Never, + /** The input socket is used when a subset of the outputs is used. */ + DependsOnOutput, + /** Can't determine statically if the input is used, check the corresponding output socket. */ + DynamicSocket, +}; + +struct InputUsageHint { + InputUsageHintType type = InputUsageHintType::DependsOnOutput; + /** Used in depends-on-output mode. */ + Vector output_dependencies; +}; + /** * Contains the mapping between the #bNodeTree and the corresponding lazy-function graph. * This is *not* a one-to-one mapping. @@ -91,7 +113,32 @@ struct GeometryNodeLazyFunctionGraphMapping { * The inputs sockets in the graph. Multiple group input nodes are combined into one in the * lazy-function graph. */ - Vector group_input_sockets; + Vector group_input_sockets; + /** + * Dummy output sockets that correspond to the active group output node. If there is no such + * node, defaulted fallback outputs are created. + */ + Vector standard_group_output_sockets; + /** + * Dummy boolean sockets that have to be passed in from the outside and indicate whether a + * specific output will be used. + */ + Vector group_output_used_sockets; + /** + * Dummy boolean sockets that can be used as group output that indicate whether a specific input + * will be used (this may depend on the used outputs as well as other inputs). + */ + Vector group_input_usage_sockets; + /** + * This is an optimization to avoid partially evaluating a node group just to figure out which + * inputs are needed. + */ + Vector group_input_usage_hints; + /** + * If the node group propagates attributes from an input geometry to the output, it has to know + * which attributes should be propagated and which can be removed (for optimization purposes). + */ + Map attribute_set_by_geometry_output; /** * A mapping used for logging intermediate values. */ diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh index d99b4c01ed7..ce6b4cd6cfe 100644 --- a/source/blender/nodes/geometry/node_geometry_util.hh +++ b/source/blender/nodes/geometry/node_geometry_util.hh @@ -50,10 +50,10 @@ Mesh *create_grid_mesh( int verts_x, int verts_y, float size_x, float size_y, const AttributeIDRef &uv_map_id); struct ConeAttributeOutputs { - StrongAnonymousAttributeID top_id; - StrongAnonymousAttributeID bottom_id; - StrongAnonymousAttributeID side_id; - StrongAnonymousAttributeID uv_map_id; + AutoAnonymousAttributeID top_id; + AutoAnonymousAttributeID bottom_id; + AutoAnonymousAttributeID side_id; + AutoAnonymousAttributeID uv_map_id; }; Mesh *create_cylinder_or_cone_mesh(float radius_top, @@ -81,6 +81,7 @@ void separate_geometry(GeometrySet &geometry_set, eAttrDomain domain, GeometryNodeDeleteGeometryMode mode, const Field &selection_field, + const AnonymousAttributePropagationInfo &propagation_info, bool &r_is_error); void get_closest_in_bvhtree(BVHTreeFromMesh &tree_data, diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc index 826f08e4c8d..a07cd1437d6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc @@ -142,9 +142,12 @@ static void node_geo_exec(GeoNodeExecParams params) const eAttrDomain domain = eAttrDomain(storage.domain); const std::string output_identifier = "Attribute" + identifier_suffix(data_type); + AutoAnonymousAttributeID attribute_id = params.get_output_anonymous_attribute_id_if_needed( + output_identifier); - if (!params.output_is_required(output_identifier)) { + if (!attribute_id) { params.set_output("Geometry", geometry_set); + params.set_default_remaining_outputs(); return; } @@ -171,7 +174,6 @@ static void node_geo_exec(GeoNodeExecParams params) break; } - WeakAnonymousAttributeID anonymous_id{"Attribute"}; const CPPType &type = field.cpp_type(); /* Run on the instances component separately to only affect the top level of instances. */ @@ -179,7 +181,7 @@ static void node_geo_exec(GeoNodeExecParams params) if (geometry_set.has_instances()) { GeometryComponent &component = geometry_set.get_component_for_write( GEO_COMPONENT_TYPE_INSTANCES); - bke::try_capture_field_on_geometry(component, anonymous_id.get(), domain, field); + bke::try_capture_field_on_geometry(component, *attribute_id, domain, field); } } else { @@ -190,14 +192,14 @@ static void node_geo_exec(GeoNodeExecParams params) for (const GeometryComponentType type : types) { if (geometry_set.has(type)) { GeometryComponent &component = geometry_set.get_component_for_write(type); - bke::try_capture_field_on_geometry(component, anonymous_id.get(), domain, field); + bke::try_capture_field_on_geometry(component, *attribute_id, domain, field); } } }); } GField output_field{std::make_shared( - std::move(anonymous_id), type, params.attribute_producer_name())}; + std::move(attribute_id), type, params.attribute_producer_name())}; switch (data_type) { case CD_PROP_FLOAT: { diff --git a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc index a1c4af79851..0135567c5e4 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_boolean.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_boolean.cc @@ -30,7 +30,7 @@ static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) } struct AttributeOutputs { - StrongAnonymousAttributeID intersecting_edges_id; + AutoAnonymousAttributeID intersecting_edges_id; }; static void node_update(bNodeTree *ntree, bNode *node) @@ -125,9 +125,8 @@ static void node_geo_exec(GeoNodeExecParams params) } AttributeOutputs attribute_outputs; - if (params.output_is_required("Intersecting Edges")) { - attribute_outputs.intersecting_edges_id = StrongAnonymousAttributeID("Intersecting Edges"); - } + attribute_outputs.intersecting_edges_id = params.get_output_anonymous_attribute_id_if_needed( + "Intersecting Edges"); Vector intersecting_edges; Mesh *result = blender::meshintersect::direct_mesh_boolean( diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc index ef839bf2acb..627abcab861 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fillet.cc @@ -67,6 +67,9 @@ static void node_geo_exec(GeoNodeExecParams params) count_field.emplace(params.extract_input>("Count")); } + const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info( + "Curve"); + geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { if (!geometry_set.has_curves()) { return; @@ -82,7 +85,11 @@ static void node_geo_exec(GeoNodeExecParams params) case GEO_NODE_CURVE_FILLET_BEZIER: { evaluator.evaluate(); bke::CurvesGeometry dst_curves = geometry::fillet_curves_bezier( - curves, curves.curves_range(), evaluator.get_evaluated(0), limit_radius); + curves, + curves.curves_range(), + evaluator.get_evaluated(0), + limit_radius, + propagation_info); Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves)); bke::curves_copy_parameters(curves_id, *dst_curves_id); geometry_set.replace_curves(dst_curves_id); @@ -96,7 +103,8 @@ static void node_geo_exec(GeoNodeExecParams params) curves.curves_range(), evaluator.get_evaluated(0), evaluator.get_evaluated(1), - limit_radius); + limit_radius, + propagation_info); Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves)); bke::curves_copy_parameters(curves_id, *dst_curves_id); geometry_set.replace_curves(dst_curves_id); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc index 13353553379..873b66688c5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_primitive_star.cc @@ -59,10 +59,10 @@ static Curves *create_star_curve(const float inner_radius, } static void create_selection_output(CurveComponent &component, - StrongAnonymousAttributeID &r_attribute) + AutoAnonymousAttributeID &r_attribute) { SpanAttributeWriter selection = - component.attributes_for_write()->lookup_or_add_for_write_only_span(r_attribute.get(), + component.attributes_for_write()->lookup_or_add_for_write_only_span(*r_attribute, ATTR_DOMAIN_POINT); for (int i : selection.span.index_range()) { selection.span[i] = i % 2 == 0; @@ -78,12 +78,12 @@ static void node_geo_exec(GeoNodeExecParams params) std::max(params.extract_input("Points"), 3)); GeometrySet output = GeometrySet::create_with_curves(curves); - if (params.output_is_required("Outer Points")) { - StrongAnonymousAttributeID attribute_output("Outer Points"); - create_selection_output(output.get_component_for_write(), attribute_output); + if (AutoAnonymousAttributeID outer_points_id = + params.get_output_anonymous_attribute_id_if_needed("Outer Points")) { + create_selection_output(output.get_component_for_write(), outer_points_id); params.set_output("Outer Points", AnonymousAttributeFieldInput::Create( - std::move(attribute_output), params.attribute_producer_name())); + std::move(outer_points_id), params.attribute_producer_name())); } params.set_output("Curve", std::move(output)); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc index 3d8d14473db..64a9ae08c9b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_type.cc @@ -67,7 +67,8 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - bke::CurvesGeometry dst_curves = geometry::convert_curves(src_curves, selection, dst_type); + bke::CurvesGeometry dst_curves = geometry::convert_curves( + src_curves, selection, dst_type, params.get_output_propagation_info("Curve")); Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves)); bke::curves_copy_parameters(src_curves_id, *dst_curves_id); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc index b01dd2e5361..479fdef56e7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_subdivide.cc @@ -49,7 +49,7 @@ static void node_geo_exec(GeoNodeExecParams params) } bke::CurvesGeometry dst_curves = geometry::subdivide_curves( - src_curves, src_curves.curves_range(), cuts); + src_curves, src_curves.curves_range(), cuts, params.get_output_propagation_info("Curve")); Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves)); bke::curves_copy_parameters(src_curves_id, *dst_curves_id); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc index 057496144d5..0b46fe569d1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc @@ -25,7 +25,8 @@ static void node_declare(NodeDeclarationBuilder &b) static void geometry_set_curve_to_mesh(GeometrySet &geometry_set, const GeometrySet &profile_set, - const bool fill_caps) + const bool fill_caps, + const AnonymousAttributePropagationInfo &propagation_info) { const Curves &curves = *geometry_set.get_curves_for_read(); const Curves *profile_curves = profile_set.get_curves_for_read(); @@ -33,13 +34,15 @@ static void geometry_set_curve_to_mesh(GeometrySet &geometry_set, GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set); if (profile_curves == nullptr) { - Mesh *mesh = bke::curve_to_wire_mesh(bke::CurvesGeometry::wrap(curves.geometry)); + Mesh *mesh = bke::curve_to_wire_mesh(bke::CurvesGeometry::wrap(curves.geometry), + propagation_info); geometry_set.replace_mesh(mesh); } else { Mesh *mesh = bke::curve_to_mesh_sweep(bke::CurvesGeometry::wrap(curves.geometry), bke::CurvesGeometry::wrap(profile_curves->geometry), - fill_caps); + fill_caps, + propagation_info); geometry_set.replace_mesh(mesh); } } @@ -52,7 +55,8 @@ static void node_geo_exec(GeoNodeExecParams params) curve_set.modify_geometry_sets([&](GeometrySet &geometry_set) { if (geometry_set.has_curves()) { - geometry_set_curve_to_mesh(geometry_set, profile_set, fill_caps); + geometry_set_curve_to_mesh( + geometry_set, profile_set, fill_caps, params.get_output_propagation_info("Mesh")); } geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH}); }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc index 4442dfa0fdb..6e443f1efb7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc @@ -111,19 +111,12 @@ static void node_geo_exec(GeoNodeExecParams params) GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set); - StrongAnonymousAttributeID tangent_anonymous_id; - StrongAnonymousAttributeID normal_anonymous_id; - StrongAnonymousAttributeID rotation_anonymous_id; - const bool rotation_required = params.output_is_required("Rotation"); - if (params.output_is_required("Tangent") || rotation_required) { - tangent_anonymous_id = StrongAnonymousAttributeID("Tangent"); - } - if (params.output_is_required("Normal") || rotation_required) { - normal_anonymous_id = StrongAnonymousAttributeID("Normal"); - } - if (rotation_required) { - rotation_anonymous_id = StrongAnonymousAttributeID("Rotation"); - } + AutoAnonymousAttributeID tangent_anonymous_id = + params.get_output_anonymous_attribute_id_if_needed("Tangent"); + AutoAnonymousAttributeID normal_anonymous_id = + params.get_output_anonymous_attribute_id_if_needed("Normal"); + AutoAnonymousAttributeID rotation_anonymous_id = + params.get_output_anonymous_attribute_id_if_needed("Rotation"); geometry::ResampleCurvesOutputAttributeIDs resample_attributes; resample_attributes.tangent_id = tangent_anonymous_id.get(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc index 97b72838b39..56912931571 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_trim.cc @@ -112,7 +112,8 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set, const GeometryNodeCurveSampleMode mode, Field &selection_field, Field &start_field, - Field &end_field) + Field &end_field, + const AnonymousAttributePropagationInfo &propagation_info) { if (!geometry_set.has_curves()) { return; @@ -139,7 +140,7 @@ static void geometry_set_curve_trim(GeometrySet &geometry_set, } bke::CurvesGeometry dst_curves = geometry::trim_curves( - src_curves, selection, starts, ends, mode); + src_curves, selection, starts, ends, mode, propagation_info); Curves *dst_curves_id = bke::curves_new_nomain(std::move(dst_curves)); bke::curves_copy_parameters(src_curves_id, *dst_curves_id); geometry_set.replace_curves(dst_curves_id); @@ -153,19 +154,24 @@ static void node_geo_exec(GeoNodeExecParams params) GeometrySet geometry_set = params.extract_input("Curve"); GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set); + const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info( + "Curve"); + Field selection_field = params.extract_input>("Selection"); if (mode == GEO_NODE_CURVE_SAMPLE_FACTOR) { Field start_field = params.extract_input>("Start"); Field end_field = params.extract_input>("End"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - geometry_set_curve_trim(geometry_set, mode, selection_field, start_field, end_field); + geometry_set_curve_trim( + geometry_set, mode, selection_field, start_field, end_field, propagation_info); }); } else if (mode == GEO_NODE_CURVE_SAMPLE_LENGTH) { Field start_field = params.extract_input>("Start_001"); Field end_field = params.extract_input>("End_001"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - geometry_set_curve_trim(geometry_set, mode, selection_field, start_field, end_field); + geometry_set_curve_trim( + geometry_set, mode, selection_field, start_field, end_field, propagation_info); }); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc index 92937482116..e92fe1a613d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc @@ -306,7 +306,8 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh, static void delete_curves_selection(GeometrySet &geometry_set, const Field &selection_field, - const eAttrDomain selection_domain) + const eAttrDomain selection_domain, + const bke::AnonymousAttributePropagationInfo &propagation_info) { const Curves &src_curves_id = *geometry_set.get_curves_for_read(); const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry); @@ -330,15 +331,17 @@ static void delete_curves_selection(GeometrySet &geometry_set, bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); if (selection_domain == ATTR_DOMAIN_POINT) { - curves.remove_points(selection); + curves.remove_points(selection, propagation_info); } else if (selection_domain == ATTR_DOMAIN_CURVE) { - curves.remove_curves(selection); + curves.remove_curves(selection, propagation_info); } } -static void separate_point_cloud_selection(GeometrySet &geometry_set, - const Field &selection_field) +static void separate_point_cloud_selection( + GeometrySet &geometry_set, + const Field &selection_field, + const AnonymousAttributePropagationInfo &propagation_info) { const PointCloud &src_pointcloud = *geometry_set.get_pointcloud_for_read(); @@ -355,8 +358,11 @@ static void separate_point_cloud_selection(GeometrySet &geometry_set, PointCloud *pointcloud = BKE_pointcloud_new_nomain(selection.size()); Map attributes; - geometry_set.gather_attributes_for_propagation( - {GEO_COMPONENT_TYPE_POINT_CLOUD}, GEO_COMPONENT_TYPE_POINT_CLOUD, false, attributes); + geometry_set.gather_attributes_for_propagation({GEO_COMPONENT_TYPE_POINT_CLOUD}, + GEO_COMPONENT_TYPE_POINT_CLOUD, + false, + propagation_info, + attributes); copy_attributes_based_on_mask(attributes, src_pointcloud.attributes(), @@ -367,7 +373,8 @@ static void separate_point_cloud_selection(GeometrySet &geometry_set, } static void delete_selected_instances(GeometrySet &geometry_set, - const Field &selection_field) + const Field &selection_field, + const AnonymousAttributePropagationInfo &propagation_info) { bke::Instances &instances = *geometry_set.get_instances_for_write(); bke::InstancesFieldContext field_context{instances}; @@ -381,7 +388,7 @@ static void delete_selected_instances(GeometrySet &geometry_set, return; } - instances.remove(selection); + instances.remove(selection, propagation_info); } static void compute_selected_verts_from_vertex_selection(const Span vertex_selection, @@ -819,7 +826,8 @@ static void do_mesh_separation(GeometrySet &geometry_set, const Mesh &mesh_in, const Span selection, const eAttrDomain domain, - const GeometryNodeDeleteGeometryMode mode) + const GeometryNodeDeleteGeometryMode mode, + const AnonymousAttributePropagationInfo &propagation_info) { /* Needed in all cases. */ Vector selected_poly_indices; @@ -831,7 +839,7 @@ static void do_mesh_separation(GeometrySet &geometry_set, Map attributes; geometry_set.gather_attributes_for_propagation( - {GEO_COMPONENT_TYPE_MESH}, GEO_COMPONENT_TYPE_MESH, false, attributes); + {GEO_COMPONENT_TYPE_MESH}, GEO_COMPONENT_TYPE_MESH, false, propagation_info, attributes); switch (mode) { case GEO_NODE_DELETE_GEOMETRY_MODE_ALL: { @@ -1059,7 +1067,8 @@ static void do_mesh_separation(GeometrySet &geometry_set, static void separate_mesh_selection(GeometrySet &geometry_set, const Field &selection_field, const eAttrDomain selection_domain, - const GeometryNodeDeleteGeometryMode mode) + const GeometryNodeDeleteGeometryMode mode, + const AnonymousAttributePropagationInfo &propagation_info) { const Mesh &src_mesh = *geometry_set.get_mesh_for_read(); bke::MeshFieldContext field_context{src_mesh, selection_domain}; @@ -1074,7 +1083,8 @@ static void separate_mesh_selection(GeometrySet &geometry_set, const VArraySpan selection_span{selection}; - do_mesh_separation(geometry_set, src_mesh, selection_span, selection_domain, mode); + do_mesh_separation( + geometry_set, src_mesh, selection_span, selection_domain, mode, propagation_info); } } // namespace blender::nodes::node_geo_delete_geometry_cc @@ -1085,6 +1095,7 @@ void separate_geometry(GeometrySet &geometry_set, const eAttrDomain domain, const GeometryNodeDeleteGeometryMode mode, const Field &selection_field, + const AnonymousAttributePropagationInfo &propagation_info, bool &r_is_error) { namespace file_ns = blender::nodes::node_geo_delete_geometry_cc; @@ -1092,26 +1103,27 @@ void separate_geometry(GeometrySet &geometry_set, bool some_valid_domain = false; if (geometry_set.has_pointcloud()) { if (domain == ATTR_DOMAIN_POINT) { - file_ns::separate_point_cloud_selection(geometry_set, selection_field); + file_ns::separate_point_cloud_selection(geometry_set, selection_field, propagation_info); some_valid_domain = true; } } if (geometry_set.has_mesh()) { if (ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_FACE, ATTR_DOMAIN_CORNER)) { - file_ns::separate_mesh_selection(geometry_set, selection_field, domain, mode); + file_ns::separate_mesh_selection( + geometry_set, selection_field, domain, mode, propagation_info); some_valid_domain = true; } } if (geometry_set.has_curves()) { if (ELEM(domain, ATTR_DOMAIN_POINT, ATTR_DOMAIN_CURVE)) { file_ns::delete_curves_selection( - geometry_set, fn::invert_boolean_field(selection_field), domain); + geometry_set, fn::invert_boolean_field(selection_field), domain, propagation_info); some_valid_domain = true; } } if (geometry_set.has_instances()) { if (domain == ATTR_DOMAIN_INSTANCE) { - file_ns::delete_selected_instances(geometry_set, selection_field); + file_ns::delete_selected_instances(geometry_set, selection_field, propagation_info); some_valid_domain = true; } } @@ -1171,15 +1183,18 @@ static void node_geo_exec(GeoNodeExecParams params) const eAttrDomain domain = eAttrDomain(storage.domain); const GeometryNodeDeleteGeometryMode mode = (GeometryNodeDeleteGeometryMode)storage.mode; + const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info( + "Geometry"); + if (domain == ATTR_DOMAIN_INSTANCE) { bool is_error; - separate_geometry(geometry_set, domain, mode, selection, is_error); + separate_geometry(geometry_set, domain, mode, selection, propagation_info, is_error); } else { geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { bool is_error; /* Invert here because we want to keep the things not in the selection. */ - separate_geometry(geometry_set, domain, mode, selection, is_error); + separate_geometry(geometry_set, domain, mode, selection, propagation_info, is_error); }); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc index a5bdc989a04..91fa215d117 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc @@ -320,8 +320,8 @@ BLI_NOINLINE static void propagate_existing_attributes( namespace { struct AttributeOutputs { - StrongAnonymousAttributeID normal_id; - StrongAnonymousAttributeID rotation_id; + AutoAnonymousAttributeID normal_id; + AutoAnonymousAttributeID rotation_id; }; } // namespace @@ -496,8 +496,11 @@ static void point_distribution_calculate(GeometrySet &geometry_set, geometry_set.replace_pointcloud(pointcloud); Map attributes; - geometry_set.gather_attributes_for_propagation( - {GEO_COMPONENT_TYPE_MESH}, GEO_COMPONENT_TYPE_POINT_CLOUD, false, attributes); + geometry_set.gather_attributes_for_propagation({GEO_COMPONENT_TYPE_MESH}, + GEO_COMPONENT_TYPE_POINT_CLOUD, + false, + params.get_output_propagation_info("Points"), + attributes); /* Position is set separately. */ attributes.remove("position"); @@ -518,12 +521,8 @@ static void node_geo_exec(GeoNodeExecParams params) const Field selection_field = params.extract_input>("Selection"); AttributeOutputs attribute_outputs; - if (params.output_is_required("Normal")) { - attribute_outputs.normal_id = StrongAnonymousAttributeID("Normal"); - } - if (params.output_is_required("Rotation")) { - attribute_outputs.rotation_id = StrongAnonymousAttributeID("Rotation"); - } + attribute_outputs.normal_id = params.get_output_anonymous_attribute_id_if_needed("Normal"); + attribute_outputs.rotation_id = params.get_output_anonymous_attribute_id_if_needed("Rotation"); lazy_threading::send_hint(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc index bb48db48559..b076f0b7261 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc @@ -132,6 +132,7 @@ static void transfer_attributes( const Span new_to_old_edges_map, const Span new_to_old_face_corners_map, const Span> boundary_vertex_to_relevant_face_map, + const AnonymousAttributePropagationInfo &propagation_info, const AttributeAccessor src_attributes, MutableAttributeAccessor dst_attributes) { @@ -139,7 +140,9 @@ static void transfer_attributes( * Remove anonymous attributes that don't need to be propagated. */ Set attribute_ids = src_attributes.all_ids(); attribute_ids.remove("position"); - attribute_ids.remove_if([](const AttributeIDRef &id) { return !id.should_be_kept(); }); + attribute_ids.remove_if([&](const AttributeIDRef &id) { + return id.is_anonymous() && !propagation_info.propagate(id.anonymous_id()); + }); for (const AttributeIDRef &id : attribute_ids) { GAttributeReader src_attribute = src_attributes.lookup(id); @@ -606,7 +609,9 @@ static void dissolve_redundant_verts(const Span edges, * * Some special cases are needed for boundaries and non-manifold geometry. */ -static Mesh *calc_dual_mesh(const Mesh &src_mesh, const bool keep_boundaries) +static Mesh *calc_dual_mesh(const Mesh &src_mesh, + const bool keep_boundaries, + const AnonymousAttributePropagationInfo &propagation_info) { const Span src_verts = src_mesh.verts(); const Span src_edges = src_mesh.edges(); @@ -887,6 +892,7 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, const bool keep_boundaries) new_to_old_edges_map, new_to_old_face_corners_map, boundary_vertex_to_relevant_face_map, + propagation_info, src_mesh.attributes(), mesh_out->attributes_for_write()); @@ -918,7 +924,8 @@ static void node_geo_exec(GeoNodeExecParams params) const bool keep_boundaries = params.extract_input("Keep Boundaries"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { if (const Mesh *mesh = geometry_set.get_mesh_for_read()) { - Mesh *new_mesh = calc_dual_mesh(*mesh, keep_boundaries); + Mesh *new_mesh = calc_dual_mesh( + *mesh, keep_boundaries, params.get_output_propagation_info("Dual Mesh")); geometry_set.replace_mesh(new_mesh); } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index a53f92e3b9f..cd191fa8498 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -56,7 +56,7 @@ static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) } struct IndexAttributes { - StrongAnonymousAttributeID duplicate_index; + AutoAnonymousAttributeID duplicate_index; }; /* -------------------------------------------------------------------- */ @@ -64,11 +64,13 @@ struct IndexAttributes { * \{ */ static Map gather_attributes_without_id( - const GeometrySet &geometry_set, const GeometryComponentType component_type) + const GeometrySet &geometry_set, + const GeometryComponentType component_type, + const AnonymousAttributePropagationInfo &propagation_info) { Map attributes; geometry_set.gather_attributes_for_propagation( - {component_type}, component_type, false, attributes); + {component_type}, component_type, false, propagation_info, attributes); attributes.remove("id"); return attributes; }; @@ -181,11 +183,12 @@ static void copy_attributes_without_id(GeometrySet &geometry_set, const eAttrDomain domain, const Span offsets, const IndexMask selection, + const AnonymousAttributePropagationInfo &propagation_info, const bke::AttributeAccessor src_attributes, bke::MutableAttributeAccessor dst_attributes) { const Map attributes = gather_attributes_without_id( - geometry_set, component_type); + geometry_set, component_type, propagation_info); for (const Map::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; @@ -221,14 +224,16 @@ static void copy_attributes_without_id(GeometrySet &geometry_set, * Copies the attributes for curve duplicates. If copying the curve domain, the attributes are * copied with an offset fill, otherwise a mapping is used. */ -static void copy_curve_attributes_without_id(const GeometrySet &geometry_set, - const bke::CurvesGeometry &src_curves, - const IndexMask selection, - const Span curve_offsets, - bke::CurvesGeometry &dst_curves) +static void copy_curve_attributes_without_id( + const GeometrySet &geometry_set, + const bke::CurvesGeometry &src_curves, + const IndexMask selection, + const Span curve_offsets, + const AnonymousAttributePropagationInfo &propagation_info, + bke::CurvesGeometry &dst_curves) { Map attributes = gather_attributes_without_id( - geometry_set, GEO_COMPONENT_TYPE_CURVE); + geometry_set, GEO_COMPONENT_TYPE_CURVE, propagation_info); for (const Map::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; @@ -318,7 +323,8 @@ static void copy_stable_id_curves(const bke::CurvesGeometry &src_curves, static void duplicate_curves(GeometrySet &geometry_set, const Field &count_field, const Field &selection_field, - const IndexAttributes &attribute_outputs) + const IndexAttributes &attribute_outputs, + const AnonymousAttributePropagationInfo &propagation_info) { if (!geometry_set.has_curves()) { geometry_set.remove_geometry_during_modify(); @@ -373,7 +379,8 @@ static void duplicate_curves(GeometrySet &geometry_set, }); all_dst_offsets.last() = dst_points_num; - copy_curve_attributes_without_id(geometry_set, curves, selection, curve_offsets, new_curves); + copy_curve_attributes_without_id( + geometry_set, curves, selection, curve_offsets, propagation_info, new_curves); copy_stable_id_curves(curves, selection, curve_offsets, new_curves); @@ -398,17 +405,19 @@ static void duplicate_curves(GeometrySet &geometry_set, * Copies the attributes for face duplicates. If copying the face domain, the attributes are * copied with an offset fill, otherwise a mapping is used. */ -static void copy_face_attributes_without_id(GeometrySet &geometry_set, - const Span edge_mapping, - const Span vert_mapping, - const Span loop_mapping, - const Span offsets, - const IndexMask selection, - const bke::AttributeAccessor src_attributes, - bke::MutableAttributeAccessor dst_attributes) +static void copy_face_attributes_without_id( + GeometrySet &geometry_set, + const Span edge_mapping, + const Span vert_mapping, + const Span loop_mapping, + const Span offsets, + const IndexMask selection, + const AnonymousAttributePropagationInfo &propagation_info, + const bke::AttributeAccessor src_attributes, + bke::MutableAttributeAccessor dst_attributes) { Map attributes = gather_attributes_without_id( - geometry_set, GEO_COMPONENT_TYPE_MESH); + geometry_set, GEO_COMPONENT_TYPE_MESH, propagation_info); for (const Map::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; @@ -506,7 +515,8 @@ static void copy_stable_id_faces(const Mesh &mesh, static void duplicate_faces(GeometrySet &geometry_set, const Field &count_field, const Field &selection_field, - const IndexAttributes &attribute_outputs) + const IndexAttributes &attribute_outputs, + const AnonymousAttributePropagationInfo &propagation_info) { if (!geometry_set.has_mesh()) { geometry_set.remove_geometry_during_modify(); @@ -588,6 +598,7 @@ static void duplicate_faces(GeometrySet &geometry_set, loop_mapping, offsets, selection, + propagation_info, mesh.attributes(), new_mesh->attributes_for_write()); @@ -612,15 +623,17 @@ static void duplicate_faces(GeometrySet &geometry_set, * Copies the attributes for edge duplicates. If copying the edge domain, the attributes are * copied with an offset fill, for point domain a mapping is used. */ -static void copy_edge_attributes_without_id(GeometrySet &geometry_set, - const Span point_mapping, - const Span offsets, - const IndexMask selection, - const bke::AttributeAccessor src_attributes, - bke::MutableAttributeAccessor dst_attributes) +static void copy_edge_attributes_without_id( + GeometrySet &geometry_set, + const Span point_mapping, + const Span offsets, + const IndexMask selection, + const AnonymousAttributePropagationInfo &propagation_info, + const bke::AttributeAccessor src_attributes, + bke::MutableAttributeAccessor dst_attributes) { Map attributes = gather_attributes_without_id( - geometry_set, GEO_COMPONENT_TYPE_MESH); + geometry_set, GEO_COMPONENT_TYPE_MESH, propagation_info); for (const Map::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; @@ -704,7 +717,8 @@ static void copy_stable_id_edges(const Mesh &mesh, static void duplicate_edges(GeometrySet &geometry_set, const Field &count_field, const Field &selection_field, - const IndexAttributes &attribute_outputs) + const IndexAttributes &attribute_outputs, + const AnonymousAttributePropagationInfo &propagation_info) { if (!geometry_set.has_mesh()) { geometry_set.remove_geometry_during_modify(); @@ -756,6 +770,7 @@ static void duplicate_edges(GeometrySet &geometry_set, vert_orig_indices, edge_offsets, selection, + propagation_info, mesh.attributes(), new_mesh->attributes_for_write()); @@ -782,7 +797,8 @@ static void duplicate_edges(GeometrySet &geometry_set, static void duplicate_points_curve(GeometrySet &geometry_set, const Field &count_field, const Field &selection_field, - const IndexAttributes &attribute_outputs) + const IndexAttributes &attribute_outputs, + const AnonymousAttributePropagationInfo &propagation_info) { const Curves &src_curves_id = *geometry_set.get_curves_for_read(); const bke::CurvesGeometry &src_curves = bke::CurvesGeometry::wrap(src_curves_id.geometry); @@ -819,7 +835,7 @@ static void duplicate_points_curve(GeometrySet &geometry_set, new_curve_offsets.last() = dst_num; Map attributes = gather_attributes_without_id( - geometry_set, GEO_COMPONENT_TYPE_CURVE); + geometry_set, GEO_COMPONENT_TYPE_CURVE, propagation_info); for (const Map::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; @@ -885,7 +901,8 @@ static void duplicate_points_curve(GeometrySet &geometry_set, static void duplicate_points_mesh(GeometrySet &geometry_set, const Field &count_field, const Field &selection_field, - const IndexAttributes &attribute_outputs) + const IndexAttributes &attribute_outputs, + const AnonymousAttributePropagationInfo &propagation_info) { const Mesh &mesh = *geometry_set.get_mesh_for_read(); const Span src_verts = mesh.verts(); @@ -910,6 +927,7 @@ static void duplicate_points_mesh(GeometrySet &geometry_set, ATTR_DOMAIN_POINT, offsets, selection, + propagation_info, mesh.attributes(), new_mesh->attributes_for_write()); @@ -935,7 +953,8 @@ static void duplicate_points_mesh(GeometrySet &geometry_set, static void duplicate_points_pointcloud(GeometrySet &geometry_set, const Field &count_field, const Field &selection_field, - const IndexAttributes &attribute_outputs) + const IndexAttributes &attribute_outputs, + const AnonymousAttributePropagationInfo &propagation_info) { const PointCloud &src_points = *geometry_set.get_pointcloud_for_read(); @@ -956,6 +975,7 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set, ATTR_DOMAIN_POINT, offsets, selection, + propagation_info, src_points.attributes(), pointcloud->attributes_for_write()); @@ -980,7 +1000,8 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set, static void duplicate_points(GeometrySet &geometry_set, const Field &count_field, const Field &selection_field, - const IndexAttributes &attribute_outputs) + const IndexAttributes &attribute_outputs, + const AnonymousAttributePropagationInfo &propagation_info) { Vector component_types = geometry_set.gather_component_types(true, true); for (const GeometryComponentType component_type : component_types) { @@ -988,17 +1009,19 @@ static void duplicate_points(GeometrySet &geometry_set, case GEO_COMPONENT_TYPE_POINT_CLOUD: if (geometry_set.has_pointcloud()) { duplicate_points_pointcloud( - geometry_set, count_field, selection_field, attribute_outputs); + geometry_set, count_field, selection_field, attribute_outputs, propagation_info); } break; case GEO_COMPONENT_TYPE_MESH: if (geometry_set.has_mesh()) { - duplicate_points_mesh(geometry_set, count_field, selection_field, attribute_outputs); + duplicate_points_mesh( + geometry_set, count_field, selection_field, attribute_outputs, propagation_info); } break; case GEO_COMPONENT_TYPE_CURVE: if (geometry_set.has_curves()) { - duplicate_points_curve(geometry_set, count_field, selection_field, attribute_outputs); + duplicate_points_curve( + geometry_set, count_field, selection_field, attribute_outputs, propagation_info); } break; default: @@ -1018,7 +1041,8 @@ static void duplicate_points(GeometrySet &geometry_set, static void duplicate_instances(GeometrySet &geometry_set, const Field &count_field, const Field &selection_field, - const IndexAttributes &attribute_outputs) + const IndexAttributes &attribute_outputs, + const AnonymousAttributePropagationInfo &propagation_info) { if (!geometry_set.has_instances()) { geometry_set.clear(); @@ -1062,6 +1086,7 @@ static void duplicate_instances(GeometrySet &geometry_set, ATTR_DOMAIN_INSTANCE, offsets, selection, + propagation_info, src_instances.attributes(), dst_instances->attributes_for_write()); @@ -1092,27 +1117,34 @@ static void node_geo_exec(GeoNodeExecParams params) Field count_field = params.extract_input>("Amount"); Field selection_field = params.extract_input>("Selection"); IndexAttributes attribute_outputs; - if (params.output_is_required("Duplicate Index")) { - attribute_outputs.duplicate_index = StrongAnonymousAttributeID("duplicate_index"); - } + attribute_outputs.duplicate_index = params.get_output_anonymous_attribute_id_if_needed( + "Duplicate Index"); + + const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info( + "Geometry"); if (duplicate_domain == ATTR_DOMAIN_INSTANCE) { - duplicate_instances(geometry_set, count_field, selection_field, attribute_outputs); + duplicate_instances( + geometry_set, count_field, selection_field, attribute_outputs, propagation_info); } else { geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { switch (duplicate_domain) { case ATTR_DOMAIN_CURVE: - duplicate_curves(geometry_set, count_field, selection_field, attribute_outputs); + duplicate_curves( + geometry_set, count_field, selection_field, attribute_outputs, propagation_info); break; case ATTR_DOMAIN_FACE: - duplicate_faces(geometry_set, count_field, selection_field, attribute_outputs); + duplicate_faces( + geometry_set, count_field, selection_field, attribute_outputs, propagation_info); break; case ATTR_DOMAIN_EDGE: - duplicate_edges(geometry_set, count_field, selection_field, attribute_outputs); + duplicate_edges( + geometry_set, count_field, selection_field, attribute_outputs, propagation_info); break; case ATTR_DOMAIN_POINT: - duplicate_points(geometry_set, count_field, selection_field, attribute_outputs); + duplicate_points( + geometry_set, count_field, selection_field, attribute_outputs, propagation_info); break; default: BLI_assert_unreachable(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc index c70d45ce334..772c4721284 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_paths_to_curves.cc @@ -18,9 +18,11 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output(N_("Curves")).propagate_all(); } -static Curves *edge_paths_to_curves_convert(const Mesh &mesh, - const IndexMask start_verts_mask, - const Span next_indices) +static Curves *edge_paths_to_curves_convert( + const Mesh &mesh, + const IndexMask start_verts_mask, + const Span next_indices, + const AnonymousAttributePropagationInfo &propagation_info) { Vector vert_indices; Vector curve_offsets; @@ -58,8 +60,8 @@ static Curves *edge_paths_to_curves_convert(const Mesh &mesh, if (vert_indices.is_empty()) { return nullptr; } - Curves *curves_id = bke::curves_new_nomain( - geometry::create_curve_from_vert_indices(mesh, vert_indices, curve_offsets, IndexRange(0))); + Curves *curves_id = bke::curves_new_nomain(geometry::create_curve_from_vert_indices( + mesh, vert_indices, curve_offsets, IndexRange(0), propagation_info)); return curves_id; } @@ -87,7 +89,8 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - geometry_set.replace_curves(edge_paths_to_curves_convert(*mesh, start_verts, next_vert)); + geometry_set.replace_curves(edge_paths_to_curves_convert( + *mesh, start_verts, next_vert, params.get_output_propagation_info("Curves"))); geometry_set.keep_only({GEO_COMPONENT_TYPE_CURVE, GEO_COMPONENT_TYPE_INSTANCES}); }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc index 057c09c9936..2948713852b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_edge_split.cc @@ -33,7 +33,8 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - geometry::split_edges(*geometry_set.get_mesh_for_write(), mask); + geometry::split_edges( + *geometry_set.get_mesh_for_write(), mask, params.get_output_propagation_info("Mesh")); } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index a36413e49b2..27f34db2f9f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -27,7 +27,7 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input(N_("Selection")).default_value(true).field_on_all().hide_value(); b.add_input(N_("Offset")) .subtype(PROP_TRANSLATION) - .implicit_field(implicit_field_inputs::normal) + .implicit_field_on_all(implicit_field_inputs::normal) .hide_value(); b.add_input(N_("Offset Scale")).default_value(1.0f).field_on_all(); b.add_input(N_("Individual")).default_value(true); @@ -61,8 +61,8 @@ static void node_update(bNodeTree *ntree, bNode *node) } struct AttributeOutputs { - StrongAnonymousAttributeID top_id; - StrongAnonymousAttributeID side_id; + AutoAnonymousAttributeID top_id; + AutoAnonymousAttributeID side_id; }; static void save_selection_as_attribute(Mesh &mesh, @@ -1334,12 +1334,8 @@ static void node_geo_exec(GeoNodeExecParams params) const Field final_offset{std::move(multiply_op)}; AttributeOutputs attribute_outputs; - if (params.output_is_required("Top")) { - attribute_outputs.top_id = StrongAnonymousAttributeID("Top"); - } - if (params.output_is_required("Side")) { - attribute_outputs.side_id = StrongAnonymousAttributeID("Side"); - } + attribute_outputs.top_id = params.get_output_anonymous_attribute_id_if_needed("Top"); + attribute_outputs.side_id = params.get_output_anonymous_attribute_id_if_needed("Side"); const bool extrude_individual = mode == GEO_NODE_EXTRUDE_MESH_FACES && params.extract_input("Individual"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc index 44172cfee60..6c38c8a91ab 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instance_on_points.cc @@ -198,8 +198,11 @@ static void node_geo_exec(GeoNodeExecParams params) GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE}; Map attributes_to_propagate; - geometry_set.gather_attributes_for_propagation( - types, GEO_COMPONENT_TYPE_INSTANCES, false, attributes_to_propagate); + geometry_set.gather_attributes_for_propagation(types, + GEO_COMPONENT_TYPE_INSTANCES, + false, + params.get_output_propagation_info("Instances"), + attributes_to_propagate); attributes_to_propagate.remove("position"); for (const GeometryComponentType type : types) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc index e43aac9d3ad..0be8743f9a1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_instances_to_points.cc @@ -26,7 +26,8 @@ static void node_declare(NodeDeclarationBuilder &b) static void convert_instances_to_points(GeometrySet &geometry_set, Field position_field, Field radius_field, - const Field selection_field) + const Field selection_field, + const AnonymousAttributePropagationInfo &propagation_info) { const bke::Instances &instances = *geometry_set.get_instances_for_read(); @@ -62,6 +63,7 @@ static void convert_instances_to_points(GeometrySet &geometry_set, geometry_set.gather_attributes_for_propagation({GEO_COMPONENT_TYPE_INSTANCES}, GEO_COMPONENT_TYPE_POINT_CLOUD, false, + propagation_info, attributes_to_propagate); /* These two attributes are added by the implicit inputs above. */ attributes_to_propagate.remove("position"); @@ -91,7 +93,8 @@ static void node_geo_exec(GeoNodeExecParams params) convert_instances_to_points(geometry_set, params.extract_input>("Position"), params.extract_input>("Radius"), - params.extract_input>("Selection")); + params.extract_input>("Selection"), + params.get_output_propagation_info("Points")); geometry_set.keep_only({GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_EDIT}); params.set_output("Points", std::move(geometry_set)); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc index 03ecb7c4c2f..d49f2583bde 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc @@ -28,7 +28,7 @@ static Map get_final_attribute_info( for (const GeometryComponent *component : components) { component->attributes()->for_all( [&](const bke::AttributeIDRef &attribute_id, const AttributeMetaData &meta_data) { - if (attribute_id.is_named() && ignored_attributes.contains(attribute_id.name())) { + if (ignored_attributes.contains(attribute_id.name())) { return true; } if (meta_data.data_type == CD_PROP_STRING) { @@ -143,7 +143,9 @@ static void join_components(Span /*src_components*/, } template -static void join_component_type(Span src_geometry_sets, GeometrySet &result) +static void join_component_type(Span src_geometry_sets, + GeometrySet &result, + const AnonymousAttributePropagationInfo &propagation_info) { Vector components; for (const GeometrySet &geometry_set : src_geometry_sets) { @@ -176,6 +178,7 @@ static void join_component_type(Span src_geometry_sets, GeometrySet geometry::RealizeInstancesOptions options; options.keep_original_ids = true; options.realize_instance_attributes = false; + options.propagation_info = propagation_info; GeometrySet joined_components = geometry::realize_instances( GeometrySet::create_with_instances(instances.release()), options); result.add(joined_components.get_component_for_write()); @@ -186,13 +189,17 @@ static void node_geo_exec(GeoNodeExecParams params) { Vector geometry_sets = params.extract_input>("Geometry"); + const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info( + "Geometry"); + GeometrySet geometry_set_result; - join_component_type(geometry_sets, geometry_set_result); - join_component_type(geometry_sets, geometry_set_result); - join_component_type(geometry_sets, geometry_set_result); - join_component_type(geometry_sets, geometry_set_result); - join_component_type(geometry_sets, geometry_set_result); - join_component_type(geometry_sets, geometry_set_result); + join_component_type(geometry_sets, geometry_set_result, propagation_info); + join_component_type(geometry_sets, geometry_set_result, propagation_info); + join_component_type(geometry_sets, geometry_set_result, propagation_info); + join_component_type(geometry_sets, geometry_set_result, propagation_info); + join_component_type(geometry_sets, geometry_set_result, propagation_info); + join_component_type( + geometry_sets, geometry_set_result, propagation_info); params.set_output("Geometry", std::move(geometry_set_result)); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc index 04c48a82e42..2fafc77bc45 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_merge_by_distance.cc @@ -38,9 +38,11 @@ static void node_init(bNodeTree * /*tree*/, bNode *node) node->storage = data; } -static PointCloud *pointcloud_merge_by_distance(const PointCloud &src_points, - const float merge_distance, - const Field &selection_field) +static PointCloud *pointcloud_merge_by_distance( + const PointCloud &src_points, + const float merge_distance, + const Field &selection_field, + const AnonymousAttributePropagationInfo &propagation_info) { bke::PointCloudFieldContext context{src_points}; FieldEvaluator evaluator{context, src_points.totpoint}; @@ -52,7 +54,8 @@ static PointCloud *pointcloud_merge_by_distance(const PointCloud &src_points, return nullptr; } - return geometry::point_merge_by_distance(src_points, merge_distance, selection); + return geometry::point_merge_by_distance( + src_points, merge_distance, selection, propagation_info); } static std::optional mesh_merge_by_distance_connected(const Mesh &mesh, @@ -97,7 +100,8 @@ static void node_geo_exec(GeoNodeExecParams params) geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { if (const PointCloud *pointcloud = geometry_set.get_pointcloud_for_read()) { - PointCloud *result = pointcloud_merge_by_distance(*pointcloud, merge_distance, selection); + PointCloud *result = pointcloud_merge_by_distance( + *pointcloud, merge_distance, selection, params.get_output_propagation_info("Geometry")); if (result) { geometry_set.replace_pointcloud(result); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc index 8f261ad9e66..9e92527f393 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc @@ -814,18 +814,10 @@ static void node_geo_exec(GeoNodeExecParams params) const float depth = params.extract_input("Depth"); ConeAttributeOutputs attribute_outputs; - if (params.output_is_required("Top")) { - attribute_outputs.top_id = StrongAnonymousAttributeID("top_selection"); - } - if (params.output_is_required("Bottom")) { - attribute_outputs.bottom_id = StrongAnonymousAttributeID("bottom_selection"); - } - if (params.output_is_required("Side")) { - attribute_outputs.side_id = StrongAnonymousAttributeID("side_selection"); - } - if (params.output_is_required("UV Map")) { - attribute_outputs.uv_map_id = StrongAnonymousAttributeID("uv_map"); - } + attribute_outputs.top_id = params.get_output_anonymous_attribute_id_if_needed("Top"); + attribute_outputs.bottom_id = params.get_output_anonymous_attribute_id_if_needed("Bottom"); + attribute_outputs.side_id = params.get_output_anonymous_attribute_id_if_needed("Side"); + attribute_outputs.uv_map_id = params.get_output_anonymous_attribute_id_if_needed("UV Map"); Mesh *mesh = create_cylinder_or_cone_mesh(radius_top, radius_bottom, diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc index 879de80e73d..88fb4c72b1a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cube.cc @@ -107,10 +107,8 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - StrongAnonymousAttributeID uv_map_id; - if (params.output_is_required("UV Map")) { - uv_map_id = StrongAnonymousAttributeID("uv_map"); - } + AutoAnonymousAttributeID uv_map_id = params.get_output_anonymous_attribute_id_if_needed( + "UV Map"); Mesh *mesh = create_cube_mesh(size, verts_x, verts_y, verts_z, uv_map_id.get()); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc index b0e857feb64..bc651cdb652 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cylinder.cc @@ -107,18 +107,10 @@ static void node_geo_exec(GeoNodeExecParams params) } ConeAttributeOutputs attribute_outputs; - if (params.output_is_required("Top")) { - attribute_outputs.top_id = StrongAnonymousAttributeID("top_selection"); - } - if (params.output_is_required("Bottom")) { - attribute_outputs.bottom_id = StrongAnonymousAttributeID("bottom_selection"); - } - if (params.output_is_required("Side")) { - attribute_outputs.side_id = StrongAnonymousAttributeID("side_selection"); - } - if (params.output_is_required("UV Map")) { - attribute_outputs.uv_map_id = StrongAnonymousAttributeID("uv_map"); - } + attribute_outputs.top_id = params.get_output_anonymous_attribute_id_if_needed("Top"); + attribute_outputs.bottom_id = params.get_output_anonymous_attribute_id_if_needed("Bottom"); + attribute_outputs.side_id = params.get_output_anonymous_attribute_id_if_needed("Side"); + attribute_outputs.uv_map_id = params.get_output_anonymous_attribute_id_if_needed("UV Map"); /* The cylinder is a special case of the cone mesh where the top and bottom radius are equal. */ Mesh *mesh = create_cylinder_or_cone_mesh(radius, diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc index 98ff797addc..b05a6d8019e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc @@ -194,10 +194,8 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - StrongAnonymousAttributeID uv_map_id; - if (params.output_is_required("UV Map")) { - uv_map_id = StrongAnonymousAttributeID("uv_map"); - } + AutoAnonymousAttributeID uv_map_id = params.get_output_anonymous_attribute_id_if_needed( + "UV Map"); Mesh *mesh = create_grid_mesh(verts_x, verts_y, size_x, size_y, uv_map_id.get()); BKE_id_material_eval_ensure_default_slot(&mesh->id); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc index cd8c6a19612..f0993da1ba2 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc @@ -77,10 +77,8 @@ static void node_geo_exec(GeoNodeExecParams params) const int subdivisions = std::min(params.extract_input("Subdivisions"), 10); const float radius = params.extract_input("Radius"); - StrongAnonymousAttributeID uv_map_id; - if (params.output_is_required("UV Map")) { - uv_map_id = StrongAnonymousAttributeID("uv_map"); - } + AutoAnonymousAttributeID uv_map_id = params.get_output_anonymous_attribute_id_if_needed( + "UV Map"); Mesh *mesh = create_ico_sphere_mesh(subdivisions, radius, uv_map_id.get()); params.set_output("Mesh", GeometrySet::create_with_mesh(mesh)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc index 5b424534d7b..ff40a970785 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc @@ -362,10 +362,8 @@ static void node_geo_exec(GeoNodeExecParams params) const float radius = params.extract_input("Radius"); - StrongAnonymousAttributeID uv_map_id; - if (params.output_is_required("UV Map")) { - uv_map_id = StrongAnonymousAttributeID("uv_map"); - } + AutoAnonymousAttributeID uv_map_id = params.get_output_anonymous_attribute_id_if_needed( + "UV Map"); Mesh *mesh = create_uv_sphere_mesh(radius, segments_num, rings_num, uv_map_id.get()); params.set_output("Mesh", GeometrySet::create_with_mesh(mesh)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc index 40626a1c2c5..2b80c6df51f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_curve.cc @@ -36,7 +36,8 @@ static void node_geo_exec(GeoNodeExecParams params) return; } - bke::CurvesGeometry curves = geometry::mesh_to_curve_convert(*mesh, selection); + bke::CurvesGeometry curves = geometry::mesh_to_curve_convert( + *mesh, selection, params.get_output_propagation_info("Curve")); geometry_set.replace_curves(bke::curves_new_nomain(std::move(curves))); geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_CURVE}); }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc index 790f0ceda9c..f551faee2e0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc @@ -24,7 +24,7 @@ static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Mesh")).supported_type(GEO_COMPONENT_TYPE_MESH); b.add_input(N_("Selection")).default_value(true).field_on_all().hide_value(); - b.add_input(N_("Position")).implicit_field(implicit_field_inputs::position); + b.add_input(N_("Position")).implicit_field_on_all(implicit_field_inputs::position); b.add_input(N_("Radius")) .default_value(0.05f) .min(0.0f) @@ -49,7 +49,8 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, Field &position_field, Field &radius_field, Field &selection_field, - const eAttrDomain domain) + const eAttrDomain domain, + const AnonymousAttributePropagationInfo &propagation_info) { const Mesh *mesh = geometry_set.get_mesh_for_read(); if (mesh == nullptr) { @@ -87,8 +88,11 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, radius.finish(); Map attributes; - geometry_set.gather_attributes_for_propagation( - {GEO_COMPONENT_TYPE_MESH}, GEO_COMPONENT_TYPE_POINT_CLOUD, false, attributes); + geometry_set.gather_attributes_for_propagation({GEO_COMPONENT_TYPE_MESH}, + GEO_COMPONENT_TYPE_POINT_CLOUD, + false, + propagation_info, + attributes); attributes.remove("position"); const AttributeAccessor src_attributes = mesh->attributes(); @@ -128,23 +132,42 @@ static void node_geo_exec(GeoNodeExecParams params) const NodeGeometryMeshToPoints &storage = node_storage(params.node()); const GeometryNodeMeshToPointsMode mode = (GeometryNodeMeshToPointsMode)storage.mode; + const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info( + "Points"); + geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { switch (mode) { case GEO_NODE_MESH_TO_POINTS_VERTICES: - geometry_set_mesh_to_points( - geometry_set, position, positive_radius, selection, ATTR_DOMAIN_POINT); + geometry_set_mesh_to_points(geometry_set, + position, + positive_radius, + selection, + ATTR_DOMAIN_POINT, + propagation_info); break; case GEO_NODE_MESH_TO_POINTS_EDGES: - geometry_set_mesh_to_points( - geometry_set, position, positive_radius, selection, ATTR_DOMAIN_EDGE); + geometry_set_mesh_to_points(geometry_set, + position, + positive_radius, + selection, + ATTR_DOMAIN_EDGE, + propagation_info); break; case GEO_NODE_MESH_TO_POINTS_FACES: - geometry_set_mesh_to_points( - geometry_set, position, positive_radius, selection, ATTR_DOMAIN_FACE); + geometry_set_mesh_to_points(geometry_set, + position, + positive_radius, + selection, + ATTR_DOMAIN_FACE, + propagation_info); break; case GEO_NODE_MESH_TO_POINTS_CORNERS: - geometry_set_mesh_to_points( - geometry_set, position, positive_radius, selection, ATTR_DOMAIN_CORNER); + geometry_set_mesh_to_points(geometry_set, + position, + positive_radius, + selection, + ATTR_DOMAIN_CORNER, + propagation_info); break; } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc index 2e9d5037c00..5cd5bbe690e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_points_to_vertices.cc @@ -21,8 +21,10 @@ static void node_declare(NodeDeclarationBuilder &b) } /* One improvement would be to move the attribute arrays directly to the mesh when possible. */ -static void geometry_set_points_to_vertices(GeometrySet &geometry_set, - Field &selection_field) +static void geometry_set_points_to_vertices( + GeometrySet &geometry_set, + Field &selection_field, + const AnonymousAttributePropagationInfo &propagation_info) { const PointCloud *points = geometry_set.get_pointcloud_for_read(); if (points == nullptr) { @@ -41,8 +43,11 @@ static void geometry_set_points_to_vertices(GeometrySet &geometry_set, const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0); Map attributes; - geometry_set.gather_attributes_for_propagation( - {GEO_COMPONENT_TYPE_POINT_CLOUD}, GEO_COMPONENT_TYPE_MESH, false, attributes); + geometry_set.gather_attributes_for_propagation({GEO_COMPONENT_TYPE_POINT_CLOUD}, + GEO_COMPONENT_TYPE_MESH, + false, + propagation_info, + attributes); Mesh *mesh = BKE_mesh_new_nomain(selection.size(), 0, 0, 0, 0); geometry_set.replace_mesh(mesh); @@ -73,7 +78,8 @@ static void node_geo_exec(GeoNodeExecParams params) Field selection_field = params.extract_input>("Selection"); geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - geometry_set_points_to_vertices(geometry_set, selection_field); + geometry_set_points_to_vertices( + geometry_set, selection_field, params.get_output_propagation_info("Mesh")); }); params.set_output("Mesh", std::move(geometry_set)); diff --git a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc index 920d3f77666..385b47a2f1e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc @@ -37,6 +37,7 @@ static void node_geo_exec(GeoNodeExecParams params) geometry::RealizeInstancesOptions options; options.keep_original_ids = legacy_behavior; options.realize_instance_attributes = !legacy_behavior; + options.propagation_info = params.get_output_propagation_info("Geometry"); geometry_set = geometry::realize_instances(geometry_set, options); params.set_output("Geometry", std::move(geometry_set)); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc index 8b01e147d0d..28c0bf84160 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_separate_geometry.cc @@ -47,29 +47,42 @@ static void node_geo_exec(GeoNodeExecParams params) const NodeGeometrySeparateGeometry &storage = node_storage(params.node()); const eAttrDomain domain = eAttrDomain(storage.domain); - auto separate_geometry_maybe_recursively = [&](GeometrySet &geometry_set, - const Field &selection) { - bool is_error; - if (domain == ATTR_DOMAIN_INSTANCE) { - /* Only delete top level instances. */ - separate_geometry( - geometry_set, domain, GEO_NODE_DELETE_GEOMETRY_MODE_ALL, selection, is_error); - } - else { - geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - separate_geometry( - geometry_set, domain, GEO_NODE_DELETE_GEOMETRY_MODE_ALL, selection, is_error); - }); - } - }; + auto separate_geometry_maybe_recursively = + [&](GeometrySet &geometry_set, + const Field &selection, + const AnonymousAttributePropagationInfo &propagation_info) { + bool is_error; + if (domain == ATTR_DOMAIN_INSTANCE) { + /* Only delete top level instances. */ + separate_geometry(geometry_set, + domain, + GEO_NODE_DELETE_GEOMETRY_MODE_ALL, + selection, + propagation_info, + is_error); + } + else { + geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { + separate_geometry(geometry_set, + domain, + GEO_NODE_DELETE_GEOMETRY_MODE_ALL, + selection, + propagation_info, + is_error); + }); + } + }; GeometrySet second_set(geometry_set); if (params.output_is_required("Selection")) { - separate_geometry_maybe_recursively(geometry_set, selection_field); + separate_geometry_maybe_recursively( + geometry_set, selection_field, params.get_output_propagation_info("Selection")); params.set_output("Selection", std::move(geometry_set)); } if (params.output_is_required("Inverted")) { - separate_geometry_maybe_recursively(second_set, fn::invert_boolean_field(selection_field)); + separate_geometry_maybe_recursively(second_set, + fn::invert_boolean_field(selection_field), + params.get_output_propagation_info("Inverted")); params.set_output("Inverted", std::move(second_set)); } } diff --git a/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc index 93dcdd37ed2..5eb98fe8f01 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_string_to_curves.cc @@ -249,7 +249,7 @@ static std::optional get_text_layout(GeoNodeExecParams ¶ms) } } - if (params.output_is_required("Line")) { + if (params.anonymous_attribute_output_is_required("Line")) { layout.line_numbers.reinitialize(layout.positions.size()); for (const int i : layout.positions.index_range()) { CharTrans &ct = chartransdata[i]; @@ -278,7 +278,7 @@ static Map create_curve_instances(GeoNodeExecParams ¶ms, { VFont *vfont = reinterpret_cast(params.node().id); Map handles; - bool pivot_required = params.output_is_required("Pivot Point"); + bool pivot_required = params.anonymous_attribute_output_is_required("Pivot Point"); for (int i : layout.char_codes.index_range()) { if (handles.contains(layout.char_codes[i])) { @@ -341,10 +341,10 @@ static void create_attributes(GeoNodeExecParams ¶ms, { MutableAttributeAccessor attributes = instances.attributes_for_write(); - if (params.output_is_required("Line")) { - StrongAnonymousAttributeID line_id = StrongAnonymousAttributeID("Line"); + if (AutoAnonymousAttributeID line_id = params.get_output_anonymous_attribute_id_if_needed( + "Line")) { SpanAttributeWriter line_attribute = attributes.lookup_or_add_for_write_only_span( - line_id.get(), ATTR_DOMAIN_INSTANCE); + *line_id, ATTR_DOMAIN_INSTANCE); line_attribute.span.copy_from(layout.line_numbers); line_attribute.finish(); params.set_output("Line", @@ -352,10 +352,10 @@ static void create_attributes(GeoNodeExecParams ¶ms, params.attribute_producer_name())); } - if (params.output_is_required("Pivot Point")) { - StrongAnonymousAttributeID pivot_id = StrongAnonymousAttributeID("Pivot"); + if (AutoAnonymousAttributeID pivot_id = params.get_output_anonymous_attribute_id_if_needed( + "Pivot Point")) { SpanAttributeWriter pivot_attribute = - attributes.lookup_or_add_for_write_only_span(pivot_id.get(), ATTR_DOMAIN_INSTANCE); + attributes.lookup_or_add_for_write_only_span(*pivot_id, ATTR_DOMAIN_INSTANCE); for (const int i : layout.char_codes.index_range()) { pivot_attribute.span[i] = layout.pivot_points.lookup(layout.char_codes[i]); diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 454fe4da23b..bfda854d4c2 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -17,6 +17,8 @@ #include "NOD_node_declaration.hh" #include "BLI_cpp_types.hh" +#include "BLI_dot_export.hh" +#include "BLI_hash.h" #include "BLI_lazy_threading.hh" #include "BLI_map.hh" @@ -111,6 +113,16 @@ class LazyFunctionForGeometryNode : public LazyFunction { const bNode &node_; public: + /** + * Index of a boolean input that indicates whether the output socket is used. + */ + Map lf_input_for_output_bsocket_usage_; + /** + * Index of an attribute set input that indicates which anonymous attributes should be + * propagated to the output. + */ + Map lf_input_for_attribute_propagation_to_output_; + LazyFunctionForGeometryNode(const bNode &node, Vector &r_used_inputs, Vector &r_used_outputs) @@ -119,6 +131,32 @@ class LazyFunctionForGeometryNode : public LazyFunction { BLI_assert(node.typeinfo->geometry_node_execute != nullptr); debug_name_ = node.name; lazy_function_interface_from_node(node, r_used_inputs, r_used_outputs, inputs_, outputs_); + + const NodeDeclaration &node_decl = *node.declaration(); + const aal::RelationsInNode *relations = node_decl.anonymous_attribute_relations(); + if (relations == nullptr) { + return; + } + Vector handled_field_outputs; + for (const aal::AvailableRelation &relation : relations->available_relations) { + const bNodeSocket &output_bsocket = node.output_socket(relation.field_output); + if (output_bsocket.is_available() && !handled_field_outputs.contains(&output_bsocket)) { + handled_field_outputs.append(&output_bsocket); + const int lf_index = inputs_.append_and_get_index_as("Output Used", CPPType::get()); + lf_input_for_output_bsocket_usage_.add(output_bsocket.identifier, lf_index); + } + } + + Vector handled_geometry_outputs; + for (const aal::PropagateRelation &relation : relations->propagate_relations) { + const bNodeSocket &output_bsocket = node.output_socket(relation.to_geometry_output); + if (output_bsocket.is_available() && !handled_geometry_outputs.contains(&output_bsocket)) { + handled_geometry_outputs.append(&output_bsocket); + const int lf_index = inputs_.append_and_get_index_as( + "Propagate to Output", CPPType::get()); + lf_input_for_attribute_propagation_to_output_.add(output_bsocket.identifier, lf_index); + } + } } void execute_impl(lf::Params ¶ms, const lf::Context &context) const override @@ -126,7 +164,11 @@ class LazyFunctionForGeometryNode : public LazyFunction { GeoNodesLFUserData *user_data = dynamic_cast(context.user_data); BLI_assert(user_data != nullptr); - GeoNodeExecParams geo_params{node_, params, context}; + GeoNodeExecParams geo_params{node_, + params, + context, + lf_input_for_output_bsocket_usage_, + lf_input_for_attribute_propagation_to_output_}; geo_eval_log::TimePoint start_time = geo_eval_log::Clock::now(); node_.typeinfo->geometry_node_execute(geo_params); @@ -138,6 +180,27 @@ class LazyFunctionForGeometryNode : public LazyFunction { tree_logger.node_execution_times.append({node_.identifier, start_time, end_time}); } } + + std::string input_name(const int index) const override + { + for (const auto [identifier, lf_index] : lf_input_for_output_bsocket_usage_.items()) { + if (index == lf_index) { + return "Use Output '" + identifier + "'"; + } + } + for (const auto [identifier, lf_index] : + lf_input_for_attribute_propagation_to_output_.items()) { + if (index == lf_index) { + return "Propagate to '" + identifier + "'"; + } + } + return inputs_[index].debug_name; + } + + std::string output_name(const int index) const override + { + return outputs_[index].debug_name; + } }; /** @@ -588,6 +651,35 @@ class LazyFunctionForViewerNode : public LazyFunction { } }; +/** + * Outputs true when a specific viewer node is used in the current context and false otherwise. + */ +class LazyFunctionForViewerInputUsage : public LazyFunction { + private: + const lf::FunctionNode &lf_viewer_node_; + + public: + LazyFunctionForViewerInputUsage(const lf::FunctionNode &lf_viewer_node) + : lf_viewer_node_(lf_viewer_node) + { + debug_name_ = "Viewer Input Usage"; + outputs_.append_as("Viewer is Used", CPPType::get()); + } + + void execute_impl(lf::Params ¶ms, const lf::Context &context) const override + { + GeoNodesLFUserData *user_data = dynamic_cast(context.user_data); + BLI_assert(user_data != nullptr); + const ComputeContextHash &context_hash = user_data->compute_context->hash(); + const GeoNodesModifierData &modifier_data = *user_data->modifier_data; + const Span nodes_with_side_effects = + modifier_data.side_effect_nodes->lookup(context_hash); + + const bool viewer_is_used = nodes_with_side_effects.contains(&lf_viewer_node_); + params.set_output(0, viewer_is_used); + } +}; + /** * This lazy-function wraps a group node. Internally it just executes the lazy-function graph of * the referenced group. @@ -596,7 +688,6 @@ class LazyFunctionForGroupNode : public LazyFunction { private: const bNode &group_node_; bool has_many_nodes_ = false; - bool use_fallback_outputs_ = false; std::optional lf_logger_; std::optional lf_side_effect_provider_; std::optional graph_executor_; @@ -608,40 +699,71 @@ class LazyFunctionForGroupNode : public LazyFunction { }; public: + /** + * For every input bsocket there is a corresponding boolean output that indicates whether that + * input is used. + */ + Map lf_output_for_input_bsocket_usage_; + /** + * For every output bsocket there is a corresponding boolean input that indicates whether the + * output is used. + */ + Map lf_input_for_output_bsocket_usage_; + /** + * For every geometry output that can propagate attributes from an input, there is an attribute + * set input. It indicates which attributes should be propagated to the output. + */ + Map lf_input_for_attribute_propagation_to_output_; + LazyFunctionForGroupNode(const bNode &group_node, - const GeometryNodesLazyFunctionGraphInfo &lf_graph_info, - Vector &r_used_inputs, - Vector &r_used_outputs) + const GeometryNodesLazyFunctionGraphInfo &lf_graph_info) : group_node_(group_node) { debug_name_ = group_node.name; - lazy_function_interface_from_node( - group_node, r_used_inputs, r_used_outputs, inputs_, outputs_); + allow_missing_requested_inputs_ = true; - bNodeTree *group_btree = reinterpret_cast(group_node_.id); - BLI_assert(group_btree != nullptr); + Vector tmp_inputs; + Vector tmp_outputs; + lazy_function_interface_from_node(group_node, tmp_inputs, tmp_outputs, inputs_, outputs_); has_many_nodes_ = lf_graph_info.num_inline_nodes_approximate > 1000; Vector graph_inputs; - for (const lf::OutputSocket *socket : lf_graph_info.mapping.group_input_sockets) { - if (socket != nullptr) { - graph_inputs.append(socket); - } + /* Add inputs that also exist on the bnode. */ + graph_inputs.extend(lf_graph_info.mapping.group_input_sockets); + + /* Add a boolean input for every output bsocket that indicates whether that socket is used. */ + for (const int i : group_node.output_sockets().index_range()) { + lf_input_for_output_bsocket_usage_.add_new( + i, + graph_inputs.append_and_get_index(lf_graph_info.mapping.group_output_used_sockets[i])); + inputs_.append_as("Output is Used", CPPType::get(), lf::ValueUsage::Maybe); } + graph_inputs.extend(lf_graph_info.mapping.group_output_used_sockets); + + /* Add an attribute set input for every output geometry socket that can propagate attributes + * from inputs. */ + for (auto [output_index, lf_socket] : + lf_graph_info.mapping.attribute_set_by_geometry_output.items()) { + const int lf_index = inputs_.append_and_get_index_as( + "Attribute Set", CPPType::get(), lf::ValueUsage::Maybe); + graph_inputs.append(lf_socket); + lf_input_for_attribute_propagation_to_output_.add(output_index, lf_index); + } + Vector graph_outputs; - if (const bNode *group_output_bnode = group_btree->group_output_node()) { - for (const bNodeSocket *bsocket : group_output_bnode->input_sockets().drop_back(1)) { - const lf::Socket *socket = lf_graph_info.mapping.dummy_socket_map.lookup_default(bsocket, - nullptr); - if (socket != nullptr) { - graph_outputs.append(&socket->as_input()); - } + /* Add outputs that also exist on the bnode. */ + graph_outputs.extend(lf_graph_info.mapping.standard_group_output_sockets); + /* Add a boolean output for every input bsocket that indicates whether that socket is used. */ + for (const int i : group_node.input_sockets().index_range()) { + const InputUsageHint &input_usage_hint = lf_graph_info.mapping.group_input_usage_hints[i]; + if (input_usage_hint.type == InputUsageHintType::DynamicSocket) { + const lf::InputSocket *lf_socket = lf_graph_info.mapping.group_input_usage_sockets[i]; + lf_output_for_input_bsocket_usage_.add_new(i, + graph_outputs.append_and_get_index(lf_socket)); + outputs_.append_as("Input is Used", CPPType::get()); } } - else { - use_fallback_outputs_ = true; - } lf_logger_.emplace(lf_graph_info); lf_side_effect_provider_.emplace(); @@ -662,11 +784,6 @@ class LazyFunctionForGroupNode : public LazyFunction { * if every individual node is very small. */ lazy_threading::send_hint(); } - if (use_fallback_outputs_) { - /* The node group itself does not have an output node, so use default values as outputs. - * The group should still be executed in case it has side effects. */ - params.set_default_remaining_outputs(); - } Storage *storage = static_cast(context.storage); @@ -702,6 +819,53 @@ class LazyFunctionForGroupNode : public LazyFunction { graph_executor_->destruct_storage(s->graph_executor_storage); std::destroy_at(s); } + + std::string name() const override + { + std::stringstream ss; + ss << "Group '" << (group_node_.id->name + 2) << "' (" << group_node_.name << ")"; + return ss.str(); + } + + std::string input_name(const int i) const override + { + if (i < group_node_.input_sockets().size()) { + return group_node_.input_socket(i).name; + } + for (const auto [bsocket_index, lf_socket_index] : + lf_input_for_output_bsocket_usage_.items()) { + if (i == lf_socket_index) { + std::stringstream ss; + ss << "'" << group_node_.output_socket(bsocket_index).name << "' output is used"; + return ss.str(); + } + } + for (const auto [bsocket_index, lf_index] : + lf_input_for_attribute_propagation_to_output_.items()) { + if (i == lf_index) { + std::stringstream ss; + ss << "Propagate to '" << group_node_.output_socket(bsocket_index).name << "'"; + return ss.str(); + } + } + return inputs_[i].debug_name; + } + + std::string output_name(const int i) const override + { + if (i < group_node_.output_sockets().size()) { + return group_node_.output_socket(i).name; + } + for (const auto [bsocket_index, lf_socket_index] : + lf_output_for_input_bsocket_usage_.items()) { + if (i == lf_socket_index) { + std::stringstream ss; + ss << "'" << group_node_.input_socket(bsocket_index).name << "' input is used"; + return ss.str(); + } + } + return outputs_[i].debug_name; + } }; static GMutablePointer get_socket_default_value(LinearAllocator<> &allocator, @@ -747,6 +911,230 @@ class GroupOutputDebugInfo : public lf::DummyDebugInfo { } }; +/** + * Computes the logical or of the inputs and supports short-circuit evaluation (i.e. if the first + * input is true already, the other inputs are not checked). + */ +class LazyFunctionForLogicalOr : public lf::LazyFunction { + public: + LazyFunctionForLogicalOr(const int inputs_num) + { + debug_name_ = "Logical Or"; + for ([[maybe_unused]] const int i : IndexRange(inputs_num)) { + inputs_.append_as("Input", CPPType::get(), lf::ValueUsage::Maybe); + } + outputs_.append_as("Output", CPPType::get()); + } + + void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override + { + int first_unavailable_input = -1; + for (const int i : inputs_.index_range()) { + if (const bool *value = params.try_get_input_data_ptr(i)) { + if (*value) { + params.set_output(0, true); + return; + } + } + else { + first_unavailable_input = i; + } + } + if (first_unavailable_input == -1) { + params.set_output(0, false); + return; + } + params.try_get_input_data_ptr_or_request(first_unavailable_input); + } +}; + +/** + * Outputs booleans that indicate which inputs of a switch node are used. Note that it's possible + * that both inputs are used when the condition is a field. + */ +class LazyFunctionForSwitchSocketUsage : public lf::LazyFunction { + public: + LazyFunctionForSwitchSocketUsage() + { + debug_name_ = "Switch Socket Usage"; + inputs_.append_as("Condition", CPPType::get>()); + outputs_.append_as("False", CPPType::get()); + outputs_.append_as("True", CPPType::get()); + } + + void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override + { + const ValueOrField &condition = params.get_input>(0); + if (condition.is_field()) { + params.set_output(0, true); + params.set_output(1, true); + } + else { + const bool value = condition.as_value(); + params.set_output(0, !value); + params.set_output(1, value); + } + } +}; + +/** + * Takes a field as input and extracts the set of anonymous attributes that it references. + */ +class LazyFunctionForAnonymousAttributeSetExtract : public lf::LazyFunction { + private: + const ValueOrFieldCPPType &type_; + + public: + LazyFunctionForAnonymousAttributeSetExtract(const ValueOrFieldCPPType &type) : type_(type) + { + debug_name_ = "Extract Attribute Set"; + inputs_.append_as("Field", type.self); + outputs_.append_as("Attributes", CPPType::get()); + } + + void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override + { + const void *value_or_field = params.try_get_input_data_ptr(0); + bke::AnonymousAttributeSet attributes; + if (type_.is_field(value_or_field)) { + const GField &field = *type_.get_field_ptr(value_or_field); + field.node().for_each_field_input_recursive([&](const FieldInput &field_input) { + if (const auto *attr_field_input = dynamic_cast( + &field_input)) { + if (!attributes.names) { + attributes.names = std::make_shared>(); + } + attributes.names->add_as(attr_field_input->anonymous_id()->name()); + } + }); + } + params.set_output(0, std::move(attributes)); + } +}; + +/** + * Conditionally joines multiple attribute sets. Each input attribute set can be disabled with a + * corresponding boolean input. + */ +class LazyFunctionForAnonymousAttributeSetJoin : public lf::LazyFunction { + const int amount_; + + public: + LazyFunctionForAnonymousAttributeSetJoin(const int amount) : amount_(amount) + { + debug_name_ = "Join Attribute Sets"; + for ([[maybe_unused]] const int i : IndexRange(amount)) { + inputs_.append_as("Use", CPPType::get()); + inputs_.append_as( + "Attribute Set", CPPType::get(), lf::ValueUsage::Maybe); + } + outputs_.append_as("Attribute Set", CPPType::get()); + } + + void execute_impl(lf::Params ¶ms, const lf::Context & /*context*/) const override + { + Vector sets; + bool set_is_missing = false; + for (const int i : IndexRange(amount_)) { + if (params.get_input(this->get_use_input(i))) { + if (bke::AnonymousAttributeSet *set = + params.try_get_input_data_ptr_or_request( + this->get_attribute_set_input(i))) { + sets.append(set); + } + else { + set_is_missing = true; + } + } + } + if (set_is_missing) { + return; + } + bke::AnonymousAttributeSet joined_set; + if (sets.is_empty()) { + /* Nothing to do. */ + } + else if (sets.size() == 1) { + joined_set.names = std::move(sets[0]->names); + } + else { + joined_set.names = std::make_shared>(); + for (const bke::AnonymousAttributeSet *set : sets) { + if (set->names) { + for (const std::string &name : *set->names) { + joined_set.names->add(name); + } + } + } + } + params.set_output(0, std::move(joined_set)); + } + + int get_use_input(const int i) const + { + return 2 * i; + } + + int get_attribute_set_input(const int i) const + { + return 2 * i + 1; + } +}; + +enum class AttributeReferenceKeyType { + /** Attribute referenced by a field passed into the group. */ + InputField, + /** Attributes referenced on the output geometry outside of the current group. */ + OutputGeometry, + /** Attribute referenced by a field created within the current group. */ + Socket, +}; + +/** + * Identifier for something that can reference anonymous attributes that should be propagated. + */ +struct AttributeReferenceKey { + AttributeReferenceKeyType type; + /* Used when type is InputField or OutputGeometry. */ + int index = 0; + /* Used when type is Socket. */ + const bNodeSocket *bsocket = nullptr; + + uint64_t hash() const + { + return get_default_hash_3(this->type, this->bsocket, this->index); + } + + friend bool operator==(const AttributeReferenceKey &a, const AttributeReferenceKey &b) + { + return a.type == b.type && a.bsocket == b.bsocket && a.index == b.index; + } + + friend std::ostream &operator<<(std::ostream &stream, const AttributeReferenceKey &value) + { + if (value.type == AttributeReferenceKeyType::InputField) { + stream << "Input Field: " << value.index; + } + else if (value.type == AttributeReferenceKeyType::OutputGeometry) { + stream << "Output Geometry: " << value.index; + } + else { + stream << "Socket: " << value.bsocket->owner_node().name << " -> " << value.bsocket->name; + } + return stream; + } +}; + +/** + * Additional information that corresponds to an #AttributeReferenceKey. + */ +struct AttributeReferenceInfo { + /** Output socket that contains an attribute set containing the referenced attributes. */ + lf::OutputSocket *lf_attribute_set_socket = nullptr; + /** Geometry sockets that contain the referenced attributes. */ + Vector initial_geometry_sockets; +}; + /** * Utility class to build a lazy-function graph based on a geometry nodes tree. * This is mainly a separate class because it makes it easier to have variables that can be @@ -762,12 +1150,34 @@ struct GeometryNodesLazyFunctionGraphBuilder { Map output_socket_map_; Map multi_input_socket_nodes_; const bke::DataTypeConversions *conversions_; + /** + * Maps bsockets to boolean sockets in the graph whereby each boolean socket indicates whether + * the bsocket is used. Sockets not contained in this map are not used. + * This is indexed by `bNodeSocket::index_in_tree()`. + */ + Array socket_is_used_map_; + /** + * Some built-in nodes get additional boolean inputs that indicate whether certain outputs are + * used (field output sockets that contain new anonymous attribute references). + */ + Vector> output_used_sockets_for_builtin_nodes_; + /** + * Maps from output geometry sockets to corresponding attribute set inputs. + */ + Map attribute_set_propagation_map_; + /** + * Boolean inputs that tell a node if some socket (of the same or another node) is used. If this + * socket is in a link-cycle, its input can become a constant true. + */ + Set socket_usage_inputs_; /** * All group input nodes are combined into one dummy node in the lazy-function graph. */ lf::DummyNode *group_input_lf_node_; + friend class UsedSocketVisualizeOptions; + public: GeometryNodesLazyFunctionGraphBuilder(const bNodeTree &btree, GeometryNodesLazyFunctionGraphInfo &lf_graph_info) @@ -783,12 +1193,28 @@ struct GeometryNodesLazyFunctionGraphBuilder { mapping_ = &lf_graph_info_->mapping; conversions_ = &bke::get_implicit_type_conversions(); + socket_is_used_map_.reinitialize(btree_.all_sockets().size()); + socket_is_used_map_.fill(nullptr); + this->prepare_node_multi_functions(); this->build_group_input_node(); + if (btree_.group_output_node() == nullptr) { + this->build_fallback_output_node(); + } this->handle_nodes(); this->handle_links(); this->add_default_inputs(); + this->build_attribute_propagation_input_node(); + this->build_output_usage_input_node(); + this->build_input_usage_output_node(); + this->build_socket_usages(); + + this->build_attribute_propagation_sets(); + this->fix_link_cycles(); + + // this->print_graph(); + lf_graph_->update_node_indices(); lf_graph_info_->num_inline_nodes_approximate += lf_graph_->nodes().size(); } @@ -818,6 +1244,29 @@ struct GeometryNodesLazyFunctionGraphBuilder { lf_graph_info_->dummy_debug_infos_.append(std::move(debug_info)); } + /** + * Build an output node that just outputs default values in the case when there is no Group + * Output node in the tree. + */ + void build_fallback_output_node() + { + Vector output_cpp_types; + auto debug_info = std::make_unique(); + for (const bNodeSocket *interface_output : btree_.interface_outputs()) { + output_cpp_types.append(interface_output->typeinfo->geometry_nodes_cpp_type); + debug_info->socket_names.append(interface_output->name); + } + + lf::Node &lf_node = lf_graph_->add_dummy(output_cpp_types, {}, debug_info.get()); + for (lf::InputSocket *lf_socket : lf_node.inputs()) { + const CPPType &type = lf_socket->type(); + lf_socket->set_default_value(type.default_value()); + } + mapping_->standard_group_output_sockets = lf_node.inputs(); + + lf_graph_info_->dummy_debug_infos_.append(std::move(debug_info)); + } + void handle_nodes() { /* Insert all nodes into the lazy function graph. */ @@ -935,22 +1384,25 @@ struct GeometryNodesLazyFunctionGraphBuilder { void handle_group_output_node(const bNode &bnode) { Vector output_cpp_types; - const Span interface_outputs = btree_.interface_outputs(); - for (const bNodeSocket *interface_input : interface_outputs) { + auto debug_info = std::make_unique(); + for (const bNodeSocket *interface_input : btree_.interface_outputs()) { output_cpp_types.append(interface_input->typeinfo->geometry_nodes_cpp_type); + debug_info->socket_names.append(interface_input->name); } - auto debug_info = std::make_unique(); lf::DummyNode &group_output_lf_node = lf_graph_->add_dummy( output_cpp_types, {}, debug_info.get()); - for (const int i : interface_outputs.index_range()) { + for (const int i : group_output_lf_node.inputs().index_range()) { const bNodeSocket &bsocket = bnode.input_socket(i); lf::InputSocket &lf_socket = group_output_lf_node.input(i); input_socket_map_.add(&bsocket, &lf_socket); mapping_->dummy_socket_map.add(&bsocket, &lf_socket); mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket); - debug_info->socket_names.append(interface_outputs[i]->name); + } + + if (&bnode == btree_.group_output_node()) { + mapping_->standard_group_output_sockets = group_output_lf_node.inputs(); } lf_graph_info_->dummy_debug_infos_.append(std::move(debug_info)); @@ -968,21 +1420,18 @@ struct GeometryNodesLazyFunctionGraphBuilder { return; } - Vector used_inputs; - Vector used_outputs; - auto lazy_function = std::make_unique( - bnode, *group_lf_graph_info, used_inputs, used_outputs); + auto lazy_function = std::make_unique(bnode, *group_lf_graph_info); lf::FunctionNode &lf_node = lf_graph_->add_function(*lazy_function); - lf_graph_info_->functions.append(std::move(lazy_function)); - for (const int i : used_inputs.index_range()) { - const bNodeSocket &bsocket = *used_inputs[i]; + + for (const int i : bnode.input_sockets().index_range()) { + const bNodeSocket &bsocket = bnode.input_socket(i); BLI_assert(!bsocket.is_multi_input()); lf::InputSocket &lf_socket = lf_node.input(i); input_socket_map_.add(&bsocket, &lf_socket); mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket); } - for (const int i : used_outputs.index_range()) { - const bNodeSocket &bsocket = *used_outputs[i]; + for (const int i : bnode.output_sockets().index_range()) { + const bNodeSocket &bsocket = bnode.output_socket(i); lf::OutputSocket &lf_socket = lf_node.output(i); output_socket_map_.add_new(&bsocket, &lf_socket); mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket); @@ -990,6 +1439,18 @@ struct GeometryNodesLazyFunctionGraphBuilder { mapping_->group_node_map.add(&bnode, &lf_node); lf_graph_info_->num_inline_nodes_approximate += group_lf_graph_info->num_inline_nodes_approximate; + static const bool static_false = false; + for (const int i : lazy_function->lf_input_for_output_bsocket_usage_.values()) { + lf_node.input(i).set_default_value(&static_false); + socket_usage_inputs_.add(&lf_node.input(i)); + } + /* Keep track of attribute set inputs that need to be populated later. */ + for (const auto [output_index, lf_input_index] : + lazy_function->lf_input_for_attribute_propagation_to_output_.items()) { + attribute_set_propagation_map_.add(&bnode.output_socket(output_index), + &lf_node.input(lf_input_index)); + } + lf_graph_info_->functions.append(std::move(lazy_function)); } void handle_geometry_node(const bNode &bnode) @@ -999,7 +1460,6 @@ struct GeometryNodesLazyFunctionGraphBuilder { auto lazy_function = std::make_unique( bnode, used_inputs, used_outputs); lf::Node &lf_node = lf_graph_->add_function(*lazy_function); - lf_graph_info_->functions.append(std::move(lazy_function)); for (const int i : used_inputs.index_range()) { const bNodeSocket &bsocket = *used_inputs[i]; @@ -1026,6 +1486,21 @@ struct GeometryNodesLazyFunctionGraphBuilder { output_socket_map_.add_new(&bsocket, &lf_socket); mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket); } + + for (const auto [identifier, lf_input_index] : + lazy_function->lf_input_for_output_bsocket_usage_.items()) { + output_used_sockets_for_builtin_nodes_.append_as(&bnode.output_by_identifier(identifier), + &lf_node.input(lf_input_index)); + socket_usage_inputs_.add_new(&lf_node.input(lf_input_index)); + } + /* Keep track of attribute set inputs that need to be populated later. */ + for (const auto [identifier, lf_input_index] : + lazy_function->lf_input_for_attribute_propagation_to_output_.items()) { + attribute_set_propagation_map_.add(&bnode.output_by_identifier(identifier), + &lf_node.input(lf_input_index)); + } + + lf_graph_info_->functions.append(std::move(lazy_function)); } void handle_multi_function_node(const bNode &bnode, const NodeMultiFunctions::Item &fn_item) @@ -1269,8 +1744,985 @@ struct GeometryNodesLazyFunctionGraphBuilder { lf_graph_->add_link(lf_node.output(0), input_lf_socket); return true; } + + /** + * Every output geometry socket that may propagate attributes has to know which attributes should + * be propagated. Therefore, every one of these outputs gets a corresponding attribute set input. + */ + void build_attribute_propagation_input_node() + { + const aal::RelationsInNode &tree_relations = *btree_.runtime->anonymous_attribute_relations; + Vector output_indices; + for (const aal::PropagateRelation &relation : tree_relations.propagate_relations) { + output_indices.append_non_duplicates(relation.to_geometry_output); + } + Vector cpp_types; + auto debug_info = std::make_unique(); + debug_info->name = "Attributes to Propagate to Output"; + cpp_types.append_n_times(&CPPType::get(), output_indices.size()); + lf::Node &lf_node = lf_graph_->add_dummy({}, cpp_types, debug_info.get()); + for (const int i : output_indices.index_range()) { + const int output_index = output_indices[i]; + mapping_->attribute_set_by_geometry_output.add(output_index, &lf_node.output(i)); + debug_info->output_names.append(btree_.interface_outputs()[output_index]->name); + } + lf_graph_info_->dummy_debug_infos_.append(std::move(debug_info)); + } + + /** + * Build new boolean group inputs that indicate which group outputs are used. + */ + void build_output_usage_input_node() + { + const Span interface_outputs = btree_.interface_outputs(); + + Vector cpp_types; + cpp_types.append_n_times(&CPPType::get(), interface_outputs.size()); + auto debug_info = std::make_unique(); + debug_info->name = "Output Socket Usage"; + lf::Node &lf_node = lf_graph_->add_dummy({}, cpp_types, debug_info.get()); + for (const int i : interface_outputs.index_range()) { + mapping_->group_output_used_sockets.append(&lf_node.output(i)); + debug_info->output_names.append(interface_outputs[i]->name); + } + lf_graph_info_->dummy_debug_infos_.append(std::move(debug_info)); + } + + /** + * Build new boolean group outputs that indicate which group inputs are used depending on other + * group inputs. + */ + void build_input_usage_output_node() + { + const Span interface_inputs = btree_.interface_inputs(); + + Vector cpp_types; + cpp_types.append_n_times(&CPPType::get(), interface_inputs.size()); + auto debug_info = std::make_unique(); + debug_info->name = "Input Socket Usage"; + lf::Node &lf_node = lf_graph_->add_dummy(cpp_types, {}, debug_info.get()); + for (const int i : interface_inputs.index_range()) { + mapping_->group_input_usage_sockets.append(&lf_node.input(i)); + debug_info->input_names.append(interface_inputs[i]->name); + } + lf_graph_info_->dummy_debug_infos_.append(std::move(debug_info)); + } + + /** + * For every socket we want to determine if it will be used depending on the inputs of the node + * group (just static analysis is not enough when there are e.g. Switch nodes). This function + * populates #socket_is_used_map_ with that information. + */ + void build_socket_usages() + { + OrSocketUsagesCache or_socket_usages_cache; + + if (const bNode *group_output_bnode = btree_.group_output_node()) { + /* Whether a group output is used is determined by a group input that has been created + * exactly for this purpose. */ + for (const bNodeSocket *bsocket : group_output_bnode->input_sockets().drop_back(1)) { + const int index = bsocket->index(); + socket_is_used_map_[bsocket->index_in_tree()] = const_cast( + mapping_->group_output_used_sockets[index]); + } + } + + /* Iterate over all nodes from right to left to determine when which sockets are used. */ + for (const bNode *bnode : btree_.toposort_right_to_left()) { + const bNodeType *node_type = bnode->typeinfo; + if (node_type == nullptr) { + /* Ignore. */ + continue; + } + + this->build_output_socket_usages(*bnode, or_socket_usages_cache); + + if (bnode->is_muted()) { + this->build_muted_node_usages(*bnode, or_socket_usages_cache); + continue; + } + + switch (node_type->type) { + case NODE_GROUP_OUTPUT: { + /* Handled before this loop already. */ + break; + } + case NODE_GROUP_INPUT: { + /* Handled after this loop. */ + break; + } + case NODE_FRAME: { + /* Ignored. */ + break; + } + case NODE_REROUTE: { + /* The input is used exactly when the output is used. */ + socket_is_used_map_[bnode->input_socket(0).index_in_tree()] = + socket_is_used_map_[bnode->output_socket(0).index_in_tree()]; + break; + } + case GEO_NODE_SWITCH: { + this->build_switch_node_socket_usage(*bnode); + break; + } + case GEO_NODE_VIEWER: { + this->build_viewer_node_socket_usage(*bnode); + break; + } + case NODE_GROUP: + case NODE_CUSTOM_GROUP: { + this->build_group_node_socket_usage(*bnode, or_socket_usages_cache); + break; + } + default: { + this->build_standard_node_input_socket_usage(*bnode, or_socket_usages_cache); + break; + } + } + } + + this->build_group_input_usages(or_socket_usages_cache); + this->link_output_used_sockets_for_builtin_nodes(); + } + + using OrSocketUsagesCache = Map, lf::OutputSocket *>; + + /** + * Combine multiple socket usages with a logical or. Inserts a new node for that purpose if + * necessary. + */ + lf::OutputSocket *or_socket_usages(MutableSpan usages, + OrSocketUsagesCache &cache) + { + if (usages.is_empty()) { + return nullptr; + } + if (usages.size() == 1) { + return usages[0]; + } + + std::sort(usages.begin(), usages.end()); + return cache.lookup_or_add_cb_as(usages, [&]() { + auto logical_or_fn = std::make_unique(usages.size()); + lf::Node &logical_or_node = lf_graph_->add_function(*logical_or_fn); + lf_graph_info_->functions.append(std::move(logical_or_fn)); + + for (const int i : usages.index_range()) { + lf_graph_->add_link(*usages[i], logical_or_node.input(i)); + } + return &logical_or_node.output(0); + }); + } + + void build_output_socket_usages(const bNode &bnode, OrSocketUsagesCache &or_socket_usages_cache) + { + /* Output sockets are used when any of their linked inputs are used. */ + for (const bNodeSocket *socket : bnode.output_sockets()) { + if (!socket->is_available()) { + continue; + } + /* Determine when linked target sockets are used. */ + Vector target_usages; + for (const bNodeLink *link : socket->directly_linked_links()) { + if (!link->is_used()) { + continue; + } + const bNodeSocket &target_socket = *link->tosock; + if (lf::OutputSocket *is_used_socket = + socket_is_used_map_[target_socket.index_in_tree()]) { + target_usages.append_non_duplicates(is_used_socket); + } + } + /* Combine target socket usages into the usage of the current socket. */ + socket_is_used_map_[socket->index_in_tree()] = this->or_socket_usages( + target_usages, or_socket_usages_cache); + } + } + + /** + * An input of a muted node is used when any of its internally linked outputs is used. + */ + void build_muted_node_usages(const bNode &bnode, OrSocketUsagesCache &or_socket_usages_cache) + { + /* Find all outputs that use a specific input. */ + MultiValueMap outputs_by_input; + for (const bNodeLink *blink : bnode.internal_links()) { + outputs_by_input.add(blink->fromsock, blink->tosock); + } + for (const auto item : outputs_by_input.items()) { + const bNodeSocket &input_bsocket = *item.key; + const Span output_bsockets = item.value; + + /* The input is used if any of the internally linked outputs is used. */ + Vector lf_socket_usages; + for (const bNodeSocket *output_bsocket : output_bsockets) { + if (lf::OutputSocket *lf_socket = socket_is_used_map_[output_bsocket->index_in_tree()]) { + lf_socket_usages.append(lf_socket); + } + } + socket_is_used_map_[input_bsocket.index_in_tree()] = this->or_socket_usages( + lf_socket_usages, or_socket_usages_cache); + } + } + + void build_switch_node_socket_usage(const bNode &bnode) + { + const bNodeSocket *switch_input_bsocket = nullptr; + const bNodeSocket *false_input_bsocket = nullptr; + const bNodeSocket *true_input_bsocket = nullptr; + const bNodeSocket *output_bsocket = nullptr; + for (const bNodeSocket *socket : bnode.input_sockets()) { + if (!socket->is_available()) { + continue; + } + if (socket->name == StringRef("Switch")) { + switch_input_bsocket = socket; + } + else if (socket->name == StringRef("False")) { + false_input_bsocket = socket; + } + else if (socket->name == StringRef("True")) { + true_input_bsocket = socket; + } + } + for (const bNodeSocket *socket : bnode.output_sockets()) { + if (socket->is_available()) { + output_bsocket = socket; + break; + } + } + lf::OutputSocket *output_is_used_socket = socket_is_used_map_[output_bsocket->index_in_tree()]; + if (output_is_used_socket == nullptr) { + return; + } + socket_is_used_map_[switch_input_bsocket->index_in_tree()] = output_is_used_socket; + lf::InputSocket *lf_switch_input = input_socket_map_.lookup(switch_input_bsocket)[0]; + if (lf::OutputSocket *lf_switch_origin = lf_switch_input->origin()) { + /* The condition input is dynamic, so the usage of the other inputs is as well. */ + static const LazyFunctionForSwitchSocketUsage switch_socket_usage_fn; + lf::Node &lf_node = lf_graph_->add_function(switch_socket_usage_fn); + lf_graph_->add_link(*lf_switch_origin, lf_node.input(0)); + socket_is_used_map_[false_input_bsocket->index_in_tree()] = &lf_node.output(0); + socket_is_used_map_[true_input_bsocket->index_in_tree()] = &lf_node.output(1); + } + else { + if (switch_input_bsocket->default_value_typed()->value) { + socket_is_used_map_[true_input_bsocket->index_in_tree()] = output_is_used_socket; + } + else { + socket_is_used_map_[false_input_bsocket->index_in_tree()] = output_is_used_socket; + } + } + } + + void build_viewer_node_socket_usage(const bNode &bnode) + { + const lf::FunctionNode &lf_viewer_node = *mapping_->viewer_node_map.lookup(&bnode); + auto lazy_function = std::make_unique(lf_viewer_node); + lf::Node &lf_node = lf_graph_->add_function(*lazy_function); + lf_graph_info_->functions.append(std::move(lazy_function)); + + for (const bNodeSocket *bsocket : bnode.input_sockets()) { + if (bsocket->is_available()) { + socket_is_used_map_[bsocket->index_in_tree()] = &lf_node.output(0); + } + } + } + + void build_group_node_socket_usage(const bNode &bnode, + OrSocketUsagesCache &or_socket_usages_cache) + { + const bNodeTree *bgroup = reinterpret_cast(bnode.id); + if (bgroup == nullptr) { + return; + } + const GeometryNodesLazyFunctionGraphInfo *group_lf_graph_info = + ensure_geometry_nodes_lazy_function_graph(*bgroup); + if (group_lf_graph_info == nullptr) { + return; + } + lf::FunctionNode &lf_group_node = const_cast( + *mapping_->group_node_map.lookup(&bnode)); + const auto &fn = static_cast(lf_group_node.function()); + + for (const bNodeSocket *input_bsocket : bnode.input_sockets()) { + const int input_index = input_bsocket->index(); + const InputUsageHint &input_usage_hint = + group_lf_graph_info->mapping.group_input_usage_hints[input_index]; + switch (input_usage_hint.type) { + case InputUsageHintType::Never: { + /* Nothing to do. */ + break; + } + case InputUsageHintType::DependsOnOutput: { + Vector output_usages; + for (const int i : input_usage_hint.output_dependencies) { + if (lf::OutputSocket *lf_socket = + socket_is_used_map_[bnode.output_socket(i).index_in_tree()]) { + output_usages.append(lf_socket); + } + } + socket_is_used_map_[input_bsocket->index_in_tree()] = this->or_socket_usages( + output_usages, or_socket_usages_cache); + break; + } + case InputUsageHintType::DynamicSocket: { + socket_is_used_map_[input_bsocket->index_in_tree()] = &const_cast( + lf_group_node.output(fn.lf_output_for_input_bsocket_usage_.lookup(input_index))); + break; + } + } + } + + for (const bNodeSocket *output_bsocket : bnode.output_sockets()) { + const int output_index = output_bsocket->index(); + const int lf_input_index = fn.lf_input_for_output_bsocket_usage_.lookup(output_index); + lf::InputSocket &lf_socket = lf_group_node.input(lf_input_index); + if (lf::OutputSocket *lf_output_is_used = + socket_is_used_map_[output_bsocket->index_in_tree()]) { + lf_graph_->add_link(*lf_output_is_used, lf_socket); + } + else { + static const bool static_false = false; + lf_socket.set_default_value(&static_false); + } + } + } + + void build_standard_node_input_socket_usage(const bNode &bnode, + OrSocketUsagesCache &or_socket_usages_cache) + { + if (bnode.input_sockets().is_empty()) { + return; + } + + Vector output_usages; + for (const bNodeSocket *output_socket : bnode.output_sockets()) { + if (!output_socket->is_available()) { + continue; + } + if (lf::OutputSocket *is_used_socket = socket_is_used_map_[output_socket->index_in_tree()]) { + output_usages.append_non_duplicates(is_used_socket); + } + } + + /* Assume every input is used when any output is used. */ + lf::OutputSocket *lf_usage = this->or_socket_usages(output_usages, or_socket_usages_cache); + if (lf_usage == nullptr) { + return; + } + + for (const bNodeSocket *input_socket : bnode.input_sockets()) { + if (input_socket->is_available()) { + socket_is_used_map_[input_socket->index_in_tree()] = lf_usage; + } + } + } + + void build_group_input_usages(OrSocketUsagesCache &or_socket_usages_cache) + { + const Span group_input_nodes = btree_.group_input_nodes(); + for (const int i : btree_.interface_inputs().index_range()) { + Vector target_usages; + for (const bNode *group_input_node : group_input_nodes) { + if (lf::OutputSocket *lf_socket = + socket_is_used_map_[group_input_node->output_socket(i).index_in_tree()]) { + target_usages.append_non_duplicates(lf_socket); + } + } + + lf::OutputSocket *lf_socket = this->or_socket_usages(target_usages, or_socket_usages_cache); + lf::InputSocket *lf_group_output = const_cast( + mapping_->group_input_usage_sockets[i]); + InputUsageHint input_usage_hint; + if (lf_socket == nullptr) { + static const bool static_false = false; + lf_group_output->set_default_value(&static_false); + input_usage_hint.type = InputUsageHintType::Never; + } + else { + lf_graph_->add_link(*lf_socket, *lf_group_output); + if (lf_socket->node().is_dummy()) { + /* Can support slightly more complex cases where it depends on more than one output in + * the future. */ + input_usage_hint.type = InputUsageHintType::DependsOnOutput; + input_usage_hint.output_dependencies = { + mapping_->group_output_used_sockets.first_index_of(lf_socket)}; + } + else { + input_usage_hint.type = InputUsageHintType::DynamicSocket; + } + } + lf_graph_info_->mapping.group_input_usage_hints.append(std::move(input_usage_hint)); + } + } + + void link_output_used_sockets_for_builtin_nodes() + { + for (const auto &[output_bsocket, lf_input] : output_used_sockets_for_builtin_nodes_) { + if (lf::OutputSocket *lf_is_used = socket_is_used_map_[output_bsocket->index_in_tree()]) { + lf_graph_->add_link(*lf_is_used, *lf_input); + } + else { + static const bool static_false = false; + lf_input->set_default_value(&static_false); + } + } + } + + void build_attribute_propagation_sets() + { + ResourceScope scope; + const Array relations_by_node = + bke::anonymous_attribute_inferencing::get_relations_by_node(btree_, scope); + + VectorSet attribute_reference_keys; + /* Indexed by reference key index. */ + Vector attribute_reference_infos; + this->build_attribute_references( + relations_by_node, attribute_reference_keys, attribute_reference_infos); + + MultiValueMap referenced_by_field_socket; + MultiValueMap propagated_to_geometry_socket; + this->gather_referenced_and_potentially_propagated_data(relations_by_node, + attribute_reference_keys, + attribute_reference_infos, + referenced_by_field_socket, + propagated_to_geometry_socket); + + MultiValueMap required_propagated_to_geometry_socket; + this->gather_required_propagated_data(relations_by_node, + attribute_reference_keys, + referenced_by_field_socket, + propagated_to_geometry_socket, + required_propagated_to_geometry_socket); + + this->build_attribute_sets_to_propagate(attribute_reference_keys, + attribute_reference_infos, + required_propagated_to_geometry_socket); + } + + void build_attribute_references(const Span relations_by_node, + VectorSet &r_attribute_reference_keys, + Vector &r_attribute_reference_infos) + { + auto add_get_attributes_node = [&](lf::OutputSocket &lf_field_socket) -> lf::OutputSocket & { + const ValueOrFieldCPPType &type = *ValueOrFieldCPPType::get_from_self( + lf_field_socket.type()); + auto lazy_function = std::make_unique(type); + lf::Node &lf_node = lf_graph_->add_function(*lazy_function); + lf_graph_->add_link(lf_field_socket, lf_node.input(0)); + lf_graph_info_->functions.append(std::move(lazy_function)); + return lf_node.output(0); + }; + + /* Find nodes that create new anonymous attributes. */ + for (const bNode *node : btree_.all_nodes()) { + const aal::RelationsInNode &relations = *relations_by_node[node->index()]; + for (const aal::AvailableRelation &relation : relations.available_relations) { + const bNodeSocket &geometry_bsocket = node->output_socket(relation.geometry_output); + const bNodeSocket &field_bsocket = node->output_socket(relation.field_output); + if (!field_bsocket.is_available()) { + continue; + } + if (!field_bsocket.is_directly_linked()) { + continue; + } + AttributeReferenceKey key; + key.type = AttributeReferenceKeyType::Socket; + key.bsocket = &field_bsocket; + const int key_index = r_attribute_reference_keys.index_of_or_add(key); + if (key_index >= r_attribute_reference_infos.size()) { + AttributeReferenceInfo info; + lf::OutputSocket &lf_field_socket = *output_socket_map_.lookup(&field_bsocket); + info.lf_attribute_set_socket = &add_get_attributes_node(lf_field_socket); + r_attribute_reference_infos.append(info); + } + AttributeReferenceInfo &info = r_attribute_reference_infos[key_index]; + if (geometry_bsocket.is_available()) { + info.initial_geometry_sockets.append(&geometry_bsocket); + } + } + } + + /* Find field group inputs that are evaluated within this node tree. */ + const aal::RelationsInNode &tree_relations = *btree_.runtime->anonymous_attribute_relations; + for (const aal::EvalRelation &relation : tree_relations.eval_relations) { + AttributeReferenceKey key; + key.type = AttributeReferenceKeyType::InputField; + key.index = relation.field_input; + r_attribute_reference_keys.add_new(key); + AttributeReferenceInfo info; + lf::OutputSocket &lf_field_socket = *const_cast( + mapping_->group_input_sockets[relation.field_input]); + info.lf_attribute_set_socket = &add_get_attributes_node(lf_field_socket); + for (const bNode *bnode : btree_.group_input_nodes()) { + info.initial_geometry_sockets.append(&bnode->output_socket(relation.geometry_input)); + } + r_attribute_reference_infos.append(std::move(info)); + } + /* Find group outputs that attributes need to be propagated to. */ + for (const aal::PropagateRelation &relation : tree_relations.propagate_relations) { + AttributeReferenceKey key; + key.type = AttributeReferenceKeyType::OutputGeometry; + key.index = relation.to_geometry_output; + const int key_index = r_attribute_reference_keys.index_of_or_add(key); + if (key_index >= r_attribute_reference_infos.size()) { + AttributeReferenceInfo info; + info.lf_attribute_set_socket = const_cast( + mapping_->attribute_set_by_geometry_output.lookup(relation.to_geometry_output)); + r_attribute_reference_infos.append(info); + } + AttributeReferenceInfo &info = r_attribute_reference_infos[key_index]; + for (const bNode *bnode : btree_.group_input_nodes()) { + info.initial_geometry_sockets.append(&bnode->output_socket(relation.from_geometry_input)); + } + } + } + + /** + * For every field socket, figure out which anonymous attributes it may reference. + * For every geometry socket, figure out which anonymous attributes may be propagated to it. + */ + void gather_referenced_and_potentially_propagated_data( + const Span relations_by_node, + const Span attribute_reference_keys, + const Span attribute_reference_infos, + MultiValueMap &r_referenced_by_field_socket, + MultiValueMap &r_propagated_to_geometry_socket) + { + /* Initialize maps. */ + for (const int key_index : attribute_reference_keys.index_range()) { + const AttributeReferenceKey &key = attribute_reference_keys[key_index]; + const AttributeReferenceInfo &info = attribute_reference_infos[key_index]; + switch (key.type) { + case AttributeReferenceKeyType::InputField: { + for (const bNode *bnode : btree_.group_input_nodes()) { + const bNodeSocket &bsocket = bnode->output_socket(key.index); + r_referenced_by_field_socket.add(&bsocket, key_index); + } + break; + } + case AttributeReferenceKeyType::OutputGeometry: { + break; + } + case AttributeReferenceKeyType::Socket: { + r_referenced_by_field_socket.add(key.bsocket, key_index); + break; + } + } + for (const bNodeSocket *geometry_bsocket : info.initial_geometry_sockets) { + r_propagated_to_geometry_socket.add(geometry_bsocket, key_index); + } + } + /* Propagate attribute usages from left to right. */ + for (const bNode *bnode : btree_.toposort_left_to_right()) { + for (const bNodeSocket *bsocket : bnode->input_sockets()) { + if (bsocket->is_available()) { + Vector referenced_keys; + Vector propagated_keys; + for (const bNodeLink *blink : bsocket->directly_linked_links()) { + if (blink->is_used()) { + referenced_keys.extend_non_duplicates( + r_referenced_by_field_socket.lookup(blink->fromsock)); + propagated_keys.extend_non_duplicates( + r_propagated_to_geometry_socket.lookup(blink->fromsock)); + } + } + if (!referenced_keys.is_empty()) { + r_referenced_by_field_socket.add_multiple(bsocket, referenced_keys); + } + if (!propagated_keys.is_empty()) { + r_propagated_to_geometry_socket.add_multiple(bsocket, propagated_keys); + } + } + } + const aal::RelationsInNode &relations = *relations_by_node[bnode->index()]; + for (const aal::ReferenceRelation &relation : relations.reference_relations) { + const bNodeSocket &input_bsocket = bnode->input_socket(relation.from_field_input); + const bNodeSocket &output_bsocket = bnode->output_socket(relation.to_field_output); + if (!input_bsocket.is_available() || !output_bsocket.is_available()) { + continue; + } + r_referenced_by_field_socket.add_multiple( + &output_bsocket, Vector(r_referenced_by_field_socket.lookup(&input_bsocket))); + } + for (const aal::PropagateRelation &relation : relations.propagate_relations) { + const bNodeSocket &input_bsocket = bnode->input_socket(relation.from_geometry_input); + const bNodeSocket &output_bsocket = bnode->output_socket(relation.to_geometry_output); + if (!input_bsocket.is_available() || !output_bsocket.is_available()) { + continue; + } + r_propagated_to_geometry_socket.add_multiple( + &output_bsocket, Vector(r_propagated_to_geometry_socket.lookup(&input_bsocket))); + } + } + } + + /** + * Determines which anonymous attributes should be propagated to which geometry sockets. + */ + void gather_required_propagated_data( + const Span relations_by_node, + const VectorSet &attribute_reference_keys, + const MultiValueMap &referenced_by_field_socket, + const MultiValueMap &propagated_to_geometry_socket, + MultiValueMap &r_required_propagated_to_geometry_socket) + { + const aal::RelationsInNode &tree_relations = *btree_.runtime->anonymous_attribute_relations; + MultiValueMap required_by_geometry_socket; + + /* Initialize required attributes at group output. */ + if (const bNode *group_output_bnode = btree_.group_output_node()) { + for (const aal::PropagateRelation &relation : tree_relations.propagate_relations) { + AttributeReferenceKey key; + key.type = AttributeReferenceKeyType::OutputGeometry; + key.index = relation.to_geometry_output; + const int key_index = attribute_reference_keys.index_of(key); + required_by_geometry_socket.add( + &group_output_bnode->input_socket(relation.to_geometry_output), key_index); + } + for (const aal::AvailableRelation &relation : tree_relations.available_relations) { + const bNodeSocket &geometry_bsocket = group_output_bnode->input_socket( + relation.geometry_output); + const bNodeSocket &field_bsocket = group_output_bnode->input_socket(relation.field_output); + required_by_geometry_socket.add_multiple( + &geometry_bsocket, referenced_by_field_socket.lookup(&field_bsocket)); + } + } + + /* Propagate attribute usages from right to left. */ + for (const bNode *bnode : btree_.toposort_right_to_left()) { + const aal::RelationsInNode &relations = *relations_by_node[bnode->index()]; + for (const bNodeSocket *bsocket : bnode->output_sockets()) { + if (!bsocket->is_available()) { + continue; + } + Vector required_attributes; + for (const bNodeLink *blink : bsocket->directly_linked_links()) { + if (blink->is_used()) { + const bNodeSocket &to_socket = *blink->tosock; + required_attributes.extend_non_duplicates( + required_by_geometry_socket.lookup(&to_socket)); + } + } + const Span available_attributes = propagated_to_geometry_socket.lookup(bsocket); + for (const int key_index : required_attributes) { + if (available_attributes.contains(key_index)) { + required_by_geometry_socket.add(bsocket, key_index); + + const AttributeReferenceKey &key = attribute_reference_keys[key_index]; + if (key.type != AttributeReferenceKeyType::Socket || + &key.bsocket->owner_node() != bnode) { + r_required_propagated_to_geometry_socket.add(bsocket, key_index); + } + } + } + } + + for (const bNodeSocket *bsocket : bnode->input_sockets()) { + if (!bsocket->is_available()) { + continue; + } + Vector required_attributes; + for (const aal::PropagateRelation &relation : relations.propagate_relations) { + if (relation.from_geometry_input == bsocket->index()) { + const bNodeSocket &output_bsocket = bnode->output_socket(relation.to_geometry_output); + required_attributes.extend_non_duplicates( + required_by_geometry_socket.lookup(&output_bsocket)); + } + } + for (const aal::EvalRelation &relation : relations.eval_relations) { + if (relation.geometry_input == bsocket->index()) { + const bNodeSocket &field_bsocket = bnode->input_socket(relation.field_input); + if (field_bsocket.is_available()) { + required_attributes.extend_non_duplicates( + referenced_by_field_socket.lookup(&field_bsocket)); + } + } + } + const Span available_attributes = propagated_to_geometry_socket.lookup(bsocket); + for (const int key_index : required_attributes) { + if (available_attributes.contains(key_index)) { + required_by_geometry_socket.add(bsocket, key_index); + } + } + } + } + } + + /** + * For every node that propagates attributes, prepare an attribute set containing information + * about which attributes should be propagated. + */ + void build_attribute_sets_to_propagate( + const Span attribute_reference_keys, + const Span attribute_reference_infos, + const MultiValueMap &required_propagated_to_geometry_socket) + { + JoinAttibuteSetsCache join_attribute_sets_cache; + + for (const auto [geometry_output_bsocket, lf_attribute_set_input] : + attribute_set_propagation_map_.items()) { + const Span required = required_propagated_to_geometry_socket.lookup( + geometry_output_bsocket); + + Vector attribute_set_sockets; + Vector used_sockets; + + for (const int i : required.index_range()) { + const int key_index = required[i]; + const AttributeReferenceKey &key = attribute_reference_keys[key_index]; + const AttributeReferenceInfo &info = attribute_reference_infos[key_index]; + lf::OutputSocket *lf_socket_usage = nullptr; + switch (key.type) { + case AttributeReferenceKeyType::InputField: { + lf_socket_usage = const_cast( + mapping_->group_input_usage_sockets[key.index]) + ->origin(); + break; + } + case AttributeReferenceKeyType::OutputGeometry: { + lf_socket_usage = const_cast( + mapping_->group_output_used_sockets[key.index]); + break; + } + case AttributeReferenceKeyType::Socket: { + lf_socket_usage = socket_is_used_map_[key.bsocket->index_in_tree()]; + break; + } + } + if (lf_socket_usage) { + attribute_set_sockets.append(info.lf_attribute_set_socket); + used_sockets.append(lf_socket_usage); + } + } + if (lf::OutputSocket *joined_attribute_set = this->join_attribute_sets( + attribute_set_sockets, used_sockets, join_attribute_sets_cache)) { + lf_graph_->add_link(*joined_attribute_set, *lf_attribute_set_input); + } + else { + static const bke::AnonymousAttributeSet empty_set; + lf_attribute_set_input->set_default_value(&empty_set); + } + } + } + + using JoinAttibuteSetsCache = Map, lf::OutputSocket *>; + + /** + * Join multiple attributes set into a single attribute set that can be passed into a node. + */ + lf::OutputSocket *join_attribute_sets(const Span attribute_set_sockets, + const Span used_sockets, + JoinAttibuteSetsCache &cache) + { + BLI_assert(attribute_set_sockets.size() == used_sockets.size()); + if (attribute_set_sockets.is_empty()) { + return nullptr; + } + if (attribute_set_sockets.size() == 1) { + return attribute_set_sockets[0]; + } + + Vector key; + key.extend(attribute_set_sockets); + key.extend(used_sockets); + std::sort(key.begin(), key.end()); + return cache.lookup_or_add_cb(key, [&]() { + auto lazy_function = std::make_unique( + attribute_set_sockets.size()); + lf::Node &lf_node = lf_graph_->add_function(*lazy_function); + for (const int i : attribute_set_sockets.index_range()) { + lf::InputSocket &lf_use_input = lf_node.input(lazy_function->get_use_input(i)); + socket_usage_inputs_.add(&lf_use_input); + lf::InputSocket &lf_attributes_input = lf_node.input( + lazy_function->get_attribute_set_input(i)); + lf_graph_->add_link(*used_sockets[i], lf_use_input); + lf_graph_->add_link(*attribute_set_sockets[i], lf_attributes_input); + } + lf_graph_info_->functions.append(std::move(lazy_function)); + return &lf_node.output(0); + }); + } + + /** + * By depending on "the future" (whether a specific socket is used in the future), it is possible + * to introduce cycles in the graph. This function finds those cycles and breaks them by removing + * specific links. + * + * Example for a cycle: There is a `Distribute Points on Faces` node and its `Normal` output is + * only used when the number of generated points is larger than 1000 because of some switch node + * later in the tree. In this case, to know whether the `Normal` output is needed, one first has + * to compute the points, but for that one has to know whether the normal information has to be + * added to the points. The fix is to always add the normal information in this case. + */ + void fix_link_cycles() + { + lf_graph_->update_socket_indices(); + const int sockets_num = lf_graph_->socket_num(); + + struct SocketState { + bool done = false; + bool in_stack = false; + }; + + Array socket_states(sockets_num); + + Stack lf_sockets_to_check; + for (lf::Node *lf_node : lf_graph_->nodes()) { + if (lf_node->is_function()) { + for (lf::OutputSocket *lf_socket : lf_node->outputs()) { + if (lf_socket->targets().is_empty()) { + lf_sockets_to_check.push(lf_socket); + } + } + } + if (lf_node->outputs().is_empty()) { + for (lf::InputSocket *lf_socket : lf_node->inputs()) { + lf_sockets_to_check.push(lf_socket); + } + } + } + Vector lf_socket_stack; + while (!lf_sockets_to_check.is_empty()) { + lf::Socket *lf_inout_socket = lf_sockets_to_check.peek(); + lf::Node &lf_node = lf_inout_socket->node(); + SocketState &state = socket_states[lf_inout_socket->index_in_graph()]; + lf_socket_stack.append(lf_inout_socket); + state.in_stack = true; + + Vector lf_origin_sockets; + if (lf_inout_socket->is_input()) { + lf::InputSocket &lf_input_socket = lf_inout_socket->as_input(); + if (lf::OutputSocket *lf_origin_socket = lf_input_socket.origin()) { + lf_origin_sockets.append(lf_origin_socket); + } + } + else { + lf::OutputSocket &lf_output_socket = lf_inout_socket->as_output(); + if (lf_node.is_function()) { + lf::FunctionNode &lf_function_node = static_cast(lf_node); + const lf::LazyFunction &fn = lf_function_node.function(); + fn.possible_output_dependencies( + lf_output_socket.index(), [&](const Span input_indices) { + for (const int input_index : input_indices) { + lf_origin_sockets.append(&lf_node.input(input_index)); + } + }); + } + } + + bool pushed_socket = false; + for (lf::Socket *lf_origin_socket : lf_origin_sockets) { + if (socket_states[lf_origin_socket->index_in_graph()].in_stack) { + const Span cycle = lf_socket_stack.as_span().drop_front( + lf_socket_stack.first_index_of(lf_origin_socket)); + + bool broke_cycle = false; + for (lf::Socket *lf_cycle_socket : cycle) { + if (lf_cycle_socket->is_input() && + socket_usage_inputs_.contains(&lf_cycle_socket->as_input())) { + lf::InputSocket &lf_cycle_input_socket = lf_cycle_socket->as_input(); + lf_graph_->clear_origin(lf_cycle_input_socket); + static const bool static_true = true; + lf_cycle_input_socket.set_default_value(&static_true); + broke_cycle = true; + } + } + if (!broke_cycle) { + BLI_assert_unreachable(); + } + } + else if (!socket_states[lf_origin_socket->index_in_graph()].done) { + lf_sockets_to_check.push(lf_origin_socket); + pushed_socket = true; + } + } + if (pushed_socket) { + continue; + } + + state.done = true; + state.in_stack = false; + lf_sockets_to_check.pop(); + lf_socket_stack.pop_last(); + } + } + + void print_graph(); }; +class UsedSocketVisualizeOptions : public lf::Graph::ToDotOptions { + private: + const GeometryNodesLazyFunctionGraphBuilder &builder_; + Map socket_font_colors_; + Map socket_name_suffixes_; + + public: + UsedSocketVisualizeOptions(const GeometryNodesLazyFunctionGraphBuilder &builder) + : builder_(builder) + { + VectorSet found; + for (const int bsocket_index : builder_.socket_is_used_map_.index_range()) { + const bNodeSocket *bsocket = builder_.btree_.all_sockets()[bsocket_index]; + lf::OutputSocket *lf_used_socket = builder_.socket_is_used_map_[bsocket_index]; + if (lf_used_socket == nullptr) { + continue; + } + const float hue = BLI_hash_int_01(uintptr_t(lf_used_socket)); + std::stringstream ss; + ss.precision(3); + ss << hue << " 0.9 0.5"; + const std::string color_str = ss.str(); + const std::string suffix = " (" + std::to_string(found.index_of_or_add(lf_used_socket)) + + ")"; + socket_font_colors_.add(lf_used_socket, color_str); + socket_name_suffixes_.add(lf_used_socket, suffix); + + if (bsocket->is_input()) { + for (const lf::InputSocket *lf_socket : builder_.input_socket_map_.lookup(bsocket)) { + socket_font_colors_.add(lf_socket, color_str); + socket_name_suffixes_.add(lf_socket, suffix); + } + } + else if (lf::OutputSocket *lf_socket = builder_.output_socket_map_.lookup(bsocket)) { + socket_font_colors_.add(lf_socket, color_str); + socket_name_suffixes_.add(lf_socket, suffix); + } + } + } + + std::optional socket_font_color(const lf::Socket &socket) const override + { + if (const std::string *color = socket_font_colors_.lookup_ptr(&socket)) { + return *color; + } + return std::nullopt; + } + + std::string socket_name(const lf::Socket &socket) const override + { + return socket.name() + socket_name_suffixes_.lookup_default(&socket, ""); + } + + void add_edge_attributes(const lf::OutputSocket & /*from*/, + const lf::InputSocket &to, + dot::DirectedEdge &dot_edge) const + { + if (builder_.socket_usage_inputs_.contains_as(&to)) { + // dot_edge.attributes.set("constraint", "false"); + dot_edge.attributes.set("color", "#00000055"); + } + } +}; + +void GeometryNodesLazyFunctionGraphBuilder::print_graph() +{ + UsedSocketVisualizeOptions options{*this}; + std::cout << "\n\n" << lf_graph_->to_dot(options) << "\n\n"; +} + const GeometryNodesLazyFunctionGraphInfo *ensure_geometry_nodes_lazy_function_graph( const bNodeTree &btree) { diff --git a/source/blender/nodes/intern/geometry_nodes_log.cc b/source/blender/nodes/intern/geometry_nodes_log.cc index 660f878c1f7..66ccab2f77f 100644 --- a/source/blender/nodes/intern/geometry_nodes_log.cc +++ b/source/blender/nodes/intern/geometry_nodes_log.cc @@ -70,7 +70,7 @@ GeometryInfoLog::GeometryInfoLog(const GeometrySet &geometry_set) [&](const bke::AttributeIDRef &attribute_id, const bke::AttributeMetaData &meta_data, const GeometryComponent & /*component*/) { - if (attribute_id.is_named() && names.add(attribute_id.name())) { + if (!attribute_id.is_anonymous() && names.add(attribute_id.name())) { this->attributes.append({attribute_id.name(), meta_data.domain, meta_data.data_type}); } }); diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc index 868b3b2c539..c338ecacbc9 100644 --- a/source/blender/nodes/intern/node_geometry_exec.cc +++ b/source/blender/nodes/intern/node_geometry_exec.cc @@ -9,10 +9,33 @@ #include "NOD_geometry_exec.hh" +#include "BLI_hash_md5.h" + #include "node_geometry_util.hh" namespace blender::nodes { +NodeAnonymousAttributeID::NodeAnonymousAttributeID(const Object &object, + const ComputeContext &compute_context, + const bNode &bnode, + const StringRef identifier) +{ + const ComputeContextHash &hash = compute_context.hash(); + { + std::stringstream ss; + ss << hash << "_" << object.id.name << "_" << bnode.identifier << "_" << identifier; + long_name_ = ss.str(); + } + { + uint64_t hash_result[2]; + BLI_hash_md5_buffer(long_name_.data(), long_name_.size(), hash_result); + std::stringstream ss; + ss << ".a_" << std::hex << hash_result[0] << hash_result[1]; + name_ = ss.str(); + BLI_assert(name_.size() < MAX_CUSTOMDATA_LAYER_NAME); + } +} + void GeoNodeExecParams::error_message_add(const NodeWarningType type, const StringRef message) const { From a318f3b8d6873ddce8e40e554aae886172f5a3c7 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 5 Jan 2023 14:07:00 +0100 Subject: [PATCH 0427/1522] install_deps: Add py binding for OCIO, OIIO, OpenVDB and USD. This was quite a fight, some resulting notes: * We cannot use anymore Boost packages because of a weird bug breaking Blender debug builds and ivolving Boost, TBB and USD (see also rB019b930d6b9c). * OCIO, OIIO, OpenVDB and USD build options where updated to match these from cmake libs building. ** Most notably, USD now has imaging, OIIO, OpenVDB and GL support. Ref. T99618. --- build_files/build_environment/install_deps.sh | 143 ++++++++++++++---- 1 file changed, 117 insertions(+), 26 deletions(-) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 81e9b0f371c..72ae675273c 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -402,6 +402,7 @@ PYTHON_VERSION_INSTALLED=$PYTHON_VERSION_SHORT PYTHON_FORCE_BUILD=false PYTHON_FORCE_REBUILD=false PYTHON_SKIP=false +_with_built_python=false # Additional Python modules. PYTHON_IDNA_VERSION="3.3" @@ -466,7 +467,9 @@ BOOST_VERSION="1.80.0" BOOST_VERSION_SHORT="1.80" BOOST_VERSION_MIN="1.49" BOOST_VERSION_MEX="2.0" -BOOST_FORCE_BUILD=false +# XXX Boost currently has an issue with python/tbb, see rB019b930 for details and patch used to fix it. +# So for now it has to be built, system packages are not usable. :( +BOOST_FORCE_BUILD=true BOOST_FORCE_REBUILD=false BOOST_SKIP=false @@ -1108,7 +1111,9 @@ PYTHON_SOURCE=( "https://www.python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHO _boost_version_nodots=`echo "$BOOST_VERSION" | sed -r 's/\./_/g'` BOOST_SOURCE=( "https://boostorg.jfrog.io/artifactory/main/release/$BOOST_VERSION/source/boost_$_boost_version_nodots.tar.bz2" ) -BOOST_BUILD_MODULES="--with-system --with-filesystem --with-thread --with-regex --with-locale --with-date_time --with-wave --with-iostreams --with-python --with-program_options --with-serialization --with-atomic" +BOOST_BUILD_MODULES="--with-filesystem --with-locale --with-thread --with-regex --with-system --with-date_time --with-wave --with-atomic --with-serialization --with-program_options --with-iostreams --with-python" +# Used by debian distros. +BOOST_DEB_PACKAGE_MODULES=( "libboost-filesystem" "libboost-locale" "libboost-thread" "libboost-regex" "libboost-system" "libboost-date-time" "libboost-wave" "libboost-atomic" "libboost-serialization" "libboost-program-options" "libboost-iostreams" "libboost-python" "libboost-numpy" ) TBB_SOURCE=( "https://github.com/oneapi-src/oneTBB/archive/$TBB_VERSION$TBB_VERSION_UPDATE.tar.gz" ) TBB_SOURCE_CMAKE=( "https://raw.githubusercontent.com/wjakob/tbb/master/CMakeLists.txt" ) @@ -1217,7 +1222,7 @@ Those libraries should be available as packages in all recent distributions (opt * libjpeg, libpng, libtiff, [openjpeg2], [libopenal]. * libx11, libxcursor, libxi, libxrandr, libxinerama (and other libx... as needed). * libwayland-client0, libdecor, libwayland-cursor0, libwayland-egl1, libxkbcommon0, libdbus-1-3, libegl1 (Wayland) - * libsqlite3, libzstd, libbz2, libssl, libfftw3, libxml2, libtinyxml, yasm, libyaml-cpp, flex. + * libsqlite3, libzstd, libbz2, libssl, libfftw3, libxml2, libtinyxml, yasm, libyaml-cpp, flex, pybind11. * libsdl2, libepoxy, libpugixml, libpotrace, [libgmp], fontconfig, [libharu/libhpdf].\"" DEPS_SPECIFIC_INFO="\"BUILDABLE DEPENDENCIES: @@ -1479,9 +1484,17 @@ _init_python() { _update_deps_python() { if [ "$1" = true ]; then BOOST_FORCE_BUILD=true + OCIO_FORCE_BUILD=true + OIIO_FORCE_BUILD=true + OPENVDB_FORCE_BUILD=true + USD_FORCE_BUILD=true fi if [ "$2" = true ]; then BOOST_FORCE_REBUILD=true + OCIO_FORCE_REBUILD=true + OIIO_FORCE_REBUILD=true + OPENVDB_FORCE_REBUILD=true + USD_FORCE_REBUILD=true fi } @@ -1567,6 +1580,9 @@ compile_Python() { PRINT "" $_python -m pip install $module --no-binary :all: done + + _with_built_python=true + _with_built_python_execpath="$INST/python-$PYTHON_VERSION_SHORT/bin/python3" } # ---------------------------------------------------------------------------- @@ -1585,12 +1601,14 @@ _update_deps_boost() { OSL_FORCE_BUILD=true OPENVDB_FORCE_BUILD=true ALEMBIC_FORCE_BUILD=true + USD_FORCE_BUILD=true fi if [ "$2" = true ]; then OIIO_FORCE_REBUILD=true OSL_FORCE_REBUILD=true OPENVDB_FORCE_REBUILD=true ALEMBIC_FORCE_REBUILD=true + USD_FORCE_REBUILD=true fi } @@ -1610,7 +1628,7 @@ compile_Boost() { fi # To be changed each time we make edits that would modify the compiled result! - boost_magic=14 + boost_magic=15 _init_boost @@ -1636,11 +1654,13 @@ compile_Boost() { mkdir -p $SRC download BOOST_SOURCE[@] $_src.tar.bz2 tar -C $SRC --transform "s,\w*,boost-$BOOST_VERSION,x" -xf $_src.tar.bz2 + + patch -d $_src -p1 < $SCRIPT_DIR/patches/boost.diff fi cd $_src if [ ! -f $_src/b2 ]; then - if [ -d $INST/python-$PYTHON_VERSION_INSTALLED ]; then + if [ -d $_with_built_python ]; then ./bootstrap.sh --with-python-root="$INST/python-$PYTHON_VERSION_INSTALLED" else ./bootstrap.sh @@ -1835,7 +1855,7 @@ compile_OCIO() { fi # To be changed each time we make edits that would modify the compiled result! - ocio_magic=3 + ocio_magic=5 _init_ocio # Force having own builds for the dependencies. @@ -1890,9 +1910,13 @@ compile_OCIO() { cmake_d="$cmake_d -D CMAKE_PREFIX_PATH=$_inst" cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst" cmake_d="$cmake_d -D OCIO_BUILD_APPS=OFF" - cmake_d="$cmake_d -D OCIO_BUILD_PYTHON=OFF" + cmake_d="$cmake_d -D OCIO_BUILD_PYTHON=ON" cmake_d="$cmake_d -D OCIO_BUILD_GPU_TESTS=OFF" + if [ "$_with_built_python" = true ]; then + cmake_d="$cmake_d -D Python_EXECUTABLE=$_with_built_python_execpath" + fi + if [ $(uname -m) == "aarch64" ]; then cmake_d="$cmake_d -D OCIO_USE_SSE=OFF" fi @@ -2082,11 +2106,13 @@ _update_deps_openexr() { OIIO_FORCE_BUILD=true OPENVDB_FORCE_BUILD=true ALEMBIC_FORCE_BUILD=true + USD_FORCE_BUILD=true fi if [ "$2" = true ]; then OIIO_FORCE_REBUILD=true OPENVDB_FORCE_REBUILD=true ALEMBIC_FORCE_REBUILD=true + USD_FORCE_REBUILD=true fi } @@ -2215,9 +2241,11 @@ _init_oiio() { _update_deps_oiio() { if [ "$1" = true ]; then OSL_FORCE_BUILD=true + USD_FORCE_BUILD=true fi if [ "$2" = true ]; then OSL_FORCE_REBUILD=true + USD_FORCE_REBUILD=true fi } @@ -2237,7 +2265,7 @@ compile_OIIO() { fi # To be changed each time we make edits that would modify the compiled result! - oiio_magic=19 + oiio_magic=20 _init_oiio # Force having own builds for the dependencies. @@ -2291,6 +2319,7 @@ compile_OIIO() { cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst" cmake_d="$cmake_d -D STOP_ON_WARNING=OFF" cmake_d="$cmake_d -D LINKSTATIC=OFF" + cmake_d="$cmake_d -D BUILD_SHARED_LIBS=ON" if [ $(uname -m) != "aarch64" ]; then cmake_d="$cmake_d -D USE_SIMD=sse2" @@ -2306,21 +2335,37 @@ compile_OIIO() { cmake_d="$cmake_d -D OpenEXR_ROOT=$INST/openexr" fi - # ptex is only needed when nicholas bishop is ready - cmake_d="$cmake_d -D USE_PTEX=OFF" + cmake_d="$cmake_d -D USE_PYTHON=ON" + if [ "$_with_built_python" = true ]; then + cmake_d="$cmake_d -D Python_EXECUTABLE=$_with_built_python_execpath" + fi # Optional tests and cmd tools cmake_d="$cmake_d -D USE_QT=OFF" - cmake_d="$cmake_d -D USE_PYTHON=OFF" + cmake_d="$cmake_d -D USE_QT5=OFF" + cmake_d="$cmake_d -D USE_OPENGL=OFF" + cmake_d="$cmake_d -D USE_TBB=OFF" + cmake_d="$cmake_d -D USE_BZIP2=OFF" + cmake_d="$cmake_d -D USE_FREETYPE=OFF" + cmake_d="$cmake_d -D USE_OPENCOLORIO=OFF" + + cmake_d="$cmake_d -D USE_WEBP=ON" + cmake_d="$cmake_d -D USE_OPENJPEG=ON" + cmake_d="$cmake_d -D USE_FFMPEG=OFF" cmake_d="$cmake_d -D USE_OPENCV=OFF" cmake_d="$cmake_d -D USE_OPENVDB=OFF" + cmake_d="$cmake_d -D USE_NUKE=OFF" + cmake_d="$cmake_d -D USE_DCMTK=OFF" + cmake_d="$cmake_d -D USE_LIBHEIF=OFF" + cmake_d="$cmake_d -D USE_GIF=OFF" + cmake_d="$cmake_d -D USE_LIBRAW=OFF" + cmake_d="$cmake_d -D USE_LIBSQUISH=OFF" + cmake_d="$cmake_d -D BUILD_TESTING=OFF" cmake_d="$cmake_d -D OIIO_BUILD_TESTS=OFF" cmake_d="$cmake_d -D OIIO_BUILD_TOOLS=ON" cmake_d="$cmake_d -D TXT2MAN=" - #cmake_d="$cmake_d -D CMAKE_EXPORT_COMPILE_COMMANDS=ON" - #cmake_d="$cmake_d -D CMAKE_VERBOSE_MAKEFILE=ON" if [ -d $INST/boost ]; then cmake_d="$cmake_d -D BOOST_ROOT=$INST/boost -D Boost_NO_SYSTEM_PATHS=ON -D Boost_NO_BOOST_CMAKE=ON" @@ -2878,7 +2923,12 @@ _init_openvdb() { } _update_deps_openvdb() { - : + if [ "$1" = true ]; then + USD_FORCE_BUILD=true + fi + if [ "$2" = true ]; then + USD_FORCE_REBUILD=true + fi } clean_OPENVDB() { @@ -2900,7 +2950,7 @@ compile_OPENVDB() { PRINT "" # To be changed each time we make edits that would modify the compiled result! - openvdb_magic=4 + openvdb_magic=5 _init_openvdb # Force having own builds for the dependencies. @@ -2949,12 +2999,18 @@ compile_OPENVDB() { cmake_d="-D CMAKE_BUILD_TYPE=Release" cmake_d="$cmake_d -D CMAKE_INSTALL_PREFIX=$_inst" cmake_d="$cmake_d -D USE_STATIC_DEPENDENCIES=OFF" + cmake_d="$cmake_d -D OPENVDB_CORE_SHARED=ON" + cmake_d="$cmake_d -D OPENVDB_CORE_STATIC=OFF" cmake_d="$cmake_d -D OPENVDB_BUILD_BINARIES=OFF" if [ "$WITH_NANOVDB" = true ]; then cmake_d="$cmake_d -D USE_NANOVDB=ON" + cmake_d="$cmake_d -D OPENVDB_BUILD_NANOVDB=ON" + cmake_d="$cmake_d -D NANOVDB_BUILD_TOOLS=OFF" else cmake_d="$cmake_d -D USE_NANOVDB=OFF" + cmake_d="$cmake_d -D OPENVDB_BUILD_NANOVDB=OFF" + cmake_d="$cmake_d -D NANOVDB_BUILD_TOOLS=OFF" fi if [ -d $INST/boost ]; then @@ -2982,6 +3038,13 @@ compile_OPENVDB() { cmake_d="$cmake_d -D Blosc_ROOT=$INST/blosc" fi + cmake_d="$cmake_d -D OPENVDB_BUILD_PYTHON_MODULE=ON" + cmake_d="$cmake_d -D OPENVDB_PYTHON_WRAP_ALL_GRID_TYPES=ON" + cmake_d="$cmake_d -D USE_NUMPY=ON" + if [ "$_with_built_python" = true ]; then + cmake_d="$cmake_d -D Python_EXECUTABLE=$_with_built_python_execpath" + fi + cmake $cmake_d .. make -j$THREADS install @@ -3147,7 +3210,7 @@ compile_USD() { fi # To be changed each time we make edits that would modify the compiled result! - usd_magic=1 + usd_magic=2 _init_usd # Force having own builds for the dependencies. @@ -3181,18 +3244,46 @@ compile_USD() { cmake_d="-D CMAKE_INSTALL_PREFIX=$_inst" # For the reasoning behind these options, please see usd.cmake. if [ -d $INST/boost ]; then - cmake_d="$cmake_d $cmake_d -D BOOST_ROOT=$INST/boost" + cmake_d="$cmake_d -DBOOST_ROOT=$INST/boost" fi if [ -d $INST/tbb ]; then - cmake_d="$cmake_d $cmake_d -D TBB_ROOT_DIR=$INST/tbb" + cmake_d="$cmake_d -DTBB_ROOT_DIR=$INST/tbb" fi - cmake_d="$cmake_d -DPXR_ENABLE_PYTHON_SUPPORT=OFF" - cmake_d="$cmake_d -DPXR_BUILD_IMAGING=OFF" + + cmake_d="$cmake_d -DPXR_ENABLE_PYTHON_SUPPORT=ON" + cmake_d="$cmake_d -DPXR_USE_PYTHON_3=ON" + if [ "$_with_built_python" = true ]; then + cmake_d="$cmake_d -D PYTHON_EXECUTABLE=$_with_built_python_execpath" + fi + + cmake_d="$cmake_d -DPXR_BUILD_IMAGING=ON" + cmake_d="$cmake_d -DPXR_BUILD_OPENIMAGEIO_PLUGIN=ON" + if [ -d $INST/openexr ]; then + cmake_d="$cmake_d -DOPENEXR_LOCATION=$INST/openexr" + fi + if [ -d $INST/oiio ]; then + cmake_d="$cmake_d -DOpenImageIO_ROOT=$INST/oiio" + fi + + cmake_d="$cmake_d -DPXR_ENABLE_OPENVDB_SUPPORT=ON" + if [ -d $INST/openvdb ]; then + cmake_d="$cmake_d -DOPENVDB_LOCATION=$INST/openvdb" + fi + + cmake_d="$cmake_d -DPXR_ENABLE_GL_SUPPORT=ON" + cmake_d="$cmake_d -DPXR_BUILD_TESTS=OFF" - cmake_d="$cmake_d -DBUILD_SHARED_LIBS=ON" - cmake_d="$cmake_d -DPXR_BUILD_MONOLITHIC=ON" + cmake_d="$cmake_d -DPXR_BUILD_EXAMPLES=OFF" + cmake_d="$cmake_d -DPXR_BUILD_TUTORIALS=OFF" + cmake_d="$cmake_d -DPXR_BUILD_USD_TOOLS=OFF" + cmake_d="$cmake_d -DPXR_ENABLE_HDF5_SUPPORT=OFF" + cmake_d="$cmake_d -DPXR_ENABLE_MATERIALX_SUPPORT=OFF" + cmake_d="$cmake_d -DPXR_BUILD_USDVIEW=OFF" + + cmake_d="$cmake_d -DPXR_BUILD_MONOLITHIC=ON" + cmake_d="$cmake_d -DBUILD_SHARED_LIBS=ON" cmake_d="$cmake_d -DCMAKE_DEBUG_POSTFIX=_d" cmake $cmake_d ./ @@ -4206,7 +4297,7 @@ install_DEB() { libxcursor-dev libxi-dev wget libsqlite3-dev libxrandr-dev libxinerama-dev \ libwayland-dev libdecor-0-dev wayland-protocols libegl-dev libxkbcommon-dev libdbus-1-dev linux-libc-dev \ libbz2-dev libncurses5-dev libssl-dev liblzma-dev libreadline-dev \ - libopenal-dev libepoxy-dev yasm \ + libopenal-dev libepoxy-dev yasm pybind11-dev \ libsdl2-dev libfftw3-dev patch bzip2 libxml2-dev libtinyxml-dev libjemalloc-dev \ libgmp-dev libpugixml-dev libpotrace-dev libhpdf-dev libzstd-dev libpystring-dev \ libglfw3-dev" @@ -4393,7 +4484,7 @@ install_DEB() { boost_version=$(echo `get_package_version_DEB libboost-dev` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/') - install_packages_DEB libboost-{filesystem,iostreams,locale,regex,system,thread,wave,program-options}$boost_version-dev + install_packages_DEB ${BOOST_DEB_PACKAGE_MODULES[@]/%/$boost_version-dev} clean_Boost else compile_Boost @@ -4929,7 +5020,7 @@ install_RPM() { libX11-devel libXi-devel libXcursor-devel libXrandr-devel libXinerama-devel \ wayland-devel libdecor-devel wayland-protocols-devel mesa-libEGL-devel libxkbcommon-devel dbus-devel kernel-headers \ wget ncurses-devel readline-devel $OPENJPEG_DEV openal-soft-devel \ - libepoxy-devel yasm patch \ + libepoxy-devel yasm patch pybind11-devel \ libxml2-devel yaml-cpp-devel tinyxml-devel jemalloc-devel \ gmp-devel pugixml-devel potrace-devel libharu-devel libzstd-devel pystring-devel" @@ -5582,7 +5673,7 @@ install_ARCH() { _packages="$BASE_DEVEL git cmake fontconfig flex \ libxi libxcursor libxrandr libxinerama libepoxy libdecor libpng libtiff wget openal \ - $OPENJPEG_DEV yasm sdl2 fftw \ + $OPENJPEG_DEV yasm sdl2 fftw pybind11 \ libxml2 yaml-cpp tinyxml python-requests jemalloc gmp potrace pugixml libharu \ zstd pystring" From 862d08bb975740e3abf3a9a4dfbdcd48275d944c Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 5 Jan 2023 14:38:14 +0100 Subject: [PATCH 0428/1522] Fix: use-after-free when threadlocal is destructed after static variable This issue was introduced in rB78f28b55d39288926634d0cc. The fix is to use a `std::shared_ptr` to ensure that the `Global` will live long enough until all `Local` objects are destructed. --- intern/guardedalloc/intern/memory_usage.cc | 39 +++++++++++++++------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/intern/guardedalloc/intern/memory_usage.cc b/intern/guardedalloc/intern/memory_usage.cc index 71987ac38d9..bb557eeda97 100644 --- a/intern/guardedalloc/intern/memory_usage.cc +++ b/intern/guardedalloc/intern/memory_usage.cc @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -14,10 +15,18 @@ namespace { +struct Local; +struct Global; + /** * This is stored per thread. Align to cache line size to avoid false sharing. */ struct alignas(64) Local { + /** + * Retain shared ownership of #Global to make sure that it is not destructed. + */ + std::shared_ptr global; + /** Helps to find bugs during program shutdown. */ bool destructed = false; /** @@ -49,7 +58,8 @@ struct alignas(64) Local { }; /** - * This is a singleton that stores global data. + * This is a singleton that stores global data. It's owned by a `std::shared_ptr` which is owned by + * the static variable in #get_global_ptr and all #Local objects. */ struct Global { /** @@ -98,10 +108,15 @@ static std::atomic use_local_counters = true; */ static constexpr int64_t peak_update_threshold = 1024 * 1024; +static std::shared_ptr &get_global_ptr() +{ + static std::shared_ptr global = std::make_shared(); + return global; +} + static Global &get_global() { - static Global global; - return global; + return *get_global_ptr(); } static Local &get_local_data() @@ -113,28 +128,28 @@ static Local &get_local_data() Local::Local() { - Global &global = get_global(); - std::lock_guard lock{global.locals_mutex}; + this->global = get_global_ptr(); - if (global.locals.empty()) { + std::lock_guard lock{this->global->locals_mutex}; + if (this->global->locals.empty()) { /* This is the first thread creating #Local, it is therefore the main thread because it's * created through #memory_usage_init. */ this->is_main = true; } /* Register self in the global list. */ - global.locals.push_back(this); + this->global->locals.push_back(this); } Local::~Local() { - Global &global = get_global(); - std::lock_guard lock{global.locals_mutex}; + std::lock_guard lock{this->global->locals_mutex}; /* Unregister self from the global list. */ - global.locals.erase(std::find(global.locals.begin(), global.locals.end(), this)); + this->global->locals.erase( + std::find(this->global->locals.begin(), this->global->locals.end(), this)); /* Don't forget the memory counts stored locally. */ - global.blocks_num_outside_locals.fetch_add(this->blocks_num, std::memory_order_relaxed); - global.mem_in_use_outside_locals.fetch_add(this->mem_in_use, std::memory_order_relaxed); + this->global->blocks_num_outside_locals.fetch_add(this->blocks_num, std::memory_order_relaxed); + this->global->mem_in_use_outside_locals.fetch_add(this->mem_in_use, std::memory_order_relaxed); if (this->is_main) { /* The main thread started shutting down. Use global counters from now on to avoid accessing From 25e28f518c1892ae486435d7acfe598a53306ae4 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 5 Jan 2023 14:49:04 +0100 Subject: [PATCH 0429/1522] install_deps: Add package handling for fribidi, harfbuzz, shaderc and vulkan ICD loader. All these are available on recent distros, don't think it's worth adding support to build them for the time being. Ref. T99618. --- build_files/build_environment/install_deps.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 72ae675273c..8ed4b5b7c51 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -1223,7 +1223,9 @@ Those libraries should be available as packages in all recent distributions (opt * libx11, libxcursor, libxi, libxrandr, libxinerama (and other libx... as needed). * libwayland-client0, libdecor, libwayland-cursor0, libwayland-egl1, libxkbcommon0, libdbus-1-3, libegl1 (Wayland) * libsqlite3, libzstd, libbz2, libssl, libfftw3, libxml2, libtinyxml, yasm, libyaml-cpp, flex, pybind11. - * libsdl2, libepoxy, libpugixml, libpotrace, [libgmp], fontconfig, [libharu/libhpdf].\"" + * libsdl2, libepoxy, libpugixml, libpotrace, [libgmp], fontconfig, [libharu/libhpdf]. + * [libvulkan/vulkan-loader]. + * [libfribidi], [libharfbuzz].\"" DEPS_SPECIFIC_INFO="\"BUILDABLE DEPENDENCIES: @@ -4296,11 +4298,12 @@ install_DEB() { git libfreetype6-dev libfontconfig-dev libx11-dev flex bison libxxf86vm-dev \ libxcursor-dev libxi-dev wget libsqlite3-dev libxrandr-dev libxinerama-dev \ libwayland-dev libdecor-0-dev wayland-protocols libegl-dev libxkbcommon-dev libdbus-1-dev linux-libc-dev \ + libvulkan-dev libshaderc-dev \ libbz2-dev libncurses5-dev libssl-dev liblzma-dev libreadline-dev \ libopenal-dev libepoxy-dev yasm pybind11-dev \ libsdl2-dev libfftw3-dev patch bzip2 libxml2-dev libtinyxml-dev libjemalloc-dev \ libgmp-dev libpugixml-dev libpotrace-dev libhpdf-dev libzstd-dev libpystring-dev \ - libglfw3-dev" + libglfw3-dev libfribidi-dev libharfbuzz-dev" VORBIS_USE=true OGG_USE=true @@ -5019,10 +5022,12 @@ install_RPM() { libtiff-devel libjpeg-devel libpng-devel sqlite-devel fftw-devel SDL2-devel \ libX11-devel libXi-devel libXcursor-devel libXrandr-devel libXinerama-devel \ wayland-devel libdecor-devel wayland-protocols-devel mesa-libEGL-devel libxkbcommon-devel dbus-devel kernel-headers \ + vulkan-loader-devel libshaderc-devel \ wget ncurses-devel readline-devel $OPENJPEG_DEV openal-soft-devel \ libepoxy-devel yasm patch pybind11-devel \ libxml2-devel yaml-cpp-devel tinyxml-devel jemalloc-devel \ - gmp-devel pugixml-devel potrace-devel libharu-devel libzstd-devel pystring-devel" + gmp-devel pugixml-devel potrace-devel libharu-devel libzstd-devel pystring-devel \ + fribidi-devel harfbuzz-devel" OPENJPEG_USE=true VORBIS_USE=true @@ -5673,9 +5678,10 @@ install_ARCH() { _packages="$BASE_DEVEL git cmake fontconfig flex \ libxi libxcursor libxrandr libxinerama libepoxy libdecor libpng libtiff wget openal \ + vulkan-icd-loader vulkan-headers shaderc \ $OPENJPEG_DEV yasm sdl2 fftw pybind11 \ libxml2 yaml-cpp tinyxml python-requests jemalloc gmp potrace pugixml libharu \ - zstd pystring" + zstd pystring fribidi harfbuzz" OPENJPEG_USE=true VORBIS_USE=true From 3819a9b15a1936753cc50e4535d27aebe81ae568 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 5 Jan 2023 15:36:24 +0100 Subject: [PATCH 0430/1522] Fix T103614: crash during geometry nodes evaluation with tbb disabled --- .../functions/intern/lazy_function_graph_executor.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/functions/intern/lazy_function_graph_executor.cc b/source/blender/functions/intern/lazy_function_graph_executor.cc index fc74b3cd213..ab7dfba196a 100644 --- a/source/blender/functions/intern/lazy_function_graph_executor.cc +++ b/source/blender/functions/intern/lazy_function_graph_executor.cc @@ -1073,6 +1073,12 @@ class Executor { bool try_enable_multi_threading() { +#ifndef WITH_TBB + /* The non-tbb task pool has the property that it immediately executes tasks under some + * circumstances. This is not supported here because tasks might be scheduled while another + * node is in the middle of being executed on the same thread. */ + return false; +#endif if (this->use_multi_threading()) { return true; } From a5d4c63e867ee18728d061456a81f8a277deef03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ale=C5=A1=20Jelov=C4=8Dan?= Date: Thu, 5 Jan 2023 15:49:25 +0100 Subject: [PATCH 0431/1522] GPencil: remove multiframe copy/paste restriction Multiframe copy paste operations were prohibited by a block of code. While this is understandable as it prevents confusing actions, there is a good use case to allow multiframe copy pasting. This patch does: - remove restricting block of code - adds outer loops for frames both in copy and paste actions. In copy action it will create an array of selected strokes from all selected frames In paste action it will create new from previous copy action merged to a single frame. It will paste to all selected frames and create new frame if autokey is on and time cursor is not on any of the keyframes. The main usecase is for creating motion smears as in examples attached. The user still need to do some actions in order to achieve desired look, such as stroke ordering and deleting excessive strokes. {F14069747} {F14069743} Reviewed By: antoniov, mendio Differential Revision: https://developer.blender.org/D16805 --- source/blender/editors/gpencil/gpencil_edit.c | 126 +++++++++++------- 1 file changed, 77 insertions(+), 49 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index aeed43a34bd..4f27c28a840 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -916,11 +916,6 @@ static int gpencil_duplicate_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) { - BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition"); - return OPERATOR_CANCELLED; - } - bool changed = false; if (is_curve_edit) { BKE_report(op->reports, RPT_ERROR, "Not implemented!"); @@ -1483,17 +1478,13 @@ static int gpencil_strokes_copy_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); bGPdata *gpd = ED_gpencil_data_get_active(C); const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd); + const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); if (gpd == NULL) { BKE_report(op->reports, RPT_ERROR, "No Grease Pencil data"); return OPERATOR_CANCELLED; } - if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) { - BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition"); - return OPERATOR_CANCELLED; - } - /* clear the buffer first */ ED_gpencil_strokes_copybuf_free(); @@ -1508,45 +1499,51 @@ static int gpencil_strokes_copy_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { bGPDframe *gpf = gpl->actframe; bGPDstroke *gps; + bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; - if (gpf == NULL) { - continue; - } + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) { + if (gpf == NULL) { + continue; + } - /* make copies of selected strokes, and deselect these once we're done */ - for (gps = gpf->strokes.first; gps; gps = gps->next) { - /* skip strokes that are invalid for current view */ - if (ED_gpencil_stroke_can_use(C, gps) == false) { - continue; - } - - if (gps->flag & GP_STROKE_SELECT) { - if (gps->totpoints == 1) { - /* Special Case: If there's just a single point in this stroke... */ - bGPDstroke *gpsd; - - /* make direct copies of the stroke and its points */ - gpsd = BKE_gpencil_stroke_duplicate(gps, false, true); - - /* saves original layer name */ - BLI_strncpy( - gpsd->runtime.tmp_layerinfo, gpl->info, sizeof(gpsd->runtime.tmp_layerinfo)); - gpsd->points = MEM_dupallocN(gps->points); - if (gps->dvert != NULL) { - gpsd->dvert = MEM_dupallocN(gps->dvert); - BKE_gpencil_stroke_weights_duplicate(gps, gpsd); + /* make copies of selected strokes, and deselect these once we're done */ + for (gps = gpf->strokes.first; gps; gps = gps->next) { + /* skip strokes that are invalid for current view */ + if (ED_gpencil_stroke_can_use(C, gps) == false) { + continue; } - /* Calc geometry data. */ - BKE_gpencil_stroke_geometry_update(gpd, gpsd); + if (gps->flag & GP_STROKE_SELECT) { + if (gps->totpoints == 1) { + /* Special Case: If there's just a single point in this stroke... */ + bGPDstroke *gpsd; - /* add to temp buffer */ - gpsd->next = gpsd->prev = NULL; - BLI_addtail(&gpencil_strokes_copypastebuf, gpsd); - } - else { - /* delegate to a helper, as there's too much to fit in here (for copying subsets)... */ - gpencil_duplicate_points(gpd, gps, &gpencil_strokes_copypastebuf, gpl->info); + /* make direct copies of the stroke and its points */ + gpsd = BKE_gpencil_stroke_duplicate(gps, false, true); + + /* saves original layer name */ + BLI_strncpy( + gpsd->runtime.tmp_layerinfo, gpl->info, sizeof(gpsd->runtime.tmp_layerinfo)); + gpsd->points = MEM_dupallocN(gps->points); + if (gps->dvert != NULL) { + gpsd->dvert = MEM_dupallocN(gps->dvert); + BKE_gpencil_stroke_weights_duplicate(gps, gpsd); + } + + /* Calc geometry data. */ + BKE_gpencil_stroke_geometry_update(gpd, gpsd); + + /* add to temp buffer */ + gpsd->next = gpsd->prev = NULL; + BLI_addtail(&gpencil_strokes_copypastebuf, gpsd); + } + else { + /* delegate to a helper, as there's too much to fit in here (for copying + * subsets)... */ + gpencil_duplicate_points(gpd, gps, &gpencil_strokes_copypastebuf, gpl->info); + } + } } } } @@ -1631,19 +1628,19 @@ static int gpencil_strokes_paste_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); bGPdata *gpd = (bGPdata *)ob->data; const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd); + const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd); /* only use active for copy merge */ Scene *scene = CTX_data_scene(C); - bGPDframe *gpf; + + bGPDframe *gpf = gpl->actframe; + bGPDstroke *gps; + bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; eGP_PasteMode type = RNA_enum_get(op->ptr, "type"); const bool on_back = RNA_boolean_get(op->ptr, "paste_back"); GHash *new_colors; /* Check for various error conditions. */ - if (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)) { - BKE_report(op->reports, RPT_ERROR, "Operator not supported in multiframe edition"); - return OPERATOR_CANCELLED; - } if (BLI_listbase_is_empty(&gpencil_strokes_copypastebuf)) { BKE_report(op->reports, @@ -1702,6 +1699,7 @@ static int gpencil_strokes_paste_exec(bContext *C, wmOperator *op) /* Copy over the strokes from the buffer (and adjust the colors) */ bGPDstroke *gps_init = (!on_back) ? gpencil_strokes_copypastebuf.first : gpencil_strokes_copypastebuf.last; + for (bGPDstroke *gps = gps_init; gps; gps = (!on_back) ? gps->next : gps->prev) { if (ED_gpencil_stroke_can_use(C, gps)) { /* Need to verify if layer exists */ @@ -1719,6 +1717,36 @@ static int gpencil_strokes_paste_exec(bContext *C, wmOperator *op) * we reuse active frame or add a new frame if one * doesn't exist already depending on REC button status. */ + + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + if (gpf->flag & GP_FRAME_SELECT) { + if (gpf) { + /* Create new stroke */ + bGPDstroke *new_stroke = BKE_gpencil_stroke_duplicate(gps, true, true); + new_stroke->runtime.tmp_layerinfo[0] = '\0'; + new_stroke->next = new_stroke->prev = NULL; + + /* Calc geometry data. */ + BKE_gpencil_stroke_geometry_update(gpd, new_stroke); + + if (on_back) { + BLI_addhead(&gpf->strokes, new_stroke); + } + else { + BLI_addtail(&gpf->strokes, new_stroke); + } + + /* Remap material */ + Material *ma = BLI_ghash_lookup(new_colors, POINTER_FROM_INT(new_stroke->mat_nr)); + new_stroke->mat_nr = BKE_gpencil_object_material_index_get(ob, ma); + CLAMP_MIN(new_stroke->mat_nr, 0); + } + } + /* If not multi-edit, exit loop. */ + if (!is_multiedit) { + break; + } + } if (IS_AUTOKEY_ON(scene) || (gpl->actframe == NULL)) { gpf = BKE_gpencil_layer_frame_get(gpl, scene->r.cfra, GP_GETFRAME_ADD_NEW); } From 2a5104e368d5d2ca91f9ee3b8c001fb7b648ed60 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Thu, 5 Jan 2023 15:59:51 +0100 Subject: [PATCH 0432/1522] Cleanup: Remove compiler warnings --- source/blender/editors/gpencil/gpencil_edit.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index 4f27c28a840..b3f7a553a88 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -1497,8 +1497,6 @@ static int gpencil_strokes_copy_exec(bContext *C, wmOperator *op) * once all done */ CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) { - bGPDframe *gpf = gpl->actframe; - bGPDstroke *gps; bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { @@ -1508,7 +1506,7 @@ static int gpencil_strokes_copy_exec(bContext *C, wmOperator *op) } /* make copies of selected strokes, and deselect these once we're done */ - for (gps = gpf->strokes.first; gps; gps = gps->next) { + for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { /* skip strokes that are invalid for current view */ if (ED_gpencil_stroke_can_use(C, gps) == false) { continue; @@ -1633,7 +1631,6 @@ static int gpencil_strokes_paste_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); bGPDframe *gpf = gpl->actframe; - bGPDstroke *gps; bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; eGP_PasteMode type = RNA_enum_get(op->ptr, "type"); From d1810d11f425345f455385312c61594f425e257a Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 23 Dec 2022 16:08:25 +0100 Subject: [PATCH 0433/1522] Fix T103303: Dbl-click in the Graph Editor wont select all keyframes This was the case when an Annotation is also present as in the report. Since {rB92d7f9ac56e0}, Dopesheet is aware of greaspencil/annotations (displays its channels/keyframes, can rename their data, layers, fcurve groupings etc.). However, the Graph Editor does not display these / should not be aware of them. Above commit already had issues that were addressed in the following commits (mostly adding the new `ANIMFILTER_FCURVESONLY` to places that dont handle greasepencil/annotations) - {rBfdf34666f00f} - {rB45f483681fef} - {rBa26038ff3851} Now in T103303 it was reported that doublicking a channel would not select all fcurve`s keyframes anymore and this wasnt actually an issue with that particular operator, but instead with another operator that is also mapped to doubleclicking: the channel renaming (I assume the keyconflict here is actually wanted behavior). Channel renaming would not return `OPERATOR_PASS_THROUGH` here anymore in the case nothing cannot be renamed, so we would not actually reach the 2nd operator at all (the one selecting all keyframes). Deeper reason for this is that the renaming operator would actually "see" a channel that could be renamed (in the case of the report: an annotation layer), but then cannot proceed, because the "real" underlying data where the doubleclick happens is an fcurve... So now exclude non-greasepencil channels in filtering as well where appropriate by also adding `ANIMFILTER_FCURVESONLY` to the filter there. Fixes T103303. Maniphest Tasks: T103303 Differential Revision: https://developer.blender.org/D16871 --- source/blender/editors/animation/anim_channels_edit.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index a83266c484e..c612ab10d65 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -2845,12 +2845,15 @@ static bool rename_anim_channels(bAnimContext *ac, int channel_index) int filter; bool success = false; - /* get the channel that was clicked on */ - /* filter channels */ + /* Filter relevant channels (note that greasepencil/annotations are not displayed in Graph + * Editor). */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); + if (ELEM(ac->datatype, ANIMCONT_FCURVES, ANIMCONT_NLA)) { + filter |= ANIMFILTER_FCURVESONLY; + } ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); - /* get channel from index */ + /* Get channel that was clicked on from index. */ ale = BLI_findlink(&anim_data, channel_index); if (ale == NULL) { /* channel not found */ From 74c4977aeaa30c554872b7f44dbdca6730160ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 5 Jan 2023 15:42:42 +0100 Subject: [PATCH 0434/1522] Pose Library: allow extrapolating the pose While blending, press E to enable extrapolation / overshoot of the pose. It will make it possible to blend in more than 100% of the pose asset. This has the potential to completely break the rig, but it can be useful to exaggerate poses when used with caution. --- source/blender/editors/armature/pose_lib_2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/armature/pose_lib_2.c b/source/blender/editors/armature/pose_lib_2.c index 1ea8bc275e9..a015e37aac6 100644 --- a/source/blender/editors/armature/pose_lib_2.c +++ b/source/blender/editors/armature/pose_lib_2.c @@ -192,7 +192,7 @@ static void poselib_blend_set_factor(PoseBlendData *pbd, const float new_factor) BKE_pose_backup_free(pbd->pose_backup); } - pbd->blend_factor = CLAMPIS(new_factor, -1.0f, 1.0f); + pbd->blend_factor = new_factor; pbd->needs_redraw = true; if (sign_changed) { @@ -351,7 +351,7 @@ static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent * pbd->slider = ED_slider_create(C); ED_slider_init(pbd->slider, event); ED_slider_factor_set(pbd->slider, pbd->blend_factor); - ED_slider_allow_overshoot_set(pbd->slider, false); + ED_slider_allow_overshoot_set(pbd->slider, true); ED_slider_is_bidirectional_set(pbd->slider, true); } From b099e9924e3232e5172bb7bbcf619b142e7a3f96 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 5 Jan 2023 17:08:12 +0100 Subject: [PATCH 0435/1522] install_deps: Add building of MaterialX. Ref. T99618 --- build_files/build_environment/install_deps.sh | 197 +++++++++++++++++- 1 file changed, 193 insertions(+), 4 deletions(-) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 8ed4b5b7c51..a0d0414fbb0 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -39,15 +39,15 @@ with-all,with-opencollada,with-jack,with-pulseaudio,with-embree,with-oidn,with-n ver-ocio:,ver-oiio:,ver-llvm:,ver-osl:,ver-osd:,ver-openvdb:,ver-xr-openxr:,ver-level-zero:\ force-all,force-python,force-boost,force-tbb,\ force-ocio,force-imath,force-openexr,force-oiio,force-llvm,force-osl,force-osd,force-openvdb,\ -force-ffmpeg,force-opencollada,force-alembic,force-embree,force-oidn,force-usd,\ +force-ffmpeg,force-opencollada,force-alembic,force-embree,force-oidn,force-materialx,force-usd,\ force-xr-openxr,force-level-zero,force-openpgl,\ build-all,build-python,build-boost,build-tbb,\ build-ocio,build-imath,build-openexr,build-oiio,build-llvm,build-osl,build-osd,build-openvdb,\ -build-ffmpeg,build-opencollada,build-alembic,build-embree,build-oidn,build-usd,\ +build-ffmpeg,build-opencollada,build-alembic,build-embree,build-oidn,build-materialx,build-usd,\ build-xr-openxr,build-level-zero,build-openpgl,\ skip-python,skip-boost,skip-tbb,\ skip-ocio,skip-imath,skip-openexr,skip-oiio,skip-llvm,skip-osl,skip-osd,skip-openvdb,\ -skip-ffmpeg,skip-opencollada,skip-alembic,skip-embree,skip-oidn,skip-usd,\ +skip-ffmpeg,skip-opencollada,skip-alembic,skip-embree,skip-oidn,skip-materialx,skip-usd,\ skip-xr-openxr,skip-level-zero,skip-openpgl \ -- "$@" \ ) @@ -223,6 +223,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS: --build-ffmpeg Force the build of FFMpeg. + --build-materialx + Force the build of MaterialX. + --build-usd Force the build of Universal Scene Description. @@ -296,6 +299,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS: --force-ffmpeg Force the rebuild of FFMpeg. + --force-materialx + Force the rebuild of MaterialX. + --force-usd Force the rebuild of Universal Scene Description. @@ -362,6 +368,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS: --skip-ffmpeg Unconditionally skip FFMpeg installation/building. + --skip-materialx + Unconditionally skip MaterialX installation/building. + --skip-usd Unconditionally skip Universal Scene Description installation/building. @@ -563,6 +572,14 @@ ALEMBIC_FORCE_BUILD=false ALEMBIC_FORCE_REBUILD=false ALEMBIC_SKIP=false +MATERIALX_VERSION="1.38.6" +MATERIALX_VERSION_SHORT="1.38" +MATERIALX_VERSION_MIN="1.38" +MATERIALX_VERSION_MEX="1.40" +MATERIALX_FORCE_BUILD=false +MATERIALX_FORCE_REBUILD=false +MATERIALX_SKIP=false + USD_VERSION="22.11" USD_VERSION_SHORT="22.11" USD_VERSION_MIN="20.05" @@ -899,6 +916,9 @@ while true; do --build-alembic) ALEMBIC_FORCE_BUILD=true; shift; continue ;; + --build-materialx) + MATERIALX_FORCE_BUILD=true; shift; continue + ;; --build-usd) USD_FORCE_BUILD=true; shift; continue ;; @@ -928,6 +948,7 @@ while true; do OIDN_FORCE_REBUILD=true FFMPEG_FORCE_REBUILD=true ALEMBIC_FORCE_REBUILD=true + MATERIALX_FORCE_REBUILD=true USD_FORCE_REBUILD=true XR_OPENXR_FORCE_REBUILD=true LEVEL_ZERO_FORCE_REBUILD=true @@ -983,6 +1004,9 @@ while true; do --force-alembic) ALEMBIC_FORCE_REBUILD=true; shift; continue ;; + --force-materialx) + MATERIALX_FORCE_REBUILD=true; shift; continue + ;; --force-usd) USD_FORCE_REBUILD=true; shift; continue ;; @@ -1046,6 +1070,9 @@ while true; do --skip-usd) USD_SKIP=true; shift; continue ;; + --skip-materialx) + MATERIALX_SKIP=true; shift; continue + ;; --skip-xr-openxr) XR_OPENXR_SKIP=true; shift; continue ;; @@ -1170,6 +1197,8 @@ ALEMBIC_SOURCE=( "https://github.com/alembic/alembic/archive/${ALEMBIC_VERSION}. # ALEMBIC_SOURCE_REPO_UID="e6c90d4faa32c4550adeaaf3f556dad4b73a92bb" # ALEMBIC_SOURCE_REPO_BRANCH="master" +MATERIALX_SOURCE=( "https://github.com/AcademySoftwareFoundation/MaterialX/archive/refs/tags/v${MATERIALX_VERSION}.tar.gz" ) + USD_SOURCE=( "https://github.com/PixarAnimationStudios/USD/archive/v${USD_VERSION}.tar.gz" ) OPENCOLLADA_USE_REPO=false @@ -3184,6 +3213,103 @@ compile_ALEMBIC() { run_ldconfig "alembic" } +#### Build materialX #### +_init_materialx() { + _src=$SRC/MaterialX-$MATERIALX_VERSION + _git=false + _inst=$INST/materialx-$MATERIALX_VERSION_SHORT + _inst_shortcut=$INST/materialx +} + +_update_deps_materialx() { + : +} + +clean_MATERIALX() { + _init_materialx + if [ -d $_inst ]; then + # Force rebuilding the dependencies if needed. + _update_deps_materialx false true + fi + _clean +} + +compile_MATERIALX() { + if [ "$NO_BUILD" = true ]; then + WARNING "--no-build enabled, MaterialX will not be compiled!" + return + fi + + # To be changed each time we make edits that would modify the compiled result! + materialx_magic=1 + _init_materialx + + # Force having own builds for the dependencies. + _update_deps_materialx true false + + # Clean install if needed! + magic_compile_check materialx-$MATERIALX_VERSION $materialx_magic + if [ $? -eq 1 -o "$MATERIALX_FORCE_REBUILD" = true ]; then + clean_MATERIALX + fi + + if [ ! -d $_inst ]; then + INFO "Building MaterialX-$MATERIALX_VERSION" + + # Force rebuilding the dependencies. + _update_deps_materialx true true + + prepare_inst + + if [ ! -d $_src ]; then + mkdir -p $SRC + download MATERIALX_SOURCE[@] "$_src.tar.gz" + + INFO "Unpacking MaterialX-$MATERIALX_VERSION" + tar -C $SRC -xf $_src.tar.gz + + patch -d $_src -p1 < $SCRIPT_DIR/patches/materialx.diff + fi + + cd $_src + + cmake_d="-D CMAKE_INSTALL_PREFIX=$_inst" + + cmake_d="$cmake_d -DMATERIALX_BUILD_SHARED_LIBS=ON" + cmake_d="$cmake_d -DCMAKE_DEBUG_POSTFIX=_d" + + cmake_d="$cmake_d -DMATERIALX_BUILD_RENDER=OFF" + + cmake_d="$cmake_d -DMATERIALX_BUILD_PYTHON=ON" + cmake_d="$cmake_d -DMATERIALX_INSTALL_PYTHON=OFF" + if [ "$_with_built_python" = true ]; then + cmake_d="$cmake_d -D Python_EXECUTABLE=$_with_built_python_execpath" + fi + + cmake $cmake_d ./ + make -j$THREADS install + make clean + + if [ ! -d $_inst ]; then + ERROR "MaterialX-$MATERIALX_VERSION failed to compile, exiting" + exit 1 + fi + + magic_compile_set materialx-$MATERIALX_VERSION $materialx_magic + + cd $CWD + INFO "Done compiling MaterialX-$MATERIALX_VERSION!" + else + INFO "Own MaterialX-$MATERIALX_VERSION is up to date, nothing to do!" + INFO "If you want to force rebuild of this lib, use the --force-materialx option." + fi + + if [ -d $_inst ]; then + _create_inst_shortcut + fi + run_ldconfig "materialx" +} + #### Build USD #### _init_usd() { _src=$SRC/USD-$USD_VERSION @@ -4679,6 +4805,16 @@ install_DEB() { compile_ALEMBIC fi + PRINT "" + if [ "$MATERIALX_SKIP" = true ]; then + WARNING "Skipping MaterialX installation, as requested..." + elif [ "$MATERIALX_FORCE_BUILD" = true ]; then + INFO "Forced MaterialX building, as requested..." + compile_MATERIALX + else + compile_MATERIALX + fi + PRINT "" if [ "$USD_SKIP" = true ]; then WARNING "Skipping USD installation, as requested..." @@ -5408,6 +5544,16 @@ install_RPM() { compile_ALEMBIC fi + PRINT "" + if [ "$MATERIALX_SKIP" = true ]; then + WARNING "Skipping MaterialX installation, as requested..." + elif [ "$MATERIALX_FORCE_BUILD" = true ]; then + INFO "Forced MaterialX building, as requested..." + compile_MATERIALX + else + compile_MATERIALX + fi + PRINT "" if [ "$USD_SKIP" = true ]; then WARNING "Skipping USD installation, as requested..." @@ -6013,6 +6159,16 @@ install_ARCH() { compile_ALEMBIC fi + PRINT "" + if [ "$MATERIALX_SKIP" = true ]; then + WARNING "Skipping MaterialX installation, as requested..." + elif [ "$MATERIALX_FORCE_BUILD" = true ]; then + INFO "Forced MaterialX building, as requested..." + compile_MATERIALX + else + compile_MATERIALX + fi + PRINT "" if [ "$USD_SKIP" = true ]; then WARNING "Skipping USD installation, as requested..." @@ -6304,6 +6460,27 @@ install_OTHER() { fi + PRINT "" + if [ "$MATERIALX_SKIP" = true ]; then + WARNING "Skipping MaterialX installation, as requested..." + elif [ "$MATERIALX_FORCE_BUILD" = true ]; then + INFO "Forced MaterialX building, as requested..." + compile_MATERIALX + else + compile_MATERIALX + fi + + PRINT "" + if [ "$USD_SKIP" = true ]; then + WARNING "Skipping USD installation, as requested..." + elif [ "$USD_FORCE_BUILD" = true ]; then + INFO "Forced USD building, as requested..." + compile_USD + else + compile_USD + fi + + if [ "$WITH_OPENCOLLADA" = true ]; then PRINT "" if [ "$OPENCOLLADA_SKIP" = true ]; then @@ -6381,7 +6558,8 @@ print_info() { _buildargs="-U *SNDFILE* -U PYTHON* -U *BOOST* -U *Boost* -U *TBB*" _buildargs="$_buildargs -U *OPENCOLORIO* -U *OPENEXR* -U *OPENIMAGEIO* -U *LLVM* -U *CLANG* -U *CYCLES*" - _buildargs="$_buildargs -U *OPENSUBDIV* -U *OPENVDB* -U *BLOSC* -U *COLLADA* -U *FFMPEG* -U *ALEMBIC* -U *USD*" + _buildargs="$_buildargs -U *OPENSUBDIV* -U *OPENVDB* -U *BLOSC* -U *COLLADA* -U *FFMPEG* -U *ALEMBIC*" + _buildargs="$_buildargs -U *MATERIALX* -U *USD*" _buildargs="$_buildargs -U *EMBREE* -U *OPENIMAGEDENOISE* -U *OPENXR* -U *OPENPGL*" _1="-D WITH_CODEC_SNDFILE=ON" @@ -6568,6 +6746,17 @@ print_info() { fi fi + if [ "$MATERIALX_SKIP" = false ]; then + _1="-D WITH_MATERIALX=ON" + PRINT " $_1" + _buildargs="$_buildargs $_1" + if [ -d $INST/materialx ]; then + _1="-D MaterialX_DIR=$INST/materialx/lib/cmake/MaterialX" + PRINT " $_1" + _buildargs="$_buildargs $_1" + fi + fi + if [ "$USD_SKIP" = false ]; then _1="-D WITH_USD=ON" PRINT " $_1" From 8a65e33d415b484d3b69ba895b237d9e0de82806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Thu, 5 Jan 2023 17:12:54 +0100 Subject: [PATCH 0436/1522] Pose Library: properly set hard min/max for blend factor Since rBcommit 74c4977a the pose library blending operator can extrapolate. This is now also reflected in the hard min/max value of the blend factor RNA property. The soft min/max are still -1/1 to indicate normal use. --- source/blender/editors/armature/pose_lib_2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/armature/pose_lib_2.c b/source/blender/editors/armature/pose_lib_2.c index a015e37aac6..827d76cce1f 100644 --- a/source/blender/editors/armature/pose_lib_2.c +++ b/source/blender/editors/armature/pose_lib_2.c @@ -568,8 +568,8 @@ void POSELIB_OT_apply_pose_asset(wmOperatorType *ot) RNA_def_float_factor(ot->srna, "blend_factor", 1.0f, - -1.0f, - 1.0f, + -FLT_MAX, + FLT_MAX, "Blend Factor", "Amount that the pose is applied on top of the existing poses. A negative " "value will apply the pose flipped over the X-axis", @@ -608,8 +608,8 @@ void POSELIB_OT_blend_pose_asset(wmOperatorType *ot) prop = RNA_def_float_factor(ot->srna, "blend_factor", 0.0f, - -1.0f, - 1.0f, + -FLT_MAX, + FLT_MAX, "Blend Factor", "Amount that the pose is applied on top of the existing poses. A " "negative value will apply the pose flipped over the X-axis", From 59ce7bf5a941f4513938f50006351ed36e565bc1 Mon Sep 17 00:00:00 2001 From: David Ballesteros Date: Thu, 5 Jan 2023 18:14:35 +0100 Subject: [PATCH 0437/1522] Nodes: better default name for custom node tree datablocks Use NodeTree.bl_label instead of "NodeTree" for more descriptive name. Implemented by Iliya Katueshenock. Differential Revision: https://developer.blender.org/D16856 --- source/blender/editors/space_node/node_add.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc index 097056b5464..534222b58e6 100644 --- a/source/blender/editors/space_node/node_add.cc +++ b/source/blender/editors/space_node/node_add.cc @@ -844,17 +844,18 @@ static int new_node_tree_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } + if (!ntreeTypeFind(idname)) { + BKE_reportf(op->reports, RPT_ERROR, "Node tree type %s undefined", idname); + return OPERATOR_CANCELLED; + } + if (RNA_struct_property_is_set(op->ptr, "name")) { RNA_string_get(op->ptr, "name", treename_buf); treename = treename_buf; } else { - treename = DATA_("NodeTree"); - } - - if (!ntreeTypeFind(idname)) { - BKE_reportf(op->reports, RPT_ERROR, "Node tree type %s undefined", idname); - return OPERATOR_CANCELLED; + const bNodeTreeType *type = ntreeTypeFind(idname); + treename = type->ui_name; } ntree = ntreeAddTree(bmain, treename, idname); From 0fb12a9c2ebc5eb12f325e75979bd70958d5af7f Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Thu, 5 Jan 2023 18:59:09 +0100 Subject: [PATCH 0438/1522] GPencil: Fix size difference between radial control and Brush size Due an internal scale of the brush size done by grease pencil draw tool (this scale factor cannot be removed), the size of the radial control is not equal to the actual stroke thickness and this makes the radial size displayed useless. This patch adds a new property that allows to pass the path of the tool path and this value is used to apply the correct scale to the radial size. Reviewed By: mendio, frogstomp, pepeland, brecht Differential Revision: https://developer.blender.org/D16866 --- .../blender/editors/gpencil/gpencil_utils.c | 14 +++++++++++++ source/blender/editors/include/ED_gpencil.h | 4 ++++ .../windowmanager/intern/wm_operators.c | 21 ++++++++++++++++--- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index c0024052d82..1f80cd06af2 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -1780,6 +1780,20 @@ float ED_gpencil_cursor_radius(bContext *C, int x, int y) return radius; } +float ED_gpencil_radial_control_scale(struct bContext *C, + struct Brush *brush, + float initial_value, + const int mval[2]) +{ + float scale_fac = 1.0f; + if ((brush && brush->gpencil_settings) && (brush->gpencil_tool == GPAINT_TOOL_DRAW)) { + float cursor_radius = ED_gpencil_cursor_radius(C, mval[0], mval[1]); + scale_fac = max_ff(cursor_radius, 1.0f) / max_ff(initial_value, 1.0f); + } + + return scale_fac; +} + /** * Helper callback for drawing the cursor itself. */ diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 129229a8861..9dd2ba5d1d3 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -645,6 +645,10 @@ void ED_gpencil_stroke_close_by_distance(struct bGPDstroke *gps, float threshold * Calculate the brush cursor size in world space. */ float ED_gpencil_cursor_radius(struct bContext *C, int x, int y); +float ED_gpencil_radial_control_scale(struct bContext *C, + struct Brush *brush, + float initial_value, + const int mval[2]); #ifdef __cplusplus } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index f43b6722550..61c03505c9b 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -73,6 +73,7 @@ #include "IMB_imbuf_types.h" #include "ED_fileselect.h" +#include "ED_gpencil.h" #include "ED_numinput.h" #include "ED_screen.h" #include "ED_undo.h" @@ -2191,6 +2192,7 @@ typedef struct { int initial_co[2]; int slow_mouse[2]; bool slow_mode; + float scale_fac; Dial *dial; GPUTexture *texture; ListBase orig_paintcursors; @@ -2244,7 +2246,7 @@ static void radial_control_update_header(wmOperator *op, bContext *C) ED_area_status_text(area, msg); } -static void radial_control_set_initial_mouse(RadialControl *rc, const wmEvent *event) +static void radial_control_set_initial_mouse(bContext *C, RadialControl *rc, const wmEvent *event) { float d[2] = {0, 0}; float zoom[2] = {1, 1}; @@ -2279,6 +2281,15 @@ static void radial_control_set_initial_mouse(RadialControl *rc, const wmEvent *e d[0] *= zoom[0]; d[1] *= zoom[1]; } + /* Grease pencil draw tool needs to rescale the cursor size. If we don't do that + * the size of the radial is not equals to the actual stroke size. */ + if (rc->ptr.owner_id && GS(rc->ptr.owner_id->name) == ID_BR && rc->prop == &rna_Brush_size) { + rc->scale_fac = ED_gpencil_radial_control_scale( + C, (Brush *)rc->ptr.owner_id, rc->initial_value, event->mval); + } + else { + rc->scale_fac = 1.0f; + } rc->initial_mouse[0] -= d[0]; rc->initial_mouse[1] -= d[1]; @@ -2483,6 +2494,9 @@ static void radial_control_paint_cursor(bContext *UNUSED(C), int x, int y, void GPU_matrix_scale_2fv(zoom); } + /* Apply scale correction (used by grease pencil brushes). */ + GPU_matrix_scale_2f(rc->scale_fac, rc->scale_fac); + /* draw rotated texture */ radial_control_paint_tex(rc, tex_radius, alpha); @@ -2816,7 +2830,7 @@ static int radial_control_invoke(bContext *C, wmOperator *op, const wmEvent *eve } rc->current_value = rc->initial_value; - radial_control_set_initial_mouse(rc, event); + radial_control_set_initial_mouse(C, rc, event); radial_control_set_tex(rc); rc->init_event = WM_userdef_event_type_from_keymap_type(event->type); @@ -3331,7 +3345,8 @@ static int redraw_timer_exec(bContext *C, wmOperator *op) const int cfra = scene->r.cfra; const char *infostr = ""; - /* NOTE: Depsgraph is used to update scene for a new state, so no need to ensure evaluation here. + /* NOTE: Depsgraph is used to update scene for a new state, so no need to ensure evaluation + * here. */ struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); From 7d712dcd0bbdac04c7721bd616d8abaac806b53a Mon Sep 17 00:00:00 2001 From: frogstomp Date: Thu, 5 Jan 2023 19:20:04 +0100 Subject: [PATCH 0439/1522] Gpencil: Add offset(Location, Rotation, Scale) by Layer, Stroke and Material to Offset modifier This patch adds two new panels in which users can control offset (position, rotation, scale) by layer and by stroke number. Use cases: - if you want to create array of Suzannes and place them one behind another, in 2d mode, Z depth will be wrong. In 3d mode there will be Z fighting. With combination of stroke and layer offset we can fight this issue without touching original drawing. - even easier way to create 2.5d environments.. simply draw on layers and then displace them in one panel instead fiddling with every layer individually Possible improvements: - add offset by material slot - add step parameter, to allow displacing groups of N strokes. {F13129598} Reviewed By: mendio, antoniov Differential Revision: https://developer.blender.org/D15106 --- .../intern/MOD_gpenciloffset.c | 119 +++++++++++++++--- .../makesdna/DNA_gpencil_modifier_defaults.h | 3 + .../makesdna/DNA_gpencil_modifier_types.h | 16 ++- .../makesrna/intern/rna_gpencil_modifier.c | 30 ++++- 4 files changed, 147 insertions(+), 21 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c index 8f0abd0a88e..b1079d1b292 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c @@ -15,12 +15,16 @@ #include "BLT_translation.h" +#include "BLI_hash.h" +#include "BLI_math.h" +#include "BLI_rand.h" #include "DNA_defaults.h" #include "DNA_gpencil_modifier_types.h" #include "DNA_gpencil_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" #include "DNA_screen_types.h" +#include "RNA_access.h" #include "BKE_context.h" #include "BKE_deform.h" @@ -31,6 +35,8 @@ #include "BKE_screen.h" #include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" +#include "DEG_depsgraph_query.h" #include "UI_interface.h" #include "UI_resources.h" @@ -46,6 +52,8 @@ static void initData(GpencilModifierData *md) BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(gpmd, modifier)); MEMCPY_STRUCT_AFTER(gpmd, DNA_struct_default_get(OffsetGpencilModifierData), modifier); + /* Open the first subpanel too, because it's activated by default. */ + md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT | UI_SUBPANEL_DATA_EXPAND_1; } static void copyData(const GpencilModifierData *md, GpencilModifierData *target) @@ -84,6 +92,8 @@ static void deformStroke(GpencilModifierData *md, const bool is_randomized = !(is_zero_v3(mmd->rnd_offset) && is_zero_v3(mmd->rnd_rot) && is_zero_v3(mmd->rnd_scale)); + const bool is_general = !(is_zero_v3(mmd->loc) && is_zero_v3(mmd->rot) && + is_zero_v3(mmd->scale)); int seed = mmd->seed; /* Make sure different modifiers get different seeds. */ @@ -92,8 +102,9 @@ static void deformStroke(GpencilModifierData *md, float rand[3][3]; float rand_offset = BLI_hash_int_01(seed); + bGPdata *gpd = ob->data; - if (is_randomized) { + if (is_randomized && mmd->mode == GP_OFFSET_RANDOM) { /* Get stroke index for random offset. */ int rnd_index = BLI_findindex(&gpf->strokes, gps); for (int j = 0; j < 3; j++) { @@ -117,9 +128,39 @@ static void deformStroke(GpencilModifierData *md, } } } + else { + if (is_randomized) { + const int step = max_ii(mmd->stroke_step, 1); + const int start_offset = mmd->stroke_start_offset; + int offset_index; + int offset_size; + float offset_factor; + switch (mmd->mode) { + case GP_OFFSET_STROKE: + offset_size = max_ii(BLI_listbase_count(&gpf->strokes), 1); + offset_index = max_ii(BLI_findindex(&gpf->strokes, gps), 0); + break; + case GP_OFFSET_MATERIAL: + offset_size = max_ii(gpd->totcol, 1); + offset_index = max_ii(gps->mat_nr, 0); + break; + case GP_OFFSET_LAYER: + offset_size = max_ii(BLI_listbase_count(&gpd->layers), 1); + offset_index = max_ii(BLI_findindex(&gpd->layers, gpl), 0); + break; + } - bGPdata *gpd = ob->data; - + offset_factor = ((offset_size - (offset_index / step + start_offset % offset_size) % + offset_size * step % offset_size) - + 1) / + (float)offset_size; + for (int j = 0; j < 3; j++) { + for (int i = 0; i < 3; i++) { + rand[j][i] = offset_factor; + } + } + } + } for (int i = 0; i < gps->totpoints; i++) { bGPDspoint *pt = &gps->points[i]; MDeformVert *dvert = gps->dvert != NULL ? &gps->dvert[i] : NULL; @@ -151,17 +192,19 @@ static void deformStroke(GpencilModifierData *md, } /* Calculate matrix. */ - mul_v3_v3fl(loc, mmd->loc, weight); - mul_v3_v3fl(rot, mmd->rot, weight); - mul_v3_v3fl(scale, mmd->scale, weight); - add_v3_fl(scale, 1.0); - loc_eul_size_to_mat4(mat, loc, rot, scale); + if (is_general) { + mul_v3_v3fl(loc, mmd->loc, weight); + mul_v3_v3fl(rot, mmd->rot, weight); + mul_v3_v3fl(scale, mmd->scale, weight); + add_v3_fl(scale, 1.0f); + loc_eul_size_to_mat4(mat, loc, rot, scale); - /* Apply scale to thickness. */ - float unit_scale = (fabsf(scale[0]) + fabsf(scale[1]) + fabsf(scale[2])) / 3.0f; - pt->pressure *= unit_scale; + /* Apply scale to thickness. */ + float unit_scale = (fabsf(scale[0]) + fabsf(scale[1]) + fabsf(scale[2])) / 3.0f; + pt->pressure *= unit_scale; - mul_m4_v3(mat, &pt->x); + mul_m4_v3(mat, &pt->x); + } } /* Calc geometry data. */ BKE_gpencil_stroke_geometry_update(gpd, gps); @@ -175,6 +218,13 @@ static void bakeModifier(struct Main *UNUSED(bmain), generic_bake_deform_stroke(depsgraph, md, ob, false, deformStroke); } +static void updateDepsgraph(GpencilModifierData *md, + const ModifierUpdateDepsgraphContext *ctx, + const int UNUSED(mode)) +{ + DEG_add_object_relation(ctx->node, ctx->object, DEG_OB_COMP_TRANSFORM, "Offset Modifier"); +} + static void foreachIDLink(GpencilModifierData *md, Object *ob, IDWalkFunc walk, void *userData) { OffsetGpencilModifierData *mmd = (OffsetGpencilModifierData *)md; @@ -187,13 +237,23 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayout *layout = panel->layout; PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL); - uiLayoutSetPropSep(layout, true); uiItemR(layout, ptr, "location", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "rotation", 0, NULL, ICON_NONE); uiItemR(layout, ptr, "scale", 0, NULL, ICON_NONE); + gpencil_modifier_panel_end(layout, ptr); + uiLayoutSetActive(layout, true); +} + +static void empty_panel_draw(const bContext *UNUSED(C), Panel *panel) +{ + uiLayout *layout = panel->layout; + + PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL); + uiLayoutSetPropSep(layout, true); + gpencil_modifier_panel_end(layout, ptr); } @@ -202,14 +262,33 @@ static void random_panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayout *layout = panel->layout; PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, NULL); - + int mode = RNA_enum_get(ptr, "mode"); uiLayoutSetPropSep(layout, true); + uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "random_offset", 0, IFACE_("Offset"), ICON_NONE); uiItemR(layout, ptr, "random_rotation", 0, IFACE_("Rotation"), ICON_NONE); uiItemR(layout, ptr, "random_scale", 0, IFACE_("Scale"), ICON_NONE); - uiItemR(layout, ptr, "use_uniform_random_scale", 0, NULL, ICON_NONE); - uiItemR(layout, ptr, "seed", 0, NULL, ICON_NONE); + switch (mode) { + case GP_OFFSET_RANDOM: + uiItemR(layout, ptr, "use_uniform_random_scale", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "seed", 0, NULL, ICON_NONE); + break; + case GP_OFFSET_STROKE: + uiItemR(layout, ptr, "stroke_step", 0, IFACE_("Stroke Step"), ICON_NONE); + uiItemR(layout, ptr, "stroke_start_offset", 0, IFACE_("Stroke Offset"), ICON_NONE); + break; + case GP_OFFSET_MATERIAL: + uiItemR(layout, ptr, "stroke_step", 0, IFACE_("Material Step"), ICON_NONE); + uiItemR(layout, ptr, "stroke_start_offset", 0, IFACE_("Material Offset"), ICON_NONE); + break; + case GP_OFFSET_LAYER: + uiItemR(layout, ptr, "stroke_step", 0, IFACE_("Layer Step"), ICON_NONE); + uiItemR(layout, ptr, "stroke_start_offset", 0, IFACE_("Layer Offset"), ICON_NONE); + break; + } + gpencil_modifier_panel_end(layout, ptr); } static void mask_panel_draw(const bContext *UNUSED(C), Panel *panel) @@ -220,9 +299,11 @@ static void mask_panel_draw(const bContext *UNUSED(C), Panel *panel) static void panelRegister(ARegionType *region_type) { PanelType *panel_type = gpencil_modifier_panel_register( - region_type, eGpencilModifierType_Offset, panel_draw); + region_type, eGpencilModifierType_Offset, empty_panel_draw); gpencil_modifier_subpanel_register( - region_type, "randomize", "Randomize", NULL, random_panel_draw, panel_type); + region_type, "general", "General", NULL, panel_draw, panel_type); + gpencil_modifier_subpanel_register( + region_type, "randomize", "Advanced", NULL, random_panel_draw, panel_type); gpencil_modifier_subpanel_register( region_type, "mask", "Influence", NULL, mask_panel_draw, panel_type); } @@ -244,7 +325,7 @@ GpencilModifierTypeInfo modifierType_Gpencil_Offset = { /* initData */ initData, /* freeData */ NULL, /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, + /* updateDepsgraph */ updateDepsgraph, /* dependsOnTime */ NULL, /* foreachIDLink */ foreachIDLink, /* foreachTexLink */ NULL, diff --git a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h index 8078283df7a..ae27cbb0195 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h @@ -152,6 +152,9 @@ .vgname = "", \ .pass_index = 0, \ .flag = 0, \ + .stroke_step = 1, \ + .mode = GP_OFFSET_RANDOM, \ + .stroke_start_offset = 0, \ .loc = {0.0f, 0.0f, 0.0f}, \ .rot = {0.0f, 0.0f, 0.0f}, \ .scale = {0.0f, 0.0f, 0.0f}, \ diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h index 0932b7107bb..3f56a25a19b 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_types.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -388,6 +388,7 @@ typedef struct ArrayGpencilModifierData { float rnd_rot[3]; /** Random Scales. */ float rnd_scale[3]; + char _pad[4]; /** (first element is the index) random values. */ int seed; @@ -759,8 +760,17 @@ typedef enum eSimplifyGpencil_Mode { GP_SIMPLIFY_MERGE = 3, } eSimplifyGpencil_Mode; +typedef enum eOffsetGpencil_Mode { + GP_OFFSET_RANDOM = 0, + GP_OFFSET_LAYER = 1, + GP_OFFSET_MATERIAL = 2, + GP_OFFSET_STROKE = 3 + +} eOffsetGpencil_Mode; + typedef struct OffsetGpencilModifierData { GpencilModifierData modifier; + struct Object *object; /** Material for filtering. */ struct Material *material; /** Layer name. */ @@ -784,8 +794,12 @@ typedef struct OffsetGpencilModifierData { float rnd_scale[3]; /** (first element is the index) random values. */ int seed; - /** Custom index for passes. */ + int mode; + int stroke_step; + int stroke_start_offset; int layer_pass; + char _pad[4]; + } OffsetGpencilModifierData; typedef enum eOffsetGpencil_Flag { diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index 6d74fd7eab8..bd25f26610a 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -434,6 +434,7 @@ RNA_GP_MOD_OBJECT_SET(WeightProx, object, OB_EMPTY); RNA_GP_MOD_OBJECT_SET(Shrinkwrap, target, OB_MESH); RNA_GP_MOD_OBJECT_SET(Shrinkwrap, aux_target, OB_MESH); RNA_GP_MOD_OBJECT_SET(Build, object, OB_EMPTY); +RNA_GP_MOD_OBJECT_SET(Offset, object, OB_EMPTY); # undef RNA_GP_MOD_OBJECT_SET @@ -1515,11 +1516,30 @@ static void rna_def_modifier_gpenciloffset(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + RNA_define_lib_overridable(true); + static EnumPropertyItem rna_enum_offset_mode_items[] = { + {GP_OFFSET_RANDOM, "RANDOM", 0, "Random", "Randomize stroke offset"}, + {GP_OFFSET_LAYER, "LAYER", 0, "Layer", "Offset layers by the same factor"}, + {GP_OFFSET_STROKE, + "STROKE", + 0, + "Stroke", + "Offset strokes by the same factor based on stroke draw order"}, + {GP_OFFSET_MATERIAL, "MATERIAL", 0, "Material", "Offset materials by the same factor"}, + {0, NULL, 0, NULL, NULL}, + }; + srna = RNA_def_struct(brna, "OffsetGpencilModifier", "GpencilModifier"); RNA_def_struct_ui_text(srna, "Offset Modifier", "Offset Stroke modifier"); RNA_def_struct_sdna(srna, "OffsetGpencilModifierData"); RNA_def_struct_ui_icon(srna, ICON_MOD_OFFSET); + prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "mode"); + RNA_def_property_enum_items(prop, rna_enum_offset_mode_items); + RNA_def_property_ui_text(prop, "Mode", ""); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + RNA_define_lib_overridable(true); prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); @@ -1620,12 +1640,20 @@ static void rna_def_modifier_gpenciloffset(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Seed", "Random seed"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + prop = RNA_def_property(srna, "stroke_step", PROP_INT, PROP_UNSIGNED); + RNA_def_property_ui_text(prop, "Step", "Number of elements that will be grouped"); + RNA_def_property_range(prop, 1, 500); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "stroke_start_offset", PROP_INT, PROP_UNSIGNED); + RNA_def_property_ui_text(prop, "Start Offset", "Offset starting point"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + prop = RNA_def_property(srna, "use_uniform_random_scale", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_OFFSET_UNIFORM_RANDOM_SCALE); RNA_def_property_ui_text( prop, "Uniform Scale", "Use the same random seed for each scale axis for a uniform scale"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); - RNA_define_lib_overridable(false); } From 084b52bcd8c9fde744985d753b36f4ba9804447f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 5 Jan 2023 19:06:05 +0100 Subject: [PATCH 0440/1522] Cycles: take into account IES texture node strength input for light tree To better estimate light contribution. Note that estimating the texture from the IES file is still missing. Contributed by Alaska. Differential Revision: https://developer.blender.org/D16901 --- intern/cycles/scene/shader.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/intern/cycles/scene/shader.cpp b/intern/cycles/scene/shader.cpp index 09255d7cee4..e03b77917ef 100644 --- a/intern/cycles/scene/shader.cpp +++ b/intern/cycles/scene/shader.cpp @@ -263,8 +263,9 @@ static float3 output_estimate_emission(ShaderOutput *output, bool &is_constant) return estimate; } - else if (node->type == LightFalloffNode::get_node_type()) { - /* Light Falloff node. */ + else if (node->type == LightFalloffNode::get_node_type() || + node->type == IESLightNode::get_node_type()) { + /* Get strength from Light Falloff and IES texture node. */ ShaderInput *strength_in = node->input("Strength"); is_constant = false; From 87f7b630b5cc7f792b57907e4054e3ee2f60e707 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 5 Jan 2023 19:42:16 +0100 Subject: [PATCH 0441/1522] Cleanup: make format --- intern/cycles/blender/device.cpp | 5 ++++- intern/cycles/blender/sync.cpp | 3 ++- intern/cycles/device/device.h | 6 +++--- intern/cycles/device/metal/device_impl.mm | 3 ++- intern/cycles/device/metal/kernel.mm | 14 +++++++------- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/intern/cycles/blender/device.cpp b/intern/cycles/blender/device.cpp index 96e7bdd03aa..9d2fba11c1a 100644 --- a/intern/cycles/blender/device.cpp +++ b/intern/cycles/blender/device.cpp @@ -30,7 +30,10 @@ int blender_device_threads(BL::Scene &b_scene) return 0; } -DeviceInfo blender_device_info(BL::Preferences &b_preferences, BL::Scene &b_scene, bool background, bool preview) +DeviceInfo blender_device_info(BL::Preferences &b_preferences, + BL::Scene &b_scene, + bool background, + bool preview) { PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); diff --git a/intern/cycles/blender/sync.cpp b/intern/cycles/blender/sync.cpp index 45fe4334f06..7df2a8cf30f 100644 --- a/intern/cycles/blender/sync.cpp +++ b/intern/cycles/blender/sync.cpp @@ -866,7 +866,8 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine &b_engine, /* Device */ params.threads = blender_device_threads(b_scene); - params.device = blender_device_info(b_preferences, b_scene, params.background, b_engine.is_preview()); + params.device = blender_device_info( + b_preferences, b_scene, params.background, b_engine.is_preview()); /* samples */ int samples = get_int(cscene, "samples"); diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h index 3923698b1cd..377c123b035 100644 --- a/intern/cycles/device/device.h +++ b/intern/cycles/device/device.h @@ -71,9 +71,9 @@ class DeviceInfo { string description; string id; /* used for user preferences, should stay fixed with changing hardware config */ int num; - bool display_device; /* GPU is used as a display device. */ - bool has_nanovdb; /* Support NanoVDB volumes. */ - bool has_light_tree; /* Support light tree. */ + bool display_device; /* GPU is used as a display device. */ + bool has_nanovdb; /* Support NanoVDB volumes. */ + bool has_light_tree; /* Support light tree. */ bool has_osl; /* Support Open Shading Language. */ bool has_guiding; /* Support path guiding. */ bool has_profiling; /* Supports runtime collection of profiling info. */ diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm index 01578155931..85486c132d8 100644 --- a/intern/cycles/device/metal/device_impl.mm +++ b/intern/cycles/device/metal/device_impl.mm @@ -469,7 +469,8 @@ void MetalDevice::compile_and_load(int device_id, MetalPipelineType pso_type) [options release]; - bool blocking_pso_build = (getenv("CYCLES_METAL_PROFILING") || MetalDeviceKernels::is_benchmark_warmup()); + bool blocking_pso_build = (getenv("CYCLES_METAL_PROFILING") || + MetalDeviceKernels::is_benchmark_warmup()); if (blocking_pso_build) { MetalDeviceKernels::wait_for_all(); starttime = 0.0; diff --git a/intern/cycles/device/metal/kernel.mm b/intern/cycles/device/metal/kernel.mm index 7b26085c75f..e4ce5e19f63 100644 --- a/intern/cycles/device/metal/kernel.mm +++ b/intern/cycles/device/metal/kernel.mm @@ -124,7 +124,7 @@ DeviceShaderCache g_shaderCache[MAX_POSSIBLE_GPUS_ON_SYSTEM]; ShaderCache *get_shader_cache(id mtlDevice) { - for (int i=0; ikernel_features & KERNEL_FEATURE_OBJECT_MOTION; MetalKernelPipeline *best_pipeline = nullptr; - while(!best_pipeline) { + while (!best_pipeline) { { thread_scoped_lock lock(cache_mutex); for (auto &pipeline : pipelines[kernel]) { @@ -366,7 +366,7 @@ MetalKernelPipeline *ShaderCache::get_best_pipeline(DeviceKernel kernel, const M bool pipeline_metalrt_hair_thick = pipeline->metalrt_features & KERNEL_FEATURE_HAIR_THICK; bool pipeline_metalrt_pointcloud = pipeline->metalrt_features & KERNEL_FEATURE_POINTCLOUD; bool pipeline_metalrt_motion = use_metalrt && - pipeline->metalrt_features & KERNEL_FEATURE_OBJECT_MOTION; + pipeline->metalrt_features & KERNEL_FEATURE_OBJECT_MOTION; if (pipeline->use_metalrt != use_metalrt || pipeline_metalrt_hair != device_metalrt_hair || pipeline_metalrt_hair_thick != device_metalrt_hair_thick || @@ -824,7 +824,7 @@ bool MetalDeviceKernels::load(MetalDevice *device, MetalPipelineType pso_type) void MetalDeviceKernels::wait_for_all() { - for (int i=0; iwait_for_all(); } } @@ -833,7 +833,7 @@ bool MetalDeviceKernels::any_specialization_happening_now() { /* Return true if any ShaderCaches have ongoing specialization requests (typically there will be * only 1). */ - for (int i=0; iincomplete_specialization_requests > 0) { return true; } @@ -868,8 +868,8 @@ const MetalKernelPipeline *MetalDeviceKernels::get_best_pipeline(const MetalDevi bool MetalDeviceKernels::is_benchmark_warmup() { NSArray *args = [[NSProcessInfo processInfo] arguments]; - for (int i = 0; i Date: Wed, 28 Dec 2022 22:19:36 +0200 Subject: [PATCH 0442/1522] BVH: implement an optimized self-overlap traversal. Previously cloth self-collision and other code that wants self-overlap data was using an ordinary BVH overlap utility function. This works, but is suboptimal because it fails to take advantage of the fact that it is comparing two identical trees. The standard traversal for self-collision essentially devolves into enumerating all elements of the tree, and then matching them to the tree starting at the root. However, the tree itself naturally partitions the space, so overlapping elements are likely to be mostly placed nearby in the tree structure as well. Instead, self-overlap can be computed by recursively computing ordinary overlap between siblings within each subtree. This only considers each pair of leaves once, and provides significantly better locality. It also avoids outputting every overlap pair twice in different order. Differential Revision: https://developer.blender.org/D16915 --- source/blender/blenkernel/intern/collision.c | 9 +- source/blender/blenlib/BLI_kdopbvh.h | 13 +- source/blender/blenlib/intern/BLI_kdopbvh.c | 121 ++++++++++++++---- .../extract_mesh_vbo_mesh_analysis.cc | 2 +- source/blender/editors/uvedit/uvedit_select.c | 2 +- 5 files changed, 118 insertions(+), 29 deletions(-) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 2acdc6543b5..cd34ae29efb 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1521,8 +1521,9 @@ static bool cloth_bvh_obj_overlap_cb(void *userdata, static bool cloth_bvh_self_overlap_cb(void *userdata, int index_a, int index_b, int UNUSED(thread)) { - /* No need for equal combinations (eg. (0,1) & (1,0)). */ - if (index_a < index_b) { + /* This shouldn't happen, but just in case. Note that equal combinations + * (eg. (0,1) & (1,0)) would be filtered out by BLI_bvhtree_overlap_self. */ + if (index_a != index_b) { ClothModifierData *clmd = (ClothModifierData *)userdata; struct Cloth *clothObject = clmd->clothObject; const MVertTri *tri_a, *tri_b; @@ -1599,8 +1600,8 @@ int cloth_bvh_collision( if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF) { bvhtree_update_from_cloth(clmd, false, true); - overlap_self = BLI_bvhtree_overlap( - cloth->bvhselftree, cloth->bvhselftree, &coll_count_self, cloth_bvh_self_overlap_cb, clmd); + overlap_self = BLI_bvhtree_overlap_self( + cloth->bvhselftree, &coll_count_self, cloth_bvh_self_overlap_cb, clmd); } do { diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 17759b6a8ac..463c95cf4f3 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -73,9 +73,11 @@ typedef struct BVHTreeRayHit { } BVHTreeRayHit; enum { - /* Use a priority queue to process nodes in the optimal order (for slow callbacks) */ BVH_OVERLAP_USE_THREADING = (1 << 0), BVH_OVERLAP_RETURN_PAIRS = (1 << 1), + /* Use a specialized self-overlap traversal to only test and output every + * pair once, rather than twice in different order as usual. */ + BVH_OVERLAP_SELF = (1 << 2), }; enum { /* Use a priority queue to process nodes in the optimal order (for slow callbacks) */ @@ -163,6 +165,9 @@ bool BLI_bvhtree_update_node( BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints); /** * Call #BLI_bvhtree_update_node() first for every node/point/triangle. + * + * Note that this does not rebalance the tree, so if the shape of the mesh changes + * too much, operations on the tree may become suboptimal. */ void BLI_bvhtree_update_tree(BVHTree *tree); @@ -191,6 +196,12 @@ BVHTreeOverlap *BLI_bvhtree_overlap(const BVHTree *tree1, unsigned int *r_overlap_num, BVHTree_OverlapCallback callback, void *userdata); +/** Compute overlaps of the tree with itself. This is faster than BLI_bvhtree_overlap + * because it only tests and returns each symmetrical pair once. */ +BVHTreeOverlap *BLI_bvhtree_overlap_self(const BVHTree *tree, + unsigned int *r_overlap_num, + BVHTree_OverlapCallback callback, + void *userdata); int *BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_num); diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index de71147f015..174a53be6da 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -95,6 +95,7 @@ BLI_STATIC_ASSERT((sizeof(void *) == 8 && sizeof(BVHTree) <= 48) || typedef struct BVHOverlapData_Shared { const BVHTree *tree1, *tree2; axis_t start_axis, stop_axis; + bool use_self; /* use for callbacks */ BVHTree_OverlapCallback callback; @@ -1231,6 +1232,62 @@ static bool tree_overlap_traverse_num(BVHOverlapData_Thread *data_thread, return false; } +/** Calls the appropriate recursive overlap traversal function. */ +static void tree_overlap_invoke_traverse(BVHOverlapData_Thread *data, + const BVHNode *node1, + const BVHNode *node2) +{ + if (data->max_interactions) { + tree_overlap_traverse_num(data, node1, node2); + } + else if (data->shared->callback) { + tree_overlap_traverse_cb(data, node1, node2); + } + else { + tree_overlap_traverse(data, node1, node2); + } +} + +/** Self-overlap traversal with callback. */ +static void tree_overlap_traverse_self_cb(BVHOverlapData_Thread *data_thread, const BVHNode *node) +{ + for (int i = 0; i < node->node_num; i++) { + /* Recursively compute self-overlap within each child. */ + tree_overlap_traverse_self_cb(data_thread, node->children[i]); + + /* Compute overlap of pairs of children, testing each one only once (assume symmetry). */ + for (int j = i + 1; j < node->node_num; j++) { + tree_overlap_traverse_cb(data_thread, node->children[i], node->children[j]); + } + } +} + +/** Self-overlap traversal without callback. */ +static void tree_overlap_traverse_self(BVHOverlapData_Thread *data_thread, const BVHNode *node) +{ + for (int i = 0; i < node->node_num; i++) { + /* Recursively compute self-overlap within each child. */ + tree_overlap_traverse_self(data_thread, node->children[i]); + + /* Compute overlap of pairs of children, testing each one only once (assume symmetry). */ + for (int j = i + 1; j < node->node_num; j++) { + tree_overlap_traverse(data_thread, node->children[i], node->children[j]); + } + } +} + +/** Calls the appropriate recursive self-overlap traversal. */ +static void tree_overlap_invoke_traverse_self(BVHOverlapData_Thread *data_thread, + const BVHNode *node) +{ + if (data_thread->shared->callback) { + tree_overlap_traverse_self_cb(data_thread, node); + } + else { + tree_overlap_traverse_self(data_thread, node); + } +} + int BLI_bvhtree_overlap_thread_num(const BVHTree *tree) { return (int)MIN2(tree->tree_type, tree->nodes[tree->leaf_num]->node_num); @@ -1243,20 +1300,20 @@ static void bvhtree_overlap_task_cb(void *__restrict userdata, BVHOverlapData_Thread *data = &((BVHOverlapData_Thread *)userdata)[j]; BVHOverlapData_Shared *data_shared = data->shared; - if (data->max_interactions) { - tree_overlap_traverse_num(data, - data_shared->tree1->nodes[data_shared->tree1->leaf_num]->children[j], - data_shared->tree2->nodes[data_shared->tree2->leaf_num]); - } - else if (data_shared->callback) { - tree_overlap_traverse_cb(data, - data_shared->tree1->nodes[data_shared->tree1->leaf_num]->children[j], - data_shared->tree2->nodes[data_shared->tree2->leaf_num]); + const BVHNode *root1 = data_shared->tree1->nodes[data_shared->tree1->leaf_num]; + + if (data_shared->use_self) { + /* This code matches one outer loop iteration within traverse_self. */ + tree_overlap_invoke_traverse_self(data, root1->children[j]); + + for (int k = j + 1; k < root1->node_num; k++) { + tree_overlap_invoke_traverse(data, root1->children[j], root1->children[k]); + } } else { - tree_overlap_traverse(data, - data_shared->tree1->nodes[data_shared->tree1->leaf_num]->children[j], - data_shared->tree2->nodes[data_shared->tree2->leaf_num]); + const BVHNode *root2 = data_shared->tree2->nodes[data_shared->tree2->leaf_num]; + + tree_overlap_invoke_traverse(data, root1->children[j], root2); } } @@ -1273,9 +1330,12 @@ BVHTreeOverlap *BLI_bvhtree_overlap_ex( bool overlap_pairs = (flag & BVH_OVERLAP_RETURN_PAIRS) != 0; bool use_threading = (flag & BVH_OVERLAP_USE_THREADING) != 0 && (tree1->leaf_num > KDOPBVH_THREAD_LEAF_THRESHOLD); + bool use_self = (flag & BVH_OVERLAP_SELF) != 0; /* 'RETURN_PAIRS' was not implemented without 'max_interactions'. */ BLI_assert(overlap_pairs || max_interactions); + /* Self-overlap does not support max interactions (it's not symmetrical). */ + BLI_assert(!use_self || tree1 == tree2 && !max_interactions); const int root_node_len = BLI_bvhtree_overlap_thread_num(tree1); const int thread_num = use_threading ? root_node_len : 1; @@ -1293,6 +1353,10 @@ BVHTreeOverlap *BLI_bvhtree_overlap_ex( return NULL; } + if (UNLIKELY(use_self && tree1 != tree2)) { + use_self = false; + } + const BVHNode *root1 = tree1->nodes[tree1->leaf_num]; const BVHNode *root2 = tree2->nodes[tree2->leaf_num]; @@ -1308,6 +1372,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap_ex( data_shared.tree2 = tree2; data_shared.start_axis = start_axis; data_shared.stop_axis = stop_axis; + data_shared.use_self = use_self; /* can be NULL */ data_shared.callback = callback; @@ -1317,7 +1382,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap_ex( /* init BVHOverlapData_Thread */ data[j].shared = &data_shared; data[j].overlap = overlap_pairs ? BLI_stack_new(sizeof(BVHTreeOverlap), __func__) : NULL; - data[j].max_interactions = max_interactions; + data[j].max_interactions = use_self ? 0 : max_interactions; /* for callback */ data[j].thread = j; @@ -1329,16 +1394,11 @@ BVHTreeOverlap *BLI_bvhtree_overlap_ex( settings.min_iter_per_thread = 1; BLI_task_parallel_range(0, root_node_len, data, bvhtree_overlap_task_cb, &settings); } + else if (use_self) { + tree_overlap_invoke_traverse_self(data, root1); + } else { - if (max_interactions) { - tree_overlap_traverse_num(data, root1, root2); - } - else if (callback) { - tree_overlap_traverse_cb(data, root1, root2); - } - else { - tree_overlap_traverse(data, root1, root2); - } + tree_overlap_invoke_traverse(data, root1, root2); } if (overlap_pairs) { @@ -1377,6 +1437,23 @@ BVHTreeOverlap *BLI_bvhtree_overlap( BVH_OVERLAP_USE_THREADING | BVH_OVERLAP_RETURN_PAIRS); } +BVHTreeOverlap *BLI_bvhtree_overlap_self( + const BVHTree *tree, + uint *r_overlap_num, + /* optional callback to test the overlap before adding (must be thread-safe!) */ + BVHTree_OverlapCallback callback, + void *userdata) +{ + return BLI_bvhtree_overlap_ex(tree, + tree, + r_overlap_num, + callback, + userdata, + 0, + BVH_OVERLAP_USE_THREADING | BVH_OVERLAP_RETURN_PAIRS | + BVH_OVERLAP_SELF); +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc index d0d97054448..9aa8a4fe6a4 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc @@ -347,7 +347,7 @@ static void statvis_calc_intersect(const MeshRenderData *mr, float *r_intersect) data.mlooptri = mr->mlooptri; data.epsilon = BLI_bvhtree_get_epsilon(tree); - BVHTreeOverlap *overlap = BLI_bvhtree_overlap(tree, tree, &overlap_len, bvh_overlap_cb, &data); + BVHTreeOverlap *overlap = BLI_bvhtree_overlap_self(tree, &overlap_len, bvh_overlap_cb, &data); if (overlap) { for (int i = 0; i < overlap_len; i++) { const MPoly *f_hit_pair[2] = { diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index 777cc1d97e4..48ffbcfa1c7 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -4427,7 +4427,7 @@ static int uv_select_overlap(bContext *C, const bool extend) BLI_bvhtree_balance(uv_tree); uint tree_overlap_len; - BVHTreeOverlap *overlap = BLI_bvhtree_overlap(uv_tree, uv_tree, &tree_overlap_len, NULL, NULL); + BVHTreeOverlap *overlap = BLI_bvhtree_overlap_self(uv_tree, &tree_overlap_len, NULL, NULL); if (overlap != NULL) { GSet *overlap_set = BLI_gset_new_ex(overlap_hash, overlap_cmp, __func__, tree_overlap_len); From 4fb0eb3a6e86af03724c3f31d5bbdcca0daba524 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Fri, 6 Jan 2023 02:34:39 +0200 Subject: [PATCH 0443/1522] Minor fixes after introducing special BVH traversal for self-collision. - Add parentheses to suppress an assertion on some compilers. - It turns out cloth self-collision math is not precisely symmetric, so sort the triangle index pair to restore behavior exactly identical to the version before the new traversal. Follow up to rB0796210c8df32 --- source/blender/blenkernel/intern/collision.c | 11 +++++++++-- source/blender/blenlib/intern/BLI_kdopbvh.c | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index cd34ae29efb..bf814b7c595 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1115,8 +1115,15 @@ static void cloth_selfcollision(void *__restrict userdata, float epsilon = clmd->coll_parms->selfepsilon; float pa[3], pb[3], vect[3]; - tri_a = &clmd->clothObject->tri[data->overlap[index].indexA]; - tri_b = &clmd->clothObject->tri[data->overlap[index].indexB]; + /* Collision math is currently not symmetric, so ensure a stable order for each pair. */ + int indexA = data->overlap[index].indexA, indexB = data->overlap[index].indexB; + + if (indexA > indexB) { + SWAP(int, indexA, indexB); + } + + tri_a = &clmd->clothObject->tri[indexA]; + tri_b = &clmd->clothObject->tri[indexB]; BLI_assert(cloth_bvh_selfcollision_is_active(clmd, clmd->clothObject, tri_a, tri_b)); diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 174a53be6da..4e958209f78 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -1335,7 +1335,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap_ex( /* 'RETURN_PAIRS' was not implemented without 'max_interactions'. */ BLI_assert(overlap_pairs || max_interactions); /* Self-overlap does not support max interactions (it's not symmetrical). */ - BLI_assert(!use_self || tree1 == tree2 && !max_interactions); + BLI_assert(!use_self || (tree1 == tree2 && !max_interactions)); const int root_node_len = BLI_bvhtree_overlap_thread_num(tree1); const int thread_num = use_threading ? root_node_len : 1; From bc5337a05a22518051f71f26ac1948e327c2ebd9 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Fri, 6 Jan 2023 01:08:17 +0100 Subject: [PATCH 0444/1522] Fix T103507: Distant lights partially contribute to wrong lightgroup The the BSDF-sampling half of MIS next-event estimation for distant lights was using the background lightgroup instead of the lamp's lightgroup. --- intern/cycles/kernel/integrator/shade_background.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/intern/cycles/kernel/integrator/shade_background.h b/intern/cycles/kernel/integrator/shade_background.h index a3dec6a7c74..3c01a162d01 100644 --- a/intern/cycles/kernel/integrator/shade_background.h +++ b/intern/cycles/kernel/integrator/shade_background.h @@ -180,8 +180,7 @@ ccl_device_inline void integrate_distant_lights(KernelGlobals kg, /* Write to render buffer. */ guiding_record_background(kg, state, light_eval, mis_weight); - film_write_surface_emission( - kg, state, light_eval, mis_weight, render_buffer, kernel_data.background.lightgroup); + film_write_surface_emission(kg, state, light_eval, mis_weight, render_buffer, ls.group); } } } From 00a20aec074c3a10a2d2e1142c14cc533c90a6b3 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Fri, 6 Jan 2023 02:32:03 +0100 Subject: [PATCH 0445/1522] Fix T103403: Lightgroup passes can contain lighting on shadow catchers --- intern/cycles/kernel/film/light_passes.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/intern/cycles/kernel/film/light_passes.h b/intern/cycles/kernel/film/light_passes.h index dbc527f2d5d..4cfd1aef43a 100644 --- a/intern/cycles/kernel/film/light_passes.h +++ b/intern/cycles/kernel/film/light_passes.h @@ -364,7 +364,9 @@ ccl_device_inline void film_write_emission_or_background_pass( } # endif /* __DENOISING_FEATURES__ */ - if (lightgroup != LIGHTGROUP_NONE && kernel_data.film.pass_lightgroup != PASS_UNUSED) { + const bool is_shadowcatcher = (path_flag & PATH_RAY_SHADOW_CATCHER_HIT) != 0; + if (!is_shadowcatcher && lightgroup != LIGHTGROUP_NONE && + kernel_data.film.pass_lightgroup != PASS_UNUSED) { film_write_pass_spectrum(buffer + kernel_data.film.pass_lightgroup + 3 * lightgroup, contribution); } @@ -373,13 +375,12 @@ ccl_device_inline void film_write_emission_or_background_pass( /* Directly visible, write to emission or background pass. */ pass_offset = pass; } - else if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { + else if (is_shadowcatcher) { /* Don't write any light passes for shadow catcher, for easier * compositing back together of the combined pass. */ - if (path_flag & PATH_RAY_SHADOW_CATCHER_HIT) { - return; - } - + return; + } + else if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { if (path_flag & PATH_RAY_SURFACE_PASS) { /* Indirectly visible through reflection. */ const Spectrum diffuse_weight = INTEGRATOR_STATE(state, path, pass_diffuse_weight); From cb7f97891d561f7477c39cc2300f838b3677ddc2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Jan 2023 13:52:56 +1100 Subject: [PATCH 0446/1522] Cleanup: quiet shadow variable warning, unused variable --- source/blender/editors/gpencil/gpencil_edit.c | 3 ++- source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index b3f7a553a88..f6d94eeaed5 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -1630,7 +1630,6 @@ static int gpencil_strokes_paste_exec(bContext *C, wmOperator *op) bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd); /* only use active for copy merge */ Scene *scene = CTX_data_scene(C); - bGPDframe *gpf = gpl->actframe; bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; eGP_PasteMode type = RNA_enum_get(op->ptr, "type"); @@ -1744,6 +1743,8 @@ static int gpencil_strokes_paste_exec(bContext *C, wmOperator *op) break; } } + + bGPDframe *gpf; if (IS_AUTOKEY_ON(scene) || (gpl->actframe == NULL)) { gpf = BKE_gpencil_layer_frame_get(gpl, scene->r.cfra, GP_GETFRAME_ADD_NEW); } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c index b1079d1b292..1beebc3cbe8 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c @@ -218,7 +218,7 @@ static void bakeModifier(struct Main *UNUSED(bmain), generic_bake_deform_stroke(depsgraph, md, ob, false, deformStroke); } -static void updateDepsgraph(GpencilModifierData *md, +static void updateDepsgraph(GpencilModifierData *UNUSED(md), const ModifierUpdateDepsgraphContext *ctx, const int UNUSED(mode)) { From 706b13959e18c75722bbbb3d29e6aa22137adb2a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Jan 2023 13:52:57 +1100 Subject: [PATCH 0447/1522] Cleanup: use double-quotes for non-enum strings --- .../scripts/startup/bl_operators/assets.py | 4 +- release/scripts/startup/bl_operators/clip.py | 2 +- .../scripts/startup/bl_operators/freestyle.py | 4 +- .../scripts/startup/bl_operators/sequencer.py | 2 +- release/scripts/startup/bl_operators/wm.py | 2 +- .../startup/bl_ui/properties_animviz.py | 2 +- .../startup/bl_ui/properties_constraint.py | 2 +- .../startup/bl_ui/properties_data_bone.py | 8 +- .../startup/bl_ui/properties_data_curves.py | 10 +-- .../startup/bl_ui/properties_data_mesh.py | 4 +- .../bl_ui/properties_data_pointcloud.py | 12 +-- .../startup/bl_ui/properties_data_volume.py | 2 +- .../startup/bl_ui/properties_output.py | 2 +- .../scripts/startup/bl_ui/space_console.py | 6 +- .../scripts/startup/bl_ui/space_dopesheet.py | 2 +- release/scripts/startup/bl_ui/space_image.py | 2 +- release/scripts/startup/bl_ui/space_node.py | 6 +- .../startup/bl_ui/space_toolsystem_common.py | 10 +-- .../startup/bl_ui/space_toolsystem_toolbar.py | 6 +- .../scripts/startup/bl_ui/space_userpref.py | 2 +- release/scripts/startup/bl_ui/space_view3d.py | 90 +++++++++---------- .../startup/bl_ui/space_view3d_toolbar.py | 2 +- .../scripts/startup/keyingsets_builtins.py | 4 +- 23 files changed, 93 insertions(+), 93 deletions(-) diff --git a/release/scripts/startup/bl_operators/assets.py b/release/scripts/startup/bl_operators/assets.py index b794ede10a2..793ac166d06 100644 --- a/release/scripts/startup/bl_operators/assets.py +++ b/release/scripts/startup/bl_operators/assets.py @@ -81,8 +81,8 @@ class ASSET_OT_open_containing_blend_file(Operator): @classmethod def poll(cls, context): - asset_file_handle = getattr(context, 'asset_file_handle', None) - asset_library_ref = getattr(context, 'asset_library_ref', None) + asset_file_handle = getattr(context, "asset_file_handle", None) + asset_library_ref = getattr(context, "asset_library_ref", None) if not asset_library_ref: cls.poll_message_set("No asset library selected") diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py index 4bdf20d207c..c38c8a57da0 100644 --- a/release/scripts/startup/bl_operators/clip.py +++ b/release/scripts/startup/bl_operators/clip.py @@ -620,7 +620,7 @@ class CLIP_OT_setup_tracking_scene(Operator): if not view_layers.get("Foreground"): if len(view_layers) == 1: fg = view_layers[0] - fg.name = 'Foreground' + fg.name = "Foreground" else: fg = view_layers.new("Foreground") diff --git a/release/scripts/startup/bl_operators/freestyle.py b/release/scripts/startup/bl_operators/freestyle.py index 02b784357b0..80520450786 100644 --- a/release/scripts/startup/bl_operators/freestyle.py +++ b/release/scripts/startup/bl_operators/freestyle.py @@ -142,7 +142,7 @@ class SCENE_OT_freestyle_add_edge_marks_to_keying_set(Operator): bpy.ops.object.mode_set(mode='OBJECT', toggle=False) for i, edge in enumerate(mesh.edges): if not edge.hide and edge.select: - path = 'edges[%d].use_freestyle_mark' % i + path = "edges[%d].use_freestyle_mark" % i ks.paths.add(mesh, path, index=0) bpy.ops.object.mode_set(mode=ob_mode, toggle=False) return {'FINISHED'} @@ -173,7 +173,7 @@ class SCENE_OT_freestyle_add_face_marks_to_keying_set(Operator): bpy.ops.object.mode_set(mode='OBJECT', toggle=False) for i, polygon in enumerate(mesh.polygons): if not polygon.hide and polygon.select: - path = 'polygons[%d].use_freestyle_mark' % i + path = "polygons[%d].use_freestyle_mark" % i ks.paths.add(mesh, path, index=0) bpy.ops.object.mode_set(mode=ob_mode, toggle=False) return {'FINISHED'} diff --git a/release/scripts/startup/bl_operators/sequencer.py b/release/scripts/startup/bl_operators/sequencer.py index a002e53d2ee..45a526272d6 100644 --- a/release/scripts/startup/bl_operators/sequencer.py +++ b/release/scripts/startup/bl_operators/sequencer.py @@ -223,7 +223,7 @@ class SequencerFadesAdd(Operator): if not self.is_long_enough(sequence, duration): continue - animated_property = 'volume' if hasattr(sequence, 'volume') else 'blend_alpha' + animated_property = "volume" if hasattr(sequence, "volume") else "blend_alpha" fade_fcurve = self.fade_find_or_create_fcurve(context, sequence, animated_property) fades = self.calculate_fades(sequence, fade_fcurve, animated_property, duration) self.fade_animation_clear(fade_fcurve, fades) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index bdb679eba07..39789cba0c4 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -2507,7 +2507,7 @@ class WM_OT_batch_rename(Operator): ('COLLECTION', "Collections", ""), ('MATERIAL', "Materials", ""), None, - # Enum identifiers are compared with 'object.type'. + # Enum identifiers are compared with `object.type`. # Follow order in "Add" menu. ('MESH', "Meshes", ""), ('CURVE', "Curves", ""), diff --git a/release/scripts/startup/bl_ui/properties_animviz.py b/release/scripts/startup/bl_ui/properties_animviz.py index 655f80b9c7c..df6d6e63ee8 100644 --- a/release/scripts/startup/bl_ui/properties_animviz.py +++ b/release/scripts/startup/bl_ui/properties_animviz.py @@ -66,7 +66,7 @@ class MotionPathButtonsPanel: col.operator(op_category + ".paths_calculate", text="Calculate...", icon=icon) # Update All & Clear All. - # Note that 'col' is from inside the preceeding `if` or `else` block. + # Note that `col` is from inside the preceding `if` or `else` block. row = col.row(align=True) row.operator("object.paths_update_visible", text="Update All Paths", icon='WORLD') row.operator(op_category + ".paths_clear", text="", icon='X').only_selected = False diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py index d949ee779e1..38e5f5719d4 100644 --- a/release/scripts/startup/bl_ui/properties_constraint.py +++ b/release/scripts/startup/bl_ui/properties_constraint.py @@ -87,7 +87,7 @@ class ConstraintButtonsPanel: @staticmethod def target_template(layout, con, subtargets=True): col = layout.column() - col.prop(con, "target") # XXX limiting settings for only 'curves' or some type of object + col.prop(con, "target") # XXX: limiting settings for only `curves` or some type of object. if con.target and subtargets: if con.target.type == 'ARMATURE': diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index 8e1808949b3..14f6da83be2 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -87,7 +87,7 @@ class BONE_PT_transform(BoneButtonsPanel, Panel): row.use_property_decorate = False row.prop(pchan, "lock_rotation", text="", emboss=False, icon='DECORATE_UNLOCKED') row = layout.row(align=True) - row.prop(pchan, "rotation_mode", text='Mode') + row.prop(pchan, "rotation_mode", text="Mode") row.label(text="", icon='BLANK1') col = layout.column() @@ -403,9 +403,9 @@ class BONE_PT_inverse_kinematics(BoneButtonsPanel, Panel): col.prop(pchan, "ik_rotation_weight", text="IK Rotation Weight", slider=True) col.active = active # not supported yet - #row = layout.row() - #row.prop(pchan, "use_ik_linear_control", text="Joint Size") - #row.prop(pchan, "ik_linear_weight", text="Weight", slider=True) + # row = layout.row() + # row.prop(pchan, "use_ik_linear_control", text="Joint Size") + # row.prop(pchan, "ik_linear_weight", text="Weight", slider=True) class BONE_PT_deform(BoneButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_data_curves.py b/release/scripts/startup/bl_ui/properties_data_curves.py index 1a353d8d9d5..e17d749acd5 100644 --- a/release/scripts/startup/bl_ui/properties_data_curves.py +++ b/release/scripts/startup/bl_ui/properties_data_curves.py @@ -12,7 +12,7 @@ class DataButtonsPanel: @classmethod def poll(cls, context): engine = context.scene.render.engine - return hasattr(context, 'curves') and context.curves and (engine in cls.COMPAT_ENGINES) + return hasattr(context, "curves") and context.curves and (engine in cls.COMPAT_ENGINES) class DATA_PT_context_curves(DataButtonsPanel, Panel): @@ -73,8 +73,8 @@ class CURVES_MT_add_attribute(Menu): layout = self.layout curves = context.curves - self.add_standard_attribute(layout, curves, 'radius', 'FLOAT', 'POINT') - self.add_standard_attribute(layout, curves, 'color', 'FLOAT_COLOR', 'POINT') + self.add_standard_attribute(layout, curves, "radius", 'FLOAT', 'POINT') + self.add_standard_attribute(layout, curves, "color", 'FLOAT_COLOR', 'POINT') layout.separator() @@ -102,8 +102,8 @@ class CURVES_UL_attributes(UIList): return flags, indices def draw_item(self, _context, layout, _data, attribute, _icon, _active_data, _active_propname, _index): - data_type = attribute.bl_rna.properties['data_type'].enum_items[attribute.data_type] - domain = attribute.bl_rna.properties['domain'].enum_items[attribute.domain] + data_type = attribute.bl_rna.properties["data_type"].enum_items[attribute.data_type] + domain = attribute.bl_rna.properties["domain"].enum_items[attribute.domain] split = layout.split(factor=0.5) split.emboss = 'NONE' diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index e390b9cb6d4..bf85c4ac533 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -551,7 +551,7 @@ class MESH_UL_attributes(UIList): return flags, indices def draw_item(self, _context, layout, _data, attribute, _icon, _active_data, _active_propname, _index): - data_type = attribute.bl_rna.properties['data_type'].enum_items[attribute.data_type] + data_type = attribute.bl_rna.properties["data_type"].enum_items[attribute.data_type] domain_name = self.display_domain_names.get(attribute.domain, "") @@ -658,7 +658,7 @@ class ColorAttributesListBase(): class MESH_UL_color_attributes(UIList, ColorAttributesListBase): def draw_item(self, _context, layout, data, attribute, _icon, _active_data, _active_propname, _index): - data_type = attribute.bl_rna.properties['data_type'].enum_items[attribute.data_type] + data_type = attribute.bl_rna.properties["data_type"].enum_items[attribute.data_type] domain_name = self.display_domain_names.get(attribute.domain, "") diff --git a/release/scripts/startup/bl_ui/properties_data_pointcloud.py b/release/scripts/startup/bl_ui/properties_data_pointcloud.py index 09639e9d69b..db1b83f0cf4 100644 --- a/release/scripts/startup/bl_ui/properties_data_pointcloud.py +++ b/release/scripts/startup/bl_ui/properties_data_pointcloud.py @@ -12,7 +12,7 @@ class DataButtonsPanel: @classmethod def poll(cls, context): engine = context.scene.render.engine - return hasattr(context, 'pointcloud') and context.pointcloud and (engine in cls.COMPAT_ENGINES) + return hasattr(context, "pointcloud") and context.pointcloud and (engine in cls.COMPAT_ENGINES) class DATA_PT_context_pointcloud(DataButtonsPanel, Panel): @@ -53,10 +53,10 @@ class POINTCLOUD_MT_add_attribute(Menu): layout = self.layout pointcloud = context.pointcloud - self.add_standard_attribute(layout, pointcloud, 'radius', 'FLOAT', 'POINT') - self.add_standard_attribute(layout, pointcloud, 'color', 'FLOAT_COLOR', 'POINT') - self.add_standard_attribute(layout, pointcloud, 'id', 'INT', 'POINT') - self.add_standard_attribute(layout, pointcloud, 'velocity', 'FLOAT_VECTOR', 'POINT') + self.add_standard_attribute(layout, pointcloud, "radius", 'FLOAT', 'POINT') + self.add_standard_attribute(layout, pointcloud, "color", 'FLOAT_COLOR', 'POINT') + self.add_standard_attribute(layout, pointcloud, "id", 'INT', 'POINT') + self.add_standard_attribute(layout, pointcloud, "velocity", 'FLOAT_VECTOR', 'POINT') layout.separator() @@ -84,7 +84,7 @@ class POINTCLOUD_UL_attributes(UIList): return flags, indices def draw_item(self, _context, layout, _data, attribute, _icon, _active_data, _active_propname, _index): - data_type = attribute.bl_rna.properties['data_type'].enum_items[attribute.data_type] + data_type = attribute.bl_rna.properties["data_type"].enum_items[attribute.data_type] split = layout.split(factor=0.75) split.emboss = 'NONE' diff --git a/release/scripts/startup/bl_ui/properties_data_volume.py b/release/scripts/startup/bl_ui/properties_data_volume.py index 1aa2faad7b8..148bb60de85 100644 --- a/release/scripts/startup/bl_ui/properties_data_volume.py +++ b/release/scripts/startup/bl_ui/properties_data_volume.py @@ -68,7 +68,7 @@ class DATA_PT_volume_file(DataButtonsPanel, Panel): class VOLUME_UL_grids(UIList): def draw_item(self, _context, layout, _data, grid, _icon, _active_data, _active_propname, _index): name = grid.name - data_type = grid.bl_rna.properties['data_type'].enum_items[grid.data_type] + data_type = grid.bl_rna.properties["data_type"].enum_items[grid.data_type] layout.emboss = 'NONE' layout.label(text=name) diff --git a/release/scripts/startup/bl_ui/properties_output.py b/release/scripts/startup/bl_ui/properties_output.py index c97d7579a81..00c81d0dc87 100644 --- a/release/scripts/startup/bl_ui/properties_output.py +++ b/release/scripts/startup/bl_ui/properties_output.py @@ -324,7 +324,7 @@ class RENDER_PT_output_color_management(RenderOutputButtonsPanel, Panel): col = flow.column() if image_settings.has_linear_colorspace: - if hasattr(owner, 'linear_colorspace_settings'): + if hasattr(owner, "linear_colorspace_settings"): col.prop(owner.linear_colorspace_settings, "name", text="Color Space") else: col.prop(owner.display_settings, "display_device") diff --git a/release/scripts/startup/bl_ui/space_console.py b/release/scripts/startup/bl_ui/space_console.py index e9d1fc516ae..4f8e740d680 100644 --- a/release/scripts/startup/bl_ui/space_console.py +++ b/release/scripts/startup/bl_ui/space_console.py @@ -31,10 +31,10 @@ class CONSOLE_MT_view(Menu): layout = self.layout props = layout.operator("wm.context_cycle_int", text="Zoom In") - props.data_path = 'space_data.font_size' + props.data_path = "space_data.font_size" props.reverse = False props = layout.operator("wm.context_cycle_int", text="Zoom Out") - props.data_path = 'space_data.font_size' + props.data_path = "space_data.font_size" props.reverse = True layout.separator() @@ -62,7 +62,7 @@ class CONSOLE_MT_language(Menu): layout = self.layout layout.column() - # Collect modules with 'console_*.execute' + # Collect modules with `console_*.execute`. languages = [] for modname, mod in sys.modules.items(): if modname.startswith("console_") and hasattr(mod, "execute"): diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 1913c809ec5..99b33840051 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -550,7 +550,7 @@ class DOPESHEET_PT_custom_props_action(PropertyPanel, Panel): bl_space_type = 'DOPESHEET_EDITOR' bl_category = "Action" bl_region_type = 'UI' - bl_context = 'data' + bl_context = "data" _context_path = "active_action" _property_type = bpy.types.Action diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index 84aeacea03c..d0f17c582d5 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -742,7 +742,7 @@ class IMAGE_HT_header(Header): # Snap. snap_uv_element = tool_settings.snap_uv_element - act_snap_uv_element = tool_settings.bl_rna.properties['snap_uv_element'].enum_items[snap_uv_element] + act_snap_uv_element = tool_settings.bl_rna.properties["snap_uv_element"].enum_items[snap_uv_element] row = layout.row(align=True) row.prop(tool_settings, "use_snap_uv", text="") diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 010dbf5b099..bf8a39ea26f 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -41,7 +41,7 @@ class NODE_HT_header(Header): layout.template_header() - # Now expanded via the 'ui_type' + # Now expanded via the `ui_type`. # layout.prop(snode, "tree_type", text="") if snode.tree_type == 'ShaderNodeTree': @@ -661,7 +661,7 @@ class NODE_PT_active_node_properties(Panel): ) def show_socket_input(self, socket): - return hasattr(socket, 'draw') and socket.enabled and not socket.is_linked + return hasattr(socket, "draw") and socket.enabled and not socket.is_linked class NODE_PT_texture_mapping(Panel): @@ -961,7 +961,7 @@ def node_panel(cls): node_cls.bl_space_type = 'NODE_EDITOR' node_cls.bl_region_type = 'UI' node_cls.bl_category = "Options" - if hasattr(node_cls, 'bl_parent_id'): + if hasattr(node_cls, "bl_parent_id"): node_cls.bl_parent_id = 'NODE_' + node_cls.bl_parent_id return node_cls diff --git a/release/scripts/startup/bl_ui/space_toolsystem_common.py b/release/scripts/startup/bl_ui/space_toolsystem_common.py index ddffbc2b827..1f950ce1611 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_common.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_common.py @@ -51,8 +51,8 @@ ToolDef = namedtuple( "idname", # The name to display in the interface. "label", - # Description (for tool-tip), when not set, use the description of 'operator', - # may be a string or a 'function(context, item, key-map) -> string'. + # Description (for tool-tip), when not set, use the description of `operator`, + # may be a string or a `function(context, item, key-map) -> string`. "description", # The name of the icon to use (found in `release/datafiles/icons`) or None for no icon. "icon", @@ -88,7 +88,7 @@ ToolDef = namedtuple( # Note that this isn't used for Blender's built in tools which use the built-in key-map. # Keep this functionality since it's likely useful for add-on key-maps. # - # Warning: currently 'from_dict' this is a list of one item, + # Warning: currently `from_dict` this is a list of one item, # so internally we can swap the key-map function for the key-map itself. # This isn't very nice and may change, tool definitions shouldn't care about this. "keymap", @@ -256,7 +256,7 @@ class ToolSelectPanelHelper: # tool flattening # - # usually 'tools' is already expanded into ToolDef + # usually 'tools' is already expanded into `ToolDef` # but when registering a tool, this can still be a function # (_tools_flatten is usually called with cls.tools_from_context(context) # [that already yields from the function]) @@ -792,7 +792,7 @@ class ToolSelectPanelHelper: item, tool, icon_value = cls._tool_get_active(context, space_type, mode, with_icon=True) if item is None: return None - # Note: we could show 'item.text' here but it makes the layout jitter when switching tools. + # NOTE: we could show `item.text` here but it makes the layout jitter when switching tools. # Add some spacing since the icon is currently assuming regular small icon size. if show_tool_icon_always: layout.label(text=" " + iface_(item.label, "Operator"), icon_value=icon_value) diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index c18c2fe4b01..fb6136154c8 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -2706,7 +2706,7 @@ class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel): ) # Private tools dictionary, store data to implement `tools_all` & `tools_from_context`. - # The keys match image spaces modes: 'context.space_data.mode'. + # The keys match image spaces modes: `context.space_data.mode`. # The values represent the tools, see `ToolSelectPanelHelper` for details. _tools = { None: [ @@ -2892,7 +2892,7 @@ class VIEW3D_PT_tools_active(ToolSelectPanelHelper, Panel): ) # Private tools dictionary, store data to implement `tools_all` & `tools_from_context`. - # The keys match object-modes from: 'context.mode'. + # The keys match object-modes from: `context.mode`. # The values represent the tools, see `ToolSelectPanelHelper` for details. _tools = { None: [ @@ -3230,7 +3230,7 @@ class SEQUENCER_PT_tools_active(ToolSelectPanelHelper, Panel): ) # Private tools dictionary, store data to implement `tools_all` & `tools_from_context`. - # The keys match sequence editors view type: 'context.space_data.view_type'. + # The keys match sequence editors view type: `context.space_data.view_type`. # The values represent the tools, see `ToolSelectPanelHelper` for details. _tools = { None: [ diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 44bc807c7dd..49b07739e93 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -1286,7 +1286,7 @@ class ThemeGenericClassGenerator: def generate_panel_classes_from_theme_areas(): from bpy.types import Theme - for theme_area in Theme.bl_rna.properties['theme_area'].enum_items_static: + for theme_area in Theme.bl_rna.properties["theme_area"].enum_items_static: if theme_area.identifier in {'USER_INTERFACE', 'STYLE', 'BONE_COLOR_SETS'}: continue diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 3e0dafac887..791e7233b49 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -70,7 +70,7 @@ class VIEW3D_HT_tool_header(Header): layout.popover("VIEW3D_PT_tools_brush_falloff") layout.popover("VIEW3D_PT_tools_brush_display") - # Note: general mode options should be added to 'draw_mode_settings'. + # NOTE: general mode options should be added to `draw_mode_settings`. if tool_mode == 'SCULPT': if is_valid_context: draw_3d_brush_settings(layout, tool_mode) @@ -889,7 +889,7 @@ class VIEW3D_HT_header(Header): row = layout.row() row.active = (object_mode == 'EDIT') or (shading.type in {'WIREFRAME', 'SOLID'}) - # While exposing 'shading.show_xray(_wireframe)' is correct. + # While exposing `shading.show_xray(_wireframe)` is correct. # this hides the key shortcut from users: T70433. if has_pose_mode: draw_depressed = overlay.show_xray_bone @@ -2290,9 +2290,9 @@ class VIEW3D_MT_add(Menu): def draw(self, context): layout = self.layout - # note, don't use 'EXEC_SCREEN' or operators won't get the 'v3d' context. + # NOTE: don't use 'EXEC_SCREEN' or operators won't get the `v3d` context. - # Note: was EXEC_AREA, but this context does not have the 'rv3d', which prevents + # NOTE: was `EXEC_AREA`, but this context does not have the `rv3d`, which prevents # "align_view" to work on first call (see T32719). layout.operator_context = 'EXEC_REGION_WIN' @@ -3291,23 +3291,23 @@ class VIEW3D_MT_mask(Menu): layout.separator() - props = layout.operator("sculpt.mask_filter", text='Smooth Mask') + props = layout.operator("sculpt.mask_filter", text="Smooth Mask") props.filter_type = 'SMOOTH' - props = layout.operator("sculpt.mask_filter", text='Sharpen Mask') + props = layout.operator("sculpt.mask_filter", text="Sharpen Mask") props.filter_type = 'SHARPEN' - props = layout.operator("sculpt.mask_filter", text='Grow Mask') + props = layout.operator("sculpt.mask_filter", text="Grow Mask") props.filter_type = 'GROW' - props = layout.operator("sculpt.mask_filter", text='Shrink Mask') + props = layout.operator("sculpt.mask_filter", text="Shrink Mask") props.filter_type = 'SHRINK' - props = layout.operator("sculpt.mask_filter", text='Increase Contrast') + props = layout.operator("sculpt.mask_filter", text="Increase Contrast") props.filter_type = 'CONTRAST_INCREASE' props.auto_iteration_count = False - props = layout.operator("sculpt.mask_filter", text='Decrease Contrast') + props = layout.operator("sculpt.mask_filter", text="Decrease Contrast") props.filter_type = 'CONTRAST_DECREASE' props.auto_iteration_count = False @@ -3352,13 +3352,13 @@ class VIEW3D_MT_face_sets(Menu): def draw(self, _context): layout = self.layout - op = layout.operator("sculpt.face_sets_create", text='Face Set from Masked') + op = layout.operator("sculpt.face_sets_create", text="Face Set from Masked") op.mode = 'MASKED' - op = layout.operator("sculpt.face_sets_create", text='Face Set from Visible') + op = layout.operator("sculpt.face_sets_create", text="Face Set from Visible") op.mode = 'VISIBLE' - op = layout.operator("sculpt.face_sets_create", text='Face Set from Edit Mode Selection') + op = layout.operator("sculpt.face_sets_create", text="Face Set from Edit Mode Selection") op.mode = 'SELECTION' layout.separator() @@ -3367,10 +3367,10 @@ class VIEW3D_MT_face_sets(Menu): layout.separator() - op = layout.operator("sculpt.face_set_edit", text='Grow Face Set') + op = layout.operator("sculpt.face_set_edit", text="Grow Face Set") op.mode = 'GROW' - op = layout.operator("sculpt.face_set_edit", text='Shrink Face Set') + op = layout.operator("sculpt.face_set_edit", text="Shrink Face Set") op.mode = 'SHRINK' layout.separator() @@ -3389,18 +3389,18 @@ class VIEW3D_MT_face_sets(Menu): layout.separator() - op = layout.operator("mesh.face_set_extract", text='Extract Face Set') + op = layout.operator("mesh.face_set_extract", text="Extract Face Set") layout.separator() - op = layout.operator("sculpt.face_set_change_visibility", text='Invert Visible Face Sets') + op = layout.operator("sculpt.face_set_change_visibility", text="Invert Visible Face Sets") op.mode = 'INVERT' - op = layout.operator("sculpt.reveal_all", text='Show All Face Sets') + op = layout.operator("sculpt.reveal_all", text="Show All Face Sets") layout.separator() - op = layout.operator("sculpt.face_sets_randomize_colors", text='Randomize Colors') + op = layout.operator("sculpt.face_sets_randomize_colors", text="Randomize Colors") class VIEW3D_MT_sculpt_set_pivot(Menu): @@ -3431,31 +3431,31 @@ class VIEW3D_MT_face_sets_init(Menu): def draw(self, _context): layout = self.layout - op = layout.operator("sculpt.face_sets_init", text='By Loose Parts') + op = layout.operator("sculpt.face_sets_init", text="By Loose Parts") op.mode = 'LOOSE_PARTS' - op = layout.operator("sculpt.face_sets_init", text='By Face Set Boundaries') + op = layout.operator("sculpt.face_sets_init", text="By Face Set Boundaries") op.mode = 'FACE_SET_BOUNDARIES' - op = layout.operator("sculpt.face_sets_init", text='By Materials') + op = layout.operator("sculpt.face_sets_init", text="By Materials") op.mode = 'MATERIALS' - op = layout.operator("sculpt.face_sets_init", text='By Normals') + op = layout.operator("sculpt.face_sets_init", text="By Normals") op.mode = 'NORMALS' - op = layout.operator("sculpt.face_sets_init", text='By UV Seams') + op = layout.operator("sculpt.face_sets_init", text="By UV Seams") op.mode = 'UV_SEAMS' - op = layout.operator("sculpt.face_sets_init", text='By Edge Creases') + op = layout.operator("sculpt.face_sets_init", text="By Edge Creases") op.mode = 'CREASES' - op = layout.operator("sculpt.face_sets_init", text='By Edge Bevel Weight') + op = layout.operator("sculpt.face_sets_init", text="By Edge Bevel Weight") op.mode = 'BEVEL_WEIGHT' - op = layout.operator("sculpt.face_sets_init", text='By Sharp Edges') + op = layout.operator("sculpt.face_sets_init", text="By Sharp Edges") op.mode = 'SHARP_EDGES' - op = layout.operator("sculpt.face_sets_init", text='By Face Maps') + op = layout.operator("sculpt.face_sets_init", text="By Face Maps") op.mode = 'FACE_MAPS' @@ -3465,13 +3465,13 @@ class VIEW3D_MT_random_mask(Menu): def draw(self, _context): layout = self.layout - op = layout.operator("sculpt.mask_init", text='Per Vertex') + op = layout.operator("sculpt.mask_init", text="Per Vertex") op.mode = 'RANDOM_PER_VERTEX' - op = layout.operator("sculpt.mask_init", text='Per Face Set') + op = layout.operator("sculpt.mask_init", text="Per Face Set") op.mode = 'RANDOM_PER_FACE_SET' - op = layout.operator("sculpt.mask_init", text='Per Loose Part') + op = layout.operator("sculpt.mask_init", text="Per Loose Part") op.mode = 'RANDOM_PER_LOOSE_PART' @@ -5500,23 +5500,23 @@ class VIEW3D_MT_sculpt_mask_edit_pie(Menu): layout = self.layout pie = layout.menu_pie() - op = pie.operator("paint.mask_flood_fill", text='Invert Mask') + op = pie.operator("paint.mask_flood_fill", text="Invert Mask") op.mode = 'INVERT' - op = pie.operator("paint.mask_flood_fill", text='Clear Mask') + op = pie.operator("paint.mask_flood_fill", text="Clear Mask") op.mode = 'VALUE' op.value = 0.0 - op = pie.operator("sculpt.mask_filter", text='Smooth Mask') + op = pie.operator("sculpt.mask_filter", text="Smooth Mask") op.filter_type = 'SMOOTH' - op = pie.operator("sculpt.mask_filter", text='Sharpen Mask') + op = pie.operator("sculpt.mask_filter", text="Sharpen Mask") op.filter_type = 'SHARPEN' - op = pie.operator("sculpt.mask_filter", text='Grow Mask') + op = pie.operator("sculpt.mask_filter", text="Grow Mask") op.filter_type = 'GROW' - op = pie.operator("sculpt.mask_filter", text='Shrink Mask') + op = pie.operator("sculpt.mask_filter", text="Shrink Mask") op.filter_type = 'SHRINK' - op = pie.operator("sculpt.mask_filter", text='Increase Contrast') + op = pie.operator("sculpt.mask_filter", text="Increase Contrast") op.filter_type = 'CONTRAST_INCREASE' op.auto_iteration_count = False - op = pie.operator("sculpt.mask_filter", text='Decrease Contrast') + op = pie.operator("sculpt.mask_filter", text="Decrease Contrast") op.filter_type = 'CONTRAST_DECREASE' op.auto_iteration_count = False @@ -5565,16 +5565,16 @@ class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu): layout = self.layout pie = layout.menu_pie() - op = pie.operator("sculpt.face_sets_create", text='Face Set from Masked') + op = pie.operator("sculpt.face_sets_create", text="Face Set from Masked") op.mode = 'MASKED' - op = pie.operator("sculpt.face_sets_create", text='Face Set from Visible') + op = pie.operator("sculpt.face_sets_create", text="Face Set from Visible") op.mode = 'VISIBLE' - op = pie.operator("sculpt.face_set_change_visibility", text='Invert Visible') + op = pie.operator("sculpt.face_set_change_visibility", text="Invert Visible") op.mode = 'INVERT' - op = pie.operator("sculpt.reveal_all", text='Show All') + op = pie.operator("sculpt.reveal_all", text="Show All") class VIEW3D_MT_wpaint_vgroup_lock_pie(Menu): @@ -6974,9 +6974,9 @@ class VIEW3D_PT_snapping(Panel): col.prop(tool_settings, "use_snap_project") if 'FACE_NEAREST' in snap_elements: - col.prop(tool_settings, 'use_snap_to_same_target') + col.prop(tool_settings, "use_snap_to_same_target") if object_mode == 'EDIT': - col.prop(tool_settings, 'snap_face_nearest_steps') + col.prop(tool_settings, "snap_face_nearest_steps") if 'VOLUME' in snap_elements: col.prop(tool_settings, "use_snap_peel_object") diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 8ebc385a8ee..c6d6a77eec2 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1084,7 +1084,7 @@ class VIEW3D_PT_tools_weightpaint_symmetry(Panel, View3DPaintPanel): wpaint = tool_settings.weight_paint mesh = context.object.data - layout.prop(mesh, 'use_mirror_vertex_groups') + layout.prop(mesh, "use_mirror_vertex_groups") draw_vpaint_symmetry(layout, wpaint, context.object) diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py index 4390e6f0959..37032657d7a 100644 --- a/release/scripts/startup/keyingsets_builtins.py +++ b/release/scripts/startup/keyingsets_builtins.py @@ -597,7 +597,7 @@ class BUILTIN_KSI_DeltaRotation(KeyingSetInfo): path = keyingsets_utils.path_add_property(base_path, "delta_rotation_quaternion") elif data.rotation_mode == 'AXIS_ANGLE': # XXX: for now, this is not available yet - #path = path_add_property(base_path, "delta_rotation_axis_angle") + # path = path_add_property(base_path, "delta_rotation_axis_angle") return else: path = keyingsets_utils.path_add_property(base_path, "delta_rotation_euler") @@ -637,7 +637,7 @@ class BUILTIN_KSI_DeltaScale(KeyingSetInfo): ############################### -# Note that this controls order of options in 'insert keyframe' menu. +# Note that this controls order of options in `insert keyframe` menu. # Better try to keep some logical order here beyond mere alphabetical one, also because of menu entries shortcut. # See also T51867. classes = ( From 14fc02f91d8d4ca9116f4397e8dd6251f815fdec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Jan 2023 13:57:21 +1100 Subject: [PATCH 0448/1522] Cleanup: spelling in comments --- intern/cycles/device/metal/device_impl.mm | 7 +++---- intern/guardedalloc/intern/memory_usage.cc | 6 +++--- source/blender/blenkernel/BKE_anonymous_attribute_id.hh | 2 +- source/blender/editors/animation/anim_channels_edit.c | 2 +- source/blender/editors/space_node/clipboard.cc | 2 +- source/blender/editors/space_node/node_relationships.cc | 2 +- .../functions/intern/lazy_function_graph_executor.cc | 2 +- .../gpencil_modifiers/intern/lineart/lineart_cpu.cc | 2 +- .../blender/nodes/intern/geometry_nodes_lazy_function.cc | 2 +- source/blender/windowmanager/intern/wm_keymap.c | 2 +- 10 files changed, 14 insertions(+), 15 deletions(-) diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm index 85486c132d8..f9fa54b30ce 100644 --- a/intern/cycles/device/metal/device_impl.mm +++ b/intern/cycles/device/metal/device_impl.mm @@ -22,7 +22,7 @@ class MetalDevice; thread_mutex MetalDevice::existing_devices_mutex; std::map MetalDevice::active_device_ids; -/* Thread-safe device access for async work. Calling code must pass an appropriatelty scoped lock +/* Thread-safe device access for async work. Calling code must pass an appropriately scoped lock * to existing_devices_mutex to safeguard against destruction of the returned instance. */ MetalDevice *MetalDevice::get_device_by_ID(int ID, thread_scoped_lock &existing_devices_mutex_lock) { @@ -377,7 +377,7 @@ bool MetalDevice::load_kernels(const uint _kernel_features) /* Only request generic kernels if they aren't cached in memory. */ if (make_source_and_check_if_compile_needed(PSO_GENERIC)) { - /* If needed, load them asynchronously in order to responsively message progess to the user. */ + /* If needed, load them asynchronously in order to responsively message progress to the user. */ int this_device_id = this->device_id; auto compile_kernels_fn = ^() { compile_and_load(this_device_id, PSO_GENERIC); @@ -401,8 +401,7 @@ bool MetalDevice::make_source_and_check_if_compile_needed(MetalPipelineType pso_ void MetalDevice::compile_and_load(int device_id, MetalPipelineType pso_type) { /* Thread-safe front-end compilation. Typically the MSL->AIR compilation can take a few seconds, - * so we avoid blocking device teardown if the user cancels a render immediately. - */ + * so we avoid blocking device tear-down if the user cancels a render immediately. */ id mtlDevice; string source; diff --git a/intern/guardedalloc/intern/memory_usage.cc b/intern/guardedalloc/intern/memory_usage.cc index bb557eeda97..d4abff32f79 100644 --- a/intern/guardedalloc/intern/memory_usage.cc +++ b/intern/guardedalloc/intern/memory_usage.cc @@ -81,7 +81,7 @@ struct Global { * To solve this, the memory counts are added to these global counters when the thread * exists. The global counters are also used when the entire process starts to exit, because the * #Local data of the main thread is already destructed when the leak detection happens (during - * destruction of static variables which happens after destruction of threadlocals). + * destruction of static variables which happens after destruction of thread-locals). */ std::atomic mem_in_use_outside_locals = 0; /** @@ -153,7 +153,7 @@ Local::~Local() if (this->is_main) { /* The main thread started shutting down. Use global counters from now on to avoid accessing - * threadlocals after they have been destructed. */ + * thread-locals after they have been destructed. */ use_local_counters.store(false, std::memory_order_relaxed); } /* Helps to detect when thread locals are accidentally accessed after destruction. */ @@ -179,7 +179,7 @@ static void update_global_peak() void memory_usage_init() { - /* Makes sure that the static and threadlocal variables on the main thread are initialized. */ + /* Makes sure that the static and thread-local variables on the main thread are initialized. */ get_local_data(); } diff --git a/source/blender/blenkernel/BKE_anonymous_attribute_id.hh b/source/blender/blenkernel/BKE_anonymous_attribute_id.hh index f9b6e2ca543..b738ff50604 100644 --- a/source/blender/blenkernel/BKE_anonymous_attribute_id.hh +++ b/source/blender/blenkernel/BKE_anonymous_attribute_id.hh @@ -27,7 +27,7 @@ namespace blender::bke { * additional information for anonymous attributes on disk (like which node created it). This * information can then be used to map stored attributes to their run-time counterpart. * - * Once created, #AnonymousAttributeID is immutable. Also it is intrinsicly reference counted so + * Once created, #AnonymousAttributeID is immutable. Also it is intrinsically reference counted so * that it can have shared ownership. `std::shared_ptr` can't be used for that purpose here, * because that is not available in C code. If possible, the #AutoAnonymousAttributeID wrapper * should be used to avoid manual reference counting in C++ code. diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index c612ab10d65..dc1fab35945 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -2845,7 +2845,7 @@ static bool rename_anim_channels(bAnimContext *ac, int channel_index) int filter; bool success = false; - /* Filter relevant channels (note that greasepencil/annotations are not displayed in Graph + /* Filter relevant channels (note that grease-pencil/annotations are not displayed in Graph * Editor). */ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS); if (ELEM(ac->datatype, ANIMCONT_FCURVES, ANIMCONT_NLA)) { diff --git a/source/blender/editors/space_node/clipboard.cc b/source/blender/editors/space_node/clipboard.cc index aa601cc4322..beda081eec8 100644 --- a/source/blender/editors/space_node/clipboard.cc +++ b/source/blender/editors/space_node/clipboard.cc @@ -86,7 +86,7 @@ struct NodeClipboard { Map &node_map, Map &socket_map) { - /* No ID refcounting, this node is virtual, + /* No ID reference-counting, this node is virtual, * detached from any actual Blender data currently. */ bNode *new_node = bke::node_copy_with_mapping( nullptr, node, LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_CREATE_NO_MAIN, false, socket_map); diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index d7e73761667..9fc18fc2235 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -56,7 +56,7 @@ struct NodeInsertOfsData { bNodeTree *ntree; bNode *insert; /* Inserted node. */ - bNode *prev, *next; /* Prev/next node in the chain. */ + bNode *prev, *next; /* Previous/next node in the chain. */ bNode *insert_parent; wmTimer *anim_timer; diff --git a/source/blender/functions/intern/lazy_function_graph_executor.cc b/source/blender/functions/intern/lazy_function_graph_executor.cc index ab7dfba196a..c7688f61460 100644 --- a/source/blender/functions/intern/lazy_function_graph_executor.cc +++ b/source/blender/functions/intern/lazy_function_graph_executor.cc @@ -1074,7 +1074,7 @@ class Executor { bool try_enable_multi_threading() { #ifndef WITH_TBB - /* The non-tbb task pool has the property that it immediately executes tasks under some + /* The non-TBB task pool has the property that it immediately executes tasks under some * circumstances. This is not supported here because tasks might be scheduled while another * node is in the middle of being executed on the same thread. */ return false; diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index 93c1571c613..54d7d5750de 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -2453,7 +2453,7 @@ static void lineart_object_load_single_instance(LineartData *ld, if ((!use_mesh) || use_mesh->edit_mesh) { /* If the object is being edited, then the mesh is not evaluated fully into the final * result, do not load them. This could be caused by incorrect evaluation order due to - * the way line art uses depsgraph.See T102612 for explaination of this workaround. */ + * the way line art uses depsgraph.See T102612 for explanation of this workaround. */ return; } } diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index bfda854d4c2..9b26756f2ff 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -1013,7 +1013,7 @@ class LazyFunctionForAnonymousAttributeSetExtract : public lf::LazyFunction { }; /** - * Conditionally joines multiple attribute sets. Each input attribute set can be disabled with a + * Conditionally joins multiple attribute sets. Each input attribute set can be disabled with a * corresponding boolean input. */ class LazyFunctionForAnonymousAttributeSetJoin : public lf::LazyFunction { diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 9c724916dd5..0ea878cec3b 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -159,7 +159,7 @@ static void wm_keymap_item_properties_update_ot_from_list(ListBase *km_lb) static bool wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b) { return (STREQ(a->idname, b->idname) && - /* We do not really care about which Main we pass here, tbh. */ + /* We do not really care about which Main we pass here, TBH. */ RNA_struct_equals(G_MAIN, a->ptr, b->ptr, RNA_EQ_UNSET_MATCH_NONE) && (a->flag & KMI_INACTIVE) == (b->flag & KMI_INACTIVE) && a->propvalue == b->propvalue); } From 8d0c98740ad3aab973933b001b6578a4afa53119 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 6 Jan 2023 14:03:33 +1100 Subject: [PATCH 0449/1522] Cleanup: remove unused OffsetGpencilModifierData.object Added as part of D15106 but was not used anywhere. --- source/blender/makesdna/DNA_gpencil_modifier_types.h | 1 - source/blender/makesrna/intern/rna_gpencil_modifier.c | 1 - 2 files changed, 2 deletions(-) diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h index 3f56a25a19b..b503a76be05 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_types.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -770,7 +770,6 @@ typedef enum eOffsetGpencil_Mode { typedef struct OffsetGpencilModifierData { GpencilModifierData modifier; - struct Object *object; /** Material for filtering. */ struct Material *material; /** Layer name. */ diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index bd25f26610a..e6c238e79ea 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -434,7 +434,6 @@ RNA_GP_MOD_OBJECT_SET(WeightProx, object, OB_EMPTY); RNA_GP_MOD_OBJECT_SET(Shrinkwrap, target, OB_MESH); RNA_GP_MOD_OBJECT_SET(Shrinkwrap, aux_target, OB_MESH); RNA_GP_MOD_OBJECT_SET(Build, object, OB_EMPTY); -RNA_GP_MOD_OBJECT_SET(Offset, object, OB_EMPTY); # undef RNA_GP_MOD_OBJECT_SET From 280502e630e99a6723861a9cae156fabd53a7eb1 Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Fri, 6 Jan 2023 17:10:28 +1300 Subject: [PATCH 0450/1522] Fix T103469: improve uv cylinder projection and uv sphere projection Multiple improvements to UV Cylinder and UV Sphere projection including: * New option "Pinch" or "Fan" to improve unwrap of faces at the poles. * Support for "Polar ZY" option on "View On Equator" and "Align To Object" * Better handling of inputs with round-off error. * Improved handling of faces touching the unit square border. * Improved handling of very wide quads spanning the right hand border. * Improved accuracy near to (0, 0). * Code cleanup and simplification. Differential Revision: https://developer.blender.org/D16869 --- source/blender/blenlib/BLI_math_geom.h | 4 +- source/blender/blenlib/intern/math_geom.c | 68 +++-- .../editors/uvedit/uvedit_unwrap_ops.c | 268 +++++++++++------- 3 files changed, 207 insertions(+), 133 deletions(-) diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index d056c42e019..e24f3c3bde8 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -1164,8 +1164,8 @@ void box_minmax_bounds_m4(float min[3], float max[3], float boundbox[2][3], floa /** \name Mapping * \{ */ -void map_to_tube(float *r_u, float *r_v, float x, float y, float z); -void map_to_sphere(float *r_u, float *r_v, float x, float y, float z); +bool map_to_tube(float *r_u, float *r_v, float x, float y, float z); +bool map_to_sphere(float *r_u, float *r_v, float x, float y, float z); void map_to_plane_v2_v3v3(float r_co[2], const float co[3], const float no[3]); void map_to_plane_axis_angle_v2_v3v3fl(float r_co[2], const float co[3], diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 08152976f7d..415e21cd272 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -4914,39 +4914,59 @@ void box_minmax_bounds_m4(float min[3], float max[3], float boundbox[2][3], floa /********************************** Mapping **********************************/ -void map_to_tube(float *r_u, float *r_v, const float x, const float y, const float z) +static float snap_coordinate(float u) { - float len; - - *r_v = (z + 1.0f) / 2.0f; - - len = sqrtf(x * x + y * y); - if (len > 0.0f) { - *r_u = (1.0f - (atan2f(x / len, y / len) / (float)M_PI)) / 2.0f; + /* Adjust a coordinate value `u` to obtain a value inside the (closed) unit interval. + * i.e. 0.0 <= snap_coordinate(u) <= 1.0. + * Due to round-off errors, it is possible that the value of `u` may be close to the boundary of + * the unit interval, but not exactly on it. In order to handle these cases, `snap_coordinate` + * checks whether `u` is within `epsilon` of the boundary, and if so, it snaps the return value + * to the boundary. */ + if (u < 0.0f) { + u += 1.0f; /* Get back into the unit interval. */ } - else { - *r_v = *r_u = 0.0f; /* to avoid un-initialized variables */ + BLI_assert(0.0f <= u); + BLI_assert(u <= 1.0f); + const float epsilon = 0.25f / 65536.0f; /* i.e. Quarter of a texel on a 65536 x 65536 texture. */ + if (u < epsilon) { + return 0.0f; /* `u` is close to 0, just return 0. */ } + if (1.0f - epsilon < u) { + return 1.0f; /* `u` is close to 1, just return 1. */ + } + return u; } -void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const float z) +bool map_to_tube(float *r_u, float *r_v, const float x, const float y, const float z) { - float len; - - len = sqrtf(x * x + y * y + z * z); - if (len > 0.0f) { - if (UNLIKELY(x == 0.0f && y == 0.0f)) { - *r_u = 0.0f; /* Otherwise domain error. */ - } - else { - *r_u = (1.0f - atan2f(x, y) / (float)M_PI) / 2.0f; - } - - *r_v = 1.0f - saacos(z / len) / (float)M_PI; + bool regular = true; + if (x * x + y * y < 1e-6f * 1e-6f) { + regular = false; /* We're too close to the cylinder's axis. */ + *r_u = 0.5f; } else { - *r_v = *r_u = 0.0f; /* to avoid un-initialized variables */ + /* The "Regular" case, just compute the coordinate. */ + *r_u = snap_coordinate(atan2f(x, -y) / (float)(2.0f * M_PI)); } + *r_v = (z + 1.0f) / 2.0f; + return regular; +} + +bool map_to_sphere(float *r_u, float *r_v, const float x, const float y, const float z) +{ + bool regular = true; + const float epsilon = 0.25f / 65536.0f; /* i.e. Quarter of a texel on a 65536 x 65536 texture. */ + const float len_xy = sqrtf(x * x + y * y); + if (len_xy <= fabsf(z) * epsilon) { + regular = false; /* We're on the line that runs through the north and south poles. */ + *r_u = 0.5f; + } + else { + /* The "Regular" case, just compute the coordinate. */ + *r_u = snap_coordinate(atan2f(x, -y) / (float)(2.0f * M_PI)); + } + *r_v = snap_coordinate(atan2f(len_xy, -z) / (float)M_PI); + return regular; } void map_to_plane_v2_v3v3(float r_co[2], const float co[3], const float no[3]) diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 18e920c55f4..0f8830a4521 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -1318,6 +1318,9 @@ void ED_uvedit_live_unwrap_end(short cancel) #define POLAR_ZX 0 #define POLAR_ZY 1 +#define PINCH 0 +#define FAN 1 + static void uv_map_transform_calc_bounds(BMEditMesh *em, float r_min[3], float r_max[3]) { BMFace *efa; @@ -1457,50 +1460,37 @@ static void uv_map_rotation_matrix_ex(float result[4][4], mul_m4_series(result, rotup, rotside, viewmatrix, rotobj); } -static void uv_map_rotation_matrix(float result[4][4], - RegionView3D *rv3d, - Object *ob, - float upangledeg, - float sideangledeg, - float radius) +static void uv_map_transform(bContext *C, wmOperator *op, float rotmat[3][3]) { - const float offset[4] = {0}; - uv_map_rotation_matrix_ex(result, rv3d, ob, upangledeg, sideangledeg, radius, offset); -} - -static void uv_map_transform(bContext *C, wmOperator *op, float rotmat[4][4]) -{ - /* context checks are messy here, making it work in both 3d view and uv editor */ Object *obedit = CTX_data_edit_object(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); - /* common operator properties */ - int align = RNA_enum_get(op->ptr, "align"); - int direction = RNA_enum_get(op->ptr, "direction"); - float radius = RNA_struct_find_property(op->ptr, "radius") ? RNA_float_get(op->ptr, "radius") : - 1.0f; - float upangledeg, sideangledeg; - if (direction == VIEW_ON_EQUATOR) { - upangledeg = 90.0f; - sideangledeg = 0.0f; - } - else { - upangledeg = 0.0f; - if (align == POLAR_ZY) { - sideangledeg = 0.0f; - } - else { - sideangledeg = 90.0f; - } - } + const int align = RNA_enum_get(op->ptr, "align"); + const int direction = RNA_enum_get(op->ptr, "direction"); + const float radius = RNA_struct_find_property(op->ptr, "radius") ? + RNA_float_get(op->ptr, "radius") : + 1.0f; - /* be compatible to the "old" sphere/cylinder mode */ + /* Be compatible to the "old" sphere/cylinder mode. */ if (direction == ALIGN_TO_OBJECT) { - unit_m4(rotmat); - } - else { - uv_map_rotation_matrix(rotmat, rv3d, obedit, upangledeg, sideangledeg, radius); + unit_m3(rotmat); + + if (align == POLAR_ZY) { + rotmat[0][0] = 0.0f; + rotmat[0][1] = 1.0f; + rotmat[1][0] = -1.0f; + rotmat[1][1] = 0.0f; + } + return; } + + const float up_angle_deg = (direction == VIEW_ON_EQUATOR) ? 90.0f : 0.0f; + const float side_angle_deg = (align == POLAR_ZY) == (direction == VIEW_ON_EQUATOR) ? 90.0f : + 0.0f; + const float offset[4] = {0}; + float rotmat4[4][4]; + uv_map_rotation_matrix_ex(rotmat4, rv3d, obedit, up_angle_deg, side_angle_deg, radius, offset); + copy_m3_m4(rotmat, rotmat4); } static void uv_transform_properties(wmOperatorType *ot, int radius) @@ -1521,6 +1511,12 @@ static void uv_transform_properties(wmOperatorType *ot, int radius) {0, NULL, 0, NULL, NULL}, }; + static const EnumPropertyItem pole_items[] = { + {PINCH, "PINCH", 0, "Pinch", "UVs are pinched at the poles"}, + {FAN, "FAN", 0, "Fan", "UVs are fanned at the poles"}, + {0, NULL, 0, NULL, NULL}, + }; + RNA_def_enum(ot->srna, "direction", direction_items, @@ -1530,9 +1526,10 @@ static void uv_transform_properties(wmOperatorType *ot, int radius) RNA_def_enum(ot->srna, "align", align_items, - VIEW_ON_EQUATOR, + POLAR_ZX, "Align", "How to determine rotation around the pole"); + RNA_def_enum(ot->srna, "pole", pole_items, PINCH, "Pole", "How to handle faces at the poles"); if (radius) { RNA_def_float(ot->srna, "radius", @@ -2730,55 +2727,120 @@ void UV_OT_reset(wmOperatorType *ot) /** \name Sphere UV Project Operator * \{ */ -static void uv_sphere_project(float target[2], - const float source[3], - const float center[3], - const float rotmat[4][4]) +static void uv_map_mirror(BMFace *efa, + const bool *regular, + const bool fan, + const int cd_loop_uv_offset) { - float pv[3]; + /* A heuristic to improve alignment of faces near the seam. + * In simple terms, we're looking for faces which span more + * than 0.5 units in the *u* coordinate. + * If we find such a face, we try and improve the unwrapping + * by adding (1.0, 0.0) onto some of the face's UVs. - sub_v3_v3v3(pv, source, center); - mul_m4_v3(rotmat, pv); + * Note that this is only a heuristic. The property we're + * attempting to maintain is that the winding of the face + * in UV space corresponds with the handedness of the face + * in 3D space w.r.t to the unwrapping. Even for triangles, + * that property is somewhat complicated to evaluate. + */ - map_to_sphere(&target[0], &target[1], pv[0], pv[1], pv[2]); - - /* split line is always zero */ - if (target[0] >= 1.0f) { - target[0] -= 1.0f; - } -} - -static void uv_map_mirror(BMEditMesh *em, BMFace *efa) -{ + float right_u = -1.0e30f; BMLoop *l; BMIter liter; - MLoopUV *luv; float **uvs = BLI_array_alloca(uvs, efa->len); - float dx; - int i, mi; - - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - - BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - uvs[i] = luv->uv; + int j; + BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + uvs[j] = luv->uv; + if (luv->uv[0] >= 1.0f) { + luv->uv[0] -= 1.0f; + } + right_u = max_ff(right_u, luv->uv[0]); } - mi = 0; - for (i = 1; i < efa->len; i++) { - if (uvs[i][0] > uvs[mi][0]) { - mi = i; + float left_u = 1.0e30f; + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + if (right_u <= luv->uv[0] + 0.5f) { + left_u = min_ff(left_u, luv->uv[0]); } } - for (i = 0; i < efa->len; i++) { - if (i != mi) { - dx = uvs[mi][0] - uvs[i][0]; - if (dx > 0.5f) { - uvs[i][0] += 1.0f; + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + if (luv->uv[0] + 0.5f < right_u) { + if (2 * luv->uv[0] + 1.0f < left_u + right_u) { + luv->uv[0] += 1.0f; } } } + if (!fan) { + return; + } + + /* Another heuristic, this time, we attempt to "fan" + * the UVs of faces which pass through one of the poles + * of the unwrapping. */ + + /* Need to recompute min and max. */ + float minmax_u[2] = {1.0e30f, -1.0e30f}; + int pole_count = 0; + for (int i = 0; i < efa->len; i++) { + if (regular[i]) { + minmax_u[0] = min_ff(minmax_u[0], uvs[i][0]); + minmax_u[1] = max_ff(minmax_u[1], uvs[i][0]); + } + else { + pole_count++; + } + } + if (pole_count == 0 || pole_count == efa->len) { + return; + } + for (int i = 0; i < efa->len; i++) { + if (regular[i]) { + continue; + } + float u = 0.0f; + float sum = 0.0f; + const int i_plus = (i + 1) % efa->len; + const int i_minus = (i + efa->len - 1) % efa->len; + if (regular[i_plus]) { + u += uvs[i_plus][0]; + sum += 1.0f; + } + if (regular[i_minus]) { + u += uvs[i_minus][0]; + sum += 1.0f; + } + if (sum == 0) { + u += minmax_u[0] + minmax_u[1]; + sum += 2.0f; + } + uvs[i][0] = u / sum; + } +} + +static void uv_sphere_project(BMFace *efa, + const float center[3], + const float rotmat[3][3], + const bool fan, + const int cd_loop_uv_offset) +{ + bool *regular = BLI_array_alloca(regular, efa->len); + int i; + BMLoop *l; + BMIter iter; + BM_ITER_ELEM_INDEX (l, &iter, efa, BM_LOOPS_OF_FACE, i) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float pv[3]; + sub_v3_v3v3(pv, l->v->co, center); + mul_m3_v3(rotmat, pv); + regular[i] = map_to_sphere(&luv->uv[0], &luv->uv[1], pv[0], pv[1], pv[2]); + } + + uv_map_mirror(efa, regular, fan, cd_loop_uv_offset); } static int sphere_project_exec(bContext *C, wmOperator *op) @@ -2800,9 +2862,7 @@ static int sphere_project_exec(bContext *C, wmOperator *op) Object *obedit = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(obedit); BMFace *efa; - BMLoop *l; - BMIter iter, liter; - MLoopUV *luv; + BMIter iter; if (em->bm->totfacesel == 0) { continue; @@ -2814,11 +2874,13 @@ static int sphere_project_exec(bContext *C, wmOperator *op) } const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - float center[3], rotmat[4][4]; + float center[3], rotmat[3][3]; uv_map_transform(C, op, rotmat); uv_map_transform_center(scene, v3d, obedit, em, center, NULL); + const bool fan = RNA_enum_get(op->ptr, "pole"); + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) { continue; @@ -2831,13 +2893,7 @@ static int sphere_project_exec(bContext *C, wmOperator *op) } } - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - - uv_sphere_project(luv->uv, l->v->co, center, rotmat); - } - - uv_map_mirror(em, efa); + uv_sphere_project(efa, center, rotmat, fan, cd_loop_uv_offset); } const bool per_face_aspect = true; @@ -2875,22 +2931,25 @@ void UV_OT_sphere_project(wmOperatorType *ot) /** \name Cylinder UV Project Operator * \{ */ -static void uv_cylinder_project(float target[2], - const float source[3], +static void uv_cylinder_project(BMFace *efa, const float center[3], - const float rotmat[4][4]) + const float rotmat[3][3], + const bool fan, + const int cd_loop_uv_offset) { - float pv[3]; - - sub_v3_v3v3(pv, source, center); - mul_m4_v3(rotmat, pv); - - map_to_tube(&target[0], &target[1], pv[0], pv[1], pv[2]); - - /* split line is always zero */ - if (target[0] >= 1.0f) { - target[0] -= 1.0f; + bool *regular = BLI_array_alloca(regular, efa->len); + int i; + BMLoop *l; + BMIter iter; + BM_ITER_ELEM_INDEX (l, &iter, efa, BM_LOOPS_OF_FACE, i) { + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float pv[3]; + sub_v3_v3v3(pv, l->v->co, center); + mul_m3_v3(rotmat, pv); + regular[i] = map_to_tube(&luv->uv[0], &luv->uv[1], pv[0], pv[1], pv[2]); } + + uv_map_mirror(efa, regular, fan, cd_loop_uv_offset); } static int cylinder_project_exec(bContext *C, wmOperator *op) @@ -2912,9 +2971,7 @@ static int cylinder_project_exec(bContext *C, wmOperator *op) Object *obedit = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(obedit); BMFace *efa; - BMLoop *l; - BMIter iter, liter; - MLoopUV *luv; + BMIter iter; if (em->bm->totfacesel == 0) { continue; @@ -2926,11 +2983,13 @@ static int cylinder_project_exec(bContext *C, wmOperator *op) } const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - float center[3], rotmat[4][4]; + float center[3], rotmat[3][3]; uv_map_transform(C, op, rotmat); uv_map_transform_center(scene, v3d, obedit, em, center, NULL); + const bool fan = RNA_enum_get(op->ptr, "pole"); + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) { continue; @@ -2941,12 +3000,7 @@ static int cylinder_project_exec(bContext *C, wmOperator *op) continue; } - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - uv_cylinder_project(luv->uv, l->v->co, center, rotmat); - } - - uv_map_mirror(em, efa); + uv_cylinder_project(efa, center, rotmat, fan, cd_loop_uv_offset); } const bool per_face_aspect = true; From b6c74b4c6f6b2b1ec28ec9db091a2a0f4fe66b94 Mon Sep 17 00:00:00 2001 From: Jesse Yurkovich Date: Thu, 5 Jan 2023 20:44:24 -0800 Subject: [PATCH 0451/1522] Fix T82081: Remove workaround for OCIO Unicode issue on Windows This workaround is no longer needed and prevents our OCIO configuration from being loaded if Blender is unpacked under a Unicode path. Differential Revision: https://developer.blender.org/D16818 --- source/blender/imbuf/intern/colormanagement.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 0678c224e6b..9f14ca0d596 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -671,17 +671,7 @@ void colormanagement_init(void) if (configdir) { BLI_path_join(configfile, sizeof(configfile), configdir, BCM_CONFIG_FILE); -#ifdef WIN32 - { - /* Quite a hack to support loading configuration from path with non-ACII symbols. */ - - char short_name[256]; - BLI_get_short_name(short_name, configfile); - config = OCIO_configCreateFromFile(short_name); - } -#else config = OCIO_configCreateFromFile(configfile); -#endif } } From 5c4d11d7099493bee4185639bb2222fcc3a271e7 Mon Sep 17 00:00:00 2001 From: Arnd Marijnissen Date: Wed, 4 Jan 2023 15:06:16 +0100 Subject: [PATCH 0452/1522] Bump buildbot gcc version to 11 --- build_files/config/pipeline_config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build_files/config/pipeline_config.yaml b/build_files/config/pipeline_config.yaml index 653c5eeb3b2..392bd842586 100644 --- a/build_files/config/pipeline_config.yaml +++ b/build_files/config/pipeline_config.yaml @@ -49,7 +49,7 @@ update-code: # buildbot: gcc: - version: '9.0.0' + version: '11.0.0' cuda10: version: '10.1.243' cuda11: From fc9c39e320a87f40473b077f96be4472f53e98b5 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 6 Jan 2023 11:01:11 +0100 Subject: [PATCH 0453/1522] Fix T103242: Missing update on undo/redo for some image properties. Issue comes from the fact that some of the image updates are handled outside of depsgraph context (through the signal system), and therefore completely ignored by the undo/redo code. Now that undo/redo tries to update as little data as possible, it needs to be aware of these changes. As a temporary workaround, until image update is fully handled through depsgraph, consider that IDs tagged with `ID_RECALC_SOURCE` should get their caches cleared on undo/redo, and tag some RNA property updates of Image/ColorSpace as such. Reviewed By: sergey Maniphest Tasks: T103242 Differential Revision: https://developer.blender.org/D16927 --- source/blender/blenloader/intern/readfile.cc | 11 ++++++++++- source/blender/makesrna/intern/rna_color.c | 1 + source/blender/makesrna/intern/rna_image.c | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 953beee6fbd..ed88495797d 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -1604,7 +1604,7 @@ static void blo_cache_storage_entry_register( /** Restore a cache data entry from old ID into new one, when reading some undo memfile. */ static void blo_cache_storage_entry_restore_in_new( - ID * /*id*/, const IDCacheKey *key, void **cache_p, uint flags, void *cache_storage_v) + ID *id, const IDCacheKey *key, void **cache_p, uint flags, void *cache_storage_v) { BLOCacheStorage *cache_storage = static_cast(cache_storage_v); @@ -1618,6 +1618,15 @@ static void blo_cache_storage_entry_restore_in_new( return; } + /* Assume that when ID source is tagged as changed, its caches need to be cleared. + * NOTE: This is mainly a work-around for some IDs, like Image, which use a non-depsgraph-handled + * process for part of their updates. + */ + if (id->recalc & ID_RECALC_SOURCE) { + *cache_p = nullptr; + return; + } + BLOCacheStorageValue *storage_value = static_cast( BLI_ghash_lookup(cache_storage->cache_map, key)); if (storage_value == nullptr) { diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index acc1efe8d12..72cf9d57c7b 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -626,6 +626,7 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *bmain, Image *ima = (Image *)id; DEG_id_tag_update(&ima->id, 0); + DEG_id_tag_update(&ima->id, ID_RECALC_SOURCE); BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_COLORMANAGE); diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 9deb8a1c90b..97233f39d86 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -194,7 +194,7 @@ static void rna_Image_colormanage_update(Main *bmain, Scene *UNUSED(scene), Poin Image *ima = (Image *)ptr->owner_id; BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_COLORMANAGE); DEG_id_tag_update(&ima->id, 0); - DEG_id_tag_update(&ima->id, ID_RECALC_EDITORS); + DEG_id_tag_update(&ima->id, ID_RECALC_EDITORS | ID_RECALC_SOURCE); WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id); WM_main_add_notifier(NC_IMAGE | NA_EDITED, &ima->id); } From 42b88c008861b6b7a12687739161436fea78c499 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 6 Jan 2023 11:50:56 +0100 Subject: [PATCH 0454/1522] Functions: simplify multi-function parameters The use of `std::variant` allows combining the four vectors into one which more closely matches the intend and avoids a workaround used before. Note that this uses `std::get_if` instead of `std::get` because `std::get` is only available since macOS 10.14. --- .../functions/FN_multi_function_params.hh | 86 +++++++++---------- .../functions/FN_multi_function_signature.hh | 41 --------- .../functions/intern/multi_function_params.cc | 8 +- 3 files changed, 44 insertions(+), 91 deletions(-) diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh index 16a33c9cda7..cfcc930c67b 100644 --- a/source/blender/functions/FN_multi_function_params.hh +++ b/source/blender/functions/FN_multi_function_params.hh @@ -12,6 +12,7 @@ */ #include +#include #include "BLI_generic_pointer.hh" #include "BLI_generic_vector_array.hh" @@ -28,10 +29,8 @@ class MFParamsBuilder { const MFSignature *signature_; IndexMask mask_; int64_t min_array_size_; - Vector virtual_arrays_; - Vector mutable_spans_; - Vector virtual_vector_arrays_; - Vector vector_arrays_; + Vector> + actual_params_; std::mutex mutex_; Vector> dummy_output_spans_; @@ -41,10 +40,7 @@ class MFParamsBuilder { MFParamsBuilder(const MFSignature &signature, const IndexMask mask) : signature_(&signature), mask_(mask), min_array_size_(mask.min_array_size()) { - virtual_arrays_.reserve(signature.virtual_array_num); - mutable_spans_.reserve(signature.span_num); - virtual_vector_arrays_.reserve(signature.virtual_vector_array_num); - vector_arrays_.reserve(signature.vector_array_num); + actual_params_.reserve(signature.param_types.size()); } public: @@ -58,32 +54,41 @@ class MFParamsBuilder { template void add_readonly_single_input_value(T value, StringRef expected_name = "") { this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get()), expected_name); - virtual_arrays_.append_unchecked_as( - varray_tag::single{}, CPPType::get(), min_array_size_, &value); + actual_params_.append_unchecked_as(std::in_place_type, + varray_tag::single{}, + CPPType::get(), + min_array_size_, + &value); } template void add_readonly_single_input(const T *value, StringRef expected_name = "") { this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get()), expected_name); - virtual_arrays_.append_unchecked_as( - varray_tag::single_ref{}, CPPType::get(), min_array_size_, value); + actual_params_.append_unchecked_as(std::in_place_type, + varray_tag::single_ref{}, + CPPType::get(), + min_array_size_, + value); } void add_readonly_single_input(const GSpan span, StringRef expected_name = "") { this->assert_current_param_type(MFParamType::ForSingleInput(span.type()), expected_name); BLI_assert(span.size() >= min_array_size_); - virtual_arrays_.append_unchecked_as(varray_tag::span{}, span); + actual_params_.append_unchecked_as(std::in_place_type, varray_tag::span{}, span); } void add_readonly_single_input(GPointer value, StringRef expected_name = "") { this->assert_current_param_type(MFParamType::ForSingleInput(*value.type()), expected_name); - virtual_arrays_.append_unchecked_as( - varray_tag::single_ref{}, *value.type(), min_array_size_, value.get()); + actual_params_.append_unchecked_as(std::in_place_type, + varray_tag::single_ref{}, + *value.type(), + min_array_size_, + value.get()); } void add_readonly_single_input(GVArray varray, StringRef expected_name = "") { this->assert_current_param_type(MFParamType::ForSingleInput(varray.type()), expected_name); BLI_assert(varray.size() >= min_array_size_); - virtual_arrays_.append_unchecked_as(std::move(varray)); + actual_params_.append_unchecked_as(std::in_place_type, std::move(varray)); } void add_readonly_vector_input(const GVectorArray &vector_array, StringRef expected_name = "") @@ -101,7 +106,7 @@ class MFParamsBuilder { { this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()), expected_name); BLI_assert(ref.size() >= min_array_size_); - virtual_vector_arrays_.append_unchecked(&ref); + actual_params_.append_unchecked_as(std::in_place_type, &ref); } template void add_uninitialized_single_output(T *value, StringRef expected_name = "") @@ -113,7 +118,7 @@ class MFParamsBuilder { { this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()), expected_name); BLI_assert(ref.size() >= min_array_size_); - mutable_spans_.append_unchecked(ref); + actual_params_.append_unchecked_as(std::in_place_type, ref); } void add_ignored_single_output(StringRef expected_name = "") { @@ -124,7 +129,7 @@ class MFParamsBuilder { const CPPType &type = param_type.data_type().single_type(); /* An empty span indicates that this is ignored. */ const GMutableSpan dummy_span{type}; - mutable_spans_.append_unchecked(dummy_span); + actual_params_.append_unchecked_as(std::in_place_type, dummy_span); } void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "") @@ -132,14 +137,14 @@ class MFParamsBuilder { this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()), expected_name); BLI_assert(vector_array.size() >= min_array_size_); - vector_arrays_.append_unchecked(&vector_array); + actual_params_.append_unchecked_as(std::in_place_type, &vector_array); } void add_single_mutable(GMutableSpan ref, StringRef expected_name = "") { this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type()), expected_name); BLI_assert(ref.size() >= min_array_size_); - mutable_spans_.append_unchecked(ref); + actual_params_.append_unchecked_as(std::in_place_type, ref); } void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "") @@ -147,7 +152,7 @@ class MFParamsBuilder { this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()), expected_name); BLI_assert(vector_array.size() >= min_array_size_); - vector_arrays_.append_unchecked(&vector_array); + actual_params_.append_unchecked_as(std::in_place_type, &vector_array); } GMutableSpan computed_array(int param_index) @@ -155,8 +160,7 @@ class MFParamsBuilder { BLI_assert(ELEM(signature_->param_types[param_index].category(), MFParamCategory::SingleOutput, MFParamCategory::SingleMutable)); - int data_index = signature_->data_index(param_index); - return mutable_spans_[data_index]; + return *std::get_if(&actual_params_[param_index]); } GVectorArray &computed_vector_array(int param_index) @@ -164,8 +168,7 @@ class MFParamsBuilder { BLI_assert(ELEM(signature_->param_types[param_index].category(), MFParamCategory::VectorOutput, MFParamCategory::VectorMutable)); - int data_index = signature_->data_index(param_index); - return *vector_arrays_[data_index]; + return **std::get_if(&actual_params_[param_index]); } ResourceScope &resource_scope() @@ -205,8 +208,7 @@ class MFParamsBuilder { int current_param_index() const { - return virtual_arrays_.size() + mutable_spans_.size() + virtual_vector_arrays_.size() + - vector_arrays_.size(); + return actual_params_.size(); } }; @@ -227,8 +229,7 @@ class MFParams { const GVArray &readonly_single_input(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, MFParamCategory::SingleInput); - int data_index = builder_->signature_->data_index(param_index); - return builder_->virtual_arrays_[data_index]; + return *std::get_if(&builder_->actual_params_[param_index]); } /** @@ -240,8 +241,7 @@ class MFParams { bool single_output_is_required(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput); - int data_index = builder_->signature_->data_index(param_index); - return !builder_->mutable_spans_[data_index].is_empty(); + return !std::get_if(&builder_->actual_params_[param_index])->is_empty(); } template @@ -252,14 +252,13 @@ class MFParams { GMutableSpan uninitialized_single_output(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput); - int data_index = builder_->signature_->data_index(param_index); - GMutableSpan span = builder_->mutable_spans_[data_index]; + GMutableSpan span = *std::get_if(&builder_->actual_params_[param_index]); if (!span.is_empty()) { return span; } /* The output is ignored by the caller, but the multi-function does not handle this case. So * create a temporary buffer that the multi-function can write to. */ - return this->ensure_dummy_single_output(data_index); + return this->ensure_dummy_single_output(param_index); } /** @@ -274,8 +273,7 @@ class MFParams { GMutableSpan uninitialized_single_output_if_required(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput); - int data_index = builder_->signature_->data_index(param_index); - return builder_->mutable_spans_[data_index]; + return *std::get_if(&builder_->actual_params_[param_index]); } template @@ -287,8 +285,7 @@ class MFParams { const GVVectorArray &readonly_vector_input(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, MFParamCategory::VectorInput); - int data_index = builder_->signature_->data_index(param_index); - return *builder_->virtual_vector_arrays_[data_index]; + return **std::get_if(&builder_->actual_params_[param_index]); } template @@ -299,8 +296,7 @@ class MFParams { GVectorArray &vector_output(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, MFParamCategory::VectorOutput); - int data_index = builder_->signature_->data_index(param_index); - return *builder_->vector_arrays_[data_index]; + return **std::get_if(&builder_->actual_params_[param_index]); } template MutableSpan single_mutable(int param_index, StringRef name = "") @@ -310,8 +306,7 @@ class MFParams { GMutableSpan single_mutable(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, MFParamCategory::SingleMutable); - int data_index = builder_->signature_->data_index(param_index); - return builder_->mutable_spans_[data_index]; + return *std::get_if(&builder_->actual_params_[param_index]); } template @@ -322,8 +317,7 @@ class MFParams { GVectorArray &vector_mutable(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, MFParamCategory::VectorMutable); - int data_index = builder_->signature_->data_index(param_index); - return *builder_->vector_arrays_[data_index]; + return **std::get_if(&builder_->actual_params_[param_index]); } private: @@ -349,7 +343,7 @@ class MFParams { #endif } - GMutableSpan ensure_dummy_single_output(int data_index); + GMutableSpan ensure_dummy_single_output(int param_index); }; } // namespace blender::fn diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh index 6181555dbd1..1c2d645c1fd 100644 --- a/source/blender/functions/FN_multi_function_signature.hh +++ b/source/blender/functions/FN_multi_function_signature.hh @@ -28,20 +28,6 @@ struct MFSignature { Vector param_types; Vector param_data_indices; bool depends_on_context = false; - - /** - * Number of elements of each of these types that has to be passed into the multi-function as an - * input or output. - */ - int span_num = 0; - int virtual_array_num = 0; - int virtual_vector_array_num = 0; - int vector_array_num = 0; - - int data_index(int param_index) const - { - return param_data_indices[param_index]; - } }; class MFSignatureBuilder { @@ -81,15 +67,6 @@ class MFSignatureBuilder { { signature_.param_names.append(name); signature_.param_types.append(MFParamType(MFParamType::Input, data_type)); - - switch (data_type.category()) { - case MFDataType::Single: - signature_.param_data_indices.append(signature_.virtual_array_num++); - break; - case MFDataType::Vector: - signature_.param_data_indices.append(signature_.virtual_vector_array_num++); - break; - } } /* Output Parameter Types */ @@ -114,15 +91,6 @@ class MFSignatureBuilder { { signature_.param_names.append(name); signature_.param_types.append(MFParamType(MFParamType::Output, data_type)); - - switch (data_type.category()) { - case MFDataType::Single: - signature_.param_data_indices.append(signature_.span_num++); - break; - case MFDataType::Vector: - signature_.param_data_indices.append(signature_.vector_array_num++); - break; - } } /* Mutable Parameter Types */ @@ -147,15 +115,6 @@ class MFSignatureBuilder { { signature_.param_names.append(name); signature_.param_types.append(MFParamType(MFParamType::Mutable, data_type)); - - switch (data_type.category()) { - case MFDataType::Single: - signature_.param_data_indices.append(signature_.span_num++); - break; - case MFDataType::Vector: - signature_.param_data_indices.append(signature_.vector_array_num++); - break; - } } void add(const char *name, const MFParamType ¶m_type) diff --git a/source/blender/functions/intern/multi_function_params.cc b/source/blender/functions/intern/multi_function_params.cc index 23e0269b443..3589c701618 100644 --- a/source/blender/functions/intern/multi_function_params.cc +++ b/source/blender/functions/intern/multi_function_params.cc @@ -4,18 +4,18 @@ namespace blender::fn { -GMutableSpan MFParams::ensure_dummy_single_output(int data_index) +GMutableSpan MFParams::ensure_dummy_single_output(int param_index) { /* Lock because we are actually modifying #builder_ and it may be used by multiple threads. */ std::lock_guard lock{builder_->mutex_}; for (const std::pair &items : builder_->dummy_output_spans_) { - if (items.first == data_index) { + if (items.first == param_index) { return items.second; } } - const CPPType &type = builder_->mutable_spans_[data_index].type(); + const CPPType &type = std::get_if(&builder_->actual_params_[param_index])->type(); void *buffer = builder_->scope_.linear_allocator().allocate( builder_->min_array_size_ * type.size(), type.alignment()); if (!type.is_trivially_destructible()) { @@ -23,7 +23,7 @@ GMutableSpan MFParams::ensure_dummy_single_output(int data_index) [&type, buffer, mask = builder_->mask_]() { type.destruct_indices(buffer, mask); }); } const GMutableSpan span{type, buffer, builder_->min_array_size_}; - builder_->dummy_output_spans_.append({data_index, span}); + builder_->dummy_output_spans_.append({param_index, span}); return span; } From 1229b966524b7d7cb12d2bcb978391f0df5c7bb6 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Fri, 6 Jan 2023 11:55:24 +0100 Subject: [PATCH 0455/1522] Fix empty asset index files after bug in asset loading Initial error caused by 1efc94bb2f7b and fixed in 6a7917162c56. However the empty index files (empty as in, they contain the version number but no assets) will have to be fixed somehow, since otherwise assets don't show up at all for people who saved asset files in a broken version. Delete empty index files if the modification timestamp indicates a time when the bug was present (plus a day before and after, to address possible time zone differences). This will basically make Blender skip the optimization for .blend files without assets for one load, but even then the index should still produce faster results than a completely non-index read. This can be removed after a while, it's just a (much needed) fix for people who were using alpha/beta builds. Differential Revision: https://developer.blender.org/D16678 Reviewed by: Jeroen Bakker --- .../editors/asset/intern/asset_indexer.cc | 137 +++++++++++++++--- 1 file changed, 119 insertions(+), 18 deletions(-) diff --git a/source/blender/editors/asset/intern/asset_indexer.cc b/source/blender/editors/asset/intern/asset_indexer.cc index 7db23161926..e1350b3119e 100644 --- a/source/blender/editors/asset/intern/asset_indexer.cc +++ b/source/blender/editors/asset/intern/asset_indexer.cc @@ -4,6 +4,7 @@ * \ingroup edasset */ +#include #include #include #include @@ -413,17 +414,24 @@ static int init_indexer_entries_from_value(FileIndexerEntries &indexer_entries, /** * \brief References the asset library directory. * - * The #AssetLibraryIndex instance is used to keep track of unused file indices. When reading any - * used indices are removed from the list and when reading is finished the unused - * indices are removed. + * The #AssetLibraryIndex instance collects file indices that are existing before the actual + * reading/updating starts. This way, the reading/updating can tag pre-existing files as used when + * they are still needed. Remaining ones (indices that are not tagged as used) can be removed once + * reading finishes. */ struct AssetLibraryIndex { + struct PreexistingFileIndexInfo { + bool is_used = false; + }; + /** - * Tracks indices that haven't been used yet. + * File indices that are existing already before reading/updating performs changes. The key is + * the absolute path. The value can store information like if the index is known to be used. * - * Contains absolute paths to the indices. + * Note that when deleting a file index (#delete_index_file()), it's also removed from here, + * since it doesn't exist and isn't relevant to keep track of anymore. */ - Set unused_file_indices; + Map preexisting_file_indices; /** * \brief Absolute path where the indices of `library` are stored. @@ -485,9 +493,10 @@ struct AssetLibraryIndex { } /** - * Initialize to keep track of unused file indices. + * Check for pre-existing index files to be able to track what is still used and what can be + * removed. See #AssetLibraryIndex::preexisting_file_indices. */ - void init_unused_index_files() + void collect_preexisting_file_indices() { const char *index_path = indices_base_path.c_str(); if (!BLI_is_dir(index_path)) { @@ -498,7 +507,7 @@ struct AssetLibraryIndex { for (int i = 0; i < dir_entries_num; i++) { struct direntry *entry = &dir_entries[i]; if (BLI_str_endswith(entry->relname, ".index.json")) { - unused_file_indices.add_as(std::string(entry->path)); + preexisting_file_indices.add_as(std::string(entry->path)); } } @@ -507,17 +516,53 @@ struct AssetLibraryIndex { void mark_as_used(const std::string &filename) { - unused_file_indices.remove(filename); + PreexistingFileIndexInfo *preexisting = preexisting_file_indices.lookup_ptr(filename); + if (preexisting) { + preexisting->is_used = true; + } } - int remove_unused_index_files() const + /** + * Removes the file index from disk and #preexisting_file_indices (invalidating its iterators, so + * don't call while iterating). + * \return true if deletion was successful. + */ + bool delete_file_index(const std::string &filename) + { + if (BLI_delete(filename.c_str(), false, false) == 0) { + preexisting_file_indices.remove(filename); + return true; + } + return false; + } + + /** + * A bug was creating empty index files for a while (see D16665). Remove empty index files from + * this period, so they are regenerated. + */ + /* Implemented further below. */ + int remove_broken_index_files(); + + int remove_unused_index_files() { int num_files_deleted = 0; - for (const std::string &unused_index : unused_file_indices) { - const char *file_path = unused_index.c_str(); - CLOG_INFO(&LOG, 2, "Remove unused index file [%s].", file_path); - BLI_delete(file_path, false, false); - num_files_deleted++; + + Set files_to_remove; + + for (auto preexisting_index : preexisting_file_indices.items()) { + if (preexisting_index.value.is_used) { + continue; + } + + const std::string &file_path = preexisting_index.key; + CLOG_INFO(&LOG, 2, "Remove unused index file [%s].", file_path.c_str()); + files_to_remove.add(preexisting_index.key); + } + + for (StringRef file_to_remove : files_to_remove) { + if (delete_file_index(file_to_remove)) { + num_files_deleted++; + } } return num_files_deleted; @@ -622,8 +667,13 @@ class AssetIndexFile : public AbstractFile { const size_t MIN_FILE_SIZE_WITH_ENTRIES = 32; std::string filename; + AssetIndexFile(AssetLibraryIndex &library_index, StringRef index_file_path) + : library_index(library_index), filename(index_file_path) + { + } + AssetIndexFile(AssetLibraryIndex &library_index, BlendFile &asset_filename) - : library_index(library_index), filename(library_index.index_file_path(asset_filename)) + : AssetIndexFile(library_index, library_index.index_file_path(asset_filename)) { } @@ -687,6 +737,56 @@ class AssetIndexFile : public AbstractFile { } }; +/* TODO(Julian): remove this after a short while. Just necessary for people who've been using alpha + * builds from a certain period. */ +int AssetLibraryIndex::remove_broken_index_files() +{ + Set files_to_remove; + + preexisting_file_indices.foreach_item( + [&](const std::string &index_path, const PreexistingFileIndexInfo &) { + AssetIndexFile index_file(*this, index_path); + + /* Bug was causing empty index files, so non-empty ones can be skipped. */ + if (index_file.constains_entries()) { + return; + } + + /* Use the file modification time stamp to attempt to remove empty index files from a + * certain period (when the bug was in there). Starting from a day before the bug was + * introduced until a day after the fix should be enough to mitigate possible local time + * zone issues. */ + + std::tm tm_from{}; + tm_from.tm_year = 2022 - 1900; /* 2022 */ + tm_from.tm_mon = 11 - 1; /* November */ + tm_from.tm_mday = 8; /* Day before bug was introduced. */ + std::tm tm_to{}; + tm_from.tm_year = 2022 - 1900; /* 2022 */ + tm_from.tm_mon = 12 - 1; /* December */ + tm_from.tm_mday = 3; /* Day after fix. */ + std::time_t timestamp_from = std::mktime(&tm_from); + std::time_t timestamp_to = std::mktime(&tm_to); + BLI_stat_t stat = {}; + if (BLI_stat(index_file.get_file_path(), &stat) == -1) { + return; + } + if (IN_RANGE(stat.st_mtime, timestamp_from, timestamp_to)) { + CLOG_INFO(&LOG, 2, "Remove potentially broken index file [%s].", index_path.c_str()); + files_to_remove.add(index_path); + } + }); + + int num_files_deleted = 0; + for (StringRef files_to_remove : files_to_remove) { + if (delete_file_index(files_to_remove)) { + num_files_deleted++; + } + } + + return num_files_deleted; +} + static eFileIndexerResult read_index(const char *filename, FileIndexerEntries *entries, int *r_read_entries_len, @@ -762,7 +862,8 @@ static void *init_user_data(const char *root_directory, size_t root_directory_ma { AssetLibraryIndex *library_index = MEM_new( __func__, StringRef(root_directory, BLI_strnlen(root_directory, root_directory_maxlen))); - library_index->init_unused_index_files(); + library_index->collect_preexisting_file_indices(); + library_index->remove_broken_index_files(); return library_index; } From 8556741183e19b7eafd217194627c7f6cf5ac357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 6 Jan 2023 11:30:40 +0100 Subject: [PATCH 0456/1522] Editors: Slider, add possibility to disable ctrl-for-increments The slider component can now be told to not use CTRL for toggling stepped 10% increments. This is useful when the operator that uses the slider needs that modifier key for its own purposes. --- source/blender/editors/include/ED_util.h | 3 +++ source/blender/editors/util/ed_draw.c | 30 ++++++++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index 9b19116b1fe..98a9746292b 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -98,6 +98,9 @@ void ED_slider_factor_set(struct tSlider *slider, float factor); bool ED_slider_allow_overshoot_get(struct tSlider *slider); void ED_slider_allow_overshoot_set(struct tSlider *slider, bool value); +bool ED_slider_allow_increments_get(struct tSlider *slider); +void ED_slider_allow_increments_set(struct tSlider *slider, bool value); + bool ED_slider_is_bidirectional_get(struct tSlider *slider); void ED_slider_is_bidirectional_set(struct tSlider *slider, bool value); diff --git a/source/blender/editors/util/ed_draw.c b/source/blender/editors/util/ed_draw.c index 1ae9608b8e6..1eacb7a2045 100644 --- a/source/blender/editors/util/ed_draw.c +++ b/source/blender/editors/util/ed_draw.c @@ -89,6 +89,10 @@ typedef struct tSlider { * This is set by the artist while using the slider. */ bool overshoot; + /** Whether keeping CTRL pressed will snap to 10% increments. + * Default is true. Set to false if the CTRL key is needed for other means. */ + bool allow_increments; + /** Move factor in 10% steps. */ bool increments; @@ -381,6 +385,7 @@ tSlider *ED_slider_create(struct bContext *C) /* Default is true, caller needs to manually set to false. */ slider->allow_overshoot = true; + slider->allow_increments = true; /* Set initial factor. */ slider->raw_factor = 0.5f; @@ -425,7 +430,7 @@ bool ED_slider_modal(tSlider *slider, const wmEvent *event) break; case EVT_LEFTCTRLKEY: case EVT_RIGHTCTRLKEY: - slider->increments = event->val == KM_PRESS; + slider->increments = slider->allow_increments && event->val == KM_PRESS; break; case MOUSEMOVE:; /* Update factor. */ @@ -469,16 +474,21 @@ void ED_slider_status_string_get(const struct tSlider *slider, STRNCPY(precision_str, TIP_("Shift - Hold for precision")); } - if (slider->increments) { - STRNCPY(increments_str, TIP_("[Ctrl] - Increments active")); + if (slider->allow_increments) { + if (slider->increments) { + STRNCPY(increments_str, TIP_(" | [Ctrl] - Increments active")); + } + else { + STRNCPY(increments_str, TIP_(" | Ctrl - Hold for 10% increments")); + } } else { - STRNCPY(increments_str, TIP_("Ctrl - Hold for 10% increments")); + increments_str[0] = '\0'; } BLI_snprintf(status_string, size_of_status_string, - "%s | %s | %s", + "%s | %s%s", overshoot_str, precision_str, increments_str); @@ -521,6 +531,16 @@ void ED_slider_allow_overshoot_set(struct tSlider *slider, const bool value) slider->allow_overshoot = value; } +bool ED_slider_allow_increments_get(struct tSlider *slider) +{ + return slider->allow_increments; +} + +void ED_slider_allow_increments_set(struct tSlider *slider, const bool value) +{ + slider->allow_increments = value; +} + bool ED_slider_is_bidirectional_get(struct tSlider *slider) { return slider->is_bidirectional; From bd36c712b928f522ff3879d54dc70fec6cb37c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 6 Jan 2023 11:37:52 +0100 Subject: [PATCH 0457/1522] Pose Library: while blending, use CTRL for flipping the pose Using negative blend factors for blending in flipped poses was undesirable. Instead, the pose blending operator now uses CTRL to flip the pose. Negative blend values are still allowed, and cause the pose asset to be subtracted from the current pose. It can quickly break the rig, but for small adjustments it can be useful. --- source/blender/editors/armature/pose_lib_2.c | 78 +++++++++++--------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/source/blender/editors/armature/pose_lib_2.c b/source/blender/editors/armature/pose_lib_2.c index 827d76cce1f..d0f87b25b2d 100644 --- a/source/blender/editors/armature/pose_lib_2.c +++ b/source/blender/editors/armature/pose_lib_2.c @@ -66,9 +66,11 @@ typedef struct PoseBlendData { /* For temp-loading the Action from the pose library. */ AssetTempIDConsumer *temp_id_consumer; - /* Blend factor, interval [-1, 1] for interpolating between current and given pose. - * Positive factors will blend in `act`, whereas negative factors will blend in `act_flipped`. */ + /* Blend factor for interpolating between current and given pose. + * 1.0 means "100% pose asset". Negative values and values > 1.0 will be used as-is, and can + * cause interesting effects. */ float blend_factor; + bool is_flipped; struct PoseBackup *pose_backup; Object *ob; /* Object to work on. */ @@ -85,11 +87,11 @@ typedef struct PoseBlendData { } PoseBlendData; /** Return the bAction that should be blended. - * This is either pbd->act or pbd->act_flipped, depending on the sign of the blend factor. + * This is either pbd->act or pbd->act_flipped, depending on is_flipped. */ static bAction *poselib_action_to_blend(PoseBlendData *pbd) { - return (pbd->blend_factor >= 0) ? pbd->act : pbd->act_flipped; + return pbd->is_flipped ? pbd->act_flipped : pbd->act; } /* Makes a copy of the current pose for restoration purposes - doesn't do constraints currently */ @@ -177,27 +179,32 @@ static void poselib_blend_apply(bContext *C, wmOperator *op) struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); AnimationEvalContext anim_eval_context = BKE_animsys_eval_context_construct(depsgraph, 0.0f); bAction *to_blend = poselib_action_to_blend(pbd); - BKE_pose_apply_action_blend(pbd->ob, to_blend, &anim_eval_context, fabs(pbd->blend_factor)); + BKE_pose_apply_action_blend(pbd->ob, to_blend, &anim_eval_context, pbd->blend_factor); } /* ---------------------------- */ static void poselib_blend_set_factor(PoseBlendData *pbd, const float new_factor) { - const bool sign_changed = signf(new_factor) != signf(pbd->blend_factor); - if (sign_changed) { - /* The zero point was crossed, meaning that the pose will be flipped. This means the pose - * backup has to change, as it only contains the bones for one side. */ - BKE_pose_backup_restore(pbd->pose_backup); - BKE_pose_backup_free(pbd->pose_backup); - } - pbd->blend_factor = new_factor; pbd->needs_redraw = true; +} - if (sign_changed) { - poselib_backup_posecopy(pbd); +static void poselib_set_flipped(PoseBlendData *pbd, const bool new_flipped) +{ + if (pbd->is_flipped == new_flipped) { + return; } + + /* The pose will toggle between flipped and normal. This means the pose + * backup has to change, as it only contains the bones for one side. */ + BKE_pose_backup_restore(pbd->pose_backup); + BKE_pose_backup_free(pbd->pose_backup); + + pbd->is_flipped = new_flipped; + pbd->needs_redraw = true; + + poselib_backup_posecopy(pbd); } /* Return operator return value. */ @@ -220,6 +227,9 @@ static int poselib_blend_handle_event(bContext *UNUSED(C), wmOperator *op, const return OPERATOR_RUNNING_MODAL; } + /* Ctrl manages the 'flipped' state. */ + poselib_set_flipped(pbd, event->modifier & KM_CTRL); + /* only accept 'press' event, and ignore 'release', so that we don't get double actions */ if (ELEM(event->val, KM_PRESS, KM_NOTHING) == 0) { return OPERATOR_RUNNING_MODAL; @@ -318,14 +328,12 @@ static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent * return false; } - /* Passing `flipped=True` is the same as flipping the sign of the blend factor. */ - const bool apply_flipped = RNA_boolean_get(op->ptr, "flipped"); - const float multiply_factor = apply_flipped ? -1.0f : 1.0f; - pbd->blend_factor = multiply_factor * RNA_float_get(op->ptr, "blend_factor"); + pbd->is_flipped = RNA_boolean_get(op->ptr, "flipped"); + pbd->blend_factor = RNA_float_get(op->ptr, "blend_factor"); /* Only construct the flipped pose if there is a chance it's actually needed. */ const bool is_interactive = (event != NULL); - if (is_interactive || pbd->blend_factor < 0) { + if (is_interactive || pbd->is_flipped) { pbd->act_flipped = flip_pose(C, ob, pbd->act); } @@ -352,6 +360,7 @@ static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent * ED_slider_init(pbd->slider, event); ED_slider_factor_set(pbd->slider, pbd->blend_factor); ED_slider_allow_overshoot_set(pbd->slider, true); + ED_slider_allow_increments_set(pbd->slider, false); ED_slider_is_bidirectional_set(pbd->slider, true); } @@ -394,8 +403,8 @@ static void poselib_blend_cleanup(bContext *C, wmOperator *op) poselib_keytag_pose(C, scene, pbd); /* Ensure the redo panel has the actually-used value, instead of the initial value. */ - RNA_float_set(op->ptr, "blend_factor", fabs(pbd->blend_factor)); - RNA_boolean_set(op->ptr, "flipped", pbd->blend_factor < 0); + RNA_float_set(op->ptr, "blend_factor", pbd->blend_factor); + RNA_boolean_set(op->ptr, "flipped", pbd->is_flipped); break; } @@ -485,7 +494,11 @@ static int poselib_blend_modal(bContext *C, wmOperator *op, const wmEvent *event strcpy(tab_string, TIP_("[Tab] - Show blended pose")); } - BLI_snprintf(status_string, sizeof(status_string), "%s | %s", tab_string, slider_string); + BLI_snprintf(status_string, + sizeof(status_string), + "%s | %s | [Ctrl] - Flip Pose", + tab_string, + slider_string); ED_workspace_status_text(C, status_string); poselib_blend_apply(C, op); @@ -572,16 +585,14 @@ void POSELIB_OT_apply_pose_asset(wmOperatorType *ot) FLT_MAX, "Blend Factor", "Amount that the pose is applied on top of the existing poses. A negative " - "value will apply the pose flipped over the X-axis", + "value will subtract the pose instead of adding it", -1.0f, 1.0f); - prop = RNA_def_boolean( - ot->srna, - "flipped", - false, - "Apply Flipped", - "When enabled, applies the pose flipped over the X-axis. This is the same as " - "passing a negative `blend_factor`"); + prop = RNA_def_boolean(ot->srna, + "flipped", + false, + "Apply Flipped", + "When enabled, applies the pose flipped over the X-axis"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); } @@ -612,7 +623,7 @@ void POSELIB_OT_blend_pose_asset(wmOperatorType *ot) FLT_MAX, "Blend Factor", "Amount that the pose is applied on top of the existing poses. A " - "negative value will apply the pose flipped over the X-axis", + "negative value will subtract the pose instead of adding it", -1.0f, 1.0f); /* Blending should always start at 0%, and not at whatever percentage was last used. This RNA @@ -624,8 +635,7 @@ void POSELIB_OT_blend_pose_asset(wmOperatorType *ot) "flipped", false, "Apply Flipped", - "When enabled, applies the pose flipped over the X-axis. This is the " - "same as passing a negative `blend_factor`"); + "When enabled, applies the pose flipped over the X-axis"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); prop = RNA_def_boolean(ot->srna, From 3337838b4990ab92aca7644f36f5f2273ffb4abe Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 6 Jan 2023 12:54:08 +0100 Subject: [PATCH 0458/1522] Fix: retrieved writable attribute but did not write to it This caused a warning because `attribute.finish` was not called. --- source/blender/blenkernel/intern/geometry_fields.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/geometry_fields.cc b/source/blender/blenkernel/intern/geometry_fields.cc index 6fe822d6dc6..9c691cb5870 100644 --- a/source/blender/blenkernel/intern/geometry_fields.cc +++ b/source/blender/blenkernel/intern/geometry_fields.cc @@ -433,8 +433,10 @@ bool try_capture_field_on_geometry(GeometryComponent &component, GMutableSpan{type, buffer, domain_size}); evaluator.evaluate(); - if (GAttributeWriter attribute = attributes.lookup_for_write(attribute_id)) { - if (attribute.domain == domain && attribute.varray.type() == type) { + const std::optional meta_data = attributes.lookup_meta_data(attribute_id); + + if (meta_data && meta_data->domain == domain && meta_data->data_type == data_type) { + if (GAttributeWriter attribute = attributes.lookup_for_write(attribute_id)) { attribute.varray.set_all(buffer); attribute.finish(); type.destruct_n(buffer, domain_size); @@ -442,6 +444,7 @@ bool try_capture_field_on_geometry(GeometryComponent &component, return true; } } + attributes.remove(attribute_id); if (attributes.add(attribute_id, domain, data_type, bke::AttributeInitMoveArray{buffer})) { return true; From 006e905957ad7d5d76845876b4528acd40d59598 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 6 Jan 2023 12:57:34 +0100 Subject: [PATCH 0459/1522] Tests: support running benchmark when Blender prints unrelated text I noticed that sometimes the geometry nodes benchmark would not work if there were some left-over debug prints in the code. The reason it did not work was because the prints were mixed with the test output print. I also tried using explicit flusing and `atexit` for printing the test output, but that didn't solve it. Just printing additional newlines to better separate the test output from other printed output helped though. --- tests/performance/api/environment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/performance/api/environment.py b/tests/performance/api/environment.py index 1e2e4a84e81..094dbfa67ed 100644 --- a/tests/performance/api/environment.py +++ b/tests/performance/api/environment.py @@ -241,7 +241,7 @@ class TestEnvironment: f'args = pickle.loads(base64.b64decode({args}))\n' f'result = {modulename}.{functionname}(args)\n' f'result = base64.b64encode(pickle.dumps(result))\n' - f'print("{output_prefix}" + result.decode())\n') + f'print("\\n{output_prefix}" + result.decode() + "\\n")\n') expr_args = blender_args + ['--python-expr', expression] lines = self.call_blender(expr_args, foreground=foreground) From d49b850399aa12ab1e62b40e38bec7c5d0096190 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 6 Jan 2023 13:01:22 +0100 Subject: [PATCH 0460/1522] Tests: run geometry nodes benchmarks multiple times to reduce noise Ideally, we would also get variance information out of the test, but that seems a bit more complex to implement. For now just run the test a couple of times and average the timings. The test now runs between 5 and 100 times, depending on how long it to run the test once. --- tests/performance/tests/geometry_nodes.py | 35 ++++++++++++++++------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/tests/performance/tests/geometry_nodes.py b/tests/performance/tests/geometry_nodes.py index 3505f5278bd..591c78045ae 100644 --- a/tests/performance/tests/geometry_nodes.py +++ b/tests/performance/tests/geometry_nodes.py @@ -11,18 +11,33 @@ def _run(args): # Evaluate objects once first, to avoid any possible lazy evaluation later. bpy.context.view_layer.update() - # Tag all objects with geometry nodes modifiers to be recalculated. - for ob in bpy.context.view_layer.objects: - for modifier in ob.modifiers: - if modifier.type == 'NODES': - ob.update_tag() - break + test_time_start = time.time() + measured_times = [] - start_time = time.time() - bpy.context.view_layer.update() - elapsed_time = time.time() - start_time + min_measurements = 5 + max_measurements = 100 + timeout = 5 - result = {'time': elapsed_time} + while True: + # Tag all objects with geometry nodes modifiers to be recalculated. + for ob in bpy.context.view_layer.objects: + for modifier in ob.modifiers: + if modifier.type == 'NODES': + ob.update_tag() + break + + start_time = time.time() + bpy.context.view_layer.update() + elapsed_time = time.time() - start_time + measured_times.append(elapsed_time) + + if len(measured_times) >= min_measurements and test_time_start + timeout < time.time(): + break + if len(measured_times) >= max_measurements: + break + + average_time = sum(measured_times) / len(measured_times) + result = {'time': average_time} return result From ae7163007d9b3d4ca457d095e39c64c673253fe9 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 6 Jan 2023 13:03:09 +0100 Subject: [PATCH 0461/1522] Allocator: improve protection against false sharing On Apple Silicon, the cache line size is 128 bytes. --- intern/guardedalloc/intern/memory_usage.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/guardedalloc/intern/memory_usage.cc b/intern/guardedalloc/intern/memory_usage.cc index d4abff32f79..2ea6fe7e85f 100644 --- a/intern/guardedalloc/intern/memory_usage.cc +++ b/intern/guardedalloc/intern/memory_usage.cc @@ -21,7 +21,7 @@ struct Global; /** * This is stored per thread. Align to cache line size to avoid false sharing. */ -struct alignas(64) Local { +struct alignas(128) Local { /** * Retain shared ownership of #Global to make sure that it is not destructed. */ From 825f01b7b58036d4ac0626749fda6197acacc8cf Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Fri, 6 Jan 2023 13:24:36 +0100 Subject: [PATCH 0462/1522] Animation: Remove While Held Pose propagate option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "While Held" option from the Pose Propagate Operator doesn't do anything meaningful. After talking with the Animation Module it was decided to remove it. In code it was called `POSE_PROPAGATE_SMART_HOLDS` Reviewed by: Sybren A. Stüvel Differential Revision: https://developer.blender.org/D16771 Ref: D16771 --- release/scripts/startup/bl_ui/space_view3d.py | 4 - source/blender/editors/armature/pose_slide.c | 138 +++--------------- 2 files changed, 18 insertions(+), 124 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 791e7233b49..f39dd131d43 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -3660,10 +3660,6 @@ class VIEW3D_MT_pose_propagate(Menu): def draw(self, _context): layout = self.layout - layout.operator("pose.propagate").mode = 'WHILE_HELD' - - layout.separator() - layout.operator("pose.propagate", text="To Next Keyframe").mode = 'NEXT_KEY' layout.operator("pose.propagate", text="To Last Keyframe (Make Cyclic)").mode = 'LAST_KEY' diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c index 85af4e25454..9ae71a32774 100644 --- a/source/blender/editors/armature/pose_slide.c +++ b/source/blender/editors/armature/pose_slide.c @@ -1753,10 +1753,8 @@ void POSE_OT_blend_to_neighbors(wmOperatorType *ot) /* "termination conditions" - i.e. when we stop */ typedef enum ePosePropagate_Termination { - /** Stop after the current hold ends. */ - POSE_PROPAGATE_SMART_HOLDS = 0, /** Only do on the last keyframe. */ - POSE_PROPAGATE_LAST_KEY, + POSE_PROPAGATE_LAST_KEY = 0, /** Stop after the next keyframe. */ POSE_PROPAGATE_NEXT_KEY, /** Stop after the specified frame. */ @@ -1772,84 +1770,25 @@ typedef enum ePosePropagate_Termination { /* --------------------------------- */ -/** - * Get frame on which the "hold" for the bone ends. - * XXX: this may not really work that well if a bone moves on some channels and not others - * if this happens to be a major issue, scrap this, and just make this happen - * independently per F-Curve - */ -static float pose_propagate_get_boneHoldEndFrame(tPChanFCurveLink *pfl, float startFrame) +typedef struct FrameLink { + struct FrameLink *next, *prev; + float frame; +} FrameLink; + +static void propagate_curve_values(ListBase /*tPChanFCurveLink*/ *pflinks, + const float source_frame, + ListBase /*FrameLink*/ *target_frames) { - struct AnimKeylist *keylist = ED_keylist_create(); - - Object *ob = pfl->ob; - AnimData *adt = ob->adt; - LinkData *ld; - float endFrame = startFrame; - - for (ld = pfl->fcurves.first; ld; ld = ld->next) { - FCurve *fcu = (FCurve *)ld->data; - fcurve_to_keylist(adt, fcu, keylist, 0); - } - ED_keylist_prepare_for_direct_access(keylist); - - /* Find the long keyframe (i.e. hold), and hence obtain the endFrame value - * - the best case would be one that starts on the frame itself - */ - const ActKeyColumn *ab = ED_keylist_find_exact(keylist, startFrame); - - /* There are only two cases for no-exact match: - * 1) the current frame is just before another key but not on a key itself - * 2) the current frame is on a key, but that key doesn't link to the next - * - * If we've got the first case, then we can search for another block, - * otherwise forget it, as we'd be overwriting some valid data. - */ - if (ab == NULL) { - /* We've got case 1, so try the one after. */ - ab = ED_keylist_find_next(keylist, startFrame); - - if ((actkeyblock_get_valid_hold(ab) & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) { - /* Try the block before this frame then as last resort. */ - ab = ED_keylist_find_prev(keylist, startFrame); + LISTBASE_FOREACH (tPChanFCurveLink *, pfl, pflinks) { + LISTBASE_FOREACH (LinkData *, ld, &pfl->fcurves) { + FCurve *fcu = (FCurve *)ld->data; + const float current_fcu_value = evaluate_fcurve(fcu, source_frame); + LISTBASE_FOREACH (FrameLink *, target_frame, target_frames) { + insert_vert_fcurve( + fcu, target_frame->frame, current_fcu_value, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NEEDED); + } } } - - /* Whatever happens, stop searching now.... */ - if ((actkeyblock_get_valid_hold(ab) & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) { - /* Restrict range to just the frame itself - * i.e. everything is in motion, so no holds to safely overwrite. */ - ab = NULL; - } - - /* Check if we can go any further than we've already gone. */ - if (ab) { - /* Go to next if it is also valid and meets "extension" criteria. */ - while (ab->next) { - const ActKeyColumn *abn = ab->next; - - /* Must be valid. */ - if ((actkeyblock_get_valid_hold(abn) & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) { - break; - } - /* Should have the same number of curves. */ - if (ab->totblock != abn->totblock) { - break; - } - - /* We can extend the bounds to the end of this "next" block now. */ - ab = abn; - } - - /* End frame can now take the value of the end of the block. */ - endFrame = ab->next->cfra; - } - - /* Free temp memory. */ - ED_keylist_free(keylist); - - /* Return the end frame we've found. */ - return endFrame; } /** @@ -1902,27 +1841,6 @@ static void pose_propagate_fcurve(FCurve *fcu, float start_frame, const float en } } -typedef struct FrameLink { - struct FrameLink *next, *prev; - float frame; -} FrameLink; - -static void propagate_curve_values(ListBase /*tPChanFCurveLink*/ *pflinks, - const float source_frame, - ListBase /*FrameLink*/ *target_frames) -{ - LISTBASE_FOREACH (tPChanFCurveLink *, pfl, pflinks) { - LISTBASE_FOREACH (LinkData *, ld, &pfl->fcurves) { - FCurve *fcu = (FCurve *)ld->data; - const float current_fcu_value = evaluate_fcurve(fcu, source_frame); - LISTBASE_FOREACH (FrameLink *, target_frame, target_frames) { - insert_vert_fcurve( - fcu, target_frame->frame, current_fcu_value, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NEEDED); - } - } - } -} - static float find_next_key(ListBase *pflinks, const float start_frame) { float target_frame = FLT_MAX; @@ -2084,21 +2002,6 @@ static int pose_propagate_exec(bContext *C, wmOperator *op) propagate_curve_values(&pflinks, current_frame, &target_frames); break; } - case POSE_PROPAGATE_SMART_HOLDS: { - /* For each bone, perform the copying required. */ - LISTBASE_FOREACH (tPChanFCurveLink *, pfl, &pflinks) { - /* Mode-specific data preprocessing (requiring access to all curves). */ - /* We store in endFrame the end frame of the "long keyframe" (i.e. a held value) - * starting from the keyframe that occurs after the current frame. */ - const int smart_end_frame = pose_propagate_get_boneHoldEndFrame(pfl, current_frame); - - /* Go through propagating pose to keyframes, curve by curve. */ - LISTBASE_FOREACH (LinkData *, ld, &pfl->fcurves) { - pose_propagate_fcurve((FCurve *)ld->data, current_frame, smart_end_frame); - } - } - break; - } } BLI_freelistN(&target_frames); @@ -2120,11 +2023,6 @@ static int pose_propagate_exec(bContext *C, wmOperator *op) void POSE_OT_propagate(wmOperatorType *ot) { static const EnumPropertyItem terminate_items[] = { - {POSE_PROPAGATE_SMART_HOLDS, - "WHILE_HELD", - 0, - "While Held", - "Propagate pose to all keyframes after current frame that don't change (Default behavior)"}, {POSE_PROPAGATE_NEXT_KEY, "NEXT_KEY", 0, @@ -2177,7 +2075,7 @@ void POSE_OT_propagate(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "mode", terminate_items, - POSE_PROPAGATE_SMART_HOLDS, + POSE_PROPAGATE_NEXT_KEY, "Terminate Mode", "Method used to determine when to stop propagating pose to keyframes"); RNA_def_float(ot->srna, From 5eab813fc0788c4e737dbc6ea85e932fb8180618 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Fri, 6 Jan 2023 13:38:43 +0100 Subject: [PATCH 0463/1522] Fix T102746: Jumping to next/previous (key)frame doesn't take subframes into account MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously when on frame 2.5 and trying to jump to a keyframe that was on frame 2, it would instead jump past it. Now it properly respects the subframes for that. Reviewed by: Sybren A. Stüvel Differential Revision: https://developer.blender.org/D16651 Ref: D16651 --- source/blender/editors/screen/screen_ops.c | 38 +++++++++++++--------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 9c0963d0fb1..dd0271f3155 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2951,6 +2951,11 @@ static int frame_offset_exec(bContext *C, wmOperator *op) int delta = RNA_int_get(op->ptr, "delta"); + /* In order to jump from e.g. 1.5 to 1 the delta needs to be incremented by 1 since the subframe + * is always zeroed. Otherwise it would jump to 0.*/ + if (delta < 0 && scene->r.subframe > 0) { + delta += 1; + } scene->r.cfra += delta; FRAMENUMBER_MIN_CLAMP(scene->r.cfra); scene->r.subframe = 0.0f; @@ -3062,7 +3067,7 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - float cfra = (float)(scene->r.cfra); + const float cfra = BKE_scene_frame_get(scene); /* Initialize binary-tree-list for getting keyframes. */ struct AnimKeylist *keylist = ED_keylist_create(); @@ -3096,25 +3101,26 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op) /* find matching keyframe in the right direction */ const ActKeyColumn *ak; + if (next) { ak = ED_keylist_find_next(keylist, cfra); - } - else { - ak = ED_keylist_find_prev(keylist, cfra); + while ((ak != NULL) && (done == false)) { + if (cfra < ak->cfra) { + BKE_scene_frame_set(scene, ak->cfra); + done = true; + } + else { + ak = ak->next; + } + } } - while ((ak != NULL) && (done == false)) { - if (scene->r.cfra != (int)ak->cfra) { - /* this changes the frame, so set the frame and we're done */ - const int whole_frame = (int)ak->cfra; - scene->r.cfra = whole_frame; - scene->r.subframe = ak->cfra - whole_frame; - done = true; - } - else { - /* take another step... */ - if (next) { - ak = ak->next; + else { + ak = ED_keylist_find_prev(keylist, cfra); + while ((ak != NULL) && (done == false)) { + if (cfra > ak->cfra) { + BKE_scene_frame_set(scene, ak->cfra); + done = true; } else { ak = ak->prev; From cc78fd4e9364338126e5145ff96ae6c544939042 Mon Sep 17 00:00:00 2001 From: Omar Emara Date: Fri, 6 Jan 2023 14:42:00 +0200 Subject: [PATCH 0464/1522] Realtime Compositor: Allow limited compositing region This patch allows the realtime compositor to be limited to a specific compositing region that is a subset of the full render region. In the context of the viewport compositor, when the viewport is in camera view and has a completely opaque passepartout, the compositing region will be limited to the visible camera region. On the user-level, this gives the user the ability to make the result of the compositor invariant of the aspect ratio, shift, and zoom of the viewport, making the result in the viewport identical to the final render compositor assuming size relative operations. It should be noted that compositing region is the *visible* camera region, that is, the result of the intersection of the camera region and the render region. So the user should be careful not to shift or zoom the view such that the camera border extends outside of the viewport to have the aforementioned benefits. While we could implement logic to fill the areas outside of the render region with zeros in some cases, there are many other ambiguous cases where such a solution wouldn't work, including the problematic case where the user zooms in very close, making the camera region much bigger than that of the render region. Differential Revision: https://developer.blender.org/D16899 Reviewed By: Clement Foucault --- .../realtime_compositor/CMakeLists.txt | 6 +- .../realtime_compositor/COM_context.hh | 17 +++- .../realtime_compositor/intern/context.cc | 10 ++ .../shaders/compositor_read_pass.glsl | 8 ++ .../shaders/compositor_set_alpha.glsl | 8 -- .../shaders/compositor_split_viewer.glsl | 2 +- .../shaders/compositor_write_output.glsl | 18 ++++ .../shaders/infos/compositor_convert_info.hh | 6 -- .../infos/compositor_read_pass_info.hh | 21 +++++ .../infos/compositor_set_alpha_info.hh | 11 --- .../infos/compositor_split_viewer_info.hh | 1 + .../infos/compositor_write_output_info.hh | 26 ++++++ .../engines/compositor/compositor_engine.cc | 92 ++++++++++++++++--- .../composite/nodes/node_composite_boxmask.cc | 2 +- .../nodes/node_composite_composite.cc | 51 ++++++++-- .../nodes/node_composite_ellipsemask.cc | 2 +- .../composite/nodes/node_composite_image.cc | 87 +++++++++++++----- .../composite/nodes/node_composite_scale.cc | 6 +- .../nodes/node_composite_split_viewer.cc | 17 +++- .../composite/nodes/node_composite_viewer.cc | 51 ++++++++-- 20 files changed, 345 insertions(+), 97 deletions(-) create mode 100644 source/blender/compositor/realtime_compositor/shaders/compositor_read_pass.glsl delete mode 100644 source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl create mode 100644 source/blender/compositor/realtime_compositor/shaders/compositor_write_output.glsl create mode 100644 source/blender/compositor/realtime_compositor/shaders/infos/compositor_read_pass_info.hh delete mode 100644 source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh create mode 100644 source/blender/compositor/realtime_compositor/shaders/infos/compositor_write_output_info.hh diff --git a/source/blender/compositor/realtime_compositor/CMakeLists.txt b/source/blender/compositor/realtime_compositor/CMakeLists.txt index 5826c70793c..f9739972690 100644 --- a/source/blender/compositor/realtime_compositor/CMakeLists.txt +++ b/source/blender/compositor/realtime_compositor/CMakeLists.txt @@ -116,15 +116,16 @@ set(GLSL_SRC shaders/compositor_normalize.glsl shaders/compositor_parallel_reduction.glsl shaders/compositor_projector_lens_distortion.glsl + shaders/compositor_read_pass.glsl shaders/compositor_realize_on_domain.glsl shaders/compositor_screen_lens_distortion.glsl - shaders/compositor_set_alpha.glsl shaders/compositor_split_viewer.glsl shaders/compositor_symmetric_blur.glsl shaders/compositor_symmetric_blur_variable_size.glsl shaders/compositor_symmetric_separable_blur.glsl shaders/compositor_tone_map_photoreceptor.glsl shaders/compositor_tone_map_simple.glsl + shaders/compositor_write_output.glsl shaders/library/gpu_shader_compositor_alpha_over.glsl shaders/library/gpu_shader_compositor_blur_common.glsl @@ -204,15 +205,16 @@ set(SRC_SHADER_CREATE_INFOS shaders/infos/compositor_normalize_info.hh shaders/infos/compositor_parallel_reduction_info.hh shaders/infos/compositor_projector_lens_distortion_info.hh + shaders/infos/compositor_read_pass_info.hh shaders/infos/compositor_realize_on_domain_info.hh shaders/infos/compositor_screen_lens_distortion_info.hh - shaders/infos/compositor_set_alpha_info.hh shaders/infos/compositor_split_viewer_info.hh shaders/infos/compositor_symmetric_blur_info.hh shaders/infos/compositor_symmetric_blur_variable_size_info.hh shaders/infos/compositor_symmetric_separable_blur_info.hh shaders/infos/compositor_tone_map_photoreceptor_info.hh shaders/infos/compositor_tone_map_simple_info.hh + shaders/infos/compositor_write_output_info.hh ) set(SHADER_CREATE_INFOS_CONTENT "") diff --git a/source/blender/compositor/realtime_compositor/COM_context.hh b/source/blender/compositor/realtime_compositor/COM_context.hh index 80fb4f70ca4..7be89bfeb0e 100644 --- a/source/blender/compositor/realtime_compositor/COM_context.hh +++ b/source/blender/compositor/realtime_compositor/COM_context.hh @@ -6,6 +6,7 @@ #include "BLI_string_ref.hh" #include "DNA_scene_types.h" +#include "DNA_vec_types.h" #include "GPU_texture.h" @@ -41,8 +42,17 @@ class Context { /* Get the active compositing scene. */ virtual const Scene *get_scene() const = 0; - /* Get the dimensions of the output. */ - virtual int2 get_output_size() = 0; + /* Get the width and height of the render passes and of the output texture returned by the + * get_input_texture and get_output_texture methods respectively. */ + virtual int2 get_render_size() const = 0; + + /* Get the rectangular region representing the area of the input that the compositor will operate + * on. Conversely, the compositor will only update the region of the output that corresponds to + * the compositing region. In the base case, the compositing region covers the entirety of the + * render region with a lower bound of zero and an upper bound of the render size returned by the + * get_render_size method. In other cases, the compositing region might be a subset of the render + * region. */ + virtual rcti get_compositing_region() const = 0; /* Get the texture representing the output where the result of the compositor should be * written. This should be called by output nodes to get their target texture. */ @@ -60,6 +70,9 @@ class Context { * appropriate place, which can be directly in the UI or just logged to the output stream. */ virtual void set_info_message(StringRef message) const = 0; + /* Get the size of the compositing region. See get_compositing_region(). */ + int2 get_compositing_region_size() const; + /* Get the current frame number of the active scene. */ int get_frame_number() const; diff --git a/source/blender/compositor/realtime_compositor/intern/context.cc b/source/blender/compositor/realtime_compositor/intern/context.cc index 0b123a2c271..a53c839c365 100644 --- a/source/blender/compositor/realtime_compositor/intern/context.cc +++ b/source/blender/compositor/realtime_compositor/intern/context.cc @@ -1,5 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BLI_rect.h" + +#include "DNA_vec_types.h" + #include "COM_context.hh" #include "COM_static_cache_manager.hh" #include "COM_static_shader_manager.hh" @@ -11,6 +15,12 @@ Context::Context(TexturePool &texture_pool) : texture_pool_(texture_pool) { } +int2 Context::get_compositing_region_size() const +{ + const rcti compositing_region = get_compositing_region(); + return int2(BLI_rcti_size_x(&compositing_region), BLI_rcti_size_y(&compositing_region)); +} + int Context::get_frame_number() const { return get_scene()->r.cfra; diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_read_pass.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_read_pass.glsl new file mode 100644 index 00000000000..ff8b33af655 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_read_pass.glsl @@ -0,0 +1,8 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + vec4 pass_color = texture_load(input_tx, texel + compositing_region_lower_bound); + imageStore(output_img, texel, READ_EXPRESSION(pass_color)); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl deleted file mode 100644 index 7dd40581790..00000000000 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_set_alpha.glsl +++ /dev/null @@ -1,8 +0,0 @@ -#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) - -void main() -{ - ivec2 texel = ivec2(gl_GlobalInvocationID.xy); - vec4 color = vec4(texture_load(image_tx, texel).rgb, texture_load(alpha_tx, texel).x); - imageStore(output_img, texel, color); -} diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl index 866b9045da2..4ed378e9ec4 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_split_viewer.glsl @@ -10,5 +10,5 @@ void main() #endif vec4 color = condition ? texture_load(first_image_tx, texel) : texture_load(second_image_tx, texel); - imageStore(output_img, texel, color); + imageStore(output_img, texel + compositing_region_lower_bound, color); } diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_write_output.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_write_output.glsl new file mode 100644 index 00000000000..d22e2a9ee67 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_write_output.glsl @@ -0,0 +1,18 @@ +#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl) + +void main() +{ + ivec2 texel = ivec2(gl_GlobalInvocationID.xy); + vec4 input_color = texture_load(input_tx, texel); + +#if defined(DIRECT_OUTPUT) + vec4 output_color = input_color; +#elif defined(OPAQUE_OUTPUT) + vec4 output_color = vec4(input_color.rgb, 1.0); +#elif defined(ALPHA_OUTPUT) + float alpha = texture_load(alpha_tx, texel).x; + vec4 output_color = vec4(input_color.rgb, alpha); +#endif + + imageStore(output_img, texel + compositing_region_lower_bound, output_color); +} diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh index 35e60056736..235525b582b 100644 --- a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_convert_info.hh @@ -61,9 +61,3 @@ GPU_SHADER_CREATE_INFO(compositor_convert_float_to_half_float) .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") .define("CONVERT_EXPRESSION(value)", "vec4(value.r, vec3(0.0))") .do_static_compilation(true); - -GPU_SHADER_CREATE_INFO(compositor_convert_color_to_opaque) - .additional_info("compositor_convert_shared") - .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") - .define("CONVERT_EXPRESSION(value)", "vec4(value.rgb, 1.0)") - .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_read_pass_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_read_pass_info.hh new file mode 100644 index 00000000000..e3e2d43f6f8 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_read_pass_info.hh @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_read_pass_shared) + .local_group_size(16, 16) + .push_constant(Type::IVEC2, "compositing_region_lower_bound") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .compute_source("compositor_read_pass.glsl"); + +GPU_SHADER_CREATE_INFO(compositor_read_pass) + .additional_info("compositor_read_pass_shared") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("READ_EXPRESSION(pass_color)", "pass_color") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_read_pass_alpha) + .additional_info("compositor_read_pass_shared") + .image(0, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .define("READ_EXPRESSION(pass_color)", "vec4(pass_color.a, vec3(0.0))") + .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh deleted file mode 100644 index ca28194e921..00000000000 --- a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_set_alpha_info.hh +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include "gpu_shader_create_info.hh" - -GPU_SHADER_CREATE_INFO(compositor_set_alpha) - .local_group_size(16, 16) - .sampler(0, ImageType::FLOAT_2D, "image_tx") - .sampler(1, ImageType::FLOAT_2D, "alpha_tx") - .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") - .compute_source("compositor_set_alpha.glsl") - .do_static_compilation(true); diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh index d5793b0ce59..b7a8b7657aa 100644 --- a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_split_viewer_info.hh @@ -6,6 +6,7 @@ GPU_SHADER_CREATE_INFO(compositor_split_viewer_shared) .local_group_size(16, 16) .push_constant(Type::FLOAT, "split_ratio") .push_constant(Type::IVEC2, "view_size") + .push_constant(Type::IVEC2, "compositing_region_lower_bound") .sampler(0, ImageType::FLOAT_2D, "first_image_tx") .sampler(1, ImageType::FLOAT_2D, "second_image_tx") .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_write_output_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_write_output_info.hh new file mode 100644 index 00000000000..c530ecc7741 --- /dev/null +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_write_output_info.hh @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(compositor_write_output_shared) + .local_group_size(16, 16) + .push_constant(Type::IVEC2, "compositing_region_lower_bound") + .sampler(0, ImageType::FLOAT_2D, "input_tx") + .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") + .compute_source("compositor_write_output.glsl"); + +GPU_SHADER_CREATE_INFO(compositor_write_output) + .additional_info("compositor_write_output_shared") + .define("DIRECT_OUTPUT") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_write_output_opaque) + .additional_info("compositor_write_output_shared") + .define("OPAQUE_OUTPUT") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(compositor_write_output_alpha) + .additional_info("compositor_write_output_shared") + .sampler(1, ImageType::FLOAT_2D, "alpha_tx") + .define("ALPHA_OUTPUT") + .do_static_compilation(true); diff --git a/source/blender/draw/engines/compositor/compositor_engine.cc b/source/blender/draw/engines/compositor/compositor_engine.cc index 03ef0be81b4..06e599e77b1 100644 --- a/source/blender/draw/engines/compositor/compositor_engine.cc +++ b/source/blender/draw/engines/compositor/compositor_engine.cc @@ -2,16 +2,23 @@ #include "BLI_listbase.h" #include "BLI_math_vec_types.hh" +#include "BLI_rect.h" #include "BLI_string_ref.hh" #include "BLI_utildefines.h" #include "BLT_translation.h" #include "DNA_ID_enums.h" +#include "DNA_camera_types.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "DNA_vec_types.h" +#include "DNA_view3d_types.h" #include "DEG_depsgraph_query.h" +#include "ED_view3d.h" + #include "DRW_render.h" #include "IMB_colormanagement.h" @@ -50,11 +57,68 @@ class Context : public realtime_compositor::Context { return DRW_context_state_get()->scene; } - int2 get_output_size() override + int2 get_render_size() const override { return int2(float2(DRW_viewport_size_get())); } + /* Returns true if the viewport is in camera view and has an opaque passepartout, that is, the + * area outside of the camera border is not visible. */ + bool is_opaque_camera_view() const + { + /* Check if the viewport is in camera view. */ + if (DRW_context_state_get()->rv3d->persp != RV3D_CAMOB) { + return false; + } + + /* Check if the camera object that is currently in view is an actual camera. It is possible for + * a non camera object to be used as a camera, in which case, there will be no passepartout or + * any other camera setting, so those pseudo cameras can be ignored. */ + Object *camera_object = DRW_context_state_get()->v3d->camera; + if (camera_object->type != OB_CAMERA) { + return false; + } + + /* Check if the camera has passepartout active and is totally opaque. */ + Camera *cam = static_cast(camera_object->data); + if (!(cam->flag & CAM_SHOWPASSEPARTOUT) || cam->passepartalpha != 1.0f) { + return false; + } + + return true; + } + + rcti get_compositing_region() const override + { + const int2 viewport_size = int2(float2(DRW_viewport_size_get())); + const rcti render_region = rcti{0, viewport_size.x, 0, viewport_size.y}; + + /* If the camera view is not opaque, that means the content outside of the camera region is + * visible to some extent, so it would make sense to include them in the compositing region. + * Otherwise, we limit the compositing region to the visible camera region because anything + * outside of the camera region will not be visible anyways. */ + if (!is_opaque_camera_view()) { + return render_region; + } + + rctf camera_border; + ED_view3d_calc_camera_border(DRW_context_state_get()->scene, + DRW_context_state_get()->depsgraph, + DRW_context_state_get()->region, + DRW_context_state_get()->v3d, + DRW_context_state_get()->rv3d, + &camera_border, + false); + + rcti camera_region; + BLI_rcti_rctf_copy_floor(&camera_region, &camera_border); + + rcti visible_camera_region; + BLI_rcti_isect(&render_region, &camera_region, &visible_camera_region); + + return visible_camera_region; + } + GPUTexture *get_output_texture() override { return DRW_viewport_texture_list_get()->color; @@ -83,36 +147,36 @@ class Engine { TexturePool texture_pool_; Context context_; realtime_compositor::Evaluator evaluator_; - /* Stores the viewport size at the time the last compositor evaluation happened. See the - * update_viewport_size method for more information. */ - int2 last_viewport_size_; + /* Stores the compositing region size at the time the last compositor evaluation happened. See + * the update_compositing_region_size method for more information. */ + int2 last_compositing_region_size_; public: Engine(char *info_message) : context_(texture_pool_, info_message), evaluator_(context_), - last_viewport_size_(context_.get_output_size()) + last_compositing_region_size_(context_.get_compositing_region_size()) { } - /* Update the viewport size and evaluate the compositor. */ + /* Update the compositing region size and evaluate the compositor. */ void draw() { - update_viewport_size(); + update_compositing_region_size(); evaluator_.evaluate(); } - /* If the size of the viewport changed from the last time the compositor was evaluated, update - * the viewport size and reset the evaluator. That's because the evaluator compiles the node tree - * in a manner that is specifically optimized for the size of the viewport. This should be called - * before evaluating the compositor. */ - void update_viewport_size() + /* If the size of the compositing region changed from the last time the compositor was evaluated, + * update the last compositor region size and reset the evaluator. That's because the evaluator + * compiles the node tree in a manner that is specifically optimized for the size of the + * compositing region. This should be called before evaluating the compositor. */ + void update_compositing_region_size() { - if (last_viewport_size_ == context_.get_output_size()) { + if (last_compositing_region_size_ == context_.get_compositing_region_size()) { return; } - last_viewport_size_ = context_.get_output_size(); + last_compositing_region_size_ = context_.get_compositing_region_size(); evaluator_.reset(); } diff --git a/source/blender/nodes/composite/nodes/node_composite_boxmask.cc b/source/blender/nodes/composite/nodes/node_composite_boxmask.cc index 17b5d64de91..1ff2b82f7bb 100644 --- a/source/blender/nodes/composite/nodes/node_composite_boxmask.cc +++ b/source/blender/nodes/composite/nodes/node_composite_boxmask.cc @@ -100,7 +100,7 @@ class BoxMaskOperation : public NodeOperation { Domain compute_domain() override { if (get_input("Mask").is_single_value()) { - return Domain(context().get_output_size()); + return Domain(context().get_compositing_region_size()); } return get_input("Mask").domain(); } diff --git a/source/blender/nodes/composite/nodes/node_composite_composite.cc b/source/blender/nodes/composite/nodes/node_composite_composite.cc index 24fe4e2d986..a7babeb28bd 100644 --- a/source/blender/nodes/composite/nodes/node_composite_composite.cc +++ b/source/blender/nodes/composite/nodes/node_composite_composite.cc @@ -81,9 +81,15 @@ class CompositeOperation : public NodeOperation { /* Executes when the alpha channel of the image is ignored. */ void execute_ignore_alpha() { - GPUShader *shader = shader_manager().get("compositor_convert_color_to_opaque"); + GPUShader *shader = shader_manager().get("compositor_write_output_opaque"); GPU_shader_bind(shader); + /* The compositing space might be limited to a subset of the output texture, so only write into + * that compositing region. */ + const rcti compositing_region = context().get_compositing_region(); + const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); + GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound); + const Result &image = get_input("Image"); image.bind_as_texture(shader, "input_tx"); @@ -91,7 +97,8 @@ class CompositeOperation : public NodeOperation { const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); - compute_dispatch_threads_at_least(shader, compute_domain().size); + const int2 compositing_region_size = context().get_compositing_region_size(); + compute_dispatch_threads_at_least(shader, compositing_region_size); image.unbind_as_texture(); GPU_texture_image_unbind(output_texture); @@ -102,22 +109,44 @@ class CompositeOperation : public NodeOperation { * to the output texture. */ void execute_copy() { + GPUShader *shader = shader_manager().get("compositor_write_output"); + GPU_shader_bind(shader); + + /* The compositing space might be limited to a subset of the output texture, so only write into + * that compositing region. */ + const rcti compositing_region = context().get_compositing_region(); + const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); + GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound); + const Result &image = get_input("Image"); + image.bind_as_texture(shader, "input_tx"); - /* Make sure any prior writes to the texture are reflected before copying it. */ - GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE); + GPUTexture *output_texture = context().get_output_texture(); + const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); + GPU_texture_image_bind(output_texture, image_unit); - GPU_texture_copy(context().get_output_texture(), image.texture()); + const int2 compositing_region_size = context().get_compositing_region_size(); + compute_dispatch_threads_at_least(shader, compositing_region_size); + + image.unbind_as_texture(); + GPU_texture_image_unbind(output_texture); + GPU_shader_unbind(); } /* Executes when the alpha channel of the image is set as the value of the input alpha. */ void execute_set_alpha() { - GPUShader *shader = shader_manager().get("compositor_set_alpha"); + GPUShader *shader = shader_manager().get("compositor_write_output_alpha"); GPU_shader_bind(shader); + /* The compositing space might be limited to a subset of the output texture, so only write into + * that compositing region. */ + const rcti compositing_region = context().get_compositing_region(); + const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); + GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound); + const Result &image = get_input("Image"); - image.bind_as_texture(shader, "image_tx"); + image.bind_as_texture(shader, "input_tx"); const Result &alpha = get_input("Alpha"); alpha.bind_as_texture(shader, "alpha_tx"); @@ -126,7 +155,8 @@ class CompositeOperation : public NodeOperation { const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); - compute_dispatch_threads_at_least(shader, compute_domain().size); + const int2 compositing_region_size = context().get_compositing_region_size(); + compute_dispatch_threads_at_least(shader, compositing_region_size); image.unbind_as_texture(); alpha.unbind_as_texture(); @@ -142,10 +172,11 @@ class CompositeOperation : public NodeOperation { return bnode().custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA; } - /* The operation domain have the same dimensions of the output without any transformations. */ + /* The operation domain has the same size as the compositing region without any transformations + * applied. */ Domain compute_domain() override { - return Domain(context().get_output_size()); + return Domain(context().get_compositing_region_size()); } }; diff --git a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc index f06b64f10b5..2b222eb17b1 100644 --- a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc +++ b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc @@ -98,7 +98,7 @@ class EllipseMaskOperation : public NodeOperation { Domain compute_domain() override { if (get_input("Mask").is_single_value()) { - return Domain(context().get_output_size()); + return Domain(context().get_compositing_region_size()); } return get_input("Mask").domain(); } diff --git a/source/blender/nodes/composite/nodes/node_composite_image.cc b/source/blender/nodes/composite/nodes/node_composite_image.cc index e743c003701..98cd5834551 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.cc +++ b/source/blender/nodes/composite/nodes/node_composite_image.cc @@ -9,6 +9,7 @@ #include "BLI_linklist.h" #include "BLI_math_vec_types.hh" +#include "BLI_rect.h" #include "BLI_utildefines.h" #include "BLT_translation.h" @@ -23,6 +24,7 @@ #include "DEG_depsgraph_query.h" #include "DNA_scene_types.h" +#include "DNA_vec_types.h" #include "RE_engine.h" #include "RE_pipeline.h" @@ -825,30 +827,9 @@ class RenderLayerOperation : public NodeOperation { { const int view_layer = bnode().custom1; GPUTexture *pass_texture = context().get_input_texture(view_layer, SCE_PASS_COMBINED); - const int2 size = int2(GPU_texture_width(pass_texture), GPU_texture_height(pass_texture)); - /* Compute image output. */ - Result &image_result = get_result("Image"); - image_result.allocate_texture(Domain(size)); - GPU_texture_copy(image_result.texture(), pass_texture); - - /* Compute alpha output. */ - Result &alpha_result = get_result("Alpha"); - alpha_result.allocate_texture(Domain(size)); - - GPUShader *shader = shader_manager().get("compositor_extract_alpha_from_color"); - GPU_shader_bind(shader); - - const int input_unit = GPU_shader_get_texture_binding(shader, "input_tx"); - GPU_texture_bind(pass_texture, input_unit); - - alpha_result.bind_as_image(shader, "output_img"); - - compute_dispatch_threads_at_least(shader, size); - - GPU_shader_unbind(); - GPU_texture_unbind(pass_texture); - alpha_result.unbind_as_image(); + execute_image(pass_texture); + execute_alpha(pass_texture); /* Other output passes are not supported for now, so allocate them as invalid. */ for (const bNodeSocket *output : this->node()->output_sockets()) { @@ -861,6 +842,66 @@ class RenderLayerOperation : public NodeOperation { } } } + + void execute_image(GPUTexture *pass_texture) + { + Result &image_result = get_result("Image"); + if (!image_result.should_compute()) { + return; + } + + GPUShader *shader = shader_manager().get("compositor_read_pass"); + GPU_shader_bind(shader); + + /* The compositing space might be limited to a subset of the pass texture, so only read that + * compositing region into an appropriately sized texture. */ + const rcti compositing_region = context().get_compositing_region(); + const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); + GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound); + + const int input_unit = GPU_shader_get_texture_binding(shader, "input_tx"); + GPU_texture_bind(pass_texture, input_unit); + + const int2 compositing_region_size = context().get_compositing_region_size(); + image_result.allocate_texture(Domain(compositing_region_size)); + image_result.bind_as_image(shader, "output_img"); + + compute_dispatch_threads_at_least(shader, compositing_region_size); + + GPU_shader_unbind(); + GPU_texture_unbind(pass_texture); + image_result.unbind_as_image(); + } + + void execute_alpha(GPUTexture *pass_texture) + { + Result &alpha_result = get_result("Alpha"); + if (!alpha_result.should_compute()) { + return; + } + + GPUShader *shader = shader_manager().get("compositor_read_pass_alpha"); + GPU_shader_bind(shader); + + /* The compositing space might be limited to a subset of the pass texture, so only read that + * compositing region into an appropriately sized texture. */ + const rcti compositing_region = context().get_compositing_region(); + const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); + GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound); + + const int input_unit = GPU_shader_get_texture_binding(shader, "input_tx"); + GPU_texture_bind(pass_texture, input_unit); + + const int2 compositing_region_size = context().get_compositing_region_size(); + alpha_result.allocate_texture(Domain(compositing_region_size)); + alpha_result.bind_as_image(shader, "output_img"); + + compute_dispatch_threads_at_least(shader, compositing_region_size); + + GPU_shader_unbind(); + GPU_texture_unbind(pass_texture); + alpha_result.unbind_as_image(); + } }; static NodeOperation *get_compositor_operation(Context &context, DNode node) diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.cc b/source/blender/nodes/composite/nodes/node_composite_scale.cc index a4e28326d9d..a9c35e985a5 100644 --- a/source/blender/nodes/composite/nodes/node_composite_scale.cc +++ b/source/blender/nodes/composite/nodes/node_composite_scale.cc @@ -149,7 +149,7 @@ class ScaleOperation : public NodeOperation { float2 get_scale_render_size_stretch() { const float2 input_size = float2(get_input("Image").domain().size); - const float2 render_size = float2(context().get_output_size()); + const float2 render_size = float2(context().get_compositing_region_size()); return render_size / input_size; } @@ -160,7 +160,7 @@ class ScaleOperation : public NodeOperation { float2 get_scale_render_size_fit() { const float2 input_size = float2(get_input("Image").domain().size); - const float2 render_size = float2(context().get_output_size()); + const float2 render_size = float2(context().get_compositing_region_size()); const float2 scale = render_size / input_size; return float2(math::min(scale.x, scale.y)); } @@ -172,7 +172,7 @@ class ScaleOperation : public NodeOperation { float2 get_scale_render_size_crop() { const float2 input_size = float2(get_input("Image").domain().size); - const float2 render_size = float2(context().get_output_size()); + const float2 render_size = float2(context().get_compositing_region_size()); const float2 scale = render_size / input_size; return float2(math::max(scale.x, scale.y)); } diff --git a/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc b/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc index b4e698f5096..73dcf42904c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc +++ b/source/blender/nodes/composite/nodes/node_composite_split_viewer.cc @@ -60,10 +60,16 @@ class ViewerOperation : public NodeOperation { GPUShader *shader = get_split_viewer_shader(); GPU_shader_bind(shader); - const int2 size = compute_domain().size; + /* The compositing space might be limited to a subset of the output texture, so only write into + * that compositing region. */ + const rcti compositing_region = context().get_compositing_region(); + const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); + GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound); GPU_shader_uniform_1f(shader, "split_ratio", get_split_ratio()); - GPU_shader_uniform_2iv(shader, "view_size", size); + + const int2 compositing_region_size = context().get_compositing_region_size(); + GPU_shader_uniform_2iv(shader, "view_size", compositing_region_size); const Result &first_image = get_input("Image"); first_image.bind_as_texture(shader, "first_image_tx"); @@ -74,7 +80,7 @@ class ViewerOperation : public NodeOperation { const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); - compute_dispatch_threads_at_least(shader, size); + compute_dispatch_threads_at_least(shader, compositing_region_size); first_image.unbind_as_texture(); second_image.unbind_as_texture(); @@ -82,10 +88,11 @@ class ViewerOperation : public NodeOperation { GPU_shader_unbind(); } - /* The operation domain have the same dimensions of the output without any transformations. */ + /* The operation domain has the same size as the compositing region without any transformations + * applied. */ Domain compute_domain() override { - return Domain(context().get_output_size()); + return Domain(context().get_compositing_region_size()); } GPUShader *get_split_viewer_shader() diff --git a/source/blender/nodes/composite/nodes/node_composite_viewer.cc b/source/blender/nodes/composite/nodes/node_composite_viewer.cc index 682b0626ccd..dca2f7a1cda 100644 --- a/source/blender/nodes/composite/nodes/node_composite_viewer.cc +++ b/source/blender/nodes/composite/nodes/node_composite_viewer.cc @@ -110,9 +110,15 @@ class ViewerOperation : public NodeOperation { /* Executes when the alpha channel of the image is ignored. */ void execute_ignore_alpha() { - GPUShader *shader = shader_manager().get("compositor_convert_color_to_opaque"); + GPUShader *shader = shader_manager().get("compositor_write_output_opaque"); GPU_shader_bind(shader); + /* The compositing space might be limited to a smaller region of the output texture, so only + * write into that compositing region. */ + const rcti compositing_region = context().get_compositing_region(); + const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); + GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound); + const Result &image = get_input("Image"); image.bind_as_texture(shader, "input_tx"); @@ -120,7 +126,8 @@ class ViewerOperation : public NodeOperation { const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); - compute_dispatch_threads_at_least(shader, compute_domain().size); + const int2 compositing_region_size = context().get_compositing_region_size(); + compute_dispatch_threads_at_least(shader, compositing_region_size); image.unbind_as_texture(); GPU_texture_image_unbind(output_texture); @@ -131,22 +138,44 @@ class ViewerOperation : public NodeOperation { * to the output texture. */ void execute_copy() { + GPUShader *shader = shader_manager().get("compositor_write_output"); + GPU_shader_bind(shader); + + /* The compositing space might be limited to a smaller region of the output texture, so only + * write into that compositing region. */ + const rcti compositing_region = context().get_compositing_region(); + const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); + GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound); + const Result &image = get_input("Image"); + image.bind_as_texture(shader, "input_tx"); - /* Make sure any prior writes to the texture are reflected before copying it. */ - GPU_memory_barrier(GPU_BARRIER_TEXTURE_UPDATE); + GPUTexture *output_texture = context().get_output_texture(); + const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); + GPU_texture_image_bind(output_texture, image_unit); - GPU_texture_copy(context().get_output_texture(), image.texture()); + const int2 compositing_region_size = context().get_compositing_region_size(); + compute_dispatch_threads_at_least(shader, compositing_region_size); + + image.unbind_as_texture(); + GPU_texture_image_unbind(output_texture); + GPU_shader_unbind(); } /* Executes when the alpha channel of the image is set as the value of the input alpha. */ void execute_set_alpha() { - GPUShader *shader = shader_manager().get("compositor_set_alpha"); + GPUShader *shader = shader_manager().get("compositor_write_output_alpha"); GPU_shader_bind(shader); + /* The compositing space might be limited to a smaller region of the output texture, so only + * write into that compositing region. */ + const rcti compositing_region = context().get_compositing_region(); + const int2 lower_bound = int2(compositing_region.xmin, compositing_region.ymin); + GPU_shader_uniform_2iv(shader, "compositing_region_lower_bound", lower_bound); + const Result &image = get_input("Image"); - image.bind_as_texture(shader, "image_tx"); + image.bind_as_texture(shader, "input_tx"); const Result &alpha = get_input("Alpha"); alpha.bind_as_texture(shader, "alpha_tx"); @@ -155,7 +184,8 @@ class ViewerOperation : public NodeOperation { const int image_unit = GPU_shader_get_texture_binding(shader, "output_img"); GPU_texture_image_bind(output_texture, image_unit); - compute_dispatch_threads_at_least(shader, compute_domain().size); + const int2 compositing_region_size = context().get_compositing_region_size(); + compute_dispatch_threads_at_least(shader, compositing_region_size); image.unbind_as_texture(); alpha.unbind_as_texture(); @@ -171,10 +201,11 @@ class ViewerOperation : public NodeOperation { return bnode().custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA; } - /* The operation domain have the same dimensions of the output without any transformations. */ + /* The operation domain has the same size as the compositing region without any transformations + * applied. */ Domain compute_domain() override { - return Domain(context().get_output_size()); + return Domain(context().get_compositing_region_size()); } }; From 0bf8b984371bfe2a069ebbb80d85e7412b1f590c Mon Sep 17 00:00:00 2001 From: Omar Emara Date: Fri, 6 Jan 2023 14:50:39 +0200 Subject: [PATCH 0465/1522] Realtime Compositor: Move out of experimental This patch moves the realtime compositor out of experimental. See T99210. The first milestone is finished with regards to implementing most essential nodes for single pass compositing. It is also now documented in the manual and no major issues are known. Differential Revision: https://developer.blender.org/D16891 Reviewed By: Clement Foucault --- release/scripts/startup/bl_ui/space_userpref.py | 1 - release/scripts/startup/bl_ui/space_view3d.py | 3 +-- source/blender/draw/intern/draw_manager.c | 4 ---- source/blender/editors/space_node/node_draw.cc | 4 ---- source/blender/makesdna/DNA_userdef_types.h | 2 -- source/blender/makesrna/intern/rna_userdef.c | 4 ---- 6 files changed, 1 insertion(+), 17 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 49b07739e93..e58302fde06 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -2324,7 +2324,6 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel): ({"property": "use_sculpt_tools_tilt"}, "T82877"), ({"property": "use_extended_asset_browser"}, ("project/view/130/", "Project Page")), ({"property": "use_override_templates"}, ("T73318", "Milestone 4")), - ({"property": "use_realtime_compositor"}, "T99210"), ), ) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index f39dd131d43..83066cb70bf 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -6212,8 +6212,7 @@ class VIEW3D_PT_shading_compositor(Panel): @classmethod def poll(cls, context): - return (context.space_data.shading.type in {'MATERIAL', 'RENDERED'} and - context.preferences.experimental.use_realtime_compositor) + return context.space_data.shading.type in {'MATERIAL', 'RENDERED'} def draw(self, context): shading = context.space_data.shading diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 9e939fb490f..d322644f0c2 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1244,10 +1244,6 @@ static void drw_engines_enable_editors(void) static bool is_compositor_enabled(void) { - if (!U.experimental.use_realtime_compositor) { - return false; - } - if (DST.draw_ctx.v3d->shading.use_compositor == V3D_SHADING_USE_COMPOSITOR_DISABLED) { return false; } diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index dfa74f37058..1660f79fe5d 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -3086,10 +3086,6 @@ static void snode_setup_v2d(SpaceNode &snode, ARegion ®ion, const float2 &cen /* Similar to is_compositor_enabled() in draw_manager.c but checks all 3D views. */ static bool realtime_compositor_is_in_use(const bContext &context) { - if (!U.experimental.use_realtime_compositor) { - return false; - } - const Scene *scene = CTX_data_scene(&context); if (!scene->use_nodes) { return false; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 18c4508efae..4c9568d9228 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -652,8 +652,6 @@ typedef struct UserDef_Experimental { char use_override_templates; char enable_eevee_next; char use_sculpt_texture_paint; - char use_realtime_compositor; - char _pad0[7]; /** `makesdna` does not allow empty structs. */ } UserDef_Experimental; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index fdc916a270c..d10b82c4a16 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -6392,10 +6392,6 @@ static void rna_def_userdef_experimental(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Sculpt Mode Tilt Support", "Support for pen tablet tilt events in Sculpt Mode"); - prop = RNA_def_property(srna, "use_realtime_compositor", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "use_realtime_compositor", 1); - RNA_def_property_ui_text(prop, "Realtime Compositor", "Enable the new realtime compositor"); - prop = RNA_def_property(srna, "use_sculpt_texture_paint", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "use_sculpt_texture_paint", 1); RNA_def_property_ui_text(prop, "Sculpt Texture Paint", "Use texture painting in Sculpt Mode"); From d05909a70c36372cf6744bea71496b0138d60b5e Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sun, 25 Dec 2022 23:23:40 +0900 Subject: [PATCH 0466/1522] Fix T102766: Refactor liboverride diffing, by un-threading restoration step. The reported backtrace in T102766 strongly points at some concurrency issues within exisitng liboverride diffing code that restores forbidden changes to reference linked data values. This commit instead add tags to mark liboverrides/properties that need to be restored, and do so in a separate new step of diffing, from the main thread only. --- source/blender/blenkernel/BKE_lib_override.h | 25 +- .../blender/blenkernel/intern/lib_override.cc | 107 +++++- source/blender/makesdna/DNA_ID.h | 9 + source/blender/makesrna/RNA_access.h | 17 +- .../intern/rna_access_compare_override.c | 308 ++++++++++-------- 5 files changed, 311 insertions(+), 155 deletions(-) diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index a98984250b9..4928ffda0ec 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -410,8 +410,6 @@ bool BKE_lib_override_library_status_check_reference(struct Main *bmain, struct * \note This is by far the biggest operation (the more time-consuming) of the three so far, * since it has to go over all properties in depth (all overridable ones at least). * Generating differential values and applying overrides are much cheaper. - * - * \return true if any library operation was created. */ void BKE_lib_override_library_operations_create(struct Main *bmain, struct ID *local, @@ -425,6 +423,29 @@ void BKE_lib_override_library_main_operations_create(struct Main *bmain, bool force_auto, int *r_report_flags); +/** + * Restore forbidden modified override properties to the values of their matching properties in the + * linked reference ID. + * + * \param r_report_flags #eRNAOverrideMatchResult flags giving info about the result of this call. + * + * \note Typically used as part of BKE_lib_override_library_main_operations_create process, since + * modifying RNA properties from non-main threads is not safe. + */ +void BKE_lib_override_library_operations_restore(struct Main *bmain, + struct ID *local, + int *r_report_flags); +/** + * Restore forbidden modified override properties to the values of their matching properties in the + * linked reference ID, for all liboverride IDs tagged as needing such process in given `bmain`. + * + * \param r_report_flags #eRNAOverrideMatchResult flags giving info about the result of this call. + * + * \note Typically used as part of BKE_lib_override_library_main_operations_create process, since + * modifying RNA properties from non-main threads is not safe. + */ +void BKE_lib_override_library_main_operations_restore(struct Main *bmain, int *r_report_flags); + /** * Reset all overrides in given \a id_root, while preserving ID relations. * diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index ce7abe63eac..0cbed770ed1 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -3297,7 +3297,10 @@ bool BKE_lib_override_library_status_check_reference(Main *bmain, ID *local) return true; } -void BKE_lib_override_library_operations_create(Main *bmain, ID *local, int *r_report_flags) +static void lib_override_library_operations_create(Main *bmain, + ID *local, + const eRNAOverrideMatch override_match_flags, + eRNAOverrideMatchResult *r_report_flags) { BLI_assert(!ID_IS_LINKED(local)); BLI_assert(local->override_library != nullptr); @@ -3330,19 +3333,24 @@ void BKE_lib_override_library_operations_create(Main *bmain, ID *local, int *r_r RNA_id_pointer_create(local->override_library->reference, &rnaptr_reference); eRNAOverrideMatchResult local_report_flags = RNA_OVERRIDE_MATCH_RESULT_INIT; - RNA_struct_override_matches( - bmain, - &rnaptr_local, - &rnaptr_reference, - nullptr, - 0, - local->override_library, - (eRNAOverrideMatch)(RNA_OVERRIDE_COMPARE_CREATE | RNA_OVERRIDE_COMPARE_RESTORE), - &local_report_flags); + RNA_struct_override_matches(bmain, + &rnaptr_local, + &rnaptr_reference, + nullptr, + 0, + local->override_library, + override_match_flags, + &local_report_flags); if (local_report_flags & RNA_OVERRIDE_MATCH_RESULT_RESTORED) { CLOG_INFO(&LOG, 2, "We did restore some properties of %s from its reference", local->name); } + if (local_report_flags & RNA_OVERRIDE_MATCH_RESULT_RESTORE_TAGGED) { + CLOG_INFO(&LOG, + 2, + "We did tag some properties of %s for restoration from its reference", + local->name); + } if (local_report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) { CLOG_INFO(&LOG, 2, "We did generate library override rules for %s", local->name); } @@ -3351,10 +3359,50 @@ void BKE_lib_override_library_operations_create(Main *bmain, ID *local, int *r_r } if (r_report_flags != nullptr) { - *r_report_flags |= local_report_flags; + *r_report_flags = static_cast(*r_report_flags | local_report_flags); } } } +void BKE_lib_override_library_operations_create(Main *bmain, ID *local, int *r_report_flags) +{ + lib_override_library_operations_create( + bmain, + local, + static_cast(RNA_OVERRIDE_COMPARE_CREATE | RNA_OVERRIDE_COMPARE_RESTORE), + reinterpret_cast(r_report_flags)); +} + +void BKE_lib_override_library_operations_restore(Main *bmain, ID *local, int *r_report_flags) +{ + if (!ID_IS_OVERRIDE_LIBRARY_REAL(local) || (local->override_library->runtime->tag & + IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RESTORE) == 0) { + return; + } + + PointerRNA rnaptr_src, rnaptr_dst; + RNA_id_pointer_create(local, &rnaptr_dst); + RNA_id_pointer_create(local->override_library->reference, &rnaptr_src); + RNA_struct_override_apply( + bmain, + &rnaptr_dst, + &rnaptr_src, + nullptr, + local->override_library, + static_cast(RNA_OVERRIDE_APPLY_FLAG_SKIP_RESYNC_CHECK | + RNA_OVERRIDE_APPLY_FLAG_RESTORE_ONLY)); + + LISTBASE_FOREACH_MUTABLE ( + IDOverrideLibraryProperty *, op, &local->override_library->properties) { + if (op->tag & IDOVERRIDE_LIBRARY_PROPERTY_TAG_NEEDS_RETORE) { + BKE_lib_override_library_property_delete(local->override_library, op); + } + } + local->override_library->runtime->tag &= ~IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RESTORE; + + if (r_report_flags != nullptr) { + *r_report_flags |= RNA_OVERRIDE_MATCH_RESULT_RESTORED; + } +} struct LibOverrideOpCreateData { Main *bmain; @@ -3368,8 +3416,12 @@ static void lib_override_library_operations_create_cb(TaskPool *__restrict pool, ID *id = static_cast(taskdata); eRNAOverrideMatchResult report_flags = RNA_OVERRIDE_MATCH_RESULT_INIT; - BKE_lib_override_library_operations_create( - create_data->bmain, id, reinterpret_cast(&report_flags)); + lib_override_library_operations_create( + create_data->bmain, + id, + static_cast(RNA_OVERRIDE_COMPARE_CREATE | + RNA_OVERRIDE_COMPARE_TAG_FOR_RESTORE), + &report_flags); atomic_fetch_and_or_uint32(reinterpret_cast(&create_data->report_flags), report_flags); } @@ -3443,6 +3495,13 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, BLI_task_pool_free(task_pool); + if (create_pool_data.report_flags & RNA_OVERRIDE_MATCH_RESULT_RESTORE_TAGGED) { + BKE_lib_override_library_main_operations_restore( + bmain, reinterpret_cast(&create_pool_data.report_flags)); + create_pool_data.report_flags = static_cast( + (create_pool_data.report_flags & ~RNA_OVERRIDE_MATCH_RESULT_RESTORE_TAGGED)); + } + if (r_report_flags != nullptr) { *r_report_flags |= create_pool_data.report_flags; } @@ -3456,6 +3515,28 @@ void BKE_lib_override_library_main_operations_create(Main *bmain, #endif } +void BKE_lib_override_library_main_operations_restore(Main *bmain, int *r_report_flags) +{ + ID *id; + + FOREACH_MAIN_ID_BEGIN (bmain, id) { + if (!(!ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY_REAL(id) && + (id->override_library->runtime->tag & IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RESTORE) != + 0)) { + continue; + } + + /* Only restore overrides if we do have the real reference data available, and not some empty + * 'placeholder' for missing data (broken links). */ + if (id->override_library->reference->tag & LIB_TAG_MISSING) { + continue; + } + + BKE_lib_override_library_operations_restore(bmain, id, r_report_flags); + } + FOREACH_MAIN_ID_END; +} + static bool lib_override_library_id_reset_do(Main *bmain, ID *id_root, const bool do_reset_system_override) diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index c416d465ebb..8b3a8793883 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -274,6 +274,9 @@ typedef struct IDOverrideLibraryProperty { enum { /** This override property (operation) is unused and should be removed by cleanup process. */ IDOVERRIDE_LIBRARY_TAG_UNUSED = 1 << 0, + + /** This override property is forbidden and should be restored to its linked reference value. */ + IDOVERRIDE_LIBRARY_PROPERTY_TAG_NEEDS_RETORE = 1 << 1, }; # @@ -287,6 +290,12 @@ typedef struct IDOverrideLibraryRuntime { enum { /** This override needs to be reloaded. */ IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RELOAD = 1 << 0, + + /** + * This override contains properties with forbidden changes, which should be restored to their + * linked reference value. + */ + IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RESTORE = 1 << 1, }; /* Main container for all overriding data info of a data-block. */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 97bef9d4965..656b0bc93b2 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -798,8 +798,10 @@ typedef enum eRNAOverrideMatch { /** Create new property override if needed and possible. */ RNA_OVERRIDE_COMPARE_CREATE = 1 << 16, - /** Restore property's value(s) to reference ones if needed and possible. */ + /** Restore property's value(s) to reference ones, if needed and possible. */ RNA_OVERRIDE_COMPARE_RESTORE = 1 << 17, + /** Tag for restoration of property's value(s) to reference ones, if needed and possible. */ + RNA_OVERRIDE_COMPARE_TAG_FOR_RESTORE = 1 << 18, } eRNAOverrideMatch; typedef enum eRNAOverrideMatchResult { @@ -810,8 +812,13 @@ typedef enum eRNAOverrideMatchResult { * differences between local and reference. */ RNA_OVERRIDE_MATCH_RESULT_CREATED = 1 << 0, + /** + * Some properties are illegaly different from their reference values and have been tagged for + * restoration. + */ + RNA_OVERRIDE_MATCH_RESULT_RESTORE_TAGGED = 1 << 1, /** Some properties were reset to reference values. */ - RNA_OVERRIDE_MATCH_RESULT_RESTORED = 1 << 1, + RNA_OVERRIDE_MATCH_RESULT_RESTORED = 1 << 2, } eRNAOverrideMatchResult; typedef enum eRNAOverrideStatus { @@ -861,6 +868,12 @@ typedef enum eRNAOverrideApplyFlag { * pointers properties, unless the destination original value (the one being overridden) is NULL. */ RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS = 1 << 0, + + /** Do not check for liboverrides needing resync with their linked reference data. */ + RNA_OVERRIDE_APPLY_FLAG_SKIP_RESYNC_CHECK = 1 << 1, + + /** Only perform restore operations. */ + RNA_OVERRIDE_APPLY_FLAG_RESTORE_ONLY = 1 << 2, } eRNAOverrideApplyFlag; /** diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c index ca133320cb6..5e6579c7fa1 100644 --- a/source/blender/makesrna/intern/rna_access_compare_override.c +++ b/source/blender/makesrna/intern/rna_access_compare_override.c @@ -633,6 +633,7 @@ bool RNA_struct_override_matches(Main *bmain, const bool ignore_overridden = (flags & RNA_OVERRIDE_COMPARE_IGNORE_OVERRIDDEN) != 0; const bool do_create = (flags & RNA_OVERRIDE_COMPARE_CREATE) != 0; const bool do_restore = (flags & RNA_OVERRIDE_COMPARE_RESTORE) != 0; + const bool do_tag_for_restore = (flags & RNA_OVERRIDE_COMPARE_TAG_FOR_RESTORE) != 0; #ifdef DEBUG_OVERRIDE_TIMEIT static float _sum_time_global = 0.0f; @@ -779,7 +780,7 @@ bool RNA_struct_override_matches(Main *bmain, } #endif - eRNAOverrideMatchResult report_flags = 0; + eRNAOverrideMatchResult report_flags = RNA_OVERRIDE_MATCH_RESULT_INIT; const int diff = rna_property_override_diff(bmain, &prop_local, &prop_reference, @@ -800,7 +801,7 @@ bool RNA_struct_override_matches(Main *bmain, matching = matching && diff == 0; if (r_report_flags) { - *r_report_flags |= report_flags; + *r_report_flags = (*r_report_flags | report_flags); } if (diff != 0) { @@ -812,29 +813,52 @@ bool RNA_struct_override_matches(Main *bmain, BKE_lib_override_library_operations_tag(op, IDOVERRIDE_LIBRARY_TAG_UNUSED, false); } - if (do_restore && (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) == 0) { + if ((do_restore || do_tag_for_restore) && + (report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) == 0) { /* We are allowed to restore to reference's values. */ if (ELEM(NULL, op, opop) || opop->operation == IDOVERRIDE_LIBRARY_OP_NOOP) { - /* We should restore that property to its reference value */ if (RNA_property_editable(ptr_local, rawprop)) { - IDOverrideLibraryPropertyOperation opop_tmp = { - .operation = IDOVERRIDE_LIBRARY_OP_REPLACE, - .subitem_reference_index = -1, - .subitem_local_index = -1, - }; - rna_property_override_operation_apply(bmain, - ptr_local, - ptr_reference, - NULL, - rawprop, - rawprop, - NULL, - NULL, - NULL, - NULL, - &opop_tmp); - if (r_report_flags) { - *r_report_flags |= RNA_OVERRIDE_MATCH_RESULT_RESTORED; + /* This property should be restored to its reference value. This should not be done + * here, since this code may be called from non-main thread (modifying data through RNA + * is not thread safe). */ + BLI_assert(op == NULL); /* Forbidden orverride prop should not exist currently. */ + + if (do_restore) { + IDOverrideLibraryPropertyOperation opop_tmp = { + .operation = IDOVERRIDE_LIBRARY_OP_REPLACE, + .subitem_reference_index = -1, + .subitem_local_index = -1, + }; + rna_property_override_operation_apply(bmain, + ptr_local, + ptr_reference, + NULL, + rawprop, + rawprop, + NULL, + NULL, + NULL, + NULL, + &opop_tmp); + if (r_report_flags) { + *r_report_flags |= RNA_OVERRIDE_MATCH_RESULT_RESTORED; + } + } + else { + if (op == NULL) { + /* An override property is needed, create a temp one if necessary. */ + op = BKE_lib_override_library_property_get(override, rna_path, NULL); + BKE_lib_override_library_operations_tag(op, IDOVERRIDE_LIBRARY_TAG_UNUSED, true); + } + BKE_lib_override_library_property_operation_get( + op, IDOVERRIDE_LIBRARY_OP_REPLACE, NULL, NULL, -1, -1, false, NULL, NULL); + BKE_lib_override_library_operations_tag( + op, IDOVERRIDE_LIBRARY_PROPERTY_TAG_NEEDS_RETORE, true); + override->runtime->tag |= IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RESTORE; + + if (r_report_flags) { + *r_report_flags |= RNA_OVERRIDE_MATCH_RESULT_RESTORE_TAGGED; + } } } else { @@ -850,7 +874,7 @@ bool RNA_struct_override_matches(Main *bmain, else if ((report_flags & RNA_OVERRIDE_MATCH_RESULT_CREATED) == 0 && ELEM(NULL, op, opop)) { /* This property is not overridden, and differs from reference, so we have no match. */ matching = false; - if (!(do_create || do_restore)) { + if (!(do_create || do_restore || do_tag_for_restore)) { /* Since we have no 'changing' action allowed, we can break here. */ if (rna_path != rna_path_buffer) { MEM_freeN(rna_path); @@ -1188,132 +1212,30 @@ void RNA_struct_override_apply(Main *bmain, #ifdef DEBUG_OVERRIDE_TIMEIT TIMEIT_START_AVERAGED(RNA_struct_override_apply); #endif + const bool do_restore_only = (flag & RNA_OVERRIDE_APPLY_FLAG_RESTORE_ONLY) != 0; /* NOTE: Applying insert operations in a separate pass is mandatory. * We could optimize this later, but for now, as inefficient as it is, * don't think this is a critical point. */ bool do_insert = false; - for (int i = 0; i < 2; i++, do_insert = true) { + for (int i = 0; i < (do_restore_only ? 1 : 2); i++, do_insert = true) { LISTBASE_FOREACH (IDOverrideLibraryProperty *, op, &override->properties) { + if (do_restore_only && (op->tag % IDOVERRIDE_LIBRARY_PROPERTY_TAG_NEEDS_RETORE) == 0) { + continue; + } + /* That tag should only exist for short lifespan when restoring values from reference linked + * data. */ + BLI_assert((op->tag & IDOVERRIDE_LIBRARY_PROPERTY_TAG_NEEDS_RETORE) == 0 || do_restore_only); + /* Simplified for now! */ PointerRNA data_src, data_dst; PointerRNA data_item_src, data_item_dst; PropertyRNA *prop_src, *prop_dst; - if (RNA_path_resolve_property_and_item_pointer( - ptr_dst, op->rna_path, &data_dst, &prop_dst, &data_item_dst) && - RNA_path_resolve_property_and_item_pointer( - ptr_src, op->rna_path, &data_src, &prop_src, &data_item_src)) { - PointerRNA data_storage, data_item_storage; - PropertyRNA *prop_storage = NULL; - - /* It is totally OK if this does not success, - * only a subset of override operations actually need storage. */ - if (ptr_storage && (ptr_storage->owner_id != NULL)) { - RNA_path_resolve_property_and_item_pointer( - ptr_storage, op->rna_path, &data_storage, &prop_storage, &data_item_storage); - } - - /* Check if an overridden ID pointer supposed to be in sync with linked data gets out of - * sync. */ - if ((ptr_dst->owner_id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0) { - if (op->rna_prop_type == PROP_POINTER && - (((IDOverrideLibraryPropertyOperation *)op->operations.first)->flag & - IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) != 0) { - BLI_assert(RNA_struct_is_ID(RNA_property_pointer_type(&data_src, prop_src))); - BLI_assert(ptr_src->owner_id == - rna_property_override_property_real_id_owner(bmain, &data_src, NULL, NULL)); - BLI_assert(ptr_dst->owner_id == - rna_property_override_property_real_id_owner(bmain, &data_dst, NULL, NULL)); - - PointerRNA prop_ptr_src = RNA_property_pointer_get(&data_src, prop_src); - PointerRNA prop_ptr_dst = RNA_property_pointer_get(&data_dst, prop_dst); - rna_property_override_check_resync( - bmain, ptr_dst, ptr_src, &prop_ptr_dst, &prop_ptr_src); - } - else if (op->rna_prop_type == PROP_COLLECTION) { - if (RNA_struct_is_ID(RNA_property_pointer_type(&data_src, prop_src))) { - BLI_assert(ptr_src->owner_id == rna_property_override_property_real_id_owner( - bmain, &data_src, NULL, NULL)); - BLI_assert(ptr_dst->owner_id == rna_property_override_property_real_id_owner( - bmain, &data_dst, NULL, NULL)); - - LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { - if ((opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) == 0) { - continue; - } - - PointerRNA *ptr_item_dst, *ptr_item_src; - PointerRNA private_ptr_item_dst, private_ptr_item_src; - rna_porperty_override_collection_subitem_lookup(ptr_dst, - ptr_src, - NULL, - prop_dst, - prop_src, - NULL, - &ptr_item_dst, - &ptr_item_src, - NULL, - &private_ptr_item_dst, - &private_ptr_item_src, - NULL, - op, - opop); - - rna_property_override_check_resync( - bmain, ptr_dst, ptr_src, ptr_item_dst, ptr_item_src); - } - } - } - } - - /* Workaround for older broken overrides, we then assume that non-matching ID pointers - * override operations that replace a non-NULL value are 'mistakes', and ignore (do not - * apply) them. */ - if ((flag & RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS) != 0 && - op->rna_prop_type == PROP_POINTER && - (((IDOverrideLibraryPropertyOperation *)op->operations.first)->flag & - IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) == 0) { - BLI_assert(ptr_src->owner_id == - rna_property_override_property_real_id_owner(bmain, &data_src, NULL, NULL)); - BLI_assert(ptr_dst->owner_id == - rna_property_override_property_real_id_owner(bmain, &data_dst, NULL, NULL)); - - PointerRNA prop_ptr_dst = RNA_property_pointer_get(&data_dst, prop_dst); - if (prop_ptr_dst.type != NULL && RNA_struct_is_ID(prop_ptr_dst.type)) { -#ifndef NDEBUG - PointerRNA prop_ptr_src = RNA_property_pointer_get(&data_src, prop_src); - BLI_assert(prop_ptr_src.type == NULL || RNA_struct_is_ID(prop_ptr_src.type)); -#endif - ID *id_dst = rna_property_override_property_real_id_owner( - bmain, &prop_ptr_dst, NULL, NULL); - - if (id_dst != NULL) { - CLOG_INFO(&LOG, - 4, - "%s: Ignoring local override on ID pointer property '%s', as requested by " - "RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS flag", - ptr_dst->owner_id->name, - op->rna_path); - continue; - } - } - } - - rna_property_override_apply_ex(bmain, - &data_dst, - &data_src, - prop_storage ? &data_storage : NULL, - prop_dst, - prop_src, - prop_storage, - &data_item_dst, - &data_item_src, - prop_storage ? &data_item_storage : NULL, - op, - do_insert); - } - else { + if (!(RNA_path_resolve_property_and_item_pointer( + ptr_dst, op->rna_path, &data_dst, &prop_dst, &data_item_dst) && + RNA_path_resolve_property_and_item_pointer( + ptr_src, op->rna_path, &data_src, &prop_src, &data_item_src))) { CLOG_INFO(&LOG, 4, "Failed to apply library override operation to '%s.%s' " @@ -1322,7 +1244,117 @@ void RNA_struct_override_apply(Main *bmain, op->rna_path, RNA_path_resolve_property(ptr_dst, op->rna_path, &data_dst, &prop_dst), RNA_path_resolve_property(ptr_src, op->rna_path, &data_src, &prop_src)); + continue; } + PointerRNA data_storage, data_item_storage; + PropertyRNA *prop_storage = NULL; + + /* It is totally OK if this does not success, + * only a subset of override operations actually need storage. */ + if (ptr_storage && (ptr_storage->owner_id != NULL)) { + RNA_path_resolve_property_and_item_pointer( + ptr_storage, op->rna_path, &data_storage, &prop_storage, &data_item_storage); + } + + /* Check if an overridden ID pointer supposed to be in sync with linked data gets out of + * sync. */ + if ((flag & RNA_OVERRIDE_APPLY_FLAG_SKIP_RESYNC_CHECK) == 0 && + (ptr_dst->owner_id->tag & LIB_TAG_LIB_OVERRIDE_NEED_RESYNC) == 0) { + if (op->rna_prop_type == PROP_POINTER && + (((IDOverrideLibraryPropertyOperation *)op->operations.first)->flag & + IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) != 0) { + BLI_assert(RNA_struct_is_ID(RNA_property_pointer_type(&data_src, prop_src))); + BLI_assert(ptr_src->owner_id == + rna_property_override_property_real_id_owner(bmain, &data_src, NULL, NULL)); + BLI_assert(ptr_dst->owner_id == + rna_property_override_property_real_id_owner(bmain, &data_dst, NULL, NULL)); + + PointerRNA prop_ptr_src = RNA_property_pointer_get(&data_src, prop_src); + PointerRNA prop_ptr_dst = RNA_property_pointer_get(&data_dst, prop_dst); + rna_property_override_check_resync( + bmain, ptr_dst, ptr_src, &prop_ptr_dst, &prop_ptr_src); + } + else if (op->rna_prop_type == PROP_COLLECTION) { + if (RNA_struct_is_ID(RNA_property_pointer_type(&data_src, prop_src))) { + BLI_assert(ptr_src->owner_id == + rna_property_override_property_real_id_owner(bmain, &data_src, NULL, NULL)); + BLI_assert(ptr_dst->owner_id == + rna_property_override_property_real_id_owner(bmain, &data_dst, NULL, NULL)); + + LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { + if ((opop->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) == 0) { + continue; + } + + PointerRNA *ptr_item_dst, *ptr_item_src; + PointerRNA private_ptr_item_dst, private_ptr_item_src; + rna_porperty_override_collection_subitem_lookup(ptr_dst, + ptr_src, + NULL, + prop_dst, + prop_src, + NULL, + &ptr_item_dst, + &ptr_item_src, + NULL, + &private_ptr_item_dst, + &private_ptr_item_src, + NULL, + op, + opop); + + rna_property_override_check_resync( + bmain, ptr_dst, ptr_src, ptr_item_dst, ptr_item_src); + } + } + } + } + + /* Workaround for older broken overrides, we then assume that non-matching ID pointers + * override operations that replace a non-NULL value are 'mistakes', and ignore (do not + * apply) them. */ + if ((flag & RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS) != 0 && + op->rna_prop_type == PROP_POINTER && + (((IDOverrideLibraryPropertyOperation *)op->operations.first)->flag & + IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) == 0) { + BLI_assert(ptr_src->owner_id == + rna_property_override_property_real_id_owner(bmain, &data_src, NULL, NULL)); + BLI_assert(ptr_dst->owner_id == + rna_property_override_property_real_id_owner(bmain, &data_dst, NULL, NULL)); + + PointerRNA prop_ptr_dst = RNA_property_pointer_get(&data_dst, prop_dst); + if (prop_ptr_dst.type != NULL && RNA_struct_is_ID(prop_ptr_dst.type)) { +#ifndef NDEBUG + PointerRNA prop_ptr_src = RNA_property_pointer_get(&data_src, prop_src); + BLI_assert(prop_ptr_src.type == NULL || RNA_struct_is_ID(prop_ptr_src.type)); +#endif + ID *id_dst = rna_property_override_property_real_id_owner( + bmain, &prop_ptr_dst, NULL, NULL); + + if (id_dst != NULL) { + CLOG_INFO(&LOG, + 4, + "%s: Ignoring local override on ID pointer property '%s', as requested by " + "RNA_OVERRIDE_APPLY_FLAG_IGNORE_ID_POINTERS flag", + ptr_dst->owner_id->name, + op->rna_path); + continue; + } + } + } + + rna_property_override_apply_ex(bmain, + &data_dst, + &data_src, + prop_storage ? &data_storage : NULL, + prop_dst, + prop_src, + prop_storage, + &data_item_dst, + &data_item_src, + prop_storage ? &data_item_storage : NULL, + op, + do_insert); } } From e0d70e6a9d38812301d5c64f3586f8ca6ecc6ee9 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 6 Jan 2023 15:20:04 +0100 Subject: [PATCH 0467/1522] Nodes: avoid processing same node group multiple times to find textures This removes a lot of overhead when there are node groups that are reused a lot and only need to be processed once. --- .../editors/space_buttons/buttons_texture.cc | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/space_buttons/buttons_texture.cc b/source/blender/editors/space_buttons/buttons_texture.cc index 277402f1572..b4424474ebc 100644 --- a/source/blender/editors/space_buttons/buttons_texture.cc +++ b/source/blender/editors/space_buttons/buttons_texture.cc @@ -154,18 +154,23 @@ static void buttons_texture_users_find_nodetree(ListBase *users, } } -static void buttons_texture_modifier_geonodes_users_add(Object *ob, - NodesModifierData *nmd, - bNodeTree *node_tree, - ListBase *users) +static void buttons_texture_modifier_geonodes_users_add( + Object *ob, + NodesModifierData *nmd, + bNodeTree *node_tree, + ListBase *users, + blender::Set &handled_groups) { PointerRNA ptr; PropertyRNA *prop; for (bNode *node : node_tree->all_nodes()) { if (node->type == NODE_GROUP && node->id) { - /* Recurse into the node group */ - buttons_texture_modifier_geonodes_users_add(ob, nmd, (bNodeTree *)node->id, users); + if (handled_groups.add(reinterpret_cast(node->id))) { + /* Recurse into the node group */ + buttons_texture_modifier_geonodes_users_add( + ob, nmd, (bNodeTree *)node->id, users, handled_groups); + } } LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) { if (socket->flag & SOCK_UNAVAIL) { @@ -205,7 +210,8 @@ static void buttons_texture_modifier_foreach(void *userData, if (md->type == eModifierType_Nodes) { NodesModifierData *nmd = (NodesModifierData *)md; if (nmd->node_group != nullptr) { - buttons_texture_modifier_geonodes_users_add(ob, nmd, nmd->node_group, users); + blender::Set handled_groups; + buttons_texture_modifier_geonodes_users_add(ob, nmd, nmd->node_group, users, handled_groups); } } else { From a3a60e96470740f3b7439a3a4373667176f78fea Mon Sep 17 00:00:00 2001 From: Indy Ray Date: Fri, 6 Jan 2023 08:30:55 -0500 Subject: [PATCH 0468/1522] Nodes: Resolve performance bottleneck with mix node updates Improve animation playback performance in EEVEE for materials using Mix nodes. Socket availability was being set and reset on every evaluation of Mix nodes, during animation playback, this was causing the graph to be marked dirty, and the whole graph being re-evaluated on every frame, causing performance issues during playback. Additionally, do a bit of cleanup, traversing the node sockets with the next link to improve clarity and reduce errors. Also refactoring `nodeSetSocketAvailability` to early out and increase clarity on no-op. Differential Revision: https://developer.blender.org/D16929 --- source/blender/blenkernel/intern/node.cc | 6 +++--- .../nodes/shader/nodes/node_shader_mix.cc | 21 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index f72ba7a1378..0eb5889da65 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3561,16 +3561,16 @@ void nodeSetActive(bNodeTree *ntree, bNode *node) void nodeSetSocketAvailability(bNodeTree *ntree, bNodeSocket *sock, bool is_available) { const bool was_available = (sock->flag & SOCK_UNAVAIL) == 0; - if (is_available != was_available) { - BKE_ntree_update_tag_socket_availability(ntree, sock); + if (is_available == was_available) { + return; } - if (is_available) { sock->flag &= ~SOCK_UNAVAIL; } else { sock->flag |= SOCK_UNAVAIL; } + BKE_ntree_update_tag_socket_availability(ntree, sock); } int nodeSocketLinkLimit(const bNodeSocket *sock) diff --git a/source/blender/nodes/shader/nodes/node_shader_mix.cc b/source/blender/nodes/shader/nodes/node_shader_mix.cc index 4200041605c..a9bc1f7f98e 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix.cc @@ -108,22 +108,23 @@ static void sh_node_mix_update(bNodeTree *ntree, bNode *node) const NodeShaderMix &storage = node_storage(*node); const eNodeSocketDatatype data_type = static_cast(storage.data_type); - LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) { + bNodeSocket *sock_factor = static_cast(node->inputs.first); + bNodeSocket *sock_factor_vec = static_cast(sock_factor->next); + + bool use_vector_factor = data_type == SOCK_VECTOR && + storage.factor_mode != NODE_MIX_MODE_UNIFORM; + + nodeSetSocketAvailability(ntree, sock_factor, !use_vector_factor); + + nodeSetSocketAvailability(ntree, sock_factor_vec, use_vector_factor); + + for (bNodeSocket *socket = sock_factor_vec->next; socket != nullptr; socket = socket->next) { nodeSetSocketAvailability(ntree, socket, socket->type == data_type); } LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) { nodeSetSocketAvailability(ntree, socket, socket->type == data_type); } - - bool use_vector_factor = data_type == SOCK_VECTOR && - storage.factor_mode != NODE_MIX_MODE_UNIFORM; - - bNodeSocket *sock_factor = (bNodeSocket *)BLI_findlink(&node->inputs, 0); - nodeSetSocketAvailability(ntree, sock_factor, !use_vector_factor); - - bNodeSocket *sock_factor_vec = (bNodeSocket *)BLI_findlink(&node->inputs, 1); - nodeSetSocketAvailability(ntree, sock_factor_vec, use_vector_factor); } class SocketSearchOp { From 87fd798ae383a344d51dcbd9f66d5834595bdc5a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 6 Jan 2023 09:26:48 -0500 Subject: [PATCH 0469/1522] Nodes: Remove runtime socket location from struct Socket locations are set while drawing the node tree in the editor. They can always be recalculated this way based on the node position and other factors. Storing them in the socket is misleading. Plus, ideally sockets would be quite small to store, this helps us move in that direction. Now the socket locations are stored as runtime data of the node editor, making use of the new node topology cache's `index_in_tree` function to make a SoA layout possible. Differential Revision: https://developer.blender.org/D15874 --- source/blender/blenkernel/BKE_node_runtime.hh | 7 -- source/blender/editors/space_node/drawnode.cc | 34 ++++--- source/blender/editors/space_node/node_add.cc | 15 +-- .../blender/editors/space_node/node_draw.cc | 97 ++++++++++++------- .../blender/editors/space_node/node_edit.cc | 27 ++++-- .../blender/editors/space_node/node_intern.hh | 21 +++- .../editors/space_node/node_relationships.cc | 57 ++++++----- 7 files changed, 160 insertions(+), 98 deletions(-) diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index ca2fa5d0b01..6146e8ea7ae 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -169,13 +169,6 @@ class bNodeSocketRuntime : NonCopyable, NonMovable { /** #eNodeTreeChangedFlag. */ uint32_t changed_flag = 0; - /** - * The location of the sockets, in the view-space of the node editor. - * \note Only calculated when drawing. - */ - float locx = 0; - float locy = 0; - /** * Runtime-only cache of the number of input links, for multi-input sockets, * including dragged node links that aren't actually in the tree. diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 7c2e7c003a3..34b5ba3ab22 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -1582,11 +1582,12 @@ void draw_nodespace_back_pix(const bContext &C, GPU_matrix_pop(); } -static float2 socket_link_connection_location(const bNode &node, +static float2 socket_link_connection_location(const Span socket_locations, + const bNode &node, const bNodeSocket &socket, const bNodeLink &link) { - const float2 socket_location(socket.runtime->locx, socket.runtime->locy); + const float2 socket_location = socket_locations[socket.index_in_tree()]; if (socket.is_multi_input() && socket.is_input() && !(node.flag & NODE_HIDDEN)) { return node_link_calculate_multi_input_position( socket_location, link.multi_input_socket_index, socket.runtime->total_inputs); @@ -1620,11 +1621,13 @@ static void calculate_inner_link_bezier_points(std::array &points) } } -static std::array node_link_bezier_points(const bNodeLink &link) +static std::array node_link_bezier_points(const Span socket_locations, + const bNodeLink &link) { std::array points; - points[0] = socket_link_connection_location(*link.fromnode, *link.fromsock, link); - points[3] = socket_link_connection_location(*link.tonode, *link.tosock, link); + points[0] = socket_link_connection_location( + socket_locations, *link.fromnode, *link.fromsock, link); + points[3] = socket_link_connection_location(socket_locations, *link.tonode, *link.tosock, link); calculate_inner_link_bezier_points(points); return points; } @@ -1640,10 +1643,11 @@ static bool node_link_draw_is_visible(const View2D &v2d, const std::array socket_locations, + const bNodeLink &link, std::array &coords) { - const std::array points = node_link_bezier_points(link); + const std::array points = node_link_bezier_points(socket_locations, link); /* The extra +1 in size is required by these functions and would be removed ideally. */ BKE_curve_forward_diff_bezier(points[0].x, @@ -2028,7 +2032,9 @@ static NodeLinkDrawConfig nodelink_get_draw_config(const bContext &C, draw_config.th_col2 = th_col2; draw_config.th_col3 = th_col3; - draw_config.dim_factor = selected ? 1.0f : node_link_dim_factor(v2d, link); + draw_config.dim_factor = selected ? 1.0f : + node_link_dim_factor( + snode.runtime->all_socket_locations, v2d, link); bTheme *btheme = UI_GetTheme(); draw_config.dash_alpha = btheme->space_node.dash_alpha; @@ -2154,7 +2160,8 @@ void node_draw_link_bezier(const bContext &C, const int th_col3, const bool selected) { - const std::array points = node_link_bezier_points(link); + const std::array points = node_link_bezier_points(snode.runtime->all_socket_locations, + link); if (!node_link_draw_is_visible(v2d, points)) { return; } @@ -2216,10 +2223,13 @@ static std::array node_link_bezier_points_dragged(const SpaceNode &sn const float2 cursor = snode.runtime->cursor * UI_DPI_FAC; std::array points; points[0] = link.fromsock ? - socket_link_connection_location(*link.fromnode, *link.fromsock, link) : + socket_link_connection_location( + snode.runtime->all_socket_locations, *link.fromnode, *link.fromsock, link) : + cursor; + points[3] = link.tosock ? + socket_link_connection_location( + snode.runtime->all_socket_locations, *link.tonode, *link.tosock, link) : cursor; - points[3] = link.tosock ? socket_link_connection_location(*link.tonode, *link.tosock, link) : - cursor; calculate_inner_link_bezier_points(points); return points; } diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc index 534222b58e6..0e3e6f0ece9 100644 --- a/source/blender/editors/space_node/node_add.cc +++ b/source/blender/editors/space_node/node_add.cc @@ -107,10 +107,12 @@ bNode *add_static_node(const bContext &C, int type, const float2 &location) /** \name Add Reroute Operator * \{ */ -std::optional link_path_intersection(const bNodeLink &link, const Span path) +std::optional link_path_intersection(const Span socket_locations, + const bNodeLink &link, + const Span path) { std::array coords; - node_link_bezier_points_evaluated(link, coords); + node_link_bezier_points_evaluated(socket_locations, link, coords); for (const int i : path.index_range().drop_back(1)) { for (const int j : IndexRange(NODE_LINK_RESOL)) { @@ -136,6 +138,7 @@ static int add_reroute_exec(bContext *C, wmOperator *op) const ARegion ®ion = *CTX_wm_region(C); SpaceNode &snode = *CTX_wm_space_node(C); bNodeTree &ntree = *snode.edittree; + const Span socket_locations = snode.runtime->all_socket_locations; Vector path; RNA_BEGIN (op->ptr, itemptr, "path") { @@ -167,16 +170,16 @@ static int add_reroute_exec(bContext *C, wmOperator *op) Map cuts_per_socket; LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { - if (node_link_is_hidden_or_dimmed(region.v2d, *link)) { + if (node_link_is_hidden_or_dimmed(socket_locations, region.v2d, *link)) { continue; } - const std::optional intersection = link_path_intersection(*link, path); - if (!intersection) { + const std::optional cut = link_path_intersection(socket_locations, *link, path); + if (!cut) { continue; } RerouteCutsForSocket &from_cuts = cuts_per_socket.lookup_or_add_default(link->fromsock); from_cuts.from_node = link->fromnode; - from_cuts.links.add(link, *intersection); + from_cuts.links.add(link, *cut); } for (const auto item : cuts_per_socket.items()) { diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 1660f79fe5d..98f45fc4956 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -317,7 +317,8 @@ static void node_update_basis(const bContext &C, const TreeDrawContext & /*tree_draw_ctx*/, bNodeTree &ntree, bNode &node, - uiBlock &block) + uiBlock &block, + MutableSpan socket_locations) { PointerRNA nodeptr; RNA_pointer_create(&ntree.id, &RNA_Node, &node, &nodeptr); @@ -387,8 +388,8 @@ static void node_update_basis(const bContext &C, buty = min_ii(buty, dy - NODE_DY); /* Round the socket location to stop it from jiggling. */ - socket->runtime->locx = round(loc.x + NODE_WIDTH(node)); - socket->runtime->locy = round(dy - NODE_DYS); + socket_locations[socket->index_in_tree()] = float2(round(loc.x + NODE_WIDTH(node)), + round(dy - NODE_DYS)); dy = buty; if (socket->next) { @@ -519,9 +520,8 @@ static void node_update_basis(const bContext &C, /* Ensure minimum socket height in case layout is empty. */ buty = min_ii(buty, dy - NODE_DY); - socket->runtime->locx = loc.x; /* Round the socket vertical position to stop it from jiggling. */ - socket->runtime->locy = round(dy - NODE_DYS); + socket_locations[socket->index_in_tree()] = float2(loc.x, round(dy - NODE_DYS)); dy = buty - multi_input_socket_offset * 0.5; if (socket->next) { @@ -551,7 +551,7 @@ static void node_update_basis(const bContext &C, /** * Based on settings in node, sets drawing rect info. */ -static void node_update_hidden(bNode &node, uiBlock &block) +static void node_update_hidden(bNode &node, uiBlock &block, MutableSpan socket_locations) { int totin = 0, totout = 0; @@ -591,8 +591,9 @@ static void node_update_hidden(bNode &node, uiBlock &block) for (bNodeSocket *socket : node.output_sockets()) { if (socket->is_visible()) { /* Round the socket location to stop it from jiggling. */ - socket->runtime->locx = round(node.runtime->totr.xmax - hiddenrad + sinf(rad) * hiddenrad); - socket->runtime->locy = round(node.runtime->totr.ymin + hiddenrad + cosf(rad) * hiddenrad); + socket_locations[socket->index_in_tree()] = { + round(node.runtime->totr.xmax - hiddenrad + sinf(rad) * hiddenrad), + round(node.runtime->totr.ymin + hiddenrad + cosf(rad) * hiddenrad)}; rad += drad; } } @@ -603,8 +604,9 @@ static void node_update_hidden(bNode &node, uiBlock &block) for (bNodeSocket *socket : node.input_sockets()) { if (socket->is_visible()) { /* Round the socket location to stop it from jiggling. */ - socket->runtime->locx = round(node.runtime->totr.xmin + hiddenrad + sinf(rad) * hiddenrad); - socket->runtime->locy = round(node.runtime->totr.ymin + hiddenrad + cosf(rad) * hiddenrad); + socket_locations[socket->index_in_tree()] = { + round(node.runtime->totr.xmin + hiddenrad + sinf(rad) * hiddenrad), + round(node.runtime->totr.ymin + hiddenrad + cosf(rad) * hiddenrad)}; rad += drad; } } @@ -1169,6 +1171,7 @@ void node_socket_add_tooltip(const bNodeTree &ntree, const bNodeSocket &sock, ui static void node_socket_draw_nested(const bContext &C, const bNodeTree &ntree, + const Span socket_locations, PointerRNA &node_ptr, uiBlock &block, const bNodeSocket &sock, @@ -1180,7 +1183,7 @@ static void node_socket_draw_nested(const bContext &C, const float size, const bool selected) { - const float2 location(sock.runtime->locx, sock.runtime->locy); + const float2 location = socket_locations[sock.index_in_tree()]; float color[4]; float outline_color[4]; @@ -1382,6 +1385,7 @@ static void node_draw_shadow(const SpaceNode &snode, static void node_draw_sockets(const View2D &v2d, const bContext &C, const bNodeTree &ntree, + const Span socket_locations, const bNode &node, uiBlock &block, const bool draw_outputs, @@ -1441,6 +1445,7 @@ static void node_draw_sockets(const View2D &v2d, node_socket_draw_nested(C, ntree, + socket_locations, node_ptr, block, *sock, @@ -1467,6 +1472,7 @@ static void node_draw_sockets(const View2D &v2d, node_socket_draw_nested(C, ntree, + socket_locations, node_ptr, block, *sock, @@ -1505,6 +1511,7 @@ static void node_draw_sockets(const View2D &v2d, if (select_all || (sock->flag & SELECT)) { node_socket_draw_nested(C, ntree, + socket_locations, node_ptr, block, *sock, @@ -1532,6 +1539,7 @@ static void node_draw_sockets(const View2D &v2d, if (select_all || (sock->flag & SELECT)) { node_socket_draw_nested(C, ntree, + socket_locations, node_ptr, block, *sock, @@ -1577,7 +1585,7 @@ static void node_draw_sockets(const View2D &v2d, node_socket_color_get(C, ntree, node_ptr, *socket, color); node_socket_outline_color_get(socket->flag & SELECT, socket->type, outline_color); - const float2 location(socket->runtime->locx, socket->runtime->locy); + const float2 location = socket_locations[socket->index_in_tree()]; node_socket_draw_multi_input(color, outline_color, width, height, location); } } @@ -2084,6 +2092,7 @@ static void node_draw_basis(const bContext &C, const View2D &v2d, const SpaceNode &snode, bNodeTree &ntree, + const Span socket_locations, const bNode &node, uiBlock &block, bNodeInstanceKey key) @@ -2384,7 +2393,7 @@ static void node_draw_basis(const bContext &C, /* Skip slow socket drawing if zoom is small. */ if (scale > 0.2f) { - node_draw_sockets(v2d, C, ntree, node, block, true, false); + node_draw_sockets(v2d, C, ntree, socket_locations, node, block, true, false); } /* Preview. */ @@ -2408,6 +2417,7 @@ static void node_draw_hidden(const bContext &C, const View2D &v2d, const SpaceNode &snode, bNodeTree &ntree, + const Span socket_locations, bNode &node, uiBlock &block) { @@ -2577,7 +2587,7 @@ static void node_draw_hidden(const bContext &C, immUnbindProgram(); GPU_blend(GPU_BLEND_NONE); - node_draw_sockets(v2d, C, ntree, node, block, true, false); + node_draw_sockets(v2d, C, ntree, socket_locations, node, block, true, false); UI_block_end(&C, &block); UI_block_draw(&C, &block); @@ -2710,18 +2720,13 @@ static void frame_node_prepare_for_draw(bNode &node, Span nodes) node.runtime->totr = rect; } -static void reroute_node_prepare_for_draw(bNode &node) +static void reroute_node_prepare_for_draw(bNode &node, MutableSpan socket_locations) { const float2 loc = node_to_view(node, float2(0)); /* Reroute node has exactly one input and one output, both in the same place. */ - bNodeSocket *socket = (bNodeSocket *)node.outputs.first; - socket->runtime->locx = loc.x; - socket->runtime->locy = loc.y; - - socket = (bNodeSocket *)node.inputs.first; - socket->runtime->locx = loc.x; - socket->runtime->locy = loc.y; + socket_locations[node.input_socket(0).index_in_tree()] = loc; + socket_locations[node.output_socket(0).index_in_tree()] = loc; const float size = 8.0f; node.width = size * 2; @@ -2735,7 +2740,8 @@ static void node_update_nodetree(const bContext &C, TreeDrawContext &tree_draw_ctx, bNodeTree &ntree, Span nodes, - Span blocks) + Span blocks, + MutableSpan socket_locations) { /* Make sure socket "used" tags are correct, for displaying value buttons. */ SpaceNode *snode = CTX_wm_space_node(&C); @@ -2751,14 +2757,14 @@ static void node_update_nodetree(const bContext &C, } if (node.is_reroute()) { - reroute_node_prepare_for_draw(node); + reroute_node_prepare_for_draw(node, socket_locations); } else { if (node.flag & NODE_HIDDEN) { - node_update_hidden(node, block); + node_update_hidden(node, block, socket_locations); } else { - node_update_basis(C, tree_draw_ctx, ntree, node, block); + node_update_basis(C, tree_draw_ctx, ntree, node, block, socket_locations); } } } @@ -2911,8 +2917,12 @@ static void frame_node_draw(const bContext &C, UI_block_draw(&C, &block); } -static void reroute_node_draw( - const bContext &C, ARegion ®ion, bNodeTree &ntree, bNode &node, uiBlock &block) +static void reroute_node_draw(const bContext &C, + ARegion ®ion, + bNodeTree &ntree, + const Span socket_locations, + const bNode &node, + uiBlock &block) { /* Skip if out of view. */ const rctf &rct = node.runtime->totr; @@ -2950,7 +2960,8 @@ static void reroute_node_draw( /* Only draw input socket as they all are placed on the same position highlight * if node itself is selected, since we don't display the node body separately. */ - node_draw_sockets(region.v2d, C, ntree, node, block, false, node.flag & SELECT); + node_draw_sockets( + region.v2d, C, ntree, socket_locations, node, block, false, node.flag & SELECT); UI_block_end(&C, &block); UI_block_draw(&C, &block); @@ -2961,6 +2972,7 @@ static void node_draw(const bContext &C, ARegion ®ion, const SpaceNode &snode, bNodeTree &ntree, + const Span socket_locations, bNode &node, uiBlock &block, bNodeInstanceKey key) @@ -2969,15 +2981,15 @@ static void node_draw(const bContext &C, frame_node_draw(C, tree_draw_ctx, region, snode, ntree, node, block); } else if (node.is_reroute()) { - reroute_node_draw(C, region, ntree, node, block); + reroute_node_draw(C, region, ntree, socket_locations, node, block); } else { const View2D &v2d = region.v2d; if (node.flag & NODE_HIDDEN) { - node_draw_hidden(C, tree_draw_ctx, v2d, snode, ntree, node, block); + node_draw_hidden(C, tree_draw_ctx, v2d, snode, ntree, socket_locations, node, block); } else { - node_draw_basis(C, tree_draw_ctx, v2d, snode, ntree, node, block, key); + node_draw_basis(C, tree_draw_ctx, v2d, snode, ntree, socket_locations, node, block, key); } } } @@ -2989,6 +3001,7 @@ static void node_draw_nodetree(const bContext &C, ARegion ®ion, SpaceNode &snode, bNodeTree &ntree, + const Span socket_locations, Span nodes, Span blocks, bNodeInstanceKey parent_key) @@ -3010,7 +3023,8 @@ static void node_draw_nodetree(const bContext &C, } const bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]); - node_draw(C, tree_draw_ctx, region, snode, ntree, *nodes[i], *blocks[i], key); + node_draw( + C, tree_draw_ctx, region, snode, ntree, socket_locations, *nodes[i], *blocks[i], key); } /* Node lines. */ @@ -3040,7 +3054,8 @@ static void node_draw_nodetree(const bContext &C, } const bNodeInstanceKey key = BKE_node_instance_key(parent_key, &ntree, nodes[i]); - node_draw(C, tree_draw_ctx, region, snode, ntree, *nodes[i], *blocks[i], key); + node_draw( + C, tree_draw_ctx, region, snode, ntree, socket_locations, *nodes[i], *blocks[i], key); } } @@ -3147,9 +3162,19 @@ static void draw_nodetree(const bContext &C, else if (ntree.type == NTREE_COMPOSIT) { tree_draw_ctx.used_by_realtime_compositor = realtime_compositor_is_in_use(C); } + snode->runtime->all_socket_locations.reinitialize(ntree.all_sockets().size()); - node_update_nodetree(C, tree_draw_ctx, ntree, nodes, blocks); - node_draw_nodetree(C, tree_draw_ctx, region, *snode, ntree, nodes, blocks, parent_key); + node_update_nodetree( + C, tree_draw_ctx, ntree, nodes, blocks, snode->runtime->all_socket_locations); + node_draw_nodetree(C, + tree_draw_ctx, + region, + *snode, + ntree, + snode->runtime->all_socket_locations, + nodes, + blocks, + parent_key); } /** diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index fb4173a9b6b..336ed1cb6d3 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -1099,10 +1099,12 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set) } } -static bool cursor_isect_multi_input_socket(const float2 &cursor, const bNodeSocket &socket) +static bool cursor_isect_multi_input_socket(const Span socket_locations, + const float2 &cursor, + const bNodeSocket &socket) { const float node_socket_height = node_socket_calculate_height(socket); - const float2 location(socket.runtime->locx, socket.runtime->locy); + const float2 location = socket_locations[socket.index_in_tree()]; /* `.xmax = socket->locx + NODE_SOCKSIZE * 5.5f` * would be the same behavior as for regular sockets. * But keep it smaller because for multi-input socket you @@ -1128,6 +1130,7 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode, const float size_sock_padded = NODE_SOCKSIZE + 4; snode.edittree->ensure_topology_cache(); + const Span socket_locations = snode.runtime->all_socket_locations; const Span nodes = snode.edittree->all_nodes(); for (int i = nodes.index_range().last(); i >= 0; i--) { @@ -1149,9 +1152,9 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode, if (in_out & SOCK_IN) { for (bNodeSocket *sock : node.input_sockets()) { if (sock->is_visible()) { - const float2 location(sock->runtime->locx, sock->runtime->locy); + const float2 location = socket_locations[sock->index_in_tree()]; if (sock->flag & SOCK_MULTI_INPUT && !(node.flag & NODE_HIDDEN)) { - if (cursor_isect_multi_input_socket(cursor, *sock)) { + if (cursor_isect_multi_input_socket(socket_locations, cursor, *sock)) { if (!socket_is_occluded(location, node, snode)) { return sock; } @@ -1168,7 +1171,7 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode, if (in_out & SOCK_OUT) { for (bNodeSocket *sock : node.output_sockets()) { if (sock->is_visible()) { - const float2 location(sock->runtime->locx, sock->runtime->locy); + const float2 location = socket_locations[sock->index_in_tree()]; if (BLI_rctf_isect_pt(&rect, location.x, location.y)) { if (!socket_is_occluded(location, node, snode)) { return sock; @@ -1188,14 +1191,16 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode, /** \name Node Link Dimming * \{ */ -float node_link_dim_factor(const View2D &v2d, const bNodeLink &link) +float node_link_dim_factor(const Span socket_locations, + const View2D &v2d, + const bNodeLink &link) { if (link.fromsock == nullptr || link.tosock == nullptr) { return 1.0f; } - const float2 from(link.fromsock->runtime->locx, link.fromsock->runtime->locy); - const float2 to(link.tosock->runtime->locx, link.tosock->runtime->locy); + const float2 from = socket_locations[link.fromsock->index_in_tree()]; + const float2 to = socket_locations[link.tosock->index_in_tree()]; const float min_endpoint_distance = std::min( std::max(BLI_rctf_length_x(&v2d.cur, from.x), BLI_rctf_length_y(&v2d.cur, from.y)), @@ -1208,9 +1213,11 @@ float node_link_dim_factor(const View2D &v2d, const bNodeLink &link) return std::clamp(1.0f - min_endpoint_distance / viewport_width * 10.0f, 0.05f, 1.0f); } -bool node_link_is_hidden_or_dimmed(const View2D &v2d, const bNodeLink &link) +bool node_link_is_hidden_or_dimmed(const Span socket_locations, + const View2D &v2d, + const bNodeLink &link) { - return nodeLinkIsHidden(&link) || node_link_dim_factor(v2d, link) < 0.5f; + return nodeLinkIsHidden(&link) || node_link_dim_factor(socket_locations, v2d, link) < 0.5f; } /** \} */ diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index 74ee9f6b3ad..fe7af557f2f 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -73,6 +73,12 @@ struct bNodeLinkDrag { }; struct SpaceNode_Runtime { + /** + * The location of all sockets in the tree, calculated while drawing the nodes. + * To be indexed with #bNodeSocket::index_in_tree(). + */ + Vector all_socket_locations; + float aspect; /** Mouse position for drawing socket-less links and adding nodes. */ @@ -241,10 +247,13 @@ void node_draw_link_bezier(const bContext &C, int th_col3, bool selected); -void node_link_bezier_points_evaluated(const bNodeLink &link, +void node_link_bezier_points_evaluated(Span all_socket_locations, + const bNodeLink &link, std::array &coords); -std::optional link_path_intersection(const bNodeLink &link, Span path); +std::optional link_path_intersection(Span socket_locations, + const bNodeLink &link, + Span path); void draw_nodespace_back_pix(const bContext &C, ARegion ®ion, @@ -314,8 +323,12 @@ int node_render_changed_exec(bContext *, wmOperator *); bNodeSocket *node_find_indicated_socket(SpaceNode &snode, const float2 &cursor, eNodeSocketInOut in_out); -float node_link_dim_factor(const View2D &v2d, const bNodeLink &link); -bool node_link_is_hidden_or_dimmed(const View2D &v2d, const bNodeLink &link); +float node_link_dim_factor(Span socket_locations, + const View2D &v2d, + const bNodeLink &link); +bool node_link_is_hidden_or_dimmed(Span socket_locations, + const View2D &v2d, + const bNodeLink &link); void NODE_OT_duplicate(wmOperatorType *ot); void NODE_OT_delete(wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 9fc18fc2235..3e62a1023f5 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -121,6 +121,7 @@ static void pick_input_link_by_link_intersect(const bContext &C, const float2 &cursor) { SpaceNode *snode = CTX_wm_space_node(&C); + const Span socket_locations = snode->runtime->all_socket_locations; float2 drag_start; RNA_float_get_array(op.ptr, "drag_start", drag_start); @@ -135,7 +136,7 @@ static void pick_input_link_by_link_intersect(const bContext &C, for (bNodeLink *link : socket->directly_linked_links()) { /* Test if the cursor is near a link. */ std::array coords; - node_link_bezier_points_evaluated(*link, coords); + node_link_bezier_points_evaluated(socket_locations, *link, coords); for (const int i : IndexRange(coords.size() - 1)) { const float distance = dist_squared_to_line_segment_v2(cursor, coords[i], coords[i + 1]); @@ -288,11 +289,12 @@ struct LinkAndPosition { float2 multi_socket_position; }; -static void sort_multi_input_socket_links_with_drag(bNodeSocket &socket, +static void sort_multi_input_socket_links_with_drag(const Span socket_locations, + bNodeSocket &socket, bNodeLink &drag_link, const float2 &cursor) { - const float2 &socket_location = {socket.runtime->locx, socket.runtime->locy}; + const float2 &socket_location = socket_locations[socket.index_in_tree()]; Vector links; for (bNodeLink *link : socket.directly_linked_links()) { @@ -635,9 +637,10 @@ static int view_socket(const bContext &C, } } if (viewer_node == nullptr) { + const float2 socket_location = + snode.runtime->all_socket_locations[bsocket_to_view.index_in_tree()]; const int viewer_type = get_default_viewer_type(&C); - const float2 location{bsocket_to_view.runtime->locx / UI_DPI_FAC + 100, - bsocket_to_view.runtime->locy / UI_DPI_FAC}; + const float2 location{socket_location.x / UI_DPI_FAC + 100, socket_location.y / UI_DPI_FAC}; viewer_node = add_static_node(C, viewer_type, location); } @@ -968,7 +971,8 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur continue; } if (tsock && tsock->is_multi_input()) { - sort_multi_input_socket_links_with_drag(*tsock, link, cursor); + sort_multi_input_socket_links_with_drag( + snode.runtime->all_socket_locations, *tsock, link, cursor); } } } @@ -1306,28 +1310,33 @@ static int cut_links_exec(bContext *C, wmOperator *op) ED_preview_kill_jobs(CTX_wm_manager(C), &bmain); bNodeTree &node_tree = *snode.edittree; + node_tree.ensure_topology_cache(); + const Span socket_locations = snode.runtime->all_socket_locations; - Set affected_nodes; - - LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &node_tree.links) { - if (node_link_is_hidden_or_dimmed(region.v2d, *link)) { + Set links_to_remove; + LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) { + if (node_link_is_hidden_or_dimmed(socket_locations, region.v2d, *link)) { continue; } - if (link_path_intersection(*link, path)) { + if (link_path_intersection(socket_locations, *link, path)) { if (!found) { /* TODO(sergey): Why did we kill jobs twice? */ ED_preview_kill_jobs(CTX_wm_manager(C), &bmain); found = true; } - - bNode *to_node = link->tonode; - nodeRemLink(snode.edittree, link); - affected_nodes.add(to_node); + links_to_remove.add(link); } } + Set affected_nodes; + for (bNodeLink *link : links_to_remove) { + bNode *to_node = link->tonode; + nodeRemLink(snode.edittree, link); + affected_nodes.add(to_node); + } + node_tree.ensure_topology_cache(); for (bNode *node : affected_nodes) { update_multi_input_indices_for_removed_links(*node); @@ -1388,6 +1397,7 @@ static int mute_links_exec(bContext *C, wmOperator *op) SpaceNode &snode = *CTX_wm_space_node(C); const ARegion ®ion = *CTX_wm_region(C); bNodeTree &ntree = *snode.edittree; + const Span socket_locations = snode.runtime->all_socket_locations; Vector path; RNA_BEGIN (op->ptr, itemptr, "path") { @@ -1412,10 +1422,10 @@ static int mute_links_exec(bContext *C, wmOperator *op) Set affected_links; LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { - if (node_link_is_hidden_or_dimmed(region.v2d, *link)) { + if (node_link_is_hidden_or_dimmed(socket_locations, region.v2d, *link)) { continue; } - if (!link_path_intersection(*link, path)) { + if (!link_path_intersection(socket_locations, *link, path)) { continue; } affected_links.add(link); @@ -1434,21 +1444,21 @@ static int mute_links_exec(bContext *C, wmOperator *op) /* Propagate mute status downstream past reroute nodes. */ if (link->tonode->is_reroute()) { Stack links; - links.push_multiple(link->tonode->output_sockets().first()->directly_linked_links()); + links.push_multiple(link->tonode->output_socket(0).directly_linked_links()); while (!links.is_empty()) { bNodeLink *link = links.pop(); nodeLinkSetMute(&ntree, link, muted); if (!link->tonode->is_reroute()) { continue; } - links.push_multiple(link->tonode->output_sockets().first()->directly_linked_links()); + links.push_multiple(link->tonode->output_socket(0).directly_linked_links()); } } /* Propagate mute status upstream past reroutes, but only if all outputs are muted. */ if (link->fromnode->is_reroute()) { if (!muted || all_links_muted(*link->fromsock)) { Stack links; - links.push_multiple(link->fromnode->input_sockets().first()->directly_linked_links()); + links.push_multiple(link->fromnode->input_socket(0).directly_linked_links()); while (!links.is_empty()) { bNodeLink *link = links.pop(); nodeLinkSetMute(&ntree, link, muted); @@ -1456,7 +1466,7 @@ static int mute_links_exec(bContext *C, wmOperator *op) continue; } if (!muted || all_links_muted(*link->fromsock)) { - links.push_multiple(link->fromnode->input_sockets().first()->directly_linked_links()); + links.push_multiple(link->fromnode->input_socket(0).directly_linked_links()); } } } @@ -1870,6 +1880,7 @@ void node_insert_on_link_flags_set(SpaceNode &snode, const ARegion ®ion) { bNodeTree &node_tree = *snode.edittree; node_tree.ensure_topology_cache(); + const Span socket_locations = snode.runtime->all_socket_locations; node_insert_on_link_flags_clear(node_tree); @@ -1882,12 +1893,12 @@ void node_insert_on_link_flags_set(SpaceNode &snode, const ARegion ®ion) bNodeLink *selink = nullptr; float dist_best = FLT_MAX; LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) { - if (node_link_is_hidden_or_dimmed(region.v2d, *link)) { + if (node_link_is_hidden_or_dimmed(socket_locations, region.v2d, *link)) { continue; } std::array coords; - node_link_bezier_points_evaluated(*link, coords); + node_link_bezier_points_evaluated(socket_locations, *link, coords); float dist = FLT_MAX; /* Loop over link coords to find shortest dist to upper left node edge of a intersected line From 2752a88478a8dedf2ca7a80d7021ec3347517ab5 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 6 Jan 2023 09:29:39 -0500 Subject: [PATCH 0470/1522] Object: Support converting curves object to mesh Previously you had to use a workaround with the Object info node to get evaluated data from the new curves object to an original editable mesh. This commit makes it so that a curves object can be converted directly to a mesh object if it has evaluated curves or an evaluated mesh. Differential Revision: https://developer.blender.org/D16930 --- .../blender/blenkernel/BKE_curve_to_mesh.hh | 2 +- source/blender/editors/object/object_add.cc | 51 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_curve_to_mesh.hh b/source/blender/blenkernel/BKE_curve_to_mesh.hh index 0f67da2d8a5..fb96fe4792b 100644 --- a/source/blender/blenkernel/BKE_curve_to_mesh.hh +++ b/source/blender/blenkernel/BKE_curve_to_mesh.hh @@ -2,7 +2,6 @@ #pragma once -struct CurvesGeometry; struct Mesh; /** \file @@ -11,6 +10,7 @@ struct Mesh; namespace blender::bke { +struct CurvesGeometry; class AnonymousAttributePropagationInfo; /** diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc index 72d9195cbb3..a6081d3733e 100644 --- a/source/blender/editors/object/object_add.cc +++ b/source/blender/editors/object/object_add.cc @@ -49,6 +49,7 @@ #include "BKE_constraint.h" #include "BKE_context.h" #include "BKE_curve.h" +#include "BKE_curve_to_mesh.hh" #include "BKE_curves.h" #include "BKE_displist.h" #include "BKE_duplilist.h" @@ -2877,6 +2878,7 @@ static Base *duplibase_for_convert( static int object_convert_exec(bContext *C, wmOperator *op) { + using namespace blender; Main *bmain = CTX_data_main(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene = CTX_data_scene(C); @@ -3359,6 +3361,55 @@ static int object_convert_exec(bContext *C, wmOperator *op) ED_rigidbody_object_remove(bmain, scene, newob); } } + else if (ob->type == OB_CURVES && target == OB_MESH) { + ob->flag |= OB_DONE; + + Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); + GeometrySet geometry; + if (ob_eval->runtime.geometry_set_eval != nullptr) { + geometry = *ob_eval->runtime.geometry_set_eval; + } + + if (keep_original) { + basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, nullptr); + newob = basen->object; + + Curves *curves = static_cast(newob->data); + id_us_min(&curves->id); + + newob->data = BKE_id_copy(bmain, &curves->id); + } + else { + newob = ob; + } + + Mesh *new_mesh = static_cast(BKE_id_new(bmain, ID_ME, newob->id.name + 2)); + if (const Mesh *mesh_eval = geometry.get_mesh_for_read()) { + BKE_mesh_nomain_to_mesh(BKE_mesh_copy_for_eval(mesh_eval, false), new_mesh, newob); + BKE_object_material_from_eval_data(bmain, newob, &mesh_eval->id); + new_mesh->attributes_for_write().remove_anonymous(); + } + else if (const Curves *curves_eval = geometry.get_curves_for_read()) { + bke::AnonymousAttributePropagationInfo propagation_info; + propagation_info.propagate_all = false; + Mesh *mesh = bke::curve_to_wire_mesh(bke::CurvesGeometry::wrap(curves_eval->geometry), + propagation_info); + BKE_mesh_nomain_to_mesh(mesh, new_mesh, newob); + BKE_object_material_from_eval_data(bmain, newob, &curves_eval->id); + } + else { + BKE_reportf(op->reports, + RPT_WARNING, + "Object '%s' has no evaluated mesh or curves data", + ob->id.name + 2); + } + + newob->data = new_mesh; + newob->type = OB_MESH; + + BKE_object_free_derived_caches(newob); + BKE_object_free_modifiers(newob, 0); + } else { continue; } From 3b37538975f3298c9ce5369d114f27fd5f84781a Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Fri, 6 Jan 2023 09:34:03 -0500 Subject: [PATCH 0471/1522] Fix T103663: Set material node can fail for single material Caused by f1c0249f34c4171ec311, which filled the wrong value. I have noticed several problems: - Using a full array as single result. - Checking single material index for 0. If we have a list of all slots, then we must check this in the list. - The result was filled false. Simple fix. - Fixed problem with incorrect recording by mask indices, not polygons. - Added domain specifics to names to avoid confusion. Differential Revision: https://developer.blender.org/D16926 --- .../nodes/node_geo_material_selection.cc | 50 +++++++++---------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc index dfb4181926e..bd1408c0f31 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_material_selection.cc @@ -20,35 +20,40 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output(N_("Selection")).field_source(); } -static void select_mesh_by_material(const Mesh &mesh, - const Material *material, - const IndexMask mask, - MutableSpan r_selection) +static VArray select_mesh_faces_by_material(const Mesh &mesh, + const Material *material, + const IndexMask face_mask) { - BLI_assert(mesh.totpoly >= r_selection.size()); Vector slots; - for (const int i : IndexRange(mesh.totcol)) { - if (mesh.mat[i] == material) { - slots.append(i); + for (const int slot_i : IndexRange(mesh.totcol)) { + if (mesh.mat[slot_i] == material) { + slots.append(slot_i); } } + if (slots.is_empty()) { + return VArray::ForSingle(false, mesh.totpoly); + } + const AttributeAccessor attributes = mesh.attributes(); const VArray material_indices = attributes.lookup_or_default( "material_index", ATTR_DOMAIN_FACE, 0); - if (material != nullptr && material_indices.is_single() && - material_indices.get_internal_single() == 0) { - r_selection.fill_indices(mask, false); - return; + if (material_indices.is_single()) { + const int slot_i = material_indices.get_internal_single(); + return VArray::ForSingle(slots.contains(slot_i), mesh.totpoly); } const VArraySpan material_indices_span(material_indices); - threading::parallel_for(mask.index_range(), 1024, [&](IndexRange range) { + Array face_selection(face_mask.min_array_size()); + threading::parallel_for(face_mask.index_range(), 1024, [&](IndexRange range) { for (const int i : range) { - const int face_index = mask[i]; - r_selection[i] = slots.contains(material_indices_span[face_index]); + const int face_index = face_mask[i]; + const int slot_i = material_indices_span[face_index]; + face_selection[face_index] = slots.contains(slot_i); } }); + + return VArray::ForContainer(std::move(face_selection)); } class MaterialSelectionFieldInput final : public bke::GeometryFieldInput { @@ -72,19 +77,12 @@ class MaterialSelectionFieldInput final : public bke::GeometryFieldInput { if (mesh == nullptr) { return {}; } + const eAttrDomain domain = context.domain(); - if (domain == ATTR_DOMAIN_FACE) { - Array selection(mask.min_array_size()); - select_mesh_by_material(*mesh, material_, mask, selection); - return VArray::ForContainer(std::move(selection)); - } + const IndexMask domain_mask = (domain == ATTR_DOMAIN_FACE) ? mask : IndexMask(mesh->totpoly); - Array selection(mesh->totpoly); - select_mesh_by_material(*mesh, material_, IndexMask(mesh->totpoly), selection); - return mesh->attributes().adapt_domain( - VArray::ForContainer(std::move(selection)), ATTR_DOMAIN_FACE, domain); - - return nullptr; + VArray selection = select_mesh_faces_by_material(*mesh, material_, domain_mask); + return mesh->attributes().adapt_domain(std::move(selection), ATTR_DOMAIN_FACE, domain); } uint64_t hash() const override From 5cc793912efe4432b51cc7ddda4005c56fcbc93b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 6 Jan 2023 16:04:03 +0100 Subject: [PATCH 0472/1522] Fix T103671: memory leak in material preview render Introduced with the fix for T103101. --- source/blender/render/intern/engine.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/render/intern/engine.cc b/source/blender/render/intern/engine.cc index 77b1e240cda..b26c685b691 100644 --- a/source/blender/render/intern/engine.cc +++ b/source/blender/render/intern/engine.cc @@ -1049,7 +1049,7 @@ bool RE_engine_render(Render *re, bool do_all) * inversion as this calls python to get the render passes, while python UI * code can also hold a lock on the render result. */ const bool create_new_result = (re->result == nullptr || !(re->r.scemode & R_BUTS_PREVIEW)); - RenderResult *new_result = engine_render_create_result(re); + RenderResult *new_result = (create_new_result) ? engine_render_create_result(re) : nullptr; BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if (create_new_result) { From a3ac91da27dd80a98a1c4674c52170e84bff83a3 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Wed, 28 Dec 2022 23:39:36 +0200 Subject: [PATCH 0473/1522] Cloth: share self and object collision BVH trees when possible. Both cloth object collision and self collision use a BVH tree representing the current cloth shape. The only difference between them is the epsilon threshold value. If these values are the same, it is possible to use the same tree for both uses, thus easily reducing the overhead in the case when both collision modes are used by the same cloth object. Differential Revision: https://developer.blender.org/D16914 --- source/blender/blenkernel/BKE_cloth.h | 2 +- source/blender/blenkernel/intern/cloth.cc | 13 ++++++++++--- source/blender/blenkernel/intern/collision.c | 6 +++++- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 8185e1883a9..d26a96bea21 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -72,7 +72,7 @@ typedef struct Cloth { unsigned char pad2; short pad3; struct BVHTree *bvhtree; /* collision tree for this cloth object */ - struct BVHTree *bvhselftree; /* collision tree for this cloth object */ + struct BVHTree *bvhselftree; /* collision tree for this cloth object (may be same as bvhtree) */ struct MVertTri *tri; struct Implicit_Data *implicit; /* our implicit solver connects to this pointer */ struct EdgeSet *edgeset; /* used for selfcollisions */ diff --git a/source/blender/blenkernel/intern/cloth.cc b/source/blender/blenkernel/intern/cloth.cc index 4f28bf5157c..fe9117b4713 100644 --- a/source/blender/blenkernel/intern/cloth.cc +++ b/source/blender/blenkernel/intern/cloth.cc @@ -461,7 +461,7 @@ void cloth_free_modifier(ClothModifierData *clmd) BLI_bvhtree_free(cloth->bvhtree); } - if (cloth->bvhselftree) { + if (cloth->bvhselftree && cloth->bvhselftree != cloth->bvhtree) { BLI_bvhtree_free(cloth->bvhselftree); } @@ -538,7 +538,7 @@ void cloth_free_modifier_extern(ClothModifierData *clmd) BLI_bvhtree_free(cloth->bvhtree); } - if (cloth->bvhselftree) { + if (cloth->bvhselftree && cloth->bvhselftree != cloth->bvhtree) { BLI_bvhtree_free(cloth->bvhselftree); } @@ -820,7 +820,14 @@ static bool cloth_from_object( } clmd->clothObject->bvhtree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->epsilon); - clmd->clothObject->bvhselftree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->selfepsilon); + + if (compare_ff(clmd->coll_parms->selfepsilon, clmd->coll_parms->epsilon, 1e-6f)) { + /* Share the BVH tree if the epsilon is the same. */ + clmd->clothObject->bvhselftree = clmd->clothObject->bvhtree; + } + else { + clmd->clothObject->bvhselftree = bvhtree_build_from_cloth(clmd, clmd->coll_parms->selfepsilon); + } return true; } diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index bf814b7c595..cf0af615b6f 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -1559,6 +1559,7 @@ int cloth_bvh_collision( BVHTreeOverlap **overlap_obj = NULL; uint coll_count_self = 0; BVHTreeOverlap *overlap_self = NULL; + bool bvh_updated = false; if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || cloth_bvh == NULL) { return 0; @@ -1569,6 +1570,7 @@ int cloth_bvh_collision( if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_ENABLED) { bvhtree_update_from_cloth(clmd, false, false); + bvh_updated = true; /* Enable self collision if this is a hair sim */ const bool is_hair = (clmd->hairdata != NULL); @@ -1605,7 +1607,9 @@ int cloth_bvh_collision( } if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF) { - bvhtree_update_from_cloth(clmd, false, true); + if (cloth->bvhselftree != cloth->bvhtree || !bvh_updated) { + bvhtree_update_from_cloth(clmd, false, true); + } overlap_self = BLI_bvhtree_overlap_self( cloth->bvhselftree, &coll_count_self, cloth_bvh_self_overlap_cb, clmd); From e1df731c91bc7b9b3349a87c4fcf18bc2f29d668 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Fri, 6 Jan 2023 13:48:36 +0200 Subject: [PATCH 0474/1522] Cloth: precompute barycentric coordinates for collision points. Profiling shows that this computation consumes a noticeable amount of time, so it is worth moving it to an earlier part of the code that is executed less frequently and is multithreaded. Differential Revision: https://developer.blender.org/D16933 --- source/blender/blenkernel/BKE_collision.h | 2 + source/blender/blenkernel/intern/collision.c | 93 ++++++++++++-------- 2 files changed, 56 insertions(+), 39 deletions(-) diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h index c390d0a8802..d36758c9c4d 100644 --- a/source/blender/blenkernel/BKE_collision.h +++ b/source/blender/blenkernel/BKE_collision.h @@ -55,6 +55,8 @@ typedef struct CollPair { #else int ap1, ap2, ap3, bp1, bp2, bp3; #endif + /* Barycentric weights of the collision point. */ + float aw1, aw2, aw3, bw1, bw2, bw3; int pointsb[4]; } CollPair; diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index cf0af615b6f..095666e7eac 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -670,7 +670,6 @@ static int cloth_collision_response_static(ClothModifierData *clmd, const bool is_hair = (clmd->hairdata != NULL); for (int i = 0; i < collision_count; i++, collpair++) { float i1[3], i2[3], i3[3]; - float w1, w2, w3, u1, u2, u3; float v1[3], v2[3], relativeVelocity[3]; zero_v3(i1); zero_v3(i2); @@ -682,23 +681,13 @@ static int cloth_collision_response_static(ClothModifierData *clmd, } /* Compute barycentric coordinates and relative "velocity" for both collision points. */ + float w1 = collpair->aw1, w2 = collpair->aw2, w3 = collpair->aw3; + float u1 = collpair->bw1, u2 = collpair->bw2, u3 = collpair->bw3; + if (is_hair) { - w2 = line_point_factor_v3( - collpair->pa, cloth->verts[collpair->ap1].tx, cloth->verts[collpair->ap2].tx); - - w1 = 1.0f - w2; - interp_v3_v3v3(v1, cloth->verts[collpair->ap1].tv, cloth->verts[collpair->ap2].tv, w2); } else { - collision_compute_barycentric(collpair->pa, - cloth->verts[collpair->ap1].tx, - cloth->verts[collpair->ap2].tx, - cloth->verts[collpair->ap3].tx, - &w1, - &w2, - &w3); - collision_interpolateOnTriangle(v1, cloth->verts[collpair->ap1].tv, cloth->verts[collpair->ap2].tv, @@ -708,14 +697,6 @@ static int cloth_collision_response_static(ClothModifierData *clmd, w3); } - collision_compute_barycentric(collpair->pb, - collmd->current_xnew[collpair->bp1].co, - collmd->current_xnew[collpair->bp2].co, - collmd->current_xnew[collpair->bp3].co, - &u1, - &u2, - &u3); - collision_interpolateOnTriangle(v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, @@ -834,7 +815,6 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd, for (int i = 0; i < collision_count; i++, collpair++) { float ia[3][3] = {{0.0f}}; float ib[3][3] = {{0.0f}}; - float w1, w2, w3, u1, u2, u3; float v1[3], v2[3], relativeVelocity[3]; /* Only handle static collisions here. */ @@ -842,22 +822,9 @@ static int cloth_selfcollision_response_static(ClothModifierData *clmd, continue; } - /* Compute barycentric coordinates for both collision points. */ - collision_compute_barycentric(collpair->pa, - cloth->verts[collpair->ap1].tx, - cloth->verts[collpair->ap2].tx, - cloth->verts[collpair->ap3].tx, - &w1, - &w2, - &w3); - - collision_compute_barycentric(collpair->pb, - cloth->verts[collpair->bp1].tx, - cloth->verts[collpair->bp2].tx, - cloth->verts[collpair->bp3].tx, - &u1, - &u2, - &u3); + /* Retrieve barycentric coordinates for both collision points. */ + float w1 = collpair->aw1, w2 = collpair->aw2, w3 = collpair->aw3; + float u1 = collpair->bw1, u2 = collpair->bw2, u3 = collpair->bw3; /* Calculate relative "velocity". */ collision_interpolateOnTriangle(v1, @@ -1053,6 +1020,23 @@ static void cloth_collision(void *__restrict userdata, collpair[index].flag = 0; data->collided = true; + + /* Compute barycentric coordinates for both collision points. */ + collision_compute_barycentric(pa, + verts1[tri_a->tri[0]].tx, + verts1[tri_a->tri[1]].tx, + verts1[tri_a->tri[2]].tx, + &collpair[index].aw1, + &collpair[index].aw2, + &collpair[index].aw3); + + collision_compute_barycentric(pb, + collmd->current_xnew[tri_b->tri[0]].co, + collmd->current_xnew[tri_b->tri[1]].co, + collmd->current_xnew[tri_b->tri[2]].co, + &collpair[index].bw1, + &collpair[index].bw2, + &collpair[index].bw3); } else { collpair[index].flag = COLLISION_INACTIVE; @@ -1159,6 +1143,23 @@ static void cloth_selfcollision(void *__restrict userdata, collpair[index].flag = 0; data->collided = true; + + /* Compute barycentric coordinates for both collision points. */ + collision_compute_barycentric(pa, + verts1[tri_a->tri[0]].tx, + verts1[tri_a->tri[1]].tx, + verts1[tri_a->tri[2]].tx, + &collpair[index].aw1, + &collpair[index].aw2, + &collpair[index].aw3); + + collision_compute_barycentric(pb, + verts1[tri_b->tri[0]].tx, + verts1[tri_b->tri[1]].tx, + verts1[tri_b->tri[2]].tx, + &collpair[index].bw1, + &collpair[index].bw2, + &collpair[index].bw3); } else { collpair[index].flag = COLLISION_INACTIVE; @@ -1217,6 +1218,20 @@ static void hair_collision(void *__restrict userdata, collpair[index].flag = 0; data->collided = true; + + /* Compute barycentric coordinates for the collision points. */ + collpair[index].aw2 = line_point_factor_v3( + pa, verts1[edge_coll->v1].tx, verts1[edge_coll->v2].tx); + + collpair[index].aw1 = 1.0f - collpair[index].aw2; + + collision_compute_barycentric(pb, + collmd->current_xnew[tri_coll->tri[0]].co, + collmd->current_xnew[tri_coll->tri[1]].co, + collmd->current_xnew[tri_coll->tri[2]].co, + &collpair[index].bw1, + &collpair[index].bw2, + &collpair[index].bw3); } else { collpair[index].flag = COLLISION_INACTIVE; From 8a16523bf1fba4371b9b79f51ad61903a71836f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Fri, 6 Jan 2023 17:02:28 +0100 Subject: [PATCH 0475/1522] BLI: Refactor matrix types & functions to use templates This patch implements the matrix types (i.e:float4x4) by making heavy usage of templating. All matrix functions are now outside of the vector classes (inside the blender::math namespace) and are not vector size dependent for the most part. ###Motivations The goal/motivations of this rewrite are the same as the Vector C++ API (D13791): - Template everything for making it work with any types and avoid code duplication. - Use functional style instead of Object Oriented function call to allow a simple compatibility layer with GLSL syntax (see T103026 for more details). - Allow most convenient constructor syntax and accessors (array subscript `matrix[c][r]`, or component alias `matrix.y.z`). - Make it cover all features the current C API supports for adoption. - Keep compilation time and debug performance somehow acceptable. ###Consideration: - The new `MatView` class can be generated by `my_float.view()` (with the last 2 being optionnal). This one allows modifying parts of the source matrix in place. It isn't pretty and duplicates a lot of code, but it is needed mainly to replace `normalize_m4`. At least I think it is a good starting point that can refined further. - An exhaustive list of missing `BLI_math_matrix.h` functions from the new API can be found here P3373. - This adds new Rotation types in order to have a clean API. This will be extended when we port the full Rotation API. The types are made so that they don't allow implicit down-casting to their vector representation. - Some functions make direct use of the Eigen library, bypassing the Eigen C API defined in `intern/eigen`. Its use is contained inside `math_matrix.cc`. There is conflicting opinion wether we should use it more so I contained its usage to almost the tasks as in the C API for now. Reviewed By: sergey, JacquesLucke, HooglyBoogly, Severin, brecht Differential Revision: https://developer.blender.org/D16625 --- source/blender/blenlib/BLI_math_base.hh | 5 + source/blender/blenlib/BLI_math_matrix.hh | 1166 +++++++++++++++++ .../blender/blenlib/BLI_math_matrix_types.hh | 948 ++++++++++++++ source/blender/blenlib/BLI_math_rotation.hh | 242 ++++ .../blenlib/BLI_math_rotation_types.hh | 244 ++++ source/blender/blenlib/BLI_math_vec_types.hh | 9 + source/blender/blenlib/BLI_math_vector.hh | 31 +- source/blender/blenlib/CMakeLists.txt | 3 + source/blender/blenlib/intern/math_matrix.cc | 457 +++++++ .../blender/blenlib/intern/math_rotation.cc | 20 + .../blenlib/tests/BLI_math_matrix_test.cc | 373 +++++- .../tests/BLI_math_matrix_types_test.cc | 403 ++++++ .../blenlib/tests/BLI_math_rotation_test.cc | 52 + tests/gtests/testing/testing.h | 6 + 14 files changed, 3943 insertions(+), 16 deletions(-) create mode 100644 source/blender/blenlib/BLI_math_matrix.hh create mode 100644 source/blender/blenlib/BLI_math_matrix_types.hh create mode 100644 source/blender/blenlib/BLI_math_rotation.hh create mode 100644 source/blender/blenlib/BLI_math_rotation_types.hh create mode 100644 source/blender/blenlib/intern/math_matrix.cc create mode 100644 source/blender/blenlib/tests/BLI_math_matrix_types_test.cc diff --git a/source/blender/blenlib/BLI_math_base.hh b/source/blender/blenlib/BLI_math_base.hh index 6ea68ae8a68..d5279dfb3c5 100644 --- a/source/blender/blenlib/BLI_math_base.hh +++ b/source/blender/blenlib/BLI_math_base.hh @@ -142,6 +142,11 @@ template inline T atan2(const T &y, const T &x) return std::atan2(y, x); } +template inline T hypot(const T &y, const T &x) +{ + return std::hypot(y, x); +} + template)), diff --git a/source/blender/blenlib/BLI_math_matrix.hh b/source/blender/blenlib/BLI_math_matrix.hh new file mode 100644 index 00000000000..a2d5abdc58b --- /dev/null +++ b/source/blender/blenlib/BLI_math_matrix.hh @@ -0,0 +1,1166 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. */ + +#pragma once + +/** \file + * \ingroup bli + */ + +#include "BLI_math_base.hh" +#include "BLI_math_matrix_types.hh" +#include "BLI_math_rotation_types.hh" +#include "BLI_math_vector.hh" + +namespace blender::math { + +/* -------------------------------------------------------------------- */ +/** \name Matrix Operations + * \{ */ + +/** + * Returns the inverse of a square matrix or zero matrix on failure. + * \a r_success is optional and set to true if the matrix was inverted successfully. + */ +template +[[nodiscard]] MatBase invert(const MatBase &mat, bool &r_success); + +/** + * Flip the matrix across its diagonal. Also flips dimensions for non square matrices. + */ +template +[[nodiscard]] MatBase transpose(const MatBase &mat); + +/** + * Normalize each column of the matrix individually. + */ +template +[[nodiscard]] MatBase normalize(const MatBase &a); + +/** + * Normalize each column of the matrix individually. + * Return the length of each column vector. + */ +template +[[nodiscard]] MatBase normalize_and_get_size( + const MatBase &a, VectorT &r_size); + +/** + * Returns the determinant of the matrix. + * It can be interpreted as the signed volume (or area) of the unit cube after transformation. + */ +template [[nodiscard]] T determinant(const MatBase &mat); + +/** + * Returns the adjoint of the matrix (also known as adjugate matrix). + */ +template MatBase adjoint(const MatBase &mat); + +/** + * Equivalent to `mat * from_location(translation)` but with fewer operation. + */ +template +[[nodiscard]] MatBase translate(const MatBase &mat, + const VectorT &translation); + +/** + * Equivalent to `mat * from_rotation(rotation)` but with fewer operation. + * Optimized for AxisAngle rotation on basis vector (i.e: AxisAngle({1, 0, 0}, 0.2)). + */ +template +[[nodiscard]] MatBase rotate(const MatBase &mat, + const RotationT &rotation); + +/** + * Equivalent to `mat * from_scale(scale)` but with fewer operation. + */ +template +[[nodiscard]] MatBase scale(const MatBase &mat, + const VectorT &scale); + +/** + * Interpolate each component linearly. + */ +template +[[nodiscard]] MatBase interpolate_linear(const MatBase &a, + const MatBase &b, + T t); + +/** + * A polar-decomposition-based interpolation between matrix A and matrix B. + * + * \note This code is about five times slower than the 'naive' interpolation + * (it typically remains below 2 usec on an average i74700, + * while naive implementation remains below 0.4 usec). + * However, it gives expected results even with non-uniformly scaled matrices, + * see T46418 for an example. + * + * Based on "Matrix Animation and Polar Decomposition", by Ken Shoemake & Tom Duff + * + * \param A: Input matrix which is totally effective with `t = 0.0`. + * \param B: Input matrix which is totally effective with `t = 1.0`. + * \param t: Interpolation factor. + */ +template +[[nodiscard]] MatBase interpolate(const MatBase &a, + const MatBase &b, + T t); + +/** + * Complete transform matrix interpolation, + * based on polar-decomposition-based interpolation from #interpolate. + * + * \param A: Input matrix which is totally effective with `t = 0.0`. + * \param B: Input matrix which is totally effective with `t = 1.0`. + * \param t: Interpolation factor. + */ +template +[[nodiscard]] MatBase interpolate(const MatBase &a, + const MatBase &b, + T t); + +/** + * Naive interpolation implementation, faster than polar decomposition + * + * \note This code is about five times faster than the polar decomposition. + * However, it gives un-expected results even with non-uniformly scaled matrices, + * see T46418 for an example. + * + * \param A: Input matrix which is totally effective with `t = 0.0`. + * \param B: Input matrix which is totally effective with `t = 1.0`. + * \param t: Interpolation factor. + */ +template +[[nodiscard]] MatBase interpolate_fast(const MatBase &a, + const MatBase &b, + T t); + +/** + * Naive transform matrix interpolation, + * based on naive-decomposition-based interpolation from #interpolate_fast. + * + * \note This code is about five times faster than the polar decomposition. + * However, it gives un-expected results even with non-uniformly scaled matrices, + * see T46418 for an example. + * + * \param A: Input matrix which is totally effective with `t = 0.0`. + * \param B: Input matrix which is totally effective with `t = 1.0`. + * \param t: Interpolation factor. + */ +template +[[nodiscard]] MatBase interpolate_fast(const MatBase &a, + const MatBase &b, + T t); + +/** + * Compute Moore-Penrose pseudo inverse of matrix. + * Singular values below epsilon are ignored for stability (truncated SVD). + * Gives a good enough approximation of the regular inverse matrix if the given matrix is + * non-invertible (ex: degenerate transform). + * The returned pseudo inverse matrix `A+` of input matrix `A` + * will *not* satisfy `A+ * A = Identity` + * but will satisfy `A * A+ * A = A`. + * For more detail, see https://en.wikipedia.org/wiki/Moore%E2%80%93Penrose_inverse. + */ +template +[[nodiscard]] MatBase pseudo_invert(const MatBase &mat, + T epsilon = 1e-8); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Init helpers. + * \{ */ + +/** + * Create a translation only matrix. Matrix dimensions should be at least 4 col x 3 row. + */ +template [[nodiscard]] MatT from_location(const typename MatT::vec3_type &location); + +/** + * Create a matrix whose diagonal is defined by the given scale vector. + * If vector dimension is lower than matrix diagonal, the missing terms are filled with ones. + */ +template +[[nodiscard]] MatT from_scale(const vec_base &scale); + +/** + * Create a rotation only matrix. + */ +template +[[nodiscard]] MatT from_rotation(const RotationT &rotation); + +/** + * Create a transform matrix with rotation and scale applied in this order. + */ +template +[[nodiscard]] MatT from_rot_scale(const RotationT &rotation, const VectorT &scale); + +/** + * Create a transform matrix with translation and rotation applied in this order. + */ +template +[[nodiscard]] MatT from_loc_rot(const typename MatT::vec3_type &location, + const RotationT &rotation); + +/** + * Create a transform matrix with translation, rotation and scale applied in this order. + */ +template +[[nodiscard]] MatT from_loc_rot_scale(const typename MatT::vec3_type &location, + const RotationT &rotation, + const vec_base &scale); + +/** + * Create a rotation matrix from 2 basis vectors. + * The matrix determinant is given to be positive and it can be converted to other rotation types. + * \note `forward` and `up` must be normalized. + */ +template +[[nodiscard]] MatT from_orthonormal_axes(const VectorT forward, const VectorT up); + +/** + * Create a transform matrix with translation and rotation from 2 basis vectors and a translation. + * \note `forward` and `up` must be normalized. + */ +template +[[nodiscard]] MatT from_orthonormal_axes(const VectorT location, + const VectorT forward, + const VectorT up); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Conversion function. + * \{ */ + +/** + * Extract euler rotation from transform matrix. + * \return the rotation with the smallest values from the potential candidates. + */ +template +[[nodiscard]] inline detail::EulerXYZ to_euler(const MatBase &mat); +template +[[nodiscard]] inline detail::EulerXYZ to_euler(const MatBase &mat); + +/** + * Extract quaternion rotation from transform matrix. + */ +template +[[nodiscard]] inline detail::Quaternion to_quaternion(const MatBase &mat); +template +[[nodiscard]] inline detail::Quaternion to_quaternion(const MatBase &mat); + +/** + * Extract the absolute 3d scale from a transform matrix. + * \tparam AllowNegativeScale if true, will compute determinant to know if matrix is negative. + * This is a costly operation so it is disabled by default. + */ +template +[[nodiscard]] inline vec_base to_scale(const MatBase &mat); + +/** + * Decompose a matrix into location, rotation, and scale components. + * \tparam AllowNegativeScale if true, will compute determinant to know if matrix is negative. + * Rotation and scale values will be flipped if it is negative. + * This is a costly operation so it is disabled by default. + */ +template +inline void to_rot_scale(const MatBase &mat, + RotationT &r_rotation, + vec_base &r_scale); +template +inline void to_loc_rot_scale(const MatBase &mat, + vec_base &r_location, + RotationT &r_rotation, + vec_base &r_scale); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Transform functions. + * \{ */ + +/** + * Transform a 3d point using a 3x3 matrix (rotation & scale). + */ +template +[[nodiscard]] vec_base transform_point(const MatBase &mat, + const vec_base &point); + +/** + * Transform a 3d point using a 4x4 matrix (location & rotation & scale). + */ +template +[[nodiscard]] vec_base transform_point(const MatBase &mat, + const vec_base &point); + +/** + * Transform a 3d direction vector using a 3x3 matrix (rotation & scale). + */ +template +[[nodiscard]] vec_base transform_direction(const MatBase &mat, + const vec_base &direction); + +/** + * Transform a 3d direction vector using a 4x4 matrix (rotation & scale). + */ +template +[[nodiscard]] vec_base transform_direction(const MatBase &mat, + const vec_base &direction); + +/** + * Project a point using a matrix (location & rotation & scale & perspective divide). + */ +template +[[nodiscard]] VectorT project_point(const MatT &mat, const VectorT &point); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Projection Matrices. + * \{ */ + +namespace projection { + +/** + * \brief Create an orthographic projection matrix using OpenGL coordinate convention: + * Maps each axis range to [-1..1] range for all axes. + * The resulting matrix can be used with either #project_point or #transform_point. + */ +template +[[nodiscard]] MatBase orthographic( + T left, T right, T bottom, T top, T near_clip, T far_clip); + +/** + * \brief Create a perspective projection matrix using OpenGL coordinate convention: + * Maps each axis range to [-1..1] range for all axes. + * `left`, `right`, `bottom`, `top` are frustum side distances at `z=near_clip`. + * The resulting matrix can be used with #project_point. + */ +template +[[nodiscard]] MatBase perspective( + T left, T right, T bottom, T top, T near_clip, T far_clip); + +/** + * \brief Create a perspective projection matrix using OpenGL coordinate convention: + * Maps each axis range to [-1..1] range for all axes. + * Uses field of view angles instead of plane distances. + * The resulting matrix can be used with #project_point. + */ +template +[[nodiscard]] MatBase perspective_fov( + T angle_left, T angle_right, T angle_bottom, T angle_top, T near_clip, T far_clip); + +} // namespace projection + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Compare / Test + * \{ */ + +/** + * Returns true if matrix has inverted handedness. + * + * \note It doesn't use determinant(mat4x4) as only the 3x3 components are needed + * when the matrix is used as a transformation to represent location/scale/rotation. + */ +template [[nodiscard]] bool is_negative(const MatBase &mat) +{ + return determinant(mat) < T(0); +} +template [[nodiscard]] bool is_negative(const MatBase &mat); + +/** + * Returns true if matrices are equal within the given epsilon. + */ +template +[[nodiscard]] inline bool is_equal(const MatBase &a, + const MatBase &b, + const T epsilon) +{ + for (int i = 0; i < NumCol; i++) { + for (int j = 0; j < NumRow; j++) { + if (math::abs(a[i][j] - b[i][j]) > epsilon) { + return false; + } + } + } + return true; +} + +/** + * Test if the X, Y and Z axes are perpendicular with each other. + */ +template [[nodiscard]] inline bool is_orthogonal(const MatT &mat) +{ + if (math::abs(math::dot(mat.x_axis(), mat.y_axis())) > 1e-5f) { + return false; + } + if (math::abs(math::dot(mat.y_axis(), mat.z_axis())) > 1e-5f) { + return false; + } + if (math::abs(math::dot(mat.z_axis(), mat.x_axis())) > 1e-5f) { + return false; + } + return true; +} + +/** + * Test if the X, Y and Z axes are perpendicular with each other and unit length. + */ +template [[nodiscard]] inline bool is_orthonormal(const MatT &mat) +{ + if (!is_orthogonal(mat)) { + return false; + } + if (math::abs(math::length_squared(mat.x_axis()) - 1) > 1e-5f) { + return false; + } + if (math::abs(math::length_squared(mat.y_axis()) - 1) > 1e-5f) { + return false; + } + if (math::abs(math::length_squared(mat.z_axis()) - 1) > 1e-5f) { + return false; + } + return true; +} + +/** + * Test if the X, Y and Z axes are perpendicular with each other and the same length. + */ +template [[nodiscard]] inline bool is_uniformly_scaled(const MatT &mat) +{ + if (!is_orthogonal(mat)) { + return false; + } + using T = typename MatT::base_type; + const T eps = 1e-7; + const T x = math::length_squared(mat.x_axis()); + const T y = math::length_squared(mat.y_axis()); + const T z = math::length_squared(mat.z_axis()); + return (math::abs(x - y) < eps) && math::abs(x - z) < eps; +} + +template +inline bool is_zero(const MatBase &mat) +{ + for (int i = 0; i < NumCol; i++) { + if (!is_zero(mat[i])) { + return false; + } + } + return true; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Implementation. + * \{ */ + +/* Implementation details. */ +namespace detail { + +template +[[nodiscard]] MatBase from_rotation(const EulerXYZ &rotation); + +template +[[nodiscard]] MatBase from_rotation(const Quaternion &rotation); + +template +[[nodiscard]] MatBase from_rotation(const AxisAngle &rotation); + +} // namespace detail + +/* Returns true if each individual columns are unit scaled. Mainly for assert usage. */ +template +[[nodiscard]] inline bool is_unit_scale(const MatBase &m) +{ + for (int i = 0; i < NumCol; i++) { + if (!is_unit_scale(m[i])) { + return false; + } + } + return true; +} + +template +[[nodiscard]] MatBase invert(const MatBase &mat) +{ + bool success; + return invert(mat, success); +} + +template +[[nodiscard]] MatBase transpose(const MatBase &mat) +{ + MatBase result; + unroll([&](auto i) { unroll([&](auto j) { result[i][j] = mat[j][i]; }); }); + return result; +} + +template +[[nodiscard]] MatBase translate(const MatBase &mat, + const VectorT &translation) +{ + using MatT = MatBase; + BLI_STATIC_ASSERT(VectorT::type_length <= MatT::col_len - 1, + "Translation should be at least 1 column less than the matrix."); + static constexpr int location_col = MatT::col_len - 1; + /* Avoid multiplying the last row if it exists. + * Allows using non square matrices like float3x2 and saves computation. */ + using IntermediateVecT = + vec_base MatT::col_len - 1) ? (MatT::col_len - 1) : MatT::row_len>; + + MatT result = mat; + unroll([&](auto c) { + *reinterpret_cast( + &result[location_col]) += translation[c] * + *reinterpret_cast(&mat[c]); + }); + return result; +} + +template +[[nodiscard]] MatBase rotate(const MatBase &mat, + const detail::AxisAngle &rotation) +{ + using MatT = MatBase; + using Vec3T = typename MatT::vec3_type; + const T &angle_sin = rotation.angle_sin(); + const T &angle_cos = rotation.angle_cos(); + const Vec3T &axis_vec = rotation.axis(); + + MatT result = mat; + /* axis_vec is given to be normalized. */ + if (axis_vec.x == T(1)) { + unroll([&](auto c) { + result[2][c] = -angle_sin * mat[1][c] + angle_cos * mat[2][c]; + result[1][c] = angle_cos * mat[1][c] + angle_sin * mat[2][c]; + }); + } + else if (axis_vec.y == T(1)) { + unroll([&](auto c) { + result[0][c] = angle_cos * mat[0][c] - angle_sin * mat[2][c]; + result[2][c] = angle_sin * mat[0][c] + angle_cos * mat[2][c]; + }); + } + else if (axis_vec.z == T(1)) { + unroll([&](auto c) { + result[0][c] = angle_cos * mat[0][c] + angle_sin * mat[1][c]; + result[1][c] = -angle_sin * mat[0][c] + angle_cos * mat[1][c]; + }); + } + else { + /* Un-optimized case. Arbitrary */ + result *= from_rotation(rotation); + } + return result; +} + +template +[[nodiscard]] MatBase scale(const MatBase &mat, + const VectorT &scale) +{ + BLI_STATIC_ASSERT(VectorT::type_length <= NumCol, + "Scale should be less or equal to the matrix in column count."); + MatBase result = mat; + unroll([&](auto c) { result[c] *= scale[c]; }); + return result; +} + +template +[[nodiscard]] MatBase interpolate_linear(const MatBase &a, + const MatBase &b, + T t) +{ + MatBase result; + unroll([&](auto c) { result[c] = interpolate(a[c], b[c], t); }); + return result; +} + +template +[[nodiscard]] MatBase normalize( + const MatView + &a) +{ + MatBase result; + unroll([&](auto i) { result[i] = math::normalize(a[i]); }); + return result; +} + +template +[[nodiscard]] MatBase normalize_and_get_size( + const MatView + &a, + VectorT &r_size) +{ + BLI_STATIC_ASSERT(VectorT::type_length == NumCol, + "r_size dimension should be equal to matrix column count."); + MatBase result; + unroll([&](auto i) { result[i] = math::normalize_and_get_length(a[i], r_size[i]); }); + return result; +} + +template +[[nodiscard]] MatBase normalize(const MatBase &a) +{ + MatBase result; + unroll([&](auto i) { result[i] = math::normalize(a[i]); }); + return result; +} + +template +[[nodiscard]] MatBase normalize_and_get_size( + const MatBase &a, VectorT &r_size) +{ + BLI_STATIC_ASSERT(VectorT::type_length == NumCol, + "r_size dimension should be equal to matrix column count."); + MatBase result; + unroll([&](auto i) { result[i] = math::normalize_and_get_length(a[i], r_size[i]); }); + return result; +} + +namespace detail { + +template +void normalized_to_eul2(const MatBase &mat, + detail::EulerXYZ &eul1, + detail::EulerXYZ &eul2) +{ + BLI_assert(math::is_unit_scale(mat)); + + const T cy = math::hypot(mat[0][0], mat[0][1]); + if (cy > T(16) * FLT_EPSILON) { + eul1.x = math::atan2(mat[1][2], mat[2][2]); + eul1.y = math::atan2(-mat[0][2], cy); + eul1.z = math::atan2(mat[0][1], mat[0][0]); + + eul2.x = math::atan2(-mat[1][2], -mat[2][2]); + eul2.y = math::atan2(-mat[0][2], -cy); + eul2.z = math::atan2(-mat[0][1], -mat[0][0]); + } + else { + eul1.x = math::atan2(-mat[2][1], mat[1][1]); + eul1.y = math::atan2(-mat[0][2], cy); + eul1.z = 0.0f; + + eul2 = eul1; + } +} + +/* Using explicit template instantiations in order to reduce compilation time. */ +extern template void normalized_to_eul2(const float3x3 &mat, + detail::EulerXYZ &eul1, + detail::EulerXYZ &eul2); +extern template void normalized_to_eul2(const double3x3 &mat, + detail::EulerXYZ &eul1, + detail::EulerXYZ &eul2); + +template detail::Quaternion normalized_to_quat_fast(const MatBase &mat) +{ + BLI_assert(math::is_unit_scale(mat)); + /* Caller must ensure matrices aren't negative for valid results, see: T24291, T94231. */ + BLI_assert(!math::is_negative(mat)); + + detail::Quaternion q; + + /* Method outlined by Mike Day, ref: https://math.stackexchange.com/a/3183435/220949 + * with an additional `sqrtf(..)` for higher precision result. + * Removing the `sqrt` causes tests to fail unless the precision is set to 1e-6 or larger. */ + + if (mat[2][2] < 0.0f) { + if (mat[0][0] > mat[1][1]) { + const T trace = 1.0f + mat[0][0] - mat[1][1] - mat[2][2]; + T s = 2.0f * math::sqrt(trace); + if (mat[1][2] < mat[2][1]) { + /* Ensure W is non-negative for a canonical result. */ + s = -s; + } + q.y = 0.25f * s; + s = 1.0f / s; + q.x = (mat[1][2] - mat[2][1]) * s; + q.z = (mat[0][1] + mat[1][0]) * s; + q.w = (mat[2][0] + mat[0][2]) * s; + if (UNLIKELY((trace == 1.0f) && (q.x == 0.0f && q.z == 0.0f && q.w == 0.0f))) { + /* Avoids the need to normalize the degenerate case. */ + q.y = 1.0f; + } + } + else { + const T trace = 1.0f - mat[0][0] + mat[1][1] - mat[2][2]; + T s = 2.0f * math::sqrt(trace); + if (mat[2][0] < mat[0][2]) { + /* Ensure W is non-negative for a canonical result. */ + s = -s; + } + q.z = 0.25f * s; + s = 1.0f / s; + q.x = (mat[2][0] - mat[0][2]) * s; + q.y = (mat[0][1] + mat[1][0]) * s; + q.w = (mat[1][2] + mat[2][1]) * s; + if (UNLIKELY((trace == 1.0f) && (q.x == 0.0f && q.y == 0.0f && q.w == 0.0f))) { + /* Avoids the need to normalize the degenerate case. */ + q.z = 1.0f; + } + } + } + else { + if (mat[0][0] < -mat[1][1]) { + const T trace = 1.0f - mat[0][0] - mat[1][1] + mat[2][2]; + T s = 2.0f * math::sqrt(trace); + if (mat[0][1] < mat[1][0]) { + /* Ensure W is non-negative for a canonical result. */ + s = -s; + } + q.w = 0.25f * s; + s = 1.0f / s; + q.x = (mat[0][1] - mat[1][0]) * s; + q.y = (mat[2][0] + mat[0][2]) * s; + q.z = (mat[1][2] + mat[2][1]) * s; + if (UNLIKELY((trace == 1.0f) && (q.x == 0.0f && q.y == 0.0f && q.z == 0.0f))) { + /* Avoids the need to normalize the degenerate case. */ + q.w = 1.0f; + } + } + else { + /* NOTE(@campbellbarton): A zero matrix will fall through to this block, + * needed so a zero scaled matrices to return a quaternion without rotation, see: T101848. + */ + const T trace = 1.0f + mat[0][0] + mat[1][1] + mat[2][2]; + T s = 2.0f * math::sqrt(trace); + q.x = 0.25f * s; + s = 1.0f / s; + q.y = (mat[1][2] - mat[2][1]) * s; + q.z = (mat[2][0] - mat[0][2]) * s; + q.w = (mat[0][1] - mat[1][0]) * s; + if (UNLIKELY((trace == 1.0f) && (q.y == 0.0f && q.z == 0.0f && q.w == 0.0f))) { + /* Avoids the need to normalize the degenerate case. */ + q.x = 1.0f; + } + } + } + + BLI_assert(!(q.x < 0.0f)); + BLI_assert(math::is_unit_scale(vec_base(q))); + return q; +} + +template +detail::Quaternion normalized_to_quat_with_checks(const MatBase &mat) +{ + const T det = math::determinant(mat); + if (UNLIKELY(!isfinite(det))) { + return detail::Quaternion::identity(); + } + else if (UNLIKELY(det < T(0))) { + return normalized_to_quat_fast(-mat); + } + return normalized_to_quat_fast(mat); +} + +/* Using explicit template instantiations in order to reduce compilation time. */ +extern template Quaternion normalized_to_quat_with_checks(const float3x3 &mat); +extern template Quaternion normalized_to_quat_with_checks(const double3x3 &mat); + +template +MatBase from_rotation(const EulerXYZ &rotation) +{ + using MatT = MatBase; + using DoublePrecision = typename TypeTraits::DoublePrecision; + DoublePrecision ci = math::cos(rotation.x); + DoublePrecision cj = math::cos(rotation.y); + DoublePrecision ch = math::cos(rotation.z); + DoublePrecision si = math::sin(rotation.x); + DoublePrecision sj = math::sin(rotation.y); + DoublePrecision sh = math::sin(rotation.z); + DoublePrecision cc = ci * ch; + DoublePrecision cs = ci * sh; + DoublePrecision sc = si * ch; + DoublePrecision ss = si * sh; + + MatT mat; + mat[0][0] = T(cj * ch); + mat[1][0] = T(sj * sc - cs); + mat[2][0] = T(sj * cc + ss); + + mat[0][1] = T(cj * sh); + mat[1][1] = T(sj * ss + cc); + mat[2][1] = T(sj * cs - sc); + + mat[0][2] = T(-sj); + mat[1][2] = T(cj * si); + mat[2][2] = T(cj * ci); + return mat; +} + +template +MatBase from_rotation(const Quaternion &rotation) +{ + using MatT = MatBase; + using DoublePrecision = typename TypeTraits::DoublePrecision; + DoublePrecision q0 = M_SQRT2 * DoublePrecision(rotation.x); + DoublePrecision q1 = M_SQRT2 * DoublePrecision(rotation.y); + DoublePrecision q2 = M_SQRT2 * DoublePrecision(rotation.z); + DoublePrecision q3 = M_SQRT2 * DoublePrecision(rotation.w); + + DoublePrecision qda = q0 * q1; + DoublePrecision qdb = q0 * q2; + DoublePrecision qdc = q0 * q3; + DoublePrecision qaa = q1 * q1; + DoublePrecision qab = q1 * q2; + DoublePrecision qac = q1 * q3; + DoublePrecision qbb = q2 * q2; + DoublePrecision qbc = q2 * q3; + DoublePrecision qcc = q3 * q3; + + MatT mat; + mat[0][0] = T(1.0 - qbb - qcc); + mat[0][1] = T(qdc + qab); + mat[0][2] = T(-qdb + qac); + + mat[1][0] = T(-qdc + qab); + mat[1][1] = T(1.0 - qaa - qcc); + mat[1][2] = T(qda + qbc); + + mat[2][0] = T(qdb + qac); + mat[2][1] = T(-qda + qbc); + mat[2][2] = T(1.0 - qaa - qbb); + return mat; +} + +template +MatBase from_rotation(const AxisAngle &rotation) +{ + using MatT = MatBase; + using Vec3T = typename MatT::vec3_type; + const T angle_sin = rotation.angle_sin(); + const T angle_cos = rotation.angle_cos(); + const Vec3T &axis = rotation.axis(); + + BLI_assert(is_unit_scale(axis)); + + T ico = (T(1) - angle_cos); + Vec3T nsi = axis * angle_sin; + + Vec3T n012 = (axis * axis) * ico; + T n_01 = (axis[0] * axis[1]) * ico; + T n_02 = (axis[0] * axis[2]) * ico; + T n_12 = (axis[1] * axis[2]) * ico; + + MatT mat = from_scale(n012 + angle_cos); + mat[0][1] = n_01 + nsi[2]; + mat[0][2] = n_02 - nsi[1]; + mat[1][0] = n_01 - nsi[2]; + mat[1][2] = n_12 + nsi[0]; + mat[2][0] = n_02 + nsi[1]; + mat[2][1] = n_12 - nsi[0]; + return mat; +} + +/* Using explicit template instantiations in order to reduce compilation time. */ +extern template MatBase from_rotation(const EulerXYZ &rotation); +extern template MatBase from_rotation(const EulerXYZ &rotation); +extern template MatBase from_rotation(const Quaternion &rotation); +extern template MatBase from_rotation(const Quaternion &rotation); +extern template MatBase from_rotation(const AxisAngle &rotation); +extern template MatBase from_rotation(const AxisAngle &rotation); + +} // namespace detail + +template +[[nodiscard]] inline detail::EulerXYZ to_euler(const MatBase &mat) +{ + detail::EulerXYZ eul1, eul2; + if constexpr (Normalized) { + detail::normalized_to_eul2(mat, eul1, eul2); + } + else { + detail::normalized_to_eul2(normalize(mat), eul1, eul2); + } + /* Return best, which is just the one with lowest values it in. */ + return (length_manhattan(vec_base(eul1)) > length_manhattan(vec_base(eul2))) ? eul2 : + eul1; +} + +template +[[nodiscard]] inline detail::EulerXYZ to_euler(const MatBase &mat) +{ + /* TODO(fclem): Avoid the copy with 3x3 ref. */ + return to_euler(MatBase(mat)); +} + +template +[[nodiscard]] inline detail::Quaternion to_quaternion(const MatBase &mat) +{ + using namespace math; + if constexpr (Normalized) { + return detail::normalized_to_quat_with_checks(mat); + } + else { + return detail::normalized_to_quat_with_checks(normalize(mat)); + } +} + +template +[[nodiscard]] inline detail::Quaternion to_quaternion(const MatBase &mat) +{ + /* TODO(fclem): Avoid the copy with 3x3 ref. */ + return to_quaternion(MatBase(mat)); +} + +template +[[nodiscard]] inline vec_base to_scale(const MatBase &mat) +{ + vec_base result = {length(mat.x_axis()), length(mat.y_axis()), length(mat.z_axis())}; + if constexpr (AllowNegativeScale) { + if (UNLIKELY(is_negative(mat))) { + result = -result; + } + } + return result; +} + +/* Implementation details. Use `to_euler` and `to_quaternion` instead. */ +namespace detail { + +template +inline void to_rotation(const MatBase &mat, detail::Quaternion &r_rotation) +{ + r_rotation = to_quaternion(mat); +} + +template +inline void to_rotation(const MatBase &mat, detail::EulerXYZ &r_rotation) +{ + r_rotation = to_euler(mat); +} + +} // namespace detail + +template +inline void to_rot_scale(const MatBase &mat, + RotationT &r_rotation, + vec_base &r_scale) +{ + MatBase normalized_mat = normalize_and_get_size(mat, r_scale); + if constexpr (AllowNegativeScale) { + if (UNLIKELY(is_negative(normalized_mat))) { + normalized_mat = -normalized_mat; + r_scale = -r_scale; + } + } + detail::to_rotation(normalized_mat, r_rotation); +} + +template +inline void to_loc_rot_scale(const MatBase &mat, + vec_base &r_location, + RotationT &r_rotation, + vec_base &r_scale) +{ + r_location = mat.location(); + to_rot_scale(MatBase(mat), r_rotation, r_scale); +} + +template [[nodiscard]] MatT from_location(const typename MatT::vec3_type &location) +{ + MatT mat = MatT::identity(); + mat.location() = location; + return mat; +} + +template +[[nodiscard]] MatT from_scale(const vec_base &scale) +{ + BLI_STATIC_ASSERT(ScaleDim <= MatT::min_dim, + "Scale dimension should fit the matrix diagonal length."); + MatT result{}; + unroll( + [&](auto i) { result[i][i] = (i < ScaleDim) ? scale[i] : typename MatT::base_type(1); }); + return result; +} + +template +[[nodiscard]] MatT from_rotation(const RotationT &rotation) +{ + return detail::from_rotation(rotation); +} + +template +[[nodiscard]] MatT from_rot_scale(const RotationT &rotation, const VectorT &scale) +{ + return from_rotation(rotation) * from_scale(scale); +} + +template +[[nodiscard]] MatT from_loc_rot_scale(const typename MatT::vec3_type &location, + const RotationT &rotation, + const vec_base &scale) +{ + using Mat3x3 = MatBase; + MatT mat = MatT(from_rot_scale(rotation, scale)); + mat.location() = location; + return mat; +} + +template +[[nodiscard]] MatT from_loc_rot(const typename MatT::vec3_type &location, + const RotationT &rotation) +{ + using Mat3x3 = MatBase; + MatT mat = MatT(from_rotation(rotation)); + mat.location() = location; + return mat; +} + +template +[[nodiscard]] MatT from_orthonormal_axes(const VectorT forward, const VectorT up) +{ + BLI_assert(is_unit_scale(forward)); + BLI_assert(is_unit_scale(up)); + + MatT matrix; + matrix.x_axis() = forward; + /* Beware of handedness! Blender uses right-handedness. + * Resulting matrix should have determinant of 1. */ + matrix.y_axis() = math::cross(up, forward); + matrix.z_axis() = up; + return matrix; +} + +template +[[nodiscard]] MatT from_orthonormal_axes(const VectorT location, + const VectorT forward, + const VectorT up) +{ + using Mat3x3 = MatBase; + MatT matrix = MatT(from_orthonormal_axes(forward, up)); + matrix.location() = location; + return matrix; +} + +template +vec_base transform_point(const MatBase &mat, const vec_base &point) +{ + return mat * point; +} + +template +vec_base transform_point(const MatBase &mat, const vec_base &point) +{ + return mat.template view<3, 3>() * point + mat.location(); +} + +template +vec_base transform_direction(const MatBase &mat, const vec_base &direction) +{ + return mat * direction; +} + +template +vec_base transform_direction(const MatBase &mat, const vec_base &direction) +{ + return mat.template view<3, 3>() * direction; +} + +template +vec_base project_point(const MatBase &mat, const vec_base &point) +{ + vec_base tmp(point, T(1)); + tmp = mat * tmp; + /* Absolute value to not flip the frustum upside down behind the camera. */ + return vec_base(tmp) / math::abs(tmp[N]); +} + +extern template float3 transform_point(const float3x3 &mat, const float3 &point); +extern template float3 transform_point(const float4x4 &mat, const float3 &point); +extern template float3 transform_direction(const float3x3 &mat, const float3 &direction); +extern template float3 transform_direction(const float4x4 &mat, const float3 &direction); +extern template float3 project_point(const float4x4 &mat, const float3 &point); +extern template float2 project_point(const float3x3 &mat, const float2 &point); + +namespace projection { + +template +MatBase orthographic(T left, T right, T bottom, T top, T near_clip, T far_clip) +{ + const T x_delta = right - left; + const T y_delta = top - bottom; + const T z_delta = far_clip - near_clip; + + MatBase mat = MatBase::identity(); + if (x_delta != 0 && y_delta != 0 && z_delta != 0) { + mat[0][0] = T(2.0) / x_delta; + mat[3][0] = -(right + left) / x_delta; + mat[1][1] = T(2.0) / y_delta; + mat[3][1] = -(top + bottom) / y_delta; + mat[2][2] = -T(2.0) / z_delta; /* NOTE: negate Z. */ + mat[3][2] = -(far_clip + near_clip) / z_delta; + } + return mat; +} + +template +MatBase perspective(T left, T right, T bottom, T top, T near_clip, T far_clip) +{ + const T x_delta = right - left; + const T y_delta = top - bottom; + const T z_delta = far_clip - near_clip; + + MatBase mat = MatBase::identity(); + if (x_delta != 0 && y_delta != 0 && z_delta != 0) { + mat[0][0] = near_clip * T(2.0) / x_delta; + mat[1][1] = near_clip * T(2.0) / y_delta; + mat[2][0] = (right + left) / x_delta; /* NOTE: negate Z. */ + mat[2][1] = (top + bottom) / y_delta; + mat[2][2] = -(far_clip + near_clip) / z_delta; + mat[2][3] = -1.0f; + mat[3][2] = (-2.0f * near_clip * far_clip) / z_delta; + } + return mat; +} + +template +[[nodiscard]] MatBase perspective_fov( + T angle_left, T angle_right, T angle_bottom, T angle_top, T near_clip, T far_clip) +{ + MatBase mat = perspective(math::tan(angle_left), + math::tan(angle_right), + math::tan(angle_bottom), + math::tan(angle_top), + near_clip, + far_clip); + mat[0][0] /= near_clip; + mat[1][1] /= near_clip; + return mat; +} + +extern template float4x4 orthographic( + float left, float right, float bottom, float top, float near_clip, float far_clip); +extern template float4x4 perspective( + float left, float right, float bottom, float top, float near_clip, float far_clip); + +} // namespace projection + +/** \} */ + +} // namespace blender::math diff --git a/source/blender/blenlib/BLI_math_matrix_types.hh b/source/blender/blenlib/BLI_math_matrix_types.hh new file mode 100644 index 00000000000..6d6e738fc4b --- /dev/null +++ b/source/blender/blenlib/BLI_math_matrix_types.hh @@ -0,0 +1,948 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. */ + +#pragma once + +/** \file + * \ingroup bli + * + * Template for matrix types. + * + * The `blender::MatBase` is a Row x Col matrix (in mathematical notation) laid + * out as column major in memory. + * + * This class overloads `+, -, *` and `+=, -=, *=` mathematical operators. + * They are all using per component operation, except for a few: + * `MatBase * Vector` the vector product with the matrix. + * `Vector * MatBase` the vector product with the **transposed** matrix. + * `MatBase * MatBase` and `MatBase *= MatBase` the matrix multiplication. + * + * The `blender::MatView` allows working on a subset of a matrix without having to move the data + * around. It can be obtained using the `MatBase.view()`. It is const by default if + * the matrix type is. Otherwise, a `blender::MutableMatView` is returned. + * + * A `blender::MutableMatView`. It is mostly the same as `blender::MatView`, but can to be + * modified. + * + * This allow working with any number type `T` (float, double, mpq, ...) and to use these types in + * shared shader files (code compiled in both C++ and Shader language). To this end, only low level + * constructors are defined inside the class itself and every function working on matrices are + * defined outside of the class in the `blender::math` namespace. + */ + +#include +#include +#include +#include + +#include "BLI_math_vec_types.hh" +#include "BLI_utildefines.h" +#include "BLI_utility_mixins.hh" + +namespace blender { + +template +struct MatView; + +template +struct MutableMatView; + +template< + /* Number type. */ + typename T, + /* Number of column in the matrix. */ + int NumCol, + /* Number of row in the matrix. */ + int NumRow, + /* Alignment in bytes. Do not align matrices whose size is not a multiple of 4 component. + * This is in order to avoid padding when using arrays of matrices. */ + int Alignment = (((NumCol * NumRow) % 4) ? 4 : 0) * sizeof(T)> +struct alignas(Alignment) MatBase : public vec_struct_base, NumCol> { + + using base_type = T; + using vec3_type = vec_base; + using col_type = vec_base; + using row_type = vec_base; + static constexpr int min_dim = (NumRow < NumCol) ? NumRow : NumCol; + static constexpr int col_len = NumCol; + static constexpr int row_len = NumRow; + + MatBase() = default; + +/* Workaround issue with template BLI_ENABLE_IF((Size == 2)) not working. */ +#define BLI_ENABLE_IF_MAT(_size, _test) int S = _size, BLI_ENABLE_IF((S _test)) + + template MatBase(col_type _x, col_type _y) + { + (*this)[0] = _x; + (*this)[1] = _y; + } + + template MatBase(col_type _x, col_type _y, col_type _z) + { + (*this)[0] = _x; + (*this)[1] = _y; + (*this)[2] = _z; + } + + template + MatBase(col_type _x, col_type _y, col_type _z, col_type _w) + { + (*this)[0] = _x; + (*this)[1] = _y; + (*this)[2] = _z; + (*this)[3] = _w; + } + + /** Masking. */ + + template + explicit MatBase(const MatBase &other) + { + if constexpr ((OtherNumRow >= NumRow) && (OtherNumCol >= NumCol)) { + unroll([&](auto i) { (*this)[i] = col_type(other[i]); }); + } + else { + /* Allow enlarging following GLSL standard (i.e: mat4x4(mat3x3())). */ + unroll([&](auto i) { + unroll([&](auto j) { + if (i < OtherNumCol && j < OtherNumRow) { + (*this)[i][j] = other[i][j]; + } + else if (i == j) { + (*this)[i][j] = T(1); + } + else { + (*this)[i][j] = T(0); + } + }); + }); + } + } + +#undef BLI_ENABLE_IF_MAT + + /** Conversion from pointers (from C-style vectors). */ + + explicit MatBase(const T *ptr) + { + unroll([&](auto i) { (*this)[i] = reinterpret_cast(ptr)[i]; }); + } + + template))> explicit MatBase(const U *ptr) + { + unroll([&](auto i) { (*this)[i] = ptr[i]; }); + } + + explicit MatBase(const T (*ptr)[NumCol]) : MatBase(static_cast(ptr[0])) + { + } + + /** Conversion from other matrix types. */ + + template explicit MatBase(const MatBase &vec) + { + unroll([&](auto i) { (*this)[i] = col_type(vec[i]); }); + } + + /** C-style pointer dereference. */ + + using c_style_mat = T[NumCol][NumRow]; + + /** \note Prevent implicit cast to types that could fit other pointer constructor. */ + const c_style_mat &ptr() const + { + return *reinterpret_cast(this); + } + + /** \note Prevent implicit cast to types that could fit other pointer constructor. */ + c_style_mat &ptr() + { + return *reinterpret_cast(this); + } + + /** \note Prevent implicit cast to types that could fit other pointer constructor. */ + const T *base_ptr() const + { + return reinterpret_cast(this); + } + + /** \note Prevent implicit cast to types that could fit other pointer constructor. */ + T *base_ptr() + { + return reinterpret_cast(this); + } + + /** View creation. */ + + template + const MatView + view() const + { + return MatView( + const_cast(*this)); + } + + template + MutableMatView + view() + { + return MutableMatView(*this); + } + + /** Array access. */ + + const col_type &operator[](int index) const + { + BLI_assert(index >= 0); + BLI_assert(index < NumCol); + return reinterpret_cast(this)[index]; + } + + col_type &operator[](int index) + { + BLI_assert(index >= 0); + BLI_assert(index < NumCol); + return reinterpret_cast(this)[index]; + } + + /** Access helpers. Using Blender coordinate system. */ + + vec3_type &x_axis() + { + BLI_STATIC_ASSERT(NumCol >= 1, "Wrong Matrix dimension"); + BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension"); + return *reinterpret_cast(&(*this)[0]); + } + + vec3_type &y_axis() + { + BLI_STATIC_ASSERT(NumCol >= 2, "Wrong Matrix dimension"); + BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension"); + return *reinterpret_cast(&(*this)[1]); + } + + vec3_type &z_axis() + { + BLI_STATIC_ASSERT(NumCol >= 3, "Wrong Matrix dimension"); + BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension"); + return *reinterpret_cast(&(*this)[2]); + } + + vec3_type &location() + { + BLI_STATIC_ASSERT(NumCol >= 4, "Wrong Matrix dimension"); + BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension"); + return *reinterpret_cast(&(*this)[3]); + } + + const vec3_type &x_axis() const + { + BLI_STATIC_ASSERT(NumCol >= 1, "Wrong Matrix dimension"); + BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension"); + return *reinterpret_cast(&(*this)[0]); + } + + const vec3_type &y_axis() const + { + BLI_STATIC_ASSERT(NumCol >= 2, "Wrong Matrix dimension"); + BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension"); + return *reinterpret_cast(&(*this)[1]); + } + + const vec3_type &z_axis() const + { + BLI_STATIC_ASSERT(NumCol >= 3, "Wrong Matrix dimension"); + BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension"); + return *reinterpret_cast(&(*this)[2]); + } + + const vec3_type &location() const + { + BLI_STATIC_ASSERT(NumCol >= 4, "Wrong Matrix dimension"); + BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension"); + return *reinterpret_cast(&(*this)[3]); + } + + /** Matrix operators. */ + + friend MatBase operator+(const MatBase &a, const MatBase &b) + { + MatBase result; + unroll([&](auto i) { result[i] = a[i] + b[i]; }); + return result; + } + + friend MatBase operator+(const MatBase &a, T b) + { + MatBase result; + unroll([&](auto i) { result[i] = a[i] + b; }); + return result; + } + + friend MatBase operator+(T a, const MatBase &b) + { + return b + a; + } + + MatBase &operator+=(const MatBase &b) + { + unroll([&](auto i) { (*this)[i] += b[i]; }); + return *this; + } + + MatBase &operator+=(T b) + { + unroll([&](auto i) { (*this)[i] += b; }); + return *this; + } + + friend MatBase operator-(const MatBase &a) + { + MatBase result; + unroll([&](auto i) { result[i] = -a[i]; }); + return result; + } + + friend MatBase operator-(const MatBase &a, const MatBase &b) + { + MatBase result; + unroll([&](auto i) { result[i] = a[i] - b[i]; }); + return result; + } + + friend MatBase operator-(const MatBase &a, T b) + { + MatBase result; + unroll([&](auto i) { result[i] = a[i] - b; }); + return result; + } + + friend MatBase operator-(T a, const MatBase &b) + { + MatBase result; + unroll([&](auto i) { result[i] = a - b[i]; }); + return result; + } + + MatBase &operator-=(const MatBase &b) + { + unroll([&](auto i) { (*this)[i] -= b[i]; }); + return *this; + } + + MatBase &operator-=(T b) + { + unroll([&](auto i) { (*this)[i] -= b; }); + return *this; + } + + /** Multiply two matrices using matrix multiplication. */ + MatBase operator*(const MatBase &b) const + { + const MatBase &a = *this; + /* This is the reference implementation. + * Might be overloaded with vectorized / optimized code. */ + /* TODO(fclem): It should be possible to return non-square matrices when multiplying against + * MatBase. */ + MatBase result{}; + unroll([&](auto j) { + unroll([&](auto i) { + /* Same as dot product, but avoid dependency on vector math. */ + unroll([&](auto k) { result[j][i] += a[k][i] * b[j][k]; }); + }); + }); + return result; + } + + /** Multiply each component by a scalar. */ + friend MatBase operator*(const MatBase &a, T b) + { + MatBase result; + unroll([&](auto i) { result[i] = a[i] * b; }); + return result; + } + + /** Multiply each component by a scalar. */ + friend MatBase operator*(T a, const MatBase &b) + { + return b * a; + } + + /** Multiply two matrices using matrix multiplication. */ + MatBase &operator*=(const MatBase &b) + { + const MatBase &a = *this; + *this = a * b; + return *this; + } + + /** Multiply each component by a scalar. */ + MatBase &operator*=(T b) + { + unroll([&](auto i) { (*this)[i] *= b; }); + return *this; + } + + /** Vector operators. */ + + friend col_type operator*(const MatBase &a, const row_type &b) + { + /* This is the reference implementation. + * Might be overloaded with vectorized / optimized code. */ + col_type result(0); + unroll([&](auto c) { result += b[c] * a[c]; }); + return result; + } + + /** Multiply by the transposed. */ + friend row_type operator*(const col_type &a, const MatBase &b) + { + /* This is the reference implementation. + * Might be overloaded with vectorized / optimized code. */ + row_type result(0); + unroll([&](auto c) { unroll([&](auto r) { result[c] += b[c][r] * a[r]; }); }); + return result; + } + + /** Compare. */ + + friend bool operator==(const MatBase &a, const MatBase &b) + { + for (int i = 0; i < NumCol; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + + friend bool operator!=(const MatBase &a, const MatBase &b) + { + return !(a == b); + } + + /** Miscellaneous. */ + + static MatBase diagonal(T value) + { + MatBase result{}; + unroll([&](auto i) { result[i][i] = value; }); + return result; + } + + static MatBase all(T value) + { + MatBase result; + unroll([&](auto i) { result[i] = col_type(value); }); + return result; + } + + static MatBase identity() + { + return diagonal(1); + } + + static MatBase zero() + { + return all(0); + } + + uint64_t hash() const + { + uint64_t h = 435109; + unroll([&](auto i) { + T value = (static_cast(this))[i]; + h = h * 33 + *reinterpret_cast *>(&value); + }); + return h; + } + + friend std::ostream &operator<<(std::ostream &stream, const MatBase &mat) + { + stream << "(\n"; + unroll([&](auto i) { + stream << "("; + unroll([&](auto j) { + /** NOTE: j and i are swapped to follow mathematical convention. */ + stream << mat[j][i]; + if (j < NumRow - 1) { + stream << ", "; + } + }); + stream << ")"; + if (i < NumCol - 1) { + stream << ","; + } + stream << "\n"; + }); + stream << ")\n"; + return stream; + } +}; + +template +struct MatView : NonCopyable, NonMovable { + using MatT = MatBase; + using SrcMatT = MatBase; + using col_type = vec_base; + using row_type = vec_base; + + const SrcMatT &mat; + + MatView() = delete; + + MatView(const SrcMatT &src) : mat(src) + { + BLI_STATIC_ASSERT(SrcStartCol >= 0, "View does not fit source matrix dimensions"); + BLI_STATIC_ASSERT(SrcStartRow >= 0, "View does not fit source matrix dimensions"); + BLI_STATIC_ASSERT(SrcStartCol + NumCol <= SrcNumCol, + "View does not fit source matrix dimensions"); + BLI_STATIC_ASSERT(SrcStartRow + NumRow <= SrcNumRow, + "View does not fit source matrix dimensions"); + } + + /** Allow wrapping C-style matrices using view. IMPORTANT: Alignment of src needs to match. */ + explicit MatView(const float (*src)[SrcNumRow]) + : MatView(*reinterpret_cast(&src[0][0])){}; + + /** Array access. */ + + const col_type &operator[](int index) const + { + BLI_assert(index >= 0); + BLI_assert(index < NumCol); + return *reinterpret_cast(&mat[index + SrcStartCol][SrcStartRow]); + } + + /** Conversion back to matrix. */ + + operator MatT() const + { + MatT mat; + unroll([&](auto c) { mat[c] = (*this)[c]; }); + return mat; + } + + /** Matrix operators. */ + + friend MatT operator+(const MatView &a, T b) + { + MatT result; + unroll([&](auto i) { result[i] = a[i] + b; }); + return result; + } + + friend MatT operator+(T a, const MatView &b) + { + return b + a; + } + + friend MatT operator-(const MatView &a) + { + MatT result; + unroll([&](auto i) { result[i] = -a[i]; }); + return result; + } + + template + friend MatT operator-(const MatView &a, + const MatView &b) + { + MatT result; + unroll([&](auto i) { result[i] = a[i] - b[i]; }); + return result; + } + + friend MatT operator-(const MatView &a, const MatT &b) + { + return a - b.template view(); + } + + template + friend MatT operator-(const MatView &a, + const MatView &b) + { + MatT result; + unroll([&](auto i) { result[i] = a[i] - b[i]; }); + return result; + } + + friend MatT operator-(const MatT &a, const MatView &b) + { + return a.template view() - b; + } + + friend MatT operator-(const MatView &a, T b) + { + MatT result; + unroll([&](auto i) { result[i] = a[i] - b; }); + return result; + } + + friend MatView operator-(T a, const MatView &b) + { + MatView result; + unroll([&](auto i) { result[i] = a - b[i]; }); + return result; + } + + /** Multiply two matrices using matrix multiplication. */ + template + MatBase operator*(const MatView &b) const + { + const MatView &a = *this; + /* This is the reference implementation. + * Might be overloaded with vectorized / optimized code. */ + MatBase result{}; + unroll([&](auto j) { + unroll([&](auto i) { + /* Same as dot product, but avoid dependency on vector math. */ + unroll([&](auto k) { result[j][i] += a[k][i] * b[j][k]; }); + }); + }); + return result; + } + + MatT operator*(const MatT &b) const + { + return *this * b.template view(); + } + + /** Multiply each component by a scalar. */ + friend MatT operator*(const MatView &a, T b) + { + MatT result; + unroll([&](auto i) { result[i] = a[i] * b; }); + return result; + } + + /** Multiply each component by a scalar. */ + friend MatT operator*(T a, const MatView &b) + { + return b * a; + } + + /** Vector operators. */ + + friend col_type operator*(const MatView &a, const row_type &b) + { + /* This is the reference implementation. + * Might be overloaded with vectorized / optimized code. */ + col_type result(0); + unroll([&](auto c) { result += b[c] * a[c]; }); + return result; + } + + /** Multiply by the transposed. */ + friend row_type operator*(const col_type &a, const MatView &b) + { + /* This is the reference implementation. + * Might be overloaded with vectorized / optimized code. */ + row_type result(0); + unroll([&](auto c) { unroll([&](auto r) { result[c] += b[c][r] * a[r]; }); }); + return result; + } + + /** Compare. */ + + friend bool operator==(const MatView &a, const MatView &b) + { + for (int i = 0; i < NumCol; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } + + friend bool operator!=(const MatView &a, const MatView &b) + { + return !(a == b); + } + + /** Miscellaneous. */ + + friend std::ostream &operator<<(std::ostream &stream, const MatView &mat) + { + return stream << mat->mat; + } +}; + +template +struct MutableMatView + : MatView { + + using MatT = MatBase; + using MatViewT = + MatView; + using SrcMatT = MatBase; + using col_type = vec_base; + using row_type = vec_base; + + public: + MutableMatView() = delete; + + MutableMatView(SrcMatT &src) : MatViewT(const_cast(src)){}; + + /** Allow wrapping C-style matrices using view. IMPORTANT: Alignment of src needs to match. */ + explicit MutableMatView(float src[SrcNumCol][SrcNumRow]) + : MutableMatView(*reinterpret_cast(&src[0][0])){}; + + /** Array access. */ + + col_type &operator[](int index) + { + return const_cast(static_cast(*this)[index]); + } + + /** Conversion to immutable view. */ + + operator MatViewT() const + { + return MatViewT(this->mat); + } + + /** Copy Assignment. */ + + template + MutableMatView &operator=(const MatView &other) + { + BLI_assert_msg( + (reinterpret_cast(&other.mat[0][0]) != + reinterpret_cast(&this->mat[0][0])) || + /* Make sure assignment won't overwrite the source. OtherSrc* is the source. */ + ((OtherSrcStartCol > SrcStartCol) || (OtherSrcStartCol + NumCol <= SrcStartCol) || + (OtherSrcStartRow > SrcStartRow + NumRow) || + (OtherSrcStartRow + NumRow <= SrcStartRow)), + "Operation is undefined if views overlap."); + unroll([&](auto i) { (*this)[i] = other[i]; }); + return *this; + } + + MutableMatView &operator=(const MatT &other) + { + *this = other.template view(); + return *this; + } + + /** Matrix operators. */ + + template + MutableMatView &operator+=(const MatView &b) + { + unroll([&](auto i) { (*this)[i] += b[i]; }); + return *this; + } + + MutableMatView &operator+=(const MatT &b) + { + return *this += b.template view(); + } + + MutableMatView &operator+=(T b) + { + unroll([&](auto i) { (*this)[i] += b; }); + return *this; + } + + template + MutableMatView &operator-=(const MatView &b) + { + unroll([&](auto i) { (*this)[i] -= b[i]; }); + return *this; + } + + MutableMatView &operator-=(const MatT &b) + { + return *this -= b.template view(); + } + + MutableMatView &operator-=(T b) + { + unroll([&](auto i) { (*this)[i] -= b; }); + return *this; + } + + /** Multiply two matrices using matrix multiplication. */ + template + MutableMatView &operator*=(const MatView &b) + { + *this = *static_cast(this) * b; + return *this; + } + + MutableMatView &operator*=(const MatT &b) + { + return *this *= b.template view(); + } + + /** Multiply each component by a scalar. */ + MutableMatView &operator*=(T b) + { + unroll([&](auto i) { (*this)[i] *= b; }); + return *this; + } +}; + +using float2x2 = MatBase; +using float2x3 = MatBase; +using float2x4 = MatBase; +using float3x2 = MatBase; +using float3x3 = MatBase; +using float3x4 = MatBase; +using float4x2 = MatBase; +using float4x3 = MatBase; +using float4x4 = MatBase; + +/* These types are reserved to wrap C matrices without copy. Note the un-alignment. */ +/* TODO: It would be preferable to align all C matrices inside DNA structs. */ +using float4x4_view = MatView; +using float4x4_mutableview = MutableMatView; + +using double2x2 = MatBase; +using double2x3 = MatBase; +using double2x4 = MatBase; +using double3x2 = MatBase; +using double3x3 = MatBase; +using double3x4 = MatBase; +using double4x2 = MatBase; +using double4x3 = MatBase; +using double4x4 = MatBase; + +/* Specialization for SSE optimization. */ +template<> float4x4 float4x4::operator*(const float4x4 &b) const; +template<> float3x3 float3x3::operator*(const float3x3 &b) const; + +extern template float2x2 float2x2::operator*(const float2x2 &b) const; +extern template double2x2 double2x2::operator*(const double2x2 &b) const; +extern template double3x3 double3x3::operator*(const double3x3 &b) const; +extern template double4x4 double4x4::operator*(const double4x4 &b) const; + +} // namespace blender diff --git a/source/blender/blenlib/BLI_math_rotation.hh b/source/blender/blenlib/BLI_math_rotation.hh new file mode 100644 index 00000000000..78c8dcbef08 --- /dev/null +++ b/source/blender/blenlib/BLI_math_rotation.hh @@ -0,0 +1,242 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +/** \file + * \ingroup bli + */ + +#include "BLI_math_matrix.hh" +#include "BLI_math_rotation_types.hh" +#include "BLI_math_vector.hh" + +namespace blender::math { + +/** + * Generic function for implementing slerp + * (quaternions and spherical vector coords). + * + * \param t: factor in [0..1] + * \param cosom: dot product from normalized vectors/quats. + * \param r_w: calculated weights. + */ +template inline vec_base interpolate_dot_slerp(const T t, const T cosom) +{ + const T eps = T(1e-4); + + BLI_assert(IN_RANGE_INCL(cosom, T(-1.0001), T(1.0001))); + + vec_base w; + /* Within [-1..1] range, avoid aligned axis. */ + if (LIKELY(math::abs(cosom) < (T(1) - eps))) { + const T omega = math::acos(cosom); + const T sinom = math::sin(omega); + + w[0] = math::sin((T(1) - t) * omega) / sinom; + w[1] = math::sin(t * omega) / sinom; + } + else { + /* Fallback to lerp */ + w[0] = T(1) - t; + w[1] = t; + } + return w; +} + +template +inline detail::Quaternion interpolate(const detail::Quaternion &a, + const detail::Quaternion &b, + T t) +{ + using Vec4T = vec_base; + BLI_assert(is_unit_scale(Vec4T(a))); + BLI_assert(is_unit_scale(Vec4T(b))); + + Vec4T quat = Vec4T(a); + T cosom = dot(Vec4T(a), Vec4T(b)); + /* Rotate around shortest angle. */ + if (cosom < T(0)) { + cosom = -cosom; + quat = -quat; + } + + vec_base w = interpolate_dot_slerp(t, cosom); + + return detail::Quaternion(w[0] * quat + w[1] * Vec4T(b)); +} + +} // namespace blender::math + +/* -------------------------------------------------------------------- */ +/** \name Template implementations + * \{ */ + +namespace blender::math::detail { + +#ifdef DEBUG +# define BLI_ASSERT_UNIT_QUATERNION(_q) \ + { \ + auto rot_vec = static_cast>(_q); \ + T quat_length = math::length_squared(rot_vec); \ + if (!(quat_length == 0 || (math::abs(quat_length - 1) < 0.0001))) { \ + std::cout << "Warning! " << __func__ << " called with non-normalized quaternion: size " \ + << quat_length << " *** report a bug ***\n"; \ + } \ + } +#else +# define BLI_ASSERT_UNIT_QUATERNION(_q) +#endif + +template AxisAngle::AxisAngle(const vec_base &axis, T angle) +{ + T length; + axis_ = math::normalize_and_get_length(axis, length); + if (length > 0.0f) { + angle_cos_ = math::cos(angle); + angle_sin_ = math::sin(angle); + angle_ = angle; + } + else { + *this = identity(); + } +} + +template AxisAngle::AxisAngle(const vec_base &from, const vec_base &to) +{ + BLI_assert(is_unit_scale(from)); + BLI_assert(is_unit_scale(to)); + + /* Avoid calculating the angle. */ + angle_cos_ = dot(from, to); + axis_ = normalize_and_get_length(cross(from, to), angle_sin_); + + if (angle_sin_ <= FLT_EPSILON) { + if (angle_cos_ > T(0)) { + /* Same vectors, zero rotation... */ + *this = identity(); + } + else { + /* Colinear but opposed vectors, 180 rotation... */ + axis_ = normalize(orthogonal(from)); + angle_sin_ = T(0); + angle_cos_ = T(-1); + } + } +} +template +AxisAngleNormalized::AxisAngleNormalized(const vec_base &axis, T angle) : AxisAngle() +{ + BLI_assert(is_unit_scale(axis)); + this->axis_ = axis; + this->angle_ = angle; + this->angle_cos_ = math::cos(angle); + this->angle_sin_ = math::sin(angle); +} + +template Quaternion::operator EulerXYZ() const +{ + using Mat3T = MatBase; + const Quaternion &quat = *this; + BLI_ASSERT_UNIT_QUATERNION(quat) + Mat3T unit_mat = math::from_rotation(quat); + return math::to_euler(unit_mat); +} + +template EulerXYZ::operator Quaternion() const +{ + const EulerXYZ &eul = *this; + const T ti = eul.x * T(0.5); + const T tj = eul.y * T(0.5); + const T th = eul.z * T(0.5); + const T ci = math::cos(ti); + const T cj = math::cos(tj); + const T ch = math::cos(th); + const T si = math::sin(ti); + const T sj = math::sin(tj); + const T sh = math::sin(th); + const T cc = ci * ch; + const T cs = ci * sh; + const T sc = si * ch; + const T ss = si * sh; + + Quaternion quat; + quat.x = cj * cc + sj * ss; + quat.y = cj * sc - sj * cs; + quat.z = cj * ss + sj * cc; + quat.w = cj * cs - sj * sc; + return quat; +} + +template Quaternion::operator AxisAngle() const +{ + const Quaternion &quat = *this; + BLI_ASSERT_UNIT_QUATERNION(quat) + + /* Calculate angle/2, and sin(angle/2). */ + T ha = math::acos(quat.x); + T si = math::sin(ha); + + /* From half-angle to angle. */ + T angle = ha * 2; + /* Prevent division by zero for axis conversion. */ + if (math::abs(si) < 0.0005) { + si = 1.0f; + } + + vec_base axis = vec_base(quat.y, quat.z, quat.w) / si; + if (math::is_zero(axis)) { + axis[1] = 1.0f; + } + return AxisAngleNormalized(axis, angle); +} + +template AxisAngle::operator Quaternion() const +{ + BLI_assert(math::is_unit_scale(axis_)); + + /** Using half angle identities: sin(angle / 2) = sqrt((1 - angle_cos) / 2) */ + T sine = math::sqrt(T(0.5) - angle_cos_ * T(0.5)); + const T cosine = math::sqrt(T(0.5) + angle_cos_ * T(0.5)); + + if (angle_sin_ < 0.0) { + sine = -sine; + } + + Quaternion quat; + quat.x = cosine; + quat.y = axis_.x * sine; + quat.z = axis_.y * sine; + quat.w = axis_.z * sine; + return quat; +} + +template EulerXYZ::operator AxisAngle() const +{ + /* Use quaternions as intermediate representation for now... */ + return AxisAngle(Quaternion(*this)); +} + +template AxisAngle::operator EulerXYZ() const +{ + /* Use quaternions as intermediate representation for now... */ + return EulerXYZ(Quaternion(*this)); +} + +/* Using explicit template instantiations in order to reduce compilation time. */ +extern template AxisAngle::operator EulerXYZ() const; +extern template AxisAngle::operator Quaternion() const; +extern template EulerXYZ::operator AxisAngle() const; +extern template EulerXYZ::operator Quaternion() const; +extern template Quaternion::operator AxisAngle() const; +extern template Quaternion::operator EulerXYZ() const; + +extern template AxisAngle::operator EulerXYZ() const; +extern template AxisAngle::operator Quaternion() const; +extern template EulerXYZ::operator AxisAngle() const; +extern template EulerXYZ::operator Quaternion() const; +extern template Quaternion::operator AxisAngle() const; +extern template Quaternion::operator EulerXYZ() const; + +} // namespace blender::math::detail + +/** \} */ diff --git a/source/blender/blenlib/BLI_math_rotation_types.hh b/source/blender/blenlib/BLI_math_rotation_types.hh new file mode 100644 index 00000000000..1689789db4b --- /dev/null +++ b/source/blender/blenlib/BLI_math_rotation_types.hh @@ -0,0 +1,244 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +/** \file + * \ingroup bli + */ + +#include "BLI_math_base.hh" +#include "BLI_math_vec_types.hh" + +namespace blender::math { + +namespace detail { + +/** + * Rotation Types + * + * It gives more semantic informations allowing overloaded functions based on the rotation + * type. It also prevent implicit cast from rotation to vector types. + */ + +/* Forward declaration. */ +template struct AxisAngle; +template struct Quaternion; + +template struct EulerXYZ { + T x, y, z; + + EulerXYZ() = default; + + EulerXYZ(const T &x, const T &y, const T &z) + { + this->x = x; + this->y = y; + this->z = z; + } + + EulerXYZ(const vec_base &vec) : EulerXYZ(UNPACK3(vec)){}; + + /** Static functions. */ + + static EulerXYZ identity() + { + return {0, 0, 0}; + } + + /** Conversions. */ + + explicit operator vec_base() const + { + return {this->x, this->y, this->z}; + } + + explicit operator AxisAngle() const; + + explicit operator Quaternion() const; + + /** Operators. */ + + friend std::ostream &operator<<(std::ostream &stream, const EulerXYZ &rot) + { + return stream << "EulerXYZ" << static_cast>(rot); + } +}; + +template struct Quaternion { + T x, y, z, w; + + Quaternion() = default; + + Quaternion(const T &x, const T &y, const T &z, const T &w) + { + this->x = x; + this->y = y; + this->z = z; + this->w = w; + } + + Quaternion(const vec_base &vec) : Quaternion(UNPACK4(vec)){}; + + /** Static functions. */ + + static Quaternion identity() + { + return {1, 0, 0, 0}; + } + + /** Conversions. */ + + explicit operator vec_base() const + { + return {this->x, this->y, this->z, this->w}; + } + + explicit operator EulerXYZ() const; + + explicit operator AxisAngle() const; + + /** Operators. */ + + const T &operator[](int i) const + { + BLI_assert(i >= 0 && i < 4); + return (&this->x)[i]; + } + + friend std::ostream &operator<<(std::ostream &stream, const Quaternion &rot) + { + return stream << "Quaternion" << static_cast>(rot); + } +}; + +template struct AxisAngle { + using vec3_type = vec_base; + + protected: + vec3_type axis_ = {0, 1, 0}; + /** Store cosine and sine so rotation is cheaper and doesn't require atan2. */ + T angle_cos_ = 1; + T angle_sin_ = 0; + /** + * Source angle for interpolation. + * It might not be computed on creation, so the getter ensures it is updated. + */ + T angle_ = 0; + + /** + * A defaulted constructor would cause zero initialization instead of default initialization, + * and not call the default member initializers. + */ + explicit AxisAngle(){}; + + public: + /** + * Create a rotation from an axis and an angle. + * \note `axis` does not have to be normalized. + * Use `AxisAngleNormalized` instead to skip normalization cost. + */ + AxisAngle(const vec3_type &axis, T angle); + + /** + * Create a rotation from 2 normalized vectors. + * \note `from` and `to` must be normalized. + */ + AxisAngle(const vec3_type &from, const vec3_type &to); + + /** Static functions. */ + + static AxisAngle identity() + { + return AxisAngle(); + } + + /** Getters. */ + + const vec3_type &axis() const + { + return axis_; + } + + const T &angle() const + { + if (UNLIKELY(angle_ == T(0) && angle_cos_ != T(1))) { + /* Angle wasn't computed by constructor. */ + const_cast(this)->angle_ = math::atan2(angle_sin_, angle_cos_); + } + return angle_; + } + + const T &angle_cos() const + { + return angle_cos_; + } + + const T &angle_sin() const + { + return angle_sin_; + } + + /** Conversions. */ + + explicit operator Quaternion() const; + + explicit operator EulerXYZ() const; + + /** Operators. */ + + friend bool operator==(const AxisAngle &a, const AxisAngle &b) + { + return (a.axis == b.axis) && (a.angle == b.angle); + } + + friend bool operator!=(const AxisAngle &a, const AxisAngle &b) + { + return (a != b); + } + + friend std::ostream &operator<<(std::ostream &stream, const AxisAngle &rot) + { + return stream << "AxisAngle(axis=" << rot.axis << ", angle=" << rot.angle << ")"; + } +}; + +/** + * A version of AxisAngle that expects axis to be already normalized. + * Implicitly cast back to AxisAngle. + */ +template struct AxisAngleNormalized : public AxisAngle { + AxisAngleNormalized(const vec_base &axis, T angle); + + operator AxisAngle() const + { + return *this; + } +}; + +/** + * Intermediate Types. + * + * Some functions need to have higher precision than standard floats for some operations. + */ +template struct TypeTraits { + using DoublePrecision = T; +}; +template<> struct TypeTraits { + using DoublePrecision = double; +}; + +}; // namespace detail + +template struct AssertUnitEpsilon> { + static constexpr U value = AssertUnitEpsilon::value * 10; +}; + +/* Most common used types. */ +using EulerXYZ = math::detail::EulerXYZ; +using Quaternion = math::detail::Quaternion; +using AxisAngle = math::detail::AxisAngle; +using AxisAngleNormalized = math::detail::AxisAngleNormalized; + +} // namespace blender::math + +/** \} */ diff --git a/source/blender/blenlib/BLI_math_vec_types.hh b/source/blender/blenlib/BLI_math_vec_types.hh index f57b4b44e61..0b3bb46db07 100644 --- a/source/blender/blenlib/BLI_math_vec_types.hh +++ b/source/blender/blenlib/BLI_math_vec_types.hh @@ -602,6 +602,15 @@ template struct vec_base : public vec_struct_base } }; +namespace math { + +template struct AssertUnitEpsilon { + /** \note Copy of BLI_ASSERT_UNIT_EPSILON_DB to avoid dragging the entire header. */ + static constexpr T value = T(0.0002); +}; + +} // namespace math + using char3 = blender::vec_base; using uchar3 = blender::vec_base; diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index 6ce033ea376..632be6316ad 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -17,18 +17,6 @@ namespace blender::math { -#ifndef NDEBUG -# define BLI_ASSERT_UNIT(v) \ - { \ - const float _test_unit = length_squared(v); \ - BLI_assert(!(std::abs(_test_unit - 1.0f) >= BLI_ASSERT_UNIT_EPSILON) || \ - !(std::abs(_test_unit) >= BLI_ASSERT_UNIT_EPSILON)); \ - } \ - (void)0 -#else -# define BLI_ASSERT_UNIT(v) (void)(v) -#endif - template inline bool is_zero(const vec_base &a) { for (int i = 0; i < Size; i++) { @@ -137,7 +125,7 @@ inline vec_base mod(const vec_base &a, const T &b) } template))> -inline T safe_mod(const vec_base &a, const vec_base &b) +inline vec_base safe_mod(const vec_base &a, const vec_base &b) { vec_base result; for (int i = 0; i < Size; i++) { @@ -147,7 +135,7 @@ inline T safe_mod(const vec_base &a, const vec_base &b) } template))> -inline T safe_mod(const vec_base &a, const T &b) +inline vec_base safe_mod(const vec_base &a, const T &b) { if (b == 0) { return vec_base(0); @@ -278,6 +266,16 @@ inline T length(const vec_base &a) return std::sqrt(length_squared(a)); } +template inline bool is_unit_scale(const vec_base &v) +{ + /* Checks are flipped so NAN doesn't assert because we're making sure the value was + * normalized and in the case we don't want NAN to be raising asserts since there + * is nothing to be done in that case. */ + const T test_unit = math::length_squared(v); + return (!(std::abs(test_unit - T(1)) >= AssertUnitEpsilon::value) || + !(std::abs(test_unit) >= AssertUnitEpsilon::value)); +} + template))> inline T distance_manhattan(const vec_base &a, const vec_base &b) { @@ -300,7 +298,7 @@ template))> inline vec_base reflect(const vec_base &incident, const vec_base &normal) { - BLI_ASSERT_UNIT(normal); + BLI_assert(is_unit_scale(normal)); return incident - 2.0 * dot(normal, incident) * normal; } @@ -400,6 +398,9 @@ inline vec_base midpoint(const vec_base &a, const vec_base))> inline vec_base faceforward(const vec_base &vector, const vec_base &incident, diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 17218a2daed..c554c19763b 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -18,6 +18,7 @@ set(INC ) set(INC_SYS + ${EIGEN3_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS} ${ZSTD_INCLUDE_DIRS} ${GMP_INCLUDE_DIRS} @@ -102,6 +103,7 @@ set(SRC intern/math_geom_inline.c intern/math_interp.c intern/math_matrix.c + intern/math_matrix.cc intern/math_rotation.c intern/math_rotation.cc intern/math_solvers.c @@ -485,6 +487,7 @@ if(WITH_GTESTS) tests/BLI_math_bits_test.cc tests/BLI_math_color_test.cc tests/BLI_math_geom_test.cc + tests/BLI_math_matrix_types_test.cc tests/BLI_math_matrix_test.cc tests/BLI_math_rotation_test.cc tests/BLI_math_solvers_test.cc diff --git a/source/blender/blenlib/intern/math_matrix.cc b/source/blender/blenlib/intern/math_matrix.cc new file mode 100644 index 00000000000..9211a608022 --- /dev/null +++ b/source/blender/blenlib/intern/math_matrix.cc @@ -0,0 +1,457 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. */ + +/** \file + * \ingroup bli + */ + +#include "BLI_math_matrix.hh" +#include "BLI_math_rotation.hh" + +#include +#include +#include + +/* -------------------------------------------------------------------- */ +/** \name Matrix multiplication + * \{ */ + +namespace blender { + +template<> float4x4 float4x4::operator*(const float4x4 &b) const +{ + using namespace math; + const float4x4 &a = *this; + float4x4 result; + +#ifdef BLI_HAVE_SSE2 + __m128 A0 = _mm_load_ps(a[0]); + __m128 A1 = _mm_load_ps(a[1]); + __m128 A2 = _mm_load_ps(a[2]); + __m128 A3 = _mm_load_ps(a[3]); + + for (int i = 0; i < 4; i++) { + __m128 B0 = _mm_set1_ps(b[i][0]); + __m128 B1 = _mm_set1_ps(b[i][1]); + __m128 B2 = _mm_set1_ps(b[i][2]); + __m128 B3 = _mm_set1_ps(b[i][3]); + + __m128 sum = _mm_add_ps(_mm_add_ps(_mm_mul_ps(B0, A0), _mm_mul_ps(B1, A1)), + _mm_add_ps(_mm_mul_ps(B2, A2), _mm_mul_ps(B3, A3))); + + _mm_store_ps(result[i], sum); + } +#else + const float4x4 T = transpose(b); + + result.x = float4(dot(a.x, T.x), dot(a.x, T.y), dot(a.x, T.z), dot(a.x, T.w)); + result.y = float4(dot(a.y, T.x), dot(a.y, T.y), dot(a.y, T.z), dot(a.y, T.w)); + result.z = float4(dot(a.z, T.x), dot(a.z, T.y), dot(a.z, T.z), dot(a.z, T.w)); + result.w = float4(dot(a.w, T.x), dot(a.w, T.y), dot(a.w, T.z), dot(a.w, T.w)); +#endif + return result; +} + +template<> float3x3 float3x3::operator*(const float3x3 &b) const +{ + using namespace math; + const float3x3 &a = *this; + float3x3 result; + +#if 0 /* 1.2 times slower. Could be used as reference for aligned version. */ + __m128 A0 = _mm_set_ps(0, a[0][2], a[0][1], a[0][0]); + __m128 A1 = _mm_set_ps(0, a[1][2], a[1][1], a[1][0]); + __m128 A2 = _mm_set_ps(0, a[2][2], a[2][1], a[2][0]); + + for (int i = 0; i < 2; i++) { + __m128 B0 = _mm_set1_ps(b[i][0]); + __m128 B1 = _mm_set1_ps(b[i][1]); + __m128 B2 = _mm_set1_ps(b[i][2]); + __m128 sum = _mm_add_ps(_mm_add_ps(_mm_mul_ps(B0, A0), _mm_mul_ps(B1, A1)), + _mm_mul_ps(B2, A2)); + _mm_storeu_ps(result[i], sum); + } + + _mm_storeu_ps(result[1], sum[1]); + /* Manual per component store to avoid segfault. */ + _mm_store_ss(&result[2][0], sum[2]); + sum[2] = _mm_shuffle_ps(sum[2], sum[2], _MM_SHUFFLE(3, 2, 1, 1)); + _mm_store_ss(&result[2][1], sum[2]); + sum[2] = _mm_shuffle_ps(sum[2], sum[2], _MM_SHUFFLE(3, 2, 1, 2)); + _mm_store_ss(&result[2][2], sum[2]); + +#else + /** Manual unrolling since MSVC doesn't seem to unroll properly. */ + result[0][0] = b[0][0] * a[0][0] + b[0][1] * a[1][0] + b[0][2] * a[2][0]; + result[0][1] = b[0][0] * a[0][1] + b[0][1] * a[1][1] + b[0][2] * a[2][1]; + result[0][2] = b[0][0] * a[0][2] + b[0][1] * a[1][2] + b[0][2] * a[2][2]; + + result[1][0] = b[1][0] * a[0][0] + b[1][1] * a[1][0] + b[1][2] * a[2][0]; + result[1][1] = b[1][0] * a[0][1] + b[1][1] * a[1][1] + b[1][2] * a[2][1]; + result[1][2] = b[1][0] * a[0][2] + b[1][1] * a[1][2] + b[1][2] * a[2][2]; + + result[2][0] = b[2][0] * a[0][0] + b[2][1] * a[1][0] + b[2][2] * a[2][0]; + result[2][1] = b[2][0] * a[0][1] + b[2][1] * a[1][1] + b[2][2] * a[2][1]; + result[2][2] = b[2][0] * a[0][2] + b[2][1] * a[1][2] + b[2][2] * a[2][2]; +#endif + return result; +} + +template float2x2 float2x2::operator*(const float2x2 &b) const; +template double2x2 double2x2::operator*(const double2x2 &b) const; +template double3x3 double3x3::operator*(const double3x3 &b) const; +template double4x4 double4x4::operator*(const double4x4 &b) const; + +} // namespace blender + +/** \} */ + +namespace blender::math { + +/* -------------------------------------------------------------------- */ +/** \name Determinant + * \{ */ + +template T determinant(const MatBase &mat) +{ + return Eigen::Map>(mat.base_ptr()).determinant(); +} + +template float determinant(const float2x2 &mat); +template float determinant(const float3x3 &mat); +template float determinant(const float4x4 &mat); +template double determinant(const double2x2 &mat); +template double determinant(const double3x3 &mat); +template double determinant(const double4x4 &mat); + +template bool is_negative(const MatBase &mat) +{ + return Eigen::Map, 0, Eigen::Stride<4, 1>>(mat.base_ptr()) + .determinant() < T(0); +} + +template bool is_negative(const float4x4 &mat); +template bool is_negative(const double4x4 &mat); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Adjoint + * \{ */ + +template MatBase adjoint(const MatBase &mat) +{ + MatBase adj; + unroll([&](auto c) { + unroll([&](auto r) { + /* Copy other cells except the "cross" to compute the determinant. */ + MatBase tmp; + unroll([&](auto m_c) { + unroll([&](auto m_r) { + if (m_c != c && m_r != r) { + int d_c = (m_c < c) ? m_c : (m_c - 1); + int d_r = (m_r < r) ? m_r : (m_r - 1); + tmp[d_c][d_r] = mat[m_c][m_r]; + } + }); + }); + T minor = determinant(tmp); + /* Transpose directly to get the adjugate. Swap destination row and col. */ + adj[r][c] = ((c + r) & 1) ? -minor : minor; + }); + }); + return adj; +} + +template float2x2 adjoint(const float2x2 &mat); +template float3x3 adjoint(const float3x3 &mat); +template float4x4 adjoint(const float4x4 &mat); +template double2x2 adjoint(const double2x2 &mat); +template double3x3 adjoint(const double3x3 &mat); +template double4x4 adjoint(const double4x4 &mat); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Inverse + * \{ */ + +template +MatBase invert(const MatBase &mat, bool &r_success) +{ + MatBase result; + Eigen::Map> M(mat.base_ptr()); + Eigen::Map> R(result.base_ptr()); + M.computeInverseWithCheck(R, r_success, 0.0f); + if (!r_success) { + R = R.Zero(); + } + return result; +} + +template float2x2 invert(const float2x2 &mat, bool &r_success); +template float3x3 invert(const float3x3 &mat, bool &r_success); +template float4x4 invert(const float4x4 &mat, bool &r_success); +template double2x2 invert(const double2x2 &mat, bool &r_success); +template double3x3 invert(const double3x3 &mat, bool &r_success); +template double4x4 invert(const double4x4 &mat, bool &r_success); + +template +MatBase pseudo_invert(const MatBase &mat, T epsilon) +{ + /* Start by trying normal inversion first. */ + bool success; + MatBase inv = invert(mat, success); + if (success) { + return inv; + } + + /** + * Compute the Single Value Decomposition of an arbitrary matrix A + * That is compute the 3 matrices U,W,V with U column orthogonal (m,n) + * ,W a diagonal matrix and V an orthogonal square matrix `s.t.A = U.W.Vt`. + * From this decomposition it is trivial to compute the (pseudo-inverse) + * of `A` as `Ainv = V.Winv.transpose(U)`. + */ + MatBase U, W, V; + vec_base S_val; + + { + using namespace Eigen; + using MatrixT = Eigen::Matrix; + using VectorT = Eigen::Matrix; + /* Blender and Eigen matrices are both column-major by default. + * Since our matrix is squared, we can use thinU/V. */ + /** WORKAROUND: + * (ComputeThinU | ComputeThinV) must be set as runtime parameters in Eigen < 3.4.0. + * But this requires the matrix type to be dynamic to avoid an assert. + */ + using MatrixDynamicT = Eigen::Matrix; + JacobiSVD svd( + Eigen::Map(mat.base_ptr(), Size, Size), ComputeThinU | ComputeThinV); + + (Eigen::Map(U.base_ptr())) = svd.matrixU(); + (Eigen::Map(S_val)) = svd.singularValues(); + (Eigen::Map(V.base_ptr())) = svd.matrixV(); + } + + /* Invert or nullify component based on epsilon comparison. */ + unroll([&](auto i) { S_val[i] = (S_val[i] < epsilon) ? T(0) : (T(1) / S_val[i]); }); + + W = from_scale>(S_val); + return (V * W) * transpose(U); +} + +template float2x2 pseudo_invert(const float2x2 &mat, float epsilon); +template float3x3 pseudo_invert(const float3x3 &mat, float epsilon); +template float4x4 pseudo_invert(const float4x4 &mat, float epsilon); +template double2x2 pseudo_invert(const double2x2 &mat, double epsilon); +template double3x3 pseudo_invert(const double3x3 &mat, double epsilon); +template double4x4 pseudo_invert(const double4x4 &mat, double epsilon); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Polar Decomposition + * \{ */ + +/** + * Right polar decomposition: + * M = UP + * + * U is the 'rotation'-like component, the closest orthogonal matrix to M. + * P is the 'scaling'-like component, defined in U space. + * + * See https://en.wikipedia.org/wiki/Polar_decomposition for more. + */ +template +static void polar_decompose(const MatBase &mat3, + MatBase &r_U, + MatBase &r_P) +{ + /* From svd decomposition (M = WSV*), we have: + * U = WV* + * P = VSV* + */ + MatBase W, V; + vec_base S_val; + + { + using namespace Eigen; + using MatrixT = Eigen::Matrix; + using VectorT = Eigen::Matrix; + /* Blender and Eigen matrices are both column-major by default. + * Since our matrix is squared, we can use thinU/V. */ + /** WORKAROUND: + * (ComputeThinU | ComputeThinV) must be set as runtime parameters in Eigen < 3.4.0. + * But this requires the matrix type to be dynamic to avoid an assert. + */ + using MatrixDynamicT = Eigen::Matrix; + JacobiSVD svd( + Eigen::Map(mat3.base_ptr(), 3, 3), ComputeThinU | ComputeThinV); + + (Eigen::Map(W.base_ptr())) = svd.matrixU(); + (Eigen::Map(S_val)) = svd.singularValues(); + (Map(V.base_ptr())) = svd.matrixV(); + } + + MatBase S = from_scale>(S_val); + MatBase Vt = transpose(V); + + r_U = W * Vt; + r_P = (V * S) * Vt; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Interpolate + * \{ */ + +template +MatBase interpolate(const MatBase &A, const MatBase &B, T t) +{ + using Mat3T = MatBase; + /* 'Rotation' component ('U' part of polar decomposition, + * the closest orthogonal matrix to M3 rot/scale + * transformation matrix), spherically interpolated. */ + Mat3T U_A, U_B; + /* 'Scaling' component ('P' part of polar decomposition, i.e. scaling in U-defined space), + * linearly interpolated. */ + Mat3T P_A, P_B; + + polar_decompose(A, U_A, P_A); + polar_decompose(B, U_B, P_B); + + /* Quaternions cannot represent an axis flip. If such a singularity is detected, choose a + * different decomposition of the matrix that still satisfies A = U_A * P_A but which has a + * positive determinant and thus no axis flips. This resolves T77154. + * + * Note that a flip of two axes is just a rotation of 180 degrees around the third axis, and + * three flipped axes are just an 180 degree rotation + a single axis flip. It is thus sufficient + * to solve this problem for single axis flips. */ + if (is_negative(U_A)) { + U_A = -U_A; + P_A = -P_A; + } + if (is_negative(U_B)) { + U_B = -U_B; + P_B = -P_B; + } + + detail::Quaternion quat_A = math::to_quaternion(U_A); + detail::Quaternion quat_B = math::to_quaternion(U_B); + detail::Quaternion quat = math::interpolate(quat_A, quat_B, t); + Mat3T U = from_rotation(quat); + + Mat3T P = interpolate_linear(P_A, P_B, t); + /* And we reconstruct rot/scale matrix from interpolated polar components */ + return U * P; +} + +template float3x3 interpolate(const float3x3 &a, const float3x3 &b, float t); +template double3x3 interpolate(const double3x3 &a, const double3x3 &b, double t); + +template +MatBase interpolate(const MatBase &A, const MatBase &B, T t) +{ + MatBase result = MatBase( + interpolate(MatBase(A), MatBase(B), t)); + + /* Location component, linearly interpolated. */ + const auto &loc_a = static_cast &>(A).location(); + const auto &loc_b = static_cast &>(B).location(); + result.location() = interpolate(loc_a, loc_b, t); + + return result; +} + +template float4x4 interpolate(const float4x4 &a, const float4x4 &b, float t); +template double4x4 interpolate(const double4x4 &a, const double4x4 &b, double t); + +template +MatBase interpolate_fast(const MatBase &a, const MatBase &b, T t) +{ + using QuaternionT = detail::Quaternion; + using Vec3T = typename MatBase::vec3_type; + + Vec3T a_scale, b_scale; + QuaternionT a_quat, b_quat; + to_rot_scale(a, a_quat, a_scale); + to_rot_scale(b, b_quat, b_scale); + + const Vec3T scale = interpolate(a_scale, b_scale, t); + const QuaternionT rotation = interpolate(a_quat, b_quat, t); + return from_rot_scale>(rotation, scale); +} + +template float3x3 interpolate_fast(const float3x3 &a, const float3x3 &b, float t); +template double3x3 interpolate_fast(const double3x3 &a, const double3x3 &b, double t); + +template +MatBase interpolate_fast(const MatBase &a, const MatBase &b, T t) +{ + using QuaternionT = detail::Quaternion; + using Vec3T = typename MatBase::vec3_type; + + Vec3T a_loc, b_loc; + Vec3T a_scale, b_scale; + QuaternionT a_quat, b_quat; + to_loc_rot_scale(a, a_loc, a_quat, a_scale); + to_loc_rot_scale(b, b_loc, b_quat, b_scale); + + const Vec3T location = interpolate(a_loc, b_loc, t); + const Vec3T scale = interpolate(a_scale, b_scale, t); + const QuaternionT rotation = interpolate(a_quat, b_quat, t); + return from_loc_rot_scale>(location, rotation, scale); +} + +template float4x4 interpolate_fast(const float4x4 &a, const float4x4 &b, float t); +template double4x4 interpolate_fast(const double4x4 &a, const double4x4 &b, double t); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Template instantiation + * \{ */ + +namespace detail { + +template void normalized_to_eul2(const float3x3 &mat, + detail::EulerXYZ &eul1, + detail::EulerXYZ &eul2); +template void normalized_to_eul2(const double3x3 &mat, + detail::EulerXYZ &eul1, + detail::EulerXYZ &eul2); + +template detail::Quaternion normalized_to_quat_with_checks(const float3x3 &mat); +template detail::Quaternion normalized_to_quat_with_checks(const double3x3 &mat); + +template MatBase from_rotation(const detail::EulerXYZ &rotation); +template MatBase from_rotation(const detail::EulerXYZ &rotation); +template MatBase from_rotation(const detail::Quaternion &rotation); +template MatBase from_rotation(const detail::Quaternion &rotation); +template MatBase from_rotation(const detail::AxisAngle &rotation); +template MatBase from_rotation(const detail::AxisAngle &rotation); + +} // namespace detail + +template float3 transform_point(const float3x3 &mat, const float3 &point); +template float3 transform_point(const float4x4 &mat, const float3 &point); +template float3 transform_direction(const float3x3 &mat, const float3 &direction); +template float3 transform_direction(const float4x4 &mat, const float3 &direction); +template float3 project_point(const float4x4 &mat, const float3 &point); +template float2 project_point(const float3x3 &mat, const float2 &point); + +namespace projection { + +template float4x4 orthographic( + float left, float right, float bottom, float top, float near_clip, float far_clip); +template float4x4 perspective( + float left, float right, float bottom, float top, float near_clip, float far_clip); + +} // namespace projection + +/** \} */ + +} // namespace blender::math diff --git a/source/blender/blenlib/intern/math_rotation.cc b/source/blender/blenlib/intern/math_rotation.cc index 454862c8d18..968d5bc57c0 100644 --- a/source/blender/blenlib/intern/math_rotation.cc +++ b/source/blender/blenlib/intern/math_rotation.cc @@ -5,10 +5,30 @@ */ #include "BLI_math_base.h" +#include "BLI_math_matrix.hh" +#include "BLI_math_rotation.hh" #include "BLI_math_rotation_legacy.hh" #include "BLI_math_vector.h" #include "BLI_math_vector.hh" +namespace blender::math::detail { + +template AxisAngle::operator EulerXYZ() const; +template AxisAngle::operator Quaternion() const; +template EulerXYZ::operator AxisAngle() const; +template EulerXYZ::operator Quaternion() const; +template Quaternion::operator AxisAngle() const; +template Quaternion::operator EulerXYZ() const; + +template AxisAngle::operator EulerXYZ() const; +template AxisAngle::operator Quaternion() const; +template EulerXYZ::operator AxisAngle() const; +template EulerXYZ::operator Quaternion() const; +template Quaternion::operator AxisAngle() const; +template Quaternion::operator EulerXYZ() const; + +} // namespace blender::math::detail + namespace blender::math { float3 rotate_direction_around_axis(const float3 &direction, const float3 &axis, const float angle) diff --git a/source/blender/blenlib/tests/BLI_math_matrix_test.cc b/source/blender/blenlib/tests/BLI_math_matrix_test.cc index e429be231b4..71c99a00807 100644 --- a/source/blender/blenlib/tests/BLI_math_matrix_test.cc +++ b/source/blender/blenlib/tests/BLI_math_matrix_test.cc @@ -3,6 +3,8 @@ #include "testing/testing.h" #include "BLI_math_matrix.h" +#include "BLI_math_matrix.hh" +#include "BLI_math_rotation.hh" TEST(math_matrix, interp_m4_m4m4_regular) { @@ -62,7 +64,7 @@ TEST(math_matrix, interp_m3_m3m3_singularity) transpose_m3(matrix_a); EXPECT_NEAR(-1.0f, determinant_m3_array(matrix_a), 1e-6); - /* This matrix represents R=(0, 0, 0), S=(-1, 0, 0) */ + /* This matrix represents R=(0, 0, 0), S=(-1, 1, 1) */ float matrix_b[3][3] = { {-1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, @@ -97,3 +99,372 @@ TEST(math_matrix, interp_m3_m3m3_singularity) EXPECT_NEAR(0.0f, determinant_m3_array(result), 1e-5); EXPECT_M3_NEAR(result, expect, 1e-5); } + +namespace blender::tests { + +using namespace blender::math; + +TEST(math_matrix, MatrixInverse) +{ + float3x3 mat = float3x3::diagonal(2); + float3x3 inv = invert(mat); + float3x3 expect = float3x3({0.5f, 0.0f, 0.0f}, {0.0f, 0.5f, 0.0f}, {0.0f, 0.0f, 0.5f}); + EXPECT_M3_NEAR(inv, expect, 1e-5f); + + bool success; + float3x3 mat2 = float3x3::all(1); + float3x3 inv2 = invert(mat2, success); + float3x3 expect2 = float3x3::all(0); + EXPECT_M3_NEAR(inv2, expect2, 1e-5f); + EXPECT_FALSE(success); +} + +TEST(math_matrix, MatrixPseudoInverse) +{ + float4x4 mat = transpose(float4x4({0.224976f, -0.333770f, 0.765074f, 0.100000f}, + {0.389669f, 0.647565f, 0.168130f, 0.200000f}, + {-0.536231f, 0.330541f, 0.443163f, 0.300000f}, + {0.000000f, 0.000000f, 0.000000f, 1.000000f})); + float4x4 expect = transpose(float4x4({0.224976f, -0.333770f, 0.765074f, 0.100000f}, + {0.389669f, 0.647565f, 0.168130f, 0.200000f}, + {-0.536231f, 0.330541f, 0.443163f, 0.300000f}, + {0.000000f, 0.000000f, 0.000000f, 1.000000f})); + float4x4 inv = pseudo_invert(mat); + pseudoinverse_m4_m4(expect.ptr(), mat.ptr(), 1e-8f); + EXPECT_M4_NEAR(inv, expect, 1e-5f); + + float4x4 mat2 = transpose(float4x4({0.000000f, -0.333770f, 0.765074f, 0.100000f}, + {0.000000f, 0.647565f, 0.168130f, 0.200000f}, + {0.000000f, 0.330541f, 0.443163f, 0.300000f}, + {0.000000f, 0.000000f, 0.000000f, 1.000000f})); + float4x4 expect2 = transpose(float4x4({0.000000f, 0.000000f, 0.000000f, 0.000000f}, + {-0.51311f, 1.02638f, 0.496437f, -0.302896f}, + {0.952803f, 0.221885f, 0.527413f, -0.297881f}, + {-0.0275438f, -0.0477073f, 0.0656508f, 0.9926f})); + float4x4 inv2 = pseudo_invert(mat2); + EXPECT_M4_NEAR(inv2, expect2, 1e-5f); +} + +TEST(math_matrix, MatrixDeterminant) +{ + float2x2 m2({1, 2}, {3, 4}); + float3x3 m3({1, 2, 3}, {-3, 4, -5}, {5, -6, 7}); + float4x4 m4({1, 2, -3, 3}, {3, 4, -5, 3}, {5, 6, 7, -3}, {5, 6, 7, 1}); + EXPECT_NEAR(determinant(m2), -2.0f, 1e-8f); + EXPECT_NEAR(determinant(m3), -16.0f, 1e-8f); + EXPECT_NEAR(determinant(m4), -112.0f, 1e-8f); + EXPECT_NEAR(determinant(double2x2(m2)), -2.0f, 1e-8f); + EXPECT_NEAR(determinant(double3x3(m3)), -16.0f, 1e-8f); + EXPECT_NEAR(determinant(double4x4(m4)), -112.0f, 1e-8f); +} + +TEST(math_matrix, MatrixAdjoint) +{ + float2x2 m2({1, 2}, {3, 4}); + float3x3 m3({1, 2, 3}, {-3, 4, -5}, {5, -6, 7}); + float4x4 m4({1, 2, -3, 3}, {3, 4, -5, 3}, {5, 6, 7, -3}, {5, 6, 7, 1}); + float2x2 expect2 = transpose(float2x2({4, -3}, {-2, 1})); + float3x3 expect3 = transpose(float3x3({-2, -4, -2}, {-32, -8, 16}, {-22, -4, 10})); + float4x4 expect4 = transpose( + float4x4({232, -184, -8, -0}, {-128, 88, 16, 0}, {80, -76, 4, 28}, {-72, 60, -12, -28})); + EXPECT_M2_NEAR(adjoint(m2), expect2, 1e-8f); + EXPECT_M3_NEAR(adjoint(m3), expect3, 1e-8f); + EXPECT_M4_NEAR(adjoint(m4), expect4, 1e-8f); +} + +TEST(math_matrix, MatrixAccess) +{ + float4x4 m({1, 2, 3, 4}, {5, 6, 7, 8}, {9, 1, 2, 3}, {4, 5, 6, 7}); + /** Access helpers. */ + EXPECT_EQ(m.x_axis(), float3(1, 2, 3)); + EXPECT_EQ(m.y_axis(), float3(5, 6, 7)); + EXPECT_EQ(m.z_axis(), float3(9, 1, 2)); + EXPECT_EQ(m.location(), float3(4, 5, 6)); +} + +TEST(math_matrix, MatrixInit) +{ + float4x4 expect; + + float4x4 m = from_location({1, 2, 3}); + expect = float4x4({1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {1, 2, 3, 1}); + EXPECT_TRUE(is_equal(m, expect, 0.00001f)); + + expect = transpose(float4x4({0.411982, -0.833738, -0.36763, 0}, + {-0.0587266, -0.426918, 0.902382, 0}, + {-0.909297, -0.350175, -0.224845, 0}, + {0, 0, 0, 1})); + EulerXYZ euler(1, 2, 3); + Quaternion quat(euler); + AxisAngle axis_angle(euler); + m = from_rotation(euler); + EXPECT_M3_NEAR(m, expect, 1e-5); + m = from_rotation(quat); + EXPECT_M3_NEAR(m, expect, 1e-5); + m = from_rotation(axis_angle); + EXPECT_M3_NEAR(m, expect, 1e-5); + + m = from_scale(float4(1, 2, 3, 4)); + expect = float4x4({1, 0, 0, 0}, {0, 2, 0, 0}, {0, 0, 3, 0}, {0, 0, 0, 4}); + EXPECT_TRUE(is_equal(m, expect, 0.00001f)); + + m = from_scale(float3(1, 2, 3)); + expect = float4x4({1, 0, 0, 0}, {0, 2, 0, 0}, {0, 0, 3, 0}, {0, 0, 0, 1}); + EXPECT_TRUE(is_equal(m, expect, 0.00001f)); + + m = from_scale(float2(1, 2)); + expect = float4x4({1, 0, 0, 0}, {0, 2, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}); + EXPECT_TRUE(is_equal(m, expect, 0.00001f)); + + m = from_loc_rot({1, 2, 3}, EulerXYZ{1, 2, 3}); + expect = float4x4({0.411982, -0.0587266, -0.909297, 0}, + {-0.833738, -0.426918, -0.350175, 0}, + {-0.36763, 0.902382, -0.224845, 0}, + {1, 2, 3, 1}); + EXPECT_TRUE(is_equal(m, expect, 0.00001f)); + + m = from_loc_rot_scale({1, 2, 3}, EulerXYZ{1, 2, 3}, float3{1, 2, 3}); + expect = float4x4({0.411982, -0.0587266, -0.909297, 0}, + {-1.66748, -0.853835, -0.700351, 0}, + {-1.10289, 2.70714, -0.674535, 0}, + {1, 2, 3, 1}); + EXPECT_TRUE(is_equal(m, expect, 0.00001f)); +} + +TEST(math_matrix, MatrixModify) +{ + const float epsilon = 1e-6; + float4x4 result, expect; + float4x4 m1 = float4x4({0, 3, 0, 0}, {2, 0, 0, 0}, {0, 0, 2, 0}, {0, 0, 0, 1}); + + expect = float4x4({0, 3, 0, 0}, {2, 0, 0, 0}, {0, 0, 2, 0}, {4, 9, 2, 1}); + result = translate(m1, float3(3, 2, 1)); + EXPECT_M4_NEAR(result, expect, epsilon); + + expect = float4x4({0, 3, 0, 0}, {2, 0, 0, 0}, {0, 0, 2, 0}, {4, 0, 0, 1}); + result = translate(m1, float2(0, 2)); + EXPECT_M4_NEAR(result, expect, epsilon); + + expect = float4x4({0, 0, -2, 0}, {2, 0, 0, 0}, {0, 3, 0, 0}, {0, 0, 0, 1}); + result = rotate(m1, AxisAngle({0, 1, 0}, M_PI_2)); + EXPECT_M4_NEAR(result, expect, epsilon); + + expect = float4x4({0, 9, 0, 0}, {4, 0, 0, 0}, {0, 0, 8, 0}, {0, 0, 0, 1}); + result = scale(m1, float3(3, 2, 4)); + EXPECT_M4_NEAR(result, expect, epsilon); + + expect = float4x4({0, 9, 0, 0}, {4, 0, 0, 0}, {0, 0, 2, 0}, {0, 0, 0, 1}); + result = scale(m1, float2(3, 2)); + EXPECT_M4_NEAR(result, expect, epsilon); +} + +TEST(math_matrix, MatrixCompareTest) +{ + float4x4 m1 = float4x4({0, 3, 0, 0}, {2, 0, 0, 0}, {0, 0, 2, 0}, {0, 0, 0, 1}); + float4x4 m2 = float4x4({0, 3.001, 0, 0}, {1.999, 0, 0, 0}, {0, 0, 2.001, 0}, {0, 0, 0, 1.001}); + float4x4 m3 = float4x4({0, 3.001, 0, 0}, {1, 1, 0, 0}, {0, 0, 2.001, 0}, {0, 0, 0, 1.001}); + float4x4 m4 = float4x4({0, 1, 0, 0}, {1, 0, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}); + float4x4 m5 = float4x4({0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}); + float4x4 m6 = float4x4({1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}); + EXPECT_TRUE(is_equal(m1, m2, 0.01f)); + EXPECT_FALSE(is_equal(m1, m2, 0.0001f)); + EXPECT_FALSE(is_equal(m1, m3, 0.01f)); + EXPECT_TRUE(is_orthogonal(m1)); + EXPECT_FALSE(is_orthogonal(m3)); + EXPECT_TRUE(is_orthonormal(m4)); + EXPECT_FALSE(is_orthonormal(m1)); + EXPECT_FALSE(is_orthonormal(m3)); + EXPECT_FALSE(is_uniformly_scaled(m1)); + EXPECT_TRUE(is_uniformly_scaled(m4)); + EXPECT_FALSE(is_zero(m4)); + EXPECT_TRUE(is_zero(m5)); + EXPECT_TRUE(is_negative(m4)); + EXPECT_FALSE(is_negative(m5)); + EXPECT_FALSE(is_negative(m6)); +} + +TEST(math_matrix, MatrixMethods) +{ + float4x4 m = float4x4({0, 3, 0, 0}, {2, 0, 0, 0}, {0, 0, 2, 0}, {0, 1, 0, 1}); + auto expect_eul = EulerXYZ(0, 0, M_PI_2); + auto expect_qt = Quaternion(0, -M_SQRT1_2, M_SQRT1_2, 0); + float3 expect_scale = float3(3, 2, 2); + float3 expect_location = float3(0, 1, 0); + + EXPECT_V3_NEAR(float3(to_euler(m)), float3(expect_eul), 0.0002f); + EXPECT_V4_NEAR(float4(to_quaternion(m)), float4(expect_qt), 0.0002f); + EXPECT_EQ(to_scale(m), expect_scale); + + float4 expect_sz = {3, 2, 2, M_SQRT2}; + float4 size; + float4x4 m1 = normalize_and_get_size(m, size); + EXPECT_TRUE(is_unit_scale(m1)); + EXPECT_V4_NEAR(size, expect_sz, 0.0002f); + + float4x4 m2 = normalize(m); + EXPECT_TRUE(is_unit_scale(m2)); + + EulerXYZ eul; + Quaternion qt; + float3 scale; + to_rot_scale(float3x3(m), eul, scale); + to_rot_scale(float3x3(m), qt, scale); + EXPECT_V3_NEAR(scale, expect_scale, 0.00001f); + EXPECT_V4_NEAR(float4(qt), float4(expect_qt), 0.0002f); + EXPECT_V3_NEAR(float3(eul), float3(expect_eul), 0.0002f); + + float3 loc; + to_loc_rot_scale(m, loc, eul, scale); + to_loc_rot_scale(m, loc, qt, scale); + EXPECT_V3_NEAR(scale, expect_scale, 0.00001f); + EXPECT_V3_NEAR(loc, expect_location, 0.00001f); + EXPECT_V4_NEAR(float4(qt), float4(expect_qt), 0.0002f); + EXPECT_V3_NEAR(float3(eul), float3(expect_eul), 0.0002f); +} + +TEST(math_matrix, MatrixTranspose) +{ + float4x4 m({1, 2, 3, 4}, {5, 6, 7, 8}, {9, 1, 2, 3}, {2, 5, 6, 7}); + float4x4 expect({1, 5, 9, 2}, {2, 6, 1, 5}, {3, 7, 2, 6}, {4, 8, 3, 7}); + EXPECT_EQ(transpose(m), expect); +} + +TEST(math_matrix, MatrixInterpolationRegular) +{ + /* Test 4x4 matrix interpolation without singularity, i.e. without axis flip. */ + + /* Transposed matrix, so that the code here is written in the same way as print_m4() outputs. */ + /* This matrix represents T=(0.1, 0.2, 0.3), R=(40, 50, 60) degrees, S=(0.7, 0.8, 0.9) */ + float4x4 m2 = transpose(float4x4({0.224976f, -0.333770f, 0.765074f, 0.100000f}, + {0.389669f, 0.647565f, 0.168130f, 0.200000f}, + {-0.536231f, 0.330541f, 0.443163f, 0.300000f}, + {0.000000f, 0.000000f, 0.000000f, 1.000000f})); + float4x4 m1 = float4x4::identity(); + float4x4 result; + const float epsilon = 1e-6; + result = interpolate(m1, m2, 0.0f); + EXPECT_M4_NEAR(result, m1, epsilon); + result = interpolate(m1, m2, 1.0f); + EXPECT_M4_NEAR(result, m2, epsilon); + + /* This matrix is based on the current implementation of the code, and isn't guaranteed to be + * correct. It's just consistent with the current implementation. */ + float4x4 expect = transpose(float4x4({0.690643f, -0.253244f, 0.484996f, 0.050000f}, + {0.271924f, 0.852623f, 0.012348f, 0.100000f}, + {-0.414209f, 0.137484f, 0.816778f, 0.150000f}, + {0.000000f, 0.000000f, 0.000000f, 1.000000f})); + result = interpolate(m1, m2, 0.5f); + EXPECT_M4_NEAR(result, expect, epsilon); + + result = interpolate_fast(m1, m2, 0.5f); + EXPECT_M4_NEAR(result, expect, epsilon); +} + +TEST(math_matrix, MatrixInterpolationSingularity) +{ + /* A singularity means that there is an axis mirror in the rotation component of the matrix. + * This is reflected in its negative determinant. + * + * The interpolation of 4x4 matrices performs linear interpolation on the translation component, + * and then uses the 3x3 interpolation function to handle rotation and scale. As a result, this + * test for a singularity in the rotation matrix only needs to test the 3x3 case. */ + + /* Transposed matrix, so that the code here is written in the same way as print_m4() outputs. */ + /* This matrix represents R=(4, 5, 6) degrees, S=(-1, 1, 1) */ + float3x3 matrix_a = transpose(float3x3({-0.990737f, -0.098227f, 0.093759f}, + {-0.104131f, 0.992735f, -0.060286f}, + {0.087156f, 0.069491f, 0.993768f})); + EXPECT_NEAR(-1.0f, determinant(matrix_a), 1e-6); + + /* This matrix represents R=(0, 0, 0), S=(-1, 1 1) */ + float3x3 matrix_b = transpose( + float3x3({-1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f})); + + float3x3 result = interpolate(matrix_a, matrix_b, 0.0f); + EXPECT_M3_NEAR(result, matrix_a, 1e-5); + + result = interpolate(matrix_a, matrix_b, 1.0f); + EXPECT_M3_NEAR(result, matrix_b, 1e-5); + + result = interpolate(matrix_a, matrix_b, 0.5f); + + float3x3 expect = transpose(float3x3({-0.997681f, -0.049995f, 0.046186f}, + {-0.051473f, 0.998181f, -0.031385f}, + {0.044533f, 0.033689f, 0.998440f})); + EXPECT_M3_NEAR(result, expect, 1e-5); + + result = interpolate_fast(matrix_a, matrix_b, 0.5f); + EXPECT_M3_NEAR(result, expect, 1e-5); + + /* Interpolating between a matrix with and without axis flip can cause it to go through a zero + * point. The determinant det(A) of a matrix represents the change in volume; interpolating + * between matrices with det(A)=-1 and det(B)=1 will have to go through a point where + * det(result)=0, so where the volume becomes zero. */ + float3x3 matrix_i = float3x3::identity(); + expect = float3x3::zero(); + result = interpolate(matrix_a, matrix_i, 0.5f); + EXPECT_NEAR(0.0f, determinant(result), 1e-5); + EXPECT_M3_NEAR(result, expect, 1e-5); +} + +TEST(math_matrix, MatrixTransform) +{ + float3 expect, result; + const float3 p(1, 2, 3); + float4x4 m4 = from_loc_rot({10, 0, 0}, EulerXYZ(M_PI_2, M_PI_2, M_PI_2)); + float3x3 m3 = from_rotation(EulerXYZ(M_PI_2, M_PI_2, M_PI_2)); + float4x4 pers4 = projection::perspective(-0.1f, 0.1f, -0.1f, 0.1f, -0.1f, -1.0f); + float3x3 pers3 = float3x3({1, 0, 0.1f}, {0, 1, 0.1f}, {0, 0.1f, 1}); + + expect = {13, 2, -1}; + result = transform_point(m4, p); + EXPECT_V3_NEAR(result, expect, 1e-2); + + expect = {3, 2, -1}; + result = transform_point(m3, p); + EXPECT_V3_NEAR(result, expect, 1e-5); + + result = transform_direction(m4, p); + EXPECT_V3_NEAR(result, expect, 1e-5); + + result = transform_direction(m3, p); + EXPECT_V3_NEAR(result, expect, 1e-5); + + expect = {-0.5, -1, -1.7222222}; + result = project_point(pers4, p); + EXPECT_V3_NEAR(result, expect, 1e-5); + + float2 expect2 = {0.76923, 1.61538}; + float2 result2 = project_point(pers3, float2(p)); + EXPECT_V2_NEAR(result2, expect2, 1e-5); +} + +TEST(math_matrix, MatrixProjection) +{ + using namespace math::projection; + float4x4 expect; + float4x4 ortho = orthographic(-0.2f, 0.3f, -0.2f, 0.4f, -0.2f, -0.5f); + float4x4 pers1 = perspective(-0.2f, 0.3f, -0.2f, 0.4f, -0.2f, -0.5f); + float4x4 pers2 = perspective_fov( + math::atan(-0.2f), math::atan(0.3f), math::atan(-0.2f), math::atan(0.4f), -0.2f, -0.5f); + + expect = transpose(float4x4({4.0f, 0.0f, 0.0f, -0.2f}, + {0.0f, 3.33333f, 0.0f, -0.333333f}, + {0.0f, 0.0f, 6.66667f, -2.33333f}, + {0.0f, 0.0f, 0.0f, 1.0f})); + EXPECT_M4_NEAR(ortho, expect, 1e-5); + + expect = transpose(float4x4({-0.8f, 0.0f, 0.2f, 0.0f}, + {0.0f, -0.666667f, 0.333333f, 0.0f}, + {0.0f, 0.0f, -2.33333f, 0.666667f}, + {0.0f, 0.0f, -1.0f, 1.0f})); + EXPECT_M4_NEAR(pers1, expect, 1e-5); + + expect = transpose(float4x4({4.0f, 0.0f, 0.2f, 0.0f}, + {0.0f, 3.33333f, 0.333333f, 0.0f}, + {0.0f, 0.0f, -2.33333f, 0.666667f}, + {0.0f, 0.0f, -1.0f, 1.0f})); + EXPECT_M4_NEAR(pers2, expect, 1e-5); +} + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_math_matrix_types_test.cc b/source/blender/blenlib/tests/BLI_math_matrix_types_test.cc new file mode 100644 index 00000000000..9b76c7aec44 --- /dev/null +++ b/source/blender/blenlib/tests/BLI_math_matrix_types_test.cc @@ -0,0 +1,403 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include "testing/testing.h" + +#include "BLI_math_matrix.hh" +#include "BLI_math_matrix_types.hh" + +namespace blender::tests { + +using namespace blender::math; + +TEST(math_matrix_types, DefaultConstructor) +{ + float2x2 m{}; + EXPECT_EQ(m[0][0], 0.0f); + EXPECT_EQ(m[1][1], 0.0f); + EXPECT_EQ(m[0][1], 0.0f); + EXPECT_EQ(m[1][0], 0.0f); +} + +TEST(math_matrix_types, StaticConstructor) +{ + float2x2 m = float2x2::identity(); + EXPECT_EQ(m[0][0], 1.0f); + EXPECT_EQ(m[1][1], 1.0f); + EXPECT_EQ(m[0][1], 0.0f); + EXPECT_EQ(m[1][0], 0.0f); + + m = float2x2::zero(); + EXPECT_EQ(m[0][0], 0.0f); + EXPECT_EQ(m[1][1], 0.0f); + EXPECT_EQ(m[0][1], 0.0f); + EXPECT_EQ(m[1][0], 0.0f); + + m = float2x2::diagonal(2); + EXPECT_EQ(m[0][0], 2.0f); + EXPECT_EQ(m[1][1], 2.0f); + EXPECT_EQ(m[0][1], 0.0f); + EXPECT_EQ(m[1][0], 0.0f); + + m = float2x2::all(1); + EXPECT_EQ(m[0][0], 1.0f); + EXPECT_EQ(m[1][1], 1.0f); + EXPECT_EQ(m[0][1], 1.0f); + EXPECT_EQ(m[1][0], 1.0f); +} + +TEST(math_matrix_types, VectorConstructor) +{ + float3x2 m({1.0f, 2.0f}, {3.0f, 4.0f}, {5.0f, 6.0f}); + EXPECT_EQ(m[0][0], 1.0f); + EXPECT_EQ(m[0][1], 2.0f); + EXPECT_EQ(m[1][0], 3.0f); + EXPECT_EQ(m[1][1], 4.0f); + EXPECT_EQ(m[2][0], 5.0f); + EXPECT_EQ(m[2][1], 6.0f); +} + +TEST(math_matrix_types, SmallerMatrixConstructor) +{ + float2x2 m2({1.0f, 2.0f}, {3.0f, 4.0f}); + float3x3 m3(m2); + EXPECT_EQ(m3[0][0], 1.0f); + EXPECT_EQ(m3[0][1], 2.0f); + EXPECT_EQ(m3[0][2], 0.0f); + EXPECT_EQ(m3[1][0], 3.0f); + EXPECT_EQ(m3[1][1], 4.0f); + EXPECT_EQ(m3[1][2], 0.0f); + EXPECT_EQ(m3[2][0], 0.0f); + EXPECT_EQ(m3[2][1], 0.0f); + EXPECT_EQ(m3[2][2], 1.0f); +} + +TEST(math_matrix_types, ComponentMasking) +{ + float3x3 m3({1.1f, 1.2f, 1.3f}, {2.1f, 2.2f, 2.3f}, {3.1f, 3.2f, 3.3f}); + float2x2 m2(m3); + EXPECT_EQ(m2[0][0], 1.1f); + EXPECT_EQ(m2[0][1], 1.2f); + EXPECT_EQ(m2[1][0], 2.1f); + EXPECT_EQ(m2[1][1], 2.2f); +} + +TEST(math_matrix_types, PointerConversion) +{ + float array[4] = {1.0f, 2.0f, 3.0f, 4.0f}; + float2x2 m2(array); + EXPECT_EQ(m2[0][0], 1.0f); + EXPECT_EQ(m2[0][1], 2.0f); + EXPECT_EQ(m2[1][0], 3.0f); + EXPECT_EQ(m2[1][1], 4.0f); +} + +TEST(math_matrix_types, TypeConversion) +{ + float3x2 m(double3x2({1.0f, 2.0f}, {3.0f, 4.0f}, {5.0f, 6.0f})); + EXPECT_EQ(m[0][0], 1.0f); + EXPECT_EQ(m[0][1], 2.0f); + EXPECT_EQ(m[1][0], 3.0f); + EXPECT_EQ(m[1][1], 4.0f); + EXPECT_EQ(m[2][0], 5.0f); + EXPECT_EQ(m[2][1], 6.0f); + + double3x2 d(m); + EXPECT_EQ(d[0][0], 1.0f); + EXPECT_EQ(d[0][1], 2.0f); + EXPECT_EQ(d[1][0], 3.0f); + EXPECT_EQ(d[1][1], 4.0f); + EXPECT_EQ(d[2][0], 5.0f); + EXPECT_EQ(d[2][1], 6.0f); +} + +TEST(math_matrix_types, PointerArrayConversion) +{ + float array[2][2] = {{1.0f, 2.0f}, {3.0f, 4.0f}}; + float(*ptr)[2] = array; + float2x2 m2(ptr); + EXPECT_EQ(m2[0][0], 1.0f); + EXPECT_EQ(m2[0][1], 2.0f); + EXPECT_EQ(m2[1][0], 3.0f); + EXPECT_EQ(m2[1][1], 4.0f); +} + +TEST(math_matrix_types, ComponentAccess) +{ + float3x3 m3({1.1f, 1.2f, 1.3f}, {2.1f, 2.2f, 2.3f}, {3.1f, 3.2f, 3.3f}); + EXPECT_EQ(m3.x.x, 1.1f); + EXPECT_EQ(m3.x.y, 1.2f); + EXPECT_EQ(m3.y.x, 2.1f); + EXPECT_EQ(m3.y.y, 2.2f); +} + +TEST(math_matrix_types, AddOperator) +{ + float3x3 m3({1.1f, 1.2f, 1.3f}, {2.1f, 2.2f, 2.3f}, {3.1f, 3.2f, 3.3f}); + + m3 = m3 + float3x3::diagonal(2); + EXPECT_EQ(m3[0][0], 3.1f); + EXPECT_EQ(m3[0][2], 1.3f); + EXPECT_EQ(m3[2][0], 3.1f); + EXPECT_EQ(m3[2][2], 5.3f); + + m3 += float3x3::diagonal(-1.0f); + EXPECT_EQ(m3[0][0], 2.1f); + EXPECT_EQ(m3[0][2], 1.3f); + EXPECT_EQ(m3[2][0], 3.1f); + EXPECT_EQ(m3[2][2], 4.3f); + + m3 += 1.0f; + EXPECT_EQ(m3[0][0], 3.1f); + EXPECT_EQ(m3[0][2], 2.3f); + EXPECT_EQ(m3[2][0], 4.1f); + EXPECT_EQ(m3[2][2], 5.3f); + + m3 = m3 + 1.0f; + EXPECT_EQ(m3[0][0], 4.1f); + EXPECT_EQ(m3[0][2], 3.3f); + EXPECT_EQ(m3[2][0], 5.1f); + EXPECT_EQ(m3[2][2], 6.3f); + + m3 = 1.0f + m3; + EXPECT_EQ(m3[0][0], 5.1f); + EXPECT_EQ(m3[0][2], 4.3f); + EXPECT_EQ(m3[2][0], 6.1f); + EXPECT_EQ(m3[2][2], 7.3f); +} + +TEST(math_matrix_types, SubtractOperator) +{ + float3x3 m3({10.0f, 10.2f, 10.3f}, {20.1f, 20.2f, 20.3f}, {30.1f, 30.2f, 30.3f}); + + m3 = m3 - float3x3::diagonal(2); + EXPECT_EQ(m3[0][0], 8.0f); + EXPECT_EQ(m3[0][2], 10.3f); + EXPECT_EQ(m3[2][0], 30.1f); + EXPECT_EQ(m3[2][2], 28.3f); + + m3 -= float3x3::diagonal(-1.0f); + EXPECT_EQ(m3[0][0], 9.0f); + EXPECT_EQ(m3[0][2], 10.3f); + EXPECT_EQ(m3[2][0], 30.1f); + EXPECT_EQ(m3[2][2], 29.3f); + + m3 -= 1.0f; + EXPECT_EQ(m3[0][0], 8.0f); + EXPECT_EQ(m3[0][2], 9.3f); + EXPECT_EQ(m3[2][0], 29.1f); + EXPECT_EQ(m3[2][2], 28.3f); + + m3 = m3 - 1.0f; + EXPECT_EQ(m3[0][0], 7.0f); + EXPECT_EQ(m3[0][2], 8.3f); + EXPECT_EQ(m3[2][0], 28.1f); + EXPECT_EQ(m3[2][2], 27.3f); + + m3 = 1.0f - m3; + EXPECT_EQ(m3[0][0], -6.0f); + EXPECT_EQ(m3[0][2], -7.3f); + EXPECT_EQ(m3[2][0], -27.1f); + EXPECT_EQ(m3[2][2], -26.3f); +} + +TEST(math_matrix_types, MultiplyOperator) +{ + float3x3 m3(float3(1.0f), float3(2.0f), float3(2.0f)); + + m3 = m3 * 2; + EXPECT_EQ(m3[0][0], 2.0f); + EXPECT_EQ(m3[2][2], 4.0f); + + m3 = 2 * m3; + EXPECT_EQ(m3[0][0], 4.0f); + EXPECT_EQ(m3[2][2], 8.0f); + + m3 *= 2; + EXPECT_EQ(m3[0][0], 8.0f); + EXPECT_EQ(m3[2][2], 16.0f); +} + +TEST(math_matrix_types, MatrixMultiplyOperator) +{ + float2x2 a(float2(1, 2), float2(3, 4)); + float2x2 b(float2(5, 6), float2(7, 8)); + + float2x2 result = a * b; + EXPECT_EQ(result[0][0], 23); + EXPECT_EQ(result[0][1], 34); + EXPECT_EQ(result[1][0], 31); + EXPECT_EQ(result[1][1], 46); + + result = a; + result *= b; + EXPECT_EQ(result[0][0], 23); + EXPECT_EQ(result[0][1], 34); + EXPECT_EQ(result[1][0], 31); + EXPECT_EQ(result[1][1], 46); + + /* Test SSE2 implementation. */ + float4x4 result2 = float4x4::diagonal(2) * float4x4::diagonal(6); + EXPECT_EQ(result2, float4x4::diagonal(12)); + + float3x3 result3 = float3x3::diagonal(2) * float3x3::diagonal(6); + EXPECT_EQ(result3, float3x3::diagonal(12)); + + /* Non square matrices. */ + float3x2 a4(float2(1, 2), float2(3, 4), float2(5, 6)); + float2x3 b4(float3(11, 7, 5), float3(13, 11, 17)); + + float2x2 expect4(float2(57, 80), float2(131, 172)); + + float2x2 result4 = a4 * b4; + EXPECT_EQ(result4[0][0], expect4[0][0]); + EXPECT_EQ(result4[0][1], expect4[0][1]); + EXPECT_EQ(result4[1][0], expect4[1][0]); + EXPECT_EQ(result4[1][1], expect4[1][1]); +} + +TEST(math_matrix_types, VectorMultiplyOperator) +{ + float3x2 mat(float2(1, 2), float2(3, 4), float2(5, 6)); + + float2 result = mat * float3(7, 8, 9); + EXPECT_EQ(result[0], 76); + EXPECT_EQ(result[1], 100); + + float3 result2 = float2(2, 3) * mat; + EXPECT_EQ(result2[0], 8); + EXPECT_EQ(result2[1], 18); + EXPECT_EQ(result2[2], 28); +} + +TEST(math_matrix_types, ViewConstructor) +{ + float4x4 mat = float4x4( + float4(1, 2, 3, 4), float4(5, 6, 7, 8), float4(9, 10, 11, 12), float4(13, 14, 15, 16)); + + auto view = mat.view<2, 2, 1, 1>(); + EXPECT_EQ(view[0][0], 6); + EXPECT_EQ(view[0][1], 7); + EXPECT_EQ(view[1][0], 10); + EXPECT_EQ(view[1][1], 11); + + float2x2 center = view; + EXPECT_EQ(center[0][0], 6); + EXPECT_EQ(center[0][1], 7); + EXPECT_EQ(center[1][0], 10); + EXPECT_EQ(center[1][1], 11); +} + +TEST(math_matrix_types, ViewFromCstyleMatrix) +{ + float c_style_mat[4][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}; + float4x4_view c_mat_view = float4x4_view(c_style_mat); + + float4x4_mutableview c_mat_mutable_view = float4x4_mutableview(c_style_mat); + + float4x4 expect = float4x4({2, 4, 6, 8}, {10, 12, 14, 16}, {18, 20, 22, 24}, {26, 28, 30, 32}); + + float4x4 mat = float4x4::diagonal(2.0f) * c_mat_view; + EXPECT_M4_NEAR(expect, mat, 1e-8f); + + c_mat_mutable_view *= float4x4::diagonal(2.0f); + EXPECT_M4_NEAR(expect, c_mat_mutable_view, 1e-8f); +} + +TEST(math_matrix_types, ViewAssignment) +{ + float4x4 mat = float4x4( + float4(1, 2, 3, 4), float4(5, 6, 7, 8), float4(9, 10, 11, 12), float4(13, 14, 15, 16)); + + mat.view<2, 2, 1, 1>() = float2x2({-1, -2}, {-3, -4}); + + float4x4 expect = float4x4({1, 2, 3, 4}, {5, -1, -2, 8}, {9, -3, -4, 12}, {13, 14, 15, 16}); + EXPECT_M4_NEAR(expect, mat, 1e-8f); + + /* Test view-view assignment. */ + mat.view<2, 2, 2, 2>() = mat.view<2, 2, 0, 0>(); + float4x4 expect2 = float4x4({1, 2, 3, 4}, {5, -1, -2, 8}, {9, -3, 1, 2}, {13, 14, 5, -1}); + EXPECT_M4_NEAR(expect2, mat, 1e-8f); + + mat.view<2, 2, 0, 0>() = mat.view<2, 2, 1, 1>(); + float4x4 expect3 = float4x4({-1, -2, 3, 4}, {-3, 1, -2, 8}, {9, -3, 1, 2}, {13, 14, 5, -1}); + EXPECT_M4_NEAR(expect3, mat, 1e-8f); + + /* Should fail to compile. */ + // const float4x4 &mat_const = mat; + // mat.view<2, 2, 2, 2>() = mat_const.view<2, 2, 0, 0>(); + + /* Should fail to run. */ + // mat.view<2, 2, 1, 1>() = mat.view<2, 2>(); +} + +TEST(math_matrix_types, ViewScalarOperators) +{ + float4x4 mat = float4x4({1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}); + + auto view = mat.view<2, 2, 1, 1>(); + EXPECT_EQ(view[0][0], 6); + EXPECT_EQ(view[0][1], 7); + EXPECT_EQ(view[1][0], 10); + EXPECT_EQ(view[1][1], 11); + + view += 1; + EXPECT_EQ(view[0][0], 7); + EXPECT_EQ(view[0][1], 8); + EXPECT_EQ(view[1][0], 11); + EXPECT_EQ(view[1][1], 12); + + view -= 2; + EXPECT_EQ(view[0][0], 5); + EXPECT_EQ(view[0][1], 6); + EXPECT_EQ(view[1][0], 9); + EXPECT_EQ(view[1][1], 10); + + view *= 4; + EXPECT_EQ(view[0][0], 20); + EXPECT_EQ(view[0][1], 24); + EXPECT_EQ(view[1][0], 36); + EXPECT_EQ(view[1][1], 40); + + /* Since we modified the view, we expect the source to have changed. */ + float4x4 expect = float4x4({1, 2, 3, 4}, {5, 20, 24, 8}, {9, 36, 40, 12}, {13, 14, 15, 16}); + EXPECT_M4_NEAR(expect, mat, 1e-8f); + + view = -view; + EXPECT_EQ(view[0][0], -20); + EXPECT_EQ(view[0][1], -24); + EXPECT_EQ(view[1][0], -36); + EXPECT_EQ(view[1][1], -40); +} + +TEST(math_matrix_types, ViewMatrixMultiplyOperator) +{ + float4x4 mat = float4x4({1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}); + auto view = mat.view<2, 2, 1, 1>(); + view = float2x2({1, 2}, {3, 4}); + + float2x2 result = view * float2x2({5, 6}, {7, 8}); + EXPECT_EQ(result[0][0], 23); + EXPECT_EQ(result[0][1], 34); + EXPECT_EQ(result[1][0], 31); + EXPECT_EQ(result[1][1], 46); + + view *= float2x2({5, 6}, {7, 8}); + EXPECT_EQ(view[0][0], 23); + EXPECT_EQ(view[0][1], 34); + EXPECT_EQ(view[1][0], 31); + EXPECT_EQ(view[1][1], 46); +} + +TEST(math_matrix_types, ViewMatrixNormalize) +{ + float4x4 mat = float4x4({1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}); + mat.view<3, 3>() = normalize(mat.view<3, 3>()); + + float4x4 expect = float4x4({0.267261236, 0.534522473, 0.80178368, 4}, + {0.476731300, 0.572077572, 0.66742378, 8}, + {0.517891824, 0.575435340, 0.63297885, 12}, + {13, 14, 15, 16}); + EXPECT_M4_NEAR(expect, mat, 1e-8f); +} + +} // namespace blender::tests diff --git a/source/blender/blenlib/tests/BLI_math_rotation_test.cc b/source/blender/blenlib/tests/BLI_math_rotation_test.cc index 7f4cbbd8b8c..32d8f8bf19e 100644 --- a/source/blender/blenlib/tests/BLI_math_rotation_test.cc +++ b/source/blender/blenlib/tests/BLI_math_rotation_test.cc @@ -5,6 +5,7 @@ #include "BLI_math_base.h" #include "BLI_math_matrix.h" #include "BLI_math_rotation.h" +#include "BLI_math_rotation.hh" #include "BLI_math_rotation_legacy.hh" #include "BLI_math_vector.hh" @@ -271,6 +272,20 @@ TEST(math_rotation, sin_cos_from_fraction_symmetry) namespace blender::math::tests { +TEST(math_rotation, DefaultConstructor) +{ + Quaternion quat{}; + EXPECT_EQ(quat.x, 0.0f); + EXPECT_EQ(quat.y, 0.0f); + EXPECT_EQ(quat.z, 0.0f); + EXPECT_EQ(quat.w, 0.0f); + + EulerXYZ eul{}; + EXPECT_EQ(eul.x, 0.0f); + EXPECT_EQ(eul.y, 0.0f); + EXPECT_EQ(eul.z, 0.0f); +} + TEST(math_rotation, RotateDirectionAroundAxis) { const float3 a = rotate_direction_around_axis({1, 0, 0}, {0, 0, 1}, M_PI_2); @@ -287,4 +302,41 @@ TEST(math_rotation, RotateDirectionAroundAxis) EXPECT_NEAR(c.z, 1.0f, FLT_EPSILON); } +TEST(math_rotation, AxisAngleConstructors) +{ + AxisAngle a({0.0f, 0.0f, 2.0f}, M_PI_2); + EXPECT_V3_NEAR(a.axis(), float3(0, 0, 1), 1e-4); + EXPECT_NEAR(a.angle(), M_PI_2, 1e-4); + + AxisAngleNormalized b({0.0f, 0.0f, 1.0f}, M_PI_2); + EXPECT_V3_NEAR(b.axis(), float3(0, 0, 1), 1e-4); + EXPECT_NEAR(b.angle(), M_PI_2, 1e-4); + + AxisAngle c({1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}); + EXPECT_V3_NEAR(c.axis(), float3(0, 0, 1), 1e-4); + EXPECT_NEAR(c.angle(), M_PI_2, 1e-4); + + AxisAngle d({1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}); + EXPECT_V3_NEAR(d.axis(), float3(0, 0, -1), 1e-4); + EXPECT_NEAR(d.angle(), M_PI_2, 1e-4); +} + +TEST(math_rotation, TypeConversion) +{ + EulerXYZ euler(0, 0, M_PI_2); + Quaternion quat(M_SQRT1_2, 0.0f, 0.0f, M_SQRT1_2); + AxisAngle axis_angle({0.0f, 0.0f, 2.0f}, M_PI_2); + + EXPECT_V4_NEAR(float4(Quaternion(euler)), float4(quat), 1e-4); + EXPECT_V3_NEAR(AxisAngle(euler).axis(), axis_angle.axis(), 1e-4); + EXPECT_NEAR(AxisAngle(euler).angle(), axis_angle.angle(), 1e-4); + + EXPECT_V3_NEAR(float3(EulerXYZ(quat)), float3(euler), 1e-4); + EXPECT_V3_NEAR(AxisAngle(quat).axis(), axis_angle.axis(), 1e-4); + EXPECT_NEAR(AxisAngle(quat).angle(), axis_angle.angle(), 1e-4); + + EXPECT_V3_NEAR(float3(EulerXYZ(axis_angle)), float3(euler), 1e-4); + EXPECT_V4_NEAR(float4(Quaternion(axis_angle)), float4(quat), 1e-4); +} + } // namespace blender::math::tests diff --git a/tests/gtests/testing/testing.h b/tests/gtests/testing/testing.h index 7b3e6e667aa..0e47dd802cb 100644 --- a/tests/gtests/testing/testing.h +++ b/tests/gtests/testing/testing.h @@ -42,6 +42,12 @@ const std::string &flags_test_release_dir(); /* bin/{blender version} in the bui } \ (void)0 +#define EXPECT_M2_NEAR(a, b, eps) \ + do { \ + EXPECT_V2_NEAR(a[0], b[0], eps); \ + EXPECT_V2_NEAR(a[1], b[1], eps); \ + } while (false); + #define EXPECT_M3_NEAR(a, b, eps) \ do { \ EXPECT_V3_NEAR(a[0], b[0], eps); \ From e9cb96d16e9e4e9fe8a0d80b3f2e775dafbcbfd7 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 6 Jan 2023 11:41:36 -0500 Subject: [PATCH 0476/1522] Fix: Build error on windows from mismatched forward declaration --- source/blender/blenkernel/BKE_curve_to_mesh.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/BKE_curve_to_mesh.hh b/source/blender/blenkernel/BKE_curve_to_mesh.hh index fb96fe4792b..4f72b98fc9b 100644 --- a/source/blender/blenkernel/BKE_curve_to_mesh.hh +++ b/source/blender/blenkernel/BKE_curve_to_mesh.hh @@ -10,7 +10,7 @@ struct Mesh; namespace blender::bke { -struct CurvesGeometry; +class CurvesGeometry; class AnonymousAttributePropagationInfo; /** From ddb30c4a02cdf342128021024b8e3567247107bb Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 6 Jan 2023 17:44:49 +0100 Subject: [PATCH 0477/1522] Fix T103396: crash extruding creased vertex with GPU subdivision --- .../draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc index 14467023f0f..d7625cb81d4 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc @@ -199,7 +199,7 @@ static void extract_lines_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache, if (mr->bm) { for (DRWSubdivLooseEdge edge : loose_edges) { const BMEdge *bm_edge = bm_original_edge_get(mr, edge.coarse_edge_index); - *flags_data++ = BM_elem_flag_test_bool(bm_edge, BM_ELEM_HIDDEN) != 0; + *flags_data++ = (bm_edge) ? BM_elem_flag_test_bool(bm_edge, BM_ELEM_HIDDEN) != 0 : 1; } } else { From 34b24fb6025011a28fcce4fc85e9132f7bf1cf57 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 6 Jan 2023 17:59:07 +0100 Subject: [PATCH 0478/1522] BLI: use proper alignment for new matrix types --- source/blender/blenlib/BLI_math_matrix_types.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/blenlib/BLI_math_matrix_types.hh b/source/blender/blenlib/BLI_math_matrix_types.hh index 6d6e738fc4b..f2cc66ebc1b 100644 --- a/source/blender/blenlib/BLI_math_matrix_types.hh +++ b/source/blender/blenlib/BLI_math_matrix_types.hh @@ -70,7 +70,7 @@ template< int NumRow, /* Alignment in bytes. Do not align matrices whose size is not a multiple of 4 component. * This is in order to avoid padding when using arrays of matrices. */ - int Alignment = (((NumCol * NumRow) % 4) ? 4 : 0) * sizeof(T)> + int Alignment = (((NumCol * NumRow) % 4 == 0) ? 4 : 1) * alignof(T)> struct alignas(Alignment) MatBase : public vec_struct_base, NumCol> { using base_type = T; @@ -923,8 +923,8 @@ using float4x4 = MatBase; /* These types are reserved to wrap C matrices without copy. Note the un-alignment. */ /* TODO: It would be preferable to align all C matrices inside DNA structs. */ -using float4x4_view = MatView; -using float4x4_mutableview = MutableMatView; +using float4x4_view = MatView; +using float4x4_mutableview = MutableMatView; using double2x2 = MatBase; using double2x3 = MatBase; From 302cb349c7f26446de3422e55c5972339ad65930 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 6 Jan 2023 18:04:41 +0100 Subject: [PATCH 0479/1522] Cleanup: quiet compiler warning For some reason this resulted in a unused-variable warning (on gcc). Think we had such false positives before when `constexpr` was used. --- source/blender/blenlib/BLI_math_matrix.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenlib/BLI_math_matrix.hh b/source/blender/blenlib/BLI_math_matrix.hh index a2d5abdc58b..a2884d04225 100644 --- a/source/blender/blenlib/BLI_math_matrix.hh +++ b/source/blender/blenlib/BLI_math_matrix.hh @@ -508,7 +508,7 @@ template using MatT = MatBase; BLI_STATIC_ASSERT(VectorT::type_length <= MatT::col_len - 1, "Translation should be at least 1 column less than the matrix."); - static constexpr int location_col = MatT::col_len - 1; + constexpr int location_col = MatT::col_len - 1; /* Avoid multiplying the last row if it exists. * Allows using non square matrices like float3x2 and saves computation. */ using IntermediateVecT = From 67e1b5256844eb525b11e0f20f4d568605b018db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Fri, 6 Jan 2023 18:19:09 +0100 Subject: [PATCH 0480/1522] BLI: Matrix: Fix compilation errors and wrong alignment Auto alignment was reversed and 0 alignment is producing warning. --- source/blender/blenlib/BLI_math_matrix.hh | 4 ++-- .../blender/blenlib/BLI_math_matrix_types.hh | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/source/blender/blenlib/BLI_math_matrix.hh b/source/blender/blenlib/BLI_math_matrix.hh index a2884d04225..17dca046dca 100644 --- a/source/blender/blenlib/BLI_math_matrix.hh +++ b/source/blender/blenlib/BLI_math_matrix.hh @@ -590,11 +590,11 @@ template -[[nodiscard]] MatBase normalize( +[[nodiscard]] MatBase normalize( const MatView &a) { - MatBase result; + MatBase result; unroll([&](auto i) { result[i] = math::normalize(a[i]); }); return result; } diff --git a/source/blender/blenlib/BLI_math_matrix_types.hh b/source/blender/blenlib/BLI_math_matrix_types.hh index f2cc66ebc1b..cfb491734f3 100644 --- a/source/blender/blenlib/BLI_math_matrix_types.hh +++ b/source/blender/blenlib/BLI_math_matrix_types.hh @@ -70,7 +70,7 @@ template< int NumRow, /* Alignment in bytes. Do not align matrices whose size is not a multiple of 4 component. * This is in order to avoid padding when using arrays of matrices. */ - int Alignment = (((NumCol * NumRow) % 4 == 0) ? 4 : 1) * alignof(T)> + int Alignment = (((NumCol * NumRow) % 4 == 0) ? 4 : 1) * sizeof(T)> struct alignas(Alignment) MatBase : public vec_struct_base, NumCol> { using base_type = T; @@ -605,7 +605,7 @@ struct MatView : NonCopyable, NonMovable { friend MatT operator-(const MatView &a, const MatT &b) { - return a - b.template view(); + return a - b.view(); } template { - using MatT = MatBase; + using MatT = MatBase; using MatViewT = MatView; using SrcMatT = MatBase; @@ -815,7 +815,7 @@ struct MutableMatView MutableMatView &operator=(const MatT &other) { - *this = other.template view(); + *this = other.view(); return *this; } @@ -841,7 +841,7 @@ struct MutableMatView MutableMatView &operator+=(const MatT &b) { - return *this += b.template view(); + return *this += b.view(); } MutableMatView &operator+=(T b) @@ -870,7 +870,7 @@ struct MutableMatView MutableMatView &operator-=(const MatT &b) { - return *this -= b.template view(); + return *this -= b.view(); } MutableMatView &operator-=(T b) @@ -900,7 +900,7 @@ struct MutableMatView MutableMatView &operator*=(const MatT &b) { - return *this *= b.template view(); + return *this *= b.view(); } /** Multiply each component by a scalar. */ From 940fd87e77b65a698ea9826191cf5a03c1eaf8f1 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Wed, 4 Jan 2023 10:33:40 +0100 Subject: [PATCH 0481/1522] Fix T103615: OSL image box mapping has flipped textures This breaks backwards compatibility some in that 3 sides will be mapped differently now, but difficult to avoid and can be considered a bugfix. Similar to rBdd8016f7081f. Maniphest Tasks: T103615 Differential Revision: https://developer.blender.org/D16910 --- .../kernel/osl/shaders/node_image_texture.osl | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/intern/cycles/kernel/osl/shaders/node_image_texture.osl b/intern/cycles/kernel/osl/shaders/node_image_texture.osl index 991fb9d161e..1a4f351d1da 100644 --- a/intern/cycles/kernel/osl/shaders/node_image_texture.osl +++ b/intern/cycles/kernel/osl/shaders/node_image_texture.osl @@ -122,6 +122,7 @@ shader node_image_texture(int use_mapping = 0, vector Nob = transform("world", "object", N); /* project from direction vector to barycentric coordinates in triangles */ + vector signed_Nob = Nob; Nob = vector(fabs(Nob[0]), fabs(Nob[1]), fabs(Nob[2])); Nob /= (Nob[0] + Nob[1] + Nob[2]); @@ -184,9 +185,10 @@ shader node_image_texture(int use_mapping = 0, float tmp_alpha; if (weight[0] > 0.0) { + point UV = point((signed_Nob[0] < 0.0) ? 1.0 - p[1] : p[1], p[2], 0.0); Color += weight[0] * image_texture_lookup(filename, - p[1], - p[2], + UV[0], + UV[1], tmp_alpha, compress_as_srgb, ignore_alpha, @@ -198,9 +200,10 @@ shader node_image_texture(int use_mapping = 0, Alpha += weight[0] * tmp_alpha; } if (weight[1] > 0.0) { + point UV = point((signed_Nob[1] > 0.0) ? 1.0 - p[0] : p[0], p[2], 0.0); Color += weight[1] * image_texture_lookup(filename, - p[0], - p[2], + UV[0], + UV[1], tmp_alpha, compress_as_srgb, ignore_alpha, @@ -212,9 +215,10 @@ shader node_image_texture(int use_mapping = 0, Alpha += weight[1] * tmp_alpha; } if (weight[2] > 0.0) { + point UV = point((signed_Nob[2] > 0.0) ? 1.0 - p[1] : p[1], p[0], 0.0); Color += weight[2] * image_texture_lookup(filename, - p[1], - p[0], + UV[0], + UV[1], tmp_alpha, compress_as_srgb, ignore_alpha, From 11ecde6a5af25b96d46dbfbf41dc2933a4128569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Tue, 3 Jan 2023 23:41:57 +0100 Subject: [PATCH 0482/1522] Cleanup: BLI: Remove BLI_ENABLE_IF((is_math_float_type)) from vector API This was limiting the use of the templates with other non internal types like Ceres types, xithout defining thing like that: `template<> inline constexpr bool is_math_float_type = true;` --- source/blender/blenlib/BLI_math_vector.hh | 66 ++++++++++------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index 632be6316ad..aac8e9f43b3 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -102,7 +102,7 @@ inline vec_base clamp(const vec_base &a, const T &min, const T return result; } -template))> +template inline vec_base mod(const vec_base &a, const vec_base &b) { vec_base result; @@ -113,8 +113,7 @@ inline vec_base mod(const vec_base &a, const vec_base return result; } -template))> -inline vec_base mod(const vec_base &a, const T &b) +template inline vec_base mod(const vec_base &a, const T &b) { BLI_assert(b != 0); vec_base result; @@ -124,7 +123,7 @@ inline vec_base mod(const vec_base &a, const T &b) return result; } -template))> +template inline vec_base safe_mod(const vec_base &a, const vec_base &b) { vec_base result; @@ -134,7 +133,7 @@ inline vec_base safe_mod(const vec_base &a, const vec_base))> +template inline vec_base safe_mod(const vec_base &a, const T &b) { if (b == 0) { @@ -152,7 +151,7 @@ inline vec_base safe_mod(const vec_base &a, const T &b) * In other words, it is equivalent to `divide_ceil(a, b) * b`. * It is undefined if \a a is negative or \b b is not strictly positive. */ -template))> +template inline vec_base ceil_to_multiple(const vec_base &a, const vec_base &b) { vec_base result; @@ -168,7 +167,7 @@ inline vec_base ceil_to_multiple(const vec_base &a, const vec_ * Integer division that returns the ceiling, instead of flooring like normal C division. * It is undefined if \a a is negative or \b b is not strictly positive. */ -template))> +template inline vec_base divide_ceil(const vec_base &a, const vec_base &b) { vec_base result; @@ -189,7 +188,7 @@ inline void min_max(const vec_base &vector, max = math::max(vector, max); } -template))> +template inline vec_base safe_divide(const vec_base &a, const vec_base &b) { vec_base result; @@ -199,14 +198,13 @@ inline vec_base safe_divide(const vec_base &a, const vec_base< return result; } -template))> +template inline vec_base safe_divide(const vec_base &a, const T &b) { return (b != 0) ? a / b : vec_base(0.0f); } -template))> -inline vec_base floor(const vec_base &a) +template inline vec_base floor(const vec_base &a) { vec_base result; for (int i = 0; i < Size; i++) { @@ -215,8 +213,7 @@ inline vec_base floor(const vec_base &a) return result; } -template))> -inline vec_base ceil(const vec_base &a) +template inline vec_base ceil(const vec_base &a) { vec_base result; for (int i = 0; i < Size; i++) { @@ -225,8 +222,7 @@ inline vec_base ceil(const vec_base &a) return result; } -template))> -inline vec_base fract(const vec_base &a) +template inline vec_base fract(const vec_base &a) { vec_base result; for (int i = 0; i < Size; i++) { @@ -235,8 +231,7 @@ inline vec_base fract(const vec_base &a) return result; } -template))> -inline T dot(const vec_base &a, const vec_base &b) +template inline T dot(const vec_base &a, const vec_base &b) { T result = a[0] * b[0]; for (int i = 1; i < Size; i++) { @@ -254,14 +249,12 @@ template inline T length_manhattan(const vec_base return result; } -template))> -inline T length_squared(const vec_base &a) +template inline T length_squared(const vec_base &a) { return dot(a, a); } -template))> -inline T length(const vec_base &a) +template inline T length(const vec_base &a) { return std::sqrt(length_squared(a)); } @@ -276,25 +269,25 @@ template inline bool is_unit_scale(const vec_base !(std::abs(test_unit) >= AssertUnitEpsilon::value)); } -template))> +template inline T distance_manhattan(const vec_base &a, const vec_base &b) { return length_manhattan(a - b); } -template))> +template inline T distance_squared(const vec_base &a, const vec_base &b) { return length_squared(a - b); } -template))> +template inline T distance(const vec_base &a, const vec_base &b) { return length(a - b); } -template))> +template inline vec_base reflect(const vec_base &incident, const vec_base &normal) { @@ -302,7 +295,7 @@ inline vec_base reflect(const vec_base &incident, return incident - 2.0 * dot(normal, incident) * normal; } -template))> +template inline vec_base refract(const vec_base &incident, const vec_base &normal, const T &eta) @@ -315,7 +308,7 @@ inline vec_base refract(const vec_base &incident, return eta * incident - (eta * dot_ni + sqrt(k)) * normal; } -template))> +template inline vec_base project(const vec_base &p, const vec_base &v_proj) { if (UNLIKELY(is_zero(v_proj))) { @@ -324,7 +317,7 @@ inline vec_base project(const vec_base &p, const vec_base))> +template inline vec_base normalize_and_get_length(const vec_base &v, T &out_length) { out_length = length_squared(v); @@ -339,15 +332,13 @@ inline vec_base normalize_and_get_length(const vec_base &v, T return vec_base(0.0); } -template))> -inline vec_base normalize(const vec_base &v) +template inline vec_base normalize(const vec_base &v) { T len; return normalize_and_get_length(v, len); } -template))> -inline vec_base cross(const vec_base &a, const vec_base &b) +template inline vec_base cross(const vec_base &a, const vec_base &b) { return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; } @@ -360,8 +351,7 @@ inline vec_base cross_high_precision(const vec_base &a, float(double(a.x) * double(b.y) - double(a.y) * double(b.x))}; } -template))> -inline vec_base cross_poly(Span> poly) +template inline vec_base cross_poly(Span> poly) { /* Newell's Method. */ int nv = int(poly.size()); @@ -384,7 +374,7 @@ inline vec_base cross_poly(Span> poly) return n; } -template))> +template inline vec_base interpolate(const vec_base &a, const vec_base &b, const FactorT &t) @@ -392,7 +382,7 @@ inline vec_base interpolate(const vec_base &a, return a * (1 - t) + b * t; } -template))> +template inline vec_base midpoint(const vec_base &a, const vec_base &b) { return (a + b) * 0.5; @@ -401,7 +391,7 @@ inline vec_base midpoint(const vec_base &a, const vec_base))> +template inline vec_base faceforward(const vec_base &vector, const vec_base &incident, const vec_base &reference) @@ -466,7 +456,7 @@ template struct isect_result { typename T::base_type lambda; }; -template))> +template isect_result> isect_seg_seg(const vec_base &v1, const vec_base &v2, const vec_base &v3, From 56216e2a62d8d0fe7f9610a2ce0a5f46c4f4d8ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Tue, 3 Jan 2023 23:59:37 +0100 Subject: [PATCH 0483/1522] Cleanup: BLI: Rename vector compare() to is_equal() for consistency Also rename parameters and give default value of 0 to epsilon. This way ommiting epsilon means expecting perfect equality. --- source/blender/blenlib/BLI_math_matrix.hh | 2 +- source/blender/blenlib/BLI_math_vector.hh | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/blenlib/BLI_math_matrix.hh b/source/blender/blenlib/BLI_math_matrix.hh index 17dca046dca..f02187690a0 100644 --- a/source/blender/blenlib/BLI_math_matrix.hh +++ b/source/blender/blenlib/BLI_math_matrix.hh @@ -378,7 +378,7 @@ template [[nodiscard]] bool is_negative(const MatBase &mat) template [[nodiscard]] inline bool is_equal(const MatBase &a, const MatBase &b, - const T epsilon) + const T epsilon = T(0)) { for (int i = 0; i < NumCol; i++) { for (int j = 0; j < NumRow; j++) { diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index aac8e9f43b3..4bd9a6a879e 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -434,10 +434,12 @@ template inline vec_base orthogonal(const vec_base &v) } template -inline bool compare(const vec_base &a, const vec_base &b, const T limit) +inline bool is_equal(const vec_base &a, + const vec_base &b, + const T epsilon = T(0)) { for (int i = 0; i < Size; i++) { - if (std::abs(a[i] - b[i]) > limit) { + if (std::abs(a[i] - b[i]) > epsilon) { return false; } } From da2dccca610f908230a742c1afe3faa49e157d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Wed, 4 Jan 2023 00:10:56 +0100 Subject: [PATCH 0484/1522] BLI: Add [[nodiscard]] to math vector lib This avoid silently ignoring the returned value. --- source/blender/blenlib/BLI_math_matrix.hh | 3 +- source/blender/blenlib/BLI_math_vector.hh | 141 ++++++++++++---------- 2 files changed, 80 insertions(+), 64 deletions(-) diff --git a/source/blender/blenlib/BLI_math_matrix.hh b/source/blender/blenlib/BLI_math_matrix.hh index f02187690a0..b0c88c8a0a6 100644 --- a/source/blender/blenlib/BLI_math_matrix.hh +++ b/source/blender/blenlib/BLI_math_matrix.hh @@ -54,7 +54,8 @@ template [[nodiscard]] T determinant(const MatBase MatBase adjoint(const MatBase &mat); +template +[[nodiscard]] MatBase adjoint(const MatBase &mat); /** * Equivalent to `mat * from_location(translation)` but with fewer operation. diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index 4bd9a6a879e..0c1edb3f0df 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -17,7 +17,7 @@ namespace blender::math { -template inline bool is_zero(const vec_base &a) +template [[nodiscard]] inline bool is_zero(const vec_base &a) { for (int i = 0; i < Size; i++) { if (a[i] != T(0)) { @@ -27,7 +27,7 @@ template inline bool is_zero(const vec_base &a) return true; } -template inline bool is_any_zero(const vec_base &a) +template [[nodiscard]] inline bool is_any_zero(const vec_base &a) { for (int i = 0; i < Size; i++) { if (a[i] == T(0)) { @@ -38,9 +38,9 @@ template inline bool is_any_zero(const vec_base & } template -inline bool almost_equal_relative(const vec_base &a, - const vec_base &b, - const T &epsilon_factor) +[[nodiscard]] inline bool almost_equal_relative(const vec_base &a, + const vec_base &b, + const T &epsilon_factor) { for (int i = 0; i < Size; i++) { const float epsilon = epsilon_factor * math::abs(a[i]); @@ -51,7 +51,8 @@ inline bool almost_equal_relative(const vec_base &a, return true; } -template inline vec_base abs(const vec_base &a) +template +[[nodiscard]] inline vec_base abs(const vec_base &a) { vec_base result; for (int i = 0; i < Size; i++) { @@ -61,7 +62,7 @@ template inline vec_base abs(const vec_base -inline vec_base min(const vec_base &a, const vec_base &b) +[[nodiscard]] inline vec_base min(const vec_base &a, const vec_base &b) { vec_base result; for (int i = 0; i < Size; i++) { @@ -71,7 +72,7 @@ inline vec_base min(const vec_base &a, const vec_base } template -inline vec_base max(const vec_base &a, const vec_base &b) +[[nodiscard]] inline vec_base max(const vec_base &a, const vec_base &b) { vec_base result; for (int i = 0; i < Size; i++) { @@ -81,9 +82,9 @@ inline vec_base max(const vec_base &a, const vec_base } template -inline vec_base clamp(const vec_base &a, - const vec_base &min, - const vec_base &max) +[[nodiscard]] inline vec_base clamp(const vec_base &a, + const vec_base &min, + const vec_base &max) { vec_base result = a; for (int i = 0; i < Size; i++) { @@ -93,7 +94,9 @@ inline vec_base clamp(const vec_base &a, } template -inline vec_base clamp(const vec_base &a, const T &min, const T &max) +[[nodiscard]] inline vec_base clamp(const vec_base &a, + const T &min, + const T &max) { vec_base result = a; for (int i = 0; i < Size; i++) { @@ -103,7 +106,7 @@ inline vec_base clamp(const vec_base &a, const T &min, const T } template -inline vec_base mod(const vec_base &a, const vec_base &b) +[[nodiscard]] inline vec_base mod(const vec_base &a, const vec_base &b) { vec_base result; for (int i = 0; i < Size; i++) { @@ -113,7 +116,8 @@ inline vec_base mod(const vec_base &a, const vec_base return result; } -template inline vec_base mod(const vec_base &a, const T &b) +template +[[nodiscard]] inline vec_base mod(const vec_base &a, const T &b) { BLI_assert(b != 0); vec_base result; @@ -124,7 +128,8 @@ template inline vec_base mod(const vec_base -inline vec_base safe_mod(const vec_base &a, const vec_base &b) +[[nodiscard]] inline vec_base safe_mod(const vec_base &a, + const vec_base &b) { vec_base result; for (int i = 0; i < Size; i++) { @@ -134,7 +139,7 @@ inline vec_base safe_mod(const vec_base &a, const vec_base -inline vec_base safe_mod(const vec_base &a, const T &b) +[[nodiscard]] inline vec_base safe_mod(const vec_base &a, const T &b) { if (b == 0) { return vec_base(0); @@ -152,7 +157,8 @@ inline vec_base safe_mod(const vec_base &a, const T &b) * It is undefined if \a a is negative or \b b is not strictly positive. */ template -inline vec_base ceil_to_multiple(const vec_base &a, const vec_base &b) +[[nodiscard]] inline vec_base ceil_to_multiple(const vec_base &a, + const vec_base &b) { vec_base result; for (int i = 0; i < Size; i++) { @@ -168,7 +174,8 @@ inline vec_base ceil_to_multiple(const vec_base &a, const vec_ * It is undefined if \a a is negative or \b b is not strictly positive. */ template -inline vec_base divide_ceil(const vec_base &a, const vec_base &b) +[[nodiscard]] inline vec_base divide_ceil(const vec_base &a, + const vec_base &b) { vec_base result; for (int i = 0; i < Size; i++) { @@ -180,16 +187,15 @@ inline vec_base divide_ceil(const vec_base &a, const vec_base< } template -inline void min_max(const vec_base &vector, - vec_base &min, - vec_base &max) +void min_max(const vec_base &vector, vec_base &min, vec_base &max) { min = math::min(vector, min); max = math::max(vector, max); } template -inline vec_base safe_divide(const vec_base &a, const vec_base &b) +[[nodiscard]] inline vec_base safe_divide(const vec_base &a, + const vec_base &b) { vec_base result; for (int i = 0; i < Size; i++) { @@ -199,12 +205,13 @@ inline vec_base safe_divide(const vec_base &a, const vec_base< } template -inline vec_base safe_divide(const vec_base &a, const T &b) +[[nodiscard]] inline vec_base safe_divide(const vec_base &a, const T &b) { return (b != 0) ? a / b : vec_base(0.0f); } -template inline vec_base floor(const vec_base &a) +template +[[nodiscard]] inline vec_base floor(const vec_base &a) { vec_base result; for (int i = 0; i < Size; i++) { @@ -213,7 +220,8 @@ template inline vec_base floor(const vec_base inline vec_base ceil(const vec_base &a) +template +[[nodiscard]] inline vec_base ceil(const vec_base &a) { vec_base result; for (int i = 0; i < Size; i++) { @@ -222,7 +230,8 @@ template inline vec_base ceil(const vec_base inline vec_base fract(const vec_base &a) +template +[[nodiscard]] inline vec_base fract(const vec_base &a) { vec_base result; for (int i = 0; i < Size; i++) { @@ -231,7 +240,8 @@ template inline vec_base fract(const vec_base inline T dot(const vec_base &a, const vec_base &b) +template +[[nodiscard]] inline T dot(const vec_base &a, const vec_base &b) { T result = a[0] * b[0]; for (int i = 1; i < Size; i++) { @@ -240,7 +250,7 @@ template inline T dot(const vec_base &a, const ve return result; } -template inline T length_manhattan(const vec_base &a) +template [[nodiscard]] inline T length_manhattan(const vec_base &a) { T result = std::abs(a[0]); for (int i = 1; i < Size; i++) { @@ -249,17 +259,17 @@ template inline T length_manhattan(const vec_base return result; } -template inline T length_squared(const vec_base &a) +template [[nodiscard]] inline T length_squared(const vec_base &a) { return dot(a, a); } -template inline T length(const vec_base &a) +template [[nodiscard]] inline T length(const vec_base &a) { return std::sqrt(length_squared(a)); } -template inline bool is_unit_scale(const vec_base &v) +template [[nodiscard]] inline bool is_unit_scale(const vec_base &v) { /* Checks are flipped so NAN doesn't assert because we're making sure the value was * normalized and in the case we don't want NAN to be raising asserts since there @@ -270,35 +280,35 @@ template inline bool is_unit_scale(const vec_base } template -inline T distance_manhattan(const vec_base &a, const vec_base &b) +[[nodiscard]] inline T distance_manhattan(const vec_base &a, const vec_base &b) { return length_manhattan(a - b); } template -inline T distance_squared(const vec_base &a, const vec_base &b) +[[nodiscard]] inline T distance_squared(const vec_base &a, const vec_base &b) { return length_squared(a - b); } template -inline T distance(const vec_base &a, const vec_base &b) +[[nodiscard]] inline T distance(const vec_base &a, const vec_base &b) { return length(a - b); } template -inline vec_base reflect(const vec_base &incident, - const vec_base &normal) +[[nodiscard]] inline vec_base reflect(const vec_base &incident, + const vec_base &normal) { BLI_assert(is_unit_scale(normal)); return incident - 2.0 * dot(normal, incident) * normal; } template -inline vec_base refract(const vec_base &incident, - const vec_base &normal, - const T &eta) +[[nodiscard]] inline vec_base refract(const vec_base &incident, + const vec_base &normal, + const T &eta) { float dot_ni = dot(normal, incident); float k = 1.0f - eta * eta * (1.0f - dot_ni * dot_ni); @@ -309,7 +319,8 @@ inline vec_base refract(const vec_base &incident, } template -inline vec_base project(const vec_base &p, const vec_base &v_proj) +[[nodiscard]] inline vec_base project(const vec_base &p, + const vec_base &v_proj) { if (UNLIKELY(is_zero(v_proj))) { return vec_base(0.0f); @@ -318,7 +329,8 @@ inline vec_base project(const vec_base &p, const vec_base -inline vec_base normalize_and_get_length(const vec_base &v, T &out_length) +[[nodiscard]] inline vec_base normalize_and_get_length(const vec_base &v, + T &out_length) { out_length = length_squared(v); /* A larger value causes normalize errors in a scaled down models with camera extreme close. */ @@ -332,26 +344,28 @@ inline vec_base normalize_and_get_length(const vec_base &v, T return vec_base(0.0); } -template inline vec_base normalize(const vec_base &v) +template +[[nodiscard]] inline vec_base normalize(const vec_base &v) { T len; return normalize_and_get_length(v, len); } -template inline vec_base cross(const vec_base &a, const vec_base &b) +template +[[nodiscard]] inline vec_base cross(const vec_base &a, const vec_base &b) { return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; } -inline vec_base cross_high_precision(const vec_base &a, - const vec_base &b) +[[nodiscard]] inline vec_base cross_high_precision(const vec_base &a, + const vec_base &b) { return {float(double(a.y) * double(b.z) - double(a.z) * double(b.y)), float(double(a.z) * double(b.x) - double(a.x) * double(b.z)), float(double(a.x) * double(b.y) - double(a.y) * double(b.x))}; } -template inline vec_base cross_poly(Span> poly) +template [[nodiscard]] inline vec_base cross_poly(Span> poly) { /* Newell's Method. */ int nv = int(poly.size()); @@ -375,15 +389,16 @@ template inline vec_base cross_poly(Span> poly) } template -inline vec_base interpolate(const vec_base &a, - const vec_base &b, - const FactorT &t) +[[nodiscard]] inline vec_base interpolate(const vec_base &a, + const vec_base &b, + const FactorT &t) { return a * (1 - t) + b * t; } template -inline vec_base midpoint(const vec_base &a, const vec_base &b) +[[nodiscard]] inline vec_base midpoint(const vec_base &a, + const vec_base &b) { return (a + b) * 0.5; } @@ -392,14 +407,14 @@ inline vec_base midpoint(const vec_base &a, const vec_base -inline vec_base faceforward(const vec_base &vector, - const vec_base &incident, - const vec_base &reference) +[[nodiscard]] inline vec_base faceforward(const vec_base &vector, + const vec_base &incident, + const vec_base &reference) { return (dot(reference, incident) < 0) ? vector : -vector; } -template inline int dominant_axis(const vec_base &a) +template [[nodiscard]] inline int dominant_axis(const vec_base &a) { vec_base b = abs(a); return ((b.x > b.y) ? ((b.x > b.z) ? 0 : 2) : ((b.y > b.z) ? 1 : 2)); @@ -410,7 +425,7 @@ template inline int dominant_axis(const vec_base &a) * \note Returned vector can be in any perpendicular direction. * \note Returned vector might not the same length as \a v. */ -template inline vec_base orthogonal(const vec_base &v) +template [[nodiscard]] inline vec_base orthogonal(const vec_base &v) { const int axis = dominant_axis(v); switch (axis) { @@ -428,15 +443,15 @@ template inline vec_base orthogonal(const vec_base &v) * Calculates a perpendicular vector to \a v. * \note Returned vector can be in any perpendicular direction. */ -template inline vec_base orthogonal(const vec_base &v) +template [[nodiscard]] inline vec_base orthogonal(const vec_base &v) { return {-v.y, v.x}; } template -inline bool is_equal(const vec_base &a, - const vec_base &b, - const T epsilon = T(0)) +[[nodiscard]] inline bool is_equal(const vec_base &a, + const vec_base &b, + const T epsilon = T(0)) { for (int i = 0; i < Size; i++) { if (std::abs(a[i] - b[i]) > epsilon) { @@ -459,9 +474,9 @@ template struct isect_result { }; template -isect_result> isect_seg_seg(const vec_base &v1, - const vec_base &v2, - const vec_base &v3, - const vec_base &v4); +[[nodiscard]] isect_result> isect_seg_seg(const vec_base &v1, + const vec_base &v2, + const vec_base &v3, + const vec_base &v4); } // namespace blender::math From 8f44c37f5cc2da6ca307f12168f5052788d50919 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Wed, 4 Jan 2023 00:14:55 +0100 Subject: [PATCH 0485/1522] Cleanup: Rename BLI_math_vec_types* files to BLI_math_vector_types This is for the sake of consistency and clarity. --- source/blender/blenkernel/BKE_attribute.hh | 2 +- source/blender/blenkernel/BKE_crazyspace.hh | 2 +- source/blender/blenkernel/BKE_curves.hh | 2 +- source/blender/blenkernel/BKE_geometry_set.hh | 2 +- source/blender/blenkernel/BKE_image_wrappers.hh | 2 +- source/blender/blenkernel/BKE_mesh_sample.hh | 2 +- source/blender/blenkernel/BKE_mesh_types.h | 2 +- source/blender/blenkernel/BKE_pbvh_pixels.hh | 2 +- source/blender/blenkernel/BKE_pointcloud.h | 2 +- source/blender/blenkernel/BKE_volume.h | 2 +- source/blender/blenkernel/intern/DerivedMesh.cc | 2 +- source/blender/blenkernel/intern/attribute_access.cc | 2 +- source/blender/blenkernel/intern/curve.cc | 2 +- source/blender/blenkernel/intern/gpencil_geom.cc | 2 +- source/blender/blenkernel/intern/mesh_boolean_convert.cc | 2 +- source/blender/blenkernel/intern/mesh_normals.cc | 2 +- source/blender/blenkernel/intern/mesh_remesh_voxel.cc | 2 +- source/blender/blenkernel/intern/object.cc | 2 +- source/blender/blenkernel/intern/object_dupli.cc | 2 +- source/blender/blenkernel/intern/pbvh_uv_islands.hh | 2 +- source/blender/blenkernel/intern/simulation.cc | 2 +- source/blender/blenkernel/intern/tracking_test.cc | 2 +- source/blender/blenkernel/intern/volume.cc | 2 +- source/blender/blenkernel/intern/volume_render.cc | 2 +- source/blender/blenkernel/intern/volume_to_mesh.cc | 2 +- source/blender/blenlib/BLI_delaunay_2d.h | 4 ++-- source/blender/blenlib/BLI_float3x3.hh | 2 +- source/blender/blenlib/BLI_float4x4.hh | 2 +- source/blender/blenlib/BLI_math_boolean.hh | 4 ++-- source/blender/blenlib/BLI_math_matrix_types.hh | 2 +- source/blender/blenlib/BLI_math_rotation_legacy.hh | 2 +- source/blender/blenlib/BLI_math_rotation_types.hh | 2 +- source/blender/blenlib/BLI_math_vector.hh | 2 +- ...I_math_vec_mpq_types.hh => BLI_math_vector_mpq_types.hh} | 0 .../{BLI_math_vec_types.hh => BLI_math_vector_types.hh} | 0 source/blender/blenlib/BLI_mesh_intersect.hh | 4 ++-- source/blender/blenlib/BLI_noise.hh | 2 +- source/blender/blenlib/BLI_rand.hh | 2 +- source/blender/blenlib/CMakeLists.txt | 6 +++--- source/blender/blenlib/intern/cpp_types.cc | 2 +- source/blender/blenlib/intern/delaunay_2d.cc | 2 +- source/blender/blenlib/intern/math_boolean.cc | 2 +- source/blender/blenlib/intern/math_vec.cc | 2 +- source/blender/blenlib/intern/mesh_boolean.cc | 2 +- source/blender/blenlib/intern/mesh_intersect.cc | 4 ++-- source/blender/blenlib/tests/BLI_delaunay_2d_test.cc | 2 +- source/blender/blenlib/tests/BLI_float3x3_test.cc | 2 +- ...math_vec_types_test.cc => BLI_math_vector_types_test.cc} | 2 +- source/blender/blenlib/tests/BLI_memory_utils_test.cc | 2 +- source/blender/blenlib/tests/BLI_mesh_boolean_test.cc | 2 +- source/blender/blenlib/tests/BLI_mesh_intersect_test.cc | 2 +- source/blender/blenloader/intern/versioning_defaults.cc | 2 +- source/blender/bmesh/intern/bmesh_query_uv.cc | 2 +- source/blender/compositor/COM_defines.h | 2 +- .../blender/compositor/realtime_compositor/COM_context.hh | 2 +- source/blender/compositor/realtime_compositor/COM_domain.hh | 2 +- source/blender/compositor/realtime_compositor/COM_result.hh | 2 +- .../realtime_compositor/COM_static_cache_manager.hh | 2 +- .../compositor/realtime_compositor/COM_texture_pool.hh | 2 +- .../blender/compositor/realtime_compositor/COM_utilities.hh | 2 +- .../algorithms/COM_algorithm_parallel_reduction.hh | 2 +- .../algorithms/COM_algorithm_symmetric_separable_blur.hh | 2 +- .../algorithms/intern/algorithm_parallel_reduction.cc | 2 +- .../algorithms/intern/symmetric_separable_blur.cc | 2 +- .../cached_resources/COM_symmetric_blur_weights.hh | 2 +- .../COM_symmetric_separable_blur_weights.hh | 2 +- .../cached_resources/intern/symmetric_blur_weights.cc | 2 +- .../compositor/realtime_compositor/intern/compile_state.cc | 2 +- .../realtime_compositor/intern/conversion_operation.cc | 2 +- .../blender/compositor/realtime_compositor/intern/domain.cc | 2 +- .../intern/input_single_value_operation.cc | 2 +- .../intern/realize_on_domain_operation.cc | 2 +- .../blender/compositor/realtime_compositor/intern/result.cc | 2 +- .../realtime_compositor/intern/static_cache_manager.cc | 2 +- .../compositor/realtime_compositor/intern/texture_pool.cc | 2 +- .../compositor/realtime_compositor/intern/utilities.cc | 2 +- source/blender/draw/engines/compositor/compositor_engine.cc | 2 +- source/blender/draw/engines/image/image_drawing_mode.hh | 2 +- source/blender/draw/engines/image/image_texture_info.hh | 2 +- source/blender/draw/intern/DRW_gpu_wrapper.hh | 2 +- source/blender/draw/intern/draw_cache_impl_curve.cc | 2 +- source/blender/draw/intern/draw_cache_impl_curves.cc | 2 +- source/blender/draw/intern/draw_cache_impl_gpencil.cc | 2 +- source/blender/draw/intern/draw_debug.hh | 2 +- source/blender/draw/intern/draw_pbvh.cc | 2 +- .../intern/mesh_extractors/extract_mesh_vbo_attributes.cc | 2 +- .../editors/interface/interface_template_search_operator.cc | 2 +- source/blender/editors/sculpt_paint/sculpt_automasking.cc | 2 +- source/blender/editors/space_node/node_group.cc | 2 +- .../blender/editors/space_spreadsheet/spreadsheet_column.cc | 2 +- .../blender/editors/space_spreadsheet/spreadsheet_layout.cc | 2 +- source/blender/functions/intern/cpp_types.cc | 2 +- source/blender/geometry/GEO_mesh_primitive_cuboid.hh | 2 +- source/blender/gpu/GPU_shader_shared_utils.h | 2 +- source/blender/io/collada/MeshImporter.h | 2 +- source/blender/io/gpencil/intern/gpencil_io_base.cc | 2 +- source/blender/io/gpencil/intern/gpencil_io_base.hh | 2 +- source/blender/io/gpencil/intern/gpencil_io_import_svg.cc | 2 +- source/blender/io/stl/importer/stl_import_mesh.hh | 2 +- source/blender/io/usd/intern/usd_reader_mesh.cc | 2 +- source/blender/io/usd/intern/usd_writer_volume.h | 2 +- source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh | 2 +- source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh | 2 +- .../blender/io/wavefront_obj/exporter/obj_export_nurbs.cc | 2 +- .../io/wavefront_obj/importer/importer_mesh_utils.hh | 2 +- .../blender/io/wavefront_obj/importer/obj_import_objects.hh | 2 +- source/blender/io/wavefront_obj/importer/obj_importer.cc | 2 +- source/blender/io/wavefront_obj/tests/obj_importer_tests.cc | 2 +- source/blender/makesdna/DNA_mesh_types.h | 2 +- source/blender/makesdna/DNA_pointcloud_types.h | 2 +- source/blender/modifiers/intern/MOD_nodes.cc | 2 +- source/blender/nodes/NOD_socket_declarations.hh | 2 +- source/blender/nodes/composite/nodes/node_composite_blur.cc | 2 +- .../nodes/composite/nodes/node_composite_bokehblur.cc | 2 +- .../nodes/composite/nodes/node_composite_bokehimage.cc | 2 +- .../blender/nodes/composite/nodes/node_composite_boxmask.cc | 2 +- .../nodes/composite/nodes/node_composite_composite.cc | 2 +- source/blender/nodes/composite/nodes/node_composite_crop.cc | 2 +- .../blender/nodes/composite/nodes/node_composite_dilate.cc | 2 +- .../nodes/composite/nodes/node_composite_directionalblur.cc | 2 +- .../nodes/composite/nodes/node_composite_ellipsemask.cc | 2 +- .../blender/nodes/composite/nodes/node_composite_glare.cc | 2 +- .../blender/nodes/composite/nodes/node_composite_image.cc | 2 +- .../nodes/composite/nodes/node_composite_lensdist.cc | 2 +- .../blender/nodes/composite/nodes/node_composite_levels.cc | 2 +- .../nodes/composite/nodes/node_composite_movieclip.cc | 2 +- .../nodes/composite/nodes/node_composite_pixelate.cc | 2 +- source/blender/nodes/composite/nodes/node_composite_rgb.cc | 2 +- .../blender/nodes/composite/nodes/node_composite_scale.cc | 2 +- .../blender/nodes/composite/nodes/node_composite_tonemap.cc | 2 +- .../nodes/composite/nodes/node_composite_trackpos.cc | 2 +- .../nodes/composite/nodes/node_composite_translate.cc | 2 +- .../blender/nodes/composite/nodes/node_composite_viewer.cc | 2 +- source/blender/nodes/geometry/node_geometry_util.hh | 2 +- source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc | 2 +- .../blender/nodes/geometry/nodes/node_geo_image_texture.cc | 2 +- .../geometry/nodes/node_geo_input_shortest_edge_paths.cc | 2 +- source/blender/nodes/intern/node_socket.cc | 2 +- source/blender/nodes/shader/nodes/node_shader_tex_brick.cc | 2 +- source/blender/render/intern/texture_margin.cc | 2 +- 140 files changed, 144 insertions(+), 144 deletions(-) rename source/blender/blenlib/{BLI_math_vec_mpq_types.hh => BLI_math_vector_mpq_types.hh} (100%) rename source/blender/blenlib/{BLI_math_vec_types.hh => BLI_math_vector_types.hh} (100%) rename source/blender/blenlib/tests/{BLI_math_vec_types_test.cc => BLI_math_vector_types_test.cc} (99%) diff --git a/source/blender/blenkernel/BKE_attribute.hh b/source/blender/blenkernel/BKE_attribute.hh index 031a4bb86ea..1eb352bfdda 100644 --- a/source/blender/blenkernel/BKE_attribute.hh +++ b/source/blender/blenkernel/BKE_attribute.hh @@ -8,7 +8,7 @@ #include "BLI_function_ref.hh" #include "BLI_generic_span.hh" #include "BLI_generic_virtual_array.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_set.hh" #include "BKE_anonymous_attribute_id.hh" diff --git a/source/blender/blenkernel/BKE_crazyspace.hh b/source/blender/blenkernel/BKE_crazyspace.hh index adebf0b7884..1d29c65454c 100644 --- a/source/blender/blenkernel/BKE_crazyspace.hh +++ b/source/blender/blenkernel/BKE_crazyspace.hh @@ -7,7 +7,7 @@ #pragma once #include "BLI_float3x3.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_span.hh" struct Depsgraph; diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index 9f849584710..1ed872c8ab8 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -17,7 +17,7 @@ #include "BLI_float4x4.hh" #include "BLI_generic_virtual_array.hh" #include "BLI_index_mask.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_shared_cache.hh" #include "BLI_span.hh" #include "BLI_task.hh" diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh index e6f55a8500f..42d773055fa 100644 --- a/source/blender/blenkernel/BKE_geometry_set.hh +++ b/source/blender/blenkernel/BKE_geometry_set.hh @@ -14,7 +14,7 @@ #include "BLI_function_ref.hh" #include "BLI_hash.hh" #include "BLI_map.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_set.hh" #include "BLI_user_counter.hh" #include "BLI_vector_set.hh" diff --git a/source/blender/blenkernel/BKE_image_wrappers.hh b/source/blender/blenkernel/BKE_image_wrappers.hh index b3e81571e05..7fa26066e73 100644 --- a/source/blender/blenkernel/BKE_image_wrappers.hh +++ b/source/blender/blenkernel/BKE_image_wrappers.hh @@ -9,7 +9,7 @@ #include "DNA_image_types.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" namespace blender::bke::image { diff --git a/source/blender/blenkernel/BKE_mesh_sample.hh b/source/blender/blenkernel/BKE_mesh_sample.hh index 94dc52d5ec9..e4d987271a3 100644 --- a/source/blender/blenkernel/BKE_mesh_sample.hh +++ b/source/blender/blenkernel/BKE_mesh_sample.hh @@ -8,7 +8,7 @@ #include "BLI_function_ref.hh" #include "BLI_generic_virtual_array.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "DNA_meshdata_types.h" diff --git a/source/blender/blenkernel/BKE_mesh_types.h b/source/blender/blenkernel/BKE_mesh_types.h index 93b65d1561f..5265ae3624c 100644 --- a/source/blender/blenkernel/BKE_mesh_types.h +++ b/source/blender/blenkernel/BKE_mesh_types.h @@ -16,7 +16,7 @@ # include "BLI_array.hh" # include "BLI_bit_vector.hh" # include "BLI_bounds_types.hh" -# include "BLI_math_vec_types.hh" +# include "BLI_math_vector_types.hh" # include "BLI_shared_cache.hh" # include "BLI_span.hh" diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh index 1b0d51fd37d..55ecf65bcac 100644 --- a/source/blender/blenkernel/BKE_pbvh_pixels.hh +++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh @@ -4,7 +4,7 @@ #pragma once #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_rect.h" #include "BLI_vector.hh" diff --git a/source/blender/blenkernel/BKE_pointcloud.h b/source/blender/blenkernel/BKE_pointcloud.h index d493e051cb5..48be080968d 100644 --- a/source/blender/blenkernel/BKE_pointcloud.h +++ b/source/blender/blenkernel/BKE_pointcloud.h @@ -11,7 +11,7 @@ # include # include "BLI_bounds_types.hh" -# include "BLI_math_vec_types.hh" +# include "BLI_math_vector_types.hh" # include "BLI_shared_cache.hh" #endif diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h index 8549cd14b3c..00b5993c5eb 100644 --- a/source/blender/blenkernel/BKE_volume.h +++ b/source/blender/blenkernel/BKE_volume.h @@ -160,7 +160,7 @@ bool BKE_volume_save(const struct Volume *volume, #ifdef __cplusplus # include "BLI_float4x4.hh" -# include "BLI_math_vec_types.hh" +# include "BLI_math_vector_types.hh" # include "BLI_string_ref.hh" bool BKE_volume_min_max(const Volume *volume, blender::float3 &r_min, blender::float3 &r_max); diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 8a57cc66e94..8ca569a7726 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -24,7 +24,7 @@ #include "BLI_blenlib.h" #include "BLI_linklist.h" #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_task.h" #include "BLI_task.hh" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index a5dbc4645fb..acae10499c3 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -16,7 +16,7 @@ #include "BLI_array_utils.hh" #include "BLI_color.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "FN_field.hh" diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index 28961461819..b510b48870b 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -16,7 +16,7 @@ #include "BLI_ghash.h" #include "BLI_index_range.hh" #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_string.h" #include "BLI_utildefines.h" #include "BLT_translation.h" diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc index 9297663b157..5bdb450596b 100644 --- a/source/blender/blenkernel/intern/gpencil_geom.cc +++ b/source/blender/blenkernel/intern/gpencil_geom.cc @@ -20,8 +20,8 @@ #include "BLI_ghash.h" #include "BLI_hash.h" #include "BLI_heap.h" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.h" +#include "BLI_math_vector_types.hh" #include "BLI_polyfill_2d.h" #include "BLI_span.hh" diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index 3d98fc7c958..14a9a852c16 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -19,7 +19,7 @@ #include "BLI_array.hh" #include "BLI_float4x4.hh" #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_mesh_boolean.hh" #include "BLI_mesh_intersect.hh" #include "BLI_span.hh" diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index 7d486a99406..b856e996bd0 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -21,7 +21,7 @@ #include "BLI_linklist.h" #include "BLI_linklist_stack.h" #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_memarena.h" #include "BLI_span.hh" #include "BLI_stack.h" diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index ddc0625ba6b..e44dd1a1c75 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -16,8 +16,8 @@ #include "BLI_array.hh" #include "BLI_index_range.hh" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.h" +#include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "BLI_task.hh" diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 0622007d97d..7f04ca9331f 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -54,7 +54,7 @@ #include "BLI_linklist.h" #include "BLI_listbase.h" #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_threads.h" #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index e7f62c339cd..e8a610d568e 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -17,7 +17,7 @@ #include "BLI_array.hh" #include "BLI_float4x4.hh" #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_rand.h" #include "BLI_span.hh" #include "BLI_vector.hh" diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.hh b/source/blender/blenkernel/intern/pbvh_uv_islands.hh index 7774c43609c..a1a0bd5da0d 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.hh +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.hh @@ -27,7 +27,7 @@ #include "BLI_float3x3.hh" #include "BLI_map.hh" #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_rect.h" #include "BLI_vector.hh" #include "BLI_vector_list.hh" diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc index f399becfa89..14719c83ee9 100644 --- a/source/blender/blenkernel/intern/simulation.cc +++ b/source/blender/blenkernel/intern/simulation.cc @@ -16,7 +16,7 @@ #include "BLI_compiler_compat.h" #include "BLI_listbase.h" #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_rand.h" #include "BLI_span.hh" #include "BLI_string.h" diff --git a/source/blender/blenkernel/intern/tracking_test.cc b/source/blender/blenkernel/intern/tracking_test.cc index 42bbf23ea44..67e31a0a2ff 100644 --- a/source/blender/blenkernel/intern/tracking_test.cc +++ b/source/blender/blenkernel/intern/tracking_test.cc @@ -5,8 +5,8 @@ #include "DNA_tracking_types.h" #include "BKE_tracking.h" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.h" +#include "BLI_math_vector_types.hh" namespace blender { diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index b768ad07aa0..04501e3fe4a 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -19,7 +19,7 @@ #include "BLI_index_range.hh" #include "BLI_map.hh" #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_path_util.h" #include "BLI_string.h" #include "BLI_string_ref.hh" diff --git a/source/blender/blenkernel/intern/volume_render.cc b/source/blender/blenkernel/intern/volume_render.cc index 700bd63c9d4..29fdafdadb4 100644 --- a/source/blender/blenkernel/intern/volume_render.cc +++ b/source/blender/blenkernel/intern/volume_render.cc @@ -8,8 +8,8 @@ #include "BLI_array.hh" #include "BLI_math_matrix.h" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.h" +#include "BLI_math_vector_types.hh" #include "BLI_vector.hh" #include "DNA_volume_types.h" diff --git a/source/blender/blenkernel/intern/volume_to_mesh.cc b/source/blender/blenkernel/intern/volume_to_mesh.cc index f3bb8726b4f..61e288b9e3f 100644 --- a/source/blender/blenkernel/intern/volume_to_mesh.cc +++ b/source/blender/blenkernel/intern/volume_to_mesh.cc @@ -2,7 +2,7 @@ #include -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "BLI_utildefines.h" diff --git a/source/blender/blenlib/BLI_delaunay_2d.h b/source/blender/blenlib/BLI_delaunay_2d.h index 53c2ff1c345..009fe3e0e61 100644 --- a/source/blender/blenlib/BLI_delaunay_2d.h +++ b/source/blender/blenlib/BLI_delaunay_2d.h @@ -202,8 +202,8 @@ void BLI_delaunay_2d_cdt_free(CDT_result *result); # include "BLI_array.hh" # include "BLI_math_mpq.hh" -# include "BLI_math_vec_mpq_types.hh" -# include "BLI_math_vec_types.hh" +# include "BLI_math_vector_mpq_types.hh" +# include "BLI_math_vector_types.hh" # include "BLI_vector.hh" namespace blender::meshintersect { diff --git a/source/blender/blenlib/BLI_float3x3.hh b/source/blender/blenlib/BLI_float3x3.hh index 178973c155d..080ae1ce3f9 100644 --- a/source/blender/blenlib/BLI_float3x3.hh +++ b/source/blender/blenlib/BLI_float3x3.hh @@ -8,8 +8,8 @@ #include "BLI_assert.h" #include "BLI_math_base.h" #include "BLI_math_matrix.h" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.h" +#include "BLI_math_vector_types.hh" namespace blender { diff --git a/source/blender/blenlib/BLI_float4x4.hh b/source/blender/blenlib/BLI_float4x4.hh index ca0d9ea0028..3ac83d91e03 100644 --- a/source/blender/blenlib/BLI_float4x4.hh +++ b/source/blender/blenlib/BLI_float4x4.hh @@ -3,9 +3,9 @@ #pragma once #include "BLI_math_matrix.h" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.h" #include "BLI_math_vector.hh" +#include "BLI_math_vector_types.hh" namespace blender { diff --git a/source/blender/blenlib/BLI_math_boolean.hh b/source/blender/blenlib/BLI_math_boolean.hh index df03e63c416..43e98d5a96f 100644 --- a/source/blender/blenlib/BLI_math_boolean.hh +++ b/source/blender/blenlib/BLI_math_boolean.hh @@ -7,11 +7,11 @@ * \brief Math vector functions needed specifically for mesh intersect and boolean. */ -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #ifdef WITH_GMP # include "BLI_math_mpq.hh" -# include "BLI_math_vec_mpq_types.hh" +# include "BLI_math_vector_mpq_types.hh" #endif namespace blender { diff --git a/source/blender/blenlib/BLI_math_matrix_types.hh b/source/blender/blenlib/BLI_math_matrix_types.hh index cfb491734f3..dee5cdb2ac2 100644 --- a/source/blender/blenlib/BLI_math_matrix_types.hh +++ b/source/blender/blenlib/BLI_math_matrix_types.hh @@ -35,7 +35,7 @@ #include #include -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_utildefines.h" #include "BLI_utility_mixins.hh" diff --git a/source/blender/blenlib/BLI_math_rotation_legacy.hh b/source/blender/blenlib/BLI_math_rotation_legacy.hh index 50a062162ad..876da97fba7 100644 --- a/source/blender/blenlib/BLI_math_rotation_legacy.hh +++ b/source/blender/blenlib/BLI_math_rotation_legacy.hh @@ -6,7 +6,7 @@ * \ingroup bli */ -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" namespace blender::math { diff --git a/source/blender/blenlib/BLI_math_rotation_types.hh b/source/blender/blenlib/BLI_math_rotation_types.hh index 1689789db4b..c88c21d1650 100644 --- a/source/blender/blenlib/BLI_math_rotation_types.hh +++ b/source/blender/blenlib/BLI_math_rotation_types.hh @@ -7,7 +7,7 @@ */ #include "BLI_math_base.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" namespace blender::math { diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index 0c1edb3f0df..48223971359 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -11,7 +11,7 @@ #include #include "BLI_math_base.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "BLI_utildefines.h" diff --git a/source/blender/blenlib/BLI_math_vec_mpq_types.hh b/source/blender/blenlib/BLI_math_vector_mpq_types.hh similarity index 100% rename from source/blender/blenlib/BLI_math_vec_mpq_types.hh rename to source/blender/blenlib/BLI_math_vector_mpq_types.hh diff --git a/source/blender/blenlib/BLI_math_vec_types.hh b/source/blender/blenlib/BLI_math_vector_types.hh similarity index 100% rename from source/blender/blenlib/BLI_math_vec_types.hh rename to source/blender/blenlib/BLI_math_vector_types.hh diff --git a/source/blender/blenlib/BLI_mesh_intersect.hh b/source/blender/blenlib/BLI_mesh_intersect.hh index 4ed1fe5f513..7333700f79b 100644 --- a/source/blender/blenlib/BLI_mesh_intersect.hh +++ b/source/blender/blenlib/BLI_mesh_intersect.hh @@ -17,8 +17,8 @@ # include "BLI_index_range.hh" # include "BLI_map.hh" # include "BLI_math_mpq.hh" -# include "BLI_math_vec_mpq_types.hh" -# include "BLI_math_vec_types.hh" +# include "BLI_math_vector_mpq_types.hh" +# include "BLI_math_vector_types.hh" # include "BLI_span.hh" # include "BLI_utility_mixins.hh" # include "BLI_vector.hh" diff --git a/source/blender/blenlib/BLI_noise.hh b/source/blender/blenlib/BLI_noise.hh index d9a947c2d2f..eae7b1fd346 100644 --- a/source/blender/blenlib/BLI_noise.hh +++ b/source/blender/blenlib/BLI_noise.hh @@ -2,7 +2,7 @@ #pragma once -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" namespace blender::noise { diff --git a/source/blender/blenlib/BLI_rand.hh b/source/blender/blenlib/BLI_rand.hh index e4f35bef217..a0261333583 100644 --- a/source/blender/blenlib/BLI_rand.hh +++ b/source/blender/blenlib/BLI_rand.hh @@ -7,7 +7,7 @@ #pragma once #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "BLI_utildefines.h" diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index c554c19763b..5ea563c1736 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -278,8 +278,8 @@ set(SRC BLI_math_solvers.h BLI_math_statistics.h BLI_math_time.h - BLI_math_vec_mpq_types.hh - BLI_math_vec_types.hh + BLI_math_vector_mpq_types.hh + BLI_math_vector_types.hh BLI_math_vector.h BLI_math_vector.hh BLI_memarena.h @@ -492,7 +492,7 @@ if(WITH_GTESTS) tests/BLI_math_rotation_test.cc tests/BLI_math_solvers_test.cc tests/BLI_math_time_test.cc - tests/BLI_math_vec_types_test.cc + tests/BLI_math_vector_types_test.cc tests/BLI_math_vector_test.cc tests/BLI_memiter_test.cc tests/BLI_memory_utils_test.cc diff --git a/source/blender/blenlib/intern/cpp_types.cc b/source/blender/blenlib/intern/cpp_types.cc index eb8f03d942f..e634b9b20a8 100644 --- a/source/blender/blenlib/intern/cpp_types.cc +++ b/source/blender/blenlib/intern/cpp_types.cc @@ -4,7 +4,7 @@ #include "BLI_cpp_type_make.hh" #include "BLI_cpp_types_make.hh" #include "BLI_float4x4.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" namespace blender { diff --git a/source/blender/blenlib/intern/delaunay_2d.cc b/source/blender/blenlib/intern/delaunay_2d.cc index afecf9ea838..43ccf9305a7 100644 --- a/source/blender/blenlib/intern/delaunay_2d.cc +++ b/source/blender/blenlib/intern/delaunay_2d.cc @@ -14,7 +14,7 @@ #include "BLI_linklist.h" #include "BLI_math_boolean.hh" #include "BLI_math_mpq.hh" -#include "BLI_math_vec_mpq_types.hh" +#include "BLI_math_vector_mpq_types.hh" #include "BLI_set.hh" #include "BLI_task.hh" #include "BLI_vector.hh" diff --git a/source/blender/blenlib/intern/math_boolean.cc b/source/blender/blenlib/intern/math_boolean.cc index e5352540dd6..977b4ca5365 100644 --- a/source/blender/blenlib/intern/math_boolean.cc +++ b/source/blender/blenlib/intern/math_boolean.cc @@ -7,7 +7,7 @@ #include "BLI_hash.hh" #include "BLI_math_boolean.hh" #include "BLI_math_mpq.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "BLI_utildefines.h" diff --git a/source/blender/blenlib/intern/math_vec.cc b/source/blender/blenlib/intern/math_vec.cc index 8d1f850d8e5..fcc726316bb 100644 --- a/source/blender/blenlib/intern/math_vec.cc +++ b/source/blender/blenlib/intern/math_vec.cc @@ -5,8 +5,8 @@ */ #include "BLI_hash.hh" -#include "BLI_math_vec_mpq_types.hh" #include "BLI_math_vector.hh" +#include "BLI_math_vector_mpq_types.hh" #include "BLI_span.hh" #include "BLI_utildefines.h" diff --git a/source/blender/blenlib/intern/mesh_boolean.cc b/source/blender/blenlib/intern/mesh_boolean.cc index 3efe62d2984..354f241a292 100644 --- a/source/blender/blenlib/intern/mesh_boolean.cc +++ b/source/blender/blenlib/intern/mesh_boolean.cc @@ -21,8 +21,8 @@ # include "BLI_math_boolean.hh" # include "BLI_math_geom.h" # include "BLI_math_mpq.hh" -# include "BLI_math_vec_mpq_types.hh" # include "BLI_math_vector.hh" +# include "BLI_math_vector_mpq_types.hh" # include "BLI_mesh_intersect.hh" # include "BLI_set.hh" # include "BLI_span.hh" diff --git a/source/blender/blenlib/intern/mesh_intersect.cc b/source/blender/blenlib/intern/mesh_intersect.cc index ee29662698a..8dcb513cb9f 100644 --- a/source/blender/blenlib/intern/mesh_intersect.cc +++ b/source/blender/blenlib/intern/mesh_intersect.cc @@ -21,9 +21,9 @@ # include "BLI_map.hh" # include "BLI_math_boolean.hh" # include "BLI_math_mpq.hh" -# include "BLI_math_vec_mpq_types.hh" -# include "BLI_math_vec_types.hh" # include "BLI_math_vector.h" +# include "BLI_math_vector_mpq_types.hh" +# include "BLI_math_vector_types.hh" # include "BLI_polyfill_2d.h" # include "BLI_set.hh" # include "BLI_sort.hh" diff --git a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc index ca99c678754..5fbb063463b 100644 --- a/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc +++ b/source/blender/blenlib/tests/BLI_delaunay_2d_test.cc @@ -23,7 +23,7 @@ extern "C" { #include "BLI_array.hh" #include "BLI_math_boolean.hh" #include "BLI_math_mpq.hh" -#include "BLI_math_vec_mpq_types.hh" +#include "BLI_math_vector_mpq_types.hh" #include "BLI_vector.hh" #include "BLI_delaunay_2d.h" diff --git a/source/blender/blenlib/tests/BLI_float3x3_test.cc b/source/blender/blenlib/tests/BLI_float3x3_test.cc index cd823b6e368..8cfcb99cc6d 100644 --- a/source/blender/blenlib/tests/BLI_float3x3_test.cc +++ b/source/blender/blenlib/tests/BLI_float3x3_test.cc @@ -4,7 +4,7 @@ #include "BLI_float3x3.hh" #include "BLI_math_base.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" namespace blender::tests { diff --git a/source/blender/blenlib/tests/BLI_math_vec_types_test.cc b/source/blender/blenlib/tests/BLI_math_vector_types_test.cc similarity index 99% rename from source/blender/blenlib/tests/BLI_math_vec_types_test.cc rename to source/blender/blenlib/tests/BLI_math_vector_types_test.cc index 7a3bd0002e1..2a5884fb282 100644 --- a/source/blender/blenlib/tests/BLI_math_vec_types_test.cc +++ b/source/blender/blenlib/tests/BLI_math_vector_types_test.cc @@ -2,7 +2,7 @@ #include "testing/testing.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" namespace blender::tests { diff --git a/source/blender/blenlib/tests/BLI_memory_utils_test.cc b/source/blender/blenlib/tests/BLI_memory_utils_test.cc index 3596de5c179..6d8b02220de 100644 --- a/source/blender/blenlib/tests/BLI_memory_utils_test.cc +++ b/source/blender/blenlib/tests/BLI_memory_utils_test.cc @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: Apache-2.0 */ -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_memory_utils.hh" #include "BLI_strict_flags.h" #include "testing/testing.h" diff --git a/source/blender/blenlib/tests/BLI_mesh_boolean_test.cc b/source/blender/blenlib/tests/BLI_mesh_boolean_test.cc index ea324534d78..bd917e6eb92 100644 --- a/source/blender/blenlib/tests/BLI_mesh_boolean_test.cc +++ b/source/blender/blenlib/tests/BLI_mesh_boolean_test.cc @@ -11,7 +11,7 @@ #include "BLI_array.hh" #include "BLI_map.hh" #include "BLI_math_mpq.hh" -#include "BLI_math_vec_mpq_types.hh" +#include "BLI_math_vector_mpq_types.hh" #include "BLI_mesh_boolean.hh" #include "BLI_vector.hh" diff --git a/source/blender/blenlib/tests/BLI_mesh_intersect_test.cc b/source/blender/blenlib/tests/BLI_mesh_intersect_test.cc index 67a5771593a..afe70c85200 100644 --- a/source/blender/blenlib/tests/BLI_mesh_intersect_test.cc +++ b/source/blender/blenlib/tests/BLI_mesh_intersect_test.cc @@ -10,7 +10,7 @@ #include "BLI_array.hh" #include "BLI_math_mpq.hh" -#include "BLI_math_vec_mpq_types.hh" +#include "BLI_math_vector_mpq_types.hh" #include "BLI_mesh_intersect.hh" #include "BLI_task.h" #include "BLI_vector.hh" diff --git a/source/blender/blenloader/intern/versioning_defaults.cc b/source/blender/blenloader/intern/versioning_defaults.cc index cfa2d01697f..51547a41316 100644 --- a/source/blender/blenloader/intern/versioning_defaults.cc +++ b/source/blender/blenloader/intern/versioning_defaults.cc @@ -15,7 +15,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_string.h" #include "BLI_system.h" #include "BLI_utildefines.h" diff --git a/source/blender/bmesh/intern/bmesh_query_uv.cc b/source/blender/bmesh/intern/bmesh_query_uv.cc index 0e2385ff4e2..44e49bc8491 100644 --- a/source/blender/bmesh/intern/bmesh_query_uv.cc +++ b/source/blender/bmesh/intern/bmesh_query_uv.cc @@ -9,7 +9,7 @@ #include "BLI_array.hh" #include "BLI_linklist.h" #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_utildefines_stack.h" #include "BKE_customdata.h" diff --git a/source/blender/compositor/COM_defines.h b/source/blender/compositor/COM_defines.h index 32f097a4dc5..c32d730f51a 100644 --- a/source/blender/compositor/COM_defines.h +++ b/source/blender/compositor/COM_defines.h @@ -3,7 +3,7 @@ #pragma once -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "DNA_vec_types.h" diff --git a/source/blender/compositor/realtime_compositor/COM_context.hh b/source/blender/compositor/realtime_compositor/COM_context.hh index 7be89bfeb0e..99eac679640 100644 --- a/source/blender/compositor/realtime_compositor/COM_context.hh +++ b/source/blender/compositor/realtime_compositor/COM_context.hh @@ -2,7 +2,7 @@ #pragma once -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_string_ref.hh" #include "DNA_scene_types.h" diff --git a/source/blender/compositor/realtime_compositor/COM_domain.hh b/source/blender/compositor/realtime_compositor/COM_domain.hh index 0e975afb1e2..997b7aea16e 100644 --- a/source/blender/compositor/realtime_compositor/COM_domain.hh +++ b/source/blender/compositor/realtime_compositor/COM_domain.hh @@ -5,7 +5,7 @@ #include #include "BLI_float3x3.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" namespace blender::realtime_compositor { diff --git a/source/blender/compositor/realtime_compositor/COM_result.hh b/source/blender/compositor/realtime_compositor/COM_result.hh index 3f8378bc4c2..aba79ad5890 100644 --- a/source/blender/compositor/realtime_compositor/COM_result.hh +++ b/source/blender/compositor/realtime_compositor/COM_result.hh @@ -3,7 +3,7 @@ #pragma once #include "BLI_float3x3.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "GPU_shader.h" #include "GPU_texture.h" diff --git a/source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh b/source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh index 20fbb156879..a09e84edcf3 100644 --- a/source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh +++ b/source/blender/compositor/realtime_compositor/COM_static_cache_manager.hh @@ -5,7 +5,7 @@ #include #include "BLI_map.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "COM_morphological_distance_feather_weights.hh" #include "COM_symmetric_blur_weights.hh" diff --git a/source/blender/compositor/realtime_compositor/COM_texture_pool.hh b/source/blender/compositor/realtime_compositor/COM_texture_pool.hh index c68219b0279..9a7654cb3f4 100644 --- a/source/blender/compositor/realtime_compositor/COM_texture_pool.hh +++ b/source/blender/compositor/realtime_compositor/COM_texture_pool.hh @@ -5,7 +5,7 @@ #include #include "BLI_map.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_vector.hh" #include "GPU_texture.h" diff --git a/source/blender/compositor/realtime_compositor/COM_utilities.hh b/source/blender/compositor/realtime_compositor/COM_utilities.hh index efd1bc2b6b0..5146dcf65cb 100644 --- a/source/blender/compositor/realtime_compositor/COM_utilities.hh +++ b/source/blender/compositor/realtime_compositor/COM_utilities.hh @@ -3,7 +3,7 @@ #pragma once #include "BLI_function_ref.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "NOD_derived_node_tree.hh" diff --git a/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh b/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh index f6d479f9bbe..d46684c7ca2 100644 --- a/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh +++ b/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_parallel_reduction.hh @@ -2,7 +2,7 @@ #pragma once -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "GPU_texture.h" diff --git a/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_symmetric_separable_blur.hh b/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_symmetric_separable_blur.hh index 317ce2ab522..de709002b76 100644 --- a/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_symmetric_separable_blur.hh +++ b/source/blender/compositor/realtime_compositor/algorithms/COM_algorithm_symmetric_separable_blur.hh @@ -2,7 +2,7 @@ #pragma once -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "COM_context.hh" #include "COM_result.hh" diff --git a/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc b/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc index 9672431992d..ba0e7eb21ac 100644 --- a/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc +++ b/source/blender/compositor/realtime_compositor/algorithms/intern/algorithm_parallel_reduction.cc @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.hh" +#include "BLI_math_vector_types.hh" #include "MEM_guardedalloc.h" diff --git a/source/blender/compositor/realtime_compositor/algorithms/intern/symmetric_separable_blur.cc b/source/blender/compositor/realtime_compositor/algorithms/intern/symmetric_separable_blur.cc index e450abdc203..e848d1475e4 100644 --- a/source/blender/compositor/realtime_compositor/algorithms/intern/symmetric_separable_blur.cc +++ b/source/blender/compositor/realtime_compositor/algorithms/intern/symmetric_separable_blur.cc @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "BLI_math_base.hh" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.hh" +#include "BLI_math_vector_types.hh" #include "GPU_shader.h" #include "GPU_texture.h" diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh index 05d3c7c6f3e..d51318ec836 100644 --- a/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh +++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_blur_weights.hh @@ -4,7 +4,7 @@ #include -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "GPU_shader.h" #include "GPU_texture.h" diff --git a/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh index 85e75e4535d..d53cce2995b 100644 --- a/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh +++ b/source/blender/compositor/realtime_compositor/cached_resources/COM_symmetric_separable_blur_weights.hh @@ -4,7 +4,7 @@ #include -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "GPU_shader.h" #include "GPU_texture.h" diff --git a/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc index a22d32a8e18..b3200d468c9 100644 --- a/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc +++ b/source/blender/compositor/realtime_compositor/cached_resources/intern/symmetric_blur_weights.cc @@ -5,8 +5,8 @@ #include "BLI_array.hh" #include "BLI_hash.hh" #include "BLI_index_range.hh" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.hh" +#include "BLI_math_vector_types.hh" #include "RE_pipeline.h" diff --git a/source/blender/compositor/realtime_compositor/intern/compile_state.cc b/source/blender/compositor/realtime_compositor/intern/compile_state.cc index 5fa2fc9d544..2708668d502 100644 --- a/source/blender/compositor/realtime_compositor/intern/compile_state.cc +++ b/source/blender/compositor/realtime_compositor/intern/compile_state.cc @@ -2,7 +2,7 @@ #include -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "DNA_node_types.h" diff --git a/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc b/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc index dd585aedec6..6b6b14c8b2c 100644 --- a/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc +++ b/source/blender/compositor/realtime_compositor/intern/conversion_operation.cc @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "GPU_shader.h" diff --git a/source/blender/compositor/realtime_compositor/intern/domain.cc b/source/blender/compositor/realtime_compositor/intern/domain.cc index 489e73d74ce..51307ec14d3 100644 --- a/source/blender/compositor/realtime_compositor/intern/domain.cc +++ b/source/blender/compositor/realtime_compositor/intern/domain.cc @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "BLI_float3x3.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "COM_domain.hh" diff --git a/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc b/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc index 99f7cd90557..75e45356999 100644 --- a/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc +++ b/source/blender/compositor/realtime_compositor/intern/input_single_value_operation.cc @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "COM_input_single_value_operation.hh" #include "COM_operation.hh" diff --git a/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc b/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc index e5c448d0e33..059687bed81 100644 --- a/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc +++ b/source/blender/compositor/realtime_compositor/intern/realize_on_domain_operation.cc @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "BLI_float3x3.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_utildefines.h" #include "GPU_shader.h" diff --git a/source/blender/compositor/realtime_compositor/intern/result.cc b/source/blender/compositor/realtime_compositor/intern/result.cc index 3e0b11cc941..ef33e4bee21 100644 --- a/source/blender/compositor/realtime_compositor/intern/result.cc +++ b/source/blender/compositor/realtime_compositor/intern/result.cc @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "BLI_float3x3.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "GPU_shader.h" #include "GPU_state.h" diff --git a/source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc b/source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc index da78412a815..83d28df04a2 100644 --- a/source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc +++ b/source/blender/compositor/realtime_compositor/intern/static_cache_manager.cc @@ -2,7 +2,7 @@ #include -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "COM_morphological_distance_feather_weights.hh" #include "COM_symmetric_blur_weights.hh" diff --git a/source/blender/compositor/realtime_compositor/intern/texture_pool.cc b/source/blender/compositor/realtime_compositor/intern/texture_pool.cc index 4b476574d72..da9bb478064 100644 --- a/source/blender/compositor/realtime_compositor/intern/texture_pool.cc +++ b/source/blender/compositor/realtime_compositor/intern/texture_pool.cc @@ -4,7 +4,7 @@ #include "BLI_hash.hh" #include "BLI_map.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_vector.hh" #include "GPU_texture.h" diff --git a/source/blender/compositor/realtime_compositor/intern/utilities.cc b/source/blender/compositor/realtime_compositor/intern/utilities.cc index 711402ad97f..f9b06854882 100644 --- a/source/blender/compositor/realtime_compositor/intern/utilities.cc +++ b/source/blender/compositor/realtime_compositor/intern/utilities.cc @@ -2,8 +2,8 @@ #include "BLI_assert.h" #include "BLI_function_ref.hh" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.hh" +#include "BLI_math_vector_types.hh" #include "BLI_utildefines.h" #include "DNA_node_types.h" diff --git a/source/blender/draw/engines/compositor/compositor_engine.cc b/source/blender/draw/engines/compositor/compositor_engine.cc index 06e599e77b1..54a64a7dd00 100644 --- a/source/blender/draw/engines/compositor/compositor_engine.cc +++ b/source/blender/draw/engines/compositor/compositor_engine.cc @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "BLI_listbase.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_rect.h" #include "BLI_string_ref.hh" #include "BLI_utildefines.h" diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh index 6d1b0e8918c..9345be800e8 100644 --- a/source/blender/draw/engines/image/image_drawing_mode.hh +++ b/source/blender/draw/engines/image/image_drawing_mode.hh @@ -12,7 +12,7 @@ #include "IMB_imbuf_types.h" #include "BLI_float4x4.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "image_batches.hh" #include "image_private.hh" diff --git a/source/blender/draw/engines/image/image_texture_info.hh b/source/blender/draw/engines/image/image_texture_info.hh index 1a6bb40068c..ed26b330383 100644 --- a/source/blender/draw/engines/image/image_texture_info.hh +++ b/source/blender/draw/engines/image/image_texture_info.hh @@ -7,7 +7,7 @@ #pragma once -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_rect.h" #include "GPU_batch.h" diff --git a/source/blender/draw/intern/DRW_gpu_wrapper.hh b/source/blender/draw/intern/DRW_gpu_wrapper.hh index e560541250b..5f11beecc15 100644 --- a/source/blender/draw/intern/DRW_gpu_wrapper.hh +++ b/source/blender/draw/intern/DRW_gpu_wrapper.hh @@ -63,7 +63,7 @@ #include "draw_manager.h" #include "draw_texture_pool.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "BLI_utildefines.h" #include "BLI_utility_mixins.hh" diff --git a/source/blender/draw/intern/draw_cache_impl_curve.cc b/source/blender/draw/intern/draw_cache_impl_curve.cc index 6188b1e0544..3e2fab001f7 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.cc +++ b/source/blender/draw/intern/draw_cache_impl_curve.cc @@ -12,8 +12,8 @@ #include "BLI_array.hh" #include "BLI_color.hh" #include "BLI_listbase.h" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.h" +#include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "BLI_utildefines.h" diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index 4fb25113f57..c7d7a6f61ea 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -14,8 +14,8 @@ #include "BLI_devirtualize_parameters.hh" #include "BLI_listbase.h" #include "BLI_math_base.h" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.hh" +#include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "BLI_task.hh" #include "BLI_utildefines.h" diff --git a/source/blender/draw/intern/draw_cache_impl_gpencil.cc b/source/blender/draw/intern/draw_cache_impl_gpencil.cc index a877f43561a..c51d408ea9c 100644 --- a/source/blender/draw/intern/draw_cache_impl_gpencil.cc +++ b/source/blender/draw/intern/draw_cache_impl_gpencil.cc @@ -23,7 +23,7 @@ #include "DEG_depsgraph_query.h" #include "BLI_hash.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_polyfill_2d.h" #include "draw_cache.h" diff --git a/source/blender/draw/intern/draw_debug.hh b/source/blender/draw/intern/draw_debug.hh index c83936bf1af..3b30352ccd2 100644 --- a/source/blender/draw/intern/draw_debug.hh +++ b/source/blender/draw/intern/draw_debug.hh @@ -14,7 +14,7 @@ #pragma once -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_string_ref.hh" #include "BLI_vector.hh" #include "DNA_object_types.h" diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index 8ba827b266c..2d6fdb96598 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -23,7 +23,7 @@ #include "BLI_index_range.hh" #include "BLI_map.hh" #include "BLI_math_color.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_string_ref.hh" #include "BLI_timeit.hh" #include "BLI_utildefines.h" diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc index 14f878c7ce2..21201593d0c 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc @@ -10,7 +10,7 @@ #include #include "BLI_color.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_string.h" #include "BKE_attribute.h" diff --git a/source/blender/editors/interface/interface_template_search_operator.cc b/source/blender/editors/interface/interface_template_search_operator.cc index c31b35c5a9a..3e28461e0f6 100644 --- a/source/blender/editors/interface/interface_template_search_operator.cc +++ b/source/blender/editors/interface/interface_template_search_operator.cc @@ -15,7 +15,7 @@ #include "BLI_array.hh" #include "BLI_ghash.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_string.h" #include "BLI_utildefines.h" diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.cc b/source/blender/editors/sculpt_paint/sculpt_automasking.cc index cdb12588401..67c3e4bfd74 100644 --- a/source/blender/editors/sculpt_paint/sculpt_automasking.cc +++ b/source/blender/editors/sculpt_paint/sculpt_automasking.cc @@ -12,7 +12,7 @@ #include "BLI_hash.h" #include "BLI_index_range.hh" #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_set.hh" #include "BLI_task.h" #include "BLI_vector.hh" diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc index 7666502b447..d89600cca0b 100644 --- a/source/blender/editors/space_node/node_group.cc +++ b/source/blender/editors/space_node/node_group.cc @@ -15,7 +15,7 @@ #include "BLI_linklist.h" #include "BLI_listbase.h" #include "BLI_map.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_set.hh" #include "BLI_string.h" #include "BLI_vector.hh" diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column.cc b/source/blender/editors/space_spreadsheet/spreadsheet_column.cc index af41225f42a..078fa3c1c02 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_column.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_column.cc @@ -7,7 +7,7 @@ #include "BLI_color.hh" #include "BLI_cpp_type.hh" #include "BLI_hash.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_string.h" #include "BLI_string_ref.hh" diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc index 06eb338bd00..2f5ff624540 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_layout.cc @@ -3,7 +3,7 @@ #include #include -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BKE_geometry_set.hh" #include "BKE_instances.hh" diff --git a/source/blender/functions/intern/cpp_types.cc b/source/blender/functions/intern/cpp_types.cc index 098e7030de4..51e51d48f73 100644 --- a/source/blender/functions/intern/cpp_types.cc +++ b/source/blender/functions/intern/cpp_types.cc @@ -4,7 +4,7 @@ #include "BLI_cpp_type_make.hh" #include "BLI_cpp_types_make.hh" #include "BLI_float4x4.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "FN_field_cpp_type_make.hh" #include "FN_init.h" diff --git a/source/blender/geometry/GEO_mesh_primitive_cuboid.hh b/source/blender/geometry/GEO_mesh_primitive_cuboid.hh index 6107b15b62d..f58fa534045 100644 --- a/source/blender/geometry/GEO_mesh_primitive_cuboid.hh +++ b/source/blender/geometry/GEO_mesh_primitive_cuboid.hh @@ -2,7 +2,7 @@ #pragma once -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" struct Mesh; namespace blender { diff --git a/source/blender/gpu/GPU_shader_shared_utils.h b/source/blender/gpu/GPU_shader_shared_utils.h index 96feed9e7d9..9c92da425f6 100644 --- a/source/blender/gpu/GPU_shader_shared_utils.h +++ b/source/blender/gpu/GPU_shader_shared_utils.h @@ -68,7 +68,7 @@ # ifdef __cplusplus # include "BLI_float4x4.hh" -# include "BLI_math_vec_types.hh" +# include "BLI_math_vector_types.hh" using blender::float2; using blender::float3; using blender::float4; diff --git a/source/blender/io/collada/MeshImporter.h b/source/blender/io/collada/MeshImporter.h index a59b24d4f24..faccbe5c055 100644 --- a/source/blender/io/collada/MeshImporter.h +++ b/source/blender/io/collada/MeshImporter.h @@ -24,7 +24,7 @@ #include "collada_utils.h" #include "BLI_edgehash.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "DNA_material_types.h" #include "DNA_mesh_types.h" diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.cc b/source/blender/io/gpencil/intern/gpencil_io_base.cc index 6cc977bfced..de97d8033b9 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_base.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_base.cc @@ -6,7 +6,7 @@ */ #include "BLI_float4x4.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_path_util.h" #include "BLI_span.hh" diff --git a/source/blender/io/gpencil/intern/gpencil_io_base.hh b/source/blender/io/gpencil/intern/gpencil_io_base.hh index f712ed839d9..c063729b634 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_base.hh +++ b/source/blender/io/gpencil/intern/gpencil_io_base.hh @@ -7,7 +7,7 @@ */ #include "BLI_float4x4.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_vector.hh" #include "DNA_space_types.h" /* for FILE_MAX */ diff --git a/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc index 23c80900659..e18f4df9c52 100644 --- a/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc +++ b/source/blender/io/gpencil/intern/gpencil_io_import_svg.cc @@ -6,7 +6,7 @@ */ #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "DNA_gpencil_types.h" diff --git a/source/blender/io/stl/importer/stl_import_mesh.hh b/source/blender/io/stl/importer/stl_import_mesh.hh index f1c0d2126a9..658d42ca7a7 100644 --- a/source/blender/io/stl/importer/stl_import_mesh.hh +++ b/source/blender/io/stl/importer/stl_import_mesh.hh @@ -8,7 +8,7 @@ #include -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_set.hh" #include "BLI_vector.hh" #include "BLI_vector_set.hh" diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index 52cd3b32b49..4b31f8cf661 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -15,7 +15,7 @@ #include "BLI_math.h" #include "BLI_math_geom.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "BLI_string.h" diff --git a/source/blender/io/usd/intern/usd_writer_volume.h b/source/blender/io/usd/intern/usd_writer_volume.h index 8c1e36b7e53..6a0a4c27202 100644 --- a/source/blender/io/usd/intern/usd_writer_volume.h +++ b/source/blender/io/usd/intern/usd_writer_volume.h @@ -3,7 +3,7 @@ #include -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "usd_writer_abstract.h" struct Volume; diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh index 9869469e616..6ee2a3fccd8 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh @@ -8,7 +8,7 @@ #include -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_utility_mixins.hh" #include "BLI_vector.hh" diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh index 2d4edd8979d..29088214b81 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh @@ -6,7 +6,7 @@ #pragma once -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "DNA_node_types.h" struct Material; diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc index 1b1ee5f8386..707b370601d 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_nurbs.cc @@ -6,7 +6,7 @@ #include "BLI_listbase.h" #include "BLI_math.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" diff --git a/source/blender/io/wavefront_obj/importer/importer_mesh_utils.hh b/source/blender/io/wavefront_obj/importer/importer_mesh_utils.hh index ce47da3e863..9b69d3914a6 100644 --- a/source/blender/io/wavefront_obj/importer/importer_mesh_utils.hh +++ b/source/blender/io/wavefront_obj/importer/importer_mesh_utils.hh @@ -6,7 +6,7 @@ #pragma once -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_span.hh" #include "BLI_vector.hh" diff --git a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh index 91f09d9e188..102a92d87f9 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_objects.hh +++ b/source/blender/io/wavefront_obj/importer/obj_import_objects.hh @@ -10,7 +10,7 @@ #include "BLI_map.hh" #include "BLI_math_base.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_set.hh" #include "BLI_vector.hh" diff --git a/source/blender/io/wavefront_obj/importer/obj_importer.cc b/source/blender/io/wavefront_obj/importer/obj_importer.cc index a42ec47151d..b5b2826fd25 100644 --- a/source/blender/io/wavefront_obj/importer/obj_importer.cc +++ b/source/blender/io/wavefront_obj/importer/obj_importer.cc @@ -7,7 +7,7 @@ #include #include "BLI_map.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_set.hh" #include "BLI_sort.hh" #include "BLI_string_ref.hh" diff --git a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc index f459e1ab1bd..225643c0682 100644 --- a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc @@ -15,7 +15,7 @@ #include "BLI_listbase.h" #include "BLI_math_base.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLO_readfile.h" diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 5e04c23445d..bea937d7d42 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -16,7 +16,7 @@ /** Workaround to forward-declare C++ type in C header. */ #ifdef __cplusplus -# include "BLI_math_vec_types.hh" +# include "BLI_math_vector_types.hh" namespace blender { template class Span; diff --git a/source/blender/makesdna/DNA_pointcloud_types.h b/source/blender/makesdna/DNA_pointcloud_types.h index 438dcf63d0d..7095e2fe278 100644 --- a/source/blender/makesdna/DNA_pointcloud_types.h +++ b/source/blender/makesdna/DNA_pointcloud_types.h @@ -10,7 +10,7 @@ #include "DNA_customdata_types.h" #ifdef __cplusplus -# include "BLI_math_vec_types.hh" +# include "BLI_math_vector_types.hh" #endif #ifdef __cplusplus diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 93b61ad76ab..af95ad6db18 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -13,7 +13,7 @@ #include "BLI_array.hh" #include "BLI_listbase.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_multi_value_map.hh" #include "BLI_set.hh" #include "BLI_string.h" diff --git a/source/blender/nodes/NOD_socket_declarations.hh b/source/blender/nodes/NOD_socket_declarations.hh index 65ca350a479..9ddbacdad0c 100644 --- a/source/blender/nodes/NOD_socket_declarations.hh +++ b/source/blender/nodes/NOD_socket_declarations.hh @@ -7,7 +7,7 @@ #include "RNA_types.h" #include "BLI_color.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" namespace blender::nodes::decl { diff --git a/source/blender/nodes/composite/nodes/node_composite_blur.cc b/source/blender/nodes/composite/nodes/node_composite_blur.cc index 147aa9d09ee..fa0b6de2e64 100644 --- a/source/blender/nodes/composite/nodes/node_composite_blur.cc +++ b/source/blender/nodes/composite/nodes/node_composite_blur.cc @@ -7,8 +7,8 @@ #include "BLI_assert.h" #include "BLI_math_base.hh" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.hh" +#include "BLI_math_vector_types.hh" #include "RNA_access.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_bokehblur.cc b/source/blender/nodes/composite/nodes/node_composite_bokehblur.cc index e35974e9d81..d98e60ce86c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_bokehblur.cc +++ b/source/blender/nodes/composite/nodes/node_composite_bokehblur.cc @@ -6,7 +6,7 @@ */ #include "BLI_math_base.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_bokehimage.cc b/source/blender/nodes/composite/nodes/node_composite_bokehimage.cc index 8b817d3a677..54ed9b56a9c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_bokehimage.cc +++ b/source/blender/nodes/composite/nodes/node_composite_bokehimage.cc @@ -6,7 +6,7 @@ */ #include "BLI_math_base.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_boxmask.cc b/source/blender/nodes/composite/nodes/node_composite_boxmask.cc index 1ff2b82f7bb..f4f2b69710d 100644 --- a/source/blender/nodes/composite/nodes/node_composite_boxmask.cc +++ b/source/blender/nodes/composite/nodes/node_composite_boxmask.cc @@ -7,7 +7,7 @@ #include -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_composite.cc b/source/blender/nodes/composite/nodes/node_composite_composite.cc index a7babeb28bd..70e4c2b5d3b 100644 --- a/source/blender/nodes/composite/nodes/node_composite_composite.cc +++ b/source/blender/nodes/composite/nodes/node_composite_composite.cc @@ -5,7 +5,7 @@ * \ingroup cmpnodes */ -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_crop.cc b/source/blender/nodes/composite/nodes/node_composite_crop.cc index 4539d2af92d..ec265163989 100644 --- a/source/blender/nodes/composite/nodes/node_composite_crop.cc +++ b/source/blender/nodes/composite/nodes/node_composite_crop.cc @@ -6,7 +6,7 @@ */ #include "BLI_math_base.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "DNA_node_types.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_dilate.cc b/source/blender/nodes/composite/nodes/node_composite_dilate.cc index cc4e09d4d0d..07063c1a06b 100644 --- a/source/blender/nodes/composite/nodes/node_composite_dilate.cc +++ b/source/blender/nodes/composite/nodes/node_composite_dilate.cc @@ -7,7 +7,7 @@ #include "BLI_assert.h" #include "BLI_math_base.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "RNA_access.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_directionalblur.cc b/source/blender/nodes/composite/nodes/node_composite_directionalblur.cc index 235194688de..56584bc8a3c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_directionalblur.cc +++ b/source/blender/nodes/composite/nodes/node_composite_directionalblur.cc @@ -7,8 +7,8 @@ #include "BLI_float3x3.hh" #include "BLI_math_base.hh" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.hh" +#include "BLI_math_vector_types.hh" #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc index 2b222eb17b1..bca4b3364a4 100644 --- a/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc +++ b/source/blender/nodes/composite/nodes/node_composite_ellipsemask.cc @@ -7,7 +7,7 @@ #include -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_glare.cc b/source/blender/nodes/composite/nodes/node_composite_glare.cc index 7209c13aa51..1fcbe44ae3e 100644 --- a/source/blender/nodes/composite/nodes/node_composite_glare.cc +++ b/source/blender/nodes/composite/nodes/node_composite_glare.cc @@ -11,7 +11,7 @@ #include "BLI_index_range.hh" #include "BLI_math_base.h" #include "BLI_math_base.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "DNA_scene_types.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_image.cc b/source/blender/nodes/composite/nodes/node_composite_image.cc index 98cd5834551..ad49d687220 100644 --- a/source/blender/nodes/composite/nodes/node_composite_image.cc +++ b/source/blender/nodes/composite/nodes/node_composite_image.cc @@ -8,7 +8,7 @@ #include "node_composite_util.hh" #include "BLI_linklist.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_rect.h" #include "BLI_utildefines.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_lensdist.cc b/source/blender/nodes/composite/nodes/node_composite_lensdist.cc index e11ed0fbfb6..fec0175785c 100644 --- a/source/blender/nodes/composite/nodes/node_composite_lensdist.cc +++ b/source/blender/nodes/composite/nodes/node_composite_lensdist.cc @@ -6,7 +6,7 @@ */ #include "BLI_math_base.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "RNA_access.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_levels.cc b/source/blender/nodes/composite/nodes/node_composite_levels.cc index 29212c7a76f..6969b631f29 100644 --- a/source/blender/nodes/composite/nodes/node_composite_levels.cc +++ b/source/blender/nodes/composite/nodes/node_composite_levels.cc @@ -8,8 +8,8 @@ #include #include "BLI_assert.h" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.hh" +#include "BLI_math_vector_types.hh" #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_movieclip.cc b/source/blender/nodes/composite/nodes/node_composite_movieclip.cc index b9d9620a214..c55df061873 100644 --- a/source/blender/nodes/composite/nodes/node_composite_movieclip.cc +++ b/source/blender/nodes/composite/nodes/node_composite_movieclip.cc @@ -5,7 +5,7 @@ * \ingroup cmpnodes */ -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BKE_context.h" #include "BKE_lib_id.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_pixelate.cc b/source/blender/nodes/composite/nodes/node_composite_pixelate.cc index c65bb7bb747..6dac0bc103a 100644 --- a/source/blender/nodes/composite/nodes/node_composite_pixelate.cc +++ b/source/blender/nodes/composite/nodes/node_composite_pixelate.cc @@ -5,8 +5,8 @@ * \ingroup cmpnodes */ -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.hh" +#include "BLI_math_vector_types.hh" #include "COM_node_operation.hh" diff --git a/source/blender/nodes/composite/nodes/node_composite_rgb.cc b/source/blender/nodes/composite/nodes/node_composite_rgb.cc index c4b5e12ea60..210508dc714 100644 --- a/source/blender/nodes/composite/nodes/node_composite_rgb.cc +++ b/source/blender/nodes/composite/nodes/node_composite_rgb.cc @@ -5,7 +5,7 @@ * \ingroup cmpnodes */ -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "DNA_node_types.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_scale.cc b/source/blender/nodes/composite/nodes/node_composite_scale.cc index a9c35e985a5..4cff57790d9 100644 --- a/source/blender/nodes/composite/nodes/node_composite_scale.cc +++ b/source/blender/nodes/composite/nodes/node_composite_scale.cc @@ -8,7 +8,7 @@ #include "BLI_assert.h" #include "BLI_float3x3.hh" #include "BLI_math_base.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "RNA_access.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_tonemap.cc b/source/blender/nodes/composite/nodes/node_composite_tonemap.cc index febbb9ddec5..6fe3bf4beba 100644 --- a/source/blender/nodes/composite/nodes/node_composite_tonemap.cc +++ b/source/blender/nodes/composite/nodes/node_composite_tonemap.cc @@ -9,8 +9,8 @@ #include "BLI_assert.h" #include "BLI_math_base.hh" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.hh" +#include "BLI_math_vector_types.hh" #include "RNA_access.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_trackpos.cc b/source/blender/nodes/composite/nodes/node_composite_trackpos.cc index fc71160da16..b6c69a738d6 100644 --- a/source/blender/nodes/composite/nodes/node_composite_trackpos.cc +++ b/source/blender/nodes/composite/nodes/node_composite_trackpos.cc @@ -6,7 +6,7 @@ */ #include "BLI_index_range.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "DNA_defaults.h" #include "DNA_movieclip_types.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_translate.cc b/source/blender/nodes/composite/nodes/node_composite_translate.cc index 154be2d428a..94d20600183 100644 --- a/source/blender/nodes/composite/nodes/node_composite_translate.cc +++ b/source/blender/nodes/composite/nodes/node_composite_translate.cc @@ -6,7 +6,7 @@ */ #include "BLI_float3x3.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/nodes/composite/nodes/node_composite_viewer.cc b/source/blender/nodes/composite/nodes/node_composite_viewer.cc index dca2f7a1cda..66a16905d67 100644 --- a/source/blender/nodes/composite/nodes/node_composite_viewer.cc +++ b/source/blender/nodes/composite/nodes/node_composite_viewer.cc @@ -5,7 +5,7 @@ * \ingroup cmpnodes */ -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BKE_global.h" #include "BKE_image.h" diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh index ce6b4cd6cfe..68205c3ce6b 100644 --- a/source/blender/nodes/geometry/node_geometry_util.hh +++ b/source/blender/nodes/geometry/node_geometry_util.hh @@ -4,7 +4,7 @@ #include -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_utildefines.h" #include "MEM_guardedalloc.h" diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc index a14661b4a50..eaf0c478e16 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc @@ -2,7 +2,7 @@ #include "BLI_array.hh" #include "BLI_delaunay_2d.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" diff --git a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc index 499d8d689c6..a93956ba042 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc @@ -5,7 +5,7 @@ #include "BKE_image.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_threads.h" #include "BLI_timeit.hh" diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc b/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc index 78ec12508b2..2eb41ea7435 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_shortest_edge_paths.cc @@ -3,7 +3,7 @@ #include #include "BLI_map.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_set.hh" #include "BLI_task.hh" diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index c608bfc383f..11fc900ea94 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -11,7 +11,7 @@ #include "BLI_color.hh" #include "BLI_listbase.h" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "BLI_string.h" #include "BLI_utildefines.h" diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc index aaae1369d79..502f5db3bf3 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc @@ -3,7 +3,7 @@ #include "node_shader_util.hh" -#include "BLI_math_vec_types.hh" +#include "BLI_math_vector_types.hh" #include "UI_interface.h" #include "UI_resources.h" diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc index 3366111ed33..2da230c8813 100644 --- a/source/blender/render/intern/texture_margin.cc +++ b/source/blender/render/intern/texture_margin.cc @@ -7,8 +7,8 @@ #include "BLI_assert.h" #include "BLI_math_geom.h" -#include "BLI_math_vec_types.hh" #include "BLI_math_vector.hh" +#include "BLI_math_vector_types.hh" #include "BLI_vector.hh" #include "BKE_DerivedMesh.h" From 73594f4c9c5924b9c5f25d0662bc1d3d9573c075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Fri, 6 Jan 2023 20:09:41 +0100 Subject: [PATCH 0486/1522] Cleanup: BLI: Rename vec_base to VecBase For consistency with our codestyle and matrix class. # Conflicts: # source/blender/blenlib/BLI_math_matrix_types.hh --- source/blender/blenlib/BLI_math_matrix.hh | 66 ++--- .../blender/blenlib/BLI_math_matrix_types.hh | 16 +- source/blender/blenlib/BLI_math_rotation.hh | 18 +- .../blenlib/BLI_math_rotation_types.hh | 16 +- source/blender/blenlib/BLI_math_vector.hh | 185 +++++++------- .../blenlib/BLI_math_vector_mpq_types.hh | 4 +- .../blender/blenlib/BLI_math_vector_types.hh | 235 +++++++++--------- source/blender/blenlib/intern/math_matrix.cc | 4 +- 8 files changed, 270 insertions(+), 274 deletions(-) diff --git a/source/blender/blenlib/BLI_math_matrix.hh b/source/blender/blenlib/BLI_math_matrix.hh index b0c88c8a0a6..219e41314f5 100644 --- a/source/blender/blenlib/BLI_math_matrix.hh +++ b/source/blender/blenlib/BLI_math_matrix.hh @@ -183,7 +183,7 @@ template [[nodiscard]] MatT from_location(const typename MatT::ve * If vector dimension is lower than matrix diagonal, the missing terms are filled with ones. */ template -[[nodiscard]] MatT from_scale(const vec_base &scale); +[[nodiscard]] MatT from_scale(const VecBase &scale); /** * Create a rotation only matrix. @@ -210,7 +210,7 @@ template template [[nodiscard]] MatT from_loc_rot_scale(const typename MatT::vec3_type &location, const RotationT &rotation, - const vec_base &scale); + const VecBase &scale); /** * Create a rotation matrix from 2 basis vectors. @@ -258,7 +258,7 @@ template * This is a costly operation so it is disabled by default. */ template -[[nodiscard]] inline vec_base to_scale(const MatBase &mat); +[[nodiscard]] inline VecBase to_scale(const MatBase &mat); /** * Decompose a matrix into location, rotation, and scale components. @@ -269,12 +269,12 @@ template template inline void to_rot_scale(const MatBase &mat, RotationT &r_rotation, - vec_base &r_scale); + VecBase &r_scale); template inline void to_loc_rot_scale(const MatBase &mat, - vec_base &r_location, + VecBase &r_location, RotationT &r_rotation, - vec_base &r_scale); + VecBase &r_scale); /** \} */ @@ -286,29 +286,29 @@ inline void to_loc_rot_scale(const MatBase &mat, * Transform a 3d point using a 3x3 matrix (rotation & scale). */ template -[[nodiscard]] vec_base transform_point(const MatBase &mat, - const vec_base &point); +[[nodiscard]] VecBase transform_point(const MatBase &mat, + const VecBase &point); /** * Transform a 3d point using a 4x4 matrix (location & rotation & scale). */ template -[[nodiscard]] vec_base transform_point(const MatBase &mat, - const vec_base &point); +[[nodiscard]] VecBase transform_point(const MatBase &mat, + const VecBase &point); /** * Transform a 3d direction vector using a 3x3 matrix (rotation & scale). */ template -[[nodiscard]] vec_base transform_direction(const MatBase &mat, - const vec_base &direction); +[[nodiscard]] VecBase transform_direction(const MatBase &mat, + const VecBase &direction); /** * Transform a 3d direction vector using a 4x4 matrix (rotation & scale). */ template -[[nodiscard]] vec_base transform_direction(const MatBase &mat, - const vec_base &direction); +[[nodiscard]] VecBase transform_direction(const MatBase &mat, + const VecBase &direction); /** * Project a point using a matrix (location & rotation & scale & perspective divide). @@ -513,8 +513,8 @@ template /* Avoid multiplying the last row if it exists. * Allows using non square matrices like float3x2 and saves computation. */ using IntermediateVecT = - vec_base MatT::col_len - 1) ? (MatT::col_len - 1) : MatT::row_len>; + VecBase MatT::col_len - 1) ? (MatT::col_len - 1) : MatT::row_len>; MatT result = mat; unroll([&](auto c) { @@ -761,7 +761,7 @@ template detail::Quaternion normalized_to_quat_fast(const MatBase } BLI_assert(!(q.x < 0.0f)); - BLI_assert(math::is_unit_scale(vec_base(q))); + BLI_assert(math::is_unit_scale(VecBase(q))); return q; } @@ -898,8 +898,8 @@ template detail::normalized_to_eul2(normalize(mat), eul1, eul2); } /* Return best, which is just the one with lowest values it in. */ - return (length_manhattan(vec_base(eul1)) > length_manhattan(vec_base(eul2))) ? eul2 : - eul1; + return (length_manhattan(VecBase(eul1)) > length_manhattan(VecBase(eul2))) ? eul2 : + eul1; } template @@ -929,9 +929,9 @@ template } template -[[nodiscard]] inline vec_base to_scale(const MatBase &mat) +[[nodiscard]] inline VecBase to_scale(const MatBase &mat) { - vec_base result = {length(mat.x_axis()), length(mat.y_axis()), length(mat.z_axis())}; + VecBase result = {length(mat.x_axis()), length(mat.y_axis()), length(mat.z_axis())}; if constexpr (AllowNegativeScale) { if (UNLIKELY(is_negative(mat))) { result = -result; @@ -960,7 +960,7 @@ inline void to_rotation(const MatBase &mat, detail::EulerXYZ &r_rota template inline void to_rot_scale(const MatBase &mat, RotationT &r_rotation, - vec_base &r_scale) + VecBase &r_scale) { MatBase normalized_mat = normalize_and_get_size(mat, r_scale); if constexpr (AllowNegativeScale) { @@ -974,9 +974,9 @@ inline void to_rot_scale(const MatBase &mat, template inline void to_loc_rot_scale(const MatBase &mat, - vec_base &r_location, + VecBase &r_location, RotationT &r_rotation, - vec_base &r_scale) + VecBase &r_scale) { r_location = mat.location(); to_rot_scale(MatBase(mat), r_rotation, r_scale); @@ -990,7 +990,7 @@ template [[nodiscard]] MatT from_location(const typename MatT::ve } template -[[nodiscard]] MatT from_scale(const vec_base &scale) +[[nodiscard]] MatT from_scale(const VecBase &scale) { BLI_STATIC_ASSERT(ScaleDim <= MatT::min_dim, "Scale dimension should fit the matrix diagonal length."); @@ -1015,7 +1015,7 @@ template template [[nodiscard]] MatT from_loc_rot_scale(const typename MatT::vec3_type &location, const RotationT &rotation, - const vec_base &scale) + const VecBase &scale) { using Mat3x3 = MatBase; MatT mat = MatT(from_rot_scale(rotation, scale)); @@ -1060,36 +1060,36 @@ template } template -vec_base transform_point(const MatBase &mat, const vec_base &point) +VecBase transform_point(const MatBase &mat, const VecBase &point) { return mat * point; } template -vec_base transform_point(const MatBase &mat, const vec_base &point) +VecBase transform_point(const MatBase &mat, const VecBase &point) { return mat.template view<3, 3>() * point + mat.location(); } template -vec_base transform_direction(const MatBase &mat, const vec_base &direction) +VecBase transform_direction(const MatBase &mat, const VecBase &direction) { return mat * direction; } template -vec_base transform_direction(const MatBase &mat, const vec_base &direction) +VecBase transform_direction(const MatBase &mat, const VecBase &direction) { return mat.template view<3, 3>() * direction; } template -vec_base project_point(const MatBase &mat, const vec_base &point) +VecBase project_point(const MatBase &mat, const VecBase &point) { - vec_base tmp(point, T(1)); + VecBase tmp(point, T(1)); tmp = mat * tmp; /* Absolute value to not flip the frustum upside down behind the camera. */ - return vec_base(tmp) / math::abs(tmp[N]); + return VecBase(tmp) / math::abs(tmp[N]); } extern template float3 transform_point(const float3x3 &mat, const float3 &point); diff --git a/source/blender/blenlib/BLI_math_matrix_types.hh b/source/blender/blenlib/BLI_math_matrix_types.hh index dee5cdb2ac2..1505452da22 100644 --- a/source/blender/blenlib/BLI_math_matrix_types.hh +++ b/source/blender/blenlib/BLI_math_matrix_types.hh @@ -71,12 +71,12 @@ template< /* Alignment in bytes. Do not align matrices whose size is not a multiple of 4 component. * This is in order to avoid padding when using arrays of matrices. */ int Alignment = (((NumCol * NumRow) % 4 == 0) ? 4 : 1) * sizeof(T)> -struct alignas(Alignment) MatBase : public vec_struct_base, NumCol> { +struct alignas(Alignment) MatBase : public vec_struct_base, NumCol> { using base_type = T; - using vec3_type = vec_base; - using col_type = vec_base; - using row_type = vec_base; + using vec3_type = VecBase; + using col_type = VecBase; + using row_type = VecBase; static constexpr int min_dim = (NumRow < NumCol) ? NumRow : NumCol; static constexpr int col_len = NumCol; static constexpr int row_len = NumRow; @@ -523,8 +523,8 @@ template; using SrcMatT = MatBase; - using col_type = vec_base; - using row_type = vec_base; + using col_type = VecBase; + using row_type = VecBase; const SrcMatT &mat; @@ -759,8 +759,8 @@ struct MutableMatView using MatViewT = MatView; using SrcMatT = MatBase; - using col_type = vec_base; - using row_type = vec_base; + using col_type = VecBase; + using row_type = VecBase; public: MutableMatView() = delete; diff --git a/source/blender/blenlib/BLI_math_rotation.hh b/source/blender/blenlib/BLI_math_rotation.hh index 78c8dcbef08..cecdec1e90c 100644 --- a/source/blender/blenlib/BLI_math_rotation.hh +++ b/source/blender/blenlib/BLI_math_rotation.hh @@ -20,13 +20,13 @@ namespace blender::math { * \param cosom: dot product from normalized vectors/quats. * \param r_w: calculated weights. */ -template inline vec_base interpolate_dot_slerp(const T t, const T cosom) +template inline VecBase interpolate_dot_slerp(const T t, const T cosom) { const T eps = T(1e-4); BLI_assert(IN_RANGE_INCL(cosom, T(-1.0001), T(1.0001))); - vec_base w; + VecBase w; /* Within [-1..1] range, avoid aligned axis. */ if (LIKELY(math::abs(cosom) < (T(1) - eps))) { const T omega = math::acos(cosom); @@ -48,7 +48,7 @@ inline detail::Quaternion interpolate(const detail::Quaternion &a, const detail::Quaternion &b, T t) { - using Vec4T = vec_base; + using Vec4T = VecBase; BLI_assert(is_unit_scale(Vec4T(a))); BLI_assert(is_unit_scale(Vec4T(b))); @@ -60,7 +60,7 @@ inline detail::Quaternion interpolate(const detail::Quaternion &a, quat = -quat; } - vec_base w = interpolate_dot_slerp(t, cosom); + VecBase w = interpolate_dot_slerp(t, cosom); return detail::Quaternion(w[0] * quat + w[1] * Vec4T(b)); } @@ -76,7 +76,7 @@ namespace blender::math::detail { #ifdef DEBUG # define BLI_ASSERT_UNIT_QUATERNION(_q) \ { \ - auto rot_vec = static_cast>(_q); \ + auto rot_vec = static_cast>(_q); \ T quat_length = math::length_squared(rot_vec); \ if (!(quat_length == 0 || (math::abs(quat_length - 1) < 0.0001))) { \ std::cout << "Warning! " << __func__ << " called with non-normalized quaternion: size " \ @@ -87,7 +87,7 @@ namespace blender::math::detail { # define BLI_ASSERT_UNIT_QUATERNION(_q) #endif -template AxisAngle::AxisAngle(const vec_base &axis, T angle) +template AxisAngle::AxisAngle(const VecBase &axis, T angle) { T length; axis_ = math::normalize_and_get_length(axis, length); @@ -101,7 +101,7 @@ template AxisAngle::AxisAngle(const vec_base &axis, T angle } } -template AxisAngle::AxisAngle(const vec_base &from, const vec_base &to) +template AxisAngle::AxisAngle(const VecBase &from, const VecBase &to) { BLI_assert(is_unit_scale(from)); BLI_assert(is_unit_scale(to)); @@ -124,7 +124,7 @@ template AxisAngle::AxisAngle(const vec_base &from, const v } } template -AxisAngleNormalized::AxisAngleNormalized(const vec_base &axis, T angle) : AxisAngle() +AxisAngleNormalized::AxisAngleNormalized(const VecBase &axis, T angle) : AxisAngle() { BLI_assert(is_unit_scale(axis)); this->axis_ = axis; @@ -183,7 +183,7 @@ template Quaternion::operator AxisAngle() const si = 1.0f; } - vec_base axis = vec_base(quat.y, quat.z, quat.w) / si; + VecBase axis = VecBase(quat.y, quat.z, quat.w) / si; if (math::is_zero(axis)) { axis[1] = 1.0f; } diff --git a/source/blender/blenlib/BLI_math_rotation_types.hh b/source/blender/blenlib/BLI_math_rotation_types.hh index c88c21d1650..f269aa79537 100644 --- a/source/blender/blenlib/BLI_math_rotation_types.hh +++ b/source/blender/blenlib/BLI_math_rotation_types.hh @@ -36,7 +36,7 @@ template struct EulerXYZ { this->z = z; } - EulerXYZ(const vec_base &vec) : EulerXYZ(UNPACK3(vec)){}; + EulerXYZ(const VecBase &vec) : EulerXYZ(UNPACK3(vec)){}; /** Static functions. */ @@ -47,7 +47,7 @@ template struct EulerXYZ { /** Conversions. */ - explicit operator vec_base() const + explicit operator VecBase() const { return {this->x, this->y, this->z}; } @@ -60,7 +60,7 @@ template struct EulerXYZ { friend std::ostream &operator<<(std::ostream &stream, const EulerXYZ &rot) { - return stream << "EulerXYZ" << static_cast>(rot); + return stream << "EulerXYZ" << static_cast>(rot); } }; @@ -77,7 +77,7 @@ template struct Quaternion { this->w = w; } - Quaternion(const vec_base &vec) : Quaternion(UNPACK4(vec)){}; + Quaternion(const VecBase &vec) : Quaternion(UNPACK4(vec)){}; /** Static functions. */ @@ -88,7 +88,7 @@ template struct Quaternion { /** Conversions. */ - explicit operator vec_base() const + explicit operator VecBase() const { return {this->x, this->y, this->z, this->w}; } @@ -107,12 +107,12 @@ template struct Quaternion { friend std::ostream &operator<<(std::ostream &stream, const Quaternion &rot) { - return stream << "Quaternion" << static_cast>(rot); + return stream << "Quaternion" << static_cast>(rot); } }; template struct AxisAngle { - using vec3_type = vec_base; + using vec3_type = VecBase; protected: vec3_type axis_ = {0, 1, 0}; @@ -207,7 +207,7 @@ template struct AxisAngle { * Implicitly cast back to AxisAngle. */ template struct AxisAngleNormalized : public AxisAngle { - AxisAngleNormalized(const vec_base &axis, T angle); + AxisAngleNormalized(const VecBase &axis, T angle); operator AxisAngle() const { diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index 48223971359..10a6dc663e4 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -17,7 +17,7 @@ namespace blender::math { -template [[nodiscard]] inline bool is_zero(const vec_base &a) +template [[nodiscard]] inline bool is_zero(const VecBase &a) { for (int i = 0; i < Size; i++) { if (a[i] != T(0)) { @@ -27,7 +27,7 @@ template [[nodiscard]] inline bool is_zero(const vec_base< return true; } -template [[nodiscard]] inline bool is_any_zero(const vec_base &a) +template [[nodiscard]] inline bool is_any_zero(const VecBase &a) { for (int i = 0; i < Size; i++) { if (a[i] == T(0)) { @@ -38,8 +38,8 @@ template [[nodiscard]] inline bool is_any_zero(const vec_b } template -[[nodiscard]] inline bool almost_equal_relative(const vec_base &a, - const vec_base &b, +[[nodiscard]] inline bool almost_equal_relative(const VecBase &a, + const VecBase &b, const T &epsilon_factor) { for (int i = 0; i < Size; i++) { @@ -51,10 +51,9 @@ template return true; } -template -[[nodiscard]] inline vec_base abs(const vec_base &a) +template [[nodiscard]] inline VecBase abs(const VecBase &a) { - vec_base result; + VecBase result; for (int i = 0; i < Size; i++) { result[i] = a[i] >= 0 ? a[i] : -a[i]; } @@ -62,9 +61,9 @@ template } template -[[nodiscard]] inline vec_base min(const vec_base &a, const vec_base &b) +[[nodiscard]] inline VecBase min(const VecBase &a, const VecBase &b) { - vec_base result; + VecBase result; for (int i = 0; i < Size; i++) { result[i] = a[i] < b[i] ? a[i] : b[i]; } @@ -72,9 +71,9 @@ template } template -[[nodiscard]] inline vec_base max(const vec_base &a, const vec_base &b) +[[nodiscard]] inline VecBase max(const VecBase &a, const VecBase &b) { - vec_base result; + VecBase result; for (int i = 0; i < Size; i++) { result[i] = a[i] > b[i] ? a[i] : b[i]; } @@ -82,11 +81,11 @@ template } template -[[nodiscard]] inline vec_base clamp(const vec_base &a, - const vec_base &min, - const vec_base &max) +[[nodiscard]] inline VecBase clamp(const VecBase &a, + const VecBase &min, + const VecBase &max) { - vec_base result = a; + VecBase result = a; for (int i = 0; i < Size; i++) { result[i] = std::clamp(result[i], min[i], max[i]); } @@ -94,11 +93,9 @@ template } template -[[nodiscard]] inline vec_base clamp(const vec_base &a, - const T &min, - const T &max) +[[nodiscard]] inline VecBase clamp(const VecBase &a, const T &min, const T &max) { - vec_base result = a; + VecBase result = a; for (int i = 0; i < Size; i++) { result[i] = std::clamp(result[i], min, max); } @@ -106,9 +103,9 @@ template } template -[[nodiscard]] inline vec_base mod(const vec_base &a, const vec_base &b) +[[nodiscard]] inline VecBase mod(const VecBase &a, const VecBase &b) { - vec_base result; + VecBase result; for (int i = 0; i < Size; i++) { BLI_assert(b[i] != 0); result[i] = std::fmod(a[i], b[i]); @@ -117,10 +114,10 @@ template } template -[[nodiscard]] inline vec_base mod(const vec_base &a, const T &b) +[[nodiscard]] inline VecBase mod(const VecBase &a, const T &b) { BLI_assert(b != 0); - vec_base result; + VecBase result; for (int i = 0; i < Size; i++) { result[i] = std::fmod(a[i], b); } @@ -128,10 +125,10 @@ template } template -[[nodiscard]] inline vec_base safe_mod(const vec_base &a, - const vec_base &b) +[[nodiscard]] inline VecBase safe_mod(const VecBase &a, + const VecBase &b) { - vec_base result; + VecBase result; for (int i = 0; i < Size; i++) { result[i] = (b[i] != 0) ? std::fmod(a[i], b[i]) : 0; } @@ -139,12 +136,12 @@ template } template -[[nodiscard]] inline vec_base safe_mod(const vec_base &a, const T &b) +[[nodiscard]] inline VecBase safe_mod(const VecBase &a, const T &b) { if (b == 0) { - return vec_base(0); + return VecBase(0); } - vec_base result; + VecBase result; for (int i = 0; i < Size; i++) { result[i] = std::fmod(a[i], b); } @@ -157,10 +154,10 @@ template * It is undefined if \a a is negative or \b b is not strictly positive. */ template -[[nodiscard]] inline vec_base ceil_to_multiple(const vec_base &a, - const vec_base &b) +[[nodiscard]] inline VecBase ceil_to_multiple(const VecBase &a, + const VecBase &b) { - vec_base result; + VecBase result; for (int i = 0; i < Size; i++) { BLI_assert(a[i] >= 0); BLI_assert(b[i] > 0); @@ -174,10 +171,10 @@ template * It is undefined if \a a is negative or \b b is not strictly positive. */ template -[[nodiscard]] inline vec_base divide_ceil(const vec_base &a, - const vec_base &b) +[[nodiscard]] inline VecBase divide_ceil(const VecBase &a, + const VecBase &b) { - vec_base result; + VecBase result; for (int i = 0; i < Size; i++) { BLI_assert(a[i] >= 0); BLI_assert(b[i] > 0); @@ -187,17 +184,17 @@ template } template -void min_max(const vec_base &vector, vec_base &min, vec_base &max) +void min_max(const VecBase &vector, VecBase &min, VecBase &max) { min = math::min(vector, min); max = math::max(vector, max); } template -[[nodiscard]] inline vec_base safe_divide(const vec_base &a, - const vec_base &b) +[[nodiscard]] inline VecBase safe_divide(const VecBase &a, + const VecBase &b) { - vec_base result; + VecBase result; for (int i = 0; i < Size; i++) { result[i] = (b[i] == 0) ? 0 : a[i] / b[i]; } @@ -205,15 +202,15 @@ template } template -[[nodiscard]] inline vec_base safe_divide(const vec_base &a, const T &b) +[[nodiscard]] inline VecBase safe_divide(const VecBase &a, const T &b) { - return (b != 0) ? a / b : vec_base(0.0f); + return (b != 0) ? a / b : VecBase(0.0f); } template -[[nodiscard]] inline vec_base floor(const vec_base &a) +[[nodiscard]] inline VecBase floor(const VecBase &a) { - vec_base result; + VecBase result; for (int i = 0; i < Size; i++) { result[i] = std::floor(a[i]); } @@ -221,9 +218,9 @@ template } template -[[nodiscard]] inline vec_base ceil(const vec_base &a) +[[nodiscard]] inline VecBase ceil(const VecBase &a) { - vec_base result; + VecBase result; for (int i = 0; i < Size; i++) { result[i] = std::ceil(a[i]); } @@ -231,9 +228,9 @@ template } template -[[nodiscard]] inline vec_base fract(const vec_base &a) +[[nodiscard]] inline VecBase fract(const VecBase &a) { - vec_base result; + VecBase result; for (int i = 0; i < Size; i++) { result[i] = a[i] - std::floor(a[i]); } @@ -241,7 +238,7 @@ template } template -[[nodiscard]] inline T dot(const vec_base &a, const vec_base &b) +[[nodiscard]] inline T dot(const VecBase &a, const VecBase &b) { T result = a[0] * b[0]; for (int i = 1; i < Size; i++) { @@ -250,7 +247,7 @@ template return result; } -template [[nodiscard]] inline T length_manhattan(const vec_base &a) +template [[nodiscard]] inline T length_manhattan(const VecBase &a) { T result = std::abs(a[0]); for (int i = 1; i < Size; i++) { @@ -259,17 +256,17 @@ template [[nodiscard]] inline T length_manhattan(const vec return result; } -template [[nodiscard]] inline T length_squared(const vec_base &a) +template [[nodiscard]] inline T length_squared(const VecBase &a) { return dot(a, a); } -template [[nodiscard]] inline T length(const vec_base &a) +template [[nodiscard]] inline T length(const VecBase &a) { return std::sqrt(length_squared(a)); } -template [[nodiscard]] inline bool is_unit_scale(const vec_base &v) +template [[nodiscard]] inline bool is_unit_scale(const VecBase &v) { /* Checks are flipped so NAN doesn't assert because we're making sure the value was * normalized and in the case we don't want NAN to be raising asserts since there @@ -280,57 +277,57 @@ template [[nodiscard]] inline bool is_unit_scale(const vec } template -[[nodiscard]] inline T distance_manhattan(const vec_base &a, const vec_base &b) +[[nodiscard]] inline T distance_manhattan(const VecBase &a, const VecBase &b) { return length_manhattan(a - b); } template -[[nodiscard]] inline T distance_squared(const vec_base &a, const vec_base &b) +[[nodiscard]] inline T distance_squared(const VecBase &a, const VecBase &b) { return length_squared(a - b); } template -[[nodiscard]] inline T distance(const vec_base &a, const vec_base &b) +[[nodiscard]] inline T distance(const VecBase &a, const VecBase &b) { return length(a - b); } template -[[nodiscard]] inline vec_base reflect(const vec_base &incident, - const vec_base &normal) +[[nodiscard]] inline VecBase reflect(const VecBase &incident, + const VecBase &normal) { BLI_assert(is_unit_scale(normal)); return incident - 2.0 * dot(normal, incident) * normal; } template -[[nodiscard]] inline vec_base refract(const vec_base &incident, - const vec_base &normal, - const T &eta) +[[nodiscard]] inline VecBase refract(const VecBase &incident, + const VecBase &normal, + const T &eta) { float dot_ni = dot(normal, incident); float k = 1.0f - eta * eta * (1.0f - dot_ni * dot_ni); if (k < 0.0f) { - return vec_base(0.0f); + return VecBase(0.0f); } return eta * incident - (eta * dot_ni + sqrt(k)) * normal; } template -[[nodiscard]] inline vec_base project(const vec_base &p, - const vec_base &v_proj) +[[nodiscard]] inline VecBase project(const VecBase &p, + const VecBase &v_proj) { if (UNLIKELY(is_zero(v_proj))) { - return vec_base(0.0f); + return VecBase(0.0f); } return v_proj * (dot(p, v_proj) / dot(v_proj, v_proj)); } template -[[nodiscard]] inline vec_base normalize_and_get_length(const vec_base &v, - T &out_length) +[[nodiscard]] inline VecBase normalize_and_get_length(const VecBase &v, + T &out_length) { out_length = length_squared(v); /* A larger value causes normalize errors in a scaled down models with camera extreme close. */ @@ -341,40 +338,40 @@ template } /* Either the vector is small or one of it's values contained `nan`. */ out_length = 0.0; - return vec_base(0.0); + return VecBase(0.0); } template -[[nodiscard]] inline vec_base normalize(const vec_base &v) +[[nodiscard]] inline VecBase normalize(const VecBase &v) { T len; return normalize_and_get_length(v, len); } template -[[nodiscard]] inline vec_base cross(const vec_base &a, const vec_base &b) +[[nodiscard]] inline VecBase cross(const VecBase &a, const VecBase &b) { return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; } -[[nodiscard]] inline vec_base cross_high_precision(const vec_base &a, - const vec_base &b) +[[nodiscard]] inline VecBase cross_high_precision(const VecBase &a, + const VecBase &b) { return {float(double(a.y) * double(b.z) - double(a.z) * double(b.y)), float(double(a.z) * double(b.x) - double(a.x) * double(b.z)), float(double(a.x) * double(b.y) - double(a.y) * double(b.x))}; } -template [[nodiscard]] inline vec_base cross_poly(Span> poly) +template [[nodiscard]] inline VecBase cross_poly(Span> poly) { /* Newell's Method. */ int nv = int(poly.size()); if (nv < 3) { - return vec_base(0, 0, 0); + return VecBase(0, 0, 0); } - const vec_base *v_prev = &poly[nv - 1]; - const vec_base *v_curr = &poly[0]; - vec_base n(0, 0, 0); + const VecBase *v_prev = &poly[nv - 1]; + const VecBase *v_curr = &poly[0]; + VecBase n(0, 0, 0); for (int i = 0; i < nv;) { n[0] = n[0] + ((*v_prev)[1] - (*v_curr)[1]) * ((*v_prev)[2] + (*v_curr)[2]); n[1] = n[1] + ((*v_prev)[2] - (*v_curr)[2]) * ((*v_prev)[0] + (*v_curr)[0]); @@ -389,16 +386,16 @@ template [[nodiscard]] inline vec_base cross_poly(Span -[[nodiscard]] inline vec_base interpolate(const vec_base &a, - const vec_base &b, - const FactorT &t) +[[nodiscard]] inline VecBase interpolate(const VecBase &a, + const VecBase &b, + const FactorT &t) { return a * (1 - t) + b * t; } template -[[nodiscard]] inline vec_base midpoint(const vec_base &a, - const vec_base &b) +[[nodiscard]] inline VecBase midpoint(const VecBase &a, + const VecBase &b) { return (a + b) * 0.5; } @@ -407,16 +404,16 @@ template * Return `vector` if `incident` and `reference` are pointing in the same direction. */ template -[[nodiscard]] inline vec_base faceforward(const vec_base &vector, - const vec_base &incident, - const vec_base &reference) +[[nodiscard]] inline VecBase faceforward(const VecBase &vector, + const VecBase &incident, + const VecBase &reference) { return (dot(reference, incident) < 0) ? vector : -vector; } -template [[nodiscard]] inline int dominant_axis(const vec_base &a) +template [[nodiscard]] inline int dominant_axis(const VecBase &a) { - vec_base b = abs(a); + VecBase b = abs(a); return ((b.x > b.y) ? ((b.x > b.z) ? 0 : 2) : ((b.y > b.z) ? 1 : 2)); } @@ -425,7 +422,7 @@ template [[nodiscard]] inline int dominant_axis(const vec_base * \note Returned vector can be in any perpendicular direction. * \note Returned vector might not the same length as \a v. */ -template [[nodiscard]] inline vec_base orthogonal(const vec_base &v) +template [[nodiscard]] inline VecBase orthogonal(const VecBase &v) { const int axis = dominant_axis(v); switch (axis) { @@ -443,14 +440,14 @@ template [[nodiscard]] inline vec_base orthogonal(const vec_ba * Calculates a perpendicular vector to \a v. * \note Returned vector can be in any perpendicular direction. */ -template [[nodiscard]] inline vec_base orthogonal(const vec_base &v) +template [[nodiscard]] inline VecBase orthogonal(const VecBase &v) { return {-v.y, v.x}; } template -[[nodiscard]] inline bool is_equal(const vec_base &a, - const vec_base &b, +[[nodiscard]] inline bool is_equal(const VecBase &a, + const VecBase &b, const T epsilon = T(0)) { for (int i = 0; i < Size; i++) { @@ -474,9 +471,9 @@ template struct isect_result { }; template -[[nodiscard]] isect_result> isect_seg_seg(const vec_base &v1, - const vec_base &v2, - const vec_base &v3, - const vec_base &v4); +[[nodiscard]] isect_result> isect_seg_seg(const VecBase &v1, + const VecBase &v2, + const VecBase &v3, + const VecBase &v4); } // namespace blender::math diff --git a/source/blender/blenlib/BLI_math_vector_mpq_types.hh b/source/blender/blenlib/BLI_math_vector_mpq_types.hh index 45c416a5734..dd6e6f38d72 100644 --- a/source/blender/blenlib/BLI_math_vector_mpq_types.hh +++ b/source/blender/blenlib/BLI_math_vector_mpq_types.hh @@ -14,8 +14,8 @@ namespace blender { -using mpq2 = vec_base; -using mpq3 = vec_base; +using mpq2 = VecBase; +using mpq3 = VecBase; namespace math { diff --git a/source/blender/blenlib/BLI_math_vector_types.hh b/source/blender/blenlib/BLI_math_vector_types.hh index 0b3bb46db07..1a408ad4b8d 100644 --- a/source/blender/blenlib/BLI_math_vector_types.hh +++ b/source/blender/blenlib/BLI_math_vector_types.hh @@ -77,16 +77,16 @@ template uint64_t vector_hash(const T &vec) } // namespace math -template struct vec_base : public vec_struct_base { +template struct VecBase : public vec_struct_base { static constexpr int type_length = Size; using base_type = T; - using uint_type = vec_base, Size>; + using uint_type = VecBase, Size>; - vec_base() = default; + VecBase() = default; - explicit vec_base(T value) + explicit VecBase(T value) { for (int i = 0; i < Size; i++) { (*this)[i] = value; @@ -94,27 +94,27 @@ template struct vec_base : public vec_struct_base } template))> - explicit vec_base(U value) : vec_base(T(value)) + explicit VecBase(U value) : VecBase(T(value)) { } /* Workaround issue with template BLI_ENABLE_IF((Size == 2)) not working. */ #define BLI_ENABLE_IF_VEC(_size, _test) int S = _size, BLI_ENABLE_IF((S _test)) - template vec_base(T _x, T _y) + template VecBase(T _x, T _y) { (*this)[0] = _x; (*this)[1] = _y; } - template vec_base(T _x, T _y, T _z) + template VecBase(T _x, T _y, T _z) { (*this)[0] = _x; (*this)[1] = _y; (*this)[2] = _z; } - template vec_base(T _x, T _y, T _z, T _w) + template VecBase(T _x, T _y, T _z, T _w) { (*this)[0] = _x; (*this)[1] = _y; @@ -125,49 +125,49 @@ template struct vec_base : public vec_struct_base /** Mixed scalar-vector constructors. */ template - constexpr vec_base(const vec_base &xy, T z) : vec_base(T(xy.x), T(xy.y), z) + constexpr VecBase(const VecBase &xy, T z) : VecBase(T(xy.x), T(xy.y), z) { } template - constexpr vec_base(T x, const vec_base &yz) : vec_base(x, T(yz.x), T(yz.y)) + constexpr VecBase(T x, const VecBase &yz) : VecBase(x, T(yz.x), T(yz.y)) { } template - vec_base(vec_base xyz, T w) : vec_base(T(xyz.x), T(xyz.y), T(xyz.z), T(w)) + VecBase(VecBase xyz, T w) : VecBase(T(xyz.x), T(xyz.y), T(xyz.z), T(w)) { } template - vec_base(T x, vec_base yzw) : vec_base(T(x), T(yzw.x), T(yzw.y), T(yzw.z)) + VecBase(T x, VecBase yzw) : VecBase(T(x), T(yzw.x), T(yzw.y), T(yzw.z)) { } template - vec_base(vec_base xy, vec_base zw) : vec_base(T(xy.x), T(xy.y), T(zw.x), T(zw.y)) + VecBase(VecBase xy, VecBase zw) : VecBase(T(xy.x), T(xy.y), T(zw.x), T(zw.y)) { } template - vec_base(vec_base xy, T z, T w) : vec_base(T(xy.x), T(xy.y), T(z), T(w)) + VecBase(VecBase xy, T z, T w) : VecBase(T(xy.x), T(xy.y), T(z), T(w)) { } template - vec_base(T x, vec_base yz, T w) : vec_base(T(x), T(yz.x), T(yz.y), T(w)) + VecBase(T x, VecBase yz, T w) : VecBase(T(x), T(yz.x), T(yz.y), T(w)) { } template - vec_base(T x, T y, vec_base zw) : vec_base(T(x), T(y), T(zw.x), T(zw.y)) + VecBase(T x, T y, VecBase zw) : VecBase(T(x), T(y), T(zw.x), T(zw.y)) { } /** Masking. */ template Size)> - explicit vec_base(const vec_base &other) + explicit VecBase(const VecBase &other) { for (int i = 0; i < Size; i++) { (*this)[i] = T(other[i]); @@ -178,24 +178,23 @@ template struct vec_base : public vec_struct_base /** Conversion from pointers (from C-style vectors). */ - vec_base(const T *ptr) + VecBase(const T *ptr) { unroll([&](auto i) { (*this)[i] = ptr[i]; }); } - template))> - explicit vec_base(const U *ptr) + template))> explicit VecBase(const U *ptr) { unroll([&](auto i) { (*this)[i] = ptr[i]; }); } - vec_base(const T (*ptr)[Size]) : vec_base(static_cast(ptr[0])) + VecBase(const T (*ptr)[Size]) : VecBase(static_cast(ptr[0])) { } /** Conversion from other vector types. */ - template explicit vec_base(const vec_base &vec) + template explicit VecBase(const VecBase &vec) { unroll([&](auto i) { (*this)[i] = T(vec[i]); }); } @@ -234,144 +233,144 @@ template struct vec_base : public vec_struct_base /** Arithmetic operators. */ - friend vec_base operator+(const vec_base &a, const vec_base &b) + friend VecBase operator+(const VecBase &a, const VecBase &b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] + b[i]; }); return result; } - friend vec_base operator+(const vec_base &a, const T &b) + friend VecBase operator+(const VecBase &a, const T &b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] + b; }); return result; } - friend vec_base operator+(const T &a, const vec_base &b) + friend VecBase operator+(const T &a, const VecBase &b) { return b + a; } - vec_base &operator+=(const vec_base &b) + VecBase &operator+=(const VecBase &b) { unroll([&](auto i) { (*this)[i] += b[i]; }); return *this; } - vec_base &operator+=(const T &b) + VecBase &operator+=(const T &b) { unroll([&](auto i) { (*this)[i] += b; }); return *this; } - friend vec_base operator-(const vec_base &a) + friend VecBase operator-(const VecBase &a) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = -a[i]; }); return result; } - friend vec_base operator-(const vec_base &a, const vec_base &b) + friend VecBase operator-(const VecBase &a, const VecBase &b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] - b[i]; }); return result; } - friend vec_base operator-(const vec_base &a, const T &b) + friend VecBase operator-(const VecBase &a, const T &b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] - b; }); return result; } - friend vec_base operator-(const T &a, const vec_base &b) + friend VecBase operator-(const T &a, const VecBase &b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a - b[i]; }); return result; } - vec_base &operator-=(const vec_base &b) + VecBase &operator-=(const VecBase &b) { unroll([&](auto i) { (*this)[i] -= b[i]; }); return *this; } - vec_base &operator-=(const T &b) + VecBase &operator-=(const T &b) { unroll([&](auto i) { (*this)[i] -= b; }); return *this; } - friend vec_base operator*(const vec_base &a, const vec_base &b) + friend VecBase operator*(const VecBase &a, const VecBase &b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] * b[i]; }); return result; } - template friend vec_base operator*(const vec_base &a, FactorT b) + template friend VecBase operator*(const VecBase &a, FactorT b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] * b; }); return result; } - friend vec_base operator*(T a, const vec_base &b) + friend VecBase operator*(T a, const VecBase &b) { return b * a; } - vec_base &operator*=(T b) + VecBase &operator*=(T b) { unroll([&](auto i) { (*this)[i] *= b; }); return *this; } - vec_base &operator*=(const vec_base &b) + VecBase &operator*=(const VecBase &b) { unroll([&](auto i) { (*this)[i] *= b[i]; }); return *this; } - friend vec_base operator/(const vec_base &a, const vec_base &b) + friend VecBase operator/(const VecBase &a, const VecBase &b) { for (int i = 0; i < Size; i++) { BLI_assert(b[i] != T(0)); } - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] / b[i]; }); return result; } - friend vec_base operator/(const vec_base &a, T b) + friend VecBase operator/(const VecBase &a, T b) { BLI_assert(b != T(0)); - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] / b; }); return result; } - friend vec_base operator/(T a, const vec_base &b) + friend VecBase operator/(T a, const VecBase &b) { for (int i = 0; i < Size; i++) { BLI_assert(b[i] != T(0)); } - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a / b[i]; }); return result; } - vec_base &operator/=(T b) + VecBase &operator/=(T b) { BLI_assert(b != T(0)); unroll([&](auto i) { (*this)[i] /= b; }); return *this; } - vec_base &operator/=(const vec_base &b) + VecBase &operator/=(const VecBase &b) { BLI_assert(b != T(0)); unroll([&](auto i) { (*this)[i] /= b[i]; }); @@ -380,155 +379,155 @@ template struct vec_base : public vec_struct_base /** Binary operators. */ - BLI_INT_OP(T) friend vec_base operator&(const vec_base &a, const vec_base &b) + BLI_INT_OP(T) friend VecBase operator&(const VecBase &a, const VecBase &b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] & b[i]; }); return result; } - BLI_INT_OP(T) friend vec_base operator&(const vec_base &a, T b) + BLI_INT_OP(T) friend VecBase operator&(const VecBase &a, T b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] & b; }); return result; } - BLI_INT_OP(T) friend vec_base operator&(T a, const vec_base &b) + BLI_INT_OP(T) friend VecBase operator&(T a, const VecBase &b) { return b & a; } - BLI_INT_OP(T) vec_base &operator&=(T b) + BLI_INT_OP(T) VecBase &operator&=(T b) { unroll([&](auto i) { (*this)[i] &= b; }); return *this; } - BLI_INT_OP(T) vec_base &operator&=(const vec_base &b) + BLI_INT_OP(T) VecBase &operator&=(const VecBase &b) { unroll([&](auto i) { (*this)[i] &= b[i]; }); return *this; } - BLI_INT_OP(T) friend vec_base operator|(const vec_base &a, const vec_base &b) + BLI_INT_OP(T) friend VecBase operator|(const VecBase &a, const VecBase &b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] | b[i]; }); return result; } - BLI_INT_OP(T) friend vec_base operator|(const vec_base &a, T b) + BLI_INT_OP(T) friend VecBase operator|(const VecBase &a, T b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] | b; }); return result; } - BLI_INT_OP(T) friend vec_base operator|(T a, const vec_base &b) + BLI_INT_OP(T) friend VecBase operator|(T a, const VecBase &b) { return b | a; } - BLI_INT_OP(T) vec_base &operator|=(T b) + BLI_INT_OP(T) VecBase &operator|=(T b) { unroll([&](auto i) { (*this)[i] |= b; }); return *this; } - BLI_INT_OP(T) vec_base &operator|=(const vec_base &b) + BLI_INT_OP(T) VecBase &operator|=(const VecBase &b) { unroll([&](auto i) { (*this)[i] |= b[i]; }); return *this; } - BLI_INT_OP(T) friend vec_base operator^(const vec_base &a, const vec_base &b) + BLI_INT_OP(T) friend VecBase operator^(const VecBase &a, const VecBase &b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] ^ b[i]; }); return result; } - BLI_INT_OP(T) friend vec_base operator^(const vec_base &a, T b) + BLI_INT_OP(T) friend VecBase operator^(const VecBase &a, T b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] ^ b; }); return result; } - BLI_INT_OP(T) friend vec_base operator^(T a, const vec_base &b) + BLI_INT_OP(T) friend VecBase operator^(T a, const VecBase &b) { return b ^ a; } - BLI_INT_OP(T) vec_base &operator^=(T b) + BLI_INT_OP(T) VecBase &operator^=(T b) { unroll([&](auto i) { (*this)[i] ^= b; }); return *this; } - BLI_INT_OP(T) vec_base &operator^=(const vec_base &b) + BLI_INT_OP(T) VecBase &operator^=(const VecBase &b) { unroll([&](auto i) { (*this)[i] ^= b[i]; }); return *this; } - BLI_INT_OP(T) friend vec_base operator~(const vec_base &a) + BLI_INT_OP(T) friend VecBase operator~(const VecBase &a) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = ~a[i]; }); return result; } /** Bit-shift operators. */ - BLI_INT_OP(T) friend vec_base operator<<(const vec_base &a, const vec_base &b) + BLI_INT_OP(T) friend VecBase operator<<(const VecBase &a, const VecBase &b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] << b[i]; }); return result; } - BLI_INT_OP(T) friend vec_base operator<<(const vec_base &a, T b) + BLI_INT_OP(T) friend VecBase operator<<(const VecBase &a, T b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] << b; }); return result; } - BLI_INT_OP(T) vec_base &operator<<=(T b) + BLI_INT_OP(T) VecBase &operator<<=(T b) { unroll([&](auto i) { (*this)[i] <<= b; }); return *this; } - BLI_INT_OP(T) vec_base &operator<<=(const vec_base &b) + BLI_INT_OP(T) VecBase &operator<<=(const VecBase &b) { unroll([&](auto i) { (*this)[i] <<= b[i]; }); return *this; } - BLI_INT_OP(T) friend vec_base operator>>(const vec_base &a, const vec_base &b) + BLI_INT_OP(T) friend VecBase operator>>(const VecBase &a, const VecBase &b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] >> b[i]; }); return result; } - BLI_INT_OP(T) friend vec_base operator>>(const vec_base &a, T b) + BLI_INT_OP(T) friend VecBase operator>>(const VecBase &a, T b) { - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] >> b; }); return result; } - BLI_INT_OP(T) vec_base &operator>>=(T b) + BLI_INT_OP(T) VecBase &operator>>=(T b) { unroll([&](auto i) { (*this)[i] >>= b; }); return *this; } - BLI_INT_OP(T) vec_base &operator>>=(const vec_base &b) + BLI_INT_OP(T) VecBase &operator>>=(const VecBase &b) { unroll([&](auto i) { (*this)[i] >>= b[i]; }); return *this; @@ -536,28 +535,28 @@ template struct vec_base : public vec_struct_base /** Modulo operators. */ - BLI_INT_OP(T) friend vec_base operator%(const vec_base &a, const vec_base &b) + BLI_INT_OP(T) friend VecBase operator%(const VecBase &a, const VecBase &b) { for (int i = 0; i < Size; i++) { BLI_assert(b[i] != T(0)); } - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] % b[i]; }); return result; } - BLI_INT_OP(T) friend vec_base operator%(const vec_base &a, T b) + BLI_INT_OP(T) friend VecBase operator%(const VecBase &a, T b) { BLI_assert(b != 0); - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a[i] % b; }); return result; } - BLI_INT_OP(T) friend vec_base operator%(T a, const vec_base &b) + BLI_INT_OP(T) friend VecBase operator%(T a, const VecBase &b) { BLI_assert(b != T(0)); - vec_base result; + VecBase result; unroll([&](auto i) { result[i] = a % b[i]; }); return result; } @@ -566,7 +565,7 @@ template struct vec_base : public vec_struct_base /** Compare. */ - friend bool operator==(const vec_base &a, const vec_base &b) + friend bool operator==(const VecBase &a, const VecBase &b) { for (int i = 0; i < Size; i++) { if (a[i] != b[i]) { @@ -576,7 +575,7 @@ template struct vec_base : public vec_struct_base return true; } - friend bool operator!=(const vec_base &a, const vec_base &b) + friend bool operator!=(const VecBase &a, const VecBase &b) { return !(a == b); } @@ -588,7 +587,7 @@ template struct vec_base : public vec_struct_base return math::vector_hash(*this); } - friend std::ostream &operator<<(std::ostream &stream, const vec_base &v) + friend std::ostream &operator<<(std::ostream &stream, const VecBase &v) { stream << "("; for (int i = 0; i < Size; i++) { @@ -611,32 +610,32 @@ template struct AssertUnitEpsilon { } // namespace math -using char3 = blender::vec_base; +using char3 = blender::VecBase; -using uchar3 = blender::vec_base; -using uchar4 = blender::vec_base; +using uchar3 = blender::VecBase; +using uchar4 = blender::VecBase; -using int2 = vec_base; -using int3 = vec_base; -using int4 = vec_base; +using int2 = VecBase; +using int3 = VecBase; +using int4 = VecBase; -using uint2 = vec_base; -using uint3 = vec_base; -using uint4 = vec_base; +using uint2 = VecBase; +using uint3 = VecBase; +using uint4 = VecBase; -using short2 = blender::vec_base; -using short3 = blender::vec_base; +using short2 = blender::VecBase; +using short3 = blender::VecBase; -using ushort2 = vec_base; -using ushort3 = blender::vec_base; -using ushort4 = blender::vec_base; +using ushort2 = VecBase; +using ushort3 = blender::VecBase; +using ushort4 = blender::VecBase; -using float2 = vec_base; -using float3 = vec_base; -using float4 = vec_base; +using float2 = VecBase; +using float3 = VecBase; +using float4 = VecBase; -using double2 = vec_base; -using double3 = vec_base; -using double4 = vec_base; +using double2 = VecBase; +using double3 = VecBase; +using double4 = VecBase; } // namespace blender diff --git a/source/blender/blenlib/intern/math_matrix.cc b/source/blender/blenlib/intern/math_matrix.cc index 9211a608022..9ab484d0d8a 100644 --- a/source/blender/blenlib/intern/math_matrix.cc +++ b/source/blender/blenlib/intern/math_matrix.cc @@ -214,7 +214,7 @@ MatBase pseudo_invert(const MatBase &mat, T epsilo * of `A` as `Ainv = V.Winv.transpose(U)`. */ MatBase U, W, V; - vec_base S_val; + VecBase S_val; { using namespace Eigen; @@ -274,7 +274,7 @@ static void polar_decompose(const MatBase &mat3, * P = VSV* */ MatBase W, V; - vec_base S_val; + VecBase S_val; { using namespace Eigen; From ba9f0d5a159110f011977690e007b371d31a3661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Fri, 6 Jan 2023 21:39:22 +0100 Subject: [PATCH 0487/1522] BLI: Math: Vector: Improve API documentation Add precision about non-trivial functions. --- source/blender/blenlib/BLI_math_vector.hh | 66 +++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index 10a6dc663e4..9bba55663bd 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -17,6 +17,9 @@ namespace blender::math { +/** + * Returns true if all components are exactly equal to 0. + */ template [[nodiscard]] inline bool is_zero(const VecBase &a) { for (int i = 0; i < Size; i++) { @@ -27,6 +30,9 @@ template [[nodiscard]] inline bool is_zero(const VecBase [[nodiscard]] inline bool is_any_zero(const VecBase &a) { for (int i = 0; i < Size; i++) { @@ -37,6 +43,10 @@ template [[nodiscard]] inline bool is_any_zero(const VecBa return false; } +/** + * Returns true if the given vectors are equal within the given epsilon. + * The epsilon is scaled for each component by magnitude of the matching component of `a`. + */ template [[nodiscard]] inline bool almost_equal_relative(const VecBase &a, const VecBase &b, @@ -124,6 +134,9 @@ template return result; } +/** + * Safe version of mod(a, b) that returns 0 if b is equal to 0. + */ template [[nodiscard]] inline VecBase safe_mod(const VecBase &a, const VecBase &b) @@ -135,6 +148,9 @@ template return result; } +/** + * Safe version of mod(a, b) that returns 0 if b is equal to 0. + */ template [[nodiscard]] inline VecBase safe_mod(const VecBase &a, const T &b) { @@ -190,6 +206,9 @@ void min_max(const VecBase &vector, VecBase &min, VecBase [[nodiscard]] inline VecBase safe_divide(const VecBase &a, const VecBase &b) @@ -201,6 +220,9 @@ template return result; } +/** + * Returns 0 if denominator is exactly equal to 0. + */ template [[nodiscard]] inline VecBase safe_divide(const VecBase &a, const T &b) { @@ -237,6 +259,12 @@ template return result; } +/** + * Dot product between two vectors. + * Equivalent to component wise multiplication followed by summation of the result. + * Equivalent to the cosine of the angle between the two vectors if the vectors are normalized. + * /note prefer using `length_manhattan(a)` than `dot(a, vec(1))` to get the sum of all components. + */ template [[nodiscard]] inline T dot(const VecBase &a, const VecBase &b) { @@ -247,6 +275,9 @@ template return result; } +/** + * Returns summation of all components. + */ template [[nodiscard]] inline T length_manhattan(const VecBase &a) { T result = std::abs(a[0]); @@ -266,6 +297,7 @@ template [[nodiscard]] inline T length(const VecBase [[nodiscard]] inline bool is_unit_scale(const VecBase &v) { /* Checks are flipped so NAN doesn't assert because we're making sure the value was @@ -315,6 +347,10 @@ template return eta * incident - (eta * dot_ni + sqrt(k)) * normal; } +/** + * Project \a p onto \a v_proj . + * Returns zero vector if \a v_proj is degenerate (zero length). + */ template [[nodiscard]] inline VecBase project(const VecBase &p, const VecBase &v_proj) @@ -348,12 +384,23 @@ template return normalize_and_get_length(v, len); } +/** + * \return cross perpendicular vector to \a a and \a b. + * \note Return zero vector if \a a and \a b are collinear. + * \note The length of the resulting vector is equal to twice the area of the triangle between \a a + * and \a b ; and it is equal to the sine of the angle between \a a and \a b if they are + * normalized. + * \note Blender 3D space uses right handedness: \a a = thumb, \a b = index, return = middle. + */ template [[nodiscard]] inline VecBase cross(const VecBase &a, const VecBase &b) { return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; } +/** + * Same as `cross(a, b)` but use double float precision for the computation. + */ [[nodiscard]] inline VecBase cross_high_precision(const VecBase &a, const VecBase &b) { @@ -362,6 +409,11 @@ template float(double(a.x) * double(b.y) - double(a.y) * double(b.x))}; } +/** + * @param poly List of points around a polygon. They don't have to be co-planar. + * @return Best fit plane normal for the given polygon loop or, zero vector if point + * loop is too short. Not normalized. + */ template [[nodiscard]] inline VecBase cross_poly(Span> poly) { /* Newell's Method. */ @@ -385,6 +437,11 @@ template [[nodiscard]] inline VecBase cross_poly(Span [[nodiscard]] inline VecBase interpolate(const VecBase &a, const VecBase &b, @@ -393,6 +450,9 @@ template return a * (1 - t) + b * t; } +/** + * @return Point halfway between \a a and \a b. + */ template [[nodiscard]] inline VecBase midpoint(const VecBase &a, const VecBase &b) @@ -411,6 +471,9 @@ template return (dot(reference, incident) < 0) ? vector : -vector; } +/** + * @return Index of the component with the greatest magnitude. + */ template [[nodiscard]] inline int dominant_axis(const VecBase &a) { VecBase b = abs(a); @@ -445,6 +508,9 @@ template [[nodiscard]] inline VecBase orthogonal(const VecBase return {-v.y, v.x}; } +/** + * Returns true if vectors are equal within the given epsilon. + */ template [[nodiscard]] inline bool is_equal(const VecBase &a, const VecBase &b, From 5fa694ffe1cd856177ccfb5ca75cc67d1db9dcec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Fri, 6 Jan 2023 21:59:14 +0100 Subject: [PATCH 0488/1522] Cleanup: BLI: Remove BLI_ENABLE_IF((is_math_float_type)) from vector API This was limiting the use of the templates with other non internal types. --- source/blender/blenlib/BLI_math_base.hh | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/source/blender/blenlib/BLI_math_base.hh b/source/blender/blenlib/BLI_math_base.hh index d5279dfb3c5..098c53e43d2 100644 --- a/source/blender/blenlib/BLI_math_base.hh +++ b/source/blender/blenlib/BLI_math_base.hh @@ -59,13 +59,12 @@ template inline T clamp(const T &a, const T &min, const T &max) return std::clamp(a, min, max); } -template))> inline T mod(const T &a, const T &b) +template inline T mod(const T &a, const T &b) { return std::fmod(a, b); } -template))> -inline T safe_mod(const T &a, const T &b) +template inline T safe_mod(const T &a, const T &b) { return (b != 0) ? std::fmod(a, b) : 0; } @@ -76,18 +75,17 @@ template inline void min_max(const T &value, T &min, T &max) max = math::max(value, max); } -template))> -inline T safe_divide(const T &a, const T &b) +template inline T safe_divide(const T &a, const T &b) { return (b != 0) ? a / b : T(0.0f); } -template))> inline T floor(const T &a) +template inline T floor(const T &a) { return std::floor(a); } -template))> inline T ceil(const T &a) +template inline T ceil(const T &a) { return std::ceil(a); } @@ -97,7 +95,7 @@ template inline T distance(const T &a, const T &b) return std::abs(a - b); } -template))> inline T fract(const T &a) +template inline T fract(const T &a) { return a - std::floor(a); } @@ -147,10 +145,7 @@ template inline T hypot(const T &y, const T &x) return std::hypot(y, x); } -template)), - BLI_ENABLE_IF((is_math_float_type))> +template inline T interpolate(const T &a, const T &b, const FactorT &t) { auto result = a * (1 - t) + b * t; From 01efcb3de2b56cf581750d6321beb1a5eb6dcab6 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Fri, 6 Jan 2023 16:29:48 -0500 Subject: [PATCH 0489/1522] Update RNA to User manual mappings --- release/scripts/modules/rna_manual_reference.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index 7dc62e6270b..28091e119cb 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -1342,7 +1342,7 @@ url_manual_mapping = ( ("bpy.types.armature.layers_protected*", "animation/armatures/properties/skeleton.html#bpy-types-armature-layers-protected"), ("bpy.types.assetmetadata.description*", "editors/asset_browser.html#bpy-types-assetmetadata-description"), ("bpy.types.bakesettings.normal_space*", "render/cycles/baking.html#bpy-types-bakesettings-normal-space"), - ("bpy.types.brush.crease_pinch_factor*", "sculpt_paint/sculpting/tools/snake_hook.html#bpy-types-brush-crease-pinch-factor"), + ("bpy.types.brush.crease_pinch_factor*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-crease-pinch-factor"), ("bpy.types.brush.elastic_deform_type*", "sculpt_paint/sculpting/tools/elastic_deform.html#bpy-types-brush-elastic-deform-type"), ("bpy.types.brush.texture_sample_bias*", "sculpt_paint/brush/texture.html#bpy-types-brush-texture-sample-bias"), ("bpy.types.brush.use_cloth_collision*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-use-cloth-collision"), @@ -1468,6 +1468,7 @@ url_manual_mapping = ( ("bpy.types.bakesettings.cage_object*", "render/cycles/baking.html#bpy-types-bakesettings-cage-object"), ("bpy.types.bakesettings.margin_type*", "render/cycles/baking.html#bpy-types-bakesettings-margin-type"), ("bpy.types.bone.use_relative_parent*", "animation/armatures/bones/properties/relations.html#bpy-types-bone-use-relative-parent"), + ("bpy.types.brush.area_radius_factor*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-area-radius-factor"), ("bpy.types.brush.auto_smooth_factor*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-auto-smooth-factor"), ("bpy.types.brush.smooth_deform_type*", "sculpt_paint/sculpting/tools/smooth.html#bpy-types-brush-smooth-deform-type"), ("bpy.types.brush.use_connected_only*", "sculpt_paint/sculpting/tools/pose.html#bpy-types-brush-use-connected-only"), @@ -1781,6 +1782,7 @@ url_manual_mapping = ( ("bpy.types.functionnodefloattoint*", "modeling/geometry_nodes/utilities/float_to_integer.html#bpy-types-functionnodefloattoint"), ("bpy.types.functionnodeinputcolor*", "modeling/geometry_nodes/input/color.html#bpy-types-functionnodeinputcolor"), ("bpy.types.geometrynodeconvexhull*", "modeling/geometry_nodes/geometry/convex_hull.html#bpy-types-geometrynodeconvexhull"), + ("bpy.types.geometrynodeimageinput*", "modeling/geometry_nodes/input/image_input.html#bpy-types-geometrynodeimageinput"), ("bpy.types.geometrynodeinputindex*", "modeling/geometry_nodes/input/input_index.html#bpy-types-geometrynodeinputindex"), ("bpy.types.geometrynodeisviewport*", "modeling/geometry_nodes/input/is_viewport.html#bpy-types-geometrynodeisviewport"), ("bpy.types.geometrynodemeshcircle*", "modeling/geometry_nodes/mesh_primitives/mesh_circle.html#bpy-types-geometrynodemeshcircle"), @@ -2172,10 +2174,11 @@ url_manual_mapping = ( ("bpy.types.bakesettings.margin*", "render/cycles/baking.html#bpy-types-bakesettings-margin"), ("bpy.types.bakesettings.target*", "render/cycles/baking.html#bpy-types-bakesettings-target"), ("bpy.types.brush.cloth_damping*", "sculpt_paint/sculpting/tools/cloth.html#bpy-types-brush-cloth-damping"), + ("bpy.types.brush.deform_target*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-deform-target"), ("bpy.types.brush.falloff_shape*", "sculpt_paint/brush/falloff.html#bpy-types-brush-falloff-shape"), ("bpy.types.brush.icon_filepath*", "sculpt_paint/brush/brush.html#bpy-types-brush-icon-filepath"), ("bpy.types.brush.stroke_method*", "sculpt_paint/brush/stroke.html#bpy-types-brush-stroke-method"), - ("bpy.types.brush.tip_roundness*", "sculpt_paint/sculpting/tools/clay_strips.html#bpy-types-brush-tip-roundness"), + ("bpy.types.brush.tip_roundness*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-tip-roundness"), ("bpy.types.camera.display_size*", "render/cameras.html#bpy-types-camera-display-size"), ("bpy.types.camera.sensor_width*", "render/cameras.html#bpy-types-camera-sensor-width"), ("bpy.types.compositornodedblur*", "compositing/types/filter/directional_blur.html#bpy-types-compositornodedblur"), @@ -2705,6 +2708,7 @@ url_manual_mapping = ( ("bpy.types.armature.rigify*", "addons/rigging/rigify/basics.html#bpy-types-armature-rigify"), ("bpy.types.bone.use_deform*", "animation/armatures/bones/properties/deform.html#bpy-types-bone-use-deform"), ("bpy.types.booleanmodifier*", "modeling/modifiers/generate/booleans.html#bpy-types-booleanmodifier"), + ("bpy.types.brush.direction*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-direction"), ("bpy.types.brush.mask_tool*", "sculpt_paint/sculpting/tools/mask.html#bpy-types-brush-mask-tool"), ("bpy.types.constraint.mute*", "animation/constraints/interface/header.html#bpy-types-constraint-mute"), ("bpy.types.constraint.name*", "animation/constraints/interface/header.html#bpy-types-constraint-name"), @@ -2798,6 +2802,7 @@ url_manual_mapping = ( ("bpy.ops.wm.save_mainfile*", "files/blend/open_save.html#bpy-ops-wm-save-mainfile"), ("bpy.types.bone.show_wire*", "animation/armatures/bones/properties/display.html#bpy-types-bone-show-wire"), ("bpy.types.brush.hardness*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-hardness"), + ("bpy.types.brush.strength*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-strength"), ("bpy.types.curves.surface*", "modeling/curves/primitives.html#bpy-types-curves-surface"), ("bpy.types.curvesmodifier*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-curvesmodifier"), ("bpy.types.ffmpegsettings*", "render/output/properties/output.html#bpy-types-ffmpegsettings"), @@ -3111,6 +3116,7 @@ url_manual_mapping = ( ("bpy.types.bonegroups*", "animation/armatures/properties/bone_groups.html#bpy-types-bonegroups"), ("bpy.types.bpy_struct*", "files/data_blocks.html#bpy-types-bpy-struct"), ("bpy.types.brush.rate*", "sculpt_paint/brush/stroke.html#bpy-types-brush-rate"), + ("bpy.types.brush.size*", "sculpt_paint/brush/brush_settings.html#bpy-types-brush-size"), ("bpy.types.collection*", "scene_layout/collections/collections.html#bpy-types-collection"), ("bpy.types.compositor*", "compositing/index.html#bpy-types-compositor"), ("bpy.types.constraint*", "animation/constraints/index.html#bpy-types-constraint"), From e756b0fea08c315eb8bea67b3fbb7c34874e9728 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 6 Jan 2023 22:23:53 +0100 Subject: [PATCH 0490/1522] Cleanup: remove dead code --- .../blender/functions/FN_multi_function_context.hh | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/source/blender/functions/FN_multi_function_context.hh b/source/blender/functions/FN_multi_function_context.hh index af5efb4cf88..7452bfced3b 100644 --- a/source/blender/functions/FN_multi_function_context.hh +++ b/source/blender/functions/FN_multi_function_context.hh @@ -22,15 +22,9 @@ class MFContext; class MFContextBuilder { private: - Map global_contexts_; - friend MFContext; public: - template void add_global_context(std::string name, const T *context) - { - global_contexts_.add_new(std::move(name), static_cast(context)); - } }; class MFContext { @@ -41,13 +35,6 @@ class MFContext { MFContext(MFContextBuilder &builder) : builder_(builder) { } - - template const T *get_global_context(StringRef name) const - { - const void *context = builder_.global_contexts_.lookup_default_as(name, nullptr); - /* TODO: Implement type checking. */ - return static_cast(context); - } }; } // namespace blender::fn From f7e9bc65abf66f80a0efaef1d98ad58c2c278123 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 6 Jan 2023 22:30:02 +0100 Subject: [PATCH 0491/1522] Cleanup: simplify getting value of generic ValueOrField --- source/blender/functions/FN_field_cpp_type.hh | 8 ++++---- source/blender/functions/FN_field_cpp_type_make.hh | 3 --- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/source/blender/functions/FN_field_cpp_type.hh b/source/blender/functions/FN_field_cpp_type.hh index cbb2a576272..dcb9efcd4f0 100644 --- a/source/blender/functions/FN_field_cpp_type.hh +++ b/source/blender/functions/FN_field_cpp_type.hh @@ -17,7 +17,6 @@ class ValueOrFieldCPPType { private: void (*construct_from_value_)(void *dst, const void *value); void (*construct_from_field_)(void *dst, GField field); - const void *(*get_value_ptr_)(const void *value_or_field); const GField *(*get_field_ptr_)(const void *value_or_field); bool (*is_field_)(const void *value_or_field); GField (*as_field_)(const void *value_or_field); @@ -42,13 +41,14 @@ class ValueOrFieldCPPType { const void *get_value_ptr(const void *value_or_field) const { - return get_value_ptr_(value_or_field); + static_assert(offsetof(ValueOrField, value) == 0); + return value_or_field; } void *get_value_ptr(void *value_or_field) const { - /* Use `const_cast` to avoid duplicating the callback for the non-const case. */ - return const_cast(get_value_ptr_(value_or_field)); + static_assert(offsetof(ValueOrField, value) == 0); + return value_or_field; } const GField *get_field_ptr(const void *value_or_field) const diff --git a/source/blender/functions/FN_field_cpp_type_make.hh b/source/blender/functions/FN_field_cpp_type_make.hh index 7a4112b432b..1ab0f591019 100644 --- a/source/blender/functions/FN_field_cpp_type_make.hh +++ b/source/blender/functions/FN_field_cpp_type_make.hh @@ -17,9 +17,6 @@ inline ValueOrFieldCPPType::ValueOrFieldCPPType(TypeTag /*value_type* construct_from_field_ = [](void *dst, GField field) { new (dst) ValueOrField(Field(std::move(field))); }; - get_value_ptr_ = [](const void *value_or_field) { - return (const void *)&((ValueOrField *)value_or_field)->value; - }; get_field_ptr_ = [](const void *value_or_field) -> const GField * { return &((ValueOrField *)value_or_field)->field; }; From 125b2835897df83adb57271ed374e42d395a744a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Fri, 6 Jan 2023 22:22:11 +0100 Subject: [PATCH 0492/1522] GPU: Add Math libraries to GPU shaders code This implement most of the functions provided by the BLI math library. This is part of the effort to unify GLSL and C++ syntax. Ref T103026. This also adds some infrastructure to make it possible to run GLSL shader unit test. Some code already present in other libs is being copied to the new libs. This patch does not make use of the new libs outside of the tests. Note that the test is still crashing when using metal. --- .../blender/blenlib/BLI_math_matrix_types.hh | 2 + .../draw/intern/shaders/common_math_lib.glsl | 7 +- source/blender/gpu/CMakeLists.txt | 10 + source/blender/gpu/GPU_shader_shared.h | 65 + source/blender/gpu/GPU_shader_shared_utils.h | 4 +- .../common/gpu_shader_math_base_lib.glsl | 152 ++ .../common/gpu_shader_math_fast_lib.glsl | 32 + .../common/gpu_shader_math_matrix_lib.glsl | 1527 +++++++++++++++++ .../common/gpu_shader_math_rotation_lib.glsl | 186 ++ .../common/gpu_shader_math_vector_lib.glsl | 535 ++++++ .../shaders/common/gpu_shader_test_lib.glsl | 214 +++ .../common/gpu_shader_utildefines_lib.glsl | 96 ++ .../gpu/shaders/infos/gpu_shader_test_info.hh | 19 + source/blender/gpu/tests/gpu_math_test.glsl | 290 ++++ source/blender/gpu/tests/gpu_shader_test.cc | 210 +++ 15 files changed, 3346 insertions(+), 3 deletions(-) create mode 100644 source/blender/gpu/shaders/common/gpu_shader_math_base_lib.glsl create mode 100644 source/blender/gpu/shaders/common/gpu_shader_math_fast_lib.glsl create mode 100644 source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl create mode 100644 source/blender/gpu/shaders/common/gpu_shader_math_rotation_lib.glsl create mode 100644 source/blender/gpu/shaders/common/gpu_shader_math_vector_lib.glsl create mode 100644 source/blender/gpu/shaders/common/gpu_shader_test_lib.glsl create mode 100644 source/blender/gpu/shaders/common/gpu_shader_utildefines_lib.glsl create mode 100644 source/blender/gpu/shaders/infos/gpu_shader_test_info.hh create mode 100644 source/blender/gpu/tests/gpu_math_test.glsl diff --git a/source/blender/blenlib/BLI_math_matrix_types.hh b/source/blender/blenlib/BLI_math_matrix_types.hh index 1505452da22..bc102a5cf7f 100644 --- a/source/blender/blenlib/BLI_math_matrix_types.hh +++ b/source/blender/blenlib/BLI_math_matrix_types.hh @@ -30,6 +30,8 @@ * defined outside of the class in the `blender::math` namespace. */ +#define __BLI_MATH_MATRIX_TYPES_HH__ + #include #include #include diff --git a/source/blender/draw/intern/shaders/common_math_lib.glsl b/source/blender/draw/intern/shaders/common_math_lib.glsl index 5842df424be..4846d81f6f1 100644 --- a/source/blender/draw/intern/shaders/common_math_lib.glsl +++ b/source/blender/draw/intern/shaders/common_math_lib.glsl @@ -16,8 +16,11 @@ #define M_1_PI2 0.101321183642337771443 /* 1/(pi^2) */ #define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ #define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ -#define FLT_MAX 3.402823e+38 -#define FLT_MIN 1.175494e-38 +#ifndef FLT_MAX +# define FLT_MAX 3.402823e+38 +# define FLT_MIN 1.175494e-38 +# define FLT_EPSILON 1.192092896e-07F +#endif vec3 mul(mat3 m, vec3 v) { diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 02793fa74be..f93317cdc28 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -388,6 +388,13 @@ set(GLSL_SRC shaders/common/gpu_shader_common_math.glsl shaders/common/gpu_shader_common_math_utils.glsl shaders/common/gpu_shader_common_mix_rgb.glsl + shaders/common/gpu_shader_math_base_lib.glsl + shaders/common/gpu_shader_math_fast_lib.glsl + shaders/common/gpu_shader_math_matrix_lib.glsl + shaders/common/gpu_shader_math_rotation_lib.glsl + shaders/common/gpu_shader_math_vector_lib.glsl + shaders/common/gpu_shader_test_lib.glsl + shaders/common/gpu_shader_utildefines_lib.glsl shaders/material/gpu_shader_material_add_shader.glsl shaders/material/gpu_shader_material_ambient_occlusion.glsl @@ -484,6 +491,8 @@ set(GLSL_SRC shaders/gpu_shader_cfg_world_clip_lib.glsl shaders/gpu_shader_colorspace_lib.glsl + tests/gpu_math_test.glsl + GPU_shader_shared_utils.h ) @@ -625,6 +634,7 @@ set(SRC_SHADER_CREATE_INFOS shaders/infos/gpu_shader_keyframe_shape_info.hh shaders/infos/gpu_shader_line_dashed_uniform_color_info.hh shaders/infos/gpu_shader_simple_lighting_info.hh + shaders/infos/gpu_shader_test_info.hh shaders/infos/gpu_shader_text_info.hh shaders/infos/gpu_srgb_to_framebuffer_space_info.hh ) diff --git a/source/blender/gpu/GPU_shader_shared.h b/source/blender/gpu/GPU_shader_shared.h index 2291de74782..4fb321ce502 100644 --- a/source/blender/gpu/GPU_shader_shared.h +++ b/source/blender/gpu/GPU_shader_shared.h @@ -7,6 +7,8 @@ #ifndef USE_GPU_SHADER_CREATE_INFO # include "GPU_shader_shared_utils.h" + +typedef struct TestOutputRawData TestOutputRawData; #endif struct NodeLinkData { @@ -66,3 +68,66 @@ struct MultiRectCallData { float4 calls_data[MAX_CALLS * 3]; }; BLI_STATIC_ASSERT_ALIGN(struct MultiRectCallData, 16) + +enum TestStatus { + TEST_STATUS_NONE = 0, + TEST_STATUS_PASSED = 1, + TEST_STATUS_FAILED = 2, +}; +enum TestType { + TEST_TYPE_BOOL = 0, + TEST_TYPE_UINT = 1, + TEST_TYPE_INT = 2, + TEST_TYPE_FLOAT = 3, + TEST_TYPE_IVEC2 = 4, + TEST_TYPE_IVEC3 = 5, + TEST_TYPE_IVEC4 = 6, + TEST_TYPE_UVEC2 = 7, + TEST_TYPE_UVEC3 = 8, + TEST_TYPE_UVEC4 = 9, + TEST_TYPE_VEC2 = 10, + TEST_TYPE_VEC3 = 11, + TEST_TYPE_VEC4 = 12, + TEST_TYPE_MAT2X2 = 13, + TEST_TYPE_MAT2X3 = 14, + TEST_TYPE_MAT2X4 = 15, + TEST_TYPE_MAT3X2 = 16, + TEST_TYPE_MAT3X3 = 17, + TEST_TYPE_MAT3X4 = 18, + TEST_TYPE_MAT4X2 = 19, + TEST_TYPE_MAT4X3 = 20, + TEST_TYPE_MAT4X4 = 21, +}; + +/** \note Contains arrays of scalar. To be use only with SSBOs to avoid padding issues. */ +struct TestOutputRawData { + uint data[16]; +}; +BLI_STATIC_ASSERT_ALIGN(struct TestOutputRawData, 16) + +struct TestOutput { + TestOutputRawData expect; + TestOutputRawData result; + /** TestStatus. */ + uint status; + /** Line error in the glsl file. */ + int line; + /** TestType of expect and result. */ + uint type; + int _pad0; +}; +BLI_STATIC_ASSERT_ALIGN(struct TestOutput, 16) + +#ifdef GPU_SHADER +TestOutput test_output( + TestOutputRawData expect, TestOutputRawData result, bool status, int line, uint type) +{ + TestOutput test; + test.expect = expect; + test.result = result; + test.status = status ? TEST_STATUS_PASSED : TEST_STATUS_FAILED; + test.line = line; + test.type = type; + return test; +} +#endif diff --git a/source/blender/gpu/GPU_shader_shared_utils.h b/source/blender/gpu/GPU_shader_shared_utils.h index 9c92da425f6..1649d1ca123 100644 --- a/source/blender/gpu/GPU_shader_shared_utils.h +++ b/source/blender/gpu/GPU_shader_shared_utils.h @@ -67,7 +67,9 @@ # include "BLI_assert.h" # ifdef __cplusplus -# include "BLI_float4x4.hh" +# ifndef __BLI_MATH_MATRIX_TYPES_HH__ +# include "BLI_float4x4.hh" +# endif # include "BLI_math_vector_types.hh" using blender::float2; using blender::float3; diff --git a/source/blender/gpu/shaders/common/gpu_shader_math_base_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_math_base_lib.glsl new file mode 100644 index 00000000000..3754c79ca21 --- /dev/null +++ b/source/blender/gpu/shaders/common/gpu_shader_math_base_lib.glsl @@ -0,0 +1,152 @@ + +/* WORKAROUND: to guard against double include in EEVEE. */ +#ifndef GPU_SHADER_MATH_BASE_LIB_GLSL +#define GPU_SHADER_MATH_BASE_LIB_GLSL + +#define M_PI 3.14159265358979323846 /* pi */ +#define M_TAU 6.28318530717958647692 /* tau = 2*pi */ +#define M_PI_2 1.57079632679489661923 /* pi/2 */ +#define M_PI_4 0.78539816339744830962 /* pi/4 */ +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ +#define M_SQRT3 1.73205080756887729352 /* sqrt(3) */ +#define M_SQRT1_3 0.57735026918962576450 /* 1/sqrt(3) */ +#define M_1_PI 0.318309886183790671538 /* 1/pi */ +#define M_E 2.7182818284590452354 /* e */ +#define M_LOG2E 1.4426950408889634074 /* log_2 e */ +#define M_LOG10E 0.43429448190325182765 /* log_10 e */ +#define M_LN2 0.69314718055994530942 /* log_e 2 */ +#define M_LN10 2.30258509299404568402 /* log_e 10 */ + +/* `powf` is really slow for raising to integer powers. */ + +float pow2f(float x) +{ + return x * x; +} +float pow3f(float x) +{ + return x * x * x; +} +float pow4f(float x) +{ + return pow2f(pow2f(x)); +} +float pow5f(float x) +{ + return pow4f(x) * x; +} +float pow6f(float x) +{ + return pow2f(pow3f(x)); +} +float pow7f(float x) +{ + return pow6f(x) * x; +} +float pow8f(float x) +{ + return pow2f(pow4f(x)); +} + +int square_i(int v) +{ + return v * v; +} +uint square_uint(uint v) +{ + return v * v; +} +float square_f(float v) +{ + return v * v; +} + +int cube_i(int v) +{ + return v * v * v; +} +uint cube_uint(uint v) +{ + return v * v * v; +} +float cube_f(float v) +{ + return v * v * v; +} + +float hypot(float x, float y) +{ + return sqrt(x * x + y * y); +} + +float atan2(float y, float x) +{ + return atan(y, x); +} + +/** + * Safe `a` modulo `b`. + * If `b` equal 0 the result will be 0. + */ +float safe_mod(float a, float b) +{ + return (b != 0.0) ? mod(a, b) : 0.0; +} + +/** + * Returns \a a if it is a multiple of \a b or the next multiple or \a b after \b a . + * In other words, it is equivalent to `divide_ceil(a, b) * b`. + * It is undefined if \a a is negative or \b b is not strictly positive. + */ +int ceil_to_multiple(int a, int b) +{ + return ((a + b - 1) / b) * b; +} +uint ceil_to_multiple(uint a, uint b) +{ + return ((a + b - 1u) / b) * b; +} + +/** + * Integer division that returns the ceiling, instead of flooring like normal C division. + * It is undefined if \a a is negative or \b b is not strictly positive. + */ +int divide_ceil(int a, int b) +{ + return (a + b - 1) / b; +} +uint divide_ceil(uint a, uint b) +{ + return (a + b - 1u) / b; +} + +/** + * Component wise, use vector to replace min if it is smaller and max if bigger. + */ +void min_max(float value, inout float min_v, inout float max_v) +{ + min_v = min(value, min_v); + max_v = max(value, max_v); +} + +/** + * Safe divide `a` by `b`. + * If `b` equal 0 the result will be 0. + */ +float safe_divide(float a, float b) +{ + return (b != 0.0) ? (a / b) : 0.0; +} + +/** + * Return true if the difference between`a` and `b` is below the `epsilon` value. + */ +bool is_equal(float a, float b, const float epsilon) +{ + return abs(a - b) <= epsilon; +} + +/** \} */ + +#endif /* GPU_SHADER_MATH_BASE_LIB_GLSL */ diff --git a/source/blender/gpu/shaders/common/gpu_shader_math_fast_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_math_fast_lib.glsl new file mode 100644 index 00000000000..6f5829bd78e --- /dev/null +++ b/source/blender/gpu/shaders/common/gpu_shader_math_fast_lib.glsl @@ -0,0 +1,32 @@ + +/* WORKAROUND: to guard against double include in EEVEE. */ +#ifndef GPU_SHADER_MATH_FAST_LIB_GLSL +#define GPU_SHADER_MATH_FAST_LIB_GLSL + +/* [Drobot2014a] Low Level Optimizations for GCN. */ +float sqrt_fast(float v) +{ + return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); +} +vec2 sqrt_fast(vec2 v) +{ + return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1)); +} + +/* [Eberly2014] GPGPU Programming for Games and Science. */ +float acos_fast(float v) +{ + float res = -0.156583 * abs(v) + M_PI_2; + res *= sqrt_fast(1.0 - abs(v)); + return (v >= 0) ? res : M_PI - res; +} +vec2 acos_fast(vec2 v) +{ + vec2 res = -0.156583 * abs(v) + M_PI_2; + res *= sqrt_fast(1.0 - abs(v)); + v.x = (v.x >= 0) ? res.x : M_PI - res.x; + v.y = (v.y >= 0) ? res.y : M_PI - res.y; + return v; +} + +#endif /* GPU_SHADER_MATH_FAST_LIB_GLSL */ diff --git a/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl new file mode 100644 index 00000000000..0363a64d5c5 --- /dev/null +++ b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl @@ -0,0 +1,1527 @@ + +#pragma BLENDER_REQUIRE(gpu_shader_math_vector_lib.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_math_rotation_lib.glsl) + +/* WORKAROUND: to guard against double include in EEVEE. */ +#ifndef GPU_SHADER_MATH_MATRIX_LIB_GLSL +# define GPU_SHADER_MATH_MATRIX_LIB_GLSL + +/* -------------------------------------------------------------------- */ +/** \name Static constructors + * \{ */ + +mat2x2 mat2x2__diagonal(float v) +{ + return mat2x2(vec2(v, 0.0), vec2(0.0, v)); +} +mat3x3 mat3x3__diagonal(float v) +{ + return mat3x3(vec3(v, 0.0, 0.0), vec3(0.0, v, 0.0), vec3(0.0, 0.0, v)); +} +mat4x4 mat4x4__diagonal(float v) +{ + return mat4x4(vec4(v, 0.0, 0.0, 0.0), + vec4(0.0, v, 0.0, 0.0), + vec4(0.0, 0.0, v, 0.0), + vec4(0.0, 0.0, 0.0, v)); +} + +mat2x2 mat2x2__all(float v) +{ + return mat2x2(vec2(v), vec2(v)); +} +mat3x3 mat3x3__all(float v) +{ + return mat3x3(vec3(v), vec3(v), vec3(v)); +} +mat4x4 mat4x4__all(float v) +{ + return mat4x4(vec4(v), vec4(v), vec4(v), vec4(v)); +} + +mat2x2 mat2x2__zero(float v) +{ + return mat2x2__all(0.0); +} +mat3x3 mat3x3__zero(float v) +{ + return mat3x3__all(0.0); +} +mat4x4 mat4x4__zero(float v) +{ + return mat4x4__all(0.0); +} + +mat2x2 mat2x2__identity() +{ + return mat2x2__diagonal(1.0); +} +mat3x3 mat3x3__identity() +{ + return mat3x3__diagonal(1.0); +} +mat4x4 mat4x4__identity() +{ + return mat4x4__diagonal(1.0); +} + +/** \} */ + +/* Metal does not need prototypes. */ +# ifndef GPU_METAL + +/* -------------------------------------------------------------------- */ +/** \name Matrix Operations + * \{ */ + +/** + * Returns the inverse of a square matrix or zero matrix on failure. + * \a r_success is optional and set to true if the matrix was inverted successfully. + */ +mat2x2 invert(mat2x2 mat); +mat3x3 invert(mat3x3 mat); +mat4x4 invert(mat4x4 mat); + +mat2x2 invert(mat2x2 mat, out bool r_success); +mat3x3 invert(mat3x3 mat, out bool r_success); +mat4x4 invert(mat4x4 mat, out bool r_success); + +/** + * Flip the matrix across its diagonal. Also flips dimensions for non square matrices. + */ +// mat3x3 transpose(mat3x3 mat); /* Built-In in GLSL language. */ + +/** + * Normalize each column of the matrix individually. + */ +mat2x2 normalize(mat2x2 mat); +mat2x3 normalize(mat2x3 mat); +mat2x4 normalize(mat2x4 mat); +mat3x2 normalize(mat3x2 mat); +mat3x3 normalize(mat3x3 mat); +mat3x4 normalize(mat3x4 mat); +mat4x2 normalize(mat4x2 mat); +mat4x3 normalize(mat4x3 mat); +mat4x4 normalize(mat4x4 mat); + +/** + * Normalize each column of the matrix individually. + * Return the length of each column vector. + */ +mat2x2 normalize_and_get_size(mat2x2 mat, out vec2 r_size); +mat2x3 normalize_and_get_size(mat2x3 mat, out vec2 r_size); +mat2x4 normalize_and_get_size(mat2x4 mat, out vec2 r_size); +mat3x2 normalize_and_get_size(mat3x2 mat, out vec3 r_size); +mat3x3 normalize_and_get_size(mat3x3 mat, out vec3 r_size); +mat3x4 normalize_and_get_size(mat3x4 mat, out vec3 r_size); +mat4x2 normalize_and_get_size(mat4x2 mat, out vec4 r_size); +mat4x3 normalize_and_get_size(mat4x3 mat, out vec4 r_size); +mat4x4 normalize_and_get_size(mat4x4 mat, out vec4 r_size); + +/** + * Returns the determinant of the matrix. + * It can be interpreted as the signed volume (or area) of the unit cube after transformation. + */ +// float determinant(mat3x3 mat); /* Built-In in GLSL language. */ + +/** + * Returns the adjoint of the matrix (also known as adjugate matrix). + */ +mat2x2 adjoint(mat2x2 mat); +mat3x3 adjoint(mat3x3 mat); +mat4x4 adjoint(mat4x4 mat); + +/** + * Equivalent to `mat * from_location(translation)` but with fewer operation. + */ +mat4x4 translate(mat4x4 mat, vec2 translation); +mat4x4 translate(mat4x4 mat, vec3 translation); + +/** + * Equivalent to `mat * from_rotation(rotation)` but with fewer operation. + * Optimized for rotation on basis vector (i.e: AxisAngle({1, 0, 0}, 0.2)). + */ +mat3x3 rotate(mat3x3 mat, AxisAngle rotation); +mat3x3 rotate(mat3x3 mat, EulerXYZ rotation); +mat4x4 rotate(mat4x4 mat, AxisAngle rotation); +mat4x4 rotate(mat4x4 mat, EulerXYZ rotation); + +/** + * Equivalent to `mat * from_scale(scale)` but with fewer operation. + */ +mat3x3 scale(mat3x3 mat, vec2 scale); +mat3x3 scale(mat3x3 mat, vec3 scale); +mat4x4 scale(mat4x4 mat, vec2 scale); +mat4x4 scale(mat4x4 mat, vec3 scale); + +/** + * Interpolate each component linearly. + */ +// mat4x4 interpolate_linear(mat4x4 a, mat4x4 b, float t); /* TODO. */ + +/** + * A polar-decomposition-based interpolation between matrix A and matrix B. + */ +// mat3x3 interpolate(mat3x3 a, mat3x3 b, float t); /* Not implemented. Too complex to port. */ + +/** + * Naive interpolation implementation, faster than polar decomposition + * + * \note This code is about five times faster than the polar decomposition. + * However, it gives un-expected results even with non-uniformly scaled matrices, + * see T46418 for an example. + * + * \param A: Input matrix which is totally effective with `t = 0.0`. + * \param B: Input matrix which is totally effective with `t = 1.0`. + * \param t: Interpolation factor. + */ +mat3x3 interpolate_fast(mat3x3 a, mat3x3 b, float t); + +/** + * Naive transform matrix interpolation, + * based on naive-decomposition-based interpolation from #interpolate_fast. + */ +mat4x4 interpolate_fast(mat4x4 a, mat4x4 b, float t); + +/** + * Compute Moore-Penrose pseudo inverse of matrix. + * Singular values below epsilon are ignored for stability (truncated SVD). + */ +// mat4x4 pseudo_invert(mat4x4 mat, float epsilon); /* Not implemented. Too complex to port. */ + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Init helpers. + * \{ */ + +/** + * Create a translation only matrix. Matrix dimensions should be at least 4 col x 3 row. + */ +mat4x4 from_location(vec3 location); + +/** + * Create a matrix whose diagonal is defined by the given scale vector. + */ +mat2x2 from_scale(vec2 scale); +mat3x3 from_scale(vec3 scale); +mat4x4 from_scale(vec4 scale); + +/** + * Create a rotation only matrix. + */ +mat2x2 from_rotation(Angle rotation); +mat3x3 from_rotation(EulerXYZ rotation); +mat3x3 from_rotation(Quaternion rotation); +mat3x3 from_rotation(AxisAngle rotation); + +/** + * Create a transform matrix with rotation and scale applied in this order. + */ +mat3x3 from_rot_scale(EulerXYZ rotation, vec3 scale); + +/** + * Create a transform matrix with translation and rotation applied in this order. + */ +mat4x4 from_loc_rot(vec3 location, EulerXYZ rotation); + +/** + * Create a transform matrix with translation, rotation and scale applied in this order. + */ +mat4x4 from_loc_rot_scale(vec3 location, EulerXYZ rotation, vec3 scale); + +/** + * Create a rotation matrix from 2 basis vectors. + * The matrix determinant is given to be positive and it can be converted to other rotation types. + * \note `forward` and `up` must be normalized. + */ +// mat3x3 from_normalized_axis_data(vec3 forward, vec3 up); /* TODO. */ + +/** + * Create a transform matrix with translation and rotation from 2 basis vectors and a translation. + * \note `forward` and `up` must be normalized. + */ +// mat4x4 from_normalized_axis_data(vec3 location, vec3 forward, vec3 up); /* TODO. */ + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Conversion function. + * \{ */ + +/** + * Extract euler rotation from transform matrix. + * \return the rotation with the smallest values from the potential candidates. + */ +EulerXYZ to_euler(mat3x3 mat); +EulerXYZ to_euler(mat3x3 mat, const bool normalized); +EulerXYZ to_euler(mat4x4 mat); +EulerXYZ to_euler(mat4x4 mat, const bool normalized); + +/** + * Extract quaternion rotation from transform matrix. + * \note normalized is set to false by default. + */ +Quaternion to_quaternion(mat3x3 mat); +Quaternion to_quaternion(mat3x3 mat, const bool normalized); +Quaternion to_quaternion(mat4x4 mat); +Quaternion to_quaternion(mat4x4 mat, const bool normalized); + +/** + * Extract the absolute 3d scale from a transform matrix. + */ +vec3 to_scale(mat3x3 mat); +vec3 to_scale(mat3x3 mat, const bool allow_negative_scale); +vec3 to_scale(mat4x4 mat); +vec3 to_scale(mat4x4 mat, const bool allow_negative_scale); + +/** + * Decompose a matrix into location, rotation, and scale components. + * \tparam allow_negative_scale if true, will compute determinant to know if matrix is negative. + * Rotation and scale values will be flipped if it is negative. + * This is a costly operation so it is disabled by default. + */ +void to_rot_scale(mat3x3 mat, out EulerXYZ r_rotation, out vec3 r_scale); +void to_rot_scale(mat3x3 mat, out Quaternion r_rotation, out vec3 r_scale); +void to_rot_scale(mat3x3 mat, out AxisAngle r_rotation, out vec3 r_scale); +void to_loc_rot_scale(mat4x4 mat, out vec3 r_location, out EulerXYZ r_rotation, out vec3 r_scale); +void to_loc_rot_scale(mat4x4 mat, + out vec3 r_location, + out Quaternion r_rotation, + out vec3 r_scale); +void to_loc_rot_scale(mat4x4 mat, out vec3 r_location, out AxisAngle r_rotation, out vec3 r_scale); + +void to_rot_scale(mat3x3 mat, + out EulerXYZ r_rotation, + out vec3 r_scale, + const bool allow_negative_scale); +void to_rot_scale(mat3x3 mat, + out Quaternion r_rotation, + out vec3 r_scale, + const bool allow_negative_scale); +void to_rot_scale(mat3x3 mat, + out AxisAngle r_rotation, + out vec3 r_scale, + const bool allow_negative_scale); +void to_loc_rot_scale(mat4x4 mat, + out vec3 r_location, + out EulerXYZ r_rotation, + out vec3 r_scale, + const bool allow_negative_scale); +void to_loc_rot_scale(mat4x4 mat, + out vec3 r_location, + out Quaternion r_rotation, + out vec3 r_scale, + const bool allow_negative_scale); +void to_loc_rot_scale(mat4x4 mat, + out vec3 r_location, + out AxisAngle r_rotation, + out vec3 r_scale, + const bool allow_negative_scale); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Transform function. + * \{ */ + +/** + * Transform a 3d point using a 3x3 matrix (rotation & scale). + */ +vec3 transform_point(mat3x3 mat, vec3 point); + +/** + * Transform a 3d point using a 4x4 matrix (location & rotation & scale). + */ +vec3 transform_point(mat4x4 mat, vec3 point); + +/** + * Transform a 3d direction vector using a 3x3 matrix (rotation & scale). + */ +vec3 transform_direction(mat3x3 mat, vec3 direction); + +/** + * Transform a 3d direction vector using a 4x4 matrix (rotation & scale). + */ +vec3 transform_direction(mat4x4 mat, vec3 direction); + +/** + * Project a point using a matrix (location & rotation & scale & perspective divide). + */ +vec2 project_point(mat3x3 mat, vec2 point); +vec3 project_point(mat4x4 mat, vec3 point); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Projection Matrices. + * \{ */ + +/** + * \brief Create an orthographic projection matrix using OpenGL coordinate convention: + * Maps each axis range to [-1..1] range for all axes. + * The resulting matrix can be used with either #project_point or #transform_point. + */ +mat4x4 projection__orthographic( + float left, float right, float bottom, float top, float near_clip, float far_clip); + +/** + * \brief Create a perspective projection matrix using OpenGL coordinate convention: + * Maps each axis range to [-1..1] range for all axes. + * `left`, `right`, `bottom`, `top` are frustum side distances at `z=near_clip`. + * The resulting matrix can be used with #project_point. + */ +mat4x4 projection__perspective( + float left, float right, float bottom, float top, float near_clip, float far_clip); + +/** + * \brief Create a perspective projection matrix using OpenGL coordinate convention: + * Maps each axis range to [-1..1] range for all axes. + * Uses field of view angles instead of plane distances. + * The resulting matrix can be used with #project_point. + */ +mat4x4 projection__perspective_fov(float angle_left, + float angle_right, + float angle_bottom, + float angle_top, + float near_clip, + float far_clip); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Compare / Test + * \{ */ + +/** + * Returns true if all of the matrices components are strictly equal to 0. + */ +bool is_zero(mat3x3 a); +bool is_zero(mat4x4 a); + +/** + * Returns true if matrix has inverted handedness. + * + * \note It doesn't use determinant(mat4x4) as only the 3x3 components are needed + * when the matrix is used as a transformation to represent location/scale/rotation. + */ +bool is_negative(mat3x3 mat); +bool is_negative(mat4x4 mat); + +/** + * Returns true if matrices are equal within the given epsilon. + */ +bool is_equal(mat2x2 a, mat2x2 b, float epsilon); +bool is_equal(mat3x3 a, mat3x3 b, float epsilon); +bool is_equal(mat4x4 a, mat4x4 b, float epsilon); + +/** + * Test if the X, Y and Z axes are perpendicular with each other. + */ +bool is_orthogonal(mat3x3 mat); +bool is_orthogonal(mat4x4 mat); + +/** + * Test if the X, Y and Z axes are perpendicular with each other and unit length. + */ +bool is_orthonormal(mat3x3 mat); +bool is_orthonormal(mat4x4 mat); + +/** + * Test if the X, Y and Z axes are perpendicular with each other and the same length. + */ +bool is_uniformly_scaled(mat3x3 mat); + +/** \} */ + +# endif /* GPU_METAL */ + +/* ---------------------------------------------------------------------- */ +/** \name Implementation + * \{ */ + +mat2x2 invert(mat2x2 mat) +{ + return inverse(mat); +} +mat3x3 invert(mat3x3 mat) +{ + return inverse(mat); +} +mat4x4 invert(mat4x4 mat) +{ + return inverse(mat); +} + +mat2x2 invert(mat2x2 mat, out bool r_success) +{ + r_success = determinant(mat) != 0.0; + return r_success ? inverse(mat) : mat2x2(0.0); +} +mat3x3 invert(mat3x3 mat, out bool r_success) +{ + r_success = determinant(mat) != 0.0; + return r_success ? inverse(mat) : mat3x3(0.0); +} +mat4x4 invert(mat4x4 mat, out bool r_success) +{ + r_success = determinant(mat) != 0.0; + return r_success ? inverse(mat) : mat4x4(0.0); +} + +# ifdef GPU_METAL +float2 normalize(float2 a) +{ + return a * rsqrt(length_squared(a)); +} +float3 normalize(float3 a) +{ + return a * rsqrt(length_squared(a)); +} +float4 normalize(float4 a) +{ + return a * rsqrt(length_squared(a)); +} +# endif + +mat2x2 normalize(mat2x2 mat) +{ + mat2x2 ret; + ret[0] = normalize(mat[0].xy); + ret[1] = normalize(mat[1].xy); + return ret; +} +mat2x3 normalize(mat2x3 mat) +{ + mat2x3 ret; + ret[0] = normalize(mat[0].xyz); + ret[1] = normalize(mat[1].xyz); + return ret; +} +mat2x4 normalize(mat2x4 mat) +{ + mat2x4 ret; + ret[0] = normalize(mat[0].xyzw); + ret[1] = normalize(mat[1].xyzw); + return ret; +} +mat3x2 normalize(mat3x2 mat) +{ + mat3x2 ret; + ret[0] = normalize(mat[0].xy); + ret[1] = normalize(mat[1].xy); + ret[2] = normalize(mat[2].xy); + return ret; +} +mat3x3 normalize(mat3x3 mat) +{ + mat3x3 ret; + ret[0] = normalize(mat[0].xyz); + ret[1] = normalize(mat[1].xyz); + ret[2] = normalize(mat[2].xyz); + return ret; +} +mat3x4 normalize(mat3x4 mat) +{ + mat3x4 ret; + ret[0] = normalize(mat[0].xyzw); + ret[1] = normalize(mat[1].xyzw); + ret[2] = normalize(mat[2].xyzw); + return ret; +} +mat4x2 normalize(mat4x2 mat) +{ + mat4x2 ret; + ret[0] = normalize(mat[0].xy); + ret[1] = normalize(mat[1].xy); + ret[2] = normalize(mat[2].xy); + ret[3] = normalize(mat[3].xy); + return ret; +} +mat4x3 normalize(mat4x3 mat) +{ + mat4x3 ret; + ret[0] = normalize(mat[0].xyz); + ret[1] = normalize(mat[1].xyz); + ret[2] = normalize(mat[2].xyz); + ret[3] = normalize(mat[3].xyz); + return ret; +} +mat4x4 normalize(mat4x4 mat) +{ + mat4x4 ret; + ret[0] = normalize(mat[0].xyzw); + ret[1] = normalize(mat[1].xyzw); + ret[2] = normalize(mat[2].xyzw); + ret[3] = normalize(mat[3].xyzw); + return ret; +} + +mat2x2 normalize_and_get_size(mat2x2 mat, out vec2 r_size) +{ + float size_x, size_y; + mat2x2 ret; + ret[0] = normalize_and_get_length(mat[0], size_x); + ret[1] = normalize_and_get_length(mat[1], size_y); + r_size = vec2(size_x, size_y); + return ret; +} +mat2x3 normalize_and_get_size(mat2x3 mat, out vec2 r_size) +{ + float size_x, size_y; + mat2x3 ret; + ret[0] = normalize_and_get_length(mat[0], size_x); + ret[1] = normalize_and_get_length(mat[1], size_y); + r_size = vec2(size_x, size_y); + return ret; +} +mat2x4 normalize_and_get_size(mat2x4 mat, out vec2 r_size) +{ + float size_x, size_y; + mat2x4 ret; + ret[0] = normalize_and_get_length(mat[0], size_x); + ret[1] = normalize_and_get_length(mat[1], size_y); + r_size = vec2(size_x, size_y); + return ret; +} +mat3x2 normalize_and_get_size(mat3x2 mat, out vec3 r_size) +{ + float size_x, size_y, size_z; + mat3x2 ret; + ret[0] = normalize_and_get_length(mat[0], size_x); + ret[1] = normalize_and_get_length(mat[1], size_y); + ret[2] = normalize_and_get_length(mat[2], size_z); + r_size = vec3(size_x, size_y, size_z); + return ret; +} +mat3x3 normalize_and_get_size(mat3x3 mat, out vec3 r_size) +{ + float size_x, size_y, size_z; + mat3x3 ret; + ret[0] = normalize_and_get_length(mat[0], size_x); + ret[1] = normalize_and_get_length(mat[1], size_y); + ret[2] = normalize_and_get_length(mat[2], size_z); + r_size = vec3(size_x, size_y, size_z); + return ret; +} +mat3x4 normalize_and_get_size(mat3x4 mat, out vec3 r_size) +{ + float size_x, size_y, size_z; + mat3x4 ret; + ret[0] = normalize_and_get_length(mat[0], size_x); + ret[1] = normalize_and_get_length(mat[1], size_y); + ret[2] = normalize_and_get_length(mat[2], size_z); + r_size = vec3(size_x, size_y, size_z); + return ret; +} +mat4x2 normalize_and_get_size(mat4x2 mat, out vec4 r_size) +{ + float size_x, size_y, size_z, size_w; + mat4x2 ret; + ret[0] = normalize_and_get_length(mat[0], size_x); + ret[1] = normalize_and_get_length(mat[1], size_y); + ret[2] = normalize_and_get_length(mat[2], size_z); + ret[3] = normalize_and_get_length(mat[3], size_w); + r_size = vec4(size_x, size_y, size_z, size_w); + return ret; +} +mat4x3 normalize_and_get_size(mat4x3 mat, out vec4 r_size) +{ + float size_x, size_y, size_z, size_w; + mat4x3 ret; + ret[0] = normalize_and_get_length(mat[0], size_x); + ret[1] = normalize_and_get_length(mat[1], size_y); + ret[2] = normalize_and_get_length(mat[2], size_z); + ret[3] = normalize_and_get_length(mat[3], size_w); + r_size = vec4(size_x, size_y, size_z, size_w); + return ret; +} +mat4x4 normalize_and_get_size(mat4x4 mat, out vec4 r_size) +{ + float size_x, size_y, size_z, size_w; + mat4x4 ret; + ret[0] = normalize_and_get_length(mat[0], size_x); + ret[1] = normalize_and_get_length(mat[1], size_y); + ret[2] = normalize_and_get_length(mat[2], size_z); + ret[3] = normalize_and_get_length(mat[3], size_w); + r_size = vec4(size_x, size_y, size_z, size_w); + return ret; +} + +mat2x2 adjoint(mat2x2 mat) +{ + mat2x2 adj; + for (int c = 0; c < 2; c++) { + for (int r = 0; r < 2; r++) { + /* Copy other cells except the "cross" to compute the determinant. */ + float tmp; + for (int m_c = 0; m_c < 2; m_c++) { + for (int m_r = 0; m_r < 2; m_r++) { + if (m_c != c && m_r != r) { + tmp = mat[m_c][m_r]; + } + } + } + float minor = tmp; + /* Transpose directly to get the adjugate. Swap destination row and col. */ + adj[r][c] = (((c + r) & 1) != 0) ? -minor : minor; + } + } + return adj; +} +mat3x3 adjoint(mat3x3 mat) +{ + mat3x3 adj; + for (int c = 0; c < 3; c++) { + for (int r = 0; r < 3; r++) { + /* Copy other cells except the "cross" to compute the determinant. */ + mat2x2 tmp; + for (int m_c = 0; m_c < 3; m_c++) { + for (int m_r = 0; m_r < 3; m_r++) { + if (m_c != c && m_r != r) { + int d_c = (m_c < c) ? m_c : (m_c - 1); + int d_r = (m_r < r) ? m_r : (m_r - 1); + tmp[d_c][d_r] = mat[m_c][m_r]; + } + } + } + float minor = determinant(tmp); + /* Transpose directly to get the adjugate. Swap destination row and col. */ + adj[r][c] = (((c + r) & 1) != 0) ? -minor : minor; + } + } + return adj; +} +mat4x4 adjoint(mat4x4 mat) +{ + mat4x4 adj; + for (int c = 0; c < 4; c++) { + for (int r = 0; r < 4; r++) { + /* Copy other cells except the "cross" to compute the determinant. */ + mat3x3 tmp; + for (int m_c = 0; m_c < 4; m_c++) { + for (int m_r = 0; m_r < 4; m_r++) { + if (m_c != c && m_r != r) { + int d_c = (m_c < c) ? m_c : (m_c - 1); + int d_r = (m_r < r) ? m_r : (m_r - 1); + tmp[d_c][d_r] = mat[m_c][m_r]; + } + } + } + float minor = determinant(tmp); + /* Transpose directly to get the adjugate. Swap destination row and col. */ + adj[r][c] = (((c + r) & 1) != 0) ? -minor : minor; + } + } + return adj; +} + +mat4x4 translate(mat4x4 mat, vec3 translation) +{ + mat[3].xyz += translation[0] * mat[0].xyz; + mat[3].xyz += translation[1] * mat[1].xyz; + mat[3].xyz += translation[2] * mat[2].xyz; + return mat; +} +mat4x4 translate(mat4x4 mat, vec2 translation) +{ + mat[3].xyz += translation[0] * mat[0].xyz; + mat[3].xyz += translation[1] * mat[1].xyz; + return mat; +} + +mat3x3 rotate(mat3x3 mat, AxisAngle rotation) +{ + mat3x3 result; + /* axis_vec is given to be normalized. */ + if (rotation.axis.x == 1.0) { + float angle_cos = cos(rotation.angle); + float angle_sin = sin(rotation.angle); + for (int c = 0; c < 3; c++) { + result[0][c] = mat[0][c]; + result[1][c] = angle_cos * mat[1][c] + angle_sin * mat[2][c]; + result[2][c] = -angle_sin * mat[1][c] + angle_cos * mat[2][c]; + } + } + else if (rotation.axis.y == 1.0) { + float angle_cos = cos(rotation.angle); + float angle_sin = sin(rotation.angle); + for (int c = 0; c < 3; c++) { + result[0][c] = angle_cos * mat[0][c] - angle_sin * mat[2][c]; + result[1][c] = mat[1][c]; + result[2][c] = angle_sin * mat[0][c] + angle_cos * mat[2][c]; + } + } + else if (rotation.axis.z == 1.0) { + float angle_cos = cos(rotation.angle); + float angle_sin = sin(rotation.angle); + for (int c = 0; c < 3; c++) { + result[0][c] = angle_cos * mat[0][c] + angle_sin * mat[1][c]; + result[1][c] = -angle_sin * mat[0][c] + angle_cos * mat[1][c]; + result[2][c] = mat[2][c]; + } + } + else { + /* Un-optimized case. Arbitrary rotation. */ + result = mat * from_rotation(rotation); + } + return result; +} +mat3x3 rotate(mat3x3 mat, EulerXYZ rotation) +{ + AxisAngle axis_angle; + if (rotation.y == 0.0 && rotation.z == 0.0) { + axis_angle = AxisAngle(vec3(1.0, 0.0, 0.0), rotation.x); + } + else if (rotation.x == 0.0 && rotation.z == 0.0) { + axis_angle = AxisAngle(vec3(0.0, 1.0, 0.0), rotation.y); + } + else if (rotation.x == 0.0 && rotation.y == 0.0) { + axis_angle = AxisAngle(vec3(0.0, 0.0, 1.0), rotation.z); + } + else { + /* Un-optimized case. Arbitrary rotation. */ + return mat * from_rotation(rotation); + } + return rotate(mat, axis_angle); +} + +mat4x4 rotate(mat4x4 mat, AxisAngle rotation) +{ + mat4x4 result = mat4x4(rotate(mat3x3(mat), rotation)); + result[0][3] = mat[0][3]; + result[1][3] = mat[1][3]; + result[2][3] = mat[2][3]; + result[3][0] = mat[3][0]; + result[3][1] = mat[3][1]; + result[3][2] = mat[3][2]; + result[3][3] = mat[3][3]; + return result; +} +mat4x4 rotate(mat4x4 mat, EulerXYZ rotation) +{ + mat4x4 result = mat4x4(rotate(mat3x3(mat), rotation)); + result[0][3] = mat[0][3]; + result[1][3] = mat[1][3]; + result[2][3] = mat[2][3]; + result[3][0] = mat[3][0]; + result[3][1] = mat[3][1]; + result[3][2] = mat[3][2]; + result[3][3] = mat[3][3]; + return result; +} + +mat3x3 scale(mat3x3 mat, vec2 scale) +{ + mat[0] *= scale[0]; + mat[1] *= scale[1]; + return mat; +} +mat3x3 scale(mat3x3 mat, vec3 scale) +{ + mat[0] *= scale[0]; + mat[1] *= scale[1]; + mat[2] *= scale[2]; + return mat; +} +mat4x4 scale(mat4x4 mat, vec2 scale) +{ + mat[0] *= scale[0]; + mat[1] *= scale[1]; + return mat; +} +mat4x4 scale(mat4x4 mat, vec3 scale) +{ + mat[0] *= scale[0]; + mat[1] *= scale[1]; + mat[2] *= scale[2]; + return mat; +} + +mat4x4 from_location(vec3 location) +{ + mat4x4 ret = mat4x4(1.0); + ret[3].xyz = location; + return ret; +} + +mat2x2 from_scale(vec2 scale) +{ + mat2x2 ret = mat2x2(0.0); + ret[0][0] = scale[0]; + ret[1][1] = scale[1]; + return ret; +} +mat3x3 from_scale(vec3 scale) +{ + mat3x3 ret = mat3x3(0.0); + ret[0][0] = scale[0]; + ret[1][1] = scale[1]; + ret[2][2] = scale[2]; + return ret; +} +mat4x4 from_scale(vec4 scale) +{ + mat4x4 ret = mat4x4(0.0); + ret[0][0] = scale[0]; + ret[1][1] = scale[1]; + ret[2][2] = scale[2]; + ret[3][3] = scale[3]; + return ret; +} + +mat2x2 from_rotation(Angle rotation) +{ + float c = cos(rotation.angle); + float s = sin(rotation.angle); + return mat2x2(c, -s, s, c); +} + +mat3x3 from_rotation(EulerXYZ rotation) +{ + float ci = cos(rotation.x); + float cj = cos(rotation.y); + float ch = cos(rotation.z); + float si = sin(rotation.x); + float sj = sin(rotation.y); + float sh = sin(rotation.z); + float cc = ci * ch; + float cs = ci * sh; + float sc = si * ch; + float ss = si * sh; + + mat3x3 mat; + mat[0][0] = cj * ch; + mat[1][0] = sj * sc - cs; + mat[2][0] = sj * cc + ss; + + mat[0][1] = cj * sh; + mat[1][1] = sj * ss + cc; + mat[2][1] = sj * cs - sc; + + mat[0][2] = -sj; + mat[1][2] = cj * si; + mat[2][2] = cj * ci; + return mat; +} + +mat3x3 from_rotation(Quaternion rotation) +{ + /** \note: Should be double but support isn't native on most GPUs. */ + float q0 = M_SQRT2 * float(rotation.x); + float q1 = M_SQRT2 * float(rotation.y); + float q2 = M_SQRT2 * float(rotation.z); + float q3 = M_SQRT2 * float(rotation.w); + + float qda = q0 * q1; + float qdb = q0 * q2; + float qdc = q0 * q3; + float qaa = q1 * q1; + float qab = q1 * q2; + float qac = q1 * q3; + float qbb = q2 * q2; + float qbc = q2 * q3; + float qcc = q3 * q3; + + mat3x3 mat; + mat[0][0] = float(1.0 - qbb - qcc); + mat[0][1] = float(qdc + qab); + mat[0][2] = float(-qdb + qac); + + mat[1][0] = float(-qdc + qab); + mat[1][1] = float(1.0 - qaa - qcc); + mat[1][2] = float(qda + qbc); + + mat[2][0] = float(qdb + qac); + mat[2][1] = float(-qda + qbc); + mat[2][2] = float(1.0 - qaa - qbb); + return mat; +} + +mat3x3 from_rotation(AxisAngle rotation) +{ + float angle_sin = sin(rotation.angle); + float angle_cos = cos(rotation.angle); + vec3 axis = rotation.axis; + + float ico = (float(1) - angle_cos); + vec3 nsi = axis * angle_sin; + + vec3 n012 = (axis * axis) * ico; + float n_01 = (axis[0] * axis[1]) * ico; + float n_02 = (axis[0] * axis[2]) * ico; + float n_12 = (axis[1] * axis[2]) * ico; + + mat3 mat = from_scale(n012 + angle_cos); + mat[0][1] = n_01 + nsi[2]; + mat[0][2] = n_02 - nsi[1]; + mat[1][0] = n_01 - nsi[2]; + mat[1][2] = n_12 + nsi[0]; + mat[2][0] = n_02 + nsi[1]; + mat[2][1] = n_12 - nsi[0]; + return mat; +} + +mat3x3 from_rot_scale(EulerXYZ rotation, vec3 scale) +{ + return from_rotation(rotation) * from_scale(scale); +} +mat3x3 from_rot_scale(Quaternion rotation, vec3 scale) +{ + return from_rotation(rotation) * from_scale(scale); +} +mat3x3 from_rot_scale(AxisAngle rotation, vec3 scale) +{ + return from_rotation(rotation) * from_scale(scale); +} + +mat4x4 from_loc_rot(vec3 location, EulerXYZ rotation) +{ + mat4x4 ret = mat4x4(from_rotation(rotation)); + ret[3].xyz = location; + return ret; +} +mat4x4 from_loc_rot(vec3 location, Quaternion rotation) +{ + mat4x4 ret = mat4x4(from_rotation(rotation)); + ret[3].xyz = location; + return ret; +} +mat4x4 from_loc_rot(vec3 location, AxisAngle rotation) +{ + mat4x4 ret = mat4x4(from_rotation(rotation)); + ret[3].xyz = location; + return ret; +} + +mat4x4 from_loc_rot_scale(vec3 location, EulerXYZ rotation, vec3 scale) +{ + mat4x4 ret = mat4x4(from_rot_scale(rotation, scale)); + ret[3].xyz = location; + return ret; +} +mat4x4 from_loc_rot_scale(vec3 location, Quaternion rotation, vec3 scale) +{ + mat4x4 ret = mat4x4(from_rot_scale(rotation, scale)); + ret[3].xyz = location; + return ret; +} +mat4x4 from_loc_rot_scale(vec3 location, AxisAngle rotation, vec3 scale) +{ + mat4x4 ret = mat4x4(from_rot_scale(rotation, scale)); + ret[3].xyz = location; + return ret; +} + +void detail__normalized_to_eul2(mat3 mat, out EulerXYZ eul1, out EulerXYZ eul2) +{ + float cy = hypot(mat[0][0], mat[0][1]); + if (cy > 16.0f * FLT_EPSILON) { + eul1.x = atan2(mat[1][2], mat[2][2]); + eul1.y = atan2(-mat[0][2], cy); + eul1.z = atan2(mat[0][1], mat[0][0]); + + eul2.x = atan2(-mat[1][2], -mat[2][2]); + eul2.y = atan2(-mat[0][2], -cy); + eul2.z = atan2(-mat[0][1], -mat[0][0]); + } + else { + eul1.x = atan2(-mat[2][1], mat[1][1]); + eul1.y = atan2(-mat[0][2], cy); + eul1.z = 0.0; + + eul2 = eul1; + } +} + +EulerXYZ to_euler(mat3x3 mat) +{ + return to_euler(mat, true); +} +EulerXYZ to_euler(mat3x3 mat, const bool normalized) +{ + if (!normalized) { + mat = normalize(mat); + } + EulerXYZ eul1, eul2; + detail__normalized_to_eul2(mat, eul1, eul2); + /* Return best, which is just the one with lowest values it in. */ + return (length_manhattan(as_vec3(eul1)) > length_manhattan(as_vec3(eul2))) ? eul2 : eul1; +} +EulerXYZ to_euler(mat4x4 mat) +{ + return to_euler(mat3(mat)); +} +EulerXYZ to_euler(mat4x4 mat, const bool normalized) +{ + return to_euler(mat3(mat), normalized); +} + +Quaternion normalized_to_quat_fast(mat3 mat) +{ + /* Caller must ensure matrices aren't negative for valid results, see: T24291, T94231. */ + Quaternion q; + + /* Method outlined by Mike Day, ref: https://math.stackexchange.com/a/3183435/220949 + * with an additional `sqrtf(..)` for higher precision result. + * Removing the `sqrt` causes tests to fail unless the precision is set to 1e-6 or larger. */ + + if (mat[2][2] < 0.0f) { + if (mat[0][0] > mat[1][1]) { + float trace = 1.0f + mat[0][0] - mat[1][1] - mat[2][2]; + float s = 2.0f * sqrt(trace); + if (mat[1][2] < mat[2][1]) { + /* Ensure W is non-negative for a canonical result. */ + s = -s; + } + q.y = 0.25f * s; + s = 1.0f / s; + q.x = (mat[1][2] - mat[2][1]) * s; + q.z = (mat[0][1] + mat[1][0]) * s; + q.w = (mat[2][0] + mat[0][2]) * s; + if ((trace == 1.0f) && (q.x == 0.0f && q.z == 0.0f && q.w == 0.0f)) { + /* Avoids the need to normalize the degenerate case. */ + q.y = 1.0f; + } + } + else { + float trace = 1.0f - mat[0][0] + mat[1][1] - mat[2][2]; + float s = 2.0f * sqrt(trace); + if (mat[2][0] < mat[0][2]) { + /* Ensure W is non-negative for a canonical result. */ + s = -s; + } + q.z = 0.25f * s; + s = 1.0f / s; + q.x = (mat[2][0] - mat[0][2]) * s; + q.y = (mat[0][1] + mat[1][0]) * s; + q.w = (mat[1][2] + mat[2][1]) * s; + if ((trace == 1.0f) && (q.x == 0.0f && q.y == 0.0f && q.w == 0.0f)) { + /* Avoids the need to normalize the degenerate case. */ + q.z = 1.0f; + } + } + } + else { + if (mat[0][0] < -mat[1][1]) { + float trace = 1.0f - mat[0][0] - mat[1][1] + mat[2][2]; + float s = 2.0f * sqrt(trace); + if (mat[0][1] < mat[1][0]) { + /* Ensure W is non-negative for a canonical result. */ + s = -s; + } + q.w = 0.25f * s; + s = 1.0f / s; + q.x = (mat[0][1] - mat[1][0]) * s; + q.y = (mat[2][0] + mat[0][2]) * s; + q.z = (mat[1][2] + mat[2][1]) * s; + if ((trace == 1.0f) && (q.x == 0.0f && q.y == 0.0f && q.z == 0.0f)) { + /* Avoids the need to normalize the degenerate case. */ + q.w = 1.0f; + } + } + else { + /* NOTE(@campbellbarton): A zero matrix will fall through to this block, + * needed so a zero scaled matrices to return a quaternion without rotation, see: T101848. + */ + float trace = 1.0f + mat[0][0] + mat[1][1] + mat[2][2]; + float s = 2.0f * sqrt(trace); + q.x = 0.25f * s; + s = 1.0f / s; + q.y = (mat[1][2] - mat[2][1]) * s; + q.z = (mat[2][0] - mat[0][2]) * s; + q.w = (mat[0][1] - mat[1][0]) * s; + if ((trace == 1.0f) && (q.y == 0.0f && q.z == 0.0f && q.w == 0.0f)) { + /* Avoids the need to normalize the degenerate case. */ + q.x = 1.0f; + } + } + } + return q; +} + +Quaternion detail__normalized_to_quat_with_checks(mat3x3 mat) +{ + float det = determinant(mat); + if (!isfinite(det)) { + return Quaternion__identity(); + } + else if (det < 0.0) { + return normalized_to_quat_fast(-mat); + } + return normalized_to_quat_fast(mat); +} + +Quaternion to_quaternion(mat3x3 mat) +{ + return detail__normalized_to_quat_with_checks(normalize(mat)); +} +Quaternion to_quaternion(mat3x3 mat, const bool normalized) +{ + if (!normalized) { + mat = normalize(mat); + } + return to_quaternion(mat); +} +Quaternion to_quaternion(mat4x4 mat) +{ + return to_quaternion(mat3(mat)); +} +Quaternion to_quaternion(mat4x4 mat, const bool normalized) +{ + return to_quaternion(mat3(mat), normalized); +} + +vec3 to_scale(mat3x3 mat) +{ + return vec3(length(mat[0]), length(mat[1]), length(mat[2])); +} +vec3 to_scale(mat3x3 mat, const bool allow_negative_scale) +{ + vec3 result = to_scale(mat); + if (allow_negative_scale) { + if (is_negative(mat)) { + result = -result; + } + } + return result; +} +vec3 to_scale(mat4x4 mat) +{ + return to_scale(mat3(mat)); +} +vec3 to_scale(mat4x4 mat, const bool allow_negative_scale) +{ + return to_scale(mat3(mat), allow_negative_scale); +} + +void to_rot_scale(mat3x3 mat, out EulerXYZ r_rotation, out vec3 r_scale) +{ + r_scale = to_scale(mat); + r_rotation = to_euler(mat, true); +} +void to_rot_scale(mat3x3 mat, + out EulerXYZ r_rotation, + out vec3 r_scale, + const bool allow_negative_scale) +{ + mat3x3 normalized_mat = normalize_and_get_size(mat, r_scale); + if (allow_negative_scale) { + if (is_negative(normalized_mat)) { + normalized_mat = -normalized_mat; + r_scale = -r_scale; + } + } + r_rotation = to_euler(mat, true); +} +void to_rot_scale(mat3x3 mat, out Quaternion r_rotation, out vec3 r_scale) +{ + r_scale = to_scale(mat); + r_rotation = to_quaternion(mat, true); +} +void to_rot_scale(mat3x3 mat, + out Quaternion r_rotation, + out vec3 r_scale, + const bool allow_negative_scale) +{ + mat3x3 normalized_mat = normalize_and_get_size(mat, r_scale); + if (allow_negative_scale) { + if (is_negative(normalized_mat)) { + normalized_mat = -normalized_mat; + r_scale = -r_scale; + } + } + r_rotation = to_quaternion(mat, true); +} + +void to_loc_rot_scale(mat4x4 mat, out vec3 r_location, out EulerXYZ r_rotation, out vec3 r_scale) +{ + r_location = mat[3].xyz; + to_rot_scale(mat3(mat), r_rotation, r_scale); +} +void to_loc_rot_scale(mat4x4 mat, + out vec3 r_location, + out EulerXYZ r_rotation, + out vec3 r_scale, + const bool allow_negative_scale) +{ + r_location = mat[3].xyz; + to_rot_scale(mat3(mat), r_rotation, r_scale, allow_negative_scale); +} +void to_loc_rot_scale(mat4x4 mat, out vec3 r_location, out Quaternion r_rotation, out vec3 r_scale) +{ + r_location = mat[3].xyz; + to_rot_scale(mat3(mat), r_rotation, r_scale); +} +void to_loc_rot_scale(mat4x4 mat, + out vec3 r_location, + out Quaternion r_rotation, + out vec3 r_scale, + const bool allow_negative_scale) +{ + r_location = mat[3].xyz; + to_rot_scale(mat3(mat), r_rotation, r_scale, allow_negative_scale); +} + +vec3 transform_point(mat3x3 mat, vec3 point) +{ + return mat * point; +} + +vec3 transform_point(mat4x4 mat, vec3 point) +{ + return (mat * vec4(point, 1.0)).xyz; +} + +vec3 transform_direction(mat3x3 mat, vec3 direction) +{ + return mat * direction; +} + +vec3 transform_direction(mat4x4 mat, vec3 direction) +{ + return mat3x3(mat) * direction; +} + +vec2 project_point(mat3x3 mat, vec2 point) +{ + vec3 tmp = mat * vec3(point, 1.0); + /* Absolute value to not flip the frustum upside down behind the camera. */ + return tmp.xy / abs(tmp.z); +} +vec3 project_point(mat4x4 mat, vec3 point) +{ + vec4 tmp = mat * vec4(point, 1.0); + /* Absolute value to not flip the frustum upside down behind the camera. */ + return tmp.xyz / abs(tmp.w); +} + +mat4x4 interpolate_fast(mat4x4 a, mat4x4 b, float t) +{ + vec3 a_loc, b_loc; + vec3 a_scale, b_scale; + Quaternion a_quat, b_quat; + to_loc_rot_scale(a, a_loc, a_quat, a_scale); + to_loc_rot_scale(b, b_loc, b_quat, b_scale); + + vec3 location = interpolate(a_loc, b_loc, t); + vec3 scale = interpolate(a_scale, b_scale, t); + Quaternion rotation = interpolate(a_quat, b_quat, t); + return from_loc_rot_scale(location, rotation, scale); +} + +mat4x4 projection__orthographic( + float left, float right, float bottom, float top, float near_clip, float far_clip) +{ + float x_delta = right - left; + float y_delta = top - bottom; + float z_delta = far_clip - near_clip; + + mat4x4 mat = mat4x4(1.0); + if (x_delta != 0.0 && y_delta != 0.0 && z_delta != 0.0) { + mat[0][0] = 2.0 / x_delta; + mat[3][0] = -(right + left) / x_delta; + mat[1][1] = 2.0 / y_delta; + mat[3][1] = -(top + bottom) / y_delta; + mat[2][2] = -2.0 / z_delta; /* NOTE: negate Z. */ + mat[3][2] = -(far_clip + near_clip) / z_delta; + } + return mat; +} + +mat4x4 projection__perspective( + float left, float right, float bottom, float top, float near_clip, float far_clip) +{ + float x_delta = right - left; + float y_delta = top - bottom; + float z_delta = far_clip - near_clip; + + mat4x4 mat = mat4x4(1.0); + if (x_delta != 0.0 && y_delta != 0.0 && z_delta != 0.0) { + mat[0][0] = near_clip * 2.0 / x_delta; + mat[1][1] = near_clip * 2.0 / y_delta; + mat[2][0] = (right + left) / x_delta; /* NOTE: negate Z. */ + mat[2][1] = (top + bottom) / y_delta; + mat[2][2] = -(far_clip + near_clip) / z_delta; + mat[2][3] = -1.0; + mat[3][2] = (-2.0 * near_clip * far_clip) / z_delta; + } + return mat; +} + +mat4x4 projection__perspective_fov(float angle_left, + float angle_right, + float angle_bottom, + float angle_top, + float near_clip, + float far_clip) +{ + mat4x4 mat = projection__perspective( + tan(angle_left), tan(angle_right), tan(angle_bottom), tan(angle_top), near_clip, far_clip); + mat[0][0] /= near_clip; + mat[1][1] /= near_clip; + return mat; +} + +bool is_zero(mat3x3 a) +{ + if (is_zero(a[0])) { + if (is_zero(a[1])) { + if (is_zero(a[2])) { + return true; + } + } + } + return false; +} +bool is_zero(mat4x4 a) +{ + if (is_zero(a[0])) { + if (is_zero(a[1])) { + if (is_zero(a[2])) { + if (is_zero(a[3])) { + return true; + } + } + } + } + return false; +} + +bool is_negative(mat3x3 mat) +{ + return determinant(mat) < 0.0; +} +bool is_negative(mat4x4 mat) +{ + return is_negative(mat3x3(mat)); +} + +bool is_equal(mat2x2 a, mat2x2 b, float epsilon) +{ + if (is_equal(a[0], b[0], epsilon)) { + if (is_equal(a[1], b[1], epsilon)) { + return true; + } + } + return false; +} +bool is_equal(mat3x3 a, mat3x3 b, float epsilon) +{ + if (is_equal(a[0], b[0], epsilon)) { + if (is_equal(a[1], b[1], epsilon)) { + if (is_equal(a[2], b[2], epsilon)) { + return true; + } + } + } + return false; +} +bool is_equal(mat4x4 a, mat4x4 b, float epsilon) +{ + if (is_equal(a[0], b[0], epsilon)) { + if (is_equal(a[1], b[1], epsilon)) { + if (is_equal(a[2], b[2], epsilon)) { + if (is_equal(a[3], b[3], epsilon)) { + return true; + } + } + } + } + return false; +} + +bool is_orthogonal(mat3x3 mat) +{ + if (abs(dot(mat[0], mat[1])) > 1e-5) { + return false; + } + if (abs(dot(mat[1], mat[2])) > 1e-5) { + return false; + } + if (abs(dot(mat[2], mat[0])) > 1e-5) { + return false; + } + return true; +} + +bool is_orthonormal(mat3x3 mat) +{ + if (!is_orthogonal(mat)) { + return false; + } + if (abs(length_squared(mat[0]) - 1.0) > 1e-5) { + return false; + } + if (abs(length_squared(mat[1]) - 1.0) > 1e-5) { + return false; + } + if (abs(length_squared(mat[2]) - 1.0) > 1e-5) { + return false; + } + return true; +} + +bool is_uniformly_scaled(mat3x3 mat) +{ + if (!is_orthogonal(mat)) { + return false; + } + const float eps = 1e-7; + float x = length_squared(mat[0]); + float y = length_squared(mat[1]); + float z = length_squared(mat[2]); + return (abs(x - y) < eps) && abs(x - z) < eps; +} + +bool is_orthogonal(mat4x4 mat) +{ + return is_orthogonal(mat3x3(mat)); +} +bool is_orthonormal(mat4x4 mat) +{ + return is_orthonormal(mat3x3(mat)); +} +bool is_uniformly_scaled(mat4x4 mat) +{ + return is_uniformly_scaled(mat3x3(mat)); +} + +/* Returns true if each individual columns are unit scaled. Mainly for assert usage. */ +bool is_unit_scale(mat4x4 m) +{ + if (is_unit_scale(m[0])) { + if (is_unit_scale(m[1])) { + if (is_unit_scale(m[2])) { + if (is_unit_scale(m[3])) { + return true; + } + } + } + } + return false; +} +bool is_unit_scale(mat3x3 m) +{ + if (is_unit_scale(m[0])) { + if (is_unit_scale(m[1])) { + if (is_unit_scale(m[2])) { + return true; + } + } + } + return false; +} +bool is_unit_scale(mat2x2 m) +{ + if (is_unit_scale(m[0])) { + if (is_unit_scale(m[1])) { + return true; + } + } + return false; +} + +/** \} */ + +#endif /* GPU_SHADER_MATH_MATRIX_LIB_GLSL */ diff --git a/source/blender/gpu/shaders/common/gpu_shader_math_rotation_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_math_rotation_lib.glsl new file mode 100644 index 00000000000..c15b3f937ec --- /dev/null +++ b/source/blender/gpu/shaders/common/gpu_shader_math_rotation_lib.glsl @@ -0,0 +1,186 @@ + +#pragma BLENDER_REQUIRE(gpu_shader_utildefines_lib.glsl) + +/* WORKAROUND: to guard against double include in EEVEE. */ +#ifndef GPU_SHADER_MATH_ROTATION_LIB_GLSL +# define GPU_SHADER_MATH_ROTATION_LIB_GLSL + +/* -------------------------------------------------------------------- */ +/** \name Rotation Types + * \{ */ + +struct Angle { + /* Angle in radian. */ + float angle; + +# ifdef GPU_METAL + Angle() = default; + Angle(float angle_) : angle(angle_){}; +# endif +}; + +struct AxisAngle { + vec3 axis; + float angle; + +# ifdef GPU_METAL + AxisAngle() = default; + AxisAngle(vec3 axis_, float angle_) : axis(axis_), angle(angle_){}; +# endif +}; + +AxisAngle AxisAngle__identity() +{ + return AxisAngle(vec3(0, 1, 0), 0); +} + +struct Quaternion { + float x, y, z, w; +# ifdef GPU_METAL + Quaternion() = default; + Quaternion(float x_, float y_, float z_, float w_) : x(x_), y(y_), z(z_), w(w_){}; +# endif +}; + +vec4 as_vec4(Quaternion quat) +{ + return vec4(quat.x, quat.y, quat.z, quat.w); +} + +Quaternion Quaternion__identity() +{ + return Quaternion(1, 0, 0, 0); +} + +struct EulerXYZ { + float x, y, z; +# ifdef GPU_METAL + EulerXYZ() = default; + EulerXYZ(float x_, float y_, float z_) : x(x_), y(y_), z(z_){}; +# endif +}; + +vec3 as_vec3(EulerXYZ eul) +{ + return vec3(eul.x, eul.y, eul.z); +} + +EulerXYZ EulerXYZ__identity() +{ + return EulerXYZ(0, 0, 0); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Rotation Functions + * \{ */ + +/** + * Generic function for implementing slerp + * (quaternions and spherical vector coords). + * + * \param t: factor in [0..1] + * \param cosom: dot product from normalized vectors/quats. + * \param r_w: calculated weights. + */ +vec2 interpolate_dot_slerp(float t, float cosom) +{ + vec2 w = vec2(1.0 - t, t); + /* Within [-1..1] range, avoid aligned axis. */ + const float eps = 1e-4; + if (abs(cosom) < 1.0 - eps) { + float omega = acos(cosom); + w = sin(w * omega) / sin(omega); + } + return w; +} + +Quaternion interpolate(Quaternion a, Quaternion b, float t) +{ + vec4 quat = as_vec4(a); + float cosom = dot(as_vec4(a), as_vec4(b)); + /* Rotate around shortest angle. */ + if (cosom < 0.0) { + cosom = -cosom; + quat = -quat; + } + vec2 w = interpolate_dot_slerp(t, cosom); + quat = w.x * quat + w.y * as_vec4(b); + return Quaternion(UNPACK4(quat)); +} + +Quaternion to_quaternion(EulerXYZ eul) +{ + float ti = eul.x * 0.5; + float tj = eul.y * 0.5; + float th = eul.z * 0.5; + float ci = cos(ti); + float cj = cos(tj); + float ch = cos(th); + float si = sin(ti); + float sj = sin(tj); + float sh = sin(th); + float cc = ci * ch; + float cs = ci * sh; + float sc = si * ch; + float ss = si * sh; + + Quaternion quat; + quat.x = cj * cc + sj * ss; + quat.y = cj * sc - sj * cs; + quat.z = cj * ss + sj * cc; + quat.w = cj * cs - sj * sc; + return quat; +} + +Quaternion to_axis_angle(AxisAngle axis_angle) +{ + float angle_cos = cos(axis_angle.angle); + /** Using half angle identities: sin(angle / 2) = sqrt((1 - angle_cos) / 2) */ + float sine = sqrt(0.5 - angle_cos * 0.5); + float cosine = sqrt(0.5 + angle_cos * 0.5); + + /* TODO(fclem): Optimize. */ + float angle_sin = sin(axis_angle.angle); + if (angle_sin < 0.0) { + sine = -sine; + } + + Quaternion quat; + quat.x = cosine; + quat.y = axis_angle.axis.x * sine; + quat.z = axis_angle.axis.y * sine; + quat.w = axis_angle.axis.z * sine; + return quat; +} + +AxisAngle to_axis_angle(Quaternion quat) +{ + /* Calculate angle/2, and sin(angle/2). */ + float ha = acos(quat.x); + float si = sin(ha); + + /* From half-angle to angle. */ + float angle = ha * 2; + /* Prevent division by zero for axis conversion. */ + if (abs(si) < 0.0005) { + si = 1.0; + } + + vec3 axis = vec3(quat.y, quat.z, quat.w) / si; + if (is_zero(axis)) { + axis[1] = 1.0; + } + return AxisAngle(axis, angle); +} + +AxisAngle to_axis_angle(EulerXYZ eul) +{ + /* Use quaternions as intermediate representation for now... */ + return to_axis_angle(to_quaternion(eul)); +} + +/** \} */ + +#endif /* GPU_SHADER_MATH_ROTATION_LIB_GLSL */ diff --git a/source/blender/gpu/shaders/common/gpu_shader_math_vector_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_math_vector_lib.glsl new file mode 100644 index 00000000000..7fde7583763 --- /dev/null +++ b/source/blender/gpu/shaders/common/gpu_shader_math_vector_lib.glsl @@ -0,0 +1,535 @@ + +#pragma BLENDER_REQUIRE(gpu_shader_math_base_lib.glsl) + +/* WORKAROUND: to guard against double include in EEVEE. */ +#ifndef GPU_SHADER_MATH_VECTOR_LIB_GLSL +# define GPU_SHADER_MATH_VECTOR_LIB_GLSL + +/* Metal does not need prototypes. */ +# ifndef GPU_METAL + +/** + * Return true if all components is equal to zero. + */ +bool is_zero(vec2 vec); +bool is_zero(vec3 vec); +bool is_zero(vec4 vec); + +/** + * Return true if any component is equal to zero. + */ +bool is_any_zero(vec2 vec); +bool is_any_zero(vec3 vec); +bool is_any_zero(vec4 vec); + +/** + * Return true if the deference between`a` and `b` is below the `epsilon` value. + * Epsilon value is scaled by magnitude of `a` before comparison. + */ +bool almost_equal_relative(vec2 a, vec2 b, const float epsilon_factor); +bool almost_equal_relative(vec3 a, vec3 b, const float epsilon_factor); +bool almost_equal_relative(vec4 a, vec4 b, const float epsilon_factor); + +/** + * Safe `a` modulo `b`. + * If `b` equal 0 the result will be 0. + */ +vec2 safe_mod(vec2 a, vec2 b); +vec3 safe_mod(vec3 a, vec3 b); +vec4 safe_mod(vec4 a, vec4 b); +vec2 safe_mod(vec2 a, float b); +vec3 safe_mod(vec3 a, float b); +vec4 safe_mod(vec4 a, float b); + +/** + * Returns \a a if it is a multiple of \a b or the next multiple or \a b after \b a . + * In other words, it is equivalent to `divide_ceil(a, b) * b`. + * It is undefined if \a a is negative or \b b is not strictly positive. + */ +ivec2 ceil_to_multiple(ivec2 a, ivec2 b); +ivec3 ceil_to_multiple(ivec3 a, ivec3 b); +ivec4 ceil_to_multiple(ivec4 a, ivec4 b); +uvec2 ceil_to_multiple(uvec2 a, uvec2 b); +uvec3 ceil_to_multiple(uvec3 a, uvec3 b); +uvec4 ceil_to_multiple(uvec4 a, uvec4 b); + +/** + * Integer division that returns the ceiling, instead of flooring like normal C division. + * It is undefined if \a a is negative or \b b is not strictly positive. + */ +ivec2 divide_ceil(ivec2 a, ivec2 b); +ivec3 divide_ceil(ivec3 a, ivec3 b); +ivec4 divide_ceil(ivec4 a, ivec4 b); +uvec2 divide_ceil(uvec2 a, uvec2 b); +uvec3 divide_ceil(uvec3 a, uvec3 b); +uvec4 divide_ceil(uvec4 a, uvec4 b); + +/** + * Component wise, use vector to replace min if it is smaller and max if bigger. + */ +void min_max(vec2 vector, inout vec2 min, inout vec2 max); +void min_max(vec3 vector, inout vec3 min, inout vec3 max); +void min_max(vec4 vector, inout vec4 min, inout vec4 max); + +/** + * Safe divide `a` by `b`. + * If `b` equal 0 the result will be 0. + */ +vec2 safe_divide(vec2 a, vec2 b); +vec3 safe_divide(vec3 a, vec3 b); +vec4 safe_divide(vec4 a, vec4 b); +vec2 safe_divide(vec2 a, float b); +vec3 safe_divide(vec3 a, float b); +vec4 safe_divide(vec4 a, float b); + +/** + * Return the manhattan length of `a`. + * This is also the sum of the absolute value of all components. + */ +float length_manhattan(vec2 a); +float length_manhattan(vec3 a); +float length_manhattan(vec4 a); + +/** + * Return the length squared of `a`. + */ +float length_squared(vec2 a); +float length_squared(vec3 a); +float length_squared(vec4 a); + +/** + * Return the manhattan distance between `a` and `b`. + */ +float distance_manhattan(vec2 a, vec2 b); +float distance_manhattan(vec3 a, vec3 b); +float distance_manhattan(vec4 a, vec4 b); + +/** + * Return the squared distance between `a` and `b`. + */ +float distance_squared(vec2 a, vec2 b); +float distance_squared(vec3 a, vec3 b); +float distance_squared(vec4 a, vec4 b); + +/** + * Return the projection of `p` onto `v_proj`. + */ +vec3 project(vec3 p, vec3 v_proj); + +/** + * Return normalized version of the `vector` and its length. + */ +vec2 normalize_and_get_length(vec2 vector, out float out_length); +vec3 normalize_and_get_length(vec3 vector, out float out_length); +vec4 normalize_and_get_length(vec4 vector, out float out_length); + +/** + * Per component linear interpolation. + */ +vec2 interpolate(vec2 a, vec2 b, float t); +vec3 interpolate(vec3 a, vec3 b, float t); +vec4 interpolate(vec4 a, vec4 b, float t); + +/** + * Return half-way point between `a` and `b`. + */ +vec2 midpoint(vec2 a, vec2 b); +vec3 midpoint(vec3 a, vec3 b); +vec4 midpoint(vec4 a, vec4 b); + +/** + * Return `vector` if `incident` and `reference` are pointing in the same direction. + */ +// vec2 faceforward(vec2 vector, vec2 incident, vec2 reference); /* Built-in GLSL. */ + +/** + * Return the index of the component with the greatest absolute value. + */ +int dominant_axis(vec3 a); + +/** + * Calculates a perpendicular vector to \a v. + * \note Returned vector can be in any perpendicular direction. + * \note Returned vector might not the same length as \a v. + */ +vec3 orthogonal(vec3 v); +/** + * Calculates a perpendicular vector to \a v. + * \note Returned vector is always rotated 90° counter clock wise. + */ +vec2 orthogonal(vec2 v); + +/** + * Return true if the difference between`a` and `b` is below the `epsilon` value. + */ +bool is_equal(vec2 a, vec2 b, const float epsilon); +bool is_equal(vec3 a, vec3 b, const float epsilon); +bool is_equal(vec4 a, vec4 b, const float epsilon); + +# endif /* GPU_METAL */ + +/* ---------------------------------------------------------------------- */ +/** \name Implementation + * \{ */ + +# ifdef GPU_METAL /* Already defined in shader_defines.msl/glsl to move here. */ +bool is_zero(vec2 vec) +{ + return all(equal(vec, vec2(0.0))); +} +bool is_zero(vec3 vec) +{ + return all(equal(vec, vec3(0.0))); +} +bool is_zero(vec4 vec) +{ + return all(equal(vec, vec4(0.0))); +} +# endif + +bool is_any_zero(vec2 vec) +{ + return any(equal(vec, vec2(0.0))); +} +bool is_any_zero(vec3 vec) +{ + return any(equal(vec, vec3(0.0))); +} +bool is_any_zero(vec4 vec) +{ + return any(equal(vec, vec4(0.0))); +} + +bool almost_equal_relative(vec2 a, vec2 b, const float epsilon_factor) +{ + for (int i = 0; i < 2; i++) { + if (abs(a[i] - b[i]) > epsilon_factor * abs(a[i])) { + return false; + } + } + return true; +} +bool almost_equal_relative(vec3 a, vec3 b, const float epsilon_factor) +{ + for (int i = 0; i < 3; i++) { + if (abs(a[i] - b[i]) > epsilon_factor * abs(a[i])) { + return false; + } + } + return true; +} +bool almost_equal_relative(vec4 a, vec4 b, const float epsilon_factor) +{ + for (int i = 0; i < 4; i++) { + if (abs(a[i] - b[i]) > epsilon_factor * abs(a[i])) { + return false; + } + } + return true; +} + +vec2 safe_mod(vec2 a, vec2 b) +{ + return select(vec2(0), mod(a, b), notEqual(b, vec2(0))); +} +vec3 safe_mod(vec3 a, vec3 b) +{ + return select(vec3(0), mod(a, b), notEqual(b, vec3(0))); +} +vec4 safe_mod(vec4 a, vec4 b) +{ + return select(vec4(0), mod(a, b), notEqual(b, vec4(0))); +} + +vec2 safe_mod(vec2 a, float b) +{ + return (b != 0.0) ? mod(a, vec2(b)) : vec2(0); +} +vec3 safe_mod(vec3 a, float b) +{ + return (b != 0.0) ? mod(a, vec3(b)) : vec3(0); +} +vec4 safe_mod(vec4 a, float b) +{ + return (b != 0.0) ? mod(a, vec4(b)) : vec4(0); +} + +ivec2 ceil_to_multiple(ivec2 a, ivec2 b) +{ + return ((a + b - 1) / b) * b; +} +ivec3 ceil_to_multiple(ivec3 a, ivec3 b) +{ + return ((a + b - 1) / b) * b; +} +ivec4 ceil_to_multiple(ivec4 a, ivec4 b) +{ + return ((a + b - 1) / b) * b; +} +uvec2 ceil_to_multiple(uvec2 a, uvec2 b) +{ + return ((a + b - 1u) / b) * b; +} +uvec3 ceil_to_multiple(uvec3 a, uvec3 b) +{ + return ((a + b - 1u) / b) * b; +} +uvec4 ceil_to_multiple(uvec4 a, uvec4 b) +{ + return ((a + b - 1u) / b) * b; +} + +ivec2 divide_ceil(ivec2 a, ivec2 b) +{ + return (a + b - 1) / b; +} +ivec3 divide_ceil(ivec3 a, ivec3 b) +{ + return (a + b - 1) / b; +} +ivec4 divide_ceil(ivec4 a, ivec4 b) +{ + return (a + b - 1) / b; +} +uvec2 divide_ceil(uvec2 a, uvec2 b) +{ + return (a + b - 1u) / b; +} +uvec3 divide_ceil(uvec3 a, uvec3 b) +{ + return (a + b - 1u) / b; +} +uvec4 divide_ceil(uvec4 a, uvec4 b) +{ + return (a + b - 1u) / b; +} + +void min_max(vec2 vector, inout vec2 min_v, inout vec2 max_v) +{ + min_v = min(vector, min_v); + max_v = max(vector, max_v); +} +void min_max(vec3 vector, inout vec3 min_v, inout vec3 max_v) +{ + min_v = min(vector, min_v); + max_v = max(vector, max_v); +} +void min_max(vec4 vector, inout vec4 min_v, inout vec4 max_v) +{ + min_v = min(vector, min_v); + max_v = max(vector, max_v); +} + +vec2 safe_divide(vec2 a, vec2 b) +{ + return select(vec2(0), a / b, notEqual(b, vec2(0))); +} +vec3 safe_divide(vec3 a, vec3 b) +{ + return select(vec3(0), a / b, notEqual(b, vec3(0))); +} +vec4 safe_divide(vec4 a, vec4 b) +{ + return select(vec4(0), a / b, notEqual(b, vec4(0))); +} + +vec2 safe_divide(vec2 a, float b) +{ + return (b != 0.0) ? (a / b) : vec2(0); +} +vec3 safe_divide(vec3 a, float b) +{ + return (b != 0.0) ? (a / b) : vec3(0); +} +vec4 safe_divide(vec4 a, float b) +{ + return (b != 0.0) ? (a / b) : vec4(0); +} + +float length_manhattan(vec2 a) +{ + return dot(abs(a), vec2(1)); +} +float length_manhattan(vec3 a) +{ + return dot(abs(a), vec3(1)); +} +float length_manhattan(vec4 a) +{ + return dot(abs(a), vec4(1)); +} + +float length_squared(vec2 a) +{ + return dot(a, a); +} +float length_squared(vec3 a) +{ + return dot(a, a); +} +float length_squared(vec4 a) +{ + return dot(a, a); +} + +float distance_manhattan(vec2 a, vec2 b) +{ + return length_manhattan(a - b); +} +float distance_manhattan(vec3 a, vec3 b) +{ + return length_manhattan(a - b); +} +float distance_manhattan(vec4 a, vec4 b) +{ + return length_manhattan(a - b); +} + +float distance_squared(vec2 a, vec2 b) +{ + return length_squared(a - b); +} +float distance_squared(vec3 a, vec3 b) +{ + return length_squared(a - b); +} +float distance_squared(vec4 a, vec4 b) +{ + return length_squared(a - b); +} + +vec3 project(vec3 p, vec3 v_proj) +{ + if (is_zero(v_proj)) { + return vec3(0); + } + return v_proj * (dot(p, v_proj) / dot(v_proj, v_proj)); +} + +vec2 normalize_and_get_length(vec2 vector, out float out_length) +{ + out_length = length_squared(vector); + const float threshold = 1e-35f; + if (out_length > threshold) { + out_length = sqrt(out_length); + return vector / out_length; + } + /* Either the vector is small or one of it's values contained `nan`. */ + out_length = 0.0; + return vec2(0.0); +} +vec3 normalize_and_get_length(vec3 vector, out float out_length) +{ + out_length = length_squared(vector); + const float threshold = 1e-35f; + if (out_length > threshold) { + out_length = sqrt(out_length); + return vector / out_length; + } + /* Either the vector is small or one of it's values contained `nan`. */ + out_length = 0.0; + return vec3(0.0); +} +vec4 normalize_and_get_length(vec4 vector, out float out_length) +{ + out_length = length_squared(vector); + const float threshold = 1e-35f; + if (out_length > threshold) { + out_length = sqrt(out_length); + return vector / out_length; + } + /* Either the vector is small or one of it's values contained `nan`. */ + out_length = 0.0; + return vec4(0.0); +} + +vec2 interpolate(vec2 a, vec2 b, float t) +{ + return mix(a, b, t); +} +vec3 interpolate(vec3 a, vec3 b, float t) +{ + return mix(a, b, t); +} +vec4 interpolate(vec4 a, vec4 b, float t) +{ + return mix(a, b, t); +} + +vec2 midpoint(vec2 a, vec2 b) +{ + return (a + b) * 0.5; +} +vec3 midpoint(vec3 a, vec3 b) +{ + return (a + b) * 0.5; +} +vec4 midpoint(vec4 a, vec4 b) +{ + return (a + b) * 0.5; +} + +int dominant_axis(vec3 a) +{ + vec3 b = abs(a); + return ((b.x > b.y) ? ((b.x > b.z) ? 0 : 2) : ((b.y > b.z) ? 1 : 2)); +} + +vec3 orthogonal(vec3 v) +{ + switch (dominant_axis(v)) { + default: + case 0: + return vec3(-v.y - v.z, v.x, v.x); + case 1: + return vec3(v.y, -v.x - v.z, v.y); + case 2: + return vec3(v.z, v.z, -v.x - v.y); + } +} + +vec2 orthogonal(vec2 v) +{ + return vec2(-v.y, v.x); +} + +bool is_equal(vec2 a, vec2 b, const float epsilon) +{ + return all(lessThanEqual(abs(a - b), vec2(epsilon))); +} +bool is_equal(vec3 a, vec3 b, const float epsilon) +{ + return all(lessThanEqual(abs(a - b), vec3(epsilon))); +} +bool is_equal(vec4 a, vec4 b, const float epsilon) +{ + return all(lessThanEqual(abs(a - b), vec4(epsilon))); +} + +# define ASSERT_UNIT_EPSILON 0.0002 + +/* Checks are flipped so NAN doesn't assert because we're making sure the value was + * normalized and in the case we don't want NAN to be raising asserts since there + * is nothing to be done in that case. */ +bool is_unit_scale(vec2 v) +{ + float test_unit = length_squared(v); + return (!(abs(test_unit - 1.0) >= ASSERT_UNIT_EPSILON) || + !(abs(test_unit) >= ASSERT_UNIT_EPSILON)); +} +bool is_unit_scale(vec3 v) +{ + float test_unit = length_squared(v); + return (!(abs(test_unit - 1.0) >= ASSERT_UNIT_EPSILON) || + !(abs(test_unit) >= ASSERT_UNIT_EPSILON)); +} +bool is_unit_scale(vec4 v) +{ + float test_unit = length_squared(v); + return (!(abs(test_unit - 1.0) >= ASSERT_UNIT_EPSILON) || + !(abs(test_unit) >= ASSERT_UNIT_EPSILON)); +} + +/** \} */ + +#endif /* GPU_SHADER_MATH_VECTOR_LIB_GLSL */ diff --git a/source/blender/gpu/shaders/common/gpu_shader_test_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_test_lib.glsl new file mode 100644 index 00000000000..eb32cea40b0 --- /dev/null +++ b/source/blender/gpu/shaders/common/gpu_shader_test_lib.glsl @@ -0,0 +1,214 @@ + +// clang-format off +#ifndef GPU_METAL +bool is_integer(bool v) { return true; } +#endif +bool is_integer(uint v) { return true; } +bool is_integer(int v) { return true; } +bool is_integer(float v) { return false; } +bool is_integer(ivec2 v) { return true; } +bool is_integer(ivec3 v) { return true; } +bool is_integer(ivec4 v) { return true; } +bool is_integer(uvec2 v) { return true; } +bool is_integer(uvec3 v) { return true; } +bool is_integer(uvec4 v) { return true; } +bool is_integer(vec2 v) { return false; } +bool is_integer(vec3 v) { return false; } +bool is_integer(vec4 v) { return false; } +bool is_integer(mat2x2 v) { return false; } +bool is_integer(mat2x3 v) { return false; } +bool is_integer(mat2x4 v) { return false; } +bool is_integer(mat3x2 v) { return false; } +bool is_integer(mat3x3 v) { return false; } +bool is_integer(mat3x4 v) { return false; } +bool is_integer(mat4x2 v) { return false; } +bool is_integer(mat4x3 v) { return false; } +bool is_integer(mat4x4 v) { return false; } + +int mat_row_len(mat2x2 v) { return 2; } +int mat_row_len(mat2x3 v) { return 3; } +int mat_row_len(mat2x4 v) { return 4; } +int mat_row_len(mat3x2 v) { return 2; } +int mat_row_len(mat3x3 v) { return 3; } +int mat_row_len(mat3x4 v) { return 4; } +int mat_row_len(mat4x2 v) { return 2; } +int mat_row_len(mat4x3 v) { return 3; } +int mat_row_len(mat4x4 v) { return 4; } + +int mat_col_len(mat2x2 v) { return 2; } +int mat_col_len(mat2x3 v) { return 2; } +int mat_col_len(mat2x4 v) { return 2; } +int mat_col_len(mat3x2 v) { return 3; } +int mat_col_len(mat3x3 v) { return 3; } +int mat_col_len(mat3x4 v) { return 3; } +int mat_col_len(mat4x2 v) { return 4; } +int mat_col_len(mat4x3 v) { return 4; } +int mat_col_len(mat4x4 v) { return 4; } +int mat_col_len(ivec2 v) { return 2; } +int mat_col_len(ivec3 v) { return 3; } +int mat_col_len(ivec4 v) { return 4; } +int mat_col_len(uvec2 v) { return 2; } +int mat_col_len(uvec3 v) { return 3; } +int mat_col_len(uvec4 v) { return 4; } +int mat_col_len(vec2 v) { return 2; } +int mat_col_len(vec3 v) { return 3; } +int mat_col_len(vec4 v) { return 4; } + +#ifndef GPU_METAL +uint to_type(bool v) { return TEST_TYPE_BOOL; } +#endif +uint to_type(uint v) { return TEST_TYPE_UINT; } +uint to_type(int v) { return TEST_TYPE_INT; } +uint to_type(float v) { return TEST_TYPE_FLOAT; } +uint to_type(ivec2 v) { return TEST_TYPE_IVEC2; } +uint to_type(ivec3 v) { return TEST_TYPE_IVEC3; } +uint to_type(ivec4 v) { return TEST_TYPE_IVEC4; } +uint to_type(uvec2 v) { return TEST_TYPE_UVEC2; } +uint to_type(uvec3 v) { return TEST_TYPE_UVEC3; } +uint to_type(uvec4 v) { return TEST_TYPE_UVEC4; } +uint to_type(vec2 v) { return TEST_TYPE_VEC2; } +uint to_type(vec3 v) { return TEST_TYPE_VEC3; } +uint to_type(vec4 v) { return TEST_TYPE_VEC4; } +uint to_type(mat2x2 v) { return TEST_TYPE_MAT2X2; } +uint to_type(mat2x3 v) { return TEST_TYPE_MAT2X3; } +uint to_type(mat2x4 v) { return TEST_TYPE_MAT2X4; } +uint to_type(mat3x2 v) { return TEST_TYPE_MAT3X2; } +uint to_type(mat3x3 v) { return TEST_TYPE_MAT3X3; } +uint to_type(mat3x4 v) { return TEST_TYPE_MAT3X4; } +uint to_type(mat4x2 v) { return TEST_TYPE_MAT4X2; } +uint to_type(mat4x3 v) { return TEST_TYPE_MAT4X3; } +uint to_type(mat4x4 v) { return TEST_TYPE_MAT4X4; } +// clang-format on + +#define WRITE_MATRIX(v) \ + TestOutputRawData raw; \ + for (int c = 0; c < mat_col_len(v); c++) { \ + for (int r = 0; r < mat_row_len(v); r++) { \ + raw.data[c * mat_row_len(v) + r] = floatBitsToUint(v[c][r]); \ + } \ + } \ + return raw; + +#define WRITE_FLOAT_VECTOR(v) \ + TestOutputRawData raw; \ + for (int c = 0; c < mat_col_len(v); c++) { \ + raw.data[c] = floatBitsToUint(v[c]); \ + } \ + return raw; + +#define WRITE_INT_VECTOR(v) \ + TestOutputRawData raw; \ + for (int c = 0; c < mat_col_len(v); c++) { \ + raw.data[c] = uint(v[c]); \ + } \ + return raw; + +#define WRITE_FLOAT_SCALAR(v) \ + TestOutputRawData raw; \ + raw.data[0] = floatBitsToUint(v); \ + return raw; + +#define WRITE_INT_SCALAR(v) \ + TestOutputRawData raw; \ + raw.data[0] = uint(v); \ + return raw; + +// clang-format off +#ifndef GPU_METAL +TestOutputRawData as_raw_data(bool v) { WRITE_INT_SCALAR(v); } +#endif +TestOutputRawData as_raw_data(uint v) { WRITE_INT_SCALAR(v); } +TestOutputRawData as_raw_data(int v) { WRITE_INT_SCALAR(v); } +TestOutputRawData as_raw_data(float v) { WRITE_FLOAT_SCALAR(v); } +TestOutputRawData as_raw_data(ivec2 v) { WRITE_INT_VECTOR(v); } +TestOutputRawData as_raw_data(ivec3 v) { WRITE_INT_VECTOR(v); } +TestOutputRawData as_raw_data(ivec4 v) { WRITE_INT_VECTOR(v); } +TestOutputRawData as_raw_data(uvec2 v) { WRITE_INT_VECTOR(v); } +TestOutputRawData as_raw_data(uvec3 v) { WRITE_INT_VECTOR(v); } +TestOutputRawData as_raw_data(uvec4 v) { WRITE_INT_VECTOR(v); } +TestOutputRawData as_raw_data(vec2 v) { WRITE_FLOAT_VECTOR(v); } +TestOutputRawData as_raw_data(vec3 v) { WRITE_FLOAT_VECTOR(v); } +TestOutputRawData as_raw_data(vec4 v) { WRITE_FLOAT_VECTOR(v); } +TestOutputRawData as_raw_data(mat2x2 v) { WRITE_MATRIX(v); } +TestOutputRawData as_raw_data(mat2x3 v) { WRITE_MATRIX(v); } +TestOutputRawData as_raw_data(mat2x4 v) { WRITE_MATRIX(v); } +TestOutputRawData as_raw_data(mat3x2 v) { WRITE_MATRIX(v); } +TestOutputRawData as_raw_data(mat3x3 v) { WRITE_MATRIX(v); } +TestOutputRawData as_raw_data(mat3x4 v) { WRITE_MATRIX(v); } +TestOutputRawData as_raw_data(mat4x2 v) { WRITE_MATRIX(v); } +TestOutputRawData as_raw_data(mat4x3 v) { WRITE_MATRIX(v); } +TestOutputRawData as_raw_data(mat4x4 v) { WRITE_MATRIX(v); } +// clang-format on + +int g_test_id = 0; + +#ifdef GPU_COMPUTE_SHADER + +# define EXPECT_OP(OP, val1, val2) \ + out_test[g_test_id++] = test_output( \ + as_raw_data(val1), as_raw_data(val2), bool(OP), int(__LINE__), to_type(val1)) +#else + +/** WORKAROUND: Fragment shader variant for older platform. */ +# define EXPECT_OP(OP, val1, val2) \ + g_test_id += 1; \ + if (g_test_id == 1) { \ + /* Avoid pixels with undefined values. */ \ + out_test = uvec4(0); \ + } \ + if (int(gl_FragCoord.y) == g_test_id - 1) { \ + TestOutput to = test_output( \ + as_raw_data(val1), as_raw_data(val2), bool(OP), int(__LINE__), to_type(val1)); \ + switch (int(gl_FragCoord.x)) { \ + case 0: \ + out_test = uvec4( \ + to.expect.data[0], to.expect.data[1], to.expect.data[2], to.expect.data[3]); \ + break; \ + case 1: \ + out_test = uvec4( \ + to.expect.data[4], to.expect.data[5], to.expect.data[6], to.expect.data[7]); \ + break; \ + case 2: \ + out_test = uvec4( \ + to.expect.data[8], to.expect.data[9], to.expect.data[10], to.expect.data[11]); \ + break; \ + case 3: \ + out_test = uvec4( \ + to.expect.data[12], to.expect.data[13], to.expect.data[14], to.expect.data[15]); \ + break; \ + case 4: \ + out_test = uvec4( \ + to.result.data[0], to.result.data[1], to.result.data[2], to.result.data[3]); \ + break; \ + case 5: \ + out_test = uvec4( \ + to.result.data[4], to.result.data[5], to.result.data[6], to.result.data[7]); \ + break; \ + case 6: \ + out_test = uvec4( \ + to.result.data[8], to.result.data[9], to.result.data[10], to.result.data[11]); \ + break; \ + case 7: \ + out_test = uvec4( \ + to.result.data[12], to.result.data[13], to.result.data[14], to.result.data[15]); \ + break; \ + case 8: \ + out_test = uvec4(to.status, to.line, to.type, 0); \ + break; \ + } \ + } + +#endif + +#define EXPECT_EQ(result, expect) EXPECT_OP((result) == (expect), result, expect) +#define EXPECT_NE(result, expect) EXPECT_OP((result) != (expect), result, expect) +#define EXPECT_LE(result, expect) EXPECT_OP((result) <= (expect), result, expect) +#define EXPECT_LT(result, expect) EXPECT_OP((result) < (expect), result, expect) +#define EXPECT_GE(result, expect) EXPECT_OP((result) >= (expect), result, expect) +#define EXPECT_GT(result, expect) EXPECT_OP((result) > (expect), result, expect) + +#define EXPECT_TRUE(result) EXPECT_OP(result, result, true) +#define EXPECT_FALSE(result) EXPECT_OP(!result, result, false) + +#define EXPECT_NEAR(result, expect, threshold) \ + EXPECT_OP(is_equal(result, expect, threshold), result, expect) diff --git a/source/blender/gpu/shaders/common/gpu_shader_utildefines_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_utildefines_lib.glsl new file mode 100644 index 00000000000..d56603e5ded --- /dev/null +++ b/source/blender/gpu/shaders/common/gpu_shader_utildefines_lib.glsl @@ -0,0 +1,96 @@ + +/* WORKAROUND: to guard against double include in EEVEE. */ +#ifndef GPU_SHADER_UTILDEFINES_GLSL +#define GPU_SHADER_UTILDEFINES_GLSL + +#ifndef FLT_MAX +# define FLT_MAX uintBitsToFloat(0x7F7FFFFFu) +# define FLT_MIN uintBitsToFloat(0x00800000u) +# define FLT_EPSILON 1.192092896e-07F +# define SHRT_MAX 0x00007FFF +# define INT_MAX 0x7FFFFFFF +# define USHRT_MAX 0x0000FFFFu +# define UINT_MAX 0xFFFFFFFFu +#endif +#define NAN_FLT uintBitsToFloat(0x7FC00000u) + +#define UNPACK2(a) (a)[0], (a)[1] +#define UNPACK3(a) (a)[0], (a)[1], (a)[2] +#define UNPACK4(a) (a)[0], (a)[1], (a)[2], (a)[3] + +/** + * Clamp input into [0..1] range. + */ +#define saturate(a) clamp(a, 0.0, 1.0) + +#define isfinite(a) (!isinf(a) && !isnan(a)) + +/* clang-format off */ +#define in_range_inclusive(val, min_v, max_v) (all(greaterThanEqual(val, min_v)) && all(lessThanEqual(val, max_v))) +#define in_range_exclusive(val, min_v, max_v) (all(greaterThan(val, min_v)) && all(lessThan(val, max_v))) +#define in_texture_range(texel, tex) (all(greaterThanEqual(texel, ivec2(0))) && all(lessThan(texel, textureSize(tex, 0).xy))) +#define in_image_range(texel, tex) (all(greaterThanEqual(texel, ivec2(0))) && all(lessThan(texel, imageSize(tex).xy))) +/* clang-format on */ + +bool flag_test(uint flag, uint val) +{ + return (flag & val) != 0u; +} +bool flag_test(int flag, uint val) +{ + return flag_test(uint(flag), val); +} +bool flag_test(int flag, int val) +{ + return (flag & val) != 0; +} + +void set_flag_from_test(inout uint value, bool test, uint flag) +{ + if (test) { + value |= flag; + } + else { + value &= ~flag; + } +} +void set_flag_from_test(inout int value, bool test, int flag) +{ + if (test) { + value |= flag; + } + else { + value &= ~flag; + } +} + +/* Keep define to match C++ implementation. */ +#define SET_FLAG_FROM_TEST(value, test, flag) flag_test(value, test, flag) + +/** + * Pack two 16-bit uint into one 32-bit uint. + */ +uint packUvec2x16(uvec2 data) +{ + data = (data & 0xFFFFu) << uvec2(0u, 16u); + return data.x | data.y; +} +uvec2 unpackUvec2x16(uint data) +{ + return (uvec2(data) >> uvec2(0u, 16u)) & uvec2(0xFFFFu); +} + +/** + * Pack four 8-bit uint into one 32-bit uint. + */ +uint packUvec4x8(uvec4 data) +{ + data = (data & 0xFFu) << uvec4(0u, 8u, 16u, 24u); + return data.x | data.y | data.z | data.w; +} +uvec4 unpackUvec4x8(uint data) +{ + return (uvec4(data) >> uvec4(0u, 8u, 16u, 24u)) & uvec4(0xFFu); +} + +#endif /* GPU_SHADER_UTILDEFINES_GLSL */ diff --git a/source/blender/gpu/shaders/infos/gpu_shader_test_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_test_info.hh new file mode 100644 index 00000000000..358b5b3c5ac --- /dev/null +++ b/source/blender/gpu/shaders/infos/gpu_shader_test_info.hh @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2022 Blender Foundation. All rights reserved. */ + +/** \file + * \ingroup gpu + */ + +#include "gpu_interface_info.hh" +#include "gpu_shader_create_info.hh" + +GPU_SHADER_CREATE_INFO(gpu_shader_test) + .typedef_source("GPU_shader_shared.h") + .fragment_out(0, Type::UVEC4, "out_test") + .additional_info("draw_fullscreen"); + +GPU_SHADER_CREATE_INFO(gpu_math_test) + .fragment_source("gpu_math_test.glsl") + .additional_info("gpu_shader_test") + .do_static_compilation(true); diff --git a/source/blender/gpu/tests/gpu_math_test.glsl b/source/blender/gpu/tests/gpu_math_test.glsl new file mode 100644 index 00000000000..ffd4faa760c --- /dev/null +++ b/source/blender/gpu/tests/gpu_math_test.glsl @@ -0,0 +1,290 @@ +/* Directive for resetting the line numbering so the failing tests lines can be printed. + * This conflict with the shader compiler error logging scheme. + * Comment out for correct compilation error line. */ +#line 5 + +#pragma BLENDER_REQUIRE(gpu_shader_math_matrix_lib.glsl) +#pragma BLENDER_REQUIRE(gpu_shader_test_lib.glsl) + +#define TEST(a, b) if (true) + +void main() +{ + TEST(math_matrix, MatrixInverse) + { + mat3x3 mat = mat3x3__diagonal(2); + mat3x3 inv = invert(mat); + mat3x3 expect = mat3x3__diagonal(0.5f); + EXPECT_NEAR(inv, expect, 1e-5f); + + bool success; + mat3x3 m2 = mat3x3__all(1); + mat3x3 inv2 = invert(m2, success); + mat3x3 expect2 = mat3x3__all(0); + EXPECT_NEAR(inv2, expect2, 1e-5f); + EXPECT_FALSE(success); + } + + TEST(math_matrix, MatrixDeterminant) + { + mat2x2 m2 = mat2x2(vec2(1, 2), vec2(3, 4)); + mat3x3 m3 = mat3x3(vec3(1, 2, 3), vec3(-3, 4, -5), vec3(5, -6, 7)); + mat4x4 m4 = mat4x4(vec4(1, 2, -3, 3), vec4(3, 4, -5, 3), vec4(5, 6, 7, -3), vec4(5, 6, 7, 1)); + EXPECT_NEAR(determinant(m2), -2.0f, 1e-8f); + EXPECT_NEAR(determinant(m3), -16.0f, 1e-8f); + EXPECT_NEAR(determinant(m4), -112.0f, 1e-8f); + } + + TEST(math_matrix, MatrixAdjoint) + { + mat2x2 m2 = mat2x2(vec2(1, 2), vec2(3, 4)); + mat3x3 m3 = mat3x3(vec3(1, 2, 3), vec3(-3, 4, -5), vec3(5, -6, 7)); + mat4x4 m4 = mat4x4(vec4(1, 2, -3, 3), vec4(3, 4, -5, 3), vec4(5, 6, 7, -3), vec4(5, 6, 7, 1)); + mat2x2 expect2 = transpose(mat2x2(vec2(4, -3), vec2(-2, 1))); + mat3x3 expect3 = transpose(mat3x3(vec3(-2, -4, -2), vec3(-32, -8, 16), vec3(-22, -4, 10))); + mat4x4 expect4 = transpose(mat4x4(vec4(232, -184, -8, -0), + vec4(-128, 88, 16, 0), + vec4(80, -76, 4, 28), + vec4(-72, 60, -12, -28))); + EXPECT_NEAR(adjoint(m2), expect2, 1e-8f); + EXPECT_NEAR(adjoint(m3), expect3, 1e-8f); + EXPECT_NEAR(adjoint(m4), expect4, 1e-8f); + } + + TEST(math_matrix, MatrixInit) + { + mat4x4 expect; + + mat4x4 m = from_location(vec3(1, 2, 3)); + expect = mat4x4(vec4(1, 0, 0, 0), vec4(0, 1, 0, 0), vec4(0, 0, 1, 0), vec4(1, 2, 3, 1)); + EXPECT_TRUE(is_equal(m, expect, 0.00001)); + + expect = transpose(mat4x4(vec4(0.411982, -0.833738, -0.36763, 0), + vec4(-0.0587266, -0.426918, 0.902382, 0), + vec4(-0.909297, -0.350175, -0.224845, 0), + vec4(0, 0, 0, 1))); + EulerXYZ euler = EulerXYZ(1, 2, 3); + Quaternion quat = to_quaternion(euler); + AxisAngle axis_angle = to_axis_angle(euler); + m = mat4(from_rotation(euler)); + EXPECT_NEAR(m, expect, 1e-5); + m = mat4(from_rotation(quat)); + EXPECT_NEAR(m, expect, 1e-5); + m = mat4(from_rotation(axis_angle)); + EXPECT_NEAR(m, expect, 1e-5); + + m = from_scale(vec4(1, 2, 3, 4)); + expect = mat4x4(vec4(1, 0, 0, 0), vec4(0, 2, 0, 0), vec4(0, 0, 3, 0), vec4(0, 0, 0, 4)); + EXPECT_TRUE(is_equal(m, expect, 0.00001)); + + m = mat4(from_scale(vec3(1, 2, 3))); + expect = mat4x4(vec4(1, 0, 0, 0), vec4(0, 2, 0, 0), vec4(0, 0, 3, 0), vec4(0, 0, 0, 1)); + EXPECT_TRUE(is_equal(m, expect, 0.00001)); + + m = mat4(from_scale(vec2(1, 2))); + expect = mat4x4(vec4(1, 0, 0, 0), vec4(0, 2, 0, 0), vec4(0, 0, 1, 0), vec4(0, 0, 0, 1)); + EXPECT_TRUE(is_equal(m, expect, 0.00001)); + + m = from_loc_rot(vec3(1, 2, 3), EulerXYZ(1, 2, 3)); + expect = mat4x4(vec4(0.411982, -0.0587266, -0.909297, 0), + vec4(-0.833738, -0.426918, -0.350175, 0), + vec4(-0.36763, 0.902382, -0.224845, 0), + vec4(1, 2, 3, 1)); + EXPECT_TRUE(is_equal(m, expect, 0.00001)); + + m = from_loc_rot_scale(vec3(1, 2, 3), EulerXYZ(1, 2, 3), vec3(1, 2, 3)); + expect = mat4x4(vec4(0.411982, -0.0587266, -0.909297, 0), + vec4(-1.66748, -0.853835, -0.700351, 0), + vec4(-1.10289, 2.70714, -0.674535, 0), + vec4(1, 2, 3, 1)); + EXPECT_TRUE(is_equal(m, expect, 0.00001)); + } + + TEST(math_matrix, MatrixModify) + { + const float epsilon = 1e-6; + mat4x4 result, expect; + mat4x4 m1 = mat4x4(vec4(0, 3, 0, 0), vec4(2, 0, 0, 0), vec4(0, 0, 2, 0), vec4(0, 0, 0, 1)); + + expect = mat4x4(vec4(0, 3, 0, 0), vec4(2, 0, 0, 0), vec4(0, 0, 2, 0), vec4(4, 9, 2, 1)); + result = translate(m1, vec3(3, 2, 1)); + EXPECT_NEAR(result, expect, epsilon); + + expect = mat4x4(vec4(0, 3, 0, 0), vec4(2, 0, 0, 0), vec4(0, 0, 2, 0), vec4(4, 0, 0, 1)); + result = translate(m1, vec2(0, 2)); + EXPECT_NEAR(result, expect, epsilon); + + expect = mat4x4(vec4(0, 0, -2, 0), vec4(2, 0, 0, 0), vec4(0, 3, 0, 0), vec4(0, 0, 0, 1)); + result = rotate(m1, AxisAngle(vec3(0, 1, 0), M_PI_2)); + EXPECT_NEAR(result, expect, epsilon); + + expect = mat4x4(vec4(0, 9, 0, 0), vec4(4, 0, 0, 0), vec4(0, 0, 8, 0), vec4(0, 0, 0, 1)); + result = scale(m1, vec3(3, 2, 4)); + EXPECT_NEAR(result, expect, epsilon); + + expect = mat4x4(vec4(0, 9, 0, 0), vec4(4, 0, 0, 0), vec4(0, 0, 2, 0), vec4(0, 0, 0, 1)); + result = scale(m1, vec2(3, 2)); + EXPECT_NEAR(result, expect, epsilon); + } + + TEST(math_matrix, MatrixCompareTest) + { + mat4x4 m1 = mat4x4(vec4(0, 3, 0, 0), vec4(2, 0, 0, 0), vec4(0, 0, 2, 0), vec4(0, 0, 0, 1)); + mat4x4 m2 = mat4x4( + vec4(0, 3.001, 0, 0), vec4(1.999, 0, 0, 0), vec4(0, 0, 2.001, 0), vec4(0, 0, 0, 1.001)); + mat4x4 m3 = mat4x4( + vec4(0, 3.001, 0, 0), vec4(1, 1, 0, 0), vec4(0, 0, 2.001, 0), vec4(0, 0, 0, 1.001)); + mat4x4 m4 = mat4x4(vec4(0, 1, 0, 0), vec4(1, 0, 0, 0), vec4(0, 0, 1, 0), vec4(0, 0, 0, 1)); + mat4x4 m5 = mat4x4(vec4(0, 0, 0, 0), vec4(0, 0, 0, 0), vec4(0, 0, 0, 0), vec4(0, 0, 0, 0)); + mat4x4 m6 = mat4x4(vec4(1, 0, 0, 0), vec4(0, 1, 0, 0), vec4(0, 0, 1, 0), vec4(0, 0, 0, 1)); + EXPECT_TRUE(is_equal(m1, m2, 0.01f)); + EXPECT_FALSE(is_equal(m1, m2, 0.0001f)); + EXPECT_FALSE(is_equal(m1, m3, 0.01f)); + EXPECT_TRUE(is_orthogonal(m1)); + EXPECT_FALSE(is_orthogonal(m3)); + EXPECT_TRUE(is_orthonormal(m4)); + EXPECT_FALSE(is_orthonormal(m1)); + EXPECT_FALSE(is_orthonormal(m3)); + EXPECT_FALSE(is_uniformly_scaled(m1)); + EXPECT_TRUE(is_uniformly_scaled(m4)); + EXPECT_FALSE(is_zero(m4)); + EXPECT_TRUE(is_zero(m5)); + EXPECT_TRUE(is_negative(m4)); + EXPECT_FALSE(is_negative(m5)); + EXPECT_FALSE(is_negative(m6)); + } + + TEST(math_matrix, MatrixMethods) + { + mat4x4 m = mat4x4(vec4(0, 3, 0, 0), vec4(2, 0, 0, 0), vec4(0, 0, 2, 0), vec4(0, 1, 0, 1)); + EulerXYZ expect_eul = EulerXYZ(0, 0, M_PI_2); + Quaternion expect_qt = Quaternion(0, -M_SQRT1_2, M_SQRT1_2, 0); + vec3 expect_scale = vec3(3, 2, 2); + vec3 expect_location = vec3(0, 1, 0); + + EXPECT_NEAR(as_vec3(to_euler(m)), as_vec3(expect_eul), 0.0002); + EXPECT_NEAR(as_vec4(to_quaternion(m)), as_vec4(expect_qt), 0.0002); + EXPECT_NEAR(to_scale(m), expect_scale, 0.00001); + + vec4 expect_sz = vec4(3, 2, 2, M_SQRT2); + vec4 size; + mat4x4 m1 = normalize_and_get_size(m, size); + EXPECT_TRUE(is_unit_scale(m1)); + EXPECT_NEAR(size, expect_sz, 0.0002); + + mat4x4 m2 = normalize(m); + EXPECT_TRUE(is_unit_scale(m2)); + + EulerXYZ eul; + Quaternion qt; + vec3 scale; + to_rot_scale(mat3x3(m), eul, scale); + to_rot_scale(mat3x3(m), qt, scale); + EXPECT_NEAR(scale, expect_scale, 0.00001); + EXPECT_NEAR(as_vec4(qt), as_vec4(expect_qt), 0.0002); + EXPECT_NEAR(as_vec3(eul), as_vec3(expect_eul), 0.0002); + + vec3 loc; + to_loc_rot_scale(m, loc, eul, scale); + to_loc_rot_scale(m, loc, qt, scale); + EXPECT_NEAR(scale, expect_scale, 0.00001); + EXPECT_NEAR(loc, expect_location, 0.00001); + EXPECT_NEAR(as_vec4(qt), as_vec4(expect_qt), 0.0002); + EXPECT_NEAR(as_vec3(eul), as_vec3(expect_eul), 0.0002); + } + + TEST(math_matrix, MatrixTranspose) + { + mat4x4 m = mat4x4(vec4(1, 2, 3, 4), vec4(5, 6, 7, 8), vec4(9, 1, 2, 3), vec4(2, 5, 6, 7)); + mat4x4 expect = mat4x4(vec4(1, 5, 9, 2), vec4(2, 6, 1, 5), vec4(3, 7, 2, 6), vec4(4, 8, 3, 7)); + EXPECT_EQ(transpose(m), expect); + } + + TEST(math_matrix, MatrixInterpolationRegular) + { + /* Test 4x4 matrix interpolation without singularity, i.e. without axis flip. */ + + /* Transposed matrix, so that the code here is written in the same way as print_m4() outputs. + */ + /* This matrix represents T=(0.1, 0.2, 0.3), R=(40, 50, 60) degrees, S=(0.7, 0.8, 0.9) */ + mat4x4 m2 = transpose(mat4x4(vec4(0.224976f, -0.333770f, 0.765074f, 0.100000f), + vec4(0.389669f, 0.647565f, 0.168130f, 0.200000f), + vec4(-0.536231f, 0.330541f, 0.443163f, 0.300000f), + vec4(0.000000f, 0.000000f, 0.000000f, 1.000000f))); + mat4x4 m1 = mat4x4__identity(); + mat4x4 result; + const float epsilon = 1e-6; + result = interpolate_fast(m1, m2, 0.0f); + EXPECT_NEAR(result, m1, epsilon); + result = interpolate_fast(m1, m2, 1.0f); + EXPECT_NEAR(result, m2, epsilon); + + /* This matrix is based on the current implementation of the code, and isn't guaranteed to be + * correct. It's just consistent with the current implementation. */ + mat4x4 expect = transpose(mat4x4(vec4(0.690643f, -0.253244f, 0.484996f, 0.050000f), + vec4(0.271924f, 0.852623f, 0.012348f, 0.100000f), + vec4(-0.414209f, 0.137484f, 0.816778f, 0.150000f), + vec4(0.000000f, 0.000000f, 0.000000f, 1.000000f))); + result = interpolate_fast(m1, m2, 0.5f); + EXPECT_NEAR(result, expect, epsilon); + } + + TEST(math_matrix, MatrixTransform) + { + vec3 expect, result; + const vec3 p = vec3(1, 2, 3); + mat4x4 m4 = from_loc_rot(vec3(10, 0, 0), EulerXYZ(M_PI_2, M_PI_2, M_PI_2)); + mat3x3 m3 = from_rotation(EulerXYZ(M_PI_2, M_PI_2, M_PI_2)); + mat4x4 pers4 = projection__perspective(-0.1f, 0.1f, -0.1f, 0.1f, -0.1f, -1.0f); + mat3x3 pers3 = mat3x3(vec3(1, 0, 0.1f), vec3(0, 1, 0.1f), vec3(0, 0.1f, 1)); + + expect = vec3(13, 2, -1); + result = transform_point(m4, p); + EXPECT_NEAR(result, expect, 1e-2); + + expect = vec3(3, 2, -1); + result = transform_point(m3, p); + EXPECT_NEAR(result, expect, 1e-5); + + result = transform_direction(m4, p); + EXPECT_NEAR(result, expect, 1e-5); + + result = transform_direction(m3, p); + EXPECT_NEAR(result, expect, 1e-5); + + expect = vec3(-0.5, -1, -1.7222222); + result = project_point(pers4, p); + EXPECT_NEAR(result, expect, 1e-5); + + vec2 expect2 = vec2(0.76923, 1.61538); + vec2 result2 = project_point(pers3, p.xy); + EXPECT_NEAR(result2, expect2, 1e-5); + } + + TEST(math_matrix, MatrixProjection) + { + mat4x4 expect; + mat4x4 ortho = projection__orthographic(-0.2f, 0.3f, -0.2f, 0.4f, -0.2f, -0.5f); + mat4x4 pers1 = projection__perspective(-0.2f, 0.3f, -0.2f, 0.4f, -0.2f, -0.5f); + mat4x4 pers2 = projection__perspective_fov( + atan(-0.2f), atan(0.3f), atan(-0.2f), atan(0.4f), -0.2f, -0.5f); + + expect = transpose(mat4x4(vec4(4.0f, 0.0f, 0.0f, -0.2f), + vec4(0.0f, 3.33333f, 0.0f, -0.333333f), + vec4(0.0f, 0.0f, 6.66667f, -2.33333f), + vec4(0.0f, 0.0f, 0.0f, 1.0f))); + EXPECT_NEAR(ortho, expect, 1e-5); + + expect = transpose(mat4x4(vec4(-0.8f, 0.0f, 0.2f, 0.0f), + vec4(0.0f, -0.666667f, 0.333333f, 0.0f), + vec4(0.0f, 0.0f, -2.33333f, 0.666667f), + vec4(0.0f, 0.0f, -1.0f, 1.0f))); + EXPECT_NEAR(pers1, expect, 1e-4); + + expect = transpose(mat4x4(vec4(4.0f, 0.0f, 0.2f, 0.0f), + vec4(0.0f, 3.33333f, 0.333333f, 0.0f), + vec4(0.0f, 0.0f, -2.33333f, 0.666667f), + vec4(0.0f, 0.0f, -1.0f, 1.0f))); + EXPECT_NEAR(pers2, expect, 1e-4); + } +} diff --git a/source/blender/gpu/tests/gpu_shader_test.cc b/source/blender/gpu/tests/gpu_shader_test.cc index 35ffc647c97..b3a72d90265 100644 --- a/source/blender/gpu/tests/gpu_shader_test.cc +++ b/source/blender/gpu/tests/gpu_shader_test.cc @@ -2,16 +2,24 @@ #include "testing/testing.h" +#include "BLI_math_matrix_types.hh" +#include "GPU_batch.h" +#include "GPU_batch_presets.h" #include "GPU_capabilities.h" #include "GPU_compute.h" +#include "GPU_context.h" +#include "GPU_framebuffer.h" #include "GPU_index_buffer.h" #include "GPU_shader.h" +#include "GPU_shader_shared.h" #include "GPU_texture.h" #include "GPU_vertex_buffer.h" #include "GPU_vertex_format.h" #include "MEM_guardedalloc.h" +#include "gpu_shader_create_info.hh" +#include "gpu_shader_dependency_private.h" #include "gpu_testing.hh" namespace blender::gpu::tests { @@ -302,4 +310,206 @@ void main() { } GPU_TEST(gpu_shader_ssbo_binding) +static void test_gpu_texture_read() +{ + GPU_render_begin(); + + eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_HOST_READ; + GPUTexture *rgba32u = GPU_texture_create_2d_ex("rgba32u", 1, 1, 1, GPU_RGBA32UI, usage, nullptr); + GPUTexture *rgba16u = GPU_texture_create_2d_ex("rgba16u", 1, 1, 1, GPU_RGBA16UI, usage, nullptr); + GPUTexture *rgba32f = GPU_texture_create_2d_ex("rgba32f", 1, 1, 1, GPU_RGBA32F, usage, nullptr); + + const float4 fcol = {0.0f, 1.3f, -231.0f, 1000.0f}; + const uint4 ucol = {0, 1, 2, 12223}; + GPU_texture_clear(rgba32u, GPU_DATA_UINT, ucol); + GPU_texture_clear(rgba16u, GPU_DATA_UINT, ucol); + GPU_texture_clear(rgba32f, GPU_DATA_FLOAT, fcol); + + GPU_finish(); + + uint4 *rgba32u_data = (uint4 *)GPU_texture_read(rgba32u, GPU_DATA_UINT, 0); + uint4 *rgba16u_data = (uint4 *)GPU_texture_read(rgba16u, GPU_DATA_UINT, 0); + float4 *rgba32f_data = (float4 *)GPU_texture_read(rgba32f, GPU_DATA_FLOAT, 0); + + EXPECT_EQ(ucol, *rgba32u_data); + EXPECT_EQ(ucol, *rgba16u_data); + EXPECT_EQ(fcol, *rgba32f_data); + + MEM_freeN(rgba32u_data); + MEM_freeN(rgba16u_data); + MEM_freeN(rgba32f_data); + + GPU_texture_free(rgba32u); + GPU_texture_free(rgba16u); + GPU_texture_free(rgba32f); + + GPU_render_end(); +} +GPU_TEST(gpu_texture_read) + +static std::string print_test_data(const TestOutputRawData &raw, TestType type) +{ + std::stringstream ss; + switch (type) { + case TEST_TYPE_BOOL: + case TEST_TYPE_UINT: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_INT: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_FLOAT: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_IVEC2: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_IVEC3: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_IVEC4: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_UVEC2: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_UVEC3: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_UVEC4: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_VEC2: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_VEC3: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_VEC4: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_MAT2X2: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_MAT2X3: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_MAT2X4: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_MAT3X2: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_MAT3X3: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_MAT3X4: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_MAT4X2: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_MAT4X3: + ss << *reinterpret_cast(&raw); + break; + case TEST_TYPE_MAT4X4: + ss << *reinterpret_cast(&raw); + break; + default: + ss << *reinterpret_cast *>(&raw); + break; + } + return ss.str(); +} + +static StringRef print_test_line(StringRefNull test_src, int64_t test_line) +{ + /* Start at line one like the line report scheme. */ + int64_t line = 1; + int64_t last_pos = 0; + int64_t pos = 0; + while ((pos = test_src.find('\n', pos)) != std::string::npos) { + if (line == test_line) { + return test_src.substr(last_pos, pos - last_pos); + } + pos += 1; /* Skip newline */ + last_pos = pos; + line++; + } + return ""; +} + +static void gpu_shader_lib_test(const char *test_src_name) +{ + using namespace shader; + + GPU_render_begin(); + + ShaderCreateInfo create_info(test_src_name); + create_info.fragment_source(test_src_name); + create_info.additional_info("gpu_shader_test"); + + StringRefNull test_src = gpu_shader_dependency_get_source(test_src_name); + + GPUShader *shader = GPU_shader_create_from_info( + reinterpret_cast(&create_info)); + GPU_shader_bind(shader); + + int test_count = 0; + /* Count tests. */ + int64_t pos = 0; + StringRefNull target = "EXPECT_"; + while ((pos = test_src.find(target, pos)) != std::string::npos) { + test_count++; + pos += sizeof("EXPECT_"); + } + + int test_output_px_len = divide_ceil_u(sizeof(TestOutput), 4 * 4); + + eGPUTextureUsage usage = GPU_TEXTURE_USAGE_ATTACHMENT | GPU_TEXTURE_USAGE_HOST_READ; + GPUTexture *tex = GPU_texture_create_2d_ex( + "tx", test_output_px_len, test_count, 1, GPU_RGBA32UI, usage, nullptr); + GPUFrameBuffer *fb = GPU_framebuffer_create("test_fb"); + GPU_framebuffer_ensure_config(&fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(tex)}); + GPU_framebuffer_bind(fb); + + GPU_batch_draw_advanced(GPU_batch_preset_quad(), 0, 3, 0, 1); + + GPU_finish(); + + TestOutput *test_data = (TestOutput *)GPU_texture_read(tex, GPU_DATA_UINT, 0); + Span tests(test_data, test_count); + + for (const TestOutput &test : tests) { + if (ELEM(test.status, TEST_STATUS_NONE, TEST_STATUS_PASSED)) { + continue; + } + else if (test.status == TEST_STATUS_FAILED) { + ADD_FAILURE_AT(test_src_name, test.line) + << "Value of: " << print_test_line(test_src, test.line) << "\n" + << " Actual: " << print_test_data(test.expect, TestType(test.type)) << "\n" + << "Expected: " << print_test_data(test.result, TestType(test.type)) << "\n"; + } + else { + BLI_assert_unreachable(); + } + } + + MEM_freeN(test_data); + + /* Cleanup. */ + GPU_shader_unbind(); + GPU_shader_free(shader); + GPU_framebuffer_free(fb); + GPU_texture_free(tex); + + GPU_render_end(); +} + +static void test_gpu_math_lib() +{ + gpu_shader_lib_test("gpu_math_test.glsl"); +} +GPU_TEST(gpu_math_lib) + } // namespace blender::gpu::tests From ed1df2ce2b5603de450994714d7510a131d01404 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 6 Jan 2023 22:50:51 +0100 Subject: [PATCH 0493/1522] Cleanup: use slightly more efficient method to add multi-function parameter This avoids one `GVArray` move. --- source/blender/nodes/intern/geometry_nodes_lazy_function.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 9b26756f2ff..9c4f04e8248 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -360,7 +360,7 @@ static void execute_multi_function_on_value_or_field( const ValueOrFieldCPPType &type = *input_types[i]; const void *value_or_field = input_values[i]; const void *value = type.get_value_ptr(value_or_field); - params.add_readonly_single_input(GVArray::ForSingleRef(type.value, 1, value)); + params.add_readonly_single_input(GPointer{type.value, value}); } for (const int i : output_types.index_range()) { const ValueOrFieldCPPType &type = *output_types[i]; From 1a8675b48db1671440c8ee932c03f2a516820e23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Sat, 7 Jan 2023 00:18:46 +0100 Subject: [PATCH 0494/1522] GPU: Fix test on metal --- source/blender/gpu/tests/gpu_shader_test.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/tests/gpu_shader_test.cc b/source/blender/gpu/tests/gpu_shader_test.cc index b3a72d90265..abf0a007b3a 100644 --- a/source/blender/gpu/tests/gpu_shader_test.cc +++ b/source/blender/gpu/tests/gpu_shader_test.cc @@ -453,7 +453,6 @@ static void gpu_shader_lib_test(const char *test_src_name) GPUShader *shader = GPU_shader_create_from_info( reinterpret_cast(&create_info)); - GPU_shader_bind(shader); int test_count = 0; /* Count tests. */ @@ -473,7 +472,17 @@ static void gpu_shader_lib_test(const char *test_src_name) GPU_framebuffer_ensure_config(&fb, {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(tex)}); GPU_framebuffer_bind(fb); - GPU_batch_draw_advanced(GPU_batch_preset_quad(), 0, 3, 0, 1); + /* TODO(fclem): remove this boilerplate. */ + GPUVertFormat format{}; + GPU_vertformat_attr_add(&format, "dummy", GPU_COMP_U32, 1, GPU_FETCH_INT); + GPUVertBuf *verts = GPU_vertbuf_create_with_format(&format); + GPU_vertbuf_data_alloc(verts, 3); + GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_TRIS, verts, nullptr, GPU_BATCH_OWNS_VBO); + + GPU_batch_set_shader(batch, shader); + GPU_batch_draw_advanced(batch, 0, 3, 0, 1); + + GPU_batch_discard(batch); GPU_finish(); From 1942d55c0745566f924ebe2da33c3b2c3281d278 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 7 Jan 2023 12:25:10 +0100 Subject: [PATCH 0495/1522] Cleanup: remove unused code --- source/blender/functions/FN_multi_function_context.hh | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/source/blender/functions/FN_multi_function_context.hh b/source/blender/functions/FN_multi_function_context.hh index 7452bfced3b..0ffd58dfca9 100644 --- a/source/blender/functions/FN_multi_function_context.hh +++ b/source/blender/functions/FN_multi_function_context.hh @@ -21,18 +21,11 @@ namespace blender::fn { class MFContext; class MFContextBuilder { - private: - friend MFContext; - - public: }; class MFContext { - private: - MFContextBuilder &builder_; - public: - MFContext(MFContextBuilder &builder) : builder_(builder) + MFContext(MFContextBuilder & /*builder*/) { } }; From 1bbf1ed03c081e61f5c76688a46d12e92da2856f Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 7 Jan 2023 12:55:48 +0100 Subject: [PATCH 0496/1522] Functions: improve devirtualization in multi-function builder This refactors how devirtualization is done in general and how multi-functions use it. * The old `Devirtualizer` class has been removed in favor of a simpler solution. It is also more general in the sense that it is not coupled with `IndexMask` and `VArray`. Instead there is a function that has inputs which control how different types are devirtualized. The new implementation is currently less general with regard to the number of parameters it supports. This can be changed in the future, but does not seem necessary now and would make the code less obvious. * Devirtualizers for different types are now defined in their respective headers. * The multi-function builder works with the `GVArray` stored in `MFParams` directly now, instead of first converting it to a `VArray`. This reduces some constant overhead, which makes the multi-function slightly faster. This is only noticable when very few elements are processed though. No functional changes or performance regressions are expected. --- .../intern/curve_to_mesh_convert.cc | 1 - .../blenlib/BLI_devirtualize_parameters.hh | 403 ++++++------------ .../blenlib/BLI_generic_virtual_array.hh | 22 + source/blender/blenlib/BLI_index_mask.hh | 18 + source/blender/blenlib/BLI_virtual_array.hh | 65 +++ .../draw/intern/draw_cache_impl_curves.cc | 1 - .../editors/curves/intern/curves_ops.cc | 1 - .../functions/FN_multi_function_builder.hh | 162 +++---- .../functions/FN_multi_function_param_type.hh | 3 - .../blender/geometry/intern/fillet_curves.cc | 1 - .../geometry/intern/mesh_split_edges.cc | 1 - .../geometry/intern/mesh_to_curve_convert.cc | 1 - .../geometry/intern/realize_instances.cc | 1 - .../geometry/nodes/node_geo_curve_sample.cc | 1 - 14 files changed, 315 insertions(+), 366 deletions(-) diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index 14c41811505..9e8eaccb024 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "BLI_array.hh" -#include "BLI_devirtualize_parameters.hh" #include "BLI_set.hh" #include "BLI_task.hh" diff --git a/source/blender/blenlib/BLI_devirtualize_parameters.hh b/source/blender/blenlib/BLI_devirtualize_parameters.hh index 77b6223f310..2086c81b30d 100644 --- a/source/blender/blenlib/BLI_devirtualize_parameters.hh +++ b/source/blender/blenlib/BLI_devirtualize_parameters.hh @@ -26,302 +26,139 @@ * times and binary sizes, depending on the number of parameters that are devirtualized separately. * So there is always a trade-off between run-time performance and compile-time/binary-size. * - * This file provides a utility to devirtualize array parameters to a function using a high level - * API. This makes it easy to experiment with different extremes of the mentioned trade-off and - * allows finding a good compromise for each function. + * This file provides a utility to devirtualize function parameters using a high level API. This + * makes it easy to experiment with different extremes of the mentioned trade-off and allows + * finding a good compromise for each function. */ -#include "BLI_parameter_pack_utils.hh" -#include "BLI_virtual_array.hh" - -namespace blender::devirtualize_parameters { - -/** - * Bit flag that specifies how an individual parameter is or can be devirtualized. - */ -enum class DeviMode { - /* This is used as zero-value to compare to, to avoid casting to int. */ - None = 0, - /* Don't use devirtualization for that parameter, just pass it along. */ - Keep = (1 << 0), - /* Devirtualize #Varray as #Span. */ - Span = (1 << 1), - /* Devirtualize #VArray as #SingleAsSpan. */ - Single = (1 << 2), - /* Devirtualize #IndexMask as #IndexRange. */ - Range = (1 << 3), -}; -ENUM_OPERATORS(DeviMode, DeviMode::Range); - -/** Utility to encode multiple #DeviMode in a type. */ -template using DeviModeSequence = ValueSequence; - -/** - * Main class that performs the devirtualization. - */ -template class Devirtualizer { - private: - /** Utility to get the tag of the I-th source type. */ - template - using type_at_index = typename TypeSequence::template at_index; - static constexpr size_t SourceTypesNum = sizeof...(SourceTypes); - - /** Function to devirtualize. */ - Fn fn_; - - /** - * Source values that will be devirtualized. Note that these are stored as pointers to avoid - * unnecessary copies. The caller is responsible for keeping the memory alive. - */ - std::tuple sources_; - - /** Keeps track of whether #fn_ has been called already to avoid calling it twice. */ - bool executed_ = false; - - public: - Devirtualizer(Fn fn, const SourceTypes *...sources) : fn_(std::move(fn)), sources_{sources...} - { - } - - /** - * Return true when the function passed to the constructor has been called already. - */ - bool executed() const - { - return executed_; - } - - /** - * At compile time, generates multiple variants of the function, each optimized for a different - * combination of devirtualized parameters. For every parameter, a bit flag is passed that - * determines how it will be devirtualized. At run-time, if possible, one of the generated - * functions is picked and executed. - * - * To check whether the function was called successfully, call #executed() afterwards. - * - * \note This generates an exponential amount of code in the final binary, depending on how many - * to-be-virtualized parameters there are. - */ - template - void try_execute_devirtualized(DeviModeSequence /* allowed_modes */) - { - BLI_assert(!executed_); - static_assert(sizeof...(AllowedModes) == SourceTypesNum); - this->try_execute_devirtualized_impl(DeviModeSequence<>(), - DeviModeSequence()); - } - - /** - * Execute the function and pass in the original parameters without doing any devirtualization. - */ - void execute_without_devirtualization() - { - BLI_assert(!executed_); - this->try_execute_devirtualized_impl_call( - make_value_sequence(), - std::make_index_sequence()); - } - - private: - /** - * A recursive method that generates all the combinations of devirtualized parameters that the - * caller requested. A recursive function is necessary to achieve generating an exponential - * number of function calls (which has to be used with care, but is expected here). - * - * At every recursive step, the #DeviMode of one parameter is determined. This is achieved by - * extending #DeviModeSequence by one element in each step. The recursion ends once all - * parameters are handled. - * - * \return True when the function has been executed. - */ - template - bool try_execute_devirtualized_impl( - /* Initially empty, but then extended by one element in each recursive step. */ - DeviModeSequence /* modes */, - /* Bit flag for every parameter. */ - DeviModeSequence /* allowed_modes */) - { - static_assert(SourceTypesNum == sizeof...(AllowedModes)); - if constexpr (SourceTypesNum == sizeof...(Mode)) { - /* End of recursion, now call the function with the determined #DeviModes. */ - this->try_execute_devirtualized_impl_call(DeviModeSequence(), - std::make_index_sequence()); - return true; - } - else { - /* Index of the parameter that is checked in the current recursive step. */ - constexpr size_t I = sizeof...(Mode); - /* Non-devirtualized parameter type. */ - using SourceType = type_at_index; - /* A bit flag indicating what devirtualizations are allowed in this step. */ - [[maybe_unused]] constexpr DeviMode allowed_modes = - DeviModeSequence::template at_index(); - - /* Handle #VArray types. */ - if constexpr (is_VArray_v) { - /* The actual virtual array, used for dynamic dispatch at run-time. */ - const SourceType &varray = *std::get(sources_); - /* Check if the virtual array is a single value. */ - if constexpr ((allowed_modes & DeviMode::Single) != DeviMode::None) { - if (varray.is_single()) { - if (this->try_execute_devirtualized_impl(DeviModeSequence(), - DeviModeSequence())) { - return true; - } - } - } - /* Check if the virtual array is a span. */ - if constexpr ((allowed_modes & DeviMode::Span) != DeviMode::None) { - if (varray.is_span()) { - if (this->try_execute_devirtualized_impl(DeviModeSequence(), - DeviModeSequence())) { - return true; - } - } - } - /* Check if it is ok if the virtual array is not devirtualized. */ - if constexpr ((allowed_modes & DeviMode::Keep) != DeviMode::None) { - if (this->try_execute_devirtualized_impl(DeviModeSequence(), - DeviModeSequence())) { - return true; - } - } - } - - /* Handle #IndexMask. */ - else if constexpr (std::is_same_v) { - /* Check if the mask is actually a contiguous range. */ - if constexpr ((allowed_modes & DeviMode::Range) != DeviMode::None) { - /* The actual mask used for dynamic dispatch at run-time. */ - const IndexMask &mask = *std::get(sources_); - if (mask.is_range()) { - if (this->try_execute_devirtualized_impl(DeviModeSequence(), - DeviModeSequence())) { - return true; - } - } - } - /* Check if mask is also allowed to stay a span. */ - if constexpr ((allowed_modes & DeviMode::Span) != DeviMode::None) { - if (this->try_execute_devirtualized_impl(DeviModeSequence(), - DeviModeSequence())) { - return true; - } - } - } - - /* Handle unknown types. */ - else { - if (this->try_execute_devirtualized_impl(DeviModeSequence(), - DeviModeSequence())) { - return true; - } - } - } - return false; - } - - /** - * Actually call the function with devirtualized parameters. - */ - template - void try_execute_devirtualized_impl_call(DeviModeSequence /* modes */, - std::index_sequence /* indices */) - { - - BLI_assert(!executed_); - fn_(this->get_devirtualized_parameter()...); - executed_ = true; - } - - /** - * Return the I-th parameter devirtualized using the passed in #DeviMode. This has different - * return types based on the template parameters. - * - * \note It is expected that the caller already knows that the parameter can be devirtualized - * with the given mode. - */ - template decltype(auto) get_devirtualized_parameter() - { - using SourceType = type_at_index; - static_assert(Mode != DeviMode::None); - if constexpr (Mode == DeviMode::Keep) { - /* Don't change the original parameter at all. */ - return *std::get(sources_); - } - if constexpr (is_VArray_v) { - const SourceType &varray = *std::get(sources_); - if constexpr (Mode == DeviMode::Single) { - /* Devirtualize virtual array as single value. */ - return SingleAsSpan(varray); - } - else if constexpr (Mode == DeviMode::Span) { - /* Devirtualize virtual array as span. */ - return varray.get_internal_span(); - } - } - else if constexpr (std::is_same_v) { - const IndexMask &mask = *std::get(sources_); - if constexpr (ELEM(Mode, DeviMode::Span)) { - /* Don't devirtualize mask, it's still a span. */ - return mask; - } - else if constexpr (Mode == DeviMode::Range) { - /* Devirtualize the mask as range. */ - return mask.as_range(); - } - } - } -}; - -} // namespace blender::devirtualize_parameters - namespace blender { /** - * Generate multiple versions of the given function optimized for different virtual arrays. - * One has to be careful with nesting multiple devirtualizations, because that results in an - * exponential number of function instantiations (increasing compile time and binary size). + * Calls the given function with devirtualized parameters if possible. Note that using many + * non-trivial devirtualizers results in exponential code growth. * - * Generally, this function should only be used when the virtual method call overhead to get an - * element from a virtual array is significant. + * \return True if the function has been called. + * + * Every devirtualizer is expected to have a `devirtualize(auto fn) -> bool` method. + * This method is expected to do one of two things: + * - Call `fn` with the devirtualized argument and return what `fn` returns. + * - Don't call `fn` (because the devirtualization failed) and return false. + * + * Examples for devirtualizers: #BasicDevirtualizer, #IndexMaskDevirtualizer, #VArrayDevirtualizer. */ -template -inline void devirtualize_varray(const VArray &varray, const Func &func, bool enable = true) +template +inline bool call_with_devirtualized_parameters(const std::tuple &devis, + const Fn &fn) { - using namespace devirtualize_parameters; - if (enable) { - Devirtualizer> devirtualizer(func, &varray); - constexpr DeviMode devi_mode = DeviMode::Single | DeviMode::Span; - devirtualizer.try_execute_devirtualized(DeviModeSequence()); - if (devirtualizer.executed()) { - return; - } + /* In theory the code below could be generalized to avoid code duplication. However, the maximum + * number of parameters is expected to be relatively low. Explicitely implementing the different + * cases makes it more obvious to see what is going on and also makes inlining everything easier + * for the compiler. */ + constexpr size_t DeviNum = sizeof...(Devirtualizers); + if constexpr (DeviNum == 0) { + fn(); + return true; } - func(varray); + if constexpr (DeviNum == 1) { + return std::get<0>(devis).devirtualize([&](auto param0) { + fn(param0); + return true; + }); + } + if constexpr (DeviNum == 2) { + return std::get<0>(devis).devirtualize([&](auto &¶m0) { + return std::get<1>(devis).devirtualize([&](auto &¶m1) { + fn(param0, param1); + return true; + }); + }); + } + if constexpr (DeviNum == 3) { + return std::get<0>(devis).devirtualize([&](auto &¶m0) { + return std::get<1>(devis).devirtualize([&](auto &¶m1) { + return std::get<2>(devis).devirtualize([&](auto &¶m2) { + fn(param0, param1, param2); + return true; + }); + }); + }); + } + if constexpr (DeviNum == 4) { + return std::get<0>(devis).devirtualize([&](auto &¶m0) { + return std::get<1>(devis).devirtualize([&](auto &¶m1) { + return std::get<2>(devis).devirtualize([&](auto &¶m2) { + return std::get<3>(devis).devirtualize([&](auto &¶m3) { + fn(param0, param1, param2, param3); + return true; + }); + }); + }); + }); + } + if constexpr (DeviNum == 5) { + return std::get<0>(devis).devirtualize([&](auto &¶m0) { + return std::get<1>(devis).devirtualize([&](auto &¶m1) { + return std::get<2>(devis).devirtualize([&](auto &¶m2) { + return std::get<3>(devis).devirtualize([&](auto &¶m3) { + return std::get<4>(devis).devirtualize([&](auto &¶m4) { + fn(param0, param1, param2, param3, param4); + return true; + }); + }); + }); + }); + }); + } + if constexpr (DeviNum == 6) { + return std::get<0>(devis).devirtualize([&](auto &¶m0) { + return std::get<1>(devis).devirtualize([&](auto &¶m1) { + return std::get<2>(devis).devirtualize([&](auto &¶m2) { + return std::get<3>(devis).devirtualize([&](auto &¶m3) { + return std::get<4>(devis).devirtualize([&](auto &¶m4) { + return std::get<5>(devis).devirtualize([&](auto &¶m5) { + fn(param0, param1, param2, param3, param4, param5); + return true; + }); + }); + }); + }); + }); + }); + } + if constexpr (DeviNum == 7) { + return std::get<0>(devis).devirtualize([&](auto &¶m0) { + return std::get<1>(devis).devirtualize([&](auto &¶m1) { + return std::get<2>(devis).devirtualize([&](auto &¶m2) { + return std::get<3>(devis).devirtualize([&](auto &¶m3) { + return std::get<4>(devis).devirtualize([&](auto &¶m4) { + return std::get<5>(devis).devirtualize([&](auto &¶m5) { + return std::get<6>(devis).devirtualize([&](auto &¶m6) { + fn(param0, param1, param2, param3, param4, param5, param6); + return true; + }); + }); + }); + }); + }); + }); + }); + } + return false; } /** - * Same as `devirtualize_varray`, but devirtualizes two virtual arrays at the same time. - * This is better than nesting two calls to `devirtualize_varray`, because it instantiates fewer - * cases. + * A devirtualizer to be used with #call_with_devirtualized_parameters. + * + * This one is very simple, it does not perform any actual devirtualization. It can be used to pass + * parameters to the function that shouldn't be devirtualized. */ -template -inline void devirtualize_varray2(const VArray &varray1, - const VArray &varray2, - const Func &func, - bool enable = true) -{ - using namespace devirtualize_parameters; - if (enable) { - Devirtualizer, VArray> devirtualizer(func, &varray1, &varray2); - constexpr DeviMode devi_mode = DeviMode::Single | DeviMode::Span; - devirtualizer.try_execute_devirtualized(DeviModeSequence()); - if (devirtualizer.executed()) { - return; - } +template struct BasicDevirtualizer { + const T value; + + template bool devirtualize(const Fn &fn) const + { + return fn(this->value); } - func(varray1, varray2); -} +}; } // namespace blender diff --git a/source/blender/blenlib/BLI_generic_virtual_array.hh b/source/blender/blenlib/BLI_generic_virtual_array.hh index e8a27cea6d8..cba767341c1 100644 --- a/source/blender/blenlib/BLI_generic_virtual_array.hh +++ b/source/blender/blenlib/BLI_generic_virtual_array.hh @@ -798,6 +798,28 @@ inline bool GVArrayCommon::is_empty() const /** \} */ +/** To be used with #call_with_devirtualized_parameters. */ +template struct GVArrayDevirtualizer { + const GVArrayImpl &varray_impl; + + template bool devirtualize(const Fn &fn) const + { + const CommonVArrayInfo info = this->varray_impl.common_info(); + const int64_t size = this->varray_impl.size(); + if constexpr (UseSingle) { + if (info.type == CommonVArrayInfo::Type::Single) { + return fn(SingleAsSpan(*static_cast(info.data), size)); + } + } + if constexpr (UseSpan) { + if (info.type == CommonVArrayInfo::Type::Span) { + return fn(Span(static_cast(info.data), size)); + } + } + return false; + } +}; + /* -------------------------------------------------------------------- */ /** \name Inline methods for #GVArray. * \{ */ diff --git a/source/blender/blenlib/BLI_index_mask.hh b/source/blender/blenlib/BLI_index_mask.hh index 6fa3fdb963e..2144955f4f5 100644 --- a/source/blender/blenlib/BLI_index_mask.hh +++ b/source/blender/blenlib/BLI_index_mask.hh @@ -284,4 +284,22 @@ class IndexMask { Vector *r_skip_amounts = nullptr) const; }; +/** To be used with #call_with_devirtualized_parameters. */ +template struct IndexMaskDevirtualizer { + const IndexMask &mask; + + template bool devirtualize(const Fn &fn) const + { + if constexpr (UseRange) { + if (this->mask.is_range()) { + return fn(this->mask.as_range()); + } + } + if constexpr (UseSpan) { + return fn(this->mask.indices()); + } + return false; + } +}; + } // namespace blender diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh index 36f5065c022..189cb85d468 100644 --- a/source/blender/blenlib/BLI_virtual_array.hh +++ b/source/blender/blenlib/BLI_virtual_array.hh @@ -27,6 +27,7 @@ #include "BLI_any.hh" #include "BLI_array.hh" +#include "BLI_devirtualize_parameters.hh" #include "BLI_index_mask.hh" #include "BLI_span.hh" @@ -1312,4 +1313,68 @@ template class SingleAsSpan { } }; +/** To be used with #call_with_devirtualized_parameters. */ +template struct VArrayDevirtualizer { + const VArray &varray; + + template bool devirtualize(const Fn &fn) const + { + const CommonVArrayInfo info = this->varray.common_info(); + const int64_t size = this->varray.size(); + if constexpr (UseSingle) { + if (info.type == CommonVArrayInfo::Type::Single) { + return fn(SingleAsSpan(*static_cast(info.data), size)); + } + } + if constexpr (UseSpan) { + if (info.type == CommonVArrayInfo::Type::Span) { + return fn(Span(static_cast(info.data), size)); + } + } + return false; + } +}; + +/** + * Generate multiple versions of the given function optimized for different virtual arrays. + * One has to be careful with nesting multiple devirtualizations, because that results in an + * exponential number of function instantiations (increasing compile time and binary size). + * + * Generally, this function should only be used when the virtual method call overhead to get an + * element from a virtual array is significant. + */ +template +inline void devirtualize_varray(const VArray &varray, const Func &func, bool enable = true) +{ + if (enable) { + if (call_with_devirtualized_parameters( + std::make_tuple(VArrayDevirtualizer{varray}), func)) { + return; + } + } + func(varray); +} + +/** + * Same as `devirtualize_varray`, but devirtualizes two virtual arrays at the same time. + * This is better than nesting two calls to `devirtualize_varray`, because it instantiates fewer + * cases. + */ +template +inline void devirtualize_varray2(const VArray &varray1, + const VArray &varray2, + const Func &func, + bool enable = true) +{ + if (enable) { + if (call_with_devirtualized_parameters( + std::make_tuple(VArrayDevirtualizer{varray1}, + VArrayDevirtualizer{varray2}), + func)) { + return; + } + } + func(varray1, varray2); +} + } // namespace blender diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index c7d7a6f61ea..751fb95ce74 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -11,7 +11,6 @@ #include "MEM_guardedalloc.h" -#include "BLI_devirtualize_parameters.hh" #include "BLI_listbase.h" #include "BLI_math_base.h" #include "BLI_math_vector.hh" diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 924967aad8a..46ccc02eabc 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -7,7 +7,6 @@ #include #include "BLI_array_utils.hh" -#include "BLI_devirtualize_parameters.hh" #include "BLI_index_mask_ops.hh" #include "BLI_utildefines.h" #include "BLI_vector_set.hh" diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index 7a936f34bd2..b0876c13729 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -10,14 +10,10 @@ #include -#include "BLI_devirtualize_parameters.hh" - #include "FN_multi_function.hh" namespace blender::fn { -namespace devi = devirtualize_parameters; - /** * These presets determine what code is generated for a #CustomMF. Different presets make different * trade-offs between run-time performance and compile-time/binary size. @@ -63,14 +59,24 @@ struct AllSpanOrSingle { static constexpr bool use_devirtualization = true; static constexpr FallbackMode fallback_mode = FallbackMode::Materialized; - template - void try_devirtualize(devi::Devirtualizer &devirtualizer) + template + auto create_devirtualizers(TypeSequence /*param_tags*/, + std::index_sequence /*indices*/, + const IndexMask &mask, + const std::tuple &loaded_params) { - using devi::DeviMode; - devirtualizer.try_execute_devirtualized( - make_value_sequence()); + return std::make_tuple(IndexMaskDevirtualizer{mask}, [&]() { + typedef ParamTags ParamTag; + typedef typename ParamTag::base_type T; + if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + const GVArrayImpl &varray_impl = *std::get(loaded_params); + return GVArrayDevirtualizer{varray_impl}; + } + else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { + T *ptr = std::get(loaded_params); + return BasicDevirtualizer{ptr}; + } + }()...); } }; @@ -83,17 +89,26 @@ template struct SomeSpanOrSingle { static constexpr bool use_devirtualization = true; static constexpr FallbackMode fallback_mode = FallbackMode::Materialized; - template - void try_devirtualize(devi::Devirtualizer &devirtualizer) + template + auto create_devirtualizers(TypeSequence /*param_tags*/, + std::index_sequence /*indices*/, + const IndexMask &mask, + const std::tuple &loaded_params) { - using devi::DeviMode; - devirtualizer.try_execute_devirtualized( - make_two_value_sequence()); + return std::make_tuple(IndexMaskDevirtualizer{mask}, [&]() { + typedef ParamTags ParamTag; + typedef typename ParamTag::base_type T; + + if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + constexpr bool UseSpan = ValueSequence::template contains(); + const GVArrayImpl &varray_impl = *std::get(loaded_params); + return GVArrayDevirtualizer{varray_impl}; + } + else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { + T *ptr = std::get(loaded_params); + return BasicDevirtualizer{ptr}; + } + }()...); } }; @@ -107,8 +122,8 @@ namespace detail { * instead of a `VArray`). */ template -void execute_array(TypeSequence /* param_tags */, - std::index_sequence /* indices */, +void execute_array(TypeSequence /*param_tags*/, + std::index_sequence /*indices*/, ElementFn element_fn, MaskT mask, /* Use restrict to tell the compiler that pointer inputs do not alias each @@ -125,7 +140,7 @@ void execute_array(TypeSequence /* param_tags */, else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { /* For outputs, pass a pointer to the function. This is done instead of passing a * reference, because the pointer points to uninitialized memory. */ - return &args[i]; + return args + i; } }()...); } @@ -151,7 +166,7 @@ template struct ArgInfo { * Similar to #execute_array but accepts two mask inputs, one for inputs and one for outputs. */ template -void execute_materialized_impl(TypeSequence /* param_tags */, +void execute_materialized_impl(TypeSequence /*param_tags*/, const ElementFn element_fn, const IndexRange in_mask, const IndexMask out_mask, @@ -168,7 +183,7 @@ void execute_materialized_impl(TypeSequence /* param_tags */, } else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { /* For outputs, a pointer is passed, because the memory is uninitialized. */ - return &chunks[out_i]; + return chunks + out_i; } }()...); } @@ -179,12 +194,12 @@ void execute_materialized_impl(TypeSequence /* param_tags */, * separately, processing happens in chunks. This allows retrieving from input virtual arrays in * chunks, which reduces virtual function call overhead. */ -template +template void execute_materialized(TypeSequence /* param_tags */, std::index_sequence /* indices */, const ElementFn element_fn, const IndexMask mask, - Args &&...args) + const std::tuple &loaded_params) { /* In theory, all elements could be processed in one chunk. However, that has the disadvantage @@ -212,19 +227,21 @@ void execute_materialized(TypeSequence /* param_tags */, typedef typename ParamTag::base_type T; [[maybe_unused]] ArgInfo &arg_info = std::get(args_info); if constexpr (ParamTag::category == MFParamCategory::SingleInput) { - VArray &varray = *args; - if (varray.is_single()) { + const GVArrayImpl &varray_impl = *std::get(loaded_params); + const CommonVArrayInfo common_info = varray_impl.common_info(); + if (common_info.type == CommonVArrayInfo::Type::Single) { /* If an input #VArray is a single value, we have to fill the buffer with that value * only once. The same unchanged buffer can then be reused in every chunk. */ MutableSpan in_chunk{std::get(buffers_owner).ptr(), buffer_size}; - const T in_single = varray.get_internal_single(); + const T &in_single = *static_cast(common_info.data); uninitialized_fill_n(in_chunk.data(), in_chunk.size(), in_single); std::get(buffers) = in_chunk; arg_info.mode = ArgMode::Single; } - else if (varray.is_span()) { + else if (common_info.type == CommonVArrayInfo::Type::Span) { /* Remember the span so that it doesn't have to be retrieved in every iteration. */ - arg_info.internal_span = varray.get_internal_span(); + const T *ptr = static_cast(common_info.data); + arg_info.internal_span = Span(ptr, varray_impl.size()); } } }(), @@ -254,7 +271,6 @@ void execute_materialized(TypeSequence /* param_tags */, return Span(std::get(buffers)); } else { - const VArray &varray = *args; if (sliced_mask_is_range) { if (!arg_info.internal_span.is_empty()) { /* In this case we can just use an existing span instead of "compressing" it into @@ -264,10 +280,11 @@ void execute_materialized(TypeSequence /* param_tags */, return arg_info.internal_span.slice(sliced_mask_range); } } + const GVArrayImpl &varray_impl = *std::get(loaded_params); /* As a fallback, do a virtual function call to retrieve all elements in the current * chunk. The elements are stored in a temporary buffer reused for every chunk. */ MutableSpan in_chunk{std::get(buffers_owner).ptr(), chunk_size}; - varray.materialize_compressed_to_uninitialized(sliced_mask, in_chunk); + varray_impl.materialize_compressed_to_uninitialized(sliced_mask, in_chunk.data()); /* Remember that this parameter has been materialized, so that the values are * destructed properly when the chunk is done. */ arg_info.mode = ArgMode::Materialized; @@ -276,7 +293,7 @@ void execute_materialized(TypeSequence /* param_tags */, } else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { /* For outputs, just pass a pointer. This is important so that `__restrict` works. */ - return args->data(); + return std::get(loaded_params); } }()...); @@ -344,40 +361,34 @@ template class CustomMF : public MultiFunction { ExecPreset exec_preset, IndexMask mask, MFParams params, - std::index_sequence /* indices */) + std::index_sequence /*indices*/) { - std::tuple retrieved_params; - ( - /* Get all parameters from #params and store them in #retrieved_params. */ - [&]() { - /* Use `typedef` instead of `using` to work around a compiler bug. */ - typedef typename TagsSequence::template at_index ParamTag; - typedef typename ParamTag::base_type T; + /* Contains `const GVArrayImpl *` for inputs and `T *` for outputs. */ + const auto loaded_params = std::make_tuple([&]() { + /* Use `typedef` instead of `using` to work around a compiler bug. */ + typedef typename TagsSequence::template at_index ParamTag; + typedef typename ParamTag::base_type T; - if constexpr (ParamTag::category == MFParamCategory::SingleInput) { - std::get(retrieved_params) = params.readonly_single_input(I); - } - if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { - std::get(retrieved_params) = params.uninitialized_single_output(I); - } - }(), - ...); - - auto array_executor = [&](auto &&...args) { - detail::execute_array(TagsSequence(), - std::make_index_sequence(), - element_fn, - std::forward(args)...); - }; + if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + return params.readonly_single_input(I).get_implementation(); + } + else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { + return static_cast(params.uninitialized_single_output(I).data()); + } + }()...); /* First try devirtualized execution, since this is the most efficient. */ bool executed_devirtualized = false; if constexpr (ExecPreset::use_devirtualization) { - devi::Devirtualizer - devirtualizer{ - array_executor, &mask, [&] { return &std::get(retrieved_params); }()...}; - exec_preset.try_devirtualize(devirtualizer); - executed_devirtualized = devirtualizer.executed(); + const auto devirtualizers = exec_preset.create_devirtualizers( + TagsSequence(), std::index_sequence(), mask, loaded_params); + executed_devirtualized = call_with_devirtualized_parameters( + devirtualizers, [&](auto &&...args) { + detail::execute_array(TagsSequence(), + std::index_sequence(), + element_fn, + std::forward(args)...); + }); } /* If devirtualized execution was disabled or not possible, use a fallback method which is @@ -385,16 +396,23 @@ template class CustomMF : public MultiFunction { if (!executed_devirtualized) { if constexpr (ExecPreset::fallback_mode == CustomMF_presets::FallbackMode::Materialized) { materialize_detail::execute_materialized( - TypeSequence(), std::index_sequence(), element_fn, mask, [&] { - return &std::get(retrieved_params); - }()...); + TagsSequence(), std::index_sequence(), element_fn, mask, loaded_params); } else { - detail::execute_array(TagsSequence(), - std::make_index_sequence(), - element_fn, - mask, - std::get(retrieved_params)...); + detail::execute_array( + TagsSequence(), std::index_sequence(), element_fn, mask, [&]() { + /* Use `typedef` instead of `using` to work around a compiler bug. */ + typedef typename TagsSequence::template at_index ParamTag; + typedef typename ParamTag::base_type T; + if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + const GVArrayImpl &varray_impl = *std::get(loaded_params); + return GVArray(&varray_impl).typed(); + } + else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { + T *ptr = std::get(loaded_params); + return ptr; + } + }()...); } } } diff --git a/source/blender/functions/FN_multi_function_param_type.hh b/source/blender/functions/FN_multi_function_param_type.hh index 8a7284624d1..c7339424f8d 100644 --- a/source/blender/functions/FN_multi_function_param_type.hh +++ b/source/blender/functions/FN_multi_function_param_type.hh @@ -34,9 +34,6 @@ enum class MFParamCategory { template struct MFParamTag { static constexpr MFParamCategory category = Category; using base_type = T; - /* TODO: Doesn't support all categories yet, this can be generalized when necessary. */ - using array_type = - std::conditional_t, MutableSpan>; }; class MFParamType { diff --git a/source/blender/geometry/intern/fillet_curves.cc b/source/blender/geometry/intern/fillet_curves.cc index 5e4f2e35c67..ff8240013fd 100644 --- a/source/blender/geometry/intern/fillet_curves.cc +++ b/source/blender/geometry/intern/fillet_curves.cc @@ -5,7 +5,6 @@ #include "BKE_curves_utils.hh" #include "BKE_geometry_set.hh" -#include "BLI_devirtualize_parameters.hh" #include "BLI_math_geom.h" #include "BLI_math_rotation_legacy.hh" #include "BLI_task.hh" diff --git a/source/blender/geometry/intern/mesh_split_edges.cc b/source/blender/geometry/intern/mesh_split_edges.cc index 5cf7d4bb935..f5470ec225c 100644 --- a/source/blender/geometry/intern/mesh_split_edges.cc +++ b/source/blender/geometry/intern/mesh_split_edges.cc @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "BLI_array_utils.hh" -#include "BLI_devirtualize_parameters.hh" #include "BLI_index_mask.hh" #include "BLI_user_counter.hh" diff --git a/source/blender/geometry/intern/mesh_to_curve_convert.cc b/source/blender/geometry/intern/mesh_to_curve_convert.cc index 8047f1dc312..722f1db0fb4 100644 --- a/source/blender/geometry/intern/mesh_to_curve_convert.cc +++ b/source/blender/geometry/intern/mesh_to_curve_convert.cc @@ -2,7 +2,6 @@ #include "BLI_array.hh" #include "BLI_array_utils.hh" -#include "BLI_devirtualize_parameters.hh" #include "BLI_set.hh" #include "BLI_task.hh" diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 9729d31779c..760427fd7e6 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -9,7 +9,6 @@ #include "DNA_object_types.h" #include "DNA_pointcloud_types.h" -#include "BLI_devirtualize_parameters.hh" #include "BLI_noise.hh" #include "BLI_task.hh" diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc index 77952938827..a18627f2142 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc @@ -1,6 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#include "BLI_devirtualize_parameters.hh" #include "BLI_generic_array.hh" #include "BLI_length_parameterize.hh" From 380db3edb314ecc8fea888a194045396f8deb589 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 7 Jan 2023 14:43:40 +0100 Subject: [PATCH 0497/1522] Cleanup: add missing override --- source/blender/nodes/intern/geometry_nodes_lazy_function.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 9c4f04e8248..8f59dea62e1 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -2708,7 +2708,7 @@ class UsedSocketVisualizeOptions : public lf::Graph::ToDotOptions { void add_edge_attributes(const lf::OutputSocket & /*from*/, const lf::InputSocket &to, - dot::DirectedEdge &dot_edge) const + dot::DirectedEdge &dot_edge) const override { if (builder_.socket_usage_inputs_.contains_as(&to)) { // dot_edge.attributes.set("constraint", "false"); From b3146200a8c4265de7fba2e2d40ef84f99d979e2 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 7 Jan 2023 16:19:59 +0100 Subject: [PATCH 0498/1522] Functions: refactor multi-function builder API * New `build_mf` namespace for the multi-function builders. * The type name of the created multi-functions is now "private", i.e. the caller has to use `auto`. This has the benefit that the implementation can change more freely without affecting the caller. * `CustomMF` does not use `std::function` internally anymore. This reduces some overhead during code generation and at run-time. * `CustomMF` now supports single-mutable parameters. --- .../intern/geometry_component_curves.cc | 24 +- .../intern/geometry_component_mesh.cc | 4 +- .../blenkernel/intern/type_conversions.cc | 4 +- .../functions/FN_multi_function_builder.hh | 518 +++++++++--------- source/blender/functions/intern/field.cc | 4 +- .../blender/functions/tests/FN_field_test.cc | 28 +- .../tests/FN_multi_function_procedure_test.cc | 30 +- .../functions/tests/FN_multi_function_test.cc | 92 ---- .../geometry/intern/resample_curves.cc | 8 +- source/blender/nodes/NOD_math_functions.hh | 38 +- .../function/nodes/node_fn_boolean_math.cc | 37 +- .../function/nodes/node_fn_combine_color.cc | 12 +- .../nodes/function/nodes/node_fn_compare.cc | 196 +++---- .../function/nodes/node_fn_float_to_int.cc | 18 +- .../function/nodes/node_fn_random_value.cc | 77 ++- .../function/nodes/node_fn_replace_string.cc | 10 +- .../function/nodes/node_fn_rotate_euler.cc | 24 +- .../function/nodes/node_fn_slice_string.cc | 4 +- .../function/nodes/node_fn_string_length.cc | 4 +- .../function/nodes/node_fn_value_to_string.cc | 4 +- .../geometry/nodes/node_geo_extrude_mesh.cc | 4 +- .../geometry/nodes/node_geo_mesh_to_points.cc | 4 +- .../nodes/geometry/nodes/node_geo_switch.cc | 4 +- .../nodes/shader/nodes/node_shader_clamp.cc | 8 +- .../shader/nodes/node_shader_map_range.cc | 185 +++---- .../nodes/shader/nodes/node_shader_math.cc | 12 +- .../nodes/shader/nodes/node_shader_mix.cc | 24 +- .../shader/nodes/node_shader_sepcomb_rgb.cc | 4 +- .../shader/nodes/node_shader_sepcomb_xyz.cc | 4 +- .../shader/nodes/node_shader_vector_math.cc | 28 +- .../shader/nodes/node_shader_vector_rotate.cc | 40 +- 31 files changed, 637 insertions(+), 816 deletions(-) diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index debcb35699e..d1d0af2b725 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -440,12 +440,12 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() make_array_write_attribute, tag_component_positions_changed); - static const fn::CustomMF_SI_SO handle_type_clamp{ + static auto handle_type_clamp = fn::build_mf::SI1_SO( "Handle Type Validate", [](int8_t value) { return std::clamp(value, BEZIER_HANDLE_FREE, BEZIER_HANDLE_ALIGN); }, - fn::CustomMF_presets::AllSpanOrSingle()}; + fn::build_mf::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider handle_type_right("handle_type_right", ATTR_DOMAIN_POINT, CD_PROP_INT8, @@ -484,10 +484,10 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() make_array_write_attribute, tag_component_positions_changed); - static const fn::CustomMF_SI_SO nurbs_order_clamp{ + static const auto nurbs_order_clamp = fn::build_mf::SI1_SO( "NURBS Order Validate", [](int8_t value) { return std::max(value, 0); }, - fn::CustomMF_presets::AllSpanOrSingle()}; + fn::build_mf::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider nurbs_order("nurbs_order", ATTR_DOMAIN_CURVE, CD_PROP_INT8, @@ -501,12 +501,12 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() tag_component_topology_changed, AttributeValidator{&nurbs_order_clamp}); - static const fn::CustomMF_SI_SO normal_mode_clamp{ + static const auto normal_mode_clamp = fn::build_mf::SI1_SO( "Normal Mode Validate", [](int8_t value) { return std::clamp(value, NORMAL_MODE_MINIMUM_TWIST, NORMAL_MODE_Z_UP); }, - fn::CustomMF_presets::AllSpanOrSingle()}; + fn::build_mf::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider normal_mode("normal_mode", ATTR_DOMAIN_CURVE, CD_PROP_INT8, @@ -520,12 +520,12 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() tag_component_normals_changed, AttributeValidator{&normal_mode_clamp}); - static const fn::CustomMF_SI_SO knots_mode_clamp{ + static const auto knots_mode_clamp = fn::build_mf::SI1_SO( "Knots Mode Validate", [](int8_t value) { return std::clamp(value, NURBS_KNOT_MODE_NORMAL, NURBS_KNOT_MODE_ENDPOINT_BEZIER); }, - fn::CustomMF_presets::AllSpanOrSingle()}; + fn::build_mf::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider nurbs_knots_mode("knots_mode", ATTR_DOMAIN_CURVE, CD_PROP_INT8, @@ -539,12 +539,12 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() tag_component_topology_changed, AttributeValidator{&knots_mode_clamp}); - static const fn::CustomMF_SI_SO curve_type_clamp{ + static const auto curve_type_clamp = fn::build_mf::SI1_SO( "Curve Type Validate", [](int8_t value) { return std::clamp(value, CURVE_TYPE_CATMULL_ROM, CURVE_TYPES_NUM); }, - fn::CustomMF_presets::AllSpanOrSingle()}; + fn::build_mf::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider curve_type("curve_type", ATTR_DOMAIN_CURVE, CD_PROP_INT8, @@ -558,10 +558,10 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() tag_component_curve_types_changed, AttributeValidator{&curve_type_clamp}); - static const fn::CustomMF_SI_SO resolution_clamp{ + static const auto resolution_clamp = fn::build_mf::SI1_SO( "Resolution Validate", [](int value) { return std::max(value, 1); }, - fn::CustomMF_presets::AllSpanOrSingle()}; + fn::build_mf::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider resolution("resolution", ATTR_DOMAIN_CURVE, CD_PROP_INT32, diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 855d422251d..b18bdc62d82 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -1264,13 +1264,13 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() make_array_write_attribute, nullptr); - static const fn::CustomMF_SI_SO material_index_clamp{ + static const auto material_index_clamp = fn::build_mf::SI1_SO( "Material Index Validate", [](int value) { /* Use #short for the maximum since many areas still use that type for indices. */ return std::clamp(value, 0, std::numeric_limits::max()); }, - fn::CustomMF_presets::AllSpanOrSingle()}; + fn::build_mf::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider material_index("material_index", ATTR_DOMAIN_FACE, CD_PROP_INT32, diff --git a/source/blender/blenkernel/intern/type_conversions.cc b/source/blender/blenkernel/intern/type_conversions.cc index c3d8f84d5c3..5aca83d415d 100644 --- a/source/blender/blenkernel/intern/type_conversions.cc +++ b/source/blender/blenkernel/intern/type_conversions.cc @@ -20,12 +20,12 @@ static void add_implicit_conversion(DataTypeConversions &conversions) static const CPPType &to_type = CPPType::get(); static const std::string conversion_name = from_type.name() + " to " + to_type.name(); - static fn::CustomMF_SI_SO multi_function{ + static auto multi_function = fn::build_mf::SI1_SO( conversion_name.c_str(), /* Use lambda instead of passing #ConversionF directly, because otherwise the compiler won't * inline the function. */ [](const From &a) { return ConversionF(a); }, - fn::CustomMF_presets::AllSpanOrSingle()}; + fn::build_mf::exec_presets::AllSpanOrSingle()); static auto convert_single_to_initialized = [](const void *src, void *dst) { *(To *)dst = ConversionF(*(const From *)src); }; diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index b0876c13729..3a491a63e6c 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -8,17 +8,15 @@ * This file contains several utilities to create multi-functions with less redundant code. */ -#include - #include "FN_multi_function.hh" -namespace blender::fn { +namespace blender::fn::build_mf { /** * These presets determine what code is generated for a #CustomMF. Different presets make different * trade-offs between run-time performance and compile-time/binary size. */ -namespace CustomMF_presets { +namespace exec_presets { /** Method to execute a function in case devirtualization was not possible. */ enum class FallbackMode { @@ -63,7 +61,7 @@ struct AllSpanOrSingle { auto create_devirtualizers(TypeSequence /*param_tags*/, std::index_sequence /*indices*/, const IndexMask &mask, - const std::tuple &loaded_params) + const std::tuple &loaded_params) const { return std::make_tuple(IndexMaskDevirtualizer{mask}, [&]() { typedef ParamTags ParamTag; @@ -72,7 +70,9 @@ struct AllSpanOrSingle { const GVArrayImpl &varray_impl = *std::get(loaded_params); return GVArrayDevirtualizer{varray_impl}; } - else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { + else if constexpr (ELEM(ParamTag::category, + MFParamCategory::SingleOutput, + MFParamCategory::SingleMutable)) { T *ptr = std::get(loaded_params); return BasicDevirtualizer{ptr}; } @@ -93,7 +93,7 @@ template struct SomeSpanOrSingle { auto create_devirtualizers(TypeSequence /*param_tags*/, std::index_sequence /*indices*/, const IndexMask &mask, - const std::tuple &loaded_params) + const std::tuple &loaded_params) const { return std::make_tuple(IndexMaskDevirtualizer{mask}, [&]() { typedef ParamTags ParamTag; @@ -104,7 +104,9 @@ template struct SomeSpanOrSingle { const GVArrayImpl &varray_impl = *std::get(loaded_params); return GVArrayDevirtualizer{varray_impl}; } - else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { + else if constexpr (ELEM(ParamTag::category, + MFParamCategory::SingleOutput, + MFParamCategory::SingleMutable)) { T *ptr = std::get(loaded_params); return BasicDevirtualizer{ptr}; } @@ -112,7 +114,7 @@ template struct SomeSpanOrSingle { } }; -} // namespace CustomMF_presets +} // namespace exec_presets namespace detail { @@ -142,23 +144,23 @@ void execute_array(TypeSequence /*param_tags*/, * reference, because the pointer points to uninitialized memory. */ return args + i; } + else if constexpr (ParamTag::category == MFParamCategory::SingleMutable) { + /* For mutables, pass a mutable reference to the function. */ + return args[i]; + } }()...); } } -} // namespace detail - -namespace materialize_detail { - -enum class ArgMode { +enum class MaterializeArgMode { Unknown, Single, Span, Materialized, }; -template struct ArgInfo { - ArgMode mode = ArgMode::Unknown; +template struct MaterializeArgInfo { + MaterializeArgMode mode = MaterializeArgMode::Unknown; Span internal_span; }; @@ -182,9 +184,11 @@ void execute_materialized_impl(TypeSequence /*param_tags*/, return chunks[in_i]; } else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { - /* For outputs, a pointer is passed, because the memory is uninitialized. */ return chunks + out_i; } + else if constexpr (ParamTag::category == MFParamCategory::SingleMutable) { + return chunks[out_i]; + } }()...); } } @@ -217,7 +221,7 @@ void execute_materialized(TypeSequence /* param_tags */, std::tuple...> buffers; /* Information about every parameter. */ - std::tuple...> args_info; + std::tuple...> args_info; ( /* Setup information for all parameters. */ @@ -225,7 +229,7 @@ void execute_materialized(TypeSequence /* param_tags */, /* Use `typedef` instead of `using` to work around a compiler bug. */ typedef ParamTags ParamTag; typedef typename ParamTag::base_type T; - [[maybe_unused]] ArgInfo &arg_info = std::get(args_info); + [[maybe_unused]] MaterializeArgInfo &arg_info = std::get(args_info); if constexpr (ParamTag::category == MFParamCategory::SingleInput) { const GVArrayImpl &varray_impl = *std::get(loaded_params); const CommonVArrayInfo common_info = varray_impl.common_info(); @@ -236,7 +240,7 @@ void execute_materialized(TypeSequence /* param_tags */, const T &in_single = *static_cast(common_info.data); uninitialized_fill_n(in_chunk.data(), in_chunk.size(), in_single); std::get(buffers) = in_chunk; - arg_info.mode = ArgMode::Single; + arg_info.mode = MaterializeArgMode::Single; } else if (common_info.type == CommonVArrayInfo::Type::Span) { /* Remember the span so that it doesn't have to be retrieved in every iteration. */ @@ -264,9 +268,9 @@ void execute_materialized(TypeSequence /* param_tags */, [&] { using ParamTag = ParamTags; using T = typename ParamTag::base_type; - [[maybe_unused]] ArgInfo &arg_info = std::get(args_info); + [[maybe_unused]] MaterializeArgInfo &arg_info = std::get(args_info); if constexpr (ParamTag::category == MFParamCategory::SingleInput) { - if (arg_info.mode == ArgMode::Single) { + if (arg_info.mode == MaterializeArgMode::Single) { /* The single value has been filled into a buffer already reused for every chunk. */ return Span(std::get(buffers)); } @@ -276,7 +280,7 @@ void execute_materialized(TypeSequence /* param_tags */, /* In this case we can just use an existing span instead of "compressing" it into * a new temporary buffer. */ const IndexRange sliced_mask_range = sliced_mask.as_range(); - arg_info.mode = ArgMode::Span; + arg_info.mode = MaterializeArgMode::Span; return arg_info.internal_span.slice(sliced_mask_range); } } @@ -287,11 +291,13 @@ void execute_materialized(TypeSequence /* param_tags */, varray_impl.materialize_compressed_to_uninitialized(sliced_mask, in_chunk.data()); /* Remember that this parameter has been materialized, so that the values are * destructed properly when the chunk is done. */ - arg_info.mode = ArgMode::Materialized; + arg_info.mode = MaterializeArgMode::Materialized; return Span(in_chunk); } } - else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { + else if constexpr (ELEM(ParamTag::category, + MFParamCategory::SingleOutput, + MFParamCategory::SingleMutable)) { /* For outputs, just pass a pointer. This is important so that `__restrict` works. */ return std::get(loaded_params); } @@ -303,9 +309,9 @@ void execute_materialized(TypeSequence /* param_tags */, /* Use `typedef` instead of `using` to work around a compiler bug. */ typedef ParamTags ParamTag; typedef typename ParamTag::base_type T; - [[maybe_unused]] ArgInfo &arg_info = std::get(args_info); + [[maybe_unused]] MaterializeArgInfo &arg_info = std::get(args_info); if constexpr (ParamTag::category == MFParamCategory::SingleInput) { - if (arg_info.mode == ArgMode::Materialized) { + if (arg_info.mode == MaterializeArgMode::Materialized) { T *in_chunk = std::get(buffers_owner).ptr(); destruct_n(in_chunk, chunk_size); } @@ -320,9 +326,9 @@ void execute_materialized(TypeSequence /* param_tags */, /* Use `typedef` instead of `using` to work around a compiler bug. */ typedef ParamTags ParamTag; typedef typename ParamTag::base_type T; - [[maybe_unused]] ArgInfo &arg_info = std::get(args_info); + [[maybe_unused]] MaterializeArgInfo &arg_info = std::get(args_info); if constexpr (ParamTag::category == MFParamCategory::SingleInput) { - if (arg_info.mode == ArgMode::Single) { + if (arg_info.mode == MaterializeArgMode::Single) { MutableSpan in_chunk = std::get(buffers); destruct_n(in_chunk.data(), in_chunk.size()); } @@ -330,272 +336,254 @@ void execute_materialized(TypeSequence /* param_tags */, }(), ...); } -} // namespace materialize_detail -template class CustomMF : public MultiFunction { - private: - std::function fn_; - MFSignature signature_; +template +inline void execute_element_fn_as_multi_function(const ElementFn element_fn, + const ExecPreset exec_preset, + const IndexMask mask, + MFParams params, + TypeSequence /*param_tags*/, + std::index_sequence /*indices*/) +{ - using TagsSequence = TypeSequence; + /* Load parameters from #MFParams. */ + /* Contains `const GVArrayImpl *` for inputs and `T *` for outputs. */ + const auto loaded_params = std::make_tuple([&]() { + /* Use `typedef` instead of `using` to work around a compiler bug. */ + typedef ParamTags ParamTag; + typedef typename ParamTag::base_type T; - public: - template - CustomMF(const char *name, - ElementFn element_fn, - ExecPreset exec_preset = CustomMF_presets::Materialized()) - { - MFSignatureBuilder signature{name}; - add_signature_parameters(signature, std::make_index_sequence()); - signature_ = signature.build(); - this->set_signature(&signature_); + if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + return params.readonly_single_input(I).get_implementation(); + } + else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { + return static_cast(params.uninitialized_single_output(I).data()); + } + else if constexpr (ParamTag::category == MFParamCategory::SingleMutable) { + return static_cast(params.single_mutable(I).data()); + } + }()...); - fn_ = [element_fn, exec_preset](IndexMask mask, MFParams params) { - execute( - element_fn, exec_preset, mask, params, std::make_index_sequence()); - }; + /* Try execute devirtualized if enabled and the input types allow it. */ + bool executed_devirtualized = false; + if constexpr (ExecPreset::use_devirtualization) { + const auto devirtualizers = exec_preset.create_devirtualizers( + TypeSequence(), std::index_sequence(), mask, loaded_params); + executed_devirtualized = call_with_devirtualized_parameters( + devirtualizers, [&](auto &&...args) { + execute_array(TypeSequence(), + std::index_sequence(), + element_fn, + std::forward(args)...); + }); } - template - static void execute(ElementFn element_fn, - ExecPreset exec_preset, - IndexMask mask, - MFParams params, - std::index_sequence /*indices*/) - { - /* Contains `const GVArrayImpl *` for inputs and `T *` for outputs. */ - const auto loaded_params = std::make_tuple([&]() { - /* Use `typedef` instead of `using` to work around a compiler bug. */ - typedef typename TagsSequence::template at_index ParamTag; - typedef typename ParamTag::base_type T; - - if constexpr (ParamTag::category == MFParamCategory::SingleInput) { - return params.readonly_single_input(I).get_implementation(); - } - else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { - return static_cast(params.uninitialized_single_output(I).data()); - } - }()...); - - /* First try devirtualized execution, since this is the most efficient. */ - bool executed_devirtualized = false; - if constexpr (ExecPreset::use_devirtualization) { - const auto devirtualizers = exec_preset.create_devirtualizers( - TagsSequence(), std::index_sequence(), mask, loaded_params); - executed_devirtualized = call_with_devirtualized_parameters( - devirtualizers, [&](auto &&...args) { - detail::execute_array(TagsSequence(), - std::index_sequence(), - element_fn, - std::forward(args)...); - }); + /* If devirtualized execution was disabled or not possible, use a fallback method which is + * slower but always works. */ + if (!executed_devirtualized) { + /* The materialized method is most common because it avoids most virtual function overhead but + * still instantiates the function only once. */ + if constexpr (ExecPreset::fallback_mode == exec_presets::FallbackMode::Materialized) { + execute_materialized(TypeSequence(), + std::index_sequence(), + element_fn, + mask, + loaded_params); } - - /* If devirtualized execution was disabled or not possible, use a fallback method which is - * slower but always works. */ - if (!executed_devirtualized) { - if constexpr (ExecPreset::fallback_mode == CustomMF_presets::FallbackMode::Materialized) { - materialize_detail::execute_materialized( - TagsSequence(), std::index_sequence(), element_fn, mask, loaded_params); - } - else { - detail::execute_array( - TagsSequence(), std::index_sequence(), element_fn, mask, [&]() { - /* Use `typedef` instead of `using` to work around a compiler bug. */ - typedef typename TagsSequence::template at_index ParamTag; - typedef typename ParamTag::base_type T; - if constexpr (ParamTag::category == MFParamCategory::SingleInput) { - const GVArrayImpl &varray_impl = *std::get(loaded_params); - return GVArray(&varray_impl).typed(); - } - else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { - T *ptr = std::get(loaded_params); - return ptr; - } - }()...); - } + else { + /* This fallback is slower because it uses virtual method calls for every element. */ + execute_array( + TypeSequence(), std::index_sequence(), element_fn, mask, [&]() { + /* Use `typedef` instead of `using` to work around a compiler bug. */ + typedef ParamTags ParamTag; + typedef typename ParamTag::base_type T; + if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + const GVArrayImpl &varray_impl = *std::get(loaded_params); + return GVArray(&varray_impl).typed(); + } + else if constexpr (ELEM(ParamTag::category, + MFParamCategory::SingleOutput, + MFParamCategory::SingleMutable)) { + T *ptr = std::get(loaded_params); + return ptr; + } + }()...); } } - - template - static void add_signature_parameters(MFSignatureBuilder &signature, - std::index_sequence /* indices */) - { - ( - /* Loop over all parameter types and add an entry for each in the signature. */ - [&] { - /* Use `typedef` instead of `using` to work around a compiler bug. */ - typedef typename TagsSequence::template at_index ParamTag; - signature.add(ParamTag(), ""); - }(), - ...); - } - - void call(IndexMask mask, MFParams params, MFContext /*context*/) const override - { - fn_(mask, params); - } -}; +} /** - * Generates a multi-function with the following parameters: - * 1. single input (SI) of type In1 - * 2. single output (SO) of type Out1 - * - * This example creates a function that adds 10 to the incoming values: - * `CustomMF_SI_SO fn("add 10", [](int value) { return value + 10; });` + * `element_fn` is expected to return nothing and to have the following parameters: + * - For single-inputs: const value or reference. + * - For single-mutables: non-const reference. + * - For single-outputs: non-const pointer. */ -template -class CustomMF_SI_SO : public CustomMF, - MFParamTag> { - public: - template - CustomMF_SI_SO(const char *name, - ElementFn element_fn, - ExecPreset exec_preset = CustomMF_presets::Materialized()) - : CustomMF, - MFParamTag>( - name, - [element_fn](const In1 &in1, Out1 *out1) { new (out1) Out1(element_fn(in1)); }, - exec_preset) - { - } -}; +template +inline auto build_multi_function_call_from_element_fn(const ElementFn element_fn, + const ExecPreset exec_preset, + TypeSequence /*param_tags*/) +{ + return [element_fn, exec_preset](const IndexMask mask, MFParams params) { + execute_element_fn_as_multi_function(element_fn, + exec_preset, + mask, + params, + TypeSequence(), + std::make_index_sequence()); + }; +} /** - * Generates a multi-function with the following parameters: - * 1. single input (SI) of type In1 - * 2. single input (SI) of type In2 - * 3. single output (SO) of type Out1 + * A multi function that just invokes the provided function in its #call method. */ -template -class CustomMF_SI_SI_SO : public CustomMF, - MFParamTag, - MFParamTag> { - public: - template - CustomMF_SI_SI_SO(const char *name, - ElementFn element_fn, - ExecPreset exec_preset = CustomMF_presets::Materialized()) - : CustomMF, - MFParamTag, - MFParamTag>( - name, - [element_fn](const In1 &in1, const In2 &in2, Out1 *out1) { - new (out1) Out1(element_fn(in1, in2)); - }, - exec_preset) - { - } -}; - -/** - * Generates a multi-function with the following parameters: - * 1. single input (SI) of type In1 - * 2. single input (SI) of type In2 - * 3. single input (SI) of type In3 - * 4. single output (SO) of type Out1 - */ -template -class CustomMF_SI_SI_SI_SO : public CustomMF, - MFParamTag, - MFParamTag, - MFParamTag> { - public: - template - CustomMF_SI_SI_SI_SO(const char *name, - ElementFn element_fn, - ExecPreset exec_preset = CustomMF_presets::Materialized()) - : CustomMF, - MFParamTag, - MFParamTag, - MFParamTag>( - name, - [element_fn](const In1 &in1, const In2 &in2, const In3 &in3, Out1 *out1) { - new (out1) Out1(element_fn(in1, in2, in3)); - }, - exec_preset) - { - } -}; - -/** - * Generates a multi-function with the following parameters: - * 1. single input (SI) of type In1 - * 2. single input (SI) of type In2 - * 3. single input (SI) of type In3 - * 4. single input (SI) of type In4 - * 5. single output (SO) of type Out1 - */ -template -class CustomMF_SI_SI_SI_SI_SO : public CustomMF, - MFParamTag, - MFParamTag, - MFParamTag, - MFParamTag> { - public: - template - CustomMF_SI_SI_SI_SI_SO(const char *name, - ElementFn element_fn, - ExecPreset exec_preset = CustomMF_presets::Materialized()) - : CustomMF, - MFParamTag, - MFParamTag, - MFParamTag, - MFParamTag>( - name, - [element_fn]( - const In1 &in1, const In2 &in2, const In3 &in3, const In4 &in4, Out1 *out1) { - new (out1) Out1(element_fn(in1, in2, in3, in4)); - }, - exec_preset) - { - } -}; - -/** - * Generates a multi-function with the following parameters: - * 1. single mutable (SM) of type Mut1 - */ -template class CustomMF_SM : public MultiFunction { +template class CustomMF : public MultiFunction { private: - using FunctionT = std::function)>; - FunctionT function_; MFSignature signature_; + CallFn call_fn_; public: - CustomMF_SM(const char *name, FunctionT function) : function_(std::move(function)) + CustomMF(const char *name, CallFn call_fn, TypeSequence /*param_tags*/) + : call_fn_(std::move(call_fn)) { MFSignatureBuilder signature{name}; - signature.single_mutable("Mut1"); + /* Loop over all parameter types and add an entry for each in the signature. */ + ([&] { signature.add(ParamTags(), ""); }(), ...); signature_ = signature.build(); this->set_signature(&signature_); } - template - CustomMF_SM(const char *name, ElementFuncT element_fn) - : CustomMF_SM(name, CustomMF_SM::create_function(element_fn)) - { - } - - template static FunctionT create_function(ElementFuncT element_fn) - { - return [=](IndexMask mask, MutableSpan mut1) { - mask.to_best_mask_type([&](const auto &mask) { - for (const int64_t i : mask) { - element_fn(mut1[i]); - } - }); - }; - } - void call(IndexMask mask, MFParams params, MFContext /*context*/) const override { - MutableSpan mut1 = params.single_mutable(0); - function_(mask, mut1); + call_fn_(mask, params); } }; +template +inline auto build_multi_function_with_n_inputs_one_output(const char *name, + const ElementFn element_fn, + const ExecPreset exec_preset, + TypeSequence /*in_types*/) +{ + constexpr auto param_tags = TypeSequence..., + MFParamTag>(); + auto call_fn = build_multi_function_call_from_element_fn( + [element_fn](const In &...in, Out *out) { new (out) Out(element_fn(in...)); }, + exec_preset, + param_tags); + return CustomMF(name, call_fn, param_tags); +} + +} // namespace detail + +/** Build multi-function with 1 single-input and 1 single-output parameter. */ +template +inline auto SI1_SO(const char *name, + const ElementFn element_fn, + const ExecPreset exec_preset = exec_presets::Materialized()) +{ + return detail::build_multi_function_with_n_inputs_one_output( + name, element_fn, exec_preset, TypeSequence()); +} + +/** Build multi-function with 2 single-input and 1 single-output parameter. */ +template +inline auto SI2_SO(const char *name, + const ElementFn element_fn, + const ExecPreset exec_preset = exec_presets::Materialized()) +{ + return detail::build_multi_function_with_n_inputs_one_output( + name, element_fn, exec_preset, TypeSequence()); +} + +/** Build multi-function with 3 single-input and 1 single-output parameter. */ +template +inline auto SI3_SO(const char *name, + const ElementFn element_fn, + const ExecPreset exec_preset = exec_presets::Materialized()) +{ + return detail::build_multi_function_with_n_inputs_one_output( + name, element_fn, exec_preset, TypeSequence()); +} + +/** Build multi-function with 4 single-input and 1 single-output parameter. */ +template +inline auto SI4_SO(const char *name, + const ElementFn element_fn, + const ExecPreset exec_preset = exec_presets::Materialized()) +{ + return detail::build_multi_function_with_n_inputs_one_output( + name, element_fn, exec_preset, TypeSequence()); +} + +/** Build multi-function with 5 single-input and 1 single-output parameter. */ +template +inline auto SI5_SO(const char *name, + const ElementFn element_fn, + const ExecPreset exec_preset = exec_presets::Materialized()) +{ + return detail::build_multi_function_with_n_inputs_one_output( + name, element_fn, exec_preset, TypeSequence()); +} + +/** Build multi-function with 6 single-input and 1 single-output parameter. */ +template +inline auto SI6_SO(const char *name, + const ElementFn element_fn, + const ExecPreset exec_preset = exec_presets::Materialized()) +{ + return detail::build_multi_function_with_n_inputs_one_output( + name, element_fn, exec_preset, TypeSequence()); +} + +/** Build multi-function with 1 single-mutable parameter. */ +template +inline auto SM(const char *name, + const ElementFn element_fn, + const ExecPreset exec_preset = exec_presets::AllSpanOrSingle()) +{ + constexpr auto param_tags = TypeSequence>(); + auto call_fn = detail::build_multi_function_call_from_element_fn( + element_fn, exec_preset, param_tags); + return detail::CustomMF(name, call_fn, param_tags); +} + +} // namespace blender::fn::build_mf + +namespace blender::fn { + /** * A multi-function that outputs the same value every time. The value is not owned by an instance * of this function. If #make_value_copy is false, the caller is responsible for destructing and diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc index a9d26fa09f1..6a5a31eb17d 100644 --- a/source/blender/functions/intern/field.cc +++ b/source/blender/functions/intern/field.cc @@ -519,8 +519,8 @@ GField make_field_constant_if_possible(GField field) Field invert_boolean_field(const Field &field) { - static CustomMF_SI_SO not_fn{ - "Not", [](bool a) { return !a; }, CustomMF_presets::AllSpanOrSingle()}; + static auto not_fn = build_mf::SI1_SO( + "Not", [](bool a) { return !a; }, build_mf::exec_presets::AllSpanOrSingle()); auto not_op = std::make_shared(FieldOperation(not_fn, {field})); return Field(not_op); } diff --git a/source/blender/functions/tests/FN_field_test.cc b/source/blender/functions/tests/FN_field_test.cc index 8c5cc817174..3e5c201195f 100644 --- a/source/blender/functions/tests/FN_field_test.cc +++ b/source/blender/functions/tests/FN_field_test.cc @@ -104,11 +104,9 @@ TEST(field, InputAndFunction) { GField index_field{std::make_shared()}; - std::unique_ptr add_fn = std::make_unique>( - "add", [](int a, int b) { return a + b; }); - GField output_field{std::make_shared( - FieldOperation(std::move(add_fn), {index_field, index_field})), - 0}; + auto add_fn = build_mf::SI2_SO("add", [](int a, int b) { return a + b; }); + GField output_field{ + std::make_shared(FieldOperation(add_fn, {index_field, index_field})), 0}; Array result(10); @@ -129,16 +127,12 @@ TEST(field, TwoFunctions) { GField index_field{std::make_shared()}; - std::unique_ptr add_fn = std::make_unique>( - "add", [](int a, int b) { return a + b; }); - GField add_field{std::make_shared( - FieldOperation(std::move(add_fn), {index_field, index_field})), - 0}; + auto add_fn = build_mf::SI2_SO("add", [](int a, int b) { return a + b; }); + GField add_field{ + std::make_shared(FieldOperation(add_fn, {index_field, index_field})), 0}; - std::unique_ptr add_10_fn = std::make_unique>( - "add_10", [](int a) { return a + 10; }); - GField result_field{ - std::make_shared(FieldOperation(std::move(add_10_fn), {add_field})), 0}; + auto add_10_fn = build_mf::SI1_SO("add_10", [](int a) { return a + 10; }); + GField result_field{std::make_shared(FieldOperation(add_10_fn, {add_field})), 0}; Array result(10); @@ -230,11 +224,9 @@ TEST(field, TwoFunctionsTwoOutputs) Field result_field_1{fn, 0}; Field intermediate_field{fn, 1}; - std::unique_ptr add_10_fn = std::make_unique>( - "add_10", [](int a) { return a + 10; }); + auto add_10_fn = build_mf::SI1_SO("add_10", [](int a) { return a + 10; }); Field result_field_2{ - std::make_shared(FieldOperation(std::move(add_10_fn), {intermediate_field})), - 0}; + std::make_shared(FieldOperation(add_10_fn, {intermediate_field})), 0}; FieldContext field_context; FieldEvaluator field_evaluator{field_context, &mask}; diff --git a/source/blender/functions/tests/FN_multi_function_procedure_test.cc b/source/blender/functions/tests/FN_multi_function_procedure_test.cc index e7cedb40f83..aa8549dad44 100644 --- a/source/blender/functions/tests/FN_multi_function_procedure_test.cc +++ b/source/blender/functions/tests/FN_multi_function_procedure_test.cc @@ -19,7 +19,7 @@ TEST(multi_function_procedure, ConstantOutput) */ CustomMF_Constant constant_fn{5}; - CustomMF_SI_SI_SO add_fn{"Add", [](int a, int b) { return a + b; }}; + auto add_fn = build_mf::SI2_SO("Add", [](int a, int b) { return a + b; }); MFProcedure procedure; MFProcedureBuilder builder{procedure}; @@ -56,8 +56,8 @@ TEST(multi_function_procedure, SimpleTest) * } */ - CustomMF_SI_SI_SO add_fn{"add", [](int a, int b) { return a + b; }}; - CustomMF_SM add_10_fn{"add_10", [](int &a) { a += 10; }}; + auto add_fn = fn::build_mf::SI2_SO("add", [](int a, int b) { return a + b; }); + auto add_10_fn = fn::build_mf::SM("add_10", [](int &a) { a += 10; }); MFProcedure procedure; MFProcedureBuilder builder{procedure}; @@ -106,8 +106,8 @@ TEST(multi_function_procedure, BranchTest) * } */ - CustomMF_SM add_10_fn{"add_10", [](int &a) { a += 10; }}; - CustomMF_SM add_100_fn{"add_100", [](int &a) { a += 100; }}; + auto add_10_fn = build_mf::SM("add_10", [](int &a) { a += 10; }); + auto add_100_fn = build_mf::SM("add_100", [](int &a) { a += 100; }); MFProcedure procedure; MFProcedureBuilder builder{procedure}; @@ -153,10 +153,10 @@ TEST(multi_function_procedure, EvaluateOne) */ int tot_evaluations = 0; - CustomMF_SI_SO add_10_fn{"add_10", [&](int a) { - tot_evaluations++; - return a + 10; - }}; + const auto add_10_fn = fn::build_mf::SI1_SO("add_10", [&](int a) { + tot_evaluations++; + return a + 10; + }); MFProcedure procedure; MFProcedureBuilder builder{procedure}; @@ -205,11 +205,11 @@ TEST(multi_function_procedure, SimpleLoop) CustomMF_Constant const_1_fn{1}; CustomMF_Constant const_0_fn{0}; - CustomMF_SI_SI_SO greater_or_equal_fn{"greater or equal", - [](int a, int b) { return a >= b; }}; - CustomMF_SM double_fn{"double", [](int &a) { a *= 2; }}; - CustomMF_SM add_1000_fn{"add 1000", [](int &a) { a += 1000; }}; - CustomMF_SM add_1_fn{"add 1", [](int &a) { a += 1; }}; + auto greater_or_equal_fn = fn::build_mf::SI2_SO( + "greater or equal", [](int a, int b) { return a >= b; }); + auto double_fn = build_mf::SM("double", [](int &a) { a *= 2; }); + auto add_1000_fn = build_mf::SM("add 1000", [](int &a) { a += 1000; }); + auto add_1_fn = build_mf::SM("add 1", [](int &a) { a += 1; }); MFProcedure procedure; MFProcedureBuilder builder{procedure}; @@ -338,7 +338,7 @@ TEST(multi_function_procedure, BufferReuse) * } */ - CustomMF_SI_SO add_10_fn{"add 10", [](int a) { return a + 10; }}; + auto add_10_fn = build_mf::SI1_SO("add 10", [](int a) { return a + 10; }); MFProcedure procedure; MFProcedureBuilder builder{procedure}; diff --git a/source/blender/functions/tests/FN_multi_function_test.cc b/source/blender/functions/tests/FN_multi_function_test.cc index ca788b0a6ee..7a582805e98 100644 --- a/source/blender/functions/tests/FN_multi_function_test.cc +++ b/source/blender/functions/tests/FN_multi_function_test.cc @@ -149,98 +149,6 @@ TEST(multi_function, GenericAppendFunction) EXPECT_EQ(vectors_ref[3][0], 1); } -TEST(multi_function, CustomMF_SI_SO) -{ - CustomMF_SI_SO fn("strlen", - [](const std::string &str) { return str.size(); }); - - Array strings = {"hello", "world", "test", "another test"}; - Array sizes(strings.size(), 0); - - MFParamsBuilder params(fn, strings.size()); - params.add_readonly_single_input(strings.as_span()); - params.add_uninitialized_single_output(sizes.as_mutable_span()); - - MFContextBuilder context; - - fn.call(IndexRange(strings.size()), params, context); - - EXPECT_EQ(sizes[0], 5); - EXPECT_EQ(sizes[1], 5); - EXPECT_EQ(sizes[2], 4); - EXPECT_EQ(sizes[3], 12); -} - -TEST(multi_function, CustomMF_SI_SI_SO) -{ - CustomMF_SI_SI_SO fn("mul", [](int a, int b) { return a * b; }); - - Array values_a = {4, 6, 8, 9}; - int value_b = 10; - Array outputs(values_a.size(), -1); - - MFParamsBuilder params(fn, values_a.size()); - params.add_readonly_single_input(values_a.as_span()); - params.add_readonly_single_input(&value_b); - params.add_uninitialized_single_output(outputs.as_mutable_span()); - - MFContextBuilder context; - - fn.call({0, 1, 3}, params, context); - - EXPECT_EQ(outputs[0], 40); - EXPECT_EQ(outputs[1], 60); - EXPECT_EQ(outputs[2], -1); - EXPECT_EQ(outputs[3], 90); -} - -TEST(multi_function, CustomMF_SI_SI_SI_SO) -{ - CustomMF_SI_SI_SI_SO fn{ - "custom", - [](int a, const std::string &b, bool c) { return uint(uint(a) + b.size() + uint(c)); }}; - - Array values_a = {5, 7, 3, 8}; - Array values_b = {"hello", "world", "another", "test"}; - Array values_c = {true, false, false, true}; - Array outputs(values_a.size(), 0); - - MFParamsBuilder params(fn, values_a.size()); - params.add_readonly_single_input(values_a.as_span()); - params.add_readonly_single_input(values_b.as_span()); - params.add_readonly_single_input(values_c.as_span()); - params.add_uninitialized_single_output(outputs.as_mutable_span()); - - MFContextBuilder context; - - fn.call({1, 2, 3}, params, context); - - EXPECT_EQ(outputs[0], 0); - EXPECT_EQ(outputs[1], 12); - EXPECT_EQ(outputs[2], 10); - EXPECT_EQ(outputs[3], 13); -} - -TEST(multi_function, CustomMF_SM) -{ - CustomMF_SM fn("AddSuffix", [](std::string &value) { value += " test"; }); - - Array values = {"a", "b", "c", "d", "e"}; - - MFParamsBuilder params(fn, values.size()); - params.add_single_mutable(values.as_mutable_span()); - - MFContextBuilder context; - - fn.call({1, 2, 3}, params, context); - - EXPECT_EQ(values[0], "a"); - EXPECT_EQ(values[1], "b test"); - EXPECT_EQ(values[2], "c test"); - EXPECT_EQ(values[3], "d test"); - EXPECT_EQ(values[4], "e"); -} - TEST(multi_function, CustomMF_Constant) { CustomMF_Constant fn{42}; diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc index cccf659ac5e..358c7ced488 100644 --- a/source/blender/geometry/intern/resample_curves.cc +++ b/source/blender/geometry/intern/resample_curves.cc @@ -17,10 +17,10 @@ namespace blender::geometry { static fn::Field get_count_input_max_one(const fn::Field &count_field) { - static fn::CustomMF_SI_SO max_one_fn( + static auto max_one_fn = fn::build_mf::SI1_SO( "Clamp Above One", [](int value) { return std::max(1, value); }, - fn::CustomMF_presets::AllSpanOrSingle()); + fn::build_mf::exec_presets::AllSpanOrSingle()); auto clamp_op = std::make_shared( fn::FieldOperation(max_one_fn, {count_field})); @@ -29,7 +29,7 @@ static fn::Field get_count_input_max_one(const fn::Field &count_field) static fn::Field get_count_input_from_length(const fn::Field &length_field) { - static fn::CustomMF_SI_SI_SO get_count_fn( + static auto get_count_fn = fn::build_mf::SI2_SO( "Length Input to Count", [](const float curve_length, const float sample_length) { /* Find the number of sampled segments by dividing the total length by @@ -37,7 +37,7 @@ static fn::Field get_count_input_from_length(const fn::Field &length const int count = int(curve_length / sample_length) + 1; return std::max(1, count); }, - fn::CustomMF_presets::AllSpanOrSingle()); + fn::build_mf::exec_presets::AllSpanOrSingle()); auto get_count_op = std::make_shared(fn::FieldOperation( get_count_fn, diff --git a/source/blender/nodes/NOD_math_functions.hh b/source/blender/nodes/NOD_math_functions.hh index 51057f600f4..b7637fb2c66 100644 --- a/source/blender/nodes/NOD_math_functions.hh +++ b/source/blender/nodes/NOD_math_functions.hh @@ -51,8 +51,8 @@ inline bool try_dispatch_float_math_fl_to_fl(const int operation, Callback &&cal return false; } - static auto exec_preset_fast = fn::CustomMF_presets::AllSpanOrSingle(); - static auto exec_preset_slow = fn::CustomMF_presets::Materialized(); + static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); + static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized(); /* This is just an utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -118,8 +118,8 @@ inline bool try_dispatch_float_math_fl_fl_to_fl(const int operation, Callback && return false; } - static auto exec_preset_fast = fn::CustomMF_presets::AllSpanOrSingle(); - static auto exec_preset_slow = fn::CustomMF_presets::Materialized(); + static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); + static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized(); /* This is just an utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -180,21 +180,21 @@ inline bool try_dispatch_float_math_fl_fl_fl_to_fl(const int operation, Callback switch (operation) { case NODE_MATH_MULTIPLY_ADD: - return dispatch(fn::CustomMF_presets::AllSpanOrSingle(), + return dispatch(fn::build_mf::exec_presets::AllSpanOrSingle(), [](float a, float b, float c) { return a * b + c; }); case NODE_MATH_COMPARE: - return dispatch(fn::CustomMF_presets::SomeSpanOrSingle<0, 1>(), + return dispatch(fn::build_mf::exec_presets::SomeSpanOrSingle<0, 1>(), [](float a, float b, float c) -> float { return ((a == b) || (fabsf(a - b) <= fmaxf(c, FLT_EPSILON))) ? 1.0f : 0.0f; }); case NODE_MATH_SMOOTH_MIN: - return dispatch(fn::CustomMF_presets::SomeSpanOrSingle<0, 1>(), + return dispatch(fn::build_mf::exec_presets::SomeSpanOrSingle<0, 1>(), [](float a, float b, float c) { return smoothminf(a, b, c); }); case NODE_MATH_SMOOTH_MAX: - return dispatch(fn::CustomMF_presets::SomeSpanOrSingle<0, 1>(), + return dispatch(fn::build_mf::exec_presets::SomeSpanOrSingle<0, 1>(), [](float a, float b, float c) { return -smoothminf(-a, -b, c); }); case NODE_MATH_WRAP: - return dispatch(fn::CustomMF_presets::SomeSpanOrSingle<0>(), + return dispatch(fn::build_mf::exec_presets::SomeSpanOrSingle<0>(), [](float a, float b, float c) { return wrapf(a, b, c); }); } return false; @@ -214,8 +214,8 @@ inline bool try_dispatch_float_math_fl3_fl3_to_fl3(const NodeVectorMathOperation return false; } - static auto exec_preset_fast = fn::CustomMF_presets::AllSpanOrSingle(); - static auto exec_preset_slow = fn::CustomMF_presets::Materialized(); + static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); + static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -269,7 +269,7 @@ inline bool try_dispatch_float_math_fl3_fl3_to_fl(const NodeVectorMathOperation return false; } - static auto exec_preset_fast = fn::CustomMF_presets::AllSpanOrSingle(); + static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -302,8 +302,8 @@ inline bool try_dispatch_float_math_fl3_fl3_fl3_to_fl3(const NodeVectorMathOpera return false; } - static auto exec_preset_fast = fn::CustomMF_presets::AllSpanOrSingle(); - static auto exec_preset_slow = fn::CustomMF_presets::Materialized(); + static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); + static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -341,7 +341,7 @@ inline bool try_dispatch_float_math_fl3_fl3_fl_to_fl3(const NodeVectorMathOperat return false; } - static auto exec_preset_slow = fn::CustomMF_presets::Materialized(); + static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -373,7 +373,7 @@ inline bool try_dispatch_float_math_fl3_to_fl(const NodeVectorMathOperation oper return false; } - static auto exec_preset_fast = fn::CustomMF_presets::AllSpanOrSingle(); + static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -402,7 +402,7 @@ inline bool try_dispatch_float_math_fl3_fl_to_fl3(const NodeVectorMathOperation return false; } - static auto exec_preset_fast = fn::CustomMF_presets::AllSpanOrSingle(); + static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -433,8 +433,8 @@ inline bool try_dispatch_float_math_fl3_to_fl3(const NodeVectorMathOperation ope return false; } - static auto exec_preset_fast = fn::CustomMF_presets::AllSpanOrSingle(); - static auto exec_preset_slow = fn::CustomMF_presets::Materialized(); + static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); + static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { diff --git a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc index 849e03ca77f..02e15fe7853 100644 --- a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc +++ b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc @@ -67,24 +67,25 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) static const fn::MultiFunction *get_multi_function(const bNode &bnode) { - static auto exec_preset = fn::CustomMF_presets::AllSpanOrSingle(); - static fn::CustomMF_SI_SI_SO and_fn{ - "And", [](bool a, bool b) { return a && b; }, exec_preset}; - static fn::CustomMF_SI_SI_SO or_fn{ - "Or", [](bool a, bool b) { return a || b; }, exec_preset}; - static fn::CustomMF_SI_SO not_fn{"Not", [](bool a) { return !a; }, exec_preset}; - static fn::CustomMF_SI_SI_SO nand_fn{ - "Not And", [](bool a, bool b) { return !(a && b); }, exec_preset}; - static fn::CustomMF_SI_SI_SO nor_fn{ - "Nor", [](bool a, bool b) { return !(a || b); }, exec_preset}; - static fn::CustomMF_SI_SI_SO xnor_fn{ - "Equal", [](bool a, bool b) { return a == b; }, exec_preset}; - static fn::CustomMF_SI_SI_SO xor_fn{ - "Not Equal", [](bool a, bool b) { return a != b; }, exec_preset}; - static fn::CustomMF_SI_SI_SO imply_fn{ - "Imply", [](bool a, bool b) { return !a || b; }, exec_preset}; - static fn::CustomMF_SI_SI_SO nimply_fn{ - "Subtract", [](bool a, bool b) { return a && !b; }, exec_preset}; + static auto exec_preset = fn::build_mf::exec_presets::AllSpanOrSingle(); + static auto and_fn = fn::build_mf::SI2_SO( + "And", [](bool a, bool b) { return a && b; }, exec_preset); + static auto or_fn = fn::build_mf::SI2_SO( + "Or", [](bool a, bool b) { return a || b; }, exec_preset); + static auto not_fn = fn::build_mf::SI1_SO( + "Not", [](bool a) { return !a; }, exec_preset); + static auto nand_fn = fn::build_mf::SI2_SO( + "Not And", [](bool a, bool b) { return !(a && b); }, exec_preset); + static auto nor_fn = fn::build_mf::SI2_SO( + "Nor", [](bool a, bool b) { return !(a || b); }, exec_preset); + static auto xnor_fn = fn::build_mf::SI2_SO( + "Equal", [](bool a, bool b) { return a == b; }, exec_preset); + static auto xor_fn = fn::build_mf::SI2_SO( + "Not Equal", [](bool a, bool b) { return a != b; }, exec_preset); + static auto imply_fn = fn::build_mf::SI2_SO( + "Imply", [](bool a, bool b) { return !a || b; }, exec_preset); + static auto nimply_fn = fn::build_mf::SI2_SO( + "Subtract", [](bool a, bool b) { return a && !b; }, exec_preset); switch (bnode.custom1) { case NODE_BOOLEAN_MATH_AND: diff --git a/source/blender/nodes/function/nodes/node_fn_combine_color.cc b/source/blender/nodes/function/nodes/node_fn_combine_color.cc index 318c8997f9a..9b395767ec3 100644 --- a/source/blender/nodes/function/nodes/node_fn_combine_color.cc +++ b/source/blender/nodes/function/nodes/node_fn_combine_color.cc @@ -53,22 +53,22 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode) { const NodeCombSepColor &storage = node_storage(bnode); - static fn::CustomMF_SI_SI_SI_SI_SO rgba_fn{ - "RGB", [](float r, float g, float b, float a) { return ColorGeometry4f(r, g, b, a); }}; - static fn::CustomMF_SI_SI_SI_SI_SO hsva_fn{ + static auto rgba_fn = fn::build_mf::SI4_SO( + "RGB", [](float r, float g, float b, float a) { return ColorGeometry4f(r, g, b, a); }); + static auto hsva_fn = fn::build_mf::SI4_SO( "HSV", [](float h, float s, float v, float a) { ColorGeometry4f r_color; hsv_to_rgb(h, s, v, &r_color.r, &r_color.g, &r_color.b); r_color.a = a; return r_color; - }}; - static fn::CustomMF_SI_SI_SI_SI_SO hsla_fn{ + }); + static auto hsla_fn = fn::build_mf::SI4_SO( "HSL", [](float h, float s, float l, float a) { ColorGeometry4f color; hsl_to_rgb(h, s, l, &color.r, &color.g, &color.b); color.a = a; return color; - }}; + }); switch (storage.mode) { case NODE_COMBSEP_COLOR_RGB: diff --git a/source/blender/nodes/function/nodes/node_fn_compare.cc b/source/blender/nodes/function/nodes/node_fn_compare.cc index d73cb8cd558..e272880fe4b 100644 --- a/source/blender/nodes/function/nodes/node_fn_compare.cc +++ b/source/blender/nodes/function/nodes/node_fn_compare.cc @@ -168,77 +168,77 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) { const NodeFunctionCompare *data = (NodeFunctionCompare *)node.storage; - static auto exec_preset_all = fn::CustomMF_presets::AllSpanOrSingle(); - static auto exec_preset_first_two = fn::CustomMF_presets::SomeSpanOrSingle<0, 1>(); + static auto exec_preset_all = fn::build_mf::exec_presets::AllSpanOrSingle(); + static auto exec_preset_first_two = fn::build_mf::exec_presets::SomeSpanOrSingle<0, 1>(); switch (data->data_type) { case SOCK_FLOAT: switch (data->operation) { case NODE_COMPARE_LESS_THAN: { - static fn::CustomMF_SI_SI_SO fn{ - "Less Than", [](float a, float b) { return a < b; }, exec_preset_all}; + static auto fn = fn::build_mf::SI2_SO( + "Less Than", [](float a, float b) { return a < b; }, exec_preset_all); return &fn; } case NODE_COMPARE_LESS_EQUAL: { - static fn::CustomMF_SI_SI_SO fn{ - "Less Equal", [](float a, float b) { return a <= b; }, exec_preset_all}; + static auto fn = fn::build_mf::SI2_SO( + "Less Equal", [](float a, float b) { return a <= b; }, exec_preset_all); return &fn; } case NODE_COMPARE_GREATER_THAN: { - static fn::CustomMF_SI_SI_SO fn{ - "Greater Than", [](float a, float b) { return a > b; }, exec_preset_all}; + static auto fn = fn::build_mf::SI2_SO( + "Greater Than", [](float a, float b) { return a > b; }, exec_preset_all); return &fn; } case NODE_COMPARE_GREATER_EQUAL: { - static fn::CustomMF_SI_SI_SO fn{ - "Greater Equal", [](float a, float b) { return a >= b; }, exec_preset_all}; + static auto fn = fn::build_mf::SI2_SO( + "Greater Equal", [](float a, float b) { return a >= b; }, exec_preset_all); return &fn; } case NODE_COMPARE_EQUAL: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Equal", [](float a, float b, float epsilon) { return std::abs(a - b) <= epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_NOT_EQUAL: - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Not Equal", [](float a, float b, float epsilon) { return std::abs(a - b) > epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } break; case SOCK_INT: switch (data->operation) { case NODE_COMPARE_LESS_THAN: { - static fn::CustomMF_SI_SI_SO fn{ - "Less Than", [](int a, int b) { return a < b; }, exec_preset_all}; + static auto fn = fn::build_mf::SI2_SO( + "Less Than", [](int a, int b) { return a < b; }, exec_preset_all); return &fn; } case NODE_COMPARE_LESS_EQUAL: { - static fn::CustomMF_SI_SI_SO fn{ - "Less Equal", [](int a, int b) { return a <= b; }, exec_preset_all}; + static auto fn = fn::build_mf::SI2_SO( + "Less Equal", [](int a, int b) { return a <= b; }, exec_preset_all); return &fn; } case NODE_COMPARE_GREATER_THAN: { - static fn::CustomMF_SI_SI_SO fn{ - "Greater Than", [](int a, int b) { return a > b; }, exec_preset_all}; + static auto fn = fn::build_mf::SI2_SO( + "Greater Than", [](int a, int b) { return a > b; }, exec_preset_all); return &fn; } case NODE_COMPARE_GREATER_EQUAL: { - static fn::CustomMF_SI_SI_SO fn{ - "Greater Equal", [](int a, int b) { return a >= b; }, exec_preset_all}; + static auto fn = fn::build_mf::SI2_SO( + "Greater Equal", [](int a, int b) { return a >= b; }, exec_preset_all); return &fn; } case NODE_COMPARE_EQUAL: { - static fn::CustomMF_SI_SI_SO fn{ - "Equal", [](int a, int b) { return a == b; }, exec_preset_all}; + static auto fn = fn::build_mf::SI2_SO( + "Equal", [](int a, int b) { return a == b; }, exec_preset_all); return &fn; } case NODE_COMPARE_NOT_EQUAL: { - static fn::CustomMF_SI_SI_SO fn{ - "Not Equal", [](int a, int b) { return a != b; }, exec_preset_all}; + static auto fn = fn::build_mf::SI2_SO( + "Not Equal", [](int a, int b) { return a != b; }, exec_preset_all); return &fn; } } @@ -248,38 +248,38 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_COMPARE_LESS_THAN: switch (data->mode) { case NODE_COMPARE_MODE_AVERAGE: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Less Than - Average", [](float3 a, float3 b) { return component_average(a) < component_average(b); }, - exec_preset_all}; + exec_preset_all); return &fn; } case NODE_COMPARE_MODE_DOT_PRODUCT: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Less Than - Dot Product", [](float3 a, float3 b, float comp) { return math::dot(a, b) < comp; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_DIRECTION: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Less Than - Direction", [](float3 a, float3 b, float angle) { return angle_v3v3(a, b) < angle; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_ELEMENT: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Less Than - Element-wise", [](float3 a, float3 b) { return a.x < b.x && a.y < b.y && a.z < b.z; }, - exec_preset_all}; + exec_preset_all); return &fn; } case NODE_COMPARE_MODE_LENGTH: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Less Than - Length", [](float3 a, float3 b) { return math::length(a) < math::length(b); }, - exec_preset_all}; + exec_preset_all); return &fn; } } @@ -287,38 +287,38 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_COMPARE_LESS_EQUAL: switch (data->mode) { case NODE_COMPARE_MODE_AVERAGE: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Less Equal - Average", [](float3 a, float3 b) { return component_average(a) <= component_average(b); }, - exec_preset_all}; + exec_preset_all); return &fn; } case NODE_COMPARE_MODE_DOT_PRODUCT: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Less Equal - Dot Product", [](float3 a, float3 b, float comp) { return math::dot(a, b) <= comp; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_DIRECTION: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Less Equal - Direction", [](float3 a, float3 b, float angle) { return angle_v3v3(a, b) <= angle; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_ELEMENT: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Less Equal - Element-wise", [](float3 a, float3 b) { return a.x <= b.x && a.y <= b.y && a.z <= b.z; }, - exec_preset_all}; + exec_preset_all); return &fn; } case NODE_COMPARE_MODE_LENGTH: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Less Equal - Length", [](float3 a, float3 b) { return math::length(a) <= math::length(b); }, - exec_preset_all}; + exec_preset_all); return &fn; } } @@ -326,38 +326,38 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_COMPARE_GREATER_THAN: switch (data->mode) { case NODE_COMPARE_MODE_AVERAGE: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Greater Than - Average", [](float3 a, float3 b) { return component_average(a) > component_average(b); }, - exec_preset_all}; + exec_preset_all); return &fn; } case NODE_COMPARE_MODE_DOT_PRODUCT: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Greater Than - Dot Product", [](float3 a, float3 b, float comp) { return math::dot(a, b) > comp; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_DIRECTION: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Greater Than - Direction", [](float3 a, float3 b, float angle) { return angle_v3v3(a, b) > angle; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_ELEMENT: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Greater Than - Element-wise", [](float3 a, float3 b) { return a.x > b.x && a.y > b.y && a.z > b.z; }, - exec_preset_all}; + exec_preset_all); return &fn; } case NODE_COMPARE_MODE_LENGTH: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Greater Than - Length", [](float3 a, float3 b) { return math::length(a) > math::length(b); }, - exec_preset_all}; + exec_preset_all); return &fn; } } @@ -365,38 +365,38 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_COMPARE_GREATER_EQUAL: switch (data->mode) { case NODE_COMPARE_MODE_AVERAGE: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Greater Equal - Average", [](float3 a, float3 b) { return component_average(a) >= component_average(b); }, - exec_preset_all}; + exec_preset_all); return &fn; } case NODE_COMPARE_MODE_DOT_PRODUCT: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Greater Equal - Dot Product", [](float3 a, float3 b, float comp) { return math::dot(a, b) >= comp; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_DIRECTION: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Greater Equal - Direction", [](float3 a, float3 b, float angle) { return angle_v3v3(a, b) >= angle; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_ELEMENT: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Greater Equal - Element-wise", [](float3 a, float3 b) { return a.x >= b.x && a.y >= b.y && a.z >= b.z; }, - exec_preset_all}; + exec_preset_all); return &fn; } case NODE_COMPARE_MODE_LENGTH: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Greater Equal - Length", [](float3 a, float3 b) { return math::length(a) >= math::length(b); }, - exec_preset_all}; + exec_preset_all); return &fn; } } @@ -404,49 +404,49 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_COMPARE_EQUAL: switch (data->mode) { case NODE_COMPARE_MODE_AVERAGE: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Equal - Average", [](float3 a, float3 b, float epsilon) { return abs(component_average(a) - component_average(b)) <= epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_DOT_PRODUCT: { - static fn::CustomMF_SI_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI4_SO( "Equal - Dot Product", [](float3 a, float3 b, float comp, float epsilon) { return abs(math::dot(a, b) - comp) <= epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_DIRECTION: { - static fn::CustomMF_SI_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI4_SO( "Equal - Direction", [](float3 a, float3 b, float angle, float epsilon) { return abs(angle_v3v3(a, b) - angle) <= epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_ELEMENT: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Equal - Element-wise", [](float3 a, float3 b, float epsilon) { return abs(a.x - b.x) <= epsilon && abs(a.y - b.y) <= epsilon && abs(a.z - b.z) <= epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_LENGTH: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Equal - Length", [](float3 a, float3 b, float epsilon) { return abs(math::length(a) - math::length(b)) <= epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } } @@ -454,49 +454,49 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_COMPARE_NOT_EQUAL: switch (data->mode) { case NODE_COMPARE_MODE_AVERAGE: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Not Equal - Average", [](float3 a, float3 b, float epsilon) { return abs(component_average(a) - component_average(b)) > epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_DOT_PRODUCT: { - static fn::CustomMF_SI_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI4_SO( "Not Equal - Dot Product", [](float3 a, float3 b, float comp, float epsilon) { return abs(math::dot(a, b) - comp) >= epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_DIRECTION: { - static fn::CustomMF_SI_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI4_SO( "Not Equal - Direction", [](float3 a, float3 b, float angle, float epsilon) { return abs(angle_v3v3(a, b) - angle) > epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_ELEMENT: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Not Equal - Element-wise", [](float3 a, float3 b, float epsilon) { return abs(a.x - b.x) > epsilon || abs(a.y - b.y) > epsilon || abs(a.z - b.z) > epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_LENGTH: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Not Equal - Length", [](float3 a, float3 b, float epsilon) { return abs(math::length(a) - math::length(b)) > epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } } @@ -506,41 +506,41 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case SOCK_RGBA: switch (data->operation) { case NODE_COMPARE_EQUAL: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Equal", [](ColorGeometry4f a, ColorGeometry4f b, float epsilon) { return abs(a.r - b.r) <= epsilon && abs(a.g - b.g) <= epsilon && abs(a.b - b.b) <= epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_NOT_EQUAL: { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Not Equal", [](ColorGeometry4f a, ColorGeometry4f b, float epsilon) { return abs(a.r - b.r) > epsilon || abs(a.g - b.g) > epsilon || abs(a.b - b.b) > epsilon; }, - exec_preset_first_two}; + exec_preset_first_two); return &fn; } case NODE_COMPARE_COLOR_BRIGHTER: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Brighter", [](ColorGeometry4f a, ColorGeometry4f b) { return rgb_to_grayscale(a) > rgb_to_grayscale(b); }, - exec_preset_all}; + exec_preset_all); return &fn; } case NODE_COMPARE_COLOR_DARKER: { - static fn::CustomMF_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI2_SO( "Darker", [](ColorGeometry4f a, ColorGeometry4f b) { return rgb_to_grayscale(a) < rgb_to_grayscale(b); }, - exec_preset_all}; + exec_preset_all); return &fn; } } @@ -548,13 +548,13 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case SOCK_STRING: switch (data->operation) { case NODE_COMPARE_EQUAL: { - static fn::CustomMF_SI_SI_SO fn{ - "Equal", [](std::string a, std::string b) { return a == b; }}; + static auto fn = fn::build_mf::SI2_SO( + "Equal", [](std::string a, std::string b) { return a == b; }); return &fn; } case NODE_COMPARE_NOT_EQUAL: { - static fn::CustomMF_SI_SI_SO fn{ - "Not Equal", [](std::string a, std::string b) { return a != b; }}; + static auto fn = fn::build_mf::SI2_SO( + "Not Equal", [](std::string a, std::string b) { return a != b; }); return &fn; } } diff --git a/source/blender/nodes/function/nodes/node_fn_float_to_int.cc b/source/blender/nodes/function/nodes/node_fn_float_to_int.cc index 95922de4e20..de68b00874f 100644 --- a/source/blender/nodes/function/nodes/node_fn_float_to_int.cc +++ b/source/blender/nodes/function/nodes/node_fn_float_to_int.cc @@ -38,15 +38,15 @@ static void node_label(const bNodeTree * /*tree*/, const bNode *node, char *labe static const fn::MultiFunction *get_multi_function(const bNode &bnode) { - static auto exec_preset = fn::CustomMF_presets::AllSpanOrSingle(); - static fn::CustomMF_SI_SO round_fn{ - "Round", [](float a) { return int(round(a)); }, exec_preset}; - static fn::CustomMF_SI_SO floor_fn{ - "Floor", [](float a) { return int(floor(a)); }, exec_preset}; - static fn::CustomMF_SI_SO ceil_fn{ - "Ceiling", [](float a) { return int(ceil(a)); }, exec_preset}; - static fn::CustomMF_SI_SO trunc_fn{ - "Truncate", [](float a) { return int(trunc(a)); }, exec_preset}; + static auto exec_preset = fn::build_mf::exec_presets::AllSpanOrSingle(); + static auto round_fn = fn::build_mf::SI1_SO( + "Round", [](float a) { return int(round(a)); }, exec_preset); + static auto floor_fn = fn::build_mf::SI1_SO( + "Floor", [](float a) { return int(floor(a)); }, exec_preset); + static auto ceil_fn = fn::build_mf::SI1_SO( + "Ceiling", [](float a) { return int(ceil(a)); }, exec_preset); + static auto trunc_fn = fn::build_mf::SI1_SO( + "Truncate", [](float a) { return int(trunc(a)); }, exec_preset); switch (static_cast(bnode.custom1)) { case FN_NODE_FLOAT_TO_INT_ROUND: diff --git a/source/blender/nodes/function/nodes/node_fn_random_value.cc b/source/blender/nodes/function/nodes/node_fn_random_value.cc index b021ff07f04..1dfd8074349 100644 --- a/source/blender/nodes/function/nodes/node_fn_random_value.cc +++ b/source/blender/nodes/function/nodes/node_fn_random_value.cc @@ -141,64 +141,49 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder) switch (data_type) { case CD_PROP_FLOAT3: { - static fn::CustomMF, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag> - fn{"Random Vector", - [](float3 min_value, float3 max_value, int id, int seed, float3 *r_value) { - const float x = noise::hash_to_float(seed, id, 0); - const float y = noise::hash_to_float(seed, id, 1); - const float z = noise::hash_to_float(seed, id, 2); - *r_value = float3(x, y, z) * (max_value - min_value) + min_value; - }, - fn::CustomMF_presets::SomeSpanOrSingle<2>()}; + static auto fn = fn::build_mf::SI4_SO( + "Random Vector", + [](float3 min_value, float3 max_value, int id, int seed) -> float3 { + const float x = noise::hash_to_float(seed, id, 0); + const float y = noise::hash_to_float(seed, id, 1); + const float z = noise::hash_to_float(seed, id, 2); + return float3(x, y, z) * (max_value - min_value) + min_value; + }, + fn::build_mf::exec_presets::SomeSpanOrSingle<2>()); builder.set_matching_fn(fn); break; } case CD_PROP_FLOAT: { - static fn::CustomMF, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag> - fn{"Random Float", - [](float min_value, float max_value, int id, int seed, float *r_value) { - const float value = noise::hash_to_float(seed, id); - *r_value = value * (max_value - min_value) + min_value; - }, - fn::CustomMF_presets::SomeSpanOrSingle<2>()}; + static auto fn = fn::build_mf::SI4_SO( + "Random Float", + [](float min_value, float max_value, int id, int seed) -> float { + const float value = noise::hash_to_float(seed, id); + return value * (max_value - min_value) + min_value; + }, + fn::build_mf::exec_presets::SomeSpanOrSingle<2>()); builder.set_matching_fn(fn); break; } case CD_PROP_INT32: { - static fn::CustomMF, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag> - fn{"Random Int", - [](int min_value, int max_value, int id, int seed, int *r_value) { - const float value = noise::hash_to_float(id, seed); - /* Add one to the maximum and use floor to produce an even - * distribution for the first and last values (See T93591). */ - *r_value = floor(value * (max_value + 1 - min_value) + min_value); - }, - fn::CustomMF_presets::SomeSpanOrSingle<2>()}; + static auto fn = fn::build_mf::SI4_SO( + "Random Int", + [](int min_value, int max_value, int id, int seed) -> int { + const float value = noise::hash_to_float(id, seed); + /* Add one to the maximum and use floor to produce an even + * distribution for the first and last values (See T93591). */ + return floor(value * (max_value + 1 - min_value) + min_value); + }, + fn::build_mf::exec_presets::SomeSpanOrSingle<2>()); builder.set_matching_fn(fn); break; } case CD_PROP_BOOL: { - static fn::CustomMF, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag> - fn{"Random Bool", - [](float probability, int id, int seed, bool *r_value) { - *r_value = noise::hash_to_float(id, seed) <= probability; - }, - fn::CustomMF_presets::SomeSpanOrSingle<1>()}; + static auto fn = fn::build_mf::SI3_SO( + "Random Bool", + [](float probability, int id, int seed) -> bool { + return noise::hash_to_float(id, seed) <= probability; + }, + fn::build_mf::exec_presets::SomeSpanOrSingle<1>()); builder.set_matching_fn(fn); break; } diff --git a/source/blender/nodes/function/nodes/node_fn_replace_string.cc b/source/blender/nodes/function/nodes/node_fn_replace_string.cc index 3a388bedbc7..3b941018c6c 100644 --- a/source/blender/nodes/function/nodes/node_fn_replace_string.cc +++ b/source/blender/nodes/function/nodes/node_fn_replace_string.cc @@ -30,10 +30,12 @@ static std::string replace_all(const StringRefNull str, static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { - static fn::CustomMF_SI_SI_SI_SO substring_fn{ - "Replace", [](const std::string &str, const std::string &find, const std::string &replace) { - return replace_all(str, find, replace); - }}; + static auto substring_fn = + fn::build_mf::SI3_SO( + "Replace", + [](const std::string &str, const std::string &find, const std::string &replace) { + return replace_all(str, find, replace); + }); builder.set_matching_fn(&substring_fn); } diff --git a/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc b/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc index 7fd9762b4e0..0cdb876edb3 100644 --- a/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc +++ b/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc @@ -54,7 +54,7 @@ static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) static const fn::MultiFunction *get_multi_function(const bNode &bnode) { - static fn::CustomMF_SI_SI_SO obj_euler_rot{ + static auto obj_euler_rot = fn::build_mf::SI2_SO( "Rotate Euler by Euler/Object", [](const float3 &input, const float3 &rotation) { float input_mat[3][3]; eul_to_mat3(input_mat, input); @@ -65,8 +65,8 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode) float3 result; mat3_to_eul(result, mat_res); return result; - }}; - static fn::CustomMF_SI_SI_SI_SO obj_AA_rot{ + }); + static auto obj_AA_rot = fn::build_mf::SI3_SO( "Rotate Euler by AxisAngle/Object", [](const float3 &input, const float3 &axis, float angle) { float input_mat[3][3]; @@ -78,8 +78,8 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode) float3 result; mat3_to_eul(result, mat_res); return result; - }}; - static fn::CustomMF_SI_SI_SO local_euler_rot{ + }); + static auto local_euler_rot = fn::build_mf::SI2_SO( "Rotate Euler by Euler/Local", [](const float3 &input, const float3 &rotation) { float input_mat[3][3]; eul_to_mat3(input_mat, input); @@ -90,8 +90,8 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode) float3 result; mat3_to_eul(result, mat_res); return result; - }}; - static fn::CustomMF_SI_SI_SI_SO local_AA_rot{ + }); + static auto local_AA_rot = fn::build_mf::SI3_SO( "Rotate Euler by AxisAngle/Local", [](const float3 &input, const float3 &axis, float angle) { float input_mat[3][3]; eul_to_mat3(input_mat, input); @@ -102,14 +102,18 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode) float3 result; mat3_to_eul(result, mat_res); return result; - }}; + }); short type = bnode.custom1; short space = bnode.custom2; if (type == FN_NODE_ROTATE_EULER_TYPE_AXIS_ANGLE) { - return space == FN_NODE_ROTATE_EULER_SPACE_OBJECT ? &obj_AA_rot : &local_AA_rot; + return space == FN_NODE_ROTATE_EULER_SPACE_OBJECT ? + static_cast(&obj_AA_rot) : + &local_AA_rot; } if (type == FN_NODE_ROTATE_EULER_TYPE_EULER) { - return space == FN_NODE_ROTATE_EULER_SPACE_OBJECT ? &obj_euler_rot : &local_euler_rot; + return space == FN_NODE_ROTATE_EULER_SPACE_OBJECT ? + static_cast(&obj_euler_rot) : + &local_euler_rot; } BLI_assert_unreachable(); return nullptr; diff --git a/source/blender/nodes/function/nodes/node_fn_slice_string.cc b/source/blender/nodes/function/nodes/node_fn_slice_string.cc index 9ce928e2cc7..3785a6e74b3 100644 --- a/source/blender/nodes/function/nodes/node_fn_slice_string.cc +++ b/source/blender/nodes/function/nodes/node_fn_slice_string.cc @@ -16,13 +16,13 @@ static void node_declare(NodeDeclarationBuilder &b) static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { - static fn::CustomMF_SI_SI_SI_SO slice_fn{ + static auto slice_fn = fn::build_mf::SI3_SO( "Slice", [](const std::string &str, int a, int b) { const int len = BLI_strlen_utf8(str.c_str()); const int start = BLI_str_utf8_offset_from_index(str.c_str(), std::clamp(a, 0, len)); const int end = BLI_str_utf8_offset_from_index(str.c_str(), std::clamp(a + b, 0, len)); return str.substr(start, std::max(end - start, 0)); - }}; + }); builder.set_matching_fn(&slice_fn); } diff --git a/source/blender/nodes/function/nodes/node_fn_string_length.cc b/source/blender/nodes/function/nodes/node_fn_string_length.cc index 02bab0b8fbf..6ced713f8f4 100644 --- a/source/blender/nodes/function/nodes/node_fn_string_length.cc +++ b/source/blender/nodes/function/nodes/node_fn_string_length.cc @@ -16,8 +16,8 @@ static void node_declare(NodeDeclarationBuilder &b) static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { - static fn::CustomMF_SI_SO str_len_fn{ - "String Length", [](const std::string &a) { return BLI_strlen_utf8(a.c_str()); }}; + static auto str_len_fn = fn::build_mf::SI1_SO( + "String Length", [](const std::string &a) { return BLI_strlen_utf8(a.c_str()); }); builder.set_matching_fn(&str_len_fn); } diff --git a/source/blender/nodes/function/nodes/node_fn_value_to_string.cc b/source/blender/nodes/function/nodes/node_fn_value_to_string.cc index 12c0fe48327..0b542fc8405 100644 --- a/source/blender/nodes/function/nodes/node_fn_value_to_string.cc +++ b/source/blender/nodes/function/nodes/node_fn_value_to_string.cc @@ -14,12 +14,12 @@ static void node_declare(NodeDeclarationBuilder &b) static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { - static fn::CustomMF_SI_SI_SO to_str_fn{ + static auto to_str_fn = fn::build_mf::SI2_SO( "Value To String", [](float a, int b) { std::stringstream stream; stream << std::fixed << std::setprecision(std::max(0, b)) << a; return stream.str(); - }}; + }); builder.set_matching_fn(&to_str_fn); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index 27f34db2f9f..bbb63babde4 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -1325,10 +1325,10 @@ static void node_geo_exec(GeoNodeExecParams params) /* Create a combined field from the offset and the scale so the field evaluator * can take care of the multiplication and to simplify each extrude function. */ - static fn::CustomMF_SI_SI_SO multiply_fn{ + static auto multiply_fn = fn::build_mf::SI2_SO( "Scale", [](const float3 &offset, const float scale) { return offset * scale; }, - fn::CustomMF_presets::AllSpanOrSingle()}; + fn::build_mf::exec_presets::AllSpanOrSingle()); std::shared_ptr multiply_op = std::make_shared( FieldOperation(multiply_fn, {std::move(offset_field), std::move(scale_field)})); const Field final_offset{std::move(multiply_op)}; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc index f551faee2e0..c8100ea4c82 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc @@ -121,10 +121,10 @@ static void node_geo_exec(GeoNodeExecParams params) /* Use another multi-function operation to make sure the input radius is greater than zero. * TODO: Use mutable multi-function once that is supported. */ - static fn::CustomMF_SI_SO max_zero_fn( + static auto max_zero_fn = fn::build_mf::SI1_SO( __func__, [](float value) { return std::max(0.0f, value); }, - fn::CustomMF_presets::AllSpanOrSingle()); + fn::build_mf::exec_presets::AllSpanOrSingle()); auto max_zero_op = std::make_shared( FieldOperation(max_zero_fn, {std::move(radius)})); Field positive_radius(std::move(max_zero_op), 0); diff --git a/source/blender/nodes/geometry/nodes/node_geo_switch.cc b/source/blender/nodes/geometry/nodes/node_geo_switch.cc index 75136013e7e..04ff3d79fc4 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_switch.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_switch.cc @@ -171,10 +171,10 @@ template void switch_fields(GeoNodeExecParams ¶ms, const StringR Field falses_field = params.extract_input>(name_false); Field trues_field = params.extract_input>(name_true); - static fn::CustomMF_SI_SI_SI_SO switch_fn{ + static auto switch_fn = fn::build_mf::SI3_SO( "Switch", [](bool condition, const T &false_value, const T &true_value) { return condition ? true_value : false_value; - }}; + }); auto switch_op = std::make_shared(FieldOperation( std::move(switch_fn), diff --git a/source/blender/nodes/shader/nodes/node_shader_clamp.cc b/source/blender/nodes/shader/nodes/node_shader_clamp.cc index 5b7c216c4c3..08480c2d130 100644 --- a/source/blender/nodes/shader/nodes/node_shader_clamp.cc +++ b/source/blender/nodes/shader/nodes/node_shader_clamp.cc @@ -44,17 +44,17 @@ static int gpu_shader_clamp(GPUMaterial *mat, static void sh_node_clamp_build_multi_function(NodeMultiFunctionBuilder &builder) { - static fn::CustomMF_SI_SI_SI_SO minmax_fn{ + static auto minmax_fn = fn::build_mf::SI3_SO( "Clamp (Min Max)", - [](float value, float min, float max) { return std::min(std::max(value, min), max); }}; - static fn::CustomMF_SI_SI_SI_SO range_fn{ + [](float value, float min, float max) { return std::min(std::max(value, min), max); }); + static auto range_fn = fn::build_mf::SI3_SO( "Clamp (Range)", [](float value, float a, float b) { if (a < b) { return clamp_f(value, a, b); } return clamp_f(value, b, a); - }}; + }); int clamp_type = builder.node().custom1; if (clamp_type == NODE_CLAMP_MINMAX) { diff --git a/source/blender/nodes/shader/nodes/node_shader_map_range.cc b/source/blender/nodes/shader/nodes/node_shader_map_range.cc index a906ee40b42..eeebabe3f00 100644 --- a/source/blender/nodes/shader/nodes/node_shader_map_range.cc +++ b/source/blender/nodes/shader/nodes/node_shader_map_range.cc @@ -233,103 +233,74 @@ static float3 clamp_range(const float3 value, const float3 min, const float3 max template static auto build_float_linear() { - return fn::CustomMF, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag>{ + return fn::build_mf::SI5_SO( Clamp ? "Map Range (clamped)" : "Map Range (unclamped)", - [](float value, float from_min, float from_max, float to_min, float to_max, float *r_value) { + [](float value, float from_min, float from_max, float to_min, float to_max) -> float { const float factor = safe_divide(value - from_min, from_max - from_min); float result = to_min + factor * (to_max - to_min); if constexpr (Clamp) { result = clamp_range(result, to_min, to_max); } - *r_value = result; + return result; }, - fn::CustomMF_presets::SomeSpanOrSingle<0>()}; + fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); } template static auto build_float_stepped() { - return fn::CustomMF, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag>{ + return fn::build_mf::SI6_SO( Clamp ? "Map Range Stepped (clamped)" : "Map Range Stepped (unclamped)", - [](float value, - float from_min, - float from_max, - float to_min, - float to_max, - float steps, - float *r_value) { + [](float value, float from_min, float from_max, float to_min, float to_max, float steps) + -> float { float factor = safe_divide(value - from_min, from_max - from_min); factor = safe_divide(floorf(factor * (steps + 1.0f)), steps); float result = to_min + factor * (to_max - to_min); if constexpr (Clamp) { result = clamp_range(result, to_min, to_max); } - *r_value = result; + return result; }, - fn::CustomMF_presets::SomeSpanOrSingle<0>()}; + fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); } template static auto build_vector_linear() { - return fn::CustomMF, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag>{ + return fn::build_mf::SI5_SO( Clamp ? "Vector Map Range (clamped)" : "Vector Map Range (unclamped)", [](const float3 &value, const float3 &from_min, const float3 &from_max, const float3 &to_min, - const float3 &to_max, - float3 *r_value) { + const float3 &to_max) -> float3 { float3 factor = math::safe_divide(value - from_min, from_max - from_min); float3 result = factor * (to_max - to_min) + to_min; if constexpr (Clamp) { result = clamp_range(result, to_min, to_max); } - *r_value = result; + return result; }, - fn::CustomMF_presets::SomeSpanOrSingle<0>()}; + fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); } template static auto build_vector_stepped() { - return fn::CustomMF, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag>{ + return fn::build_mf::SI6_SO( Clamp ? "Vector Map Range Stepped (clamped)" : "Vector Map Range Stepped (unclamped)", [](const float3 &value, const float3 &from_min, const float3 &from_max, const float3 &to_min, const float3 &to_max, - const float3 &steps, - float3 *r_value) { + const float3 &steps) -> float3 { float3 factor = math::safe_divide(value - from_min, from_max - from_min); factor = math::safe_divide(math::floor(factor * (steps + 1.0f)), steps); float3 result = factor * (to_max - to_min) + to_min; if constexpr (Clamp) { result = clamp_range(result, to_min, to_max); } - *r_value = result; + return result; }, - fn::CustomMF_presets::SomeSpanOrSingle<0>()}; + fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); } static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &builder) @@ -364,48 +335,36 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui break; } case NODE_MAP_RANGE_SMOOTHSTEP: { - static fn::CustomMF, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag> - fn{"Vector Map Range Smoothstep", - [](const float3 &value, - const float3 &from_min, - const float3 &from_max, - const float3 &to_min, - const float3 &to_max, - float3 *r_value) { - float3 factor = math::safe_divide(value - from_min, from_max - from_min); - clamp_v3(factor, 0.0f, 1.0f); - factor = (float3(3.0f) - 2.0f * factor) * (factor * factor); - *r_value = factor * (to_max - to_min) + to_min; - }, - fn::CustomMF_presets::SomeSpanOrSingle<0>()}; + static auto fn = fn::build_mf::SI5_SO( + "Vector Map Range Smoothstep", + [](const float3 &value, + const float3 &from_min, + const float3 &from_max, + const float3 &to_min, + const float3 &to_max) -> float3 { + float3 factor = math::safe_divide(value - from_min, from_max - from_min); + clamp_v3(factor, 0.0f, 1.0f); + factor = (float3(3.0f) - 2.0f * factor) * (factor * factor); + return factor * (to_max - to_min) + to_min; + }, + fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); builder.set_matching_fn(fn); break; } case NODE_MAP_RANGE_SMOOTHERSTEP: { - static fn::CustomMF, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag> - fn{"Vector Map Range Smootherstep", - [](const float3 &value, - const float3 &from_min, - const float3 &from_max, - const float3 &to_min, - const float3 &to_max, - float3 *r_value) { - float3 factor = math::safe_divide(value - from_min, from_max - from_min); - clamp_v3(factor, 0.0f, 1.0f); - factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f); - *r_value = factor * (to_max - to_min) + to_min; - }, - fn::CustomMF_presets::SomeSpanOrSingle<0>()}; + static auto fn = fn::build_mf::SI5_SO( + "Vector Map Range Smootherstep", + [](const float3 &value, + const float3 &from_min, + const float3 &from_max, + const float3 &to_min, + const float3 &to_max) -> float3 { + float3 factor = math::safe_divide(value - from_min, from_max - from_min); + clamp_v3(factor, 0.0f, 1.0f); + factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f); + return factor * (to_max - to_min) + to_min; + }, + fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); builder.set_matching_fn(fn); break; } @@ -438,48 +397,30 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui break; } case NODE_MAP_RANGE_SMOOTHSTEP: { - static fn::CustomMF, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag> - fn{"Map Range Smoothstep", - [](float value, - float from_min, - float from_max, - float to_min, - float to_max, - float *r_value) { - float factor = safe_divide(value - from_min, from_max - from_min); - factor = std::clamp(factor, 0.0f, 1.0f); - factor = (3.0f - 2.0f * factor) * (factor * factor); - *r_value = to_min + factor * (to_max - to_min); - }, - fn::CustomMF_presets::SomeSpanOrSingle<0>()}; + static auto fn = fn::build_mf::SI5_SO( + "Map Range Smoothstep", + [](float value, float from_min, float from_max, float to_min, float to_max) + -> float { + float factor = safe_divide(value - from_min, from_max - from_min); + factor = std::clamp(factor, 0.0f, 1.0f); + factor = (3.0f - 2.0f * factor) * (factor * factor); + return to_min + factor * (to_max - to_min); + }, + fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); builder.set_matching_fn(fn); break; } case NODE_MAP_RANGE_SMOOTHERSTEP: { - static fn::CustomMF, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag, - fn::MFParamTag> - fn{"Map Range Smoothstep", - [](float value, - float from_min, - float from_max, - float to_min, - float to_max, - float *r_value) { - float factor = safe_divide(value - from_min, from_max - from_min); - factor = std::clamp(factor, 0.0f, 1.0f); - factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f); - *r_value = to_min + factor * (to_max - to_min); - }, - fn::CustomMF_presets::SomeSpanOrSingle<0>()}; + static auto fn = fn::build_mf::SI5_SO( + "Map Range Smoothstep", + [](float value, float from_min, float from_max, float to_min, float to_max) + -> float { + float factor = safe_divide(value - from_min, from_max - from_min); + factor = std::clamp(factor, 0.0f, 1.0f); + factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f); + return to_min + factor * (to_max - to_min); + }, + fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); builder.set_matching_fn(fn); break; } diff --git a/source/blender/nodes/shader/nodes/node_shader_math.cc b/source/blender/nodes/shader/nodes/node_shader_math.cc index 5fe1bb48cc2..1a2c22862b3 100644 --- a/source/blender/nodes/shader/nodes/node_shader_math.cc +++ b/source/blender/nodes/shader/nodes/node_shader_math.cc @@ -109,8 +109,8 @@ static const fn::MultiFunction *get_base_multi_function(const bNode &node) try_dispatch_float_math_fl_to_fl( mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SO fn{ - info.title_case_name.c_str(), function, devi_fn}; + static auto fn = fn::build_mf::SI1_SO( + info.title_case_name.c_str(), function, devi_fn); base_fn = &fn; }); if (base_fn != nullptr) { @@ -119,8 +119,8 @@ static const fn::MultiFunction *get_base_multi_function(const bNode &node) try_dispatch_float_math_fl_fl_to_fl( mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SI_SO fn{ - info.title_case_name.c_str(), function, devi_fn}; + static auto fn = fn::build_mf::SI2_SO( + info.title_case_name.c_str(), function, devi_fn); base_fn = &fn; }); if (base_fn != nullptr) { @@ -129,8 +129,8 @@ static const fn::MultiFunction *get_base_multi_function(const bNode &node) try_dispatch_float_math_fl_fl_fl_to_fl( mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SI_SI_SO fn{ - info.title_case_name.c_str(), function, devi_fn}; + static auto fn = fn::build_mf::SI3_SO( + info.title_case_name.c_str(), function, devi_fn); base_fn = &fn; }); if (base_fn != nullptr) { diff --git a/source/blender/nodes/shader/nodes/node_shader_mix.cc b/source/blender/nodes/shader/nodes/node_shader_mix.cc index a9bc1f7f98e..e8255f1f6af 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix.cc @@ -412,51 +412,51 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) switch (data->data_type) { case SOCK_FLOAT: { if (clamp_factor) { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Clamp Mix Float", [](float t, const float a, const float b) { return math::interpolate(a, b, std::clamp(t, 0.0f, 1.0f)); - }}; + }); return &fn; } else { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Mix Float", [](const float t, const float a, const float b) { return math::interpolate(a, b, t); - }}; + }); return &fn; } } case SOCK_VECTOR: { if (clamp_factor) { if (uniform_factor) { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Clamp Mix Vector", [](const float t, const float3 a, const float3 b) { return math::interpolate(a, b, std::clamp(t, 0.0f, 1.0f)); - }}; + }); return &fn; } else { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Clamp Mix Vector Non Uniform", [](float3 t, const float3 a, const float3 b) { t = math::clamp(t, 0.0f, 1.0f); return a * (float3(1.0f) - t) + b * t; - }}; + }); return &fn; } } else { if (uniform_factor) { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Mix Vector", [](const float t, const float3 a, const float3 b) { return math::interpolate(a, b, t); - }}; + }); return &fn; } else { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Mix Vector Non Uniform", [](const float3 t, const float3 a, const float3 b) { return a * (float3(1.0f) - t) + b * t; - }}; + }); return &fn; } } diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc index 28c4eef823f..219f31eefd7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc @@ -108,8 +108,8 @@ static int gpu_shader_combrgb(GPUMaterial *mat, static void sh_node_combrgb_build_multi_function(NodeMultiFunctionBuilder &builder) { - static fn::CustomMF_SI_SI_SI_SO fn{ - "Combine RGB", [](float r, float g, float b) { return ColorGeometry4f(r, g, b, 1.0f); }}; + static auto fn = fn::build_mf::SI3_SO( + "Combine RGB", [](float r, float g, float b) { return ColorGeometry4f(r, g, b, 1.0f); }); builder.set_matching_fn(fn); } diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc index 131ae16ef1b..1ee6947480c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc @@ -125,10 +125,10 @@ static int gpu_shader_combxyz(GPUMaterial *mat, static void sh_node_combxyz_build_multi_function(NodeMultiFunctionBuilder &builder) { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Combine Vector", [](float x, float y, float z) { return float3(x, y, z); }, - fn::CustomMF_presets::AllSpanOrSingle()}; + fn::build_mf::exec_presets::AllSpanOrSingle()); builder.set_matching_fn(fn); } diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc index f7cf70aa8e1..96747139b87 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc @@ -233,8 +233,8 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) try_dispatch_float_math_fl3_fl3_to_fl3( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SI_SO fn{ - info.title_case_name.c_str(), function, exec_preset}; + static auto fn = fn::build_mf::SI2_SO( + info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -243,8 +243,8 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) try_dispatch_float_math_fl3_fl3_fl3_to_fl3( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SI_SI_SO fn{ - info.title_case_name.c_str(), function, exec_preset}; + static auto fn = fn::build_mf::SI3_SO( + info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -253,8 +253,8 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) try_dispatch_float_math_fl3_fl3_fl_to_fl3( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SI_SI_SO fn{ - info.title_case_name.c_str(), function, exec_preset}; + static auto fn = fn::build_mf::SI3_SO( + info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -263,8 +263,8 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) try_dispatch_float_math_fl3_fl3_to_fl( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SI_SO fn{ - info.title_case_name.c_str(), function, exec_preset}; + static auto fn = fn::build_mf::SI2_SO( + info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -273,8 +273,8 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) try_dispatch_float_math_fl3_fl_to_fl3( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SI_SO fn{ - info.title_case_name.c_str(), function, exec_preset}; + static auto fn = fn::build_mf::SI2_SO( + info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -283,8 +283,8 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) try_dispatch_float_math_fl3_to_fl3( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SO fn{ - info.title_case_name.c_str(), function, exec_preset}; + static auto fn = fn::build_mf::SI1_SO( + info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); if (multi_fn != nullptr) { @@ -293,8 +293,8 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) try_dispatch_float_math_fl3_to_fl( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static fn::CustomMF_SI_SO fn{ - info.title_case_name.c_str(), function, exec_preset}; + static auto fn = fn::build_mf::SI1_SO( + info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); if (multi_fn != nullptr) { diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc index bdf7360873d..d59c9271ccb 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc @@ -104,77 +104,77 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) switch (mode) { case NODE_VECTOR_ROTATE_TYPE_AXIS: { if (invert) { - static fn::CustomMF_SI_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI4_SO( "Rotate Axis", [](const float3 &in, const float3 ¢er, const float3 &axis, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, -angle); - }}; + }); return &fn; } - static fn::CustomMF_SI_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI4_SO( "Rotate Axis", [](const float3 &in, const float3 ¢er, const float3 &axis, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, angle); - }}; + }); return &fn; } case NODE_VECTOR_ROTATE_TYPE_AXIS_X: { float3 axis = float3(1.0f, 0.0f, 0.0f); if (invert) { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Rotate X-Axis", [=](const float3 &in, const float3 ¢er, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, -angle); - }}; + }); return &fn; } - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Rotate X-Axis", [=](const float3 &in, const float3 ¢er, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, angle); - }}; + }); return &fn; } case NODE_VECTOR_ROTATE_TYPE_AXIS_Y: { float3 axis = float3(0.0f, 1.0f, 0.0f); if (invert) { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Rotate Y-Axis", [=](const float3 &in, const float3 ¢er, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, -angle); - }}; + }); return &fn; } - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Rotate Y-Axis", [=](const float3 &in, const float3 ¢er, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, angle); - }}; + }); return &fn; } case NODE_VECTOR_ROTATE_TYPE_AXIS_Z: { float3 axis = float3(0.0f, 0.0f, 1.0f); if (invert) { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Rotate Z-Axis", [=](const float3 &in, const float3 ¢er, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, -angle); - }}; + }); return &fn; } - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Rotate Z-Axis", [=](const float3 &in, const float3 ¢er, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, angle); - }}; + }); return &fn; } case NODE_VECTOR_ROTATE_TYPE_EULER_XYZ: { if (invert) { - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Rotate Euler", [](const float3 &in, const float3 ¢er, const float3 &rotation) { return sh_node_vector_rotate_euler(in, center, rotation, true); - }}; + }); return &fn; } - static fn::CustomMF_SI_SI_SI_SO fn{ + static auto fn = fn::build_mf::SI3_SO( "Rotate Euler", [](const float3 &in, const float3 ¢er, const float3 &rotation) { return sh_node_vector_rotate_euler(in, center, rotation, false); - }}; + }); return &fn; } default: From 577442a26fd3c5c17ddb04326e8da22e28bfca80 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 7 Jan 2023 16:30:56 +0100 Subject: [PATCH 0499/1522] Functions: build multi-function signature in-place This avoids a move of the signature after building it. Tthe value had to be moved out of `MFSignatureBuilder` in the `build` method. This also makes the naming a bit less confusing where sometimes both the `MFSignature` and `MFSignatureBuilder` were referred to as "signature". --- .../functions/FN_multi_function_builder.hh | 10 ++- .../functions/FN_multi_function_signature.hh | 10 +-- .../intern/multi_function_builder.cc | 24 +++---- .../multi_function_procedure_executor.cc | 5 +- .../blender/functions/tests/FN_field_test.cc | 11 ++-- .../functions/tests/FN_multi_function_test.cc | 11 ++-- .../tests/FN_multi_function_test_common.hh | 61 +++++++++-------- .../nodes/node_fn_align_euler_to_vector.cc | 13 ++-- .../nodes/node_fn_input_special_characters.cc | 9 +-- .../function/nodes/node_fn_separate_color.cc | 45 +++++++------ .../geometry/nodes/node_geo_curve_sample.cc | 28 ++++---- .../geometry/nodes/node_geo_image_texture.cc | 11 ++-- .../geometry/nodes/node_geo_proximity.cc | 11 ++-- .../nodes/geometry/nodes/node_geo_raycast.cc | 21 +++--- .../geometry/nodes/node_geo_sample_index.cc | 9 +-- .../geometry/nodes/node_geo_sample_nearest.cc | 9 +-- .../nodes/node_geo_sample_nearest_surface.cc | 9 +-- .../nodes/node_geo_sample_uv_surface.cc | 24 +++---- .../shader/nodes/node_shader_color_ramp.cc | 11 ++-- .../nodes/shader/nodes/node_shader_curves.cc | 33 +++++----- .../nodes/shader/nodes/node_shader_mix.cc | 13 ++-- .../nodes/shader/nodes/node_shader_mix_rgb.cc | 13 ++-- .../shader/nodes/node_shader_sepcomb_rgb.cc | 13 ++-- .../shader/nodes/node_shader_sepcomb_xyz.cc | 13 ++-- .../shader/nodes/node_shader_tex_brick.cc | 29 +++++---- .../shader/nodes/node_shader_tex_checker.cc | 17 ++--- .../shader/nodes/node_shader_tex_gradient.cc | 11 ++-- .../shader/nodes/node_shader_tex_magic.cc | 15 +++-- .../shader/nodes/node_shader_tex_musgrave.cc | 23 +++---- .../shader/nodes/node_shader_tex_noise.cc | 21 +++--- .../shader/nodes/node_shader_tex_voronoi.cc | 65 ++++++++++--------- .../shader/nodes/node_shader_tex_wave.cc | 23 +++---- .../nodes/node_shader_tex_white_noise.cc | 13 ++-- 33 files changed, 331 insertions(+), 303 deletions(-) diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index 3a491a63e6c..f9f0890f4fb 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -445,10 +445,9 @@ template class CustomMF : public MultiFu CustomMF(const char *name, CallFn call_fn, TypeSequence /*param_tags*/) : call_fn_(std::move(call_fn)) { - MFSignatureBuilder signature{name}; + MFSignatureBuilder builder{name, signature_}; /* Loop over all parameter types and add an entry for each in the signature. */ - ([&] { signature.add(ParamTags(), ""); }(), ...); - signature_ = signature.build(); + ([&] { builder.add(ParamTags(), ""); }(), ...); this->set_signature(&signature_); } @@ -631,9 +630,8 @@ template class CustomMF_Constant : public MultiFunction { public: template CustomMF_Constant(U &&value) : value_(std::forward(value)) { - MFSignatureBuilder signature{"Constant"}; - signature.single_output("Value"); - signature_ = signature.build(); + MFSignatureBuilder builder{"Constant", signature_}; + builder.single_output("Value"); this->set_signature(&signature_); } diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh index 1c2d645c1fd..44f2b84867d 100644 --- a/source/blender/functions/FN_multi_function_signature.hh +++ b/source/blender/functions/FN_multi_function_signature.hh @@ -32,19 +32,15 @@ struct MFSignature { class MFSignatureBuilder { private: - MFSignature signature_; + MFSignature &signature_; public: - MFSignatureBuilder(const char *function_name) + MFSignatureBuilder(const char *function_name, MFSignature &signature_to_build) + : signature_(signature_to_build) { signature_.function_name = function_name; } - MFSignature build() const - { - return std::move(signature_); - } - /* Input Parameter Types */ template void single_input(const char *name) diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc index 32a41f99c48..bda5ec19cea 100644 --- a/source/blender/functions/intern/multi_function_builder.cc +++ b/source/blender/functions/intern/multi_function_builder.cc @@ -18,9 +18,8 @@ CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type, } value_ = value; - MFSignatureBuilder signature{"Constant"}; - signature.single_output("Value", type); - signature_ = signature.build(); + MFSignatureBuilder builder{"Constant", signature_}; + builder.single_output("Value", type); this->set_signature(&signature_); } @@ -58,9 +57,8 @@ bool CustomMF_GenericConstant::equals(const MultiFunction &other) const CustomMF_GenericConstantArray::CustomMF_GenericConstantArray(GSpan array) : array_(array) { const CPPType &type = array.type(); - MFSignatureBuilder signature{"Constant Vector"}; - signature.vector_output("Value", type); - signature_ = signature.build(); + MFSignatureBuilder builder{"Constant Vector", signature_}; + builder.vector_output("Value", type); this->set_signature(&signature_); } @@ -78,14 +76,13 @@ CustomMF_DefaultOutput::CustomMF_DefaultOutput(Span input_types, Span output_types) : output_amount_(output_types.size()) { - MFSignatureBuilder signature{"Default Output"}; + MFSignatureBuilder builder{"Default Output", signature_}; for (MFDataType data_type : input_types) { - signature.input("Input", data_type); + builder.input("Input", data_type); } for (MFDataType data_type : output_types) { - signature.output("Output", data_type); + builder.output("Output", data_type); } - signature_ = signature.build(); this->set_signature(&signature_); } void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext /*context*/) const @@ -106,10 +103,9 @@ void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext /*c CustomMF_GenericCopy::CustomMF_GenericCopy(MFDataType data_type) { - MFSignatureBuilder signature{"Copy"}; - signature.input("Input", data_type); - signature.output("Output", data_type); - signature_ = signature.build(); + MFSignatureBuilder builder{"Copy", signature_}; + builder.input("Input", data_type); + builder.output("Output", data_type); this->set_signature(&signature_); } diff --git a/source/blender/functions/intern/multi_function_procedure_executor.cc b/source/blender/functions/intern/multi_function_procedure_executor.cc index 4fe3c27ea27..6c997e2e222 100644 --- a/source/blender/functions/intern/multi_function_procedure_executor.cc +++ b/source/blender/functions/intern/multi_function_procedure_executor.cc @@ -8,13 +8,12 @@ namespace blender::fn { MFProcedureExecutor::MFProcedureExecutor(const MFProcedure &procedure) : procedure_(procedure) { - MFSignatureBuilder signature("Procedure Executor"); + MFSignatureBuilder builder("Procedure Executor", signature_); for (const ConstMFParameter ¶m : procedure.params()) { - signature.add("Parameter", MFParamType(param.type, param.variable->data_type())); + builder.add("Parameter", MFParamType(param.type, param.variable->data_type())); } - signature_ = signature.build(); this->set_signature(&signature_); } diff --git a/source/blender/functions/tests/FN_field_test.cc b/source/blender/functions/tests/FN_field_test.cc index 3e5c201195f..5e3ae5676fc 100644 --- a/source/blender/functions/tests/FN_field_test.cc +++ b/source/blender/functions/tests/FN_field_test.cc @@ -156,12 +156,11 @@ class TwoOutputFunction : public MultiFunction { public: TwoOutputFunction() { - MFSignatureBuilder signature{"Two Outputs"}; - signature.single_input("In1"); - signature.single_input("In2"); - signature.single_output("Add"); - signature.single_output("Add10"); - signature_ = signature.build(); + MFSignatureBuilder builder{"Two Outputs", signature_}; + builder.single_input("In1"); + builder.single_input("In2"); + builder.single_output("Add"); + builder.single_output("Add10"); this->set_signature(&signature_); } diff --git a/source/blender/functions/tests/FN_multi_function_test.cc b/source/blender/functions/tests/FN_multi_function_test.cc index 7a582805e98..5306fe0b20c 100644 --- a/source/blender/functions/tests/FN_multi_function_test.cc +++ b/source/blender/functions/tests/FN_multi_function_test.cc @@ -19,11 +19,12 @@ class AddFunction : public MultiFunction { static MFSignature create_signature() { - MFSignatureBuilder signature("Add"); - signature.single_input("A"); - signature.single_input("B"); - signature.single_output("Result"); - return signature.build(); + MFSignature signature; + MFSignatureBuilder builder("Add", signature); + builder.single_input("A"); + builder.single_input("B"); + builder.single_output("Result"); + return signature; } void call(IndexMask mask, MFParams params, MFContext /*context*/) const override diff --git a/source/blender/functions/tests/FN_multi_function_test_common.hh b/source/blender/functions/tests/FN_multi_function_test_common.hh index 15e8baf2001..82433723760 100644 --- a/source/blender/functions/tests/FN_multi_function_test_common.hh +++ b/source/blender/functions/tests/FN_multi_function_test_common.hh @@ -14,10 +14,11 @@ class AddPrefixFunction : public MultiFunction { static MFSignature create_signature() { - MFSignatureBuilder signature{"Add Prefix"}; - signature.single_input("Prefix"); - signature.single_mutable("Strings"); - return signature.build(); + MFSignature signature; + MFSignatureBuilder builder{"Add Prefix", signature}; + builder.single_input("Prefix"); + builder.single_mutable("Strings"); + return signature; } void call(IndexMask mask, MFParams params, MFContext /*context*/) const override @@ -41,10 +42,11 @@ class CreateRangeFunction : public MultiFunction { static MFSignature create_signature() { - MFSignatureBuilder signature{"Create Range"}; - signature.single_input("Size"); - signature.vector_output("Range"); - return signature.build(); + MFSignature signature; + MFSignatureBuilder builder{"Create Range", signature}; + builder.single_input("Size"); + builder.vector_output("Range"); + return signature; } void call(IndexMask mask, MFParams params, MFContext /*context*/) const override @@ -68,10 +70,9 @@ class GenericAppendFunction : public MultiFunction { public: GenericAppendFunction(const CPPType &type) { - MFSignatureBuilder signature{"Append"}; - signature.vector_mutable("Vector", type); - signature.single_input("Value", type); - signature_ = signature.build(); + MFSignatureBuilder builder{"Append", signature_}; + builder.vector_mutable("Vector", type); + builder.single_input("Value", type); this->set_signature(&signature_); } @@ -99,10 +100,11 @@ class ConcatVectorsFunction : public MultiFunction { static MFSignature create_signature() { - MFSignatureBuilder signature{"Concat Vectors"}; - signature.vector_mutable("A"); - signature.vector_input("B"); - return signature.build(); + MFSignature signature; + MFSignatureBuilder builder{"Concat Vectors", signature}; + builder.vector_mutable("A"); + builder.vector_input("B"); + return signature; } void call(IndexMask mask, MFParams params, MFContext /*context*/) const override @@ -123,10 +125,11 @@ class AppendFunction : public MultiFunction { static MFSignature create_signature() { - MFSignatureBuilder signature{"Append"}; - signature.vector_mutable("Vector"); - signature.single_input("Value"); - return signature.build(); + MFSignature signature; + MFSignatureBuilder builder{"Append", signature}; + builder.vector_mutable("Vector"); + builder.single_input("Value"); + return signature; } void call(IndexMask mask, MFParams params, MFContext /*context*/) const override @@ -150,10 +153,11 @@ class SumVectorFunction : public MultiFunction { static MFSignature create_signature() { - MFSignatureBuilder signature{"Sum Vectors"}; - signature.vector_input("Vector"); - signature.single_output("Sum"); - return signature.build(); + MFSignature signature; + MFSignatureBuilder builder{"Sum Vectors", signature}; + builder.vector_input("Vector"); + builder.single_output("Sum"); + return signature; } void call(IndexMask mask, MFParams params, MFContext /*context*/) const override @@ -181,10 +185,11 @@ class OptionalOutputsFunction : public MultiFunction { static MFSignature create_signature() { - MFSignatureBuilder signature{"Optional Outputs"}; - signature.single_output("Out 1"); - signature.single_output("Out 2"); - return signature.build(); + MFSignature signature; + MFSignatureBuilder builder{"Optional Outputs", signature}; + builder.single_output("Out 1"); + builder.single_output("Out 2"); + return signature; } void call(IndexMask mask, MFParams params, MFContext /*context*/) const override diff --git a/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc b/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc index 20180971127..21290220ff6 100644 --- a/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc +++ b/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc @@ -148,13 +148,14 @@ class MF_AlignEulerToVector : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Align Euler to Vector"}; - signature.single_input("Rotation"); - signature.single_input("Factor"); - signature.single_input("Vector"); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Align Euler to Vector", signature}; + builder.single_input("Rotation"); + builder.single_input("Factor"); + builder.single_input("Vector"); - signature.single_output("Rotation"); - return signature.build(); + builder.single_output("Rotation"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc b/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc index 44397d27121..fab8d13ffcb 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc @@ -20,10 +20,11 @@ class MF_SpecialCharacters : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Special Characters"}; - signature.single_output("Line Break"); - signature.single_output("Tab"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Special Characters", signature}; + builder.single_output("Line Break"); + builder.single_output("Tab"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/function/nodes/node_fn_separate_color.cc b/source/blender/nodes/function/nodes/node_fn_separate_color.cc index 4e48d7fa44b..bb663fb4427 100644 --- a/source/blender/nodes/function/nodes/node_fn_separate_color.cc +++ b/source/blender/nodes/function/nodes/node_fn_separate_color.cc @@ -47,13 +47,14 @@ class SeparateRGBAFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Separate Color"}; - signature.single_input("Color"); - signature.single_output("Red"); - signature.single_output("Green"); - signature.single_output("Blue"); - signature.single_output("Alpha"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Separate Color", signature}; + builder.single_input("Color"); + builder.single_output("Red"); + builder.single_output("Green"); + builder.single_output("Blue"); + builder.single_output("Alpha"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override @@ -108,13 +109,14 @@ class SeparateHSVAFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Separate Color"}; - signature.single_input("Color"); - signature.single_output("Hue"); - signature.single_output("Saturation"); - signature.single_output("Value"); - signature.single_output("Alpha"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Separate Color", signature}; + builder.single_input("Color"); + builder.single_output("Hue"); + builder.single_output("Saturation"); + builder.single_output("Value"); + builder.single_output("Alpha"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override @@ -148,13 +150,14 @@ class SeparateHSLAFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Separate Color"}; - signature.single_input("Color"); - signature.single_output("Hue"); - signature.single_output("Saturation"); - signature.single_output("Lightness"); - signature.single_output("Alpha"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Separate Color", signature}; + builder.single_input("Color"); + builder.single_output("Hue"); + builder.single_output("Saturation"); + builder.single_output("Lightness"); + builder.single_output("Alpha"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc index a18627f2142..4fb5889a057 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc @@ -217,12 +217,13 @@ class SampleFloatSegmentsFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Sample Curve Index"}; - signature.single_input("Length"); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Sample Curve Index", signature}; + builder.single_input("Length"); - signature.single_output("Curve Index"); - signature.single_output("Length in Curve"); - return signature.build(); + builder.single_output("Curve Index"); + builder.single_output("Length in Curve"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override @@ -267,14 +268,15 @@ class SampleCurveFunction : public fn::MultiFunction { fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Sample Curve"}; - signature.single_input("Curve Index"); - signature.single_input("Length"); - signature.single_output("Position"); - signature.single_output("Tangent"); - signature.single_output("Normal"); - signature.single_output("Value", src_field_.cpp_type()); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Sample Curve", signature}; + builder.single_input("Curve Index"); + builder.single_input("Length"); + builder.single_output("Position"); + builder.single_output("Tangent"); + builder.single_output("Normal"); + builder.single_output("Value", src_field_.cpp_type()); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc index a93956ba042..1fed3136ee1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc @@ -93,11 +93,12 @@ class ImageFieldsFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"ImageFunction"}; - signature.single_input("Vector"); - signature.single_output("Color"); - signature.single_output("Alpha"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"ImageFunction", signature}; + builder.single_input("Vector"); + builder.single_output("Color"); + builder.single_output("Alpha"); + return signature; } static int wrap_periodic(int x, const int width) diff --git a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc index c3c776e9067..9655df2ef8e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc @@ -144,11 +144,12 @@ class ProximityFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Geometry Proximity"}; - signature.single_input("Source Position"); - signature.single_output("Position"); - signature.single_output("Distance"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Geometry Proximity", signature}; + builder.single_input("Source Position"); + builder.single_output("Position"); + builder.single_output("Distance"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc index dbaabbea799..85e545271ec 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc @@ -231,18 +231,19 @@ class RaycastFunction : public fn::MultiFunction { fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Geometry Proximity"}; - signature.single_input("Source Position"); - signature.single_input("Ray Direction"); - signature.single_input("Ray Length"); - signature.single_output("Is Hit"); - signature.single_output("Hit Position"); - signature.single_output("Hit Normal"); - signature.single_output("Distance"); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Geometry Proximity", signature}; + builder.single_input("Source Position"); + builder.single_input("Ray Direction"); + builder.single_input("Ray Length"); + builder.single_output("Is Hit"); + builder.single_output("Hit Position"); + builder.single_output("Hit Normal"); + builder.single_output("Distance"); if (target_data_) { - signature.single_output("Attribute", target_data_->type()); + builder.single_output("Attribute", target_data_->type()); } - return signature.build(); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc index 3dd47d37ea8..48b45106f61 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc @@ -208,10 +208,11 @@ class SampleIndexFunction : public fn::MultiFunction { fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Sample Index"}; - signature.single_input("Index"); - signature.single_output("Value", src_field_.cpp_type()); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Sample Index", signature}; + builder.single_input("Index"); + builder.single_output("Value", src_field_.cpp_type()); + return signature; } void evaluate_field() diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc index b38d7f2fec4..cb9e6ca8edd 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc @@ -253,10 +253,11 @@ class SampleNearestFunction : public fn::MultiFunction { fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Sample Nearest"}; - signature.single_input("Position"); - signature.single_output("Index"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Sample Nearest", signature}; + builder.single_input("Position"); + builder.single_output("Index"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc index 2628fcf3321..29361251e91 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc @@ -146,10 +146,11 @@ class SampleNearestSurfaceFunction : public fn::MultiFunction { fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Sample Nearest Surface"}; - signature.single_input("Position"); - signature.single_output("Value", src_field_.cpp_type()); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Sample Nearest Surface", signature}; + builder.single_input("Position"); + builder.single_output("Value", src_field_.cpp_type()); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc index 7fb4596dfbe..6291c9b4e28 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc @@ -136,11 +136,12 @@ class SampleMeshBarycentricFunction : public fn::MultiFunction { fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Sample Barycentric Triangles"}; - signature.single_input("Triangle Index"); - signature.single_input("Barycentric Weight"); - signature.single_output("Value", src_field_.cpp_type()); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Sample Barycentric Triangles", signature}; + builder.single_input("Triangle Index"); + builder.single_input("Barycentric Weight"); + builder.single_output("Value", src_field_.cpp_type()); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override @@ -206,12 +207,13 @@ class ReverseUVSampleFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Sample UV Surface"}; - signature.single_input("Sample UV"); - signature.single_output("Is Valid"); - signature.single_output("Triangle Index"); - signature.single_output("Barycentric Weights"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Sample UV Surface", signature}; + builder.single_input("Sample UV"); + builder.single_output("Is Valid"); + builder.single_output("Triangle Index"); + builder.single_output("Barycentric Weights"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc b/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc index f5d405c7678..1f82a91aa1c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc +++ b/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc @@ -100,11 +100,12 @@ class ColorBandFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Color Band"}; - signature.single_input("Value"); - signature.single_output("Color"); - signature.single_output("Alpha"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Color Band", signature}; + builder.single_input("Value"); + builder.single_output("Color"); + builder.single_output("Alpha"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.cc b/source/blender/nodes/shader/nodes/node_shader_curves.cc index 0945c39ee50..30452861ff4 100644 --- a/source/blender/nodes/shader/nodes/node_shader_curves.cc +++ b/source/blender/nodes/shader/nodes/node_shader_curves.cc @@ -76,11 +76,12 @@ class CurveVecFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Curve Vec"}; - signature.single_input("Fac"); - signature.single_input("Vector"); - signature.single_output("Vector"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Curve Vec", signature}; + builder.single_input("Fac"); + builder.single_input("Vector"); + builder.single_output("Vector"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override @@ -221,11 +222,12 @@ class CurveRGBFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Curve RGB"}; - signature.single_input("Fac"); - signature.single_input("Color"); - signature.single_output("Color"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Curve RGB", signature}; + builder.single_input("Fac"); + builder.single_input("Color"); + builder.single_output("Color"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override @@ -343,11 +345,12 @@ class CurveFloatFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Curve Float"}; - signature.single_input("Factor"); - signature.single_input("Value"); - signature.single_output("Value"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Curve Float", signature}; + builder.single_input("Factor"); + builder.single_input("Value"); + builder.single_output("Value"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_mix.cc b/source/blender/nodes/shader/nodes/node_shader_mix.cc index e8255f1f6af..243e752bed7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix.cc @@ -367,12 +367,13 @@ class MixColorFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"MixColor"}; - signature.single_input("Factor"); - signature.single_input("A"); - signature.single_input("B"); - signature.single_output("Result"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"MixColor", signature}; + builder.single_input("Factor"); + builder.single_input("A"); + builder.single_input("B"); + builder.single_output("Result"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc index aadbdbe4716..74d3a90b13f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc @@ -105,12 +105,13 @@ class MixRGBFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"MixRGB"}; - signature.single_input("Fac"); - signature.single_input("Color1"); - signature.single_input("Color2"); - signature.single_output("Color"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"MixRGB", signature}; + builder.single_input("Fac"); + builder.single_input("Color1"); + builder.single_input("Color2"); + builder.single_output("Color"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc index 219f31eefd7..9c7e632ebd4 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc @@ -37,12 +37,13 @@ class SeparateRGBFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Separate RGB"}; - signature.single_input("Color"); - signature.single_output("R"); - signature.single_output("G"); - signature.single_output("B"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Separate RGB", signature}; + builder.single_input("Color"); + builder.single_output("R"); + builder.single_output("G"); + builder.single_output("B"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc index 1ee6947480c..83f580782a9 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc @@ -37,12 +37,13 @@ class MF_SeparateXYZ : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Separate XYZ"}; - signature.single_input("XYZ"); - signature.single_output("X"); - signature.single_output("Y"); - signature.single_output("Z"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Separate XYZ", signature}; + builder.single_input("XYZ"); + builder.single_output("X"); + builder.single_output("Y"); + builder.single_output("Z"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc index 502f5db3bf3..80f1b5a73e8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc @@ -128,20 +128,21 @@ class BrickFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"BrickTexture"}; - signature.single_input("Vector"); - signature.single_input("Color1"); - signature.single_input("Color2"); - signature.single_input("Mortar"); - signature.single_input("Scale"); - signature.single_input("Mortar Size"); - signature.single_input("Mortar Smooth"); - signature.single_input("Bias"); - signature.single_input("Brick Width"); - signature.single_input("Row Height"); - signature.single_output("Color"); - signature.single_output("Fac"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"BrickTexture", signature}; + builder.single_input("Vector"); + builder.single_input("Color1"); + builder.single_input("Color2"); + builder.single_input("Mortar"); + builder.single_input("Scale"); + builder.single_input("Mortar Size"); + builder.single_input("Mortar Smooth"); + builder.single_input("Bias"); + builder.single_input("Brick Width"); + builder.single_input("Row Height"); + builder.single_output("Color"); + builder.single_output("Fac"); + return signature; } /* Fast integer noise. */ diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc index bef3eb990eb..61c85b136f8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc @@ -54,14 +54,15 @@ class NodeTexChecker : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"Checker"}; - signature.single_input("Vector"); - signature.single_input("Color1"); - signature.single_input("Color2"); - signature.single_input("Scale"); - signature.single_output("Color"); - signature.single_output("Fac"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Checker", signature}; + builder.single_input("Vector"); + builder.single_input("Color1"); + builder.single_input("Color2"); + builder.single_input("Scale"); + builder.single_output("Color"); + builder.single_output("Fac"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc index f7bff442420..d1c2990d7e2 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc @@ -60,11 +60,12 @@ class GradientFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"GradientFunction"}; - signature.single_input("Vector"); - signature.single_output("Color"); - signature.single_output("Fac"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"GradientFunction", signature}; + builder.single_input("Vector"); + builder.single_output("Color"); + builder.single_output("Fac"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc index f68f1747b21..5692bfe7770 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc @@ -61,13 +61,14 @@ class MagicFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"MagicFunction"}; - signature.single_input("Vector"); - signature.single_input("Scale"); - signature.single_input("Distortion"); - signature.single_output("Color"); - signature.single_output("Fac"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"MagicFunction", signature}; + builder.single_input("Vector"); + builder.single_input("Scale"); + builder.single_input("Distortion"); + builder.single_output("Color"); + builder.single_output("Fac"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc index e79b12b78b9..45b9d42e76c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc @@ -167,31 +167,32 @@ class MusgraveFunction : public fn::MultiFunction { static fn::MFSignature create_signature(const int dimensions, const int musgrave_type) { - fn::MFSignatureBuilder signature{"Musgrave"}; + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Musgrave", signature}; if (ELEM(dimensions, 2, 3, 4)) { - signature.single_input("Vector"); + builder.single_input("Vector"); } if (ELEM(dimensions, 1, 4)) { - signature.single_input("W"); + builder.single_input("W"); } - signature.single_input("Scale"); - signature.single_input("Detail"); - signature.single_input("Dimension"); - signature.single_input("Lacunarity"); + builder.single_input("Scale"); + builder.single_input("Detail"); + builder.single_input("Dimension"); + builder.single_input("Lacunarity"); if (ELEM(musgrave_type, SHD_MUSGRAVE_RIDGED_MULTIFRACTAL, SHD_MUSGRAVE_HYBRID_MULTIFRACTAL, SHD_MUSGRAVE_HETERO_TERRAIN)) { - signature.single_input("Offset"); + builder.single_input("Offset"); } if (ELEM(musgrave_type, SHD_MUSGRAVE_RIDGED_MULTIFRACTAL, SHD_MUSGRAVE_HYBRID_MULTIFRACTAL)) { - signature.single_input("Gain"); + builder.single_input("Gain"); } - signature.single_output("Fac"); + builder.single_output("Fac"); - return signature.build(); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc b/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc index d72e9c3c451..3a4a97d0a1a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc @@ -100,24 +100,25 @@ class NoiseFunction : public fn::MultiFunction { static fn::MFSignature create_signature(int dimensions) { - fn::MFSignatureBuilder signature{"Noise"}; + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"Noise", signature}; if (ELEM(dimensions, 2, 3, 4)) { - signature.single_input("Vector"); + builder.single_input("Vector"); } if (ELEM(dimensions, 1, 4)) { - signature.single_input("W"); + builder.single_input("W"); } - signature.single_input("Scale"); - signature.single_input("Detail"); - signature.single_input("Roughness"); - signature.single_input("Distortion"); + builder.single_input("Scale"); + builder.single_input("Detail"); + builder.single_input("Roughness"); + builder.single_input("Distortion"); - signature.single_output("Fac"); - signature.single_output("Color"); + builder.single_output("Fac"); + builder.single_output("Color"); - return signature.build(); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc index f07ef1b6c60..a02cb3c046a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc @@ -209,31 +209,32 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { static fn::MFSignature create_signature(int dimensions, int feature) { - fn::MFSignatureBuilder signature{"voronoi_minowski"}; + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"voronoi_minowski", signature}; if (ELEM(dimensions, 2, 3, 4)) { - signature.single_input("Vector"); + builder.single_input("Vector"); } if (ELEM(dimensions, 1, 4)) { - signature.single_input("W"); + builder.single_input("W"); } - signature.single_input("Scale"); + builder.single_input("Scale"); if (feature == SHD_VORONOI_SMOOTH_F1) { - signature.single_input("Smoothness"); + builder.single_input("Smoothness"); } - signature.single_input("Exponent"); - signature.single_input("Randomness"); - signature.single_output("Distance"); - signature.single_output("Color"); + builder.single_input("Exponent"); + builder.single_input("Randomness"); + builder.single_output("Distance"); + builder.single_output("Color"); if (dimensions != 1) { - signature.single_output("Position"); + builder.single_output("Position"); } if (ELEM(dimensions, 1, 4)) { - signature.single_output("W"); + builder.single_output("W"); } - return signature.build(); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override @@ -646,30 +647,31 @@ class VoronoiMetricFunction : public fn::MultiFunction { static fn::MFSignature create_signature(int dimensions, int feature) { - fn::MFSignatureBuilder signature{"voronoi_metric"}; + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"voronoi_metric", signature}; if (ELEM(dimensions, 2, 3, 4)) { - signature.single_input("Vector"); + builder.single_input("Vector"); } if (ELEM(dimensions, 1, 4)) { - signature.single_input("W"); + builder.single_input("W"); } - signature.single_input("Scale"); + builder.single_input("Scale"); if (feature == SHD_VORONOI_SMOOTH_F1) { - signature.single_input("Smoothness"); + builder.single_input("Smoothness"); } - signature.single_input("Randomness"); - signature.single_output("Distance"); - signature.single_output("Color"); + builder.single_input("Randomness"); + builder.single_output("Distance"); + builder.single_output("Color"); if (dimensions != 1) { - signature.single_output("Position"); + builder.single_output("Position"); } if (ELEM(dimensions, 1, 4)) { - signature.single_output("W"); + builder.single_output("W"); } - return signature.build(); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override @@ -1158,25 +1160,26 @@ class VoronoiEdgeFunction : public fn::MultiFunction { static fn::MFSignature create_signature(int dimensions, int feature) { - fn::MFSignatureBuilder signature{"voronoi_edge"}; + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"voronoi_edge", signature}; if (ELEM(dimensions, 2, 3, 4)) { - signature.single_input("Vector"); + builder.single_input("Vector"); } if (ELEM(dimensions, 1, 4)) { - signature.single_input("W"); + builder.single_input("W"); } - signature.single_input("Scale"); - signature.single_input("Randomness"); + builder.single_input("Scale"); + builder.single_input("Randomness"); if (feature == SHD_VORONOI_DISTANCE_TO_EDGE) { - signature.single_output("Distance"); + builder.single_output("Distance"); } if (feature == SHD_VORONOI_N_SPHERE_RADIUS) { - signature.single_output("Radius"); + builder.single_output("Radius"); } - return signature.build(); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc index f4effe28815..d2be2487489 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc @@ -100,17 +100,18 @@ class WaveFunction : public fn::MultiFunction { static fn::MFSignature create_signature() { - fn::MFSignatureBuilder signature{"MagicFunction"}; - signature.single_input("Vector"); - signature.single_input("Scale"); - signature.single_input("Distortion"); - signature.single_input("Detail"); - signature.single_input("Detail Scale"); - signature.single_input("Detail Roughness"); - signature.single_input("Phase Offset"); - signature.single_output("Color"); - signature.single_output("Fac"); - return signature.build(); + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"MagicFunction", signature}; + builder.single_input("Vector"); + builder.single_input("Scale"); + builder.single_input("Distortion"); + builder.single_input("Detail"); + builder.single_input("Detail Scale"); + builder.single_input("Detail Roughness"); + builder.single_input("Phase Offset"); + builder.single_output("Color"); + builder.single_output("Fac"); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc index 58787a9afa3..0a4ac73b277 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc @@ -82,19 +82,20 @@ class WhiteNoiseFunction : public fn::MultiFunction { static fn::MFSignature create_signature(int dimensions) { - fn::MFSignatureBuilder signature{"WhiteNoise"}; + fn::MFSignature signature; + fn::MFSignatureBuilder builder{"WhiteNoise", signature}; if (ELEM(dimensions, 2, 3, 4)) { - signature.single_input("Vector"); + builder.single_input("Vector"); } if (ELEM(dimensions, 1, 4)) { - signature.single_input("W"); + builder.single_input("W"); } - signature.single_output("Value"); - signature.single_output("Color"); + builder.single_output("Value"); + builder.single_output("Color"); - return signature.build(); + return signature; } void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override From a5b27f985881911c3174c3271b56b7c597d6b424 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 7 Jan 2023 16:51:26 +0100 Subject: [PATCH 0500/1522] Functions: simplify multi-function signature type * `depends_on_context` was not used for a long time already. * `param_data_indices` is not used since rB42b88c008861b6. * The remaining data is moved to a single `Vector` to avoid having to do two allocations when the size signature becomes larger than fits into the inline buffer. --- source/blender/functions/FN_multi_function.hh | 13 +++------ .../functions/FN_multi_function_params.hh | 22 +++++++-------- .../functions/FN_multi_function_signature.hh | 28 ++++++------------- .../intern/multi_function_builder.cc | 2 +- .../multi_function_procedure_executor.cc | 8 ++---- 5 files changed, 27 insertions(+), 46 deletions(-) diff --git a/source/blender/functions/FN_multi_function.hh b/source/blender/functions/FN_multi_function.hh index 7089f6895a7..53392e6acd2 100644 --- a/source/blender/functions/FN_multi_function.hh +++ b/source/blender/functions/FN_multi_function.hh @@ -67,22 +67,22 @@ class MultiFunction { int param_amount() const { - return signature_ref_->param_types.size(); + return signature_ref_->params.size(); } IndexRange param_indices() const { - return signature_ref_->param_types.index_range(); + return signature_ref_->params.index_range(); } MFParamType param_type(int param_index) const { - return signature_ref_->param_types[param_index]; + return signature_ref_->params[param_index].type; } StringRefNull param_name(int param_index) const { - return signature_ref_->param_names[param_index]; + return signature_ref_->params[param_index].name; } StringRefNull name() const @@ -92,11 +92,6 @@ class MultiFunction { virtual std::string debug_name() const; - bool depends_on_context() const - { - return signature_ref_->depends_on_context; - } - const MFSignature &signature() const { BLI_assert(signature_ref_ != nullptr); diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh index cfcc930c67b..fec75ac8159 100644 --- a/source/blender/functions/FN_multi_function_params.hh +++ b/source/blender/functions/FN_multi_function_params.hh @@ -40,7 +40,7 @@ class MFParamsBuilder { MFParamsBuilder(const MFSignature &signature, const IndexMask mask) : signature_(&signature), mask_(mask), min_array_size_(mask.min_array_size()) { - actual_params_.reserve(signature.param_types.size()); + actual_params_.reserve(signature.params.size()); } public: @@ -124,7 +124,7 @@ class MFParamsBuilder { { this->assert_current_param_name(expected_name); const int param_index = this->current_param_index(); - const MFParamType ¶m_type = signature_->param_types[param_index]; + const MFParamType ¶m_type = signature_->params[param_index].type; BLI_assert(param_type.category() == MFParamCategory::SingleOutput); const CPPType &type = param_type.data_type().single_type(); /* An empty span indicates that this is ignored. */ @@ -157,7 +157,7 @@ class MFParamsBuilder { GMutableSpan computed_array(int param_index) { - BLI_assert(ELEM(signature_->param_types[param_index].category(), + BLI_assert(ELEM(signature_->params[param_index].type.category(), MFParamCategory::SingleOutput, MFParamCategory::SingleMutable)); return *std::get_if(&actual_params_[param_index]); @@ -165,7 +165,7 @@ class MFParamsBuilder { GVectorArray &computed_vector_array(int param_index) { - BLI_assert(ELEM(signature_->param_types[param_index].category(), + BLI_assert(ELEM(signature_->params[param_index].type.category(), MFParamCategory::VectorOutput, MFParamCategory::VectorMutable)); return **std::get_if(&actual_params_[param_index]); @@ -184,11 +184,11 @@ class MFParamsBuilder { int param_index = this->current_param_index(); if (expected_name != "") { - StringRef actual_name = signature_->param_names[param_index]; + StringRef actual_name = signature_->params[param_index].name; BLI_assert(actual_name == expected_name); } - MFParamType expected_type = signature_->param_types[param_index]; + MFParamType expected_type = signature_->params[param_index].type; BLI_assert(expected_type == param_type); #endif } @@ -201,7 +201,7 @@ class MFParamsBuilder { return; } const int param_index = this->current_param_index(); - StringRef actual_name = signature_->param_names[param_index]; + StringRef actual_name = signature_->params[param_index].name; BLI_assert(actual_name == expected_name); #endif } @@ -325,9 +325,9 @@ class MFParams { { UNUSED_VARS_NDEBUG(param_index, name, param_type); #ifdef DEBUG - BLI_assert(builder_->signature_->param_types[param_index] == param_type); + BLI_assert(builder_->signature_->params[param_index].type == param_type); if (name.size() > 0) { - BLI_assert(builder_->signature_->param_names[param_index] == name); + BLI_assert(builder_->signature_->params[param_index].name == name); } #endif } @@ -336,9 +336,9 @@ class MFParams { { UNUSED_VARS_NDEBUG(param_index, name, category); #ifdef DEBUG - BLI_assert(builder_->signature_->param_types[param_index].category() == category); + BLI_assert(builder_->signature_->params[param_index].type.category() == category); if (name.size() > 0) { - BLI_assert(builder_->signature_->param_names[param_index] == name); + BLI_assert(builder_->signature_->params[param_index].name == name); } #endif } diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh index 44f2b84867d..4797afd6a83 100644 --- a/source/blender/functions/FN_multi_function_signature.hh +++ b/source/blender/functions/FN_multi_function_signature.hh @@ -16,6 +16,11 @@ namespace blender::fn { struct MFSignature { + struct ParamInfo { + MFParamType type; + const char *name; + }; + /** * The name should be statically allocated so that it lives longer than this signature. This is * used instead of an #std::string because of the overhead when many functions are created. @@ -24,10 +29,7 @@ struct MFSignature { * actually needed. */ const char *function_name; - Vector param_names; - Vector param_types; - Vector param_data_indices; - bool depends_on_context = false; + Vector params; }; class MFSignatureBuilder { @@ -61,8 +63,7 @@ class MFSignatureBuilder { } void input(const char *name, MFDataType data_type) { - signature_.param_names.append(name); - signature_.param_types.append(MFParamType(MFParamType::Input, data_type)); + signature_.params.append({MFParamType(MFParamType::Input, data_type), name}); } /* Output Parameter Types */ @@ -85,8 +86,7 @@ class MFSignatureBuilder { } void output(const char *name, MFDataType data_type) { - signature_.param_names.append(name); - signature_.param_types.append(MFParamType(MFParamType::Output, data_type)); + signature_.params.append({MFParamType(MFParamType::Output, data_type), name}); } /* Mutable Parameter Types */ @@ -109,8 +109,7 @@ class MFSignatureBuilder { } void mutable_(const char *name, MFDataType data_type) { - signature_.param_names.append(name); - signature_.param_types.append(MFParamType(MFParamType::Mutable, data_type)); + signature_.params.append({MFParamType(MFParamType::Mutable, data_type), name}); } void add(const char *name, const MFParamType ¶m_type) @@ -153,15 +152,6 @@ class MFSignatureBuilder { } BLI_assert_unreachable(); } - - /* Context */ - - /** This indicates that the function accesses the context. This disables optimizations that - * depend on the fact that the function always performers the same operation. */ - void depends_on_context() - { - signature_.depends_on_context = true; - } }; } // namespace blender::fn diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc index bda5ec19cea..30b734b881b 100644 --- a/source/blender/functions/intern/multi_function_builder.cc +++ b/source/blender/functions/intern/multi_function_builder.cc @@ -26,7 +26,7 @@ CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type, CustomMF_GenericConstant::~CustomMF_GenericConstant() { if (owns_value_) { - signature_.param_types[0].data_type().single_type().destruct(const_cast(value_)); + signature_.params[0].type.data_type().single_type().destruct(const_cast(value_)); MEM_freeN(const_cast(value_)); } } diff --git a/source/blender/functions/intern/multi_function_procedure_executor.cc b/source/blender/functions/intern/multi_function_procedure_executor.cc index 6c997e2e222..f5e25a5fb3c 100644 --- a/source/blender/functions/intern/multi_function_procedure_executor.cc +++ b/source/blender/functions/intern/multi_function_procedure_executor.cc @@ -974,14 +974,10 @@ class VariableStates { } }; -static bool evaluate_as_one(const MultiFunction &fn, - Span param_variable_states, +static bool evaluate_as_one(Span param_variable_states, const IndexMask &mask, const IndexMask &full_mask) { - if (fn.depends_on_context()) { - return false; - } if (mask.size() < full_mask.size()) { return false; } @@ -1059,7 +1055,7 @@ static void execute_call_instruction(const MFCallInstruction &instruction, /* If all inputs to the function are constant, it's enough to call the function only once instead * of for every index. */ - if (evaluate_as_one(fn, param_variable_states, mask, variable_states.full_mask())) { + if (evaluate_as_one(param_variable_states, mask, variable_states.full_mask())) { MFParamsBuilder params(fn, 1); fill_params__one(fn, mask, params, variable_states, param_variable_states); From eedcf1876a6651c38d8f4daa2e65d1fb81f77c5d Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 7 Jan 2023 17:32:28 +0100 Subject: [PATCH 0501/1522] Functions: introduce multi-function namespace This moves all multi-function related code in the `functions` module into a new `multi_function` namespace. This is similar to how there is a `lazy_function` namespace. The main benefit of this is that many types names that were prefixed with `MF` (for "multi function") can be simplified. There is also a common shorthand for the `multi_function` namespace: `mf`. This is also similar to lazy-functions where the shortened namespace is called `lf`. --- source/blender/blenkernel/BKE_attribute.hh | 4 +- source/blender/blenkernel/BKE_node.h | 3 - .../blenkernel/BKE_type_conversions.hh | 21 +- .../intern/geometry_component_curves.cc | 24 +- .../intern/geometry_component_mesh.cc | 4 +- .../blenkernel/intern/type_conversions.cc | 28 +- source/blender/functions/FN_field.hh | 18 +- source/blender/functions/FN_lazy_function.hh | 4 + source/blender/functions/FN_multi_function.hh | 39 +- .../functions/FN_multi_function_builder.hh | 94 ++--- .../functions/FN_multi_function_context.hh | 14 +- .../functions/FN_multi_function_data_type.hh | 36 +- .../functions/FN_multi_function_param_type.hh | 72 ++-- .../functions/FN_multi_function_params.hh | 78 ++-- .../functions/FN_multi_function_procedure.hh | 336 ++++++++-------- .../FN_multi_function_procedure_builder.hh | 137 ++++--- .../FN_multi_function_procedure_executor.hh | 14 +- ...N_multi_function_procedure_optimization.hh | 12 +- .../functions/FN_multi_function_signature.hh | 62 +-- source/blender/functions/intern/field.cc | 65 ++-- .../functions/intern/multi_function.cc | 28 +- .../intern/multi_function_builder.cc | 38 +- .../functions/intern/multi_function_params.cc | 4 +- .../intern/multi_function_procedure.cc | 368 +++++++++--------- .../multi_function_procedure_builder.cc | 72 ++-- .../multi_function_procedure_executor.cc | 172 ++++---- .../multi_function_procedure_optimization.cc | 39 +- .../blender/functions/tests/FN_field_test.cc | 22 +- .../tests/FN_multi_function_procedure_test.cc | 132 +++---- .../functions/tests/FN_multi_function_test.cc | 50 +-- .../tests/FN_multi_function_test_common.hh | 70 ++-- .../geometry/intern/resample_curves.cc | 8 +- source/blender/modifiers/intern/MOD_nodes.cc | 5 +- .../nodes/NOD_geometry_nodes_lazy_function.hh | 2 +- source/blender/nodes/NOD_math_functions.hh | 38 +- source/blender/nodes/NOD_multi_function.hh | 18 +- .../nodes/node_fn_align_euler_to_vector.cc | 12 +- .../function/nodes/node_fn_boolean_math.cc | 24 +- .../function/nodes/node_fn_combine_color.cc | 10 +- .../nodes/function/nodes/node_fn_compare.cc | 104 ++--- .../function/nodes/node_fn_float_to_int.cc | 14 +- .../function/nodes/node_fn_input_bool.cc | 2 +- .../function/nodes/node_fn_input_color.cc | 2 +- .../nodes/function/nodes/node_fn_input_int.cc | 2 +- .../nodes/node_fn_input_special_characters.cc | 12 +- .../function/nodes/node_fn_input_string.cc | 2 +- .../function/nodes/node_fn_input_vector.cc | 2 +- .../function/nodes/node_fn_random_value.cc | 16 +- .../function/nodes/node_fn_replace_string.cc | 10 +- .../function/nodes/node_fn_rotate_euler.cc | 16 +- .../function/nodes/node_fn_separate_color.cc | 36 +- .../function/nodes/node_fn_slice_string.cc | 2 +- .../function/nodes/node_fn_string_length.cc | 2 +- .../function/nodes/node_fn_value_to_string.cc | 2 +- .../geometry/nodes/node_geo_curve_sample.cc | 24 +- .../geometry/nodes/node_geo_extrude_mesh.cc | 4 +- .../geometry/nodes/node_geo_image_texture.cc | 12 +- .../geometry/nodes/node_geo_mesh_to_points.cc | 4 +- .../geometry/nodes/node_geo_proximity.cc | 12 +- .../nodes/geometry/nodes/node_geo_raycast.cc | 12 +- .../geometry/nodes/node_geo_sample_index.cc | 12 +- .../geometry/nodes/node_geo_sample_nearest.cc | 12 +- .../nodes/node_geo_sample_nearest_surface.cc | 12 +- .../nodes/node_geo_sample_uv_surface.cc | 24 +- .../nodes/geometry/nodes/node_geo_switch.cc | 2 +- .../intern/geometry_nodes_lazy_function.cc | 11 +- .../nodes/shader/nodes/node_shader_clamp.cc | 4 +- .../shader/nodes/node_shader_color_ramp.cc | 12 +- .../nodes/shader/nodes/node_shader_curves.cc | 36 +- .../shader/nodes/node_shader_map_range.cc | 32 +- .../nodes/shader/nodes/node_shader_math.cc | 20 +- .../nodes/shader/nodes/node_shader_mix.cc | 28 +- .../nodes/shader/nodes/node_shader_mix_rgb.cc | 12 +- .../shader/nodes/node_shader_sepcomb_rgb.cc | 14 +- .../shader/nodes/node_shader_sepcomb_xyz.cc | 16 +- .../shader/nodes/node_shader_tex_brick.cc | 12 +- .../shader/nodes/node_shader_tex_checker.cc | 12 +- .../shader/nodes/node_shader_tex_gradient.cc | 12 +- .../shader/nodes/node_shader_tex_magic.cc | 12 +- .../shader/nodes/node_shader_tex_musgrave.cc | 12 +- .../shader/nodes/node_shader_tex_noise.cc | 12 +- .../shader/nodes/node_shader_tex_voronoi.cc | 38 +- .../shader/nodes/node_shader_tex_wave.cc | 12 +- .../nodes/node_shader_tex_white_noise.cc | 12 +- .../nodes/shader/nodes/node_shader_value.cc | 2 +- .../shader/nodes/node_shader_vector_math.cc | 20 +- .../shader/nodes/node_shader_vector_rotate.cc | 24 +- 87 files changed, 1437 insertions(+), 1459 deletions(-) diff --git a/source/blender/blenkernel/BKE_attribute.hh b/source/blender/blenkernel/BKE_attribute.hh index 1eb352bfdda..0ff120328d3 100644 --- a/source/blender/blenkernel/BKE_attribute.hh +++ b/source/blender/blenkernel/BKE_attribute.hh @@ -17,7 +17,9 @@ struct Mesh; struct PointCloud; namespace blender::fn { +namespace multi_function { class MultiFunction; +} class GField; } // namespace blender::fn @@ -174,7 +176,7 @@ struct AttributeValidator { /** * Single input, single output function that corrects attribute values if necessary. */ - const fn::MultiFunction *function; + const fn::multi_function::MultiFunction *function; operator bool() const { diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 675328b15c4..47e198c9a12 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -107,9 +107,6 @@ class GeoNodeExecParams; class NodeDeclarationBuilder; class GatherLinkSearchOpParams; } // namespace nodes -namespace fn { -class MFDataType; -} // namespace fn namespace realtime_compositor { class Context; class NodeOperation; diff --git a/source/blender/blenkernel/BKE_type_conversions.hh b/source/blender/blenkernel/BKE_type_conversions.hh index 1cca172e188..172cd414ab3 100644 --- a/source/blender/blenkernel/BKE_type_conversions.hh +++ b/source/blender/blenkernel/BKE_type_conversions.hh @@ -8,19 +8,19 @@ namespace blender::bke { struct ConversionFunctions { - const fn::MultiFunction *multi_function; + const mf::MultiFunction *multi_function; void (*convert_single_to_initialized)(const void *src, void *dst); void (*convert_single_to_uninitialized)(const void *src, void *dst); }; class DataTypeConversions { private: - Map, ConversionFunctions> conversions_; + Map, ConversionFunctions> conversions_; public: - void add(fn::MFDataType from_type, - fn::MFDataType to_type, - const fn::MultiFunction &fn, + void add(mf::DataType from_type, + mf::DataType to_type, + const mf::MultiFunction &fn, void (*convert_single_to_initialized)(const void *src, void *dst), void (*convert_single_to_uninitialized)(const void *src, void *dst)) { @@ -28,19 +28,18 @@ class DataTypeConversions { {&fn, convert_single_to_initialized, convert_single_to_uninitialized}); } - const ConversionFunctions *get_conversion_functions(fn::MFDataType from, fn::MFDataType to) const + const ConversionFunctions *get_conversion_functions(mf::DataType from, mf::DataType to) const { return conversions_.lookup_ptr({from, to}); } const ConversionFunctions *get_conversion_functions(const CPPType &from, const CPPType &to) const { - return this->get_conversion_functions(fn::MFDataType::ForSingle(from), - fn::MFDataType::ForSingle(to)); + return this->get_conversion_functions(mf::DataType::ForSingle(from), + mf::DataType::ForSingle(to)); } - const fn::MultiFunction *get_conversion_multi_function(fn::MFDataType from, - fn::MFDataType to) const + const mf::MultiFunction *get_conversion_multi_function(mf::DataType from, mf::DataType to) const { const ConversionFunctions *functions = this->get_conversion_functions(from, to); return functions ? functions->multi_function : nullptr; @@ -49,7 +48,7 @@ class DataTypeConversions { bool is_convertible(const CPPType &from_type, const CPPType &to_type) const { return conversions_.contains( - {fn::MFDataType::ForSingle(from_type), fn::MFDataType::ForSingle(to_type)}); + {mf::DataType::ForSingle(from_type), mf::DataType::ForSingle(to_type)}); } void convert_to_uninitialized(const CPPType &from_type, diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index d1d0af2b725..075a6838704 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -440,12 +440,12 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() make_array_write_attribute, tag_component_positions_changed); - static auto handle_type_clamp = fn::build_mf::SI1_SO( + static auto handle_type_clamp = mf::build::SI1_SO( "Handle Type Validate", [](int8_t value) { return std::clamp(value, BEZIER_HANDLE_FREE, BEZIER_HANDLE_ALIGN); }, - fn::build_mf::exec_presets::AllSpanOrSingle()); + mf::build::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider handle_type_right("handle_type_right", ATTR_DOMAIN_POINT, CD_PROP_INT8, @@ -484,10 +484,10 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() make_array_write_attribute, tag_component_positions_changed); - static const auto nurbs_order_clamp = fn::build_mf::SI1_SO( + static const auto nurbs_order_clamp = mf::build::SI1_SO( "NURBS Order Validate", [](int8_t value) { return std::max(value, 0); }, - fn::build_mf::exec_presets::AllSpanOrSingle()); + mf::build::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider nurbs_order("nurbs_order", ATTR_DOMAIN_CURVE, CD_PROP_INT8, @@ -501,12 +501,12 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() tag_component_topology_changed, AttributeValidator{&nurbs_order_clamp}); - static const auto normal_mode_clamp = fn::build_mf::SI1_SO( + static const auto normal_mode_clamp = mf::build::SI1_SO( "Normal Mode Validate", [](int8_t value) { return std::clamp(value, NORMAL_MODE_MINIMUM_TWIST, NORMAL_MODE_Z_UP); }, - fn::build_mf::exec_presets::AllSpanOrSingle()); + mf::build::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider normal_mode("normal_mode", ATTR_DOMAIN_CURVE, CD_PROP_INT8, @@ -520,12 +520,12 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() tag_component_normals_changed, AttributeValidator{&normal_mode_clamp}); - static const auto knots_mode_clamp = fn::build_mf::SI1_SO( + static const auto knots_mode_clamp = mf::build::SI1_SO( "Knots Mode Validate", [](int8_t value) { return std::clamp(value, NURBS_KNOT_MODE_NORMAL, NURBS_KNOT_MODE_ENDPOINT_BEZIER); }, - fn::build_mf::exec_presets::AllSpanOrSingle()); + mf::build::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider nurbs_knots_mode("knots_mode", ATTR_DOMAIN_CURVE, CD_PROP_INT8, @@ -539,12 +539,12 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() tag_component_topology_changed, AttributeValidator{&knots_mode_clamp}); - static const auto curve_type_clamp = fn::build_mf::SI1_SO( + static const auto curve_type_clamp = mf::build::SI1_SO( "Curve Type Validate", [](int8_t value) { return std::clamp(value, CURVE_TYPE_CATMULL_ROM, CURVE_TYPES_NUM); }, - fn::build_mf::exec_presets::AllSpanOrSingle()); + mf::build::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider curve_type("curve_type", ATTR_DOMAIN_CURVE, CD_PROP_INT8, @@ -558,10 +558,10 @@ static ComponentAttributeProviders create_attribute_providers_for_curve() tag_component_curve_types_changed, AttributeValidator{&curve_type_clamp}); - static const auto resolution_clamp = fn::build_mf::SI1_SO( + static const auto resolution_clamp = mf::build::SI1_SO( "Resolution Validate", [](int value) { return std::max(value, 1); }, - fn::build_mf::exec_presets::AllSpanOrSingle()); + mf::build::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider resolution("resolution", ATTR_DOMAIN_CURVE, CD_PROP_INT32, diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index b18bdc62d82..f587f2ced47 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -1264,13 +1264,13 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() make_array_write_attribute, nullptr); - static const auto material_index_clamp = fn::build_mf::SI1_SO( + static const auto material_index_clamp = mf::build::SI1_SO( "Material Index Validate", [](int value) { /* Use #short for the maximum since many areas still use that type for indices. */ return std::clamp(value, 0, std::numeric_limits::max()); }, - fn::build_mf::exec_presets::AllSpanOrSingle()); + mf::build::exec_presets::AllSpanOrSingle()); static BuiltinCustomDataLayerProvider material_index("material_index", ATTR_DOMAIN_FACE, CD_PROP_INT32, diff --git a/source/blender/blenkernel/intern/type_conversions.cc b/source/blender/blenkernel/intern/type_conversions.cc index 5aca83d415d..f1dea155225 100644 --- a/source/blender/blenkernel/intern/type_conversions.cc +++ b/source/blender/blenkernel/intern/type_conversions.cc @@ -11,7 +11,7 @@ namespace blender::bke { -using fn::MFDataType; +using mf::DataType; template static void add_implicit_conversion(DataTypeConversions &conversions) @@ -20,20 +20,20 @@ static void add_implicit_conversion(DataTypeConversions &conversions) static const CPPType &to_type = CPPType::get(); static const std::string conversion_name = from_type.name() + " to " + to_type.name(); - static auto multi_function = fn::build_mf::SI1_SO( + static auto multi_function = mf::build::SI1_SO( conversion_name.c_str(), /* Use lambda instead of passing #ConversionF directly, because otherwise the compiler won't * inline the function. */ [](const From &a) { return ConversionF(a); }, - fn::build_mf::exec_presets::AllSpanOrSingle()); + mf::build::exec_presets::AllSpanOrSingle()); static auto convert_single_to_initialized = [](const void *src, void *dst) { *(To *)dst = ConversionF(*(const From *)src); }; static auto convert_single_to_uninitialized = [](const void *src, void *dst) { new (dst) To(ConversionF(*(const From *)src)); }; - conversions.add(fn::MFDataType::ForSingle(), - fn::MFDataType::ForSingle(), + conversions.add(mf::DataType::ForSingle(), + mf::DataType::ForSingle(), multi_function, convert_single_to_initialized, convert_single_to_uninitialized); @@ -361,26 +361,26 @@ void DataTypeConversions::convert_to_uninitialized(const CPPType &from_type, } const ConversionFunctions *functions = this->get_conversion_functions( - MFDataType::ForSingle(from_type), MFDataType::ForSingle(to_type)); + DataType::ForSingle(from_type), DataType::ForSingle(to_type)); BLI_assert(functions != nullptr); functions->convert_single_to_uninitialized(from_value, to_value); } static void call_convert_to_uninitialized_fn(const GVArray &from, - const fn::MultiFunction &fn, + const mf::MultiFunction &fn, const IndexMask mask, GMutableSpan to) { - fn::MFParamsBuilder params{fn, mask.min_array_size()}; + mf::ParamsBuilder params{fn, mask.min_array_size()}; params.add_readonly_single_input(from); params.add_uninitialized_single_output(to); - fn::MFContextBuilder context; + mf::ContextBuilder context; fn.call_auto(mask, params, context); } static void call_convert_to_uninitialized_fn(const GVArray &from, - const fn::MultiFunction &fn, + const mf::MultiFunction &fn, GMutableSpan to) { call_convert_to_uninitialized_fn(from, fn, IndexMask(from.size()), to); @@ -394,8 +394,8 @@ void DataTypeConversions::convert_to_initialized_n(GSpan from_span, GMutableSpan BLI_assert(from_span.size() == to_span.size()); BLI_assert(this->is_convertible(from_type, to_type)); - const fn::MultiFunction *fn = this->get_conversion_multi_function( - MFDataType::ForSingle(from_type), MFDataType::ForSingle(to_type)); + const mf::MultiFunction *fn = this->get_conversion_multi_function(DataType::ForSingle(from_type), + DataType::ForSingle(to_type)); to_type.destruct_n(to_span.data(), to_span.size()); call_convert_to_uninitialized_fn(GVArray::ForSpan(from_span), *fn, to_span); @@ -541,8 +541,8 @@ fn::GField DataTypeConversions::try_convert(fn::GField field, const CPPType &to_ if (!this->is_convertible(from_type, to_type)) { return {}; } - const fn::MultiFunction &fn = *this->get_conversion_multi_function( - fn::MFDataType::ForSingle(from_type), fn::MFDataType::ForSingle(to_type)); + const mf::MultiFunction &fn = *this->get_conversion_multi_function( + mf::DataType::ForSingle(from_type), mf::DataType::ForSingle(to_type)); return {std::make_shared(fn, Vector{std::move(field)})}; } diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh index 7f940294113..993558b3a18 100644 --- a/source/blender/functions/FN_field.hh +++ b/source/blender/functions/FN_field.hh @@ -212,28 +212,28 @@ class FieldOperation : public FieldNode { * The multi-function used by this node. It is optionally owned. * Multi-functions with mutable or vector parameters are not supported currently. */ - std::shared_ptr owned_function_; - const MultiFunction *function_; + std::shared_ptr owned_function_; + const mf::MultiFunction *function_; /** Inputs to the operation. */ blender::Vector inputs_; public: - FieldOperation(std::shared_ptr function, Vector inputs = {}); - FieldOperation(const MultiFunction &function, Vector inputs = {}); + FieldOperation(std::shared_ptr function, Vector inputs = {}); + FieldOperation(const mf::MultiFunction &function, Vector inputs = {}); ~FieldOperation(); Span inputs() const; - const MultiFunction &multi_function() const; + const mf::MultiFunction &multi_function() const; const CPPType &output_cpp_type(int output_index) const override; - static std::shared_ptr Create(std::shared_ptr function, + static std::shared_ptr Create(std::shared_ptr function, Vector inputs = {}) { return std::make_shared(FieldOperation(std::move(function), inputs)); } - static std::shared_ptr Create(const MultiFunction &function, + static std::shared_ptr Create(const mf::MultiFunction &function, Vector inputs = {}) { return std::make_shared(FieldOperation(function, inputs)); @@ -640,7 +640,7 @@ inline Span FieldOperation::inputs() const return inputs_; } -inline const MultiFunction &FieldOperation::multi_function() const +inline const mf::MultiFunction &FieldOperation::multi_function() const { return *function_; } @@ -649,7 +649,7 @@ inline const CPPType &FieldOperation::output_cpp_type(int output_index) const { int output_counter = 0; for (const int param_index : function_->param_indices()) { - MFParamType param_type = function_->param_type(param_index); + mf::ParamType param_type = function_->param_type(param_index); if (param_type.is_output()) { if (output_counter == output_index) { return param_type.data_type().single_type(); diff --git a/source/blender/functions/FN_lazy_function.hh b/source/blender/functions/FN_lazy_function.hh index bc85c155c2e..5379e5f8506 100644 --- a/source/blender/functions/FN_lazy_function.hh +++ b/source/blender/functions/FN_lazy_function.hh @@ -470,3 +470,7 @@ inline void Params::assert_valid_thread() const /** \} */ } // namespace blender::fn::lazy_function + +namespace blender { +namespace lf = fn::lazy_function; +} diff --git a/source/blender/functions/FN_multi_function.hh b/source/blender/functions/FN_multi_function.hh index 53392e6acd2..7a281809e4e 100644 --- a/source/blender/functions/FN_multi_function.hh +++ b/source/blender/functions/FN_multi_function.hh @@ -22,7 +22,7 @@ * arrays are not owned by MFParams. * - `IndexMask`: An array of indices indicating which indices in the provided arrays should be * touched/processed. - * - `MFContext`: Further information for the called function. + * - `Context`: Further information for the called function. * * A new multi-function is generally implemented as follows: * 1. Create a new subclass of MultiFunction. @@ -35,11 +35,11 @@ #include "FN_multi_function_context.hh" #include "FN_multi_function_params.hh" -namespace blender::fn { +namespace blender::fn::multi_function { class MultiFunction { private: - const MFSignature *signature_ref_ = nullptr; + const Signature *signature_ref_ = nullptr; public: virtual ~MultiFunction() @@ -52,8 +52,8 @@ class MultiFunction { * - Automatic index mask offsetting to avoid large temporary intermediate arrays that are mostly * unused. */ - void call_auto(IndexMask mask, MFParams params, MFContext context) const; - virtual void call(IndexMask mask, MFParams params, MFContext context) const = 0; + void call_auto(IndexMask mask, MFParams params, Context context) const; + virtual void call(IndexMask mask, MFParams params, Context context) const = 0; virtual uint64_t hash() const { @@ -75,7 +75,7 @@ class MultiFunction { return signature_ref_->params.index_range(); } - MFParamType param_type(int param_index) const + ParamType param_type(int param_index) const { return signature_ref_->params[param_index].type; } @@ -92,7 +92,7 @@ class MultiFunction { virtual std::string debug_name() const; - const MFSignature &signature() const + const Signature &signature() const { BLI_assert(signature_ref_ != nullptr); return *signature_ref_; @@ -128,7 +128,7 @@ class MultiFunction { * child classes. No copy of the signature is made, so the caller has to make sure that the * signature lives as long as the multi function. It is ok to embed the signature into the child * class. */ - void set_signature(const MFSignature *signature) + void set_signature(const Signature *signature) { /* Take a pointer as argument, so that it is more obvious that no copy is created. */ BLI_assert(signature != nullptr); @@ -138,25 +138,18 @@ class MultiFunction { virtual ExecutionHints get_execution_hints() const; }; -inline MFParamsBuilder::MFParamsBuilder(const MultiFunction &fn, int64_t mask_size) - : MFParamsBuilder(fn.signature(), IndexMask(mask_size)) +inline ParamsBuilder::ParamsBuilder(const MultiFunction &fn, int64_t mask_size) + : ParamsBuilder(fn.signature(), IndexMask(mask_size)) { } -inline MFParamsBuilder::MFParamsBuilder(const MultiFunction &fn, const IndexMask *mask) - : MFParamsBuilder(fn.signature(), *mask) +inline ParamsBuilder::ParamsBuilder(const MultiFunction &fn, const IndexMask *mask) + : ParamsBuilder(fn.signature(), *mask) { } -namespace multi_function_types { -using fn::MFContext; -using fn::MFContextBuilder; -using fn::MFDataType; -using fn::MFParamCategory; -using fn::MFParams; -using fn::MFParamsBuilder; -using fn::MFParamType; -using fn::MultiFunction; -} // namespace multi_function_types +} // namespace blender::fn::multi_function -} // namespace blender::fn +namespace blender { +namespace mf = fn::multi_function; +} diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index f9f0890f4fb..997f52f4066 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -10,7 +10,7 @@ #include "FN_multi_function.hh" -namespace blender::fn::build_mf { +namespace blender::fn::multi_function::build { /** * These presets determine what code is generated for a #CustomMF. Different presets make different @@ -66,13 +66,13 @@ struct AllSpanOrSingle { return std::make_tuple(IndexMaskDevirtualizer{mask}, [&]() { typedef ParamTags ParamTag; typedef typename ParamTag::base_type T; - if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + if constexpr (ParamTag::category == ParamCategory::SingleInput) { const GVArrayImpl &varray_impl = *std::get(loaded_params); return GVArrayDevirtualizer{varray_impl}; } else if constexpr (ELEM(ParamTag::category, - MFParamCategory::SingleOutput, - MFParamCategory::SingleMutable)) { + ParamCategory::SingleOutput, + ParamCategory::SingleMutable)) { T *ptr = std::get(loaded_params); return BasicDevirtualizer{ptr}; } @@ -99,14 +99,14 @@ template struct SomeSpanOrSingle { typedef ParamTags ParamTag; typedef typename ParamTag::base_type T; - if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + if constexpr (ParamTag::category == ParamCategory::SingleInput) { constexpr bool UseSpan = ValueSequence::template contains(); const GVArrayImpl &varray_impl = *std::get(loaded_params); return GVArrayDevirtualizer{varray_impl}; } else if constexpr (ELEM(ParamTag::category, - MFParamCategory::SingleOutput, - MFParamCategory::SingleMutable)) { + ParamCategory::SingleOutput, + ParamCategory::SingleMutable)) { T *ptr = std::get(loaded_params); return BasicDevirtualizer{ptr}; } @@ -135,16 +135,16 @@ void execute_array(TypeSequence /*param_tags*/, for (const int64_t i : mask) { element_fn([&]() -> decltype(auto) { using ParamTag = typename TypeSequence::template at_index; - if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + if constexpr (ParamTag::category == ParamCategory::SingleInput) { /* For inputs, pass the value (or a reference to it) to the function. */ return args[i]; } - else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { + else if constexpr (ParamTag::category == ParamCategory::SingleOutput) { /* For outputs, pass a pointer to the function. This is done instead of passing a * reference, because the pointer points to uninitialized memory. */ return args + i; } - else if constexpr (ParamTag::category == MFParamCategory::SingleMutable) { + else if constexpr (ParamTag::category == ParamCategory::SingleMutable) { /* For mutables, pass a mutable reference to the function. */ return args[i]; } @@ -180,13 +180,13 @@ void execute_materialized_impl(TypeSequence /*param_tags*/, const int64_t out_i = out_mask[i]; element_fn([&]() -> decltype(auto) { using ParamTag = ParamTags; - if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + if constexpr (ParamTag::category == ParamCategory::SingleInput) { return chunks[in_i]; } - else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { + else if constexpr (ParamTag::category == ParamCategory::SingleOutput) { return chunks + out_i; } - else if constexpr (ParamTag::category == MFParamCategory::SingleMutable) { + else if constexpr (ParamTag::category == ParamCategory::SingleMutable) { return chunks[out_i]; } }()...); @@ -230,7 +230,7 @@ void execute_materialized(TypeSequence /* param_tags */, typedef ParamTags ParamTag; typedef typename ParamTag::base_type T; [[maybe_unused]] MaterializeArgInfo &arg_info = std::get(args_info); - if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + if constexpr (ParamTag::category == ParamCategory::SingleInput) { const GVArrayImpl &varray_impl = *std::get(loaded_params); const CommonVArrayInfo common_info = varray_impl.common_info(); if (common_info.type == CommonVArrayInfo::Type::Single) { @@ -269,7 +269,7 @@ void execute_materialized(TypeSequence /* param_tags */, using ParamTag = ParamTags; using T = typename ParamTag::base_type; [[maybe_unused]] MaterializeArgInfo &arg_info = std::get(args_info); - if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + if constexpr (ParamTag::category == ParamCategory::SingleInput) { if (arg_info.mode == MaterializeArgMode::Single) { /* The single value has been filled into a buffer already reused for every chunk. */ return Span(std::get(buffers)); @@ -296,8 +296,8 @@ void execute_materialized(TypeSequence /* param_tags */, } } else if constexpr (ELEM(ParamTag::category, - MFParamCategory::SingleOutput, - MFParamCategory::SingleMutable)) { + ParamCategory::SingleOutput, + ParamCategory::SingleMutable)) { /* For outputs, just pass a pointer. This is important so that `__restrict` works. */ return std::get(loaded_params); } @@ -310,7 +310,7 @@ void execute_materialized(TypeSequence /* param_tags */, typedef ParamTags ParamTag; typedef typename ParamTag::base_type T; [[maybe_unused]] MaterializeArgInfo &arg_info = std::get(args_info); - if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + if constexpr (ParamTag::category == ParamCategory::SingleInput) { if (arg_info.mode == MaterializeArgMode::Materialized) { T *in_chunk = std::get(buffers_owner).ptr(); destruct_n(in_chunk, chunk_size); @@ -327,7 +327,7 @@ void execute_materialized(TypeSequence /* param_tags */, typedef ParamTags ParamTag; typedef typename ParamTag::base_type T; [[maybe_unused]] MaterializeArgInfo &arg_info = std::get(args_info); - if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + if constexpr (ParamTag::category == ParamCategory::SingleInput) { if (arg_info.mode == MaterializeArgMode::Single) { MutableSpan in_chunk = std::get(buffers); destruct_n(in_chunk.data(), in_chunk.size()); @@ -353,13 +353,13 @@ inline void execute_element_fn_as_multi_function(const ElementFn element_fn, typedef ParamTags ParamTag; typedef typename ParamTag::base_type T; - if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + if constexpr (ParamTag::category == ParamCategory::SingleInput) { return params.readonly_single_input(I).get_implementation(); } - else if constexpr (ParamTag::category == MFParamCategory::SingleOutput) { + else if constexpr (ParamTag::category == ParamCategory::SingleOutput) { return static_cast(params.uninitialized_single_output(I).data()); } - else if constexpr (ParamTag::category == MFParamCategory::SingleMutable) { + else if constexpr (ParamTag::category == ParamCategory::SingleMutable) { return static_cast(params.single_mutable(I).data()); } }()...); @@ -397,13 +397,13 @@ inline void execute_element_fn_as_multi_function(const ElementFn element_fn, /* Use `typedef` instead of `using` to work around a compiler bug. */ typedef ParamTags ParamTag; typedef typename ParamTag::base_type T; - if constexpr (ParamTag::category == MFParamCategory::SingleInput) { + if constexpr (ParamTag::category == ParamCategory::SingleInput) { const GVArrayImpl &varray_impl = *std::get(loaded_params); return GVArray(&varray_impl).typed(); } else if constexpr (ELEM(ParamTag::category, - MFParamCategory::SingleOutput, - MFParamCategory::SingleMutable)) { + ParamCategory::SingleOutput, + ParamCategory::SingleMutable)) { T *ptr = std::get(loaded_params); return ptr; } @@ -438,20 +438,20 @@ inline auto build_multi_function_call_from_element_fn(const ElementFn element_fn */ template class CustomMF : public MultiFunction { private: - MFSignature signature_; + Signature signature_; CallFn call_fn_; public: CustomMF(const char *name, CallFn call_fn, TypeSequence /*param_tags*/) : call_fn_(std::move(call_fn)) { - MFSignatureBuilder builder{name, signature_}; + SignatureBuilder builder{name, signature_}; /* Loop over all parameter types and add an entry for each in the signature. */ ([&] { builder.add(ParamTags(), ""); }(), ...); this->set_signature(&signature_); } - void call(IndexMask mask, MFParams params, MFContext /*context*/) const override + void call(IndexMask mask, MFParams params, Context /*context*/) const override { call_fn_(mask, params); } @@ -463,8 +463,8 @@ inline auto build_multi_function_with_n_inputs_one_output(const char *name, const ExecPreset exec_preset, TypeSequence /*in_types*/) { - constexpr auto param_tags = TypeSequence..., - MFParamTag>(); + constexpr auto param_tags = TypeSequence..., + MFParamTag>(); auto call_fn = build_multi_function_call_from_element_fn( [element_fn](const In &...in, Out *out) { new (out) Out(element_fn(in...)); }, exec_preset, @@ -573,15 +573,15 @@ inline auto SM(const char *name, const ElementFn element_fn, const ExecPreset exec_preset = exec_presets::AllSpanOrSingle()) { - constexpr auto param_tags = TypeSequence>(); + constexpr auto param_tags = TypeSequence>(); auto call_fn = detail::build_multi_function_call_from_element_fn( element_fn, exec_preset, param_tags); return detail::CustomMF(name, call_fn, param_tags); } -} // namespace blender::fn::build_mf +} // namespace blender::fn::multi_function::build -namespace blender::fn { +namespace blender::fn::multi_function { /** * A multi-function that outputs the same value every time. The value is not owned by an instance @@ -592,7 +592,7 @@ class CustomMF_GenericConstant : public MultiFunction { private: const CPPType &type_; const void *value_; - MFSignature signature_; + Signature signature_; bool owns_value_; template friend class CustomMF_Constant; @@ -600,7 +600,7 @@ class CustomMF_GenericConstant : public MultiFunction { public: CustomMF_GenericConstant(const CPPType &type, const void *value, bool make_value_copy); ~CustomMF_GenericConstant(); - void call(IndexMask mask, MFParams params, MFContext context) const override; + void call(IndexMask mask, MFParams params, Context context) const override; uint64_t hash() const override; bool equals(const MultiFunction &other) const override; }; @@ -612,11 +612,11 @@ class CustomMF_GenericConstant : public MultiFunction { class CustomMF_GenericConstantArray : public MultiFunction { private: GSpan array_; - MFSignature signature_; + Signature signature_; public: CustomMF_GenericConstantArray(GSpan array); - void call(IndexMask mask, MFParams params, MFContext context) const override; + void call(IndexMask mask, MFParams params, Context context) const override; }; /** @@ -625,17 +625,17 @@ class CustomMF_GenericConstantArray : public MultiFunction { template class CustomMF_Constant : public MultiFunction { private: T value_; - MFSignature signature_; + Signature signature_; public: template CustomMF_Constant(U &&value) : value_(std::forward(value)) { - MFSignatureBuilder builder{"Constant", signature_}; + SignatureBuilder builder{"Constant", signature_}; builder.single_output("Value"); this->set_signature(&signature_); } - void call(IndexMask mask, MFParams params, MFContext /*context*/) const override + void call(IndexMask mask, MFParams params, Context /*context*/) const override { MutableSpan output = params.uninitialized_single_output(0); mask.to_best_mask_type([&](const auto &mask) { @@ -671,20 +671,20 @@ template class CustomMF_Constant : public MultiFunction { class CustomMF_DefaultOutput : public MultiFunction { private: int output_amount_; - MFSignature signature_; + Signature signature_; public: - CustomMF_DefaultOutput(Span input_types, Span output_types); - void call(IndexMask mask, MFParams params, MFContext context) const override; + CustomMF_DefaultOutput(Span input_types, Span output_types); + void call(IndexMask mask, MFParams params, Context context) const override; }; class CustomMF_GenericCopy : public MultiFunction { private: - MFSignature signature_; + Signature signature_; public: - CustomMF_GenericCopy(MFDataType data_type); - void call(IndexMask mask, MFParams params, MFContext context) const override; + CustomMF_GenericCopy(DataType data_type); + void call(IndexMask mask, MFParams params, Context context) const override; }; -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/FN_multi_function_context.hh b/source/blender/functions/FN_multi_function_context.hh index 0ffd58dfca9..33817200edf 100644 --- a/source/blender/functions/FN_multi_function_context.hh +++ b/source/blender/functions/FN_multi_function_context.hh @@ -5,7 +5,7 @@ /** \file * \ingroup fn * - * An #MFContext is passed along with every call to a multi-function. Right now it does nothing, + * An #Context is passed along with every call to a multi-function. Right now it does nothing, * but it can be used for the following purposes: * - Pass debug information up and down the function call stack. * - Pass reusable memory buffers to sub-functions to increase performance. @@ -16,18 +16,18 @@ #include "BLI_map.hh" -namespace blender::fn { +namespace blender::fn::multi_function { -class MFContext; +class Context; -class MFContextBuilder { +class ContextBuilder { }; -class MFContext { +class Context { public: - MFContext(MFContextBuilder & /*builder*/) + Context(ContextBuilder & /*builder*/) { } }; -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/FN_multi_function_data_type.hh b/source/blender/functions/FN_multi_function_data_type.hh index d63e0faaca5..d0b586c88ab 100644 --- a/source/blender/functions/FN_multi_function_data_type.hh +++ b/source/blender/functions/FN_multi_function_data_type.hh @@ -5,16 +5,16 @@ /** \file * \ingroup fn * - * A MFDataType describes what type of data a multi-function gets as input, outputs or mutates. + * A DataType describes what type of data a multi-function gets as input, outputs or mutates. * Currently, only individual elements or vectors of elements are supported. Adding more data types * is possible when necessary. */ #include "BLI_cpp_type.hh" -namespace blender::fn { +namespace blender::fn::multi_function { -class MFDataType { +class DataType { public: enum Category { Single, @@ -25,31 +25,31 @@ class MFDataType { Category category_; const CPPType *type_; - MFDataType(Category category, const CPPType &type) : category_(category), type_(&type) + DataType(Category category, const CPPType &type) : category_(category), type_(&type) { } public: - MFDataType() = default; + DataType() = default; - static MFDataType ForSingle(const CPPType &type) + static DataType ForSingle(const CPPType &type) { - return MFDataType(Single, type); + return DataType(Single, type); } - static MFDataType ForVector(const CPPType &type) + static DataType ForVector(const CPPType &type) { - return MFDataType(Vector, type); + return DataType(Vector, type); } - template static MFDataType ForSingle() + template static DataType ForSingle() { - return MFDataType::ForSingle(CPPType::get()); + return DataType::ForSingle(CPPType::get()); } - template static MFDataType ForVector() + template static DataType ForVector() { - return MFDataType::ForVector(CPPType::get()); + return DataType::ForVector(CPPType::get()); } bool is_single() const @@ -79,8 +79,8 @@ class MFDataType { return *type_; } - friend bool operator==(const MFDataType &a, const MFDataType &b); - friend bool operator!=(const MFDataType &a, const MFDataType &b); + friend bool operator==(const DataType &a, const DataType &b); + friend bool operator!=(const DataType &a, const DataType &b); std::string to_string() const { @@ -100,14 +100,14 @@ class MFDataType { } }; -inline bool operator==(const MFDataType &a, const MFDataType &b) +inline bool operator==(const DataType &a, const DataType &b) { return a.category_ == b.category_ && a.type_ == b.type_; } -inline bool operator!=(const MFDataType &a, const MFDataType &b) +inline bool operator!=(const DataType &a, const DataType &b) { return !(a == b); } -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/FN_multi_function_param_type.hh b/source/blender/functions/FN_multi_function_param_type.hh index c7339424f8d..a80e7f7ebd9 100644 --- a/source/blender/functions/FN_multi_function_param_type.hh +++ b/source/blender/functions/FN_multi_function_param_type.hh @@ -14,15 +14,15 @@ * - Mutable: A mutable parameter can be considered to be an input and output. The caller has to * initialize the data, but the function is allowed to modify it. * - * Furthermore, every parameter has a MFDataType that describes what kind of data is being passed + * Furthermore, every parameter has a DataType that describes what kind of data is being passed * around. */ #include "FN_multi_function_data_type.hh" -namespace blender::fn { +namespace blender::fn::multi_function { -enum class MFParamCategory { +enum class ParamCategory { SingleInput, VectorInput, SingleOutput, @@ -31,12 +31,12 @@ enum class MFParamCategory { VectorMutable, }; -template struct MFParamTag { - static constexpr MFParamCategory category = Category; +template struct MFParamTag { + static constexpr ParamCategory category = Category; using base_type = T; }; -class MFParamType { +class ParamType { public: enum InterfaceType { Input, @@ -46,45 +46,45 @@ class MFParamType { private: InterfaceType interface_type_; - MFDataType data_type_; + DataType data_type_; public: - MFParamType(InterfaceType interface_type, MFDataType data_type) + ParamType(InterfaceType interface_type, DataType data_type) : interface_type_(interface_type), data_type_(data_type) { } - static MFParamType ForSingleInput(const CPPType &type) + static ParamType ForSingleInput(const CPPType &type) { - return MFParamType(InterfaceType::Input, MFDataType::ForSingle(type)); + return ParamType(InterfaceType::Input, DataType::ForSingle(type)); } - static MFParamType ForVectorInput(const CPPType &base_type) + static ParamType ForVectorInput(const CPPType &base_type) { - return MFParamType(InterfaceType::Input, MFDataType::ForVector(base_type)); + return ParamType(InterfaceType::Input, DataType::ForVector(base_type)); } - static MFParamType ForSingleOutput(const CPPType &type) + static ParamType ForSingleOutput(const CPPType &type) { - return MFParamType(InterfaceType::Output, MFDataType::ForSingle(type)); + return ParamType(InterfaceType::Output, DataType::ForSingle(type)); } - static MFParamType ForVectorOutput(const CPPType &base_type) + static ParamType ForVectorOutput(const CPPType &base_type) { - return MFParamType(InterfaceType::Output, MFDataType::ForVector(base_type)); + return ParamType(InterfaceType::Output, DataType::ForVector(base_type)); } - static MFParamType ForMutableSingle(const CPPType &type) + static ParamType ForMutableSingle(const CPPType &type) { - return MFParamType(InterfaceType::Mutable, MFDataType::ForSingle(type)); + return ParamType(InterfaceType::Mutable, DataType::ForSingle(type)); } - static MFParamType ForMutableVector(const CPPType &base_type) + static ParamType ForMutableVector(const CPPType &base_type) { - return MFParamType(InterfaceType::Mutable, MFDataType::ForVector(base_type)); + return ParamType(InterfaceType::Mutable, DataType::ForVector(base_type)); } - MFDataType data_type() const + DataType data_type() const { return data_type_; } @@ -94,34 +94,34 @@ class MFParamType { return interface_type_; } - MFParamCategory category() const + ParamCategory category() const { switch (data_type_.category()) { - case MFDataType::Single: { + case DataType::Single: { switch (interface_type_) { case Input: - return MFParamCategory::SingleInput; + return ParamCategory::SingleInput; case Output: - return MFParamCategory::SingleOutput; + return ParamCategory::SingleOutput; case Mutable: - return MFParamCategory::SingleMutable; + return ParamCategory::SingleMutable; } break; } - case MFDataType::Vector: { + case DataType::Vector: { switch (interface_type_) { case Input: - return MFParamCategory::VectorInput; + return ParamCategory::VectorInput; case Output: - return MFParamCategory::VectorOutput; + return ParamCategory::VectorOutput; case Mutable: - return MFParamCategory::VectorMutable; + return ParamCategory::VectorMutable; } break; } } BLI_assert_unreachable(); - return MFParamCategory::SingleInput; + return ParamCategory::SingleInput; } bool is_input_or_mutable() const @@ -139,18 +139,18 @@ class MFParamType { return interface_type_ == Output; } - friend bool operator==(const MFParamType &a, const MFParamType &b); - friend bool operator!=(const MFParamType &a, const MFParamType &b); + friend bool operator==(const ParamType &a, const ParamType &b); + friend bool operator!=(const ParamType &a, const ParamType &b); }; -inline bool operator==(const MFParamType &a, const MFParamType &b) +inline bool operator==(const ParamType &a, const ParamType &b) { return a.interface_type_ == b.interface_type_ && a.data_type_ == b.data_type_; } -inline bool operator!=(const MFParamType &a, const MFParamType &b) +inline bool operator!=(const ParamType &a, const ParamType &b) { return !(a == b); } -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh index fec75ac8159..caf43714e50 100644 --- a/source/blender/functions/FN_multi_function_params.hh +++ b/source/blender/functions/FN_multi_function_params.hh @@ -5,9 +5,9 @@ /** \file * \ingroup fn * - * This file provides an MFParams and MFParamsBuilder structure. + * This file provides an MFParams and ParamsBuilder structure. * - * `MFParamsBuilder` is used by a function caller to be prepare all parameters that are passed into + * `ParamsBuilder` is used by a function caller to be prepare all parameters that are passed into * the function. `MFParams` is then used inside the called function to access the parameters. */ @@ -21,12 +21,12 @@ #include "FN_multi_function_signature.hh" -namespace blender::fn { +namespace blender::fn::multi_function { -class MFParamsBuilder { +class ParamsBuilder { private: ResourceScope scope_; - const MFSignature *signature_; + const Signature *signature_; IndexMask mask_; int64_t min_array_size_; Vector> @@ -37,23 +37,23 @@ class MFParamsBuilder { friend class MFParams; - MFParamsBuilder(const MFSignature &signature, const IndexMask mask) + ParamsBuilder(const Signature &signature, const IndexMask mask) : signature_(&signature), mask_(mask), min_array_size_(mask.min_array_size()) { actual_params_.reserve(signature.params.size()); } public: - MFParamsBuilder(const class MultiFunction &fn, int64_t size); + ParamsBuilder(const class MultiFunction &fn, int64_t size); /** * The indices referenced by the #mask has to live longer than the params builder. This is * because the it might have to destruct elements for all masked indices in the end. */ - MFParamsBuilder(const class MultiFunction &fn, const IndexMask *mask); + ParamsBuilder(const class MultiFunction &fn, const IndexMask *mask); template void add_readonly_single_input_value(T value, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get()), expected_name); + this->assert_current_param_type(ParamType::ForSingleInput(CPPType::get()), expected_name); actual_params_.append_unchecked_as(std::in_place_type, varray_tag::single{}, CPPType::get(), @@ -62,7 +62,7 @@ class MFParamsBuilder { } template void add_readonly_single_input(const T *value, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForSingleInput(CPPType::get()), expected_name); + this->assert_current_param_type(ParamType::ForSingleInput(CPPType::get()), expected_name); actual_params_.append_unchecked_as(std::in_place_type, varray_tag::single_ref{}, CPPType::get(), @@ -71,13 +71,13 @@ class MFParamsBuilder { } void add_readonly_single_input(const GSpan span, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForSingleInput(span.type()), expected_name); + this->assert_current_param_type(ParamType::ForSingleInput(span.type()), expected_name); BLI_assert(span.size() >= min_array_size_); actual_params_.append_unchecked_as(std::in_place_type, varray_tag::span{}, span); } void add_readonly_single_input(GPointer value, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForSingleInput(*value.type()), expected_name); + this->assert_current_param_type(ParamType::ForSingleInput(*value.type()), expected_name); actual_params_.append_unchecked_as(std::in_place_type, varray_tag::single_ref{}, *value.type(), @@ -86,7 +86,7 @@ class MFParamsBuilder { } void add_readonly_single_input(GVArray varray, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForSingleInput(varray.type()), expected_name); + this->assert_current_param_type(ParamType::ForSingleInput(varray.type()), expected_name); BLI_assert(varray.size() >= min_array_size_); actual_params_.append_unchecked_as(std::in_place_type, std::move(varray)); } @@ -104,7 +104,7 @@ class MFParamsBuilder { } void add_readonly_vector_input(const GVVectorArray &ref, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForVectorInput(ref.type()), expected_name); + this->assert_current_param_type(ParamType::ForVectorInput(ref.type()), expected_name); BLI_assert(ref.size() >= min_array_size_); actual_params_.append_unchecked_as(std::in_place_type, &ref); } @@ -116,7 +116,7 @@ class MFParamsBuilder { } void add_uninitialized_single_output(GMutableSpan ref, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForSingleOutput(ref.type()), expected_name); + this->assert_current_param_type(ParamType::ForSingleOutput(ref.type()), expected_name); BLI_assert(ref.size() >= min_array_size_); actual_params_.append_unchecked_as(std::in_place_type, ref); } @@ -124,8 +124,8 @@ class MFParamsBuilder { { this->assert_current_param_name(expected_name); const int param_index = this->current_param_index(); - const MFParamType ¶m_type = signature_->params[param_index].type; - BLI_assert(param_type.category() == MFParamCategory::SingleOutput); + const ParamType ¶m_type = signature_->params[param_index].type; + BLI_assert(param_type.category() == ParamCategory::SingleOutput); const CPPType &type = param_type.data_type().single_type(); /* An empty span indicates that this is ignored. */ const GMutableSpan dummy_span{type}; @@ -134,7 +134,7 @@ class MFParamsBuilder { void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForVectorOutput(vector_array.type()), + this->assert_current_param_type(ParamType::ForVectorOutput(vector_array.type()), expected_name); BLI_assert(vector_array.size() >= min_array_size_); actual_params_.append_unchecked_as(std::in_place_type, &vector_array); @@ -142,14 +142,14 @@ class MFParamsBuilder { void add_single_mutable(GMutableSpan ref, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForMutableSingle(ref.type()), expected_name); + this->assert_current_param_type(ParamType::ForMutableSingle(ref.type()), expected_name); BLI_assert(ref.size() >= min_array_size_); actual_params_.append_unchecked_as(std::in_place_type, ref); } void add_vector_mutable(GVectorArray &vector_array, StringRef expected_name = "") { - this->assert_current_param_type(MFParamType::ForMutableVector(vector_array.type()), + this->assert_current_param_type(ParamType::ForMutableVector(vector_array.type()), expected_name); BLI_assert(vector_array.size() >= min_array_size_); actual_params_.append_unchecked_as(std::in_place_type, &vector_array); @@ -158,16 +158,16 @@ class MFParamsBuilder { GMutableSpan computed_array(int param_index) { BLI_assert(ELEM(signature_->params[param_index].type.category(), - MFParamCategory::SingleOutput, - MFParamCategory::SingleMutable)); + ParamCategory::SingleOutput, + ParamCategory::SingleMutable)); return *std::get_if(&actual_params_[param_index]); } GVectorArray &computed_vector_array(int param_index) { BLI_assert(ELEM(signature_->params[param_index].type.category(), - MFParamCategory::VectorOutput, - MFParamCategory::VectorMutable)); + ParamCategory::VectorOutput, + ParamCategory::VectorMutable)); return **std::get_if(&actual_params_[param_index]); } @@ -177,7 +177,7 @@ class MFParamsBuilder { } private: - void assert_current_param_type(MFParamType param_type, StringRef expected_name = "") + void assert_current_param_type(ParamType param_type, StringRef expected_name = "") { UNUSED_VARS_NDEBUG(param_type, expected_name); #ifdef DEBUG @@ -188,7 +188,7 @@ class MFParamsBuilder { BLI_assert(actual_name == expected_name); } - MFParamType expected_type = signature_->params[param_index].type; + ParamType expected_type = signature_->params[param_index].type; BLI_assert(expected_type == param_type); #endif } @@ -214,10 +214,10 @@ class MFParamsBuilder { class MFParams { private: - MFParamsBuilder *builder_; + ParamsBuilder *builder_; public: - MFParams(MFParamsBuilder &builder) : builder_(&builder) + MFParams(ParamsBuilder &builder) : builder_(&builder) { } @@ -228,7 +228,7 @@ class MFParams { } const GVArray &readonly_single_input(int param_index, StringRef name = "") { - this->assert_correct_param(param_index, name, MFParamCategory::SingleInput); + this->assert_correct_param(param_index, name, ParamCategory::SingleInput); return *std::get_if(&builder_->actual_params_[param_index]); } @@ -240,7 +240,7 @@ class MFParams { */ bool single_output_is_required(int param_index, StringRef name = "") { - this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput); + this->assert_correct_param(param_index, name, ParamCategory::SingleOutput); return !std::get_if(&builder_->actual_params_[param_index])->is_empty(); } @@ -251,7 +251,7 @@ class MFParams { } GMutableSpan uninitialized_single_output(int param_index, StringRef name = "") { - this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput); + this->assert_correct_param(param_index, name, ParamCategory::SingleOutput); GMutableSpan span = *std::get_if(&builder_->actual_params_[param_index]); if (!span.is_empty()) { return span; @@ -272,7 +272,7 @@ class MFParams { } GMutableSpan uninitialized_single_output_if_required(int param_index, StringRef name = "") { - this->assert_correct_param(param_index, name, MFParamCategory::SingleOutput); + this->assert_correct_param(param_index, name, ParamCategory::SingleOutput); return *std::get_if(&builder_->actual_params_[param_index]); } @@ -284,7 +284,7 @@ class MFParams { } const GVVectorArray &readonly_vector_input(int param_index, StringRef name = "") { - this->assert_correct_param(param_index, name, MFParamCategory::VectorInput); + this->assert_correct_param(param_index, name, ParamCategory::VectorInput); return **std::get_if(&builder_->actual_params_[param_index]); } @@ -295,7 +295,7 @@ class MFParams { } GVectorArray &vector_output(int param_index, StringRef name = "") { - this->assert_correct_param(param_index, name, MFParamCategory::VectorOutput); + this->assert_correct_param(param_index, name, ParamCategory::VectorOutput); return **std::get_if(&builder_->actual_params_[param_index]); } @@ -305,7 +305,7 @@ class MFParams { } GMutableSpan single_mutable(int param_index, StringRef name = "") { - this->assert_correct_param(param_index, name, MFParamCategory::SingleMutable); + this->assert_correct_param(param_index, name, ParamCategory::SingleMutable); return *std::get_if(&builder_->actual_params_[param_index]); } @@ -316,12 +316,12 @@ class MFParams { } GVectorArray &vector_mutable(int param_index, StringRef name = "") { - this->assert_correct_param(param_index, name, MFParamCategory::VectorMutable); + this->assert_correct_param(param_index, name, ParamCategory::VectorMutable); return **std::get_if(&builder_->actual_params_[param_index]); } private: - void assert_correct_param(int param_index, StringRef name, MFParamType param_type) + void assert_correct_param(int param_index, StringRef name, ParamType param_type) { UNUSED_VARS_NDEBUG(param_index, name, param_type); #ifdef DEBUG @@ -332,7 +332,7 @@ class MFParams { #endif } - void assert_correct_param(int param_index, StringRef name, MFParamCategory category) + void assert_correct_param(int param_index, StringRef name, ParamCategory category) { UNUSED_VARS_NDEBUG(param_index, name, category); #ifdef DEBUG @@ -346,4 +346,4 @@ class MFParams { GMutableSpan ensure_dummy_single_output(int param_index); }; -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/FN_multi_function_procedure.hh b/source/blender/functions/FN_multi_function_procedure.hh index da269b08155..b4bdbf37780 100644 --- a/source/blender/functions/FN_multi_function_procedure.hh +++ b/source/blender/functions/FN_multi_function_procedure.hh @@ -8,19 +8,19 @@ #include "FN_multi_function.hh" -namespace blender::fn { +namespace blender::fn::multi_function { -class MFVariable; -class MFInstruction; -class MFCallInstruction; -class MFBranchInstruction; -class MFDestructInstruction; -class MFDummyInstruction; -class MFReturnInstruction; -class MFProcedure; +class Variable; +class Instruction; +class CallInstruction; +class BranchInstruction; +class DestructInstruction; +class DummyInstruction; +class ReturnInstruction; +class Procedure; /** Every instruction has exactly one of these types. */ -enum class MFInstructionType { +enum class InstructionType { Call, Branch, Destruct, @@ -29,10 +29,10 @@ enum class MFInstructionType { }; /** - * An #MFInstructionCursor points to a position in a multi-function procedure, where an instruction + * An #InstructionCursor points to a position in a multi-function procedure, where an instruction * can be inserted. */ -class MFInstructionCursor { +class InstructionCursor { public: enum Type { None, @@ -45,33 +45,33 @@ class MFInstructionCursor { private: Type type_ = None; - MFInstruction *instruction_ = nullptr; + Instruction *instruction_ = nullptr; /* Only used when it is a branch instruction. */ bool branch_output_ = false; public: - MFInstructionCursor() = default; - MFInstructionCursor(MFCallInstruction &instruction); - MFInstructionCursor(MFDestructInstruction &instruction); - MFInstructionCursor(MFBranchInstruction &instruction, bool branch_output); - MFInstructionCursor(MFDummyInstruction &instruction); + InstructionCursor() = default; + InstructionCursor(CallInstruction &instruction); + InstructionCursor(DestructInstruction &instruction); + InstructionCursor(BranchInstruction &instruction, bool branch_output); + InstructionCursor(DummyInstruction &instruction); - static MFInstructionCursor ForEntry(); + static InstructionCursor ForEntry(); - MFInstruction *next(MFProcedure &procedure) const; - void set_next(MFProcedure &procedure, MFInstruction *new_instruction) const; + Instruction *next(Procedure &procedure) const; + void set_next(Procedure &procedure, Instruction *new_instruction) const; - MFInstruction *instruction() const; + Instruction *instruction() const; Type type() const; - friend bool operator==(const MFInstructionCursor &a, const MFInstructionCursor &b) + friend bool operator==(const InstructionCursor &a, const InstructionCursor &b) { return a.type_ == b.type_ && a.instruction_ == b.instruction_ && a.branch_output_ == b.branch_output_; } - friend bool operator!=(const MFInstructionCursor &a, const MFInstructionCursor &b) + friend bool operator!=(const InstructionCursor &a, const InstructionCursor &b) { return !(a == b); } @@ -82,21 +82,21 @@ class MFInstructionCursor { * either uninitialized or contains a value for every index (remember, a multi-function procedure * is always evaluated for many indices at the same time). */ -class MFVariable : NonCopyable, NonMovable { +class Variable : NonCopyable, NonMovable { private: - MFDataType data_type_; - Vector users_; + DataType data_type_; + Vector users_; std::string name_; int index_in_graph_; - friend MFProcedure; - friend MFCallInstruction; - friend MFBranchInstruction; - friend MFDestructInstruction; + friend Procedure; + friend CallInstruction; + friend BranchInstruction; + friend DestructInstruction; public: - MFDataType data_type() const; - Span users(); + DataType data_type() const; + Span users(); StringRefNull name() const; void set_name(std::string name); @@ -105,78 +105,78 @@ class MFVariable : NonCopyable, NonMovable { }; /** Base class for all instruction types. */ -class MFInstruction : NonCopyable, NonMovable { +class Instruction : NonCopyable, NonMovable { protected: - MFInstructionType type_; - Vector prev_; + InstructionType type_; + Vector prev_; - friend MFProcedure; - friend MFCallInstruction; - friend MFBranchInstruction; - friend MFDestructInstruction; - friend MFDummyInstruction; - friend MFReturnInstruction; + friend Procedure; + friend CallInstruction; + friend BranchInstruction; + friend DestructInstruction; + friend DummyInstruction; + friend ReturnInstruction; public: - MFInstructionType type() const; + InstructionType type() const; /** * Other instructions that come before this instruction. There can be multiple previous * instructions when branching is used in the procedure. */ - Span prev() const; + Span prev() const; }; /** * References a multi-function that is evaluated when the instruction is executed. It also * references the variables whose data will be passed into the multi-function. */ -class MFCallInstruction : public MFInstruction { +class CallInstruction : public Instruction { private: const MultiFunction *fn_ = nullptr; - MFInstruction *next_ = nullptr; - MutableSpan params_; + Instruction *next_ = nullptr; + MutableSpan params_; - friend MFProcedure; + friend Procedure; public: const MultiFunction &fn() const; - MFInstruction *next(); - const MFInstruction *next() const; - void set_next(MFInstruction *instruction); + Instruction *next(); + const Instruction *next() const; + void set_next(Instruction *instruction); - void set_param_variable(int param_index, MFVariable *variable); - void set_params(Span variables); + void set_param_variable(int param_index, Variable *variable); + void set_params(Span variables); - Span params(); - Span params() const; + Span params(); + Span params() const; }; /** * What makes a branch instruction special is that it has two successor instructions. One that will * be used when a condition variable was true, and one otherwise. */ -class MFBranchInstruction : public MFInstruction { +class BranchInstruction : public Instruction { private: - MFVariable *condition_ = nullptr; - MFInstruction *branch_true_ = nullptr; - MFInstruction *branch_false_ = nullptr; + Variable *condition_ = nullptr; + Instruction *branch_true_ = nullptr; + Instruction *branch_false_ = nullptr; - friend MFProcedure; + friend Procedure; public: - MFVariable *condition(); - const MFVariable *condition() const; - void set_condition(MFVariable *variable); + Variable *condition(); + const Variable *condition() const; + void set_condition(Variable *variable); - MFInstruction *branch_true(); - const MFInstruction *branch_true() const; - void set_branch_true(MFInstruction *instruction); + Instruction *branch_true(); + const Instruction *branch_true() const; + void set_branch_true(Instruction *instruction); - MFInstruction *branch_false(); - const MFInstruction *branch_false() const; - void set_branch_false(MFInstruction *instruction); + Instruction *branch_false(); + const Instruction *branch_false() const; + void set_branch_false(Instruction *instruction); }; /** @@ -185,55 +185,55 @@ class MFBranchInstruction : public MFInstruction { * destructed before the procedure ends. Destructing early is generally a good thing, because it * might help with memory buffer reuse, which decreases memory-usage and increases performance. */ -class MFDestructInstruction : public MFInstruction { +class DestructInstruction : public Instruction { private: - MFVariable *variable_ = nullptr; - MFInstruction *next_ = nullptr; + Variable *variable_ = nullptr; + Instruction *next_ = nullptr; - friend MFProcedure; + friend Procedure; public: - MFVariable *variable(); - const MFVariable *variable() const; - void set_variable(MFVariable *variable); + Variable *variable(); + const Variable *variable() const; + void set_variable(Variable *variable); - MFInstruction *next(); - const MFInstruction *next() const; - void set_next(MFInstruction *instruction); + Instruction *next(); + const Instruction *next() const; + void set_next(Instruction *instruction); }; /** * This instruction does nothing, it just exists to building a procedure simpler in some cases. */ -class MFDummyInstruction : public MFInstruction { +class DummyInstruction : public Instruction { private: - MFInstruction *next_ = nullptr; + Instruction *next_ = nullptr; - friend MFProcedure; + friend Procedure; public: - MFInstruction *next(); - const MFInstruction *next() const; - void set_next(MFInstruction *instruction); + Instruction *next(); + const Instruction *next() const; + void set_next(Instruction *instruction); }; /** * This instruction ends the procedure. */ -class MFReturnInstruction : public MFInstruction { +class ReturnInstruction : public Instruction { }; /** * Inputs and outputs of the entire procedure network. */ struct MFParameter { - MFParamType::InterfaceType type; - MFVariable *variable; + ParamType::InterfaceType type; + Variable *variable; }; struct ConstMFParameter { - MFParamType::InterfaceType type; - const MFVariable *variable; + ParamType::InterfaceType type; + const Variable *variable; }; /** @@ -241,46 +241,46 @@ struct ConstMFParameter { * variables and instructions that operate on those variables. Branching and looping within the * procedure is supported as well. * - * Typically, a #MFProcedure should be constructed using a #MFProcedureBuilder, which has many more + * Typically, a #Procedure should be constructed using a #ProcedureBuilder, which has many more * utility methods for common use cases. */ -class MFProcedure : NonCopyable, NonMovable { +class Procedure : NonCopyable, NonMovable { private: LinearAllocator<> allocator_; - Vector call_instructions_; - Vector branch_instructions_; - Vector destruct_instructions_; - Vector dummy_instructions_; - Vector return_instructions_; - Vector variables_; + Vector call_instructions_; + Vector branch_instructions_; + Vector destruct_instructions_; + Vector dummy_instructions_; + Vector return_instructions_; + Vector variables_; Vector params_; Vector> owned_functions_; - MFInstruction *entry_ = nullptr; + Instruction *entry_ = nullptr; - friend class MFProcedureDotExport; + friend class ProcedureDotExport; public: - MFProcedure() = default; - ~MFProcedure(); + Procedure() = default; + ~Procedure(); - MFVariable &new_variable(MFDataType data_type, std::string name = ""); - MFCallInstruction &new_call_instruction(const MultiFunction &fn); - MFBranchInstruction &new_branch_instruction(); - MFDestructInstruction &new_destruct_instruction(); - MFDummyInstruction &new_dummy_instruction(); - MFReturnInstruction &new_return_instruction(); + Variable &new_variable(DataType data_type, std::string name = ""); + CallInstruction &new_call_instruction(const MultiFunction &fn); + BranchInstruction &new_branch_instruction(); + DestructInstruction &new_destruct_instruction(); + DummyInstruction &new_dummy_instruction(); + ReturnInstruction &new_return_instruction(); - void add_parameter(MFParamType::InterfaceType interface_type, MFVariable &variable); + void add_parameter(ParamType::InterfaceType interface_type, Variable &variable); Span params() const; template const MultiFunction &construct_function(Args &&...args); - MFInstruction *entry(); - const MFInstruction *entry() const; - void set_entry(MFInstruction &entry); + Instruction *entry(); + const Instruction *entry() const; + void set_entry(Instruction &entry); - Span variables(); - Span variables() const; + Span variables(); + Span variables() const; std::string to_dot() const; @@ -298,59 +298,49 @@ class MFProcedure : NonCopyable, NonMovable { bool can_be_uninitialized = false; }; - InitState find_initialization_state_before_instruction(const MFInstruction &target_instruction, - const MFVariable &variable) const; + InitState find_initialization_state_before_instruction(const Instruction &target_instruction, + const Variable &variable) const; }; -namespace multi_function_procedure_types { -using MFVariable = fn::MFVariable; -using MFInstruction = fn::MFInstruction; -using MFCallInstruction = fn::MFCallInstruction; -using MFBranchInstruction = fn::MFBranchInstruction; -using MFDestructInstruction = fn::MFDestructInstruction; -using MFProcedure = fn::MFProcedure; -} // namespace multi_function_procedure_types - /* -------------------------------------------------------------------- */ -/** \name #MFInstructionCursor Inline Methods +/** \name #InstructionCursor Inline Methods * \{ */ -inline MFInstructionCursor::MFInstructionCursor(MFCallInstruction &instruction) +inline InstructionCursor::InstructionCursor(CallInstruction &instruction) : type_(Call), instruction_(&instruction) { } -inline MFInstructionCursor::MFInstructionCursor(MFDestructInstruction &instruction) +inline InstructionCursor::InstructionCursor(DestructInstruction &instruction) : type_(Destruct), instruction_(&instruction) { } -inline MFInstructionCursor::MFInstructionCursor(MFBranchInstruction &instruction, - bool branch_output) +inline InstructionCursor::InstructionCursor(BranchInstruction &instruction, bool branch_output) : type_(Branch), instruction_(&instruction), branch_output_(branch_output) { } -inline MFInstructionCursor::MFInstructionCursor(MFDummyInstruction &instruction) +inline InstructionCursor::InstructionCursor(DummyInstruction &instruction) : type_(Dummy), instruction_(&instruction) { } -inline MFInstructionCursor MFInstructionCursor::ForEntry() +inline InstructionCursor InstructionCursor::ForEntry() { - MFInstructionCursor cursor; + InstructionCursor cursor; cursor.type_ = Type::Entry; return cursor; } -inline MFInstruction *MFInstructionCursor::instruction() const +inline Instruction *InstructionCursor::instruction() const { /* This isn't really const correct unfortunately, because to make it correct we'll need a const - * version of #MFInstructionCursor. */ + * version of #InstructionCursor. */ return instruction_; } -inline MFInstructionCursor::Type MFInstructionCursor::type() const +inline InstructionCursor::Type InstructionCursor::type() const { return type_; } @@ -358,25 +348,25 @@ inline MFInstructionCursor::Type MFInstructionCursor::type() const /** \} */ /* -------------------------------------------------------------------- */ -/** \name #MFVariable Inline Methods +/** \name #Variable Inline Methods * \{ */ -inline MFDataType MFVariable::data_type() const +inline DataType Variable::data_type() const { return data_type_; } -inline Span MFVariable::users() +inline Span Variable::users() { return users_; } -inline StringRefNull MFVariable::name() const +inline StringRefNull Variable::name() const { return name_; } -inline int MFVariable::index_in_procedure() const +inline int Variable::index_in_procedure() const { return index_in_graph_; } @@ -384,15 +374,15 @@ inline int MFVariable::index_in_procedure() const /** \} */ /* -------------------------------------------------------------------- */ -/** \name #MFInstruction Inline Methods +/** \name #Instruction Inline Methods * \{ */ -inline MFInstructionType MFInstruction::type() const +inline InstructionType Instruction::type() const { return type_; } -inline Span MFInstruction::prev() const +inline Span Instruction::prev() const { return prev_; } @@ -400,30 +390,30 @@ inline Span MFInstruction::prev() const /** \} */ /* -------------------------------------------------------------------- */ -/** \name #MFCallInstruction Inline Methods +/** \name #CallInstruction Inline Methods * \{ */ -inline const MultiFunction &MFCallInstruction::fn() const +inline const MultiFunction &CallInstruction::fn() const { return *fn_; } -inline MFInstruction *MFCallInstruction::next() +inline Instruction *CallInstruction::next() { return next_; } -inline const MFInstruction *MFCallInstruction::next() const +inline const Instruction *CallInstruction::next() const { return next_; } -inline Span MFCallInstruction::params() +inline Span CallInstruction::params() { return params_; } -inline Span MFCallInstruction::params() const +inline Span CallInstruction::params() const { return params_; } @@ -431,35 +421,35 @@ inline Span MFCallInstruction::params() const /** \} */ /* -------------------------------------------------------------------- */ -/** \name #MFBranchInstruction Inline Methods +/** \name #BranchInstruction Inline Methods * \{ */ -inline MFVariable *MFBranchInstruction::condition() +inline Variable *BranchInstruction::condition() { return condition_; } -inline const MFVariable *MFBranchInstruction::condition() const +inline const Variable *BranchInstruction::condition() const { return condition_; } -inline MFInstruction *MFBranchInstruction::branch_true() +inline Instruction *BranchInstruction::branch_true() { return branch_true_; } -inline const MFInstruction *MFBranchInstruction::branch_true() const +inline const Instruction *BranchInstruction::branch_true() const { return branch_true_; } -inline MFInstruction *MFBranchInstruction::branch_false() +inline Instruction *BranchInstruction::branch_false() { return branch_false_; } -inline const MFInstruction *MFBranchInstruction::branch_false() const +inline const Instruction *BranchInstruction::branch_false() const { return branch_false_; } @@ -467,25 +457,25 @@ inline const MFInstruction *MFBranchInstruction::branch_false() const /** \} */ /* -------------------------------------------------------------------- */ -/** \name #MFDestructInstruction Inline Methods +/** \name #DestructInstruction Inline Methods * \{ */ -inline MFVariable *MFDestructInstruction::variable() +inline Variable *DestructInstruction::variable() { return variable_; } -inline const MFVariable *MFDestructInstruction::variable() const +inline const Variable *DestructInstruction::variable() const { return variable_; } -inline MFInstruction *MFDestructInstruction::next() +inline Instruction *DestructInstruction::next() { return next_; } -inline const MFInstruction *MFDestructInstruction::next() const +inline const Instruction *DestructInstruction::next() const { return next_; } @@ -493,15 +483,15 @@ inline const MFInstruction *MFDestructInstruction::next() const /** \} */ /* -------------------------------------------------------------------- */ -/** \name #MFDummyInstruction Inline Methods +/** \name #DummyInstruction Inline Methods * \{ */ -inline MFInstruction *MFDummyInstruction::next() +inline Instruction *DummyInstruction::next() { return next_; } -inline const MFInstruction *MFDummyInstruction::next() const +inline const Instruction *DummyInstruction::next() const { return next_; } @@ -509,37 +499,37 @@ inline const MFInstruction *MFDummyInstruction::next() const /** \} */ /* -------------------------------------------------------------------- */ -/** \name #MFProcedure Inline Methods +/** \name #Procedure Inline Methods * \{ */ -inline Span MFProcedure::params() const +inline Span Procedure::params() const { static_assert(sizeof(MFParameter) == sizeof(ConstMFParameter)); return params_.as_span().cast(); } -inline MFInstruction *MFProcedure::entry() +inline Instruction *Procedure::entry() { return entry_; } -inline const MFInstruction *MFProcedure::entry() const +inline const Instruction *Procedure::entry() const { return entry_; } -inline Span MFProcedure::variables() +inline Span Procedure::variables() { return variables_; } -inline Span MFProcedure::variables() const +inline Span Procedure::variables() const { return variables_; } template -inline const MultiFunction &MFProcedure::construct_function(Args &&...args) +inline const MultiFunction &Procedure::construct_function(Args &&...args) { destruct_ptr fn = allocator_.construct(std::forward(args)...); const MultiFunction &fn_ref = *fn; @@ -549,4 +539,4 @@ inline const MultiFunction &MFProcedure::construct_function(Args &&...args) /** \} */ -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/FN_multi_function_procedure_builder.hh b/source/blender/functions/FN_multi_function_procedure_builder.hh index 5292fa16cb0..f5170a1513b 100644 --- a/source/blender/functions/FN_multi_function_procedure_builder.hh +++ b/source/blender/functions/FN_multi_function_procedure_builder.hh @@ -8,182 +8,181 @@ #include "FN_multi_function_procedure.hh" -namespace blender::fn { +namespace blender::fn::multi_function { /** - * Utility class to build a #MFProcedure. + * Utility class to build a #Procedure. */ -class MFProcedureBuilder { +class ProcedureBuilder { private: /** Procedure that is being build. */ - MFProcedure *procedure_ = nullptr; + Procedure *procedure_ = nullptr; /** Cursors where the next instruction should be inserted. */ - Vector cursors_; + Vector cursors_; public: struct Branch; struct Loop; - MFProcedureBuilder(MFProcedure &procedure, - MFInstructionCursor initial_cursor = MFInstructionCursor::ForEntry()); + ProcedureBuilder(Procedure &procedure, + InstructionCursor initial_cursor = InstructionCursor::ForEntry()); - MFProcedureBuilder(Span builders); + ProcedureBuilder(Span builders); - MFProcedureBuilder(Branch &branch); + ProcedureBuilder(Branch &branch); - void set_cursor(const MFInstructionCursor &cursor); - void set_cursor(Span cursors); - void set_cursor(Span builders); + void set_cursor(const InstructionCursor &cursor); + void set_cursor(Span cursors); + void set_cursor(Span builders); void set_cursor_after_branch(Branch &branch); void set_cursor_after_loop(Loop &loop); - void add_destruct(MFVariable &variable); - void add_destruct(Span variables); + void add_destruct(Variable &variable); + void add_destruct(Span variables); - MFReturnInstruction &add_return(); + ReturnInstruction &add_return(); - Branch add_branch(MFVariable &condition); + Branch add_branch(Variable &condition); Loop add_loop(); void add_loop_continue(Loop &loop); void add_loop_break(Loop &loop); - MFCallInstruction &add_call_with_no_variables(const MultiFunction &fn); - MFCallInstruction &add_call_with_all_variables(const MultiFunction &fn, - Span param_variables); + CallInstruction &add_call_with_no_variables(const MultiFunction &fn); + CallInstruction &add_call_with_all_variables(const MultiFunction &fn, + Span param_variables); - Vector add_call(const MultiFunction &fn, - Span input_and_mutable_variables = {}); + Vector add_call(const MultiFunction &fn, + Span input_and_mutable_variables = {}); template - std::array add_call(const MultiFunction &fn, - Span input_and_mutable_variables = {}); + std::array add_call(const MultiFunction &fn, + Span input_and_mutable_variables = {}); - void add_parameter(MFParamType::InterfaceType interface_type, MFVariable &variable); - MFVariable &add_parameter(MFParamType param_type, std::string name = ""); + void add_parameter(ParamType::InterfaceType interface_type, Variable &variable); + Variable &add_parameter(ParamType param_type, std::string name = ""); - MFVariable &add_input_parameter(MFDataType data_type, std::string name = ""); - template MFVariable &add_single_input_parameter(std::string name = ""); - template MFVariable &add_single_mutable_parameter(std::string name = ""); + Variable &add_input_parameter(DataType data_type, std::string name = ""); + template Variable &add_single_input_parameter(std::string name = ""); + template Variable &add_single_mutable_parameter(std::string name = ""); - void add_output_parameter(MFVariable &variable); + void add_output_parameter(Variable &variable); private: - void link_to_cursors(MFInstruction *instruction); + void link_to_cursors(Instruction *instruction); }; -struct MFProcedureBuilder::Branch { - MFProcedureBuilder branch_true; - MFProcedureBuilder branch_false; +struct ProcedureBuilder::Branch { + ProcedureBuilder branch_true; + ProcedureBuilder branch_false; }; -struct MFProcedureBuilder::Loop { - MFInstruction *begin = nullptr; - MFDummyInstruction *end = nullptr; +struct ProcedureBuilder::Loop { + Instruction *begin = nullptr; + DummyInstruction *end = nullptr; }; /* -------------------------------------------------------------------- - * MFProcedureBuilder inline methods. + * ProcedureBuilder inline methods. */ -inline MFProcedureBuilder::MFProcedureBuilder(Branch &branch) - : MFProcedureBuilder(*branch.branch_true.procedure_) +inline ProcedureBuilder::ProcedureBuilder(Branch &branch) + : ProcedureBuilder(*branch.branch_true.procedure_) { this->set_cursor_after_branch(branch); } -inline MFProcedureBuilder::MFProcedureBuilder(MFProcedure &procedure, - MFInstructionCursor initial_cursor) +inline ProcedureBuilder::ProcedureBuilder(Procedure &procedure, InstructionCursor initial_cursor) : procedure_(&procedure), cursors_({initial_cursor}) { } -inline MFProcedureBuilder::MFProcedureBuilder(Span builders) - : MFProcedureBuilder(*builders[0]->procedure_) +inline ProcedureBuilder::ProcedureBuilder(Span builders) + : ProcedureBuilder(*builders[0]->procedure_) { this->set_cursor(builders); } -inline void MFProcedureBuilder::set_cursor(const MFInstructionCursor &cursor) +inline void ProcedureBuilder::set_cursor(const InstructionCursor &cursor) { cursors_ = {cursor}; } -inline void MFProcedureBuilder::set_cursor(Span cursors) +inline void ProcedureBuilder::set_cursor(Span cursors) { cursors_ = cursors; } -inline void MFProcedureBuilder::set_cursor_after_branch(Branch &branch) +inline void ProcedureBuilder::set_cursor_after_branch(Branch &branch) { this->set_cursor({&branch.branch_false, &branch.branch_true}); } -inline void MFProcedureBuilder::set_cursor_after_loop(Loop &loop) +inline void ProcedureBuilder::set_cursor_after_loop(Loop &loop) { - this->set_cursor(MFInstructionCursor{*loop.end}); + this->set_cursor(InstructionCursor{*loop.end}); } -inline void MFProcedureBuilder::set_cursor(Span builders) +inline void ProcedureBuilder::set_cursor(Span builders) { cursors_.clear(); - for (MFProcedureBuilder *builder : builders) { + for (ProcedureBuilder *builder : builders) { cursors_.extend(builder->cursors_); } } template -inline std::array MFProcedureBuilder::add_call( - const MultiFunction &fn, Span input_and_mutable_variables) +inline std::array ProcedureBuilder::add_call( + const MultiFunction &fn, Span input_and_mutable_variables) { - Vector output_variables = this->add_call(fn, input_and_mutable_variables); + Vector output_variables = this->add_call(fn, input_and_mutable_variables); BLI_assert(output_variables.size() == OutputN); - std::array output_array; + std::array output_array; initialized_copy_n(output_variables.data(), OutputN, output_array.data()); return output_array; } -inline void MFProcedureBuilder::add_parameter(MFParamType::InterfaceType interface_type, - MFVariable &variable) +inline void ProcedureBuilder::add_parameter(ParamType::InterfaceType interface_type, + Variable &variable) { procedure_->add_parameter(interface_type, variable); } -inline MFVariable &MFProcedureBuilder::add_parameter(MFParamType param_type, std::string name) +inline Variable &ProcedureBuilder::add_parameter(ParamType param_type, std::string name) { - MFVariable &variable = procedure_->new_variable(param_type.data_type(), std::move(name)); + Variable &variable = procedure_->new_variable(param_type.data_type(), std::move(name)); this->add_parameter(param_type.interface_type(), variable); return variable; } -inline MFVariable &MFProcedureBuilder::add_input_parameter(MFDataType data_type, std::string name) +inline Variable &ProcedureBuilder::add_input_parameter(DataType data_type, std::string name) { - return this->add_parameter(MFParamType(MFParamType::Input, data_type), std::move(name)); + return this->add_parameter(ParamType(ParamType::Input, data_type), std::move(name)); } template -inline MFVariable &MFProcedureBuilder::add_single_input_parameter(std::string name) +inline Variable &ProcedureBuilder::add_single_input_parameter(std::string name) { - return this->add_parameter(MFParamType::ForSingleInput(CPPType::get()), std::move(name)); + return this->add_parameter(ParamType::ForSingleInput(CPPType::get()), std::move(name)); } template -inline MFVariable &MFProcedureBuilder::add_single_mutable_parameter(std::string name) +inline Variable &ProcedureBuilder::add_single_mutable_parameter(std::string name) { - return this->add_parameter(MFParamType::ForMutableSingle(CPPType::get()), std::move(name)); + return this->add_parameter(ParamType::ForMutableSingle(CPPType::get()), std::move(name)); } -inline void MFProcedureBuilder::add_output_parameter(MFVariable &variable) +inline void ProcedureBuilder::add_output_parameter(Variable &variable) { - this->add_parameter(MFParamType::Output, variable); + this->add_parameter(ParamType::Output, variable); } -inline void MFProcedureBuilder::link_to_cursors(MFInstruction *instruction) +inline void ProcedureBuilder::link_to_cursors(Instruction *instruction) { - for (MFInstructionCursor &cursor : cursors_) { + for (InstructionCursor &cursor : cursors_) { cursor.set_next(*procedure_, instruction); } } -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/FN_multi_function_procedure_executor.hh b/source/blender/functions/FN_multi_function_procedure_executor.hh index 2233ae7d675..514b6fbd224 100644 --- a/source/blender/functions/FN_multi_function_procedure_executor.hh +++ b/source/blender/functions/FN_multi_function_procedure_executor.hh @@ -8,21 +8,21 @@ #include "FN_multi_function_procedure.hh" -namespace blender::fn { +namespace blender::fn::multi_function { /** A multi-function that executes a procedure internally. */ -class MFProcedureExecutor : public MultiFunction { +class ProcedureExecutor : public MultiFunction { private: - MFSignature signature_; - const MFProcedure &procedure_; + Signature signature_; + const Procedure &procedure_; public: - MFProcedureExecutor(const MFProcedure &procedure); + ProcedureExecutor(const Procedure &procedure); - void call(IndexMask mask, MFParams params, MFContext context) const override; + void call(IndexMask mask, MFParams params, Context context) const override; private: ExecutionHints get_execution_hints() const override; }; -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/FN_multi_function_procedure_optimization.hh b/source/blender/functions/FN_multi_function_procedure_optimization.hh index f5a02d84d42..c1f0f32b448 100644 --- a/source/blender/functions/FN_multi_function_procedure_optimization.hh +++ b/source/blender/functions/FN_multi_function_procedure_optimization.hh @@ -5,11 +5,11 @@ /** \file * \ingroup fn * - * A #MFProcedure optimization pass takes an existing procedure and changes it in a way that + * A #Procedure optimization pass takes an existing procedure and changes it in a way that * improves its performance when executed. * * Oftentimes it would also be possible to implement a specific optimization directly during - * construction of the initial #MFProcedure. There is a trade-off between doing that or just + * construction of the initial #Procedure. There is a trade-off between doing that or just * building a "simple" procedure and then optimizing it uses separate optimization passes. * - Doing optimizations directly during construction is typically faster than doing it as a * separate pass. However, it would be much harder to turn the optimization off when it is not @@ -23,10 +23,10 @@ #include "FN_multi_function_procedure.hh" -namespace blender::fn::procedure_optimization { +namespace blender::fn::multi_function::procedure_optimization { /** - * When generating a procedure, destruct instructions (#MFDestructInstruction) have to be inserted + * When generating a procedure, destruct instructions (#DestructInstruction) have to be inserted * for all variables that are not outputs. Often the simplest approach is to add these instructions * at the very end. However, when the procedure is executed this is not optimal, because many more * variables are initialized at the same time than necessary. This inhibits the reuse of memory @@ -42,6 +42,6 @@ namespace blender::fn::procedure_optimization { * \param block_end_instr: The instruction that points to the last instruction within a linear * chain of instructions. The algorithm moves instructions backward starting at this instruction. */ -void move_destructs_up(MFProcedure &procedure, MFInstruction &block_end_instr); +void move_destructs_up(Procedure &procedure, Instruction &block_end_instr); -} // namespace blender::fn::procedure_optimization +} // namespace blender::fn::multi_function::procedure_optimization diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh index 4797afd6a83..7de7507d851 100644 --- a/source/blender/functions/FN_multi_function_signature.hh +++ b/source/blender/functions/FN_multi_function_signature.hh @@ -6,18 +6,18 @@ * \ingroup fn * * The signature of a multi-function contains the functions name and expected parameters. New - * signatures should be build using the #MFSignatureBuilder class. + * signatures should be build using the #SignatureBuilder class. */ #include "FN_multi_function_param_type.hh" #include "BLI_vector.hh" -namespace blender::fn { +namespace blender::fn::multi_function { -struct MFSignature { +struct Signature { struct ParamInfo { - MFParamType type; + ParamType type; const char *name; }; @@ -32,12 +32,12 @@ struct MFSignature { Vector params; }; -class MFSignatureBuilder { +class SignatureBuilder { private: - MFSignature &signature_; + Signature &signature_; public: - MFSignatureBuilder(const char *function_name, MFSignature &signature_to_build) + SignatureBuilder(const char *function_name, Signature &signature_to_build) : signature_(signature_to_build) { signature_.function_name = function_name; @@ -51,7 +51,7 @@ class MFSignatureBuilder { } void single_input(const char *name, const CPPType &type) { - this->input(name, MFDataType::ForSingle(type)); + this->input(name, DataType::ForSingle(type)); } template void vector_input(const char *name) { @@ -59,11 +59,11 @@ class MFSignatureBuilder { } void vector_input(const char *name, const CPPType &base_type) { - this->input(name, MFDataType::ForVector(base_type)); + this->input(name, DataType::ForVector(base_type)); } - void input(const char *name, MFDataType data_type) + void input(const char *name, DataType data_type) { - signature_.params.append({MFParamType(MFParamType::Input, data_type), name}); + signature_.params.append({ParamType(ParamType::Input, data_type), name}); } /* Output Parameter Types */ @@ -74,7 +74,7 @@ class MFSignatureBuilder { } void single_output(const char *name, const CPPType &type) { - this->output(name, MFDataType::ForSingle(type)); + this->output(name, DataType::ForSingle(type)); } template void vector_output(const char *name) { @@ -82,11 +82,11 @@ class MFSignatureBuilder { } void vector_output(const char *name, const CPPType &base_type) { - this->output(name, MFDataType::ForVector(base_type)); + this->output(name, DataType::ForVector(base_type)); } - void output(const char *name, MFDataType data_type) + void output(const char *name, DataType data_type) { - signature_.params.append({MFParamType(MFParamType::Output, data_type), name}); + signature_.params.append({ParamType(ParamType::Output, data_type), name}); } /* Mutable Parameter Types */ @@ -97,7 +97,7 @@ class MFSignatureBuilder { } void single_mutable(const char *name, const CPPType &type) { - this->mutable_(name, MFDataType::ForSingle(type)); + this->mutable_(name, DataType::ForSingle(type)); } template void vector_mutable(const char *name) { @@ -105,48 +105,48 @@ class MFSignatureBuilder { } void vector_mutable(const char *name, const CPPType &base_type) { - this->mutable_(name, MFDataType::ForVector(base_type)); + this->mutable_(name, DataType::ForVector(base_type)); } - void mutable_(const char *name, MFDataType data_type) + void mutable_(const char *name, DataType data_type) { - signature_.params.append({MFParamType(MFParamType::Mutable, data_type), name}); + signature_.params.append({ParamType(ParamType::Mutable, data_type), name}); } - void add(const char *name, const MFParamType ¶m_type) + void add(const char *name, const ParamType ¶m_type) { switch (param_type.interface_type()) { - case MFParamType::Input: + case ParamType::Input: this->input(name, param_type.data_type()); break; - case MFParamType::Mutable: + case ParamType::Mutable: this->mutable_(name, param_type.data_type()); break; - case MFParamType::Output: + case ParamType::Output: this->output(name, param_type.data_type()); break; } } - template + template void add(MFParamTag /* tag */, const char *name) { switch (Category) { - case MFParamCategory::SingleInput: + case ParamCategory::SingleInput: this->single_input(name); return; - case MFParamCategory::VectorInput: + case ParamCategory::VectorInput: this->vector_input(name); return; - case MFParamCategory::SingleOutput: + case ParamCategory::SingleOutput: this->single_output(name); return; - case MFParamCategory::VectorOutput: + case ParamCategory::VectorOutput: this->vector_output(name); return; - case MFParamCategory::SingleMutable: + case ParamCategory::SingleMutable: this->single_mutable(name); return; - case MFParamCategory::VectorMutable: + case ParamCategory::VectorMutable: this->vector_mutable(name); return; } @@ -154,4 +154,4 @@ class MFSignatureBuilder { } }; -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/intern/field.cc b/source/blender/functions/intern/field.cc index 6a5a31eb17d..bc55e023950 100644 --- a/source/blender/functions/intern/field.cc +++ b/source/blender/functions/intern/field.cc @@ -142,19 +142,19 @@ static Set find_varying_fields(const FieldTreeInfo &field_tree_info, /** * Builds the #procedure so that it computes the fields. */ -static void build_multi_function_procedure_for_fields(MFProcedure &procedure, +static void build_multi_function_procedure_for_fields(mf::Procedure &procedure, ResourceScope &scope, const FieldTreeInfo &field_tree_info, Span output_fields) { - MFProcedureBuilder builder{procedure}; + mf::ProcedureBuilder builder{procedure}; /* Every input, intermediate and output field corresponds to a variable in the procedure. */ - Map variable_by_field; + Map variable_by_field; /* Start by adding the field inputs as parameters to the procedure. */ for (const FieldInput &field_input : field_tree_info.deduplicated_field_inputs) { - MFVariable &variable = builder.add_input_parameter( - MFDataType::ForSingle(field_input.cpp_type()), field_input.debug_name()); + mf::Variable &variable = builder.add_input_parameter( + mf::DataType::ForSingle(field_input.cpp_type()), field_input.debug_name()); variable_by_field.add_new({field_input, 0}, &variable); } @@ -196,20 +196,20 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure, else { /* All inputs variables are ready, now gather all variables that are used by the * function and call it. */ - const MultiFunction &multi_function = operation_node.multi_function(); - Vector variables(multi_function.param_amount()); + const mf::MultiFunction &multi_function = operation_node.multi_function(); + Vector variables(multi_function.param_amount()); int param_input_index = 0; int param_output_index = 0; for (const int param_index : multi_function.param_indices()) { - const MFParamType param_type = multi_function.param_type(param_index); - const MFParamType::InterfaceType interface_type = param_type.interface_type(); - if (interface_type == MFParamType::Input) { + const mf::ParamType param_type = multi_function.param_type(param_index); + const mf::ParamType::InterfaceType interface_type = param_type.interface_type(); + if (interface_type == mf::ParamType::Input) { const GField &input_field = operation_inputs[param_input_index]; variables[param_index] = variable_by_field.lookup(input_field); param_input_index++; } - else if (interface_type == MFParamType::Output) { + else if (interface_type == mf::ParamType::Output) { const GFieldRef output_field{operation_node, param_output_index}; const bool output_is_ignored = field_tree_info.field_users.lookup(output_field).is_empty() && @@ -220,7 +220,7 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure, } else { /* Create a new variable for used outputs. */ - MFVariable &new_variable = procedure.new_variable(param_type.data_type()); + mf::Variable &new_variable = procedure.new_variable(param_type.data_type()); variables[param_index] = &new_variable; variable_by_field.add_new(output_field, &new_variable); } @@ -236,9 +236,9 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure, } case FieldNodeType::Constant: { const FieldConstant &constant_node = static_cast(field_node); - const MultiFunction &fn = procedure.construct_function( + const mf::MultiFunction &fn = procedure.construct_function( constant_node.type(), constant_node.value().get(), false); - MFVariable &new_variable = *builder.add_call<1>(fn)[0]; + mf::Variable &new_variable = *builder.add_call<1>(fn)[0]; variable_by_field.add_new(field, &new_variable); break; } @@ -247,13 +247,14 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure, } /* Add output parameters to the procedure. */ - Set already_output_variables; + Set already_output_variables; for (const GFieldRef &field : output_fields) { - MFVariable *variable = variable_by_field.lookup(field); + mf::Variable *variable = variable_by_field.lookup(field); if (!already_output_variables.add(variable)) { /* One variable can be output at most once. To output the same value twice, we have to make * a copy first. */ - const MultiFunction ©_fn = scope.construct(variable->data_type()); + const mf::MultiFunction ©_fn = scope.construct( + variable->data_type()); variable = builder.add_call<1>(copy_fn, {variable})[0]; } builder.add_output_parameter(*variable); @@ -264,13 +265,13 @@ static void build_multi_function_procedure_for_fields(MFProcedure &procedure, variable_by_field.remove(field); } /* Add destructor calls for the remaining variables. */ - for (MFVariable *variable : variable_by_field.values()) { + for (mf::Variable *variable : variable_by_field.values()) { builder.add_destruct(*variable); } - MFReturnInstruction &return_instr = builder.add_return(); + mf::ReturnInstruction &return_instr = builder.add_return(); - procedure_optimization::move_destructs_up(procedure, return_instr); + mf::procedure_optimization::move_destructs_up(procedure, return_instr); // std::cout << procedure.to_dot() << "\n"; BLI_assert(procedure.validate()); @@ -366,13 +367,13 @@ Vector evaluate_fields(ResourceScope &scope, /* Evaluate varying fields if necessary. */ if (!varying_fields_to_evaluate.is_empty()) { /* Build the procedure for those fields. */ - MFProcedure procedure; + mf::Procedure procedure; build_multi_function_procedure_for_fields( procedure, scope, field_tree_info, varying_fields_to_evaluate); - MFProcedureExecutor procedure_executor{procedure}; + mf::ProcedureExecutor procedure_executor{procedure}; - MFParamsBuilder mf_params{procedure_executor, &mask}; - MFContextBuilder mf_context; + mf::ParamsBuilder mf_params{procedure_executor, &mask}; + mf::ContextBuilder mf_context; /* Provide inputs to the procedure executor. */ for (const GVArray &varray : field_context_inputs) { @@ -418,12 +419,12 @@ Vector evaluate_fields(ResourceScope &scope, /* Evaluate constant fields if necessary. */ if (!constant_fields_to_evaluate.is_empty()) { /* Build the procedure for those fields. */ - MFProcedure procedure; + mf::Procedure procedure; build_multi_function_procedure_for_fields( procedure, scope, field_tree_info, constant_fields_to_evaluate); - MFProcedureExecutor procedure_executor{procedure}; - MFParamsBuilder mf_params{procedure_executor, 1}; - MFContextBuilder mf_context; + mf::ProcedureExecutor procedure_executor{procedure}; + mf::ParamsBuilder mf_params{procedure_executor, 1}; + mf::ContextBuilder mf_context; /* Provide inputs to the procedure executor. */ for (const GVArray &varray : field_context_inputs) { @@ -519,8 +520,8 @@ GField make_field_constant_if_possible(GField field) Field invert_boolean_field(const Field &field) { - static auto not_fn = build_mf::SI1_SO( - "Not", [](bool a) { return !a; }, build_mf::exec_presets::AllSpanOrSingle()); + static auto not_fn = mf::build::SI1_SO( + "Not", [](bool a) { return !a; }, mf::build::exec_presets::AllSpanOrSingle()); auto not_op = std::make_shared(FieldOperation(not_fn, {field})); return Field(not_op); } @@ -597,7 +598,7 @@ void FieldNode::for_each_field_input_recursive(FunctionRef function, +FieldOperation::FieldOperation(std::shared_ptr function, Vector inputs) : FieldOperation(*function, std::move(inputs)) { @@ -662,7 +663,7 @@ static std::shared_ptr combine_field_inputs(Span fiel return new_field_inputs; } -FieldOperation::FieldOperation(const MultiFunction &function, Vector inputs) +FieldOperation::FieldOperation(const mf::MultiFunction &function, Vector inputs) : FieldNode(FieldNodeType::Operation), function_(&function), inputs_(std::move(inputs)) { field_inputs_ = combine_field_inputs(inputs_); diff --git a/source/blender/functions/intern/multi_function.cc b/source/blender/functions/intern/multi_function.cc index c05087a4c2d..3d20ce4bac3 100644 --- a/source/blender/functions/intern/multi_function.cc +++ b/source/blender/functions/intern/multi_function.cc @@ -5,7 +5,7 @@ #include "BLI_task.hh" #include "BLI_threads.h" -namespace blender::fn { +namespace blender::fn::multi_function { using ExecutionHints = MultiFunction::ExecutionHints; @@ -22,10 +22,10 @@ ExecutionHints MultiFunction::get_execution_hints() const static bool supports_threading_by_slicing_params(const MultiFunction &fn) { for (const int i : fn.param_indices()) { - const MFParamType param_type = fn.param_type(i); + const ParamType param_type = fn.param_type(i); if (ELEM(param_type.interface_type(), - MFParamType::InterfaceType::Mutable, - MFParamType::InterfaceType::Output)) { + ParamType::InterfaceType::Mutable, + ParamType::InterfaceType::Output)) { if (param_type.data_type().is_vector()) { return false; } @@ -52,7 +52,7 @@ static int64_t compute_grain_size(const ExecutionHints &hints, const IndexMask m return grain_size; } -void MultiFunction::call_auto(IndexMask mask, MFParams params, MFContext context) const +void MultiFunction::call_auto(IndexMask mask, MFParams params, Context context) const { if (mask.is_empty()) { return; @@ -90,24 +90,24 @@ void MultiFunction::call_auto(IndexMask mask, MFParams params, MFContext context Vector offset_mask_indices; const IndexMask offset_mask = mask.slice_and_offset(sub_range, offset_mask_indices); - MFParamsBuilder offset_params{*this, offset_mask.min_array_size()}; + ParamsBuilder offset_params{*this, offset_mask.min_array_size()}; /* Slice all parameters so that for the actual function call. */ for (const int param_index : this->param_indices()) { - const MFParamType param_type = this->param_type(param_index); + const ParamType param_type = this->param_type(param_index); switch (param_type.category()) { - case MFParamCategory::SingleInput: { + case ParamCategory::SingleInput: { const GVArray &varray = params.readonly_single_input(param_index); offset_params.add_readonly_single_input(varray.slice(input_slice_range)); break; } - case MFParamCategory::SingleMutable: { + case ParamCategory::SingleMutable: { const GMutableSpan span = params.single_mutable(param_index); const GMutableSpan sliced_span = span.slice(input_slice_range); offset_params.add_single_mutable(sliced_span); break; } - case MFParamCategory::SingleOutput: { + case ParamCategory::SingleOutput: { const GMutableSpan span = params.uninitialized_single_output_if_required(param_index); if (span.is_empty()) { offset_params.add_ignored_single_output(); @@ -118,9 +118,9 @@ void MultiFunction::call_auto(IndexMask mask, MFParams params, MFContext context } break; } - case MFParamCategory::VectorInput: - case MFParamCategory::VectorMutable: - case MFParamCategory::VectorOutput: { + case ParamCategory::VectorInput: + case ParamCategory::VectorMutable: + case ParamCategory::VectorOutput: { BLI_assert_unreachable(); break; } @@ -136,4 +136,4 @@ std::string MultiFunction::debug_name() const return signature_ref_->function_name; } -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc index 30b734b881b..20186e56e1e 100644 --- a/source/blender/functions/intern/multi_function_builder.cc +++ b/source/blender/functions/intern/multi_function_builder.cc @@ -4,7 +4,7 @@ #include "BLI_hash.hh" -namespace blender::fn { +namespace blender::fn::multi_function { CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type, const void *value, @@ -18,7 +18,7 @@ CustomMF_GenericConstant::CustomMF_GenericConstant(const CPPType &type, } value_ = value; - MFSignatureBuilder builder{"Constant", signature_}; + SignatureBuilder builder{"Constant", signature_}; builder.single_output("Value", type); this->set_signature(&signature_); } @@ -31,7 +31,7 @@ CustomMF_GenericConstant::~CustomMF_GenericConstant() } } -void CustomMF_GenericConstant::call(IndexMask mask, MFParams params, MFContext /*context*/) const +void CustomMF_GenericConstant::call(IndexMask mask, MFParams params, Context /*context*/) const { GMutableSpan output = params.uninitialized_single_output(0); type_.fill_construct_indices(value_, output.data(), mask); @@ -57,14 +57,14 @@ bool CustomMF_GenericConstant::equals(const MultiFunction &other) const CustomMF_GenericConstantArray::CustomMF_GenericConstantArray(GSpan array) : array_(array) { const CPPType &type = array.type(); - MFSignatureBuilder builder{"Constant Vector", signature_}; + SignatureBuilder builder{"Constant Vector", signature_}; builder.vector_output("Value", type); this->set_signature(&signature_); } void CustomMF_GenericConstantArray::call(IndexMask mask, MFParams params, - MFContext /*context*/) const + Context /*context*/) const { GVectorArray &vectors = params.vector_output(0); for (int64_t i : mask) { @@ -72,23 +72,23 @@ void CustomMF_GenericConstantArray::call(IndexMask mask, } } -CustomMF_DefaultOutput::CustomMF_DefaultOutput(Span input_types, - Span output_types) +CustomMF_DefaultOutput::CustomMF_DefaultOutput(Span input_types, + Span output_types) : output_amount_(output_types.size()) { - MFSignatureBuilder builder{"Default Output", signature_}; - for (MFDataType data_type : input_types) { + SignatureBuilder builder{"Default Output", signature_}; + for (DataType data_type : input_types) { builder.input("Input", data_type); } - for (MFDataType data_type : output_types) { + for (DataType data_type : output_types) { builder.output("Output", data_type); } this->set_signature(&signature_); } -void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext /*context*/) const +void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, Context /*context*/) const { for (int param_index : this->param_indices()) { - MFParamType param_type = this->param_type(param_index); + ParamType param_type = this->param_type(param_index); if (!param_type.is_output()) { continue; } @@ -101,25 +101,25 @@ void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, MFContext /*c } } -CustomMF_GenericCopy::CustomMF_GenericCopy(MFDataType data_type) +CustomMF_GenericCopy::CustomMF_GenericCopy(DataType data_type) { - MFSignatureBuilder builder{"Copy", signature_}; + SignatureBuilder builder{"Copy", signature_}; builder.input("Input", data_type); builder.output("Output", data_type); this->set_signature(&signature_); } -void CustomMF_GenericCopy::call(IndexMask mask, MFParams params, MFContext /*context*/) const +void CustomMF_GenericCopy::call(IndexMask mask, MFParams params, Context /*context*/) const { - const MFDataType data_type = this->param_type(0).data_type(); + const DataType data_type = this->param_type(0).data_type(); switch (data_type.category()) { - case MFDataType::Single: { + case DataType::Single: { const GVArray &inputs = params.readonly_single_input(0, "Input"); GMutableSpan outputs = params.uninitialized_single_output(1, "Output"); inputs.materialize_to_uninitialized(mask, outputs.data()); break; } - case MFDataType::Vector: { + case DataType::Vector: { const GVVectorArray &inputs = params.readonly_vector_input(0, "Input"); GVectorArray &outputs = params.vector_output(1, "Output"); outputs.extend(mask, inputs); @@ -128,4 +128,4 @@ void CustomMF_GenericCopy::call(IndexMask mask, MFParams params, MFContext /*con } } -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/intern/multi_function_params.cc b/source/blender/functions/intern/multi_function_params.cc index 3589c701618..a85a2ed539c 100644 --- a/source/blender/functions/intern/multi_function_params.cc +++ b/source/blender/functions/intern/multi_function_params.cc @@ -2,7 +2,7 @@ #include "FN_multi_function_params.hh" -namespace blender::fn { +namespace blender::fn::multi_function { GMutableSpan MFParams::ensure_dummy_single_output(int param_index) { @@ -27,4 +27,4 @@ GMutableSpan MFParams::ensure_dummy_single_output(int param_index) return span; } -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/intern/multi_function_procedure.cc b/source/blender/functions/intern/multi_function_procedure.cc index b78787de57c..263d0b0ff62 100644 --- a/source/blender/functions/intern/multi_function_procedure.cc +++ b/source/blender/functions/intern/multi_function_procedure.cc @@ -5,9 +5,9 @@ #include "BLI_dot_export.hh" #include "BLI_stack.hh" -namespace blender::fn { +namespace blender::fn::multi_function { -void MFInstructionCursor::set_next(MFProcedure &procedure, MFInstruction *new_instruction) const +void InstructionCursor::set_next(Procedure &procedure, Instruction *new_instruction) const { switch (type_) { case Type::None: { @@ -18,11 +18,11 @@ void MFInstructionCursor::set_next(MFProcedure &procedure, MFInstruction *new_in break; } case Type::Call: { - static_cast(instruction_)->set_next(new_instruction); + static_cast(instruction_)->set_next(new_instruction); break; } case Type::Branch: { - MFBranchInstruction &branch_instruction = *static_cast(instruction_); + BranchInstruction &branch_instruction = *static_cast(instruction_); if (branch_output_) { branch_instruction.set_branch_true(new_instruction); } @@ -32,17 +32,17 @@ void MFInstructionCursor::set_next(MFProcedure &procedure, MFInstruction *new_in break; } case Type::Destruct: { - static_cast(instruction_)->set_next(new_instruction); + static_cast(instruction_)->set_next(new_instruction); break; } case Type::Dummy: { - static_cast(instruction_)->set_next(new_instruction); + static_cast(instruction_)->set_next(new_instruction); break; } } } -MFInstruction *MFInstructionCursor::next(MFProcedure &procedure) const +Instruction *InstructionCursor::next(Procedure &procedure) const { switch (type_) { case Type::None: @@ -50,28 +50,28 @@ MFInstruction *MFInstructionCursor::next(MFProcedure &procedure) const case Type::Entry: return procedure.entry(); case Type::Call: - return static_cast(instruction_)->next(); + return static_cast(instruction_)->next(); case Type::Branch: { - MFBranchInstruction &branch_instruction = *static_cast(instruction_); + BranchInstruction &branch_instruction = *static_cast(instruction_); if (branch_output_) { return branch_instruction.branch_true(); } return branch_instruction.branch_false(); } case Type::Destruct: - return static_cast(instruction_)->next(); + return static_cast(instruction_)->next(); case Type::Dummy: - return static_cast(instruction_)->next(); + return static_cast(instruction_)->next(); } return nullptr; } -void MFVariable::set_name(std::string name) +void Variable::set_name(std::string name) { name_ = std::move(name); } -void MFCallInstruction::set_next(MFInstruction *instruction) +void CallInstruction::set_next(Instruction *instruction) { if (next_ != nullptr) { next_->prev_.remove_first_occurrence_and_reorder(*this); @@ -82,7 +82,7 @@ void MFCallInstruction::set_next(MFInstruction *instruction) next_ = instruction; } -void MFCallInstruction::set_param_variable(int param_index, MFVariable *variable) +void CallInstruction::set_param_variable(int param_index, Variable *variable) { if (params_[param_index] != nullptr) { params_[param_index]->users_.remove_first_occurrence_and_reorder(this); @@ -94,7 +94,7 @@ void MFCallInstruction::set_param_variable(int param_index, MFVariable *variable params_[param_index] = variable; } -void MFCallInstruction::set_params(Span variables) +void CallInstruction::set_params(Span variables) { BLI_assert(variables.size() == params_.size()); for (const int i : variables.index_range()) { @@ -102,7 +102,7 @@ void MFCallInstruction::set_params(Span variables) } } -void MFBranchInstruction::set_condition(MFVariable *variable) +void BranchInstruction::set_condition(Variable *variable) { if (condition_ != nullptr) { condition_->users_.remove_first_occurrence_and_reorder(this); @@ -113,7 +113,7 @@ void MFBranchInstruction::set_condition(MFVariable *variable) condition_ = variable; } -void MFBranchInstruction::set_branch_true(MFInstruction *instruction) +void BranchInstruction::set_branch_true(Instruction *instruction) { if (branch_true_ != nullptr) { branch_true_->prev_.remove_first_occurrence_and_reorder({*this, true}); @@ -124,7 +124,7 @@ void MFBranchInstruction::set_branch_true(MFInstruction *instruction) branch_true_ = instruction; } -void MFBranchInstruction::set_branch_false(MFInstruction *instruction) +void BranchInstruction::set_branch_false(Instruction *instruction) { if (branch_false_ != nullptr) { branch_false_->prev_.remove_first_occurrence_and_reorder({*this, false}); @@ -135,7 +135,7 @@ void MFBranchInstruction::set_branch_false(MFInstruction *instruction) branch_false_ = instruction; } -void MFDestructInstruction::set_variable(MFVariable *variable) +void DestructInstruction::set_variable(Variable *variable) { if (variable_ != nullptr) { variable_->users_.remove_first_occurrence_and_reorder(this); @@ -146,7 +146,7 @@ void MFDestructInstruction::set_variable(MFVariable *variable) variable_ = variable; } -void MFDestructInstruction::set_next(MFInstruction *instruction) +void DestructInstruction::set_next(Instruction *instruction) { if (next_ != nullptr) { next_->prev_.remove_first_occurrence_and_reorder(*this); @@ -157,7 +157,7 @@ void MFDestructInstruction::set_next(MFInstruction *instruction) next_ = instruction; } -void MFDummyInstruction::set_next(MFInstruction *instruction) +void DummyInstruction::set_next(Instruction *instruction) { if (next_ != nullptr) { next_->prev_.remove_first_occurrence_and_reorder(*this); @@ -168,9 +168,9 @@ void MFDummyInstruction::set_next(MFInstruction *instruction) next_ = instruction; } -MFVariable &MFProcedure::new_variable(MFDataType data_type, std::string name) +Variable &Procedure::new_variable(DataType data_type, std::string name) { - MFVariable &variable = *allocator_.construct().release(); + Variable &variable = *allocator_.construct().release(); variable.name_ = std::move(name); variable.data_type_ = data_type; variable.index_in_graph_ = variables_.size(); @@ -178,86 +178,86 @@ MFVariable &MFProcedure::new_variable(MFDataType data_type, std::string name) return variable; } -MFCallInstruction &MFProcedure::new_call_instruction(const MultiFunction &fn) +CallInstruction &Procedure::new_call_instruction(const MultiFunction &fn) { - MFCallInstruction &instruction = *allocator_.construct().release(); - instruction.type_ = MFInstructionType::Call; + CallInstruction &instruction = *allocator_.construct().release(); + instruction.type_ = InstructionType::Call; instruction.fn_ = &fn; - instruction.params_ = allocator_.allocate_array(fn.param_amount()); + instruction.params_ = allocator_.allocate_array(fn.param_amount()); instruction.params_.fill(nullptr); call_instructions_.append(&instruction); return instruction; } -MFBranchInstruction &MFProcedure::new_branch_instruction() +BranchInstruction &Procedure::new_branch_instruction() { - MFBranchInstruction &instruction = *allocator_.construct().release(); - instruction.type_ = MFInstructionType::Branch; + BranchInstruction &instruction = *allocator_.construct().release(); + instruction.type_ = InstructionType::Branch; branch_instructions_.append(&instruction); return instruction; } -MFDestructInstruction &MFProcedure::new_destruct_instruction() +DestructInstruction &Procedure::new_destruct_instruction() { - MFDestructInstruction &instruction = *allocator_.construct().release(); - instruction.type_ = MFInstructionType::Destruct; + DestructInstruction &instruction = *allocator_.construct().release(); + instruction.type_ = InstructionType::Destruct; destruct_instructions_.append(&instruction); return instruction; } -MFDummyInstruction &MFProcedure::new_dummy_instruction() +DummyInstruction &Procedure::new_dummy_instruction() { - MFDummyInstruction &instruction = *allocator_.construct().release(); - instruction.type_ = MFInstructionType::Dummy; + DummyInstruction &instruction = *allocator_.construct().release(); + instruction.type_ = InstructionType::Dummy; dummy_instructions_.append(&instruction); return instruction; } -MFReturnInstruction &MFProcedure::new_return_instruction() +ReturnInstruction &Procedure::new_return_instruction() { - MFReturnInstruction &instruction = *allocator_.construct().release(); - instruction.type_ = MFInstructionType::Return; + ReturnInstruction &instruction = *allocator_.construct().release(); + instruction.type_ = InstructionType::Return; return_instructions_.append(&instruction); return instruction; } -void MFProcedure::add_parameter(MFParamType::InterfaceType interface_type, MFVariable &variable) +void Procedure::add_parameter(ParamType::InterfaceType interface_type, Variable &variable) { params_.append({interface_type, &variable}); } -void MFProcedure::set_entry(MFInstruction &entry) +void Procedure::set_entry(Instruction &entry) { if (entry_ != nullptr) { - entry_->prev_.remove_first_occurrence_and_reorder(MFInstructionCursor::ForEntry()); + entry_->prev_.remove_first_occurrence_and_reorder(InstructionCursor::ForEntry()); } entry_ = &entry; - entry_->prev_.append(MFInstructionCursor::ForEntry()); + entry_->prev_.append(InstructionCursor::ForEntry()); } -MFProcedure::~MFProcedure() +Procedure::~Procedure() { - for (MFCallInstruction *instruction : call_instructions_) { - instruction->~MFCallInstruction(); + for (CallInstruction *instruction : call_instructions_) { + instruction->~CallInstruction(); } - for (MFBranchInstruction *instruction : branch_instructions_) { - instruction->~MFBranchInstruction(); + for (BranchInstruction *instruction : branch_instructions_) { + instruction->~BranchInstruction(); } - for (MFDestructInstruction *instruction : destruct_instructions_) { - instruction->~MFDestructInstruction(); + for (DestructInstruction *instruction : destruct_instructions_) { + instruction->~DestructInstruction(); } - for (MFDummyInstruction *instruction : dummy_instructions_) { - instruction->~MFDummyInstruction(); + for (DummyInstruction *instruction : dummy_instructions_) { + instruction->~DummyInstruction(); } - for (MFReturnInstruction *instruction : return_instructions_) { - instruction->~MFReturnInstruction(); + for (ReturnInstruction *instruction : return_instructions_) { + instruction->~ReturnInstruction(); } - for (MFVariable *variable : variables_) { - variable->~MFVariable(); + for (Variable *variable : variables_) { + variable->~Variable(); } } -bool MFProcedure::validate() const +bool Procedure::validate() const { if (entry_ == nullptr) { return false; @@ -280,19 +280,19 @@ bool MFProcedure::validate() const return true; } -bool MFProcedure::validate_all_instruction_pointers_set() const +bool Procedure::validate_all_instruction_pointers_set() const { - for (const MFCallInstruction *instruction : call_instructions_) { + for (const CallInstruction *instruction : call_instructions_) { if (instruction->next_ == nullptr) { return false; } } - for (const MFDestructInstruction *instruction : destruct_instructions_) { + for (const DestructInstruction *instruction : destruct_instructions_) { if (instruction->next_ == nullptr) { return false; } } - for (const MFBranchInstruction *instruction : branch_instructions_) { + for (const BranchInstruction *instruction : branch_instructions_) { if (instruction->branch_true_ == nullptr) { return false; } @@ -300,7 +300,7 @@ bool MFProcedure::validate_all_instruction_pointers_set() const return false; } } - for (const MFDummyInstruction *instruction : dummy_instructions_) { + for (const DummyInstruction *instruction : dummy_instructions_) { if (instruction->next_ == nullptr) { return false; } @@ -308,28 +308,28 @@ bool MFProcedure::validate_all_instruction_pointers_set() const return true; } -bool MFProcedure::validate_all_params_provided() const +bool Procedure::validate_all_params_provided() const { - for (const MFCallInstruction *instruction : call_instructions_) { + for (const CallInstruction *instruction : call_instructions_) { const MultiFunction &fn = instruction->fn(); for (const int param_index : fn.param_indices()) { - const MFParamType param_type = fn.param_type(param_index); - if (param_type.category() == MFParamCategory::SingleOutput) { + const ParamType param_type = fn.param_type(param_index); + if (param_type.category() == ParamCategory::SingleOutput) { /* Single outputs are optional. */ continue; } - const MFVariable *variable = instruction->params_[param_index]; + const Variable *variable = instruction->params_[param_index]; if (variable == nullptr) { return false; } } } - for (const MFBranchInstruction *instruction : branch_instructions_) { + for (const BranchInstruction *instruction : branch_instructions_) { if (instruction->condition_ == nullptr) { return false; } } - for (const MFDestructInstruction *instruction : destruct_instructions_) { + for (const DestructInstruction *instruction : destruct_instructions_) { if (instruction->variable_ == nullptr) { return false; } @@ -337,13 +337,13 @@ bool MFProcedure::validate_all_params_provided() const return true; } -bool MFProcedure::validate_same_variables_in_one_call() const +bool Procedure::validate_same_variables_in_one_call() const { - for (const MFCallInstruction *instruction : call_instructions_) { + for (const CallInstruction *instruction : call_instructions_) { const MultiFunction &fn = *instruction->fn_; for (const int param_index : fn.param_indices()) { - const MFParamType param_type = fn.param_type(param_index); - const MFVariable *variable = instruction->params_[param_index]; + const ParamType param_type = fn.param_type(param_index); + const Variable *variable = instruction->params_[param_index]; if (variable == nullptr) { continue; } @@ -351,17 +351,17 @@ bool MFProcedure::validate_same_variables_in_one_call() const if (other_param_index == param_index) { continue; } - const MFVariable *other_variable = instruction->params_[other_param_index]; + const Variable *other_variable = instruction->params_[other_param_index]; if (other_variable != variable) { continue; } - if (ELEM(param_type.interface_type(), MFParamType::Mutable, MFParamType::Output)) { + if (ELEM(param_type.interface_type(), ParamType::Mutable, ParamType::Output)) { /* When a variable is used as mutable or output parameter, it can only be used once. */ return false; } - const MFParamType other_param_type = fn.param_type(other_param_index); + const ParamType other_param_type = fn.param_type(other_param_index); /* A variable is allowed to be used as input more than once. */ - if (other_param_type.interface_type() != MFParamType::Input) { + if (other_param_type.interface_type() != ParamType::Input) { return false; } } @@ -370,9 +370,9 @@ bool MFProcedure::validate_same_variables_in_one_call() const return true; } -bool MFProcedure::validate_parameters() const +bool Procedure::validate_parameters() const { - Set variables; + Set variables; for (const MFParameter ¶m : params_) { /* One variable cannot be used as multiple parameters. */ if (!variables.add(param.variable)) { @@ -382,45 +382,45 @@ bool MFProcedure::validate_parameters() const return true; } -bool MFProcedure::validate_initialization() const +bool Procedure::validate_initialization() const { /* TODO: Issue warning when it maybe wrongly initialized. */ - for (const MFDestructInstruction *instruction : destruct_instructions_) { - const MFVariable &variable = *instruction->variable_; + for (const DestructInstruction *instruction : destruct_instructions_) { + const Variable &variable = *instruction->variable_; const InitState state = this->find_initialization_state_before_instruction(*instruction, variable); if (!state.can_be_initialized) { return false; } } - for (const MFBranchInstruction *instruction : branch_instructions_) { - const MFVariable &variable = *instruction->condition_; + for (const BranchInstruction *instruction : branch_instructions_) { + const Variable &variable = *instruction->condition_; const InitState state = this->find_initialization_state_before_instruction(*instruction, variable); if (!state.can_be_initialized) { return false; } } - for (const MFCallInstruction *instruction : call_instructions_) { + for (const CallInstruction *instruction : call_instructions_) { const MultiFunction &fn = *instruction->fn_; for (const int param_index : fn.param_indices()) { - const MFParamType param_type = fn.param_type(param_index); + const ParamType param_type = fn.param_type(param_index); /* If the parameter was an unneeded output, it could be null. */ if (!instruction->params_[param_index]) { continue; } - const MFVariable &variable = *instruction->params_[param_index]; + const Variable &variable = *instruction->params_[param_index]; const InitState state = this->find_initialization_state_before_instruction(*instruction, variable); switch (param_type.interface_type()) { - case MFParamType::Input: - case MFParamType::Mutable: { + case ParamType::Input: + case ParamType::Mutable: { if (!state.can_be_initialized) { return false; } break; } - case MFParamType::Output: { + case ParamType::Output: { if (!state.can_be_uninitialized) { return false; } @@ -429,14 +429,14 @@ bool MFProcedure::validate_initialization() const } } } - Set variables_that_should_be_initialized_on_return; + Set variables_that_should_be_initialized_on_return; for (const MFParameter ¶m : params_) { - if (ELEM(param.type, MFParamType::Mutable, MFParamType::Output)) { + if (ELEM(param.type, ParamType::Mutable, ParamType::Output)) { variables_that_should_be_initialized_on_return.add_new(param.variable); } } - for (const MFReturnInstruction *instruction : return_instructions_) { - for (const MFVariable *variable : variables_) { + for (const ReturnInstruction *instruction : return_instructions_) { + for (const Variable *variable : variables_) { const InitState init_state = this->find_initialization_state_before_instruction(*instruction, *variable); if (variables_that_should_be_initialized_on_return.contains(variable)) { @@ -454,8 +454,8 @@ bool MFProcedure::validate_initialization() const return true; } -MFProcedure::InitState MFProcedure::find_initialization_state_before_instruction( - const MFInstruction &target_instruction, const MFVariable &target_variable) const +Procedure::InitState Procedure::find_initialization_state_before_instruction( + const Instruction &target_instruction, const Variable &target_variable) const { InitState state; @@ -463,7 +463,7 @@ MFProcedure::InitState MFProcedure::find_initialization_state_before_instruction bool caller_initialized_variable = false; for (const MFParameter ¶m : params_) { if (param.variable == &target_variable) { - if (ELEM(param.type, MFParamType::Input, MFParamType::Mutable)) { + if (ELEM(param.type, ParamType::Input, ParamType::Mutable)) { caller_initialized_variable = true; break; } @@ -481,30 +481,30 @@ MFProcedure::InitState MFProcedure::find_initialization_state_before_instruction check_entry_instruction(); } - Set checked_instructions; - Stack instructions_to_check; - for (const MFInstructionCursor &cursor : target_instruction.prev_) { + Set checked_instructions; + Stack instructions_to_check; + for (const InstructionCursor &cursor : target_instruction.prev_) { if (cursor.instruction() != nullptr) { instructions_to_check.push(cursor.instruction()); } } while (!instructions_to_check.is_empty()) { - const MFInstruction &instruction = *instructions_to_check.pop(); + const Instruction &instruction = *instructions_to_check.pop(); if (!checked_instructions.add(&instruction)) { /* Skip if the instruction has been checked already. */ continue; } bool state_modified = false; switch (instruction.type_) { - case MFInstructionType::Call: { - const MFCallInstruction &call_instruction = static_cast( + case InstructionType::Call: { + const CallInstruction &call_instruction = static_cast( instruction); const MultiFunction &fn = *call_instruction.fn_; for (const int param_index : fn.param_indices()) { if (call_instruction.params_[param_index] == &target_variable) { - const MFParamType param_type = fn.param_type(param_index); - if (param_type.interface_type() == MFParamType::Output) { + const ParamType param_type = fn.param_type(param_index); + if (param_type.interface_type() == ParamType::Output) { state.can_be_initialized = true; state_modified = true; break; @@ -513,18 +513,18 @@ MFProcedure::InitState MFProcedure::find_initialization_state_before_instruction } break; } - case MFInstructionType::Destruct: { - const MFDestructInstruction &destruct_instruction = - static_cast(instruction); + case InstructionType::Destruct: { + const DestructInstruction &destruct_instruction = static_cast( + instruction); if (destruct_instruction.variable_ == &target_variable) { state.can_be_uninitialized = true; state_modified = true; } break; } - case MFInstructionType::Branch: - case MFInstructionType::Dummy: - case MFInstructionType::Return: { + case InstructionType::Branch: + case InstructionType::Dummy: + case InstructionType::Return: { /* These instruction types don't change the initialization state of variables. */ break; } @@ -534,7 +534,7 @@ MFProcedure::InitState MFProcedure::find_initialization_state_before_instruction if (&instruction == entry_) { check_entry_instruction(); } - for (const MFInstructionCursor &cursor : instruction.prev_) { + for (const InstructionCursor &cursor : instruction.prev_) { if (cursor.instruction() != nullptr) { instructions_to_check.push(cursor.instruction()); } @@ -545,15 +545,15 @@ MFProcedure::InitState MFProcedure::find_initialization_state_before_instruction return state; } -class MFProcedureDotExport { +class ProcedureDotExport { private: - const MFProcedure &procedure_; + const Procedure &procedure_; dot::DirectedGraph digraph_; - Map dot_nodes_by_begin_; - Map dot_nodes_by_end_; + Map dot_nodes_by_begin_; + Map dot_nodes_by_end_; public: - MFProcedureDotExport(const MFProcedure &procedure) : procedure_(procedure) + ProcedureDotExport(const Procedure &procedure) : procedure_(procedure) { } @@ -566,7 +566,7 @@ class MFProcedureDotExport { void create_nodes() { - Vector all_instructions; + Vector all_instructions; auto add_instructions = [&](auto instructions) { all_instructions.extend(instructions.begin(), instructions.end()); }; @@ -576,38 +576,38 @@ class MFProcedureDotExport { add_instructions(procedure_.dummy_instructions_); add_instructions(procedure_.return_instructions_); - Set handled_instructions; + Set handled_instructions; - for (const MFInstruction *representative : all_instructions) { + for (const Instruction *representative : all_instructions) { if (handled_instructions.contains(representative)) { continue; } - Vector block_instructions = this->get_instructions_in_block( + Vector block_instructions = this->get_instructions_in_block( *representative); std::stringstream ss; ss << "<"; - for (const MFInstruction *current : block_instructions) { + for (const Instruction *current : block_instructions) { handled_instructions.add_new(current); switch (current->type()) { - case MFInstructionType::Call: { - this->instruction_to_string(*static_cast(current), ss); + case InstructionType::Call: { + this->instruction_to_string(*static_cast(current), ss); break; } - case MFInstructionType::Destruct: { - this->instruction_to_string(*static_cast(current), ss); + case InstructionType::Destruct: { + this->instruction_to_string(*static_cast(current), ss); break; } - case MFInstructionType::Dummy: { - this->instruction_to_string(*static_cast(current), ss); + case InstructionType::Dummy: { + this->instruction_to_string(*static_cast(current), ss); break; } - case MFInstructionType::Return: { - this->instruction_to_string(*static_cast(current), ss); + case InstructionType::Return: { + this->instruction_to_string(*static_cast(current), ss); break; } - case MFInstructionType::Branch: { - this->instruction_to_string(*static_cast(current), ss); + case InstructionType::Branch: { + this->instruction_to_string(*static_cast(current), ss); break; } } @@ -625,7 +625,7 @@ class MFProcedureDotExport { void create_edges() { auto create_edge = [&](dot::Node &from_node, - const MFInstruction *to_instruction) -> dot::DirectedEdge & { + const Instruction *to_instruction) -> dot::DirectedEdge & { if (to_instruction == nullptr) { dot::Node &to_node = digraph_.new_node("missing"); to_node.set_shape(dot::Attr_shape::Diamond); @@ -636,35 +636,35 @@ class MFProcedureDotExport { }; for (auto item : dot_nodes_by_end_.items()) { - const MFInstruction &from_instruction = *item.key; + const Instruction &from_instruction = *item.key; dot::Node &from_node = *item.value; switch (from_instruction.type()) { - case MFInstructionType::Call: { - const MFInstruction *to_instruction = - static_cast(from_instruction).next(); + case InstructionType::Call: { + const Instruction *to_instruction = + static_cast(from_instruction).next(); create_edge(from_node, to_instruction); break; } - case MFInstructionType::Destruct: { - const MFInstruction *to_instruction = - static_cast(from_instruction).next(); + case InstructionType::Destruct: { + const Instruction *to_instruction = + static_cast(from_instruction).next(); create_edge(from_node, to_instruction); break; } - case MFInstructionType::Dummy: { - const MFInstruction *to_instruction = - static_cast(from_instruction).next(); + case InstructionType::Dummy: { + const Instruction *to_instruction = + static_cast(from_instruction).next(); create_edge(from_node, to_instruction); break; } - case MFInstructionType::Return: { + case InstructionType::Return: { break; } - case MFInstructionType::Branch: { - const MFBranchInstruction &branch_instruction = static_cast( + case InstructionType::Branch: { + const BranchInstruction &branch_instruction = static_cast( from_instruction); - const MFInstruction *to_true_instruction = branch_instruction.branch_true(); - const MFInstruction *to_false_instruction = branch_instruction.branch_false(); + const Instruction *to_true_instruction = branch_instruction.branch_true(); + const Instruction *to_false_instruction = branch_instruction.branch_false(); create_edge(from_node, to_true_instruction).attributes.set("color", "#118811"); create_edge(from_node, to_false_instruction).attributes.set("color", "#881111"); break; @@ -676,22 +676,22 @@ class MFProcedureDotExport { create_edge(entry_node, procedure_.entry()); } - bool has_to_be_block_begin(const MFInstruction &instruction) + bool has_to_be_block_begin(const Instruction &instruction) { if (instruction.prev().size() != 1) { return true; } if (ELEM(instruction.prev()[0].type(), - MFInstructionCursor::Type::Branch, - MFInstructionCursor::Type::Entry)) { + InstructionCursor::Type::Branch, + InstructionCursor::Type::Entry)) { return true; } return false; } - const MFInstruction &get_first_instruction_in_block(const MFInstruction &representative) + const Instruction &get_first_instruction_in_block(const Instruction &representative) { - const MFInstruction *current = &representative; + const Instruction *current = &representative; while (!this->has_to_be_block_begin(*current)) { current = current->prev()[0].instruction(); if (current == &representative) { @@ -702,25 +702,25 @@ class MFProcedureDotExport { return *current; } - const MFInstruction *get_next_instruction_in_block(const MFInstruction &instruction, - const MFInstruction &block_begin) + const Instruction *get_next_instruction_in_block(const Instruction &instruction, + const Instruction &block_begin) { - const MFInstruction *next = nullptr; + const Instruction *next = nullptr; switch (instruction.type()) { - case MFInstructionType::Call: { - next = static_cast(instruction).next(); + case InstructionType::Call: { + next = static_cast(instruction).next(); break; } - case MFInstructionType::Destruct: { - next = static_cast(instruction).next(); + case InstructionType::Destruct: { + next = static_cast(instruction).next(); break; } - case MFInstructionType::Dummy: { - next = static_cast(instruction).next(); + case InstructionType::Dummy: { + next = static_cast(instruction).next(); break; } - case MFInstructionType::Return: - case MFInstructionType::Branch: { + case InstructionType::Return: + case InstructionType::Branch: { break; } } @@ -736,18 +736,18 @@ class MFProcedureDotExport { return next; } - Vector get_instructions_in_block(const MFInstruction &representative) + Vector get_instructions_in_block(const Instruction &representative) { - Vector instructions; - const MFInstruction &begin = this->get_first_instruction_in_block(representative); - for (const MFInstruction *current = &begin; current != nullptr; + Vector instructions; + const Instruction &begin = this->get_first_instruction_in_block(representative); + for (const Instruction *current = &begin; current != nullptr; current = this->get_next_instruction_in_block(*current, begin)) { instructions.append(current); } return instructions; } - void variable_to_string(const MFVariable *variable, std::stringstream &ss) + void variable_to_string(const Variable *variable, std::stringstream &ss) { if (variable == nullptr) { ss << "null"; @@ -765,24 +765,24 @@ class MFProcedureDotExport { ss << name; } - void instruction_to_string(const MFCallInstruction &instruction, std::stringstream &ss) + void instruction_to_string(const CallInstruction &instruction, std::stringstream &ss) { const MultiFunction &fn = instruction.fn(); this->instruction_name_format(fn.debug_name() + ": ", ss); for (const int param_index : fn.param_indices()) { - const MFParamType param_type = fn.param_type(param_index); - const MFVariable *variable = instruction.params()[param_index]; + const ParamType param_type = fn.param_type(param_index); + const Variable *variable = instruction.params()[param_index]; ss << R"()"; switch (param_type.interface_type()) { - case MFParamType::Input: { + case ParamType::Input: { ss << "in"; break; } - case MFParamType::Mutable: { + case ParamType::Mutable: { ss << "mut"; break; } - case MFParamType::Output: { + case ParamType::Output: { ss << "out"; break; } @@ -795,24 +795,24 @@ class MFProcedureDotExport { } } - void instruction_to_string(const MFDestructInstruction &instruction, std::stringstream &ss) + void instruction_to_string(const DestructInstruction &instruction, std::stringstream &ss) { instruction_name_format("Destruct ", ss); variable_to_string(instruction.variable(), ss); } - void instruction_to_string(const MFDummyInstruction & /*instruction*/, std::stringstream &ss) + void instruction_to_string(const DummyInstruction & /*instruction*/, std::stringstream &ss) { instruction_name_format("Dummy ", ss); } - void instruction_to_string(const MFReturnInstruction & /*instruction*/, std::stringstream &ss) + void instruction_to_string(const ReturnInstruction & /*instruction*/, std::stringstream &ss) { instruction_name_format("Return ", ss); Vector outgoing_parameters; for (const ConstMFParameter ¶m : procedure_.params()) { - if (ELEM(param.type, MFParamType::Mutable, MFParamType::Output)) { + if (ELEM(param.type, ParamType::Mutable, ParamType::Output)) { outgoing_parameters.append(param); } } @@ -825,7 +825,7 @@ class MFProcedureDotExport { } } - void instruction_to_string(const MFBranchInstruction &instruction, std::stringstream &ss) + void instruction_to_string(const BranchInstruction &instruction, std::stringstream &ss) { instruction_name_format("Branch ", ss); variable_to_string(instruction.condition(), ss); @@ -837,7 +837,7 @@ class MFProcedureDotExport { ss << "Entry: "; Vector incoming_parameters; for (const ConstMFParameter ¶m : procedure_.params()) { - if (ELEM(param.type, MFParamType::Input, MFParamType::Mutable)) { + if (ELEM(param.type, ParamType::Input, ParamType::Mutable)) { incoming_parameters.append(param); } } @@ -855,10 +855,10 @@ class MFProcedureDotExport { } }; -std::string MFProcedure::to_dot() const +std::string Procedure::to_dot() const { - MFProcedureDotExport dot_export{*this}; + ProcedureDotExport dot_export{*this}; return dot_export.generate(); } -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/intern/multi_function_procedure_builder.cc b/source/blender/functions/intern/multi_function_procedure_builder.cc index 858172e774d..cb4fe2cd1ed 100644 --- a/source/blender/functions/intern/multi_function_procedure_builder.cc +++ b/source/blender/functions/intern/multi_function_procedure_builder.cc @@ -2,65 +2,65 @@ #include "FN_multi_function_procedure_builder.hh" -namespace blender::fn { +namespace blender::fn::multi_function { -void MFProcedureBuilder::add_destruct(MFVariable &variable) +void ProcedureBuilder::add_destruct(Variable &variable) { - MFDestructInstruction &instruction = procedure_->new_destruct_instruction(); + DestructInstruction &instruction = procedure_->new_destruct_instruction(); instruction.set_variable(&variable); this->link_to_cursors(&instruction); - cursors_ = {MFInstructionCursor{instruction}}; + cursors_ = {InstructionCursor{instruction}}; } -void MFProcedureBuilder::add_destruct(Span variables) +void ProcedureBuilder::add_destruct(Span variables) { - for (MFVariable *variable : variables) { + for (Variable *variable : variables) { this->add_destruct(*variable); } } -MFReturnInstruction &MFProcedureBuilder::add_return() +ReturnInstruction &ProcedureBuilder::add_return() { - MFReturnInstruction &instruction = procedure_->new_return_instruction(); + ReturnInstruction &instruction = procedure_->new_return_instruction(); this->link_to_cursors(&instruction); cursors_ = {}; return instruction; } -MFCallInstruction &MFProcedureBuilder::add_call_with_no_variables(const MultiFunction &fn) +CallInstruction &ProcedureBuilder::add_call_with_no_variables(const MultiFunction &fn) { - MFCallInstruction &instruction = procedure_->new_call_instruction(fn); + CallInstruction &instruction = procedure_->new_call_instruction(fn); this->link_to_cursors(&instruction); - cursors_ = {MFInstructionCursor{instruction}}; + cursors_ = {InstructionCursor{instruction}}; return instruction; } -MFCallInstruction &MFProcedureBuilder::add_call_with_all_variables( - const MultiFunction &fn, Span param_variables) +CallInstruction &ProcedureBuilder::add_call_with_all_variables(const MultiFunction &fn, + Span param_variables) { - MFCallInstruction &instruction = this->add_call_with_no_variables(fn); + CallInstruction &instruction = this->add_call_with_no_variables(fn); instruction.set_params(param_variables); return instruction; } -Vector MFProcedureBuilder::add_call(const MultiFunction &fn, - Span input_and_mutable_variables) +Vector ProcedureBuilder::add_call(const MultiFunction &fn, + Span input_and_mutable_variables) { - Vector output_variables; - MFCallInstruction &instruction = this->add_call_with_no_variables(fn); + Vector output_variables; + CallInstruction &instruction = this->add_call_with_no_variables(fn); for (const int param_index : fn.param_indices()) { - const MFParamType param_type = fn.param_type(param_index); + const ParamType param_type = fn.param_type(param_index); switch (param_type.interface_type()) { - case MFParamType::Input: - case MFParamType::Mutable: { - MFVariable *variable = input_and_mutable_variables.first(); + case ParamType::Input: + case ParamType::Mutable: { + Variable *variable = input_and_mutable_variables.first(); instruction.set_param_variable(param_index, variable); input_and_mutable_variables = input_and_mutable_variables.drop_front(1); break; } - case MFParamType::Output: { - MFVariable &variable = procedure_->new_variable(param_type.data_type(), - fn.param_name(param_index)); + case ParamType::Output: { + Variable &variable = procedure_->new_variable(param_type.data_type(), + fn.param_name(param_index)); instruction.set_param_variable(param_index, &variable); output_variables.append(&variable); break; @@ -72,26 +72,26 @@ Vector MFProcedureBuilder::add_call(const MultiFunction &fn, return output_variables; } -MFProcedureBuilder::Branch MFProcedureBuilder::add_branch(MFVariable &condition) +ProcedureBuilder::Branch ProcedureBuilder::add_branch(Variable &condition) { - MFBranchInstruction &instruction = procedure_->new_branch_instruction(); + BranchInstruction &instruction = procedure_->new_branch_instruction(); instruction.set_condition(&condition); this->link_to_cursors(&instruction); /* Clear cursors because this builder ends here. */ cursors_.clear(); Branch branch{*procedure_, *procedure_}; - branch.branch_true.set_cursor(MFInstructionCursor{instruction, true}); - branch.branch_false.set_cursor(MFInstructionCursor{instruction, false}); + branch.branch_true.set_cursor(InstructionCursor{instruction, true}); + branch.branch_false.set_cursor(InstructionCursor{instruction, false}); return branch; } -MFProcedureBuilder::Loop MFProcedureBuilder::add_loop() +ProcedureBuilder::Loop ProcedureBuilder::add_loop() { - MFDummyInstruction &loop_begin = procedure_->new_dummy_instruction(); - MFDummyInstruction &loop_end = procedure_->new_dummy_instruction(); + DummyInstruction &loop_begin = procedure_->new_dummy_instruction(); + DummyInstruction &loop_end = procedure_->new_dummy_instruction(); this->link_to_cursors(&loop_begin); - cursors_ = {MFInstructionCursor{loop_begin}}; + cursors_ = {InstructionCursor{loop_begin}}; Loop loop; loop.begin = &loop_begin; @@ -100,18 +100,18 @@ MFProcedureBuilder::Loop MFProcedureBuilder::add_loop() return loop; } -void MFProcedureBuilder::add_loop_continue(Loop &loop) +void ProcedureBuilder::add_loop_continue(Loop &loop) { this->link_to_cursors(loop.begin); /* Clear cursors because this builder ends here. */ cursors_.clear(); } -void MFProcedureBuilder::add_loop_break(Loop &loop) +void ProcedureBuilder::add_loop_break(Loop &loop) { this->link_to_cursors(loop.end); /* Clear cursors because this builder ends here. */ cursors_.clear(); } -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/intern/multi_function_procedure_executor.cc b/source/blender/functions/intern/multi_function_procedure_executor.cc index f5e25a5fb3c..b25ec3e856b 100644 --- a/source/blender/functions/intern/multi_function_procedure_executor.cc +++ b/source/blender/functions/intern/multi_function_procedure_executor.cc @@ -4,14 +4,14 @@ #include "BLI_stack.hh" -namespace blender::fn { +namespace blender::fn::multi_function { -MFProcedureExecutor::MFProcedureExecutor(const MFProcedure &procedure) : procedure_(procedure) +ProcedureExecutor::ProcedureExecutor(const Procedure &procedure) : procedure_(procedure) { - MFSignatureBuilder builder("Procedure Executor", signature_); + SignatureBuilder builder("Procedure Executor", signature_); for (const ConstMFParameter ¶m : procedure.params()) { - builder.add("Parameter", MFParamType(param.type, param.variable->data_type())); + builder.add("Parameter", ParamType(param.type, param.variable->data_type())); } this->set_signature(&signature_); @@ -236,7 +236,7 @@ class ValueAllocator : NonCopyable, NonMovable { return this->obtain(*vector_array); } - void release_value(VariableValue *value, const MFDataType &data_type) + void release_value(VariableValue *value, const DataType &data_type) { switch (value->type) { case ValueType::GVArray: { @@ -317,7 +317,7 @@ class VariableState : NonCopyable, NonMovable { /* This a non-owning pointer to either span buffer or #GVectorArray or null. */ void *caller_provided_storage_ = nullptr; - void destruct_value(ValueAllocator &value_allocator, const MFDataType &data_type) + void destruct_value(ValueAllocator &value_allocator, const DataType &data_type) { value_allocator.release_value(value_, data_type); value_ = nullptr; @@ -359,7 +359,7 @@ class VariableState : NonCopyable, NonMovable { return tot_initialized_ == 0; } - void add_as_input(MFParamsBuilder ¶ms, IndexMask mask, const MFDataType &data_type) const + void add_as_input(ParamsBuilder ¶ms, IndexMask mask, const DataType &data_type) const { /* Sanity check to make sure that enough values are initialized. */ BLI_assert(mask.size() <= tot_initialized_); @@ -399,7 +399,7 @@ class VariableState : NonCopyable, NonMovable { } void ensure_is_mutable(IndexMask full_mask, - const MFDataType &data_type, + const DataType &data_type, ValueAllocator &value_allocator) { if (value_ != nullptr && ELEM(value_->type, ValueType::Span, ValueType::GVectorArray)) { @@ -409,7 +409,7 @@ class VariableState : NonCopyable, NonMovable { const int array_size = full_mask.min_array_size(); switch (data_type.category()) { - case MFDataType::Single: { + case DataType::Single: { const CPPType &type = data_type.single_type(); VariableValue_Span *new_value = nullptr; if (caller_provided_storage_ == nullptr) { @@ -440,7 +440,7 @@ class VariableState : NonCopyable, NonMovable { value_ = new_value; break; } - case MFDataType::Vector: { + case DataType::Vector: { const CPPType &type = data_type.vector_base_type(); VariableValue_GVectorArray *new_value = nullptr; if (caller_provided_storage_ == nullptr) { @@ -471,10 +471,10 @@ class VariableState : NonCopyable, NonMovable { } } - void add_as_mutable(MFParamsBuilder ¶ms, + void add_as_mutable(ParamsBuilder ¶ms, IndexMask mask, IndexMask full_mask, - const MFDataType &data_type, + const DataType &data_type, ValueAllocator &value_allocator) { /* Sanity check to make sure that enough values are initialized. */ @@ -504,10 +504,10 @@ class VariableState : NonCopyable, NonMovable { } } - void add_as_output(MFParamsBuilder ¶ms, + void add_as_output(ParamsBuilder ¶ms, IndexMask mask, IndexMask full_mask, - const MFDataType &data_type, + const DataType &data_type, ValueAllocator &value_allocator) { /* Sanity check to make sure that enough values are not initialized. */ @@ -538,7 +538,7 @@ class VariableState : NonCopyable, NonMovable { tot_initialized_ += mask.size(); } - void add_as_input__one(MFParamsBuilder ¶ms, const MFDataType &data_type) const + void add_as_input__one(ParamsBuilder ¶ms, const DataType &data_type) const { BLI_assert(this->is_one()); BLI_assert(value_ != nullptr); @@ -571,7 +571,7 @@ class VariableState : NonCopyable, NonMovable { } } - void ensure_is_mutable__one(const MFDataType &data_type, ValueAllocator &value_allocator) + void ensure_is_mutable__one(const DataType &data_type, ValueAllocator &value_allocator) { BLI_assert(this->is_one()); if (value_ != nullptr && ELEM(value_->type, ValueType::OneSingle, ValueType::OneVector)) { @@ -579,7 +579,7 @@ class VariableState : NonCopyable, NonMovable { } switch (data_type.category()) { - case MFDataType::Single: { + case DataType::Single: { const CPPType &type = data_type.single_type(); VariableValue_OneSingle *new_value = value_allocator.obtain_OneSingle(type); if (value_ != nullptr) { @@ -600,7 +600,7 @@ class VariableState : NonCopyable, NonMovable { value_ = new_value; break; } - case MFDataType::Vector: { + case DataType::Vector: { const CPPType &type = data_type.vector_base_type(); VariableValue_OneVector *new_value = value_allocator.obtain_OneVector(type); if (value_ != nullptr) { @@ -624,8 +624,8 @@ class VariableState : NonCopyable, NonMovable { } } - void add_as_mutable__one(MFParamsBuilder ¶ms, - const MFDataType &data_type, + void add_as_mutable__one(ParamsBuilder ¶ms, + const DataType &data_type, ValueAllocator &value_allocator) { BLI_assert(this->is_one()); @@ -653,9 +653,9 @@ class VariableState : NonCopyable, NonMovable { } } - void add_as_output__one(MFParamsBuilder ¶ms, + void add_as_output__one(ParamsBuilder ¶ms, IndexMask mask, - const MFDataType &data_type, + const DataType &data_type, ValueAllocator &value_allocator) { BLI_assert(this->is_one()); @@ -697,7 +697,7 @@ class VariableState : NonCopyable, NonMovable { */ bool destruct(IndexMask mask, IndexMask full_mask, - const MFDataType &data_type, + const DataType &data_type, ValueAllocator &value_allocator) { BLI_assert(value_ != nullptr); @@ -822,14 +822,14 @@ class VariableState : NonCopyable, NonMovable { class VariableStates { private: ValueAllocator value_allocator_; - const MFProcedure &procedure_; - /** The state of every variable, indexed by #MFVariable::index_in_procedure(). */ + const Procedure &procedure_; + /** The state of every variable, indexed by #Variable::index_in_procedure(). */ Array variable_states_; IndexMask full_mask_; public: VariableStates(LinearAllocator<> &linear_allocator, - const MFProcedure &procedure, + const Procedure &procedure, IndexMask full_mask) : value_allocator_(linear_allocator), procedure_(procedure), @@ -843,7 +843,7 @@ class VariableStates { for (const int variable_i : procedure_.variables().index_range()) { VariableState &state = variable_states_[variable_i]; if (state.value_ != nullptr) { - const MFVariable *variable = procedure_.variables()[variable_i]; + const Variable *variable = procedure_.variables()[variable_i]; state.destruct_value(value_allocator_, variable->data_type()); } } @@ -859,13 +859,13 @@ class VariableStates { return full_mask_; } - void add_initial_variable_states(const MFProcedureExecutor &fn, - const MFProcedure &procedure, + void add_initial_variable_states(const ProcedureExecutor &fn, + const Procedure &procedure, MFParams ¶ms) { for (const int param_index : fn.param_indices()) { - MFParamType param_type = fn.param_type(param_index); - const MFVariable *variable = procedure.params()[param_index].variable; + ParamType param_type = fn.param_type(param_index); + const Variable *variable = procedure.params()[param_index].variable; auto add_state = [&](VariableValue *value, bool input_is_initialized, @@ -880,32 +880,32 @@ class VariableStates { }; switch (param_type.category()) { - case MFParamCategory::SingleInput: { + case ParamCategory::SingleInput: { const GVArray &data = params.readonly_single_input(param_index); add_state(value_allocator_.obtain_GVArray(data), true); break; } - case MFParamCategory::VectorInput: { + case ParamCategory::VectorInput: { const GVVectorArray &data = params.readonly_vector_input(param_index); add_state(value_allocator_.obtain_GVVectorArray(data), true); break; } - case MFParamCategory::SingleOutput: { + case ParamCategory::SingleOutput: { GMutableSpan data = params.uninitialized_single_output(param_index); add_state(value_allocator_.obtain_Span_not_owned(data.data()), false, data.data()); break; } - case MFParamCategory::VectorOutput: { + case ParamCategory::VectorOutput: { GVectorArray &data = params.vector_output(param_index); add_state(value_allocator_.obtain_GVectorArray_not_owned(data), false, &data); break; } - case MFParamCategory::SingleMutable: { + case ParamCategory::SingleMutable: { GMutableSpan data = params.single_mutable(param_index); add_state(value_allocator_.obtain_Span_not_owned(data.data()), true, data.data()); break; } - case MFParamCategory::VectorMutable: { + case ParamCategory::VectorMutable: { GVectorArray &data = params.vector_mutable(param_index); add_state(value_allocator_.obtain_GVectorArray_not_owned(data), true, &data); break; @@ -915,21 +915,21 @@ class VariableStates { } void add_as_param(VariableState &variable_state, - MFParamsBuilder ¶ms, - const MFParamType ¶m_type, + ParamsBuilder ¶ms, + const ParamType ¶m_type, const IndexMask &mask) { - const MFDataType data_type = param_type.data_type(); + const DataType data_type = param_type.data_type(); switch (param_type.interface_type()) { - case MFParamType::Input: { + case ParamType::Input: { variable_state.add_as_input(params, mask, data_type); break; } - case MFParamType::Mutable: { + case ParamType::Mutable: { variable_state.add_as_mutable(params, mask, full_mask_, data_type, value_allocator_); break; } - case MFParamType::Output: { + case ParamType::Output: { variable_state.add_as_output(params, mask, full_mask_, data_type, value_allocator_); break; } @@ -937,28 +937,28 @@ class VariableStates { } void add_as_param__one(VariableState &variable_state, - MFParamsBuilder ¶ms, - const MFParamType ¶m_type, + ParamsBuilder ¶ms, + const ParamType ¶m_type, const IndexMask &mask) { - const MFDataType data_type = param_type.data_type(); + const DataType data_type = param_type.data_type(); switch (param_type.interface_type()) { - case MFParamType::Input: { + case ParamType::Input: { variable_state.add_as_input__one(params, data_type); break; } - case MFParamType::Mutable: { + case ParamType::Mutable: { variable_state.add_as_mutable__one(params, data_type, value_allocator_); break; } - case MFParamType::Output: { + case ParamType::Output: { variable_state.add_as_output__one(params, mask, data_type, value_allocator_); break; } } } - void destruct(const MFVariable &variable, const IndexMask &mask) + void destruct(const Variable &variable, const IndexMask &mask) { VariableState &variable_state = this->get_variable_state(variable); if (variable_state.destruct(mask, full_mask_, variable.data_type(), value_allocator_)) { @@ -966,7 +966,7 @@ class VariableStates { } } - VariableState &get_variable_state(const MFVariable &variable) + VariableState &get_variable_state(const Variable &variable) { const int variable_i = variable.index_in_procedure(); VariableState &variable_state = variable_states_[variable_i]; @@ -990,12 +990,12 @@ static bool evaluate_as_one(Span param_variable_states, } static void gather_parameter_variable_states(const MultiFunction &fn, - const MFCallInstruction &instruction, + const CallInstruction &instruction, VariableStates &variable_states, MutableSpan r_param_variable_states) { for (const int param_index : fn.param_indices()) { - const MFVariable *variable = instruction.params()[param_index]; + const Variable *variable = instruction.params()[param_index]; if (variable == nullptr) { r_param_variable_states[param_index] = nullptr; } @@ -1008,12 +1008,12 @@ static void gather_parameter_variable_states(const MultiFunction &fn, static void fill_params__one(const MultiFunction &fn, const IndexMask mask, - MFParamsBuilder ¶ms, + ParamsBuilder ¶ms, VariableStates &variable_states, const Span param_variable_states) { for (const int param_index : fn.param_indices()) { - const MFParamType param_type = fn.param_type(param_index); + const ParamType param_type = fn.param_type(param_index); VariableState *variable_state = param_variable_states[param_index]; if (variable_state == nullptr) { params.add_ignored_single_output(); @@ -1026,12 +1026,12 @@ static void fill_params__one(const MultiFunction &fn, static void fill_params(const MultiFunction &fn, const IndexMask mask, - MFParamsBuilder ¶ms, + ParamsBuilder ¶ms, VariableStates &variable_states, const Span param_variable_states) { for (const int param_index : fn.param_indices()) { - const MFParamType param_type = fn.param_type(param_index); + const ParamType param_type = fn.param_type(param_index); VariableState *variable_state = param_variable_states[param_index]; if (variable_state == nullptr) { params.add_ignored_single_output(); @@ -1042,10 +1042,10 @@ static void fill_params(const MultiFunction &fn, } } -static void execute_call_instruction(const MFCallInstruction &instruction, +static void execute_call_instruction(const CallInstruction &instruction, const IndexMask mask, VariableStates &variable_states, - const MFContext &context) + const Context &context) { const MultiFunction &fn = instruction.fn(); @@ -1056,7 +1056,7 @@ static void execute_call_instruction(const MFCallInstruction &instruction, /* If all inputs to the function are constant, it's enough to call the function only once instead * of for every index. */ if (evaluate_as_one(param_variable_states, mask, variable_states.full_mask())) { - MFParamsBuilder params(fn, 1); + ParamsBuilder params(fn, 1); fill_params__one(fn, mask, params, variable_states, param_variable_states); try { @@ -1068,7 +1068,7 @@ static void execute_call_instruction(const MFCallInstruction &instruction, } } else { - MFParamsBuilder params(fn, &mask); + ParamsBuilder params(fn, &mask); fill_params(fn, mask, params, variable_states, param_variable_states); try { @@ -1098,7 +1098,7 @@ struct InstructionIndices { /** Contains information about the next instruction that should be executed. */ struct NextInstructionInfo { - const MFInstruction *instruction = nullptr; + const Instruction *instruction = nullptr; InstructionIndices indices; IndexMask mask() const @@ -1123,7 +1123,7 @@ class InstructionScheduler { public: InstructionScheduler() = default; - void add_referenced_indices(const MFInstruction &instruction, IndexMask mask) + void add_referenced_indices(const Instruction &instruction, IndexMask mask) { if (mask.is_empty()) { return; @@ -1134,7 +1134,7 @@ class InstructionScheduler { next_instructions_.push({&instruction, std::move(new_indices)}); } - void add_owned_indices(const MFInstruction &instruction, Vector indices) + void add_owned_indices(const Instruction &instruction, Vector indices) { if (indices.is_empty()) { return; @@ -1158,7 +1158,7 @@ class InstructionScheduler { return next_instructions_.peek(); } - void update_instruction_pointer(const MFInstruction &instruction) + void update_instruction_pointer(const Instruction &instruction) { next_instructions_.peek().instruction = &instruction; } @@ -1169,7 +1169,7 @@ class InstructionScheduler { } }; -void MFProcedureExecutor::call(IndexMask full_mask, MFParams params, MFContext context) const +void ProcedureExecutor::call(IndexMask full_mask, MFParams params, Context context) const { BLI_assert(procedure_.validate()); @@ -1186,19 +1186,19 @@ void MFProcedureExecutor::call(IndexMask full_mask, MFParams params, MFContext c /* Loop until all indices got to a return instruction. */ while (!scheduler.is_done()) { const NextInstructionInfo &instr_info = scheduler.peek(); - const MFInstruction &instruction = *instr_info.instruction; + const Instruction &instruction = *instr_info.instruction; switch (instruction.type()) { - case MFInstructionType::Call: { - const MFCallInstruction &call_instruction = static_cast( + case InstructionType::Call: { + const CallInstruction &call_instruction = static_cast( instruction); execute_call_instruction(call_instruction, instr_info.mask(), variable_states, context); scheduler.update_instruction_pointer(*call_instruction.next()); break; } - case MFInstructionType::Branch: { - const MFBranchInstruction &branch_instruction = static_cast( + case InstructionType::Branch: { + const BranchInstruction &branch_instruction = static_cast( instruction); - const MFVariable *condition_var = branch_instruction.condition(); + const Variable *condition_var = branch_instruction.condition(); VariableState &variable_state = variable_states.get_variable_state(*condition_var); IndicesSplitVectors new_indices; @@ -1208,21 +1208,21 @@ void MFProcedureExecutor::call(IndexMask full_mask, MFParams params, MFContext c scheduler.add_owned_indices(*branch_instruction.branch_true(), new_indices[true]); break; } - case MFInstructionType::Destruct: { - const MFDestructInstruction &destruct_instruction = - static_cast(instruction); - const MFVariable *variable = destruct_instruction.variable(); + case InstructionType::Destruct: { + const DestructInstruction &destruct_instruction = static_cast( + instruction); + const Variable *variable = destruct_instruction.variable(); variable_states.destruct(*variable, instr_info.mask()); scheduler.update_instruction_pointer(*destruct_instruction.next()); break; } - case MFInstructionType::Dummy: { - const MFDummyInstruction &dummy_instruction = static_cast( + case InstructionType::Dummy: { + const DummyInstruction &dummy_instruction = static_cast( instruction); scheduler.update_instruction_pointer(*dummy_instruction.next()); break; } - case MFInstructionType::Return: { + case InstructionType::Return: { /* Don't insert the indices back into the scheduler. */ scheduler.pop(); break; @@ -1231,17 +1231,17 @@ void MFProcedureExecutor::call(IndexMask full_mask, MFParams params, MFContext c } for (const int param_index : this->param_indices()) { - const MFParamType param_type = this->param_type(param_index); - const MFVariable *variable = procedure_.params()[param_index].variable; + const ParamType param_type = this->param_type(param_index); + const Variable *variable = procedure_.params()[param_index].variable; VariableState &variable_state = variable_states.get_variable_state(*variable); switch (param_type.interface_type()) { - case MFParamType::Input: { + case ParamType::Input: { /* Input variables must be destructed in the end. */ BLI_assert(variable_state.is_fully_uninitialized(full_mask)); break; } - case MFParamType::Mutable: - case MFParamType::Output: { + case ParamType::Mutable: + case ParamType::Output: { /* Mutable and output variables must be initialized in the end. */ BLI_assert(variable_state.is_fully_initialized(full_mask)); /* Make sure that the data is in the memory provided by the caller. */ @@ -1253,7 +1253,7 @@ void MFProcedureExecutor::call(IndexMask full_mask, MFParams params, MFContext c } } -MultiFunction::ExecutionHints MFProcedureExecutor::get_execution_hints() const +MultiFunction::ExecutionHints ProcedureExecutor::get_execution_hints() const { ExecutionHints hints; hints.allocates_array = true; @@ -1261,4 +1261,4 @@ MultiFunction::ExecutionHints MFProcedureExecutor::get_execution_hints() const return hints; } -} // namespace blender::fn +} // namespace blender::fn::multi_function diff --git a/source/blender/functions/intern/multi_function_procedure_optimization.cc b/source/blender/functions/intern/multi_function_procedure_optimization.cc index 70ea2c0bb1b..0c4261d7ee6 100644 --- a/source/blender/functions/intern/multi_function_procedure_optimization.cc +++ b/source/blender/functions/intern/multi_function_procedure_optimization.cc @@ -2,20 +2,19 @@ #include "FN_multi_function_procedure_optimization.hh" -namespace blender::fn::procedure_optimization { +namespace blender::fn::multi_function::procedure_optimization { -void move_destructs_up(MFProcedure &procedure, MFInstruction &block_end_instr) +void move_destructs_up(Procedure &procedure, Instruction &block_end_instr) { /* A mapping from a variable to its destruct instruction. */ - Map destruct_instructions; - MFInstruction *current_instr = &block_end_instr; + Map destruct_instructions; + Instruction *current_instr = &block_end_instr; while (true) { - MFInstructionType instr_type = current_instr->type(); + InstructionType instr_type = current_instr->type(); switch (instr_type) { - case MFInstructionType::Destruct: { - MFDestructInstruction &destruct_instr = static_cast( - *current_instr); - MFVariable *variable = destruct_instr.variable(); + case InstructionType::Destruct: { + DestructInstruction &destruct_instr = static_cast(*current_instr); + Variable *variable = destruct_instr.variable(); if (variable == nullptr) { continue; } @@ -24,31 +23,31 @@ void move_destructs_up(MFProcedure &procedure, MFInstruction &block_end_instr) destruct_instructions.add(variable, &destruct_instr); break; } - case MFInstructionType::Call: { - MFCallInstruction &call_instr = static_cast(*current_instr); + case InstructionType::Call: { + CallInstruction &call_instr = static_cast(*current_instr); /* For each variable, place the corresponding remembered destruct instruction right after * this call instruction. */ - for (MFVariable *variable : call_instr.params()) { + for (Variable *variable : call_instr.params()) { if (variable == nullptr) { continue; } - MFDestructInstruction *destruct_instr = destruct_instructions.pop_default(variable, - nullptr); + DestructInstruction *destruct_instr = destruct_instructions.pop_default(variable, + nullptr); if (destruct_instr == nullptr) { continue; } /* Unlink destruct instruction from previous position. */ - MFInstruction *after_destruct_instr = destruct_instr->next(); + Instruction *after_destruct_instr = destruct_instr->next(); while (!destruct_instr->prev().is_empty()) { /* Do a copy of the cursor here, because `destruct_instr->prev()` changes when * #set_next is called below. */ - const MFInstructionCursor cursor = destruct_instr->prev()[0]; + const InstructionCursor cursor = destruct_instr->prev()[0]; cursor.set_next(procedure, after_destruct_instr); } /* Insert destruct instruction in new position. */ - MFInstruction *next_instr = call_instr.next(); + Instruction *next_instr = call_instr.next(); call_instr.set_next(destruct_instr); destruct_instr->set_next(next_instr); } @@ -59,12 +58,12 @@ void move_destructs_up(MFProcedure &procedure, MFInstruction &block_end_instr) } } - const Span prev_cursors = current_instr->prev(); + const Span prev_cursors = current_instr->prev(); if (prev_cursors.size() != 1) { /* Stop when there is some branching before this instruction. */ break; } - const MFInstructionCursor &prev_cursor = prev_cursors[0]; + const InstructionCursor &prev_cursor = prev_cursors[0]; current_instr = prev_cursor.instruction(); if (current_instr == nullptr) { /* Stop when there is no previous instruction. E.g. when this is the first instruction. */ @@ -73,4 +72,4 @@ void move_destructs_up(MFProcedure &procedure, MFInstruction &block_end_instr) } } -} // namespace blender::fn::procedure_optimization +} // namespace blender::fn::multi_function::procedure_optimization diff --git a/source/blender/functions/tests/FN_field_test.cc b/source/blender/functions/tests/FN_field_test.cc index 5e3ae5676fc..63058249dfc 100644 --- a/source/blender/functions/tests/FN_field_test.cc +++ b/source/blender/functions/tests/FN_field_test.cc @@ -13,7 +13,7 @@ TEST(field, ConstantFunction) { /* TODO: Figure out how to not use another "FieldOperation(" inside of std::make_shared. */ GField constant_field{std::make_shared( - FieldOperation(std::make_unique>(10), {})), + FieldOperation(std::make_unique>(10), {})), 0}; Array result(4); @@ -104,7 +104,7 @@ TEST(field, InputAndFunction) { GField index_field{std::make_shared()}; - auto add_fn = build_mf::SI2_SO("add", [](int a, int b) { return a + b; }); + auto add_fn = mf::build::SI2_SO("add", [](int a, int b) { return a + b; }); GField output_field{ std::make_shared(FieldOperation(add_fn, {index_field, index_field})), 0}; @@ -127,11 +127,11 @@ TEST(field, TwoFunctions) { GField index_field{std::make_shared()}; - auto add_fn = build_mf::SI2_SO("add", [](int a, int b) { return a + b; }); + auto add_fn = mf::build::SI2_SO("add", [](int a, int b) { return a + b; }); GField add_field{ std::make_shared(FieldOperation(add_fn, {index_field, index_field})), 0}; - auto add_10_fn = build_mf::SI1_SO("add_10", [](int a) { return a + 10; }); + auto add_10_fn = mf::build::SI1_SO("add_10", [](int a) { return a + 10; }); GField result_field{std::make_shared(FieldOperation(add_10_fn, {add_field})), 0}; Array result(10); @@ -149,14 +149,14 @@ TEST(field, TwoFunctions) EXPECT_EQ(result[8], 26); } -class TwoOutputFunction : public MultiFunction { +class TwoOutputFunction : public mf::MultiFunction { private: - MFSignature signature_; + mf::Signature signature_; public: TwoOutputFunction() { - MFSignatureBuilder builder{"Two Outputs", signature_}; + mf::SignatureBuilder builder{"Two Outputs", signature_}; builder.single_input("In1"); builder.single_input("In2"); builder.single_output("Add"); @@ -164,7 +164,7 @@ class TwoOutputFunction : public MultiFunction { this->set_signature(&signature_); } - void call(IndexMask mask, MFParams params, MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &in1 = params.readonly_single_input(0, "In1"); const VArray &in2 = params.readonly_single_input(1, "In2"); @@ -223,7 +223,7 @@ TEST(field, TwoFunctionsTwoOutputs) Field result_field_1{fn, 0}; Field intermediate_field{fn, 1}; - auto add_10_fn = build_mf::SI1_SO("add_10", [](int a) { return a + 10; }); + auto add_10_fn = mf::build::SI1_SO("add_10", [](int a) { return a + 10; }); Field result_field_2{ std::make_shared(FieldOperation(add_10_fn, {intermediate_field})), 0}; @@ -248,7 +248,7 @@ TEST(field, TwoFunctionsTwoOutputs) TEST(field, SameFieldTwice) { GField constant_field{ - std::make_shared(std::make_unique>(10)), 0}; + std::make_shared(std::make_unique>(10)), 0}; FieldContext field_context; IndexMask mask{IndexRange(2)}; @@ -267,7 +267,7 @@ TEST(field, SameFieldTwice) TEST(field, IgnoredOutput) { - static OptionalOutputsFunction fn; + static mf::tests::OptionalOutputsFunction fn; Field field{std::make_shared(fn), 0}; FieldContext field_context; diff --git a/source/blender/functions/tests/FN_multi_function_procedure_test.cc b/source/blender/functions/tests/FN_multi_function_procedure_test.cc index aa8549dad44..6c717756599 100644 --- a/source/blender/functions/tests/FN_multi_function_procedure_test.cc +++ b/source/blender/functions/tests/FN_multi_function_procedure_test.cc @@ -7,7 +7,7 @@ #include "FN_multi_function_procedure_executor.hh" #include "FN_multi_function_test_common.hh" -namespace blender::fn::tests { +namespace blender::fn::multi_function::tests { TEST(multi_function_procedure, ConstantOutput) { @@ -19,10 +19,10 @@ TEST(multi_function_procedure, ConstantOutput) */ CustomMF_Constant constant_fn{5}; - auto add_fn = build_mf::SI2_SO("Add", [](int a, int b) { return a + b; }); + auto add_fn = build::SI2_SO("Add", [](int a, int b) { return a + b; }); - MFProcedure procedure; - MFProcedureBuilder builder{procedure}; + Procedure procedure; + ProcedureBuilder builder{procedure}; auto [var1] = builder.add_call<1>(constant_fn); auto [var2] = builder.add_call<1>(add_fn, {var1, var1}); @@ -32,10 +32,10 @@ TEST(multi_function_procedure, ConstantOutput) EXPECT_TRUE(procedure.validate()); - MFProcedureExecutor executor{procedure}; + ProcedureExecutor executor{procedure}; - MFParamsBuilder params{executor, 2}; - MFContextBuilder context; + ParamsBuilder params{executor, 2}; + ContextBuilder context; Array output_array(2); params.add_uninitialized_single_output(output_array.as_mutable_span()); @@ -56,14 +56,14 @@ TEST(multi_function_procedure, SimpleTest) * } */ - auto add_fn = fn::build_mf::SI2_SO("add", [](int a, int b) { return a + b; }); - auto add_10_fn = fn::build_mf::SM("add_10", [](int &a) { a += 10; }); + auto add_fn = mf::build::SI2_SO("add", [](int a, int b) { return a + b; }); + auto add_10_fn = mf::build::SM("add_10", [](int &a) { a += 10; }); - MFProcedure procedure; - MFProcedureBuilder builder{procedure}; + Procedure procedure; + ProcedureBuilder builder{procedure}; - MFVariable *var1 = &builder.add_single_input_parameter(); - MFVariable *var2 = &builder.add_single_input_parameter(); + Variable *var1 = &builder.add_single_input_parameter(); + Variable *var2 = &builder.add_single_input_parameter(); auto [var3] = builder.add_call<1>(add_fn, {var1, var2}); auto [var4] = builder.add_call<1>(add_fn, {var2, var3}); builder.add_call(add_10_fn, {var4}); @@ -73,10 +73,10 @@ TEST(multi_function_procedure, SimpleTest) EXPECT_TRUE(procedure.validate()); - MFProcedureExecutor executor{procedure}; + ProcedureExecutor executor{procedure}; - MFParamsBuilder params{executor, 3}; - MFContextBuilder context; + ParamsBuilder params{executor, 3}; + ContextBuilder context; Array input_array = {1, 2, 3}; params.add_readonly_single_input(input_array.as_span()); @@ -106,16 +106,16 @@ TEST(multi_function_procedure, BranchTest) * } */ - auto add_10_fn = build_mf::SM("add_10", [](int &a) { a += 10; }); - auto add_100_fn = build_mf::SM("add_100", [](int &a) { a += 100; }); + auto add_10_fn = build::SM("add_10", [](int &a) { a += 10; }); + auto add_100_fn = build::SM("add_100", [](int &a) { a += 100; }); - MFProcedure procedure; - MFProcedureBuilder builder{procedure}; + Procedure procedure; + ProcedureBuilder builder{procedure}; - MFVariable *var1 = &builder.add_single_mutable_parameter(); - MFVariable *var2 = &builder.add_single_input_parameter(); + Variable *var1 = &builder.add_single_mutable_parameter(); + Variable *var2 = &builder.add_single_input_parameter(); - MFProcedureBuilder::Branch branch = builder.add_branch(*var2); + ProcedureBuilder::Branch branch = builder.add_branch(*var2); branch.branch_false.add_call(add_10_fn, {var1}); branch.branch_true.add_call(add_100_fn, {var1}); builder.set_cursor_after_branch(branch); @@ -125,8 +125,8 @@ TEST(multi_function_procedure, BranchTest) EXPECT_TRUE(procedure.validate()); - MFProcedureExecutor procedure_fn{procedure}; - MFParamsBuilder params(procedure_fn, 5); + ProcedureExecutor procedure_fn{procedure}; + ParamsBuilder params(procedure_fn, 5); Array values_a = {1, 5, 3, 6, 2}; Array values_cond = {true, false, true, true, false}; @@ -134,7 +134,7 @@ TEST(multi_function_procedure, BranchTest) params.add_single_mutable(values_a.as_mutable_span()); params.add_readonly_single_input(values_cond.as_span()); - MFContextBuilder context; + ContextBuilder context; procedure_fn.call({1, 2, 3, 4}, params, context); EXPECT_EQ(values_a[0], 1); @@ -153,28 +153,28 @@ TEST(multi_function_procedure, EvaluateOne) */ int tot_evaluations = 0; - const auto add_10_fn = fn::build_mf::SI1_SO("add_10", [&](int a) { + const auto add_10_fn = mf::build::SI1_SO("add_10", [&](int a) { tot_evaluations++; return a + 10; }); - MFProcedure procedure; - MFProcedureBuilder builder{procedure}; + Procedure procedure; + ProcedureBuilder builder{procedure}; - MFVariable *var1 = &builder.add_single_input_parameter(); + Variable *var1 = &builder.add_single_input_parameter(); auto [var2] = builder.add_call<1>(add_10_fn, {var1}); builder.add_destruct(*var1); builder.add_return(); builder.add_output_parameter(*var2); - MFProcedureExecutor procedure_fn{procedure}; - MFParamsBuilder params{procedure_fn, 5}; + ProcedureExecutor procedure_fn{procedure}; + ParamsBuilder params{procedure_fn, 5}; Array values_out = {1, 2, 3, 4, 5}; params.add_readonly_single_input_value(1); params.add_uninitialized_single_output(values_out.as_mutable_span()); - MFContextBuilder context; + ContextBuilder context; procedure_fn.call({0, 1, 3, 4}, params, context); EXPECT_EQ(values_out[0], 11); @@ -205,25 +205,25 @@ TEST(multi_function_procedure, SimpleLoop) CustomMF_Constant const_1_fn{1}; CustomMF_Constant const_0_fn{0}; - auto greater_or_equal_fn = fn::build_mf::SI2_SO( + auto greater_or_equal_fn = mf::build::SI2_SO( "greater or equal", [](int a, int b) { return a >= b; }); - auto double_fn = build_mf::SM("double", [](int &a) { a *= 2; }); - auto add_1000_fn = build_mf::SM("add 1000", [](int &a) { a += 1000; }); - auto add_1_fn = build_mf::SM("add 1", [](int &a) { a += 1; }); + auto double_fn = build::SM("double", [](int &a) { a *= 2; }); + auto add_1000_fn = build::SM("add 1000", [](int &a) { a += 1000; }); + auto add_1_fn = build::SM("add 1", [](int &a) { a += 1; }); - MFProcedure procedure; - MFProcedureBuilder builder{procedure}; + Procedure procedure; + ProcedureBuilder builder{procedure}; - MFVariable *var_count = &builder.add_single_input_parameter("count"); + Variable *var_count = &builder.add_single_input_parameter("count"); auto [var_out] = builder.add_call<1>(const_1_fn); var_out->set_name("out"); auto [var_index] = builder.add_call<1>(const_0_fn); var_index->set_name("index"); - MFProcedureBuilder::Loop loop = builder.add_loop(); + ProcedureBuilder::Loop loop = builder.add_loop(); auto [var_condition] = builder.add_call<1>(greater_or_equal_fn, {var_index, var_count}); var_condition->set_name("condition"); - MFProcedureBuilder::Branch branch = builder.add_branch(*var_condition); + ProcedureBuilder::Branch branch = builder.add_branch(*var_condition); branch.branch_true.add_destruct(*var_condition); branch.branch_true.add_loop_break(loop); branch.branch_false.add_destruct(*var_condition); @@ -239,8 +239,8 @@ TEST(multi_function_procedure, SimpleLoop) EXPECT_TRUE(procedure.validate()); - MFProcedureExecutor procedure_fn{procedure}; - MFParamsBuilder params{procedure_fn, 5}; + ProcedureExecutor procedure_fn{procedure}; + ParamsBuilder params{procedure_fn, 5}; Array counts = {4, 3, 7, 6, 4}; Array results(5, -1); @@ -248,7 +248,7 @@ TEST(multi_function_procedure, SimpleLoop) params.add_readonly_single_input(counts.as_span()); params.add_uninitialized_single_output(results.as_mutable_span()); - MFContextBuilder context; + ContextBuilder context; procedure_fn.call({0, 1, 3, 4}, params, context); EXPECT_EQ(results[0], 1016); @@ -277,11 +277,11 @@ TEST(multi_function_procedure, Vectors) SumVectorFunction sum_elements_fn; CustomMF_Constant constant_5_fn{5}; - MFProcedure procedure; - MFProcedureBuilder builder{procedure}; + Procedure procedure; + ProcedureBuilder builder{procedure}; - MFVariable *var_v1 = &builder.add_input_parameter(MFDataType::ForVector()); - MFVariable *var_v2 = &builder.add_parameter(MFParamType::ForMutableVector(CPPType::get())); + Variable *var_v1 = &builder.add_input_parameter(DataType::ForVector()); + Variable *var_v2 = &builder.add_parameter(ParamType::ForMutableVector(CPPType::get())); builder.add_call(extend_fn, {var_v1, var_v2}); auto [var_constant] = builder.add_call<1>(constant_5_fn); builder.add_call(append_fn, {var_v2, var_constant}); @@ -295,8 +295,8 @@ TEST(multi_function_procedure, Vectors) EXPECT_TRUE(procedure.validate()); - MFProcedureExecutor procedure_fn{procedure}; - MFParamsBuilder params{procedure_fn, 5}; + ProcedureExecutor procedure_fn{procedure}; + ParamsBuilder params{procedure_fn, 5}; Array v1 = {5, 2, 3}; GVectorArray v2{CPPType::get(), 5}; @@ -310,7 +310,7 @@ TEST(multi_function_procedure, Vectors) params.add_vector_mutable(v2); params.add_vector_output(v3); - MFContextBuilder context; + ContextBuilder context; procedure_fn.call({0, 1, 3, 4}, params, context); EXPECT_EQ(v2[0].size(), 6); @@ -338,12 +338,12 @@ TEST(multi_function_procedure, BufferReuse) * } */ - auto add_10_fn = build_mf::SI1_SO("add 10", [](int a) { return a + 10; }); + auto add_10_fn = build::SI1_SO("add 10", [](int a) { return a + 10; }); - MFProcedure procedure; - MFProcedureBuilder builder{procedure}; + Procedure procedure; + ProcedureBuilder builder{procedure}; - MFVariable *var_a = &builder.add_single_input_parameter(); + Variable *var_a = &builder.add_single_input_parameter(); auto [var_b] = builder.add_call<1>(add_10_fn, {var_a}); builder.add_destruct(*var_a); auto [var_c] = builder.add_call<1>(add_10_fn, {var_b}); @@ -359,16 +359,16 @@ TEST(multi_function_procedure, BufferReuse) EXPECT_TRUE(procedure.validate()); - MFProcedureExecutor procedure_fn{procedure}; + ProcedureExecutor procedure_fn{procedure}; Array inputs = {4, 1, 6, 2, 3}; Array results(5, -1); - MFParamsBuilder params{procedure_fn, 5}; + ParamsBuilder params{procedure_fn, 5}; params.add_readonly_single_input(inputs.as_span()); params.add_uninitialized_single_output(results.as_mutable_span()); - MFContextBuilder context; + ContextBuilder context; procedure_fn.call({0, 2, 3, 4}, params, context); EXPECT_EQ(results[0], 54); @@ -380,12 +380,12 @@ TEST(multi_function_procedure, BufferReuse) TEST(multi_function_procedure, OutputBufferReplaced) { - MFProcedure procedure; - MFProcedureBuilder builder{procedure}; + Procedure procedure; + ProcedureBuilder builder{procedure}; const int output_value = 42; CustomMF_GenericConstant constant_fn(CPPType::get(), &output_value, false); - MFVariable &var_o = procedure.new_variable(MFDataType::ForSingle()); + Variable &var_o = procedure.new_variable(DataType::ForSingle()); builder.add_output_parameter(var_o); builder.add_call_with_all_variables(constant_fn, {&var_o}); builder.add_destruct(var_o); @@ -394,13 +394,13 @@ TEST(multi_function_procedure, OutputBufferReplaced) EXPECT_TRUE(procedure.validate()); - MFProcedureExecutor procedure_fn{procedure}; + ProcedureExecutor procedure_fn{procedure}; Array output(3, 0); - fn::MFParamsBuilder params(procedure_fn, output.size()); + mf::ParamsBuilder params(procedure_fn, output.size()); params.add_uninitialized_single_output(output.as_mutable_span()); - fn::MFContextBuilder context; + mf::ContextBuilder context; procedure_fn.call(IndexMask(output.size()), params, context); EXPECT_EQ(output[0], output_value); @@ -408,4 +408,4 @@ TEST(multi_function_procedure, OutputBufferReplaced) EXPECT_EQ(output[2], output_value); } -} // namespace blender::fn::tests +} // namespace blender::fn::multi_function::tests diff --git a/source/blender/functions/tests/FN_multi_function_test.cc b/source/blender/functions/tests/FN_multi_function_test.cc index 5306fe0b20c..f0db195960c 100644 --- a/source/blender/functions/tests/FN_multi_function_test.cc +++ b/source/blender/functions/tests/FN_multi_function_test.cc @@ -6,28 +6,28 @@ #include "FN_multi_function_builder.hh" #include "FN_multi_function_test_common.hh" -namespace blender::fn::tests { +namespace blender::fn::multi_function::tests { namespace { class AddFunction : public MultiFunction { public: AddFunction() { - static MFSignature signature = create_signature(); + static Signature signature = create_signature(); this->set_signature(&signature); } - static MFSignature create_signature() + static Signature create_signature() { - MFSignature signature; - MFSignatureBuilder builder("Add", signature); + Signature signature; + SignatureBuilder builder("Add", signature); builder.single_input("A"); builder.single_input("B"); builder.single_output("Result"); return signature; } - void call(IndexMask mask, MFParams params, MFContext /*context*/) const override + void call(IndexMask mask, MFParams params, Context /*context*/) const override { const VArray &a = params.readonly_single_input(0, "A"); const VArray &b = params.readonly_single_input(1, "B"); @@ -47,12 +47,12 @@ TEST(multi_function, AddFunction) Array input2 = {10, 20, 30}; Array output(3, -1); - MFParamsBuilder params(fn, 3); + ParamsBuilder params(fn, 3); params.add_readonly_single_input(input1.as_span()); params.add_readonly_single_input(input2.as_span()); params.add_uninitialized_single_output(output.as_mutable_span()); - MFContextBuilder context; + ContextBuilder context; fn.call({0, 2}, params, context); @@ -74,11 +74,11 @@ TEST(multi_function, AddPrefixFunction) std::string prefix = "AB"; - MFParamsBuilder params(fn, strings.size()); + ParamsBuilder params(fn, strings.size()); params.add_readonly_single_input(&prefix); params.add_single_mutable(strings.as_mutable_span()); - MFContextBuilder context; + ContextBuilder context; fn.call({0, 2, 3}, params, context); @@ -96,11 +96,11 @@ TEST(multi_function, CreateRangeFunction) GVectorArray_TypedMutableRef ranges_ref{ranges}; Array sizes = {3, 0, 6, 1, 4}; - MFParamsBuilder params(fn, ranges.size()); + ParamsBuilder params(fn, ranges.size()); params.add_readonly_single_input(sizes.as_span()); params.add_vector_output(ranges); - MFContextBuilder context; + ContextBuilder context; fn.call({0, 1, 2, 3}, params, context); @@ -128,11 +128,11 @@ TEST(multi_function, GenericAppendFunction) vectors_ref.append(2, 6); Array values = {5, 7, 3, 1}; - MFParamsBuilder params(fn, vectors.size()); + ParamsBuilder params(fn, vectors.size()); params.add_vector_mutable(vectors); params.add_readonly_single_input(values.as_span()); - MFContextBuilder context; + ContextBuilder context; fn.call(IndexRange(vectors.size()), params, context); @@ -156,10 +156,10 @@ TEST(multi_function, CustomMF_Constant) Array outputs(4, 0); - MFParamsBuilder params(fn, outputs.size()); + ParamsBuilder params(fn, outputs.size()); params.add_uninitialized_single_output(outputs.as_mutable_span()); - MFContextBuilder context; + ContextBuilder context; fn.call({0, 2, 3}, params, context); @@ -176,10 +176,10 @@ TEST(multi_function, CustomMF_GenericConstant) Array outputs(4, 0); - MFParamsBuilder params(fn, outputs.size()); + ParamsBuilder params(fn, outputs.size()); params.add_uninitialized_single_output(outputs.as_mutable_span()); - MFContextBuilder context; + ContextBuilder context; fn.call({0, 1, 2}, params, context); @@ -197,10 +197,10 @@ TEST(multi_function, CustomMF_GenericConstantArray) GVectorArray vector_array{CPPType::get(), 4}; GVectorArray_TypedMutableRef vector_array_ref{vector_array}; - MFParamsBuilder params(fn, vector_array.size()); + ParamsBuilder params(fn, vector_array.size()); params.add_vector_output(vector_array); - MFContextBuilder context; + ContextBuilder context; fn.call({1, 2, 3}, params, context); @@ -220,20 +220,20 @@ TEST(multi_function, IgnoredOutputs) { OptionalOutputsFunction fn; { - MFParamsBuilder params(fn, 10); + ParamsBuilder params(fn, 10); params.add_ignored_single_output("Out 1"); params.add_ignored_single_output("Out 2"); - MFContextBuilder context; + ContextBuilder context; fn.call(IndexRange(10), params, context); } { Array results_1(10); Array results_2(10, NoInitialization()); - MFParamsBuilder params(fn, 10); + ParamsBuilder params(fn, 10); params.add_uninitialized_single_output(results_1.as_mutable_span(), "Out 1"); params.add_uninitialized_single_output(results_2.as_mutable_span(), "Out 2"); - MFContextBuilder context; + ContextBuilder context; fn.call(IndexRange(10), params, context); EXPECT_EQ(results_1[0], 5); @@ -244,4 +244,4 @@ TEST(multi_function, IgnoredOutputs) } } // namespace -} // namespace blender::fn::tests +} // namespace blender::fn::multi_function::tests diff --git a/source/blender/functions/tests/FN_multi_function_test_common.hh b/source/blender/functions/tests/FN_multi_function_test_common.hh index 82433723760..2014e4fc74e 100644 --- a/source/blender/functions/tests/FN_multi_function_test_common.hh +++ b/source/blender/functions/tests/FN_multi_function_test_common.hh @@ -2,26 +2,26 @@ #include "FN_multi_function.hh" -namespace blender::fn::tests { +namespace blender::fn::multi_function::tests { class AddPrefixFunction : public MultiFunction { public: AddPrefixFunction() { - static MFSignature signature = create_signature(); + static Signature signature = create_signature(); this->set_signature(&signature); } - static MFSignature create_signature() + static Signature create_signature() { - MFSignature signature; - MFSignatureBuilder builder{"Add Prefix", signature}; + Signature signature; + SignatureBuilder builder{"Add Prefix", signature}; builder.single_input("Prefix"); builder.single_mutable("Strings"); return signature; } - void call(IndexMask mask, MFParams params, MFContext /*context*/) const override + void call(IndexMask mask, MFParams params, Context /*context*/) const override { const VArray &prefixes = params.readonly_single_input(0, "Prefix"); MutableSpan strings = params.single_mutable(1, "Strings"); @@ -36,20 +36,20 @@ class CreateRangeFunction : public MultiFunction { public: CreateRangeFunction() { - static MFSignature signature = create_signature(); + static Signature signature = create_signature(); this->set_signature(&signature); } - static MFSignature create_signature() + static Signature create_signature() { - MFSignature signature; - MFSignatureBuilder builder{"Create Range", signature}; + Signature signature; + SignatureBuilder builder{"Create Range", signature}; builder.single_input("Size"); builder.vector_output("Range"); return signature; } - void call(IndexMask mask, MFParams params, MFContext /*context*/) const override + void call(IndexMask mask, MFParams params, Context /*context*/) const override { const VArray &sizes = params.readonly_single_input(0, "Size"); GVectorArray &ranges = params.vector_output(1, "Range"); @@ -65,18 +65,18 @@ class CreateRangeFunction : public MultiFunction { class GenericAppendFunction : public MultiFunction { private: - MFSignature signature_; + Signature signature_; public: GenericAppendFunction(const CPPType &type) { - MFSignatureBuilder builder{"Append", signature_}; + SignatureBuilder builder{"Append", signature_}; builder.vector_mutable("Vector", type); builder.single_input("Value", type); this->set_signature(&signature_); } - void call(IndexMask mask, MFParams params, MFContext /*context*/) const override + void call(IndexMask mask, MFParams params, Context /*context*/) const override { GVectorArray &vectors = params.vector_mutable(0, "Vector"); const GVArray &values = params.readonly_single_input(1, "Value"); @@ -94,20 +94,20 @@ class ConcatVectorsFunction : public MultiFunction { public: ConcatVectorsFunction() { - static MFSignature signature = create_signature(); + static Signature signature = create_signature(); this->set_signature(&signature); } - static MFSignature create_signature() + static Signature create_signature() { - MFSignature signature; - MFSignatureBuilder builder{"Concat Vectors", signature}; + Signature signature; + SignatureBuilder builder{"Concat Vectors", signature}; builder.vector_mutable("A"); builder.vector_input("B"); return signature; } - void call(IndexMask mask, MFParams params, MFContext /*context*/) const override + void call(IndexMask mask, MFParams params, Context /*context*/) const override { GVectorArray &a = params.vector_mutable(0); const GVVectorArray &b = params.readonly_vector_input(1); @@ -119,20 +119,20 @@ class AppendFunction : public MultiFunction { public: AppendFunction() { - static MFSignature signature = create_signature(); + static Signature signature = create_signature(); this->set_signature(&signature); } - static MFSignature create_signature() + static Signature create_signature() { - MFSignature signature; - MFSignatureBuilder builder{"Append", signature}; + Signature signature; + SignatureBuilder builder{"Append", signature}; builder.vector_mutable("Vector"); builder.single_input("Value"); return signature; } - void call(IndexMask mask, MFParams params, MFContext /*context*/) const override + void call(IndexMask mask, MFParams params, Context /*context*/) const override { GVectorArray_TypedMutableRef vectors = params.vector_mutable(0); const VArray &values = params.readonly_single_input(1); @@ -147,20 +147,20 @@ class SumVectorFunction : public MultiFunction { public: SumVectorFunction() { - static MFSignature signature = create_signature(); + static Signature signature = create_signature(); this->set_signature(&signature); } - static MFSignature create_signature() + static Signature create_signature() { - MFSignature signature; - MFSignatureBuilder builder{"Sum Vectors", signature}; + Signature signature; + SignatureBuilder builder{"Sum Vectors", signature}; builder.vector_input("Vector"); builder.single_output("Sum"); return signature; } - void call(IndexMask mask, MFParams params, MFContext /*context*/) const override + void call(IndexMask mask, MFParams params, Context /*context*/) const override { const VVectorArray &vectors = params.readonly_vector_input(0); MutableSpan sums = params.uninitialized_single_output(1); @@ -179,20 +179,20 @@ class OptionalOutputsFunction : public MultiFunction { public: OptionalOutputsFunction() { - static MFSignature signature = create_signature(); + static Signature signature = create_signature(); this->set_signature(&signature); } - static MFSignature create_signature() + static Signature create_signature() { - MFSignature signature; - MFSignatureBuilder builder{"Optional Outputs", signature}; + Signature signature; + SignatureBuilder builder{"Optional Outputs", signature}; builder.single_output("Out 1"); builder.single_output("Out 2"); return signature; } - void call(IndexMask mask, MFParams params, MFContext /*context*/) const override + void call(IndexMask mask, MFParams params, Context /*context*/) const override { if (params.single_output_is_required(0, "Out 1")) { MutableSpan values = params.uninitialized_single_output(0, "Out 1"); @@ -205,4 +205,4 @@ class OptionalOutputsFunction : public MultiFunction { } }; -} // namespace blender::fn::tests +} // namespace blender::fn::multi_function::tests diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc index 358c7ced488..eff67a5d1ba 100644 --- a/source/blender/geometry/intern/resample_curves.cc +++ b/source/blender/geometry/intern/resample_curves.cc @@ -17,10 +17,10 @@ namespace blender::geometry { static fn::Field get_count_input_max_one(const fn::Field &count_field) { - static auto max_one_fn = fn::build_mf::SI1_SO( + static auto max_one_fn = mf::build::SI1_SO( "Clamp Above One", [](int value) { return std::max(1, value); }, - fn::build_mf::exec_presets::AllSpanOrSingle()); + mf::build::exec_presets::AllSpanOrSingle()); auto clamp_op = std::make_shared( fn::FieldOperation(max_one_fn, {count_field})); @@ -29,7 +29,7 @@ static fn::Field get_count_input_max_one(const fn::Field &count_field) static fn::Field get_count_input_from_length(const fn::Field &length_field) { - static auto get_count_fn = fn::build_mf::SI2_SO( + static auto get_count_fn = mf::build::SI2_SO( "Length Input to Count", [](const float curve_length, const float sample_length) { /* Find the number of sampled segments by dividing the total length by @@ -37,7 +37,7 @@ static fn::Field get_count_input_from_length(const fn::Field &length const int count = int(curve_length / sample_length) + 1; return std::max(1, count); }, - fn::build_mf::exec_presets::AllSpanOrSingle()); + mf::build::exec_presets::AllSpanOrSingle()); auto get_count_op = std::make_shared(fn::FieldOperation( get_count_fn, diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index af95ad6db18..2c5e02fbbe5 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -125,17 +125,16 @@ using blender::fn::ValueOrFieldCPPType; using blender::nodes::FieldInferencingInterface; using blender::nodes::GeoNodeExecParams; using blender::nodes::InputSocketFieldType; -using blender::nodes::geo_eval_log::GeoModifierLog; -using blender::threading::EnumerableThreadSpecific; -using namespace blender::fn::multi_function_types; using blender::nodes::geo_eval_log::GeometryAttributeInfo; using blender::nodes::geo_eval_log::GeometryInfoLog; +using blender::nodes::geo_eval_log::GeoModifierLog; using blender::nodes::geo_eval_log::GeoNodeLog; using blender::nodes::geo_eval_log::GeoTreeLog; using blender::nodes::geo_eval_log::NamedAttributeUsage; using blender::nodes::geo_eval_log::NodeWarning; using blender::nodes::geo_eval_log::NodeWarningType; using blender::nodes::geo_eval_log::ValueLog; +using blender::threading::EnumerableThreadSpecific; static void initData(ModifierData *md) { diff --git a/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh b/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh index 7f49d067061..793798c4974 100644 --- a/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh +++ b/source/blender/nodes/NOD_geometry_nodes_lazy_function.hh @@ -31,8 +31,8 @@ struct Depsgraph; namespace blender::nodes { -namespace lf = fn::lazy_function; using lf::LazyFunction; +using mf::MultiFunction; /** * Data that is passed into geometry nodes evaluation from the modifier. diff --git a/source/blender/nodes/NOD_math_functions.hh b/source/blender/nodes/NOD_math_functions.hh index b7637fb2c66..0641cef318e 100644 --- a/source/blender/nodes/NOD_math_functions.hh +++ b/source/blender/nodes/NOD_math_functions.hh @@ -51,8 +51,8 @@ inline bool try_dispatch_float_math_fl_to_fl(const int operation, Callback &&cal return false; } - static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); - static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized(); + static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle(); + static auto exec_preset_slow = mf::build::exec_presets::Materialized(); /* This is just an utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -118,8 +118,8 @@ inline bool try_dispatch_float_math_fl_fl_to_fl(const int operation, Callback && return false; } - static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); - static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized(); + static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle(); + static auto exec_preset_slow = mf::build::exec_presets::Materialized(); /* This is just an utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -180,21 +180,21 @@ inline bool try_dispatch_float_math_fl_fl_fl_to_fl(const int operation, Callback switch (operation) { case NODE_MATH_MULTIPLY_ADD: - return dispatch(fn::build_mf::exec_presets::AllSpanOrSingle(), + return dispatch(mf::build::exec_presets::AllSpanOrSingle(), [](float a, float b, float c) { return a * b + c; }); case NODE_MATH_COMPARE: - return dispatch(fn::build_mf::exec_presets::SomeSpanOrSingle<0, 1>(), + return dispatch(mf::build::exec_presets::SomeSpanOrSingle<0, 1>(), [](float a, float b, float c) -> float { return ((a == b) || (fabsf(a - b) <= fmaxf(c, FLT_EPSILON))) ? 1.0f : 0.0f; }); case NODE_MATH_SMOOTH_MIN: - return dispatch(fn::build_mf::exec_presets::SomeSpanOrSingle<0, 1>(), + return dispatch(mf::build::exec_presets::SomeSpanOrSingle<0, 1>(), [](float a, float b, float c) { return smoothminf(a, b, c); }); case NODE_MATH_SMOOTH_MAX: - return dispatch(fn::build_mf::exec_presets::SomeSpanOrSingle<0, 1>(), + return dispatch(mf::build::exec_presets::SomeSpanOrSingle<0, 1>(), [](float a, float b, float c) { return -smoothminf(-a, -b, c); }); case NODE_MATH_WRAP: - return dispatch(fn::build_mf::exec_presets::SomeSpanOrSingle<0>(), + return dispatch(mf::build::exec_presets::SomeSpanOrSingle<0>(), [](float a, float b, float c) { return wrapf(a, b, c); }); } return false; @@ -214,8 +214,8 @@ inline bool try_dispatch_float_math_fl3_fl3_to_fl3(const NodeVectorMathOperation return false; } - static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); - static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized(); + static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle(); + static auto exec_preset_slow = mf::build::exec_presets::Materialized(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -269,7 +269,7 @@ inline bool try_dispatch_float_math_fl3_fl3_to_fl(const NodeVectorMathOperation return false; } - static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); + static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -302,8 +302,8 @@ inline bool try_dispatch_float_math_fl3_fl3_fl3_to_fl3(const NodeVectorMathOpera return false; } - static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); - static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized(); + static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle(); + static auto exec_preset_slow = mf::build::exec_presets::Materialized(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -341,7 +341,7 @@ inline bool try_dispatch_float_math_fl3_fl3_fl_to_fl3(const NodeVectorMathOperat return false; } - static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized(); + static auto exec_preset_slow = mf::build::exec_presets::Materialized(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -373,7 +373,7 @@ inline bool try_dispatch_float_math_fl3_to_fl(const NodeVectorMathOperation oper return false; } - static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); + static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -402,7 +402,7 @@ inline bool try_dispatch_float_math_fl3_fl_to_fl3(const NodeVectorMathOperation return false; } - static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); + static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { @@ -433,8 +433,8 @@ inline bool try_dispatch_float_math_fl3_to_fl3(const NodeVectorMathOperation ope return false; } - static auto exec_preset_fast = fn::build_mf::exec_presets::AllSpanOrSingle(); - static auto exec_preset_slow = fn::build_mf::exec_presets::Materialized(); + static auto exec_preset_fast = mf::build::exec_presets::AllSpanOrSingle(); + static auto exec_preset_slow = mf::build::exec_presets::Materialized(); /* This is just a utility function to keep the individual cases smaller. */ auto dispatch = [&](auto exec_preset, auto math_function) -> bool { diff --git a/source/blender/nodes/NOD_multi_function.hh b/source/blender/nodes/NOD_multi_function.hh index 676bf03927e..e47842507d2 100644 --- a/source/blender/nodes/NOD_multi_function.hh +++ b/source/blender/nodes/NOD_multi_function.hh @@ -8,8 +8,6 @@ namespace blender::nodes { -using namespace fn::multi_function_types; - class NodeMultiFunctions; /** @@ -19,8 +17,8 @@ class NodeMultiFunctionBuilder : NonCopyable, NonMovable { private: const bNode &node_; const bNodeTree &tree_; - std::shared_ptr owned_built_fn_; - const MultiFunction *built_fn_ = nullptr; + std::shared_ptr owned_built_fn_; + const mf::MultiFunction *built_fn_ = nullptr; friend NodeMultiFunctions; @@ -31,8 +29,8 @@ class NodeMultiFunctionBuilder : NonCopyable, NonMovable { * Assign a multi-function for the current node. The input and output parameters of the function * have to match the available sockets in the node. */ - void set_matching_fn(const MultiFunction *fn); - void set_matching_fn(const MultiFunction &fn); + void set_matching_fn(const mf::MultiFunction *fn); + void set_matching_fn(const mf::MultiFunction &fn); /** * Utility method for creating and assigning a multi-function when it can't have a static @@ -50,8 +48,8 @@ class NodeMultiFunctionBuilder : NonCopyable, NonMovable { class NodeMultiFunctions { public: struct Item { - const MultiFunction *fn = nullptr; - std::shared_ptr owned_fn; + const mf::MultiFunction *fn = nullptr; + std::shared_ptr owned_fn; }; private: @@ -82,12 +80,12 @@ inline const bNodeTree &NodeMultiFunctionBuilder::tree() return tree_; } -inline void NodeMultiFunctionBuilder::set_matching_fn(const MultiFunction *fn) +inline void NodeMultiFunctionBuilder::set_matching_fn(const mf::MultiFunction *fn) { built_fn_ = fn; } -inline void NodeMultiFunctionBuilder::set_matching_fn(const MultiFunction &fn) +inline void NodeMultiFunctionBuilder::set_matching_fn(const mf::MultiFunction &fn) { built_fn_ = &fn; } diff --git a/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc b/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc index 21290220ff6..21e60f127ce 100644 --- a/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc +++ b/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc @@ -133,7 +133,7 @@ static void align_rotations_fixed_pivot(IndexMask mask, }); } -class MF_AlignEulerToVector : public fn::MultiFunction { +class MF_AlignEulerToVector : public mf::MultiFunction { private: int main_axis_mode_; int pivot_axis_mode_; @@ -142,14 +142,14 @@ class MF_AlignEulerToVector : public fn::MultiFunction { MF_AlignEulerToVector(int main_axis_mode, int pivot_axis_mode) : main_axis_mode_(main_axis_mode), pivot_axis_mode_(pivot_axis_mode) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Align Euler to Vector", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Align Euler to Vector", signature}; builder.single_input("Rotation"); builder.single_input("Factor"); builder.single_input("Vector"); @@ -158,7 +158,7 @@ class MF_AlignEulerToVector : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &input_rotations = params.readonly_single_input(0, "Rotation"); const VArray &factors = params.readonly_single_input(1, "Factor"); diff --git a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc index 02e15fe7853..188a6d916bf 100644 --- a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc +++ b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc @@ -65,26 +65,26 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) } } -static const fn::MultiFunction *get_multi_function(const bNode &bnode) +static const mf::MultiFunction *get_multi_function(const bNode &bnode) { - static auto exec_preset = fn::build_mf::exec_presets::AllSpanOrSingle(); - static auto and_fn = fn::build_mf::SI2_SO( + static auto exec_preset = mf::build::exec_presets::AllSpanOrSingle(); + static auto and_fn = mf::build::SI2_SO( "And", [](bool a, bool b) { return a && b; }, exec_preset); - static auto or_fn = fn::build_mf::SI2_SO( + static auto or_fn = mf::build::SI2_SO( "Or", [](bool a, bool b) { return a || b; }, exec_preset); - static auto not_fn = fn::build_mf::SI1_SO( + static auto not_fn = mf::build::SI1_SO( "Not", [](bool a) { return !a; }, exec_preset); - static auto nand_fn = fn::build_mf::SI2_SO( + static auto nand_fn = mf::build::SI2_SO( "Not And", [](bool a, bool b) { return !(a && b); }, exec_preset); - static auto nor_fn = fn::build_mf::SI2_SO( + static auto nor_fn = mf::build::SI2_SO( "Nor", [](bool a, bool b) { return !(a || b); }, exec_preset); - static auto xnor_fn = fn::build_mf::SI2_SO( + static auto xnor_fn = mf::build::SI2_SO( "Equal", [](bool a, bool b) { return a == b; }, exec_preset); - static auto xor_fn = fn::build_mf::SI2_SO( + static auto xor_fn = mf::build::SI2_SO( "Not Equal", [](bool a, bool b) { return a != b; }, exec_preset); - static auto imply_fn = fn::build_mf::SI2_SO( + static auto imply_fn = mf::build::SI2_SO( "Imply", [](bool a, bool b) { return !a || b; }, exec_preset); - static auto nimply_fn = fn::build_mf::SI2_SO( + static auto nimply_fn = mf::build::SI2_SO( "Subtract", [](bool a, bool b) { return a && !b; }, exec_preset); switch (bnode.custom1) { @@ -114,7 +114,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode) static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { - const fn::MultiFunction *fn = get_multi_function(builder.node()); + const mf::MultiFunction *fn = get_multi_function(builder.node()); builder.set_matching_fn(fn); } diff --git a/source/blender/nodes/function/nodes/node_fn_combine_color.cc b/source/blender/nodes/function/nodes/node_fn_combine_color.cc index 9b395767ec3..ec1d03125e2 100644 --- a/source/blender/nodes/function/nodes/node_fn_combine_color.cc +++ b/source/blender/nodes/function/nodes/node_fn_combine_color.cc @@ -49,20 +49,20 @@ static void node_init(bNodeTree * /*tree*/, bNode *node) node->storage = data; } -static const fn::MultiFunction *get_multi_function(const bNode &bnode) +static const mf::MultiFunction *get_multi_function(const bNode &bnode) { const NodeCombSepColor &storage = node_storage(bnode); - static auto rgba_fn = fn::build_mf::SI4_SO( + static auto rgba_fn = mf::build::SI4_SO( "RGB", [](float r, float g, float b, float a) { return ColorGeometry4f(r, g, b, a); }); - static auto hsva_fn = fn::build_mf::SI4_SO( + static auto hsva_fn = mf::build::SI4_SO( "HSV", [](float h, float s, float v, float a) { ColorGeometry4f r_color; hsv_to_rgb(h, s, v, &r_color.r, &r_color.g, &r_color.b); r_color.a = a; return r_color; }); - static auto hsla_fn = fn::build_mf::SI4_SO( + static auto hsla_fn = mf::build::SI4_SO( "HSL", [](float h, float s, float l, float a) { ColorGeometry4f color; hsl_to_rgb(h, s, l, &color.r, &color.g, &color.b); @@ -85,7 +85,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode) static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { - const fn::MultiFunction *fn = get_multi_function(builder.node()); + const mf::MultiFunction *fn = get_multi_function(builder.node()); builder.set_matching_fn(fn); } diff --git a/source/blender/nodes/function/nodes/node_fn_compare.cc b/source/blender/nodes/function/nodes/node_fn_compare.cc index e272880fe4b..62cfaf369a0 100644 --- a/source/blender/nodes/function/nodes/node_fn_compare.cc +++ b/source/blender/nodes/function/nodes/node_fn_compare.cc @@ -164,45 +164,45 @@ static float component_average(float3 a) return (a.x + a.y + a.z) / 3.0f; } -static const fn::MultiFunction *get_multi_function(const bNode &node) +static const mf::MultiFunction *get_multi_function(const bNode &node) { const NodeFunctionCompare *data = (NodeFunctionCompare *)node.storage; - static auto exec_preset_all = fn::build_mf::exec_presets::AllSpanOrSingle(); - static auto exec_preset_first_two = fn::build_mf::exec_presets::SomeSpanOrSingle<0, 1>(); + static auto exec_preset_all = mf::build::exec_presets::AllSpanOrSingle(); + static auto exec_preset_first_two = mf::build::exec_presets::SomeSpanOrSingle<0, 1>(); switch (data->data_type) { case SOCK_FLOAT: switch (data->operation) { case NODE_COMPARE_LESS_THAN: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Less Than", [](float a, float b) { return a < b; }, exec_preset_all); return &fn; } case NODE_COMPARE_LESS_EQUAL: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Less Equal", [](float a, float b) { return a <= b; }, exec_preset_all); return &fn; } case NODE_COMPARE_GREATER_THAN: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Greater Than", [](float a, float b) { return a > b; }, exec_preset_all); return &fn; } case NODE_COMPARE_GREATER_EQUAL: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Greater Equal", [](float a, float b) { return a >= b; }, exec_preset_all); return &fn; } case NODE_COMPARE_EQUAL: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Equal", [](float a, float b, float epsilon) { return std::abs(a - b) <= epsilon; }, exec_preset_first_two); return &fn; } case NODE_COMPARE_NOT_EQUAL: - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Not Equal", [](float a, float b, float epsilon) { return std::abs(a - b) > epsilon; }, exec_preset_first_two); @@ -212,32 +212,32 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case SOCK_INT: switch (data->operation) { case NODE_COMPARE_LESS_THAN: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Less Than", [](int a, int b) { return a < b; }, exec_preset_all); return &fn; } case NODE_COMPARE_LESS_EQUAL: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Less Equal", [](int a, int b) { return a <= b; }, exec_preset_all); return &fn; } case NODE_COMPARE_GREATER_THAN: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Greater Than", [](int a, int b) { return a > b; }, exec_preset_all); return &fn; } case NODE_COMPARE_GREATER_EQUAL: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Greater Equal", [](int a, int b) { return a >= b; }, exec_preset_all); return &fn; } case NODE_COMPARE_EQUAL: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Equal", [](int a, int b) { return a == b; }, exec_preset_all); return &fn; } case NODE_COMPARE_NOT_EQUAL: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Not Equal", [](int a, int b) { return a != b; }, exec_preset_all); return &fn; } @@ -248,35 +248,35 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_COMPARE_LESS_THAN: switch (data->mode) { case NODE_COMPARE_MODE_AVERAGE: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Less Than - Average", [](float3 a, float3 b) { return component_average(a) < component_average(b); }, exec_preset_all); return &fn; } case NODE_COMPARE_MODE_DOT_PRODUCT: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Less Than - Dot Product", [](float3 a, float3 b, float comp) { return math::dot(a, b) < comp; }, exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_DIRECTION: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Less Than - Direction", [](float3 a, float3 b, float angle) { return angle_v3v3(a, b) < angle; }, exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_ELEMENT: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Less Than - Element-wise", [](float3 a, float3 b) { return a.x < b.x && a.y < b.y && a.z < b.z; }, exec_preset_all); return &fn; } case NODE_COMPARE_MODE_LENGTH: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Less Than - Length", [](float3 a, float3 b) { return math::length(a) < math::length(b); }, exec_preset_all); @@ -287,35 +287,35 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_COMPARE_LESS_EQUAL: switch (data->mode) { case NODE_COMPARE_MODE_AVERAGE: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Less Equal - Average", [](float3 a, float3 b) { return component_average(a) <= component_average(b); }, exec_preset_all); return &fn; } case NODE_COMPARE_MODE_DOT_PRODUCT: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Less Equal - Dot Product", [](float3 a, float3 b, float comp) { return math::dot(a, b) <= comp; }, exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_DIRECTION: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Less Equal - Direction", [](float3 a, float3 b, float angle) { return angle_v3v3(a, b) <= angle; }, exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_ELEMENT: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Less Equal - Element-wise", [](float3 a, float3 b) { return a.x <= b.x && a.y <= b.y && a.z <= b.z; }, exec_preset_all); return &fn; } case NODE_COMPARE_MODE_LENGTH: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Less Equal - Length", [](float3 a, float3 b) { return math::length(a) <= math::length(b); }, exec_preset_all); @@ -326,35 +326,35 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_COMPARE_GREATER_THAN: switch (data->mode) { case NODE_COMPARE_MODE_AVERAGE: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Greater Than - Average", [](float3 a, float3 b) { return component_average(a) > component_average(b); }, exec_preset_all); return &fn; } case NODE_COMPARE_MODE_DOT_PRODUCT: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Greater Than - Dot Product", [](float3 a, float3 b, float comp) { return math::dot(a, b) > comp; }, exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_DIRECTION: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Greater Than - Direction", [](float3 a, float3 b, float angle) { return angle_v3v3(a, b) > angle; }, exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_ELEMENT: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Greater Than - Element-wise", [](float3 a, float3 b) { return a.x > b.x && a.y > b.y && a.z > b.z; }, exec_preset_all); return &fn; } case NODE_COMPARE_MODE_LENGTH: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Greater Than - Length", [](float3 a, float3 b) { return math::length(a) > math::length(b); }, exec_preset_all); @@ -365,35 +365,35 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_COMPARE_GREATER_EQUAL: switch (data->mode) { case NODE_COMPARE_MODE_AVERAGE: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Greater Equal - Average", [](float3 a, float3 b) { return component_average(a) >= component_average(b); }, exec_preset_all); return &fn; } case NODE_COMPARE_MODE_DOT_PRODUCT: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Greater Equal - Dot Product", [](float3 a, float3 b, float comp) { return math::dot(a, b) >= comp; }, exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_DIRECTION: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Greater Equal - Direction", [](float3 a, float3 b, float angle) { return angle_v3v3(a, b) >= angle; }, exec_preset_first_two); return &fn; } case NODE_COMPARE_MODE_ELEMENT: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Greater Equal - Element-wise", [](float3 a, float3 b) { return a.x >= b.x && a.y >= b.y && a.z >= b.z; }, exec_preset_all); return &fn; } case NODE_COMPARE_MODE_LENGTH: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Greater Equal - Length", [](float3 a, float3 b) { return math::length(a) >= math::length(b); }, exec_preset_all); @@ -404,7 +404,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_COMPARE_EQUAL: switch (data->mode) { case NODE_COMPARE_MODE_AVERAGE: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Equal - Average", [](float3 a, float3 b, float epsilon) { return abs(component_average(a) - component_average(b)) <= epsilon; @@ -413,7 +413,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) return &fn; } case NODE_COMPARE_MODE_DOT_PRODUCT: { - static auto fn = fn::build_mf::SI4_SO( + static auto fn = mf::build::SI4_SO( "Equal - Dot Product", [](float3 a, float3 b, float comp, float epsilon) { return abs(math::dot(a, b) - comp) <= epsilon; @@ -422,7 +422,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) return &fn; } case NODE_COMPARE_MODE_DIRECTION: { - static auto fn = fn::build_mf::SI4_SO( + static auto fn = mf::build::SI4_SO( "Equal - Direction", [](float3 a, float3 b, float angle, float epsilon) { return abs(angle_v3v3(a, b) - angle) <= epsilon; @@ -431,7 +431,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) return &fn; } case NODE_COMPARE_MODE_ELEMENT: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Equal - Element-wise", [](float3 a, float3 b, float epsilon) { return abs(a.x - b.x) <= epsilon && abs(a.y - b.y) <= epsilon && @@ -441,7 +441,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) return &fn; } case NODE_COMPARE_MODE_LENGTH: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Equal - Length", [](float3 a, float3 b, float epsilon) { return abs(math::length(a) - math::length(b)) <= epsilon; @@ -454,7 +454,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_COMPARE_NOT_EQUAL: switch (data->mode) { case NODE_COMPARE_MODE_AVERAGE: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Not Equal - Average", [](float3 a, float3 b, float epsilon) { return abs(component_average(a) - component_average(b)) > epsilon; @@ -463,7 +463,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) return &fn; } case NODE_COMPARE_MODE_DOT_PRODUCT: { - static auto fn = fn::build_mf::SI4_SO( + static auto fn = mf::build::SI4_SO( "Not Equal - Dot Product", [](float3 a, float3 b, float comp, float epsilon) { return abs(math::dot(a, b) - comp) >= epsilon; @@ -472,7 +472,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) return &fn; } case NODE_COMPARE_MODE_DIRECTION: { - static auto fn = fn::build_mf::SI4_SO( + static auto fn = mf::build::SI4_SO( "Not Equal - Direction", [](float3 a, float3 b, float angle, float epsilon) { return abs(angle_v3v3(a, b) - angle) > epsilon; @@ -481,7 +481,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) return &fn; } case NODE_COMPARE_MODE_ELEMENT: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Not Equal - Element-wise", [](float3 a, float3 b, float epsilon) { return abs(a.x - b.x) > epsilon || abs(a.y - b.y) > epsilon || @@ -491,7 +491,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) return &fn; } case NODE_COMPARE_MODE_LENGTH: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Not Equal - Length", [](float3 a, float3 b, float epsilon) { return abs(math::length(a) - math::length(b)) > epsilon; @@ -506,7 +506,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case SOCK_RGBA: switch (data->operation) { case NODE_COMPARE_EQUAL: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Equal", [](ColorGeometry4f a, ColorGeometry4f b, float epsilon) { return abs(a.r - b.r) <= epsilon && abs(a.g - b.g) <= epsilon && @@ -516,7 +516,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) return &fn; } case NODE_COMPARE_NOT_EQUAL: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Not Equal", [](ColorGeometry4f a, ColorGeometry4f b, float epsilon) { return abs(a.r - b.r) > epsilon || abs(a.g - b.g) > epsilon || @@ -526,7 +526,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) return &fn; } case NODE_COMPARE_COLOR_BRIGHTER: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Brighter", [](ColorGeometry4f a, ColorGeometry4f b) { return rgb_to_grayscale(a) > rgb_to_grayscale(b); @@ -535,7 +535,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) return &fn; } case NODE_COMPARE_COLOR_DARKER: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Darker", [](ColorGeometry4f a, ColorGeometry4f b) { return rgb_to_grayscale(a) < rgb_to_grayscale(b); @@ -548,12 +548,12 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case SOCK_STRING: switch (data->operation) { case NODE_COMPARE_EQUAL: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Equal", [](std::string a, std::string b) { return a == b; }); return &fn; } case NODE_COMPARE_NOT_EQUAL: { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( "Not Equal", [](std::string a, std::string b) { return a != b; }); return &fn; } @@ -565,7 +565,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { - const fn::MultiFunction *fn = get_multi_function(builder.node()); + const mf::MultiFunction *fn = get_multi_function(builder.node()); builder.set_matching_fn(fn); } diff --git a/source/blender/nodes/function/nodes/node_fn_float_to_int.cc b/source/blender/nodes/function/nodes/node_fn_float_to_int.cc index de68b00874f..ea149eddfc1 100644 --- a/source/blender/nodes/function/nodes/node_fn_float_to_int.cc +++ b/source/blender/nodes/function/nodes/node_fn_float_to_int.cc @@ -36,16 +36,16 @@ static void node_label(const bNodeTree * /*tree*/, const bNode *node, char *labe BLI_strncpy(label, IFACE_(name), maxlen); } -static const fn::MultiFunction *get_multi_function(const bNode &bnode) +static const mf::MultiFunction *get_multi_function(const bNode &bnode) { - static auto exec_preset = fn::build_mf::exec_presets::AllSpanOrSingle(); - static auto round_fn = fn::build_mf::SI1_SO( + static auto exec_preset = mf::build::exec_presets::AllSpanOrSingle(); + static auto round_fn = mf::build::SI1_SO( "Round", [](float a) { return int(round(a)); }, exec_preset); - static auto floor_fn = fn::build_mf::SI1_SO( + static auto floor_fn = mf::build::SI1_SO( "Floor", [](float a) { return int(floor(a)); }, exec_preset); - static auto ceil_fn = fn::build_mf::SI1_SO( + static auto ceil_fn = mf::build::SI1_SO( "Ceiling", [](float a) { return int(ceil(a)); }, exec_preset); - static auto trunc_fn = fn::build_mf::SI1_SO( + static auto trunc_fn = mf::build::SI1_SO( "Truncate", [](float a) { return int(trunc(a)); }, exec_preset); switch (static_cast(bnode.custom1)) { @@ -65,7 +65,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode) static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { - const fn::MultiFunction *fn = get_multi_function(builder.node()); + const mf::MultiFunction *fn = get_multi_function(builder.node()); builder.set_matching_fn(fn); } diff --git a/source/blender/nodes/function/nodes/node_fn_input_bool.cc b/source/blender/nodes/function/nodes/node_fn_input_bool.cc index e9d04beb71e..31167ea43fa 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_bool.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_bool.cc @@ -24,7 +24,7 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { const bNode &bnode = builder.node(); NodeInputBool *node_storage = static_cast(bnode.storage); - builder.construct_and_set_matching_fn>(node_storage->boolean); + builder.construct_and_set_matching_fn>(node_storage->boolean); } static void node_init(bNodeTree * /*tree*/, bNode *node) diff --git a/source/blender/nodes/function/nodes/node_fn_input_color.cc b/source/blender/nodes/function/nodes/node_fn_input_color.cc index bf12eeba5d8..30a3bcf29ab 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_color.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_color.cc @@ -25,7 +25,7 @@ static void node_build_multi_function(blender::nodes::NodeMultiFunctionBuilder & const bNode &bnode = builder.node(); NodeInputColor *node_storage = static_cast(bnode.storage); blender::ColorGeometry4f color = (ColorGeometry4f)node_storage->color; - builder.construct_and_set_matching_fn>(color); + builder.construct_and_set_matching_fn>(color); } static void node_init(bNodeTree * /*tree*/, bNode *node) diff --git a/source/blender/nodes/function/nodes/node_fn_input_int.cc b/source/blender/nodes/function/nodes/node_fn_input_int.cc index 1ecafc370d3..a42407c620b 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_int.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_int.cc @@ -24,7 +24,7 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { const bNode &bnode = builder.node(); NodeInputInt *node_storage = static_cast(bnode.storage); - builder.construct_and_set_matching_fn>(node_storage->integer); + builder.construct_and_set_matching_fn>(node_storage->integer); } static void node_init(bNodeTree * /*tree*/, bNode *node) diff --git a/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc b/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc index fab8d13ffcb..7ccd6f3d87f 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc @@ -10,24 +10,24 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_output(N_("Tab")); } -class MF_SpecialCharacters : public fn::MultiFunction { +class MF_SpecialCharacters : public mf::MultiFunction { public: MF_SpecialCharacters() { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Special Characters", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Special Characters", signature}; builder.single_output("Line Break"); builder.single_output("Tab"); return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { MutableSpan lb = params.uninitialized_single_output(0, "Line Break"); MutableSpan tab = params.uninitialized_single_output(1, "Tab"); diff --git a/source/blender/nodes/function/nodes/node_fn_input_string.cc b/source/blender/nodes/function/nodes/node_fn_input_string.cc index 3d13e5c2b44..ea007c21d53 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_string.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_string.cc @@ -23,7 +23,7 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder) const bNode &bnode = builder.node(); NodeInputString *node_storage = static_cast(bnode.storage); std::string string = std::string((node_storage->string) ? node_storage->string : ""); - builder.construct_and_set_matching_fn>(std::move(string)); + builder.construct_and_set_matching_fn>(std::move(string)); } static void node_init(bNodeTree * /*tree*/, bNode *node) diff --git a/source/blender/nodes/function/nodes/node_fn_input_vector.cc b/source/blender/nodes/function/nodes/node_fn_input_vector.cc index d5f2f98641f..084eb3372d5 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_vector.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_vector.cc @@ -25,7 +25,7 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder) const bNode &bnode = builder.node(); NodeInputVector *node_storage = static_cast(bnode.storage); float3 vector(node_storage->vector); - builder.construct_and_set_matching_fn>(vector); + builder.construct_and_set_matching_fn>(vector); } static void node_init(bNodeTree * /*tree*/, bNode *node) diff --git a/source/blender/nodes/function/nodes/node_fn_random_value.cc b/source/blender/nodes/function/nodes/node_fn_random_value.cc index 1dfd8074349..df90c2103cc 100644 --- a/source/blender/nodes/function/nodes/node_fn_random_value.cc +++ b/source/blender/nodes/function/nodes/node_fn_random_value.cc @@ -141,7 +141,7 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder) switch (data_type) { case CD_PROP_FLOAT3: { - static auto fn = fn::build_mf::SI4_SO( + static auto fn = mf::build::SI4_SO( "Random Vector", [](float3 min_value, float3 max_value, int id, int seed) -> float3 { const float x = noise::hash_to_float(seed, id, 0); @@ -149,23 +149,23 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder) const float z = noise::hash_to_float(seed, id, 2); return float3(x, y, z) * (max_value - min_value) + min_value; }, - fn::build_mf::exec_presets::SomeSpanOrSingle<2>()); + mf::build::exec_presets::SomeSpanOrSingle<2>()); builder.set_matching_fn(fn); break; } case CD_PROP_FLOAT: { - static auto fn = fn::build_mf::SI4_SO( + static auto fn = mf::build::SI4_SO( "Random Float", [](float min_value, float max_value, int id, int seed) -> float { const float value = noise::hash_to_float(seed, id); return value * (max_value - min_value) + min_value; }, - fn::build_mf::exec_presets::SomeSpanOrSingle<2>()); + mf::build::exec_presets::SomeSpanOrSingle<2>()); builder.set_matching_fn(fn); break; } case CD_PROP_INT32: { - static auto fn = fn::build_mf::SI4_SO( + static auto fn = mf::build::SI4_SO( "Random Int", [](int min_value, int max_value, int id, int seed) -> int { const float value = noise::hash_to_float(id, seed); @@ -173,17 +173,17 @@ static void node_build_multi_function(NodeMultiFunctionBuilder &builder) * distribution for the first and last values (See T93591). */ return floor(value * (max_value + 1 - min_value) + min_value); }, - fn::build_mf::exec_presets::SomeSpanOrSingle<2>()); + mf::build::exec_presets::SomeSpanOrSingle<2>()); builder.set_matching_fn(fn); break; } case CD_PROP_BOOL: { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Random Bool", [](float probability, int id, int seed) -> bool { return noise::hash_to_float(id, seed) <= probability; }, - fn::build_mf::exec_presets::SomeSpanOrSingle<1>()); + mf::build::exec_presets::SomeSpanOrSingle<1>()); builder.set_matching_fn(fn); break; } diff --git a/source/blender/nodes/function/nodes/node_fn_replace_string.cc b/source/blender/nodes/function/nodes/node_fn_replace_string.cc index 3b941018c6c..061380bd1a7 100644 --- a/source/blender/nodes/function/nodes/node_fn_replace_string.cc +++ b/source/blender/nodes/function/nodes/node_fn_replace_string.cc @@ -30,12 +30,10 @@ static std::string replace_all(const StringRefNull str, static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { - static auto substring_fn = - fn::build_mf::SI3_SO( - "Replace", - [](const std::string &str, const std::string &find, const std::string &replace) { - return replace_all(str, find, replace); - }); + static auto substring_fn = mf::build::SI3_SO( + "Replace", [](const std::string &str, const std::string &find, const std::string &replace) { + return replace_all(str, find, replace); + }); builder.set_matching_fn(&substring_fn); } diff --git a/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc b/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc index 0cdb876edb3..6cc3677df1f 100644 --- a/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc +++ b/source/blender/nodes/function/nodes/node_fn_rotate_euler.cc @@ -52,9 +52,9 @@ static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) uiItemR(layout, ptr, "space", UI_ITEM_R_EXPAND, nullptr, ICON_NONE); } -static const fn::MultiFunction *get_multi_function(const bNode &bnode) +static const mf::MultiFunction *get_multi_function(const bNode &bnode) { - static auto obj_euler_rot = fn::build_mf::SI2_SO( + static auto obj_euler_rot = mf::build::SI2_SO( "Rotate Euler by Euler/Object", [](const float3 &input, const float3 &rotation) { float input_mat[3][3]; eul_to_mat3(input_mat, input); @@ -66,7 +66,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode) mat3_to_eul(result, mat_res); return result; }); - static auto obj_AA_rot = fn::build_mf::SI3_SO( + static auto obj_AA_rot = mf::build::SI3_SO( "Rotate Euler by AxisAngle/Object", [](const float3 &input, const float3 &axis, float angle) { float input_mat[3][3]; @@ -79,7 +79,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode) mat3_to_eul(result, mat_res); return result; }); - static auto local_euler_rot = fn::build_mf::SI2_SO( + static auto local_euler_rot = mf::build::SI2_SO( "Rotate Euler by Euler/Local", [](const float3 &input, const float3 &rotation) { float input_mat[3][3]; eul_to_mat3(input_mat, input); @@ -91,7 +91,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode) mat3_to_eul(result, mat_res); return result; }); - static auto local_AA_rot = fn::build_mf::SI3_SO( + static auto local_AA_rot = mf::build::SI3_SO( "Rotate Euler by AxisAngle/Local", [](const float3 &input, const float3 &axis, float angle) { float input_mat[3][3]; eul_to_mat3(input_mat, input); @@ -107,12 +107,12 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode) short space = bnode.custom2; if (type == FN_NODE_ROTATE_EULER_TYPE_AXIS_ANGLE) { return space == FN_NODE_ROTATE_EULER_SPACE_OBJECT ? - static_cast(&obj_AA_rot) : + static_cast(&obj_AA_rot) : &local_AA_rot; } if (type == FN_NODE_ROTATE_EULER_TYPE_EULER) { return space == FN_NODE_ROTATE_EULER_SPACE_OBJECT ? - static_cast(&obj_euler_rot) : + static_cast(&obj_euler_rot) : &local_euler_rot; } BLI_assert_unreachable(); @@ -121,7 +121,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &bnode) static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { - const fn::MultiFunction *fn = get_multi_function(builder.node()); + const mf::MultiFunction *fn = get_multi_function(builder.node()); builder.set_matching_fn(fn); } diff --git a/source/blender/nodes/function/nodes/node_fn_separate_color.cc b/source/blender/nodes/function/nodes/node_fn_separate_color.cc index bb663fb4427..c717a9de080 100644 --- a/source/blender/nodes/function/nodes/node_fn_separate_color.cc +++ b/source/blender/nodes/function/nodes/node_fn_separate_color.cc @@ -37,18 +37,18 @@ static void node_init(bNodeTree * /*tree*/, bNode *node) node->storage = data; } -class SeparateRGBAFunction : public fn::MultiFunction { +class SeparateRGBAFunction : public mf::MultiFunction { public: SeparateRGBAFunction() { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Separate Color", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Separate Color", signature}; builder.single_input("Color"); builder.single_output("Red"); builder.single_output("Green"); @@ -57,7 +57,7 @@ class SeparateRGBAFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &colors = params.readonly_single_input(0, "Color"); @@ -99,18 +99,18 @@ class SeparateRGBAFunction : public fn::MultiFunction { } }; -class SeparateHSVAFunction : public fn::MultiFunction { +class SeparateHSVAFunction : public mf::MultiFunction { public: SeparateHSVAFunction() { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Separate Color", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Separate Color", signature}; builder.single_input("Color"); builder.single_output("Hue"); builder.single_output("Saturation"); @@ -119,7 +119,7 @@ class SeparateHSVAFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &colors = params.readonly_single_input(0, "Color"); @@ -140,18 +140,18 @@ class SeparateHSVAFunction : public fn::MultiFunction { } }; -class SeparateHSLAFunction : public fn::MultiFunction { +class SeparateHSLAFunction : public mf::MultiFunction { public: SeparateHSLAFunction() { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Separate Color", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Separate Color", signature}; builder.single_input("Color"); builder.single_output("Hue"); builder.single_output("Saturation"); @@ -160,7 +160,7 @@ class SeparateHSLAFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &colors = params.readonly_single_input(0, "Color"); diff --git a/source/blender/nodes/function/nodes/node_fn_slice_string.cc b/source/blender/nodes/function/nodes/node_fn_slice_string.cc index 3785a6e74b3..522e5639433 100644 --- a/source/blender/nodes/function/nodes/node_fn_slice_string.cc +++ b/source/blender/nodes/function/nodes/node_fn_slice_string.cc @@ -16,7 +16,7 @@ static void node_declare(NodeDeclarationBuilder &b) static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { - static auto slice_fn = fn::build_mf::SI3_SO( + static auto slice_fn = mf::build::SI3_SO( "Slice", [](const std::string &str, int a, int b) { const int len = BLI_strlen_utf8(str.c_str()); const int start = BLI_str_utf8_offset_from_index(str.c_str(), std::clamp(a, 0, len)); diff --git a/source/blender/nodes/function/nodes/node_fn_string_length.cc b/source/blender/nodes/function/nodes/node_fn_string_length.cc index 6ced713f8f4..06012be4900 100644 --- a/source/blender/nodes/function/nodes/node_fn_string_length.cc +++ b/source/blender/nodes/function/nodes/node_fn_string_length.cc @@ -16,7 +16,7 @@ static void node_declare(NodeDeclarationBuilder &b) static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { - static auto str_len_fn = fn::build_mf::SI1_SO( + static auto str_len_fn = mf::build::SI1_SO( "String Length", [](const std::string &a) { return BLI_strlen_utf8(a.c_str()); }); builder.set_matching_fn(&str_len_fn); } diff --git a/source/blender/nodes/function/nodes/node_fn_value_to_string.cc b/source/blender/nodes/function/nodes/node_fn_value_to_string.cc index 0b542fc8405..16f5d717644 100644 --- a/source/blender/nodes/function/nodes/node_fn_value_to_string.cc +++ b/source/blender/nodes/function/nodes/node_fn_value_to_string.cc @@ -14,7 +14,7 @@ static void node_declare(NodeDeclarationBuilder &b) static void node_build_multi_function(NodeMultiFunctionBuilder &builder) { - static auto to_str_fn = fn::build_mf::SI2_SO( + static auto to_str_fn = mf::build::SI2_SO( "Value To String", [](float a, int b) { std::stringstream stream; stream << std::fixed << std::setprecision(std::max(0, b)) << a; diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc index 4fb5889a057..46c9f8c8805 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc @@ -201,7 +201,7 @@ static void sample_indices_and_factors_to_compressed(const Span accumulat * Given an array of accumulated lengths, find the segment indices that * sample lengths lie on, and how far along the segment they are. */ -class SampleFloatSegmentsFunction : public fn::MultiFunction { +class SampleFloatSegmentsFunction : public mf::MultiFunction { private: Array accumulated_lengths_; GeometryNodeCurveSampleMode length_mode_; @@ -211,14 +211,14 @@ class SampleFloatSegmentsFunction : public fn::MultiFunction { const GeometryNodeCurveSampleMode length_mode) : accumulated_lengths_(std::move(accumulated_lengths)), length_mode_(length_mode) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Sample Curve Index", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Sample Curve Index", signature}; builder.single_input("Length"); builder.single_output("Curve Index"); @@ -226,7 +226,7 @@ class SampleFloatSegmentsFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArraySpan lengths = params.readonly_single_input(0, "Length"); MutableSpan indices = params.uninitialized_single_output(1, "Curve Index"); @@ -238,7 +238,7 @@ class SampleFloatSegmentsFunction : public fn::MultiFunction { } }; -class SampleCurveFunction : public fn::MultiFunction { +class SampleCurveFunction : public mf::MultiFunction { private: /** * The function holds a geometry set instead of curves or a curve component reference in order @@ -249,7 +249,7 @@ class SampleCurveFunction : public fn::MultiFunction { GField src_field_; GeometryNodeCurveSampleMode length_mode_; - fn::MFSignature signature_; + mf::Signature signature_; std::optional source_context_; std::unique_ptr source_evaluator_; @@ -266,10 +266,10 @@ class SampleCurveFunction : public fn::MultiFunction { this->evaluate_source(); } - fn::MFSignature create_signature() + mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Sample Curve", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Sample Curve", signature}; builder.single_input("Curve Index"); builder.single_input("Length"); builder.single_output("Position"); @@ -279,7 +279,7 @@ class SampleCurveFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { MutableSpan sampled_positions = params.uninitialized_single_output_if_required( 2, "Position"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index bbb63babde4..db410cd1d4b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -1325,10 +1325,10 @@ static void node_geo_exec(GeoNodeExecParams params) /* Create a combined field from the offset and the scale so the field evaluator * can take care of the multiplication and to simplify each extrude function. */ - static auto multiply_fn = fn::build_mf::SI2_SO( + static auto multiply_fn = mf::build::SI2_SO( "Scale", [](const float3 &offset, const float scale) { return offset * scale; }, - fn::build_mf::exec_presets::AllSpanOrSingle()); + mf::build::exec_presets::AllSpanOrSingle()); std::shared_ptr multiply_op = std::make_shared( FieldOperation(multiply_fn, {std::move(offset_field), std::move(scale_field)})); const Field final_offset{std::move(multiply_op)}; diff --git a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc index 1fed3136ee1..102ab492e6b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc @@ -45,7 +45,7 @@ static void node_init(bNodeTree * /*tree*/, bNode *node) node->storage = tex; } -class ImageFieldsFunction : public fn::MultiFunction { +class ImageFieldsFunction : public mf::MultiFunction { private: const int8_t interpolation_; const int8_t extension_; @@ -64,7 +64,7 @@ class ImageFieldsFunction : public fn::MultiFunction { image_(image), image_user_(image_user) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); image_buffer_ = BKE_image_acquire_ibuf(&image_, &image_user_, &image_lock_); @@ -91,10 +91,10 @@ class ImageFieldsFunction : public fn::MultiFunction { BKE_image_release_ibuf(&image_, image_buffer_, image_lock_); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"ImageFunction", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"ImageFunction", signature}; builder.single_input("Vector"); builder.single_output("Color"); builder.single_output("Alpha"); @@ -319,7 +319,7 @@ class ImageFieldsFunction : public fn::MultiFunction { } } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &vectors = params.readonly_single_input(0, "Vector"); MutableSpan r_color = params.uninitialized_single_output( diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc index c8100ea4c82..f6ed43d3e20 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc @@ -121,10 +121,10 @@ static void node_geo_exec(GeoNodeExecParams params) /* Use another multi-function operation to make sure the input radius is greater than zero. * TODO: Use mutable multi-function once that is supported. */ - static auto max_zero_fn = fn::build_mf::SI1_SO( + static auto max_zero_fn = mf::build::SI1_SO( __func__, [](float value) { return std::max(0.0f, value); }, - fn::build_mf::exec_presets::AllSpanOrSingle()); + mf::build::exec_presets::AllSpanOrSingle()); auto max_zero_op = std::make_shared( FieldOperation(max_zero_fn, {std::move(radius)})); Field positive_radius(std::move(max_zero_op), 0); diff --git a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc index 9655df2ef8e..b8d7586391e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc @@ -129,7 +129,7 @@ static bool calculate_pointcloud_proximity(const VArray &positions, return true; } -class ProximityFunction : public fn::MultiFunction { +class ProximityFunction : public mf::MultiFunction { private: GeometrySet target_; GeometryNodeProximityTargetType type_; @@ -138,21 +138,21 @@ class ProximityFunction : public fn::MultiFunction { ProximityFunction(GeometrySet target, GeometryNodeProximityTargetType type) : target_(std::move(target)), type_(type) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Geometry Proximity", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Geometry Proximity", signature}; builder.single_input("Source Position"); builder.single_output("Position"); builder.single_output("Distance"); return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &src_positions = params.readonly_single_input(0, "Source Position"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc index 85e545271ec..a3277b8e3b9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc @@ -202,7 +202,7 @@ static void raycast_to_mesh(IndexMask mask, } } -class RaycastFunction : public fn::MultiFunction { +class RaycastFunction : public mf::MultiFunction { private: GeometrySet target_; GeometryNodeRaycastMapMode mapping_; @@ -217,7 +217,7 @@ class RaycastFunction : public fn::MultiFunction { * the field inputs for better performance. */ const eAttrDomain domain_ = ATTR_DOMAIN_CORNER; - fn::MFSignature signature_; + mf::Signature signature_; public: RaycastFunction(GeometrySet target, GField src_field, GeometryNodeRaycastMapMode mapping) @@ -229,10 +229,10 @@ class RaycastFunction : public fn::MultiFunction { this->set_signature(&signature_); } - fn::MFSignature create_signature() + mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Geometry Proximity", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Geometry Proximity", signature}; builder.single_input("Source Position"); builder.single_input("Ray Direction"); builder.single_input("Ray Length"); @@ -246,7 +246,7 @@ class RaycastFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { /* Hit positions are always necessary for retrieving the attribute from the target if that * output is required, so always retrieve a span from the evaluator in that case (it's diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc index 48b45106f61..8c5da6dd387 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc @@ -176,13 +176,13 @@ void copy_with_clamped_indices(const VArray &src, * instance geometry set in the source. A future optimization could be removing that limitation * internally. */ -class SampleIndexFunction : public fn::MultiFunction { +class SampleIndexFunction : public mf::MultiFunction { GeometrySet src_geometry_; GField src_field_; eAttrDomain domain_; bool clamp_; - fn::MFSignature signature_; + mf::Signature signature_; std::optional geometry_context_; std::unique_ptr evaluator_; @@ -206,10 +206,10 @@ class SampleIndexFunction : public fn::MultiFunction { this->evaluate_field(); } - fn::MFSignature create_signature() + mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Sample Index", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Sample Index", signature}; builder.single_input("Index"); builder.single_output("Value", src_field_.cpp_type()); return signature; @@ -229,7 +229,7 @@ class SampleIndexFunction : public fn::MultiFunction { src_data_ = &evaluator_->get_evaluated(0); } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &indices = params.readonly_single_input(0, "Index"); GMutableSpan dst = params.uninitialized_single_output(1, "Value"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc index cb9e6ca8edd..87785a7ed44 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc @@ -232,13 +232,13 @@ static const GeometryComponent *find_source_component(const GeometrySet &geometr return nullptr; } -class SampleNearestFunction : public fn::MultiFunction { +class SampleNearestFunction : public mf::MultiFunction { GeometrySet source_; eAttrDomain domain_; const GeometryComponent *src_component_; - fn::MFSignature signature_; + mf::Signature signature_; public: SampleNearestFunction(GeometrySet geometry, eAttrDomain domain) @@ -251,16 +251,16 @@ class SampleNearestFunction : public fn::MultiFunction { this->src_component_ = find_source_component(source_, domain_); } - fn::MFSignature create_signature() + mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Sample Nearest", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Sample Nearest", signature}; builder.single_input("Position"); builder.single_output("Index"); return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &positions = params.readonly_single_input(0, "Position"); MutableSpan indices = params.uninitialized_single_output(1, "Index"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc index 29361251e91..f07623ee649 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc @@ -116,7 +116,7 @@ static void get_closest_mesh_looptris(const Mesh &mesh, * function could be called many times, calculate the data from the source geometry once and store * it for later. */ -class SampleNearestSurfaceFunction : public fn::MultiFunction { +class SampleNearestSurfaceFunction : public mf::MultiFunction { GeometrySet source_; GField src_field_; @@ -128,7 +128,7 @@ class SampleNearestSurfaceFunction : public fn::MultiFunction { */ eAttrDomain domain_ = ATTR_DOMAIN_CORNER; - fn::MFSignature signature_; + mf::Signature signature_; std::optional source_context_; std::unique_ptr source_evaluator_; @@ -144,16 +144,16 @@ class SampleNearestSurfaceFunction : public fn::MultiFunction { this->evaluate_source_field(); } - fn::MFSignature create_signature() + mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Sample Nearest Surface", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Sample Nearest Surface", signature}; builder.single_input("Position"); builder.single_output("Value", src_field_.cpp_type()); return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &positions = params.readonly_single_input(0, "Position"); GMutableSpan dst = params.uninitialized_single_output_if_required(1, "Value"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc index 6291c9b4e28..42e602826a1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc @@ -105,7 +105,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) } } -class SampleMeshBarycentricFunction : public fn::MultiFunction { +class SampleMeshBarycentricFunction : public mf::MultiFunction { GeometrySet source_; GField src_field_; @@ -116,7 +116,7 @@ class SampleMeshBarycentricFunction : public fn::MultiFunction { */ eAttrDomain domain_ = ATTR_DOMAIN_CORNER; - fn::MFSignature signature_; + mf::Signature signature_; std::optional source_context_; std::unique_ptr source_evaluator_; @@ -134,17 +134,17 @@ class SampleMeshBarycentricFunction : public fn::MultiFunction { this->evaluate_source(); } - fn::MFSignature create_signature() + mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Sample Barycentric Triangles", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Sample Barycentric Triangles", signature}; builder.single_input("Triangle Index"); builder.single_input("Barycentric Weight"); builder.single_output("Value", src_field_.cpp_type()); return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArraySpan triangle_indices = params.readonly_single_input(0, "Triangle Index"); @@ -185,7 +185,7 @@ class SampleMeshBarycentricFunction : public fn::MultiFunction { } }; -class ReverseUVSampleFunction : public fn::MultiFunction { +class ReverseUVSampleFunction : public mf::MultiFunction { GeometrySet source_; Field src_uv_map_field_; @@ -200,15 +200,15 @@ class ReverseUVSampleFunction : public fn::MultiFunction { : source_(std::move(geometry)), src_uv_map_field_(std::move(src_uv_map_field)) { source_.ensure_owns_direct_data(); - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); this->evaluate_source(); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Sample UV Surface", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Sample UV Surface", signature}; builder.single_input("Sample UV"); builder.single_output("Is Valid"); builder.single_output("Triangle Index"); @@ -216,7 +216,7 @@ class ReverseUVSampleFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArraySpan sample_uvs = params.readonly_single_input(0, "Sample UV"); MutableSpan is_valid = params.uninitialized_single_output_if_required(1, diff --git a/source/blender/nodes/geometry/nodes/node_geo_switch.cc b/source/blender/nodes/geometry/nodes/node_geo_switch.cc index 04ff3d79fc4..6873c557310 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_switch.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_switch.cc @@ -171,7 +171,7 @@ template void switch_fields(GeoNodeExecParams ¶ms, const StringR Field falses_field = params.extract_input>(name_false); Field trues_field = params.extract_input>(name_true); - static auto switch_fn = fn::build_mf::SI3_SO( + static auto switch_fn = mf::build::SI3_SO( "Switch", [](bool condition, const T &false_value, const T &true_value) { return condition ? true_value : false_value; }); diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 8f59dea62e1..bb4337a75eb 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -37,7 +37,6 @@ namespace blender::nodes { using fn::ValueOrField; using fn::ValueOrFieldCPPType; -using namespace fn::multi_function_types; static const CPPType *get_socket_cpp_type(const bNodeSocketType &typeinfo) { @@ -353,8 +352,8 @@ static void execute_multi_function_on_value_or_field( } else { /* In this case, the multi-function is evaluated directly. */ - MFParamsBuilder params{fn, 1}; - MFContextBuilder context; + mf::ParamsBuilder params{fn, 1}; + mf::ContextBuilder context; for (const int i : input_types.index_range()) { const ValueOrFieldCPPType &type = *input_types[i]; @@ -445,7 +444,7 @@ class LazyFunctionForMutedNode : public LazyFunction { if (from_type != nullptr && to_type != nullptr) { if (conversions.is_convertible(from_type->value, to_type->value)) { const MultiFunction &multi_fn = *conversions.get_conversion_multi_function( - MFDataType::ForSingle(from_type->value), MFDataType::ForSingle(to_type->value)); + mf::DataType::ForSingle(from_type->value), mf::DataType::ForSingle(to_type->value)); execute_multi_function_on_value_or_field( multi_fn, {}, {from_type}, {to_type}, {input_value}, {output_value}); } @@ -1676,8 +1675,8 @@ struct GeometryNodesLazyFunctionGraphBuilder { if (from_field_type != nullptr && to_field_type != nullptr) { if (conversions_->is_convertible(from_field_type->value, to_field_type->value)) { const MultiFunction &multi_fn = *conversions_->get_conversion_multi_function( - MFDataType::ForSingle(from_field_type->value), - MFDataType::ForSingle(to_field_type->value)); + mf::DataType::ForSingle(from_field_type->value), + mf::DataType::ForSingle(to_field_type->value)); auto fn = std::make_unique( multi_fn, *from_field_type, *to_field_type); lf::Node &conversion_node = lf_graph_->add_function(*fn); diff --git a/source/blender/nodes/shader/nodes/node_shader_clamp.cc b/source/blender/nodes/shader/nodes/node_shader_clamp.cc index 08480c2d130..f2d300a6f19 100644 --- a/source/blender/nodes/shader/nodes/node_shader_clamp.cc +++ b/source/blender/nodes/shader/nodes/node_shader_clamp.cc @@ -44,10 +44,10 @@ static int gpu_shader_clamp(GPUMaterial *mat, static void sh_node_clamp_build_multi_function(NodeMultiFunctionBuilder &builder) { - static auto minmax_fn = fn::build_mf::SI3_SO( + static auto minmax_fn = mf::build::SI3_SO( "Clamp (Min Max)", [](float value, float min, float max) { return std::min(std::max(value, min), max); }); - static auto range_fn = fn::build_mf::SI3_SO( + static auto range_fn = mf::build::SI3_SO( "Clamp (Range)", [](float value, float a, float b) { if (a < b) { return clamp_f(value, a, b); diff --git a/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc b/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc index 1f82a91aa1c..91ba40de7a6 100644 --- a/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc +++ b/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc @@ -87,28 +87,28 @@ static int gpu_shader_valtorgb(GPUMaterial *mat, return GPU_stack_link(mat, node, "valtorgb", in, out, tex, GPU_constant(&layer)); } -class ColorBandFunction : public fn::MultiFunction { +class ColorBandFunction : public mf::MultiFunction { private: const ColorBand &color_band_; public: ColorBandFunction(const ColorBand &color_band) : color_band_(color_band) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Color Band", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Color Band", signature}; builder.single_input("Value"); builder.single_output("Color"); builder.single_output("Alpha"); return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &values = params.readonly_single_input(0, "Value"); MutableSpan colors = params.uninitialized_single_output( diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.cc b/source/blender/nodes/shader/nodes/node_shader_curves.cc index 30452861ff4..63d3ab80786 100644 --- a/source/blender/nodes/shader/nodes/node_shader_curves.cc +++ b/source/blender/nodes/shader/nodes/node_shader_curves.cc @@ -63,28 +63,28 @@ static int gpu_shader_curve_vec(GPUMaterial *mat, GPU_uniform(end_slopes)); } -class CurveVecFunction : public fn::MultiFunction { +class CurveVecFunction : public mf::MultiFunction { private: const CurveMapping &cumap_; public: CurveVecFunction(const CurveMapping &cumap) : cumap_(cumap) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Curve Vec", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Curve Vec", signature}; builder.single_input("Fac"); builder.single_input("Vector"); builder.single_output("Vector"); return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Fac"); const VArray &vec_in = params.readonly_single_input(1, "Vector"); @@ -209,28 +209,28 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat, GPU_uniform(end_slopes)); } -class CurveRGBFunction : public fn::MultiFunction { +class CurveRGBFunction : public mf::MultiFunction { private: const CurveMapping &cumap_; public: CurveRGBFunction(const CurveMapping &cumap) : cumap_(cumap) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Curve RGB", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Curve RGB", signature}; builder.single_input("Fac"); builder.single_input("Color"); builder.single_output("Color"); return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Fac"); const VArray &col_in = params.readonly_single_input(1, @@ -332,28 +332,28 @@ static int gpu_shader_curve_float(GPUMaterial *mat, GPU_uniform(end_slopes)); } -class CurveFloatFunction : public fn::MultiFunction { +class CurveFloatFunction : public mf::MultiFunction { private: const CurveMapping &cumap_; public: CurveFloatFunction(const CurveMapping &cumap) : cumap_(cumap) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Curve Float", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Curve Float", signature}; builder.single_input("Factor"); builder.single_input("Value"); builder.single_output("Value"); return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Factor"); const VArray &val_in = params.readonly_single_input(1, "Value"); diff --git a/source/blender/nodes/shader/nodes/node_shader_map_range.cc b/source/blender/nodes/shader/nodes/node_shader_map_range.cc index eeebabe3f00..8b2240657e8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_map_range.cc +++ b/source/blender/nodes/shader/nodes/node_shader_map_range.cc @@ -233,7 +233,7 @@ static float3 clamp_range(const float3 value, const float3 min, const float3 max template static auto build_float_linear() { - return fn::build_mf::SI5_SO( + return mf::build::SI5_SO( Clamp ? "Map Range (clamped)" : "Map Range (unclamped)", [](float value, float from_min, float from_max, float to_min, float to_max) -> float { const float factor = safe_divide(value - from_min, from_max - from_min); @@ -243,12 +243,12 @@ template static auto build_float_linear() } return result; }, - fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); + mf::build::exec_presets::SomeSpanOrSingle<0>()); } template static auto build_float_stepped() { - return fn::build_mf::SI6_SO( + return mf::build::SI6_SO( Clamp ? "Map Range Stepped (clamped)" : "Map Range Stepped (unclamped)", [](float value, float from_min, float from_max, float to_min, float to_max, float steps) -> float { @@ -260,12 +260,12 @@ template static auto build_float_stepped() } return result; }, - fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); + mf::build::exec_presets::SomeSpanOrSingle<0>()); } template static auto build_vector_linear() { - return fn::build_mf::SI5_SO( + return mf::build::SI5_SO( Clamp ? "Vector Map Range (clamped)" : "Vector Map Range (unclamped)", [](const float3 &value, const float3 &from_min, @@ -279,12 +279,12 @@ template static auto build_vector_linear() } return result; }, - fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); + mf::build::exec_presets::SomeSpanOrSingle<0>()); } template static auto build_vector_stepped() { - return fn::build_mf::SI6_SO( + return mf::build::SI6_SO( Clamp ? "Vector Map Range Stepped (clamped)" : "Vector Map Range Stepped (unclamped)", [](const float3 &value, const float3 &from_min, @@ -300,7 +300,7 @@ template static auto build_vector_stepped() } return result; }, - fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); + mf::build::exec_presets::SomeSpanOrSingle<0>()); } static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &builder) @@ -335,7 +335,7 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui break; } case NODE_MAP_RANGE_SMOOTHSTEP: { - static auto fn = fn::build_mf::SI5_SO( + static auto fn = mf::build::SI5_SO( "Vector Map Range Smoothstep", [](const float3 &value, const float3 &from_min, @@ -347,12 +347,12 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui factor = (float3(3.0f) - 2.0f * factor) * (factor * factor); return factor * (to_max - to_min) + to_min; }, - fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); + mf::build::exec_presets::SomeSpanOrSingle<0>()); builder.set_matching_fn(fn); break; } case NODE_MAP_RANGE_SMOOTHERSTEP: { - static auto fn = fn::build_mf::SI5_SO( + static auto fn = mf::build::SI5_SO( "Vector Map Range Smootherstep", [](const float3 &value, const float3 &from_min, @@ -364,7 +364,7 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f); return factor * (to_max - to_min) + to_min; }, - fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); + mf::build::exec_presets::SomeSpanOrSingle<0>()); builder.set_matching_fn(fn); break; } @@ -397,7 +397,7 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui break; } case NODE_MAP_RANGE_SMOOTHSTEP: { - static auto fn = fn::build_mf::SI5_SO( + static auto fn = mf::build::SI5_SO( "Map Range Smoothstep", [](float value, float from_min, float from_max, float to_min, float to_max) -> float { @@ -406,12 +406,12 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui factor = (3.0f - 2.0f * factor) * (factor * factor); return to_min + factor * (to_max - to_min); }, - fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); + mf::build::exec_presets::SomeSpanOrSingle<0>()); builder.set_matching_fn(fn); break; } case NODE_MAP_RANGE_SMOOTHERSTEP: { - static auto fn = fn::build_mf::SI5_SO( + static auto fn = mf::build::SI5_SO( "Map Range Smoothstep", [](float value, float from_min, float from_max, float to_min, float to_max) -> float { @@ -420,7 +420,7 @@ static void sh_node_map_range_build_multi_function(NodeMultiFunctionBuilder &bui factor = factor * factor * factor * (factor * (factor * 6.0f - 15.0f) + 10.0f); return to_min + factor * (to_max - to_min); }, - fn::build_mf::exec_presets::SomeSpanOrSingle<0>()); + mf::build::exec_presets::SomeSpanOrSingle<0>()); builder.set_matching_fn(fn); break; } diff --git a/source/blender/nodes/shader/nodes/node_shader_math.cc b/source/blender/nodes/shader/nodes/node_shader_math.cc index 1a2c22862b3..8cfcdefefc0 100644 --- a/source/blender/nodes/shader/nodes/node_shader_math.cc +++ b/source/blender/nodes/shader/nodes/node_shader_math.cc @@ -102,14 +102,14 @@ static int gpu_shader_math(GPUMaterial *mat, return 0; } -static const fn::MultiFunction *get_base_multi_function(const bNode &node) +static const mf::MultiFunction *get_base_multi_function(const bNode &node) { const int mode = node.custom1; - const fn::MultiFunction *base_fn = nullptr; + const mf::MultiFunction *base_fn = nullptr; try_dispatch_float_math_fl_to_fl( mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) { - static auto fn = fn::build_mf::SI1_SO( + static auto fn = mf::build::SI1_SO( info.title_case_name.c_str(), function, devi_fn); base_fn = &fn; }); @@ -119,7 +119,7 @@ static const fn::MultiFunction *get_base_multi_function(const bNode &node) try_dispatch_float_math_fl_fl_to_fl( mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( info.title_case_name.c_str(), function, devi_fn); base_fn = &fn; }); @@ -129,7 +129,7 @@ static const fn::MultiFunction *get_base_multi_function(const bNode &node) try_dispatch_float_math_fl_fl_fl_to_fl( mode, [&](auto devi_fn, auto function, const FloatMathOperationInfo &info) { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( info.title_case_name.c_str(), function, devi_fn); base_fn = &fn; }); @@ -140,17 +140,17 @@ static const fn::MultiFunction *get_base_multi_function(const bNode &node) return nullptr; } -class ClampWrapperFunction : public fn::MultiFunction { +class ClampWrapperFunction : public mf::MultiFunction { private: - const fn::MultiFunction &fn_; + const mf::MultiFunction &fn_; public: - ClampWrapperFunction(const fn::MultiFunction &fn) : fn_(fn) + ClampWrapperFunction(const mf::MultiFunction &fn) : fn_(fn) { this->set_signature(&fn.signature()); } - void call(IndexMask mask, fn::MFParams params, fn::MFContext context) const override + void call(IndexMask mask, mf::MFParams params, mf::Context context) const override { fn_.call(mask, params, context); @@ -168,7 +168,7 @@ class ClampWrapperFunction : public fn::MultiFunction { static void sh_node_math_build_multi_function(NodeMultiFunctionBuilder &builder) { - const fn::MultiFunction *base_function = get_base_multi_function(builder.node()); + const mf::MultiFunction *base_function = get_base_multi_function(builder.node()); const bool clamp_output = builder.node().custom2 != 0; if (clamp_output) { diff --git a/source/blender/nodes/shader/nodes/node_shader_mix.cc b/source/blender/nodes/shader/nodes/node_shader_mix.cc index 243e752bed7..9edbdc28dd2 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix.cc @@ -351,7 +351,7 @@ static int gpu_shader_mix(GPUMaterial *mat, return ret; } -class MixColorFunction : public fn::MultiFunction { +class MixColorFunction : public mf::MultiFunction { private: const bool clamp_factor_; const bool clamp_result_; @@ -361,14 +361,14 @@ class MixColorFunction : public fn::MultiFunction { MixColorFunction(const bool clamp_factor, const bool clamp_result, const int blend_type) : clamp_factor_(clamp_factor), clamp_result_(clamp_result), blend_type_(blend_type) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"MixColor", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"MixColor", signature}; builder.single_input("Factor"); builder.single_input("A"); builder.single_input("B"); @@ -376,7 +376,7 @@ class MixColorFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Factor"); const VArray &col1 = params.readonly_single_input(1, "A"); @@ -405,7 +405,7 @@ class MixColorFunction : public fn::MultiFunction { } }; -static const fn::MultiFunction *get_multi_function(const bNode &node) +static const mf::MultiFunction *get_multi_function(const bNode &node) { const NodeShaderMix *data = (NodeShaderMix *)node.storage; bool uniform_factor = data->factor_mode == NODE_MIX_MODE_UNIFORM; @@ -413,14 +413,14 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) switch (data->data_type) { case SOCK_FLOAT: { if (clamp_factor) { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Clamp Mix Float", [](float t, const float a, const float b) { return math::interpolate(a, b, std::clamp(t, 0.0f, 1.0f)); }); return &fn; } else { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Mix Float", [](const float t, const float a, const float b) { return math::interpolate(a, b, t); }); @@ -430,14 +430,14 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case SOCK_VECTOR: { if (clamp_factor) { if (uniform_factor) { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Clamp Mix Vector", [](const float t, const float3 a, const float3 b) { return math::interpolate(a, b, std::clamp(t, 0.0f, 1.0f)); }); return &fn; } else { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Clamp Mix Vector Non Uniform", [](float3 t, const float3 a, const float3 b) { t = math::clamp(t, 0.0f, 1.0f); return a * (float3(1.0f) - t) + b * t; @@ -447,14 +447,14 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) } else { if (uniform_factor) { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Mix Vector", [](const float t, const float3 a, const float3 b) { return math::interpolate(a, b, t); }); return &fn; } else { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Mix Vector Non Uniform", [](const float3 t, const float3 a, const float3 b) { return a * (float3(1.0f) - t) + b * t; }); @@ -476,7 +476,7 @@ static void sh_node_mix_build_multi_function(NodeMultiFunctionBuilder &builder) storage.clamp_factor, storage.clamp_result, storage.blend_type); } else { - const fn::MultiFunction *fn = get_multi_function(builder.node()); + const mf::MultiFunction *fn = get_multi_function(builder.node()); builder.set_matching_fn(fn); } } diff --git a/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc index 74d3a90b13f..e21cbff4e12 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc @@ -91,7 +91,7 @@ static int gpu_shader_mix_rgb(GPUMaterial *mat, return ret; } -class MixRGBFunction : public fn::MultiFunction { +class MixRGBFunction : public mf::MultiFunction { private: bool clamp_; int type_; @@ -99,14 +99,14 @@ class MixRGBFunction : public fn::MultiFunction { public: MixRGBFunction(bool clamp, int type) : clamp_(clamp), type_(type) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"MixRGB", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"MixRGB", signature}; builder.single_input("Fac"); builder.single_input("Color1"); builder.single_input("Color2"); @@ -114,7 +114,7 @@ class MixRGBFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Fac"); const VArray &col1 = params.readonly_single_input(1, diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc index 9c7e632ebd4..8b2260af17a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc @@ -27,18 +27,18 @@ static int gpu_shader_seprgb(GPUMaterial *mat, return GPU_stack_link(mat, node, "separate_rgb", in, out); } -class SeparateRGBFunction : public fn::MultiFunction { +class SeparateRGBFunction : public mf::MultiFunction { public: SeparateRGBFunction() { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Separate RGB", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Separate RGB", signature}; builder.single_input("Color"); builder.single_output("R"); builder.single_output("G"); @@ -46,7 +46,7 @@ class SeparateRGBFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &colors = params.readonly_single_input(0, "Color"); @@ -109,7 +109,7 @@ static int gpu_shader_combrgb(GPUMaterial *mat, static void sh_node_combrgb_build_multi_function(NodeMultiFunctionBuilder &builder) { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Combine RGB", [](float r, float g, float b) { return ColorGeometry4f(r, g, b, 1.0f); }); builder.set_matching_fn(fn); } diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc index 83f580782a9..97776b77f63 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc @@ -27,18 +27,18 @@ static int gpu_shader_sepxyz(GPUMaterial *mat, return GPU_stack_link(mat, node, "separate_xyz", in, out); } -class MF_SeparateXYZ : public fn::MultiFunction { +class MF_SeparateXYZ : public mf::MultiFunction { public: MF_SeparateXYZ() { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Separate XYZ", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Separate XYZ", signature}; builder.single_input("XYZ"); builder.single_output("X"); builder.single_output("Y"); @@ -46,7 +46,7 @@ class MF_SeparateXYZ : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &vectors = params.readonly_single_input(0, "XYZ"); MutableSpan xs = params.uninitialized_single_output_if_required(1, "X"); @@ -126,10 +126,10 @@ static int gpu_shader_combxyz(GPUMaterial *mat, static void sh_node_combxyz_build_multi_function(NodeMultiFunctionBuilder &builder) { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Combine Vector", [](float x, float y, float z) { return float3(x, y, z); }, - fn::build_mf::exec_presets::AllSpanOrSingle()); + mf::build::exec_presets::AllSpanOrSingle()); builder.set_matching_fn(fn); } diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc index 80f1b5a73e8..789aaee5e64 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc @@ -108,7 +108,7 @@ static int node_shader_gpu_tex_brick(GPUMaterial *mat, GPU_constant(&squash_freq)); } -class BrickFunction : public fn::MultiFunction { +class BrickFunction : public mf::MultiFunction { private: const float offset_; const int offset_freq_; @@ -122,14 +122,14 @@ class BrickFunction : public fn::MultiFunction { const int squash_freq) : offset_(offset), offset_freq_(offset_freq), squash_(squash), squash_freq_(squash_freq) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"BrickTexture", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"BrickTexture", signature}; builder.single_input("Vector"); builder.single_input("Color1"); builder.single_input("Color2"); @@ -204,7 +204,7 @@ class BrickFunction : public fn::MultiFunction { return float2(tint, mortar); } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); const VArray &color1_values = params.readonly_single_input( diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc index 61c85b136f8..3c6404f1aa6 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc @@ -44,18 +44,18 @@ static int node_shader_gpu_tex_checker(GPUMaterial *mat, return GPU_stack_link(mat, node, "node_tex_checker", in, out); } -class NodeTexChecker : public fn::MultiFunction { +class NodeTexChecker : public mf::MultiFunction { public: NodeTexChecker() { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Checker", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Checker", signature}; builder.single_input("Vector"); builder.single_input("Color1"); builder.single_input("Color2"); @@ -65,7 +65,7 @@ class NodeTexChecker : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); const VArray &color1 = params.readonly_single_input( diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc index d1c2990d7e2..8a28b2f455a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc @@ -47,28 +47,28 @@ static int node_shader_gpu_tex_gradient(GPUMaterial *mat, return GPU_stack_link(mat, node, "node_tex_gradient", in, out, GPU_constant(&gradient_type)); } -class GradientFunction : public fn::MultiFunction { +class GradientFunction : public mf::MultiFunction { private: int gradient_type_; public: GradientFunction(int gradient_type) : gradient_type_(gradient_type) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"GradientFunction", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"GradientFunction", signature}; builder.single_input("Vector"); builder.single_output("Color"); builder.single_output("Fac"); return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc index 5692bfe7770..5cf3c67b50d 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc @@ -48,21 +48,21 @@ static int node_shader_gpu_tex_magic(GPUMaterial *mat, return GPU_stack_link(mat, node, "node_tex_magic", in, out, GPU_constant(&depth)); } -class MagicFunction : public fn::MultiFunction { +class MagicFunction : public mf::MultiFunction { private: int depth_; public: MagicFunction(int depth) : depth_(depth) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"MagicFunction", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"MagicFunction", signature}; builder.single_input("Vector"); builder.single_input("Scale"); builder.single_input("Distortion"); @@ -71,7 +71,7 @@ class MagicFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); const VArray &scale = params.readonly_single_input(1, "Scale"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc index 45b9d42e76c..39cbb1ff12e 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc @@ -125,7 +125,7 @@ static void node_shader_update_tex_musgrave(bNodeTree *ntree, bNode *node) node_sock_label(outFacSock, "Height"); } -class MusgraveFunction : public fn::MultiFunction { +class MusgraveFunction : public mf::MultiFunction { private: const int dimensions_; const int musgrave_type_; @@ -136,7 +136,7 @@ class MusgraveFunction : public fn::MultiFunction { { BLI_assert(dimensions >= 1 && dimensions <= 4); BLI_assert(musgrave_type >= 0 && musgrave_type <= 4); - static std::array signatures{ + static std::array signatures{ create_signature(1, SHD_MUSGRAVE_MULTIFRACTAL), create_signature(2, SHD_MUSGRAVE_MULTIFRACTAL), create_signature(3, SHD_MUSGRAVE_MULTIFRACTAL), @@ -165,10 +165,10 @@ class MusgraveFunction : public fn::MultiFunction { this->set_signature(&signatures[dimensions + musgrave_type * 4 - 1]); } - static fn::MFSignature create_signature(const int dimensions, const int musgrave_type) + static mf::Signature create_signature(const int dimensions, const int musgrave_type) { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Musgrave", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Musgrave", signature}; if (ELEM(dimensions, 2, 3, 4)) { builder.single_input("Vector"); @@ -195,7 +195,7 @@ class MusgraveFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { auto get_vector = [&](int param_index) -> VArray { return params.readonly_single_input(param_index, "Vector"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc b/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc index 3a4a97d0a1a..f22c5d87c98 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc @@ -81,7 +81,7 @@ static void node_shader_update_tex_noise(bNodeTree *ntree, bNode *node) nodeSetSocketAvailability(ntree, sockW, storage.dimensions == 1 || storage.dimensions == 4); } -class NoiseFunction : public fn::MultiFunction { +class NoiseFunction : public mf::MultiFunction { private: int dimensions_; @@ -89,7 +89,7 @@ class NoiseFunction : public fn::MultiFunction { NoiseFunction(int dimensions) : dimensions_(dimensions) { BLI_assert(dimensions >= 1 && dimensions <= 4); - static std::array signatures{ + static std::array signatures{ create_signature(1), create_signature(2), create_signature(3), @@ -98,10 +98,10 @@ class NoiseFunction : public fn::MultiFunction { this->set_signature(&signatures[dimensions - 1]); } - static fn::MFSignature create_signature(int dimensions) + static mf::Signature create_signature(int dimensions) { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"Noise", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"Noise", signature}; if (ELEM(dimensions, 2, 3, 4)) { builder.single_input("Vector"); @@ -121,7 +121,7 @@ class NoiseFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { int param = ELEM(dimensions_, 2, 3, 4) + ELEM(dimensions_, 1, 4); const VArray &scale = params.readonly_single_input(param++, "Scale"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc index a02cb3c046a..1f1313b44be 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc @@ -179,9 +179,9 @@ static void node_shader_update_tex_voronoi(bNodeTree *ntree, bNode *node) nodeSetSocketAvailability(ntree, outRadiusSock, storage.feature == SHD_VORONOI_N_SPHERE_RADIUS); } -static MultiFunction::ExecutionHints voronoi_execution_hints{50, false}; +static mf::MultiFunction::ExecutionHints voronoi_execution_hints{50, false}; -class VoronoiMinowskiFunction : public fn::MultiFunction { +class VoronoiMinowskiFunction : public mf::MultiFunction { private: int dimensions_; int feature_; @@ -191,7 +191,7 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { { BLI_assert(dimensions >= 2 && dimensions <= 4); BLI_assert(feature >= 0 && feature <= 2); - static std::array signatures{ + static std::array signatures{ create_signature(2, SHD_VORONOI_F1), create_signature(3, SHD_VORONOI_F1), create_signature(4, SHD_VORONOI_F1), @@ -207,10 +207,10 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { this->set_signature(&signatures[(dimensions - 1) + feature * 3 - 1]); } - static fn::MFSignature create_signature(int dimensions, int feature) + static mf::Signature create_signature(int dimensions, int feature) { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"voronoi_minowski", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"voronoi_minowski", signature}; if (ELEM(dimensions, 2, 3, 4)) { builder.single_input("Vector"); @@ -237,7 +237,7 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { auto get_vector = [&](int param_index) -> VArray { return params.readonly_single_input(param_index, "Vector"); @@ -614,7 +614,7 @@ class VoronoiMinowskiFunction : public fn::MultiFunction { } }; -class VoronoiMetricFunction : public fn::MultiFunction { +class VoronoiMetricFunction : public mf::MultiFunction { private: int dimensions_; int feature_; @@ -626,7 +626,7 @@ class VoronoiMetricFunction : public fn::MultiFunction { { BLI_assert(dimensions >= 1 && dimensions <= 4); BLI_assert(feature >= 0 && feature <= 4); - static std::array signatures{ + static std::array signatures{ create_signature(1, SHD_VORONOI_F1), create_signature(2, SHD_VORONOI_F1), create_signature(3, SHD_VORONOI_F1), @@ -645,10 +645,10 @@ class VoronoiMetricFunction : public fn::MultiFunction { this->set_signature(&signatures[dimensions + feature * 4 - 1]); } - static fn::MFSignature create_signature(int dimensions, int feature) + static mf::Signature create_signature(int dimensions, int feature) { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"voronoi_metric", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"voronoi_metric", signature}; if (ELEM(dimensions, 2, 3, 4)) { builder.single_input("Vector"); @@ -674,7 +674,7 @@ class VoronoiMetricFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { auto get_vector = [&](int param_index) -> VArray { return params.readonly_single_input(param_index, "Vector"); @@ -1134,7 +1134,7 @@ class VoronoiMetricFunction : public fn::MultiFunction { } }; -class VoronoiEdgeFunction : public fn::MultiFunction { +class VoronoiEdgeFunction : public mf::MultiFunction { private: int dimensions_; int feature_; @@ -1144,7 +1144,7 @@ class VoronoiEdgeFunction : public fn::MultiFunction { { BLI_assert(dimensions >= 1 && dimensions <= 4); BLI_assert(feature >= 3 && feature <= 4); - static std::array signatures{ + static std::array signatures{ create_signature(1, SHD_VORONOI_DISTANCE_TO_EDGE), create_signature(2, SHD_VORONOI_DISTANCE_TO_EDGE), create_signature(3, SHD_VORONOI_DISTANCE_TO_EDGE), @@ -1158,10 +1158,10 @@ class VoronoiEdgeFunction : public fn::MultiFunction { this->set_signature(&signatures[dimensions + (feature - 3) * 4 - 1]); } - static fn::MFSignature create_signature(int dimensions, int feature) + static mf::Signature create_signature(int dimensions, int feature) { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"voronoi_edge", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"voronoi_edge", signature}; if (ELEM(dimensions, 2, 3, 4)) { builder.single_input("Vector"); @@ -1182,7 +1182,7 @@ class VoronoiEdgeFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { auto get_vector = [&](int param_index) -> VArray { return params.readonly_single_input(param_index, "Vector"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc index d2be2487489..9fb712efeec 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc @@ -80,7 +80,7 @@ static int node_shader_gpu_tex_wave(GPUMaterial *mat, GPU_constant(&wave_profile)); } -class WaveFunction : public fn::MultiFunction { +class WaveFunction : public mf::MultiFunction { private: int wave_type_; int bands_direction_; @@ -94,14 +94,14 @@ class WaveFunction : public fn::MultiFunction { rings_direction_(rings_direction), wave_profile_(wave_profile) { - static fn::MFSignature signature = create_signature(); + static mf::Signature signature = create_signature(); this->set_signature(&signature); } - static fn::MFSignature create_signature() + static mf::Signature create_signature() { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"MagicFunction", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"MagicFunction", signature}; builder.single_input("Vector"); builder.single_input("Scale"); builder.single_input("Distortion"); @@ -114,7 +114,7 @@ class WaveFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); const VArray &scale = params.readonly_single_input(1, "Scale"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc index 0a4ac73b277..816143eaa33 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc @@ -63,7 +63,7 @@ static void node_shader_update_tex_white_noise(bNodeTree *ntree, bNode *node) nodeSetSocketAvailability(ntree, sockW, node->custom1 == 1 || node->custom1 == 4); } -class WhiteNoiseFunction : public fn::MultiFunction { +class WhiteNoiseFunction : public mf::MultiFunction { private: int dimensions_; @@ -71,7 +71,7 @@ class WhiteNoiseFunction : public fn::MultiFunction { WhiteNoiseFunction(int dimensions) : dimensions_(dimensions) { BLI_assert(dimensions >= 1 && dimensions <= 4); - static std::array signatures{ + static std::array signatures{ create_signature(1), create_signature(2), create_signature(3), @@ -80,10 +80,10 @@ class WhiteNoiseFunction : public fn::MultiFunction { this->set_signature(&signatures[dimensions - 1]); } - static fn::MFSignature create_signature(int dimensions) + static mf::Signature create_signature(int dimensions) { - fn::MFSignature signature; - fn::MFSignatureBuilder builder{"WhiteNoise", signature}; + mf::Signature signature; + mf::SignatureBuilder builder{"WhiteNoise", signature}; if (ELEM(dimensions, 2, 3, 4)) { builder.single_input("Vector"); @@ -98,7 +98,7 @@ class WhiteNoiseFunction : public fn::MultiFunction { return signature; } - void call(IndexMask mask, fn::MFParams params, fn::MFContext /*context*/) const override + void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { int param = ELEM(dimensions_, 2, 3, 4) + ELEM(dimensions_, 1, 4); diff --git a/source/blender/nodes/shader/nodes/node_shader_value.cc b/source/blender/nodes/shader/nodes/node_shader_value.cc index c190438c417..0722ca05f5b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_value.cc +++ b/source/blender/nodes/shader/nodes/node_shader_value.cc @@ -29,7 +29,7 @@ static void sh_node_value_build_multi_function(NodeMultiFunctionBuilder &builder { const bNodeSocket *bsocket = (bNodeSocket *)builder.node().outputs.first; const bNodeSocketValueFloat *value = (const bNodeSocketValueFloat *)bsocket->default_value; - builder.construct_and_set_matching_fn>(value->value); + builder.construct_and_set_matching_fn>(value->value); } } // namespace blender::nodes::node_shader_value_cc diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc index 96747139b87..0fc83cd0f46 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_math.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_math.cc @@ -225,15 +225,15 @@ static void node_shader_update_vector_math(bNodeTree *ntree, bNode *node) } } -static const fn::MultiFunction *get_multi_function(const bNode &node) +static const mf::MultiFunction *get_multi_function(const bNode &node) { NodeVectorMathOperation operation = NodeVectorMathOperation(node.custom1); - const fn::MultiFunction *multi_fn = nullptr; + const mf::MultiFunction *multi_fn = nullptr; try_dispatch_float_math_fl3_fl3_to_fl3( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); @@ -243,7 +243,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) try_dispatch_float_math_fl3_fl3_fl3_to_fl3( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); @@ -253,7 +253,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) try_dispatch_float_math_fl3_fl3_fl_to_fl3( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); @@ -263,7 +263,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) try_dispatch_float_math_fl3_fl3_to_fl( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); @@ -273,7 +273,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) try_dispatch_float_math_fl3_fl_to_fl3( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static auto fn = fn::build_mf::SI2_SO( + static auto fn = mf::build::SI2_SO( info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); @@ -283,7 +283,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) try_dispatch_float_math_fl3_to_fl3( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static auto fn = fn::build_mf::SI1_SO( + static auto fn = mf::build::SI1_SO( info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); @@ -293,7 +293,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) try_dispatch_float_math_fl3_to_fl( operation, [&](auto exec_preset, auto function, const FloatMathOperationInfo &info) { - static auto fn = fn::build_mf::SI1_SO( + static auto fn = mf::build::SI1_SO( info.title_case_name.c_str(), function, exec_preset); multi_fn = &fn; }); @@ -306,7 +306,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) static void sh_node_vector_math_build_multi_function(NodeMultiFunctionBuilder &builder) { - const fn::MultiFunction *fn = get_multi_function(builder.node()); + const mf::MultiFunction *fn = get_multi_function(builder.node()); builder.set_matching_fn(fn); } diff --git a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc index d59c9271ccb..9792ac4fb80 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vector_rotate.cc @@ -96,7 +96,7 @@ static float3 sh_node_vector_rotate_euler(const float3 &vector, return result + center; } -static const fn::MultiFunction *get_multi_function(const bNode &node) +static const mf::MultiFunction *get_multi_function(const bNode &node) { bool invert = node.custom2; const int mode = node.custom1; @@ -104,14 +104,14 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) switch (mode) { case NODE_VECTOR_ROTATE_TYPE_AXIS: { if (invert) { - static auto fn = fn::build_mf::SI4_SO( + static auto fn = mf::build::SI4_SO( "Rotate Axis", [](const float3 &in, const float3 ¢er, const float3 &axis, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, -angle); }); return &fn; } - static auto fn = fn::build_mf::SI4_SO( + static auto fn = mf::build::SI4_SO( "Rotate Axis", [](const float3 &in, const float3 ¢er, const float3 &axis, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, angle); @@ -121,13 +121,13 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_VECTOR_ROTATE_TYPE_AXIS_X: { float3 axis = float3(1.0f, 0.0f, 0.0f); if (invert) { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Rotate X-Axis", [=](const float3 &in, const float3 ¢er, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, -angle); }); return &fn; } - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Rotate X-Axis", [=](const float3 &in, const float3 ¢er, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, angle); }); @@ -136,13 +136,13 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_VECTOR_ROTATE_TYPE_AXIS_Y: { float3 axis = float3(0.0f, 1.0f, 0.0f); if (invert) { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Rotate Y-Axis", [=](const float3 &in, const float3 ¢er, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, -angle); }); return &fn; } - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Rotate Y-Axis", [=](const float3 &in, const float3 ¢er, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, angle); }); @@ -151,13 +151,13 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) case NODE_VECTOR_ROTATE_TYPE_AXIS_Z: { float3 axis = float3(0.0f, 0.0f, 1.0f); if (invert) { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Rotate Z-Axis", [=](const float3 &in, const float3 ¢er, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, -angle); }); return &fn; } - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Rotate Z-Axis", [=](const float3 &in, const float3 ¢er, float angle) { return sh_node_vector_rotate_around_axis(in, center, axis, angle); }); @@ -165,13 +165,13 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) } case NODE_VECTOR_ROTATE_TYPE_EULER_XYZ: { if (invert) { - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Rotate Euler", [](const float3 &in, const float3 ¢er, const float3 &rotation) { return sh_node_vector_rotate_euler(in, center, rotation, true); }); return &fn; } - static auto fn = fn::build_mf::SI3_SO( + static auto fn = mf::build::SI3_SO( "Rotate Euler", [](const float3 &in, const float3 ¢er, const float3 &rotation) { return sh_node_vector_rotate_euler(in, center, rotation, false); }); @@ -185,7 +185,7 @@ static const fn::MultiFunction *get_multi_function(const bNode &node) static void sh_node_vector_rotate_build_multi_function(NodeMultiFunctionBuilder &builder) { - const fn::MultiFunction *fn = get_multi_function(builder.node()); + const mf::MultiFunction *fn = get_multi_function(builder.node()); builder.set_matching_fn(fn); } From a2ea32a600def98a1ee2d8d2eb63126e4d51fe53 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 7 Jan 2023 18:00:37 +0100 Subject: [PATCH 0502/1522] Cleanup: inline signatures into multi-function constructors This reduces the amount of code. Also the signature should be thought of as being setup in the constructor, so it's good if the code is there as well. --- .../functions/tests/FN_multi_function_test.cc | 19 ++-- .../tests/FN_multi_function_test_common.hh | 102 ++++++++---------- .../nodes/node_fn_align_euler_to_vector.cc | 22 ++-- .../nodes/node_fn_input_special_characters.cc | 17 ++- .../function/nodes/node_fn_separate_color.cc | 69 ++++++------ .../geometry/nodes/node_geo_curve_sample.cc | 35 +++--- .../geometry/nodes/node_geo_image_texture.cc | 19 ++-- .../geometry/nodes/node_geo_proximity.cc | 19 ++-- .../nodes/geometry/nodes/node_geo_raycast.cc | 10 +- .../geometry/nodes/node_geo_sample_index.cc | 13 +-- .../geometry/nodes/node_geo_sample_nearest.cc | 11 +- .../nodes/node_geo_sample_nearest_surface.cc | 10 +- .../nodes/node_geo_sample_uv_surface.cc | 32 +++--- .../shader/nodes/node_shader_color_ramp.cc | 19 ++-- .../nodes/shader/nodes/node_shader_curves.cc | 57 +++++----- .../nodes/shader/nodes/node_shader_mix.cc | 21 ++-- .../nodes/shader/nodes/node_shader_mix_rgb.cc | 21 ++-- .../shader/nodes/node_shader_sepcomb_rgb.cc | 21 ++-- .../shader/nodes/node_shader_sepcomb_xyz.cc | 21 ++-- .../shader/nodes/node_shader_tex_brick.cc | 37 +++---- .../shader/nodes/node_shader_tex_checker.cc | 25 ++--- .../shader/nodes/node_shader_tex_gradient.cc | 19 ++-- .../shader/nodes/node_shader_tex_magic.cc | 23 ++-- .../shader/nodes/node_shader_tex_wave.cc | 31 +++--- 24 files changed, 274 insertions(+), 399 deletions(-) diff --git a/source/blender/functions/tests/FN_multi_function_test.cc b/source/blender/functions/tests/FN_multi_function_test.cc index f0db195960c..9be5e224f09 100644 --- a/source/blender/functions/tests/FN_multi_function_test.cc +++ b/source/blender/functions/tests/FN_multi_function_test.cc @@ -13,20 +13,17 @@ class AddFunction : public MultiFunction { public: AddFunction() { - static Signature signature = create_signature(); + static Signature signature = []() { + Signature signature; + SignatureBuilder builder("Add", signature); + builder.single_input("A"); + builder.single_input("B"); + builder.single_output("Result"); + return signature; + }(); this->set_signature(&signature); } - static Signature create_signature() - { - Signature signature; - SignatureBuilder builder("Add", signature); - builder.single_input("A"); - builder.single_input("B"); - builder.single_output("Result"); - return signature; - } - void call(IndexMask mask, MFParams params, Context /*context*/) const override { const VArray &a = params.readonly_single_input(0, "A"); diff --git a/source/blender/functions/tests/FN_multi_function_test_common.hh b/source/blender/functions/tests/FN_multi_function_test_common.hh index 2014e4fc74e..adf70498fa6 100644 --- a/source/blender/functions/tests/FN_multi_function_test_common.hh +++ b/source/blender/functions/tests/FN_multi_function_test_common.hh @@ -8,19 +8,16 @@ class AddPrefixFunction : public MultiFunction { public: AddPrefixFunction() { - static Signature signature = create_signature(); + static const Signature signature = []() { + Signature signature; + SignatureBuilder builder{"Add Prefix", signature}; + builder.single_input("Prefix"); + builder.single_mutable("Strings"); + return signature; + }(); this->set_signature(&signature); } - static Signature create_signature() - { - Signature signature; - SignatureBuilder builder{"Add Prefix", signature}; - builder.single_input("Prefix"); - builder.single_mutable("Strings"); - return signature; - } - void call(IndexMask mask, MFParams params, Context /*context*/) const override { const VArray &prefixes = params.readonly_single_input(0, "Prefix"); @@ -36,19 +33,16 @@ class CreateRangeFunction : public MultiFunction { public: CreateRangeFunction() { - static Signature signature = create_signature(); + static const Signature signature = []() { + Signature signature; + SignatureBuilder builder{"Create Range", signature}; + builder.single_input("Size"); + builder.vector_output("Range"); + return signature; + }(); this->set_signature(&signature); } - static Signature create_signature() - { - Signature signature; - SignatureBuilder builder{"Create Range", signature}; - builder.single_input("Size"); - builder.vector_output("Range"); - return signature; - } - void call(IndexMask mask, MFParams params, Context /*context*/) const override { const VArray &sizes = params.readonly_single_input(0, "Size"); @@ -94,19 +88,16 @@ class ConcatVectorsFunction : public MultiFunction { public: ConcatVectorsFunction() { - static Signature signature = create_signature(); + static const Signature signature = []() { + Signature signature; + SignatureBuilder builder{"Concat Vectors", signature}; + builder.vector_mutable("A"); + builder.vector_input("B"); + return signature; + }(); this->set_signature(&signature); } - static Signature create_signature() - { - Signature signature; - SignatureBuilder builder{"Concat Vectors", signature}; - builder.vector_mutable("A"); - builder.vector_input("B"); - return signature; - } - void call(IndexMask mask, MFParams params, Context /*context*/) const override { GVectorArray &a = params.vector_mutable(0); @@ -119,19 +110,16 @@ class AppendFunction : public MultiFunction { public: AppendFunction() { - static Signature signature = create_signature(); + static const Signature signature = []() { + Signature signature; + SignatureBuilder builder{"Append", signature}; + builder.vector_mutable("Vector"); + builder.single_input("Value"); + return signature; + }(); this->set_signature(&signature); } - static Signature create_signature() - { - Signature signature; - SignatureBuilder builder{"Append", signature}; - builder.vector_mutable("Vector"); - builder.single_input("Value"); - return signature; - } - void call(IndexMask mask, MFParams params, Context /*context*/) const override { GVectorArray_TypedMutableRef vectors = params.vector_mutable(0); @@ -147,19 +135,16 @@ class SumVectorFunction : public MultiFunction { public: SumVectorFunction() { - static Signature signature = create_signature(); + static const Signature signature = []() { + Signature signature; + SignatureBuilder builder{"Sum Vectors", signature}; + builder.vector_input("Vector"); + builder.single_output("Sum"); + return signature; + }(); this->set_signature(&signature); } - static Signature create_signature() - { - Signature signature; - SignatureBuilder builder{"Sum Vectors", signature}; - builder.vector_input("Vector"); - builder.single_output("Sum"); - return signature; - } - void call(IndexMask mask, MFParams params, Context /*context*/) const override { const VVectorArray &vectors = params.readonly_vector_input(0); @@ -179,19 +164,16 @@ class OptionalOutputsFunction : public MultiFunction { public: OptionalOutputsFunction() { - static Signature signature = create_signature(); + static const Signature signature = []() { + Signature signature; + SignatureBuilder builder{"Optional Outputs", signature}; + builder.single_output("Out 1"); + builder.single_output("Out 2"); + return signature; + }(); this->set_signature(&signature); } - static Signature create_signature() - { - Signature signature; - SignatureBuilder builder{"Optional Outputs", signature}; - builder.single_output("Out 1"); - builder.single_output("Out 2"); - return signature; - } - void call(IndexMask mask, MFParams params, Context /*context*/) const override { if (params.single_output_is_required(0, "Out 1")) { diff --git a/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc b/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc index 21e60f127ce..efea88088cf 100644 --- a/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc +++ b/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc @@ -142,22 +142,18 @@ class MF_AlignEulerToVector : public mf::MultiFunction { MF_AlignEulerToVector(int main_axis_mode, int pivot_axis_mode) : main_axis_mode_(main_axis_mode), pivot_axis_mode_(pivot_axis_mode) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Align Euler to Vector", signature}; + builder.single_input("Rotation"); + builder.single_input("Factor"); + builder.single_input("Vector"); + builder.single_output("Rotation"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Align Euler to Vector", signature}; - builder.single_input("Rotation"); - builder.single_input("Factor"); - builder.single_input("Vector"); - - builder.single_output("Rotation"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &input_rotations = params.readonly_single_input(0, "Rotation"); diff --git a/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc b/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc index 7ccd6f3d87f..1392a923136 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc @@ -14,19 +14,16 @@ class MF_SpecialCharacters : public mf::MultiFunction { public: MF_SpecialCharacters() { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Special Characters", signature}; + builder.single_output("Line Break"); + builder.single_output("Tab"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Special Characters", signature}; - builder.single_output("Line Break"); - builder.single_output("Tab"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { MutableSpan lb = params.uninitialized_single_output(0, "Line Break"); diff --git a/source/blender/nodes/function/nodes/node_fn_separate_color.cc b/source/blender/nodes/function/nodes/node_fn_separate_color.cc index c717a9de080..fae7c275f5d 100644 --- a/source/blender/nodes/function/nodes/node_fn_separate_color.cc +++ b/source/blender/nodes/function/nodes/node_fn_separate_color.cc @@ -41,22 +41,19 @@ class SeparateRGBAFunction : public mf::MultiFunction { public: SeparateRGBAFunction() { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Separate Color", signature}; + builder.single_input("Color"); + builder.single_output("Red"); + builder.single_output("Green"); + builder.single_output("Blue"); + builder.single_output("Alpha"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Separate Color", signature}; - builder.single_input("Color"); - builder.single_output("Red"); - builder.single_output("Green"); - builder.single_output("Blue"); - builder.single_output("Alpha"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &colors = params.readonly_single_input(0, @@ -103,22 +100,19 @@ class SeparateHSVAFunction : public mf::MultiFunction { public: SeparateHSVAFunction() { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Separate Color", signature}; + builder.single_input("Color"); + builder.single_output("Hue"); + builder.single_output("Saturation"); + builder.single_output("Value"); + builder.single_output("Alpha"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Separate Color", signature}; - builder.single_input("Color"); - builder.single_output("Hue"); - builder.single_output("Saturation"); - builder.single_output("Value"); - builder.single_output("Alpha"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &colors = params.readonly_single_input(0, @@ -144,22 +138,19 @@ class SeparateHSLAFunction : public mf::MultiFunction { public: SeparateHSLAFunction() { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Separate Color", signature}; + builder.single_input("Color"); + builder.single_output("Hue"); + builder.single_output("Saturation"); + builder.single_output("Lightness"); + builder.single_output("Alpha"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Separate Color", signature}; - builder.single_input("Color"); - builder.single_output("Hue"); - builder.single_output("Saturation"); - builder.single_output("Lightness"); - builder.single_output("Alpha"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &colors = params.readonly_single_input(0, diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc index 46c9f8c8805..2ca30b0fef5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc @@ -211,21 +211,18 @@ class SampleFloatSegmentsFunction : public mf::MultiFunction { const GeometryNodeCurveSampleMode length_mode) : accumulated_lengths_(std::move(accumulated_lengths)), length_mode_(length_mode) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Sample Curve Index", signature}; + builder.single_input("Length"); + + builder.single_output("Curve Index"); + builder.single_output("Length in Curve"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Sample Curve Index", signature}; - builder.single_input("Length"); - - builder.single_output("Curve Index"); - builder.single_output("Length in Curve"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArraySpan lengths = params.readonly_single_input(0, "Length"); @@ -261,22 +258,16 @@ class SampleCurveFunction : public mf::MultiFunction { const GField &src_field) : geometry_set_(std::move(geometry_set)), src_field_(src_field), length_mode_(length_mode) { - signature_ = create_signature(); - this->set_signature(&signature_); - this->evaluate_source(); - } - - mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Sample Curve", signature}; + mf::SignatureBuilder builder{"Sample Curve", signature_}; builder.single_input("Curve Index"); builder.single_input("Length"); builder.single_output("Position"); builder.single_output("Tangent"); builder.single_output("Normal"); builder.single_output("Value", src_field_.cpp_type()); - return signature; + this->set_signature(&signature_); + + this->evaluate_source(); } void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc index 102ab492e6b..bca477646c3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc @@ -64,7 +64,14 @@ class ImageFieldsFunction : public mf::MultiFunction { image_(image), image_user_(image_user) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"ImageFunction", signature}; + builder.single_input("Vector"); + builder.single_output("Color"); + builder.single_output("Alpha"); + return signature; + }(); this->set_signature(&signature); image_buffer_ = BKE_image_acquire_ibuf(&image_, &image_user_, &image_lock_); @@ -91,16 +98,6 @@ class ImageFieldsFunction : public mf::MultiFunction { BKE_image_release_ibuf(&image_, image_buffer_, image_lock_); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"ImageFunction", signature}; - builder.single_input("Vector"); - builder.single_output("Color"); - builder.single_output("Alpha"); - return signature; - } - static int wrap_periodic(int x, const int width) { x %= width; diff --git a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc index b8d7586391e..2b7d05c7dff 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc @@ -138,20 +138,17 @@ class ProximityFunction : public mf::MultiFunction { ProximityFunction(GeometrySet target, GeometryNodeProximityTargetType type) : target_(std::move(target)), type_(type) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Geometry Proximity", signature}; + builder.single_input("Source Position"); + builder.single_output("Position"); + builder.single_output("Distance"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Geometry Proximity", signature}; - builder.single_input("Source Position"); - builder.single_output("Position"); - builder.single_output("Distance"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &src_positions = params.readonly_single_input(0, diff --git a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc index a3277b8e3b9..ab4b48ece42 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc @@ -225,14 +225,8 @@ class RaycastFunction : public mf::MultiFunction { { target_.ensure_owns_direct_data(); this->evaluate_target_field(std::move(src_field)); - signature_ = create_signature(); - this->set_signature(&signature_); - } - mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Geometry Proximity", signature}; + mf::SignatureBuilder builder{"Geometry Proximity", signature_}; builder.single_input("Source Position"); builder.single_input("Ray Direction"); builder.single_input("Ray Length"); @@ -243,7 +237,7 @@ class RaycastFunction : public mf::MultiFunction { if (target_data_) { builder.single_output("Attribute", target_data_->type()); } - return signature; + this->set_signature(&signature_); } void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc index 8c5da6dd387..e461d3a8503 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc @@ -200,21 +200,14 @@ class SampleIndexFunction : public mf::MultiFunction { { src_geometry_.ensure_owns_direct_data(); - signature_ = this->create_signature(); + mf::SignatureBuilder builder{"Sample Index", signature_}; + builder.single_input("Index"); + builder.single_output("Value", src_field_.cpp_type()); this->set_signature(&signature_); this->evaluate_field(); } - mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Sample Index", signature}; - builder.single_input("Index"); - builder.single_output("Value", src_field_.cpp_type()); - return signature; - } - void evaluate_field() { const GeometryComponent *component = find_source_component(src_geometry_, domain_); diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc index 87785a7ed44..1d649545b2c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc @@ -245,19 +245,12 @@ class SampleNearestFunction : public mf::MultiFunction { : source_(std::move(geometry)), domain_(domain) { source_.ensure_owns_direct_data(); - signature_ = this->create_signature(); - this->set_signature(&signature_); - this->src_component_ = find_source_component(source_, domain_); - } - mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Sample Nearest", signature}; + mf::SignatureBuilder builder{"Sample Nearest", signature_}; builder.single_input("Position"); builder.single_output("Index"); - return signature; + this->set_signature(&signature_); } void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc index f07623ee649..709bd152c33 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc @@ -139,18 +139,12 @@ class SampleNearestSurfaceFunction : public mf::MultiFunction { : source_(std::move(geometry)), src_field_(std::move(src_field)) { source_.ensure_owns_direct_data(); - signature_ = this->create_signature(); - this->set_signature(&signature_); this->evaluate_source_field(); - } - mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Sample Nearest Surface", signature}; + mf::SignatureBuilder builder{"Sample Nearest Surface", signature_}; builder.single_input("Position"); builder.single_output("Value", src_field_.cpp_type()); - return signature; + this->set_signature(&signature_); } void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc index 42e602826a1..615f2a5ed8d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc @@ -129,19 +129,13 @@ class SampleMeshBarycentricFunction : public mf::MultiFunction { : source_(std::move(geometry)), src_field_(std::move(src_field)) { source_.ensure_owns_direct_data(); - this->set_signature(&signature_); - signature_ = this->create_signature(); this->evaluate_source(); - } - mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Sample Barycentric Triangles", signature}; + mf::SignatureBuilder builder{"Sample Barycentric Triangles", signature_}; builder.single_input("Triangle Index"); builder.single_input("Barycentric Weight"); builder.single_output("Value", src_field_.cpp_type()); - return signature; + this->set_signature(&signature_); } void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override @@ -200,20 +194,18 @@ class ReverseUVSampleFunction : public mf::MultiFunction { : source_(std::move(geometry)), src_uv_map_field_(std::move(src_uv_map_field)) { source_.ensure_owns_direct_data(); - static mf::Signature signature = create_signature(); - this->set_signature(&signature); this->evaluate_source(); - } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Sample UV Surface", signature}; - builder.single_input("Sample UV"); - builder.single_output("Is Valid"); - builder.single_output("Triangle Index"); - builder.single_output("Barycentric Weights"); - return signature; + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Sample UV Surface", signature}; + builder.single_input("Sample UV"); + builder.single_output("Is Valid"); + builder.single_output("Triangle Index"); + builder.single_output("Barycentric Weights"); + return signature; + }(); + this->set_signature(&signature); } void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override diff --git a/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc b/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc index 91ba40de7a6..ff414bbf344 100644 --- a/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc +++ b/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc @@ -94,20 +94,17 @@ class ColorBandFunction : public mf::MultiFunction { public: ColorBandFunction(const ColorBand &color_band) : color_band_(color_band) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Color Band", signature}; + builder.single_input("Value"); + builder.single_output("Color"); + builder.single_output("Alpha"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Color Band", signature}; - builder.single_input("Value"); - builder.single_output("Color"); - builder.single_output("Alpha"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &values = params.readonly_single_input(0, "Value"); diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.cc b/source/blender/nodes/shader/nodes/node_shader_curves.cc index 63d3ab80786..9ae8a6e20f9 100644 --- a/source/blender/nodes/shader/nodes/node_shader_curves.cc +++ b/source/blender/nodes/shader/nodes/node_shader_curves.cc @@ -70,20 +70,17 @@ class CurveVecFunction : public mf::MultiFunction { public: CurveVecFunction(const CurveMapping &cumap) : cumap_(cumap) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Curve Vec", signature}; + builder.single_input("Fac"); + builder.single_input("Vector"); + builder.single_output("Vector"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Curve Vec", signature}; - builder.single_input("Fac"); - builder.single_input("Vector"); - builder.single_output("Vector"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Fac"); @@ -216,20 +213,17 @@ class CurveRGBFunction : public mf::MultiFunction { public: CurveRGBFunction(const CurveMapping &cumap) : cumap_(cumap) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Curve RGB", signature}; + builder.single_input("Fac"); + builder.single_input("Color"); + builder.single_output("Color"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Curve RGB", signature}; - builder.single_input("Fac"); - builder.single_input("Color"); - builder.single_output("Color"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Fac"); @@ -339,20 +333,17 @@ class CurveFloatFunction : public mf::MultiFunction { public: CurveFloatFunction(const CurveMapping &cumap) : cumap_(cumap) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Curve Float", signature}; + builder.single_input("Factor"); + builder.single_input("Value"); + builder.single_output("Value"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Curve Float", signature}; - builder.single_input("Factor"); - builder.single_input("Value"); - builder.single_output("Value"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Factor"); diff --git a/source/blender/nodes/shader/nodes/node_shader_mix.cc b/source/blender/nodes/shader/nodes/node_shader_mix.cc index 9edbdc28dd2..f23be857421 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix.cc @@ -361,21 +361,18 @@ class MixColorFunction : public mf::MultiFunction { MixColorFunction(const bool clamp_factor, const bool clamp_result, const int blend_type) : clamp_factor_(clamp_factor), clamp_result_(clamp_result), blend_type_(blend_type) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"MixColor", signature}; + builder.single_input("Factor"); + builder.single_input("A"); + builder.single_input("B"); + builder.single_output("Result"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"MixColor", signature}; - builder.single_input("Factor"); - builder.single_input("A"); - builder.single_input("B"); - builder.single_output("Result"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Factor"); diff --git a/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc index e21cbff4e12..7ae93857f61 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc @@ -99,21 +99,18 @@ class MixRGBFunction : public mf::MultiFunction { public: MixRGBFunction(bool clamp, int type) : clamp_(clamp), type_(type) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"MixRGB", signature}; + builder.single_input("Fac"); + builder.single_input("Color1"); + builder.single_input("Color2"); + builder.single_output("Color"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"MixRGB", signature}; - builder.single_input("Fac"); - builder.single_input("Color1"); - builder.single_input("Color2"); - builder.single_output("Color"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Fac"); diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc index 8b2260af17a..83982aabee4 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc @@ -31,21 +31,18 @@ class SeparateRGBFunction : public mf::MultiFunction { public: SeparateRGBFunction() { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Separate RGB", signature}; + builder.single_input("Color"); + builder.single_output("R"); + builder.single_output("G"); + builder.single_output("B"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Separate RGB", signature}; - builder.single_input("Color"); - builder.single_output("R"); - builder.single_output("G"); - builder.single_output("B"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &colors = params.readonly_single_input(0, diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc index 97776b77f63..33c4d4257b4 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc @@ -31,21 +31,18 @@ class MF_SeparateXYZ : public mf::MultiFunction { public: MF_SeparateXYZ() { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Separate XYZ", signature}; + builder.single_input("XYZ"); + builder.single_output("X"); + builder.single_output("Y"); + builder.single_output("Z"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Separate XYZ", signature}; - builder.single_input("XYZ"); - builder.single_output("X"); - builder.single_output("Y"); - builder.single_output("Z"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &vectors = params.readonly_single_input(0, "XYZ"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc index 789aaee5e64..62e1c14714c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc @@ -122,29 +122,26 @@ class BrickFunction : public mf::MultiFunction { const int squash_freq) : offset_(offset), offset_freq_(offset_freq), squash_(squash), squash_freq_(squash_freq) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"BrickTexture", signature}; + builder.single_input("Vector"); + builder.single_input("Color1"); + builder.single_input("Color2"); + builder.single_input("Mortar"); + builder.single_input("Scale"); + builder.single_input("Mortar Size"); + builder.single_input("Mortar Smooth"); + builder.single_input("Bias"); + builder.single_input("Brick Width"); + builder.single_input("Row Height"); + builder.single_output("Color"); + builder.single_output("Fac"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"BrickTexture", signature}; - builder.single_input("Vector"); - builder.single_input("Color1"); - builder.single_input("Color2"); - builder.single_input("Mortar"); - builder.single_input("Scale"); - builder.single_input("Mortar Size"); - builder.single_input("Mortar Smooth"); - builder.single_input("Bias"); - builder.single_input("Brick Width"); - builder.single_input("Row Height"); - builder.single_output("Color"); - builder.single_output("Fac"); - return signature; - } - /* Fast integer noise. */ static float brick_noise(uint n) { diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc index 3c6404f1aa6..ee1e3758e24 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc @@ -48,23 +48,20 @@ class NodeTexChecker : public mf::MultiFunction { public: NodeTexChecker() { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"Checker", signature}; + builder.single_input("Vector"); + builder.single_input("Color1"); + builder.single_input("Color2"); + builder.single_input("Scale"); + builder.single_output("Color"); + builder.single_output("Fac"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"Checker", signature}; - builder.single_input("Vector"); - builder.single_input("Color1"); - builder.single_input("Color2"); - builder.single_input("Scale"); - builder.single_output("Color"); - builder.single_output("Fac"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc index 8a28b2f455a..2c0e22dcbbd 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc @@ -54,20 +54,17 @@ class GradientFunction : public mf::MultiFunction { public: GradientFunction(int gradient_type) : gradient_type_(gradient_type) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"GradientFunction", signature}; + builder.single_input("Vector"); + builder.single_output("Color"); + builder.single_output("Fac"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"GradientFunction", signature}; - builder.single_input("Vector"); - builder.single_output("Color"); - builder.single_output("Fac"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc index 5cf3c67b50d..0228ed5535f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc @@ -55,22 +55,19 @@ class MagicFunction : public mf::MultiFunction { public: MagicFunction(int depth) : depth_(depth) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"MagicFunction", signature}; + builder.single_input("Vector"); + builder.single_input("Scale"); + builder.single_input("Distortion"); + builder.single_output("Color"); + builder.single_output("Fac"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"MagicFunction", signature}; - builder.single_input("Vector"); - builder.single_input("Scale"); - builder.single_input("Distortion"); - builder.single_output("Color"); - builder.single_output("Fac"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc index 9fb712efeec..ffb7cc6350a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc @@ -94,26 +94,23 @@ class WaveFunction : public mf::MultiFunction { rings_direction_(rings_direction), wave_profile_(wave_profile) { - static mf::Signature signature = create_signature(); + static const mf::Signature signature = []() { + mf::Signature signature; + mf::SignatureBuilder builder{"MagicFunction", signature}; + builder.single_input("Vector"); + builder.single_input("Scale"); + builder.single_input("Distortion"); + builder.single_input("Detail"); + builder.single_input("Detail Scale"); + builder.single_input("Detail Roughness"); + builder.single_input("Phase Offset"); + builder.single_output("Color"); + builder.single_output("Fac"); + return signature; + }(); this->set_signature(&signature); } - static mf::Signature create_signature() - { - mf::Signature signature; - mf::SignatureBuilder builder{"MagicFunction", signature}; - builder.single_input("Vector"); - builder.single_input("Scale"); - builder.single_input("Distortion"); - builder.single_input("Detail"); - builder.single_input("Detail Scale"); - builder.single_input("Detail Roughness"); - builder.single_input("Phase Offset"); - builder.single_output("Color"); - builder.single_output("Fac"); - return signature; - } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); From c4d4db39dc2e38fb9db50eb89caf9759e79da7e4 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 7 Jan 2023 20:23:20 +0100 Subject: [PATCH 0503/1522] Functions: enable more gcc optimizations for multi-functions This mainly helps GCC catch up with Clang in terms of field evaluation performance in some cases. In some cases this patch can speedup field evaluation 2-3x (e.g. when there are many float math nodes). See D16942 for a more detailed benchmark. --- .../functions/FN_multi_function_builder.hh | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index 997f52f4066..20b28658932 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -124,13 +124,19 @@ namespace detail { * instead of a `VArray`). */ template -void execute_array(TypeSequence /*param_tags*/, - std::index_sequence /*indices*/, - ElementFn element_fn, - MaskT mask, - /* Use restrict to tell the compiler that pointer inputs do not alias each - * other. This is important for some compiler optimizations. */ - Args &&__restrict... args) +/* Perform additional optimizations on this loop because it is a very hot loop. For example, the + * math node in geometry nodes is processed here. */ +#if (defined(__GNUC__) && !defined(__clang__)) +[[gnu::optimize("-funroll-loops")]] [[gnu::optimize("O3")]] +#endif +void execute_array( + TypeSequence /*param_tags*/, + std::index_sequence /*indices*/, + ElementFn element_fn, + MaskT mask, + /* Use restrict to tell the compiler that pointer inputs do not alias each + * other. This is important for some compiler optimizations. */ + Args &&__restrict... args) { for (const int64_t i : mask) { element_fn([&]() -> decltype(auto) { From 2895c6708656b749b76331a907b539654ca125e1 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Sat, 7 Jan 2023 20:27:23 +0100 Subject: [PATCH 0504/1522] Fix T103408: Cycles deadlock during GPU viewport rendering This was caused by rB0d73d5c1a2, which releases the scene mutex during kernel loading. However, the reset mutex was still held, which can cause a deadlock if another thread tries to reset the session, since it will acquire the released scene mutex and then wait for the reset mutex. Turns out there's no point in keeping the reset mutex locked after the delayed reset section, so now we just release it earlier, which resolves the deadlock. --- intern/cycles/session/session.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/intern/cycles/session/session.cpp b/intern/cycles/session/session.cpp index 9fa7f5da296..9e7e0e6e2a4 100644 --- a/intern/cycles/session/session.cpp +++ b/intern/cycles/session/session.cpp @@ -289,19 +289,24 @@ RenderWork Session::run_update_for_next_iteration() RenderWork render_work; thread_scoped_lock scene_lock(scene->mutex); - thread_scoped_lock reset_lock(delayed_reset_.mutex); bool have_tiles = true; bool switched_to_new_tile = false; + bool did_reset = false; - const bool did_reset = delayed_reset_.do_reset; - if (delayed_reset_.do_reset) { - thread_scoped_lock buffers_lock(buffers_mutex_); - do_delayed_reset(); + /* Perform delayed reset if requested. */ + { + thread_scoped_lock reset_lock(delayed_reset_.mutex); + if (delayed_reset_.do_reset) { + did_reset = true; - /* After reset make sure the tile manager is at the first big tile. */ - have_tiles = tile_manager_.next(); - switched_to_new_tile = true; + thread_scoped_lock buffers_lock(buffers_mutex_); + do_delayed_reset(); + + /* After reset make sure the tile manager is at the first big tile. */ + have_tiles = tile_manager_.next(); + switched_to_new_tile = true; + } } /* Update number of samples in the integrator. From e22247a965e2c55be08a9b091f5663a55d7a59ca Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 7 Jan 2023 20:54:14 +0100 Subject: [PATCH 0505/1522] Fix: crash when opening file with visible node editor Caused by rB87fd798ae383a344d51dcbd9f66d5834595bdc5a. --- source/blender/editors/space_node/node_edit.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 336ed1cb6d3..fa26455f01c 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -1131,6 +1131,10 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode, snode.edittree->ensure_topology_cache(); const Span socket_locations = snode.runtime->all_socket_locations; + if (socket_locations.is_empty()) { + /* Sockets haven't been drawn yet, e.g. when the file is currently opening. */ + return nullptr; + } const Span nodes = snode.edittree->all_nodes(); for (int i = nodes.index_range().last(); i >= 0; i--) { From ef78811ac7b15f20d2aacd1a148998d0bbb25642 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 7 Jan 2023 23:49:36 +0100 Subject: [PATCH 0506/1522] Cleanup: add missing inline --- .../functions/FN_multi_function_builder.hh | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index 20b28658932..22c6e8a850e 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -129,14 +129,14 @@ template /*param_tags*/, - std::index_sequence /*indices*/, - ElementFn element_fn, - MaskT mask, - /* Use restrict to tell the compiler that pointer inputs do not alias each - * other. This is important for some compiler optimizations. */ - Args &&__restrict... args) +inline void +execute_array(TypeSequence /*param_tags*/, + std::index_sequence /*indices*/, + ElementFn element_fn, + MaskT mask, + /* Use restrict to tell the compiler that pointer inputs do not alias each + * other. This is important for some compiler optimizations. */ + Args &&__restrict... args) { for (const int64_t i : mask) { element_fn([&]() -> decltype(auto) { @@ -174,11 +174,11 @@ template struct MaterializeArgInfo { * Similar to #execute_array but accepts two mask inputs, one for inputs and one for outputs. */ template -void execute_materialized_impl(TypeSequence /*param_tags*/, - const ElementFn element_fn, - const IndexRange in_mask, - const IndexMask out_mask, - Chunks &&__restrict... chunks) +inline void execute_materialized_impl(TypeSequence /*param_tags*/, + const ElementFn element_fn, + const IndexRange in_mask, + const IndexMask out_mask, + Chunks &&__restrict... chunks) { BLI_assert(in_mask.size() == out_mask.size()); for (const int64_t i : IndexRange(in_mask.size())) { @@ -205,11 +205,11 @@ void execute_materialized_impl(TypeSequence /*param_tags*/, * chunks, which reduces virtual function call overhead. */ template -void execute_materialized(TypeSequence /* param_tags */, - std::index_sequence /* indices */, - const ElementFn element_fn, - const IndexMask mask, - const std::tuple &loaded_params) +inline void execute_materialized(TypeSequence /* param_tags */, + std::index_sequence /* indices */, + const ElementFn element_fn, + const IndexMask mask, + const std::tuple &loaded_params) { /* In theory, all elements could be processed in one chunk. However, that has the disadvantage From d4c085c17d135df810951d5dff4c2693916ff1d6 Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Sun, 8 Jan 2023 14:03:22 +0100 Subject: [PATCH 0507/1522] Metal: Resolve failing assertions relating to memory sizing and texture swizzle. Required texture bytesize calculation for compacted data types was incorrectly calculated, resulting in an erroneous format conversion taking place instead of direct data upload. Metal dummy buffer size also temporarily increased to address problematic cases where the bound buffer was too small for missing UBOs. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D16904 --- source/blender/gpu/intern/gpu_texture_private.hh | 8 ++++++++ source/blender/gpu/metal/mtl_context.mm | 7 ++++++- source/blender/gpu/metal/mtl_texture.mm | 2 +- source/blender/imbuf/intern/util_gpu.c | 4 ++-- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh index 35e0bf7b953..554c1e03d77 100644 --- a/source/blender/gpu/intern/gpu_texture_private.hh +++ b/source/blender/gpu/intern/gpu_texture_private.hh @@ -477,6 +477,14 @@ inline size_t to_bytesize(eGPUDataFormat data_format) inline size_t to_bytesize(eGPUTextureFormat tex_format, eGPUDataFormat data_format) { + /* Special case for compacted types. + * Standard component len calcualtion does not apply, as the texture formats contain multiple + * channels, but associated data format contains several compacted components. */ + if ((tex_format == GPU_R11F_G11F_B10F && data_format == GPU_DATA_10_11_11_REV) || + (tex_format == GPU_RGB10_A2 && data_format == GPU_DATA_2_10_10_10_REV)) { + return 4; + } + return to_component_len(tex_format) * to_bytesize(data_format); } diff --git a/source/blender/gpu/metal/mtl_context.mm b/source/blender/gpu/metal/mtl_context.mm index 530ea35294e..9ccb91f1104 100644 --- a/source/blender/gpu/metal/mtl_context.mm +++ b/source/blender/gpu/metal/mtl_context.mm @@ -480,7 +480,12 @@ id MTLContext::get_null_buffer() return null_buffer_; } - static const int null_buffer_size = 4096; + /* TODO(mpw_apple_gpusw): Null buffer size temporarily increased to cover + * maximum possible UBO size. There are a number of cases which need to be + * resolved in the high level where an expected UBO does not have a bound + * buffer. The null buffer needs to at least cover the size of these + * UBOs to avoid any GPU memory issues. */ + static const int null_buffer_size = 20480; null_buffer_ = [this->device newBufferWithLength:null_buffer_size options:MTLResourceStorageModeManaged]; [null_buffer_ retain]; diff --git a/source/blender/gpu/metal/mtl_texture.mm b/source/blender/gpu/metal/mtl_texture.mm index d2d466bffe1..2d6ee9a8e6a 100644 --- a/source/blender/gpu/metal/mtl_texture.mm +++ b/source/blender/gpu/metal/mtl_texture.mm @@ -473,7 +473,7 @@ void gpu::MTLTexture::update_sub( @autoreleasepool { /* Determine totalsize of INPUT Data. */ int num_channels = to_component_len(format_); - int input_bytes_per_pixel = num_channels * to_bytesize(type); + int input_bytes_per_pixel = to_bytesize(format_, type); int totalsize = 0; /* If unpack row length is used, size of input data uses the unpack row length, rather than the diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c index 5bd18ee028a..9f4e2cf179c 100644 --- a/source/blender/imbuf/intern/util_gpu.c +++ b/source/blender/imbuf/intern/util_gpu.c @@ -252,11 +252,11 @@ GPUTexture *IMB_touch_gpu_texture(const char *name, GPUTexture *tex; if (layers > 0) { tex = GPU_texture_create_2d_array_ex( - name, w, h, layers, 9999, tex_format, GPU_TEXTURE_USAGE_SHADER_READ, NULL); + name, w, h, layers, 9999, tex_format, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW, NULL); } else { tex = GPU_texture_create_2d_ex( - name, w, h, 9999, tex_format, GPU_TEXTURE_USAGE_SHADER_READ, NULL); + name, w, h, 9999, tex_format, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW, NULL); } GPU_texture_swizzle_set(tex, imb_gpu_get_swizzle(ibuf)); From 5f9a48ed59782e9b0b0c69bb7a2d869888434b07 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 8 Jan 2023 15:04:51 +0100 Subject: [PATCH 0508/1522] Functions: improve compiler optimizability of multi-function evaluation This simplifies the code enough so that msvc is able to unroll and vectorize some multi-functions like simple addition. The performance improvements are almost as good as the GCC improvements shown in D16942 (for add and multiply at least). --- .../functions/FN_multi_function_builder.hh | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index 22c6e8a850e..04849bcc221 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -138,23 +138,18 @@ execute_array(TypeSequence /*param_tags*/, * other. This is important for some compiler optimizations. */ Args &&__restrict... args) { - for (const int64_t i : mask) { - element_fn([&]() -> decltype(auto) { - using ParamTag = typename TypeSequence::template at_index; - if constexpr (ParamTag::category == ParamCategory::SingleInput) { - /* For inputs, pass the value (or a reference to it) to the function. */ - return args[i]; - } - else if constexpr (ParamTag::category == ParamCategory::SingleOutput) { - /* For outputs, pass a pointer to the function. This is done instead of passing a - * reference, because the pointer points to uninitialized memory. */ - return args + i; - } - else if constexpr (ParamTag::category == ParamCategory::SingleMutable) { - /* For mutables, pass a mutable reference to the function. */ - return args[i]; - } - }()...); + if constexpr (std::is_same_v, IndexRange>) { + /* Having this explicit loop is necessary for msvc to be able to vectorize this. */ + const int64_t start = mask.start(); + const int64_t end = mask.one_after_last(); + for (int64_t i = start; i < end; i++) { + element_fn(args[i]...); + } + } + else { + for (const int32_t i : mask) { + element_fn(args[i]...); + } } } @@ -190,7 +185,7 @@ inline void execute_materialized_impl(TypeSequence /*param_tags*/, return chunks[in_i]; } else if constexpr (ParamTag::category == ParamCategory::SingleOutput) { - return chunks + out_i; + return chunks[out_i]; } else if constexpr (ParamTag::category == ParamCategory::SingleMutable) { return chunks[out_i]; @@ -472,7 +467,7 @@ inline auto build_multi_function_with_n_inputs_one_output(const char *name, constexpr auto param_tags = TypeSequence..., MFParamTag>(); auto call_fn = build_multi_function_call_from_element_fn( - [element_fn](const In &...in, Out *out) { new (out) Out(element_fn(in...)); }, + [element_fn](const In &...in, Out &out) { new (&out) Out(element_fn(in...)); }, exec_preset, param_tags); return CustomMF(name, call_fn, param_tags); From d8750aa1daf327bd3f369c2f4b467a72513bd92f Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 8 Jan 2023 15:17:09 +0100 Subject: [PATCH 0509/1522] Fix T103734: reroutes don't propagate attribute references correctly --- .../intern/node_tree_anonymous_attributes.cc | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/node_tree_anonymous_attributes.cc b/source/blender/blenkernel/intern/node_tree_anonymous_attributes.cc index 9ade129afb5..d355f6a768c 100644 --- a/source/blender/blenkernel/intern/node_tree_anonymous_attributes.cc +++ b/source/blender/blenkernel/intern/node_tree_anonymous_attributes.cc @@ -14,6 +14,11 @@ namespace blender::bke::anonymous_attribute_inferencing { namespace aal = nodes::aal; using nodes::NodeDeclaration; +static bool socket_is_field(const bNodeSocket &socket) +{ + return socket.display_shape == SOCK_DISPLAY_SHAPE_DIAMOND; +} + static const aal::RelationsInNode &get_relations_in_node(const bNode &node, ResourceScope &scope) { if (node.is_group()) { @@ -22,6 +27,25 @@ static const aal::RelationsInNode &get_relations_in_node(const bNode &node, Reso return *group->runtime->anonymous_attribute_relations; } } + if (node.is_reroute()) { + const bNodeSocket &socket = node.input_socket(0); + if (socket_is_field(socket)) { + static const aal::RelationsInNode field_relations = []() { + aal::RelationsInNode relations; + relations.reference_relations.append({0, 0}); + return relations; + }(); + return field_relations; + } + if (socket.type == SOCK_GEOMETRY) { + static const aal::RelationsInNode geometry_relations = []() { + aal::RelationsInNode relations; + relations.propagate_relations.append({0, 0}); + return relations; + }(); + return geometry_relations; + } + } if (const NodeDeclaration *node_decl = node.declaration()) { if (const aal::RelationsInNode *relations = node_decl->anonymous_attribute_relations()) { return *relations; @@ -41,11 +65,6 @@ Array get_relations_by_node(const bNodeTree &tree, return relations_by_node; } -static bool socket_is_field(const bNodeSocket &socket) -{ - return socket.display_shape == SOCK_DISPLAY_SHAPE_DIAMOND; -} - /** * Start at a group output socket and find all linked group inputs. */ From 710f8164b4ed92f917f4b385bf834cc3dd34c80e Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 8 Jan 2023 15:19:39 +0100 Subject: [PATCH 0510/1522] Fix: crash when inserting reroute node --- source/blender/editors/space_node/node_edit.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index fa26455f01c..ebcef77baef 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -1131,7 +1131,7 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode, snode.edittree->ensure_topology_cache(); const Span socket_locations = snode.runtime->all_socket_locations; - if (socket_locations.is_empty()) { + if (socket_locations.size() != snode.edittree->all_sockets().size()) { /* Sockets haven't been drawn yet, e.g. when the file is currently opening. */ return nullptr; } From b1d2ea3e1b1173122eebecda0c3bd7552f4ee9c1 Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Sun, 8 Jan 2023 15:40:40 +0100 Subject: [PATCH 0511/1522] Metal: Add gl_PrimitiveID support. Resolves failing Mesh Snap utilities line add-on. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D16905 --- source/blender/gpu/metal/mtl_shader_generator.hh | 1 + source/blender/gpu/metal/mtl_shader_generator.mm | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/source/blender/gpu/metal/mtl_shader_generator.hh b/source/blender/gpu/metal/mtl_shader_generator.hh index f4cf42deb68..90f9a86b064 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.hh +++ b/source/blender/gpu/metal/mtl_shader_generator.hh @@ -391,6 +391,7 @@ class MSLGeneratorInterface { bool uses_gl_InstanceID; bool uses_gl_BaseInstanceARB; bool uses_gl_FrontFacing; + bool uses_gl_PrimitiveID; /* Sets the output render target array index when using multilayered rendering. */ bool uses_gl_FragDepth; bool uses_mtl_array_index_; diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm index 9ed1461f857..fc37263d239 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.mm +++ b/source/blender/gpu/metal/mtl_shader_generator.mm @@ -670,6 +670,9 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info) msl_iface.uses_gl_FrontFacing = bool(info->builtins_ & BuiltinBits::FRONT_FACING) || shd_builder_->glsl_fragment_source_.find("gl_FrontFacing") != std::string::npos; + msl_iface.uses_gl_PrimitiveID = bool(info->builtins_ & BuiltinBits::PRIMITIVE_ID) || + shd_builder_->glsl_fragment_source_.find("gl_PrimitiveID") != + std::string::npos; /* NOTE(Metal): If FragColor is not used, then we treat the first fragment output attachment * as the primary output. */ @@ -990,6 +993,9 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info) if (msl_iface.uses_gl_FrontFacing) { ss_fragment << "MTLBOOL gl_FrontFacing;" << std::endl; } + if (msl_iface.uses_gl_PrimitiveID) { + ss_fragment << "uint gl_PrimitiveID;" << std::endl; + } /* Add Texture members. */ for (const MSLTextureSampler &tex : msl_iface.texture_samplers) { @@ -1515,6 +1521,9 @@ std::string MSLGeneratorInterface::generate_msl_fragment_entry_stub() if (this->uses_gl_FrontFacing) { out << "fragment_shader_instance.gl_FrontFacing = gl_FrontFacing;" << std::endl; } + if (this->uses_gl_PrimitiveID) { + out << "fragment_shader_instance.gl_PrimitiveID = gl_PrimitiveID;" << std::endl; + } /* Copy vertex attributes into local variable.s */ out << this->generate_msl_fragment_input_population(); @@ -1690,6 +1699,9 @@ std::string MSLGeneratorInterface::generate_msl_fragment_inputs_string() if (this->uses_gl_FrontFacing) { out << ",\n\tconst MTLBOOL gl_FrontFacing [[front_facing]]"; } + if (this->uses_gl_PrimitiveID) { + out << ",\n\tconst uint gl_PrimitiveID [[primitive_id]]"; + } /* Barycentrics. */ if (this->uses_barycentrics) { From ed8f3dc9c79de72f3b8dd8bdcdf9b47cecb2a541 Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Sun, 8 Jan 2023 15:58:05 +0100 Subject: [PATCH 0512/1522] Fix T103399: correctly apply SRGB framebuffer and shader conversion mode in Metal. First binding of a framebuffer lead to an incorrect SRGB conversion state being applied, as attachments, where presence of SRGB is determined, were processed after the SRGB check rather than before. This DIFF also cleans up SRGB naming conventions and caching of fallback non-srgb texture view, for use when SRGB mode is disabled. Authored by Apple: Michael Parkin-White Ref T103399 Ref T96261 Reviewed By: fclem Maniphest Tasks: T103399, T96261 Differential Revision: https://developer.blender.org/D16907 --- source/blender/gpu/metal/mtl_framebuffer.hh | 8 +++--- source/blender/gpu/metal/mtl_framebuffer.mm | 27 ++++++++++++--------- source/blender/gpu/metal/mtl_texture.hh | 5 ++++ source/blender/gpu/metal/mtl_texture.mm | 24 ++++++++++++++++++ 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/source/blender/gpu/metal/mtl_framebuffer.hh b/source/blender/gpu/metal/mtl_framebuffer.hh index 434d1a15b43..2d3d5fb0730 100644 --- a/source/blender/gpu/metal/mtl_framebuffer.hh +++ b/source/blender/gpu/metal/mtl_framebuffer.hh @@ -100,9 +100,9 @@ class MTLFrameBuffer : public FrameBuffer { /** Whether `MTLRenderPassDescriptor[N]` requires updating with latest state. */ bool descriptor_dirty_[MTL_FB_CONFIG_MAX]; /** Whether SRGB is enabled for this frame-buffer configuration. */ - bool srgb_enabled_; + bool enabled_srgb_; /** Whether the primary Frame-buffer attachment is an SRGB target or not. */ - bool is_srgb_; + bool srgb_; public: /** @@ -223,12 +223,12 @@ class MTLFrameBuffer : public FrameBuffer { bool get_srgb_enabled() { - return srgb_enabled_; + return enabled_srgb_; } bool get_is_srgb() { - return is_srgb_; + return srgb_; } private: diff --git a/source/blender/gpu/metal/mtl_framebuffer.mm b/source/blender/gpu/metal/mtl_framebuffer.mm index 467a4a6f412..dc8741e377b 100644 --- a/source/blender/gpu/metal/mtl_framebuffer.mm +++ b/source/blender/gpu/metal/mtl_framebuffer.mm @@ -27,8 +27,8 @@ MTLFrameBuffer::MTLFrameBuffer(MTLContext *ctx, const char *name) : FrameBuffer( dirty_state_ctx_ = nullptr; has_pending_clear_ = false; colour_attachment_count_ = 0; - srgb_enabled_ = false; - is_srgb_ = false; + enabled_srgb_ = false; + srgb_ = false; for (int i = 0; i < GPU_FB_MAX_COLOR_ATTACHMENT; i++) { mtl_color_attachments_[i].used = false; @@ -99,19 +99,19 @@ void MTLFrameBuffer::bind(bool enabled_srgb) return; } + /* Ensure local MTLAttachment data is up to date. */ + this->update_attachments(true); + /* Ensure SRGB state is up-to-date and valid. */ - bool srgb_state_changed = srgb_enabled_ != enabled_srgb; + bool srgb_state_changed = enabled_srgb_ != enabled_srgb; if (context_->active_fb != this || srgb_state_changed) { if (srgb_state_changed) { this->mark_dirty(); } - srgb_enabled_ = enabled_srgb; - GPU_shader_set_framebuffer_srgb_target(srgb_enabled_ && is_srgb_); + enabled_srgb_ = enabled_srgb; + GPU_shader_set_framebuffer_srgb_target(enabled_srgb && srgb_); } - /* Ensure local MTLAttachment data is up to date. */ - this->update_attachments(true); - /* Reset clear state on bind -- Clears and load/store ops are set after binding. */ this->reset_clear_state(); @@ -740,7 +740,7 @@ void MTLFrameBuffer::update_attachments(bool update_viewport) /* Check whether the first attachment is SRGB. */ if (first_attachment != GPU_FB_MAX_ATTACHMENT) { - is_srgb_ = (first_attachment_mtl.texture->format_get() == GPU_SRGB8_A8); + srgb_ = (first_attachment_mtl.texture->format_get() == GPU_SRGB8_A8); } /* Reset viewport and Scissor (If viewport is smaller or equal to the framebuffer size). */ @@ -1617,10 +1617,13 @@ MTLRenderPassDescriptor *MTLFrameBuffer::bake_render_pass_descriptor(bool load_c } /* IF SRGB is enabled, but we are rendering with SRGB disabled, sample texture view. */ - /* TODO(Metal): Consider caching SRGB texture view. */ id source_color_texture = texture; - if (this->get_is_srgb() && !this->get_srgb_enabled()) { - source_color_texture = [texture newTextureViewWithPixelFormat:MTLPixelFormatRGBA8Unorm]; + if (this->get_is_srgb() && + mtl_color_attachments_[attachment_ind].texture->is_format_srgb() && + !this->get_srgb_enabled()) { + source_color_texture = + mtl_color_attachments_[attachment_ind].texture->get_non_srgb_handle(); + BLI_assert(source_color_texture != nil); } /* Resolve appropriate load action -- IF force load, perform load. diff --git a/source/blender/gpu/metal/mtl_texture.hh b/source/blender/gpu/metal/mtl_texture.hh index 1237e2275b3..7a9cee97d24 100644 --- a/source/blender/gpu/metal/mtl_texture.hh +++ b/source/blender/gpu/metal/mtl_texture.hh @@ -180,6 +180,9 @@ class MTLTexture : public Texture { uint blit_fb_slice_ = 0; uint blit_fb_mip_ = 0; + /* Non-SRGB texture view, used for when a framebuffer is bound with SRGB disabled. */ + id texture_no_srgb_ = nil; + /* Texture view properties */ /* In Metal, we use texture views to either limit mipmap ranges, * , apply a swizzle mask, or both. @@ -251,6 +254,7 @@ class MTLTexture : public Texture { /* Remove once no longer required -- will just return 0 for now in MTL path. */ uint gl_bindcode_get() const override; + bool is_format_srgb(); bool texture_is_baked(); const char *get_name() { @@ -305,6 +309,7 @@ class MTLTexture : public Texture { id get_metal_handle(); id get_metal_handle_base(); + id get_non_srgb_handle(); MTLSamplerState get_sampler_state(); void blit(id blit_encoder, uint src_x_offset, diff --git a/source/blender/gpu/metal/mtl_texture.mm b/source/blender/gpu/metal/mtl_texture.mm index 2d6ee9a8e6a..daf3fb8c36e 100644 --- a/source/blender/gpu/metal/mtl_texture.mm +++ b/source/blender/gpu/metal/mtl_texture.mm @@ -1933,6 +1933,11 @@ void gpu::MTLTexture::reset() is_dirty_ = true; } + if (texture_no_srgb_ != nil) { + [texture_no_srgb_ release]; + texture_no_srgb_ = nil; + } + if (mip_swizzle_view_ != nil) { [mip_swizzle_view_ release]; mip_swizzle_view_ = nil; @@ -1963,6 +1968,25 @@ void gpu::MTLTexture::reset() /** \} */ +/* -------------------------------------------------------------------- */ +/** \name SRGB Handling. + * \{ */ +bool MTLTexture::is_format_srgb() +{ + return (format_ == GPU_SRGB8_A8); +} + +id MTLTexture::get_non_srgb_handle() +{ + id base_tex = get_metal_handle_base(); + BLI_assert(base_tex != nil); + if (texture_no_srgb_ == nil) { + texture_no_srgb_ = [base_tex newTextureViewWithPixelFormat:MTLPixelFormatRGBA8Unorm]; + } + return texture_no_srgb_; +} + +/** \} */ /* -------------------------------------------------------------------- */ /** \name Pixel Buffer * \{ */ From d3f626b535313af616b0574958b2d064fc88c5d3 Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Sun, 8 Jan 2023 16:16:21 +0100 Subject: [PATCH 0513/1522] Fix T103658: Resolve Metal partial texture update overwriting whole image when staging textures are used. Staging texture update copied over the entire texture, rather than just the region of the texture which had been updated. Also added early-exit for cases where the net texture update extent was zero, as this was causing validation failures. Authored by Apple: Michael Parkin-White Ref T103658 Ref T96261 Reviewed By: fclem Maniphest Tasks: T103658, T96261 Differential Revision: https://developer.blender.org/D16924 --- source/blender/gpu/metal/mtl_texture.mm | 92 +++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 7 deletions(-) diff --git a/source/blender/gpu/metal/mtl_texture.mm b/source/blender/gpu/metal/mtl_texture.mm index daf3fb8c36e..043033e6b0e 100644 --- a/source/blender/gpu/metal/mtl_texture.mm +++ b/source/blender/gpu/metal/mtl_texture.mm @@ -457,16 +457,14 @@ void gpu::MTLTexture::update_sub( if (is_depth_format) { switch (type_) { - case GPU_TEXTURE_2D: { + case GPU_TEXTURE_2D: update_sub_depth_2d(mip, offset, extent, type, data); return; - } default: MTL_LOG_ERROR( "[Error] gpu::MTLTexture::update_sub not yet supported for other depth " "configurations\n"); return; - return; } } @@ -488,17 +486,29 @@ void gpu::MTLTexture::update_sub( totalsize = input_bytes_per_pixel * max_ii(expected_update_w, 1); break; case 2: - totalsize = input_bytes_per_pixel * max_ii(expected_update_w, 1) * max_ii(extent[1], 1); + totalsize = input_bytes_per_pixel * max_ii(expected_update_w, 1) * extent[1]; break; case 3: - totalsize = input_bytes_per_pixel * max_ii(expected_update_w, 1) * max_ii(extent[1], 1) * - max_ii(extent[2], 1); + totalsize = input_bytes_per_pixel * max_ii(expected_update_w, 1) * extent[1] * extent[2]; break; default: BLI_assert(false); break; } + /* Early exit if update size is zero. update_sub sometimes has a zero-sized + * extent when called from texture painting. */ + if (totalsize <= 0 || extent[0] <= 0) { + MTL_LOG_WARNING( + "MTLTexture::update_sub called with extent size of zero for one or more dimensions. " + "(%d, %d, %d) - DimCount: %u\n", + extent[0], + extent[1], + extent[2], + this->dimensions_count()); + return; + } + /* When unpack row length is used, provided data does not necessarily contain padding for last * row, so we only include up to the end of updated data. */ if (ctx->pipeline_state.unpack_row_length > 0) { @@ -942,7 +952,75 @@ void gpu::MTLTexture::update_sub( /* When using staging texture, copy results into existing texture. */ BLI_assert(staging_texture != nil); blit_encoder = ctx->main_command_buffer.ensure_begin_blit_encoder(); - [blit_encoder copyFromTexture:staging_texture toTexture:texture_]; + + /* Copy modified staging texture region back to original texture. + * Differing blit dimensions based on type. */ + switch (type_) { + case GPU_TEXTURE_1D: + case GPU_TEXTURE_1D_ARRAY: { + int base_slice = (type_ == GPU_TEXTURE_1D_ARRAY) ? offset[1] : 0; + int final_slice = base_slice + ((type_ == GPU_TEXTURE_1D_ARRAY) ? extent[1] : 1); + for (int array_index = base_slice; array_index < final_slice; array_index++) { + [blit_encoder copyFromTexture:staging_texture + sourceSlice:array_index + sourceLevel:mip + sourceOrigin:MTLOriginMake(offset[0], 0, 0) + sourceSize:MTLSizeMake(extent[0], 1, 1) + toTexture:texture_ + destinationSlice:array_index + destinationLevel:mip + destinationOrigin:MTLOriginMake(offset[0], 0, 0)]; + } + } break; + case GPU_TEXTURE_2D: + case GPU_TEXTURE_2D_ARRAY: { + int base_slice = (type_ == GPU_TEXTURE_2D_ARRAY) ? offset[2] : 0; + int final_slice = base_slice + ((type_ == GPU_TEXTURE_2D_ARRAY) ? extent[2] : 1); + for (int array_index = base_slice; array_index < final_slice; array_index++) { + [blit_encoder copyFromTexture:staging_texture + sourceSlice:array_index + sourceLevel:mip + sourceOrigin:MTLOriginMake(offset[0], offset[1], 0) + sourceSize:MTLSizeMake(extent[0], extent[1], 1) + toTexture:texture_ + destinationSlice:array_index + destinationLevel:mip + destinationOrigin:MTLOriginMake(offset[0], offset[1], 0)]; + } + } break; + case GPU_TEXTURE_3D: { + [blit_encoder copyFromTexture:staging_texture + sourceSlice:0 + sourceLevel:mip + sourceOrigin:MTLOriginMake(offset[0], offset[1], offset[2]) + sourceSize:MTLSizeMake(extent[0], extent[1], extent[2]) + toTexture:texture_ + destinationSlice:0 + destinationLevel:mip + destinationOrigin:MTLOriginMake(offset[0], offset[1], offset[2])]; + } break; + case GPU_TEXTURE_CUBE: + case GPU_TEXTURE_CUBE_ARRAY: { + /* Iterate over all cube faces in range (offset[2], offset[2] + extent[2]). */ + for (int i = 0; i < extent[2]; i++) { + int face_index = offset[2] + i; + [blit_encoder copyFromTexture:staging_texture + sourceSlice:face_index + sourceLevel:mip + sourceOrigin:MTLOriginMake(offset[0], offset[1], 0) + sourceSize:MTLSizeMake(extent[0], extent[1], 1) + toTexture:texture_ + destinationSlice:face_index + destinationLevel:mip + destinationOrigin:MTLOriginMake(offset[0], offset[1], 0)]; + } + } break; + case GPU_TEXTURE_ARRAY: + case GPU_TEXTURE_BUFFER: + BLI_assert_unreachable(); + break; + } + [staging_texture release]; } From 891b97302957dc4df3db6182c4121e39a0775e0b Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 8 Jan 2023 17:19:57 +0100 Subject: [PATCH 0514/1522] Functions: optimize multi-function evaluation in materialized mode This allows auto-vectorization to happen when the a multi-function is evaluated in "materialized" mode, i.e. it is processed in chunks where all input and outputs values are stored in contiguous arrays. It also unifies the handling input, mutable and output parameters a bit. Now they all can use tempory buffers in the same way. --- .../functions/FN_multi_function_builder.hh | 161 +++++++++++------- 1 file changed, 95 insertions(+), 66 deletions(-) diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index 04849bcc221..bfe88e01f04 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -162,35 +162,24 @@ enum class MaterializeArgMode { template struct MaterializeArgInfo { MaterializeArgMode mode = MaterializeArgMode::Unknown; - Span internal_span; + const typename ParamTag::base_type *internal_span_data; }; /** - * Similar to #execute_array but accepts two mask inputs, one for inputs and one for outputs. + * Similar to #execute_array but is only used with arrays and does not need a mask. */ template -inline void execute_materialized_impl(TypeSequence /*param_tags*/, - const ElementFn element_fn, - const IndexRange in_mask, - const IndexMask out_mask, - Chunks &&__restrict... chunks) +#if (defined(__GNUC__) && !defined(__clang__)) +[[gnu::optimize("-funroll-loops")]] [[gnu::optimize("O3")]] +#endif +inline void +execute_materialized_impl(TypeSequence /*param_tags*/, + const ElementFn element_fn, + const int64_t size, + Chunks &&__restrict... chunks) { - BLI_assert(in_mask.size() == out_mask.size()); - for (const int64_t i : IndexRange(in_mask.size())) { - const int64_t in_i = in_mask[i]; - const int64_t out_i = out_mask[i]; - element_fn([&]() -> decltype(auto) { - using ParamTag = ParamTags; - if constexpr (ParamTag::category == ParamCategory::SingleInput) { - return chunks[in_i]; - } - else if constexpr (ParamTag::category == ParamCategory::SingleOutput) { - return chunks[out_i]; - } - else if constexpr (ParamTag::category == ParamCategory::SingleMutable) { - return chunks[out_i]; - } - }()...); + for (int64_t i = 0; i < size; i++) { + element_fn(chunks[i]...); } } @@ -211,15 +200,12 @@ inline void execute_materialized(TypeSequence /* param_tags */, * that large temporary arrays are needed. Using small chunks allows using small arrays, which * are reused multiple times, which improves cache efficiency. The chunk size also shouldn't be * too small, because then overhead of the outer loop over chunks becomes significant again. */ - static constexpr int64_t MaxChunkSize = 32; + static constexpr int64_t MaxChunkSize = 64; const int64_t mask_size = mask.size(); - const int64_t buffer_size = std::min(mask_size, MaxChunkSize); + const int64_t tmp_buffer_size = std::min(mask_size, MaxChunkSize); - /* Local buffers that are used to temporarily store values retrieved from virtual arrays. */ - std::tuple...> buffers_owner; - - /* A span for each parameter which is either empty or points to memory in #buffers_owner. */ - std::tuple...> buffers; + /* Local buffers that are used to temporarily store values for processing. */ + std::tuple...> temporary_buffers; /* Information about every parameter. */ std::tuple...> args_info; @@ -237,16 +223,17 @@ inline void execute_materialized(TypeSequence /* param_tags */, if (common_info.type == CommonVArrayInfo::Type::Single) { /* If an input #VArray is a single value, we have to fill the buffer with that value * only once. The same unchanged buffer can then be reused in every chunk. */ - MutableSpan in_chunk{std::get(buffers_owner).ptr(), buffer_size}; const T &in_single = *static_cast(common_info.data); - uninitialized_fill_n(in_chunk.data(), in_chunk.size(), in_single); - std::get(buffers) = in_chunk; + T *tmp_buffer = std::get(temporary_buffers).ptr(); + uninitialized_fill_n(tmp_buffer, tmp_buffer_size, in_single); arg_info.mode = MaterializeArgMode::Single; } else if (common_info.type == CommonVArrayInfo::Type::Span) { /* Remember the span so that it doesn't have to be retrieved in every iteration. */ - const T *ptr = static_cast(common_info.data); - arg_info.internal_span = Span(ptr, varray_impl.size()); + arg_info.internal_span_data = static_cast(common_info.data); + } + else { + arg_info.internal_span_data = nullptr; } } }(), @@ -254,56 +241,98 @@ inline void execute_materialized(TypeSequence /* param_tags */, /* Outer loop over all chunks. */ for (int64_t chunk_start = 0; chunk_start < mask_size; chunk_start += MaxChunkSize) { - const IndexMask sliced_mask = mask.slice_safe(chunk_start, MaxChunkSize); - const int64_t chunk_size = sliced_mask.size(); + const int64_t chunk_end = std::min(chunk_start + MaxChunkSize, mask_size); + const int64_t chunk_size = chunk_end - chunk_start; + const IndexMask sliced_mask = mask.slice(chunk_start, chunk_size); + const int64_t mask_start = sliced_mask[0]; const bool sliced_mask_is_range = sliced_mask.is_range(); + /* Move mutable data into temporary array. */ + if (!sliced_mask_is_range) { + ( + [&] { + /* Use `typedef` instead of `using` to work around a compiler bug. */ + typedef ParamTags ParamTag; + typedef typename ParamTag::base_type T; + if constexpr (ParamTag::category == ParamCategory::SingleMutable) { + T *tmp_buffer = std::get(temporary_buffers).ptr(); + T *param_buffer = std::get(loaded_params); + for (int64_t i = 0; i < chunk_size; i++) { + new (tmp_buffer + i) T(std::move(param_buffer[sliced_mask[i]])); + } + } + }(), + ...); + } + execute_materialized_impl( TypeSequence(), element_fn, - /* Inputs are "compressed" into contiguous arrays without gaps. */ - IndexRange(chunk_size), - /* Outputs are written directly into the correct place in the output arrays. */ - sliced_mask, + chunk_size, /* Prepare every parameter for this chunk. */ [&] { using ParamTag = ParamTags; using T = typename ParamTag::base_type; [[maybe_unused]] MaterializeArgInfo &arg_info = std::get(args_info); + T *tmp_buffer = std::get(temporary_buffers); if constexpr (ParamTag::category == ParamCategory::SingleInput) { if (arg_info.mode == MaterializeArgMode::Single) { /* The single value has been filled into a buffer already reused for every chunk. */ - return Span(std::get(buffers)); + return const_cast(tmp_buffer); } - else { - if (sliced_mask_is_range) { - if (!arg_info.internal_span.is_empty()) { - /* In this case we can just use an existing span instead of "compressing" it into - * a new temporary buffer. */ - const IndexRange sliced_mask_range = sliced_mask.as_range(); - arg_info.mode = MaterializeArgMode::Span; - return arg_info.internal_span.slice(sliced_mask_range); - } - } - const GVArrayImpl &varray_impl = *std::get(loaded_params); - /* As a fallback, do a virtual function call to retrieve all elements in the current - * chunk. The elements are stored in a temporary buffer reused for every chunk. */ - MutableSpan in_chunk{std::get(buffers_owner).ptr(), chunk_size}; - varray_impl.materialize_compressed_to_uninitialized(sliced_mask, in_chunk.data()); - /* Remember that this parameter has been materialized, so that the values are - * destructed properly when the chunk is done. */ - arg_info.mode = MaterializeArgMode::Materialized; - return Span(in_chunk); + if (sliced_mask_is_range && arg_info.internal_span_data != nullptr) { + /* In this case we can just use an existing span instead of "compressing" it into + * a new temporary buffer. */ + arg_info.mode = MaterializeArgMode::Span; + return arg_info.internal_span_data + mask_start; } + const GVArrayImpl &varray_impl = *std::get(loaded_params); + /* As a fallback, do a virtual function call to retrieve all elements in the current + * chunk. The elements are stored in a temporary buffer reused for every chunk. */ + varray_impl.materialize_compressed_to_uninitialized(sliced_mask, tmp_buffer); + /* Remember that this parameter has been materialized, so that the values are + * destructed properly when the chunk is done. */ + arg_info.mode = MaterializeArgMode::Materialized; + return const_cast(tmp_buffer); } else if constexpr (ELEM(ParamTag::category, ParamCategory::SingleOutput, ParamCategory::SingleMutable)) { /* For outputs, just pass a pointer. This is important so that `__restrict` works. */ - return std::get(loaded_params); + if (sliced_mask_is_range) { + /* Can write into the caller-provided buffer directly. */ + T *param_buffer = std::get(loaded_params); + return param_buffer + mask_start; + } + else { + /* Use the temporary buffer. The values will have to be copied out of that + * buffer into the caller-provided buffer afterwards. */ + return const_cast(tmp_buffer); + } } }()...); + /* Relocate outputs from temporary buffers to buffers provided by caller. */ + if (!sliced_mask_is_range) { + ( + [&] { + /* Use `typedef` instead of `using` to work around a compiler bug. */ + typedef ParamTags ParamTag; + typedef typename ParamTag::base_type T; + if constexpr (ELEM(ParamTag::category, + ParamCategory::SingleOutput, + ParamCategory::SingleMutable)) { + T *tmp_buffer = std::get(temporary_buffers).ptr(); + T *param_buffer = std::get(loaded_params); + for (int64_t i = 0; i < chunk_size; i++) { + new (param_buffer + sliced_mask[i]) T(std::move(tmp_buffer[i])); + std::destroy_at(tmp_buffer + i); + } + } + }(), + ...); + } + ( /* Destruct values that have been materialized before. */ [&] { @@ -313,8 +342,8 @@ inline void execute_materialized(TypeSequence /* param_tags */, [[maybe_unused]] MaterializeArgInfo &arg_info = std::get(args_info); if constexpr (ParamTag::category == ParamCategory::SingleInput) { if (arg_info.mode == MaterializeArgMode::Materialized) { - T *in_chunk = std::get(buffers_owner).ptr(); - destruct_n(in_chunk, chunk_size); + T *tmp_buffer = std::get(temporary_buffers).ptr(); + destruct_n(tmp_buffer, chunk_size); } } }(), @@ -330,8 +359,8 @@ inline void execute_materialized(TypeSequence /* param_tags */, [[maybe_unused]] MaterializeArgInfo &arg_info = std::get(args_info); if constexpr (ParamTag::category == ParamCategory::SingleInput) { if (arg_info.mode == MaterializeArgMode::Single) { - MutableSpan in_chunk = std::get(buffers); - destruct_n(in_chunk.data(), in_chunk.size()); + T *tmp_buffer = std::get(temporary_buffers).ptr(); + destruct_n(tmp_buffer, tmp_buffer_size); } } }(), From 73a2c79c074ae0e3f5cbc970df0d502672aa2986 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 8 Jan 2023 21:09:33 +0100 Subject: [PATCH 0515/1522] Functions: free memory of unused sockets earlier During geometry nodes evaluation some sockets can be determined to be unused, for example based on the condition input in a switch node. Once a socket is determined to be unused, that information has to be propagated backwards through the tree to free any memory that may have been reserved for those sockets already. This is happening before this commit already, but in a less ideal way. Determining that sockets are unused early is good because it helps with memory reuse and avoids copy-on-write copies caused by shared data. Now, nodes that are scheduled because an output became unused have priority over nodes scheduled for other reasons. --- .../intern/lazy_function_graph_executor.cc | 97 ++++++++++++++----- 1 file changed, 71 insertions(+), 26 deletions(-) diff --git a/source/blender/functions/intern/lazy_function_graph_executor.cc b/source/blender/functions/intern/lazy_function_graph_executor.cc index c7688f61460..4270885fc98 100644 --- a/source/blender/functions/intern/lazy_function_graph_executor.cc +++ b/source/blender/functions/intern/lazy_function_graph_executor.cc @@ -206,6 +206,44 @@ struct LockedNode { class Executor; class GraphExecutorLFParams; +/** + * Keeps track of nodes that are currently scheduled on a thread. A node can only be scheduled by + * one thread at the same time. + */ +struct ScheduledNodes { + private: + /** Use two stacks of scheduled nodes for different priorities. */ + Vector priority_; + Vector normal_; + + public: + void schedule(const FunctionNode &node, const bool is_priority) + { + if (is_priority) { + this->priority_.append(&node); + } + else { + this->normal_.append(&node); + } + } + + const FunctionNode *pop_next_node() + { + if (!this->priority_.is_empty()) { + return this->priority_.pop_last(); + } + if (!this->normal_.is_empty()) { + return this->normal_.pop_last(); + } + return nullptr; + } + + bool is_empty() const + { + return this->priority_.is_empty() && this->normal_.is_empty(); + } +}; + struct CurrentTask { /** * Mutex used to protect #scheduled_nodes when the executor uses multi-threading. @@ -214,7 +252,7 @@ struct CurrentTask { /** * Nodes that have been scheduled to execute next. */ - Vector scheduled_nodes; + ScheduledNodes scheduled_nodes; /** * Makes it cheaper to check if there are any scheduled nodes because it avoids locking the * mutex. @@ -330,7 +368,7 @@ class Executor { this->schedule_side_effect_nodes(side_effect_nodes, current_task); } - this->schedule_newly_requested_outputs(current_task); + this->schedule_for_new_output_usages(current_task); this->forward_newly_provided_inputs(current_task); this->run_task(current_task); @@ -394,20 +432,29 @@ class Executor { std::destroy_at(&node_state); } - void schedule_newly_requested_outputs(CurrentTask ¤t_task) + /** + * When the usage of output values changed, propagate that information backwards. + */ + void schedule_for_new_output_usages(CurrentTask ¤t_task) { for (const int graph_output_index : self_.graph_outputs_.index_range()) { - if (params_->get_output_usage(graph_output_index) != ValueUsage::Used) { + if (params_->output_was_set(graph_output_index)) { continue; } - if (params_->output_was_set(graph_output_index)) { + const ValueUsage output_usage = params_->get_output_usage(graph_output_index); + if (output_usage == ValueUsage::Maybe) { continue; } const InputSocket &socket = *self_.graph_outputs_[graph_output_index]; const Node &node = socket.node(); NodeState &node_state = *node_states_[node.index_in_graph()]; this->with_locked_node(node, node_state, current_task, [&](LockedNode &locked_node) { - this->set_input_required(locked_node, socket); + if (output_usage == ValueUsage::Used) { + this->set_input_required(locked_node, socket); + } + else { + this->set_input_unused(locked_node, socket); + } }); } } @@ -532,7 +579,7 @@ class Executor { for (const FunctionNode *node : side_effect_nodes) { NodeState &node_state = *node_states_[node->index_in_graph()]; this->with_locked_node(*node, node_state, current_task, [&](LockedNode &locked_node) { - this->schedule_node(locked_node, current_task); + this->schedule_node(locked_node, current_task, false); }); } } @@ -603,7 +650,7 @@ class Executor { return; } output_state.usage = ValueUsage::Used; - this->schedule_node(locked_node, current_task); + this->schedule_node(locked_node, current_task, false); }); } @@ -625,14 +672,16 @@ class Executor { params_->set_input_unused(graph_input_index); } else { - this->schedule_node(locked_node, current_task); + /* Schedule as priority node. This allows freeing up memory earlier which results in + * better memory reuse and less copy-on-write copies caused by shared data. */ + this->schedule_node(locked_node, current_task, true); } } } }); } - void schedule_node(LockedNode &locked_node, CurrentTask ¤t_task) + void schedule_node(LockedNode &locked_node, CurrentTask ¤t_task, const bool is_priority) { BLI_assert(locked_node.node.is_function()); switch (locked_node.node_state.schedule_state) { @@ -641,10 +690,10 @@ class Executor { const FunctionNode &node = static_cast(locked_node.node); if (this->use_multi_threading()) { std::lock_guard lock{current_task.mutex}; - current_task.scheduled_nodes.append(&node); + current_task.scheduled_nodes.schedule(node, is_priority); } else { - current_task.scheduled_nodes.append(&node); + current_task.scheduled_nodes.schedule(node, is_priority); } current_task.has_scheduled_nodes.store(true, std::memory_order_relaxed); break; @@ -700,12 +749,11 @@ class Executor { void run_task(CurrentTask ¤t_task) { - while (!current_task.scheduled_nodes.is_empty()) { - const FunctionNode &node = *current_task.scheduled_nodes.pop_last(); + while (const FunctionNode *node = current_task.scheduled_nodes.pop_next_node()) { if (current_task.scheduled_nodes.is_empty()) { current_task.has_scheduled_nodes.store(false, std::memory_order_relaxed); } - this->run_node_task(node, current_task); + this->run_node_task(*node, current_task); } } @@ -814,7 +862,7 @@ class Executor { NodeScheduleState::RunningAndRescheduled; node_state.schedule_state = NodeScheduleState::NotScheduled; if (reschedule_requested && !node_state.node_has_finished) { - this->schedule_node(locked_node, current_task); + this->schedule_node(locked_node, current_task, false); } }); } @@ -1061,7 +1109,7 @@ class Executor { (locked_node.node.is_function() && static_cast(locked_node.node) .function() .allow_missing_requested_inputs())) { - this->schedule_node(locked_node, current_task); + this->schedule_node(locked_node, current_task, false); } } } @@ -1120,14 +1168,13 @@ class Executor { void move_scheduled_nodes_to_task_pool(CurrentTask ¤t_task) { BLI_assert(this->use_multi_threading()); - using FunctionNodeVector = Vector; - FunctionNodeVector *nodes = MEM_new(__func__); + ScheduledNodes *scheduled_nodes = MEM_new(__func__); { std::lock_guard lock{current_task.mutex}; if (current_task.scheduled_nodes.is_empty()) { return; } - *nodes = std::move(current_task.scheduled_nodes); + *scheduled_nodes = std::move(current_task.scheduled_nodes); current_task.has_scheduled_nodes.store(false, std::memory_order_relaxed); } /* All nodes are pushed as a single task in the pool. This avoids unnecessary threading @@ -1136,17 +1183,15 @@ class Executor { task_pool_.load(), [](TaskPool *pool, void *data) { Executor &executor = *static_cast(BLI_task_pool_user_data(pool)); - FunctionNodeVector &nodes = *static_cast(data); + ScheduledNodes &scheduled_nodes = *static_cast(data); CurrentTask new_current_task; - new_current_task.scheduled_nodes = std::move(nodes); + new_current_task.scheduled_nodes = std::move(scheduled_nodes); new_current_task.has_scheduled_nodes.store(true, std::memory_order_relaxed); executor.run_task(new_current_task); }, - nodes, + scheduled_nodes, true, - [](TaskPool * /*pool*/, void *data) { - MEM_delete(static_cast(data)); - }); + [](TaskPool * /*pool*/, void *data) { MEM_delete(static_cast(data)); }); } LinearAllocator<> &get_main_or_local_allocator() From d11f3267cd9370d793264f5eba6eacefd4da2f56 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Sun, 8 Jan 2023 13:57:09 -0800 Subject: [PATCH 0516/1522] Fix T103210: Don't Always Clear Glyphs With Zoom Do not clear all the font's glyph caches with single-step zoom operators if the area does not change font size when doing so. See D16785 for more details. Differential Revision: https://developer.blender.org/D16785 Reviewed by Campbell Barton --- source/blender/editors/interface/view2d_ops.cc | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/interface/view2d_ops.cc b/source/blender/editors/interface/view2d_ops.cc index 30c5e79a794..b76f5f1e49f 100644 --- a/source/blender/editors/interface/view2d_ops.cc +++ b/source/blender/editors/interface/view2d_ops.cc @@ -791,9 +791,14 @@ static void view_zoomstep_apply(bContext *C, wmOperator *op) * \{ */ /* Cleanup temp custom-data. */ -static void view_zoomstep_exit(wmOperator *op) +static void view_zoomstep_exit(bContext *C, wmOperator *op) { - UI_view2d_zoom_cache_reset(); + ScrArea *area = CTX_wm_area(C); + /* Some areas change font sizes when zooming, so clear glyph cache. */ + if (area && !ELEM(area->spacetype, SPACE_GRAPH, SPACE_ACTION)) { + UI_view2d_zoom_cache_reset(); + } + v2dViewZoomData *vzd = static_cast(op->customdata); vzd->v2d->flag &= ~V2D_IS_NAVIGATING; MEM_SAFE_FREE(op->customdata); @@ -816,7 +821,7 @@ static int view_zoomin_exec(bContext *C, wmOperator *op) /* apply movement, then we're done */ view_zoomstep_apply(C, op); - view_zoomstep_exit(op); + view_zoomstep_exit(C, op); return OPERATOR_FINISHED; } @@ -880,7 +885,7 @@ static int view_zoomout_exec(bContext *C, wmOperator *op) /* apply movement, then we're done */ view_zoomstep_apply(C, op); - view_zoomstep_exit(op); + view_zoomstep_exit(C, op); return OPERATOR_FINISHED; } @@ -1477,7 +1482,7 @@ static int view2d_ndof_invoke(bContext *C, wmOperator *op, const wmEvent *event) view_zoomstep_apply_ex( C, vzd, do_zoom_xy[0] ? zoom_factor : 0.0f, do_zoom_xy[1] ? zoom_factor : 0.0f); - view_zoomstep_exit(op); + view_zoomstep_exit(C, op); } return OPERATOR_FINISHED; From e7a554e551e45332292aefebfedf5edf08c7400b Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Sun, 8 Jan 2023 22:54:51 +0100 Subject: [PATCH 0517/1522] Fix T94698: Cycles: Volume-scattered light is always counted as diffuse At the first bounce, the diffuse/glossy/transmission weights are stored so that contributions along the path can be split into the d/g/t indirect passes. However, volume bounces always set the weight even at indirect bounces, so even paths that had their first bounce on a purely glossy object would suddenly start counting towards the diffuse indirect pass after a secondary volume bounce. --- intern/cycles/kernel/integrator/shade_volume.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h index 456bebe771a..624aeb5edee 100644 --- a/intern/cycles/kernel/integrator/shade_volume.h +++ b/intern/cycles/kernel/integrator/shade_volume.h @@ -979,8 +979,10 @@ ccl_device_forceinline bool integrate_volume_phase_scatter( INTEGRATOR_STATE_WRITE(state, path, throughput) = throughput_phase; if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { - INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_spectrum(); - INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_spectrum(); + if (INTEGRATOR_STATE(state, path, bounce) == 0) { + INTEGRATOR_STATE_WRITE(state, path, pass_diffuse_weight) = one_spectrum(); + INTEGRATOR_STATE_WRITE(state, path, pass_glossy_weight) = zero_spectrum(); + } } /* Update path state */ From 95696d09bc0725e49b5caf79db00927183fe569b Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Mon, 9 Jan 2023 03:05:57 +0100 Subject: [PATCH 0518/1522] Fix T88849: Motion blur in cycles leaves bright edge on trailing end of blur The code that computes and inverts the shutter CDF had some issues that caused the result to be asymmetric, this tweaks it to be more robust and produce symmetric outputs for symmetric inputs. --- intern/cycles/scene/camera.cpp | 2 +- intern/cycles/util/math_cdf.cpp | 7 ++++--- intern/cycles/util/math_cdf.h | 4 +++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/intern/cycles/scene/camera.cpp b/intern/cycles/scene/camera.cpp index 255dd320ec7..6eda0b7ab55 100644 --- a/intern/cycles/scene/camera.cpp +++ b/intern/cycles/scene/camera.cpp @@ -32,7 +32,7 @@ static float shutter_curve_eval(float x, array &shutter_curve) return 1.0f; } - x *= shutter_curve.size(); + x = saturatef(x) * shutter_curve.size() - 1; int index = (int)x; float frac = x - index; if (index < shutter_curve.size() - 1) { diff --git a/intern/cycles/util/math_cdf.cpp b/intern/cycles/util/math_cdf.cpp index 928cd6a1932..a009652d8c8 100644 --- a/intern/cycles/util/math_cdf.cpp +++ b/intern/cycles/util/math_cdf.cpp @@ -16,6 +16,7 @@ void util_cdf_invert(const int resolution, const bool make_symmetric, vector &inv_cdf) { + assert(cdf[0] == 0.0f && cdf[resolution] == 1.0f); const float inv_resolution = 1.0f / (float)resolution; const float range = to - from; inv_cdf.resize(resolution); @@ -39,8 +40,8 @@ void util_cdf_invert(const int resolution, } else { for (int i = 0; i < resolution; i++) { - float x = from + range * (float)i * inv_resolution; - int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin(); + float x = (i + 0.5f) * inv_resolution; + int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin() - 1; float t; if (index < cdf.size() - 1) { t = (x - cdf[index]) / (cdf[index + 1] - cdf[index]); @@ -49,7 +50,7 @@ void util_cdf_invert(const int resolution, t = 0.0f; index = resolution; } - inv_cdf[i] = (index + t) * inv_resolution; + inv_cdf[i] = from + range * (index + t) * inv_resolution; } } } diff --git a/intern/cycles/util/math_cdf.h b/intern/cycles/util/math_cdf.h index 82e6a69c04b..2555f194b2e 100644 --- a/intern/cycles/util/math_cdf.h +++ b/intern/cycles/util/math_cdf.h @@ -26,9 +26,11 @@ void util_cdf_evaluate( cdf[i + 1] = cdf[i] + fabsf(y); } /* Normalize the CDF. */ + float fac = (cdf[resolution] == 0.0f) ? 0.0f : 1.0f / cdf[resolution]; for (int i = 0; i <= resolution; i++) { - cdf[i] /= cdf[resolution]; + cdf[i] *= fac; } + cdf[resolution] = 1.0f; } /* Invert pre-calculated CDF function. */ From d8e01150d6356b171f03021dd6abcae39f3a7c81 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Sat, 7 Jan 2023 21:55:37 +0100 Subject: [PATCH 0519/1522] Fix T94752: Cycles renders stereoscopic panoramas incorrectly The bug is caused by rBb66b3f547c43e841a7d5da0ecb2c911628339f56. From what I can see, that fix was intended to enable manual lens shift for panorama cameras, but it appears that it also unintentionally applies interocular shift. This fix disables the multiview shift for panorama cameras, that way manual lens shift still works but we get the 2.x behavior for stereoscopic renders back. Differential Revision: https://developer.blender.org/D16950 --- source/blender/blenkernel/intern/camera.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c index 7c1193d80ab..2d5dc9010bf 100644 --- a/source/blender/blenkernel/intern/camera.c +++ b/source/blender/blenkernel/intern/camera.c @@ -1119,6 +1119,9 @@ float BKE_camera_multiview_shift_x(const RenderData *rd, if (rd->views_format == SCE_VIEWS_FORMAT_MULTIVIEW) { return data->shiftx; } + if (data->type == CAM_PANO) { + return data->shiftx; + } /* SCE_VIEWS_SETUP_BASIC */ return camera_stereo3d_shift_x(camera, viewname); } From 4546e35c92022997dacc322c8ab43df23bf98ca3 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Sun, 8 Jan 2023 21:38:54 +0100 Subject: [PATCH 0520/1522] Fix T95244: Cycles produces incorrect AO pass for shadow catchers Differential Revision: https://developer.blender.org/D16951 --- intern/cycles/kernel/integrator/shade_surface.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 19bec243757..3410195cd19 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -502,8 +502,15 @@ ccl_device_forceinline void integrate_surface_ao(KernelGlobals kg, rng_state, ccl_global float *ccl_restrict render_buffer) { + const uint32_t path_flag = INTEGRATOR_STATE(state, path, flag); + if (!(kernel_data.kernel_features & KERNEL_FEATURE_AO_ADDITIVE) && - !(INTEGRATOR_STATE(state, path, flag) & PATH_RAY_CAMERA)) { + !(path_flag & PATH_RAY_CAMERA)) { + return; + } + + /* Skip AO for paths that were split off for shadow catchers to avoid double-counting. */ + if (path_flag & PATH_RAY_SHADOW_CATCHER_PASS) { return; } From 0e0139b30467c90fd37efa7692123e359b74d4a5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 9 Jan 2023 17:34:53 +1100 Subject: [PATCH 0521/1522] Cleanup: quiet warning for unused pose_propagate_fcurve --- source/blender/editors/armature/pose_slide.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c index 9ae71a32774..e2610628f97 100644 --- a/source/blender/editors/armature/pose_slide.c +++ b/source/blender/editors/armature/pose_slide.c @@ -1794,7 +1794,9 @@ static void propagate_curve_values(ListBase /*tPChanFCurveLink*/ *pflinks, /** * Propagate just works along each F-Curve in turn. */ -static void pose_propagate_fcurve(FCurve *fcu, float start_frame, const float end_frame) +static void UNUSED_FUNCTION(pose_propagate_fcurve)(FCurve *fcu, + float start_frame, + const float end_frame) { /* Skip if no keyframes to edit. */ if ((fcu->bezt == NULL) || (fcu->totvert < 2)) { From 02226e90692831637d511f666ca93f2ef57d7ab7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 9 Jan 2023 17:39:35 +1100 Subject: [PATCH 0522/1522] Cleanup: spelling in comments --- source/blender/blenlib/BLI_devirtualize_parameters.hh | 2 +- source/blender/blenlib/BLI_math_rotation_types.hh | 4 ++-- source/blender/editors/screen/screen_ops.c | 4 ++-- source/blender/functions/FN_multi_function_builder.hh | 2 +- source/blender/gpu/intern/gpu_texture_private.hh | 4 ++-- source/blender/makesrna/RNA_access.h | 2 +- source/blender/makesrna/intern/rna_access_compare_override.c | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/source/blender/blenlib/BLI_devirtualize_parameters.hh b/source/blender/blenlib/BLI_devirtualize_parameters.hh index 2086c81b30d..5a10e944a9d 100644 --- a/source/blender/blenlib/BLI_devirtualize_parameters.hh +++ b/source/blender/blenlib/BLI_devirtualize_parameters.hh @@ -51,7 +51,7 @@ inline bool call_with_devirtualized_parameters(const std::tupleptr, "delta"); - /* In order to jump from e.g. 1.5 to 1 the delta needs to be incremented by 1 since the subframe - * is always zeroed. Otherwise it would jump to 0.*/ + /* In order to jump from e.g. 1.5 to 1 the delta needs to be incremented by 1 since the sub-frame + * is always zeroed. Otherwise it would jump to 0. */ if (delta < 0 && scene->r.subframe > 0) { delta += 1; } diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index bfe88e01f04..bb366ea47ea 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -139,7 +139,7 @@ execute_array(TypeSequence /*param_tags*/, Args &&__restrict... args) { if constexpr (std::is_same_v, IndexRange>) { - /* Having this explicit loop is necessary for msvc to be able to vectorize this. */ + /* Having this explicit loop is necessary for MSVC to be able to vectorize this. */ const int64_t start = mask.start(); const int64_t end = mask.one_after_last(); for (int64_t i = start; i < end; i++) { diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh index 554c1e03d77..344ec911adc 100644 --- a/source/blender/gpu/intern/gpu_texture_private.hh +++ b/source/blender/gpu/intern/gpu_texture_private.hh @@ -44,7 +44,7 @@ typedef enum eGPUTextureType { ENUM_OPERATORS(eGPUTextureType, GPU_TEXTURE_CUBE_ARRAY) /* Format types for samplers within the shader. - * This covers the sampler format type permutations within GLSL/MSL.*/ + * This covers the sampler format type permutations within GLSL/MSL. */ typedef enum eGPUSamplerFormat { GPU_SAMPLER_TYPE_FLOAT = 0, GPU_SAMPLER_TYPE_INT = 1, @@ -478,7 +478,7 @@ inline size_t to_bytesize(eGPUDataFormat data_format) inline size_t to_bytesize(eGPUTextureFormat tex_format, eGPUDataFormat data_format) { /* Special case for compacted types. - * Standard component len calcualtion does not apply, as the texture formats contain multiple + * Standard component len calculation does not apply, as the texture formats contain multiple * channels, but associated data format contains several compacted components. */ if ((tex_format == GPU_R11F_G11F_B10F && data_format == GPU_DATA_10_11_11_REV) || (tex_format == GPU_RGB10_A2 && data_format == GPU_DATA_2_10_10_10_REV)) { diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 656b0bc93b2..14d7c6691f6 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -813,7 +813,7 @@ typedef enum eRNAOverrideMatchResult { */ RNA_OVERRIDE_MATCH_RESULT_CREATED = 1 << 0, /** - * Some properties are illegaly different from their reference values and have been tagged for + * Some properties are illegally different from their reference values and have been tagged for * restoration. */ RNA_OVERRIDE_MATCH_RESULT_RESTORE_TAGGED = 1 << 1, diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c index 5e6579c7fa1..a0a084869d8 100644 --- a/source/blender/makesrna/intern/rna_access_compare_override.c +++ b/source/blender/makesrna/intern/rna_access_compare_override.c @@ -821,7 +821,7 @@ bool RNA_struct_override_matches(Main *bmain, /* This property should be restored to its reference value. This should not be done * here, since this code may be called from non-main thread (modifying data through RNA * is not thread safe). */ - BLI_assert(op == NULL); /* Forbidden orverride prop should not exist currently. */ + BLI_assert(op == NULL); /* Forbidden override prop should not exist currently. */ if (do_restore) { IDOverrideLibraryPropertyOperation opop_tmp = { From 59ce3b8f6b1cec9ed76929e56093ac2813fb6aed Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 9 Jan 2023 18:56:17 +1100 Subject: [PATCH 0523/1522] Cleanup: doxygen comment use Avoid '\note' outside of doxygen comments. --- source/blender/blenkernel/BKE_lib_override.h | 8 ++++---- source/blender/blenlib/BLI_math_matrix.hh | 4 ++-- source/blender/draw/intern/draw_cache_impl_pointcloud.cc | 2 +- source/blender/draw/intern/draw_curves.cc | 2 +- source/blender/draw/intern/draw_hair.cc | 2 +- .../draw/intern/shaders/common_pointcloud_lib.glsl | 2 +- .../draw/intern/shaders/draw_command_generate_comp.glsl | 2 +- source/blender/geometry/intern/trim_curves.cc | 2 +- source/blender/geometry/intern/uv_parametrizer.cc | 7 ++++--- .../gpu/shaders/common/gpu_shader_math_matrix_lib.glsl | 4 ++-- 10 files changed, 18 insertions(+), 17 deletions(-) diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index 4928ffda0ec..12139b7a6f0 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -401,7 +401,7 @@ bool BKE_lib_override_library_status_check_reference(struct Main *bmain, struct * Compare local and reference data-blocks and create new override operations as needed, * or reset to reference values if overriding is not allowed. * - * \param r_report_flags #eRNAOverrideMatchResult flags giving info about the result of this call. + * \param r_report_flags: #eRNAOverrideMatchResult flags giving info about the result of this call. * * \note Defining override operations is only mandatory before saving a `.blend` file on disk * (not for undo!). @@ -417,7 +417,7 @@ void BKE_lib_override_library_operations_create(struct Main *bmain, /** * Check all overrides from given \a bmain and create/update overriding operations as needed. * - * \param r_report_flags #eRNAOverrideMatchResult flags giving info about the result of this call. + * \param r_report_flags: #eRNAOverrideMatchResult flags giving info about the result of this call. */ void BKE_lib_override_library_main_operations_create(struct Main *bmain, bool force_auto, @@ -427,7 +427,7 @@ void BKE_lib_override_library_main_operations_create(struct Main *bmain, * Restore forbidden modified override properties to the values of their matching properties in the * linked reference ID. * - * \param r_report_flags #eRNAOverrideMatchResult flags giving info about the result of this call. + * \param r_report_flags: #eRNAOverrideMatchResult flags giving info about the result of this call. * * \note Typically used as part of BKE_lib_override_library_main_operations_create process, since * modifying RNA properties from non-main threads is not safe. @@ -439,7 +439,7 @@ void BKE_lib_override_library_operations_restore(struct Main *bmain, * Restore forbidden modified override properties to the values of their matching properties in the * linked reference ID, for all liboverride IDs tagged as needing such process in given `bmain`. * - * \param r_report_flags #eRNAOverrideMatchResult flags giving info about the result of this call. + * \param r_report_flags: #eRNAOverrideMatchResult flags giving info about the result of this call. * * \note Typically used as part of BKE_lib_override_library_main_operations_create process, since * modifying RNA properties from non-main threads is not safe. diff --git a/source/blender/blenlib/BLI_math_matrix.hh b/source/blender/blenlib/BLI_math_matrix.hh index 219e41314f5..79699e082f6 100644 --- a/source/blender/blenlib/BLI_math_matrix.hh +++ b/source/blender/blenlib/BLI_math_matrix.hh @@ -254,7 +254,7 @@ template /** * Extract the absolute 3d scale from a transform matrix. - * \tparam AllowNegativeScale if true, will compute determinant to know if matrix is negative. + * \tparam AllowNegativeScale: if true, will compute determinant to know if matrix is negative. * This is a costly operation so it is disabled by default. */ template @@ -262,7 +262,7 @@ template /** * Decompose a matrix into location, rotation, and scale components. - * \tparam AllowNegativeScale if true, will compute determinant to know if matrix is negative. + * \tparam AllowNegativeScale: if true, will compute determinant to know if matrix is negative. * Rotation and scale values will be flipped if it is negative. * This is a costly operation so it is disabled by default. */ diff --git a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc index ddbfe232361..4997aef6089 100644 --- a/source/blender/draw/intern/draw_cache_impl_pointcloud.cc +++ b/source/blender/draw/intern/draw_cache_impl_pointcloud.cc @@ -225,7 +225,7 @@ static const uint half_octahedron_tris[4][3] = { static void pointcloud_extract_indices(const PointCloud &pointcloud, PointCloudBatchCache &cache) { - /** \note: Avoid modulo by non-power-of-two in shader. */ + /** \note Avoid modulo by non-power-of-two in shader. */ uint32_t vertid_max = pointcloud.totpoint * 32; uint32_t index_len = pointcloud.totpoint * ARRAY_SIZE(half_octahedron_tris); diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc index 3660b460e25..62493df95f9 100644 --- a/source/blender/draw/intern/draw_curves.cc +++ b/source/blender/draw/intern/draw_curves.cc @@ -395,7 +395,7 @@ DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object, DRW_shgroup_uniform_float_copy(shgrp, "hairRadTip", hair_rad_tip); DRW_shgroup_uniform_bool_copy(shgrp, "hairCloseTip", hair_close_tip); if (gpu_material) { - /* \note: This needs to happen before the drawcall to allow correct attribute extraction. + /* NOTE: This needs to happen before the drawcall to allow correct attribute extraction. * (see T101896) */ DRW_shgroup_add_material_resources(shgrp, gpu_material); } diff --git a/source/blender/draw/intern/draw_hair.cc b/source/blender/draw/intern/draw_hair.cc index 9e1969d2f68..a7632abeafc 100644 --- a/source/blender/draw/intern/draw_hair.cc +++ b/source/blender/draw/intern/draw_hair.cc @@ -294,7 +294,7 @@ DRWShadingGroup *DRW_shgroup_hair_create_sub(Object *object, DRW_shgroup_uniform_float_copy(shgrp, "hairRadTip", hair_rad_tip); DRW_shgroup_uniform_bool_copy(shgrp, "hairCloseTip", hair_close_tip); if (gpu_material) { - /* \note: This needs to happen before the drawcall to allow correct attribute extraction. + /* NOTE: This needs to happen before the drawcall to allow correct attribute extraction. * (see T101896) */ DRW_shgroup_add_material_resources(shgrp, gpu_material); } diff --git a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl index 018e62b8c65..9d2a6f37882 100644 --- a/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl +++ b/source/blender/draw/intern/shaders/common_pointcloud_lib.glsl @@ -53,7 +53,7 @@ void pointcloud_get_pos_nor_radius(out vec3 outpos, out vec3 outnor, out float o mat3 facing_mat = pointcloud_get_facing_matrix(p); - /** \note: Avoid modulo by non-power-of-two in shader. See Index buffer setup. */ + /* NOTE: Avoid modulo by non-power-of-two in shader. See Index buffer setup. */ int vert_id = gl_VertexID % 32; vec3 pos_inst = vec3(0.0); diff --git a/source/blender/draw/intern/shaders/draw_command_generate_comp.glsl b/source/blender/draw/intern/shaders/draw_command_generate_comp.glsl index ddb4baf8f5b..75e5cda29d2 100644 --- a/source/blender/draw/intern/shaders/draw_command_generate_comp.glsl +++ b/source/blender/draw/intern/shaders/draw_command_generate_comp.glsl @@ -51,7 +51,7 @@ void main() if (visibility_word_per_draw > 0) { uint visibility_word = resource_index * visibility_word_per_draw; for (uint i = 0; i < visibility_word_per_draw; i++, visibility_word++) { - /* \note: This assumes proto.instance_len is 1. */ + /* NOTE: This assumes `proto.instance_len` is 1. */ /* TODO: Assert. */ visible_instance_len += bitCount(visibility_buf[visibility_word]); } diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc index 53a22b581b5..94bd212d70e 100644 --- a/source/blender/geometry/intern/trim_curves.cc +++ b/source/blender/geometry/intern/trim_curves.cc @@ -295,7 +295,7 @@ static bke::curves::bezier::Insertion knot_insert_bezier( * Sample source curve data in the interval defined by the points [start_point, end_point]. * Uses linear interpolation to compute the endpoints. * - * \tparam include_start_point If False, the 'start_point' point sample will not be copied + * \tparam include_start_point: If False, the 'start_point' point sample will not be copied * and not accounted for in the destination range. * \param src_data: Source to sample from. * \param dst_data: Destination to write samples to. diff --git a/source/blender/geometry/intern/uv_parametrizer.cc b/source/blender/geometry/intern/uv_parametrizer.cc index ed8c4b46e50..ff3458aa0e6 100644 --- a/source/blender/geometry/intern/uv_parametrizer.cc +++ b/source/blender/geometry/intern/uv_parametrizer.cc @@ -3897,9 +3897,10 @@ void GEO_uv_parametrizer_face_add(ParamHandle *phandle, continue; } - /* An existing triangle has already been inserted. As a heuristic, attempt to add the - * *previous* triangle. \note: Should probably call `GEO_uv_parametrizer_face_add` instead of - * `p_face_add_construct`. */ + /* An existing triangle has already been inserted. + * As a heuristic, attempt to add the *previous* triangle. + * NOTE: Should probably call `GEO_uv_parametrizer_face_add` + * instead of `p_face_add_construct`. */ int iprev = permute[(i + pm - 1) % pm]; p_face_add_construct(phandle, key, vkeys, co, uv, iprev, i0, i1, pin, select); diff --git a/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl index 0363a64d5c5..ded6904451f 100644 --- a/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl +++ b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl @@ -277,7 +277,7 @@ vec3 to_scale(mat4x4 mat, const bool allow_negative_scale); /** * Decompose a matrix into location, rotation, and scale components. - * \tparam allow_negative_scale if true, will compute determinant to know if matrix is negative. + * \tparam allow_negative_scale: if true, will compute determinant to know if matrix is negative. * Rotation and scale values will be flipped if it is negative. * This is a costly operation so it is disabled by default. */ @@ -907,7 +907,7 @@ mat3x3 from_rotation(EulerXYZ rotation) mat3x3 from_rotation(Quaternion rotation) { - /** \note: Should be double but support isn't native on most GPUs. */ + /* NOTE: Should be double but support isn't native on most GPUs. */ float q0 = M_SQRT2 * float(rotation.x); float q1 = M_SQRT2 * float(rotation.y); float q2 = M_SQRT2 * float(rotation.z); From 63c985e0f71baabad138d75e3cf26c72c84ce917 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 9 Jan 2023 18:56:54 +1100 Subject: [PATCH 0524/1522] Cleanup: format --- intern/cycles/device/metal/device_impl.mm | 3 ++- source/blender/imbuf/intern/util_gpu.c | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm index f9fa54b30ce..87614f656c3 100644 --- a/intern/cycles/device/metal/device_impl.mm +++ b/intern/cycles/device/metal/device_impl.mm @@ -377,7 +377,8 @@ bool MetalDevice::load_kernels(const uint _kernel_features) /* Only request generic kernels if they aren't cached in memory. */ if (make_source_and_check_if_compile_needed(PSO_GENERIC)) { - /* If needed, load them asynchronously in order to responsively message progress to the user. */ + /* If needed, load them asynchronously in order to responsively message progress to the user. + */ int this_device_id = this->device_id; auto compile_kernels_fn = ^() { compile_and_load(this_device_id, PSO_GENERIC); diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c index 9f4e2cf179c..eda89c7296d 100644 --- a/source/blender/imbuf/intern/util_gpu.c +++ b/source/blender/imbuf/intern/util_gpu.c @@ -251,12 +251,25 @@ GPUTexture *IMB_touch_gpu_texture(const char *name, GPUTexture *tex; if (layers > 0) { - tex = GPU_texture_create_2d_array_ex( - name, w, h, layers, 9999, tex_format, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW, NULL); + tex = GPU_texture_create_2d_array_ex(name, + w, + h, + layers, + 9999, + tex_format, + GPU_TEXTURE_USAGE_SHADER_READ | + GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW, + NULL); } else { - tex = GPU_texture_create_2d_ex( - name, w, h, 9999, tex_format, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW, NULL); + tex = GPU_texture_create_2d_ex(name, + w, + h, + 9999, + tex_format, + GPU_TEXTURE_USAGE_SHADER_READ | + GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW, + NULL); } GPU_texture_swizzle_set(tex, imb_gpu_get_swizzle(ibuf)); From 4887401789ea7716365bbd65207161f1dd3dd6cb Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 9 Jan 2023 09:20:17 +0100 Subject: [PATCH 0525/1522] Usual UI messages and i18n fixes and tweaks. --- intern/cycles/blender/addon/properties.py | 12 ++++++++---- release/scripts/modules/bl_i18n_utils/settings.py | 1 + .../modules/bl_i18n_utils/utils_spell_check.py | 1 + release/scripts/startup/bl_ui/space_userpref.py | 4 ++-- release/scripts/startup/bl_ui/space_view3d.py | 2 +- source/blender/makesrna/intern/rna_userdef.c | 10 +++++----- 6 files changed, 18 insertions(+), 12 deletions(-) diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index a27a75e48fa..9ec663eb258 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -83,7 +83,7 @@ enum_use_layer_samples = ( enum_sampling_pattern = ( ('SOBOL_BURLEY', "Sobol-Burley", "Use on-the-fly computed Owen-scrambled Sobol for random sampling", 0), - ('TABULATED_SOBOL', "Tabulated Sobol", "Use precomputed tables of Owen-scrambled Sobol for random sampling", 1), + ('TABULATED_SOBOL', "Tabulated Sobol", "Use pre-computed tables of Owen-scrambled Sobol for random sampling", 1), ) enum_emission_sampling = ( @@ -905,7 +905,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): use_fast_gi: BoolProperty( name="Fast GI Approximation", - description="Approximate diffuse indirect light with background tinted ambient occlusion. This provides fast alternative to full global illumination, for interactive viewport rendering or final renders with reduced quality", + description="Approximate diffuse indirect light with background tinted ambient occlusion. " + "This provides fast alternative to full global illumination, for interactive viewport rendering or final renders with reduced quality", default=False, ) @@ -1539,13 +1540,16 @@ class CyclesPreferences(bpy.types.AddonPreferences): use_metalrt: BoolProperty( name="MetalRT (Experimental)", - description="MetalRT for ray tracing uses less memory for scenes which use curves extensively, and can give better performance in specific cases. However this support is experimental and some scenes may render incorrectly", + description="MetalRT for ray tracing uses less memory for scenes which use curves extensively, and can give better " + "performance in specific cases. However this support is experimental and some scenes may render incorrectly", default=False, ) kernel_optimization_level: EnumProperty( name="Kernel Optimization", - description="Kernels can be optimized based on scene content. Optimized kernels are requested at the start of a render. If optimized kernels are not available, rendering will proceed using generic kernels until the optimized set is available in the cache. This can result in additional CPU usage for a brief time (tens of seconds).", + description="Kernels can be optimized based on scene content. Optimized kernels are requested at the start of a render. " + "If optimized kernels are not available, rendering will proceed using generic kernels until the optimized set " + "is available in the cache. This can result in additional CPU usage for a brief time (tens of seconds)", default='FULL', items=( ('OFF', "Off", "Disable kernel optimization. Slowest rendering, no extra background CPU usage"), diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py index 2f3efc47180..ed8bdb2e014 100644 --- a/release/scripts/modules/bl_i18n_utils/settings.py +++ b/release/scripts/modules/bl_i18n_utils/settings.py @@ -412,6 +412,7 @@ WARN_MSGID_NOT_CAPITALIZED_ALLOWED = { "selected", "selected and lock unselected", "selected and unlock unselected", + "screen", "the lazy dog", "this legacy pose library to pose assets", "to the top level of the tree", diff --git a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py index e4b755033aa..82ac9ea4970 100644 --- a/release/scripts/modules/bl_i18n_utils/utils_spell_check.py +++ b/release/scripts/modules/bl_i18n_utils/utils_spell_check.py @@ -542,6 +542,7 @@ class SpellChecker: "voronoi", "voxel", "voxels", "vsync", + "vulkan", "wireframe", "zmask", "ztransp", diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index e58302fde06..945abe3f5a4 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -605,7 +605,7 @@ class USERPREF_PT_system_cycles_devices(SystemPanel, CenterAlignMixIn, Panel): class USERPREF_PT_system_gpu_backend(SystemPanel, CenterAlignMixIn, Panel): - bl_label = "GPU Backend" + bl_label = "GPU Back end" @classmethod def poll(cls, _context): @@ -622,7 +622,7 @@ class USERPREF_PT_system_gpu_backend(SystemPanel, CenterAlignMixIn, Panel): col.prop(system, "gpu_backend") if system.gpu_backend != gpu.platform.backend_type_get(): - layout.label(text="Requires a restart of Blender to take effect.", icon='INFO') + layout.label(text="Requires a restart of Blender to take effect", icon='INFO') class USERPREF_PT_system_os_settings(SystemPanel, CenterAlignMixIn, Panel): diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 83066cb70bf..60494aa4d9e 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -6224,7 +6224,7 @@ class VIEW3D_PT_shading_compositor(Panel): row.active = not is_macos row.prop(shading, "use_compositor", expand=True) if is_macos and shading.use_compositor != "DISABLED": - self.layout.label(text="Compositor not supported on MacOS.", icon='ERROR') + self.layout.label(text="Compositor not supported on MacOS", icon='ERROR') class VIEW3D_PT_gizmo_display(Panel): diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index d10b82c4a16..ba9d750f1bb 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -141,9 +141,9 @@ static const EnumPropertyItem rna_enum_userdef_viewport_aa_items[] = { }; static const EnumPropertyItem rna_enum_preference_gpu_backend_items[] = { - {GPU_BACKEND_OPENGL, "OPENGL", 0, "OpenGL", "Use OpenGL backend"}, - {GPU_BACKEND_METAL, "METAL", 0, "Metal", "Use Metal backend"}, - {GPU_BACKEND_VULKAN, "VULKAN", 0, "Vulkan", "Use Vulkan backend"}, + {GPU_BACKEND_OPENGL, "OPENGL", 0, "OpenGL", "Use OpenGL back end"}, + {GPU_BACKEND_METAL, "METAL", 0, "Metal", "Use Metal back end"}, + {GPU_BACKEND_VULKAN, "VULKAN", 0, "Vulkan", "Use Vulkan back end"}, {0, NULL, 0, NULL, NULL}, }; @@ -5647,8 +5647,8 @@ static void rna_def_userdef_system(BlenderRNA *brna) RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_preference_gpu_backend_itemf"); RNA_def_property_ui_text( prop, - "GPU Backend", - "GPU backend to use. (Requires restarting Blender for changes to take effect)"); + "GPU Back end", + "GPU back end to use (requires restarting Blender for changes to take effect)"); /* Audio */ From f3df7b4fbde52291984ea6cf6e110ffc6395ac30 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 9 Jan 2023 09:44:54 +0100 Subject: [PATCH 0526/1522] Fix T103075: Crash when using Limit textures. Crash only occured when textures was stored in a gray scale GPU texture and was scaled down to fit inside the given limitation. In this case the original number of pixels were packed into the GPU buffer, not taken into account the scaled down image. This resulted in a buffer overflow. --- source/blender/imbuf/intern/util_gpu.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/imbuf/intern/util_gpu.c b/source/blender/imbuf/intern/util_gpu.c index eda89c7296d..c71a867669a 100644 --- a/source/blender/imbuf/intern/util_gpu.c +++ b/source/blender/imbuf/intern/util_gpu.c @@ -223,13 +223,14 @@ static void *imb_gpu_get_data(const ImBuf *ibuf, return NULL; } + int buffer_size = do_rescale ? rescale_size[0] * rescale_size[1] : ibuf->x * ibuf->y; if (is_float_rect) { - for (uint64_t i = 0; i < ibuf->x * ibuf->y; i++) { + for (uint64_t i = 0; i < buffer_size; i++) { ((float *)data_rect)[i] = ((float *)src_rect)[i * 4]; } } else { - for (uint64_t i = 0; i < ibuf->x * ibuf->y; i++) { + for (uint64_t i = 0; i < buffer_size; i++) { ((uchar *)data_rect)[i] = ((uchar *)src_rect)[i * 4]; } } From b5390a4aeeb71671d282e244b422a7e065abfff5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 9 Jan 2023 22:03:14 +1100 Subject: [PATCH 0527/1522] Fix assert on blend file load when seek fails Only assert seek worked as expected when it doesn't return an error. --- source/blender/blenloader/intern/readfile.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index ed88495797d..91a72fb50c4 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -724,13 +724,15 @@ static BHeadN *get_bhead(FileData *fd) new_bhead->has_data = false; new_bhead->is_memchunk_identical = false; new_bhead->bhead = bhead; - off64_t seek_new = fd->file->seek(fd->file, bhead.len, SEEK_CUR); - if (seek_new == -1) { + const off64_t seek_new = fd->file->seek(fd->file, bhead.len, SEEK_CUR); + if (UNLIKELY(seek_new == -1)) { fd->is_eof = true; MEM_freeN(new_bhead); new_bhead = nullptr; } - BLI_assert(fd->file->offset == seek_new); + else { + BLI_assert(fd->file->offset == seek_new); + } } else { fd->is_eof = true; From b3f664f8fbfe6cc4839447649bed1e156710a692 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Mon, 9 Jan 2023 12:40:33 +0100 Subject: [PATCH 0528/1522] GPencil: Fix unreported Vertex Color missing in Outline Draw When drawing using the option `Outline` the result stroke was not using the Vertex Color option and always was converted using material. Now the vertex color option is used. --- source/blender/editors/gpencil/gpencil_paint.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 9b746d9fd6b..547bda6a1e3 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -962,11 +962,15 @@ static bGPDstroke *gpencil_stroke_to_outline(tGPsdata *p, bGPDstroke *gps) /* Set pressure constant. */ gps_perimeter->thickness = max_ii((int)outline_thickness, 1); + /* Apply Fill Vertex Color data. */ + ED_gpencil_fill_vertex_color_set(p->scene->toolsettings, brush, gps); bGPDspoint *pt; for (int i = 0; i < gps_perimeter->totpoints; i++) { pt = &gps_perimeter->points[i]; pt->pressure = 1.0f; + /* Apply Point Vertex Color data. */ + ED_gpencil_point_vertex_color_set(p->scene->toolsettings, brush, pt, NULL); } /* Remove original stroke. */ From 589cbbf0e382a77b19f90886370682a0feab6fa6 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 9 Jan 2023 13:15:20 +0100 Subject: [PATCH 0529/1522] Tests: test availability of new bundled Python libraries Differential Revision: https://developer.blender.org/D16733 --- tests/python/CMakeLists.txt | 2 +- tests/python/bl_bundled_modules.py | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index e4916bb3ff5..cc16a5641e1 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -80,7 +80,7 @@ add_blender_test( add_blender_test( script_bundled_modules - --python ${CMAKE_CURRENT_LIST_DIR}/bl_bundled_modules.py + --python ${CMAKE_CURRENT_LIST_DIR}/bl_bundled_modules.py -- --inside-blender ) # test running operators doesn't segfault under various conditions diff --git a/tests/python/bl_bundled_modules.py b/tests/python/bl_bundled_modules.py index 7728a2deb47..6cb87b5aaed 100644 --- a/tests/python/bl_bundled_modules.py +++ b/tests/python/bl_bundled_modules.py @@ -1,7 +1,16 @@ # SPDX-License-Identifier: GPL-2.0-or-later -# Test that modules we ship with our Python installation are available +# Test that modules we ship with our Python installation are available, +# both for Blender itself and the bundled Python executable. +import os +import subprocess +import sys + +app = "Blender" if sys.argv[-1] == "--inside-blender" else "Python" +sys.stderr.write(f"Testing bundled modules in {app} executable.\n") + +# General purpose modules. import bz2 import certifi import ctypes @@ -14,3 +23,16 @@ import ssl import urllib3 import zlib import zstandard + +# VFX platform modules. +from pxr import Usd +import MaterialX +import OpenImageIO +import PyOpenColorIO +import pyopenvdb + +# Test modules in bundled Python standalone executable. +if app == "Blender": + script_filepath = os.path.abspath(__file__) + proc = subprocess.Popen([sys.executable, script_filepath]) + sys.exit(proc.wait()) From 29a41ed6c2f86248516c3d983f807000685305ef Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 9 Jan 2023 14:31:36 +0100 Subject: [PATCH 0530/1522] Fix T103747: crash when using rotation output of Curve to Points node --- source/blender/nodes/NOD_geometry_exec.hh | 4 ++-- .../nodes/geometry/nodes/node_geo_curve_to_points.cc | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh index 60f58f4c215..ed0ba4105fd 100644 --- a/source/blender/nodes/NOD_geometry_exec.hh +++ b/source/blender/nodes/NOD_geometry_exec.hh @@ -283,9 +283,9 @@ class GeoNodeExecParams { * attribute is not needed. */ AutoAnonymousAttributeID get_output_anonymous_attribute_id_if_needed( - const StringRef output_identifier) + const StringRef output_identifier, const bool force_create = false) { - if (!this->anonymous_attribute_output_is_required(output_identifier)) { + if (!this->anonymous_attribute_output_is_required(output_identifier) && !force_create) { return {}; } const GeoNodesLFUserData &user_data = *this->user_data(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc index 6e443f1efb7..ab7a9bef8db 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc @@ -111,12 +111,13 @@ static void node_geo_exec(GeoNodeExecParams params) GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set); - AutoAnonymousAttributeID tangent_anonymous_id = - params.get_output_anonymous_attribute_id_if_needed("Tangent"); - AutoAnonymousAttributeID normal_anonymous_id = - params.get_output_anonymous_attribute_id_if_needed("Normal"); AutoAnonymousAttributeID rotation_anonymous_id = params.get_output_anonymous_attribute_id_if_needed("Rotation"); + const bool need_tangent_and_normal = bool(rotation_anonymous_id); + AutoAnonymousAttributeID tangent_anonymous_id = + params.get_output_anonymous_attribute_id_if_needed("Tangent", need_tangent_and_normal); + AutoAnonymousAttributeID normal_anonymous_id = + params.get_output_anonymous_attribute_id_if_needed("Normal", need_tangent_and_normal); geometry::ResampleCurvesOutputAttributeIDs resample_attributes; resample_attributes.tangent_id = tangent_anonymous_id.get(); From ca45c2dc59ab663835d2c85e6b22a0f77ab46568 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 9 Jan 2023 14:52:06 +0100 Subject: [PATCH 0531/1522] Fix T103756: wrong anonymous attribute tooltip --- .../blender/blenkernel/BKE_anonymous_attribute_id.hh | 2 ++ source/blender/blenkernel/BKE_geometry_fields.hh | 2 +- .../blenkernel/intern/anonymous_attribute_id.cc | 5 +++++ source/blender/nodes/NOD_geometry_exec.hh | 10 ++++++++-- source/blender/nodes/intern/node_geometry_exec.cc | 9 ++++++++- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/BKE_anonymous_attribute_id.hh b/source/blender/blenkernel/BKE_anonymous_attribute_id.hh index b738ff50604..7e4ca4b7afd 100644 --- a/source/blender/blenkernel/BKE_anonymous_attribute_id.hh +++ b/source/blender/blenkernel/BKE_anonymous_attribute_id.hh @@ -47,6 +47,8 @@ class AnonymousAttributeID { return name_; } + virtual std::string user_name() const; + void user_add() const { users_.fetch_add(1); diff --git a/source/blender/blenkernel/BKE_geometry_fields.hh b/source/blender/blenkernel/BKE_geometry_fields.hh index 967bb912cc6..085bade618c 100644 --- a/source/blender/blenkernel/BKE_geometry_fields.hh +++ b/source/blender/blenkernel/BKE_geometry_fields.hh @@ -268,7 +268,7 @@ class AnonymousAttributeFieldInput : public GeometryFieldInput { AnonymousAttributeFieldInput(AutoAnonymousAttributeID anonymous_id, const CPPType &type, std::string producer_name) - : GeometryFieldInput(type, anonymous_id->name()), + : GeometryFieldInput(type, anonymous_id->user_name()), anonymous_id_(std::move(anonymous_id)), producer_name_(producer_name) { diff --git a/source/blender/blenkernel/intern/anonymous_attribute_id.cc b/source/blender/blenkernel/intern/anonymous_attribute_id.cc index e15ea6b643c..38f9c3df772 100644 --- a/source/blender/blenkernel/intern/anonymous_attribute_id.cc +++ b/source/blender/blenkernel/intern/anonymous_attribute_id.cc @@ -4,6 +4,11 @@ namespace blender::bke { +std::string AnonymousAttributeID::user_name() const +{ + return this->name(); +} + bool AnonymousAttributePropagationInfo::propagate(const AnonymousAttributeID &anonymous_id) const { if (this->propagate_all) { diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh index ed0ba4105fd..088e076be35 100644 --- a/source/blender/nodes/NOD_geometry_exec.hh +++ b/source/blender/nodes/NOD_geometry_exec.hh @@ -49,12 +49,16 @@ using geo_eval_log::NodeWarningType; */ class NodeAnonymousAttributeID : public AnonymousAttributeID { std::string long_name_; + std::string socket_name_; public: NodeAnonymousAttributeID(const Object &object, const ComputeContext &compute_context, const bNode &bnode, - const StringRef identifier); + const StringRef identifier, + const StringRef name); + + std::string user_name() const override; }; class GeoNodeExecParams { @@ -288,13 +292,15 @@ class GeoNodeExecParams { if (!this->anonymous_attribute_output_is_required(output_identifier) && !force_create) { return {}; } + const bNodeSocket &output_socket = node_.output_by_identifier(output_identifier); const GeoNodesLFUserData &user_data = *this->user_data(); const ComputeContext &compute_context = *user_data.compute_context; return MEM_new(__func__, *user_data.modifier_data->self_object, compute_context, node_, - output_identifier); + output_identifier, + output_socket.name); } /** diff --git a/source/blender/nodes/intern/node_geometry_exec.cc b/source/blender/nodes/intern/node_geometry_exec.cc index c338ecacbc9..1824ff965ea 100644 --- a/source/blender/nodes/intern/node_geometry_exec.cc +++ b/source/blender/nodes/intern/node_geometry_exec.cc @@ -18,7 +18,9 @@ namespace blender::nodes { NodeAnonymousAttributeID::NodeAnonymousAttributeID(const Object &object, const ComputeContext &compute_context, const bNode &bnode, - const StringRef identifier) + const StringRef identifier, + const StringRef name) + : socket_name_(name) { const ComputeContextHash &hash = compute_context.hash(); { @@ -36,6 +38,11 @@ NodeAnonymousAttributeID::NodeAnonymousAttributeID(const Object &object, } } +std::string NodeAnonymousAttributeID::user_name() const +{ + return socket_name_; +} + void GeoNodeExecParams::error_message_add(const NodeWarningType type, const StringRef message) const { From f5179830a7acbea85e10dfaabbf0deffef799cd2 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 9 Jan 2023 08:59:34 -0500 Subject: [PATCH 0532/1522] Cleanup: BLI Vector comment formatting, grammar --- source/blender/blenlib/BLI_math_vector.hh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index 9bba55663bd..1e8f5a3f42a 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -263,7 +263,7 @@ template * Dot product between two vectors. * Equivalent to component wise multiplication followed by summation of the result. * Equivalent to the cosine of the angle between the two vectors if the vectors are normalized. - * /note prefer using `length_manhattan(a)` than `dot(a, vec(1))` to get the sum of all components. + * \note prefer using `length_manhattan(a)` than `dot(a, vec(1))` to get the sum of all components. */ template [[nodiscard]] inline T dot(const VecBase &a, const VecBase &b) @@ -297,7 +297,7 @@ template [[nodiscard]] inline T length(const VecBase [[nodiscard]] inline bool is_unit_scale(const VecBase &v) { /* Checks are flipped so NAN doesn't assert because we're making sure the value was @@ -410,9 +410,9 @@ template } /** - * @param poly List of points around a polygon. They don't have to be co-planar. - * @return Best fit plane normal for the given polygon loop or, zero vector if point - * loop is too short. Not normalized. + * \param poly: Array of points around a polygon. They don't have to be co-planar. + * \return Best fit plane normal for the given polygon loop or zero vector if point + * array is too short. Not normalized. */ template [[nodiscard]] inline VecBase cross_poly(Span> poly) { @@ -439,8 +439,8 @@ template [[nodiscard]] inline VecBase cross_poly(Span [[nodiscard]] inline VecBase interpolate(const VecBase &a, @@ -451,7 +451,7 @@ template } /** - * @return Point halfway between \a a and \a b. + * \return Point halfway between \a a and \a b. */ template [[nodiscard]] inline VecBase midpoint(const VecBase &a, @@ -472,7 +472,7 @@ template } /** - * @return Index of the component with the greatest magnitude. + * \return Index of the component with the greatest magnitude. */ template [[nodiscard]] inline int dominant_axis(const VecBase &a) { From 385bd0c4e97eb3961521fbd01c3358dbc468e477 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 9 Jan 2023 15:02:26 +0100 Subject: [PATCH 0533/1522] Fix T103685: Animation on objects that are disabled is ignored Happens, for example, when the object has animation, and disabled for render, and animation render is performed. The regression has been uncovered by f12f7800c296 which made it so the dependency graph relies on runtime visibility tracking and updates (without updating relations). The optimization from a while ago in the ff60dd8b18ed got in a way of the visibilit updates because it removed relation between two no-op nodes which belong to different IDs, which make the visibility tracking impossible. This change makes it so only relations which belong to the same component are removed. This matches the expectations of the visibility tracking (which, actually, also needed to happen at the moment of the initial optimization commit). Technically, this change could introduce some performance regression, but with the current design design of the graph it is not really avoidable. The idea to gain the best performance is to separate relations which actually define the execution flow, and which are only needed to define things like visibility dependencies. --- .../intern/builder/deg_builder_remove_noop.cc | 48 +++++++++++++++---- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_remove_noop.cc b/source/blender/depsgraph/intern/builder/deg_builder_remove_noop.cc index 992620a6f03..89e590111a3 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_remove_noop.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_remove_noop.cc @@ -30,9 +30,28 @@ static inline bool is_unused_noop(OperationNode *op_node) return op_node->is_noop() && op_node->outlinks.is_empty(); } +static inline bool is_removable_relation(const Relation *relation) +{ + if (relation->from->type != NodeType::OPERATION || relation->to->type != NodeType::OPERATION) { + return true; + } + + const OperationNode *operation_from = static_cast(relation->from); + const OperationNode *operation_to = static_cast(relation->to); + + /* If the relation connects two different IDs there is a high risk that the removal of the + * relation will make it so visibility flushing is not possible at runtime. This happens with + * relations like the DoF on camera of custom shape on bines: such relation do not lead to an + * actual depsgraph evaluation operation as they are handled on render engine level. + * + * The indirectly linked objects could have some of their components invisible as well, so + * also keep relations which connect different components of the same object so that visibility + * tracking happens correct in those cases as well. */ + return operation_from->owner == operation_to->owner; +} + void deg_graph_remove_unused_noops(Depsgraph *graph) { - int num_removed_relations = 0; deque queue; for (OperationNode *node : graph->operations) { @@ -41,18 +60,19 @@ void deg_graph_remove_unused_noops(Depsgraph *graph) } } + Vector relations_to_remove; + while (!queue.empty()) { OperationNode *to_remove = queue.front(); queue.pop_front(); - while (!to_remove->inlinks.is_empty()) { - Relation *rel_in = to_remove->inlinks[0]; - Node *dependency = rel_in->from; + for (Relation *rel_in : to_remove->inlinks) { + if (!is_removable_relation(rel_in)) { + continue; + } - /* Remove the relation. */ - rel_in->unlink(); - delete rel_in; - num_removed_relations++; + Node *dependency = rel_in->from; + relations_to_remove.append(rel_in); /* Queue parent no-op node that has now become unused. */ OperationNode *operation = dependency->get_exit_operation(); @@ -64,8 +84,16 @@ void deg_graph_remove_unused_noops(Depsgraph *graph) /* TODO(Sybren): Remove the node itself. */ } - DEG_DEBUG_PRINTF( - (::Depsgraph *)graph, BUILD, "Removed %d relations to no-op nodes\n", num_removed_relations); + /* Remove the relations. */ + for (Relation *relation : relations_to_remove) { + relation->unlink(); + delete relation; + } + + DEG_DEBUG_PRINTF((::Depsgraph *)graph, + BUILD, + "Removed %d relations to no-op nodes\n", + int(relations_to_remove.size())); } } // namespace blender::deg From 8d2f4ddb2fc0af60bb46ccd6130416a0b10a29e4 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 9 Jan 2023 14:28:25 +0100 Subject: [PATCH 0534/1522] Fix T103423: boolean crash on macOS Apple silicon Thanks to Howard Trickey for finding the cause. --- build_files/build_environment/cmake/gmp.cmake | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build_files/build_environment/cmake/gmp.cmake b/build_files/build_environment/cmake/gmp.cmake index 820da4bdf7d..ffab5ed00e5 100644 --- a/build_files/build_environment/cmake/gmp.cmake +++ b/build_files/build_environment/cmake/gmp.cmake @@ -22,6 +22,14 @@ elseif(UNIX AND NOT APPLE) ) endif() +# Boolean crashes with Arm assembly, see T103423. +if(BLENDER_PLATFORM_ARM) + set(GMP_OPTIONS + ${GMP_OPTIONS} + --disable-assembly + ) +endif() + ExternalProject_Add(external_gmp URL file://${PACKAGE_DIR}/${GMP_FILE} DOWNLOAD_DIR ${DOWNLOAD_DIR} From 08b2d0402198366699a3a61baad8715b642f0610 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 9 Jan 2023 11:12:03 -0500 Subject: [PATCH 0535/1522] Cleanup: Use std::swap instead of macro in C++ code --- .../blender/blenkernel/intern/DerivedMesh.cc | 2 +- source/blender/blenkernel/intern/attribute.cc | 2 +- source/blender/blenkernel/intern/brush.cc | 2 +- source/blender/blenkernel/intern/curve.cc | 20 +++++++------- source/blender/blenkernel/intern/displist.cc | 2 +- source/blender/blenkernel/intern/key.cc | 2 +- .../blenkernel/intern/mball_tessellate.cc | 2 +- source/blender/blenkernel/intern/mesh.cc | 2 +- .../blenkernel/intern/mesh_evaluate.cc | 10 +++---- .../blenkernel/intern/mesh_legacy_convert.cc | 10 +++---- source/blender/blenkernel/intern/paint.cc | 4 +-- source/blender/blenkernel/intern/scene.cc | 8 +++--- source/blender/blenlib/intern/listbase.cc | 6 ++--- .../blenlib/tests/BLI_math_rotation_test.cc | 2 +- source/blender/bmesh/intern/bmesh_mesh.cc | 6 ++--- .../bmesh/intern/bmesh_mesh_normals.cc | 2 +- .../operations/COM_GlareFogGlowOperation.cc | 8 +++--- .../operations/COM_VectorBlurOperation.cc | 2 +- .../eevee_next/eevee_depth_of_field.cc | 2 +- .../draw/engines/eevee_next/eevee_film.cc | 2 +- .../draw/engines/eevee_next/eevee_velocity.cc | 8 +++--- .../engines/overlay/overlay_motion_path.cc | 2 +- .../extract_mesh_ibo_lines_adjacency.cc | 2 +- source/blender/editors/interface/interface.cc | 26 +++++++++---------- .../editors/interface/interface_align.cc | 2 +- .../editors/interface/interface_anim.cc | 4 +-- .../editors/interface/interface_handlers.cc | 4 +-- .../editors/interface/interface_widgets.cc | 18 ++++++------- .../blender/editors/mesh/editmesh_select.cc | 2 +- source/blender/editors/mesh/meshtools.cc | 4 +-- .../blender/editors/object/object_vgroup.cc | 14 +++++----- .../blender/editors/space_image/image_undo.cc | 20 +++++++------- .../blender/editors/space_node/node_draw.cc | 4 +-- .../blender/editors/space_node/node_gizmo.cc | 4 +-- .../editors/space_node/node_relationships.cc | 2 +- .../editors/space_view3d/view3d_draw.cc | 4 +-- .../geometry/intern/mesh_merge_by_distance.cc | 2 +- .../geometry/intern/uv_parametrizer.cc | 10 +++---- .../intern/lineart/lineart_cpu.cc | 4 +-- source/blender/modifiers/intern/MOD_screw.cc | 6 ++--- source/blender/render/intern/multires_bake.cc | 14 +++++----- source/blender/render/intern/pipeline.cc | 2 +- .../windowmanager/intern/wm_event_system.cc | 2 +- 43 files changed, 128 insertions(+), 128 deletions(-) diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 8ca569a7726..564cb8e38ef 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -286,7 +286,7 @@ void DM_ensure_looptri_data(DerivedMesh *dm) BLI_assert(dm->looptris.array_wip == nullptr); - SWAP(MLoopTri *, dm->looptris.array, dm->looptris.array_wip); + std::swap(dm->looptris.array, dm->looptris.array_wip); if ((looptris_num > dm->looptris.num_alloc) || (looptris_num < dm->looptris.num_alloc * 2) || (totpoly == 0)) { diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc index 58990c5c024..4e1a925bf5e 100644 --- a/source/blender/blenkernel/intern/attribute.cc +++ b/source/blender/blenkernel/intern/attribute.cc @@ -612,7 +612,7 @@ static void get_domains_types(eAttrDomain domains[ATTR_DOMAIN_NUM]) } /* Swap corner and face. */ - SWAP(eAttrDomain, domains[ATTR_DOMAIN_FACE], domains[ATTR_DOMAIN_CORNER]); + std::swap(domains[ATTR_DOMAIN_FACE], domains[ATTR_DOMAIN_CORNER]); } int BKE_id_attribute_to_index(const ID *id, diff --git a/source/blender/blenkernel/intern/brush.cc b/source/blender/blenkernel/intern/brush.cc index 6f1435e90b8..28baa871e12 100644 --- a/source/blender/blenkernel/intern/brush.cc +++ b/source/blender/blenkernel/intern/brush.cc @@ -407,7 +407,7 @@ static void brush_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old) /* NOTE: We do not swap IDProperties, as dealing with potential ID pointers in those would be * fairly delicate. */ - SWAP(IDProperty *, id_new->properties, id_old->properties); + std::swap(id_new->properties, id_old->properties); } IDTypeInfo IDType_ID_BR = { diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index b510b48870b..f2e6d037fe0 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -704,7 +704,7 @@ Nurb *BKE_nurb_copy(Nurb *src, int pntsu, int pntsv) *newnu = blender::dna::shallow_copy(*src); if (pntsu == 1) { - SWAP(int, pntsu, pntsv); + std::swap(pntsu, pntsv); } newnu->pntsu = pntsu; newnu->pntsv = pntsv; @@ -3048,7 +3048,7 @@ void BKE_curve_bevelList_make(Object *ob, const ListBase *nurbs, const bool for_ bevp2 = bevp1 + (bl->nr - 1); nr = bl->nr / 2; while (nr--) { - SWAP(BevPoint, *bevp1, *bevp2); + std::swap( *bevp1, *bevp2); bevp1++; bevp2--; } @@ -4437,7 +4437,7 @@ void BKE_nurb_direction_switch(Nurb *nu) a /= 2; while (a > 0) { if (bezt1 != bezt2) { - SWAP(BezTriple, *bezt1, *bezt2); + std::swap(*bezt1, *bezt2); } swap_v3_v3(bezt1->vec[0], bezt1->vec[2]); @@ -4446,12 +4446,12 @@ void BKE_nurb_direction_switch(Nurb *nu) swap_v3_v3(bezt2->vec[0], bezt2->vec[2]); } - SWAP(uint8_t, bezt1->h1, bezt1->h2); - SWAP(uint8_t, bezt1->f1, bezt1->f3); + std::swap( bezt1->h1, bezt1->h2); + std::swap( bezt1->f1, bezt1->f3); if (bezt1 != bezt2) { - SWAP(uint8_t, bezt2->h1, bezt2->h2); - SWAP(uint8_t, bezt2->f1, bezt2->f3); + std::swap( bezt2->h1, bezt2->h2); + std::swap( bezt2->f1, bezt2->f3); bezt1->tilt = -bezt1->tilt; bezt2->tilt = -bezt2->tilt; } @@ -4469,7 +4469,7 @@ void BKE_nurb_direction_switch(Nurb *nu) bp2 = bp1 + (a - 1); a /= 2; while (bp1 != bp2 && a > 0) { - SWAP(BPoint, *bp1, *bp2); + std::swap( *bp1, *bp2); a--; bp1->tilt = -bp1->tilt; bp2->tilt = -bp2->tilt; @@ -4491,7 +4491,7 @@ void BKE_nurb_direction_switch(Nurb *nu) fp2 = fp1 + (a - 1); a /= 2; while (fp1 != fp2 && a > 0) { - SWAP(float, *fp1, *fp2); + std::swap( *fp1, *fp2); a--; fp1++; fp2--; @@ -4530,7 +4530,7 @@ void BKE_nurb_direction_switch(Nurb *nu) a /= 2; while (bp1 != bp2 && a > 0) { - SWAP(BPoint, *bp1, *bp2); + std::swap( *bp1, *bp2); a--; bp1++; bp2--; diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc index 2e285170b93..8cdcb85a033 100644 --- a/source/blender/blenkernel/intern/displist.cc +++ b/source/blender/blenkernel/intern/displist.cc @@ -1090,7 +1090,7 @@ static void calc_bevfac_mapping(const Curve *cu, } if (end < *r_start || (end == *r_start && *r_lastblend < 1.0f - *r_firstblend)) { - SWAP(int, *r_start, end); + std::swap(*r_start, end); tmpf = *r_lastblend; *r_lastblend = 1.0f - *r_firstblend; *r_firstblend = 1.0f - tmpf; diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index b19ad6a3e97..f8d7f822e7d 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -2547,7 +2547,7 @@ bool BKE_keyblock_move(Object *ob, int org_index, int new_index) BLI_listbase_swaplinks(&key->block, kb, other_kb); /* Swap absolute positions. */ - SWAP(float, kb->pos, other_kb->pos); + std::swap(kb->pos, other_kb->pos); kb = other_kb; } diff --git a/source/blender/blenkernel/intern/mball_tessellate.cc b/source/blender/blenkernel/intern/mball_tessellate.cc index c2322da19cb..1e3519847fe 100644 --- a/source/blender/blenkernel/intern/mball_tessellate.cc +++ b/source/blender/blenkernel/intern/mball_tessellate.cc @@ -181,7 +181,7 @@ static uint partition_mainb(MetaElem **mainb, uint start, uint end, uint s, floa break; } - SWAP(MetaElem *, mainb[i], mainb[j]); + std::swap(mainb[i], mainb[j]); i++; j--; } diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index a7f1eb1df00..30ed0e2ad02 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1746,7 +1746,7 @@ void BKE_mesh_mselect_active_set(Mesh *me, int index, int type) } else if (msel_index != me->totselect - 1) { /* move to the end */ - SWAP(MSelect, me->mselect[msel_index], me->mselect[me->totselect - 1]); + std::swap(me->mselect[msel_index], me->mselect[me->totselect - 1]); } BLI_assert((me->mselect[me->totselect - 1].index == index) && diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc index de080c9dff2..3df25464e34 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.cc +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -542,8 +542,8 @@ void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip) co_b = co[x * sides + y]; swap_v3_v3(co_a, co_b); - SWAP(float, co_a[0], co_a[1]); - SWAP(float, co_b[0], co_b[1]); + std::swap(co_a[0], co_a[1]); + std::swap(co_b[0], co_b[1]); if (use_loop_mdisp_flip) { co_a[2] *= -1.0f; @@ -553,7 +553,7 @@ void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip) co_a = co[x * sides + x]; - SWAP(float, co_a[0], co_a[1]); + std::swap(co_a[0], co_a[1]); if (use_loop_mdisp_flip) { co_a[2] *= -1.0f; @@ -588,10 +588,10 @@ void BKE_mesh_polygon_flip_ex(const MPoly *mpoly, for (loopstart++; loopend > loopstart; loopstart++, loopend--) { mloop[loopend].e = mloop[loopend - 1].e; - SWAP(uint, mloop[loopstart].e, prev_edge_index); + std::swap(mloop[loopstart].e, prev_edge_index); if (!loops_in_ldata) { - SWAP(MLoop, mloop[loopstart], mloop[loopend]); + std::swap(mloop[loopstart], mloop[loopend]); } if (lnors) { swap_v3_v3(lnors[loopstart], lnors[loopend]); diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 7d4f0f8f7f8..3dce2d8b136 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -158,7 +158,7 @@ static void mesh_calc_edges_mdata(const MVert * /*allvert*/, /* order is swapped so extruding this edge as a surface won't flip face normals * with cyclic curves */ if (ed->v1 + 1 != ed->v2) { - SWAP(uint, med->v1, med->v2); + std::swap(med->v1, med->v2); } med++; } @@ -912,8 +912,8 @@ int BKE_mesh_mface_index_validate(MFace *mface, CustomData *fdata, int mfindex, if (mface->v3 == 0) { static int corner_indices[4] = {1, 2, 0, 3}; - SWAP(uint, mface->v1, mface->v2); - SWAP(uint, mface->v2, mface->v3); + std::swap(mface->v1, mface->v2); + std::swap(mface->v2, mface->v3); if (fdata) { CustomData_swap_corners(fdata, mfindex, corner_indices); @@ -924,8 +924,8 @@ int BKE_mesh_mface_index_validate(MFace *mface, CustomData *fdata, int mfindex, if (mface->v3 == 0 || mface->v4 == 0) { static int corner_indices[4] = {2, 3, 0, 1}; - SWAP(uint, mface->v1, mface->v3); - SWAP(uint, mface->v2, mface->v4); + std::swap(mface->v1, mface->v3); + std::swap(mface->v2, mface->v4); if (fdata) { CustomData_swap_corners(fdata, mfindex, corner_indices); diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index acc6a32b0eb..1f7dc7071c2 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -128,7 +128,7 @@ static void palette_undo_preserve(BlendLibReader * /*reader*/, ID *id_new, ID *i /* NOTE: We do not swap IDProperties, as dealing with potential ID pointers in those would be * fairly delicate. */ BKE_lib_id_swap(nullptr, id_new, id_old); - SWAP(IDProperty *, id_new->properties, id_old->properties); + std::swap(id_new->properties, id_old->properties); } IDTypeInfo IDType_ID_PAL = { @@ -1080,7 +1080,7 @@ bool BKE_paint_ensure(ToolSettings *ts, Paint **r_paint) Paint paint_test = **r_paint; BKE_paint_runtime_init(ts, *r_paint); /* Swap so debug doesn't hide errors when release fails. */ - SWAP(Paint, **r_paint, paint_test); + std::swap(**r_paint, paint_test); BLI_assert(paint_test.runtime.ob_mode == (*r_paint)->runtime.ob_mode); BLI_assert(paint_test.runtime.tool_offset == (*r_paint)->runtime.tool_offset); #endif diff --git a/source/blender/blenkernel/intern/scene.cc b/source/blender/blenkernel/intern/scene.cc index 8ec2d06adfc..57f49c23b88 100644 --- a/source/blender/blenkernel/intern/scene.cc +++ b/source/blender/blenkernel/intern/scene.cc @@ -510,12 +510,12 @@ static void scene_foreach_toolsettings_id_pointer_process( } /* We failed to find a new valid pointer for the previous ID, just keep the current one as * if we had been under SCENE_FOREACH_UNDO_NO_RESTORE case. */ - SWAP(ID *, *id_p, *id_old_p); + std::swap(*id_p, *id_old_p); break; } case SCENE_FOREACH_UNDO_NO_RESTORE: /* Counteract the swap of the whole ToolSettings container struct. */ - SWAP(ID *, *id_p, *id_old_p); + std::swap(*id_p, *id_old_p); break; } } @@ -1686,14 +1686,14 @@ static void scene_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old) Scene *scene_new = (Scene *)id_new; Scene *scene_old = (Scene *)id_old; - SWAP(View3DCursor, scene_old->cursor, scene_new->cursor); + std::swap( scene_old->cursor, scene_new->cursor); if (scene_new->toolsettings != nullptr && scene_old->toolsettings != nullptr) { /* First try to restore ID pointers that can be and should be preserved (like brushes or * palettes), and counteract the swap of the whole ToolSettings structs below for the others * (like object ones). */ scene_foreach_toolsettings( nullptr, scene_new->toolsettings, true, reader, scene_old->toolsettings); - SWAP(ToolSettings, *scene_old->toolsettings, *scene_new->toolsettings); + std::swap( *scene_old->toolsettings, *scene_new->toolsettings); } } diff --git a/source/blender/blenlib/intern/listbase.cc b/source/blender/blenlib/intern/listbase.cc index 0d5f2d2537a..6812a12c9f0 100644 --- a/source/blender/blenlib/intern/listbase.cc +++ b/source/blender/blenlib/intern/listbase.cc @@ -140,7 +140,7 @@ void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) } if (linkb->next == linka) { - SWAP(Link *, linka, linkb); + std::swap(linka, linkb); } if (linka->next == linkb) { @@ -150,8 +150,8 @@ void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) linkb->next = linka; } else { /* Non-contiguous items, we can safely swap. */ - SWAP(Link *, linka->prev, linkb->prev); - SWAP(Link *, linka->next, linkb->next); + std::swap(linka->prev, linkb->prev); + std::swap(linka->next, linkb->next); } /* Update neighbors of linka and linkb. */ diff --git a/source/blender/blenlib/tests/BLI_math_rotation_test.cc b/source/blender/blenlib/tests/BLI_math_rotation_test.cc index 32d8f8bf19e..140f499ca8e 100644 --- a/source/blender/blenlib/tests/BLI_math_rotation_test.cc +++ b/source/blender/blenlib/tests/BLI_math_rotation_test.cc @@ -221,7 +221,7 @@ static void test_sin_cos_from_fraction_symmetry(const int range) sin_cos_fl[0] = fabsf(sin_cos_fl[0]); sin_cos_fl[1] = fabsf(sin_cos_fl[1]); if (sin_cos_fl[0] > sin_cos_fl[1]) { - SWAP(float, sin_cos_fl[0], sin_cos_fl[1]); + std::swap(sin_cos_fl[0], sin_cos_fl[1]); } break; } diff --git a/source/blender/bmesh/intern/bmesh_mesh.cc b/source/blender/bmesh/intern/bmesh_mesh.cc index 5c8f32b9bfa..d8fe0c36108 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.cc +++ b/source/blender/bmesh/intern/bmesh_mesh.cc @@ -1249,7 +1249,7 @@ void BM_mesh_rebuild(BMesh *bm, * (and not be needed). */ if (remap & BM_VERT) { if (bm->vtable) { - SWAP(BMVert **, vtable_dst, bm->vtable); + std::swap(vtable_dst, bm->vtable); bm->vtable_tot = bm->totvert; bm->elem_table_dirty &= ~BM_VERT; } @@ -1260,7 +1260,7 @@ void BM_mesh_rebuild(BMesh *bm, if (remap & BM_EDGE) { if (bm->etable) { - SWAP(BMEdge **, etable_dst, bm->etable); + std::swap(etable_dst, bm->etable); bm->etable_tot = bm->totedge; bm->elem_table_dirty &= ~BM_EDGE; } @@ -1278,7 +1278,7 @@ void BM_mesh_rebuild(BMesh *bm, if (remap & BM_FACE) { if (bm->ftable) { - SWAP(BMFace **, ftable_dst, bm->ftable); + std::swap(ftable_dst, bm->ftable); bm->ftable_tot = bm->totface; bm->elem_table_dirty &= ~BM_FACE; } diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.cc b/source/blender/bmesh/intern/bmesh_mesh_normals.cc index 41203f25b6b..03bd1811fd8 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_normals.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_normals.cc @@ -935,7 +935,7 @@ static void bm_mesh_loops_calc_normals_for_vert_with_clnors(BMesh *bm, * The order doesn't matter, so swap the links as it's simpler than tracking * reference to `link_best`. */ if (link_best != loops_of_vert) { - SWAP(void *, link_best->link, loops_of_vert->link); + std::swap(link_best->link, loops_of_vert->link); } } diff --git a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc index 4f7b1be9057..b5fe0fdf6f3 100644 --- a/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc +++ b/source/blender/compositor/operations/COM_GlareFogGlowOperation.cc @@ -130,7 +130,7 @@ static void FHT2D(fREAL *data, uint Mx, uint My, uint nzp, uint inverse) for (j = 0; j < Ny; j++) { for (i = j + 1; i < Nx; i++) { uint op = i + (j << Mx), np = j + (i << My); - SWAP(fREAL, data[op], data[np]); + std::swap(data[op], data[np]); } } } @@ -145,15 +145,15 @@ static void FHT2D(fREAL *data, uint Mx, uint My, uint nzp, uint inverse) continue; } for (k = i, j = PRED(i); j != i; k = j, j = PRED(j), stm--) { - SWAP(fREAL, data[j], data[k]); + std::swap(data[j], data[k]); } #undef PRED stm--; } } - SWAP(uint, Nx, Ny); - SWAP(uint, Mx, My); + std::swap(Nx, Ny); + std::swap(Mx, My); /* Now columns == transposed rows. */ for (j = 0; j < Ny; j++) { diff --git a/source/blender/compositor/operations/COM_VectorBlurOperation.cc b/source/blender/compositor/operations/COM_VectorBlurOperation.cc index 1330557c06f..39b190c8c8e 100644 --- a/source/blender/compositor/operations/COM_VectorBlurOperation.cc +++ b/source/blender/compositor/operations/COM_VectorBlurOperation.cc @@ -655,7 +655,7 @@ void zbuf_accumulate_vecblur(NodeBlurData *nbd, } } } - SWAP(float *, minvecbufrect, vecbufrect); + std::swap(minvecbufrect, vecbufrect); } /* Make vertex buffer with averaged speed and Z-values. */ diff --git a/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc b/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc index 226635c1ade..ec89cdba0b1 100644 --- a/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc +++ b/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc @@ -754,7 +754,7 @@ void DepthOfField::render(View &view, DRW_stats_group_end(); /* Swap buffers so that next effect has the right input. */ - SWAP(GPUTexture *, *input_tx, *output_tx); + std::swap(*input_tx, *output_tx); } /** \} */ diff --git a/source/blender/draw/engines/eevee_next/eevee_film.cc b/source/blender/draw/engines/eevee_next/eevee_film.cc index 82f948167dc..beab3bdb196 100644 --- a/source/blender/draw/engines/eevee_next/eevee_film.cc +++ b/source/blender/draw/engines/eevee_next/eevee_film.cc @@ -595,7 +595,7 @@ void Film::update_sample_table() } /* Put the closest one in first position. */ if (closest_index != 0) { - SWAP(FilmSample, data_.samples[closest_index], data_.samples[0]); + std::swap(data_.samples[closest_index], data_.samples[0]); } } else { diff --git a/source/blender/draw/engines/eevee_next/eevee_velocity.cc b/source/blender/draw/engines/eevee_next/eevee_velocity.cc index 52401c8003e..b2dec3698cf 100644 --- a/source/blender/draw/engines/eevee_next/eevee_velocity.cc +++ b/source/blender/draw/engines/eevee_next/eevee_velocity.cc @@ -219,10 +219,10 @@ void VelocityModule::step_swap() } auto swap_steps = [&](eVelocityStep step_a, eVelocityStep step_b) { - SWAP(VelocityObjectBuf *, object_steps[step_a], object_steps[step_b]); - SWAP(VelocityGeometryBuf *, geometry_steps[step_a], geometry_steps[step_b]); - SWAP(CameraDataBuf *, camera_steps[step_a], camera_steps[step_b]); - SWAP(float, step_time[step_a], step_time[step_b]); + std::swap(object_steps[step_a], object_steps[step_b]); + std::swap(geometry_steps[step_a], geometry_steps[step_b]); + std::swap(camera_steps[step_a], camera_steps[step_b]); + std::swap(step_time[step_a], step_time[step_b]); for (VelocityObjectData &vel : velocity_map.values()) { vel.obj.ofs[step_a] = vel.obj.ofs[step_b]; diff --git a/source/blender/draw/engines/overlay/overlay_motion_path.cc b/source/blender/draw/engines/overlay/overlay_motion_path.cc index 3f6954f821b..17b14363a50 100644 --- a/source/blender/draw/engines/overlay/overlay_motion_path.cc +++ b/source/blender/draw/engines/overlay/overlay_motion_path.cc @@ -95,7 +95,7 @@ static void motion_path_get_frame_range_to_draw(bAnimVizSettings *avs, } if (start > end) { - SWAP(int, start, end); + std::swap(start, end); } CLAMP(start, mpath->start_frame, mpath->end_frame); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc index 3124a35608d..6353a016899 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines_adjacency.cc @@ -148,7 +148,7 @@ static void extract_lines_adjacency_finish(const MeshRenderData * /*mr*/, BLI_edgehashIterator_getKey(ehi, &v2, &v3); l1 = uint(abs(v_data)) - 1; if (v_data < 0) { /* `inv_opposite`. */ - SWAP(uint, v2, v3); + std::swap(v2, v3); } l2 = data->vert_to_loop[v2]; l3 = data->vert_to_loop[v3]; diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index 6728b1e3a41..6998aa91e9f 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -863,26 +863,26 @@ static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but) /* typically the same pointers, but not on undo/redo */ /* XXX some menu buttons store button itself in but->poin. Ugly */ if (oldbut->poin != (char *)oldbut) { - SWAP(char *, oldbut->poin, but->poin); - SWAP(void *, oldbut->func_argN, but->func_argN); + std::swap(oldbut->poin, but->poin); + std::swap(oldbut->func_argN, but->func_argN); } /* Move tooltip from new to old. */ - SWAP(uiButToolTipFunc, oldbut->tip_func, but->tip_func); - SWAP(void *, oldbut->tip_arg, but->tip_arg); - SWAP(uiFreeArgFunc, oldbut->tip_arg_free, but->tip_arg_free); + std::swap(oldbut->tip_func, but->tip_func); + std::swap(oldbut->tip_arg, but->tip_arg); + std::swap(oldbut->tip_arg_free, but->tip_arg_free); oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy); oldbut->drawflag = (oldbut->drawflag & ~drawflag_copy) | (but->drawflag & drawflag_copy); ui_but_extra_icons_update_from_old_but(but, oldbut); - SWAP(ListBase, but->extra_op_icons, oldbut->extra_op_icons); + std::swap(but->extra_op_icons, oldbut->extra_op_icons); if (oldbut->type == UI_BTYPE_SEARCH_MENU) { uiButSearch *search_oldbut = (uiButSearch *)oldbut, *search_but = (uiButSearch *)but; - SWAP(uiFreeArgFunc, search_oldbut->arg_free_fn, search_but->arg_free_fn); - SWAP(void *, search_oldbut->arg, search_but->arg); + std::swap(search_oldbut->arg_free_fn, search_but->arg_free_fn); + std::swap(search_oldbut->arg, search_but->arg); } /* copy hardmin for list rows to prevent 'sticking' highlight to mouse position @@ -901,7 +901,7 @@ static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but) case UI_BTYPE_VIEW_ITEM: { uiButViewItem *view_item_oldbut = (uiButViewItem *)oldbut; uiButViewItem *view_item_newbut = (uiButViewItem *)but; - SWAP(uiViewItemHandle *, view_item_newbut->view_item, view_item_oldbut->view_item); + std::swap(view_item_newbut->view_item, view_item_oldbut->view_item); break; } default: @@ -912,7 +912,7 @@ static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but) /* needed for alt+mouse wheel over enums */ if (but->str != but->strdata) { if (oldbut->str != oldbut->strdata) { - SWAP(char *, but->str, oldbut->str); + std::swap(but->str, oldbut->str); } else { oldbut->str = but->str; @@ -928,10 +928,10 @@ static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but) } if (but->dragpoin) { - SWAP(void *, but->dragpoin, oldbut->dragpoin); + std::swap(but->dragpoin, oldbut->dragpoin); } if (but->imb) { - SWAP(ImBuf *, but->imb, oldbut->imb); + std::swap(but->imb, oldbut->imb); } /* NOTE: if layout hasn't been applied yet, it uses old button pointers... */ @@ -5853,7 +5853,7 @@ void UI_block_order_flip(uiBlock *block) LISTBASE_FOREACH (uiBut *, but, &block->buttons) { but->rect.ymin = centy - (but->rect.ymin - centy); but->rect.ymax = centy - (but->rect.ymax - centy); - SWAP(float, but->rect.ymin, but->rect.ymax); + std::swap(but->rect.ymin, but->rect.ymax); } block->flag ^= UI_BLOCK_IS_FLIP; diff --git a/source/blender/editors/interface/interface_align.cc b/source/blender/editors/interface/interface_align.cc index e17012c9166..2f7d4fc68ea 100644 --- a/source/blender/editors/interface/interface_align.cc +++ b/source/blender/editors/interface/interface_align.cc @@ -156,7 +156,7 @@ static void block_align_proximity_compute(ButAlign *butal, ButAlign *butal_other delta_side_opp = max_ff(fabsf(*butal->borders[side_opp] - *butal_other->borders[side]), FLT_MIN); if (delta_side_opp < delta) { - SWAP(int, side, side_opp); + std::swap(side, side_opp); delta = delta_side_opp; } diff --git a/source/blender/editors/interface/interface_anim.cc b/source/blender/editors/interface/interface_anim.cc index aa218aa51f4..a8a4faf622f 100644 --- a/source/blender/editors/interface/interface_anim.cc +++ b/source/blender/editors/interface/interface_anim.cc @@ -326,7 +326,7 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void * /*arg_dummy*/) } /* FIXME(@campbellbarton): swapping active pointer is weak. */ - SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->but.active); + std::swap(but_anim->active, but_decorate->but.active); wm->op_undo_depth++; if (but_anim->flag & UI_BUT_DRIVEN) { @@ -350,6 +350,6 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void * /*arg_dummy*/) WM_operator_properties_free(&props_ptr); } - SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->but.active); + std::swap(but_anim->active, but_decorate->but.active); wm->op_undo_depth--; } diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index dfd89dd2b38..ab965fb7560 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -3087,7 +3087,7 @@ static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data, but->selsta = but->pos; but->selend = data->sel_pos_init; if (but->selend < but->selsta) { - SWAP(short, but->selsta, but->selend); + std::swap(but->selsta, but->selend); } ui_but_update(but); @@ -3190,7 +3190,7 @@ static void ui_textedit_move(uiBut *but, but->selend = data->sel_pos_init; } if (but->selend < but->selsta) { - SWAP(short, but->selsta, but->selend); + std::swap( but->selsta, but->selend); } } } diff --git a/source/blender/editors/interface/interface_widgets.cc b/source/blender/editors/interface/interface_widgets.cc index 3c0b5064d1f..54e380526cb 100644 --- a/source/blender/editors/interface/interface_widgets.cc +++ b/source/blender/editors/interface/interface_widgets.cc @@ -2500,7 +2500,7 @@ static void widget_state(uiWidgetType *wt, const uiWidgetStateInfo *state, eUIEm copy_v3_v3_uchar(wt->wcol.text, wt->wcol.text_sel); if (state->but_flag & UI_SELECT) { - SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown); + std::swap(wt->wcol.shadetop, wt->wcol.shadedown); } } else { @@ -2534,7 +2534,7 @@ static void widget_state(uiWidgetType *wt, const uiWidgetStateInfo *state, eUIEm if (state->but_flag & UI_BUT_DRAG_MULTI) { /* the button isn't SELECT but we're editing this so draw with sel color */ copy_v4_v4_uchar(wt->wcol.inner, wt->wcol.inner_sel); - SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown); + std::swap(wt->wcol.shadetop, wt->wcol.shadedown); color_blend_v3_v3(wt->wcol.text, wt->wcol.text_sel, 0.85f); } @@ -2592,7 +2592,7 @@ static void widget_state_numslider(uiWidgetType *wt, } if (state->but_flag & UI_SELECT) { - SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown); + std::swap(wt->wcol.shadetop, wt->wcol.shadedown); } } @@ -3306,7 +3306,7 @@ static void widget_numbut_draw(uiWidgetColors *wcol, const int handle_width = min_ii(BLI_rcti_size_x(rect) / 3, BLI_rcti_size_y(rect) * 0.7f); if (state->but_flag & UI_SELECT) { - SWAP(short, wcol->shadetop, wcol->shadedown); + std::swap(wcol->shadetop, wcol->shadedown); } uiWidgetBase wtb; @@ -3483,7 +3483,7 @@ void UI_draw_widget_scroll(uiWidgetColors *wcol, const rcti *rect, const rcti *s /* draw back part, colors swapped and shading inverted */ if (horizontal) { - SWAP(short, wcol->shadetop, wcol->shadedown); + std::swap(wcol->shadetop, wcol->shadedown); } round_box_edges(&wtb, UI_CNR_ALL, rect, rad); @@ -3494,7 +3494,7 @@ void UI_draw_widget_scroll(uiWidgetColors *wcol, const rcti *rect, const rcti *s /* pass */ } else { - SWAP(short, wcol->shadetop, wcol->shadedown); + std::swap(wcol->shadetop, wcol->shadedown); copy_v4_v4_uchar(wcol->inner, wcol->item); @@ -3721,7 +3721,7 @@ static void widget_numslider(uiBut *but, copy_v3_v3_uchar(wcol->inner, wcol->item); if (!(state->but_flag & UI_SELECT)) { - SWAP(short, wcol->shadetop, wcol->shadedown); + std::swap(wcol->shadetop, wcol->shadedown); } rcti rect1 = *rect; @@ -3789,7 +3789,7 @@ static void widget_numslider(uiBut *but, copy_v3_v3_uchar(wcol->outline, outline); if (!(state->but_flag & UI_SELECT)) { - SWAP(short, wcol->shadetop, wcol->shadedown); + std::swap(wcol->shadetop, wcol->shadedown); } } @@ -3946,7 +3946,7 @@ static void widget_textbut(uiWidgetColors *wcol, const float zoom) { if (state->but_flag & UI_SELECT) { - SWAP(short, wcol->shadetop, wcol->shadedown); + std::swap(wcol->shadetop, wcol->shadedown); } uiWidgetBase wtb; diff --git a/source/blender/editors/mesh/editmesh_select.cc b/source/blender/editors/mesh/editmesh_select.cc index 2ef2772d404..d86d12eb155 100644 --- a/source/blender/editors/mesh/editmesh_select.cc +++ b/source/blender/editors/mesh/editmesh_select.cc @@ -3048,7 +3048,7 @@ bool EDBM_select_interior_faces(BMEditMesh *em) /* Only for predictable results that don't depend on the order of radial loops, * not essential. */ if (i_a > i_b) { - SWAP(int, i_a, i_b); + std::swap(i_a, i_b); } /* Merge the groups. */ diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc index cf34852b3c0..99a4ece0408 100644 --- a/source/blender/editors/mesh/meshtools.cc +++ b/source/blender/editors/mesh/meshtools.cc @@ -1158,8 +1158,8 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval) /* make sure v4 is not 0 if a quad */ if (mf->v4 && mirrormf.v4 == 0) { - SWAP(uint, mirrormf.v1, mirrormf.v3); - SWAP(uint, mirrormf.v2, mirrormf.v4); + std::swap(mirrormf.v1, mirrormf.v3); + std::swap(mirrormf.v2, mirrormf.v4); } hashmf = static_cast(BLI_ghash_lookup(fhash, &mirrormf)); diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc index d3bdf8ca4d3..7be44795d63 100644 --- a/source/blender/editors/object/object_vgroup.cc +++ b/source/blender/editors/object/object_vgroup.cc @@ -1465,10 +1465,10 @@ static void moveCloserToDistanceFromPlane(Depsgraph *depsgraph, } /* switch with k */ if (bestIndex != k) { - SWAP(bool, upDown[k], upDown[bestIndex]); - SWAP(int, dwIndices[k], dwIndices[bestIndex]); + std::swap(upDown[k], upDown[bestIndex]); + std::swap(dwIndices[k], dwIndices[bestIndex]); swap_v2_v2(changes[k], changes[bestIndex]); - SWAP(float, dists[k], dists[bestIndex]); + std::swap(dists[k], dists[bestIndex]); } } bestIndex = -1; @@ -2092,7 +2092,7 @@ static void vgroup_smooth_subset(Object *ob, } } - SWAP(float *, weight_accum_curr, weight_accum_prev); + std::swap(weight_accum_curr, weight_accum_prev); } ED_vgroup_parray_from_weight_array(dvert_array, dvert_tot, weight_accum_prev, def_nr, true); @@ -2319,14 +2319,14 @@ static void dvert_mirror_op(MDeformVert *dvert, /* swap */ if (mirror_weights) { if (all_vgroups) { - SWAP(MDeformVert, *dvert, *dvert_mirr); + std::swap(*dvert, *dvert_mirr); } else { MDeformWeight *dw = BKE_defvert_find_index(dvert, act_vgroup); MDeformWeight *dw_mirr = BKE_defvert_find_index(dvert_mirr, act_vgroup); if (dw && dw_mirr) { - SWAP(float, dw->weight, dw_mirr->weight); + std::swap(dw->weight, dw_mirr->weight); } else if (dw) { dw_mirr = BKE_defvert_ensure_index(dvert_mirr, act_vgroup); @@ -2349,7 +2349,7 @@ static void dvert_mirror_op(MDeformVert *dvert, else { /* dvert should always be the target, only swaps pointer */ if (sel_mirr) { - SWAP(MDeformVert *, dvert, dvert_mirr); + std::swap(dvert, dvert_mirr); } if (mirror_weights) { diff --git a/source/blender/editors/space_image/image_undo.cc b/source/blender/editors/space_image/image_undo.cc index 1589195d2af..b7aaca0bbd8 100644 --- a/source/blender/editors/space_image/image_undo.cc +++ b/source/blender/editors/space_image/image_undo.cc @@ -261,10 +261,10 @@ void *ED_image_paint_tile_push(PaintTileMap *paint_tile_map, ED_IMAGE_UNDO_TILE_SIZE); if (has_float) { - SWAP(float *, ptile->rect.fp, (*tmpibuf)->rect_float); + std::swap( ptile->rect.fp, (*tmpibuf)->rect_float); } else { - SWAP(uint32_t *, ptile->rect.uint, (*tmpibuf)->rect); + std::swap(ptile->rect.uint, (*tmpibuf)->rect); } PaintTileKey key = {}; @@ -299,10 +299,10 @@ static void ptile_restore_runtime_map(PaintTileMap *paint_tile_map) const bool has_float = (ibuf->rect_float != nullptr); if (has_float) { - SWAP(float *, ptile->rect.fp, tmpibuf->rect_float); + std::swap( ptile->rect.fp, tmpibuf->rect_float); } else { - SWAP(uint32_t *, ptile->rect.uint, tmpibuf->rect); + std::swap(ptile->rect.uint, tmpibuf->rect); } IMB_rectcpy(ibuf, @@ -315,10 +315,10 @@ static void ptile_restore_runtime_map(PaintTileMap *paint_tile_map) ED_IMAGE_UNDO_TILE_SIZE); if (has_float) { - SWAP(float *, ptile->rect.fp, tmpibuf->rect_float); + std::swap( ptile->rect.fp, tmpibuf->rect_float); } else { - SWAP(uint32_t *, ptile->rect.uint, tmpibuf->rect); + std::swap(ptile->rect.uint, tmpibuf->rect); } /* Force OpenGL reload (maybe partial update will operate better?) */ @@ -380,19 +380,19 @@ static void utile_init_from_imbuf( const bool has_float = ibuf->rect_float; if (has_float) { - SWAP(float *, utile->rect.fp, tmpibuf->rect_float); + std::swap( utile->rect.fp, tmpibuf->rect_float); } else { - SWAP(uint32_t *, utile->rect.uint_ptr, tmpibuf->rect); + std::swap(utile->rect.uint_ptr, tmpibuf->rect); } IMB_rectcpy(tmpibuf, ibuf, 0, 0, x, y, ED_IMAGE_UNDO_TILE_SIZE, ED_IMAGE_UNDO_TILE_SIZE); if (has_float) { - SWAP(float *, utile->rect.fp, tmpibuf->rect_float); + std::swap( utile->rect.fp, tmpibuf->rect_float); } else { - SWAP(uint32_t *, utile->rect.uint_ptr, tmpibuf->rect); + std::swap(utile->rect.uint_ptr, tmpibuf->rect); } } diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 98f45fc4956..098c08686b4 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -434,10 +434,10 @@ static void node_update_basis(const bContext &C, /* Make sure that maximums are bigger or equal to minimums. */ if (node.runtime->prvr.xmax < node.runtime->prvr.xmin) { - SWAP(float, node.runtime->prvr.xmax, node.runtime->prvr.xmin); + std::swap(node.runtime->prvr.xmax, node.runtime->prvr.xmin); } if (node.runtime->prvr.ymax < node.runtime->prvr.ymin) { - SWAP(float, node.runtime->prvr.ymax, node.runtime->prvr.ymin); + std::swap(node.runtime->prvr.ymax, node.runtime->prvr.ymin); } } diff --git a/source/blender/editors/space_node/node_gizmo.cc b/source/blender/editors/space_node/node_gizmo.cc index 7a77d523f43..a55960b5583 100644 --- a/source/blender/editors/space_node/node_gizmo.cc +++ b/source/blender/editors/space_node/node_gizmo.cc @@ -285,10 +285,10 @@ static void gizmo_node_crop_prop_matrix_set(const wmGizmo *gz, rct_isect.ymax = 1; BLI_rctf_isect(&rct_isect, &rct, &rct); if (nx) { - SWAP(float, rct.xmin, rct.xmax); + std::swap( rct.xmin, rct.xmax); } if (ny) { - SWAP(float, rct.ymin, rct.ymax); + std::swap( rct.ymin, rct.ymax); } two_xy_from_rect(nxy, &rct, dims, is_relative); gizmo_node_crop_update(crop_group); diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index 3e62a1023f5..c3ed050e8e4 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -355,7 +355,7 @@ static void snode_autoconnect(SpaceNode &snode, const bool allow_multiple, const bNode *node_to = sorted_nodes[i + 1]; /* Corner case: input/output node aligned the wrong way around (T47729). */ if (BLI_listbase_is_empty(&node_to->inputs) || BLI_listbase_is_empty(&node_fr->outputs)) { - SWAP(bNode *, node_fr, node_to); + std::swap(node_fr, node_to); } /* If there are selected sockets, connect those. */ diff --git a/source/blender/editors/space_view3d/view3d_draw.cc b/source/blender/editors/space_view3d/view3d_draw.cc index 4fed15ccf24..e45bf3c1488 100644 --- a/source/blender/editors/space_view3d/view3d_draw.cc +++ b/source/blender/editors/space_view3d/view3d_draw.cc @@ -493,7 +493,7 @@ static void drawviewborder_triangle( ofs = h * (h / w); } if (dir == 'B') { - SWAP(float, y1, y2); + std::swap(y1, y2); } immVertex2f(shdr_pos, x1, y1); @@ -513,7 +513,7 @@ static void drawviewborder_triangle( ofs = w * (w / h); } if (dir == 'B') { - SWAP(float, x1, x2); + std::swap(x1, x2); } immVertex2f(shdr_pos, x1, y1); diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc index 6116586a8cf..618bcbd95e8 100644 --- a/source/blender/geometry/intern/mesh_merge_by_distance.cc +++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc @@ -1654,7 +1654,7 @@ std::optional mesh_merge_by_distance_connected(const Mesh &mesh, continue; } if (v1 > v2) { - SWAP(int, v1, v2); + std::swap( v1, v2); } WeldVertexCluster *v1_cluster = &vert_clusters[v1]; WeldVertexCluster *v2_cluster = &vert_clusters[v2]; diff --git a/source/blender/geometry/intern/uv_parametrizer.cc b/source/blender/geometry/intern/uv_parametrizer.cc index ff3458aa0e6..03accc5dd2e 100644 --- a/source/blender/geometry/intern/uv_parametrizer.cc +++ b/source/blender/geometry/intern/uv_parametrizer.cc @@ -2168,7 +2168,7 @@ static void p_chart_simplify_compute(PChart *chart) if (edge->vert->u.heaplink != link) { edge->flag |= (PEDGE_COLLAPSE_EDGE | PEDGE_COLLAPSE_PAIR); edge->next->vert->u.heaplink = nullptr; - SWAP(PEdge *, edge, pair); + std::swap( edge, pair); } else { edge->flag |= PEDGE_COLLAPSE_EDGE; @@ -2237,7 +2237,7 @@ static void p_chart_complexify(PChart *chart) pair = e->pair; if (edge->flag & PEDGE_COLLAPSE_PAIR) { - SWAP(PEdge *, edge, pair); + std::swap( edge, pair); } p_split_vertex(edge, pair); @@ -3142,9 +3142,9 @@ static bool p_chart_lscm_solve(ParamHandle *handle, PChart *chart) } if (flip_faces) { - SWAP(float, a2, a3); - SWAP(PEdge *, e2, e3); - SWAP(PVert *, v2, v3); + std::swap(a2, a3); + std::swap(e2, e3); + std::swap(v2, v3); } float sina1 = sinf(a1); diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index 54d7d5750de..357b818bbdc 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -1878,7 +1878,7 @@ static void lineart_edge_neighbor_init_task(void *__restrict userdata, adj_e->v1 = mloop[looptri->tri[i % 3]].v; adj_e->v2 = mloop[looptri->tri[(i + 1) % 3]].v; if (adj_e->v1 > adj_e->v2) { - SWAP(uint32_t, adj_e->v1, adj_e->v2); + std::swap( adj_e->v1, adj_e->v2); } edge_nabr->e = -1; @@ -3267,7 +3267,7 @@ static void lineart_add_isec_thread(LineartIsecThread *th, isec_single->tri1 = tri1; isec_single->tri2 = tri2; if (tri1->target_reference > tri2->target_reference) { - SWAP(LineartTriangle *, isec_single->tri1, isec_single->tri2); + std::swap( isec_single->tri1, isec_single->tri2); } th->current++; } diff --git a/source/blender/modifiers/intern/MOD_screw.cc b/source/blender/modifiers/intern/MOD_screw.cc index 5d9e6a84422..d1660d0ced4 100644 --- a/source/blender/modifiers/intern/MOD_screw.cc +++ b/source/blender/modifiers/intern/MOD_screw.cc @@ -464,7 +464,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* also order edges based on faces */ if (medge_new[ml_orig->e].v1 != ml_orig->v) { - SWAP(uint, medge_new[ml_orig->e].v1, medge_new[ml_orig->e].v2); + std::swap(medge_new[ml_orig->e].v1, medge_new[ml_orig->e].v2); } } } @@ -716,7 +716,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * if (lt_iter.v == lt_iter.e->v1) { if (ed_loop_flip == 0) { // printf("\t\t\tFlipping 0\n"); - SWAP(uint, lt_iter.e->v1, lt_iter.e->v2); + std::swap(lt_iter.e->v1, lt_iter.e->v2); } #if 0 else { @@ -727,7 +727,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * else if (lt_iter.v == lt_iter.e->v2) { if (ed_loop_flip == 1) { // printf("\t\t\tFlipping 1\n"); - SWAP(uint, lt_iter.e->v1, lt_iter.e->v2); + std::swap(lt_iter.e->v1, lt_iter.e->v2); } #if 0 else { diff --git a/source/blender/render/intern/multires_bake.cc b/source/blender/render/intern/multires_bake.cc index 4ef71dc39a3..5f27a1b9dc7 100644 --- a/source/blender/render/intern/multires_bake.cc +++ b/source/blender/render/intern/multires_bake.cc @@ -259,7 +259,7 @@ static void rasterize_half(const MBakeRast *bake_rast, float x_r = l_stable != 0 ? (s0_l + (((s1_l - s0_l) * (y - t0_l)) / (t1_l - t0_l))) : s0_l; if (is_mid_right != 0) { - SWAP(float, x_l, x_r); + std::swap( x_l, x_r); } iXl = int(ceilf(x_l)); @@ -298,17 +298,17 @@ static void bake_rasterize(const MBakeRast *bake_rast, /* sort by T */ if (tlo > tmi && tlo > thi) { - SWAP(float, shi, slo); - SWAP(float, thi, tlo); + std::swap( shi, slo); + std::swap( thi, tlo); } else if (tmi > thi) { - SWAP(float, shi, smi); - SWAP(float, thi, tmi); + std::swap( shi, smi); + std::swap( thi, tmi); } if (tlo > tmi) { - SWAP(float, slo, smi); - SWAP(float, tlo, tmi); + std::swap( slo, smi); + std::swap( tlo, tmi); } /* check if mid point is to the left or to the right of the lo-hi edge */ diff --git a/source/blender/render/intern/pipeline.cc b/source/blender/render/intern/pipeline.cc index 4a926bb47cd..5cd151189da 100644 --- a/source/blender/render/intern/pipeline.cc +++ b/source/blender/render/intern/pipeline.cc @@ -340,7 +340,7 @@ void RE_SwapResult(Render *re, RenderResult **rr) { /* for keeping render buffers */ if (re) { - SWAP(RenderResult *, re->result, *rr); + std::swap(re->result, *rr); } } diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index 528495fe7ba..1af97196acd 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -4426,7 +4426,7 @@ static void wm_event_get_keymap_from_toolsystem_ex(wmWindowManager *wm, if (is_gizmo_visible && !is_gizmo_highlight) { if (keymap_id_list_len == 2) { - SWAP(const char *, keymap_id_list[0], keymap_id_list[1]); + std::swap(keymap_id_list[0], keymap_id_list[1]); } } From 891fe70d7f0a84573b94379d067f00fb0469b0c2 Mon Sep 17 00:00:00 2001 From: Leon Schittek Date: Mon, 9 Jan 2023 11:37:27 -0500 Subject: [PATCH 0536/1522] Fix T103739: Nodes pasted at wrong position with UI scale --- source/blender/editors/space_node/clipboard.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/editors/space_node/clipboard.cc b/source/blender/editors/space_node/clipboard.cc index beda081eec8..95c1c25e343 100644 --- a/source/blender/editors/space_node/clipboard.cc +++ b/source/blender/editors/space_node/clipboard.cc @@ -257,11 +257,10 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op) } /* DPI factor needs to be removed when computing a View2D offset from drawing rects. */ center /= clipboard.nodes.size(); - center /= UI_DPI_FAC; float2 mouse_location; RNA_property_float_get_array(op->ptr, offset_prop, mouse_location); - const float2 offset = mouse_location - center; + const float2 offset = (mouse_location - center) / UI_DPI_FAC; for (bNode *new_node : node_map.values()) { new_node->locx += offset.x; From ec2046c38da49528af26f9aedc5913b733105dd0 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Mon, 9 Jan 2023 17:55:02 +0100 Subject: [PATCH 0537/1522] Fix T103531: Hold split not working correctly Incorrect offset was calculated when strip was implicitly retimed (movie FPS does not match scene FPS). This is because strip playback rate was not used for offset calculation at all. Since hold offset is specifying numbers of frames to skip, but at frame rate of the source, this could result in gap when splitting the strip. If that occurs, gap is compensated by moving handle to frame where strip is split. --- source/blender/sequencer/intern/strip_edit.c | 46 ++++++++++++-------- source/blender/sequencer/intern/strip_time.c | 4 +- source/blender/sequencer/intern/strip_time.h | 3 ++ 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c index 69e43f3679c..5ac4bd03f43 100644 --- a/source/blender/sequencer/intern/strip_edit.c +++ b/source/blender/sequencer/intern/strip_edit.c @@ -258,7 +258,10 @@ bool SEQ_edit_move_strip_to_meta(Scene *scene, return true; } -static void seq_split_set_right_hold_offset(Scene *scene, Sequence *seq, int timeline_frame) +static void seq_split_set_right_hold_offset(Main *bmain, + Scene *scene, + Sequence *seq, + int timeline_frame) { const float content_start = SEQ_time_start_frame_get(seq); const float content_end = SEQ_time_content_end_frame_get(scene, seq); @@ -268,31 +271,35 @@ static void seq_split_set_right_hold_offset(Scene *scene, Sequence *seq, int tim const float offset = content_start + 1 - timeline_frame; seq->start -= offset; seq->startofs += offset; - SEQ_time_right_handle_frame_set(scene, seq, timeline_frame); } /* Adjust within range of strip contents. */ else if ((timeline_frame >= content_start) && (timeline_frame <= content_end)) { seq->endofs = 0; - seq->anim_endofs += (content_end - timeline_frame) * seq->speed_factor; - } - /* Adjust within range of extended still-frames after strip. */ - else if (timeline_frame > content_end) { - SEQ_time_right_handle_frame_set(scene, seq, timeline_frame); + float speed_factor = (seq->type == SEQ_TYPE_SOUND_RAM) ? + seq_time_media_playback_rate_factor_get(scene, seq) : + seq_time_playback_rate_factor_get(scene, seq); + seq->anim_endofs += round_fl_to_int((content_end - timeline_frame) * speed_factor); } + + /* Needed only to set `seq->len`. */ + SEQ_add_reload_new_file(bmain, scene, seq, false); + SEQ_time_right_handle_frame_set(scene, seq, timeline_frame); } -static void seq_split_set_left_hold_offset(Scene *scene, Sequence *seq, int timeline_frame) +static void seq_split_set_left_hold_offset(Main *bmain, + Scene *scene, + Sequence *seq, + int timeline_frame) { const float content_start = SEQ_time_start_frame_get(seq); const float content_end = SEQ_time_content_end_frame_get(scene, seq); - /* Adjust within range of extended still-frames before strip. */ - if (timeline_frame < content_start) { - SEQ_time_left_handle_frame_set(scene, seq, timeline_frame); - } /* Adjust within range of strip contents. */ - else if ((timeline_frame >= content_start) && (timeline_frame <= content_end)) { - seq->anim_startofs += (timeline_frame - content_start) * seq->speed_factor; + if ((timeline_frame >= content_start) && (timeline_frame <= content_end)) { + float speed_factor = (seq->type == SEQ_TYPE_SOUND_RAM) ? + seq_time_media_playback_rate_factor_get(scene, seq) : + seq_time_playback_rate_factor_get(scene, seq); + seq->anim_startofs += round_fl_to_int((timeline_frame - content_start) * speed_factor); seq->start = timeline_frame; seq->startofs = 0; } @@ -301,8 +308,11 @@ static void seq_split_set_left_hold_offset(Scene *scene, Sequence *seq, int time const float offset = timeline_frame - content_end + 1; seq->start += offset; seq->endofs += offset; - SEQ_time_left_handle_frame_set(scene, seq, timeline_frame); } + + /* Needed only to set `seq->len`. */ + SEQ_add_reload_new_file(bmain, scene, seq, false); + SEQ_time_left_handle_frame_set(scene, seq, timeline_frame); } static bool seq_edit_split_effect_intersect_check(const Scene *scene, @@ -326,8 +336,7 @@ static void seq_edit_split_handle_strip_offsets(Main *bmain, SEQ_time_left_handle_frame_set(scene, right_seq, timeline_frame); break; case SEQ_SPLIT_HARD: - seq_split_set_left_hold_offset(scene, right_seq, timeline_frame); - SEQ_add_reload_new_file(bmain, scene, right_seq, false); + seq_split_set_left_hold_offset(bmain, scene, right_seq, timeline_frame); break; } } @@ -338,8 +347,7 @@ static void seq_edit_split_handle_strip_offsets(Main *bmain, SEQ_time_right_handle_frame_set(scene, left_seq, timeline_frame); break; case SEQ_SPLIT_HARD: - seq_split_set_right_hold_offset(scene, left_seq, timeline_frame); - SEQ_add_reload_new_file(bmain, scene, left_seq, false); + seq_split_set_right_hold_offset(bmain, scene, left_seq, timeline_frame); break; } } diff --git a/source/blender/sequencer/intern/strip_time.c b/source/blender/sequencer/intern/strip_time.c index 0b480b22e91..7ef3f0f5a47 100644 --- a/source/blender/sequencer/intern/strip_time.c +++ b/source/blender/sequencer/intern/strip_time.c @@ -31,7 +31,7 @@ #include "strip_time.h" #include "utils.h" -static float seq_time_media_playback_rate_factor_get(const Scene *scene, const Sequence *seq) +float seq_time_media_playback_rate_factor_get(const Scene *scene, const Sequence *seq) { if ((seq->flag & SEQ_AUTO_PLAYBACK_RATE) == 0) { return 1.0f; @@ -44,7 +44,7 @@ static float seq_time_media_playback_rate_factor_get(const Scene *scene, const S return seq->media_playback_rate / scene_playback_rate; } -static float seq_time_playback_rate_factor_get(const Scene *scene, const Sequence *seq) +float seq_time_playback_rate_factor_get(const Scene *scene, const Sequence *seq) { return seq_time_media_playback_rate_factor_get(scene, seq) * seq->speed_factor; } diff --git a/source/blender/sequencer/intern/strip_time.h b/source/blender/sequencer/intern/strip_time.h index 19f549924df..c8946c47710 100644 --- a/source/blender/sequencer/intern/strip_time.h +++ b/source/blender/sequencer/intern/strip_time.h @@ -41,6 +41,9 @@ void seq_time_gap_info_get(const struct Scene *scene, void seq_time_effect_range_set(const struct Scene *scene, Sequence *seq); void seq_time_update_effects_strip_range(const struct Scene *scene, struct SeqCollection *effects); void seq_time_translate_handles(const struct Scene *scene, struct Sequence *seq, const int offset); +float seq_time_media_playback_rate_factor_get(const struct Scene *scene, + const struct Sequence *seq); +float seq_time_playback_rate_factor_get(const struct Scene *scene, const struct Sequence *seq); #ifdef __cplusplus } From 3b476d020aba99309549011308ebfee4e7712129 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 9 Jan 2023 12:58:16 -0500 Subject: [PATCH 0538/1522] Cleanup: Move particle.c to C++ In order to simplify a mesh data structure refactor. See T103343 --- source/blender/blenkernel/BKE_particle.h | 4 +- source/blender/blenkernel/CMakeLists.txt | 2 +- .../intern/{particle.c => particle.cc} | 604 +++++++++--------- 3 files changed, 315 insertions(+), 295 deletions(-) rename source/blender/blenkernel/intern/{particle.c => particle.cc} (90%) diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 618e69b5436..7dfbf3c5cc5 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -267,7 +267,7 @@ BLI_INLINE void psys_frand_vec(ParticleSystem *psys, unsigned int seed, float ve } /* ----------- functions needed outside particlesystem ---------------- */ -/* particle.c */ +/* particle.cc */ /* Few helpers for count-all etc. */ @@ -540,7 +540,7 @@ void BKE_particlesystem_reset_all(struct Object *object); /* ----------- functions needed only inside particlesystem ------------ */ -/* particle.c */ +/* particle.cc */ void psys_disable_all(struct Object *ob); void psys_enable_all(struct Object *ob); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 101baf1e983..7e11481b9c8 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -244,7 +244,7 @@ set(SRC intern/paint.cc intern/paint_canvas.cc intern/paint_toolslots.c - intern/particle.c + intern/particle.cc intern/particle_child.c intern/particle_distribute.c intern/particle_system.c diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.cc similarity index 90% rename from source/blender/blenkernel/intern/particle.c rename to source/blender/blenkernel/intern/particle.cc index f9abe7de830..0b1d8606807 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.cc @@ -8,9 +8,9 @@ /* Allow using deprecated functionality for .blend file I/O. */ #define DNA_DEPRECATED_ALLOW -#include -#include -#include +#include +#include +#include #include "MEM_guardedalloc.h" @@ -87,24 +87,25 @@ static void particle_settings_init(ID *id) MEMCPY_STRUCT_AFTER(particle_settings, DNA_struct_default_get(ParticleSettings), id); - particle_settings->effector_weights = BKE_effector_add_weights(NULL); + particle_settings->effector_weights = BKE_effector_add_weights(nullptr); particle_settings->pd = BKE_partdeflect_new(PFIELD_NULL); particle_settings->pd2 = BKE_partdeflect_new(PFIELD_NULL); } -static void particle_settings_copy_data(Main *UNUSED(bmain), +static void particle_settings_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, - const int UNUSED(flag)) + const int /*flag*/) { ParticleSettings *particle_settings_dst = (ParticleSettings *)id_dst; const ParticleSettings *partticle_settings_src = (const ParticleSettings *)id_src; particle_settings_dst->pd = BKE_partdeflect_copy(partticle_settings_src->pd); particle_settings_dst->pd2 = BKE_partdeflect_copy(partticle_settings_src->pd2); - particle_settings_dst->effector_weights = MEM_dupallocN( - partticle_settings_src->effector_weights); - particle_settings_dst->fluid = MEM_dupallocN(partticle_settings_src->fluid); + particle_settings_dst->effector_weights = static_cast( + MEM_dupallocN(partticle_settings_src->effector_weights)); + particle_settings_dst->fluid = static_cast( + MEM_dupallocN(partticle_settings_src->fluid)); if (partticle_settings_src->clumpcurve) { particle_settings_dst->clumpcurve = BKE_curvemapping_copy(partticle_settings_src->clumpcurve); @@ -120,7 +121,8 @@ static void particle_settings_copy_data(Main *UNUSED(bmain), for (int a = 0; a < MAX_MTEX; a++) { if (partticle_settings_src->mtex[a]) { - particle_settings_dst->mtex[a] = MEM_dupallocN(partticle_settings_src->mtex[a]); + particle_settings_dst->mtex[a] = static_cast( + MEM_dupallocN(partticle_settings_src->mtex[a])); } } @@ -266,10 +268,10 @@ static void particle_settings_blend_write(BlendWriter *writer, ID *id, const voi } LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) { - /* update indices, but only if dw->ob is set (can be NULL after loading e.g.) */ - if (dw->ob != NULL) { + /* update indices, but only if dw->ob is set (can be nullptr after loading e.g.) */ + if (dw->ob != nullptr) { dw->index = 0; - if (part->instance_collection) { /* can be NULL if lining fails or set to None */ + if (part->instance_collection) { /* can be nullptr if lining fails or set to None */ FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (part->instance_collection, object) { if (object == dw->ob) { break; @@ -300,10 +302,10 @@ static void particle_settings_blend_write(BlendWriter *writer, ID *id, const voi } } -void BKE_particle_partdeflect_blend_read_data(BlendDataReader *UNUSED(reader), PartDeflect *pd) +void BKE_particle_partdeflect_blend_read_data(BlendDataReader * /*reader*/, PartDeflect *pd) { if (pd) { - pd->rng = NULL; + pd->rng = nullptr; } } @@ -479,33 +481,33 @@ static void particle_settings_blend_read_expand(BlendExpander *expander, ID *id) } IDTypeInfo IDType_ID_PA = { - .id_code = ID_PA, - .id_filter = FILTER_ID_PA, - .main_listbase_index = INDEX_ID_PA, - .struct_size = sizeof(ParticleSettings), - .name = "ParticleSettings", - .name_plural = "particles", - .translation_context = BLT_I18NCONTEXT_ID_PARTICLESETTINGS, - .flags = 0, - .asset_type_info = NULL, + /*id_code*/ ID_PA, + /*id_filter*/ FILTER_ID_PA, + /*main_listbase_index*/ INDEX_ID_PA, + /*struct_size*/ sizeof(ParticleSettings), + /*name*/ "ParticleSettings", + /*name_plural*/ "particles", + /*translation_context*/ BLT_I18NCONTEXT_ID_PARTICLESETTINGS, + /*flags*/ 0, + /*asset_type_info*/ nullptr, - .init_data = particle_settings_init, - .copy_data = particle_settings_copy_data, - .free_data = particle_settings_free_data, - .make_local = NULL, - .foreach_id = particle_settings_foreach_id, - .foreach_cache = NULL, - .foreach_path = NULL, - .owner_pointer_get = NULL, + /*init_data*/ particle_settings_init, + /*copy_data*/ particle_settings_copy_data, + /*free_data*/ particle_settings_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ particle_settings_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ nullptr, + /*owner_pointer_get*/ nullptr, - .blend_write = particle_settings_blend_write, - .blend_read_data = particle_settings_blend_read_data, - .blend_read_lib = particle_settings_blend_read_lib, - .blend_read_expand = particle_settings_blend_read_expand, + /*blend_write*/ particle_settings_blend_write, + /*blend_read_data*/ particle_settings_blend_read_data, + /*blend_read_lib*/ particle_settings_blend_read_lib, + /*blend_read_expand*/ particle_settings_blend_read_expand, - .blend_read_undo_preserve = NULL, + /*blend_read_undo_preserve*/ nullptr, - .lib_override_apply_post = NULL, + /*lib_override_apply_post*/ nullptr, }; uint PSYS_FRAND_SEED_OFFSET[PSYS_FRAND_COUNT]; @@ -597,11 +599,11 @@ static ParticleCacheKey **psys_alloc_path_cache_buffers(ListBase *bufs, int tot, tot = MAX2(tot, 1); totkey = 0; - cache = MEM_callocN(tot * sizeof(void *), "PathCacheArray"); + cache = static_cast(MEM_callocN(tot * sizeof(void *), "PathCacheArray")); while (totkey < tot) { totbufkey = MIN2(tot - totkey, PATH_CACHE_BUF_SIZE); - buf = MEM_callocN(sizeof(LinkData), "PathCacheLinkData"); + buf = static_cast(MEM_callocN(sizeof(LinkData), "PathCacheLinkData")); buf->data = MEM_callocN(sizeof(ParticleCacheKey) * totbufkey * totkeys, "ParticleCacheKey"); for (i = 0; i < totbufkey; i++) { @@ -623,7 +625,7 @@ static void psys_free_path_cache_buffers(ParticleCacheKey **cache, ListBase *buf MEM_freeN(cache); } - for (buf = bufs->first; buf; buf = buf->next) { + for (buf = static_cast(bufs->first); buf; buf = buf->next) { MEM_freeN(buf->data); } BLI_freelistN(bufs); @@ -636,28 +638,29 @@ static void psys_free_path_cache_buffers(ParticleCacheKey **cache, ListBase *buf ParticleSystem *psys_get_current(Object *ob) { ParticleSystem *psys; - if (ob == NULL) { - return NULL; + if (ob == nullptr) { + return nullptr; } - for (psys = ob->particlesystem.first; psys; psys = psys->next) { + for (psys = static_cast(ob->particlesystem.first); psys; psys = psys->next) { if (psys->flag & PSYS_CURRENT) { return psys; } } - return NULL; + return nullptr; } short psys_get_current_num(Object *ob) { ParticleSystem *psys; short i; - if (ob == NULL) { + if (ob == nullptr) { return 0; } - for (psys = ob->particlesystem.first, i = 0; psys; psys = psys->next, i++) { + for (psys = static_cast(ob->particlesystem.first), i = 0; psys; + psys = psys->next, i++) { if (psys->flag & PSYS_CURRENT) { return i; } @@ -670,11 +673,12 @@ void psys_set_current_num(Object *ob, int index) ParticleSystem *psys; short i; - if (ob == NULL) { + if (ob == nullptr) { return; } - for (psys = ob->particlesystem.first, i = 0; psys; psys = psys->next, i++) { + for (psys = static_cast(ob->particlesystem.first), i = 0; psys; + psys = psys->next, i++) { if (i == index) { psys->flag |= PSYS_CURRENT; } @@ -690,9 +694,9 @@ void psys_sim_data_init(ParticleSimulationData *sim) ParticleSettings *part = psys->part; /* Prepare lattice deform. */ - psys->lattice_deform_data = NULL; + psys->lattice_deform_data = nullptr; if (psys_in_edit_mode(sim->depsgraph, sim->psys) == 0) { - Object *lattice = NULL; + Object *lattice = nullptr; ModifierData *md = (ModifierData *)psys_get_modifier(sim->ob, sim->psys); bool for_render = DEG_get_mode(sim->depsgraph) == DAG_EVAL_RENDER; int mode = for_render ? eModifierMode_Render : eModifierMode_Realtime; @@ -709,7 +713,7 @@ void psys_sim_data_init(ParticleSimulationData *sim) } } if (lattice) { - psys->lattice_deform_data = BKE_lattice_deform_data_create(lattice, NULL); + psys->lattice_deform_data = BKE_lattice_deform_data_create(lattice, nullptr); } } @@ -731,13 +735,13 @@ void psys_sim_data_free(ParticleSimulationData *sim) if (psys->lattice_deform_data) { BKE_lattice_deform_data_destroy(psys->lattice_deform_data); - psys->lattice_deform_data = NULL; + psys->lattice_deform_data = nullptr; } } void psys_disable_all(Object *ob) { - ParticleSystem *psys = ob->particlesystem.first; + ParticleSystem *psys = static_cast(ob->particlesystem.first); for (; psys; psys = psys->next) { psys->flag |= PSYS_DISABLED; @@ -745,7 +749,7 @@ void psys_disable_all(Object *ob) } void psys_enable_all(Object *ob) { - ParticleSystem *psys = ob->particlesystem.first; + ParticleSystem *psys = static_cast(ob->particlesystem.first); for (; psys; psys = psys->next) { psys->flag &= ~PSYS_DISABLED; @@ -754,7 +758,7 @@ void psys_enable_all(Object *ob) ParticleSystem *psys_orig_get(ParticleSystem *psys) { - if (psys->orig_psys == NULL) { + if (psys->orig_psys == nullptr) { return psys; } return psys->orig_psys; @@ -766,8 +770,8 @@ struct ParticleSystem *psys_eval_get(Depsgraph *depsgraph, Object *object, Parti if (object_eval == object) { return psys; } - ParticleSystem *psys_eval = object_eval->particlesystem.first; - while (psys_eval != NULL) { + ParticleSystem *psys_eval = static_cast(object_eval->particlesystem.first); + while (psys_eval != nullptr) { if (psys_eval->orig_psys == psys) { return psys_eval; } @@ -778,7 +782,7 @@ struct ParticleSystem *psys_eval_get(Depsgraph *depsgraph, Object *object, Parti static PTCacheEdit *psys_orig_edit_get(ParticleSystem *psys) { - if (psys->orig_psys == NULL) { + if (psys->orig_psys == nullptr) { return psys->edit; } return psys->orig_psys->edit; @@ -790,7 +794,7 @@ bool psys_in_edit_mode(Depsgraph *depsgraph, const ParticleSystem *psys) ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph); BKE_view_layer_synced_ensure(scene, view_layer); const Object *object = BKE_view_layer_active_object_get(view_layer); - if (object == NULL) { + if (object == nullptr) { /* TODO(sergey): Needs double-check with multi-object edit. */ return false; } @@ -842,16 +846,16 @@ void psys_find_group_weights(ParticleSettings *part) /* Find object pointers based on index. If the collection is linked from * another library linking may not have the object pointers available on * file load, so we have to retrieve them later. See T49273. */ - ListBase instance_collection_objects = {NULL, NULL}; + ListBase instance_collection_objects = {nullptr, nullptr}; if (part->instance_collection) { instance_collection_objects = BKE_collection_object_cache_get(part->instance_collection); } LISTBASE_FOREACH (ParticleDupliWeight *, dw, &part->instance_weights) { - if (dw->ob == NULL) { - Base *base = BLI_findlink(&instance_collection_objects, dw->index); - if (base != NULL) { + if (dw->ob == nullptr) { + Base *base = static_cast(BLI_findlink(&instance_collection_objects, dw->index)); + if (base != nullptr) { dw->ob = base->object; } } @@ -870,10 +874,10 @@ void psys_check_group_weights(ParticleSettings *part) /* Find object pointers. */ psys_find_group_weights(part); - /* Remove NULL objects, that were removed from the collection. */ - dw = part->instance_weights.first; + /* Remove nullptr objects, that were removed from the collection. */ + dw = static_cast(part->instance_weights.first); while (dw) { - if (dw->ob == NULL || + if (dw->ob == nullptr || !BKE_collection_has_object_recursive(part->instance_collection, dw->ob)) { tdw = dw->next; BLI_freelinkN(&part->instance_weights, dw); @@ -887,13 +891,14 @@ void psys_check_group_weights(ParticleSettings *part) /* Add new objects in the collection. */ int index = 0; FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (part->instance_collection, object) { - dw = part->instance_weights.first; + dw = static_cast(part->instance_weights.first); while (dw && dw->ob != object) { dw = dw->next; } if (!dw) { - dw = MEM_callocN(sizeof(ParticleDupliWeight), "ParticleDupliWeight"); + dw = static_cast( + MEM_callocN(sizeof(ParticleDupliWeight), "ParticleDupliWeight")); dw->ob = object; dw->count = 1; BLI_addtail(&part->instance_weights, dw); @@ -905,7 +910,7 @@ void psys_check_group_weights(ParticleSettings *part) /* Ensure there is an element marked as current. */ int current = 0; - for (dw = part->instance_weights.first; dw; dw = dw->next) { + for (dw = static_cast(part->instance_weights.first); dw; dw = dw->next) { if (dw->flag & PART_DUPLIW_CURRENT) { current = 1; break; @@ -913,7 +918,7 @@ void psys_check_group_weights(ParticleSettings *part) } if (!current) { - dw = part->instance_weights.first; + dw = static_cast(part->instance_weights.first); if (dw) { dw->flag |= PART_DUPLIW_CURRENT; } @@ -952,7 +957,7 @@ void free_hair(Object *object, ParticleSystem *psys, int dynamics) if (psys->clmd) { if (dynamics) { BKE_modifier_free((ModifierData *)psys->clmd); - psys->clmd = NULL; + psys->clmd = nullptr; PTCacheID pid; BKE_ptcache_id_from_particles(&pid, object, psys); BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0); @@ -963,14 +968,14 @@ void free_hair(Object *object, ParticleSystem *psys, int dynamics) } if (psys->hair_in_mesh) { - BKE_id_free(NULL, psys->hair_in_mesh); + BKE_id_free(nullptr, psys->hair_in_mesh); } - psys->hair_in_mesh = NULL; + psys->hair_in_mesh = nullptr; if (psys->hair_out_mesh) { - BKE_id_free(NULL, psys->hair_out_mesh); + BKE_id_free(nullptr, psys->hair_out_mesh); } - psys->hair_out_mesh = NULL; + psys->hair_out_mesh = nullptr; } void free_keyed_keys(ParticleSystem *psys) { @@ -986,7 +991,7 @@ void free_keyed_keys(ParticleSystem *psys) LOOP_PARTICLES { if (pa->keys) { - pa->keys = NULL; + pa->keys = nullptr; pa->totkey = 0; } } @@ -995,19 +1000,19 @@ void free_keyed_keys(ParticleSystem *psys) static void free_child_path_cache(ParticleSystem *psys) { psys_free_path_cache_buffers(psys->childcache, &psys->childcachebufs); - psys->childcache = NULL; + psys->childcache = nullptr; psys->totchildcache = 0; } void psys_free_path_cache(ParticleSystem *psys, PTCacheEdit *edit) { if (edit) { psys_free_path_cache_buffers(edit->pathcache, &edit->pathcachebufs); - edit->pathcache = NULL; + edit->pathcache = nullptr; edit->totcached = 0; } if (psys) { psys_free_path_cache_buffers(psys->pathcache, &psys->pathcachebufs); - psys->pathcache = NULL; + psys->pathcache = nullptr; psys->totcached = 0; free_child_path_cache(psys); @@ -1017,7 +1022,7 @@ void psys_free_children(ParticleSystem *psys) { if (psys->child) { MEM_freeN(psys->child); - psys->child = NULL; + psys->child = nullptr; psys->totchild = 0; } @@ -1028,7 +1033,7 @@ void psys_free_particles(ParticleSystem *psys) PARTICLE_P; if (psys->particles) { - /* Even though psys->part should never be NULL, + /* Even though psys->part should never be nullptr, * this can happen as an exception during deletion. * See ID_REMAP_SKIP/FORCE/FLAG_NEVER_NULL_USAGE in BKE_library_remap. */ if (psys->part && psys->part->type == PART_HAIR) { @@ -1049,7 +1054,7 @@ void psys_free_particles(ParticleSystem *psys) } MEM_freeN(psys->particles); - psys->particles = NULL; + psys->particles = nullptr; psys->totpart = 0; } } @@ -1075,7 +1080,7 @@ void psys_free(Object *ob, ParticleSystem *psys) int nr = 0; ParticleSystem *tpsys; - psys_free_path_cache(psys, NULL); + psys_free_path_cache(psys, nullptr); /* NOTE: We pass dynamics=0 to free_hair() to prevent it from doing an * unneeded clear of the cache. But for historical reason that code path @@ -1089,7 +1094,7 @@ void psys_free(Object *ob, ParticleSystem *psys) * paths there is beyond me. */ free_hair(ob, psys, 0); - if (psys->clmd != NULL) { + if (psys->clmd != nullptr) { BKE_modifier_free((ModifierData *)psys->clmd); } @@ -1101,12 +1106,13 @@ void psys_free(Object *ob, ParticleSystem *psys) if (psys->child) { MEM_freeN(psys->child); - psys->child = NULL; + psys->child = nullptr; psys->totchild = 0; } /* check if we are last non-visible particle system */ - for (tpsys = ob->particlesystem.first; tpsys; tpsys = tpsys->next) { + for (tpsys = static_cast(ob->particlesystem.first); tpsys; + tpsys = tpsys->next) { if (tpsys->part) { if (ELEM(tpsys->part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) { nr++; @@ -1119,12 +1125,12 @@ void psys_free(Object *ob, ParticleSystem *psys) ob->transflag &= ~OB_DUPLIPARTS; } - psys->part = NULL; + psys->part = nullptr; if ((psys->flag & PSYS_SHARED_CACHES) == 0) { BKE_ptcache_free_list(&psys->ptcaches); } - psys->pointcache = NULL; + psys->pointcache = nullptr; BLI_freelistN(&psys->targets); @@ -1161,8 +1167,8 @@ void psys_copy_particles(ParticleSystem *psys_dst, ParticleSystem *psys_src) psys_dst->totpart = psys_src->totpart; psys_dst->totchild = psys_src->totchild; /* Copy particles and children. */ - psys_dst->particles = MEM_dupallocN(psys_src->particles); - psys_dst->child = MEM_dupallocN(psys_src->child); + psys_dst->particles = static_cast(MEM_dupallocN(psys_src->particles)); + psys_dst->child = static_cast(MEM_dupallocN(psys_src->child)); /* Ideally this should only be performed if `(psys_dst->part->type == PART_HAIR)`. * @@ -1175,19 +1181,19 @@ void psys_copy_particles(ParticleSystem *psys_dst, ParticleSystem *psys_src) * data, which should still be preserved in case the missing particle settings ID becomes valid * again. * - * Furthermore, #free_hair() always frees `pa->hair` if it's not NULL, regardless of the + * Furthermore, #free_hair() always frees `pa->hair` if it's not nullptr, regardless of the * particle type. So *not* copying here would cause a double free (or more), e.g. freeing the * copy-on-write copy and the original data will crash Blender. * In any case, sharing pointers between `psys_src` and `psys_dst` should be forbidden. * - * So while we could in theory 'sanitize' the situation by setting `pa->hair` to NULL in the new - * copy (in case of non-`PART_HAIR` type), it is probably safer for now to systematically + * So while we could in theory 'sanitize' the situation by setting `pa->hair` to nullptr in the + * new copy (in case of non-`PART_HAIR` type), it is probably safer for now to systematically * duplicate the `hair` data if available. */ { ParticleData *pa; int p; for (p = 0, pa = psys_dst->particles; p < psys_dst->totpart; p++, pa++) { - pa->hair = MEM_dupallocN(pa->hair); + pa->hair = static_cast(MEM_dupallocN(pa->hair)); } } if (psys_dst->particles && (psys_dst->particles->keys || psys_dst->particles->boid)) { @@ -1195,17 +1201,17 @@ void psys_copy_particles(ParticleSystem *psys_dst, ParticleSystem *psys_src) BoidParticle *boid = psys_dst->particles->boid; ParticleData *pa; int p; - if (key != NULL) { - key = MEM_dupallocN(key); + if (key != nullptr) { + key = static_cast(MEM_dupallocN(key)); } - if (boid != NULL) { - boid = MEM_dupallocN(boid); + if (boid != nullptr) { + boid = static_cast(MEM_dupallocN(boid)); } for (p = 0, pa = psys_dst->particles; p < psys_dst->totpart; p++, pa++) { - if (boid != NULL) { + if (boid != nullptr) { pa->boid = boid++; } - if (key != NULL) { + if (key != nullptr) { pa->keys = key; key += pa->totkey; } @@ -1288,7 +1294,7 @@ typedef struct ParticleInterpolationData { * It uses #ParticleInterpolationData.pm to store the current memory cache frame * so it's thread safe. */ -static void get_pointcache_keys_for_time(Object *UNUSED(ob), +static void get_pointcache_keys_for_time(Object * /*ob*/, PointCache *cache, PTCacheMem **cur, int index, @@ -1296,11 +1302,11 @@ static void get_pointcache_keys_for_time(Object *UNUSED(ob), ParticleKey *key1, ParticleKey *key2) { - static PTCacheMem *pm = NULL; + static PTCacheMem *pm = nullptr; int index1, index2; if (index < 0) { /* initialize */ - *cur = cache->mem_cache.first; + *cur = static_cast(cache->mem_cache.first); if (*cur) { *cur = (*cur)->next; @@ -1308,7 +1314,7 @@ static void get_pointcache_keys_for_time(Object *UNUSED(ob), } else { if (*cur) { - while (*cur && (*cur)->next && (float)(*cur)->frame < t) { + while (*cur && (*cur)->next && float((*cur)->frame) < t) { *cur = (*cur)->next; } @@ -1320,21 +1326,21 @@ static void get_pointcache_keys_for_time(Object *UNUSED(ob), return; } - BKE_ptcache_make_particle_key(key2, index2, pm->data, (float)pm->frame); + BKE_ptcache_make_particle_key(key2, index2, pm->data, float(pm->frame)); if (index1 < 0) { copy_particle_key(key1, key2, 1); } else { - BKE_ptcache_make_particle_key(key1, index1, pm->prev->data, (float)pm->prev->frame); + BKE_ptcache_make_particle_key(key1, index1, pm->prev->data, float(pm->prev->frame)); } } else if (cache->mem_cache.first) { - pm = cache->mem_cache.first; + pm = static_cast(cache->mem_cache.first); index2 = BKE_ptcache_mem_index_find(pm, index); if (index2 < 0) { return; } - BKE_ptcache_make_particle_key(key2, index2, pm->data, (float)pm->frame); + BKE_ptcache_make_particle_key(key2, index2, pm->data, float(pm->frame)); copy_particle_key(key1, key2, 1); } } @@ -1347,7 +1353,7 @@ static int get_pointcache_times_for_particle(PointCache *cache, PTCacheMem *pm; int ret = 0; - for (pm = cache->mem_cache.first; pm; pm = pm->next) { + for (pm = static_cast(cache->mem_cache.first); pm; pm = pm->next) { if (BKE_ptcache_mem_index_find(pm, index) >= 0) { *r_start = pm->frame; ret++; @@ -1355,7 +1361,7 @@ static int get_pointcache_times_for_particle(PointCache *cache, } } - for (pm = cache->mem_cache.last; pm; pm = pm->prev) { + for (pm = static_cast(cache->mem_cache.last); pm; pm = pm->prev) { if (BKE_ptcache_mem_index_find(pm, index) >= 0) { /* Die *after* the last available frame. */ *r_dietime = pm->frame + 1; @@ -1372,7 +1378,7 @@ float psys_get_dietime_from_cache(PointCache *cache, int index) PTCacheMem *pm; int dietime = 10000000; /* some max value so that we can default to pa->time+lifetime */ - for (pm = cache->mem_cache.last; pm; pm = pm->prev) { + for (pm = static_cast(cache->mem_cache.last); pm; pm = pm->prev) { if (BKE_ptcache_mem_index_find(pm, index) >= 0) { /* Die *after* the last available frame. */ dietime = pm->frame + 1; @@ -1380,7 +1386,7 @@ float psys_get_dietime_from_cache(PointCache *cache, int index) } } - return (float)dietime; + return float(dietime); } static void init_particle_interpolation(Object *ob, @@ -1393,7 +1399,7 @@ static void init_particle_interpolation(Object *ob, PTCacheEditPoint *point = pind->epoint; pind->ekey[0] = point->keys; - pind->ekey[1] = point->totkey > 1 ? point->keys + 1 : NULL; + pind->ekey[1] = point->totkey > 1 ? point->keys + 1 : nullptr; pind->birthtime = *(point->keys->time); pind->dietime = *((point->keys + point->totkey - 1)->time); @@ -1401,14 +1407,14 @@ static void init_particle_interpolation(Object *ob, else if (pind->keyed) { ParticleKey *key = pa->keys; pind->kkey[0] = key; - pind->kkey[1] = pa->totkey > 1 ? key + 1 : NULL; + pind->kkey[1] = pa->totkey > 1 ? key + 1 : nullptr; pind->birthtime = key->time; pind->dietime = (key + pa->totkey - 1)->time; } else if (pind->cache) { float start = 0.0f, dietime = 0.0f; - get_pointcache_keys_for_time(ob, pind->cache, &pind->pm, -1, 0.0f, NULL, NULL); + get_pointcache_keys_for_time(ob, pind->cache, &pind->pm, -1, 0.0f, nullptr, nullptr); pind->birthtime = pa ? pa->time : pind->cache->startframe; pind->dietime = pa ? pa->dietime : (pind->cache->endframe + 1); @@ -1485,7 +1491,7 @@ static void do_particle_interpolation(ParticleSystem *psys, } else if (pind->keyed) { /* we have only one key, so let's use that */ - if (pind->kkey[1] == NULL) { + if (pind->kkey[1] == nullptr) { copy_particle_key(result, pind->kkey[0], 1); return; } @@ -1499,7 +1505,7 @@ static void do_particle_interpolation(ParticleSystem *psys, } if (psys->part->phystype == PART_PHYS_KEYED && psys->flag & PSYS_KEYED_TIMING) { - ParticleTarget *pt = psys->targets.first; + ParticleTarget *pt = static_cast(psys->targets.first); pt = pt->next; @@ -1567,7 +1573,7 @@ static void do_particle_interpolation(ParticleSystem *psys, memcpy(keys + 2, pind->kkey[1], sizeof(ParticleKey)); } else if (pind->cache) { - get_pointcache_keys_for_time(NULL, pind->cache, &pind->pm, p, real_t, keys + 1, keys + 2); + get_pointcache_keys_for_time(nullptr, pind->cache, &pind->pm, p, real_t, keys + 1, keys + 2); } else { hair_to_particle(keys + 1, pind->hkey[0]); @@ -1855,16 +1861,16 @@ void psys_interpolate_mcol(const MCol *mcol, int quad, const float w[4], MCol *m if (quad) { cp4 = (char *)&mcol[3]; - cp[0] = (int)(w[0] * cp1[0] + w[1] * cp2[0] + w[2] * cp3[0] + w[3] * cp4[0]); - cp[1] = (int)(w[0] * cp1[1] + w[1] * cp2[1] + w[2] * cp3[1] + w[3] * cp4[1]); - cp[2] = (int)(w[0] * cp1[2] + w[1] * cp2[2] + w[2] * cp3[2] + w[3] * cp4[2]); - cp[3] = (int)(w[0] * cp1[3] + w[1] * cp2[3] + w[2] * cp3[3] + w[3] * cp4[3]); + cp[0] = int(w[0] * cp1[0] + w[1] * cp2[0] + w[2] * cp3[0] + w[3] * cp4[0]); + cp[1] = int(w[0] * cp1[1] + w[1] * cp2[1] + w[2] * cp3[1] + w[3] * cp4[1]); + cp[2] = int(w[0] * cp1[2] + w[1] * cp2[2] + w[2] * cp3[2] + w[3] * cp4[2]); + cp[3] = int(w[0] * cp1[3] + w[1] * cp2[3] + w[2] * cp3[3] + w[3] * cp4[3]); } else { - cp[0] = (int)(w[0] * cp1[0] + w[1] * cp2[0] + w[2] * cp3[0]); - cp[1] = (int)(w[0] * cp1[1] + w[1] * cp2[1] + w[2] * cp3[1]); - cp[2] = (int)(w[0] * cp1[2] + w[1] * cp2[2] + w[2] * cp3[2]); - cp[3] = (int)(w[0] * cp1[3] + w[1] * cp2[3] + w[2] * cp3[3]); + cp[0] = int(w[0] * cp1[0] + w[1] * cp2[0] + w[2] * cp3[0]); + cp[1] = int(w[0] * cp1[1] + w[1] * cp2[1] + w[2] * cp3[1]); + cp[2] = int(w[0] * cp1[2] + w[1] * cp2[2] + w[2] * cp3[2]); + cp[3] = int(w[0] * cp1[3] + w[1] * cp2[3] + w[2] * cp3[3]); } } @@ -1880,7 +1886,7 @@ static float psys_interpolate_value_from_verts( return values[index]; case PART_FROM_FACE: case PART_FROM_VOLUME: { - MFace *mfaces = CustomData_get_layer(&mesh->fdata, CD_MFACE); + MFace *mfaces = static_cast(CustomData_get_layer(&mesh->fdata, CD_MFACE)); MFace *mf = &mfaces[index]; return interpolate_particle_value( values[mf->v1], values[mf->v2], values[mf->v3], values[mf->v4], fw, mf->v4); @@ -1938,9 +1944,9 @@ int psys_particle_dm_face_lookup(Mesh *mesh_final, float uv[2]; const float(*faceuv)[2]; - const int *index_mf_to_mpoly_deformed = NULL; - const int *index_mf_to_mpoly = NULL; - const int *index_mp_to_orig = NULL; + const int *index_mf_to_mpoly_deformed = nullptr; + const int *index_mf_to_mpoly = nullptr; + const int *index_mp_to_orig = nullptr; const int totface_final = mesh_final->totface; const int totface_deformed = mesh_original ? mesh_original->totface : totface_final; @@ -1949,12 +1955,15 @@ int psys_particle_dm_face_lookup(Mesh *mesh_final, return DMCACHE_NOTFOUND; } - index_mf_to_mpoly = CustomData_get_layer(&mesh_final->fdata, CD_ORIGINDEX); - index_mp_to_orig = CustomData_get_layer(&mesh_final->pdata, CD_ORIGINDEX); + index_mf_to_mpoly = static_cast( + CustomData_get_layer(&mesh_final->fdata, CD_ORIGINDEX)); + index_mp_to_orig = static_cast( + CustomData_get_layer(&mesh_final->pdata, CD_ORIGINDEX)); BLI_assert(index_mf_to_mpoly); if (mesh_original) { - index_mf_to_mpoly_deformed = CustomData_get_layer(&mesh_original->fdata, CD_ORIGINDEX); + index_mf_to_mpoly_deformed = static_cast( + CustomData_get_layer(&mesh_original->fdata, CD_ORIGINDEX)); } else { BLI_assert(BKE_mesh_is_deformed_only(mesh_final)); @@ -1964,16 +1973,17 @@ int psys_particle_dm_face_lookup(Mesh *mesh_final, pindex_orig = index_mf_to_mpoly_deformed[findex_orig]; - if (mesh_original == NULL) { + if (mesh_original == nullptr) { mesh_original = mesh_final; } - index_mf_to_mpoly_deformed = NULL; + index_mf_to_mpoly_deformed = nullptr; - mtessface_final = CustomData_get_layer(&mesh_final->fdata, CD_MFACE); - osface_final = CustomData_get_layer(&mesh_final->fdata, CD_ORIGSPACE); + mtessface_final = static_cast(CustomData_get_layer(&mesh_final->fdata, CD_MFACE)); + osface_final = static_cast( + CustomData_get_layer(&mesh_final->fdata, CD_ORIGSPACE)); - if (osface_final == NULL) { + if (osface_final == nullptr) { /* Assume we don't need osface_final data, and we get a direct 1-1 mapping... */ if (findex_orig < totface_final) { // printf("\tNO CD_ORIGSPACE, assuming not needed\n"); @@ -2039,7 +2049,7 @@ static int psys_map_index_on_dm(Mesh *mesh, int index, int index_dmcache, const float fw[4], - float UNUSED(foffset), + float /*foffset*/, int *mapindex, float mapfw[4]) { @@ -2089,11 +2099,13 @@ static int psys_map_index_on_dm(Mesh *mesh, /* modify the original weights to become * weights for the derived mesh face */ - OrigSpaceFace *osface = CustomData_get_layer(&mesh->fdata, CD_ORIGSPACE); - const MFace *mfaces = CustomData_get_layer(&mesh->fdata, CD_MFACE); + OrigSpaceFace *osface = static_cast( + CustomData_get_layer(&mesh->fdata, CD_ORIGSPACE)); + const MFace *mfaces = static_cast( + CustomData_get_layer(&mesh->fdata, CD_MFACE)); const MFace *mface = &mfaces[i]; - if (osface == NULL) { + if (osface == nullptr) { mapfw[0] = mapfw[1] = mapfw[2] = mapfw[3] = 0.0f; } else { @@ -2143,7 +2155,7 @@ void psys_particle_on_dm(Mesh *mesh_final, return; } - orcodata = CustomData_get_layer(&mesh_final->vdata, CD_ORCO); + orcodata = static_cast(CustomData_get_layer(&mesh_final->vdata, CD_ORCO)); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh_final); if (from == PART_FROM_VERT) { @@ -2174,10 +2186,10 @@ void psys_particle_on_dm(Mesh *mesh_final, MTFace *mtface; MVert *mvert; - MFace *mfaces = CustomData_get_layer(&mesh_final->fdata, CD_MFACE); + MFace *mfaces = static_cast(CustomData_get_layer(&mesh_final->fdata, CD_MFACE)); mface = &mfaces[mapindex]; mvert = BKE_mesh_verts_for_write(mesh_final); - mtface = CustomData_get_layer(&mesh_final->fdata, CD_MTFACE); + mtface = static_cast(CustomData_get_layer(&mesh_final->fdata, CD_MTFACE)); if (mtface) { mtface += mapindex; @@ -2241,7 +2253,7 @@ ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys) ModifierData *md; ParticleSystemModifierData *psmd; - for (md = ob->modifiers.first; md; md = md->next) { + for (md = static_cast(ob->modifiers.first); md; md = md->next) { if (md->type == eModifierType_ParticleSystem) { psmd = (ParticleSystemModifierData *)md; if (psmd->psys == psys) { @@ -2249,7 +2261,7 @@ ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys) } } } - return NULL; + return nullptr; } /************************************************/ @@ -2257,9 +2269,9 @@ ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys) /************************************************/ /* ready for future use */ -static void psys_particle_on_shape(int UNUSED(distr), - int UNUSED(index), - float *UNUSED(fuv), +static void psys_particle_on_shape(int /*distr*/, + int /*index*/, + float * /*fuv*/, float vec[3], float nor[3], float utan[3], @@ -2398,14 +2410,14 @@ void precalc_guides(ParticleSimulationData *sim, ListBase *effectors) pd_point_from_particle(sim, pa, &state, &point); - for (eff = effectors->first; eff; eff = eff->next) { + for (eff = static_cast(effectors->first); eff; eff = eff->next) { if (eff->pd->forcefield != PFIELD_GUIDE) { continue; } if (!eff->guide_data) { - eff->guide_data = MEM_callocN(sizeof(GuideEffectorData) * psys->totpart, - "GuideEffectorData"); + eff->guide_data = static_cast( + MEM_callocN(sizeof(GuideEffectorData) * psys->totpart, "GuideEffectorData")); } data = eff->guide_data + p; @@ -2428,9 +2440,9 @@ bool do_guides(Depsgraph *depsgraph, float time) { CurveMapping *clumpcurve = (part->child_flag & PART_CHILD_USE_CLUMP_CURVE) ? part->clumpcurve : - NULL; + nullptr; CurveMapping *roughcurve = (part->child_flag & PART_CHILD_USE_ROUGH_CURVE) ? part->roughcurve : - NULL; + nullptr; EffectorCache *eff; PartDeflect *pd; Curve *cu; @@ -2442,7 +2454,7 @@ bool do_guides(Depsgraph *depsgraph, float vec_to_point[3]; if (effectors) { - for (eff = effectors->first; eff; eff = eff->next) { + for (eff = static_cast(effectors->first); eff; eff = eff->next) { pd = eff->pd; if (pd->forcefield != PFIELD_GUIDE) { @@ -2464,14 +2476,18 @@ bool do_guides(Depsgraph *depsgraph, cu = (Curve *)eff->ob->data; if (pd->flag & PFIELD_GUIDE_PATH_ADD) { - if (BKE_where_on_path( - eff->ob, data->strength * guidetime, guidevec, guidedir, NULL, &radius, &weight) == - 0) { + if (BKE_where_on_path(eff->ob, + data->strength * guidetime, + guidevec, + guidedir, + nullptr, + &radius, + &weight) == 0) { return 0; } } else { - if (BKE_where_on_path(eff->ob, guidetime, guidevec, guidedir, NULL, &radius, &weight) == + if (BKE_where_on_path(eff->ob, guidetime, guidevec, guidedir, nullptr, &radius, &weight) == 0) { return 0; } @@ -2503,7 +2519,7 @@ bool do_guides(Depsgraph *depsgraph, BKE_displist_calc_taper(depsgraph, eff->scene, cu->taperobj, - (int)(data->strength * guidetime * 100.0f), + int(data->strength * guidetime * 100.0f), 100)); } else { /* Curve size. */ @@ -2587,10 +2603,10 @@ static void do_path_effectors(ParticleSimulationData *sim, ParticleCacheKey *ca, int k, int steps, - float *UNUSED(rootco), + float * /*rootco*/, float effector, - float UNUSED(dfra), - float UNUSED(cfra), + float /*dfra*/, + float /*cfra*/, float *length, float *vec) { @@ -2613,12 +2629,12 @@ static void do_path_effectors(ParticleSimulationData *sim, sim->psys->part->effector_weights, &epoint, force, - NULL, - NULL); + nullptr, + nullptr); mul_v3_fl(force, - effector * powf((float)k / (float)steps, 100.0f * sim->psys->part->eff_hair) / - (float)steps); + effector * powf(float(k) / float(steps), 100.0f * sim->psys->part->eff_hair) / + float(steps)); add_v3_v3(force, vec); @@ -2669,7 +2685,7 @@ float *psys_cache_vgroup(Mesh *mesh, ParticleSystem *psys, int vgroup) const MDeformVert *dvert = BKE_mesh_deform_verts(mesh); if (dvert) { int totvert = mesh->totvert, i; - vg = MEM_callocN(sizeof(float) * totvert, "vg_cache"); + vg = static_cast(MEM_callocN(sizeof(float) * totvert, "vg_cache")); if (psys->vg_neg & (1 << vgroup)) { for (i = 0; i < totvert; i++) { vg[i] = 1.0f - BKE_defvert_find_weight(&dvert[i], psys->vgroup[vgroup] - 1); @@ -2694,10 +2710,10 @@ void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params int p, totparent, totchild = sim->psys->totchild; float co[3], orco[3]; int from = PART_FROM_FACE; - totparent = (int)(totchild * part->parents * 0.3f); + totparent = int(totchild * part->parents * 0.3f); if (use_render_params && part->child_percent && part->child_render_percent) { - totparent *= (float)part->child_percent / (float)part->child_render_percent; + totparent *= float(part->child_percent) / float(part->child_render_percent); } /* hard limit, workaround for it being ignored above */ @@ -2735,7 +2751,7 @@ void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params for (; p < totchild; p++, cpa++) { psys_particle_on_emitter( sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco); - cpa->parent = BLI_kdtree_3d_find_nearest(tree, orco, NULL); + cpa->parent = BLI_kdtree_3d_find_nearest(tree, orco, nullptr); } BLI_kdtree_3d_free(tree); @@ -2761,7 +2777,7 @@ static bool psys_thread_context_init_path(ParticleThreadContext *ctx, ParticleEditSettings *pset = &scene->toolsettings->particle; if ((use_render_params == 0) && - (psys_orig_edit_get(psys) == NULL || pset->flag & PE_DRAW_PART) == 0) { + (psys_orig_edit_get(psys) == nullptr || pset->flag & PE_DRAW_PART) == 0) { totchild = 0; } @@ -2769,10 +2785,10 @@ static bool psys_thread_context_init_path(ParticleThreadContext *ctx, } if (totchild && part->childtype == PART_CHILD_FACES) { - totparent = (int)(totchild * part->parents * 0.3f); + totparent = int(totchild * part->parents * 0.3f); if (use_render_params && part->child_percent && part->child_render_percent) { - totparent *= (float)part->child_percent / (float)part->child_render_percent; + totparent *= float(part->child_percent) / float(part->child_render_percent); } /* part->parents could still be 0 so we can't test with totparent */ @@ -2783,7 +2799,7 @@ static bool psys_thread_context_init_path(ParticleThreadContext *ctx, segments = 1 << part->ren_step; } else { - totchild = (int)((float)totchild * (float)part->disp / 100.0f); + totchild = int(float(totchild) * float(part->disp) / 100.0f); } totparent = MIN2(totparent, totchild); @@ -2827,21 +2843,21 @@ static bool psys_thread_context_init_path(ParticleThreadContext *ctx, BKE_curvemapping_changed_all(ctx->clumpcurve); } else { - ctx->clumpcurve = NULL; + ctx->clumpcurve = nullptr; } if ((part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && part->roughcurve) { ctx->roughcurve = BKE_curvemapping_copy(part->roughcurve); BKE_curvemapping_changed_all(ctx->roughcurve); } else { - ctx->roughcurve = NULL; + ctx->roughcurve = nullptr; } if ((part->child_flag & PART_CHILD_USE_TWIST_CURVE) && part->twistcurve) { ctx->twistcurve = BKE_curvemapping_copy(part->twistcurve); BKE_curvemapping_changed_all(ctx->twistcurve); } else { - ctx->twistcurve = NULL; + ctx->twistcurve = nullptr; } return true; @@ -3010,7 +3026,7 @@ static void psys_thread_create_path(ParticleTask *task, * ctx->sim.psmd->dm_final, * ctx->sim.psmd->dm_deformed, * pa->num, pa->fuv, - * NULL); + * nullptr); */ cpa_num = ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND) ? pa->num : pa->num_dmcache; @@ -3065,7 +3081,7 @@ static void psys_thread_create_path(ParticleTask *task, /* Fade the effect of rotation for even lengths in the end */ project_v3_v3v3(dvec, off2[w], (key[w] + k)->vel); - madd_v3_v3fl(off2[w], dvec, -(float)k / (float)ctx->segments); + madd_v3_v3fl(off2[w], dvec, -float(k) / float(ctx->segments)); } add_v3_v3(off2[w], (key[w] + k)->co); @@ -3099,7 +3115,7 @@ static void psys_thread_create_path(ParticleTask *task, part->childrad); } - child->time = (float)k / (float)ctx->segments; + child->time = float(k) / float(ctx->segments); } /* apply effectors */ @@ -3126,8 +3142,8 @@ static void psys_thread_create_path(ParticleTask *task, } { - ParticleData *pa = NULL; - ParticleCacheKey *par = NULL; + ParticleData *pa = nullptr; + ParticleCacheKey *par = nullptr; float par_co[3]; float par_orco[3]; @@ -3153,7 +3169,7 @@ static void psys_thread_create_path(ParticleTask *task, } if (pa->flag & PARS_UNEXIST) { - pa = NULL; + pa = nullptr; } } @@ -3168,9 +3184,9 @@ static void psys_thread_create_path(ParticleTask *task, pa->fuv, pa->foffset, par_co, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, par_orco); psys_apply_child_modifiers( @@ -3187,9 +3203,9 @@ static void psys_thread_create_path(ParticleTask *task, } } -static void exec_child_path_cache(TaskPool *__restrict UNUSED(pool), void *taskdata) +static void exec_child_path_cache(TaskPool *__restrict /*pool*/, void *taskdata) { - ParticleTask *task = taskdata; + ParticleTask *task = static_cast(taskdata); ParticleThreadContext *ctx = task->ctx; ParticleSystem *psys = ctx->sim.psys; ParticleCacheKey **cache = psys->childcache; @@ -3246,7 +3262,7 @@ void psys_cache_child_paths(ParticleSimulationData *sim, ParticleTask *task = &tasks_parent[i]; psys_task_init_path(task, sim); - BLI_task_pool_push(task_pool, exec_child_path_cache, task, false, NULL); + BLI_task_pool_push(task_pool, exec_child_path_cache, task, false, nullptr); } BLI_task_pool_work_and_wait(task_pool); @@ -3257,7 +3273,7 @@ void psys_cache_child_paths(ParticleSimulationData *sim, ParticleTask *task = &tasks_child[i]; psys_task_init_path(task, sim); - BLI_task_pool_push(task_pool, exec_child_path_cache, task, false, NULL); + BLI_task_pool_push(task_pool, exec_child_path_cache, task, false, nullptr); } BLI_task_pool_work_and_wait(task_pool); @@ -3321,7 +3337,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re Mesh *hair_mesh = (psys->part->type == PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS) ? psys->hair_out_mesh : - NULL; + nullptr; ParticleKey result; @@ -3333,16 +3349,15 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re float birthtime = 0.0, dietime = 0.0; float t, time = 0.0, dfra = 1.0; - // float frs_sec = sim->scene->r.frs_sec; /*UNUSED*/ float col[4] = {0.5f, 0.5f, 0.5f, 1.0f}; float prev_tangent[3] = {0.0f, 0.0f, 0.0f}, hairmat[4][4]; float rotmat[3][3]; int k; - int segments = (int)pow(2.0, (double)((use_render_params) ? part->ren_step : part->draw_step)); + int segments = int(pow(2.0, double((use_render_params) ? part->ren_step : part->draw_step))); int totpart = psys->totpart; float length, vec[3]; - float *vg_effector = NULL; - float *vg_length = NULL, pa_length = 1.0f; + float *vg_effector = nullptr; + float *vg_length = nullptr, pa_length = 1.0f; int keyed, baked; /* we don't have anything valid to create paths from so let's quit here */ @@ -3351,7 +3366,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re } if (psys_in_edit_mode(sim->depsgraph, psys)) { - if ((psys->edit == NULL || pset->flag & PE_DRAW_PART) == 0) { + if ((psys->edit == nullptr || pset->flag & PE_DRAW_PART) == 0) { return; } } @@ -3397,8 +3412,8 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re } pind.keyed = keyed; - pind.cache = baked ? psys->pointcache : NULL; - pind.epoint = NULL; + pind.cache = baked ? psys->pointcache : nullptr; + pind.epoint = nullptr; pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE); pind.mesh = hair_mesh; @@ -3434,7 +3449,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re /*--interpolate actual path from data points--*/ for (k = 0, ca = cache[p]; k <= segments; k++, ca++) { - time = (float)k / (float)segments; + time = float(k) / float(segments); t = birthtime + time * (dietime - birthtime); result.time = -t; do_particle_interpolation(psys, p, pa, t, &pind, &result); @@ -3489,7 +3504,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re sim->psys->effectors, (ParticleKey *)ca, p, - (float)k / (float)segments); + float(k) / float(segments)); } } @@ -3517,7 +3532,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re copy_v3_v3((ca - 1)->vel, ca->vel); } - ca->time = (float)k / (float)segments; + ca->time = float(k) / float(segments); } /* First rotation is based on emitting face orientation. * This is way better than having flipping rotations resulting @@ -3553,7 +3568,7 @@ typedef struct CacheEditrPathsIterData { static void psys_cache_edit_paths_iter(void *__restrict iter_data_v, const int iter, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { CacheEditrPathsIterData *iter_data = (CacheEditrPathsIterData *)iter_data_v; PTCacheEdit *edit = iter_data->edit; @@ -3568,7 +3583,7 @@ static void psys_cache_edit_paths_iter(void *__restrict iter_data_v, ParticleSystem *psys = edit->psys; ParticleCacheKey **cache = edit->pathcache; ParticleSystemModifierData *psmd = iter_data->psmd; - ParticleData *pa = iter_data->pa ? iter_data->pa + iter : NULL; + ParticleData *pa = iter_data->pa ? iter_data->pa + iter : nullptr; PTCacheEditKey *ekey = point->keys; const int segments = iter_data->segments; const bool use_weight = iter_data->use_weight; @@ -3578,15 +3593,15 @@ static void psys_cache_edit_paths_iter(void *__restrict iter_data_v, ParticleInterpolationData pind; pind.keyed = 0; - pind.cache = NULL; + pind.cache = nullptr; pind.epoint = point; pind.bspline = psys ? (psys->part->flag & PART_HAIR_BSPLINE) : 0; - pind.mesh = NULL; + pind.mesh = nullptr; /* should init_particle_interpolation set this ? */ if (use_weight) { - pind.hkey[0] = NULL; - /* pa != NULL since the weight brush is only available for hair */ + pind.hkey[0] = nullptr; + /* pa != nullptr since the weight brush is only available for hair */ pind.hkey[0] = pa->hair; pind.hkey[1] = pa->hair + 1; } @@ -3618,7 +3633,7 @@ static void psys_cache_edit_paths_iter(void *__restrict iter_data_v, int k; float t, time = 0.0f, keytime = 0.0f; for (k = 0, ca = cache[iter]; k <= segments; k++, ca++) { - time = (float)k / (float)segments; + time = float(k) / float(segments); t = birthtime + time * (dietime - birthtime); ParticleKey result; result.time = -t; @@ -3729,12 +3744,12 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, ParticleSystem *psys = edit->psys; - ParticleData *pa = psys ? psys->particles : NULL; + ParticleData *pa = psys ? psys->particles : nullptr; int segments = 1 << pset->draw_step; int totpart = edit->totpoint, recalc_set = 0; - if (edit->psmd_eval == NULL) { + if (edit->psmd_eval == nullptr) { return; } @@ -3754,8 +3769,8 @@ void psys_cache_edit_paths(Depsgraph *depsgraph, recalc_set = 1; } - const bool use_weight = (pset->brushtype == PE_BRUSH_WEIGHT) && (psys != NULL) && - (psys->particles != NULL); + const bool use_weight = (pset->brushtype == PE_BRUSH_WEIGHT) && (psys != nullptr) && + (psys->particles != nullptr); CacheEditrPathsIterData iter_data; iter_data.object = ob; @@ -3877,11 +3892,13 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4] return; } - MFace *mfaces = CustomData_get_layer(&mesh->fdata, CD_MFACE); + MFace *mfaces = static_cast(CustomData_get_layer(&mesh->fdata, CD_MFACE)); mface = &mfaces[i]; - const OrigSpaceFace *osface = CustomData_get(&mesh->fdata, i, CD_ORIGSPACE); + const OrigSpaceFace *osface = static_cast( + CustomData_get(&mesh->fdata, i, CD_ORIGSPACE)); - if (orco && (orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO))) { + if (orco && + (orcodata = static_cast(CustomData_get_layer(&mesh->vdata, CD_ORCO)))) { copy_v3_v3(v[0], orcodata[mface->v1]); copy_v3_v3(v[1], orcodata[mface->v2]); copy_v3_v3(v[2], orcodata[mface->v3]); @@ -3889,7 +3906,7 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4] /* ugly hack to use non-transformed orcos, since only those * give symmetric results for mirroring in particle mode */ if (CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX)) { - BKE_mesh_orco_verts_transform(ob->data, v, 3, 1); + BKE_mesh_orco_verts_transform(static_cast(ob->data), v, 3, 1); } } else { @@ -3899,11 +3916,11 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4] copy_v3_v3(v[2], verts[mface->v3].co); } - triatomat(v[0], v[1], v[2], (osface) ? osface->uv : NULL, mat); + triatomat(v[0], v[1], v[2], (osface) ? osface->uv : nullptr, mat); } void psys_mat_hair_to_object( - Object *UNUSED(ob), Mesh *mesh, short from, ParticleData *pa, float hairmat[4][4]) + Object * /*ob*/, Mesh *mesh, short from, ParticleData *pa, float hairmat[4][4]) { float vec[3]; @@ -3929,7 +3946,7 @@ void psys_mat_hair_to_orco( /* see psys_face_mat for why this function is called */ if (CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX)) { - BKE_mesh_orco_verts_transform(ob->data, &orco, 1, 1); + BKE_mesh_orco_verts_transform(static_cast(ob->data), &orco, 1, 1); } copy_v3_v3(hairmat[3], orco); } @@ -3965,24 +3982,24 @@ static ModifierData *object_add_or_copy_particle_system( ParticleSystemModifierData *psmd; if (!ob || ob->type != OB_MESH) { - return NULL; + return nullptr; } - if (name == NULL) { - name = (psys_orig != NULL) ? psys_orig->name : DATA_("ParticleSystem"); + if (name == nullptr) { + name = (psys_orig != nullptr) ? psys_orig->name : DATA_("ParticleSystem"); } - psys = ob->particlesystem.first; + psys = static_cast(ob->particlesystem.first); for (; psys; psys = psys->next) { psys->flag &= ~PSYS_CURRENT; } - psys = MEM_callocN(sizeof(ParticleSystem), "particle_system"); + psys = static_cast(MEM_callocN(sizeof(ParticleSystem), "particle_system")); psys->pointcache = BKE_ptcache_add(&psys->ptcaches); BLI_addtail(&ob->particlesystem, psys); psys_unique_name(ob, psys, name); - if (psys_orig != NULL) { + if (psys_orig != nullptr) { psys->part = psys_orig->part; id_us_plus(&psys->part->id); } @@ -4000,7 +4017,7 @@ static ModifierData *object_add_or_copy_particle_system( psys->totpart = 0; psys->flag = PSYS_CURRENT; - if (scene != NULL) { + if (scene != nullptr) { psys->cfra = BKE_scene_frame_to_ctime(scene, scene->r.cfra + 1); } @@ -4012,7 +4029,7 @@ static ModifierData *object_add_or_copy_particle_system( ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob, const char *name) { - return object_add_or_copy_particle_system(bmain, scene, ob, name, NULL); + return object_add_or_copy_particle_system(bmain, scene, ob, name, nullptr); } ModifierData *object_copy_particle_system(Main *bmain, @@ -4020,11 +4037,11 @@ ModifierData *object_copy_particle_system(Main *bmain, Object *ob, const ParticleSystem *psys_orig) { - return object_add_or_copy_particle_system(bmain, scene, ob, NULL, psys_orig); + return object_add_or_copy_particle_system(bmain, scene, ob, nullptr, psys_orig); } void object_remove_particle_system(Main *bmain, - Scene *UNUSED(scene), + Scene * /*scene*/, Object *ob, ParticleSystem *psys) { @@ -4042,7 +4059,7 @@ void object_remove_particle_system(Main *bmain, /* Clear particle system pointer in flow settings. */ if ((fmd->type == MOD_FLUID_TYPE_FLOW) && fmd->flow && fmd->flow->psys) { if (fmd->flow->psys == psys) { - fmd->flow->psys = NULL; + fmd->flow->psys = nullptr; } } /* Clear particle flag in domain settings when removing particle system manually. */ @@ -4090,7 +4107,7 @@ void object_remove_particle_system(Main *bmain, DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md; if (pmd->brush && pmd->brush->psys) { if (pmd->brush->psys == psys) { - pmd->brush->psys = NULL; + pmd->brush->psys = nullptr; } } } @@ -4127,7 +4144,7 @@ ParticleSettings *BKE_particlesettings_add(Main *bmain, const char *name) { ParticleSettings *part; - part = BKE_id_new(bmain, ID_PA, name); + part = static_cast(BKE_id_new(bmain, ID_PA, name)); return part; } @@ -4191,9 +4208,9 @@ static int get_particle_uv(Mesh *mesh, const MTFace *tf; int i; - tf = CustomData_get_layer_named(&mesh->fdata, CD_MTFACE, name); + tf = static_cast(CustomData_get_layer_named(&mesh->fdata, CD_MTFACE, name)); - if (tf == NULL) { + if (tf == nullptr) { return 0; } @@ -4316,7 +4333,7 @@ static void get_cpa_texture(Mesh *mesh, break; case TEXCO_UV: if (fw && get_particle_uv(mesh, - NULL, + nullptr, face_index, fw, mtex->uvname, @@ -4337,7 +4354,7 @@ static void get_cpa_texture(Mesh *mesh, break; } - RE_texture_evaluate(mtex, texvec, 0, NULL, false, false, &value, rgba); + RE_texture_evaluate(mtex, texvec, 0, nullptr, false, false, &value, rgba); if ((event & mtex->mapto) & PAMAP_ROUGH) { ptex->rough1 = ptex->rough2 = ptex->roughe = texture_value_blend( @@ -4378,7 +4395,7 @@ void psys_get_texture( ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f; ptex->twist = 1.0f; - ptex->time = (float)(pa - sim->psys->particles) / (float)sim->psys->totpart; + ptex->time = float(pa - sim->psys->particles) / float(sim->psys->totpart); for (m = 0; m < MAX_MTEX; m++, mtexp++) { mtex = *mtexp; @@ -4443,8 +4460,7 @@ void psys_get_texture( /* texture coordinates in range [-1, 1] */ texvec[0] = 2.0f * (cfra - pa->time) / (pa->dietime - pa->time) - 1.0f; if (sim->psys->totpart > 0) { - texvec[1] = 2.0f * (float)(pa - sim->psys->particles) / (float)sim->psys->totpart - - 1.0f; + texvec[1] = 2.0f * float(pa - sim->psys->particles) / float(sim->psys->totpart) - 1.0f; } else { texvec[1] = 0.0f; @@ -4453,7 +4469,7 @@ void psys_get_texture( break; } - RE_texture_evaluate(mtex, texvec, 0, NULL, false, false, &value, rgba); + RE_texture_evaluate(mtex, texvec, 0, nullptr, false, false, &value, rgba); if ((event & mtex->mapto) & PAMAP_TIME) { /* the first time has to set the base value for time regardless of blend mode */ @@ -4533,8 +4549,8 @@ float psys_get_child_time( } float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, - float UNUSED(cfra), - float *UNUSED(pa_time)) + float /*cfra*/, + float * /*pa_time*/) { ParticleSettings *part = psys->part; float size; /* time XXX */ @@ -4670,13 +4686,13 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, pa = psys->particles + p; pind.keyed = keyed; - pind.cache = cached ? psys->pointcache : NULL; - pind.epoint = NULL; + pind.cache = cached ? psys->pointcache : nullptr; + pind.epoint = nullptr; pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE); /* `pind.dm` disabled in edit-mode means we don't get effectors taken into * account when subdividing for instance. */ pind.mesh = psys_in_edit_mode(sim->depsgraph, psys) ? - NULL : + nullptr : psys->hair_out_mesh; /* XXX(@sybren): EEK. */ init_particle_interpolation(sim->ob, psys, pa, &pind); do_particle_interpolation(psys, p, pa, t, &pind, state); @@ -4722,7 +4738,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, cpa = psys->child + p - totpart; if (state->time < 0.0f) { - t = psys_get_child_time(psys, cpa, -state->time, NULL, NULL); + t = psys_get_child_time(psys, cpa, -state->time, nullptr, nullptr); } if (part->childtype == PART_CHILD_FACES) { @@ -4852,8 +4868,8 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, } /* apply different deformations to the child path */ - ParticleChildModifierContext modifier_ctx = {NULL}; - modifier_ctx.thread_ctx = NULL; + ParticleChildModifierContext modifier_ctx = {nullptr}; + modifier_ctx.thread_ctx = nullptr; modifier_ctx.sim = sim; modifier_ctx.ptex = &ptex; modifier_ctx.cpa = cpa; @@ -4862,7 +4878,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, modifier_ctx.par_vel = par->vel; modifier_ctx.par_rot = par->rot; modifier_ctx.par_orco = par_orco; - modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : NULL; + modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : nullptr; do_child_modifiers(&modifier_ctx, hairmat, state, t); /* try to estimate correct velocity */ @@ -4896,8 +4912,8 @@ bool psys_get_particle_state(ParticleSimulationData *sim, { ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; - ParticleData *pa = NULL; - ChildParticle *cpa = NULL; + ParticleData *pa = nullptr; + ChildParticle *cpa = nullptr; float cfra; int totpart = psys->totpart; float timestep = psys_get_timestep(sim); @@ -4917,7 +4933,7 @@ bool psys_get_particle_state(ParticleSimulationData *sim, cpa = psys->child + p - totpart; - state->time = psys_get_child_time(psys, cpa, cfra, NULL, NULL); + state->time = psys_get_child_time(psys, cpa, cfra, nullptr, nullptr); if (!always) { if ((state->time < 0.0f && !(part->flag & PART_UNBORN)) || @@ -4969,17 +4985,17 @@ bool psys_get_particle_state(ParticleSimulationData *sim, CLAMP(t, 0.0f, 1.0f); unit_m4(mat); - ParticleChildModifierContext modifier_ctx = {NULL}; - modifier_ctx.thread_ctx = NULL; + ParticleChildModifierContext modifier_ctx = {nullptr}; + modifier_ctx.thread_ctx = nullptr; modifier_ctx.sim = sim; - modifier_ctx.ptex = NULL; + modifier_ctx.ptex = nullptr; modifier_ctx.cpa = cpa; modifier_ctx.orco = cpa->fuv; modifier_ctx.par_co = key1->co; modifier_ctx.par_vel = key1->vel; modifier_ctx.par_rot = key1->rot; modifier_ctx.par_orco = par_orco; - modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : NULL; + modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : nullptr; do_child_modifiers(&modifier_ctx, mat, state, t); @@ -5068,7 +5084,7 @@ void psys_get_dupli_texture(ParticleSystem *psys, float loc[3]; int num; - /* XXX: on checking '(psmd->dm != NULL)' + /* XXX: on checking '(psmd->dm != nullptr)' * This is incorrect but needed for meta-ball evaluation. * Ideally this would be calculated via the depsgraph, however with meta-balls, * the entire scenes dupli's are scanned, which also looks into uncalculated data. @@ -5082,15 +5098,17 @@ void psys_get_dupli_texture(ParticleSystem *psys, bool is_grid = (part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT); if (cpa) { - if ((part->childtype == PART_CHILD_FACES) && (psmd->mesh_final != NULL)) { + if ((part->childtype == PART_CHILD_FACES) && (psmd->mesh_final != nullptr)) { if (!is_grid) { CustomData *mtf_data = &psmd->mesh_final->fdata; const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); if (uv_idx >= 0) { - const MTFace *mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); - if (mtface != NULL) { - const MFace *mface = CustomData_get(&psmd->mesh_final->fdata, cpa->num, CD_MFACE); + const MTFace *mtface = static_cast( + CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx)); + if (mtface != nullptr) { + const MFace *mface = static_cast( + CustomData_get(&psmd->mesh_final->fdata, cpa->num, CD_MFACE)); mtface += cpa->num; psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv); } @@ -5114,7 +5132,7 @@ void psys_get_dupli_texture(ParticleSystem *psys, pa = psys->particles + cpa->pa[0]; } - if ((part->from == PART_FROM_FACE) && (psmd->mesh_final != NULL) && !is_grid) { + if ((part->from == PART_FROM_FACE) && (psmd->mesh_final != nullptr) && !is_grid) { num = pa->num_dmcache; if (num == DMCACHE_NOTFOUND) { @@ -5132,8 +5150,10 @@ void psys_get_dupli_texture(ParticleSystem *psys, const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); if (uv_idx >= 0) { - const MTFace *mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); - const MFace *mface = CustomData_get(&psmd->mesh_final->fdata, num, CD_MFACE); + const MTFace *mtface = static_cast( + CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx)); + const MFace *mface = static_cast( + CustomData_get(&psmd->mesh_final->fdata, num, CD_MFACE)); mtface += num; psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv); } @@ -5160,7 +5180,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, sub_v3_v3v3(vec, (cache + cache->segments)->co, cache->co); len = normalize_v3(vec); - if (pa == NULL && psys->part->childflat != PART_CHILD_FACES) { + if (pa == nullptr && psys->part->childflat != PART_CHILD_FACES) { pa = psys->particles + cpa->pa[0]; } @@ -5219,7 +5239,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, if (psys->part->randphasefac != 0.0f) { phasefac += psys->part->randphasefac * psys_frand(psys, (pa - psys->particles) + 20); } - axis_angle_to_quat(q_phase, vec, phasefac * (float)M_PI); + axis_angle_to_quat(q_phase, vec, phasefac * float(M_PI)); mul_qt_v3(q_phase, side); } @@ -5276,8 +5296,8 @@ void psys_apply_hair_lattice(Depsgraph *depsgraph, Scene *scene, Object *ob, Par } /* Draw Engine */ -void (*BKE_particle_batch_cache_dirty_tag_cb)(ParticleSystem *psys, int mode) = NULL; -void (*BKE_particle_batch_cache_free_cb)(ParticleSystem *psys) = NULL; +void (*BKE_particle_batch_cache_dirty_tag_cb)(ParticleSystem *psys, int mode) = nullptr; +void (*BKE_particle_batch_cache_free_cb)(ParticleSystem *psys) = nullptr; void BKE_particle_batch_cache_dirty_tag(ParticleSystem *psys, int mode) { @@ -5352,7 +5372,7 @@ void BKE_particle_system_blend_read_data(BlendDataReader *reader, ListBase *part if (psys->particles && psys->particles->keys) { for (a = 0, pa = psys->particles; a < psys->totpart; a++, pa++) { - pa->keys = NULL; + pa->keys = nullptr; pa->totkey = 0; } @@ -5364,51 +5384,51 @@ void BKE_particle_system_blend_read_data(BlendDataReader *reader, ListBase *part BLO_read_data_address(reader, &pa->boid); /* This is purely runtime data, but still can be an issue if left dangling. */ - pa->boid->ground = NULL; + pa->boid->ground = nullptr; for (a = 1, pa++; a < psys->totpart; a++, pa++) { pa->boid = (pa - 1)->boid + 1; - pa->boid->ground = NULL; + pa->boid->ground = nullptr; } } else if (psys->particles) { for (a = 0, pa = psys->particles; a < psys->totpart; a++, pa++) { - pa->boid = NULL; + pa->boid = nullptr; } } BLO_read_data_address(reader, &psys->fluid_springs); BLO_read_data_address(reader, &psys->child); - psys->effectors = NULL; + psys->effectors = nullptr; BLO_read_list(reader, &psys->targets); - psys->edit = NULL; - psys->free_edit = NULL; - psys->pathcache = NULL; - psys->childcache = NULL; + psys->edit = nullptr; + psys->free_edit = nullptr; + psys->pathcache = nullptr; + psys->childcache = nullptr; BLI_listbase_clear(&psys->pathcachebufs); BLI_listbase_clear(&psys->childcachebufs); - psys->pdd = NULL; + psys->pdd = nullptr; if (psys->clmd) { BLO_read_data_address(reader, &psys->clmd); - psys->clmd->clothObject = NULL; - psys->clmd->hairdata = NULL; + psys->clmd->clothObject = nullptr; + psys->clmd->hairdata = nullptr; BLO_read_data_address(reader, &psys->clmd->sim_parms); BLO_read_data_address(reader, &psys->clmd->coll_parms); if (psys->clmd->sim_parms) { - psys->clmd->sim_parms->effector_weights = NULL; + psys->clmd->sim_parms->effector_weights = nullptr; if (psys->clmd->sim_parms->presets > 10) { psys->clmd->sim_parms->presets = 0; } } - psys->hair_in_mesh = psys->hair_out_mesh = NULL; - psys->clmd->solver_result = NULL; + psys->hair_in_mesh = psys->hair_out_mesh = nullptr; + psys->clmd->solver_result = nullptr; } BKE_ptcache_blend_read_data(reader, &psys->ptcaches, &psys->pointcache, 0); @@ -5416,11 +5436,11 @@ void BKE_particle_system_blend_read_data(BlendDataReader *reader, ListBase *part psys->clmd->point_cache = psys->pointcache; } - psys->tree = NULL; - psys->bvhtree = NULL; + psys->tree = nullptr; + psys->bvhtree = nullptr; - psys->orig_psys = NULL; - psys->batch_cache = NULL; + psys->orig_psys = nullptr; + psys->batch_cache = nullptr; } } @@ -5444,9 +5464,9 @@ void BKE_particle_system_blend_read_lib(BlendLibReader *reader, /* XXX(@campbellbarton): from reading existing code this seems correct but intended usage * of point-cache with cloth should be added in #ParticleSystem. */ psys->clmd->point_cache = psys->pointcache; - psys->clmd->ptcaches.first = psys->clmd->ptcaches.last = NULL; + psys->clmd->ptcaches.first = psys->clmd->ptcaches.last = nullptr; BLO_read_id_address(reader, id->lib, &psys->clmd->coll_parms->group); - psys->clmd->modifier.error = NULL; + psys->clmd->modifier.error = nullptr; } } else { From b314d92e7dbeefee5edd6e65d90e560b215fd992 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 9 Jan 2023 18:13:36 +0100 Subject: [PATCH 0539/1522] Fix T102942: Cycles wrong alpha for multi-layer PSD files --- intern/cycles/scene/image_oiio.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/intern/cycles/scene/image_oiio.cpp b/intern/cycles/scene/image_oiio.cpp index d0adef912be..a5824eeb267 100644 --- a/intern/cycles/scene/image_oiio.cpp +++ b/intern/cycles/scene/image_oiio.cpp @@ -211,6 +211,11 @@ bool OIIOImageLoader::load_pixels(const ImageMetaData &metadata, if (strcmp(in->format_name(), "dds") == 0) { do_associate_alpha = true; } + /* Workaround OIIO bug that sets oiio:UnassociatedAlpha on the last layer + * but not composite image that we read. */ + if (strcmp(in->format_name(), "psd") == 0) { + do_associate_alpha = true; + } } } From 71ca339fe04b6f0b7f7391ce215e41212c267140 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 9 Jan 2023 20:41:04 +0100 Subject: [PATCH 0540/1522] GPU: Fix math lib compilation and tests on AMD drivers - Matrix normalize overloads needs to have the vector normalize redefined. - double underscore (anywhere in symbol name) are reserved. - Some operation yield different result due to float imprecision. Increasing epsilon threshold for the failing tests. --- .../common/gpu_shader_math_matrix_lib.glsl | 94 +++++++++---------- .../common/gpu_shader_math_rotation_lib.glsl | 6 +- source/blender/gpu/tests/gpu_math_test.glsl | 22 ++--- 3 files changed, 60 insertions(+), 62 deletions(-) diff --git a/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl index ded6904451f..1ed8eb46f19 100644 --- a/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl +++ b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl @@ -10,15 +10,15 @@ /** \name Static constructors * \{ */ -mat2x2 mat2x2__diagonal(float v) +mat2x2 mat2x2_diagonal(float v) { return mat2x2(vec2(v, 0.0), vec2(0.0, v)); } -mat3x3 mat3x3__diagonal(float v) +mat3x3 mat3x3_diagonal(float v) { return mat3x3(vec3(v, 0.0, 0.0), vec3(0.0, v, 0.0), vec3(0.0, 0.0, v)); } -mat4x4 mat4x4__diagonal(float v) +mat4x4 mat4x4_diagonal(float v) { return mat4x4(vec4(v, 0.0, 0.0, 0.0), vec4(0.0, v, 0.0, 0.0), @@ -26,43 +26,43 @@ mat4x4 mat4x4__diagonal(float v) vec4(0.0, 0.0, 0.0, v)); } -mat2x2 mat2x2__all(float v) +mat2x2 mat2x2_all(float v) { return mat2x2(vec2(v), vec2(v)); } -mat3x3 mat3x3__all(float v) +mat3x3 mat3x3_all(float v) { return mat3x3(vec3(v), vec3(v), vec3(v)); } -mat4x4 mat4x4__all(float v) +mat4x4 mat4x4_all(float v) { return mat4x4(vec4(v), vec4(v), vec4(v), vec4(v)); } -mat2x2 mat2x2__zero(float v) +mat2x2 mat2x2_zero(float v) { - return mat2x2__all(0.0); + return mat2x2_all(0.0); } -mat3x3 mat3x3__zero(float v) +mat3x3 mat3x3_zero(float v) { - return mat3x3__all(0.0); + return mat3x3_all(0.0); } -mat4x4 mat4x4__zero(float v) +mat4x4 mat4x4_zero(float v) { - return mat4x4__all(0.0); + return mat4x4_all(0.0); } -mat2x2 mat2x2__identity() +mat2x2 mat2x2_identity() { - return mat2x2__diagonal(1.0); + return mat2x2_diagonal(1.0); } -mat3x3 mat3x3__identity() +mat3x3 mat3x3_identity() { - return mat3x3__diagonal(1.0); + return mat3x3_diagonal(1.0); } -mat4x4 mat4x4__identity() +mat4x4 mat4x4_identity() { - return mat4x4__diagonal(1.0); + return mat4x4_diagonal(1.0); } /** \} */ @@ -362,7 +362,7 @@ vec3 project_point(mat4x4 mat, vec3 point); * Maps each axis range to [-1..1] range for all axes. * The resulting matrix can be used with either #project_point or #transform_point. */ -mat4x4 projection__orthographic( +mat4x4 projection_orthographic( float left, float right, float bottom, float top, float near_clip, float far_clip); /** @@ -371,7 +371,7 @@ mat4x4 projection__orthographic( * `left`, `right`, `bottom`, `top` are frustum side distances at `z=near_clip`. * The resulting matrix can be used with #project_point. */ -mat4x4 projection__perspective( +mat4x4 projection_perspective( float left, float right, float bottom, float top, float near_clip, float far_clip); /** @@ -380,12 +380,12 @@ mat4x4 projection__perspective( * Uses field of view angles instead of plane distances. * The resulting matrix can be used with #project_point. */ -mat4x4 projection__perspective_fov(float angle_left, - float angle_right, - float angle_bottom, - float angle_top, - float near_clip, - float far_clip); +mat4x4 projection_perspective_fov(float angle_left, + float angle_right, + float angle_bottom, + float angle_top, + float near_clip, + float far_clip); /** \} */ @@ -469,20 +469,18 @@ mat4x4 invert(mat4x4 mat, out bool r_success) return r_success ? inverse(mat) : mat4x4(0.0); } -# ifdef GPU_METAL -float2 normalize(float2 a) +vec2 normalize(vec2 a) { - return a * rsqrt(length_squared(a)); + return a * inversesqrt(length_squared(a)); } -float3 normalize(float3 a) +vec3 normalize(vec3 a) { - return a * rsqrt(length_squared(a)); + return a * inversesqrt(length_squared(a)); } -float4 normalize(float4 a) +vec4 normalize(vec4 a) { - return a * rsqrt(length_squared(a)); + return a * inversesqrt(length_squared(a)); } -# endif mat2x2 normalize(mat2x2 mat) { @@ -1013,7 +1011,7 @@ mat4x4 from_loc_rot_scale(vec3 location, AxisAngle rotation, vec3 scale) return ret; } -void detail__normalized_to_eul2(mat3 mat, out EulerXYZ eul1, out EulerXYZ eul2) +void detail_normalized_to_eul2(mat3 mat, out EulerXYZ eul1, out EulerXYZ eul2) { float cy = hypot(mat[0][0], mat[0][1]); if (cy > 16.0f * FLT_EPSILON) { @@ -1044,7 +1042,7 @@ EulerXYZ to_euler(mat3x3 mat, const bool normalized) mat = normalize(mat); } EulerXYZ eul1, eul2; - detail__normalized_to_eul2(mat, eul1, eul2); + detail_normalized_to_eul2(mat, eul1, eul2); /* Return best, which is just the one with lowest values it in. */ return (length_manhattan(as_vec3(eul1)) > length_manhattan(as_vec3(eul2))) ? eul2 : eul1; } @@ -1140,11 +1138,11 @@ Quaternion normalized_to_quat_fast(mat3 mat) return q; } -Quaternion detail__normalized_to_quat_with_checks(mat3x3 mat) +Quaternion detail_normalized_to_quat_with_checks(mat3x3 mat) { float det = determinant(mat); if (!isfinite(det)) { - return Quaternion__identity(); + return Quaternion_identity(); } else if (det < 0.0) { return normalized_to_quat_fast(-mat); @@ -1154,7 +1152,7 @@ Quaternion detail__normalized_to_quat_with_checks(mat3x3 mat) Quaternion to_quaternion(mat3x3 mat) { - return detail__normalized_to_quat_with_checks(normalize(mat)); + return detail_normalized_to_quat_with_checks(normalize(mat)); } Quaternion to_quaternion(mat3x3 mat, const bool normalized) { @@ -1310,7 +1308,7 @@ mat4x4 interpolate_fast(mat4x4 a, mat4x4 b, float t) return from_loc_rot_scale(location, rotation, scale); } -mat4x4 projection__orthographic( +mat4x4 projection_orthographic( float left, float right, float bottom, float top, float near_clip, float far_clip) { float x_delta = right - left; @@ -1329,7 +1327,7 @@ mat4x4 projection__orthographic( return mat; } -mat4x4 projection__perspective( +mat4x4 projection_perspective( float left, float right, float bottom, float top, float near_clip, float far_clip) { float x_delta = right - left; @@ -1349,14 +1347,14 @@ mat4x4 projection__perspective( return mat; } -mat4x4 projection__perspective_fov(float angle_left, - float angle_right, - float angle_bottom, - float angle_top, - float near_clip, - float far_clip) +mat4x4 projection_perspective_fov(float angle_left, + float angle_right, + float angle_bottom, + float angle_top, + float near_clip, + float far_clip) { - mat4x4 mat = projection__perspective( + mat4x4 mat = projection_perspective( tan(angle_left), tan(angle_right), tan(angle_bottom), tan(angle_top), near_clip, far_clip); mat[0][0] /= near_clip; mat[1][1] /= near_clip; diff --git a/source/blender/gpu/shaders/common/gpu_shader_math_rotation_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_math_rotation_lib.glsl index c15b3f937ec..64730870b7a 100644 --- a/source/blender/gpu/shaders/common/gpu_shader_math_rotation_lib.glsl +++ b/source/blender/gpu/shaders/common/gpu_shader_math_rotation_lib.glsl @@ -29,7 +29,7 @@ struct AxisAngle { # endif }; -AxisAngle AxisAngle__identity() +AxisAngle AxisAngle_identity() { return AxisAngle(vec3(0, 1, 0), 0); } @@ -47,7 +47,7 @@ vec4 as_vec4(Quaternion quat) return vec4(quat.x, quat.y, quat.z, quat.w); } -Quaternion Quaternion__identity() +Quaternion Quaternion_identity() { return Quaternion(1, 0, 0, 0); } @@ -65,7 +65,7 @@ vec3 as_vec3(EulerXYZ eul) return vec3(eul.x, eul.y, eul.z); } -EulerXYZ EulerXYZ__identity() +EulerXYZ EulerXYZ_identity() { return EulerXYZ(0, 0, 0); } diff --git a/source/blender/gpu/tests/gpu_math_test.glsl b/source/blender/gpu/tests/gpu_math_test.glsl index ffd4faa760c..b4e9058381b 100644 --- a/source/blender/gpu/tests/gpu_math_test.glsl +++ b/source/blender/gpu/tests/gpu_math_test.glsl @@ -12,15 +12,15 @@ void main() { TEST(math_matrix, MatrixInverse) { - mat3x3 mat = mat3x3__diagonal(2); + mat3x3 mat = mat3x3_diagonal(2); mat3x3 inv = invert(mat); - mat3x3 expect = mat3x3__diagonal(0.5f); + mat3x3 expect = mat3x3_diagonal(0.5f); EXPECT_NEAR(inv, expect, 1e-5f); bool success; - mat3x3 m2 = mat3x3__all(1); + mat3x3 m2 = mat3x3_all(1); mat3x3 inv2 = invert(m2, success); - mat3x3 expect2 = mat3x3__all(0); + mat3x3 expect2 = mat3x3_all(0); EXPECT_NEAR(inv2, expect2, 1e-5f); EXPECT_FALSE(success); } @@ -71,7 +71,7 @@ void main() m = mat4(from_rotation(quat)); EXPECT_NEAR(m, expect, 1e-5); m = mat4(from_rotation(axis_angle)); - EXPECT_NEAR(m, expect, 1e-5); + EXPECT_NEAR(m, expect, 3e-4); /* Has some precision issue on some platform. */ m = from_scale(vec4(1, 2, 3, 4)); expect = mat4x4(vec4(1, 0, 0, 0), vec4(0, 2, 0, 0), vec4(0, 0, 3, 0), vec4(0, 0, 0, 4)); @@ -211,9 +211,9 @@ void main() vec4(0.389669f, 0.647565f, 0.168130f, 0.200000f), vec4(-0.536231f, 0.330541f, 0.443163f, 0.300000f), vec4(0.000000f, 0.000000f, 0.000000f, 1.000000f))); - mat4x4 m1 = mat4x4__identity(); + mat4x4 m1 = mat4x4_identity(); mat4x4 result; - const float epsilon = 1e-6; + const float epsilon = 2e-5; result = interpolate_fast(m1, m2, 0.0f); EXPECT_NEAR(result, m1, epsilon); result = interpolate_fast(m1, m2, 1.0f); @@ -235,7 +235,7 @@ void main() const vec3 p = vec3(1, 2, 3); mat4x4 m4 = from_loc_rot(vec3(10, 0, 0), EulerXYZ(M_PI_2, M_PI_2, M_PI_2)); mat3x3 m3 = from_rotation(EulerXYZ(M_PI_2, M_PI_2, M_PI_2)); - mat4x4 pers4 = projection__perspective(-0.1f, 0.1f, -0.1f, 0.1f, -0.1f, -1.0f); + mat4x4 pers4 = projection_perspective(-0.1f, 0.1f, -0.1f, 0.1f, -0.1f, -1.0f); mat3x3 pers3 = mat3x3(vec3(1, 0, 0.1f), vec3(0, 1, 0.1f), vec3(0, 0.1f, 1)); expect = vec3(13, 2, -1); @@ -264,9 +264,9 @@ void main() TEST(math_matrix, MatrixProjection) { mat4x4 expect; - mat4x4 ortho = projection__orthographic(-0.2f, 0.3f, -0.2f, 0.4f, -0.2f, -0.5f); - mat4x4 pers1 = projection__perspective(-0.2f, 0.3f, -0.2f, 0.4f, -0.2f, -0.5f); - mat4x4 pers2 = projection__perspective_fov( + mat4x4 ortho = projection_orthographic(-0.2f, 0.3f, -0.2f, 0.4f, -0.2f, -0.5f); + mat4x4 pers1 = projection_perspective(-0.2f, 0.3f, -0.2f, 0.4f, -0.2f, -0.5f); + mat4x4 pers2 = projection_perspective_fov( atan(-0.2f), atan(0.3f), atan(-0.2f), atan(0.4f), -0.2f, -0.5f); expect = transpose(mat4x4(vec4(4.0f, 0.0f, 0.0f, -0.2f), From 7bf75231e8c578c16fd7981d3a6f26de5e5ba754 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 9 Jan 2023 17:14:06 -0500 Subject: [PATCH 0541/1522] Nodes: Improve wording of node operator descriptions - Avoid calling node interface items "sockets" - Use "active" instead of "current" to be more correct - Avoid using the same word in description and name - A couple grammar fixes --- source/blender/editors/space_node/node_edit.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index ebcef77baef..d93b93d8f8c 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -1744,7 +1744,7 @@ void NODE_OT_mute_toggle(wmOperatorType *ot) { /* identifiers */ ot->name = "Toggle Node Mute"; - ot->description = "Toggle muting of the nodes"; + ot->description = "Toggle muting of selected nodes"; ot->idname = "NODE_OT_mute_toggle"; /* callbacks */ @@ -1783,7 +1783,7 @@ void NODE_OT_delete(wmOperatorType *ot) { /* identifiers */ ot->name = "Delete"; - ot->description = "Delete selected nodes"; + ot->description = "Remove selected nodes"; ot->idname = "NODE_OT_delete"; /* api callbacks */ @@ -1871,7 +1871,7 @@ void NODE_OT_delete_reconnect(wmOperatorType *ot) { /* identifiers */ ot->name = "Delete with Reconnect"; - ot->description = "Delete nodes; will reconnect nodes as if deletion was muted"; + ot->description = "Remove nodes and reconnect nodes as if deletion was muted"; ot->idname = "NODE_OT_delete_reconnect"; /* api callbacks */ @@ -1975,7 +1975,7 @@ void NODE_OT_output_file_remove_active_socket(wmOperatorType *ot) { /* identifiers */ ot->name = "Remove File Node Socket"; - ot->description = "Remove active input from a file output node"; + ot->description = "Remove the active input from a file output node"; ot->idname = "NODE_OT_output_file_remove_active_socket"; /* callbacks */ @@ -2171,7 +2171,7 @@ void NODE_OT_tree_socket_add(wmOperatorType *ot) { /* identifiers */ ot->name = "Add Node Tree Interface Socket"; - ot->description = "Add an input or output socket to the current node tree"; + ot->description = "Add an input or output to the active node tree"; ot->idname = "NODE_OT_tree_socket_add"; /* api callbacks */ @@ -2222,7 +2222,7 @@ void NODE_OT_tree_socket_remove(wmOperatorType *ot) { /* identifiers */ ot->name = "Remove Node Tree Interface Socket"; - ot->description = "Remove an input or output socket to the current node tree"; + ot->description = "Remove an input or output from the active node tree"; ot->idname = "NODE_OT_tree_socket_remove"; /* api callbacks */ @@ -2321,7 +2321,7 @@ void NODE_OT_tree_socket_change_type(wmOperatorType *ot) /* identifiers */ ot->name = "Change Node Tree Interface Socket Type"; - ot->description = "Change the type of a socket of the current node tree"; + ot->description = "Change the type of an input or output of the active node tree"; ot->idname = "NODE_OT_tree_socket_change_type"; /* api callbacks */ @@ -2402,7 +2402,7 @@ void NODE_OT_tree_socket_move(wmOperatorType *ot) { /* identifiers */ ot->name = "Move Node Tree Socket"; - ot->description = "Move a socket up or down in the current node tree's sockets stack"; + ot->description = "Move a socket up or down in the active node tree's interface"; ot->idname = "NODE_OT_tree_socket_move"; /* api callbacks */ From 317a5f61f00b06dfbd2b5140149e588db36b3c60 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Tue, 10 Jan 2023 02:07:00 +0100 Subject: [PATCH 0542/1522] Cycles: Fix recently introduced off-by-one error in an assert This was added in rB95696d09bc07, but I got the index wrong. --- intern/cycles/util/math_cdf.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/intern/cycles/util/math_cdf.cpp b/intern/cycles/util/math_cdf.cpp index a009652d8c8..cc02d630977 100644 --- a/intern/cycles/util/math_cdf.cpp +++ b/intern/cycles/util/math_cdf.cpp @@ -16,7 +16,9 @@ void util_cdf_invert(const int resolution, const bool make_symmetric, vector &inv_cdf) { - assert(cdf[0] == 0.0f && cdf[resolution] == 1.0f); + const int cdf_size = cdf.size(); + assert(cdf[0] == 0.0f && cdf[cdf_size - 1] == 1.0f); + const float inv_resolution = 1.0f / (float)resolution; const float range = to - from; inv_cdf.resize(resolution); @@ -26,12 +28,12 @@ void util_cdf_invert(const int resolution, float x = i / (float)half_size; int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin(); float t; - if (index < cdf.size() - 1) { + if (index < cdf_size - 1) { t = (x - cdf[index]) / (cdf[index + 1] - cdf[index]); } else { t = 0.0f; - index = cdf.size() - 1; + index = cdf_size - 1; } float y = ((index + t) / (resolution - 1)) * (2.0f * range); inv_cdf[half_size + i] = 0.5f * (1.0f + y); @@ -43,7 +45,7 @@ void util_cdf_invert(const int resolution, float x = (i + 0.5f) * inv_resolution; int index = upper_bound(cdf.begin(), cdf.end(), x) - cdf.begin() - 1; float t; - if (index < cdf.size() - 1) { + if (index < cdf_size - 1) { t = (x - cdf[index]) / (cdf[index + 1] - cdf[index]); } else { From c41601becd73ef67d041ed9cbb9b189fddd183d0 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Tue, 10 Jan 2023 02:32:16 +0100 Subject: [PATCH 0543/1522] Fix T89037: Cycles: Backfacing node can be wrong for lights with negative scale When rendering in the viewport (or probably on instanced objects, but I didn't test that), emissive objects whose scale is negative give the wrong value on the "backfacing" input when multiple sampling is enabled. The underlying problem was a corner case in how normal transformation is handled, which is generally a bit messy. From what I can tell, the pattern appears to be: - If you first transform vertices to world space and then compute the normal from them (as triangle light samping, MNEE and light tree do), you need to flip whenever the transform has negative scale regardless of whether the transform has been applied - If you compute the normal in object space and then transform it to world space (as the regular shader_setup_from_ray path does), you only need to flip if the transform was already applied and was negative - If you get the normal from a local intersection result (as bevel and SSS do), you only need to flip if the transform was already applied and was negative - If you get the normal from vertex normals, you don't need to do anything since the host-side code does the flip for you (arguably it'd be more consistent to do this in the kernel as well, but meh, not worth the potential slowdown) So, this patch fixes the logic in the triangle emission code. Also, turns out that the MNEE code had the same problem and was also having problems in the viewport on negative-scale objects, this is also fixed now. Differential Revision: https://developer.blender.org/D16952 --- intern/cycles/kernel/geom/motion_triangle_shader.h | 2 +- intern/cycles/kernel/geom/object.h | 5 +++++ intern/cycles/kernel/geom/triangle.h | 4 ++-- intern/cycles/kernel/integrator/mnee.h | 3 ++- intern/cycles/kernel/integrator/subsurface_disk.h | 2 +- intern/cycles/kernel/light/triangle.h | 2 +- intern/cycles/kernel/svm/bevel.h | 2 +- intern/cycles/kernel/types.h | 6 +++--- intern/cycles/scene/object.cpp | 6 ++++-- 9 files changed, 20 insertions(+), 12 deletions(-) diff --git a/intern/cycles/kernel/geom/motion_triangle_shader.h b/intern/cycles/kernel/geom/motion_triangle_shader.h index 413a61b380a..0ec5e29f480 100644 --- a/intern/cycles/kernel/geom/motion_triangle_shader.h +++ b/intern/cycles/kernel/geom/motion_triangle_shader.h @@ -58,7 +58,7 @@ ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals kg, sd->P = motion_triangle_point_from_uv(kg, sd, isect_object, isect_prim, sd->u, sd->v, verts); /* Compute face normal. */ float3 Ng; - if (sd->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { + if (object_negative_scale_applied(sd->object_flag)) { Ng = normalize(cross(verts[2] - verts[0], verts[1] - verts[0])); } else { diff --git a/intern/cycles/kernel/geom/object.h b/intern/cycles/kernel/geom/object.h index 14ceb636e2e..f5f3c36f208 100644 --- a/intern/cycles/kernel/geom/object.h +++ b/intern/cycles/kernel/geom/object.h @@ -201,6 +201,11 @@ ccl_device_inline void object_normal_transform(KernelGlobals kg, *N = normalize(transform_direction_transposed(&tfm, *N)); } +ccl_device_inline bool object_negative_scale_applied(const int object_flag) +{ + return ((object_flag & SD_OBJECT_NEGATIVE_SCALE) && (object_flag & SD_OBJECT_TRANSFORM_APPLIED)); +} + /* Transform direction vector from object to world space */ ccl_device_inline void object_dir_transform(KernelGlobals kg, diff --git a/intern/cycles/kernel/geom/triangle.h b/intern/cycles/kernel/geom/triangle.h index 6b9450d59ef..b5fb67260a9 100644 --- a/intern/cycles/kernel/geom/triangle.h +++ b/intern/cycles/kernel/geom/triangle.h @@ -21,7 +21,7 @@ ccl_device_inline float3 triangle_normal(KernelGlobals kg, ccl_private ShaderDat const float3 v2 = kernel_data_fetch(tri_verts, tri_vindex.w + 2); /* return normal */ - if (sd->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { + if (object_negative_scale_applied(sd->object_flag)) { return normalize(cross(v2 - v0, v1 - v0)); } else { @@ -50,7 +50,7 @@ ccl_device_inline void triangle_point_normal(KernelGlobals kg, /* get object flags */ int object_flag = kernel_data_fetch(object_flag, object); /* compute normal */ - if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { + if (object_negative_scale_applied(object_flag)) { *Ng = normalize(cross(v2 - v0, v1 - v0)); } else { diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h index 7f5f2c97497..debbce497dc 100644 --- a/intern/cycles/kernel/integrator/mnee.h +++ b/intern/cycles/kernel/integrator/mnee.h @@ -176,8 +176,9 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg, /* Geometric normal. */ vtx->ng = normalize(cross(dp_du, dp_dv)); - if (sd_vtx->object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) + if (sd_vtx->object_flag & SD_OBJECT_NEGATIVE_SCALE) { vtx->ng = -vtx->ng; + } /* Shading normals: Interpolate normals between vertices. */ float n_len; diff --git a/intern/cycles/kernel/integrator/subsurface_disk.h b/intern/cycles/kernel/integrator/subsurface_disk.h index 16fb45392f4..083834a87da 100644 --- a/intern/cycles/kernel/integrator/subsurface_disk.h +++ b/intern/cycles/kernel/integrator/subsurface_disk.h @@ -120,7 +120,7 @@ ccl_device_inline bool subsurface_disk(KernelGlobals kg, if (path_flag & PATH_RAY_SUBSURFACE_BACKFACING) { hit_Ng = -hit_Ng; } - if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { + if (object_negative_scale_applied(object_flag)) { hit_Ng = -hit_Ng; } diff --git a/intern/cycles/kernel/light/triangle.h b/intern/cycles/kernel/light/triangle.h index 829bacb31f3..7a9a395c2b6 100644 --- a/intern/cycles/kernel/light/triangle.h +++ b/intern/cycles/kernel/light/triangle.h @@ -146,7 +146,7 @@ ccl_device_forceinline bool triangle_light_sample(KernelGlobals kg, /* flip normal if necessary */ const int object_flag = kernel_data_fetch(object_flag, object); - if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { + if (object_flag & SD_OBJECT_NEGATIVE_SCALE) { ls->Ng = -ls->Ng; } ls->eval_fac = 1.0f; diff --git a/intern/cycles/kernel/svm/bevel.h b/intern/cycles/kernel/svm/bevel.h index c1e227959f8..736ea9b80c1 100644 --- a/intern/cycles/kernel/svm/bevel.h +++ b/intern/cycles/kernel/svm/bevel.h @@ -224,7 +224,7 @@ ccl_device float3 svm_bevel( float3 hit_Ng = isect.Ng[hit]; int object = isect.hits[hit].object; int object_flag = kernel_data_fetch(object_flag, object); - if (object_flag & SD_OBJECT_NEGATIVE_SCALE_APPLIED) { + if (object_negative_scale_applied(object_flag)) { hit_Ng = -hit_Ng; } diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 69b73d78417..ff75e70ba6b 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -850,8 +850,8 @@ enum ShaderDataObjectFlag { SD_OBJECT_MOTION = (1 << 1), /* Vertices have transform applied. */ SD_OBJECT_TRANSFORM_APPLIED = (1 << 2), - /* Vertices have negative scale applied. */ - SD_OBJECT_NEGATIVE_SCALE_APPLIED = (1 << 3), + /* The object's transform applies a negative scale. */ + SD_OBJECT_NEGATIVE_SCALE = (1 << 3), /* Object has a volume shader. */ SD_OBJECT_HAS_VOLUME = (1 << 4), /* Object intersects AABB of an object with volume shader. */ @@ -873,7 +873,7 @@ enum ShaderDataObjectFlag { SD_OBJECT_CAUSTICS = (SD_OBJECT_CAUSTICS_CASTER | SD_OBJECT_CAUSTICS_RECEIVER), SD_OBJECT_FLAGS = (SD_OBJECT_HOLDOUT_MASK | SD_OBJECT_MOTION | SD_OBJECT_TRANSFORM_APPLIED | - SD_OBJECT_NEGATIVE_SCALE_APPLIED | SD_OBJECT_HAS_VOLUME | + SD_OBJECT_NEGATIVE_SCALE | SD_OBJECT_HAS_VOLUME | SD_OBJECT_INTERSECTS_VOLUME | SD_OBJECT_SHADOW_CATCHER | SD_OBJECT_HAS_VOLUME_ATTRIBUTES | SD_OBJECT_CAUSTICS | SD_OBJECT_HAS_VOLUME_MOTION) diff --git a/intern/cycles/scene/object.cpp b/intern/cycles/scene/object.cpp index 898e161f832..c788c6f4a8c 100644 --- a/intern/cycles/scene/object.cpp +++ b/intern/cycles/scene/object.cpp @@ -435,6 +435,10 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s state->have_motion = true; } + if (transform_negative_scale(tfm)) { + flag |= SD_OBJECT_NEGATIVE_SCALE; + } + if (geom->geometry_type == Geometry::MESH || geom->geometry_type == Geometry::POINTCLOUD) { /* TODO: why only mesh? */ Mesh *mesh = static_cast(geom); @@ -970,8 +974,6 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P } object_flag[i] |= SD_OBJECT_TRANSFORM_APPLIED; - if (geom->transform_negative_scaled) - object_flag[i] |= SD_OBJECT_NEGATIVE_SCALE_APPLIED; } } From 39c30f6983009847d010856bee8a193a8ee3e73c Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Tue, 10 Jan 2023 02:44:12 +0100 Subject: [PATCH 0544/1522] Cycles: Account for negative scale when using one-sided light tree sampling Differential Revision: https://developer.blender.org/D16952 --- intern/cycles/kernel/light/tree.h | 13 +++++++++---- intern/cycles/scene/light_tree.cpp | 17 ++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 3c6f118ace3..423879bcddc 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -223,11 +223,16 @@ ccl_device bool compute_emitter_centroid_and_dir(KernelGlobals kg, triangle_world_space_vertices(kg, object, prim_id, -1.0f, vertices); centroid = (vertices[0] + vertices[1] + vertices[2]) / 3.0f; - if (kemitter->emission_sampling == EMISSION_SAMPLING_FRONT) { + const bool is_front_only = (kemitter->emission_sampling == EMISSION_SAMPLING_FRONT); + const bool is_back_only = (kemitter->emission_sampling == EMISSION_SAMPLING_BACK); + if (is_front_only || is_back_only) { dir = safe_normalize(cross(vertices[1] - vertices[0], vertices[2] - vertices[0])); - } - else if (kemitter->emission_sampling == EMISSION_SAMPLING_BACK) { - dir = -safe_normalize(cross(vertices[1] - vertices[0], vertices[2] - vertices[0])); + if (is_back_only) { + dir = -dir; + } + if (kernel_data_fetch(object_flag, object) & SD_OBJECT_NEGATIVE_SCALE) { + dir = -dir; + } } else { /* Double-sided: any vector in the plane. */ diff --git a/intern/cycles/scene/light_tree.cpp b/intern/cycles/scene/light_tree.cpp index f9bd479cf1c..4fa4755479b 100644 --- a/intern/cycles/scene/light_tree.cpp +++ b/intern/cycles/scene/light_tree.cpp @@ -94,14 +94,17 @@ LightTreePrimitive::LightTreePrimitive(Scene *scene, int prim_id, int object_id) * seems to work fine */ centroid = (vertices[0] + vertices[1] + vertices[2]) / 3.0f; - if (shader->emission_sampling == EMISSION_SAMPLING_FRONT) { - /* Front only. */ + const bool is_front_only = (shader->emission_sampling == EMISSION_SAMPLING_FRONT); + const bool is_back_only = (shader->emission_sampling == EMISSION_SAMPLING_BACK); + if (is_front_only || is_back_only) { + /* One-sided. */ bcone.axis = safe_normalize(cross(vertices[1] - vertices[0], vertices[2] - vertices[0])); - bcone.theta_o = 0; - } - else if (shader->emission_sampling == EMISSION_SAMPLING_BACK) { - /* Back only. */ - bcone.axis = -safe_normalize(cross(vertices[1] - vertices[0], vertices[2] - vertices[0])); + if (is_back_only) { + bcone.axis = -bcone.axis; + } + if (transform_negative_scale(object->get_tfm())) { + bcone.axis = -bcone.axis; + } bcone.theta_o = 0; } else { From 63b9a57f8bd81135f8fc26a9bd219541a1f646f9 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Mon, 9 Jan 2023 23:45:12 -0300 Subject: [PATCH 0545/1522] Cleanup: use descriptive names for transform snapping functions activeSnap --> transform_snap_is_active activeSnap_SnappingIndividual --> transform_snap_project_individual_is_active activeSnap_SnappingAsGroup --> transform_snap_mixed_is_active applySnappingIndividual --> transform_snap_project_individual_apply applySnappingAsGroup --> transform_snap_mixed_apply Also rearrange functions to be close to where they are used. And use static when possible. --- .../editors/transform/transform_constraints.c | 2 +- .../transform/transform_convert_armature.c | 2 +- .../transform/transform_convert_curve.c | 2 +- .../transform/transform_convert_lattice.c | 2 +- .../transform/transform_convert_mball.c | 2 +- .../transform/transform_convert_mesh.c | 6 +- .../transform/transform_convert_node.cc | 2 +- .../transform/transform_convert_object.c | 2 +- .../transform_convert_object_texspace.c | 2 +- .../transform/transform_convert_particle.c | 2 +- .../transform_mode_edge_rotate_normal.c | 2 +- .../transform/transform_mode_edge_seq_slide.c | 2 +- .../transform/transform_mode_edge_slide.c | 2 +- .../editors/transform/transform_mode_resize.c | 2 +- .../editors/transform/transform_mode_rotate.c | 4 +- .../transform/transform_mode_skin_resize.c | 2 +- .../transform/transform_mode_translate.c | 8 +- .../transform/transform_mode_vert_slide.c | 2 +- .../editors/transform/transform_snap.cc | 101 +++++++++--------- .../editors/transform/transform_snap.h | 9 +- .../transform/transform_snap_animation.c | 2 +- 21 files changed, 82 insertions(+), 78 deletions(-) diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 4de000c96cf..b0db9398e80 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -393,7 +393,7 @@ static void applyAxisConstraintVec(const TransInfo *t, if (!td && t->con.mode & CON_APPLY) { bool is_snap_to_point = false, is_snap_to_edge = false, is_snap_to_face = false; - if (activeSnap(t)) { + if (transform_snap_is_active(t)) { if (validSnap(t)) { is_snap_to_edge = (t->tsnap.snapElem & SCE_SNAP_MODE_EDGE) != 0; is_snap_to_face = (t->tsnap.snapElem & SCE_SNAP_MODE_FACE_RAYCAST) != 0; diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index 2e37f6b7c34..ada6d1c40b2 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -1193,7 +1193,7 @@ static void restoreBones(TransDataContainer *tc) static void recalcData_edit_armature(TransInfo *t) { if (t->state != TRANS_CANCEL) { - applySnappingIndividual(t); + transform_snap_project_individual_apply(t); } FOREACH_TRANS_DATA_CONTAINER (t, tc) { diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c index 3a4098cf06f..58ed8ad7d33 100644 --- a/source/blender/editors/transform/transform_convert_curve.c +++ b/source/blender/editors/transform/transform_convert_curve.c @@ -419,7 +419,7 @@ static void createTransCurveVerts(bContext *UNUSED(C), TransInfo *t) static void recalcData_curve(TransInfo *t) { if (t->state != TRANS_CANCEL) { - applySnappingIndividual(t); + transform_snap_project_individual_apply(t); } FOREACH_TRANS_DATA_CONTAINER (t, tc) { diff --git a/source/blender/editors/transform/transform_convert_lattice.c b/source/blender/editors/transform/transform_convert_lattice.c index cb391b4930b..bc53ce02996 100644 --- a/source/blender/editors/transform/transform_convert_lattice.c +++ b/source/blender/editors/transform/transform_convert_lattice.c @@ -102,7 +102,7 @@ static void createTransLatticeVerts(bContext *UNUSED(C), TransInfo *t) static void recalcData_lattice(TransInfo *t) { if (t->state != TRANS_CANCEL) { - applySnappingIndividual(t); + transform_snap_project_individual_apply(t); } FOREACH_TRANS_DATA_CONTAINER (t, tc) { diff --git a/source/blender/editors/transform/transform_convert_mball.c b/source/blender/editors/transform/transform_convert_mball.c index bae2ea8b20d..b4150539a51 100644 --- a/source/blender/editors/transform/transform_convert_mball.c +++ b/source/blender/editors/transform/transform_convert_mball.c @@ -123,7 +123,7 @@ static void createTransMBallVerts(bContext *UNUSED(C), TransInfo *t) static void recalcData_mball(TransInfo *t) { if (t->state != TRANS_CANCEL) { - applySnappingIndividual(t); + transform_snap_project_individual_apply(t); } FOREACH_TRANS_DATA_CONTAINER (t, tc) { if (tc->data_len) { diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index a8c34a95389..34432004701 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -1895,7 +1895,7 @@ static void tc_mesh_partial_types_calc(TransInfo *t, struct PartialTypeState *r_ partial_for_looptri = PARTIAL_TYPE_GROUP; partial_for_normals = PARTIAL_TYPE_GROUP; /* Translation can rotate when snapping to normal. */ - if (activeSnap(t) && usingSnappingNormal(t) && validSnappingNormal(t)) { + if (transform_snap_is_active(t) && usingSnappingNormal(t) && validSnappingNormal(t)) { partial_for_normals = PARTIAL_TYPE_ALL; } break; @@ -1926,7 +1926,7 @@ static void tc_mesh_partial_types_calc(TransInfo *t, struct PartialTypeState *r_ } /* With projection, transform isn't affine. */ - if (activeSnap_SnappingIndividual(t)) { + if (transform_snap_project_individual_is_active(t)) { if (partial_for_looptri == PARTIAL_TYPE_GROUP) { partial_for_looptri = PARTIAL_TYPE_ALL; } @@ -2042,7 +2042,7 @@ static void recalcData_mesh(TransInfo *t) bool is_canceling = t->state == TRANS_CANCEL; /* Apply corrections. */ if (!is_canceling) { - applySnappingIndividual(t); + transform_snap_project_individual_apply(t); bool do_mirror = !(t->flag & T_NO_MIRROR); FOREACH_TRANS_DATA_CONTAINER (t, tc) { diff --git a/source/blender/editors/transform/transform_convert_node.cc b/source/blender/editors/transform/transform_convert_node.cc index ea89d50a86d..e49ec77fdbf 100644 --- a/source/blender/editors/transform/transform_convert_node.cc +++ b/source/blender/editors/transform/transform_convert_node.cc @@ -156,7 +156,7 @@ static void node_snap_grid_apply(TransInfo *t) { using namespace blender; - if (!(activeSnap(t) && (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) { + if (!(transform_snap_is_active(t) && (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) { return; } diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c index 55f7cd9b23d..401d72485c8 100644 --- a/source/blender/editors/transform/transform_convert_object.c +++ b/source/blender/editors/transform/transform_convert_object.c @@ -878,7 +878,7 @@ static void recalcData_objects(TransInfo *t) bool motionpath_update = false; if (t->state != TRANS_CANCEL) { - applySnappingIndividual(t); + transform_snap_project_individual_apply(t); } FOREACH_TRANS_DATA_CONTAINER (t, tc) { diff --git a/source/blender/editors/transform/transform_convert_object_texspace.c b/source/blender/editors/transform/transform_convert_object_texspace.c index b4c1c134d49..cd2a3d6a40b 100644 --- a/source/blender/editors/transform/transform_convert_object_texspace.c +++ b/source/blender/editors/transform/transform_convert_object_texspace.c @@ -92,7 +92,7 @@ static void recalcData_texspace(TransInfo *t) { if (t->state != TRANS_CANCEL) { - applySnappingIndividual(t); + transform_snap_project_individual_apply(t); } FOREACH_TRANS_DATA_CONTAINER (t, tc) { diff --git a/source/blender/editors/transform/transform_convert_particle.c b/source/blender/editors/transform/transform_convert_particle.c index e6ff730d4d1..f1bda0a5a35 100644 --- a/source/blender/editors/transform/transform_convert_particle.c +++ b/source/blender/editors/transform/transform_convert_particle.c @@ -241,7 +241,7 @@ static void flushTransParticles(TransInfo *t) static void recalcData_particles(TransInfo *t) { if (t->state != TRANS_CANCEL) { - applySnappingIndividual(t); + transform_snap_project_individual_apply(t); } flushTransParticles(t); } diff --git a/source/blender/editors/transform/transform_mode_edge_rotate_normal.c b/source/blender/editors/transform/transform_mode_edge_rotate_normal.c index 8d790b4699b..63303b81493 100644 --- a/source/blender/editors/transform/transform_mode_edge_rotate_normal.c +++ b/source/blender/editors/transform/transform_mode_edge_rotate_normal.c @@ -84,7 +84,7 @@ static void applyNormalRotation(TransInfo *t, const int UNUSED(mval[2])) transform_snap_increment(t, &angle); - applySnappingAsGroup(t, &angle); + transform_snap_mixed_apply(t, &angle); applyNumInput(&t->num, &angle); diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c index 5ca1fdf75c6..ae824b5a712 100644 --- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c @@ -87,7 +87,7 @@ static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2])) } else { copy_v2_v2(values_final, t->values); - applySnappingAsGroup(t, values_final); + transform_snap_mixed_apply(t, values_final); transform_convert_sequencer_channel_clamp(t, values_final); if (t->con.mode & CON_APPLY) { diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index 220cc11cf2c..2d4cc7e2c76 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -1447,7 +1447,7 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2])) final = t->values[0] + t->values_modal_offset[0]; - applySnappingAsGroup(t, &final); + transform_snap_mixed_apply(t, &final); if (!validSnap(t)) { transform_snap_increment(t, &final); } diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c index 4e671768721..668e1ed567f 100644 --- a/source/blender/editors/transform/transform_mode_resize.c +++ b/source/blender/editors/transform/transform_mode_resize.c @@ -203,7 +203,7 @@ static void applyResize(TransInfo *t, const int UNUSED(mval[2])) constraintNumInput(t, t->values_final); } - applySnappingAsGroup(t, t->values_final); + transform_snap_mixed_apply(t, t->values_final); } size_to_mat3(mat, t->values_final); diff --git a/source/blender/editors/transform/transform_mode_rotate.c b/source/blender/editors/transform/transform_mode_rotate.c index 110000def35..a56d3b23149 100644 --- a/source/blender/editors/transform/transform_mode_rotate.c +++ b/source/blender/editors/transform/transform_mode_rotate.c @@ -368,8 +368,8 @@ static void applyRotation(TransInfo *t, const int UNUSED(mval[2])) final = large_rotation_limit(final); } else { - applySnappingAsGroup(t, &final); - if (!(activeSnap(t) && validSnap(t))) { + transform_snap_mixed_apply(t, &final); + if (!(transform_snap_is_active(t) && validSnap(t))) { transform_snap_increment(t, &final); } } diff --git a/source/blender/editors/transform/transform_mode_skin_resize.c b/source/blender/editors/transform/transform_mode_skin_resize.c index bdbb66b72f4..6bf3e25de8a 100644 --- a/source/blender/editors/transform/transform_mode_skin_resize.c +++ b/source/blender/editors/transform/transform_mode_skin_resize.c @@ -99,7 +99,7 @@ static void applySkinResize(TransInfo *t, const int UNUSED(mval[2])) constraintNumInput(t, t->values_final); } - applySnappingAsGroup(t, t->values_final); + transform_snap_mixed_apply(t, t->values_final); } size_to_mat3(mat_final, t->values_final); diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index ce82c788dfe..9257512268d 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -398,7 +398,7 @@ static void translate_snap_grid_apply(TransInfo *t, static bool translate_snap_grid(TransInfo *t, float *val) { - if (!activeSnap(t)) { + if (!transform_snap_is_active(t)) { return false; } @@ -475,7 +475,7 @@ static void applyTranslationValue(TransInfo *t, const float vec[3]) enum eTranslateRotateMode rotate_mode = TRANSLATE_ROTATE_OFF; - if (activeSnap(t) && usingSnappingNormal(t) && validSnappingNormal(t)) { + if (transform_snap_is_active(t) && usingSnappingNormal(t) && validSnappingNormal(t)) { rotate_mode = TRANSLATE_ROTATE_ON; } @@ -610,7 +610,7 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2])) } t->tsnap.snapElem = SCE_SNAP_MODE_NONE; - applySnappingAsGroup(t, global_dir); + transform_snap_mixed_apply(t, global_dir); translate_snap_grid(t, global_dir); if (t->con.mode & CON_APPLY) { @@ -621,7 +621,7 @@ static void applyTranslation(TransInfo *t, const int UNUSED(mval[2])) float incr_dir[3]; copy_v3_v3(incr_dir, global_dir); - if (!(activeSnap(t) && validSnap(t)) && + if (!(transform_snap_is_active(t) && validSnap(t)) && transform_snap_increment_ex(t, (t->con.mode & CON_APPLY) != 0, incr_dir)) { /* Test for mixed snap with grid. */ diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c index d9a56c030fd..e8813241809 100644 --- a/source/blender/editors/transform/transform_mode_vert_slide.c +++ b/source/blender/editors/transform/transform_mode_vert_slide.c @@ -562,7 +562,7 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2])) final = t->values[0] + t->values_modal_offset[0]; - applySnappingAsGroup(t, &final); + transform_snap_mixed_apply(t, &final); if (!validSnap(t)) { transform_snap_increment(t, &final); } diff --git a/source/blender/editors/transform/transform_snap.cc b/source/blender/editors/transform/transform_snap.cc index ab7318cbc67..c2a0c0abc65 100644 --- a/source/blender/editors/transform/transform_snap.cc +++ b/source/blender/editors/transform/transform_snap.cc @@ -119,50 +119,12 @@ bool validSnap(const TransInfo *t) (t->tsnap.status & (MULTI_POINTS | TARGET_INIT)) == (MULTI_POINTS | TARGET_INIT); } -bool activeSnap(const TransInfo *t) +bool transform_snap_is_active(const TransInfo *t) { return ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP) || ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) == MOD_SNAP_INVERT); } -bool activeSnap_SnappingIndividual(const TransInfo *t) -{ - if (!activeSnap(t) || (t->flag & T_NO_PROJECT)) { - return false; - } - - if (!(t->tsnap.project || (t->tsnap.mode & SCE_SNAP_MODE_FACE_NEAREST))) { - return false; - } - - if (doForceIncrementSnap(t)) { - return false; - } - - return true; -} - -bool activeSnap_SnappingAsGroup(const TransInfo *t) -{ - if (!activeSnap(t)) { - return false; - } - - if (t->tsnap.mode == SCE_SNAP_MODE_FACE_RAYCAST && t->tsnap.project) { - return false; - } - - if (t->tsnap.mode == SCE_SNAP_MODE_FACE_NEAREST) { - return false; - } - - if (doForceIncrementSnap(t)) { - return false; - } - - return true; -} - bool transformModeUseSnap(const TransInfo *t) { ToolSettings *ts = t->settings; @@ -190,7 +152,7 @@ static bool doForceIncrementSnap(const TransInfo *t) void drawSnapping(const struct bContext *C, TransInfo *t) { uchar col[4], selectedCol[4], activeCol[4]; - if (!activeSnap(t)) { + if (!transform_snap_is_active(t)) { return; } @@ -483,9 +445,30 @@ static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td /* TODO: support snap alignment similar to #SCE_SNAP_MODE_FACE_RAYCAST? */ } -void applySnappingIndividual(TransInfo *t) +bool transform_snap_project_individual_is_active(const TransInfo *t) { - if (!activeSnap_SnappingIndividual(t)) { + if (!transform_snap_is_active(t) || (t->flag & T_NO_PROJECT)) { + return false; + } + + if (!transform_snap_is_active(t) || (t->flag & T_NO_PROJECT)) { + return false; + } + + if (!(t->tsnap.project || (t->tsnap.mode & SCE_SNAP_MODE_FACE_NEAREST))) { + return false; + } + + if (doForceIncrementSnap(t)) { + return false; + } + + return true; +} + +void transform_snap_project_individual_apply(TransInfo *t) +{ + if (!transform_snap_project_individual_is_active(t)) { return; } @@ -514,9 +497,30 @@ void applySnappingIndividual(TransInfo *t) } } -void applySnappingAsGroup(TransInfo *t, float *vec) +static bool transform_snap_mixed_is_active(const TransInfo *t) { - if (!activeSnap_SnappingAsGroup(t)) { + if (!transform_snap_is_active(t)) { + return false; + } + + if (t->tsnap.mode == SCE_SNAP_MODE_FACE_RAYCAST && t->tsnap.project) { + return false; + } + + if (t->tsnap.mode == SCE_SNAP_MODE_FACE_NEAREST) { + return false; + } + + if (doForceIncrementSnap(t)) { + return false; + } + + return true; +} + +void transform_snap_mixed_apply(TransInfo *t, float *vec) +{ + if (!transform_snap_mixed_is_active(t)) { return; } @@ -526,7 +530,7 @@ void applySnappingAsGroup(TransInfo *t, float *vec) t->tsnap.applySnap(t, vec); } else if (((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) != 0) && - activeSnap(t)) { + transform_snap_is_active(t)) { double current = PIL_check_seconds_timer(); /* Time base quirky code to go around find-nearest slowness. */ @@ -1628,7 +1632,7 @@ static void snap_increment_apply(const TransInfo *t, bool transform_snap_increment_ex(const TransInfo *t, bool use_local_space, float *r_val) { - if (!activeSnap(t)) { + if (!transform_snap_is_active(t)) { return false; } @@ -1664,8 +1668,9 @@ bool transform_snap_increment(const TransInfo *t, float *r_val) float transform_snap_increment_get(const TransInfo *t) { - if (activeSnap(t) && (!transformModeUseSnap(t) || - (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) { + if (transform_snap_is_active(t) && + (!transformModeUseSnap(t) || + (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) { return (t->modifiers & MOD_PRECISION) ? t->snap[1] : t->snap[0]; } diff --git a/source/blender/editors/transform/transform_snap.h b/source/blender/editors/transform/transform_snap.h index 16d9062e978..2757a0813f9 100644 --- a/source/blender/editors/transform/transform_snap.h +++ b/source/blender/editors/transform/transform_snap.h @@ -43,16 +43,15 @@ bool transform_snap_increment_ex(const TransInfo *t, bool use_local_space, float bool transform_snap_increment(const TransInfo *t, float *val); float transform_snap_increment_get(const TransInfo *t); -bool activeSnap(const TransInfo *t); -bool activeSnap_SnappingIndividual(const TransInfo *t); -bool activeSnap_SnappingAsGroup(const TransInfo *t); +bool transform_snap_is_active(const TransInfo *t); bool validSnap(const TransInfo *t); void initSnapping(struct TransInfo *t, struct wmOperator *op); void freeSnapping(struct TransInfo *t); -void applySnappingIndividual(TransInfo *t); -void applySnappingAsGroup(TransInfo *t, float *vec); +bool transform_snap_project_individual_is_active(const TransInfo *t); +void transform_snap_project_individual_apply(TransInfo *t); +void transform_snap_mixed_apply(TransInfo *t, float *vec); void resetSnapping(TransInfo *t); eRedrawFlag handleSnapping(TransInfo *t, const struct wmEvent *event); void drawSnapping(const struct bContext *C, TransInfo *t); diff --git a/source/blender/editors/transform/transform_snap_animation.c b/source/blender/editors/transform/transform_snap_animation.c index fbb7c812525..c0c625f0fb4 100644 --- a/source/blender/editors/transform/transform_snap_animation.c +++ b/source/blender/editors/transform/transform_snap_animation.c @@ -34,7 +34,7 @@ short getAnimEdit_SnapMode(TransInfo *t) } } else if (t->spacetype == SPACE_GRAPH) { - if ((t->mode == TFM_TRANSLATION) && activeSnap(t)) { + if ((t->mode == TFM_TRANSLATION) && transform_snap_is_active(t)) { return autosnap; } SpaceGraph *sipo = (SpaceGraph *)t->area->spacedata.first; From 92449e634ff709856f75161b95a84d5b59097f7e Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Mon, 9 Jan 2023 23:56:14 -0300 Subject: [PATCH 0546/1522] Fix duplicate code in 63b9a57f8bd8 --- source/blender/editors/transform/transform_snap.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/transform/transform_snap.cc b/source/blender/editors/transform/transform_snap.cc index c2a0c0abc65..0eebe05fa0c 100644 --- a/source/blender/editors/transform/transform_snap.cc +++ b/source/blender/editors/transform/transform_snap.cc @@ -447,11 +447,11 @@ static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td bool transform_snap_project_individual_is_active(const TransInfo *t) { - if (!transform_snap_is_active(t) || (t->flag & T_NO_PROJECT)) { + if (!transform_snap_is_active(t)) { return false; } - if (!transform_snap_is_active(t) || (t->flag & T_NO_PROJECT)) { + if (t->flag & T_NO_PROJECT) { return false; } From 13450c2d22cd1bbe05850b96670fbdec74bad9c8 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 9 Jan 2023 23:26:32 -0500 Subject: [PATCH 0547/1522] Cleanup: Clang format Mostly bad white space from a bad find & replace in my own cleanup commit. --- source/blender/blenkernel/intern/curve.cc | 16 +++++++-------- source/blender/blenkernel/intern/scene.cc | 4 ++-- .../editors/interface/interface_handlers.cc | 4 ++-- .../blender/editors/space_image/image_undo.cc | 20 +++++++++---------- .../blender/editors/space_node/node_gizmo.cc | 4 ++-- .../transform/transform_convert_node.cc | 3 ++- .../geometry/intern/mesh_merge_by_distance.cc | 2 +- .../intern/lineart/lineart_cpu.cc | 4 ++-- source/blender/render/intern/multires_bake.cc | 14 ++++++------- .../windowmanager/intern/wm_event_system.cc | 2 +- 10 files changed, 37 insertions(+), 36 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index f2e6d037fe0..139d4a45553 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -3048,7 +3048,7 @@ void BKE_curve_bevelList_make(Object *ob, const ListBase *nurbs, const bool for_ bevp2 = bevp1 + (bl->nr - 1); nr = bl->nr / 2; while (nr--) { - std::swap( *bevp1, *bevp2); + std::swap(*bevp1, *bevp2); bevp1++; bevp2--; } @@ -4446,12 +4446,12 @@ void BKE_nurb_direction_switch(Nurb *nu) swap_v3_v3(bezt2->vec[0], bezt2->vec[2]); } - std::swap( bezt1->h1, bezt1->h2); - std::swap( bezt1->f1, bezt1->f3); + std::swap(bezt1->h1, bezt1->h2); + std::swap(bezt1->f1, bezt1->f3); if (bezt1 != bezt2) { - std::swap( bezt2->h1, bezt2->h2); - std::swap( bezt2->f1, bezt2->f3); + std::swap(bezt2->h1, bezt2->h2); + std::swap(bezt2->f1, bezt2->f3); bezt1->tilt = -bezt1->tilt; bezt2->tilt = -bezt2->tilt; } @@ -4469,7 +4469,7 @@ void BKE_nurb_direction_switch(Nurb *nu) bp2 = bp1 + (a - 1); a /= 2; while (bp1 != bp2 && a > 0) { - std::swap( *bp1, *bp2); + std::swap(*bp1, *bp2); a--; bp1->tilt = -bp1->tilt; bp2->tilt = -bp2->tilt; @@ -4491,7 +4491,7 @@ void BKE_nurb_direction_switch(Nurb *nu) fp2 = fp1 + (a - 1); a /= 2; while (fp1 != fp2 && a > 0) { - std::swap( *fp1, *fp2); + std::swap(*fp1, *fp2); a--; fp1++; fp2--; @@ -4530,7 +4530,7 @@ void BKE_nurb_direction_switch(Nurb *nu) a /= 2; while (bp1 != bp2 && a > 0) { - std::swap( *bp1, *bp2); + std::swap(*bp1, *bp2); a--; bp1++; bp2--; diff --git a/source/blender/blenkernel/intern/scene.cc b/source/blender/blenkernel/intern/scene.cc index 57f49c23b88..124de007ade 100644 --- a/source/blender/blenkernel/intern/scene.cc +++ b/source/blender/blenkernel/intern/scene.cc @@ -1686,14 +1686,14 @@ static void scene_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old) Scene *scene_new = (Scene *)id_new; Scene *scene_old = (Scene *)id_old; - std::swap( scene_old->cursor, scene_new->cursor); + std::swap(scene_old->cursor, scene_new->cursor); if (scene_new->toolsettings != nullptr && scene_old->toolsettings != nullptr) { /* First try to restore ID pointers that can be and should be preserved (like brushes or * palettes), and counteract the swap of the whole ToolSettings structs below for the others * (like object ones). */ scene_foreach_toolsettings( nullptr, scene_new->toolsettings, true, reader, scene_old->toolsettings); - std::swap( *scene_old->toolsettings, *scene_new->toolsettings); + std::swap(*scene_old->toolsettings, *scene_new->toolsettings); } } diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index ab965fb7560..44a14f254c0 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -3087,7 +3087,7 @@ static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data, but->selsta = but->pos; but->selend = data->sel_pos_init; if (but->selend < but->selsta) { - std::swap(but->selsta, but->selend); + std::swap(but->selsta, but->selend); } ui_but_update(but); @@ -3190,7 +3190,7 @@ static void ui_textedit_move(uiBut *but, but->selend = data->sel_pos_init; } if (but->selend < but->selsta) { - std::swap( but->selsta, but->selend); + std::swap(but->selsta, but->selend); } } } diff --git a/source/blender/editors/space_image/image_undo.cc b/source/blender/editors/space_image/image_undo.cc index b7aaca0bbd8..085a045b6c4 100644 --- a/source/blender/editors/space_image/image_undo.cc +++ b/source/blender/editors/space_image/image_undo.cc @@ -261,10 +261,10 @@ void *ED_image_paint_tile_push(PaintTileMap *paint_tile_map, ED_IMAGE_UNDO_TILE_SIZE); if (has_float) { - std::swap( ptile->rect.fp, (*tmpibuf)->rect_float); + std::swap(ptile->rect.fp, (*tmpibuf)->rect_float); } else { - std::swap(ptile->rect.uint, (*tmpibuf)->rect); + std::swap(ptile->rect.uint, (*tmpibuf)->rect); } PaintTileKey key = {}; @@ -299,10 +299,10 @@ static void ptile_restore_runtime_map(PaintTileMap *paint_tile_map) const bool has_float = (ibuf->rect_float != nullptr); if (has_float) { - std::swap( ptile->rect.fp, tmpibuf->rect_float); + std::swap(ptile->rect.fp, tmpibuf->rect_float); } else { - std::swap(ptile->rect.uint, tmpibuf->rect); + std::swap(ptile->rect.uint, tmpibuf->rect); } IMB_rectcpy(ibuf, @@ -315,10 +315,10 @@ static void ptile_restore_runtime_map(PaintTileMap *paint_tile_map) ED_IMAGE_UNDO_TILE_SIZE); if (has_float) { - std::swap( ptile->rect.fp, tmpibuf->rect_float); + std::swap(ptile->rect.fp, tmpibuf->rect_float); } else { - std::swap(ptile->rect.uint, tmpibuf->rect); + std::swap(ptile->rect.uint, tmpibuf->rect); } /* Force OpenGL reload (maybe partial update will operate better?) */ @@ -380,19 +380,19 @@ static void utile_init_from_imbuf( const bool has_float = ibuf->rect_float; if (has_float) { - std::swap( utile->rect.fp, tmpibuf->rect_float); + std::swap(utile->rect.fp, tmpibuf->rect_float); } else { - std::swap(utile->rect.uint_ptr, tmpibuf->rect); + std::swap(utile->rect.uint_ptr, tmpibuf->rect); } IMB_rectcpy(tmpibuf, ibuf, 0, 0, x, y, ED_IMAGE_UNDO_TILE_SIZE, ED_IMAGE_UNDO_TILE_SIZE); if (has_float) { - std::swap( utile->rect.fp, tmpibuf->rect_float); + std::swap(utile->rect.fp, tmpibuf->rect_float); } else { - std::swap(utile->rect.uint_ptr, tmpibuf->rect); + std::swap(utile->rect.uint_ptr, tmpibuf->rect); } } diff --git a/source/blender/editors/space_node/node_gizmo.cc b/source/blender/editors/space_node/node_gizmo.cc index a55960b5583..f2e788fce93 100644 --- a/source/blender/editors/space_node/node_gizmo.cc +++ b/source/blender/editors/space_node/node_gizmo.cc @@ -285,10 +285,10 @@ static void gizmo_node_crop_prop_matrix_set(const wmGizmo *gz, rct_isect.ymax = 1; BLI_rctf_isect(&rct_isect, &rct, &rct); if (nx) { - std::swap( rct.xmin, rct.xmax); + std::swap(rct.xmin, rct.xmax); } if (ny) { - std::swap( rct.ymin, rct.ymax); + std::swap(rct.ymin, rct.ymax); } two_xy_from_rect(nxy, &rct, dims, is_relative); gizmo_node_crop_update(crop_group); diff --git a/source/blender/editors/transform/transform_convert_node.cc b/source/blender/editors/transform/transform_convert_node.cc index e49ec77fdbf..1c35323a154 100644 --- a/source/blender/editors/transform/transform_convert_node.cc +++ b/source/blender/editors/transform/transform_convert_node.cc @@ -156,7 +156,8 @@ static void node_snap_grid_apply(TransInfo *t) { using namespace blender; - if (!(transform_snap_is_active(t) && (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) { + if (!(transform_snap_is_active(t) && + (t->tsnap.mode & (SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)))) { return; } diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc index 618bcbd95e8..145be5a1b8a 100644 --- a/source/blender/geometry/intern/mesh_merge_by_distance.cc +++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc @@ -1654,7 +1654,7 @@ std::optional mesh_merge_by_distance_connected(const Mesh &mesh, continue; } if (v1 > v2) { - std::swap( v1, v2); + std::swap(v1, v2); } WeldVertexCluster *v1_cluster = &vert_clusters[v1]; WeldVertexCluster *v2_cluster = &vert_clusters[v2]; diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index 357b818bbdc..68c8dd8c18d 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -1878,7 +1878,7 @@ static void lineart_edge_neighbor_init_task(void *__restrict userdata, adj_e->v1 = mloop[looptri->tri[i % 3]].v; adj_e->v2 = mloop[looptri->tri[(i + 1) % 3]].v; if (adj_e->v1 > adj_e->v2) { - std::swap( adj_e->v1, adj_e->v2); + std::swap(adj_e->v1, adj_e->v2); } edge_nabr->e = -1; @@ -3267,7 +3267,7 @@ static void lineart_add_isec_thread(LineartIsecThread *th, isec_single->tri1 = tri1; isec_single->tri2 = tri2; if (tri1->target_reference > tri2->target_reference) { - std::swap( isec_single->tri1, isec_single->tri2); + std::swap(isec_single->tri1, isec_single->tri2); } th->current++; } diff --git a/source/blender/render/intern/multires_bake.cc b/source/blender/render/intern/multires_bake.cc index 5f27a1b9dc7..34d6a5312f7 100644 --- a/source/blender/render/intern/multires_bake.cc +++ b/source/blender/render/intern/multires_bake.cc @@ -259,7 +259,7 @@ static void rasterize_half(const MBakeRast *bake_rast, float x_r = l_stable != 0 ? (s0_l + (((s1_l - s0_l) * (y - t0_l)) / (t1_l - t0_l))) : s0_l; if (is_mid_right != 0) { - std::swap( x_l, x_r); + std::swap(x_l, x_r); } iXl = int(ceilf(x_l)); @@ -298,17 +298,17 @@ static void bake_rasterize(const MBakeRast *bake_rast, /* sort by T */ if (tlo > tmi && tlo > thi) { - std::swap( shi, slo); - std::swap( thi, tlo); + std::swap(shi, slo); + std::swap(thi, tlo); } else if (tmi > thi) { - std::swap( shi, smi); - std::swap( thi, tmi); + std::swap(shi, smi); + std::swap(thi, tmi); } if (tlo > tmi) { - std::swap( slo, smi); - std::swap( tlo, tmi); + std::swap(slo, smi); + std::swap(tlo, tmi); } /* check if mid point is to the left or to the right of the lo-hi edge */ diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index 1af97196acd..49d1a2feb43 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -4426,7 +4426,7 @@ static void wm_event_get_keymap_from_toolsystem_ex(wmWindowManager *wm, if (is_gizmo_visible && !is_gizmo_highlight) { if (keymap_id_list_len == 2) { - std::swap(keymap_id_list[0], keymap_id_list[1]); + std::swap(keymap_id_list[0], keymap_id_list[1]); } } From 05ddc7daa23ec57a59156db4ebf5f0ba72a668b0 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 9 Jan 2023 23:29:58 -0500 Subject: [PATCH 0548/1522] Nodes: Avoid small allocations for internal links Since internal links are only runtime data, we have the flexibility to allocating every link individually. Instead we can store links directly in the node runtime vector. This allows avoiding many small allocations when copying and changing node trees. In the future we could use a smaller type like a pair of sockets instead of `bNodeLink` to save memory. Differential Revision: https://developer.blender.org/D16960 --- source/blender/blenkernel/BKE_node.h | 2 +- source/blender/blenkernel/BKE_node_runtime.hh | 4 +-- source/blender/blenkernel/intern/node.cc | 36 +++++++------------ .../blender/blenkernel/intern/node_runtime.cc | 4 +-- .../blenkernel/intern/node_tree_update.cc | 20 +++++------ .../compositor/intern/COM_NodeGraph.cc | 4 +-- .../blender/editors/space_node/node_draw.cc | 6 ++-- source/blender/makesdna/DNA_node_types.h | 2 +- source/blender/makesrna/intern/rna_nodetree.c | 6 ++-- .../blender/nodes/intern/derived_node_tree.cc | 6 ++-- .../intern/geometry_nodes_lazy_function.cc | 10 +++--- source/blender/nodes/intern/node_exec.cc | 14 ++++---- source/blender/nodes/intern/node_socket.cc | 10 +++--- 13 files changed, 56 insertions(+), 68 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 47e198c9a12..3cb577fb92e 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -690,7 +690,7 @@ void nodeRemoveNode(struct Main *bmain, void nodeDimensionsGet(const struct bNode *node, float *r_width, float *r_height); void nodeTagUpdateID(struct bNode *node); -void nodeInternalLinks(struct bNode *node, struct bNodeLink ***r_links, int *r_len); +void nodeInternalLinks(struct bNode *node, struct bNodeLink **r_links, int *r_len); #ifdef __cplusplus diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 6146e8ea7ae..c5322b7c6ba 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -254,7 +254,7 @@ class bNodeRuntime : NonCopyable, NonMovable { float anim_ofsx; /** List of cached internal links (input to output), for muted nodes and operators. */ - Vector internal_links; + Vector internal_links; /** Eagerly maintained cache of the node's index in the tree. */ int index_in_tree = -1; @@ -626,7 +626,7 @@ inline bool bNode::is_group_output() const return this->type == NODE_GROUP_OUTPUT; } -inline blender::Span bNode::internal_links() const +inline blender::Span bNode::internal_links() const { return this->runtime->internal_links; } diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 0eb5889da65..e42a974eba2 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -1959,10 +1959,10 @@ void nodeRemoveSocketEx(bNodeTree *ntree, bNode *node, bNodeSocket *sock, bool d } } - for (bNodeLink *link : node->runtime->internal_links) { - if (link->fromsock == sock || link->tosock == sock) { - node->runtime->internal_links.remove_first_occurrence_and_reorder(link); - MEM_freeN(link); + for (const int64_t i : node->runtime->internal_links.index_range()) { + const bNodeLink &link = node->runtime->internal_links[i]; + if (link.fromsock == sock || link.tosock == sock) { + node->runtime->internal_links.remove_and_reorder(i); BKE_ntree_update_tag_node_internal_link(ntree, node); break; } @@ -1986,9 +1986,6 @@ void nodeRemoveAllSockets(bNodeTree *ntree, bNode *node) } } - for (bNodeLink *link : node->runtime->internal_links) { - MEM_freeN(link); - } node->runtime->internal_links.clear(); LISTBASE_FOREACH_MUTABLE (bNodeSocket *, sock, &node->inputs) { @@ -2312,14 +2309,12 @@ bNode *node_copy_with_mapping(bNodeTree *dst_tree, node_dst->prop = IDP_CopyProperty_ex(node_src.prop, flag); } - node_dst->runtime->internal_links.clear(); - for (const bNodeLink *src_link : node_src.runtime->internal_links) { - bNodeLink *dst_link = (bNodeLink *)MEM_dupallocN(src_link); - dst_link->fromnode = node_dst; - dst_link->tonode = node_dst; - dst_link->fromsock = socket_map.lookup(src_link->fromsock); - dst_link->tosock = socket_map.lookup(src_link->tosock); - node_dst->runtime->internal_links.append(dst_link); + node_dst->runtime->internal_links = node_src.runtime->internal_links; + for (bNodeLink &dst_link : node_dst->runtime->internal_links) { + dst_link.fromnode = node_dst; + dst_link.tonode = node_dst; + dst_link.fromsock = socket_map.lookup(dst_link.fromsock); + dst_link.tosock = socket_map.lookup(dst_link.tosock); } if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) { @@ -2474,8 +2469,8 @@ static void adjust_multi_input_indices_after_removed_link(bNodeTree *ntree, void nodeInternalRelink(bNodeTree *ntree, bNode *node) { /* store link pointers in output sockets, for efficient lookup */ - for (bNodeLink *link : node->runtime->internal_links) { - link->tosock->link = link; + for (bNodeLink &link : node->runtime->internal_links) { + link.tosock->link = &link; } /* redirect downstream links */ @@ -2989,11 +2984,6 @@ void node_free_node(bNodeTree *ntree, bNode *node) MEM_freeN(sock); } - for (bNodeLink *link : node->runtime->internal_links) { - MEM_freeN(link); - } - node->runtime->internal_links.clear(); - if (node->prop) { /* Remember, no ID user refcount management here! */ IDP_FreePropertyContent_ex(node->prop, false); @@ -3644,7 +3634,7 @@ void nodeTagUpdateID(bNode *node) node->runtime->update |= NODE_UPDATE_ID; } -void nodeInternalLinks(bNode *node, bNodeLink ***r_links, int *r_len) +void nodeInternalLinks(bNode *node, bNodeLink **r_links, int *r_len) { *r_links = node->runtime->internal_links.data(); *r_len = node->runtime->internal_links.size(); diff --git a/source/blender/blenkernel/intern/node_runtime.cc b/source/blender/blenkernel/intern/node_runtime.cc index d3b16d4c1a5..dc24e5ddbc4 100644 --- a/source/blender/blenkernel/intern/node_runtime.cc +++ b/source/blender/blenkernel/intern/node_runtime.cc @@ -95,8 +95,8 @@ static void update_internal_link_inputs(const bNodeTree &ntree) for (bNodeSocket *socket : node->runtime->outputs) { socket->runtime->internal_link_input = nullptr; } - for (bNodeLink *link : node->runtime->internal_links) { - link->tosock->runtime->internal_link_input = link->fromsock; + for (bNodeLink &link : node->runtime->internal_links) { + link.tosock->runtime->internal_link_input = link.fromsock; } } } diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc index 93e8f24787a..397556e23fc 100644 --- a/source/blender/blenkernel/intern/node_tree_update.cc +++ b/source/blender/blenkernel/intern/node_tree_update.cc @@ -635,8 +635,8 @@ class NodeTreeMainUpdater { const bNodeSocket *from_socket = item.first; const bNodeSocket *to_socket = item.second; bool found = false; - for (const bNodeLink *internal_link : node->runtime->internal_links) { - if (from_socket == internal_link->fromsock && to_socket == internal_link->tosock) { + for (const bNodeLink &internal_link : node->runtime->internal_links) { + if (from_socket == internal_link.fromsock && to_socket == internal_link.tosock) { found = true; } } @@ -682,19 +682,17 @@ class NodeTreeMainUpdater { bNode &node, Span> links) { - for (bNodeLink *link : node.runtime->internal_links) { - MEM_freeN(link); - } node.runtime->internal_links.clear(); + node.runtime->internal_links.reserve(links.size()); for (const auto &item : links) { bNodeSocket *from_socket = item.first; bNodeSocket *to_socket = item.second; - bNodeLink *link = MEM_cnew(__func__); - link->fromnode = &node; - link->fromsock = from_socket; - link->tonode = &node; - link->tosock = to_socket; - link->flag |= NODE_LINK_VALID; + bNodeLink link{}; + link.fromnode = &node; + link.fromsock = from_socket; + link.tonode = &node; + link.tosock = to_socket; + link.flag |= NODE_LINK_VALID; node.runtime->internal_links.append(link); } BKE_ntree_update_tag_node_internal_link(&ntree, &node); diff --git a/source/blender/compositor/intern/COM_NodeGraph.cc b/source/blender/compositor/intern/COM_NodeGraph.cc index 34a145f6bf5..c4f840cde4e 100644 --- a/source/blender/compositor/intern/COM_NodeGraph.cc +++ b/source/blender/compositor/intern/COM_NodeGraph.cc @@ -181,8 +181,8 @@ void NodeGraph::add_proxies_mute(bNodeTree *b_ntree, bNodeInstanceKey key, bool is_active_group) { - for (const bNodeLink *b_link : b_node->internal_links()) { - SocketProxyNode *proxy = new SocketProxyNode(b_node, b_link->fromsock, b_link->tosock, false); + for (const bNodeLink &b_link : b_node->internal_links()) { + SocketProxyNode *proxy = new SocketProxyNode(b_node, b_link.fromsock, b_link.tosock, false); add_node(proxy, b_ntree, key, is_active_group); } } diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index 098c08686b4..ef284c3e3bf 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -675,9 +675,9 @@ static void node_draw_mute_line(const bContext &C, { GPU_blend(GPU_BLEND_ALPHA); - for (const bNodeLink *link : node.internal_links()) { - if (!nodeLinkIsHidden(link)) { - node_draw_link_bezier(C, v2d, snode, *link, TH_WIRE_INNER, TH_WIRE_INNER, TH_WIRE, false); + for (const bNodeLink &link : node.internal_links()) { + if (!nodeLinkIsHidden(&link)) { + node_draw_link_bezier(C, v2d, snode, link, TH_WIRE_INNER, TH_WIRE_INNER, TH_WIRE, false); } } diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 7053836f7ff..2ddf166566a 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -375,7 +375,7 @@ typedef struct bNode { bool is_group_output() const; const blender::nodes::NodeDeclaration *declaration() const; /** A span containing all internal links when the node is muted. */ - blender::Span internal_links() const; + blender::Span internal_links() const; /* The following methods are only available when #bNodeTree.ensure_topology_cache has been * called. */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 300bca9e369..f895a00e23a 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -2377,10 +2377,10 @@ static void rna_Node_parent_set(PointerRNA *ptr, static void rna_Node_internal_links_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { bNode *node = ptr->data; - bNodeLink **begin; + bNodeLink *begin; int len; nodeInternalLinks(node, &begin, &len); - rna_iterator_array_begin(iter, begin, sizeof(bNodeLink *), len, false, NULL); + rna_iterator_array_begin(iter, begin, sizeof(bNodeLink), len, false, NULL); } static bool rna_Node_parent_poll(PointerRNA *ptr, PointerRNA value) @@ -12203,7 +12203,7 @@ static void rna_def_node(BlenderRNA *brna) "rna_Node_internal_links_begin", "rna_iterator_array_next", "rna_iterator_array_end", - "rna_iterator_array_dereference_get", + "rna_iterator_array_get", NULL, NULL, NULL, diff --git a/source/blender/nodes/intern/derived_node_tree.cc b/source/blender/nodes/intern/derived_node_tree.cc index 9b8a9f2401a..ff978efc14a 100644 --- a/source/blender/nodes/intern/derived_node_tree.cc +++ b/source/blender/nodes/intern/derived_node_tree.cc @@ -236,8 +236,8 @@ void DOutputSocket::foreach_target_socket(ForeachTargetSocketFn target_fn, path_info.sockets.pop_last(); } else if (linked_node->is_muted()) { - for (const bNodeLink *internal_link : linked_node->internal_links()) { - if (internal_link->fromsock != linked_socket.bsocket()) { + for (const bNodeLink &internal_link : linked_node->internal_links()) { + if (internal_link.fromsock != linked_socket.bsocket()) { continue; } /* The internal link only forwards the first incoming link. */ @@ -247,7 +247,7 @@ void DOutputSocket::foreach_target_socket(ForeachTargetSocketFn target_fn, } } const DInputSocket mute_input = linked_socket; - const DOutputSocket mute_output{context_, internal_link->tosock}; + const DOutputSocket mute_output{context_, internal_link.tosock}; path_info.sockets.append(mute_input); path_info.sockets.append(mute_output); mute_output.foreach_target_socket(target_fn, path_info); diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index bb4337a75eb..4aec8d405ea 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -400,9 +400,9 @@ class LazyFunctionForMutedNode : public LazyFunction { input_by_output_index_.reinitialize(outputs_.size()); input_by_output_index_.fill(-1); - for (const bNodeLink *internal_link : node.internal_links()) { - const int input_i = r_used_inputs.first_index_of_try(internal_link->fromsock); - const int output_i = r_used_outputs.first_index_of_try(internal_link->tosock); + for (const bNodeLink &internal_link : node.internal_links()) { + const int input_i = r_used_inputs.first_index_of_try(internal_link.fromsock); + const int output_i = r_used_outputs.first_index_of_try(internal_link.tosock); if (ELEM(-1, input_i, output_i)) { continue; } @@ -1945,8 +1945,8 @@ struct GeometryNodesLazyFunctionGraphBuilder { { /* Find all outputs that use a specific input. */ MultiValueMap outputs_by_input; - for (const bNodeLink *blink : bnode.internal_links()) { - outputs_by_input.add(blink->fromsock, blink->tosock); + for (const bNodeLink &blink : bnode.internal_links()) { + outputs_by_input.add(blink.fromsock, blink.tosock); } for (const auto item : outputs_by_input.items()) { const bNodeSocket &input_bsocket = *item.key; diff --git a/source/blender/nodes/intern/node_exec.cc b/source/blender/nodes/intern/node_exec.cc index 3d8eafec75a..da8e2148ab0 100644 --- a/source/blender/nodes/intern/node_exec.cc +++ b/source/blender/nodes/intern/node_exec.cc @@ -71,18 +71,18 @@ static void node_init_input_index(bNodeSocket *sock, int *index) static void node_init_output_index_muted(bNodeSocket *sock, int *index, - const blender::Span internal_links) + const blender::MutableSpan internal_links) { - bNodeLink *link; + const bNodeLink *link; /* copy the stack index from internally connected input to skip the node */ - for (bNodeLink *iter_link : internal_links) { - if (iter_link->tosock == sock) { - sock->stack_index = iter_link->fromsock->stack_index; + for (bNodeLink &iter_link : internal_links) { + if (iter_link.tosock == sock) { + sock->stack_index = iter_link.fromsock->stack_index; /* set the link pointer to indicate that this socket * should not overwrite the stack value! */ - sock->link = iter_link; - link = iter_link; + sock->link = &iter_link; + link = &iter_link; break; } } diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index 11fc900ea94..9110813b4d7 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -220,12 +220,12 @@ static void refresh_socket_list(bNodeTree &ntree, link->tosock = new_socket; } } - for (bNodeLink *internal_link : node.runtime->internal_links) { - if (internal_link->fromsock == old_socket_with_same_identifier) { - internal_link->fromsock = new_socket; + for (bNodeLink &internal_link : node.runtime->internal_links) { + if (internal_link.fromsock == old_socket_with_same_identifier) { + internal_link.fromsock = new_socket; } - else if (internal_link->tosock == old_socket_with_same_identifier) { - internal_link->tosock = new_socket; + else if (internal_link.tosock == old_socket_with_same_identifier) { + internal_link.tosock = new_socket; } } } From 1af62cb3bf46f0cd328ab0840a1363eca938c628 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 10 Jan 2023 00:10:43 -0500 Subject: [PATCH 0549/1522] Mesh: Move positions to a generic attribute **Changes** As described in T93602, this patch removes all use of the `MVert` struct, replacing it with a generic named attribute with the name `"position"`, consistent with other geometry types. Variable names have been changed from `verts` to `positions`, to align with the attribute name and the more generic design (positions are not vertices, they are just an attribute stored on the point domain). This change is made possible by previous commits that moved all other data out of `MVert` to runtime data or other generic attributes. What remains is mostly a simple type change. Though, the type still shows up 859 times, so the patch is quite large. One compromise is that now `CD_MASK_BAREMESH` now contains `CD_PROP_FLOAT3`. With the general move towards generic attributes over custom data types, we are removing use of these type masks anyway. **Benefits** The most obvious benefit is reduced memory usage and the benefits that brings in memory-bound situations. `float3` is only 3 bytes, in comparison to `MVert` which was 4. When there are millions of vertices this starts to matter more. The other benefits come from using a more generic type. Instead of writing algorithms specifically for `MVert`, code can just use arrays of vectors. This will allow eliminating many temporary arrays or wrappers used to extract positions. Many possible improvements aren't implemented in this patch, though I did switch simplify or remove the process of creating temporary position arrays in a few places. The design clarity that "positions are just another attribute" brings allows removing explicit copying of vertices in some procedural operations-- they are just processed like most other attributes. **Performance** This touches so many areas that it's hard to benchmark exhaustively, but I observed some areas as examples. * The mesh line node with 4 million count was 1.5x (8ms to 12ms) faster. * The Spring splash screen went from ~4.3 to ~4.5 fps. * The subdivision surface modifier/node was slightly faster RNA access through Python may be slightly slower, since now we need a name lookup instead of just a custom data type lookup for each index. **Future Improvements** * Remove uses of "vert_coords" functions: * `BKE_mesh_vert_coords_alloc` * `BKE_mesh_vert_coords_get` * `BKE_mesh_vert_coords_apply{_with_mat4}` * Remove more hidden copying of positions * General simplification now possible in many areas * Convert more code to C++ to use `float3` instead of `float[3]` * Currently `reinterpret_cast` is used for those C-API functions Differential Revision: https://developer.blender.org/D15982 --- intern/cycles/blender/mesh.cpp | 18 +- release/datafiles/locale | 2 +- release/scripts/addons | 2 +- .../startup/bl_ui/properties_data_mesh.py | 2 +- source/blender/blenkernel/BKE_DerivedMesh.h | 8 +- source/blender/blenkernel/BKE_bvhutils.h | 9 +- source/blender/blenkernel/BKE_collision.h | 7 +- source/blender/blenkernel/BKE_key.h | 5 +- source/blender/blenkernel/BKE_mesh.h | 52 ++--- source/blender/blenkernel/BKE_mesh_fair.h | 6 +- .../blenkernel/BKE_mesh_legacy_convert.h | 9 + source/blender/blenkernel/BKE_mesh_mapping.h | 8 +- source/blender/blenkernel/BKE_mesh_remap.h | 13 +- source/blender/blenkernel/BKE_mesh_sample.hh | 2 +- source/blender/blenkernel/BKE_mesh_tangent.h | 4 +- source/blender/blenkernel/BKE_mesh_types.h | 2 +- source/blender/blenkernel/BKE_multires.h | 1 - source/blender/blenkernel/BKE_paint.h | 3 +- source/blender/blenkernel/BKE_particle.h | 3 +- source/blender/blenkernel/BKE_pbvh.h | 19 +- source/blender/blenkernel/BKE_subdiv.h | 2 +- source/blender/blenkernel/BKE_subdiv_mesh.h | 3 +- .../blender/blenkernel/BKE_volume_to_mesh.hh | 2 +- .../blender/blenkernel/intern/DerivedMesh.cc | 44 ++--- source/blender/blenkernel/intern/attribute.cc | 3 + .../intern/attribute_access_intern.hh | 3 +- source/blender/blenkernel/intern/bvhutils.cc | 117 ++++++------ .../blender/blenkernel/intern/cdderivedmesh.c | 18 +- source/blender/blenkernel/intern/cloth.cc | 25 +-- source/blender/blenkernel/intern/collision.c | 78 ++++---- source/blender/blenkernel/intern/constraint.c | 5 +- .../blender/blenkernel/intern/crazyspace.cc | 8 +- .../intern/curve_to_mesh_convert.cc | 13 +- .../blender/blenkernel/intern/customdata.cc | 13 +- .../blenkernel/intern/data_transfer.cc | 28 +-- .../blender/blenkernel/intern/dynamicpaint.c | 104 +++++----- source/blender/blenkernel/intern/effect.c | 10 +- source/blender/blenkernel/intern/fluid.c | 94 ++++----- .../intern/geometry_component_mesh.cc | 33 ++-- .../blender/blenkernel/intern/gpencil_geom.cc | 19 +- source/blender/blenkernel/intern/key.cc | 44 ++--- .../blenkernel/intern/mball_tessellate.cc | 9 +- source/blender/blenkernel/intern/mesh.cc | 108 +++++------ .../blenkernel/intern/mesh_boolean_convert.cc | 61 +++--- .../blender/blenkernel/intern/mesh_convert.cc | 45 ++--- .../blenkernel/intern/mesh_evaluate.cc | 127 +++++++------ source/blender/blenkernel/intern/mesh_fair.cc | 19 +- .../blenkernel/intern/mesh_iterators.cc | 41 ++-- .../blenkernel/intern/mesh_legacy_convert.cc | 90 +++++++-- .../blender/blenkernel/intern/mesh_mapping.cc | 15 +- source/blender/blenkernel/intern/mesh_merge.c | 20 +- .../blender/blenkernel/intern/mesh_mirror.cc | 34 ++-- .../blender/blenkernel/intern/mesh_normals.cc | 179 +++++++----------- .../blender/blenkernel/intern/mesh_remap.cc | 109 +++++------ .../blenkernel/intern/mesh_remesh_voxel.cc | 46 ++--- .../blender/blenkernel/intern/mesh_runtime.cc | 19 +- .../blender/blenkernel/intern/mesh_sample.cc | 36 ++-- .../blender/blenkernel/intern/mesh_tangent.cc | 40 ++-- .../blenkernel/intern/mesh_tessellate.cc | 62 +++--- .../blenkernel/intern/mesh_validate.cc | 24 +-- .../blender/blenkernel/intern/mesh_wrapper.cc | 11 +- source/blender/blenkernel/intern/modifier.cc | 4 +- source/blender/blenkernel/intern/multires.cc | 2 +- .../blenkernel/intern/multires_reshape.h | 3 +- .../intern/multires_reshape_apply_base.c | 21 +- .../intern/multires_reshape_subdivide.c | 10 +- .../blenkernel/intern/multires_reshape_util.c | 8 +- source/blender/blenkernel/intern/object.cc | 34 ++-- .../blender/blenkernel/intern/object_dupli.cc | 34 ++-- source/blender/blenkernel/intern/paint.cc | 23 ++- source/blender/blenkernel/intern/particle.cc | 61 +++--- .../blenkernel/intern/particle_distribute.c | 69 +++---- .../blenkernel/intern/particle_system.c | 35 ++-- source/blender/blenkernel/intern/pbvh.c | 87 ++++----- .../blender/blenkernel/intern/pbvh_intern.h | 5 +- source/blender/blenkernel/intern/rigidbody.c | 27 +-- .../blender/blenkernel/intern/shrinkwrap.cc | 50 ++--- source/blender/blenkernel/intern/softbody.c | 160 ++++++++-------- .../blenkernel/intern/subdiv_converter_mesh.c | 4 +- .../blender/blenkernel/intern/subdiv_eval.c | 5 +- .../blender/blenkernel/intern/subdiv_mesh.cc | 96 ++++------ .../blender/blenkernel/intern/subsurf_ccg.c | 24 ++- .../blenkernel/intern/volume_to_mesh.cc | 9 +- .../blenloader/intern/versioning_250.c | 4 +- .../blenloader/intern/versioning_290.c | 2 +- .../blenloader/intern/versioning_400.cc | 1 + .../bmesh/intern/bmesh_mesh_convert.cc | 45 +++-- .../blender/bmesh/intern/bmesh_mesh_convert.h | 4 +- source/blender/draw/DRW_pbvh.h | 3 +- .../draw/intern/draw_cache_extract_mesh.cc | 6 +- .../draw_cache_extract_mesh_render_data.cc | 4 +- .../intern/draw_cache_impl_subdivision.cc | 35 ++-- source/blender/draw/intern/draw_pbvh.cc | 5 +- .../intern/mesh_extractors/extract_mesh.hh | 9 +- .../extract_mesh_ibo_points.cc | 1 - .../extract_mesh_vbo_edge_fac.cc | 8 +- .../extract_mesh_vbo_edit_data.cc | 1 - .../extract_mesh_vbo_edituv_stretch_angle.cc | 21 +- .../extract_mesh_vbo_edituv_stretch_area.cc | 3 +- .../extract_mesh_vbo_fdots_pos.cc | 6 +- .../extract_mesh_vbo_mesh_analysis.cc | 35 ++-- .../extract_mesh_vbo_pos_nor.cc | 20 +- .../extract_mesh_vbo_select_idx.cc | 1 - .../mesh_extractors/extract_mesh_vbo_tan.cc | 7 +- .../editors/armature/armature_skinning.c | 4 +- .../blender/editors/armature/meshlaplacian.c | 9 +- .../editors/curves/intern/curves_ops.cc | 50 ++--- source/blender/editors/include/ED_view3d.h | 12 +- source/blender/editors/mesh/editface.cc | 4 +- source/blender/editors/mesh/mesh_data.cc | 6 +- source/blender/editors/mesh/mesh_mirror.c | 4 +- source/blender/editors/mesh/meshtools.cc | 59 +++--- .../blender/editors/object/object_bake_api.c | 2 +- .../blender/editors/object/object_modifier.cc | 32 ++-- .../blender/editors/object/object_remesh.cc | 7 +- .../blender/editors/object/object_vgroup.cc | 33 ++-- .../blender/editors/physics/particle_edit.c | 26 +-- .../blender/editors/physics/particle_object.c | 15 +- .../editors/sculpt_paint/curves_sculpt_add.cc | 12 +- .../sculpt_paint/curves_sculpt_puff.cc | 10 +- .../sculpt_paint/curves_sculpt_slide.cc | 14 +- .../blender/editors/sculpt_paint/paint_hide.c | 8 +- .../editors/sculpt_paint/paint_image_proj.cc | 56 +++--- .../blender/editors/sculpt_paint/paint_mask.c | 12 +- .../editors/sculpt_paint/paint_utils.c | 4 +- .../editors/sculpt_paint/paint_vertex.cc | 12 +- source/blender/editors/sculpt_paint/sculpt.cc | 42 ++-- .../editors/sculpt_paint/sculpt_boundary.c | 12 +- .../editors/sculpt_paint/sculpt_brush_types.c | 46 ++--- .../editors/sculpt_paint/sculpt_cloth.c | 10 +- .../editors/sculpt_paint/sculpt_dyntopo.c | 2 +- .../editors/sculpt_paint/sculpt_face_set.cc | 10 +- .../editors/sculpt_paint/sculpt_filter_mesh.c | 2 +- .../editors/sculpt_paint/sculpt_geodesic.c | 23 ++- .../editors/sculpt_paint/sculpt_intern.h | 2 +- .../sculpt_paint/sculpt_multiplane_scrape.c | 2 +- .../sculpt_paint/sculpt_paint_image.cc | 29 +-- .../editors/sculpt_paint/sculpt_pose.c | 2 +- .../editors/sculpt_paint/sculpt_smooth.c | 6 +- .../editors/sculpt_paint/sculpt_transform.c | 4 +- .../editors/sculpt_paint/sculpt_undo.c | 22 +-- .../blender/editors/space_view3d/drawobject.c | 14 +- .../editors/space_view3d/view3d_iterators.cc | 18 +- .../editors/space_view3d/view3d_select.cc | 3 - .../transform/transform_snap_object.cc | 21 +- .../editors/uvedit/uvedit_unwrap_ops.c | 10 +- .../blender_interface/BlenderFileLoader.cpp | 23 ++- .../BlenderStrokeRenderer.cpp | 27 ++- .../geometry/intern/add_curves_on_mesh.cc | 8 +- .../geometry/intern/mesh_merge_by_distance.cc | 28 +-- .../geometry/intern/mesh_primitive_cuboid.cc | 14 +- .../geometry/intern/mesh_to_curve_convert.cc | 17 +- .../blender/geometry/intern/mesh_to_volume.cc | 12 +- .../geometry/intern/realize_instances.cc | 23 +-- .../intern/lineart/lineart_cpu.cc | 15 +- .../gpu/intern/gpu_shader_builder_stubs.cc | 3 +- .../io/alembic/exporter/abc_writer_hair.cc | 8 +- .../io/alembic/exporter/abc_writer_mesh.cc | 4 +- .../io/alembic/intern/abc_customdata.h | 5 +- .../io/alembic/intern/abc_reader_mesh.cc | 16 +- .../blender/io/collada/GeometryExporter.cpp | 30 +-- source/blender/io/collada/MeshImporter.cpp | 10 +- .../io/stl/importer/stl_import_mesh.cc | 8 +- .../blender/io/usd/intern/usd_reader_mesh.cc | 7 +- .../blender/io/usd/intern/usd_writer_mesh.cc | 7 +- .../wavefront_obj/exporter/obj_export_mesh.cc | 13 +- .../wavefront_obj/exporter/obj_export_mesh.hh | 2 +- .../wavefront_obj/importer/obj_import_mesh.cc | 4 +- .../wavefront_obj/tests/obj_importer_tests.cc | 6 +- .../blender/makesdna/DNA_customdata_types.h | 4 +- source/blender/makesdna/DNA_mesh_types.h | 10 +- source/blender/makesdna/DNA_meshdata_types.h | 67 ++++--- source/blender/makesdna/DNA_modifier_types.h | 16 +- .../blender/makesdna/intern/dna_rename_defs.h | 1 + source/blender/makesrna/intern/rna_mesh.c | 49 +++-- source/blender/makesrna/intern/rna_particle.c | 15 +- source/blender/modifiers/intern/MOD_array.cc | 55 +++--- .../blender/modifiers/intern/MOD_boolean.cc | 7 +- source/blender/modifiers/intern/MOD_build.c | 9 - .../blender/modifiers/intern/MOD_collision.c | 25 ++- .../modifiers/intern/MOD_datatransfer.cc | 6 +- .../blender/modifiers/intern/MOD_displace.cc | 4 - source/blender/modifiers/intern/MOD_explode.c | 42 ++-- source/blender/modifiers/intern/MOD_mask.cc | 15 +- .../blender/modifiers/intern/MOD_meshcache.c | 21 +- .../modifiers/intern/MOD_meshsequencecache.cc | 7 +- .../blender/modifiers/intern/MOD_multires.cc | 4 +- .../modifiers/intern/MOD_normal_edit.cc | 23 +-- source/blender/modifiers/intern/MOD_ocean.c | 20 +- .../modifiers/intern/MOD_particleinstance.c | 30 ++- source/blender/modifiers/intern/MOD_remesh.c | 10 +- source/blender/modifiers/intern/MOD_screw.cc | 88 +++------ .../blender/modifiers/intern/MOD_shrinkwrap.c | 6 - source/blender/modifiers/intern/MOD_skin.c | 65 ++++--- .../modifiers/intern/MOD_solidify_extrude.c | 67 +++---- .../intern/MOD_solidify_nonmanifold.c | 20 +- source/blender/modifiers/intern/MOD_surface.c | 17 +- .../modifiers/intern/MOD_surfacedeform.c | 4 +- source/blender/modifiers/intern/MOD_util.cc | 10 +- .../blender/modifiers/intern/MOD_uvproject.cc | 3 +- .../modifiers/intern/MOD_weighted_normal.cc | 32 ++-- .../modifiers/intern/MOD_weightvg_util.c | 2 +- .../geometry/nodes/node_geo_convex_hull.cc | 7 +- .../geometry/nodes/node_geo_curve_fill.cc | 4 +- .../node_geo_deform_curves_on_surface.cc | 16 +- .../nodes/node_geo_delete_geometry.cc | 22 +-- .../node_geo_distribute_points_on_faces.cc | 16 +- .../geometry/nodes/node_geo_dual_mesh.cc | 20 +- .../nodes/node_geo_duplicate_elements.cc | 11 +- .../geometry/nodes/node_geo_extrude_mesh.cc | 39 ++-- .../nodes/node_geo_input_mesh_edge_angle.cc | 38 ++-- .../node_geo_input_mesh_edge_vertices.cc | 8 +- .../nodes/node_geo_input_mesh_face_area.cc | 7 +- .../node_geo_input_mesh_face_is_planar.cc | 6 +- .../nodes/node_geo_mesh_primitive_circle.cc | 6 +- .../nodes/node_geo_mesh_primitive_cone.cc | 18 +- .../nodes/node_geo_mesh_primitive_grid.cc | 14 +- .../nodes/node_geo_mesh_primitive_line.cc | 6 +- .../node_geo_mesh_primitive_uv_sphere.cc | 12 +- .../geometry/nodes/node_geo_sample_nearest.cc | 11 +- .../geometry/nodes/node_geo_scale_elements.cc | 14 +- .../geometry/nodes/node_geo_set_position.cc | 35 ---- .../nodes/node_geo_uv_pack_islands.cc | 4 +- .../geometry/nodes/node_geo_uv_unwrap.cc | 4 +- .../geometry/nodes/node_geo_volume_to_mesh.cc | 4 +- .../python/mathutils/mathutils_bvhtree.c | 6 +- source/blender/render/intern/bake.cc | 42 ++-- source/blender/render/intern/multires_bake.cc | 16 +- .../blender/render/intern/texture_margin.cc | 8 +- .../render/intern/texture_pointdensity.c | 7 +- .../blender/simulation/intern/hair_volume.cpp | 4 +- source/tools | 2 +- 232 files changed, 2391 insertions(+), 2659 deletions(-) diff --git a/intern/cycles/blender/mesh.cpp b/intern/cycles/blender/mesh.cpp index 736b80bacd6..b82ef9bbe78 100644 --- a/intern/cycles/blender/mesh.cpp +++ b/intern/cycles/blender/mesh.cpp @@ -679,7 +679,7 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b if (num_verts == 0) { return; } - const MVert *verts = static_cast(b_mesh.vertices[0].ptr.data); + const float(*positions)[3] = static_cast(b_mesh.vertices[0].ptr.data); /* STEP 1: Find out duplicated vertices and point duplicates to a single * original vertex. @@ -765,10 +765,8 @@ static void attr_create_pointiness(Scene *scene, Mesh *mesh, BL::Mesh &b_mesh, b continue; } visited_edges.insert(v0, v1); - const MVert &b_vert_0 = verts[v0]; - const MVert &b_vert_1 = verts[v1]; - float3 co0 = make_float3(b_vert_0.co[0], b_vert_0.co[1], b_vert_0.co[2]); - float3 co1 = make_float3(b_vert_1.co[0], b_vert_1.co[1], b_vert_1.co[2]); + float3 co0 = make_float3(positions[v0][0], positions[v0][1], positions[v0][2]); + float3 co1 = make_float3(positions[v1][0], positions[v1][1], positions[v1][2]); float3 edge = normalize(co1 - co0); edge_accum[v0] += edge; edge_accum[v1] += -edge; @@ -919,7 +917,7 @@ static void create_mesh(Scene *scene, return; } - const MVert *verts = static_cast(b_mesh.vertices[0].ptr.data); + const float(*positions)[3] = static_cast(b_mesh.vertices[0].ptr.data); if (!subdivision) { numtris = numfaces; @@ -942,8 +940,7 @@ static void create_mesh(Scene *scene, /* create vertex coordinates and normals */ for (int i = 0; i < numverts; i++) { - const MVert &b_vert = verts[i]; - mesh->add_vertex(make_float3(b_vert.co[0], b_vert.co[1], b_vert.co[2])); + mesh->add_vertex(make_float3(positions[i][0], positions[i][1], positions[i][2])); } AttributeSet &attributes = (subdivision) ? mesh->subd_attributes : mesh->attributes; @@ -1252,14 +1249,13 @@ void BlenderSync::sync_mesh_motion(BL::Depsgraph b_depsgraph, float3 *mP = attr_mP->data_float3() + motion_step * numverts; float3 *mN = (attr_mN) ? attr_mN->data_float3() + motion_step * numverts : NULL; - const MVert *verts = static_cast(b_mesh.vertices[0].ptr.data); + const float(*positions)[3] = static_cast(b_mesh.vertices[0].ptr.data); /* NOTE: We don't copy more that existing amount of vertices to prevent * possible memory corruption. */ for (int i = 0; i < std::min(b_verts_num, numverts); i++) { - const MVert &b_vert = verts[i]; - mP[i] = make_float3(b_vert.co[0], b_vert.co[1], b_vert.co[2]); + mP[i] = make_float3(positions[i][0], positions[i][1], positions[i][2]); } if (mN) { const float(*b_vert_normals)[3] = static_cast( diff --git a/release/datafiles/locale b/release/datafiles/locale index 7084c4ecd97..7be7aff5a18 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 7084c4ecd97d93459d9d23fd90f81589b09be5df +Subproject commit 7be7aff5a18c550465b3f7634539ed4168af7c51 diff --git a/release/scripts/addons b/release/scripts/addons index a9d4443c244..c226f867aff 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit a9d4443c244f89399ec4bcc427e05a07950528cc +Subproject commit c226f867affd12881533a54c8c90ac6eebfaca6c diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index bf85c4ac533..b7f7d925c2b 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -605,7 +605,7 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel): colliding_names = [] for collection in ( # Built-in names. - {"position": None, "shade_smooth": None, "normal": None, "crease": None}, + {"shade_smooth": None, "normal": None, "crease": None}, mesh.attributes, mesh.uv_layers, None if ob is None else ob.vertex_groups, diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index cb9c4256e33..967f9ea240c 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -61,7 +61,6 @@ struct CustomData_MeshMasks; struct Depsgraph; struct MEdge; struct MFace; -struct MVert; struct Mesh; struct ModifierData; struct Object; @@ -125,7 +124,10 @@ struct DerivedMesh { * and freed on the next ->release(). consider using getVert/Edge/Face if * you are only interested in a few verts/edges/faces. */ - struct MVert *(*getVertArray)(DerivedMesh *dm); + /** + * \warning The real return type is `float(*)[3]`. + */ + float *(*getVertArray)(DerivedMesh *dm); struct MEdge *(*getEdgeArray)(DerivedMesh *dm); struct MLoop *(*getLoopArray)(DerivedMesh *dm); struct MPoly *(*getPolyArray)(DerivedMesh *dm); @@ -133,7 +135,7 @@ struct DerivedMesh { /** Copy all verts/edges/faces from the derived mesh into * *{vert/edge/face}_r (must point to a buffer large enough) */ - void (*copyVertArray)(DerivedMesh *dm, struct MVert *r_vert); + void (*copyVertArray)(DerivedMesh *dm, float (*r_positions)[3]); void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *r_edge); void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *r_loop); void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *r_poly); diff --git a/source/blender/blenkernel/BKE_bvhutils.h b/source/blender/blenkernel/BKE_bvhutils.h index fdc8f9c270f..67b282ff2ad 100644 --- a/source/blender/blenkernel/BKE_bvhutils.h +++ b/source/blender/blenkernel/BKE_bvhutils.h @@ -25,7 +25,6 @@ extern "C" { struct BMEditMesh; struct MFace; -struct MVert; struct Mesh; struct PointCloud; @@ -59,7 +58,7 @@ typedef struct BVHTreeFromMesh { BVHTree_RayCastCallback raycast_callback; /* Vertex array, so that callbacks have instant access to data. */ - const struct MVert *vert; + const float (*vert_positions)[3]; const struct MEdge *edge; const struct MFace *face; const struct MLoop *loop; @@ -123,7 +122,7 @@ BVHTree *bvhtree_from_editmesh_verts_ex(BVHTreeFromEditMesh *data, * (else will be computed from mask). */ BVHTree *bvhtree_from_mesh_verts_ex(struct BVHTreeFromMesh *data, - const struct MVert *vert, + const float (*vert_positions)[3], int verts_num, const blender::BitVector<> &verts_mask, int verts_num_active, @@ -154,7 +153,7 @@ BVHTree *bvhtree_from_editmesh_edges_ex(BVHTreeFromEditMesh *data, * (else will be computed from mask). */ BVHTree *bvhtree_from_mesh_edges_ex(struct BVHTreeFromMesh *data, - const struct MVert *vert, + const float (*vert_positions)[3], const struct MEdge *edge, int edges_num, const blender::BitVector<> &edges_mask, @@ -181,7 +180,7 @@ BVHTree *bvhtree_from_editmesh_looptri_ex(BVHTreeFromEditMesh *data, * Builds a BVH-tree where nodes are the looptri faces of the given mesh. */ BVHTree *bvhtree_from_mesh_looptri_ex(struct BVHTreeFromMesh *data, - const struct MVert *vert, + const float (*vert_positions)[3], const struct MLoop *mloop, const struct MLoopTri *looptri, int looptri_num, diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h index d36758c9c4d..01e0a0ce062 100644 --- a/source/blender/blenkernel/BKE_collision.h +++ b/source/blender/blenkernel/BKE_collision.h @@ -14,7 +14,6 @@ struct BVHTree; struct Collection; struct CollisionModifierData; struct Depsgraph; -struct MVert; struct MVertTri; struct Object; struct Scene; @@ -90,13 +89,13 @@ typedef struct FaceCollPair { // used in modifier.cc from collision.c ///////////////////////////////////////////////// -struct BVHTree *bvhtree_build_from_mvert(const struct MVert *mvert, +struct BVHTree *bvhtree_build_from_mvert(const float (*positions)[3], const struct MVertTri *tri, int tri_num, float epsilon); void bvhtree_update_from_mvert(struct BVHTree *bvhtree, - const struct MVert *mvert, - const struct MVert *mvert_moving, + const float (*positions)[3], + const float (*positions_moving)[3], const struct MVertTri *tri, int tri_num, bool moving); diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index 7fb3e71ad3d..d89ef744449 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -13,7 +13,6 @@ struct Lattice; struct ListBase; struct Main; struct Mesh; -struct MVert; struct Object; /* Kernel prototypes */ @@ -132,7 +131,9 @@ void BKE_keyblock_update_from_mesh(const struct Mesh *me, struct KeyBlock *kb); void BKE_keyblock_convert_from_mesh(const struct Mesh *me, const struct Key *key, struct KeyBlock *kb); -void BKE_keyblock_convert_to_mesh(const struct KeyBlock *kb, struct MVert *mvert, int totvert); +void BKE_keyblock_convert_to_mesh(const struct KeyBlock *kb, + float (*vert_positions)[3], + int totvert); /** * Computes normals (vertices, polygons and/or loops ones) of given mesh for given shape key. diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 066d302fdd1..cd291d4a42d 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -38,7 +38,6 @@ struct MLoop; struct MLoopTri; struct MLoopUV; struct MPoly; -struct MVert; struct Main; struct MemArena; struct Mesh; @@ -193,6 +192,8 @@ struct Mesh *BKE_mesh_new_nomain_from_curve(const struct Object *ob); struct Mesh *BKE_mesh_new_nomain_from_curve_displist(const struct Object *ob, const struct ListBase *dispbase); +bool BKE_mesh_attribute_required(const char *name); + bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me); bool BKE_mesh_clear_facemap_customdata(struct Mesh *me); @@ -324,7 +325,7 @@ void BKE_mesh_vert_coords_apply(struct Mesh *mesh, const float (*vert_coords)[3] */ void BKE_mesh_recalc_looptri(const struct MLoop *mloop, const struct MPoly *mpoly, - const struct MVert *mvert, + const float (*vert_positions)[3], int totloop, int totpoly, struct MLoopTri *mlooptri); @@ -338,7 +339,7 @@ void BKE_mesh_recalc_looptri(const struct MLoop *mloop, */ void BKE_mesh_recalc_looptri_with_normals(const struct MLoop *mloop, const struct MPoly *mpoly, - const struct MVert *mvert, + const float (*vert_positions)[3], int totloop, int totpoly, struct MLoopTri *mlooptri, @@ -420,12 +421,8 @@ bool BKE_mesh_poly_normals_are_dirty(const struct Mesh *mesh); void BKE_mesh_calc_poly_normal(const struct MPoly *mpoly, const struct MLoop *loopstart, - const struct MVert *mvarray, + const float (*vert_positions)[3], float r_no[3]); -void BKE_mesh_calc_poly_normal_coords(const struct MPoly *mpoly, - const struct MLoop *loopstart, - const float (*vertex_coords)[3], - float r_no[3]); /** * Calculate face normals directly into a result array. @@ -433,7 +430,7 @@ void BKE_mesh_calc_poly_normal_coords(const struct MPoly *mpoly, * \note Usually #BKE_mesh_poly_normals_ensure is the preferred way to access face normals, * since they may already be calculated and cached on the mesh. */ -void BKE_mesh_calc_normals_poly(const struct MVert *mvert, +void BKE_mesh_calc_normals_poly(const float (*vert_positions)[3], int mvert_len, const struct MLoop *mloop, int mloop_len, @@ -447,7 +444,7 @@ void BKE_mesh_calc_normals_poly(const struct MVert *mvert, * \note Usually #BKE_mesh_vertex_normals_ensure is the preferred way to access vertex normals, * since they may already be calculated and cached on the mesh. */ -void BKE_mesh_calc_normals_poly_and_vertex(const struct MVert *mvert, +void BKE_mesh_calc_normals_poly_and_vertex(const float (*vert_positions)[3], int mvert_len, const struct MLoop *mloop, int mloop_len, @@ -597,7 +594,7 @@ void BKE_lnor_space_custom_normal_to_data(const MLoopNorSpace *lnor_space, * * \param loop_to_poly_map: Optional pre-created map from loops to their polygon. */ -void BKE_mesh_normals_loop_split(const struct MVert *mverts, +void BKE_mesh_normals_loop_split(const float (*vert_positions)[3], const float (*vert_normals)[3], int numVerts, const struct MEdge *medges, @@ -614,7 +611,7 @@ void BKE_mesh_normals_loop_split(const struct MVert *mverts, MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2]); -void BKE_mesh_normals_loop_custom_set(const struct MVert *mverts, +void BKE_mesh_normals_loop_custom_set(const float (*vert_positions)[3], const float (*vert_normals)[3], int numVerts, struct MEdge *medges, @@ -626,7 +623,7 @@ void BKE_mesh_normals_loop_custom_set(const struct MVert *mverts, const float (*poly_normals)[3], int numPolys, short (*r_clnors_data)[2]); -void BKE_mesh_normals_loop_custom_from_verts_set(const struct MVert *mverts, +void BKE_mesh_normals_loop_custom_from_verts_set(const float (*vert_positions)[3], const float (*vert_normals)[3], float (*r_custom_vert_normals)[3], int numVerts, @@ -689,17 +686,17 @@ void BKE_mesh_set_custom_normals_from_verts(struct Mesh *mesh, float (*r_custom_ void BKE_mesh_calc_poly_center(const struct MPoly *mpoly, const struct MLoop *loopstart, - const struct MVert *mvarray, + const float (*vert_positions)[3], float r_cent[3]); /* NOTE: passing poly-normal is only a speedup so we can skip calculating it. */ float BKE_mesh_calc_poly_area(const struct MPoly *mpoly, const struct MLoop *loopstart, - const struct MVert *mvarray); + const float (*vert_positions)[3]); float BKE_mesh_calc_area(const struct Mesh *me); float BKE_mesh_calc_poly_uv_area(const struct MPoly *mpoly, const struct MLoopUV *uv_array); void BKE_mesh_calc_poly_angles(const struct MPoly *mpoly, const struct MLoop *loopstart, - const struct MVert *mvarray, + const float (*vert_positions)[3], float angles[]); void BKE_mesh_poly_edgehash_insert(struct EdgeHash *ehash, @@ -729,7 +726,7 @@ bool BKE_mesh_center_of_volume(const struct Mesh *me, float r_cent[3]); * \param r_volume: Volume (unsigned). * \param r_center: Center of mass. */ -void BKE_mesh_calc_volume(const struct MVert *mverts, +void BKE_mesh_calc_volume(const float (*vert_positions)[3], int mverts_num, const struct MLoopTri *mlooptri, int looptri_num, @@ -888,7 +885,7 @@ bool BKE_mesh_validate_material_indices(struct Mesh *me); * by importers that load normals (for example). */ bool BKE_mesh_validate_arrays(struct Mesh *me, - struct MVert *mverts, + float (*vert_positions)[3], unsigned int totvert, struct MEdge *medges, unsigned int totedge, @@ -992,13 +989,14 @@ BLI_INLINE int *BKE_mesh_material_indices_for_write(Mesh *mesh) &mesh->pdata, CD_PROP_INT32, CD_SET_DEFAULT, NULL, mesh->totpoly, "material_index"); } -BLI_INLINE const MVert *BKE_mesh_verts(const Mesh *mesh) +BLI_INLINE const float (*BKE_mesh_vert_positions(const Mesh *mesh))[3] { - return (const MVert *)CustomData_get_layer(&mesh->vdata, CD_MVERT); + return (const float(*)[3])CustomData_get_layer_named(&mesh->vdata, CD_PROP_FLOAT3, "position"); } -BLI_INLINE MVert *BKE_mesh_verts_for_write(Mesh *mesh) +BLI_INLINE float (*BKE_mesh_vert_positions_for_write(Mesh *mesh))[3] { - return (MVert *)CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MVERT, mesh->totvert); + return (float(*)[3])CustomData_duplicate_referenced_layer_named( + &mesh->vdata, CD_PROP_FLOAT3, "position", mesh->totvert); } BLI_INLINE const MEdge *BKE_mesh_edges(const Mesh *mesh) @@ -1049,15 +1047,17 @@ BLI_INLINE MDeformVert *BKE_mesh_deform_verts_for_write(Mesh *mesh) #ifdef __cplusplus +# include "BLI_math_vector_types.hh" # include "BLI_span.hh" -inline blender::Span Mesh::verts() const +inline blender::Span Mesh::vert_positions() const { - return {BKE_mesh_verts(this), this->totvert}; + return {reinterpret_cast(BKE_mesh_vert_positions(this)), this->totvert}; } -inline blender::MutableSpan Mesh::verts_for_write() +inline blender::MutableSpan Mesh::vert_positions_for_write() { - return {BKE_mesh_verts_for_write(this), this->totvert}; + return {reinterpret_cast(BKE_mesh_vert_positions_for_write(this)), + this->totvert}; } inline blender::Span Mesh::edges() const diff --git a/source/blender/blenkernel/BKE_mesh_fair.h b/source/blender/blenkernel/BKE_mesh_fair.h index 9d94c692858..5aeb94ceffc 100644 --- a/source/blender/blenkernel/BKE_mesh_fair.h +++ b/source/blender/blenkernel/BKE_mesh_fair.h @@ -29,10 +29,10 @@ void BKE_bmesh_prefair_and_fair_verts(struct BMesh *bm, bool *affect_verts, eMeshFairingDepth depth); -/* This function can optionally use the MVert coordinates of deform_mverts to read and write the - * fairing result. When NULL, the function will use mesh->mverts directly. */ +/* This function can optionally use the vertex coordinates of deform_mverts to read and write the + * fairing result. When NULL, the function will use mesh positions directly. */ void BKE_mesh_prefair_and_fair_verts(struct Mesh *mesh, - struct MVert *deform_mverts, + float (*deform_vert_positions)[3], bool *affect_verts, eMeshFairingDepth depth); diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h index 65804e9ac24..a561cf9e8fd 100644 --- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h +++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h @@ -10,7 +10,9 @@ #include "BLI_utildefines.h" #ifdef __cplusplus +# include "BLI_resource_scope.hh" # include "BLI_span.hh" +# include "BLI_vector.hh" # include "DNA_customdata_types.h" #endif @@ -88,6 +90,13 @@ void BKE_mesh_legacy_convert_loose_edges_to_flag(struct Mesh *mesh); void BKE_mesh_legacy_attribute_flags_to_strings(struct Mesh *mesh); void BKE_mesh_legacy_attribute_strings_to_flags(struct Mesh *mesh); +struct MVert *BKE_mesh_legacy_convert_positions_to_verts( + Mesh *mesh, + blender::ResourceScope &temp_arrays_for_convert, + blender::Vector &vert_layers_to_write); + +void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh); + #endif /** diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h index b49d61ac0a8..b70e05ed14f 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.h +++ b/source/blender/blenkernel/BKE_mesh_mapping.h @@ -19,7 +19,6 @@ struct MLoop; struct MLoopTri; struct MLoopUV; struct MPoly; -struct MVert; /* UvVertMap */ #define STD_UV_CONNECT_LIMIT 0.0001f @@ -146,7 +145,6 @@ void BKE_mesh_vert_loop_map_create(MeshElemMap **r_map, */ void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map, int **r_mem, - const struct MVert *mvert, int totvert, const struct MLoopTri *mlooptri, int totlooptri, @@ -260,7 +258,7 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store, int num_innercut_items, int *innercut_item_indices); -typedef bool (*MeshRemapIslandsCalc)(const struct MVert *verts, +typedef bool (*MeshRemapIslandsCalc)(const float (*vert_positions)[3], int totvert, const struct MEdge *edges, int totedge, @@ -277,7 +275,7 @@ typedef bool (*MeshRemapIslandsCalc)(const struct MVert *verts, * Calculate 'generic' UV islands, i.e. based only on actual geometry data (edge seams), * not some UV layers coordinates. */ -bool BKE_mesh_calc_islands_loop_poly_edgeseam(const struct MVert *verts, +bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3], int totvert, const struct MEdge *edges, int totedge, @@ -300,7 +298,7 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const struct MVert *verts, * Not sure it would be worth the more complex code, though, * those loops are supposed to be really quick to do. */ -bool BKE_mesh_calc_islands_loop_poly_uvmap(struct MVert *verts, +bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3], int totvert, struct MEdge *edges, int totedge, diff --git a/source/blender/blenkernel/BKE_mesh_remap.h b/source/blender/blenkernel/BKE_mesh_remap.h index efbf542c831..7508821860c 100644 --- a/source/blender/blenkernel/BKE_mesh_remap.h +++ b/source/blender/blenkernel/BKE_mesh_remap.h @@ -12,7 +12,6 @@ extern "C" { struct CustomData; struct CustomData_MeshMasks; -struct MVert; struct MemArena; struct Mesh; @@ -158,14 +157,14 @@ void BKE_mesh_remap_calc_source_cddata_masks_from_map_modes( * in favor of a global good matching. */ float BKE_mesh_remap_calc_difference_from_mesh(const struct SpaceTransform *space_transform, - const struct MVert *verts_dst, + const float (*vert_positions_dst)[3], int numverts_dst, struct Mesh *me_src); /** * Set r_space_transform so that best bbox of dst matches best bbox of src. */ -void BKE_mesh_remap_find_best_match_from_mesh(const struct MVert *verts_dst, +void BKE_mesh_remap_find_best_match_from_mesh(const float (*vert_positions_dst)[3], int numverts_dst, struct Mesh *me_src, struct SpaceTransform *r_space_transform); @@ -174,7 +173,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(int mode, const struct SpaceTransform *space_transform, float max_dist, float ray_radius, - const struct MVert *verts_dst, + const float (*vert_positions_dst)[3], int numverts_dst, bool dirty_nors_dst, struct Mesh *me_src, @@ -185,7 +184,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(int mode, const struct SpaceTransform *space_transform, float max_dist, float ray_radius, - const struct MVert *verts_dst, + const float (*vert_positions_dst)[3], int numverts_dst, const struct MEdge *edges_dst, int numedges_dst, @@ -199,7 +198,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(int mode, float max_dist, float ray_radius, struct Mesh *mesh_dst, - const struct MVert *verts_dst, + const float (*vert_positions_dst)[3], int numverts_dst, const struct MEdge *edges_dst, int numedges_dst, @@ -221,7 +220,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(int mode, float max_dist, float ray_radius, const struct Mesh *mesh_dst, - const struct MVert *verts_dst, + const float (*vert_positions_dst)[3], const struct MLoop *loops_dst, const struct MPoly *polys_dst, int numpolys_dst, diff --git a/source/blender/blenkernel/BKE_mesh_sample.hh b/source/blender/blenkernel/BKE_mesh_sample.hh index e4d987271a3..191c5c57ee9 100644 --- a/source/blender/blenkernel/BKE_mesh_sample.hh +++ b/source/blender/blenkernel/BKE_mesh_sample.hh @@ -127,7 +127,7 @@ int sample_surface_points_projected( Vector &r_looptri_indices, Vector &r_positions); -float3 compute_bary_coord_in_triangle(Span verts, +float3 compute_bary_coord_in_triangle(Span vert_positions, Span loops, const MLoopTri &looptri, const float3 &position); diff --git a/source/blender/blenkernel/BKE_mesh_tangent.h b/source/blender/blenkernel/BKE_mesh_tangent.h index b018ab978b2..cec98da5ef6 100644 --- a/source/blender/blenkernel/BKE_mesh_tangent.h +++ b/source/blender/blenkernel/BKE_mesh_tangent.h @@ -17,7 +17,7 @@ struct ReportList; * split normals can be used to recreate the full tangent space. * NOTE: * The mesh should be made of only tris and quads! */ -void BKE_mesh_calc_loop_tangent_single_ex(const struct MVert *mverts, +void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3], int numVerts, const struct MLoop *mloops, float (*r_looptangent)[4], @@ -41,7 +41,7 @@ void BKE_mesh_calc_loop_tangent_single(struct Mesh *mesh, /** * See: #BKE_editmesh_loop_tangent_calc (matching logic). */ -void BKE_mesh_calc_loop_tangent_ex(const struct MVert *mvert, +void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], const struct MPoly *mpoly, uint mpoly_len, const struct MLoop *mloop, diff --git a/source/blender/blenkernel/BKE_mesh_types.h b/source/blender/blenkernel/BKE_mesh_types.h index 5265ae3624c..0e0bced37ec 100644 --- a/source/blender/blenkernel/BKE_mesh_types.h +++ b/source/blender/blenkernel/BKE_mesh_types.h @@ -47,7 +47,7 @@ typedef enum eMeshBatchDirtyMode { /** #MeshRuntime.wrapper_type */ typedef enum eMeshWrapperType { - /** Use mesh data (#Mesh.mvert, #Mesh.medge, #Mesh.mloop, #Mesh.mpoly). */ + /** Use mesh data (#Mesh.vert_positions(), #Mesh.medge, #Mesh.mloop, #Mesh.mpoly). */ ME_WRAPPER_TYPE_MDATA = 0, /** Use edit-mesh data (#Mesh.edit_mesh, #MeshRuntime.edit_data). */ ME_WRAPPER_TYPE_BMESH = 1, diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 13dc32fede5..57e87ddddd8 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -27,7 +27,6 @@ struct SubdivCCG; struct MLoop; struct MLoopTri; struct MPoly; -struct MVert; /** * Delete mesh mdisps and grid paint masks. diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index ba631bd92a0..55c89e2d6b1 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -39,7 +39,6 @@ struct ImageUser; struct ListBase; struct MLoop; struct MLoopTri; -struct MVert; struct Main; struct Mesh; struct MeshElemMap; @@ -577,7 +576,7 @@ typedef struct SculptSession { struct Depsgraph *depsgraph; /* These are always assigned to base mesh data when using PBVH_FACES and PBVH_GRIDS. */ - struct MVert *mvert; + float (*vert_positions)[3]; const struct MPoly *mpoly; const struct MLoop *mloop; diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 7dfbf3c5cc5..5cf0eced72e 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -36,7 +36,6 @@ struct LinkNode; struct MCol; struct MFace; struct MTFace; -struct MVert; struct Main; struct ModifierData; struct Object; @@ -583,7 +582,7 @@ void psys_get_texture(struct ParticleSimulationData *sim, * Interpolate a location on a face based on face coordinates. */ void psys_interpolate_face(struct Mesh *mesh, - const struct MVert *mvert, + const float (*vert_positions)[3], const float (*vert_normals)[3], struct MFace *mface, struct MTFace *tface, diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index a1e1253bd54..0e7eb957fd9 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -32,7 +32,6 @@ struct IsectRayPrecalc; struct MLoop; struct MLoopTri; struct MPoly; -struct MVert; struct Mesh; struct MeshElemMap; struct PBVH; @@ -267,7 +266,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, struct Mesh *mesh, const struct MPoly *mpoly, const struct MLoop *mloop, - struct MVert *verts, + float (*vert_positions)[3], int totvert, struct CustomData *vdata, struct CustomData *ldata, @@ -478,10 +477,7 @@ void BKE_pbvh_node_get_grids(PBVH *pbvh, int *gridsize, struct CCGElem ***r_griddata); void BKE_pbvh_node_num_verts(PBVH *pbvh, PBVHNode *node, int *r_uniquevert, int *r_totvert); -void BKE_pbvh_node_get_verts(PBVH *pbvh, - PBVHNode *node, - const int **r_vert_indices, - struct MVert **r_verts); +const int *BKE_pbvh_node_get_vert_indices(PBVHNode *node); void BKE_pbvh_node_get_loops(PBVH *pbvh, PBVHNode *node, const int **r_loop_indices, @@ -587,12 +583,13 @@ typedef struct PBVHVertexIter { int gridsize; /* mesh */ - struct MVert *mverts; + float (*vert_positions)[3]; float (*vert_normals)[3]; const bool *hide_vert; int totvert; const int *vert_indices; float *vmask; + bool is_mesh; /* bmesh */ struct GSetIterator bm_unique_verts; @@ -602,7 +599,6 @@ typedef struct PBVHVertexIter { /* result: these are all computed in the macro, but we assume * that compiler optimization's will skip the ones we don't use */ - struct MVert *mvert; struct BMVert *bm_vert; float *co; float *no; @@ -647,8 +643,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m } \ } \ } \ - else if (vi.mverts) { \ - vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \ + else if (vi.vert_positions) { \ if (vi.respect_hide) { \ vi.visible = !(vi.hide_vert && vi.hide_vert[vi.vert_indices[vi.gx]]); \ if (mode == PBVH_ITER_UNIQUE && !vi.visible) { \ @@ -658,7 +653,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m else { \ BLI_assert(vi.visible); \ } \ - vi.co = vi.mvert->co; \ + vi.co = vi.vert_positions[vi.vert_indices[vi.gx]]; \ vi.no = vi.vert_normals[vi.vert_indices[vi.gx]]; \ vi.index = vi.vertex.i = vi.vert_indices[vi.i]; \ if (vi.vmask) { \ @@ -770,7 +765,7 @@ void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode); -struct MVert *BKE_pbvh_get_verts(const PBVH *pbvh); +float (*BKE_pbvh_get_vert_positions(const PBVH *pbvh))[3]; const float (*BKE_pbvh_get_vert_normals(const PBVH *pbvh))[3]; const bool *BKE_pbvh_get_vert_hide(const PBVH *pbvh); bool *BKE_pbvh_get_vert_hide_for_write(PBVH *pbvh); diff --git a/source/blender/blenkernel/BKE_subdiv.h b/source/blender/blenkernel/BKE_subdiv.h index 97bcab8a3a2..a99cc4e6c1a 100644 --- a/source/blender/blenkernel/BKE_subdiv.h +++ b/source/blender/blenkernel/BKE_subdiv.h @@ -94,7 +94,7 @@ typedef struct SubdivStats { double topology_refiner_creation_time; /* Total time spent in BKE_subdiv_to_mesh(). */ double subdiv_to_mesh_time; - /* Geometry (MVert and co) creation time during SUBDIV_TYO_MESH. */ + /* Geometry (mesh vertices) creation time during SUBDIV_TYO_MESH. */ double subdiv_to_mesh_geometry_time; /* Time spent on evaluator creation from topology refiner. */ double evaluator_creation_time; diff --git a/source/blender/blenkernel/BKE_subdiv_mesh.h b/source/blender/blenkernel/BKE_subdiv_mesh.h index 49c45efafe0..d1ccc60061c 100644 --- a/source/blender/blenkernel/BKE_subdiv_mesh.h +++ b/source/blender/blenkernel/BKE_subdiv_mesh.h @@ -16,7 +16,6 @@ extern "C" { struct Mesh; struct MeshElemMap; struct MEdge; -struct MVert; struct Subdiv; typedef struct SubdivToMeshSettings { @@ -39,7 +38,7 @@ struct Mesh *BKE_subdiv_to_mesh(struct Subdiv *subdiv, /* Interpolate a position along the `coarse_edge` at the relative `u` coordinate. If `is_simple` is * false, this will perform a B-Spline interpolation using the edge neighbors, otherwise a linear * interpolation will be done base on the edge vertices. */ -void BKE_subdiv_mesh_interpolate_position_on_edge(const struct MVert *coarse_verts, +void BKE_subdiv_mesh_interpolate_position_on_edge(const float (*coarse_positions)[3], const struct MEdge *coarse_edges, const struct MeshElemMap *vert_to_edge_map, int coarse_edge_index, diff --git a/source/blender/blenkernel/BKE_volume_to_mesh.hh b/source/blender/blenkernel/BKE_volume_to_mesh.hh index 9a3ab1000ea..15e405a103d 100644 --- a/source/blender/blenkernel/BKE_volume_to_mesh.hh +++ b/source/blender/blenkernel/BKE_volume_to_mesh.hh @@ -62,7 +62,7 @@ void fill_mesh_from_openvdb_data(const Span vdb_verts, int vert_offset, int poly_offset, int loop_offset, - MutableSpan verts, + MutableSpan vert_positions, MutableSpan polys, MutableSpan loops); diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 564cb8e38ef..19e9eba2d0c 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -92,18 +92,19 @@ static void editbmesh_calc_modifier_final_normals_or_defer( /* -------------------------------------------------------------------- */ -static MVert *dm_getVertArray(DerivedMesh *dm) +static float *dm_getVertArray(DerivedMesh *dm) { - MVert *mvert = (MVert *)CustomData_get_layer(&dm->vertData, CD_MVERT); + float(*positions)[3] = (float(*)[3])CustomData_get_layer_named( + &dm->vertData, CD_PROP_FLOAT3, "position"); - if (!mvert) { - mvert = (MVert *)CustomData_add_layer( - &dm->vertData, CD_MVERT, CD_SET_DEFAULT, nullptr, dm->getNumVerts(dm)); - CustomData_set_layer_flag(&dm->vertData, CD_MVERT, CD_FLAG_TEMPORARY); - dm->copyVertArray(dm, mvert); + if (!positions) { + positions = (float(*)[3])CustomData_add_layer_named( + &dm->vertData, CD_PROP_FLOAT3, CD_SET_DEFAULT, nullptr, dm->getNumVerts(dm), "position"); + CustomData_set_layer_flag(&dm->vertData, CD_PROP_FLOAT3, CD_FLAG_TEMPORARY); + dm->copyVertArray(dm, positions); } - return mvert; + return (float *)positions; } static MEdge *dm_getEdgeArray(DerivedMesh *dm) @@ -350,10 +351,6 @@ static void mesh_set_only_copy(Mesh *mesh, const CustomData_MeshMasks *mask) void *DM_get_vert_data_layer(DerivedMesh *dm, int type) { - if (type == CD_MVERT) { - return dm->getVertArray(dm); - } - return CustomData_get_layer(&dm->vertData, type); } @@ -672,10 +669,8 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, BLI_assert((mesh_input->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0); - /* Deformed vertex locations array. Deform only modifier need this type of - * float array rather than MVert*. Tracked along with mesh_final as an - * optimization to avoid copying coordinates back and forth if there are - * multiple sequential deform only modifiers. */ + /* TODO: Remove use of `deformed_verts` in mesh modifier stack + * since mesh positions are now stored in a contiguous array. */ float(*deformed_verts)[3] = nullptr; int num_deformed_verts = mesh_input->totvert; bool isPrevDeform = false; @@ -1262,10 +1257,8 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph, /* This geometry set contains the non-mesh data that might be generated by modifiers. */ GeometrySet geometry_set_final; - /* Deformed vertex locations array. Deform only modifier need this type of - * float array rather than MVert*. Tracked along with mesh_final as an - * optimization to avoid copying coordinates back and forth if there are - * multiple sequential deform only modifiers. */ + /* TODO: Remove use of `deformed_verts` in mesh modifier stack + * since mesh positions are now stored in a contiguous array. */ float(*deformed_verts)[3] = nullptr; int num_deformed_verts = 0; bool isPrevDeform = false; @@ -1928,9 +1921,9 @@ void mesh_get_mapped_verts_coords(Mesh *me_eval, float (*r_cos)[3], const int to MEM_freeN(userData.vertex_visit); } else { - const Span verts = me_eval->verts(); + const Span positions = me_eval->vert_positions(); for (int i = 0; i < totcos; i++) { - copy_v3_v3(r_cos[i], verts[i].co); + copy_v3_v3(r_cos[i], positions[i]); } } } @@ -1943,7 +1936,7 @@ static void mesh_init_origspace(Mesh *mesh) CD_ORIGSPACE_MLOOP); const int numpoly = mesh->totpoly; // const int numloop = mesh->totloop; - const Span verts = mesh->verts(); + const Span positions = mesh->vert_positions(); const Span polys = mesh->polys(); const Span loops = mesh->loops(); @@ -1968,12 +1961,13 @@ static void mesh_init_origspace(Mesh *mesh) float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX}; float translate[2], scale[2]; - BKE_mesh_calc_poly_normal(mp, l, verts.data(), p_nor); + BKE_mesh_calc_poly_normal( + mp, l, reinterpret_cast(positions.data()), p_nor); axis_dominant_v3_to_m3(mat, p_nor); vcos_2d.resize(mp->totloop); for (j = 0; j < mp->totloop; j++, l++) { - mul_v3_m3v3(co, mat, verts[l->v].co); + mul_v3_m3v3(co, mat, positions[l->v]); copy_v2_v2(vcos_2d[j], co); for (k = 0; k < 2; k++) { diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc index 4e1a925bf5e..ddf70ee7535 100644 --- a/source/blender/blenkernel/intern/attribute.cc +++ b/source/blender/blenkernel/intern/attribute.cc @@ -31,6 +31,7 @@ #include "BKE_curves.hh" #include "BKE_customdata.h" #include "BKE_editmesh.h" +#include "BKE_mesh.h" #include "BKE_pointcloud.h" #include "BKE_report.h" @@ -478,6 +479,8 @@ bool BKE_id_attribute_required(const ID *id, const char *name) return BKE_pointcloud_attribute_required((const PointCloud *)id, name); case ID_CV: return BKE_curves_attribute_required((const Curves *)id, name); + case ID_ME: + return BKE_mesh_attribute_required(name); default: return false; } diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh index ccf9ae83182..fe84123f2b5 100644 --- a/source/blender/blenkernel/intern/attribute_access_intern.hh +++ b/source/blender/blenkernel/intern/attribute_access_intern.hh @@ -220,8 +220,7 @@ template GVMutableArray make_array_write_attribute(void *data, const /** * This provider is used to provide access to builtin attributes. It supports making internal types - * available as different types. For example, the vertex position attribute is stored as part of - * the #MVert struct, but is exposed as float3 attribute. + * available as different types. * * It also supports named builtin attributes, and will look up attributes in #CustomData by name * if the stored type is the same as the attribute type. diff --git a/source/blender/blenkernel/intern/bvhutils.cc b/source/blender/blenkernel/intern/bvhutils.cc index b8756db4736..fc1072d4cb8 100644 --- a/source/blender/blenkernel/intern/bvhutils.cc +++ b/source/blender/blenkernel/intern/bvhutils.cc @@ -30,6 +30,7 @@ #include "MEM_guardedalloc.h" using blender::BitVector; +using blender::float3; using blender::IndexRange; using blender::Span; using blender::VArray; @@ -236,14 +237,14 @@ static void mesh_faces_nearest_point(void *userdata, BVHTreeNearest *nearest) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; - const MVert *vert = data->vert; + const float(*positions)[3] = data->vert_positions; const MFace *face = data->face + index; const float *t0, *t1, *t2, *t3; - t0 = vert[face->v1].co; - t1 = vert[face->v2].co; - t2 = vert[face->v3].co; - t3 = face->v4 ? vert[face->v4].co : nullptr; + t0 = positions[face->v1]; + t1 = positions[face->v2]; + t2 = positions[face->v3]; + t3 = face->v4 ? positions[face->v4] : nullptr; do { float nearest_tmp[3], dist_sq; @@ -271,12 +272,12 @@ static void mesh_looptri_nearest_point(void *userdata, BVHTreeNearest *nearest) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; - const MVert *vert = data->vert; + const float(*positions)[3] = data->vert_positions; const MLoopTri *lt = &data->looptri[index]; const float *vtri_co[3] = { - vert[data->loop[lt->tri[0]].v].co, - vert[data->loop[lt->tri[1]].v].co, - vert[data->loop[lt->tri[2]].v].co, + positions[data->loop[lt->tri[0]].v], + positions[data->loop[lt->tri[1]].v], + positions[data->loop[lt->tri[2]].v], }; float nearest_tmp[3], dist_sq; @@ -332,14 +333,14 @@ static void mesh_faces_spherecast(void *userdata, BVHTreeRayHit *hit) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; - const MVert *vert = data->vert; + const float(*positions)[3] = data->vert_positions; const MFace *face = &data->face[index]; const float *t0, *t1, *t2, *t3; - t0 = vert[face->v1].co; - t1 = vert[face->v2].co; - t2 = vert[face->v3].co; - t3 = face->v4 ? vert[face->v4].co : nullptr; + t0 = positions[face->v1]; + t1 = positions[face->v2]; + t2 = positions[face->v3]; + t3 = face->v4 ? positions[face->v4] : nullptr; do { float dist; @@ -371,12 +372,12 @@ static void mesh_looptri_spherecast(void *userdata, BVHTreeRayHit *hit) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; - const MVert *vert = data->vert; + const float(*positions)[3] = data->vert_positions; const MLoopTri *lt = &data->looptri[index]; const float *vtri_co[3] = { - vert[data->loop[lt->tri[0]].v].co, - vert[data->loop[lt->tri[1]].v].co, - vert[data->loop[lt->tri[2]].v].co, + positions[data->loop[lt->tri[0]].v], + positions[data->loop[lt->tri[1]].v], + positions[data->loop[lt->tri[2]].v], }; float dist; @@ -441,13 +442,13 @@ static void mesh_edges_nearest_point(void *userdata, BVHTreeNearest *nearest) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; - const MVert *vert = data->vert; + const float(*positions)[3] = data->vert_positions; const MEdge *edge = data->edge + index; float nearest_tmp[3], dist_sq; const float *t0, *t1; - t0 = vert[edge->v1].co; - t1 = vert[edge->v2].co; + t0 = positions[edge->v1]; + t1 = positions[edge->v2]; closest_to_line_segment_v3(nearest_tmp, co, t0, t1); dist_sq = len_squared_v3v3(nearest_tmp, co); @@ -506,7 +507,7 @@ static void mesh_verts_spherecast(void *userdata, BVHTreeRayHit *hit) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; - const float *v = data->vert[index].co; + const float *v = data->vert_positions[index]; mesh_verts_spherecast_do(index, v, ray, hit); } @@ -523,15 +524,15 @@ static void mesh_edges_spherecast(void *userdata, BVHTreeRayHit *hit) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; - const MVert *vert = data->vert; + const float(*positions)[3] = data->vert_positions; const MEdge *edge = &data->edge[index]; const float radius_sq = square_f(ray->radius); float dist; const float *v1, *v2, *r1; float r2[3], i1[3], i2[3]; - v1 = vert[edge->v1].co; - v2 = vert[edge->v2].co; + v1 = positions[edge->v1]; + v2 = positions[edge->v2]; /* In case we get a zero-length edge, handle it as a point! */ if (equals_v3v3(v1, v2)) { @@ -574,7 +575,7 @@ static void mesh_edges_spherecast(void *userdata, static void bvhtree_from_mesh_setup_data(BVHTree *tree, const BVHCacheType bvh_cache_type, - const MVert *vert, + const float (*positions)[3], const MEdge *edge, const MFace *face, const MLoop *loop, @@ -585,7 +586,7 @@ static void bvhtree_from_mesh_setup_data(BVHTree *tree, r_data->tree = tree; - r_data->vert = vert; + r_data->vert_positions = positions; r_data->edge = edge; r_data->face = face; r_data->loop = loop; @@ -703,7 +704,7 @@ static BVHTree *bvhtree_from_editmesh_verts_create_tree(float epsilon, static BVHTree *bvhtree_from_mesh_verts_create_tree(float epsilon, int tree_type, int axis, - const MVert *vert, + const float (*positions)[3], const int verts_num, const BitVector<> &verts_mask, int verts_num_active) @@ -727,7 +728,7 @@ static BVHTree *bvhtree_from_mesh_verts_create_tree(float epsilon, if (!verts_mask.is_empty() && !verts_mask[i]) { continue; } - BLI_bvhtree_insert(tree, i, vert[i].co, 1); + BLI_bvhtree_insert(tree, i, positions[i], 1); } BLI_assert(BLI_bvhtree_get_len(tree) == verts_num_active); @@ -761,7 +762,7 @@ BVHTree *bvhtree_from_editmesh_verts( } BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data, - const MVert *vert, + const float (*vert_positions)[3], const int verts_num, const BitVector<> &verts_mask, int verts_num_active, @@ -770,14 +771,14 @@ BVHTree *bvhtree_from_mesh_verts_ex(BVHTreeFromMesh *data, int axis) { BVHTree *tree = bvhtree_from_mesh_verts_create_tree( - epsilon, tree_type, axis, vert, verts_num, verts_mask, verts_num_active); + epsilon, tree_type, axis, vert_positions, verts_num, verts_mask, verts_num_active); bvhtree_balance(tree, false); if (data) { /* Setup BVHTreeFromMesh */ bvhtree_from_mesh_setup_data( - tree, BVHTREE_FROM_VERTS, vert, nullptr, nullptr, nullptr, nullptr, data); + tree, BVHTREE_FROM_VERTS, vert_positions, nullptr, nullptr, nullptr, nullptr, data); } return tree; @@ -829,7 +830,7 @@ static BVHTree *bvhtree_from_editmesh_edges_create_tree(float epsilon, return tree; } -static BVHTree *bvhtree_from_mesh_edges_create_tree(const MVert *vert, +static BVHTree *bvhtree_from_mesh_edges_create_tree(const float (*positions)[3], const MEdge *edge, const int edge_num, const BitVector<> &edges_mask, @@ -859,8 +860,8 @@ static BVHTree *bvhtree_from_mesh_edges_create_tree(const MVert *vert, continue; } float co[2][3]; - copy_v3_v3(co[0], vert[edge[i].v1].co); - copy_v3_v3(co[1], vert[edge[i].v2].co); + copy_v3_v3(co[0], positions[edge[i].v1]); + copy_v3_v3(co[1], positions[edge[i].v2]); BLI_bvhtree_insert(tree, i, co[0], 2); } @@ -895,7 +896,7 @@ BVHTree *bvhtree_from_editmesh_edges( } BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data, - const MVert *vert, + const float (*vert_positions)[3], const MEdge *edge, const int edges_num, const BitVector<> &edges_mask, @@ -905,14 +906,14 @@ BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data, int axis) { BVHTree *tree = bvhtree_from_mesh_edges_create_tree( - vert, edge, edges_num, edges_mask, edges_num_active, epsilon, tree_type, axis); + vert_positions, edge, edges_num, edges_mask, edges_num_active, epsilon, tree_type, axis); bvhtree_balance(tree, false); if (data) { /* Setup BVHTreeFromMesh */ bvhtree_from_mesh_setup_data( - tree, BVHTREE_FROM_EDGES, vert, edge, nullptr, nullptr, nullptr, data); + tree, BVHTREE_FROM_EDGES, vert_positions, edge, nullptr, nullptr, nullptr, data); } return tree; @@ -927,7 +928,7 @@ BVHTree *bvhtree_from_mesh_edges_ex(BVHTreeFromMesh *data, static BVHTree *bvhtree_from_mesh_faces_create_tree(float epsilon, int tree_type, int axis, - const MVert *vert, + const float (*positions)[3], const MFace *face, const int faces_num, const BitVector<> &faces_mask, @@ -951,18 +952,18 @@ static BVHTree *bvhtree_from_mesh_faces_create_tree(float epsilon, return nullptr; } - if (vert && face) { + if (positions && face) { for (int i = 0; i < faces_num; i++) { float co[4][3]; if (!faces_mask.is_empty() && !faces_mask[i]) { continue; } - copy_v3_v3(co[0], vert[face[i].v1].co); - copy_v3_v3(co[1], vert[face[i].v2].co); - copy_v3_v3(co[2], vert[face[i].v3].co); + copy_v3_v3(co[0], positions[face[i].v1]); + copy_v3_v3(co[1], positions[face[i].v2]); + copy_v3_v3(co[2], positions[face[i].v3]); if (face[i].v4) { - copy_v3_v3(co[3], vert[face[i].v4].co); + copy_v3_v3(co[3], positions[face[i].v4]); } BLI_bvhtree_insert(tree, i, co[0], face[i].v4 ? 4 : 3); @@ -1033,7 +1034,7 @@ static BVHTree *bvhtree_from_editmesh_looptri_create_tree(float epsilon, static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon, int tree_type, int axis, - const MVert *vert, + const float (*positions)[3], const MLoop *mloop, const MLoopTri *looptri, const int looptri_num, @@ -1057,16 +1058,16 @@ static BVHTree *bvhtree_from_mesh_looptri_create_tree(float epsilon, return nullptr; } - if (vert && looptri) { + if (positions && looptri) { for (int i = 0; i < looptri_num; i++) { float co[3][3]; if (!looptri_mask.is_empty() && !looptri_mask[i]) { continue; } - copy_v3_v3(co[0], vert[mloop[looptri[i].tri[0]].v].co); - copy_v3_v3(co[1], vert[mloop[looptri[i].tri[1]].v].co); - copy_v3_v3(co[2], vert[mloop[looptri[i].tri[2]].v].co); + copy_v3_v3(co[0], positions[mloop[looptri[i].tri[0]].v]); + copy_v3_v3(co[1], positions[mloop[looptri[i].tri[1]].v]); + copy_v3_v3(co[2], positions[mloop[looptri[i].tri[2]].v]); BLI_bvhtree_insert(tree, i, co[0], 3); } @@ -1104,7 +1105,7 @@ BVHTree *bvhtree_from_editmesh_looptri( } BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data, - const struct MVert *vert, + const float (*vert_positions)[3], const struct MLoop *mloop, const struct MLoopTri *looptri, const int looptri_num, @@ -1117,7 +1118,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data, BVHTree *tree = bvhtree_from_mesh_looptri_create_tree(epsilon, tree_type, axis, - vert, + vert_positions, mloop, looptri, looptri_num, @@ -1129,7 +1130,7 @@ BVHTree *bvhtree_from_mesh_looptri_ex(BVHTreeFromMesh *data, if (data) { /* Setup BVHTreeFromMesh */ bvhtree_from_mesh_setup_data( - tree, BVHTREE_FROM_LOOPTRI, vert, nullptr, nullptr, mloop, looptri, data); + tree, BVHTREE_FROM_LOOPTRI, vert_positions, nullptr, nullptr, mloop, looptri, data); } return tree; @@ -1212,14 +1213,14 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, looptri = BKE_mesh_runtime_looptri_ensure(mesh); looptri_len = BKE_mesh_runtime_looptri_len(mesh); } - const Span verts = mesh->verts(); + const float(*positions)[3] = reinterpret_cast(mesh->vert_positions().data()); const Span edges = mesh->edges(); const Span loops = mesh->loops(); /* Setup BVHTreeFromMesh */ bvhtree_from_mesh_setup_data(nullptr, bvh_cache_type, - verts.data(), + positions, edges.data(), (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE), loops.data(), @@ -1247,7 +1248,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, ATTR_FALLTHROUGH; case BVHTREE_FROM_VERTS: data->tree = bvhtree_from_mesh_verts_create_tree( - 0.0f, tree_type, 6, verts.data(), mesh->totvert, mask, mask_bits_act_len); + 0.0f, tree_type, 6, positions, mesh->totvert, mask, mask_bits_act_len); break; case BVHTREE_FROM_LOOSEEDGES: @@ -1255,7 +1256,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, ATTR_FALLTHROUGH; case BVHTREE_FROM_EDGES: data->tree = bvhtree_from_mesh_edges_create_tree( - verts.data(), edges.data(), mesh->totedge, mask, mask_bits_act_len, 0.0f, tree_type, 6); + positions, edges.data(), mesh->totedge, mask, mask_bits_act_len, 0.0f, tree_type, 6); break; case BVHTREE_FROM_FACES: @@ -1264,7 +1265,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, 0.0f, tree_type, 6, - verts.data(), + positions, (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE), mesh->totface, {}, @@ -1284,7 +1285,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, data->tree = bvhtree_from_mesh_looptri_create_tree(0.0f, tree_type, 6, - verts.data(), + positions, loops.data(), looptri, looptri_len, diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 41993764c0c..7370ee6970a 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -38,7 +38,7 @@ typedef struct { /* these point to data in the DerivedMesh custom data layers, * they are only here for efficiency and convenience */ - MVert *mvert; + float (*vert_positions)[3]; const float (*vert_normals)[3]; MEdge *medge; MFace *mface; @@ -75,10 +75,10 @@ static int cdDM_getNumPolys(DerivedMesh *dm) return dm->numPolyData; } -static void cdDM_copyVertArray(DerivedMesh *dm, MVert *r_vert) +static void cdDM_copyVertArray(DerivedMesh *dm, float (*r_positions)[3]) { CDDerivedMesh *cddm = (CDDerivedMesh *)dm; - memcpy(r_vert, cddm->mvert, sizeof(*r_vert) * dm->numVertData); + memcpy(r_positions, cddm->vert_positions, sizeof(float[3]) * dm->numVertData); } static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *r_edge) @@ -103,7 +103,7 @@ static void cdDM_getVertCo(DerivedMesh *dm, int index, float r_co[3]) { CDDerivedMesh *cddm = (CDDerivedMesh *)dm; - copy_v3_v3(r_co, cddm->mvert[index].co); + copy_v3_v3(r_co, cddm->vert_positions[index]); } static void cdDM_getVertNo(DerivedMesh *dm, int index, float r_no[3]) @@ -121,8 +121,12 @@ static void cdDM_recalc_looptri(DerivedMesh *dm) DM_ensure_looptri_data(dm); BLI_assert(totpoly == 0 || cddm->dm.looptris.array_wip != NULL); - BKE_mesh_recalc_looptri( - cddm->mloop, cddm->mpoly, cddm->mvert, totloop, totpoly, cddm->dm.looptris.array_wip); + BKE_mesh_recalc_looptri(cddm->mloop, + cddm->mpoly, + cddm->vert_positions, + totloop, + totpoly, + cddm->dm.looptris.array_wip); BLI_assert(cddm->dm.looptris.array == NULL); atomic_cas_ptr( @@ -217,7 +221,7 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh, CustomData_merge(&mesh->ldata, &dm->loopData, cddata_masks.lmask, alloctype, mesh->totloop); CustomData_merge(&mesh->pdata, &dm->polyData, cddata_masks.pmask, alloctype, mesh->totpoly); - cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT); + cddm->vert_positions = CustomData_get_layer_named(&dm->vertData, CD_PROP_FLOAT3, "position"); /* Though this may be an unnecessary calculation, simply retrieving the layer may return nothing * or dirty normals. */ cddm->vert_normals = BKE_mesh_vertex_normals_ensure(mesh); diff --git a/source/blender/blenkernel/intern/cloth.cc b/source/blender/blenkernel/intern/cloth.cc index fe9117b4713..e300c4d5084 100644 --- a/source/blender/blenkernel/intern/cloth.cc +++ b/source/blender/blenkernel/intern/cloth.cc @@ -247,18 +247,18 @@ static bool do_init_cloth(Object *ob, ClothModifierData *clmd, Mesh *result, int static int do_step_cloth( Depsgraph *depsgraph, Object *ob, ClothModifierData *clmd, Mesh *result, int framenr) { + using namespace blender; /* simulate 1 frame forward */ ClothVertex *verts = nullptr; Cloth *cloth; ListBase *effectors = nullptr; - MVert *mvert; uint i = 0; int ret = 0; bool vert_mass_changed = false; cloth = clmd->clothObject; verts = cloth->verts; - mvert = BKE_mesh_verts_for_write(result); + const Span positions = result->vert_positions(); vert_mass_changed = verts->mass != clmd->sim_parms->mass; /* force any pinned verts to their constrained location. */ @@ -268,7 +268,7 @@ static int do_step_cloth( copy_v3_v3(verts->txold, verts->x); /* Get the current position. */ - copy_v3_v3(verts->xconst, mvert[i].co); + copy_v3_v3(verts->xconst, positions[i]); mul_m4_v3(ob->object_to_world, verts->xconst); if (vert_mass_changed) { @@ -715,6 +715,7 @@ static float cloth_shrink_factor(ClothModifierData *clmd, ClothVertex *verts, in static bool cloth_from_object( Object *ob, ClothModifierData *clmd, Mesh *mesh, float /*framenr*/, int first) { + using namespace blender; int i = 0; ClothVertex *verts = nullptr; const float(*shapekey_rest)[3] = nullptr; @@ -758,14 +759,14 @@ static bool cloth_from_object( CustomData_get_layer(&mesh->vdata, CD_CLOTH_ORCO)); } - MVert *mvert = BKE_mesh_verts_for_write(mesh); + const Span positions = mesh->vert_positions(); verts = clmd->clothObject->verts; /* set initial values */ for (i = 0; i < mesh->totvert; i++, verts++) { if (first) { - copy_v3_v3(verts->x, mvert[i].co); + copy_v3_v3(verts->x, positions[i]); mul_m4_v3(ob->object_to_world, verts->x); @@ -1159,13 +1160,14 @@ static void cloth_update_springs(ClothModifierData *clmd) /* Update rest verts, for dynamically deformable cloth */ static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh) { + using namespace blender; uint i = 0; - const MVert *mvert = BKE_mesh_verts(mesh); + const Span positions = mesh->vert_positions(); ClothVertex *verts = clmd->clothObject->verts; /* vertex count is already ensured to match */ for (i = 0; i < mesh->totvert; i++, verts++) { - copy_v3_v3(verts->xrest, mvert[i].co); + copy_v3_v3(verts->xrest, positions[i]); mul_m4_v3(ob->object_to_world, verts->xrest); } } @@ -1173,13 +1175,14 @@ static void cloth_update_verts(Object *ob, ClothModifierData *clmd, Mesh *mesh) /* Write rest vert locations to a copy of the mesh. */ static Mesh *cloth_make_rest_mesh(ClothModifierData *clmd, Mesh *mesh) { + using namespace blender; Mesh *new_mesh = BKE_mesh_copy_for_eval(mesh, false); ClothVertex *verts = clmd->clothObject->verts; - MVert *mvert = BKE_mesh_verts_for_write(new_mesh); + MutableSpan positions = mesh->vert_positions_for_write(); /* vertex count is already ensured to match */ - for (uint i = 0; i < mesh->totvert; i++, verts++) { - copy_v3_v3(mvert[i].co, verts->xrest); + for (const int i : positions.index_range()) { + positions[i] = verts[i].xrest; } BKE_mesh_tag_coords_changed(new_mesh); @@ -1395,7 +1398,7 @@ static bool find_internal_spring_target_vertex(BVHTreeFromMesh *treedata, float co[3], no[3], new_co[3]; float radius; - copy_v3_v3(co, treedata->vert[v_idx].co); + copy_v3_v3(co, treedata->vert_positions[v_idx]); negate_v3_v3(no, vert_normals[v_idx]); float vec_len = sin(max_diversion); diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 095666e7eac..9ff9ec08816 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -72,16 +72,16 @@ void collision_move_object(CollisionModifierData *collmd, /* the collider doesn't move this frame */ if (collmd->is_static) { for (i = 0; i < collmd->mvert_num; i++) { - zero_v3(collmd->current_v[i].co); + zero_v3(collmd->current_v[i]); } return; } for (i = 0; i < collmd->mvert_num; i++) { - interp_v3_v3v3(collmd->current_x[i].co, collmd->x[i].co, collmd->xnew[i].co, prevstep); - interp_v3_v3v3(collmd->current_xnew[i].co, collmd->x[i].co, collmd->xnew[i].co, step); - sub_v3_v3v3(collmd->current_v[i].co, collmd->current_xnew[i].co, collmd->current_x[i].co); + interp_v3_v3v3(collmd->current_x[i], collmd->x[i], collmd->xnew[i], prevstep); + interp_v3_v3v3(collmd->current_xnew[i], collmd->x[i], collmd->xnew[i], step); + sub_v3_v3v3(collmd->current_v[i], collmd->current_xnew[i], collmd->current_x[i]); } bvhtree_update_from_mvert(collmd->bvhtree, @@ -92,7 +92,7 @@ void collision_move_object(CollisionModifierData *collmd, moving_bvh); } -BVHTree *bvhtree_build_from_mvert(const MVert *mvert, +BVHTree *bvhtree_build_from_mvert(const float (*positions)[3], const struct MVertTri *tri, int tri_num, float epsilon) @@ -105,9 +105,9 @@ BVHTree *bvhtree_build_from_mvert(const MVert *mvert, for (i = 0, vt = tri; i < tri_num; i++, vt++) { float co[3][3]; - copy_v3_v3(co[0], mvert[vt->tri[0]].co); - copy_v3_v3(co[1], mvert[vt->tri[1]].co); - copy_v3_v3(co[2], mvert[vt->tri[2]].co); + copy_v3_v3(co[0], positions[vt->tri[0]]); + copy_v3_v3(co[1], positions[vt->tri[1]]); + copy_v3_v3(co[2], positions[vt->tri[2]]); BLI_bvhtree_insert(tree, i, co[0], 3); } @@ -119,18 +119,18 @@ BVHTree *bvhtree_build_from_mvert(const MVert *mvert, } void bvhtree_update_from_mvert(BVHTree *bvhtree, - const MVert *mvert, - const MVert *mvert_moving, + const float (*positions)[3], + const float (*positions_moving)[3], const MVertTri *tri, int tri_num, bool moving) { - if ((bvhtree == NULL) || (mvert == NULL)) { + if ((bvhtree == NULL) || (positions == NULL)) { return; } - if (mvert_moving == NULL) { + if (positions_moving == NULL) { moving = false; } @@ -140,17 +140,17 @@ void bvhtree_update_from_mvert(BVHTree *bvhtree, float co[3][3]; bool ret; - copy_v3_v3(co[0], mvert[vt->tri[0]].co); - copy_v3_v3(co[1], mvert[vt->tri[1]].co); - copy_v3_v3(co[2], mvert[vt->tri[2]].co); + copy_v3_v3(co[0], positions[vt->tri[0]]); + copy_v3_v3(co[1], positions[vt->tri[1]]); + copy_v3_v3(co[2], positions[vt->tri[2]]); /* copy new locations into array */ if (moving) { float co_moving[3][3]; /* update moving positions */ - copy_v3_v3(co_moving[0], mvert_moving[vt->tri[0]].co); - copy_v3_v3(co_moving[1], mvert_moving[vt->tri[1]].co); - copy_v3_v3(co_moving[2], mvert_moving[vt->tri[2]].co); + copy_v3_v3(co_moving[0], positions_moving[vt->tri[0]]); + copy_v3_v3(co_moving[1], positions_moving[vt->tri[1]]); + copy_v3_v3(co_moving[2], positions_moving[vt->tri[2]]); ret = BLI_bvhtree_update_node(bvhtree, i, &co[0][0], &co_moving[0][0], 3); } @@ -698,9 +698,9 @@ static int cloth_collision_response_static(ClothModifierData *clmd, } collision_interpolateOnTriangle(v2, - collmd->current_v[collpair->bp1].co, - collmd->current_v[collpair->bp2].co, - collmd->current_v[collpair->bp3].co, + collmd->current_v[collpair->bp1], + collmd->current_v[collpair->bp2], + collmd->current_v[collpair->bp3], u1, u2, u3); @@ -992,9 +992,9 @@ static void cloth_collision(void *__restrict userdata, distance = compute_collision_point_tri_tri(verts1[tri_a->tri[0]].tx, verts1[tri_a->tri[1]].tx, verts1[tri_a->tri[2]].tx, - collmd->current_xnew[tri_b->tri[0]].co, - collmd->current_xnew[tri_b->tri[1]].co, - collmd->current_xnew[tri_b->tri[2]].co, + collmd->current_xnew[tri_b->tri[0]], + collmd->current_xnew[tri_b->tri[1]], + collmd->current_xnew[tri_b->tri[2]], data->culling, data->use_normal, pa, @@ -1031,9 +1031,9 @@ static void cloth_collision(void *__restrict userdata, &collpair[index].aw3); collision_compute_barycentric(pb, - collmd->current_xnew[tri_b->tri[0]].co, - collmd->current_xnew[tri_b->tri[1]].co, - collmd->current_xnew[tri_b->tri[2]].co, + collmd->current_xnew[tri_b->tri[0]], + collmd->current_xnew[tri_b->tri[1]], + collmd->current_xnew[tri_b->tri[2]], &collpair[index].bw1, &collpair[index].bw2, &collpair[index].bw3); @@ -1191,9 +1191,9 @@ static void hair_collision(void *__restrict userdata, /* Compute distance and normal. */ distance = compute_collision_point_edge_tri(verts1[edge_coll->v1].tx, verts1[edge_coll->v2].tx, - collmd->current_x[tri_coll->tri[0]].co, - collmd->current_x[tri_coll->tri[1]].co, - collmd->current_x[tri_coll->tri[2]].co, + collmd->current_x[tri_coll->tri[0]], + collmd->current_x[tri_coll->tri[1]], + collmd->current_x[tri_coll->tri[2]], data->culling, data->use_normal, pa, @@ -1226,9 +1226,9 @@ static void hair_collision(void *__restrict userdata, collpair[index].aw1 = 1.0f - collpair[index].aw2; collision_compute_barycentric(pb, - collmd->current_xnew[tri_coll->tri[0]].co, - collmd->current_xnew[tri_coll->tri[1]].co, - collmd->current_xnew[tri_coll->tri[2]].co, + collmd->current_xnew[tri_coll->tri[0]], + collmd->current_xnew[tri_coll->tri[1]], + collmd->current_xnew[tri_coll->tri[2]], &collpair[index].bw1, &collpair[index].bw2, &collpair[index].bw3); @@ -1747,17 +1747,17 @@ void collision_get_collider_velocity(float vel_old[3], /* compute barycentric coordinates */ collision_compute_barycentric(collpair->pb, - collmd->current_x[collpair->bp1].co, - collmd->current_x[collpair->bp2].co, - collmd->current_x[collpair->bp3].co, + collmd->current_x[collpair->bp1], + collmd->current_x[collpair->bp2], + collmd->current_x[collpair->bp3], &u1, &u2, &u3); collision_interpolateOnTriangle(vel_new, - collmd->current_v[collpair->bp1].co, - collmd->current_v[collpair->bp2].co, - collmd->current_v[collpair->bp3].co, + collmd->current_v[collpair->bp1], + collmd->current_v[collpair->bp2], + collmd->current_v[collpair->bp3], u1, u2, u3); diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 03613058b5b..4ebf7d184b3 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -548,7 +548,7 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[ else if (me_eval) { const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me_eval); const MDeformVert *dvert = CustomData_get_layer(&me_eval->vdata, CD_MDEFORMVERT); - const MVert *verts = BKE_mesh_verts(me_eval); + const float(*positions)[3] = BKE_mesh_vert_positions(me_eval); int numVerts = me_eval->totvert; /* check that dvert is a valid pointers (just in case) */ @@ -557,11 +557,10 @@ static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[ /* get the average of all verts with that are in the vertex-group */ for (int i = 0; i < numVerts; i++) { const MDeformVert *dv = &dvert[i]; - const MVert *mv = &verts[i]; const MDeformWeight *dw = BKE_defvert_find_index(dv, defgroup); if (dw && dw->weight > 0.0f) { - madd_v3_v3fl(vec, mv->co, dw->weight); + madd_v3_v3fl(vec, positions[i], dw->weight); madd_v3_v3fl(normal, vert_normals[i], dw->weight); weightsum += dw->weight; } diff --git a/source/blender/blenkernel/intern/crazyspace.cc b/source/blender/blenkernel/intern/crazyspace.cc index 28281378d5a..dd58f137abe 100644 --- a/source/blender/blenkernel/intern/crazyspace.cc +++ b/source/blender/blenkernel/intern/crazyspace.cc @@ -188,7 +188,7 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me, BLI_bitmap *vert_tag = BLI_BITMAP_NEW(me->totvert, __func__); /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */ - const Span verts = me->verts(); + const Span positions = me->vert_positions(); const Span polys = me->polys(); const Span loops = me->loops(); @@ -214,9 +214,9 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me, co_next = origcos[ml_next->v]; } else { - co_prev = verts[ml_prev->v].co; - co_curr = verts[ml_curr->v].co; - co_next = verts[ml_next->v].co; + co_prev = positions[ml_prev->v]; + co_curr = positions[ml_curr->v]; + co_next = positions[ml_next->v]; } set_crazy_vertex_quat( diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index 9e8eaccb024..305a245a036 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -188,7 +188,7 @@ static void fill_mesh_positions(const int main_point_num, const Span tangents, const Span normals, const Span radii, - MutableSpan mesh_positions) + MutableSpan mesh_positions) { if (profile_point_num == 1) { for (const int i_ring : IndexRange(main_point_num)) { @@ -197,9 +197,7 @@ static void fill_mesh_positions(const int main_point_num, if (!radii.is_empty()) { point_matrix.apply_scale(radii[i_ring]); } - - MVert &vert = mesh_positions[i_ring]; - copy_v3_v3(vert.co, point_matrix * profile_positions.first()); + mesh_positions[i_ring] = point_matrix * profile_positions.first(); } } else { @@ -212,8 +210,7 @@ static void fill_mesh_positions(const int main_point_num, const int ring_vert_start = i_ring * profile_point_num; for (const int i_profile : IndexRange(profile_point_num)) { - MVert &vert = mesh_positions[ring_vert_start + i_profile]; - copy_v3_v3(vert.co, point_matrix * profile_positions[i_profile]); + mesh_positions[ring_vert_start + i_profile] = point_matrix * profile_positions[i_profile]; } } } @@ -643,7 +640,7 @@ 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); - MutableSpan verts = mesh->verts_for_write(); + MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); @@ -691,7 +688,7 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, tangents.slice(info.main_points), normals.slice(info.main_points), radii.is_empty() ? radii : radii.slice(info.main_points), - verts.slice(info.vert_range)); + positions.slice(info.vert_range)); }); if (profile.curve_type_counts()[CURVE_TYPE_BEZIER] > 0) { diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 60d38895a89..68b7fba63c7 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -1638,7 +1638,7 @@ static void layerInterp_propbool(const void **sources, } static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { - /* 0: CD_MVERT */ + /* 0: CD_MVERT */ /* DEPRECATED */ {sizeof(MVert), "MVert", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}, /* 1: CD_MSTICKY */ /* DEPRECATED */ {sizeof(float[2]), "", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}, @@ -2106,22 +2106,22 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = { }; const CustomData_MeshMasks CD_MASK_BAREMESH = { - /* vmask */ CD_MASK_MVERT, + /* vmask */ CD_MASK_PROP_FLOAT3, /* emask */ CD_MASK_MEDGE, /* fmask */ 0, /* pmask */ CD_MASK_MPOLY | CD_MASK_FACEMAP, /* lmask */ CD_MASK_MLOOP, }; const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = { - /* vmask */ CD_MASK_MVERT | CD_MASK_ORIGINDEX, + /* vmask */ CD_MASK_PROP_FLOAT3 | CD_MASK_ORIGINDEX, /* emask */ CD_MASK_MEDGE | CD_MASK_ORIGINDEX, /* fmask */ 0, /* pmask */ CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_ORIGINDEX, /* lmask */ CD_MASK_MLOOP, }; 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_CREASE | CD_MASK_BWEIGHT), + /* vmask */ (CD_MASK_PROP_FLOAT3 | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | + CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | CD_MASK_CREASE | CD_MASK_BWEIGHT), /* emask */ (CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_BWEIGHT | CD_MASK_CREASE), /* fmask */ 0, @@ -2157,7 +2157,7 @@ const CustomData_MeshMasks CD_MASK_BMESH = { 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 | + /* vmask */ (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_CREASE), @@ -2372,6 +2372,7 @@ bool CustomData_merge(const CustomData *source, static bool attribute_stored_in_bmesh_flag(const StringRef name) { return ELEM(name, + "position", ".hide_vert", ".hide_edge", ".hide_poly", diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index 4220d106095..6efe4fb38d9 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -257,7 +257,7 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src, if (dtdata_type == DT_TYPE_LNOR) { /* Compute custom normals into regular loop normals, which will be used for the transfer. */ - const MVert *verts_dst = BKE_mesh_verts(me_dst); + const float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst); const int num_verts_dst = me_dst->totvert; const MEdge *edges_dst = BKE_mesh_edges(me_dst); const int num_edges_dst = me_dst->totedge; @@ -287,7 +287,7 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src, CustomData_set_layer_flag(ldata_dst, CD_NORMAL, CD_FLAG_TEMPORARY); } if (dirty_nors_dst || do_loop_nors_dst) { - BKE_mesh_normals_loop_split(verts_dst, + BKE_mesh_normals_loop_split(positions_dst, BKE_mesh_vertex_normals_ensure(me_dst), num_verts_dst, edges_dst, @@ -320,7 +320,7 @@ static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/, } /* Bake edited destination loop normals into custom normals again. */ - const MVert *verts_dst = BKE_mesh_verts(me_dst); + const float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst); const int num_verts_dst = me_dst->totvert; MEdge *edges_dst = BKE_mesh_edges_for_write(me_dst); const int num_edges_dst = me_dst->totedge; @@ -342,7 +342,7 @@ static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/, } /* Note loop_nors_dst contains our custom normals as transferred from source... */ - BKE_mesh_normals_loop_custom_set(verts_dst, + BKE_mesh_normals_loop_custom_set(positions_dst, BKE_mesh_vertex_normals_ensure(me_dst), num_verts_dst, edges_dst, @@ -932,7 +932,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, } if (cddata_type == CD_FAKE_SHAPEKEY) { /* TODO: leaving shape-keys aside for now, quite specific case, - * since we can't access them from #MVert :/ */ + * since we can't access them from mesh vertices :/ */ return false; } } @@ -1314,7 +1314,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, } BKE_mesh_remap_find_best_match_from_mesh( - BKE_mesh_verts(me_dst), me_dst->totvert, me_src, space_transform); + BKE_mesh_vert_positions(me_dst), me_dst->totvert, me_src, space_transform); } /* Check all possible data types. @@ -1342,7 +1342,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, } if (DT_DATATYPE_IS_VERT(dtdata_type)) { - MVert *verts_dst = BKE_mesh_verts_for_write(me_dst); + float(*positions_dst)[3] = BKE_mesh_vert_positions_for_write(me_dst); const int num_verts_dst = me_dst->totvert; if (!geom_map_init[VDATA]) { @@ -1381,7 +1381,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, space_transform, max_distance, ray_radius, - verts_dst, + positions_dst, num_verts_dst, dirty_nors_dst, me_src, @@ -1426,7 +1426,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, } } if (DT_DATATYPE_IS_EDGE(dtdata_type)) { - const MVert *verts_dst = BKE_mesh_verts_for_write(me_dst); + const float(*positions_dst)[3] = BKE_mesh_vert_positions_for_write(me_dst); const int num_verts_dst = me_dst->totvert; const MEdge *edges_dst = BKE_mesh_edges(me_dst); const int num_edges_dst = me_dst->totedge; @@ -1460,7 +1460,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, space_transform, max_distance, ray_radius, - verts_dst, + positions_dst, num_verts_dst, edges_dst, num_edges_dst, @@ -1507,7 +1507,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, } } if (DT_DATATYPE_IS_LOOP(dtdata_type)) { - const MVert *verts_dst = BKE_mesh_verts(me_dst); + const float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst); const int num_verts_dst = me_dst->totvert; const MEdge *edges_dst = BKE_mesh_edges(me_dst); const int num_edges_dst = me_dst->totedge; @@ -1549,7 +1549,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, max_distance, ray_radius, me_dst, - verts_dst, + positions_dst, num_verts_dst, edges_dst, num_edges_dst, @@ -1604,7 +1604,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, } } if (DT_DATATYPE_IS_POLY(dtdata_type)) { - const MVert *verts_dst = BKE_mesh_verts(me_dst); + const float(*positions_dst)[3] = BKE_mesh_vert_positions(me_dst); const int num_verts_dst = me_dst->totvert; const MPoly *polys_dst = BKE_mesh_polys(me_dst); const int num_polys_dst = me_dst->totpoly; @@ -1641,7 +1641,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, max_distance, ray_radius, me_dst, - verts_dst, + positions_dst, loops_dst, polys_dst, num_polys_dst, diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index ef8a4990842..9fbc95712c2 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -201,7 +201,7 @@ typedef struct PaintBakeData { * 3 float dir vec + 1 float str */ float *brush_velocity; /** copy of previous frame vertices. used to observe surface movement. */ - MVert *prev_verts; + float (*prev_positions)[3]; /** Previous frame object matrix. */ float prev_obmat[4][4]; /** flag to check if surface was cleared/reset -> have to redo velocity etc. */ @@ -900,8 +900,8 @@ static void free_bakeData(PaintSurfaceData *data) if (bData->grid) { freeGrid(data); } - if (bData->prev_verts) { - MEM_freeN(bData->prev_verts); + if (bData->prev_positions) { + MEM_freeN(bData->prev_positions); } if (bData->velocity) { MEM_freeN(bData->velocity); @@ -1774,7 +1774,7 @@ typedef struct DynamicPaintModifierApplyData { const DynamicPaintSurface *surface; Object *ob; - MVert *mvert; + float (*vert_positions)[3]; const float (*vert_normals)[3]; const MLoop *mloop; const MPoly *mpoly; @@ -1791,13 +1791,11 @@ static void dynamic_paint_apply_surface_displace_cb(void *__restrict userdata, const DynamicPaintModifierApplyData *data = userdata; const DynamicPaintSurface *surface = data->surface; - MVert *mvert = data->mvert; const float *value = (float *)surface->data->type_data; const float val = value[i] * surface->disp_factor; - /* same as 'mvert[i].co[0] -= normal[0] * val' etc. */ - madd_v3_v3fl(mvert[i].co, data->vert_normals[i], -val); + madd_v3_v3fl(data->vert_positions[i], data->vert_normals[i], -val); } /* apply displacing vertex surface to the derived mesh */ @@ -1811,11 +1809,9 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh /* displace paint */ if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) { - MVert *mvert = BKE_mesh_verts_for_write(result); - DynamicPaintModifierApplyData data = { .surface = surface, - .mvert = mvert, + .vert_positions = BKE_mesh_vert_positions_for_write(result), .vert_normals = BKE_mesh_vertex_normals_ensure(result), }; TaskParallelSettings settings; @@ -1882,9 +1878,8 @@ static void dynamic_paint_apply_surface_wave_cb(void *__restrict userdata, const DynamicPaintModifierApplyData *data = userdata; PaintWavePoint *wPoint = (PaintWavePoint *)data->surface->data->type_data; - MVert *mvert = data->mvert; - madd_v3_v3fl(mvert[i].co, data->vert_normals[i], wPoint[i].height); + madd_v3_v3fl(data->vert_positions[i], data->vert_normals[i], wPoint[i].height); } /* @@ -2010,11 +2005,9 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * } /* wave simulation */ else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) { - MVert *mvert = BKE_mesh_verts_for_write(result); - DynamicPaintModifierApplyData data = { .surface = surface, - .mvert = mvert, + .vert_positions = BKE_mesh_vert_positions_for_write(result), .vert_normals = BKE_mesh_vertex_normals_ensure(result), }; TaskParallelSettings settings; @@ -2961,7 +2954,6 @@ int dynamicPaint_createUVSurface(Scene *scene, BKE_mesh_vert_looptri_map_create(&vert_to_looptri_map, &vert_to_looptri_map_mem, - BKE_mesh_verts_for_write(mesh), mesh->totvert, mlooptri, tottri, @@ -3413,16 +3405,16 @@ static void mesh_tris_spherecast_dp(void *userdata, BVHTreeRayHit *hit) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; - const MVert *vert = data->vert; + const float(*positions)[3] = data->vert_positions; const MLoopTri *mlooptri = data->looptri; const MLoop *mloop = data->loop; const float *t0, *t1, *t2; float dist; - t0 = vert[mloop[mlooptri[index].tri[0]].v].co; - t1 = vert[mloop[mlooptri[index].tri[1]].v].co; - t2 = vert[mloop[mlooptri[index].tri[2]].v].co; + t0 = positions[mloop[mlooptri[index].tri[0]].v]; + t1 = positions[mloop[mlooptri[index].tri[1]].v]; + t2 = positions[mloop[mlooptri[index].tri[2]].v]; dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2); @@ -3445,15 +3437,15 @@ static void mesh_tris_nearest_point_dp(void *userdata, BVHTreeNearest *nearest) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; - const MVert *vert = data->vert; + const float(*positions)[3] = data->vert_positions; const MLoopTri *mlooptri = data->looptri; const MLoop *mloop = data->loop; float nearest_tmp[3], dist_sq; const float *t0, *t1, *t2; - t0 = vert[mloop[mlooptri[index].tri[0]].v].co; - t1 = vert[mloop[mlooptri[index].tri[1]].v].co; - t2 = vert[mloop[mlooptri[index].tri[2]].v].co; + t0 = positions[mloop[mlooptri[index].tri[0]].v]; + t1 = positions[mloop[mlooptri[index].tri[1]].v]; + t2 = positions[mloop[mlooptri[index].tri[2]].v]; closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2); dist_sq = len_squared_v3v3(co, nearest_tmp); @@ -3709,8 +3701,8 @@ static bool meshBrush_boundsIntersect(Bounds3D *b1, typedef struct DynamicPaintBrushVelocityData { Vec3f *brush_vel; - const MVert *mvert_p; - const MVert *mvert_c; + const float (*positions_p)[3]; + const float (*positions_c)[3]; float (*obmat)[4]; float (*prev_obmat)[4]; @@ -3726,8 +3718,8 @@ static void dynamic_paint_brush_velocity_compute_cb(void *__restrict userdata, Vec3f *brush_vel = data->brush_vel; - const MVert *mvert_p = data->mvert_p; - const MVert *mvert_c = data->mvert_c; + const float(*positions_p)[3] = data->positions_p; + const float(*positions_c)[3] = data->positions_c; float(*obmat)[4] = data->obmat; float(*prev_obmat)[4] = data->prev_obmat; @@ -3736,10 +3728,10 @@ static void dynamic_paint_brush_velocity_compute_cb(void *__restrict userdata, float p1[3], p2[3]; - copy_v3_v3(p1, mvert_p[i].co); + copy_v3_v3(p1, positions_p[i]); mul_m4_v3(prev_obmat, p1); - copy_v3_v3(p2, mvert_c[i].co); + copy_v3_v3(p2, positions_c[i]); mul_m4_v3(obmat, p2); sub_v3_v3v3(brush_vel[i].v, p2, p1); @@ -3755,7 +3747,6 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, { float prev_obmat[4][4]; Mesh *mesh_p, *mesh_c; - MVert *mvert_p, *mvert_c; int numOfVerts_p, numOfVerts_c; float cur_sfra = scene->r.subframe; @@ -3782,7 +3773,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, mesh_p = BKE_mesh_copy_for_eval(dynamicPaint_brush_mesh_get(brush), false); numOfVerts_p = mesh_p->totvert; - mvert_p = BKE_mesh_verts_for_write(mesh_p); + float(*positions_p)[3] = BKE_mesh_vert_positions_for_write(mesh_p); copy_m4_m4(prev_obmat, ob->object_to_world); /* current frame mesh */ @@ -3798,7 +3789,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, eModifierType_DynamicPaint); mesh_c = dynamicPaint_brush_mesh_get(brush); numOfVerts_c = mesh_c->totvert; - mvert_c = BKE_mesh_verts_for_write(mesh_c); + float(*positions_c)[3] = BKE_mesh_vert_positions_for_write(mesh_c); (*brushVel) = (struct Vec3f *)MEM_mallocN(numOfVerts_c * sizeof(Vec3f), "Dynamic Paint brush velocity"); @@ -3808,14 +3799,14 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, /* if mesh is constructive -> num of verts has changed, only use current frame derived mesh */ if (numOfVerts_p != numOfVerts_c) { - mvert_p = mvert_c; + positions_p = positions_c; } /* calculate speed */ DynamicPaintBrushVelocityData data = { .brush_vel = *brushVel, - .mvert_p = mvert_p, - .mvert_c = mvert_c, + .positions_p = positions_p, + .positions_c = positions_c, .obmat = ob->object_to_world, .prev_obmat = prev_obmat, .timescale = timescale, @@ -3886,7 +3877,7 @@ typedef struct DynamicPaintPaintData { const int c_index; Mesh *mesh; - const MVert *mvert; + const float (*positions)[3]; const MLoop *mloop; const MLoopTri *mlooptri; const float brush_radius; @@ -3919,7 +3910,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex( const float timescale = data->timescale; const int c_index = data->c_index; - const MVert *mvert = data->mvert; + const float(*positions)[3] = data->positions; const MLoop *mloop = data->mloop; const MLoopTri *mlooptri = data->mlooptri; const float brush_radius = data->brush_radius; @@ -4000,7 +3991,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex( }; float dot; - normal_tri_v3(hit.no, mvert[vtri[0]].co, mvert[vtri[1]].co, mvert[vtri[2]].co); + normal_tri_v3(hit.no, positions[vtri[0]], positions[vtri[1]], positions[vtri[2]]); dot = dot_v3v3(ray_dir, hit.no); /* If ray and hit face normal are facing same direction @@ -4149,7 +4140,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex( const int v3 = mloop[mlooptri[hitTri].tri[2]].v; /* calculate barycentric weights for hit point */ - interp_weights_tri_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, hitCoord); + interp_weights_tri_v3(weights, positions[v1], positions[v2], positions[v3], hitCoord); /* Simple check based on brush surface velocity, * TODO: perhaps implement something that handles volume movement as well. */ @@ -4245,7 +4236,6 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, PaintBakeData *bData = sData->bData; Mesh *mesh = NULL; Vec3f *brushVelocity = NULL; - MVert *mvert = NULL; const MLoopTri *mlooptri = NULL; const MLoop *mloop = NULL; @@ -4269,7 +4259,7 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, VolumeGrid *grid = bData->grid; mesh = BKE_mesh_copy_for_eval(brush_mesh, false); - mvert = BKE_mesh_verts_for_write(mesh); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); mloop = BKE_mesh_loops(mesh); @@ -4279,8 +4269,8 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, * (Faster than transforming per surface point * coordinates and normals to object space) */ for (ii = 0; ii < numOfVerts; ii++) { - mul_m4_v3(brushOb->object_to_world, mvert[ii].co); - boundInsert(&mesh_bb, mvert[ii].co); + mul_m4_v3(brushOb->object_to_world, positions[ii]); + boundInsert(&mesh_bb, positions[ii]); /* for proximity project calculate average normal */ if (brush->flags & MOD_DPAINT_PROX_PROJECT && brush->collision != MOD_DPAINT_COL_VOLUME) { @@ -4325,7 +4315,7 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, .timescale = timescale, .c_index = c_index, .mesh = mesh, - .mvert = mvert, + .positions = positions, .mloop = mloop, .mlooptri = mlooptri, .brush_radius = brush_radius, @@ -4758,7 +4748,7 @@ static bool dynamicPaint_paintSinglePoint( } const Mesh *brush_mesh = dynamicPaint_brush_mesh_get(brush); - const MVert *mvert = BKE_mesh_verts(brush_mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(brush_mesh); /* * Loop through every surface point @@ -4769,7 +4759,7 @@ static bool dynamicPaint_paintSinglePoint( .brushOb = brushOb, .scene = scene, .timescale = timescale, - .mvert = mvert, + .positions = positions, .brush_radius = brush_radius, .brushVelocity = &brushVel, .pointCoord = pointCoord, @@ -5861,11 +5851,11 @@ static bool dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *o PaintSurfaceData *sData = surface->data; PaintBakeData *bData = sData->bData; Mesh *mesh = dynamicPaint_canvas_mesh_get(surface->canvas); - const MVert *mvert = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); int numOfVerts = mesh->totvert; - if (!bData->prev_verts) { + if (!bData->prev_positions) { return true; } @@ -5876,7 +5866,7 @@ static bool dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *o /* vertices */ for (int i = 0; i < numOfVerts; i++) { - if (!equals_v3v3(bData->prev_verts[i].co, mvert[i].co)) { + if (!equals_v3v3(bData->prev_positions[i], positions[i])) { return true; } } @@ -5889,7 +5879,7 @@ typedef struct DynamicPaintGenerateBakeData { const DynamicPaintSurface *surface; Object *ob; - const MVert *mvert; + const float (*positions)[3]; const float (*vert_normals)[3]; const Vec3f *canvas_verts; @@ -6021,7 +6011,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface, const bool do_accel_data = (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) != 0; int canvasNumOfVerts = mesh->totvert; - const MVert *mvert = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); Vec3f *canvas_verts; if (bData) { @@ -6067,8 +6057,8 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface, bData->s_num = MEM_mallocN(sData->total_points * sizeof(uint), "Dynamic Paint bData s_num"); bData->realCoord = (struct Vec3f *)MEM_mallocN(surface_totalSamples(surface) * sizeof(Vec3f), "Dynamic Paint point coords"); - bData->prev_verts = MEM_mallocN(canvasNumOfVerts * sizeof(MVert), - "Dynamic Paint bData prev_verts"); + bData->prev_positions = MEM_mallocN(canvasNumOfVerts * sizeof(float[3]), + "Dynamic Paint bData prev_positions"); /* if any allocation failed, free everything */ if (!bData->bNormal || !bData->s_pos || !bData->s_num || !bData->realCoord || !canvas_verts) { @@ -6112,7 +6102,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface, */ bData->mesh_bounds.valid = false; for (index = 0; index < canvasNumOfVerts; index++) { - copy_v3_v3(canvas_verts[index].v, mvert[index].co); + copy_v3_v3(canvas_verts[index].v, positions[index]); mul_m4_v3(ob->object_to_world, canvas_verts[index].v); boundInsert(&bData->mesh_bounds, canvas_verts[index].v); } @@ -6123,7 +6113,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface, DynamicPaintGenerateBakeData data = { .surface = surface, .ob = ob, - .mvert = mvert, + .positions = positions, .vert_normals = BKE_mesh_vertex_normals_ensure(mesh), .canvas_verts = canvas_verts, .do_velocity_data = do_velocity_data, @@ -6144,7 +6134,7 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface, /* Copy current frame vertices to check against in next frame */ copy_m4_m4(bData->prev_obmat, ob->object_to_world); - memcpy(bData->prev_verts, mvert, canvasNumOfVerts * sizeof(MVert)); + memcpy(bData->prev_positions, positions, canvasNumOfVerts * sizeof(float[3])); bData->clear = 0; diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index c2ae4efbde8..84fda9034cb 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -663,9 +663,9 @@ bool closest_point_on_surface(SurfaceModifierData *surmd, const MLoop *mloop = surmd->bvhtree->loop; const MLoopTri *lt = &surmd->bvhtree->looptri[nearest.index]; - copy_v3_v3(surface_vel, surmd->v[mloop[lt->tri[0]].v].co); - add_v3_v3(surface_vel, surmd->v[mloop[lt->tri[1]].v].co); - add_v3_v3(surface_vel, surmd->v[mloop[lt->tri[2]].v].co); + copy_v3_v3(surface_vel, surmd->v[mloop[lt->tri[0]].v]); + add_v3_v3(surface_vel, surmd->v[mloop[lt->tri[1]].v]); + add_v3_v3(surface_vel, surmd->v[mloop[lt->tri[2]].v]); mul_v3_fl(surface_vel, (1.0f / 3.0f)); } @@ -701,10 +701,10 @@ bool get_effector_data(EffectorCache *eff, else if (eff->pd && eff->pd->shape == PFIELD_SHAPE_POINTS) { /* TODO: hair and points object support */ const Mesh *me_eval = BKE_object_get_evaluated_mesh(eff->ob); - const MVert *verts = BKE_mesh_verts(me_eval); + const float(*positions)[3] = BKE_mesh_vert_positions(me_eval); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me_eval); if (me_eval != NULL) { - copy_v3_v3(efd->loc, verts[*efd->index].co); + copy_v3_v3(efd->loc, positions[*efd->index]); copy_v3_v3(efd->nor, vert_normals[*efd->index]); mul_m4_v3(eff->ob->object_to_world, efd->loc); diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index c72f498cd5a..bd8acfe626f 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -404,7 +404,7 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds, float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; float size[3]; - MVert *verts = BKE_mesh_verts_for_write(me); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(me); float scale = 0.0; int res; @@ -412,7 +412,7 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds, /* Set minimum and maximum coordinates of BB. */ for (i = 0; i < me->totvert; i++) { - minmax_v3v3_v3(min, max, verts[i].co); + minmax_v3v3_v3(min, max, positions[i]); } /* Set domain bounds. */ @@ -840,7 +840,7 @@ BLI_INLINE void apply_effector_fields(FluidEffectorSettings *UNUSED(fes), } static void update_velocities(FluidEffectorSettings *fes, - const MVert *mvert, + const float (*vert_positions)[3], const MLoop *mloop, const MLoopTri *mlooptri, float *velocity_map, @@ -870,7 +870,8 @@ static void update_velocities(FluidEffectorSettings *fes, v1 = mloop[mlooptri[f_index].tri[0]].v; v2 = mloop[mlooptri[f_index].tri[1]].v; v3 = mloop[mlooptri[f_index].tri[2]].v; - interp_weights_tri_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, nearest.co); + interp_weights_tri_v3( + weights, vert_positions[v1], vert_positions[v2], vert_positions[v3], nearest.co); /* Apply object velocity. */ float hit_vel[3]; @@ -937,7 +938,7 @@ static void update_velocities(FluidEffectorSettings *fes, typedef struct ObstaclesFromDMData { FluidEffectorSettings *fes; - const MVert *mvert; + const float (*vert_positions)[3]; const MLoop *mloop; const MLoopTri *mlooptri; @@ -972,7 +973,7 @@ static void obstacles_from_mesh_task_cb(void *__restrict userdata, /* Calculate object velocities. Result in bb->velocity. */ update_velocities(data->fes, - data->mvert, + data->vert_positions, data->mloop, data->mlooptri, bb->velocity, @@ -1005,7 +1006,7 @@ static void obstacles_from_mesh(Object *coll_ob, bool has_velocity = false; Mesh *me = BKE_mesh_copy_for_eval(fes->mesh, false); - MVert *verts = BKE_mesh_verts_for_write(me); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(me); int min[3], max[3], res[3]; @@ -1036,11 +1037,11 @@ static void obstacles_from_mesh(Object *coll_ob, float co[3]; /* Vertex position. */ - mul_m4_v3(coll_ob->object_to_world, verts[i].co); - manta_pos_to_cell(fds, verts[i].co); + mul_m4_v3(coll_ob->object_to_world, positions[i]); + manta_pos_to_cell(fds, positions[i]); /* Vertex velocity. */ - add_v3fl_v3fl_v3i(co, verts[i].co, fds->shift); + add_v3fl_v3fl_v3i(co, positions[i], fds->shift); if (has_velocity) { sub_v3_v3v3(&vert_vel[i * 3], co, &fes->verts_old[i * 3]); mul_v3_fl(&vert_vel[i * 3], 1.0f / dt); @@ -1048,7 +1049,7 @@ static void obstacles_from_mesh(Object *coll_ob, copy_v3_v3(&fes->verts_old[i * 3], co); /* Calculate emission map bounds. */ - bb_boundInsert(bb, verts[i].co); + bb_boundInsert(bb, positions[i]); } /* Set emission map. @@ -1070,7 +1071,7 @@ static void obstacles_from_mesh(Object *coll_ob, ObstaclesFromDMData data = { .fes = fes, - .mvert = verts, + .vert_positions = positions, .mloop = mloop, .mlooptri = looptri, .tree = &tree_data, @@ -1784,7 +1785,7 @@ static void update_distances(int index, } static void sample_mesh(FluidFlowSettings *ffs, - const MVert *mvert, + const float (*vert_positions)[3], const float (*vert_normals)[3], const MLoop *mloop, const MLoopTri *mlooptri, @@ -1872,7 +1873,8 @@ static void sample_mesh(FluidFlowSettings *ffs, v1 = mloop[mlooptri[f_index].tri[0]].v; v2 = mloop[mlooptri[f_index].tri[1]].v; v3 = mloop[mlooptri[f_index].tri[2]].v; - interp_weights_tri_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, nearest.co); + interp_weights_tri_v3( + weights, vert_positions[v1], vert_positions[v2], vert_positions[v3], nearest.co); /* Compute emission strength for smoke flow. */ if (is_gas_flow) { @@ -1978,7 +1980,7 @@ typedef struct EmitFromDMData { FluidDomainSettings *fds; FluidFlowSettings *ffs; - const MVert *mvert; + const float (*vert_positions)[3]; const float (*vert_normals)[3]; const MLoop *mloop; const MLoopTri *mlooptri; @@ -2012,7 +2014,7 @@ static void emit_from_mesh_task_cb(void *__restrict userdata, * Result in bb->influence. Also computes initial velocities. Result in bb->velocity. */ if (ELEM(data->ffs->behavior, FLUID_FLOW_BEHAVIOR_GEOMETRY, FLUID_FLOW_BEHAVIOR_INFLOW)) { sample_mesh(data->ffs, - data->mvert, + data->vert_positions, data->vert_normals, data->mloop, data->mlooptri, @@ -2062,7 +2064,7 @@ static void emit_from_mesh( /* Copy mesh for thread safety as we modify it. * Main issue is its VertArray being modified, then replaced and freed. */ Mesh *me = BKE_mesh_copy_for_eval(ffs->mesh, false); - MVert *verts = BKE_mesh_verts_for_write(me); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(me); const MLoop *mloop = BKE_mesh_loops(me); const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me); @@ -2091,8 +2093,8 @@ static void emit_from_mesh( float(*vert_normals)[3] = BKE_mesh_vertex_normals_for_write(me); for (i = 0; i < numverts; i++) { /* Vertex position. */ - mul_m4_v3(flow_ob->object_to_world, verts[i].co); - manta_pos_to_cell(fds, verts[i].co); + mul_m4_v3(flow_ob->object_to_world, positions[i]); + manta_pos_to_cell(fds, positions[i]); /* Vertex normal. */ mul_mat3_m4_v3(flow_ob->object_to_world, vert_normals[i]); @@ -2102,7 +2104,7 @@ static void emit_from_mesh( /* Vertex velocity. */ if (ffs->flags & FLUID_FLOW_INITVELOCITY) { float co[3]; - add_v3fl_v3fl_v3i(co, verts[i].co, fds->shift); + add_v3fl_v3fl_v3i(co, positions[i], fds->shift); if (has_velocity) { sub_v3_v3v3(&vert_vel[i * 3], co, &ffs->verts_old[i * 3]); mul_v3_fl(&vert_vel[i * 3], 1.0 / dt); @@ -2111,7 +2113,7 @@ static void emit_from_mesh( } /* Calculate emission map bounds. */ - bb_boundInsert(bb, verts[i].co); + bb_boundInsert(bb, positions[i]); } mul_m4_v3(flow_ob->object_to_world, flow_center); manta_pos_to_cell(fds, flow_center); @@ -2136,7 +2138,7 @@ static void emit_from_mesh( EmitFromDMData data = { .fds = fds, .ffs = ffs, - .mvert = verts, + .vert_positions = positions, .vert_normals = vert_normals, .mloop = mloop, .mlooptri = mlooptri, @@ -3204,7 +3206,6 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, Object *ob) { Mesh *me; - MVert *mverts; MPoly *mpolys; MLoop *mloops; float min[3]; @@ -3248,7 +3249,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, if (!me) { return NULL; } - mverts = BKE_mesh_verts_for_write(me); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(me); mpolys = BKE_mesh_polys_for_write(me); mloops = BKE_mesh_loops_for_write(me); @@ -3285,30 +3286,30 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, } /* Loop for vertices and normals. */ - for (i = 0; i < num_verts; i++, mverts++) { + for (i = 0; i < num_verts; i++) { /* Vertices (data is normalized cube around domain origin). */ - mverts->co[0] = manta_liquid_get_vertex_x_at(fds->fluid, i); - mverts->co[1] = manta_liquid_get_vertex_y_at(fds->fluid, i); - mverts->co[2] = manta_liquid_get_vertex_z_at(fds->fluid, i); + positions[i][0] = manta_liquid_get_vertex_x_at(fds->fluid, i); + positions[i][1] = manta_liquid_get_vertex_y_at(fds->fluid, i); + positions[i][2] = manta_liquid_get_vertex_z_at(fds->fluid, i); /* Adjust coordinates from Mantaflow to match viewport scaling. */ float tmp[3] = {(float)fds->res[0], (float)fds->res[1], (float)fds->res[2]}; /* Scale to unit cube around 0. */ mul_v3_fl(tmp, fds->mesh_scale * 0.5f); - sub_v3_v3(mverts->co, tmp); + sub_v3_v3(positions[i], tmp); /* Apply scaling of domain object. */ - mul_v3_fl(mverts->co, fds->dx / fds->mesh_scale); + mul_v3_fl(positions[i], fds->dx / fds->mesh_scale); - mul_v3_v3(mverts->co, co_scale); - add_v3_v3(mverts->co, co_offset); + mul_v3_v3(positions[i], co_scale); + add_v3_v3(positions[i], co_offset); # ifdef DEBUG_PRINT /* Debugging: Print coordinates of vertices. */ - printf("mverts->co[0]: %f, mverts->co[1]: %f, mverts->co[2]: %f\n", - mverts->co[0], - mverts->co[1], - mverts->co[2]); + printf("positions[i][0]: %f, positions[i][1]: %f, positions[i][2]: %f\n", + positions[i][0], + positions[i][1], + positions[i][2]); # endif # ifdef DEBUG_PRINT @@ -3364,7 +3365,6 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Object *ob) { Mesh *result; - MVert *mverts; MPoly *mpolys; MLoop *mloops; float min[3]; @@ -3384,7 +3384,7 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje } result = BKE_mesh_new_nomain(num_verts, 0, 0, num_faces * 4, num_faces); - mverts = BKE_mesh_verts_for_write(result); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(result); mpolys = BKE_mesh_polys_for_write(result); mloops = BKE_mesh_loops_for_write(result); @@ -3395,36 +3395,36 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje /* Set vertices of smoke BB. Especially important, when BB changes (adaptive domain). */ /* Top slab */ - co = mverts[0].co; + co = positions[0]; co[0] = min[0]; co[1] = min[1]; co[2] = max[2]; - co = mverts[1].co; + co = positions[1]; co[0] = max[0]; co[1] = min[1]; co[2] = max[2]; - co = mverts[2].co; + co = positions[2]; co[0] = max[0]; co[1] = max[1]; co[2] = max[2]; - co = mverts[3].co; + co = positions[3]; co[0] = min[0]; co[1] = max[1]; co[2] = max[2]; /* Bottom slab. */ - co = mverts[4].co; + co = positions[4]; co[0] = min[0]; co[1] = min[1]; co[2] = min[2]; - co = mverts[5].co; + co = positions[5]; co[0] = max[0]; co[1] = min[1]; co[2] = min[2]; - co = mverts[6].co; + co = positions[6]; co[0] = max[0]; co[1] = max[1]; co[2] = min[2]; - co = mverts[7].co; + co = positions[7]; co[0] = min[0]; co[1] = max[1]; co[2] = min[2]; @@ -3495,7 +3495,7 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje mul_mat3_m4_v3(ob->world_to_object, fds->obj_shift_f); /* Apply shift to vertices. */ for (int i = 0; i < num_verts; i++) { - add_v3_v3(mverts[i].co, fds->obj_shift_f); + add_v3_v3(positions[i], fds->obj_shift_f); } } diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index f587f2ced47..186ac90c2c7 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -904,16 +904,6 @@ static GVMutableArray make_derived_write_attribute(void *data, const int domain_ MutableSpan((StructT *)data, domain_num)); } -static float3 get_vertex_position(const MVert &vert) -{ - return float3(vert.co); -} - -static void set_vertex_position(MVert &vert, float3 position) -{ - copy_v3_v3(vert.co, position); -} - static void tag_component_positions_changed(void *owner) { Mesh *mesh = static_cast(owner); @@ -1237,18 +1227,17 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() #undef MAKE_CONST_CUSTOM_DATA_GETTER #undef MAKE_MUTABLE_CUSTOM_DATA_GETTER - static BuiltinCustomDataLayerProvider position( - "position", - ATTR_DOMAIN_POINT, - CD_PROP_FLOAT3, - CD_MVERT, - BuiltinAttributeProvider::NonCreatable, - BuiltinAttributeProvider::Writable, - BuiltinAttributeProvider::NonDeletable, - point_access, - make_derived_read_attribute, - make_derived_write_attribute, - tag_component_positions_changed); + static BuiltinCustomDataLayerProvider position("position", + ATTR_DOMAIN_POINT, + CD_PROP_FLOAT3, + CD_PROP_FLOAT3, + BuiltinAttributeProvider::NonCreatable, + BuiltinAttributeProvider::Writable, + BuiltinAttributeProvider::NonDeletable, + point_access, + make_array_read_attribute, + make_array_write_attribute, + tag_component_positions_changed); static NormalAttributeProvider normal; diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc index 5bdb450596b..e209c772fa0 100644 --- a/source/blender/blenkernel/intern/gpencil_geom.cc +++ b/source/blender/blenkernel/intern/gpencil_geom.cc @@ -2471,7 +2471,7 @@ static void gpencil_generate_edgeloops(Object *ob, if (me->totedge == 0) { return; } - const Span verts = me->verts(); + const Span vert_positions = me->vert_positions(); const Span edges = me->edges(); const Span dverts = me->deform_verts(); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me); @@ -2488,18 +2488,16 @@ static void gpencil_generate_edgeloops(Object *ob, for (int i = 0; i < me->totedge; i++) { const MEdge *ed = &edges[i]; gped = &gp_edges[i]; - const MVert *mv1 = &verts[ed->v1]; copy_v3_v3(gped->n1, vert_normals[ed->v1]); gped->v1 = ed->v1; - copy_v3_v3(gped->v1_co, mv1->co); + copy_v3_v3(gped->v1_co, vert_positions[ed->v1]); - const MVert *mv2 = &verts[ed->v2]; copy_v3_v3(gped->n2, vert_normals[ed->v2]); gped->v2 = ed->v2; - copy_v3_v3(gped->v2_co, mv2->co); + copy_v3_v3(gped->v2_co, vert_positions[ed->v2]); - sub_v3_v3v3(gped->vec, mv1->co, mv2->co); + sub_v3_v3v3(gped->vec, vert_positions[ed->v1], vert_positions[ed->v2]); /* If use seams, mark as done if not a seam. */ if ((use_seams) && ((ed->flag & ME_SEAM) == 0)) { @@ -2559,13 +2557,11 @@ static void gpencil_generate_edgeloops(Object *ob, float fpt[3]; for (int i = 0; i < array_len + 1; i++) { int vertex_index = i == 0 ? gp_edges[stroke[0]].v1 : gp_edges[stroke[i - 1]].v2; - const MVert *mv = &verts[vertex_index]; - /* Add segment. */ bGPDspoint *pt = &gps_stroke->points[i]; copy_v3_v3(fpt, vert_normals[vertex_index]); mul_v3_v3fl(fpt, fpt, offset); - add_v3_v3v3(&pt->x, mv->co, fpt); + add_v3_v3v3(&pt->x, vert_positions[vertex_index], fpt); mul_m4_v3(matrix, &pt->x); pt->pressure = 1.0f; @@ -2683,7 +2679,7 @@ bool BKE_gpencil_convert_mesh(Main *bmain, /* Use evaluated data to get mesh with all modifiers on top. */ Object *ob_eval = (Object *)DEG_get_evaluated_object(depsgraph, ob_mesh); const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval); - const Span verts = me_eval->verts(); + const Span positions = me_eval->vert_positions(); const Span polys = me_eval->polys(); const Span loops = me_eval->loops(); int mpoly_len = me_eval->totpoly; @@ -2758,10 +2754,9 @@ bool BKE_gpencil_convert_mesh(Main *bmain, /* Add points to strokes. */ for (int j = 0; j < mp->totloop; j++) { const MLoop *ml = &loops[mp->loopstart + j]; - const MVert *mv = &verts[ml->v]; bGPDspoint *pt = &gps_fill->points[j]; - copy_v3_v3(&pt->x, mv->co); + copy_v3_v3(&pt->x, positions[ml->v]); mul_m4_v3(matrix, &pt->x); pt->pressure = 1.0f; pt->strength = 1.0f; diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index f8d7f822e7d..c4e083f9fc5 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -1508,7 +1508,6 @@ static void do_latt_key(Object *ob, Key *key, char *out, const int tot) } } -static void keyblock_data_convert_to_mesh(const float (*fp)[3], MVert *mvert, const int totvert); static void keyblock_data_convert_to_lattice(const float (*fp)[3], BPoint *bpoint, const int totpoint); @@ -1608,9 +1607,9 @@ float *BKE_key_evaluate_object_ex( switch (GS(obdata->name)) { case ID_ME: { Mesh *mesh = (Mesh *)obdata; - MVert *verts = BKE_mesh_verts_for_write(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); const int totvert = min_ii(tot, mesh->totvert); - keyblock_data_convert_to_mesh((const float(*)[3])out, verts, totvert); + memcpy(out, positions, sizeof(float[3]) * totvert); break; } case ID_LT: { @@ -2187,21 +2186,15 @@ void BKE_keyblock_convert_to_curve(KeyBlock *kb, Curve * /*cu*/, ListBase *nurb) void BKE_keyblock_update_from_mesh(const Mesh *me, KeyBlock *kb) { - float(*fp)[3]; - int a, tot; - BLI_assert(me->totvert == kb->totelem); - tot = me->totvert; + const int tot = me->totvert; if (tot == 0) { return; } - const MVert *mvert = BKE_mesh_verts(me); - fp = static_cast(kb->data); - for (a = 0; a < tot; a++, fp++, mvert++) { - copy_v3_v3(*fp, mvert->co); - } + const float(*positions)[3] = BKE_mesh_vert_positions(me); + memcpy(kb->data, positions, sizeof(float[3]) * tot); } void BKE_keyblock_convert_from_mesh(const Mesh *me, const Key *key, KeyBlock *kb) @@ -2220,19 +2213,12 @@ void BKE_keyblock_convert_from_mesh(const Mesh *me, const Key *key, KeyBlock *kb BKE_keyblock_update_from_mesh(me, kb); } -static void keyblock_data_convert_to_mesh(const float (*fp)[3], MVert *mvert, const int totvert) +void BKE_keyblock_convert_to_mesh(const KeyBlock *kb, + float (*vert_positions)[3], + const int totvert) { - for (int i = 0; i < totvert; i++, fp++, mvert++) { - copy_v3_v3(mvert->co, *fp); - } -} - -void BKE_keyblock_convert_to_mesh(const KeyBlock *kb, MVert *mvert, const int totvert) -{ - const float(*fp)[3] = static_cast(kb->data); const int tot = min_ii(kb->totelem, totvert); - - keyblock_data_convert_to_mesh(fp, mvert, tot); + memcpy(kb->data, vert_positions, sizeof(float[3]) * tot); } void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, @@ -2245,8 +2231,8 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, return; } - MVert *verts = static_cast(MEM_dupallocN(BKE_mesh_verts(mesh))); - BKE_keyblock_convert_to_mesh(kb, verts, mesh->totvert); + float(*positions)[3] = static_cast(MEM_dupallocN(BKE_mesh_vert_positions(mesh))); + BKE_keyblock_convert_to_mesh(kb, positions, mesh->totvert); const MEdge *edges = BKE_mesh_edges(mesh); const MPoly *polys = BKE_mesh_polys(mesh); const MLoop *loops = BKE_mesh_loops(mesh); @@ -2273,10 +2259,10 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, if (poly_normals_needed) { BKE_mesh_calc_normals_poly( - verts, mesh->totvert, loops, mesh->totloop, polys, mesh->totpoly, poly_normals); + positions, mesh->totvert, loops, mesh->totloop, polys, mesh->totpoly, poly_normals); } if (vert_normals_needed) { - BKE_mesh_calc_normals_poly_and_vertex(verts, + BKE_mesh_calc_normals_poly_and_vertex(positions, mesh->totvert, loops, mesh->totloop, @@ -2288,7 +2274,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, if (loop_normals_needed) { short(*clnors)[2] = static_cast( CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL)); /* May be nullptr. */ - BKE_mesh_normals_loop_split(verts, + BKE_mesh_normals_loop_split(positions, vert_normals, mesh->totvert, edges, @@ -2312,7 +2298,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, if (free_poly_normals) { MEM_freeN(poly_normals); } - MEM_freeN(verts); + MEM_freeN(positions); } /************************* raw coords ************************/ diff --git a/source/blender/blenkernel/intern/mball_tessellate.cc b/source/blender/blenkernel/intern/mball_tessellate.cc index 1e3519847fe..12ed0fc0fc9 100644 --- a/source/blender/blenkernel/intern/mball_tessellate.cc +++ b/source/blender/blenkernel/intern/mball_tessellate.cc @@ -1463,12 +1463,9 @@ Mesh *BKE_mball_polygonize(Depsgraph *depsgraph, Scene *scene, Object *ob) Mesh *mesh = (Mesh *)BKE_id_new_nomain(ID_ME, ((ID *)ob->data)->name + 2); mesh->totvert = int(process.curvertex); - MVert *mvert = static_cast( - CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CONSTRUCT, nullptr, mesh->totvert)); - for (int i = 0; i < mesh->totvert; i++) { - copy_v3_v3(mvert[i].co, process.co[i]); - } - MEM_freeN(process.co); + CustomData_add_layer_named( + &mesh->vdata, CD_PROP_FLOAT3, CD_ASSIGN, process.co, mesh->totvert, "position"); + process.co = nullptr; mesh->totpoly = int(process.curindex); MPoly *mpoly = static_cast( diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 30ed0e2ad02..b35f5d6aa83 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -18,6 +18,7 @@ #include "DNA_object_types.h" #include "BLI_bit_vector.hh" +#include "BLI_bounds.hh" #include "BLI_edgehash.h" #include "BLI_endian_switch.h" #include "BLI_ghash.h" @@ -28,6 +29,7 @@ #include "BLI_math.h" #include "BLI_math_vector.hh" #include "BLI_memarena.h" +#include "BLI_resource_scope.hh" #include "BLI_span.hh" #include "BLI_string.h" #include "BLI_task.hh" @@ -228,6 +230,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address Vector edge_layers; Vector loop_layers; Vector poly_layers; + blender::ResourceScope temp_arrays_for_legacy_format; /* cache only - don't write */ mesh->mface = nullptr; @@ -251,6 +254,18 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address else { Set names_to_skip; if (!BLO_write_is_undo(writer)) { + /* When converting to the old mesh format, don't save redundant attributes. */ + names_to_skip.add_multiple_new({".hide_vert", + ".hide_edge", + ".hide_poly", + "position", + "material_index", + ".select_vert", + ".select_edge", + ".select_poly"}); + + mesh->mvert = BKE_mesh_legacy_convert_positions_to_verts( + mesh, temp_arrays_for_legacy_format, vert_layers); BKE_mesh_legacy_convert_hide_layers_to_flags(mesh); BKE_mesh_legacy_convert_selection_layers_to_flags(mesh); BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh); @@ -261,17 +276,8 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address mesh->active_color_attribute = nullptr; mesh->default_color_attribute = nullptr; BKE_mesh_legacy_convert_loose_edges_to_flag(mesh); - /* When converting to the old mesh format, don't save redundant attributes. */ - names_to_skip.add_multiple_new({".hide_vert", - ".hide_edge", - ".hide_poly", - "material_index", - ".select_vert", - ".select_edge", - ".select_poly"}); /* Set deprecated mesh data pointers for forward compatibility. */ - mesh->mvert = const_cast(mesh->verts().data()); mesh->medge = const_cast(mesh->edges().data()); mesh->mpoly = const_cast(mesh->polys().data()); mesh->mloop = const_cast(mesh->loops().data()); @@ -480,9 +486,8 @@ static int customdata_compare( const float thresh_sq = thresh * thresh; 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_PROP_BYTE_COLOR | - CD_MASK_MDEFORMVERT; + const uint64_t cd_mask_non_generic = CD_MASK_MEDGE | CD_MASK_MPOLY | 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; const Span loops_1 = m1->loops(); const Span loops_2 = m2->loops(); @@ -525,22 +530,6 @@ static int customdata_compare( found_corresponding_layer = true; switch (l1->type) { - - case CD_MVERT: { - MVert *v1 = (MVert *)l1->data; - MVert *v2 = (MVert *)l2->data; - int vtot = m1->totvert; - - for (j = 0; j < vtot; j++, v1++, v2++) { - for (int k = 0; k < 3; k++) { - if (compare_threshold_relative(v1->co[k], v2->co[k], thresh)) { - return MESHCMP_VERTCOMISMATCH; - } - } - } - break; - } - /* We're order-agnostic for edges here. */ case CD_MEDGE: { MEdge *e1 = (MEdge *)l1->data; @@ -788,6 +777,11 @@ const char *BKE_mesh_cmp(Mesh *me1, Mesh *me2, float thresh) return nullptr; } +bool BKE_mesh_attribute_required(const char *name) +{ + return StringRef(name) == "position"; +} + void BKE_mesh_ensure_skin_customdata(Mesh *me) { BMesh *bm = me->edit_mesh ? me->edit_mesh->bm : nullptr; @@ -936,8 +930,9 @@ Mesh *BKE_mesh_add(Main *bmain, const char *name) /* Custom data layer functions; those assume that totXXX are set correctly. */ static void mesh_ensure_cdlayers_primary(Mesh *mesh, bool do_tessface) { - if (!CustomData_get_layer(&mesh->vdata, CD_MVERT)) { - CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, mesh->totvert); + if (!CustomData_get_layer_named(&mesh->vdata, CD_PROP_FLOAT3, "position")) { + CustomData_add_layer_named( + &mesh->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, mesh->totvert, "position"); } if (!CustomData_get_layer(&mesh->edata, CD_MEDGE)) { CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, mesh->totedge); @@ -1293,12 +1288,12 @@ float (*BKE_mesh_orco_verts_get(Object *ob))[3] /* Get appropriate vertex coordinates */ float(*vcos)[3] = (float(*)[3])MEM_calloc_arrayN(me->totvert, sizeof(*vcos), "orco mesh"); - const Span verts = tme->verts(); + const Span positions = tme->vert_positions(); int totvert = min_ii(tme->totvert, me->totvert); for (int a = 0; a < totvert; a++) { - copy_v3_v3(vcos[a], verts[a].co); + copy_v3_v3(vcos[a], positions[a]); } return vcos; @@ -1548,23 +1543,8 @@ bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3]) return false; } - me->runtime->bounds_cache.ensure([me](Bounds &r_bounds) { - const Span verts = me->verts(); - r_bounds = threading::parallel_reduce( - verts.index_range(), - 1024, - Bounds{float3(FLT_MAX), float3(-FLT_MAX)}, - [verts](IndexRange range, const Bounds &init) { - Bounds result = init; - for (const int i : range) { - math::min_max(float3(verts[i].co), result.min, result.max); - } - return result; - }, - [](const Bounds &a, const Bounds &b) { - return Bounds{math::min(a.min, b.min), math::max(a.max, b.max)}; - }); - }); + me->runtime->bounds_cache.ensure( + [me](Bounds &r_bounds) { r_bounds = *bounds::min_max(me->vert_positions()); }); const Bounds &bounds = me->runtime->bounds_cache.data(); copy_v3_v3(r_min, math::min(bounds.min, float3(r_min))); @@ -1575,10 +1555,10 @@ bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3]) void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys) { - MutableSpan verts = me->verts_for_write(); + MutableSpan positions = me->vert_positions_for_write(); - for (MVert &vert : verts) { - mul_m4_v3(mat, vert.co); + for (float3 &position : positions) { + mul_m4_v3(mat, position); } if (do_keys && me->key) { @@ -1609,9 +1589,9 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys) void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys) { - MutableSpan verts = me->verts_for_write(); - for (MVert &vert : verts) { - add_v3_v3(vert.co, offset); + MutableSpan positions = me->vert_positions_for_write(); + for (float3 &position : positions) { + position += offset; } int i; @@ -1785,9 +1765,9 @@ float (*BKE_mesh_vert_coords_alloc(const Mesh *mesh, int *r_vert_len))[3] void BKE_mesh_vert_coords_apply(Mesh *mesh, const float (*vert_coords)[3]) { - MutableSpan verts = mesh->verts_for_write(); - for (const int i : verts.index_range()) { - copy_v3_v3(verts[i].co, vert_coords[i]); + MutableSpan positions = mesh->vert_positions_for_write(); + for (const int i : positions.index_range()) { + copy_v3_v3(positions[i], vert_coords[i]); } BKE_mesh_tag_coords_changed(mesh); } @@ -1796,9 +1776,9 @@ void BKE_mesh_vert_coords_apply_with_mat4(Mesh *mesh, const float (*vert_coords)[3], const float mat[4][4]) { - MutableSpan verts = mesh->verts_for_write(); - for (const int i : verts.index_range()) { - mul_v3_m4v3(verts[i].co, mat, vert_coords[i]); + MutableSpan positions = mesh->vert_positions_for_write(); + for (const int i : positions.index_range()) { + mul_v3_m4v3(positions[i], mat, vert_coords[i]); } BKE_mesh_tag_coords_changed(mesh); } @@ -1834,14 +1814,14 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, /* may be nullptr */ clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); - const Span verts = mesh->verts(); + const Span positions = mesh->vert_positions(); const Span edges = mesh->edges(); const Span polys = mesh->polys(); const Span loops = mesh->loops(); - BKE_mesh_normals_loop_split(verts.data(), + BKE_mesh_normals_loop_split(reinterpret_cast(positions.data()), BKE_mesh_vertex_normals_ensure(mesh), - verts.size(), + positions.size(), edges.data(), edges.size(), loops.data(), diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index 14a9a852c16..8ae08972cad 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -102,16 +102,16 @@ class MeshesToIMeshInfo { const Mesh **r_orig_mesh, int *r_orig_mesh_index, int *r_index_in_orig_mesh) const; - const MVert *input_mvert_for_orig_index(int orig_index, - const Mesh **r_orig_mesh, - int *r_index_in_orig_mesh) const; + void input_mvert_for_orig_index(int orig_index, + const Mesh **r_orig_mesh, + int *r_index_in_orig_mesh) const; const MEdge *input_medge_for_orig_index(int orig_index, const Mesh **r_orig_mesh, int *r_index_in_orig_mesh) const; }; /* Given an index `imesh_v` in the `IMesh`, return the index of the - * input `Mesh` that contained the `MVert` that it came from. */ + * input `Mesh` that contained the vertex that it came from. */ int MeshesToIMeshInfo::input_mesh_for_imesh_vert(int imesh_v) const { int n = int(mesh_vert_offset.size()); @@ -124,7 +124,7 @@ int MeshesToIMeshInfo::input_mesh_for_imesh_vert(int imesh_v) const } /* Given an index `imesh_e` used as an original index in the `IMesh`, - * return the index of the input `Mesh` that contained the `MVert` that it came from. */ + * return the index of the input `Mesh` that contained the vertex that it came from. */ int MeshesToIMeshInfo::input_mesh_for_imesh_edge(int imesh_e) const { int n = int(mesh_edge_offset.size()); @@ -180,26 +180,23 @@ const MPoly *MeshesToIMeshInfo::input_mpoly_for_orig_index(int orig_index, /* Given an index of an original vertex in the `IMesh`, find out the input * `Mesh` that it came from and return it in `*r_orig_mesh`. - * Also find the index of the `MVert` in that `Mesh` and return it in + * Also find the index of the vertex in that `Mesh` and return it in * `*r_index_in_orig_mesh`. */ -const MVert *MeshesToIMeshInfo::input_mvert_for_orig_index(int orig_index, - const Mesh **r_orig_mesh, - int *r_index_in_orig_mesh) const +void MeshesToIMeshInfo::input_mvert_for_orig_index(int orig_index, + const Mesh **r_orig_mesh, + int *r_index_in_orig_mesh) const { int orig_mesh_index = input_mesh_for_imesh_vert(orig_index); BLI_assert(0 <= orig_mesh_index && orig_mesh_index < meshes.size()); const Mesh *me = meshes[orig_mesh_index]; - const Span verts = me->verts(); int index_in_mesh = orig_index - mesh_vert_offset[orig_mesh_index]; BLI_assert(0 <= index_in_mesh && index_in_mesh < me->totvert); - const MVert *mv = &verts[index_in_mesh]; if (r_orig_mesh) { *r_orig_mesh = me; } if (r_index_in_orig_mesh) { *r_index_in_orig_mesh = index_in_mesh; } - return mv; } /* Similarly for edges. */ @@ -229,7 +226,7 @@ const MEdge *MeshesToIMeshInfo::input_medge_for_orig_index(int orig_index, * first Mesh. To do this transformation, we also need the transformation * obmats corresponding to the Meshes, so they are in the `obmats` argument. * The 'original' indexes in the IMesh are the indexes you get by - * a scheme that offsets each MVert, MEdge, and MPoly index by the sum of the + * a scheme that offsets each vertex, MEdge, and MPoly index by the sum of the * vertices, edges, and polys in the preceding Meshes in the mesh span. * The `*r_info class` is filled in with information needed to make the * correspondence between the Mesh MVerts/MPolys and the IMesh Verts/Faces. @@ -287,7 +284,7 @@ static IMesh meshes_to_imesh(Span meshes, const float4x4 inv_target_mat = clean_transform(target_transform).inverted(); /* For each input `Mesh`, make `Vert`s and `Face`s for the corresponding - * `MVert`s and `MPoly`s, and keep track of the original indices (using the + * vertices and `MPoly`s, and keep track of the original indices (using the * concatenating offset scheme) inside the `Vert`s and `Face`s. * When making `Face`s, we also put in the original indices for `MEdge`s that * make up the `MPoly`s using the same scheme. */ @@ -309,7 +306,7 @@ static IMesh meshes_to_imesh(Span meshes, bool need_face_flip = r_info->has_negative_transform[mi] != r_info->has_negative_transform[0]; Vector verts(me->totvert); - const Span mesh_verts = me->verts(); + const Span vert_positions = me->vert_positions(); const Span polys = me->polys(); const Span loops = me->loops(); @@ -318,10 +315,9 @@ static IMesh meshes_to_imesh(Span meshes, * for example when the first mesh is already in the target space. (Note the logic * directly above, which uses an identity matrix with a null input transform). */ if (obmats[mi] == nullptr) { - threading::parallel_for(mesh_verts.index_range(), 2048, [&](IndexRange range) { - float3 co; + threading::parallel_for(vert_positions.index_range(), 2048, [&](IndexRange range) { for (int i : range) { - co = float3(mesh_verts[i].co); + float3 co = vert_positions[i]; mpq3 mco = mpq3(co.x, co.y, co.z); double3 dco(mco[0].get_d(), mco[1].get_d(), mco[2].get_d()); verts[i] = new Vert(mco, dco, NO_INDEX, i); @@ -329,17 +325,16 @@ static IMesh meshes_to_imesh(Span meshes, }); } else { - threading::parallel_for(mesh_verts.index_range(), 2048, [&](IndexRange range) { - float3 co; + threading::parallel_for(vert_positions.index_range(), 2048, [&](IndexRange range) { for (int i : range) { - co = r_info->to_target_transform[mi] * float3(mesh_verts[i].co); + float3 co = r_info->to_target_transform[mi] * vert_positions[i]; mpq3 mco = mpq3(co.x, co.y, co.z); double3 dco(mco[0].get_d(), mco[1].get_d(), mco[2].get_d()); verts[i] = new Vert(mco, dco, NO_INDEX, i); } }); } - for (int i : mesh_verts.index_range()) { + for (int i : vert_positions.index_range()) { r_info->mesh_to_imesh_vert[v] = arena.add_or_find_vert(verts[i]); ++v; } @@ -384,9 +379,7 @@ static void copy_vert_attributes(Mesh *dest_mesh, const CustomData *source_cd = &orig_me->vdata; for (int source_layer_i = 0; source_layer_i < source_cd->totlayer; ++source_layer_i) { int ty = source_cd->layers[source_layer_i].type; - /* The (first) CD_MVERT layer is the same as dest_mesh->vdata, so we've - * already set the coordinate to the right value. */ - if (ty == CD_MVERT) { + if (StringRef(source_cd->layers->name) == "position") { continue; } const char *name = source_cd->layers[source_layer_i].name; @@ -559,16 +552,19 @@ static void get_poly2d_cos(const Mesh *me, const float4x4 &trans_mat, float r_axis_mat[3][3]) { - const Span verts = me->verts(); + const Span positions = me->vert_positions(); const Span loops = me->loops(); const Span poly_loops = loops.slice(mp->loopstart, mp->totloop); /* Project coordinates to 2d in cos_2d, using normal as projection axis. */ float axis_dominant[3]; - BKE_mesh_calc_poly_normal(mp, &loops[mp->loopstart], verts.data(), axis_dominant); + BKE_mesh_calc_poly_normal(mp, + &loops[mp->loopstart], + reinterpret_cast(positions.data()), + axis_dominant); axis_dominant_v3_to_m3(r_axis_mat, axis_dominant); for (const int i : poly_loops.index_range()) { - float3 co = verts[poly_loops[i].v].co; + float3 co = positions[poly_loops[i].v]; co = trans_mat * co; mul_v2_m3v3(cos_2d[i], r_axis_mat, co); } @@ -605,7 +601,7 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh, get_poly2d_cos(orig_me, orig_mp, cos_2d, mim.to_target_transform[orig_me_index], axis_mat); } CustomData *target_cd = &dest_mesh->ldata; - const Span dst_verts = dest_mesh->verts(); + const Span dst_positions = dest_mesh->vert_positions(); const Span dst_loops = dest_mesh->loops(); for (int i = 0; i < mp->totloop; ++i) { int loop_index = mp->loopstart + i; @@ -616,7 +612,7 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh, * The coordinate needs to be projected into 2d, just like the interpolating polygon's * coordinates were. The `dest_mesh` coordinates are already in object 0 local space. */ float co[2]; - mul_v2_m3v3(co, axis_mat, dst_verts[dst_loops[loop_index].v].co); + mul_v2_m3v3(co, axis_mat, dst_positions[dst_loops[loop_index].v]); interp_weights_poly_v2(weights.data(), cos_2d, orig_mp->totloop, co); } for (int source_layer_i = 0; source_layer_i < source_cd->totlayer; ++source_layer_i) { @@ -719,7 +715,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) merge_vertex_loop_poly_customdata_layers(result, mim); /* Set the vertex coordinate values and other data. */ - MutableSpan verts = result->verts_for_write(); + MutableSpan positions = result->vert_positions_for_write(); for (int vi : im->vert_index_range()) { const Vert *v = im->vert(vi); if (v->orig != NO_INDEX) { @@ -728,8 +724,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim) mim.input_mvert_for_orig_index(v->orig, &orig_me, &index_in_orig_me); copy_vert_attributes(result, orig_me, vi, index_in_orig_me); } - MVert *mv = &verts[vi]; - copy_v3fl_v3db(mv->co, v->co); + copy_v3fl_v3db(positions[vi], v->co); } /* Set the loopstart and totloop for each output poly, diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index bbd70a9d152..b6ccb0ea52d 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -190,7 +190,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba } Mesh *mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly); - MutableSpan verts = mesh->verts_for_write(); + MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); @@ -213,7 +213,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba a = dl->parts * dl->nr; const float *data = dl->verts; while (a--) { - copy_v3_v3(verts[dst_vert].co, data); + copy_v3_v3(positions[dst_vert], data); data += 3; dst_vert++; } @@ -235,7 +235,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba a = dl->parts * dl->nr; const float *data = dl->verts; while (a--) { - copy_v3_v3(verts[dst_vert].co, data); + copy_v3_v3(positions[dst_vert], data); data += 3; dst_vert++; } @@ -261,7 +261,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba a = dl->nr; const float *data = dl->verts; while (a--) { - copy_v3_v3(verts[dst_vert].co, data); + copy_v3_v3(positions[dst_vert], data); data += 3; dst_vert++; } @@ -296,7 +296,7 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba a = dl->parts * dl->nr; const float *data = dl->verts; while (a--) { - copy_v3_v3(verts[dst_vert].co, data); + copy_v3_v3(positions[dst_vert], data); data += 3; dst_vert++; } @@ -456,7 +456,7 @@ static void appendPolyLineVert(ListBase *lb, uint index) void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int edge_users_test) { - const Span verts = me->verts(); + const Span positions = me->vert_positions(); const Span mesh_edges = me->edges(); const Span polys = me->polys(); const Span loops = me->loops(); @@ -588,7 +588,7 @@ void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int ed /* add points */ vl = (VertLink *)polyline.first; for (i = 0, bp = nu->bp; i < totpoly; i++, bp++, vl = (VertLink *)vl->next) { - copy_v3_v3(bp->vec, verts[vl->index].co); + copy_v3_v3(bp->vec, positions[vl->index]); bp->f1 = SELECT; bp->radius = bp->weight = 1.0; } @@ -644,11 +644,11 @@ void BKE_pointcloud_from_mesh(Mesh *me, PointCloud *pointcloud) bke::AttributeAccessor mesh_attributes = me->attributes(); bke::MutableAttributeAccessor point_attributes = pointcloud->attributes_for_write(); - const VArray mesh_positions = mesh_attributes.lookup_or_default( + const VArray vert_positions = mesh_attributes.lookup_or_default( "position", ATTR_DOMAIN_POINT, float3(0)); bke::SpanAttributeWriter point_positions = point_attributes.lookup_or_add_for_write_only_span("position", ATTR_DOMAIN_POINT); - mesh_positions.materialize(point_positions.span); + vert_positions.materialize(point_positions.span); point_positions.finish(); } @@ -679,25 +679,8 @@ void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me) me->totvert = pointcloud->totpoint; - /* Merge over all attributes. */ CustomData_merge( &pointcloud->pdata, &me->vdata, CD_MASK_PROP_ALL, CD_DUPLICATE, pointcloud->totpoint); - - /* Convert the Position attribute to a mesh vertex. */ - CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert); - - const int layer_idx = CustomData_get_named_layer_index( - &me->vdata, CD_PROP_FLOAT3, POINTCLOUD_ATTR_POSITION); - CustomDataLayer *pos_layer = &me->vdata.layers[layer_idx]; - float(*positions)[3] = (float(*)[3])pos_layer->data; - - MutableSpan verts = me->verts_for_write(); - for (int i = 0; i < me->totvert; i++) { - copy_v3_v3(verts[i].co, positions[i]); - } - - /* Delete Position attribute since it is now in vertex coordinates. */ - CustomData_free_layer(&me->vdata, CD_PROP_FLOAT3, me->totvert, layer_idx); } void BKE_mesh_edges_set_draw_render(Mesh *mesh) @@ -1227,8 +1210,7 @@ void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb) { BLI_assert(mesh_src->id.tag & LIB_TAG_NO_MAIN); - int a, totvert = mesh_src->totvert; - float *fp; + const int totvert = mesh_src->totvert; if (totvert == 0 || mesh_dst->totvert == 0 || mesh_dst->totvert != totvert) { return; @@ -1239,10 +1221,5 @@ void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb) } kb->data = MEM_malloc_arrayN(mesh_dst->key->elemsize, mesh_dst->totvert, "kb->data"); kb->totelem = totvert; - - fp = (float *)kb->data; - const Span verts = mesh_src->verts(); - for (a = 0; a < kb->totelem; a++, fp += 3) { - copy_v3_v3(fp, verts[a].co); - } + MutableSpan(static_cast(kb->data), kb->totelem).copy_from(mesh_src->vert_positions()); } diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc index 3df25464e34..c0b461e524e 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.cc +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -30,6 +30,7 @@ #include "BKE_mesh.h" #include "BKE_multires.h" +using blender::float3; using blender::MutableSpan; using blender::Span; using blender::VArray; @@ -40,7 +41,7 @@ using blender::VArray; static void mesh_calc_ngon_center(const MPoly *mpoly, const MLoop *loopstart, - const MVert *mvert, + const float (*positions)[3], float cent[3]) { const float w = 1.0f / float(mpoly->totloop); @@ -48,38 +49,41 @@ static void mesh_calc_ngon_center(const MPoly *mpoly, zero_v3(cent); for (int i = 0; i < mpoly->totloop; i++) { - madd_v3_v3fl(cent, mvert[(loopstart++)->v].co, w); + madd_v3_v3fl(cent, positions[(loopstart++)->v], w); } } void BKE_mesh_calc_poly_center(const MPoly *mpoly, const MLoop *loopstart, - const MVert *mvarray, + const float (*vert_positions)[3], float r_cent[3]) { if (mpoly->totloop == 3) { mid_v3_v3v3v3(r_cent, - mvarray[loopstart[0].v].co, - mvarray[loopstart[1].v].co, - mvarray[loopstart[2].v].co); + vert_positions[loopstart[0].v], + vert_positions[loopstart[1].v], + vert_positions[loopstart[2].v]); } else if (mpoly->totloop == 4) { mid_v3_v3v3v3v3(r_cent, - mvarray[loopstart[0].v].co, - mvarray[loopstart[1].v].co, - mvarray[loopstart[2].v].co, - mvarray[loopstart[3].v].co); + vert_positions[loopstart[0].v], + vert_positions[loopstart[1].v], + vert_positions[loopstart[2].v], + vert_positions[loopstart[3].v]); } else { - mesh_calc_ngon_center(mpoly, loopstart, mvarray, r_cent); + mesh_calc_ngon_center(mpoly, loopstart, vert_positions, r_cent); } } -float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const MVert *mvarray) +float BKE_mesh_calc_poly_area(const MPoly *mpoly, + const MLoop *loopstart, + const float (*vert_positions)[3]) { if (mpoly->totloop == 3) { - return area_tri_v3( - mvarray[loopstart[0].v].co, mvarray[loopstart[1].v].co, mvarray[loopstart[2].v].co); + return area_tri_v3(vert_positions[loopstart[0].v], + vert_positions[loopstart[1].v], + vert_positions[loopstart[2].v]); } const MLoop *l_iter = loopstart; @@ -87,7 +91,7 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const /* pack vertex cos into an array for area_poly_v3 */ for (int i = 0; i < mpoly->totloop; i++, l_iter++) { - copy_v3_v3(vertexcos[i], mvarray[l_iter->v].co); + copy_v3_v3(vertexcos[i], vert_positions[l_iter->v]); } /* finally calculate the area */ @@ -98,13 +102,14 @@ float BKE_mesh_calc_poly_area(const MPoly *mpoly, const MLoop *loopstart, const float BKE_mesh_calc_area(const Mesh *me) { - const Span verts = me->verts(); + const Span positions = me->vert_positions(); const Span polys = me->polys(); const Span loops = me->loops(); float total_area = 0.0f; for (const MPoly &poly : polys) { - total_area += BKE_mesh_calc_poly_area(&poly, &loops[poly.loopstart], verts.data()); + total_area += BKE_mesh_calc_poly_area( + &poly, &loops[poly.loopstart], reinterpret_cast(positions.data())); } return total_area; } @@ -129,7 +134,7 @@ float BKE_mesh_calc_poly_uv_area(const MPoly *mpoly, const MLoopUV *uv_array) static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MPoly *mpoly, const MLoop *loopstart, - const MVert *mvarray, + const float (*positions)[3], float r_cent[3]) { const float *v_pivot, *v_step1; @@ -137,11 +142,11 @@ static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MPoly *mpoly, zero_v3(r_cent); - v_pivot = mvarray[loopstart[0].v].co; - v_step1 = mvarray[loopstart[1].v].co; + v_pivot = positions[loopstart[0].v]; + v_step1 = positions[loopstart[1].v]; for (int i = 2; i < mpoly->totloop; i++) { - const float *v_step2 = mvarray[loopstart[i].v].co; + const float *v_step2 = positions[loopstart[i].v]; /* Calculate the 6x volume of the tetrahedron formed by the 3 vertices * of the triangle and the origin as the fourth vertex */ @@ -171,7 +176,7 @@ static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MPoly *mpoly, */ static float mesh_calc_poly_volume_centroid_with_reference_center(const MPoly *mpoly, const MLoop *loopstart, - const MVert *mvarray, + const Span positions, const float reference_center[3], float r_cent[3]) { @@ -179,11 +184,11 @@ static float mesh_calc_poly_volume_centroid_with_reference_center(const MPoly *m float v_pivot[3], v_step1[3]; float total_volume = 0.0f; zero_v3(r_cent); - sub_v3_v3v3(v_pivot, mvarray[loopstart[0].v].co, reference_center); - sub_v3_v3v3(v_step1, mvarray[loopstart[1].v].co, reference_center); + sub_v3_v3v3(v_pivot, positions[loopstart[0].v], reference_center); + sub_v3_v3v3(v_step1, positions[loopstart[1].v], reference_center); for (int i = 2; i < mpoly->totloop; i++) { float v_step2[3]; - sub_v3_v3v3(v_step2, mvarray[loopstart[i].v].co, reference_center); + sub_v3_v3v3(v_step2, positions[loopstart[i].v], reference_center); const float tetra_volume = volume_tri_tetrahedron_signed_v3_6x(v_pivot, v_step1, v_step2); total_volume += tetra_volume; for (uint j = 0; j < 3; j++) { @@ -202,19 +207,19 @@ static float mesh_calc_poly_volume_centroid_with_reference_center(const MPoly *m */ static float mesh_calc_poly_area_centroid(const MPoly *mpoly, const MLoop *loopstart, - const MVert *mvarray, + const float (*positions)[3], float r_cent[3]) { float total_area = 0.0f; float v1[3], v2[3], v3[3], normal[3], tri_cent[3]; - BKE_mesh_calc_poly_normal(mpoly, loopstart, mvarray, normal); - copy_v3_v3(v1, mvarray[loopstart[0].v].co); - copy_v3_v3(v2, mvarray[loopstart[1].v].co); + BKE_mesh_calc_poly_normal(mpoly, loopstart, positions, normal); + copy_v3_v3(v1, positions[loopstart[0].v]); + copy_v3_v3(v2, positions[loopstart[1].v]); zero_v3(r_cent); for (int i = 2; i < mpoly->totloop; i++) { - copy_v3_v3(v3, mvarray[loopstart[i].v].co); + copy_v3_v3(v3, positions[loopstart[i].v]); float tri_area = area_tri_signed_v3(v1, v2, v3, normal); total_area += tri_area; @@ -232,7 +237,7 @@ static float mesh_calc_poly_area_centroid(const MPoly *mpoly, void BKE_mesh_calc_poly_angles(const MPoly *mpoly, const MLoop *loopstart, - const MVert *mvarray, + const float (*vert_positions)[3], float angles[]) { float nor_prev[3]; @@ -241,11 +246,13 @@ void BKE_mesh_calc_poly_angles(const MPoly *mpoly, int i_this = mpoly->totloop - 1; int i_next = 0; - sub_v3_v3v3(nor_prev, mvarray[loopstart[i_this - 1].v].co, mvarray[loopstart[i_this].v].co); + sub_v3_v3v3( + nor_prev, vert_positions[loopstart[i_this - 1].v], vert_positions[loopstart[i_this].v]); normalize_v3(nor_prev); while (i_next < mpoly->totloop) { - sub_v3_v3v3(nor_next, mvarray[loopstart[i_this].v].co, mvarray[loopstart[i_next].v].co); + sub_v3_v3v3( + nor_next, vert_positions[loopstart[i_this].v], vert_positions[loopstart[i_next].v]); normalize_v3(nor_next); angles[i_this] = angle_normalized_v3v3(nor_prev, nor_next); @@ -293,10 +300,10 @@ void BKE_mesh_poly_edgebitmap_insert(uint *edge_bitmap, const MPoly *mp, const M bool BKE_mesh_center_median(const Mesh *me, float r_cent[3]) { - const Span verts = me->verts(); + const Span positions = me->vert_positions(); zero_v3(r_cent); - for (const MVert &vert : verts) { - add_v3_v3(r_cent, vert.co); + for (const int i : positions.index_range()) { + add_v3_v3(r_cent, positions[i]); } /* otherwise we get NAN for 0 verts */ if (me->totvert) { @@ -308,14 +315,14 @@ bool BKE_mesh_center_median(const Mesh *me, float r_cent[3]) bool BKE_mesh_center_median_from_polys(const Mesh *me, float r_cent[3]) { int tot = 0; - const Span verts = me->verts(); + const Span positions = me->vert_positions(); const Span polys = me->polys(); const Span loops = me->loops(); zero_v3(r_cent); for (const MPoly &poly : polys) { int loopend = poly.loopstart + poly.totloop; for (int j = poly.loopstart; j < loopend; j++) { - add_v3_v3(r_cent, verts[loops[j].v].co); + add_v3_v3(r_cent, positions[loops[j].v]); } tot += poly.totloop; } @@ -345,7 +352,7 @@ bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3]) float poly_area; float total_area = 0.0f; float poly_cent[3]; - const MVert *verts = BKE_mesh_verts(me); + const float(*positions)[3] = BKE_mesh_vert_positions(me); const MPoly *polys = BKE_mesh_polys(me); const MLoop *loops = BKE_mesh_loops(me); @@ -353,7 +360,8 @@ bool BKE_mesh_center_of_surface(const Mesh *me, float r_cent[3]) /* calculate a weighted average of polygon centroids */ for (mpoly = polys; i--; mpoly++) { - poly_area = mesh_calc_poly_area_centroid(mpoly, loops + mpoly->loopstart, verts, poly_cent); + poly_area = mesh_calc_poly_area_centroid( + mpoly, loops + mpoly->loopstart, positions, poly_cent); madd_v3_v3fl(r_cent, poly_cent, poly_area); total_area += poly_area; @@ -378,7 +386,7 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3]) float poly_volume; float total_volume = 0.0f; float poly_cent[3]; - const MVert *verts = BKE_mesh_verts(me); + const Span positions = me->vert_positions(); const MPoly *polys = BKE_mesh_polys(me); const MLoop *loops = BKE_mesh_loops(me); @@ -391,7 +399,7 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3]) /* calculate a weighted average of polyhedron centroids */ for (mpoly = polys; i--; mpoly++) { poly_volume = mesh_calc_poly_volume_centroid_with_reference_center( - mpoly, loops + mpoly->loopstart, verts, init_cent, poly_cent); + mpoly, loops + mpoly->loopstart, positions, init_cent, poly_cent); /* poly_cent is already volume-weighted, so no need to multiply by the volume */ add_v3_v3(r_cent, poly_cent); @@ -420,7 +428,7 @@ bool BKE_mesh_center_of_volume(const Mesh *me, float r_cent[3]) /** \name Mesh Volume Calculation * \{ */ -static bool mesh_calc_center_centroid_ex(const MVert *mverts, +static bool mesh_calc_center_centroid_ex(const float (*positions)[3], int /*mverts_num*/, const MLoopTri *looptri, int looptri_num, @@ -438,15 +446,15 @@ static bool mesh_calc_center_centroid_ex(const MVert *mverts, const MLoopTri *lt; int i; for (i = 0, lt = looptri; i < looptri_num; i++, lt++) { - const MVert *v1 = &mverts[mloop[lt->tri[0]].v]; - const MVert *v2 = &mverts[mloop[lt->tri[1]].v]; - const MVert *v3 = &mverts[mloop[lt->tri[2]].v]; + const float *v1 = positions[mloop[lt->tri[0]].v]; + const float *v2 = positions[mloop[lt->tri[1]].v]; + const float *v3 = positions[mloop[lt->tri[2]].v]; float area; - area = area_tri_v3(v1->co, v2->co, v3->co); - madd_v3_v3fl(r_center, v1->co, area); - madd_v3_v3fl(r_center, v2->co, area); - madd_v3_v3fl(r_center, v3->co, area); + area = area_tri_v3(v1, v2, v3); + madd_v3_v3fl(r_center, v1, area); + madd_v3_v3fl(r_center, v2, area); + madd_v3_v3fl(r_center, v3, area); totweight += area; } if (totweight == 0.0f) { @@ -458,7 +466,7 @@ static bool mesh_calc_center_centroid_ex(const MVert *mverts, return true; } -void BKE_mesh_calc_volume(const MVert *mverts, +void BKE_mesh_calc_volume(const float (*vert_positions)[3], const int mverts_num, const MLoopTri *looptri, const int looptri_num, @@ -482,27 +490,28 @@ void BKE_mesh_calc_volume(const MVert *mverts, return; } - if (!mesh_calc_center_centroid_ex(mverts, mverts_num, looptri, looptri_num, mloop, center)) { + if (!mesh_calc_center_centroid_ex( + vert_positions, mverts_num, looptri, looptri_num, mloop, center)) { return; } totvol = 0.0f; for (i = 0, lt = looptri; i < looptri_num; i++, lt++) { - const MVert *v1 = &mverts[mloop[lt->tri[0]].v]; - const MVert *v2 = &mverts[mloop[lt->tri[1]].v]; - const MVert *v3 = &mverts[mloop[lt->tri[2]].v]; + const float *v1 = vert_positions[mloop[lt->tri[0]].v]; + const float *v2 = vert_positions[mloop[lt->tri[1]].v]; + const float *v3 = vert_positions[mloop[lt->tri[2]].v]; float vol; - vol = volume_tetrahedron_signed_v3(center, v1->co, v2->co, v3->co); + vol = volume_tetrahedron_signed_v3(center, v1, v2, v3); if (r_volume) { totvol += vol; } if (r_center) { /* averaging factor 1/3 is applied in the end */ - madd_v3_v3fl(r_center, v1->co, vol); - madd_v3_v3fl(r_center, v2->co, vol); - madd_v3_v3fl(r_center, v3->co, vol); + madd_v3_v3fl(r_center, v1, vol); + madd_v3_v3fl(r_center, v2, vol); + madd_v3_v3fl(r_center, v3, vol); } } diff --git a/source/blender/blenkernel/intern/mesh_fair.cc b/source/blender/blenkernel/intern/mesh_fair.cc index 960e6c43103..ddf6b342236 100644 --- a/source/blender/blenkernel/intern/mesh_fair.cc +++ b/source/blender/blenkernel/intern/mesh_fair.cc @@ -27,6 +27,7 @@ #include "eigen_capi.h" using blender::Array; +using blender::float3; using blender::Map; using blender::MutableSpan; using blender::Span; @@ -191,12 +192,12 @@ class FairingContext { class MeshFairingContext : public FairingContext { public: - MeshFairingContext(Mesh *mesh, MVert *deform_mverts) + MeshFairingContext(Mesh *mesh, MutableSpan deform_positions) { totvert_ = mesh->totvert; totloop_ = mesh->totloop; - MutableSpan verts = mesh->verts_for_write(); + MutableSpan positions = mesh->vert_positions_for_write(); medge_ = mesh->edges(); mpoly_ = mesh->polys(); mloop_ = mesh->loops(); @@ -210,14 +211,14 @@ class MeshFairingContext : public FairingContext { /* Deformation coords. */ co_.reserve(mesh->totvert); - if (deform_mverts) { + if (!deform_positions.is_empty()) { for (int i = 0; i < mesh->totvert; i++) { - co_[i] = deform_mverts[i].co; + co_[i] = deform_positions[i]; } } else { for (int i = 0; i < mesh->totvert; i++) { - co_[i] = verts[i].co; + co_[i] = positions[i]; } } @@ -466,11 +467,15 @@ static void prefair_and_fair_verts(FairingContext *fairing_context, } void BKE_mesh_prefair_and_fair_verts(struct Mesh *mesh, - struct MVert *deform_mverts, + float (*deform_vert_positions)[3], bool *affect_verts, const eMeshFairingDepth depth) { - MeshFairingContext *fairing_context = new MeshFairingContext(mesh, deform_mverts); + MutableSpan deform_positions_span; + if (deform_vert_positions) { + deform_positions_span = {reinterpret_cast(deform_vert_positions), mesh->totvert}; + } + MeshFairingContext *fairing_context = new MeshFairingContext(mesh, deform_positions_span); prefair_and_fair_verts(fairing_context, affect_verts, depth); delete fairing_context; } diff --git a/source/blender/blenkernel/intern/mesh_iterators.cc b/source/blender/blenkernel/intern/mesh_iterators.cc index bc765c0ddd0..b1aa4dcec53 100644 --- a/source/blender/blenkernel/intern/mesh_iterators.cc +++ b/source/blender/blenkernel/intern/mesh_iterators.cc @@ -65,26 +65,26 @@ void BKE_mesh_foreach_mapped_vert( } } else { - const MVert *mv = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const int *index = static_cast(CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX)); const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ? BKE_mesh_vertex_normals_ensure(mesh) : nullptr; if (index) { - for (int i = 0; i < mesh->totvert; i++, mv++) { + for (int i = 0; i < mesh->totvert; i++) { const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[i] : nullptr; const int orig = *index++; if (orig == ORIGINDEX_NONE) { continue; } - func(userData, orig, mv->co, no); + func(userData, orig, positions[i], no); } } else { - for (int i = 0; i < mesh->totvert; i++, mv++) { + for (int i = 0; i < mesh->totvert; i++) { const float *no = (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[i] : nullptr; - func(userData, i, mv->co, no); + func(userData, i, positions[i], no); } } } @@ -120,7 +120,7 @@ void BKE_mesh_foreach_mapped_edge( } } else { - const MVert *mv = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const MEdge *med = BKE_mesh_edges(mesh); const int *index = static_cast(CustomData_get_layer(&mesh->edata, CD_ORIGINDEX)); @@ -130,12 +130,12 @@ void BKE_mesh_foreach_mapped_edge( if (orig == ORIGINDEX_NONE) { continue; } - func(userData, orig, mv[med->v1].co, mv[med->v2].co); + func(userData, orig, positions[med->v1], positions[med->v2]); } } else if (mesh->totedge == tot_edges) { for (int i = 0; i < mesh->totedge; i++, med++) { - func(userData, i, mv[med->v1].co, mv[med->v2].co); + func(userData, i, positions[med->v1], positions[med->v2]); } } } @@ -190,7 +190,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh, CustomData_get_layer(&mesh->ldata, CD_NORMAL)) : nullptr; - const MVert *mv = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const MLoop *ml = BKE_mesh_loops(mesh); const MPoly *mp = BKE_mesh_polys(mesh); const int *v_index = static_cast( @@ -208,7 +208,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh, if (ELEM(ORIGINDEX_NONE, v_idx, f_idx)) { continue; } - func(userData, v_idx, f_idx, mv[ml->v].co, no); + func(userData, v_idx, f_idx, positions[ml->v], no); } } } @@ -218,7 +218,7 @@ void BKE_mesh_foreach_mapped_loop(Mesh *mesh, const int v_idx = ml->v; const int f_idx = p_idx; const float *no = loop_normals ? *loop_normals++ : nullptr; - func(userData, v_idx, f_idx, mv[ml->v].co, no); + func(userData, v_idx, f_idx, positions[ml->v], no); } } } @@ -265,7 +265,7 @@ void BKE_mesh_foreach_mapped_face_center( } } else { - const MVert *mvert = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const MPoly *mp = BKE_mesh_polys(mesh); const MLoop *loops = BKE_mesh_loops(mesh); const MLoop *ml; @@ -281,9 +281,9 @@ void BKE_mesh_foreach_mapped_face_center( } float cent[3]; ml = &loops[mp->loopstart]; - BKE_mesh_calc_poly_center(mp, ml, mvert, cent); + BKE_mesh_calc_poly_center(mp, ml, positions, cent); if (flag & MESH_FOREACH_USE_NORMAL) { - BKE_mesh_calc_poly_normal(mp, ml, mvert, no); + BKE_mesh_calc_poly_normal(mp, ml, positions, no); } func(userData, orig, cent, no); } @@ -292,9 +292,9 @@ void BKE_mesh_foreach_mapped_face_center( for (int i = 0; i < mesh->totpoly; i++, mp++) { float cent[3]; ml = &loops[mp->loopstart]; - BKE_mesh_calc_poly_center(mp, ml, mvert, cent); + BKE_mesh_calc_poly_center(mp, ml, positions, cent); if (flag & MESH_FOREACH_USE_NORMAL) { - BKE_mesh_calc_poly_normal(mp, ml, mvert, no); + BKE_mesh_calc_poly_normal(mp, ml, positions, no); } func(userData, i, cent, no); } @@ -308,11 +308,10 @@ void BKE_mesh_foreach_mapped_subdiv_face_center( void *userData, MeshForeachFlag flag) { - const MVert *verts = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const MPoly *mp = BKE_mesh_polys(mesh); const MLoop *loops = BKE_mesh_loops(mesh); const MLoop *ml; - const MVert *mv; const float(*vert_normals)[3] = (flag & MESH_FOREACH_USE_NORMAL) ? BKE_mesh_vertex_normals_ensure(mesh) : nullptr; @@ -328,11 +327,10 @@ void BKE_mesh_foreach_mapped_subdiv_face_center( } ml = &loops[mp->loopstart]; for (int j = 0; j < mp->totloop; j++, ml++) { - mv = &verts[ml->v]; if (BLI_BITMAP_TEST(facedot_tags, ml->v)) { func(userData, orig, - mv->co, + positions[ml->v], (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[ml->v] : nullptr); } } @@ -342,11 +340,10 @@ void BKE_mesh_foreach_mapped_subdiv_face_center( for (int i = 0; i < mesh->totpoly; i++, mp++) { ml = &loops[mp->loopstart]; for (int j = 0; j < mp->totloop; j++, ml++) { - mv = &verts[ml->v]; if (BLI_BITMAP_TEST(facedot_tags, ml->v)) { func(userData, i, - mv->co, + positions[ml->v], (flag & MESH_FOREACH_USE_NORMAL) ? vert_normals[ml->v] : nullptr); } } diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 3dce2d8b136..2d7cc73208a 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -17,8 +17,10 @@ #include "BLI_edgehash.h" #include "BLI_math.h" +#include "BLI_math_vector_types.hh" #include "BLI_memarena.h" #include "BLI_polyfill_2d.h" +#include "BLI_resource_scope.hh" #include "BLI_task.hh" #include "BLI_utildefines.h" @@ -29,6 +31,9 @@ #include "BKE_mesh_legacy_convert.h" #include "BKE_multires.h" +using blender::MutableSpan; +using blender::Span; + /* -------------------------------------------------------------------- */ /** \name Legacy Edge Calculation * \{ */ @@ -206,7 +211,8 @@ void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old) using namespace blender; MEdge *medge; int totedge = 0; - const Span verts = me->verts(); + const Span verts(static_cast(CustomData_get_layer(&me->vdata, CD_MVERT)), + me->totvert); const Span polys = me->polys(); MutableSpan loops = me->loops_for_write(); @@ -248,7 +254,8 @@ void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh) return; } - const Span verts = mesh->verts(); + const Span verts(static_cast(CustomData_get_layer(&mesh->vdata, CD_MVERT)), + mesh->totvert); const Span edges = mesh->edges(); for (const MVert &vert : verts) { @@ -940,7 +947,7 @@ static int mesh_tessface_calc(Mesh &mesh, CustomData *fdata, CustomData *ldata, CustomData *pdata, - MVert *mvert, + float (*positions)[3], int totface, int totloop, int totpoly) @@ -1070,9 +1077,9 @@ static int mesh_tessface_calc(Mesh &mesh, /* Calculate the normal, flipped: to get a positive 2D cross product. */ ml = mloop + mp_loopstart; - co_prev = mvert[ml[mp_totloop - 1].v].co; + co_prev = positions[ml[mp_totloop - 1].v]; for (j = 0; j < mp_totloop; j++, ml++) { - co_curr = mvert[ml->v].co; + co_curr = positions[ml->v]; add_newell_cross_v3_v3v3(normal, co_prev, co_curr); co_prev = co_curr; } @@ -1085,7 +1092,7 @@ static int mesh_tessface_calc(Mesh &mesh, ml = mloop + mp_loopstart; for (j = 0; j < mp_totloop; j++, ml++) { - mul_v2_m3v3(projverts[j], axis_mat, mvert[ml->v].co); + mul_v2_m3v3(projverts[j], axis_mat, positions[ml->v]); } BLI_polyfill_calc_arena(projverts, mp_totloop, 1, tris, arena); @@ -1188,7 +1195,7 @@ void BKE_mesh_tessface_calc(Mesh *mesh) &mesh->fdata, &mesh->ldata, &mesh->pdata, - BKE_mesh_verts_for_write(mesh), + BKE_mesh_vert_positions_for_write(mesh), mesh->totface, mesh->totloop, mesh->totpoly); @@ -1242,7 +1249,7 @@ void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh) void BKE_mesh_legacy_bevel_weight_from_layers(Mesh *mesh) { using namespace blender; - MutableSpan verts = mesh->verts_for_write(); + MutableSpan verts(mesh->mvert, mesh->totvert); if (const float *weights = static_cast( CustomData_get_layer(&mesh->vdata, CD_BWEIGHT))) { mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT; @@ -1275,7 +1282,7 @@ void BKE_mesh_legacy_bevel_weight_from_layers(Mesh *mesh) void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh) { using namespace blender; - const Span verts = mesh->verts(); + const Span verts(mesh->mvert, mesh->totvert); if (mesh->cd_flag & ME_CDFLAG_VERT_BWEIGHT) { float *weights = static_cast( CustomData_add_layer(&mesh->vdata, CD_BWEIGHT, CD_CONSTRUCT, nullptr, verts.size())); @@ -1344,7 +1351,7 @@ void BKE_mesh_legacy_convert_hide_layers_to_flags(Mesh *mesh) using namespace blender::bke; const AttributeAccessor attributes = mesh->attributes(); - MutableSpan verts = mesh->verts_for_write(); + MutableSpan verts(mesh->mvert, mesh->totvert); const VArray hide_vert = attributes.lookup_or_default( ".hide_vert", ATTR_DOMAIN_POINT, false); threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { @@ -1378,7 +1385,7 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh) using namespace blender::bke; MutableAttributeAccessor attributes = mesh->attributes_for_write(); - const Span verts = mesh->verts(); + const Span verts(mesh->mvert, mesh->totvert); if (std::any_of(verts.begin(), verts.end(), [](const MVert &vert) { return vert.flag_legacy & ME_HIDE; })) { @@ -1471,7 +1478,7 @@ void BKE_mesh_legacy_convert_selection_layers_to_flags(Mesh *mesh) using namespace blender::bke; const AttributeAccessor attributes = mesh->attributes(); - MutableSpan verts = mesh->verts_for_write(); + MutableSpan verts(mesh->mvert, mesh->totvert); const VArray select_vert = attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { @@ -1505,7 +1512,7 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh) using namespace blender::bke; MutableAttributeAccessor attributes = mesh->attributes_for_write(); - const Span verts = mesh->verts(); + const Span verts(mesh->mvert, mesh->totvert); if (std::any_of(verts.begin(), verts.end(), [](const MVert &vert) { return vert.flag_legacy & SELECT; })) { @@ -1513,7 +1520,7 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh) ".select_vert", ATTR_DOMAIN_POINT); threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { - select_vert.span[i] = (verts[i].flag_legacy & SELECT) != 0; + select_vert.span[i] = verts[i].flag_legacy & SELECT; } }); select_vert.finish(); @@ -1526,7 +1533,7 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh) ".select_edge", ATTR_DOMAIN_EDGE); threading::parallel_for(edges.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { - select_edge.span[i] = (edges[i].flag & SELECT) != 0; + select_edge.span[i] = edges[i].flag & SELECT; } }); select_edge.finish(); @@ -1539,7 +1546,7 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh) ".select_poly", ATTR_DOMAIN_FACE); threading::parallel_for(polys.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { - select_poly.span[i] = (polys[i].flag & ME_FACE_SEL) != 0; + select_poly.span[i] = polys[i].flag & ME_FACE_SEL; } }); select_poly.finish(); @@ -1575,6 +1582,57 @@ void BKE_mesh_legacy_convert_loose_edges_to_flag(Mesh *mesh) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Vertex and Position Conversion + * \{ */ + +MVert *BKE_mesh_legacy_convert_positions_to_verts( + Mesh *mesh, + blender::ResourceScope &temp_arrays_for_convert, + blender::Vector &vert_layers_to_write) +{ + using namespace blender; + + const Span positions = mesh->vert_positions(); + + CustomDataLayer mvert_layer{}; + mvert_layer.type = CD_MVERT; + MutableSpan verts = temp_arrays_for_convert.construct>(mesh->totvert); + mvert_layer.data = verts.data(); + + threading::parallel_for(verts.index_range(), 2048, [&](IndexRange range) { + for (const int i : range) { + copy_v3_v3(verts[i].co_legacy, positions[i]); + } + }); + + vert_layers_to_write.append(mvert_layer); + return verts.data(); +} + +void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh) +{ + using namespace blender; + using namespace blender::bke; + + const Span verts(static_cast(CustomData_get_layer(&mesh->vdata, CD_MVERT)), + mesh->totvert); + MutableSpan positions( + static_cast(CustomData_add_layer_named( + &mesh->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, mesh->totvert, "position")), + mesh->totvert); + threading::parallel_for(verts.index_range(), 2048, [&](IndexRange range) { + for (const int i : range) { + positions[i] = verts[i].co_legacy; + } + }); + + CustomData_free_layers(&mesh->vdata, CD_MVERT, mesh->totvert); + mesh->mvert = nullptr; +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Attribute Active Flag to String Conversion * \{ */ diff --git a/source/blender/blenkernel/intern/mesh_mapping.cc b/source/blender/blenkernel/intern/mesh_mapping.cc index cdd7fd4895d..0503e51da06 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.cc +++ b/source/blender/blenkernel/intern/mesh_mapping.cc @@ -262,7 +262,6 @@ void BKE_mesh_vert_loop_map_create(MeshElemMap **r_map, void BKE_mesh_vert_looptri_map_create(MeshElemMap **r_map, int **r_mem, - const MVert * /*mvert*/, const int totvert, const MLoopTri *mlooptri, const int totlooptri, @@ -1053,9 +1052,7 @@ static bool mesh_check_island_boundary_uv(const MPoly * /*mp*/, return (me->flag & ME_SEAM) != 0; } -static bool mesh_calc_islands_loop_poly_uv(const MVert * /*verts*/, - const int /*totvert*/, - const MEdge *edges, +static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges, const int totedge, const MPoly *polys, const int totpoly, @@ -1203,7 +1200,7 @@ static bool mesh_calc_islands_loop_poly_uv(const MVert * /*verts*/, return true; } -bool BKE_mesh_calc_islands_loop_poly_edgeseam(const MVert *verts, +bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3], const int totvert, const MEdge *edges, const int totedge, @@ -1213,11 +1210,12 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const MVert *verts, const int totloop, MeshIslandStore *r_island_store) { + UNUSED_VARS(vert_positions, totvert); return mesh_calc_islands_loop_poly_uv( - verts, totvert, edges, totedge, polys, totpoly, loops, totloop, nullptr, r_island_store); + edges, totedge, polys, totpoly, loops, totloop, nullptr, r_island_store); } -bool BKE_mesh_calc_islands_loop_poly_uvmap(MVert *verts, +bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3], const int totvert, MEdge *edges, const int totedge, @@ -1228,9 +1226,10 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(MVert *verts, const MLoopUV *luvs, MeshIslandStore *r_island_store) { + UNUSED_VARS(vert_positions, totvert); BLI_assert(luvs != nullptr); return mesh_calc_islands_loop_poly_uv( - verts, totvert, edges, totedge, polys, totpoly, loops, totloop, luvs, r_island_store); + edges, totedge, polys, totpoly, loops, totloop, luvs, r_island_store); } /** \} */ diff --git a/source/blender/blenkernel/intern/mesh_merge.c b/source/blender/blenkernel/intern/mesh_merge.c index 9c0e3c1bf59..fbc4ac3d208 100644 --- a/source/blender/blenkernel/intern/mesh_merge.c +++ b/source/blender/blenkernel/intern/mesh_merge.c @@ -14,6 +14,7 @@ #include "BLI_bitmap.h" #include "BLI_edgehash.h" #include "BLI_ghash.h" +#include "BLI_math_vector.h" #include "BLI_utildefines.h" #include "BLI_utildefines_stack.h" @@ -203,18 +204,14 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, const int totedge = mesh->totedge; const int totloop = mesh->totloop; const int totpoly = mesh->totpoly; - const MVert *src_verts = BKE_mesh_verts(mesh); const MEdge *src_edges = BKE_mesh_edges(mesh); const MPoly *src_polys = BKE_mesh_polys(mesh); const MLoop *src_loops = BKE_mesh_loops(mesh); const int totvert_final = totvert - tot_vtargetmap; - const MVert *mv; - MVert *mvert = MEM_malloc_arrayN(totvert_final, sizeof(*mvert), __func__); int *oldv = MEM_malloc_arrayN(totvert_final, sizeof(*oldv), __func__); int *newv = MEM_malloc_arrayN(totvert, sizeof(*newv), __func__); - STACK_DECLARE(mvert); STACK_DECLARE(oldv); /* NOTE: create (totedge + totloop) elements because partially invalid polys due to merge may @@ -256,18 +253,15 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, STACK_INIT(oldl, totloop); STACK_INIT(oldp, totpoly); - STACK_INIT(mvert, totvert_final); STACK_INIT(medge, totedge); STACK_INIT(mloop, totloop); STACK_INIT(mpoly, totpoly); /* fill newv with destination vertex indices */ - mv = src_verts; c = 0; - for (i = 0; i < totvert; i++, mv++) { + for (i = 0; i < totvert; i++) { if (vtargetmap[i] == -1) { STACK_PUSH(oldv, i); - STACK_PUSH(mvert, *mv); newv[i] = c++; } else { @@ -347,7 +341,6 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, BLI_bitmap *vert_tag = BLI_BITMAP_NEW(mesh->totvert, __func__); mp = src_polys; - mv = src_verts; for (i = 0; i < totpoly; i++, mp++) { MPoly *mp_new; @@ -571,7 +564,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, /* Create new cddm. */ result = BKE_mesh_new_nomain_from_template( - mesh, STACK_SIZE(mvert), STACK_SIZE(medge), 0, STACK_SIZE(mloop), STACK_SIZE(mpoly)); + mesh, totvert_final, STACK_SIZE(medge), 0, STACK_SIZE(mloop), STACK_SIZE(mpoly)); /* Update edge indices and copy customdata. */ MEdge *new_med = medge; @@ -598,8 +591,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, } /* Copy vertex customdata. */ - mv = mvert; - for (i = 0; i < result->totvert; i++, mv++) { + for (i = 0; i < result->totvert; i++) { CustomData_copy_data(&mesh->vdata, &result->vdata, oldv[i], i, 1); } @@ -610,9 +602,6 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, } /* Copy over data. #CustomData_add_layer can do this, need to look it up. */ - if (STACK_SIZE(mvert)) { - memcpy(BKE_mesh_verts_for_write(result), mvert, sizeof(MVert) * STACK_SIZE(mvert)); - } if (STACK_SIZE(medge)) { memcpy(BKE_mesh_edges_for_write(result), medge, sizeof(MEdge) * STACK_SIZE(medge)); } @@ -623,7 +612,6 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, memcpy(BKE_mesh_polys_for_write(result), mpoly, sizeof(MPoly) * STACK_SIZE(mpoly)); } - MEM_freeN(mvert); MEM_freeN(medge); MEM_freeN(mloop); MEM_freeN(mpoly); diff --git a/source/blender/blenkernel/intern/mesh_mirror.cc b/source/blender/blenkernel/intern/mesh_mirror.cc index 7d875ba799b..65628a4e2c9 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.cc +++ b/source/blender/blenkernel/intern/mesh_mirror.cc @@ -126,7 +126,6 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, (axis == 2 && mmd->flag & MOD_MIR_BISECT_AXIS_Z)); Mesh *result; - MVert *mv, *mv_prev; MEdge *me; MLoop *ml; MPoly *mp; @@ -204,9 +203,11 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, maxPolys); /* Subdivision-surface for eg won't have mesh data in the custom-data arrays. - * Now add #MVert/#MEdge/#MPoly layers. */ - if (!CustomData_has_layer(&mesh->vdata, CD_MVERT)) { - memcpy(BKE_mesh_verts_for_write(result), BKE_mesh_verts(mesh), sizeof(MVert) * mesh->totvert); + * Now add position/#MEdge/#MPoly layers. */ + if (BKE_mesh_vert_positions(mesh) != NULL) { + memcpy(BKE_mesh_vert_positions_for_write(result), + BKE_mesh_vert_positions(mesh), + sizeof(float[3]) * mesh->totvert); } if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) { memcpy(BKE_mesh_edges_for_write(result), BKE_mesh_edges(mesh), sizeof(MEdge) * mesh->totedge); @@ -233,10 +234,11 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, } /* mirror vertex coordinates */ - mv_prev = BKE_mesh_verts_for_write(result); - mv = mv_prev + maxVerts; - for (i = 0; i < maxVerts; i++, mv++, mv_prev++) { - mul_m4_v3(mtx, mv->co); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(result); + for (i = 0; i < maxVerts; i++) { + const int vert_index_prev = i; + const int vert_index = maxVerts + i; + mul_m4_v3(mtx, positions[vert_index]); if (do_vtargetmap) { /* Compare location of the original and mirrored vertex, @@ -253,13 +255,14 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, * old, incorrect behavior of merging the source vertex into its copy. */ if (use_correct_order_on_merge) { - if (UNLIKELY(len_squared_v3v3(mv_prev->co, mv->co) < tolerance_sq)) { + if (UNLIKELY(len_squared_v3v3(positions[vert_index_prev], positions[vert_index]) < + tolerance_sq)) { *vtmap_b = i; tot_vtargetmap++; /* average location */ - mid_v3_v3v3(mv->co, mv_prev->co, mv->co); - copy_v3_v3(mv_prev->co, mv->co); + mid_v3_v3v3(positions[vert_index], positions[vert_index_prev], positions[vert_index]); + copy_v3_v3(positions[vert_index_prev], positions[vert_index]); } else { *vtmap_b = -1; @@ -269,13 +272,14 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, *vtmap_a = -1; } else { - if (UNLIKELY(len_squared_v3v3(mv_prev->co, mv->co) < tolerance_sq)) { + if (UNLIKELY(len_squared_v3v3(positions[vert_index_prev], positions[vert_index]) < + tolerance_sq)) { *vtmap_a = maxVerts + i; tot_vtargetmap++; /* average location */ - mid_v3_v3v3(mv->co, mv_prev->co, mv->co); - copy_v3_v3(mv_prev->co, mv->co); + mid_v3_v3v3(positions[vert_index], positions[vert_index_prev], positions[vert_index]); + copy_v3_v3(positions[vert_index_prev], positions[vert_index]); } else { *vtmap_a = -1; @@ -404,7 +408,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, /* calculate custom normals into loop_normals, then mirror first half into second half */ - BKE_mesh_normals_loop_split(BKE_mesh_verts(result), + BKE_mesh_normals_loop_split(BKE_mesh_vert_positions(result), BKE_mesh_vertex_normals_ensure(result), result->totvert, BKE_mesh_edges(result), diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index b856e996bd0..266ef0efa0b 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -164,67 +164,18 @@ bool BKE_mesh_poly_normals_are_dirty(const Mesh *mesh) */ static void mesh_calc_ngon_normal(const MPoly *mpoly, const MLoop *loopstart, - const MVert *mvert, - float normal[3]) + const float (*positions)[3], + float r_normal[3]) { const int nverts = mpoly->totloop; - const float *v_prev = mvert[loopstart[nverts - 1].v].co; - const float *v_curr; - - zero_v3(normal); - - /* Newell's Method */ - for (int i = 0; i < nverts; i++) { - v_curr = mvert[loopstart[i].v].co; - add_newell_cross_v3_v3v3(normal, v_prev, v_curr); - v_prev = v_curr; - } - - if (UNLIKELY(normalize_v3(normal) == 0.0f)) { - normal[2] = 1.0f; /* other axis set to 0.0 */ - } -} - -void BKE_mesh_calc_poly_normal(const MPoly *mpoly, - const MLoop *loopstart, - const MVert *mvarray, - float r_no[3]) -{ - if (mpoly->totloop > 4) { - mesh_calc_ngon_normal(mpoly, loopstart, mvarray, r_no); - } - else if (mpoly->totloop == 3) { - normal_tri_v3( - r_no, mvarray[loopstart[0].v].co, mvarray[loopstart[1].v].co, mvarray[loopstart[2].v].co); - } - else if (mpoly->totloop == 4) { - normal_quad_v3(r_no, - mvarray[loopstart[0].v].co, - mvarray[loopstart[1].v].co, - mvarray[loopstart[2].v].co, - mvarray[loopstart[3].v].co); - } - else { /* horrible, two sided face! */ - r_no[0] = 0.0; - r_no[1] = 0.0; - r_no[2] = 1.0; - } -} -/* duplicate of function above _but_ takes coords rather than mverts */ -static void mesh_calc_ngon_normal_coords(const MPoly *mpoly, - const MLoop *loopstart, - const float (*vertex_coords)[3], - float r_normal[3]) -{ - const int nverts = mpoly->totloop; - const float *v_prev = vertex_coords[loopstart[nverts - 1].v]; + const float *v_prev = positions[loopstart[nverts - 1].v]; const float *v_curr; zero_v3(r_normal); /* Newell's Method */ for (int i = 0; i < nverts; i++) { - v_curr = vertex_coords[loopstart[i].v]; + v_curr = positions[loopstart[i].v]; add_newell_cross_v3_v3v3(r_normal, v_prev, v_curr); v_prev = v_curr; } @@ -234,26 +185,26 @@ static void mesh_calc_ngon_normal_coords(const MPoly *mpoly, } } -void BKE_mesh_calc_poly_normal_coords(const MPoly *mpoly, - const MLoop *loopstart, - const float (*vertex_coords)[3], - float r_no[3]) +void BKE_mesh_calc_poly_normal(const MPoly *mpoly, + const MLoop *loopstart, + const float (*vert_positions)[3], + float r_no[3]) { if (mpoly->totloop > 4) { - mesh_calc_ngon_normal_coords(mpoly, loopstart, vertex_coords, r_no); + mesh_calc_ngon_normal(mpoly, loopstart, vert_positions, r_no); } else if (mpoly->totloop == 3) { normal_tri_v3(r_no, - vertex_coords[loopstart[0].v], - vertex_coords[loopstart[1].v], - vertex_coords[loopstart[2].v]); + vert_positions[loopstart[0].v], + vert_positions[loopstart[1].v], + vert_positions[loopstart[2].v]); } else if (mpoly->totloop == 4) { normal_quad_v3(r_no, - vertex_coords[loopstart[0].v], - vertex_coords[loopstart[1].v], - vertex_coords[loopstart[2].v], - vertex_coords[loopstart[3].v]); + vert_positions[loopstart[0].v], + vert_positions[loopstart[1].v], + vert_positions[loopstart[2].v], + vert_positions[loopstart[3].v]); } else { /* horrible, two sided face! */ r_no[0] = 0.0; @@ -262,7 +213,7 @@ void BKE_mesh_calc_poly_normal_coords(const MPoly *mpoly, } } -static void calculate_normals_poly(const Span verts, +static void calculate_normals_poly(const Span positions, const Span polys, const Span loops, MutableSpan poly_normals) @@ -271,20 +222,23 @@ static void calculate_normals_poly(const Span verts, threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) { for (const int poly_i : range) { const MPoly &poly = polys[poly_i]; - BKE_mesh_calc_poly_normal(&poly, &loops[poly.loopstart], verts.data(), poly_normals[poly_i]); + BKE_mesh_calc_poly_normal(&poly, + &loops[poly.loopstart], + reinterpret_cast(positions.data()), + poly_normals[poly_i]); } }); } -void BKE_mesh_calc_normals_poly(const MVert *mvert, - const int mvert_len, +void BKE_mesh_calc_normals_poly(const float (*vert_positions)[3], + const int verts_num, const MLoop *mloop, const int mloop_len, const MPoly *mpoly, int mpoly_len, float (*r_poly_normals)[3]) { - calculate_normals_poly({mvert, mvert_len}, + calculate_normals_poly({reinterpret_cast(vert_positions), verts_num}, {mpoly, mpoly_len}, {mloop, mloop_len}, {reinterpret_cast(r_poly_normals), mpoly_len}); @@ -299,7 +253,7 @@ void BKE_mesh_calc_normals_poly(const MVert *mvert, * meshes can slow down high-poly meshes. For details on performance, see D11993. * \{ */ -static void calculate_normals_poly_and_vert(const Span verts, +static void calculate_normals_poly_and_vert(const Span positions, const Span polys, const Span loops, MutableSpan poly_normals, @@ -328,9 +282,9 @@ static void calculate_normals_poly_and_vert(const Span verts, { zero_v3(pnor); /* Newell's Method */ - const float *v_curr = verts[poly_loops[i_end].v].co; + const float *v_curr = positions[poly_loops[i_end].v]; for (int i_next = 0; i_next <= i_end; i_next++) { - const float *v_next = verts[poly_loops[i_next].v].co; + const float *v_next = positions[poly_loops[i_next].v]; add_newell_cross_v3_v3v3(pnor, v_curr, v_next); v_curr = v_next; } @@ -343,13 +297,13 @@ static void calculate_normals_poly_and_vert(const Span verts, /* Inline version of #accumulate_vertex_normals_poly_v3. */ { float edvec_prev[3], edvec_next[3], edvec_end[3]; - const float *v_curr = verts[poly_loops[i_end].v].co; - sub_v3_v3v3(edvec_prev, verts[poly_loops[i_end - 1].v].co, v_curr); + const float *v_curr = positions[poly_loops[i_end].v]; + sub_v3_v3v3(edvec_prev, positions[poly_loops[i_end - 1].v], v_curr); normalize_v3(edvec_prev); copy_v3_v3(edvec_end, edvec_prev); for (int i_next = 0, i_curr = i_end; i_next <= i_end; i_curr = i_next++) { - const float *v_next = verts[poly_loops[i_next].v].co; + const float *v_next = positions[poly_loops[i_next].v]; /* Skip an extra normalization by reusing the first calculated edge. */ if (i_next != i_end) { @@ -376,20 +330,20 @@ static void calculate_normals_poly_and_vert(const Span verts, /* Normalize and validate computed vertex normals. */ { - threading::parallel_for(verts.index_range(), 1024, [&](const IndexRange range) { + threading::parallel_for(positions.index_range(), 1024, [&](const IndexRange range) { for (const int vert_i : range) { float *no = vert_normals[vert_i]; if (UNLIKELY(normalize_v3(no) == 0.0f)) { /* Following Mesh convention; we use vertex coordinate itself for normal in this case. */ - normalize_v3_v3(no, verts[vert_i].co); + normalize_v3_v3(no, positions[vert_i]); } } }); } } -void BKE_mesh_calc_normals_poly_and_vertex(const MVert *mvert, +void BKE_mesh_calc_normals_poly_and_vertex(const float (*vert_positions)[3], const int mvert_len, const MLoop *mloop, const int mloop_len, @@ -398,7 +352,7 @@ void BKE_mesh_calc_normals_poly_and_vertex(const MVert *mvert, float (*r_poly_normals)[3], float (*r_vert_normals)[3]) { - calculate_normals_poly_and_vert({mvert, mvert_len}, + calculate_normals_poly_and_vert({reinterpret_cast(vert_positions), mvert_len}, {mpoly, mpoly_len}, {mloop, mloop_len}, {reinterpret_cast(r_poly_normals), mpoly_len}, @@ -434,15 +388,15 @@ const float (*BKE_mesh_vertex_normals_ensure(const Mesh *mesh))[3] /* Isolate task because a mutex is locked and computing normals is multi-threaded. */ blender::threading::isolate_task([&]() { Mesh &mesh_mutable = *const_cast(mesh); - const Span verts = mesh_mutable.verts(); + const Span positions = mesh_mutable.vert_positions(); const Span polys = mesh_mutable.polys(); const Span loops = mesh_mutable.loops(); vert_normals = BKE_mesh_vertex_normals_for_write(&mesh_mutable); poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable); - BKE_mesh_calc_normals_poly_and_vertex(verts.data(), - verts.size(), + BKE_mesh_calc_normals_poly_and_vertex(reinterpret_cast(positions.data()), + positions.size(), loops.data(), loops.size(), polys.data(), @@ -479,14 +433,14 @@ const float (*BKE_mesh_poly_normals_ensure(const Mesh *mesh))[3] /* Isolate task because a mutex is locked and computing normals is multi-threaded. */ blender::threading::isolate_task([&]() { Mesh &mesh_mutable = *const_cast(mesh); - const Span verts = mesh_mutable.verts(); + const Span positions = mesh_mutable.vert_positions(); const Span polys = mesh_mutable.polys(); const Span loops = mesh_mutable.loops(); poly_normals = BKE_mesh_poly_normals_for_write(&mesh_mutable); - BKE_mesh_calc_normals_poly(verts.data(), - verts.size(), + BKE_mesh_calc_normals_poly(reinterpret_cast(positions.data()), + positions.size(), loops.data(), loops.size(), polys.data(), @@ -818,7 +772,7 @@ struct LoopSplitTaskDataCommon { MutableSpan clnors_data; /* Read-only. */ - Span verts; + Span positions; Span edges; Span loops; Span polys; @@ -993,7 +947,7 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS MLoopNorSpaceArray *lnors_spacearr = common_data->lnors_spacearr; const Span clnors_data = common_data->clnors_data; - const Span verts = common_data->verts; + const Span positions = common_data->positions; const Span edges = common_data->edges; const Span loops = common_data->loops; const Span poly_normals = common_data->poly_normals; @@ -1022,17 +976,14 @@ static void split_loop_nor_single_do(LoopSplitTaskDataCommon *common_data, LoopS float vec_curr[3], vec_prev[3]; const uint mv_pivot_index = loops[ml_curr_index].v; /* The vertex we are "fanning" around! */ - const MVert *mv_pivot = &verts[mv_pivot_index]; const MEdge *me_curr = &edges[loops[ml_curr_index].e]; - const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &verts[me_curr->v2] : - &verts[me_curr->v1]; + const int vert_2 = me_curr->v1 == mv_pivot_index ? me_curr->v2 : me_curr->v1; const MEdge *me_prev = &edges[loops[ml_prev_index].e]; - const MVert *mv_3 = (me_prev->v1 == mv_pivot_index) ? &verts[me_prev->v2] : - &verts[me_prev->v1]; + const int vert_3 = me_prev->v1 == mv_pivot_index ? me_prev->v2 : me_prev->v1; - sub_v3_v3v3(vec_curr, mv_2->co, mv_pivot->co); + sub_v3_v3v3(vec_curr, positions[vert_2], positions[mv_pivot_index]); normalize_v3(vec_curr); - sub_v3_v3v3(vec_prev, mv_3->co, mv_pivot->co); + sub_v3_v3v3(vec_prev, positions[vert_3], positions[mv_pivot_index]); normalize_v3(vec_prev); BKE_lnor_space_define(lnor_space, loop_normals[ml_curr_index], vec_curr, vec_prev, nullptr); @@ -1054,7 +1005,7 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, MutableSpan loop_normals = common_data->loop_normals; MutableSpan clnors_data = common_data->clnors_data; - const Span verts = common_data->verts; + const Span positions = common_data->positions; const Span edges = common_data->edges; const Span polys = common_data->polys; const Span loops = common_data->loops; @@ -1077,7 +1028,6 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, * number of sharp edges per vertex, I doubt the additional memory usage would be worth it, * especially as it should not be a common case in real-life meshes anyway). */ const uint mv_pivot_index = loops[ml_curr_index].v; /* The vertex we are "fanning" around! */ - const MVert *mv_pivot = &verts[mv_pivot_index]; /* `ml_curr_index` would be mlfan_prev if we needed that one. */ const MEdge *me_org = &edges[loops[ml_curr_index].e]; @@ -1108,9 +1058,10 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, /* Only need to compute previous edge's vector once, then we can just reuse old current one! */ { - const MVert *mv_2 = (me_org->v1 == mv_pivot_index) ? &verts[me_org->v2] : &verts[me_org->v1]; + const float3 &mv_2 = (me_org->v1 == mv_pivot_index) ? positions[me_org->v2] : + positions[me_org->v1]; - sub_v3_v3v3(vec_org, mv_2->co, mv_pivot->co); + sub_v3_v3v3(vec_org, mv_2, positions[mv_pivot_index]); normalize_v3(vec_org); copy_v3_v3(vec_prev, vec_org); @@ -1129,10 +1080,10 @@ static void split_loop_nor_fan_do(LoopSplitTaskDataCommon *common_data, * given the fact that this code should not be called that much in real-life meshes. */ { - const MVert *mv_2 = (me_curr->v1 == mv_pivot_index) ? &verts[me_curr->v2] : - &verts[me_curr->v1]; + const float3 &mv_2 = (me_curr->v1 == mv_pivot_index) ? positions[me_curr->v2] : + positions[me_curr->v1]; - sub_v3_v3v3(vec_curr, mv_2->co, mv_pivot->co); + sub_v3_v3v3(vec_curr, mv_2, positions[mv_pivot_index]); normalize_v3(vec_curr); } @@ -1491,7 +1442,7 @@ static void loop_split_generator(TaskPool *pool, LoopSplitTaskDataCommon *common } } -void BKE_mesh_normals_loop_split(const MVert *mverts, +void BKE_mesh_normals_loop_split(const float (*vert_positions)[3], const float (*vert_normals)[3], const int numVerts, const MEdge *medges, @@ -1593,7 +1544,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, common_data.lnors_spacearr = r_lnors_spacearr; common_data.loop_normals = {reinterpret_cast(r_loop_normals), numLoops}; common_data.clnors_data = {reinterpret_cast(clnors_data), clnors_data ? numLoops : 0}; - common_data.verts = {mverts, numVerts}; + common_data.positions = {reinterpret_cast(vert_positions), numVerts}; common_data.edges = {medges, numEdges}; common_data.polys = polys; common_data.loops = loops; @@ -1658,7 +1609,7 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, * r_custom_loop_normals is expected to have normalized normals, or zero ones, * in which case they will be replaced by default loop/vertex normal. */ -static void mesh_normals_loop_custom_set(const MVert *mverts, +static void mesh_normals_loop_custom_set(const float (*positions)[3], const float (*vert_normals)[3], const int numVerts, MEdge *medges, @@ -1694,7 +1645,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, BLI_SMALLSTACK_DECLARE(clnors_data, short *); /* Compute current lnor spacearr. */ - BKE_mesh_normals_loop_split(mverts, + BKE_mesh_normals_loop_split(positions, vert_normals, numVerts, medges, @@ -1821,7 +1772,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, /* And now, recompute our new auto `loop_normals` and lnor spacearr! */ BKE_lnor_spacearr_clear(&lnors_spacearr); - BKE_mesh_normals_loop_split(mverts, + BKE_mesh_normals_loop_split(positions, vert_normals, numVerts, medges, @@ -1898,7 +1849,7 @@ static void mesh_normals_loop_custom_set(const MVert *mverts, BKE_lnor_spacearr_free(&lnors_spacearr); } -void BKE_mesh_normals_loop_custom_set(const MVert *mverts, +void BKE_mesh_normals_loop_custom_set(const float (*vert_positions)[3], const float (*vert_normals)[3], const int numVerts, MEdge *medges, @@ -1911,7 +1862,7 @@ void BKE_mesh_normals_loop_custom_set(const MVert *mverts, const int numPolys, short (*r_clnors_data)[2]) { - mesh_normals_loop_custom_set(mverts, + mesh_normals_loop_custom_set(vert_positions, vert_normals, numVerts, medges, @@ -1926,7 +1877,7 @@ void BKE_mesh_normals_loop_custom_set(const MVert *mverts, false); } -void BKE_mesh_normals_loop_custom_from_verts_set(const MVert *mverts, +void BKE_mesh_normals_loop_custom_from_verts_set(const float (*vert_positions)[3], const float (*vert_normals)[3], float (*r_custom_vert_normals)[3], const int numVerts, @@ -1939,7 +1890,7 @@ void BKE_mesh_normals_loop_custom_from_verts_set(const MVert *mverts, const int numPolys, short (*r_clnors_data)[2]) { - mesh_normals_loop_custom_set(mverts, + mesh_normals_loop_custom_set(vert_positions, vert_normals, numVerts, medges, @@ -1967,14 +1918,14 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const clnors = (short(*)[2])CustomData_add_layer( &mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, nullptr, numloops); } - const Span verts = mesh->verts(); + const Span positions = mesh->vert_positions(); MutableSpan edges = mesh->edges_for_write(); const Span polys = mesh->polys(); const Span loops = mesh->loops(); - mesh_normals_loop_custom_set(verts.data(), + mesh_normals_loop_custom_set(reinterpret_cast(positions.data()), BKE_mesh_vertex_normals_ensure(mesh), - verts.size(), + positions.size(), edges.data(), edges.size(), loops.data(), diff --git a/source/blender/blenkernel/intern/mesh_remap.cc b/source/blender/blenkernel/intern/mesh_remap.cc index f66570bdcc7..08f7716e097 100644 --- a/source/blender/blenkernel/intern/mesh_remap.cc +++ b/source/blender/blenkernel/intern/mesh_remap.cc @@ -110,7 +110,7 @@ static bool mesh_remap_bvhtree_query_raycast(BVHTreeFromMesh *treedata, * \{ */ float BKE_mesh_remap_calc_difference_from_mesh(const SpaceTransform *space_transform, - const MVert *verts_dst, + const float (*vert_positions_dst)[3], const int numverts_dst, Mesh *me_src) { @@ -127,7 +127,7 @@ float BKE_mesh_remap_calc_difference_from_mesh(const SpaceTransform *space_trans for (i = 0; i < numverts_dst; i++) { float tmp_co[3]; - copy_v3_v3(tmp_co, verts_dst[i].co); + copy_v3_v3(tmp_co, vert_positions_dst[i]); /* Convert the vertex to tree coordinates, if needed. */ if (space_transform) { @@ -164,7 +164,7 @@ float BKE_mesh_remap_calc_difference_from_mesh(const SpaceTransform *space_trans * axes in those cases. We default to dummy generated orthogonal vectors in this case, * instead of using eigen vectors. */ -static void mesh_calc_eigen_matrix(const MVert *verts, +static void mesh_calc_eigen_matrix(const float (*positions)[3], const float (*vcos)[3], const int numverts, float r_mat[4][4]) @@ -176,14 +176,9 @@ static void mesh_calc_eigen_matrix(const MVert *verts, bool eigen_success; int i; - if (verts) { - const MVert *mv; - float(*co)[3]; - + if (positions) { cos = static_cast(MEM_mallocN(sizeof(*cos) * size_t(numverts), __func__)); - for (i = 0, co = cos, mv = verts; i < numverts; i++, co++, mv++) { - copy_v3_v3(*co, mv->co); - } + memcpy(cos, positions, sizeof(float[3]) * size_t(numverts)); /* TODO(sergey): For until we officially drop all compilers which * doesn't handle casting correct we use workaround to avoid explicit * cast here. @@ -244,7 +239,7 @@ static void mesh_calc_eigen_matrix(const MVert *verts, copy_v3_v3(r_mat[3], center); } -void BKE_mesh_remap_find_best_match_from_mesh(const MVert *verts_dst, +void BKE_mesh_remap_find_best_match_from_mesh(const float (*vert_positions_dst)[3], const int numverts_dst, Mesh *me_src, SpaceTransform *r_space_transform) @@ -270,11 +265,11 @@ void BKE_mesh_remap_find_best_match_from_mesh(const MVert *verts_dst, float(*vcos_src)[3] = BKE_mesh_vert_coords_alloc(me_src, nullptr); mesh_calc_eigen_matrix(nullptr, (const float(*)[3])vcos_src, numverts_src, mat_src); - mesh_calc_eigen_matrix(verts_dst, nullptr, numverts_dst, mat_dst); + mesh_calc_eigen_matrix(vert_positions_dst, nullptr, numverts_dst, mat_dst); BLI_space_transform_global_from_matrices(r_space_transform, mat_dst, mat_src); match = BKE_mesh_remap_calc_difference_from_mesh( - r_space_transform, verts_dst, numverts_dst, me_src); + r_space_transform, vert_positions_dst, numverts_dst, me_src); best_match = match; copy_m4_m4(best_mat_dst, mat_dst); @@ -286,7 +281,7 @@ void BKE_mesh_remap_find_best_match_from_mesh(const MVert *verts_dst, BLI_space_transform_global_from_matrices(r_space_transform, mat_dst, mat_src); match = BKE_mesh_remap_calc_difference_from_mesh( - r_space_transform, verts_dst, numverts_dst, me_src); + r_space_transform, vert_positions_dst, numverts_dst, me_src); if (match < best_match) { best_match = match; copy_m4_m4(best_mat_dst, mat_dst); @@ -469,7 +464,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, const SpaceTransform *space_transform, const float max_dist, const float ray_radius, - const MVert *verts_dst, + const float (*vert_positions_dst)[3], const int numverts_dst, const bool /*dirty_nors_dst*/, Mesh *me_src, @@ -502,7 +497,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, nearest.index = -1; for (i = 0; i < numverts_dst; i++) { - copy_v3_v3(tmp_co, verts_dst[i].co); + copy_v3_v3(tmp_co, vert_positions_dst[i]); /* Convert the vertex to tree coordinates, if needed. */ if (space_transform) { @@ -527,7 +522,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, nearest.index = -1; for (i = 0; i < numverts_dst; i++) { - copy_v3_v3(tmp_co, verts_dst[i].co); + copy_v3_v3(tmp_co, vert_positions_dst[i]); /* Convert the vertex to tree coordinates, if needed. */ if (space_transform) { @@ -589,7 +584,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_co, vert_positions_dst[i]); copy_v3_v3(tmp_no, vert_normals_dst[i]); /* Convert the vertex to tree coordinates, if needed. */ @@ -626,7 +621,7 @@ void BKE_mesh_remap_calc_verts_from_mesh(const int mode, nearest.index = -1; for (i = 0; i < numverts_dst; i++) { - copy_v3_v3(tmp_co, verts_dst[i].co); + copy_v3_v3(tmp_co, vert_positions_dst[i]); /* Convert the vertex to tree coordinates, if needed. */ if (space_transform) { @@ -695,7 +690,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, const SpaceTransform *space_transform, const float max_dist, const float ray_radius, - const MVert *verts_dst, + const float (*vert_positions_dst)[3], const int numverts_dst, const MEdge *edges_dst, const int numedges_dst, @@ -765,7 +760,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, /* Compute closest verts only once! */ if (v_dst_to_src_map[vidx_dst].hit_dist == -1.0f) { - copy_v3_v3(tmp_co, verts_dst[vidx_dst].co); + copy_v3_v3(tmp_co, vert_positions_dst[vidx_dst]); /* Convert the vertex to tree coordinates, if needed. */ if (space_transform) { @@ -803,7 +798,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, const MEdge *e_src = &edges_src[*eidx_src]; const float *other_co_src = vcos_src[BKE_mesh_edge_other_vert(e_src, vidx_src)]; const float *other_co_dst = - verts_dst[BKE_mesh_edge_other_vert(e_dst, int(vidx_dst))].co; + vert_positions_dst[BKE_mesh_edge_other_vert(e_dst, int(vidx_dst))]; const float totdist = first_dist + len_v3v3(other_co_src, other_co_dst); if (totdist < best_totdist) { @@ -816,8 +811,8 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, if (best_eidx_src >= 0) { const float *co1_src = vcos_src[edges_src[best_eidx_src].v1]; const float *co2_src = vcos_src[edges_src[best_eidx_src].v2]; - const float *co1_dst = verts_dst[e_dst->v1].co; - const float *co2_dst = verts_dst[e_dst->v2].co; + const float *co1_dst = vert_positions_dst[e_dst->v1]; + const float *co2_dst = vert_positions_dst[e_dst->v2]; float co_src[3], co_dst[3]; /* TODO: would need an isect_seg_seg_v3(), actually! */ @@ -858,7 +853,10 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, nearest.index = -1; for (i = 0; i < numedges_dst; i++) { - interp_v3_v3v3(tmp_co, verts_dst[edges_dst[i].v1].co, verts_dst[edges_dst[i].v2].co, 0.5f); + interp_v3_v3v3(tmp_co, + vert_positions_dst[edges_dst[i].v1], + vert_positions_dst[edges_dst[i].v2], + 0.5f); /* Convert the vertex to tree coordinates, if needed. */ if (space_transform) { @@ -884,7 +882,10 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, BKE_bvhtree_from_mesh_get(&treedata, me_src, BVHTREE_FROM_LOOPTRI, 2); for (i = 0; i < numedges_dst; i++) { - interp_v3_v3v3(tmp_co, verts_dst[edges_dst[i].v1].co, verts_dst[edges_dst[i].v2].co, 0.5f); + interp_v3_v3v3(tmp_co, + vert_positions_dst[edges_dst[i].v1], + vert_positions_dst[edges_dst[i].v2], + 0.5f); /* Convert the vertex to tree coordinates, if needed. */ if (space_transform) { @@ -957,8 +958,8 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, int sources_num = 0; int j; - copy_v3_v3(v1_co, verts_dst[me->v1].co); - copy_v3_v3(v2_co, verts_dst[me->v2].co); + copy_v3_v3(v1_co, vert_positions_dst[me->v1]); + copy_v3_v3(v2_co, vert_positions_dst[me->v2]); copy_v3_v3(v1_no, vert_normals_dst[me->v1]); copy_v3_v3(v2_no, vert_normals_dst[me->v2]); @@ -1045,7 +1046,7 @@ void BKE_mesh_remap_calc_edges_from_mesh(const int mode, static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands, const int island_index, BLI_AStarGraph *as_graph, - const MVert *verts, + const float (*positions)[3], const MPoly *polys, const MLoop *loops, const int edge_idx, @@ -1077,7 +1078,7 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands, } if (poly_status[pidx_isld] == POLY_UNSET) { - BKE_mesh_calc_poly_center(mp, &loops[mp->loopstart], verts, poly_centers[pidx_isld]); + BKE_mesh_calc_poly_center(mp, &loops[mp->loopstart], positions, poly_centers[pidx_isld]); BLI_astar_node_init(as_graph, pidx_isld, poly_centers[pidx_isld]); poly_status[pidx_isld] = POLY_CENTER_INIT; } @@ -1102,7 +1103,7 @@ static void mesh_island_to_astar_graph_edge_process(MeshIslandStore *islands, static void mesh_island_to_astar_graph(MeshIslandStore *islands, const int island_index, - const MVert *verts, + const float (*positions)[3], MeshElemMap *edge_to_poly_map, const int numedges, const MLoop *loops, @@ -1143,7 +1144,7 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands, mesh_island_to_astar_graph_edge_process(islands, island_index, r_as_graph, - verts, + positions, polys, loops, island_einnercut_map->indices[i], @@ -1175,7 +1176,7 @@ static void mesh_island_to_astar_graph(MeshIslandStore *islands, mesh_island_to_astar_graph_edge_process(islands, island_index, r_as_graph, - verts, + positions, polys, loops, int(ml->e), @@ -1234,7 +1235,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, const float max_dist, const float ray_radius, Mesh *mesh_dst, - const MVert *verts_dst, + const float (*vert_positions_dst)[3], const int numverts_dst, const MEdge *edges_dst, const int numedges_dst, @@ -1307,7 +1308,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, /* Unlike above, those are one-to-one mappings, simpler! */ int *loop_to_poly_map_src = nullptr; - const MVert *verts_src = BKE_mesh_verts(me_src); + const float(*positions_src)[3] = BKE_mesh_vert_positions(me_src); const int num_verts_src = me_src->totvert; float(*vcos_src)[3] = nullptr; const MEdge *edges_src = BKE_mesh_edges(me_src); @@ -1367,7 +1368,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, CustomData_set_layer_flag(ldata_dst, CD_NORMAL, CD_FLAG_TEMPORARY); } if (dirty_nors_dst || do_loop_nors_dst) { - BKE_mesh_normals_loop_split(verts_dst, + BKE_mesh_normals_loop_split(vert_positions_dst, BKE_mesh_vertex_normals_ensure(mesh_dst), numverts_dst, edges_dst, @@ -1436,7 +1437,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, plidx_src++, lidx_src++) { loop_to_poly_map_src[lidx_src] = pidx_src; } - BKE_mesh_calc_poly_center(mp_src, ml_src, verts_src, poly_cents_src[pidx_src]); + BKE_mesh_calc_poly_center(mp_src, ml_src, positions_src, poly_cents_src[pidx_src]); } } @@ -1449,7 +1450,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, /* First, generate the islands, if possible. */ if (gen_islands_src) { - use_islands = gen_islands_src(verts_src, + use_islands = gen_islands_src(positions_src, num_verts_src, edges_src, num_edges_src, @@ -1489,7 +1490,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, for (tindex = 0; tindex < num_trees; tindex++) { mesh_island_to_astar_graph(use_islands ? &island_store : nullptr, tindex, - verts_src, + positions_src, edge_to_poly_map_src, num_edges_src, loops_src, @@ -1520,7 +1521,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, } } bvhtree_from_mesh_verts_ex(&treedata[tindex], - verts_src, + positions_src, num_verts_src, verts_active, num_verts_active, @@ -1552,7 +1553,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, } } bvhtree_from_mesh_looptri_ex(&treedata[tindex], - verts_src, + positions_src, loops_src, looptri_src, num_looptri_src, @@ -1608,7 +1609,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, if (use_from_vert) { MeshElemMap *vert_to_refelem_map_src = nullptr; - copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co); + copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]); nearest.index = -1; /* Convert the vertex to tree coordinates, if needed. */ @@ -1671,7 +1672,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, if (!pcent_dst_valid) { BKE_mesh_calc_poly_center( - mp_dst, &loops_dst[mp_dst->loopstart], verts_dst, pcent_dst); + mp_dst, &loops_dst[mp_dst->loopstart], vert_positions_dst, pcent_dst); pcent_dst_valid = true; } pcent_src = poly_cents_src[pidx_src]; @@ -1717,7 +1718,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, int n = (ray_radius > 0.0f) ? MREMAP_RAYCAST_APPROXIMATE_NR : 1; float w = 1.0f; - copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co); + copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]); copy_v3_v3(tmp_no, loop_nors_dst[plidx_dst + mp_dst->loopstart]); /* We do our transform here, since we may do several raycast/nearest queries. */ @@ -1745,7 +1746,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, * is null, it means none of its loop mapped to this source island, * hence we can skip it later. */ - copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co); + copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]); nearest.index = -1; /* Convert the vertex to tree coordinates, if needed. */ @@ -1771,7 +1772,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, } } else { /* Nearest poly either to use all its loops/verts or just closest one. */ - copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co); + copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]); nearest.index = -1; /* Convert the vertex to tree coordinates, if needed. */ @@ -1901,7 +1902,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, float best_dist_sq = FLT_MAX; ml_dst = &loops_dst[lidx_dst]; - copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co); + copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]); /* We do our transform here, * since we may do several raycast/nearest queries. */ @@ -1914,7 +1915,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, mp_src = &polys_src[pidx_src]; ml_src = &loops_src[mp_src->loopstart]; for (j = 0; j < mp_src->totloop; j++, ml_src++) { - const float dist_sq = len_squared_v3v3(verts_src[ml_src->v].co, tmp_co); + const float dist_sq = len_squared_v3v3(positions_src[ml_src->v], tmp_co); if (dist_sq < best_dist_sq) { best_dist_sq = dist_sq; lidx_src = mp_src->loopstart + j; @@ -1994,7 +1995,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, int j; ml_dst = &loops_dst[lidx_dst]; - copy_v3_v3(tmp_co, verts_dst[ml_dst->v].co); + copy_v3_v3(tmp_co, vert_positions_dst[ml_dst->v]); /* We do our transform here, * since we may do several raycast/nearest queries. */ @@ -2162,7 +2163,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, const float max_dist, const float ray_radius, const Mesh *mesh_dst, - const MVert *verts_dst, + const float (*vert_positions_dst)[3], const MLoop *loops_dst, const MPoly *polys_dst, const int numpolys_dst, @@ -2203,7 +2204,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, for (i = 0; i < numpolys_dst; i++) { const MPoly *mp = &polys_dst[i]; - BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co); + BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], vert_positions_dst, tmp_co); /* Convert the vertex to tree coordinates, if needed. */ if (space_transform) { @@ -2228,7 +2229,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, for (i = 0; i < numpolys_dst; i++) { const MPoly *mp = &polys_dst[i]; - BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, tmp_co); + BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], vert_positions_dst, tmp_co); copy_v3_v3(tmp_no, poly_nors_dst[i]); /* Convert the vertex to tree coordinates, if needed. */ @@ -2291,7 +2292,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, const int tris_num = mp->totloop - 2; int j; - BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], verts_dst, pcent_dst); + BKE_mesh_calc_poly_center(mp, &loops_dst[mp->loopstart], vert_positions_dst, pcent_dst); copy_v3_v3(tmp_no, poly_nors_dst[i]); /* We do our transform here, else it'd be redone by raycast helper for each ray, ugh! */ @@ -2321,7 +2322,7 @@ void BKE_mesh_remap_calc_polys_from_mesh(const int mode, for (j = 0; j < mp->totloop; j++) { const MLoop *ml = &loops_dst[j + mp->loopstart]; - copy_v3_v3(tmp_co, verts_dst[ml->v].co); + copy_v3_v3(tmp_co, vert_positions_dst[ml->v]); if (space_transform) { BLI_space_transform_apply(space_transform, tmp_co); } diff --git a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc index e44dd1a1c75..dfbc1298960 100644 --- a/source/blender/blenkernel/intern/mesh_remesh_voxel.cc +++ b/source/blender/blenkernel/intern/mesh_remesh_voxel.cc @@ -63,7 +63,7 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh, void (*update_cb)(void *, float progress, int *cancel), void *update_cb_data) { - const Span input_verts = input_mesh->verts(); + const Span input_positions = input_mesh->vert_positions(); const Span input_loops = input_mesh->loops(); const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(input_mesh); @@ -75,13 +75,8 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh, const int totfaces = BKE_mesh_runtime_looptri_len(input_mesh); const int totverts = input_mesh->totvert; - Array verts(totverts); Array faces(totfaces * 3); - for (const int i : IndexRange(totverts)) { - verts[i] = input_verts[i].co; - } - for (const int i : IndexRange(totfaces)) { MVertTri &vt = verttri[i]; faces[i * 3] = vt.tri[0]; @@ -94,7 +89,7 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh, qrd.totfaces = totfaces; qrd.totverts = totverts; - qrd.verts = (float *)verts.data(); + qrd.verts = (float *)input_positions.data(); qrd.faces = faces.data(); qrd.target_faces = target_faces; @@ -127,13 +122,11 @@ static Mesh *remesh_quadriflow(const Mesh *input_mesh, /* Construct the new output mesh */ Mesh *mesh = BKE_mesh_new_nomain(qrd.out_totverts, 0, 0, qrd.out_totfaces * 4, qrd.out_totfaces); BKE_mesh_copy_parameters(mesh, input_mesh); - MutableSpan mesh_verts = mesh->verts_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); - for (const int i : IndexRange(qrd.out_totverts)) { - copy_v3_v3(mesh_verts[i].co, &qrd.out_verts[i * 3]); - } + mesh->vert_positions_for_write().copy_from( + Span(reinterpret_cast(qrd.out_verts), qrd.out_totverts)); for (const int i : IndexRange(qrd.out_totfaces)) { MPoly &poly = polys[i]; @@ -193,7 +186,7 @@ Mesh *BKE_mesh_remesh_quadriflow(const Mesh *mesh, static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh, const float voxel_size) { - const Span verts = mesh->verts(); + const Span positions = mesh->vert_positions(); const Span loops = mesh->loops(); const Span looptris = mesh->looptris(); @@ -201,7 +194,7 @@ static openvdb::FloatGrid::Ptr remesh_voxel_level_set_create(const Mesh *mesh, std::vector triangles(looptris.size()); for (const int i : IndexRange(mesh->totvert)) { - const float3 co = verts[i].co; + const float3 &co = positions[i]; points[i] = openvdb::Vec3s(co.x, co.y, co.z); } @@ -232,12 +225,12 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set Mesh *mesh = BKE_mesh_new_nomain( vertices.size(), 0, 0, quads.size() * 4 + tris.size() * 3, quads.size() + tris.size()); - MutableSpan mesh_verts = mesh->verts_for_write(); + MutableSpan vert_positions = mesh->vert_positions_for_write(); MutableSpan mesh_polys = mesh->polys_for_write(); MutableSpan mesh_loops = mesh->loops_for_write(); - for (const int i : mesh_verts.index_range()) { - copy_v3_v3(mesh_verts[i].co, float3(vertices[i].x(), vertices[i].y(), vertices[i].z())); + for (const int i : vert_positions.index_range()) { + vert_positions[i] = float3(vertices[i].x(), vertices[i].y(), vertices[i].z()); } for (const int i : IndexRange(quads.size())) { @@ -288,7 +281,7 @@ void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, const Mesh *source) { BVHTreeFromMesh bvhtree = {nullptr}; BKE_bvhtree_from_mesh_get(&bvhtree, source, BVHTREE_FROM_VERTS, 2); - const Span target_verts = target->verts(); + const Span target_positions = target->vert_positions(); const float *source_mask = (const float *)CustomData_get_layer(&source->vdata, CD_PAINT_MASK); if (source_mask == nullptr) { return; @@ -309,7 +302,7 @@ void BKE_mesh_remesh_reproject_paint_mask(Mesh *target, const Mesh *source) nearest.index = -1; nearest.dist_sq = FLT_MAX; BLI_bvhtree_find_nearest( - bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree); + bvhtree.tree, target_positions[i], &nearest, bvhtree.nearest_callback, &bvhtree); if (nearest.index != -1) { target_mask[i] = source_mask[nearest.index]; } @@ -324,7 +317,7 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source) using namespace blender::bke; const AttributeAccessor src_attributes = source->attributes(); MutableAttributeAccessor dst_attributes = target->attributes_for_write(); - const Span target_verts = target->verts(); + const Span target_positions = target->vert_positions(); const Span target_polys = target->polys(); const Span target_loops = target->loops(); @@ -352,9 +345,11 @@ void BKE_remesh_reproject_sculpt_face_sets(Mesh *target, const Mesh *source) BVHTreeNearest nearest; nearest.index = -1; nearest.dist_sq = FLT_MAX; - const MPoly &poly = target_polys[i]; - BKE_mesh_calc_poly_center( - &poly, &target_loops[poly.loopstart], target_verts.data(), from_co); + const MPoly *mpoly = &target_polys[i]; + BKE_mesh_calc_poly_center(mpoly, + &target_loops[mpoly->loopstart], + reinterpret_cast(target_positions.data()), + from_co); BLI_bvhtree_find_nearest( bvhtree.tree, from_co, &nearest, bvhtree.nearest_callback, &bvhtree); if (nearest.index != -1) { @@ -402,7 +397,7 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source) size_t data_size = CustomData_sizeof(layer->type); void *target_data = target_cdata->layers[layer_i].data; void *source_data = layer->data; - const Span target_verts = target->verts(); + const Span target_positions = target->vert_positions(); if (domain == ATTR_DOMAIN_POINT) { blender::threading::parallel_for( @@ -412,8 +407,7 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source) nearest.index = -1; nearest.dist_sq = FLT_MAX; BLI_bvhtree_find_nearest( - bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree); - + bvhtree.tree, target_positions[i], &nearest, bvhtree.nearest_callback, &bvhtree); if (nearest.index != -1) { memcpy(POINTER_OFFSET(target_data, size_t(i) * data_size), POINTER_OFFSET(source_data, size_t(nearest.index) * data_size), @@ -449,7 +443,7 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source) nearest.index = -1; nearest.dist_sq = FLT_MAX; BLI_bvhtree_find_nearest( - bvhtree.tree, target_verts[i].co, &nearest, bvhtree.nearest_callback, &bvhtree); + bvhtree.tree, target_positions[i], &nearest, bvhtree.nearest_callback, &bvhtree); if (nearest.index == -1) { continue; diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc index 8f71b9eee71..b3e416c2b7b 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.cc +++ b/source/blender/blenkernel/intern/mesh_runtime.cc @@ -25,6 +25,7 @@ #include "BKE_shrinkwrap.h" #include "BKE_subdiv_ccg.h" +using blender::float3; using blender::MutableSpan; using blender::Span; @@ -143,20 +144,24 @@ void Mesh::loose_edges_tag_none() const blender::Span Mesh::looptris() const { this->runtime->looptris_cache.ensure([&](blender::Array &r_data) { - const Span verts = this->verts(); + const Span positions = this->vert_positions(); const Span polys = this->polys(); const Span loops = this->loops(); r_data.reinitialize(poly_to_tri_count(polys.size(), loops.size())); if (BKE_mesh_poly_normals_are_dirty(this)) { - BKE_mesh_recalc_looptri( - loops.data(), polys.data(), verts.data(), loops.size(), polys.size(), r_data.data()); + BKE_mesh_recalc_looptri(loops.data(), + polys.data(), + reinterpret_cast(positions.data()), + loops.size(), + polys.size(), + r_data.data()); } else { BKE_mesh_recalc_looptri_with_normals(loops.data(), polys.data(), - verts.data(), + reinterpret_cast(positions.data()), loops.size(), polys.size(), r_data.data(), @@ -317,7 +322,7 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval) printf("MESH: %s\n", me_eval->id.name + 2); } - MutableSpan verts = me_eval->verts_for_write(); + MutableSpan positions = me_eval->vert_positions_for_write(); MutableSpan edges = me_eval->edges_for_write(); MutableSpan polys = me_eval->polys_for_write(); MutableSpan loops = me_eval->loops_for_write(); @@ -338,8 +343,8 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval) is_valid &= BKE_mesh_validate_arrays( me_eval, - verts.data(), - verts.size(), + reinterpret_cast(positions.data()), + positions.size(), edges.data(), edges.size(), static_cast(CustomData_get_layer(&me_eval->fdata, CD_MFACE)), diff --git a/source/blender/blenkernel/intern/mesh_sample.cc b/source/blender/blenkernel/intern/mesh_sample.cc index ed7ae8113a7..316fa41e16f 100644 --- a/source/blender/blenkernel/intern/mesh_sample.cc +++ b/source/blender/blenkernel/intern/mesh_sample.cc @@ -156,7 +156,7 @@ Span MeshAttributeInterpolator::ensure_barycentric_coords() } bary_coords_.reinitialize(mask_.min_array_size()); - const Span verts = mesh_->verts(); + const Span positions = mesh_->vert_positions(); const Span loops = mesh_->loops(); const Span looptris = mesh_->looptris(); @@ -169,9 +169,9 @@ Span MeshAttributeInterpolator::ensure_barycentric_coords() const int v2_index = loops[looptri.tri[2]].v; interp_weights_tri_v3(bary_coords_[i], - verts[v0_index].co, - verts[v1_index].co, - verts[v2_index].co, + positions[v0_index], + positions[v1_index], + positions[v2_index], positions_[i]); } return bary_coords_; @@ -185,7 +185,7 @@ Span MeshAttributeInterpolator::ensure_nearest_weights() } nearest_weights_.reinitialize(mask_.min_array_size()); - const Span verts = mesh_->verts(); + const Span positions = mesh_->vert_positions(); const Span loops = mesh_->loops(); const Span looptris = mesh_->looptris(); @@ -197,9 +197,9 @@ Span MeshAttributeInterpolator::ensure_nearest_weights() const int v1_index = loops[looptri.tri[1]].v; const int v2_index = loops[looptri.tri[2]].v; - const float d0 = len_squared_v3v3(positions_[i], verts[v0_index].co); - const float d1 = len_squared_v3v3(positions_[i], verts[v1_index].co); - const float d2 = len_squared_v3v3(positions_[i], verts[v2_index].co); + const float d0 = len_squared_v3v3(positions_[i], positions[v0_index]); + const float d1 = len_squared_v3v3(positions_[i], positions[v1_index]); + const float d2 = len_squared_v3v3(positions_[i], positions[v2_index]); nearest_weights_[i] = MIN3_PAIR(d0, d1, d2, float3(1, 0, 0), float3(0, 1, 0), float3(0, 0, 1)); } @@ -258,7 +258,7 @@ int sample_surface_points_spherical(RandomNumberGenerator &rng, Vector &r_looptri_indices, Vector &r_positions) { - const Span verts = mesh.verts(); + const Span positions = mesh.vert_positions(); const Span loops = mesh.loops(); const Span looptris = mesh.looptris(); @@ -272,9 +272,9 @@ int sample_surface_points_spherical(RandomNumberGenerator &rng, for (const int looptri_index : looptri_indices_to_sample) { const MLoopTri &looptri = looptris[looptri_index]; - const float3 &v0 = verts[loops[looptri.tri[0]].v].co; - const float3 &v1 = verts[loops[looptri.tri[1]].v].co; - const float3 &v2 = verts[loops[looptri.tri[2]].v].co; + const float3 &v0 = positions[loops[looptri.tri[0]].v]; + const float3 &v1 = positions[loops[looptri.tri[1]].v]; + const float3 &v2 = positions[loops[looptri.tri[2]].v]; const float looptri_area = area_tri_v3(v0, v1, v2); @@ -355,7 +355,7 @@ int sample_surface_points_projected( Vector &r_looptri_indices, Vector &r_positions) { - const Span verts = mesh.verts(); + const Span positions = mesh.vert_positions(); const Span loops = mesh.loops(); const Span looptris = mesh.looptris(); @@ -398,7 +398,7 @@ int sample_surface_points_projected( const float3 pos = ray_hit.co; const float3 bary_coords = compute_bary_coord_in_triangle( - verts, loops, looptris[looptri_index], pos); + positions, loops, looptris[looptri_index], pos); r_positions.append(pos); r_bary_coords.append(bary_coords); @@ -408,14 +408,14 @@ int sample_surface_points_projected( return point_count; } -float3 compute_bary_coord_in_triangle(const Span verts, +float3 compute_bary_coord_in_triangle(const Span vert_positions, const Span loops, const MLoopTri &looptri, const float3 &position) { - const float3 &v0 = verts[loops[looptri.tri[0]].v].co; - const float3 &v1 = verts[loops[looptri.tri[1]].v].co; - const float3 &v2 = verts[loops[looptri.tri[2]].v].co; + const float3 &v0 = vert_positions[loops[looptri.tri[0]].v]; + const float3 &v1 = vert_positions[loops[looptri.tri[1]].v]; + const float3 &v2 = vert_positions[loops[looptri.tri[2]].v]; float3 bary_coords; interp_weights_tri_v3(bary_coords, v0, v1, v2, position); return bary_coords; diff --git a/source/blender/blenkernel/intern/mesh_tangent.cc b/source/blender/blenkernel/intern/mesh_tangent.cc index 8534a68cca4..4a9155914a3 100644 --- a/source/blender/blenkernel/intern/mesh_tangent.cc +++ b/source/blender/blenkernel/intern/mesh_tangent.cc @@ -47,7 +47,7 @@ struct BKEMeshToTangent { mikk::float3 GetPosition(const uint face_num, const uint vert_num) { const uint loop_idx = uint(mpolys[face_num].loopstart) + vert_num; - return mikk::float3(mverts[mloops[loop_idx].v].co); + return mikk::float3(positions[mloops[loop_idx].v]); } mikk::float3 GetTexCoord(const uint face_num, const uint vert_num) @@ -69,14 +69,14 @@ struct BKEMeshToTangent { const MPoly *mpolys; /* faces */ const MLoop *mloops; /* faces vertices */ - const MVert *mverts; /* vertices */ + const float (*positions)[3]; /* vertices */ const MLoopUV *luvs; /* texture coordinates */ const float (*loop_normals)[3]; /* loops' normals */ float (*tangents)[4]; /* output tangents */ int num_polys; /* number of polygons */ }; -void BKE_mesh_calc_loop_tangent_single_ex(const MVert *mverts, +void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3], const int /*numVerts*/, const MLoop *mloops, float (*r_looptangent)[4], @@ -91,7 +91,7 @@ void BKE_mesh_calc_loop_tangent_single_ex(const MVert *mverts, BKEMeshToTangent mesh_to_tangent; mesh_to_tangent.mpolys = mpolys; mesh_to_tangent.mloops = mloops; - mesh_to_tangent.mverts = mverts; + mesh_to_tangent.positions = vert_positions; mesh_to_tangent.luvs = loopuvs; mesh_to_tangent.loop_normals = loop_normals; mesh_to_tangent.tangents = r_looptangent; @@ -141,7 +141,7 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, return; } - BKE_mesh_calc_loop_tangent_single_ex(BKE_mesh_verts(mesh), + BKE_mesh_calc_loop_tangent_single_ex(BKE_mesh_vert_positions(mesh), mesh->totvert, BKE_mesh_loops(mesh), r_looptangents, @@ -213,7 +213,7 @@ struct SGLSLMeshToTangent { { const MLoopTri *lt; uint loop_index = GetLoop(face_num, vert_num, lt); - return mikk::float3(mvert[mloop[loop_index].v].co); + return mikk::float3(positions[mloop[loop_index].v]); } mikk::float3 GetTexCoord(const uint face_num, const uint vert_num) @@ -246,18 +246,18 @@ struct SGLSLMeshToTangent { float normal[3]; if (mp->totloop == 4) { normal_quad_v3(normal, - mvert[mloop[mp->loopstart + 0].v].co, - mvert[mloop[mp->loopstart + 1].v].co, - mvert[mloop[mp->loopstart + 2].v].co, - mvert[mloop[mp->loopstart + 3].v].co); + positions[mloop[mp->loopstart + 0].v], + positions[mloop[mp->loopstart + 1].v], + positions[mloop[mp->loopstart + 2].v], + positions[mloop[mp->loopstart + 3].v]); } else #endif { normal_tri_v3(normal, - mvert[mloop[lt->tri[0]].v].co, - mvert[mloop[lt->tri[1]].v].co, - mvert[mloop[lt->tri[2]].v].co); + positions[mloop[lt->tri[0]].v], + positions[mloop[lt->tri[1]].v], + positions[mloop[lt->tri[2]].v]); } return mikk::float3(normal); } @@ -275,10 +275,10 @@ struct SGLSLMeshToTangent { const float (*precomputedFaceNormals)[3]; const float (*precomputedLoopNormals)[3]; const MLoopTri *looptri; - const MLoopUV *mloopuv; /* texture coordinates */ - const MPoly *mpoly; /* indices */ - const MLoop *mloop; /* indices */ - const MVert *mvert; /* vertex coordinates */ + const MLoopUV *mloopuv; /* texture coordinates */ + const MPoly *mpoly; /* indices */ + const MLoop *mloop; /* indices */ + const float (*positions)[3]; /* vertex coordinates */ const float (*vert_normals)[3]; const float (*orco)[3]; float (*tangent)[4]; /* destination */ @@ -385,7 +385,7 @@ void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData, } } -void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert, +void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], const MPoly *mpoly, const uint mpoly_len, const MLoop *mloop, @@ -490,7 +490,7 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert, mesh2tangent->face_as_quad_map = face_as_quad_map; mesh2tangent->num_face_as_quad_map = num_face_as_quad_map; #endif - mesh2tangent->mvert = mvert; + mesh2tangent->positions = vert_positions; mesh2tangent->vert_normals = vert_normals; mesh2tangent->mpoly = mpoly; mesh2tangent->mloop = mloop; @@ -573,7 +573,7 @@ void BKE_mesh_calc_loop_tangents(Mesh *me_eval, /* TODO(@campbellbarton): store in Mesh.runtime to avoid recalculation. */ short tangent_mask = 0; BKE_mesh_calc_loop_tangent_ex( - BKE_mesh_verts(me_eval), + BKE_mesh_vert_positions(me_eval), BKE_mesh_polys(me_eval), uint(me_eval->totpoly), BKE_mesh_loops(me_eval), diff --git a/source/blender/blenkernel/intern/mesh_tessellate.cc b/source/blender/blenkernel/intern/mesh_tessellate.cc index df83743634c..275163c0007 100644 --- a/source/blender/blenkernel/intern/mesh_tessellate.cc +++ b/source/blender/blenkernel/intern/mesh_tessellate.cc @@ -42,7 +42,7 @@ */ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop, const MPoly *mpoly, - const MVert *mvert, + const float (*positions)[3], uint poly_index, MLoopTri *mlt, MemArena **pf_arena_p, @@ -72,17 +72,17 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop, if (UNLIKELY(face_normal ? is_quad_flip_v3_first_third_fast_with_normal( /* Simpler calculation (using the normal). */ - mvert[mloop[mlt_a->tri[0]].v].co, - mvert[mloop[mlt_a->tri[1]].v].co, - mvert[mloop[mlt_a->tri[2]].v].co, - mvert[mloop[mlt_b->tri[2]].v].co, + positions[mloop[mlt_a->tri[0]].v], + positions[mloop[mlt_a->tri[1]].v], + positions[mloop[mlt_a->tri[2]].v], + positions[mloop[mlt_b->tri[2]].v], normal_precalc) : is_quad_flip_v3_first_third_fast( /* Expensive calculation (no normal). */ - mvert[mloop[mlt_a->tri[0]].v].co, - mvert[mloop[mlt_a->tri[1]].v].co, - mvert[mloop[mlt_a->tri[2]].v].co, - mvert[mloop[mlt_b->tri[2]].v].co))) { + positions[mloop[mlt_a->tri[0]].v], + positions[mloop[mlt_a->tri[1]].v], + positions[mloop[mlt_a->tri[2]].v], + positions[mloop[mlt_b->tri[2]].v]))) { /* Flip out of degenerate 0-2 state. */ mlt_a->tri[2] = mlt_b->tri[2]; mlt_b->tri[0] = mlt_a->tri[1]; @@ -102,9 +102,9 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop, /* Calc normal, flipped: to get a positive 2D cross product. */ ml = mloop + mp_loopstart; - co_prev = mvert[ml[mp_totloop - 1].v].co; + co_prev = positions[ml[mp_totloop - 1].v]; for (uint j = 0; j < mp_totloop; j++, ml++) { - co_curr = mvert[ml->v].co; + co_curr = positions[ml->v]; add_newell_cross_v3_v3v3(normal, co_prev, co_curr); co_prev = co_curr; } @@ -131,7 +131,7 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop, ml = mloop + mp_loopstart; for (uint j = 0; j < mp_totloop; j++, ml++) { - mul_v2_m3v3(projverts[j], axis_mat, mvert[ml->v].co); + mul_v2_m3v3(projverts[j], axis_mat, positions[ml->v]); } BLI_polyfill_calc_arena(projverts, mp_totloop, 1, tris, pf_arena); @@ -152,30 +152,30 @@ BLI_INLINE void mesh_calc_tessellation_for_face_impl(const MLoop *mloop, static void mesh_calc_tessellation_for_face(const MLoop *mloop, const MPoly *mpoly, - const MVert *mvert, + const float (*positions)[3], uint poly_index, MLoopTri *mlt, MemArena **pf_arena_p) { mesh_calc_tessellation_for_face_impl( - mloop, mpoly, mvert, poly_index, mlt, pf_arena_p, false, nullptr); + mloop, mpoly, positions, poly_index, mlt, pf_arena_p, false, nullptr); } static void mesh_calc_tessellation_for_face_with_normal(const MLoop *mloop, const MPoly *mpoly, - const MVert *mvert, + const float (*positions)[3], uint poly_index, MLoopTri *mlt, MemArena **pf_arena_p, const float normal_precalc[3]) { mesh_calc_tessellation_for_face_impl( - mloop, mpoly, mvert, poly_index, mlt, pf_arena_p, true, normal_precalc); + mloop, mpoly, positions, poly_index, mlt, pf_arena_p, true, normal_precalc); } static void mesh_recalc_looptri__single_threaded(const MLoop *mloop, const MPoly *mpoly, - const MVert *mvert, + const float (*positions)[3], int totloop, int totpoly, MLoopTri *mlooptri, @@ -189,7 +189,7 @@ static void mesh_recalc_looptri__single_threaded(const MLoop *mloop, for (uint poly_index = 0; poly_index < uint(totpoly); poly_index++, mp++) { mesh_calc_tessellation_for_face_with_normal(mloop, mpoly, - mvert, + positions, poly_index, &mlooptri[tri_index], &pf_arena, @@ -200,7 +200,7 @@ static void mesh_recalc_looptri__single_threaded(const MLoop *mloop, else { for (uint poly_index = 0; poly_index < uint(totpoly); poly_index++, mp++) { mesh_calc_tessellation_for_face( - mloop, mpoly, mvert, poly_index, &mlooptri[tri_index], &pf_arena); + mloop, mpoly, positions, poly_index, &mlooptri[tri_index], &pf_arena); tri_index += uint(mp->totloop - 2); } } @@ -216,7 +216,7 @@ static void mesh_recalc_looptri__single_threaded(const MLoop *mloop, struct TessellationUserData { const MLoop *mloop; const MPoly *mpoly; - const MVert *mvert; + const float (*positions)[3]; /** Output array. */ MLoopTri *mlooptri; @@ -238,7 +238,7 @@ static void mesh_calc_tessellation_for_face_fn(void *__restrict userdata, const int tri_index = poly_to_tri_count(index, data->mpoly[index].loopstart); mesh_calc_tessellation_for_face_impl(data->mloop, data->mpoly, - data->mvert, + data->positions, uint(index), &data->mlooptri[tri_index], &tls_data->pf_arena, @@ -255,7 +255,7 @@ static void mesh_calc_tessellation_for_face_with_normal_fn(void *__restrict user const int tri_index = poly_to_tri_count(index, data->mpoly[index].loopstart); mesh_calc_tessellation_for_face_impl(data->mloop, data->mpoly, - data->mvert, + data->positions, uint(index), &data->mlooptri[tri_index], &tls_data->pf_arena, @@ -274,7 +274,7 @@ static void mesh_calc_tessellation_for_face_free_fn(const void *__restrict /*use static void mesh_recalc_looptri__multi_threaded(const MLoop *mloop, const MPoly *mpoly, - const MVert *mvert, + const float (*positions)[3], int /*totloop*/, int totpoly, MLoopTri *mlooptri, @@ -286,7 +286,7 @@ static void mesh_recalc_looptri__multi_threaded(const MLoop *mloop, }; data.mloop = mloop; data.mpoly = mpoly; - data.mvert = mvert; + data.positions = positions; data.mlooptri = mlooptri; data.poly_normals = poly_normals; @@ -308,22 +308,24 @@ static void mesh_recalc_looptri__multi_threaded(const MLoop *mloop, void BKE_mesh_recalc_looptri(const MLoop *mloop, const MPoly *mpoly, - const MVert *mvert, + const float (*vert_positions)[3], int totloop, int totpoly, MLoopTri *mlooptri) { if (totloop < MESH_FACE_TESSELLATE_THREADED_LIMIT) { - mesh_recalc_looptri__single_threaded(mloop, mpoly, mvert, totloop, totpoly, mlooptri, nullptr); + mesh_recalc_looptri__single_threaded( + mloop, mpoly, vert_positions, totloop, totpoly, mlooptri, nullptr); } else { - mesh_recalc_looptri__multi_threaded(mloop, mpoly, mvert, totloop, totpoly, mlooptri, nullptr); + mesh_recalc_looptri__multi_threaded( + mloop, mpoly, vert_positions, totloop, totpoly, mlooptri, nullptr); } } void BKE_mesh_recalc_looptri_with_normals(const MLoop *mloop, const MPoly *mpoly, - const MVert *mvert, + const float (*vert_positions)[3], int totloop, int totpoly, MLoopTri *mlooptri, @@ -332,11 +334,11 @@ void BKE_mesh_recalc_looptri_with_normals(const MLoop *mloop, BLI_assert(poly_normals != nullptr); if (totloop < MESH_FACE_TESSELLATE_THREADED_LIMIT) { mesh_recalc_looptri__single_threaded( - mloop, mpoly, mvert, totloop, totpoly, mlooptri, poly_normals); + mloop, mpoly, vert_positions, totloop, totpoly, mlooptri, poly_normals); } else { mesh_recalc_looptri__multi_threaded( - mloop, mpoly, mvert, totloop, totpoly, mlooptri, poly_normals); + mloop, mpoly, vert_positions, totloop, totpoly, mlooptri, poly_normals); } } diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc index 634a92e23ca..6d9660ff8bb 100644 --- a/source/blender/blenkernel/intern/mesh_validate.cc +++ b/source/blender/blenkernel/intern/mesh_validate.cc @@ -33,6 +33,7 @@ #include "MEM_guardedalloc.h" +using blender::float3; using blender::MutableSpan; using blender::Span; @@ -206,7 +207,7 @@ static int search_polyloop_cmp(const void *v1, const void *v2) /* NOLINTNEXTLINE: readability-function-size */ bool BKE_mesh_validate_arrays(Mesh *mesh, - MVert *mverts, + float (*vert_positions)[3], uint totvert, MEdge *medges, uint totedge, @@ -246,7 +247,6 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, mesh->attributes_for_write().lookup_for_write("material_index"); blender::MutableVArraySpan material_indices_span(material_indices.varray); - MVert *mv = mverts; MEdge *me; MLoop *ml; MPoly *mp; @@ -302,15 +302,15 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, vert_normals = BKE_mesh_vertex_normals_ensure(mesh); } - for (i = 0; i < totvert; i++, mv++) { + for (i = 0; i < totvert; i++) { bool fix_normal = true; for (j = 0; j < 3; j++) { - if (!isfinite(mv->co[j])) { + if (!isfinite(vert_positions[i][j])) { PRINT_ERR("\tVertex %u: has invalid coordinate", i); if (do_fixes) { - zero_v3(mv->co); + zero_v3(vert_positions[i]); fix_flag.verts = true; } @@ -332,7 +332,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, * although it's also possible degenerate/opposite faces accumulate to a zero vector. * To detect this a full normal recalculation would be needed, which is out of scope * for a basic validity check (see "Vertex Normal" in the doc-string). */ - if (!is_zero_v3(mv->co)) { + if (!is_zero_v3(vert_positions[i])) { PRINT_ERR("\tVertex %u: has zero normal, assuming Z-up normal", i); if (do_fixes) { float *normal = (float *)vert_normals[i]; @@ -1066,14 +1066,14 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_ do_verbose, true, &changed); - MutableSpan verts = me->verts_for_write(); + MutableSpan positions = me->vert_positions_for_write(); MutableSpan edges = me->edges_for_write(); MutableSpan polys = me->polys_for_write(); MutableSpan loops = me->loops_for_write(); BKE_mesh_validate_arrays(me, - verts.data(), - verts.size(), + reinterpret_cast(positions.data()), + positions.size(), edges.data(), edges.size(), (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE), @@ -1117,14 +1117,14 @@ bool BKE_mesh_is_valid(Mesh *me) do_fixes, &changed); - MutableSpan verts = me->verts_for_write(); + MutableSpan positions = me->vert_positions_for_write(); MutableSpan edges = me->edges_for_write(); MutableSpan polys = me->polys_for_write(); MutableSpan loops = me->loops_for_write(); is_valid &= BKE_mesh_validate_arrays(me, - verts.data(), - verts.size(), + reinterpret_cast(positions.data()), + positions.size(), edges.data(), edges.size(), (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE), diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc index 61a95fb4d0e..33c67e606b9 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.cc +++ b/source/blender/blenkernel/intern/mesh_wrapper.cc @@ -7,7 +7,7 @@ * output of a modified mesh. * * This API handles the case when the modifier stack outputs a mesh which does not have - * #Mesh data (#MPoly, #MLoop, #MEdge, #MVert). + * #Mesh data (#MPoly, #MLoop, #MEdge, etc). * Currently this is used so the resulting mesh can have #BMEditMesh data, * postponing the converting until it's needed or avoiding conversion entirely * which can be an expensive operation. @@ -46,6 +46,7 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +using blender::float3; using blender::Span; Mesh *BKE_mesh_wrapper_from_editmesh_with_coords(BMEditMesh *em, @@ -192,9 +193,9 @@ void BKE_mesh_wrapper_vert_coords_copy(const Mesh *me, case ME_WRAPPER_TYPE_MDATA: case ME_WRAPPER_TYPE_SUBD: { BLI_assert(vert_coords_len <= me->totvert); - const Span verts = me->verts(); + const Span positions = me->vert_positions(); for (int i = 0; i < vert_coords_len; i++) { - copy_v3_v3(vert_coords[i], verts[i].co); + copy_v3_v3(vert_coords[i], positions[i]); } return; } @@ -230,9 +231,9 @@ void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *me, case ME_WRAPPER_TYPE_MDATA: case ME_WRAPPER_TYPE_SUBD: { BLI_assert(vert_coords_len == me->totvert); - const Span verts = me->verts(); + const Span positions = me->vert_positions(); for (int i = 0; i < vert_coords_len; i++) { - mul_v3_m4v3(vert_coords[i], mat, verts[i].co); + mul_v3_m4v3(vert_coords[i], mat, positions[i]); } return; } diff --git a/source/blender/blenkernel/intern/modifier.cc b/source/blender/blenkernel/intern/modifier.cc index 92a7c778b68..50c9c13a9ac 100644 --- a/source/blender/blenkernel/intern/modifier.cc +++ b/source/blender/blenkernel/intern/modifier.cc @@ -1189,8 +1189,8 @@ void BKE_modifier_blend_write(BlendWriter *writer, const ID *id_owner, ListBase CollisionModifierData *collmd = (CollisionModifierData *)md; /* TODO: CollisionModifier should use pointcache * + have proper reset events before enabling this. */ - writestruct(wd, DATA, MVert, collmd->numverts, collmd->x); - writestruct(wd, DATA, MVert, collmd->numverts, collmd->xnew); + writestruct(wd, DATA, float[3], collmd->numverts, collmd->x); + writestruct(wd, DATA, float[3], collmd->numverts, collmd->xnew); writestruct(wd, DATA, MFace, collmd->numfaces, collmd->mfaces); #endif } diff --git a/source/blender/blenkernel/intern/multires.cc b/source/blender/blenkernel/intern/multires.cc index aca392d7c19..890a1379e4c 100644 --- a/source/blender/blenkernel/intern/multires.cc +++ b/source/blender/blenkernel/intern/multires.cc @@ -1618,7 +1618,7 @@ int mdisp_rot_face_to_crn( float mindist = FLT_MAX; for (i = 0; i < mpoly->totloop; i++) { - float len = len_v3v3(nullptr, mvert[mloop[mpoly->loopstart + i].v].co); + float len = len_v3v3(nullptr, positions[mloop[mpoly->loopstart + i].v]); if (len < mindist) { mindist = len; minS = i; diff --git a/source/blender/blenkernel/intern/multires_reshape.h b/source/blender/blenkernel/intern/multires_reshape.h index f27618b2145..1aa20cb7f48 100644 --- a/source/blender/blenkernel/intern/multires_reshape.h +++ b/source/blender/blenkernel/intern/multires_reshape.h @@ -19,7 +19,6 @@ struct Mesh; struct MLoop; struct MPoly; struct MultiresModifierData; -struct MVert; struct Object; struct Subdiv; struct SubdivCCG; @@ -34,7 +33,7 @@ typedef struct MultiresReshapeContext { /* Base mesh from original object. * NOTE: Does NOT include any leading modifiers in it. */ struct Mesh *base_mesh; - const struct MVert *base_verts; + const float (*base_positions)[3]; const struct MEdge *base_edges; const struct MPoly *base_polys; const struct MLoop *base_loops; diff --git a/source/blender/blenkernel/intern/multires_reshape_apply_base.c b/source/blender/blenkernel/intern/multires_reshape_apply_base.c index 81b0abbdcf5..0da5d814992 100644 --- a/source/blender/blenkernel/intern/multires_reshape_apply_base.c +++ b/source/blender/blenkernel/intern/multires_reshape_apply_base.c @@ -30,14 +30,13 @@ void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *reshape_context) { Mesh *base_mesh = reshape_context->base_mesh; - MVert *base_verts = BKE_mesh_verts_for_write(base_mesh); + float(*base_positions)[3] = BKE_mesh_vert_positions_for_write(base_mesh); /* Update the context in case the vertices were duplicated. */ - reshape_context->base_verts = base_verts; + reshape_context->base_positions = base_positions; const MLoop *mloop = reshape_context->base_loops; for (int loop_index = 0; loop_index < base_mesh->totloop; ++loop_index) { const MLoop *loop = &mloop[loop_index]; - MVert *vert = &base_verts[loop->v]; GridCoord grid_coord; grid_coord.grid_index = loop_index; @@ -53,7 +52,7 @@ void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *resh float D[3]; mul_v3_m3v3(D, tangent_matrix, grid_element.displacement); - add_v3_v3v3(vert->co, P, D); + add_v3_v3v3(base_positions[loop->v], P, D); } } @@ -69,9 +68,9 @@ static float v3_dist_from_plane(const float v[3], const float center[3], const f void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape_context) { Mesh *base_mesh = reshape_context->base_mesh; - MVert *base_verts = BKE_mesh_verts_for_write(base_mesh); + float(*base_positions)[3] = BKE_mesh_vert_positions_for_write(base_mesh); /* Update the context in case the vertices were duplicated. */ - reshape_context->base_verts = base_verts; + reshape_context->base_positions = base_positions; MeshElemMap *pmap; int *pmap_mem; BKE_mesh_vert_poly_map_create(&pmap, @@ -85,7 +84,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape float(*origco)[3] = MEM_calloc_arrayN( base_mesh->totvert, sizeof(float[3]), "multires apply base origco"); for (int i = 0; i < base_mesh->totvert; i++) { - copy_v3_v3(origco[i], base_verts[i].co); + copy_v3_v3(origco[i], base_positions[i]); } for (int i = 0; i < base_mesh->totvert; i++) { @@ -120,7 +119,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape float(*fake_co)[3]; float no[3]; - /* Set up poly, loops, and coords in order to call BKE_mesh_calc_poly_normal_coords(). */ + /* Set up poly, loops, and coords in order to call BKE_mesh_calc_poly_normal(). */ fake_poly.totloop = p->totloop; fake_poly.loopstart = 0; fake_loops = MEM_malloc_arrayN(p->totloop, sizeof(MLoop), "fake_loops"); @@ -139,7 +138,7 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape } } - BKE_mesh_calc_poly_normal_coords(&fake_poly, fake_loops, (const float(*)[3])fake_co, no); + BKE_mesh_calc_poly_normal(&fake_poly, fake_loops, (const float(*)[3])fake_co, no); MEM_freeN(fake_loops); MEM_freeN(fake_co); @@ -148,10 +147,10 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape normalize_v3(avg_no); /* Push vertex away from the plane. */ - const float dist = v3_dist_from_plane(base_verts[i].co, center, avg_no); + const float dist = v3_dist_from_plane(base_positions[i], center, avg_no); copy_v3_v3(push, avg_no); mul_v3_fl(push, dist); - add_v3_v3(base_verts[i].co, push); + add_v3_v3(base_positions[i], push); } MEM_freeN(origco); diff --git a/source/blender/blenkernel/intern/multires_reshape_subdivide.c b/source/blender/blenkernel/intern/multires_reshape_subdivide.c index effea2467bc..e3cb6f52a41 100644 --- a/source/blender/blenkernel/intern/multires_reshape_subdivide.c +++ b/source/blender/blenkernel/intern/multires_reshape_subdivide.c @@ -28,7 +28,7 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh) { - const MVert *verts = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const MPoly *polys = BKE_mesh_polys(mesh); const MLoop *loops = BKE_mesh_loops(mesh); @@ -37,7 +37,7 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh) for (int p = 0; p < totpoly; p++) { const MPoly *poly = &polys[p]; float poly_center[3]; - BKE_mesh_calc_poly_center(poly, &loops[poly->loopstart], verts, poly_center); + BKE_mesh_calc_poly_center(poly, &loops[poly->loopstart], positions, poly_center); for (int l = 0; l < poly->totloop; l++) { const int loop_index = poly->loopstart + l; @@ -53,9 +53,9 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh) const MLoop *loop_prev = &loops[prev_loop_index]; copy_v3_v3(disps[0], poly_center); - mid_v3_v3v3(disps[1], verts[loop->v].co, verts[loop_next->v].co); - mid_v3_v3v3(disps[2], verts[loop->v].co, verts[loop_prev->v].co); - copy_v3_v3(disps[3], verts[loop->v].co); + mid_v3_v3v3(disps[1], positions[loop->v], positions[loop_next->v]); + mid_v3_v3v3(disps[2], positions[loop->v], positions[loop_prev->v]); + copy_v3_v3(disps[3], positions[loop->v]); } } } diff --git a/source/blender/blenkernel/intern/multires_reshape_util.c b/source/blender/blenkernel/intern/multires_reshape_util.c index 4fc1217158c..1c33fbb6dd8 100644 --- a/source/blender/blenkernel/intern/multires_reshape_util.c +++ b/source/blender/blenkernel/intern/multires_reshape_util.c @@ -152,7 +152,7 @@ bool multires_reshape_context_create_from_base_mesh(MultiresReshapeContext *resh reshape_context->mmd = mmd; reshape_context->base_mesh = base_mesh; - reshape_context->base_verts = BKE_mesh_verts(base_mesh); + reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh); reshape_context->base_edges = BKE_mesh_edges(base_mesh); reshape_context->base_polys = BKE_mesh_polys(base_mesh); reshape_context->base_loops = BKE_mesh_loops(base_mesh); @@ -189,7 +189,7 @@ bool multires_reshape_context_create_from_object(MultiresReshapeContext *reshape reshape_context->mmd = mmd; reshape_context->base_mesh = base_mesh; - reshape_context->base_verts = BKE_mesh_verts(base_mesh); + reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh); reshape_context->base_edges = BKE_mesh_edges(base_mesh); reshape_context->base_polys = BKE_mesh_polys(base_mesh); reshape_context->base_loops = BKE_mesh_loops(base_mesh); @@ -221,7 +221,7 @@ bool multires_reshape_context_create_from_ccg(MultiresReshapeContext *reshape_co context_zero(reshape_context); reshape_context->base_mesh = base_mesh; - reshape_context->base_verts = BKE_mesh_verts(base_mesh); + reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh); reshape_context->base_edges = BKE_mesh_edges(base_mesh); reshape_context->base_polys = BKE_mesh_polys(base_mesh); reshape_context->base_loops = BKE_mesh_loops(base_mesh); @@ -268,7 +268,7 @@ bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape reshape_context->mmd = mmd; reshape_context->base_mesh = base_mesh; - reshape_context->base_verts = BKE_mesh_verts(base_mesh); + reshape_context->base_positions = BKE_mesh_vert_positions(base_mesh); reshape_context->base_edges = BKE_mesh_edges(base_mesh); reshape_context->base_polys = BKE_mesh_polys(base_mesh); reshape_context->base_loops = BKE_mesh_loops(base_mesh); diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 7f04ca9331f..d33f8fe5de7 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -3242,7 +3242,7 @@ static void give_parvert(Object *par, int nr, float vec[3]) BKE_object_get_evaluated_mesh(par); if (me_eval) { - const MVert *verts = BKE_mesh_verts(me_eval); + const Span positions = me_eval->vert_positions(); int count = 0; int numVerts = me_eval->totvert; @@ -3276,14 +3276,14 @@ static void give_parvert(Object *par, int nr, float vec[3]) /* Get the average of all verts with (original index == nr). */ for (int i = 0; i < numVerts; i++) { if (index[i] == nr) { - add_v3_v3(vec, verts[i].co); + add_v3_v3(vec, positions[i]); count++; } } } else { if (nr < numVerts) { - add_v3_v3(vec, verts[nr].co); + add_v3_v3(vec, positions[nr]); count++; } } @@ -3297,7 +3297,7 @@ static void give_parvert(Object *par, int nr, float vec[3]) else { /* use first index if its out of range */ if (me_eval->totvert) { - copy_v3_v3(vec, verts[0].co); + copy_v3_v3(vec, positions[0]); } } } @@ -4182,10 +4182,9 @@ void BKE_object_foreach_display_point(Object *ob, float3 co; if (mesh_eval != nullptr) { - const MVert *verts = BKE_mesh_verts(mesh_eval); - const int totvert = mesh_eval->totvert; - for (int i = 0; i < totvert; i++) { - mul_v3_m4v3(co, obmat, verts[i].co); + const Span positions = mesh_eval->vert_positions(); + for (const int i : positions.index_range()) { + mul_v3_m4v3(co, obmat, positions[i]); func_cb(co, user_data); } } @@ -4810,8 +4809,9 @@ bool BKE_object_shapekey_remove(Main *bmain, Object *ob, KeyBlock *kb) switch (ob->type) { case OB_MESH: { Mesh *mesh = (Mesh *)ob->data; - MutableSpan verts = mesh->verts_for_write(); - BKE_keyblock_convert_to_mesh(key->refkey, verts.data(), mesh->totvert); + MutableSpan positions = mesh->vert_positions_for_write(); + BKE_keyblock_convert_to_mesh( + key->refkey, reinterpret_cast(positions.data()), mesh->totvert); break; } case OB_CURVES_LEGACY: @@ -5310,31 +5310,31 @@ KDTree_3d *BKE_object_as_kdtree(Object *ob, int *r_tot) const int *index; if (me_eval && (index = (const int *)CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX))) { - const Span verts = me->verts(); + const Span positions = me->vert_positions(); /* Tree over-allocates in case where some verts have #ORIGINDEX_NONE. */ tot = 0; - tree = BLI_kdtree_3d_new(verts.size()); + tree = BLI_kdtree_3d_new(positions.size()); /* We don't how many verts from the DM we can use. */ - for (i = 0; i < verts.size(); i++) { + for (i = 0; i < positions.size(); i++) { if (index[i] != ORIGINDEX_NONE) { float co[3]; - mul_v3_m4v3(co, ob->object_to_world, verts[i].co); + mul_v3_m4v3(co, ob->object_to_world, positions[i]); BLI_kdtree_3d_insert(tree, index[i], co); tot++; } } } else { - const Span verts = me->verts(); + const Span positions = me->vert_positions(); - tot = verts.size(); + tot = positions.size(); tree = BLI_kdtree_3d_new(tot); for (i = 0; i < tot; i++) { float co[3]; - mul_v3_m4v3(co, ob->object_to_world, verts[i].co); + mul_v3_m4v3(co, ob->object_to_world, positions[i]); BLI_kdtree_3d_insert(tree, i, co); } } diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index e8a610d568e..2db9c2c31c1 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -553,7 +553,7 @@ struct VertexDupliData_Mesh { VertexDupliData_Params params; int totvert; - const MVert *mvert; + Span vert_positions; const float (*vert_normals)[3]; const float (*orco)[3]; @@ -644,7 +644,6 @@ static void make_child_duplis_verts_from_mesh(const DupliContext *ctx, VertexDupliData_Mesh *vdd = (VertexDupliData_Mesh *)userdata; const bool use_rotation = vdd->params.use_rotation; - const MVert *mvert = vdd->mvert; const int totvert = vdd->totvert; invert_m4_m4(inst_ob->world_to_object, inst_ob->object_to_world); @@ -653,8 +652,13 @@ static void make_child_duplis_verts_from_mesh(const DupliContext *ctx, mul_m4_m4m4(child_imat, inst_ob->world_to_object, ctx->object->object_to_world); for (int i = 0; i < totvert; i++) { - DupliObject *dob = vertex_dupli( - vdd->params.ctx, inst_ob, child_imat, i, mvert[i].co, vdd->vert_normals[i], use_rotation); + DupliObject *dob = vertex_dupli(vdd->params.ctx, + inst_ob, + child_imat, + i, + vdd->vert_positions[i], + vdd->vert_normals[i], + use_rotation); if (vdd->orco) { copy_v3_v3(dob->orco, vdd->orco[i]); } @@ -730,7 +734,7 @@ static void make_duplis_verts(const DupliContext *ctx) VertexDupliData_Mesh vdd{}; vdd.params = vdd_params; vdd.totvert = me_eval->totvert; - vdd.mvert = me_eval->verts().data(); + vdd.vert_positions = me_eval->vert_positions(); vdd.vert_normals = BKE_mesh_vertex_normals_ensure(me_eval); vdd.orco = (const float(*)[3])CustomData_get_layer(&me_eval->vdata, CD_ORCO); @@ -1056,7 +1060,7 @@ struct FaceDupliData_Mesh { int totface; const MPoly *mpoly; const MLoop *mloop; - const MVert *mvert; + Span positions; const float (*orco)[3]; const MLoopUV *mloopuv; }; @@ -1155,14 +1159,14 @@ static DupliObject *face_dupli_from_mesh(const DupliContext *ctx, /* Mesh variables. */ const MPoly *mpoly, const MLoop *mloopstart, - const MVert *mvert) + const Span positions) { const int coords_len = mpoly->totloop; Array coords(coords_len); const MLoop *ml = mloopstart; for (int i = 0; i < coords_len; i++, ml++) { - coords[i] = float3(mvert[ml->v].co); + coords[i] = positions[ml->v]; } return face_dupli(ctx, inst_ob, child_imat, index, use_scale, scale_fac, coords); @@ -1206,7 +1210,6 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx, FaceDupliData_Mesh *fdd = (FaceDupliData_Mesh *)userdata; const MPoly *mpoly = fdd->mpoly, *mp; const MLoop *mloop = fdd->mloop; - const MVert *mvert = fdd->mvert; const float(*orco)[3] = fdd->orco; const MLoopUV *mloopuv = fdd->mloopuv; const int totface = fdd->totface; @@ -1222,8 +1225,15 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx, for (a = 0, mp = mpoly; a < totface; a++, mp++) { const MLoop *loopstart = mloop + mp->loopstart; - DupliObject *dob = face_dupli_from_mesh( - fdd->params.ctx, inst_ob, child_imat, a, use_scale, scale_fac, mp, loopstart, mvert); + DupliObject *dob = face_dupli_from_mesh(fdd->params.ctx, + inst_ob, + child_imat, + a, + use_scale, + scale_fac, + mp, + loopstart, + fdd->positions); const float w = 1.0f / float(mp->totloop); if (orco) { @@ -1312,7 +1322,7 @@ static void make_duplis_faces(const DupliContext *ctx) fdd.totface = me_eval->totpoly; fdd.mpoly = me_eval->polys().data(); fdd.mloop = me_eval->loops().data(); - fdd.mvert = me_eval->verts().data(); + fdd.positions = me_eval->vert_positions(); fdd.mloopuv = (uv_idx != -1) ? (const MLoopUV *)CustomData_get_layer_n( &me_eval->ldata, CD_MLOOPUV, uv_idx) : nullptr; diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 1f7dc7071c2..75d9f0d5b89 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -67,6 +67,10 @@ #include "bmesh.h" +using blender::float3; +using blender::MutableSpan; +using blender::Span; + static void sculpt_attribute_update_refs(Object *ob); static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob, eAttrDomain domain, @@ -77,9 +81,6 @@ static SculptAttribute *sculpt_attribute_ensure_ex(Object *ob, bool flat_array_for_bmesh); static void sculptsession_bmesh_add_layers(Object *ob); -using blender::MutableSpan; -using blender::Span; - static void palette_init_data(ID *id) { Palette *palette = (Palette *)id; @@ -1694,7 +1695,7 @@ static void sculpt_update_object( /* These are assigned to the base mesh in Multires. This is needed because Face Sets operators * and tools use the Face Sets data from the base mesh when Multires is active. */ - ss->mvert = BKE_mesh_verts_for_write(me); + ss->vert_positions = BKE_mesh_vert_positions_for_write(me); ss->mpoly = BKE_mesh_polys(me); ss->mloop = BKE_mesh_loops(me); } @@ -1702,7 +1703,7 @@ static void sculpt_update_object( ss->totvert = me->totvert; ss->totpoly = me->totpoly; ss->totfaces = me->totpoly; - ss->mvert = BKE_mesh_verts_for_write(me); + ss->vert_positions = BKE_mesh_vert_positions_for_write(me); ss->mpoly = BKE_mesh_polys(me); ss->mloop = BKE_mesh_loops(me); ss->multires.active = false; @@ -2178,21 +2179,25 @@ static PBVH *build_pbvh_from_regular_mesh(Object *ob, Mesh *me_eval_deform, bool PBVH *pbvh = BKE_pbvh_new(PBVH_FACES); BKE_pbvh_respect_hide_set(pbvh, respect_hide); - MutableSpan verts = me->verts_for_write(); + MutableSpan positions = me->vert_positions_for_write(); const Span polys = me->polys(); const Span loops = me->loops(); MLoopTri *looptri = static_cast( MEM_malloc_arrayN(looptris_num, sizeof(*looptri), __func__)); - BKE_mesh_recalc_looptri( - loops.data(), polys.data(), verts.data(), me->totloop, me->totpoly, looptri); + BKE_mesh_recalc_looptri(loops.data(), + polys.data(), + reinterpret_cast(positions.data()), + me->totloop, + me->totpoly, + looptri); BKE_pbvh_build_mesh(pbvh, me, polys.data(), loops.data(), - verts.data(), + reinterpret_cast(positions.data()), me->totvert, &me->vdata, &me->ldata, diff --git a/source/blender/blenkernel/intern/particle.cc b/source/blender/blenkernel/intern/particle.cc index 0b1d8606807..5e3b393ce6b 100644 --- a/source/blender/blenkernel/intern/particle.cc +++ b/source/blender/blenkernel/intern/particle.cc @@ -78,6 +78,8 @@ #include "particle_private.h" +using blender::float3; + static void fluid_free_settings(SPHFluidSettings *fluid); static void particle_settings_init(ID *id) @@ -1272,7 +1274,7 @@ typedef struct ParticleInterpolationData { HairKey *hkey[2]; Mesh *mesh; - MVert *mvert[2]; + float3 *vert_positions[2]; int keyed; ParticleKey *kkey[2]; @@ -1432,9 +1434,9 @@ static void init_particle_interpolation(Object *ob, pind->dietime = (key + pa->totkey - 1)->time; if (pind->mesh) { - MVert *verts = BKE_mesh_verts_for_write(pind->mesh); - pind->mvert[0] = &verts[pa->hair_index]; - pind->mvert[1] = pind->mvert[0] + 1; + float3 *positions = pind->mesh->vert_positions_for_write().data(); + pind->vert_positions[0] = &positions[pa->hair_index]; + pind->vert_positions[1] = pind->vert_positions[0] + 1; } } } @@ -1452,9 +1454,9 @@ static void hair_to_particle(ParticleKey *key, HairKey *hkey) key->time = hkey->time; } -static void mvert_to_particle(ParticleKey *key, MVert *mvert, HairKey *hkey) +static void mvert_to_particle(ParticleKey *key, float3 *position, HairKey *hkey) { - copy_v3_v3(key->co, mvert->co); + copy_v3_v3(key->co, *position); key->time = hkey->time; } @@ -1552,7 +1554,7 @@ static void do_particle_interpolation(ParticleSystem *psys, while (pind->hkey[1]->time < real_t) { pind->hkey[1]++; - pind->mvert[1]++; + pind->vert_positions[1]++; } pind->hkey[0] = pind->hkey[1] - 1; @@ -1564,9 +1566,9 @@ static void do_particle_interpolation(ParticleSystem *psys, edit_to_particle(keys + 2, pind->ekey[1]); } else if (pind->mesh) { - pind->mvert[0] = pind->mvert[1] - 1; - mvert_to_particle(keys + 1, pind->mvert[0], pind->hkey[0]); - mvert_to_particle(keys + 2, pind->mvert[1], pind->hkey[1]); + pind->vert_positions[0] = pind->vert_positions[1] - 1; + mvert_to_particle(keys + 1, pind->vert_positions[0], pind->hkey[0]); + mvert_to_particle(keys + 2, pind->vert_positions[1], pind->hkey[1]); } else if (pind->keyed) { memcpy(keys + 1, pind->kkey[0], sizeof(ParticleKey)); @@ -1592,10 +1594,10 @@ static void do_particle_interpolation(ParticleSystem *psys, } else if (pind->mesh) { if (pind->hkey[0] != pa->hair) { - mvert_to_particle(keys, pind->mvert[0] - 1, pind->hkey[0] - 1); + mvert_to_particle(keys, pind->vert_positions[0] - 1, pind->hkey[0] - 1); } else { - mvert_to_particle(keys, pind->mvert[0], pind->hkey[0]); + mvert_to_particle(keys, pind->vert_positions[0], pind->hkey[0]); } } else { @@ -1617,10 +1619,10 @@ static void do_particle_interpolation(ParticleSystem *psys, } else if (pind->mesh) { if (pind->hkey[1] != pa->hair + pa->totkey - 1) { - mvert_to_particle(keys + 3, pind->mvert[1] + 1, pind->hkey[1] + 1); + mvert_to_particle(keys + 3, pind->vert_positions[1] + 1, pind->hkey[1] + 1); } else { - mvert_to_particle(keys + 3, pind->mvert[1], pind->hkey[1]); + mvert_to_particle(keys + 3, pind->vert_positions[1], pind->hkey[1]); } } else { @@ -1698,7 +1700,7 @@ static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCach /************************************************/ void psys_interpolate_face(Mesh *mesh, - const MVert *mvert, + const float (*vert_positions)[3], const float (*vert_normals)[3], MFace *mface, MTFace *tface, @@ -1717,16 +1719,16 @@ void psys_interpolate_face(Mesh *mesh, float tuv[4][2]; const float *o1, *o2, *o3, *o4; - v1 = mvert[mface->v1].co; - v2 = mvert[mface->v2].co; - v3 = mvert[mface->v3].co; + v1 = vert_positions[mface->v1]; + v2 = vert_positions[mface->v2]; + v3 = vert_positions[mface->v3]; copy_v3_v3(n1, vert_normals[mface->v1]); copy_v3_v3(n2, vert_normals[mface->v2]); copy_v3_v3(n3, vert_normals[mface->v3]); if (mface->v4) { - v4 = mvert[mface->v4].co; + v4 = vert_positions[mface->v4]; copy_v3_v3(n4, vert_normals[mface->v4]); interp_v3_v3v3v3v3(vec, v1, v2, v3, v4, w); @@ -2159,8 +2161,8 @@ void psys_particle_on_dm(Mesh *mesh_final, const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh_final); if (from == PART_FROM_VERT) { - const MVert *verts = BKE_mesh_verts(mesh_final); - copy_v3_v3(vec, verts[mapindex].co); + const float(*vert_positions)[3] = BKE_mesh_vert_positions(mesh_final); + copy_v3_v3(vec, vert_positions[mapindex]); if (nor) { copy_v3_v3(nor, vert_normals[mapindex]); @@ -2184,11 +2186,10 @@ void psys_particle_on_dm(Mesh *mesh_final, else { /* PART_FROM_FACE / PART_FROM_VOLUME */ MFace *mface; MTFace *mtface; - MVert *mvert; MFace *mfaces = static_cast(CustomData_get_layer(&mesh_final->fdata, CD_MFACE)); mface = &mfaces[mapindex]; - mvert = BKE_mesh_verts_for_write(mesh_final); + const float(*vert_positions)[3] = BKE_mesh_vert_positions(mesh_final); mtface = static_cast(CustomData_get_layer(&mesh_final->fdata, CD_MTFACE)); if (mtface) { @@ -2197,7 +2198,7 @@ void psys_particle_on_dm(Mesh *mesh_final, if (from == PART_FROM_VOLUME) { psys_interpolate_face(mesh_final, - mvert, + vert_positions, vert_normals, mface, mtface, @@ -2220,7 +2221,7 @@ void psys_particle_on_dm(Mesh *mesh_final, } else { psys_interpolate_face(mesh_final, - mvert, + vert_positions, vert_normals, mface, mtface, @@ -3670,7 +3671,7 @@ static void psys_cache_edit_paths_iter(void *__restrict iter_data_v, BKE_defvert_weight_to_rgb(ca->col, pind.hkey[1]->weight); } else { - /* WARNING: copied from 'do_particle_interpolation' (without 'mvert' array stepping) */ + /* WARNING: copied from 'do_particle_interpolation' (without 'vertex' array stepping) */ float real_t; if (result.time < 0.0f) { real_t = -result.time; @@ -3910,10 +3911,10 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4] } } else { - const MVert *verts = BKE_mesh_verts(mesh); - copy_v3_v3(v[0], verts[mface->v1].co); - copy_v3_v3(v[1], verts[mface->v2].co); - copy_v3_v3(v[2], verts[mface->v3].co); + const float(*vert_positions)[3] = BKE_mesh_vert_positions(mesh); + copy_v3_v3(v[0], vert_positions[mface->v1]); + copy_v3_v3(v[1], vert_positions[mface->v2]); + copy_v3_v3(v[2], vert_positions[mface->v3]); } triatomat(v[0], v[1], v[2], (osface) ? osface->uv : nullptr, mat); diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 0301b83a043..b7e53fac15f 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -98,18 +98,15 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys) { ParticleData *pa = NULL; float min[3], max[3], delta[3], d; - MVert *mv, *mvert = BKE_mesh_verts_for_write(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); int totvert = mesh->totvert, from = psys->part->from; int i, j, k, p, res = psys->part->grid_res, size[3], axis; /* find bounding box of dm */ if (totvert > 0) { - mv = mvert; - copy_v3_v3(min, mv->co); - copy_v3_v3(max, mv->co); - mv++; - for (i = 1; i < totvert; i++, mv++) { - minmax_v3v3_v3(min, max, mv->co); + INIT_MINMAX(min, max); + for (i = 1; i < totvert; i++) { + minmax_v3v3_v3(min, max, positions[i]); } } else { @@ -163,8 +160,8 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys) min[1] -= d / 2.0f; min[2] -= d / 2.0f; - for (i = 0, mv = mvert; i < totvert; i++, mv++) { - sub_v3_v3v3(vec, mv->co, min); + for (i = 0; i < totvert; i++) { + sub_v3_v3v3(vec, positions[i], min); vec[0] /= delta[0]; vec[1] /= delta[1]; vec[2] /= delta[2]; @@ -221,9 +218,9 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys) for (i = 0; i < totface; i++, mface++) { ParticleData *pa1 = NULL, *pa2 = NULL; - copy_v3_v3(v1, mvert[mface->v1].co); - copy_v3_v3(v2, mvert[mface->v2].co); - copy_v3_v3(v3, mvert[mface->v3].co); + copy_v3_v3(v1, positions[mface->v1]); + copy_v3_v3(v2, positions[mface->v2]); + copy_v3_v3(v3, positions[mface->v3]); bool intersects_tri = isect_ray_tri_watertight_v3( co1, &isect_precalc, v1, v2, v3, &lambda, NULL); @@ -232,7 +229,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys) } if (mface->v4 && (!intersects_tri || from == PART_FROM_VOLUME)) { - copy_v3_v3(v4, mvert[mface->v4].co); + copy_v3_v3(v4, positions[mface->v4]); if (isect_ray_tri_watertight_v3(co1, &isect_precalc, v1, v3, v4, &lambda, NULL)) { pa2 = (pa + (int)(lambda * size[a]) * a0mul); @@ -570,14 +567,15 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, { ParticleThreadContext *ctx = thread->ctx; Mesh *mesh = ctx->mesh; - float *v1, *v2, *v3, *v4, nor[3], co[3]; + const float *v1, *v2, *v3, *v4; + float nor[3], co[3]; float cur_d, min_d, randu, randv; int distr = ctx->distr; int i, intersect, tot; int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */ MFace *mface; - MVert *mvert = BKE_mesh_verts_for_write(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); pa->num = i = ctx->index[p]; MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); @@ -614,8 +612,18 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, /* experimental */ tot = mesh->totface; - psys_interpolate_face( - mesh, mvert, BKE_mesh_vertex_normals_ensure(mesh), mface, 0, 0, pa->fuv, co, nor, 0, 0, 0); + psys_interpolate_face(mesh, + positions, + BKE_mesh_vertex_normals_ensure(mesh), + mface, + 0, + 0, + pa->fuv, + co, + nor, + 0, + 0, + 0); normalize_v3(nor); negate_v3(nor); @@ -628,9 +636,9 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, continue; } - v1 = mvert[mface->v1].co; - v2 = mvert[mface->v2].co; - v3 = mvert[mface->v3].co; + v1 = positions[mface->v1]; + v2 = positions[mface->v2]; + v3 = positions[mface->v3]; if (isect_ray_tri_v3(co, nor, v2, v3, v1, &cur_d, NULL)) { if (cur_d < min_d) { @@ -640,7 +648,7 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, } } if (mface->v4) { - v4 = mvert[mface->v4].co; + v4 = positions[mface->v4]; if (isect_ray_tri_v3(co, nor, v4, v1, v3, &cur_d, NULL)) { if (cur_d < min_d) { @@ -993,7 +1001,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, BKE_mesh_orco_ensure(ob, mesh); if (from == PART_FROM_VERT) { - MVert *mv = BKE_mesh_verts_for_write(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const float(*orcodata)[3] = CustomData_get_layer(&mesh->vdata, CD_ORCO); int totvert = mesh->totvert; @@ -1005,7 +1013,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, BKE_mesh_orco_verts_transform(ob->data, &co, 1, 1); } else { - copy_v3_v3(co, mv[p].co); + copy_v3_v3(co, positions[p]); } BLI_kdtree_3d_insert(tree, p, co); } @@ -1040,7 +1048,6 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, /* Calculate weights from face areas */ if ((part->flag & PART_EDISTR || children) && from != PART_FROM_VERT) { - MVert *v1, *v2, *v3, *v4; float totarea = 0.0f, co1[3], co2[3], co3[3], co4[3]; const float(*orcodata)[3]; @@ -1064,16 +1071,12 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, } } else { - MVert *verts = BKE_mesh_verts_for_write(mesh); - v1 = &verts[mf->v1]; - v2 = &verts[mf->v2]; - v3 = &verts[mf->v3]; - copy_v3_v3(co1, v1->co); - copy_v3_v3(co2, v2->co); - copy_v3_v3(co3, v3->co); + const float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); + copy_v3_v3(co1, positions[mf->v1]); + copy_v3_v3(co2, positions[mf->v2]); + copy_v3_v3(co3, positions[mf->v3]); if (mf->v4) { - v4 = &verts[mf->v4]; - copy_v3_v3(co4, v4->co); + copy_v3_v3(co4, positions[mf->v4]); } } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index d97a217a734..25935a590b9 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2779,18 +2779,18 @@ void BKE_psys_collision_neartest_cb(void *userdata, ParticleCollision *col = (ParticleCollision *)userdata; ParticleCollisionElement pce; const MVertTri *vt = &col->md->tri[index]; - MVert *x = col->md->x; - MVert *v = col->md->current_v; + float(*x)[3] = col->md->x; + float(*v)[3] = col->md->current_v; float t = hit->dist / col->original_ray_length; int collision = 0; - pce.x[0] = x[vt->tri[0]].co; - pce.x[1] = x[vt->tri[1]].co; - pce.x[2] = x[vt->tri[2]].co; + pce.x[0] = x[vt->tri[0]]; + pce.x[1] = x[vt->tri[1]]; + pce.x[2] = x[vt->tri[2]]; - pce.v[0] = v[vt->tri[0]].co; - pce.v[1] = v[vt->tri[1]].co; - pce.v[2] = v[vt->tri[2]].co; + pce.v[0] = v[vt->tri[0]]; + pce.v[1] = v[vt->tri[1]]; + pce.v[2] = v[vt->tri[2]]; pce.tot = 3; pce.inside = 0; @@ -3307,7 +3307,6 @@ static void hair_create_input_mesh(ParticleSimulationData *sim, ParticleSystem *psys = sim->psys; ParticleSettings *part = psys->part; Mesh *mesh; - MVert *mvert; MEdge *medge; MDeformVert *dvert; HairKey *key; @@ -3321,7 +3320,7 @@ static void hair_create_input_mesh(ParticleSimulationData *sim, if (!mesh) { *r_mesh = mesh = BKE_mesh_new_nomain(totpoint, totedge, 0, 0, 0); } - mvert = BKE_mesh_verts_for_write(mesh); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); medge = BKE_mesh_edges_for_write(mesh); dvert = BKE_mesh_deform_verts_for_write(mesh); @@ -3345,6 +3344,8 @@ static void hair_create_input_mesh(ParticleSimulationData *sim, psys->clmd->sim_parms->vgroup_mass = 1; + int vert_index = 0; + /* XXX placeholder for more flexible future hair settings */ hair_radius = part->size; @@ -3383,16 +3384,16 @@ static void hair_create_input_mesh(ParticleSimulationData *sim, hair->radius = hair_radius; hair->bending_stiffness = bending_stiffness; - add_v3_v3v3(mvert->co, co, co); - sub_v3_v3(mvert->co, co_next); - mul_m4_v3(hairmat, mvert->co); + add_v3_v3v3(positions[vert_index], co, co); + sub_v3_v3(positions[vert_index], co_next); + mul_m4_v3(hairmat, positions[vert_index]); medge->v1 = pa->hair_index - 1; medge->v2 = pa->hair_index; dvert = hair_set_pinning(dvert, 1.0f); - mvert++; + vert_index++; medge++; } @@ -3404,8 +3405,8 @@ static void hair_create_input_mesh(ParticleSimulationData *sim, hair->radius = hair_radius; hair->bending_stiffness = bending_stiffness; - copy_v3_v3(mvert->co, co); - mul_m4_v3(hairmat, mvert->co); + copy_v3_v3(positions[vert_index], co); + mul_m4_v3(hairmat, positions[vert_index]); if (k) { medge->v1 = pa->hair_index + k - 1; @@ -3420,7 +3421,7 @@ static void hair_create_input_mesh(ParticleSimulationData *sim, dvert = hair_set_pinning(dvert, 1.0f); } - mvert++; + vert_index++; if (k) { medge++; } diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index a6a362b1daf..2a8683ecaaa 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -674,7 +674,7 @@ static void pbvh_draw_args_init(PBVH *pbvh, PBVH_GPU_Args *args, PBVHNode *node) args->grid_hidden = pbvh->grid_hidden; args->face_sets_color_default = pbvh->face_sets_color_default; args->face_sets_color_seed = pbvh->face_sets_color_seed; - args->mvert = pbvh->verts; + args->vert_positions = pbvh->vert_positions; args->mloop = pbvh->mloop; args->mpoly = pbvh->mpoly; args->mlooptri = pbvh->looptri; @@ -811,7 +811,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, Mesh *mesh, const MPoly *mpoly, const MLoop *mloop, - MVert *verts, + float (*vert_positions)[3], int totvert, struct CustomData *vdata, struct CustomData *ldata, @@ -830,7 +830,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, &mesh->pdata, CD_PROP_INT32, "material_index"); pbvh->mloop = mloop; pbvh->looptri = looptri; - pbvh->verts = verts; + pbvh->vert_positions = vert_positions; BKE_mesh_vertex_normals_ensure(mesh); pbvh->vert_normals = BKE_mesh_vertex_normals_for_write(mesh); pbvh->hide_vert = (bool *)CustomData_get_layer_named(&mesh->vdata, CD_PROP_BOOL, ".hide_vert"); @@ -867,7 +867,7 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, BB_reset((BB *)bbc); for (int j = 0; j < sides; j++) { - BB_expand((BB *)bbc, verts[pbvh->mloop[lt->tri[j]].v].co); + BB_expand((BB *)bbc, vert_positions[pbvh->mloop[lt->tri[j]].v]); } BBC_update_centroid(bbc); @@ -1024,10 +1024,10 @@ void BKE_pbvh_free(PBVH *pbvh) } if (pbvh->deformed) { - if (pbvh->verts) { + if (pbvh->vert_positions) { /* if pbvh was deformed, new memory was allocated for verts/faces -- free it */ - MEM_freeN((void *)pbvh->verts); + MEM_freeN((void *)pbvh->vert_positions); } } @@ -1392,7 +1392,7 @@ static void pbvh_update_normals_accum_task_cb(void *__restrict userdata, /* Face normal and mask */ if (lt->poly != mpoly_prev) { const MPoly *mp = &pbvh->mpoly[lt->poly]; - BKE_mesh_calc_poly_normal(mp, &pbvh->mloop[mp->loopstart], pbvh->verts, fn); + BKE_mesh_calc_poly_normal(mp, &pbvh->mloop[mp->loopstart], pbvh->vert_positions, fn); mpoly_prev = lt->poly; } @@ -1803,11 +1803,9 @@ void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flag) static void pbvh_faces_node_visibility_update(PBVH *pbvh, PBVHNode *node) { - MVert *mvert; - const int *vert_indices; int totvert, i; BKE_pbvh_node_num_verts(pbvh, node, NULL, &totvert); - BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert); + const int *vert_indices = BKE_pbvh_node_get_vert_indices(node); if (pbvh->hide_vert == NULL) { BKE_pbvh_node_fully_hidden_set(node, false); @@ -2204,18 +2202,10 @@ int BKE_pbvh_num_faces(const PBVH *pbvh) return 0; } -void BKE_pbvh_node_get_verts(PBVH *pbvh, - PBVHNode *node, - const int **r_vert_indices, - MVert **r_verts) -{ - if (r_vert_indices) { - *r_vert_indices = node->vert_indices; - } +const int *BKE_pbvh_node_get_vert_indices(PBVHNode *node) - if (r_verts) { - *r_verts = pbvh->verts; - } +{ + return node->vert_indices; } void BKE_pbvh_node_num_verts(PBVH *pbvh, PBVHNode *node, int *r_uniquevert, int *r_totvert) @@ -2526,7 +2516,7 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh, int *r_active_face_index, float *r_face_normal) { - const MVert *vert = pbvh->verts; + const float(*positions)[3] = pbvh->vert_positions; const MLoop *mloop = pbvh->mloop; const int *faces = node->prim_indices; int totface = node->totprim; @@ -2550,9 +2540,9 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh, } else { /* intersect with current coordinates */ - co[0] = vert[mloop[lt->tri[0]].v].co; - co[1] = vert[mloop[lt->tri[1]].v].co; - co[2] = vert[mloop[lt->tri[2]].v].co; + co[0] = positions[mloop[lt->tri[0]].v]; + co[1] = positions[mloop[lt->tri[1]].v]; + co[2] = positions[mloop[lt->tri[2]].v]; } if (ray_face_intersection_tri(ray_start, isect_precalc, co[0], co[1], co[2], depth)) { @@ -2836,7 +2826,7 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh, float *depth, float *dist_sq) { - const MVert *vert = pbvh->verts; + const float(*positions)[3] = pbvh->vert_positions; const MLoop *mloop = pbvh->mloop; const int *faces = node->prim_indices; int i, totface = node->totprim; @@ -2864,9 +2854,9 @@ static bool pbvh_faces_node_nearest_to_ray(PBVH *pbvh, /* intersect with current coordinates */ hit |= ray_face_nearest_tri(ray_start, ray_normal, - vert[mloop[lt->tri[0]].v].co, - vert[mloop[lt->tri[1]].v].co, - vert[mloop[lt->tri[2]].v].co, + positions[mloop[lt->tri[0]].v], + positions[mloop[lt->tri[1]].v], + positions[mloop[lt->tri[2]].v], depth, dist_sq); } @@ -3187,15 +3177,9 @@ float (*BKE_pbvh_vert_coords_alloc(PBVH *pbvh))[3] { float(*vertCos)[3] = NULL; - if (pbvh->verts) { - MVert *mvert = pbvh->verts; - - vertCos = MEM_callocN(3 * pbvh->totvert * sizeof(float), "BKE_pbvh_get_vertCoords"); - float *co = (float *)vertCos; - - for (int a = 0; a < pbvh->totvert; a++, mvert++, co += 3) { - copy_v3_v3(co, mvert->co); - } + if (pbvh->vert_positions) { + vertCos = MEM_malloc_arrayN(pbvh->totvert, sizeof(float[3]), __func__); + memcpy(vertCos, pbvh->vert_positions, sizeof(float[3]) * pbvh->totvert); } return vertCos; @@ -3209,12 +3193,12 @@ void BKE_pbvh_vert_coords_apply(PBVH *pbvh, const float (*vertCos)[3], const int } if (!pbvh->deformed) { - if (pbvh->verts) { + if (pbvh->vert_positions) { /* if pbvh is not already deformed, verts/faces points to the */ /* original data and applying new coords to this arrays would lead to */ /* unneeded deformation -- duplicate verts/faces to avoid this */ - pbvh->verts = MEM_dupallocN(pbvh->verts); + pbvh->vert_positions = MEM_dupallocN(pbvh->vert_positions); /* No need to dupalloc pbvh->looptri, this one is 'totally owned' by pbvh, * it's never some mesh data. */ @@ -3222,13 +3206,13 @@ void BKE_pbvh_vert_coords_apply(PBVH *pbvh, const float (*vertCos)[3], const int } } - if (pbvh->verts) { - MVert *mvert = pbvh->verts; + if (pbvh->vert_positions) { + float(*positions)[3] = pbvh->vert_positions; /* copy new verts coords */ - for (int a = 0; a < pbvh->totvert; a++, mvert++) { + for (int a = 0; a < pbvh->totvert; a++) { /* no need for float comparison here (memory is exactly equal or not) */ - if (memcmp(mvert->co, vertCos[a], sizeof(float[3])) != 0) { - copy_v3_v3(mvert->co, vertCos[a]); + if (memcmp(positions[a], vertCos[a], sizeof(float[3])) != 0) { + copy_v3_v3(positions[a], vertCos[a]); BKE_pbvh_vert_tag_update_normal(pbvh, BKE_pbvh_make_vref(a)); } } @@ -3333,15 +3317,13 @@ void BKE_pbvh_node_color_buffer_free(PBVH *pbvh) void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode) { struct CCGElem **grids; - struct MVert *verts; - const int *vert_indices; int *grid_indices; int totgrid, gridsize, uniq_verts, totvert; vi->grid = NULL; vi->no = NULL; vi->fno = NULL; - vi->mvert = NULL; + vi->vert_positions = NULL; vi->vertex.i = 0LL; vi->respect_hide = pbvh->respect_hide; @@ -3352,7 +3334,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, &gridsize, &grids); BKE_pbvh_node_num_verts(pbvh, node, &uniq_verts, &totvert); - BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &verts); + const int *vert_indices = BKE_pbvh_node_get_vert_indices(node); vi->key = pbvh->gridkey; vi->grids = grids; @@ -3367,7 +3349,8 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m vi->totvert = uniq_verts; } vi->vert_indices = vert_indices; - vi->mverts = verts; + vi->vert_positions = pbvh->vert_positions; + vi->is_mesh = pbvh->vert_positions != NULL; if (pbvh->header.type == PBVH_BMESH) { BLI_gsetIterator_init(&vi->bm_unique_verts, node->bm_unique_verts); @@ -3443,10 +3426,10 @@ void BKE_pbvh_parallel_range_settings(TaskParallelSettings *settings, settings->use_threading = use_threading && totnode > 1; } -MVert *BKE_pbvh_get_verts(const PBVH *pbvh) +float (*BKE_pbvh_get_vert_positions(const PBVH *pbvh))[3] { BLI_assert(pbvh->header.type == PBVH_FACES); - return pbvh->verts; + return pbvh->vert_positions; } const float (*BKE_pbvh_get_vert_normals(const PBVH *pbvh))[3] diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index ee728a698dd..d3db65137de 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -15,7 +15,6 @@ extern "C" { struct MLoop; struct MLoopTri; struct MPoly; -struct MVert; /* Axis-aligned bounding box */ typedef struct { @@ -56,7 +55,7 @@ struct PBVHNode { int *prim_indices; unsigned int totprim; /* Number of primitives inside prim_indices. */ - /* Array of indices into the mesh's MVert array. Contains the + /* Array of indices into the mesh's vertex array. Contains the * indices of all vertices used by faces that are within this * node's bounding box. * @@ -158,7 +157,7 @@ struct PBVH { /* NOTE: Normals are not `const` because they can be updated for drawing by sculpt code. */ float (*vert_normals)[3]; bool *hide_vert; - struct MVert *verts; + float (*vert_positions)[3]; const struct MPoly *mpoly; bool *hide_poly; /** Material indices. Only valid for polygon meshes. */ diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 5e91b23bce3..6f9abd4c48d 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -359,12 +359,12 @@ static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob, { rbCollisionShape *shape = NULL; Mesh *mesh = NULL; - MVert *mvert = NULL; + float(*positions)[3] = NULL; int totvert = 0; if (ob->type == OB_MESH && ob->data) { mesh = rigidbody_get_mesh(ob); - mvert = (mesh) ? BKE_mesh_verts_for_write(mesh) : NULL; + positions = (mesh) ? BKE_mesh_vert_positions_for_write(mesh) : NULL; totvert = (mesh) ? mesh->totvert : 0; } else { @@ -372,7 +372,8 @@ static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob, } if (totvert) { - shape = RB_shape_new_convex_hull((float *)mvert, sizeof(MVert), totvert, margin, can_embed); + shape = RB_shape_new_convex_hull( + (float *)positions, sizeof(float[3]), totvert, margin, can_embed); } else { CLOG_ERROR(&LOG, "no vertices to define Convex Hull collision shape with"); @@ -401,7 +402,7 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob) return NULL; } - const MVert *mvert = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); totvert = mesh->totvert; looptri = BKE_mesh_runtime_looptri_ensure(mesh); tottri = BKE_mesh_runtime_looptri_len(mesh); @@ -419,12 +420,12 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob) /* init mesh data for collision shape */ mdata = RB_trimesh_data_new(tottri, totvert); - RB_trimesh_add_vertices(mdata, (float *)mvert, totvert, sizeof(MVert)); + RB_trimesh_add_vertices(mdata, (float *)positions, totvert, sizeof(float[3])); /* loop over all faces, adding them as triangles to the collision shape * (so for some faces, more than triangle will get added) */ - if (mvert && looptri) { + if (positions && looptri) { for (i = 0; i < tottri; i++) { /* add first triangle - verts 1,2,3 */ const MLoopTri *lt = &looptri[i]; @@ -676,14 +677,14 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol) return; } - const MVert *mvert = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); totvert = mesh->totvert; lt = BKE_mesh_runtime_looptri_ensure(mesh); tottri = BKE_mesh_runtime_looptri_len(mesh); const MLoop *mloop = BKE_mesh_loops(mesh); if (totvert > 0 && tottri > 0) { - BKE_mesh_calc_volume(mvert, totvert, lt, tottri, mloop, &volume, NULL); + BKE_mesh_calc_volume(positions, totvert, lt, tottri, mloop, &volume, NULL); const float volume_scale = mat4_to_volume_scale(ob->object_to_world); volume *= fabsf(volume_scale); } @@ -750,14 +751,14 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3]) return; } - const MVert *mvert = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); totvert = mesh->totvert; looptri = BKE_mesh_runtime_looptri_ensure(mesh); tottri = BKE_mesh_runtime_looptri_len(mesh); const MLoop *mloop = BKE_mesh_loops(mesh); if (totvert > 0 && tottri > 0) { - BKE_mesh_calc_volume(mvert, totvert, looptri, tottri, mloop, NULL, r_center); + BKE_mesh_calc_volume(positions, totvert, looptri, tottri, mloop, NULL, r_center); } } break; @@ -1673,14 +1674,14 @@ static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Object *ob, RigidBodyO if (rbo->shape == RB_SHAPE_TRIMESH && rbo->flag & RBO_FLAG_USE_DEFORM) { Mesh *mesh = ob->runtime.mesh_deform_eval; if (mesh) { - MVert *mvert = BKE_mesh_verts_for_write(mesh); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); int totvert = mesh->totvert; const BoundBox *bb = BKE_object_boundbox_get(ob); RB_shape_trimesh_update(rbo->shared->physics_shape, - (float *)mvert, + (float *)positions, totvert, - sizeof(MVert), + sizeof(float[3]), bb->vec[0], bb->vec[6]); } diff --git a/source/blender/blenkernel/intern/shrinkwrap.cc b/source/blender/blenkernel/intern/shrinkwrap.cc index d196f044c58..1a0b33ca2b1 100644 --- a/source/blender/blenkernel/intern/shrinkwrap.cc +++ b/source/blender/blenkernel/intern/shrinkwrap.cc @@ -59,7 +59,7 @@ struct ShrinkwrapCalcData { Object *ob; /* object we are applying shrinkwrap to */ - MVert *vert; /* Array of verts being projected. */ + float (*vert_positions)[3]; /* Array of verts being projected. */ const float (*vert_normals)[3]; /* Vertices being shrink-wrapped. */ float (*vertexCos)[3]; @@ -188,7 +188,7 @@ static void merge_vert_dir(ShrinkwrapBoundaryVertData *vdata, static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh) { - const MVert *mvert = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const MEdge *medge = BKE_mesh_edges(mesh); const MLoop *mloop = BKE_mesh_loops(mesh); @@ -285,7 +285,7 @@ static ShrinkwrapBoundaryData *shrinkwrap_build_boundary_data(Mesh *mesh) const MEdge *edge = &medge[i]; float dir[3]; - sub_v3_v3v3(dir, mvert[edge->v2].co, mvert[edge->v1].co); + sub_v3_v3v3(dir, positions[edge->v2], positions[edge->v1]); normalize_v3(dir); merge_vert_dir(boundary_verts, vert_status, vert_boundary_id[edge->v1], dir, 1); @@ -355,8 +355,8 @@ static void shrinkwrap_calc_nearest_vertex_cb_ex(void *__restrict userdata, } /* Convert the vertex to tree coordinates */ - if (calc->vert) { - copy_v3_v3(tmp_co, calc->vert[i].co); + if (calc->vert_positions) { + copy_v3_v3(tmp_co, calc->vert_positions[i]); } else { copy_v3_v3(tmp_co, co); @@ -517,12 +517,13 @@ static void shrinkwrap_calc_normal_projection_cb_ex(void *__restrict userdata, return; } - if (calc->vert != nullptr && calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) { - /* calc->vert contains verts from evaluated mesh. */ + if (calc->vert_positions != nullptr && + calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) { + /* calc->vert_positions contains verts from evaluated mesh. */ /* These coordinates are deformed by vertexCos only for normal projection * (to get correct normals) for other cases calc->verts contains undeformed coordinates and * vertexCos should be used */ - copy_v3_v3(tmp_co, calc->vert[i].co); + copy_v3_v3(tmp_co, calc->vert_positions[i]); copy_v3_v3(tmp_no, calc->vert_normals[i]); } else { @@ -638,7 +639,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc) /* Prepare data to retrieve the direction in which we should project each vertex */ if (calc->smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL) { - if (calc->vert == nullptr) { + if (calc->vert_positions == nullptr) { return; } } @@ -934,7 +935,7 @@ static void target_project_edge(const ShrinkwrapTreeData *tree, { const BVHTreeFromMesh *data = &tree->treeData; const MEdge *edge = &data->edge[eidx]; - const float *vedge_co[2] = {data->vert[edge->v1].co, data->vert[edge->v2].co}; + const float *vedge_co[2] = {data->vert_positions[edge->v1], data->vert_positions[edge->v2]}; #ifdef TRACE_TARGET_PROJECT printf("EDGE %d (%.3f,%.3f,%.3f) (%.3f,%.3f,%.3f)\n", @@ -1012,9 +1013,9 @@ static void mesh_looptri_target_project(void *userdata, const MLoopTri *lt = &data->looptri[index]; const MLoop *loop[3] = { &data->loop[lt->tri[0]], &data->loop[lt->tri[1]], &data->loop[lt->tri[2]]}; - const MVert *vtri[3] = { - &data->vert[loop[0]->v], &data->vert[loop[1]->v], &data->vert[loop[2]->v]}; - const float *vtri_co[3] = {vtri[0]->co, vtri[1]->co, vtri[2]->co}; + const float *vtri_co[3] = {data->vert_positions[loop[0]->v], + data->vert_positions[loop[1]->v], + data->vert_positions[loop[2]->v]}; float raw_hit_co[3], hit_co[3], hit_no[3], dist_sq, vtri_no[3][3]; /* First find the closest point and bail out if it's worse than the current solution. */ @@ -1116,8 +1117,8 @@ static void shrinkwrap_calc_nearest_surface_point_cb_ex(void *__restrict userdat } /* Convert the vertex to tree coordinates */ - if (calc->vert) { - copy_v3_v3(tmp_co, calc->vert[i].co); + if (calc->vert_positions) { + copy_v3_v3(tmp_co, calc->vert_positions[i]); } else { copy_v3_v3(tmp_co, co); @@ -1202,9 +1203,9 @@ void BKE_shrinkwrap_compute_smooth_normal(const ShrinkwrapTreeData *tree, } interp_weights_tri_v3(w, - treeData->vert[vert_indices[0]].co, - treeData->vert[vert_indices[1]].co, - treeData->vert[vert_indices[2]].co, + treeData->vert_positions[vert_indices[0]], + treeData->vert_positions[vert_indices[1]], + treeData->vert_positions[vert_indices[2]], tmp_co); /* Interpolate using weights. */ @@ -1405,8 +1406,8 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, calc.aux_target = DEG_get_evaluated_object(ctx->depsgraph, smd->auxTarget); if (mesh != nullptr && smd->shrinkType == MOD_SHRINKWRAP_PROJECT) { - /* Setup arrays to get vertices position, normals and deform weights. */ - calc.vert = BKE_mesh_verts_for_write(mesh); + /* Setup arrays to get vertexs positions, normals and deform weights */ + calc.vert_positions = BKE_mesh_vert_positions_for_write(mesh); calc.vert_normals = BKE_mesh_vertex_normals_ensure(mesh); /* Using vertices positions/normals as if a subsurface was applied */ @@ -1426,11 +1427,12 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, (ob->mode & OB_MODE_EDIT) ? SUBSURF_IN_EDIT_MODE : SubsurfFlags(0)); if (ss_mesh) { - calc.vert = static_cast(ss_mesh->getVertDataArray(ss_mesh, CD_MVERT)); - if (calc.vert) { + calc.vert_positions = reinterpret_cast(ss_mesh->getVertArray(ss_mesh)); + if (calc.vert_positions) { /* TRICKY: this code assumes subsurface will have the transformed original vertices * in their original order at the end of the vert array. */ - calc.vert = calc.vert + ss_mesh->getNumVerts(ss_mesh) - dm->getNumVerts(dm); + calc.vert_positions = calc.vert_positions + ss_mesh->getNumVerts(ss_mesh) - + dm->getNumVerts(dm); } } @@ -1571,7 +1573,7 @@ void BKE_shrinkwrap_remesh_target_project(Mesh *src_me, Mesh *target_me, Object calc.vgroup = -1; calc.target = target_me; calc.keepDist = ssmd.keepDist; - calc.vert = BKE_mesh_verts_for_write(src_me); + calc.vert_positions = BKE_mesh_vert_positions_for_write(src_me); BLI_SPACE_TRANSFORM_SETUP(&calc.local2target, ob_target, ob_target); ShrinkwrapTreeData tree; diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 0a6cb1a8556..457b8de4592 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -255,8 +255,8 @@ typedef struct ccdf_minmax { typedef struct ccd_Mesh { int mvert_num, tri_num; - const MVert *mvert; - const MVert *mprevvert; + const float (*vert_positions)[3]; + const float (*vert_positions_prev)[3]; const MVertTri *tri; int safety; ccdf_minmax *mima; @@ -290,20 +290,20 @@ static ccd_Mesh *ccd_mesh_make(Object *ob) pccd_M->safety = CCD_SAFETY; pccd_M->bbmin[0] = pccd_M->bbmin[1] = pccd_M->bbmin[2] = 1e30f; pccd_M->bbmax[0] = pccd_M->bbmax[1] = pccd_M->bbmax[2] = -1e30f; - pccd_M->mprevvert = NULL; + pccd_M->vert_positions_prev = NULL; /* Blow it up with force-field ranges. */ hull = max_ff(ob->pd->pdef_sbift, ob->pd->pdef_sboft); /* Allocate and copy verts. */ - pccd_M->mvert = MEM_dupallocN(cmd->xnew); + pccd_M->vert_positions = MEM_dupallocN(cmd->xnew); /* note that xnew coords are already in global space, */ /* determine the ortho BB */ for (i = 0; i < pccd_M->mvert_num; i++) { const float *v; /* evaluate limits */ - v = pccd_M->mvert[i].co; + v = pccd_M->vert_positions[i]; pccd_M->bbmin[0] = min_ff(pccd_M->bbmin[0], v[0] - hull); pccd_M->bbmin[1] = min_ff(pccd_M->bbmin[1], v[1] - hull); pccd_M->bbmin[2] = min_ff(pccd_M->bbmin[2], v[2] - hull); @@ -325,7 +325,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob) mima->minx = mima->miny = mima->minz = 1e30f; mima->maxx = mima->maxy = mima->maxz = -1e30f; - v = pccd_M->mvert[vt->tri[0]].co; + v = pccd_M->vert_positions[vt->tri[0]]; mima->minx = min_ff(mima->minx, v[0] - hull); mima->miny = min_ff(mima->miny, v[1] - hull); mima->minz = min_ff(mima->minz, v[2] - hull); @@ -333,7 +333,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob) mima->maxy = max_ff(mima->maxy, v[1] + hull); mima->maxz = max_ff(mima->maxz, v[2] + hull); - v = pccd_M->mvert[vt->tri[1]].co; + v = pccd_M->vert_positions[vt->tri[1]]; mima->minx = min_ff(mima->minx, v[0] - hull); mima->miny = min_ff(mima->miny, v[1] - hull); mima->minz = min_ff(mima->minz, v[2] - hull); @@ -341,7 +341,7 @@ static ccd_Mesh *ccd_mesh_make(Object *ob) mima->maxy = max_ff(mima->maxy, v[1] + hull); mima->maxz = max_ff(mima->maxz, v[2] + hull); - v = pccd_M->mvert[vt->tri[2]].co; + v = pccd_M->vert_positions[vt->tri[2]]; mima->minx = min_ff(mima->minx, v[0] - hull); mima->miny = min_ff(mima->miny, v[1] - hull); mima->minz = min_ff(mima->minz, v[2] - hull); @@ -381,19 +381,19 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M) hull = max_ff(ob->pd->pdef_sbift, ob->pd->pdef_sboft); /* rotate current to previous */ - if (pccd_M->mprevvert) { - MEM_freeN((void *)pccd_M->mprevvert); + if (pccd_M->vert_positions_prev) { + MEM_freeN((void *)pccd_M->vert_positions_prev); } - pccd_M->mprevvert = pccd_M->mvert; + pccd_M->vert_positions_prev = pccd_M->vert_positions; /* Allocate and copy verts. */ - pccd_M->mvert = MEM_dupallocN(cmd->xnew); + pccd_M->vert_positions = MEM_dupallocN(cmd->xnew); /* note that xnew coords are already in global space, */ /* determine the ortho BB */ for (i = 0; i < pccd_M->mvert_num; i++) { const float *v; /* evaluate limits */ - v = pccd_M->mvert[i].co; + v = pccd_M->vert_positions[i]; pccd_M->bbmin[0] = min_ff(pccd_M->bbmin[0], v[0] - hull); pccd_M->bbmin[1] = min_ff(pccd_M->bbmin[1], v[1] - hull); pccd_M->bbmin[2] = min_ff(pccd_M->bbmin[2], v[2] - hull); @@ -403,7 +403,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M) pccd_M->bbmax[2] = max_ff(pccd_M->bbmax[2], v[2] + hull); /* evaluate limits */ - v = pccd_M->mprevvert[i].co; + v = pccd_M->vert_positions_prev[i]; pccd_M->bbmin[0] = min_ff(pccd_M->bbmin[0], v[0] - hull); pccd_M->bbmin[1] = min_ff(pccd_M->bbmin[1], v[1] - hull); pccd_M->bbmin[2] = min_ff(pccd_M->bbmin[2], v[2] - hull); @@ -420,8 +420,8 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M) mima->minx = mima->miny = mima->minz = 1e30f; mima->maxx = mima->maxy = mima->maxz = -1e30f; - /* mvert */ - v = pccd_M->mvert[vt->tri[0]].co; + /* vert_positions */ + v = pccd_M->vert_positions[vt->tri[0]]; mima->minx = min_ff(mima->minx, v[0] - hull); mima->miny = min_ff(mima->miny, v[1] - hull); mima->minz = min_ff(mima->minz, v[2] - hull); @@ -429,7 +429,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M) mima->maxy = max_ff(mima->maxy, v[1] + hull); mima->maxz = max_ff(mima->maxz, v[2] + hull); - v = pccd_M->mvert[vt->tri[1]].co; + v = pccd_M->vert_positions[vt->tri[1]]; mima->minx = min_ff(mima->minx, v[0] - hull); mima->miny = min_ff(mima->miny, v[1] - hull); mima->minz = min_ff(mima->minz, v[2] - hull); @@ -437,7 +437,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M) mima->maxy = max_ff(mima->maxy, v[1] + hull); mima->maxz = max_ff(mima->maxz, v[2] + hull); - v = pccd_M->mvert[vt->tri[2]].co; + v = pccd_M->vert_positions[vt->tri[2]]; mima->minx = min_ff(mima->minx, v[0] - hull); mima->miny = min_ff(mima->miny, v[1] - hull); mima->minz = min_ff(mima->minz, v[2] - hull); @@ -445,8 +445,8 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M) mima->maxy = max_ff(mima->maxy, v[1] + hull); mima->maxz = max_ff(mima->maxz, v[2] + hull); - /* mprevvert */ - v = pccd_M->mprevvert[vt->tri[0]].co; + /* vert_positions_prev */ + v = pccd_M->vert_positions_prev[vt->tri[0]]; mima->minx = min_ff(mima->minx, v[0] - hull); mima->miny = min_ff(mima->miny, v[1] - hull); mima->minz = min_ff(mima->minz, v[2] - hull); @@ -454,7 +454,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M) mima->maxy = max_ff(mima->maxy, v[1] + hull); mima->maxz = max_ff(mima->maxz, v[2] + hull); - v = pccd_M->mprevvert[vt->tri[1]].co; + v = pccd_M->vert_positions_prev[vt->tri[1]]; mima->minx = min_ff(mima->minx, v[0] - hull); mima->miny = min_ff(mima->miny, v[1] - hull); mima->minz = min_ff(mima->minz, v[2] - hull); @@ -462,7 +462,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M) mima->maxy = max_ff(mima->maxy, v[1] + hull); mima->maxz = max_ff(mima->maxz, v[2] + hull); - v = pccd_M->mprevvert[vt->tri[2]].co; + v = pccd_M->vert_positions_prev[vt->tri[2]]; mima->minx = min_ff(mima->minx, v[0] - hull); mima->miny = min_ff(mima->miny, v[1] - hull); mima->minz = min_ff(mima->minz, v[2] - hull); @@ -476,10 +476,10 @@ static void ccd_mesh_free(ccd_Mesh *ccdm) { /* Make sure we're not nuking objects we don't know. */ if (ccdm && (ccdm->safety == CCD_SAFETY)) { - MEM_freeN((void *)ccdm->mvert); + MEM_freeN((void *)ccdm->vert_positions); MEM_freeN((void *)ccdm->tri); - if (ccdm->mprevvert) { - MEM_freeN((void *)ccdm->mprevvert); + if (ccdm->vert_positions_prev) { + MEM_freeN((void *)ccdm->vert_positions_prev); } MEM_freeN(ccdm->mima); MEM_freeN(ccdm); @@ -1068,12 +1068,12 @@ static int sb_detect_face_pointCached(const float face_v1[3], { /* only with deflecting set */ if (ob->pd && ob->pd->deflect) { - const MVert *mvert = NULL; - const MVert *mprevvert = NULL; + const float(*vert_positions)[3] = NULL; + const float(*vert_positions_prev)[3] = NULL; if (ccdm) { - mvert = ccdm->mvert; + vert_positions = ccdm->vert_positions; a = ccdm->mvert_num; - mprevvert = ccdm->mprevvert; + vert_positions_prev = ccdm->vert_positions_prev; outerfacethickness = ob->pd->pdef_sboft; if ((aabbmax[0] < ccdm->bbmin[0]) || (aabbmax[1] < ccdm->bbmin[1]) || (aabbmax[2] < ccdm->bbmin[2]) || (aabbmin[0] > ccdm->bbmax[0]) || @@ -1091,12 +1091,12 @@ static int sb_detect_face_pointCached(const float face_v1[3], } /* Use mesh. */ - if (mvert) { + if (vert_positions) { while (a) { - copy_v3_v3(nv1, mvert[a - 1].co); - if (mprevvert) { + copy_v3_v3(nv1, vert_positions[a - 1]); + if (vert_positions_prev) { mul_v3_fl(nv1, time); - madd_v3_v3fl(nv1, mprevvert[a - 1].co, 1.0f - time); + madd_v3_v3fl(nv1, vert_positions_prev[a - 1], 1.0f - time); } /* Origin to face_v2. */ sub_v3_v3(nv1, face_v2); @@ -1120,7 +1120,7 @@ static int sb_detect_face_pointCached(const float face_v1[3], } a--; } /* while (a) */ - } /* if (mvert) */ + } /* if (vert_positions) */ } /* if (ob->pd && ob->pd->deflect) */ BLI_ghashIterator_step(ihash); } @@ -1160,15 +1160,15 @@ static int sb_detect_face_collisionCached(const float face_v1[3], { /* only with deflecting set */ if (ob->pd && ob->pd->deflect) { - const MVert *mvert = NULL; - const MVert *mprevvert = NULL; + const float(*vert_positions)[3] = NULL; + const float(*vert_positions_prev)[3] = NULL; const MVertTri *vt = NULL; const ccdf_minmax *mima = NULL; if (ccdm) { - mvert = ccdm->mvert; + vert_positions = ccdm->vert_positions; vt = ccdm->tri; - mprevvert = ccdm->mprevvert; + vert_positions_prev = ccdm->vert_positions_prev; mima = ccdm->mima; a = ccdm->tri_num; @@ -1197,21 +1197,21 @@ static int sb_detect_face_collisionCached(const float face_v1[3], continue; } - if (mvert) { + if (vert_positions) { - copy_v3_v3(nv1, mvert[vt->tri[0]].co); - copy_v3_v3(nv2, mvert[vt->tri[1]].co); - copy_v3_v3(nv3, mvert[vt->tri[2]].co); + copy_v3_v3(nv1, vert_positions[vt->tri[0]]); + copy_v3_v3(nv2, vert_positions[vt->tri[1]]); + copy_v3_v3(nv3, vert_positions[vt->tri[2]]); - if (mprevvert) { + if (vert_positions_prev) { mul_v3_fl(nv1, time); - madd_v3_v3fl(nv1, mprevvert[vt->tri[0]].co, 1.0f - time); + madd_v3_v3fl(nv1, vert_positions_prev[vt->tri[0]], 1.0f - time); mul_v3_fl(nv2, time); - madd_v3_v3fl(nv2, mprevvert[vt->tri[1]].co, 1.0f - time); + madd_v3_v3fl(nv2, vert_positions_prev[vt->tri[1]], 1.0f - time); mul_v3_fl(nv3, time); - madd_v3_v3fl(nv3, mprevvert[vt->tri[2]].co, 1.0f - time); + madd_v3_v3fl(nv3, vert_positions_prev[vt->tri[2]], 1.0f - time); } } @@ -1336,14 +1336,14 @@ static int sb_detect_edge_collisionCached(const float edge_v1[3], { /* only with deflecting set */ if (ob->pd && ob->pd->deflect) { - const MVert *mvert = NULL; - const MVert *mprevvert = NULL; + const float(*vert_positions)[3] = NULL; + const float(*vert_positions_prev)[3] = NULL; const MVertTri *vt = NULL; const ccdf_minmax *mima = NULL; if (ccdm) { - mvert = ccdm->mvert; - mprevvert = ccdm->mprevvert; + vert_positions = ccdm->vert_positions; + vert_positions_prev = ccdm->vert_positions_prev; vt = ccdm->tri; mima = ccdm->mima; a = ccdm->tri_num; @@ -1373,21 +1373,21 @@ static int sb_detect_edge_collisionCached(const float edge_v1[3], continue; } - if (mvert) { + if (vert_positions) { - copy_v3_v3(nv1, mvert[vt->tri[0]].co); - copy_v3_v3(nv2, mvert[vt->tri[1]].co); - copy_v3_v3(nv3, mvert[vt->tri[2]].co); + copy_v3_v3(nv1, vert_positions[vt->tri[0]]); + copy_v3_v3(nv2, vert_positions[vt->tri[1]]); + copy_v3_v3(nv3, vert_positions[vt->tri[2]]); - if (mprevvert) { + if (vert_positions_prev) { mul_v3_fl(nv1, time); - madd_v3_v3fl(nv1, mprevvert[vt->tri[0]].co, 1.0f - time); + madd_v3_v3fl(nv1, vert_positions_prev[vt->tri[0]], 1.0f - time); mul_v3_fl(nv2, time); - madd_v3_v3fl(nv2, mprevvert[vt->tri[1]].co, 1.0f - time); + madd_v3_v3fl(nv2, vert_positions_prev[vt->tri[1]], 1.0f - time); mul_v3_fl(nv3, time); - madd_v3_v3fl(nv3, mprevvert[vt->tri[2]].co, 1.0f - time); + madd_v3_v3fl(nv3, vert_positions_prev[vt->tri[2]], 1.0f - time); } } @@ -1635,14 +1635,14 @@ static int sb_detect_vertex_collisionCached(float opco[3], { /* only with deflecting set */ if (ob->pd && ob->pd->deflect) { - const MVert *mvert = NULL; - const MVert *mprevvert = NULL; + const float(*vert_positions)[3] = NULL; + const float(*vert_positions_prev)[3] = NULL; const MVertTri *vt = NULL; const ccdf_minmax *mima = NULL; if (ccdm) { - mvert = ccdm->mvert; - mprevvert = ccdm->mprevvert; + vert_positions = ccdm->vert_positions; + vert_positions_prev = ccdm->vert_positions_prev; vt = ccdm->tri; mima = ccdm->mima; a = ccdm->tri_num; @@ -1686,30 +1686,30 @@ static int sb_detect_vertex_collisionCached(float opco[3], continue; } - if (mvert) { + if (vert_positions) { - copy_v3_v3(nv1, mvert[vt->tri[0]].co); - copy_v3_v3(nv2, mvert[vt->tri[1]].co); - copy_v3_v3(nv3, mvert[vt->tri[2]].co); + copy_v3_v3(nv1, vert_positions[vt->tri[0]]); + copy_v3_v3(nv2, vert_positions[vt->tri[1]]); + copy_v3_v3(nv3, vert_positions[vt->tri[2]]); - if (mprevvert) { + if (vert_positions_prev) { /* Grab the average speed of the collider vertices before we spoil nvX * humm could be done once a SB steps but then we' need to store that too * since the AABB reduced probability to get here drastically * it might be a nice tradeoff CPU <--> memory. */ - sub_v3_v3v3(vv1, nv1, mprevvert[vt->tri[0]].co); - sub_v3_v3v3(vv2, nv2, mprevvert[vt->tri[1]].co); - sub_v3_v3v3(vv3, nv3, mprevvert[vt->tri[2]].co); + sub_v3_v3v3(vv1, nv1, vert_positions_prev[vt->tri[0]]); + sub_v3_v3v3(vv2, nv2, vert_positions_prev[vt->tri[1]]); + sub_v3_v3v3(vv3, nv3, vert_positions_prev[vt->tri[2]]); mul_v3_fl(nv1, time); - madd_v3_v3fl(nv1, mprevvert[vt->tri[0]].co, 1.0f - time); + madd_v3_v3fl(nv1, vert_positions_prev[vt->tri[0]], 1.0f - time); mul_v3_fl(nv2, time); - madd_v3_v3fl(nv2, mprevvert[vt->tri[1]].co, 1.0f - time); + madd_v3_v3fl(nv2, vert_positions_prev[vt->tri[1]], 1.0f - time); mul_v3_fl(nv3, time); - madd_v3_v3fl(nv3, mprevvert[vt->tri[2]].co, 1.0f - time); + madd_v3_v3fl(nv3, vert_positions_prev[vt->tri[2]], 1.0f - time); } } @@ -1743,7 +1743,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], deflected = 2; } } - if ((mprevvert) && (*damp > 0.0f)) { + if ((vert_positions_prev) && (*damp > 0.0f)) { choose_winner(ve, opco, nv1, nv2, nv3, vv1, vv2, vv3); add_v3_v3(avel, ve); cavel++; @@ -2632,18 +2632,18 @@ static void springs_from_mesh(Object *ob) BodyPoint *bp; int a; float scale = 1.0f; - const MVert *verts = BKE_mesh_verts(me); + const float(*vert_positions)[3] = BKE_mesh_vert_positions(me); sb = ob->soft; if (me && sb) { /* using bp->origS as a container for spring calculations here * will be overwritten sbObjectStep() to receive - * actual modifier stack positions + * actual modifier stack vert_positions */ if (me->totvert) { bp = ob->soft->bpoint; for (a = 0; a < me->totvert; a++, bp++) { - copy_v3_v3(bp->origS, verts[a].co); + copy_v3_v3(bp->origS, vert_positions[a]); mul_m4_v3(ob->object_to_world, bp->origS); } } @@ -2755,7 +2755,7 @@ static void mesh_faces_to_scratch(Object *ob) MLoopTri *looptri, *lt; BodyFace *bodyface; int a; - const MVert *verts = BKE_mesh_verts(me); + const float(*vert_positions)[3] = BKE_mesh_vert_positions(me); const MPoly *polys = BKE_mesh_polys(me); const MLoop *loops = BKE_mesh_loops(me); @@ -2763,7 +2763,7 @@ static void mesh_faces_to_scratch(Object *ob) sb->scratch->totface = poly_to_tri_count(me->totpoly, me->totloop); looptri = lt = MEM_mallocN(sizeof(*looptri) * sb->scratch->totface, __func__); - BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri); + BKE_mesh_recalc_looptri(loops, polys, vert_positions, me->totloop, me->totpoly, looptri); bodyface = sb->scratch->bodyface = MEM_mallocN(sizeof(BodyFace) * sb->scratch->totface, "SB_body_Faces"); @@ -3564,7 +3564,7 @@ void sbObjectStep(struct Depsgraph *depsgraph, if (framenr == startframe) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); - /* first frame, no simulation to do, just set the positions */ + /* first frame, no simulation to do, just set the vert_positions */ softbody_update_positions(ob, sb, vertexCos, numVerts); BKE_ptcache_validate(cache, framenr); diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c index aabed2cea28..09d01a5b50f 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c @@ -34,7 +34,7 @@ typedef struct ConverterStorage { SubdivSettings settings; const Mesh *mesh; - const MVert *verts; + const float (*vert_positions)[3]; const MEdge *edges; const MPoly *polys; const MLoop *loops; @@ -395,7 +395,7 @@ static void init_user_data(OpenSubdiv_Converter *converter, ConverterStorage *user_data = MEM_mallocN(sizeof(ConverterStorage), __func__); user_data->settings = *settings; user_data->mesh = mesh; - user_data->verts = BKE_mesh_verts(mesh); + user_data->vert_positions = BKE_mesh_vert_positions(mesh); user_data->edges = BKE_mesh_edges(mesh); user_data->polys = BKE_mesh_polys(mesh); user_data->loops = BKE_mesh_loops(mesh); diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c index e6f24aa6ff8..97ee072c296 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.c +++ b/source/blender/blenkernel/intern/subdiv_eval.c @@ -81,7 +81,7 @@ static void set_coarse_positions(Subdiv *subdiv, const Mesh *mesh, const float (*coarse_vertex_cos)[3]) { - const MVert *mvert = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const MPoly *mpoly = BKE_mesh_polys(mesh); const MLoop *mloop = BKE_mesh_loops(mesh); /* Mark vertices which needs new coordinates. */ @@ -109,8 +109,7 @@ static void set_coarse_positions(Subdiv *subdiv, vertex_co = coarse_vertex_cos[vertex_index]; } else { - const MVert *vertex = &mvert[vertex_index]; - vertex_co = vertex->co; + vertex_co = positions[vertex_index]; } copy_v3_v3(&buffer[manifold_vertex_index][0], vertex_co); manifold_vertex_index++; diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc index d8ccb6f57df..f7c607624e0 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.cc +++ b/source/blender/blenkernel/intern/subdiv_mesh.cc @@ -28,6 +28,7 @@ #include "MEM_guardedalloc.h" +using blender::float3; using blender::Span; /* -------------------------------------------------------------------- */ @@ -37,14 +38,14 @@ using blender::Span; struct SubdivMeshContext { const SubdivToMeshSettings *settings; const Mesh *coarse_mesh; - const MVert *coarse_verts; + const float (*coarse_positions)[3]; const MEdge *coarse_edges; const MPoly *coarse_polys; const MLoop *coarse_loops; Subdiv *subdiv; Mesh *subdiv_mesh; - MVert *subdiv_verts; + float3 *subdiv_positions; MEdge *subdiv_edges; MPoly *subdiv_polys; MLoop *subdiv_loops; @@ -83,7 +84,7 @@ static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx) static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx) { Mesh *subdiv_mesh = ctx->subdiv_mesh; - ctx->subdiv_verts = BKE_mesh_verts_for_write(subdiv_mesh); + ctx->subdiv_positions = subdiv_mesh->vert_positions_for_write().data(); ctx->subdiv_edges = BKE_mesh_edges_for_write(subdiv_mesh); ctx->subdiv_polys = BKE_mesh_polys_for_write(subdiv_mesh); ctx->subdiv_loops = BKE_mesh_loops_for_write(subdiv_mesh); @@ -485,18 +486,17 @@ static void subdiv_accumulate_vertex_displacement(SubdivMeshContext *ctx, const int ptex_face_index, const float u, const float v, - MVert *subdiv_vert) + const int subdiv_vertex_index) { /* Accumulate displacement. */ Subdiv *subdiv = ctx->subdiv; - const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts; float dummy_P[3], dPdu[3], dPdv[3], D[3]; BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, dummy_P, dPdu, dPdv); /* NOTE: The subdivided mesh is allocated in this module, and its vertices are kept at zero * locations as a default calloc(). */ BKE_subdiv_eval_displacement(subdiv, ptex_face_index, u, v, dPdu, dPdv, D); - add_v3_v3(subdiv_vert->co, D); + ctx->subdiv_positions[subdiv_vertex_index] += D; if (ctx->accumulated_counters) { ++ctx->accumulated_counters[subdiv_vertex_index]; @@ -543,23 +543,20 @@ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_contex * \{ */ static void subdiv_vertex_data_copy(const SubdivMeshContext *ctx, - const MVert *coarse_vertex, - MVert *subdiv_vertex) + const int coarse_vertex_index, + const int subdiv_vertex_index) { const Mesh *coarse_mesh = ctx->coarse_mesh; - const int coarse_vertex_index = coarse_vertex - ctx->coarse_verts; - const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_verts; CustomData_copy_data( &coarse_mesh->vdata, &ctx->subdiv_mesh->vdata, coarse_vertex_index, subdiv_vertex_index, 1); } static void subdiv_vertex_data_interpolate(const SubdivMeshContext *ctx, - MVert *subdiv_vertex, + const int subdiv_vertex_index, const VerticesForInterpolation *vertex_interpolation, const float u, const float v) { - const int subdiv_vertex_index = subdiv_vertex - ctx->subdiv_verts; const float weights[4] = {(1.0f - u) * (1.0f - v), u * (1.0f - v), u * v, (1.0f - u) * v}; CustomData_interp(vertex_interpolation->vertex_data, &ctx->subdiv_mesh->vdata, @@ -577,23 +574,23 @@ static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext const int ptex_face_index, const float u, const float v, - const MVert *coarse_vert, - MVert *subdiv_vert) + const int coarse_vertex_index, + const int subdiv_vertex_index) { - const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts; + float3 &subdiv_position = ctx->subdiv_positions[subdiv_vertex_index]; /* Displacement is accumulated in subdiv vertex position. * Needs to be backed up before copying data from original vertex. */ float D[3] = {0.0f, 0.0f, 0.0f}; if (ctx->have_displacement) { const float inv_num_accumulated = 1.0f / ctx->accumulated_counters[subdiv_vertex_index]; - copy_v3_v3(D, subdiv_vert->co); + copy_v3_v3(D, subdiv_position); mul_v3_fl(D, inv_num_accumulated); } /* Copy custom data and evaluate position. */ - subdiv_vertex_data_copy(ctx, coarse_vert, subdiv_vert); - BKE_subdiv_eval_limit_point(ctx->subdiv, ptex_face_index, u, v, subdiv_vert->co); + subdiv_vertex_data_copy(ctx, coarse_vertex_index, subdiv_vertex_index); + BKE_subdiv_eval_limit_point(ctx->subdiv, ptex_face_index, u, v, subdiv_position); /* Apply displacement. */ - add_v3_v3(subdiv_vert->co, D); + subdiv_position += D; /* Evaluate undeformed texture coordinate. */ subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index); /* Remove face-dot flag. This can happen if there is more than one subsurf modifier. */ @@ -606,22 +603,22 @@ static void evaluate_vertex_and_apply_displacement_interpolate( const float u, const float v, VerticesForInterpolation *vertex_interpolation, - MVert *subdiv_vert) + const int subdiv_vertex_index) { - const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_verts; + float3 &subdiv_position = ctx->subdiv_positions[subdiv_vertex_index]; /* Displacement is accumulated in subdiv vertex position. * Needs to be backed up before copying data from original vertex. */ float D[3] = {0.0f, 0.0f, 0.0f}; if (ctx->have_displacement) { const float inv_num_accumulated = 1.0f / ctx->accumulated_counters[subdiv_vertex_index]; - copy_v3_v3(D, subdiv_vert->co); + copy_v3_v3(D, subdiv_position); mul_v3_fl(D, inv_num_accumulated); } /* Interpolate custom data and evaluate position. */ - subdiv_vertex_data_interpolate(ctx, subdiv_vert, vertex_interpolation, u, v); - BKE_subdiv_eval_limit_point(ctx->subdiv, ptex_face_index, u, v, subdiv_vert->co); + subdiv_vertex_data_interpolate(ctx, subdiv_vertex_index, vertex_interpolation, u, v); + BKE_subdiv_eval_limit_point(ctx->subdiv, ptex_face_index, u, v, subdiv_position); /* Apply displacement. */ - add_v3_v3(subdiv_vert->co, D); + add_v3_v3(subdiv_position, D); /* Evaluate undeformed texture coordinate. */ subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index); } @@ -635,8 +632,7 @@ static void subdiv_mesh_vertex_displacement_every_corner_or_edge( const int subdiv_vertex_index) { SubdivMeshContext *ctx = static_cast(foreach_context->user_data); - MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index]; - subdiv_accumulate_vertex_displacement(ctx, ptex_face_index, u, v, subdiv_vert); + subdiv_accumulate_vertex_displacement(ctx, ptex_face_index, u, v, subdiv_vertex_index); } static void subdiv_mesh_vertex_displacement_every_corner( @@ -680,10 +676,8 @@ static void subdiv_mesh_vertex_corner(const SubdivForeachContext *foreach_contex { BLI_assert(coarse_vertex_index != ORIGINDEX_NONE); SubdivMeshContext *ctx = static_cast(foreach_context->user_data); - const MVert *coarse_vert = &ctx->coarse_verts[coarse_vertex_index]; - MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index]; evaluate_vertex_and_apply_displacement_copy( - ctx, ptex_face_index, u, v, coarse_vert, subdiv_vert); + ctx, ptex_face_index, u, v, coarse_vertex_index, subdiv_vertex_index); } static void subdiv_mesh_ensure_vertex_interpolation(SubdivMeshContext *ctx, @@ -727,10 +721,9 @@ static void subdiv_mesh_vertex_edge(const SubdivForeachContext *foreach_context, SubdivMeshContext *ctx = static_cast(foreach_context->user_data); SubdivMeshTLS *tls = static_cast(tls_v); const MPoly *coarse_poly = &ctx->coarse_polys[coarse_poly_index]; - MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index]; subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly, coarse_corner); evaluate_vertex_and_apply_displacement_interpolate( - ctx, ptex_face_index, u, v, &tls->vertex_interpolation, subdiv_vert); + ctx, ptex_face_index, u, v, &tls->vertex_interpolation, subdiv_vertex_index); } static bool subdiv_mesh_is_center_vertex(const MPoly *coarse_poly, const float u, const float v) @@ -773,10 +766,10 @@ static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context Subdiv *subdiv = ctx->subdiv; const MPoly *coarse_poly = &ctx->coarse_polys[coarse_poly_index]; Mesh *subdiv_mesh = ctx->subdiv_mesh; - MVert *subdiv_vert = &ctx->subdiv_verts[subdiv_vertex_index]; + float3 &subdiv_position = ctx->subdiv_positions[subdiv_vertex_index]; subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly, coarse_corner); - subdiv_vertex_data_interpolate(ctx, subdiv_vert, &tls->vertex_interpolation, u, v); - BKE_subdiv_eval_final_point(subdiv, ptex_face_index, u, v, subdiv_vert->co); + subdiv_vertex_data_interpolate(ctx, subdiv_vertex_index, &tls->vertex_interpolation, u, v); + BKE_subdiv_eval_final_point(subdiv, ptex_face_index, u, v, subdiv_position); subdiv_mesh_tag_center_vertex(coarse_poly, subdiv_vertex_index, u, v, subdiv_mesh); subdiv_vertex_orco_evaluate(ctx, ptex_face_index, u, v, subdiv_vertex_index); } @@ -966,9 +959,7 @@ static void subdiv_mesh_vertex_loose(const SubdivForeachContext *foreach_context const int subdiv_vertex_index) { SubdivMeshContext *ctx = static_cast(foreach_context->user_data); - const MVert *coarse_vertex = &ctx->coarse_verts[coarse_vertex_index]; - MVert *subdiv_vertex = &ctx->subdiv_verts[subdiv_vertex_index]; - subdiv_vertex_data_copy(ctx, coarse_vertex, subdiv_vertex); + subdiv_vertex_data_copy(ctx, coarse_vertex_index, subdiv_vertex_index); } /* Get neighbor edges of the given one. @@ -1012,21 +1003,21 @@ static void find_edge_neighbors(const MEdge *coarse_edges, } } -static void points_for_loose_edges_interpolation_get(const MVert *coarse_mvert, +static void points_for_loose_edges_interpolation_get(const float (*coarse_positions)[3], const MEdge *coarse_edge, const MEdge *neighbors[2], float points_r[4][3]) { /* Middle points corresponds to the edge. */ - copy_v3_v3(points_r[1], coarse_mvert[coarse_edge->v1].co); - copy_v3_v3(points_r[2], coarse_mvert[coarse_edge->v2].co); + copy_v3_v3(points_r[1], coarse_positions[coarse_edge->v1]); + copy_v3_v3(points_r[2], coarse_positions[coarse_edge->v2]); /* Start point, duplicate from edge start if no neighbor. */ if (neighbors[0] != nullptr) { if (neighbors[0]->v1 == coarse_edge->v1) { - copy_v3_v3(points_r[0], coarse_mvert[neighbors[0]->v2].co); + copy_v3_v3(points_r[0], coarse_positions[neighbors[0]->v2]); } else { - copy_v3_v3(points_r[0], coarse_mvert[neighbors[0]->v1].co); + copy_v3_v3(points_r[0], coarse_positions[neighbors[0]->v1]); } } else { @@ -1036,10 +1027,10 @@ static void points_for_loose_edges_interpolation_get(const MVert *coarse_mvert, /* End point, duplicate from edge end if no neighbor. */ if (neighbors[1] != nullptr) { if (neighbors[1]->v1 == coarse_edge->v2) { - copy_v3_v3(points_r[3], coarse_mvert[neighbors[1]->v2].co); + copy_v3_v3(points_r[3], coarse_positions[neighbors[1]->v2]); } else { - copy_v3_v3(points_r[3], coarse_mvert[neighbors[1]->v1].co); + copy_v3_v3(points_r[3], coarse_positions[neighbors[1]->v1]); } } else { @@ -1048,7 +1039,7 @@ static void points_for_loose_edges_interpolation_get(const MVert *coarse_mvert, } } -void BKE_subdiv_mesh_interpolate_position_on_edge(const MVert *coarse_verts, +void BKE_subdiv_mesh_interpolate_position_on_edge(const float (*coarse_positions)[3], const MEdge *coarse_edges, const MeshElemMap *vert_to_edge_map, const int coarse_edge_index, @@ -1058,16 +1049,14 @@ void BKE_subdiv_mesh_interpolate_position_on_edge(const MVert *coarse_verts, { const MEdge *coarse_edge = &coarse_edges[coarse_edge_index]; if (is_simple) { - const MVert *vert_1 = &coarse_verts[coarse_edge->v1]; - const MVert *vert_2 = &coarse_verts[coarse_edge->v2]; - interp_v3_v3v3(pos_r, vert_1->co, vert_2->co, u); + interp_v3_v3v3(pos_r, coarse_positions[coarse_edge->v1], coarse_positions[coarse_edge->v2], u); } else { /* Find neighbors of the coarse edge. */ const MEdge *neighbors[2]; find_edge_neighbors(coarse_edges, vert_to_edge_map, coarse_edge_index, neighbors); float points[4][3]; - points_for_loose_edges_interpolation_get(coarse_verts, coarse_edge, neighbors, points); + points_for_loose_edges_interpolation_get(coarse_positions, coarse_edge, neighbors, points); float weights[4]; key_curve_position_weights(u, weights, KEY_BSPLINE); interp_v3_v3v3v3v3(pos_r, points[0], points[1], points[2], points[3], weights); @@ -1128,14 +1117,13 @@ static void subdiv_mesh_vertex_of_loose_edge(const SubdivForeachContext *foreach subdiv_mesh_vertex_of_loose_edge_interpolate(ctx, coarse_edge, u, subdiv_vertex_index); } /* Interpolate coordinate. */ - MVert *subdiv_vertex = &ctx->subdiv_verts[subdiv_vertex_index]; - BKE_subdiv_mesh_interpolate_position_on_edge(ctx->coarse_verts, + BKE_subdiv_mesh_interpolate_position_on_edge(ctx->coarse_positions, ctx->coarse_edges, ctx->vert_to_edge_map, coarse_edge_index, is_simple, u, - subdiv_vertex->co); + ctx->subdiv_positions[subdiv_vertex_index]); } /** \} */ @@ -1196,7 +1184,7 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv, subdiv_context.settings = settings; subdiv_context.coarse_mesh = coarse_mesh; - subdiv_context.coarse_verts = BKE_mesh_verts(coarse_mesh); + subdiv_context.coarse_positions = BKE_mesh_vert_positions(coarse_mesh); subdiv_context.coarse_edges = BKE_mesh_edges(coarse_mesh); subdiv_context.coarse_polys = BKE_mesh_polys(coarse_mesh); subdiv_context.coarse_loops = BKE_mesh_loops(coarse_mesh); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index bfb1f781a70..92cefa4d8b1 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -562,9 +562,8 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss, CCGVertHDL *fVerts = NULL; BLI_array_declare(fVerts); #endif - MVert *mvert = dm->getVertArray(dm); + float(*positions)[3] = (float(*)[3])dm->getVertArray(dm); MEdge *medge = dm->getEdgeArray(dm); - MVert *mv; MEdge *me; MLoop *mloop = dm->getLoopArray(dm), *ml; MPoly *mpoly = dm->getPolyArray(dm), *mp; @@ -575,16 +574,15 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss, ccgSubSurf_initFullSync(ss); - mv = mvert; index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX); - for (i = 0; i < totvert; i++, mv++) { + for (i = 0; i < totvert; i++) { CCGVert *v; if (vertexCos) { ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), vertexCos[i], 0, &v); } else { - ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), mv->co, 0, &v); + ccgSubSurf_syncVert(ss, POINTER_FROM_INT(i), positions[i], 0, &v); } ((int *)ccgSubSurf_getVertUserData(ss, v))[1] = (index) ? *index++ : i; @@ -877,12 +875,12 @@ static void ccgDM_getFinalVertNo(DerivedMesh *dm, int vertNum, float r_no[3]) } /* utility function */ -BLI_INLINE void ccgDM_to_MVert(MVert *mv, const CCGKey *key, CCGElem *elem) +BLI_INLINE void ccgDM_to_MVert(float mv[3], const CCGKey *key, CCGElem *elem) { - copy_v3_v3(mv->co, CCG_elem_co(key, elem)); + copy_v3_v3(mv, CCG_elem_co(key, elem)); } -static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) +static void ccgDM_copyFinalVertArray(DerivedMesh *dm, float (*r_positions)[3]) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; CCGSubSurf *ss = ccgdm->ss; @@ -902,12 +900,12 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); vd = ccgSubSurf_getFaceCenterData(f); - ccgDM_to_MVert(&mvert[i++], &key, vd); + ccgDM_to_MVert(r_positions[i++], &key, vd); for (S = 0; S < numVerts; S++) { for (x = 1; x < gridSize - 1; x++) { vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x); - ccgDM_to_MVert(&mvert[i++], &key, vd); + ccgDM_to_MVert(r_positions[i++], &key, vd); } } @@ -915,7 +913,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) for (y = 1; y < gridSize - 1; y++) { for (x = 1; x < gridSize - 1; x++) { vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y); - ccgDM_to_MVert(&mvert[i++], &key, vd); + ccgDM_to_MVert(r_positions[i++], &key, vd); } } } @@ -931,7 +929,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) * unit length. This is most likely caused by edges with no faces which are now zeroed out, * see comment in: `ccgSubSurf__calcVertNormals()`. */ vd = ccgSubSurf_getEdgeData(ss, e, x); - ccgDM_to_MVert(&mvert[i++], &key, vd); + ccgDM_to_MVert(r_positions[i++], &key, vd); } } @@ -940,7 +938,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) CCGVert *v = ccgdm->vertMap[index].vert; vd = ccgSubSurf_getVertData(ss, v); - ccgDM_to_MVert(&mvert[i++], &key, vd); + ccgDM_to_MVert(r_positions[i++], &key, vd); } } diff --git a/source/blender/blenkernel/intern/volume_to_mesh.cc b/source/blender/blenkernel/intern/volume_to_mesh.cc index 61e288b9e3f..8fb8f40cbcc 100644 --- a/source/blender/blenkernel/intern/volume_to_mesh.cc +++ b/source/blender/blenkernel/intern/volume_to_mesh.cc @@ -113,15 +113,12 @@ void fill_mesh_from_openvdb_data(const Span vdb_verts, const int vert_offset, const int poly_offset, const int loop_offset, - MutableSpan verts, + MutableSpan vert_positions, MutableSpan polys, MutableSpan loops) { /* Write vertices. */ - for (const int i : vdb_verts.index_range()) { - const blender::float3 co = blender::float3(vdb_verts[i].asV()); - copy_v3_v3(verts[vert_offset + i].co, co); - } + vert_positions.slice(vert_offset, vdb_verts.size()).copy_from(vdb_verts.cast()); /* Write triangles. */ for (const int i : vdb_tris.index_range()) { @@ -178,7 +175,7 @@ Mesh *volume_to_mesh(const openvdb::GridBase &grid, 0, 0, 0, - mesh->verts_for_write(), + mesh->vert_positions_for_write(), mesh->polys_for_write(), mesh->loops_for_write()); diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index b01d1917f6d..217a971d844 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -996,9 +996,9 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if ((key = blo_do_versions_newlibadr(fd, lib, me->key)) && key->refkey) { data = key->refkey->data; tot = MIN2(me->totvert, key->refkey->totelem); - MVert *verts = BKE_mesh_verts_for_write(me); + MVert *verts = (MVert *)CustomData_get_layer(&me->vdata, CD_MVERT); for (a = 0; a < tot; a++, data += 3) { - copy_v3_v3(verts[a].co, data); + copy_v3_v3(verts[a].co_legacy, data); } } } diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index b8161a9dc40..eca1abc2bc9 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -822,7 +822,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) if (mp->totloop == 2) { bool changed; BKE_mesh_validate_arrays(me, - BKE_mesh_verts_for_write(me), + BKE_mesh_vert_positions_for_write(me), me->totvert, BKE_mesh_edges_for_write(me), me->totedge, diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 583e885a487..87b191de240 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -33,6 +33,7 @@ static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh) BKE_mesh_legacy_bevel_weight_to_layers(&mesh); BKE_mesh_legacy_face_set_to_generic(&mesh); BKE_mesh_legacy_edge_crease_to_layers(&mesh); + BKE_mesh_legacy_convert_verts_to_positions(&mesh); BKE_mesh_legacy_attribute_flags_to_strings(&mesh); } diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 0ee1d546ddc..4019c4245e2 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -37,7 +37,7 @@ * But basics are as follows. * * - Vertex locations (possibly modified from initial active key-block) - * are copied directly into #MVert.co + * are copied directly into the mesh position attribute. * (special confusing note that these may be restored later, when editing the 'Basis', read on). * - if the 'Key' is relative, and the active key-block is the basis for ANY other key-blocks - * get an array of offsets between the new vertex locations and the original shape key @@ -105,6 +105,7 @@ static CLG_LogRef LOG = {"bmesh.mesh.convert"}; using blender::Array; +using blender::float3; using blender::IndexRange; using blender::MutableSpan; using blender::Span; @@ -303,11 +304,11 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar const int *material_indices = (const int *)CustomData_get_layer_named( &me->pdata, CD_PROP_INT32, "material_index"); - Span mvert = me->verts(); + const Span positions = me->vert_positions(); Array vtable(me->totvert); - for (const int i : mvert.index_range()) { + for (const int i : positions.index_range()) { BMVert *v = vtable[i] = BM_vert_create( - bm, keyco ? keyco[i] : mvert[i].co, nullptr, BM_CREATE_SKIP_CD); + bm, keyco ? keyco[i] : positions[i], nullptr, BM_CREATE_SKIP_CD); BM_elem_index_set(v, i); /* set_ok */ if (hide_vert && hide_vert[i]) { @@ -614,16 +615,16 @@ static int bm_to_mesh_shape_layer_index_from_kb(BMesh *bm, KeyBlock *currkey) * * \param bm: The source BMesh. * \param key: The destination key. - * \param mvert: The destination vertex array (in some situations it's coordinates are updated). + * \param positions: The destination vertex array (in some situations its coordinates are updated). * \param active_shapekey_to_mvert: When editing a non-basis shape key, the coordinates for the - * basis are typically copied into the `mvert` array since it makes sense for the meshes + * basis are typically copied into the `positions` array since it makes sense for the meshes * vertex coordinates to match the "Basis" key. - * When enabled, skip this step and copy #BMVert.co directly to #MVert.co, + * When enabled, skip this step and copy #BMVert.co directly to the mesh position. * See #BMeshToMeshParams.active_shapekey_to_mvert doc-string. */ static void bm_to_mesh_shape(BMesh *bm, Key *key, - MutableSpan mvert, + MutableSpan positions, const bool active_shapekey_to_mvert) { KeyBlock *actkey = static_cast(BLI_findlink(&key->block, bm->shapenr - 1)); @@ -685,7 +686,7 @@ static void bm_to_mesh_shape(BMesh *bm, /* Check the vertex existed when entering edit-mode (otherwise don't apply an offset). */ if (keyi != ORIGINDEX_NONE) { float *co_orig = (float *)BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset); - /* Could use 'eve->co' or the destination #MVert.co, they're the same at this point. */ + /* Could use 'eve->co' or the destination position, they're the same at this point. */ sub_v3_v3v3(ofs[i], eve->co, co_orig); } else { @@ -703,7 +704,7 @@ static void bm_to_mesh_shape(BMesh *bm, * while users might not notice since the shape-key is applied in the viewport, * exporters for example may still use the underlying coordinates, see: T30771 & T96135. * - * Needed when editing any shape that isn't the (`key->refkey`), the vertices in `me->mvert` + * Needed when editing any shape that isn't the (`key->refkey`), the vertices in mesh positions * currently have vertex coordinates set from the current-shape (initialized from #BMVert.co). * In this case it's important to overwrite these coordinates with the basis-keys coordinates. */ bool update_vertex_coords_from_refkey = false; @@ -755,7 +756,7 @@ static void bm_to_mesh_shape(BMesh *bm, keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset); if (keyi != ORIGINDEX_NONE) { float *co_refkey = (float *)BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset_refkey); - copy_v3_v3(mvert[i].co, co_refkey); + copy_v3_v3(positions[i], co_refkey); } } } @@ -846,6 +847,7 @@ static void write_fn_to_attribute(blender::bke::MutableAttributeAccessor attribu static void assert_bmesh_has_no_mesh_only_attributes(const BMesh &bm) { (void)bm; /* Unused in the release builds. */ + BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_FLOAT3, "position") == nullptr); /* The "hide" attributes are stored as flags on #BMesh. */ BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".hide_vert") == nullptr); @@ -924,6 +926,7 @@ static void convert_bmesh_selection_flags_to_mesh_attributes(BMesh &bm, void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params) { + using namespace blender; BMVert *v, *eve; BMEdge *e; BMFace *f; @@ -962,11 +965,12 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly); } - CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert); + CustomData_add_layer_named( + &me->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, me->totvert, "position"); CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, me->totedge); CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, me->totloop); CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly); - MutableSpan mvert = me->verts_for_write(); + MutableSpan positions = me->vert_positions_for_write(); MutableSpan medge = me->edges_for_write(); MutableSpan mpoly = me->polys_for_write(); MutableSpan mloop = me->loops_for_write(); @@ -981,7 +985,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh i = 0; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - copy_v3_v3(mvert[i].co, v->co); + copy_v3_v3(positions[i], v->co); if (BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { need_hide_vert = true; @@ -1168,7 +1172,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh } if (me->key) { - bm_to_mesh_shape(bm, me->key, mvert, params->active_shapekey_to_mvert); + bm_to_mesh_shape(bm, me->key, positions, params->active_shapekey_to_mvert); } /* Run this even when shape keys aren't used since it may be used for hooks or vertex parents. */ @@ -1204,7 +1208,10 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * me->totloop = bm->totloop; me->totpoly = bm->totface; - CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, bm->totvert); + if (!CustomData_get_layer_named(&me->vdata, CD_PROP_FLOAT3, "position")) { + CustomData_add_layer_named( + &me->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, bm->totvert, "position"); + } CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, bm->totedge); CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, bm->totloop); CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, bm->totface); @@ -1225,7 +1232,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * BMVert *eve; BMEdge *eed; BMFace *efa; - MutableSpan mvert = me->verts_for_write(); + MutableSpan positions = me->vert_positions_for_write(); MutableSpan medge = me->edges_for_write(); MutableSpan mpoly = me->polys_for_write(); MutableSpan loops = me->loops_for_write(); @@ -1239,9 +1246,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * bke::SpanAttributeWriter hide_vert_attribute; bke::SpanAttributeWriter select_vert_attribute; BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { - MVert *mv = &mvert[i]; - - copy_v3_v3(mv->co, eve->co); + copy_v3_v3(positions[i], eve->co); BM_elem_index_set(eve, i); /* set_inline */ diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.h b/source/blender/bmesh/intern/bmesh_mesh_convert.h index 5137df6d487..82b6d41b19b 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.h +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.h @@ -55,8 +55,8 @@ struct BMeshToMeshParams { */ bool update_shapekey_indices; /** - * Instead of copying the basis shape-key into the #MVert array, - * copy the #BMVert.co directly to #MVert.co (used for reading undo data). + * Instead of copying the basis shape-key into the position array, + * copy the #BMVert.co directly to the #Mesh position (used for reading undo data). */ bool active_shapekey_to_mvert; struct CustomData_MeshMasks cd_mask_extra; diff --git a/source/blender/draw/DRW_pbvh.h b/source/blender/draw/DRW_pbvh.h index 6956b44c695..db21f22aeb0 100644 --- a/source/blender/draw/DRW_pbvh.h +++ b/source/blender/draw/DRW_pbvh.h @@ -27,7 +27,6 @@ struct Object; struct Mesh; struct MLoopTri; struct CustomData; -struct MVert; struct MEdge; struct MLoop; struct MPoly; @@ -41,7 +40,7 @@ typedef struct PBVH_GPU_Args { struct BMesh *bm; const struct Mesh *me; - const struct MVert *mvert; + const float (*vert_positions)[3]; const struct MLoop *mloop; const struct MPoly *mpoly; int mesh_verts_num, mesh_faces_num, mesh_grids_num; diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.cc b/source/blender/draw/intern/draw_cache_extract_mesh.cc index f533904f355..ab89436f636 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh.cc @@ -368,11 +368,9 @@ static void extract_range_iter_lvert_mesh(void *__restrict userdata, const ExtractorIterData *data = static_cast(userdata); const MeshRenderData *mr = data->mr; - const int lvert_index = data->loose_elems[iter]; - const MVert *mv = &((const MVert *)data->elems)[lvert_index]; for (const ExtractorRunData &run_data : data->extractors) { run_data.extractor->iter_lvert_mesh( - mr, mv, iter, POINTER_OFFSET(extract_data, run_data.data_offset)); + mr, iter, POINTER_OFFSET(extract_data, run_data.data_offset)); } } @@ -406,7 +404,7 @@ BLI_INLINE void extract_task_range_run_iter(const MeshRenderData *mr, break; case MR_ITER_LVERT: range_data.loose_elems = mr->lverts; - range_data.elems = is_mesh ? mr->mvert : (void *)mr->bm->vtable; + range_data.elems = is_mesh ? mr->vert_positions : (void *)mr->bm->vtable; func = is_mesh ? extract_range_iter_lvert_mesh : extract_range_iter_lvert_bm; stop = mr->vert_loose_len; break; diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc index ba117a75be6..1488fc79fd9 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc @@ -368,7 +368,7 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_ MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__)); short(*clnors)[2] = static_cast( CustomData_get_layer(&mr->me->ldata, CD_CUSTOMLOOPNORMAL)); - BKE_mesh_normals_loop_split(mr->mvert, + BKE_mesh_normals_loop_split(reinterpret_cast(mr->vert_positions), mr->vert_normals, mr->vert_len, mr->medge, @@ -542,7 +542,7 @@ MeshRenderData *mesh_render_data_create(Object *object, mr->poly_len = mr->me->totpoly; mr->tri_len = poly_to_tri_count(mr->poly_len, mr->loop_len); - mr->mvert = BKE_mesh_verts(mr->me); + mr->vert_positions = mr->me->vert_positions().data(); mr->medge = BKE_mesh_edges(mr->me); mr->mpoly = BKE_mesh_polys(mr->me); mr->mloop = BKE_mesh_loops(mr->me); diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index a225c931a14..25ec4a578d5 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -2201,7 +2201,7 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac int subd_vert_offset = 0; /* Subdivide each loose coarse edge. */ - const Span coarse_verts = coarse_mesh->verts(); + const Span coarse_positions = coarse_mesh->vert_positions(); const Span coarse_edges = coarse_mesh->edges(); int *vert_to_edge_buffer; @@ -2225,13 +2225,14 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac DRWSubdivLooseVertex &subd_v1 = loose_subd_verts[subd_vert_offset]; subd_v1.coarse_vertex_index = (i == 0) ? coarse_edge->v1 : -1u; const float u1 = i * inv_resolution_1; - BKE_subdiv_mesh_interpolate_position_on_edge(coarse_verts.data(), - coarse_edges.data(), - vert_to_edge_map, - coarse_edge_index, - is_simple, - u1, - subd_v1.co); + BKE_subdiv_mesh_interpolate_position_on_edge( + reinterpret_cast(coarse_positions.data()), + coarse_edges.data(), + vert_to_edge_map, + coarse_edge_index, + is_simple, + u1, + subd_v1.co); subd_edge.loose_subdiv_v1_index = subd_vert_offset++; @@ -2239,13 +2240,14 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac DRWSubdivLooseVertex &subd_v2 = loose_subd_verts[subd_vert_offset]; subd_v2.coarse_vertex_index = ((i + 1) == resolution - 1) ? coarse_edge->v2 : -1u; const float u2 = (i + 1) * inv_resolution_1; - BKE_subdiv_mesh_interpolate_position_on_edge(coarse_verts.data(), - coarse_edges.data(), - vert_to_edge_map, - coarse_edge_index, - is_simple, - u2, - subd_v2.co); + BKE_subdiv_mesh_interpolate_position_on_edge( + reinterpret_cast(coarse_positions.data()), + coarse_edges.data(), + vert_to_edge_map, + coarse_edge_index, + is_simple, + u2, + subd_v2.co); subd_edge.loose_subdiv_v2_index = subd_vert_offset++; } @@ -2257,11 +2259,10 @@ void DRW_subdivide_loose_geom(DRWSubdivCache *subdiv_cache, MeshBufferCache *cac /* Copy the remaining loose_verts. */ for (int i = 0; i < coarse_loose_vert_len; i++) { const int coarse_vertex_index = cache->loose_geom.verts[i]; - const MVert &coarse_vertex = coarse_verts[coarse_vertex_index]; DRWSubdivLooseVertex &subd_v = loose_subd_verts[subd_vert_offset++]; subd_v.coarse_vertex_index = cache->loose_geom.verts[i]; - copy_v3_v3(subd_v.co, coarse_vertex.co); + copy_v3_v3(subd_v.co, coarse_positions[coarse_vertex_index]); } subdiv_cache->loose_geom.edges = loose_subd_edges; diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index 2d6fdb96598..b212e29ccff 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -346,7 +346,7 @@ struct PBVHBatches { if (!(mp->flag & ME_SMOOTH)) { smooth = true; - BKE_mesh_calc_poly_normal(mp, args->mloop + mp->loopstart, args->mvert, fno); + BKE_mesh_calc_poly_normal(mp, args->mloop + mp->loopstart, args->vert_positions, fno); normal_float_to_short_v3(no, fno); } else { @@ -587,7 +587,8 @@ struct PBVHBatches { case CD_PBVH_CO_TYPE: foreach_faces( [&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const MLoopTri * /*tri*/) { - *static_cast(GPU_vertbuf_raw_step(&access)) = args->mvert[vertex_i].co; + *static_cast( + GPU_vertbuf_raw_step(&access)) = args->vert_positions[vertex_i]; }); break; case CD_PBVH_NO_TYPE: diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh index c6230e2695e..e5be3db7726 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh @@ -9,6 +9,8 @@ #pragma once +#include "BLI_math_vector_types.hh" + #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -72,7 +74,7 @@ struct MeshRenderData { int freestyle_face_ofs; /** Mesh */ Mesh *me; - const MVert *mvert; + const blender::float3 *vert_positions; const MEdge *medge; const MLoop *mloop; const MPoly *mpoly; @@ -267,10 +269,7 @@ using ExtractLVertBMeshFn = void(const MeshRenderData *mr, const BMVert *eve, int lvert_index, void *data); -using ExtractLVertMeshFn = void(const MeshRenderData *mr, - const MVert *mv, - int lvert_index, - void *data); +using ExtractLVertMeshFn = void(const MeshRenderData *mr, int lvert_index, void *data); using ExtractLooseGeomSubdivFn = void(const DRWSubdivCache *subdiv_cache, const MeshRenderData *mr, void *buffer, diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc index e84f122d03e..d5e8447ff64 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_points.cc @@ -113,7 +113,6 @@ static void extract_points_iter_lvert_bm(const MeshRenderData *mr, } static void extract_points_iter_lvert_mesh(const MeshRenderData *mr, - const MVert * /*mv*/, const int lvert_index, void *_userdata) { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc index 8937fedc50f..aea1aacf5ea 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc @@ -130,10 +130,10 @@ static void extract_edge_fac_iter_poly_mesh(const MeshRenderData *mr, const int ml_index_last = mp->totloop + mp->loopstart - 1; const int ml_index_other = (ml_index == ml_index_last) ? mp->loopstart : (ml_index + 1); const MLoop *ml_next = &mr->mloop[ml_index_other]; - const MVert *v1 = &mr->mvert[ml->v]; - const MVert *v2 = &mr->mvert[ml_next->v]; - float ratio = loop_edge_factor_get( - mr->poly_normals[mp_index], v1->co, mr->vert_normals[ml->v], v2->co); + float ratio = loop_edge_factor_get(mr->poly_normals[mp_index], + mr->vert_positions[ml->v], + mr->vert_normals[ml->v], + mr->vert_positions[ml_next->v]); data->vbo_data[ml_index] = ratio * 253 + 1; } else { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc index 31dc2fdff6a..80365d9da15 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc @@ -223,7 +223,6 @@ static void extract_edit_data_iter_lvert_bm(const MeshRenderData *mr, } static void extract_edit_data_iter_lvert_mesh(const MeshRenderData *mr, - const MVert * /*mv*/, const int lvert_index, void *_data) { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc index 9fd15a2309c..88de5fafe63 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc @@ -167,15 +167,16 @@ static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr float(*auv)[2] = data->auv, *last_auv = data->last_auv; float(*av)[3] = data->av, *last_av = data->last_av; int l_next = ml_index + 1; - const MVert *v, *v_next; if (ml_index == mp->loopstart) { /* First loop in face. */ const int ml_index_last = ml_index_end - 1; const int l_next_tmp = mp->loopstart; - v = &mr->mvert[mr->mloop[ml_index_last].v]; - v_next = &mr->mvert[mr->mloop[l_next_tmp].v]; - compute_normalize_edge_vectors( - auv, av, data->luv[ml_index_last].uv, data->luv[l_next_tmp].uv, v->co, v_next->co); + compute_normalize_edge_vectors(auv, + av, + data->luv[ml_index_last].uv, + data->luv[l_next_tmp].uv, + mr->vert_positions[mr->mloop[ml_index_last].v], + mr->vert_positions[mr->mloop[l_next_tmp].v]); /* Save last edge. */ copy_v2_v2(last_auv, auv[1]); copy_v3_v3(last_av, av[1]); @@ -190,10 +191,12 @@ static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr copy_v3_v3(av[1], last_av); } else { - v = &mr->mvert[mr->mloop[ml_index].v]; - v_next = &mr->mvert[mr->mloop[l_next].v]; - compute_normalize_edge_vectors( - auv, av, data->luv[ml_index].uv, data->luv[l_next].uv, v->co, v_next->co); + compute_normalize_edge_vectors(auv, + av, + data->luv[ml_index].uv, + data->luv[l_next].uv, + mr->vert_positions[mr->mloop[ml_index].v], + mr->vert_positions[mr->mloop[l_next].v]); } edituv_get_edituv_stretch_angle(auv, av, &data->vbo_data[ml_index]); } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc index 7c96fbd6a99..78b85694ad9 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc @@ -75,7 +75,8 @@ static void compute_area_ratio(const MeshRenderData *mr, const MLoopUV *uv_data = (const MLoopUV *)CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV); const MPoly *mp = mr->mpoly; for (int mp_index = 0; mp_index < mr->poly_len; mp_index++, mp++) { - float area = BKE_mesh_calc_poly_area(mp, &mr->mloop[mp->loopstart], mr->mvert); + float area = BKE_mesh_calc_poly_area( + mp, &mr->mloop[mp->loopstart], reinterpret_cast(mr->vert_positions)); float uvarea = BKE_mesh_calc_poly_uv_area(mp, uv_data); tot_area += area; tot_uv_area += uvarea; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc index d43eb6117df..f5c470e7a75 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_pos.cc @@ -75,7 +75,6 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr, float *co = center[mp_index]; zero_v3(co); - const MVert *mvert = mr->mvert; const MLoop *mloop = mr->mloop; const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags; @@ -84,13 +83,12 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr, const MLoop *ml = &mloop[ml_index]; if (mr->use_subsurf_fdots) { if (BLI_BITMAP_TEST(facedot_tags, ml->v)) { - copy_v3_v3(center[mp_index], mvert[ml->v].co); + copy_v3_v3(center[mp_index], mr->vert_positions[ml->v]); break; } } else { - const MVert *mv = &mvert[ml->v]; - add_v3_v3(center[mp_index], mv->co); + add_v3_v3(center[mp_index], mr->vert_positions[ml->v]); } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc index 9aa8a4fe6a4..a7fdbc2facf 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_mesh_analysis.cc @@ -217,9 +217,9 @@ static void statvis_calc_thickness(const MeshRenderData *mr, float *r_thickness) const MLoopTri *mlooptri = mr->mlooptri; for (int i = 0; i < mr->tri_len; i++, mlooptri++) { const int index = mlooptri->poly; - const float *cos[3] = {mr->mvert[mr->mloop[mlooptri->tri[0]].v].co, - mr->mvert[mr->mloop[mlooptri->tri[1]].v].co, - mr->mvert[mr->mloop[mlooptri->tri[2]].v].co}; + const float *cos[3] = {mr->vert_positions[mr->mloop[mlooptri->tri[0]].v], + mr->vert_positions[mr->mloop[mlooptri->tri[1]].v], + mr->vert_positions[mr->mloop[mlooptri->tri[2]].v]}; float ray_co[3]; float ray_no[3]; @@ -259,7 +259,7 @@ static void statvis_calc_thickness(const MeshRenderData *mr, float *r_thickness) } struct BVHTree_OverlapData { - const MVert *verts; + const float3 *positions; const MLoop *loops; const MLoopTri *mlooptri; float epsilon; @@ -276,12 +276,12 @@ static bool bvh_overlap_cb(void *userdata, int index_a, int index_b, int /*threa return false; } - const float *tri_a_co[3] = {data->verts[data->loops[tri_a->tri[0]].v].co, - data->verts[data->loops[tri_a->tri[1]].v].co, - data->verts[data->loops[tri_a->tri[2]].v].co}; - const float *tri_b_co[3] = {data->verts[data->loops[tri_b->tri[0]].v].co, - data->verts[data->loops[tri_b->tri[1]].v].co, - data->verts[data->loops[tri_b->tri[2]].v].co}; + const float *tri_a_co[3] = {data->positions[data->loops[tri_a->tri[0]].v], + data->positions[data->loops[tri_a->tri[1]].v], + data->positions[data->loops[tri_a->tri[2]].v]}; + const float *tri_b_co[3] = {data->positions[data->loops[tri_b->tri[0]].v], + data->positions[data->loops[tri_b->tri[1]].v], + data->positions[data->loops[tri_b->tri[2]].v]}; float ix_pair[2][3]; int verts_shared = 0; @@ -342,7 +342,7 @@ static void statvis_calc_intersect(const MeshRenderData *mr, float *r_intersect) BVHTree *tree = BKE_bvhtree_from_mesh_get(&treeData, mr->me, BVHTREE_FROM_LOOPTRI, 4); struct BVHTree_OverlapData data = {nullptr}; - data.verts = mr->mvert; + data.positions = mr->vert_positions; data.loops = mr->mloop; data.mlooptri = mr->mlooptri; data.epsilon = BLI_bvhtree_get_epsilon(tree); @@ -454,9 +454,9 @@ static void statvis_calc_distort(const MeshRenderData *mr, float *r_distort) const MLoop *l_next = &mr->mloop[mp->loopstart + (i + 1) % mp->totloop]; float no_corner[3]; normal_tri_v3(no_corner, - mr->mvert[l_prev->v].co, - mr->mvert[l_curr->v].co, - mr->mvert[l_next->v].co); + mr->vert_positions[l_prev->v], + mr->vert_positions[l_curr->v], + mr->vert_positions[l_next->v]); /* simple way to detect (what is most likely) concave */ if (dot_v3v3(f_no, no_corner) < 0.0f) { negate_v3(no_corner); @@ -534,8 +534,6 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp) for (int i = 0; i < mp->totloop; i++) { const MLoop *l_curr = &mr->mloop[mp->loopstart + (i + 0) % mp->totloop]; const MLoop *l_next = &mr->mloop[mp->loopstart + (i + 1) % mp->totloop]; - const MVert *v_curr = &mr->mvert[l_curr->v]; - const MVert *v_next = &mr->mvert[l_next->v]; float angle; void **pval; bool value_is_init = BLI_edgehash_ensure_p(eh, l_curr->v, l_next->v, &pval); @@ -548,7 +546,10 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp) const float *f1_no = mr->poly_normals[mp_index]; const float *f2_no = static_cast(*pval); angle = angle_normalized_v3v3(f1_no, f2_no); - angle = is_edge_convex_v3(v_curr->co, v_next->co, f1_no, f2_no) ? angle : -angle; + angle = is_edge_convex_v3( + mr->vert_positions[l_curr->v], mr->vert_positions[l_next->v], f1_no, f2_no) ? + angle : + -angle; /* Tag as manifold. */ *pval = nullptr; } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc index ac3317e27ec..4c1464c108f 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc @@ -95,9 +95,8 @@ static void extract_pos_nor_iter_poly_mesh(const MeshRenderData *mr, const MLoop *ml = &mloop[ml_index]; PosNorLoop *vert = &data->vbo_data[ml_index]; - const MVert *mv = &mr->mvert[ml->v]; const bool vert_hidden = mr->hide_vert && mr->hide_vert[ml->v]; - copy_v3_v3(vert->pos, mv->co); + copy_v3_v3(vert->pos, mr->vert_positions[ml->v]); vert->nor = data->normals[ml->v].low; /* Flag for paint mode overlay. */ if (poly_hidden || vert_hidden || @@ -136,8 +135,8 @@ static void extract_pos_nor_iter_ledge_mesh(const MeshRenderData *mr, MeshExtract_PosNor_Data *data = static_cast(_data); const int ml_index = mr->loop_len + ledge_index * 2; PosNorLoop *vert = &data->vbo_data[ml_index]; - copy_v3_v3(vert[0].pos, mr->mvert[med->v1].co); - copy_v3_v3(vert[1].pos, mr->mvert[med->v2].co); + copy_v3_v3(vert[0].pos, mr->vert_positions[med->v1]); + copy_v3_v3(vert[1].pos, mr->vert_positions[med->v2]); vert[0].nor = data->normals[med->v1].low; vert[1].nor = data->normals[med->v2].low; } @@ -157,7 +156,6 @@ static void extract_pos_nor_iter_lvert_bm(const MeshRenderData *mr, } static void extract_pos_nor_iter_lvert_mesh(const MeshRenderData *mr, - const MVert *mv, const int lvert_index, void *_data) { @@ -167,7 +165,7 @@ static void extract_pos_nor_iter_lvert_mesh(const MeshRenderData *mr, const int ml_index = offset + lvert_index; const int v_index = mr->lverts[lvert_index]; PosNorLoop *vert = &data->vbo_data[ml_index]; - copy_v3_v3(vert->pos, mv->co); + copy_v3_v3(vert->pos, mr->vert_positions[v_index]); vert->nor = data->normals[v_index].low; } @@ -474,8 +472,7 @@ static void extract_pos_nor_hq_iter_poly_mesh(const MeshRenderData *mr, const bool vert_hidden = mr->hide_vert && mr->hide_vert[ml->v]; PosNorHQLoop *vert = &data->vbo_data[ml_index]; - const MVert *mv = &mr->mvert[ml->v]; - copy_v3_v3(vert->pos, mv->co); + copy_v3_v3(vert->pos, mr->vert_positions[ml->v]); copy_v3_v3_short(vert->nor, data->normals[ml->v].high); /* Flag for paint mode overlay. */ @@ -516,8 +513,8 @@ static void extract_pos_nor_hq_iter_ledge_mesh(const MeshRenderData *mr, MeshExtract_PosNorHQ_Data *data = static_cast(_data); const int ml_index = mr->loop_len + ledge_index * 2; PosNorHQLoop *vert = &data->vbo_data[ml_index]; - copy_v3_v3(vert[0].pos, mr->mvert[med->v1].co); - copy_v3_v3(vert[1].pos, mr->mvert[med->v2].co); + copy_v3_v3(vert[0].pos, mr->vert_positions[med->v1]); + copy_v3_v3(vert[1].pos, mr->vert_positions[med->v2]); copy_v3_v3_short(vert[0].nor, data->normals[med->v1].high); vert[0].nor[3] = 0; copy_v3_v3_short(vert[1].nor, data->normals[med->v2].high); @@ -540,7 +537,6 @@ static void extract_pos_nor_hq_iter_lvert_bm(const MeshRenderData *mr, } static void extract_pos_nor_hq_iter_lvert_mesh(const MeshRenderData *mr, - const MVert *mv, const int lvert_index, void *_data) { @@ -550,7 +546,7 @@ static void extract_pos_nor_hq_iter_lvert_mesh(const MeshRenderData *mr, const int ml_index = offset + lvert_index; const int v_index = mr->lverts[lvert_index]; PosNorHQLoop *vert = &data->vbo_data[ml_index]; - copy_v3_v3(vert->pos, mv->co); + copy_v3_v3(vert->pos, mr->vert_positions[v_index]); copy_v3_v3_short(vert->nor, data->normals[v_index].high); vert->nor[3] = 0; } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc index 5c196a67d0b..fd02c642a5b 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_select_idx.cc @@ -169,7 +169,6 @@ static void extract_vert_idx_iter_ledge_mesh(const MeshRenderData *mr, } static void extract_vert_idx_iter_lvert_mesh(const MeshRenderData *mr, - const MVert * /*mv*/, const int lvert_index, void *data) { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc index 5df881251c1..a6123dbbda9 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc @@ -88,9 +88,8 @@ static void extract_tan_init_common(const MeshRenderData *mr, } } else { - const MVert *mv = mr->mvert; - for (int v = 0; v < mr->vert_len; v++, mv++) { - copy_v3_v3(orco[v], mv->co); + for (int v = 0; v < mr->vert_len; v++) { + copy_v3_v3(orco[v], mr->vert_positions[v]); } } BKE_mesh_orco_verts_transform(mr->me, orco, mr->vert_len, 0); @@ -114,7 +113,7 @@ static void extract_tan_init_common(const MeshRenderData *mr, &tangent_mask); } else { - BKE_mesh_calc_loop_tangent_ex(mr->mvert, + BKE_mesh_calc_loop_tangent_ex(reinterpret_cast(mr->vert_positions), mr->mpoly, mr->poly_len, mr->mloop, diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c index 3c9c8cf05b3..6fb07dc7da6 100644 --- a/source/blender/editors/armature/armature_skinning.c +++ b/source/blender/editors/armature/armature_skinning.c @@ -409,10 +409,10 @@ static void add_verts_to_dgroups(ReportList *reports, } /* transform verts to global space */ - const MVert *mesh_verts = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); for (int i = 0; i < mesh->totvert; i++) { if (!vertsfilled) { - copy_v3_v3(verts[i], mesh_verts[i].co); + copy_v3_v3(verts[i], positions[i]); } mul_m4_v3(ob->object_to_world, verts[i]); } diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index de83d5d0c1f..133741d172f 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -652,7 +652,7 @@ void heat_bone_weighting(Object *ob, int a, tris_num, j, bbone, firstsegment, lastsegment; bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; - const MVert *mesh_verts = BKE_mesh_verts(me); + const float(*vert_positions)[3] = BKE_mesh_vert_positions(me); const MPoly *polys = BKE_mesh_polys(me); const MLoop *loops = BKE_mesh_loops(me); bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; @@ -700,7 +700,7 @@ void heat_bone_weighting(Object *ob, sys->heat.tris_num = poly_to_tri_count(me->totpoly, me->totloop); mlooptri = MEM_mallocN(sizeof(*sys->heat.mlooptri) * sys->heat.tris_num, __func__); - BKE_mesh_recalc_looptri(loops, polys, mesh_verts, me->totloop, me->totpoly, mlooptri); + BKE_mesh_recalc_looptri(loops, polys, vert_positions, me->totloop, me->totpoly, mlooptri); sys->heat.mlooptri = mlooptri; sys->heat.mloop = loops; @@ -1753,7 +1753,6 @@ void ED_mesh_deform_bind_callback(Object *object, MeshDeformModifierData *mmd_orig = (MeshDeformModifierData *)BKE_modifier_get_original( object, &mmd->modifier); MeshDeformBind mdb; - const MVert *mvert; int a; waitcursor(1); @@ -1773,9 +1772,9 @@ void ED_mesh_deform_bind_callback(Object *object, mdb.cagecos = MEM_callocN(sizeof(*mdb.cagecos) * mdb.cage_verts_num, "MeshDeformBindCos"); copy_m4_m4(mdb.cagemat, cagemat); - mvert = BKE_mesh_verts(mdb.cagemesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mdb.cagemesh); for (a = 0; a < mdb.cage_verts_num; a++) { - copy_v3_v3(mdb.cagecos[a], mvert[a].co); + copy_v3_v3(mdb.cagecos[a], positions[a]); } for (a = 0; a < mdb.verts_num; a++) { mul_v3_m4v3(mdb.vertexcos[a], mdb.cagemat, vertexcos + a * 3); diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 46ccc02eabc..91e0837c679 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -140,7 +140,7 @@ using bke::CurvesGeometry; namespace convert_to_particle_system { -static int find_mface_for_root_position(const Span verts, +static int find_mface_for_root_position(const Span positions, const MFace *mface, const Span possible_mface_indices, const float3 &root_pos) @@ -158,9 +158,9 @@ static int find_mface_for_root_position(const Span verts, float3 point_in_triangle; closest_on_tri_to_point_v3(point_in_triangle, root_pos, - verts[possible_mface.v1].co, - verts[possible_mface.v2].co, - verts[possible_mface.v3].co); + positions[possible_mface.v1], + positions[possible_mface.v2], + positions[possible_mface.v3]); const float distance_sq = len_squared_v3v3(root_pos, point_in_triangle); if (distance_sq < best_distance_sq) { best_distance_sq = distance_sq; @@ -172,9 +172,9 @@ static int find_mface_for_root_position(const Span verts, float3 point_in_triangle; closest_on_tri_to_point_v3(point_in_triangle, root_pos, - verts[possible_mface.v1].co, - verts[possible_mface.v3].co, - verts[possible_mface.v4].co); + positions[possible_mface.v1], + positions[possible_mface.v3], + positions[possible_mface.v4]); const float distance_sq = len_squared_v3v3(root_pos, point_in_triangle); if (distance_sq < best_distance_sq) { best_distance_sq = distance_sq; @@ -188,22 +188,22 @@ static int find_mface_for_root_position(const Span verts, /** * \return Barycentric coordinates in the #MFace. */ -static float4 compute_mface_weights_for_position(const Span verts, +static float4 compute_mface_weights_for_position(const Span positions, const MFace &mface, const float3 &position) { float4 mface_weights; if (mface.v4) { - float mface_verts_su[4][3]; - copy_v3_v3(mface_verts_su[0], verts[mface.v1].co); - copy_v3_v3(mface_verts_su[1], verts[mface.v2].co); - copy_v3_v3(mface_verts_su[2], verts[mface.v3].co); - copy_v3_v3(mface_verts_su[3], verts[mface.v4].co); - interp_weights_poly_v3(mface_weights, mface_verts_su, 4, position); + float mface_positions_su[4][3]; + copy_v3_v3(mface_positions_su[0], positions[mface.v1]); + copy_v3_v3(mface_positions_su[1], positions[mface.v2]); + copy_v3_v3(mface_positions_su[2], positions[mface.v3]); + copy_v3_v3(mface_positions_su[3], positions[mface.v4]); + interp_weights_poly_v3(mface_weights, mface_positions_su, 4, position); } else { interp_weights_tri_v3( - mface_weights, verts[mface.v1].co, verts[mface.v2].co, verts[mface.v3].co, position); + mface_weights, positions[mface.v1], positions[mface.v2], positions[mface.v3], position); mface_weights[3] = 0.0f; } return mface_weights; @@ -286,7 +286,7 @@ static void try_convert_single_object(Object &curves_ob, const bke::CurvesSurfaceTransforms transforms{curves_ob, &surface_ob}; const MFace *mfaces = (const MFace *)CustomData_get_layer(&surface_me.fdata, CD_MFACE); - const Span verts = surface_me.verts(); + const Span positions = surface_me.vert_positions(); for (const int new_hair_i : IndexRange(hair_num)) { const int curve_i = new_hair_i; @@ -306,10 +306,10 @@ static void try_convert_single_object(Object &curves_ob, const int poly_i = looptri.poly; const int mface_i = find_mface_for_root_position( - verts, mfaces, poly_to_mface_map[poly_i], root_pos_su); + positions, mfaces, poly_to_mface_map[poly_i], root_pos_su); const MFace &mface = mfaces[mface_i]; - const float4 mface_weights = compute_mface_weights_for_position(verts, mface, root_pos_su); + const float4 mface_weights = compute_mface_weights_for_position(positions, mface, root_pos_su); ParticleData &particle = particles[new_hair_i]; const int num_keys = points.size(); @@ -543,7 +543,7 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry); const Mesh &surface_mesh = *static_cast(surface_ob.data); - const Span verts = surface_mesh.verts(); + const Span surface_positions = surface_mesh.vert_positions(); const Span loops = surface_mesh.loops(); const Span surface_looptris = surface_mesh.looptris(); VArraySpan surface_uv_map; @@ -603,9 +603,9 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, const float2 &uv0 = surface_uv_map[corner0]; const float2 &uv1 = surface_uv_map[corner1]; const float2 &uv2 = surface_uv_map[corner2]; - const float3 &p0_su = verts[loops[corner0].v].co; - const float3 &p1_su = verts[loops[corner1].v].co; - const float3 &p2_su = verts[loops[corner2].v].co; + const float3 &p0_su = surface_positions[loops[corner0].v]; + const float3 &p1_su = surface_positions[loops[corner1].v]; + const float3 &p2_su = surface_positions[loops[corner2].v]; float3 bary_coords; interp_weights_tri_v3(bary_coords, p0_su, p1_su, p2_su, new_first_point_pos_su); const float2 uv = attribute_math::mix3(bary_coords, uv0, uv1, uv2); @@ -639,9 +639,9 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, const MLoopTri &looptri = surface_looptris[lookup_result.looptri_index]; const float3 &bary_coords = lookup_result.bary_weights; - const float3 &p0_su = verts[loops[looptri.tri[0]].v].co; - const float3 &p1_su = verts[loops[looptri.tri[1]].v].co; - const float3 &p2_su = verts[loops[looptri.tri[2]].v].co; + const float3 &p0_su = surface_positions[loops[looptri.tri[0]].v]; + const float3 &p1_su = surface_positions[loops[looptri.tri[1]].v]; + const float3 &p2_su = surface_positions[loops[looptri.tri[2]].v]; float3 new_first_point_pos_su; interp_v3_v3v3v3(new_first_point_pos_su, p0_su, p1_su, p2_su, bary_coords); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 52aa5f56fee..f475eeee335 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -30,7 +30,6 @@ struct Depsgraph; struct EditBone; struct GPUSelectResult; struct ID; -struct MVert; struct Main; struct MetaElem; struct Nurb; @@ -355,11 +354,12 @@ void ED_view3d_cursor_snap_draw_util(struct RegionView3D *rv3d, /* foreach iterators */ -void meshobject_foreachScreenVert( - struct ViewContext *vc, - void (*func)(void *userData, struct MVert *eve, const float screen_co[2], int index), - void *userData, - eV3DProjTest clip_flag); +void meshobject_foreachScreenVert(struct ViewContext *vc, + void (*func)(void *userData, + const float screen_co[2], + int index), + void *userData, + eV3DProjTest clip_flag); void mesh_foreachScreenVert( struct ViewContext *vc, void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index), diff --git a/source/blender/editors/mesh/editface.cc b/source/blender/editors/mesh/editface.cc index 1c6d1747516..605f1327a84 100644 --- a/source/blender/editors/mesh/editface.cc +++ b/source/blender/editors/mesh/editface.cc @@ -385,7 +385,7 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3]) copy_m3_m4(bmat, ob->object_to_world); - const Span verts = me->verts(); + const Span positions = me->vert_positions(); const Span polys = me->polys(); const Span loops = me->loops(); bke::AttributeAccessor attributes = me->attributes(); @@ -402,7 +402,7 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3]) const MPoly &poly = polys[i]; const MLoop *ml = &loops[poly.loopstart]; for (int b = 0; b < poly.totloop; b++, ml++) { - mul_v3_m3v3(vec, bmat, verts[ml->v].co); + mul_v3_m3v3(vec, bmat, positions[ml->v]); add_v3_v3v3(vec, vec, ob->object_to_world[3]); minmax_v3v3_v3(r_min, r_max, vec); } diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index 204fb7012ab..b22f3a1d3df 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -48,6 +48,7 @@ #include "mesh_intern.h" /* own include */ using blender::Array; +using blender::float3; using blender::MutableSpan; using blender::Span; @@ -1129,8 +1130,9 @@ static void mesh_add_verts(Mesh *mesh, int len) CustomData_copy(&mesh->vdata, &vdata, CD_MASK_MESH.vmask, CD_SET_DEFAULT, totvert); CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert); - if (!CustomData_has_layer(&vdata, CD_MVERT)) { - CustomData_add_layer(&vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, totvert); + if (!CustomData_get_layer_named(&vdata, CD_PROP_FLOAT3, "position")) { + CustomData_add_layer_named( + &vdata, CD_PROP_FLOAT3, CD_SET_DEFAULT, nullptr, totvert, "position"); } CustomData_free(&mesh->vdata, mesh->totvert); diff --git a/source/blender/editors/mesh/mesh_mirror.c b/source/blender/editors/mesh/mesh_mirror.c index ad5a5d362f1..4ef2dae4389 100644 --- a/source/blender/editors/mesh/mesh_mirror.c +++ b/source/blender/editors/mesh/mesh_mirror.c @@ -55,9 +55,9 @@ void ED_mesh_mirror_spatial_table_begin(Object *ob, BMEditMesh *em, Mesh *me_eva } } else { - const MVert *verts = BKE_mesh_verts(me_eval ? me_eval : me); + const float(*positions)[3] = BKE_mesh_vert_positions(me_eval ? me_eval : me); for (int i = 0; i < totvert; i++) { - BLI_kdtree_3d_insert(MirrKdStore.tree, i, verts[i].co); + BLI_kdtree_3d_insert(MirrKdStore.tree, i, positions[i]); } } diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc index 99a4ece0408..a710ac423fd 100644 --- a/source/blender/editors/mesh/meshtools.cc +++ b/source/blender/editors/mesh/meshtools.cc @@ -55,6 +55,7 @@ #include "WM_api.h" #include "WM_types.h" +using blender::float3; using blender::MutableSpan; using blender::Span; @@ -71,7 +72,7 @@ static void join_mesh_single(Depsgraph *depsgraph, Object *ob_dst, Object *ob_src, const float imat[4][4], - MVert **mvert_pp, + float3 **vert_positions_pp, MEdge **medge_pp, MLoop **mloop_pp, MPoly **mpoly_pp, @@ -96,7 +97,7 @@ static void join_mesh_single(Depsgraph *depsgraph, int a, b; Mesh *me = static_cast(ob_src->data); - MVert *mvert = *mvert_pp; + float3 *vert_positions = *vert_positions_pp; MEdge *medge = *medge_pp; MLoop *mloop = *mloop_pp; MPoly *mpoly = *mpoly_pp; @@ -135,8 +136,8 @@ static void join_mesh_single(Depsgraph *depsgraph, mul_m4_m4m4(cmat, imat, ob_src->object_to_world); /* transform vertex coordinates into new space */ - for (a = 0; a < me->totvert; a++, mvert++) { - mul_m4_v3(cmat, mvert->co); + for (a = 0; a < me->totvert; a++) { + mul_m4_v3(cmat, vert_positions[a]); } /* For each shape-key in destination mesh: @@ -164,8 +165,8 @@ static void join_mesh_single(Depsgraph *depsgraph, } else { /* Copy this mesh's vertex coordinates to the destination shape-key. */ - for (a = 0, mvert = *mvert_pp; a < me->totvert; a++, cos++, mvert++) { - copy_v3_v3(*cos, mvert->co); + for (a = 0; a < me->totvert; a++, cos++) { + copy_v3_v3(*cos, vert_positions[a]); } } } @@ -192,8 +193,8 @@ static void join_mesh_single(Depsgraph *depsgraph, } else { /* Copy base-coordinates to the destination shape-key. */ - for (a = 0, mvert = *mvert_pp; a < me->totvert; a++, cos++, mvert++) { - copy_v3_v3(*cos, mvert->co); + for (a = 0; a < me->totvert; a++, cos++) { + copy_v3_v3(*cos, vert_positions[a]); } } } @@ -287,7 +288,7 @@ static void join_mesh_single(Depsgraph *depsgraph, /* these are used for relinking (cannot be set earlier, or else reattaching goes wrong) */ *vertofs += me->totvert; - *mvert_pp += me->totvert; + *vert_positions_pp += me->totvert; *edgeofs += me->totedge; *medge_pp += me->totedge; *loopofs += me->totloop; @@ -330,7 +331,6 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); Material **matar = nullptr, *ma; Mesh *me; - MVert *mvert = nullptr; MEdge *medge = nullptr; MPoly *mpoly = nullptr; MLoop *mloop = nullptr; @@ -581,7 +581,8 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) CustomData_reset(&ldata); CustomData_reset(&pdata); - mvert = (MVert *)CustomData_add_layer(&vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, totvert); + float3 *vert_positions = (float3 *)CustomData_add_layer_named( + &vdata, CD_PROP_FLOAT3, CD_SET_DEFAULT, nullptr, totvert, "position"); medge = (MEdge *)CustomData_add_layer(&edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, totedge); mloop = (MLoop *)CustomData_add_layer(&ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, totloop); mpoly = (MPoly *)CustomData_add_layer(&pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, totpoly); @@ -606,7 +607,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) ob, ob, imat, - &mvert, + &vert_positions, &medge, &mloop, &mpoly, @@ -640,7 +641,7 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op) ob, ob_iter, imat, - &mvert, + &vert_positions, &medge, &mloop, &mpoly, @@ -897,13 +898,13 @@ static bool ed_mesh_mirror_topo_table_update(Object *ob, Mesh *me_eval) static int mesh_get_x_mirror_vert_spatial(Object *ob, Mesh *me_eval, int index) { Mesh *me = static_cast(ob->data); - const Span verts = me_eval ? me_eval->verts() : me->verts(); + const Span positions = me_eval ? me_eval->vert_positions() : me->vert_positions(); float vec[3]; - vec[0] = -verts[index].co[0]; - vec[1] = verts[index].co[1]; - vec[2] = verts[index].co[2]; + vec[0] = -positions[index][0]; + vec[1] = positions[index][1]; + vec[2] = positions[index][2]; return ED_mesh_mirror_spatial_table_lookup(ob, nullptr, me_eval, vec); } @@ -1119,7 +1120,6 @@ static bool mirror_facecmp(const void *a, const void *b) int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval) { Mesh *me = static_cast(ob->data); - const MVert *mv; MFace mirrormf, *mf, *hashmf; GHash *fhash; int *mirrorverts, *mirrorfaces; @@ -1134,13 +1134,13 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval) mirrorverts = static_cast(MEM_callocN(sizeof(int) * totvert, "MirrorVerts")); mirrorfaces = static_cast(MEM_callocN(sizeof(int[2]) * totface, "MirrorFaces")); - const Span verts = me_eval ? me_eval->verts() : me->verts(); + const Span vert_positions = me_eval ? me_eval->vert_positions() : me->vert_positions(); MFace *mface = (MFace *)CustomData_get_layer(&(me_eval ? me_eval : me)->fdata, CD_MFACE); ED_mesh_mirror_spatial_table_begin(ob, em, me_eval); - for (a = 0, mv = verts.data(); a < totvert; a++, mv++) { - mirrorverts[a] = mesh_get_x_mirror_vert(ob, me_eval, a, use_topology); + for (const int i : vert_positions.index_range()) { + mirrorverts[i] = mesh_get_x_mirror_vert(ob, me_eval, i, use_topology); } ED_mesh_mirror_spatial_table_end(ob); @@ -1221,7 +1221,7 @@ static void ed_mesh_pick_face_vert__mpoly_find( const float mval[2], /* mesh data (evaluated) */ const MPoly *mp, - const MVert *mvert, + const Span vert_positions, const MLoop *mloop, /* return values */ float *r_len_best, @@ -1232,8 +1232,8 @@ static void ed_mesh_pick_face_vert__mpoly_find( for (ml = &mloop[mp->loopstart]; j--; ml++) { float sco[2]; const int v_idx = ml->v; - const float *co = mvert[v_idx].co; - if (ED_view3d_project_float_object(region, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + if (ED_view3d_project_float_object(region, vert_positions[v_idx], sco, V3D_PROJ_TEST_NOP) == + V3D_PROJ_RET_OK) { const float len_test = len_manhattan_v2v2(mval, sco); if (len_test < *r_len_best) { *r_len_best = len_test; @@ -1266,7 +1266,7 @@ bool ED_mesh_pick_face_vert( const float mval_f[2] = {float(mval[0]), float(mval[1])}; float len_best = FLT_MAX; - const Span verts = me_eval->verts(); + const Span vert_positions = me_eval->vert_positions(); const Span polys = me_eval->polys(); const Span loops = me_eval->loops(); @@ -1277,7 +1277,7 @@ bool ED_mesh_pick_face_vert( for (const int i : polys.index_range()) { if (index_mp_to_orig[i] == poly_index) { ed_mesh_pick_face_vert__mpoly_find( - region, mval_f, &polys[i], verts.data(), loops.data(), &len_best, &v_idx_best); + region, mval_f, &polys[i], vert_positions, loops.data(), &len_best, &v_idx_best); } } } @@ -1286,7 +1286,7 @@ bool ED_mesh_pick_face_vert( ed_mesh_pick_face_vert__mpoly_find(region, mval_f, &polys[poly_index], - verts.data(), + vert_positions, loops.data(), &len_best, &v_idx_best); @@ -1318,7 +1318,6 @@ bool ED_mesh_pick_face_vert( * \return boolean true == Found */ struct VertPickData { - const MVert *mvert; const bool *hide_vert; const float *mval_f; /* [2] */ ARegion *region; @@ -1393,7 +1392,7 @@ bool ED_mesh_pick_vert( /* find the vert closest to 'mval' */ const float mval_f[2] = {float(mval[0]), float(mval[1])}; - VertPickData data = {nullptr}; + VertPickData data{}; ED_view3d_init_mats_rv3d(ob, rv3d); @@ -1402,8 +1401,6 @@ bool ED_mesh_pick_vert( } /* setup data */ - const Span verts = me->verts(); - data.mvert = verts.data(); data.region = region; data.mval_f = mval_f; data.len_best = FLT_MAX; diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index b2b24a88204..e53199c504f 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -1034,7 +1034,7 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets, const MLoop *loops = BKE_mesh_loops(me_eval); BKE_mesh_recalc_looptri(loops, BKE_mesh_polys(me_eval), - BKE_mesh_verts(me_eval), + BKE_mesh_vert_positions(me_eval), me_eval->totloop, me_eval->totpoly, looptri); diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index e8da35c25f4..dc5037d892d 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -95,6 +95,7 @@ #include "object_intern.h" +using blender::float3; using blender::Span; static CLG_LogRef LOG = {"ed.object"}; @@ -594,13 +595,13 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList * /*reports*/, me->totvert = verts_num; me->totedge = edges_num; - CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, verts_num); + CustomData_add_layer_named( + &me->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, verts_num, "position"); CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, edges_num); CustomData_add_layer(&me->fdata, CD_MFACE, CD_SET_DEFAULT, nullptr, 0); - blender::MutableSpan verts = me->verts_for_write(); + blender::MutableSpan positions = me->vert_positions_for_write(); blender::MutableSpan edges = me->edges_for_write(); - MVert *mvert = verts.data(); MEdge *medge = edges.data(); bke::MutableAttributeAccessor attributes = me->attributes_for_write(); @@ -614,7 +615,7 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList * /*reports*/, ParticleCacheKey *key = cache[a]; int kmax = key->segments; for (int k = 0; k <= kmax; k++, key++, cvert++, vert_index++) { - copy_v3_v3(mvert[vert_index].co, key->co); + positions[vert_index] = key->co; if (k) { medge->v1 = cvert - 1; medge->v2 = cvert; @@ -633,7 +634,7 @@ bool ED_object_modifier_convert_psys_to_mesh(ReportList * /*reports*/, ParticleCacheKey *key = cache[a]; int kmax = key->segments; for (int k = 0; k <= kmax; k++, key++, cvert++, vert_index++) { - copy_v3_v3(mvert[vert_index].co, key->co); + copy_v3_v3(positions[vert_index], key->co); if (k) { medge->v1 = cvert - 1; medge->v2 = cvert; @@ -713,7 +714,8 @@ static Mesh *create_applied_mesh_for_modifier(Depsgraph *depsgraph, if (build_shapekey_layers && me->key) { if (KeyBlock *kb = static_cast( BLI_findlink(&me->key->block, ob_eval->shapenr - 1))) { - BKE_keyblock_convert_to_mesh(kb, me->verts_for_write().data(), me->totvert); + BKE_keyblock_convert_to_mesh( + kb, reinterpret_cast(me->vert_positions_for_write().data()), me->totvert); } } @@ -2828,7 +2830,7 @@ void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot) } static void skin_armature_bone_create(Object *skin_ob, - const MVert *mvert, + const Span positions, const MEdge *medge, bArmature *arm, BLI_bitmap *edges_visited, @@ -2855,8 +2857,8 @@ static void skin_armature_bone_create(Object *skin_ob, bone->flag |= BONE_CONNECTED; } - copy_v3_v3(bone->head, mvert[parent_v].co); - copy_v3_v3(bone->tail, mvert[v].co); + copy_v3_v3(bone->head, positions[parent_v]); + copy_v3_v3(bone->tail, positions[v]); bone->rad_head = bone->rad_tail = 0.25; BLI_snprintf(bone->name, sizeof(bone->name), "Bone.%.2d", endx); @@ -2867,14 +2869,14 @@ static void skin_armature_bone_create(Object *skin_ob, ED_vgroup_vert_add(skin_ob, dg, v, 1, WEIGHT_REPLACE); } - skin_armature_bone_create(skin_ob, mvert, medge, arm, edges_visited, emap, bone, v); + skin_armature_bone_create(skin_ob, positions, medge, arm, edges_visited, emap, bone, v); } } static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, Object *skin_ob) { Mesh *me = static_cast(skin_ob->data); - const Span me_verts = me->verts(); + const Span me_positions = me->vert_positions(); const Span me_edges = me->edges(); Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); @@ -2882,7 +2884,7 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, const Mesh *me_eval_deform = mesh_get_eval_deform( depsgraph, scene_eval, ob_eval, &CD_MASK_BAREMESH); - const Span verts_eval = me_eval_deform->verts(); + const Span positions_eval = me_eval_deform->vert_positions(); /* add vertex weights to original mesh */ CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, nullptr, me->totvert); @@ -2917,8 +2919,8 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, if (emap[v].count > 1) { bone = ED_armature_ebone_add(arm, "Bone"); - copy_v3_v3(bone->head, me_verts[v].co); - copy_v3_v3(bone->tail, me_verts[v].co); + copy_v3_v3(bone->head, me_positions[v]); + copy_v3_v3(bone->tail, me_positions[v]); bone->head[1] = 1.0f; bone->rad_head = bone->rad_tail = 0.25; @@ -2926,7 +2928,7 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, if (emap[v].count >= 1) { skin_armature_bone_create( - skin_ob, verts_eval.data(), me_edges.data(), arm, edges_visited, emap, bone, v); + skin_ob, positions_eval, me_edges.data(), arm, edges_visited, emap, bone, v); } } } diff --git a/source/blender/editors/object/object_remesh.cc b/source/blender/editors/object/object_remesh.cc index db2769aac00..a808ca1337b 100644 --- a/source/blender/editors/object/object_remesh.cc +++ b/source/blender/editors/object/object_remesh.cc @@ -73,6 +73,7 @@ #include "object_intern.h" /* own include */ +using blender::float3; using blender::IndexRange; using blender::Span; @@ -675,7 +676,7 @@ static bool mesh_is_manifold_consistent(Mesh *mesh) * check that the direction of the faces are consistent and doesn't suddenly * flip */ - const Span verts = mesh->verts(); + const Span positions = mesh->vert_positions(); const Span edges = mesh->edges(); const Span loops = mesh->loops(); @@ -713,9 +714,7 @@ static bool mesh_is_manifold_consistent(Mesh *mesh) break; } /* Check for zero length edges */ - const MVert &v1 = verts[edges[i].v1]; - const MVert &v2 = verts[edges[i].v2]; - if (compare_v3v3(v1.co, v2.co, 1e-4f)) { + if (compare_v3v3(positions[edges[i].v1], positions[edges[i].v2], 1e-4f)) { is_manifold_consistent = false; break; } diff --git a/source/blender/editors/object/object_vgroup.cc b/source/blender/editors/object/object_vgroup.cc index 7be44795d63..0bb2a075e95 100644 --- a/source/blender/editors/object/object_vgroup.cc +++ b/source/blender/editors/object/object_vgroup.cc @@ -68,6 +68,7 @@ #include "object_intern.h" +using blender::float3; using blender::MutableSpan; using blender::Span; @@ -1286,12 +1287,12 @@ static blender::Vector getSurroundingVerts(Mesh *me, int vert) * coord is the place the average is stored, * points is the point cloud, count is the number of points in the cloud. */ -static void getSingleCoordinate(MVert *points, int count, float coord[3]) +static void getSingleCoordinate(float3 *points, int count, float coord[3]) { int i; zero_v3(coord); for (i = 0; i < count; i++) { - add_v3_v3(coord, points[i].co); + add_v3_v3(coord, points[i]); } mul_v3_fl(coord, 1.0f / count); } @@ -1357,7 +1358,7 @@ static void moveCloserToDistanceFromPlane(Depsgraph *depsgraph, Mesh *me_deform; MDeformWeight *dw, *dw_eval; - MVert m; + float3 m; MDeformVert *dvert = me->deform_verts_for_write().data() + index; MDeformVert *dvert_eval = mesh_eval->deform_verts_for_write().data() + index; int totweight = dvert->totweight; @@ -1382,9 +1383,9 @@ static void moveCloserToDistanceFromPlane(Depsgraph *depsgraph, do { wasChange = false; me_deform = mesh_get_eval_deform(depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH); - const Span verts = me_deform->verts(); - m = verts[index]; - copy_v3_v3(oldPos, m.co); + const Span positions = me_deform->vert_positions(); + m = positions[index]; + copy_v3_v3(oldPos, m); distToStart = dot_v3v3(norm, oldPos) + d; if (distToBe == originalDistToBe) { @@ -1425,9 +1426,8 @@ static void moveCloserToDistanceFromPlane(Depsgraph *depsgraph, } dw_eval->weight = dw->weight; me_deform = mesh_get_eval_deform(depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH); - m = verts[index]; - getVerticalAndHorizontalChange( - norm, d, coord, oldPos, distToStart, m.co, changes, dists, i); + m = positions[index]; + getVerticalAndHorizontalChange(norm, d, coord, oldPos, distToStart, m, changes, dists, i); dw->weight = oldw; dw_eval->weight = oldw; if (!k) { @@ -1531,28 +1531,27 @@ static void vgroup_fix( int i; Mesh *me = static_cast(ob->data); - MVert *mvert = me->verts_for_write().data(); if (!(me->editflag & ME_EDIT_PAINT_VERT_SEL)) { return; } const bke::AttributeAccessor attributes = me->attributes(); const VArray select_vert = attributes.lookup_or_default( ".select_vert", ATTR_DOMAIN_POINT, false); - for (i = 0; i < me->totvert && mvert; i++, mvert++) { + for (i = 0; i < me->totvert; i++) { if (select_vert[i]) { blender::Vector verts = getSurroundingVerts(me, i); const int count = verts.size(); if (!verts.is_empty()) { - MVert m; - MVert *p = static_cast(MEM_callocN(sizeof(MVert) * (count), "deformedPoints")); + float3 m; + float3 *p = static_cast(MEM_callocN(sizeof(float3) * (count), "deformedPoints")); int k; Mesh *me_deform = mesh_get_eval_deform( depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH); - const Span verts_deform = me_deform->verts(); + const Span positions_deform = me_deform->vert_positions(); k = count; while (k--) { - p[k] = verts_deform[verts[k]]; + p[k] = positions_deform[verts[k]]; } if (count >= 3) { @@ -1560,8 +1559,8 @@ static void vgroup_fix( float coord[3]; float norm[3]; getSingleCoordinate(p, count, coord); - m = verts_deform[i]; - sub_v3_v3v3(norm, m.co, coord); + m = positions_deform[i]; + sub_v3_v3v3(norm, m, coord); mag = normalize_v3(norm); if (mag) { /* zeros fix */ d = -dot_v3v3(norm, coord); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 22295c260e2..02569184541 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -1452,28 +1452,23 @@ void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *UNUSED(ob), Part vec = edit->emitter_cosnos; nor = vec + 3; - const MVert *verts = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); for (i = 0; i < totface; i++, vec += 6, nor += 6) { MFace *mface = &mfaces[i]; - const MVert *mvert; - mvert = &verts[mface->v1]; - copy_v3_v3(vec, mvert->co); + copy_v3_v3(vec, positions[mface->v1]); copy_v3_v3(nor, vert_normals[mface->v1]); - mvert = &verts[mface->v2]; - add_v3_v3v3(vec, vec, mvert->co); + add_v3_v3v3(vec, vec, positions[mface->v2]); add_v3_v3(nor, vert_normals[mface->v2]); - mvert = &verts[mface->v3]; - add_v3_v3v3(vec, vec, mvert->co); + add_v3_v3v3(vec, vec, positions[mface->v3]); add_v3_v3(nor, vert_normals[mface->v3]); if (mface->v4) { - mvert = &verts[mface->v4]; - add_v3_v3v3(vec, vec, mvert->co); + add_v3_v3v3(vec, vec, positions[mface->v4]); add_v3_v3(nor, vert_normals[mface->v4]); mul_v3_fl(vec, 0.25); @@ -4142,7 +4137,6 @@ static int particle_intersect_mesh(Depsgraph *depsgraph, float *ipoint) { MFace *mface = NULL; - MVert *mvert = NULL; int i, totface, intersect = 0; float cur_d, cur_uv[2], v1[3], v2[3], v3[3], v4[3], min[3], max[3], p_min[3], p_max[3]; float cur_ipoint[3]; @@ -4180,7 +4174,7 @@ static int particle_intersect_mesh(Depsgraph *depsgraph, totface = mesh->totface; mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); - mvert = BKE_mesh_verts_for_write(mesh); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); /* lets intersect the faces */ for (i = 0; i < totface; i++, mface++) { @@ -4193,11 +4187,11 @@ static int particle_intersect_mesh(Depsgraph *depsgraph, } } else { - copy_v3_v3(v1, mvert[mface->v1].co); - copy_v3_v3(v2, mvert[mface->v2].co); - copy_v3_v3(v3, mvert[mface->v3].co); + copy_v3_v3(v1, positions[mface->v1]); + copy_v3_v3(v2, positions[mface->v2]); + copy_v3_v3(v3, positions[mface->v3]); if (mface->v4) { - copy_v3_v3(v4, mvert[mface->v4].co); + copy_v3_v3(v4, positions[mface->v4]); } } diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 852156f9403..ebf030bad71 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -707,7 +707,6 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, BVHTreeFromMesh bvhtree = {NULL}; MFace *mface = NULL, *mf; const MEdge *medge = NULL, *me; - MVert *mvert; Mesh *mesh, *target_mesh; int numverts; int k; @@ -752,11 +751,11 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, BKE_mesh_tessface_ensure(mesh); numverts = mesh->totvert; - mvert = BKE_mesh_verts_for_write(mesh); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); /* convert to global coordinates */ for (int i = 0; i < numverts; i++) { - mul_m4_v3(to_mat, mvert[i].co); + mul_m4_v3(to_mat, positions[i]); } if (mesh->totface != 0) { @@ -803,11 +802,11 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, mf = &mface[nearest.index]; - copy_v3_v3(v[0], mvert[mf->v1].co); - copy_v3_v3(v[1], mvert[mf->v2].co); - copy_v3_v3(v[2], mvert[mf->v3].co); + copy_v3_v3(v[0], positions[mf->v1]); + copy_v3_v3(v[1], positions[mf->v2]); + copy_v3_v3(v[2], positions[mf->v3]); if (mf->v4) { - copy_v3_v3(v[3], mvert[mf->v4].co); + copy_v3_v3(v[3], positions[mf->v4]); interp_weights_poly_v3(tpa->fuv, v, 4, nearest.co); } else { @@ -827,7 +826,7 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, else { me = &medge[nearest.index]; - tpa->fuv[1] = line_point_factor_v3(nearest.co, mvert[me->v1].co, mvert[me->v2].co); + tpa->fuv[1] = line_point_factor_v3(nearest.co, positions[me->v1], positions[me->v2]); tpa->fuv[0] = 1.0f - tpa->fuv[1]; tpa->fuv[2] = tpa->fuv[3] = 0.0f; tpa->foffset = 0.0f; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc index 2da5a427aaa..4f7668e8e67 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_add.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_add.cc @@ -90,7 +90,7 @@ struct AddOperationExecutor { Object *surface_ob_eval_ = nullptr; Mesh *surface_eval_ = nullptr; - Span surface_verts_eval_; + Span surface_positions_eval_; Span surface_loops_eval_; Span surface_looptris_eval_; VArraySpan surface_uv_map_eval_; @@ -142,7 +142,7 @@ struct AddOperationExecutor { report_empty_evaluated_surface(stroke_extension.reports); return; } - surface_verts_eval_ = surface_eval_->verts(); + surface_positions_eval_ = surface_eval_->vert_positions(); surface_loops_eval_ = surface_eval_->loops(); surface_looptris_eval_ = surface_eval_->looptris(); BKE_bvhtree_from_mesh_get(&surface_bvh_eval_, surface_eval_, BVHTREE_FROM_LOOPTRI, 2); @@ -303,7 +303,7 @@ struct AddOperationExecutor { const MLoopTri &looptri = surface_looptris_eval_[looptri_index]; const float3 brush_pos_su = ray_hit.co; const float3 bary_coords = bke::mesh_surface_sample::compute_bary_coord_in_triangle( - surface_verts_eval_, surface_loops_eval_, looptri, brush_pos_su); + surface_positions_eval_, surface_loops_eval_, looptri, brush_pos_su); const float2 uv = bke::mesh_surface_sample::sample_corner_attrribute_with_bary_coords( bary_coords, looptri, surface_uv_map_eval_); @@ -428,9 +428,9 @@ struct AddOperationExecutor { brush_radius_su, [&](const int index, const float3 & /*co*/, const float /*dist_sq*/) { const MLoopTri &looptri = surface_looptris_eval_[index]; - const float3 v0_su = surface_verts_eval_[surface_loops_eval_[looptri.tri[0]].v].co; - const float3 v1_su = surface_verts_eval_[surface_loops_eval_[looptri.tri[1]].v].co; - const float3 v2_su = surface_verts_eval_[surface_loops_eval_[looptri.tri[2]].v].co; + const float3 &v0_su = surface_positions_eval_[surface_loops_eval_[looptri.tri[0]].v]; + const float3 &v1_su = surface_positions_eval_[surface_loops_eval_[looptri.tri[1]].v]; + const float3 &v2_su = surface_positions_eval_[surface_loops_eval_[looptri.tri[2]].v]; float3 normal_su; normal_tri_v3(normal_su, v0_su, v1_su, v2_su); if (math::dot(normal_su, view_direction_su) >= 0.0f) { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc index 5224385d4aa..2e84574bdae 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc @@ -70,7 +70,7 @@ struct PuffOperationExecutor { Object *surface_ob_ = nullptr; Mesh *surface_ = nullptr; - Span surface_verts_; + Span surface_positions_; Span surface_loops_; Span surface_looptris_; Span corner_normals_su_; @@ -120,7 +120,7 @@ struct PuffOperationExecutor { reinterpret_cast(CustomData_get_layer(&surface_->ldata, CD_NORMAL)), surface_->totloop}; - surface_verts_ = surface_->verts(); + surface_positions_ = surface_->vert_positions(); surface_loops_ = surface_->loops(); surface_looptris_ = surface_->looptris(); BKE_bvhtree_from_mesh_get(&surface_bvh_, surface_, BVHTREE_FROM_LOOPTRI, 2); @@ -292,9 +292,9 @@ struct PuffOperationExecutor { const MLoopTri &looptri = surface_looptris_[nearest.index]; const float3 closest_pos_su = nearest.co; - const float3 &v0_su = surface_verts_[surface_loops_[looptri.tri[0]].v].co; - const float3 &v1_su = surface_verts_[surface_loops_[looptri.tri[1]].v].co; - const float3 &v2_su = surface_verts_[surface_loops_[looptri.tri[2]].v].co; + const float3 &v0_su = surface_positions_[surface_loops_[looptri.tri[0]].v]; + const float3 &v1_su = surface_positions_[surface_loops_[looptri.tri[1]].v]; + const float3 &v2_su = surface_positions_[surface_loops_[looptri.tri[2]].v]; float3 bary_coords; interp_weights_tri_v3(bary_coords, v0_su, v1_su, v2_su, closest_pos_su); const float3 normal_su = geometry::compute_surface_point_normal( diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc index 0ac70f51d8a..f21813d777c 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc @@ -104,7 +104,7 @@ struct SlideOperationExecutor { Object *surface_ob_eval_ = nullptr; Mesh *surface_eval_ = nullptr; - Span surface_verts_eval_; + Span surface_positions_eval_; Span surface_loops_eval_; Span surface_looptris_eval_; VArraySpan surface_uv_map_eval_; @@ -198,7 +198,7 @@ struct SlideOperationExecutor { return; } surface_looptris_eval_ = surface_eval_->looptris(); - surface_verts_eval_ = surface_eval_->verts(); + surface_positions_eval_ = surface_eval_->vert_positions(); surface_loops_eval_ = surface_eval_->loops(); surface_uv_map_eval_ = surface_eval_->attributes().lookup(uv_map_name, ATTR_DOMAIN_CORNER); @@ -315,7 +315,7 @@ struct SlideOperationExecutor { { const float4x4 brush_transform_inv = brush_transform.inverted(); - const Span verts_orig_su = surface_orig_->verts(); + const Span positions_orig_su = surface_orig_->vert_positions(); const Span loops_orig = surface_orig_->loops(); MutableSpan positions_orig_cu = curves_orig_->positions_for_write(); @@ -379,7 +379,7 @@ struct SlideOperationExecutor { /* Compute the uv of the new surface position on the evaluated mesh. */ const MLoopTri &looptri_eval = surface_looptris_eval_[looptri_index_eval]; const float3 bary_weights_eval = bke::mesh_surface_sample::compute_bary_coord_in_triangle( - surface_verts_eval_, surface_loops_eval_, looptri_eval, hit_pos_eval_su); + surface_positions_eval_, surface_loops_eval_, looptri_eval, hit_pos_eval_su); const float2 uv = attribute_math::mix3(bary_weights_eval, surface_uv_map_eval_[looptri_eval.tri[0]], surface_uv_map_eval_[looptri_eval.tri[1]], @@ -406,9 +406,9 @@ struct SlideOperationExecutor { const float3 new_first_pos_orig_cu = transforms_.surface_to_curves * attribute_math::mix3(bary_weights_orig, - verts_orig_su[loops_orig[looptri_orig.tri[0]].v].co, - verts_orig_su[loops_orig[looptri_orig.tri[1]].v].co, - verts_orig_su[loops_orig[looptri_orig.tri[2]].v].co); + positions_orig_su[loops_orig[looptri_orig.tri[0]].v], + positions_orig_su[loops_orig[looptri_orig.tri[1]].v], + positions_orig_su[loops_orig[looptri_orig.tri[2]].v]); /* Actually transform curve points. */ const float4x4 slide_transform = this->get_slide_transform( diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index 9e435ee0748..09fcbef2180 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -68,14 +68,13 @@ static void partialvis_update_mesh(Object *ob, float planes[4][4]) { Mesh *me = ob->data; - MVert *mvert; + const float(*positions)[3] = BKE_pbvh_get_vert_positions(pbvh); const float *paint_mask; - const int *vert_indices; int totvert, i; bool any_changed = false, any_visible = false; BKE_pbvh_node_num_verts(pbvh, node, NULL, &totvert); - BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert); + const int *vert_indices = BKE_pbvh_node_get_vert_indices(node); paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK); bool *hide_vert = CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".hide_vert"); @@ -87,11 +86,10 @@ static void partialvis_update_mesh(Object *ob, SCULPT_undo_push_node(ob, node, SCULPT_UNDO_HIDDEN); for (i = 0; i < totvert; i++) { - MVert *v = &mvert[vert_indices[i]]; float vmask = paint_mask ? paint_mask[vert_indices[i]] : 0; /* Hide vertex if in the hide volume. */ - if (is_effected(area, planes, v->co, vmask)) { + if (is_effected(area, planes, positions[vert_indices[i]], vmask)) { hide_vert[vert_indices[i]] = (action == PARTIALVIS_HIDE); any_changed = true; } diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.cc b/source/blender/editors/sculpt_paint/paint_image_proj.cc index 61aa984c1af..fd797e2b00a 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.cc +++ b/source/blender/editors/sculpt_paint/paint_image_proj.cc @@ -412,7 +412,7 @@ struct ProjPaintState { int totedge_eval; int totvert_eval; - const MVert *mvert_eval; + const float (*vert_positions_eval)[3]; const float (*vert_normals)[3]; const MEdge *medge_eval; const MPoly *mpoly_eval; @@ -931,9 +931,9 @@ static bool project_bucket_point_occluded(const ProjPaintState *ps, if (do_clip) { const float *vtri_co[3] = { - ps->mvert_eval[ps->mloop_eval[lt->tri[0]].v].co, - ps->mvert_eval[ps->mloop_eval[lt->tri[1]].v].co, - ps->mvert_eval[ps->mloop_eval[lt->tri[2]].v].co, + ps->vert_positions_eval[ps->mloop_eval[lt->tri[0]].v], + ps->vert_positions_eval[ps->mloop_eval[lt->tri[1]].v], + ps->vert_positions_eval[ps->mloop_eval[lt->tri[2]].v], }; isect_ret = project_paint_occlude_ptv_clip( pixelScreenCo, UNPACK3(vtri_ss), UNPACK3(vtri_co), w, ps->is_ortho, ps->rv3d); @@ -1745,9 +1745,9 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps, /* In case the normalizing per pixel isn't optimal, * we could cache or access from evaluated mesh. */ normal_tri_v3(no, - ps->mvert_eval[lt_vtri[0]].co, - ps->mvert_eval[lt_vtri[1]].co, - ps->mvert_eval[lt_vtri[2]].co); + ps->vert_positions_eval[lt_vtri[0]], + ps->vert_positions_eval[lt_vtri[1]], + ps->vert_positions_eval[lt_vtri[2]]); } if (UNLIKELY(ps->is_flip_object)) { @@ -1762,9 +1762,9 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps, /* Annoying but for the perspective view we need to get the pixels location in 3D space :/ */ float viewDirPersp[3]; const float *co1, *co2, *co3; - co1 = ps->mvert_eval[lt_vtri[0]].co; - co2 = ps->mvert_eval[lt_vtri[1]].co; - co3 = ps->mvert_eval[lt_vtri[2]].co; + co1 = ps->vert_positions_eval[lt_vtri[0]]; + co2 = ps->vert_positions_eval[lt_vtri[1]]; + co3 = ps->vert_positions_eval[lt_vtri[2]]; /* Get the direction from the viewPoint to the pixel and normalize */ viewDirPersp[0] = (ps->viewPos[0] - (w[0] * co1[0] + w[1] * co2[0] + w[2] * co3[0])); @@ -3043,9 +3043,9 @@ static void project_paint_face_init(const ProjPaintState *ps, const bool do_backfacecull = ps->do_backfacecull; const bool do_clip = RV3D_CLIPPING_ENABLED(ps->v3d, ps->rv3d); - vCo[0] = ps->mvert_eval[lt_vtri[0]].co; - vCo[1] = ps->mvert_eval[lt_vtri[1]].co; - vCo[2] = ps->mvert_eval[lt_vtri[2]].co; + vCo[0] = ps->vert_positions_eval[lt_vtri[0]]; + vCo[1] = ps->vert_positions_eval[lt_vtri[1]]; + vCo[2] = ps->vert_positions_eval[lt_vtri[2]]; /* Use lt_uv_pxoffset instead of lt_tri_uv so we can offset the UV half a pixel * this is done so we can avoid offsetting all the pixels by 0.5 which causes @@ -3142,9 +3142,9 @@ static void project_paint_face_init(const ProjPaintState *ps, * because it is a relatively expensive operation. */ if (do_clip || do_3d_mapping) { interp_v3_v3v3v3(wco, - ps->mvert_eval[lt_vtri[0]].co, - ps->mvert_eval[lt_vtri[1]].co, - ps->mvert_eval[lt_vtri[2]].co, + ps->vert_positions_eval[lt_vtri[0]], + ps->vert_positions_eval[lt_vtri[1]], + ps->vert_positions_eval[lt_vtri[2]], w); if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, true)) { /* Watch out that no code below this needs to run */ @@ -3803,7 +3803,6 @@ static void proj_paint_state_viewport_init(ProjPaintState *ps, const char symmet static void proj_paint_state_screen_coords_init(ProjPaintState *ps, const int diameter) { - const MVert *mv; float *projScreenCo; float projMargin; int a; @@ -3815,8 +3814,8 @@ static void proj_paint_state_screen_coords_init(ProjPaintState *ps, const int di projScreenCo = *ps->screenCoords; if (ps->is_ortho) { - for (a = 0, mv = ps->mvert_eval; a < ps->totvert_eval; a++, mv++, projScreenCo += 4) { - mul_v3_m4v3(projScreenCo, ps->projectMat, mv->co); + for (a = 0; a < ps->totvert_eval; a++, projScreenCo += 4) { + mul_v3_m4v3(projScreenCo, ps->projectMat, ps->vert_positions_eval[a]); /* screen space, not clamped */ projScreenCo[0] = float(ps->winx * 0.5f) + (ps->winx * 0.5f) * projScreenCo[0]; @@ -3825,8 +3824,8 @@ static void proj_paint_state_screen_coords_init(ProjPaintState *ps, const int di } } else { - for (a = 0, mv = ps->mvert_eval; a < ps->totvert_eval; a++, mv++, projScreenCo += 4) { - copy_v3_v3(projScreenCo, mv->co); + for (a = 0; a < ps->totvert_eval; a++, projScreenCo += 4) { + copy_v3_v3(projScreenCo, ps->vert_positions_eval[a]); projScreenCo[3] = 1.0f; mul_m4_v4(ps->projectMat, projScreenCo); @@ -3897,7 +3896,7 @@ static void proj_paint_state_cavity_init(ProjPaintState *ps) for (a = 0, me = ps->medge_eval; a < ps->totedge_eval; a++, me++) { float e[3]; - sub_v3_v3v3(e, ps->mvert_eval[me->v1].co, ps->mvert_eval[me->v2].co); + sub_v3_v3v3(e, ps->vert_positions_eval[me->v1], ps->vert_positions_eval[me->v2]); normalize_v3(e); add_v3_v3(edges[me->v2], e); counter[me->v2]++; @@ -3969,13 +3968,12 @@ static void proj_paint_state_vert_flags_init(ProjPaintState *ps) { if (ps->do_backfacecull && ps->do_mask_normal) { float viewDirPersp[3]; - const MVert *mv; float no[3]; int a; ps->vertFlags = MEM_cnew_array(ps->totvert_eval, "paint-vertFlags"); - for (a = 0, mv = ps->mvert_eval; a < ps->totvert_eval; a++, mv++) { + for (a = 0; a < ps->totvert_eval; a++) { copy_v3_v3(no, ps->vert_normals[a]); if (UNLIKELY(ps->is_flip_object)) { negate_v3(no); @@ -3988,7 +3986,7 @@ static void proj_paint_state_vert_flags_init(ProjPaintState *ps) } } else { - sub_v3_v3v3(viewDirPersp, ps->viewPos, mv->co); + sub_v3_v3v3(viewDirPersp, ps->viewPos, ps->vert_positions_eval[a]); normalize_v3(viewDirPersp); if (UNLIKELY(ps->is_flip_object)) { negate_v3(viewDirPersp); @@ -4076,7 +4074,7 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p } ps->mat_array[totmat - 1] = nullptr; - ps->mvert_eval = BKE_mesh_verts(ps->me_eval); + ps->vert_positions_eval = BKE_mesh_vert_positions(ps->me_eval); ps->vert_normals = BKE_mesh_vertex_normals_ensure(ps->me_eval); if (ps->do_mask_cavity) { ps->medge_eval = BKE_mesh_edges(ps->me_eval); @@ -5716,9 +5714,9 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po UnifiedPaintSettings *ups = &ps->scene->toolsettings->unified_paint_settings; interp_v3_v3v3v3(world, - ps->mvert_eval[lt_vtri[0]].co, - ps->mvert_eval[lt_vtri[1]].co, - ps->mvert_eval[lt_vtri[2]].co, + ps->vert_positions_eval[lt_vtri[0]], + ps->vert_positions_eval[lt_vtri[1]], + ps->vert_positions_eval[lt_vtri[2]], w); ups->average_stroke_counter++; diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index ad9ae6b4349..eff24ceb0b3 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -1148,7 +1148,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex const float(*ob_imat)[4] = vc->obact->world_to_object; /* Write vertices coordinates for the front face. */ - MVert *verts = BKE_mesh_verts_for_write(trim_operation->mesh); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(trim_operation->mesh); float depth_point[3]; madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_front); for (int i = 0; i < tot_screen_points; i++) { @@ -1160,7 +1160,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point); madd_v3_v3fl(new_point, shape_normal, depth_front); } - mul_v3_m4v3(verts[i].co, ob_imat, new_point); + mul_v3_m4v3(positions[i], ob_imat, new_point); mul_v3_m4v3(trim_operation->true_mesh_co[i], ob_imat, new_point); } @@ -1175,7 +1175,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point); madd_v3_v3fl(new_point, shape_normal, depth_back); } - mul_v3_m4v3(verts[i + tot_screen_points].co, ob_imat, new_point); + mul_v3_m4v3(positions[i + tot_screen_points], ob_imat, new_point); mul_v3_m4v3(trim_operation->true_mesh_co[i + tot_screen_points], ob_imat, new_point); } @@ -1362,9 +1362,9 @@ static void sculpt_gesture_trim_apply_for_symmetry_pass(bContext *UNUSED(C), { SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; Mesh *trim_mesh = trim_operation->mesh; - MVert *verts = BKE_mesh_verts_for_write(trim_mesh); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(trim_mesh); for (int i = 0; i < trim_mesh->totvert; i++) { - flip_v3_v3(verts[i].co, trim_operation->true_mesh_co[i], sgcontext->symmpass); + flip_v3_v3(positions[i], trim_operation->true_mesh_co[i], sgcontext->symmpass); } sculpt_gesture_trim_normals_update(sgcontext); sculpt_gesture_apply_trim(sgcontext); @@ -1473,7 +1473,7 @@ static void project_line_gesture_apply_task_cb(void *__restrict userdata, continue; } add_v3_v3(vd.co, disp); - if (vd.mvert) { + if (vd.vert_positions) { BKE_pbvh_vert_tag_update_normal(sgcontext->ss->pbvh, vd.vertex); } any_updated = true; diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index f87ca073c82..0a8dbd58b2a 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -288,7 +288,7 @@ static void imapaint_pick_uv( const MLoopTri *lt = BKE_mesh_runtime_looptri_ensure(me_eval); const int tottri = BKE_mesh_runtime_looptri_len(me_eval); - const MVert *mvert = BKE_mesh_verts(me_eval); + const float(*positions)[3] = BKE_mesh_vert_positions(me_eval); const MLoop *mloop = BKE_mesh_loops(me_eval); const int *index_mp_to_orig = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX); @@ -317,7 +317,7 @@ static void imapaint_pick_uv( float tri_co[3][3]; for (int j = 3; j--;) { - copy_v3_v3(tri_co[j], mvert[mloop[lt->tri[j]].v].co); + copy_v3_v3(tri_co[j], positions[mloop[lt->tri[j]].v]); } if (mode == PAINT_CANVAS_SOURCE_MATERIAL) { diff --git a/source/blender/editors/sculpt_paint/paint_vertex.cc b/source/blender/editors/sculpt_paint/paint_vertex.cc index db23fc564f6..4469e4ca647 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.cc +++ b/source/blender/editors/sculpt_paint/paint_vertex.cc @@ -2072,7 +2072,7 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata, * Otherwise, take the current vert. */ const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; - const MVert *mv_curr = &ss->mvert[v_index]; + const float3 &mv_curr = ss->vert_positions[v_index]; /* If the vertex is selected */ if (!(use_face_sel || use_vert_sel) || select_vert[v_index]) { @@ -2099,11 +2099,11 @@ static void do_wpaint_brush_smear_task_cb_ex(void *__restrict userdata, for (int k = 0; k < mp->totloop; k++, ml_other++) { const uint v_other_index = ml_other->v; if (v_other_index != v_index) { - const MVert *mv_other = &ss->mvert[v_other_index]; + const float3 &mv_other = ss->vert_positions[v_other_index]; /* Get the direction from the selected vert to the neighbor. */ float other_dir[3]; - sub_v3_v3v3(other_dir, mv_curr->co, mv_other->co); + sub_v3_v3v3(other_dir, mv_curr, mv_other); project_plane_v3_v3v3(other_dir, other_dir, cache->view_normal); normalize_v3(other_dir); @@ -3307,7 +3307,7 @@ static void do_vpaint_brush_smear(bContext *C, const int v_index = has_grids ? ss->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i]; const float grid_alpha = has_grids ? 1.0f / vd.gridsize : 1.0f; - const MVert *mv_curr = &ss->mvert[v_index]; + const float3 &mv_curr = &ss->vert_positions[v_index]; /* if the vertex is selected for painting. */ if (!use_vert_sel || select_vert[v_index]) { @@ -3344,12 +3344,12 @@ static void do_vpaint_brush_smear(bContext *C, for (int k = 0; k < mp->totloop; k++, ml_other++) { const uint v_other_index = ml_other->v; if (v_other_index != v_index) { - const MVert *mv_other = &ss->mvert[v_other_index]; + const float3 &mv_other = &ss->vert_positions[v_other_index]; /* Get the direction from the * selected vert to the neighbor. */ float other_dir[3]; - sub_v3_v3v3(other_dir, mv_curr->co, mv_other->co); + sub_v3_v3v3(other_dir, mv_curr, mv_other); project_plane_v3_v3v3(other_dir, other_dir, cache->view_normal); normalize_v3(other_dir); diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 899044145d3..e1586e00788 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -73,6 +73,7 @@ #include "bmesh.h" +using blender::float3; using blender::MutableSpan; /* -------------------------------------------------------------------- */ @@ -112,10 +113,10 @@ const float *SCULPT_vertex_co_get(SculptSession *ss, PBVHVertRef vertex) switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { if (ss->shapekey_active || ss->deform_modifiers_active) { - const MVert *mverts = BKE_pbvh_get_verts(ss->pbvh); - return mverts[vertex.i].co; + const float(*positions)[3] = BKE_pbvh_get_vert_positions(ss->pbvh); + return positions[vertex.i]; } - return ss->mvert[vertex.i].co; + return ss->vert_positions[vertex.i]; } case PBVH_BMESH: return ((BMVert *)vertex.i)->co; @@ -201,12 +202,12 @@ const float *SCULPT_vertex_co_for_grab_active_get(SculptSession *ss, PBVHVertRef if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) { /* Always grab active shape key if the sculpt happens on shapekey. */ if (ss->shapekey_active) { - const MVert *mverts = BKE_pbvh_get_verts(ss->pbvh); - return mverts[vertex.i].co; + const float(*positions)[3] = BKE_pbvh_get_vert_positions(ss->pbvh); + return positions[vertex.i]; } /* Sculpting on the base mesh. */ - return ss->mvert[vertex.i].co; + return ss->vert_positions[vertex.i]; } /* Everything else, such as sculpting on multires. */ @@ -287,14 +288,14 @@ void SCULPT_active_vertex_normal_get(SculptSession *ss, float normal[3]) SCULPT_vertex_normal_get(ss, SCULPT_active_vertex_get(ss), normal); } -MVert *SCULPT_mesh_deformed_mverts_get(SculptSession *ss) +float (*SCULPT_mesh_deformed_positions_get(SculptSession *ss))[3] { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: if (ss->shapekey_active || ss->deform_modifiers_active) { - return BKE_pbvh_get_verts(ss->pbvh); + return BKE_pbvh_get_vert_positions(ss->pbvh); } - return ss->mvert; + return ss->vert_positions; case PBVH_BMESH: case PBVH_GRIDS: return nullptr; @@ -1576,7 +1577,7 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata, else { copy_v3_v3(vd.fno, orig_vert_data.no); } - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -3232,7 +3233,7 @@ static void do_gravity_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], offset, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -3300,12 +3301,7 @@ void SCULPT_vertcos_to_key(Object *ob, KeyBlock *kb, const float (*vertCos)[3]) /* Modifying of basis key should update mesh. */ if (kb == me->key->refkey) { - MVert *verts = BKE_mesh_verts_for_write(me); - - for (a = 0; a < me->totvert; a++) { - copy_v3_v3(verts[a].co, vertCos[a]); - } - BKE_mesh_tag_coords_changed(me); + BKE_mesh_vert_coords_apply(me, vertCos); } /* Apply new coords on active key block, no need to re-allocate kb->data here! */ @@ -3718,7 +3714,7 @@ static void do_brush_action(Sculpt *sd, /* Flush displacement from deformed PBVH vertex to original mesh. */ static void sculpt_flush_pbvhvert_deform(const SculptSession &ss, const PBVHVertexIter &vd, - MutableSpan verts) + MutableSpan positions) { float disp[3], newco[3]; int index = vd.vert_indices[vd.i]; @@ -3731,7 +3727,7 @@ static void sculpt_flush_pbvhvert_deform(const SculptSession &ss, copy_v3_v3(ss.orig_cos[index], newco); if (!ss.shapekey_active) { - copy_v3_v3(verts[index].co, newco); + copy_v3_v3(positions[index], newco); } } @@ -3752,7 +3748,7 @@ static void sculpt_combine_proxies_node(Object &object, BKE_pbvh_node_get_proxies(&node, &proxies, &proxy_count); Mesh &mesh = *static_cast(object.data); - MutableSpan verts = mesh.verts_for_write(); + MutableSpan positions = mesh.vert_positions_for_write(); PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, &node, vd, PBVH_ITER_UNIQUE) { @@ -3777,7 +3773,7 @@ static void sculpt_combine_proxies_node(Object &object, SCULPT_clip(&sd, ss, vd.co, val); if (ss->deform_modifiers_active) { - sculpt_flush_pbvhvert_deform(*ss, vd, verts); + sculpt_flush_pbvhvert_deform(*ss, vd, positions); } } BKE_pbvh_vertex_iter_end; @@ -3889,13 +3885,13 @@ void SCULPT_flush_stroke_deform(Sculpt * /*sd*/, Object *ob, bool is_proxy_used) BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); - MutableSpan verts = me->verts_for_write(); + MutableSpan positions = me->vert_positions_for_write(); threading::parallel_for(IndexRange(totnode), 1, [&](IndexRange range) { for (const int i : range) { PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, nodes[i], vd, PBVH_ITER_UNIQUE) { - sculpt_flush_pbvhvert_deform(*ss, vd, verts); + sculpt_flush_pbvhvert_deform(*ss, vd, positions); if (!vertCos) { continue; diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c index 2bf6110dca0..967a4331ecd 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.c +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c @@ -698,7 +698,7 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata, angle * boundary->edit_info[vd.index].strength_factor * mask * automask); add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -749,7 +749,7 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata, boundary->edit_info[vd.index].strength_factor * disp * mask * automask * strength); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -800,7 +800,7 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata, boundary->edit_info[vd.index].strength_factor * disp * mask * automask * strength); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -848,7 +848,7 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata, ss->cache->grab_delta_symmetry, boundary->edit_info[vd.index].strength_factor * mask * automask * strength); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -907,7 +907,7 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata, angle * mask * automask * boundary->edit_info[vd.index].strength_factor); add_v3_v3(target_co, boundary->twist.pivot_position); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -966,7 +966,7 @@ static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata, madd_v3_v3v3fl( target_co, vd.co, disp, boundary->edit_info[vd.index].strength_factor * mask * strength); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_brush_types.c b/source/blender/editors/sculpt_paint/sculpt_brush_types.c index 666fa884e03..c24bdba662a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_brush_types.c +++ b/source/blender/editors/sculpt_paint/sculpt_brush_types.c @@ -279,7 +279,7 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], offset, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -384,7 +384,7 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], val, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -489,7 +489,7 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], val, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -614,7 +614,7 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], val, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -776,7 +776,7 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], val, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -940,7 +940,7 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], val, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -1074,7 +1074,7 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], val, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -1283,7 +1283,7 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, copy_v3_v3(proxy[vd.i], disp); } - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -1376,7 +1376,7 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], cono, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -1462,7 +1462,7 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata, add_v3_v3(proxy[vd.i], ss->cache->location); sub_v3_v3(proxy[vd.i], orig_data.co); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -1586,7 +1586,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, SCULPT_clip(sd, ss, vd.co, final_co); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -1666,7 +1666,7 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata, mul_v3_fl(val, fade * ss->cache->radius); mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -1732,7 +1732,7 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], cono, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -1833,7 +1833,7 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata, add_v3_v3v3(proxy[vd.i], val1, val2); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -1959,7 +1959,7 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata, } mul_v3_v3fl(proxy[vd.i], disp_center, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -2075,7 +2075,7 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], grab_delta, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -2190,7 +2190,7 @@ static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata, copy_v3_v3(proxy[vd.i], final_disp); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -2275,7 +2275,7 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], offset, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -2395,7 +2395,7 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], final_disp, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -2528,7 +2528,7 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata, &automask_data); SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -2616,7 +2616,7 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata, sub_v3_v3v3(disp, limit_co, vd.co); mul_v3_v3fl(proxy[vd.i], disp, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -2735,7 +2735,7 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata, add_v3_v3v3(new_co, ss->cache->limit_surface_co[vd.index], interp_limit_surface_disp); interp_v3_v3v3(vd.co, vd.co, new_co, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -2863,7 +2863,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata, SCULPT_clip(sd, ss, vd.co, val); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c index cf7e1d027f7..a5c469ca3a0 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c @@ -635,12 +635,12 @@ static void cloth_brush_collision_cb(void *userdata, ClothBrushCollision *col = (ClothBrushCollision *)userdata; CollisionModifierData *col_data = col->col_data; MVertTri *verttri = &col_data->tri[index]; - MVert *mverts = col_data->x; + float(*positions)[3] = col_data->x; float *tri[3], no[3], co[3]; - tri[0] = mverts[verttri->tri[0]].co; - tri[1] = mverts[verttri->tri[1]].co; - tri[2] = mverts[verttri->tri[2]].co; + tri[0] = positions[verttri->tri[0]]; + tri[1] = positions[verttri->tri[1]]; + tri[2] = positions[verttri->tri[2]]; float dist = 0.0f; bool tri_hit = isect_ray_tri_watertight_v3( @@ -783,7 +783,7 @@ static void do_cloth_brush_solve_simulation_task_cb_ex( copy_v3_v3(vd.co, cloth_sim->pos[vd.index]); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c index 388f4111555..192a4545e94 100644 --- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c +++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c @@ -314,7 +314,7 @@ enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob) UNUSED_VARS_NDEBUG(ss); for (int i = 0; i < CD_NUMTYPES; i++) { - if (!ELEM(i, CD_MVERT, CD_MEDGE, CD_MFACE, CD_MLOOP, CD_MPOLY, CD_PAINT_MASK, CD_ORIGINDEX)) { + if (!ELEM(i, CD_MEDGE, CD_MFACE, CD_MLOOP, CD_MPOLY, CD_PAINT_MASK, CD_ORIGINDEX)) { if (CustomData_has_layer(&me->vdata, i)) { flag |= DYNTOPO_WARN_VDATA; } diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index 7253a41f97f..584e4d20d2b 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -120,7 +120,7 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, ss, &test, data->brush->falloff_shape); const int thread_id = BLI_task_parallel_thread_id(tls); - MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss); + const float(*positions)[3] = SCULPT_mesh_deformed_positions_get(ss); AutomaskingNodeData automask_data; SCULPT_automasking_node_begin( data->ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]); @@ -135,7 +135,7 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, const MPoly *p = &ss->mpoly[vert_map->indices[j]]; float poly_center[3]; - BKE_mesh_calc_poly_center(p, &ss->mloop[p->loopstart], mvert, poly_center); + BKE_mesh_calc_poly_center(p, &ss->mloop[p->loopstart], positions, poly_center); if (!sculpt_brush_test_sq_fn(&test, poly_center)) { continue; @@ -237,7 +237,7 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata, &automask_data); SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -1253,8 +1253,8 @@ static void sculpt_face_set_edit_fair_face_set(Object *ob, SCULPT_vertex_has_unique_face_set(ss, vertex); } - MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss); - BKE_mesh_prefair_and_fair_verts(mesh, mvert, fair_verts, fair_order); + float(*positions)[3] = SCULPT_mesh_deformed_positions_get(ss); + BKE_mesh_prefair_and_fair_verts(mesh, positions, fair_verts, fair_order); MEM_freeN(fair_verts); } diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c index e677b565a10..f6bf9c0c488 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c @@ -530,7 +530,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, add_v3_v3v3(final_pos, orig_co, disp); } copy_v3_v3(vd.co, final_pos); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_geodesic.c b/source/blender/editors/sculpt_paint/sculpt_geodesic.c index 5d74853be8c..89cf2fda27e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_geodesic.c +++ b/source/blender/editors/sculpt_paint/sculpt_geodesic.c @@ -34,8 +34,12 @@ #define SCULPT_GEODESIC_VERTEX_NONE -1 /* Propagate distance from v1 and v2 to v0. */ -static bool sculpt_geodesic_mesh_test_dist_add( - MVert *mvert, const int v0, const int v1, const int v2, float *dists, GSet *initial_verts) +static bool sculpt_geodesic_mesh_test_dist_add(const float (*vert_positions)[3], + const int v0, + const int v1, + const int v2, + float *dists, + GSet *initial_verts) { if (BLI_gset_haskey(initial_verts, POINTER_FROM_INT(v0))) { return false; @@ -53,11 +57,11 @@ static bool sculpt_geodesic_mesh_test_dist_add( return false; } dist0 = geodesic_distance_propagate_across_triangle( - mvert[v0].co, mvert[v1].co, mvert[v2].co, dists[v1], dists[v2]); + vert_positions[v0], vert_positions[v1], vert_positions[v2], dists[v1], dists[v2]); } else { float vec[3]; - sub_v3_v3v3(vec, mvert[v1].co, mvert[v0].co); + sub_v3_v3v3(vec, vert_positions[v1], vert_positions[v0]); dist0 = dists[v1] + len_v3(vec); } @@ -81,7 +85,7 @@ static float *SCULPT_geodesic_mesh_create(Object *ob, const float limit_radius_sq = limit_radius * limit_radius; - MVert *verts = SCULPT_mesh_deformed_mverts_get(ss); + float(*vert_positions)[3] = SCULPT_mesh_deformed_positions_get(ss); const MEdge *edges = BKE_mesh_edges(mesh); const MPoly *polys = BKE_mesh_polys(mesh); const MLoop *loops = BKE_mesh_loops(mesh); @@ -135,9 +139,9 @@ static float *SCULPT_geodesic_mesh_create(Object *ob, * number of vertices (usually just 1 or 2). */ GSET_ITER (gs_iter, initial_verts) { const int v = POINTER_AS_INT(BLI_gsetIterator_getKey(&gs_iter)); - float *v_co = verts[v].co; + float *v_co = vert_positions[v]; for (int i = 0; i < totvert; i++) { - if (len_squared_v3v3(v_co, verts[i].co) <= limit_radius_sq) { + if (len_squared_v3v3(v_co, vert_positions[i]) <= limit_radius_sq) { BLI_BITMAP_ENABLE(affected_vertex, i); } } @@ -167,7 +171,7 @@ static float *SCULPT_geodesic_mesh_create(Object *ob, SWAP(int, v1, v2); } sculpt_geodesic_mesh_test_dist_add( - verts, v2, v1, SCULPT_GEODESIC_VERTEX_NONE, dists, initial_verts); + vert_positions, v2, v1, SCULPT_GEODESIC_VERTEX_NONE, dists, initial_verts); } if (ss->epmap[e].count != 0) { @@ -184,7 +188,8 @@ static float *SCULPT_geodesic_mesh_create(Object *ob, if (ELEM(v_other, v1, v2)) { continue; } - if (sculpt_geodesic_mesh_test_dist_add(verts, v_other, v1, v2, dists, initial_verts)) { + if (sculpt_geodesic_mesh_test_dist_add( + vert_positions, v_other, v1, v2, dists, initial_verts)) { for (int edge_map_index = 0; edge_map_index < ss->vemap[v_other].count; edge_map_index++) { const int e_other = ss->vemap[v_other].indices[edge_map_index]; diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index ae23983e6c9..6a6fce851e7 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -1004,7 +1004,7 @@ void SCULPT_active_vertex_normal_get(SculptSession *ss, float normal[3]); /* Returns PBVH deformed vertices array if shape keys or deform modifiers are used, otherwise * returns mesh original vertices array. */ -struct MVert *SCULPT_mesh_deformed_mverts_get(SculptSession *ss); +float (*SCULPT_mesh_deformed_positions_get(SculptSession *ss))[3]; /* Fake Neighbors */ diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c index fd8f5b8945c..ccee7814f83 100644 --- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c +++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c @@ -201,7 +201,7 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], val, fade); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc index 6244cf8e33d..75c84c48f77 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc +++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc @@ -124,7 +124,7 @@ template class PaintingKernel { SculptSession *ss; const Brush *brush; const int thread_id; - const MVert *mvert; + const float3 *vert_positions_; float4 brush_color; float brush_strength; @@ -139,8 +139,11 @@ template class PaintingKernel { explicit PaintingKernel(SculptSession *ss, const Brush *brush, const int thread_id, - const MVert *mvert) - : ss(ss), brush(brush), thread_id(thread_id), mvert(mvert) + const float (*positions)[3]) + : ss(ss), + brush(brush), + thread_id(thread_id), + vert_positions_(reinterpret_cast(positions)) { init_brush_strength(); init_brush_test(); @@ -268,9 +271,9 @@ template class PaintingKernel { barycentric_weights.y, 1.0f - barycentric_weights.x - barycentric_weights.y); interp_v3_v3v3v3(result, - mvert[vert_indices[0]].co, - mvert[vert_indices[1]].co, - mvert[vert_indices[2]].co, + vert_positions_[vert_indices[0]], + vert_positions_[vert_indices[1]], + vert_positions_[vert_indices[2]], barycentric); return result; } @@ -279,7 +282,7 @@ template class PaintingKernel { static std::vector init_uv_primitives_brush_test(SculptSession *ss, PaintGeometryPrimitives &geom_primitives, PaintUVPrimitives &uv_primitives, - const MVert *mvert) + const float (*positions)[3]) { std::vector brush_test(uv_primitives.size()); SculptBrushTest test; @@ -295,10 +298,10 @@ static std::vector init_uv_primitives_brush_test(SculptSession *ss, const int3 &vert_indices = geom_primitives.get_vert_indices( paint_input.geometry_primitive_index); - float3 triangle_min_bounds(mvert[vert_indices[0]].co); + float3 triangle_min_bounds(positions[vert_indices[0]]); float3 triangle_max_bounds(triangle_min_bounds); for (int i = 1; i < 3; i++) { - const float3 &pos = mvert[vert_indices[i]].co; + const float3 &pos = positions[vert_indices[i]]; triangle_min_bounds.x = min_ff(triangle_min_bounds.x, pos.x); triangle_min_bounds.y = min_ff(triangle_min_bounds.y, pos.y); triangle_min_bounds.z = min_ff(triangle_min_bounds.z, pos.z); @@ -325,13 +328,13 @@ static void do_paint_pixels(void *__restrict userdata, PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(*pbvh); NodeData &node_data = BKE_pbvh_pixels_node_data_get(*node); const int thread_id = BLI_task_parallel_thread_id(tls); - MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss); + const float(*positions)[3] = SCULPT_mesh_deformed_positions_get(ss); std::vector brush_test = init_uv_primitives_brush_test( - ss, pbvh_data.geom_primitives, node_data.uv_primitives, mvert); + ss, pbvh_data.geom_primitives, node_data.uv_primitives, positions); - PaintingKernel kernel_float4(ss, brush, thread_id, mvert); - PaintingKernel kernel_byte4(ss, brush, thread_id, mvert); + PaintingKernel kernel_float4(ss, brush, thread_id, positions); + PaintingKernel kernel_byte4(ss, brush, thread_id, positions); AutomaskingNodeData automask_data; SCULPT_automasking_node_begin(ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]); diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c index 5f671c1f0e1..389a548fb2d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_pose.c +++ b/source/blender/editors/sculpt_paint/sculpt_pose.c @@ -193,7 +193,7 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata, float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); copy_v3_v3(target_co, final_pos); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c index 09b1c69da45..5af8381f6da 100644 --- a/source/blender/editors/sculpt_paint/sculpt_smooth.c +++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c @@ -221,7 +221,7 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata, madd_v3_v3v3fl(disp, vd.co, ss->cache->detail_directions[vd.index], fade); SCULPT_clip(sd, ss, vd.co, disp); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -319,7 +319,7 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata, sub_v3_v3v3(val, avg, vd.co); madd_v3_v3v3fl(val, vd.co, val, fade); SCULPT_clip(sd, ss, vd.co, val); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -489,7 +489,7 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex( SCULPT_surface_smooth_laplacian_step( ss, disp, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.vertex, orig_data.co, alpha); madd_v3_v3fl(vd.co, disp, clamp_f(fade, 0.0f, 1.0f)); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c index 0463e8adbaf..b8ee3404159 100644 --- a/source/blender/editors/sculpt_paint/sculpt_transform.c +++ b/source/blender/editors/sculpt_paint/sculpt_transform.c @@ -173,7 +173,7 @@ static void sculpt_transform_task_cb(void *__restrict userdata, mul_v3_fl(disp, 1.0f - fade); add_v3_v3v3(vd.co, start_co, disp); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } @@ -247,7 +247,7 @@ static void sculpt_elastic_transform_task_cb(void *__restrict userdata, copy_v3_v3(proxy[vd.i], final_disp); - if (vd.mvert) { + if (vd.is_mesh) { BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index e5cb9c924b6..4b971fa6663 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -320,9 +320,8 @@ static void update_cb_partial(PBVHNode *node, void *userdata) BKE_pbvh_node_mark_update(node); } int verts_num; - const int *vert_indices; BKE_pbvh_node_num_verts(data->pbvh, node, NULL, &verts_num); - BKE_pbvh_node_get_verts(data->pbvh, node, &vert_indices, NULL); + const int *vert_indices = BKE_pbvh_node_get_vert_indices(node); if (data->modified_mask_verts != NULL) { for (int i = 0; i < verts_num; i++) { if (data->modified_mask_verts[vert_indices[i]]) { @@ -391,7 +390,6 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt Object *ob = BKE_view_layer_active_object_get(view_layer); SculptSession *ss = ob->sculpt; SubdivCCG *subdiv_ccg = ss->subdiv_ccg; - MVert *mvert; int *index; if (unode->maxvert) { @@ -417,7 +415,7 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt /* No need for float comparison here (memory is exactly equal or not). */ index = unode->index; - mvert = ss->mvert; + float(*positions)[3] = ss->vert_positions; if (ss->shapekey_active) { float(*vertCos)[3]; @@ -444,7 +442,7 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt /* Propagate new coords to keyblock. */ SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos); - /* PBVH uses its own mvert array, so coords should be */ + /* PBVH uses its own vertex array, so coords should be */ /* propagated to PBVH here. */ BKE_pbvh_vert_coords_apply(ss->pbvh, vertCos, ss->shapekey_active->totelem); @@ -454,20 +452,20 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt if (unode->orig_co) { if (ss->deform_modifiers_active) { for (int i = 0; i < unode->totvert; i++) { - sculpt_undo_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co); + sculpt_undo_restore_deformed(ss, unode, i, index[i], positions[index[i]]); BKE_pbvh_vert_tag_update_normal(ss->pbvh, BKE_pbvh_make_vref(index[i])); } } else { for (int i = 0; i < unode->totvert; i++) { - swap_v3_v3(mvert[index[i]].co, unode->orig_co[i]); + swap_v3_v3(positions[index[i]], unode->orig_co[i]); BKE_pbvh_vert_tag_update_normal(ss->pbvh, BKE_pbvh_make_vref(index[i])); } } } else { for (int i = 0; i < unode->totvert; i++) { - swap_v3_v3(mvert[index[i]].co, unode->co[i]); + swap_v3_v3(positions[index[i]], unode->co[i]); BKE_pbvh_vert_tag_update_normal(ss->pbvh, BKE_pbvh_make_vref(index[i])); } } @@ -1463,12 +1461,10 @@ static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode) /* Already stored during allocation. */ } else { - MVert *mvert; - const int *vert_indices; int allvert; BKE_pbvh_node_num_verts(pbvh, node, NULL, &allvert); - BKE_pbvh_node_get_verts(pbvh, node, &vert_indices, &mvert); + const int *vert_indices = BKE_pbvh_node_get_vert_indices(node); for (int i = 0; i < allvert; i++) { BLI_BITMAP_SET(unode->vert_hidden, i, hide_vert[vert_indices[i]]); } @@ -1656,11 +1652,11 @@ SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType memcpy(unode->grids, grids, sizeof(int) * totgrid); } else { - const int *vert_indices, *loop_indices; + const int *loop_indices; int allvert, allloop; BKE_pbvh_node_num_verts(ss->pbvh, unode->node, NULL, &allvert); - BKE_pbvh_node_get_verts(ss->pbvh, node, &vert_indices, NULL); + const int *vert_indices = BKE_pbvh_node_get_vert_indices(node); memcpy(unode->index, vert_indices, sizeof(int) * allvert); if (unode->loop_index) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 6370d56ae8c..f19464e4e1e 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -69,7 +69,7 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, if (facemap_data) { GPU_blend(GPU_BLEND_ALPHA); - const MVert *verts = BKE_mesh_verts(me); + const float(*positions)[3] = BKE_mesh_vert_positions(me); const MPoly *polys = BKE_mesh_polys(me); const MLoop *loops = BKE_mesh_loops(me); @@ -100,9 +100,9 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, for (mp = polys, i = 0; i < mpoly_len; i++, mp++) { if (facemap_data[i] == facemap) { for (int j = 2; j < mp->totloop; j++) { - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[loops[mlt->tri[0]].v].co); - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[loops[mlt->tri[1]].v].co); - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[loops[mlt->tri[2]].v].co); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), positions[loops[mlt->tri[0]].v]); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), positions[loops[mlt->tri[1]].v]); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), positions[loops[mlt->tri[2]].v]); vbo_len_used += 3; mlt++; } @@ -120,9 +120,9 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, const MLoop *ml_a = ml_start + 1; const MLoop *ml_b = ml_start + 2; for (int j = 2; j < mp->totloop; j++) { - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[ml_start->v].co); - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[ml_a->v].co); - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), verts[ml_b->v].co); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), positions[ml_start->v]); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), positions[ml_a->v]); + copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), positions[ml_b->v]); vbo_len_used += 3; ml_a++; diff --git a/source/blender/editors/space_view3d/view3d_iterators.cc b/source/blender/editors/space_view3d/view3d_iterators.cc index aaa817ec00c..f35fbf5c944 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.cc +++ b/source/blender/editors/space_view3d/view3d_iterators.cc @@ -203,10 +203,9 @@ static bool view3d_project_segment_to_screen_with_clip_tag(const ARegion *region * \{ */ struct foreachScreenObjectVert_userData { - void (*func)(void *userData, MVert *mv, const float screen_co[2], int index); + void (*func)(void *userData, const float screen_co[2], int index); void *userData; ViewContext vc; - MVert *verts; const bool *hide_vert; eV3DProjTest clip_flag; }; @@ -269,7 +268,6 @@ static void meshobject_foreachScreenVert__mapFunc(void *userData, if (data->hide_vert && data->hide_vert[index]) { return; } - MVert *mv = &data->verts[index]; float screen_co[2]; @@ -278,14 +276,15 @@ static void meshobject_foreachScreenVert__mapFunc(void *userData, return; } - data->func(data->userData, mv, screen_co, index); + data->func(data->userData, screen_co, index); } -void meshobject_foreachScreenVert( - ViewContext *vc, - void (*func)(void *userData, MVert *eve, const float screen_co[2], int index), - void *userData, - eV3DProjTest clip_flag) +void meshobject_foreachScreenVert(ViewContext *vc, + void (*func)(void *userData, + const float screen_co[2], + int index), + void *userData, + eV3DProjTest clip_flag) { BLI_assert((clip_flag & V3D_PROJ_TEST_CLIP_CONTENT) == 0); foreachScreenObjectVert_userData data; @@ -302,7 +301,6 @@ void meshobject_foreachScreenVert( data.func = func; data.userData = userData; data.clip_flag = clip_flag; - data.verts = BKE_mesh_verts_for_write((Mesh *)vc->obact->data); data.hide_vert = (const bool *)CustomData_get_layer_named( &me->vdata, CD_PROP_BOOL, ".hide_vert"); diff --git a/source/blender/editors/space_view3d/view3d_select.cc b/source/blender/editors/space_view3d/view3d_select.cc index 51b64f7ca04..45222642023 100644 --- a/source/blender/editors/space_view3d/view3d_select.cc +++ b/source/blender/editors/space_view3d/view3d_select.cc @@ -1170,7 +1170,6 @@ struct LassoSelectUserData_ForMeshVert { blender::MutableSpan select_vert; }; static void do_lasso_select_meshobject__doSelectVert(void *userData, - MVert * /*mv*/, const float screen_co[2], int index) { @@ -3196,7 +3195,6 @@ struct BoxSelectUserData_ForMeshVert { blender::MutableSpan select_vert; }; static void do_paintvert_box_select__doSelectVert(void *userData, - MVert * /*mv*/, const float screen_co[2], int index) { @@ -4216,7 +4214,6 @@ struct CircleSelectUserData_ForMeshVert { blender::MutableSpan select_vert; }; static void paint_vertsel_circle_select_doSelectVert(void *userData, - MVert * /*mv*/, const float screen_co[2], int index) { diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index 71ddddc1d41..d55de8909a5 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -241,7 +241,7 @@ static void snap_object_data_mesh_get(SnapObjectContext *sctx, bool use_hide, BVHTreeFromMesh *r_treedata) { - const Span verts = me_eval->verts(); + const Span vert_positions = me_eval->vert_positions(); const Span polys = me_eval->polys(); const Span loops = me_eval->loops(); @@ -254,12 +254,13 @@ static void snap_object_data_mesh_get(SnapObjectContext *sctx, BKE_bvhtree_from_mesh_get( r_treedata, me_eval, use_hide ? BVHTREE_FROM_LOOPTRI_NO_HIDDEN : BVHTREE_FROM_LOOPTRI, 4); - BLI_assert(r_treedata->vert == verts.data()); + BLI_assert(reinterpret_cast(r_treedata->vert_positions) == + vert_positions.data()); BLI_assert(r_treedata->loop == loops.data()); BLI_assert(!polys.data() || r_treedata->looptri); BLI_assert(!r_treedata->tree || r_treedata->looptri); - UNUSED_VARS_NDEBUG(verts, polys, loops); + UNUSED_VARS_NDEBUG(vert_positions, polys, loops); } /* Searches for the #Mesh_Runtime associated with the object that is most likely to be updated due @@ -620,12 +621,12 @@ static void mesh_looptri_raycast_backface_culling_cb(void *userdata, BVHTreeRayHit *hit) { const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; - const MVert *vert = data->vert; + const float(*vert_positions)[3] = data->vert_positions; const MLoopTri *lt = &data->looptri[index]; const float *vtri_co[3] = { - vert[data->loop[lt->tri[0]].v].co, - vert[data->loop[lt->tri[1]].v].co, - vert[data->loop[lt->tri[2]].v].co, + vert_positions[data->loop[lt->tri[0]].v], + vert_positions[data->loop[lt->tri[1]].v], + vert_positions[data->loop[lt->tri[2]].v], }; float dist = bvhtree_ray_tri_intersection(ray, hit->dist, UNPACK3(vtri_co)); @@ -1424,7 +1425,7 @@ struct Nearest2dUserData { BMesh *bm; }; struct { - const MVert *vert; + const float (*vert_positions)[3]; const float (*vert_normals)[3]; const MEdge *edge; /* only used for #BVHTreeFromMeshEdges */ const MLoop *loop; @@ -1438,7 +1439,7 @@ struct Nearest2dUserData { static void cb_mvert_co_get(const int index, const Nearest2dUserData *data, const float **r_co) { - *r_co = data->vert[index].co; + *r_co = data->vert_positions[index]; } static void cb_bvert_co_get(const int index, const Nearest2dUserData *data, const float **r_co) @@ -1713,7 +1714,7 @@ static void nearest2d_data_init_mesh(const Mesh *mesh, r_nearest2d->get_tri_verts_index = cb_mlooptri_verts_get; r_nearest2d->get_tri_edges_index = cb_mlooptri_edges_get; - r_nearest2d->vert = mesh->verts().data(); + r_nearest2d->vert_positions = BKE_mesh_vert_positions(mesh); r_nearest2d->vert_normals = BKE_mesh_vertex_normals_ensure(mesh); r_nearest2d->edge = mesh->edges().data(); r_nearest2d->loop = mesh->loops().data(); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 0f8830a4521..47c66be0634 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -619,7 +619,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, Mesh *subdiv_mesh = subdivide_edit_mesh(ob, em, &smd); - const MVert *subsurfedVerts = BKE_mesh_verts(subdiv_mesh); + const float(*subsurfedPositions)[3] = BKE_mesh_vert_positions(subdiv_mesh); const MEdge *subsurfedEdges = BKE_mesh_edges(subdiv_mesh); const MPoly *subsurfedPolys = BKE_mesh_polys(subdiv_mesh); const MLoop *subsurfedLoops = BKE_mesh_loops(subdiv_mesh); @@ -679,10 +679,10 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, vkeys[2] = (ParamKey)mloop[2].v; vkeys[3] = (ParamKey)mloop[3].v; - co[0] = subsurfedVerts[mloop[0].v].co; - co[1] = subsurfedVerts[mloop[1].v].co; - co[2] = subsurfedVerts[mloop[2].v].co; - co[3] = subsurfedVerts[mloop[3].v].co; + co[0] = subsurfedPositions[mloop[0].v]; + co[1] = subsurfedPositions[mloop[1].v]; + co[2] = subsurfedPositions[mloop[2].v]; + co[3] = subsurfedPositions[mloop[3].v]; /* This is where all the magic is done. * If the vertex exists in the, we pass the original uv pointer to the solver, thus diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 53c2b1d235b..0752b1a7b91 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -14,6 +14,7 @@ #include +using blender::float3; using blender::Span; namespace Freestyle { @@ -401,15 +402,19 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) { char *name = ob->id.name + 2; - const Span mesh_verts = me->verts(); + const Span vert_positions = me->vert_positions(); const Span mesh_polys = me->polys(); const Span mesh_loops = me->loops(); // Compute loop triangles int tottri = poly_to_tri_count(me->totpoly, me->totloop); MLoopTri *mlooptri = (MLoopTri *)MEM_malloc_arrayN(tottri, sizeof(*mlooptri), __func__); - BKE_mesh_recalc_looptri( - mesh_loops.data(), mesh_polys.data(), mesh_verts.data(), me->totloop, me->totpoly, mlooptri); + BKE_mesh_recalc_looptri(mesh_loops.data(), + mesh_polys.data(), + reinterpret_cast(vert_positions.data()), + me->totloop, + me->totpoly, + mlooptri); // Compute loop normals BKE_mesh_calc_normals_split(me); @@ -444,9 +449,9 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) for (int a = 0; a < tottri; a++) { const MLoopTri *lt = &mlooptri[a]; - copy_v3_v3(v1, mesh_verts[mesh_loops[lt->tri[0]].v].co); - copy_v3_v3(v2, mesh_verts[mesh_loops[lt->tri[1]].v].co); - copy_v3_v3(v3, mesh_verts[mesh_loops[lt->tri[2]].v].co); + copy_v3_v3(v1, vert_positions[mesh_loops[lt->tri[0]].v]); + copy_v3_v3(v2, vert_positions[mesh_loops[lt->tri[1]].v]); + copy_v3_v3(v3, vert_positions[mesh_loops[lt->tri[2]].v]); mul_m4_v3(obmat, v1); mul_m4_v3(obmat, v2); @@ -517,9 +522,9 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) const MPoly *mp = &mesh_polys[lt->poly]; Material *mat = BKE_object_material_get(ob, material_indices[lt->poly] + 1); - copy_v3_v3(v1, mesh_verts[mesh_loops[lt->tri[0]].v].co); - copy_v3_v3(v2, mesh_verts[mesh_loops[lt->tri[1]].v].co); - copy_v3_v3(v3, mesh_verts[mesh_loops[lt->tri[2]].v].co); + copy_v3_v3(v1, vert_positions[mesh_loops[lt->tri[0]].v]); + copy_v3_v3(v2, vert_positions[mesh_loops[lt->tri[1]].v]); + copy_v3_v3(v3, vert_positions[mesh_loops[lt->tri[2]].v]); mul_m4_v3(obmat, v1); mul_m4_v3(obmat, v2); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index fa93a44af66..ea47359aa2a 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -56,6 +56,8 @@ #include +using blender::float3; + namespace Freestyle { const char *BlenderStrokeRenderer::uvNames[] = {"along_stroke", "along_stroke_tips"}; @@ -578,8 +580,8 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex) mesh->totloop = group->totloop; mesh->totcol = group->materials.size(); - MVert *verts = (MVert *)CustomData_add_layer( - &mesh->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, mesh->totvert); + float3 *vert_positions = (float3 *)CustomData_add_layer_named( + &mesh->vdata, CD_PROP_FLOAT3, CD_SET_DEFAULT, nullptr, mesh->totvert, "position"); MEdge *edges = (MEdge *)CustomData_add_layer( &mesh->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, mesh->totedge); MPoly *polys = (MPoly *)CustomData_add_layer( @@ -666,19 +668,17 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex) else { if (!visible) { // first vertex - verts->co[0] = svRep[0]->point2d()[0]; - verts->co[1] = svRep[0]->point2d()[1]; - verts->co[2] = get_stroke_vertex_z(); + vert_positions[vertex_index][0] = svRep[0]->point2d()[0]; + vert_positions[vertex_index][1] = svRep[0]->point2d()[1]; + vert_positions[vertex_index][2] = get_stroke_vertex_z(); - ++verts; ++vertex_index; // second vertex - verts->co[0] = svRep[1]->point2d()[0]; - verts->co[1] = svRep[1]->point2d()[1]; - verts->co[2] = get_stroke_vertex_z(); + vert_positions[vertex_index][0] = svRep[1]->point2d()[0]; + vert_positions[vertex_index][1] = svRep[1]->point2d()[1]; + vert_positions[vertex_index][2] = get_stroke_vertex_z(); - ++verts; ++vertex_index; // first edge @@ -690,10 +690,9 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex) visible = true; // vertex - verts->co[0] = svRep[2]->point2d()[0]; - verts->co[1] = svRep[2]->point2d()[1]; - verts->co[2] = get_stroke_vertex_z(); - ++verts; + vert_positions[vertex_index][0] = svRep[2]->point2d()[0]; + vert_positions[vertex_index][1] = svRep[2]->point2d()[1]; + vert_positions[vertex_index][2] = get_stroke_vertex_z(); ++vertex_index; // edges diff --git a/source/blender/geometry/intern/add_curves_on_mesh.cc b/source/blender/geometry/intern/add_curves_on_mesh.cc index 55f0398fd3c..0b66b00937e 100644 --- a/source/blender/geometry/intern/add_curves_on_mesh.cc +++ b/source/blender/geometry/intern/add_curves_on_mesh.cc @@ -246,7 +246,7 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, Vector used_uvs; /* Find faces that the passed in uvs belong to. */ - const Span surface_verts = inputs.surface->verts(); + const Span surface_positions = inputs.surface->vert_positions(); const Span surface_loops = inputs.surface->loops(); for (const int i : inputs.uvs.index_range()) { const float2 &uv = inputs.uvs[i]; @@ -260,9 +260,9 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, looptris.append(&looptri); const float3 root_position_su = attribute_math::mix3( result.bary_weights, - surface_verts[surface_loops[looptri.tri[0]].v].co, - surface_verts[surface_loops[looptri.tri[1]].v].co, - surface_verts[surface_loops[looptri.tri[2]].v].co); + surface_positions[surface_loops[looptri.tri[0]].v], + surface_positions[surface_loops[looptri.tri[1]].v], + surface_positions[surface_loops[looptri.tri[2]].v]); root_positions_cu.append(inputs.transforms->surface_to_curves * root_position_su); used_uvs.append(uv); } diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc index 145be5a1b8a..b9addd8dd57 100644 --- a/source/blender/geometry/intern/mesh_merge_by_distance.cc +++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc @@ -1274,7 +1274,6 @@ static void customdata_weld( int src_i, dest_i; int j; - float co[3] = {0.0f, 0.0f, 0.0f}; short flag = 0; /* interpolates a layer at a time */ @@ -1297,14 +1296,7 @@ static void customdata_weld( /* if we found a matching layer, add the data */ if (dest->layers[dest_i].type == type) { void *src_data = source->layers[src_i].data; - - if (type == CD_MVERT) { - for (j = 0; j < count; j++) { - MVert *mv_src = &((MVert *)src_data)[src_indices[j]]; - add_v3_v3(co, mv_src->co); - } - } - else if (type == CD_MEDGE) { + if (type == CD_MEDGE) { for (j = 0; j < count; j++) { MEdge *me_src = &((MEdge *)src_data)[src_indices[j]]; flag |= me_src->flag; @@ -1340,13 +1332,7 @@ static void customdata_weld( for (dest_i = 0; dest_i < dest->totlayer; dest_i++) { CustomDataLayer *layer_dst = &dest->layers[dest_i]; const int type = layer_dst->type; - if (type == CD_MVERT) { - MVert *mv = &((MVert *)layer_dst->data)[dest_index]; - mul_v3_fl(co, fac); - - copy_v3_v3(mv->co, co); - } - else if (type == CD_MEDGE) { + if (type == CD_MEDGE) { MEdge *me = &((MEdge *)layer_dst->data)[dest_index]; me->flag = flag; } @@ -1578,9 +1564,9 @@ std::optional mesh_merge_by_distance_all(const Mesh &mesh, KDTree_3d *tree = BLI_kdtree_3d_new(selection.size()); - const Span verts = mesh.verts(); + const Span positions = mesh.vert_positions(); for (const int i : selection) { - BLI_kdtree_3d_insert(tree, i, verts[i].co); + BLI_kdtree_3d_insert(tree, i, positions[i]); } BLI_kdtree_3d_balance(tree); @@ -1605,7 +1591,7 @@ std::optional mesh_merge_by_distance_connected(const Mesh &mesh, const float merge_distance, const bool only_loose_edges) { - const Span verts = mesh.verts(); + const Span positions = mesh.vert_positions(); const Span edges = mesh.edges(); int vert_kill_len = 0; @@ -1616,9 +1602,9 @@ std::optional mesh_merge_by_distance_connected(const Mesh &mesh, Array vert_clusters(mesh.totvert); - for (const int i : verts.index_range()) { + for (const int i : positions.index_range()) { WeldVertexCluster &vc = vert_clusters[i]; - copy_v3_v3(vc.co, verts[i].co); + copy_v3_v3(vc.co, positions[i]); vc.merged_verts = 0; } const float merge_dist_sq = square_f(merge_distance); diff --git a/source/blender/geometry/intern/mesh_primitive_cuboid.cc b/source/blender/geometry/intern/mesh_primitive_cuboid.cc index a014c488a3b..4471ddf7297 100644 --- a/source/blender/geometry/intern/mesh_primitive_cuboid.cc +++ b/source/blender/geometry/intern/mesh_primitive_cuboid.cc @@ -54,7 +54,7 @@ struct CuboidConfig { } }; -static void calculate_verts(const CuboidConfig &config, MutableSpan verts) +static void calculate_positions(const CuboidConfig &config, MutableSpan positions) { const float z_bottom = -config.size.z / 2.0f; const float z_delta = config.size.z / config.edges_z; @@ -75,7 +75,7 @@ static void calculate_verts(const CuboidConfig &config, MutableSpan verts const float y_pos = y_front + y_delta * y; for (const int x : IndexRange(config.verts_x)) { const float x_pos = x_left + x_delta * x; - copy_v3_v3(verts[vert_index++].co, float3(x_pos, y_pos, z_pos)); + copy_v3_v3(positions[vert_index++], float3(x_pos, y_pos, z_pos)); } } } @@ -87,7 +87,7 @@ static void calculate_verts(const CuboidConfig &config, MutableSpan verts const float z_pos = z_bottom + z_delta * z; for (const int x : IndexRange(config.verts_x)) { const float x_pos = x_left + x_delta * x; - copy_v3_v3(verts[vert_index++].co, float3(x_pos, y_pos, z_pos)); + copy_v3_v3(positions[vert_index++], float3(x_pos, y_pos, z_pos)); } } else { @@ -95,9 +95,9 @@ static void calculate_verts(const CuboidConfig &config, MutableSpan verts const float x_pos = x_left; const float y_pos = y_front + y_delta * y; const float z_pos = z_bottom + z_delta * z; - copy_v3_v3(verts[vert_index++].co, float3(x_pos, y_pos, z_pos)); + copy_v3_v3(positions[vert_index++], float3(x_pos, y_pos, z_pos)); const float x_pos2 = x_left + x_delta * config.edges_x; - copy_v3_v3(verts[vert_index++].co, float3(x_pos2, y_pos, z_pos)); + copy_v3_v3(positions[vert_index++], float3(x_pos2, y_pos, z_pos)); } } } @@ -405,11 +405,11 @@ Mesh *create_cuboid_mesh(const float3 &size, Mesh *mesh = BKE_mesh_new_nomain( config.vertex_count, 0, 0, config.loop_count, config.poly_count); - MutableSpan verts = mesh->verts_for_write(); + MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); - calculate_verts(config, verts); + calculate_positions(config, positions); calculate_polys(config, polys, loops); BKE_mesh_calc_edges(mesh, false, false); diff --git a/source/blender/geometry/intern/mesh_to_curve_convert.cc b/source/blender/geometry/intern/mesh_to_curve_convert.cc index 722f1db0fb4..06bef16dec7 100644 --- a/source/blender/geometry/intern/mesh_to_curve_convert.cc +++ b/source/blender/geometry/intern/mesh_to_curve_convert.cc @@ -77,7 +77,7 @@ struct CurveFromEdgesOutput { IndexRange cyclic_curves; }; -static CurveFromEdgesOutput edges_to_curve_point_indices(Span verts, +static CurveFromEdgesOutput edges_to_curve_point_indices(const int verts_num, Span> edges) { Vector vert_indices; @@ -85,22 +85,22 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(Span verts, Vector curve_offsets; /* Compute the number of edges connecting to each vertex. */ - Array neighbor_count(verts.size(), 0); + Array neighbor_count(verts_num, 0); for (const std::pair &edge : edges) { neighbor_count[edge.first]++; neighbor_count[edge.second]++; } /* Compute an offset into the array of neighbor edges based on the counts. */ - Array neighbor_offsets(verts.size()); + Array neighbor_offsets(verts_num); int start = 0; - for (const int i : verts.index_range()) { + for (const int i : IndexRange(verts_num)) { neighbor_offsets[i] = start; start += neighbor_count[i]; } /* Use as an index into the "neighbor group" for each vertex. */ - Array used_slots(verts.size(), 0); + Array used_slots(verts_num, 0); /* Calculate the indices of each vertex's neighboring edges. */ Array neighbors(edges.size() * 2); for (const int i : edges.index_range()) { @@ -115,7 +115,7 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(Span verts, /* Now use the neighbor group offsets calculated above as a count used edges at each vertex. */ Array unused_edges = std::move(used_slots); - for (const int start_vert : verts.index_range()) { + for (const int start_vert : IndexRange(verts_num)) { /* The vertex will be part of a cyclic curve. */ if (neighbor_count[start_vert] == 2) { continue; @@ -163,7 +163,7 @@ static CurveFromEdgesOutput edges_to_curve_point_indices(Span verts, const int cyclic_start = curve_offsets.size(); /* All remaining edges are part of cyclic curves (we skipped vertices with two edges before). */ - for (const int start_vert : verts.index_range()) { + for (const int start_vert : IndexRange(verts_num)) { if (unused_edges[start_vert] != 2) { continue; } @@ -216,8 +216,7 @@ bke::CurvesGeometry mesh_to_curve_convert( const bke::AnonymousAttributePropagationInfo &propagation_info) { Vector> selected_edges = get_selected_edges(mesh, selection); - const Span verts = mesh.verts(); - CurveFromEdgesOutput output = edges_to_curve_point_indices(verts, selected_edges); + CurveFromEdgesOutput output = edges_to_curve_point_indices(mesh.totvert, selected_edges); return create_curve_from_vert_indices( mesh, output.vert_indices, output.curve_offsets, output.cyclic_curves, propagation_info); diff --git a/source/blender/geometry/intern/mesh_to_volume.cc b/source/blender/geometry/intern/mesh_to_volume.cc index b6025f8f1a9..12a4a95bd71 100644 --- a/source/blender/geometry/intern/mesh_to_volume.cc +++ b/source/blender/geometry/intern/mesh_to_volume.cc @@ -16,7 +16,7 @@ namespace blender::geometry { /* This class follows the MeshDataAdapter interface from openvdb. */ class OpenVDBMeshAdapter { private: - Span verts_; + Span positions_; Span loops_; Span looptris_; float4x4 transform_; @@ -30,7 +30,10 @@ class OpenVDBMeshAdapter { }; OpenVDBMeshAdapter::OpenVDBMeshAdapter(const Mesh &mesh, float4x4 transform) - : verts_(mesh.verts()), loops_(mesh.loops()), looptris_(mesh.looptris()), transform_(transform) + : positions_(mesh.vert_positions()), + loops_(mesh.loops()), + looptris_(mesh.looptris()), + transform_(transform) { } @@ -41,7 +44,7 @@ size_t OpenVDBMeshAdapter::polygonCount() const size_t OpenVDBMeshAdapter::pointCount() const { - return size_t(verts_.size()); + return size_t(positions_.size()); } size_t OpenVDBMeshAdapter::vertexCount(size_t /*polygon_index*/) const @@ -55,8 +58,7 @@ void OpenVDBMeshAdapter::getIndexSpacePoint(size_t polygon_index, openvdb::Vec3d &pos) const { const MLoopTri &looptri = looptris_[polygon_index]; - const MVert &vertex = verts_[loops_[looptri.tri[vertex_index]].v]; - const float3 transformed_co = transform_ * float3(vertex.co); + const float3 transformed_co = transform_ * positions_[loops_[looptri.tri[vertex_index]].v]; pos = &transformed_co.x; } diff --git a/source/blender/geometry/intern/realize_instances.cc b/source/blender/geometry/intern/realize_instances.cc index 760427fd7e6..5c1f0605d24 100644 --- a/source/blender/geometry/intern/realize_instances.cc +++ b/source/blender/geometry/intern/realize_instances.cc @@ -100,7 +100,7 @@ struct MeshElementStartIndices { struct MeshRealizeInfo { const Mesh *mesh = nullptr; - Span verts; + Span positions; Span edges; Span polys; Span loops; @@ -890,7 +890,7 @@ static AllMeshesInfo preprocess_meshes(const GeometrySet &geometry_set, MeshRealizeInfo &mesh_info = info.realize_info[mesh_index]; const Mesh *mesh = info.order[mesh_index]; mesh_info.mesh = mesh; - mesh_info.verts = mesh->verts(); + mesh_info.positions = mesh->vert_positions(); mesh_info.edges = mesh->edges(); mesh_info.polys = mesh->polys(); mesh_info.loops = mesh->loops(); @@ -936,7 +936,7 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options, const RealizeMeshTask &task, const OrderedAttributes &ordered_attributes, MutableSpan dst_attribute_writers, - MutableSpan all_dst_verts, + MutableSpan all_dst_positions, MutableSpan all_dst_edges, MutableSpan all_dst_polys, MutableSpan all_dst_loops, @@ -946,27 +946,24 @@ static void execute_realize_mesh_task(const RealizeInstancesOptions &options, const MeshRealizeInfo &mesh_info = *task.mesh_info; const Mesh &mesh = *mesh_info.mesh; - const Span src_verts = mesh_info.verts; + const Span src_positions = mesh_info.positions; const Span src_edges = mesh_info.edges; const Span src_polys = mesh_info.polys; const Span src_loops = mesh_info.loops; - const IndexRange dst_vert_range(task.start_indices.vertex, src_verts.size()); + const IndexRange dst_vert_range(task.start_indices.vertex, src_positions.size()); const IndexRange dst_edge_range(task.start_indices.edge, src_edges.size()); const IndexRange dst_poly_range(task.start_indices.poly, src_polys.size()); const IndexRange dst_loop_range(task.start_indices.loop, src_loops.size()); - MutableSpan dst_verts = all_dst_verts.slice(dst_vert_range); + MutableSpan dst_positions = all_dst_positions.slice(dst_vert_range); MutableSpan dst_edges = all_dst_edges.slice(dst_edge_range); MutableSpan dst_polys = all_dst_polys.slice(dst_poly_range); MutableSpan dst_loops = all_dst_loops.slice(dst_loop_range); - threading::parallel_for(src_verts.index_range(), 1024, [&](const IndexRange vert_range) { + threading::parallel_for(src_positions.index_range(), 1024, [&](const IndexRange vert_range) { for (const int i : vert_range) { - const MVert &src_vert = src_verts[i]; - MVert &dst_vert = dst_verts[i]; - dst_vert = src_vert; - copy_v3_v3(dst_vert.co, task.transform * float3(src_vert.co)); + dst_positions[i] = task.transform * src_positions[i]; } }); threading::parallel_for(src_edges.index_range(), 1024, [&](const IndexRange edge_range) { @@ -1072,7 +1069,7 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, MeshComponent &dst_component = r_realized_geometry.get_component_for_write(); dst_component.replace(dst_mesh); bke::MutableAttributeAccessor dst_attributes = dst_mesh->attributes_for_write(); - MutableSpan dst_verts = dst_mesh->verts_for_write(); + MutableSpan dst_positions = dst_mesh->vert_positions_for_write(); MutableSpan dst_edges = dst_mesh->edges_for_write(); MutableSpan dst_polys = dst_mesh->polys_for_write(); MutableSpan dst_loops = dst_mesh->loops_for_write(); @@ -1121,7 +1118,7 @@ static void execute_realize_mesh_tasks(const RealizeInstancesOptions &options, task, ordered_attributes, dst_attribute_writers, - dst_verts, + dst_positions, dst_edges, dst_polys, dst_loops, diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index 68c8dd8c18d..8971b2f297c 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -1412,7 +1412,7 @@ struct LineartEdgeNeighbor { }; struct VertData { - const MVert *mvert; + const float (*positions)[3]; LineartVert *v_arr; double (*model_view)[4]; double (*model_view_proj)[4]; @@ -1423,10 +1423,9 @@ static void lineart_mvert_transform_task(void *__restrict userdata, const TaskParallelTLS *__restrict /*tls*/) { VertData *vert_task_data = (VertData *)userdata; - const MVert *m_v = &vert_task_data->mvert[i]; double co[4]; LineartVert *v = &vert_task_data->v_arr[i]; - copy_v3db_v3fl(co, m_v->co); + copy_v3db_v3fl(co, vert_task_data->positions[i]); mul_v3_m4v3_db(v->gloc, vert_task_data->model_view, co); mul_v4_m4v3_db(v->fbcoord, vert_task_data->model_view_proj, co); v->index = i; @@ -1785,7 +1784,7 @@ static void lineart_triangle_adjacent_assign(LineartTriangle *tri, struct TriData { LineartObjectInfo *ob_info; - blender::Span verts; + blender::Span positions; blender::Span loops; const MLoopTri *mlooptri; const int *material_indices; @@ -1801,7 +1800,7 @@ static void lineart_load_tri_task(void *__restrict userdata, { TriData *tri_task_data = (TriData *)userdata; LineartObjectInfo *ob_info = tri_task_data->ob_info; - const blender::Span verts = tri_task_data->verts; + const blender::Span positions = tri_task_data->positions; const blender::Span loops = tri_task_data->loops; const MLoopTri *mlooptri = &tri_task_data->mlooptri[i]; const int *material_indices = tri_task_data->material_indices; @@ -1839,7 +1838,7 @@ static void lineart_load_tri_task(void *__restrict userdata, double gn[3]; float no[3]; - normal_tri_v3(no, verts[v1].co, verts[v2].co, verts[v3].co); + normal_tri_v3(no, positions[v1], positions[v2], positions[v3]); copy_v3db_v3fl(gn, no); mul_v3_mat3_m4v3_db(tri->gn, ob_info->normal, gn); normalize_v3_db(tri->gn); @@ -2026,7 +2025,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, vert_settings.min_iter_per_thread = 4000; VertData vert_data; - vert_data.mvert = BKE_mesh_verts(me); + vert_data.positions = BKE_mesh_vert_positions(me); vert_data.v_arr = la_v_arr; vert_data.model_view = ob_info->model_view; vert_data.model_view_proj = ob_info->model_view_proj; @@ -2043,8 +2042,8 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, TriData tri_data; tri_data.ob_info = ob_info; + tri_data.positions = me->vert_positions(); tri_data.mlooptri = mlooptri; - tri_data.verts = me->verts(); tri_data.loops = me->loops(); tri_data.material_indices = material_indices; tri_data.vert_arr = la_v_arr; diff --git a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc index ebb06ee55b9..49042db50ba 100644 --- a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc +++ b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc @@ -148,9 +148,10 @@ bool paint_is_grid_face_hidden(const uint * /*grid_hidden*/, * \{ */ void BKE_mesh_calc_poly_normal(const struct MPoly * /*mpoly*/, const struct MLoop * /*loopstart*/, - const struct MVert * /*mvarray*/, + const float (*vert_positions)[3], float[3] /*col*/) { + UNUSED_VARS(vert_positions); BLI_assert_unreachable(); } diff --git a/source/blender/io/alembic/exporter/abc_writer_hair.cc b/source/blender/io/alembic/exporter/abc_writer_hair.cc index a189d4cda6d..e4c61a7cb68 100644 --- a/source/blender/io/alembic/exporter/abc_writer_hair.cc +++ b/source/blender/io/alembic/exporter/abc_writer_hair.cc @@ -122,7 +122,7 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context, MTFace *mtface = (MTFace *)CustomData_get_layer(&mesh->fdata, CD_MTFACE); MFace *mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); - const MVert *mverts = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); if ((!mtface || !mface) && !uv_warning_shown_) { @@ -163,7 +163,7 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context, uv_values.emplace_back(r_uv[0], r_uv[1]); psys_interpolate_face(mesh, - mverts, + positions, vert_normals, face, tface, @@ -246,7 +246,7 @@ void ABCHairWriter::write_hair_child_sample(const HierarchyContext &context, MFace *mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); MTFace *mtface = (MTFace *)CustomData_get_layer(&mesh->fdata, CD_MTFACE); - const MVert *mverts = BKE_mesh_verts(mesh); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); ParticleSystem *psys = context.particle_system; @@ -280,7 +280,7 @@ void ABCHairWriter::write_hair_child_sample(const HierarchyContext &context, uv_values.emplace_back(r_uv[0], r_uv[1]); psys_interpolate_face(mesh, - mverts, + positions, vert_normals, face, tface, diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc index 084d26198bc..cc45764793a 100644 --- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc +++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc @@ -436,9 +436,9 @@ static void get_vertices(struct Mesh *mesh, std::vector &points) points.clear(); points.resize(mesh->totvert); - const Span verts = mesh->verts(); + const Span positions = mesh->vert_positions(); for (int i = 0, e = mesh->totvert; i < e; i++) { - copy_yup_from_zup(points[i].getValue(), verts[i].co); + copy_yup_from_zup(points[i].getValue(), positions[i]); } } diff --git a/source/blender/io/alembic/intern/abc_customdata.h b/source/blender/io/alembic/intern/abc_customdata.h index 0ddba866016..41fd4327a2f 100644 --- a/source/blender/io/alembic/intern/abc_customdata.h +++ b/source/blender/io/alembic/intern/abc_customdata.h @@ -6,6 +6,8 @@ * \ingroup balembic */ +#include "BLI_math_vector_types.hh" + #include #include @@ -15,7 +17,6 @@ struct CustomData; struct MLoop; struct MLoopUV; struct MPoly; -struct MVert; struct Mesh; using Alembic::Abc::ICompoundProperty; @@ -34,7 +35,7 @@ struct CDStreamConfig { MPoly *mpoly; int totpoly; - MVert *mvert; + float3 *positions; int totvert; MLoopUV *mloopuv; diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc index f632891dfda..2a228385372 100644 --- a/source/blender/io/alembic/intern/abc_reader_mesh.cc +++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc @@ -122,31 +122,30 @@ struct AbcMeshData { UInt32ArraySamplePtr uvs_indices; }; -static void read_mverts_interp(MVert *mverts, +static void read_mverts_interp(float3 *vert_positions, const P3fArraySamplePtr &positions, const P3fArraySamplePtr &ceil_positions, const double weight) { float tmp[3]; for (int i = 0; i < positions->size(); i++) { - MVert &mvert = mverts[i]; const Imath::V3f &floor_pos = (*positions)[i]; const Imath::V3f &ceil_pos = (*ceil_positions)[i]; interp_v3_v3v3(tmp, floor_pos.getValue(), ceil_pos.getValue(), float(weight)); - copy_zup_from_yup(mvert.co, tmp); + copy_zup_from_yup(vert_positions[i], tmp); } } static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data) { - MVert *mverts = config.mvert; + float3 *vert_positions = config.positions; const P3fArraySamplePtr &positions = mesh_data.positions; if (config.use_vertex_interpolation && config.weight != 0.0f && mesh_data.ceil_positions != nullptr && mesh_data.ceil_positions->size() == positions->size()) { - read_mverts_interp(mverts, positions, mesh_data.ceil_positions, config.weight); + read_mverts_interp(vert_positions, positions, mesh_data.ceil_positions, config.weight); BKE_mesh_tag_coords_changed(config.mesh); return; } @@ -156,12 +155,11 @@ static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data) void read_mverts(Mesh &mesh, const P3fArraySamplePtr positions, const N3fArraySamplePtr normals) { - MutableSpan verts = mesh.verts_for_write(); + MutableSpan vert_positions = mesh.vert_positions_for_write(); for (int i = 0; i < positions->size(); i++) { - MVert &mvert = verts[i]; Imath::V3f pos_in = (*positions)[i]; - copy_zup_from_yup(mvert.co, pos_in.getValue()); + copy_zup_from_yup(vert_positions[i], pos_in.getValue()); } BKE_mesh_tag_coords_changed(&mesh); @@ -519,7 +517,7 @@ CDStreamConfig get_config(Mesh *mesh, const bool use_vertex_interpolation) { CDStreamConfig config; config.mesh = mesh; - config.mvert = mesh->verts_for_write().data(); + config.positions = mesh->vert_positions_for_write().data(); config.mloop = mesh->loops_for_write().data(); config.mpoly = mesh->polys_for_write().data(); config.totvert = mesh->totvert; diff --git a/source/blender/io/collada/GeometryExporter.cpp b/source/blender/io/collada/GeometryExporter.cpp index 5ede22163fc..862f4b95cef 100644 --- a/source/blender/io/collada/GeometryExporter.cpp +++ b/source/blender/io/collada/GeometryExporter.cpp @@ -27,6 +27,7 @@ #include "collada_internal.h" #include "collada_utils.h" +using blender::float3; using blender::Span; void GeometryExporter::exportGeom() @@ -119,12 +120,13 @@ void GeometryExporter::operator()(Object *ob) if (this->export_settings.get_include_shapekeys()) { Key *key = BKE_key_from_object(ob); if (key) { - blender::MutableSpan verts = me->verts_for_write(); + blender::MutableSpan positions = me->vert_positions_for_write(); KeyBlock *kb = (KeyBlock *)key->block.first; /* skip the basis */ kb = kb->next; for (; kb; kb = kb->next) { - BKE_keyblock_convert_to_mesh(kb, verts.data(), me->totvert); + BKE_keyblock_convert_to_mesh( + kb, reinterpret_cast(positions.data()), me->totvert); export_key_mesh(ob, me, kb); } } @@ -436,13 +438,13 @@ void GeometryExporter::create_mesh_primitive_list(short material_index, void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) { - const Span verts = me->verts(); + const Span positions = me->vert_positions(); COLLADASW::FloatSourceF source(mSW); source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION)); source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION) + ARRAY_ID_SUFFIX); - source.setAccessorCount(verts.size()); + source.setAccessorCount(positions.size()); source.setAccessorStride(3); COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); @@ -453,13 +455,15 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) * count = ""> */ source.prepareToAppendValues(); /* appends data to */ - for (const int i : verts.index_range()) { + for (const int i : positions.index_range()) { Vector co; if (export_settings.get_apply_global_orientation()) { - bc_add_global_transform(co, verts[i].co, export_settings.get_global_transform()); + float co_c[3]; + copy_v3_v3(co_c, positions[i]); + bc_add_global_transform(co, co_c, export_settings.get_global_transform()); } else { - copy_v3_v3(co, verts[i].co); + copy_v3_v3(co, positions[i]); } source.appendValues(co[0], co[1], co[2]); } @@ -579,11 +583,6 @@ bool operator<(const Normal &a, const Normal &b) void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::vector &nor) { -#if 0 - int totverts = dm->getNumVerts(dm); - MVert *verts = dm->getVertArray(dm); -#endif - COLLADASW::FloatSourceF source(mSW); source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL)); source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL) + ARRAY_ID_SUFFIX); @@ -617,7 +616,7 @@ void GeometryExporter::create_normals(std::vector &normals, std::map shared_normal_indices; int last_normal_index = -1; - const Span verts = me->verts(); + const Span positions = me->vert_positions(); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me); const Span polys = me->polys(); const Span loops = me->loops(); @@ -638,7 +637,10 @@ void GeometryExporter::create_normals(std::vector &normals, /* For flat faces use face normal as vertex normal: */ float vector[3]; - BKE_mesh_calc_poly_normal(mpoly, &loops[mpoly->loopstart], verts.data(), vector); + BKE_mesh_calc_poly_normal(mpoly, + &loops[mpoly->loopstart], + reinterpret_cast(positions.data()), + vector); Normal n = {vector[0], vector[1], vector[2]}; normals.push_back(n); diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp index 436d919f8d5..cdcd8564f92 100644 --- a/source/blender/io/collada/MeshImporter.cpp +++ b/source/blender/io/collada/MeshImporter.cpp @@ -34,6 +34,7 @@ #include "MeshImporter.h" #include "collada_utils.h" +using blender::float3; using blender::MutableSpan; /* get node name, or fall back to original id if not present (name is optional) */ @@ -350,10 +351,11 @@ void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me) } me->totvert = pos.getFloatValues()->getCount() / stride; - CustomData_add_layer(&me->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, me->totvert); - MutableSpan verts = me->verts_for_write(); - for (const int i : verts.index_range()) { - get_vector(verts[i].co, pos, i, stride); + CustomData_add_layer_named( + &me->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, me->totvert, "position"); + MutableSpan positions = me->vert_positions_for_write(); + for (const int i : positions.index_range()) { + get_vector(positions[i], pos, i, stride); } } diff --git a/source/blender/io/stl/importer/stl_import_mesh.cc b/source/blender/io/stl/importer/stl_import_mesh.cc index de993cd2f27..3a87c4e3559 100644 --- a/source/blender/io/stl/importer/stl_import_mesh.cc +++ b/source/blender/io/stl/importer/stl_import_mesh.cc @@ -76,11 +76,9 @@ Mesh *STLMeshHelper::to_mesh(Main *bmain, char *mesh_name) id_us_min(&mesh->id); mesh->totvert = verts_.size(); - CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_SET_DEFAULT, nullptr, mesh->totvert); - MutableSpan verts = mesh->verts_for_write(); - for (int i = 0; i < mesh->totvert; i++) { - copy_v3_v3(verts[i].co, verts_[i]); - } + CustomData_add_layer_named( + &mesh->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, mesh->totvert, "position"); + mesh->vert_positions_for_write().copy_from(verts_); mesh->totpoly = tris_.size(); mesh->totloop = tris_.size() * 3; diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index 4b31f8cf661..c112fe7b51a 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -695,12 +695,9 @@ void USDMeshReader::read_mesh_sample(ImportSettings *settings, * in code that expect this data to be there. */ if (new_mesh || (settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) { - MutableSpan verts = mesh->verts_for_write(); + MutableSpan vert_positions = mesh->vert_positions_for_write(); for (int i = 0; i < positions_.size(); i++) { - MVert &mvert = verts[i]; - mvert.co[0] = positions_[i][0]; - mvert.co[1] = positions_[i][1]; - mvert.co[2] = positions_[i][2]; + vert_positions[i] = {positions_[i][0], positions_[i][1], positions_[i][2]}; } BKE_mesh_tag_coords_changed(mesh); diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index e7d79e888e4..12d73b5e1cb 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -249,9 +249,10 @@ static void get_vertices(const Mesh *mesh, USDMeshData &usd_mesh_data) { usd_mesh_data.points.reserve(mesh->totvert); - const Span verts = mesh->verts(); - for (const int i : verts.index_range()) { - usd_mesh_data.points.push_back(pxr::GfVec3f(verts[i].co)); + const Span positions = mesh->vert_positions(); + for (const int i : positions.index_range()) { + const float3 &position = positions[i]; + usd_mesh_data.points.push_back(pxr::GfVec3f(position.x, position.y, position.z)); } } diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc index e0a5811ae76..d057319ec3d 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc @@ -40,7 +40,7 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj BKE_object_get_evaluated_mesh(&export_object_eval_) : BKE_object_get_pre_modified_mesh(&export_object_eval_); if (export_mesh_) { - mesh_verts_ = export_mesh_->verts(); + mesh_positions_ = export_mesh_->vert_positions(); mesh_edges_ = export_mesh_->edges(); mesh_polys_ = export_mesh_->polys(); mesh_loops_ = export_mesh_->loops(); @@ -72,7 +72,7 @@ void OBJMesh::set_mesh(Mesh *mesh) } owned_export_mesh_ = mesh; export_mesh_ = owned_export_mesh_; - mesh_verts_ = mesh->verts(); + mesh_positions_ = mesh->vert_positions(); mesh_edges_ = mesh->edges(); mesh_polys_ = mesh->polys(); mesh_loops_ = mesh->loops(); @@ -267,8 +267,7 @@ const char *OBJMesh::get_object_material_name(const int16_t mat_nr) const float3 OBJMesh::calc_vertex_coords(const int vert_index, const float global_scale) const { - float3 r_coords; - copy_v3_v3(r_coords, mesh_verts_[vert_index].co); + float3 r_coords = mesh_positions_[vert_index]; mul_m4_v3(world_and_axes_transform_, r_coords); mul_v3_fl(r_coords, global_scale); return r_coords; @@ -351,8 +350,10 @@ float3 OBJMesh::calc_poly_normal(const int poly_index) const { float3 r_poly_normal; const MPoly &poly = mesh_polys_[poly_index]; - BKE_mesh_calc_poly_normal( - &poly, &mesh_loops_[poly.loopstart], mesh_verts_.data(), r_poly_normal); + BKE_mesh_calc_poly_normal(&poly, + &mesh_loops_[poly.loopstart], + reinterpret_cast(mesh_positions_.data()), + r_poly_normal); mul_m3_v3(world_and_axes_normal_transform_, r_poly_normal); normalize_v3(r_poly_normal); return r_poly_normal; diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh index 6ee2a3fccd8..0c151cb4454 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh @@ -36,7 +36,7 @@ class OBJMesh : NonCopyable { const Mesh *export_mesh_; /** A mesh owned here, if created or modified for the export. May be null. */ Mesh *owned_export_mesh_ = nullptr; - Span mesh_verts_; + Span mesh_positions_; Span mesh_edges_; Span mesh_polys_; Span mesh_loops_; diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc index 42293a9b992..008aaf5cd98 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc @@ -154,7 +154,7 @@ void MeshFromGeometry::fixup_invalid_faces() void MeshFromGeometry::create_vertices(Mesh *mesh) { - MutableSpan verts = mesh->verts_for_write(); + MutableSpan positions = mesh->vert_positions_for_write(); /* Go through all the global vertex indices from min to max, * checking which ones are actually and building a global->local * index mapping. Write out the used vertex positions into the Mesh @@ -168,7 +168,7 @@ void MeshFromGeometry::create_vertices(Mesh *mesh) } int local_vi = int(mesh_geometry_.global_to_local_vertices_.size()); BLI_assert(local_vi >= 0 && local_vi < mesh->totvert); - copy_v3_v3(verts[local_vi].co, global_vertices_.vertices[vi]); + copy_v3_v3(positions[local_vi], global_vertices_.vertices[vi]); mesh_geometry_.global_to_local_vertices_.add_new(vi, local_vi); } } diff --git a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc index 225643c0682..afa860ba7c2 100644 --- a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc @@ -101,9 +101,9 @@ class obj_importer_test : public BlendfileLoadingBaseTest { EXPECT_EQ(mesh->totedge, exp.mesh_totedge_or_curve_endp); EXPECT_EQ(mesh->totpoly, exp.mesh_totpoly_or_curve_order); EXPECT_EQ(mesh->totloop, exp.mesh_totloop_or_curve_cyclic); - const Span verts = mesh->verts(); - EXPECT_V3_NEAR(verts.first().co, exp.vert_first, 0.0001f); - EXPECT_V3_NEAR(verts.last().co, exp.vert_last, 0.0001f); + const Span positions = mesh->vert_positions(); + EXPECT_V3_NEAR(positions.first(), exp.vert_first, 0.0001f); + EXPECT_V3_NEAR(positions.last(), exp.vert_last, 0.0001f); const float3 *lnors = (const float3 *)CustomData_get_layer(&mesh->ldata, CD_NORMAL); float3 normal_first = lnors != nullptr ? lnors[0] : float3(0, 0, 0); EXPECT_V3_NEAR(normal_first, exp.normal_first, 0.0001f); diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 0710ed6d30f..6586cd4dd5b 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -94,8 +94,8 @@ typedef enum eCustomDataType { */ CD_AUTO_FROM_NAME = -1, - CD_MVERT = 0, #ifdef DNA_DEPRECATED_ALLOW + CD_MVERT = 0, /* DEPRECATED */ CD_MSTICKY = 1, /* DEPRECATED */ #endif CD_MDEFORMVERT = 2, /* Array of `MDeformVert`. */ @@ -165,7 +165,7 @@ typedef enum eCustomDataType { } eCustomDataType; /* Bits for eCustomDataMask */ -#define CD_MASK_MVERT (1 << CD_MVERT) +// #define CD_MASK_MVERT (1 << CD_MVERT) /* DEPRECATED */ // #define CD_MASK_MSTICKY (1 << CD_MSTICKY) /* DEPRECATED */ #define CD_MASK_MDEFORMVERT (1 << CD_MDEFORMVERT) #define CD_MASK_MEDGE (1 << CD_MEDGE) diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index bea937d7d42..78d228bb681 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -44,7 +44,6 @@ struct MCol; struct MEdge; struct MFace; struct MLoopTri; -struct MVert; struct Material; typedef struct Mesh { @@ -65,7 +64,7 @@ typedef struct Mesh { */ struct Material **mat; - /** The number of vertices (#MVert) in the mesh, and the size of #vdata. */ + /** The number of vertices in the mesh, and the size of #vdata. */ int totvert; /** The number of edges (#MEdge) in the mesh, and the size of #edata. */ int totedge; @@ -219,12 +218,11 @@ typedef struct Mesh { MeshRuntimeHandle *runtime; #ifdef __cplusplus /** - * Array of vertex positions (and various other data). Edges and faces are defined by indices - * into this array. + * Array of vertex positions. Edges and faces are defined by indices into this array. */ - blender::Span verts() const; + blender::Span vert_positions() const; /** Write access to vertex data. */ - blender::MutableSpan verts_for_write(); + blender::MutableSpan vert_positions_for_write(); /** * Array of edges, containing vertex indices. For simple triangle or quad meshes, edges could be * calculated from the #MPoly and #MLoop arrays, however, edges need to be stored explicitly to diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 96c543d3db5..7c1abc80525 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -18,36 +18,6 @@ extern "C" { /** \name Geometry Elements * \{ */ -/** - * Mesh Vertices. - * - * Typically accessed from #Mesh.verts() - */ -typedef struct MVert { - float co[3]; - /** - * Deprecated flag for storing hide status and selection, which are now stored in separate - * generic attributes. Kept for file read and write. - */ - char flag_legacy; - /** - * Deprecated bevel weight storage, now located in #CD_BWEIGHT, except for file read and write. - */ - char bweight_legacy; - char _pad[2]; -} MVert; - -/** #MVert.flag */ - -#ifdef DNA_DEPRECATED_ALLOW -enum { - /** Deprecated selection status. Now stored in ".select_vert" attribute. */ - /* SELECT = (1 << 0), */ - /** Deprecated hide status. Now stored in ".hide_vert" attribute. */ - ME_HIDE = (1 << 4), -}; -#endif - /** * Mesh Edges. * @@ -114,7 +84,7 @@ enum { * Typically accessed with #Mesh.loops(). */ typedef struct MLoop { - /** Vertex index into an #MVert array. */ + /** Vertex index. */ unsigned int v; /** Edge index into an #MEdge array. */ unsigned int e; @@ -155,7 +125,7 @@ enum { /** * #MLoopTri's are lightweight triangulation data, * for functionality that doesn't support ngons (#MPoly). - * This is cache data created from (#MPoly, #MLoop & #MVert arrays). + * This is cache data created from (#MPoly, #MLoop & position arrays). * There is no attempt to maintain this data's validity over time, * any changes to the underlying mesh invalidate the #MLoopTri array, * which will need to be re-calculated. @@ -182,9 +152,9 @@ enum { * * // access vertex locations. * float *vtri_co[3] = { - * mvert[mloop[lt->tri[0]].v].co, - * mvert[mloop[lt->tri[1]].v].co, - * mvert[mloop[lt->tri[2]].v].co, + * positions[mloop[lt->tri[0]].v], + * positions[mloop[lt->tri[1]].v], + * positions[mloop[lt->tri[2]].v], * }; * * // access UV coordinates (works for all loop data, vertex colors... etc). @@ -477,6 +447,33 @@ enum { /** \name Deprecated Structs * \{ */ +/** + * Deprecated mesh vertex data structure. Now stored with generic attributes. + */ +#ifdef DNA_DEPRECATED_ALLOW +typedef struct MVert { + float co_legacy[3]; + /** + * Deprecated flag for storing hide status and selection, which are now stored in separate + * generic attributes. Kept for file read and write. + */ + char flag_legacy; + /** + * Deprecated bevel weight storage, now located in #CD_BWEIGHT, except for file read and write. + */ + char bweight_legacy; + char _pad[2]; +} MVert; + +/** #MVert.flag */ +enum { + /** Deprecated selection status. Now stored in ".select_vert" attribute. */ + /* SELECT = (1 << 0), */ + /** Deprecated hide status. Now stored in ".hide_vert" attribute. */ + ME_HIDE = (1 << 4), +}; +#endif + /** * Used in Blender pre 2.63, See #MLoop, #MPoly for face data stored in the blend file. * Use for reading old files and in a handful of cases which should be removed eventually. diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 97e42efd5ac..810d2bae59a 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -849,17 +849,17 @@ typedef struct CollisionModifierData { ModifierData modifier; /** Position at the beginning of the frame. */ - struct MVert *x; + float (*x)[3]; /** Position at the end of the frame. */ - struct MVert *xnew; + float (*xnew)[3]; /** Unused at the moment, but was discussed during sprint. */ - struct MVert *xold; + float (*xold)[3]; /** New position at the actual inter-frame step. */ - struct MVert *current_xnew; + float (*current_xnew)[3]; /** Position at the actual inter-frame step. */ - struct MVert *current_x; + float (*current_x)[3]; /** (xnew - x) at the actual inter-frame step. */ - struct MVert *current_v; + float (*current_v)[3]; struct MVertTri *tri; @@ -879,9 +879,9 @@ typedef struct SurfaceModifierData { ModifierData modifier; /** Old position. */ - struct MVert *x; + float (*x)[3]; /** Velocity. */ - struct MVert *v; + float (*v)[3]; struct Mesh *mesh; diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h index b2bf0aead90..6d4592bb338 100644 --- a/source/blender/makesdna/intern/dna_rename_defs.h +++ b/source/blender/makesdna/intern/dna_rename_defs.h @@ -108,6 +108,7 @@ DNA_STRUCT_RENAME_ELEM(Object_Runtime, crazyspace_num_verts, crazyspace_verts_nu DNA_STRUCT_RENAME_ELEM(MEdge, bweight, bweight_legacy) DNA_STRUCT_RENAME_ELEM(MEdge, crease, crease_legacy) DNA_STRUCT_RENAME_ELEM(MPoly, mat_nr, mat_nr_legacy) +DNA_STRUCT_RENAME_ELEM(MVert, co, co_legacy) DNA_STRUCT_RENAME_ELEM(MVert, bweight, bweight_legacy) DNA_STRUCT_RENAME_ELEM(MVert, flag, flag_legacy) DNA_STRUCT_RENAME_ELEM(ParticleSettings, child_nbr, child_percent) diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 7351ca1d8ca..c0969aaa3ba 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -365,8 +365,8 @@ static void rna_Mesh_update_positions_tag(Main *bmain, Scene *scene, PointerRNA static int rna_MeshVertex_index_get(PointerRNA *ptr) { const Mesh *mesh = rna_mesh(ptr); - const MVert *vert = (MVert *)ptr->data; - const int index = (int)(vert - BKE_mesh_verts(mesh)); + const float(*position)[3] = (const float(*)[3])ptr->data; + const int index = (int)(position - BKE_mesh_vert_positions(mesh)); BLI_assert(index >= 0); BLI_assert(index < mesh->totvert); return index; @@ -439,6 +439,16 @@ int rna_Mesh_loop_triangles_lookup_int(PointerRNA *ptr, int index, PointerRNA *r return true; } +static void rna_MeshVertex_co_get(PointerRNA *ptr, float *value) +{ + copy_v3_v3(value, (const float *)ptr->data); +} + +static void rna_MeshVertex_co_set(PointerRNA *ptr, const float *value) +{ + copy_v3_v3((float *)ptr->data, value); +} + static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value) { Mesh *mesh = rna_mesh(ptr); @@ -618,9 +628,9 @@ static void rna_MeshPolygon_normal_get(PointerRNA *ptr, float *values) { Mesh *me = rna_mesh(ptr); MPoly *mp = (MPoly *)ptr->data; - const MVert *verts = BKE_mesh_verts(me); + const float(*positions)[3] = BKE_mesh_vert_positions(me); const MLoop *loops = BKE_mesh_loops(me); - BKE_mesh_calc_poly_normal(mp, loops + mp->loopstart, verts, values); + BKE_mesh_calc_poly_normal(mp, loops + mp->loopstart, positions, values); } static bool rna_MeshPolygon_hide_get(PointerRNA *ptr) @@ -695,18 +705,18 @@ static void rna_MeshPolygon_center_get(PointerRNA *ptr, float *values) { Mesh *me = rna_mesh(ptr); MPoly *mp = (MPoly *)ptr->data; - const MVert *verts = BKE_mesh_verts(me); + const float(*positions)[3] = BKE_mesh_vert_positions(me); const MLoop *loops = BKE_mesh_loops(me); - BKE_mesh_calc_poly_center(mp, loops + mp->loopstart, verts, values); + BKE_mesh_calc_poly_center(mp, loops + mp->loopstart, positions, values); } static float rna_MeshPolygon_area_get(PointerRNA *ptr) { Mesh *me = (Mesh *)ptr->owner_id; MPoly *mp = (MPoly *)ptr->data; - const MVert *verts = BKE_mesh_verts(me); + const float(*positions)[3] = BKE_mesh_vert_positions(me); const MLoop *loops = BKE_mesh_loops(me); - return BKE_mesh_calc_poly_area(mp, loops + mp->loopstart, verts); + return BKE_mesh_calc_poly_area(mp, loops + mp->loopstart, positions); } static void rna_MeshPolygon_flip(ID *id, MPoly *mp) @@ -732,13 +742,13 @@ static void rna_MeshLoopTriangle_normal_get(PointerRNA *ptr, float *values) { Mesh *me = rna_mesh(ptr); MLoopTri *lt = (MLoopTri *)ptr->data; - const MVert *verts = BKE_mesh_verts(me); + const float(*positions)[3] = BKE_mesh_vert_positions(me); const MLoop *loops = BKE_mesh_loops(me); uint v1 = loops[lt->tri[0]].v; uint v2 = loops[lt->tri[1]].v; uint v3 = loops[lt->tri[2]].v; - normal_tri_v3(values, verts[v1].co, verts[v2].co, verts[v3].co); + normal_tri_v3(values, positions[v1], positions[v2], positions[v3]); } static void rna_MeshLoopTriangle_split_normals_get(PointerRNA *ptr, float *values) @@ -763,12 +773,12 @@ static float rna_MeshLoopTriangle_area_get(PointerRNA *ptr) { Mesh *me = rna_mesh(ptr); MLoopTri *lt = (MLoopTri *)ptr->data; - const MVert *verts = BKE_mesh_verts(me); + const float(*positions)[3] = BKE_mesh_vert_positions(me); const MLoop *loops = BKE_mesh_loops(me); uint v1 = loops[lt->tri[0]].v; uint v2 = loops[lt->tri[1]].v; uint v3 = loops[lt->tri[2]].v; - return area_tri_v3(verts[v1].co, verts[v2].co, verts[v3].co); + return area_tri_v3(positions[v1], positions[v2], positions[v3]); } static void rna_MeshLoopColor_color_get(PointerRNA *ptr, float *values) @@ -834,19 +844,19 @@ static void rna_MeshVertex_groups_begin(CollectionPropertyIterator *iter, Pointe static void rna_MeshVertex_undeformed_co_get(PointerRNA *ptr, float values[3]) { Mesh *me = rna_mesh(ptr); - MVert *mvert = (MVert *)ptr->data; + const float *position = (const float *)ptr->data; const float(*orco)[3] = CustomData_get_layer(&me->vdata, CD_ORCO); if (orco) { const int index = rna_MeshVertex_index_get(ptr); - /* orco is normalized to 0..1, we do inverse to match mvert->co */ + /* orco is normalized to 0..1, we do inverse to match the vertex position */ float loc[3], size[3]; BKE_mesh_texspace_get(me->texcomesh ? me->texcomesh : me, loc, size); madd_v3_v3v3v3(values, loc, orco[index], size); } else { - copy_v3_v3(values, mvert->co); + copy_v3_v3(values, position); } } @@ -1651,7 +1661,7 @@ static void rna_Mesh_vertices_begin(CollectionPropertyIterator *iter, PointerRNA { Mesh *mesh = rna_mesh(ptr); rna_iterator_array_begin( - iter, BKE_mesh_verts_for_write(mesh), sizeof(MVert), mesh->totvert, false, NULL); + iter, BKE_mesh_vert_positions_for_write(mesh), sizeof(float[3]), mesh->totvert, false, NULL); } static int rna_Mesh_vertices_length(PointerRNA *ptr) { @@ -1666,7 +1676,7 @@ int rna_Mesh_vertices_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr) } r_ptr->owner_id = &mesh->id; r_ptr->type = &RNA_MeshVertex; - r_ptr->data = &BKE_mesh_verts_for_write(mesh)[index]; + r_ptr->data = &BKE_mesh_vert_positions_for_write(mesh)[index]; return true; } @@ -2244,13 +2254,14 @@ static void rna_def_mvert(BlenderRNA *brna) PropertyRNA *prop; srna = RNA_def_struct(brna, "MeshVertex", NULL); - RNA_def_struct_sdna(srna, "MVert"); RNA_def_struct_ui_text(srna, "Mesh Vertex", "Vertex in a Mesh data-block"); RNA_def_struct_path_func(srna, "rna_MeshVertex_path"); RNA_def_struct_ui_icon(srna, ICON_VERTEXSEL); prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_ui_text(prop, "Location", ""); + RNA_def_property_array(prop, 3); + RNA_def_property_float_funcs(prop, "rna_MeshVertex_co_get", "rna_MeshVertex_co_set", NULL); + RNA_def_property_ui_text(prop, "Position", ""); RNA_def_property_update(prop, 0, "rna_Mesh_update_positions_tag"); prop = RNA_def_property(srna, "normal", PROP_FLOAT, PROP_DIRECTION); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index aef5aea5bac..ad579a48d2f 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -213,9 +213,8 @@ static void rna_ParticleHairKey_location_object_get(PointerRNA *ptr, float *valu if (pa) { Mesh *hair_mesh = (psmd->psys->flag & PSYS_HAIR_DYNAMICS) ? psmd->psys->hair_out_mesh : NULL; if (hair_mesh) { - const MVert *verts = BKE_mesh_verts(hair_mesh); - const MVert *mv = &verts[pa->hair_index + (hkey - pa->hair)]; - copy_v3_v3(values, mv->co); + const float(*positions)[3] = BKE_mesh_vert_positions(hair_mesh); + copy_v3_v3(values, positions[pa->hair_index + (hkey - pa->hair)]); } else { float hairmat[4][4]; @@ -279,9 +278,8 @@ static void hair_key_location_object_set(HairKey *hair_key, if (hair_key_index == -1) { return; } - MVert *verts = BKE_mesh_verts_for_write(hair_mesh); - MVert *mv = &verts[particle->hair_index + (hair_key_index)]; - copy_v3_v3(mv->co, src_co); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(hair_mesh); + copy_v3_v3(positions[particle->hair_index + (hair_key_index)], src_co); return; } @@ -324,9 +322,8 @@ static void rna_ParticleHairKey_co_object(HairKey *hairkey, NULL; if (particle) { if (hair_mesh) { - const MVert *verts = BKE_mesh_verts(hair_mesh); - const MVert *mv = &verts[particle->hair_index + (hairkey - particle->hair)]; - copy_v3_v3(n_co, mv->co); + const float(*positions)[3] = BKE_mesh_vert_positions(hair_mesh); + copy_v3_v3(n_co, positions[particle->hair_index + (hairkey - particle->hair)]); } else { float hairmat[4][4]; diff --git a/source/blender/modifiers/intern/MOD_array.cc b/source/blender/modifiers/intern/MOD_array.cc index 0acba6dd3f9..a2197835b3d 100644 --- a/source/blender/modifiers/intern/MOD_array.cc +++ b/source/blender/modifiers/intern/MOD_array.cc @@ -125,15 +125,15 @@ static int svert_sum_cmp(const void *e1, const void *e2) } static void svert_from_mvert(SortVertsElem *sv, - const MVert *mv, + const float (*vert_positions)[3], const int i_begin, const int i_end) { int i; - for (i = i_begin; i < i_end; i++, sv++, mv++) { + for (i = i_begin; i < i_end; i++, sv++) { sv->vertex_num = i; - copy_v3_v3(sv->co, mv->co); - sv->sum_co = sum_v3(mv->co); + copy_v3_v3(sv->co, vert_positions[i]); + sv->sum_co = sum_v3(vert_positions[i]); } } @@ -145,7 +145,7 @@ static void svert_from_mvert(SortVertsElem *sv, * The `int doubles_map[verts_source_num]` array must have been allocated by caller. */ static void dm_mvert_map_doubles(int *doubles_map, - const MVert *mverts, + const float (*vert_positions)[3], const int target_start, const int target_verts_num, const int source_start, @@ -167,10 +167,10 @@ static void dm_mvert_map_doubles(int *doubles_map, MEM_malloc_arrayN(source_verts_num, sizeof(SortVertsElem), __func__)); /* Copy target vertices index and cos into SortVertsElem array */ - svert_from_mvert(sorted_verts_target, mverts + target_start, target_start, target_end); + svert_from_mvert(sorted_verts_target, vert_positions, target_start, target_end); /* Copy source vertices index and cos into SortVertsElem array */ - svert_from_mvert(sorted_verts_source, mverts + source_start, source_start, source_end); + svert_from_mvert(sorted_verts_source, vert_positions, source_start, source_end); /* sort arrays according to sum of vertex coordinates (sumco) */ qsort(sorted_verts_target, target_verts_num, sizeof(SortVertsElem), svert_sum_cmp); @@ -238,8 +238,8 @@ static void dm_mvert_map_doubles(int *doubles_map, * then there will be no mapping at all for this source. */ while (best_target_vertex != -1 && !ELEM(doubles_map[best_target_vertex], -1, best_target_vertex)) { - if (compare_len_v3v3(mverts[sve_source->vertex_num].co, - mverts[doubles_map[best_target_vertex]].co, + if (compare_len_v3v3(vert_positions[sve_source->vertex_num], + vert_positions[doubles_map[best_target_vertex]], dist)) { best_target_vertex = doubles_map[best_target_vertex]; } @@ -276,11 +276,10 @@ static void mesh_merge_transform(Mesh *result, { int *index_orig; int i; - MVert *mv; MEdge *me; MLoop *ml; MPoly *mp; - MVert *result_verts = BKE_mesh_verts_for_write(result); + float(*result_positions)[3] = BKE_mesh_vert_positions_for_write(result); MEdge *result_edges = BKE_mesh_edges_for_write(result); MPoly *result_polys = BKE_mesh_polys_for_write(result); MLoop *result_loops = BKE_mesh_loops_for_write(result); @@ -290,10 +289,8 @@ static void mesh_merge_transform(Mesh *result, CustomData_copy_data(&cap_mesh->ldata, &result->ldata, 0, cap_loops_index, cap_nloops); CustomData_copy_data(&cap_mesh->pdata, &result->pdata, 0, cap_polys_index, cap_npolys); - mv = result_verts + cap_verts_index; - - for (i = 0; i < cap_nverts; i++, mv++) { - mul_m4_v3(cap_offset, mv->co); + for (i = 0; i < cap_nverts; i++) { + mul_m4_v3(cap_offset, result_positions[cap_verts_index + i]); } /* We have to correct normals too, if we do not tag them as dirty later! */ @@ -429,7 +426,6 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* Build up offset array, accumulating all settings options. */ unit_m4(offset); - const MVert *src_verts = BKE_mesh_verts(mesh); const MEdge *src_edges = BKE_mesh_edges(mesh); const MPoly *src_polys = BKE_mesh_polys(mesh); const MLoop *src_loops = BKE_mesh_loops(mesh); @@ -440,12 +436,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, if (amd->offset_type & MOD_ARR_OFF_RELATIVE) { float min[3], max[3]; - const MVert *src_mv; - INIT_MINMAX(min, max); - for (src_mv = src_verts, j = chunk_nverts; j--; src_mv++) { - minmax_v3v3_v3(min, max, src_mv->co); - } + BKE_mesh_minmax(mesh, min, max); for (j = 3; j--;) { offset[3][j] += amd->scale[j] * (max[j] - min[j]); @@ -542,7 +534,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* Initialize a result dm */ result = BKE_mesh_new_nomain_from_template( mesh, result_nverts, result_nedges, 0, result_nloops, result_npolys); - MVert *result_verts = BKE_mesh_verts_for_write(result); + float(*result_positions)[3] = BKE_mesh_vert_positions_for_write(result); MEdge *result_edges = BKE_mesh_edges_for_write(result); MPoly *result_polys = BKE_mesh_polys_for_write(result); MLoop *result_loops = BKE_mesh_loops_for_write(result); @@ -560,10 +552,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, chunk_npolys); /* Subdivision-surface for eg won't have mesh data in the custom-data arrays. - * Now add #MVert/#MEdge/#MPoly layers. */ - if (!CustomData_has_layer(&mesh->vdata, CD_MVERT)) { - memcpy(result_verts, src_verts, sizeof(MVert) * mesh->totvert); - } + * Now add #position/#MEdge/#MPoly layers. */ if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) { memcpy(result_edges, src_edges, sizeof(MEdge) * mesh->totedge); } @@ -600,7 +589,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* apply offset to all new verts */ for (i = 0; i < chunk_nverts; i++) { const int i_dst = vert_offset + i; - mul_m4_v3(current_offset, result_verts[i_dst].co); + mul_m4_v3(current_offset, result_positions[i_dst]); /* We have to correct normals too, if we do not tag them as dirty! */ if (!use_recalc_normals) { @@ -644,8 +633,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, while (target != -1 && !ELEM(full_doubles_map[target], -1, target)) { /* If target is already mapped, we only follow that mapping if final target remains * close enough from current vert (otherwise no mapping at all). */ - if (compare_len_v3v3(result_verts[this_chunk_index].co, - result_verts[full_doubles_map[target]].co, + if (compare_len_v3v3(result_positions[this_chunk_index], + result_positions[full_doubles_map[target]], amd->merge_dist)) { target = full_doubles_map[target]; } @@ -659,7 +648,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, } else { dm_mvert_map_doubles(full_doubles_map, - result_verts, + result_positions, (c - 1) * chunk_nverts, chunk_nverts, c * chunk_nverts, @@ -698,7 +687,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, if (use_merge && (amd->flags & MOD_ARR_MERGEFINAL) && (count > 1)) { /* Merge first and last copies */ dm_mvert_map_doubles(full_doubles_map, - result_verts, + result_positions, last_chunk_start, last_chunk_nverts, first_chunk_start, @@ -728,7 +717,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* Identify doubles with first chunk */ if (use_merge) { dm_mvert_map_doubles(full_doubles_map, - result_verts, + result_positions, first_chunk_start, first_chunk_nverts, start_cap_start, @@ -758,7 +747,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* Identify doubles with last chunk */ if (use_merge) { dm_mvert_map_doubles(full_doubles_map, - result_verts, + result_positions, last_chunk_start, last_chunk_nverts, end_cap_start, diff --git a/source/blender/modifiers/intern/MOD_boolean.cc b/source/blender/modifiers/intern/MOD_boolean.cc index 178be2d8962..6175455867e 100644 --- a/source/blender/modifiers/intern/MOD_boolean.cc +++ b/source/blender/modifiers/intern/MOD_boolean.cc @@ -62,6 +62,7 @@ #endif using blender::Array; +using blender::float3; using blender::float4x4; using blender::IndexRange; using blender::MutableSpan; @@ -142,9 +143,9 @@ static Mesh *get_quick_mesh( invert_m4_m4(imat, ob_self->object_to_world); mul_m4_m4m4(omat, imat, ob_operand_ob->object_to_world); - MutableSpan verts = result->verts_for_write(); - for (const int i : verts.index_range()) { - mul_m4_v3(omat, verts[i].co); + MutableSpan positions = result->vert_positions_for_write(); + for (const int i : positions.index_range()) { + mul_m4_v3(omat, positions[i]); } BKE_mesh_tag_coords_changed(result); diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index 78724d6a2a1..c6bda4a707b 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -75,7 +75,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct const int vert_src_num = mesh->totvert; const int edge_src_num = mesh->totedge; const int poly_src_num = mesh->totpoly; - const MVert *mvert_src = BKE_mesh_verts(mesh); const MEdge *medge_src = BKE_mesh_edges(mesh); const MPoly *mpoly_src = BKE_mesh_polys(mesh); const MLoop *mloop_src = BKE_mesh_loops(mesh); @@ -202,23 +201,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct /* now we know the number of verts, edges and faces, we can create the mesh. */ result = BKE_mesh_new_nomain_from_template( mesh, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash), 0, loops_dst_num, faces_dst_num); - MVert *result_verts = BKE_mesh_verts_for_write(result); MEdge *result_edges = BKE_mesh_edges_for_write(result); MPoly *result_polys = BKE_mesh_polys_for_write(result); MLoop *result_loops = BKE_mesh_loops_for_write(result); /* copy the vertices across */ GHASH_ITER (gh_iter, vertHash) { - MVert source; - MVert *dest; int oldIndex = POINTER_AS_INT(BLI_ghashIterator_getKey(&gh_iter)); int newIndex = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter)); - - source = mvert_src[oldIndex]; - dest = &result_verts[newIndex]; - CustomData_copy_data(&mesh->vdata, &result->vdata, oldIndex, newIndex, 1); - *dest = source; } /* copy the edges across, remapping indices */ diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index 82faf08b349..f933bcff360 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -93,7 +93,6 @@ static void deformVerts(ModifierData *md, { CollisionModifierData *collmd = (CollisionModifierData *)md; Mesh *mesh_src; - MVert *tempVert = NULL; Object *ob = ctx->object; /* If collision is disabled, free the stale data and exit. */ @@ -145,11 +144,11 @@ static void deformVerts(ModifierData *md, if (collmd->time_xnew == -1000) { /* first time */ - collmd->x = MEM_dupallocN(BKE_mesh_verts(mesh_src)); /* frame start position */ + collmd->x = MEM_dupallocN(BKE_mesh_vert_positions(mesh_src)); /* frame start position */ for (uint i = 0; i < mvert_num; i++) { /* we save global positions */ - mul_m4_v3(ob->object_to_world, collmd->x[i].co); + mul_m4_v3(ob->object_to_world, collmd->x[i]); } collmd->xnew = MEM_dupallocN(collmd->x); /* Frame end position. */ @@ -177,25 +176,25 @@ static void deformVerts(ModifierData *md, } else if (mvert_num == collmd->mvert_num) { /* put positions to old positions */ - tempVert = collmd->x; + float(*temp)[3] = collmd->x; collmd->x = collmd->xnew; - collmd->xnew = tempVert; + collmd->xnew = temp; collmd->time_x = collmd->time_xnew; - memcpy(collmd->xnew, BKE_mesh_verts(mesh_src), mvert_num * sizeof(MVert)); + memcpy(collmd->xnew, BKE_mesh_vert_positions(mesh_src), mvert_num * sizeof(float[3])); bool is_static = true; for (uint i = 0; i < mvert_num; i++) { /* we save global positions */ - mul_m4_v3(ob->object_to_world, collmd->xnew[i].co); + mul_m4_v3(ob->object_to_world, collmd->xnew[i]); /* detect motion */ - is_static = is_static && equals_v3v3(collmd->x[i].co, collmd->xnew[i].co); + is_static = is_static && equals_v3v3(collmd->x[i], collmd->xnew[i]); } - memcpy(collmd->current_xnew, collmd->x, mvert_num * sizeof(MVert)); - memcpy(collmd->current_x, collmd->x, mvert_num * sizeof(MVert)); + memcpy(collmd->current_xnew, collmd->x, mvert_num * sizeof(float[3])); + memcpy(collmd->current_x, collmd->x, mvert_num * sizeof(float[3])); /* check if GUI setting has changed for bvh */ if (collmd->bvhtree) { @@ -265,9 +264,9 @@ static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md) collmd->xnew = newdataadr(fd, collmd->xnew); collmd->mfaces = newdataadr(fd, collmd->mfaces); - collmd->current_x = MEM_calloc_arrayN(collmd->mvert_num, sizeof(MVert), "current_x"); - collmd->current_xnew = MEM_calloc_arrayN(collmd->mvert_num, sizeof(MVert), "current_xnew"); - collmd->current_v = MEM_calloc_arrayN(collmd->mvert_num, sizeof(MVert), "current_v"); + collmd->current_x = MEM_calloc_arrayN(collmd->mvert_num, sizeof(float[3]), "current_x"); + collmd->current_xnew = MEM_calloc_arrayN(collmd->mvert_num, sizeof(float[3]), "current_xnew"); + collmd->current_v = MEM_calloc_arrayN(collmd->mvert_num, sizeof(float[3]), "current_v"); #endif collmd->x = NULL; diff --git a/source/blender/modifiers/intern/MOD_datatransfer.cc b/source/blender/modifiers/intern/MOD_datatransfer.cc index 25e8eb8fa20..40411f06ef3 100644 --- a/source/blender/modifiers/intern/MOD_datatransfer.cc +++ b/source/blender/modifiers/intern/MOD_datatransfer.cc @@ -175,12 +175,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * BLI_SPACE_TRANSFORM_SETUP(space_transform, ctx->object, ob_source); } - const MVert *me_verts = BKE_mesh_verts(me); + const float(*me_positions)[3] = BKE_mesh_vert_positions(me); const MEdge *me_edges = BKE_mesh_edges(me); - const MVert *result_verts = BKE_mesh_verts(result); + const float(*result_positions)[3] = BKE_mesh_vert_positions(result); const MEdge *result_edges = BKE_mesh_edges(result); - if (((result == me) || (me_verts == result_verts) || (me_edges == result_edges)) && + if (((result == me) || (me_positions == result_positions) || (me_edges == result_edges)) && (dtmd->data_types & DT_TYPES_AFFECT_MESH)) { /* We need to duplicate data here, otherwise setting custom normals, edges' sharpness, etc., * could modify org mesh, see T43671. */ diff --git a/source/blender/modifiers/intern/MOD_displace.cc b/source/blender/modifiers/intern/MOD_displace.cc index db90242fd55..402752610eb 100644 --- a/source/blender/modifiers/intern/MOD_displace.cc +++ b/source/blender/modifiers/intern/MOD_displace.cc @@ -155,7 +155,6 @@ struct DisplaceUserdata { float (*tex_co)[3]; float (*vertexCos)[3]; float local_mat[4][4]; - MVert *mvert; const float (*vert_normals)[3]; float (*vert_clnors)[3]; }; @@ -265,7 +264,6 @@ static void displaceModifier_do(DisplaceModifierData *dmd, const int verts_num) { Object *ob = ctx->object; - MVert *mvert; const MDeformVert *dvert; int direction = dmd->direction; int defgrp_index; @@ -282,7 +280,6 @@ static void displaceModifier_do(DisplaceModifierData *dmd, return; } - mvert = BKE_mesh_verts_for_write(mesh); MOD_get_vgroup(ob, mesh, dmd->defgrp_name, &dvert, &defgrp_index); if (defgrp_index >= 0 && dvert == nullptr) { @@ -337,7 +334,6 @@ static void displaceModifier_do(DisplaceModifierData *dmd, data.tex_co = tex_co; data.vertexCos = vertexCos; copy_m4_m4(data.local_mat, local_mat); - data.mvert = mvert; if (direction == MOD_DISP_DIR_NOR) { data.vert_normals = BKE_mesh_vertex_normals_ensure(mesh); } diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index b0806fed91c..819ffbba26d 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -91,7 +91,6 @@ static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *p { ParticleSystem *psys = psmd->psys; MFace *fa = NULL, *mface = NULL; - MVert *mvert = NULL; ParticleData *pa; KDTree_3d *tree; RNG *rng; @@ -100,7 +99,7 @@ static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *p int i, p, v1, v2, v3, v4 = 0; const bool invert_vgroup = (emd->flag & eExplodeFlag_INVERT_VGROUP) != 0; - mvert = BKE_mesh_verts_for_write(mesh); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); totvert = mesh->totvert; totface = mesh->totface; @@ -160,10 +159,10 @@ static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *p /* set face-particle-indexes to nearest particle to face center */ for (i = 0, fa = mface; i < totface; i++, fa++) { - add_v3_v3v3(center, mvert[fa->v1].co, mvert[fa->v2].co); - add_v3_v3(center, mvert[fa->v3].co); + add_v3_v3v3(center, positions[fa->v1], positions[fa->v2]); + add_v3_v3(center, positions[fa->v3]); if (fa->v4) { - add_v3_v3(center, mvert[fa->v4].co); + add_v3_v3(center, positions[fa->v4]); mul_v3_fl(center, 0.25); } else { @@ -641,7 +640,7 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) Mesh *split_m; MFace *mf = NULL, *df1 = NULL; MFace *mface = CustomData_get_layer(&mesh->fdata, CD_MFACE); - MVert *dupve, *mv; + float *dupve; EdgeHash *edgehash; EdgeHashIterator *ehi; int totvert = mesh->totvert; @@ -730,18 +729,11 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) layers_num = CustomData_number_of_layers(&split_m->fdata, CD_MTFACE); - const MVert *mesh_verts = BKE_mesh_verts(mesh); - MVert *split_m_verts = BKE_mesh_verts_for_write(split_m); + float(*split_m_positions)[3] = BKE_mesh_vert_positions_for_write(split_m); /* copy new faces & verts (is it really this painful with custom data??) */ for (i = 0; i < totvert; i++) { - MVert source; - MVert *dest; - source = mesh_verts[i]; - dest = &split_m_verts[i]; - CustomData_copy_data(&mesh->vdata, &split_m->vdata, i, i, 1); - *dest = source; } /* override original facepa (original pointer is saved in caller function) */ @@ -759,16 +751,13 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2); esplit = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi)); - mv = &split_m_verts[ed_v2]; - dupve = &split_m_verts[esplit]; CustomData_copy_data(&split_m->vdata, &split_m->vdata, ed_v2, esplit, 1); - *dupve = *mv; + dupve = split_m_positions[esplit]; + copy_v3_v3(dupve, split_m_positions[ed_v2]); - mv = &split_m_verts[ed_v1]; - - mid_v3_v3v3(dupve->co, dupve->co, mv->co); + mid_v3_v3v3(dupve, dupve, split_m_positions[ed_v1]); } BLI_edgehashIterator_free(ehi); @@ -989,26 +978,23 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, psys_sim_data_init(&sim); - const MVert *mesh_verts = BKE_mesh_verts(mesh); - MVert *explode_verts = BKE_mesh_verts_for_write(explode); + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); + float(*explode_positions)[3] = BKE_mesh_vert_positions_for_write(explode); /* duplicate & displace vertices */ ehi = BLI_edgehashIterator_new(vertpahash); for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { - MVert source; - MVert *dest; /* get particle + vertex from hash */ BLI_edgehashIterator_getKey(ehi, &ed_v1, &ed_v2); ed_v2 -= totvert; v = POINTER_AS_INT(BLI_edgehashIterator_getValue(ehi)); - source = mesh_verts[ed_v1]; - dest = &explode_verts[v]; + copy_v3_v3(explode_positions[v], positions[ed_v1]); CustomData_copy_data(&mesh->vdata, &explode->vdata, ed_v1, v, 1); - *dest = source; + copy_v3_v3(explode_positions[v], positions[ed_v1]); if (ed_v2 != totpart) { /* get particle */ @@ -1019,7 +1005,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, state.time = ctime; psys_get_particle_state(&sim, ed_v2, &state, 1); - vertco = explode_verts[v].co; + vertco = explode_positions[v]; mul_m4_v3(ctx->object->object_to_world, vertco); sub_v3_v3(vertco, birth.co); diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc index 48f56eccd47..9349ddc4aaa 100644 --- a/source/blender/modifiers/intern/MOD_mask.cc +++ b/source/blender/modifiers/intern/MOD_mask.cc @@ -50,6 +50,7 @@ #include "BLI_vector.hh" using blender::Array; +using blender::float3; using blender::IndexRange; using blender::ListBaseWrapper; using blender::MutableSpan; @@ -330,19 +331,12 @@ static void copy_masked_verts_to_new_mesh(const Mesh &src_mesh, Span vertex_map) { BLI_assert(src_mesh.totvert == vertex_map.size()); - const Span src_verts = src_mesh.verts(); - MutableSpan dst_verts = dst_mesh.verts_for_write(); - for (const int i_src : vertex_map.index_range()) { const int i_dst = vertex_map[i_src]; if (i_dst == -1) { continue; } - const MVert &v_src = src_verts[i_src]; - MVert &v_dst = dst_verts[i_dst]; - - v_dst = v_src; CustomData_copy_data(&src_mesh.vdata, &dst_mesh.vdata, i_src, i_dst, 1); } } @@ -370,9 +364,7 @@ static void add_interp_verts_copy_edges_to_new_mesh(const Mesh &src_mesh, { BLI_assert(src_mesh.totvert == vertex_mask.size()); BLI_assert(src_mesh.totedge == r_edge_map.size()); - const Span src_verts = src_mesh.verts(); const Span src_edges = src_mesh.edges(); - MutableSpan dst_verts = dst_mesh.verts_for_write(); MutableSpan dst_edges = dst_mesh.edges_for_write(); uint vert_index = dst_mesh.totvert - verts_add_num; @@ -412,11 +404,6 @@ static void add_interp_verts_copy_edges_to_new_mesh(const Mesh &src_mesh, float weights[2] = {1.0f - fac, fac}; CustomData_interp( &src_mesh.vdata, &dst_mesh.vdata, (int *)&e_src.v1, weights, nullptr, 2, vert_index); - MVert &v = dst_verts[vert_index]; - const MVert &v1 = src_verts[e_src.v1]; - const MVert &v2 = src_verts[e_src.v2]; - - interp_v3_v3v3(v.co, v1.co, v2.co, fac); vert_index++; } } diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c index 822da40edb7..b7cb97bec1d 100644 --- a/source/blender/modifiers/intern/MOD_meshcache.c +++ b/source/blender/modifiers/intern/MOD_meshcache.c @@ -176,35 +176,22 @@ static void meshcache_do(MeshCacheModifierData *mcmd, BKE_modifier_set_error(ob, &mcmd->modifier, "'Integrate' requires faces"); } else { - /* the moons align! */ - int i; - - float(*vertexCos_Source)[3] = MEM_malloc_arrayN( - verts_num, sizeof(*vertexCos_Source), __func__); float(*vertexCos_New)[3] = MEM_malloc_arrayN(verts_num, sizeof(*vertexCos_New), __func__); - const MVert *mv = BKE_mesh_verts(me); - - for (i = 0; i < verts_num; i++, mv++) { - copy_v3_v3(vertexCos_Source[i], mv->co); - } BKE_mesh_calc_relative_deform( BKE_mesh_polys(me), me->totpoly, BKE_mesh_loops(me), me->totvert, - - (const float(*)[3])vertexCos_Source, /* From the original Mesh. */ - (const float(*)[3])vertexCos_Real, /* the input we've been given (shape keys!) */ - - (const float(*)[3])vertexCos, /* The result of this modifier. */ - vertexCos_New /* The result of this function. */ + BKE_mesh_vert_positions(me), /* From the original Mesh. */ + (const float(*)[3])vertexCos_Real, /* the input we've been given (shape keys!) */ + (const float(*)[3])vertexCos, /* The result of this modifier. */ + vertexCos_New /* The result of this function. */ ); /* write the corrected locations back into the result */ memcpy(vertexCos, vertexCos_New, sizeof(*vertexCos) * verts_num); - MEM_freeN(vertexCos_Source); MEM_freeN(vertexCos_New); } } diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.cc b/source/blender/modifiers/intern/MOD_meshsequencecache.cc index ecbb8ebe607..15fa7645430 100644 --- a/source/blender/modifiers/intern/MOD_meshsequencecache.cc +++ b/source/blender/modifiers/intern/MOD_meshsequencecache.cc @@ -60,6 +60,7 @@ # include "usd.h" #endif +using blender::float3; using blender::Span; static void initData(ModifierData *md) @@ -200,17 +201,17 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } if (me != nullptr) { - const Span mesh_verts = mesh->verts(); + const Span mesh_positions = mesh->vert_positions(); const Span mesh_edges = mesh->edges(); const Span mesh_polys = mesh->polys(); - const Span me_verts = me->verts(); + const Span me_positions = me->vert_positions(); const Span me_edges = me->edges(); const Span me_polys = me->polys(); /* TODO(sybren+bastien): possibly check relevant custom data layers (UV/color depending on * flags) and duplicate those too. * XXX(Hans): This probably isn't true anymore with various CoW improvements, etc. */ - if ((me_verts.data() == mesh_verts.data()) || (me_edges.data() == mesh_edges.data()) || + if ((me_positions.data() == mesh_positions.data()) || (me_edges.data() == mesh_edges.data()) || (me_polys.data() == mesh_polys.data())) { /* We need to duplicate data here, otherwise we'll modify org mesh, see T51701. */ mesh = reinterpret_cast( diff --git a/source/blender/modifiers/intern/MOD_multires.cc b/source/blender/modifiers/intern/MOD_multires.cc index 2bc3763c46b..8b379f8ac60 100644 --- a/source/blender/modifiers/intern/MOD_multires.cc +++ b/source/blender/modifiers/intern/MOD_multires.cc @@ -219,7 +219,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * mesh->flag & ME_AUTOSMOOTH && CustomData_has_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); /* NOTE: Orco needs final coordinates on CPU side, which are expected to be - * accessible via MVert. For this reason we do not evaluate multires to + * accessible via mesh vertices. For this reason we do not evaluate multires to * grids when orco is requested. */ const bool for_orco = (ctx->flag & MOD_APPLY_ORCO) != 0; /* Needed when rendering or baking will in sculpt mode. */ @@ -244,7 +244,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * sculpt_session->multires.level = mmd->sculptlvl; sculpt_session->totvert = mesh->totvert; sculpt_session->totpoly = mesh->totpoly; - sculpt_session->mvert = nullptr; + sculpt_session->vert_positions = nullptr; sculpt_session->mpoly = nullptr; sculpt_session->mloop = nullptr; } diff --git a/source/blender/modifiers/intern/MOD_normal_edit.cc b/source/blender/modifiers/intern/MOD_normal_edit.cc index cc25f032228..a3295ae24de 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.cc +++ b/source/blender/modifiers/intern/MOD_normal_edit.cc @@ -47,15 +47,16 @@ static void generate_vert_coordinates(Mesh *mesh, float (*r_cos)[3], float r_size[3]) { + using namespace blender; float min_co[3], max_co[3]; float diff[3]; bool do_diff = false; INIT_MINMAX(min_co, max_co); - const MVert *mv = BKE_mesh_verts(mesh); - for (int i = 0; i < mesh->totvert; i++, mv++) { - copy_v3_v3(r_cos[i], mv->co); + const Span positions = mesh->vert_positions(); + for (int i = 0; i < mesh->totvert; i++) { + copy_v3_v3(r_cos[i], positions[i]); if (r_size != nullptr && ob_center == nullptr) { minmax_v3v3_v3(min_co, max_co, r_cos[i]); } @@ -221,7 +222,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, const MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup, - const MVert *mvert, + const float (*vert_positions)[3], const int verts_num, MEdge *medge, const int edges_num, @@ -329,7 +330,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, BKE_mesh_normals_tag_dirty(mesh); } - BKE_mesh_normals_loop_custom_set(mvert, + BKE_mesh_normals_loop_custom_set(vert_positions, BKE_mesh_vertex_normals_ensure(mesh), verts_num, medge, @@ -360,7 +361,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, const MDeformVert *dvert, const int defgrp_index, const bool use_invert_vgroup, - const MVert *mvert, + const float (*positions)[3], const int verts_num, MEdge *medge, const int edges_num, @@ -445,7 +446,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, BKE_mesh_normals_tag_dirty(mesh); } - BKE_mesh_normals_loop_custom_set(mvert, + BKE_mesh_normals_loop_custom_set(positions, BKE_mesh_vertex_normals_ensure(mesh), verts_num, medge, @@ -527,7 +528,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, const int edges_num = result->totedge; const int loops_num = result->totloop; const int polys_num = result->totpoly; - const MVert *verts = BKE_mesh_verts(result); + const float(*positions)[3] = BKE_mesh_vert_positions(result); MEdge *edges = BKE_mesh_edges_for_write(result); const MPoly *polys = BKE_mesh_polys(result); MLoop *loops = BKE_mesh_loops_for_write(result); @@ -549,7 +550,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, loop_normals = static_cast( MEM_malloc_arrayN(size_t(loops_num), sizeof(*loop_normals), __func__)); - BKE_mesh_normals_loop_split(verts, + BKE_mesh_normals_loop_split(positions, vert_normals, verts_num, edges, @@ -588,7 +589,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, dvert, defgrp_index, use_invert_vgroup, - verts, + positions, verts_num, edges, edges_num, @@ -611,7 +612,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, dvert, defgrp_index, use_invert_vgroup, - verts, + positions, verts_num, edges, edges_num, diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index bee1bd7795a..336b36a69c6 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -154,7 +154,7 @@ static bool dependsOnNormals(ModifierData *md) #ifdef WITH_OCEANSIM typedef struct GenerateOceanGeometryData { - MVert *mverts; + float (*vert_positions)[3]; MPoly *mpolys; MLoop *mloops; MLoopUV *mloopuvs; @@ -175,7 +175,7 @@ static void generate_ocean_geometry_verts(void *__restrict userdata, for (x = 0; x <= gogd->res_x; x++) { const int i = y * (gogd->res_x + 1) + x; - float *co = gogd->mverts[i].co; + float *co = gogd->vert_positions[i]; co[0] = gogd->ox + (x * gogd->sx); co[1] = gogd->oy + (y * gogd->sy); co[2] = 0.0f; @@ -270,7 +270,7 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co result = BKE_mesh_new_nomain(verts_num, 0, 0, polys_num * 4, polys_num); BKE_mesh_copy_parameters_for_eval(result, mesh_orig); - gogd.mverts = BKE_mesh_verts_for_write(result); + gogd.vert_positions = BKE_mesh_vert_positions_for_write(result); gogd.mpolys = BKE_mesh_polys_for_write(result); gogd.mloops = BKE_mesh_loops_for_write(result); @@ -363,15 +363,15 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes CLAMP(cfra_for_cache, omd->bakestart, omd->bakeend); cfra_for_cache -= omd->bakestart; /* shift to 0 based */ - MVert *verts = BKE_mesh_verts_for_write(result); - MPoly *polys = BKE_mesh_polys_for_write(result); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(result); + const MPoly *polys = BKE_mesh_polys(result); /* add vcols before displacement - allows lookup based on position */ if (omd->flag & MOD_OCEAN_GENERATE_FOAM) { const int polys_num = result->totpoly; const int loops_num = result->totloop; - MLoop *mloops = BKE_mesh_loops_for_write(result); + const MLoop *mloops = BKE_mesh_loops(result); MLoopCol *mloopcols = CustomData_add_layer_named( &result->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, NULL, loops_num, omd->foamlayername); @@ -386,10 +386,10 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes } if (mloopcols) { /* unlikely to fail */ - MPoly *mp; + const MPoly *mp; for (i = 0, mp = polys; i < polys_num; i++, mp++) { - MLoop *ml = &mloops[mp->loopstart]; + const MLoop *ml = &mloops[mp->loopstart]; MLoopCol *mlcol = &mloopcols[mp->loopstart]; MLoopCol *mlcolspray = NULL; @@ -398,7 +398,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes } for (j = mp->totloop; j--; ml++, mlcol++) { - const float *vco = verts[ml->v].co; + const float *vco = positions[ml->v]; const float u = OCEAN_CO(size_co_inv, vco[0]); const float v = OCEAN_CO(size_co_inv, vco[1]); float foam; @@ -446,7 +446,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes const int verts_num = result->totvert; for (i = 0; i < verts_num; i++) { - float *vco = verts[i].co; + float *vco = positions[i]; const float u = OCEAN_CO(size_co_inv, vco[0]); const float v = OCEAN_CO(size_co_inv, vco[1]); diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 46e14dd6bfb..e0677751a16 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -315,10 +315,9 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * result = BKE_mesh_new_nomain_from_template(mesh, maxvert, maxedge, 0, maxloop, maxpoly); - const MVert *orig_mvert = BKE_mesh_verts(mesh); const MPoly *orig_mpoly = BKE_mesh_polys(mesh); const MLoop *orig_mloop = BKE_mesh_loops(mesh); - MVert *mvert = BKE_mesh_verts_for_write(result); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(result); MEdge *edges = BKE_mesh_edges_for_write(result); MPoly *mpoly = BKE_mesh_polys_for_write(result); MLoop *mloop = BKE_mesh_loops_for_write(result); @@ -349,13 +348,9 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* set vertices coordinates */ for (k = 0; k < totvert; k++) { ParticleKey state; - const MVert *inMV; int vindex = p_skip * totvert + k; - MVert *mv = mvert + vindex; - inMV = orig_mvert + k; - CustomData_copy_data(&mesh->vdata, &result->vdata, k, p_skip * totvert + k, 1); - *mv = *inMV; + CustomData_copy_data(&mesh->vdata, &result->vdata, k, vindex, 1); if (vert_part_index != NULL) { vert_part_index[vindex] = p; @@ -365,10 +360,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } /* Change orientation based on object trackflag. */ - copy_v3_v3(temp_co, mv->co); - mv->co[axis] = temp_co[track]; - mv->co[(axis + 1) % 3] = temp_co[(track + 1) % 3]; - mv->co[(axis + 2) % 3] = temp_co[(track + 2) % 3]; + copy_v3_v3(temp_co, positions[vindex]); + positions[vindex][axis] = temp_co[track]; + positions[vindex][(axis + 1) % 3] = temp_co[(track + 1) % 3]; + positions[vindex][(axis + 2) % 3] = temp_co[(track + 2) % 3]; /* get particle state */ if ((psys->flag & (PSYS_HAIR_DONE | PSYS_KEYED) || psys->pointcache->flag & PTCACHE_BAKED) && @@ -382,13 +377,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * state.time = pimd->position * (1.0f - ran); } else { - state.time = (mv->co[axis] - min_co) / (max_co - min_co) * pimd->position * (1.0f - ran); + state.time = (positions[vindex][axis] - min_co) / (max_co - min_co) * pimd->position * + (1.0f - ran); if (trackneg) { state.time = 1.0f - state.time; } - mv->co[axis] = 0.0; + positions[vindex][axis] = 0.0; } psys_get_particle_on_path(&sim, p, &state, 1); @@ -462,13 +458,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * psys_get_particle_state(&sim, p, &state, 1); } - mul_qt_v3(state.rot, mv->co); + mul_qt_v3(state.rot, positions[vindex]); if (pimd->flag & eParticleInstanceFlag_UseSize) { - mul_v3_fl(mv->co, size[p]); + mul_v3_fl(positions[vindex], size[p]); } - add_v3_v3(mv->co, state.co); + add_v3_v3(positions[vindex], state.co); - mul_m4_v3(spacemat, mv->co); + mul_m4_v3(spacemat, positions[vindex]); } /* Create edges and adjust edge vertex indices. */ diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c index d6241fcb290..220b9e87aff 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.c @@ -60,8 +60,8 @@ static void init_dualcon_mesh(DualConInput *input, Mesh *mesh) { memset(input, 0, sizeof(DualConInput)); - input->co = (void *)BKE_mesh_verts(mesh); - input->co_stride = sizeof(MVert); + input->co = (void *)BKE_mesh_vert_positions(mesh); + input->co_stride = sizeof(float[3]); input->totco = mesh->totvert; input->mloop = (void *)BKE_mesh_loops(mesh); @@ -79,7 +79,7 @@ static void init_dualcon_mesh(DualConInput *input, Mesh *mesh) * keep track of the current elements */ typedef struct { Mesh *mesh; - MVert *verts; + float (*vert_positions)[3]; MPoly *polys; MLoop *loops; int curvert, curface; @@ -95,7 +95,7 @@ static void *dualcon_alloc_output(int totvert, int totquad) } output->mesh = BKE_mesh_new_nomain(totvert, 0, 0, 4 * totquad, totquad); - output->verts = BKE_mesh_verts_for_write(output->mesh); + output->vert_positions = BKE_mesh_vert_positions_for_write(output->mesh); output->polys = BKE_mesh_polys_for_write(output->mesh); output->loops = BKE_mesh_loops_for_write(output->mesh); @@ -108,7 +108,7 @@ static void dualcon_add_vert(void *output_v, const float co[3]) BLI_assert(output->curvert < output->mesh->totvert); - copy_v3_v3(output->verts[output->curvert].co, co); + copy_v3_v3(output->vert_positions[output->curvert], co); output->curvert++; } diff --git a/source/blender/modifiers/intern/MOD_screw.cc b/source/blender/modifiers/intern/MOD_screw.cc index d1660d0ced4..e6e89ac7789 100644 --- a/source/blender/modifiers/intern/MOD_screw.cc +++ b/source/blender/modifiers/intern/MOD_screw.cc @@ -115,7 +115,7 @@ static void screwvert_iter_step(ScrewVertIter *iter) } static Mesh *mesh_remove_doubles_on_axis(Mesh *result, - MVert *mvert_new, + float (*vert_positions_new)[3], const uint totvert, const uint step_tot, const float axis_vec[3], @@ -131,18 +131,18 @@ static Mesh *mesh_remove_doubles_on_axis(Mesh *result, float axis_co[3]; if (use_offset) { float offset_co[3]; - sub_v3_v3v3(offset_co, mvert_new[i].co, axis_offset); + sub_v3_v3v3(offset_co, vert_positions_new[i], axis_offset); project_v3_v3v3_normalized(axis_co, offset_co, axis_vec); add_v3_v3(axis_co, axis_offset); } else { - project_v3_v3v3_normalized(axis_co, mvert_new[i].co, axis_vec); + project_v3_v3v3_normalized(axis_co, vert_positions_new[i], axis_vec); } - const float dist_sq = len_squared_v3v3(axis_co, mvert_new[i].co); + const float dist_sq = len_squared_v3v3(axis_co, vert_positions_new[i]); if (dist_sq <= merge_threshold_sq) { BLI_BITMAP_ENABLE(vert_tag, i); tot_doubles += 1; - copy_v3_v3(mvert_new[i].co, axis_co); + copy_v3_v3(vert_positions_new[i], axis_co); } } @@ -241,8 +241,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MPoly *mp_new; MLoop *ml_new; MEdge *med_new, *med_new_firstloop; - MVert *mv_new, *mv_new_base; - const MVert *mv_orig; Object *ob_axis = ltmd->ob_axis; ScrewVertConnect *vc, *vc_tmp, *vert_connect = nullptr; @@ -382,12 +380,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * result = BKE_mesh_new_nomain_from_template( mesh, int(maxVerts), int(maxEdges), 0, int(maxPolys) * 4, int(maxPolys)); - const MVert *mvert_orig = BKE_mesh_verts(mesh); + const float(*vert_positions_orig)[3] = BKE_mesh_vert_positions(mesh); const MEdge *medge_orig = BKE_mesh_edges(mesh); const MPoly *mpoly_orig = BKE_mesh_polys(mesh); const MLoop *mloop_orig = BKE_mesh_loops(mesh); - MVert *mvert_new = BKE_mesh_verts_for_write(result); + float(*vert_positions_new)[3] = BKE_mesh_vert_positions_for_write(result); MEdge *medge_new = BKE_mesh_edges_for_write(result); MPoly *mpoly_new = BKE_mesh_polys_for_write(result); MLoop *mloop_new = BKE_mesh_loops_for_write(result); @@ -413,8 +411,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) { - for (i = 0, mv_orig = mvert_orig; i < totvert; i++, mv_orig++) { - const float v = dist_signed_squared_to_plane_v3(mv_orig->co, uv_axis_plane); + for (i = 0; i < totvert; i++) { + const float v = dist_signed_squared_to_plane_v3(vert_positions_orig[i], uv_axis_plane); uv_v_minmax[0] = min_ff(v, uv_v_minmax[0]); uv_v_minmax[1] = max_ff(v, uv_v_minmax[1]); } @@ -428,9 +426,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* Set the locations of the first set of verts */ - mv_new = mvert_new; - mv_orig = mvert_orig; - /* Copy the first set of edges */ const MEdge *med_orig = medge_orig; med_new = medge_new; @@ -476,22 +471,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * * Sort edge verts for correct face flipping * NOT REALLY NEEDED but face flipping is nice. */ - /* Notice! - * - * Since we are only ordering the edges here it can avoid mallocing the - * extra space by abusing the vert array before its filled with new verts. - * The new array for vert_connect must be at least `sizeof(ScrewVertConnect) * totvert` - * and the size of our resulting meshes array is `sizeof(MVert) * totvert * 3` - * so its safe to use the second 2 thirds of #MVert the array for vert_connect, - * just make sure #ScrewVertConnect struct is no more than twice as big as #MVert, - * at the moment there is no chance of that being a problem, - * unless #MVert becomes half its current size. - * - * once the edges are ordered, vert_connect is not needed and it can be used for verts - * - * This makes the modifier faster with one less allocate. - */ - vert_connect = static_cast( MEM_malloc_arrayN(totvert, sizeof(ScrewVertConnect), __func__)); /* skip the first slice of verts. */ @@ -503,14 +482,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * // printf("\n\n\n\n\nStarting Modifier\n"); /* set edge users */ med_new = medge_new; - mv_new = mvert_new; if (ob_axis != nullptr) { /* `mtx_tx` is initialized early on. */ - for (i = 0; i < totvert; i++, mv_new++, mv_orig++, vc++) { - vc->co[0] = mv_new->co[0] = mv_orig->co[0]; - vc->co[1] = mv_new->co[1] = mv_orig->co[1]; - vc->co[2] = mv_new->co[2] = mv_orig->co[2]; + for (i = 0; i < totvert; i++, vc++) { + vc->co[0] = vert_positions_new[i][0] = vert_positions_orig[i][0]; + vc->co[1] = vert_positions_new[i][1] = vert_positions_orig[i][1]; + vc->co[2] = vert_positions_new[i][2] = vert_positions_orig[i][2]; vc->flag = 0; vc->e[0] = vc->e[1] = nullptr; @@ -525,10 +503,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } } else { - for (i = 0; i < totvert; i++, mv_new++, mv_orig++, vc++) { - vc->co[0] = mv_new->co[0] = mv_orig->co[0]; - vc->co[1] = mv_new->co[1] = mv_orig->co[1]; - vc->co[2] = mv_new->co[2] = mv_orig->co[2]; + for (i = 0; i < totvert; i++, vc++) { + vc->co[0] = vert_positions_new[i][0] = vert_positions_orig[i][0]; + vc->co[1] = vert_positions_new[i][1] = vert_positions_orig[i][1]; + vc->co[2] = vert_positions_new[i][2] = vert_positions_orig[i][2]; vc->flag = 0; vc->e[0] = vc->e[1] = nullptr; @@ -755,11 +733,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } } else { - mv_orig = mvert_orig; - mv_new = mvert_new; - - for (i = 0; i < totvert; i++, mv_new++, mv_orig++) { - copy_v3_v3(mv_new->co, mv_orig->co); + for (i = 0; i < totvert; i++) { + copy_v3_v3(vert_positions_new[i], vert_positions_orig[i]); } } /* done with edge connectivity based normal flipping */ @@ -787,25 +762,24 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * /* copy a slice */ CustomData_copy_data(&mesh->vdata, &result->vdata, 0, int(varray_stride), int(totvert)); - mv_new_base = mvert_new; - mv_new = &mvert_new[varray_stride]; /* advance to the next slice */ + /* set location */ + for (j = 0; j < totvert; j++) { + const int vert_new = int(varray_stride) + int(j); - for (j = 0; j < totvert; j++, mv_new_base++, mv_new++) { - /* set location */ - copy_v3_v3(mv_new->co, mv_new_base->co); + copy_v3_v3(vert_positions_new[vert_new], vert_positions_new[j]); /* only need to set these if using non cleared memory */ // mv_new->mat_nr = mv_new->flag = 0; if (ob_axis != nullptr) { - sub_v3_v3(mv_new->co, mtx_tx[3]); + sub_v3_v3(vert_positions_new[vert_new], mtx_tx[3]); - mul_m4_v3(mat, mv_new->co); + mul_m4_v3(mat, vert_positions_new[vert_new]); - add_v3_v3(mv_new->co, mtx_tx[3]); + add_v3_v3(vert_positions_new[vert_new], mtx_tx[3]); } else { - mul_m4_v3(mat, mv_new->co); + mul_m4_v3(mat, vert_positions_new[vert_new]); } /* add the new edge */ @@ -870,8 +844,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } if (has_mloop_orig == false && mloopuv_layers_tot) { - uv_v_offset_a = dist_signed_to_plane_v3(mvert_new[medge_new[i].v1].co, uv_axis_plane); - uv_v_offset_b = dist_signed_to_plane_v3(mvert_new[medge_new[i].v2].co, uv_axis_plane); + uv_v_offset_a = dist_signed_to_plane_v3(vert_positions_new[medge_new[i].v1], uv_axis_plane); + uv_v_offset_b = dist_signed_to_plane_v3(vert_positions_new[medge_new[i].v2], uv_axis_plane); if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) { uv_v_offset_a = (uv_v_offset_a - uv_v_minmax[0]) * uv_v_range_inv; @@ -989,7 +963,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * med_new++; } - /* validate loop edges */ +/* validate loop edges */ #if 0 { uint i = 0; @@ -1026,7 +1000,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * if (do_remove_doubles) { result = mesh_remove_doubles_on_axis(result, - mvert_new, + vert_positions_new, totvert, step_tot, axis_vec, diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index df8b9d53a2f..b5e66a1af79 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -56,12 +56,6 @@ static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_ma if (smd->vgroup_name[0] != '\0') { r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; } - - if ((smd->shrinkType == MOD_SHRINKWRAP_PROJECT) && - (smd->projAxis == MOD_SHRINKWRAP_PROJECT_OVER_NORMAL)) { - /* XXX Really? These should always be present, always... */ - r_cddata_masks->vmask |= CD_MASK_MVERT; - } } static bool isDisabled(const struct Scene *UNUSED(scene), diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 4b0301f2884..b7b8c9cbe53 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -132,12 +132,12 @@ typedef enum { } SkinNodeFlag; typedef struct Frame { - /* Index in the MVert array */ + /* Index in the vertex array */ BMVert *verts[4]; /* Location of each corner */ float co[4][3]; /* Indicates which corners have been merged with another - * frame's corner (so they share an MVert index) */ + * frame's corner (so they share a vertex index) */ struct { /* Merge to target frame/corner (no merge if frame is null) */ struct Frame *frame; @@ -520,7 +520,7 @@ static float half_v2(const float v[2]) static void end_node_frames(int v, SkinNode *skin_nodes, - const MVert *mvert, + const float (*vert_positions)[3], const MVertSkin *nodes, const MeshElemMap *emap, EMat *emat) @@ -540,8 +540,8 @@ static void end_node_frames(int v, mat[0][2] = mat[1][0] = mat[2][1] = 1; /* Caps */ - create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, avg); - create_frame(&skin_nodes[v].frames[1], mvert[v].co, rad, mat, -avg); + create_frame(&skin_nodes[v].frames[0], vert_positions[v], rad, mat, avg); + create_frame(&skin_nodes[v].frames[1], vert_positions[v], rad, mat, -avg); } else { /* For nodes with an incoming edge, create a single (capped) frame */ @@ -557,7 +557,7 @@ static void end_node_frames(int v, Frame *frame = &skin_nodes[v].frames[0]; /* End frame */ - create_frame(frame, mvert[v].co, rad, mat, 0); + create_frame(frame, vert_positions[v], rad, mat, 0); /* The caps might need to have their normals inverted. So check if they * need to be flipped when creating faces. */ @@ -605,7 +605,7 @@ static int connection_node_mat(float mat[3][3], int v, const MeshElemMap *emap, static void connection_node_frames(int v, SkinNode *skin_nodes, - const MVert *mvert, + const float (*vert_positions)[3], const MVertSkin *nodes, const MeshElemMap *emap, EMat *emat) @@ -630,14 +630,14 @@ static void connection_node_frames(int v, if (e1->origin != v) { negate_v3(mat[0]); } - create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, avg); + create_frame(&skin_nodes[v].frames[0], vert_positions[v], rad, mat, avg); skin_nodes[v].seam_edges[0] = emap[v].indices[0]; copy_m3_m3(mat, e2->mat); if (e2->origin != v) { negate_v3(mat[0]); } - create_frame(&skin_nodes[v].frames[1], mvert[v].co, rad, mat, avg); + create_frame(&skin_nodes[v].frames[1], vert_positions[v], rad, mat, avg); skin_nodes[v].seam_edges[1] = emap[v].indices[1]; return; @@ -645,11 +645,14 @@ static void connection_node_frames(int v, /* Build regular frame */ node_frames_init(&skin_nodes[v], 1); - create_frame(&skin_nodes[v].frames[0], mvert[v].co, rad, mat, 0); + create_frame(&skin_nodes[v].frames[0], vert_positions[v], rad, mat, 0); } -static SkinNode *build_frames( - const MVert *mvert, int verts_num, const MVertSkin *nodes, const MeshElemMap *emap, EMat *emat) +static SkinNode *build_frames(const float (*vert_positions)[3], + int verts_num, + const MVertSkin *nodes, + const MeshElemMap *emap, + EMat *emat) { SkinNode *skin_nodes; int v; @@ -658,10 +661,10 @@ static SkinNode *build_frames( for (v = 0; v < verts_num; v++) { if (emap[v].count <= 1) { - end_node_frames(v, skin_nodes, mvert, nodes, emap, emat); + end_node_frames(v, skin_nodes, vert_positions, nodes, emap, emat); } else if (emap[v].count == 2) { - connection_node_frames(v, skin_nodes, mvert, nodes, emap, emat); + connection_node_frames(v, skin_nodes, vert_positions, nodes, emap, emat); } else { /* Branch node generates no frames */ @@ -714,7 +717,7 @@ static void build_emats_stack(BLI_Stack *stack, const MeshElemMap *emap, const MEdge *medge, const MVertSkin *vs, - const MVert *mvert) + const float (*vert_positions)[3]) { EdgeStackElem stack_elem; float axis[3], angle; @@ -741,11 +744,11 @@ static void build_emats_stack(BLI_Stack *stack, /* If parent is a branch node, start a new edge chain */ if (parent_is_branch) { - calc_edge_mat(emat[e].mat, mvert[parent_v].co, mvert[v].co); + calc_edge_mat(emat[e].mat, vert_positions[parent_v], vert_positions[v]); } else { /* Build edge matrix guided by parent matrix */ - sub_v3_v3v3(emat[e].mat[0], mvert[v].co, mvert[parent_v].co); + sub_v3_v3v3(emat[e].mat[0], vert_positions[v], vert_positions[parent_v]); normalize_v3(emat[e].mat[0]); angle = angle_normalized_v3v3(stack_elem.mat[0], emat[e].mat[0]); cross_v3_v3v3(axis, stack_elem.mat[0], emat[e].mat[0]); @@ -765,7 +768,7 @@ static void build_emats_stack(BLI_Stack *stack, } static EMat *build_edge_mats(const MVertSkin *vs, - const MVert *mvert, + const float (*vert_positions)[3], const int verts_num, const MEdge *medge, const MeshElemMap *emap, @@ -789,7 +792,8 @@ static EMat *build_edge_mats(const MVertSkin *vs, if (vs[v].flag & MVERT_SKIN_ROOT) { if (emap[v].count >= 1) { const MEdge *e = &medge[emap[v].indices[0]]; - calc_edge_mat(stack_elem.mat, mvert[v].co, mvert[BKE_mesh_edge_other_vert(e, v)].co); + calc_edge_mat( + stack_elem.mat, vert_positions[v], vert_positions[BKE_mesh_edge_other_vert(e, v)]); stack_elem.parent_v = v; /* Add adjacent edges to stack */ @@ -809,7 +813,7 @@ static EMat *build_edge_mats(const MVertSkin *vs, } while (!BLI_stack_is_empty(stack)) { - build_emats_stack(stack, visited_e, emat, emap, medge, vs, mvert); + build_emats_stack(stack, visited_e, emat, emap, medge, vs, vert_positions); } MEM_freeN(visited_e); @@ -825,7 +829,7 @@ static EMat *build_edge_mats(const MVertSkin *vs, * nodes, at least two intermediate frames are required. (This avoids * having any special cases for dealing with sharing a frame between * two hulls.) */ -static int calc_edge_subdivisions(const MVert *mvert, +static int calc_edge_subdivisions(const float (*vert_positions)[3], const MVertSkin *nodes, const MEdge *e, const int *degree) @@ -855,7 +859,7 @@ static int calc_edge_subdivisions(const MVert *mvert, if (avg_radius != 0.0f) { /* possible (but unlikely) that we overflow INT_MAX */ float subdivisions_num_fl; - const float edge_len = len_v3v3(mvert[e->v1].co, mvert[e->v2].co); + const float edge_len = len_v3v3(vert_positions[e->v1], vert_positions[e->v2]); subdivisions_num_fl = (edge_len / avg_radius); if (subdivisions_num_fl < NUM_SUBDIVISIONS_MAX) { subdivisions_num = (int)subdivisions_num_fl; @@ -889,7 +893,7 @@ static Mesh *subdivide_base(const Mesh *orig) float radrat; const MVertSkin *orignode = CustomData_get_layer(&orig->vdata, CD_MVERT_SKIN); - const MVert *origvert = BKE_mesh_verts(orig); + const float(*orig_vert_positions)[3] = BKE_mesh_vert_positions(orig); const MEdge *origedge = BKE_mesh_edges(orig); const MDeformVert *origdvert = BKE_mesh_deform_verts(orig); int orig_vert_num = orig->totvert; @@ -905,7 +909,7 @@ static Mesh *subdivide_base(const Mesh *orig) /* Per edge, store how many subdivisions are needed */ int *edge_subd = MEM_calloc_arrayN((uint)orig_edge_num, sizeof(int), "edge_subd"); for (i = 0, subd_num = 0; i < orig_edge_num; i++) { - edge_subd[i] += calc_edge_subdivisions(origvert, orignode, &origedge[i], degree); + edge_subd[i] += calc_edge_subdivisions(orig_vert_positions, orignode, &origedge[i], degree); BLI_assert(edge_subd[i] >= 0); subd_num += edge_subd[i]; } @@ -916,7 +920,7 @@ static Mesh *subdivide_base(const Mesh *orig) Mesh *result = BKE_mesh_new_nomain_from_template( orig, orig_vert_num + subd_num, orig_edge_num + subd_num, 0, 0, 0); - MVert *outvert = BKE_mesh_verts_for_write(result); + float(*out_vert_positions)[3] = BKE_mesh_vert_positions_for_write(result); MEdge *outedge = BKE_mesh_edges_for_write(result); MVertSkin *outnode = CustomData_get_layer(&result->vdata, CD_MVERT_SKIN); MDeformVert *outdvert = NULL; @@ -978,7 +982,8 @@ static Mesh *subdivide_base(const Mesh *orig) float t = powf(r, radrat); /* Interpolate vertex coord */ - interp_v3_v3v3(outvert[v].co, outvert[e->v1].co, outvert[e->v2].co, t); + interp_v3_v3v3( + out_vert_positions[v], out_vert_positions[e->v1], out_vert_positions[e->v2], t); /* Interpolate skin radii */ interp_v3_v3v3(outnode[v].radius, orignode[e->v1].radius, orignode[e->v2].radius, t); @@ -1910,7 +1915,6 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_ SkinNode *skin_nodes; MeshElemMap *emap; int *emapmem; - const MVert *mvert; const MEdge *medge; const MDeformVert *dvert; int verts_num, edges_num; @@ -1918,7 +1922,7 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_ nodes = CustomData_get_layer(&origmesh->vdata, CD_MVERT_SKIN); - mvert = BKE_mesh_verts(origmesh); + const float(*vert_positions)[3] = BKE_mesh_vert_positions(origmesh); dvert = BKE_mesh_deform_verts(origmesh); medge = BKE_mesh_edges(origmesh); verts_num = origmesh->totvert; @@ -1926,8 +1930,9 @@ static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_ BKE_mesh_vert_edge_map_create(&emap, &emapmem, medge, verts_num, edges_num); - emat = build_edge_mats(nodes, mvert, verts_num, medge, emap, edges_num, &has_valid_root); - skin_nodes = build_frames(mvert, verts_num, nodes, emap, emat); + emat = build_edge_mats( + nodes, vert_positions, verts_num, medge, emap, edges_num, &has_valid_root); + skin_nodes = build_frames(vert_positions, verts_num, nodes, emap, emat); MEM_freeN(emat); emat = NULL; diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c index 08e9569bd95..468f7af4f80 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.c +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c @@ -215,7 +215,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index); - const MVert *orig_mvert = BKE_mesh_verts(mesh); + const float(*orig_vert_positions)[3] = BKE_mesh_vert_positions(mesh); const MEdge *orig_medge = BKE_mesh_edges(mesh); const MPoly *orig_mpoly = BKE_mesh_polys(mesh); const MLoop *orig_mloop = BKE_mesh_loops(mesh); @@ -335,7 +335,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex (int)((loops_num * stride) + newLoops), (int)((polys_num * stride) + newPolys)); - MVert *mvert = BKE_mesh_verts_for_write(result); + float(*vert_positions)[3] = BKE_mesh_vert_positions_for_write(result); MEdge *medge = BKE_mesh_edges_for_write(result); MPoly *mpoly = BKE_mesh_polys_for_write(result); MLoop *mloop = BKE_mesh_loops_for_write(result); @@ -398,7 +398,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (((ofs_new >= ofs_orig) == do_flip) == test) { \ i_end = verts_num; \ do_shell_align = true; \ - mv = mvert; \ + vert_index = 0; \ } \ else { \ if (do_shell) { \ @@ -409,7 +409,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex i_end = newVerts; \ do_shell_align = false; \ } \ - mv = &mvert[verts_num]; \ + vert_index = verts_num; \ } \ (void)0 @@ -495,7 +495,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex vert_lens = MEM_malloc_arrayN(verts_num, sizeof(float), "vert_lens"); copy_vn_fl(vert_lens, (int)verts_num, FLT_MAX); for (uint i = 0; i < edges_num; i++) { - const float ed_len_sq = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co); + const float ed_len_sq = len_squared_v3v3(vert_positions[medge[i].v1], + vert_positions[medge[i].v2]); vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len_sq); vert_lens[medge[i].v2] = min_ff(vert_lens[medge[i].v2], ed_len_sq); } @@ -547,7 +548,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex !ELEM(edge_user_pairs[i][1], INVALID_UNUSED, INVALID_PAIR)) { const float *n0 = poly_nors[edge_user_pairs[i][0]]; const float *n1 = poly_nors[edge_user_pairs[i][1]]; - sub_v3_v3v3(e, orig_mvert[ed->v1].co, orig_mvert[ed->v2].co); + sub_v3_v3v3(e, orig_vert_positions[ed->v1], orig_vert_positions[ed->v2]); normalize_v3(e); const float angle = angle_signed_on_axis_v3v3_v3(n0, n1, e); if (do_angle_clamp) { @@ -571,10 +572,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex ofs_new_vgroup = ofs_new; - MVert *mv; + uint vert_index; INIT_VERT_ARRAY_OFFSETS(false); - for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { + for (i_orig = 0; i_orig < i_end; i_orig++, vert_index++) { const uint i = do_shell_align ? i_orig : new_vert_arr[i_orig]; if (dvert) { const MDeformVert *dv = &dvert[i]; @@ -608,10 +609,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } } if (vert_nors) { - madd_v3_v3fl(mv->co, vert_nors[i], ofs_new_vgroup); + madd_v3_v3fl(vert_positions[vert_index], vert_nors[i], ofs_new_vgroup); } else { - madd_v3_v3fl(mv->co, mesh_vert_normals[i], ofs_new_vgroup); + madd_v3_v3fl(vert_positions[vert_index], mesh_vert_normals[i], ofs_new_vgroup); } } } @@ -623,10 +624,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex ofs_new_vgroup = ofs_orig; /* as above but swapped */ - MVert *mv; + uint vert_index; INIT_VERT_ARRAY_OFFSETS(true); - for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { + for (i_orig = 0; i_orig < i_end; i_orig++, vert_index++) { const uint i = do_shell_align ? i_orig : new_vert_arr[i_orig]; if (dvert) { const MDeformVert *dv = &dvert[i]; @@ -660,10 +661,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } } if (vert_nors) { - madd_v3_v3fl(mv->co, vert_nors[i], ofs_new_vgroup); + madd_v3_v3fl(vert_positions[vert_index], vert_nors[i], ofs_new_vgroup); } else { - madd_v3_v3fl(mv->co, mesh_vert_normals[i], ofs_new_vgroup); + madd_v3_v3fl(vert_positions[vert_index], mesh_vert_normals[i], ofs_new_vgroup); } } } @@ -713,8 +714,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (vert_nors == NULL) { vert_nors = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "mod_solid_vno"); - const MVert *mv; - for (i = 0, mv = mvert; i < verts_num; i++, mv++) { + for (i = 0; i < verts_num; i++) { copy_v3_v3(vert_nors[i], mesh_vert_normals[i]); } } @@ -730,12 +730,12 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex const MLoop *ml = &mloop[mp->loopstart]; - sub_v3_v3v3(nor_prev, mvert[ml[i_curr - 1].v].co, mvert[ml[i_curr].v].co); + sub_v3_v3v3(nor_prev, vert_positions[ml[i_curr - 1].v], vert_positions[ml[i_curr].v]); normalize_v3(nor_prev); while (i_next < mp->totloop) { float angle; - sub_v3_v3v3(nor_next, mvert[ml[i_curr].v].co, mvert[ml[i_next].v].co); + sub_v3_v3v3(nor_next, vert_positions[ml[i_curr].v], vert_positions[ml[i_next].v]); normalize_v3(nor_next); angle = angle_normalized_v3v3(nor_prev, nor_next); @@ -847,7 +847,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex vert_angs[ed->v2] = max_ff(vert_angs[ed->v2], angle); } if (do_bevel_convex) { - sub_v3_v3v3(e, orig_mvert[ed->v1].co, orig_mvert[ed->v2].co); + sub_v3_v3v3(e, orig_vert_positions[ed->v1], orig_vert_positions[ed->v2]); normalize_v3(e); edge_angs[i] = angle_signed_on_axis_v3v3_v3(n0, n1, e); if (!do_rim) { @@ -867,7 +867,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex const float offset_sq = offset * offset; copy_vn_fl(vert_lens_sq, (int)verts_num, FLT_MAX); for (i = 0; i < edges_num; i++) { - const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co); + const float ed_len = len_squared_v3v3(vert_positions[medge[i].v1], + vert_positions[medge[i].v2]); vert_lens_sq[medge[i].v1] = min_ff(vert_lens_sq[medge[i].v1], ed_len); vert_lens_sq[medge[i].v2] = min_ff(vert_lens_sq[medge[i].v2], ed_len); } @@ -926,14 +927,15 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex uint i_orig, i_end; bool do_shell_align; - MVert *mv; + uint vert_index; INIT_VERT_ARRAY_OFFSETS(false); - for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { + for (i_orig = 0; i_orig < i_end; i_orig++, vert_index++) { const uint i_other = do_shell_align ? i_orig : new_vert_arr[i_orig]; if (vert_accum[i_other]) { /* zero if unselected */ - madd_v3_v3fl( - mv->co, vert_nors[i_other], ofs_new * (vert_angles[i_other] / vert_accum[i_other])); + madd_v3_v3fl(vert_positions[vert_index], + vert_nors[i_other], + ofs_new * (vert_angles[i_other] / vert_accum[i_other])); } } } @@ -943,14 +945,15 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex bool do_shell_align; /* same as above but swapped, intentional use of 'ofs_new' */ - MVert *mv; + uint vert_index; INIT_VERT_ARRAY_OFFSETS(true); - for (i_orig = 0; i_orig < i_end; i_orig++, mv++) { + for (i_orig = 0; i_orig < i_end; i_orig++, vert_index++) { const uint i_other = do_shell_align ? i_orig : new_vert_arr[i_orig]; if (vert_accum[i_other]) { /* zero if unselected */ - madd_v3_v3fl( - mv->co, vert_nors[i_other], ofs_orig * (vert_angles[i_other] / vert_accum[i_other])); + madd_v3_v3fl(vert_positions[vert_index], + vert_nors[i_other], + ofs_orig * (vert_angles[i_other] / vert_accum[i_other])); } } } @@ -1157,10 +1160,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex #ifdef SOLIDIFY_SIDE_NORMALS if (do_side_normals) { normal_quad_v3(nor, - mvert[ml[j - 4].v].co, - mvert[ml[j - 3].v].co, - mvert[ml[j - 2].v].co, - mvert[ml[j - 1].v].co); + vert_positions[ml[j - 4].v], + vert_positions[ml[j - 3].v], + vert_positions[ml[j - 2].v], + vert_positions[ml[j - 1].v]); add_v3_v3(edge_vert_nos[ed->v1], nor); add_v3_v3(edge_vert_nos[ed->v2], nor); diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index 9d0b5c30b5e..6351adcbe94 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -184,7 +184,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const bool do_flat_faces = dvert && (smd->flag & MOD_SOLIDIFY_NONMANIFOLD_FLAT_FACES); - const MVert *orig_mvert = BKE_mesh_verts(mesh); + const float(*orig_vert_positions)[3] = BKE_mesh_vert_positions(mesh); const MEdge *orig_medge = BKE_mesh_edges(mesh); const MPoly *orig_mpoly = BKE_mesh_polys(mesh); const MLoop *orig_mloop = BKE_mesh_loops(mesh); @@ -220,7 +220,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (len_squared_v3(poly_nors[i]) < 0.5f) { const MEdge *e = orig_medge + orig_mloop[mp->loopstart].e; float edgedir[3]; - sub_v3_v3v3(edgedir, orig_mvert[e->v2].co, orig_mvert[e->v1].co); + sub_v3_v3v3(edgedir, orig_vert_positions[e->v2], orig_vert_positions[e->v1]); if (fabsf(edgedir[2]) < fabsf(edgedir[1])) { poly_nors[i][2] = 1.0f; } @@ -293,9 +293,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, verts_num, sizeof(*orig_mvert_co), "orig_mvert_co in solidify"); /* Fill in the original vertex positions. */ for (uint i = 0; i < verts_num; i++) { - orig_mvert_co[i][0] = orig_mvert[i].co[0]; - orig_mvert_co[i][1] = orig_mvert[i].co[1]; - orig_mvert_co[i][2] = orig_mvert[i].co[2]; + orig_mvert_co[i][0] = orig_vert_positions[i][0]; + orig_mvert_co[i][1] = orig_vert_positions[i][1]; + orig_mvert_co[i][2] = orig_vert_positions[i][2]; } /* Create edge to #NewEdgeRef map. */ @@ -1398,9 +1398,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } } - const MVert *mv = orig_mvert; gs_ptr = orig_vert_groups_arr; - for (uint i = 0; i < verts_num; i++, mv++, gs_ptr++) { + for (uint i = 0; i < verts_num; i++, gs_ptr++) { if (*gs_ptr) { EdgeGroup *g = *gs_ptr; for (uint j = 0; g->valid; j++, g++) { @@ -1962,7 +1961,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, (int)(new_loops_num), (int)(new_polys_num)); - MVert *mvert = BKE_mesh_verts_for_write(result); + float(*vert_positions)[3] = BKE_mesh_vert_positions_for_write(result); MEdge *medge = BKE_mesh_edges_for_write(result); MPoly *mpoly = BKE_mesh_polys_for_write(result); MLoop *mloop = BKE_mesh_loops_for_write(result); @@ -2005,7 +2004,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, for (uint j = 0; g->valid; j++, g++) { if (g->new_vert != MOD_SOLIDIFY_EMPTY_TAG) { CustomData_copy_data(&mesh->vdata, &result->vdata, (int)i, (int)g->new_vert, 1); - copy_v3_v3(mvert[g->new_vert].co, g->co); + copy_v3_v3(vert_positions[g->new_vert], g->co); } } } @@ -2115,8 +2114,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Make boundary edges/faces. */ { gs_ptr = orig_vert_groups_arr; - const MVert *mv = orig_mvert; - for (uint i = 0; i < verts_num; i++, gs_ptr++, mv++) { + for (uint i = 0; i < verts_num; i++, gs_ptr++) { EdgeGroup *gs = *gs_ptr; if (gs) { EdgeGroup *g = gs; diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c index a34d66f394b..ba63468d075 100644 --- a/source/blender/modifiers/intern/MOD_surface.c +++ b/source/blender/modifiers/intern/MOD_surface.c @@ -125,7 +125,6 @@ static void deformVerts(ModifierData *md, if (surmd->mesh) { uint mesh_verts_num = 0, i = 0; int init = 0; - MVert *x, *v; BKE_mesh_vert_coords_apply(surmd->mesh, vertexCos); @@ -142,8 +141,8 @@ static void deformVerts(ModifierData *md, surmd->v = NULL; } - surmd->x = MEM_calloc_arrayN(mesh_verts_num, sizeof(MVert), "MVert"); - surmd->v = MEM_calloc_arrayN(mesh_verts_num, sizeof(MVert), "MVert"); + surmd->x = MEM_calloc_arrayN(mesh_verts_num, sizeof(float[3]), __func__); + surmd->v = MEM_calloc_arrayN(mesh_verts_num, sizeof(float[3]), __func__); surmd->verts_num = mesh_verts_num; @@ -151,19 +150,19 @@ static void deformVerts(ModifierData *md, } /* convert to global coordinates and calculate velocity */ - MVert *verts = BKE_mesh_verts_for_write(surmd->mesh); - for (i = 0, x = surmd->x, v = surmd->v; i < mesh_verts_num; i++, x++, v++) { - float *vec = verts[i].co; + float(*positions)[3] = BKE_mesh_vert_positions_for_write(surmd->mesh); + for (i = 0; i < mesh_verts_num; i++) { + float *vec = positions[i]; mul_m4_v3(ctx->object->object_to_world, vec); if (init) { - v->co[0] = v->co[1] = v->co[2] = 0.0f; + surmd->v[i][0] = surmd->v[i][1] = surmd->v[i][2] = 0.0f; } else { - sub_v3_v3v3(v->co, vec, x->co); + sub_v3_v3v3(surmd->v[i], vec, surmd->x[i]); } - copy_v3_v3(x->co, vec); + copy_v3_v3(surmd->x[i], vec); } surmd->cfra = cfra; diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index 6a9321a78a2..000d44abd99 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -1169,7 +1169,7 @@ static bool surfacedeformBind(Object *ob, Mesh *mesh) { BVHTreeFromMesh treeData = {NULL}; - const MVert *mvert = BKE_mesh_verts(target); + const float(*positions)[3] = BKE_mesh_vert_positions(target); const MPoly *mpoly = BKE_mesh_polys(target); const MEdge *medge = BKE_mesh_edges(target); const MLoop *mloop = BKE_mesh_loops(target); @@ -1268,7 +1268,7 @@ static bool surfacedeformBind(Object *ob, invert_m4_m4(data.imat, smd_orig->mat); for (int i = 0; i < target_verts_num; i++) { - mul_v3_m4v3(data.targetCos[i], smd_orig->mat, mvert[i].co); + mul_v3_m4v3(data.targetCos[i], smd_orig->mat, positions[i]); } TaskParallelSettings settings; diff --git a/source/blender/modifiers/intern/MOD_util.cc b/source/blender/modifiers/intern/MOD_util.cc index 9e8bbc477b7..321478d8470 100644 --- a/source/blender/modifiers/intern/MOD_util.cc +++ b/source/blender/modifiers/intern/MOD_util.cc @@ -129,17 +129,17 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, texmapping = MOD_DISP_MAP_LOCAL; } - const MVert *mv = BKE_mesh_verts(mesh); - for (i = 0; i < verts_num; i++, mv++, r_texco++) { + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); + for (i = 0; i < verts_num; i++, r_texco++) { switch (texmapping) { case MOD_DISP_MAP_LOCAL: - copy_v3_v3(*r_texco, cos != nullptr ? *cos : mv->co); + copy_v3_v3(*r_texco, cos != nullptr ? *cos : positions[i]); break; case MOD_DISP_MAP_GLOBAL: - mul_v3_m4v3(*r_texco, ob->object_to_world, cos != nullptr ? *cos : mv->co); + mul_v3_m4v3(*r_texco, ob->object_to_world, cos != nullptr ? *cos : positions[i]); break; case MOD_DISP_MAP_OBJECT: - mul_v3_m4v3(*r_texco, ob->object_to_world, cos != nullptr ? *cos : mv->co); + mul_v3_m4v3(*r_texco, ob->object_to_world, cos != nullptr ? *cos : positions[i]); mul_m4_v3(mapref_imat, *r_texco); break; } diff --git a/source/blender/modifiers/intern/MOD_uvproject.cc b/source/blender/modifiers/intern/MOD_uvproject.cc index 895572d9477..61e584eaf9d 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.cc +++ b/source/blender/modifiers/intern/MOD_uvproject.cc @@ -235,8 +235,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, float best_dot; /* get the untransformed face normal */ - BKE_mesh_calc_poly_normal_coords( - mp, loops + mp->loopstart, (const float(*)[3])coords, face_no); + BKE_mesh_calc_poly_normal(mp, loops + mp->loopstart, (const float(*)[3])coords, face_no); /* find the projector which the face points at most directly * (projector normal with largest dot product is best) diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.cc b/source/blender/modifiers/intern/MOD_weighted_normal.cc index a7278d13093..c5f20954b03 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.cc +++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc @@ -72,7 +72,7 @@ struct WeightedNormalData { int loops_num; int polys_num; - const MVert *mvert; + const float (*vert_positions)[3]; const float (*vert_normals)[3]; MEdge *medge; @@ -187,7 +187,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, const int loops_num = wn_data->loops_num; const int polys_num = wn_data->polys_num; - const MVert *mvert = wn_data->mvert; + const float(*positions)[3] = wn_data->vert_positions; MEdge *medge = wn_data->medge; const MLoop *mloop = wn_data->mloop; @@ -223,7 +223,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, * we do not actually care about computed loop_normals for now... */ loop_normals = static_cast( MEM_calloc_arrayN(size_t(loops_num), sizeof(*loop_normals), __func__)); - BKE_mesh_normals_loop_split(mvert, + BKE_mesh_normals_loop_split(positions, wn_data->vert_normals, verts_num, medge, @@ -355,7 +355,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, } } - BKE_mesh_normals_loop_custom_set(mvert, + BKE_mesh_normals_loop_custom_set(positions, wn_data->vert_normals, verts_num, medge, @@ -386,7 +386,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, copy_v3_v3(vert_normals[mv_index], items_data[mv_index].normal); } - BKE_mesh_normals_loop_custom_from_verts_set(mvert, + BKE_mesh_normals_loop_custom_from_verts_set(positions, wn_data->vert_normals, vert_normals, verts_num, @@ -405,7 +405,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, loop_normals = static_cast( MEM_calloc_arrayN(size_t(loops_num), sizeof(*loop_normals), __func__)); - BKE_mesh_normals_loop_split(mvert, + BKE_mesh_normals_loop_split(positions, wn_data->vert_normals, verts_num, medge, @@ -429,7 +429,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, } } - BKE_mesh_normals_loop_custom_set(mvert, + BKE_mesh_normals_loop_custom_set(positions, wn_data->vert_normals, verts_num, medge, @@ -454,7 +454,7 @@ static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *w { const int polys_num = wn_data->polys_num; - const MVert *mvert = wn_data->mvert; + const float(*positions)[3] = wn_data->vert_positions; const MLoop *mloop = wn_data->mloop; const MPoly *mpoly = wn_data->mpoly; @@ -466,7 +466,7 @@ static void wn_face_area(WeightedNormalModifierData *wnmd, WeightedNormalData *w ModePair *f_area = face_area; for (mp_index = 0, mp = mpoly; mp_index < polys_num; mp_index++, mp++, f_area++) { - f_area->val = BKE_mesh_calc_poly_area(mp, &mloop[mp->loopstart], mvert); + f_area->val = BKE_mesh_calc_poly_area(mp, &mloop[mp->loopstart], positions); f_area->index = mp_index; } @@ -481,7 +481,7 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData const int loops_num = wn_data->loops_num; const int polys_num = wn_data->polys_num; - const MVert *mvert = wn_data->mvert; + const float(*positions)[3] = wn_data->vert_positions; const MLoop *mloop = wn_data->mloop; const MPoly *mpoly = wn_data->mpoly; @@ -496,7 +496,7 @@ static void wn_corner_angle(WeightedNormalModifierData *wnmd, WeightedNormalData float *index_angle = static_cast( MEM_malloc_arrayN(size_t(mp->totloop), sizeof(*index_angle), __func__)); - BKE_mesh_calc_poly_angles(mp, ml_start, mvert, index_angle); + BKE_mesh_calc_poly_angles(mp, ml_start, positions, index_angle); ModePair *c_angl = &corner_angle[mp->loopstart]; float *angl = index_angle; @@ -519,7 +519,7 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD const int loops_num = wn_data->loops_num; const int polys_num = wn_data->polys_num; - const MVert *mvert = wn_data->mvert; + const float(*positions)[3] = wn_data->vert_positions; const MLoop *mloop = wn_data->mloop; const MPoly *mpoly = wn_data->mpoly; @@ -532,10 +532,10 @@ static void wn_face_with_angle(WeightedNormalModifierData *wnmd, WeightedNormalD for (mp_index = 0, mp = mpoly; mp_index < polys_num; mp_index++, mp++) { const MLoop *ml_start = &mloop[mp->loopstart]; - float face_area = BKE_mesh_calc_poly_area(mp, ml_start, mvert); + float face_area = BKE_mesh_calc_poly_area(mp, ml_start, positions); float *index_angle = static_cast( MEM_malloc_arrayN(size_t(mp->totloop), sizeof(*index_angle), __func__)); - BKE_mesh_calc_poly_angles(mp, ml_start, mvert, index_angle); + BKE_mesh_calc_poly_angles(mp, ml_start, positions, index_angle); ModePair *cmbnd = &combined[mp->loopstart]; float *angl = index_angle; @@ -583,7 +583,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * const int edges_num = result->totedge; const int loops_num = result->totloop; const int polys_num = result->totpoly; - const MVert *mvert = BKE_mesh_verts(result); + const float(*positions)[3] = BKE_mesh_vert_positions(result); MEdge *medge = BKE_mesh_edges_for_write(result); const MPoly *mpoly = BKE_mesh_polys(result); const MLoop *mloop = BKE_mesh_loops(result); @@ -630,7 +630,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * wn_data.loops_num = loops_num; wn_data.polys_num = polys_num; - wn_data.mvert = mvert; + wn_data.vert_positions = positions; wn_data.vert_normals = BKE_mesh_vertex_normals_ensure(result); wn_data.medge = medge; diff --git a/source/blender/modifiers/intern/MOD_weightvg_util.c b/source/blender/modifiers/intern/MOD_weightvg_util.c index 3302384568b..b15b9cf75f1 100644 --- a/source/blender/modifiers/intern/MOD_weightvg_util.c +++ b/source/blender/modifiers/intern/MOD_weightvg_util.c @@ -140,7 +140,7 @@ void weightvg_do_mask(const ModifierEvalContext *ctx, /* Use new generic get_texture_coords, but do not modify our DNA struct for it... * XXX Why use a ModifierData stuff here ? Why not a simple, generic struct for parameters? * What e.g. if a modifier wants to use several textures? - * Why use only v_co, and not MVert (or both)? + * Why use only v_co, and not mesh positions (or both)? */ t_map.texture = texture; t_map.map_object = tex_map_object; diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc index 825913fb985..549ae1e4944 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc @@ -46,11 +46,10 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span coords) } /* Copy vertices. */ - MutableSpan dst_verts = result->verts_for_write(); + MutableSpan dst_positions = result->vert_positions_for_write(); for (const int i : IndexRange(verts_num)) { - float co[3]; int original_index; - plConvexHullGetVertex(hull, i, co, &original_index); + plConvexHullGetVertex(hull, i, dst_positions[i], &original_index); if (original_index >= 0 && original_index < coords.size()) { # if 0 /* Disabled because it only works for meshes, not predictable enough. */ @@ -59,8 +58,6 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span coords) CustomData_copy_data(&mesh->vdata, &result->vdata, int(original_index), int(i), 1); } # endif - /* Copy the position of the original point. */ - copy_v3_v3(dst_verts[i].co, co); } else { BLI_assert_msg(0, "Unexpected new vertex in hull output"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc index eaf0c478e16..acd888c6780 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc @@ -79,13 +79,13 @@ static Mesh *cdt_to_mesh(const meshintersect::CDT_result &result) } Mesh *mesh = BKE_mesh_new_nomain(vert_len, edge_len, 0, loop_len, poly_len); - MutableSpan verts = mesh->verts_for_write(); + MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); for (const int i : IndexRange(result.vert.size())) { - copy_v3_v3(verts[i].co, float3(float(result.vert[i].x), float(result.vert[i].y), 0.0f)); + positions[i] = float3(float(result.vert[i].x), float(result.vert[i].y), 0.0f); } for (const int i : IndexRange(result.edge.size())) { edges[i].v1 = result.edge[i].first; diff --git a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc index 4e38cbf2a28..f748c7384ad 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc @@ -66,11 +66,11 @@ static void deform_curves(const CurvesGeometry &curves, const float4x4 curves_to_surface = surface_to_curves.inverted(); - const Span surface_verts_old = surface_mesh_old.verts(); + const Span surface_positions_old = surface_mesh_old.vert_positions(); const Span surface_loops_old = surface_mesh_old.loops(); const Span surface_looptris_old = surface_mesh_old.looptris(); - const Span surface_verts_new = surface_mesh_new.verts(); + const Span surface_positions_new = surface_mesh_new.vert_positions(); const Span surface_loops_new = surface_mesh_new.loops(); const Span surface_looptris_new = surface_mesh_new.looptris(); @@ -120,14 +120,14 @@ static void deform_curves(const CurvesGeometry &curves, const float3 normal_new = math::normalize( mix3(bary_weights_new, normal_0_new, normal_1_new, normal_2_new)); - const float3 &pos_0_old = surface_verts_old[vert_0_old].co; - const float3 &pos_1_old = surface_verts_old[vert_1_old].co; - const float3 &pos_2_old = surface_verts_old[vert_2_old].co; + const float3 &pos_0_old = surface_positions_old[vert_0_old]; + const float3 &pos_1_old = surface_positions_old[vert_1_old]; + const float3 &pos_2_old = surface_positions_old[vert_2_old]; const float3 pos_old = mix3(bary_weights_old, pos_0_old, pos_1_old, pos_2_old); - const float3 &pos_0_new = surface_verts_new[vert_0_new].co; - const float3 &pos_1_new = surface_verts_new[vert_1_new].co; - const float3 &pos_2_new = surface_verts_new[vert_2_new].co; + const float3 &pos_0_new = surface_positions_new[vert_0_new]; + const float3 &pos_1_new = surface_positions_new[vert_1_new]; + const float3 &pos_2_new = surface_positions_new[vert_2_new]; const float3 pos_new = mix3(bary_weights_new, pos_0_new, pos_1_new, pos_2_new); /* The translation is just the difference between the old and new position on the surface. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc index e92fe1a613d..7bb6b50fe18 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_delete_geometry.cc @@ -153,23 +153,6 @@ static void copy_face_corner_attributes(const Map attributes, src_attributes, dst_attributes, ATTR_DOMAIN_CORNER, IndexMask(indices)); } -static void copy_masked_verts_to_new_mesh(const Mesh &src_mesh, - Mesh &dst_mesh, - Span vertex_map) -{ - BLI_assert(src_mesh.totvert == vertex_map.size()); - const Span src_verts = src_mesh.verts(); - MutableSpan dst_verts = dst_mesh.verts_for_write(); - - for (const int i_src : vertex_map.index_range()) { - const int i_dst = vertex_map[i_src]; - if (i_dst == -1) { - continue; - } - dst_verts[i_dst] = src_verts[i_src]; - } -} - static void copy_masked_edges_to_new_mesh(const Mesh &src_mesh, Mesh &dst_mesh, Span edge_map) { BLI_assert(src_mesh.totedge == edge_map.size()); @@ -899,7 +882,6 @@ static void do_mesh_separation(GeometrySet &geometry_set, selected_polys_num); /* Copy the selected parts of the mesh over to the new mesh. */ - copy_masked_verts_to_new_mesh(mesh_in, *mesh_out, vertex_map); copy_masked_edges_to_new_mesh(mesh_in, *mesh_out, vertex_map, edge_map); copy_masked_polys_to_new_mesh( mesh_in, *mesh_out, vertex_map, edge_map, selected_poly_indices, new_loop_starts); @@ -976,7 +958,7 @@ static void do_mesh_separation(GeometrySet &geometry_set, selected_polys_num); /* Copy the selected parts of the mesh over to the new mesh. */ - mesh_out->verts_for_write().copy_from(mesh_in.verts()); + mesh_out->vert_positions_for_write().copy_from(mesh_in.vert_positions()); copy_masked_edges_to_new_mesh(mesh_in, *mesh_out, edge_map); copy_masked_polys_to_new_mesh( mesh_in, *mesh_out, edge_map, selected_poly_indices, new_loop_starts); @@ -1037,7 +1019,7 @@ static void do_mesh_separation(GeometrySet &geometry_set, &mesh_in, mesh_in.totvert, mesh_in.totedge, 0, selected_loops_num, selected_polys_num); /* Copy the selected parts of the mesh over to the new mesh. */ - mesh_out->verts_for_write().copy_from(mesh_in.verts()); + mesh_out->vert_positions_for_write().copy_from(mesh_in.vert_positions()); mesh_out->edges_for_write().copy_from(mesh_in.edges()); copy_masked_polys_to_new_mesh(mesh_in, *mesh_out, selected_poly_indices, new_loop_starts); diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc index 91fa215d117..d37f36e17a5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc @@ -105,7 +105,7 @@ static void sample_mesh_surface(const Mesh &mesh, Vector &r_bary_coords, Vector &r_looptri_indices) { - const Span verts = mesh.verts(); + const Span positions = mesh.vert_positions(); const Span loops = mesh.loops(); const Span looptris = mesh.looptris(); @@ -117,9 +117,9 @@ static void sample_mesh_surface(const Mesh &mesh, const int v0_index = loops[v0_loop].v; const int v1_index = loops[v1_loop].v; const int v2_index = loops[v2_loop].v; - const float3 v0_pos = verts[v0_index].co; - const float3 v1_pos = verts[v1_index].co; - const float3 v2_pos = verts[v2_index].co; + const float3 v0_pos = positions[v0_index]; + const float3 v1_pos = positions[v1_index]; + const float3 v2_pos = positions[v2_index]; float looptri_density_factor = 1.0f; if (!density_factors.is_empty()) { @@ -348,7 +348,7 @@ BLI_NOINLINE static void compute_attribute_outputs(const Mesh &mesh, attribute_outputs.rotation_id.get(), ATTR_DOMAIN_POINT); } - const Span verts = mesh.verts(); + const Span positions = mesh.vert_positions(); const Span loops = mesh.loops(); const Span looptris = mesh.looptris(); @@ -360,9 +360,9 @@ BLI_NOINLINE static void compute_attribute_outputs(const Mesh &mesh, const int v0_index = loops[looptri.tri[0]].v; const int v1_index = loops[looptri.tri[1]].v; const int v2_index = loops[looptri.tri[2]].v; - const float3 v0_pos = verts[v0_index].co; - const float3 v1_pos = verts[v1_index].co; - const float3 v2_pos = verts[v2_index].co; + const float3 v0_pos = positions[v0_index]; + const float3 v1_pos = positions[v1_index]; + const float3 v2_pos = positions[v2_index]; ids.span[i] = noise::hash(noise::hash_float(bary_coord), looptri_index); diff --git a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc index b076f0b7261..8e51e8ac2b5 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_dual_mesh.cc @@ -613,7 +613,7 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, const bool keep_boundaries, const AnonymousAttributePropagationInfo &propagation_info) { - const Span src_verts = src_mesh.verts(); + const Span src_positions = src_mesh.vert_positions(); const Span src_edges = src_mesh.edges(); const Span src_polys = src_mesh.polys(); const Span src_loops = src_mesh.loops(); @@ -625,7 +625,7 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, * over in order of their indices, the polygon's indices will be sorted in ascending order. * (This can change once they are sorted using `sort_vertex_polys`). */ Array> vert_to_poly_map = bke::mesh_topology::build_vert_to_poly_map( - src_polys, src_loops, src_verts.size()); + src_polys, src_loops, src_positions.size()); Array> vertex_shared_edges(src_mesh.totvert); Array> vertex_corners(src_mesh.totvert); threading::parallel_for(vert_to_poly_map.index_range(), 512, [&](IndexRange range) { @@ -677,8 +677,10 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, Vector vertex_positions(src_mesh.totpoly); for (const int i : IndexRange(src_mesh.totpoly)) { const MPoly &poly = src_polys[i]; - BKE_mesh_calc_poly_center( - &poly, &src_loops[poly.loopstart], src_verts.data(), vertex_positions[i]); + BKE_mesh_calc_poly_center(&poly, + &src_loops[poly.loopstart], + reinterpret_cast(src_positions.data()), + vertex_positions[i]); } Array boundary_edge_midpoint_index; @@ -688,9 +690,8 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, /* We need to add vertices at the centers of boundary edges. */ for (const int i : IndexRange(src_mesh.totedge)) { if (edge_types[i] == EdgeType::Boundary) { - float3 mid; const MEdge &edge = src_edges[i]; - mid_v3_v3v3(mid, src_verts[edge.v1].co, src_verts[edge.v2].co); + const float3 mid = math::midpoint(src_positions[edge.v1], src_positions[edge.v2]); boundary_edge_midpoint_index[i] = vertex_positions.size(); vertex_positions.append(mid); } @@ -841,7 +842,7 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, new_to_old_face_corners_map.append(sorted_corners.first()); boundary_vertex_to_relevant_face_map.append( std::pair(loop_indices.last(), last_face_center)); - vertex_positions.append(src_verts[i].co); + vertex_positions.append(src_positions[i]); const int boundary_vertex = loop_indices.last(); add_edge(src_edges, edge1, @@ -896,7 +897,7 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, src_mesh.attributes(), mesh_out->attributes_for_write()); - MutableSpan dst_verts = mesh_out->verts_for_write(); + mesh_out->vert_positions_for_write().copy_from(vertex_positions); MutableSpan dst_edges = mesh_out->edges_for_write(); MutableSpan dst_polys = mesh_out->polys_for_write(); MutableSpan dst_loops = mesh_out->loops_for_write(); @@ -911,9 +912,6 @@ static Mesh *calc_dual_mesh(const Mesh &src_mesh, dst_loops[i].v = loops[i]; dst_loops[i].e = loop_edges[i]; } - for (const int i : IndexRange(mesh_out->totvert)) { - copy_v3_v3(dst_verts[i].co, vertex_positions[i]); - } dst_edges.copy_from(new_edges); return mesh_out; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index cd191fa8498..0dfebb1362c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -525,7 +525,6 @@ static void duplicate_faces(GeometrySet &geometry_set, geometry_set.keep_only_during_modify({GEO_COMPONENT_TYPE_MESH}); const Mesh &mesh = *geometry_set.get_mesh_for_read(); - const Span verts = mesh.verts(); const Span edges = mesh.edges(); const Span polys = mesh.polys(); const Span loops = mesh.loops(); @@ -550,12 +549,11 @@ static void duplicate_faces(GeometrySet &geometry_set, offsets[selection.size()] = total_polys; Mesh *new_mesh = BKE_mesh_new_nomain(total_loops, total_loops, 0, total_loops, total_polys); - MutableSpan new_verts = new_mesh->verts_for_write(); MutableSpan new_edges = new_mesh->edges_for_write(); MutableSpan new_polys = new_mesh->polys_for_write(); MutableSpan new_loops = new_mesh->loops_for_write(); - Array vert_mapping(new_verts.size()); + Array vert_mapping(new_mesh->totvert); Array edge_mapping(new_edges.size()); Array loop_mapping(new_loops.size()); @@ -571,7 +569,6 @@ static void duplicate_faces(GeometrySet &geometry_set, for (const int i_loops : IndexRange(source.totloop)) { const MLoop ¤t_loop = loops[source.loopstart + i_loops]; loop_mapping[loop_index] = source.loopstart + i_loops; - new_verts[loop_index] = verts[current_loop.v]; vert_mapping[loop_index] = current_loop.v; new_edges[loop_index] = edges[current_loop.e]; edge_mapping[loop_index] = current_loop.e; @@ -905,10 +902,9 @@ static void duplicate_points_mesh(GeometrySet &geometry_set, const AnonymousAttributePropagationInfo &propagation_info) { const Mesh &mesh = *geometry_set.get_mesh_for_read(); - const Span src_verts = mesh.verts(); bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_POINT}; - FieldEvaluator evaluator{field_context, src_verts.size()}; + FieldEvaluator evaluator{field_context, mesh.totvert}; evaluator.add(count_field); evaluator.set_selection(selection_field); evaluator.evaluate(); @@ -918,9 +914,6 @@ static void duplicate_points_mesh(GeometrySet &geometry_set, Array offsets = accumulate_counts_to_offsets(selection, counts); Mesh *new_mesh = BKE_mesh_new_nomain(offsets.last(), 0, 0, 0, 0); - MutableSpan dst_verts = new_mesh->verts_for_write(); - - threaded_slice_fill(offsets.as_span(), selection, src_verts, dst_verts); copy_attributes_without_id(geometry_set, GEO_COMPONENT_TYPE_MESH, diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index db410cd1d4b..1362e6e051c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -221,7 +221,7 @@ static void extrude_mesh_vertices(Mesh &mesh, const IndexRange new_vert_range{orig_vert_size, selection.size()}; const IndexRange new_edge_range{orig_edge_size, selection.size()}; - MutableSpan new_verts = mesh.verts_for_write().slice(new_vert_range); + MutableSpan new_positions = mesh.vert_positions_for_write().slice(new_vert_range); MutableSpan new_edges = mesh.edges_for_write().slice(new_edge_range); for (const int i_selection : selection.index_range()) { @@ -265,8 +265,7 @@ static void extrude_mesh_vertices(Mesh &mesh, devirtualize_varray(offsets, [&](const auto offsets) { threading::parallel_for(selection.index_range(), 1024, [&](const IndexRange range) { for (const int i : range) { - const float3 offset = offsets[selection[i]]; - add_v3_v3(new_verts[i].co, offset); + new_positions[i] += offsets[selection[i]]; } }); }); @@ -593,19 +592,19 @@ static void extrude_mesh_edges(Mesh &mesh, return true; }); - MutableSpan new_verts = mesh.verts_for_write().slice(new_vert_range); + MutableSpan new_positions = mesh.vert_positions_for_write().slice(new_vert_range); if (edge_offsets.is_single()) { const float3 offset = edge_offsets.get_internal_single(); - threading::parallel_for(new_verts.index_range(), 1024, [&](const IndexRange range) { + threading::parallel_for(new_positions.index_range(), 1024, [&](const IndexRange range) { for (const int i : range) { - add_v3_v3(new_verts[i].co, offset); + new_positions[i] += offset; } }); } else { - threading::parallel_for(new_verts.index_range(), 1024, [&](const IndexRange range) { + threading::parallel_for(new_positions.index_range(), 1024, [&](const IndexRange range) { for (const int i : range) { - add_v3_v3(new_verts[i].co, vert_offsets[new_vert_indices[i]]); + new_positions[i] += vert_offsets[new_vert_indices[i]]; } }); } @@ -978,15 +977,19 @@ static void extrude_mesh_face_regions(Mesh &mesh, /* Translate vertices based on the offset. If the vertex is used by a selected edge, it will * have been duplicated and only the new vertex should use the offset. Otherwise the vertex might * still need an offset, but it was reused on the inside of a region of extruded faces. */ - MutableSpan verts = mesh.verts_for_write(); + MutableSpan positions = mesh.vert_positions_for_write(); if (poly_offsets.is_single()) { const float3 offset = poly_offsets.get_internal_single(); threading::parallel_for( IndexRange(all_selected_verts.size()), 1024, [&](const IndexRange range) { for (const int i_orig : all_selected_verts.as_span().slice(range)) { const int i_new = new_vert_indices.index_of_try(i_orig); - MVert &vert = verts[(i_new == -1) ? i_orig : new_vert_range[i_new]]; - add_v3_v3(vert.co, offset); + if (i_new == -1) { + positions[i_orig] += offset; + } + else { + positions[new_vert_range[i_new]] += offset; + } } }); } @@ -996,8 +999,12 @@ static void extrude_mesh_face_regions(Mesh &mesh, for (const int i_orig : all_selected_verts.as_span().slice(range)) { const int i_new = new_vert_indices.index_of_try(i_orig); const float3 offset = vert_offsets[i_orig]; - MVert &vert = verts[(i_new == -1) ? i_orig : new_vert_range[i_new]]; - add_v3_v3(vert.co, offset); + if (i_new == -1) { + positions[i_orig] += offset; + } + else { + positions[new_vert_range[i_new]] += offset; + } } }); } @@ -1094,7 +1101,7 @@ static void extrude_individual_mesh_faces(Mesh &mesh, side_poly_range.size(), side_loop_range.size()); - MutableSpan new_verts = mesh.verts_for_write().slice(new_vert_range); + MutableSpan new_positions = mesh.vert_positions_for_write().slice(new_vert_range); MutableSpan edges = mesh.edges_for_write(); MutableSpan connect_edges = edges.slice(connect_edge_range); MutableSpan duplicate_edges = edges.slice(duplicate_edge_range); @@ -1269,8 +1276,8 @@ static void extrude_individual_mesh_faces(Mesh &mesh, threading::parallel_for(poly_selection.index_range(), 1024, [&](const IndexRange range) { for (const int i_selection : range) { const IndexRange extrude_range = selected_corner_range(index_offsets, i_selection); - for (MVert &vert : new_verts.slice(extrude_range)) { - add_v3_v3(vert.co, poly_offset[poly_selection[i_selection]]); + for (float3 &position : new_positions.slice(extrude_range)) { + position += poly_offset[poly_selection[i_selection]]; } } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc index 29730ab8dc4..8c426d7a55d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_angle.cc @@ -64,20 +64,27 @@ class AngleFieldInput final : public bke::MeshFieldInput { const eAttrDomain domain, const IndexMask /*mask*/) const final { - const Span verts = mesh.verts(); + const Span positions = mesh.vert_positions(); const Span polys = mesh.polys(); const Span loops = mesh.loops(); Array edge_map = create_edge_map(polys, loops, mesh.totedge); - auto angle_fn = [edge_map = std::move(edge_map), verts, polys, loops](const int i) -> float { + auto angle_fn = + [edge_map = std::move(edge_map), positions, polys, loops](const int i) -> float { if (edge_map[i].face_count != 2) { return 0.0f; } const MPoly &mpoly_1 = polys[edge_map[i].face_index_1]; const MPoly &mpoly_2 = polys[edge_map[i].face_index_2]; float3 normal_1, normal_2; - BKE_mesh_calc_poly_normal(&mpoly_1, &loops[mpoly_1.loopstart], verts.data(), normal_1); - BKE_mesh_calc_poly_normal(&mpoly_2, &loops[mpoly_2.loopstart], verts.data(), normal_2); + BKE_mesh_calc_poly_normal(&mpoly_1, + &loops[mpoly_1.loopstart], + reinterpret_cast(positions.data()), + normal_1); + BKE_mesh_calc_poly_normal(&mpoly_2, + &loops[mpoly_2.loopstart], + reinterpret_cast(positions.data()), + normal_2); return angle_normalized_v3v3(normal_1, normal_2); }; @@ -113,14 +120,14 @@ class SignedAngleFieldInput final : public bke::MeshFieldInput { const eAttrDomain domain, const IndexMask /*mask*/) const final { - const Span verts = mesh.verts(); + const Span positions = mesh.vert_positions(); const Span edges = mesh.edges(); const Span polys = mesh.polys(); const Span loops = mesh.loops(); Array edge_map = create_edge_map(polys, loops, mesh.totedge); auto angle_fn = - [edge_map = std::move(edge_map), verts, edges, polys, loops](const int i) -> float { + [edge_map = std::move(edge_map), positions, edges, polys, loops](const int i) -> float { if (edge_map[i].face_count != 2) { return 0.0f; } @@ -129,18 +136,25 @@ class SignedAngleFieldInput final : public bke::MeshFieldInput { /* Find the normals of the 2 polys. */ float3 poly_1_normal, poly_2_normal; - BKE_mesh_calc_poly_normal(&mpoly_1, &loops[mpoly_1.loopstart], verts.data(), poly_1_normal); - BKE_mesh_calc_poly_normal(&mpoly_2, &loops[mpoly_2.loopstart], verts.data(), poly_2_normal); + BKE_mesh_calc_poly_normal(&mpoly_1, + &loops[mpoly_1.loopstart], + reinterpret_cast(positions.data()), + poly_1_normal); + BKE_mesh_calc_poly_normal(&mpoly_2, + &loops[mpoly_2.loopstart], + reinterpret_cast(positions.data()), + poly_2_normal); /* Find the centerpoint of the axis edge */ - const float3 edge_centerpoint = (float3(verts[edges[i].v1].co) + - float3(verts[edges[i].v2].co)) * - 0.5f; + const float3 edge_centerpoint = (positions[edges[i].v1] + positions[edges[i].v2]) * 0.5f; /* Get the centerpoint of poly 2 and subtract the edge centerpoint to get a tangent * normal for poly 2. */ float3 poly_center_2; - BKE_mesh_calc_poly_center(&mpoly_2, &loops[mpoly_2.loopstart], verts.data(), poly_center_2); + BKE_mesh_calc_poly_center(&mpoly_2, + &loops[mpoly_2.loopstart], + reinterpret_cast(positions.data()), + poly_center_2); const float3 poly_2_tangent = math::normalize(poly_center_2 - edge_centerpoint); const float concavity = math::dot(poly_1_normal, poly_2_tangent); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc index 513ddd76055..667beeefd2f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_edge_vertices.cc @@ -83,19 +83,19 @@ static VArray construct_edge_positions_gvarray(const Mesh &mesh, const VertNumber vertex, const eAttrDomain domain) { - const Span verts = mesh.verts(); + const Span positions = mesh.vert_positions(); const Span edges = mesh.edges(); if (vertex == VertNumber::V1) { return mesh.attributes().adapt_domain( - VArray::ForFunc(edges.size(), - [verts, edges](const int i) { return verts[edges[i].v1].co; }), + VArray::ForFunc( + edges.size(), [positions, edges](const int i) { return positions[edges[i].v1]; }), ATTR_DOMAIN_EDGE, domain); } return mesh.attributes().adapt_domain( VArray::ForFunc(edges.size(), - [verts, edges](const int i) { return verts[edges[i].v2].co; }), + [positions, edges](const int i) { return positions[edges[i].v2]; }), ATTR_DOMAIN_EDGE, domain); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc index aec1c27a4fc..d9f5f4b82a3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_area.cc @@ -18,13 +18,14 @@ static void node_declare(NodeDeclarationBuilder &b) static VArray construct_face_area_varray(const Mesh &mesh, const eAttrDomain domain) { - const Span verts = mesh.verts(); + const Span positions = mesh.vert_positions(); const Span polys = mesh.polys(); const Span loops = mesh.loops(); - auto area_fn = [verts, polys, loops](const int i) -> float { + auto area_fn = [positions, polys, loops](const int i) -> float { const MPoly &poly = polys[i]; - return BKE_mesh_calc_poly_area(&poly, &loops[poly.loopstart], verts.data()); + return BKE_mesh_calc_poly_area( + &poly, &loops[poly.loopstart], reinterpret_cast(positions.data())); }; return mesh.attributes().adapt_domain( diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc index 69b84bcaf45..9f1f544d2a9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_mesh_face_is_planar.cc @@ -37,7 +37,7 @@ class PlanarFieldInput final : public bke::MeshFieldInput { const eAttrDomain domain, IndexMask /*mask*/) const final { - const Span verts = mesh.verts(); + const Span positions = mesh.vert_positions(); const Span polys = mesh.polys(); const Span loops = mesh.loops(); const Span poly_normals = mesh.poly_normals(); @@ -48,7 +48,7 @@ class PlanarFieldInput final : public bke::MeshFieldInput { evaluator.evaluate(); const VArray thresholds = evaluator.get_evaluated(0); - auto planar_fn = [verts, polys, loops, thresholds, poly_normals](const int i) -> bool { + auto planar_fn = [positions, polys, loops, thresholds, poly_normals](const int i) -> bool { const MPoly &poly = polys[i]; if (poly.totloop <= 3) { return true; @@ -60,7 +60,7 @@ class PlanarFieldInput final : public bke::MeshFieldInput { float max = -FLT_MAX; for (const int i_loop : poly_loops.index_range()) { - const float3 vert = verts[poly_loops[i_loop].v].co; + const float3 &vert = positions[poly_loops[i_loop].v]; float dot = math::dot(reference_normal, vert); if (dot > max) { max = dot; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc index fca2f0b7313..4b4d7ecb702 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_circle.cc @@ -109,7 +109,7 @@ static Mesh *create_circle_mesh(const float radius, circle_corner_total(fill_type, verts_num), circle_face_total(fill_type, verts_num)); BKE_id_material_eval_ensure_default_slot(&mesh->id); - MutableSpan verts = mesh->verts_for_write(); + MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); @@ -118,10 +118,10 @@ static Mesh *create_circle_mesh(const float radius, const float angle_delta = 2.0f * (M_PI / float(verts_num)); for (const int i : IndexRange(verts_num)) { const float angle = i * angle_delta; - copy_v3_v3(verts[i].co, float3(std::cos(angle) * radius, std::sin(angle) * radius, 0.0f)); + positions[i] = float3(std::cos(angle) * radius, std::sin(angle) * radius, 0.0f); } if (fill_type == GEO_NODE_MESH_CIRCLE_FILL_TRIANGLE_FAN) { - copy_v3_v3(verts.last().co, float3(0)); + positions.last() = float3(0); } /* Create outer edges. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc index 9e92527f393..757fab12e82 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_cone.cc @@ -255,7 +255,7 @@ int ConeConfig::calculate_total_corners() return corner_total; } -static void calculate_cone_verts(const ConeConfig &config, MutableSpan verts) +static void calculate_cone_verts(const ConeConfig &config, MutableSpan positions) { Array circle(config.circle_segments); const float angle_delta = 2.0f * (M_PI / float(config.circle_segments)); @@ -270,7 +270,7 @@ static void calculate_cone_verts(const ConeConfig &config, MutableSpan ve /* Top cone tip or triangle fan center. */ if (config.top_has_center_vert) { - copy_v3_fl3(verts[vert_index++].co, 0.0f, 0.0f, config.height); + positions[vert_index++] = {0.0f, 0.0f, config.height}; } /* Top fill including the outer edge of the fill. */ @@ -281,7 +281,7 @@ static void calculate_cone_verts(const ConeConfig &config, MutableSpan ve for (const int j : IndexRange(config.circle_segments)) { const float x = circle[j].x * top_fill_radius; const float y = circle[j].y * top_fill_radius; - copy_v3_fl3(verts[vert_index++].co, x, y, config.height); + positions[vert_index++] = {x, y, config.height}; } } } @@ -296,7 +296,7 @@ static void calculate_cone_verts(const ConeConfig &config, MutableSpan ve for (const int j : IndexRange(config.circle_segments)) { const float x = circle[j].x * ring_radius; const float y = circle[j].y * ring_radius; - copy_v3_fl3(verts[vert_index++].co, x, y, ring_height); + positions[vert_index++] = {x, y, ring_height}; } } @@ -308,14 +308,14 @@ static void calculate_cone_verts(const ConeConfig &config, MutableSpan ve for (const int j : IndexRange(config.circle_segments)) { const float x = circle[j].x * bottom_fill_radius; const float y = circle[j].y * bottom_fill_radius; - copy_v3_fl3(verts[vert_index++].co, x, y, -config.height); + positions[vert_index++] = {x, y, -config.height}; } } } /* Bottom cone tip or triangle fan center. */ if (config.bottom_has_center_vert) { - copy_v3_fl3(verts[vert_index++].co, 0.0f, 0.0f, -config.height); + positions[vert_index++] = {0.0f, 0.0f, -config.height}; } } @@ -660,7 +660,7 @@ static Mesh *create_vertex_mesh() { /* Returns a mesh with a single vertex at the origin. */ Mesh *mesh = BKE_mesh_new_nomain(1, 0, 0, 0, 0); - copy_v3_fl3(mesh->verts_for_write().first().co, 0.0f, 0.0f, 0.0f); + mesh->vert_positions_for_write().first() = float3(0); return mesh; } @@ -692,12 +692,12 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top, config.tot_verts, config.tot_edges, 0, config.tot_corners, config.tot_faces); BKE_id_material_eval_ensure_default_slot(&mesh->id); - MutableSpan verts = mesh->verts_for_write(); + MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); - calculate_cone_verts(config, verts); + calculate_cone_verts(config, positions); calculate_cone_edges(config, edges); calculate_cone_faces(config, loops, polys); if (attribute_outputs.uv_map_id) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc index b05a6d8019e..4e6cc590a7b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_grid.cc @@ -16,7 +16,7 @@ namespace blender::nodes { static void calculate_uvs(Mesh *mesh, - Span verts, + Span positions, Span loops, const float size_x, const float size_y, @@ -31,7 +31,7 @@ static void calculate_uvs(Mesh *mesh, const float dy = (size_y == 0.0f) ? 0.0f : 1.0f / size_y; threading::parallel_for(loops.index_range(), 1024, [&](IndexRange range) { for (const int i : range) { - const float3 &co = verts[loops[i].v].co; + const float3 &co = positions[loops[i].v]; uv_attribute.span[i].x = (co.x + size_x * 0.5f) * dx; uv_attribute.span[i].y = (co.y + size_y * 0.5f) * dy; } @@ -54,7 +54,7 @@ Mesh *create_grid_mesh(const int verts_x, 0, edges_x * edges_y * 4, edges_x * edges_y); - MutableSpan verts = mesh->verts_for_write(); + MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); @@ -70,9 +70,9 @@ Mesh *create_grid_mesh(const int verts_x, threading::parallel_for(IndexRange(verts_y), 512, [&](IndexRange y_range) { for (const int y : y_range) { const int vert_index = y_offset + y; - verts[vert_index].co[0] = (x - x_shift) * dx; - verts[vert_index].co[1] = (y - y_shift) * dy; - verts[vert_index].co[2] = 0.0f; + positions[vert_index].x = (x - x_shift) * dx; + positions[vert_index].y = (y - y_shift) * dy; + positions[vert_index].z = 0.0f; } }); } @@ -145,7 +145,7 @@ Mesh *create_grid_mesh(const int verts_x, }); if (uv_map_id && mesh->totpoly != 0) { - calculate_uvs(mesh, verts, loops, size_x, size_y, uv_map_id); + calculate_uvs(mesh, positions, loops, size_x, size_y, uv_map_id); } mesh->loose_edges_tag_none(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc index 0de0bb80826..f7774485671 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc @@ -179,15 +179,15 @@ Mesh *create_line_mesh(const float3 start, const float3 delta, const int count) Mesh *mesh = BKE_mesh_new_nomain(count, count - 1, 0, 0, 0); BKE_id_material_eval_ensure_default_slot(&mesh->id); - MutableSpan verts = mesh->verts_for_write(); + MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan edges = mesh->edges_for_write(); threading::parallel_invoke( 1024 < count, [&]() { - threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { + threading::parallel_for(positions.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { - copy_v3_v3(verts[i].co, start + delta * i); + positions[i] = start + delta * i; } }); }, diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc index ff40a970785..a93fccb3f37 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc @@ -64,7 +64,7 @@ static int sphere_face_total(const int segments, const int rings) * Also calculate vertex normals here, since the calculation is trivial, and it allows avoiding the * calculation later, if it's necessary. The vertex normals are just the normalized positions. */ -BLI_NOINLINE static void calculate_sphere_vertex_data(MutableSpan verts, +BLI_NOINLINE static void calculate_sphere_vertex_data(MutableSpan positions, MutableSpan vert_normals, const float radius, const int segments, @@ -84,7 +84,7 @@ BLI_NOINLINE static void calculate_sphere_vertex_data(MutableSpan verts, segment_sines[segment] = std::sin(phi); } - copy_v3_v3(verts[0].co, float3(0.0f, 0.0f, radius)); + positions[0] = float3(0.0f, 0.0f, radius); vert_normals.first() = float3(0.0f, 0.0f, 1.0f); int vert_index = 1; @@ -95,13 +95,13 @@ BLI_NOINLINE static void calculate_sphere_vertex_data(MutableSpan verts, for (const int segment : IndexRange(1, segments)) { const float x = sin_theta * segment_cosines[segment]; const float y = sin_theta * segment_sines[segment]; - copy_v3_v3(verts[vert_index].co, float3(x, y, z) * radius); + positions[vert_index] = float3(x, y, z) * radius; vert_normals[vert_index] = float3(x, y, z); vert_index++; } } - copy_v3_v3(verts.last().co, float3(0.0f, 0.0f, -radius)); + positions.last() = float3(0.0f, 0.0f, -radius); vert_normals.last() = float3(0.0f, 0.0f, -1.0f); } @@ -316,7 +316,7 @@ static Mesh *create_uv_sphere_mesh(const float radius, sphere_corner_total(segments, rings), sphere_face_total(segments, rings)); BKE_id_material_eval_ensure_default_slot(&mesh->id); - MutableSpan verts = mesh->verts_for_write(); + MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan edges = mesh->edges_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); @@ -326,7 +326,7 @@ static Mesh *create_uv_sphere_mesh(const float radius, [&]() { MutableSpan vert_normals{ reinterpret_cast(BKE_mesh_vertex_normals_for_write(mesh)), mesh->totvert}; - calculate_sphere_vertex_data(verts, vert_normals, radius, segments, rings); + calculate_sphere_vertex_data(positions, vert_normals, radius, segments, rings); BKE_mesh_vertex_normals_clear_dirty(mesh); }, [&]() { calculate_sphere_edge_indices(edges, segments, rings); }, diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc index 1d649545b2c..06babe28493 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc @@ -163,7 +163,7 @@ static void get_closest_mesh_corners(const Mesh &mesh, const MutableSpan r_distances_sq, const MutableSpan r_positions) { - const Span verts = mesh.verts(); + const Span vert_positions = mesh.vert_positions(); const Span polys = mesh.polys(); const Span loops = mesh.loops(); @@ -178,24 +178,23 @@ static void get_closest_mesh_corners(const Mesh &mesh, /* Find the closest vertex in the polygon. */ float min_distance_sq = FLT_MAX; - const MVert *closest_mvert; + int closest_vert_index = 0; int closest_loop_index = 0; for (const int loop_index : IndexRange(poly.loopstart, poly.totloop)) { const MLoop &loop = loops[loop_index]; const int vertex_index = loop.v; - const MVert &mvert = verts[vertex_index]; - const float distance_sq = math::distance_squared(position, float3(mvert.co)); + const float distance_sq = math::distance_squared(position, vert_positions[vertex_index]); if (distance_sq < min_distance_sq) { min_distance_sq = distance_sq; closest_loop_index = loop_index; - closest_mvert = &mvert; + closest_vert_index = vertex_index; } } if (!r_corner_indices.is_empty()) { r_corner_indices[i] = closest_loop_index; } if (!r_positions.is_empty()) { - r_positions[i] = closest_mvert->co; + r_positions[i] = vert_positions[closest_vert_index]; } if (!r_distances_sq.is_empty()) { r_distances_sq[i] = min_distance_sq; diff --git a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc index da9b04c06c0..d2e77e92f85 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_scale_elements.cc @@ -157,7 +157,7 @@ static void scale_vertex_islands_uniformly(Mesh &mesh, const UniformScaleParams ¶ms, const GetVertexIndicesFn get_vertex_indices) { - MutableSpan verts = mesh.verts_for_write(); + MutableSpan positions = mesh.vert_positions_for_write(); const Span edges = mesh.edges(); const Span polys = mesh.polys(); const Span loops = mesh.loops(); @@ -182,10 +182,7 @@ static void scale_vertex_islands_uniformly(Mesh &mesh, center *= f; for (const int vert_index : vertex_indices) { - MVert &vert = verts[vert_index]; - const float3 old_position = vert.co; - const float3 new_position = transform_with_uniform_scale(old_position, center, scale); - copy_v3_v3(vert.co, new_position); + positions[vert_index] = transform_with_uniform_scale(positions[vert_index], center, scale); } } }); @@ -198,7 +195,7 @@ static void scale_vertex_islands_on_axis(Mesh &mesh, const AxisScaleParams ¶ms, const GetVertexIndicesFn get_vertex_indices) { - MutableSpan verts = mesh.verts_for_write(); + MutableSpan positions = mesh.vert_positions_for_write(); const Span edges = mesh.edges(); const Span polys = mesh.polys(); const Span loops = mesh.loops(); @@ -231,10 +228,7 @@ static void scale_vertex_islands_on_axis(Mesh &mesh, const float4x4 transform = create_single_axis_transform(center, axis, scale); for (const int vert_index : vertex_indices) { - MVert &vert = verts[vert_index]; - const float3 old_position = vert.co; - const float3 new_position = transform * old_position; - copy_v3_v3(vert.co, new_position); + positions[vert_index] = transform * positions[vert_index]; } } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index 4a76e230af7..caa911a5f45 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -41,41 +41,6 @@ static void set_computed_position_and_offset(GeometryComponent &component, const int grain_size = 10000; switch (component.type()) { - case GEO_COMPONENT_TYPE_MESH: { - Mesh *mesh = static_cast(component).get_for_write(); - MutableSpan verts = mesh->verts_for_write(); - if (in_positions.is_same(positions_read_only)) { - devirtualize_varray(in_offsets, [&](const auto in_offsets) { - threading::parallel_for( - selection.index_range(), grain_size, [&](const IndexRange range) { - for (const int i : selection.slice(range)) { - const float3 offset = in_offsets[i]; - add_v3_v3(verts[i].co, offset); - } - }); - }); - if (in_offsets.is_single() && selection.size() == verts.size()) { - BKE_mesh_tag_coords_changed_uniformly(mesh); - } - else { - BKE_mesh_tag_coords_changed(mesh); - } - } - else { - devirtualize_varray2( - in_positions, in_offsets, [&](const auto in_positions, const auto in_offsets) { - threading::parallel_for( - selection.index_range(), grain_size, [&](const IndexRange range) { - for (const int i : selection.slice(range)) { - const float3 new_position = in_positions[i] + in_offsets[i]; - copy_v3_v3(verts[i].co, new_position); - } - }); - }); - BKE_mesh_tag_coords_changed(mesh); - } - break; - } case GEO_COMPONENT_TYPE_CURVE: { if (attributes.contains("handle_right") && attributes.contains("handle_left")) { CurveComponent &curve_component = static_cast(component); diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc index 04ba2282439..2224abd0a65 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_pack_islands.cc @@ -37,7 +37,7 @@ static VArray construct_uv_gvarray(const Mesh &mesh, const float margin, const eAttrDomain domain) { - const Span verts = mesh.verts(); + const Span positions = mesh.vert_positions(); const Span polys = mesh.polys(); const Span loops = mesh.loops(); @@ -67,7 +67,7 @@ static VArray construct_uv_gvarray(const Mesh &mesh, for (const int i : IndexRange(mp.totloop)) { const MLoop &ml = loops[mp.loopstart + i]; mp_vkeys[i] = ml.v; - mp_co[i] = verts[ml.v].co; + mp_co[i] = positions[ml.v]; mp_uv[i] = uv[mp.loopstart + i]; mp_pin[i] = false; mp_select[i] = false; diff --git a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc index 8286e04172f..6c05234f1e8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_uv_unwrap.cc @@ -62,7 +62,7 @@ static VArray construct_uv_gvarray(const Mesh &mesh, const GeometryNodeUVUnwrapMethod method, const eAttrDomain domain) { - const Span verts = mesh.verts(); + const Span positions = mesh.vert_positions(); const Span edges = mesh.edges(); const Span polys = mesh.polys(); const Span loops = mesh.loops(); @@ -95,7 +95,7 @@ static VArray construct_uv_gvarray(const Mesh &mesh, for (const int i : IndexRange(mp.totloop)) { const MLoop &ml = loops[mp.loopstart + i]; mp_vkeys[i] = ml.v; - mp_co[i] = verts[ml.v].co; + mp_co[i] = positions[ml.v]; mp_uv[i] = uv[mp.loopstart + i]; mp_pin[i] = false; mp_select[i] = false; diff --git a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc index c076a6c08f3..5703cce98c3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_volume_to_mesh.cc @@ -123,7 +123,7 @@ static Mesh *create_mesh_from_volume_grids(Span gri Mesh *mesh = BKE_mesh_new_nomain(vert_offset, 0, 0, loop_offset, poly_offset); BKE_id_material_eval_ensure_default_slot(&mesh->id); - MutableSpan verts = mesh->verts_for_write(); + MutableSpan positions = mesh->vert_positions_for_write(); MutableSpan polys = mesh->polys_for_write(); MutableSpan loops = mesh->loops_for_write(); @@ -135,7 +135,7 @@ static Mesh *create_mesh_from_volume_grids(Span gri vert_offsets[i], poly_offsets[i], loop_offsets[i], - verts, + positions, polys, loops); } diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c index 7b6c444515b..b2738a5cb8f 100644 --- a/source/blender/python/mathutils/mathutils_bvhtree.c +++ b/source/blender/python/mathutils/mathutils_bvhtree.c @@ -1147,11 +1147,7 @@ static PyObject *C_BVHTree_FromObject(PyObject *UNUSED(cls), PyObject *args, PyO coords = MEM_mallocN(sizeof(*coords) * (size_t)coords_len, __func__); tris = MEM_mallocN(sizeof(*tris) * (size_t)tris_len, __func__); - - const MVert *verts = BKE_mesh_verts(mesh); - for (int i = 0; i < mesh->totvert; i++) { - copy_v3_v3(coords[i], verts[i].co); - } + memcpy(coords, BKE_mesh_vert_positions(mesh), sizeof(float[3]) * (size_t)mesh->totvert); mloop = BKE_mesh_loops(mesh); } diff --git a/source/blender/render/intern/bake.cc b/source/blender/render/intern/bake.cc index e88dbcc3778..8b598ceb6a0 100644 --- a/source/blender/render/intern/bake.cc +++ b/source/blender/render/intern/bake.cc @@ -92,7 +92,7 @@ struct TSpace { }; struct TriTessFace { - const MVert *mverts[3]; + const float *positions[3]; const float *vert_normals[3]; const TSpace *tspace[3]; const float *loop_normal[3]; @@ -194,9 +194,9 @@ static void calc_point_from_barycentric_cage(TriTessFace *triangles_low, triangle[1] = &triangles_cage[primitive_id]; for (i = 0; i < 2; i++) { - copy_v3_v3(data[i][0], triangle[i]->mverts[0]->co); - copy_v3_v3(data[i][1], triangle[i]->mverts[1]->co); - copy_v3_v3(data[i][2], triangle[i]->mverts[2]->co); + copy_v3_v3(data[i][0], triangle[i]->positions[0]); + copy_v3_v3(data[i][1], triangle[i]->positions[1]); + copy_v3_v3(data[i][2], triangle[i]->positions[2]); interp_barycentric_tri_v3(data[i], u, v, coord[i]); } @@ -236,9 +236,9 @@ static void calc_point_from_barycentric_extrusion(TriTessFace *triangles, TriTessFace *triangle = &triangles[primitive_id]; is_smooth = triangle->is_smooth || is_cage; - copy_v3_v3(data[0], triangle->mverts[0]->co); - copy_v3_v3(data[1], triangle->mverts[1]->co); - copy_v3_v3(data[2], triangle->mverts[2]->co); + copy_v3_v3(data[0], triangle->positions[0]); + copy_v3_v3(data[1], triangle->positions[1]); + copy_v3_v3(data[2], triangle->positions[2]); interp_barycentric_tri_v3(data, u, v, coord); @@ -394,8 +394,8 @@ static bool cast_ray_highpoly(BVHTreeFromMesh *treeData, /* compute position differentials on low poly object */ float duco_low[3], dvco_low[3], dxco[3], dyco[3]; - sub_v3_v3v3(duco_low, triangle_low->mverts[0]->co, triangle_low->mverts[2]->co); - sub_v3_v3v3(dvco_low, triangle_low->mverts[1]->co, triangle_low->mverts[2]->co); + sub_v3_v3v3(duco_low, triangle_low->positions[0], triangle_low->positions[2]); + sub_v3_v3v3(dvco_low, triangle_low->positions[1], triangle_low->positions[2]); mul_v3_v3fl(dxco, duco_low, pixel_low->du_dx); madd_v3_v3fl(dxco, dvco_low, pixel_low->dv_dx); @@ -416,9 +416,9 @@ static bool cast_ray_highpoly(BVHTreeFromMesh *treeData, /* compute barycentric differentials from position differentials */ barycentric_differentials_from_position(hits[hit_mesh].co, - triangle_high->mverts[0]->co, - triangle_high->mverts[1]->co, - triangle_high->mverts[2]->co, + triangle_high->positions[0], + triangle_high->positions[1], + triangle_high->positions[2], dxco, dyco, triangle_high->normal, @@ -460,7 +460,7 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval uint mpoly_prev = UINT_MAX; float no[3]; - const MVert *verts = BKE_mesh_verts(me); + const float(*positions)[3] = BKE_mesh_vert_positions(me); const MPoly *polys = BKE_mesh_polys(me); const MLoop *loops = BKE_mesh_loops(me); @@ -474,10 +474,10 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval if (precomputed_normals != nullptr) { BKE_mesh_recalc_looptri_with_normals( - loops, polys, verts, me->totloop, me->totpoly, looptri, precomputed_normals); + loops, polys, positions, me->totloop, me->totpoly, looptri, precomputed_normals); } else { - BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri); + BKE_mesh_recalc_looptri(loops, polys, positions, me->totloop, me->totpoly, looptri); } const TSpace *tspace = nullptr; @@ -499,9 +499,9 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval const MLoopTri *lt = &looptri[i]; const MPoly *mp = &polys[lt->poly]; - triangles[i].mverts[0] = &verts[loops[lt->tri[0]].v]; - triangles[i].mverts[1] = &verts[loops[lt->tri[1]].v]; - triangles[i].mverts[2] = &verts[loops[lt->tri[2]].v]; + triangles[i].positions[0] = positions[loops[lt->tri[0]].v]; + triangles[i].positions[1] = positions[loops[lt->tri[1]].v]; + triangles[i].positions[2] = positions[loops[lt->tri[2]].v]; triangles[i].vert_normals[0] = vert_normals[loops[lt->tri[0]].v]; triangles[i].vert_normals[1] = vert_normals[loops[lt->tri[1]].v]; triangles[i].vert_normals[2] = vert_normals[loops[lt->tri[2]].v]; @@ -521,7 +521,7 @@ static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval if (calculate_normal) { if (lt->poly != mpoly_prev) { - BKE_mesh_calc_poly_normal(mp, &loops[mp->loopstart], verts, no); + BKE_mesh_calc_poly_normal(mp, &loops[mp->loopstart], positions, no); mpoly_prev = lt->poly; } copy_v3_v3(triangles[i].normal, no); @@ -744,10 +744,10 @@ void RE_bake_pixels_populate(Mesh *me, const int tottri = poly_to_tri_count(me->totpoly, me->totloop); MLoopTri *looptri = static_cast(MEM_mallocN(sizeof(*looptri) * tottri, __func__)); - const MVert *verts = BKE_mesh_verts(me); + const float(*positions)[3] = BKE_mesh_vert_positions(me); const MPoly *polys = BKE_mesh_polys(me); const MLoop *loops = BKE_mesh_loops(me); - BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri); + BKE_mesh_recalc_looptri(loops, polys, positions, me->totloop, me->totpoly, looptri); const int *material_indices = BKE_mesh_material_indices(me); const int materials_num = targets->materials_num; diff --git a/source/blender/render/intern/multires_bake.cc b/source/blender/render/intern/multires_bake.cc index 34d6a5312f7..c5154e8017a 100644 --- a/source/blender/render/intern/multires_bake.cc +++ b/source/blender/render/intern/multires_bake.cc @@ -60,7 +60,7 @@ struct MultiresBakeResult { }; struct MResolvePixelData { - MVert *mvert; + const float (*vert_positions)[3]; const float (*vert_normals)[3]; MPoly *mpoly; const int *material_indices; @@ -125,7 +125,7 @@ static void multiresbake_get_normal(const MResolvePixelData *data, copy_v3_v3(r_normal, data->precomputed_normals[poly_index]); } else { - BKE_mesh_calc_poly_normal(mp, &data->mloop[mp->loopstart], data->mvert, r_normal); + BKE_mesh_calc_poly_normal(mp, &data->mloop[mp->loopstart], data->vert_positions, r_normal); } } } @@ -472,7 +472,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, MultiresBakeThread *handles; MultiresBakeQueue queue; - MVert *mvert = dm->getVertArray(dm); + const float(*positions)[3] = (float(*)[3])dm->getVertArray(dm); MPoly *mpoly = dm->getPolyArray(dm); MLoop *mloop = dm->getLoopArray(dm); MLoopUV *mloopuv = static_cast(dm->getLoopDataArray(dm, CD_MLOOPUV)); @@ -485,9 +485,9 @@ static void do_multires_bake(MultiresBakeRender *bkr, Mesh *temp_mesh = BKE_mesh_new_nomain( dm->getNumVerts(dm), dm->getNumEdges(dm), 0, dm->getNumLoops(dm), dm->getNumPolys(dm)); - memcpy(BKE_mesh_verts_for_write(temp_mesh), - dm->getVertArray(dm), - temp_mesh->totvert * sizeof(MVert)); + memcpy(temp_mesh->vert_positions_for_write().data(), + positions, + temp_mesh->totvert * sizeof(float[3])); memcpy(BKE_mesh_edges_for_write(temp_mesh), dm->getEdgeArray(dm), temp_mesh->totedge * sizeof(MEdge)); @@ -503,7 +503,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, if (require_tangent) { if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) == -1) { BKE_mesh_calc_loop_tangent_ex( - dm->getVertArray(dm), + positions, dm->getPolyArray(dm), dm->getNumPolys(dm), dm->getLoopArray(dm), @@ -555,7 +555,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, handle->data.mpoly = mpoly; handle->data.material_indices = static_cast( CustomData_get_layer_named(&dm->polyData, CD_PROP_INT32, "material_index")); - handle->data.mvert = mvert; + handle->data.vert_positions = positions; handle->data.vert_normals = vert_normals; handle->data.mloopuv = mloopuv; BKE_image_get_tile_uv(ima, tile->tile_number, handle->data.uv_offset); diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc index 2da230c8813..472a75bae66 100644 --- a/source/blender/render/intern/texture_margin.cc +++ b/source/blender/render/intern/texture_margin.cc @@ -515,8 +515,12 @@ static void generate_margin(ImBuf *ibuf, tottri = poly_to_tri_count(me->totpoly, me->totloop); looptri_mem = static_cast(MEM_mallocN(sizeof(*looptri) * tottri, __func__)); - BKE_mesh_recalc_looptri( - mloop, mpoly, me->verts().data(), me->totloop, me->totpoly, looptri_mem); + BKE_mesh_recalc_looptri(mloop, + mpoly, + reinterpret_cast(me->vert_positions().data()), + me->totloop, + me->totpoly, + looptri_mem); looptri = looptri_mem; } else { diff --git a/source/blender/render/intern/texture_pointdensity.c b/source/blender/render/intern/texture_pointdensity.c index 09173aaa0e3..c99482a56a6 100644 --- a/source/blender/render/intern/texture_pointdensity.c +++ b/source/blender/render/intern/texture_pointdensity.c @@ -361,7 +361,6 @@ static void pointdensity_cache_object(PointDensity *pd, Object *ob) { float *data_color; int i; - const MVert *mvert = NULL, *mv; Mesh *mesh = ob->data; #if 0 /* UNUSED */ @@ -377,7 +376,7 @@ static void pointdensity_cache_object(PointDensity *pd, Object *ob) } #endif - mvert = BKE_mesh_verts(mesh); /* local object space */ + const float(*positions)[3] = BKE_mesh_vert_positions(mesh); /* local object space */ pd->totpoints = mesh->totvert; if (pd->totpoints == 0) { return; @@ -387,10 +386,10 @@ static void pointdensity_cache_object(PointDensity *pd, Object *ob) alloc_point_data(pd); point_data_pointers(pd, NULL, NULL, &data_color); - for (i = 0, mv = mvert; i < pd->totpoints; i++, mv++) { + for (i = 0; i < pd->totpoints; i++) { float co[3]; - copy_v3_v3(co, mv->co); + copy_v3_v3(co, positions[i]); switch (pd->ob_cache_space) { case TEX_PD_OBJECTSPACE: diff --git a/source/blender/simulation/intern/hair_volume.cpp b/source/blender/simulation/intern/hair_volume.cpp index 97042f433c2..3e221aa8588 100644 --- a/source/blender/simulation/intern/hair_volume.cpp +++ b/source/blender/simulation/intern/hair_volume.cpp @@ -1215,8 +1215,8 @@ static HairGridVert *hair_volume_create_collision_grid(ClothModifierData *clmd, colliders = BKE_collider_cache_create(depsgraph, NULL, NULL); if (colliders && collfac > 0.0f) { for (col = colliders->first; col; col = col->next) { - MVert *loc0 = col->collmd->x; - MVert *loc1 = col->collmd->xnew; + float3 *loc0 = col->collmd->x; + float3 *loc1 = col->collmd->xnew; float vel[3]; float weights[8]; int di, dj, dk; diff --git a/source/tools b/source/tools index e1744b9bd82..f542f4d21a0 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit e1744b9bd82527cf7e8af63362b61bd309b5711b +Subproject commit f542f4d21a077d85ffb3e43aa7f170976dee20b6 From fdcbad37be96572ff138591444e6bba2f2aae921 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 10 Jan 2023 16:27:11 +1100 Subject: [PATCH 0550/1522] Fix window creation with Hi-DPI exiting under Wayland Wayland requires the windows surface size is divisible by the surface scale. This wasn't guaranteed when creating new temporary windows. This meant opening the preferences could exit Blender with an error with Hi-DPI configurations. --- intern/ghost/intern/GHOST_WindowWayland.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index 5957e992436..9c179a6394f 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -797,11 +797,6 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, window_->ghost_window = this; window_->ghost_system = system; - window_->frame.size[0] = int32_t(width); - window_->frame.size[1] = int32_t(height); - - window_->is_dialog = is_dialog; - /* NOTE(@campbellbarton): The scale set here to avoid flickering on startup. * When all monitors use the same scale (which is quite common) there aren't any problems. * @@ -813,6 +808,16 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system, * avoiding a large window flashing before it's made smaller. */ window_->scale = outputs_max_scale_or_default(system_->outputs(), 1, &window_->scale_fractional); + window_->frame.size[0] = int32_t(width); + window_->frame.size[1] = int32_t(height); + + /* The window surface must be rounded to the scale, + * failing to do so causes the WAYLAND-server to close the window immediately. */ + window_->frame.size[0] = (window_->frame.size[0] / window_->scale) * window_->scale; + window_->frame.size[1] = (window_->frame.size[1] / window_->scale) * window_->scale; + + window_->is_dialog = is_dialog; + /* Window surfaces. */ window_->wl_surface = wl_compositor_create_surface(system_->wl_compositor()); ghost_wl_surface_tag(window_->wl_surface); From d48f95d31c939e0c3f2c186c3f2ce092b76f3ec9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 10 Jan 2023 16:34:39 +1100 Subject: [PATCH 0551/1522] Cleanup: use vert_ prefix for positions of FaceDupliData_Mesh Match VertexDupliData_Mesh. --- source/blender/blenkernel/intern/object_dupli.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index 2db9c2c31c1..a9f2406ccfd 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -1060,7 +1060,7 @@ struct FaceDupliData_Mesh { int totface; const MPoly *mpoly; const MLoop *mloop; - Span positions; + Span vert_positions; const float (*orco)[3]; const MLoopUV *mloopuv; }; @@ -1159,14 +1159,14 @@ static DupliObject *face_dupli_from_mesh(const DupliContext *ctx, /* Mesh variables. */ const MPoly *mpoly, const MLoop *mloopstart, - const Span positions) + const Span vert_positions) { const int coords_len = mpoly->totloop; Array coords(coords_len); const MLoop *ml = mloopstart; for (int i = 0; i < coords_len; i++, ml++) { - coords[i] = positions[ml->v]; + coords[i] = vert_positions[ml->v]; } return face_dupli(ctx, inst_ob, child_imat, index, use_scale, scale_fac, coords); @@ -1233,7 +1233,7 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx, scale_fac, mp, loopstart, - fdd->positions); + fdd->vert_positions); const float w = 1.0f / float(mp->totloop); if (orco) { @@ -1322,7 +1322,7 @@ static void make_duplis_faces(const DupliContext *ctx) fdd.totface = me_eval->totpoly; fdd.mpoly = me_eval->polys().data(); fdd.mloop = me_eval->loops().data(); - fdd.positions = me_eval->vert_positions(); + fdd.vert_positions = me_eval->vert_positions(); fdd.mloopuv = (uv_idx != -1) ? (const MLoopUV *)CustomData_get_layer_n( &me_eval->ldata, CD_MLOOPUV, uv_idx) : nullptr; From 485ab420757bdad5ce4ec9b64ca31ab7fec78dd7 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Mon, 9 Jan 2023 21:37:22 -0800 Subject: [PATCH 0552/1522] BLF: Improved CJK Font Preview Differentiation Use font's OS/2 table code page range bits to help differentiate between Korean, Japanese, Simplified & Traditional Chinese fonts. See D16484 for details. Differential Revision: https://developer.blender.org/D16484 Reviewed by Brecht Van Lommel --- source/blender/blenfont/intern/blf_thumbs.c | 16 ++++++++++++++++ source/blender/imbuf/intern/thumbs_font.c | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/source/blender/blenfont/intern/blf_thumbs.c b/source/blender/blenfont/intern/blf_thumbs.c index 8a640ac86a7..0a0ae32af87 100644 --- a/source/blender/blenfont/intern/blf_thumbs.c +++ b/source/blender/blenfont/intern/blf_thumbs.c @@ -257,6 +257,22 @@ static const char32_t *blf_get_sample_text(FT_Face face) count_bits_i((uint)os2_table->ulUnicodeRange3) + count_bits_i((uint)os2_table->ulUnicodeRange4); + /* Use OS/2 Table code page range bits to differentiate between (combined) CJK fonts. + * See https://learn.microsoft.com/en-us/typography/opentype/spec/os2#cpr */ + FT_ULong codepages = os2_table->ulCodePageRange1; + if (codepages & (1 << 19) || codepages & (1 << 21)) { + return U"\ud55c\uad6d\uc5b4"; /* 한국어 Korean. */ + } + if (codepages & (1 << 20)) { + return U"\u7E41\u9AD4\u5B57"; /* 繁體字 Traditional Chinese. */ + } + if (codepages & (1 << 17) && !(codepages & (1 << 18))) { + return U"\u65E5\u672C\u8A9E"; /* 日本語 Japanese. */ + } + if (codepages & (1 << 18) && !(codepages & (1 << 17))) { + return U"\u7B80\u4F53\u5B57"; /* 简体字 Simplified Chinese. */ + } + for (uint i = 0; i < ARRAY_SIZE(unicode_samples); ++i) { const UnicodeSample *s = &unicode_samples[i]; if (os2_table && s->field && s->mask) { diff --git a/source/blender/imbuf/intern/thumbs_font.c b/source/blender/imbuf/intern/thumbs_font.c index c3ed81698d9..64f6741a34b 100644 --- a/source/blender/imbuf/intern/thumbs_font.c +++ b/source/blender/imbuf/intern/thumbs_font.c @@ -17,7 +17,7 @@ #include "../../blenfont/BLF_api.h" /* Only change if we need to update the previews in the on-disk cache. */ -#define FONT_THUMB_VERSION "1.0.0" +#define FONT_THUMB_VERSION "1.0.1" struct ImBuf *IMB_thumb_load_font(const char *filename, uint x, uint y) { From 6ef8db35e7a8104a81c0fb5c8522c3e93fb4f75d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 10 Jan 2023 16:39:53 +1100 Subject: [PATCH 0553/1522] Cleanup: clarify naming for deformed vertex positions & normals Edit-mesh duplicator logic used a struct member vert_coords which read as an alternative (and inconsistent) naming to vert_positions. Rename to `vert_positions_deform` as the purpose of this value is to assign when modifiers deform an edit-mesh. Add `_deform` suffix to normals as well. --- .../blender/blenkernel/intern/object_dupli.cc | 49 ++++++++++--------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index a9f2406ccfd..18dd92b62b4 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -565,8 +565,8 @@ struct VertexDupliData_EditMesh { BMEditMesh *em; /* Can be nullptr. */ - const float (*vert_coords)[3]; - const float (*vert_normals)[3]; + const float (*vert_positions_deform)[3]; + const float (*vert_normals_deform)[3]; /** * \note The edit-mesh may assign #DupliObject.orco in cases when a regular mesh wouldn't. @@ -682,14 +682,14 @@ static void make_child_duplis_verts_from_editmesh(const DupliContext *ctx, BMIter iter; int i; - const float(*vert_coords)[3] = vdd->vert_coords; - const float(*vert_normals)[3] = vdd->vert_normals; + const float(*vert_positions_deform)[3] = vdd->vert_positions_deform; + const float(*vert_normals_deform)[3] = vdd->vert_normals_deform; BM_ITER_MESH_INDEX (v, &iter, em->bm, BM_VERTS_OF_MESH, i) { const float *co, *no; - if (vert_coords != nullptr) { - co = vert_coords[i]; - no = vert_normals ? vert_normals[i] : nullptr; + if (vert_positions_deform != nullptr) { + co = vert_positions_deform[i]; + no = vert_normals_deform ? vert_normals_deform[i] : nullptr; } else { co = v->co; @@ -710,10 +710,10 @@ static void make_duplis_verts(const DupliContext *ctx) /* Gather mesh info. */ BMEditMesh *em = nullptr; - const float(*vert_coords)[3] = nullptr; - const float(*vert_normals)[3] = nullptr; + const float(*vert_positions_deform)[3] = nullptr; + const float(*vert_normals_deform)[3] = nullptr; const Mesh *me_eval = mesh_data_from_duplicator_object( - parent, &em, &vert_coords, use_rotation ? &vert_normals : nullptr); + parent, &em, &vert_positions_deform, use_rotation ? &vert_normals_deform : nullptr); if (em == nullptr && me_eval == nullptr) { return; } @@ -724,9 +724,9 @@ static void make_duplis_verts(const DupliContext *ctx) VertexDupliData_EditMesh vdd{}; vdd.params = vdd_params; vdd.em = em; - vdd.vert_coords = vert_coords; - vdd.vert_normals = vert_normals; - vdd.has_orco = (vert_coords != nullptr); + vdd.vert_positions_deform = vert_positions_deform; + vdd.vert_normals_deform = vert_normals_deform; + vdd.has_orco = (vert_positions_deform != nullptr); make_child_duplis(ctx, &vdd, make_child_duplis_verts_from_editmesh); } @@ -1073,7 +1073,7 @@ struct FaceDupliData_EditMesh { bool has_orco, has_uvs; int cd_loop_uv_offset; /* Can be nullptr. */ - const float (*vert_coords)[3]; + const float (*vert_positions_deform)[3]; }; static void get_dupliface_transform_from_coords(Span coords, @@ -1181,7 +1181,7 @@ static DupliObject *face_dupli_from_editmesh(const DupliContext *ctx, /* Mesh variables. */ BMFace *f, - const float (*vert_coords)[3]) + const float (*vert_positions_deform)[3]) { const int coords_len = f->len; Array coords(coords_len); @@ -1189,9 +1189,9 @@ static DupliObject *face_dupli_from_editmesh(const DupliContext *ctx, BMLoop *l_first, *l_iter; int i = 0; l_iter = l_first = BM_FACE_FIRST_LOOP(f); - if (vert_coords != nullptr) { + if (vert_positions_deform != nullptr) { do { - copy_v3_v3(coords[i++], vert_coords[BM_elem_index_get(l_iter->v)]); + copy_v3_v3(coords[i++], vert_positions_deform[BM_elem_index_get(l_iter->v)]); } while ((l_iter = l_iter->next) != l_first); } else { @@ -1261,9 +1261,9 @@ static void make_child_duplis_faces_from_editmesh(const DupliContext *ctx, BMIter iter; const bool use_scale = fdd->params.use_scale; - const float(*vert_coords)[3] = fdd->vert_coords; + const float(*vert_positions_deform)[3] = fdd->vert_positions_deform; - BLI_assert((vert_coords == nullptr) || (em->bm->elem_index_dirty & BM_VERT) == 0); + BLI_assert((vert_positions_deform == nullptr) || (em->bm->elem_index_dirty & BM_VERT) == 0); invert_m4_m4(inst_ob->world_to_object, inst_ob->object_to_world); /* Relative transform from parent to child space. */ @@ -1272,7 +1272,7 @@ static void make_child_duplis_faces_from_editmesh(const DupliContext *ctx, BM_ITER_MESH_INDEX (f, &iter, em->bm, BM_FACES_OF_MESH, a) { DupliObject *dob = face_dupli_from_editmesh( - fdd->params.ctx, inst_ob, child_imat, a, use_scale, scale_fac, f, vert_coords); + fdd->params.ctx, inst_ob, child_imat, a, use_scale, scale_fac, f, vert_positions_deform); if (fdd->has_orco) { const float w = 1.0f / float(f->len); @@ -1294,8 +1294,9 @@ static void make_duplis_faces(const DupliContext *ctx) /* Gather mesh info. */ BMEditMesh *em = nullptr; - const float(*vert_coords)[3] = nullptr; - const Mesh *me_eval = mesh_data_from_duplicator_object(parent, &em, &vert_coords, nullptr); + const float(*vert_positions_deform)[3] = nullptr; + const Mesh *me_eval = mesh_data_from_duplicator_object( + parent, &em, &vert_positions_deform, nullptr); if (em == nullptr && me_eval == nullptr) { return; } @@ -1307,8 +1308,8 @@ static void make_duplis_faces(const DupliContext *ctx) FaceDupliData_EditMesh fdd{}; fdd.params = fdd_params; fdd.em = em; - fdd.vert_coords = vert_coords; - fdd.has_orco = (vert_coords != nullptr); + fdd.vert_positions_deform = vert_positions_deform; + fdd.has_orco = (vert_positions_deform != nullptr); fdd.has_uvs = (uv_idx != -1); fdd.cd_loop_uv_offset = (uv_idx != -1) ? CustomData_get_n_offset(&em->bm->ldata, CD_MLOOPUV, uv_idx) : From 6c774feba2c9a1eb5834646f597a0f2c63177914 Mon Sep 17 00:00:00 2001 From: Martijn Versteegh Date: Tue, 10 Jan 2023 00:47:04 -0500 Subject: [PATCH 0554/1522] Mesh: Move UV layers to generic attributes Currently the `MLoopUV` struct stores UV coordinates and flags related to editing UV maps in the UV editor. This patch changes the coordinates to use the generic 2D vector type, and moves the flags into three separate boolean attributes. This follows the design in T95965, with the ultimate intention of simplifying code and improving performance. Importantly, the change allows exporters and renderers to use UVs "touched" by geometry nodes, which only creates generic attributes. It also allows geometry nodes to create "proper" UV maps from scratch, though only with the Store Named Attribute node for now. The new design considers any 2D vector attribute on the corner domain to be a UV map. In the future, they might be distinguished from regular 2D vectors with attribute metadata, which may be helpful because they are often interpolated differently. Most of the code changes deal with passing around UV BMesh custom data offsets and tracking the boolean "sublayers". The boolean layers are use the following prefixes for attribute names: vert selection: `.vs.`, edge selection: `.es.`, pinning: `.pn.`. Currently these are short to avoid using up the maximum length of attribute names. To accommodate for these 4 extra characters, the name length limit is enlarged to 68 bytes, while the maximum user settable name length is still 64 bytes. Unfortunately Python/RNA API access to the UV flag data becomes slower. Accessing the boolean layers directly is be better for performance in general. Like the other mesh SoA refactors, backward and forward compatibility aren't affected, and won't be changed until 4.0. We pay for that by making mesh reading and writing more expensive with conversions. Resolves T85962 Differential Revision: https://developer.blender.org/D14365 --- .../startup/bl_ui/properties_data_mesh.py | 1 - source/blender/blenkernel/BKE_attribute.h | 4 + source/blender/blenkernel/BKE_customdata.h | 37 +- .../blender/blenkernel/BKE_editmesh_tangent.h | 3 +- source/blender/blenkernel/BKE_mesh.h | 2 - .../blenkernel/BKE_mesh_legacy_convert.h | 5 + source/blender/blenkernel/BKE_mesh_mapping.h | 7 +- source/blender/blenkernel/BKE_mesh_tangent.h | 8 +- .../blender/blenkernel/intern/DerivedMesh.cc | 2 +- source/blender/blenkernel/intern/attribute.cc | 144 ++- .../blenkernel/intern/attribute_access.cc | 105 +- .../intern/attribute_access_intern.hh | 38 - .../blender/blenkernel/intern/customdata.cc | 229 ++-- .../blenkernel/intern/data_transfer.cc | 6 +- .../blender/blenkernel/intern/dynamicpaint.c | 71 +- .../blenkernel/intern/editmesh_tangent.cc | 12 +- source/blender/blenkernel/intern/fluid.c | 13 +- .../intern/geometry_component_mesh.cc | 21 +- .../blender/blenkernel/intern/layer_utils.c | 2 +- source/blender/blenkernel/intern/mesh.cc | 66 +- .../blender/blenkernel/intern/mesh_convert.cc | 20 +- .../blenkernel/intern/mesh_evaluate.cc | 18 - .../blenkernel/intern/mesh_legacy_convert.cc | 227 +++- .../blender/blenkernel/intern/mesh_mapping.cc | 28 +- .../intern/mesh_merge_customdata.cc | 18 +- .../blender/blenkernel/intern/mesh_mirror.cc | 22 +- .../blender/blenkernel/intern/mesh_tangent.cc | 67 +- .../blenkernel/intern/mesh_validate.cc | 10 +- .../blender/blenkernel/intern/object_dupli.cc | 17 +- .../blenkernel/intern/object_update.cc | 2 +- .../blender/blenkernel/intern/paint_canvas.cc | 4 +- .../blender/blenkernel/intern/pbvh_pixels.cc | 6 +- .../blenkernel/intern/pbvh_uv_islands.cc | 4 +- .../blenkernel/intern/pbvh_uv_islands.hh | 4 +- .../blenkernel/intern/subdiv_converter_mesh.c | 4 +- .../blender/blenkernel/intern/subdiv_eval.c | 14 +- .../blender/blenkernel/intern/subdiv_mesh.cc | 15 +- .../blender/blenkernel/intern/subsurf_ccg.c | 24 +- .../blenloader/intern/versioning_280.c | 3 +- .../blenloader/intern/versioning_400.cc | 1 + .../blenloader/intern/versioning_defaults.cc | 9 +- source/blender/bmesh/bmesh.h | 1 + source/blender/bmesh/bmesh_class.h | 13 + source/blender/bmesh/intern/bmesh_interp.c | 57 + source/blender/bmesh/intern/bmesh_interp.h | 9 + .../bmesh/intern/bmesh_mesh_convert.cc | 81 ++ source/blender/bmesh/intern/bmesh_polygon.c | 6 +- source/blender/bmesh/intern/bmesh_query_uv.cc | 65 +- source/blender/bmesh/intern/bmesh_query_uv.h | 5 + .../bmesh/operators/bmo_join_triangles.c | 3 +- source/blender/bmesh/operators/bmo_mirror.c | 18 +- .../blender/bmesh/operators/bmo_primitive.c | 86 +- source/blender/bmesh/operators/bmo_utils.c | 40 +- source/blender/bmesh/tools/bmesh_bevel.c | 34 +- .../bmesh/tools/bmesh_decimate_dissolve.c | 6 +- source/blender/bmesh/tools/bmesh_path_uv.c | 39 +- .../draw/engines/overlay/overlay_edit_uv.cc | 5 +- .../draw/engines/workbench/workbench_engine.c | 4 +- source/blender/draw/intern/draw_cache.c | 2 +- .../draw/intern/draw_cache_impl_mesh.cc | 18 +- .../draw/intern/draw_cache_impl_particles.c | 18 +- .../blender/draw/intern/draw_manager_data.cc | 8 +- source/blender/draw/intern/draw_pbvh.cc | 17 +- .../intern/mesh_extractors/extract_mesh.cc | 19 +- .../intern/mesh_extractors/extract_mesh.hh | 6 +- .../extract_mesh_vbo_edit_data.cc | 6 +- .../extract_mesh_vbo_edituv_data.cc | 25 +- .../extract_mesh_vbo_edituv_stretch_angle.cc | 42 +- .../extract_mesh_vbo_edituv_stretch_area.cc | 9 +- .../extract_mesh_vbo_fdots_edituv_data.cc | 8 +- .../extract_mesh_vbo_fdots_uv.cc | 14 +- .../mesh_extractors/extract_mesh_vbo_tan.cc | 9 +- .../mesh_extractors/extract_mesh_vbo_uv.cc | 25 +- .../editors/curves/intern/curves_ops.cc | 2 +- .../editors/geometry/geometry_attributes.cc | 19 - source/blender/editors/include/ED_mesh.h | 8 + source/blender/editors/include/ED_uvedit.h | 55 +- source/blender/editors/mesh/editface.cc | 2 +- .../blender/editors/mesh/editmesh_select.cc | 4 +- source/blender/editors/mesh/editmesh_utils.c | 79 +- source/blender/editors/mesh/mesh_data.cc | 138 ++- source/blender/editors/mesh/meshtools.cc | 6 +- source/blender/editors/object/object_add.cc | 2 +- source/blender/editors/object/object_bake.c | 2 +- .../blender/editors/object/object_bake_api.c | 6 +- .../editors/object/object_data_transfer.c | 6 +- .../editors/sculpt_paint/paint_image_proj.cc | 88 +- .../editors/sculpt_paint/paint_utils.c | 23 +- .../blender/editors/sculpt_paint/sculpt_uv.c | 67 +- .../editors/space_view3d/view3d_draw.cc | 4 +- .../transform/transform_convert_mesh_uv.c | 33 +- .../blender/editors/uvedit/uvedit_buttons.c | 20 +- .../editors/uvedit/uvedit_clipboard.cc | 14 +- source/blender/editors/uvedit/uvedit_intern.h | 8 +- .../blender/editors/uvedit/uvedit_islands.cc | 52 +- source/blender/editors/uvedit/uvedit_ops.c | 279 +++-- source/blender/editors/uvedit/uvedit_path.c | 103 +- source/blender/editors/uvedit/uvedit_rip.c | 93 +- source/blender/editors/uvedit/uvedit_select.c | 993 +++++++++--------- .../editors/uvedit/uvedit_smart_stitch.c | 173 ++- .../editors/uvedit/uvedit_unwrap_ops.c | 259 +++-- .../BlenderStrokeRenderer.cpp | 39 +- source/blender/gpu/GPU_material.h | 10 +- .../blender/gpu/intern/gpu_vertex_format.cc | 2 +- .../io/alembic/exporter/abc_writer_mesh.cc | 8 +- .../io/alembic/intern/abc_customdata.cc | 31 +- .../io/alembic/intern/abc_customdata.h | 5 +- .../io/alembic/intern/abc_reader_mesh.cc | 13 +- source/blender/io/collada/EffectExporter.cpp | 4 +- .../blender/io/collada/GeometryExporter.cpp | 26 +- source/blender/io/collada/InstanceWriter.cpp | 6 +- source/blender/io/collada/MeshImporter.cpp | 12 +- source/blender/io/collada/MeshImporter.h | 2 +- source/blender/io/collada/collada_utils.cpp | 10 +- .../blender/io/usd/intern/usd_reader_mesh.cc | 14 +- .../io/usd/intern/usd_writer_abstract.cc | 2 +- .../blender/io/usd/intern/usd_writer_mesh.cc | 7 +- .../wavefront_obj/exporter/obj_export_mesh.cc | 32 +- .../wavefront_obj/importer/obj_import_mesh.cc | 33 +- .../wavefront_obj/tests/obj_importer_tests.cc | 6 +- .../blender/makesdna/DNA_customdata_types.h | 7 +- .../blender/makesdna/DNA_dynamicpaint_types.h | 8 +- source/blender/makesdna/DNA_fluid_types.h | 5 +- source/blender/makesdna/DNA_meshdata_types.h | 41 +- source/blender/makesdna/DNA_modifier_types.h | 54 +- source/blender/makesdna/DNA_node_types.h | 5 +- source/blender/makesdna/DNA_particle_types.h | 5 +- source/blender/makesdna/DNA_texture_types.h | 10 +- .../blender/makesrna/intern/rna_attribute.c | 4 +- source/blender/makesrna/intern/rna_mesh.c | 164 ++- source/blender/makesrna/intern/rna_mesh_api.c | 2 +- source/blender/makesrna/intern/rna_modifier.c | 13 +- source/blender/makesrna/intern/rna_object.c | 2 +- source/blender/makesrna/intern/rna_particle.c | 4 +- source/blender/modifiers/intern/MOD_array.cc | 10 +- .../modifiers/intern/MOD_dynamicpaint.c | 4 +- source/blender/modifiers/intern/MOD_ocean.c | 26 +- source/blender/modifiers/intern/MOD_screw.cc | 28 +- source/blender/modifiers/intern/MOD_util.cc | 13 +- .../blender/modifiers/intern/MOD_uvproject.cc | 20 +- source/blender/modifiers/intern/MOD_uvwarp.cc | 18 +- .../node_geo_mesh_primitive_ico_sphere.cc | 6 +- .../python/bmesh/bmesh_py_types_customdata.c | 33 +- .../python/bmesh/bmesh_py_types_meshdata.c | 165 ++- .../python/bmesh/bmesh_py_types_meshdata.h | 6 +- source/blender/render/RE_bake.h | 1 - source/blender/render/RE_texture_margin.h | 1 - source/blender/render/intern/bake.cc | 10 +- source/blender/render/intern/multires_bake.cc | 68 +- .../blender/render/intern/texture_margin.cc | 24 +- 150 files changed, 3111 insertions(+), 2437 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index b7f7d925c2b..61027f68f19 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -607,7 +607,6 @@ class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel): # Built-in names. {"shade_smooth": None, "normal": None, "crease": None}, mesh.attributes, - mesh.uv_layers, None if ob is None else ob.vertex_groups, ): if collection is None: diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h index eef1459be81..7c01a9205fc 100644 --- a/source/blender/blenkernel/BKE_attribute.h +++ b/source/blender/blenkernel/BKE_attribute.h @@ -131,6 +131,10 @@ struct CustomDataLayer *BKE_id_attributes_color_find(const struct ID *id, const bool BKE_id_attribute_calc_unique_name(struct ID *id, const char *name, char *outname); +const char *BKE_uv_map_vert_select_name_get(const char *uv_map_name, char *buffer); +const char *BKE_uv_map_edge_select_name_get(const char *uv_map_name, char *buffer); +const char *BKE_uv_map_pin_name_get(const char *uv_map_name, char *buffer); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 582dd1b5a29..b97ac9cc9b9 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -31,6 +31,28 @@ struct CustomData_MeshMasks; struct ID; typedef uint64_t eCustomDataMask; +/* These names are used as prefixes for UV layer names to find the associated boolean + * layers. They should never be longer than 2 chars, as MAX_CUSTOMDATA_LAYER_NAME + * has 4 extra bytes above what can be used for the base layer name, and these + * prefixes are placed between 2 '.'s at the start of the layer name. + * For example The uv vert selection layer of a layer named 'UVMap.001' + * will be called '.vs.UVMap.001' . */ +#define UV_VERTSEL_NAME "vs" +#define UV_EDGESEL_NAME "es" +#define UV_PINNED_NAME "pn" + +/** + * UV map related customdata offsets into BMesh attribute blocks. See #BM_uv_map_get_offsets. + * Defined in #BKE_customdata.h to avoid including bmesh.h in many unrelated areas. + * An offset of -1 means that the corresponding layer does not exist. + */ +typedef struct BMUVOffsets { + int uv; + int select_vert; + int select_edge; + int pin; +} BMUVOffsets; + /* A data type large enough to hold 1 element from any custom-data layer type. */ typedef struct { unsigned char data[64]; @@ -125,7 +147,7 @@ void CustomData_data_mix_value( /** * Compares if data1 is equal to data2. type is a valid CustomData type - * enum (e.g. #CD_MLOOPUV). the layer type's equal function is used to compare + * enum (e.g. #CD_PROP_FLOAT). the layer type's equal function is used to compare * the data, if it exists, otherwise #memcmp is used. */ bool CustomData_data_equals(int type, const void *data1, const void *data2); @@ -422,6 +444,7 @@ int CustomData_get_n_offset(const struct CustomData *data, int type, int n); int CustomData_get_layer_index(const struct CustomData *data, int type); int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n); int CustomData_get_named_layer_index(const struct CustomData *data, int type, const char *name); +int CustomData_get_named_layer_index_notype(const struct CustomData *data, const char *name); int CustomData_get_active_layer_index(const struct CustomData *data, int type); int CustomData_get_render_layer_index(const struct CustomData *data, int type); int CustomData_get_clone_layer_index(const struct CustomData *data, int type); @@ -531,6 +554,13 @@ bool CustomData_layertype_is_dynamic(int type); */ int CustomData_layertype_layers_max(int type); +#ifdef __cplusplus + +/** \return The maximum length for a layer name with the given prefix. */ +int CustomData_name_max_length_calc(blender::StringRef name); + +#endif + /** * Make sure the name of layer at index is unique. */ @@ -604,8 +634,9 @@ enum { CD_FAKE_SEAM = CD_FAKE | 100, /* UV seam flag for edges. */ /* Multiple types of mesh elements... */ - CD_FAKE_UV = CD_FAKE | - CD_MLOOPUV, /* UV flag, because we handle both loop's UVs and poly's textures. */ + CD_FAKE_UV = + CD_FAKE | + CD_PROP_FLOAT2, /* UV flag, because we handle both loop's UVs and poly's textures. */ CD_FAKE_LNOR = CD_FAKE | CD_CUSTOMLOOPNORMAL, /* Because we play with clnor and temp lnor layers here. */ diff --git a/source/blender/blenkernel/BKE_editmesh_tangent.h b/source/blender/blenkernel/BKE_editmesh_tangent.h index ee1fda2e5db..c2697ec38b0 100644 --- a/source/blender/blenkernel/BKE_editmesh_tangent.h +++ b/source/blender/blenkernel/BKE_editmesh_tangent.h @@ -9,6 +9,7 @@ #ifdef __cplusplus extern "C" { #endif +#include "DNA_customdata_types.h" /** * \see #BKE_mesh_calc_loop_tangent, same logic but used arrays instead of #BMesh data. @@ -19,7 +20,7 @@ extern "C" { */ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em, bool calc_active_tangent, - const char (*tangent_names)[MAX_NAME], + const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len, const float (*poly_normals)[3], const float (*loop_normals)[3], diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index cd291d4a42d..ffca4cff347 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -36,7 +36,6 @@ struct MEdge; struct MFace; struct MLoop; struct MLoopTri; -struct MLoopUV; struct MPoly; struct Main; struct MemArena; @@ -693,7 +692,6 @@ float BKE_mesh_calc_poly_area(const struct MPoly *mpoly, const struct MLoop *loopstart, const float (*vert_positions)[3]); float BKE_mesh_calc_area(const struct Mesh *me); -float BKE_mesh_calc_poly_uv_area(const struct MPoly *mpoly, const struct MLoopUV *uv_array); void BKE_mesh_calc_poly_angles(const struct MPoly *mpoly, const struct MLoop *loopstart, const float (*vert_positions)[3], diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h index a561cf9e8fd..3b1b94e516a 100644 --- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h +++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h @@ -26,6 +26,11 @@ struct MFace; #ifdef __cplusplus +void BKE_mesh_legacy_convert_uvs_to_struct(Mesh *mesh, + blender::ResourceScope &temp_mloopuv_for_convert, + blender::Vector &layers_to_write); +void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh); + /** * Move face sets to the legacy type from a generic type. */ diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h index b70e05ed14f..36ac0708629 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.h +++ b/source/blender/blenkernel/BKE_mesh_mapping.h @@ -17,7 +17,6 @@ extern "C" { struct MEdge; struct MLoop; struct MLoopTri; -struct MLoopUV; struct MPoly; /* UvVertMap */ @@ -105,7 +104,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const struct MPoly *mpoly, const bool *hide_poly, const bool *select_poly, const struct MLoop *mloop, - const struct MLoopUV *mloopuv, + const float (*mloopuv)[2], unsigned int totpoly, unsigned int totvert, const float limit[2], @@ -288,7 +287,7 @@ bool BKE_mesh_calc_islands_loop_poly_edgeseam(const float (*vert_positions)[3], /** * Calculate UV islands. * - * \note If no MLoopUV layer is passed, we only consider edges tagged as seams as UV boundaries. + * \note If no UV layer is passed, we only consider edges tagged as seams as UV boundaries. * This has the advantages of simplicity, and being valid/common to all UV maps. * However, it means actual UV islands without matching UV seams will not be handled correctly. * If a valid UV layer is passed as \a luvs parameter, @@ -306,7 +305,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3], int totpoly, struct MLoop *loops, int totloop, - const struct MLoopUV *luvs, + const float (*luvs)[2], MeshIslandStore *r_island_store); /** diff --git a/source/blender/blenkernel/BKE_mesh_tangent.h b/source/blender/blenkernel/BKE_mesh_tangent.h index cec98da5ef6..b30ce13da8d 100644 --- a/source/blender/blenkernel/BKE_mesh_tangent.h +++ b/source/blender/blenkernel/BKE_mesh_tangent.h @@ -22,7 +22,7 @@ void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3], const struct MLoop *mloops, float (*r_looptangent)[4], const float (*loop_normals)[3], - const struct MLoopUV *loopuv, + const float (*loopuv)[2], int numLoops, const struct MPoly *mpolys, int numPolys, @@ -50,7 +50,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], struct CustomData *loopdata, bool calc_active_tangent, - const char (*tangent_names)[64], + const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len, const float (*vert_normals)[3], const float (*poly_normals)[3], @@ -63,7 +63,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], void BKE_mesh_calc_loop_tangents(struct Mesh *me_eval, bool calc_active_tangent, - const char (*tangent_names)[MAX_NAME], + const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len); /* Helpers */ @@ -81,7 +81,7 @@ void BKE_mesh_add_loop_tangent_named_layer_for_uv(struct CustomData *uv_data, */ void BKE_mesh_calc_loop_tangent_step_0(const struct CustomData *loopData, bool calc_active_tangent, - const char (*tangent_names)[64], + const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_count, bool *rcalc_act, bool *rcalc_ren, diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 19e9eba2d0c..709f52060fc 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -1690,7 +1690,7 @@ 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_PROP_BYTE_COLOR; + r_mask->lmask |= CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_BYTE_COLOR; r_mask->fmask |= CD_MASK_MTFACE; } diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc index ddf70ee7535..4b090e710f5 100644 --- a/source/blender/blenkernel/intern/attribute.cc +++ b/source/blender/blenkernel/intern/attribute.cc @@ -141,6 +141,19 @@ bool BKE_attribute_allow_procedural_access(const char *attribute_name) return blender::bke::allow_procedural_attribute_access(attribute_name); } +static bool bke_id_attribute_rename_if_exists(ID *id, + const char *old_name, + const char *new_name, + ReportList *reports) +{ + CustomDataLayer *layer = BKE_id_attribute_search( + id, old_name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL); + if (layer == nullptr) { + return false; + } + return BKE_id_attribute_rename(id, old_name, new_name, reports); +} + bool BKE_id_attribute_rename(ID *id, const char *old_name, const char *new_name, @@ -155,8 +168,18 @@ bool BKE_id_attribute_rename(ID *id, BKE_report(reports, RPT_ERROR, "Attribute name can not be empty"); return false; } - if (STREQ(old_name, new_name)) { - return false; + + /* NOTE: Checking if the new name matches the old name only makes sense when the name + * is clamped to it's maximum length, otherwise assigning an over-long name multiple times + * will add `.001` suffix unnecessarily. */ + { + const int maxlength = CustomData_name_max_length_calc(new_name); + /* NOTE: A function that performs a clamped comparison without copying would be handy here. */ + char new_name_clamped[MAX_CUSTOMDATA_LAYER_NAME]; + BLI_strncpy_utf8(new_name_clamped, new_name, maxlength); + if (STREQ(old_name, new_name_clamped)) { + return false; + } } CustomDataLayer *layer = BKE_id_attribute_search( @@ -169,6 +192,24 @@ bool BKE_id_attribute_rename(ID *id, char result_name[MAX_CUSTOMDATA_LAYER_NAME]; BKE_id_attribute_calc_unique_name(id, new_name, result_name); + if (layer->type == CD_PROP_FLOAT2 && GS(id->name) == ID_ME) { + /* Rename UV sub-attributes. */ + char buffer_src[MAX_CUSTOMDATA_LAYER_NAME]; + char buffer_dst[MAX_CUSTOMDATA_LAYER_NAME]; + + bke_id_attribute_rename_if_exists(id, + BKE_uv_map_vert_select_name_get(layer->name, buffer_src), + BKE_uv_map_vert_select_name_get(result_name, buffer_dst), + reports); + bke_id_attribute_rename_if_exists(id, + BKE_uv_map_edge_select_name_get(layer->name, buffer_src), + BKE_uv_map_edge_select_name_get(result_name, buffer_dst), + reports); + bke_id_attribute_rename_if_exists(id, + BKE_uv_map_pin_name_get(layer->name, buffer_src), + BKE_uv_map_pin_name_get(result_name, buffer_dst), + reports); + } if (StringRef(old_name) == BKE_id_attributes_active_color_name(id)) { BKE_id_attributes_active_color_set(id, result_name); } @@ -213,18 +254,18 @@ static bool unique_name_cb(void *arg, const char *name) bool BKE_id_attribute_calc_unique_name(ID *id, const char *name, char *outname) { AttrUniqueData data{id}; + const int maxlength = CustomData_name_max_length_calc(name); /* Set default name if none specified. * NOTE: We only call IFACE_() if needed to avoid locale lookup overhead. */ if (!name || name[0] == '\0') { - BLI_strncpy(outname, IFACE_("Attribute"), MAX_CUSTOMDATA_LAYER_NAME); + BLI_strncpy(outname, IFACE_("Attribute"), maxlength); } else { - BLI_strncpy_utf8(outname, name, MAX_CUSTOMDATA_LAYER_NAME); + BLI_strncpy_utf8(outname, name, maxlength); } - return BLI_uniquename_cb( - unique_name_cb, &data, nullptr, '.', outname, MAX_CUSTOMDATA_LAYER_NAME); + return BLI_uniquename_cb(unique_name_cb, &data, nullptr, '.', outname, maxlength); } CustomDataLayer *BKE_id_attribute_new( @@ -263,6 +304,24 @@ CustomDataLayer *BKE_id_attribute_new( return (index == -1) ? nullptr : &(customdata->layers[index]); } +static void bke_id_attribute_copy_if_exists(ID *id, const char *srcname, const char *dstname) +{ + using namespace blender::bke; + + std::optional attributes = get_attribute_accessor_for_write(*id); + if (!attributes) { + return; + } + + GAttributeReader src = attributes->lookup(srcname); + if (!src) { + return; + } + + const eCustomDataType type = cpp_type_to_custom_data_type(src.varray.type()); + attributes->add(dstname, src.domain, type, AttributeInitVArray(src.varray)); +} + CustomDataLayer *BKE_id_attribute_duplicate(ID *id, const char *name, ReportList *reports) { using namespace blender::bke; @@ -292,6 +351,22 @@ CustomDataLayer *BKE_id_attribute_duplicate(ID *id, const char *name, ReportList const eCustomDataType type = cpp_type_to_custom_data_type(src.varray.type()); attributes->add(uniquename, src.domain, type, AttributeInitVArray(src.varray)); + if (GS(id->name) == ID_ME && type == CD_PROP_FLOAT2) { + /* Duplicate UV sub-attributes. */ + char buffer_src[MAX_CUSTOMDATA_LAYER_NAME]; + char buffer_dst[MAX_CUSTOMDATA_LAYER_NAME]; + + bke_id_attribute_copy_if_exists(id, + BKE_uv_map_vert_select_name_get(name, buffer_src), + BKE_uv_map_vert_select_name_get(uniquename, buffer_dst)); + bke_id_attribute_copy_if_exists(id, + BKE_uv_map_edge_select_name_get(name, buffer_src), + BKE_uv_map_edge_select_name_get(uniquename, buffer_dst)); + bke_id_attribute_copy_if_exists(id, + BKE_uv_map_pin_name_get(name, buffer_src), + BKE_uv_map_pin_name_get(uniquename, buffer_dst)); + } + return BKE_id_attribute_search(id, uniquename, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL); } @@ -316,11 +391,27 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports) if (BMEditMesh *em = mesh->edit_mesh) { for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) { if (CustomData *data = info[domain].customdata) { + int layer_index = CustomData_get_named_layer_index_notype(data, name); + if (layer_index >= 0) { + if (data->layers[layer_index].type == CD_PROP_FLOAT2) { + /* free associated UV map bool layers */ + char buffer_src[MAX_CUSTOMDATA_LAYER_NAME]; + BM_data_layer_free_named( + em->bm, data, BKE_uv_map_vert_select_name_get(name, buffer_src)); + BM_data_layer_free_named( + em->bm, data, BKE_uv_map_edge_select_name_get(name, buffer_src)); + BM_data_layer_free_named(em->bm, data, BKE_uv_map_pin_name_get(name, buffer_src)); + } + } + /* Because it's possible that name is owned by the layer and will be freed + * when freeing the layer, do these checks before freeing. */ + const bool is_active_color_attribute = name == StringRef(mesh->active_color_attribute); + const bool is_default_color_attribute = name == StringRef(mesh->default_color_attribute); if (BM_data_layer_free_named(em->bm, data, name)) { - if (name == StringRef(mesh->active_color_attribute)) { + if (is_active_color_attribute) { MEM_SAFE_FREE(mesh->active_color_attribute); } - else if (name == StringRef(mesh->default_color_attribute)) { + else if (is_default_color_attribute) { MEM_SAFE_FREE(mesh->default_color_attribute); } return true; @@ -332,10 +423,23 @@ bool BKE_id_attribute_remove(ID *id, const char *name, ReportList *reports) } std::optional attributes = get_attribute_accessor_for_write(*id); + if (!attributes) { return false; } + if (GS(id->name) == ID_ME) { + + std::optional metadata = attributes->lookup_meta_data(name); + if (metadata->data_type == CD_PROP_FLOAT2) { + /* remove UV sub-attributes. */ + char buffer_src[MAX_CUSTOMDATA_LAYER_NAME]; + BKE_id_attribute_remove(id, BKE_uv_map_vert_select_name_get(name, buffer_src), reports); + BKE_id_attribute_remove(id, BKE_uv_map_edge_select_name_get(name, buffer_src), reports); + BKE_id_attribute_remove(id, BKE_uv_map_pin_name_get(name, buffer_src), reports); + } + } + return attributes->remove(name); } @@ -784,3 +888,27 @@ void BKE_id_attribute_copy_domains_temp(short id_type, *((short *)r_id->name) = id_type; } + +const char *BKE_uv_map_vert_select_name_get(const char *uv_map_name, char *buffer) +{ + BLI_assert(strlen(UV_VERTSEL_NAME) == 2); + BLI_assert(strlen(uv_map_name) < MAX_CUSTOMDATA_LAYER_NAME - 4); + BLI_snprintf(buffer, MAX_CUSTOMDATA_LAYER_NAME, ".%s.%s", UV_VERTSEL_NAME, uv_map_name); + return buffer; +} + +const char *BKE_uv_map_edge_select_name_get(const char *uv_map_name, char *buffer) +{ + BLI_assert(strlen(UV_EDGESEL_NAME) == 2); + BLI_assert(strlen(uv_map_name) < MAX_CUSTOMDATA_LAYER_NAME - 4); + BLI_snprintf(buffer, MAX_CUSTOMDATA_LAYER_NAME, ".%s.%s", UV_EDGESEL_NAME, uv_map_name); + return buffer; +} + +const char *BKE_uv_map_pin_name_get(const char *uv_map_name, char *buffer) +{ + BLI_assert(strlen(UV_PINNED_NAME) == 2); + BLI_assert(strlen(uv_map_name) < MAX_CUSTOMDATA_LAYER_NAME - 4); + BLI_snprintf(buffer, MAX_CUSTOMDATA_LAYER_NAME, ".%s.%s", UV_PINNED_NAME, uv_map_name); + return buffer; +} diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index acae10499c3..d95c80cf1eb 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -54,8 +54,25 @@ const char *no_procedural_access_message = bool allow_procedural_attribute_access(StringRef attribute_name) { - return !attribute_name.startswith(".sculpt") && !attribute_name.startswith(".select") && - !attribute_name.startswith(".hide"); + if (attribute_name.startswith(".select")) { + return false; + } + if (attribute_name.startswith(".sculpt")) { + return false; + } + if (attribute_name.startswith(".hide")) { + return false; + } + if (attribute_name.startswith("." UV_VERTSEL_NAME ".")) { + return false; + } + if (attribute_name.startswith("." UV_EDGESEL_NAME ".")) { + return false; + } + if (attribute_name.startswith("." UV_PINNED_NAME ".")) { + return false; + } + return true; } static int attribute_data_type_complexity(const eCustomDataType data_type) @@ -204,7 +221,7 @@ static void *add_generic_custom_data_layer(CustomData &custom_data, const AttributeIDRef &attribute_id) { if (!attribute_id.is_anonymous()) { - char attribute_name_c[MAX_NAME]; + char attribute_name_c[MAX_CUSTOMDATA_LAYER_NAME]; attribute_id.name().copy(attribute_name_c); return CustomData_add_layer_named( &custom_data, data_type, alloctype, layer_data, domain_num, attribute_name_c); @@ -522,88 +539,6 @@ bool CustomDataAttributeProvider::foreach_attribute(const void *owner, return true; } -GAttributeReader NamedLegacyCustomDataProvider::try_get_for_read( - const void *owner, const AttributeIDRef &attribute_id) const -{ - const CustomData *custom_data = custom_data_access_.get_const_custom_data(owner); - if (custom_data == nullptr) { - return {}; - } - for (const CustomDataLayer &layer : Span(custom_data->layers, custom_data->totlayer)) { - if (layer.type == stored_type_) { - if (custom_data_layer_matches_attribute_id(layer, attribute_id)) { - const int domain_num = custom_data_access_.get_element_num(owner); - return {as_read_attribute_(layer.data, domain_num), domain_}; - } - } - } - return {}; -} - -GAttributeWriter NamedLegacyCustomDataProvider::try_get_for_write( - void *owner, const AttributeIDRef &attribute_id) const -{ - CustomData *custom_data = custom_data_access_.get_custom_data(owner); - if (custom_data == nullptr) { - return {}; - } - for (CustomDataLayer &layer : MutableSpan(custom_data->layers, custom_data->totlayer)) { - if (layer.type == stored_type_) { - if (custom_data_layer_matches_attribute_id(layer, attribute_id)) { - const int element_num = custom_data_access_.get_element_num(owner); - void *data = CustomData_duplicate_referenced_layer_named( - custom_data, stored_type_, layer.name, element_num); - return {as_write_attribute_(data, element_num), domain_}; - } - } - } - return {}; -} - -bool NamedLegacyCustomDataProvider::try_delete(void *owner, - const AttributeIDRef &attribute_id) const -{ - CustomData *custom_data = custom_data_access_.get_custom_data(owner); - if (custom_data == nullptr) { - return false; - } - for (const int i : IndexRange(custom_data->totlayer)) { - const CustomDataLayer &layer = custom_data->layers[i]; - if (layer.type == stored_type_) { - if (custom_data_layer_matches_attribute_id(layer, attribute_id)) { - const int element_num = custom_data_access_.get_element_num(owner); - CustomData_free_layer(custom_data, stored_type_, element_num, i); - return true; - } - } - } - return false; -} - -bool NamedLegacyCustomDataProvider::foreach_attribute( - const void *owner, const AttributeForeachCallback callback) const -{ - const CustomData *custom_data = custom_data_access_.get_const_custom_data(owner); - if (custom_data == nullptr) { - return true; - } - for (const CustomDataLayer &layer : Span(custom_data->layers, custom_data->totlayer)) { - if (layer.type == stored_type_) { - AttributeMetaData meta_data{domain_, attribute_type_}; - if (!callback(layer.name, meta_data)) { - return false; - } - } - } - return true; -} - -void NamedLegacyCustomDataProvider::foreach_domain( - const FunctionRef callback) const -{ - callback(domain_); -} - CustomDataAttributes::CustomDataAttributes() { CustomData_reset(&data); diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh index fe84123f2b5..b429756e754 100644 --- a/source/blender/blenkernel/intern/attribute_access_intern.hh +++ b/source/blender/blenkernel/intern/attribute_access_intern.hh @@ -170,44 +170,6 @@ class CustomDataAttributeProvider final : public DynamicAttributesProvider { } }; -/** - * This attribute provider is used for uv maps and vertex colors. - */ -class NamedLegacyCustomDataProvider final : public DynamicAttributesProvider { - private: - using AsReadAttribute = GVArray (*)(const void *data, int domain_num); - using AsWriteAttribute = GVMutableArray (*)(void *data, int domain_num); - const eAttrDomain domain_; - const eCustomDataType attribute_type_; - const eCustomDataType stored_type_; - const CustomDataAccessInfo custom_data_access_; - const AsReadAttribute as_read_attribute_; - const AsWriteAttribute as_write_attribute_; - - public: - NamedLegacyCustomDataProvider(const eAttrDomain domain, - const eCustomDataType attribute_type, - const eCustomDataType stored_type, - const CustomDataAccessInfo custom_data_access, - const AsReadAttribute as_read_attribute, - const AsWriteAttribute as_write_attribute) - : domain_(domain), - attribute_type_(attribute_type), - stored_type_(stored_type), - custom_data_access_(custom_data_access), - as_read_attribute_(as_read_attribute), - as_write_attribute_(as_write_attribute) - { - } - - GAttributeReader try_get_for_read(const void *owner, - const AttributeIDRef &attribute_id) const final; - GAttributeWriter try_get_for_write(void *owner, const AttributeIDRef &attribute_id) const final; - bool try_delete(void *owner, const AttributeIDRef &attribute_id) const final; - bool foreach_attribute(const void *owner, const AttributeForeachCallback callback) const final; - void foreach_domain(const FunctionRef callback) const final; -}; - template GVArray make_array_read_attribute(const void *data, const int domain_num) { return VArray::ForSpan(Span((const T *)data, domain_num)); diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 68b7fba63c7..8444598d7d8 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -58,6 +58,7 @@ /* only for customdata_data_transfer_interp_normal_normals */ #include "data_transfer_intern.h" +using blender::float2; using blender::IndexRange; using blender::Set; using blender::Span; @@ -1011,110 +1012,9 @@ static void layerInterp_mloopcol(const void **sources, /** \} */ /* -------------------------------------------------------------------- */ -/** \name Callbacks for (#MLoopUV, #CD_MLOOPUV) +/** \name Callbacks for #OrigSpaceLoop * \{ */ -static void layerCopyValue_mloopuv(const void *source, - void *dest, - const int mixmode, - const float mixfactor) -{ - const MLoopUV *luv1 = static_cast(source); - MLoopUV *luv2 = static_cast(dest); - - /* We only support a limited subset of advanced mixing here - - * namely the mixfactor interpolation. */ - - if (mixmode == CDT_MIX_NOMIX) { - copy_v2_v2(luv2->uv, luv1->uv); - } - else { - interp_v2_v2v2(luv2->uv, luv2->uv, luv1->uv, mixfactor); - } -} - -static bool layerEqual_mloopuv(const void *data1, const void *data2) -{ - const MLoopUV *luv1 = static_cast(data1); - const MLoopUV *luv2 = static_cast(data2); - - return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f; -} - -static void layerMultiply_mloopuv(void *data, const float fac) -{ - MLoopUV *luv = static_cast(data); - - mul_v2_fl(luv->uv, fac); -} - -static void layerInitMinMax_mloopuv(void *vmin, void *vmax) -{ - MLoopUV *min = static_cast(vmin); - MLoopUV *max = static_cast(vmax); - - INIT_MINMAX2(min->uv, max->uv); -} - -static void layerDoMinMax_mloopuv(const void *data, void *vmin, void *vmax) -{ - const MLoopUV *luv = static_cast(data); - MLoopUV *min = static_cast(vmin); - MLoopUV *max = static_cast(vmax); - - minmax_v2v2_v2(min->uv, max->uv, luv->uv); -} - -static void layerAdd_mloopuv(void *data1, const void *data2) -{ - MLoopUV *l1 = static_cast(data1); - const MLoopUV *l2 = static_cast(data2); - - add_v2_v2(l1->uv, l2->uv); -} - -static void layerInterp_mloopuv(const void **sources, - const float *weights, - const float * /*sub_weights*/, - int count, - void *dest) -{ - float uv[2]; - int flag = 0; - - zero_v2(uv); - - for (int i = 0; i < count; i++) { - const float interp_weight = weights[i]; - const MLoopUV *src = static_cast(sources[i]); - madd_v2_v2fl(uv, src->uv, interp_weight); - if (interp_weight > 0.0f) { - flag |= src->flag; - } - } - - /* Delay writing to the destination in case dest is in sources. */ - copy_v2_v2(((MLoopUV *)dest)->uv, uv); - ((MLoopUV *)dest)->flag = flag; -} - -static bool layerValidate_mloopuv(void *data, const uint totitems, const bool do_fixes) -{ - MLoopUV *uv = static_cast(data); - bool has_errors = false; - - for (int i = 0; i < totitems; i++, uv++) { - if (!is_finite_v2(uv->uv)) { - if (do_fixes) { - zero_v2(uv->uv); - } - has_errors = true; - } - } - - return has_errors; -} - /* origspace is almost exact copy of mloopuv's, keep in sync */ static void layerCopyValue_mloop_origspace(const void *source, void *dest, @@ -1616,6 +1516,46 @@ static bool layerValidate_propfloat2(void *data, const uint totitems, const bool return has_errors; } +static bool layerEqual_propfloat2(const void *data1, const void *data2) +{ + const float2 &a = *static_cast(data1); + const float2 &b = *static_cast(data2); + return blender::math::distance_squared(a, b) < 0.00001f; +} + +static void layerInitMinMax_propfloat2(void *vmin, void *vmax) +{ + float2 &min = *static_cast(vmin); + float2 &max = *static_cast(vmax); + INIT_MINMAX2(min, max); +} + +static void layerDoMinMax_propfloat2(const void *data, void *vmin, void *vmax) +{ + const float2 &value = *static_cast(data); + float2 &a = *static_cast(vmin); + float2 &b = *static_cast(vmax); + blender::math::min_max(value, a, b); +} + +static void layerCopyValue_propfloat2(const void *source, + void *dest, + const int mixmode, + const float mixfactor) +{ + const float2 &a = *static_cast(source); + float2 &b = *static_cast(dest); + + /* We only support a limited subset of advanced mixing here- + * namely the mixfactor interpolation. */ + if (mixmode == CDT_MIX_NOMIX) { + b = a; + } + else { + b = blender::math::interpolate(b, a, mixfactor); + } +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -1757,28 +1697,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { /* NOTE: when we expose the UV Map / TexFace split to the user, * change this back to face Texture. */ {sizeof(int), "", 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}, - /* 16: CD_MLOOPUV */ - {sizeof(MLoopUV), - "MLoopUV", - 1, - N_("UVMap"), - nullptr, - nullptr, - layerInterp_mloopuv, - nullptr, - nullptr, - nullptr, - layerValidate_mloopuv, - layerEqual_mloopuv, - layerMultiply_mloopuv, - layerInitMinMax_mloopuv, - layerAdd_mloopuv, - layerDoMinMax_mloopuv, - layerCopyValue_mloopuv, - nullptr, - nullptr, - nullptr, - layerMaxNum_tface}, + /* 16: CD_MLOOPUV */ /* DEPRECATED */ + {sizeof(MLoopUV), "MLoopUV", 1, N_("UVMap")}, /* 17: CD_PROP_BYTE_COLOR */ {sizeof(MLoopCol), "MLoopCol", @@ -2025,10 +1945,12 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { nullptr, nullptr, layerValidate_propfloat2, - nullptr, + layerEqual_propfloat2, layerMultiply_propfloat2, - nullptr, - layerAdd_propfloat2}, + layerInitMinMax_propfloat2, + layerAdd_propfloat2, + layerDoMinMax_propfloat2, + layerCopyValue_propfloat2}, /* 50: CD_PROP_BOOL */ {sizeof(bool), "bool", @@ -2128,8 +2050,8 @@ const CustomData_MeshMasks CD_MASK_MESH = { /* pmask */ (CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL), /* lmask */ - (CD_MASK_MLOOP | CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL | - CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), + (CD_MASK_MLOOP | CD_MASK_MDISPS | 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 | @@ -2142,8 +2064,8 @@ const CustomData_MeshMasks CD_MASK_DERIVEDMESH = { /* pmask */ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL), /* lmask */ - (CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_PREVIEW_MLOOPCOL | - CD_MASK_ORIGSPACE_MLOOP | CD_MASK_PROP_ALL), /* XXX MISSING CD_MASK_MLOOPTANGENT ? */ + (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 | @@ -2153,8 +2075,7 @@ const CustomData_MeshMasks CD_MASK_BMESH = { /* pmask */ (CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL), /* lmask */ - (CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | - CD_MASK_PROP_ALL), + (CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), }; const CustomData_MeshMasks CD_MASK_EVERYTHING = { /* vmask */ (CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_MDEFORMVERT | @@ -2172,7 +2093,7 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = { (CD_MASK_MPOLY | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL), /* lmask */ - (CD_MASK_MLOOP | CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL | CD_MASK_MLOOPUV | + (CD_MASK_MLOOP | CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_MLOOPTANGENT | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), }; @@ -2399,7 +2320,7 @@ CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData CustomData dst = *src; dst.layers = static_cast( MEM_calloc_arrayN(dst_layers.size(), sizeof(CustomDataLayer), __func__)); - dst.totlayer = dst_layers.size(); + dst.maxlayer = dst.totlayer = dst_layers.size(); memcpy(dst.layers, dst_layers.data(), dst_layers.as_span().size_in_bytes()); CustomData_update_typemap(&dst); @@ -2586,6 +2507,17 @@ int CustomData_get_named_layer_index(const CustomData *data, const int type, con return -1; } +int CustomData_get_named_layer_index_notype(const CustomData *data, const char *name) +{ + for (int i = 0; i < data->totlayer; i++) { + if (STREQ(data->layers[i].name, name)) { + return i; + } + } + + return -1; +} + int CustomData_get_active_layer_index(const CustomData *data, const int type) { const int layer_index = data->typemap[type]; @@ -4234,6 +4166,9 @@ void CustomData_from_bmesh_block(const CustomData *source, /* copies a layer at a time */ int dest_i = 0; for (int src_i = 0; src_i < source->totlayer; src_i++) { + if (source->layers[src_i].flag & CD_FLAG_NOCOPY) { + continue; + } /* find the first dest layer with type >= the source type * (this should work because layers are ordered by type) @@ -4374,6 +4309,20 @@ static bool customdata_unique_check(void *arg, const char *name) return cd_layer_find_dupe(data_arg->data, name, data_arg->type, data_arg->index); } +int CustomData_name_max_length_calc(const blender::StringRef name) +{ + if (name.startswith(".")) { + return MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX; + } + for (const blender::StringRef prefix : + {"." UV_VERTSEL_NAME, UV_EDGESEL_NAME ".", UV_PINNED_NAME "."}) { + if (name.startswith(prefix)) { + return MAX_CUSTOMDATA_LAYER_NAME; + } + } + return MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX; +} + void CustomData_set_layer_unique_name(CustomData *data, const int index) { CustomDataLayer *nlayer = &data->layers[index]; @@ -4385,14 +4334,15 @@ void CustomData_set_layer_unique_name(CustomData *data, const int index) return; } + const int max_length = CustomData_name_max_length_calc(nlayer->name); + /* Set default name if none specified. Note we only call DATA_() when * needed to avoid overhead of locale lookups in the depsgraph. */ if (nlayer->name[0] == '\0') { STRNCPY(nlayer->name, DATA_(typeInfo->defaultname)); } - BLI_uniquename_cb( - customdata_unique_check, &data_arg, nullptr, '.', nlayer->name, sizeof(nlayer->name)); + BLI_uniquename_cb(customdata_unique_check, &data_arg, nullptr, '.', nlayer->name, max_length); } void CustomData_validate_layer_name(const CustomData *data, @@ -4477,8 +4427,9 @@ static bool CustomData_layer_ensure_data_exists(CustomDataLayer *layer, size_t c switch (layer->type) { /* When more instances of corrupt files are found, add them here. */ - case CD_PROP_BOOL: /* See T84935. */ - case CD_MLOOPUV: /* See T90620. */ + case CD_PROP_BOOL: /* See T84935. */ + case CD_MLOOPUV: /* See T90620. */ + case CD_PROP_FLOAT2: /* See T90620. */ layer->data = MEM_calloc_arrayN(count, typeInfo->size, layerType_getName(layer->type)); BLI_assert(layer->data); if (typeInfo->set_default_value) { diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index 6efe4fb38d9..39837051c0a 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -67,7 +67,7 @@ void BKE_object_data_transfer_dttypes_to_cdmask(const int dtdata_types, r_data_masks->vmask |= CD_MASK_MDEFORMVERT; /* Exception for vgroups :/ */ } else if (cddata_type == CD_FAKE_UV) { - r_data_masks->lmask |= CD_MASK_MLOOPUV; + r_data_masks->lmask |= CD_MASK_PROP_FLOAT2; } else if (cddata_type == CD_FAKE_LNOR) { r_data_masks->lmask |= CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL; @@ -989,7 +989,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, } else if (elem_type == ME_LOOP) { if (cddata_type == CD_FAKE_UV) { - cddata_type = CD_MLOOPUV; + cddata_type = CD_PROP_FLOAT2; } else if (cddata_type == CD_FAKE_LNOR) { /* Pre-process should have generated it, @@ -1028,7 +1028,7 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, } else if (elem_type == ME_POLY) { if (cddata_type == CD_FAKE_UV) { - cddata_type = CD_MLOOPUV; + cddata_type = CD_PROP_FLOAT2; } if (!(cddata_type & CD_FAKE)) { diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 9fbc95712c2..21614b53eae 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -1468,7 +1468,7 @@ typedef struct DynamicPaintSetInitColorData { const DynamicPaintSurface *surface; const MLoop *mloop; - const MLoopUV *mloopuv; + const float (*mloopuv)[2]; const MLoopTri *mlooptri; const MLoopCol *mloopcol; struct ImagePool *pool; @@ -1486,7 +1486,7 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb( const MLoop *mloop = data->mloop; const MLoopTri *mlooptri = data->mlooptri; - const MLoopUV *mloopuv = data->mloopuv; + const float(*mloopuv)[2] = data->mloopuv; struct ImagePool *pool = data->pool; Tex *tex = data->surface->init_texture; @@ -1499,8 +1499,8 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb( const uint vert = mloop[mlooptri[i].tri[j]].v; /* remap to [-1.0, 1.0] */ - uv[0] = mloopuv[mlooptri[i].tri[j]].uv[0] * 2.0f - 1.0f; - uv[1] = mloopuv[mlooptri[i].tri[j]].uv[1] * 2.0f - 1.0f; + uv[0] = mloopuv[mlooptri[i].tri[j]][0] * 2.0f - 1.0f; + uv[1] = mloopuv[mlooptri[i].tri[j]][1] * 2.0f - 1.0f; multitex_ext_safe(tex, uv, &texres, pool, scene_color_manage, false); @@ -1520,7 +1520,7 @@ static void dynamic_paint_set_init_color_tex_to_imseq_cb( PaintPoint *pPoint = (PaintPoint *)sData->type_data; const MLoopTri *mlooptri = data->mlooptri; - const MLoopUV *mloopuv = data->mloopuv; + const float(*mloopuv)[2] = data->mloopuv; Tex *tex = data->surface->init_texture; ImgSeqFormatData *f_data = (ImgSeqFormatData *)sData->format_data; const int samples = (data->surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1; @@ -1534,7 +1534,7 @@ static void dynamic_paint_set_init_color_tex_to_imseq_cb( /* collect all uvs */ for (int j = 3; j--;) { - copy_v2_v2(&uv[j * 3], mloopuv[mlooptri[f_data->uv_p[i].tri_index].tri[j]].uv); + copy_v2_v2(&uv[j * 3], mloopuv[mlooptri[f_data->uv_p[i].tri_index].tri[j]]); } /* interpolate final uv pos */ @@ -1615,8 +1615,9 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface } /* get uv map */ - CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, surface->init_layername, uvname); - const MLoopUV *mloopuv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname); + CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, surface->init_layername, uvname); + const float(*mloopuv)[2] = CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname); + if (!mloopuv) { return; } @@ -2178,7 +2179,7 @@ typedef struct DynamicPaintCreateUVSurfaceData { Vec3f *tempWeights; const MLoopTri *mlooptri; - const MLoopUV *mloopuv; + const float (*mloopuv)[2]; const MLoop *mloop; const int tottri; @@ -2196,7 +2197,7 @@ static void dynamic_paint_create_uv_surface_direct_cb( Vec3f *tempWeights = data->tempWeights; const MLoopTri *mlooptri = data->mlooptri; - const MLoopUV *mloopuv = data->mloopuv; + const float(*mloopuv)[2] = data->mloopuv; const MLoop *mloop = data->mloop; const int tottri = data->tottri; @@ -2249,9 +2250,9 @@ static void dynamic_paint_create_uv_surface_direct_cb( continue; } - const float *uv1 = mloopuv[mlooptri[i].tri[0]].uv; - const float *uv2 = mloopuv[mlooptri[i].tri[1]].uv; - const float *uv3 = mloopuv[mlooptri[i].tri[2]].uv; + const float *uv1 = mloopuv[mlooptri[i].tri[0]]; + const float *uv2 = mloopuv[mlooptri[i].tri[1]]; + const float *uv3 = mloopuv[mlooptri[i].tri[2]]; /* If point is inside the face */ if (isect_point_tri_v2(point[sample], uv1, uv2, uv3) != 0) { @@ -2291,7 +2292,7 @@ static void dynamic_paint_create_uv_surface_neighbor_cb( Vec3f *tempWeights = data->tempWeights; const MLoopTri *mlooptri = data->mlooptri; - const MLoopUV *mloopuv = data->mloopuv; + const float(*mloopuv)[2] = data->mloopuv; const MLoop *mloop = data->mloop; uint32_t *active_points = data->active_points; @@ -2332,9 +2333,9 @@ static void dynamic_paint_create_uv_surface_neighbor_cb( if (tempPoints[ind].neighbor_pixel == -1 && tempPoints[ind].tri_index != -1) { float uv[2]; const int i = tempPoints[ind].tri_index; - const float *uv1 = mloopuv[mlooptri[i].tri[0]].uv; - const float *uv2 = mloopuv[mlooptri[i].tri[1]].uv; - const float *uv3 = mloopuv[mlooptri[i].tri[2]].uv; + const float *uv1 = mloopuv[mlooptri[i].tri[0]]; + const float *uv2 = mloopuv[mlooptri[i].tri[1]]; + const float *uv3 = mloopuv[mlooptri[i].tri[2]]; /* tri index */ /* There is a low possibility of actually having a neighbor point which tri is @@ -2378,7 +2379,7 @@ static void dynamic_paint_create_uv_surface_neighbor_cb( #undef JITTER_SAMPLES static float dist_squared_to_looptri_uv_edges(const MLoopTri *mlooptri, - const MLoopUV *mloopuv, + const float (*mloopuv)[2], int tri_index, const float point[2]) { @@ -2389,8 +2390,8 @@ static float dist_squared_to_looptri_uv_edges(const MLoopTri *mlooptri, for (int i = 0; i < 3; i++) { const float dist_squared = dist_squared_to_line_segment_v2( point, - mloopuv[mlooptri[tri_index].tri[(i + 0)]].uv, - mloopuv[mlooptri[tri_index].tri[(i + 1) % 3]].uv); + mloopuv[mlooptri[tri_index].tri[(i + 0)]], + mloopuv[mlooptri[tri_index].tri[(i + 1) % 3]]); if (dist_squared < min_distance) { min_distance = dist_squared; @@ -2503,7 +2504,7 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa { const MLoop *mloop = data->mloop; const MLoopTri *mlooptri = data->mlooptri; - const MLoopUV *mloopuv = data->mloopuv; + const float(*mloopuv)[2] = data->mloopuv; const uint *loop_idx = mlooptri[tri_index].tri; @@ -2516,9 +2517,9 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa float uv0[2], uv1[2], uv2[2]; - copy_v2_v2(uv0, mloopuv[loop_idx[(edge_idx + 0)]].uv); - copy_v2_v2(uv1, mloopuv[loop_idx[(edge_idx + 1) % 3]].uv); - copy_v2_v2(uv2, mloopuv[loop_idx[(edge_idx + 2) % 3]].uv); + copy_v2_v2(uv0, mloopuv[loop_idx[(edge_idx + 0)]]); + copy_v2_v2(uv1, mloopuv[loop_idx[(edge_idx + 1) % 3]]); + copy_v2_v2(uv2, mloopuv[loop_idx[(edge_idx + 2) % 3]]); /* Verify the target point is on the opposite side of the edge from the third triangle * vertex, to ensure that we always move closer to the goal point. */ @@ -2569,13 +2570,13 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa /* Allow for swapped vertex order */ if (overt0 == vert0 && overt1 == vert1) { found_other = true; - copy_v2_v2(ouv0, mloopuv[other_loop_idx[(j + 0)]].uv); - copy_v2_v2(ouv1, mloopuv[other_loop_idx[(j + 1) % 3]].uv); + copy_v2_v2(ouv0, mloopuv[other_loop_idx[(j + 0)]]); + copy_v2_v2(ouv1, mloopuv[other_loop_idx[(j + 1) % 3]]); } else if (overt0 == vert1 && overt1 == vert0) { found_other = true; - copy_v2_v2(ouv1, mloopuv[other_loop_idx[(j + 0)]].uv); - copy_v2_v2(ouv0, mloopuv[other_loop_idx[(j + 1) % 3]].uv); + copy_v2_v2(ouv1, mloopuv[other_loop_idx[(j + 0)]]); + copy_v2_v2(ouv0, mloopuv[other_loop_idx[(j + 1) % 3]]); } if (found_other) { @@ -2798,7 +2799,7 @@ int dynamicPaint_createUVSurface(Scene *scene, PaintUVPoint *tempPoints = NULL; Vec3f *tempWeights = NULL; const MLoopTri *mlooptri = NULL; - const MLoopUV *mloopuv = NULL; + const float(*mloopuv)[2] = NULL; const MLoop *mloop = NULL; Bounds2D *faceBB = NULL; @@ -2819,9 +2820,9 @@ int dynamicPaint_createUVSurface(Scene *scene, const int tottri = BKE_mesh_runtime_looptri_len(mesh); /* get uv map */ - if (CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) { - CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, surface->uvlayer_name, uvname); - mloopuv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname); + if (CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) { + CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, surface->uvlayer_name, uvname); + mloopuv = CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname); } /* Check for validity */ @@ -2880,11 +2881,11 @@ int dynamicPaint_createUVSurface(Scene *scene, if (!error) { for (int i = 0; i < tottri; i++) { - copy_v2_v2(faceBB[i].min, mloopuv[mlooptri[i].tri[0]].uv); - copy_v2_v2(faceBB[i].max, mloopuv[mlooptri[i].tri[0]].uv); + copy_v2_v2(faceBB[i].min, mloopuv[mlooptri[i].tri[0]]); + copy_v2_v2(faceBB[i].max, mloopuv[mlooptri[i].tri[0]]); for (int j = 1; j < 3; j++) { - minmax_v2v2_v2(faceBB[i].min, faceBB[i].max, mloopuv[mlooptri[i].tri[j]].uv); + minmax_v2v2_v2(faceBB[i].min, faceBB[i].max, mloopuv[mlooptri[i].tri[j]]); } } diff --git a/source/blender/blenkernel/intern/editmesh_tangent.cc b/source/blender/blenkernel/intern/editmesh_tangent.cc index 12799afd2f7..6af839585f7 100644 --- a/source/blender/blenkernel/intern/editmesh_tangent.cc +++ b/source/blender/blenkernel/intern/editmesh_tangent.cc @@ -151,7 +151,7 @@ static void emDM_calc_loop_tangents_thread(TaskPool *__restrict /*pool*/, void * void BKE_editmesh_loop_tangent_calc(BMEditMesh *em, bool calc_active_tangent, - const char (*tangent_names)[MAX_NAME], + const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len, const float (*poly_normals)[3], const float (*loop_normals)[3], @@ -254,7 +254,7 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em, /* NOTE: we assume we do have tessellated loop normals at this point * (in case it is object-enabled), have to check this is valid. */ mesh2tangent->precomputedLoopNormals = loop_normals; - mesh2tangent->cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, n); + mesh2tangent->cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, n); /* needed for indexing loop-tangents */ int htype_index = BM_LOOP; @@ -270,8 +270,8 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em, else { /* Fill the resulting tangent_mask */ int uv_ind = CustomData_get_named_layer_index( - &bm->ldata, CD_MLOOPUV, loopdata_out->layers[index].name); - int uv_start = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV); + &bm->ldata, CD_PROP_FLOAT2, loopdata_out->layers[index].name); + int uv_start = CustomData_get_layer_index(&bm->ldata, CD_PROP_FLOAT2); BLI_assert(uv_ind != -1 && uv_start != -1); BLI_assert(uv_ind - uv_start < MAX_MTFACE); tangent_mask_curr |= 1 << (uv_ind - uv_start); @@ -306,7 +306,7 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em, *tangent_mask_curr_p = tangent_mask_curr; - int act_uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, act_uv_n); + int act_uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_PROP_FLOAT2, act_uv_n); if (act_uv_index >= 0) { int tan_index = CustomData_get_named_layer_index( loopdata_out, CD_TANGENT, bm->ldata.layers[act_uv_index].name); @@ -314,7 +314,7 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em, } /* else tangent has been built from orco */ /* Update render layer index */ - int ren_uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, ren_uv_n); + int ren_uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_PROP_FLOAT2, ren_uv_n); if (ren_uv_index >= 0) { int tan_index = CustomData_get_named_layer_index( loopdata_out, CD_TANGENT, bm->ldata.layers[ren_uv_index].name); diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c index bd8acfe626f..b95d82e83d8 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.c @@ -1789,7 +1789,7 @@ static void sample_mesh(FluidFlowSettings *ffs, const float (*vert_normals)[3], const MLoop *mloop, const MLoopTri *mlooptri, - const MLoopUV *mloopuv, + const float (*mloopuv)[2], float *influence_map, float *velocity_map, int index, @@ -1909,9 +1909,9 @@ static void sample_mesh(FluidFlowSettings *ffs, } else if (mloopuv) { const float *uv[3]; - uv[0] = mloopuv[mlooptri[f_index].tri[0]].uv; - uv[1] = mloopuv[mlooptri[f_index].tri[1]].uv; - uv[2] = mloopuv[mlooptri[f_index].tri[2]].uv; + uv[0] = mloopuv[mlooptri[f_index].tri[0]]; + uv[1] = mloopuv[mlooptri[f_index].tri[1]]; + uv[2] = mloopuv[mlooptri[f_index].tri[2]]; interp_v2_v2v2v2(tex_co, UNPACK3(uv), weights); @@ -1984,7 +1984,7 @@ typedef struct EmitFromDMData { const float (*vert_normals)[3]; const MLoop *mloop; const MLoopTri *mlooptri; - const MLoopUV *mloopuv; + const float (*mloopuv)[2]; const MDeformVert *dvert; int defgrp_index; @@ -2070,7 +2070,8 @@ static void emit_from_mesh( const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me); const int numverts = me->totvert; const MDeformVert *dvert = BKE_mesh_deform_verts(me); - const MLoopUV *mloopuv = CustomData_get_layer_named(&me->ldata, CD_MLOOPUV, ffs->uvlayer_name); + const float(*mloopuv)[2] = CustomData_get_layer_named( + &me->ldata, CD_PROP_FLOAT2, ffs->uvlayer_name); if (ffs->flags & FLUID_FLOW_INITVELOCITY) { vert_vel = MEM_callocN(sizeof(float[3]) * numverts, "manta_flow_velocity"); diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 186ac90c2c7..c91dc249249 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -922,16 +922,6 @@ static void set_shade_smooth(MPoly &mpoly, bool value) SET_FLAG_FROM_TEST(mpoly.flag, value, ME_SMOOTH); } -static float2 get_loop_uv(const MLoopUV &uv) -{ - return float2(uv.uv); -} - -static void set_loop_uv(MLoopUV &uv, float2 co) -{ - copy_v2_v2(uv.uv, co); -} - static float get_crease(const float &crease) { return crease; @@ -1299,14 +1289,6 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() make_derived_write_attribute, nullptr); - static NamedLegacyCustomDataProvider uvs( - ATTR_DOMAIN_CORNER, - CD_PROP_FLOAT2, - CD_MLOOPUV, - corner_access, - make_derived_read_attribute, - make_derived_write_attribute); - static VertexGroupsAttributeProvider vertex_groups; static CustomDataAttributeProvider corner_custom_data(ATTR_DOMAIN_CORNER, corner_access); static CustomDataAttributeProvider point_custom_data(ATTR_DOMAIN_POINT, point_access); @@ -1315,8 +1297,7 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() return ComponentAttributeProviders( {&position, &id, &material_index, &shade_smooth, &normal, &crease}, - {&uvs, - &corner_custom_data, + {&corner_custom_data, &vertex_groups, &point_custom_data, &edge_custom_data, diff --git a/source/blender/blenkernel/intern/layer_utils.c b/source/blender/blenkernel/intern/layer_utils.c index 23067d1a4e3..11bd82601f8 100644 --- a/source/blender/blenkernel/intern/layer_utils.c +++ b/source/blender/blenkernel/intern/layer_utils.c @@ -248,7 +248,7 @@ bool BKE_view_layer_filter_edit_mesh_has_uvs(const Object *ob, void *UNUSED(user const Mesh *me = ob->data; const BMEditMesh *em = me->edit_mesh; if (em != NULL) { - if (CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV) != -1) { + if (CustomData_has_layer(&em->bm->ldata, CD_PROP_FLOAT2)) { return true; } } diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index b35f5d6aa83..d2e61d37e44 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -288,6 +288,10 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address CustomData_blend_write_prepare(mesh->edata, edge_layers, names_to_skip); CustomData_blend_write_prepare(mesh->ldata, loop_layers, names_to_skip); CustomData_blend_write_prepare(mesh->pdata, poly_layers, names_to_skip); + + if (!BLO_write_is_undo(writer)) { + BKE_mesh_legacy_convert_uvs_to_struct(mesh, temp_arrays_for_legacy_format, loop_layers); + } } mesh->runtime = nullptr; @@ -479,35 +483,71 @@ static const char *cmpcode_to_str(int code) } } +static bool is_sublayer_name(char const *sublayer_name, char const *name) +{ + BLI_assert(strlen(sublayer_name) == 2); + if (name[1] != sublayer_name[0]) { + return false; + } + if (name[2] != sublayer_name[1]) { + return false; + } + if (name[3] != '.') { + return false; + } + return true; +} + +static bool is_uv_bool_sublayer(CustomDataLayer const *l) +{ + char const *name = l->name; + + if (name[0] != '.') { + return false; + } + + return is_sublayer_name(UV_VERTSEL_NAME, name) || is_sublayer_name(UV_EDGESEL_NAME, name) || + is_sublayer_name(UV_PINNED_NAME, name); +} + /** Thresh is threshold for comparing vertices, UV's, vertex colors, weights, etc. */ static int customdata_compare( CustomData *c1, CustomData *c2, const int total_length, Mesh *m1, Mesh *m2, const float thresh) { - const float thresh_sq = thresh * thresh; CustomDataLayer *l1, *l2; int layer_count1 = 0, layer_count2 = 0, j; - const uint64_t cd_mask_non_generic = CD_MASK_MEDGE | CD_MASK_MPOLY | CD_MASK_MLOOPUV | - CD_MASK_PROP_BYTE_COLOR | CD_MASK_MDEFORMVERT; + const uint64_t cd_mask_non_generic = CD_MASK_MEDGE | CD_MASK_MPOLY | CD_MASK_PROP_BYTE_COLOR | + CD_MASK_MDEFORMVERT; const uint64_t cd_mask_all_attr = CD_MASK_PROP_ALL | cd_mask_non_generic; const Span loops_1 = m1->loops(); const Span loops_2 = m2->loops(); + /* The uv selection / pin layers are ignored in the comparisons because + * the original flags they replace were ignored as well. Because of the + * lazy creation of these layers it would need careful handling of the + * test files to compare these layers. For now it has been decided to + * skip them. + */ + for (int i = 0; i < c1->totlayer; i++) { l1 = &c1->layers[i]; - if ((CD_TYPE_AS_MASK(l1->type) & cd_mask_all_attr) && l1->anonymous_id == nullptr) { + if ((CD_TYPE_AS_MASK(l1->type) & cd_mask_all_attr) && l1->anonymous_id == nullptr && + !is_uv_bool_sublayer(l1)) { layer_count1++; } } for (int i = 0; i < c2->totlayer; i++) { l2 = &c2->layers[i]; - if ((CD_TYPE_AS_MASK(l2->type) & cd_mask_all_attr) && l2->anonymous_id == nullptr) { + if ((CD_TYPE_AS_MASK(l2->type) & cd_mask_all_attr) && l2->anonymous_id == nullptr && + !is_uv_bool_sublayer(l2)) { layer_count2++; } } if (layer_count1 != layer_count2) { - /* TODO(@HooglyBoogly): Re-enable after tests are updated for material index refactor. */ + /* TODO(@HooglyBoogly): Re-enable after tests are updated for material index refactor and UV as + * generic attribute refactor. */ // return MESHCMP_CDLAYERS_MISMATCH; } @@ -516,7 +556,7 @@ static int customdata_compare( for (int i1 = 0; i1 < c1->totlayer; i1++) { l1 = c1->layers + i1; - if (l1->anonymous_id != nullptr) { + if (l1->anonymous_id != nullptr || is_uv_bool_sublayer(l1)) { continue; } bool found_corresponding_layer = false; @@ -584,18 +624,6 @@ static int customdata_compare( } break; } - case CD_MLOOPUV: { - MLoopUV *lp1 = (MLoopUV *)l1->data; - MLoopUV *lp2 = (MLoopUV *)l2->data; - int ltot = m1->totloop; - - for (j = 0; j < ltot; j++, lp1++, lp2++) { - if (len_squared_v2v2(lp1->uv, lp2->uv) > thresh_sq) { - return MESHCMP_LOOPUVMISMATCH; - } - } - break; - } case CD_PROP_BYTE_COLOR: { MLoopCol *lp1 = (MLoopCol *)l1->data; MLoopCol *lp2 = (MLoopCol *)l2->data; diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index b6ccb0ea52d..4f74f070e81 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -198,8 +198,8 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba MutableAttributeAccessor attributes = mesh->attributes_for_write(); SpanAttributeWriter material_indices = attributes.lookup_or_add_for_write_only_span( "material_index", ATTR_DOMAIN_FACE); - MLoopUV *mloopuv = static_cast(CustomData_add_layer_named( - &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, DATA_("UVMap"))); + blender::float2 *mloopuv = static_cast(CustomData_add_layer_named( + &mesh->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, mesh->totloop, DATA_("UVMap"))); int dst_vert = 0; int dst_edge = 0; @@ -278,8 +278,8 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba if (mloopuv) { for (int i = 0; i < 3; i++, mloopuv++) { - mloopuv->uv[0] = (loops[dst_loop + i].v - startvert) / float(dl->nr - 1); - mloopuv->uv[1] = 0.0f; + (*mloopuv)[0] = (loops[dst_loop + i].v - startvert) / float(dl->nr - 1); + (*mloopuv)[1] = 0.0f; } } @@ -355,15 +355,15 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba /* find uv based on vertex index into grid array */ int v = loops[dst_loop + i].v - startvert; - mloopuv->uv[0] = (v / dl->nr) / float(orco_sizev); - mloopuv->uv[1] = (v % dl->nr) / float(orco_sizeu); + (*mloopuv)[0] = (v / dl->nr) / float(orco_sizev); + (*mloopuv)[1] = (v % dl->nr) / float(orco_sizeu); /* cyclic correction */ - if (ELEM(i, 1, 2) && mloopuv->uv[0] == 0.0f) { - mloopuv->uv[0] = 1.0f; + if ((ELEM(i, 1, 2)) && (*mloopuv)[0] == 0.0f) { + (*mloopuv)[0] = 1.0f; } - if (ELEM(i, 0, 1) && mloopuv->uv[1] == 0.0f) { - mloopuv->uv[1] = 1.0f; + if ((ELEM(i, 0, 1)) && (*mloopuv)[1] == 0.0f) { + (*mloopuv)[1] = 1.0f; } } } diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc index c0b461e524e..629d9e89ed6 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.cc +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -114,24 +114,6 @@ float BKE_mesh_calc_area(const Mesh *me) return total_area; } -float BKE_mesh_calc_poly_uv_area(const MPoly *mpoly, const MLoopUV *uv_array) -{ - - int i, l_iter = mpoly->loopstart; - float area; - float(*vertexcos)[2] = (float(*)[2])BLI_array_alloca(vertexcos, size_t(mpoly->totloop)); - - /* pack vertex cos into an array for area_poly_v2 */ - for (i = 0; i < mpoly->totloop; i++, l_iter++) { - copy_v2_v2(vertexcos[i], uv_array[l_iter].uv); - } - - /* finally calculate the area */ - area = area_poly_v2(vertexcos, uint(mpoly->totloop)); - - return area; -} - static float UNUSED_FUNCTION(mesh_calc_poly_volume_centroid)(const MPoly *mpoly, const MLoop *loopstart, const float (*positions)[3], diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 2d7cc73208a..9fd9214f8af 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -302,17 +302,18 @@ static void bm_corners_to_loops_ex(ID *id, for (int i = 0; i < numTex; i++) { const MTFace *texface = (const MTFace *)CustomData_get_n(fdata, CD_MTFACE, findex, i); - MLoopUV *mloopuv = (MLoopUV *)CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i); - copy_v2_v2(mloopuv->uv, texface->uv[0]); - mloopuv++; - copy_v2_v2(mloopuv->uv, texface->uv[1]); - mloopuv++; - copy_v2_v2(mloopuv->uv, texface->uv[2]); - mloopuv++; + blender::float2 *uv = static_cast( + CustomData_get_n(ldata, CD_PROP_FLOAT2, loopstart, i)); + copy_v2_v2(*uv, texface->uv[0]); + uv++; + copy_v2_v2(*uv, texface->uv[1]); + uv++; + copy_v2_v2(*uv, texface->uv[2]); + uv++; if (mf->v4) { - copy_v2_v2(mloopuv->uv, texface->uv[3]); - mloopuv++; + copy_v2_v2(*uv, texface->uv[3]); + uv++; } } @@ -394,7 +395,7 @@ static void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *ldata, int to for (int i = 0; i < fdata->totlayer; i++) { if (fdata->layers[i].type == CD_MTFACE) { CustomData_add_layer_named( - ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, totloop, fdata->layers[i].name); + ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, totloop, fdata->layers[i].name); } else if (fdata->layers[i].type == CD_MCOL) { CustomData_add_layer_named( @@ -537,17 +538,17 @@ static void update_active_fdata_layers(Mesh &mesh, CustomData *fdata, CustomData { int act; - if (CustomData_has_layer(ldata, CD_MLOOPUV)) { - act = CustomData_get_active_layer(ldata, CD_MLOOPUV); + if (CustomData_has_layer(ldata, CD_PROP_FLOAT2)) { + act = CustomData_get_active_layer(ldata, CD_PROP_FLOAT2); CustomData_set_layer_active(fdata, CD_MTFACE, act); - act = CustomData_get_render_layer(ldata, CD_MLOOPUV); + act = CustomData_get_render_layer(ldata, CD_PROP_FLOAT2); CustomData_set_layer_render(fdata, CD_MTFACE, act); - act = CustomData_get_clone_layer(ldata, CD_MLOOPUV); + act = CustomData_get_clone_layer(ldata, CD_PROP_FLOAT2); CustomData_set_layer_clone(fdata, CD_MTFACE, act); - act = CustomData_get_stencil_layer(ldata, CD_MLOOPUV); + act = CustomData_get_stencil_layer(ldata, CD_PROP_FLOAT2); CustomData_set_layer_stencil(fdata, CD_MTFACE, act); } @@ -584,7 +585,7 @@ static bool check_matching_legacy_layer_counts(CustomData *fdata, CustomData *ld ((a_num += CustomData_number_of_layers(l_a, t_a)) == \ (b_num += CustomData_number_of_layers(l_b, t_b))) - if (!LAYER_CMP(ldata, CD_MLOOPUV, fdata, CD_MTFACE)) { + if (!LAYER_CMP(ldata, CD_PROP_FLOAT2, fdata, CD_MTFACE)) { return false; } if (!LAYER_CMP(ldata, CD_PROP_BYTE_COLOR, fdata, CD_MCOL)) { @@ -617,7 +618,7 @@ static void add_mface_layers(Mesh &mesh, CustomData *fdata, CustomData *ldata, i BLI_assert(!check_matching_legacy_layer_counts(fdata, ldata, false)); for (int i = 0; i < ldata->totlayer; i++) { - if (ldata->layers[i].type == CD_MLOOPUV) { + if (ldata->layers[i].type == CD_PROP_FLOAT2) { CustomData_add_layer_named( fdata, CD_MTFACE, CD_SET_DEFAULT, nullptr, total, ldata->layers[i].name); } @@ -655,7 +656,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me) * Callers could also check but safer to do here - campbell */ } else { - const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); + const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); 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); @@ -674,7 +675,7 @@ 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 != " + "had to reset!\n CD_MTFACE: %d != CD_PROP_FLOAT2: %d || CD_MCOL: %d != " "CD_PROP_BYTE_COLOR: " "%d\n", __func__, @@ -717,16 +718,16 @@ static void CustomData_bmesh_do_versions_update_active_layers(CustomData *fdata, if (CustomData_has_layer(fdata, CD_MTFACE)) { act = CustomData_get_active_layer(fdata, CD_MTFACE); - CustomData_set_layer_active(ldata, CD_MLOOPUV, act); + CustomData_set_layer_active(ldata, CD_PROP_FLOAT2, act); act = CustomData_get_render_layer(fdata, CD_MTFACE); - CustomData_set_layer_render(ldata, CD_MLOOPUV, act); + CustomData_set_layer_render(ldata, CD_PROP_FLOAT2, act); act = CustomData_get_clone_layer(fdata, CD_MTFACE); - CustomData_set_layer_clone(ldata, CD_MLOOPUV, act); + CustomData_set_layer_clone(ldata, CD_PROP_FLOAT2, act); act = CustomData_get_stencil_layer(fdata, CD_MTFACE); - CustomData_set_layer_stencil(ldata, CD_MLOOPUV, act); + CustomData_set_layer_stencil(ldata, CD_PROP_FLOAT2, act); } if (CustomData_has_layer(fdata, CD_MCOL)) { @@ -792,7 +793,7 @@ static void mesh_loops_to_tessdata(CustomData *fdata, * we could be ~25% quicker with dedicated code. * 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 numUV = CustomData_number_of_layers(ldata, CD_PROP_FLOAT2); 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); @@ -804,12 +805,13 @@ static void mesh_loops_to_tessdata(CustomData *fdata, for (i = 0; i < numUV; i++) { MTFace *texface = (MTFace *)CustomData_get_layer_n(fdata, CD_MTFACE, i); - const MLoopUV *mloopuv = (const MLoopUV *)CustomData_get_layer_n(ldata, CD_MLOOPUV, i); + const blender::float2 *uv = static_cast( + CustomData_get_layer_n(ldata, CD_PROP_FLOAT2, i)); for (findex = 0, pidx = polyindices, lidx = loopindices; findex < num_faces; pidx++, lidx++, findex++, texface++) { for (j = (mface ? mface[findex].v4 : (*lidx)[3]) ? 4 : 3; j--;) { - copy_v2_v2(texface->uv[j], mloopuv[(*lidx)[j]].uv); + copy_v2_v2(texface->uv[j], uv[(*lidx)[j]]); } } } @@ -1469,6 +1471,179 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh) /** \} */ /* -------------------------------------------------------------------- */ +/** \name Generic UV Map Conversion + * \{ */ + +void BKE_mesh_legacy_convert_uvs_to_struct( + Mesh *mesh, + blender::ResourceScope &temp_mloopuv_for_convert, + blender::Vector &face_corner_layers_to_write) +{ + using namespace blender; + using namespace blender::bke; + const AttributeAccessor attributes = mesh->attributes(); + Vector new_layer_to_write; + + /* Don't write the boolean UV map sublayers which will be written in the legacy #MLoopUV type. */ + Set uv_sublayers_to_skip; + char vert_name[MAX_CUSTOMDATA_LAYER_NAME]; + char edge_name[MAX_CUSTOMDATA_LAYER_NAME]; + char pin_name[MAX_CUSTOMDATA_LAYER_NAME]; + for (const CustomDataLayer &layer : face_corner_layers_to_write) { + uv_sublayers_to_skip.add_multiple_new({BKE_uv_map_vert_select_name_get(layer.name, vert_name), + BKE_uv_map_edge_select_name_get(layer.name, edge_name), + BKE_uv_map_pin_name_get(layer.name, pin_name)}); + } + + for (const CustomDataLayer &layer : face_corner_layers_to_write) { + if (uv_sublayers_to_skip.contains_as(layer.name)) { + continue; + } + if (layer.type != CD_PROP_FLOAT2) { + new_layer_to_write.append(layer); + continue; + } + const Span coords{static_cast(layer.data), mesh->totloop}; + CustomDataLayer mloopuv_layer = layer; + mloopuv_layer.type = CD_MLOOPUV; + MutableSpan mloopuv = temp_mloopuv_for_convert.construct>( + mesh->totloop); + mloopuv_layer.data = mloopuv.data(); + + char buffer[MAX_CUSTOMDATA_LAYER_NAME]; + const VArray vert_selection = attributes.lookup_or_default( + BKE_uv_map_vert_select_name_get(layer.name, buffer), ATTR_DOMAIN_CORNER, false); + const VArray edge_selection = attributes.lookup_or_default( + BKE_uv_map_edge_select_name_get(layer.name, buffer), ATTR_DOMAIN_CORNER, false); + const VArray pin = attributes.lookup_or_default( + BKE_uv_map_pin_name_get(layer.name, buffer), ATTR_DOMAIN_CORNER, false); + + threading::parallel_for(mloopuv.index_range(), 2048, [&](IndexRange range) { + for (const int i : range) { + copy_v2_v2(mloopuv[i].uv, coords[i]); + SET_FLAG_FROM_TEST(mloopuv[i].flag, vert_selection[i], MLOOPUV_VERTSEL); + SET_FLAG_FROM_TEST(mloopuv[i].flag, edge_selection[i], MLOOPUV_EDGESEL); + SET_FLAG_FROM_TEST(mloopuv[i].flag, pin[i], MLOOPUV_PINNED); + } + }); + new_layer_to_write.append(mloopuv_layer); + } + + face_corner_layers_to_write = new_layer_to_write; + mesh->ldata.totlayer = new_layer_to_write.size(); + mesh->ldata.maxlayer = mesh->ldata.totlayer; +} + +void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh) +{ + using namespace blender; + using namespace blender::bke; + + /* Store layer names since they will be removed, used to set the active status of new layers. + * Use intermediate #StringRef because the names can be null. */ + const std::string active_uv = StringRef( + CustomData_get_active_layer_name(&mesh->ldata, CD_MLOOPUV)); + const std::string default_uv = StringRef( + CustomData_get_render_layer_name(&mesh->ldata, CD_MLOOPUV)); + + Set uv_layers_to_convert; + for (const int uv_layer_i : IndexRange(CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV))) { + uv_layers_to_convert.add_as(CustomData_get_layer_name(&mesh->ldata, CD_MLOOPUV, uv_layer_i)); + } + + for (const StringRefNull name : uv_layers_to_convert) { + const MLoopUV *mloopuv = static_cast( + CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, name.c_str())); + const uint32_t needed_boolean_attributes = threading::parallel_reduce( + IndexRange(mesh->totloop), + 4096, + 0, + [&](const IndexRange range, uint32_t init) { + for (const int i : range) { + init |= mloopuv[i].flag; + } + return init; + }, + [](const uint32_t a, const uint32_t b) { return a | b; }); + + float2 *coords = static_cast( + MEM_malloc_arrayN(mesh->totloop, sizeof(float2), __func__)); + bool *vert_selection = nullptr; + bool *edge_selection = nullptr; + bool *pin = nullptr; + if (needed_boolean_attributes & MLOOPUV_VERTSEL) { + vert_selection = static_cast( + MEM_malloc_arrayN(mesh->totloop, sizeof(bool), __func__)); + } + if (needed_boolean_attributes & MLOOPUV_EDGESEL) { + edge_selection = static_cast( + MEM_malloc_arrayN(mesh->totloop, sizeof(bool), __func__)); + } + if (needed_boolean_attributes & MLOOPUV_PINNED) { + pin = static_cast(MEM_malloc_arrayN(mesh->totloop, sizeof(bool), __func__)); + } + + threading::parallel_for(IndexRange(mesh->totloop), 4096, [&](IndexRange range) { + for (const int i : range) { + coords[i] = mloopuv[i].uv; + } + if (vert_selection) { + for (const int i : range) { + vert_selection[i] = mloopuv[i].flag & MLOOPUV_VERTSEL; + } + } + if (edge_selection) { + for (const int i : range) { + edge_selection[i] = mloopuv[i].flag & MLOOPUV_EDGESEL; + } + } + if (pin) { + for (const int i : range) { + pin[i] = mloopuv[i].flag & MLOOPUV_PINNED; + } + } + }); + + CustomData_free_layer_named(&mesh->ldata, name.c_str(), mesh->totloop); + CustomData_add_layer_named( + &mesh->ldata, CD_PROP_FLOAT2, CD_ASSIGN, coords, mesh->totloop, name.c_str()); + char buffer[MAX_CUSTOMDATA_LAYER_NAME]; + if (vert_selection) { + CustomData_add_layer_named(&mesh->ldata, + CD_PROP_BOOL, + CD_ASSIGN, + vert_selection, + mesh->totloop, + BKE_uv_map_vert_select_name_get(name.c_str(), buffer)); + } + if (edge_selection) { + CustomData_add_layer_named(&mesh->ldata, + CD_PROP_BOOL, + CD_ASSIGN, + edge_selection, + mesh->totloop, + BKE_uv_map_edge_select_name_get(name.c_str(), buffer)); + } + if (pin) { + CustomData_add_layer_named(&mesh->ldata, + CD_PROP_BOOL, + CD_ASSIGN, + pin, + mesh->totloop, + BKE_uv_map_pin_name_get(name.c_str(), buffer)); + } + } + + CustomData_set_layer_active_index( + &mesh->ldata, + CD_PROP_FLOAT2, + CustomData_get_named_layer_index(&mesh->ldata, CD_PROP_FLOAT2, active_uv.c_str())); + CustomData_set_layer_render_index( + &mesh->ldata, + CD_PROP_FLOAT2, + CustomData_get_named_layer_index(&mesh->ldata, CD_PROP_FLOAT2, default_uv.c_str())); +} + /** \name Selection Attribute and Legacy Flag Conversion * \{ */ diff --git a/source/blender/blenkernel/intern/mesh_mapping.cc b/source/blender/blenkernel/intern/mesh_mapping.cc index 0503e51da06..9028f6d51b3 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.cc +++ b/source/blender/blenkernel/intern/mesh_mapping.cc @@ -34,7 +34,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly, const bool *hide_poly, const bool *select_poly, const MLoop *mloop, - const MLoopUV *mloopuv, + const float (*mloopuv)[2], uint totpoly, uint totvert, const float limit[2], @@ -95,7 +95,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly, vmap->vert[mloop[mp->loopstart + i].v] = buf; if (use_winding) { - copy_v2_v2(tf_uv[i], mloopuv[mpoly[a].loopstart + i].uv); + copy_v2_v2(tf_uv[i], mloopuv[mpoly[a].loopstart + i]); } buf++; @@ -120,14 +120,14 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly, v->next = newvlist; newvlist = v; - uv = mloopuv[mpoly[v->poly_index].loopstart + v->loop_of_poly_index].uv; + uv = mloopuv[mpoly[v->poly_index].loopstart + v->loop_of_poly_index]; lastv = nullptr; iterv = vlist; while (iterv) { next = iterv->next; - uv2 = mloopuv[mpoly[iterv->poly_index].loopstart + iterv->loop_of_poly_index].uv; + uv2 = mloopuv[mpoly[iterv->poly_index].loopstart + iterv->loop_of_poly_index]; sub_v2_v2v2(uvdiff, uv2, uv); if (fabsf(uv[0] - uv2[0]) < limit[0] && fabsf(uv[1] - uv2[1]) < limit[1] && @@ -1004,7 +1004,7 @@ void BKE_mesh_loop_islands_add(MeshIslandStore *island_store, */ struct MeshCheckIslandBoundaryUv { const MLoop *loops; - const MLoopUV *luvs; + const float (*luvs)[2]; const MeshElemMap *edge_loop_map; }; @@ -1020,27 +1020,27 @@ static bool mesh_check_island_boundary_uv(const MPoly * /*mp*/, const MeshCheckIslandBoundaryUv *data = static_cast( user_data); const MLoop *loops = data->loops; - const MLoopUV *luvs = data->luvs; + const float(*luvs)[2] = data->luvs; const MeshElemMap *edge_to_loops = &data->edge_loop_map[ml->e]; BLI_assert(edge_to_loops->count >= 2 && (edge_to_loops->count % 2) == 0); const uint v1 = loops[edge_to_loops->indices[0]].v; const uint v2 = loops[edge_to_loops->indices[1]].v; - const float *uvco_v1 = luvs[edge_to_loops->indices[0]].uv; - const float *uvco_v2 = luvs[edge_to_loops->indices[1]].uv; + const float *uvco_v1 = luvs[edge_to_loops->indices[0]]; + const float *uvco_v2 = luvs[edge_to_loops->indices[1]]; for (int i = 2; i < edge_to_loops->count; i += 2) { if (loops[edge_to_loops->indices[i]].v == v1) { - if (!equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i]].uv) || - !equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i + 1]].uv)) { + if (!equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i]]) || + !equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i + 1]])) { return true; } } else { BLI_assert(loops[edge_to_loops->indices[i]].v == v2); UNUSED_VARS_NDEBUG(v2); - if (!equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i]].uv) || - !equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i + 1]].uv)) { + if (!equals_v2v2(uvco_v2, luvs[edge_to_loops->indices[i]]) || + !equals_v2v2(uvco_v1, luvs[edge_to_loops->indices[i + 1]])) { return true; } } @@ -1058,7 +1058,7 @@ static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges, const int totpoly, const MLoop *loops, const int totloop, - const MLoopUV *luvs, + const float (*luvs)[2], MeshIslandStore *r_island_store) { int *poly_groups = nullptr; @@ -1223,7 +1223,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3], const int totpoly, MLoop *loops, const int totloop, - const MLoopUV *luvs, + const float (*luvs)[2], MeshIslandStore *r_island_store) { UNUSED_VARS(vert_positions, totvert); diff --git a/source/blender/blenkernel/intern/mesh_merge_customdata.cc b/source/blender/blenkernel/intern/mesh_merge_customdata.cc index 2c500f4d972..7a0895c18e1 100644 --- a/source/blender/blenkernel/intern/mesh_merge_customdata.cc +++ b/source/blender/blenkernel/intern/mesh_merge_customdata.cc @@ -10,6 +10,7 @@ #include "DNA_meshdata_types.h" #include "BLI_math.h" +#include "BLI_math_vector_types.hh" #include "BLI_task.hh" #include "BLI_utildefines.h" @@ -57,7 +58,7 @@ static int compare_v2_classify(const float uv_a[2], const float uv_b[2]) return CMP_APART; } -static void merge_uvs_for_vertex(const Span loops_for_vert, Span mloopuv_layers) +static void merge_uvs_for_vertex(const Span loops_for_vert, Span mloopuv_layers) { if (loops_for_vert.size() <= 1) { return; @@ -65,14 +66,14 @@ static void merge_uvs_for_vertex(const Span loops_for_vert, Span /* Manipulate a copy of the loop indices, de-duplicating UV's per layer. */ Vector loops_merge; loops_merge.reserve(loops_for_vert.size()); - for (MLoopUV *mloopuv : mloopuv_layers) { + for (float2 *mloopuv : mloopuv_layers) { BLI_assert(loops_merge.is_empty()); loops_merge.extend_unchecked(loops_for_vert); while (loops_merge.size() > 1) { uint i_last = uint(loops_merge.size()) - 1; - const float *uv_src = mloopuv[loops_merge[0]].uv; + const float *uv_src = mloopuv[loops_merge[0]]; for (uint i = 1; i <= i_last;) { - float *uv_dst = mloopuv[loops_merge[i]].uv; + float *uv_dst = mloopuv[loops_merge[i]]; switch (compare_v2_classify(uv_src, uv_dst)) { case CMP_CLOSE: { uv_dst[0] = uv_src[0]; @@ -106,7 +107,7 @@ void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me) if (me->totloop == 0) { return; } - const int mloopuv_layers_num = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); + const int mloopuv_layers_num = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); if (mloopuv_layers_num == 0) { return; } @@ -121,14 +122,15 @@ void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me) me->totpoly, me->totloop); - Vector mloopuv_layers; + Vector mloopuv_layers; mloopuv_layers.reserve(mloopuv_layers_num); for (int a = 0; a < mloopuv_layers_num; a++) { - MLoopUV *mloopuv = static_cast(CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a)); + float2 *mloopuv = static_cast(CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, a)); mloopuv_layers.append_unchecked(mloopuv); } - Span mloopuv_layers_as_span = mloopuv_layers.as_span(); + Span mloopuv_layers_as_span = mloopuv_layers.as_span(); + threading::parallel_for(IndexRange(me->totvert), 1024, [&](IndexRange range) { for (const int64_t v_index : range) { MeshElemMap &loops_for_vert = vert_to_loop[v_index]; diff --git a/source/blender/blenkernel/intern/mesh_mirror.cc b/source/blender/blenkernel/intern/mesh_mirror.cc index 65628a4e2c9..843f7226432 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.cc +++ b/source/blender/blenkernel/intern/mesh_mirror.cc @@ -357,34 +357,34 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, /* If set, flip around center of each tile. */ const bool do_mirr_udim = (mmd->flag & MOD_MIR_MIRROR_UDIM) != 0; - const int totuv = CustomData_number_of_layers(&result->ldata, CD_MLOOPUV); + const int totuv = CustomData_number_of_layers(&result->ldata, CD_PROP_FLOAT2); for (a = 0; a < totuv; a++) { - MLoopUV *dmloopuv = static_cast( - CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, a)); + float(*dmloopuv)[2] = static_cast( + CustomData_get_layer_n(&result->ldata, CD_PROP_FLOAT2, a)); int j = maxLoops; dmloopuv += j; /* second set of loops only */ for (; j-- > 0; dmloopuv++) { if (do_mirr_u) { - float u = dmloopuv->uv[0]; + float u = (*dmloopuv)[0]; if (do_mirr_udim) { - dmloopuv->uv[0] = ceilf(u) - fmodf(u, 1.0f) + mmd->uv_offset[0]; + (*dmloopuv)[0] = ceilf(u) - fmodf(u, 1.0f) + mmd->uv_offset[0]; } else { - dmloopuv->uv[0] = 1.0f - u + mmd->uv_offset[0]; + (*dmloopuv)[0] = 1.0f - u + mmd->uv_offset[0]; } } if (do_mirr_v) { - float v = dmloopuv->uv[1]; + float v = (*dmloopuv)[1]; if (do_mirr_udim) { - dmloopuv->uv[1] = ceilf(v) - fmodf(v, 1.0f) + mmd->uv_offset[1]; + (*dmloopuv)[1] = ceilf(v) - fmodf(v, 1.0f) + mmd->uv_offset[1]; } else { - dmloopuv->uv[1] = 1.0f - v + mmd->uv_offset[1]; + (*dmloopuv)[1] = 1.0f - v + mmd->uv_offset[1]; } } - dmloopuv->uv[0] += mmd->uv_offset_copy[0]; - dmloopuv->uv[1] += mmd->uv_offset_copy[1]; + (*dmloopuv)[0] += mmd->uv_offset_copy[0]; + (*dmloopuv)[1] += mmd->uv_offset_copy[1]; } } } diff --git a/source/blender/blenkernel/intern/mesh_tangent.cc b/source/blender/blenkernel/intern/mesh_tangent.cc index 4a9155914a3..35c7c1f40bc 100644 --- a/source/blender/blenkernel/intern/mesh_tangent.cc +++ b/source/blender/blenkernel/intern/mesh_tangent.cc @@ -18,6 +18,7 @@ #include "BLI_task.h" #include "BLI_utildefines.h" +#include "BKE_attribute.hh" #include "BKE_customdata.h" #include "BKE_mesh.h" #include "BKE_mesh_runtime.h" @@ -29,6 +30,8 @@ #include "atomic_ops.h" #include "mikktspace.hh" +using blender::float2; + /* -------------------------------------------------------------------- */ /** \name Mesh Tangent Calculations (Single Layer) * \{ */ @@ -52,7 +55,7 @@ struct BKEMeshToTangent { mikk::float3 GetTexCoord(const uint face_num, const uint vert_num) { - const float *uv = luvs[uint(mpolys[face_num].loopstart) + vert_num].uv; + const float *uv = luvs[uint(mpolys[face_num].loopstart) + vert_num]; return mikk::float3(uv[0], uv[1], 1.0f); } @@ -70,7 +73,7 @@ struct BKEMeshToTangent { const MPoly *mpolys; /* faces */ const MLoop *mloops; /* faces vertices */ const float (*positions)[3]; /* vertices */ - const MLoopUV *luvs; /* texture coordinates */ + const float (*luvs)[2]; /* texture coordinates */ const float (*loop_normals)[3]; /* loops' normals */ float (*tangents)[4]; /* output tangents */ int num_polys; /* number of polygons */ @@ -81,7 +84,7 @@ void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3], const MLoop *mloops, float (*r_looptangent)[4], const float (*loop_normals)[3], - const MLoopUV *loopuvs, + const float (*loop_uvs)[2], const int /*numLoops*/, const MPoly *mpolys, const int numPolys, @@ -92,7 +95,7 @@ void BKE_mesh_calc_loop_tangent_single_ex(const float (*vert_positions)[3], mesh_to_tangent.mpolys = mpolys; mesh_to_tangent.mloops = mloops; mesh_to_tangent.positions = vert_positions; - mesh_to_tangent.luvs = loopuvs; + mesh_to_tangent.luvs = loop_uvs; mesh_to_tangent.loop_normals = loop_normals; mesh_to_tangent.tangents = r_looptangent; mesh_to_tangent.num_polys = numPolys; @@ -116,16 +119,16 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, float (*r_looptangents)[4], ReportList *reports) { - const MLoopUV *loopuvs; + using namespace blender; + using namespace blender::bke; - /* Check we have valid texture coordinates first! */ - if (uvmap) { - loopuvs = static_cast(CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvmap)); + if (!uvmap) { + uvmap = CustomData_get_active_layer_name(&mesh->ldata, CD_PROP_FLOAT2); } - else { - loopuvs = static_cast(CustomData_get_layer(&mesh->ldata, CD_MLOOPUV)); - } - if (!loopuvs) { + + const AttributeAccessor attributes = mesh->attributes(); + const VArraySpan uv_map = attributes.lookup(uvmap, ATTR_DOMAIN_CORNER); + if (uv_map.is_empty()) { BKE_reportf(reports, RPT_ERROR, "Tangent space computation needs a UV Map, \"%s\" not found, aborting", @@ -146,7 +149,7 @@ void BKE_mesh_calc_loop_tangent_single(Mesh *mesh, BKE_mesh_loops(mesh), r_looptangents, loop_normals, - loopuvs, + reinterpret_cast(uv_map.data()), mesh->totloop, BKE_mesh_polys(mesh), mesh->totpoly, @@ -221,7 +224,7 @@ struct SGLSLMeshToTangent { const MLoopTri *lt; uint loop_index = GetLoop(face_num, vert_num, lt); if (mloopuv != nullptr) { - const float *uv = mloopuv[loop_index].uv; + const float2 &uv = mloopuv[loop_index]; return mikk::float3(uv[0], uv[1], 1.0f); } const float *l_orco = orco[mloop[loop_index].v]; @@ -275,7 +278,7 @@ struct SGLSLMeshToTangent { const float (*precomputedFaceNormals)[3]; const float (*precomputedLoopNormals)[3]; const MLoopTri *looptri; - const MLoopUV *mloopuv; /* texture coordinates */ + const float2 *mloopuv; /* texture coordinates */ const MPoly *mpoly; /* indices */ const MLoop *mloop; /* indices */ const float (*positions)[3]; /* vertex coordinates */ @@ -306,7 +309,7 @@ void BKE_mesh_add_loop_tangent_named_layer_for_uv(CustomData *uv_data, const char *layer_name) { if (CustomData_get_named_layer_index(tan_data, CD_TANGENT, layer_name) == -1 && - CustomData_get_named_layer_index(uv_data, CD_MLOOPUV, layer_name) != -1) { + CustomData_get_named_layer_index(uv_data, CD_PROP_FLOAT2, layer_name) != -1) { CustomData_add_layer_named( tan_data, CD_TANGENT, CD_SET_DEFAULT, nullptr, numLoopData, layer_name); } @@ -314,7 +317,7 @@ void BKE_mesh_add_loop_tangent_named_layer_for_uv(CustomData *uv_data, void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData, bool calc_active_tangent, - const char (*tangent_names)[MAX_NAME], + const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_count, bool *rcalc_act, bool *rcalc_ren, @@ -325,15 +328,15 @@ void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData, short *rtangent_mask) { /* Active uv in viewport */ - int layer_index = CustomData_get_layer_index(loopData, CD_MLOOPUV); - *ract_uv_n = CustomData_get_active_layer(loopData, CD_MLOOPUV); + int layer_index = CustomData_get_layer_index(loopData, CD_PROP_FLOAT2); + *ract_uv_n = CustomData_get_active_layer(loopData, CD_PROP_FLOAT2); ract_uv_name[0] = 0; if (*ract_uv_n != -1) { strcpy(ract_uv_name, loopData->layers[*ract_uv_n + layer_index].name); } /* Active tangent in render */ - *rren_uv_n = CustomData_get_render_layer(loopData, CD_MLOOPUV); + *rren_uv_n = CustomData_get_render_layer(loopData, CD_PROP_FLOAT2); rren_uv_name[0] = 0; if (*rren_uv_n != -1) { strcpy(rren_uv_name, loopData->layers[*rren_uv_n + layer_index].name); @@ -361,9 +364,9 @@ void BKE_mesh_calc_loop_tangent_step_0(const CustomData *loopData, } *rtangent_mask = 0; - const int uv_layer_num = CustomData_number_of_layers(loopData, CD_MLOOPUV); + const int uv_layer_num = CustomData_number_of_layers(loopData, CD_PROP_FLOAT2); for (int n = 0; n < uv_layer_num; n++) { - const char *name = CustomData_get_layer_name(loopData, CD_MLOOPUV, n); + const char *name = CustomData_get_layer_name(loopData, CD_PROP_FLOAT2, n); bool add = false; for (int i = 0; i < tangent_names_count; i++) { if (tangent_names[i][0] && STREQ(tangent_names[i], name)) { @@ -394,7 +397,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], CustomData *loopdata, bool calc_active_tangent, - const char (*tangent_names)[MAX_NAME], + const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len, const float (*vert_normals)[3], const float (*poly_normals)[3], @@ -409,8 +412,8 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], int ren_uv_n = -1; bool calc_act = false; bool calc_ren = false; - char act_uv_name[MAX_NAME]; - char ren_uv_name[MAX_NAME]; + char act_uv_name[MAX_CUSTOMDATA_LAYER_NAME]; + char ren_uv_name[MAX_CUSTOMDATA_LAYER_NAME]; short tangent_mask = 0; short tangent_mask_curr = *tangent_mask_curr_p; @@ -501,8 +504,8 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], mesh2tangent->precomputedFaceNormals = poly_normals; mesh2tangent->orco = nullptr; - mesh2tangent->mloopuv = static_cast( - CustomData_get_layer_named(loopdata, CD_MLOOPUV, loopdata_out->layers[index].name)); + mesh2tangent->mloopuv = static_cast(CustomData_get_layer_named( + loopdata, CD_PROP_FLOAT2, loopdata_out->layers[index].name)); /* Fill the resulting tangent_mask */ if (!mesh2tangent->mloopuv) { @@ -515,8 +518,8 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], } else { int uv_ind = CustomData_get_named_layer_index( - loopdata, CD_MLOOPUV, loopdata_out->layers[index].name); - int uv_start = CustomData_get_layer_index(loopdata, CD_MLOOPUV); + loopdata, CD_PROP_FLOAT2, loopdata_out->layers[index].name); + int uv_start = CustomData_get_layer_index(loopdata, CD_PROP_FLOAT2); BLI_assert(uv_ind != -1 && uv_start != -1); BLI_assert(uv_ind - uv_start < MAX_MTFACE); tangent_mask_curr |= short(1 << (uv_ind - uv_start)); @@ -545,7 +548,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], /* Update active layer index */ int act_uv_index = (act_uv_n != -1) ? - CustomData_get_layer_index_n(loopdata, CD_MLOOPUV, act_uv_n) : + CustomData_get_layer_index_n(loopdata, CD_PROP_FLOAT2, act_uv_n) : -1; if (act_uv_index != -1) { int tan_index = CustomData_get_named_layer_index( @@ -555,7 +558,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], /* Update render layer index */ int ren_uv_index = (ren_uv_n != -1) ? - CustomData_get_layer_index_n(loopdata, CD_MLOOPUV, ren_uv_n) : + CustomData_get_layer_index_n(loopdata, CD_PROP_FLOAT2, ren_uv_n) : -1; if (ren_uv_index != -1) { int tan_index = CustomData_get_named_layer_index( @@ -567,7 +570,7 @@ void BKE_mesh_calc_loop_tangent_ex(const float (*vert_positions)[3], void BKE_mesh_calc_loop_tangents(Mesh *me_eval, bool calc_active_tangent, - const char (*tangent_names)[MAX_NAME], + const char (*tangent_names)[MAX_CUSTOMDATA_LAYER_NAME], int tangent_names_len) { /* TODO(@campbellbarton): store in Mesh.runtime to avoid recalculation. */ diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc index 6d9660ff8bb..e834ef70b4e 100644 --- a/source/blender/blenkernel/intern/mesh_validate.cc +++ b/source/blender/blenkernel/intern/mesh_validate.cc @@ -1022,7 +1022,7 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata, is_valid &= mesh_validate_customdata( 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_uvloop = CustomData_number_of_layers(ldata, CD_PROP_FLOAT2); if (tot_uvloop > MAX_MTFACE) { PRINT_ERR( "\tMore UV layers than %d allowed, %d last ones won't be available for render, shaders, " @@ -1032,12 +1032,12 @@ bool BKE_mesh_validate_all_customdata(CustomData *vdata, } /* check indices of clone/stencil */ - if (do_fixes && CustomData_get_clone_layer(ldata, CD_MLOOPUV) >= tot_uvloop) { - CustomData_set_layer_clone(ldata, CD_MLOOPUV, 0); + if (do_fixes && CustomData_get_clone_layer(ldata, CD_PROP_FLOAT2) >= tot_uvloop) { + CustomData_set_layer_clone(ldata, CD_PROP_FLOAT2, 0); is_change_l = true; } - if (do_fixes && CustomData_get_stencil_layer(ldata, CD_MLOOPUV) >= tot_uvloop) { - CustomData_set_layer_stencil(ldata, CD_MLOOPUV, 0); + if (do_fixes && CustomData_get_stencil_layer(ldata, CD_PROP_FLOAT2) >= tot_uvloop) { + CustomData_set_layer_stencil(ldata, CD_PROP_FLOAT2, 0); is_change_l = true; } diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index 18dd92b62b4..e5d15918a2b 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -67,6 +67,7 @@ #include "RNA_types.h" using blender::Array; +using blender::float2; using blender::float3; using blender::float4x4; using blender::Span; @@ -1062,7 +1063,7 @@ struct FaceDupliData_Mesh { const MLoop *mloop; Span vert_positions; const float (*orco)[3]; - const MLoopUV *mloopuv; + const float2 *mloopuv; }; struct FaceDupliData_EditMesh { @@ -1211,7 +1212,7 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx, const MPoly *mpoly = fdd->mpoly, *mp; const MLoop *mloop = fdd->mloop; const float(*orco)[3] = fdd->orco; - const MLoopUV *mloopuv = fdd->mloopuv; + const float2 *mloopuv = fdd->mloopuv; const int totface = fdd->totface; const bool use_scale = fdd->params.use_scale; int a; @@ -1243,7 +1244,7 @@ static void make_child_duplis_faces_from_mesh(const DupliContext *ctx, } if (mloopuv) { for (int j = 0; j < mp->totloop; j++) { - madd_v2_v2fl(dob->uv, mloopuv[mp->loopstart + j].uv, w); + madd_v2_v2fl(dob->uv, mloopuv[mp->loopstart + j], w); } } } @@ -1304,7 +1305,7 @@ static void make_duplis_faces(const DupliContext *ctx) FaceDupliData_Params fdd_params = {ctx, (parent->transflag & OB_DUPLIFACES_SCALE) != 0}; if (em != nullptr) { - const int uv_idx = CustomData_get_render_layer(&em->bm->ldata, CD_MLOOPUV); + const int uv_idx = CustomData_get_render_layer(&em->bm->ldata, CD_PROP_FLOAT2); FaceDupliData_EditMesh fdd{}; fdd.params = fdd_params; fdd.em = em; @@ -1312,20 +1313,20 @@ static void make_duplis_faces(const DupliContext *ctx) fdd.has_orco = (vert_positions_deform != nullptr); fdd.has_uvs = (uv_idx != -1); fdd.cd_loop_uv_offset = (uv_idx != -1) ? - CustomData_get_n_offset(&em->bm->ldata, CD_MLOOPUV, uv_idx) : + CustomData_get_n_offset(&em->bm->ldata, CD_PROP_FLOAT2, uv_idx) : -1; make_child_duplis(ctx, &fdd, make_child_duplis_faces_from_editmesh); } else { - const int uv_idx = CustomData_get_render_layer(&me_eval->ldata, CD_MLOOPUV); + const int uv_idx = CustomData_get_render_layer(&me_eval->ldata, CD_PROP_FLOAT2); FaceDupliData_Mesh fdd{}; fdd.params = fdd_params; fdd.totface = me_eval->totpoly; fdd.mpoly = me_eval->polys().data(); fdd.mloop = me_eval->loops().data(); fdd.vert_positions = me_eval->vert_positions(); - fdd.mloopuv = (uv_idx != -1) ? (const MLoopUV *)CustomData_get_layer_n( - &me_eval->ldata, CD_MLOOPUV, uv_idx) : + fdd.mloopuv = (uv_idx != -1) ? (const float2 *)CustomData_get_layer_n( + &me_eval->ldata, CD_PROP_FLOAT2, uv_idx) : nullptr; fdd.orco = (const float(*)[3])CustomData_get_layer(&me_eval->vdata, CD_ORCO); diff --git a/source/blender/blenkernel/intern/object_update.cc b/source/blender/blenkernel/intern/object_update.cc index 625aa666023..a7da1bfb5d2 100644 --- a/source/blender/blenkernel/intern/object_update.cc +++ b/source/blender/blenkernel/intern/object_update.cc @@ -158,7 +158,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_PROP_BYTE_COLOR; + cddata_masks.lmask |= CD_MASK_PROP_FLOAT2 | 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_canvas.cc b/source/blender/blenkernel/intern/paint_canvas.cc index 1c360c7f881..e9fe8d4cc96 100644 --- a/source/blender/blenkernel/intern/paint_canvas.cc +++ b/source/blender/blenkernel/intern/paint_canvas.cc @@ -80,7 +80,7 @@ int BKE_paint_canvas_uvmap_layer_index_get(const struct PaintModeSettings *setti } const Mesh *mesh = static_cast(ob->data); - return CustomData_get_active_layer_index(&mesh->ldata, CD_MLOOPUV); + return CustomData_get_active_layer_index(&mesh->ldata, CD_PROP_FLOAT2); } case PAINT_CANVAS_SOURCE_MATERIAL: { /* Use uv map of the canvas. */ @@ -98,7 +98,7 @@ int BKE_paint_canvas_uvmap_layer_index_get(const struct PaintModeSettings *setti } const Mesh *mesh = static_cast(ob->data); - return CustomData_get_named_layer_index(&mesh->ldata, CD_MLOOPUV, slot->uvname); + return CustomData_get_named_layer_index(&mesh->ldata, CD_PROP_FLOAT2, slot->uvname); } } return -1; diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index e21103c9f19..884da8b89f0 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -147,7 +147,7 @@ struct EncodePixelsUserData { ImageUser *image_user; PBVH *pbvh; Vector *nodes; - const MLoopUV *ldata_uv; + const float2 *ldata_uv; const uv_islands::UVIslandsMask *uv_masks; /** Lookup to retrieve the UV primitives based on the primitive index. */ const UVPrimitiveLookup *uv_primitive_lookup; @@ -355,8 +355,8 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image return; } - const MLoopUV *ldata_uv = static_cast( - CustomData_get_layer(&mesh->ldata, CD_MLOOPUV)); + const float2 *ldata_uv = static_cast( + CustomData_get_layer(&mesh->ldata, CD_PROP_FLOAT2)); if (ldata_uv == nullptr) { return; } diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index 15397170525..5f4a888805e 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -116,7 +116,7 @@ static void mesh_data_init_primitives(MeshData &mesh_data) MeshUVVert uv_vert; uv_vert.loop = tri.tri[j]; uv_vert.vertex = &mesh_data.vertices[mesh_data.loops[uv_vert.loop].v]; - uv_vert.uv = mesh_data.mloopuv[uv_vert.loop].uv; + uv_vert.uv = mesh_data.mloopuv[uv_vert.loop]; primitive.vertices.append(uv_vert); } mesh_data.primitives.append(primitive); @@ -218,7 +218,7 @@ static void mesh_data_init(MeshData &mesh_data) MeshData::MeshData(const Span looptris, const Span loops, const int verts_num, - const Span mloopuv) + const Span mloopuv) : looptris(looptris), verts_num(verts_num), loops(loops), mloopuv(mloopuv) { mesh_data_init(*this); diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.hh b/source/blender/blenkernel/intern/pbvh_uv_islands.hh index a1a0bd5da0d..db1b12cdcb3 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.hh +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.hh @@ -95,7 +95,7 @@ struct MeshData { const Span looptris; const int64_t verts_num; const Span loops; - const Span mloopuv; + const Span mloopuv; Vector primitives; Vector edges; @@ -107,7 +107,7 @@ struct MeshData { explicit MeshData(const Span looptris, const Span loops, const int verts_num, - const Span mloopuv); + const Span mloopuv); }; struct UVVertex { diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.c index 09d01a5b50f..64d31ed7f58 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.c @@ -193,14 +193,14 @@ static int get_num_uv_layers(const OpenSubdiv_Converter *converter) { ConverterStorage *storage = converter->user_data; const Mesh *mesh = storage->mesh; - return CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV); + return CustomData_number_of_layers(&mesh->ldata, CD_PROP_FLOAT2); } static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int layer_index) { ConverterStorage *storage = converter->user_data; const Mesh *mesh = storage->mesh; - const MLoopUV *mloopuv = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, layer_index); + const float(*mloopuv)[2] = CustomData_get_layer_n(&mesh->ldata, CD_PROP_FLOAT2, layer_index); const int num_poly = mesh->totpoly; const int num_vert = mesh->totvert; const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT}; diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.c index 97ee072c296..302eeacbf2e 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.c +++ b/source/blender/blenkernel/intern/subdiv_eval.c @@ -126,7 +126,7 @@ typedef struct FaceVaryingDataFromUVContext { OpenSubdiv_TopologyRefiner *topology_refiner; const Mesh *mesh; const MPoly *polys; - const MLoopUV *mloopuv; + const float (*mloopuv)[2]; float (*buffer)[2]; int layer_index; } FaceVaryingDataFromUVContext; @@ -139,7 +139,7 @@ static void set_face_varying_data_from_uv_task(void *__restrict userdata, OpenSubdiv_TopologyRefiner *topology_refiner = ctx->topology_refiner; const int layer_index = ctx->layer_index; const MPoly *mpoly = &ctx->polys[face_index]; - const MLoopUV *mluv = &ctx->mloopuv[mpoly->loopstart]; + const float(*mluv)[2] = &ctx->mloopuv[mpoly->loopstart]; /* TODO(sergey): OpenSubdiv's C-API converter can change winding of * loops of a face, need to watch for that, to prevent wrong UVs assigned. @@ -148,19 +148,19 @@ static void set_face_varying_data_from_uv_task(void *__restrict userdata, const int *uv_indices = topology_refiner->getFaceFVarValueIndices( topology_refiner, face_index, layer_index); for (int vertex_index = 0; vertex_index < num_face_vertices; vertex_index++, mluv++) { - copy_v2_v2(ctx->buffer[uv_indices[vertex_index]], mluv->uv); + copy_v2_v2(ctx->buffer[uv_indices[vertex_index]], *mluv); } } static void set_face_varying_data_from_uv(Subdiv *subdiv, const Mesh *mesh, - const MLoopUV *mloopuv, + const float (*mloopuv)[2], const int layer_index) { OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; OpenSubdiv_Evaluator *evaluator = subdiv->evaluator; const int num_faces = topology_refiner->getNumFaces(topology_refiner); - const MLoopUV *mluv = mloopuv; + const float(*mluv)[2] = mloopuv; const int num_fvar_values = topology_refiner->getNumFVarValues(topology_refiner, layer_index); /* Use a temporary buffer so we do not upload UVs one at a time to the GPU. */ @@ -249,9 +249,9 @@ bool BKE_subdiv_eval_refine_from_mesh(Subdiv *subdiv, /* Set coordinates of base mesh vertices. */ set_coarse_positions(subdiv, mesh, coarse_vertex_cos); /* Set face-varying data to UV maps. */ - const int num_uv_layers = CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV); + const int num_uv_layers = CustomData_number_of_layers(&mesh->ldata, CD_PROP_FLOAT2); for (int layer_index = 0; layer_index < num_uv_layers; layer_index++) { - const MLoopUV *mloopuv = CustomData_get_layer_n(&mesh->ldata, CD_MLOOPUV, layer_index); + const float(*mloopuv)[2] = CustomData_get_layer_n(&mesh->ldata, CD_PROP_FLOAT2, layer_index); set_face_varying_data_from_uv(subdiv, mesh, mloopuv, layer_index); } /* Set vertex data to orco. */ diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc index f7c607624e0..2d1b6dd3f0e 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.cc +++ b/source/blender/blenkernel/intern/subdiv_mesh.cc @@ -16,6 +16,7 @@ #include "BLI_array.hh" #include "BLI_bitmap.h" #include "BLI_math_vector.h" +#include "BLI_math_vector_types.hh" #include "BKE_customdata.h" #include "BKE_key.h" @@ -28,6 +29,7 @@ #include "MEM_guardedalloc.h" +using blender::float2; using blender::float3; using blender::Span; @@ -57,7 +59,8 @@ struct SubdivMeshContext { int *poly_origindex; /* UV layers interpolation. */ int num_uv_layers; - MLoopUV *uv_layers[MAX_MTFACE]; + float2 *uv_layers[MAX_MTFACE]; + /* Original coordinates (ORCO) interpolation. */ float (*orco)[3]; float (*cloth_orco)[3]; @@ -74,10 +77,10 @@ struct SubdivMeshContext { static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx) { Mesh *subdiv_mesh = ctx->subdiv_mesh; - ctx->num_uv_layers = CustomData_number_of_layers(&subdiv_mesh->ldata, CD_MLOOPUV); + ctx->num_uv_layers = CustomData_number_of_layers(&subdiv_mesh->ldata, CD_PROP_FLOAT2); for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) { - ctx->uv_layers[layer_index] = static_cast( - CustomData_get_layer_n(&subdiv_mesh->ldata, CD_MLOOPUV, layer_index)); + ctx->uv_layers[layer_index] = static_cast( + CustomData_get_layer_n(&subdiv_mesh->ldata, CD_PROP_FLOAT2, layer_index)); } } @@ -858,8 +861,8 @@ static void subdiv_eval_uv_layer(SubdivMeshContext *ctx, Subdiv *subdiv = ctx->subdiv; const int mloop_index = subdiv_loop - ctx->subdiv_loops; for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) { - MLoopUV *subdiv_loopuv = &ctx->uv_layers[layer_index][mloop_index]; - BKE_subdiv_eval_face_varying(subdiv, layer_index, ptex_face_index, u, v, subdiv_loopuv->uv); + BKE_subdiv_eval_face_varying( + subdiv, layer_index, ptex_face_index, u, v, ctx->uv_layers[layer_index][mloop_index]); } } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 92cefa4d8b1..c6f8fef3a93 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -262,7 +262,7 @@ static void get_face_uv_map_vert( static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, - const MLoopUV *mloopuv) + const float (*mloopuv)[2]) { MPoly *mpoly = dm->getPolyArray(dm); MLoop *mloop = dm->getLoopArray(dm); @@ -312,7 +312,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, int loopid = mpoly[v->poly_index].loopstart + v->loop_of_poly_index; CCGVertHDL vhdl = POINTER_FROM_INT(loopid); - copy_v2_v2(uv, mloopuv[loopid].uv); + copy_v2_v2(uv, mloopuv[loopid]); ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv); } @@ -387,11 +387,11 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh * { CCGFaceIterator fi; int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S; - const MLoopUV *dmloopuv = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, n); - /* need to update both CD_MTFACE & CD_MLOOPUV, hrmf, we could get away with + const float(*dmloopuv)[2] = CustomData_get_layer_n(&dm->loopData, CD_PROP_FLOAT2, n); + /* need to update both CD_MTFACE & CD_PROP_FLOAT2, hrmf, we could get away with * just tface except applying the modifier then looses subsurf UV */ MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n); - MLoopUV *mloopuv = CustomData_get_layer_n(&result->loopData, CD_MLOOPUV, n); + float(*mloopuv)[2] = CustomData_get_layer_n(&result->loopData, CD_PROP_FLOAT2, n); if (!dmloopuv || (!tface && !mloopuv)) { return; @@ -421,7 +421,7 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh * /* load coordinates from uvss into tface */ MTFace *tf = tface; - MLoopUV *mluv = mloopuv; + float(*mluv)[2] = mloopuv; for (index = 0; index < totface; index++) { CCGFace *f = faceMap[index]; @@ -446,10 +446,10 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh * } if (mluv) { - copy_v2_v2(mluv[0].uv, a); - copy_v2_v2(mluv[1].uv, d); - copy_v2_v2(mluv[2].uv, c); - copy_v2_v2(mluv[3].uv, b); + copy_v2_v2(mluv[0], a); + copy_v2_v2(mluv[1], d); + copy_v2_v2(mluv[2], c); + copy_v2_v2(mluv[3], b); mluv += 4; } } @@ -1801,8 +1801,8 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, if (useSubsurfUv) { CustomData *ldata = &ccgdm->dm.loopData; CustomData *dmldata = &dm->loopData; - int numlayer = CustomData_number_of_layers(ldata, CD_MLOOPUV); - int dmnumlayer = CustomData_number_of_layers(dmldata, CD_MLOOPUV); + int numlayer = CustomData_number_of_layers(ldata, CD_PROP_FLOAT2); + int dmnumlayer = CustomData_number_of_layers(dmldata, CD_PROP_FLOAT2); for (i = 0; i < numlayer && i < dmnumlayer; i++) { set_subsurf_uv(ss, dm, &ccgdm->dm, i); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 09292841e91..8cbc08357a4 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1792,7 +1792,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) if (DNA_struct_find(fd->filesdna, "MTexPoly")) { for (Mesh *me = bmain->meshes.first; me; me = me->id.next) { /* If we have UV's, so this file will have MTexPoly layers too! */ - if (CustomData_has_layer(&me->ldata, CD_MLOOPUV)) { + if (CustomData_has_layer(&me->ldata, CD_MLOOPUV) || + CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2)) { CustomData_update_typemap(&me->pdata); CustomData_free_layers(&me->pdata, CD_MTEXPOLY, me->totpoly); } diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 87b191de240..d561c3592d7 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -29,6 +29,7 @@ static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh) { BKE_mesh_legacy_convert_flags_to_selection_layers(&mesh); BKE_mesh_legacy_convert_flags_to_hide_layers(&mesh); + BKE_mesh_legacy_convert_uvs_to_generic(&mesh); BKE_mesh_legacy_convert_mpoly_to_material_indices(&mesh); BKE_mesh_legacy_bevel_weight_to_layers(&mesh); BKE_mesh_legacy_face_set_to_generic(&mesh); diff --git a/source/blender/blenloader/intern/versioning_defaults.cc b/source/blender/blenloader/intern/versioning_defaults.cc index 51547a41316..0e7a21c3291 100644 --- a/source/blender/blenloader/intern/versioning_defaults.cc +++ b/source/blender/blenloader/intern/versioning_defaults.cc @@ -351,17 +351,16 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene) /* Correct default startup UV's. */ Mesh *me = static_cast(BLI_findstring(&bmain->meshes, "Cube", offsetof(ID, name) + 2)); - if (me && (me->totloop == 24) && CustomData_has_layer(&me->ldata, CD_MLOOPUV)) { - MLoopUV *mloopuv = static_cast(CustomData_get_layer(&me->ldata, CD_MLOOPUV)); + if (me && (me->totloop == 24) && CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2)) { const float uv_values[24][2] = { {0.625, 0.50}, {0.875, 0.50}, {0.875, 0.75}, {0.625, 0.75}, {0.375, 0.75}, {0.625, 0.75}, {0.625, 1.00}, {0.375, 1.00}, {0.375, 0.00}, {0.625, 0.00}, {0.625, 0.25}, {0.375, 0.25}, {0.125, 0.50}, {0.375, 0.50}, {0.375, 0.75}, {0.125, 0.75}, {0.375, 0.50}, {0.625, 0.50}, {0.625, 0.75}, {0.375, 0.75}, {0.375, 0.25}, {0.625, 0.25}, {0.625, 0.50}, {0.375, 0.50}, }; - for (int i = 0; i < ARRAY_SIZE(uv_values); i++) { - copy_v2_v2(mloopuv[i].uv, uv_values[i]); - } + float(*mloopuv)[2] = static_cast( + CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2)); + memcpy(mloopuv, uv_values, sizeof(float[2]) * me->totloop); } /* Make sure that the curve profile is initialized */ diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index e559944324f..d0aac884b53 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -173,6 +173,7 @@ * - Use two different iterator types for BMO map/buffer types. */ +#include "BKE_customdata.h" #include "DNA_customdata_types.h" /* BMesh struct in bmesh_class.h uses */ #include "DNA_listBase.h" /* selection history uses */ diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index e837ec9eae2..a724a8783d4 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -533,6 +533,19 @@ typedef bool (*BMLoopPairFilterFunc)(const BMLoop *, const BMLoop *, void *user_ #define BM_ELEM_CD_GET_BOOL(ele, offset) \ (BLI_assert(offset != -1), *((bool *)((char *)(ele)->head.data + (offset)))) +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) +# define BM_ELEM_CD_GET_BOOL_P(ele, offset) \ + (BLI_assert(offset != -1), \ + _Generic(ele, \ + GENERIC_TYPE_ANY((bool *)POINTER_OFFSET((ele)->head.data, offset), \ + _BM_GENERIC_TYPE_ELEM_NONCONST), \ + GENERIC_TYPE_ANY((const bool *)POINTER_OFFSET((ele)->head.data, offset), \ + _BM_GENERIC_TYPE_ELEM_CONST))) +#else +# define BM_ELEM_CD_GET_BOOL_P(ele, offset) \ + (BLI_assert(offset != -1), (bool *)((char *)(ele)->head.data + (offset))) +#endif + #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) # define BM_ELEM_CD_GET_VOID_P(ele, offset) \ (BLI_assert(offset != -1), \ diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 8ceefc94d8a..e0422f21782 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -15,8 +15,10 @@ #include "BLI_linklist.h" #include "BLI_math.h" #include "BLI_memarena.h" +#include "BLI_string.h" #include "BLI_task.h" +#include "BKE_attribute.h" #include "BKE_customdata.h" #include "BKE_multires.h" @@ -864,6 +866,61 @@ void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char * } } +void BM_data_layer_ensure_named(BMesh *bm, CustomData *data, int type, const char *name) +{ + if (CustomData_get_named_layer_index(data, type, name) == -1) { + BM_data_layer_add_named(bm, data, type, name); + } +} + +void BM_uv_map_ensure_select_and_pin_attrs(BMesh *bm) +{ + const int nr_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_PROP_FLOAT2); + for (int l = 0; l < nr_uv_layers; l++) { + /* NOTE: you can't re-use the returnvalue of CustomData_get_layer_name() because adding layers + * can invalidate that. */ + char name[MAX_CUSTOMDATA_LAYER_NAME]; + BM_data_layer_ensure_named( + bm, + &bm->ldata, + CD_PROP_BOOL, + BKE_uv_map_vert_select_name_get(CustomData_get_layer_name(&bm->ldata, CD_PROP_FLOAT2, l), + name)); + BM_data_layer_ensure_named( + bm, + &bm->ldata, + CD_PROP_BOOL, + BKE_uv_map_edge_select_name_get(CustomData_get_layer_name(&bm->ldata, CD_PROP_FLOAT2, l), + name)); + BM_data_layer_ensure_named( + bm, + &bm->ldata, + CD_PROP_BOOL, + BKE_uv_map_pin_name_get(CustomData_get_layer_name(&bm->ldata, CD_PROP_FLOAT2, l), name)); + } +} + +void BM_uv_map_ensure_vert_select_attr(BMesh *bm, const char *uv_map_name) +{ + char name[MAX_CUSTOMDATA_LAYER_NAME]; + BM_data_layer_ensure_named( + bm, &bm->ldata, CD_PROP_BOOL, BKE_uv_map_vert_select_name_get(uv_map_name, name)); +} + +void BM_uv_map_ensure_edge_select_attr(BMesh *bm, const char *uv_map_name) +{ + char name[MAX_CUSTOMDATA_LAYER_NAME]; + BM_data_layer_ensure_named( + bm, &bm->ldata, CD_PROP_BOOL, BKE_uv_map_edge_select_name_get(uv_map_name, name)); +} + +void BM_uv_map_ensure_pin_attr(BMesh *bm, const char *uv_map_name) +{ + char name[MAX_CUSTOMDATA_LAYER_NAME]; + BM_data_layer_ensure_named( + bm, &bm->ldata, CD_PROP_BOOL, BKE_uv_map_pin_name_get(uv_map_name, name)); +} + void BM_data_layer_free(BMesh *bm, CustomData *data, int type) { CustomData olddata = *data; diff --git a/source/blender/bmesh/intern/bmesh_interp.h b/source/blender/bmesh/intern/bmesh_interp.h index 21c99f00eab..013ed9d237f 100644 --- a/source/blender/bmesh/intern/bmesh_interp.h +++ b/source/blender/bmesh/intern/bmesh_interp.h @@ -62,7 +62,16 @@ void BM_data_interp_face_vert_edge( BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v, BMEdge *e, float fac); void BM_data_layer_add(BMesh *bm, CustomData *data, int type); void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name); +void BM_data_layer_ensure_named(BMesh *bm, CustomData *data, int type, const char *name); void BM_data_layer_free(BMesh *bm, CustomData *data, int type); + +/** Ensure the dependent boolean layers exist for all face corner #CD_PROP_FLOAT2 layers. */ +void BM_uv_map_ensure_select_and_pin_attrs(BMesh *bm); + +void BM_uv_map_ensure_vert_select_attr(BMesh *bm, const char *uv_map_name); +void BM_uv_map_ensure_edge_select_attr(BMesh *bm, const char *uv_map_name); +void BM_uv_map_ensure_pin_attr(BMesh *bm, const char *uv_map_name); + /** * Remove a named custom data layer, if it existed. Return true if the layer was removed. */ diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 4019c4245e2..3d3251598eb 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -149,7 +149,40 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar mask.pmask); CustomData mesh_ldata = CustomData_shallow_copy_remove_non_bmesh_attributes(&me->ldata, mask.lmask); + + blender::Vector temporary_layers_to_delete; + + for (const int layer_index : + IndexRange(CustomData_number_of_layers(&mesh_ldata, CD_PROP_FLOAT2))) { + char name[MAX_CUSTOMDATA_LAYER_NAME]; + BKE_uv_map_vert_select_name_get( + CustomData_get_layer_name(&mesh_ldata, CD_PROP_FLOAT2, layer_index), name); + if (CustomData_get_named_layer_index(&mesh_ldata, CD_PROP_BOOL, name) < 0) { + CustomData_add_layer_named( + &mesh_ldata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, me->totloop, name); + temporary_layers_to_delete.append(std::string(name)); + } + BKE_uv_map_edge_select_name_get( + CustomData_get_layer_name(&mesh_ldata, CD_PROP_FLOAT2, layer_index), name); + if (CustomData_get_named_layer_index(&mesh_ldata, CD_PROP_BOOL, name) < 0) { + CustomData_add_layer_named( + &mesh_ldata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, me->totloop, name); + temporary_layers_to_delete.append(std::string(name)); + } + BKE_uv_map_pin_name_get(CustomData_get_layer_name(&mesh_ldata, CD_PROP_FLOAT2, layer_index), + name); + if (CustomData_get_named_layer_index(&mesh_ldata, CD_PROP_BOOL, name) < 0) { + CustomData_add_layer_named( + &mesh_ldata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, me->totloop, name); + temporary_layers_to_delete.append(std::string(name)); + } + } + BLI_SCOPED_DEFER([&]() { + for (const std::string &name : temporary_layers_to_delete) { + CustomData_free_layer_named(&mesh_ldata, name.c_str(), me->totloop); + } + MEM_SAFE_FREE(mesh_vdata.layers); MEM_SAFE_FREE(mesh_edata.layers); MEM_SAFE_FREE(mesh_pdata.layers); @@ -956,6 +989,54 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh me->totface = 0; me->act_face = -1; + /* Mark UV selection layers which are all false as 'nocopy'. */ + for (const int layer_index : + IndexRange(CustomData_number_of_layers(&bm->ldata, CD_PROP_FLOAT2))) { + char const *layer_name = CustomData_get_layer_name(&bm->ldata, CD_PROP_FLOAT2, layer_index); + char sub_layer_name[MAX_CUSTOMDATA_LAYER_NAME]; + int vertsel_layer_index = CustomData_get_named_layer_index( + &bm->ldata, CD_PROP_BOOL, BKE_uv_map_vert_select_name_get(layer_name, sub_layer_name)); + int edgesel_layer_index = CustomData_get_named_layer_index( + &bm->ldata, CD_PROP_BOOL, BKE_uv_map_edge_select_name_get(layer_name, sub_layer_name)); + int pin_layer_index = CustomData_get_named_layer_index( + &bm->ldata, CD_PROP_BOOL, BKE_uv_map_pin_name_get(layer_name, sub_layer_name)); + int vertsel_offset = bm->ldata.layers[vertsel_layer_index].offset; + int edgesel_offset = bm->ldata.layers[edgesel_layer_index].offset; + int pin_offset = bm->ldata.layers[pin_layer_index].offset; + bool need_vertsel = false; + bool need_edgesel = false; + bool need_pin = false; + + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + BMIter liter; + BMLoop *l; + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { + need_vertsel |= BM_ELEM_CD_GET_BOOL(l, vertsel_offset); + need_edgesel |= BM_ELEM_CD_GET_BOOL(l, edgesel_offset); + need_pin |= BM_ELEM_CD_GET_BOOL(l, pin_offset); + } + } + + if (need_vertsel) { + bm->ldata.layers[vertsel_layer_index].flag &= ~CD_FLAG_NOCOPY; + } + else { + bm->ldata.layers[vertsel_layer_index].flag |= CD_FLAG_NOCOPY; + } + if (need_edgesel) { + bm->ldata.layers[edgesel_layer_index].flag &= ~CD_FLAG_NOCOPY; + } + else { + bm->ldata.layers[edgesel_layer_index].flag |= CD_FLAG_NOCOPY; + } + if (need_pin) { + bm->ldata.layers[pin_layer_index].flag &= ~CD_FLAG_NOCOPY; + } + else { + bm->ldata.layers[pin_layer_index].flag |= CD_FLAG_NOCOPY; + } + } + { CustomData_MeshMasks mask = CD_MASK_MESH; CustomData_MeshMasks_update(&mask, ¶ms->cd_mask_extra); diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 6df446a377c..a2aecf80456 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -234,9 +234,9 @@ float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset) /* The Trapezium Area Rule */ float cross = 0.0f; do { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l_iter->next, cd_loop_uv_offset); - cross += (luv_next->uv[0] - luv->uv[0]) * (luv_next->uv[1] + luv->uv[1]); + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset); + const float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l_iter->next, cd_loop_uv_offset); + cross += (luv_next[0] - luv[0]) * (luv_next[1] + luv[1]); } while ((l_iter = l_iter->next) != l_first); return fabsf(cross * 0.5f); } diff --git a/source/blender/bmesh/intern/bmesh_query_uv.cc b/source/blender/bmesh/intern/bmesh_query_uv.cc index 44e49bc8491..d4863ebc29a 100644 --- a/source/blender/bmesh/intern/bmesh_query_uv.cc +++ b/source/blender/bmesh/intern/bmesh_query_uv.cc @@ -12,6 +12,7 @@ #include "BLI_math_vector_types.hh" #include "BLI_utildefines_stack.h" +#include "BKE_attribute.hh" #include "BKE_customdata.h" #include "DNA_meshdata_types.h" @@ -19,12 +20,36 @@ #include "bmesh.h" #include "intern/bmesh_private.h" +BMUVOffsets BM_uv_map_get_offsets(const BMesh *bm) +{ + using namespace blender; + using namespace blender::bke; + const int layer_index = CustomData_get_active_layer_index(&bm->ldata, CD_PROP_FLOAT2); + if (layer_index == -1) { + return {-1, -1, -1, -1}; + } + + char const *name = bm->ldata.layers[layer_index].name; + char buffer[MAX_CUSTOMDATA_LAYER_NAME]; + + BMUVOffsets offsets; + offsets.uv = bm->ldata.layers[layer_index].offset; + offsets.select_vert = CustomData_get_offset_named( + &bm->ldata, CD_PROP_BOOL, BKE_uv_map_vert_select_name_get(name, buffer)); + offsets.select_edge = CustomData_get_offset_named( + &bm->ldata, CD_PROP_BOOL, BKE_uv_map_edge_select_name_get(name, buffer)); + offsets.pin = CustomData_get_offset_named( + &bm->ldata, CD_PROP_BOOL, BKE_uv_map_pin_name_get(name, buffer)); + + return offsets; +} + static void uv_aspect(const BMLoop *l, const float aspect[2], const int cd_loop_uv_offset, float r_uv[2]) { - const float *uv = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset))->uv; + const float *uv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); r_uv[0] = uv[0] * aspect[0]; r_uv[1] = uv[1] * aspect[1]; } @@ -81,8 +106,8 @@ void BM_face_uv_calc_center_median(const BMFace *f, const int cd_loop_uv_offset, zero_v2(r_cent); l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - const MLoopUV *luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - add_v2_v2(r_cent, luv->uv); + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset); + add_v2_v2(r_cent, luv); } while ((l_iter = l_iter->next) != l_first); mul_v2_fl(r_cent, 1.0f / float(f->len)); @@ -96,8 +121,7 @@ float BM_face_uv_calc_cross(const BMFace *f, const int cd_loop_uv_offset) int i = 0; l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - const MLoopUV *luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - uvs[i++] = luv->uv; + uvs[i++] = BM_ELEM_CD_GET_FLOAT2_P(l_iter, cd_loop_uv_offset); } while ((l_iter = l_iter->next) != l_first); return cross_poly_v2(reinterpret_cast(uvs.data()), f->len); } @@ -108,31 +132,30 @@ void BM_face_uv_minmax(const BMFace *f, float min[2], float max[2], const int cd const BMLoop *l_first; l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - const MLoopUV *luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - minmax_v2v2_v2(min, max, luv->uv); + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset); + minmax_v2v2_v2(min, max, luv); } while ((l_iter = l_iter->next) != l_first); } bool BM_loop_uv_share_edge_check(BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset) { BLI_assert(l_a->e == l_b->e); - MLoopUV *luv_a_curr = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset); - MLoopUV *luv_a_next = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_a->next, cd_loop_uv_offset); - MLoopUV *luv_b_curr = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_b, cd_loop_uv_offset); - MLoopUV *luv_b_next = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_b->next, cd_loop_uv_offset); + float *luv_a_curr = BM_ELEM_CD_GET_FLOAT_P(l_a, cd_loop_uv_offset); + float *luv_a_next = BM_ELEM_CD_GET_FLOAT_P(l_a->next, cd_loop_uv_offset); + float *luv_b_curr = BM_ELEM_CD_GET_FLOAT_P(l_b, cd_loop_uv_offset); + float *luv_b_next = BM_ELEM_CD_GET_FLOAT_P(l_b->next, cd_loop_uv_offset); if (l_a->v != l_b->v) { std::swap(luv_b_curr, luv_b_next); } - return (equals_v2v2(luv_a_curr->uv, luv_b_curr->uv) && - equals_v2v2(luv_a_next->uv, luv_b_next->uv)); + return (equals_v2v2(luv_a_curr, luv_b_curr) && equals_v2v2(luv_a_next, luv_b_next)); } bool BM_loop_uv_share_vert_check(BMLoop *l_a, BMLoop *l_b, const int cd_loop_uv_offset) { BLI_assert(l_a->v == l_b->v); - const MLoopUV *luv_a = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset); - const MLoopUV *luv_b = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_b, cd_loop_uv_offset); - if (!equals_v2v2(luv_a->uv, luv_b->uv)) { + const float *luv_a = BM_ELEM_CD_GET_FLOAT_P(l_a, cd_loop_uv_offset); + const float *luv_b = BM_ELEM_CD_GET_FLOAT_P(l_b, cd_loop_uv_offset); + if (!equals_v2v2(luv_a, luv_b)) { return false; } return true; @@ -150,11 +173,9 @@ bool BM_edge_uv_share_vert_check(BMEdge *e, BMLoop *l_a, BMLoop *l_b, const int const BMLoop *l_other_b = BM_loop_other_vert_loop_by_edge(l_b, e); { - const MLoopUV *luv_other_a = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_other_a, - cd_loop_uv_offset); - const MLoopUV *luv_other_b = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_other_b, - cd_loop_uv_offset); - if (!equals_v2v2(luv_other_a->uv, luv_other_b->uv)) { + const float *luv_other_a = BM_ELEM_CD_GET_FLOAT_P(l_other_a, cd_loop_uv_offset); + const float *luv_other_b = BM_ELEM_CD_GET_FLOAT_P(l_other_b, cd_loop_uv_offset); + if (!equals_v2v2(luv_other_a, luv_other_b)) { return false; } } @@ -172,7 +193,7 @@ bool BM_face_uv_point_inside_test(const BMFace *f, const float co[2], const int BLI_assert(BM_face_is_normal_valid(f)); for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l_iter = l_iter->next) { - projverts[i] = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset))->uv; + projverts[i] = BM_ELEM_CD_GET_FLOAT2_P(l_iter, cd_loop_uv_offset); } return isect_point_poly_v2( diff --git a/source/blender/bmesh/intern/bmesh_query_uv.h b/source/blender/bmesh/intern/bmesh_query_uv.h index edb756875f3..422e858f1b7 100644 --- a/source/blender/bmesh/intern/bmesh_query_uv.h +++ b/source/blender/bmesh/intern/bmesh_query_uv.h @@ -10,6 +10,11 @@ extern "C" { #endif +/** + * Retrieve the custom data offsets for layers used for user interaction with the active UV map. + */ +BMUVOffsets BM_uv_map_get_offsets(const BMesh *bm); + float BM_loop_uv_calc_edge_length_squared(const BMLoop *l, int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index df749b591dc..3a2216d78a0 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -277,7 +277,8 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) } if (BMO_slot_bool_get(op->slots_in, "cmp_uvs") && - bm_edge_delimit_cdata(&bm->ldata, CD_MLOOPUV, &delimit_data.cdata[delimit_data.cdata_len])) { + bm_edge_delimit_cdata( + &bm->ldata, CD_PROP_FLOAT2, &delimit_data.cdata[delimit_data.cdata_len])) { delimit_data.cdata_len += 1; } diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c index 72507cbab6d..434c1524ca9 100644 --- a/source/blender/bmesh/operators/bmo_mirror.c +++ b/source/blender/bmesh/operators/bmo_mirror.c @@ -67,30 +67,30 @@ void bmo_mirror_exec(BMesh *bm, BMOperator *op) if (mirror_u || mirror_v) { BMFace *f; BMLoop *l; - MLoopUV *luv; - const int totlayer = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV); + float *luv; + const int totlayer = CustomData_number_of_layers(&bm->ldata, CD_PROP_FLOAT2); BMIter liter; BMO_ITER (f, &siter, dupeop.slots_out, "geom.out", BM_FACE) { BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { for (i = 0; i < totlayer; i++) { - luv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i); + luv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_PROP_FLOAT2, i); if (mirror_u) { - float uv_u = luv->uv[0]; + float uv_u = luv[0]; if (mirror_udim) { - luv->uv[0] = ceilf(uv_u) - fmodf(uv_u, 1.0f); + luv[0] = ceilf(uv_u) - fmodf(uv_u, 1.0f); } else { - luv->uv[0] = 1.0f - uv_u; + luv[0] = 1.0f - uv_u; } } if (mirror_v) { - float uv_v = luv->uv[1]; + float uv_v = luv[1]; if (mirror_udim) { - luv->uv[1] = ceilf(uv_v) - fmodf(uv_v, 1.0f); + luv[1] = ceilf(uv_v) - fmodf(uv_v, 1.0f); } else { - luv->uv[1] = 1.0f - uv_v; + luv[1] = 1.0f - uv_v; } } } diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c index c60ffbedb94..70984ba10bd 100644 --- a/source/blender/bmesh/operators/bmo_primitive.c +++ b/source/blender/bmesh/operators/bmo_primitive.c @@ -719,7 +719,7 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op) const float xtot_inv2 = 2.0f / (xtot); const float ytot_inv2 = 2.0f / (ytot); - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2); const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs"); BMVert **varr; @@ -799,7 +799,7 @@ void BM_mesh_calc_uvs_grid(BMesh *bm, } BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, loop_index) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); switch (loop_index) { case 0: @@ -818,8 +818,8 @@ void BM_mesh_calc_uvs_grid(BMesh *bm, break; } - luv->uv[0] = x; - luv->uv[1] = y; + luv[0] = x; + luv[1] = y; } x += dx; @@ -836,7 +836,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op) const int seg = BMO_slot_int_get(op->slots_in, "u_segments"); const int tot = BMO_slot_int_get(op->slots_in, "v_segments"); - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2); const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs"); BMOperator bmop, prevop; @@ -955,7 +955,7 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op) const float rad_div = rad / 200.0f; const int subdiv = BMO_slot_int_get(op->slots_in, "subdivisions"); - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2); const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs"); BMVert *eva[12]; @@ -1000,9 +1000,9 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op) if (calc_uvs) { int loop_index; BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, loop_index) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->uv[0] = icouvs[uvi][0]; - luv->uv[1] = icouvs[uvi][1]; + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + luv[0] = icouvs[uvi][0]; + luv[1] = icouvs[uvi][1]; uvi++; } } @@ -1063,7 +1063,7 @@ static void bm_mesh_calc_uvs_sphere_face(BMFace *f, const int cd_loop_uv_offset) avgy /= 3.0f; BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, loop_index) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); float x = l->v->co[0]; float y = l->v->co[1]; float z = l->v->co[2]; @@ -1084,10 +1084,10 @@ static void bm_mesh_calc_uvs_sphere_face(BMFace *f, const int cd_loop_uv_offset) } float phi = saacos(z / len); - luv->uv[0] = 0.5f + theta / ((float)M_PI * 2); - luv->uv[1] = 1.0f - phi / (float)M_PI; + luv[0] = 0.5f + theta / ((float)M_PI * 2); + luv[1] = 1.0f - phi / (float)M_PI; - uvs[loop_index] = luv->uv; + uvs[loop_index] = luv; } /* Fix awkwardly-wrapping UVs */ @@ -1133,9 +1133,9 @@ void BM_mesh_calc_uvs_sphere(BMesh *bm, const short oflag, const int cd_loop_uv_ continue; } BM_ITER_ELEM_INDEX (l, &iter2, f, BM_LOOPS_OF_FACE, loop_index) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (luv->uv[0] < minx) { - minx = luv->uv[0]; + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + if (luv[0] < minx) { + minx = luv[0]; } } } @@ -1145,8 +1145,8 @@ void BM_mesh_calc_uvs_sphere(BMesh *bm, const short oflag, const int cd_loop_uv_ continue; } BM_ITER_ELEM_INDEX (l, &iter2, f, BM_LOOPS_OF_FACE, loop_index) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->uv[0] -= minx; + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + luv[0] -= minx; } } } @@ -1159,7 +1159,7 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op) BMO_slot_mat4_get(op->slots_in, "matrix", mat); - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2); const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs"); for (i = 0; i < monkeynv; i++) { @@ -1213,15 +1213,15 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op) BMLoop *l; BMIter liter; BM_ITER_ELEM (l, &liter, f_new_a, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->uv[0] = monkeyuvs[uvi * 2 + 0]; - luv->uv[1] = monkeyuvs[uvi * 2 + 1]; + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + luv[0] = monkeyuvs[uvi * 2 + 0]; + luv[1] = monkeyuvs[uvi * 2 + 1]; uvi++; } BM_ITER_ELEM (l, &liter, f_new_b, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->uv[0] = monkeyuvs[uvi * 2 + 0]; - luv->uv[1] = monkeyuvs[uvi * 2 + 1]; + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + luv[0] = monkeyuvs[uvi * 2 + 0]; + luv[1] = monkeyuvs[uvi * 2 + 1]; uvi++; } } @@ -1239,7 +1239,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op) const bool cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends"); const bool cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris"); - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2); const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs"); BMVert *v1, *lastv1 = NULL, *cent1, *firstv1 = NULL; @@ -1335,7 +1335,7 @@ void BM_mesh_calc_uvs_circle( } BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); float uv_vco[3]; copy_v3_v3(uv_vco, l->v->co); @@ -1343,8 +1343,8 @@ void BM_mesh_calc_uvs_circle( mul_m4_v3(inv_mat, uv_vco); /* then just take those coords for UVs */ - luv->uv[0] = uv_center + uv_scale * uv_vco[0]; - luv->uv[1] = uv_center + uv_scale * uv_vco[1]; + luv[0] = uv_center + uv_scale * uv_vco[0]; + luv[1] = uv_center + uv_scale * uv_vco[1]; } } } @@ -1361,7 +1361,7 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op) const bool cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends"); const bool cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris"); - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2); const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs"); if (!segs) { @@ -1556,7 +1556,7 @@ void BM_mesh_calc_uvs_cone(BMesh *bm, if (f->len == 4 && radius_top && radius_bottom) { /* side face - so unwrap it in a rectangle */ BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, loop_index) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); switch (loop_index) { case 0: @@ -1575,8 +1575,8 @@ void BM_mesh_calc_uvs_cone(BMesh *bm, break; } - luv->uv[0] = x; - luv->uv[1] = y; + luv[0] = x; + luv[1] = y; } } else { @@ -1585,18 +1585,18 @@ void BM_mesh_calc_uvs_cone(BMesh *bm, BM_face_normal_update(f); BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); float uv_vco[3]; mul_v3_m4v3(uv_vco, inv_mat, l->v->co); if (dot_v3v3(f->no, local_up) > 0.0f) { /* if this is a top face of the cone */ - luv->uv[0] = uv_center_x_top + uv_vco[0] * uv_scale_top; - luv->uv[1] = uv_center_y + uv_vco[1] * uv_scale_top; + luv[0] = uv_center_x_top + uv_vco[0] * uv_scale_top; + luv[1] = uv_center_y + uv_vco[1] * uv_scale_top; } else { - luv->uv[0] = uv_center_x_bottom + uv_vco[0] * uv_scale_bottom; - luv->uv[1] = uv_center_y + uv_vco[1] * uv_scale_bottom; + luv[0] = uv_center_x_bottom + uv_vco[0] * uv_scale_bottom; + luv[1] = uv_center_y + uv_vco[1] * uv_scale_bottom; } } } @@ -1609,7 +1609,7 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op) float mat[4][4]; float off = BMO_slot_float_get(op->slots_in, "size") / 2.0f; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2); const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs"); /* rotation order set to match 'BM_mesh_calc_uvs_cube' */ @@ -1670,7 +1670,7 @@ void BM_mesh_calc_uvs_cube(BMesh *bm, const short oflag) BMIter fiter, liter; const float width = 0.25f; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2); float x = 0.375f; float y = 0.0f; @@ -1685,10 +1685,10 @@ void BM_mesh_calc_uvs_cube(BMesh *bm, const short oflag) } BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, loop_index) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); - luv->uv[0] = x; - luv->uv[1] = y; + luv[0] = x; + luv[1] = y; switch (loop_index) { case 0: diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index d88f3112a71..a821fa2b744 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -462,56 +462,56 @@ void bmo_rotate_uvs_exec(BMesh *bm, BMOperator *op) BMIter l_iter; /* iteration loop */ const bool use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw"); - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2); if (cd_loop_uv_offset != -1) { BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) { if (use_ccw == false) { /* same loops direction */ BMLoop *lf; /* current face loops */ - MLoopUV *f_luv; /* first face loop uv */ + float *f_luv; /* first face loop uv */ float p_uv[2]; /* previous uvs */ float t_uv[2]; /* temp uvs */ int n = 0; BM_ITER_ELEM (lf, &l_iter, fs, BM_LOOPS_OF_FACE) { /* current loop uv is the previous loop uv */ - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(lf, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(lf, cd_loop_uv_offset); if (n == 0) { f_luv = luv; - copy_v2_v2(p_uv, luv->uv); + copy_v2_v2(p_uv, luv); } else { - copy_v2_v2(t_uv, luv->uv); - copy_v2_v2(luv->uv, p_uv); + copy_v2_v2(t_uv, luv); + copy_v2_v2(luv, p_uv); copy_v2_v2(p_uv, t_uv); } n++; } - copy_v2_v2(f_luv->uv, p_uv); + copy_v2_v2(f_luv, p_uv); } - else { /* counter loop direction */ - BMLoop *lf; /* current face loops */ - MLoopUV *p_luv; /* previous loop uv */ - MLoopUV *luv; + else { /* counter loop direction */ + BMLoop *lf; /* current face loops */ + float *p_luv; /* previous loop uv */ + float *luv; float t_uv[2]; /* current uvs */ int n = 0; BM_ITER_ELEM (lf, &l_iter, fs, BM_LOOPS_OF_FACE) { /* previous loop uv is the current loop uv */ - luv = BM_ELEM_CD_GET_VOID_P(lf, cd_loop_uv_offset); + luv = BM_ELEM_CD_GET_FLOAT_P(lf, cd_loop_uv_offset); if (n == 0) { p_luv = luv; - copy_v2_v2(t_uv, luv->uv); + copy_v2_v2(t_uv, luv); } else { - copy_v2_v2(p_luv->uv, luv->uv); + copy_v2_v2(p_luv, luv); p_luv = luv; } n++; } - copy_v2_v2(luv->uv, t_uv); + copy_v2_v2(luv, t_uv); } } } @@ -530,22 +530,22 @@ static void bm_face_reverse_uvs(BMFace *f, const int cd_loop_uv_offset) float(*uvs)[2] = BLI_array_alloca(uvs, f->len); BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - copy_v2_v2(uvs[i], luv->uv); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + copy_v2_v2(uvs[i], luv); } /* now that we have the uvs in the array, reverse! */ BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) { /* current loop uv is the previous loop uv */ - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - copy_v2_v2(luv->uv, uvs[(f->len - i - 1)]); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + copy_v2_v2(luv, uvs[(f->len - i - 1)]); } } void bmo_reverse_uvs_exec(BMesh *bm, BMOperator *op) { BMOIter iter; BMFace *f; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2); if (cd_loop_uv_offset != -1) { BMO_ITER (f, &iter, op->slots_in, "faces", BM_FACE) { diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index fbc47505924..330a66e5800 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -811,7 +811,7 @@ static void math_layer_info_init(BevelParams *bp, BMesh *bm) bp->math_layer_info.has_math_layers = false; bp->math_layer_info.face_component = NULL; for (int i = 0; i < bm->ldata.totlayer; i++) { - if (CustomData_has_layer(&bm->ldata, CD_MLOOPUV)) { + if (CustomData_has_layer(&bm->ldata, CD_PROP_FLOAT2)) { bp->math_layer_info.has_math_layers = true; break; } @@ -1009,10 +1009,10 @@ static BMFace *choose_rep_face(BevelParams *bp, BMFace **face, int nfaces) * Caller should ensure that no seams are violated by doing this. */ static void bev_merge_uvs(BMesh *bm, BMVert *v) { - int num_of_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV); + int num_of_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_PROP_FLOAT2); for (int i = 0; i < num_of_uv_layers; i++) { - int cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, i); + int cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, i); if (cd_loop_uv_offset == -1) { return; @@ -1023,15 +1023,15 @@ static void bev_merge_uvs(BMesh *bm, BMVert *v) BMIter iter; BMLoop *l; BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - add_v2_v2(uv, luv->uv); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + add_v2_v2(uv, luv); n++; } if (n > 1) { mul_v2_fl(uv, 1.0f / (float)n); BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - copy_v2_v2(luv->uv, uv); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + copy_v2_v2(luv, uv); } } } @@ -1041,7 +1041,7 @@ static void bev_merge_uvs(BMesh *bm, BMVert *v) * and part of faces that share edge bme. */ static void bev_merge_edge_uvs(BMesh *bm, BMEdge *bme, BMVert *v) { - int num_of_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV); + int num_of_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_PROP_FLOAT2); BMLoop *l1 = NULL; BMLoop *l2 = NULL; @@ -1060,22 +1060,22 @@ static void bev_merge_edge_uvs(BMesh *bm, BMEdge *bme, BMVert *v) } for (int i = 0; i < num_of_uv_layers; i++) { - int cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, i); + int cd_loop_uv_offset = CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, i); if (cd_loop_uv_offset == -1) { return; } float uv[2] = {0.0f, 0.0f}; - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l1, cd_loop_uv_offset); - add_v2_v2(uv, luv->uv); - luv = BM_ELEM_CD_GET_VOID_P(l2, cd_loop_uv_offset); - add_v2_v2(uv, luv->uv); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l1, cd_loop_uv_offset); + add_v2_v2(uv, luv); + luv = BM_ELEM_CD_GET_FLOAT_P(l2, cd_loop_uv_offset); + add_v2_v2(uv, luv); mul_v2_fl(uv, 0.5f); - luv = BM_ELEM_CD_GET_VOID_P(l1, cd_loop_uv_offset); - copy_v2_v2(luv->uv, uv); - luv = BM_ELEM_CD_GET_VOID_P(l2, cd_loop_uv_offset); - copy_v2_v2(luv->uv, uv); + luv = BM_ELEM_CD_GET_FLOAT_P(l1, cd_loop_uv_offset); + copy_v2_v2(luv, uv); + luv = BM_ELEM_CD_GET_FLOAT_P(l2, cd_loop_uv_offset); + copy_v2_v2(luv, uv); } } diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c index 8a11815bd4c..11adeaf5c10 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c +++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c @@ -289,14 +289,14 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, int i; if (delimit & BMO_DELIM_UV) { - const int layer_len = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV); + const int layer_len = CustomData_number_of_layers(&bm->ldata, CD_PROP_FLOAT2); if (layer_len == 0) { delimit &= ~BMO_DELIM_UV; } else { - delimit_data.cd_loop_type = CD_MLOOPUV; + delimit_data.cd_loop_type = CD_PROP_FLOAT2; delimit_data.cd_loop_size = CustomData_sizeof(delimit_data.cd_loop_type); - delimit_data.cd_loop_offset = CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, 0); + delimit_data.cd_loop_offset = CustomData_get_n_offset(&bm->ldata, CD_PROP_FLOAT2, 0); delimit_data.cd_loop_offset_end = delimit_data.cd_loop_size * layer_len; } } diff --git a/source/blender/bmesh/tools/bmesh_path_uv.c b/source/blender/bmesh/tools/bmesh_path_uv.c index ecc92fd09a4..26726fe4bac 100644 --- a/source/blender/bmesh/tools/bmesh_path_uv.c +++ b/source/blender/bmesh/tools/bmesh_path_uv.c @@ -67,23 +67,23 @@ static void verttag_add_adjacent_uv(HeapSimple *heap, BLI_assert(params->aspect_y != 0.0f); const int cd_loop_uv_offset = params->cd_loop_uv_offset; const int l_a_index = BM_elem_index_get(l_a); - const MLoopUV *luv_a = BM_ELEM_CD_GET_VOID_P(l_a, cd_loop_uv_offset); - const float uv_a[2] = {luv_a->uv[0], luv_a->uv[1] / params->aspect_y}; + const float *luv_a = BM_ELEM_CD_GET_FLOAT_P(l_a, cd_loop_uv_offset); + const float uv_a[2] = {luv_a[0], luv_a[1] / params->aspect_y}; { BMIter liter; BMLoop *l; /* Loop over faces of face, but do so by first looping over loops. */ BM_ITER_ELEM (l, &liter, l_a->v, BM_LOOPS_OF_VERT) { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (equals_v2v2(luv_a->uv, luv->uv)) { + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + if (equals_v2v2(luv_a, luv)) { /* 'l_a' is already tagged, tag all adjacent. */ BM_elem_flag_enable(l, BM_ELEM_TAG); BMLoop *l_b = l->next; do { if (!BM_elem_flag_test(l_b, BM_ELEM_TAG)) { - const MLoopUV *luv_b = BM_ELEM_CD_GET_VOID_P(l_b, cd_loop_uv_offset); - const float uv_b[2] = {luv_b->uv[0], luv_b->uv[1] / params->aspect_y}; + const float *luv_b = BM_ELEM_CD_GET_FLOAT_P(l_b, cd_loop_uv_offset); + const float uv_b[2] = {luv_b[0], luv_b[1] / params->aspect_y}; /* We know 'l_b' is not visited, check it out! */ const int l_b_index = BM_elem_index_get(l_b); const float cost_cut = params->use_topology_distance ? 1.0f : len_v2v2(uv_a, uv_b); @@ -189,13 +189,13 @@ static float edgetag_cut_cost_vert_uv( BMLoop *l_v1 = (l_v->v == l_e_a->v) ? l_e_a->next : l_e_a; BMLoop *l_v2 = (l_v->v == l_e_b->v) ? l_e_b->next : l_e_b; - MLoopUV *luv_v1 = BM_ELEM_CD_GET_VOID_P(l_v1, cd_loop_uv_offset); - MLoopUV *luv_v2 = BM_ELEM_CD_GET_VOID_P(l_v2, cd_loop_uv_offset); - MLoopUV *luv_v = BM_ELEM_CD_GET_VOID_P(l_v, cd_loop_uv_offset); + float *luv_v1 = BM_ELEM_CD_GET_FLOAT_P(l_v1, cd_loop_uv_offset); + float *luv_v2 = BM_ELEM_CD_GET_FLOAT_P(l_v2, cd_loop_uv_offset); + float *luv_v = BM_ELEM_CD_GET_FLOAT_P(l_v, cd_loop_uv_offset); - float uv_v1[2] = {luv_v1->uv[0], luv_v1->uv[1] / aspect_y}; - float uv_v2[2] = {luv_v2->uv[0], luv_v2->uv[1] / aspect_y}; - float uv_v[2] = {luv_v->uv[0], luv_v->uv[1] / aspect_y}; + float uv_v1[2] = {luv_v1[0], luv_v1[1] / aspect_y}; + float uv_v2[2] = {luv_v2[0], luv_v2[1] / aspect_y}; + float uv_v[2] = {luv_v[0], luv_v[1] / aspect_y}; return step_cost_3_v2(uv_v1, uv_v, uv_v2); } @@ -204,11 +204,11 @@ static float edgetag_cut_cost_face_uv( BMLoop *l_e_a, BMLoop *l_e_b, BMFace *f, const float aspect_v2[2], const int cd_loop_uv_offset) { float l_e_a_cent[2], l_e_b_cent[2], f_cent[2]; - MLoopUV *luv_e_a = BM_ELEM_CD_GET_VOID_P(l_e_a, cd_loop_uv_offset); - MLoopUV *luv_e_b = BM_ELEM_CD_GET_VOID_P(l_e_b, cd_loop_uv_offset); + float *luv_e_a = BM_ELEM_CD_GET_FLOAT_P(l_e_a, cd_loop_uv_offset); + float *luv_e_b = BM_ELEM_CD_GET_FLOAT_P(l_e_b, cd_loop_uv_offset); - mid_v2_v2v2(l_e_a_cent, luv_e_a->uv, luv_e_a->uv); - mid_v2_v2v2(l_e_b_cent, luv_e_b->uv, luv_e_b->uv); + mid_v2_v2v2(l_e_a_cent, luv_e_a, luv_e_a); + mid_v2_v2v2(l_e_b_cent, luv_e_b, luv_e_b); mul_v2_v2(l_e_a_cent, aspect_v2); mul_v2_v2(l_e_b_cent, aspect_v2); @@ -397,9 +397,8 @@ static float facetag_cut_cost_edge_uv(BMFace *f_a, BM_face_uv_calc_center_median_weighted(f_a, aspect_v2, cd_loop_uv_offset, f_a_cent); BM_face_uv_calc_center_median_weighted(f_b, aspect_v2, cd_loop_uv_offset, f_b_cent); - const float *co_v1 = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_edge, cd_loop_uv_offset))->uv; - const float *co_v2 = - ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_edge->next, cd_loop_uv_offset))->uv; + const float *co_v1 = BM_ELEM_CD_GET_FLOAT_P(l_edge, cd_loop_uv_offset); + const float *co_v2 = BM_ELEM_CD_GET_FLOAT_P(l_edge->next, cd_loop_uv_offset); #if 0 mid_v2_v2v2(e_cent, co_v1, co_v2); @@ -444,7 +443,7 @@ static float facetag_cut_cost_vert_uv(BMFace *f_a, BM_face_uv_calc_center_median_weighted(f_a, aspect_v2, cd_loop_uv_offset, f_a_cent); BM_face_uv_calc_center_median_weighted(f_b, aspect_v2, cd_loop_uv_offset, f_b_cent); - copy_v2_v2(v_cent, ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_vert, cd_loop_uv_offset))->uv); + copy_v2_v2(v_cent, BM_ELEM_CD_GET_FLOAT_P(l_vert, cd_loop_uv_offset)); mul_v2_v2(f_a_cent, aspect_v2); mul_v2_v2(f_b_cent, aspect_v2); diff --git a/source/blender/draw/engines/overlay/overlay_edit_uv.cc b/source/blender/draw/engines/overlay/overlay_edit_uv.cc index 44e657b253e..fbe5e24112b 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_uv.cc +++ b/source/blender/draw/engines/overlay/overlay_edit_uv.cc @@ -442,10 +442,11 @@ static void overlay_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob) const DRWContextState *draw_ctx = DRW_context_state_get(); const bool is_edit_object = DRW_object_is_in_edit_mode(ob); Mesh *me = (Mesh *)ob->data; - const bool has_active_object_uvmap = CustomData_get_active_layer(&me->ldata, CD_MLOOPUV) != -1; + const bool has_active_object_uvmap = CustomData_get_active_layer(&me->ldata, CD_PROP_FLOAT2) != + -1; const bool has_active_edit_uvmap = is_edit_object && (CustomData_get_active_layer(&me->edit_mesh->bm->ldata, - CD_MLOOPUV) != -1); + CD_PROP_FLOAT2) != -1); const bool draw_shadows = (draw_ctx->object_mode != OB_MODE_OBJECT) && (ob->mode == draw_ctx->object_mode); diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c index 15a16539a26..830a9213f5a 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.c +++ b/source/blender/draw/engines/workbench/workbench_engine.c @@ -297,7 +297,7 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd, if (ob->dt < OB_TEXTURE) { color_type = V3D_SHADING_MATERIAL_COLOR; } - else if ((me == NULL) || !CustomData_has_layer(ldata, CD_MLOOPUV)) { + else if ((me == NULL) || !CustomData_has_layer(ldata, CD_PROP_FLOAT2)) { /* Disable color mode if data layer is unavailable. */ color_type = V3D_SHADING_MATERIAL_COLOR; } @@ -322,7 +322,7 @@ static eV3DShadingColorType workbench_color_type_get(WORKBENCH_PrivateData *wpd, if (!is_sculpt_pbvh && !is_render) { /* Force texture or vertex mode if object is in paint mode. */ - if (is_texpaint_mode && me && CustomData_has_layer(ldata, CD_MLOOPUV)) { + if (is_texpaint_mode && me && CustomData_has_layer(ldata, CD_PROP_FLOAT2)) { color_type = V3D_SHADING_TEXTURE_COLOR; if (r_texpaint_mode) { *r_texpaint_mode = true; diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 00ac2563c43..f1f62d8aee9 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -3371,7 +3371,7 @@ void DRW_cdlayer_attr_aliases_add(GPUVertFormat *format, /* Active render layer name. */ if (is_active_render) { - GPU_vertformat_alias_add(format, cl->type == CD_MLOOPUV ? "a" : base_name); + GPU_vertformat_alias_add(format, cl->type == CD_PROP_FLOAT2 ? "a" : base_name); } /* Active display layer name. */ diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc index 15057af2472..54385250884 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.cc +++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc @@ -252,7 +252,7 @@ static void mesh_cd_calc_active_uv_layer(const Object *object, { const Mesh *me_final = editmesh_final_or_this(object, me); const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final); - int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV); + int layer = CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2); if (layer != -1) { cd_used->uv |= (1 << layer); } @@ -264,7 +264,7 @@ static void mesh_cd_calc_active_mask_uv_layer(const Object *object, { const Mesh *me_final = editmesh_final_or_this(object, me); const CustomData *cd_ldata = mesh_cd_ldata_get_from_mesh(me_final); - int layer = CustomData_get_stencil_layer(cd_ldata, CD_MLOOPUV); + int layer = CustomData_get_stencil_layer(cd_ldata, CD_PROP_FLOAT2); if (layer != -1) { cd_used->uv |= (1 << layer); } @@ -312,7 +312,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, * We do it based on the specified name. */ if (name[0] != '\0') { - layer = CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name); + layer = CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, name); type = CD_MTFACE; #if 0 /* Tangents are always from UV's - this will never happen. */ @@ -354,8 +354,9 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, switch (type) { case CD_MTFACE: { if (layer == -1) { - layer = (name[0] != '\0') ? CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name) : - CustomData_get_render_layer(cd_ldata, CD_MLOOPUV); + layer = (name[0] != '\0') ? + CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, name) : + CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2); } if (layer != -1) { cd_used.uv |= (1 << layer); @@ -364,12 +365,13 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, } case CD_TANGENT: { if (layer == -1) { - layer = (name[0] != '\0') ? CustomData_get_named_layer(cd_ldata, CD_MLOOPUV, name) : - CustomData_get_render_layer(cd_ldata, CD_MLOOPUV); + layer = (name[0] != '\0') ? + CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, name) : + CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2); /* Only fallback to orco (below) when we have no UV layers, see: T56545 */ if (layer == -1 && name[0] != '\0') { - layer = CustomData_get_render_layer(cd_ldata, CD_MLOOPUV); + layer = CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2); } } if (layer != -1) { diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index e1d63158b0b..d2f9a634922 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -833,10 +833,10 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; if (psmd != NULL && psmd->mesh_final != NULL) { - if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPUV)) { - cache->num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV); - active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPUV); - render_uv = CustomData_get_render_layer(&psmd->mesh_final->ldata, CD_MLOOPUV); + if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_PROP_FLOAT2)) { + cache->num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_PROP_FLOAT2); + active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_PROP_FLOAT2); + render_uv = CustomData_get_render_layer(&psmd->mesh_final->ldata, CD_PROP_FLOAT2); } if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR)) { cache->num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, @@ -897,7 +897,7 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit GPU_vertbuf_attr_get_raw_data(cache->proc_uv_buf[i], uv_id, &uv_step[i]); char attr_safe_name[GPU_MAX_SAFE_ATTR_NAME]; - const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i); + const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_PROP_FLOAT2, i); GPU_vertformat_safe_attr_name(name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME); int n = 0; @@ -1170,9 +1170,9 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, MCol **parent_mcol = NULL; if (psmd != NULL) { - if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPUV)) { - num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV); - active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPUV); + if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_PROP_FLOAT2)) { + num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_PROP_FLOAT2); + active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_PROP_FLOAT2); } if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR)) { num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_PROP_BYTE_COLOR); @@ -1198,7 +1198,7 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, for (int i = 0; i < num_uv_layers; i++) { char uuid[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME]; - const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i); + const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_PROP_FLOAT2, i); GPU_vertformat_safe_attr_name(name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME); BLI_snprintf(uuid, sizeof(uuid), "a%s", attr_safe_name); diff --git a/source/blender/draw/intern/draw_manager_data.cc b/source/blender/draw/intern/draw_manager_data.cc index c7b1ddffab3..5b4e0792577 100644 --- a/source/blender/draw/intern/draw_manager_data.cc +++ b/source/blender/draw/intern/draw_manager_data.cc @@ -1422,11 +1422,11 @@ void DRW_shgroup_call_sculpt(DRWShadingGroup *shgroup, } if (use_uv) { - int layer_i = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); + int layer_i = CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2); if (layer_i != -1) { CustomDataLayer *layer = me->ldata.layers + layer_i; - attrs[attrs_num].type = CD_MLOOPUV; + attrs[attrs_num].type = CD_PROP_FLOAT2; attrs[attrs_num].domain = ATTR_DOMAIN_CORNER; BLI_strncpy(attrs[attrs_num].name, layer->name, sizeof(attrs[attrs_num].name)); @@ -1483,11 +1483,11 @@ void DRW_shgroup_call_sculpt_with_materials(DRWShadingGroup **shgroups, for (uint i = 0; i < 32; i++) { if (cd_needed.uv & (1 << i)) { - int layer_i = CustomData_get_layer_index_n(&me->ldata, CD_MLOOPUV, i); + int layer_i = CustomData_get_layer_index_n(&me->ldata, CD_PROP_FLOAT2, i); CustomDataLayer *layer = layer_i != -1 ? me->ldata.layers + layer_i : nullptr; if (layer) { - attrs[attrs_i].type = CD_MLOOPUV; + attrs[attrs_i].type = CD_PROP_FLOAT2; attrs[attrs_i].domain = ATTR_DOMAIN_CORNER; BLI_strncpy(attrs[attrs_i].name, layer->name, sizeof(PBVHAttrReq::name)); attrs_i++; diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index b212e29ccff..42e2686df82 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -76,7 +76,7 @@ static bool valid_pbvh_attr(int type) case CD_PBVH_MASK_TYPE: case CD_PROP_COLOR: case CD_PROP_BYTE_COLOR: - case CD_MLOOPUV: + case CD_PROP_FLOAT2: return true; } @@ -651,15 +651,6 @@ struct PBVHBatches { break; } - case CD_MLOOPUV: { - MLoopUV *mloopuv = static_cast( - CustomData_get_layer_named(args->ldata, CD_MLOOPUV, vbo.name.c_str())); - - foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const MLoopTri *tri) { - *static_cast(GPU_vertbuf_raw_step(&access)) = mloopuv[tri->tri[tri_i]].uv; - }); - break; - } case CD_PROP_COLOR: if (vbo.domain == ATTR_DOMAIN_POINT) { MPropCol *mpropcol = static_cast( @@ -881,10 +872,6 @@ struct PBVHBatches { GPU_vertformat_attr_add(&format, "a", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); need_aliases = true; break; - case CD_MLOOPUV: - GPU_vertformat_attr_add(&format, "uvs", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - need_aliases = true; - break; case CD_PBVH_FSET_TYPE: GPU_vertformat_attr_add(&format, "fset", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); break; @@ -924,7 +911,7 @@ struct PBVHBatches { } else { switch (type) { - case CD_MLOOPUV: + case CD_PROP_FLOAT2: prefix = "u"; break; default: diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh.cc index ec7d3a933b4..72d7c31110f 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.cc @@ -91,7 +91,7 @@ const MeshExtract *mesh_extract_override_get(const MeshExtract *extractor, void mesh_render_data_face_flag(const MeshRenderData *mr, const BMFace *efa, - const int cd_ofs, + const BMUVOffsets offsets, EditLoopData *eattr) { if (efa == mr->efa_act) { @@ -104,7 +104,7 @@ void mesh_render_data_face_flag(const MeshRenderData *mr, if (efa == mr->efa_act_uv) { eattr->v_flag |= VFLAG_FACE_UV_ACTIVE; } - if ((cd_ofs != -1) && uvedit_face_select_test_ex(mr->toolsettings, (BMFace *)efa, cd_ofs)) { + if ((offsets.uv != -1) && uvedit_face_select_test_ex(mr->toolsettings, (BMFace *)efa, offsets)) { eattr->v_flag |= VFLAG_FACE_UV_SELECT; } @@ -121,30 +121,29 @@ void mesh_render_data_face_flag(const MeshRenderData *mr, void mesh_render_data_loop_flag(const MeshRenderData *mr, BMLoop *l, - const int cd_ofs, + const BMUVOffsets offsets, EditLoopData *eattr) { - if (cd_ofs == -1) { + if (offsets.uv == -1) { return; } - MLoopUV *luv = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_ofs); - if (luv != nullptr && (luv->flag & MLOOPUV_PINNED)) { + if (BM_ELEM_CD_GET_BOOL(l, offsets.pin)) { eattr->v_flag |= VFLAG_VERT_UV_PINNED; } - if (uvedit_uv_select_test_ex(mr->toolsettings, l, cd_ofs)) { + if (uvedit_uv_select_test_ex(mr->toolsettings, l, offsets)) { eattr->v_flag |= VFLAG_VERT_UV_SELECT; } } void mesh_render_data_loop_edge_flag(const MeshRenderData *mr, BMLoop *l, - const int cd_ofs, + const BMUVOffsets offsets, EditLoopData *eattr) { - if (cd_ofs == -1) { + if (offsets.uv == -1) { return; } - if (uvedit_edge_select_test_ex(mr->toolsettings, l, cd_ofs)) { + if (uvedit_edge_select_test_ex(mr->toolsettings, l, offsets)) { eattr->v_flag |= VFLAG_EDGE_UV_SELECT; eattr->v_flag |= VFLAG_VERT_UV_SELECT; } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh index e5be3db7726..cd4a4bdb233 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh.hh +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh.hh @@ -389,15 +389,15 @@ const MeshExtract *mesh_extract_override_get(const MeshExtract *extractor, bool do_single_mat); void mesh_render_data_face_flag(const MeshRenderData *mr, const BMFace *efa, - int cd_ofs, + BMUVOffsets offsets, EditLoopData *eattr); void mesh_render_data_loop_flag(const MeshRenderData *mr, BMLoop *l, - int cd_ofs, + BMUVOffsets offsets, EditLoopData *eattr); void mesh_render_data_loop_edge_flag(const MeshRenderData *mr, BMLoop *l, - int cd_ofs, + BMUVOffsets offsets, EditLoopData *eattr); extern const MeshExtract extract_tris; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc index 80365d9da15..c6ba9283084 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edit_data.cc @@ -138,7 +138,7 @@ static void extract_edit_data_iter_poly_bm(const MeshRenderData *mr, EditLoopData *data = vbo_data + l_index; memset(data, 0x0, sizeof(*data)); - mesh_render_data_face_flag(mr, f, -1, data); + mesh_render_data_face_flag(mr, f, {-1, -1, -1, -1}, data); mesh_render_data_edge_flag(mr, l_iter->e, data); mesh_render_data_vert_flag(mr, l_iter->v, data); } while ((l_iter = l_iter->next) != l_first); @@ -161,7 +161,7 @@ static void extract_edit_data_iter_poly_mesh(const MeshRenderData *mr, BMEdge *eed = bm_original_edge_get(mr, ml->e); BMVert *eve = bm_original_vert_get(mr, ml->v); if (efa) { - mesh_render_data_face_flag(mr, efa, -1, data); + mesh_render_data_face_flag(mr, efa, {-1, -1, -1, -1}, data); } if (eed) { mesh_render_data_edge_flag(mr, eed, data); @@ -288,7 +288,7 @@ static void extract_edit_data_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache, /* coarse_quad can be null when called by the mesh iteration below. */ if (coarse_quad) { /* The -1 parameter is for edit_uvs, which we don't do here. */ - mesh_render_data_face_flag(mr, coarse_quad, -1, edit_loop_data); + mesh_render_data_face_flag(mr, coarse_quad, {-1, -1, -1, -1}, edit_loop_data); } } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc index 3ebf2daf1e9..6e55cca37d2 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_data.cc @@ -19,7 +19,7 @@ namespace blender::draw { struct MeshExtract_EditUVData_Data { EditLoopData *vbo_data; - int cd_ofs; + BMUVOffsets offsets; }; static void extract_edituv_data_init_common(const MeshRenderData *mr, @@ -37,9 +37,8 @@ static void extract_edituv_data_init_common(const MeshRenderData *mr, GPU_vertbuf_init_with_format(vbo, &format); GPU_vertbuf_data_alloc(vbo, loop_len); - CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata; data->vbo_data = (EditLoopData *)GPU_vertbuf_get_data(vbo); - data->cd_ofs = CustomData_get_offset(cd_ldata, CD_MLOOPUV); + data->offsets = BM_uv_map_get_offsets(mr->bm); } static void extract_edituv_data_init(const MeshRenderData *mr, @@ -64,9 +63,9 @@ static void extract_edituv_data_iter_poly_bm(const MeshRenderData *mr, MeshExtract_EditUVData_Data *data = static_cast(_data); EditLoopData *eldata = &data->vbo_data[l_index]; memset(eldata, 0x0, sizeof(*eldata)); - mesh_render_data_loop_flag(mr, l_iter, data->cd_ofs, eldata); - mesh_render_data_face_flag(mr, f, data->cd_ofs, eldata); - mesh_render_data_loop_edge_flag(mr, l_iter, data->cd_ofs, eldata); + mesh_render_data_loop_flag(mr, l_iter, data->offsets, eldata); + mesh_render_data_face_flag(mr, f, data->offsets, eldata); + mesh_render_data_loop_edge_flag(mr, l_iter, data->offsets, eldata); } while ((l_iter = l_iter->next) != l_first); } @@ -90,8 +89,8 @@ static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr, if (eed && eve) { /* Loop on an edge endpoint. */ BMLoop *l = BM_face_edge_share_loop(efa, eed); - mesh_render_data_loop_flag(mr, l, data->cd_ofs, eldata); - mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, eldata); + mesh_render_data_loop_flag(mr, l, data->offsets, eldata); + mesh_render_data_loop_edge_flag(mr, l, data->offsets, eldata); } else { if (eed == nullptr) { @@ -105,7 +104,7 @@ static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr, if (eed) { /* Mapped points on an edge between two edit verts. */ BMLoop *l = BM_face_edge_share_loop(efa, eed); - mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, eldata); + mesh_render_data_loop_edge_flag(mr, l, data->offsets, eldata); } } } @@ -146,8 +145,8 @@ static void extract_edituv_data_iter_subdiv_bm(const DRWSubdivCache *subdiv_cach BMEdge *eed = BM_edge_at_index(mr->bm, edge_origindex); /* Loop on an edge endpoint. */ BMLoop *l = BM_face_edge_share_loop(const_cast(coarse_quad), eed); - mesh_render_data_loop_flag(mr, l, data->cd_ofs, edit_loop_data); - mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, edit_loop_data); + mesh_render_data_loop_flag(mr, l, data->offsets, edit_loop_data); + mesh_render_data_loop_edge_flag(mr, l, data->offsets, edit_loop_data); } else { if (edge_origindex == -1) { @@ -160,11 +159,11 @@ static void extract_edituv_data_iter_subdiv_bm(const DRWSubdivCache *subdiv_cach /* Mapped points on an edge between two edit verts. */ BMEdge *eed = BM_edge_at_index(mr->bm, edge_origindex); BMLoop *l = BM_face_edge_share_loop(const_cast(coarse_quad), eed); - mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, edit_loop_data); + mesh_render_data_loop_edge_flag(mr, l, data->offsets, edit_loop_data); } } - mesh_render_data_face_flag(mr, coarse_quad, data->cd_ofs, edit_loop_data); + mesh_render_data_face_flag(mr, coarse_quad, data->offsets, edit_loop_data); } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc index 88de5fafe63..5edda1567b4 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc @@ -9,6 +9,8 @@ #include "BKE_mesh.h" +#include "BLI_math_vector_types.hh" + #include "extract_mesh.hh" #include "draw_subdivision.h" @@ -26,7 +28,7 @@ struct UVStretchAngle { struct MeshExtract_StretchAngle_Data { UVStretchAngle *vbo_data; - const MLoopUV *luv; + const float2 *uv; float auv[2][2], last_auv[2]; float av[2][3], last_av[3]; int cd_ofs; @@ -94,11 +96,11 @@ static void extract_edituv_stretch_angle_init(const MeshRenderData *mr, /* Special iterator needed to save about half of the computing cost. */ if (mr->extract_type == MR_EXTRACT_BMESH) { - data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_MLOOPUV); + data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_PROP_FLOAT2); } else { BLI_assert(mr->extract_type == MR_EXTRACT_MESH); - data->luv = (const MLoopUV *)CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV); + data->uv = (const float2 *)CustomData_get_layer(&mr->me->ldata, CD_PROP_FLOAT2); } } @@ -115,18 +117,18 @@ static void extract_edituv_stretch_angle_iter_poly_bm(const MeshRenderData *mr, do { const int l_index = BM_elem_index_get(l_iter); - const MLoopUV *luv, *luv_next; + const float(*luv)[2], (*luv_next)[2]; BMLoop *l_next = l_iter->next; if (l_iter == BM_FACE_FIRST_LOOP(f)) { /* First loop in face. */ BMLoop *l_tmp = l_iter->prev; BMLoop *l_next_tmp = l_iter; - luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_tmp, data->cd_ofs); - luv_next = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_next_tmp, data->cd_ofs); + luv = BM_ELEM_CD_GET_FLOAT2_P(l_tmp, data->cd_ofs); + luv_next = BM_ELEM_CD_GET_FLOAT2_P(l_next_tmp, data->cd_ofs); compute_normalize_edge_vectors(auv, av, - luv->uv, - luv_next->uv, + *luv, + *luv_next, bm_vert_co_get(mr, l_tmp->v), bm_vert_co_get(mr, l_next_tmp->v)); /* Save last edge. */ @@ -142,14 +144,10 @@ static void extract_edituv_stretch_angle_iter_poly_bm(const MeshRenderData *mr, copy_v3_v3(av[1], last_av); } else { - luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, data->cd_ofs); - luv_next = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_next, data->cd_ofs); - compute_normalize_edge_vectors(auv, - av, - luv->uv, - luv_next->uv, - bm_vert_co_get(mr, l_iter->v), - bm_vert_co_get(mr, l_next->v)); + luv = BM_ELEM_CD_GET_FLOAT2_P(l_iter, data->cd_ofs); + luv_next = BM_ELEM_CD_GET_FLOAT2_P(l_next, data->cd_ofs); + compute_normalize_edge_vectors( + auv, av, *luv, *luv_next, bm_vert_co_get(mr, l_iter->v), bm_vert_co_get(mr, l_next->v)); } edituv_get_edituv_stretch_angle(auv, av, &data->vbo_data[l_index]); } while ((l_iter = l_iter->next) != l_first); @@ -173,8 +171,8 @@ static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr const int l_next_tmp = mp->loopstart; compute_normalize_edge_vectors(auv, av, - data->luv[ml_index_last].uv, - data->luv[l_next_tmp].uv, + data->uv[ml_index_last], + data->uv[l_next_tmp], mr->vert_positions[mr->mloop[ml_index_last].v], mr->vert_positions[mr->mloop[l_next_tmp].v]); /* Save last edge. */ @@ -193,8 +191,8 @@ static void extract_edituv_stretch_angle_iter_poly_mesh(const MeshRenderData *mr else { compute_normalize_edge_vectors(auv, av, - data->luv[ml_index].uv, - data->luv[l_next].uv, + data->uv[ml_index], + data->uv[l_next], mr->vert_positions[mr->mloop[ml_index].v], mr->vert_positions[mr->mloop[l_next].v]); } @@ -249,7 +247,7 @@ static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache *subdi uint32_t uv_layers = cache->cd_used.uv; /* HACK to fix T68857 */ if (mr->extract_type == MR_EXTRACT_BMESH && cache->cd_used.edit_uv == 1) { - int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV); + int layer = CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2); if (layer != -1) { uv_layers |= (1 << layer); } @@ -258,7 +256,7 @@ static void extract_edituv_stretch_angle_init_subdiv(const DRWSubdivCache *subdi int uvs_offset = 0; for (int i = 0; i < MAX_MTFACE; i++) { if (uv_layers & (1 << i)) { - if (i == CustomData_get_active_layer(cd_ldata, CD_MLOOPUV)) { + if (i == CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2)) { break; } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc index 78b85694ad9..76f1900a7e4 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_area.cc @@ -5,6 +5,8 @@ * \ingroup draw */ +#include "BLI_math_vector_types.hh" + #include "MEM_guardedalloc.h" #include "BKE_mesh.h" @@ -57,7 +59,7 @@ static void compute_area_ratio(const MeshRenderData *mr, if (mr->extract_type == MR_EXTRACT_BMESH) { CustomData *cd_ldata = &mr->bm->ldata; - int uv_ofs = CustomData_get_offset(cd_ldata, CD_MLOOPUV); + int uv_ofs = CustomData_get_offset(cd_ldata, CD_PROP_FLOAT2); BMFace *efa; BMIter f_iter; @@ -72,12 +74,13 @@ static void compute_area_ratio(const MeshRenderData *mr, } else { BLI_assert(mr->extract_type == MR_EXTRACT_MESH); - const MLoopUV *uv_data = (const MLoopUV *)CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV); + const float2 *uv_data = (const float2 *)CustomData_get_layer(&mr->me->ldata, CD_PROP_FLOAT2); const MPoly *mp = mr->mpoly; for (int mp_index = 0; mp_index < mr->poly_len; mp_index++, mp++) { float area = BKE_mesh_calc_poly_area( mp, &mr->mloop[mp->loopstart], reinterpret_cast(mr->vert_positions)); - float uvarea = BKE_mesh_calc_poly_uv_area(mp, uv_data); + float uvarea = area_poly_v2(reinterpret_cast(&uv_data[mp->loopstart]), + mp->totloop); tot_area += area; tot_uv_area += uvarea; r_area_ratio[mp_index] = area_ratio_get(area, uvarea); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc index 55ad2e67487..1ac4512bab0 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_edituv_data.cc @@ -17,7 +17,7 @@ namespace blender::draw { struct MeshExtract_EditUVFdotData_Data { EditLoopData *vbo_data; - int cd_ofs; + BMUVOffsets offsets; }; static void extract_fdots_edituv_data_init(const MeshRenderData *mr, @@ -36,7 +36,7 @@ static void extract_fdots_edituv_data_init(const MeshRenderData *mr, MeshExtract_EditUVFdotData_Data *data = static_cast(tls_data); data->vbo_data = (EditLoopData *)GPU_vertbuf_get_data(vbo); - data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_MLOOPUV); + data->offsets = BM_uv_map_get_offsets(mr->bm); } static void extract_fdots_edituv_data_iter_poly_bm(const MeshRenderData *mr, @@ -47,7 +47,7 @@ static void extract_fdots_edituv_data_iter_poly_bm(const MeshRenderData *mr, MeshExtract_EditUVFdotData_Data *data = static_cast(_data); EditLoopData *eldata = &data->vbo_data[BM_elem_index_get(f)]; memset(eldata, 0x0, sizeof(*eldata)); - mesh_render_data_face_flag(mr, f, data->cd_ofs, eldata); + mesh_render_data_face_flag(mr, f, data->offsets, eldata); } static void extract_fdots_edituv_data_iter_poly_mesh(const MeshRenderData *mr, @@ -60,7 +60,7 @@ static void extract_fdots_edituv_data_iter_poly_mesh(const MeshRenderData *mr, memset(eldata, 0x0, sizeof(*eldata)); BMFace *efa = bm_original_face_get(mr, mp_index); if (efa) { - mesh_render_data_face_flag(mr, efa, data->cd_ofs, eldata); + mesh_render_data_face_flag(mr, efa, data->offsets, eldata); } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc index 802f000cb43..c8d4144f38c 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_fdots_uv.cc @@ -17,7 +17,7 @@ namespace blender::draw { struct MeshExtract_FdotUV_Data { float (*vbo_data)[2]; - const MLoopUV *uv_data; + const float (*uv_data)[2]; int cd_ofs; }; @@ -46,10 +46,10 @@ static void extract_fdots_uv_init(const MeshRenderData *mr, data->vbo_data = (float(*)[2])GPU_vertbuf_get_data(vbo); if (mr->extract_type == MR_EXTRACT_BMESH) { - data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_MLOOPUV); + data->cd_ofs = CustomData_get_offset(&mr->bm->ldata, CD_PROP_FLOAT2); } else { - data->uv_data = (const MLoopUV *)CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV); + data->uv_data = (const float(*)[2])CustomData_get_layer(&mr->me->ldata, CD_PROP_FLOAT2); } } @@ -63,8 +63,8 @@ static void extract_fdots_uv_iter_poly_bm(const MeshRenderData * /*mr*/, l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { float w = 1.0f / float(f->len); - const MLoopUV *luv = (const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, data->cd_ofs); - madd_v2_v2fl(data->vbo_data[BM_elem_index_get(f)], luv->uv, w); + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, data->cd_ofs); + madd_v2_v2fl(data->vbo_data[BM_elem_index_get(f)], luv, w); } while ((l_iter = l_iter->next) != l_first); } @@ -82,12 +82,12 @@ static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr, const MLoop *ml = &mloop[ml_index]; if (mr->use_subsurf_fdots) { if (BLI_BITMAP_TEST(facedot_tags, ml->v)) { - copy_v2_v2(data->vbo_data[mp_index], data->uv_data[ml_index].uv); + copy_v2_v2(data->vbo_data[mp_index], data->uv_data[ml_index]); } } else { float w = 1.0f / float(mp->totloop); - madd_v2_v2fl(data->vbo_data[mp_index], data->uv_data[ml_index].uv, w); + madd_v2_v2fl(data->vbo_data[mp_index], data->uv_data[ml_index], w); } } } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc index a6123dbbda9..0ee95b7dcf6 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc @@ -48,7 +48,8 @@ static void extract_tan_init_common(const MeshRenderData *mr, /* FIXME(T91838): This is to avoid a crash when orco tangent was requested but there are valid * uv layers. It would be better to fix the root cause. */ - if (tan_layers == 0 && use_orco_tan && CustomData_get_layer_index(cd_ldata, CD_MLOOPUV) != -1) { + if (tan_layers == 0 && use_orco_tan && + CustomData_get_layer_index(cd_ldata, CD_PROP_FLOAT2) != -1) { tan_layers = 1; use_orco_tan = false; } @@ -56,17 +57,17 @@ static void extract_tan_init_common(const MeshRenderData *mr, for (int i = 0; i < MAX_MTFACE; i++) { if (tan_layers & (1 << i)) { char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME]; - const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i); + const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_PROP_FLOAT2, i); GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME); /* Tangent layer name. */ BLI_snprintf(attr_name, sizeof(attr_name), "t%s", attr_safe_name); GPU_vertformat_attr_add(format, attr_name, comp_type, 4, fetch_mode); /* Active render layer name. */ - if (i == CustomData_get_render_layer(cd_ldata, CD_MLOOPUV)) { + if (i == CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2)) { GPU_vertformat_alias_add(format, "t"); } /* Active display layer name. */ - if (i == CustomData_get_active_layer(cd_ldata, CD_MLOOPUV)) { + if (i == CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2)) { GPU_vertformat_alias_add(format, "at"); } diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc index fe6e31af3c2..54dbfa4fbe1 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc @@ -5,6 +5,7 @@ * \ingroup draw */ +#include "BLI_math_vector_types.hh" #include "BLI_string.h" #include "draw_subdivision.h" @@ -29,7 +30,7 @@ static bool mesh_extract_uv_format_init(GPUVertFormat *format, uint32_t uv_layers = cache->cd_used.uv; /* HACK to fix T68857 */ if (extract_type == MR_EXTRACT_BMESH && cache->cd_used.edit_uv == 1) { - int layer = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV); + int layer = CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2); if (layer != -1) { uv_layers |= (1 << layer); } @@ -40,24 +41,24 @@ static bool mesh_extract_uv_format_init(GPUVertFormat *format, for (int i = 0; i < MAX_MTFACE; i++) { if (uv_layers & (1 << i)) { char attr_name[32], attr_safe_name[GPU_MAX_SAFE_ATTR_NAME]; - const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_MLOOPUV, i); + const char *layer_name = CustomData_get_layer_name(cd_ldata, CD_PROP_FLOAT2, i); GPU_vertformat_safe_attr_name(layer_name, attr_safe_name, GPU_MAX_SAFE_ATTR_NAME); /* UV layer name. */ BLI_snprintf(attr_name, sizeof(attr_name), "a%s", attr_safe_name); GPU_vertformat_attr_add(format, attr_name, GPU_COMP_F32, 2, GPU_FETCH_FLOAT); /* Active render layer name. */ - if (i == CustomData_get_render_layer(cd_ldata, CD_MLOOPUV)) { + if (i == CustomData_get_render_layer(cd_ldata, CD_PROP_FLOAT2)) { GPU_vertformat_alias_add(format, "a"); } /* Active display layer name. */ - if (i == CustomData_get_active_layer(cd_ldata, CD_MLOOPUV)) { + if (i == CustomData_get_active_layer(cd_ldata, CD_PROP_FLOAT2)) { GPU_vertformat_alias_add(format, "au"); /* Alias to `pos` for edit uvs. */ GPU_vertformat_alias_add(format, "pos"); } /* Stencil mask uv layer name. */ - if (i == CustomData_get_stencil_layer(cd_ldata, CD_MLOOPUV)) { + if (i == CustomData_get_stencil_layer(cd_ldata, CD_PROP_FLOAT2)) { GPU_vertformat_alias_add(format, "mu"); } } @@ -90,28 +91,28 @@ static void extract_uv_init(const MeshRenderData *mr, GPU_vertbuf_init_with_format(vbo, &format); GPU_vertbuf_data_alloc(vbo, v_len); - float(*uv_data)[2] = (float(*)[2])GPU_vertbuf_get_data(vbo); + float2 *uv_data = static_cast(GPU_vertbuf_get_data(vbo)); for (int i = 0; i < MAX_MTFACE; i++) { if (uv_layers & (1 << i)) { if (mr->extract_type == MR_EXTRACT_BMESH) { - int cd_ofs = CustomData_get_n_offset(cd_ldata, CD_MLOOPUV, i); + int cd_ofs = CustomData_get_n_offset(cd_ldata, CD_PROP_FLOAT2, i); BMIter f_iter; BMFace *efa; BM_ITER_MESH (efa, &f_iter, mr->bm, BM_FACES_OF_MESH) { BMLoop *l_iter, *l_first; l_iter = l_first = BM_FACE_FIRST_LOOP(efa); do { - MLoopUV *luv = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_ofs); - memcpy(uv_data, luv->uv, sizeof(*uv_data)); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_ofs); + memcpy(uv_data, luv, sizeof(*uv_data)); uv_data++; } while ((l_iter = l_iter->next) != l_first); } } else { - const MLoopUV *layer_data = (const MLoopUV *)CustomData_get_layer_n( - cd_ldata, CD_MLOOPUV, i); + const float2 *layer_data = static_cast( + CustomData_get_layer_n(cd_ldata, CD_PROP_FLOAT2, i)); for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, uv_data++, layer_data++) { - memcpy(uv_data, layer_data->uv, sizeof(*uv_data)); + memcpy(uv_data, layer_data, sizeof(*uv_data)); } } } diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 91e0837c679..9a998b34f3c 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -960,7 +960,7 @@ static int surface_set_exec(bContext *C, wmOperator *op) Mesh &new_surface_mesh = *static_cast(new_surface_ob.data); const char *new_uv_map_name = CustomData_get_active_layer_name(&new_surface_mesh.ldata, - CD_MLOOPUV); + CD_PROP_FLOAT2); CTX_DATA_BEGIN (C, Object *, selected_ob, selected_objects) { if (selected_ob->type != OB_CURVES) { diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index 696397bd12a..516d67220cb 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -248,7 +248,6 @@ static int geometry_color_attribute_add_exec(bContext *C, wmOperator *op) enum class ConvertAttributeMode { Generic, - UVMap, VertexGroup, }; @@ -301,23 +300,6 @@ static int geometry_attribute_convert_exec(bContext *C, wmOperator *op) } break; } - case ConvertAttributeMode::UVMap: { - MLoopUV *dst_uvs = static_cast( - MEM_calloc_arrayN(mesh->totloop, sizeof(MLoopUV), __func__)); - VArray src_varray = attributes.lookup_or_default( - name, ATTR_DOMAIN_CORNER, {0.0f, 0.0f}); - for (const int i : IndexRange(mesh->totloop)) { - copy_v2_v2(dst_uvs[i].uv, src_varray[i]); - } - attributes.remove(name); - CustomData_add_layer_named( - &mesh->ldata, CD_MLOOPUV, CD_ASSIGN, dst_uvs, mesh->totloop, name.c_str()); - int *active_index = BKE_id_attributes_active_index_p(&mesh->id); - if (*active_index > 0) { - *active_index -= 1; - } - break; - } case ConvertAttributeMode::VertexGroup: { Array src_weights(mesh->totvert); VArray src_varray = attributes.lookup_or_default( @@ -710,7 +692,6 @@ void GEOMETRY_OT_attribute_convert(wmOperatorType *ot) static EnumPropertyItem mode_items[] = { {int(ConvertAttributeMode::Generic), "GENERIC", 0, "Generic", ""}, - {int(ConvertAttributeMode::UVMap), "UV_MAP", 0, "UV Map", ""}, {int(ConvertAttributeMode::VertexGroup), "VERTEX_GROUP", 0, "Vertex Group", ""}, {0, nullptr, 0, nullptr, nullptr}, }; diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 59f348f6d8a..fdd0d639883 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -552,6 +552,13 @@ void ED_mesh_geometry_clear(struct Mesh *mesh); void ED_mesh_update(struct Mesh *mesh, struct bContext *C, bool calc_edges, bool calc_edges_loose); +bool *ED_mesh_uv_map_vert_select_layer_ensure(struct Mesh *mesh, int uv_map_index); +bool *ED_mesh_uv_map_edge_select_layer_ensure(struct Mesh *mesh, int uv_map_index); +bool *ED_mesh_uv_map_pin_layer_ensure(struct Mesh *mesh, int uv_map_index); +const bool *ED_mesh_uv_map_vert_select_layer_get(const struct Mesh *mesh, int uv_map_index); +const bool *ED_mesh_uv_map_edge_select_layer_get(const struct Mesh *mesh, int uv_map_index); +const bool *ED_mesh_uv_map_pin_layer_get(const struct Mesh *mesh, int uv_map_index); + bool ED_mesh_edge_is_loose(const struct Mesh *mesh, int index); void ED_mesh_uv_ensure(struct Mesh *me, const char *name); @@ -560,6 +567,7 @@ int ED_mesh_uv_add( bool ED_mesh_uv_remove_index(struct Mesh *me, int n); bool ED_mesh_uv_remove_active(struct Mesh *me); bool ED_mesh_uv_remove_named(struct Mesh *me, const char *name); + void ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me); /** * Without a #bContext, called when UV-editing. diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 20c4b3f5700..7aa745abdf6 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -7,6 +7,8 @@ #pragma once +#include "BKE_customdata.h" + #ifdef __cplusplus extern "C" { #endif @@ -87,17 +89,19 @@ bool ED_uvedit_test(struct Object *obedit); bool uvedit_face_visible_test_ex(const struct ToolSettings *ts, struct BMFace *efa); bool uvedit_face_select_test_ex(const struct ToolSettings *ts, struct BMFace *efa, - int cd_loop_uv_offset); + BMUVOffsets offsets); + bool uvedit_edge_select_test_ex(const struct ToolSettings *ts, struct BMLoop *l, - int cd_loop_uv_offset); + BMUVOffsets offsets); bool uvedit_uv_select_test_ex(const struct ToolSettings *ts, struct BMLoop *l, - int cd_loop_uv_offset); + BMUVOffsets offsets); + bool uvedit_face_visible_test(const struct Scene *scene, struct BMFace *efa); -bool uvedit_face_select_test(const struct Scene *scene, struct BMFace *efa, int cd_loop_uv_offset); -bool uvedit_edge_select_test(const struct Scene *scene, struct BMLoop *l, int cd_loop_uv_offset); -bool uvedit_uv_select_test(const struct Scene *scene, struct BMLoop *l, int cd_loop_uv_offset); +bool uvedit_face_select_test(const struct Scene *scene, struct BMFace *efa, BMUVOffsets offsets); +bool uvedit_edge_select_test(const struct Scene *scene, struct BMLoop *l, BMUVOffsets offsets); +bool uvedit_uv_select_test(const struct Scene *scene, struct BMLoop *l, BMUVOffsets offsets); /* Individual UV element selection functions. */ @@ -111,7 +115,7 @@ void uvedit_face_select_set(const struct Scene *scene, struct BMFace *efa, bool select, bool do_history, - int cd_loop_uv_offset); + BMUVOffsets offsets); /** * \brief Select UV Edge * @@ -122,7 +126,7 @@ void uvedit_edge_select_set(const struct Scene *scene, struct BMLoop *l, bool select, bool do_history, - int cd_loop_uv_offset); + BMUVOffsets offsets); /** * \brief Select UV Vertex * @@ -133,7 +137,7 @@ void uvedit_uv_select_set(const struct Scene *scene, struct BMLoop *l, bool select, bool do_history, - int cd_loop_uv_offset); + BMUVOffsets offsets); /* Low level functions for (de)selecting individual UV elements. Ensure UV face visibility before * use. */ @@ -142,29 +146,31 @@ void uvedit_face_select_enable(const struct Scene *scene, struct BMesh *bm, struct BMFace *efa, bool do_history, - int cd_loop_uv_offset); + BMUVOffsets offsets); void uvedit_face_select_disable(const struct Scene *scene, struct BMesh *bm, struct BMFace *efa, - int cd_loop_uv_offset); + BMUVOffsets offsets); + void uvedit_edge_select_enable(const struct Scene *scene, struct BMesh *bm, struct BMLoop *l, bool do_history, - int cd_loop_uv_offset); + BMUVOffsets offsets); void uvedit_edge_select_disable(const struct Scene *scene, struct BMesh *bm, struct BMLoop *l, - int cd_loop_uv_offset); + BMUVOffsets offsets); + void uvedit_uv_select_enable(const struct Scene *scene, struct BMesh *bm, struct BMLoop *l, bool do_history, - int cd_loop_uv_offset); + BMUVOffsets offsets); void uvedit_uv_select_disable(const struct Scene *scene, struct BMesh *bm, struct BMLoop *l, - int cd_loop_uv_offset); + BMUVOffsets offsets); /* Sticky mode UV element selection functions. */ @@ -173,19 +179,20 @@ void uvedit_face_select_set_with_sticky(const struct Scene *scene, struct BMFace *efa, bool select, bool do_history, - int cd_loop_uv_offset); + BMUVOffsets offsets); void uvedit_edge_select_set_with_sticky(const struct Scene *scene, struct BMEditMesh *em, struct BMLoop *l, bool select, bool do_history, - int cd_loop_uv_offset); + BMUVOffsets offsets); + void uvedit_uv_select_set_with_sticky(const struct Scene *scene, struct BMEditMesh *em, struct BMLoop *l, bool select, bool do_history, - int cd_loop_uv_offset); + BMUVOffsets offsets); /* Low level functions for sticky element selection (sticky mode independent). Type of sticky * selection is specified explicitly (using sticky_flag, except for face selection). */ @@ -195,28 +202,28 @@ void uvedit_face_select_shared_vert(const struct Scene *scene, struct BMFace *efa, const bool select, const bool do_history, - const int cd_loop_uv_offset); + BMUVOffsets offsets); void uvedit_edge_select_shared_vert(const struct Scene *scene, struct BMEditMesh *em, struct BMLoop *l, const bool select, const int sticky_flag, const bool do_history, - const int cd_loop_uv_offset); + BMUVOffsets offsets); void uvedit_uv_select_shared_vert(const struct Scene *scene, struct BMEditMesh *em, struct BMLoop *l, const bool select, const int sticky_flag, const bool do_history, - const int cd_loop_uv_offset); + BMUVOffsets offsets); /* Sets required UV edge flags as specified by the sticky_flag. */ void uvedit_edge_select_set_noflush(const struct Scene *scene, struct BMLoop *l, const bool select, const int sticky_flag, - const int cd_loop_uv_offset); + BMUVOffsets offsets); /** * \brief UV Select Mode set @@ -315,7 +322,7 @@ struct FaceIsland { * \note While this is duplicate information, * it allows islands from multiple meshes to be stored in the same list. */ - int cd_loop_uv_offset; + BMUVOffsets offsets; float aspect_y; }; @@ -326,7 +333,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene, const bool only_selected_uvs, const bool use_seams, const float aspect_y, - const int cd_loop_uv_offset); + BMUVOffsets offsets); struct UVMapUDIM_Params { const struct Image *image; diff --git a/source/blender/editors/mesh/editface.cc b/source/blender/editors/mesh/editface.cc index 605f1327a84..af968b2aeba 100644 --- a/source/blender/editors/mesh/editface.cc +++ b/source/blender/editors/mesh/editface.cc @@ -379,7 +379,7 @@ bool paintface_minmax(Object *ob, float r_min[3], float r_max[3]) float vec[3], bmat[3][3]; const Mesh *me = BKE_mesh_from_object(ob); - if (!me || !CustomData_has_layer(&me->ldata, CD_MLOOPUV)) { + if (!me || !CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2)) { return ok; } diff --git a/source/blender/editors/mesh/editmesh_select.cc b/source/blender/editors/mesh/editmesh_select.cc index d86d12eb155..6955db63fe8 100644 --- a/source/blender/editors/mesh/editmesh_select.cc +++ b/source/blender/editors/mesh/editmesh_select.cc @@ -3211,7 +3211,7 @@ static int select_linked_delimit_default_from_op(wmOperator *op, const int selec static void select_linked_delimit_validate(BMesh *bm, int *delimit) { if ((*delimit) & BMO_DELIM_UV) { - if (!CustomData_has_layer(&bm->ldata, CD_MLOOPUV)) { + if (!CustomData_has_layer(&bm->ldata, CD_PROP_FLOAT2)) { (*delimit) &= ~BMO_DELIM_UV; } } @@ -3222,7 +3222,7 @@ static void select_linked_delimit_begin(BMesh *bm, int delimit) DelimitData delimit_data = {0}; if (delimit & BMO_DELIM_UV) { - delimit_data.cd_loop_type = CD_MLOOPUV; + delimit_data.cd_loop_type = CD_PROP_FLOAT2; delimit_data.cd_loop_offset = CustomData_get_offset(&bm->ldata, delimit_data.cd_loop_type); if (delimit_data.cd_loop_offset == -1) { delimit &= ~BMO_DELIM_UV; diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index bbc092d0a99..3f1981b1e75 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -459,10 +459,10 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us /* vars from original func */ UvVertMap *vmap; UvMapVert *buf; - const MLoopUV *luv; + const float(*luv)[2]; uint a; int totverts, i, totuv, totfaces; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2); bool *winding = NULL; BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE); @@ -516,8 +516,8 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us buf++; if (use_winding) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - copy_v2_v2(tf_uv[i], luv->uv); + luv = BM_ELEM_CD_GET_FLOAT2_P(l, cd_loop_uv_offset); + copy_v2_v2(tf_uv[i], *luv); } } @@ -542,8 +542,7 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us efa = BM_face_at_index(bm, v->poly_index); l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, v->loop_of_poly_index); - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - uv = luv->uv; + uv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); lastv = NULL; iterv = vlist; @@ -552,8 +551,7 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us next = iterv->next; efa = BM_face_at_index(bm, iterv->poly_index); l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, iterv->loop_of_poly_index); - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - uv2 = luv->uv; + uv2 = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); if (compare_v2v2(uv2, uv, STD_UV_CONNECT_LIMIT) && (!use_winding || winding[iterv->poly_index] == winding[v->poly_index])) { @@ -682,7 +680,7 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map, UvElement *islandbuf, uint *map, bool uv_selected, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { BM_uv_element_map_ensure_head_table(element_map); @@ -723,7 +721,7 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map, while (element) { /* Scan forwards around the BMFace that contains element->l. */ - if (!uv_selected || uvedit_edge_select_test(scene, element->l, cd_loop_uv_offset)) { + if (!uv_selected || uvedit_edge_select_test(scene, element->l, offsets)) { UvElement *next = BM_uv_element_get(element_map, element->l->next->f, element->l->next); if (next->island == INVALID_ISLAND) { UvElement *tail = element_map->head_table[next - element_map->storage]; @@ -739,7 +737,7 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map, } /* Scan backwards around the BMFace that contains element->l. */ - if (!uv_selected || uvedit_edge_select_test(scene, element->l->prev, cd_loop_uv_offset)) { + if (!uv_selected || uvedit_edge_select_test(scene, element->l->prev, offsets)) { UvElement *prev = BM_uv_element_get(element_map, element->l->prev->f, element->l->prev); if (prev->island == INVALID_ISLAND) { UvElement *tail = element_map->head_table[prev - element_map->storage]; @@ -788,14 +786,14 @@ static void bm_uv_build_islands(UvElementMap *element_map, int *island_number = MEM_callocN(sizeof(*island_number) * bm->totface, "uv_island_number_face"); copy_vn_i(island_number, bm->totface, INVALID_ISLAND); - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets uv_offsets = BM_uv_map_get_offsets(bm); const bool use_uv_edge_connectivity = scene->toolsettings->uv_flag & UV_SYNC_SELECTION ? scene->toolsettings->selectmode & SCE_SELECT_EDGE : scene->toolsettings->uv_selectmode & UV_SELECT_EDGE; if (use_uv_edge_connectivity) { nislands = bm_uv_edge_select_build_islands( - element_map, scene, islandbuf, map, uv_selected, cd_loop_uv_offset); + element_map, scene, islandbuf, map, uv_selected, uv_offsets); islandbufsize = totuv; } @@ -813,7 +811,7 @@ static void bm_uv_build_islands(UvElementMap *element_map, BMLoop *l; BMIter liter; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uv_selected && !uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (uv_selected && !uvedit_uv_select_test(scene, l, uv_offsets)) { continue; } @@ -890,20 +888,23 @@ static void bm_uv_build_islands(UvElementMap *element_map, } /* return true if `loop` has UV co-ordinates which match `luv_a` and `luv_b` */ -static bool loop_uv_match(BMLoop *loop, MLoopUV *luv_a, MLoopUV *luv_b, int cd_loop_uv_offset) +static bool loop_uv_match(BMLoop *loop, + const float luv_a[2], + const float luv_b[2], + int cd_loop_uv_offset) { - MLoopUV *luv_c = BM_ELEM_CD_GET_VOID_P(loop, cd_loop_uv_offset); - MLoopUV *luv_d = BM_ELEM_CD_GET_VOID_P(loop->next, cd_loop_uv_offset); - return compare_v2v2(luv_a->uv, luv_c->uv, STD_UV_CONNECT_LIMIT) && - compare_v2v2(luv_b->uv, luv_d->uv, STD_UV_CONNECT_LIMIT); + const float *luv_c = BM_ELEM_CD_GET_FLOAT_P(loop, cd_loop_uv_offset); + const float *luv_d = BM_ELEM_CD_GET_FLOAT_P(loop->next, cd_loop_uv_offset); + return compare_v2v2(luv_a, luv_c, STD_UV_CONNECT_LIMIT) && + compare_v2v2(luv_b, luv_d, STD_UV_CONNECT_LIMIT); } /* Given `anchor` and `edge`, return true if there are edges that fan between them that are * seam-free. */ static bool seam_connected_recursive(BMVert *anchor, BMEdge *edge, - MLoopUV *luv_anchor, - MLoopUV *luv_fan, + float luv_anchor[2], + float luv_fan[2], BMLoop *needle, GSet *visited, int cd_loop_uv_offset) @@ -931,7 +932,7 @@ static bool seam_connected_recursive(BMVert *anchor, return true; /* Success. */ } - MLoopUV *luv_far = BM_ELEM_CD_GET_VOID_P(loop->prev, cd_loop_uv_offset); + float *luv_far = BM_ELEM_CD_GET_FLOAT_P(loop->prev, cd_loop_uv_offset); if (seam_connected_recursive( anchor, loop->prev->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) { return true; @@ -947,7 +948,7 @@ static bool seam_connected_recursive(BMVert *anchor, return true; /* Success. */ } - MLoopUV *luv_far = BM_ELEM_CD_GET_VOID_P(loop->next->next, cd_loop_uv_offset); + float *luv_far = BM_ELEM_CD_GET_FLOAT_P(loop->next->next, cd_loop_uv_offset); if (seam_connected_recursive( anchor, loop->next->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) { return true; @@ -970,8 +971,8 @@ static bool seam_connected(BMLoop *loop_a, BMLoop *loop_b, GSet *visited, int cd BLI_gset_clear(visited, NULL); - MLoopUV *luv_anchor = BM_ELEM_CD_GET_VOID_P(loop_a, cd_loop_uv_offset); - MLoopUV *luv_fan = BM_ELEM_CD_GET_VOID_P(loop_a->next, cd_loop_uv_offset); + float *luv_anchor = BM_ELEM_CD_GET_FLOAT_P(loop_a, cd_loop_uv_offset); + float *luv_fan = BM_ELEM_CD_GET_FLOAT_P(loop_a->next, cd_loop_uv_offset); const bool result = seam_connected_recursive( loop_a->v, loop_a->e, luv_anchor, luv_fan, loop_b, visited, cd_loop_uv_offset); return result; @@ -991,9 +992,9 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, BMFace *efa; BMIter iter, liter; BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE); - MLoopUV *luv; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - if (cd_loop_uv_offset < 0) { + + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); + if (offsets.uv < 0) { return NULL; } @@ -1016,7 +1017,7 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, else { BMLoop *l; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (uvedit_uv_select_test(scene, l, offsets)) { totuv++; } } @@ -1057,7 +1058,7 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, int i; BMLoop *l; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { - if (uv_selected && !uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (uv_selected && !uvedit_uv_select_test(scene, l, offsets)) { continue; } @@ -1070,8 +1071,8 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, element_map->vertex[BM_elem_index_get(l->v)] = buf; if (use_winding) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - copy_v2_v2(tf_uv[i], luv->uv); + const float *uv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + copy_v2_v2(tf_uv[i], uv); } buf++; @@ -1098,9 +1099,8 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, v->next = newvlist; newvlist = v; - luv = BM_ELEM_CD_GET_VOID_P(v->l, cd_loop_uv_offset); - const float *uv = luv->uv; - bool uv_vert_sel = uvedit_uv_select_test(scene, v->l, cd_loop_uv_offset); + const float *uv = BM_ELEM_CD_GET_VOID_P(v->l, offsets.uv); + bool uv_vert_sel = uvedit_uv_select_test(scene, v->l, offsets); UvElement *lastv = NULL; UvElement *iterv = vlist; @@ -1108,20 +1108,19 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, /* Scan through unsorted list, finding UvElements which are connected to `v`. */ while (iterv) { UvElement *next = iterv->next; - luv = BM_ELEM_CD_GET_VOID_P(iterv->l, cd_loop_uv_offset); bool connected = true; /* Assume connected unless we can prove otherwise. */ if (connected) { /* Are the two UVs close together? */ - const float *uv2 = luv->uv; + const float *uv2 = BM_ELEM_CD_GET_FLOAT_P(iterv->l, offsets.uv); connected = compare_v2v2(uv2, uv, STD_UV_CONNECT_LIMIT); } if (connected) { /* Check if the uv loops share the same selection state (if not, they are not connected * as they have been ripped or other edit commands have separated them). */ - const bool uv2_vert_sel = uvedit_uv_select_test(scene, iterv->l, cd_loop_uv_offset); + const bool uv2_vert_sel = uvedit_uv_select_test(scene, iterv->l, offsets); connected = (uv_vert_sel == uv2_vert_sel); } @@ -1131,7 +1130,7 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, } if (connected && use_seams) { - connected = seam_connected(iterv->l, v->l, seam_visited_gset, cd_loop_uv_offset); + connected = seam_connected(iterv->l, v->l, seam_visited_gset, offsets.uv); } if (connected) { @@ -1257,7 +1256,7 @@ BMFace *EDBM_uv_active_face_get(BMEditMesh *em, const bool sloppy, const bool se bool EDBM_uv_check(BMEditMesh *em) { /* some of these checks could be a touch overkill */ - return em && em->bm->totface && CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV); + return em && em->bm->totface && CustomData_has_layer(&em->bm->ldata, CD_PROP_FLOAT2); } bool EDBM_vert_color_check(BMEditMesh *em) diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index b22f3a1d3df..d939db74e73 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -36,6 +36,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "BLT_translation.h" + #include "ED_mesh.h" #include "ED_object.h" #include "ED_paint.h" @@ -48,6 +50,7 @@ #include "mesh_intern.h" /* own include */ using blender::Array; +using blender::float2; using blender::float3; using blender::MutableSpan; using blender::Span; @@ -118,7 +121,7 @@ static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer) int layer_index, tot, n; char htype = BM_FACE; - if (ELEM(type, CD_PROP_BYTE_COLOR, CD_MLOOPUV)) { + if (ELEM(type, CD_PROP_BYTE_COLOR, CD_PROP_FLOAT2)) { htype = BM_LOOP; } else if (ELEM(type, CD_PROP_COLOR)) { @@ -186,18 +189,18 @@ static void mesh_uv_reset_bmface(BMFace *f, const int cd_loop_uv_offset) int i; BM_ITER_ELEM_INDEX (l, &liter, f, BM_LOOPS_OF_FACE, i) { - fuv[i] = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset))->uv; + fuv[i] = ((float *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset)); } mesh_uv_reset_array(fuv.data(), f->len); } -static void mesh_uv_reset_mface(const MPoly *mp, MLoopUV *mloopuv) +static void mesh_uv_reset_mface(const MPoly *mp, float2 *mloopuv) { Array fuv(mp->totloop); for (int i = 0; i < mp->totloop; i++) { - fuv[i] = mloopuv[mp->loopstart + i].uv; + fuv[i] = mloopuv[mp->loopstart + i]; } mesh_uv_reset_array(fuv.data(), mp->totloop); @@ -209,7 +212,8 @@ void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum) if (em) { /* Collect BMesh UVs */ - const int cd_loop_uv_offset = CustomData_get_n_offset(&em->bm->ldata, CD_MLOOPUV, layernum); + const int cd_loop_uv_offset = CustomData_get_n_offset( + &em->bm->ldata, CD_PROP_FLOAT2, layernum); BMFace *efa; BMIter iter; @@ -226,8 +230,9 @@ void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum) } else { /* Collect Mesh UVs */ - BLI_assert(CustomData_has_layer(&me->ldata, CD_MLOOPUV)); - MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, layernum); + BLI_assert(CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2)); + float2 *mloopuv = static_cast( + CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, layernum)); const MPoly *polys = BKE_mesh_polys(me); for (int i = 0; i < me->totpoly; i++) { @@ -242,7 +247,7 @@ void ED_mesh_uv_loop_reset(bContext *C, Mesh *me) { /* could be ldata or pdata */ CustomData *ldata = GET_CD_DATA(me, ldata); - const int layernum = CustomData_get_active_layer(ldata, CD_MLOOPUV); + const int layernum = CustomData_get_active_layer(ldata, CD_PROP_FLOAT2); ED_mesh_uv_loop_reset_ex(me, layernum); WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); @@ -256,53 +261,60 @@ int ED_mesh_uv_add( BMEditMesh *em; int layernum_dst; + if (!name) { + name = DATA_("UVMap"); + } + + char unique_name[MAX_CUSTOMDATA_LAYER_NAME]; + BKE_id_attribute_calc_unique_name(&me->id, name, unique_name); bool is_init = false; if (me->edit_mesh) { em = me->edit_mesh; - layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPUV); + layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_PROP_FLOAT2); if (layernum_dst >= MAX_MTFACE) { BKE_reportf(reports, RPT_WARNING, "Cannot add more than %i UV maps", MAX_MTFACE); return -1; } - /* CD_MLOOPUV */ - BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_MLOOPUV, name); + BM_data_layer_add_named(em->bm, &em->bm->ldata, CD_PROP_FLOAT2, unique_name); + BM_uv_map_ensure_select_and_pin_attrs(em->bm); /* copy data from active UV */ if (layernum_dst && do_init) { - const int layernum_src = CustomData_get_active_layer(&em->bm->ldata, CD_MLOOPUV); - BM_data_layer_copy(em->bm, &em->bm->ldata, CD_MLOOPUV, layernum_src, layernum_dst); + const int layernum_src = CustomData_get_active_layer(&em->bm->ldata, CD_PROP_FLOAT2); + BM_data_layer_copy(em->bm, &em->bm->ldata, CD_PROP_FLOAT2, layernum_src, layernum_dst); is_init = true; } if (active_set || layernum_dst == 0) { - CustomData_set_layer_active(&em->bm->ldata, CD_MLOOPUV, layernum_dst); + CustomData_set_layer_active(&em->bm->ldata, CD_PROP_FLOAT2, layernum_dst); } } else { - layernum_dst = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); + layernum_dst = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); if (layernum_dst >= MAX_MTFACE) { BKE_reportf(reports, RPT_WARNING, "Cannot add more than %i UV maps", MAX_MTFACE); return -1; } - if (CustomData_has_layer(&me->ldata, CD_MLOOPUV) && do_init) { + if (CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2) && do_init) { CustomData_add_layer_named(&me->ldata, - CD_MLOOPUV, + CD_PROP_FLOAT2, CD_DUPLICATE, - CustomData_get_layer(&me->ldata, CD_MLOOPUV), + CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2), me->totloop, - name); + unique_name); + is_init = true; } else { CustomData_add_layer_named( - &me->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, me->totloop, name); + &me->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, me->totloop, unique_name); } if (active_set || layernum_dst == 0) { - CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, layernum_dst); + CustomData_set_layer_active(&me->ldata, CD_PROP_FLOAT2, layernum_dst); } } @@ -317,6 +329,72 @@ int ED_mesh_uv_add( return layernum_dst; } +static const bool *mesh_loop_boolean_custom_data_get_by_name(const Mesh &mesh, const char *name) +{ + return static_cast(CustomData_get_layer_named(&mesh.ldata, CD_PROP_BOOL, name)); +} + +const bool *ED_mesh_uv_map_vert_select_layer_get(const Mesh *mesh, const int uv_index) +{ + using namespace blender::bke; + char buffer[MAX_CUSTOMDATA_LAYER_NAME]; + const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index); + return mesh_loop_boolean_custom_data_get_by_name( + *mesh, BKE_uv_map_vert_select_name_get(uv_name, buffer)); +} +/* UV map edge selections are stored on face corners (loops) and not on edges + * because we need selections per face edge, even when the edge is split in UV space. */ +const bool *ED_mesh_uv_map_edge_select_layer_get(const Mesh *mesh, const int uv_index) +{ + using namespace blender::bke; + char buffer[MAX_CUSTOMDATA_LAYER_NAME]; + const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index); + return mesh_loop_boolean_custom_data_get_by_name( + *mesh, BKE_uv_map_edge_select_name_get(uv_name, buffer)); +} + +const bool *ED_mesh_uv_map_pin_layer_get(const Mesh *mesh, const int uv_index) +{ + using namespace blender::bke; + char buffer[MAX_CUSTOMDATA_LAYER_NAME]; + const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index); + return mesh_loop_boolean_custom_data_get_by_name(*mesh, + BKE_uv_map_pin_name_get(uv_name, buffer)); +} + +static bool *ensure_corner_boolean_attribute(Mesh &mesh, const blender::StringRefNull name) +{ + bool *data = static_cast(CustomData_duplicate_referenced_layer_named( + &mesh.ldata, CD_PROP_BOOL, name.c_str(), mesh.totloop)); + if (!data) { + data = static_cast(CustomData_add_layer_named( + &mesh.ldata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, mesh.totpoly, name.c_str())); + } + return data; +} + +bool *ED_mesh_uv_map_vert_select_layer_ensure(Mesh *mesh, const int uv_index) +{ + using namespace blender::bke; + char buffer[MAX_CUSTOMDATA_LAYER_NAME]; + const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index); + return ensure_corner_boolean_attribute(*mesh, BKE_uv_map_vert_select_name_get(uv_name, buffer)); +} +bool *ED_mesh_uv_map_edge_select_layer_ensure(Mesh *mesh, const int uv_index) +{ + using namespace blender::bke; + char buffer[MAX_CUSTOMDATA_LAYER_NAME]; + const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index); + return ensure_corner_boolean_attribute(*mesh, BKE_uv_map_edge_select_name_get(uv_name, buffer)); +} +bool *ED_mesh_uv_map_pin_layer_ensure(Mesh *mesh, const int uv_index) +{ + using namespace blender::bke; + char buffer[MAX_CUSTOMDATA_LAYER_NAME]; + const char *uv_name = CustomData_get_layer_name(&mesh->ldata, CD_PROP_FLOAT2, uv_index); + return ensure_corner_boolean_attribute(*mesh, BKE_uv_map_pin_name_get(uv_name, buffer)); +} + void ED_mesh_uv_ensure(Mesh *me, const char *name) { BMEditMesh *em; @@ -325,13 +403,13 @@ void ED_mesh_uv_ensure(Mesh *me, const char *name) if (me->edit_mesh) { em = me->edit_mesh; - layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPUV); + layernum_dst = CustomData_number_of_layers(&em->bm->ldata, CD_PROP_FLOAT2); if (layernum_dst == 0) { ED_mesh_uv_add(me, name, true, true, nullptr); } } else { - layernum_dst = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); + layernum_dst = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); if (layernum_dst == 0) { ED_mesh_uv_add(me, name, true, true, nullptr); } @@ -344,7 +422,7 @@ bool ED_mesh_uv_remove_index(Mesh *me, const int n) CustomDataLayer *cdlu; int index; - index = CustomData_get_layer_index_n(ldata, CD_MLOOPUV, n); + index = CustomData_get_layer_index_n(ldata, CD_PROP_FLOAT2, n); cdlu = (index == -1) ? nullptr : &ldata->layers[index]; if (!cdlu) { @@ -361,7 +439,7 @@ bool ED_mesh_uv_remove_index(Mesh *me, const int n) bool ED_mesh_uv_remove_active(Mesh *me) { CustomData *ldata = GET_CD_DATA(me, ldata); - const int n = CustomData_get_active_layer(ldata, CD_MLOOPUV); + const int n = CustomData_get_active_layer(ldata, CD_PROP_FLOAT2); if (n != -1) { return ED_mesh_uv_remove_index(me, n); @@ -371,7 +449,7 @@ bool ED_mesh_uv_remove_active(Mesh *me) bool ED_mesh_uv_remove_named(Mesh *me, const char *name) { CustomData *ldata = GET_CD_DATA(me, ldata); - const int n = CustomData_get_named_layer(ldata, CD_MLOOPUV, name); + const int n = CustomData_get_named_layer(ldata, CD_PROP_FLOAT2, name); if (n != -1) { return ED_mesh_uv_remove_index(me, n); } @@ -508,7 +586,7 @@ static bool uv_texture_remove_poll(bContext *C) Object *ob = ED_object_context(C); Mesh *me = static_cast(ob->data); CustomData *ldata = GET_CD_DATA(me, ldata); - const int active = CustomData_get_active_layer(ldata, CD_MLOOPUV); + const int active = CustomData_get_active_layer(ldata, CD_PROP_FLOAT2); if (active != -1) { return true; } @@ -549,12 +627,14 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static int mesh_uv_texture_remove_exec(bContext *C, wmOperator * /*op*/) +static int mesh_uv_texture_remove_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); Mesh *me = static_cast(ob->data); - if (!ED_mesh_uv_remove_active(me)) { + CustomData *ldata = GET_CD_DATA(me, ldata); + const char *name = CustomData_get_active_layer_name(ldata, CD_PROP_FLOAT2); + if (!BKE_id_attribute_remove(&me->id, name, op->reports)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc index a710ac423fd..bf10d51f2e1 100644 --- a/source/blender/editors/mesh/meshtools.cc +++ b/source/blender/editors/mesh/meshtools.cc @@ -1050,9 +1050,9 @@ static float *editmesh_get_mirror_uv( BMLoop *l; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - if ((fabsf(luv->uv[0] - vec[0]) < 0.001f) && (fabsf(luv->uv[1] - vec[1]) < 0.001f)) { - return luv->uv; + float *luv2 = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_PROP_FLOAT2); + if ((fabsf(luv[0] - vec[0]) < 0.001f) && (fabsf(luv[1] - vec[1]) < 0.001f)) { + return luv; } } } diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc index a6081d3733e..db8867e994d 100644 --- a/source/blender/editors/object/object_add.cc +++ b/source/blender/editors/object/object_add.cc @@ -2097,7 +2097,7 @@ static int object_curves_empty_hair_add_exec(bContext *C, wmOperator *op) /* Decide which UV map to use for attachment. */ Mesh *surface_mesh = static_cast(surface_ob->data); - const char *uv_name = CustomData_get_active_layer_name(&surface_mesh->ldata, CD_MLOOPUV); + const char *uv_name = CustomData_get_active_layer_name(&surface_mesh->ldata, CD_PROP_FLOAT2); if (uv_name != nullptr) { curves_id->surface_uv_map = BLI_strdup(uv_name); } diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 91641de1605..46dd6132bbb 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -155,7 +155,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op) break; } - if (!CustomData_has_layer(&me->ldata, CD_MLOOPUV)) { + if (!CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2)) { BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking"); ok = false; diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c index e53199c504f..0b0e7eb55aa 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.c @@ -461,7 +461,7 @@ static bool bake_object_check(const Scene *scene, } } else if (target == R_BAKE_TARGET_IMAGE_TEXTURES) { - if (CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV) == -1) { + if (CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2) == -1) { BKE_reportf( reports, RPT_ERROR, "No active UV layer found in the object \"%s\"", ob->id.name + 2); return false; @@ -1381,7 +1381,7 @@ static int bake(const BakeAPIRender *bkr, if (bkr->uv_layer[0] != '\0') { Mesh *me = (Mesh *)ob_low->data; - if (CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, bkr->uv_layer) == -1) { + if (CustomData_get_named_layer(&me->ldata, CD_PROP_FLOAT2, bkr->uv_layer) == -1) { BKE_reportf(reports, RPT_ERROR, "No UV layer named \"%s\" found in the object \"%s\"", @@ -2246,7 +2246,7 @@ void OBJECT_OT_bake(wmOperatorType *ot) RNA_def_string(ot->srna, "uv_layer", NULL, - MAX_CUSTOMDATA_LAYER_NAME, + MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX, "UV Layer", "UV layer to override active"); } diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c index 78b059d5514..5f1af79c446 100644 --- a/source/blender/editors/object/object_data_transfer.c +++ b/source/blender/editors/object/object_data_transfer.c @@ -176,16 +176,16 @@ static const EnumPropertyItem *dt_layers_select_src_itemf(bContext *C, Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src); CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH; - cddata_masks.lmask |= CD_MASK_MLOOPUV; + cddata_masks.lmask |= CD_MASK_PROP_FLOAT2; Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks); - int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPUV); + int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_PROP_FLOAT2); RNA_enum_item_add_separator(&item, &totitem); for (int i = 0; i < num_data; i++) { tmp_item.value = i; tmp_item.identifier = tmp_item.name = CustomData_get_layer_name( - &me_eval->ldata, CD_MLOOPUV, i); + &me_eval->ldata, CD_PROP_FLOAT2, i); RNA_enum_item_add(&item, &totitem, &tmp_item); } } diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.cc b/source/blender/editors/sculpt_paint/paint_image_proj.cc index fd797e2b00a..fe14e0482f0 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.cc +++ b/source/blender/editors/sculpt_paint/paint_image_proj.cc @@ -421,16 +421,16 @@ struct ProjPaintState { const MLoop *mloop_eval; const MLoopTri *mlooptri_eval; - const MLoopUV *mloopuv_stencil_eval; + const float (*mloopuv_stencil_eval)[2]; /** * \note These UV layers are aligned to \a mpoly_eval * but each pointer references the start of the layer, * so a loop indirection is needed as well. */ - const MLoopUV **poly_to_loop_uv; + const float (**poly_to_loop_uv)[2]; /** other UV map, use for cloning between layers. */ - const MLoopUV **poly_to_loop_uv_clone; + const float (**poly_to_loop_uv_clone)[2]; /* Actual material for each index, either from object or Mesh datablock... */ Material **mat_array; @@ -518,14 +518,13 @@ BLI_INLINE const MPoly *ps_tri_index_to_mpoly(const ProjPaintState *ps, int tri_ int(ps->mloop_eval[lt->tri[2]].v), #define PS_LOOPTRI_AS_UV_3(uvlayer, lt) \ - uvlayer[lt->poly][lt->tri[0]].uv, uvlayer[lt->poly][lt->tri[1]].uv, \ - uvlayer[lt->poly][lt->tri[2]].uv, + uvlayer[lt->poly][lt->tri[0]], uvlayer[lt->poly][lt->tri[1]], uvlayer[lt->poly][lt->tri[2]], #define PS_LOOPTRI_ASSIGN_UV_3(uv_tri, uvlayer, lt) \ { \ - (uv_tri)[0] = uvlayer[lt->poly][lt->tri[0]].uv; \ - (uv_tri)[1] = uvlayer[lt->poly][lt->tri[1]].uv; \ - (uv_tri)[2] = uvlayer[lt->poly][lt->tri[2]].uv; \ + (uv_tri)[0] = uvlayer[lt->poly][lt->tri[0]]; \ + (uv_tri)[1] = uvlayer[lt->poly][lt->tri[1]]; \ + (uv_tri)[2] = uvlayer[lt->poly][lt->tri[2]]; \ } \ ((void)0) @@ -1672,9 +1671,9 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps, if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, nullptr, nullptr))) { const MLoopTri *lt_other = &ps->mlooptri_eval[tri_index]; - const float *lt_other_tri_uv[3] = {ps->mloopuv_stencil_eval[lt_other->tri[0]].uv, - ps->mloopuv_stencil_eval[lt_other->tri[1]].uv, - ps->mloopuv_stencil_eval[lt_other->tri[2]].uv}; + const float *lt_other_tri_uv[3] = {ps->mloopuv_stencil_eval[lt_other->tri[0]], + ps->mloopuv_stencil_eval[lt_other->tri[1]], + ps->mloopuv_stencil_eval[lt_other->tri[2]]}; /* #BKE_image_acquire_ibuf - TODO: this may be slow. */ uchar rgba_ub[4]; @@ -4048,7 +4047,7 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p CustomData_MeshMasks cddata_masks = scene_eval->customdata_mask; cddata_masks.fmask |= CD_MASK_MTFACE; - cddata_masks.lmask |= CD_MASK_MLOOPUV; + cddata_masks.lmask |= CD_MASK_PROP_FLOAT2; if (ps->do_face_sel) { cddata_masks.vmask |= CD_MASK_ORIGINDEX; cddata_masks.emask |= CD_MASK_ORIGINDEX; @@ -4056,7 +4055,7 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p } ps->me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &cddata_masks); - if (!CustomData_has_layer(&ps->me_eval->ldata, CD_MLOOPUV)) { + if (!CustomData_has_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2)) { ps->me_eval = nullptr; return false; } @@ -4094,38 +4093,39 @@ static bool proj_paint_state_mesh_eval_init(const bContext *C, ProjPaintState *p ps->mlooptri_eval = BKE_mesh_runtime_looptri_ensure(ps->me_eval); ps->totlooptri_eval = BKE_mesh_runtime_looptri_len(ps->me_eval); - ps->poly_to_loop_uv = static_cast( - MEM_mallocN(ps->totpoly_eval * sizeof(MLoopUV *), "proj_paint_mtfaces")); + ps->poly_to_loop_uv = static_cast( + MEM_mallocN(ps->totpoly_eval * sizeof(float(*)[2]), "proj_paint_mtfaces")); return true; } struct ProjPaintLayerClone { - const MLoopUV *mloopuv_clone_base; + const float (*mloopuv_clone_base)[2]; const TexPaintSlot *slot_last_clone; const TexPaintSlot *slot_clone; }; static void proj_paint_layer_clone_init(ProjPaintState *ps, ProjPaintLayerClone *layer_clone) { - const MLoopUV *mloopuv_clone_base = nullptr; + const float(*mloopuv_clone_base)[2] = nullptr; /* use clone mtface? */ if (ps->do_layer_clone) { - const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV); + const int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->ldata, + CD_PROP_FLOAT2); - ps->poly_to_loop_uv_clone = static_cast( - MEM_mallocN(ps->totpoly_eval * sizeof(MLoopUV *), "proj_paint_mtfaces")); + ps->poly_to_loop_uv_clone = static_cast( + MEM_mallocN(ps->totpoly_eval * sizeof(float(*)[2]), "proj_paint_mtfaces")); if (layer_num != -1) { - mloopuv_clone_base = static_cast( - CustomData_get_layer_n(&ps->me_eval->ldata, CD_MLOOPUV, layer_num)); + mloopuv_clone_base = static_cast( + CustomData_get_layer_n(&ps->me_eval->ldata, CD_PROP_FLOAT2, layer_num)); } if (mloopuv_clone_base == nullptr) { /* get active instead */ - mloopuv_clone_base = static_cast( - CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV)); + mloopuv_clone_base = static_cast( + CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2)); } } @@ -4154,10 +4154,10 @@ static bool project_paint_clone_face_skip(ProjPaintState *ps, if (ps->do_material_slots) { if (lc->slot_clone != lc->slot_last_clone) { if (!lc->slot_clone->uvname || - !(lc->mloopuv_clone_base = static_cast(CustomData_get_layer_named( - &ps->me_eval->ldata, CD_MLOOPUV, lc->slot_clone->uvname)))) { - lc->mloopuv_clone_base = static_cast( - CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV)); + !(lc->mloopuv_clone_base = static_cast(CustomData_get_layer_named( + &ps->me_eval->ldata, CD_PROP_FLOAT2, lc->slot_clone->uvname)))) { + lc->mloopuv_clone_base = static_cast( + CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2)); } lc->slot_last_clone = lc->slot_clone; } @@ -4299,7 +4299,7 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps, MemArena *arena, const ProjPaintFaceLookup *face_lookup, ProjPaintLayerClone *layer_clone, - const MLoopUV *mloopuv_base, + const float (*mloopuv_base)[2], const bool is_multi_view) { /* Image Vars - keep track of images we have used */ @@ -4325,17 +4325,17 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps, slot = project_paint_face_paint_slot(ps, tri_index); /* all faces should have a valid slot, reassert here */ if (slot == nullptr) { - mloopuv_base = static_cast( - CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV)); + mloopuv_base = static_cast( + CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2)); tpage = ps->canvas_ima; } else { if (slot != slot_last) { if (!slot->uvname || - !(mloopuv_base = static_cast( - CustomData_get_layer_named(&ps->me_eval->ldata, CD_MLOOPUV, slot->uvname)))) { - mloopuv_base = static_cast( - CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV)); + !(mloopuv_base = static_cast(CustomData_get_layer_named( + &ps->me_eval->ldata, CD_PROP_FLOAT2, slot->uvname)))) { + mloopuv_base = static_cast( + CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2)); } slot_last = slot; } @@ -4360,7 +4360,7 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps, ps->poly_to_loop_uv[lt->poly] = mloopuv_base; - tile = project_paint_face_paint_tile(tpage, mloopuv_base[lt->tri[0]].uv); + tile = project_paint_face_paint_tile(tpage, mloopuv_base[lt->tri[0]]); #ifndef PROJ_DEBUG_NOSEAMBLEED project_paint_bleed_add_face_user(ps, arena, lt, tri_index); @@ -4478,7 +4478,7 @@ static void project_paint_begin(const bContext *C, { ProjPaintLayerClone layer_clone; ProjPaintFaceLookup face_lookup; - const MLoopUV *mloopuv_base = nullptr; + const float(*mloopuv_base)[2] = nullptr; /* At the moment this is just ps->arena_mt[0], but use this to show were not multi-threading. */ MemArena *arena; @@ -4508,17 +4508,17 @@ static void project_paint_begin(const bContext *C, proj_paint_layer_clone_init(ps, &layer_clone); if (ps->do_layer_stencil || ps->do_stencil_brush) { - // int layer_num = CustomData_get_stencil_layer(&ps->me_eval->ldata, CD_MLOOPUV); - int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->ldata, CD_MLOOPUV); + // int layer_num = CustomData_get_stencil_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2); + int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->ldata, CD_PROP_FLOAT2); if (layer_num != -1) { - ps->mloopuv_stencil_eval = static_cast( - CustomData_get_layer_n(&ps->me_eval->ldata, CD_MLOOPUV, layer_num)); + ps->mloopuv_stencil_eval = static_cast( + CustomData_get_layer_n(&ps->me_eval->ldata, CD_PROP_FLOAT2, layer_num)); } if (ps->mloopuv_stencil_eval == nullptr) { /* get active instead */ - ps->mloopuv_stencil_eval = static_cast( - CustomData_get_layer(&ps->me_eval->ldata, CD_MLOOPUV)); + ps->mloopuv_stencil_eval = static_cast( + CustomData_get_layer(&ps->me_eval->ldata, CD_PROP_FLOAT2)); } if (ps->do_stencil_brush) { @@ -6424,7 +6424,7 @@ bool ED_paint_proj_mesh_data_check( } me = BKE_mesh_from_object(ob); - layernum = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); + layernum = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); if (layernum == 0) { hasuvs = false; diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 0a8dbd58b2a..ccfdd0c0e49 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -312,8 +312,8 @@ static void imapaint_pick_uv( findex = index_mp_to_orig ? index_mp_to_orig[lt->poly] : lt->poly; if (findex == faceindex) { - const MLoopUV *mloopuv; - const MLoopUV *tri_uv[3]; + const float(*mloopuv)[2]; + const float *tri_uv[3]; float tri_co[3][3]; for (int j = 3; j--;) { @@ -329,17 +329,18 @@ static void imapaint_pick_uv( slot = &ma->texpaintslot[ma->paint_active_slot]; if (!(slot && slot->uvname && - (mloopuv = CustomData_get_layer_named(&me_eval->ldata, CD_MLOOPUV, slot->uvname)))) { - mloopuv = CustomData_get_layer(&me_eval->ldata, CD_MLOOPUV); + (mloopuv = CustomData_get_layer_named( + &me_eval->ldata, CD_PROP_FLOAT2, slot->uvname)))) { + mloopuv = CustomData_get_layer(&me_eval->ldata, CD_PROP_FLOAT2); } } else { - mloopuv = CustomData_get_layer(&me_eval->ldata, CD_MLOOPUV); + mloopuv = CustomData_get_layer(&me_eval->ldata, CD_PROP_FLOAT2); } - tri_uv[0] = &mloopuv[lt->tri[0]]; - tri_uv[1] = &mloopuv[lt->tri[1]]; - tri_uv[2] = &mloopuv[lt->tri[2]]; + tri_uv[0] = mloopuv[lt->tri[0]]; + tri_uv[1] = mloopuv[lt->tri[1]]; + tri_uv[2] = mloopuv[lt->tri[2]]; p[0] = xy[0]; p[1] = xy[1]; @@ -347,8 +348,8 @@ static void imapaint_pick_uv( imapaint_tri_weights(matrix, view, UNPACK3(tri_co), p, w); absw = fabsf(w[0]) + fabsf(w[1]) + fabsf(w[2]); if (absw < minabsw) { - uv[0] = tri_uv[0]->uv[0] * w[0] + tri_uv[1]->uv[0] * w[1] + tri_uv[2]->uv[0] * w[2]; - uv[1] = tri_uv[0]->uv[1] * w[0] + tri_uv[1]->uv[1] * w[1] + tri_uv[2]->uv[1] * w[2]; + uv[0] = tri_uv[0][0] * w[0] + tri_uv[1][0] * w[1] + tri_uv[2][0] * w[2]; + uv[1] = tri_uv[0][1] * w[0] + tri_uv[1][1] * w[1] + tri_uv[2][1] * w[2]; minabsw = absw; } } @@ -423,7 +424,7 @@ void paint_sample_color( uint faceindex; uint totpoly = me->totpoly; - if (CustomData_has_layer(&me_eval->ldata, CD_MLOOPUV)) { + if (CustomData_has_layer(&me_eval->ldata, CD_PROP_FLOAT2)) { ED_view3d_viewcontext_init(C, &vc, depsgraph); view3d_operator_needs_opengl(C); diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index 4739fa52674..6e622a56515 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -219,7 +219,7 @@ static void HC_relaxation_iteration_uv(BMEditMesh *em, apply_sculpt_data_constraints(sculptdata, sculptdata->uv[i].uv); for (element = sculptdata->uv[i].element; element; element = element->next) { - MLoopUV *luv; + float(*luv)[2]; BMLoop *l; if (element->separate && element != sculptdata->uv[i].element) { @@ -227,8 +227,8 @@ static void HC_relaxation_iteration_uv(BMEditMesh *em, } l = element->l; - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(luv->uv, sculptdata->uv[i].uv); + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_PROP_FLOAT2); + copy_v2_v2(*luv, sculptdata->uv[i].uv); } } } @@ -302,7 +302,7 @@ static void laplacian_relaxation_iteration_uv(BMEditMesh *em, apply_sculpt_data_constraints(sculptdata, sculptdata->uv[i].uv); for (element = sculptdata->uv[i].element; element; element = element->next) { - MLoopUV *luv; + float(*luv)[2]; BMLoop *l; if (element->separate && element != sculptdata->uv[i].element) { @@ -310,8 +310,8 @@ static void laplacian_relaxation_iteration_uv(BMEditMesh *em, } l = element->l; - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(luv->uv, sculptdata->uv[i].uv); + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_PROP_FLOAT2); + copy_v2_v2(*luv, sculptdata->uv[i].uv); } } } @@ -323,12 +323,12 @@ static void add_weighted_edge(float (*delta_buf)[3], const UvElement *storage, const UvElement *ele_next, const UvElement *ele_prev, - const MLoopUV *luv_next, - const MLoopUV *luv_prev, + const float luv_next[2], + const float luv_prev[2], const float weight) { float delta[2]; - sub_v2_v2v2(delta, luv_next->uv, luv_prev->uv); + sub_v2_v2v2(delta, luv_next, luv_prev); bool code1 = (ele_prev->flag & MARK_BOUNDARY); bool code2 = (ele_next->flag & MARK_BOUNDARY); @@ -380,7 +380,7 @@ static void relaxation_iteration_uv(BMEditMesh *em, struct UvElement **head_table = BM_uv_element_map_ensure_head_table(sculptdata->elementMap); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); BLI_assert(cd_loop_uv_offset >= 0); const int total_uvs = sculptdata->elementMap->total_uvs; @@ -397,9 +397,9 @@ static void relaxation_iteration_uv(BMEditMesh *em, const float *v_prev_co = ele_prev->l->v->co; const float *v_next_co = ele_next->l->v->co; - const MLoopUV *luv_curr = BM_ELEM_CD_GET_VOID_P(ele_curr->l, cd_loop_uv_offset); - const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(ele_next->l, cd_loop_uv_offset); - const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(ele_prev->l, cd_loop_uv_offset); + const float(*luv_curr)[2] = BM_ELEM_CD_GET_FLOAT2_P(ele_curr->l, cd_loop_uv_offset); + const float(*luv_next)[2] = BM_ELEM_CD_GET_FLOAT2_P(ele_next->l, cd_loop_uv_offset); + const float(*luv_prev)[2] = BM_ELEM_CD_GET_FLOAT2_P(ele_prev->l, cd_loop_uv_offset); const UvElement *head_curr = head_table[ele_curr - sculptdata->elementMap->storage]; const UvElement *head_next = head_table[ele_next - sculptdata->elementMap->storage]; @@ -407,11 +407,11 @@ static void relaxation_iteration_uv(BMEditMesh *em, /* If the mesh is triangulated with no boundaries, only one edge is required. */ const float weight_curr = tri_weight_v3(method, v_curr_co, v_prev_co, v_next_co); - add_weighted_edge(delta_buf, storage, head_next, head_prev, luv_next, luv_prev, weight_curr); + add_weighted_edge(delta_buf, storage, head_next, head_prev, *luv_next, *luv_prev, weight_curr); /* Triangulated with a boundary? We need the incoming edges to solve the boundary. */ const float weight_prev = tri_weight_v3(method, v_prev_co, v_curr_co, v_next_co); - add_weighted_edge(delta_buf, storage, head_next, head_curr, luv_next, luv_curr, weight_prev); + add_weighted_edge(delta_buf, storage, head_next, head_curr, *luv_next, *luv_curr, weight_prev); if (method == UV_SCULPT_TOOL_RELAX_LAPLACIAN) { /* Laplacian method has zero weights on virtual edges. */ @@ -420,7 +420,7 @@ static void relaxation_iteration_uv(BMEditMesh *em, /* Meshes with quads (or other n-gons) need "virtual" edges too. */ const float weight_next = tri_weight_v3(method, v_next_co, v_curr_co, v_prev_co); - add_weighted_edge(delta_buf, storage, head_prev, head_curr, luv_prev, luv_curr, weight_next); + add_weighted_edge(delta_buf, storage, head_prev, head_curr, *luv_prev, *luv_curr, weight_next); } Brush *brush = BKE_paint_brush(sculptdata->uvsculpt); @@ -444,18 +444,18 @@ static void relaxation_iteration_uv(BMEditMesh *em, const float *delta_sum = delta_buf[adj_el->element - storage]; { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(adj_el->element->l, cd_loop_uv_offset); - BLI_assert(adj_el->uv == luv->uv); /* Only true for head. */ - adj_el->uv[0] = luv->uv[0] + strength * safe_divide(delta_sum[0], delta_sum[2]); - adj_el->uv[1] = luv->uv[1] + strength * safe_divide(delta_sum[1], delta_sum[2]); + const float(*luv)[2] = BM_ELEM_CD_GET_FLOAT2_P(adj_el->element->l, cd_loop_uv_offset); + BLI_assert(adj_el->uv == (float *)luv); /* Only true for head. */ + adj_el->uv[0] = (*luv)[0] + strength * safe_divide(delta_sum[0], delta_sum[2]); + adj_el->uv[1] = (*luv)[1] + strength * safe_divide(delta_sum[1], delta_sum[2]); apply_sculpt_data_constraints(sculptdata, adj_el->uv); } /* Copy UV co-ordinates to all UvElements. */ UvElement *tail = adj_el->element; while (tail) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(tail->l, cd_loop_uv_offset); - copy_v2_v2(luv->uv, adj_el->uv); + float(*luv)[2] = BM_ELEM_CD_GET_FLOAT2_P(tail->l, cd_loop_uv_offset); + copy_v2_v2(*luv, adj_el->uv); tail = tail->next; if (tail && tail->separate) { break; @@ -527,7 +527,7 @@ static void uv_sculpt_stroke_apply(bContext *C, apply_sculpt_data_constraints(sculptdata, sculptdata->uv[i].uv); for (element = sculptdata->uv[i].element; element; element = element->next) { - MLoopUV *luv; + float(*luv)[2]; BMLoop *l; if (element->separate && element != sculptdata->uv[i].element) { @@ -535,8 +535,8 @@ static void uv_sculpt_stroke_apply(bContext *C, } l = element->l; - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(luv->uv, sculptdata->uv[i].uv); + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_PROP_FLOAT2); + copy_v2_v2(*luv, sculptdata->uv[i].uv); } } } @@ -570,7 +570,7 @@ static void uv_sculpt_stroke_apply(bContext *C, apply_sculpt_data_constraints(sculptdata, sculptdata->uv[uvindex].uv); for (element = sculptdata->uv[uvindex].element; element; element = element->next) { - MLoopUV *luv; + float(*luv)[2]; BMLoop *l; if (element->separate && element != sculptdata->uv[uvindex].element) { @@ -578,8 +578,8 @@ static void uv_sculpt_stroke_apply(bContext *C, } l = element->l; - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(luv->uv, sculptdata->uv[uvindex].uv); + luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_PROP_FLOAT2); + copy_v2_v2(*luv, sculptdata->uv[uvindex].uv); } } if (sima->flag & SI_LIVE_UNWRAP) { @@ -666,7 +666,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm ARegion *region = CTX_wm_region(C); float co[2]; BMFace *efa; - MLoopUV *luv; + float(*luv)[2]; BMLoop *l; BMIter iter, liter; @@ -736,6 +736,8 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm data->totalUniqueUvs = unique_uvs; /* Index for the UvElements. */ int counter = -1; + + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); /* initialize the unique UVs */ for (int i = 0; i < bm->totvert; i++) { UvElement *element = data->elementMap->vertex[i]; @@ -749,14 +751,13 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm continue; } - l = element->l; - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + luv = BM_ELEM_CD_GET_FLOAT2_P(element->l, offsets.uv); counter++; data->uv[counter].element = element; - data->uv[counter].uv = luv->uv; + data->uv[counter].uv = *luv; if (data->tool != UV_SCULPT_TOOL_GRAB) { - if (luv->flag & MLOOPUV_PINNED) { + if (BM_ELEM_CD_GET_BOOL(element->l, offsets.pin)) { data->uv[counter].is_locked = true; } } diff --git a/source/blender/editors/space_view3d/view3d_draw.cc b/source/blender/editors/space_view3d/view3d_draw.cc index e45bf3c1488..91bfc104f5b 100644 --- a/source/blender/editors/space_view3d/view3d_draw.cc +++ b/source/blender/editors/space_view3d/view3d_draw.cc @@ -2413,12 +2413,12 @@ void ED_view3d_datamask(const bContext *C, CustomData_MeshMasks *r_cddata_masks) { if (ELEM(v3d->shading.type, OB_TEXTURE, OB_MATERIAL, OB_RENDER)) { - r_cddata_masks->lmask |= CD_MASK_MLOOPUV | CD_MASK_PROP_BYTE_COLOR; + r_cddata_masks->lmask |= CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_BYTE_COLOR; r_cddata_masks->vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR; } else if (v3d->shading.type == OB_SOLID) { if (v3d->shading.color_type == V3D_SHADING_TEXTURE_COLOR) { - r_cddata_masks->lmask |= CD_MASK_MLOOPUV; + r_cddata_masks->lmask |= CD_MASK_PROP_FLOAT2; } if (v3d->shading.color_type == V3D_SHADING_VERTEX_COLOR) { r_cddata_masks->lmask |= CD_MASK_PROP_BYTE_COLOR; diff --git a/source/blender/editors/transform/transform_convert_mesh_uv.c b/source/blender/editors/transform/transform_convert_mesh_uv.c index 5c90395ae22..c7d5411f907 100644 --- a/source/blender/editors/transform/transform_convert_mesh_uv.c +++ b/source/blender/editors/transform/transform_convert_mesh_uv.c @@ -90,7 +90,8 @@ static void uv_set_connectivity_distance(const ToolSettings *ts, BLI_LINKSTACK_INIT(queue); BLI_LINKSTACK_INIT(queue_next); - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); + BMIter fiter, liter; BMVert *f; BMLoop *l; @@ -105,7 +106,7 @@ static void uv_set_connectivity_distance(const ToolSettings *ts, BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { float dist; - bool uv_vert_sel = uvedit_uv_select_test_ex(ts, l, cd_loop_uv_offset); + bool uv_vert_sel = uvedit_uv_select_test_ex(ts, l, offsets); if (uv_vert_sel) { BLI_LINKSTACK_PUSH(queue, l); @@ -136,10 +137,10 @@ static void uv_set_connectivity_distance(const ToolSettings *ts, BMLoop *l_other, *l_connected; BMIter l_connected_iter; - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); float l_uv[2]; - copy_v2_v2(l_uv, luv->uv); + copy_v2_v2(l_uv, luv); mul_v2_v2(l_uv, aspect); BM_ITER_ELEM (l_other, &liter, l->f, BM_LOOPS_OF_FACE) { @@ -147,9 +148,9 @@ static void uv_set_connectivity_distance(const ToolSettings *ts, continue; } float other_uv[2], edge_vec[2]; - MLoopUV *luv_other = BM_ELEM_CD_GET_VOID_P(l_other, cd_loop_uv_offset); + float *luv_other = BM_ELEM_CD_GET_FLOAT_P(l_other, offsets.uv); - copy_v2_v2(other_uv, luv_other->uv); + copy_v2_v2(other_uv, luv_other); mul_v2_v2(other_uv, aspect); sub_v2_v2v2(edge_vec, l_uv, other_uv); @@ -179,14 +180,14 @@ static void uv_set_connectivity_distance(const ToolSettings *ts, continue; } - MLoopUV *luv_connected = BM_ELEM_CD_GET_VOID_P(l_connected, cd_loop_uv_offset); + float *luv_connected = BM_ELEM_CD_GET_FLOAT_P(l_connected, offsets.uv); connected_vert_sel = BM_elem_flag_test_bool(l_connected, TMP_LOOP_SELECT_TAG); /* Check if this loop is connected in UV space. * If the uv loops share the same selection state (if not, they are not connected as * they have been ripped or other edit commands have separated them). */ bool connected = other_vert_sel == connected_vert_sel && - equals_v2v2(luv_other->uv, luv_connected->uv); + equals_v2v2(luv_other, luv_connected); if (!connected) { continue; } @@ -261,7 +262,7 @@ static void createTransUVs(bContext *C, TransInfo *t) int co_num; } *island_center = NULL; int count = 0, countsel = 0; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); if (!ED_space_image_show_uvedit(sima, tc->obedit)) { continue; @@ -291,15 +292,15 @@ static void createTransUVs(bContext *C, TransInfo *t) /* Make sure that the loop element flag is cleared for when we use it in * uv_set_connectivity_distance later. */ BM_elem_flag_disable(l, BM_ELEM_TAG); - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (uvedit_uv_select_test(scene, l, offsets)) { countsel++; if (island_center) { UvElement *element = BM_uv_element_get(elementmap, efa, l); if (element->flag == false) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - add_v2_v2(island_center[element->island].co, luv->uv); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + add_v2_v2(island_center[element->island].co, luv); island_center[element->island].co_num++; element->flag = true; } @@ -354,8 +355,8 @@ static void createTransUVs(bContext *C, TransInfo *t) } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - const bool selected = uvedit_uv_select_test(scene, l, cd_loop_uv_offset); - MLoopUV *luv; + const bool selected = uvedit_uv_select_test(scene, l, offsets); + float(*luv)[2]; const float *center = NULL; float prop_distance = FLT_MAX; @@ -375,8 +376,8 @@ static void createTransUVs(bContext *C, TransInfo *t) } } - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - UVsToTransData(t->aspect, td++, td2d++, luv->uv, center, prop_distance, selected); + luv = (float(*)[2])BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + UVsToTransData(t->aspect, td++, td2d++, *luv, center, prop_distance, selected); } } diff --git a/source/blender/editors/uvedit/uvedit_buttons.c b/source/blender/editors/uvedit/uvedit_buttons.c index 10368f7d43f..baa6f7dbd45 100644 --- a/source/blender/editors/uvedit/uvedit_buttons.c +++ b/source/blender/editors/uvedit/uvedit_buttons.c @@ -47,7 +47,7 @@ static int uvedit_center(Scene *scene, Object **objects, uint objects_len, float BMFace *f; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; + float *luv; int tot = 0; zero_v2(center); @@ -55,7 +55,7 @@ static int uvedit_center(Scene *scene, Object **objects, uint objects_len, float for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, f)) { @@ -63,9 +63,9 @@ static int uvedit_center(Scene *scene, Object **objects, uint objects_len, float } BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - add_v2_v2(center, luv->uv); + if (uvedit_uv_select_test(scene, l, offsets)) { + luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + add_v2_v2(center, luv); tot++; } } @@ -88,13 +88,13 @@ static void uvedit_translate(Scene *scene, BMFace *f; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; + float *luv; for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, f)) { @@ -102,9 +102,9 @@ static void uvedit_translate(Scene *scene, } BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - add_v2_v2(luv->uv, delta); + if (uvedit_uv_select_test(scene, l, offsets)) { + luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + add_v2_v2(luv, delta); } } } diff --git a/source/blender/editors/uvedit/uvedit_clipboard.cc b/source/blender/editors/uvedit/uvedit_clipboard.cc index 998da929415..9c8722b36a0 100644 --- a/source/blender/editors/uvedit/uvedit_clipboard.cc +++ b/source/blender/editors/uvedit/uvedit_clipboard.cc @@ -157,8 +157,8 @@ void UV_ClipboardBuffer::append(UvElementMap *element_map, const int cd_loop_uv_ if (!element->separate) { continue; } - MLoopUV *luv = static_cast(BM_ELEM_CD_GET_VOID_P(element->l, cd_loop_uv_offset)); - uv.append(std::make_pair(luv->uv[0], luv->uv[1])); + float *luv = BM_ELEM_CD_GET_FLOAT_P(element->l, cd_loop_uv_offset); + uv.append(std::make_pair(luv[0], luv[1])); } } } @@ -183,9 +183,9 @@ void UV_ClipboardBuffer::write_uvs(UvElementMap *element_map, BLI_assert(unique_uv < label.size()); const std::pair &source_uv = uv_clipboard->uv[label[unique_uv]]; while (element) { - MLoopUV *luv = static_cast(BM_ELEM_CD_GET_VOID_P(element->l, cd_loop_uv_offset)); - luv->uv[0] = source_uv.first; - luv->uv[1] = source_uv.second; + float *luv = BM_ELEM_CD_GET_FLOAT_P(element->l, cd_loop_uv_offset); + luv[0] = source_uv.first; + luv[1] = source_uv.second; element = element->next; if (!element || element->separate) { break; @@ -282,7 +282,7 @@ static int uv_copy_exec(bContext *C, wmOperator * /*op*/) UvElementMap *element_map = BM_uv_element_map_create( em->bm, scene, true, false, use_seams, true); if (element_map) { - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); uv_clipboard->append(element_map, cd_loop_uv_offset); } BM_uv_element_map_free(element_map); @@ -313,7 +313,7 @@ static int uv_paste_exec(bContext *C, wmOperator * /*op*/) BMEditMesh *em = BKE_editmesh_from_object(ob); const bool use_seams = false; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); UvElementMap *dest_element_map = BM_uv_element_map_create( em->bm, scene, true, false, use_seams, true); diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index 098c6ad8655..f691cb7d79e 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -121,13 +121,13 @@ BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene, bool uvedit_vert_is_edge_select_any_other(const struct Scene *scene, struct BMLoop *l, - const int cd_loop_uv_offset); + BMUVOffsets offsets); bool uvedit_vert_is_face_select_any_other(const struct Scene *scene, struct BMLoop *l, - const int cd_loop_uv_offset); + BMUVOffsets offsets); bool uvedit_vert_is_all_other_faces_selected(const struct Scene *scene, struct BMLoop *l, - const int cd_loop_uv_offset); + BMUVOffsets offsets); /* utility tool functions */ @@ -171,7 +171,7 @@ bool uvedit_select_is_any_selected_multi(const struct Scene *scene, */ const float *uvedit_first_selected_uv_from_vertex(struct Scene *scene, struct BMVert *eve, - int cd_loop_uv_offset); + BMUVOffsets offsets); void UV_OT_select_all(struct wmOperatorType *ot); void UV_OT_select(struct wmOperatorType *ot); diff --git a/source/blender/editors/uvedit/uvedit_islands.cc b/source/blender/editors/uvedit/uvedit_islands.cc index dc572b9f88e..85ee80fe851 100644 --- a/source/blender/editors/uvedit/uvedit_islands.cc +++ b/source/blender/editors/uvedit/uvedit_islands.cc @@ -65,15 +65,15 @@ static void island_uv_transform(FaceIsland *island, * To convert post-transform to pre-transform, use `A * x + b == A * (x + c), c = A^-1 * b` */ - const int cd_loop_uv_offset = island->cd_loop_uv_offset; + const int cd_loop_uv_offset = island->offsets.uv; const int faces_len = island->faces_len; for (int i = 0; i < faces_len; i++) { BMFace *f = island->faces[i]; BMLoop *l; BMIter iter; BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { - MLoopUV *luv = (MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - mul_v2_m2_add_v2v2(luv->uv, matrix, luv->uv, pre_translate); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + mul_v2_m2_add_v2v2(luv, matrix, luv, pre_translate); } } } @@ -134,9 +134,8 @@ static float (*bm_face_array_calc_unique_uv_coords( } BM_elem_flag_disable(l_iter, BM_ELEM_TAG); - const MLoopUV *luv = static_cast( - BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset)); - copy_v2_v2(coords[coords_len++], luv->uv); + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset); + copy_v2_v2(coords[coords_len++], luv); /* Un tag all connected so we don't add them twice. * Note that we will tag other loops not part of `faces` but this is harmless, @@ -150,9 +149,8 @@ static float (*bm_face_array_calc_unique_uv_coords( do { if (l_radial->v == l_iter->v) { if (BM_elem_flag_test(l_radial, BM_ELEM_TAG)) { - const MLoopUV *luv_radial = static_cast( - BM_ELEM_CD_GET_VOID_P(l_radial, cd_loop_uv_offset)); - if (equals_v2v2(luv->uv, luv_radial->uv)) { + const float *luv_radial = BM_ELEM_CD_GET_FLOAT_P(l_radial, cd_loop_uv_offset); + if (equals_v2v2(luv, luv_radial)) { /* Don't add this UV when met in another face in `faces`. */ BM_elem_flag_disable(l_iter, BM_ELEM_TAG); } @@ -172,7 +170,7 @@ static void face_island_uv_rotate_fit_aabb(FaceIsland *island) BMFace **faces = island->faces; const int faces_len = island->faces_len; const float aspect_y = island->aspect_y; - const int cd_loop_uv_offset = island->cd_loop_uv_offset; + const int cd_loop_uv_offset = island->offsets.uv; /* Calculate unique coordinates since calculating a convex hull can be an expensive operation. */ int coords_len; @@ -320,7 +318,7 @@ static float uv_nearest_grid_tile_distance(const int udim_grid[2], * \{ */ struct SharedUVLoopData { - int cd_loop_uv_offset; + BMUVOffsets offsets; bool use_seams; }; @@ -334,7 +332,7 @@ static bool bm_loop_uv_shared_edge_check(const BMLoop *l_a, const BMLoop *l_b, v } } - return BM_loop_uv_share_edge_check((BMLoop *)l_a, (BMLoop *)l_b, data->cd_loop_uv_offset); + return BM_loop_uv_share_edge_check((BMLoop *)l_a, (BMLoop *)l_b, data->offsets.uv); } /** @@ -347,9 +345,9 @@ int bm_mesh_calc_uv_islands(const Scene *scene, const bool only_selected_uvs, const bool use_seams, const float aspect_y, - const int cd_loop_uv_offset) + const BMUVOffsets uv_offsets) { - BLI_assert(cd_loop_uv_offset >= 0); + BLI_assert(uv_offsets.uv >= 0); int island_added = 0; BM_mesh_elem_table_ensure(bm, BM_FACE); @@ -367,7 +365,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene, BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { bool value = false; if (BM_elem_flag_test(f, BM_ELEM_SELECT) && - uvedit_face_select_test(scene, f, cd_loop_uv_offset)) { + uvedit_face_select_test(scene, f, uv_offsets)) { value = true; } BM_elem_flag_set(f, BM_ELEM_TAG, value); @@ -380,7 +378,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene, } struct SharedUVLoopData user_data = {0}; - user_data.cd_loop_uv_offset = cd_loop_uv_offset; + user_data.offsets = uv_offsets; user_data.use_seams = use_seams; const int group_len = BM_mesh_calc_face_groups(bm, @@ -408,7 +406,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene, MEM_callocN(sizeof(*island), __func__)); island->faces = faces; island->faces_len = faces_len; - island->cd_loop_uv_offset = cd_loop_uv_offset; + island->offsets = uv_offsets; island->aspect_y = aspect_y; BLI_addtail(island_list, island); island_added += 1; @@ -626,18 +624,17 @@ static bool island_has_pins(const Scene *scene, const bool only_selected_faces = params->only_selected_faces; BMLoop *l; BMIter iter; - const int cd_loop_uv_offset = island->cd_loop_uv_offset; + const int pin_offset = island->offsets.pin; for (int i = 0; i < island->faces_len; i++) { BMFace *efa = island->faces[i]; if (pin_unselected && only_selected_faces && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { return true; } - BM_ITER_ELEM (l, &iter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = static_cast(BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset)); - if (luv->flag & MLOOPUV_PINNED) { + BM_ITER_ELEM (l, &iter, island->faces[i], BM_LOOPS_OF_FACE) { + if (BM_ELEM_CD_GET_BOOL(l, pin_offset)) { return true; } - if (pin_unselected && !uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (pin_unselected && !uvedit_uv_select_test(scene, l, island->offsets)) { return true; } } @@ -672,8 +669,9 @@ void ED_uvedit_pack_islands_multi(const Scene *scene, bm = em->bm; } BLI_assert(bm); - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - if (cd_loop_uv_offset == -1) { + + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); + if (offsets.uv == -1) { continue; } @@ -700,7 +698,7 @@ void ED_uvedit_pack_islands_multi(const Scene *scene, only_selected_uvs, params->use_seams, aspect_y, - cd_loop_uv_offset); + offsets); /* Remove from linked list and append to blender::Vector. */ LISTBASE_FOREACH_MUTABLE (struct FaceIsland *, island, &island_list) { @@ -728,7 +726,7 @@ void ED_uvedit_pack_islands_multi(const Scene *scene, /* Only calculate selection bounding box if using closest_udim. */ for (int i = 0; i < island->faces_len; i++) { BMFace *f = island->faces[i]; - BM_face_uv_minmax(f, selection_min_co, selection_max_co, island->cd_loop_uv_offset); + BM_face_uv_minmax(f, selection_min_co, selection_max_co, island->offsets.uv); } } @@ -737,7 +735,7 @@ void ED_uvedit_pack_islands_multi(const Scene *scene, } bm_face_array_calc_bounds( - island->faces, island->faces_len, island->cd_loop_uv_offset, &island->bounds_rect); + island->faces, island->faces_len, island->offsets.uv, &island->bounds_rect); } /* Center of bounding box containing all selected UVs. */ diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index dbbba2656fd..e35e05a9ef3 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -88,7 +88,7 @@ static int UNUSED_FUNCTION(ED_operator_uvmap_mesh)(bContext *C) if (ob && ob->type == OB_MESH) { Mesh *me = ob->data; - if (CustomData_get_layer(&me->ldata, CD_MLOOPUV) != NULL) { + if (CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2) != NULL) { return 1; } } @@ -204,9 +204,9 @@ bool ED_uvedit_minmax_multi( BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; + float *luv; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { @@ -214,9 +214,9 @@ bool ED_uvedit_minmax_multi( } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - minmax_v2v2_v2(r_min, r_max, luv->uv); + if (uvedit_uv_select_test(scene, l, offsets)) { + luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + minmax_v2v2_v2(r_min, r_max, luv); changed = true; } } @@ -235,14 +235,12 @@ void ED_uvedit_select_all(BMesh *bm) BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; - - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag |= (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL); + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true); } } } @@ -262,9 +260,9 @@ static bool ED_uvedit_median_multi(const Scene *scene, BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; + float *luv; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { @@ -272,9 +270,9 @@ static bool ED_uvedit_median_multi(const Scene *scene, } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - add_v2_v2(co, luv->uv); + luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + if (uvedit_uv_select_test(scene, l, offsets)) { + add_v2_v2(co, luv); sel++; } } @@ -371,7 +369,7 @@ static bool uvedit_uv_align_weld(Scene *scene, const float cent[2]) { bool changed = false; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); BMIter iter; BMFace *efa; @@ -383,19 +381,19 @@ static bool uvedit_uv_align_weld(Scene *scene, BMIter liter; BMLoop *l; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (!uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (!uvedit_uv_select_test(scene, l, offsets)) { continue; } - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_VOID_P(l, offsets.uv); if (ELEM(tool, UV_ALIGN_X, UV_WELD)) { - if (luv->uv[0] != cent[0]) { - luv->uv[0] = cent[0]; + if (luv[0] != cent[0]) { + luv[0] = cent[0]; changed = true; } } if (ELEM(tool, UV_ALIGN_Y, UV_WELD)) { - if (luv->uv[1] != cent[1]) { - luv->uv[1] = cent[1]; + if (luv[1] != cent[1]) { + luv[1] = cent[1]; changed = true; } } @@ -404,17 +402,17 @@ static bool uvedit_uv_align_weld(Scene *scene, return changed; } -/** Bitwise-or together, then choose #MLoopUV with highest value. */ +/** Bitwise-or together, then choose loop with highest value. */ typedef enum eUVEndPointPrecedence { UVEP_INVALID = 0, UVEP_SELECTED = (1 << 0), UVEP_PINNED = (1 << 1), /* i.e. Pinned verts are preferred to selected. */ } eUVEndPointPrecedence; -static eUVEndPointPrecedence uvedit_line_update_get_precedence(const MLoopUV *luv) +static eUVEndPointPrecedence uvedit_line_update_get_precedence(const bool pinned) { eUVEndPointPrecedence precedence = UVEP_SELECTED; - if (luv->flag & MLOOPUV_PINNED) { + if (pinned) { precedence |= UVEP_PINNED; } return precedence; @@ -424,16 +422,17 @@ static eUVEndPointPrecedence uvedit_line_update_get_precedence(const MLoopUV *lu * Helper to find two endpoints (`a` and `b`) which have higher precedence, and are far apart. * Note that is only a heuristic and won't always find the best two endpoints. */ -static bool uvedit_line_update_endpoint(const MLoopUV *luv, +static bool uvedit_line_update_endpoint(const float *luv, + const bool pinned, float uv_a[2], eUVEndPointPrecedence *prec_a, float uv_b[2], eUVEndPointPrecedence *prec_b) { - eUVEndPointPrecedence flags = uvedit_line_update_get_precedence(luv); + eUVEndPointPrecedence flags = uvedit_line_update_get_precedence(pinned); - float len_sq_a = len_squared_v2v2(uv_a, luv->uv); - float len_sq_b = len_squared_v2v2(uv_b, luv->uv); + float len_sq_a = len_squared_v2v2(uv_a, luv); + float len_sq_b = len_squared_v2v2(uv_b, luv); /* Caching the value of `len_sq_ab` is unlikely to be faster than recalculating. * Profile before optimizing. */ @@ -441,13 +440,13 @@ static bool uvedit_line_update_endpoint(const MLoopUV *luv, if ((*prec_a < flags && 0.0f < len_sq_b) || (*prec_a == flags && len_sq_ab < len_sq_b)) { *prec_a = flags; - copy_v2_v2(uv_a, luv->uv); + copy_v2_v2(uv_a, luv); return true; } if ((*prec_b < flags && 0.0f < len_sq_a) || (*prec_b == flags && len_sq_ab < len_sq_a)) { *prec_b = flags; - copy_v2_v2(uv_b, luv->uv); + copy_v2_v2(uv_b, luv); return true; } @@ -460,7 +459,7 @@ static bool uvedit_line_update_endpoint(const MLoopUV *luv, */ static bool uvedit_uv_straighten_elements(const UvElement *element, const int len, - const int cd_loop_uv_offset, + const BMUVOffsets offsets, const eUVWeldAlign tool) { float uv_start[2]; @@ -472,8 +471,9 @@ static bool uvedit_uv_straighten_elements(const UvElement *element, for (int i = 0; i < 10; i++) { /* Heuristic to prevent infinite loop. */ bool update = false; for (int j = 0; j < len; j++) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(element[j].l, cd_loop_uv_offset); - update |= uvedit_line_update_endpoint(luv, uv_start, &prec_start, uv_end, &prec_end); + float *luv = BM_ELEM_CD_GET_FLOAT_P(element[j].l, offsets.uv); + bool pinned = BM_ELEM_CD_GET_BOOL(element[j].l, offsets.pin); + update |= uvedit_line_update_endpoint(luv, pinned, uv_start, &prec_start, uv_end, &prec_end); } if (!update) { break; @@ -508,19 +508,19 @@ static bool uvedit_uv_straighten_elements(const UvElement *element, bool changed = false; for (int j = 0; j < len; j++) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(element[j].l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(element[j].l, offsets.uv); /* Projection of point (x, y) over line (x1, y1, x2, y2) along X axis: * new_y = (y2 - y1) / (x2 - x1) * (x - x1) + y1 * Maybe this should be a BLI func? Or is it already existing? * Could use interp_v2_v2v2, but not sure it's worth it here. */ if (tool_local == UV_STRAIGHTEN_X) { - luv->uv[0] = a * (luv->uv[1] - uv_start[1]) + uv_start[0]; + luv[0] = a * (luv[1] - uv_start[1]) + uv_start[0]; } else if (tool_local == UV_STRAIGHTEN_Y) { - luv->uv[1] = a * (luv->uv[0] - uv_start[0]) + uv_start[1]; + luv[1] = a * (luv[0] - uv_start[0]) + uv_start[1]; } else { - closest_to_line_segment_v2(luv->uv, luv->uv, uv_start, uv_end); + closest_to_line_segment_v2(luv, luv, uv_start, uv_end); } changed = true; /* TODO: Did the UV actually move? */ } @@ -532,8 +532,8 @@ static bool uvedit_uv_straighten_elements(const UvElement *element, */ static bool uvedit_uv_straighten(Scene *scene, BMesh *bm, eUVWeldAlign tool) { - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - if (cd_loop_uv_offset == -1) { + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); + if (offsets.uv == -1) { return false; } @@ -546,7 +546,7 @@ static bool uvedit_uv_straighten(Scene *scene, BMesh *bm, eUVWeldAlign tool) for (int i = 0; i < element_map->total_islands; i++) { changed |= uvedit_uv_straighten_elements(element_map->storage + element_map->island_indices[i], element_map->island_total_uvs[i], - cd_loop_uv_offset, + offsets, tool); } @@ -578,7 +578,7 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool) continue; } - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BMIter iter, liter; BMFace *efa; @@ -590,9 +590,9 @@ static void uv_weld_align(bContext *C, eUVWeldAlign tool) } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - minmax_v2v2_v2(min, max, luv->uv); + if (uvedit_uv_select_test(scene, l, offsets)) { + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + minmax_v2v2_v2(min, max, luv); } } } @@ -701,8 +701,8 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op) bool *changed = MEM_callocN(sizeof(bool) * objects_len, "uv_remove_doubles_selected.changed"); - /* Maximum index of an objects[i]'s MLoopUVs in MLoopUV_arr. - * It helps find which MLoopUV in *MLoopUV_arr belongs to which object. */ + /* Maximum index of an objects[i]'s UVs in UV_arr. + * It helps find which UV in *mloopuv_arr belongs to which object. */ uint *ob_mloopuv_max_idx = MEM_callocN(sizeof(uint) * objects_len, "uv_remove_doubles_selected.ob_mloopuv_max_idx"); @@ -724,7 +724,7 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op) int *duplicates = NULL; BLI_array_declare(duplicates); - MLoopUV **mloopuv_arr = NULL; + float **mloopuv_arr = NULL; BLI_array_declare(mloopuv_arr); int mloopuv_count = 0; /* Also used for *duplicates count. */ @@ -740,7 +740,7 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op) continue; } - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { @@ -748,9 +748,9 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op) } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - BLI_kdtree_2d_insert(tree, mloopuv_count, luv->uv); + if (uvedit_uv_select_test(scene, l, offsets)) { + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + BLI_kdtree_2d_insert(tree, mloopuv_count, luv); BLI_array_append(duplicates, -1); BLI_array_append(mloopuv_arr, luv); mloopuv_count++; @@ -777,7 +777,7 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op) if (duplicates[i] != i) { /* If not self then accumulate uv for averaging. * Self uv is already present in accumulator */ - add_v2_v2(mloopuv_arr[duplicates[i]]->uv, mloopuv_arr[i]->uv); + add_v2_v2(mloopuv_arr[duplicates[i]], mloopuv_arr[i]); } uv_duplicate_count[duplicates[i]]++; } @@ -787,14 +787,14 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op) continue; } - mul_v2_fl(mloopuv_arr[i]->uv, 1.0f / (float)uv_duplicate_count[i]); + mul_v2_fl(mloopuv_arr[i], 1.0f / (float)uv_duplicate_count[i]); } MEM_freeN(uv_duplicate_count); /* Update duplicated uvs. */ uint ob_index = 0; for (int i = 0; i < mloopuv_count; i++) { - /* Make sure we know which object owns the MLoopUV at this index. + /* Make sure we know which object owns the mloopuv at this index. * Remember that in some cases the object will have no loop uv, * thus we need the while loop, and not simply an if check. */ while (ob_mloopuv_max_idx[ob_index] < i) { @@ -805,7 +805,7 @@ static int uv_remove_doubles_to_selected(bContext *C, wmOperator *op) continue; } - copy_v2_v2(mloopuv_arr[i]->uv, mloopuv_arr[duplicates[i]]->uv); + copy_v2_v2(mloopuv_arr[i], mloopuv_arr[duplicates[i]]); changed[ob_index] = true; } @@ -853,7 +853,7 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op) KDTree_2d *tree = BLI_kdtree_2d_new(uv_maxlen); - MLoopUV **mloopuv_arr = NULL; + float **mloopuv_arr = NULL; BLI_array_declare(mloopuv_arr); int mloopuv_count = 0; @@ -870,7 +870,7 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op) continue; } - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { @@ -878,9 +878,9 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op) } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (!uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - BLI_kdtree_2d_insert(tree, mloopuv_count, luv->uv); + if (!uvedit_uv_select_test(scene, l, offsets)) { + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + BLI_kdtree_2d_insert(tree, mloopuv_count, luv); BLI_array_append(mloopuv_arr, luv); mloopuv_count++; } @@ -903,7 +903,7 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op) continue; } - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { @@ -911,13 +911,13 @@ static int uv_remove_doubles_to_unselected(bContext *C, wmOperator *op) } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + if (uvedit_uv_select_test(scene, l, offsets)) { + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); KDTreeNearest_2d nearest; - const int i = BLI_kdtree_2d_find_nearest(tree, luv->uv, &nearest); + const int i = BLI_kdtree_2d_find_nearest(tree, luv, &nearest); if (i != -1 && nearest.dist < threshold) { - copy_v2_v2(luv->uv, mloopuv_arr[i]->uv); + copy_v2_v2(luv, mloopuv_arr[i]); changed = true; } } @@ -1105,10 +1105,10 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Object *obedit, const float curs BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; + float *luv; bool changed = false; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { @@ -1116,9 +1116,9 @@ static bool uv_snap_uvs_to_cursor(Scene *scene, Object *obedit, const float curs } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - copy_v2_v2(luv->uv, cursor); + if (uvedit_uv_select_test(scene, l, offsets)) { + luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + copy_v2_v2(luv, cursor); changed = true; } } @@ -1133,10 +1133,10 @@ static bool uv_snap_uvs_offset(Scene *scene, Object *obedit, const float offset[ BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; + float *luv; bool changed = false; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { @@ -1144,9 +1144,9 @@ static bool uv_snap_uvs_offset(Scene *scene, Object *obedit, const float offset[ } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - add_v2_v2(luv->uv, offset); + if (uvedit_uv_select_test(scene, l, offsets)) { + luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + add_v2_v2(luv, offset); changed = true; } } @@ -1162,9 +1162,9 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Object *obedit) BMFace *f; BMLoop *l, *lsub; BMIter iter, liter, lsubiter; - MLoopUV *luv; + float *luv; bool changed = false; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); /* index every vert that has a selected UV using it, but only once so as to * get unique indices and to count how much to malloc */ @@ -1172,7 +1172,7 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Object *obedit) if (uvedit_face_visible_test(scene, f)) { BM_elem_flag_enable(f, BM_ELEM_TAG); BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - BM_elem_flag_set(l, BM_ELEM_TAG, uvedit_uv_select_test(scene, l, cd_loop_uv_offset)); + BM_elem_flag_set(l, BM_ELEM_TAG, uvedit_uv_select_test(scene, l, offsets)); } } else { @@ -1191,15 +1191,15 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Object *obedit) if (BM_elem_flag_test(lsub->f, BM_ELEM_TAG) && /* Face: visible. */ !BM_elem_flag_test(lsub, BM_ELEM_TAG)) /* Loop: unselected. */ { - luv = BM_ELEM_CD_GET_VOID_P(lsub, cd_loop_uv_offset); - add_v2_v2(uv, luv->uv); + luv = BM_ELEM_CD_GET_FLOAT_P(lsub, offsets.uv); + add_v2_v2(uv, luv); uv_tot++; } } if (uv_tot) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - mul_v2_v2fl(luv->uv, uv, 1.0f / (float)uv_tot); + luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + mul_v2_v2fl(luv, uv, 1.0f / (float)uv_tot); changed = true; } } @@ -1216,12 +1216,12 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; + float *luv; int width = 0, height = 0; float w, h; bool changed = false; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); ED_space_image_get_size(sima, &width, &height); w = (float)width; @@ -1233,9 +1233,9 @@ static bool uv_snap_uvs_to_pixels(SpaceImage *sima, Scene *scene, Object *obedit } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - uv_snap_to_pixel(luv->uv, w, h); + if (uvedit_uv_select_test(scene, l, offsets)) { + luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + uv_snap_to_pixel(luv, w, h); } } @@ -1343,7 +1343,6 @@ static int uv_pin_exec(bContext *C, wmOperator *op) BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; const ToolSettings *ts = scene->toolsettings; const bool clear = RNA_boolean_get(op->ptr, "clear"); const bool synced_selection = (ts->uv_flag & UV_SYNC_SELECTION) != 0; @@ -1357,7 +1356,9 @@ static int uv_pin_exec(bContext *C, wmOperator *op) BMEditMesh *em = BKE_editmesh_from_object(obedit); bool changed = false; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_pin_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); if (synced_selection && (em->bm->totvertsel == 0)) { continue; @@ -1369,16 +1370,10 @@ static int uv_pin_exec(bContext *C, wmOperator *op) } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (uvedit_uv_select_test(scene, l, offsets)) { changed = true; - if (clear) { - luv->flag &= ~MLOOPUV_PINNED; - } - else { - luv->flag |= MLOOPUV_PINNED; - } + BM_ELEM_CD_SET_BOOL(l, offsets.pin, !clear); } } } @@ -1417,24 +1412,21 @@ static void UV_OT_pin(wmOperatorType *ot) /** \name Hide Operator * \{ */ -/* Check if vertex/edge is selected or unselected based on #bool_test arg. Needed for select swap - * support */ -#define UV_VERT_SEL_TEST(luv, bool_test) \ - ((((luv)->flag & MLOOPUV_VERTSEL) == MLOOPUV_VERTSEL) == bool_test) +/* check if we are selected or unselected based on 'bool_test' arg, + * needed for select swap support */ +#define UV_VERT_SEL_TEST(l, bool_test) (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) == bool_test) -#define UV_EDGE_SEL_TEST(luv, bool_test) \ - ((((luv)->flag & MLOOPUV_EDGESEL) == MLOOPUV_EDGESEL) == bool_test) +#define UV_EDGE_SEL_TEST(l, bool_test) (BM_ELEM_CD_GET_BOOL(l, offsets.select_edge) == bool_test) -/* Is the specified UV face, selected or unselected depending on bool_test. */ -static bool bm_face_is_all_uv_sel(BMFace *f, bool select_test, const int cd_loop_uv_offset) +/* is every UV vert selected or unselected depending on bool_test */ +static bool bm_face_is_all_uv_sel(BMFace *f, bool select_test, const BMUVOffsets offsets) { BMLoop *l_iter; BMLoop *l_first; l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - if (!UV_EDGE_SEL_TEST(luv, select_test)) { + if (!UV_EDGE_SEL_TEST(l_iter, select_test)) { return false; } } while ((l_iter = l_iter->next) != l_first); @@ -1460,9 +1452,11 @@ static int uv_hide_exec(bContext *C, wmOperator *op) BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); if (ts->uv_flag & UV_SYNC_SELECTION) { if (EDBM_mesh_hide(em, swap)) { @@ -1484,9 +1478,8 @@ static int uv_hide_exec(bContext *C, wmOperator *op) } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (UV_VERT_SEL_TEST(luv, !swap) || UV_EDGE_SEL_TEST(luv, !swap)) { + if (UV_VERT_SEL_TEST(l, !swap) || UV_EDGE_SEL_TEST(l, !swap)) { hide = 1; break; } @@ -1496,27 +1489,26 @@ static int uv_hide_exec(bContext *C, wmOperator *op) if (use_face_center) { if (em->selectmode == SCE_SELECT_FACE) { /* Deselect BMesh face if UV face is (de)selected depending on #swap. */ - if (bm_face_is_all_uv_sel(efa, !swap, cd_loop_uv_offset)) { + if (bm_face_is_all_uv_sel(efa, !swap, offsets)) { BM_face_select_set(em->bm, efa, false); } - uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset); + uvedit_face_select_disable(scene, em->bm, efa, offsets); } else { - if (bm_face_is_all_uv_sel(efa, true, cd_loop_uv_offset) == !swap) { + if (bm_face_is_all_uv_sel(efa, true, offsets) == !swap) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); /* For both cases rely on edge sel tests, since all vert sel tests are invalid in * case of sticky selections. */ - if (UV_EDGE_SEL_TEST(luv, !swap) && (em->selectmode == SCE_SELECT_EDGE)) { + if (UV_EDGE_SEL_TEST(l, !swap) && (em->selectmode == SCE_SELECT_EDGE)) { BM_edge_select_set(em->bm, l->e, false); } - else if (UV_EDGE_SEL_TEST(luv, !swap) && (em->selectmode == SCE_SELECT_VERTEX)) { + else if (UV_EDGE_SEL_TEST(l, !swap) && (em->selectmode == SCE_SELECT_VERTEX)) { BM_vert_select_set(em->bm, l->v, false); } } } if (!swap) { - uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset); + uvedit_face_select_disable(scene, em->bm, efa, offsets); } } } @@ -1524,12 +1516,11 @@ static int uv_hide_exec(bContext *C, wmOperator *op) /* Deselect BMesh face depending on the type of UV selectmode and the type of UV element * being considered. */ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (UV_EDGE_SEL_TEST(luv, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) { + if (UV_EDGE_SEL_TEST(l, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) { BM_face_select_set(em->bm, efa, false); break; } - if (UV_VERT_SEL_TEST(luv, !swap) && (ts->uv_selectmode == UV_SELECT_VERTEX)) { + if (UV_VERT_SEL_TEST(l, !swap) && (ts->uv_selectmode == UV_SELECT_VERTEX)) { BM_face_select_set(em->bm, efa, false); break; } @@ -1538,12 +1529,11 @@ static int uv_hide_exec(bContext *C, wmOperator *op) break; } } - uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset); + uvedit_face_select_disable(scene, em->bm, efa, offsets); } else { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (UV_EDGE_SEL_TEST(luv, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) { + if (UV_EDGE_SEL_TEST(l, !swap) && (ts->uv_selectmode == UV_SELECT_EDGE)) { if (em->selectmode == SCE_SELECT_EDGE) { BM_edge_select_set(em->bm, l->e, false); } @@ -1552,7 +1542,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op) BM_vert_select_set(em->bm, l->next->v, false); } } - else if (UV_VERT_SEL_TEST(luv, !swap) && (ts->uv_selectmode != UV_SELECT_EDGE)) { + else if (UV_VERT_SEL_TEST(l, !swap) && (ts->uv_selectmode != UV_SELECT_EDGE)) { if (em->selectmode == SCE_SELECT_EDGE) { BM_edge_select_set(em->bm, l->e, false); } @@ -1562,7 +1552,7 @@ static int uv_hide_exec(bContext *C, wmOperator *op) } } if (!swap) { - uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset); + uvedit_face_select_disable(scene, em->bm, efa, offsets); } } } @@ -1632,9 +1622,11 @@ static int uv_reveal_exec(bContext *C, wmOperator *op) BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); /* NOTE: Selecting faces is delayed so that it doesn't select verts/edges and confuse certain * UV selection checks. @@ -1664,8 +1656,8 @@ static int uv_reveal_exec(bContext *C, wmOperator *op) BM_elem_flag_disable(efa, BM_ELEM_TAG); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - SET_FLAG_FROM_TEST(luv->flag, select, (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL)); + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select); } /* BM_face_select_set(em->bm, efa, true); */ BM_elem_flag_enable(efa, BM_ELEM_TAG); @@ -1688,8 +1680,9 @@ static int uv_reveal_exec(bContext *C, wmOperator *op) if (!totsel) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - SET_FLAG_FROM_TEST(luv->flag, select, (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL)); + + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select); } } /* BM_face_select_set(em->bm, efa, true); */ @@ -1703,8 +1696,8 @@ static int uv_reveal_exec(bContext *C, wmOperator *op) BM_elem_flag_disable(efa, BM_ELEM_TAG); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - SET_FLAG_FROM_TEST(luv->flag, select, (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL)); + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select); } /* BM_face_select_set(em->bm, efa, true); */ BM_elem_flag_enable(efa, BM_ELEM_TAG); @@ -1716,8 +1709,8 @@ static int uv_reveal_exec(bContext *C, wmOperator *op) BM_elem_flag_disable(efa, BM_ELEM_TAG); if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - SET_FLAG_FROM_TEST(luv->flag, select, (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL)); + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select); } /* BM_face_select_set(em->bm, efa, true); */ BM_elem_flag_enable(efa, BM_ELEM_TAG); @@ -1853,7 +1846,7 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op) continue; } - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); bool changed = false; BMFace *f; @@ -1870,14 +1863,14 @@ static int uv_seams_from_islands_exec(bContext *C, wmOperator *op) if (l_iter == l_iter->radial_next) { continue; } - if (!uvedit_edge_select_test(scene, l_iter, cd_loop_uv_offset)) { + if (!uvedit_edge_select_test(scene, l_iter, offsets)) { continue; } bool mark = false; BMLoop *l_other = l_iter->radial_next; do { - if (!BM_loop_uv_share_edge_check(l_iter, l_other, cd_loop_uv_offset)) { + if (!BM_loop_uv_share_edge_check(l_iter, l_other, offsets.uv)) { mark = true; break; } @@ -1959,12 +1952,12 @@ static int uv_mark_seam_exec(bContext *C, wmOperator *op) continue; } - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (uvedit_face_visible_test(scene, efa)) { BM_ITER_ELEM (loop, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) { + if (uvedit_edge_select_test(scene, loop, offsets)) { BM_elem_flag_set(loop->e, BM_ELEM_SEAM, flag_set); changed = true; } diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c index 78436d17203..82d8c536fba 100644 --- a/source/blender/editors/uvedit/uvedit_path.c +++ b/source/blender/editors/uvedit/uvedit_path.c @@ -71,7 +71,7 @@ struct PathSelectParams { struct UserData_UV { Scene *scene; BMEditMesh *em; - int cd_loop_uv_offset; + BMUVOffsets offsets; }; static void path_select_properties(wmOperatorType *ot) @@ -121,15 +121,15 @@ static bool verttag_test_cb(BMLoop *l, void *user_data_v) /* All connected loops are selected or we return false. */ struct UserData_UV *user_data = user_data_v; const Scene *scene = user_data->scene; - const int cd_loop_uv_offset = user_data->cd_loop_uv_offset; - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + const int cd_loop_uv_offset = user_data->offsets.uv; + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); BMIter iter; BMLoop *l_iter; BM_ITER_ELEM (l_iter, &iter, l->v, BM_LOOPS_OF_VERT) { if (verttag_filter_cb(l_iter, user_data)) { - const MLoopUV *luv_iter = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - if (equals_v2v2(luv->uv, luv_iter->uv)) { - if (!uvedit_uv_select_test(scene, l_iter, cd_loop_uv_offset)) { + const float *luv_iter = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset); + if (equals_v2v2(luv, luv_iter)) { + if (!uvedit_uv_select_test(scene, l_iter, user_data->offsets)) { return false; } } @@ -142,15 +142,15 @@ static void verttag_set_cb(BMLoop *l, bool val, void *user_data_v) struct UserData_UV *user_data = user_data_v; const Scene *scene = user_data->scene; BMEditMesh *em = user_data->em; - const int cd_loop_uv_offset = user_data->cd_loop_uv_offset; - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + const uint cd_loop_uv_offset = user_data->offsets.uv; + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); BMIter iter; BMLoop *l_iter; BM_ITER_ELEM (l_iter, &iter, l->v, BM_LOOPS_OF_VERT) { if (verttag_filter_cb(l_iter, user_data)) { - MLoopUV *luv_iter = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - if (equals_v2v2(luv->uv, luv_iter->uv)) { - uvedit_uv_select_set(scene, em->bm, l_iter, val, false, cd_loop_uv_offset); + const float *luv_iter = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset); + if (equals_v2v2(luv, luv_iter)) { + uvedit_uv_select_set(scene, em->bm, l_iter, val, false, user_data->offsets); } } } @@ -162,7 +162,7 @@ static int mouse_mesh_uv_shortest_path_vert(Scene *scene, BMLoop *l_src, BMLoop *l_dst, const float aspect_y, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; @@ -171,14 +171,14 @@ static int mouse_mesh_uv_shortest_path_vert(Scene *scene, struct UserData_UV user_data = { .scene = scene, .em = em, - .cd_loop_uv_offset = cd_loop_uv_offset, + .offsets = offsets, }; const struct BMCalcPathUVParams params = { .use_topology_distance = op_params->use_topology_distance, .use_step_face = op_params->use_face_step, .aspect_y = aspect_y, - .cd_loop_uv_offset = cd_loop_uv_offset, + .cd_loop_uv_offset = offsets.uv, }; LinkNode *path = NULL; @@ -253,13 +253,12 @@ static bool edgetag_test_cb(BMLoop *l, void *user_data_v) /* All connected loops (UV) are selected or we return false. */ struct UserData_UV *user_data = user_data_v; const Scene *scene = user_data->scene; - const int cd_loop_uv_offset = user_data->cd_loop_uv_offset; BMIter iter; BMLoop *l_iter; BM_ITER_ELEM (l_iter, &iter, l->e, BM_LOOPS_OF_EDGE) { if (edgetag_filter_cb(l_iter, user_data)) { - if (BM_loop_uv_share_edge_check(l, l_iter, cd_loop_uv_offset)) { - if (!uvedit_edge_select_test(scene, l_iter, cd_loop_uv_offset)) { + if (BM_loop_uv_share_edge_check(l, l_iter, user_data->offsets.uv)) { + if (!uvedit_edge_select_test(scene, l_iter, user_data->offsets)) { return false; } } @@ -272,8 +271,7 @@ static void edgetag_set_cb(BMLoop *l, bool val, void *user_data_v) struct UserData_UV *user_data = user_data_v; const Scene *scene = user_data->scene; BMEditMesh *em = user_data->em; - const int cd_loop_uv_offset = user_data->cd_loop_uv_offset; - uvedit_edge_select_set_with_sticky(scene, em, l, val, false, cd_loop_uv_offset); + uvedit_edge_select_set_with_sticky(scene, em, l, val, false, user_data->offsets); } static int mouse_mesh_uv_shortest_path_edge(Scene *scene, @@ -282,7 +280,7 @@ static int mouse_mesh_uv_shortest_path_edge(Scene *scene, BMLoop *l_src, BMLoop *l_dst, const float aspect_y, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; @@ -291,14 +289,14 @@ static int mouse_mesh_uv_shortest_path_edge(Scene *scene, struct UserData_UV user_data = { .scene = scene, .em = em, - .cd_loop_uv_offset = cd_loop_uv_offset, + .offsets = offsets, }; const struct BMCalcPathUVParams params = { .use_topology_distance = op_params->use_topology_distance, .use_step_face = op_params->use_face_step, .aspect_y = aspect_y, - .cd_loop_uv_offset = cd_loop_uv_offset, + .cd_loop_uv_offset = offsets.uv, }; LinkNode *path = NULL; @@ -375,11 +373,10 @@ static bool facetag_test_cb(BMFace *f, void *user_data_v) /* All connected loops are selected or we return false. */ struct UserData_UV *user_data = user_data_v; const Scene *scene = user_data->scene; - const int cd_loop_uv_offset = user_data->cd_loop_uv_offset; BMIter iter; BMLoop *l_iter; BM_ITER_ELEM (l_iter, &iter, f, BM_LOOPS_OF_FACE) { - if (!uvedit_edge_select_test(scene, l_iter, cd_loop_uv_offset)) { + if (!uvedit_edge_select_test(scene, l_iter, user_data->offsets)) { return false; } } @@ -390,8 +387,7 @@ static void facetag_set_cb(BMFace *f, bool val, void *user_data_v) struct UserData_UV *user_data = user_data_v; const Scene *scene = user_data->scene; BMEditMesh *em = user_data->em; - const int cd_loop_uv_offset = user_data->cd_loop_uv_offset; - uvedit_face_select_set_with_sticky(scene, em, f, val, false, cd_loop_uv_offset); + uvedit_face_select_set_with_sticky(scene, em, f, val, false, user_data->offsets); } static int mouse_mesh_uv_shortest_path_face(Scene *scene, @@ -400,7 +396,7 @@ static int mouse_mesh_uv_shortest_path_face(Scene *scene, BMFace *f_src, BMFace *f_dst, const float aspect_y, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; @@ -409,14 +405,14 @@ static int mouse_mesh_uv_shortest_path_face(Scene *scene, struct UserData_UV user_data = { .scene = scene, .em = em, - .cd_loop_uv_offset = cd_loop_uv_offset, + .offsets = offsets, }; const struct BMCalcPathUVParams params = { .use_topology_distance = op_params->use_topology_distance, .use_step_face = op_params->use_face_step, .aspect_y = aspect_y, - .cd_loop_uv_offset = cd_loop_uv_offset, + .cd_loop_uv_offset = offsets.uv, }; LinkNode *path = NULL; @@ -492,7 +488,7 @@ static bool uv_shortest_path_pick_ex(Scene *scene, BMElem *ele_src, BMElem *ele_dst, const float aspect_y, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { const ToolSettings *ts = scene->toolsettings; const char uv_selectmode = ED_uvedit_select_mode_get(scene); @@ -503,33 +499,18 @@ static bool uv_shortest_path_pick_ex(Scene *scene, /* pass */ } else if (ele_src->head.htype == BM_FACE) { - flush = mouse_mesh_uv_shortest_path_face(scene, - obedit, - op_params, - (BMFace *)ele_src, - (BMFace *)ele_dst, - aspect_y, - cd_loop_uv_offset); + flush = mouse_mesh_uv_shortest_path_face( + scene, obedit, op_params, (BMFace *)ele_src, (BMFace *)ele_dst, aspect_y, offsets); ok = true; } else if (ele_src->head.htype == BM_LOOP) { if (uv_selectmode & UV_SELECT_EDGE) { - flush = mouse_mesh_uv_shortest_path_edge(scene, - obedit, - op_params, - (BMLoop *)ele_src, - (BMLoop *)ele_dst, - aspect_y, - cd_loop_uv_offset); + flush = mouse_mesh_uv_shortest_path_edge( + scene, obedit, op_params, (BMLoop *)ele_src, (BMLoop *)ele_dst, aspect_y, offsets); } else { - flush = mouse_mesh_uv_shortest_path_vert(scene, - obedit, - op_params, - (BMLoop *)ele_src, - (BMLoop *)ele_dst, - aspect_y, - cd_loop_uv_offset); + flush = mouse_mesh_uv_shortest_path_vert( + scene, obedit, op_params, (BMLoop *)ele_src, (BMLoop *)ele_dst, aspect_y, offsets); } ok = true; } @@ -586,7 +567,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); float aspect_y; { @@ -628,8 +609,8 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve else { l_src = ED_uvedit_active_edge_loop_get(bm); if (l_src != NULL) { - if (!uvedit_uv_select_test(scene, l_src, cd_loop_uv_offset) && - !uvedit_uv_select_test(scene, l_src->next, cd_loop_uv_offset)) { + if (!uvedit_uv_select_test(scene, l_src, offsets) && + !uvedit_uv_select_test(scene, l_src->next, offsets)) { l_src = NULL; } ele_src = (BMElem *)l_src; @@ -654,7 +635,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve else { l_src = ED_uvedit_active_vert_loop_get(bm); if (l_src != NULL) { - if (!uvedit_uv_select_test(scene, l_src, cd_loop_uv_offset)) { + if (!uvedit_uv_select_test(scene, l_src, offsets)) { l_src = NULL; } } @@ -668,7 +649,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve } uv_shortest_path_pick_ex( - scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset); + scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets); /* To support redo. */ int index; @@ -697,7 +678,7 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op) Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); float aspect_y; { @@ -743,7 +724,7 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op) op_params.track_active = true; if (!uv_shortest_path_pick_ex( - scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset)) { + scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets)) { return OPERATOR_CANCELLED; } @@ -804,7 +785,9 @@ static int uv_shortest_path_select_exec(bContext *C, wmOperator *op) Object *obedit = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); + BMElem *ele_src = NULL, *ele_dst = NULL; /* Find 2x elements. */ @@ -833,7 +816,7 @@ static int uv_shortest_path_select_exec(bContext *C, wmOperator *op) path_select_params_from_op(op, &op_params); uv_shortest_path_pick_ex( - scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, cd_loop_uv_offset); + scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets); found_valid_elements = true; } diff --git a/source/blender/editors/uvedit/uvedit_rip.c b/source/blender/editors/uvedit/uvedit_rip.c index 5497b9cd1e5..de83f9e63ef 100644 --- a/source/blender/editors/uvedit/uvedit_rip.c +++ b/source/blender/editors/uvedit/uvedit_rip.c @@ -186,13 +186,13 @@ static BMLoop *bm_vert_step_fan_loop_uv(BMLoop *l, BMEdge **e_step, const int cd static void bm_loop_uv_select_single_vert_validate(BMLoop *l_init, const int cd_loop_uv_offset) { - const MLoopUV *luv_init = BM_ELEM_CD_GET_VOID_P(l_init, cd_loop_uv_offset); + const float *luv_init = BM_ELEM_CD_GET_FLOAT_P(l_init, cd_loop_uv_offset); BMIter liter; BMLoop *l; bool is_single_vert = true; BM_ITER_ELEM (l, &liter, l_init->v, BM_LOOPS_OF_VERT) { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (equals_v2v2(luv_init->uv, luv->uv)) { + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + if (equals_v2v2(luv_init, luv)) { if (UL(l->prev)->is_select_edge || UL(l)->is_select_edge) { is_single_vert = false; break; @@ -202,8 +202,8 @@ static void bm_loop_uv_select_single_vert_validate(BMLoop *l_init, const int cd_ if (is_single_vert == false) { BM_ITER_ELEM (l, &liter, l_init->v, BM_LOOPS_OF_VERT) { if (UL(l)->is_select_vert_single) { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (equals_v2v2(luv_init->uv, luv->uv)) { + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + if (equals_v2v2(luv_init, luv)) { UL(l)->is_select_vert_single = false; } } @@ -227,12 +227,12 @@ static void bm_loop_calc_uv_angle_from_dir(BMLoop *l, { /* Calculate 3 directions, return the shortest angle. */ float dir_test[3][2]; - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset); - const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + const float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l->prev, cd_loop_uv_offset); + const float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l->next, cd_loop_uv_offset); - sub_v2_v2v2(dir_test[0], luv->uv, luv_prev->uv); - sub_v2_v2v2(dir_test[2], luv->uv, luv_next->uv); + sub_v2_v2v2(dir_test[0], luv, luv_prev); + sub_v2_v2v2(dir_test[2], luv, luv_next); dir_test[0][1] /= aspect_y; dir_test[2][1] /= aspect_y; @@ -302,8 +302,7 @@ static UVRipSingle *uv_rip_single_from_loop(BMLoop *l_init_orig, const int cd_loop_uv_offset) { UVRipSingle *rip = MEM_callocN(sizeof(*rip), __func__); - const float *co_center = - (((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_init_orig, cd_loop_uv_offset))->uv); + const float *co_center = BM_ELEM_CD_GET_FLOAT_P(l_init_orig, cd_loop_uv_offset); rip->loops = BLI_gset_ptr_new(__func__); /* Track the closest loop, start walking from this so in the event we have multiple @@ -328,8 +327,8 @@ static UVRipSingle *uv_rip_single_from_loop(BMLoop *l_init_orig, BMLoop *l; BM_ITER_ELEM (l, &liter, l_init_orig->v, BM_LOOPS_OF_VERT) { if (BM_elem_flag_test(l->f, BM_ELEM_TAG)) { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (equals_v2v2(co_center, luv->uv)) { + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + if (equals_v2v2(co_center, luv)) { uv_fan_count_all += 1; /* Clear at the same time. */ UL(l)->is_select_vert_single = true; @@ -462,19 +461,19 @@ static float uv_rip_pairs_calc_uv_angle(BMLoop *l_init, const int cd_loop_uv_offset) { BMIter liter; - const MLoopUV *luv_init = BM_ELEM_CD_GET_VOID_P(l_init, cd_loop_uv_offset); + const float *luv_init = BM_ELEM_CD_GET_FLOAT_P(l_init, cd_loop_uv_offset); float angle_of_side = 0.0f; BMLoop *l; BM_ITER_ELEM (l, &liter, l_init->v, BM_LOOPS_OF_VERT) { if (UL(l)->in_rip_pairs) { if (UL(l)->side == side) { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (equals_v2v2(luv_init->uv, luv->uv)) { - const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset); - const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + if (equals_v2v2(luv_init, luv)) { + const float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l->prev, cd_loop_uv_offset); + const float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l->next, cd_loop_uv_offset); float dir_prev[2], dir_next[2]; - sub_v2_v2v2(dir_prev, luv_prev->uv, luv->uv); - sub_v2_v2v2(dir_next, luv_next->uv, luv->uv); + sub_v2_v2v2(dir_prev, luv_prev, luv); + sub_v2_v2v2(dir_next, luv_next, luv); dir_prev[1] /= aspect_y; dir_next[1] /= aspect_y; const float luv_angle = angle_v2v2(dir_prev, dir_next); @@ -490,15 +489,15 @@ static float uv_rip_pairs_calc_uv_angle(BMLoop *l_init, static int uv_rip_pairs_loop_count_on_side(BMLoop *l_init, uint side, const int cd_loop_uv_offset) { - const MLoopUV *luv_init = BM_ELEM_CD_GET_VOID_P(l_init, cd_loop_uv_offset); + const float *luv_init = BM_ELEM_CD_GET_FLOAT_P(l_init, cd_loop_uv_offset); int count = 0; BMIter liter; BMLoop *l; BM_ITER_ELEM (l, &liter, l_init->v, BM_LOOPS_OF_VERT) { if (UL(l)->in_rip_pairs) { if (UL(l)->side == side) { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (equals_v2v2(luv_init->uv, luv->uv)) { + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + if (equals_v2v2(luv_init, luv)) { count += 1; } } @@ -694,18 +693,18 @@ static bool uv_rip_pairs_calc_center_and_direction(UVRipPairs *rip, GSET_ITER (gs_iter, rip->loops) { BMLoop *l = BLI_gsetIterator_getKey(&gs_iter); int side = UL(l)->side; - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - add_v2_v2(r_center, luv->uv); + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + add_v2_v2(r_center, luv); float dir[2]; if (!UL(l)->is_select_edge) { - const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - sub_v2_v2v2(dir, luv_next->uv, luv->uv); + const float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l->next, cd_loop_uv_offset); + sub_v2_v2v2(dir, luv_next, luv); add_v2_v2(r_dir_side[side], dir); } if (!UL(l->prev)->is_select_edge) { - const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset); - sub_v2_v2v2(dir, luv_prev->uv, luv->uv); + const float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l->prev, cd_loop_uv_offset); + sub_v2_v2v2(dir, luv_prev, luv); add_v2_v2(r_dir_side[side], dir); } side_total[side] += 1; @@ -735,7 +734,10 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const Mesh *me = (Mesh *)obedit->data; BMEditMesh *em = me->edit_mesh; BMesh *bm = em->bm; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); BMFace *efa; BMIter iter, liter; @@ -759,13 +761,11 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { bool is_all = true; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (luv->flag & MLOOPUV_VERTSEL) { - const MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset); - if (luv->flag & MLOOPUV_EDGESEL) { + if (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert)) { + if (BM_ELEM_CD_GET_BOOL(l, offsets.select_edge)) { UL(l)->is_select_edge = true; } - else if ((luv_prev->flag & MLOOPUV_EDGESEL) == 0) { + else if (!BM_ELEM_CD_GET_BOOL(l->prev, offsets.select_edge)) { /* #bm_loop_uv_select_single_vert_validate validates below. */ UL(l)->is_select_vert_single = true; is_all = false; @@ -793,7 +793,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (UL(l)->is_select_vert_single) { - bm_loop_uv_select_single_vert_validate(l, cd_loop_uv_offset); + bm_loop_uv_select_single_vert_validate(l, offsets.uv); } } } @@ -809,13 +809,12 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (!UL(l)->is_select_all) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (luv->flag & MLOOPUV_VERTSEL) { - luv->flag &= ~MLOOPUV_VERTSEL; + if (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert)) { + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); changed = true; } - if (luv->flag & MLOOPUV_EDGESEL) { - luv->flag &= ~MLOOPUV_EDGESEL; + if (BM_ELEM_CD_GET_BOOL(l, offsets.select_edge)) { + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); changed = true; } } @@ -830,12 +829,12 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (UL(l)->is_select_edge) { if (!UL(l)->in_rip_pairs) { - UVRipPairs *rip = uv_rip_pairs_from_loop(l, aspect_y, cd_loop_uv_offset); + UVRipPairs *rip = uv_rip_pairs_from_loop(l, aspect_y, offsets.uv); float center[2]; float dir_cursor[2]; float dir_side[2][2]; int side_from_cursor = -1; - if (uv_rip_pairs_calc_center_and_direction(rip, cd_loop_uv_offset, center, dir_side)) { + if (uv_rip_pairs_calc_center_and_direction(rip, offsets.uv, center, dir_side)) { for (int i = 0; i < 2; i++) { sub_v2_v2v2(dir_cursor, center, co); normalize_v2(dir_cursor); @@ -848,7 +847,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const BMLoop *l_iter = BLI_gsetIterator_getKey(&gs_iter); ULData *ul = UL(l_iter); if (ul->side == side_from_cursor) { - uvedit_uv_select_disable(scene, em->bm, l_iter, cd_loop_uv_offset); + uvedit_uv_select_disable(scene, bm, l_iter, offsets); changed = true; } /* Ensure we don't operate on these again. */ @@ -858,7 +857,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const } } else if (UL(l)->is_select_vert_single) { - UVRipSingle *rip = uv_rip_single_from_loop(l, co, aspect_y, cd_loop_uv_offset); + UVRipSingle *rip = uv_rip_single_from_loop(l, co, aspect_y, offsets.uv); /* We only ever use one side. */ const int side_from_cursor = 0; GSetIterator gs_iter; @@ -866,7 +865,7 @@ static bool uv_rip_object(Scene *scene, Object *obedit, const float co[2], const BMLoop *l_iter = BLI_gsetIterator_getKey(&gs_iter); ULData *ul = UL(l_iter); if (ul->side == side_from_cursor) { - uvedit_uv_select_disable(scene, em->bm, l_iter, cd_loop_uv_offset); + uvedit_uv_select_disable(scene, bm, l_iter, offsets); changed = true; } /* Ensure we don't operate on these again. */ diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index 48ffbcfa1c7..a3fec5acdc4 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -198,7 +198,7 @@ void ED_uvedit_select_sync_flush(const ToolSettings *ts, BMEditMesh *em, const b static void uvedit_vertex_select_tagged(BMEditMesh *em, Scene *scene, bool select, - int cd_loop_uv_offset) + const BMUVOffsets offsets) { BMFace *efa; BMLoop *l; @@ -207,7 +207,7 @@ static void uvedit_vertex_select_tagged(BMEditMesh *em, BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) { - uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset); + uvedit_uv_select_set(scene, em->bm, l, select, false, offsets); } } } @@ -225,34 +225,34 @@ bool uvedit_face_visible_test(const Scene *scene, BMFace *efa) return uvedit_face_visible_test_ex(scene->toolsettings, efa); } -bool uvedit_face_select_test_ex(const ToolSettings *ts, BMFace *efa, const int cd_loop_uv_offset) +bool uvedit_face_select_test_ex(const ToolSettings *ts, BMFace *efa, const BMUVOffsets offsets) { + BLI_assert(offsets.select_vert >= 0); + BLI_assert(offsets.select_edge >= 0); if (ts->uv_flag & UV_SYNC_SELECTION) { return BM_elem_flag_test(efa, BM_ELEM_SELECT); } BMLoop *l; - MLoopUV *luv; BMIter liter; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); if (ts->uv_selectmode & UV_SELECT_VERTEX) { - if ((luv->flag & MLOOPUV_VERTSEL) == 0) { + if (!BM_ELEM_CD_GET_BOOL(l, offsets.select_vert)) { return false; } } else { - if ((luv->flag & MLOOPUV_EDGESEL) == 0) { + if (!BM_ELEM_CD_GET_BOOL(l, offsets.select_edge)) { return false; } } } return true; } -bool uvedit_face_select_test(const Scene *scene, BMFace *efa, const int cd_loop_uv_offset) +bool uvedit_face_select_test(const Scene *scene, BMFace *efa, const BMUVOffsets offsets) { - return uvedit_face_select_test_ex(scene->toolsettings, efa, cd_loop_uv_offset); + return uvedit_face_select_test_ex(scene->toolsettings, efa, offsets); } void uvedit_face_select_set_with_sticky(const Scene *scene, @@ -260,12 +260,12 @@ void uvedit_face_select_set_with_sticky(const Scene *scene, BMFace *efa, const bool select, const bool do_history, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { const ToolSettings *ts = scene->toolsettings; const char sticky = ts->uv_sticky; if (ts->uv_flag & UV_SYNC_SELECTION) { - uvedit_face_select_set(scene, em->bm, efa, select, do_history, cd_loop_uv_offset); + uvedit_face_select_set(scene, em->bm, efa, select, do_history, offsets); return; } if (!uvedit_face_visible_test(scene, efa)) { @@ -275,12 +275,12 @@ void uvedit_face_select_set_with_sticky(const Scene *scene, * (not part of any face selections). This now uses the sticky location mode logic instead. */ switch (sticky) { case SI_STICKY_DISABLE: { - uvedit_face_select_set(scene, em->bm, efa, select, do_history, cd_loop_uv_offset); + uvedit_face_select_set(scene, em->bm, efa, select, do_history, offsets); break; } default: { /* SI_STICKY_LOC and SI_STICKY_VERTEX modes. */ - uvedit_face_select_shared_vert(scene, em, efa, select, do_history, cd_loop_uv_offset); + uvedit_face_select_shared_vert(scene, em, efa, select, do_history, offsets); } } } @@ -290,23 +290,20 @@ void uvedit_face_select_shared_vert(const Scene *scene, BMFace *efa, const bool select, const bool do_history, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { BMLoop *l; BMIter liter; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); if (select) { - luv->flag |= MLOOPUV_EDGESEL; - uvedit_uv_select_shared_vert( - scene, em, l, select, SI_STICKY_LOC, do_history, cd_loop_uv_offset); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true); + uvedit_uv_select_shared_vert(scene, em, l, select, SI_STICKY_LOC, do_history, offsets); } else { - luv->flag &= ~MLOOPUV_EDGESEL; - if (!uvedit_vert_is_face_select_any_other(scene, l, cd_loop_uv_offset)) { - uvedit_uv_select_shared_vert( - scene, em, l, select, SI_STICKY_LOC, do_history, cd_loop_uv_offset); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); + if (!uvedit_vert_is_face_select_any_other(scene, l, offsets)) { + uvedit_uv_select_shared_vert(scene, em, l, select, SI_STICKY_LOC, do_history, offsets); } } } @@ -317,20 +314,21 @@ void uvedit_face_select_set(const Scene *scene, BMFace *efa, const bool select, const bool do_history, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { if (select) { - uvedit_face_select_enable(scene, bm, efa, do_history, cd_loop_uv_offset); + uvedit_face_select_enable(scene, bm, efa, do_history, offsets); } else { - uvedit_face_select_disable(scene, bm, efa, cd_loop_uv_offset); + uvedit_face_select_disable(scene, bm, efa, offsets); } } void uvedit_face_select_enable( - const Scene *scene, BMesh *bm, BMFace *efa, const bool do_history, const int cd_loop_uv_offset) + const Scene *scene, BMesh *bm, BMFace *efa, const bool do_history, const BMUVOffsets offsets) { - BLI_assert(cd_loop_uv_offset >= 0); + BLI_assert(offsets.select_vert >= 0); + BLI_assert(offsets.select_edge >= 0); const ToolSettings *ts = scene->toolsettings; if (ts->uv_flag & UV_SYNC_SELECTION) { @@ -341,12 +339,11 @@ void uvedit_face_select_enable( } else { BMLoop *l; - MLoopUV *luv; BMIter liter; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag |= (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL); + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true); } } } @@ -354,9 +351,10 @@ void uvedit_face_select_enable( void uvedit_face_select_disable(const Scene *scene, BMesh *bm, BMFace *efa, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { - BLI_assert(cd_loop_uv_offset >= 0); + BLI_assert(offsets.select_vert >= 0); + BLI_assert(offsets.select_edge >= 0); const ToolSettings *ts = scene->toolsettings; if (ts->uv_flag & UV_SYNC_SELECTION) { @@ -364,18 +362,19 @@ void uvedit_face_select_disable(const Scene *scene, } else { BMLoop *l; - MLoopUV *luv; BMIter liter; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag &= ~(MLOOPUV_VERTSEL | MLOOPUV_EDGESEL); + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); } } } -bool uvedit_edge_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_loop_uv_offset) +bool uvedit_edge_select_test_ex(const ToolSettings *ts, BMLoop *l, const BMUVOffsets offsets) { + BLI_assert(offsets.select_vert >= 0); + BLI_assert(offsets.select_edge >= 0); if (ts->uv_flag & UV_SYNC_SELECTION) { if (ts->selectmode & SCE_SELECT_FACE) { return BM_elem_flag_test(l->f, BM_ELEM_SELECT); @@ -387,18 +386,16 @@ bool uvedit_edge_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_ BM_elem_flag_test(l->next->v, BM_ELEM_SELECT); } - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (ts->uv_selectmode & UV_SELECT_VERTEX) { - MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - return (luv->flag & MLOOPUV_VERTSEL) && (luv_next->flag & MLOOPUV_VERTSEL); + return BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) && + BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert); } - return (luv->flag & MLOOPUV_EDGESEL); + return BM_ELEM_CD_GET_BOOL(l, offsets.select_edge); } -bool uvedit_edge_select_test(const Scene *scene, BMLoop *l, const int cd_loop_uv_offset) +bool uvedit_edge_select_test(const Scene *scene, BMLoop *l, const BMUVOffsets offsets) { - return uvedit_edge_select_test_ex(scene->toolsettings, l, cd_loop_uv_offset); + return uvedit_edge_select_test_ex(scene->toolsettings, l, offsets); } void uvedit_edge_select_set_with_sticky(const Scene *scene, @@ -406,11 +403,11 @@ void uvedit_edge_select_set_with_sticky(const Scene *scene, BMLoop *l, const bool select, const bool do_history, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { const ToolSettings *ts = scene->toolsettings; if (ts->uv_flag & UV_SYNC_SELECTION) { - uvedit_edge_select_set(scene, em->bm, l, select, do_history, cd_loop_uv_offset); + uvedit_edge_select_set(scene, em->bm, l, select, do_history, offsets); return; } @@ -418,19 +415,17 @@ void uvedit_edge_select_set_with_sticky(const Scene *scene, switch (sticky) { case SI_STICKY_DISABLE: { if (uvedit_face_visible_test(scene, l->f)) { - uvedit_edge_select_set(scene, em->bm, l, select, do_history, cd_loop_uv_offset); + uvedit_edge_select_set(scene, em->bm, l, select, do_history, offsets); } break; } case SI_STICKY_VERTEX: { - uvedit_edge_select_shared_vert( - scene, em, l, select, SI_STICKY_VERTEX, do_history, cd_loop_uv_offset); + uvedit_edge_select_shared_vert(scene, em, l, select, SI_STICKY_VERTEX, do_history, offsets); break; } default: { /* SI_STICKY_LOC (Fallback) */ - uvedit_edge_select_shared_vert( - scene, em, l, select, SI_STICKY_LOC, do_history, cd_loop_uv_offset); + uvedit_edge_select_shared_vert(scene, em, l, select, SI_STICKY_LOC, do_history, offsets); break; } } @@ -449,31 +444,28 @@ void uvedit_edge_select_shared_vert(const Scene *scene, const bool select, const int sticky_flag, const bool do_history, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { BLI_assert(ELEM(sticky_flag, SI_STICKY_LOC, SI_STICKY_VERTEX)); /* Set edge flags. Rely on this for face visibility checks */ - uvedit_edge_select_set_noflush(scene, l, select, sticky_flag, cd_loop_uv_offset); + uvedit_edge_select_set_noflush(scene, l, select, sticky_flag, offsets); /* Vert selections. */ BMLoop *l_iter = l; do { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - if (select && (luv->flag & MLOOPUV_EDGESEL)) { + if (select && BM_ELEM_CD_GET_BOOL(l_iter, offsets.select_edge)) { + uvedit_uv_select_shared_vert(scene, em, l_iter, true, SI_STICKY_LOC, do_history, offsets); uvedit_uv_select_shared_vert( - scene, em, l_iter, true, SI_STICKY_LOC, do_history, cd_loop_uv_offset); - uvedit_uv_select_shared_vert( - scene, em, l_iter->next, true, SI_STICKY_LOC, do_history, cd_loop_uv_offset); + scene, em, l_iter->next, true, SI_STICKY_LOC, do_history, offsets); } - else if (!select && !(luv->flag & MLOOPUV_EDGESEL)) { - if (!uvedit_vert_is_edge_select_any_other(scene, l, cd_loop_uv_offset)) { - uvedit_uv_select_shared_vert( - scene, em, l_iter, false, SI_STICKY_LOC, do_history, cd_loop_uv_offset); + else if (!select && !BM_ELEM_CD_GET_BOOL(l_iter, offsets.select_edge)) { + if (!uvedit_vert_is_edge_select_any_other(scene, l, offsets)) { + uvedit_uv_select_shared_vert(scene, em, l_iter, false, SI_STICKY_LOC, do_history, offsets); } - if (!uvedit_vert_is_edge_select_any_other(scene, l->next, cd_loop_uv_offset)) { + if (!uvedit_vert_is_edge_select_any_other(scene, l->next, offsets)) { uvedit_uv_select_shared_vert( - scene, em, l_iter->next, false, SI_STICKY_LOC, do_history, cd_loop_uv_offset); + scene, em, l_iter->next, false, SI_STICKY_LOC, do_history, offsets); } } } while (((l_iter = l_iter->radial_next) != l) && (sticky_flag != SI_STICKY_LOC)); @@ -484,16 +476,16 @@ void uvedit_edge_select_set_noflush(const Scene *scene, BMLoop *l, const bool select, const int sticky_flag, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { - MLoopUV *luv; + BLI_assert(offsets.uv >= 0); + BLI_assert(offsets.select_edge >= 0); BMLoop *l_iter = l; do { if (uvedit_face_visible_test(scene, l_iter->f)) { if ((sticky_flag == SI_STICKY_VERTEX) || - BM_loop_uv_share_edge_check(l, l_iter, cd_loop_uv_offset)) { - luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - SET_FLAG_FROM_TEST(luv->flag, select, MLOOPUV_EDGESEL); + BM_loop_uv_share_edge_check(l, l_iter, offsets.uv)) { + BM_ELEM_CD_SET_BOOL(l_iter, offsets.select_edge, select); } } } while (((l_iter = l_iter->radial_next) != l) && (sticky_flag != SI_STICKY_DISABLE)); @@ -504,22 +496,23 @@ void uvedit_edge_select_set(const Scene *scene, BMLoop *l, const bool select, const bool do_history, - const int cd_loop_uv_offset) - + const BMUVOffsets offsets) { if (select) { - uvedit_edge_select_enable(scene, bm, l, do_history, cd_loop_uv_offset); + uvedit_edge_select_enable(scene, bm, l, do_history, offsets); } else { - uvedit_edge_select_disable(scene, bm, l, cd_loop_uv_offset); + uvedit_edge_select_disable(scene, bm, l, offsets); } } void uvedit_edge_select_enable( - const Scene *scene, BMesh *bm, BMLoop *l, const bool do_history, const int cd_loop_uv_offset) + const Scene *scene, BMesh *bm, BMLoop *l, const bool do_history, const BMUVOffsets offsets) { const ToolSettings *ts = scene->toolsettings; + BLI_assert(offsets.select_vert >= 0); + BLI_assert(offsets.select_edge >= 0); if (ts->uv_flag & UV_SYNC_SELECTION) { if (ts->selectmode & SCE_SELECT_FACE) { @@ -538,22 +531,20 @@ void uvedit_edge_select_enable( } } else { - MLoopUV *luv, *luv_next; - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - - luv->flag |= (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL); - luv_next->flag |= MLOOPUV_VERTSEL; + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true); + BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, true); } } void uvedit_edge_select_disable(const Scene *scene, BMesh *bm, BMLoop *l, - const int cd_loop_uv_offset) - + const BMUVOffsets offsets) { const ToolSettings *ts = scene->toolsettings; + BLI_assert(offsets.select_vert >= 0); + BLI_assert(offsets.select_edge >= 0); if (ts->uv_flag & UV_SYNC_SELECTION) { if (ts->selectmode & SCE_SELECT_FACE) { @@ -568,30 +559,26 @@ void uvedit_edge_select_disable(const Scene *scene, } } else { - MLoopUV *luv, *luv_next; - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - - luv->flag &= ~MLOOPUV_EDGESEL; + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); if ((ts->uv_selectmode & UV_SELECT_VERTEX) == 0) { /* Deselect UV vertex if not part of another edge selection */ - MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset); - if (!(luv_next->flag & MLOOPUV_EDGESEL)) { - luv_next->flag &= ~MLOOPUV_VERTSEL; + if (!BM_ELEM_CD_GET_BOOL(l->next, offsets.select_edge)) { + BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, false); } - if (!(luv_prev->flag & MLOOPUV_EDGESEL)) { - luv->flag &= ~MLOOPUV_VERTSEL; + if (!BM_ELEM_CD_GET_BOOL(l->prev, offsets.select_edge)) { + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); } } else { - luv_next->flag &= ~MLOOPUV_VERTSEL; - luv->flag &= ~MLOOPUV_VERTSEL; + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); + BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, false); } } } -bool uvedit_uv_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_loop_uv_offset) +bool uvedit_uv_select_test_ex(const ToolSettings *ts, BMLoop *l, const BMUVOffsets offsets) { + BLI_assert(offsets.select_vert >= 0); if (ts->uv_flag & UV_SYNC_SELECTION) { if (ts->selectmode & SCE_SELECT_FACE) { return BM_elem_flag_test_bool(l->f, BM_ELEM_SELECT); @@ -602,8 +589,6 @@ bool uvedit_uv_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_lo return BM_elem_flag_test_bool(l->v, BM_ELEM_SELECT); } - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (ts->selectmode & SCE_SELECT_FACE) { /* Are you looking for `uvedit_face_select_test(...)` instead? */ } @@ -612,12 +597,12 @@ bool uvedit_uv_select_test_ex(const ToolSettings *ts, BMLoop *l, const int cd_lo /* Are you looking for `uvedit_edge_select_test(...)` instead? */ } - return (luv->flag & MLOOPUV_VERTSEL) != 0; + return BM_ELEM_CD_GET_BOOL(l, offsets.select_vert); } -bool uvedit_uv_select_test(const Scene *scene, BMLoop *l, const int cd_loop_uv_offset) +bool uvedit_uv_select_test(const Scene *scene, BMLoop *l, const BMUVOffsets offsets) { - return uvedit_uv_select_test_ex(scene->toolsettings, l, cd_loop_uv_offset); + return uvedit_uv_select_test_ex(scene->toolsettings, l, offsets); } void uvedit_uv_select_set_with_sticky(const Scene *scene, @@ -625,11 +610,11 @@ void uvedit_uv_select_set_with_sticky(const Scene *scene, BMLoop *l, const bool select, const bool do_history, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { const ToolSettings *ts = scene->toolsettings; if (ts->uv_flag & UV_SYNC_SELECTION) { - uvedit_uv_select_set(scene, em->bm, l, select, do_history, cd_loop_uv_offset); + uvedit_uv_select_set(scene, em->bm, l, select, do_history, offsets); return; } @@ -637,19 +622,17 @@ void uvedit_uv_select_set_with_sticky(const Scene *scene, switch (sticky) { case SI_STICKY_DISABLE: { if (uvedit_face_visible_test(scene, l->f)) { - uvedit_uv_select_set(scene, em->bm, l, select, do_history, cd_loop_uv_offset); + uvedit_uv_select_set(scene, em->bm, l, select, do_history, offsets); } break; } case SI_STICKY_VERTEX: { - uvedit_uv_select_shared_vert( - scene, em, l, select, SI_STICKY_VERTEX, do_history, cd_loop_uv_offset); + uvedit_uv_select_shared_vert(scene, em, l, select, SI_STICKY_VERTEX, do_history, offsets); break; } default: { /* SI_STICKY_LOC. */ - uvedit_uv_select_shared_vert( - scene, em, l, select, SI_STICKY_LOC, do_history, cd_loop_uv_offset); + uvedit_uv_select_shared_vert(scene, em, l, select, SI_STICKY_LOC, do_history, offsets); break; } } @@ -668,9 +651,10 @@ void uvedit_uv_select_shared_vert(const Scene *scene, const bool select, const int sticky_flag, const bool do_history, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { BLI_assert(ELEM(sticky_flag, SI_STICKY_LOC, SI_STICKY_VERTEX)); + BLI_assert(offsets.uv >= 0); BMEdge *e_first, *e_iter; e_first = e_iter = l->e; @@ -686,13 +670,12 @@ void uvedit_uv_select_shared_vert(const Scene *scene, if (sticky_flag == SI_STICKY_VERTEX) { do_select = true; } - else if (BM_loop_uv_share_vert_check(l, l_radial_iter, cd_loop_uv_offset)) { + else if (BM_loop_uv_share_vert_check(l, l_radial_iter, offsets.uv)) { do_select = true; } if (do_select) { - uvedit_uv_select_set( - scene, em->bm, l_radial_iter, select, do_history, cd_loop_uv_offset); + uvedit_uv_select_set(scene, em->bm, l_radial_iter, select, do_history, offsets); } } } @@ -705,20 +688,21 @@ void uvedit_uv_select_set(const Scene *scene, BMLoop *l, const bool select, const bool do_history, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { if (select) { - uvedit_uv_select_enable(scene, bm, l, do_history, cd_loop_uv_offset); + uvedit_uv_select_enable(scene, bm, l, do_history, offsets); } else { - uvedit_uv_select_disable(scene, bm, l, cd_loop_uv_offset); + uvedit_uv_select_disable(scene, bm, l, offsets); } } void uvedit_uv_select_enable( - const Scene *scene, BMesh *bm, BMLoop *l, const bool do_history, const int cd_loop_uv_offset) + const Scene *scene, BMesh *bm, BMLoop *l, const bool do_history, const BMUVOffsets offsets) { const ToolSettings *ts = scene->toolsettings; + BLI_assert(offsets.select_vert >= 0); if (ts->selectmode & SCE_SELECT_EDGE) { /* Are you looking for `uvedit_edge_select_set(...)` instead? */ @@ -737,17 +721,14 @@ void uvedit_uv_select_enable( } } else { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag |= MLOOPUV_VERTSEL; + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); } } -void uvedit_uv_select_disable(const Scene *scene, - BMesh *bm, - BMLoop *l, - const int cd_loop_uv_offset) +void uvedit_uv_select_disable(const Scene *scene, BMesh *bm, BMLoop *l, const BMUVOffsets offsets) { const ToolSettings *ts = scene->toolsettings; + BLI_assert(offsets.select_vert >= 0); if (ts->uv_flag & UV_SYNC_SELECTION) { if (ts->selectmode & SCE_SELECT_FACE) { @@ -758,21 +739,21 @@ void uvedit_uv_select_disable(const Scene *scene, } } else { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag &= ~MLOOPUV_VERTSEL; + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); } } static BMLoop *uvedit_loop_find_other_radial_loop_with_visible_face(const Scene *scene, BMLoop *l_src, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { + BLI_assert(offsets.uv >= 0); BMLoop *l_other = NULL; BMLoop *l_iter = l_src->radial_next; if (l_iter != l_src) { do { if (uvedit_face_visible_test(scene, l_iter->f) && - BM_loop_uv_share_edge_check(l_src, l_iter, cd_loop_uv_offset)) { + BM_loop_uv_share_edge_check(l_src, l_iter, offsets.uv)) { /* Check UV's are contiguous. */ if (l_other == NULL) { l_other = l_iter; @@ -791,10 +772,9 @@ static BMLoop *uvedit_loop_find_other_radial_loop_with_visible_face(const Scene static BMLoop *uvedit_loop_find_other_boundary_loop_with_visible_face(const Scene *scene, BMLoop *l_edge, BMVert *v_pivot, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { - BLI_assert(uvedit_loop_find_other_radial_loop_with_visible_face( - scene, l_edge, cd_loop_uv_offset) == NULL); + BLI_assert(uvedit_loop_find_other_radial_loop_with_visible_face(scene, l_edge, offsets) == NULL); BMLoop *l_step = l_edge; l_step = (l_step->v == v_pivot) ? l_step->prev : l_step->next; @@ -802,16 +782,15 @@ static BMLoop *uvedit_loop_find_other_boundary_loop_with_visible_face(const Scen do { BLI_assert(BM_vert_in_edge(l_step->e, v_pivot)); l_step_last = l_step; - l_step = uvedit_loop_find_other_radial_loop_with_visible_face( - scene, l_step, cd_loop_uv_offset); + l_step = uvedit_loop_find_other_radial_loop_with_visible_face(scene, l_step, offsets); if (l_step) { l_step = (l_step->v == v_pivot) ? l_step->prev : l_step->next; } } while (l_step != NULL); if (l_step_last != NULL) { - BLI_assert(uvedit_loop_find_other_radial_loop_with_visible_face( - scene, l_step_last, cd_loop_uv_offset) == NULL); + BLI_assert(uvedit_loop_find_other_radial_loop_with_visible_face(scene, l_step_last, offsets) == + NULL); } return l_step_last; @@ -831,11 +810,12 @@ bool uv_find_nearest_edge( BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv, *luv_next; + float *luv, *luv_next; int i; bool found = false; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); + BLI_assert(offsets.uv >= 0); BM_mesh_elem_index_ensure(em->bm, BM_VERT); @@ -844,11 +824,11 @@ bool uv_find_nearest_edge( continue; } BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); + luv = BM_ELEM_CD_GET_VOID_P(l, offsets.uv); + luv_next = BM_ELEM_CD_GET_VOID_P(l->next, offsets.uv); float delta[2]; - closest_to_line_segment_v2(delta, co, luv->uv, luv_next->uv); + closest_to_line_segment_v2(delta, co, luv, luv_next); sub_v2_v2(delta, co); mul_v2_v2(delta, hit->scale); @@ -857,7 +837,7 @@ bool uv_find_nearest_edge( /* Ensures that successive selection attempts will select other edges sharing the same * UV coordinates as the previous selection. */ - if ((penalty != 0.0f) && uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) { + if ((penalty != 0.0f) && uvedit_edge_select_test(scene, l, offsets)) { dist_test_sq = square_f(sqrtf(dist_test_sq) + penalty); } if (dist_test_sq < hit->dist_sq) { @@ -898,7 +878,7 @@ bool uv_find_nearest_face_ex( BMEditMesh *em = BKE_editmesh_from_object(obedit); bool found = false; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); BMIter iter; BMFace *efa; @@ -964,9 +944,9 @@ bool uv_find_nearest_face_multi( static bool uv_nearest_between(const BMLoop *l, const float co[2], const int cd_loop_uv_offset) { - const float *uv_prev = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset))->uv; - const float *uv_curr = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset))->uv; - const float *uv_next = ((MLoopUV *)BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset))->uv; + const float *uv_prev = BM_ELEM_CD_GET_FLOAT_P(l->prev, cd_loop_uv_offset); + const float *uv_curr = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + const float *uv_next = BM_ELEM_CD_GET_FLOAT_P(l->next, cd_loop_uv_offset); return ((line_point_side_v2(uv_prev, uv_curr, co) > 0.0f) && (line_point_side_v2(uv_next, uv_curr, co) <= 0.0f)); @@ -984,7 +964,8 @@ bool uv_find_nearest_vert( BM_mesh_elem_index_ensure(em->bm, BM_VERT); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); + BLI_assert(offsets.uv >= 0); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { @@ -995,24 +976,24 @@ bool uv_find_nearest_vert( BMLoop *l; int i; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); float delta[2]; - sub_v2_v2v2(delta, co, luv->uv); + sub_v2_v2v2(delta, co, luv); mul_v2_v2(delta, hit->scale); float dist_test_sq = len_squared_v2(delta); /* Ensures that successive selection attempts will select other vertices sharing the same * UV coordinates */ - if ((penalty_dist != 0.0f) && uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if ((penalty_dist != 0.0f) && uvedit_uv_select_test(scene, l, offsets)) { dist_test_sq = square_f(sqrtf(dist_test_sq) + penalty_dist); } if (dist_test_sq <= hit->dist_sq) { if (dist_test_sq == hit->dist_sq) { - if (!uv_nearest_between(l, co, cd_loop_uv_offset)) { + if (!uv_nearest_between(l, co, offsets.uv)) { continue; } } @@ -1060,7 +1041,8 @@ static bool uvedit_nearest_uv(const Scene *scene, BMFace *efa; const float *uv_best = NULL; float dist_best = *dist_sq; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); + BLI_assert(offsets.uv >= 0); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { continue; @@ -1068,11 +1050,11 @@ static bool uvedit_nearest_uv(const Scene *scene, BMLoop *l_iter, *l_first; l_iter = l_first = BM_FACE_FIRST_LOOP(efa); do { - if (ignore_selected && uvedit_uv_select_test(scene, l_iter, cd_loop_uv_offset)) { + if (ignore_selected && uvedit_uv_select_test(scene, l_iter, offsets)) { continue; } - const float *uv = ((const MLoopUV *)BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset))->uv; + const float *uv = BM_ELEM_CD_GET_FLOAT_P(l_iter, offsets.uv); float co_tmp[2]; mul_v2_v2v2(co_tmp, scale, uv); const float dist_test = len_squared_v2v2(co, co_tmp); @@ -1134,7 +1116,7 @@ BMLoop *uv_find_nearest_loop_from_vert(struct Scene *scene, const float co[2]) { BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); BMIter liter; BMLoop *l; @@ -1146,8 +1128,8 @@ BMLoop *uv_find_nearest_loop_from_vert(struct Scene *scene, continue; } - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - const float dist_test_sq = len_squared_v2v2(co, luv->uv); + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + const float dist_test_sq = len_squared_v2v2(co, luv); if (dist_test_sq < dist_best_sq) { dist_best_sq = dist_test_sq; l_found = l; @@ -1162,8 +1144,7 @@ BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene, const float co[2]) { BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - BLI_assert(cd_loop_uv_offset >= 0); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); BMIter eiter; BMLoop *l; @@ -1174,9 +1155,9 @@ BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene, if (!uvedit_face_visible_test(scene, l->f)) { continue; } - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - const float dist_test_sq = dist_squared_to_line_segment_v2(co, luv->uv, luv_next->uv); + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + const float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l->next, cd_loop_uv_offset); + const float dist_test_sq = dist_squared_to_line_segment_v2(co, luv, luv_next); if (dist_test_sq < dist_best_sq) { dist_best_sq = dist_test_sq; l_found = l; @@ -1191,10 +1172,9 @@ BMLoop *uv_find_nearest_loop_from_edge(struct Scene *scene, /** \name Helper functions for UV selection. * \{ */ -bool uvedit_vert_is_edge_select_any_other(const Scene *scene, - BMLoop *l, - const int cd_loop_uv_offset) +bool uvedit_vert_is_edge_select_any_other(const Scene *scene, BMLoop *l, const BMUVOffsets offsets) { + BLI_assert(offsets.uv >= 0); BMEdge *e_iter = l->e; do { BMLoop *l_radial_iter = e_iter->l, *l_other; @@ -1203,8 +1183,8 @@ bool uvedit_vert_is_edge_select_any_other(const Scene *scene, /* Use #l_other to check if the uvs are connected (share the same uv coordinates) * and #l_radial_iter for the actual edge selection test. */ l_other = (l_radial_iter->v != l->v) ? l_radial_iter->next : l_radial_iter; - if (BM_loop_uv_share_vert_check(l, l_other, cd_loop_uv_offset) && - uvedit_edge_select_test(scene, l_radial_iter, cd_loop_uv_offset)) { + if (BM_loop_uv_share_vert_check(l, l_other, offsets.uv) && + uvedit_edge_select_test(scene, l_radial_iter, offsets)) { return true; } } @@ -1214,18 +1194,17 @@ bool uvedit_vert_is_edge_select_any_other(const Scene *scene, return false; } -bool uvedit_vert_is_face_select_any_other(const Scene *scene, - BMLoop *l, - const int cd_loop_uv_offset) +bool uvedit_vert_is_face_select_any_other(const Scene *scene, BMLoop *l, const BMUVOffsets offsets) { + BLI_assert(offsets.uv >= 0); BMIter liter; BMLoop *l_iter; BM_ITER_ELEM (l_iter, &liter, l->v, BM_LOOPS_OF_VERT) { if (!uvedit_face_visible_test(scene, l_iter->f) || (l_iter->f == l->f)) { continue; } - if (BM_loop_uv_share_vert_check(l, l_iter, cd_loop_uv_offset) && - uvedit_face_select_test(scene, l_iter->f, cd_loop_uv_offset)) { + if (BM_loop_uv_share_vert_check(l, l_iter, offsets.uv) && + uvedit_face_select_test(scene, l_iter->f, offsets)) { return true; } } @@ -1234,30 +1213,28 @@ bool uvedit_vert_is_face_select_any_other(const Scene *scene, bool uvedit_vert_is_all_other_faces_selected(const Scene *scene, BMLoop *l, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { + BLI_assert(offsets.uv >= 0); BMIter liter; BMLoop *l_iter; BM_ITER_ELEM (l_iter, &liter, l->v, BM_LOOPS_OF_VERT) { if (!uvedit_face_visible_test(scene, l_iter->f) || (l_iter->f == l->f)) { continue; } - if (BM_loop_uv_share_vert_check(l, l_iter, cd_loop_uv_offset) && - !uvedit_face_select_test(scene, l_iter->f, cd_loop_uv_offset)) { + if (BM_loop_uv_share_vert_check(l, l_iter, offsets.uv) && + !uvedit_face_select_test(scene, l_iter->f, offsets)) { return false; } } return true; } -/** - * Clear specified UV flag (vert/edge/pinned). - */ -static void bm_uv_flag_clear(const Scene *scene, - BMesh *bm, - const int flag, - const int cd_loop_uv_offset) +static void bm_clear_uv_vert_selection(const Scene *scene, BMesh *bm, const BMUVOffsets offsets) { + if (offsets.select_vert == -1) { + return; + } BMFace *efa; BMLoop *l; BMIter iter, liter; @@ -1266,8 +1243,7 @@ static void bm_uv_flag_clear(const Scene *scene, continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag &= ~flag; + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); } } } @@ -1282,7 +1258,10 @@ static void bm_uv_flag_clear(const Scene *scene, void ED_uvedit_selectmode_flush(const Scene *scene, BMEditMesh *em) { const ToolSettings *ts = scene->toolsettings; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BLI_assert((ts->uv_flag & UV_SYNC_SELECTION) == 0); UNUSED_VARS_NDEBUG(ts); @@ -1297,16 +1276,9 @@ void ED_uvedit_selectmode_flush(const Scene *scene, BMEditMesh *em) continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv, *luv_next; - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - - if ((luv->flag & MLOOPUV_VERTSEL) && (luv_next->flag & MLOOPUV_VERTSEL)) { - luv->flag |= MLOOPUV_EDGESEL; - } - else { - luv->flag &= ~MLOOPUV_EDGESEL; - } + bool edge_selected = BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) && + BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, edge_selected); } } } @@ -1323,7 +1295,10 @@ void uvedit_select_flush(const Scene *scene, BMEditMesh *em) /* Careful when using this in face select mode. * For face selections with sticky mode enabled, this can create invalid selection states. */ const ToolSettings *ts = scene->toolsettings; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BLI_assert((ts->uv_flag & UV_SYNC_SELECTION) == 0); UNUSED_VARS_NDEBUG(ts); @@ -1336,12 +1311,9 @@ void uvedit_select_flush(const Scene *scene, BMEditMesh *em) continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv, *luv_next; - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - - if ((luv->flag & MLOOPUV_VERTSEL) && (luv_next->flag & MLOOPUV_VERTSEL)) { - luv->flag |= MLOOPUV_EDGESEL; + if (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) && + BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert)) { + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true); } } } @@ -1350,7 +1322,10 @@ void uvedit_select_flush(const Scene *scene, BMEditMesh *em) void uvedit_deselect_flush(const Scene *scene, BMEditMesh *em) { const ToolSettings *ts = scene->toolsettings; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BLI_assert((ts->uv_flag & UV_SYNC_SELECTION) == 0); UNUSED_VARS_NDEBUG(ts); @@ -1363,14 +1338,9 @@ void uvedit_deselect_flush(const Scene *scene, BMEditMesh *em) continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv, *luv_next; - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - - if (luv->flag & MLOOPUV_EDGESEL) { - if (!(luv->flag & MLOOPUV_VERTSEL) || !(luv_next->flag & MLOOPUV_VERTSEL)) { - luv->flag &= ~MLOOPUV_EDGESEL; - } + if ((!BM_ELEM_CD_GET_BOOL(l, offsets.select_vert)) || + (!BM_ELEM_CD_GET_BOOL(l->next, offsets.select_vert))) { + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); } } } @@ -1393,13 +1363,13 @@ enum eUVEdgeLoopBoundaryMode { static BMLoop *bm_select_edgeloop_double_side_next(const Scene *scene, BMLoop *l_step, BMVert *v_from, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { if (l_step->f->len == 4) { BMVert *v_from_next = BM_edge_other_vert(l_step->e, v_from); BMLoop *l_step_over = (v_from == l_step->v) ? l_step->next : l_step->prev; l_step_over = uvedit_loop_find_other_radial_loop_with_visible_face( - scene, l_step_over, cd_loop_uv_offset); + scene, l_step_over, offsets); if (l_step_over) { return (l_step_over->v == v_from_next) ? l_step_over->prev : l_step_over->next; } @@ -1410,11 +1380,11 @@ static BMLoop *bm_select_edgeloop_double_side_next(const Scene *scene, static BMLoop *bm_select_edgeloop_single_side_next(const Scene *scene, BMLoop *l_step, BMVert *v_from, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { BMVert *v_from_next = BM_edge_other_vert(l_step->e, v_from); return uvedit_loop_find_other_boundary_loop_with_visible_face( - scene, l_step, v_from_next, cd_loop_uv_offset); + scene, l_step, v_from_next, offsets); } /* TODO(@campbellbarton): support this in the BMesh API, as we have for clearing other types. */ @@ -1437,7 +1407,7 @@ static void bm_loop_tags_clear(BMesh *bm) static void uv_select_edgeloop_double_side_tag(const Scene *scene, BMEditMesh *em, BMLoop *l_init_pair[2], - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { bm_loop_tags_clear(em->bm); @@ -1451,8 +1421,8 @@ static void uv_select_edgeloop_double_side_tag(const Scene *scene, if (!uvedit_face_visible_test(scene, l_step_pair[0]->f) || !uvedit_face_visible_test(scene, l_step_pair[1]->f) || /* Check loops have not diverged. */ - (uvedit_loop_find_other_radial_loop_with_visible_face( - scene, l_step_pair[0], cd_loop_uv_offset) != l_step_pair[1])) { + (uvedit_loop_find_other_radial_loop_with_visible_face(scene, l_step_pair[0], offsets) != + l_step_pair[1])) { break; } @@ -1465,7 +1435,7 @@ static void uv_select_edgeloop_double_side_tag(const Scene *scene, /* Walk over both sides, ensure they keep on the same edge. */ for (int i = 0; i < ARRAY_SIZE(l_step_pair); i++) { l_step_pair[i] = bm_select_edgeloop_double_side_next( - scene, l_step_pair[i], v_from, cd_loop_uv_offset); + scene, l_step_pair[i], v_from, offsets); } if ((l_step_pair[0] && BM_elem_flag_test(l_step_pair[0], BM_ELEM_TAG)) || @@ -1486,7 +1456,7 @@ static void uv_select_edgeloop_double_side_tag(const Scene *scene, static void uv_select_edgeloop_single_side_tag(const Scene *scene, BMEditMesh *em, BMLoop *l_init, - const int cd_loop_uv_offset, + const BMUVOffsets offsets, enum eUVEdgeLoopBoundaryMode boundary_mode, int r_count_by_select[2]) { @@ -1505,13 +1475,12 @@ static void uv_select_edgeloop_single_side_tag(const Scene *scene, if (!uvedit_face_visible_test(scene, l_step->f) || /* Check the boundary is still a boundary. */ - (uvedit_loop_find_other_radial_loop_with_visible_face( - scene, l_step, cd_loop_uv_offset) != NULL)) { + (uvedit_loop_find_other_radial_loop_with_visible_face(scene, l_step, offsets) != NULL)) { break; } if (r_count_by_select != NULL) { - r_count_by_select[uvedit_edge_select_test(scene, l_step, cd_loop_uv_offset)] += 1; + r_count_by_select[uvedit_edge_select_test(scene, l_step, offsets)] += 1; /* Early exit when mixed could be optional if needed. */ if (r_count_by_select[0] && r_count_by_select[1]) { r_count_by_select[0] = r_count_by_select[1] = -1; @@ -1524,7 +1493,7 @@ static void uv_select_edgeloop_single_side_tag(const Scene *scene, BMVert *v_from_next = BM_edge_other_vert(l_step->e, v_from); BMFace *f_step_prev = l_step->f; - l_step = bm_select_edgeloop_single_side_next(scene, l_step, v_from, cd_loop_uv_offset); + l_step = bm_select_edgeloop_single_side_next(scene, l_step, v_from, offsets); if (l_step && BM_elem_flag_test(l_step, BM_ELEM_TAG)) { break; @@ -1546,10 +1515,13 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c BMEditMesh *em = BKE_editmesh_from_object(obedit); bool select; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); if (extend) { - select = !uvedit_edge_select_test(scene, hit->l, cd_loop_uv_offset); + select = !uvedit_edge_select_test(scene, hit->l, offsets); } else { select = true; @@ -1557,7 +1529,7 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c BMLoop *l_init_pair[2] = { hit->l, - uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, cd_loop_uv_offset), + uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, offsets), }; /* When selecting boundaries, support cycling between selection modes. */ @@ -1569,13 +1541,13 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c int count_by_select[2]; /* If the loops selected toggle the boundaries. */ uv_select_edgeloop_single_side_tag( - scene, em, l_init_pair[0], cd_loop_uv_offset, boundary_mode, count_by_select); + scene, em, l_init_pair[0], offsets, boundary_mode, count_by_select); if (count_by_select[!select] == 0) { boundary_mode = UV_EDGE_LOOP_BOUNDARY_ALL; /* If the boundary is selected, toggle back to the loop. */ uv_select_edgeloop_single_side_tag( - scene, em, l_init_pair[0], cd_loop_uv_offset, boundary_mode, count_by_select); + scene, em, l_init_pair[0], offsets, boundary_mode, count_by_select); if (count_by_select[!select] == 0) { boundary_mode = UV_EDGE_LOOP_BOUNDARY_LOOP; } @@ -1583,11 +1555,10 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c } if (l_init_pair[1] == NULL) { - uv_select_edgeloop_single_side_tag( - scene, em, l_init_pair[0], cd_loop_uv_offset, boundary_mode, NULL); + uv_select_edgeloop_single_side_tag(scene, em, l_init_pair[0], offsets, boundary_mode, NULL); } else { - uv_select_edgeloop_double_side_tag(scene, em, l_init_pair, cd_loop_uv_offset); + uv_select_edgeloop_double_side_tag(scene, em, l_init_pair, offsets); } /* Apply the selection. */ @@ -1605,13 +1576,11 @@ static int uv_select_edgeloop(Scene *scene, Object *obedit, UvNearestHit *hit, c BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l_iter, BM_ELEM_TAG)) { if (ts->uv_selectmode == UV_SELECT_VERTEX) { - uvedit_uv_select_set_with_sticky(scene, em, l_iter, select, false, cd_loop_uv_offset); - uvedit_uv_select_set_with_sticky( - scene, em, l_iter->next, select, false, cd_loop_uv_offset); + uvedit_uv_select_set_with_sticky(scene, em, l_iter, select, false, offsets); + uvedit_uv_select_set_with_sticky(scene, em, l_iter->next, select, false, offsets); } else { - uvedit_edge_select_set_with_sticky( - scene, em, l_iter, select, false, cd_loop_uv_offset); + uvedit_edge_select_set_with_sticky(scene, em, l_iter, select, false, offsets); } } } @@ -1632,7 +1601,10 @@ static int uv_select_faceloop(Scene *scene, Object *obedit, UvNearestHit *hit, c BMEditMesh *em = BKE_editmesh_from_object(obedit); bool select; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); if (!extend) { uv_select_all_perform(scene, obedit, SEL_DESELECT); @@ -1641,7 +1613,7 @@ static int uv_select_faceloop(Scene *scene, Object *obedit, UvNearestHit *hit, c BM_mesh_elem_hflag_disable_all(em->bm, BM_FACE, BM_ELEM_TAG, false); if (extend) { - select = !uvedit_face_select_test(scene, hit->l->f, cd_loop_uv_offset); + select = !uvedit_face_select_test(scene, hit->l->f, offsets); } else { select = true; @@ -1649,7 +1621,7 @@ static int uv_select_faceloop(Scene *scene, Object *obedit, UvNearestHit *hit, c BMLoop *l_pair[2] = { hit->l, - uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, cd_loop_uv_offset), + uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, offsets), }; for (int side = 0; side < 2; side++) { @@ -1659,13 +1631,13 @@ static int uv_select_faceloop(Scene *scene, Object *obedit, UvNearestHit *hit, c break; } - uvedit_face_select_set_with_sticky(scene, em, l_step->f, select, false, cd_loop_uv_offset); + uvedit_face_select_set_with_sticky(scene, em, l_step->f, select, false, offsets); BM_elem_flag_enable(l_step->f, BM_ELEM_TAG); if (l_step->f->len == 4) { BMLoop *l_step_opposite = l_step->next->next; l_step = uvedit_loop_find_other_radial_loop_with_visible_face( - scene, l_step_opposite, cd_loop_uv_offset); + scene, l_step_opposite, offsets); } else { l_step = NULL; @@ -1701,7 +1673,10 @@ static int uv_select_edgering(Scene *scene, Object *obedit, UvNearestHit *hit, c (ts->uv_selectmode & UV_SELECT_VERTEX); bool select; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); if (!extend) { uv_select_all_perform(scene, obedit, SEL_DESELECT); @@ -1710,7 +1685,7 @@ static int uv_select_edgering(Scene *scene, Object *obedit, UvNearestHit *hit, c BM_mesh_elem_hflag_disable_all(em->bm, BM_EDGE, BM_ELEM_TAG, false); if (extend) { - select = !uvedit_edge_select_test(scene, hit->l, cd_loop_uv_offset); + select = !uvedit_edge_select_test(scene, hit->l, offsets); } else { select = true; @@ -1718,7 +1693,7 @@ static int uv_select_edgering(Scene *scene, Object *obedit, UvNearestHit *hit, c BMLoop *l_pair[2] = { hit->l, - uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, cd_loop_uv_offset), + uvedit_loop_find_other_radial_loop_with_visible_face(scene, hit->l, offsets), }; for (int side = 0; side < 2; side++) { @@ -1734,23 +1709,22 @@ static int uv_select_edgering(Scene *scene, Object *obedit, UvNearestHit *hit, c /* While selecting face loops is now done in a separate function #uv_select_faceloop(), * this check is still kept for edge ring selection, to keep it consistent with how edge * ring selection works in face mode in the 3D viewport. */ - uvedit_face_select_set_with_sticky(scene, em, l_step->f, select, false, cd_loop_uv_offset); + uvedit_face_select_set_with_sticky(scene, em, l_step->f, select, false, offsets); } else if (use_vertex_select) { - uvedit_uv_select_set_with_sticky(scene, em, l_step, select, false, cd_loop_uv_offset); - uvedit_uv_select_set_with_sticky( - scene, em, l_step->next, select, false, cd_loop_uv_offset); + uvedit_uv_select_set_with_sticky(scene, em, l_step, select, false, offsets); + uvedit_uv_select_set_with_sticky(scene, em, l_step->next, select, false, offsets); } else { /* Edge select mode */ - uvedit_edge_select_set_with_sticky(scene, em, l_step, select, false, cd_loop_uv_offset); + uvedit_edge_select_set_with_sticky(scene, em, l_step, select, false, offsets); } BM_elem_flag_enable(l_step->e, BM_ELEM_TAG); if (l_step->f->len == 4) { BMLoop *l_step_opposite = l_step->next->next; l_step = uvedit_loop_find_other_radial_loop_with_visible_face( - scene, l_step_opposite, cd_loop_uv_offset); + scene, l_step_opposite, offsets); if (l_step == NULL) { /* Ensure we touch the opposite edge if we can't walk over it. */ l_step = l_step_opposite; @@ -1767,10 +1741,10 @@ static int uv_select_edgering(Scene *scene, Object *obedit, UvNearestHit *hit, c if (l_step && BM_elem_flag_test(l_step->e, BM_ELEM_TAG)) { /* Previously this check was not done and this resulted in the final edge in the edge ring * cycle to be skipped during selection (caused by old sticky selection behavior). */ - if (select && uvedit_edge_select_test(scene, l_step, cd_loop_uv_offset)) { + if (select && uvedit_edge_select_test(scene, l_step, offsets)) { break; } - if (!select && !uvedit_edge_select_test(scene, l_step, cd_loop_uv_offset)) { + if (!select && !uvedit_edge_select_test(scene, l_step, offsets)) { break; } } @@ -1814,7 +1788,11 @@ static void uv_select_linked_multi(Scene *scene, char *flag; BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BLI_assert(active_uv_name != NULL); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BM_mesh_elem_table_ensure(em->bm, BM_FACE); /* we can use this too */ @@ -1846,7 +1824,7 @@ static void uv_select_linked_multi(Scene *scene, } else { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (uvedit_uv_select_test(scene, l, offsets)) { bool add_to_stack = true; if (uv_sync_select) { /* Special case, vertex/edge & sync select being enabled. @@ -1860,16 +1838,15 @@ static void uv_select_linked_multi(Scene *scene, * - There are no connected fully selected faces UV-connected to this loop. */ BLI_assert(!select_faces); - if (uvedit_face_select_test(scene, l->f, cd_loop_uv_offset)) { + if (uvedit_face_select_test(scene, l->f, offsets)) { /* pass */ } else { BMIter liter_other; BMLoop *l_other; BM_ITER_ELEM (l_other, &liter_other, l->v, BM_LOOPS_OF_VERT) { - if ((l != l_other) && - !BM_loop_uv_share_vert_check(l, l_other, cd_loop_uv_offset) && - uvedit_face_select_test(scene, l_other->f, cd_loop_uv_offset)) { + if ((l != l_other) && !BM_loop_uv_share_vert_check(l, l_other, offsets.uv) && + uvedit_face_select_test(scene, l_other->f, offsets)) { add_to_stack = false; break; } @@ -1951,7 +1928,7 @@ static void uv_select_linked_multi(Scene *scene, } else { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (uvedit_uv_select_test(scene, l, offsets)) { found_selected = true; break; } @@ -1970,7 +1947,7 @@ static void uv_select_linked_multi(Scene *scene, BM_face_select_set(em->bm, efa, value); \ } \ else { \ - uvedit_face_select_set(scene, em->bm, efa, value, false, cd_loop_uv_offset); \ + uvedit_face_select_set(scene, em->bm, efa, value, false, offsets); \ } \ (void)0 @@ -2011,7 +1988,7 @@ static void uv_select_linked_multi(Scene *scene, const float *uvedit_first_selected_uv_from_vertex(Scene *scene, BMVert *eve, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { BMIter liter; BMLoop *l; @@ -2021,9 +1998,9 @@ const float *uvedit_first_selected_uv_from_vertex(Scene *scene, continue; } - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - return luv->uv; + if (uvedit_uv_select_test(scene, l, offsets)) { + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + return luv; } } @@ -2058,7 +2035,10 @@ static int uv_select_more_less(bContext *C, const bool select) bool changed = false; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); if (ts->uv_flag & UV_SYNC_SELECTION) { if (select) { @@ -2089,15 +2069,14 @@ static int uv_select_more_less(bContext *C, const bool select) int sel_state = 0; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (luv->flag & MLOOPUV_VERTSEL) { + if (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert)) { sel_state |= NEIGHBORING_FACE_IS_SEL; } else { sel_state |= CURR_FACE_IS_UNSEL; } - if (!(luv->flag & MLOOPUV_EDGESEL)) { + if (!BM_ELEM_CD_GET_BOOL(l, offsets.select_edge)) { sel_state |= CURR_FACE_IS_UNSEL; } @@ -2114,12 +2093,12 @@ static int uv_select_more_less(bContext *C, const bool select) #undef CURR_FACE_IS_UNSEL } else { - if (!uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { + if (!uvedit_face_select_test(scene, efa, offsets)) { continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { /* Deselect face when at least one of the surrounding faces is not selected */ - if (!uvedit_vert_is_all_other_faces_selected(scene, l, cd_loop_uv_offset)) { + if (!uvedit_vert_is_all_other_faces_selected(scene, l, offsets)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); changed = true; break; @@ -2143,9 +2122,7 @@ static int uv_select_more_less(bContext *C, const bool select) if (uvedit_face_visible_test(scene, efa)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - - if (((luv->flag & MLOOPUV_VERTSEL) != 0) == select) { + if (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) == select) { BM_elem_flag_enable(l->next, BM_ELEM_TAG); BM_elem_flag_enable(l->prev, BM_ELEM_TAG); changed = true; @@ -2229,20 +2206,19 @@ bool uvedit_select_is_any_selected(const Scene *scene, Object *obedit) BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; if (ts->uv_flag & UV_SYNC_SELECTION) { return (em->bm->totvertsel || em->bm->totedgesel || em->bm->totfacesel); } - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (luv->flag & MLOOPUV_VERTSEL) { + if (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert)) { return true; } } @@ -2270,16 +2246,18 @@ static void uv_select_all(const Scene *scene, BMEditMesh *em, bool select_all) BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - const int uv_select_flags = (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - SET_FLAG_FROM_TEST(luv->flag, select_all, uv_select_flags); + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, select_all); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, select_all); } } } @@ -2289,27 +2267,30 @@ static void uv_select_invert(const Scene *scene, BMEditMesh *em) const ToolSettings *ts = scene->toolsettings; BLI_assert((ts->uv_flag & UV_SYNC_SELECTION) == 0); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; char uv_selectmode = ts->uv_selectmode; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (ELEM(uv_selectmode, UV_SELECT_EDGE, UV_SELECT_FACE)) { - /* Use #MLOOPUV_EDGESEL to flag edges that must be selected. */ - luv->flag ^= MLOOPUV_EDGESEL; - luv->flag &= ~MLOOPUV_VERTSEL; + if ((uv_selectmode == UV_SELECT_EDGE) || (uv_selectmode == UV_SELECT_FACE)) { + /* Use UV edge selection to find vertices and edges that must be selected. */ + bool es = BM_ELEM_CD_GET_BOOL(l, offsets.select_edge); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, !es); + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); } - /* Use #MLOOPUV_VERTSEL to flag verts that must be selected. */ - else if (ELEM(uv_selectmode, UV_SELECT_VERTEX, UV_SELECT_ISLAND)) { - luv->flag ^= MLOOPUV_VERTSEL; - luv->flag &= ~MLOOPUV_EDGESEL; + /* Use UV vertex selection to find vertices and edges that must be selected. */ + else if ((uv_selectmode == UV_SELECT_VERTEX) || (uv_selectmode == UV_SELECT_ISLAND)) { + bool vs = BM_ELEM_CD_GET_BOOL(l, offsets.select_vert); + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, !vs); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); } } } @@ -2533,21 +2514,24 @@ static bool uv_mouse_select_multi(bContext *C, if (found) { Object *obedit = hit.ob; BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); if (selectmode == UV_SELECT_FACE) { - is_selected = uvedit_face_select_test(scene, hit.efa, cd_loop_uv_offset); + is_selected = uvedit_face_select_test(scene, hit.efa, offsets); } else if (selectmode == UV_SELECT_EDGE) { - is_selected = uvedit_edge_select_test(scene, hit.l, cd_loop_uv_offset); + is_selected = uvedit_edge_select_test(scene, hit.l, offsets); } else { /* Vertex or island. For island (if we were using #uv_find_nearest_face_multi_ex, see above), * `hit.l` is NULL, use `hit.efa` instead. */ if (hit.l != NULL) { - is_selected = uvedit_uv_select_test(scene, hit.l, cd_loop_uv_offset); + is_selected = uvedit_uv_select_test(scene, hit.l, offsets); } else { - is_selected = uvedit_face_select_test(scene, hit.efa, cd_loop_uv_offset); + is_selected = uvedit_face_select_test(scene, hit.efa, offsets); } } } @@ -2570,7 +2554,10 @@ static bool uv_mouse_select_multi(bContext *C, if (found) { Object *obedit = hit.ob; BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); if (selectmode == UV_SELECT_ISLAND) { const bool extend = params->sel_op == SEL_OP_ADD; @@ -2610,17 +2597,15 @@ static bool uv_mouse_select_multi(bContext *C, } if (selectmode == UV_SELECT_FACE) { - uvedit_face_select_set_with_sticky( - scene, em, hit.efa, select_value, true, cd_loop_uv_offset); + uvedit_face_select_set_with_sticky(scene, em, hit.efa, select_value, true, offsets); flush = 1; } else if (selectmode == UV_SELECT_EDGE) { - uvedit_edge_select_set_with_sticky( - scene, em, hit.l, select_value, true, cd_loop_uv_offset); + uvedit_edge_select_set_with_sticky(scene, em, hit.l, select_value, true, offsets); flush = 1; } else if (selectmode == UV_SELECT_VERTEX) { - uvedit_uv_select_set_with_sticky(scene, em, hit.l, select_value, true, cd_loop_uv_offset); + uvedit_uv_select_set_with_sticky(scene, em, hit.l, select_value, true, offsets); flush = 1; } else { @@ -3126,7 +3111,6 @@ static int uv_select_split_exec(bContext *C, wmOperator *op) BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; if (ts->uv_flag & UV_SYNC_SELECTION) { BKE_report(op->reports, RPT_ERROR, "Cannot split selection when sync selection is enabled"); @@ -3145,7 +3129,10 @@ static int uv_select_split_exec(bContext *C, wmOperator *op) bool changed = false; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { bool is_sel = false; @@ -3157,12 +3144,13 @@ static int uv_select_split_exec(bContext *C, wmOperator *op) /* are we all selected? */ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if ((luv->flag & MLOOPUV_VERTSEL) || (luv->flag & MLOOPUV_EDGESEL)) { + if (BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) || + BM_ELEM_CD_GET_BOOL(l, offsets.select_edge)) { is_sel = true; } - if (!(luv->flag & MLOOPUV_VERTSEL) || !(luv->flag & MLOOPUV_EDGESEL)) { + if (!BM_ELEM_CD_GET_BOOL(l, offsets.select_vert) || + !BM_ELEM_CD_GET_BOOL(l, offsets.select_edge)) { is_unsel = true; } @@ -3174,8 +3162,8 @@ static int uv_select_split_exec(bContext *C, wmOperator *op) if (is_sel && is_unsel) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag &= ~(MLOOPUV_VERTSEL | MLOOPUV_EDGESEL); + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); } changed = true; @@ -3239,12 +3227,12 @@ static void uv_select_flush_from_tag_sticky_loc_internal(const Scene *scene, const uint efa_index, BMLoop *l, const bool select, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { UvMapVert *start_vlist = NULL, *vlist_iter; BMFace *efa_vlist; - uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset); + uvedit_uv_select_set(scene, em->bm, l, select, false, offsets); vlist_iter = BM_uv_vert_map_at_index(vmap, BM_elem_index_get(l->v)); @@ -3274,7 +3262,7 @@ static void uv_select_flush_from_tag_sticky_loc_internal(const Scene *scene, l_other = BM_iter_at_index( em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->loop_of_poly_index); - uvedit_uv_select_set(scene, em->bm, l_other, select, false, cd_loop_uv_offset); + uvedit_uv_select_set(scene, em->bm, l_other, select, false, offsets); } vlist_iter = vlist_iter->next; } @@ -3303,7 +3291,10 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co BMFace *efa; BMLoop *l; BMIter iter, liter; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ELEM(ts->uv_sticky, SI_STICKY_VERTEX, SI_STICKY_LOC)) { @@ -3320,17 +3311,16 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, efa_index) { if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); if (select) { - luv->flag |= MLOOPUV_EDGESEL; + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); uv_select_flush_from_tag_sticky_loc_internal( - scene, em, vmap, efa_index, l, select, cd_loop_uv_offset); + scene, em, vmap, efa_index, l, select, offsets); } else { - luv->flag &= ~MLOOPUV_EDGESEL; - if (!uvedit_vert_is_face_select_any_other(scene, l, cd_loop_uv_offset)) { + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); + if (!uvedit_vert_is_face_select_any_other(scene, l, offsets)) { uv_select_flush_from_tag_sticky_loc_internal( - scene, em, vmap, efa_index, l, select, cd_loop_uv_offset); + scene, em, vmap, efa_index, l, select, offsets); } } } @@ -3341,7 +3331,7 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co else { /* SI_STICKY_DISABLE or ts->uv_flag & UV_SYNC_SELECTION */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { - uvedit_face_select_set(scene, em->bm, efa, select, false, cd_loop_uv_offset); + uvedit_face_select_set(scene, em->bm, efa, select, false, offsets); } } } @@ -3371,11 +3361,14 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co BMLoop *l; BMIter iter, liter; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ts->uv_sticky == SI_STICKY_VERTEX) { /* Tag all verts as untouched, then touch the ones that have a face center - * in the loop and select all MLoopUV's that use a touched vert. */ + * in the loop and select all UV's that use a touched vert. */ BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { @@ -3390,7 +3383,7 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l->v, BM_ELEM_TAG)) { - uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset); + uvedit_uv_select_set(scene, em->bm, l, select, false, offsets); } } } @@ -3409,7 +3402,7 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l, BM_ELEM_TAG)) { uv_select_flush_from_tag_sticky_loc_internal( - scene, em, vmap, efa_index, l, select, cd_loop_uv_offset); + scene, em, vmap, efa_index, l, select, offsets); } } } @@ -3419,7 +3412,7 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_elem_flag_test(l, BM_ELEM_TAG)) { - uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset); + uvedit_uv_select_set(scene, em->bm, l, select, false, offsets); } } } @@ -3427,10 +3420,10 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co } /** - * Flush the selection from UV edge flags based on sticky modes. + * Flush the selection from UV edges based on sticky modes. * * Useful when performing edge selections in different sticky modes, since setting the required - * edge flags (#MLOOPUV_EDGESEL) is done manually or using #uvedit_edge_select_set_noflush, + * edge selection is done manually or using #uvedit_edge_select_set_noflush, * but dealing with sticky modes for vertex selections is best done in a separate function. * * \note Current behavior is selecting only; deselecting can be added but the behavior isn't @@ -3443,15 +3436,18 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMEditMesh * BMLoop *l; BMIter iter, liter; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ELEM(ts->uv_sticky, SI_STICKY_LOC, SI_STICKY_VERTEX)) { - /* Use the #MLOOPUV_EDGESEL flag to identify which verts must to be selected */ + /* Use UV edge selection to identify which verts must to be selected */ struct UvVertMap *vmap; uint efa_index; /* Clear UV vert flags */ - bm_uv_flag_clear(scene, em->bm, MLOOPUV_VERTSEL, cd_loop_uv_offset); + bm_clear_uv_vert_selection(scene, em->bm, offsets); BM_mesh_elem_table_ensure(em->bm, BM_FACE); vmap = BM_uv_vert_map_create(em->bm, false, false); @@ -3465,14 +3461,12 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMEditMesh * continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv; - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); /* Select verts based on UV edge flag. */ - if (luv->flag & MLOOPUV_EDGESEL) { + if (BM_ELEM_CD_GET_BOOL(l, offsets.select_edge)) { uv_select_flush_from_tag_sticky_loc_internal( - scene, em, vmap, efa_index, l, true, cd_loop_uv_offset); + scene, em, vmap, efa_index, l, true, offsets); uv_select_flush_from_tag_sticky_loc_internal( - scene, em, vmap, efa_index, l->next, true, cd_loop_uv_offset); + scene, em, vmap, efa_index, l->next, true, offsets); } } } @@ -3481,17 +3475,13 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMEditMesh * else { BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv, *luv_next, *luv_prev; - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - luv_prev = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_uv_offset); - if (luv->flag & MLOOPUV_EDGESEL) { - luv->flag |= MLOOPUV_VERTSEL; - luv_next->flag |= MLOOPUV_VERTSEL; + if (BM_ELEM_CD_GET_BOOL(l, offsets.select_edge)) { + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); + BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, true); } - else if (!(luv_prev->flag & MLOOPUV_EDGESEL)) { - luv->flag &= ~MLOOPUV_VERTSEL; + else if (!BM_ELEM_CD_GET_BOOL(l->prev, offsets.select_edge)) { + BM_ELEM_CD_SET_BOOL(l->next, offsets.select_vert, false); } } } @@ -3514,7 +3504,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op) BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; + float *luv; rctf rectf; bool pinned; const bool use_face_center = ((ts->uv_flag & UV_SYNC_SELECTION) ? @@ -3553,7 +3543,11 @@ static int uv_box_select_exec(bContext *C, wmOperator *op) bool changed = false; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_pin_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); /* do actual selection */ if (use_face_center && !pinned) { @@ -3565,7 +3559,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op) BM_elem_flag_disable(efa, BM_ELEM_TAG); if (uvedit_face_visible_test(scene, efa)) { - BM_face_uv_calc_center_median(efa, cd_loop_uv_offset, cent); + BM_face_uv_calc_center_median(efa, offsets.uv, cent); if (BLI_rctf_isect_pt_v(&rectf, cent)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); changed = true; @@ -3586,13 +3580,12 @@ static int uv_box_select_exec(bContext *C, wmOperator *op) } BMLoop *l_prev = BM_FACE_FIRST_LOOP(efa)->prev; - MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l_prev, cd_loop_uv_offset); + float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l_prev, offsets.uv); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (BLI_rctf_isect_pt_v(&rectf, luv->uv) && BLI_rctf_isect_pt_v(&rectf, luv_prev->uv)) { - uvedit_edge_select_set_with_sticky( - scene, em, l_prev, select, false, cd_loop_uv_offset); + luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + if (BLI_rctf_isect_pt_v(&rectf, luv) && BLI_rctf_isect_pt_v(&rectf, luv_prev)) { + uvedit_edge_select_set_with_sticky(scene, em, l_prev, select, false, offsets); changed = true; do_second_pass = false; } @@ -3609,13 +3602,12 @@ static int uv_box_select_exec(bContext *C, wmOperator *op) continue; } BMLoop *l_prev = BM_FACE_FIRST_LOOP(efa)->prev; - MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l_prev, cd_loop_uv_offset); + float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l_prev, offsets.uv); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (BLI_rctf_isect_segment(&rectf, luv_prev->uv, luv->uv)) { - uvedit_edge_select_set_with_sticky( - scene, em, l_prev, select, false, cd_loop_uv_offset); + luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + if (BLI_rctf_isect_segment(&rectf, luv_prev, luv)) { + uvedit_edge_select_set_with_sticky(scene, em, l_prev, select, false, offsets); changed = true; } l_prev = l; @@ -3635,19 +3627,19 @@ static int uv_box_select_exec(bContext *C, wmOperator *op) } bool has_selected = false; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (select != uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + if (select != uvedit_uv_select_test(scene, l, offsets)) { if (!pinned || (ts->uv_flag & UV_SYNC_SELECTION)) { /* UV_SYNC_SELECTION - can't do pinned selection */ - if (BLI_rctf_isect_pt_v(&rectf, luv->uv)) { - uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset); + if (BLI_rctf_isect_pt_v(&rectf, luv)) { + uvedit_uv_select_set(scene, em->bm, l, select, false, offsets); BM_elem_flag_enable(l->v, BM_ELEM_TAG); has_selected = true; } } else if (pinned) { - if ((luv->flag & MLOOPUV_PINNED) && BLI_rctf_isect_pt_v(&rectf, luv->uv)) { - uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset); + if (BM_ELEM_CD_GET_BOOL(l, offsets.pin) && BLI_rctf_isect_pt_v(&rectf, luv)) { + uvedit_uv_select_set(scene, em->bm, l, select, false, offsets); BM_elem_flag_enable(l->v, BM_ELEM_TAG); } } @@ -3663,7 +3655,7 @@ static int uv_box_select_exec(bContext *C, wmOperator *op) } if (ts->uv_sticky == SI_STICKY_VERTEX) { - uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset); + uvedit_vertex_select_tagged(em, scene, select, offsets); } } @@ -3754,7 +3746,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; + float *luv; int x, y, radius, width, height; float zoomx, zoomy; float offset[2], ellipse[2]; @@ -3804,16 +3796,19 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) bool changed = false; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); /* do selection */ if (use_face_center) { BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_elem_flag_disable(efa, BM_ELEM_TAG); /* assume not touched */ - if (select != uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { + if (select != uvedit_face_select_test(scene, efa, offsets)) { float cent[2]; - BM_face_uv_calc_center_median(efa, cd_loop_uv_offset, cent); + BM_face_uv_calc_center_median(efa, offsets.uv, cent); if (uv_circle_select_is_point_inside(cent, offset, ellipse)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); changed = true; @@ -3833,13 +3828,12 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) } BMLoop *l_prev = BM_FACE_FIRST_LOOP(efa)->prev; - MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l_prev, cd_loop_uv_offset); + float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l_prev, offsets.uv); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (uv_circle_select_is_edge_inside(luv->uv, luv_prev->uv, offset, ellipse)) { - uvedit_edge_select_set_with_sticky( - scene, em, l_prev, select, false, cd_loop_uv_offset); + luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + if (uv_circle_select_is_edge_inside(luv, luv_prev, offset, ellipse)) { + uvedit_edge_select_set_with_sticky(scene, em, l_prev, select, false, offsets); changed = true; } l_prev = l; @@ -3856,11 +3850,11 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) } bool has_selected = false; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (select != uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (uv_circle_select_is_point_inside(luv->uv, offset, ellipse)) { + if (select != uvedit_uv_select_test(scene, l, offsets)) { + luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + if (uv_circle_select_is_point_inside(luv, offset, ellipse)) { changed = true; - uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset); + uvedit_uv_select_set(scene, em->bm, l, select, false, offsets); BM_elem_flag_enable(l->v, BM_ELEM_TAG); has_selected = true; } @@ -3876,7 +3870,7 @@ static int uv_circle_select_exec(bContext *C, wmOperator *op) } if (ts->uv_sticky == SI_STICKY_VERTEX) { - uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset); + uvedit_vertex_select_tagged(em, scene, select, offsets); } } @@ -4006,15 +4000,18 @@ static bool do_lasso_select_mesh_uv(bContext *C, BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); if (use_face_center) { /* Face Center Select. */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_elem_flag_disable(efa, BM_ELEM_TAG); /* assume not touched */ - if (select != uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { + if (select != uvedit_face_select_test(scene, efa, offsets)) { float cent[2]; - BM_face_uv_calc_center_median(efa, cd_loop_uv_offset, cent); + BM_face_uv_calc_center_median(efa, offsets.uv, cent); if (do_lasso_select_mesh_uv_is_point_inside(region, &rect, mcoords, mcoords_len, cent)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); changed = true; @@ -4035,16 +4032,14 @@ static bool do_lasso_select_mesh_uv(bContext *C, } BMLoop *l_prev = BM_FACE_FIRST_LOOP(efa)->prev; - MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l_prev, cd_loop_uv_offset); + float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l_prev, offsets.uv); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (do_lasso_select_mesh_uv_is_point_inside( - region, &rect, mcoords, mcoords_len, luv->uv) && + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + if (do_lasso_select_mesh_uv_is_point_inside(region, &rect, mcoords, mcoords_len, luv) && do_lasso_select_mesh_uv_is_point_inside( - region, &rect, mcoords, mcoords_len, luv_prev->uv)) { - uvedit_edge_select_set_with_sticky( - scene, em, l_prev, select, false, cd_loop_uv_offset); + region, &rect, mcoords, mcoords_len, luv_prev)) { + uvedit_edge_select_set_with_sticky(scene, em, l_prev, select, false, offsets); do_second_pass = false; changed = true; } @@ -4061,14 +4056,13 @@ static bool do_lasso_select_mesh_uv(bContext *C, continue; } BMLoop *l_prev = BM_FACE_FIRST_LOOP(efa)->prev; - MLoopUV *luv_prev = BM_ELEM_CD_GET_VOID_P(l_prev, cd_loop_uv_offset); + float *luv_prev = BM_ELEM_CD_GET_FLOAT_P(l_prev, offsets.uv); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); if (do_lasso_select_mesh_uv_is_edge_inside( - region, &rect, mcoords, mcoords_len, luv->uv, luv_prev->uv)) { - uvedit_edge_select_set_with_sticky( - scene, em, l_prev, select, false, cd_loop_uv_offset); + region, &rect, mcoords, mcoords_len, luv, luv_prev)) { + uvedit_edge_select_set_with_sticky(scene, em, l_prev, select, false, offsets); changed = true; } l_prev = l; @@ -4086,11 +4080,11 @@ static bool do_lasso_select_mesh_uv(bContext *C, } bool has_selected = false; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (select != uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + if (select != uvedit_uv_select_test(scene, l, offsets)) { + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); if (do_lasso_select_mesh_uv_is_point_inside( - region, &rect, mcoords, mcoords_len, luv->uv)) { - uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset); + region, &rect, mcoords, mcoords_len, luv)) { + uvedit_uv_select_set(scene, em->bm, l, select, false, offsets); changed = true; BM_elem_flag_enable(l->v, BM_ELEM_TAG); has_selected = true; @@ -4107,7 +4101,7 @@ static bool do_lasso_select_mesh_uv(bContext *C, } if (ts->uv_sticky == SI_STICKY_VERTEX) { - uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset); + uvedit_vertex_select_tagged(em, scene, select, offsets); } } @@ -4188,7 +4182,6 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *op) BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; uint objects_len = 0; Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( @@ -4198,8 +4191,12 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *op) Object *obedit = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); bool changed = false; + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_pin_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!uvedit_face_visible_test(scene, efa)) { @@ -4207,10 +4204,9 @@ static int uv_select_pinned_exec(bContext *C, wmOperator *op) } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (luv->flag & MLOOPUV_PINNED) { - uvedit_uv_select_enable(scene, em->bm, l, false, cd_loop_uv_offset); + if (BM_ELEM_CD_GET_BOOL(l, offsets.pin)) { + uvedit_uv_select_enable(scene, em->bm, l, false, offsets); changed = true; } } @@ -4370,7 +4366,7 @@ static int uv_select_overlap(bContext *C, const bool extend) BMFace *efa; BMLoop *l; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); /* Triangulate each UV face and store it inside the BVH. */ int face_index; @@ -4393,8 +4389,8 @@ static int uv_select_overlap(bContext *C, const bool extend) int vert_index; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, vert_index) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - copy_v2_v2(uv_verts[vert_index], luv->uv); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + copy_v2_v2(uv_verts[vert_index], luv); } BLI_polyfill_calc(uv_verts, face_len, 0, indices); @@ -4451,20 +4447,26 @@ static int uv_select_overlap(bContext *C, const bool extend) BMEditMesh *em_b = BKE_editmesh_from_object(obedit_b); BMFace *face_a = em_a->bm->ftable[o_a->face_index]; BMFace *face_b = em_b->bm->ftable[o_b->face_index]; - const int cd_loop_uv_offset_a = CustomData_get_offset(&em_a->bm->ldata, CD_MLOOPUV); - const int cd_loop_uv_offset_b = CustomData_get_offset(&em_b->bm->ldata, CD_MLOOPUV); + const char *uv_a_name = CustomData_get_active_layer_name(&em_a->bm->ldata, CD_PROP_FLOAT2); + const char *uv_b_name = CustomData_get_active_layer_name(&em_b->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em_a->bm, uv_a_name); + BM_uv_map_ensure_vert_select_attr(em_b->bm, uv_b_name); + BM_uv_map_ensure_edge_select_attr(em_a->bm, uv_a_name); + BM_uv_map_ensure_edge_select_attr(em_b->bm, uv_b_name); + const BMUVOffsets offsets_a = BM_uv_map_get_offsets(em_a->bm); + const BMUVOffsets offsets_b = BM_uv_map_get_offsets(em_b->bm); /* Skip if both faces are already selected. */ - if (uvedit_face_select_test(scene, face_a, cd_loop_uv_offset_a) && - uvedit_face_select_test(scene, face_b, cd_loop_uv_offset_b)) { + if (uvedit_face_select_test(scene, face_a, offsets_a) && + uvedit_face_select_test(scene, face_b, offsets_b)) { continue; } /* Main tri-tri overlap test. */ const float endpoint_bias = -1e-4f; if (overlap_tri_tri_uv_test(o_a->tri, o_b->tri, endpoint_bias)) { - uvedit_face_select_enable(scene, em_a->bm, face_a, false, cd_loop_uv_offset_a); - uvedit_face_select_enable(scene, em_b->bm, face_b, false, cd_loop_uv_offset_b); + uvedit_face_select_enable(scene, em_a->bm, face_a, false, offsets_a); + uvedit_face_select_enable(scene, em_b->bm, face_b, false, offsets_b); } } @@ -4517,16 +4519,19 @@ void UV_OT_select_overlap(wmOperatorType *ot) static float get_uv_vert_needle(const eUVSelectSimilar type, BMVert *vert, const float ob_m3[3][3], - MLoopUV *luv, - const int cd_loop_uv_offset) + BMLoop *loop, + const BMUVOffsets offsets) { + BLI_assert(offsets.pin >= 0); + BLI_assert(offsets.uv >= 0); + float result = 0.0f; switch (type) { case UV_SSIM_AREA_UV: { BMFace *f; BMIter iter; BM_ITER_ELEM (f, &iter, vert, BM_FACES_OF_VERT) { - result += BM_face_calc_area_uv(f, cd_loop_uv_offset); + result += BM_face_calc_area_uv(f, offsets.uv); } } break; case UV_SSIM_AREA_3D: { @@ -4544,7 +4549,7 @@ static float get_uv_vert_needle(const eUVSelectSimilar type, } } break; case UV_SSIM_PIN: - return (luv->flag & MLOOPUV_PINNED) ? 1.0f : 0.0f; + return (BM_ELEM_CD_GET_BOOL(loop, offsets.pin)) ? 1.0f : 0.0f; default: BLI_assert_unreachable(); return false; @@ -4556,17 +4561,19 @@ static float get_uv_vert_needle(const eUVSelectSimilar type, static float get_uv_edge_needle(const eUVSelectSimilar type, BMEdge *edge, const float ob_m3[3][3], - MLoopUV *luv_a, - MLoopUV *luv_b, - const int cd_loop_uv_offset) + BMLoop *loop_a, + BMLoop *loop_b, + const BMUVOffsets offsets) { + BLI_assert(offsets.pin >= 0); + BLI_assert(offsets.uv >= 0); float result = 0.0f; switch (type) { case UV_SSIM_AREA_UV: { BMFace *f; BMIter iter; BM_ITER_ELEM (f, &iter, edge, BM_FACES_OF_EDGE) { - result += BM_face_calc_area_uv(f, cd_loop_uv_offset); + result += BM_face_calc_area_uv(f, offsets.uv); } } break; case UV_SSIM_AREA_3D: { @@ -4576,8 +4583,11 @@ static float get_uv_edge_needle(const eUVSelectSimilar type, result += BM_face_calc_area_with_mat3(f, ob_m3); } } break; - case UV_SSIM_LENGTH_UV: - return len_v2v2(luv_a->uv, luv_b->uv); + case UV_SSIM_LENGTH_UV: { + float *luv_a = BM_ELEM_CD_GET_FLOAT_P(loop_a, offsets.uv); + float *luv_b = BM_ELEM_CD_GET_FLOAT_P(loop_b, offsets.uv); + return len_v2v2(luv_a, luv_b); + } break; case UV_SSIM_LENGTH_3D: return len_v3v3(edge->v1->co, edge->v2->co); case UV_SSIM_SIDES: { @@ -4588,10 +4598,10 @@ static float get_uv_edge_needle(const eUVSelectSimilar type, } } break; case UV_SSIM_PIN: - if (luv_a->flag & MLOOPUV_PINNED) { + if (BM_ELEM_CD_GET_BOOL(loop_a, offsets.pin)) { result += 1.0f; } - if (luv_b->flag & MLOOPUV_PINNED) { + if (BM_ELEM_CD_GET_BOOL(loop_b, offsets.pin)) { result += 1.0f; } break; @@ -4606,12 +4616,14 @@ static float get_uv_edge_needle(const eUVSelectSimilar type, static float get_uv_face_needle(const eUVSelectSimilar type, BMFace *face, const float ob_m3[3][3], - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { + BLI_assert(offsets.pin >= 0); + BLI_assert(offsets.uv >= 0); float result = 0.0f; switch (type) { case UV_SSIM_AREA_UV: - return BM_face_calc_area_uv(face, cd_loop_uv_offset); + return BM_face_calc_area_uv(face, offsets.uv); case UV_SSIM_AREA_3D: return BM_face_calc_area_with_mat3(face, ob_m3); case UV_SSIM_SIDES: @@ -4620,8 +4632,7 @@ static float get_uv_face_needle(const eUVSelectSimilar type, BMLoop *l; BMIter liter; BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (luv->flag & MLOOPUV_PINNED) { + if (BM_ELEM_CD_GET_BOOL(l, offsets.pin)) { result += 1.0f; } } @@ -4638,14 +4649,15 @@ static float get_uv_face_needle(const eUVSelectSimilar type, static float get_uv_island_needle(const eUVSelectSimilar type, const struct FaceIsland *island, const float ob_m3[3][3], - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { + BLI_assert(offsets.uv >= 0); float result = 0.0f; switch (type) { case UV_SSIM_AREA_UV: for (int i = 0; i < island->faces_len; i++) { - result += BM_face_calc_area_uv(island->faces[i], cd_loop_uv_offset); + result += BM_face_calc_area_uv(island->faces[i], offsets.uv); } break; case UV_SSIM_AREA_3D: @@ -4703,7 +4715,7 @@ static int uv_select_similar_vert_exec(bContext *C, wmOperator *op) continue; } - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); float ob_m3[3][3]; copy_m3_m4(ob_m3, ob->object_to_world); @@ -4716,11 +4728,10 @@ static int uv_select_similar_vert_exec(bContext *C, wmOperator *op) BMLoop *l; BMIter liter; BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) { - if (!uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (!uvedit_uv_select_test(scene, l, offsets)) { continue; } - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - float needle = get_uv_vert_needle(type, l->v, ob_m3, luv, cd_loop_uv_offset); + float needle = get_uv_vert_needle(type, l->v, ob_m3, l, offsets); BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle); } } @@ -4740,7 +4751,8 @@ static int uv_select_similar_vert_exec(bContext *C, wmOperator *op) } bool changed = false; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); float ob_m3[3][3]; copy_m3_m4(ob_m3, ob->object_to_world); @@ -4753,14 +4765,13 @@ static int uv_select_similar_vert_exec(bContext *C, wmOperator *op) BMLoop *l; BMIter liter; BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (uvedit_uv_select_test(scene, l, offsets)) { continue; /* Already selected. */ } - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - const float needle = get_uv_vert_needle(type, l->v, ob_m3, luv, cd_loop_uv_offset); + const float needle = get_uv_vert_needle(type, l->v, ob_m3, l, offsets); bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare); if (select) { - uvedit_uv_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset); + uvedit_uv_select_set(scene, em->bm, l, select, false, offsets); changed = true; } } @@ -4816,7 +4827,7 @@ static int uv_select_similar_edge_exec(bContext *C, wmOperator *op) continue; } - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); float ob_m3[3][3]; copy_m3_m4(ob_m3, ob->object_to_world); @@ -4829,13 +4840,11 @@ static int uv_select_similar_edge_exec(bContext *C, wmOperator *op) BMLoop *l; BMIter liter; BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) { - if (!uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) { + if (!uvedit_edge_select_test(scene, l, offsets)) { continue; } - MLoopUV *luv_a = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - MLoopUV *luv_b = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - float needle = get_uv_edge_needle(type, l->e, ob_m3, luv_a, luv_b, cd_loop_uv_offset); + float needle = get_uv_edge_needle(type, l->e, ob_m3, l, l->next, offsets); if (tree_1d) { BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle); } @@ -4857,7 +4866,7 @@ static int uv_select_similar_edge_exec(bContext *C, wmOperator *op) } bool changed = false; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); float ob_m3[3][3]; copy_m3_m4(ob_m3, ob->object_to_world); @@ -4870,16 +4879,14 @@ static int uv_select_similar_edge_exec(bContext *C, wmOperator *op) BMLoop *l; BMIter liter; BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) { - if (uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) { + if (uvedit_edge_select_test(scene, l, offsets)) { continue; /* Already selected. */ } - MLoopUV *luv_a = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - MLoopUV *luv_b = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); - float needle = get_uv_edge_needle(type, l->e, ob_m3, luv_a, luv_b, cd_loop_uv_offset); + float needle = get_uv_edge_needle(type, l->e, ob_m3, l, l->next, offsets); bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare); if (select) { - uvedit_edge_select_set(scene, em->bm, l, select, false, cd_loop_uv_offset); + uvedit_edge_select_set(scene, em->bm, l, select, false, offsets); changed = true; } } @@ -4929,7 +4936,7 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op) float ob_m3[3][3]; copy_m3_m4(ob_m3, ob->object_to_world); - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); BMFace *face; BMIter iter; @@ -4937,11 +4944,11 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op) if (!uvedit_face_visible_test(scene, face)) { continue; } - if (!uvedit_face_select_test(scene, face, cd_loop_uv_offset)) { + if (!uvedit_face_select_test(scene, face, offsets)) { continue; } - float needle = get_uv_face_needle(type, face, ob_m3, cd_loop_uv_offset); + float needle = get_uv_face_needle(type, face, ob_m3, offsets); if (tree_1d) { BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle); } @@ -4960,7 +4967,7 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op) BMesh *bm = em->bm; bool changed = false; bool do_history = false; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); float ob_m3[3][3]; copy_m3_m4(ob_m3, ob->object_to_world); @@ -4971,15 +4978,15 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op) if (!uvedit_face_visible_test(scene, face)) { continue; } - if (uvedit_face_select_test(scene, face, cd_loop_uv_offset)) { + if (uvedit_face_select_test(scene, face, offsets)) { continue; } - float needle = get_uv_face_needle(type, face, ob_m3, cd_loop_uv_offset); + float needle = get_uv_face_needle(type, face, ob_m3, offsets); bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare); if (select) { - uvedit_face_select_set(scene, em->bm, face, select, do_history, cd_loop_uv_offset); + uvedit_face_select_set(scene, bm, face, select, do_history, offsets); changed = true; } } @@ -4996,7 +5003,7 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op) static bool uv_island_selected(const Scene *scene, struct FaceIsland *island) { BLI_assert(island && island->faces_len); - return uvedit_face_select_test(scene, island->faces[0], island->cd_loop_uv_offset); + return uvedit_face_select_test(scene, island->faces[0], island->offsets); } static int uv_select_similar_island_exec(bContext *C, wmOperator *op) @@ -5022,20 +5029,14 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op) for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - if (cd_loop_uv_offset == -1) { + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); + if (offsets.uv == -1) { continue; } float aspect_y = 1.0f; /* Placeholder value, aspect doesn't change connectivity. */ - island_list_len += bm_mesh_calc_uv_islands(scene, - em->bm, - &island_list_ptr[ob_index], - face_selected, - false, - false, - aspect_y, - cd_loop_uv_offset); + island_list_len += bm_mesh_calc_uv_islands( + scene, em->bm, &island_list_ptr[ob_index], face_selected, false, false, aspect_y, offsets); } struct FaceIsland **island_array = MEM_callocN(sizeof(*island_array) * island_list_len, @@ -5047,7 +5048,7 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op) for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); if (cd_loop_uv_offset == -1) { continue; } @@ -5061,7 +5062,7 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op) if (!uv_island_selected(scene, island)) { continue; } - float needle = get_uv_island_needle(type, island, ob_m3, cd_loop_uv_offset); + float needle = get_uv_island_needle(type, island, ob_m3, island->offsets); if (tree_1d) { BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle); } @@ -5077,7 +5078,7 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op) for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); if (cd_loop_uv_offset == -1) { continue; } @@ -5091,7 +5092,7 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op) if (uv_island_selected(scene, island)) { continue; } - float needle = get_uv_island_needle(type, island, ob_m3, cd_loop_uv_offset); + float needle = get_uv_island_needle(type, island, ob_m3, island->offsets); bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare); if (!select) { continue; @@ -5099,7 +5100,7 @@ static int uv_select_similar_island_exec(bContext *C, wmOperator *op) bool do_history = false; for (int j = 0; j < island->faces_len; j++) { uvedit_face_select_set( - scene, em->bm, island->faces[j], select, do_history, island->cd_loop_uv_offset); + scene, em->bm, island->faces[j], select, do_history, island->offsets); } changed = true; } @@ -5231,7 +5232,8 @@ void UV_OT_select_similar(wmOperatorType *ot) BMFace **ED_uvedit_selected_faces(const Scene *scene, BMesh *bm, int len_max, int *r_faces_len) { - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); + CLAMP_MAX(len_max, bm->totface); int faces_len = 0; BMFace **faces = MEM_mallocN(sizeof(*faces) * len_max, __func__); @@ -5240,7 +5242,7 @@ BMFace **ED_uvedit_selected_faces(const Scene *scene, BMesh *bm, int len_max, in BMFace *f; BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { if (uvedit_face_visible_test(scene, f)) { - if (uvedit_face_select_test(scene, f, cd_loop_uv_offset)) { + if (uvedit_face_select_test(scene, f, offsets)) { faces[faces_len++] = f; if (faces_len == len_max) { goto finally; @@ -5259,7 +5261,9 @@ finally: BMLoop **ED_uvedit_selected_edges(const Scene *scene, BMesh *bm, int len_max, int *r_edges_len) { - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); + BLI_assert(offsets.uv >= 0); + CLAMP_MAX(len_max, bm->totloop); int edges_len = 0; BMLoop **edges = MEM_mallocN(sizeof(*edges) * len_max, __func__); @@ -5282,7 +5286,7 @@ BMLoop **ED_uvedit_selected_edges(const Scene *scene, BMesh *bm, int len_max, in BMLoop *l_iter; BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) { if (!BM_elem_flag_test(l_iter, BM_ELEM_TAG)) { - if (uvedit_edge_select_test(scene, l_iter, cd_loop_uv_offset)) { + if (uvedit_edge_select_test(scene, l_iter, offsets)) { BM_elem_flag_enable(l_iter, BM_ELEM_TAG); edges[edges_len++] = l_iter; @@ -5294,7 +5298,7 @@ BMLoop **ED_uvedit_selected_edges(const Scene *scene, BMesh *bm, int len_max, in if (l_iter != l_iter->radial_next) { BMLoop *l_radial_iter = l_iter->radial_next; do { - if (BM_loop_uv_share_edge_check(l_iter, l_radial_iter, cd_loop_uv_offset)) { + if (BM_loop_uv_share_edge_check(l_iter, l_radial_iter, offsets.uv)) { BM_elem_flag_enable(l_radial_iter, BM_ELEM_TAG); } } while ((l_radial_iter = l_radial_iter->radial_next) != l_iter); @@ -5315,7 +5319,10 @@ finally: BMLoop **ED_uvedit_selected_verts(const Scene *scene, BMesh *bm, int len_max, int *r_verts_len) { - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); + BLI_assert(offsets.select_vert >= 0); + BLI_assert(offsets.uv >= 0); + CLAMP_MAX(len_max, bm->totloop); int verts_len = 0; BMLoop **verts = MEM_mallocN(sizeof(*verts) * len_max, __func__); @@ -5338,8 +5345,7 @@ BMLoop **ED_uvedit_selected_verts(const Scene *scene, BMesh *bm, int len_max, in BMLoop *l_iter; BM_ITER_ELEM (l_iter, &liter, f, BM_LOOPS_OF_FACE) { if (!BM_elem_flag_test(l_iter, BM_ELEM_TAG)) { - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset); - if (luv->flag & MLOOPUV_VERTSEL) { + if (BM_ELEM_CD_GET_BOOL(l_iter, offsets.select_vert)) { BM_elem_flag_enable(l_iter->v, BM_ELEM_TAG); verts[verts_len++] = l_iter; @@ -5351,7 +5357,7 @@ BMLoop **ED_uvedit_selected_verts(const Scene *scene, BMesh *bm, int len_max, in BMIter liter_disk; BMLoop *l_disk_iter; BM_ITER_ELEM (l_disk_iter, &liter_disk, l_iter->v, BM_LOOPS_OF_VERT) { - if (BM_loop_uv_share_vert_check(l_iter, l_disk_iter, cd_loop_uv_offset)) { + if (BM_loop_uv_share_vert_check(l_iter, l_disk_iter, offsets.uv)) { BM_elem_flag_enable(l_disk_iter, BM_ELEM_TAG); } } @@ -5381,7 +5387,7 @@ finally: */ static void uv_isolate_selected_islands(const Scene *scene, BMEditMesh *em, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { BLI_assert((scene->toolsettings->uv_flag & UV_SYNC_SELECTION) == 0); BMFace *efa; @@ -5390,6 +5396,8 @@ static void uv_isolate_selected_islands(const Scene *scene, if (elementmap == NULL) { return; } + BLI_assert(offsets.select_vert >= 0); + BLI_assert(offsets.select_edge >= 0); int num_islands = elementmap->total_islands; /* Boolean array that tells if island with index i is completely selected or not. */ @@ -5403,7 +5411,7 @@ static void uv_isolate_selected_islands(const Scene *scene, } BM_elem_flag_enable(efa, BM_ELEM_TAG); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (!uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) { + if (!uvedit_edge_select_test(scene, l, offsets)) { UvElement *element = BM_uv_element_get(elementmap, efa, l); is_island_not_selected[element->island] = true; } @@ -5419,8 +5427,8 @@ static void uv_isolate_selected_islands(const Scene *scene, UvElement *element = BM_uv_element_get(elementmap, efa, l); /* Deselect all elements of islands which are not completely selected. */ if (is_island_not_selected[element->island] == true) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag &= ~(MLOOPUV_VERTSEL | MLOOPUV_EDGESEL); + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); } } } @@ -5435,7 +5443,10 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit) BLI_assert((ts->uv_flag & UV_SYNC_SELECTION) == 0); BMEditMesh *em = BKE_editmesh_from_object(obedit); char sticky = ts->uv_sticky; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BMFace *efa; BMLoop *l; BMIter iter, liter; @@ -5449,7 +5460,7 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit) continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (uvedit_uv_select_test(scene, l, offsets)) { BM_elem_flag_enable(l, BM_ELEM_TAG); } } @@ -5466,8 +5477,8 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit) continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) { - uvedit_edge_select_set_noflush(scene, l, true, sticky, cd_loop_uv_offset); + if (uvedit_edge_select_test(scene, l, offsets)) { + uvedit_edge_select_set_noflush(scene, l, true, sticky, offsets); } } } @@ -5480,10 +5491,10 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit) BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_elem_flag_disable(efa, BM_ELEM_TAG); if (uvedit_face_visible_test(scene, efa)) { - if (uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { + if (uvedit_face_select_test(scene, efa, offsets)) { BM_elem_flag_enable(efa, BM_ELEM_TAG); } - uvedit_face_select_set(scene, em->bm, efa, false, false, cd_loop_uv_offset); + uvedit_face_select_set(scene, em->bm, efa, false, false, offsets); } } uv_select_flush_from_tag_face(scene, obedit, true); @@ -5491,7 +5502,7 @@ void ED_uvedit_selectmode_clean(const Scene *scene, Object *obedit) else if (ts->uv_selectmode == UV_SELECT_ISLAND) { /* Island mode. */ - uv_isolate_selected_islands(scene, em, cd_loop_uv_offset); + uv_isolate_selected_islands(scene, em, offsets); } ED_uvedit_selectmode_flush(scene, em); diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 865262e6947..6be2300cca3 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -322,16 +322,14 @@ static bool stitch_check_uvs_stitchable(UvElement *element, limit = ssc->limit_dist; if (ssc->use_limit) { - MLoopUV *luv, *luv_iter; BMLoop *l; l = element->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + float *luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); l = element_iter->l; - luv_iter = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + float *luv_iter = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); - if (fabsf(luv->uv[0] - luv_iter->uv[0]) < limit && - fabsf(luv->uv[1] - luv_iter->uv[1]) < limit) { + if (fabsf(luv[0] - luv_iter[0]) < limit && fabsf(luv[1] - luv_iter[1]) < limit) { return 1; } return 0; @@ -355,23 +353,19 @@ static bool stitch_check_edges_stitchable(UvEdge *edge, if (ssc->use_limit) { BMLoop *l; - MLoopUV *luv_orig1, *luv_iter1; - MLoopUV *luv_orig2, *luv_iter2; l = state->uvs[edge->uv1]->l; - luv_orig1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + float *luv_orig1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); l = state->uvs[edge_iter->uv1]->l; - luv_iter1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + float *luv_iter1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); l = state->uvs[edge->uv2]->l; - luv_orig2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + float *luv_orig2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); l = state->uvs[edge_iter->uv2]->l; - luv_iter2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + float *luv_iter2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); - if (fabsf(luv_orig1->uv[0] - luv_iter1->uv[0]) < limit && - fabsf(luv_orig1->uv[1] - luv_iter1->uv[1]) < limit && - fabsf(luv_orig2->uv[0] - luv_iter2->uv[0]) < limit && - fabsf(luv_orig2->uv[1] - luv_iter2->uv[1]) < limit) { + if (fabsf(luv_orig1[0] - luv_iter1[0]) < limit && fabsf(luv_orig1[1] - luv_iter1[1]) < limit && + fabsf(luv_orig2[0] - luv_iter2[0]) < limit && fabsf(luv_orig2[1] - luv_iter2[1]) < limit) { return 1; } return 0; @@ -462,18 +456,16 @@ static void stitch_calculate_island_snapping(StitchState *state, for (j = 0; j < numOfIslandUVs; j++, element++) { /* stitchable uvs have already been processed, don't process */ if (!(element->flag & STITCH_PROCESSED)) { - MLoopUV *luv; BMLoop *l; l = element->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + float *luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); if (final) { - stitch_uv_rotate( - rotation_mat, island_stitch_data[i].medianPoint, luv->uv, state->aspect); + stitch_uv_rotate(rotation_mat, island_stitch_data[i].medianPoint, luv, state->aspect); - add_v2_v2(luv->uv, island_stitch_data[i].translation); + add_v2_v2(luv, island_stitch_data[i].translation); } else { @@ -511,13 +503,12 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge, float edgecos, edgesin; int index1, index2; float rotation; - MLoopUV *luv1, *luv2; element1 = state->uvs[edge->uv1]; element2 = state->uvs[edge->uv2]; - luv1 = CustomData_bmesh_get(&bm->ldata, element1->l->head.data, CD_MLOOPUV); - luv2 = CustomData_bmesh_get(&bm->ldata, element2->l->head.data, CD_MLOOPUV); + float *luv1 = CustomData_bmesh_get(&bm->ldata, element1->l->head.data, CD_PROP_FLOAT2); + float *luv2 = CustomData_bmesh_get(&bm->ldata, element2->l->head.data, CD_PROP_FLOAT2); if (ssc->mode == STITCH_VERT) { index1 = uvfinal_map[element1 - state->element_map->storage]; @@ -530,8 +521,8 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge, /* the idea here is to take the directions of the edges and find the rotation between * final and initial direction. This, using inner and outer vector products, * gives the angle. Directions are differences so... */ - uv1[0] = luv2->uv[0] - luv1->uv[0]; - uv1[1] = luv2->uv[1] - luv1->uv[1]; + uv1[0] = luv2[0] - luv1[0]; + uv1[1] = luv2[1] - luv1[1]; uv1[1] /= state->aspect; @@ -901,24 +892,23 @@ static void stitch_propagate_uv_final_position(Scene *scene, BMesh *bm = state->em->bm; StitchPreviewer *preview = state->stitch_preview; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); if (element->flag & STITCH_STITCHABLE) { UvElement *element_iter = element; /* propagate to coincident uvs */ do { BMLoop *l; - MLoopUV *luv; l = element_iter->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + float *luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); element_iter->flag |= STITCH_PROCESSED; /* either flush to preview or to the MTFace, if final */ if (final) { - copy_v2_v2(luv->uv, final_position[index].uv); + copy_v2_v2(luv, final_position[index].uv); - uvedit_uv_select_enable(scene, state->em->bm, l, false, cd_loop_uv_offset); + uvedit_uv_select_enable(scene, state->em->bm, l, false, offsets); } else { int face_preview_pos = @@ -1053,7 +1043,7 @@ static int stitch_process_data(StitchStateContainer *ssc, *********************************************************************/ if (!final) { BMLoop *l; - MLoopUV *luv; + float *luv; int stitchBufferIndex = 0, unstitchBufferIndex = 0; int preview_size = (ssc->mode == STITCH_VERT) ? 2 : 4; /* initialize the preview buffers */ @@ -1074,17 +1064,17 @@ static int stitch_process_data(StitchStateContainer *ssc, UvElement *element = (UvElement *)state->uvs[i]; if (element->flag & STITCH_STITCHABLE) { l = element->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); - copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv->uv); + copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 2], luv); stitchBufferIndex++; } else if (element->flag & STITCH_SELECTED) { l = element->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); - copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv->uv); + copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 2], luv); unstitchBufferIndex++; } } @@ -1097,24 +1087,24 @@ static int stitch_process_data(StitchStateContainer *ssc, if (edge->flag & STITCH_STITCHABLE) { l = element1->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv->uv); + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); + copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4], luv); l = element2->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv->uv); + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); + copy_v2_v2(&preview->preview_stitchable[stitchBufferIndex * 4 + 2], luv); stitchBufferIndex++; BLI_assert(stitchBufferIndex <= preview->num_stitchable); } else if (edge->flag & STITCH_SELECTED) { l = element1->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv->uv); + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); + copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4], luv); l = element2->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv->uv); + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); + copy_v2_v2(&preview->preview_unstitchable[unstitchBufferIndex * 4 + 2], luv); unstitchBufferIndex++; BLI_assert(unstitchBufferIndex <= preview->num_unstitchable); @@ -1152,7 +1142,7 @@ static int stitch_process_data(StitchStateContainer *ssc, if (!final) { BMIter liter; BMLoop *l; - MLoopUV *luv; + float *luv; uint buffer_index = 0; /* initialize the preview buffers */ @@ -1171,7 +1161,7 @@ static int stitch_process_data(StitchStateContainer *ssc, return 0; } - /* copy data from MLoopUVs to the preview display buffers */ + /* copy data from UVs to the preview display buffers */ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { /* just to test if face was added for processing. * uvs of unselected vertices will return NULL */ @@ -1184,27 +1174,27 @@ static int stitch_process_data(StitchStateContainer *ssc, if (face_preview_pos != STITCH_NO_PREVIEW) { preview->uvs_per_polygon[preview_position[index].polycount_position] = efa->len; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - copy_v2_v2(preview->preview_polys + face_preview_pos + i * 2, luv->uv); + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); + copy_v2_v2(preview->preview_polys + face_preview_pos + i * 2, luv); } } /* if this is the static_island on the active object */ if (element->island == ssc->static_island) { BMLoop *fl = BM_FACE_FIRST_LOOP(efa); - MLoopUV *fuv = CustomData_bmesh_get(&bm->ldata, fl->head.data, CD_MLOOPUV); + float *fuv = CustomData_bmesh_get(&bm->ldata, fl->head.data, CD_PROP_FLOAT2); BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { if (i < numoftris) { /* using next since the first uv is already accounted for */ BMLoop *lnext = l->next; - MLoopUV *luvnext = CustomData_bmesh_get( - &bm->ldata, lnext->next->head.data, CD_MLOOPUV); - luv = CustomData_bmesh_get(&bm->ldata, lnext->head.data, CD_MLOOPUV); + float *luvnext = CustomData_bmesh_get( + &bm->ldata, lnext->next->head.data, CD_PROP_FLOAT2); + luv = CustomData_bmesh_get(&bm->ldata, lnext->head.data, CD_PROP_FLOAT2); - memcpy(preview->static_tris + buffer_index, fuv->uv, sizeof(float[2])); - memcpy(preview->static_tris + buffer_index + 2, luv->uv, sizeof(float[2])); - memcpy(preview->static_tris + buffer_index + 4, luvnext->uv, sizeof(float[2])); + memcpy(preview->static_tris + buffer_index, fuv, sizeof(float[2])); + memcpy(preview->static_tris + buffer_index + 2, luv, sizeof(float[2])); + memcpy(preview->static_tris + buffer_index + 4, luvnext, sizeof(float[2])); buffer_index += 6; } else { @@ -1238,14 +1228,14 @@ static int stitch_process_data(StitchStateContainer *ssc, if (element->flag & STITCH_STITCHABLE) { BMLoop *l; - MLoopUV *luv; + float *luv; l = element->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); uvfinal_map[element - state->element_map->storage] = i; - copy_v2_v2(final_position[i].uv, luv->uv); + copy_v2_v2(final_position[i].uv, luv); final_position[i].count = 1; if (ssc->snap_islands && element->island == ssc->static_island && !stitch_midpoints) { @@ -1257,16 +1247,16 @@ static int stitch_process_data(StitchStateContainer *ssc, if (element_iter->separate) { if (stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) { l = element_iter->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); if (stitch_midpoints) { - add_v2_v2(final_position[i].uv, luv->uv); + add_v2_v2(final_position[i].uv, luv); final_position[i].count++; } else if (element_iter->island == ssc->static_island) { /* if multiple uvs on the static island exist, * last checked remains. to disambiguate we need to limit or use * edge stitch */ - copy_v2_v2(final_position[i].uv, luv->uv); + copy_v2_v2(final_position[i].uv, luv); } } } @@ -1281,17 +1271,17 @@ static int stitch_process_data(StitchStateContainer *ssc, UvEdge *edge = state->selection_stack[i]; if (edge->flag & STITCH_STITCHABLE) { - MLoopUV *luv2, *luv1; + float *luv2, *luv1; BMLoop *l; UvEdge *edge_iter; l = state->uvs[edge->uv1]->l; - luv1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + luv1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); l = state->uvs[edge->uv2]->l; - luv2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + luv2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); - copy_v2_v2(final_position[edge->uv1].uv, luv1->uv); - copy_v2_v2(final_position[edge->uv2].uv, luv2->uv); + copy_v2_v2(final_position[edge->uv1].uv, luv1); + copy_v2_v2(final_position[edge->uv2].uv, luv2); final_position[edge->uv1].count = 1; final_position[edge->uv2].count = 1; @@ -1306,19 +1296,19 @@ static int stitch_process_data(StitchStateContainer *ssc, for (edge_iter = edge->first; edge_iter; edge_iter = edge_iter->next) { if (stitch_check_edges_state_stitchable(edge, edge_iter, ssc, state)) { l = state->uvs[edge_iter->uv1]->l; - luv1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + luv1 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); l = state->uvs[edge_iter->uv2]->l; - luv2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + luv2 = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); if (stitch_midpoints) { - add_v2_v2(final_position[edge->uv1].uv, luv1->uv); + add_v2_v2(final_position[edge->uv1].uv, luv1); final_position[edge->uv1].count++; - add_v2_v2(final_position[edge->uv2].uv, luv2->uv); + add_v2_v2(final_position[edge->uv2].uv, luv2); final_position[edge->uv2].count++; } else if (edge_iter->element->island == ssc->static_island) { - copy_v2_v2(final_position[edge->uv1].uv, luv1->uv); - copy_v2_v2(final_position[edge->uv2].uv, luv2->uv); + copy_v2_v2(final_position[edge->uv1].uv, luv1); + copy_v2_v2(final_position[edge->uv2].uv, luv2); } } } @@ -1343,20 +1333,18 @@ static int stitch_process_data(StitchStateContainer *ssc, if (element->flag & STITCH_STITCHABLE) { BMLoop *l; - MLoopUV *luv; + float *luv; l = element->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); /* accumulate each islands' translation from stitchable elements. * It is important to do here because in final pass MTFaces * get modified and result is zero. */ - island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - - luv->uv[0]; - island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - - luv->uv[1]; - island_stitch_data[element->island].medianPoint[0] += luv->uv[0]; - island_stitch_data[element->island].medianPoint[1] += luv->uv[1]; + island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv[0]; + island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv[1]; + island_stitch_data[element->island].medianPoint[0] += luv[0]; + island_stitch_data[element->island].medianPoint[1] += luv[1]; island_stitch_data[element->island].numOfElements++; } } @@ -1398,20 +1386,18 @@ static int stitch_process_data(StitchStateContainer *ssc, if (element->flag & STITCH_STITCHABLE) { BMLoop *l; - MLoopUV *luv; + float *luv; l = element->l; - luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); + luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PROP_FLOAT2); /* accumulate each islands' translation from stitchable elements. * it is important to do here because in final pass MTFaces * get modified and result is zero. */ - island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - - luv->uv[0]; - island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - - luv->uv[1]; - island_stitch_data[element->island].medianPoint[0] += luv->uv[0]; - island_stitch_data[element->island].medianPoint[1] += luv->uv[1]; + island_stitch_data[element->island].translation[0] += final_position[i].uv[0] - luv[0]; + island_stitch_data[element->island].translation[1] += final_position[i].uv[1] - luv[1]; + island_stitch_data[element->island].medianPoint[0] += luv[0]; + island_stitch_data[element->island].medianPoint[1] += luv[1]; island_stitch_data[element->island].numOfElements++; } } @@ -1645,13 +1631,12 @@ static void stitch_switch_selection_mode_all(StitchStateContainer *ssc) static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *normal, float aspect) { BMLoop *l1 = edge->element->l; - MLoopUV *luv1, *luv2; float tangent[2]; - luv1 = CustomData_bmesh_get(&em->bm->ldata, l1->head.data, CD_MLOOPUV); - luv2 = CustomData_bmesh_get(&em->bm->ldata, l1->next->head.data, CD_MLOOPUV); + float *luv1 = CustomData_bmesh_get(&em->bm->ldata, l1->head.data, CD_PROP_FLOAT2); + float *luv2 = CustomData_bmesh_get(&em->bm->ldata, l1->next->head.data, CD_PROP_FLOAT2); - sub_v2_v2v2(tangent, luv2->uv, luv1->uv); + sub_v2_v2v2(tangent, luv2, luv1); tangent[1] /= aspect; @@ -1845,7 +1830,7 @@ static StitchState *stitch_init(bContext *C, float aspx, aspy; BMEditMesh *em = BKE_editmesh_from_object(obedit); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); state = MEM_callocN(sizeof(StitchState), "stitch state obj"); @@ -2076,7 +2061,7 @@ static StitchState *stitch_init(bContext *C, BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (uvedit_uv_select_test(scene, l, offsets)) { UvElement *element = BM_uv_element_get(state->element_map, efa, l); if (element) { stitch_select_uv(element, state, 1); @@ -2097,7 +2082,7 @@ static StitchState *stitch_init(bContext *C, } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_edge_select_test(scene, l, cd_loop_uv_offset)) { + if (uvedit_edge_select_test(scene, l, offsets)) { UvEdge *edge = uv_edge_get(l, state); if (edge) { stitch_select_edge(edge, state, true); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 47c66be0634..15a19fda77e 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -101,9 +101,8 @@ static bool ED_uvedit_ensure_uvs(Object *obedit) BMEditMesh *em = BKE_editmesh_from_object(obedit); BMFace *efa; BMIter iter; - int cd_loop_uv_offset; - if (em && em->bm->totface && !CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV)) { + if (em && em->bm->totface && !CustomData_has_layer(&em->bm->ldata, CD_PROP_FLOAT2)) { ED_mesh_uv_add(obedit->data, NULL, true, true, NULL); } @@ -112,7 +111,10 @@ static bool ED_uvedit_ensure_uvs(Object *obedit) return 0; } - cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const char *active_uv_name = CustomData_get_active_layer_name(&em->bm->ldata, CD_PROP_FLOAT2); + BM_uv_map_ensure_vert_select_attr(em->bm, active_uv_name); + BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); /* select new UV's (ignore UV_SYNC_SELECTION in this case) */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { @@ -120,8 +122,8 @@ static bool ED_uvedit_ensure_uvs(Object *obedit) BMLoop *l; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->flag |= (MLOOPUV_VERTSEL | MLOOPUV_EDGESEL); + BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true); } } @@ -197,9 +199,9 @@ static bool uvedit_have_selection(const Scene *scene, BMEditMesh *em, const Unwr BMFace *efa; BMLoop *l; BMIter iter, liter; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); - if (cd_loop_uv_offset == -1) { + if (offsets.uv == -1) { return (em->bm->totfacesel != 0); } @@ -216,7 +218,7 @@ static bool uvedit_have_selection(const Scene *scene, BMEditMesh *em, const Unwr } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (uvedit_uv_select_test(scene, l, offsets)) { break; } } @@ -282,7 +284,7 @@ void ED_uvedit_get_aspect(Object *ob, float *r_aspx, float *r_aspy) static bool uvedit_is_face_affected(const Scene *scene, BMFace *efa, const UnwrapOptions *options, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { return false; @@ -296,7 +298,7 @@ static bool uvedit_is_face_affected(const Scene *scene, BMLoop *l; BMIter iter; BM_ITER_ELEM (l, &iter, efa, BM_LOOPS_OF_FACE) { - if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + if (uvedit_uv_select_test(scene, l, offsets)) { return true; } } @@ -312,19 +314,19 @@ static void uvedit_prepare_pinned_indices(ParamHandle *handle, const Scene *scene, BMFace *efa, const UnwrapOptions *options, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { BMIter liter; BMLoop *l; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - bool pin = luv->flag & MLOOPUV_PINNED; + bool pin = BM_ELEM_CD_GET_BOOL(l, offsets.pin); if (options->pin_unselected && !pin) { - pin = !uvedit_uv_select_test(scene, l, cd_loop_uv_offset); + pin = !uvedit_uv_select_test(scene, l, offsets); } if (pin) { int bmvertindex = BM_elem_index_get(l->v); - GEO_uv_prepare_pin_index(handle, bmvertindex, luv->uv); + const float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + GEO_uv_prepare_pin_index(handle, bmvertindex, luv); } } } @@ -334,7 +336,7 @@ static void construct_param_handle_face_add(ParamHandle *handle, BMFace *efa, ParamKey face_index, const UnwrapOptions *options, - const int cd_loop_uv_offset) + const BMUVOffsets offsets) { ParamKey *vkeys = BLI_array_alloca(vkeys, efa->len); bool *pin = BLI_array_alloca(pin, efa->len); @@ -349,13 +351,13 @@ static void construct_param_handle_face_add(ParamHandle *handle, /* let parametrizer split the ngon, it can make better decisions * about which split is best for unwrapping than poly-fill. */ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); - vkeys[i] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->v), luv->uv); + vkeys[i] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->v), luv); co[i] = l->v->co; - uv[i] = luv->uv; - pin[i] = (luv->flag & MLOOPUV_PINNED) != 0; - select[i] = uvedit_uv_select_test(scene, l, cd_loop_uv_offset); + uv[i] = luv; + pin[i] = BM_ELEM_CD_GET_BOOL(l, offsets.pin); + select[i] = uvedit_uv_select_test(scene, l, offsets); if (options->pin_unselected && !select[i]) { pin[i] = true; } @@ -373,8 +375,8 @@ static void construct_param_edge_set_seams(ParamHandle *handle, return; /* Seams are not required with these options. */ } - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - if (cd_loop_uv_offset == -1) { + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); + if (offsets.uv == -1) { return; /* UVs aren't present on BMesh. Nothing to do. */ } @@ -391,11 +393,11 @@ static void construct_param_edge_set_seams(ParamHandle *handle, BMLoop *l; BMIter liter; BM_ITER_ELEM (l, &liter, edge, BM_LOOPS_OF_EDGE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l->next, offsets.uv); ParamKey vkeys[2]; - vkeys[0] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->v), luv->uv); - vkeys[1] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->next->v), luv_next->uv); + vkeys[0] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->v), luv); + vkeys[1] = GEO_uv_find_pin_index(handle, BM_elem_index_get(l->next->v), luv_next); /* Set the seam. */ GEO_uv_parametrizer_edge_set_seam(handle, vkeys); @@ -431,16 +433,16 @@ static ParamHandle *construct_param_handle(const Scene *scene, /* we need the vert indices */ BM_mesh_elem_index_ensure(bm, BM_VERT); - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { - if (uvedit_is_face_affected(scene, efa, options, cd_loop_uv_offset)) { - uvedit_prepare_pinned_indices(handle, scene, efa, options, cd_loop_uv_offset); + if (uvedit_is_face_affected(scene, efa, options, offsets)) { + uvedit_prepare_pinned_indices(handle, scene, efa, options, offsets); } } BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { - if (uvedit_is_face_affected(scene, efa, options, cd_loop_uv_offset)) { - construct_param_handle_face_add(handle, scene, efa, i, options, cd_loop_uv_offset); + if (uvedit_is_face_affected(scene, efa, options, offsets)) { + construct_param_handle_face_add(handle, scene, efa, i, options, offsets); } } @@ -488,22 +490,21 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene, BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); - if (cd_loop_uv_offset == -1) { + if (offsets.uv == -1) { continue; } BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { - if (uvedit_is_face_affected(scene, efa, options, cd_loop_uv_offset)) { - uvedit_prepare_pinned_indices(handle, scene, efa, options, cd_loop_uv_offset); + if (uvedit_is_face_affected(scene, efa, options, offsets)) { + uvedit_prepare_pinned_indices(handle, scene, efa, options, offsets); } } BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) { - if (uvedit_is_face_affected(scene, efa, options, cd_loop_uv_offset)) { - construct_param_handle_face_add( - handle, scene, efa, i + offset, options, cd_loop_uv_offset); + if (uvedit_is_face_affected(scene, efa, options, offsets)) { + construct_param_handle_face_add(handle, scene, efa, i + offset, options, offsets); } } @@ -518,7 +519,7 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene, } static void texface_from_original_index(const Scene *scene, - const int cd_loop_uv_offset, + const BMUVOffsets offsets, BMFace *efa, int index, float **r_uv, @@ -527,7 +528,6 @@ static void texface_from_original_index(const Scene *scene, { BMLoop *l; BMIter liter; - MLoopUV *luv; *r_uv = NULL; *r_pin = 0; @@ -539,10 +539,10 @@ static void texface_from_original_index(const Scene *scene, BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (BM_elem_index_get(l->v) == index) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - *r_uv = luv->uv; - *r_pin = (luv->flag & MLOOPUV_PINNED) ? 1 : 0; - *r_select = uvedit_uv_select_test(scene, l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + *r_uv = luv; + *r_pin = BM_ELEM_CD_GET_BOOL(l, offsets.pin); + *r_select = uvedit_uv_select_test(scene, l, offsets); break; } } @@ -594,7 +594,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, /* similar to the above, we need a way to map edges to their original ones */ BMEdge **edgeMap; - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); ParamHandle *handle = GEO_uv_parametrizer_construct_begin(); @@ -687,34 +687,14 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, /* This is where all the magic is done. * If the vertex exists in the, we pass the original uv pointer to the solver, thus * flushing the solution to the edit mesh. */ - texface_from_original_index(scene, - cd_loop_uv_offset, - origFace, - origVertIndices[mloop[0].v], - &uv[0], - &pin[0], - &select[0]); - texface_from_original_index(scene, - cd_loop_uv_offset, - origFace, - origVertIndices[mloop[1].v], - &uv[1], - &pin[1], - &select[1]); - texface_from_original_index(scene, - cd_loop_uv_offset, - origFace, - origVertIndices[mloop[2].v], - &uv[2], - &pin[2], - &select[2]); - texface_from_original_index(scene, - cd_loop_uv_offset, - origFace, - origVertIndices[mloop[3].v], - &uv[3], - &pin[3], - &select[3]); + texface_from_original_index( + scene, offsets, origFace, origVertIndices[mloop[0].v], &uv[0], &pin[0], &select[0]); + texface_from_original_index( + scene, offsets, origFace, origVertIndices[mloop[1].v], &uv[1], &pin[1], &select[1]); + texface_from_original_index( + scene, offsets, origFace, origVertIndices[mloop[2].v], &uv[2], &pin[2], &select[2]); + texface_from_original_index( + scene, offsets, origFace, origVertIndices[mloop[3].v], &uv[3], &pin[3], &select[3]); GEO_uv_parametrizer_face_add(handle, key, 4, vkeys, co, uv, pin, select); } @@ -1553,21 +1533,21 @@ static void shrink_loop_uv_by_aspect_ratio(BMFace *efa, BMLoop *l; BMIter iter; BM_ITER_ELEM (l, &iter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); if (aspect_y > 1.0f) { /* Reduce round-off error, i.e. `u = (u - 0.5) / aspect_y + 0.5`. */ - luv->uv[0] = luv->uv[0] / aspect_y + (0.5f - 0.5f / aspect_y); + luv[0] = luv[0] / aspect_y + (0.5f - 0.5f / aspect_y); } else { /* Reduce round-off error, i.e. `v = (v - 0.5) * aspect_y + 0.5`. */ - luv->uv[1] = luv->uv[1] * aspect_y + (0.5f - 0.5f * aspect_y); + luv[1] = luv[1] * aspect_y + (0.5f - 0.5f * aspect_y); } } } static void correct_uv_aspect(Object *ob, BMEditMesh *em) { - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); float aspx, aspy; ED_uvedit_get_aspect(ob, &aspx, &aspy); const float aspect_y = aspx / aspy; @@ -1596,7 +1576,7 @@ static void correct_uv_aspect_per_face(Object *ob, BMEditMesh *em) /* Lazily initialize aspect ratio for materials. */ copy_vn_fl(material_aspect_y, materials_num, -1.0f); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); BMFace *efa; BMIter iter; @@ -1685,7 +1665,6 @@ static void uv_map_clip_correct(const Scene *scene, BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; float dx, dy, min[2], max[2]; const bool correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"); const bool clip_to_bounds = (RNA_struct_find_property(op->ptr, "clip_to_bounds") && @@ -1698,7 +1677,7 @@ static void uv_map_clip_correct(const Scene *scene, Object *ob = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(ob); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); /* Correct for image aspect ratio. */ if (correct_aspect) { @@ -1717,13 +1696,13 @@ static void uv_map_clip_correct(const Scene *scene, continue; } - if (only_selected_uvs && !uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { + if (only_selected_uvs && !uvedit_face_select_test(scene, efa, offsets)) { continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - minmax_v2v2_v2(min, max, luv->uv); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + minmax_v2v2_v2(min, max, luv); } } } @@ -1734,13 +1713,13 @@ static void uv_map_clip_correct(const Scene *scene, continue; } - if (only_selected_uvs && !uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { + if (only_selected_uvs && !uvedit_face_select_test(scene, efa, offsets)) { continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - clamp_v2(luv->uv, 0.0f, 1.0f); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + clamp_v2(luv, 0.0f, 1.0f); } } } @@ -1767,22 +1746,22 @@ static void uv_map_clip_correct(const Scene *scene, Object *ob = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(ob); - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_SELECT)) { continue; } - if (only_selected_uvs && !uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { + if (only_selected_uvs && !uvedit_face_select_test(scene, efa, offsets)) { continue; } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); - luv->uv[0] = (luv->uv[0] - min[0]) * dx; - luv->uv[1] = (luv->uv[1] - min[1]) * dy; + luv[0] = (luv[0] - min[0]) * dx; + luv[1] = (luv[1] - min[1]) * dy; } } } @@ -1802,7 +1781,7 @@ static void uvedit_unwrap(const Scene *scene, UnwrapResultInfo *result_info) { BMEditMesh *em = BKE_editmesh_from_object(obedit); - if (!CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV)) { + if (!CustomData_has_layer(&em->bm->ldata, CD_PROP_FLOAT2)) { return; } @@ -2274,8 +2253,8 @@ static int smart_project_exec(bContext *C, wmOperator *op) continue; } - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - BLI_assert(cd_loop_uv_offset >= 0); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); + BLI_assert(offsets.uv >= 0); ThickFace *thick_faces = MEM_mallocN(sizeof(*thick_faces) * em->bm->totface, __func__); uint thick_faces_len = 0; @@ -2285,8 +2264,8 @@ static int smart_project_exec(bContext *C, wmOperator *op) } if (only_selected_uvs) { - if (!uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { - uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset); + if (!uvedit_face_select_test(scene, efa, offsets)) { + uvedit_face_select_disable(scene, em->bm, efa, offsets); continue; } } @@ -2306,8 +2285,8 @@ static int smart_project_exec(bContext *C, wmOperator *op) BMIter liter; BMLoop *l; BM_ITER_ELEM (l, &liter, thick_faces[thick_faces_len - 1].efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - zero_v2(luv->uv); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + zero_v2(luv); changed = true; } @@ -2367,8 +2346,8 @@ static int smart_project_exec(bContext *C, wmOperator *op) BMIter liter; BMLoop *l; BM_ITER_ELEM (l, &liter, tf->efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - mul_v2_m3v3(luv->uv, axis_mat, l->v->co); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + mul_v2_m3v3(luv, axis_mat, l->v->co); } changed = true; } @@ -2515,7 +2494,6 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; float rotmat[4][4]; float objects_pos_offset[4]; bool changed_multi = false; @@ -2549,7 +2527,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) continue; } - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); if (use_orthographic) { uv_map_rotation_matrix_ex(rotmat, rv3d, obedit, 90.0f, 0.0f, 1.0f, objects_pos_offset); @@ -2560,8 +2538,8 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - BLI_uvproject_from_view_ortho(luv->uv, l->v->co, rotmat); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + BLI_uvproject_from_view_ortho(luv, l->v->co, rotmat); } changed = true; } @@ -2581,8 +2559,8 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - BLI_uvproject_from_camera(luv->uv, l->v->co, uci); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + BLI_uvproject_from_camera(luv, l->v->co, uci); } changed = true; } @@ -2599,9 +2577,9 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); BLI_uvproject_from_view( - luv->uv, l->v->co, rv3d->persmat, rotmat, region->winx, region->winy); + luv, l->v->co, rv3d->persmat, rotmat, region->winx, region->winy); } changed = true; } @@ -2751,27 +2729,27 @@ static void uv_map_mirror(BMFace *efa, float **uvs = BLI_array_alloca(uvs, efa->len); int j; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - uvs[j] = luv->uv; - if (luv->uv[0] >= 1.0f) { - luv->uv[0] -= 1.0f; + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + uvs[j] = luv; + if (luv[0] >= 1.0f) { + luv[0] -= 1.0f; } - right_u = max_ff(right_u, luv->uv[0]); + right_u = max_ff(right_u, luv[0]); } float left_u = 1.0e30f; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (right_u <= luv->uv[0] + 0.5f) { - left_u = min_ff(left_u, luv->uv[0]); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + if (right_u <= luv[0] + 0.5f) { + left_u = min_ff(left_u, luv[0]); } } BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - if (luv->uv[0] + 0.5f < right_u) { - if (2 * luv->uv[0] + 1.0f < left_u + right_u) { - luv->uv[0] += 1.0f; + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); + if (luv[0] + 0.5f < right_u) { + if (2 * luv[0] + 1.0f < left_u + right_u) { + luv[0] += 1.0f; } } } @@ -2833,11 +2811,11 @@ static void uv_sphere_project(BMFace *efa, BMLoop *l; BMIter iter; BM_ITER_ELEM_INDEX (l, &iter, efa, BM_LOOPS_OF_FACE, i) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); float pv[3]; sub_v3_v3v3(pv, l->v->co, center); mul_m3_v3(rotmat, pv); - regular[i] = map_to_sphere(&luv->uv[0], &luv->uv[1], pv[0], pv[1], pv[2]); + regular[i] = map_to_sphere(&luv[0], &luv[1], pv[0], pv[1], pv[2]); } uv_map_mirror(efa, regular, fan, cd_loop_uv_offset); @@ -2873,7 +2851,7 @@ static int sphere_project_exec(bContext *C, wmOperator *op) continue; } - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); float center[3], rotmat[3][3]; uv_map_transform(C, op, rotmat); @@ -2887,13 +2865,13 @@ static int sphere_project_exec(bContext *C, wmOperator *op) } if (only_selected_uvs) { - if (!uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { - uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset); + if (!uvedit_face_select_test(scene, efa, offsets)) { + uvedit_face_select_disable(scene, em->bm, efa, offsets); continue; } } - uv_sphere_project(efa, center, rotmat, fan, cd_loop_uv_offset); + uv_sphere_project(efa, center, rotmat, fan, offsets.uv); } const bool per_face_aspect = true; @@ -2942,11 +2920,11 @@ static void uv_cylinder_project(BMFace *efa, BMLoop *l; BMIter iter; BM_ITER_ELEM_INDEX (l, &iter, efa, BM_LOOPS_OF_FACE, i) { - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); float pv[3]; sub_v3_v3v3(pv, l->v->co, center); mul_m3_v3(rotmat, pv); - regular[i] = map_to_tube(&luv->uv[0], &luv->uv[1], pv[0], pv[1], pv[2]); + regular[i] = map_to_tube(&luv[0], &luv[1], pv[0], pv[1], pv[2]); } uv_map_mirror(efa, regular, fan, cd_loop_uv_offset); @@ -2982,7 +2960,7 @@ static int cylinder_project_exec(bContext *C, wmOperator *op) continue; } - const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); float center[3], rotmat[3][3]; uv_map_transform(C, op, rotmat); @@ -2995,12 +2973,12 @@ static int cylinder_project_exec(bContext *C, wmOperator *op) continue; } - if (only_selected_uvs && !uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { - uvedit_face_select_disable(scene, em->bm, efa, cd_loop_uv_offset); + if (only_selected_uvs && !uvedit_face_select_test(scene, efa, offsets)) { + uvedit_face_select_disable(scene, em->bm, efa, offsets); continue; } - uv_cylinder_project(efa, center, rotmat, fan, cd_loop_uv_offset); + uv_cylinder_project(efa, center, rotmat, fan, offsets.uv); } const bool per_face_aspect = true; @@ -3048,13 +3026,10 @@ static void uvedit_unwrap_cube_project(const Scene *scene, BMFace *efa; BMLoop *l; BMIter iter, liter; - MLoopUV *luv; float loc[3]; int cox, coy; - int cd_loop_uv_offset; - - cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); if (center) { copy_v3_v3(loc, center); @@ -3074,17 +3049,17 @@ static void uvedit_unwrap_cube_project(const Scene *scene, if (use_select && !BM_elem_flag_test(efa, BM_ELEM_SELECT)) { continue; } - if (only_selected_uvs && !uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) { - uvedit_face_select_disable(scene, bm, efa, cd_loop_uv_offset); + if (only_selected_uvs && !uvedit_face_select_test(scene, efa, offsets)) { + uvedit_face_select_disable(scene, bm, efa, offsets); continue; } axis_dominant_v3(&cox, &coy, efa->no); BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - luv->uv[0] = 0.5f + ((l->v->co[cox] - loc[cox]) / cube_size); - luv->uv[1] = 0.5f + ((l->v->co[coy] - loc[coy]) / cube_size); + float *luv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); + luv[0] = 0.5f + ((l->v->co[cox] - loc[cox]) / cube_size); + luv[1] = 0.5f + ((l->v->co[coy] - loc[coy]) / cube_size); } } } diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index ea47359aa2a..a04e9584005 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -44,6 +44,7 @@ #include "BLI_ghash.h" #include "BLI_listbase.h" #include "BLI_math_color.h" +#include "BLI_math_vector_types.hh" #include "BLI_math_vector.h" #include "BLI_utildefines.h" @@ -590,18 +591,18 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex) &mesh->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, mesh->totloop); int *material_indices = (int *)CustomData_add_layer_named( &mesh->pdata, CD_PROP_INT32, CD_SET_DEFAULT, nullptr, mesh->totpoly, "material_index"); - MLoopUV *loopsuv[2] = {nullptr}; + blender::float2 *loopsuv[2] = {nullptr}; if (hasTex) { // First UV layer - loopsuv[0] = static_cast(CustomData_add_layer_named( - &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, uvNames[0])); - CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 0); + loopsuv[0] = static_cast(CustomData_add_layer_named( + &mesh->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, mesh->totloop, uvNames[0])); + CustomData_set_layer_active(&mesh->ldata, CD_PROP_FLOAT2, 0); // Second UV layer - loopsuv[1] = static_cast(CustomData_add_layer_named( - &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, uvNames[1])); - CustomData_set_layer_active(&mesh->ldata, CD_MLOOPUV, 1); + loopsuv[1] = static_cast(CustomData_add_layer_named( + &mesh->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, mesh->totloop, uvNames[1])); + CustomData_set_layer_active(&mesh->ldata, CD_PROP_FLOAT2, 1); } // colors and transparency (the latter represented by grayscale colors) @@ -745,24 +746,24 @@ void BlenderStrokeRenderer::GenerateStrokeMesh(StrokeGroup *group, bool hasTex) // Second UV layer (loopsuv[1]) has tips: (texCoord(1)). for (int L = 0; L < 2; L++) { if (is_odd) { - loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x(); - loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y(); + loopsuv[L][0][0] = svRep[2]->texCoord(L).x(); + loopsuv[L][0][1] = svRep[2]->texCoord(L).y(); - loopsuv[L][1].uv[0] = svRep[0]->texCoord(L).x(); - loopsuv[L][1].uv[1] = svRep[0]->texCoord(L).y(); + loopsuv[L][1][0] = svRep[0]->texCoord(L).x(); + loopsuv[L][1][1] = svRep[0]->texCoord(L).y(); - loopsuv[L][2].uv[0] = svRep[1]->texCoord(L).x(); - loopsuv[L][2].uv[1] = svRep[1]->texCoord(L).y(); + loopsuv[L][2][0] = svRep[1]->texCoord(L).x(); + loopsuv[L][2][1] = svRep[1]->texCoord(L).y(); } else { - loopsuv[L][0].uv[0] = svRep[2]->texCoord(L).x(); - loopsuv[L][0].uv[1] = svRep[2]->texCoord(L).y(); + loopsuv[L][0][0] = svRep[2]->texCoord(L).x(); + loopsuv[L][0][1] = svRep[2]->texCoord(L).y(); - loopsuv[L][1].uv[0] = svRep[1]->texCoord(L).x(); - loopsuv[L][1].uv[1] = svRep[1]->texCoord(L).y(); + loopsuv[L][1][0] = svRep[1]->texCoord(L).x(); + loopsuv[L][1][1] = svRep[1]->texCoord(L).y(); - loopsuv[L][2].uv[0] = svRep[0]->texCoord(L).x(); - loopsuv[L][2].uv[1] = svRep[0]->texCoord(L).y(); + loopsuv[L][2][0] = svRep[0]->texCoord(L).x(); + loopsuv[L][2][1] = svRep[0]->texCoord(L).y(); } loopsuv[L] += 3; } diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 3dad2a1a19a..f9bae39b016 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -301,7 +301,7 @@ void GPU_pass_cache_free(void); typedef struct GPUMaterialAttribute { struct GPUMaterialAttribute *next, *prev; int type; /* eCustomDataType */ - char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ + char name[68]; /* MAX_CUSTOMDATA_LAYER_NAME */ char input_name[12 + 1]; /* GPU_MAX_SAFE_ATTR_NAME + 1 */ eGPUType gputype; eGPUDefaultValue default_value; /* Only for volumes attributes. */ @@ -335,8 +335,8 @@ typedef struct GPUUniformAttr { struct GPUUniformAttr *next, *prev; /* Meaningful part of the attribute set key. */ - char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ - /** Hash of name[64] + use_dupli. */ + char name[68]; /* MAX_CUSTOMDATA_LAYER_NAME */ + /** Hash of name[68] + use_dupli. */ uint32_t hash_code; bool use_dupli; @@ -362,8 +362,8 @@ typedef struct GPULayerAttr { struct GPULayerAttr *next, *prev; /* Meaningful part of the attribute set key. */ - char name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ - /** Hash of name[64]. */ + char name[68]; /* MAX_CUSTOMDATA_LAYER_NAME */ + /** Hash of name[68]. */ uint32_t hash_code; /* Helper fields used by code generation. */ diff --git a/source/blender/gpu/intern/gpu_vertex_format.cc b/source/blender/gpu/intern/gpu_vertex_format.cc index 76d95ac1b55..fb480326def 100644 --- a/source/blender/gpu/intern/gpu_vertex_format.cc +++ b/source/blender/gpu/intern/gpu_vertex_format.cc @@ -199,7 +199,7 @@ void GPU_vertformat_multiload_enable(GPUVertFormat *format, int load_count) for (int i = 0; i < attr_len; i++, attr++) { const char *attr_name = GPU_vertformat_attr_name_get(format, attr, 0); for (int j = 1; j < load_count; j++) { - char load_name[64]; + char load_name[68 /* MAX_CUSTOMDATA_LAYER_NAME */]; BLI_snprintf(load_name, sizeof(load_name), "%s%d", attr_name, j); GPUVertAttr *dst_attr = &format->attrs[format->attr_len++]; *dst_attr = *attr; diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc index cc45764793a..dfe744a1197 100644 --- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc +++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc @@ -240,8 +240,10 @@ void ABCGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh) mesh_sample.setUVs(uv_sample); } - write_custom_data( - abc_poly_mesh_schema_.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV); + write_custom_data(abc_poly_mesh_schema_.getArbGeomParams(), + m_custom_data_config, + &mesh->ldata, + CD_PROP_FLOAT2); } if (args_.export_params->normals) { @@ -307,7 +309,7 @@ void ABCGenericMeshWriter::write_subd(HierarchyContext &context, struct Mesh *me } write_custom_data( - abc_subdiv_schema_.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_MLOOPUV); + abc_subdiv_schema_.getArbGeomParams(), m_custom_data_config, &mesh->ldata, CD_PROP_FLOAT2); } if (args_.export_params->orcos) { diff --git a/source/blender/io/alembic/intern/abc_customdata.cc b/source/blender/io/alembic/intern/abc_customdata.cc index 81ac0f9fd52..035f49325c4 100644 --- a/source/blender/io/alembic/intern/abc_customdata.cc +++ b/source/blender/io/alembic/intern/abc_customdata.cc @@ -50,7 +50,7 @@ static void get_uvs(const CDStreamConfig &config, std::vector &uvidx, const void *cd_data) { - const MLoopUV *mloopuv_array = static_cast(cd_data); + const float2 *mloopuv_array = static_cast(cd_data); if (!mloopuv_array) { return; @@ -68,14 +68,14 @@ static void get_uvs(const CDStreamConfig &config, /* Iterate in reverse order to match exported polygons. */ for (int i = 0; i < num_poly; i++) { MPoly ¤t_poly = mpoly[i]; - const MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop; + const float2 *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop; for (int j = 0; j < current_poly.totloop; j++, count++) { loopuv--; uvidx[count] = count; - uvs[count][0] = loopuv->uv[0]; - uvs[count][1] = loopuv->uv[1]; + uvs[count][0] = (*loopuv)[0]; + uvs[count][1] = (*loopuv)[1]; } } } @@ -87,13 +87,13 @@ static void get_uvs(const CDStreamConfig &config, for (int i = 0; i < num_poly; i++) { MPoly ¤t_poly = mpoly[i]; MLoop *looppoly = mloop + current_poly.loopstart + current_poly.totloop; - const MLoopUV *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop; + const float2 *loopuv = mloopuv_array + current_poly.loopstart + current_poly.totloop; for (int j = 0; j < current_poly.totloop; j++) { looppoly--; loopuv--; - Imath::V2f uv(loopuv->uv[0], loopuv->uv[1]); + Imath::V2f uv((*loopuv)[0], (*loopuv)[1]); bool found_same = false; /* Find UV already in uvs array. */ @@ -119,17 +119,17 @@ static void get_uvs(const CDStreamConfig &config, const char *get_uv_sample(UVSample &sample, const CDStreamConfig &config, CustomData *data) { - const int active_uvlayer = CustomData_get_active_layer(data, CD_MLOOPUV); + const int active_uvlayer = CustomData_get_active_layer(data, CD_PROP_FLOAT2); if (active_uvlayer < 0) { return ""; } - const void *cd_data = CustomData_get_layer_n(data, CD_MLOOPUV, active_uvlayer); + const void *cd_data = CustomData_get_layer_n(data, CD_PROP_FLOAT2, active_uvlayer); get_uvs(config, sample.uvs, sample.indices, cd_data); - return CustomData_get_layer_name(data, CD_MLOOPUV, active_uvlayer); + return CustomData_get_layer_name(data, CD_PROP_FLOAT2, active_uvlayer); } /* Convention to write UVs: @@ -283,7 +283,7 @@ void write_custom_data(const OCompoundProperty &prop, const void *cd_data = CustomData_get_layer_n(data, cd_data_type, i); const char *name = CustomData_get_layer_name(data, cd_data_type, i); - if (cd_data_type == CD_MLOOPUV) { + if (cd_data_type == CD_PROP_FLOAT2) { /* Already exported. */ if (i == active_layer) { continue; @@ -317,7 +317,7 @@ static void read_uvs(const CDStreamConfig &config, { MPoly *mpolys = config.mpoly; MLoop *mloops = config.mloop; - MLoopUV *mloopuvs = static_cast(data); + float2 *mloopuvs = static_cast(data); uint uv_index, loop_index, rev_loop_index; @@ -334,9 +334,9 @@ static void read_uvs(const CDStreamConfig &config, uv_index = (*indices)[loop_index]; const Imath::V2f &uv = (*uvs)[uv_index]; - MLoopUV &loopuv = mloopuvs[rev_loop_index]; - loopuv.uv[0] = uv[0]; - loopuv.uv[1] = uv[1]; + float2 &loopuv = mloopuvs[rev_loop_index]; + loopuv[0] = uv[0]; + loopuv[1] = uv[1]; } } } @@ -497,7 +497,8 @@ static void read_custom_data_uvs(const ICompoundProperty &prop, return; } - void *cd_data = config.add_customdata_cb(config.mesh, prop_header.getName().c_str(), CD_MLOOPUV); + void *cd_data = config.add_customdata_cb( + config.mesh, prop_header.getName().c_str(), CD_PROP_FLOAT2); read_uvs(config, cd_data, uv_scope, sample.getVals(), uvs_indices); } diff --git a/source/blender/io/alembic/intern/abc_customdata.h b/source/blender/io/alembic/intern/abc_customdata.h index 41fd4327a2f..a2e257e2285 100644 --- a/source/blender/io/alembic/intern/abc_customdata.h +++ b/source/blender/io/alembic/intern/abc_customdata.h @@ -13,9 +13,10 @@ #include +#include "BLI_math_vector_types.hh" + struct CustomData; struct MLoop; -struct MLoopUV; struct MPoly; struct Mesh; @@ -38,7 +39,7 @@ struct CDStreamConfig { float3 *positions; int totvert; - MLoopUV *mloopuv; + float2 *mloopuv; CustomData *loopdata; diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc index 2a228385372..53204fc3e47 100644 --- a/source/blender/io/alembic/intern/abc_reader_mesh.cc +++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc @@ -177,7 +177,7 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data) { MPoly *mpolys = config.mpoly; MLoop *mloops = config.mloop; - MLoopUV *mloopuvs = config.mloopuv; + float2 *mloopuvs = config.mloopuv; const Int32ArraySamplePtr &face_indices = mesh_data.face_indices; const Int32ArraySamplePtr &face_counts = mesh_data.face_counts; @@ -221,7 +221,6 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data) last_vertex_index = loop.v; if (do_uvs) { - MLoopUV &loopuv = mloopuvs[rev_loop_index]; uv_index = (*uvs_indices)[do_uvs_per_loop ? loop_index : loop.v]; /* Some Alembic files are broken (or at least export UVs in a way we don't expect). */ @@ -229,8 +228,8 @@ static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data) continue; } - loopuv.uv[0] = (*uvs)[uv_index][0]; - loopuv.uv[1] = (*uvs)[uv_index][1]; + mloopuvs[rev_loop_index][0] = (*uvs)[uv_index][0]; + mloopuvs[rev_loop_index][1] = (*uvs)[uv_index][1]; } } } @@ -371,8 +370,8 @@ BLI_INLINE void read_uvs_params(CDStreamConfig &config, name = uv.getName(); } - void *cd_ptr = config.add_customdata_cb(config.mesh, name.c_str(), CD_MLOOPUV); - config.mloopuv = static_cast(cd_ptr); + void *cd_ptr = config.add_customdata_cb(config.mesh, name.c_str(), CD_PROP_FLOAT2); + config.mloopuv = static_cast(cd_ptr); } static void *add_customdata_cb(Mesh *mesh, const char *name, int data_type) @@ -380,7 +379,7 @@ static void *add_customdata_cb(Mesh *mesh, const char *name, int data_type) eCustomDataType cd_data_type = static_cast(data_type); /* unsupported custom data type -- don't do anything. */ - if (!ELEM(cd_data_type, CD_MLOOPUV, CD_PROP_BYTE_COLOR)) { + if (!ELEM(cd_data_type, CD_PROP_FLOAT2, CD_PROP_BYTE_COLOR)) { return nullptr; } diff --git a/source/blender/io/collada/EffectExporter.cpp b/source/blender/io/collada/EffectExporter.cpp index e8a715633e1..d53f8c0997c 100644 --- a/source/blender/io/collada/EffectExporter.cpp +++ b/source/blender/io/collada/EffectExporter.cpp @@ -29,9 +29,9 @@ static std::string getActiveUVLayerName(Object *ob) { Mesh *me = (Mesh *)ob->data; - int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); + int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); if (num_layers) { - return std::string(bc_CustomData_get_active_layer_name(&me->ldata, CD_MLOOPUV)); + return std::string(bc_CustomData_get_active_layer_name(&me->ldata, CD_PROP_FLOAT2)); } return ""; diff --git a/source/blender/io/collada/GeometryExporter.cpp b/source/blender/io/collada/GeometryExporter.cpp index 862f4b95cef..64cefb168c8 100644 --- a/source/blender/io/collada/GeometryExporter.cpp +++ b/source/blender/io/collada/GeometryExporter.cpp @@ -15,6 +15,7 @@ #include "DNA_meshdata_types.h" +#include "BLI_math_vector_types.hh" #include "BLI_utildefines.h" #include "BKE_attribute.hh" @@ -78,7 +79,7 @@ void GeometryExporter::operator()(Object *ob) /* writes for normal coords */ createNormalsSource(geom_id, me, nor); - bool has_uvs = bool(CustomData_has_layer(&me->ldata, CD_MLOOPUV)); + bool has_uvs = bool(CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2)); /* writes for uv coords if mesh has uv coords */ if (has_uvs) { @@ -162,7 +163,7 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb) /* writes for normal coords */ createNormalsSource(geom_id, me, nor); - bool has_uvs = bool(CustomData_has_layer(&me->ldata, CD_MLOOPUV)); + bool has_uvs = bool(CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2)); /* writes for uv coords if mesh has uv coords */ if (has_uvs) { @@ -367,13 +368,13 @@ void GeometryExporter::create_mesh_primitive_list(short material_index, til.push_back(normals_input); /* if mesh has uv coords writes for TEXCOORD */ - int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); - int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); + int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); + int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2); for (int i = 0; i < num_layers; i++) { - int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_MLOOPUV, i); + int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_PROP_FLOAT2, i); if (!this->export_settings.get_active_uv_only() || layer_index == active_uv_index) { - // char *name = CustomData_get_layer_name(&me->ldata, CD_MLOOPUV, i); + // char *name = CustomData_get_layer_name(&me->ldata, CD_PROP_FLOAT2, i); COLLADASW::Input texcoord_input( COLLADASW::InputSemantic::TEXCOORD, makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings.get_active_uv_only())), @@ -538,15 +539,16 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) int totuv = me->totloop; const Span polys = me->polys(); - int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); + int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); /* write for each layer * each will get id like meshName + "map-channel-1" */ - int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); + int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2); for (int a = 0; a < num_layers; a++) { - int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_MLOOPUV, a); + int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_PROP_FLOAT2, a); if (!this->export_settings.get_active_uv_only() || layer_index == active_uv_index) { - MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a); + const blender::float2 *uv_map = static_cast( + CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, a)); COLLADASW::FloatSourceF source(mSW); std::string layer_id = makeTexcoordSourceId( @@ -564,9 +566,9 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) for (const int i : polys.index_range()) { const MPoly *mpoly = &polys[i]; - MLoopUV *mloop = mloops + mpoly->loopstart; + const blender::float2 *mloop = uv_map + mpoly->loopstart; for (int j = 0; j < mpoly->totloop; j++) { - source.appendValues(mloop[j].uv[0], mloop[j].uv[1]); + source.appendValues(mloop[j][0], mloop[j][1]); } } diff --git a/source/blender/io/collada/InstanceWriter.cpp b/source/blender/io/collada/InstanceWriter.cpp index d88f24b8e8b..76ada0be099 100644 --- a/source/blender/io/collada/InstanceWriter.cpp +++ b/source/blender/io/collada/InstanceWriter.cpp @@ -38,13 +38,13 @@ void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial &bind_materia // create for each uv map Mesh *me = (Mesh *)ob->data; - int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); + int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); int map_index = 0; - int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); + int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2); for (int b = 0; b < num_layers; b++) { if (!active_uv_only || b == active_uv_index) { - char *name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPUV, b); + char *name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_FLOAT2, b); im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++)); } } diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp index cdcd8564f92..0c8bd29a3c9 100644 --- a/source/blender/io/collada/MeshImporter.cpp +++ b/source/blender/io/collada/MeshImporter.cpp @@ -246,7 +246,7 @@ void MeshImporter::set_vcol(MLoopCol *mloopcol, } } -void MeshImporter::set_face_uv(MLoopUV *mloopuv, +void MeshImporter::set_face_uv(blender::float2 *mloopuv, UVDataWrapper &uvs, int start_index, COLLADAFW::IndexList &index_list, @@ -257,7 +257,7 @@ void MeshImporter::set_face_uv(MLoopUV *mloopuv, for (int index = 0; index < count; index++) { int uv_index = indices[index + start_index]; - uvs.getUV(uv_index, mloopuv[index].uv); + uvs.getUV(uv_index, mloopuv[index]); } } @@ -474,10 +474,10 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me) COLLADAFW::String &uvname = info->mName; /* Allocate space for UV_data */ CustomData_add_layer_named( - &me->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, me->totloop, uvname.c_str()); + &me->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, me->totloop, uvname.c_str()); } /* activate the first uv map */ - CustomData_set_layer_active(&me->ldata, CD_MLOOPUV, 0); + CustomData_set_layer_active(&me->ldata, CD_PROP_FLOAT2, 0); } int totcolset = collada_mesh->getColors().getInputInfosArray().getCount(); @@ -719,8 +719,8 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, uvset_index++) { /* get mtface by face index and uv set index */ COLLADAFW::IndexList &index_list = *index_list_array_uvcoord[uvset_index]; - MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_named( - &me->ldata, CD_MLOOPUV, index_list.getName().c_str()); + blender::float2 *mloopuv = static_cast(CustomData_get_layer_named( + &me->ldata, CD_PROP_FLOAT2, index_list.getName().c_str())); if (mloopuv == nullptr) { fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to TEXCOORD [#%s].\n", diff --git a/source/blender/io/collada/MeshImporter.h b/source/blender/io/collada/MeshImporter.h index faccbe5c055..dbe3cce0ca4 100644 --- a/source/blender/io/collada/MeshImporter.h +++ b/source/blender/io/collada/MeshImporter.h @@ -95,7 +95,7 @@ class MeshImporter : public MeshImporterBase { bool set_poly_indices( MPoly *mpoly, MLoop *mloop, int loop_index, const unsigned int *indices, int loop_count); - void set_face_uv(MLoopUV *mloopuv, + void set_face_uv(blender::float2 *mloopuv, UVDataWrapper &uvs, int start_index, COLLADAFW::IndexList &index_list, diff --git a/source/blender/io/collada/collada_utils.cpp b/source/blender/io/collada/collada_utils.cpp index 96ff78a715a..8a093e0c5e1 100644 --- a/source/blender/io/collada/collada_utils.cpp +++ b/source/blender/io/collada/collada_utils.cpp @@ -322,7 +322,7 @@ bool bc_is_root_bone(Bone *aBone, bool deform_bones_only) int bc_get_active_UVLayer(Object *ob) { Mesh *me = (Mesh *)ob->data; - return CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); + return CustomData_get_active_layer_index(&me->ldata, CD_PROP_FLOAT2); } std::string bc_url_encode(std::string data) @@ -1071,9 +1071,9 @@ void bc_copy_m4d_v44(double (&r)[4][4], std::vector> &a) */ static std::string bc_get_active_uvlayer_name(Mesh *me) { - int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); + int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); if (num_layers) { - char *layer_name = bc_CustomData_get_active_layer_name(&me->ldata, CD_MLOOPUV); + char *layer_name = bc_CustomData_get_active_layer_name(&me->ldata, CD_PROP_FLOAT2); if (layer_name) { return std::string(layer_name); } @@ -1096,9 +1096,9 @@ static std::string bc_get_active_uvlayer_name(Object *ob) */ static std::string bc_get_uvlayer_name(Mesh *me, int layer) { - int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); + int num_layers = CustomData_number_of_layers(&me->ldata, CD_PROP_FLOAT2); if (num_layers && layer < num_layers) { - char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPUV, layer); + char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_PROP_FLOAT2, layer); if (layer_name) { return std::string(layer_name); } diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index c112fe7b51a..b88874e57c3 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -199,7 +199,7 @@ static void *add_customdata_cb(Mesh *mesh, const char *name, const int data_type int numloops; /* unsupported custom data type -- don't do anything. */ - if (!ELEM(cd_data_type, CD_MLOOPUV, CD_PROP_BYTE_COLOR)) { + if (!ELEM(cd_data_type, CD_PROP_FLOAT2, CD_PROP_BYTE_COLOR)) { return nullptr; } @@ -364,7 +364,7 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo for (int layer_idx = 0; layer_idx < ldata->totlayer; layer_idx++) { const CustomDataLayer *layer = &ldata->layers[layer_idx]; std::string layer_name = std::string(layer->name); - if (layer->type != CD_MLOOPUV) { + if (layer->type != CD_PROP_FLOAT2) { continue; } @@ -411,7 +411,7 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo for (int layer_idx = 0; layer_idx < ldata->totlayer; layer_idx++) { const CustomDataLayer *layer = &ldata->layers[layer_idx]; - if (layer->type != CD_MLOOPUV) { + if (layer->type != CD_PROP_FLOAT2) { continue; } @@ -446,15 +446,15 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo continue; } - MLoopUV *mloopuv = static_cast(layer->data); + float2 *mloopuv = static_cast(layer->data); if (is_left_handed_) { uv_index = rev_loop_index; } else { uv_index = loop_index; } - mloopuv[uv_index].uv[0] = sample.uvs[usd_uv_index][0]; - mloopuv[uv_index].uv[1] = sample.uvs[usd_uv_index][1]; + mloopuv[uv_index][0] = sample.uvs[usd_uv_index][0]; + mloopuv[uv_index][1] = sample.uvs[usd_uv_index][1]; } } } @@ -896,7 +896,7 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh, existing_mesh, positions_.size(), 0, 0, face_indices_.size(), face_counts_.size()); for (pxr::TfToken token : uv_tokens) { - add_customdata_cb(active_mesh, token.GetText(), CD_MLOOPUV); + add_customdata_cb(active_mesh, token.GetText(), CD_PROP_FLOAT2); } } diff --git a/source/blender/io/usd/intern/usd_writer_abstract.cc b/source/blender/io/usd/intern/usd_writer_abstract.cc index 2be9b1c065a..f4ae9d20e52 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.cc +++ b/source/blender/io/usd/intern/usd_writer_abstract.cc @@ -30,7 +30,7 @@ static std::string get_mesh_active_uvlayer_name(const Object *ob) const Mesh *me = static_cast(ob->data); - const char *name = CustomData_get_active_layer_name(&me->ldata, CD_MLOOPUV); + const char *name = CustomData_get_active_layer_name(&me->ldata, CD_PROP_FLOAT2); return name ? name : ""; } diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index 12d73b5e1cb..237e1414eaf 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -9,6 +9,7 @@ #include #include "BLI_assert.h" +#include "BLI_math_vector_types.hh" #include "BLI_math_vector.h" #include "BKE_attribute.h" @@ -113,7 +114,7 @@ void USDGenericMeshWriter::write_uv_maps(const Mesh *mesh, pxr::UsdGeomMesh usd_ const CustomData *ldata = &mesh->ldata; for (int layer_idx = 0; layer_idx < ldata->totlayer; layer_idx++) { const CustomDataLayer *layer = &ldata->layers[layer_idx]; - if (layer->type != CD_MLOOPUV) { + if (layer->type != CD_PROP_FLOAT2) { continue; } @@ -125,10 +126,10 @@ void USDGenericMeshWriter::write_uv_maps(const Mesh *mesh, pxr::UsdGeomMesh usd_ pxr::UsdGeomPrimvar uv_coords_primvar = primvarsAPI.CreatePrimvar( primvar_name, pxr::SdfValueTypeNames->TexCoord2fArray, pxr::UsdGeomTokens->faceVarying); - MLoopUV *mloopuv = static_cast(layer->data); + const float2 *mloopuv = static_cast(layer->data); pxr::VtArray uv_coords; for (int loop_idx = 0; loop_idx < mesh->totloop; loop_idx++) { - uv_coords.push_back(pxr::GfVec2f(mloopuv[loop_idx].uv)); + uv_coords.push_back(pxr::GfVec2f(mloopuv[loop_idx].x, mloopuv[loop_idx].y)); } if (!uv_coords_primvar.HasValue()) { diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc index d057319ec3d..fd843b195ec 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc @@ -288,24 +288,28 @@ Vector OBJMesh::calc_poly_vertex_indices(const int poly_index) const void OBJMesh::store_uv_coords_and_indices() { const int totvert = export_mesh_->totvert; - const MLoopUV *mloopuv = static_cast( - CustomData_get_layer(&export_mesh_->ldata, CD_MLOOPUV)); - if (!mloopuv) { + const StringRef active_uv_name = CustomData_get_active_layer_name(&export_mesh_->ldata, + CD_PROP_FLOAT2); + if (active_uv_name.is_empty()) { tot_uv_vertices_ = 0; return; } + const bke::AttributeAccessor attributes = export_mesh_->attributes(); + const VArraySpan uv_map = attributes.lookup(active_uv_name, ATTR_DOMAIN_CORNER); + const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT}; - UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create(mesh_polys_.data(), - nullptr, - nullptr, - mesh_loops_.data(), - mloopuv, - mesh_polys_.size(), - totvert, - limit, - false, - false); + UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create( + mesh_polys_.data(), + nullptr, + nullptr, + mesh_loops_.data(), + reinterpret_cast(uv_map.data()), + mesh_polys_.size(), + totvert, + limit, + false, + false); uv_indices_.resize(mesh_polys_.size()); /* At least total vertices of a mesh will be present in its texture map. So @@ -324,7 +328,7 @@ void OBJMesh::store_uv_coords_and_indices() /* Store UV vertex coordinates. */ uv_coords_.resize(tot_uv_vertices_); const int loopstart = mesh_polys_[uv_vert->poly_index].loopstart; - Span vert_uv_coords(mloopuv[loopstart + uv_vert->loop_of_poly_index].uv, 2); + Span vert_uv_coords(uv_map[loopstart + uv_vert->loop_of_poly_index], 2); uv_coords_[tot_uv_vertices_ - 1] = float2(vert_uv_coords[0], vert_uv_coords[1]); /* Store UV vertex indices. */ diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc index 008aaf5cd98..6323b5ba1fc 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc @@ -266,22 +266,41 @@ void MeshFromGeometry::create_uv_verts(Mesh *mesh) if (global_vertices_.uv_vertices.size() <= 0) { return; } - MLoopUV *mluv_dst = static_cast(CustomData_add_layer( - &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh_geometry_.total_loops_)); + + bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); + bke::SpanAttributeWriter uv_map = attributes.lookup_or_add_for_write_only_span( + "UVMap", ATTR_DOMAIN_CORNER); + int tot_loop_idx = 0; + bool added_uv = false; for (const PolyElem &curr_face : mesh_geometry_.face_elements_) { for (int idx = 0; idx < curr_face.corner_count_; ++idx) { const PolyCorner &curr_corner = mesh_geometry_.face_corners_[curr_face.start_index_ + idx]; - const int uv_index = curr_corner.uv_vert_index; - float2 uv(0, 0); - if (uv_index >= 0 && uv_index < global_vertices_.uv_vertices.size()) { - uv = global_vertices_.uv_vertices[uv_index]; + if (curr_corner.uv_vert_index >= 0 && + curr_corner.uv_vert_index < global_vertices_.uv_vertices.size()) { + uv_map.span[tot_loop_idx] = global_vertices_.uv_vertices[curr_corner.uv_vert_index]; + added_uv = true; + } + else { + uv_map.span[tot_loop_idx] = {0.f, 0.f}; } - copy_v2_v2(mluv_dst[tot_loop_idx].uv, uv); tot_loop_idx++; } } + + uv_map.finish(); + + /* If we have an object without UVs which resides in the same .obj file + * as an object which *does* have UVs we can end up adding a UV layer + * filled with zeroes. + * We could maybe check before creating this layer but that would need + * iterating over the whole mesh to check for UVs and as this is probably + * the exception rather than the rule, just delete it afterwards. + */ + if (!added_uv) { + attributes.remove("UVMap"); + } } static Material *get_or_create_material(Main *bmain, diff --git a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc index afa860ba7c2..5f5587577a1 100644 --- a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc @@ -107,9 +107,9 @@ class obj_importer_test : public BlendfileLoadingBaseTest { const float3 *lnors = (const float3 *)CustomData_get_layer(&mesh->ldata, CD_NORMAL); float3 normal_first = lnors != nullptr ? lnors[0] : float3(0, 0, 0); EXPECT_V3_NEAR(normal_first, exp.normal_first, 0.0001f); - const MLoopUV *mloopuv = static_cast( - CustomData_get_layer(&mesh->ldata, CD_MLOOPUV)); - float2 uv_first = mloopuv ? float2(mloopuv->uv) : float2(0, 0); + const float2 *mloopuv = static_cast( + CustomData_get_layer(&mesh->ldata, CD_PROP_FLOAT2)); + float2 uv_first = mloopuv ? *mloopuv : float2(0, 0); EXPECT_V2_NEAR(uv_first, exp.uv_first, 0.0001f); if (exp.color_first.x >= 0) { const float4 *colors = (const float4 *)CustomData_get_layer(&mesh->vdata, CD_PROP_COLOR); diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 6586cd4dd5b..3d5cd273eda 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -44,7 +44,8 @@ typedef struct CustomDataLayer { /** Shape keyblock unique id reference. */ int uid; /** Layer name, MAX_CUSTOMDATA_LAYER_NAME. */ - char name[64]; + char name[68]; + char _pad1[4]; /** Layer data. */ void *data; /** @@ -54,7 +55,8 @@ typedef struct CustomDataLayer { const AnonymousAttributeIDHandle *anonymous_id; } CustomDataLayer; -#define MAX_CUSTOMDATA_LAYER_NAME 64 +#define MAX_CUSTOMDATA_LAYER_NAME 68 +#define MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX 64 typedef struct CustomDataExternal { /** FILE_MAX. */ @@ -181,7 +183,6 @@ typedef enum eCustomDataType { #define CD_MASK_ORIGSPACE (1 << CD_ORIGSPACE) #define CD_MASK_ORCO (1 << CD_ORCO) // #define CD_MASK_MTEXPOLY (1 << CD_MTEXPOLY) /* DEPRECATED */ -#define CD_MASK_MLOOPUV (1 << CD_MLOOPUV) #define CD_MASK_PROP_BYTE_COLOR (1 << CD_PROP_BYTE_COLOR) #define CD_MASK_TANGENT (1 << CD_TANGENT) #define CD_MASK_MDISPS (1 << CD_MDISPS) diff --git a/source/blender/makesdna/DNA_dynamicpaint_types.h b/source/blender/makesdna/DNA_dynamicpaint_types.h index eef3b59c20d..3d3cc20a571 100644 --- a/source/blender/makesdna/DNA_dynamicpaint_types.h +++ b/source/blender/makesdna/DNA_dynamicpaint_types.h @@ -113,7 +113,7 @@ typedef struct DynamicPaintSurface { float init_color[4]; struct Tex *init_texture; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char init_layername[64]; + char init_layername[68]; int dry_speed, diss_speed; float color_dry_threshold; @@ -130,13 +130,13 @@ typedef struct DynamicPaintSurface { char _pad2[4]; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char uvlayer_name[64]; + char uvlayer_name[68]; /** 1024 = FILE_MAX. */ char image_output_path[1024]; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char output_name[64]; + char output_name[68]; /** MAX_CUSTOMDATA_LAYER_NAME */ /* some surfaces have 2 outputs. */ - char output_name2[64]; + char output_name2[68]; } DynamicPaintSurface; diff --git a/source/blender/makesdna/DNA_fluid_types.h b/source/blender/makesdna/DNA_fluid_types.h index 5a1636879bb..10fa1004f3d 100644 --- a/source/blender/makesdna/DNA_fluid_types.h +++ b/source/blender/makesdna/DNA_fluid_types.h @@ -784,14 +784,15 @@ typedef struct FluidFlowSettings { float texture_offset; char _pad2[4]; /* MAX_CUSTOMDATA_LAYER_NAME. */ - char uvlayer_name[64]; + char uvlayer_name[68]; + char _pad3[4]; short vgroup_density; short type; /* Smoke, flames, both, outflow, liquid. */ short behavior; /* Inflow, outflow, static. */ short source; short texture_type; - short _pad3[3]; + short _pad4[3]; int flags; /* Absolute emission etc. */ } FluidFlowSettings; diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 7c1abc80525..7879b3e9551 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -159,9 +159,9 @@ enum { * * // access UV coordinates (works for all loop data, vertex colors... etc). * float *uvtri_co[3] = { - * mloopuv[lt->tri[0]].uv, - * mloopuv[lt->tri[1]].uv, - * mloopuv[lt->tri[2]].uv, + * mloopuv[lt->tri[0]], + * mloopuv[lt->tri[1]], + * mloopuv[lt->tri[2]], * }; * \endcode * @@ -312,21 +312,6 @@ typedef enum eMVertSkinFlag { /** \name Custom Data (Loop) * \{ */ -/** - * UV coordinate for a polygon face & flag for selection & other options. - */ -typedef struct MLoopUV { - float uv[2]; - int flag; -} MLoopUV; - -/** #MLoopUV.flag */ -enum { - MLOOPUV_EDGESEL = (1 << 0), - MLOOPUV_VERTSEL = (1 << 1), - MLOOPUV_PINNED = (1 << 2), -}; - /** * \note While alpha is not currently in the 3D Viewport, * this may eventually be added back, keep this value set to 255. @@ -447,6 +432,26 @@ enum { /** \name Deprecated Structs * \{ */ +#ifdef DNA_DEPRECATED_ALLOW + +/** + * UV coordinate for a polygon face & flag for selection & other options. + * Deprecated, but kept to read old files. UV coordinates are now stored as #CD_PROP_FLOAT2 layers. + */ +typedef struct MLoopUV { + float uv[2]; + int flag; +} MLoopUV; + +/** #MLoopUV.flag */ +enum { + MLOOPUV_EDGESEL = (1 << 0), + MLOOPUV_VERTSEL = (1 << 1), + MLOOPUV_PINNED = (1 << 2), +}; + +#endif + /** * Deprecated mesh vertex data structure. Now stored with generic attributes. */ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 810d2bae59a..170fa0b4351 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -143,7 +143,8 @@ typedef struct MappingInfoModifierData { struct Object *map_object; char map_bone[64]; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char uvlayer_name[64]; + char uvlayer_name[68]; + char _pad1[4]; int uvlayer_tmp; int texmapping; } MappingInfoModifierData; @@ -558,7 +559,8 @@ typedef struct DisplaceModifierData { struct Object *map_object; char map_bone[64]; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char uvlayer_name[64]; + char uvlayer_name[68]; + char _pad1[4]; int uvlayer_tmp; int texmapping; /* end MappingInfoModifierData */ @@ -570,7 +572,7 @@ typedef struct DisplaceModifierData { float midlevel; int space; short flag; - char _pad[6]; + char _pad2[6]; } DisplaceModifierData; /** #DisplaceModifierData.flag */ @@ -614,9 +616,8 @@ typedef struct UVProjectModifierData { float aspectx, aspecty; float scalex, scaley; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char uvlayer_name[64]; + char uvlayer_name[68]; int uvlayer_tmp; - char _pad[4]; } UVProjectModifierData; #define MOD_UVPROJECT_MAXPROJECTORS 10 @@ -719,7 +720,8 @@ typedef struct WaveModifierData { struct Object *map_object; char map_bone[64]; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char uvlayer_name[64]; + char uvlayer_name[68]; + char _pad1[4]; int uvlayer_tmp; int texmapping; /* End MappingInfoModifierData. */ @@ -729,14 +731,14 @@ typedef struct WaveModifierData { char defgrp_name[64]; short flag; - char _pad[2]; + char _pad2[2]; float startx, starty, height, width; float narrow, speed, damp, falloff; float timeoffs, lifetime; - char _pad1[4]; - void *_pad2; + char _pad3[4]; + void *_pad4; } WaveModifierData; /** #WaveModifierData.flag */ @@ -1059,9 +1061,9 @@ typedef struct ParticleInstanceModifierData { float rotation, random_rotation; float particle_amount, particle_offset; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char index_layer_name[64]; + char index_layer_name[68]; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char value_layer_name[64]; + char value_layer_name[68]; void *_pad1; } ParticleInstanceModifierData; @@ -1082,8 +1084,9 @@ typedef struct ExplodeModifierData { short flag, vgroup; float protect; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char uvname[64]; - void *_pad1; + char uvname[68]; + char _pad1[4]; + void *_pad2; } ExplodeModifierData; typedef struct MultiresModifierData { @@ -1397,8 +1400,8 @@ typedef struct OceanModifierData { /** FILE_MAX. */ char cachepath[1024]; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char foamlayername[64]; - char spraylayername[64]; + char foamlayername[68]; + char spraylayername[68]; char cached; char geometry_mode; @@ -1446,7 +1449,8 @@ typedef struct WarpModifierData { struct Object *map_object; char map_bone[64]; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char uvlayer_name[64]; + char uvlayer_name[68]; + char _pad1[4]; int uvlayer_tmp; int texmapping; /* End #MappingInfoModifierData. */ @@ -1465,8 +1469,8 @@ typedef struct WarpModifierData { float falloff_radius; char flag; char falloff_type; - char _pad[6]; - void *_pad1; + char _pad2[6]; + void *_pad3; } WarpModifierData; /** #WarpModifierData.flag */ @@ -1527,10 +1531,9 @@ typedef struct WeightVGEditModifierData { /** How to map the texture (using MOD_DISP_MAP_* enums). */ int mask_tex_mapping; /** Name of the UV map. MAX_CUSTOMDATA_LAYER_NAME. */ - char mask_tex_uvlayer_name[64]; + char mask_tex_uvlayer_name[68]; /* Padding... */ - char _pad0[4]; void *_pad1; } WeightVGEditModifierData; @@ -1581,12 +1584,13 @@ typedef struct WeightVGMixModifierData { /** How to map the texture. */ int mask_tex_mapping; /** Name of the UV map. MAX_CUSTOMDATA_LAYER_NAME. */ - char mask_tex_uvlayer_name[64]; + char mask_tex_uvlayer_name[68]; + char _pad1[4]; char flag; /* Padding... */ - char _pad1[3]; + char _pad2[3]; } WeightVGMixModifierData; /** #WeightVGMixModifierData.mix_mode (how second vgroup's weights affect first ones). */ @@ -1669,7 +1673,8 @@ typedef struct WeightVGProximityModifierData { /** How to map the texture. */ int mask_tex_mapping; /** Name of the UV Map. MAX_CUSTOMDATA_LAYER_NAME. */ - char mask_tex_uvlayer_name[64]; + char mask_tex_uvlayer_name[68]; + char _pad1[4]; /** Distances mapping to 0.0/1.0 weights. */ float min_dist, max_dist; @@ -1943,7 +1948,8 @@ typedef struct UVWarpModifierData { /** Optional vertex-group name, #MAX_VGROUP_NAME. */ char vgroup_name[64]; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char uvlayer_name[64]; + char uvlayer_name[68]; + char _pad[4]; } UVWarpModifierData; /** #UVWarpModifierData.flag */ diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 2ddf166566a..c0ea55885d0 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -1136,12 +1136,11 @@ typedef struct NodeShaderTexPointDensity { short interpolation; short color_source; short ob_color_source; - /** Vertex attribute layer for color source, MAX_CUSTOMDATA_LAYER_NAME. */ - char vertex_attribute_name[64]; /* Used at runtime only by sampling RNA API. */ PointDensity pd; int cached_resolution; - char _pad2[4]; + /** Vertex attribute layer for color source, MAX_CUSTOMDATA_LAYER_NAME. */ + char vertex_attribute_name[68]; } NodeShaderTexPointDensity; typedef struct NodeShaderPrincipled { diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index c4f11905e10..75410716e22 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -359,12 +359,13 @@ typedef struct ParticleSystem { char _pad1[6]; /** Billboard uv name, MAX_CUSTOMDATA_LAYER_NAME. */ - char bb_uvname[3][64] DNA_DEPRECATED; + char bb_uvname[3][68] DNA_DEPRECATED; + char _pad2[4]; /* if you change these remember to update array lengths to PSYS_TOT_VG! */ /** Vertex groups, 0==disable, 1==starting index. */ short vgroup[13], vg_neg, rt3; - char _pad[6]; + char _pad3[6]; /* point cache */ struct PointCache *pointcache; diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index c7d49db130e..4b3daf92d8b 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -31,7 +31,8 @@ typedef struct MTex { struct Object *object; struct Tex *tex; /** MAX_CUSTOMDATA_LAYER_NAME. */ - char uvname[64]; + char uvname[68]; + char _pad1[4]; char projx, projy, projz, mapping; char brush_map_mode, brush_angle_mode; @@ -122,7 +123,8 @@ typedef struct PointDensity { /** cache points in world-space, object space, ... ? */ short ob_cache_space; /** vertex attribute layer for color source, MAX_CUSTOMDATA_LAYER_NAME */ - char vertex_attribute_name[64]; + char vertex_attribute_name[68]; + char _pad1[4]; /** The acceleration tree containing points. */ void *point_tree; @@ -133,11 +135,11 @@ typedef struct PointDensity { short noise_depth; short noise_influence; short noise_basis; - char _pad1[6]; + char _pad2[6]; float noise_fac; float speed_scale, falloff_speed_scale; - char _pad2[4]; + char _pad3[4]; /** For time -> color */ struct ColorBand *coba; diff --git a/source/blender/makesrna/intern/rna_attribute.c b/source/blender/makesrna/intern/rna_attribute.c index 67d0e8adef5..13d3e08c462 100644 --- a/source/blender/makesrna/intern/rna_attribute.c +++ b/source/blender/makesrna/intern/rna_attribute.c @@ -1191,7 +1191,7 @@ static void rna_def_attribute_group(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_AttributeGroup_update_active_color"); prop = RNA_def_property(srna, "default_color_name", PROP_STRING, PROP_NONE); - RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME); + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); RNA_def_property_string_funcs(prop, "rna_AttributeGroup_default_color_name_get", "rna_AttributeGroup_default_color_name_length", @@ -1202,7 +1202,7 @@ static void rna_def_attribute_group(BlenderRNA *brna) "The name of the default color attribute used as a fallback for rendering"); prop = RNA_def_property(srna, "active_color_name", PROP_STRING, PROP_NONE); - RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME); + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); RNA_def_property_string_funcs(prop, "rna_AttributeGroup_active_color_name_get", "rna_AttributeGroup_active_color_name_length", diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index c0969aaa3ba..0bf233767cd 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -964,12 +964,15 @@ static void rna_MPoly_freestyle_face_mark_set(PointerRNA *ptr, bool value) /* uv_layers */ -DEFINE_CUSTOMDATA_LAYER_COLLECTION(uv_layer, ldata, CD_MLOOPUV) -DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(uv_layer, ldata, CD_MLOOPUV, active, MeshUVLoopLayer) -DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(uv_layer, ldata, CD_MLOOPUV, clone, MeshUVLoopLayer) +DEFINE_CUSTOMDATA_LAYER_COLLECTION(uv_layer, ldata, CD_PROP_FLOAT2) DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM( - uv_layer, ldata, CD_MLOOPUV, stencil, MeshUVLoopLayer) -DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(uv_layer, ldata, CD_MLOOPUV, render, MeshUVLoopLayer) + uv_layer, ldata, CD_PROP_FLOAT2, active, MeshUVLoopLayer) +DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM( + uv_layer, ldata, CD_PROP_FLOAT2, clone, MeshUVLoopLayer) +DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM( + uv_layer, ldata, CD_PROP_FLOAT2, stencil, MeshUVLoopLayer) +DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM( + uv_layer, ldata, CD_PROP_FLOAT2, render, MeshUVLoopLayer) /* MeshUVLoopLayer */ @@ -986,7 +989,7 @@ static void rna_MeshUVLoopLayer_data_begin(CollectionPropertyIterator *iter, Poi Mesh *me = rna_mesh(ptr); CustomDataLayer *layer = (CustomDataLayer *)ptr->data; rna_iterator_array_begin( - iter, layer->data, sizeof(MLoopUV), (me->edit_mesh) ? 0 : me->totloop, 0, NULL); + iter, layer->data, sizeof(float[2]), (me->edit_mesh) ? 0 : me->totloop, 0, NULL); } static int rna_MeshUVLoopLayer_data_length(PointerRNA *ptr) @@ -997,32 +1000,32 @@ static int rna_MeshUVLoopLayer_data_length(PointerRNA *ptr) static bool rna_MeshUVLoopLayer_active_render_get(PointerRNA *ptr) { - return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_MLOOPUV, 1); + return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_PROP_FLOAT2, 1); } static bool rna_MeshUVLoopLayer_active_get(PointerRNA *ptr) { - return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_MLOOPUV, 0); + return rna_CustomDataLayer_active_get(ptr, rna_mesh_ldata(ptr), CD_PROP_FLOAT2, 0); } static bool rna_MeshUVLoopLayer_clone_get(PointerRNA *ptr) { - return rna_CustomDataLayer_clone_get(ptr, rna_mesh_ldata(ptr), CD_MLOOPUV); + return rna_CustomDataLayer_clone_get(ptr, rna_mesh_ldata(ptr), CD_PROP_FLOAT2); } static void rna_MeshUVLoopLayer_active_render_set(PointerRNA *ptr, bool value) { - rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPUV, 1); + rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_PROP_FLOAT2, 1); } static void rna_MeshUVLoopLayer_active_set(PointerRNA *ptr, bool value) { - rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPUV, 0); + rna_CustomDataLayer_active_set(ptr, rna_mesh_ldata(ptr), value, CD_PROP_FLOAT2, 0); } static void rna_MeshUVLoopLayer_clone_set(PointerRNA *ptr, bool value) { - rna_CustomDataLayer_clone_set(ptr, rna_mesh_ldata(ptr), value, CD_MLOOPUV); + rna_CustomDataLayer_clone_set(ptr, rna_mesh_ldata(ptr), value, CD_PROP_FLOAT2); } /* vertex_color_layers */ @@ -1803,7 +1806,117 @@ int rna_Mesh_poly_normals_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_p static char *rna_MeshUVLoop_path(const PointerRNA *ptr) { - return rna_LoopCustomData_data_path(ptr, "uv_layers", CD_MLOOPUV); + return rna_LoopCustomData_data_path(ptr, "uv_layers", CD_PROP_FLOAT2); +} +/* The rna_MeshUVLoop_*_get/set() functions get passed a pointer to + * the (float2) uv attribute. This is for historical reasons because + * the api used to wrap MLoopUV, which contained the uv and all the selection + * pin states in a single struct. But since that struct no longer exists and + * we still can use only a single pointer to access these, we need to look up + * the original attribute layer and the index of the uv in it to be able to + * find the associated bool layers. So we scan the available foat2 layers + * to find into which layer the pointer we got passed points. */ +static bool get_uv_index_and_layer(const PointerRNA *ptr, + int *r_uv_map_index, + int *r_index_in_attribute) +{ + const Mesh *mesh = rna_mesh(ptr); + const float(*uv_coord)[2] = (const float(*)[2])ptr->data; + + /* We don't know from which attribute the RNA pointer is from, so we need to scan them all. */ + const int uv_layers_num = CustomData_number_of_layers(&mesh->ldata, CD_PROP_FLOAT2); + for (int layer_i = 0; layer_i < uv_layers_num; layer_i++) { + const float(*layer_data)[2] = (float(*)[2])CustomData_get_layer_n( + &mesh->ldata, CD_PROP_FLOAT2, layer_i); + const ptrdiff_t index = uv_coord - layer_data; + if (index >= 0 && index < mesh->totloop) { + *r_uv_map_index = layer_i; + *r_index_in_attribute = index; + return true; + } + } + /* This can happen if the Customdata arrays were re-allocated between obtaining the + * python object and accessing it.*/ + return false; +} + +static bool rna_MeshUVLoop_select_get(PointerRNA *ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + int uv_map_index; + int loop_index; + const bool *select = NULL; + if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) { + select = ED_mesh_uv_map_vert_select_layer_get(mesh, uv_map_index); + } + return select ? select[loop_index] : false; +} + +static void rna_MeshUVLoop_select_set(PointerRNA *ptr, const bool value) +{ + Mesh *mesh = rna_mesh(ptr); + int uv_map_index; + int loop_index; + if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) { + bool *select = ED_mesh_uv_map_vert_select_layer_ensure(mesh, uv_map_index); + select[loop_index] = value; + } +} + +static bool rna_MeshUVLoop_select_edge_get(PointerRNA *ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + int uv_map_index; + int loop_index; + const bool *select_edge = NULL; + if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) { + select_edge = ED_mesh_uv_map_edge_select_layer_get(mesh, uv_map_index); + } + return select_edge ? select_edge[loop_index] : false; +} + +static void rna_MeshUVLoop_select_edge_set(PointerRNA *ptr, const bool value) +{ + Mesh *mesh = rna_mesh(ptr); + int uv_map_index; + int loop_index; + if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) { + bool *select_edge = ED_mesh_uv_map_edge_select_layer_ensure(mesh, uv_map_index); + select_edge[loop_index] = value; + } +} + +static bool rna_MeshUVLoop_pin_uv_get(PointerRNA *ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + int uv_map_index; + int loop_index; + const bool *pin_uv = NULL; + if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) { + pin_uv = ED_mesh_uv_map_pin_layer_get(mesh, uv_map_index); + } + return pin_uv ? pin_uv[loop_index] : false; +} + +static void rna_MeshUVLoop_pin_uv_set(PointerRNA *ptr, const bool value) +{ + Mesh *mesh = rna_mesh(ptr); + int uv_map_index; + int loop_index; + if (get_uv_index_and_layer(ptr, &uv_map_index, &loop_index)) { + bool *pin_uv = ED_mesh_uv_map_pin_layer_ensure(mesh, uv_map_index); + pin_uv[loop_index] = value; + } +} + +static void rna_MeshUVLoop_uv_get(PointerRNA *ptr, float *value) +{ + copy_v2_v2(value, ptr->data); +} + +static void rna_MeshUVLoop_uv_set(PointerRNA *ptr, const float *value) +{ + copy_v2_v2(ptr->data, value); } static char *rna_MeshLoopColorLayer_path(const PointerRNA *ptr) @@ -2125,7 +2238,7 @@ static PointerRNA rna_Mesh_uv_layers_new(struct Mesh *me, if (index != -1) { ldata = rna_mesh_ldata_helper(me); - cdl = &ldata->layers[CustomData_get_layer_index_n(ldata, CD_MLOOPUV, index)]; + cdl = &ldata->layers[CustomData_get_layer_index_n(ldata, CD_PROP_FLOAT2, index)]; } RNA_pointer_create(&me->id, &RNA_MeshUVLoopLayer, cdl, &ptr); @@ -2134,9 +2247,10 @@ static PointerRNA rna_Mesh_uv_layers_new(struct Mesh *me, static void rna_Mesh_uv_layers_remove(struct Mesh *me, ReportList *reports, CustomDataLayer *layer) { - if (ED_mesh_uv_remove_named(me, layer->name) == false) { - BKE_reportf(reports, RPT_ERROR, "Texture layer '%s' not found", layer->name); + if (!BKE_id_attribute_find(&me->id, layer->name, CD_PROP_FLOAT, ATTR_DOMAIN_CORNER)) { + BKE_reportf(reports, RPT_ERROR, "UV map '%s' not found", layer->name); } + BKE_id_attribute_remove(&me->id, layer->name, reports); } static bool rna_Mesh_is_editmode_get(PointerRNA *ptr) @@ -2636,6 +2750,7 @@ static void rna_def_mloopuv(BlenderRNA *brna) prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_struct_name_property(srna, prop); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshLoopLayer_name_set"); + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); RNA_def_property_ui_text(prop, "Name", "Name of UV map"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); @@ -2660,23 +2775,25 @@ static void rna_def_mloopuv(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); srna = RNA_def_struct(brna, "MeshUVLoop", NULL); - RNA_def_struct_sdna(srna, "MLoopUV"); RNA_def_struct_ui_text(srna, "Mesh UV Layer", "Layer of UV coordinates in a Mesh data-block"); RNA_def_struct_path_func(srna, "rna_MeshUVLoop_path"); prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_XYZ); + RNA_def_property_array(prop, 2); + RNA_def_property_float_funcs(prop, "rna_MeshUVLoop_uv_get", "rna_MeshUVLoop_uv_set", NULL); RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); prop = RNA_def_property(srna, "pin_uv", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", MLOOPUV_PINNED); + RNA_def_property_boolean_funcs(prop, "rna_MeshUVLoop_pin_uv_get", "rna_MeshUVLoop_pin_uv_set"); RNA_def_property_ui_text(prop, "UV Pinned", ""); prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", MLOOPUV_VERTSEL); + RNA_def_property_boolean_funcs(prop, "rna_MeshUVLoop_select_get", "rna_MeshUVLoop_select_set"); RNA_def_property_ui_text(prop, "UV Select", ""); prop = RNA_def_property(srna, "select_edge", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", MLOOPUV_EDGESEL); + RNA_def_property_boolean_funcs( + prop, "rna_MeshUVLoop_select_edge_get", "rna_MeshUVLoop_select_edge_set"); RNA_def_property_ui_text(prop, "UV Edge Select", ""); } @@ -2695,6 +2812,7 @@ static void rna_def_mloopcol(BlenderRNA *brna) prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_struct_name_property(srna, prop); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshLoopLayer_name_set"); + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); RNA_def_property_ui_text(prop, "Name", "Name of Vertex color layer"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); @@ -2755,6 +2873,7 @@ static void rna_def_MPropCol(BlenderRNA *brna) prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_struct_name_property(srna, prop); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshVertexLayer_name_set"); + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); RNA_def_property_ui_text(prop, "Name", "Name of Sculpt Vertex color layer"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); @@ -2815,6 +2934,7 @@ static void rna_def_mproperties(BlenderRNA *brna) prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); \ RNA_def_struct_name_property(srna, prop); \ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshAnyLayer_name_set"); \ + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); \ RNA_def_property_ui_text(prop, "Name", ""); \ RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); \ \ @@ -2857,6 +2977,7 @@ static void rna_def_mproperties(BlenderRNA *brna) prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); \ RNA_def_struct_name_property(srna, prop); \ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshAnyLayer_name_set"); \ + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); \ RNA_def_property_ui_text(prop, "Name", ""); \ RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); \ \ @@ -2898,6 +3019,7 @@ static void rna_def_mproperties(BlenderRNA *brna) prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); \ RNA_def_struct_name_property(srna, prop); \ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshAnyLayer_name_set"); \ + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); \ RNA_def_property_ui_text(prop, "Name", ""); \ RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); \ \ @@ -3405,6 +3527,7 @@ static void rna_def_skin_vertices(BlenderRNA *brna, PropertyRNA *UNUSED(cprop)) prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_struct_name_property(srna, prop); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshVertexLayer_name_set"); + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); RNA_def_property_ui_text(prop, "Name", "Name of skin layer"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); @@ -3567,6 +3690,7 @@ static void rna_def_face_map(BlenderRNA *brna) prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_struct_name_property(srna, prop); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshPolyLayer_name_set"); + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); RNA_def_property_ui_text(prop, "Name", "Name of face map layer"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index 0675c39299e..b6bb6f34282 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -248,7 +248,7 @@ void RNA_api_mesh(StructRNA *srna) parm = RNA_def_string(func, "uvmap", NULL, - MAX_CUSTOMDATA_LAYER_NAME, + MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX, "", "Name of the UV map to use for tangent space computation"); diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 24db2136af9..8270ed24fd9 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -1355,16 +1355,16 @@ static const EnumPropertyItem *rna_DataTransferModifier_layers_select_src_itemf( Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src); CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH; - cddata_masks.lmask |= CD_MASK_MLOOPUV; + cddata_masks.lmask |= CD_MASK_PROP_FLOAT2; me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks); - num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPUV); + num_data = CustomData_number_of_layers(&me_eval->ldata, CD_PROP_FLOAT2); RNA_enum_item_add_separator(&item, &totitem); for (i = 0; i < num_data; i++) { tmp_item.value = i; tmp_item.identifier = tmp_item.name = CustomData_get_layer_name( - &me_eval->ldata, CD_MLOOPUV, i); + &me_eval->ldata, CD_PROP_FLOAT2, i); RNA_enum_item_add(&item, &totitem, &tmp_item); } } @@ -1473,13 +1473,14 @@ static const EnumPropertyItem *rna_DataTransferModifier_layers_select_dst_itemf( me_dst = ob_dst->data; ldata = &me_dst->ldata; - num_data = CustomData_number_of_layers(ldata, CD_MLOOPUV); + num_data = CustomData_number_of_layers(ldata, CD_PROP_FLOAT2); RNA_enum_item_add_separator(&item, &totitem); for (i = 0; i < num_data; i++) { tmp_item.value = i; - tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPUV, i); + tmp_item.identifier = tmp_item.name = CustomData_get_layer_name( + ldata, CD_PROP_FLOAT2, i); RNA_enum_item_add(&item, &totitem, &tmp_item); } } @@ -3861,7 +3862,7 @@ static void rna_def_modifier_explode(BlenderRNA *brna) prop = RNA_def_property(srna, "particle_uv", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "uvname"); - RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME); + RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX); RNA_def_property_ui_text(prop, "Particle UV", "UV map to change with particle age"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 8a24aa113b7..17d2310b262 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1056,7 +1056,7 @@ void rna_object_uvlayer_name_set(PointerRNA *ptr, const char *value, char *resul for (a = 0; a < me->ldata.totlayer; a++) { layer = &me->ldata.layers[a]; - if (layer->type == CD_MLOOPUV && STREQ(layer->name, value)) { + if (layer->type == CD_PROP_FLOAT2 && STREQ(layer->name, value)) { BLI_strncpy(result, value, maxlen); return; } diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index ad579a48d2f..1d80123b5d9 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -382,7 +382,7 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, int num = particle->num_dmcache; int from = modifier->psys->part->from; - if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) { + if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_PROP_FLOAT2)) { BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); return; } @@ -641,7 +641,7 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, zero_v2(r_uv); return; } - if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) { + if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_PROP_FLOAT2)) { BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); zero_v2(r_uv); return; diff --git a/source/blender/modifiers/intern/MOD_array.cc b/source/blender/modifiers/intern/MOD_array.cc index a2197835b3d..665ed094631 100644 --- a/source/blender/modifiers/intern/MOD_array.cc +++ b/source/blender/modifiers/intern/MOD_array.cc @@ -660,10 +660,10 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, /* handle UVs */ if (chunk_nloops > 0 && is_zero_v2(amd->uv_offset) == false) { - const int totuv = CustomData_number_of_layers(&result->ldata, CD_MLOOPUV); + const int totuv = CustomData_number_of_layers(&result->ldata, CD_PROP_FLOAT2); for (i = 0; i < totuv; i++) { - MLoopUV *dmloopuv = static_cast( - CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, i)); + blender::float2 *dmloopuv = static_cast( + CustomData_get_layer_n(&result->ldata, CD_PROP_FLOAT2, i)); dmloopuv += chunk_nloops; for (c = 1; c < count; c++) { const float uv_offset[2] = { @@ -672,8 +672,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, }; int l_index = chunk_nloops; for (; l_index-- != 0; dmloopuv++) { - dmloopuv->uv[0] += uv_offset[0]; - dmloopuv->uv[1] += uv_offset[1]; + (*dmloopuv)[0] += uv_offset[0]; + (*dmloopuv)[1] += uv_offset[1]; } } } diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c index c19c231d44c..98b0f623843 100644 --- a/source/blender/modifiers/intern/MOD_dynamicpaint.c +++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c @@ -81,10 +81,10 @@ static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_ma if (pmd->canvas) { DynamicPaintSurface *surface = pmd->canvas->surfaces.first; for (; surface; surface = surface->next) { - /* UV's: #CD_MLOOPUV. */ + /* UV's: #CD_PROP_FLOAT2. */ if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ || surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) { - r_cddata_masks->lmask |= CD_MASK_MLOOPUV; + r_cddata_masks->lmask |= CD_MASK_PROP_FLOAT2; } /* Vertex Colors: #CD_PROP_BYTE_COLOR. */ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT || diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 336b36a69c6..4aa896707dd 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -157,7 +157,7 @@ typedef struct GenerateOceanGeometryData { float (*vert_positions)[3]; MPoly *mpolys; MLoop *mloops; - MLoopUV *mloopuvs; + float (*mloopuvs)[2]; int res_x, res_y; int rx, ry; @@ -220,22 +220,22 @@ static void generate_ocean_geometry_uvs(void *__restrict userdata, for (x = 0; x < gogd->res_x; x++) { const int i = y * gogd->res_x + x; - MLoopUV *luv = &gogd->mloopuvs[i * 4]; + float(*luv)[2] = &gogd->mloopuvs[i * 4]; - luv->uv[0] = x * gogd->ix; - luv->uv[1] = y * gogd->iy; + (*luv)[0] = x * gogd->ix; + (*luv)[1] = y * gogd->iy; luv++; - luv->uv[0] = (x + 1) * gogd->ix; - luv->uv[1] = y * gogd->iy; + (*luv)[0] = (x + 1) * gogd->ix; + (*luv)[1] = y * gogd->iy; luv++; - luv->uv[0] = (x + 1) * gogd->ix; - luv->uv[1] = (y + 1) * gogd->iy; + (*luv)[0] = (x + 1) * gogd->ix; + (*luv)[1] = (y + 1) * gogd->iy; luv++; - luv->uv[0] = x * gogd->ix; - luv->uv[1] = (y + 1) * gogd->iy; + (*luv)[0] = x * gogd->ix; + (*luv)[1] = (y + 1) * gogd->iy; luv++; } } @@ -287,9 +287,9 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co BKE_mesh_calc_edges(result, false, false); /* add uvs */ - if (CustomData_number_of_layers(&result->ldata, CD_MLOOPUV) < MAX_MTFACE) { - gogd.mloopuvs = CustomData_add_layer( - &result->ldata, CD_MLOOPUV, CD_SET_DEFAULT, NULL, polys_num * 4); + if (CustomData_number_of_layers(&result->ldata, CD_PROP_FLOAT2) < MAX_MTFACE) { + gogd.mloopuvs = CustomData_add_layer_named( + &result->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, NULL, polys_num * 4, "UVMap"); if (gogd.mloopuvs) { /* unlikely to fail */ gogd.ix = 1.0 / gogd.rx; diff --git a/source/blender/modifiers/intern/MOD_screw.cc b/source/blender/modifiers/intern/MOD_screw.cc index e6e89ac7789..82592a13faf 100644 --- a/source/blender/modifiers/intern/MOD_screw.cc +++ b/source/blender/modifiers/intern/MOD_screw.cc @@ -213,8 +213,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * uint *vert_loop_map = nullptr; /* orig vert to orig loop */ /* UV Coords */ - const uint mloopuv_layers_tot = uint(CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV)); - blender::Array mloopuv_layers(mloopuv_layers_tot); + const uint mloopuv_layers_tot = uint(CustomData_number_of_layers(&mesh->ldata, CD_PROP_FLOAT2)); + blender::Array mloopuv_layers(mloopuv_layers_tot); float uv_u_scale; float uv_v_minmax[2] = {FLT_MAX, -FLT_MAX}; float uv_v_range_inv; @@ -406,8 +406,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * if (mloopuv_layers_tot) { uint uv_lay; for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { - mloopuv_layers[uv_lay] = static_cast( - CustomData_get_layer_n(&result->ldata, CD_MLOOPUV, int(uv_lay))); + mloopuv_layers[uv_lay] = static_cast( + CustomData_get_layer_n(&result->ldata, CD_PROP_FLOAT2, int(uv_lay))); } if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) { @@ -887,12 +887,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * const float uv_u_offset_a = float(step) * uv_u_scale; const float uv_u_offset_b = float(step + 1) * uv_u_scale; for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { - MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index]; + blender::float2 *mluv = &mloopuv_layers[uv_lay][l_index]; - mluv[quad_ord[0]].uv[0] += uv_u_offset_a; - mluv[quad_ord[1]].uv[0] += uv_u_offset_a; - mluv[quad_ord[2]].uv[0] += uv_u_offset_b; - mluv[quad_ord[3]].uv[0] += uv_u_offset_b; + mluv[quad_ord[0]][0] += uv_u_offset_a; + mluv[quad_ord[1]][0] += uv_u_offset_a; + mluv[quad_ord[2]][0] += uv_u_offset_b; + mluv[quad_ord[3]][0] += uv_u_offset_b; } } } @@ -904,12 +904,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * const float uv_u_offset_a = float(step) * uv_u_scale; const float uv_u_offset_b = float(step + 1) * uv_u_scale; for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { - MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index]; + blender::float2 *mluv = &mloopuv_layers[uv_lay][l_index]; - copy_v2_fl2(mluv[quad_ord[0]].uv, uv_u_offset_a, uv_v_offset_a); - copy_v2_fl2(mluv[quad_ord[1]].uv, uv_u_offset_a, uv_v_offset_b); - copy_v2_fl2(mluv[quad_ord[2]].uv, uv_u_offset_b, uv_v_offset_b); - copy_v2_fl2(mluv[quad_ord[3]].uv, uv_u_offset_b, uv_v_offset_a); + copy_v2_fl2(mluv[quad_ord[0]], uv_u_offset_a, uv_v_offset_a); + copy_v2_fl2(mluv[quad_ord[1]], uv_u_offset_a, uv_v_offset_b); + copy_v2_fl2(mluv[quad_ord[2]], uv_u_offset_b, uv_v_offset_b); + copy_v2_fl2(mluv[quad_ord[3]], uv_u_offset_b, uv_v_offset_a); } } } diff --git a/source/blender/modifiers/intern/MOD_util.cc b/source/blender/modifiers/intern/MOD_util.cc index 321478d8470..9826987a15d 100644 --- a/source/blender/modifiers/intern/MOD_util.cc +++ b/source/blender/modifiers/intern/MOD_util.cc @@ -91,17 +91,16 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, /* UVs need special handling, since they come from faces */ if (texmapping == MOD_DISP_MAP_UV) { - if (CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) { + if (CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) { const MPoly *mpoly = BKE_mesh_polys(mesh); const MPoly *mp; const MLoop *mloop = BKE_mesh_loops(mesh); BLI_bitmap *done = BLI_BITMAP_NEW(verts_num, __func__); const int polys_num = mesh->totpoly; char uvname[MAX_CUSTOMDATA_LAYER_NAME]; - - CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, dmd->uvlayer_name, uvname); - const MLoopUV *mloop_uv = static_cast( - CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname)); + CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, dmd->uvlayer_name, uvname); + const float(*mloop_uv)[2] = static_cast( + CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname)); /* verts are given the UV from the first face that uses them */ for (i = 0, mp = mpoly; i < polys_num; i++, mp++) { @@ -113,8 +112,8 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd, if (!BLI_BITMAP_TEST(done, vidx)) { /* remap UVs from [0, 1] to [-1, 1] */ - r_texco[vidx][0] = (mloop_uv[lidx].uv[0] * 2.0f) - 1.0f; - r_texco[vidx][1] = (mloop_uv[lidx].uv[1] * 2.0f) - 1.0f; + r_texco[vidx][0] = (mloop_uv[lidx][0] * 2.0f) - 1.0f; + r_texco[vidx][1] = (mloop_uv[lidx][1] * 2.0f) - 1.0f; BLI_BITMAP_ENABLE(done, vidx); } diff --git a/source/blender/modifiers/intern/MOD_uvproject.cc b/source/blender/modifiers/intern/MOD_uvproject.cc index 61e584eaf9d..20b5d45ebcc 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.cc +++ b/source/blender/modifiers/intern/MOD_uvproject.cc @@ -55,7 +55,7 @@ static void initData(ModifierData *md) static void requiredDataMask(ModifierData * /*md*/, CustomData_MeshMasks *r_cddata_masks) { /* ask for UV coordinates */ - r_cddata_masks->lmask |= CD_MASK_MLOOPUV; + r_cddata_masks->lmask |= CD_MASK_PROP_FLOAT2; } static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData) @@ -118,13 +118,13 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, /* Create a new layer if no UV Maps are available * (e.g. if a preceding modifier could not preserve it). */ - if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) { + if (!CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) { CustomData_add_layer_named( - &mesh->ldata, CD_MLOOPUV, CD_SET_DEFAULT, nullptr, mesh->totloop, umd->uvlayer_name); + &mesh->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, mesh->totloop, umd->uvlayer_name); } /* make sure we're using an existing layer */ - CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname); + CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, umd->uvlayer_name, uvname); /* calculate a projection matrix and normal for each projector */ for (i = 0; i < projectors_num; i++) { @@ -185,8 +185,8 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, loops_num = mesh->totloop; /* make sure we are not modifying the original UV map */ - MLoopUV *mloop_uv = static_cast( - CustomData_duplicate_referenced_layer_named(&mesh->ldata, CD_MLOOPUV, uvname, loops_num)); + float(*mloop_uv)[2] = static_cast(CustomData_duplicate_referenced_layer_named( + &mesh->ldata, CD_PROP_FLOAT2, uvname, loops_num)); coords = BKE_mesh_vert_coords_alloc(mesh, &verts_num); @@ -214,7 +214,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, uint lidx = mp->loopstart + fidx; uint vidx = loops[lidx].v; BLI_uvproject_from_camera( - mloop_uv[lidx].uv, coords[vidx], static_cast(projectors[0].uci)); + mloop_uv[lidx], coords[vidx], static_cast(projectors[0].uci)); } while (fidx--); } else { @@ -223,7 +223,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, do { uint lidx = mp->loopstart + fidx; uint vidx = loops[lidx].v; - copy_v2_v2(mloop_uv[lidx].uv, coords[vidx]); + copy_v2_v2(mloop_uv[lidx], coords[vidx]); } while (fidx--); } } @@ -257,7 +257,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, uint lidx = mp->loopstart + fidx; uint vidx = loops[lidx].v; BLI_uvproject_from_camera( - mloop_uv[lidx].uv, coords[vidx], static_cast(best_projector->uci)); + mloop_uv[lidx], coords[vidx], static_cast(best_projector->uci)); } while (fidx--); } else { @@ -265,7 +265,7 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, do { uint lidx = mp->loopstart + fidx; uint vidx = loops[lidx].v; - mul_v2_project_m4_v3(mloop_uv[lidx].uv, best_projector->projmat, coords[vidx]); + mul_v2_project_m4_v3(mloop_uv[lidx], best_projector->projmat, coords[vidx]); } while (fidx--); } } diff --git a/source/blender/modifiers/intern/MOD_uvwarp.cc b/source/blender/modifiers/intern/MOD_uvwarp.cc index 0954165d656..ff036597f01 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.cc +++ b/source/blender/modifiers/intern/MOD_uvwarp.cc @@ -82,7 +82,7 @@ static void matrix_from_obj_pchan(float mat[4][4], Object *ob, const char *bonen struct UVWarpData { const MPoly *mpoly; const MLoop *mloop; - MLoopUV *mloopuv; + float (*mloopuv)[2]; const MDeformVert *dvert; int defgrp_index; @@ -99,7 +99,7 @@ static void uv_warp_compute(void *__restrict userdata, const MPoly *mp = &data->mpoly[i]; const MLoop *ml = &data->mloop[mp->loopstart]; - MLoopUV *mluv = &data->mloopuv[mp->loopstart]; + float(*mluv)[2] = &data->mloopuv[mp->loopstart]; const MDeformVert *dvert = data->dvert; const int defgrp_index = data->defgrp_index; @@ -115,13 +115,13 @@ static void uv_warp_compute(void *__restrict userdata, 1.0f - BKE_defvert_find_weight(&dvert[ml->v], defgrp_index) : BKE_defvert_find_weight(&dvert[ml->v], defgrp_index); - uv_warp_from_mat4_pair(uv, mluv->uv, warp_mat); - interp_v2_v2v2(mluv->uv, mluv->uv, uv, weight); + uv_warp_from_mat4_pair(uv, (*mluv), warp_mat); + interp_v2_v2v2((*mluv), (*mluv), uv, weight); } } else { for (l = 0; l < mp->totloop; l++, mluv++) { - uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat); + uv_warp_from_mat4_pair(*mluv, *mluv, warp_mat); } } } @@ -139,7 +139,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * const bool invert_vgroup = (umd->flag & MOD_UVWARP_INVERT_VGROUP) != 0; /* make sure there are UV Maps available */ - if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) { + if (!CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) { return mesh; } @@ -190,7 +190,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * translate_m4(warp_mat, -umd->center[0], -umd->center[1], 0.0f); /* make sure we're using an existing layer */ - CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname); + CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, umd->uvlayer_name, uvname); const MPoly *polys = BKE_mesh_polys(mesh); const MLoop *loops = BKE_mesh_loops(mesh); @@ -198,8 +198,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * loops_num = mesh->totloop; /* make sure we are not modifying the original UV map */ - MLoopUV *mloopuv = static_cast( - CustomData_duplicate_referenced_layer_named(&mesh->ldata, CD_MLOOPUV, uvname, loops_num)); + float(*mloopuv)[2] = static_cast(CustomData_duplicate_referenced_layer_named( + &mesh->ldata, CD_PROP_FLOAT2, uvname, loops_num)); MOD_get_vgroup(ctx->object, mesh, umd->vgroup_name, &dvert, &defgrp_index); UVWarpData data{}; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc index f0993da1ba2..e18f6601f37 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_ico_sphere.cc @@ -40,7 +40,11 @@ static Mesh *create_ico_sphere_mesh(const int subdivisions, bmesh_create_params.use_toolflags = true; const BMAllocTemplate allocsize = {0, 0, 0, 0}; BMesh *bm = BM_mesh_create(&allocsize, &bmesh_create_params); - BM_data_layer_add_named(bm, &bm->ldata, CD_MLOOPUV, nullptr); + BM_data_layer_add_named(bm, &bm->ldata, CD_PROP_FLOAT2, "UVMap"); + /* Make sure the associated boolean layers exists as well. Normally this would be done when + * adding a UV layer via python or when copying from Mesh, but when we 'manually' create the UV + * layer we need to make sure the boolean layers exist as well. */ + BM_uv_map_ensure_select_and_pin_attrs(bm); BMO_op_callf(bm, BMO_FLAG_DEFAULTS, diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index 1288083f8e7..e1708037095 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -360,7 +360,7 @@ static PyGetSetDef bpy_bmlayeraccess_loop_getseters[] = { (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, bpy_bmlayeraccess_collection__uv_doc, - (void *)CD_MLOOPUV}, + (void *)CD_PROP_FLOAT2}, {"color", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, @@ -462,6 +462,12 @@ static PyObject *bpy_bmlayercollection_verify(BPy_BMLayerCollection *self) BM_data_layer_add(self->bm, data, self->type); index = 0; } + if (self->type == CD_PROP_FLOAT2 && self->htype == BM_LOOP) { + /* Because adding CustomData layers to a bmesh will invalidate any existing pointers + * in Py objects we can't lazily add the associated bool layers. So add them all right + * now. */ + BM_uv_map_ensure_select_and_pin_attrs(self->bm); + } BLI_assert(index >= 0); @@ -503,6 +509,13 @@ static PyObject *bpy_bmlayercollection_new(BPy_BMLayerCollection *self, PyObject BM_data_layer_add(self->bm, data, self->type); } + if (self->type == CD_PROP_FLOAT2 && self->htype == BM_LOOP) { + /* Because adding CustomData layers to a bmesh will invalidate any existing pointers + * in Py objects we can't lazily add the associated bool layers. So add them all right + * now. */ + BM_uv_map_ensure_select_and_pin_attrs(self->bm); + } + index = CustomData_number_of_layers(data, self->type) - 1; BLI_assert(index >= 0); @@ -1131,8 +1144,12 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer) ret = PyBytes_FromStringAndSize(mstring->s, mstring->s_len); break; } - case CD_MLOOPUV: { - ret = BPy_BMLoopUV_CreatePyObject(value); + case CD_PROP_FLOAT2: { + if (UNLIKELY(py_ele->bm != py_layer->bm)) { + PyErr_SetString(PyExc_ValueError, "BMElem[layer]: layer is from another mesh"); + return NULL; + } + ret = BPy_BMLoopUV_CreatePyObject(py_ele->bm, (BMLoop *)py_ele->ele); break; } case CD_PROP_BYTE_COLOR: { @@ -1233,8 +1250,14 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj } break; } - case CD_MLOOPUV: { - ret = BPy_BMLoopUV_AssignPyObject(value, py_value); + case CD_PROP_FLOAT2: { + if (UNLIKELY(py_ele->bm != py_layer->bm)) { + PyErr_SetString(PyExc_ValueError, "BMElem[layer]: layer is from another mesh"); + ret = -1; + } + else { + ret = BPy_BMLoopUV_AssignPyObject(py_ele->bm, (BMLoop *)py_ele->ele, py_value); + } break; } case CD_PROP_BYTE_COLOR: { diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.c b/source/blender/python/bmesh/bmesh_py_types_meshdata.c index a627aa06e63..673adacfdde 100644 --- a/source/blender/python/bmesh/bmesh_py_types_meshdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.c @@ -5,7 +5,15 @@ * \ingroup pybmesh * * This file defines custom-data types which can't be accessed as primitive - * python types such as #MDeformVert, #MLoopUV. + * Python types such as #MDeformVert. It also exposed UV map data in a way + * compatible with the (deprecated) #MLoopUV type. + * MLoopUV used to be a struct containing both the UV information and various + * selection flags. This has since been split up into a float2 attribute + * and three boolean attributes for the selection/pin states. + * For backwards compatibility, the original #MLoopUV is emulated in the + * python API. This comes at a performance penalty however, and the plan is + * to provide direct access to the boolean layers for faster access. Eventually + * (probably in 4.0) #BPy_BMLoopUV should be removed on the Python side as well. */ #include @@ -15,12 +23,15 @@ #include "DNA_meshdata_types.h" #include "DNA_object_types.h" +#include "BKE_customdata.h" + #include "BLI_math_base.h" #include "BLI_math_vector.h" #include "BLI_utildefines.h" #include "BKE_deform.h" +#include "bmesh.h" #include "bmesh_py_types_meshdata.h" #include "../generic/py_capi_utils.h" @@ -33,72 +44,124 @@ typedef struct BPy_BMLoopUV { PyObject_VAR_HEAD - MLoopUV *data; + float *uv; + /* vert_select, edge_select and pin could be NULL, signifying those layers don't exist. + * Currently those layers are always created on a BMesh because adding layers to an existing + * BMesh is slow and invalidates existing python objects having pointers into the original + * datablocks (adding a layer re-generates all blocks). But eventually the plan is to lazily + * allocate the bool layers 'on demand'. Therefore the code tries to handle all cases where + * the layers don't exist. */ + bool *vert_select; + bool *edge_select; + bool *pin; + BMLoop *loop; } BPy_BMLoopUV; PyDoc_STRVAR(bpy_bmloopuv_uv_doc, "Loops UV (as a 2D Vector).\n\n:type: :class:`mathutils.Vector`"); static PyObject *bpy_bmloopuv_uv_get(BPy_BMLoopUV *self, void *UNUSED(closure)) { - return Vector_CreatePyObject_wrap(self->data->uv, 2, NULL); + return Vector_CreatePyObject_wrap(self->uv, 2, NULL); } static int bpy_bmloopuv_uv_set(BPy_BMLoopUV *self, PyObject *value, void *UNUSED(closure)) { float tvec[2]; if (mathutils_array_parse(tvec, 2, 2, value, "BMLoopUV.uv") != -1) { - copy_v2_v2(self->data->uv, tvec); + copy_v2_v2(self->uv, tvec); return 0; } return -1; } -PyDoc_STRVAR(bpy_bmloopuv_flag__pin_uv_doc, "UV pin state.\n\n:type: boolean"); -PyDoc_STRVAR(bpy_bmloopuv_flag__select_doc, "UV select state.\n\n:type: boolean"); -PyDoc_STRVAR(bpy_bmloopuv_flag__select_edge_doc, "UV edge select state.\n\n:type: boolean"); +PyDoc_STRVAR(bpy_bmloopuv_pin_uv_doc, "UV pin state.\n\n:type: boolean"); +PyDoc_STRVAR(bpy_bmloopuv_select_doc, "UV select state.\n\n:type: boolean"); +PyDoc_STRVAR(bpy_bmloopuv_select_edge_doc, "UV edge select state.\n\n:type: boolean"); -static PyObject *bpy_bmloopuv_flag_get(BPy_BMLoopUV *self, void *flag_p) +static PyObject *bpy_bmloopuv_pin_uv_get(BPy_BMLoopUV *self, void *UNUSED(closure)) { - const int flag = POINTER_AS_INT(flag_p); - return PyBool_FromLong(self->data->flag & flag); + /* A non existing pin layer means nothing is currently pinned */ + return self->pin ? PyBool_FromLong(*self->pin) : false; } -static int bpy_bmloopuv_flag_set(BPy_BMLoopUV *self, PyObject *value, void *flag_p) +static int bpy_bmloopuv_pin_uv_set(BPy_BMLoopUV *self, PyObject *value, void *UNUSED(closure)) { - const int flag = POINTER_AS_INT(flag_p); - - switch (PyC_Long_AsBool(value)) { - case true: - self->data->flag |= flag; - return 0; - case false: - self->data->flag &= ~flag; - return 0; - default: - /* error is set */ - return -1; + /* TODO: if we add lazy allocation of the associated uv map bool layers to BMesh we need + * to add a pin layer and update self->pin in the case of self->pin being NULL. + * This isn't easy to do currently as adding CustomData layers to a BMesh invalidates + * existing python objects. So for now lazy allocation isn't done and self->pin should + * never be NULL. */ + BLI_assert(self->pin); + if (self->pin) { + *self->pin = PyC_Long_AsBool(value); } + else { + PyErr_SetString(PyExc_RuntimeError, + "active uv layer has no associated pin layer. This is a bug!"); + return -1; + } + return 0; +} + +static PyObject *bpy_bmloopuv_select_get(BPy_BMLoopUV *self, void *UNUSED(closure)) +{ + /* A non existing vert_select layer means nothing is currently selected */ + return self->vert_select ? PyBool_FromLong(*self->vert_select) : false; +} +static int bpy_bmloopuv_select_set(BPy_BMLoopUV *self, PyObject *value, void *UNUSED(closure)) +{ + /* TODO: see comment above on bpy_bmloopuv_pin_uv_set(), the same applies here. */ + BLI_assert(self->vert_select); + if (self->vert_select) { + *self->vert_select = PyC_Long_AsBool(value); + } + else { + PyErr_SetString(PyExc_RuntimeError, + "active uv layer has no associated vertex selection layer. This is a bug!"); + return -1; + } + return 0; +} + +static PyObject *bpy_bmloopuv_select_edge_get(BPy_BMLoopUV *self, void *UNUSED(closure)) +{ + /* A non existing edge_select layer means nothing is currently selected */ + return self->edge_select ? PyBool_FromLong(*self->edge_select) : false; +} +static int bpy_bmloopuv_select_edge_set(BPy_BMLoopUV *self, PyObject *value, void *UNUSED(closure)) +{ + /* TODO: see comment above on bpy_bmloopuv_pin_uv_set(), the same applies here. */ + BLI_assert(self->edge_select); + if (self->edge_select) { + *self->edge_select = PyC_Long_AsBool(value); + } + else { + PyErr_SetString(PyExc_RuntimeError, + "active uv layer has no associated edge selection layer. This is a bug!"); + return -1; + } + return 0; } static PyGetSetDef bpy_bmloopuv_getseters[] = { /* attributes match rna_def_mloopuv. */ {"uv", (getter)bpy_bmloopuv_uv_get, (setter)bpy_bmloopuv_uv_set, bpy_bmloopuv_uv_doc, NULL}, {"pin_uv", - (getter)bpy_bmloopuv_flag_get, - (setter)bpy_bmloopuv_flag_set, - bpy_bmloopuv_flag__pin_uv_doc, - (void *)MLOOPUV_PINNED}, + (getter)bpy_bmloopuv_pin_uv_get, + (setter)bpy_bmloopuv_pin_uv_set, + bpy_bmloopuv_pin_uv_doc, + NULL}, {"select", - (getter)bpy_bmloopuv_flag_get, - (setter)bpy_bmloopuv_flag_set, - bpy_bmloopuv_flag__select_doc, - (void *)MLOOPUV_VERTSEL}, + (getter)bpy_bmloopuv_select_get, + (setter)bpy_bmloopuv_select_set, + bpy_bmloopuv_select_doc, + NULL}, {"select_edge", - (getter)bpy_bmloopuv_flag_get, - (setter)bpy_bmloopuv_flag_set, - bpy_bmloopuv_flag__select_edge_doc, - (void *)MLOOPUV_EDGESEL}, + (getter)bpy_bmloopuv_select_edge_get, + (setter)bpy_bmloopuv_select_edge_set, + bpy_bmloopuv_select_edge_doc, + NULL}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; @@ -120,21 +183,45 @@ static void bm_init_types_bmloopuv(void) PyType_Ready(&BPy_BMLoopUV_Type); } -int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *mloopuv, PyObject *value) +int BPy_BMLoopUV_AssignPyObject(struct BMesh *bm, BMLoop *loop, PyObject *value) { if (UNLIKELY(!BPy_BMLoopUV_Check(value))) { PyErr_Format(PyExc_TypeError, "expected BMLoopUV, not a %.200s", Py_TYPE(value)->tp_name); return -1; } - *((MLoopUV *)mloopuv) = *(((BPy_BMLoopUV *)value)->data); + BPy_BMLoopUV *src = (BPy_BMLoopUV *)value; + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); + + float *luv = BM_ELEM_CD_GET_FLOAT_P(loop, offsets.uv); + copy_v2_v2(luv, src->uv); + + if (src->vert_select) { + BM_ELEM_CD_SET_BOOL(loop, offsets.select_vert, *src->vert_select); + } + + if (src->edge_select) { + BM_ELEM_CD_SET_BOOL(loop, offsets.select_edge, *src->edge_select); + } + if (src->pin) { + BM_ELEM_CD_SET_BOOL(loop, offsets.pin, *src->pin); + } return 0; } -PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *mloopuv) +PyObject *BPy_BMLoopUV_CreatePyObject(struct BMesh *bm, BMLoop *loop) { BPy_BMLoopUV *self = PyObject_New(BPy_BMLoopUV, &BPy_BMLoopUV_Type); - self->data = mloopuv; + + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); + + self->uv = BM_ELEM_CD_GET_FLOAT_P(loop, offsets.uv); + self->vert_select = offsets.select_vert >= 0 ? BM_ELEM_CD_GET_BOOL_P(loop, offsets.select_vert) : + NULL; + self->edge_select = offsets.select_edge >= 0 ? BM_ELEM_CD_GET_BOOL_P(loop, offsets.select_edge) : + NULL; + self->pin = offsets.pin >= 0 ? BM_ELEM_CD_GET_BOOL_P(loop, offsets.pin) : NULL; + return (PyObject *)self; } diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.h b/source/blender/python/bmesh/bmesh_py_types_meshdata.h index c349f7a9962..620977a834a 100644 --- a/source/blender/python/bmesh/bmesh_py_types_meshdata.h +++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.h @@ -19,11 +19,11 @@ typedef struct BPy_BMGenericMeshData { struct MDeformVert; struct MLoopCol; -struct MLoopUV; struct MVertSkin; +struct BMesh; -int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *mloopuv, PyObject *value); -PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *mloopuv); +int BPy_BMLoopUV_AssignPyObject(struct BMesh *bm, BMLoop *loop, PyObject *value); +PyObject *BPy_BMLoopUV_CreatePyObject(struct BMesh *bm, BMLoop *loop); int BPy_BMVertSkin_AssignPyObject(struct MVertSkin *mvertskin, PyObject *value); PyObject *BPy_BMVertSkin_CreatePyObject(struct MVertSkin *mvertskin); diff --git a/source/blender/render/RE_bake.h b/source/blender/render/RE_bake.h index ebfc7509504..717c5053a38 100644 --- a/source/blender/render/RE_bake.h +++ b/source/blender/render/RE_bake.h @@ -11,7 +11,6 @@ struct Depsgraph; struct ImBuf; -struct MLoopUV; struct Mesh; struct Render; diff --git a/source/blender/render/RE_texture_margin.h b/source/blender/render/RE_texture_margin.h index 023615cea87..fd8e41adb3a 100644 --- a/source/blender/render/RE_texture_margin.h +++ b/source/blender/render/RE_texture_margin.h @@ -13,7 +13,6 @@ extern "C" { struct DerivedMesh; struct IMBuf; struct ImBuf; -struct MLoopUV; struct Mesh; /** diff --git a/source/blender/render/intern/bake.cc b/source/blender/render/intern/bake.cc index 8b598ceb6a0..e1fc33a4b9d 100644 --- a/source/blender/render/intern/bake.cc +++ b/source/blender/render/intern/bake.cc @@ -714,13 +714,13 @@ void RE_bake_pixels_populate(Mesh *me, const BakeTargets *targets, const char *uv_layer) { - const MLoopUV *mloopuv; + const float(*mloopuv)[2]; if ((uv_layer == nullptr) || (uv_layer[0] == '\0')) { - mloopuv = static_cast(CustomData_get_layer(&me->ldata, CD_MLOOPUV)); + mloopuv = static_cast(CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2)); } else { - int uv_id = CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer); - mloopuv = static_cast(CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uv_id)); + int uv_id = CustomData_get_named_layer(&me->ldata, CD_PROP_FLOAT2, uv_layer); + mloopuv = static_cast(CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, uv_id)); } if (mloopuv == nullptr) { @@ -771,7 +771,7 @@ void RE_bake_pixels_populate(Mesh *me, /* Compute triangle vertex UV coordinates. */ float vec[3][2]; for (int a = 0; a < 3; a++) { - const float *uv = mloopuv[lt->tri[a]].uv; + const float *uv = mloopuv[lt->tri[a]]; /* NOTE(@campbellbarton): workaround for pixel aligned UVs which are common and can screw * up our intersection tests where a pixel gets in between 2 faces or the middle of a quad, diff --git a/source/blender/render/intern/multires_bake.cc b/source/blender/render/intern/multires_bake.cc index c5154e8017a..2d696788069 100644 --- a/source/blender/render/intern/multires_bake.cc +++ b/source/blender/render/intern/multires_bake.cc @@ -65,7 +65,7 @@ struct MResolvePixelData { MPoly *mpoly; const int *material_indices; MLoop *mloop; - MLoopUV *mloopuv; + float (*mloopuv)[2]; float uv_offset[2]; const MLoopTri *mlooptri; float *pvtangent; @@ -159,9 +159,9 @@ static void flush_pixel(const MResolvePixelData *data, const int x, const int y) float u, v, w, sign; int r; - st0 = data->mloopuv[data->mlooptri[data->tri_index].tri[0]].uv; - st1 = data->mloopuv[data->mlooptri[data->tri_index].tri[1]].uv; - st2 = data->mloopuv[data->mlooptri[data->tri_index].tri[2]].uv; + st0 = data->mloopuv[data->mlooptri[data->tri_index].tri[0]]; + st1 = data->mloopuv[data->mlooptri[data->tri_index].tri[1]]; + st2 = data->mloopuv[data->mlooptri[data->tri_index].tri[2]]; multiresbake_get_normal(data, data->tri_index, 0, no0); /* can optimize these 3 into one call */ multiresbake_get_normal(data, data->tri_index, 1, no1); @@ -384,7 +384,7 @@ static void *do_multires_bake_thread(void *data_v) while ((tri_index = multires_bake_queue_next_tri(handle->queue)) >= 0) { const MLoopTri *lt = &data->mlooptri[tri_index]; const short mat_nr = data->material_indices == nullptr ? 0 : data->material_indices[lt->poly]; - const MLoopUV *mloopuv = data->mloopuv; + const float(*mloopuv)[2] = data->mloopuv; if (multiresbake_test_break(bkr)) { break; @@ -398,9 +398,9 @@ static void *do_multires_bake_thread(void *data_v) data->tri_index = tri_index; float uv[3][2]; - sub_v2_v2v2(uv[0], mloopuv[lt->tri[0]].uv, data->uv_offset); - sub_v2_v2v2(uv[1], mloopuv[lt->tri[1]].uv, data->uv_offset); - sub_v2_v2v2(uv[2], mloopuv[lt->tri[2]].uv, data->uv_offset); + sub_v2_v2v2(uv[0], mloopuv[lt->tri[0]], data->uv_offset); + sub_v2_v2v2(uv[1], mloopuv[lt->tri[1]], data->uv_offset); + sub_v2_v2v2(uv[2], mloopuv[lt->tri[2]], data->uv_offset); bake_rasterize(bake_rast, uv[0], uv[1], uv[2]); @@ -475,7 +475,7 @@ static void do_multires_bake(MultiresBakeRender *bkr, const float(*positions)[3] = (float(*)[3])dm->getVertArray(dm); MPoly *mpoly = dm->getPolyArray(dm); MLoop *mloop = dm->getLoopArray(dm); - MLoopUV *mloopuv = static_cast(dm->getLoopDataArray(dm, CD_MLOOPUV)); + float(*mloopuv)[2] = static_cast(dm->getLoopDataArray(dm, CD_PROP_FLOAT2)); float *pvtangent = nullptr; ListBase threads; @@ -838,7 +838,8 @@ static void apply_heights_callback(DerivedMesh *lores_dm, const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index; MLoop *mloop = lores_dm->getLoopArray(lores_dm); MPoly *mpoly = lores_dm->getPolyArray(lores_dm) + lt->poly; - MLoopUV *mloopuv = static_cast(lores_dm->getLoopDataArray(lores_dm, CD_MLOOPUV)); + float(*mloopuv)[2] = static_cast( + lores_dm->getLoopDataArray(lores_dm, CD_PROP_FLOAT2)); MHeightBakeData *height_data = (MHeightBakeData *)bake_data; MultiresBakeThread *thread_data = (MultiresBakeThread *)thread_data_v; float uv[2], *st0, *st1, *st2, *st3; @@ -848,16 +849,16 @@ static void apply_heights_callback(DerivedMesh *lores_dm, /* ideally we would work on triangles only, however, we rely on quads to get orthogonal * coordinates for use in grid space (triangle barycentric is not orthogonal) */ if (mpoly->totloop == 4) { - st0 = mloopuv[mpoly->loopstart].uv; - st1 = mloopuv[mpoly->loopstart + 1].uv; - st2 = mloopuv[mpoly->loopstart + 2].uv; - st3 = mloopuv[mpoly->loopstart + 3].uv; + st0 = mloopuv[mpoly->loopstart]; + st1 = mloopuv[mpoly->loopstart + 1]; + st2 = mloopuv[mpoly->loopstart + 2]; + st3 = mloopuv[mpoly->loopstart + 3]; resolve_quad_uv_v2(uv, st, st0, st1, st2, st3); } else { - st0 = mloopuv[lt->tri[0]].uv; - st1 = mloopuv[lt->tri[1]].uv; - st2 = mloopuv[lt->tri[2]].uv; + st0 = mloopuv[lt->tri[0]]; + st1 = mloopuv[lt->tri[1]]; + st2 = mloopuv[lt->tri[2]]; resolve_tri_uv_v2(uv, st, st0, st1, st2); } @@ -952,7 +953,8 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm, { const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index; MPoly *mpoly = lores_dm->getPolyArray(lores_dm) + lt->poly; - MLoopUV *mloopuv = static_cast(lores_dm->getLoopDataArray(lores_dm, CD_MLOOPUV)); + float(*mloopuv)[2] = static_cast( + lores_dm->getLoopDataArray(lores_dm, CD_PROP_FLOAT2)); MNormalBakeData *normal_data = (MNormalBakeData *)bake_data; float uv[2], *st0, *st1, *st2, *st3; int pixel = ibuf->x * y + x; @@ -961,16 +963,16 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm, /* ideally we would work on triangles only, however, we rely on quads to get orthogonal * coordinates for use in grid space (triangle barycentric is not orthogonal) */ if (mpoly->totloop == 4) { - st0 = mloopuv[mpoly->loopstart].uv; - st1 = mloopuv[mpoly->loopstart + 1].uv; - st2 = mloopuv[mpoly->loopstart + 2].uv; - st3 = mloopuv[mpoly->loopstart + 3].uv; + st0 = mloopuv[mpoly->loopstart]; + st1 = mloopuv[mpoly->loopstart + 1]; + st2 = mloopuv[mpoly->loopstart + 2]; + st3 = mloopuv[mpoly->loopstart + 3]; resolve_quad_uv_v2(uv, st, st0, st1, st2, st3); } else { - st0 = mloopuv[lt->tri[0]].uv; - st1 = mloopuv[lt->tri[1]].uv; - st2 = mloopuv[lt->tri[2]].uv; + st0 = mloopuv[lt->tri[0]]; + st1 = mloopuv[lt->tri[1]]; + st2 = mloopuv[lt->tri[2]]; resolve_tri_uv_v2(uv, st, st0, st1, st2); } @@ -1213,7 +1215,7 @@ static void apply_ao_callback(DerivedMesh *lores_dm, { const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index; MPoly *mpoly = lores_dm->getPolyArray(lores_dm) + lt->poly; - MLoopUV *mloopuv = lores_dm->getLoopDataArray(lores_dm, CD_MLOOPUV); + float (*mloopuv)[2] = lores_dm->getLoopDataArray(lores_dm, CD_PROP_FLOAT2); MAOBakeData *ao_data = (MAOBakeData *)bake_data; int i, k, perm_ofs; @@ -1228,16 +1230,16 @@ static void apply_ao_callback(DerivedMesh *lores_dm, /* ideally we would work on triangles only, however, we rely on quads to get orthogonal * coordinates for use in grid space (triangle barycentric is not orthogonal) */ if (mpoly->totloop == 4) { - st0 = mloopuv[mpoly->loopstart].uv; - st1 = mloopuv[mpoly->loopstart + 1].uv; - st2 = mloopuv[mpoly->loopstart + 2].uv; - st3 = mloopuv[mpoly->loopstart + 3].uv; + st0 = mloopuv[mpoly->loopstart]; + st1 = mloopuv[mpoly->loopstart + 1]; + st2 = mloopuv[mpoly->loopstart + 2]; + st3 = mloopuv[mpoly->loopstart + 3]; resolve_quad_uv_v2(uv, st, st0, st1, st2, st3); } else { - st0 = mloopuv[lt->tri[0]].uv; - st1 = mloopuv[lt->tri[1]].uv; - st2 = mloopuv[lt->tri[2]].uv; + st0 = mloopuv[lt->tri[0]]; + st1 = mloopuv[lt->tri[1]]; + st2 = mloopuv[lt->tri[2]]; resolve_tri_uv_v2(uv, st, st0, st1, st2); } diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc index 472a75bae66..a04f1cd75c4 100644 --- a/source/blender/render/intern/texture_margin.cc +++ b/source/blender/render/intern/texture_margin.cc @@ -56,7 +56,7 @@ class TextureMarginMap { MPoly const *mpoly_; MLoop const *mloop_; - MLoopUV const *mloopuv_; + float2 const *mloopuv_; int totpoly_; int totloop_; int totedge_; @@ -67,7 +67,7 @@ class TextureMarginMap { const float uv_offset[2], MPoly const *mpoly, MLoop const *mloop, - MLoopUV const *mloopuv, + float2 const *mloopuv, int totpoly, int totloop, int totedge) @@ -280,11 +280,11 @@ class TextureMarginMap { } private: - float2 uv_to_xy(MLoopUV const &mloopuv) const + float2 uv_to_xy(const float2 &mloopuv) const { float2 ret; - ret.x = (((mloopuv.uv[0] - uv_offset_[0]) * w_) - (0.5f + 0.001f)); - ret.y = (((mloopuv.uv[1] - uv_offset_[1]) * h_) - (0.5f + 0.001f)); + ret.x = (((mloopuv[0] - uv_offset_[0]) * w_) - (0.5f + 0.001f)); + ret.y = (((mloopuv[1] - uv_offset_[1]) * h_) - (0.5f + 0.001f)); return ret; } @@ -489,7 +489,7 @@ static void generate_margin(ImBuf *ibuf, const MPoly *mpoly; const MLoop *mloop; - const MLoopUV *mloopuv; + const float2 *mloopuv; int totpoly, totloop, totedge; int tottri; @@ -505,12 +505,12 @@ static void generate_margin(ImBuf *ibuf, mloop = me->loops().data(); if ((uv_layer == nullptr) || (uv_layer[0] == '\0')) { - mloopuv = static_cast(CustomData_get_layer(&me->ldata, CD_MLOOPUV)); + mloopuv = static_cast(CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2)); } else { - int uv_id = CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer); - mloopuv = static_cast( - CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uv_id)); + int uv_id = CustomData_get_named_layer(&me->ldata, CD_PROP_FLOAT2, uv_layer); + mloopuv = static_cast( + CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, uv_id)); } tottri = poly_to_tri_count(me->totpoly, me->totloop); @@ -531,7 +531,7 @@ static void generate_margin(ImBuf *ibuf, totloop = dm->getNumLoops(dm); mpoly = dm->getPolyArray(dm); mloop = dm->getLoopArray(dm); - mloopuv = (MLoopUV const *)dm->getLoopDataArray(dm, CD_MLOOPUV); + mloopuv = static_cast(dm->getLoopDataArray(dm, CD_PROP_FLOAT2)); looptri = dm->getLoopTriArray(dm); tottri = dm->getNumLoopTri(dm); @@ -556,7 +556,7 @@ static void generate_margin(ImBuf *ibuf, float vec[3][2]; for (int a = 0; a < 3; a++) { - const float *uv = mloopuv[lt->tri[a]].uv; + const float *uv = mloopuv[lt->tri[a]]; /* NOTE(@campbellbarton): workaround for pixel aligned UVs which are common and can screw up * our intersection tests where a pixel gets in between 2 faces or the middle of a quad, From aaaa75f906ba3580b63533df82df4446ce3d1c35 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 10 Jan 2023 01:01:09 -0500 Subject: [PATCH 0555/1522] Fix: Failing test after combination of Mesh refactors The mesh positions are now a span, but the convex hull didn't copy the custom data layout to the new mesh since it assumed it didn't need to. Moving UV maps to a generic attribute triggers this difference in the test results. It doesn't really make sense for the convex hull node to copy the source mesh custom data layout at all anyway, but do it anyway to avoid having to change the tests right now. --- source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc index 549ae1e4944..84cc2b49141 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc @@ -183,7 +183,7 @@ static Mesh *compute_hull(const GeometrySet &geometry_set) /* If there is only one positions virtual array and it is already contiguous, avoid copying * all of the positions and instead pass the span directly to the convex hull function. */ if (span_count == 1 && count == 1) { - return hull_from_bullet(nullptr, positions_span); + return hull_from_bullet(geometry_set.get_mesh_for_read(), positions_span); } Array positions(total_num); From dad9f45561a1cd129d86cbdd93b883dcaef0df26 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 10 Jan 2023 17:07:30 +1100 Subject: [PATCH 0556/1522] Cleanup: move run-time members of SurfaceModifierData into a struct Using run-time members in the surface modifier complicated code-review and caused an unnecessary renaming in `dna_rename_defs.h`. Also rename: - `x` -> `vert_positions_prev`. - `v` -> `vert_velocities`. - `cfra` -> `cfra_prev`. --- source/blender/blenkernel/intern/effect.c | 17 ++-- .../blender/makesdna/DNA_modifier_defaults.h | 7 +- source/blender/makesdna/DNA_modifier_types.h | 18 ++-- .../blender/makesdna/intern/dna_rename_defs.h | 1 - source/blender/modifiers/intern/MOD_surface.c | 96 +++++++++---------- 5 files changed, 66 insertions(+), 73 deletions(-) diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 84fda9034cb..3c8b76380ee 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -644,13 +644,13 @@ bool closest_point_on_surface(SurfaceModifierData *surmd, float surface_nor[3], float surface_vel[3]) { + BVHTreeFromMesh *bvhtree = surmd->runtime.bvhtree; BVHTreeNearest nearest; nearest.index = -1; nearest.dist_sq = FLT_MAX; - BLI_bvhtree_find_nearest( - surmd->bvhtree->tree, co, &nearest, surmd->bvhtree->nearest_callback, surmd->bvhtree); + BLI_bvhtree_find_nearest(bvhtree->tree, co, &nearest, bvhtree->nearest_callback, bvhtree); if (nearest.index != -1) { copy_v3_v3(surface_co, nearest.co); @@ -660,12 +660,12 @@ bool closest_point_on_surface(SurfaceModifierData *surmd, } if (surface_vel) { - const MLoop *mloop = surmd->bvhtree->loop; - const MLoopTri *lt = &surmd->bvhtree->looptri[nearest.index]; + const MLoop *mloop = bvhtree->loop; + const MLoopTri *lt = &bvhtree->looptri[nearest.index]; - copy_v3_v3(surface_vel, surmd->v[mloop[lt->tri[0]].v]); - add_v3_v3(surface_vel, surmd->v[mloop[lt->tri[1]].v]); - add_v3_v3(surface_vel, surmd->v[mloop[lt->tri[2]].v]); + copy_v3_v3(surface_vel, surmd->runtime.vert_velocities[mloop[lt->tri[0]].v]); + add_v3_v3(surface_vel, surmd->runtime.vert_velocities[mloop[lt->tri[1]].v]); + add_v3_v3(surface_vel, surmd->runtime.vert_velocities[mloop[lt->tri[2]].v]); mul_v3_fl(surface_vel, (1.0f / 3.0f)); } @@ -684,7 +684,8 @@ bool get_effector_data(EffectorCache *eff, /* In case surface object is in Edit mode when loading the .blend, * surface modifier is never executed and bvhtree never built, see T48415. */ - if (eff->pd && eff->pd->shape == PFIELD_SHAPE_SURFACE && eff->surmd && eff->surmd->bvhtree) { + if (eff->pd && eff->pd->shape == PFIELD_SHAPE_SURFACE && eff->surmd && + eff->surmd->runtime.bvhtree) { /* closest point in the object surface is an effector */ float vec[3]; diff --git a/source/blender/makesdna/DNA_modifier_defaults.h b/source/blender/makesdna/DNA_modifier_defaults.h index 92a65a50bd4..6ba973ee4ec 100644 --- a/source/blender/makesdna/DNA_modifier_defaults.h +++ b/source/blender/makesdna/DNA_modifier_defaults.h @@ -616,12 +616,7 @@ #define _DNA_DEFAULT_SurfaceModifierData \ { \ - .x = NULL, \ - .v = NULL, \ - .mesh = NULL, \ - .bvhtree = NULL, \ - .cfra = 0, \ - .verts_num = 0, \ + /* Intentionally empty (all run-time data). */ \ } #define _DNA_DEFAULT_SurfaceDeformModifierData \ diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 170fa0b4351..aa7df999cf5 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -877,20 +877,24 @@ typedef struct CollisionModifierData { struct BVHTree *bvhtree; } CollisionModifierData; -typedef struct SurfaceModifierData { - ModifierData modifier; +typedef struct SurfaceModifierData_Runtime { - /** Old position. */ - float (*x)[3]; - /** Velocity. */ - float (*v)[3]; + float (*vert_positions_prev)[3]; + float (*vert_velocities)[3]; struct Mesh *mesh; /** Bounding volume hierarchy of the mesh faces. */ struct BVHTreeFromMesh *bvhtree; - int cfra, verts_num; + int cfra_prev, verts_num; + +} SurfaceModifierData_Runtime; + +typedef struct SurfaceModifierData { + ModifierData modifier; + + SurfaceModifierData_Runtime runtime; } SurfaceModifierData; typedef struct BooleanModifierData { diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h index 6d4592bb338..dce7d353fe6 100644 --- a/source/blender/makesdna/intern/dna_rename_defs.h +++ b/source/blender/makesdna/intern/dna_rename_defs.h @@ -125,7 +125,6 @@ DNA_STRUCT_RENAME_ELEM(SpaceSeq, overlay_type, overlay_frame_type) DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, num_mesh_verts, mesh_verts_num) DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, numpoly, target_polys_num) DNA_STRUCT_RENAME_ELEM(SurfaceDeformModifierData, numverts, bind_verts_num) -DNA_STRUCT_RENAME_ELEM(SurfaceModifierData, numverts, verts_num) DNA_STRUCT_RENAME_ELEM(Text, name, filepath) DNA_STRUCT_RENAME_ELEM(ThemeSpace, scrubbing_background, time_scrub_background) DNA_STRUCT_RENAME_ELEM(ThemeSpace, show_back_grad, background_type) diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c index ba63468d075..00fe739b49c 100644 --- a/source/blender/modifiers/intern/MOD_surface.c +++ b/source/blender/modifiers/intern/MOD_surface.c @@ -56,10 +56,7 @@ static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int BKE_modifier_copydata_generic(md_src, md_dst, flag); - surmd_dst->bvhtree = NULL; - surmd_dst->mesh = NULL; - surmd_dst->x = NULL; - surmd_dst->v = NULL; + memset(&surmd_dst->runtime, 0, sizeof(surmd_dst->runtime)); } static void freeData(ModifierData *md) @@ -67,19 +64,19 @@ static void freeData(ModifierData *md) SurfaceModifierData *surmd = (SurfaceModifierData *)md; if (surmd) { - if (surmd->bvhtree) { - free_bvhtree_from_mesh(surmd->bvhtree); - MEM_SAFE_FREE(surmd->bvhtree); + if (surmd->runtime.bvhtree) { + free_bvhtree_from_mesh(surmd->runtime.bvhtree); + MEM_SAFE_FREE(surmd->runtime.bvhtree); } - if (surmd->mesh) { - BKE_id_free(NULL, surmd->mesh); - surmd->mesh = NULL; + if (surmd->runtime.mesh) { + BKE_id_free(NULL, surmd->runtime.mesh); + surmd->runtime.mesh = NULL; } - MEM_SAFE_FREE(surmd->x); + MEM_SAFE_FREE(surmd->runtime.vert_positions_prev); - MEM_SAFE_FREE(surmd->v); + MEM_SAFE_FREE(surmd->runtime.vert_velocities); } } @@ -98,23 +95,24 @@ static void deformVerts(ModifierData *md, const int cfra = (int)DEG_get_ctime(ctx->depsgraph); /* Free mesh and BVH cache. */ - if (surmd->bvhtree) { - free_bvhtree_from_mesh(surmd->bvhtree); - MEM_SAFE_FREE(surmd->bvhtree); + if (surmd->runtime.bvhtree) { + free_bvhtree_from_mesh(surmd->runtime.bvhtree); + MEM_SAFE_FREE(surmd->runtime.bvhtree); } - if (surmd->mesh) { - BKE_id_free(NULL, surmd->mesh); - surmd->mesh = NULL; + if (surmd->runtime.mesh) { + BKE_id_free(NULL, surmd->runtime.mesh); + surmd->runtime.mesh = NULL; } if (mesh) { /* Not possible to use get_mesh() in this case as we'll modify its vertices * and get_mesh() would return 'mesh' directly. */ - surmd->mesh = (Mesh *)BKE_id_copy_ex(NULL, (ID *)mesh, NULL, LIB_ID_COPY_LOCALIZE); + surmd->runtime.mesh = (Mesh *)BKE_id_copy_ex(NULL, (ID *)mesh, NULL, LIB_ID_COPY_LOCALIZE); } else { - surmd->mesh = MOD_deform_mesh_eval_get(ctx->object, NULL, NULL, NULL, verts_num, false); + surmd->runtime.mesh = MOD_deform_mesh_eval_get( + ctx->object, NULL, NULL, NULL, verts_num, false); } if (!ctx->object->pd) { @@ -122,61 +120,61 @@ static void deformVerts(ModifierData *md, return; } - if (surmd->mesh) { + if (surmd->runtime.mesh) { uint mesh_verts_num = 0, i = 0; int init = 0; - BKE_mesh_vert_coords_apply(surmd->mesh, vertexCos); + BKE_mesh_vert_coords_apply(surmd->runtime.mesh, vertexCos); - mesh_verts_num = surmd->mesh->totvert; + mesh_verts_num = surmd->runtime.mesh->totvert; - if (mesh_verts_num != surmd->verts_num || surmd->x == NULL || surmd->v == NULL || - cfra != surmd->cfra + 1) { - if (surmd->x) { - MEM_freeN(surmd->x); - surmd->x = NULL; - } - if (surmd->v) { - MEM_freeN(surmd->v); - surmd->v = NULL; - } + if ((mesh_verts_num != surmd->runtime.verts_num) || + (surmd->runtime.vert_positions_prev == NULL) || (surmd->runtime.vert_velocities == NULL) || + (cfra != surmd->runtime.cfra_prev + 1)) { - surmd->x = MEM_calloc_arrayN(mesh_verts_num, sizeof(float[3]), __func__); - surmd->v = MEM_calloc_arrayN(mesh_verts_num, sizeof(float[3]), __func__); + MEM_SAFE_FREE(surmd->runtime.vert_positions_prev); + MEM_SAFE_FREE(surmd->runtime.vert_velocities); - surmd->verts_num = mesh_verts_num; + surmd->runtime.vert_positions_prev = MEM_calloc_arrayN( + mesh_verts_num, sizeof(float[3]), __func__); + surmd->runtime.vert_velocities = MEM_calloc_arrayN( + mesh_verts_num, sizeof(float[3]), __func__); + + surmd->runtime.verts_num = mesh_verts_num; init = 1; } /* convert to global coordinates and calculate velocity */ - float(*positions)[3] = BKE_mesh_vert_positions_for_write(surmd->mesh); + float(*positions)[3] = BKE_mesh_vert_positions_for_write(surmd->runtime.mesh); for (i = 0; i < mesh_verts_num; i++) { float *vec = positions[i]; mul_m4_v3(ctx->object->object_to_world, vec); if (init) { - surmd->v[i][0] = surmd->v[i][1] = surmd->v[i][2] = 0.0f; + zero_v3(surmd->runtime.vert_velocities[i]); } else { - sub_v3_v3v3(surmd->v[i], vec, surmd->x[i]); + sub_v3_v3v3(surmd->runtime.vert_velocities[i], vec, surmd->runtime.vert_positions_prev[i]); } - copy_v3_v3(surmd->x[i], vec); + copy_v3_v3(surmd->runtime.vert_positions_prev[i], vec); } - surmd->cfra = cfra; + surmd->runtime.cfra_prev = cfra; - const bool has_poly = surmd->mesh->totpoly > 0; - const bool has_edge = surmd->mesh->totedge > 0; + const bool has_poly = surmd->runtime.mesh->totpoly > 0; + const bool has_edge = surmd->runtime.mesh->totedge > 0; if (has_poly || has_edge) { - surmd->bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh"); + surmd->runtime.bvhtree = MEM_callocN(sizeof(BVHTreeFromMesh), "BVHTreeFromMesh"); if (has_poly) { - BKE_bvhtree_from_mesh_get(surmd->bvhtree, surmd->mesh, BVHTREE_FROM_LOOPTRI, 2); + BKE_bvhtree_from_mesh_get( + surmd->runtime.bvhtree, surmd->runtime.mesh, BVHTREE_FROM_LOOPTRI, 2); } else if (has_edge) { - BKE_bvhtree_from_mesh_get(surmd->bvhtree, surmd->mesh, BVHTREE_FROM_EDGES, 2); + BKE_bvhtree_from_mesh_get( + surmd->runtime.bvhtree, surmd->runtime.mesh, BVHTREE_FROM_EDGES, 2); } } } @@ -202,11 +200,7 @@ static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md) { SurfaceModifierData *surmd = (SurfaceModifierData *)md; - surmd->mesh = NULL; - surmd->bvhtree = NULL; - surmd->x = NULL; - surmd->v = NULL; - surmd->verts_num = 0; + memset(&surmd->runtime, 0, sizeof(surmd->runtime)); } ModifierTypeInfo modifierType_Surface = { From ed663219965bd79e410df23a1dd2b52decd9efa0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 10 Jan 2023 17:43:20 +1100 Subject: [PATCH 0557/1522] GHOST/Wayland: simplify logic for disconnecting monitors under Wayland The T103586 fix effectively ran the wl_surface_listener.leave callback to as WLROOTS based compositors doesn't run them. Remove the workaround since it's an error in WLROOTS to be fixed upstream. Temporarily using the wrong window scale when disconnecting a monitor on configurations that use different DPI per monitor is a minor enough issue that I don't think it makes sense to workaround in GHOST. --- intern/ghost/intern/GHOST_SystemWayland.cpp | 61 ++++++++++++++++----- intern/ghost/intern/GHOST_SystemWayland.h | 21 ++++++- 2 files changed, 64 insertions(+), 18 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 251466d9501..d823db2afd7 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -4534,7 +4534,7 @@ static void output_handle_scale(void *data, struct wl_output * /*wl_output*/, co CLOG_INFO(LOG, 2, "scale"); GWL_Output *output = static_cast(data); output->scale = factor; - output->system->output_scale_update_maybe_leave(output, false); + output->system->output_scale_update(output); } static const struct wl_output_listener output_listener = { @@ -4736,7 +4736,11 @@ static void gwl_registry_wl_output_remove(GWL_Display *display, if (!on_exit) { /* Needed for WLROOTS, does nothing if surface leave callbacks have already run. */ - output->system->output_scale_update_maybe_leave(output, true); + if (output->system->output_unref(output->wl_output)) { + CLOG_WARN(LOG, + "mis-behaving compositor failed to call \"surface_listener.leave\" " + "window scale may be invalid!"); + } } if (output->xdg_output) { @@ -6744,11 +6748,13 @@ void GHOST_SystemWayland::seat_active_set(const struct GWL_Seat *seat) gwl_display_seat_active_set(display_, seat); } -void GHOST_SystemWayland::window_surface_unref(const wl_surface *wl_surface) +bool GHOST_SystemWayland::window_surface_unref(const wl_surface *wl_surface) { + bool changed = false; #define SURFACE_CLEAR_PTR(surface_test) \ if (surface_test == wl_surface) { \ surface_test = nullptr; \ + changed = true; \ } \ ((void)0); @@ -6760,37 +6766,62 @@ void GHOST_SystemWayland::window_surface_unref(const wl_surface *wl_surface) SURFACE_CLEAR_PTR(seat->wl_surface_window_focus_dnd); } #undef SURFACE_CLEAR_PTR + + return changed; } -void GHOST_SystemWayland::output_scale_update_maybe_leave(GWL_Output *output, bool leave) +bool GHOST_SystemWayland::output_unref(wl_output *wl_output) { - /* Update scale, optionally leaving the outputs beforehand. */ - GHOST_WindowManager *window_manager = output->system->getWindowManager(); + bool changed = false; + if (!ghost_wl_output_own(wl_output)) { + return changed; + } + + /* NOTE: keep in sync with `output_scale_update`. */ + GWL_Output *output = ghost_wl_output_user_data(wl_output); + GHOST_WindowManager *window_manager = getWindowManager(); + if (window_manager) { + for (GHOST_IWindow *iwin : window_manager->getWindows()) { + GHOST_WindowWayland *win = static_cast(iwin); + if (win->outputs_leave(output)) { + changed = true; + } + } + } + for (GWL_Seat *seat : display_->seats) { + if (seat->pointer.outputs.erase(output)) { + changed = true; + } + if (seat->tablet.outputs.erase(output)) { + changed = true; + } + } + return changed; +} + +void GHOST_SystemWayland::output_scale_update(GWL_Output *output) +{ + /* NOTE: keep in sync with `output_unref`. */ + GHOST_WindowManager *window_manager = getWindowManager(); if (window_manager) { for (GHOST_IWindow *iwin : window_manager->getWindows()) { GHOST_WindowWayland *win = static_cast(iwin); const std::vector &outputs = win->outputs(); - bool found = leave ? win->outputs_leave(output) : - !(std::find(outputs.begin(), outputs.end(), output) == outputs.cend()); - if (found) { + if (!(std::find(outputs.begin(), outputs.end(), output) == outputs.cend())) { win->outputs_changed_update_scale(); } } } for (GWL_Seat *seat : display_->seats) { - bool found; - - found = leave ? seat->pointer.outputs.erase(output) : seat->pointer.outputs.count(output); - if (found) { + if (seat->pointer.outputs.count(output)) { if (seat->cursor.wl_surface_cursor != nullptr) { update_cursor_scale( seat->cursor, seat->system->wl_shm(), &seat->pointer, seat->cursor.wl_surface_cursor); } } - found = leave ? seat->tablet.outputs.erase(output) : seat->tablet.outputs.count(output); - if (found) { + if (seat->tablet.outputs.count(output)) { for (struct zwp_tablet_tool_v2 *zwp_tablet_tool_v2 : seat->tablet_tools) { GWL_TabletTool *tablet_tool = static_cast( zwp_tablet_tool_v2_get_user_data(zwp_tablet_tool_v2)); diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h index c102a3d7a12..c745d3b1d36 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.h +++ b/intern/ghost/intern/GHOST_SystemWayland.h @@ -194,10 +194,25 @@ class GHOST_SystemWayland : public GHOST_System { /** Set this seat to be active. */ void seat_active_set(const struct GWL_Seat *seat); - void output_scale_update_maybe_leave(GWL_Output *output, bool leave); + /** + * Clear all references to this output. + * + * \note The compositor should have already called the `wl_surface_listener.leave` callback, + * however some compositors may not (see T103586). + * So remove references to the output before it's destroyed to avoid crashing. + * + * \return true when any references were removed. + */ + bool output_unref(struct wl_output *wl_output); - /** Clear all references to this surface to prevent accessing NULL pointers. */ - void window_surface_unref(const wl_surface *wl_surface); + void output_scale_update(GWL_Output *output); + + /** + * Clear all references to this surface to prevent accessing NULL pointers. + * + * \return true when any references were removed. + */ + bool window_surface_unref(const wl_surface *wl_surface); bool window_cursor_grab_set(const GHOST_TGrabCursorMode mode, const GHOST_TGrabCursorMode mode_current, From b7f5e4b1b61653a8c50f6593df74b4aa4995ff6f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 10 Jan 2023 19:04:07 +1100 Subject: [PATCH 0558/1522] Fix building on MSVC Empty struct introduced in dad9f45561a1cd129d86cbdd93b883dcaef0df26. --- source/blender/makesdna/DNA_modifier_defaults.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesdna/DNA_modifier_defaults.h b/source/blender/makesdna/DNA_modifier_defaults.h index 6ba973ee4ec..44644d7eb78 100644 --- a/source/blender/makesdna/DNA_modifier_defaults.h +++ b/source/blender/makesdna/DNA_modifier_defaults.h @@ -616,7 +616,7 @@ #define _DNA_DEFAULT_SurfaceModifierData \ { \ - /* Intentionally empty (all run-time data). */ \ + .runtime = {NULL}, /* Include to avoid empty an struct (for MSVC). */ \ } #define _DNA_DEFAULT_SurfaceDeformModifierData \ From 6f38ce5a406ec2771090e6536d96219b2c0f3743 Mon Sep 17 00:00:00 2001 From: Pratik Borhade Date: Tue, 10 Jan 2023 15:27:57 +0530 Subject: [PATCH 0559/1522] Fix T103679: Add missing operators in object context menu for point cloud and curves Set origin and convert operator now accepts point cloud and new curve object. But these operators were not added in context menu. Support for set origin and convert operator was added in rBadb4dd911b91, rB933d56d9e98d and rB2752a88478a8 Reviewed by: HooglyBoogly Differential Revision: https://developer.blender.org/D16939 --- release/scripts/startup/bl_ui/space_view3d.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 60494aa4d9e..0af3325ae2c 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2696,14 +2696,14 @@ class VIEW3D_MT_object_context_menu(Menu): if selected_objects_len > 1: layout.operator("object.join") - if obj.type in {'MESH', 'CURVE', 'SURFACE', 'POINTCLOUD', 'META', 'FONT'}: + if obj.type in {'MESH', 'CURVE', 'CURVES', 'SURFACE', 'POINTCLOUD', 'META', 'FONT'}: layout.operator_menu_enum("object.convert", "target") if obj.type == 'GPENCIL': layout.operator_menu_enum("gpencil.convert", "type", text="Convert To") if ( - obj.type in {'MESH', 'CURVE', 'SURFACE', 'GPENCIL', 'LATTICE', 'ARMATURE', 'META', 'FONT'} or + obj.type in {'MESH', 'CURVE', 'CURVES', 'SURFACE', 'GPENCIL', 'LATTICE', 'ARMATURE', 'META', 'FONT', 'POINTCLOUD'} or (obj.type == 'EMPTY' and obj.instance_collection is not None) ): layout.operator_context = 'INVOKE_REGION_WIN' From c6b4bd407ef1068ba201c49d971213e5d6785e59 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Tue, 10 Jan 2023 09:35:59 -0300 Subject: [PATCH 0560/1522] Cleanup: deduplicate conditions in transform code The `t->spacetype` check is already done in `setSnappingCallback`. --- source/blender/editors/transform/transform_snap.cc | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/transform/transform_snap.cc b/source/blender/editors/transform/transform_snap.cc index 0eebe05fa0c..00ccf1ed632 100644 --- a/source/blender/editors/transform/transform_snap.cc +++ b/source/blender/editors/transform/transform_snap.cc @@ -741,12 +741,7 @@ static void initSnappingMode(TransInfo *t) t->tsnap.project = false; } - if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE, SPACE_NODE, SPACE_SEQ)) { - /* Not with camera selected in camera view. */ - if (!(t->options & CTX_CAMERA)) { - setSnappingCallback(t); - } - } + setSnappingCallback(t); if (t->spacetype == SPACE_VIEW3D) { if (t->tsnap.object_context == nullptr) { @@ -903,6 +898,10 @@ void freeSnapping(TransInfo *t) static void setSnappingCallback(TransInfo *t) { if (t->spacetype == SPACE_VIEW3D) { + if (t->options & CTX_CAMERA) { + /* Not with camera selected in camera view. */ + return; + } t->tsnap.calcSnap = snap_calc_view3d_fn; } else if (t->spacetype == SPACE_IMAGE) { @@ -924,6 +923,9 @@ static void setSnappingCallback(TransInfo *t) /* The target is calculated along with the snap point. */ return; } + else { + return; + } switch (t->tsnap.source_select) { case SCE_SNAP_SOURCE_CLOSEST: From 387fc9b40b41ff6e0039332052dedeeda0962b5b Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 10 Jan 2023 14:57:23 +0100 Subject: [PATCH 0561/1522] MacOS: Silence OpenGL deprecation warnings. OpenGL is deprecated by Apple and triggers a warning when used. The goal is that OpenGL is replaced by Metal backend, but we are not there yet. To improve tracability of new warnings we hide deprecation warnings when the GHOST_ContextCGL.h file is included. NOTE: This change silences other deprecation warnings as well. --- intern/ghost/intern/GHOST_SystemCocoa.mm | 6 ++++++ intern/ghost/intern/GHOST_WindowCocoa.mm | 6 ++++++ source/blender/gpu/metal/mtl_context.hh | 6 ++++++ 3 files changed, 18 insertions(+) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index b8463286eab..f8e86e1a720 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -16,6 +16,12 @@ #include "GHOST_WindowCocoa.h" #include "GHOST_WindowManager.h" +/* Don't generate OpenGL deprecation warning. This is a known thing, and is not something easily + * solvable in a short term. */ +#ifdef __clang__ +# pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + #include "GHOST_ContextCGL.h" #ifdef WITH_VULKAN_BACKEND diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 8748bbaeb35..849e59cd809 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -6,6 +6,12 @@ #include "GHOST_Debug.h" #include "GHOST_SystemCocoa.h" +/* Don't generate OpenGL deprecation warning. This is a known thing, and is not something easily + * solvable in a short term. */ +#ifdef __clang__ +# pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + #include "GHOST_ContextCGL.h" #ifdef WITH_VULKAN_BACKEND diff --git a/source/blender/gpu/metal/mtl_context.hh b/source/blender/gpu/metal/mtl_context.hh index e2789dbf9a7..ce2fd357ca9 100644 --- a/source/blender/gpu/metal/mtl_context.hh +++ b/source/blender/gpu/metal/mtl_context.hh @@ -12,6 +12,12 @@ #include "GPU_common_types.h" #include "GPU_context.h" +/* Don't generate OpenGL deprecation warning. This is a known thing, and is not something easily + * solvable in a short term. */ +#ifdef __clang__ +# pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + #include "intern/GHOST_Context.h" #include "intern/GHOST_ContextCGL.h" #include "intern/GHOST_Window.h" From 597aecc01644f0063fa4545dabadc5f73387e3d3 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 10 Jan 2023 15:01:02 +0100 Subject: [PATCH 0562/1522] MacOS: Update Min Requirement to 10.15. A few weeks ago we enabled the Metal back-end for the viewport. Due to metal, master is only able to build on MacOS 10.15 and above. The previous minimum requirement is MacOS 10.13. It was already planned to bump to a higher version for Blender 3.6. After a short discussion via bf-committers it was decided that it is fine to bump it for 3.5 release. This patch cleans up the CMake files and update the minimum requirement. With this patch the next deprecations will be listsed. - `NSOpenGLView`, `NSOpenGLContext` is deprecated. (replaced by metal) - `NSStringPboardType` is replaced by `NSPasteboardTypeString` - `NSTIFFPboardType` is replaced by `NSPasteboardTypeTIFF` - `NSFilenamesPboardType` should be replaved by multiple pasteboard items with `NSPasteboardTypeFileURL` instead. - `NSUserNotification` should be replaced with UserNotifications.frameworks API Deprecations will be handled in separate tasks and commits. OpenGL won't be fixed at this moment, as it will be phased out in the future. NSStringPboardType, NSTiffPboardType & NSFilenamesPboardType will be provided in a single patch. NSUserNotification will also be provided in its own patch. Reviewed By: brecht, sergey Differential Revision: https://developer.blender.org/D16953 --- CMakeLists.txt | 4 ---- build_files/cmake/platform/platform_apple_xcode.cmake | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c957ce37df5..9dfb962a57e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -605,10 +605,6 @@ else() set(WITH_METAL_BACKEND OFF) endif() -if(WITH_METAL_BACKEND) - set(CMAKE_OSX_DEPLOYMENT_TARGET "10.15" CACHE STRING "Minimum OS X deployment version" FORCE) -endif() - if(WIN32) getDefaultWindowsPrefixBase(CMAKE_GENERIC_PROGRAM_FILES) set(CPACK_INSTALL_PREFIX ${CMAKE_GENERIC_PROGRAM_FILES}/${}) diff --git a/build_files/cmake/platform/platform_apple_xcode.cmake b/build_files/cmake/platform/platform_apple_xcode.cmake index 06890f1cee1..d5579357ce4 100644 --- a/build_files/cmake/platform/platform_apple_xcode.cmake +++ b/build_files/cmake/platform/platform_apple_xcode.cmake @@ -155,8 +155,8 @@ if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64") # M1 chips run Big Sur onwards. set(OSX_MIN_DEPLOYMENT_TARGET 11.00) else() - # 10.13 is our min. target, if you use higher sdk, weak linking happens - set(OSX_MIN_DEPLOYMENT_TARGET 10.13) + # 10.15 is our min. target, if you use higher sdk, weak linking happens + set(OSX_MIN_DEPLOYMENT_TARGET 10.15) endif() set(CMAKE_OSX_DEPLOYMENT_TARGET "${OSX_MIN_DEPLOYMENT_TARGET}" CACHE STRING "" FORCE) From fddb76e9af8de34852cb9906abd1de43ad9f24d3 Mon Sep 17 00:00:00 2001 From: Amelie Fondevilla Date: Tue, 10 Jan 2023 14:18:09 +0100 Subject: [PATCH 0563/1522] Fix: new Grease Pencil layer not selected when added from the viewport When adding a new layer from the viewport, the newly created layer is set as active, which is visible in the properties panel, but the selection in the dopesheet was not updated accordingly, due to a missing notifier which is added in this patch. --- source/blender/editors/gpencil/gpencil_data.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index 4f61016215a..c876832bc0c 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -247,6 +247,7 @@ static int gpencil_layer_add_exec(bContext *C, wmOperator *op) ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); } WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); + WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL); return OPERATOR_FINISHED; } From 250eda36b8f91a2f89b202d5eb79108260e1b1e3 Mon Sep 17 00:00:00 2001 From: Marc Chehab Date: Tue, 10 Jan 2023 15:37:02 +0100 Subject: [PATCH 0564/1522] GPencil: Build modifier add "natural drawing" time This patch uses the recorded drawing speed to rebuild the strokes. This results in a way more natural feel of the animation. Here's a short summary of existing data used: - gps->points->time: This is a timestamp in seconds of when the point was created since the creation of the stroke. It's quite often 0 (I added a sanitization routine). - gpf->inittime: This is a timestamp in seconds when a stroke was drawn measured since some unknown point in time. I only ever use the difference between two strokes, so the absolute value is not relevant. Reviewed By: frogstomp, antoniov, mendio Differential Revision: https://developer.blender.org/D16759 --- .../blenloader/intern/versioning_300.cc | 14 + source/blender/editors/include/ED_gpencil.h | 2 +- .../intern/MOD_gpencilbuild.c | 412 ++++++++++++------ .../makesdna/DNA_gpencil_modifier_defaults.h | 3 + .../makesdna/DNA_gpencil_modifier_types.h | 24 +- .../makesrna/intern/rna_gpencil_modifier.c | 85 +++- 6 files changed, 400 insertions(+), 140 deletions(-) diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 38ecfaf41ea..6b4f374bf0e 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3842,6 +3842,20 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) LISTBASE_FOREACH (Light *, light, &bmain->lights) { light->radius = light->area_size; } + /* Grease Pencil Build modifier: Set default value for new natural drawspeed factor and maximum + * gap. */ + if (!DNA_struct_elem_find(fd->filesdna, "BuildGpencilModifierData", "float", "speed_fac") || + !DNA_struct_elem_find(fd->filesdna, "BuildGpencilModifierData", "float", "speed_maxgap")) { + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) { + if (md->type == eGpencilModifierType_Build) { + BuildGpencilModifierData *mmd = (BuildGpencilModifierData *)md; + mmd->speed_fac = 1.2f; + mmd->speed_maxgap = 0.5f; + } + } + } + } } /** diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h index 9dd2ba5d1d3..c95e58f9559 100644 --- a/source/blender/editors/include/ED_gpencil.h +++ b/source/blender/editors/include/ED_gpencil.h @@ -83,7 +83,7 @@ typedef struct tGPspoint { float pressure; /** Pressure of tablet at this point for alpha factor. */ float strength; - /** Time relative to stroke start (used when converting to path). */ + /** Time relative to stroke start (used when converting to path & in build modifier). */ float time; /** Factor of uv along the stroke. */ float uv_fac; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c index 49ac3275c82..e4320a7b5a8 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c @@ -47,6 +47,13 @@ #include "MOD_gpencil_modifiertypes.h" #include "MOD_gpencil_ui_common.h" +/* Two hard-coded values for GP_BUILD_MODE_ADDITIVE with GP_BUILD_TIMEMODE_DRAWSPEED. */ + +/* The minimum time gap we should worry about points with no time. */ +#define GP_BUILD_CORRECTGAP 0.001 +/* The time for geometric strokes */ +#define GP_BUILD_TIME_GEOSTROKES 1.0 + static void initData(GpencilModifierData *md) { BuildGpencilModifierData *gpmd = (BuildGpencilModifierData *)md; @@ -252,53 +259,55 @@ static int cmp_stroke_build_details(const void *ps1, const void *ps2) return p1->distance > p2->distance ? 1 : (p1->distance == p2->distance ? 0 : -1); } -/* Sequential and additive - Show strokes one after the other. */ +/* Sequential - Show strokes one after the other (includes additive mode). */ static void build_sequential(Object *ob, BuildGpencilModifierData *mmd, + Depsgraph *depsgraph, bGPdata *gpd, bGPDframe *gpf, - const int target_def_nr, + int target_def_nr, float fac, - bool additive) + const float *ctime) { + /* Total number of strokes in this run. */ size_t tot_strokes = BLI_listbase_count(&gpf->strokes); - size_t start_stroke; + /* First stroke to build. */ + size_t start_stroke = 0; + /* Pointer to current stroke. */ bGPDstroke *gps; + /* Recycled counter. */ size_t i; + Scene *scene = DEG_get_evaluated_scene(depsgraph); + /* Framerate of scene. */ + const float fps = (((float)scene->r.frs_sec) / scene->r.frs_sec_base); - /* 1) Determine which strokes to start with & total strokes to build. */ - - if (additive) { + /* 1) Determine which strokes to start with (& adapt total number of strokes to build). */ + if (mmd->mode == GP_BUILD_MODE_ADDITIVE) { if (gpf->prev) { - start_stroke = BLI_listbase_count(&gpf->prev->strokes); - } - else { - start_stroke = 0; + start_stroke = BLI_listbase_count(&gpf->runtime.gpf_orig->prev->strokes); } if (start_stroke <= tot_strokes) { tot_strokes = tot_strokes - start_stroke; } - else { - start_stroke = 0; - } - } - else { - start_stroke = 0; } - /* 2) Compute proportion of time each stroke should occupy */ + /* 2) Compute proportion of time each stroke should occupy. */ /* NOTE: This assumes that the total number of points won't overflow! */ tStrokeBuildDetails *table = MEM_callocN(sizeof(tStrokeBuildDetails) * tot_strokes, __func__); - size_t totpoints = 0; + /* Pointer to cache table of times for each point. */ + float *idx_times; + /* Running overall time sum incrementing per point. */ + float sumtime = 0; + /* Running overall point sum. */ + size_t sumpoints = 0; - /* 2.1) First pass - Tally up points */ + /* 2.1) Pass to initially tally up points. */ for (gps = BLI_findlink(&gpf->strokes, start_stroke), i = 0; gps; gps = gps->next, i++) { tStrokeBuildDetails *cell = &table[i]; cell->gps = gps; cell->totpoints = gps->totpoints; - - totpoints += cell->totpoints; + sumpoints += cell->totpoints; /* Compute distance to control object if set, and build according to that order. */ if (mmd->object) { @@ -321,7 +330,104 @@ static void build_sequential(Object *ob, qsort(table, tot_strokes, sizeof(tStrokeBuildDetails), cmp_stroke_build_details); } - /* 2.2) Second pass - Compute the overall indices for points */ + /* 2.2) If GP_BUILD_TIMEMODE_DRAWSPEED: Tally up point timestamps & delays to idx_times. */ + if (mmd->time_mode == GP_BUILD_TIMEMODE_DRAWSPEED) { + idx_times = MEM_callocN(sizeof(float) * sumpoints, __func__); + /* Maximum time gap between strokes in seconds. */ + const float GP_BUILD_MAXGAP = mmd->speed_maxgap; + /* Running reference to overall current point. */ + size_t curpoint = 0; + /* Running timestamp of last point that had data. */ + float last_pointtime = 0; + + for (i = 0; i < tot_strokes; i++) { + tStrokeBuildDetails *cell = &table[i]; + /* Adding delay between strokes to sumtime. */ + if (mmd->object == NULL) { + /* Normal case: Delay to last stroke. */ + if (i != 0 && 0 < cell->gps->inittime && 0 < (cell - 1)->gps->inittime) { + float curgps_delay = fabs(cell->gps->inittime - (cell - 1)->gps->inittime) - + last_pointtime; + if (0 < curgps_delay) { + sumtime += MIN2(curgps_delay, GP_BUILD_MAXGAP); + } + } + } + + /* Going through the points of the current stroke + * and filling in "zeropoints" where "time" = 0. */ + + /* Count of consecutive points where "time" is 0. */ + int zeropoints = 0; + for (int j = 0; j < cell->totpoints; j++) { + /* Defining time for first point in stroke. */ + if (j == 0) { + idx_times[curpoint] = sumtime; + last_pointtime = cell->gps->points[0].time; + } + /* Entering subsequent points */ + else { + if (cell->gps->points[j].time == 0) { + idx_times[curpoint] = sumtime; + zeropoints++; + } + /* From here current point has time data */ + else { + float deltatime = fabs(cell->gps->points[j].time - last_pointtime); + /* Do we need to sanitize previous points? */ + if (0 < zeropoints) { + /* Only correct if timegap bigger than MIN_CORRECTGAP. */ + if (GP_BUILD_CORRECTGAP < deltatime) { + /* Cycling backwards through zeropoints to fix them. */ + for (int k = 0; k < zeropoints; k++) { + float linear_fill = interpf( + deltatime, 0, ((float)k + 1) / (zeropoints + 1)); /* Factor = Proportion. */ + idx_times[curpoint - k - 1] = sumtime + linear_fill; + } + } + else { + zeropoints = 0; + } + } + + /* Normal behaviour with time data */ + idx_times[curpoint] = sumtime + deltatime; + sumtime = idx_times[curpoint]; + last_pointtime = cell->gps->points[j].time; + zeropoints = 0; + } + } + curpoint += 1; + } + + /* If stroke had no time data at all, use mmd->time_geostrokes. */ + if (zeropoints + 1 == cell->totpoints) { + for (int j = 0; j < cell->totpoints; j++) { + idx_times[(int)curpoint - j - 1] = (float)(cell->totpoints - j) * + GP_BUILD_TIME_GEOSTROKES / + (float)cell->totpoints + + sumtime; + } + last_pointtime = GP_BUILD_TIME_GEOSTROKES; + sumtime += GP_BUILD_TIME_GEOSTROKES; + } + } + + float gp_build_speedfactor = mmd->speed_fac; + /* If current frame can't be built before next frame, adjust gp_build_speedfactor. */ + if (gpf->next && + (gpf->framenum + sumtime * fps / gp_build_speedfactor) > gpf->next->framenum) { + gp_build_speedfactor = sumtime * fps / (gpf->next->framenum - gpf->framenum); + } + /* Apply gp_build_speedfactor to all points & to sumtime. */ + for (i = 0; i < sumpoints; i++) { + float *idx_time = &idx_times[i]; + *idx_time /= gp_build_speedfactor; + } + sumtime /= gp_build_speedfactor; + } + + /* 2.3) Pass to compute overall indices for points (per stroke). */ for (i = 0; i < tot_strokes; i++) { tStrokeBuildDetails *cell = &table[i]; @@ -329,12 +435,12 @@ static void build_sequential(Object *ob, cell->start_idx = 0; } else { - cell->start_idx = (cell - 1)->end_idx; + cell->start_idx = (cell - 1)->end_idx + 1; } cell->end_idx = cell->start_idx + cell->totpoints - 1; } - /* 3) Determine the global indices for points that should be visible */ + /* 3) Determine the global indices for points that should be visible. */ size_t first_visible = 0; size_t last_visible = 0; /* Need signed numbers because the representation of fading offset would exceed the beginning and @@ -343,30 +449,60 @@ static void build_sequential(Object *ob, int fade_end = 0; bool fading_enabled = (mmd->flag & GP_BUILD_USE_FADING); - float set_fade_fac = fading_enabled ? mmd->fade_fac : 0.0f; - float use_fac = interpf(1 + set_fade_fac, 0, fac); + float use_fac; + + if (mmd->time_mode == GP_BUILD_TIMEMODE_DRAWSPEED) { + /* Recalculate equivalent of "fac" using timestamps. */ + float targettime = (*ctime - (float)gpf->framenum) / fps; + fac = 0; + /* If ctime is in current frame, find last point. */ + if (0 < targettime && targettime < sumtime) { + /* All except GP_BUILD_TRANSITION_SHRINK count forwards. */ + if (mmd->transition != GP_BUILD_TRANSITION_SHRINK) { + for (i = 0; i < sumpoints; i++) { + if (targettime < idx_times[i]) { + fac = (float)i / sumpoints; + break; + } + } + } + else { + for (i = 0; i < sumpoints; i++) { + if (targettime < sumtime - idx_times[sumpoints - i - 1]) { + fac = (float)i / sumpoints; + break; + } + } + } + } + /* Don't check if ctime is beyond time of current frame. */ + else if (targettime >= sumtime) { + fac = 1; + } + } + use_fac = interpf(1 + set_fade_fac, 0, fac); float use_fade_fac = use_fac - set_fade_fac; CLAMP(use_fade_fac, 0.0f, 1.0f); switch (mmd->transition) { - /* Show in forward order - * - As fac increases, the number of visible points increases - */ + /* Show in forward order + * - As fac increases, the number of visible points increases + */ case GP_BUILD_TRANSITION_GROW: first_visible = 0; /* always visible */ - last_visible = (size_t)roundf(totpoints * use_fac); - fade_start = (int)roundf(totpoints * use_fade_fac); + last_visible = (size_t)roundf(sumpoints * use_fac); + fade_start = (int)roundf(sumpoints * use_fade_fac); fade_end = last_visible; break; - /* Hide in reverse order - * - As fac increases, the number of points visible at the end decreases - */ + /* Hide in reverse order + * - As fac increases, the number of points visible at the end decreases + */ case GP_BUILD_TRANSITION_SHRINK: first_visible = 0; /* always visible (until last point removed) */ - last_visible = (size_t)(totpoints * (1.0f + set_fade_fac - use_fac)); - fade_start = (int)roundf(totpoints * (1.0f - use_fade_fac - set_fade_fac)); + last_visible = (size_t)(sumpoints * (1.0f + set_fade_fac - use_fac)); + fade_start = (int)roundf(sumpoints * (1.0f - use_fade_fac - set_fade_fac)); fade_end = last_visible; break; @@ -374,10 +510,10 @@ static void build_sequential(Object *ob, * - As fac increases, the early points start getting hidden */ case GP_BUILD_TRANSITION_VANISH: - first_visible = (size_t)(totpoints * use_fade_fac); - last_visible = totpoints; /* i.e. visible until the end, unless first overlaps this */ + first_visible = (size_t)(sumpoints * use_fade_fac); + last_visible = sumpoints; /* i.e. visible until the end, unless first overlaps this */ fade_start = first_visible; - fade_end = (int)roundf(totpoints * use_fac); + fade_end = (int)roundf(sumpoints * use_fac); break; } @@ -434,6 +570,9 @@ static void build_sequential(Object *ob, /* Free table */ MEM_freeN(table); + if (mmd->time_mode == GP_BUILD_TIMEMODE_DRAWSPEED) { + MEM_freeN(idx_times); + } } /* --------------------------------------------- */ @@ -451,7 +590,7 @@ static void build_concurrent(BuildGpencilModifierData *mmd, const bool reverse = (mmd->transition != GP_BUILD_TRANSITION_GROW); /* 1) Determine the longest stroke, to figure out when short strokes should start */ - /* FIXME: A *really* long stroke here could dwarf everything else, causing bad timings */ + /* Todo: A *really* long stroke here could dwarf everything else, causing bad timings */ for (gps = gpf->strokes.first; gps; gps = gps->next) { if (gps->totpoints > max_points) { max_points = gps->totpoints; @@ -565,11 +704,17 @@ static void generate_geometry(GpencilModifierData *md, bGPDframe *gpf) { BuildGpencilModifierData *mmd = (BuildGpencilModifierData *)md; + /* Prevent incompatible options at runtime. */ if (mmd->mode == GP_BUILD_MODE_ADDITIVE) { mmd->transition = GP_BUILD_TRANSITION_GROW; + mmd->start_delay = 0; } + if (mmd->mode == GP_BUILD_MODE_CONCURRENT && mmd->time_mode == GP_BUILD_TIMEMODE_DRAWSPEED) { + mmd->time_mode = GP_BUILD_TIMEMODE_FRAMES; + } + const bool reverse = (mmd->transition != GP_BUILD_TRANSITION_GROW); - const bool is_percentage = (mmd->flag & GP_BUILD_PERCENTAGE); + const bool is_percentage = (mmd->time_mode == GP_BUILD_TIMEMODE_PERCENTAGE); const float ctime = DEG_get_ctime(depsgraph); @@ -633,75 +778,78 @@ static void generate_geometry(GpencilModifierData *md, } } - /* Compute start and end frames for the animation effect - * By default, the upper bound is given by the "maximum length" setting + /* Default "fac" value to call build_sequential even with + * GP_BUILD_TIMEMODE_DRAWSPEED, which uses separate logic + * in function build_sequential() */ - float start_frame = is_percentage ? gpf->framenum : gpf->framenum + mmd->start_delay; - /* When use percentage don't need a limit in the upper bound, so use a maximum value for the last - * frame. */ - float end_frame = is_percentage ? start_frame + 9999 : start_frame + mmd->length; + float fac = 1; - if (gpf->next) { - /* Use the next frame or upper bound as end frame, whichever is lower/closer */ - end_frame = MIN2(end_frame, gpf->next->framenum); + if (mmd->time_mode != GP_BUILD_TIMEMODE_DRAWSPEED) { + /* Compute start and end frames for the animation effect + * By default, the upper bound is given by the "length" setting. + */ + float start_frame = is_percentage ? gpf->framenum : gpf->framenum + mmd->start_delay; + /* When use percentage don't need a limit in the upper bound, so use a maximum value for the + * last frame. */ + float end_frame = is_percentage ? start_frame + 9999 : start_frame + mmd->length; + + if (gpf->next) { + /* Use the next frame or upper bound as end frame, whichever is lower/closer */ + end_frame = MIN2(end_frame, gpf->next->framenum); + } + + /* Early exit if current frame is outside start/end bounds */ + /* NOTE: If we're beyond the next/previous frames (if existent), + * then we wouldn't have this problem anyway... */ + if (ctime < start_frame) { + /* Before Start - Animation hasn't started. Display initial state. */ + if (reverse) { + /* 1) Reverse = Start with all, end with nothing. + * ==> Do nothing (everything already present) + */ + } + else { + /* 2) Forward Order = Start with nothing, end with the full frame. + * ==> Free all strokes, and return an empty frame + */ + gpf_clear_all_strokes(gpf); + } + + /* Early exit */ + return; + } + if (ctime >= end_frame) { + /* Past End - Animation finished. Display final result. */ + if (reverse) { + /* 1) Reverse = Start with all, end with nothing. + * ==> Free all strokes, and return an empty frame + */ + gpf_clear_all_strokes(gpf); + } + else { + /* 2) Forward Order = Start with nothing, end with the full frame. + * ==> Do Nothing (everything already present) + */ + } + + /* Early exit */ + return; + } + /* Determine how far along we are given current time, start_frame and end_frame */ + fac = is_percentage ? mmd->percentage_fac : (ctime - start_frame) / (end_frame - start_frame); } - /* Early exit if current frame is outside start/end bounds */ - /* NOTE: If we're beyond the next/previous frames (if existent), - * then we wouldn't have this problem anyway... */ - if (ctime < start_frame) { - /* Before Start - Animation hasn't started. Display initial state. */ - if (reverse) { - /* 1) Reverse = Start with all, end with nothing. - * ==> Do nothing (everything already present) - */ - } - else { - /* 2) Forward Order = Start with nothing, end with the full frame. - * ==> Free all strokes, and return an empty frame - */ - gpf_clear_all_strokes(gpf); - } - - /* Early exit */ - return; - } - if (ctime >= end_frame) { - /* Past End - Animation finished. Display final result. */ - if (reverse) { - /* 1) Reverse = Start with all, end with nothing. - * ==> Free all strokes, and return an empty frame - */ - gpf_clear_all_strokes(gpf); - } - else { - /* 2) Forward Order = Start with nothing, end with the full frame. - * ==> Do Nothing (everything already present) - */ - } - - /* Early exit */ - return; - } - - /* Determine how far along we are between the keyframes */ - float fac = is_percentage ? mmd->percentage_fac : - (ctime - start_frame) / (end_frame - start_frame); - - /* Time management mode */ + /* Calling the correct build mode */ switch (mmd->mode) { case GP_BUILD_MODE_SEQUENTIAL: - build_sequential(ob, mmd, gpd, gpf, target_def_nr, fac, false); + case GP_BUILD_MODE_ADDITIVE: + build_sequential(ob, mmd, depsgraph, gpd, gpf, target_def_nr, fac, &ctime); break; case GP_BUILD_MODE_CONCURRENT: build_concurrent(mmd, gpd, gpf, target_def_nr, fac); break; - case GP_BUILD_MODE_ADDITIVE: - build_sequential(ob, mmd, gpd, gpf, target_def_nr, fac, true); - break; - default: printf("Unsupported build mode (%d) for GP Build Modifier: '%s'\n", mmd->mode, @@ -727,49 +875,59 @@ static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Objec static void panel_draw(const bContext *UNUSED(C), Panel *panel) { - uiLayout *row, *sub; uiLayout *layout = panel->layout; PointerRNA ob_ptr; PointerRNA *ptr = gpencil_modifier_panel_get_property_pointers(panel, &ob_ptr); - int mode = RNA_enum_get(ptr, "mode"); - const bool use_percentage = RNA_boolean_get(ptr, "use_percentage"); + const int mode = RNA_enum_get(ptr, "mode"); + int time_mode = RNA_enum_get(ptr, "time_mode"); uiLayoutSetPropSep(layout, true); + /* First: Build mode and build settings. */ uiItemR(layout, ptr, "mode", 0, NULL, ICON_NONE); + if (mode == GP_BUILD_MODE_SEQUENTIAL) { + uiItemR(layout, ptr, "transition", 0, NULL, ICON_NONE); + } + if (mode == GP_BUILD_MODE_CONCURRENT) { + /* Concurrent mode doesn't support GP_BUILD_TIMEMODE_DRAWSPEED, so unset it. */ + if (time_mode == GP_BUILD_TIMEMODE_DRAWSPEED) { + RNA_enum_set(ptr, "time_mode", GP_BUILD_TIMEMODE_FRAMES); + time_mode = GP_BUILD_TIMEMODE_FRAMES; + } + uiItemR(layout, ptr, "transition", 0, NULL, ICON_NONE); + } + uiItemS(layout); + + /* Second: Time mode and time settings. */ + + uiItemR(layout, ptr, "time_mode", 0, NULL, ICON_NONE); if (mode == GP_BUILD_MODE_CONCURRENT) { uiItemR(layout, ptr, "concurrent_time_alignment", 0, NULL, ICON_NONE); } - - uiItemS(layout); - - if (ELEM(mode, GP_BUILD_MODE_SEQUENTIAL, GP_BUILD_MODE_CONCURRENT)) { - uiItemR(layout, ptr, "transition", 0, NULL, ICON_NONE); + switch (time_mode) { + case GP_BUILD_TIMEMODE_DRAWSPEED: + uiItemR(layout, ptr, "speed_factor", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "speed_maxgap", 0, NULL, ICON_NONE); + break; + case GP_BUILD_TIMEMODE_FRAMES: + uiItemR(layout, ptr, "length", 0, IFACE_("Frames"), ICON_NONE); + if (mode != GP_BUILD_MODE_ADDITIVE) { + uiItemR(layout, ptr, "start_delay", 0, NULL, ICON_NONE); + } + break; + case GP_BUILD_TIMEMODE_PERCENTAGE: + uiItemR(layout, ptr, "percentage_factor", 0, NULL, ICON_NONE); + break; + default: + break; } - row = uiLayoutRow(layout, true); - uiLayoutSetActive(row, !use_percentage); - uiItemR(row, ptr, "start_delay", 0, NULL, ICON_NONE); - row = uiLayoutRow(layout, true); - uiLayoutSetActive(row, !use_percentage); - uiItemR(row, ptr, "length", 0, IFACE_("Frames"), ICON_NONE); - uiItemS(layout); + uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE); - row = uiLayoutRowWithHeading(layout, true, IFACE_("Factor")); - uiLayoutSetPropDecorate(row, false); - uiItemR(row, ptr, "use_percentage", 0, "", ICON_NONE); - sub = uiLayoutRow(row, true); - uiLayoutSetActive(sub, use_percentage); - uiItemR(sub, ptr, "percentage_factor", 0, "", ICON_NONE); - uiItemDecoratorR(row, ptr, "percentage_factor", 0); - - uiItemS(layout); - - if (ELEM(mode, GP_BUILD_MODE_SEQUENTIAL, GP_BUILD_MODE_ADDITIVE)) { - uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE); - } + /* Some housekeeping to prevent clashes between incompatible + * options */ /* Check for incompatible time modifier. */ Object *ob = ob_ptr.data; diff --git a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h index ae27cbb0195..00543b9df9a 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h @@ -54,6 +54,9 @@ .mode = 0, \ .transition = 0, \ .time_alignment = 0, \ + .time_mode = 0, \ + .speed_fac = 1.2f, \ + .speed_maxgap = 0.5f, \ .percentage_fac = 0.0f, \ } diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h index b503a76be05..146d4bc94bc 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_types.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -452,11 +452,19 @@ typedef struct BuildGpencilModifierData { short transition; /** - * (eGpencilBuild_TimeAlignment) + * (eBuildGpencil_TimeAlignment) * For the "Concurrent" mode, when should "shorter" strips start/end. */ short time_alignment; + /* Speed factor for GP_BUILD_TIMEMODE_DRAWSPEED. */ + float speed_fac; + /* Maxmium time gap between strokes for GP_BUILD_TIMEMODE_DRAWSPEED. */ + float speed_maxgap; + /* Which time mode should be used. */ + short time_mode; + char _pad[6]; + /** Build origin control object. */ struct Object *object; @@ -499,6 +507,15 @@ typedef enum eBuildGpencil_TimeAlignment { /* TODO: Random Offsets, Stretch-to-Fill */ } eBuildGpencil_TimeAlignment; +typedef enum eBuildGpencil_TimeMode { + /* Use a number of frames build. */ + GP_BUILD_TIMEMODE_FRAMES = 0, + /* Use manual percentage to build. */ + GP_BUILD_TIMEMODE_PERCENTAGE = 1, + /* Use factor of recorded speed to build. */ + GP_BUILD_TIMEMODE_DRAWSPEED = 2, +} eBuildGpencil_TimeMode; + typedef enum eBuildGpencil_Flag { /* Restrict modifier to particular layer/passes? */ GP_BUILD_INVERT_LAYER = (1 << 0), @@ -507,10 +524,7 @@ typedef enum eBuildGpencil_Flag { /* Restrict modifier to only operating between the nominated frames */ GP_BUILD_RESTRICT_TIME = (1 << 2), GP_BUILD_INVERT_LAYERPASS = (1 << 3), - - /* Use a percentage instead of frame number to evaluate strokes. */ - GP_BUILD_PERCENTAGE = (1 << 4), - GP_BUILD_USE_FADING = (1 << 5), + GP_BUILD_USE_FADING = (1 << 4), } eBuildGpencil_Flag; typedef struct LatticeGpencilModifierData { diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index e6c238e79ea..46d8b7f8f3c 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -158,6 +158,25 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = { {0, NULL, 0, NULL, NULL}, }; +static const EnumPropertyItem gpencil_build_time_mode_items[] = { + {GP_BUILD_TIMEMODE_DRAWSPEED, + "DRAWSPEED", + 0, + "Natural Drawing Speed", + "Use recorded speed multiplied by a factor"}, + {GP_BUILD_TIMEMODE_FRAMES, + "FRAMES", + 0, + "Number of Frames", + "Set a fixed number of frames for all build animations"}, + {GP_BUILD_TIMEMODE_PERCENTAGE, + "PERCENTAGE", + 0, + "Percentage Factor", + "Set a manual percentage to build"}, + {0, NULL, 0, NULL, NULL}, +}; + #ifndef RNA_RUNTIME static const EnumPropertyItem modifier_modify_color_items[] = { {GP_MODIFY_COLOR_BOTH, "BOTH", 0, "Stroke & Fill", "Modify fill and stroke colors"}, @@ -925,6 +944,33 @@ static void rna_EnvelopeGpencilModifier_material_set(PointerRNA *ptr, rna_GpencilModifier_material_set(ptr, value, ma_target, reports); } +const EnumPropertyItem *gpencil_build_time_mode_filter(bContext *UNUSED(C), + PointerRNA *ptr, + PropertyRNA *prop, + bool *r_free) +{ + + GpencilModifierData *md = ptr->data; + BuildGpencilModifierData *mmd = (BuildGpencilModifierData *)md; + const bool is_concurrent = (mmd->mode == GP_BUILD_MODE_CONCURRENT); + + EnumPropertyItem *item_list = NULL; + int totitem = 0; + + for (const EnumPropertyItem *item = gpencil_build_time_mode_items; item->identifier != NULL; + item++) { + if (is_concurrent && item->identifier == "DRAWSPEED") { + continue; + } + RNA_enum_item_add(&item_list, &totitem, item); + } + + RNA_enum_item_end(&item_list, &totitem); + *r_free = true; + + return item_list; +} + #else static void rna_def_modifier_gpencilnoise(BlenderRNA *brna) @@ -2466,7 +2512,7 @@ static void rna_def_modifier_gpencilbuild(BlenderRNA *brna) /* Mode */ prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_gpencil_build_mode_items); - RNA_def_property_ui_text(prop, "Mode", "How many strokes are being animated at a time"); + RNA_def_property_ui_text(prop, "Mode", "How strokes are being built"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); /* Direction */ @@ -2480,9 +2526,7 @@ static void rna_def_modifier_gpencilbuild(BlenderRNA *brna) prop = RNA_def_property(srna, "start_delay", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "start_delay"); RNA_def_property_ui_text( - prop, - "Start Delay", - "Number of frames after each GP keyframe before the modifier has any effect"); + prop, "Delay", "Number of frames after each GP keyframe before the modifier has any effect"); RNA_def_property_range(prop, 0, MAXFRAMEF); RNA_def_property_ui_range(prop, 0, 200, 1, -1); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); @@ -2501,8 +2545,35 @@ static void rna_def_modifier_gpencilbuild(BlenderRNA *brna) prop = RNA_def_property(srna, "concurrent_time_alignment", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "time_alignment"); RNA_def_property_enum_items(prop, prop_gpencil_build_time_align_items); + RNA_def_property_ui_text(prop, "Time Alignment", "How should strokes start to appear/disappear"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + /* Which time mode to use: Current frames, manual percentage, or drawspeed. */ + prop = RNA_def_property(srna, "time_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "time_mode"); + RNA_def_property_enum_items(prop, gpencil_build_time_mode_items); + RNA_def_property_enum_funcs(prop, NULL, NULL, "gpencil_build_time_mode_filter"); RNA_def_property_ui_text( - prop, "Time Alignment", "When should strokes start to appear/disappear"); + prop, + "Timing", + "Use drawing speed, a number of frames, or a manual factor to build strokes"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + /* Speed factor for GP_BUILD_TIMEMODE_DRAWSPEED. */ + /* Todo: Does it work? */ + prop = RNA_def_property(srna, "speed_factor", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "speed_fac"); + RNA_def_property_ui_text(prop, "Speed Factor", "Multiply recorded drawing speed by a factor"); + RNA_def_property_range(prop, 0.0f, 100.0f); + RNA_def_property_ui_range(prop, 0, 5, 0.001, -1); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + /* Max gap in seconds between strokes for GP_BUILD_TIMEMODE_DRAWSPEED. */ + prop = RNA_def_property(srna, "speed_maxgap", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "speed_maxgap"); + RNA_def_property_ui_text(prop, "Maximum Gap", "The maximum gap between strokes in seconds"); + RNA_def_property_range(prop, 0.0f, 100.0f); + RNA_def_property_ui_range(prop, 0, 4, 0.01, -1); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); /* Time Limits */ @@ -2512,9 +2583,9 @@ static void rna_def_modifier_gpencilbuild(BlenderRNA *brna) prop, "Restrict Frame Range", "Only modify strokes during the specified frame range"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); - /* Use percentage */ + /* Use percentage bool (used by sequential & concurrent modes) */ prop = RNA_def_property(srna, "use_percentage", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_BUILD_PERCENTAGE); + RNA_def_property_boolean_sdna(prop, NULL, "time_mode", GP_BUILD_TIMEMODE_PERCENTAGE); RNA_def_property_ui_text( prop, "Restrict Visible Points", "Use a percentage factor to determine the visible points"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); From 35e54b52e6ecbb0465f1a28e0915769160b7bf86 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 10 Jan 2023 15:27:28 +0100 Subject: [PATCH 0565/1522] Assets: "All" asset library Adds a new built-in asset library that contains all other asset libraries visible in the asset library selector menu. This also means all their asset catalogs will be displayed as a single merged tree. The asset catalogs are not editable, since this would require support for writing multiple catalog definition files, which isn't there yet. Often it's not relevant where an asset comes from. Users just want to be able to get an asset quickly, comparable to how people use a search engine to browse images or the web itself, instead of first going to a dedicated platform. They don't want to bother with first choosing where they want the result to come from. This especially is needed for the Asset Shelf (T102879) that is being developed for the brush assets project (T101895). With this, users will have access to all their brushes efficiently from the 3D view, without much browsing. Did an informal review of the asset system bits with Sybren. --- .../blender/asset_system/AS_asset_catalog.hh | 34 ++++- .../blender/asset_system/AS_asset_library.hh | 27 +++- .../asset_system/intern/asset_catalog.cc | 42 +++++- .../asset_system/intern/asset_library.cc | 25 +++- .../intern/asset_library_service.cc | 132 ++++++++++++++---- .../intern/asset_library_service.hh | 11 +- .../blender/editors/asset/ED_asset_catalog.h | 2 + .../blender/editors/asset/ED_asset_catalog.hh | 10 ++ .../blender/editors/asset/ED_asset_library.h | 7 +- source/blender/editors/asset/ED_asset_list.hh | 15 ++ .../editors/asset/intern/asset_catalog.cc | 22 +++ .../intern/asset_library_reference_enum.cc | 21 +-- .../editors/asset/intern/asset_list.cc | 43 +++--- .../blender/editors/asset/intern/asset_ops.cc | 13 +- .../space_file/asset_catalog_tree_view.cc | 30 +++- source/blender/editors/space_file/filelist.cc | 98 +++++++++++-- source/blender/editors/space_file/filesel.c | 8 +- source/blender/makesdna/DNA_asset_defaults.h | 2 +- source/blender/makesdna/DNA_asset_types.h | 3 +- source/blender/makesdna/DNA_space_types.h | 2 + 20 files changed, 458 insertions(+), 89 deletions(-) diff --git a/source/blender/asset_system/AS_asset_catalog.hh b/source/blender/asset_system/AS_asset_catalog.hh index 87b9425c8c6..8f818c6a768 100644 --- a/source/blender/asset_system/AS_asset_catalog.hh +++ b/source/blender/asset_system/AS_asset_catalog.hh @@ -45,11 +45,17 @@ class AssetCatalogService { Vector> undo_snapshots_; Vector> redo_snapshots_; + const bool is_read_only_ = false; + public: static const CatalogFilePath DEFAULT_CATALOG_FILENAME; + struct read_only_tag { + }; + public: AssetCatalogService(); + explicit AssetCatalogService(read_only_tag); explicit AssetCatalogService(const CatalogFilePath &asset_library_root); /** @@ -62,11 +68,24 @@ class AssetCatalogService { void tag_has_unsaved_changes(AssetCatalog *edited_catalog); bool has_unsaved_changes() const; + /** + * Check if this is a read-only service meaning the user shouldn't be able to do edits. This is + * not enforced by internal catalog code, the catalog service user is responsible for it. For + * example the UI should disallow edits. + */ + bool is_read_only() const; + /** Load asset catalog definitions from the files found in the asset library. */ void load_from_disk(); /** Load asset catalog definitions from the given file or directory. */ void load_from_disk(const CatalogFilePath &file_or_directory_path); + /** + * Duplicate the catalogs from \a other_service into this one. Does not rebuild the tree, this + * needs to be done by the caller (call #rebuild_tree()!). + */ + void add_from_existing(const AssetCatalogService &other_service); + /** * Write the catalog definitions to disk. * @@ -105,6 +124,15 @@ class AssetCatalogService { */ void reload_catalogs(); + /** + * Make sure the tree is updated to the latest collection of catalogs stored in this service. + * Does not depend on a CDF file being available so this can be called on a service that stores + * catalogs that are not stored in a CDF. + * Most API functions that modify catalog data will trigger this, unless otherwise specified (for + * batch operations). + */ + void rebuild_tree(); + /** Return catalog with the given ID. Return nullptr if not found. */ AssetCatalog *find_catalog(CatalogID catalog_id) const; @@ -222,7 +250,6 @@ class AssetCatalogService { const CatalogFilePath &blend_file_path); std::unique_ptr read_into_tree(); - void rebuild_tree(); /** * For every catalog, ensure that its parent path also has a known catalog. @@ -270,6 +297,11 @@ class AssetCatalogCollection { AssetCatalogCollection(AssetCatalogCollection &&other) noexcept = default; std::unique_ptr deep_copy() const; + /** + * Copy the catalogs from \a other and append them to this collection. Copies no other data + * otherwise. + */ + void add_catalogs_from_existing(const AssetCatalogCollection &other); protected: static OwningAssetCatalogMap copy_catalog_map(const OwningAssetCatalogMap &orig); diff --git a/source/blender/asset_system/AS_asset_library.hh b/source/blender/asset_system/AS_asset_library.hh index f272ed6ff51..b3b7d421724 100644 --- a/source/blender/asset_system/AS_asset_library.hh +++ b/source/blender/asset_system/AS_asset_library.hh @@ -56,6 +56,8 @@ class AssetLibrary { */ std::unique_ptr asset_storage_; + std::function on_refresh_; + bCallbackFuncStore on_save_callback_store_{}; public: @@ -65,6 +67,8 @@ class AssetLibrary { std::unique_ptr catalog_service; + friend class AssetLibraryService; + public: /** * \param root_path: If this is an asset library on disk, the top-level directory path. @@ -72,6 +76,16 @@ class AssetLibrary { AssetLibrary(StringRef root_path = ""); ~AssetLibrary(); + /** + * Execute \a fn for every asset library that is loaded. The asset library is passed to the + * \a fn call. + * + * \param skip_all_library: When true, the \a fn will also be executed for the "All" asset + * library. This is just a combination of the other ones, so usually + * iterating over it is redundant. + */ + static void foreach_loaded(FunctionRef fn, bool include_all_library); + void load_catalogs(); /** Load catalogs that have changed on disk. */ @@ -128,9 +142,6 @@ class AssetLibrary { AssetIdentifier asset_identifier_from_library(StringRef relative_asset_path); StringRefNull root_path() const; - - private: - std::optional find_asset_index(const AssetRepresentation &asset); }; Vector all_valid_asset_library_refs(); @@ -138,12 +149,22 @@ Vector all_valid_asset_library_refs(); } // namespace blender::asset_system /** + * Load the data for an asset library, but not the asset representations themselves (loading these + * is currently not done in the asset system). + * + * For the "All" asset library (#ASSET_LIBRARY_ALL), every other known asset library will be + * loaded as well. So a call to #AssetLibrary::foreach_loaded() can be expected to iterate over all + * libraries. + * * \warning Catalogs are reloaded, invalidating catalog pointers. Do not store catalog pointers, * store CatalogIDs instead and lookup the catalog where needed. */ blender::asset_system::AssetLibrary *AS_asset_library_load( const Main *bmain, const AssetLibraryReference &library_reference); +std::string AS_asset_library_root_path_from_library_ref( + const AssetLibraryReference &library_reference); + /** * Try to find an appropriate location for an asset library root from a file or directory path. * Does not check if \a input_path exists. diff --git a/source/blender/asset_system/intern/asset_catalog.cc b/source/blender/asset_system/intern/asset_catalog.cc index c295f2de16e..6fd01ab14f7 100644 --- a/source/blender/asset_system/intern/asset_catalog.cc +++ b/source/blender/asset_system/intern/asset_catalog.cc @@ -43,6 +43,11 @@ AssetCatalogService::AssetCatalogService() { } +AssetCatalogService::AssetCatalogService(read_only_tag) : AssetCatalogService() +{ + const_cast(is_read_only_) = true; +} + AssetCatalogService::AssetCatalogService(const CatalogFilePath &asset_library_root) : AssetCatalogService() { @@ -51,6 +56,8 @@ AssetCatalogService::AssetCatalogService(const CatalogFilePath &asset_library_ro void AssetCatalogService::tag_has_unsaved_changes(AssetCatalog *edited_catalog) { + BLI_assert(!is_read_only_); + if (edited_catalog) { edited_catalog->flags.has_unsaved_changes = true; } @@ -85,6 +92,11 @@ bool AssetCatalogService::has_unsaved_changes() const return catalog_collection_->has_unsaved_changes_; } +bool AssetCatalogService::is_read_only() const +{ + return is_read_only_; +} + void AssetCatalogService::tag_all_catalogs_as_unsaved_changes() { for (auto &catalog : catalog_collection_->catalogs_.values()) { @@ -322,6 +334,11 @@ void AssetCatalogService::load_from_disk(const CatalogFilePath &file_or_director rebuild_tree(); } +void AssetCatalogService::add_from_existing(const AssetCatalogService &other_service) +{ + catalog_collection_->add_catalogs_from_existing(*other_service.catalog_collection_); +} + void AssetCatalogService::load_directory_recursive(const CatalogFilePath &directory_path) { /* TODO(@sybren): implement proper multi-file support. For now, just load @@ -452,6 +469,8 @@ bool AssetCatalogService::is_catalog_known_with_unsaved_changes(const CatalogID bool AssetCatalogService::write_to_disk(const CatalogFilePath &blend_file_path) { + BLI_assert(!is_read_only_); + if (!write_to_disk_ex(blend_file_path)) { return false; } @@ -625,6 +644,7 @@ void AssetCatalogService::undo() void AssetCatalogService::redo() { + BLI_assert(!is_read_only_); BLI_assert_msg(is_redo_possbile(), "Redo stack is empty"); undo_snapshots_.append(std::move(catalog_collection_)); @@ -634,6 +654,7 @@ void AssetCatalogService::redo() void AssetCatalogService::undo_push() { + BLI_assert(!is_read_only_); std::unique_ptr snapshot = catalog_collection_->deep_copy(); undo_snapshots_.append(std::move(snapshot)); redo_snapshots_.clear(); @@ -657,15 +678,24 @@ std::unique_ptr AssetCatalogCollection::deep_copy() cons return copy; } +static void copy_catalog_map_into_existing(const OwningAssetCatalogMap &source, + OwningAssetCatalogMap &dest) +{ + for (const auto &orig_catalog_uptr : source.values()) { + auto copy_catalog_uptr = std::make_unique(*orig_catalog_uptr); + dest.add_new(copy_catalog_uptr->catalog_id, std::move(copy_catalog_uptr)); + } +} + +void AssetCatalogCollection::add_catalogs_from_existing(const AssetCatalogCollection &other) +{ + copy_catalog_map_into_existing(other.catalogs_, catalogs_); +} + OwningAssetCatalogMap AssetCatalogCollection::copy_catalog_map(const OwningAssetCatalogMap &orig) { OwningAssetCatalogMap copy; - - for (const auto &orig_catalog_uptr : orig.values()) { - auto copy_catalog_uptr = std::make_unique(*orig_catalog_uptr); - copy.add_new(copy_catalog_uptr->catalog_id, std::move(copy_catalog_uptr)); - } - + copy_catalog_map_into_existing(orig, copy); return copy; } diff --git a/source/blender/asset_system/intern/asset_library.cc b/source/blender/asset_system/intern/asset_library.cc index 9a6b73ef501..2379e738e37 100644 --- a/source/blender/asset_system/intern/asset_library.cc +++ b/source/blender/asset_system/intern/asset_library.cc @@ -65,6 +65,12 @@ bool AS_asset_library_has_any_unsaved_catalogs() return service->has_any_unsaved_catalogs(); } +std::string AS_asset_library_root_path_from_library_ref( + const AssetLibraryReference &library_reference) +{ + return AssetLibraryService::root_path_from_library_ref(library_reference); +} + std::string AS_asset_library_find_suitable_root_path_from_path( const blender::StringRefNull input_path) { @@ -114,9 +120,11 @@ void AS_asset_library_refresh_catalog_simplename(struct ::AssetLibrary *asset_li void AS_asset_library_remap_ids(const IDRemapper *mappings) { AssetLibraryService *service = AssetLibraryService::get(); - service->foreach_loaded_asset_library([mappings](asset_system::AssetLibrary &library) { - library.remap_ids_and_remove_invalid(*mappings); - }); + service->foreach_loaded_asset_library( + [mappings](asset_system::AssetLibrary &library) { + library.remap_ids_and_remove_invalid(*mappings); + }, + true); } namespace blender::asset_system { @@ -135,6 +143,13 @@ AssetLibrary::~AssetLibrary() } } +void AssetLibrary::foreach_loaded(FunctionRef fn, + const bool include_all_library) +{ + AssetLibraryService *service = AssetLibraryService::get(); + service->foreach_loaded_asset_library(fn, include_all_library); +} + void AssetLibrary::load_catalogs() { auto catalog_service = std::make_unique(root_path()); @@ -144,7 +159,9 @@ void AssetLibrary::load_catalogs() void AssetLibrary::refresh() { - this->catalog_service->reload_catalogs(); + if (on_refresh_) { + on_refresh_(*this); + } } AssetRepresentation &AssetLibrary::add_external_asset(StringRef relative_asset_path, diff --git a/source/blender/asset_system/intern/asset_library_service.cc b/source/blender/asset_system/intern/asset_library_service.cc index 79097ac8cd2..af48a173bc0 100644 --- a/source/blender/asset_system/intern/asset_library_service.cc +++ b/source/blender/asset_system/intern/asset_library_service.cc @@ -14,6 +14,7 @@ #include "CLG_log.h" +#include "AS_asset_catalog_tree.hh" #include "AS_asset_library.hh" #include "asset_library_service.hh" #include "utils.hh" @@ -56,23 +57,29 @@ void AssetLibraryService::destroy() AssetLibrary *AssetLibraryService::get_asset_library( const Main *bmain, const AssetLibraryReference &library_reference) { - if (library_reference.type == ASSET_LIBRARY_LOCAL) { - /* For the "Current File" library we get the asset library root path based on main. */ - std::string root_path = bmain ? AS_asset_library_find_suitable_root_path_from_main(bmain) : ""; + const eAssetLibraryType type = eAssetLibraryType(library_reference.type); - if (root_path.empty()) { - /* File wasn't saved yet. */ - return get_asset_library_current_file(); + switch (type) { + case ASSET_LIBRARY_LOCAL: { + /* For the "Current File" library we get the asset library root path based on main. */ + std::string root_path = bmain ? AS_asset_library_find_suitable_root_path_from_main(bmain) : + ""; + + if (root_path.empty()) { + /* File wasn't saved yet. */ + return get_asset_library_current_file(); + } + return get_asset_library_on_disk(root_path); } + case ASSET_LIBRARY_ALL: + return get_asset_library_all(bmain); + case ASSET_LIBRARY_CUSTOM: { + std::string root_path = root_path_from_library_ref(library_reference); - return get_asset_library_on_disk(root_path); - } - if (library_reference.type == ASSET_LIBRARY_CUSTOM) { - bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_from_index( - &U, library_reference.custom_library_index); - - if (user_library) { - return get_asset_library_on_disk(user_library->path); + if (!root_path.empty()) { + return get_asset_library_on_disk(root_path); + } + break; } } @@ -100,6 +107,8 @@ AssetLibrary *AssetLibraryService::get_asset_library_on_disk(StringRefNull root_ lib->on_blend_save_handler_register(); lib->load_catalogs(); + /* Reload catalogs on refresh. */ + lib->on_refresh_ = [](AssetLibrary &self) { self.catalog_service->reload_catalogs(); }; on_disk_libraries_.add_new(normalized_root_path, std::move(lib_uptr)); CLOG_INFO(&LOG, 2, "get \"%s\" (loaded)", normalized_root_path.c_str()); @@ -110,6 +119,7 @@ AssetLibrary *AssetLibraryService::get_asset_library_current_file() { if (current_file_library_) { CLOG_INFO(&LOG, 2, "get current file lib (cached)"); + current_file_library_->refresh(); } else { CLOG_INFO(&LOG, 2, "get current file lib (loaded)"); @@ -121,6 +131,74 @@ AssetLibrary *AssetLibraryService::get_asset_library_current_file() return lib; } +static void rebuild_all_library(AssetLibrary &all_library, const bool reload_catalogs) +{ + /* Start with empty catalog storage. */ + all_library.catalog_service = std::make_unique( + AssetCatalogService::read_only_tag()); + + AssetLibrary::foreach_loaded( + [&](AssetLibrary &nested) { + if (reload_catalogs) { + nested.catalog_service->reload_catalogs(); + } + all_library.catalog_service->add_from_existing(*nested.catalog_service); + }, + false); + all_library.catalog_service->rebuild_tree(); +} + +AssetLibrary *AssetLibraryService::get_asset_library_all(const Main *bmain) +{ + /* (Re-)load all other asset libraries. */ + for (AssetLibraryReference &library_ref : all_valid_asset_library_refs()) { + /* Skip self :) */ + if (library_ref.type == ASSET_LIBRARY_ALL) { + continue; + } + + /* Ensure all asset libraries are loaded. */ + get_asset_library(bmain, library_ref); + } + + if (all_library_) { + CLOG_INFO(&LOG, 2, "get all lib (cached)"); + all_library_->refresh(); + return all_library_.get(); + } + + CLOG_INFO(&LOG, 2, "get all lib (loaded)"); + all_library_ = std::make_unique(); + + /* Don't reload catalogs on this initial read, they've just been loaded above. */ + rebuild_all_library(*all_library_, /*reload_catlogs=*/false); + + all_library_->on_refresh_ = [](AssetLibrary &all_library) { + rebuild_all_library(all_library, /*reload_catalogs=*/true); + }; + + return all_library_.get(); +} + +std::string AssetLibraryService::root_path_from_library_ref( + const AssetLibraryReference &library_reference) +{ + if (ELEM(library_reference.type, ASSET_LIBRARY_ALL, ASSET_LIBRARY_LOCAL)) { + return ""; + } + + BLI_assert(library_reference.type == ASSET_LIBRARY_CUSTOM); + BLI_assert(library_reference.custom_library_index >= 0); + + bUserAssetLibrary *user_library = BKE_preferences_asset_library_find_from_index( + &U, library_reference.custom_library_index); + if (!user_library || !user_library->path[0]) { + return ""; + } + + return user_library->path; +} + void AssetLibraryService::allocate_service_instance() { instance_ = std::make_unique(); @@ -164,21 +242,25 @@ void AssetLibraryService::app_handler_unregister() bool AssetLibraryService::has_any_unsaved_catalogs() const { - if (current_file_library_ && current_file_library_->catalog_service->has_unsaved_changes()) { - return true; - } + bool has_unsaved_changes = false; - for (const auto &asset_lib_uptr : on_disk_libraries_.values()) { - if (asset_lib_uptr->catalog_service->has_unsaved_changes()) { - return true; - } - } - - return false; + foreach_loaded_asset_library( + [&has_unsaved_changes](AssetLibrary &library) { + if (library.catalog_service->has_unsaved_changes()) { + has_unsaved_changes = true; + } + }, + true); + return has_unsaved_changes; } -void AssetLibraryService::foreach_loaded_asset_library(FunctionRef fn) const +void AssetLibraryService::foreach_loaded_asset_library(FunctionRef fn, + const bool include_all_library) const { + if (include_all_library && all_library_) { + fn(*all_library_); + } + if (current_file_library_) { fn(*current_file_library_); } diff --git a/source/blender/asset_system/intern/asset_library_service.hh b/source/blender/asset_system/intern/asset_library_service.hh index fd7d4f25d56..1dd9bda7aca 100644 --- a/source/blender/asset_system/intern/asset_library_service.hh +++ b/source/blender/asset_system/intern/asset_library_service.hh @@ -40,6 +40,8 @@ class AssetLibraryService { * the file was saved, a valid path for the library can be determined and #on_disk_libraries_ * above should be used. */ std::unique_ptr current_file_library_; + /** The "all" asset library, merging all other libraries into one. */ + std::unique_ptr all_library_; /* Handlers for managing the life cycle of the AssetLibraryService instance. */ bCallbackFuncStore on_load_callback_store_; @@ -55,6 +57,8 @@ class AssetLibraryService { /** Destroy the AssetLibraryService singleton. It will be reallocated by #get() if necessary. */ static void destroy(); + static std::string root_path_from_library_ref(const AssetLibraryReference &library_reference); + AssetLibrary *get_asset_library(const Main *bmain, const AssetLibraryReference &library_reference); @@ -66,10 +70,15 @@ class AssetLibraryService { /** Get the "Current File" asset library. */ AssetLibrary *get_asset_library_current_file(); + /** Get the "All" asset library, which loads all others and merges them into one. */ + AssetLibrary *get_asset_library_all(const Main *bmain); + /** Returns whether there are any known asset libraries with unsaved catalog edits. */ bool has_any_unsaved_catalogs() const; - void foreach_loaded_asset_library(FunctionRef fn) const; + /** See AssetLibrary::foreach_loaded(). */ + void foreach_loaded_asset_library(FunctionRef fn, + bool include_all_library) const; protected: /** Allocate a new instance of the service and assign it to `instance_`. */ diff --git a/source/blender/editors/asset/ED_asset_catalog.h b/source/blender/editors/asset/ED_asset_catalog.h index 04df381bec9..9f6850b7266 100644 --- a/source/blender/editors/asset/ED_asset_catalog.h +++ b/source/blender/editors/asset/ED_asset_catalog.h @@ -19,6 +19,8 @@ struct Main; void ED_asset_catalogs_save_from_main_path(struct AssetLibrary *library, const struct Main *bmain); +/** Saving catalog edits when the file is saved is a global option shared for each asset library, + * and as such ignores the per asset library #ED_asset_catalogs_read_only(). */ void ED_asset_catalogs_set_save_catalogs_when_file_is_saved(bool should_save); bool ED_asset_catalogs_get_save_catalogs_when_file_is_saved(void); diff --git a/source/blender/editors/asset/ED_asset_catalog.hh b/source/blender/editors/asset/ED_asset_catalog.hh index 4d61f816085..139a25fd10a 100644 --- a/source/blender/editors/asset/ED_asset_catalog.hh +++ b/source/blender/editors/asset/ED_asset_catalog.hh @@ -6,6 +6,10 @@ * UI/Editor level API for catalog operations, creating richer functionality than the asset system * catalog API provides (which this uses internally). * + * Functions can be expected to not perform any change when #ED_asset_catalogs_read_only() returns + * true. Generally UI code should disable such functionality in this case, so these functions are + * not called at all. + * * Note that `ED_asset_catalog.h` is part of this API. */ @@ -19,6 +23,12 @@ struct AssetLibrary; +/** + * Returns if the catalogs of \a library are allowed to be editable, or if the UI should forbid + * edits. + */ +[[nodiscard]] bool ED_asset_catalogs_read_only(const AssetLibrary &library); + blender::asset_system::AssetCatalog *ED_asset_catalog_add( AssetLibrary *library, blender::StringRefNull name, blender::StringRef parent_path = nullptr); void ED_asset_catalog_remove(AssetLibrary *library, diff --git a/source/blender/editors/asset/ED_asset_library.h b/source/blender/editors/asset/ED_asset_library.h index cc0d97054b6..c4baadc23c8 100644 --- a/source/blender/editors/asset/ED_asset_library.h +++ b/source/blender/editors/asset/ED_asset_library.h @@ -29,10 +29,13 @@ AssetLibraryReference ED_asset_library_reference_from_enum_value(int value); * Since this is meant for UI display, skips non-displayable libraries, that is, libraries with an * empty name or path. * - * \param include_local_library: Whether to include the "Current File" library or not. + * \param include_generated: Whether to include libraries that are generated and thus cannot be + * written to. Setting this to false means only custom libraries will be + * included, since they are stored on disk with a single root directory, + * thus have a well defined location that can be written to. */ const struct EnumPropertyItem *ED_asset_library_reference_to_rna_enum_itemf( - bool include_local_library); + bool include_generated); #ifdef __cplusplus } diff --git a/source/blender/editors/asset/ED_asset_list.hh b/source/blender/editors/asset/ED_asset_list.hh index 541fa315f77..c99890974d5 100644 --- a/source/blender/editors/asset/ED_asset_list.hh +++ b/source/blender/editors/asset/ED_asset_list.hh @@ -15,6 +15,21 @@ struct AssetLibraryReference; struct FileDirEntry; struct bContext; +namespace blender::asset_system { +class AssetLibrary; +} + +/** + * Get the asset library being read into an asset-list and identified using \a library_reference. + * + * \note The asset library may be allocated and loaded asynchronously, so it's not available right + * after fetching, and this function will return null. The asset list code sends `NC_ASSET | + * ND_ASSET_LIST_READING` notifiers until loading is done, they can be used to continuously + * call this function to retrieve the asset library once available. + */ +blender::asset_system::AssetLibrary *ED_assetlist_library_get_once_available( + const AssetLibraryReference &library_reference); + /* Can return false to stop iterating. */ using AssetListIterFn = blender::FunctionRef; void ED_assetlist_iterate(const AssetLibraryReference &library_reference, AssetListIterFn fn); diff --git a/source/blender/editors/asset/intern/asset_catalog.cc b/source/blender/editors/asset/intern/asset_catalog.cc index 10aa27a7687..2bfde0aeaae 100644 --- a/source/blender/editors/asset/intern/asset_catalog.cc +++ b/source/blender/editors/asset/intern/asset_catalog.cc @@ -19,6 +19,13 @@ using namespace blender; using namespace blender::asset_system; +bool ED_asset_catalogs_read_only(const ::AssetLibrary &library) +{ + asset_system::AssetCatalogService *catalog_service = AS_asset_library_get_catalog_service( + &library); + return catalog_service->is_read_only(); +} + struct CatalogUniqueNameFnData { const AssetCatalogService &catalog_service; StringRef parent_path; @@ -53,6 +60,9 @@ asset_system::AssetCatalog *ED_asset_catalog_add(::AssetLibrary *library, if (!catalog_service) { return nullptr; } + if (ED_asset_catalogs_read_only(*library)) { + return nullptr; + } std::string unique_name = catalog_name_ensure_unique(*catalog_service, name, parent_path); AssetCatalogPath fullpath = AssetCatalogPath(parent_path) / unique_name; @@ -76,6 +86,9 @@ void ED_asset_catalog_remove(::AssetLibrary *library, const CatalogID &catalog_i BLI_assert_unreachable(); return; } + if (ED_asset_catalogs_read_only(*library)) { + return; + } catalog_service->undo_push(); catalog_service->tag_has_unsaved_changes(nullptr); @@ -93,6 +106,9 @@ void ED_asset_catalog_rename(::AssetLibrary *library, BLI_assert_unreachable(); return; } + if (ED_asset_catalogs_read_only(*library)) { + return; + } AssetCatalog *catalog = catalog_service->find_catalog(catalog_id); @@ -120,6 +136,9 @@ void ED_asset_catalog_move(::AssetLibrary *library, BLI_assert_unreachable(); return; } + if (ED_asset_catalogs_read_only(*library)) { + return; + } AssetCatalog *src_catalog = catalog_service->find_catalog(src_catalog_id); if (!src_catalog) { @@ -161,6 +180,9 @@ void ED_asset_catalogs_save_from_main_path(::AssetLibrary *library, const Main * BLI_assert_unreachable(); return; } + if (ED_asset_catalogs_read_only(*library)) { + return; + } /* Since writing to disk also means loading any on-disk changes, it may be a good idea to store * an undo step. */ diff --git a/source/blender/editors/asset/intern/asset_library_reference_enum.cc b/source/blender/editors/asset/intern/asset_library_reference_enum.cc index 773838a54cd..d20f3205a77 100644 --- a/source/blender/editors/asset/intern/asset_library_reference_enum.cc +++ b/source/blender/editors/asset/intern/asset_library_reference_enum.cc @@ -47,7 +47,7 @@ AssetLibraryReference ED_asset_library_reference_from_enum_value(int value) if (value < ASSET_LIBRARY_CUSTOM) { library.type = value; library.custom_library_index = -1; - BLI_assert(ELEM(value, ASSET_LIBRARY_LOCAL)); + BLI_assert(ELEM(value, ASSET_LIBRARY_ALL, ASSET_LIBRARY_LOCAL)); return library; } @@ -70,16 +70,18 @@ AssetLibraryReference ED_asset_library_reference_from_enum_value(int value) return library; } -const EnumPropertyItem *ED_asset_library_reference_to_rna_enum_itemf( - const bool include_local_library) +const EnumPropertyItem *ED_asset_library_reference_to_rna_enum_itemf(const bool include_generated) { EnumPropertyItem *item = nullptr; int totitem = 0; - if (include_local_library) { - const EnumPropertyItem predefined_items[] = { - /* For the future. */ - // {ASSET_REPO_BUNDLED, "BUNDLED", 0, "Bundled", "Show the default user assets"}, + if (include_generated) { + const EnumPropertyItem generated_items[] = { + {ASSET_LIBRARY_ALL, + "ALL", + ICON_NONE, + "All", + "Show assets from all of the listed asset libraries"}, {ASSET_LIBRARY_LOCAL, "LOCAL", ICON_CURRENT_FILE, @@ -88,8 +90,9 @@ const EnumPropertyItem *ED_asset_library_reference_to_rna_enum_itemf( {0, nullptr, 0, nullptr, nullptr}, }; - /* Add predefined items. */ - RNA_enum_items_add(&item, &totitem, predefined_items); + /* Add predefined libraries that are generated and not simple directories that can be written + * to. */ + RNA_enum_items_add(&item, &totitem, generated_items); } /* Add separator if needed. */ diff --git a/source/blender/editors/asset/intern/asset_list.cc b/source/blender/editors/asset/intern/asset_list.cc index caceedbd4a5..64934316413 100644 --- a/source/blender/editors/asset/intern/asset_list.cc +++ b/source/blender/editors/asset/intern/asset_list.cc @@ -12,6 +12,8 @@ #include #include +#include "AS_asset_library.hh" + #include "BKE_context.h" #include "BLI_map.hh" @@ -112,6 +114,7 @@ class AssetList : NonCopyable { bool needsRefetch() const; bool isLoaded() const; + asset_system::AssetLibrary *asset_library() const; void iterate(AssetListIterFn fn) const; bool listen(const wmNotifier ¬ifier) const; int size() const; @@ -127,16 +130,7 @@ AssetList::AssetList(eFileSelectType filesel_type, const AssetLibraryReference & void AssetList::setup() { FileList *files = filelist_; - - bUserAssetLibrary *user_library = nullptr; - - /* Ensure valid repository, or fall-back to local one. */ - if (library_ref_.type == ASSET_LIBRARY_CUSTOM) { - BLI_assert(library_ref_.custom_library_index >= 0); - - user_library = BKE_preferences_asset_library_find_from_index( - &U, library_ref_.custom_library_index); - } + std::string asset_lib_path = AS_asset_library_root_path_from_library_ref(library_ref_); /* Relevant bits from file_refresh(). */ /* TODO pass options properly. */ @@ -158,13 +152,10 @@ void AssetList::setup() filelist_setindexer(files, use_asset_indexer ? &file_indexer_asset : &file_indexer_noop); char path[FILE_MAXDIR] = ""; - if (user_library) { - BLI_strncpy(path, user_library->path, sizeof(path)); - filelist_setdir(files, path); - } - else { - filelist_setdir(files, path); + if (!asset_lib_path.empty()) { + BLI_strncpy(path, asset_lib_path.c_str(), sizeof(path)); } + filelist_setdir(files, path); } void AssetList::fetch(const bContext &C) @@ -195,6 +186,11 @@ bool AssetList::isLoaded() const return filelist_is_ready(filelist_); } +asset_system::AssetLibrary *AssetList::asset_library() const +{ + return reinterpret_cast(filelist_asset_library(filelist_)); +} + void AssetList::iterate(AssetListIterFn fn) const { FileList *files = filelist_; @@ -373,7 +369,9 @@ void AssetListStorage::remapID(ID *id_new, ID *id_old) std::optional AssetListStorage::asset_library_reference_to_fileselect_type( const AssetLibraryReference &library_reference) { - switch (library_reference.type) { + switch (eAssetLibraryType(library_reference.type)) { + case ASSET_LIBRARY_ALL: + return FILE_ASSET_LIBRARY_ALL; case ASSET_LIBRARY_CUSTOM: return FILE_ASSET_LIBRARY; case ASSET_LIBRARY_LOCAL: @@ -412,6 +410,7 @@ AssetListStorage::AssetListMap &AssetListStorage::global_storage() /** \name C-API * \{ */ +using namespace blender; using namespace blender::ed::asset; void ED_assetlist_storage_fetch(const AssetLibraryReference *library_reference, const bContext *C) @@ -462,6 +461,16 @@ void ED_assetlist_iterate(const AssetLibraryReference &library_reference, AssetL } } +asset_system::AssetLibrary *ED_assetlist_library_get_once_available( + const AssetLibraryReference &library_reference) +{ + const AssetList *list = AssetListStorage::lookup_list(library_reference); + if (!list) { + return nullptr; + } + return list->asset_library(); +} + ImBuf *ED_assetlist_asset_image_get(const AssetHandle *asset_handle) { ImBuf *imbuf = filelist_file_getimage(asset_handle->file_data); diff --git a/source/blender/editors/asset/intern/asset_ops.cc b/source/blender/editors/asset/intern/asset_ops.cc index 3bbfa2ac0f4..cc38bc15364 100644 --- a/source/blender/editors/asset/intern/asset_ops.cc +++ b/source/blender/editors/asset/intern/asset_ops.cc @@ -435,7 +435,18 @@ static void ASSET_OT_library_refresh(struct wmOperatorType *ot) static bool asset_catalog_operator_poll(bContext *C) { const SpaceFile *sfile = CTX_wm_space_file(C); - return sfile && ED_fileselect_active_asset_library_get(sfile); + if (!sfile) { + return false; + } + const AssetLibrary *asset_library = ED_fileselect_active_asset_library_get(sfile); + if (!asset_library) { + return false; + } + if (ED_asset_catalogs_read_only(*asset_library)) { + CTX_wm_operator_poll_msg_set(C, "Asset catalogs cannot be edited in this asset library"); + return false; + } + return true; } static int asset_catalog_new_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/space_file/asset_catalog_tree_view.cc b/source/blender/editors/space_file/asset_catalog_tree_view.cc index 19b3f135e24..8b7b19387c2 100644 --- a/source/blender/editors/space_file/asset_catalog_tree_view.cc +++ b/source/blender/editors/space_file/asset_catalog_tree_view.cc @@ -119,6 +119,8 @@ class AssetCatalogDropController : public ui::AbstractViewItemDropController { static AssetCatalog *get_drag_catalog(const wmDrag &drag, const ::AssetLibrary &asset_library); static bool has_droppable_asset(const wmDrag &drag, const char **r_disabled_hint); + static bool can_modify_catalogs(const ::AssetLibrary &asset_library, + const char **r_disabled_hint); static bool drop_assets_into_catalog(struct bContext *C, const AssetCatalogTreeView &tree_view, const wmDrag &drag, @@ -321,7 +323,9 @@ void AssetCatalogTreeViewItem::build_context_menu(bContext &C, uiLayout &column) bool AssetCatalogTreeViewItem::supports_renaming() const { - return true; + const AssetCatalogTreeView &tree_view = static_cast( + get_tree_view()); + return !ED_asset_catalogs_read_only(*tree_view.asset_library_); } bool AssetCatalogTreeViewItem::rename(StringRefNull new_name) @@ -360,7 +364,12 @@ AssetCatalogDropController::AssetCatalogDropController(AssetCatalogTreeView &tre bool AssetCatalogDropController::can_drop(const wmDrag &drag, const char **r_disabled_hint) const { if (drag.type == WM_DRAG_ASSET_CATALOG) { - const AssetCatalog *drag_catalog = get_drag_catalog(drag, get_asset_library()); + const ::AssetLibrary &library = get_asset_library(); + if (!can_modify_catalogs(library, r_disabled_hint)) { + return false; + } + + const AssetCatalog *drag_catalog = get_drag_catalog(drag, library); /* NOTE: Technically it's not an issue to allow this (the catalog will just receive a new * path and the catalog system will generate missing parents from the path). But it does * appear broken to users, so disabling entirely. */ @@ -512,6 +521,16 @@ bool AssetCatalogDropController::has_droppable_asset(const wmDrag &drag, return false; } +bool AssetCatalogDropController::can_modify_catalogs(const ::AssetLibrary &library, + const char **r_disabled_hint) +{ + if (ED_asset_catalogs_read_only(library)) { + *r_disabled_hint = "Catalogs cannot be edited in this asset library"; + return false; + } + return true; +} + ::AssetLibrary &AssetCatalogDropController::get_asset_library() const { return *get_view().asset_library_; @@ -579,9 +598,12 @@ bool AssetCatalogTreeViewAllItem::DropController::can_drop(const wmDrag &drag, if (drag.type != WM_DRAG_ASSET_CATALOG) { return false; } + ::AssetLibrary &library = *get_view().asset_library_; + if (!AssetCatalogDropController::can_modify_catalogs(library, r_disabled_hint)) { + return false; + } - const AssetCatalog *drag_catalog = AssetCatalogDropController::get_drag_catalog( - drag, *get_view().asset_library_); + const AssetCatalog *drag_catalog = AssetCatalogDropController::get_drag_catalog(drag, library); if (drag_catalog->path.parent() == "") { *r_disabled_hint = "Catalog is already placed at the highest level"; return false; diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc index cd1c3f8280b..22986672650 100644 --- a/source/blender/editors/space_file/filelist.cc +++ b/source/blender/editors/space_file/filelist.cc @@ -320,6 +320,10 @@ static void filelist_readjob_main_assets(FileListReadJob *job_params, bool *stop, bool *do_update, float *progress); +static void filelist_readjob_all_asset_library(FileListReadJob *job_params, + bool *stop, + bool *do_update, + float *progress); /* helper, could probably go in BKE actually? */ static int groupname_to_code(const char *group); @@ -1362,11 +1366,10 @@ static bool filelist_checkdir_main(FileList *filelist, char *r_dir, const bool d return filelist_checkdir_lib(filelist, r_dir, do_change); } -static bool filelist_checkdir_main_assets(FileList * /*filelist*/, - char * /*r_dir*/, - const bool /*do_change*/) +static bool filelist_checkdir_return_always_valid(struct FileList * /*filelist*/, + char * /*r_dir*/, + const bool /*do_change*/) { - /* Main is always valid. */ return true; } @@ -1768,12 +1771,19 @@ void filelist_settype(FileList *filelist, short type) filelist->tags |= FILELIST_TAGS_USES_MAIN_DATA; break; case FILE_MAIN_ASSET: - filelist->check_dir_fn = filelist_checkdir_main_assets; + filelist->check_dir_fn = filelist_checkdir_return_always_valid; filelist->read_job_fn = filelist_readjob_main_assets; filelist->prepare_filter_fn = prepare_filter_asset_library; filelist->filter_fn = is_filtered_main_assets; filelist->tags |= FILELIST_TAGS_USES_MAIN_DATA | FILELIST_TAGS_NO_THREADS; break; + case FILE_ASSET_LIBRARY_ALL: + filelist->check_dir_fn = filelist_checkdir_return_always_valid; + filelist->read_job_fn = filelist_readjob_all_asset_library; + filelist->prepare_filter_fn = prepare_filter_asset_library; + filelist->filter_fn = is_filtered_asset_library; + filelist->tags |= FILELIST_TAGS_USES_MAIN_DATA; + break; default: filelist->check_dir_fn = filelist_checkdir_dir; filelist->read_job_fn = filelist_readjob_dir; @@ -2852,6 +2862,9 @@ void filelist_entry_parent_select_set(FileList *filelist, bool filelist_islibrary(FileList *filelist, char *dir, char **r_group) { + if (filelist->asset_library) { + return true; + } return BLO_library_path_explode(filelist->filelist.root, dir, r_group, nullptr); } @@ -2893,6 +2906,11 @@ struct FileListReadJob { * `Materials/Material.001`). */ char cur_relbase[FILE_MAX_LIBEXTRA]; + /** The current asset library to load. Usually the same as #FileList.asset_library, however + * sometimes the #FileList one is a combination of multiple other ones ("All" asset library), + * which need to be loaded individually. Then this can be set to override the #FileList library. + * Use this in all loading code. */ + asset_system::AssetLibrary *load_asset_library; /** Set to request a partial read that only adds files representing #Main data (IDs). Used when * #Main may have received changes of interest (e.g. asset removed or renamed). */ bool only_main_data; @@ -3070,7 +3088,6 @@ static void filelist_readjob_list_lib_add_datablock(FileListReadJob *job_params, const int idcode, const char *group_name) { - FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */ FileListInternEntry *entry = MEM_cnew(__func__); if (prefix_relpath_with_group_name) { std::string datablock_path = StringRef(group_name) + "/" + datablock_info->name; @@ -3086,7 +3103,7 @@ static void filelist_readjob_list_lib_add_datablock(FileListReadJob *job_params, if (datablock_info->asset_data) { entry->typeflag |= FILE_TYPE_ASSET; - if (filelist->asset_library) { + if (job_params->load_asset_library) { /* Take ownership over the asset data (shallow copies into unique_ptr managed memory) to * pass it on to the asset system. */ std::unique_ptr metadata = std::make_unique(*datablock_info->asset_data); @@ -3096,7 +3113,7 @@ static void filelist_readjob_list_lib_add_datablock(FileListReadJob *job_params, datablock_info->asset_data = metadata.get(); datablock_info->free_asset_data = false; - entry->asset = &filelist->asset_library->add_external_asset( + entry->asset = &job_params->load_asset_library->add_external_asset( entry->relpath, datablock_info->name, std::move(metadata)); } } @@ -3600,7 +3617,7 @@ static void filelist_readjob_recursive_dir_add_items(const bool do_lib, } /* Only load assets when browsing an asset library. For normal file browsing we return all * entries. `FLF_ASSETS_ONLY` filter can be enabled/disabled by the user. */ - if (filelist->asset_library) { + if (job_params->load_asset_library) { list_lib_options |= LIST_LIB_ASSETS_ONLY; } std::optional lib_entries_num = filelist_readjob_list_lib( @@ -3715,6 +3732,8 @@ static void filelist_readjob_load_asset_library_data(FileListReadJob *job_params * #filelist_readjob_endjob() will move it into the real filelist. */ tmp_filelist->asset_library = AS_asset_library_load(job_params->current_main, *job_params->filelist->asset_library_ref); + /* Set asset library to load (may be overridden later for loading nested ones). */ + job_params->load_asset_library = tmp_filelist->asset_library; *do_update = true; } @@ -3752,8 +3771,8 @@ static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params, entry->local_data.preview_image = BKE_asset_metadata_preview_get_from_id(id_iter->asset_data, id_iter); entry->local_data.id = id_iter; - if (filelist->asset_library) { - entry->asset = &filelist->asset_library->add_local_id_asset(entry->relpath, *id_iter); + if (job_params->load_asset_library) { + entry->asset = &job_params->load_asset_library->add_local_id_asset(entry->relpath, *id_iter); } entries_num++; BLI_addtail(&tmp_entries, entry); @@ -3780,6 +3799,10 @@ static void filelist_readjob_main_assets_add_items(FileListReadJob *job_params, */ static bool filelist_contains_main(const FileList *filelist, const Main *bmain) { + if (filelist->asset_library_ref && (filelist->asset_library_ref->type == ASSET_LIBRARY_ALL)) { + return true; + } + const char *blendfile_path = BKE_main_blendfile_path(bmain); return blendfile_path[0] && BLI_path_contains(filelist->filelist.root, blendfile_path); } @@ -3797,6 +3820,8 @@ static void filelist_readjob_asset_library(FileListReadJob *job_params, /* A valid, but empty file-list from now. */ filelist->filelist.entries_num = 0; + BLI_assert(job_params->filelist->asset_library_ref != nullptr); + /* NOP if already read. */ filelist_readjob_load_asset_library_data(job_params, do_update); @@ -3834,6 +3859,57 @@ static void filelist_readjob_main_assets(FileListReadJob *job_params, filelist_readjob_main_assets_add_items(job_params, stop, do_update, progress); } +static void filelist_readjob_all_asset_library(FileListReadJob *job_params, + bool *stop, + bool *do_update, + float *progress) +{ + FileList *filelist = job_params->tmp_filelist; /* Use the thread-safe filelist queue. */ + BLI_assert(BLI_listbase_is_empty(&filelist->filelist.entries) && + (filelist->filelist.entries_num == FILEDIR_NBR_ENTRIES_UNSET)); + + filelist_readjob_load_asset_library_data(job_params, do_update); + + /* A valid, but empty file-list from now. */ + filelist->filelist.entries_num = 0; + + filelist_readjob_main_assets_add_items(job_params, stop, do_update, progress); + + /* When only doing partialy reload for main data, we're done. */ + if (job_params->only_main_data) { + return; + } + + /* Count how many asset libraries need to be loaded, for progress reporting. Not very precise. */ + int library_count = 0; + asset_system::AssetLibrary::foreach_loaded([&library_count](auto &) { library_count++; }, false); + + BLI_assert(filelist->asset_library != nullptr); + + int libraries_done_count = 0; + /* The "All" asset library was loaded, which means all other asset libraries are also loaded. + * Load their assets from disk into the "All" library. */ + asset_system::AssetLibrary::foreach_loaded( + [&](asset_system::AssetLibrary &nested_library) { + StringRefNull root_path = nested_library.root_path(); + if (root_path.is_empty()) { + return; + } + + /* Override library info to read this library. */ + job_params->load_asset_library = &nested_library; + BLI_strncpy(filelist->filelist.root, root_path.c_str(), sizeof(filelist->filelist.root)); + + float progress_this = 0.0f; + filelist_readjob_recursive_dir_add_items( + true, job_params, stop, do_update, &progress_this); + + libraries_done_count++; + *progress = float(libraries_done_count) / library_count; + }, + false); +} + /** * Check if the read-job is requesting a partial reread of the file list only. */ diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index af2c9d4e757..0b0ab2b0d66 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -423,16 +423,20 @@ static void fileselect_refresh_asset_params(FileAssetSelectParams *asset_params) } switch (library->type) { + case ASSET_LIBRARY_ALL: + base_params->dir[0] = '\0'; + base_params->type = FILE_ASSET_LIBRARY_ALL; + break; case ASSET_LIBRARY_LOCAL: base_params->dir[0] = '\0'; + base_params->type = FILE_MAIN_ASSET; break; case ASSET_LIBRARY_CUSTOM: BLI_assert(user_library); BLI_strncpy(base_params->dir, user_library->path, sizeof(base_params->dir)); + base_params->type = FILE_ASSET_LIBRARY; break; } - base_params->type = (library->type == ASSET_LIBRARY_LOCAL) ? FILE_MAIN_ASSET : - FILE_ASSET_LIBRARY; } void fileselect_refresh_params(SpaceFile *sfile) diff --git a/source/blender/makesdna/DNA_asset_defaults.h b/source/blender/makesdna/DNA_asset_defaults.h index cef4c1270b8..63239f23e4e 100644 --- a/source/blender/makesdna/DNA_asset_defaults.h +++ b/source/blender/makesdna/DNA_asset_defaults.h @@ -21,7 +21,7 @@ #define _DNA_DEFAULT_AssetLibraryReference \ { \ .type = ASSET_LIBRARY_LOCAL, \ - /* Not needed really (should be ignored for #ASSET_LIBRARY_LOCAL), but helps debugging. */ \ + /* Not needed really (should be ignored for anything but #ASSET_LIBRARY_CUSTOM), but helps debugging. */ \ .custom_library_index = -1, \ } diff --git a/source/blender/makesdna/DNA_asset_types.h b/source/blender/makesdna/DNA_asset_types.h index f4a57644dff..195cc059f18 100644 --- a/source/blender/makesdna/DNA_asset_types.h +++ b/source/blender/makesdna/DNA_asset_types.h @@ -89,8 +89,7 @@ typedef enum eAssetLibraryType { // ASSET_LIBRARY_BUNDLED = 0, /** Display assets from the current session (current "Main"). */ ASSET_LIBRARY_LOCAL = 1, - /* For the future. Display assets for the current project. */ - // ASSET_LIBRARY_PROJECT = 2, + ASSET_LIBRARY_ALL = 2, /** Display assets from custom asset libraries, as defined in the preferences * (#bUserAssetLibrary). The name will be taken from #FileSelectParams.asset_library_ref.idname diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 72e39647093..54edf795e6c 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1001,6 +1001,8 @@ typedef enum eFileSelectType { FILE_MAIN_ASSET = 3, /** Load assets of an asset library containing external files. */ FILE_ASSET_LIBRARY = 4, + /** Load all asset libraries. */ + FILE_ASSET_LIBRARY_ALL = 5, FILE_UNIX = 8, FILE_BLENDER = 8, /* don't display relative paths */ From 66af16571dfe3cb314a59edfee3469a557821e47 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 10 Jan 2023 15:37:31 +0100 Subject: [PATCH 0566/1522] Refactor: Use new "All" asset library to extend node menus with assets Updates the add and search menu of the node editor to use the new "All" asset library introduced in the previous commit. This simplifies code by removing redundant logic to merge contents of multiple asset libraries. --- .../editors/space_node/add_menu_assets.cc | 117 ++++++++---------- .../editors/space_node/add_node_search.cc | 33 ++--- 2 files changed, 57 insertions(+), 93 deletions(-) diff --git a/source/blender/editors/space_node/add_menu_assets.cc b/source/blender/editors/space_node/add_menu_assets.cc index bb5f33f8cf0..fc250b63ffe 100644 --- a/source/blender/editors/space_node/add_menu_assets.cc +++ b/source/blender/editors/space_node/add_menu_assets.cc @@ -49,13 +49,6 @@ struct LibraryAsset { AssetHandle handle; }; -struct LibraryCatalog { - asset_system::AssetLibrary *library; - /* Catalog pointers are not save to store. Use the catalog ID instead and lookup the catalog when - * needed. */ - const asset_system::CatalogID catalog_id; -}; - struct AssetItemTree { asset_system::AssetCatalogTree catalogs; MultiValueMap assets_per_path; @@ -63,14 +56,18 @@ struct AssetItemTree { full_catalog_per_tree_item; }; +static AssetLibraryReference all_library_reference() +{ + AssetLibraryReference all_library_ref{}; + all_library_ref.custom_library_index = -1; + all_library_ref.type = ASSET_LIBRARY_ALL; + return all_library_ref; +} + static bool all_loading_finished() { - for (const AssetLibraryReference &library : asset_system::all_valid_asset_library_refs()) { - if (!ED_assetlist_is_loaded(&library)) { - return false; - } - } - return true; + AssetLibraryReference all_library_ref = all_library_reference(); + return ED_assetlist_is_loaded(&all_library_ref); } static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree *node_tree) @@ -78,68 +75,52 @@ static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree *node if (!node_tree) { return {}; } - const Main &bmain = *CTX_data_main(&C); - const Vector all_libraries = asset_system::all_valid_asset_library_refs(); - - /* Merge catalogs from all libraries to deduplicate menu items. Also store the catalog and - * library for each asset ID in order to use them later when retrieving assets and removing - * empty catalogs. */ - Map id_to_catalog_map; - asset_system::AssetCatalogTree catalogs_from_all_libraries; - for (const AssetLibraryReference &library_ref : all_libraries) { - if (asset_system::AssetLibrary *library = AS_asset_library_load(&bmain, library_ref)) { - if (asset_system::AssetCatalogTree *tree = library->catalog_service->get_catalog_tree()) { - tree->foreach_item([&](asset_system::AssetCatalogTreeItem &item) { - const asset_system::CatalogID &id = item.get_catalog_id(); - asset_system::AssetCatalog *catalog = library->catalog_service->find_catalog(id); - catalogs_from_all_libraries.insert_item(*catalog); - id_to_catalog_map.add(item.get_catalog_id(), LibraryCatalog{library, id}); - }); - } - } - } /* Find all the matching node group assets for every catalog path. */ MultiValueMap assets_per_path; - for (const AssetLibraryReference &library_ref : all_libraries) { - AssetFilterSettings type_filter{}; - type_filter.id_types = FILTER_ID_NT; - ED_assetlist_storage_fetch(&library_ref, &C); - ED_assetlist_ensure_previews_job(&library_ref, &C); - ED_assetlist_iterate(library_ref, [&](AssetHandle asset) { - if (!ED_asset_filter_matches_asset(&type_filter, &asset)) { - return true; - } - const AssetMetaData &meta_data = *ED_asset_handle_get_metadata(&asset); - const IDProperty *tree_type = BKE_asset_metadata_idprop_find(&meta_data, "type"); - if (tree_type == nullptr || IDP_Int(tree_type) != node_tree->type) { - return true; - } - if (BLI_uuid_is_nil(meta_data.catalog_id)) { - return true; - } - const LibraryCatalog *library_catalog = id_to_catalog_map.lookup_ptr(meta_data.catalog_id); - if (library_catalog == nullptr) { - return true; - } - const asset_system::AssetCatalog *catalog = - library_catalog->library->catalog_service->find_catalog(library_catalog->catalog_id); - assets_per_path.add(catalog->path, LibraryAsset{library_ref, asset}); - return true; - }); + AssetFilterSettings type_filter{}; + type_filter.id_types = FILTER_ID_NT; + + const AssetLibraryReference all_library_ref = all_library_reference(); + + ED_assetlist_storage_fetch(&all_library_ref, &C); + ED_assetlist_ensure_previews_job(&all_library_ref, &C); + + asset_system::AssetLibrary *all_library = ED_assetlist_library_get_once_available(all_library_ref); + if (!all_library) { + return {}; } - /* Build the final tree without any of the catalogs that don't have proper node group assets. */ - asset_system::AssetCatalogTree catalogs_with_node_assets; - catalogs_from_all_libraries.foreach_item([&](asset_system::AssetCatalogTreeItem &item) { - if (!assets_per_path.lookup(item.catalog_path()).is_empty()) { - const asset_system::CatalogID &id = item.get_catalog_id(); - const LibraryCatalog &library_catalog = id_to_catalog_map.lookup(id); - asset_system::AssetCatalog *catalog = library_catalog.library->catalog_service->find_catalog( - id); - catalogs_with_node_assets.insert_item(*catalog); + ED_assetlist_iterate(all_library_ref, [&](AssetHandle asset) { + if (!ED_asset_filter_matches_asset(&type_filter, &asset)) { + return true; } + const AssetMetaData &meta_data = *ED_asset_handle_get_metadata(&asset); + const IDProperty *tree_type = BKE_asset_metadata_idprop_find(&meta_data, "type"); + if (tree_type == nullptr || IDP_Int(tree_type) != node_tree->type) { + return true; + } + if (BLI_uuid_is_nil(meta_data.catalog_id)) { + return true; + } + + const asset_system::AssetCatalog *catalog = all_library->catalog_service->find_catalog( + meta_data.catalog_id); + assets_per_path.add(catalog->path, LibraryAsset{all_library_ref, asset}); + return true; + }); + + /* Build an own tree without any of the catalogs that don't have proper node group assets. */ + asset_system::AssetCatalogTree catalogs_with_node_assets; + asset_system::AssetCatalogTree &catalog_tree = *all_library->catalog_service->get_catalog_tree(); + catalog_tree.foreach_item([&](asset_system::AssetCatalogTreeItem &item) { + if (assets_per_path.lookup(item.catalog_path()).is_empty()) { + return; + } + asset_system::AssetCatalog *catalog = all_library->catalog_service->find_catalog( + item.get_catalog_id()); + catalogs_with_node_assets.insert_item(*catalog); }); /* Build another map storing full asset paths for each tree item, in order to have stable diff --git a/source/blender/editors/space_node/add_node_search.cc b/source/blender/editors/space_node/add_node_search.cc index 26f99238a0d..07fc06d0dde 100644 --- a/source/blender/editors/space_node/add_node_search.cc +++ b/source/blender/editors/space_node/add_node_search.cc @@ -93,12 +93,15 @@ static void search_items_for_asset_metadata(const bNodeTree &node_tree, search_items.append(std::move(item)); } -static void gather_search_items_for_asset_library(const bContext &C, - const bNodeTree &node_tree, - const AssetLibraryReference &library_ref, - Set &r_added_assets, - Vector &search_items) +static void gather_search_items_for_all_assets(const bContext &C, + const bNodeTree &node_tree, + Set &r_added_assets, + Vector &search_items) { + AssetLibraryReference library_ref{}; + library_ref.custom_library_index = -1; + library_ref.type = ASSET_LIBRARY_ALL; + AssetFilterSettings filter_settings{}; filter_settings.id_types = FILTER_ID_NT; @@ -117,26 +120,6 @@ static void gather_search_items_for_asset_library(const bContext &C, }); } -static void gather_search_items_for_all_assets(const bContext &C, - const bNodeTree &node_tree, - Set &r_added_assets, - Vector &search_items) -{ - int i; - LISTBASE_FOREACH_INDEX (const bUserAssetLibrary *, asset_library, &U.asset_libraries, i) { - AssetLibraryReference library_ref{}; - library_ref.custom_library_index = i; - library_ref.type = ASSET_LIBRARY_CUSTOM; - /* Skip local assets to avoid duplicates when the asset is part of the local file library. */ - gather_search_items_for_asset_library(C, node_tree, library_ref, r_added_assets, search_items); - } - - AssetLibraryReference library_ref{}; - library_ref.custom_library_index = -1; - library_ref.type = ASSET_LIBRARY_LOCAL; - gather_search_items_for_asset_library(C, node_tree, library_ref, r_added_assets, search_items); -} - static void gather_search_items_for_node_groups(const bContext &C, const bNodeTree &node_tree, const Set &local_assets, From 09a5443f201e4a612e9fb31ce252d3c31370bf91 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Tue, 10 Jan 2023 16:13:37 +0100 Subject: [PATCH 0567/1522] GPencil: Fix unreported wrong fill vertex color in Outline The Fill vertex color was assigned to the wrong stroke. It needs to be set in the perimeter stroke, not in the original one. --- source/blender/editors/gpencil/gpencil_paint.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index 547bda6a1e3..5814248f24c 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -963,7 +963,7 @@ static bGPDstroke *gpencil_stroke_to_outline(tGPsdata *p, bGPDstroke *gps) /* Set pressure constant. */ gps_perimeter->thickness = max_ii((int)outline_thickness, 1); /* Apply Fill Vertex Color data. */ - ED_gpencil_fill_vertex_color_set(p->scene->toolsettings, brush, gps); + ED_gpencil_fill_vertex_color_set(p->scene->toolsettings, brush, gps_perimeter); bGPDspoint *pt; for (int i = 0; i < gps_perimeter->totpoints; i++) { From 3a98dc681206bd37917d76f35bcb9b846bad09e9 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Tue, 10 Jan 2023 16:12:13 +0100 Subject: [PATCH 0568/1522] Fix crash when dragging video into VSE timeline Caused by NULL dereference in strip overlap handling (expand to fit), because `time_dependent_strips` strip collection is not created. Check if strip collection is provided in `query_right_side_strips()`. --- source/blender/sequencer/intern/strip_transform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/sequencer/intern/strip_transform.c b/source/blender/sequencer/intern/strip_transform.c index 58f41d7e180..1edc4b85f96 100644 --- a/source/blender/sequencer/intern/strip_transform.c +++ b/source/blender/sequencer/intern/strip_transform.c @@ -309,7 +309,7 @@ static SeqCollection *query_right_side_strips(const Scene *scene, SeqCollection *collection = SEQ_collection_create(__func__); LISTBASE_FOREACH (Sequence *, seq, seqbase) { - if (SEQ_collection_has_strip(seq, time_dependent_strips)) { + if (time_dependent_strips != NULL && SEQ_collection_has_strip(seq, time_dependent_strips)) { continue; } if (SEQ_collection_has_strip(seq, transformed_strips)) { From df5ebd348b66c16084c47543f95a15fc53da5a0f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 10 Jan 2023 16:31:21 +0100 Subject: [PATCH 0569/1522] Fix T103556: Cycles viewport unexpected pixel changes when hovering over UI With the GPU API the sampler can not be set after texture binding, which caused a delay of the actual change. Now do both in a single call for correctness and performance. --- intern/cycles/blender/display_driver.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/intern/cycles/blender/display_driver.cpp b/intern/cycles/blender/display_driver.cpp index 58f179d1824..8df0061d8ca 100644 --- a/intern/cycles/blender/display_driver.cpp +++ b/intern/cycles/blender/display_driver.cpp @@ -721,8 +721,6 @@ static void draw_tile(const float2 &zoom, return; } - GPU_texture_bind(texture.gpu_texture, 0); - /* Trick to keep sharp rendering without jagged edges on all GPUs. * * The idea here is to enforce driver to use linear interpolation when the image is not zoomed @@ -735,14 +733,14 @@ static void draw_tile(const float2 &zoom, const float zoomed_height = draw_tile.params.size.y * zoom.y; if (texture.width != draw_tile.params.size.x || texture.height != draw_tile.params.size.y) { /* Resolution divider is different from 1, force nearest interpolation. */ - GPU_texture_filter_mode(texture.gpu_texture, false); + GPU_texture_bind_ex(texture.gpu_texture, GPU_SAMPLER_DEFAULT, 0, false); } else if (zoomed_width - draw_tile.params.size.x > 0.5f || zoomed_height - draw_tile.params.size.y > 0.5f) { - GPU_texture_filter_mode(texture.gpu_texture, false); + GPU_texture_bind_ex(texture.gpu_texture, GPU_SAMPLER_DEFAULT, 0, false); } else { - GPU_texture_filter_mode(texture.gpu_texture, true); + GPU_texture_bind_ex(texture.gpu_texture, GPU_SAMPLER_FILTER, 0, false); } /* Draw at the parameters for which the texture has been updated for. This allows to always draw From 9b8c2f91f6065593aeed36067ce74fe5991233fb Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 10 Jan 2023 16:33:00 +0100 Subject: [PATCH 0570/1522] Cleanup: Compile `filesel.c` in C++ This is a mere "get this to compile in C++", didn't do changes like using `MEM_cnew()` instead of `MEM_calloc()`. Needed for the blender-project-basics branch, so I don't have to write C wrappers for a single call from this file. --- .../blender/editors/space_file/CMakeLists.txt | 2 +- .../space_file/{filesel.c => filesel.cc} | 38 +++++++++++-------- 2 files changed, 23 insertions(+), 17 deletions(-) rename source/blender/editors/space_file/{filesel.c => filesel.cc} (97%) diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt index ede48060126..2c3b775f796 100644 --- a/source/blender/editors/space_file/CMakeLists.txt +++ b/source/blender/editors/space_file/CMakeLists.txt @@ -32,7 +32,7 @@ set(SRC file_panels.c file_utils.c filelist.cc - filesel.c + filesel.cc folder_history.cc fsmenu.c space_file.c diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.cc similarity index 97% rename from source/blender/editors/space_file/filesel.c rename to source/blender/editors/space_file/filesel.cc index 0b0ab2b0d66..32181a9f5f6 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.cc @@ -5,9 +5,9 @@ * \ingroup spfile */ -#include -#include -#include +#include +#include +#include #include #include @@ -99,8 +99,8 @@ static void fileselect_ensure_updated_asset_params(SpaceFile *sfile) FileAssetSelectParams *asset_params = sfile->asset_params; if (!asset_params) { - asset_params = sfile->asset_params = MEM_callocN(sizeof(*asset_params), - "FileAssetSelectParams"); + asset_params = sfile->asset_params = static_cast( + MEM_callocN(sizeof(*asset_params), "FileAssetSelectParams")); asset_params->base_params.details_flags = U_default.file_space_data.details_flags; asset_params->asset_library_ref.type = ASSET_LIBRARY_LOCAL; asset_params->asset_library_ref.custom_library_index = -1; @@ -139,7 +139,8 @@ static FileSelectParams *fileselect_ensure_updated_file_params(SpaceFile *sfile) /* create new parameters if necessary */ if (!sfile->params) { - sfile->params = MEM_callocN(sizeof(FileSelectParams), "fileselparams"); + sfile->params = static_cast( + MEM_callocN(sizeof(FileSelectParams), "fileselparams")); /* set path to most recently opened .blend */ BLI_split_dirfile(blendfile_path, sfile->params->dir, @@ -534,7 +535,7 @@ void ED_fileselect_activate_by_id(SpaceFile *sfile, ID *asset_id, const bool def static void on_reload_select_by_relpath(SpaceFile *sfile, onReloadFnData custom_data) { - const char *relative_path = custom_data; + const char *relative_path = static_cast(custom_data); ED_fileselect_activate_by_relpath(sfile, relative_path); } @@ -879,7 +880,9 @@ FileAttributeColumnType file_attribute_column_type_find_isect(const View2D *v2d, /* Column header drawing doesn't use left tile border, so subtract it. */ rel_x = mx - (tile_x - layout->tile_border_x); - for (FileAttributeColumnType column = 0; column < ATTRIBUTE_COLUMN_MAX; column++) { + for (FileAttributeColumnType column = FileAttributeColumnType(0); + column < ATTRIBUTE_COLUMN_MAX; + column = FileAttributeColumnType(int(column) + 1)) { if (!file_attribute_column_type_enabled(params, column)) { continue; } @@ -940,8 +943,10 @@ static void file_attribute_columns_widths(const FileSelectParams *params, FileLa /* Name column uses remaining width */ else { int remwidth = layout->tile_w; - for (FileAttributeColumnType column_type = ATTRIBUTE_COLUMN_MAX - 1; column_type >= 0; - column_type--) { + for (FileAttributeColumnType column_type = + FileAttributeColumnType(int(ATTRIBUTE_COLUMN_MAX) - 1); + column_type >= 0; + column_type = FileAttributeColumnType(int(column_type) - 1)) { if ((column_type == COLUMN_NAME) || !file_attribute_column_type_enabled(params, column_type)) { continue; @@ -978,7 +983,8 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *region) int textheight; if (sfile->layout == NULL) { - sfile->layout = MEM_callocN(sizeof(struct FileLayout), "file_layout"); + sfile->layout = static_cast( + MEM_callocN(sizeof(struct FileLayout), "file_layout")); sfile->layout->dirty = true; } else if (sfile->layout->dirty == false) { @@ -1084,7 +1090,7 @@ void ED_file_change_dir_ex(bContext *C, ScrArea *area) if (UNLIKELY(area->spacetype != SPACE_FILE)) { return; } - SpaceFile *sfile = area->spacedata.first; + SpaceFile *sfile = static_cast(area->spacedata.first); FileSelectParams *params = ED_fileselect_get_active_params(sfile); if (params) { wmWindowManager *wm = CTX_wm_manager(C); @@ -1151,7 +1157,7 @@ int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matche return match; } -int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) +int autocomplete_directory(struct bContext *C, char *str, void * /*arg_v*/) { SpaceFile *sfile = CTX_wm_space_file(C); int match = AUTOCOMPLETE_NO_MATCH; @@ -1199,7 +1205,7 @@ int autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) return match; } -int autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) +int autocomplete_file(struct bContext *C, char *str, void * /*arg_v*/) { SpaceFile *sfile = CTX_wm_space_file(C); int match = AUTOCOMPLETE_NO_MATCH; @@ -1366,7 +1372,7 @@ ScrArea *ED_fileselect_handler_area_find(const wmWindow *win, const wmOperator * ED_screen_areas_iter (win, screen, area) { if (area->spacetype == SPACE_FILE) { - SpaceFile *sfile = area->spacedata.first; + SpaceFile *sfile = static_cast(area->spacedata.first); if (sfile->op == file_operator) { return area; @@ -1386,7 +1392,7 @@ ScrArea *ED_fileselect_handler_area_find_any_with_op(const wmWindow *win) continue; } - const SpaceFile *sfile = area->spacedata.first; + const SpaceFile *sfile = static_cast(area->spacedata.first); if (sfile->op) { return area; } From db688b62f9e2d5a73d7bfaaac7cb0f5b2e8c1d6b Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Tue, 10 Jan 2023 17:00:43 +0100 Subject: [PATCH 0571/1522] Fix T103764: Grease Pencil modes other than Draw use a wrong radial It was introduced in commit https://developer.blender.org/rB0fb12a9c2ebc The problem was that the tool uses the same values for all modes, but the new calculation must be only for Draw mode. Now the mode is checked. --- source/blender/editors/gpencil/gpencil_utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c index 1f80cd06af2..a7895b94600 100644 --- a/source/blender/editors/gpencil/gpencil_utils.c +++ b/source/blender/editors/gpencil/gpencil_utils.c @@ -1786,7 +1786,8 @@ float ED_gpencil_radial_control_scale(struct bContext *C, const int mval[2]) { float scale_fac = 1.0f; - if ((brush && brush->gpencil_settings) && (brush->gpencil_tool == GPAINT_TOOL_DRAW)) { + if ((brush && brush->gpencil_settings) && (brush->ob_mode == OB_MODE_PAINT_GPENCIL) && + (brush->gpencil_tool == GPAINT_TOOL_DRAW)) { float cursor_radius = ED_gpencil_cursor_radius(C, mval[0], mval[1]); scale_fac = max_ff(cursor_radius, 1.0f) / max_ff(initial_value, 1.0f); } From 8a3a1a0c14468fd397548378ce4499e566b274a3 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 10 Jan 2023 17:13:12 +0100 Subject: [PATCH 0572/1522] Fix T103781: assert when connecting viewer node on mesh without faces `Span.data()` does not have to be `nullptr` when the size is zero. This happens e.g. when slicing a span to a size of zero. --- source/blender/blenlib/BLI_generic_array.hh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/source/blender/blenlib/BLI_generic_array.hh b/source/blender/blenlib/BLI_generic_array.hh index 03dc8814309..c46dbe0c907 100644 --- a/source/blender/blenlib/BLI_generic_array.hh +++ b/source/blender/blenlib/BLI_generic_array.hh @@ -89,11 +89,8 @@ class GArray { */ GArray(const GSpan span, Allocator allocator = {}) : GArray(span.type(), span.size(), allocator) { - if (span.data() != nullptr) { - BLI_assert(span.size() != 0); - /* Use copy assign rather than construct since the memory is already initialized. */ - type_->copy_assign_n(span.data(), data_, size_); - } + /* Use copy assign rather than construct since the memory is already initialized. */ + type_->copy_assign_n(span.data(), data_, size_); } /** From d397ecae3255a150954bee32249fd7d58a39d903 Mon Sep 17 00:00:00 2001 From: Charlie Jolly Date: Sat, 7 Jan 2023 14:32:49 +0000 Subject: [PATCH 0573/1522] Geometry Nodes: Add a selection input to the store named attribute node This patch is a response to T101313. Adds a selection to the Store Named Attribute node. If the attribute does not exist unselected parts are filled with zero values. Otherwise, only the selected parts are filled. Differential Revision: https://developer.blender.org/D16237 --- .../blender/blenkernel/BKE_geometry_fields.hh | 6 +++ .../blenkernel/intern/geometry_fields.cc | 51 ++++++++++++++++--- .../nodes/node_geo_store_named_attribute.cc | 9 ++-- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/BKE_geometry_fields.hh b/source/blender/blenkernel/BKE_geometry_fields.hh index 085bade618c..5f5333beb63 100644 --- a/source/blender/blenkernel/BKE_geometry_fields.hh +++ b/source/blender/blenkernel/BKE_geometry_fields.hh @@ -315,6 +315,12 @@ bool try_capture_field_on_geometry(GeometryComponent &component, const eAttrDomain domain, const fn::GField &field); +bool try_capture_field_on_geometry(GeometryComponent &component, + const AttributeIDRef &attribute_id, + const eAttrDomain domain, + const fn::Field &selection, + const fn::GField &field); + /** * Try to find the geometry domain that the field should be evaluated on. If it is not obvious * which domain is correct, none is returned. diff --git a/source/blender/blenkernel/intern/geometry_fields.cc b/source/blender/blenkernel/intern/geometry_fields.cc index 9c691cb5870..f4f4d0d8719 100644 --- a/source/blender/blenkernel/intern/geometry_fields.cc +++ b/source/blender/blenkernel/intern/geometry_fields.cc @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BLI_array_utils.hh" + #include "BKE_attribute.hh" #include "BKE_curves.hh" #include "BKE_geometry_fields.hh" @@ -408,6 +410,7 @@ bool NormalFieldInput::is_equal_to(const fn::FieldNode &other) const bool try_capture_field_on_geometry(GeometryComponent &component, const AttributeIDRef &attribute_id, const eAttrDomain domain, + const fn::Field &selection, const fn::GField &field) { MutableAttributeAccessor attributes = *component.attributes_for_write(); @@ -423,19 +426,44 @@ bool try_capture_field_on_geometry(GeometryComponent &component, const IndexMask mask{IndexMask(domain_size)}; const bke::AttributeValidator validator = attributes.lookup_validator(attribute_id); - /* Could avoid allocating a new buffer if: - * - We are writing to an attribute that exists already with the correct domain and type. - * - The field does not depend on that attribute (we can't easily check for that yet). */ - void *buffer = MEM_mallocN(type.size() * domain_size, __func__); + const std::optional meta_data = attributes.lookup_meta_data(attribute_id); + const bool attribute_exists = meta_data && meta_data->domain == domain && + meta_data->data_type == data_type; + /* We are writing to an attribute that exists already with the correct domain and type. */ + if (attribute_exists) { + if (GSpanAttributeWriter dst_attribute = attributes.lookup_for_write_span(attribute_id)) { + bke::GeometryFieldContext field_context{component, domain}; + const IndexMask mask{IndexMask(domain_size)}; + + fn::FieldEvaluator evaluator{field_context, &mask}; + evaluator.add(validator.validate_field_if_necessary(field)); + evaluator.set_selection(selection); + evaluator.evaluate(); + + const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); + + array_utils::copy(evaluator.get_evaluated(0), selection, dst_attribute.span); + + dst_attribute.finish(); + return true; + } + } + + /* Could avoid allocating a new buffer if: + * - The field does not depend on that attribute (we can't easily check for that yet). */ + void *buffer = MEM_mallocN_aligned(type.size() * domain_size, type.alignment(), __func__); + if (selection.node().depends_on_input() || !fn::evaluate_constant_field(selection)) { + /* If every element might not be selected, the buffer must be initialized. */ + type.value_initialize_n(buffer, domain_size); + } fn::FieldEvaluator evaluator{field_context, &mask}; evaluator.add_with_destination(validator.validate_field_if_necessary(field), GMutableSpan{type, buffer, domain_size}); + evaluator.set_selection(selection); evaluator.evaluate(); - const std::optional meta_data = attributes.lookup_meta_data(attribute_id); - - if (meta_data && meta_data->domain == domain && meta_data->data_type == data_type) { + if (attribute_exists) { if (GAttributeWriter attribute = attributes.lookup_for_write(attribute_id)) { attribute.varray.set_all(buffer); attribute.finish(); @@ -457,6 +485,15 @@ bool try_capture_field_on_geometry(GeometryComponent &component, return false; } +bool try_capture_field_on_geometry(GeometryComponent &component, + const AttributeIDRef &attribute_id, + const eAttrDomain domain, + const fn::GField &field) +{ + const fn::Field selection = fn::make_constant_field(true); + return try_capture_field_on_geometry(component, attribute_id, domain, selection, field); +} + std::optional try_detect_field_domain(const GeometryComponent &component, const fn::GField &field) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc index d42793d474f..462b332568f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_store_named_attribute.cc @@ -20,6 +20,7 @@ NODE_STORAGE_FUNCS(NodeGeometryStoreNamedAttribute) static void node_declare(NodeDeclarationBuilder &b) { b.add_input(N_("Geometry")); + b.add_input(N_("Selection")).default_value(true).hide_value().field_on_all(); b.add_input(N_("Name")).is_attribute_name(); b.add_input(N_("Value"), "Value_Vector").field_on_all(); b.add_input(N_("Value"), "Value_Float").field_on_all(); @@ -52,7 +53,7 @@ static void node_update(bNodeTree *ntree, bNode *node) const eCustomDataType data_type = eCustomDataType(storage.data_type); bNodeSocket *socket_geometry = static_cast(node->inputs.first); - bNodeSocket *socket_name = socket_geometry->next; + bNodeSocket *socket_name = socket_geometry->next->next; bNodeSocket *socket_vector = socket_name->next; bNodeSocket *socket_float = socket_vector->next; bNodeSocket *socket_color4f = socket_float->next; @@ -108,6 +109,8 @@ static void node_geo_exec(GeoNodeExecParams params) const eCustomDataType data_type = eCustomDataType(storage.data_type); const eAttrDomain domain = eAttrDomain(storage.domain); + const Field selection = params.extract_input>("Selection"); + GField field; switch (data_type) { case CD_PROP_FLOAT: @@ -147,7 +150,7 @@ static void node_geo_exec(GeoNodeExecParams params) if (geometry_set.has_instances()) { GeometryComponent &component = geometry_set.get_component_for_write( GEO_COMPONENT_TYPE_INSTANCES); - if (!bke::try_capture_field_on_geometry(component, name, domain, field)) { + if (!bke::try_capture_field_on_geometry(component, name, domain, selection, field)) { if (component.attribute_domain_size(domain) != 0) { failure.store(true); } @@ -160,7 +163,7 @@ static void node_geo_exec(GeoNodeExecParams params) {GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_POINT_CLOUD, GEO_COMPONENT_TYPE_CURVE}) { if (geometry_set.has(type)) { GeometryComponent &component = geometry_set.get_component_for_write(type); - if (!bke::try_capture_field_on_geometry(component, name, domain, field)) { + if (!bke::try_capture_field_on_geometry(component, name, domain, selection, field)) { if (component.attribute_domain_size(domain) != 0) { failure.store(true); } From 5bc71f22a24a48780fe335c557f2f9bbc690eb85 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Tue, 10 Jan 2023 15:56:17 -0300 Subject: [PATCH 0574/1522] Snap Gizmo: remove unused "snap_elements" This property was intended to keep the snap elements synchronized with the scene. But another solution exists. And this property is not even working correctly. --- .../gizmo_library/gizmo_types/snap3d_gizmo.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c index c5a542c0bf3..5cac8b93b88 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c @@ -41,17 +41,6 @@ typedef struct SnapGizmo3D { V3DSnapCursorState *snap_state; } SnapGizmo3D; -static void snap_gizmo_snap_elements_update(SnapGizmo3D *snap_gizmo) -{ - wmGizmoProperty *gz_prop_snap; - gz_prop_snap = WM_gizmo_target_property_find(&snap_gizmo->gizmo, "snap_elements"); - - if (gz_prop_snap->prop) { - V3DSnapCursorState *snap_state = snap_gizmo->snap_state; - snap_state->snap_elem_force |= RNA_property_enum_get(&gz_prop_snap->ptr, gz_prop_snap->prop); - } -} - /* -------------------------------------------------------------------- */ /** \name ED_gizmo_library specific API * \{ */ @@ -262,9 +251,6 @@ static int snap_gizmo_test_select(bContext *C, wmGizmo *gz, const int mval[2]) { SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - /* Snap Elements can change while the gizmo is active. Need to be updated somewhere. */ - snap_gizmo_snap_elements_update(snap_gizmo); - /* Snap values are updated too late at the cursor. Be sure to update ahead of time. */ int x, y; { @@ -404,9 +390,6 @@ static void GIZMO_GT_snap_3d(wmGizmoType *gzt) INT_MAX); RNA_def_property_int_array_funcs_runtime( prop, gizmo_snap_rna_snap_elem_index_get_fn, NULL, NULL); - - /* Read/Write. */ - WM_gizmotype_target_property_def(gzt, "snap_elements", PROP_ENUM, 1); } void ED_gizmotypes_snap_3d(void) From 30c90f0ad015ae23eb37780f64429ba9e406eafe Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Tue, 10 Jan 2023 14:49:51 -0500 Subject: [PATCH 0575/1522] Cleanup: Replace "UV's" with "UVs" An apostrophe should not be used because it is not a mark of plural, even for initialisms. This involves mostly comments, but a few UI messages are affected as well. Differential Revision: https://developer.blender.org/D16749 --- doc/python_api/examples/bpy.types.Mesh.py | 6 +++--- .../scripts/modules/bpy_extras/object_utils.py | 2 +- .../startup/bl_operators/add_mesh_torus.py | 2 +- .../startup/bl_operators/uvcalc_lightmap.py | 6 +++--- source/blender/blenkernel/BKE_mesh.h | 4 ++-- source/blender/blenkernel/BKE_pbvh_pixels.hh | 2 +- source/blender/blenkernel/intern/mesh.cc | 2 +- .../blenkernel/intern/mesh_legacy_convert.cc | 2 +- source/blender/blenkernel/intern/mesh_mapping.cc | 2 +- .../blenkernel/intern/mesh_merge_customdata.cc | 6 +++--- source/blender/blenlib/BLI_uvproject.h | 2 +- .../blender/blenloader/intern/versioning_280.c | 2 +- .../blenloader/intern/versioning_defaults.cc | 2 +- source/blender/bmesh/bmesh.h | 2 +- source/blender/bmesh/intern/bmesh_interp.c | 2 +- source/blender/bmesh/intern/bmesh_opdefines.c | 6 +++--- source/blender/bmesh/intern/bmesh_operators.h | 2 +- source/blender/bmesh/intern/bmesh_walkers_impl.c | 2 +- source/blender/bmesh/operators/bmo_inset.c | 6 +++--- source/blender/bmesh/tools/bmesh_bevel.c | 4 ++-- source/blender/bmesh/tools/bmesh_boolean.cc | 2 +- source/blender/bmesh/tools/bmesh_intersect.c | 2 +- .../blender/bmesh/tools/bmesh_path_region_uv.c | 4 ++-- .../draw/engines/overlay/overlay_edit_uv.cc | 2 +- .../blender/draw/intern/draw_cache_impl_mesh.cc | 2 +- source/blender/draw/intern/draw_manager.c | 2 +- .../extract_mesh_vbo_edituv_stretch_angle.cc | 2 +- source/blender/editors/include/ED_mesh.h | 2 +- source/blender/editors/mesh/editmesh_tools.c | 2 +- source/blender/editors/object/object_add.cc | 2 +- source/blender/editors/object/object_modifier.cc | 2 +- .../editors/sculpt_paint/paint_image_proj.cc | 12 ++++++------ source/blender/editors/sculpt_paint/sculpt_uv.c | 16 ++++++++-------- .../editors/transform/transform_convert.c | 2 +- source/blender/editors/uvedit/uvedit_intern.h | 2 +- source/blender/editors/uvedit/uvedit_ops.c | 4 ++-- source/blender/editors/uvedit/uvedit_rip.c | 8 ++++---- source/blender/editors/uvedit/uvedit_select.c | 10 +++++----- .../blender/editors/uvedit/uvedit_smart_stitch.c | 4 ++-- .../blender/editors/uvedit/uvedit_unwrap_ops.c | 10 +++++----- source/blender/makesdna/DNA_meshdata_types.h | 4 ++-- source/blender/makesdna/DNA_scene_types.h | 6 +++--- source/blender/makesrna/intern/rna_modifier.c | 4 ++-- source/blender/makesrna/intern/rna_scene.c | 4 ++-- .../blender/modifiers/intern/MOD_dynamicpaint.c | 2 +- .../windowmanager/intern/wm_event_system.cc | 2 +- 46 files changed, 89 insertions(+), 89 deletions(-) diff --git a/doc/python_api/examples/bpy.types.Mesh.py b/doc/python_api/examples/bpy.types.Mesh.py index 68cc42ec6bf..8872201e123 100644 --- a/doc/python_api/examples/bpy.types.Mesh.py +++ b/doc/python_api/examples/bpy.types.Mesh.py @@ -13,16 +13,16 @@ Blender stores 4 main arrays to define mesh geometry. - :class:`Mesh.polygons`: (reference a range of loops) -Each polygon reference a slice in the loop array, this way, polygons do not store vertices or corner data such as UV's directly, +Each polygon references a slice in the loop array, this way, polygons do not store vertices or corner data such as UVs directly, only a reference to loops that the polygon uses. :class:`Mesh.loops`, :class:`Mesh.uv_layers` :class:`Mesh.vertex_colors` are all aligned so the same polygon loop -indices can be used to find the UV's and vertex colors as with as the vertices. +indices can be used to find the UVs and vertex colors as with as the vertices. To compare mesh API options see: :ref:`NGons and Tessellation Faces ` -This example script prints the vertices and UV's for each polygon, assumes the active object is a mesh with UVs. +This example script prints the vertices and UVs for each polygon, assumes the active object is a mesh with UVs. """ import bpy diff --git a/release/scripts/modules/bpy_extras/object_utils.py b/release/scripts/modules/bpy_extras/object_utils.py index 5275a83e062..efbd635955c 100644 --- a/release/scripts/modules/bpy_extras/object_utils.py +++ b/release/scripts/modules/bpy_extras/object_utils.py @@ -127,7 +127,7 @@ def object_data_add(context, obdata, operator=None, name=None): layer.update() # apply location # layer.objects.active = obj_new - # Match up UV layers, this is needed so adding an object with UV's + # Match up UV layers, this is needed so adding an object with UVs # doesn't create new layers when there happens to be a naming mismatch. uv_new = obdata.uv_layers.active if uv_new is not None: diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py index 90d1326e1a2..88934d086a9 100644 --- a/release/scripts/startup/bl_operators/add_mesh_torus.py +++ b/release/scripts/startup/bl_operators/add_mesh_torus.py @@ -71,7 +71,7 @@ def add_uvs(mesh, minor_seg, major_seg): u_step = 1.0 / major_seg v_step = 1.0 / minor_seg - # Round UV's, needed when segments aren't divisible by 4. + # Round UVs, needed when segments aren't divisible by 4. u_init = 0.5 + fmod(0.5, u_step) v_init = 0.5 + fmod(0.5, v_step) diff --git a/release/scripts/startup/bl_operators/uvcalc_lightmap.py b/release/scripts/startup/bl_operators/uvcalc_lightmap.py index 8c78424f54a..ca309bff9e4 100644 --- a/release/scripts/startup/bl_operators/uvcalc_lightmap.py +++ b/release/scripts/startup/bl_operators/uvcalc_lightmap.py @@ -84,7 +84,7 @@ class prettyface: # ngon, note: # for ngons to calculate the width/height we need to do the # whole projection, unlike other faces - # we store normalized UV's in the faces coords to avoid + # we store normalized UVs in the faces coords to avoid # calculating the projection and rotating it twice. no = data.normal @@ -110,7 +110,7 @@ class prettyface: self.height = yspan # ngons work different, we store projected result - # in UV's to avoid having to re-project later. + # in UVs to avoid having to re-project later. for i, co in enumerate(cos_2d): self.uv[i][:] = ((co.x - xmin) / xspan, (co.y - ymin) / yspan) @@ -570,7 +570,7 @@ from bpy.props import BoolProperty, FloatProperty, IntProperty class LightMapPack(Operator): - """Pack each faces UV's into the UV bounds""" + """Pack each face's UVs into the UV bounds""" bl_idname = "uv.lightmap_pack" bl_label = "Lightmap Pack" diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index ffca4cff347..5190d09ccf8 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -807,9 +807,9 @@ struct Mesh *BKE_mesh_merge_verts(struct Mesh *mesh, int merge_mode); /** - * Account for custom-data such as UV's becoming detached because of imprecision + * Account for custom-data such as UVs becoming detached because of imprecision * in custom-data interpolation. - * Without running this operation subdivision surface can cause UV's to be disconnected, + * Without running this operation subdivision surface can cause UVs to be disconnected, * see: T81065. */ void BKE_mesh_merge_customdata_for_apply_modifier(struct Mesh *me); diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh index 55ecf65bcac..a6b5bb565c5 100644 --- a/source/blender/blenkernel/BKE_pbvh_pixels.hh +++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh @@ -59,7 +59,7 @@ struct UVPrimitivePaintInput { /** Corresponding index into PaintGeometryPrimitives */ int64_t geometry_primitive_index; /** - * Delta barycentric coordinates between 2 neighboring UV's in the U direction. + * Delta barycentric coordinates between 2 neighboring UVs in the U direction. * * Only the first two coordinates are stored. The third should be recalculated */ diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index d2e61d37e44..60547a57094 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -510,7 +510,7 @@ static bool is_uv_bool_sublayer(CustomDataLayer const *l) is_sublayer_name(UV_PINNED_NAME, name); } -/** Thresh is threshold for comparing vertices, UV's, vertex colors, weights, etc. */ +/** Thresh is threshold for comparing vertices, UVs, vertex colors, weights, etc. */ static int customdata_compare( CustomData *c1, CustomData *c2, const int total_length, Mesh *m1, Mesh *m2, const float thresh) { diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 9fd9214f8af..868653013a6 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -524,7 +524,7 @@ static void convert_mfaces_to_mpolys(ID *id, } /* NOTE: we don't convert NGons at all, these are not even real ngons, - * they have their own UV's, colors etc - its more an editing feature. */ + * they have their own UVs, colors etc - it's more an editing feature. */ BLI_edgehash_free(eh, nullptr); diff --git a/source/blender/blenkernel/intern/mesh_mapping.cc b/source/blender/blenkernel/intern/mesh_mapping.cc index 9028f6d51b3..7ebf57ffd3c 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.cc +++ b/source/blender/blenkernel/intern/mesh_mapping.cc @@ -4,7 +4,7 @@ * \ingroup bke * * Functions for accessing mesh connectivity data. - * eg: polys connected to verts, UV's connected to verts. + * eg: polys connected to verts, UVs connected to verts. */ #include "MEM_guardedalloc.h" diff --git a/source/blender/blenkernel/intern/mesh_merge_customdata.cc b/source/blender/blenkernel/intern/mesh_merge_customdata.cc index 7a0895c18e1..f219ad3ae19 100644 --- a/source/blender/blenkernel/intern/mesh_merge_customdata.cc +++ b/source/blender/blenkernel/intern/mesh_merge_customdata.cc @@ -38,11 +38,11 @@ static int compare_v2_classify(const float uv_a[2], const float uv_b[2]) * values as the absolute value doesn't account for float precision at difference scales. * - For subdivision-surface ULP of 3 is sufficient, * although this value is extremely small. - * - For bevel the ULP of 12 is sufficient to merge UV's that appear to be connected + * - For bevel the ULP of 12 is sufficient to merge UVs that appear to be connected * with bevel on Suzanne beveled 15% with 6 segments. * * These values could be tweaked but should be kept on the small side to prevent - * unintentional joining of intentionally dis-connected UV's. + * unintentional joining of intentionally disconnected UVs. * * Before v2.91 the threshold was either (`1e-4` or `0.05 / image_size` for selection picking). * So picking used a threshold of `1e-4` for a 500x500 image and `1e-5` for a 5000x5000 image. @@ -63,7 +63,7 @@ static void merge_uvs_for_vertex(const Span loops_for_vert, Span if (loops_for_vert.size() <= 1) { return; } - /* Manipulate a copy of the loop indices, de-duplicating UV's per layer. */ + /* Manipulate a copy of the loop indices, de-duplicating UVs per layer. */ Vector loops_merge; loops_merge.reserve(loops_for_vert.size()); for (float2 *mloopuv : mloopuv_layers) { diff --git a/source/blender/blenlib/BLI_uvproject.h b/source/blender/blenlib/BLI_uvproject.h index a94fd796121..ecd3fa744db 100644 --- a/source/blender/blenlib/BLI_uvproject.h +++ b/source/blender/blenlib/BLI_uvproject.h @@ -40,7 +40,7 @@ void BLI_uvproject_from_view(float target[2], float winy); /** - * Apply orthographic UV's. + * Apply orthographic UVs. */ void BLI_uvproject_from_view_ortho(float target[2], float source[3], const float rotmat[4][4]); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 8cbc08357a4..980c8894e10 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1791,7 +1791,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) /* MTexPoly now removed. */ if (DNA_struct_find(fd->filesdna, "MTexPoly")) { for (Mesh *me = bmain->meshes.first; me; me = me->id.next) { - /* If we have UV's, so this file will have MTexPoly layers too! */ + /* If we have UVs, so this file will have MTexPoly layers too! */ if (CustomData_has_layer(&me->ldata, CD_MLOOPUV) || CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2)) { CustomData_update_typemap(&me->pdata); diff --git a/source/blender/blenloader/intern/versioning_defaults.cc b/source/blender/blenloader/intern/versioning_defaults.cc index 0e7a21c3291..d833e964232 100644 --- a/source/blender/blenloader/intern/versioning_defaults.cc +++ b/source/blender/blenloader/intern/versioning_defaults.cc @@ -349,7 +349,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene) ts->sculpt->paint.symmetry_flags |= PAINT_SYMMETRY_FEATHER; } - /* Correct default startup UV's. */ + /* Correct default startup UVs. */ Mesh *me = static_cast(BLI_findstring(&bmain->meshes, "Cube", offsetof(ID, name) + 2)); if (me && (me->totloop == 24) && CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2)) { const float uv_values[24][2] = { diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index d0aac884b53..1157b8f0a58 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -14,7 +14,7 @@ * BMesh stores topology in four main element structures: * * - Faces - BMFace - * - Loops - BMLoop, (stores per-face-vertex data, UV's, vertex-colors, etc) + * - Loops - BMLoop, (stores per-face-vertex data, UVs, vertex-colors, etc) * - Edges - BMEdge * - Verts - BMVert * \subsection bm_header_flags Header Flags diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index e0422f21782..f666c9f940d 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -1045,7 +1045,7 @@ void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float /* -------------------------------------------------------------------- */ /** \name Loop interpolation functions: BM_vert_loop_groups_data_layer_*** * - * Handling loop custom-data such as UV's, while keeping contiguous fans is rather tedious. + * Handling loop custom-data such as UVs, while keeping contiguous fans is rather tedious. * Especially when a verts loops can have multiple CustomData layers, * and each layer can have multiple (different) contiguous fans. * Said differently, a single vertices loops may span multiple UV islands. diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 1c8bd3bd54e..0ffb3f6652e 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -447,7 +447,7 @@ static BMOpDefine bmo_pointmerge_def = { }; /* - * Collapse Connected UV's. + * Collapse Connected UVs. * * Collapses connected UV vertices. */ @@ -1453,7 +1453,7 @@ static BMOpDefine bmo_spin_def = { /* * UV Rotation. * - * Cycle the loop UV's + * Cycle the loop UVs */ static BMOpDefine bmo_rotate_uvs_def = { "rotate_uvs", @@ -1470,7 +1470,7 @@ static BMOpDefine bmo_rotate_uvs_def = { /* * UV Reverse. * - * Reverse the UV's + * Reverse the UVs */ static BMOpDefine bmo_reverse_uvs_def = { "reverse_uvs", diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h index d29c913b0aa..387372c20ee 100644 --- a/source/blender/bmesh/intern/bmesh_operators.h +++ b/source/blender/bmesh/intern/bmesh_operators.h @@ -162,7 +162,7 @@ void BM_mesh_esubdivide(BMesh *bm, int seed); /** - * Fills first available UV-map with grid-like UV's for all faces with `oflag` set. + * Fills first available UV-map with grid-like UVs for all faces with `oflag` set. * * \param bm: The BMesh to operate on * \param x_segments: The x-resolution of the grid diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index ef9892669ed..2984ea93cb7 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -1546,7 +1546,7 @@ static void *bmw_UVEdgeWalker_step(BMWalker *walker) } /* Go over loops around `l->v` and `l->next->v` and see which ones share `l` and `l->next` - * UV's coordinates. in addition, push on `l->next` if necessary. */ + * UV coordinates. in addition, push on `l->next` if necessary. */ for (i = 0; i < 2; i++) { BMIter liter; BMLoop *l_pivot, *l_radial; diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c index 2a6b5459d1c..f46b9158c45 100644 --- a/source/blender/bmesh/operators/bmo_inset.c +++ b/source/blender/bmesh/operators/bmo_inset.c @@ -97,7 +97,7 @@ static void bm_interp_face_free(InterpFace *iface, BMesh *bm) #ifdef USE_LOOP_CUSTOMDATA_MERGE /** - * This function merges loop customdata (UV's) + * This function merges loop customdata (UVs) * where interpolating the values across the face causes values to diverge. */ static void bm_loop_customdata_merge(BMesh *bm, @@ -177,7 +177,7 @@ static void bm_loop_customdata_merge(BMesh *bm, BM_ELEM_CD_GET_VOID_P(l_a_outer, offset), BM_ELEM_CD_GET_VOID_P(l_b_outer, offset)) == true) - /* Epsilon for comparing UV's is too big, gives noticeable problems. */ + /* Epsilon for comparing UVs is too big, gives noticeable problems. */ # if 0 && /* check if the data ends up diverged */ @@ -1183,7 +1183,7 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op) f = BM_face_create_verts(bm, varr, j, es->l->f, BM_CREATE_NOP, true); BMO_face_flag_enable(bm, f, ELE_NEW); - /* Copy for loop data, otherwise UV's and vcols are no good. + /* Copy for loop data, otherwise UVs and vcols are no good. * tiny speedup here we could be more clever and copy from known adjacent data * also - we could attempt to interpolate the loop data, * this would be much slower but more useful too. */ diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 330a66e5800..d3888e31da6 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -97,7 +97,7 @@ typedef struct EdgeHalf { bool is_bev; /** Is e->v2 the vertex at this end? */ bool is_rev; - /** Is e a seam for custom loop-data (e.g., UV's). */ + /** Is e a seam for custom loop-data (e.g., UVs). */ bool is_seam; /** Used during the custom profile orientation pass. */ bool visited_rpo; @@ -5463,7 +5463,7 @@ static void bevel_build_rings(BevelParams *bp, BMesh *bm, BevVert *bv, BoundVert BMVert *bmv4 = mesh_vert(vm, i, j + 1, k)->v; BMVert *bmvs[4] = {bmv1, bmv2, bmv3, bmv4}; BLI_assert(bmv1 && bmv2 && bmv3 && bmv4); - /* For each created quad, the UV's etc. will be interpolated + /* For each created quad, the UVs etc. will be interpolated * in potentially a different face for each corner and may need * to snap to a particular edge before interpolating. * The fr and se arrays will be filled with the interpolation faces diff --git a/source/blender/bmesh/tools/bmesh_boolean.cc b/source/blender/bmesh/tools/bmesh_boolean.cc index 288a0d9ab74..e09b8130f40 100644 --- a/source/blender/bmesh/tools/bmesh_boolean.cc +++ b/source/blender/bmesh/tools/bmesh_boolean.cc @@ -278,7 +278,7 @@ static bool apply_mesh_output_to_bmesh(BMesh *bm, IMesh &m_out, bool keep_hidden BM_elem_select_copy(bm, bmf, orig_face); } BM_elem_flag_enable(bmf, KEEP_FLAG); - /* Now do interpolation of loop data (e.g., UV's) using the example face. */ + /* Now do interpolation of loop data (e.g., UVs) using the example face. */ if (orig_face != nullptr) { BMIter liter; BMLoop *l = static_cast(BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, bmf)); diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c index a06efe8da96..a6dd914a016 100644 --- a/source/blender/bmesh/tools/bmesh_intersect.c +++ b/source/blender/bmesh/tools/bmesh_intersect.c @@ -10,7 +10,7 @@ * Supported: * - Concave faces. * - Non-planar faces. - * - Custom-data (UV's etc). + * - Custom-data (UVs etc). * * Unsupported: * - Intersecting between different meshes. diff --git a/source/blender/bmesh/tools/bmesh_path_region_uv.c b/source/blender/bmesh/tools/bmesh_path_region_uv.c index 56090ed9916..17812fe3bdd 100644 --- a/source/blender/bmesh/tools/bmesh_path_region_uv.c +++ b/source/blender/bmesh/tools/bmesh_path_region_uv.c @@ -7,7 +7,7 @@ * (path isn't ordered). * * \note This uses the same behavior as bmesh_path_region.c - * however walking UV's causes enough differences that it's + * however walking UVs causes enough differences that it's * impractical to share the code. */ @@ -233,7 +233,7 @@ static LinkNode *mesh_calc_path_region_elem(BMesh *bm, continue; } - /* Flush the depth to connected loops (only needed for UV's). */ + /* Flush the depth to connected loops (only needed for UVs). */ if (depths[side][BM_elem_index_get(l_iter)] == -1) { depths[side][BM_elem_index_get(l_iter)] = depths[side][l_a_index]; } diff --git a/source/blender/draw/engines/overlay/overlay_edit_uv.cc b/source/blender/draw/engines/overlay/overlay_edit_uv.cc index fbe5e24112b..8b3c4e5d0ce 100644 --- a/source/blender/draw/engines/overlay/overlay_edit_uv.cc +++ b/source/blender/draw/engines/overlay/overlay_edit_uv.cc @@ -102,7 +102,7 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata) const bool show_overlays = !pd->hide_overlays; Image *image = sima->image; - /* By design no image is an image type. This so editor shows UV's by default. */ + /* By design no image is an image type. This so editor shows UVs by default. */ const bool is_image_type = (image == nullptr) || ELEM(image->type, IMA_TYPE_IMAGE, IMA_TYPE_MULTILAYER, diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.cc b/source/blender/draw/intern/draw_cache_impl_mesh.cc index 54385250884..bfeafdf7dcb 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.cc +++ b/source/blender/draw/intern/draw_cache_impl_mesh.cc @@ -315,7 +315,7 @@ static DRW_MeshCDMask mesh_cd_calc_used_gpu_layers(const Object *object, layer = CustomData_get_named_layer(cd_ldata, CD_PROP_FLOAT2, name); type = CD_MTFACE; -#if 0 /* Tangents are always from UV's - this will never happen. */ +#if 0 /* Tangents are always from UVs - this will never happen. */ if (layer == -1) { layer = CustomData_get_named_layer(cd_ldata, CD_TANGENT, name); type = CD_TANGENT; diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index d322644f0c2..9953da4847d 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2183,7 +2183,7 @@ void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph, DRW_viewport_colormanagement_set(viewport); /* TODO(jbakker): Only populate when editor needs to draw object. - * for the image editor this is when showing UV's. */ + * for the image editor this is when showing UVs. */ const bool do_populate_loop = (DST.draw_ctx.space_data->spacetype == SPACE_IMAGE); const bool do_annotations = drw_draw_show_annotation(); const bool do_draw_gizmos = (DST.draw_ctx.space_data->spacetype != SPACE_IMAGE); diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc index 5edda1567b4..a7b0331769c 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc @@ -61,7 +61,7 @@ static void edituv_get_edituv_stretch_angle(float auv[2][2], const float av[2][3], UVStretchAngle *r_stretch) { - /* Send UV's to the shader and let it compute the aspect corrected angle. */ + /* Send UVs to the shader and let it compute the aspect corrected angle. */ r_stretch->uv_angles[0] = v2_to_short_angle(auv[0]); r_stretch->uv_angles[1] = v2_to_short_angle(auv[1]); /* Compute 3D angle here. */ diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index fdd0d639883..8ab6e31bef3 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -153,7 +153,7 @@ struct UvElement **BM_uv_element_map_ensure_head_table(struct UvElementMap *elem int *BM_uv_element_map_ensure_unique_index(struct UvElementMap *element_map); /** - * Can we edit UV's for this mesh? + * Can we edit UVs for this mesh? */ bool EDBM_uv_check(struct BMEditMesh *em); /** diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 63447c85818..620d6c2ea5e 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -733,7 +733,7 @@ void MESH_OT_edge_collapse(wmOperatorType *ot) /* identifiers */ ot->name = "Collapse Edges & Faces"; ot->description = - "Collapse isolated edge and face regions, merging data such as UV's and color attributes. " + "Collapse isolated edge and face regions, merging data such as UVs and color attributes. " "This can collapse edge-rings as well as regions of connected faces into vertices"; ot->idname = "MESH_OT_edge_collapse"; diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc index db8867e994d..3d9cb9b8167 100644 --- a/source/blender/editors/object/object_add.cc +++ b/source/blender/editors/object/object_add.cc @@ -3572,7 +3572,7 @@ void OBJECT_OT_convert(wmOperatorType *ot) ot->srna, "merge_customdata", true, - "Merge UV's", + "Merge UVs", "Merge UV coordinates that share a vertex to account for imprecision in some modifiers"); prop = RNA_def_float_rotation(ot->srna, diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index dc5037d892d..57d62b3a95b 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -1777,7 +1777,7 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot) RNA_def_boolean(ot->srna, "merge_customdata", true, - "Merge UV's", + "Merge UVs", "For mesh objects, merge UV coordinates that share a vertex to account for " "imprecision in some modifiers"); PropertyRNA *prop = RNA_def_boolean(ot->srna, diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.cc b/source/blender/editors/sculpt_paint/paint_image_proj.cc index fe14e0482f0..6544b1f2bda 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.cc +++ b/source/blender/editors/sculpt_paint/paint_image_proj.cc @@ -1034,7 +1034,7 @@ static int line_isect_x(const float p1[2], const float p2[2], const float x_leve #ifndef PROJ_DEBUG_NOSEAMBLEED static bool cmp_uv(const float vec2a[2], const float vec2b[2]) { - /* if the UV's are not between 0.0 and 1.0 */ + /* if the UVs are not between 0.0 and 1.0 */ float xa = fmodf(vec2a[0], 1.0f); float ya = fmodf(vec2a[1], 1.0f); @@ -1295,8 +1295,8 @@ static float compute_seam_normal(VertSeam *seam, VertSeam *adj, float r_no[2]) return angle_rel; } -/* Calculate outset UV's, this is not the same as simply scaling the UVs, - * since the outset coords are a margin that keep an even distance from the original UV's, +/* Calculate outset UVs, this is not the same as simply scaling the UVs, + * since the outset coords are a margin that keep an even distance from the original UVs, * note that the image aspect is taken into account */ static void uv_image_outset(const ProjPaintState *ps, float (*orig_uv)[2], @@ -2433,7 +2433,7 @@ static bool IsectPT2Df_limit( /** * Clip the face by a bucket and set the uv-space bucket_bounds_uv - * so we have the clipped UV's to do pixel intersection tests with + * so we have the clipped UVs to do pixel intersection tests with */ static int float_z_sort_flip(const void *p1, const void *p2) { @@ -3241,7 +3241,7 @@ static void project_paint_face_init(const ProjPaintState *ps, float seam_subsection[4][2]; float fac1, fac2; - /* Pixel-space UV's. */ + /* Pixel-space UVs. */ float lt_puv[3][2]; lt_puv[0][0] = lt_uv_pxoffset[0][0] * ibuf->x; @@ -4344,7 +4344,7 @@ static void project_paint_prepare_all_faces(ProjPaintState *ps, if (slot->ima == ps->stencil_ima) { /* Delay continuing the loop until after loop_uvs and bleed faces are initialized. * While this shouldn't be used, face-winding reads all polys. - * It's less trouble to set all faces to valid UV's, + * It's less trouble to set all faces to valid UVs, * avoiding nullptr checks all over. */ skip_tri = true; tpage = nullptr; diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index 6e622a56515..998fe50b9ac 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -82,7 +82,7 @@ typedef struct UVInitialStroke { /* Initial Selection,for grab brushes for instance */ UVInitialStrokeElement *initialSelection; - /* Total initially selected UV's. */ + /* Total initially selected UVs. */ int totalInitialSelected; /* initial mouse coordinates */ @@ -91,9 +91,9 @@ typedef struct UVInitialStroke { /* custom data for uv smoothing brush */ typedef struct UvSculptData { - /* Contains the first of each set of coincident UV's. + /* Contains the first of each set of coincident UVs. * These will be used to perform smoothing on and propagate the changes - * to their coincident UV's */ + * to their coincident UVs */ UvAdjacencyElement *uv; /* Total number of unique UVs. */ @@ -111,7 +111,7 @@ typedef struct UvSculptData { /* timer to be used for airbrush-type brush */ wmTimer *timer; - /* to determine quickly adjacent UV's */ + /* to determine quickly adjacent UVs */ UvElementMap *elementMap; /* uvsmooth Paint for fast reference */ @@ -709,7 +709,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm island_index = element->island; } - /* Count 'unique' UV's */ + /* Count 'unique' UVs */ int unique_uvs = data->elementMap->total_unique_uvs; if (do_island_optimization) { unique_uvs = data->elementMap->island_total_unique_uvs[island_index]; @@ -785,8 +785,8 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm offset1 = uniqueUv[itmp1]; offset2 = uniqueUv[itmp2]; - /* Using an order policy, sort UV's according to address space. - * This avoids having two different UvEdges with the same UV's on different positions. */ + /* Using an order policy, sort UVs according to address space. + * This avoids having two different UvEdges with the same UVs on different positions. */ if (offset1 < offset2) { edges[counter].uv1 = offset1; edges[counter].uv2 = offset2; @@ -832,7 +832,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm BLI_ghash_free(edgeHash, NULL, NULL); MEM_SAFE_FREE(edges); - /* transfer boundary edge property to UV's */ + /* transfer boundary edge property to UVs */ for (int i = 0; i < data->totalUvEdges; i++) { if (!data->uvedges[i].is_interior) { data->uv[data->uvedges[i].uv1].is_boundary = true; diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index 22f42d4ab5c..b02d1ed06c4 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -833,7 +833,7 @@ static void init_TransDataContainers(TransInfo *t, if (object_mode & OB_MODE_EDIT) { tc->obedit = objects[i]; - /* Check needed for UV's */ + /* Check needed for UVs */ if ((t->flag & T_2D_EDIT) == 0) { tc->use_local_mat = true; } diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index f691cb7d79e..c090d8b95b7 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -34,7 +34,7 @@ typedef struct UvNearestHit { */ float dist_sq; - /** Scale the UV's to account for aspect ratio from the image view. */ + /** Scale the UVs to account for aspect ratio from the image view. */ float scale[2]; } UvNearestHit; diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index e35e05a9ef3..1f98df1b386 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -1333,7 +1333,7 @@ static void UV_OT_snap_selected(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Pin UV's Operator +/** \name Pin UVs Operator * \{ */ static int uv_pin_exec(bContext *C, wmOperator *op) @@ -2097,7 +2097,7 @@ void ED_operatormacros_uvedit(void) ot = WM_operatortype_append_macro("UV_OT_rip_move", "UV Rip Move", - "Unstitch UV's and move the result", + "Unstitch UVs and move the result", OPTYPE_UNDO | OPTYPE_REGISTER); WM_operatortype_macro_define(ot, "UV_OT_rip"); otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); diff --git a/source/blender/editors/uvedit/uvedit_rip.c b/source/blender/editors/uvedit/uvedit_rip.c index de83f9e63ef..6cb6e67cced 100644 --- a/source/blender/editors/uvedit/uvedit_rip.c +++ b/source/blender/editors/uvedit/uvedit_rip.c @@ -55,7 +55,7 @@ typedef struct ULData { /** When the specified UV edge is selected. */ uint is_select_edge : 1; /** - * When only this UV is selected and none of the other UV's + * When only this UV is selected and none of the other UVs * around the connected fan are attached to an edge. * * In this case there is no need to detect contiguous loops, @@ -106,7 +106,7 @@ static BMLoop *bm_loop_find_other_radial_loop_with_visible_face(BMLoop *l_src, do { if (BM_elem_flag_test(l_iter->f, BM_ELEM_TAG) && UL(l_iter)->is_select_edge && BM_loop_uv_share_edge_check(l_src, l_iter, cd_loop_uv_offset)) { - /* Check UV's are contiguous. */ + /* Check UVs are contiguous. */ if (l_other == NULL) { l_other = l_iter; } @@ -132,7 +132,7 @@ static BMLoop *bm_loop_find_other_fan_loop_with_visible_face(BMLoop *l_src, do { if (BM_elem_flag_test(l_iter->f, BM_ELEM_TAG) && BM_loop_uv_share_edge_check(l_src, l_iter, cd_loop_uv_offset)) { - /* Check UV's are contiguous. */ + /* Check UVs are contiguous. */ if (l_other == NULL) { l_other = l_iter; } @@ -162,7 +162,7 @@ static BMLoop *bm_loop_find_other_fan_loop_with_visible_face(BMLoop *l_src, } /** - * A version of #BM_vert_step_fan_loop that checks UV's. + * A version of #BM_vert_step_fan_loop that checks UVs. */ static BMLoop *bm_vert_step_fan_loop_uv(BMLoop *l, BMEdge **e_step, const int cd_loop_uv_offset) { diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index a3fec5acdc4..a54d62b11b0 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -754,7 +754,7 @@ static BMLoop *uvedit_loop_find_other_radial_loop_with_visible_face(const Scene do { if (uvedit_face_visible_test(scene, l_iter->f) && BM_loop_uv_share_edge_check(l_src, l_iter, offsets.uv)) { - /* Check UV's are contiguous. */ + /* Check UVs are contiguous. */ if (l_other == NULL) { l_other = l_iter; } @@ -1107,7 +1107,7 @@ bool ED_uvedit_nearest_uv_multi(const View2D *v2d, * * These functions are quite specialized, useful when sync select is enabled * and we want to pick an active UV vertex/edge from the active element which may - * have multiple UV's split out. + * have multiple UVs split out. * \{ */ BMLoop *uv_find_nearest_loop_from_vert(struct Scene *scene, @@ -1830,7 +1830,7 @@ static void uv_select_linked_multi(Scene *scene, /* Special case, vertex/edge & sync select being enabled. * * Without this, a second linked select will 'grow' each time as each new - * selection reaches the boundaries of islands that share vertices but not UV's. + * selection reaches the boundaries of islands that share vertices but not UVs. * * Rules applied here: * - This loops face isn't selected. @@ -3368,7 +3368,7 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ts->uv_sticky == SI_STICKY_VERTEX) { /* Tag all verts as untouched, then touch the ones that have a face center - * in the loop and select all UV's that use a touched vert. */ + * in the loop and select all UVs that use a touched vert. */ BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { @@ -4160,7 +4160,7 @@ void UV_OT_select_lasso(wmOperatorType *ot) /** \} */ /* -------------------------------------------------------------------- */ -/** \name Select Pinned UV's Operator +/** \name Select Pinned UVs Operator * \{ */ static int uv_select_pinned_exec(bContext *C, wmOperator *op) diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 6be2300cca3..e6d895bd826 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1911,8 +1911,8 @@ static StitchState *stitch_init(bContext *C, all_edges[counter].first = NULL; all_edges[counter].flag = 0; all_edges[counter].element = element; - /* Using an order policy, sort UV's according to address space. - * This avoids having two different UvEdges with the same UV's on different positions. */ + /* Using an order policy, sort UVs according to address space. + * This avoids having two different UvEdges with the same UVs on different positions. */ if (offset1 < offset2) { all_edges[counter].uv1 = offset1; all_edges[counter].uv2 = offset2; diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 15a19fda77e..1ab398c185c 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -116,7 +116,7 @@ static bool ED_uvedit_ensure_uvs(Object *obedit) BM_uv_map_ensure_edge_select_attr(em->bm, active_uv_name); const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); - /* select new UV's (ignore UV_SYNC_SELECTION in this case) */ + /* select new UVs (ignore UV_SYNC_SELECTION in this case) */ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { BMIter liter; BMLoop *l; @@ -176,7 +176,7 @@ typedef struct UnwrapOptions { /** Only affect selected faces. */ bool only_selected_faces; /** - * Only affect selected UV's. + * Only affect selected UVs. * \note Disable this for operations that don't run in the image-window. * Unwrapping from the 3D view for example, where only 'only_selected_faces' should be used. */ @@ -1650,7 +1650,7 @@ static void uv_map_clip_correct_properties(wmOperatorType *ot) /** * \param per_face_aspect: Calculate the aspect ratio per-face, - * otherwise use a single aspect for all UV's based on the material of the active face. + * otherwise use a single aspect for all UVs based on the material of the active face. * TODO: using per-face aspect may split UV islands so more advanced UV projection methods * such as "Unwrap" & "Smart UV Projections" will need to handle aspect correction themselves. * For now keep using a single aspect for all faces in this case. @@ -2073,7 +2073,7 @@ void UV_OT_unwrap(wmOperatorType *ot) /** \name Smart UV Project Operator * \{ */ -/* Ignore all areas below this, as the UV's get zeroed. */ +/* Ignore all areas below this, as the UVs get zeroed. */ static const float smart_uv_project_area_ignore = 1e-12f; typedef struct ThickFace { @@ -2281,7 +2281,7 @@ static int smart_project_exec(bContext *C, wmOperator *op) while ((thick_faces_len > 0) && !(thick_faces[thick_faces_len - 1].area > smart_uv_project_area_ignore)) { - /* Zero UV's so they don't overlap with other faces being unwrapped. */ + /* Zero UVs so they don't overlap with other faces being unwrapped. */ BMIter liter; BMLoop *l; BM_ITER_ELEM (l, &liter, thick_faces[thick_faces_len - 1].efa, BM_LOOPS_OF_FACE) { diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 7879b3e9551..47c0bd9acd8 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -139,7 +139,7 @@ enum { * - Physics/collision detection. * * Storing loop indices (instead of vertex indices) allows us to - * directly access UV's, vertex-colors as well as vertices. + * directly access UVs, vertex-colors as well as vertices. * The index of the source polygon is stored as well, * giving access to materials and polygon normals. * @@ -364,7 +364,7 @@ typedef struct GridPaintMask { * Original space within a face (similar to UV coordinates), * however they are used to determine the original position in a face. * - * Unlike UV's these are not user editable and always start out using a fixed 0-1 range. + * Unlike UVs these are not user editable and always start out using a fixed 0-1 range. * Currently only used for particle placement. */ # diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index e81d8d8ed55..a42fb09dbf7 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2526,11 +2526,11 @@ enum { #define UVCALC_FILLHOLES (1 << 0) /** Would call this UVCALC_ASPECT_CORRECT, except it should be default with old file. */ #define UVCALC_NO_ASPECT_CORRECT (1 << 1) -/** Adjust UV's while transforming with Vert or Edge Slide. */ +/** Adjust UVs while transforming with Vert or Edge Slide. */ #define UVCALC_TRANSFORM_CORRECT_SLIDE (1 << 2) -/** Use mesh data after subsurf to compute UV's. */ +/** Use mesh data after subsurf to compute UVs. */ #define UVCALC_USESUBSURF (1 << 3) -/** Adjust UV's while transforming to avoid distortion */ +/** Adjust UVs while transforming to avoid distortion */ #define UVCALC_TRANSFORM_CORRECT (1 << 4) /** Keep equal values merged while correcting custom-data. */ #define UVCALC_TRANSFORM_CORRECT_KEEP_CONNECTED (1 << 5) diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 8270ed24fd9..090ef1e5e28 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -4902,13 +4902,13 @@ static void rna_def_modifier_screw(BlenderRNA *brna) prop = RNA_def_property(srna, "use_stretch_u", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SCREW_UV_STRETCH_U); RNA_def_property_ui_text( - prop, "Stretch U", "Stretch the U coordinates between 0 and 1 when UV's are present"); + prop, "Stretch U", "Stretch the U coordinates between 0 and 1 when UVs are present"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "use_stretch_v", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_SCREW_UV_STRETCH_V); RNA_def_property_ui_text( - prop, "Stretch V", "Stretch the V coordinates between 0 and 1 when UV's are present"); + prop, "Stretch V", "Stretch the V coordinates between 0 and 1 when UVs are present"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); # if 0 diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 61ba96c6d6e..5c75512183d 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -92,7 +92,7 @@ static const EnumPropertyItem uv_sculpt_relaxation_items[] = { "COTAN", 0, "Geometry", - "Use Geometry (cotangent) relaxation, making UV's follow the underlying 3D geometry"}, + "Use Geometry (cotangent) relaxation, making UVs follow the underlying 3D geometry"}, {0, NULL, 0, NULL, NULL}, }; #endif @@ -3277,7 +3277,7 @@ static void rna_def_tool_settings(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "uvcalc_flag", UVCALC_TRANSFORM_CORRECT); RNA_def_property_ui_text(prop, "Correct Face Attributes", - "Correct data such as UV's and color attributes when transforming"); + "Correct data such as UVs and color attributes when transforming"); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); prop = RNA_def_property(srna, "use_transform_correct_keep_connected", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c index 98b0f623843..2f6d0da1fde 100644 --- a/source/blender/modifiers/intern/MOD_dynamicpaint.c +++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c @@ -81,7 +81,7 @@ static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_ma if (pmd->canvas) { DynamicPaintSurface *surface = pmd->canvas->surfaces.first; for (; surface; surface = surface->next) { - /* UV's: #CD_PROP_FLOAT2. */ + /* UVs: #CD_PROP_FLOAT2. */ if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ || surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) { r_cddata_masks->lmask |= CD_MASK_PROP_FLOAT2; diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index 49d1a2feb43..ba8f13dd5c3 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -420,7 +420,7 @@ void wm_event_do_depsgraph(bContext *C, bool is_after_open_file) if (wm->is_interface_locked) { return; } - /* Combine data-masks so one window doesn't disable UV's in another T26448. */ + /* Combine data-masks so one window doesn't disable UVs in another T26448. */ CustomData_MeshMasks win_combine_v3d_datamask = {0}; LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { const Scene *scene = WM_window_get_active_scene(win); From dd9e1eded0d48e19a500233b20e8c5f18ed12a09 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 10 Jan 2023 16:12:14 -0500 Subject: [PATCH 0576/1522] Mesh: Move sharp edge flag to generic attribute Move the `ME_SHARP` flag for mesh edges to a generic boolean attribute. This will help allow changing mesh edges to just a pair of integers, giving performance improvements. In the future it could also give benefits for normal calculation, which could more easily check if all or no edges are marked sharp, which is helpful considering the plans in T93551. The attribute is generally only allocated when it's necessary. When leaving edit mode, it will only be created if an edge is marked sharp. The data can be edited with geometry nodes just like a regular edge domain boolean attribute. The attribute is named `sharp_edge`, aiming to reflect the similar `select_edge` naming and to allow a future `sharp_face` name in a separate commit. Ref T95966 Differential Revision: https://developer.blender.org/D16921 --- source/blender/blenkernel/BKE_mesh.h | 15 ++-- .../blenkernel/BKE_mesh_legacy_convert.h | 3 + source/blender/blenkernel/BKE_mesh_mapping.h | 1 + .../intern/curve_to_mesh_convert.cc | 85 +++++++++++++------ .../blender/blenkernel/intern/customdata.cc | 3 +- .../blenkernel/intern/data_transfer.cc | 33 ++++++- .../intern/geometry_component_mesh.cc | 14 ++- source/blender/blenkernel/intern/key.cc | 3 + source/blender/blenkernel/intern/mesh.cc | 8 +- .../blenkernel/intern/mesh_legacy_convert.cc | 42 +++++++++ .../blender/blenkernel/intern/mesh_mapping.cc | 18 +++- .../blender/blenkernel/intern/mesh_mirror.cc | 3 + .../blender/blenkernel/intern/mesh_normals.cc | 70 ++++++++------- .../blender/blenkernel/intern/mesh_remap.cc | 3 + .../blender/blenkernel/intern/subsurf_ccg.c | 2 +- .../blenloader/intern/versioning_400.cc | 1 + source/blender/bmesh/intern/bmesh_construct.c | 6 +- .../bmesh/intern/bmesh_mesh_convert.cc | 25 ++++++ .../draw_cache_extract_mesh_render_data.cc | 3 + source/blender/editors/mesh/mesh_data.cc | 31 +++---- .../editors/sculpt_paint/sculpt_face_set.cc | 5 +- .../intern/lineart/lineart_cpu.cc | 12 ++- .../wavefront_obj/exporter/obj_export_mesh.cc | 3 + source/blender/makesdna/DNA_meshdata_types.h | 3 +- source/blender/makesrna/intern/rna_mesh.c | 31 ++++++- source/blender/makesrna/intern/rna_mesh_api.c | 3 + .../modifiers/intern/MOD_normal_edit.cc | 21 ++++- .../intern/MOD_solidify_nonmanifold.c | 5 +- .../modifiers/intern/MOD_weighted_normal.cc | 20 ++++- 29 files changed, 360 insertions(+), 112 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 5190d09ccf8..4d81507ef1c 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -472,14 +472,14 @@ void BKE_mesh_ensure_normals_for_display(struct Mesh *mesh); * Used when defining an empty custom loop normals data layer, * to keep same shading as with auto-smooth! */ -void BKE_edges_sharp_from_angle_set(struct MEdge *medges, - int numEdges, +void BKE_edges_sharp_from_angle_set(int numEdges, const struct MLoop *mloops, int numLoops, const struct MPoly *mpolys, const float (*poly_normals)[3], int numPolys, - float split_angle); + float split_angle, + bool *sharp_edges); /** * References a contiguous loop-fan with normal offset vars. @@ -592,6 +592,8 @@ void BKE_lnor_space_custom_normal_to_data(const MLoopNorSpace *lnor_space, * (splitting edges). * * \param loop_to_poly_map: Optional pre-created map from loops to their polygon. + * \param sharp_edges: Optional array of sharp edge tags, used to split the evaluated normals on + * each side of the edge. */ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3], const float (*vert_normals)[3], @@ -606,6 +608,7 @@ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3], int numPolys, bool use_split_normals, float split_angle, + const bool *sharp_edges, const int *loop_to_poly_map, MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2]); @@ -613,7 +616,7 @@ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3], void BKE_mesh_normals_loop_custom_set(const float (*vert_positions)[3], const float (*vert_normals)[3], int numVerts, - struct MEdge *medges, + const struct MEdge *medges, int numEdges, const struct MLoop *mloops, float (*r_custom_loop_normals)[3], @@ -621,18 +624,20 @@ void BKE_mesh_normals_loop_custom_set(const float (*vert_positions)[3], const struct MPoly *mpolys, const float (*poly_normals)[3], int numPolys, + bool *sharp_edges, short (*r_clnors_data)[2]); void BKE_mesh_normals_loop_custom_from_verts_set(const float (*vert_positions)[3], const float (*vert_normals)[3], float (*r_custom_vert_normals)[3], int numVerts, - struct MEdge *medges, + const struct MEdge *medges, int numEdges, const struct MLoop *mloops, int numLoops, const struct MPoly *mpolys, const float (*poly_normals)[3], int numPolys, + bool *sharp_edges, short (*r_clnors_data)[2]); /** diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h index 3b1b94e516a..d6689da7d86 100644 --- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h +++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h @@ -95,6 +95,9 @@ void BKE_mesh_legacy_convert_loose_edges_to_flag(struct Mesh *mesh); void BKE_mesh_legacy_attribute_flags_to_strings(struct Mesh *mesh); void BKE_mesh_legacy_attribute_strings_to_flags(struct Mesh *mesh); +void BKE_mesh_legacy_sharp_edges_to_flags(struct Mesh *mesh); +void BKE_mesh_legacy_sharp_edges_from_flags(struct Mesh *mesh); + struct MVert *BKE_mesh_legacy_convert_positions_to_verts( Mesh *mesh, blender::ResourceScope &temp_arrays_for_convert, diff --git a/source/blender/blenkernel/BKE_mesh_mapping.h b/source/blender/blenkernel/BKE_mesh_mapping.h index 36ac0708629..4db3ea414f4 100644 --- a/source/blender/blenkernel/BKE_mesh_mapping.h +++ b/source/blender/blenkernel/BKE_mesh_mapping.h @@ -322,6 +322,7 @@ int *BKE_mesh_calc_smoothgroups(const struct MEdge *medge, int totpoly, const struct MLoop *mloop, int totloop, + const bool *sharp_edges, int *r_totgroup, bool use_bitflags); diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index 305a245a036..481e3018942 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -17,13 +17,6 @@ namespace blender::bke { -static void mark_edges_sharp(MutableSpan edges) -{ - for (MEdge &edge : edges) { - edge.flag |= ME_SHARP; - } -} - static void fill_mesh_topology(const int vert_offset, const int edge_offset, const int poly_offset, @@ -155,28 +148,26 @@ static void fill_mesh_topology(const int vert_offset, loop_end.v = last_ring_vert_offset + i; loop_end.e = last_ring_edge_offset + i; } - - mark_edges_sharp(edges.slice(profile_edges_start, profile_segment_num)); - mark_edges_sharp(edges.slice(last_ring_edge_offset, profile_segment_num)); } } +/** Set the sharp status for edges that correspond to control points with vector handles. */ static void mark_bezier_vector_edges_sharp(const int profile_point_num, const int main_segment_num, const Span control_point_offsets, const Span handle_types_left, const Span handle_types_right, - MutableSpan edges) + MutableSpan sharp_edges) { const int main_edges_start = 0; if (curves::bezier::point_is_sharp(handle_types_left, handle_types_right, 0)) { - mark_edges_sharp(edges.slice(main_edges_start, main_segment_num)); + sharp_edges.slice(main_edges_start, main_segment_num).fill(true); } for (const int i : IndexRange(profile_point_num).drop_front(1)) { if (curves::bezier::point_is_sharp(handle_types_left, handle_types_right, i)) { - mark_edges_sharp(edges.slice( - main_edges_start + main_segment_num * control_point_offsets[i - 1], main_segment_num)); + const int offset = main_edges_start + main_segment_num * control_point_offsets[i - 1]; + sharp_edges.slice(offset, main_segment_num).fill(true); } } } @@ -624,6 +615,38 @@ static void copy_curve_domain_attribute_to_mesh(const ResultOffsets &mesh_offset }); } +static void write_sharp_bezier_edges(const CurvesInfo &curves_info, + const ResultOffsets &offsets, + MutableAttributeAccessor mesh_attributes, + SpanAttributeWriter &sharp_edges) +{ + const CurvesGeometry &profile = curves_info.profile; + if (!profile.has_curve_with_type(CURVE_TYPE_BEZIER)) { + return; + } + const VArraySpan handle_types_left{profile.handle_types_left()}; + const VArraySpan handle_types_right{profile.handle_types_right()}; + if (!handle_types_left.contains(BEZIER_HANDLE_VECTOR) && + !handle_types_right.contains(BEZIER_HANDLE_VECTOR)) { + return; + } + + sharp_edges = mesh_attributes.lookup_or_add_for_write_span("sharp_edge", ATTR_DOMAIN_EDGE); + + const VArray types = profile.curve_types(); + foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) { + if (types[info.i_profile] == CURVE_TYPE_BEZIER) { + const IndexRange points = profile.points_for_curve(info.i_profile); + mark_bezier_vector_edges_sharp(points.size(), + info.main_segment_num, + profile.bezier_evaluated_offsets_for_curve(info.i_profile), + handle_types_left.slice(points), + handle_types_right.slice(points), + sharp_edges.span.slice(info.edge_range)); + } + }); +} + Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, const CurvesGeometry &profile, const bool fill_caps, @@ -691,28 +714,34 @@ Mesh *curve_to_mesh_sweep(const CurvesGeometry &main, positions.slice(info.vert_range)); }); - if (profile.curve_type_counts()[CURVE_TYPE_BEZIER] > 0) { - const VArray curve_types = profile.curve_types(); - const VArraySpan handle_types_left{profile.handle_types_left()}; - const VArraySpan handle_types_right{profile.handle_types_right()}; + MutableAttributeAccessor mesh_attributes = mesh->attributes_for_write(); + SpanAttributeWriter sharp_edges; + write_sharp_bezier_edges(curves_info, offsets, mesh_attributes, sharp_edges); + if (fill_caps) { + if (!sharp_edges) { + sharp_edges = mesh_attributes.lookup_or_add_for_write_span("sharp_edge", + ATTR_DOMAIN_EDGE); + } foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) { - if (curve_types[info.i_profile] == CURVE_TYPE_BEZIER) { - const IndexRange points = profile.points_for_curve(info.i_profile); - mark_bezier_vector_edges_sharp(points.size(), - info.main_segment_num, - profile.bezier_evaluated_offsets_for_curve(info.i_profile), - handle_types_left.slice(points), - handle_types_right.slice(points), - edges.slice(info.edge_range)); + if (info.main_cyclic || !info.profile_cyclic) { + return; } + const int main_edges_start = info.edge_range.start(); + const int last_ring_index = info.main_points.size() - 1; + const int profile_edges_start = main_edges_start + + info.profile_points.size() * info.main_segment_num; + const int last_ring_edge_offset = profile_edges_start + + info.profile_segment_num * last_ring_index; + + sharp_edges.span.slice(profile_edges_start, info.profile_segment_num).fill(true); + sharp_edges.span.slice(last_ring_edge_offset, info.profile_segment_num).fill(true); }); } + sharp_edges.finish(); Set main_attributes_set; - MutableAttributeAccessor mesh_attributes = mesh->attributes_for_write(); - main_attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData meta_data) { if (!should_add_attribute_to_mesh( main_attributes, mesh_attributes, id, meta_data, propagation_info)) { diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 8444598d7d8..433c4355d97 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -2300,7 +2300,8 @@ static bool attribute_stored_in_bmesh_flag(const StringRef name) ".select_vert", ".select_edge", ".select_poly", - "material_index"); + "material_index", + "sharp_edge"); } CustomData CustomData_shallow_copy_remove_non_bmesh_attributes(const CustomData *src, diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index 39837051c0a..b3b8d4730bb 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -20,6 +20,7 @@ #include "BLI_utildefines.h" #include "BKE_attribute.h" +#include "BKE_attribute.hh" #include "BKE_customdata.h" #include "BKE_data_transfer.h" #include "BKE_deform.h" @@ -287,6 +288,8 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src, CustomData_set_layer_flag(ldata_dst, CD_NORMAL, CD_FLAG_TEMPORARY); } if (dirty_nors_dst || do_loop_nors_dst) { + const bool *sharp_edges = static_cast( + CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, "sharp_edge")); BKE_mesh_normals_loop_split(positions_dst, BKE_mesh_vertex_normals_ensure(me_dst), num_verts_dst, @@ -300,6 +303,7 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src, num_polys_dst, use_split_nors_dst, split_angle_dst, + sharp_edges, nullptr, nullptr, custom_nors_dst); @@ -314,6 +318,7 @@ static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/, const int dtdata_type, const bool changed) { + using namespace blender; if (dtdata_type == DT_TYPE_LNOR) { if (!changed) { return; @@ -341,6 +346,10 @@ static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/, ldata_dst, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, nullptr, num_loops_dst)); } + bke::MutableAttributeAccessor attributes = me_dst->attributes_for_write(); + bke::SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_span( + "sharp_edge", ATTR_DOMAIN_EDGE); + /* Note loop_nors_dst contains our custom normals as transferred from source... */ BKE_mesh_normals_loop_custom_set(positions_dst, BKE_mesh_vertex_normals_ensure(me_dst), @@ -353,7 +362,9 @@ static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/, polys_dst, poly_nors_dst, num_polys_dst, + sharp_edges.span.data(), custom_nors_dst); + sharp_edges.finish(); } } @@ -961,11 +972,11 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, } return true; } - if (r_map && ELEM(cddata_type, CD_FAKE_SHARP, CD_FAKE_SEAM)) { + if (r_map && cddata_type == CD_FAKE_SEAM) { const size_t elem_size = sizeof(*((MEdge *)nullptr)); const size_t data_size = sizeof(((MEdge *)nullptr)->flag); const size_t data_offset = offsetof(MEdge, flag); - const uint64_t data_flag = (cddata_type == CD_FAKE_SHARP) ? ME_SHARP : ME_SEAM; + const uint64_t data_flag = ME_SEAM; data_transfer_layersmapping_add_item(r_map, cddata_type, @@ -984,7 +995,23 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, interp_data); return true; } - + if (r_map && cddata_type == CD_FAKE_SHARP) { + if (!CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, "sharp_edge")) { + CustomData_add_layer_named( + &me_dst->edata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, me_dst->totedge, "sharp_edge"); + } + data_transfer_layersmapping_add_item_cd( + r_map, + CD_PROP_BOOL, + mix_mode, + mix_factor, + mix_weights, + CustomData_get_layer_named(&me_src->edata, CD_PROP_BOOL, "sharp_edge"), + CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, "sharp_edge"), + interp, + interp_data); + return true; + } return false; } else if (elem_type == ME_LOOP) { diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index c91dc249249..7b694be324a 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -1276,6 +1276,18 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() make_derived_write_attribute, nullptr); + static BuiltinCustomDataLayerProvider sharp_edge("sharp_edge", + ATTR_DOMAIN_EDGE, + CD_PROP_BOOL, + CD_PROP_BOOL, + BuiltinAttributeProvider::Creatable, + BuiltinAttributeProvider::Writable, + BuiltinAttributeProvider::Deletable, + edge_access, + make_array_read_attribute, + make_array_write_attribute, + nullptr); + static BuiltinCustomDataLayerProvider crease( "crease", ATTR_DOMAIN_EDGE, @@ -1296,7 +1308,7 @@ static ComponentAttributeProviders create_attribute_providers_for_mesh() static CustomDataAttributeProvider face_custom_data(ATTR_DOMAIN_FACE, face_access); return ComponentAttributeProviders( - {&position, &id, &material_index, &shade_smooth, &normal, &crease}, + {&position, &id, &material_index, &shade_smooth, &sharp_edge, &normal, &crease}, {&corner_custom_data, &vertex_groups, &point_custom_data, diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index c4e083f9fc5..0dfb6d2c093 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -2274,6 +2274,8 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, if (loop_normals_needed) { short(*clnors)[2] = static_cast( CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL)); /* May be nullptr. */ + const bool *sharp_edges = static_cast( + CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge")); BKE_mesh_normals_loop_split(positions, vert_normals, mesh->totvert, @@ -2287,6 +2289,7 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, mesh->totpoly, (mesh->flag & ME_AUTOSMOOTH) != 0, mesh->smoothresh, + sharp_edges, nullptr, nullptr, clnors); diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 60547a57094..f67cf7e0646 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -272,6 +272,7 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address BKE_mesh_legacy_bevel_weight_from_layers(mesh); BKE_mesh_legacy_face_set_from_generic(mesh, poly_layers); BKE_mesh_legacy_edge_crease_from_layers(mesh); + BKE_mesh_legacy_sharp_edges_to_flags(mesh); BKE_mesh_legacy_attribute_strings_to_flags(mesh); mesh->active_color_attribute = nullptr; mesh->default_color_attribute = nullptr; @@ -1830,8 +1831,6 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray *r_lnors_spacearr, float (*r_corner_normals)[3]) { - short(*clnors)[2] = nullptr; - /* Note that we enforce computing clnors when the clnor space array is requested by caller here. * However, we obviously only use the auto-smooth angle threshold * only in case auto-smooth is enabled. */ @@ -1840,7 +1839,9 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : float(M_PI); /* may be nullptr */ - clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); + short(*clnors)[2] = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); + const bool *sharp_edges = static_cast( + CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge")); const Span positions = mesh->vert_positions(); const Span edges = mesh->edges(); @@ -1860,6 +1861,7 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, polys.size(), use_split_normals, split_angle, + sharp_edges, nullptr, r_lnors_spacearr, clnors); diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 868653013a6..1ad70792a22 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -1341,6 +1341,48 @@ void BKE_mesh_legacy_edge_crease_to_layers(Mesh *mesh) } } +/* -------------------------------------------------------------------- */ +/** \name Sharp Edge Conversion + * \{ */ + +void BKE_mesh_legacy_sharp_edges_to_flags(Mesh *mesh) +{ + using namespace blender; + MutableSpan edges = mesh->edges_for_write(); + if (const bool *sharp_edges = static_cast( + CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge"))) { + threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) { + for (const int i : range) { + SET_FLAG_FROM_TEST(edges[i].flag, sharp_edges[i], ME_SHARP); + } + }); + } + else { + for (const int i : edges.index_range()) { + edges[i].flag &= ~ME_SHARP; + } + } +} + +void BKE_mesh_legacy_sharp_edges_from_flags(Mesh *mesh) +{ + using namespace blender; + using namespace blender::bke; + const Span edges = mesh->edges(); + MutableAttributeAccessor attributes = mesh->attributes_for_write(); + if (std::any_of( + edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & ME_SHARP; })) { + SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_only_span( + "sharp_edge", ATTR_DOMAIN_EDGE); + threading::parallel_for(edges.index_range(), 4096, [&](const IndexRange range) { + for (const int i : range) { + sharp_edges.span[i] = edges[i].flag & ME_SHARP; + } + }); + sharp_edges.finish(); + } +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/mesh_mapping.cc b/source/blender/blenkernel/intern/mesh_mapping.cc index 7ebf57ffd3c..15bdf58849a 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.cc +++ b/source/blender/blenkernel/intern/mesh_mapping.cc @@ -632,6 +632,8 @@ Vector> build_edge_to_loop_map_resizable(const Span loops, co using MeshRemap_CheckIslandBoundary = bool (*)(const MPoly *mpoly, const MLoop *mloop, const MEdge *medge, + const int edge_index, + const bool *sharp_edges, const int edge_user_count, const MPoly *mpoly_array, const MeshElemMap *edge_poly_map, @@ -643,6 +645,7 @@ static void poly_edge_loop_islands_calc(const MEdge *medge, const int totpoly, const MLoop *mloop, const int totloop, + const bool *sharp_edges, MeshElemMap *edge_poly_map, const bool use_bitflags, MeshRemap_CheckIslandBoundary edge_boundary_check, @@ -734,7 +737,8 @@ static void poly_edge_loop_islands_calc(const MEdge *medge, const MeshElemMap *map_ele = &edge_poly_map[me_idx]; const int *p = map_ele->indices; int i = map_ele->count; - if (!edge_boundary_check(mp, ml, me, i, mpoly, map_ele, edge_boundary_check_data)) { + if (!edge_boundary_check( + mp, ml, me, me_idx, sharp_edges, i, mpoly, map_ele, edge_boundary_check_data)) { for (; i--; p++) { /* if we meet other non initialized its a bug */ BLI_assert(ELEM(poly_groups[*p], 0, poly_group_id)); @@ -834,7 +838,9 @@ static void poly_edge_loop_islands_calc(const MEdge *medge, static bool poly_is_island_boundary_smooth_cb(const MPoly *mp, const MLoop * /*ml*/, - const MEdge *me, + const MEdge * /*me*/, + const int edge_index, + const bool *sharp_edges, const int edge_user_count, const MPoly *mpoly_array, const MeshElemMap *edge_poly_map, @@ -842,7 +848,8 @@ static bool poly_is_island_boundary_smooth_cb(const MPoly *mp, { /* Edge is sharp if one of its polys is flat, or edge itself is sharp, * or edge is not used by exactly two polygons. */ - if ((mp->flag & ME_SMOOTH) && !(me->flag & ME_SHARP) && (edge_user_count == 2)) { + if ((mp->flag & ME_SMOOTH) && !(sharp_edges && sharp_edges[edge_index]) && + (edge_user_count == 2)) { /* In that case, edge appears to be smooth, but we need to check its other poly too. */ const MPoly *mp_other = (mp == &mpoly_array[edge_poly_map->indices[0]]) ? &mpoly_array[edge_poly_map->indices[1]] : @@ -858,6 +865,7 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge, const int totpoly, const MLoop *mloop, const int totloop, + const bool *sharp_edges, int *r_totgroup, const bool use_bitflags) { @@ -869,6 +877,7 @@ int *BKE_mesh_calc_smoothgroups(const MEdge *medge, totpoly, mloop, totloop, + sharp_edges, nullptr, use_bitflags, poly_is_island_boundary_smooth_cb, @@ -1011,6 +1020,8 @@ struct MeshCheckIslandBoundaryUv { static bool mesh_check_island_boundary_uv(const MPoly * /*mp*/, const MLoop *ml, const MEdge *me, + const int /*edge_index*/, + const bool * /*sharp_edges*/, const int /*edge_user_count*/, const MPoly * /*mpoly_array*/, const MeshElemMap * /*edge_poly_map*/, @@ -1109,6 +1120,7 @@ static bool mesh_calc_islands_loop_poly_uv(const MEdge *edges, totpoly, loops, totloop, + nullptr, edge_poly_map, false, mesh_check_island_boundary_uv, diff --git a/source/blender/blenkernel/intern/mesh_mirror.cc b/source/blender/blenkernel/intern/mesh_mirror.cc index 843f7226432..3f5d18e86b9 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.cc +++ b/source/blender/blenkernel/intern/mesh_mirror.cc @@ -408,6 +408,8 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, /* calculate custom normals into loop_normals, then mirror first half into second half */ + const bool *sharp_edges = static_cast( + CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge")); BKE_mesh_normals_loop_split(BKE_mesh_vert_positions(result), BKE_mesh_vertex_normals_ensure(result), result->totvert, @@ -421,6 +423,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, totpoly, true, mesh->smoothresh, + sharp_edges, nullptr, &lnors_spacearr, clnors); diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index 266ef0efa0b..aa5b2d761f7 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -30,6 +30,7 @@ #include "BLI_timeit.hh" #include "BLI_utildefines.h" +#include "BKE_attribute.hh" #include "BKE_customdata.h" #include "BKE_editmesh_cache.h" #include "BKE_global.h" @@ -44,6 +45,7 @@ using blender::int2; using blender::MutableSpan; using blender::short2; using blender::Span; +using blender::VArray; // #define DEBUG_TIME @@ -787,15 +789,15 @@ struct LoopSplitTaskDataCommon { /* See comment about edge_to_loops below. */ #define IS_EDGE_SHARP(_e2l) ELEM((_e2l)[1], INDEX_UNSET, INDEX_INVALID) -static void mesh_edges_sharp_tag(const Span edges, - const Span polys, +static void mesh_edges_sharp_tag(const Span polys, const Span loops, const Span loop_to_poly_map, const Span poly_normals, + const Span sharp_edges, const bool check_angle, const float split_angle, MutableSpan edge_to_loops, - BitVector<> *r_sharp_edges) + MutableSpan r_sharp_edges) { using namespace blender; const float split_angle_cos = check_angle ? cosf(split_angle) : -1.0f; @@ -825,15 +827,15 @@ static void mesh_edges_sharp_tag(const Span edges, * or both poly have opposed (flipped) normals, i.e. both loops on the same edge share the * same vertex, or angle between both its polys' normals is above split_angle value. */ - if (!(poly.flag & ME_SMOOTH) || (edges[edge_i].flag & ME_SHARP) || + if (!(poly.flag & ME_SMOOTH) || (!sharp_edges.is_empty() && sharp_edges[edge_i]) || vert_i == loops[e2l[0]].v || is_angle_sharp) { /* NOTE: we are sure that loop != 0 here ;). */ e2l[1] = INDEX_INVALID; /* We want to avoid tagging edges as sharp when it is already defined as such by * other causes than angle threshold. */ - if (r_sharp_edges && is_angle_sharp) { - (*r_sharp_edges)[edge_i].set(); + if (!r_sharp_edges.is_empty() && is_angle_sharp) { + r_sharp_edges[edge_i] = true; } } else { @@ -846,8 +848,8 @@ static void mesh_edges_sharp_tag(const Span edges, /* We want to avoid tagging edges as sharp when it is already defined as such by * other causes than angle threshold. */ - if (r_sharp_edges) { - (*r_sharp_edges)[edge_i].reset(); + if (!r_sharp_edges.is_empty()) { + r_sharp_edges[edge_i] = false; } } /* Else, edge is already 'disqualified' (i.e. sharp)! */ @@ -855,14 +857,14 @@ static void mesh_edges_sharp_tag(const Span edges, } } -void BKE_edges_sharp_from_angle_set(MEdge *medges, - const int numEdges, +void BKE_edges_sharp_from_angle_set(const int numEdges, const MLoop *mloops, const int numLoops, const MPoly *mpolys, const float (*poly_normals)[3], const int numPolys, - const float split_angle) + const float split_angle, + bool *sharp_edges) { using namespace blender; using namespace blender::bke; @@ -878,24 +880,15 @@ void BKE_edges_sharp_from_angle_set(MEdge *medges, const Array loop_to_poly = mesh_topology::build_loop_to_poly_map({mpolys, numPolys}, numLoops); - BitVector<> sharp_edges(numEdges, false); - mesh_edges_sharp_tag({medges, numEdges}, - {mpolys, numPolys}, + mesh_edges_sharp_tag({mpolys, numPolys}, {mloops, numLoops}, loop_to_poly, {reinterpret_cast(poly_normals), numPolys}, + Span(sharp_edges, numEdges), true, split_angle, edge_to_loops, - &sharp_edges); - - threading::parallel_for(IndexRange(numEdges), 4096, [&](const IndexRange range) { - for (const int edge_i : range) { - if (sharp_edges[edge_i]) { - medges[edge_i].flag |= ME_SHARP; - } - } - }); + {sharp_edges, numEdges}); } static void loop_manifold_fan_around_vert_next(const Span loops, @@ -1455,6 +1448,7 @@ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3], const int numPolys, const bool use_split_normals, const float split_angle, + const bool *sharp_edges, const int *loop_to_poly_map, MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2]) @@ -1565,15 +1559,15 @@ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3], }); /* This first loop check which edges are actually smooth, and compute edge vectors. */ - mesh_edges_sharp_tag({medges, numEdges}, - polys, + mesh_edges_sharp_tag(polys, loops, loop_to_poly, {reinterpret_cast(poly_normals), numPolys}, + Span(sharp_edges, sharp_edges ? numEdges : 0), check_angle, split_angle, edge_to_loops, - nullptr); + {}); if (numLoops < LOOP_SPLIT_TASK_BLOCK_SIZE * 8) { /* Not enough loops to be worth the whole threading overhead. */ @@ -1612,7 +1606,7 @@ void BKE_mesh_normals_loop_split(const float (*vert_positions)[3], static void mesh_normals_loop_custom_set(const float (*positions)[3], const float (*vert_normals)[3], const int numVerts, - MEdge *medges, + const MEdge *medges, const int numEdges, const MLoop *mloops, float (*r_custom_loop_normals)[3], @@ -1620,6 +1614,7 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3], const MPoly *mpolys, const float (*poly_normals)[3], const int numPolys, + MutableSpan sharp_edges, short (*r_clnors_data)[2], const bool use_vertices) { @@ -1658,6 +1653,7 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3], numPolys, use_split_normals, split_angle, + sharp_edges.data(), loop_to_poly.data(), &lnors_spacearr, nullptr); @@ -1740,7 +1736,7 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3], const MPoly *mp = &mpolys[loop_to_poly[lidx]]; const MLoop *mlp = &mloops[(lidx == mp->loopstart) ? mp->loopstart + mp->totloop - 1 : lidx - 1]; - medges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e].flag |= ME_SHARP; + sharp_edges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e] = true; org_nor = nor; } @@ -1765,7 +1761,7 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3], const MPoly *mp = &mpolys[loop_to_poly[lidx]]; const MLoop *mlp = &mloops[(lidx == mp->loopstart) ? mp->loopstart + mp->totloop - 1 : lidx - 1]; - medges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e].flag |= ME_SHARP; + sharp_edges[(prev_ml->e == mlp->e) ? prev_ml->e : ml->e] = true; } } } @@ -1785,6 +1781,7 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3], numPolys, use_split_normals, split_angle, + sharp_edges.data(), loop_to_poly.data(), &lnors_spacearr, nullptr); @@ -1852,7 +1849,7 @@ static void mesh_normals_loop_custom_set(const float (*positions)[3], void BKE_mesh_normals_loop_custom_set(const float (*vert_positions)[3], const float (*vert_normals)[3], const int numVerts, - MEdge *medges, + const MEdge *medges, const int numEdges, const MLoop *mloops, float (*r_custom_loop_normals)[3], @@ -1860,6 +1857,7 @@ void BKE_mesh_normals_loop_custom_set(const float (*vert_positions)[3], const MPoly *mpolys, const float (*poly_normals)[3], const int numPolys, + bool *sharp_edges, short (*r_clnors_data)[2]) { mesh_normals_loop_custom_set(vert_positions, @@ -1873,6 +1871,7 @@ void BKE_mesh_normals_loop_custom_set(const float (*vert_positions)[3], mpolys, poly_normals, numPolys, + {sharp_edges, numEdges}, r_clnors_data, false); } @@ -1881,13 +1880,14 @@ void BKE_mesh_normals_loop_custom_from_verts_set(const float (*vert_positions)[3 const float (*vert_normals)[3], float (*r_custom_vert_normals)[3], const int numVerts, - MEdge *medges, + const MEdge *medges, const int numEdges, const MLoop *mloops, const int numLoops, const MPoly *mpolys, const float (*poly_normals)[3], const int numPolys, + bool *sharp_edges, short (*r_clnors_data)[2]) { mesh_normals_loop_custom_set(vert_positions, @@ -1901,12 +1901,15 @@ void BKE_mesh_normals_loop_custom_from_verts_set(const float (*vert_positions)[3 mpolys, poly_normals, numPolys, + {sharp_edges, numEdges}, r_clnors_data, true); } static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const bool use_vertices) { + using namespace blender; + using namespace blender::bke; short(*clnors)[2]; const int numloops = mesh->totloop; @@ -1922,6 +1925,9 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const MutableSpan edges = mesh->edges_for_write(); const Span polys = mesh->polys(); const Span loops = mesh->loops(); + MutableAttributeAccessor attributes = mesh->attributes_for_write(); + SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_span( + "sharp_edge", ATTR_DOMAIN_EDGE); mesh_normals_loop_custom_set(reinterpret_cast(positions.data()), BKE_mesh_vertex_normals_ensure(mesh), @@ -1934,8 +1940,10 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const polys.data(), BKE_mesh_poly_normals_ensure(mesh), polys.size(), + sharp_edges.span, clnors, use_vertices); + sharp_edges.finish(); } void BKE_mesh_set_custom_normals(Mesh *mesh, float (*r_custom_loop_normals)[3]) diff --git a/source/blender/blenkernel/intern/mesh_remap.cc b/source/blender/blenkernel/intern/mesh_remap.cc index 08f7716e097..0b073e8d77f 100644 --- a/source/blender/blenkernel/intern/mesh_remap.cc +++ b/source/blender/blenkernel/intern/mesh_remap.cc @@ -1368,6 +1368,8 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, CustomData_set_layer_flag(ldata_dst, CD_NORMAL, CD_FLAG_TEMPORARY); } if (dirty_nors_dst || do_loop_nors_dst) { + const bool *sharp_edges = static_cast( + CustomData_get_layer_named(&mesh_dst->edata, CD_PROP_BOOL, "sharp_edge")); BKE_mesh_normals_loop_split(vert_positions_dst, BKE_mesh_vertex_normals_ensure(mesh_dst), numverts_dst, @@ -1381,6 +1383,7 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, numpolys_dst, use_split_nors_dst, split_angle_dst, + sharp_edges, nullptr, nullptr, custom_nors_dst); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index c6f8fef3a93..910076d8b43 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -999,7 +999,7 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) if (edgeFlags) { if (edgeIdx != -1) { - ed_flag |= ((edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW); + ed_flag |= ((edgeFlags[index] & ME_SEAM) | ME_EDGEDRAW); } } else { diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index d561c3592d7..35ab2b249e2 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -32,6 +32,7 @@ static void version_mesh_legacy_to_struct_of_array_format(Mesh &mesh) BKE_mesh_legacy_convert_uvs_to_generic(&mesh); BKE_mesh_legacy_convert_mpoly_to_material_indices(&mesh); BKE_mesh_legacy_bevel_weight_to_layers(&mesh); + BKE_mesh_legacy_sharp_edges_from_flags(&mesh); BKE_mesh_legacy_face_set_to_generic(&mesh); BKE_mesh_legacy_edge_crease_to_layers(&mesh); BKE_mesh_legacy_convert_verts_to_positions(&mesh); diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index 90609121963..0c05e7bb83d 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -718,8 +718,7 @@ BMesh *BM_mesh_copy(BMesh *bm_old) char BM_edge_flag_from_mflag(const short mflag) { - return (((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | ((mflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) | - ((mflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0)); + return (((mflag & ME_SEAM) ? BM_ELEM_SEAM : 0) | ((mflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0)); } char BM_face_flag_from_mflag(const char mflag) { @@ -730,8 +729,7 @@ short BM_edge_flag_to_mflag(BMEdge *e) { const char hflag = e->head.hflag; - return (((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) | ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) | - ((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0)); + return (((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) | ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0)); } char BM_face_flag_to_mflag(BMFace *f) { diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.cc b/source/blender/bmesh/intern/bmesh_mesh_convert.cc index 3d3251598eb..c795fd1138a 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_convert.cc +++ b/source/blender/bmesh/intern/bmesh_mesh_convert.cc @@ -336,6 +336,8 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar &me->pdata, CD_PROP_BOOL, ".hide_poly"); const int *material_indices = (const int *)CustomData_get_layer_named( &me->pdata, CD_PROP_INT32, "material_index"); + const bool *sharp_edges = (const bool *)CustomData_get_layer_named( + &me->edata, CD_PROP_BOOL, "sharp_edge"); const Span positions = me->vert_positions(); Array vtable(me->totvert); @@ -390,6 +392,9 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshPar if (select_edge && select_edge[i]) { BM_edge_select_set(bm, e, true); } + if (!(sharp_edges && sharp_edges[i])) { + BM_elem_flag_enable(e, BM_ELEM_SMOOTH); + } /* Copy Custom Data */ CustomData_to_bmesh_block(&mesh_edata, &bm->edata, i, &e->head.data, true); @@ -1063,6 +1068,7 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh bool need_hide_edge = false; bool need_hide_poly = false; bool need_material_index = false; + bool need_sharp_edge = false; i = 0; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { @@ -1098,6 +1104,9 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { need_select_edge = true; } + if (!BM_elem_flag_test(e, BM_ELEM_SMOOTH)) { + need_sharp_edge = true; + } BM_elem_index_set(e, i); /* set_inline */ @@ -1158,6 +1167,13 @@ void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMesh ATTR_DOMAIN_FACE, [&](const int i) { return int(BM_face_at_index(bm, i)->mat_nr); }); } + if (need_sharp_edge) { + BM_mesh_elem_table_ensure(bm, BM_EDGE); + write_fn_to_attribute( + me->attributes_for_write(), "sharp_edge", ATTR_DOMAIN_EDGE, [&](const int i) { + return !BM_elem_flag_test(BM_edge_at_index(bm, i), BM_ELEM_SMOOTH); + }); + } /* Patch hook indices and vertex parents. */ if (params->calc_object_remap && (ototvert > 0)) { @@ -1352,6 +1368,7 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * bke::SpanAttributeWriter hide_edge_attribute; bke::SpanAttributeWriter select_edge_attribute; + bke::SpanAttributeWriter sharp_edge_attribute; BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) { MEdge *med = &medge[i]; @@ -1375,6 +1392,13 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * } select_edge_attribute.span[i] = true; } + if (!BM_elem_flag_test(eed, BM_ELEM_SMOOTH)) { + if (!sharp_edge_attribute) { + sharp_edge_attribute = mesh_attributes.lookup_or_add_for_write_span( + "sharp_edge", ATTR_DOMAIN_EDGE); + } + sharp_edge_attribute.span[i] = true; + } CustomData_from_bmesh_block(&bm->edata, &me->edata, eed->head.data, i); } @@ -1442,4 +1466,5 @@ void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks * select_vert_attribute.finish(); select_edge_attribute.finish(); select_poly_attribute.finish(); + sharp_edge_attribute.finish(); } diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc index 1488fc79fd9..add0a395d70 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc @@ -368,6 +368,8 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_ MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__)); short(*clnors)[2] = static_cast( CustomData_get_layer(&mr->me->ldata, CD_CUSTOMLOOPNORMAL)); + const bool *sharp_edges = static_cast( + CustomData_get_layer_named(&mr->me->edata, CD_PROP_BOOL, "sharp_edge")); BKE_mesh_normals_loop_split(reinterpret_cast(mr->vert_positions), mr->vert_normals, mr->vert_len, @@ -381,6 +383,7 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_ mr->poly_len, is_auto_smooth, split_angle, + sharp_edges, nullptr, nullptr, clnors); diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index d939db74e73..8b3ecf6f59f 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -843,6 +843,7 @@ void MESH_OT_customdata_skin_clear(wmOperatorType *ot) /* Clear custom loop normals */ static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator * /*op*/) { + using namespace blender; Mesh *me = ED_mesh_context(C); if (BKE_mesh_has_custom_loop_normals(me)) { return OPERATOR_CANCELLED; @@ -862,18 +863,20 @@ static int mesh_customdata_custom_splitnormals_add_exec(bContext *C, wmOperator /* Tag edges as sharp according to smooth threshold if needed, * to preserve auto-smooth shading. */ if (me->flag & ME_AUTOSMOOTH) { - MutableSpan edges = me->edges_for_write(); const Span polys = me->polys(); const Span loops = me->loops(); - - BKE_edges_sharp_from_angle_set(edges.data(), - edges.size(), + bke::MutableAttributeAccessor attributes = me->attributes_for_write(); + bke::SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_span( + "sharp_edge", ATTR_DOMAIN_EDGE); + BKE_edges_sharp_from_angle_set(me->totedge, loops.data(), loops.size(), polys.data(), BKE_mesh_poly_normals_ensure(me), polys.size(), - me->smoothresh); + me->smoothresh, + sharp_edges.span.data()); + sharp_edges.finish(); } CustomData_add_layer(&me->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, nullptr, me->totloop); @@ -1532,36 +1535,34 @@ Mesh *ED_mesh_context(bContext *C) void ED_mesh_split_faces(Mesh *mesh) { using namespace blender; - Array edges(mesh->edges()); const Span polys = mesh->polys(); const Span loops = mesh->loops(); const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : float(M_PI); - BKE_edges_sharp_from_angle_set(edges.data(), - edges.size(), + + Array sharp_edges(mesh->totedge, false); + BKE_edges_sharp_from_angle_set(mesh->totedge, loops.data(), loops.size(), polys.data(), BKE_mesh_poly_normals_ensure(mesh), polys.size(), - split_angle); + split_angle, + sharp_edges.data()); threading::parallel_for(polys.index_range(), 1024, [&](const IndexRange range) { for (const int poly_i : range) { const MPoly &poly = polys[poly_i]; if (!(poly.flag & ME_SMOOTH)) { for (const MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) { - edges[loop.e].flag |= ME_SHARP; + sharp_edges[loop.e] = true; } } } }); Vector split_indices; - const IndexMask split_mask = index_mask_ops::find_indices_based_on_predicate( - edges.index_range(), 4096, split_indices, [&](const int64_t i) { - return edges[i].flag & ME_SHARP; - }); - + const IndexMask split_mask = index_mask_ops::find_indices_from_virtual_array( + sharp_edges.index_range(), VArray::ForSpan(sharp_edges), 4096, split_indices); if (split_mask.is_empty()) { return; } diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index 584e4d20d2b..d5e8e1cdf98 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -697,10 +697,11 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op) break; } case SCULPT_FACE_SETS_FROM_SHARP_EDGES: { - const Span edges = mesh->edges(); + const VArraySpan sharp_edges = mesh->attributes().lookup_or_default( + "sharp_edge", ATTR_DOMAIN_EDGE, false); sculpt_face_sets_init_flood_fill( ob, [&](const int /*from_face*/, const int edge, const int /*to_face*/) -> bool { - return (edges[edge].flag & ME_SHARP) == 0; + return !sharp_edges[edge]; }); break; } diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index 8971b2f297c..60279e687cc 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -17,6 +17,7 @@ #include "PIL_time.h" +#include "BKE_attribute.hh" #include "BKE_camera.h" #include "BKE_collection.h" #include "BKE_customdata.h" @@ -1477,6 +1478,7 @@ struct EdgeFeatData { blender::Span loops; blender::Span polys; LineartTriangle *tri_array; + blender::VArray sharp_edges; LineartVert *v_array; float crease_threshold; bool use_auto_smooth; @@ -1682,9 +1684,8 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata, e_feat_data->edges.data(), e_feat_data->loops.data(), &mlooptri[i / 3], real_edges); if (real_edges[i % 3] >= 0) { - const MEdge *medge = &e_feat_data->edges[real_edges[i % 3]]; - - if (ld->conf.use_crease && ld->conf.sharp_as_crease && (medge->flag & ME_SHARP)) { + if (ld->conf.use_crease && ld->conf.sharp_as_crease && + e_feat_data->sharp_edges[real_edges[i % 3]]) { edge_flag_result |= LRT_EDGE_FLAG_CREASE; } @@ -2068,6 +2069,10 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, edge_feat_settings.userdata_chunk_size = sizeof(EdgeFeatReduceData); edge_feat_settings.func_reduce = feat_data_sum_reduce; + const bke::AttributeAccessor attributes = me->attributes(); + const VArray sharp_edges = attributes.lookup_or_default( + "sharp_edge", ATTR_DOMAIN_EDGE, false); + EdgeFeatData edge_feat_data = {nullptr}; edge_feat_data.ld = la_data; edge_feat_data.me = me; @@ -2077,6 +2082,7 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info, edge_feat_data.edges = me->edges(); edge_feat_data.polys = me->polys(); edge_feat_data.loops = me->loops(); + edge_feat_data.sharp_edges = sharp_edges; edge_feat_data.edge_nabr = lineart_build_edge_neighbor(me, total_edges); edge_feat_data.tri_array = la_tri_arr; edge_feat_data.v_array = la_v_arr; diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc index fd843b195ec..0d664811d12 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc @@ -192,12 +192,15 @@ void OBJMesh::ensure_mesh_normals() const void OBJMesh::calc_smooth_groups(const bool use_bitflags) { + const bool *sharp_edges = static_cast( + CustomData_get_layer_named(&export_mesh_->edata, CD_PROP_BOOL, "sharp_edge")); poly_smooth_groups_ = BKE_mesh_calc_smoothgroups(mesh_edges_.data(), mesh_edges_.size(), mesh_polys_.data(), mesh_polys_.size(), mesh_loops_.data(), mesh_loops_.size(), + sharp_edges, &tot_smooth_groups_, use_bitflags); } diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 47c0bd9acd8..3b4a52eb29a 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -46,8 +46,9 @@ enum { #ifdef DNA_DEPRECATED_ALLOW /** Deprecated loose edge status. Now stored in #Mesh::loose_edges() runtime cache. */ ME_LOOSEEDGE = (1 << 7), + /** Deprecated sharp edge status. Now stored in "sharp_edge" attribute. */ + ME_SHARP = (1 << 9), #endif - ME_SHARP = (1 << 9), /* only reason this flag remains a 'short' */ }; /** diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 0bf233767cd..e1e75d25157 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1506,6 +1506,32 @@ static void rna_MeshEdge_select_set(PointerRNA *ptr, bool value) select_edge[index] = value; } +static bool rna_MeshEdge_use_edge_sharp_get(PointerRNA *ptr) +{ + const Mesh *mesh = rna_mesh(ptr); + const bool *sharp_edge = (const bool *)CustomData_get_layer_named( + &mesh->edata, CD_PROP_BOOL, "sharp_edge"); + const int index = rna_MeshEdge_index_get(ptr); + return sharp_edge == NULL ? false : sharp_edge[index]; +} + +static void rna_MeshEdge_use_edge_sharp_set(PointerRNA *ptr, bool value) +{ + Mesh *mesh = rna_mesh(ptr); + bool *sharp_edge = (bool *)CustomData_duplicate_referenced_layer_named( + &mesh->edata, CD_PROP_BOOL, "sharp_edge", mesh->totedge); + if (!sharp_edge) { + if (!value) { + /* Skip adding layer if it doesn't exist already anyway and we're not hiding an element. */ + return; + } + sharp_edge = (bool *)CustomData_add_layer_named( + &mesh->edata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, mesh->totedge, "sharp_edge"); + } + const int index = rna_MeshEdge_index_get(ptr); + sharp_edge[index] = value; +} + static bool rna_MeshEdge_is_loose_get(PointerRNA *ptr) { const Mesh *mesh = rna_mesh(ptr); @@ -2476,8 +2502,9 @@ static void rna_def_medge(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Mesh_update_select"); prop = RNA_def_property(srna, "use_edge_sharp", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", ME_SHARP); - RNA_def_property_ui_text(prop, "Sharp", "Sharp edge for the Edge Split modifier"); + RNA_def_property_boolean_funcs( + prop, "rna_MeshEdge_use_edge_sharp_get", "rna_MeshEdge_use_edge_sharp_set"); + RNA_def_property_ui_text(prop, "Sharp", "Sharp edge for shading"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); prop = RNA_def_property(srna, "is_loose", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index b6bb6f34282..b36b14b95a4 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -91,12 +91,15 @@ static void rna_Mesh_calc_smooth_groups( Mesh *mesh, bool use_bitflags, int *r_poly_group_len, int **r_poly_group, int *r_group_total) { *r_poly_group_len = mesh->totpoly; + const bool *sharp_edges = (const bool *)CustomData_get_layer_named( + &mesh->edata, CD_PROP_BOOL, "sharp_edge"); *r_poly_group = BKE_mesh_calc_smoothgroups(BKE_mesh_edges(mesh), mesh->totedge, BKE_mesh_polys(mesh), mesh->totpoly, BKE_mesh_loops(mesh), mesh->totloop, + sharp_edges, r_group_total, use_bitflags); } diff --git a/source/blender/modifiers/intern/MOD_normal_edit.cc b/source/blender/modifiers/intern/MOD_normal_edit.cc index a3295ae24de..964e62ab79d 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.cc +++ b/source/blender/modifiers/intern/MOD_normal_edit.cc @@ -21,6 +21,7 @@ #include "DNA_object_types.h" #include "DNA_screen_types.h" +#include "BKE_attribute.hh" #include "BKE_context.h" #include "BKE_deform.h" #include "BKE_lib_id.h" @@ -224,8 +225,9 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, const bool use_invert_vgroup, const float (*vert_positions)[3], const int verts_num, - MEdge *medge, + const MEdge *medge, const int edges_num, + bool *sharp_edges, MLoop *mloop, const int loops_num, const MPoly *mpoly, @@ -341,6 +343,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, mpoly, poly_normals, polys_num, + sharp_edges, clnors); MEM_freeN(cos); @@ -363,8 +366,9 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, const bool use_invert_vgroup, const float (*positions)[3], const int verts_num, - MEdge *medge, + const MEdge *medge, const int edges_num, + bool *sharp_edges, MLoop *mloop, const int loops_num, const MPoly *mpoly, @@ -457,6 +461,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, mpoly, poly_normals, polys_num, + sharp_edges, clnors); MEM_freeN(nos); @@ -487,6 +492,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, Object *ob, Mesh *mesh) { + using namespace blender; const bool use_invert_vgroup = ((enmd->flag & MOD_NORMALEDIT_INVERT_VGROUP) != 0); const bool use_current_clnors = !((enmd->mix_mode == MOD_NORMALEDIT_MIX_COPY) && (enmd->mix_factor == 1.0f) && (enmd->defgrp_name[0] == '\0') && @@ -529,7 +535,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, const int loops_num = result->totloop; const int polys_num = result->totpoly; const float(*positions)[3] = BKE_mesh_vert_positions(result); - MEdge *edges = BKE_mesh_edges_for_write(result); + const MEdge *edges = BKE_mesh_edges(result); const MPoly *polys = BKE_mesh_polys(result); MLoop *loops = BKE_mesh_loops_for_write(result); @@ -543,6 +549,10 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(result); const float(*poly_normals)[3] = BKE_mesh_poly_normals_ensure(result); + bke::MutableAttributeAccessor attributes = result->attributes_for_write(); + bke::SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_span( + "sharp_edge", ATTR_DOMAIN_EDGE); + short(*clnors)[2] = static_cast(CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL)); if (use_current_clnors) { clnors = static_cast( @@ -563,6 +573,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, polys_num, true, result->smoothresh, + sharp_edges.span.data(), nullptr, nullptr, clnors); @@ -593,6 +604,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, verts_num, edges, edges_num, + sharp_edges.span.data(), loops, loops_num, polys, @@ -616,6 +628,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, verts_num, edges, edges_num, + sharp_edges.span.data(), loops, loops_num, polys, @@ -626,6 +639,8 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, result->runtime->is_original_bmesh = false; + sharp_edges.finish(); + return result; } diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index 6351adcbe94..41217955f85 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -2204,7 +2204,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } medge[edge_index].v1 = last_g->new_vert; medge[edge_index].v2 = g->new_vert; - medge[edge_index].flag = ME_EDGEDRAW | ((last_flag | flag) & (ME_SEAM | ME_SHARP)); + medge[edge_index].flag = ME_EDGEDRAW | ((last_flag | flag) & ME_SEAM); if (result_edge_crease) { result_edge_crease[edge_index] = max_ff(mv_crease, min_ff(last_max_crease, max_crease)); @@ -2237,8 +2237,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, last_g->open_face_edge = edge_index; medge[edge_index].v1 = last_g->new_vert; medge[edge_index].v2 = first_g->new_vert; - medge[edge_index].flag = ME_EDGEDRAW | - ((last_flag | first_flag) & (ME_SEAM | ME_SHARP)); + medge[edge_index].flag = ME_EDGEDRAW | ((last_flag | first_flag) & ME_SEAM); if (result_edge_crease) { result_edge_crease[edge_index] = max_ff(mv_crease, min_ff(last_max_crease, first_max_crease)); diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.cc b/source/blender/modifiers/intern/MOD_weighted_normal.cc index c5f20954b03..416ce19a0c5 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.cc +++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc @@ -19,6 +19,7 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "BKE_attribute.hh" #include "BKE_context.h" #include "BKE_deform.h" #include "BKE_lib_id.h" @@ -74,7 +75,8 @@ struct WeightedNormalData { const float (*vert_positions)[3]; const float (*vert_normals)[3]; - MEdge *medge; + const MEdge *medge; + bool *sharp_edges; const MLoop *mloop; blender::Span loop_to_poly; @@ -188,7 +190,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, const int polys_num = wn_data->polys_num; const float(*positions)[3] = wn_data->vert_positions; - MEdge *medge = wn_data->medge; + const MEdge *medge = wn_data->medge; const MLoop *mloop = wn_data->mloop; short(*clnors)[2] = wn_data->clnors; @@ -236,6 +238,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, polys_num, true, split_angle, + wn_data->sharp_edges, loop_to_poly.data(), &lnors_spacearr, has_clnors ? clnors : nullptr); @@ -366,6 +369,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, mpoly, poly_normals, polys_num, + wn_data->sharp_edges, clnors); } else { @@ -397,6 +401,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, mpoly, poly_normals, polys_num, + wn_data->sharp_edges, clnors); MEM_freeN(vert_normals); @@ -418,6 +423,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, polys_num, true, split_angle, + wn_data->sharp_edges, loop_to_poly.data(), nullptr, has_clnors ? clnors : nullptr); @@ -440,6 +446,7 @@ static void apply_weights_vertex_normal(WeightedNormalModifierData *wnmd, mpoly, poly_normals, polys_num, + wn_data->sharp_edges, clnors); } } @@ -584,7 +591,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * const int loops_num = result->totloop; const int polys_num = result->totpoly; const float(*positions)[3] = BKE_mesh_vert_positions(result); - MEdge *medge = BKE_mesh_edges_for_write(result); + const MEdge *medge = BKE_mesh_edges(result); const MPoly *mpoly = BKE_mesh_polys(result); const MLoop *mloop = BKE_mesh_loops(result); @@ -624,6 +631,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * const Array loop_to_poly_map = bke::mesh_topology::build_loop_to_poly_map(result->polys(), result->totloop); + bke::MutableAttributeAccessor attributes = result->attributes_for_write(); + bke::SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_span( + "sharp_edge", ATTR_DOMAIN_EDGE); + WeightedNormalData wn_data{}; wn_data.verts_num = verts_num; wn_data.edges_num = edges_num; @@ -633,6 +644,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * wn_data.vert_positions = positions; wn_data.vert_normals = BKE_mesh_vertex_normals_ensure(result); wn_data.medge = medge; + wn_data.sharp_edges = sharp_edges.span.data(); wn_data.mloop = mloop; wn_data.loop_to_poly = loop_to_poly_map; @@ -669,6 +681,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * result->runtime->is_original_bmesh = false; + sharp_edges.finish(); + return result; } From 50d6af1e0e8f98a2dd0ba6245026c18da7b3cedb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 13:03:44 +1100 Subject: [PATCH 0577/1522] Fix invalid string comparison Error from recent addition: 250eda36b8f91a2f89b202d5eb79108260e1b1e3. Compare the enum value instead. --- source/blender/makesrna/intern/rna_gpencil_modifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index 46d8b7f8f3c..bfb13f26136 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -959,7 +959,7 @@ const EnumPropertyItem *gpencil_build_time_mode_filter(bContext *UNUSED(C), for (const EnumPropertyItem *item = gpencil_build_time_mode_items; item->identifier != NULL; item++) { - if (is_concurrent && item->identifier == "DRAWSPEED") { + if (is_concurrent && (item->value == GP_BUILD_TIMEMODE_DRAWSPEED)) { continue; } RNA_enum_item_add(&item_list, &totitem, item); From bd9602036a182df778228a838c67feaf3e9299c4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 13:03:46 +1100 Subject: [PATCH 0578/1522] Fix pose-slide failing with array custom properties Pose slide would attempt to use non-array functions to get/set RNA array properties. Asserting in debug mode. --- source/blender/editors/armature/pose_slide.c | 65 +++++++++++++++++--- 1 file changed, 58 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c index e2610628f97..86675a1bef2 100644 --- a/source/blender/editors/armature/pose_slide.c +++ b/source/blender/editors/armature/pose_slide.c @@ -521,24 +521,75 @@ static void pose_slide_apply_props(tPoseSlideOp *pso, switch (RNA_property_type(prop)) { /* Continuous values that can be smoothly interpolated. */ case PROP_FLOAT: { - float tval = RNA_property_float_get(&ptr, prop); + const bool is_array = RNA_property_array_check(prop); + float tval; + if (is_array) { + if (UNLIKELY((uint)fcu->array_index >= RNA_property_array_length(&ptr, prop))) { + break; /* Out of range, skip. */ + } + tval = RNA_property_float_get_index(&ptr, prop, fcu->array_index); + } + else { + tval = RNA_property_float_get(&ptr, prop); + } + pose_slide_apply_val(pso, fcu, pfl->ob, &tval); - RNA_property_float_set(&ptr, prop, tval); + + if (is_array) { + RNA_property_float_set_index(&ptr, prop, fcu->array_index, tval); + } + else { + RNA_property_float_set(&ptr, prop, tval); + } break; } case PROP_INT: { - float tval = (float)RNA_property_int_get(&ptr, prop); + const bool is_array = RNA_property_array_check(prop); + float tval; + if (is_array) { + if (UNLIKELY((uint)fcu->array_index >= RNA_property_array_length(&ptr, prop))) { + break; /* Out of range, skip. */ + } + tval = RNA_property_int_get_index(&ptr, prop, fcu->array_index); + } + else { + tval = RNA_property_int_get(&ptr, prop); + } + pose_slide_apply_val(pso, fcu, pfl->ob, &tval); - RNA_property_int_set(&ptr, prop, (int)tval); + + if (is_array) { + RNA_property_int_set_index(&ptr, prop, fcu->array_index, tval); + } + else { + RNA_property_int_set(&ptr, prop, tval); + } break; } /* Values which can only take discrete values. */ case PROP_BOOLEAN: { - float tval = (float)RNA_property_boolean_get(&ptr, prop); + const bool is_array = RNA_property_array_check(prop); + float tval; + if (is_array) { + if (UNLIKELY((uint)fcu->array_index >= RNA_property_array_length(&ptr, prop))) { + break; /* Out of range, skip. */ + } + tval = RNA_property_boolean_get_index(&ptr, prop, fcu->array_index); + } + else { + tval = RNA_property_boolean_get(&ptr, prop); + } + pose_slide_apply_val(pso, fcu, pfl->ob, &tval); - RNA_property_boolean_set( - &ptr, prop, (int)tval); /* XXX: do we need threshold clamping here? */ + + /* XXX: do we need threshold clamping here? */ + if (is_array) { + RNA_property_boolean_set_index(&ptr, prop, fcu->array_index, tval); + } + else { + RNA_property_boolean_set(&ptr, prop, tval); + } break; } case PROP_ENUM: { From 9f283bee7ecfedabc7a6b46fb9f2cece6b3e31ec Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 13:03:48 +1100 Subject: [PATCH 0579/1522] BLI_string_ref: avoid passing null to strncmp (quiet ASAN warning) The existing logic to avoid passing null only worked when both strings were null. --- source/blender/blenlib/BLI_string_ref.hh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/blender/blenlib/BLI_string_ref.hh b/source/blender/blenlib/BLI_string_ref.hh index 14dee54d730..6ad4d6fd3af 100644 --- a/source/blender/blenlib/BLI_string_ref.hh +++ b/source/blender/blenlib/BLI_string_ref.hh @@ -608,9 +608,14 @@ constexpr bool operator==(StringRef a, StringRef b) return false; } if (a.data() == b.data()) { - /* This also avoids passing null to the call below, which would results in an ASAN warning. */ + /* This also avoids passing null to the call below when both are null, + * which would results in an ASAN warning. */ return true; } + if (!a.data() || !b.data()) { + /* Account for a single value being null, resulting in an ASAN warning. */ + return false; + } return STREQLEN(a.data(), b.data(), size_t(a.size())); } From 12a26b8fe392d8801794e9873f47bcecdb624328 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 13:03:49 +1100 Subject: [PATCH 0580/1522] Cleanup: format --- release/scripts/startup/bl_ui/space_view3d.py | 7 +++---- source/blender/editors/space_node/add_menu_assets.cc | 3 ++- .../intern/blender_interface/BlenderStrokeRenderer.cpp | 2 +- source/blender/io/usd/intern/usd_writer_mesh.cc | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 0af3325ae2c..bb11ed80ac2 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2702,10 +2702,9 @@ class VIEW3D_MT_object_context_menu(Menu): if obj.type == 'GPENCIL': layout.operator_menu_enum("gpencil.convert", "type", text="Convert To") - if ( - obj.type in {'MESH', 'CURVE', 'CURVES', 'SURFACE', 'GPENCIL', 'LATTICE', 'ARMATURE', 'META', 'FONT', 'POINTCLOUD'} or - (obj.type == 'EMPTY' and obj.instance_collection is not None) - ): + if (obj.type in { + 'MESH', 'CURVE', 'CURVES', 'SURFACE', 'GPENCIL', 'LATTICE', 'ARMATURE', 'META', 'FONT', 'POINTCLOUD', + } or (obj.type == 'EMPTY' and obj.instance_collection is not None)): layout.operator_context = 'INVOKE_REGION_WIN' layout.operator_menu_enum("object.origin_set", text="Set Origin", property="type") layout.operator_context = 'INVOKE_DEFAULT' diff --git a/source/blender/editors/space_node/add_menu_assets.cc b/source/blender/editors/space_node/add_menu_assets.cc index fc250b63ffe..912493c3e7e 100644 --- a/source/blender/editors/space_node/add_menu_assets.cc +++ b/source/blender/editors/space_node/add_menu_assets.cc @@ -87,7 +87,8 @@ static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree *node ED_assetlist_storage_fetch(&all_library_ref, &C); ED_assetlist_ensure_previews_job(&all_library_ref, &C); - asset_system::AssetLibrary *all_library = ED_assetlist_library_get_once_available(all_library_ref); + asset_system::AssetLibrary *all_library = ED_assetlist_library_get_once_available( + all_library_ref); if (!all_library) { return {}; } diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp index a04e9584005..40f49b458f4 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp @@ -44,8 +44,8 @@ #include "BLI_ghash.h" #include "BLI_listbase.h" #include "BLI_math_color.h" -#include "BLI_math_vector_types.hh" #include "BLI_math_vector.h" +#include "BLI_math_vector_types.hh" #include "BLI_utildefines.h" #include "DEG_depsgraph.h" diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index 237e1414eaf..45fa0d48d80 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -9,8 +9,8 @@ #include #include "BLI_assert.h" -#include "BLI_math_vector_types.hh" #include "BLI_math_vector.h" +#include "BLI_math_vector_types.hh" #include "BKE_attribute.h" #include "BKE_attribute.hh" From 494c3ba063d89781b085291ccebb5741bdb90ab7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 13:03:51 +1100 Subject: [PATCH 0581/1522] Cleanup: quiet warning mixing enum/int & replace NULL with nullptr --- source/blender/editors/space_file/filesel.cc | 133 +++++++++--------- .../makesrna/intern/rna_gpencil_modifier.c | 2 +- 2 files changed, 68 insertions(+), 67 deletions(-) diff --git a/source/blender/editors/space_file/filesel.cc b/source/blender/editors/space_file/filesel.cc index 32181a9f5f6..446e5434edf 100644 --- a/source/blender/editors/space_file/filesel.cc +++ b/source/blender/editors/space_file/filesel.cc @@ -94,7 +94,7 @@ static void fileselect_initialize_params_common(SpaceFile *sfile, FileSelectPara static void fileselect_ensure_updated_asset_params(SpaceFile *sfile) { BLI_assert(sfile->browse_mode == FILE_BROWSE_MODE_ASSETS); - BLI_assert(sfile->op == NULL); + BLI_assert(sfile->op == nullptr); FileAssetSelectParams *asset_params = sfile->asset_params; @@ -158,11 +158,11 @@ static FileSelectParams *fileselect_ensure_updated_file_params(SpaceFile *sfile) /* set the parameters from the operator, if it exists */ if (op) { PropertyRNA *prop; - const bool is_files = (RNA_struct_find_property(op->ptr, "files") != NULL); - const bool is_filepath = (RNA_struct_find_property(op->ptr, "filepath") != NULL); - const bool is_filename = (RNA_struct_find_property(op->ptr, "filename") != NULL); - const bool is_directory = (RNA_struct_find_property(op->ptr, "directory") != NULL); - const bool is_relative_path = (RNA_struct_find_property(op->ptr, "relative_path") != NULL); + const bool is_files = (RNA_struct_find_property(op->ptr, "files") != nullptr); + const bool is_filepath = (RNA_struct_find_property(op->ptr, "filepath") != nullptr); + const bool is_filename = (RNA_struct_find_property(op->ptr, "filename") != nullptr); + const bool is_directory = (RNA_struct_find_property(op->ptr, "directory") != nullptr); + const bool is_relative_path = (RNA_struct_find_property(op->ptr, "relative_path") != nullptr); BLI_strncpy_utf8( params->title, WM_operatortype_name(op->type, op->ptr), sizeof(params->title)); @@ -208,68 +208,69 @@ static FileSelectParams *fileselect_ensure_updated_file_params(SpaceFile *sfile) params->flag |= FILE_DIRSEL_ONLY; } if ((prop = RNA_struct_find_property(op->ptr, "check_existing"))) { - params->flag |= RNA_property_boolean_get(op->ptr, prop) ? FILE_CHECK_EXISTING : 0; + params->flag |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_CHECK_EXISTING) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "hide_props_region"))) { - params->flag |= RNA_property_boolean_get(op->ptr, prop) ? FILE_HIDE_TOOL_PROPS : 0; + params->flag |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_HIDE_TOOL_PROPS) : 0; } params->filter = 0; if ((prop = RNA_struct_find_property(op->ptr, "filter_blender"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDER : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_BLENDER) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_blenlib"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDERLIB : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_BLENDERLIB) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_backup"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDER_BACKUP : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_BLENDER_BACKUP) : + 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_image"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_IMAGE : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_IMAGE) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_movie"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_MOVIE : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_MOVIE) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_python"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_PYSCRIPT : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_PYSCRIPT) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_font"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_FTFONT : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_FTFONT) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_sound"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_SOUND : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_SOUND) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_text"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_TEXT : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_TEXT) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_archive"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_ARCHIVE : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_ARCHIVE) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_folder"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_FOLDER : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_FOLDER) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_btx"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BTX : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_BTX) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_collada"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_COLLADA : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_COLLADA) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_alembic"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_ALEMBIC : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_ALEMBIC) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_usd"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_USD : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_USD) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_obj"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_OBJECT_IO : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_OBJECT_IO) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_volume"))) { - params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_VOLUME : 0; + params->filter |= RNA_property_boolean_get(op->ptr, prop) ? int(FILE_TYPE_VOLUME) : 0; } if ((prop = RNA_struct_find_property(op->ptr, "filter_glob"))) { /* Protection against Python scripts not setting proper size limit. */ char *tmp = RNA_property_string_get_alloc( - op->ptr, prop, params->filter_glob, sizeof(params->filter_glob), NULL); + op->ptr, prop, params->filter_glob, sizeof(params->filter_glob), nullptr); if (tmp != params->filter_glob) { BLI_strncpy(params->filter_glob, tmp, sizeof(params->filter_glob)); MEM_freeN(tmp); @@ -366,14 +367,14 @@ FileSelectParams *ED_fileselect_ensure_active_params(SpaceFile *sfile) } BLI_assert_msg(0, "Invalid browse mode set in file space."); - return NULL; + return nullptr; } FileSelectParams *ED_fileselect_get_active_params(const SpaceFile *sfile) { if (!sfile) { /* Sometimes called in poll before space type was checked. */ - return NULL; + return nullptr; } switch ((eFileBrowse_Mode)sfile->browse_mode) { @@ -384,23 +385,23 @@ FileSelectParams *ED_fileselect_get_active_params(const SpaceFile *sfile) } BLI_assert_msg(0, "Invalid browse mode set in file space."); - return NULL; + return nullptr; } FileSelectParams *ED_fileselect_get_file_params(const SpaceFile *sfile) { - return (sfile->browse_mode == FILE_BROWSE_MODE_FILES) ? sfile->params : NULL; + return (sfile->browse_mode == FILE_BROWSE_MODE_FILES) ? sfile->params : nullptr; } FileAssetSelectParams *ED_fileselect_get_asset_params(const SpaceFile *sfile) { - return (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS) ? sfile->asset_params : NULL; + return (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS) ? sfile->asset_params : nullptr; } bool ED_fileselect_is_local_asset_library(const SpaceFile *sfile) { const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile); - if (asset_params == NULL) { + if (asset_params == nullptr) { return false; } return asset_params->asset_library_ref.type == ASSET_LIBRARY_LOCAL; @@ -410,7 +411,7 @@ static void fileselect_refresh_asset_params(FileAssetSelectParams *asset_params) { AssetLibraryReference *library = &asset_params->asset_library_ref; FileSelectParams *base_params = &asset_params->base_params; - bUserAssetLibrary *user_library = NULL; + bUserAssetLibrary *user_library = nullptr; /* Ensure valid repository, or fall-back to local one. */ if (library->type == ASSET_LIBRARY_CUSTOM) { @@ -461,7 +462,7 @@ bool ED_fileselect_is_asset_browser(const SpaceFile *sfile) struct AssetLibrary *ED_fileselect_active_asset_library_get(const SpaceFile *sfile) { if (!ED_fileselect_is_asset_browser(sfile) || !sfile->files) { - return NULL; + return nullptr; } return filelist_asset_library(sfile->files); @@ -470,13 +471,13 @@ struct AssetLibrary *ED_fileselect_active_asset_library_get(const SpaceFile *sfi struct ID *ED_fileselect_active_asset_get(const SpaceFile *sfile) { if (!ED_fileselect_is_asset_browser(sfile)) { - return NULL; + return nullptr; } FileSelectParams *params = ED_fileselect_get_active_params(sfile); const FileDirEntry *file = filelist_file(sfile->files, params->active_file); - if (file == NULL) { - return NULL; + if (file == nullptr) { + return nullptr; } return filelist_file_get_id(file); @@ -491,7 +492,7 @@ void ED_fileselect_activate_asset_catalog(const SpaceFile *sfile, const bUUID ca FileAssetSelectParams *params = ED_fileselect_get_asset_params(sfile); params->asset_catalog_visibility = FILE_SHOW_ASSETS_FROM_CATALOG; params->catalog_id = catalog_id; - WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, NULL); + WM_main_add_notifier(NC_SPACE | ND_SPACE_ASSET_PARAMS, nullptr); } static void on_reload_activate_by_id(SpaceFile *sfile, onReloadFnData custom_data) @@ -522,15 +523,15 @@ void ED_fileselect_activate_by_id(SpaceFile *sfile, ID *asset_id, const bool def const int file_index = filelist_file_find_id(files, asset_id); const FileDirEntry *file = filelist_file_ex(files, file_index, true); - if (file == NULL) { + if (file == nullptr) { return; } params->active_file = file_index; filelist_entry_select_set(files, file, FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL); - WM_main_add_notifier(NC_ASSET | NA_ACTIVATED, NULL); - WM_main_add_notifier(NC_ASSET | NA_SELECTED, NULL); + WM_main_add_notifier(NC_ASSET | NA_ACTIVATED, nullptr); + WM_main_add_notifier(NC_ASSET | NA_SELECTED, nullptr); } static void on_reload_select_by_relpath(SpaceFile *sfile, onReloadFnData custom_data) @@ -545,7 +546,7 @@ void ED_fileselect_activate_by_relpath(SpaceFile *sfile, const char *relative_pa * there is a fair chance that the to-be-activated file at relative_path will only be present * after these operations have completed. Defer activation until then. */ struct FileList *files = sfile->files; - if (files == NULL || filelist_pending(files) || filelist_needs_force_reset(files)) { + if (files == nullptr || filelist_pending(files) || filelist_needs_force_reset(files)) { /* Casting away the constness of `relative_path` is safe here, because eventually it just ends * up in another call to this function, and then it's a const char* again. */ file_on_reload_callback_register(sfile, on_reload_select_by_relpath, (char *)relative_path); @@ -563,13 +564,13 @@ void ED_fileselect_activate_by_relpath(SpaceFile *sfile, const char *relative_pa filelist_entry_select_set(files, file, FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL); } } - WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); + WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_PARAMS, nullptr); } void ED_fileselect_deselect_all(SpaceFile *sfile) { file_select_deselect_all(sfile, FILE_SEL_SELECTED); - WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); + WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_PARAMS, nullptr); } /* The subset of FileSelectParams.flag items we store into preferences. Note that FILE_SORT_ALPHA @@ -590,7 +591,7 @@ void ED_fileselect_window_params_get(const wmWindow *win, int win_size[2], bool static bool file_select_use_default_display_type(const SpaceFile *sfile) { PropertyRNA *prop; - return (sfile->op == NULL) || + return (sfile->op == nullptr) || !(prop = RNA_struct_find_property(sfile->op->ptr, "display_type")) || (RNA_property_enum_get(sfile->op->ptr, prop) == FILE_DEFAULTDISPLAY); } @@ -598,7 +599,7 @@ static bool file_select_use_default_display_type(const SpaceFile *sfile) static bool file_select_use_default_sort_type(const SpaceFile *sfile) { PropertyRNA *prop; - return (sfile->op == NULL) || + return (sfile->op == nullptr) || !(prop = RNA_struct_find_property(sfile->op->ptr, "sort_method")) || (RNA_property_enum_get(sfile->op->ptr, prop) == FILE_SORT_DEFAULT); } @@ -724,7 +725,7 @@ FileSelection ED_fileselect_layout_offset_rect(FileLayout *layout, const rcti *r FileSelection sel; sel.first = sel.last = -1; - if (layout == NULL) { + if (layout == nullptr) { return sel; } @@ -772,7 +773,7 @@ int ED_fileselect_layout_offset(FileLayout *layout, int x, int y) int offsetx, offsety; int active_file; - if (layout == NULL) { + if (layout == nullptr) { return -1; } @@ -977,12 +978,12 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *region) FileSelectParams *params = ED_fileselect_get_active_params(sfile); /* Request a slightly more compact layout for asset browsing. */ const bool compact = ED_fileselect_is_asset_browser(sfile); - FileLayout *layout = NULL; + FileLayout *layout = nullptr; View2D *v2d = ®ion->v2d; int numfiles; int textheight; - if (sfile->layout == NULL) { + if (sfile->layout == nullptr) { sfile->layout = static_cast( MEM_callocN(sizeof(struct FileLayout), "file_layout")); sfile->layout->dirty = true; @@ -1176,7 +1177,7 @@ int autocomplete_directory(struct bContext *C, char *str, void * /*arg_v*/) if (dir) { AutoComplete *autocpl = UI_autocomplete_begin(str, FILE_MAX); - while ((de = readdir(dir)) != NULL) { + while ((de = readdir(dir)) != nullptr) { if (FILENAME_IS_CURRPAR(de->d_name)) { /* pass */ } @@ -1227,7 +1228,7 @@ int autocomplete_file(struct bContext *C, char *str, void * /*arg_v*/) void ED_fileselect_clear(wmWindowManager *wm, SpaceFile *sfile) { - /* only NULL in rare cases - T29734. */ + /* Only null in rare cases, see: T29734. */ if (sfile->files) { filelist_readjob_stop(sfile->files, wm); filelist_freelib(sfile->files); @@ -1236,7 +1237,7 @@ void ED_fileselect_clear(wmWindowManager *wm, SpaceFile *sfile) FileSelectParams *params = ED_fileselect_get_active_params(sfile); params->highlight_file = -1; - WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_LIST, NULL); + WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_LIST, nullptr); } void ED_fileselect_exit(wmWindowManager *wm, SpaceFile *sfile) @@ -1247,7 +1248,7 @@ void ED_fileselect_exit(wmWindowManager *wm, SpaceFile *sfile) if (sfile->op) { wmWindow *temp_win = (wm->winactive && WM_window_is_temp_screen(wm->winactive)) ? wm->winactive : - NULL; + nullptr; if (temp_win) { int win_size[2]; bool is_maximized; @@ -1256,11 +1257,11 @@ void ED_fileselect_exit(wmWindowManager *wm, SpaceFile *sfile) ED_fileselect_params_to_userdef(sfile, win_size, is_maximized); } else { - ED_fileselect_params_to_userdef(sfile, NULL, false); + ED_fileselect_params_to_userdef(sfile, nullptr, false); } WM_event_fileselect_event(wm, sfile->op, EVT_FILESELECT_EXTERNAL_CANCEL); - sfile->op = NULL; + sfile->op = nullptr; } folder_history_list_free(sfile); @@ -1269,14 +1270,14 @@ void ED_fileselect_exit(wmWindowManager *wm, SpaceFile *sfile) ED_fileselect_clear(wm, sfile); filelist_free(sfile->files); MEM_freeN(sfile->files); - sfile->files = NULL; + sfile->files = nullptr; } } void file_params_smoothscroll_timer_clear(wmWindowManager *wm, wmWindow *win, SpaceFile *sfile) { WM_event_remove_timer(wm, win, sfile->smoothscroll_timer); - sfile->smoothscroll_timer = NULL; + sfile->smoothscroll_timer = nullptr; } void file_params_invoke_rename_postscroll(wmWindowManager *wm, wmWindow *win, SpaceFile *sfile) @@ -1285,7 +1286,7 @@ void file_params_invoke_rename_postscroll(wmWindowManager *wm, wmWindow *win, Sp params->rename_flag = FILE_PARAMS_RENAME_POSTSCROLL_PENDING; - if (sfile->smoothscroll_timer != NULL) { + if (sfile->smoothscroll_timer != nullptr) { file_params_smoothscroll_timer_clear(wm, win, sfile); } sfile->smoothscroll_timer = WM_event_add_timer(wm, win, TIMER1, 1.0 / 1000.0); @@ -1312,15 +1313,15 @@ void file_params_rename_end(wmWindowManager *wm, void file_params_renamefile_clear(FileSelectParams *params) { params->renamefile[0] = '\0'; - params->rename_id = NULL; + params->rename_id = nullptr; params->rename_flag = 0; } static int file_params_find_renamed(const FileSelectParams *params, struct FileList *filelist) { /* Find the file either through the local ID/asset it represents or its relative path. */ - return (params->rename_id != NULL) ? filelist_file_find_id(filelist, params->rename_id) : - filelist_file_find_path(filelist, params->renamefile); + return (params->rename_id != nullptr) ? filelist_file_find_id(filelist, params->rename_id) : + filelist_file_find_path(filelist, params->renamefile); } void file_params_renamefile_activate(SpaceFile *sfile, FileSelectParams *params) @@ -1332,12 +1333,12 @@ void file_params_renamefile_activate(SpaceFile *sfile, FileSelectParams *params) return; } - BLI_assert(params->renamefile[0] != '\0' || params->rename_id != NULL); + BLI_assert(params->renamefile[0] != '\0' || params->rename_id != nullptr); int idx = file_params_find_renamed(params, sfile->files); if (idx >= 0) { FileDirEntry *file = filelist_file(sfile->files, idx); - BLI_assert(file != NULL); + BLI_assert(file != nullptr); params->active_file = idx; filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_SELECTED, CHECK_ALL); @@ -1380,7 +1381,7 @@ ScrArea *ED_fileselect_handler_area_find(const wmWindow *win, const wmOperator * } } - return NULL; + return nullptr; } ScrArea *ED_fileselect_handler_area_find_any_with_op(const wmWindow *win) @@ -1398,7 +1399,7 @@ ScrArea *ED_fileselect_handler_area_find_any_with_op(const wmWindow *win) } } - return NULL; + return nullptr; } void ED_fileselect_ensure_default_filepath(struct bContext *C, diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index bfb13f26136..58ecec54013 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -946,7 +946,7 @@ static void rna_EnvelopeGpencilModifier_material_set(PointerRNA *ptr, const EnumPropertyItem *gpencil_build_time_mode_filter(bContext *UNUSED(C), PointerRNA *ptr, - PropertyRNA *prop, + PropertyRNA *UNUSED(prop), bool *r_free) { From 8367f2bffc58a8f591ed2e6d67f6dd625dc5041c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 13:03:53 +1100 Subject: [PATCH 0582/1522] Cleanup: function style casts for C++ --- .../blender/blenkernel/intern/customdata.cc | 2 +- source/blender/blenkernel/intern/modifier.cc | 2 +- source/blender/blenkernel/intern/particle.cc | 4 +-- source/blender/blenlib/intern/math_boolean.cc | 4 +-- .../extract_mesh_vbo_edituv_stretch_angle.cc | 2 +- .../blender/editors/mesh/editmesh_select.cc | 12 +++---- source/blender/editors/mesh/editmesh_undo.cc | 4 +-- .../blender/editors/render/render_shading.cc | 8 ++--- source/blender/editors/space_file/filesel.cc | 34 +++++++++---------- source/blender/render/intern/multires_bake.cc | 6 ++-- 10 files changed, 39 insertions(+), 39 deletions(-) diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 433c4355d97..1d970d35148 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -5249,7 +5249,7 @@ void CustomData_debug_info_from_layers(const CustomData *data, const char *inden const char *name = CustomData_layertype_name(type); const int size = CustomData_sizeof(type); const void *pt = CustomData_get_layer(data, type); - const int pt_size = pt ? (int)(MEM_allocN_len(pt) / size) : 0; + const int pt_size = pt ? int(MEM_allocN_len(pt) / size) : 0; const char *structname; int structnum; CustomData_file_write_info(type, &structname, &structnum); diff --git a/source/blender/blenkernel/intern/modifier.cc b/source/blender/blenkernel/intern/modifier.cc index 50c9c13a9ac..508c1fe2331 100644 --- a/source/blender/blenkernel/intern/modifier.cc +++ b/source/blender/blenkernel/intern/modifier.cc @@ -349,7 +349,7 @@ void BKE_modifier_copydata_generic(const ModifierData *md_src, const size_t data_size = sizeof(ModifierData); const char *md_src_data = ((const char *)md_src) + data_size; char *md_dst_data = ((char *)md_dst) + data_size; - BLI_assert(data_size <= (size_t)mti->structSize); + BLI_assert(data_size <= size_t(mti->structSize)); memcpy(md_dst_data, md_src_data, size_t(mti->structSize) - data_size); /* Runtime fields are never to be preserved. */ diff --git a/source/blender/blenkernel/intern/particle.cc b/source/blender/blenkernel/intern/particle.cc index 5e3b393ce6b..484cb343a97 100644 --- a/source/blender/blenkernel/intern/particle.cc +++ b/source/blender/blenkernel/intern/particle.cc @@ -521,8 +521,8 @@ void BKE_particle_init_rng(void) RNG *rng = BLI_rng_new_srandom(5831); /* arbitrary */ for (int i = 0; i < PSYS_FRAND_COUNT; i++) { PSYS_FRAND_BASE[i] = BLI_rng_get_float(rng); - PSYS_FRAND_SEED_OFFSET[i] = (uint)BLI_rng_get_int(rng); - PSYS_FRAND_SEED_MULTIPLIER[i] = (uint)BLI_rng_get_int(rng); + PSYS_FRAND_SEED_OFFSET[i] = uint(BLI_rng_get_int(rng)); + PSYS_FRAND_SEED_MULTIPLIER[i] = uint(BLI_rng_get_int(rng)); } BLI_rng_free(rng); } diff --git a/source/blender/blenlib/intern/math_boolean.cc b/source/blender/blenlib/intern/math_boolean.cc index 977b4ca5365..689c23ce092 100644 --- a/source/blender/blenlib/intern/math_boolean.cc +++ b/source/blender/blenlib/intern/math_boolean.cc @@ -201,7 +201,7 @@ static RobustInitCaller init_caller; y = bvirt - b #define Fast_Two_Diff(a, b, x, y) \ - x = (double)(a - b); \ + x = double(a - b); \ Fast_Two_Diff_Tail(a, b, x, y) #define Two_Sum_Tail(a, b, x, y) \ @@ -253,7 +253,7 @@ static RobustInitCaller init_caller; y = (alo * blo) - err3 #define Two_Product_2Presplit(a, ahi, alo, b, bhi, blo, x, y) \ - x = (double)(a * b); \ + x = double(a * b); \ err1 = x - (ahi * bhi); \ err2 = err1 - (alo * bhi); \ err3 = err2 - (ahi * blo); \ diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc index a7b0331769c..b295a314883 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edituv_stretch_angle.cc @@ -70,7 +70,7 @@ static void edituv_get_edituv_stretch_angle(float auv[2][2], #if 0 /* here for reference, this is done in shader now. */ float uvang = angle_normalized_v2v2(auv0, auv1); float ang = angle_normalized_v3v3(av0, av1); - float stretch = fabsf(uvang - ang) / (float)M_PI; + float stretch = fabsf(uvang - ang) / float(M_PI); return 1.0f - pow2f(1.0f - stretch); #endif } diff --git a/source/blender/editors/mesh/editmesh_select.cc b/source/blender/editors/mesh/editmesh_select.cc index 6955db63fe8..b911da376b4 100644 --- a/source/blender/editors/mesh/editmesh_select.cc +++ b/source/blender/editors/mesh/editmesh_select.cc @@ -266,8 +266,8 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc, uint base_index = 0; if (!XRAY_FLAG_ENABLED(vc->v3d)) { - uint dist_px_manhattan_test = (uint)ED_view3d_backbuf_sample_size_clamp(vc->region, - *dist_px_manhattan_p); + uint dist_px_manhattan_test = uint( + ED_view3d_backbuf_sample_size_clamp(vc->region, *dist_px_manhattan_p)); uint index; BMVert *eve; @@ -492,8 +492,8 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc, uint base_index = 0; if (!XRAY_FLAG_ENABLED(vc->v3d)) { - uint dist_px_manhattan_test = (uint)ED_view3d_backbuf_sample_size_clamp(vc->region, - *dist_px_manhattan_p); + uint dist_px_manhattan_test = uint( + ED_view3d_backbuf_sample_size_clamp(vc->region, *dist_px_manhattan_p)); uint index; BMEdge *eed; @@ -713,8 +713,8 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc, { uint dist_px_manhattan_test = 0; if (*dist_px_manhattan_p != 0.0f && (use_zbuf_single_px == false)) { - dist_px_manhattan_test = (uint)ED_view3d_backbuf_sample_size_clamp(vc->region, - *dist_px_manhattan_p); + dist_px_manhattan_test = uint( + ED_view3d_backbuf_sample_size_clamp(vc->region, *dist_px_manhattan_p)); } DRW_select_buffer_context_create(bases, bases_len, SCE_SELECT_FACE); diff --git a/source/blender/editors/mesh/editmesh_undo.cc b/source/blender/editors/mesh/editmesh_undo.cc index 5c837e61a79..565ce28a3c1 100644 --- a/source/blender/editors/mesh/editmesh_undo.cc +++ b/source/blender/editors/mesh/editmesh_undo.cc @@ -398,13 +398,13 @@ static void um_arraystore_compact_with_info(UndoMesh *um, const UndoMesh *um_ref &um_arraystore.bs_stride, &size_expanded, &size_compacted); const double percent_total = size_expanded ? - (((double)size_compacted / (double)size_expanded) * 100.0) : + ((double(size_compacted) / double(size_expanded)) * 100.0) : -1.0; size_t size_expanded_step = size_expanded - size_expanded_prev; size_t size_compacted_step = size_compacted - size_compacted_prev; const double percent_step = size_expanded_step ? - (((double)size_compacted_step / (double)size_expanded_step) * + ((double(size_compacted_step) / double(size_expanded_step)) * 100.0) : -1.0; diff --git a/source/blender/editors/render/render_shading.cc b/source/blender/editors/render/render_shading.cc index e5c2b9702e5..c62483daf6b 100644 --- a/source/blender/editors/render/render_shading.cc +++ b/source/blender/editors/render/render_shading.cc @@ -2603,10 +2603,10 @@ static void copy_mtex_copybuf(ID *id) switch (GS(id->name)) { case ID_PA: - mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]); + mtex = &(((ParticleSettings *)id)->mtex[int(((ParticleSettings *)id)->texact)]); break; case ID_LS: - mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]); + mtex = &(((FreestyleLineStyle *)id)->mtex[int(((FreestyleLineStyle *)id)->texact)]); break; default: break; @@ -2631,10 +2631,10 @@ static void paste_mtex_copybuf(ID *id) switch (GS(id->name)) { case ID_PA: - mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]); + mtex = &(((ParticleSettings *)id)->mtex[int(((ParticleSettings *)id)->texact)]); break; case ID_LS: - mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]); + mtex = &(((FreestyleLineStyle *)id)->mtex[int(((FreestyleLineStyle *)id)->texact)]); break; default: BLI_assert_msg(0, "invalid id type"); diff --git a/source/blender/editors/space_file/filesel.cc b/source/blender/editors/space_file/filesel.cc index 446e5434edf..12d05054e9b 100644 --- a/source/blender/editors/space_file/filesel.cc +++ b/source/blender/editors/space_file/filesel.cc @@ -701,16 +701,16 @@ int ED_fileselect_layout_numfiles(FileLayout *layout, ARegion *region) */ if (layout->flag & FILE_LAYOUT_HOR) { const int x_item = layout->tile_w + (2 * layout->tile_border_x); - const int x_view = (int)BLI_rctf_size_x(®ion->v2d.cur); + const int x_view = int(BLI_rctf_size_x(®ion->v2d.cur)); const int x_over = x_item - (x_view % x_item); - numfiles = (int)((float)(x_view + x_over) / (float)(x_item)); + numfiles = int(float(x_view + x_over) / float(x_item)); return numfiles * layout->rows; } const int y_item = layout->tile_h + (2 * layout->tile_border_y); - const int y_view = (int)BLI_rctf_size_y(®ion->v2d.cur) - layout->offset_top; + const int y_view = int(BLI_rctf_size_y(®ion->v2d.cur)) - layout->offset_top; const int y_over = y_item - (y_view % y_item); - numfiles = (int)((float)(y_view + y_over) / (float)(y_item)); + numfiles = int(float(y_view + y_over) / float(y_item)); return numfiles * layout->flow_columns; } @@ -871,7 +871,7 @@ FileAttributeColumnType file_attribute_column_type_find_isect(const View2D *v2d, UI_view2d_region_to_view(v2d, x, v2d->mask.ymax - layout->offset_top - 1, &mx, &my); offset_tile = ED_fileselect_layout_offset( - layout, (int)(v2d->tot.xmin + mx), (int)(v2d->tot.ymax - my)); + layout, int(v2d->tot.xmin + mx), int(v2d->tot.ymax - my)); if (offset_tile > -1) { int tile_x, tile_y; int pos_x = 0; @@ -939,7 +939,7 @@ static void file_attribute_columns_widths(const FileSelectParams *params, FileLa pad; columns[COLUMN_SIZE].width = file_string_width(small_size ? "98.7 M" : "098.7 MiB") + pad; if (params->display == FILE_IMGDISPLAY) { - columns[COLUMN_NAME].width = ((float)params->thumbnail_size / 8.0f) * UI_UNIT_X; + columns[COLUMN_NAME].width = (float(params->thumbnail_size) / 8.0f) * UI_UNIT_X; } /* Name column uses remaining width */ else { @@ -993,22 +993,22 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *region) } numfiles = filelist_files_ensure(sfile->files); - textheight = (int)file_font_pointsize(); + textheight = int(file_font_pointsize()); layout = sfile->layout; layout->textheight = textheight; if (params->display == FILE_IMGDISPLAY) { const float pad_fac = compact ? 0.15f : 0.3f; /* Matches UI_preview_tile_size_x()/_y() by default. */ - layout->prv_w = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_X; - layout->prv_h = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_Y; + layout->prv_w = (float(params->thumbnail_size) / 20.0f) * UI_UNIT_X; + layout->prv_h = (float(params->thumbnail_size) / 20.0f) * UI_UNIT_Y; layout->tile_border_x = pad_fac * UI_UNIT_X; layout->tile_border_y = pad_fac * UI_UNIT_X; layout->prv_border_x = pad_fac * UI_UNIT_X; layout->prv_border_y = pad_fac * UI_UNIT_Y; layout->tile_w = layout->prv_w + 2 * layout->prv_border_x; layout->tile_h = layout->prv_h + 2 * layout->prv_border_y + textheight; - layout->width = (int)(BLI_rctf_size_x(&v2d->cur) - 2 * layout->tile_border_x); + layout->width = int(BLI_rctf_size_x(&v2d->cur) - 2 * layout->tile_border_x); layout->flow_columns = layout->width / (layout->tile_w + 2 * layout->tile_border_x); layout->attribute_column_header_h = 0; layout->offset_top = 0; @@ -1027,17 +1027,17 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *region) int rowcount; /* Matches UI_preview_tile_size_x()/_y() by default. */ - layout->prv_w = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_X; - layout->prv_h = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_Y; + layout->prv_w = (float(params->thumbnail_size) / 20.0f) * UI_UNIT_X; + layout->prv_h = (float(params->thumbnail_size) / 20.0f) * UI_UNIT_Y; layout->tile_border_x = 0.4f * UI_UNIT_X; layout->tile_border_y = 0.1f * UI_UNIT_Y; layout->tile_h = textheight * 3 / 2; - layout->width = (int)(BLI_rctf_size_x(&v2d->cur) - 2 * layout->tile_border_x); + layout->width = int(BLI_rctf_size_x(&v2d->cur) - 2 * layout->tile_border_x); layout->tile_w = layout->width; layout->flow_columns = 1; layout->attribute_column_header_h = layout->tile_h * 1.2f + 2 * layout->tile_border_y; layout->offset_top = layout->attribute_column_header_h; - rowcount = (int)(BLI_rctf_size_y(&v2d->cur) - layout->offset_top - 2 * layout->tile_border_y) / + rowcount = int(BLI_rctf_size_y(&v2d->cur) - layout->offset_top - 2 * layout->tile_border_y) / (layout->tile_h + 2 * layout->tile_border_y); file_attribute_columns_init(params, layout); @@ -1049,14 +1049,14 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *region) } else if (params->display == FILE_HORIZONTALDISPLAY) { /* Matches UI_preview_tile_size_x()/_y() by default. */ - layout->prv_w = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_X; - layout->prv_h = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_Y; + layout->prv_w = (float(params->thumbnail_size) / 20.0f) * UI_UNIT_X; + layout->prv_h = (float(params->thumbnail_size) / 20.0f) * UI_UNIT_Y; layout->tile_border_x = 0.4f * UI_UNIT_X; layout->tile_border_y = 0.1f * UI_UNIT_Y; layout->tile_h = textheight * 3 / 2; layout->attribute_column_header_h = 0; layout->offset_top = layout->attribute_column_header_h; - layout->height = (int)(BLI_rctf_size_y(&v2d->cur) - 2 * layout->tile_border_y); + layout->height = int(BLI_rctf_size_y(&v2d->cur) - 2 * layout->tile_border_y); /* Padding by full scroll-bar H is too much, can overlap tile border Y. */ layout->rows = (layout->height - V2D_SCROLL_HEIGHT + layout->tile_border_y) / (layout->tile_h + 2 * layout->tile_border_y); diff --git a/source/blender/render/intern/multires_bake.cc b/source/blender/render/intern/multires_bake.cc index 2d696788069..8a7d8090da4 100644 --- a/source/blender/render/intern/multires_bake.cc +++ b/source/blender/render/intern/multires_bake.cc @@ -1275,11 +1275,11 @@ static void apply_ao_callback(DerivedMesh *lores_dm, const ushort J = ao_data->permutation_table_2[i]; const float JitPh = (get_ao_random2(I + perm_ofs) & (MAX_NUMBER_OF_AO_RAYS - 1)) / - ((float)MAX_NUMBER_OF_AO_RAYS); + float(MAX_NUMBER_OF_AO_RAYS); const float JitTh = (get_ao_random1(J + perm_ofs) & (MAX_NUMBER_OF_AO_RAYS - 1)) / - ((float)MAX_NUMBER_OF_AO_RAYS); + float(MAX_NUMBER_OF_AO_RAYS); const float SiSqPhi = (I + JitPh) / ao_data->number_of_rays; - const float Theta = (float)(2 * M_PI) * ((J + JitTh) / ao_data->number_of_rays); + const float Theta = float(2 * M_PI) * ((J + JitTh) / ao_data->number_of_rays); /* this gives results identical to the so-called cosine * weighted distribution relative to the north pole. From 32812c2cc2a70bee018d205586e70154faeccbf7 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 10 Jan 2023 20:07:47 -0500 Subject: [PATCH 0583/1522] Cleanup: Remove redundant mesh data mask handling Byte colors are generic attributes and are therefore included in CD_MASK_PROP_ALL. Also clarify the use of vertex groups. They always have to be propagated since they're displayed in the spreadsheet, etc. --- source/blender/blenkernel/intern/mesh.cc | 3 +-- source/blender/blenkernel/intern/object_update.cc | 10 ++++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index f67cf7e0646..47832e669ed 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -517,8 +517,7 @@ static int customdata_compare( { CustomDataLayer *l1, *l2; int layer_count1 = 0, layer_count2 = 0, j; - const uint64_t cd_mask_non_generic = CD_MASK_MEDGE | CD_MASK_MPOLY | CD_MASK_PROP_BYTE_COLOR | - CD_MASK_MDEFORMVERT; + const uint64_t cd_mask_non_generic = CD_MASK_MEDGE | CD_MASK_MPOLY | CD_MASK_MDEFORMVERT; const uint64_t cd_mask_all_attr = CD_MASK_PROP_ALL | cd_mask_non_generic; const Span loops_1 = m1->loops(); const Span loops_2 = m2->loops(); diff --git a/source/blender/blenkernel/intern/object_update.cc b/source/blender/blenkernel/intern/object_update.cc index a7da1bfb5d2..5abd5188d1e 100644 --- a/source/blender/blenkernel/intern/object_update.cc +++ b/source/blender/blenkernel/intern/object_update.cc @@ -141,9 +141,9 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o CustomData_MeshMasks cddata_masks = scene->customdata_mask; CustomData_MeshMasks_update(&cddata_masks, &CD_MASK_BAREMESH); /* Custom attributes should not be removed automatically. They might be used by the render - * engine or scripts. They can still be removed explicitly using geometry nodes. - * Crease can be used in generic situations with geometry nodes as well. */ - cddata_masks.vmask |= CD_MASK_PROP_ALL | CD_MASK_CREASE; + * engine or scripts. They can still be removed explicitly using geometry nodes. Crease and + * vertex groups can be used in arbitrary situations with geometry nodes as well. */ + cddata_masks.vmask |= CD_MASK_PROP_ALL | CD_MASK_CREASE | CD_MASK_MDEFORMVERT; cddata_masks.emask |= CD_MASK_PROP_ALL | CD_MASK_CREASE; cddata_masks.fmask |= CD_MASK_PROP_ALL; cddata_masks.pmask |= CD_MASK_PROP_ALL; @@ -154,12 +154,10 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o #ifdef WITH_FREESTYLE cddata_masks.emask |= CD_MASK_FREESTYLE_EDGE; cddata_masks.pmask |= CD_MASK_FREESTYLE_FACE; - cddata_masks.vmask |= CD_MASK_MDEFORMVERT; #endif if (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER) { /* Always compute UVs, vertex colors as orcos for render. */ - cddata_masks.lmask |= CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_BYTE_COLOR; - cddata_masks.vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR; + cddata_masks.vmask |= CD_MASK_ORCO; } makeDerivedMesh(depsgraph, scene, ob, &cddata_masks); /* was CD_MASK_BAREMESH */ break; From bd7a1d5de60956e726f73e9a2fcf44547b2211ca Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 13:39:13 +1100 Subject: [PATCH 0584/1522] Docs: improve doc-string for UI_BUT_HAS_SEP_CHAR & UI_SEP_CHAR --- source/blender/editors/include/UI_interface.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 415356d1d71..cd729a330ca 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -79,7 +79,11 @@ typedef struct uiViewItemHandle uiViewItemHandle; /* Defines */ -/* char for splitting strings, aligning shortcuts in menus, users never see */ +/** + * Character used for splitting labels (right align text after this character). + * Users should never see this character. + * Only applied when #UI_BUT_HAS_SEP_CHAR flag is enabled, see it's doc-string for details. + */ #define UI_SEP_CHAR '|' #define UI_SEP_CHAR_S "|" @@ -220,7 +224,12 @@ enum { /** Use for popups to start editing the button on initialization. */ UI_BUT_ACTIVATE_ON_INIT = 1 << 26, - /** #uiBut.str contains #UI_SEP_CHAR, used for key shortcuts */ + /** + * #uiBut.str contains #UI_SEP_CHAR, used to show key-shortcuts right aligned. + * + * Since a label may contain #UI_SEP_CHAR, it's important to split on the last occurrence + * (meaning the right aligned text can't contain this character). + */ UI_BUT_HAS_SEP_CHAR = 1 << 27, /** Don't run updates while dragging (needed in rare cases). */ UI_BUT_UPDATE_DELAY = 1 << 28, From 28d38e876fff564be10b341a5d0f81c13d24f7ed Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 13:53:22 +1100 Subject: [PATCH 0585/1522] Cleanup: rename face_corners to loop for internal layer operations Follows naming used elsewhere. --- source/blender/blenkernel/BKE_mesh_legacy_convert.h | 7 ++++--- source/blender/blenkernel/intern/mesh_legacy_convert.cc | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh_legacy_convert.h b/source/blender/blenkernel/BKE_mesh_legacy_convert.h index d6689da7d86..5b72d85a433 100644 --- a/source/blender/blenkernel/BKE_mesh_legacy_convert.h +++ b/source/blender/blenkernel/BKE_mesh_legacy_convert.h @@ -26,9 +26,10 @@ struct MFace; #ifdef __cplusplus -void BKE_mesh_legacy_convert_uvs_to_struct(Mesh *mesh, - blender::ResourceScope &temp_mloopuv_for_convert, - blender::Vector &layers_to_write); +void BKE_mesh_legacy_convert_uvs_to_struct( + Mesh *mesh, + blender::ResourceScope &temp_mloopuv_for_convert, + blender::Vector &loop_layers_to_write); void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh); /** diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 1ad70792a22..2fea74176f9 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -1519,7 +1519,7 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh) void BKE_mesh_legacy_convert_uvs_to_struct( Mesh *mesh, blender::ResourceScope &temp_mloopuv_for_convert, - blender::Vector &face_corner_layers_to_write) + blender::Vector &loop_layers_to_write) { using namespace blender; using namespace blender::bke; @@ -1531,13 +1531,13 @@ void BKE_mesh_legacy_convert_uvs_to_struct( char vert_name[MAX_CUSTOMDATA_LAYER_NAME]; char edge_name[MAX_CUSTOMDATA_LAYER_NAME]; char pin_name[MAX_CUSTOMDATA_LAYER_NAME]; - for (const CustomDataLayer &layer : face_corner_layers_to_write) { + for (const CustomDataLayer &layer : loop_layers_to_write) { uv_sublayers_to_skip.add_multiple_new({BKE_uv_map_vert_select_name_get(layer.name, vert_name), BKE_uv_map_edge_select_name_get(layer.name, edge_name), BKE_uv_map_pin_name_get(layer.name, pin_name)}); } - for (const CustomDataLayer &layer : face_corner_layers_to_write) { + for (const CustomDataLayer &layer : loop_layers_to_write) { if (uv_sublayers_to_skip.contains_as(layer.name)) { continue; } @@ -1571,7 +1571,7 @@ void BKE_mesh_legacy_convert_uvs_to_struct( new_layer_to_write.append(mloopuv_layer); } - face_corner_layers_to_write = new_layer_to_write; + loop_layers_to_write = new_layer_to_write; mesh->ldata.totlayer = new_layer_to_write.size(); mesh->ldata.maxlayer = mesh->ldata.totlayer; } From 86464cfcef2c982ae532b47553207be13f3d3815 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 13:57:51 +1100 Subject: [PATCH 0586/1522] Fix error converting UV's to MLoopUV Logic to skip UV layers that are part of the MLoopUV treated all loop-layers as UV's, causing duplicate and invalid names to be added to be added to 'uv_sublayers_to_skip', this asserted in debug mode when saving the `ellie_animation.blend` demo blend file. --- .../blender/blenkernel/intern/mesh_legacy_convert.cc | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 2fea74176f9..07fe17794ff 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -1532,13 +1532,16 @@ void BKE_mesh_legacy_convert_uvs_to_struct( char edge_name[MAX_CUSTOMDATA_LAYER_NAME]; char pin_name[MAX_CUSTOMDATA_LAYER_NAME]; for (const CustomDataLayer &layer : loop_layers_to_write) { - uv_sublayers_to_skip.add_multiple_new({BKE_uv_map_vert_select_name_get(layer.name, vert_name), - BKE_uv_map_edge_select_name_get(layer.name, edge_name), - BKE_uv_map_pin_name_get(layer.name, pin_name)}); + if (layer.type == CD_PROP_FLOAT2) { + uv_sublayers_to_skip.add_multiple_new( + {BKE_uv_map_vert_select_name_get(layer.name, vert_name), + BKE_uv_map_edge_select_name_get(layer.name, edge_name), + BKE_uv_map_pin_name_get(layer.name, pin_name)}); + } } for (const CustomDataLayer &layer : loop_layers_to_write) { - if (uv_sublayers_to_skip.contains_as(layer.name)) { + if (layer.name[0] && uv_sublayers_to_skip.contains_as(layer.name)) { continue; } if (layer.type != CD_PROP_FLOAT2) { From d8d20e0e59c9856c6ba47ce9c9f0c843d32f48c4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 17:54:12 +1100 Subject: [PATCH 0587/1522] UI: include 'drag-' prefix in the short-cut text for menu items This was already done for double-click events but not drag events. --- source/blender/makesdna/DNA_windowmanager_types.h | 9 ++++++--- source/blender/windowmanager/intern/wm_keymap.c | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index af0bb721f60..6e5bb593d22 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -390,11 +390,14 @@ typedef struct wmKeyMapItem { short propvalue; /* event */ - /** Event code itself. */ + /** Event code itself (#EVT_LEFTCTRLKEY, #LEFTMOUSE etc). */ short type; - /** KM_ANY, KM_PRESS, KM_NOTHING etc. */ + /** Button state (#KM_ANY, #KM_PRESS, #KM_DBL_CLICK, #KM_CLICK_DRAG, #KM_NOTHING etc). */ int8_t val; - /** Use when `val == KM_CLICK_DRAG`. */ + /** + * The 2D direction of the event to use when `val == KM_CLICK_DRAG`. + * Set to #KM_DIRECTION_N, #KM_DIRECTION_S & related values, #KM_NOTHING for any direction. + */ int8_t direction; /** `oskey` also known as apple, windows-key or super. */ short shift, ctrl, alt, oskey; diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 0ea878cec3b..39cf1e6d202 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -1197,6 +1197,9 @@ int WM_keymap_item_raw_to_string(const short shift, if (val == KM_DBL_CLICK) { p += BLI_strcpy_rlen(p, IFACE_("dbl-")); } + else if (val == KM_CLICK_DRAG) { + p += BLI_strcpy_rlen(p, IFACE_("drag-")); + } p += BLI_strcpy_rlen(p, WM_key_event_string(type, compact)); } From f88e78856945e7c916bb5fa191c5e403834487b6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 17:58:12 +1100 Subject: [PATCH 0588/1522] Pose Slide: set the value of "release_confirm" from the event when unset Needed to fix T103267, so the properties for the menu item and the drag action will match & show the shortcut in the menu. --- source/blender/editors/armature/pose_lib_2.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/armature/pose_lib_2.c b/source/blender/editors/armature/pose_lib_2.c index d0f87b25b2d..5b7ad6fb900 100644 --- a/source/blender/editors/armature/pose_lib_2.c +++ b/source/blender/editors/armature/pose_lib_2.c @@ -353,9 +353,14 @@ static bool poselib_blend_init_data(bContext *C, wmOperator *op, const wmEvent * /* Release confirm data. Only available if there's an event to work with. */ if (is_interactive) { PropertyRNA *release_confirm_prop = RNA_struct_find_property(op->ptr, "release_confirm"); - pbd->release_confirm_info.use_release_confirm = (release_confirm_prop != NULL) && - RNA_property_boolean_get(op->ptr, - release_confirm_prop); + if (release_confirm_prop && RNA_property_is_set(op->ptr, release_confirm_prop)) { + pbd->release_confirm_info.use_release_confirm = RNA_property_boolean_get( + op->ptr, release_confirm_prop); + } + else { + pbd->release_confirm_info.use_release_confirm = event->val != KM_RELEASE; + } + pbd->slider = ED_slider_create(C); ED_slider_init(pbd->slider, event); ED_slider_factor_set(pbd->slider, pbd->blend_factor); From 68c6fc6d385aa69dde36a9d46bdc4773b1cab621 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 19:14:35 +1100 Subject: [PATCH 0589/1522] Fix T103267: No shortcuts shown in the Pose Assets context menu Support displaying shortcuts for uiListDyn.custom_drag_* & custom_activate_* operators. --- source/blender/editors/include/UI_interface.h | 14 +++ .../editors/interface/interface_utils.cc | 106 ++++++++++++++++++ .../blender/windowmanager/intern/wm_keymap.c | 7 ++ 3 files changed, 127 insertions(+) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index cd729a330ca..0705052921e 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -3130,6 +3130,20 @@ void UI_butstore_register(uiButStore *bs_handle, uiBut **but_p); bool UI_butstore_register_update(uiBlock *block, uiBut *but_dst, const uiBut *but_src); void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p); +/** + * A version of #WM_key_event_operator_string that's limited to UI elements. + * + * This supports showing shortcuts in context-menus (for example), + * for actions that can also be activated using shortcuts while the cursor is over the button. + * Without this those shortcuts aren't discoverable for users. + */ +const char *UI_key_event_operator_string(const struct bContext *C, + const char *opname, + IDProperty *properties, + const bool is_strict, + char *result, + const int result_len); + /* ui_interface_region_tooltip.c */ /** diff --git a/source/blender/editors/interface/interface_utils.cc b/source/blender/editors/interface/interface_utils.cc index 157ffa6f02c..4835e4c4f7f 100644 --- a/source/blender/editors/interface/interface_utils.cc +++ b/source/blender/editors/interface/interface_utils.cc @@ -25,8 +25,10 @@ #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_idprop.h" #include "BKE_lib_id.h" #include "BKE_report.h" +#include "BKE_screen.h" #include "MEM_guardedalloc.h" @@ -1094,3 +1096,107 @@ void UI_butstore_update(uiBlock *block) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Key Event from UI + * \{ */ + +/** + * Follow the logic from #wm_keymap_item_find_in_keymap. + */ +static bool ui_key_event_property_match(const char *opname, + IDProperty *properties, + const bool is_strict, + wmOperatorType *ui_optype, + PointerRNA *ui_opptr) +{ + if (!STREQ(ui_optype->idname, opname)) { + return false; + } + + bool match = false; + if (properties) { + if (ui_opptr && IDP_EqualsProperties_ex( + properties, static_cast(ui_opptr->data), is_strict)) { + match = true; + } + } + else { + match = true; + } + return match; +} + +const char *UI_key_event_operator_string(const bContext *C, + const char *opname, + IDProperty *properties, + const bool is_strict, + char *result, + const int result_len) +{ + /* NOTE: currently only actions on UI Lists are supported (for the asset manager). + * Other kinds of events can be supported as needed. */ + + ARegion *region = CTX_wm_region(C); + if (region == nullptr) { + return nullptr; + } + + /* Early exit regions which don't have UI-Lists. */ + if ((region->type->keymapflag & ED_KEYMAP_UI) == 0) { + return nullptr; + } + + uiBut *but = UI_region_active_but_get(region); + if (but == nullptr) { + return nullptr; + } + + if (but->type != UI_BTYPE_PREVIEW_TILE) { + return nullptr; + } + + short event_val = KM_NOTHING; + short event_type = KM_NOTHING; + + uiBut *listbox = nullptr; + LISTBASE_FOREACH_BACKWARD (uiBut *, but_iter, &but->block->buttons) { + if ((but_iter->type == UI_BTYPE_LISTBOX) && ui_but_contains_rect(but_iter, &but->rect)) { + listbox = but_iter; + break; + } + } + + if (listbox && listbox->custom_data) { + uiList *list = static_cast(listbox->custom_data); + uiListDyn *dyn_data = list->dyn_data; + if ((dyn_data->custom_activate_optype != nullptr) && + ui_key_event_property_match(opname, + properties, + is_strict, + dyn_data->custom_activate_optype, + dyn_data->custom_activate_opptr)) { + event_val = KM_CLICK; + event_type = LEFTMOUSE; + } + else if ((dyn_data->custom_activate_optype != nullptr) && + ui_key_event_property_match(opname, + properties, + is_strict, + dyn_data->custom_drag_optype, + dyn_data->custom_drag_opptr)) { + event_val = KM_CLICK_DRAG; + event_type = LEFTMOUSE; + } + } + + if ((event_val != KM_NOTHING) && (event_type != KM_NOTHING)) { + WM_keymap_item_raw_to_string( + false, false, false, false, 0, event_val, event_type, false, result, result_len); + return result; + } + + return nullptr; +} + +/** \} */ diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 39cf1e6d202..807d84dcc51 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -25,6 +25,8 @@ #include "BLF_api.h" +#include "UI_interface.h" + #include "BKE_context.h" #include "BKE_global.h" #include "BKE_idprop.h" @@ -1659,6 +1661,11 @@ char *WM_key_event_operator_string(const bContext *C, return result; } + /* Check UI state (non key-map actions for UI regions). */ + if (UI_key_event_operator_string(C, opname, properties, is_strict, result, result_len)) { + return result; + } + return NULL; } From d3e8d63a8c455d09ff3660cc158a28439d5eb06d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 20:00:59 +1100 Subject: [PATCH 0590/1522] Fix error in StringRef equality Regression in [0] wasn't correct as it's important for empty strings to be equal to nullptr. [0]: 9f283bee7ecfedabc7a6b46fb9f2cece6b3e31ec --- source/blender/blenlib/BLI_string_ref.hh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/blender/blenlib/BLI_string_ref.hh b/source/blender/blenlib/BLI_string_ref.hh index 6ad4d6fd3af..4f6f2cbfa41 100644 --- a/source/blender/blenlib/BLI_string_ref.hh +++ b/source/blender/blenlib/BLI_string_ref.hh @@ -612,9 +612,13 @@ constexpr bool operator==(StringRef a, StringRef b) * which would results in an ASAN warning. */ return true; } - if (!a.data() || !b.data()) { - /* Account for a single value being null, resulting in an ASAN warning. */ - return false; + /* Account for a single value being null, resulting in an ASAN warning. + * Ensure an empty string is equal to a string with a null pointer. */ + if (!a.data()) { + return *b.data() == '\0'; + } + if (!b.data()) { + return *a.data() == '\0'; } return STREQLEN(a.data(), b.data(), size_t(a.size())); } From cff2807affc60fe94e87df19f00c51c5c70713df Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 20:55:33 +1100 Subject: [PATCH 0591/1522] Fix T103719: missing shortcuts info for some tool-settings Tool settings can be accessed from both `tool_settings` & `scene.tool_settings`. As of [0] `scene.tool_settings` was used instead of `tool_settings` causing the snap shortcut not to display. Resolve by supporting variations of data-paths so both are detected. [0]: 9a76dd2454c2d6f84e4f15c0235669b317599fbd --- source/blender/editors/interface/interface.cc | 108 +++++++++++------- 1 file changed, 66 insertions(+), 42 deletions(-) diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index 6998aa91e9f..2a21356b9aa 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -1454,63 +1454,87 @@ static bool ui_but_event_property_operator_string(const bContext *C, } } - char *data_path = WM_context_path_resolve_property_full(C, ptr, prop, prop_index); + /* There may be multiple data-paths to the same properties, + * support different variations so key bindings are properly detected no matter which are used. + */ + char *data_path_variations[2] = {nullptr}; + int data_path_variations_num = 0; + + { + char *data_path = WM_context_path_resolve_property_full(C, ptr, prop, prop_index); + + /* Always iterate once, even if data-path isn't set. */ + data_path_variations[data_path_variations_num++] = data_path; + + if (data_path) { + if (STRPREFIX(data_path, "scene.tool_settings.")) { + data_path_variations[data_path_variations_num++] = BLI_strdup(data_path + 6); + } + } + } /* We have a data-path! */ bool found = false; - if (data_path || (prop_enum_value_ok && prop_enum_value_id)) { - /* Create a property to host the "data_path" property we're sending to the operators. */ - IDProperty *prop_path; - const IDPropertyTemplate group_val = {0}; - prop_path = IDP_New(IDP_GROUP, &group_val, __func__); - if (data_path) { - IDP_AddToGroup(prop_path, IDP_NewString(data_path, "data_path", strlen(data_path) + 1)); - } - if (prop_enum_value_ok) { - const EnumPropertyItem *item; - bool free; - RNA_property_enum_items((bContext *)C, ptr, prop, &item, nullptr, &free); - const int index = RNA_enum_from_value(item, prop_enum_value); - if (index != -1) { - IDProperty *prop_value; - if (prop_enum_value_is_int) { - const int value = item[index].value; - IDPropertyTemplate val = {}; - val.i = value; - prop_value = IDP_New(IDP_INT, &val, prop_enum_value_id); + for (int data_path_index = 0; data_path_index < data_path_variations_num && (found == false); + data_path_index++) { + const char *data_path = data_path_variations[data_path_index]; + if (data_path || (prop_enum_value_ok && prop_enum_value_id)) { + /* Create a property to host the "data_path" property we're sending to the operators. */ + IDProperty *prop_path; + + const IDPropertyTemplate group_val = {0}; + prop_path = IDP_New(IDP_GROUP, &group_val, __func__); + if (data_path) { + IDP_AddToGroup(prop_path, IDP_NewString(data_path, "data_path", strlen(data_path) + 1)); + } + if (prop_enum_value_ok) { + const EnumPropertyItem *item; + bool free; + RNA_property_enum_items((bContext *)C, ptr, prop, &item, nullptr, &free); + const int index = RNA_enum_from_value(item, prop_enum_value); + if (index != -1) { + IDProperty *prop_value; + if (prop_enum_value_is_int) { + const int value = item[index].value; + IDPropertyTemplate val = {}; + val.i = value; + prop_value = IDP_New(IDP_INT, &val, prop_enum_value_id); + } + else { + const char *id = item[index].identifier; + prop_value = IDP_NewString(id, prop_enum_value_id, strlen(id) + 1); + } + IDP_AddToGroup(prop_path, prop_value); } else { - const char *id = item[index].identifier; - prop_value = IDP_NewString(id, prop_enum_value_id, strlen(id) + 1); + opnames_len = 0; /* Do nothing. */ + } + if (free) { + MEM_freeN((void *)item); } - IDP_AddToGroup(prop_path, prop_value); } - else { - opnames_len = 0; /* Do nothing. */ - } - if (free) { - MEM_freeN((void *)item); + + /* check each until one works... */ + + for (int i = 0; (i < opnames_len) && (opnames[i]); i++) { + if (WM_key_event_operator_string( + C, opnames[i], WM_OP_INVOKE_REGION_WIN, prop_path, false, buf, buf_len)) { + found = true; + break; + } } + /* cleanup */ + IDP_FreeProperty(prop_path); } + } - /* check each until one works... */ - - for (int i = 0; (i < opnames_len) && (opnames[i]); i++) { - if (WM_key_event_operator_string( - C, opnames[i], WM_OP_INVOKE_REGION_WIN, prop_path, false, buf, buf_len)) { - found = true; - break; - } - } - - /* cleanup */ - IDP_FreeProperty(prop_path); + for (int data_path_index = 0; data_path_index < data_path_variations_num; data_path_index++) { + char *data_path = data_path_variations[data_path_index]; if (data_path) { MEM_freeN(data_path); } } - return found; } From 866b24ac886e77b388e5262587778cf6ee434b2a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 11 Jan 2023 21:08:15 +1100 Subject: [PATCH 0592/1522] Cleanup: use continue in loop to reduce right-shift --- .../blender/windowmanager/intern/wm_keymap.c | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 807d84dcc51..9e322228884 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -1316,12 +1316,13 @@ static wmKeyMapItem *wm_keymap_item_find_in_keymap(wmKeyMap *keymap, if (kmi->flag & KMI_INACTIVE) { continue; } + if (!STREQ(kmi->idname, opname)) { + continue; + } bool kmi_match = false; - - if (STREQ(kmi->idname, opname)) { - if (properties) { - /* example of debugging keymaps */ + if (properties) { + /* example of debugging keymaps */ #if 0 if (kmi->ptr) { if (STREQ("MESH_OT_rip_move", opname)) { @@ -1333,54 +1334,53 @@ static wmKeyMapItem *wm_keymap_item_find_in_keymap(wmKeyMap *keymap, } #endif - if (kmi->ptr && IDP_EqualsProperties_ex(properties, kmi->ptr->data, is_strict)) { - kmi_match = true; - } - /* Debug only, helps spotting mismatches between menu entries and shortcuts! */ - else if (G.debug & G_DEBUG_WM) { - if (is_strict && kmi->ptr) { - wmOperatorType *ot = WM_operatortype_find(opname, true); - if (ot) { - /* make a copy of the properties and set unset ones to their default values. */ - PointerRNA opptr; - IDProperty *properties_default = IDP_CopyProperty(kmi->ptr->data); + if (kmi->ptr && IDP_EqualsProperties_ex(properties, kmi->ptr->data, is_strict)) { + kmi_match = true; + } + /* Debug only, helps spotting mismatches between menu entries and shortcuts! */ + else if (G.debug & G_DEBUG_WM) { + if (is_strict && kmi->ptr) { + wmOperatorType *ot = WM_operatortype_find(opname, true); + if (ot) { + /* make a copy of the properties and set unset ones to their default values. */ + PointerRNA opptr; + IDProperty *properties_default = IDP_CopyProperty(kmi->ptr->data); - RNA_pointer_create(NULL, ot->srna, properties_default, &opptr); - WM_operator_properties_default(&opptr, true); + RNA_pointer_create(NULL, ot->srna, properties_default, &opptr); + WM_operator_properties_default(&opptr, true); - if (IDP_EqualsProperties_ex(properties, properties_default, is_strict)) { - char kmi_str[128]; - WM_keymap_item_to_string(kmi, false, kmi_str, sizeof(kmi_str)); - /* NOTE: given properties could come from other things than menu entry. */ - printf( - "%s: Some set values in menu entry match default op values, " - "this might not be desired!\n", - opname); - printf("\tkm: '%s', kmi: '%s'\n", keymap->idname, kmi_str); + if (IDP_EqualsProperties_ex(properties, properties_default, is_strict)) { + char kmi_str[128]; + WM_keymap_item_to_string(kmi, false, kmi_str, sizeof(kmi_str)); + /* NOTE: given properties could come from other things than menu entry. */ + printf( + "%s: Some set values in menu entry match default op values, " + "this might not be desired!\n", + opname); + printf("\tkm: '%s', kmi: '%s'\n", keymap->idname, kmi_str); #ifndef NDEBUG # ifdef WITH_PYTHON - printf("OPERATOR\n"); - IDP_print(properties); - printf("KEYMAP\n"); - IDP_print(kmi->ptr->data); + printf("OPERATOR\n"); + IDP_print(properties); + printf("KEYMAP\n"); + IDP_print(kmi->ptr->data); # endif #endif - printf("\n"); - } - - IDP_FreeProperty(properties_default); + printf("\n"); } + + IDP_FreeProperty(properties_default); } } } - else { - kmi_match = true; - } + } + else { + kmi_match = true; + } - if (kmi_match) { - if ((params == NULL) || params->filter_fn(keymap, kmi, params->user_data)) { - return kmi; - } + if (kmi_match) { + if ((params == NULL) || params->filter_fn(keymap, kmi, params->user_data)) { + return kmi; } } } From 8f7bb812c461d04bef1f0f69495267501de4a3e7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 11 Jan 2023 11:46:53 +0100 Subject: [PATCH 0593/1522] Gitea: Add Issue and Pull Request templates It is a part of the Phabricator to Gitea migration. The issue template is based on the bug submission instructions which are shown in the Phabricator's bug submission form. Some further tweaks are likely needed, but the current version of the template simplifies re-iteration while working on the migration. The pull request template is needed to override the template in the .github folder which is otherwise picked up by Gitea. --- .gitea/issue_template.yaml | 45 +++++++++++++++++++++++++++++++++ .gitea/pull_request_template.md | 4 +++ 2 files changed, 49 insertions(+) create mode 100644 .gitea/issue_template.yaml create mode 100644 .gitea/pull_request_template.md diff --git a/.gitea/issue_template.yaml b/.gitea/issue_template.yaml new file mode 100644 index 00000000000..08b98a0112e --- /dev/null +++ b/.gitea/issue_template.yaml @@ -0,0 +1,45 @@ +name: Bug Report +about: File a bug report +labels: + - bug +ref: master +body: + - type: markdown + attributes: + value: | + ### First time bug reporting? + Read [these tips](https://wiki.blender.org/wiki/Process/Bug_Reports) and watch this **[How to Report a Bug](https://www.youtube.com/watch?v=JTD0OJq_rF4)** video to make a complete, valid bug report. Remember to write your bug report in **English**. + + ### What not to report here + For feature requests, feedback, questions or issues building Blender, see [communication channels](https://wiki.blender.org/wiki/Communication/Contact#User_Feedback_and_Requests). + + ### Please verify + * Always test with the latest official release from [blender.org](https://www.blender.org/) and daily build from [builder.blender.org](https://builder.blender.org/). + * Please use `Help > Report a Bug` in Blender to automatically fill system information and exact Blender version. + * Test [previous Blender versions](https://download.blender.org/release/) to find the latest version that was working as expected. + * Find steps to redo the bug consistently without any non-official add-ons, and include a **small and simple .blend file** to demonstrate the bug. + * If there are multiple bugs, make multiple bug reports. + * Sometimes, driver or software upgrades cause problems. On Windows, try a clean install of the graphics drivers. + + ### Help the developers + Bug fixing is important, the developers will handle a report swiftly. For that reason, we need your help to carefully provide instructions that others can follow quickly. You do your half of the work, then we do our half! + + If a report is tagged with Needs Information from User and it has no reply after a week, we will assume the issue is gone and close the report. + + - type: textarea + attributes: + label: "Description" + value: | + **System Information** + Operating system: + Graphics card: + + **Blender Version** + Broken: (example: 2.80, edbf15d3c044, master, 2018-11-28, as found on the splash screen) + Worked: (newest version of Blender that worked as expected) + + **Short description of error** + + **Exact steps for others to reproduce the error** + Based on the default startup or an attached .blend file (as simple as possible). + diff --git a/.gitea/pull_request_template.md b/.gitea/pull_request_template.md new file mode 100644 index 00000000000..a6614b8ef00 --- /dev/null +++ b/.gitea/pull_request_template.md @@ -0,0 +1,4 @@ +--- +name: Pull Request +about: Submit a pull request +--- From 5d07b0e6da70d380a2d42fdade8caf02737342ad Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 11 Jan 2023 13:19:11 +0100 Subject: [PATCH 0594/1522] Cleanup: delegate to string_view equality for StringRef This also fixes an issue introduced in rBd3e8d63a8c455d0, where the function relied on the `StringRef` being null-terminated. --- source/blender/blenlib/BLI_string_ref.hh | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/source/blender/blenlib/BLI_string_ref.hh b/source/blender/blenlib/BLI_string_ref.hh index 4f6f2cbfa41..f7606ccc860 100644 --- a/source/blender/blenlib/BLI_string_ref.hh +++ b/source/blender/blenlib/BLI_string_ref.hh @@ -604,28 +604,12 @@ inline std::string operator+(StringRef a, StringRef b) * Ideally, we only use StringRef in our code to avoid this problem altogether. */ constexpr bool operator==(StringRef a, StringRef b) { - if (a.size() != b.size()) { - return false; - } - if (a.data() == b.data()) { - /* This also avoids passing null to the call below when both are null, - * which would results in an ASAN warning. */ - return true; - } - /* Account for a single value being null, resulting in an ASAN warning. - * Ensure an empty string is equal to a string with a null pointer. */ - if (!a.data()) { - return *b.data() == '\0'; - } - if (!b.data()) { - return *a.data() == '\0'; - } - return STREQLEN(a.data(), b.data(), size_t(a.size())); + return std::string_view(a) == std::string_view(b); } constexpr bool operator!=(StringRef a, StringRef b) { - return !(a == b); + return std::string_view(a) != std::string_view(b); } constexpr bool operator<(StringRef a, StringRef b) From a6b6f5db10aebcc13c7e42134c5f2dd66b030b20 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 11 Jan 2023 15:27:31 +0100 Subject: [PATCH 0595/1522] Fix issue with recent refactor in liboverride diffing. New code from rBd05909a70c36 last week did not take into account liboverride templates and `NOOP` operations. So we cannot assume that there is no valid override property for these which need to be restored. While we may get rid of templates at some point now, for now they are still exposed in PY API, and have some basic unittests, so keep them working as best as possible. Issue reported on IRC by Martijn Versteegh (@Baardaap), thanks! --- .../blender/blenkernel/intern/lib_override.cc | 13 ++++++++++++- .../intern/rna_access_compare_override.c | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index 0cbed770ed1..8a9440a8e32 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -3394,7 +3394,18 @@ void BKE_lib_override_library_operations_restore(Main *bmain, ID *local, int *r_ LISTBASE_FOREACH_MUTABLE ( IDOverrideLibraryProperty *, op, &local->override_library->properties) { if (op->tag & IDOVERRIDE_LIBRARY_PROPERTY_TAG_NEEDS_RETORE) { - BKE_lib_override_library_property_delete(local->override_library, op); + LISTBASE_FOREACH_MUTABLE (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { + if (opop->tag & IDOVERRIDE_LIBRARY_PROPERTY_TAG_NEEDS_RETORE) { + BKE_lib_override_library_property_operation_delete(op, opop); + } + } + if (BLI_listbase_is_empty(&local->override_library->properties)) { + BKE_lib_override_library_property_delete(local->override_library, op); + } + else { + BKE_lib_override_library_operations_tag( + op, IDOVERRIDE_LIBRARY_PROPERTY_TAG_NEEDS_RETORE, false); + } } } local->override_library->runtime->tag &= ~IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RESTORE; diff --git a/source/blender/makesrna/intern/rna_access_compare_override.c b/source/blender/makesrna/intern/rna_access_compare_override.c index a0a084869d8..af13171f202 100644 --- a/source/blender/makesrna/intern/rna_access_compare_override.c +++ b/source/blender/makesrna/intern/rna_access_compare_override.c @@ -821,8 +821,6 @@ bool RNA_struct_override_matches(Main *bmain, /* This property should be restored to its reference value. This should not be done * here, since this code may be called from non-main thread (modifying data through RNA * is not thread safe). */ - BLI_assert(op == NULL); /* Forbidden override prop should not exist currently. */ - if (do_restore) { IDOverrideLibraryPropertyOperation opop_tmp = { .operation = IDOVERRIDE_LIBRARY_OP_REPLACE, @@ -850,10 +848,14 @@ bool RNA_struct_override_matches(Main *bmain, op = BKE_lib_override_library_property_get(override, rna_path, NULL); BKE_lib_override_library_operations_tag(op, IDOVERRIDE_LIBRARY_TAG_UNUSED, true); } - BKE_lib_override_library_property_operation_get( - op, IDOVERRIDE_LIBRARY_OP_REPLACE, NULL, NULL, -1, -1, false, NULL, NULL); - BKE_lib_override_library_operations_tag( - op, IDOVERRIDE_LIBRARY_PROPERTY_TAG_NEEDS_RETORE, true); + IDOverrideLibraryPropertyOperation *opop_restore = + BKE_lib_override_library_property_operation_get( + op, IDOVERRIDE_LIBRARY_OP_REPLACE, NULL, NULL, -1, -1, false, NULL, NULL); + /* Do not use `BKE_lib_override_library_operations_tag` here, as the property may be + * a valid one that has other operations that needs to remain (e.g. from a template, + * a NOOP operation to enforce no change on that property, etc.). */ + op->tag |= IDOVERRIDE_LIBRARY_PROPERTY_TAG_NEEDS_RETORE; + opop_restore->tag |= IDOVERRIDE_LIBRARY_PROPERTY_TAG_NEEDS_RETORE; override->runtime->tag |= IDOVERRIDE_LIBRARY_RUNTIME_TAG_NEEDS_RESTORE; if (r_report_flags) { @@ -1153,6 +1155,10 @@ static void rna_property_override_apply_ex(Main *bmain, const bool do_insert) { LISTBASE_FOREACH (IDOverrideLibraryPropertyOperation *, opop, &op->operations) { + if (opop->operation == IDOVERRIDE_LIBRARY_OP_NOOP) { + continue; + } + if (!do_insert != !ELEM(opop->operation, IDOVERRIDE_LIBRARY_OP_INSERT_AFTER, IDOVERRIDE_LIBRARY_OP_INSERT_BEFORE)) { From 3b761901b6d6d5c089a89d0df9d8d12fd7f8e368 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 11 Jan 2023 11:50:45 -0300 Subject: [PATCH 0596/1522] Fix T103783: crash when canceling vertex crease having vertex groups `transdata_restore_basic` uses `copy_v3_v3` to restore a pointer that is 1D. --- .../editors/transform/transform_convert_mesh_vert_cdata.c | 6 +++--- source/blender/editors/transform/transform_data.h | 8 ++++---- source/blender/editors/transform/transform_generics.c | 8 ++++---- .../editors/transform/transform_mode_edge_bevelweight.c | 6 +++--- .../editors/transform/transform_mode_edge_crease.c | 6 +++--- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c b/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c index 6145962acbf..0d29892cd5e 100644 --- a/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c +++ b/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c @@ -49,8 +49,8 @@ static void tc_mesh_cdata_transdata_create(TransDataBasic *td, { BLI_assert(BM_elem_flag_test(eve, BM_ELEM_HIDDEN) == 0); - td->loc = weight; - td->iloc[0] = *weight; + td->val = weight; + td->ival = *weight; if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { td->flag |= TD_SELECTED; @@ -268,7 +268,7 @@ static void tc_mesh_cdata_apply_to_mirror(TransInfo *t) if (tc->use_mirror_axis_any) { TransDataMirror *td_mirror = tc->data_mirror; for (int i = 0; i < tc->data_mirror_len; i++, td_mirror++) { - td_mirror->loc[0] = td_mirror->loc_src[0]; + *td_mirror->val = td_mirror->loc_src[0]; } } } diff --git a/source/blender/editors/transform/transform_data.h b/source/blender/editors/transform/transform_data.h index 195fab93f72..2518fef3b39 100644 --- a/source/blender/editors/transform/transform_data.h +++ b/source/blender/editors/transform/transform_data.h @@ -20,6 +20,10 @@ struct bConstraint; float iloc[3]; \ /** Individual data center. */ \ float center[3]; \ + /** Value pointer for special transforms. */ \ + float *val; \ + /** Old value. */ \ + float ival; \ /** Various flags. */ \ int flag @@ -114,10 +118,6 @@ typedef struct TransData { float rdist; /** Factor of the transformation (for Proportional Editing). */ float factor; - /** Value pointer for special transforms. */ - float *val; - /** Old value. */ - float ival; /** Transformation matrix from data space to global space. */ float mtx[3][3]; /** Transformation matrix from global space to data space. */ diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 449a53573e6..5d3e326d8b0 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -815,16 +815,16 @@ static void transdata_restore_basic(TransDataBasic *td_basic) if (td_basic->loc) { copy_v3_v3(td_basic->loc, td_basic->iloc); } + + if (td_basic->val && td_basic->val != td_basic->loc) { + *td_basic->val = td_basic->ival; + } } static void restoreElement(TransData *td) { transdata_restore_basic((TransDataBasic *)td); - if (td->val && td->val != td->loc) { - *td->val = td->ival; - } - if (td->ext && (td->flag & TD_NO_EXT) == 0) { if (td->ext->rot) { copy_v3_v3(td->ext->rot, td->ext->irot); diff --git a/source/blender/editors/transform/transform_mode_edge_bevelweight.c b/source/blender/editors/transform/transform_mode_edge_bevelweight.c index e96e74b596c..c46eee5eb56 100644 --- a/source/blender/editors/transform/transform_mode_edge_bevelweight.c +++ b/source/blender/editors/transform/transform_mode_edge_bevelweight.c @@ -44,11 +44,11 @@ static void transdata_elem_bevel_weight(const TransInfo *UNUSED(t), TransData *td, const float weight) { - if (td->loc == NULL) { + if (td->val == NULL) { return; } - *td->loc = td->iloc[0] + weight * td->factor; - CLAMP(*td->loc, 0.0f, 1.0f); + *td->val = td->ival + weight * td->factor; + CLAMP(*td->val, 0.0f, 1.0f); } static void transdata_elem_bevel_weight_fn(void *__restrict iter_data_v, diff --git a/source/blender/editors/transform/transform_mode_edge_crease.c b/source/blender/editors/transform/transform_mode_edge_crease.c index 1a3ccf30387..2ced57860c5 100644 --- a/source/blender/editors/transform/transform_mode_edge_crease.c +++ b/source/blender/editors/transform/transform_mode_edge_crease.c @@ -44,12 +44,12 @@ static void transdata_elem_crease(const TransInfo *UNUSED(t), TransData *td, const float crease) { - if (td->loc == NULL) { + if (td->val == NULL) { return; } - *td->loc = td->iloc[0] + crease * td->factor; - CLAMP(*td->loc, 0.0f, 1.0f); + *td->val = td->ival + crease * td->factor; + CLAMP(*td->val, 0.0f, 1.0f); } static void transdata_elem_crease_fn(void *__restrict iter_data_v, From ad01cdd7fc931c7e313eebc0027a05d96e36e66f Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 11 Jan 2023 12:08:04 -0300 Subject: [PATCH 0597/1522] Transform: improve safety when restoring data --- .../blender/editors/transform/transform_generics.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 5d3e326d8b0..968e2bca5b9 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -811,13 +811,15 @@ void applyTransObjects(TransInfo *t) static void transdata_restore_basic(TransDataBasic *td_basic) { - /* TransData for crease has no loc */ - if (td_basic->loc) { - copy_v3_v3(td_basic->loc, td_basic->iloc); + if (td_basic->val) { + *td_basic->val = td_basic->ival; } - if (td_basic->val && td_basic->val != td_basic->loc) { - *td_basic->val = td_basic->ival; + /* TODO(mano-wii): Only use 3D or larger vectors in `td->loc`. + * If `loc` and `val` point to the same address, it may indicate that `loc` is not 3D which is + * not safe for `copy_v3_v3`. */ + if (td_basic->loc && td_basic->val != td_basic->loc) { + copy_v3_v3(td_basic->loc, td_basic->iloc); } } From 5029f3e483d9fe8395163670e2d6d00eb5bf1c9f Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 11 Jan 2023 12:49:19 -0300 Subject: [PATCH 0598/1522] Fix crease and bevel weight unaffected when transforming Regression in 3b761901b --- .../blender/editors/transform/transform_convert_mesh_edge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/transform/transform_convert_mesh_edge.c b/source/blender/editors/transform/transform_convert_mesh_edge.c index fd62b199345..f8ea8ea9f7d 100644 --- a/source/blender/editors/transform/transform_convert_mesh_edge.c +++ b/source/blender/editors/transform/transform_convert_mesh_edge.c @@ -103,8 +103,8 @@ static void createTransEdge(bContext *UNUSED(C), TransInfo *t) td->ext = NULL; fl_ptr = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset); - td->loc = fl_ptr; - td->iloc[0] = *fl_ptr; + td->val = fl_ptr; + td->ival = *fl_ptr; td++; } From 4d1f12212b112330a9c78cd48d46f9679e9c1b6d Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 11 Jan 2023 12:28:48 -0300 Subject: [PATCH 0599/1522] Transform: deduplicate code Edge Bevel Weight and Edge Crease operations have the same code. Only the name displayed in the header changes. --- .../blender/editors/transform/CMakeLists.txt | 3 +- .../editors/transform/transform_mode.h | 7 +- ...e_crease.c => transform_mode_customdata.c} | 91 ++++++---- .../transform_mode_edge_bevelweight.c | 157 ------------------ 4 files changed, 58 insertions(+), 200 deletions(-) rename source/blender/editors/transform/{transform_mode_edge_crease.c => transform_mode_customdata.c} (54%) delete mode 100644 source/blender/editors/transform/transform_mode_edge_bevelweight.c diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt index 6c9b834d34b..bcd87ff9572 100644 --- a/source/blender/editors/transform/CMakeLists.txt +++ b/source/blender/editors/transform/CMakeLists.txt @@ -63,8 +63,7 @@ set(SRC transform_mode_boneenvelope.c transform_mode_boneroll.c transform_mode_curveshrinkfatten.c - transform_mode_edge_bevelweight.c - transform_mode_edge_crease.c + transform_mode_customdata.c transform_mode_edge_rotate_normal.c transform_mode_edge_seq_slide.c transform_mode_edge_slide.c diff --git a/source/blender/editors/transform/transform_mode.h b/source/blender/editors/transform/transform_mode.h index 063de87ebb2..b782d27a3c6 100644 --- a/source/blender/editors/transform/transform_mode.h +++ b/source/blender/editors/transform/transform_mode.h @@ -94,14 +94,11 @@ void initBoneRoll(TransInfo *t); void initCurveShrinkFatten(TransInfo *t); -/* transform_mode_edge_bevelweight.c */ - -void initBevelWeight(TransInfo *t); - -/* transform_mode_edge_crease.c */ +/* transform_mode_customdata.c */ void initEgdeCrease(TransInfo *t); void initVertCrease(TransInfo *t); +void initBevelWeight(TransInfo *t); /* transform_mode_edge_rotate_normal.c */ diff --git a/source/blender/editors/transform/transform_mode_edge_crease.c b/source/blender/editors/transform/transform_mode_customdata.c similarity index 54% rename from source/blender/editors/transform/transform_mode_edge_crease.c rename to source/blender/editors/transform/transform_mode_customdata.c index 2ced57860c5..fb4ee2484bc 100644 --- a/source/blender/editors/transform/transform_mode_edge_crease.c +++ b/source/blender/editors/transform/transform_mode_customdata.c @@ -27,64 +27,64 @@ #include "transform_mode.h" /* -------------------------------------------------------------------- */ -/** \name Transform (Crease) Element +/** \name Transform Element * \{ */ /** * \note Small arrays / data-structures should be stored copied for faster memory access. */ -struct TransDataArgs_Crease { +struct TransDataArgs_Value { const TransInfo *t; const TransDataContainer *tc; - float crease; + float value; }; -static void transdata_elem_crease(const TransInfo *UNUSED(t), - const TransDataContainer *UNUSED(tc), - TransData *td, - const float crease) +static void transdata_elem_value(const TransInfo *UNUSED(t), + const TransDataContainer *UNUSED(tc), + TransData *td, + const float value) { if (td->val == NULL) { return; } - *td->val = td->ival + crease * td->factor; + *td->val = td->ival + value * td->factor; CLAMP(*td->val, 0.0f, 1.0f); } -static void transdata_elem_crease_fn(void *__restrict iter_data_v, - const int iter, - const TaskParallelTLS *__restrict UNUSED(tls)) +static void transdata_elem_value_fn(void *__restrict iter_data_v, + const int iter, + const TaskParallelTLS *__restrict UNUSED(tls)) { - struct TransDataArgs_Crease *data = iter_data_v; + struct TransDataArgs_Value *data = iter_data_v; TransData *td = &data->tc->data[iter]; if (td->flag & TD_SKIP) { return; } - transdata_elem_crease(data->t, data->tc, td, data->crease); + transdata_elem_value(data->t, data->tc, td, data->value); } /** \} */ /* -------------------------------------------------------------------- */ -/** \name Transform (Crease) +/** \name Transform Value * \{ */ -static void applyCrease(TransInfo *t, const int UNUSED(mval[2])) +static void apply_value_impl(TransInfo *t, const char *value_name) { - float crease; + float value; int i; char str[UI_MAX_DRAW_STR]; - crease = t->values[0] + t->values_modal_offset[0]; + value = t->values[0] + t->values_modal_offset[0]; - CLAMP_MAX(crease, 1.0f); + CLAMP_MAX(value, 1.0f); - transform_snap_increment(t, &crease); + transform_snap_increment(t, &value); - applyNumInput(&t->num, &crease); + applyNumInput(&t->num, &value); - t->values_final[0] = crease; + t->values_final[0] = value; /* header print for NumInput */ if (hasNumInput(&t->num)) { @@ -92,20 +92,20 @@ static void applyCrease(TransInfo *t, const int UNUSED(mval[2])) outputNumInput(&(t->num), c, &t->scene->unit); - if (crease >= 0.0f) { - BLI_snprintf(str, sizeof(str), TIP_("Crease: +%s %s"), c, t->proptext); + if (value >= 0.0f) { + BLI_snprintf(str, sizeof(str), "%s: +%s %s", value_name, c, t->proptext); } else { - BLI_snprintf(str, sizeof(str), TIP_("Crease: %s %s"), c, t->proptext); + BLI_snprintf(str, sizeof(str), "%s: %s %s", value_name, c, t->proptext); } } else { /* default header print */ - if (crease >= 0.0f) { - BLI_snprintf(str, sizeof(str), TIP_("Crease: +%.3f %s"), crease, t->proptext); + if (value >= 0.0f) { + BLI_snprintf(str, sizeof(str), "%s: +%.3f %s", value_name, value, t->proptext); } else { - BLI_snprintf(str, sizeof(str), TIP_("Crease: %.3f %s"), crease, t->proptext); + BLI_snprintf(str, sizeof(str), "%s: %.3f %s", value_name, value, t->proptext); } } @@ -116,18 +116,18 @@ static void applyCrease(TransInfo *t, const int UNUSED(mval[2])) if (td->flag & TD_SKIP) { continue; } - transdata_elem_crease(t, tc, td, crease); + transdata_elem_value(t, tc, td, value); } } else { - struct TransDataArgs_Crease data = { + struct TransDataArgs_Value data = { .t = t, .tc = tc, - .crease = crease, + .value = value, }; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); - BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_crease_fn, &settings); + BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_value_fn, &settings); } } @@ -136,11 +136,18 @@ static void applyCrease(TransInfo *t, const int UNUSED(mval[2])) ED_area_status_text(t->area, str); } -static void initCrease_ex(TransInfo *t, int mode) +static void applyCrease(TransInfo *t, const int UNUSED(mval[2])) { - t->mode = mode; - t->transform = applyCrease; + apply_value_impl(t, TIP_("Crease")); +} +static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2])) +{ + apply_value_impl(t, TIP_("Bevel Weight")); +} + +static void init_mode_impl(TransInfo *t) +{ initMouseInputMode(t, &t->mouse, INPUT_SPRING_DELTA); t->idx_max = 0; @@ -157,11 +164,23 @@ static void initCrease_ex(TransInfo *t, int mode) void initEgdeCrease(TransInfo *t) { - initCrease_ex(t, TFM_EDGE_CREASE); + init_mode_impl(t); + t->mode = TFM_EDGE_CREASE; + t->transform = applyCrease; } void initVertCrease(TransInfo *t) { - initCrease_ex(t, TFM_VERT_CREASE); + init_mode_impl(t); + t->mode = TFM_VERT_CREASE; + t->transform = applyCrease; } + +void initBevelWeight(TransInfo *t) +{ + init_mode_impl(t); + t->mode = TFM_BWEIGHT; + t->transform = applyBevelWeight; +} + /** \} */ diff --git a/source/blender/editors/transform/transform_mode_edge_bevelweight.c b/source/blender/editors/transform/transform_mode_edge_bevelweight.c deleted file mode 100644 index c46eee5eb56..00000000000 --- a/source/blender/editors/transform/transform_mode_edge_bevelweight.c +++ /dev/null @@ -1,157 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later - * Copyright 2001-2002 NaN Holding BV. All rights reserved. */ - -/** \file - * \ingroup edtransform - */ - -#include - -#include "BLI_math.h" -#include "BLI_string.h" -#include "BLI_task.h" - -#include "BKE_context.h" -#include "BKE_unit.h" - -#include "ED_screen.h" - -#include "UI_interface.h" - -#include "BLT_translation.h" - -#include "transform.h" -#include "transform_convert.h" -#include "transform_snap.h" - -#include "transform_mode.h" - -/* -------------------------------------------------------------------- */ -/** \name Transform (Bevel Weight) Element - * \{ */ - -/** - * \note Small arrays / data-structures should be stored copied for faster memory access. - */ -struct TransDataArgs_BevelWeight { - const TransInfo *t; - const TransDataContainer *tc; - float weight; -}; - -static void transdata_elem_bevel_weight(const TransInfo *UNUSED(t), - const TransDataContainer *UNUSED(tc), - TransData *td, - const float weight) -{ - if (td->val == NULL) { - return; - } - *td->val = td->ival + weight * td->factor; - CLAMP(*td->val, 0.0f, 1.0f); -} - -static void transdata_elem_bevel_weight_fn(void *__restrict iter_data_v, - const int iter, - const TaskParallelTLS *__restrict UNUSED(tls)) -{ - struct TransDataArgs_BevelWeight *data = iter_data_v; - TransData *td = &data->tc->data[iter]; - if (td->flag & TD_SKIP) { - return; - } - transdata_elem_bevel_weight(data->t, data->tc, td, data->weight); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Transform (Bevel Weight) - * \{ */ - -static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2])) -{ - float weight; - int i; - char str[UI_MAX_DRAW_STR]; - - weight = t->values[0] + t->values_modal_offset[0]; - - CLAMP_MAX(weight, 1.0f); - - transform_snap_increment(t, &weight); - - applyNumInput(&t->num, &weight); - - t->values_final[0] = weight; - - /* header print for NumInput */ - if (hasNumInput(&t->num)) { - char c[NUM_STR_REP_LEN]; - - outputNumInput(&(t->num), c, &t->scene->unit); - - if (weight >= 0.0f) { - BLI_snprintf(str, sizeof(str), TIP_("Bevel Weight: +%s %s"), c, t->proptext); - } - else { - BLI_snprintf(str, sizeof(str), TIP_("Bevel Weight: %s %s"), c, t->proptext); - } - } - else { - /* default header print */ - if (weight >= 0.0f) { - BLI_snprintf(str, sizeof(str), TIP_("Bevel Weight: +%.3f %s"), weight, t->proptext); - } - else { - BLI_snprintf(str, sizeof(str), TIP_("Bevel Weight: %.3f %s"), weight, t->proptext); - } - } - - FOREACH_TRANS_DATA_CONTAINER (t, tc) { - if (tc->data_len < TRANSDATA_THREAD_LIMIT) { - TransData *td = tc->data; - for (i = 0; i < tc->data_len; i++, td++) { - if (td->flag & TD_SKIP) { - continue; - } - transdata_elem_bevel_weight(t, tc, td, weight); - } - } - else { - struct TransDataArgs_BevelWeight data = { - .t = t, - .tc = tc, - .weight = weight, - }; - TaskParallelSettings settings; - BLI_parallel_range_settings_defaults(&settings); - BLI_task_parallel_range(0, tc->data_len, &data, transdata_elem_bevel_weight_fn, &settings); - } - } - - recalcData(t); - - ED_area_status_text(t->area, str); -} - -void initBevelWeight(TransInfo *t) -{ - t->mode = TFM_BWEIGHT; - t->transform = applyBevelWeight; - - initMouseInputMode(t, &t->mouse, INPUT_SPRING_DELTA); - - t->idx_max = 0; - t->num.idx_max = 0; - t->snap[0] = 0.1f; - t->snap[1] = t->snap[0] * 0.1f; - - copy_v3_fl(t->num.val_inc, t->snap[0]); - t->num.unit_sys = t->scene->unit.system; - t->num.unit_type[0] = B_UNIT_NONE; - - t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT; -} - -/** \} */ From 88e9826529d1cce750181d6355a42a2bbcdb1ff3 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Wed, 11 Jan 2023 09:57:58 -0800 Subject: [PATCH 0600/1522] Sculpt: Fix T102889: Sculpt trim tool extrudes in perspective Added an extrude mode enum to the trim operators to control extrusion: "project" and "fixed." "Fixed" just extrudes along a fixed normal and is the new default. --- release/datafiles/locale | 2 +- release/scripts/addons | 2 +- .../startup/bl_ui/space_toolsystem_toolbar.py | 2 + .../blender/editors/sculpt_paint/paint_mask.c | 53 ++++++++++++++++--- source/tools | 2 +- 5 files changed, 51 insertions(+), 10 deletions(-) diff --git a/release/datafiles/locale b/release/datafiles/locale index 7be7aff5a18..7084c4ecd97 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 7be7aff5a18c550465b3f7634539ed4168af7c51 +Subproject commit 7084c4ecd97d93459d9d23fd90f81589b09be5df diff --git a/release/scripts/addons b/release/scripts/addons index c226f867aff..a9d4443c244 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit c226f867affd12881533a54c8c90ac6eebfaca6c +Subproject commit a9d4443c244f89399ec4bcc427e05a07950528cc diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index fb6136154c8..37cb01503d3 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1408,6 +1408,7 @@ class _defs_sculpt: def draw_settings(_context, layout, tool): props = tool.operator_properties("sculpt.trim_box_gesture") layout.prop(props, "trim_mode", expand=False) + layout.prop(props, "trim_extrude_mode", expand=False) layout.prop(props, "use_cursor_depth", expand=False) return dict( idname="builtin.box_trim", @@ -1424,6 +1425,7 @@ class _defs_sculpt: props = tool.operator_properties("sculpt.trim_lasso_gesture") layout.prop(props, "trim_mode", expand=False) layout.prop(props, "trim_orientation", expand=False) + layout.prop(props, "trim_extrude_mode", expand=False) layout.prop(props, "use_cursor_depth", expand=False) return dict( idname="builtin.lasso_trim", diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index eff24ceb0b3..3ebd5fe799d 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -954,6 +954,21 @@ static EnumPropertyItem prop_trim_orientation_types[] = { {0, NULL, 0, NULL, NULL}, }; +typedef enum eSculptTrimExtrudeMode { + SCULPT_GESTURE_TRIM_EXTRUDE_PROJECT, + SCULPT_GESTURE_TRIM_EXTRUDE_FIXED +} eSculptTrimExtrudeMode; + +static EnumPropertyItem prop_trim_extrude_modes[] = { + {SCULPT_GESTURE_TRIM_EXTRUDE_PROJECT, + "PROJECT", + 0, + "Project", + "Project back faces when extruding"}, + {SCULPT_GESTURE_TRIM_EXTRUDE_FIXED, "FIXED", 0, "Fixed", "Extrude back faces by fixed amount"}, + {0, NULL, 0, NULL, NULL}, +}; + typedef struct SculptGestureTrimOperation { SculptGestureOperation op; @@ -967,6 +982,7 @@ typedef struct SculptGestureTrimOperation { eSculptTrimOperationType mode; eSculptTrimOrientationType orientation; + eSculptTrimExtrudeMode extrude_mode; } SculptGestureTrimOperation; static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext) @@ -1160,23 +1176,39 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point); madd_v3_v3fl(new_point, shape_normal, depth_front); } - mul_v3_m4v3(positions[i], ob_imat, new_point); - mul_v3_m4v3(trim_operation->true_mesh_co[i], ob_imat, new_point); + + copy_v3_v3(positions[i], new_point); } /* Write vertices coordinates for the back face. */ madd_v3_v3v3fl(depth_point, shape_origin, shape_normal, depth_back); for (int i = 0; i < tot_screen_points; i++) { float new_point[3]; - if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) { - ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point); + + if (trim_operation->extrude_mode == SCULPT_GESTURE_TRIM_EXTRUDE_PROJECT) { + if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) { + ED_view3d_win_to_3d(vc->v3d, region, depth_point, screen_points[i], new_point); + } + else { + ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point); + madd_v3_v3fl(new_point, shape_normal, depth_back); + } } else { - ED_view3d_win_to_3d_on_plane(region, shape_plane, screen_points[i], false, new_point); + copy_v3_v3(new_point, positions[i]); madd_v3_v3fl(new_point, shape_normal, depth_back); } - mul_v3_m4v3(positions[i + tot_screen_points], ob_imat, new_point); - mul_v3_m4v3(trim_operation->true_mesh_co[i + tot_screen_points], ob_imat, new_point); + + copy_v3_v3(positions[i + tot_screen_points], new_point); + } + + /* Project to object space. */ + for (int i = 0; i < tot_screen_points * 2; i++) { + float new_point[3]; + + copy_v3_v3(new_point, positions[i]); + mul_v3_m4v3(positions[i], ob_imat, new_point); + mul_v3_m4v3(trim_operation->true_mesh_co[i], ob_imat, new_point); } /* Get the triangulation for the front/back poly. */ @@ -1404,6 +1436,7 @@ static void sculpt_gesture_init_trim_properties(SculptGestureContext *sgcontext, trim_operation->mode = RNA_enum_get(op->ptr, "trim_mode"); trim_operation->use_cursor_depth = RNA_boolean_get(op->ptr, "use_cursor_depth"); trim_operation->orientation = RNA_enum_get(op->ptr, "trim_orientation"); + trim_operation->extrude_mode = RNA_enum_get(op->ptr, "trim_extrude_mode"); /* If the cursor was not over the mesh, force the orientation to view. */ if (!sgcontext->ss->gesture_initial_hit) { @@ -1431,6 +1464,12 @@ static void sculpt_trim_gesture_operator_properties(wmOperatorType *ot) SCULPT_GESTURE_TRIM_ORIENTATION_VIEW, "Shape Orientation", NULL); + RNA_def_enum(ot->srna, + "trim_extrude_mode", + prop_trim_extrude_modes, + SCULPT_GESTURE_TRIM_EXTRUDE_FIXED, + "Extrude Mode", + NULL); } /* Project Gesture Operation. */ diff --git a/source/tools b/source/tools index f542f4d21a0..e1744b9bd82 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit f542f4d21a077d85ffb3e43aa7f170976dee20b6 +Subproject commit e1744b9bd82527cf7e8af63362b61bd309b5711b From ff86573d72cadf431c6f39aac9c8ebb78853acdc Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Wed, 11 Jan 2023 21:35:09 +0100 Subject: [PATCH 0601/1522] Fix T102313: Enabling shadow catcher in viewport render shows self-shadowing The problem here is that whether an object is a shadow catcher or not affects the visibility flags, but changes to the shadow catcher property did not trigger a visibility flag update. --- intern/cycles/scene/object.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/intern/cycles/scene/object.cpp b/intern/cycles/scene/object.cpp index c788c6f4a8c..dc98389575a 100644 --- a/intern/cycles/scene/object.cpp +++ b/intern/cycles/scene/object.cpp @@ -217,6 +217,7 @@ void Object::tag_update(Scene *scene) if (is_shadow_catcher_is_modified()) { scene->tag_shadow_catcher_modified(); + flag |= ObjectManager::VISIBILITY_MODIFIED; } } From 442b08aac0c77c5167b31e651b260dfa04155c1c Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 11 Jan 2023 18:20:05 -0300 Subject: [PATCH 0602/1522] Snap Gizmo: support the WM_GIZMO_HIDDEN flag Support snap cursor removal in poll callback, this makes it possible to delay cursor removal if the gizmo is hidden. --- .../gizmo_library/gizmo_types/snap3d_gizmo.c | 62 +++++++++++++++---- source/blender/editors/include/ED_view3d.h | 4 +- .../editors/space_view3d/view3d_cursor_snap.c | 13 ++-- .../editors/space_view3d/view3d_placement.c | 12 +++- .../windowmanager/intern/wm_event_system.cc | 9 ++- 5 files changed, 73 insertions(+), 27 deletions(-) diff --git a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c index 5cac8b93b88..8f2cb016f86 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c @@ -226,6 +226,49 @@ static void gizmo_snap_rna_snap_elem_index_get_fn(struct PointerRNA *UNUSED(ptr) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Snap Cursor Utils + * \{ */ + +static void snap_cursor_free(SnapGizmo3D *snap_gizmo) +{ + if (snap_gizmo->snap_state) { + ED_view3d_cursor_snap_deactive(snap_gizmo->snap_state); + snap_gizmo->snap_state = NULL; + } +} + +/* XXX: Delayed snap cursor removal. */ +static bool snap_cursor_poll(ARegion *region, void *data) +{ + SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)data; + if (snap_gizmo->gizmo.flag & WM_GIZMO_HIDDEN) { + snap_cursor_free(snap_gizmo); + return false; + } + + if (!WM_gizmomap_group_find_ptr(region->gizmo_map, snap_gizmo->gizmo.parent_gzgroup->type)) { + /* Wrong viewport. */ + snap_cursor_free(snap_gizmo); + return false; + } + return true; +} + +static void snap_cursor_init(SnapGizmo3D *snap_gizmo) +{ + snap_gizmo->snap_state = ED_view3d_cursor_snap_active(); + snap_gizmo->snap_state->draw_point = true; + snap_gizmo->snap_state->draw_plane = false; + + rgba_float_to_uchar(snap_gizmo->snap_state->color_point, snap_gizmo->gizmo.color); + + snap_gizmo->snap_state->poll = snap_cursor_poll; + snap_gizmo->snap_state->poll_data = snap_gizmo; +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name GIZMO_GT_snap_3d * \{ */ @@ -233,17 +276,15 @@ static void gizmo_snap_rna_snap_elem_index_get_fn(struct PointerRNA *UNUSED(ptr) static void snap_gizmo_setup(wmGizmo *gz) { gz->flag |= WM_GIZMO_NO_TOOLTIP; - SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - snap_gizmo->snap_state = ED_view3d_cursor_snap_active(); - snap_gizmo->snap_state->gzgrp_type = gz->parent_gzgroup->type; - snap_gizmo->snap_state->draw_point = true; - snap_gizmo->snap_state->draw_plane = false; - - rgba_float_to_uchar(snap_gizmo->snap_state->color_point, gz->color); + snap_cursor_init((SnapGizmo3D *)gz); } -static void snap_gizmo_draw(const bContext *UNUSED(C), wmGizmo *UNUSED(gz)) +static void snap_gizmo_draw(const bContext *UNUSED(C), wmGizmo *gz) { + SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; + if (snap_gizmo->snap_state == NULL) { + snap_cursor_init(snap_gizmo); + } /* All drawing is handled at the paint cursor. */ } @@ -292,10 +333,7 @@ static int snap_gizmo_invoke(bContext *UNUSED(C), static void snap_gizmo_free(wmGizmo *gz) { - SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)gz; - if (snap_gizmo->snap_state) { - ED_view3d_cursor_snap_deactive(snap_gizmo->snap_state); - } + snap_cursor_free((SnapGizmo3D *)gz); } static void GIZMO_GT_snap_3d(wmGizmoType *gzt) diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index f475eeee335..12313b3d244 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -320,7 +320,6 @@ typedef struct V3DSnapCursorState { uchar color_line[4]; uchar color_point[4]; uchar color_box[4]; - struct wmGizmoGroupType *gzgrp_type; /* Force cursor to be drawn only when gizmo is available. */ float *prevpoint; float box_dimensions[3]; eSnapMode snap_elem_force; /* If SCE_SNAP_MODE_NONE, use scene settings. */ @@ -329,6 +328,9 @@ typedef struct V3DSnapCursorState { bool draw_point; bool draw_plane; bool draw_box; + + bool (*poll)(struct ARegion *region, void *custom_poll_data); + void *poll_data; } V3DSnapCursorState; void ED_view3d_cursor_snap_state_default_set(V3DSnapCursorState *state); diff --git a/source/blender/editors/space_view3d/view3d_cursor_snap.c b/source/blender/editors/space_view3d/view3d_cursor_snap.c index 771a964dbcd..875097b4827 100644 --- a/source/blender/editors/space_view3d/view3d_cursor_snap.c +++ b/source/blender/editors/space_view3d/view3d_cursor_snap.c @@ -826,14 +826,10 @@ static bool v3d_cursor_snap_poll_fn(bContext *C) return false; }; + /* Call this callback last and don't reuse the `state` as the caller can free the cursor. */ V3DSnapCursorState *state = ED_view3d_cursor_snap_state_get(); - if (state->gzgrp_type) { - /* Check the respective gizmo group is in the region. */ - wmGizmoMap *gzmap = region->gizmo_map; - if (WM_gizmomap_group_find_ptr(gzmap, state->gzgrp_type) == NULL) { - /* Wrong viewport. */ - return false; - } + if (state->poll && !state->poll(region, state->poll_data)) { + return false; } return true; @@ -959,10 +955,11 @@ void ED_view3d_cursor_snap_state_default_set(V3DSnapCursorState *state) /* These values are temporarily set by the tool. * They are not convenient as default values. * So reset to null. */ - g_data_intern.state_default.gzgrp_type = NULL; g_data_intern.state_default.prevpoint = NULL; g_data_intern.state_default.draw_plane = false; g_data_intern.state_default.draw_box = false; + g_data_intern.state_default.poll = NULL; + g_data_intern.state_default.poll_data = NULL; } V3DSnapCursorState *ED_view3d_cursor_snap_active(void) diff --git a/source/blender/editors/space_view3d/view3d_placement.c b/source/blender/editors/space_view3d/view3d_placement.c index 7588ad8d2c1..dfa4ba04e54 100644 --- a/source/blender/editors/space_view3d/view3d_placement.c +++ b/source/blender/editors/space_view3d/view3d_placement.c @@ -1515,11 +1515,21 @@ static void preview_plane_free_fn(void *customdata) ED_view3d_cursor_snap_deactive(snap_state); } +static bool snap_cursor_poll(ARegion *region, void *data) +{ + if (WM_gizmomap_group_find_ptr(region->gizmo_map, (wmGizmoGroupType *)data) == NULL) { + /* Wrong viewport. */ + return false; + } + return true; +} + static void WIDGETGROUP_placement_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup) { V3DSnapCursorState *snap_state = ED_view3d_cursor_snap_active(); if (snap_state) { - snap_state->gzgrp_type = gzgroup->type; + snap_state->poll = snap_cursor_poll; + snap_state->poll_data = gzgroup->type; snap_state->draw_plane = true; gzgroup->customdata = snap_state; diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index ba8f13dd5c3..14812c4335d 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -3573,10 +3573,10 @@ static ARegion *region_event_inside(bContext *C, const int xy[2]) return nullptr; } -static void wm_paintcursor_tag(bContext *C, wmPaintCursor *pc, ARegion *region) +static void wm_paintcursor_tag(bContext *C, wmWindowManager *wm, ARegion *region) { if (region) { - for (; pc; pc = pc->next) { + LISTBASE_FOREACH_MUTABLE (wmPaintCursor *, pc, &wm->paintcursors) { if (pc->poll == nullptr || pc->poll(C)) { wmWindow *win = CTX_wm_window(C); WM_paint_cursor_tag_redraw(win, region); @@ -3598,7 +3598,7 @@ static void wm_paintcursor_test(bContext *C, const wmEvent *event) ARegion *region = CTX_wm_region(C); if (region) { - wm_paintcursor_tag(C, static_cast(wm->paintcursors.first), region); + wm_paintcursor_tag(C, wm, region); } /* If previous position was not in current region, we have to set a temp new context. */ @@ -3608,8 +3608,7 @@ static void wm_paintcursor_test(bContext *C, const wmEvent *event) CTX_wm_area_set(C, area_event_inside(C, event->prev_xy)); CTX_wm_region_set(C, region_event_inside(C, event->prev_xy)); - wm_paintcursor_tag( - C, static_cast(wm->paintcursors.first), CTX_wm_region(C)); + wm_paintcursor_tag(C, wm, CTX_wm_region(C)); CTX_wm_area_set(C, area); CTX_wm_region_set(C, region); From 2b32a2c3b2193ccfe9062efd842f35798fca0cd5 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 11 Jan 2023 18:52:30 -0300 Subject: [PATCH 0603/1522] Snap Gizmo: hide snap cursor if another gizmo is highlighted --- .../blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c index 8f2cb016f86..4a5bad575e7 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c @@ -242,6 +242,10 @@ static void snap_cursor_free(SnapGizmo3D *snap_gizmo) static bool snap_cursor_poll(ARegion *region, void *data) { SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)data; + if (!(snap_gizmo->gizmo.state & WM_GIZMO_STATE_HIGHLIGHT)) { + return false; + } + if (snap_gizmo->gizmo.flag & WM_GIZMO_HIDDEN) { snap_cursor_free(snap_gizmo); return false; From 2b4bf586ade5a5941f116383074871941a629f23 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Thu, 12 Jan 2023 00:48:56 +0100 Subject: [PATCH 0604/1522] Fix T102920: Cycles doesn't support multiple outputs on muted nodes Cycles converts internal links to converter nodes which don't do anything and later on get collapsed by the graph optimization. However, the previous code assumed that one Blender input socket maps to one Cycles input socket. When a node is muted, there might be internal links from one input to multiple outputs. In Cycles, this meant that one Blender input socket now mapped to multiple input sockets on all the converter nodes, so only the last one survived. THe fix is simple, just make the mapping a MultiMap. --- intern/cycles/blender/shader.cpp | 33 ++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/intern/cycles/blender/shader.cpp b/intern/cycles/blender/shader.cpp index f25e98469fb..5220e680a50 100644 --- a/intern/cycles/blender/shader.cpp +++ b/intern/cycles/blender/shader.cpp @@ -26,7 +26,7 @@ CCL_NAMESPACE_BEGIN -typedef map PtrInputMap; +typedef unordered_multimap PtrInputMap; typedef map PtrOutputMap; typedef map ProxyMap; @@ -1251,7 +1251,9 @@ static void add_nodes(Scene *scene, ConvertNode *proxy = graph->create_node(to_socket_type, to_socket_type, true); - input_map[b_link.from_socket().ptr.data] = proxy->inputs[0]; + /* Muted nodes can result in multiple Cycles input sockets mapping to the same Blender + * input socket, so this needs to be a multimap. */ + input_map.emplace(b_link.from_socket().ptr.data, proxy->inputs[0]); output_map[b_link.to_socket().ptr.data] = proxy->outputs[0]; graph->add(proxy); @@ -1286,7 +1288,7 @@ static void add_nodes(Scene *scene, /* register the proxy node for internal binding */ group_proxy_input_map[b_input.identifier()] = proxy; - input_map[b_input.ptr.data] = proxy->inputs[0]; + input_map.emplace(b_input.ptr.data, proxy->inputs[0]); set_default_value(proxy->inputs[0], b_input, b_data, b_ntree); } @@ -1338,7 +1340,7 @@ static void add_nodes(Scene *scene, if (proxy_it != proxy_output_map.end()) { ConvertNode *proxy = proxy_it->second; - input_map[b_input.ptr.data] = proxy->inputs[0]; + input_map.emplace(b_input.ptr.data, proxy->inputs[0]); set_default_value(proxy->inputs[0], b_input, b_data, b_ntree); } @@ -1369,7 +1371,7 @@ static void add_nodes(Scene *scene, /* XXX should not happen, report error? */ continue; } - input_map[b_input.ptr.data] = input; + input_map.emplace(b_input.ptr.data, input); set_default_value(input, b_input, b_data, b_ntree); } @@ -1401,20 +1403,23 @@ static void add_nodes(Scene *scene, BL::NodeSocket b_from_sock = b_link.from_socket(); BL::NodeSocket b_to_sock = b_link.to_socket(); - ShaderOutput *output = 0; - ShaderInput *input = 0; - + ShaderOutput *output = nullptr; PtrOutputMap::iterator output_it = output_map.find(b_from_sock.ptr.data); if (output_it != output_map.end()) output = output_it->second; - PtrInputMap::iterator input_it = input_map.find(b_to_sock.ptr.data); - if (input_it != input_map.end()) - input = input_it->second; - /* either node may be NULL when the node was not exported, typically + /* either socket may be NULL when the node was not exported, typically * because the node type is not supported */ - if (output && input) - graph->connect(output, input); + if (output != nullptr) { + ShaderOutput *output = output_it->second; + auto inputs = input_map.equal_range(b_to_sock.ptr.data); + for (PtrInputMap::iterator input_it = inputs.first; input_it != inputs.second; ++input_it) { + ShaderInput *input = input_it->second; + if (input != nullptr) { + graph->connect(output, input); + } + } + } } } From 0349a6e6e05ee5f3c941890a8ce4062615ecf5cc Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Wed, 11 Jan 2023 23:00:51 -0300 Subject: [PATCH 0605/1522] Fix disappearing snap indication in Measure tool Snap cursor disappeared while dragging. Regression in 2b32a2c3b --- .../blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c | 3 ++- source/blender/editors/space_view3d/view3d_gizmo_ruler.c | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c index 4a5bad575e7..571a2b6ef61 100644 --- a/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c +++ b/source/blender/editors/gizmo_library/gizmo_types/snap3d_gizmo.c @@ -242,7 +242,8 @@ static void snap_cursor_free(SnapGizmo3D *snap_gizmo) static bool snap_cursor_poll(ARegion *region, void *data) { SnapGizmo3D *snap_gizmo = (SnapGizmo3D *)data; - if (!(snap_gizmo->gizmo.state & WM_GIZMO_STATE_HIGHLIGHT)) { + if (!(snap_gizmo->gizmo.state & WM_GIZMO_STATE_HIGHLIGHT) && + !(snap_gizmo->gizmo.flag & WM_GIZMO_DRAW_VALUE)) { return false; } diff --git a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c index c94043f2397..b9a30eac3c6 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_ruler.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_ruler.c @@ -301,10 +301,13 @@ static void ruler_state_set(RulerInfo *ruler_info, int state) } if (state == RULER_STATE_NORMAL) { - /* pass */ + WM_gizmo_set_flag(ruler_info->snap_data.gizmo, WM_GIZMO_DRAW_VALUE, false); } else if (state == RULER_STATE_DRAG) { memset(&ruler_info->drag_state_prev, 0x0, sizeof(ruler_info->drag_state_prev)); + + /* Force the snap cursor to appear even though it is not highlighted. */ + WM_gizmo_set_flag(ruler_info->snap_data.gizmo, WM_GIZMO_DRAW_VALUE, true); } else { BLI_assert(0); From b9177014b6f0081534635347153a0a9380a1d018 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 12 Jan 2023 08:35:14 +0100 Subject: [PATCH 0606/1522] 3D Texturing: Replace pointers with indexes in pbvh_uv_islands Replace the pointers in the MeshEdge with indexes, removing MeshPrimitive and MeshVertex. Code cleanup proposed by the geometry nodes to make the data structures more reusable by other areas of Blender as well. Old implementation was to focused to the texture painting. Initial the idea was to do the same with the data structures in UVIslands, but there some concerns were raised that requires a different design than expected from a clean-up patch. Concerns raised about converting UVIslands: * Maps between UVPrimitive, UVEdge and UVVertex will be stored inside the UVIsland. During UVIsland extraction detected islands can be merged. When they are merged all Indexes should be updated. * It is not possible to pre-allocate all buffers as they grow, what will lead to more re-allocations. The current implementation uses a VectorList to ensure that re-allocations don't require the data to be moved to the newly allocated memory. We could store some information about last used sizes in runtime data to reduce the re-allocation overhead. * Solution would require index based access inside a VectorList, which might increase the complexity. * UVIslands during 3d texturing is used as intermediate data, the final data is stored as PackedPixelRows. We could proceed converting UVIslands as well, but that would lower the performance noticeably. 3D texturing has performance requirements, so when doing so we should make sure that it matches that as well. Reviewed By: HooglyBoogly Maniphest Tasks: T101740 Differential Revision: https://developer.blender.org/D16752 --- source/blender/blenkernel/BKE_pbvh_pixels.hh | 2 +- .../blender/blenkernel/intern/pbvh_pixels.cc | 40 +- .../blenkernel/intern/pbvh_uv_islands.cc | 480 +++++++++--------- .../blenkernel/intern/pbvh_uv_islands.hh | 144 ++++-- 4 files changed, 366 insertions(+), 300 deletions(-) diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh index a6b5bb565c5..b6e006805ec 100644 --- a/source/blender/blenkernel/BKE_pbvh_pixels.hh +++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh @@ -51,7 +51,7 @@ struct PaintGeometryPrimitives { int64_t mem_size() const { - return size() * sizeof(int3); + return this->vert_indices.as_span().size_in_bytes(); } }; diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index 884da8b89f0..39651349ae9 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later * Copyright 2022 Blender Foundation. All rights reserved. */ +#include "BKE_attribute.hh" #include "BKE_customdata.h" #include "BKE_mesh.h" #include "BKE_mesh_mapping.h" @@ -105,10 +106,10 @@ static void update_geom_primitives(PBVH &pbvh, const uv_islands::MeshData &mesh_ { PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(pbvh); pbvh_data.clear_data(); - for (const uv_islands::MeshPrimitive &mesh_primitive : mesh_data.primitives) { - pbvh_data.geom_primitives.append(int3(mesh_primitive.vertices[0].vertex->v, - mesh_primitive.vertices[1].vertex->v, - mesh_primitive.vertices[2].vertex->v)); + for (const MLoopTri &looptri : mesh_data.looptris) { + pbvh_data.geom_primitives.append(int3(mesh_data.loops[looptri.tri[0]].v, + mesh_data.loops[looptri.tri[1]].v, + mesh_data.loops[looptri.tri[2]].v)); } } @@ -134,7 +135,7 @@ struct UVPrimitiveLookup { for (VectorList::UsedVector &uv_primitives : uv_island.uv_primitives) { for (uv_islands::UVPrimitive &uv_primitive : uv_primitives) { - lookup[uv_primitive.primitive->index].append_as(Entry(&uv_primitive, uv_island_index)); + lookup[uv_primitive.primitive_i].append_as(Entry(&uv_primitive, uv_island_index)); } } uv_island_index++; @@ -143,11 +144,11 @@ struct UVPrimitiveLookup { }; struct EncodePixelsUserData { + const uv_islands::MeshData *mesh_data; Image *image; ImageUser *image_user; PBVH *pbvh; Vector *nodes; - const float2 *ldata_uv; const uv_islands::UVIslandsMask *uv_masks; /** Lookup to retrieve the UV primitives based on the primitive index. */ const UVPrimitiveLookup *uv_primitive_lookup; @@ -158,6 +159,7 @@ static void do_encode_pixels(void *__restrict userdata, const TaskParallelTLS *__restrict /*tls*/) { EncodePixelsUserData *data = static_cast(userdata); + const uv_islands::MeshData &mesh_data = *data->mesh_data; Image *image = data->image; ImageUser image_user = *data->image_user; PBVHNode *node = (*data->nodes)[n]; @@ -183,9 +185,9 @@ static void do_encode_pixels(void *__restrict userdata, data->uv_primitive_lookup->lookup[geom_prim_index]) { uv_islands::UVBorder uv_border = entry.uv_primitive->extract_border(); float2 uvs[3] = { - entry.uv_primitive->get_uv_vertex(0)->uv - tile_offset, - entry.uv_primitive->get_uv_vertex(1)->uv - tile_offset, - entry.uv_primitive->get_uv_vertex(2)->uv - tile_offset, + entry.uv_primitive->get_uv_vertex(mesh_data, 0)->uv - tile_offset, + entry.uv_primitive->get_uv_vertex(mesh_data, 1)->uv - tile_offset, + entry.uv_primitive->get_uv_vertex(mesh_data, 2)->uv - tile_offset, }; const float minv = clamp_f(min_fff(uvs[0].y, uvs[1].y, uvs[2].y), 0.0f, 1.0f); const int miny = floor(minv * image_buffer->y); @@ -355,16 +357,16 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image return; } - const float2 *ldata_uv = static_cast( - CustomData_get_layer(&mesh->ldata, CD_PROP_FLOAT2)); - if (ldata_uv == nullptr) { + const StringRef active_uv_name = CustomData_get_active_layer_name(&mesh->ldata, CD_PROP_FLOAT2); + if (active_uv_name.is_empty()) { return; } - uv_islands::MeshData mesh_data({pbvh->looptri, pbvh->totprim}, - {pbvh->mloop, mesh->totloop}, - pbvh->totvert, - {ldata_uv, mesh->totloop}); + const AttributeAccessor attributes = mesh->attributes(); + const VArraySpan uv_map = attributes.lookup(active_uv_name, ATTR_DOMAIN_CORNER); + + uv_islands::MeshData mesh_data( + {pbvh->looptri, pbvh->totprim}, {pbvh->mloop, mesh->totloop}, pbvh->totvert, uv_map); uv_islands::UVIslands islands(mesh_data); uv_islands::UVIslandsMask uv_masks; @@ -380,20 +382,20 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image ushort2(tile_buffer->x, tile_buffer->y)); BKE_image_release_ibuf(image, tile_buffer, nullptr); } - uv_masks.add(islands); + uv_masks.add(mesh_data, islands); uv_masks.dilate(image->seam_margin); islands.extract_borders(); - islands.extend_borders(uv_masks); + islands.extend_borders(mesh_data, uv_masks); update_geom_primitives(*pbvh, mesh_data); UVPrimitiveLookup uv_primitive_lookup(mesh_data.looptris.size(), islands); EncodePixelsUserData user_data; + user_data.mesh_data = &mesh_data; user_data.pbvh = pbvh; user_data.image = image; user_data.image_user = image_user; - user_data.ldata_uv = ldata_uv; user_data.nodes = &nodes_to_update; user_data.uv_primitive_lookup = &uv_primitive_lookup; user_data.uv_masks = &uv_masks; diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index 5f4a888805e..aac61750d47 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -28,27 +28,40 @@ static void uv_primitive_append_to_uv_vertices(UVPrimitive &uv_primitive) } /* -------------------------------------------------------------------- */ -/** \name MeshPrimitive +/** \name Mesh Primitives * \{ */ -MeshUVVert *MeshPrimitive::get_other_uv_vertex(const MeshVertex *v1, const MeshVertex *v2) +int primitive_get_other_uv_vertex(const MeshData &mesh_data, + const MLoopTri &looptri, + const int v1, + const int v2) { - BLI_assert(vertices[0].vertex == v1 || vertices[1].vertex == v1 || vertices[2].vertex == v1); - BLI_assert(vertices[0].vertex == v2 || vertices[1].vertex == v2 || vertices[2].vertex == v2); - for (MeshUVVert &uv_vertex : vertices) { - if (!ELEM(uv_vertex.vertex, v1, v2)) { - return &uv_vertex; + const Span mesh_loops = mesh_data.loops; + BLI_assert(ELEM(v1, + mesh_loops[looptri.tri[0]].v, + mesh_loops[looptri.tri[1]].v, + mesh_loops[looptri.tri[2]].v)); + BLI_assert(ELEM(v2, + mesh_loops[looptri.tri[0]].v, + mesh_loops[looptri.tri[1]].v, + mesh_loops[looptri.tri[2]].v)); + for (const int loop : looptri.tri) { + const int vert = mesh_loops[loop].v; + if (vert != v1 && vert != v2) { + return vert; } } - return nullptr; + return -1; } -bool MeshPrimitive::has_shared_uv_edge(const MeshPrimitive *other) const +bool primitive_has_shared_uv_edge(const Span uv_map, + const MLoopTri &looptri, + const MLoopTri &other) { int shared_uv_verts = 0; - for (const MeshUVVert &vert : vertices) { - for (const MeshUVVert &other_vert : other->vertices) { - if (vert.uv == other_vert.uv) { + for (const int loop : looptri.tri) { + for (const int other_loop : other.tri) { + if (uv_map[loop] == uv_map[other_loop]) { shared_uv_verts += 1; } } @@ -56,33 +69,34 @@ bool MeshPrimitive::has_shared_uv_edge(const MeshPrimitive *other) const return shared_uv_verts >= 2; } -static const MeshUVVert &get_uv_vert(const MeshPrimitive &mesh_primitive, const MeshVertex *vert) +static int get_uv_loop(const MeshData &mesh_data, const MLoopTri &looptri, const int vert) { - for (const MeshUVVert &uv_vert : mesh_primitive.vertices) { - if (uv_vert.vertex == vert) { - return uv_vert; + for (const int loop : looptri.tri) { + if (mesh_data.loops[loop].v == vert) { + return loop; } } BLI_assert_unreachable(); - return mesh_primitive.vertices[0]; + return looptri.tri[0]; } -static bool has_vertex(const MeshPrimitive &mesh_primitive, const MeshVertex &mesh_vertex) +static bool has_vertex(const MeshData &mesh_data, const MLoopTri &looptri, const int vert) { for (int i = 0; i < 3; i++) { - if (mesh_primitive.vertices[i].vertex == &mesh_vertex) { + const int vert_i = mesh_data.loops[looptri.tri[i]].v; + if (vert_i == vert) { return true; } } return false; } -rctf MeshPrimitive::uv_bounds() const +rctf primitive_uv_bounds(const MLoopTri &looptri, const Span uv_map) { rctf result; BLI_rctf_init_minmax(&result); - for (const MeshUVVert &uv_vertex : vertices) { - BLI_rctf_do_minmax_v(&result, uv_vertex.uv); + for (const int loop : looptri.tri) { + BLI_rctf_do_minmax_v(&result, uv_map[loop]); } return result; } @@ -93,43 +107,13 @@ rctf MeshPrimitive::uv_bounds() const /** \name MeshData * \{ */ -static void mesh_data_init_vertices(MeshData &mesh_data) -{ - mesh_data.vertices.reserve(mesh_data.verts_num); - for (int64_t i = 0; i < mesh_data.verts_num; i++) { - MeshVertex vert; - vert.v = i; - mesh_data.vertices.append(vert); - } -} - -static void mesh_data_init_primitives(MeshData &mesh_data) -{ - mesh_data.primitives.reserve(mesh_data.looptris.size()); - for (int64_t i = 0; i < mesh_data.looptris.size(); i++) { - const MLoopTri &tri = mesh_data.looptris[i]; - MeshPrimitive primitive; - primitive.index = i; - primitive.poly = tri.poly; - - for (int j = 0; j < 3; j++) { - MeshUVVert uv_vert; - uv_vert.loop = tri.tri[j]; - uv_vert.vertex = &mesh_data.vertices[mesh_data.loops[uv_vert.loop].v]; - uv_vert.uv = mesh_data.mloopuv[uv_vert.loop]; - primitive.vertices.append(uv_vert); - } - mesh_data.primitives.append(primitive); - } -} - static void mesh_data_init_edges(MeshData &mesh_data) { mesh_data.edges.reserve(mesh_data.looptris.size() * 2); EdgeHash *eh = BLI_edgehash_new_ex(__func__, mesh_data.looptris.size() * 3); for (int64_t i = 0; i < mesh_data.looptris.size(); i++) { const MLoopTri &tri = mesh_data.looptris[i]; - MeshPrimitive &primitive = mesh_data.primitives[i]; + Vector edges; for (int j = 0; j < 3; j++) { int v1 = mesh_data.loops[tri.tri[j]].v; int v2 = mesh_data.loops[tri.tri[(j + 1) % 3]].v; @@ -144,82 +128,96 @@ static void mesh_data_init_edges(MeshData &mesh_data) edge_index = mesh_data.edges.size(); *edge_index_ptr = POINTER_FROM_INT(edge_index + 1); MeshEdge edge; - edge.vert1 = &mesh_data.vertices[v1]; - edge.vert2 = &mesh_data.vertices[v2]; + edge.vert1 = v1; + edge.vert2 = v2; mesh_data.edges.append(edge); - MeshEdge *edge_ptr = &mesh_data.edges.last(); - mesh_data.vertices[v1].edges.append(edge_ptr); - mesh_data.vertices[v2].edges.append(edge_ptr); + mesh_data.vert_to_edge_map.add(edge_index, v1, v2); } - MeshEdge *edge = &mesh_data.edges[edge_index]; - edge->primitives.append(&primitive); - primitive.edges.append(edge); + edges.append(edge_index); + } + mesh_data.primitive_to_edge_map.add(edges, i); + } + /* Build edge to neighboring triangle map. */ + mesh_data.edge_to_primitive_map = EdgeToPrimitiveMap(mesh_data.edges.size()); + for (const int prim_i : mesh_data.looptris.index_range()) { + for (const int edge_i : mesh_data.primitive_to_edge_map[prim_i]) { + mesh_data.edge_to_primitive_map.add(prim_i, edge_i); } } + BLI_edgehash_free(eh, nullptr); } -static const int64_t INVALID_UV_ISLAND_ID = -1; +static constexpr int INVALID_UV_ISLAND_ID = -1; /** * NOTE: doesn't support weird topology where unconnected mesh primitives share the same uv * island. For a accurate implementation we should use implement an uv_prim_lookup. */ -static void extract_uv_neighbors(Vector &prims_to_add, MeshPrimitive *primitive) +static void extract_uv_neighbors(const MeshData &mesh_data, + const Span uv_island_ids, + const int primitive_i, + Vector &prims_to_add) { - for (MeshEdge *edge : primitive->edges) { - for (MeshPrimitive *other_primitive : edge->primitives) { - if (primitive == other_primitive) { + for (const int edge : mesh_data.primitive_to_edge_map[primitive_i]) { + for (const int other_primitive_i : mesh_data.edge_to_primitive_map[edge]) { + if (primitive_i == other_primitive_i) { continue; } - if (other_primitive->uv_island_id != INVALID_UV_ISLAND_ID) { + if (uv_island_ids[other_primitive_i] != INVALID_UV_ISLAND_ID) { continue; } - if (primitive->has_shared_uv_edge(other_primitive)) { - prims_to_add.append(other_primitive); + if (primitive_has_shared_uv_edge(mesh_data.uv_map, + mesh_data.looptris[primitive_i], + mesh_data.looptris[other_primitive_i])) { + prims_to_add.append(other_primitive_i); } } } } -static void mesh_data_init_primitive_uv_island_ids(MeshData &mesh_data) +static int mesh_data_init_primitive_uv_island_ids(MeshData &mesh_data) { - for (MeshPrimitive &primitive : mesh_data.primitives) { - primitive.uv_island_id = INVALID_UV_ISLAND_ID; - } + mesh_data.uv_island_ids.reinitialize(mesh_data.looptris.size()); + mesh_data.uv_island_ids.fill(INVALID_UV_ISLAND_ID); - int64_t uv_island_id = 0; - Vector prims_to_add; - for (MeshPrimitive &primitive : mesh_data.primitives) { + int uv_island_id = 0; + Vector prims_to_add; + for (const int primitive_i : mesh_data.looptris.index_range()) { /* Early exit when uv island id is already extracted during uv neighbor extractions. */ - if (primitive.uv_island_id != INVALID_UV_ISLAND_ID) { + if (mesh_data.uv_island_ids[primitive_i] != INVALID_UV_ISLAND_ID) { continue; } - prims_to_add.append(&primitive); + prims_to_add.append(primitive_i); while (!prims_to_add.is_empty()) { - MeshPrimitive *primitive = prims_to_add.pop_last(); - primitive->uv_island_id = uv_island_id; - extract_uv_neighbors(prims_to_add, primitive); + const int other_primitive_i = prims_to_add.pop_last(); + mesh_data.uv_island_ids[other_primitive_i] = uv_island_id; + extract_uv_neighbors(mesh_data, mesh_data.uv_island_ids, other_primitive_i, prims_to_add); } uv_island_id++; } - mesh_data.uv_island_len = uv_island_id; + + return uv_island_id; } static void mesh_data_init(MeshData &mesh_data) { - mesh_data_init_vertices(mesh_data); - mesh_data_init_primitives(mesh_data); mesh_data_init_edges(mesh_data); - mesh_data_init_primitive_uv_island_ids(mesh_data); + mesh_data.uv_island_len = mesh_data_init_primitive_uv_island_ids(mesh_data); } MeshData::MeshData(const Span looptris, const Span loops, const int verts_num, - const Span mloopuv) - : looptris(looptris), verts_num(verts_num), loops(loops), mloopuv(mloopuv) + const Span uv_map) + : looptris(looptris), + verts_num(verts_num), + loops(loops), + uv_map(uv_map), + vert_to_edge_map(verts_num), + edge_to_primitive_map(0), + primitive_to_edge_map(looptris.size()) { mesh_data_init(*this); } @@ -241,7 +239,8 @@ UVVertex::UVVertex() uv_vertex_init_flags(*this); } -UVVertex::UVVertex(const MeshUVVert &vert) : vertex(vert.vertex), uv(vert.uv) +UVVertex::UVVertex(const MeshData &mesh_data, const int loop) + : vertex(mesh_data.loops[loop].v), uv(mesh_data.uv_map[loop]) { uv_vertex_init_flags(*this); } @@ -252,10 +251,10 @@ UVVertex::UVVertex(const MeshUVVert &vert) : vertex(vert.vertex), uv(vert.uv) /** \name UVEdge * \{ */ -bool UVEdge::has_shared_edge(const MeshUVVert &v1, const MeshUVVert &v2) const +bool UVEdge::has_shared_edge(const Span uv_map, const int loop_1, const int loop_2) const { - return (vertices[0]->uv == v1.uv && vertices[1]->uv == v2.uv) || - (vertices[0]->uv == v2.uv && vertices[1]->uv == v1.uv); + return (vertices[0]->uv == uv_map[loop_1] && vertices[1]->uv == uv_map[loop_2]) || + (vertices[0]->uv == uv_map[loop_2] && vertices[1]->uv == uv_map[loop_1]); } bool UVEdge::has_shared_edge(const UVVertex &v1, const UVVertex &v2) const @@ -269,22 +268,21 @@ bool UVEdge::has_shared_edge(const UVEdge &other) const return has_shared_edge(*other.vertices[0], *other.vertices[1]); } -bool UVEdge::has_same_vertices(const MeshVertex &vert1, const MeshVertex &vert2) const +bool UVEdge::has_same_vertices(const int vert1, const int vert2) const { - return (vertices[0]->vertex == &vert1 && vertices[1]->vertex == &vert2) || - (vertices[0]->vertex == &vert2 && vertices[1]->vertex == &vert1); + return (vertices[0]->vertex == vert1 && vertices[1]->vertex == vert2) || + (vertices[0]->vertex == vert2 && vertices[1]->vertex == vert1); } bool UVEdge::has_same_uv_vertices(const UVEdge &other) const { return has_shared_edge(other) && - has_same_vertices(*other.vertices[0]->vertex, *other.vertices[1]->vertex); - ; + has_same_vertices(other.vertices[0]->vertex, other.vertices[1]->vertex); } bool UVEdge::has_same_vertices(const MeshEdge &edge) const { - return has_same_vertices(*edge.vert1, *edge.vert2); + return has_same_vertices(edge.vert1, edge.vert2); } bool UVEdge::is_border_edge() const @@ -292,7 +290,7 @@ bool UVEdge::is_border_edge() const return uv_primitives.size() == 1; } -UVVertex *UVEdge::get_other_uv_vertex(const MeshVertex *vertex) +UVVertex *UVEdge::get_other_uv_vertex(const int vertex) { if (vertices[0]->vertex == vertex) { return vertices[1]; @@ -307,7 +305,7 @@ UVVertex *UVEdge::get_other_uv_vertex(const MeshVertex *vertex) * \{ */ UVVertex *UVIsland::lookup(const UVVertex &vertex) { - int64_t vert_index = vertex.vertex->v; + const int vert_index = vertex.vertex; Vector &vertices = uv_vertex_lookup.lookup_or_add_default(vert_index); for (UVVertex *v : vertices) { if (v->uv == vertex.uv) { @@ -328,7 +326,7 @@ UVVertex *UVIsland::lookup_or_create(const UVVertex &vertex) UVVertex *result = &uv_vertices.last(); result->uv_edges.clear(); /* v is already a key. Ensured by UVIsland::lookup in this method. */ - uv_vertex_lookup.lookup(vertex.vertex->v).append(result); + uv_vertex_lookup.lookup(vertex.vertex).append(result); return result; } @@ -388,11 +386,11 @@ bool UVIsland::has_shared_edge(const UVPrimitive &primitive) const return false; } -bool UVIsland::has_shared_edge(const MeshPrimitive &primitive) const +bool UVIsland::has_shared_edge(const MeshData &mesh_data, const int primitive_i) const { for (const VectorList::UsedVector &primitives : uv_primitives) { for (const UVPrimitive &prim : primitives) { - if (prim.has_shared_edge(primitive)) { + if (prim.has_shared_edge(mesh_data, primitive_i)) { return true; } } @@ -405,23 +403,27 @@ void UVIsland::extend_border(const UVPrimitive &primitive) for (const VectorList::UsedVector &primitives : uv_primitives) { for (const UVPrimitive &prim : primitives) { if (prim.has_shared_edge(primitive)) { - append(primitive); + this->append(primitive); } } } } -static UVPrimitive *add_primitive(UVIsland &uv_island, MeshPrimitive &primitive) +static UVPrimitive *add_primitive(const MeshData &mesh_data, + UVIsland &uv_island, + const int primitive_i) { - UVPrimitive uv_primitive(&primitive); + UVPrimitive uv_primitive(primitive_i); + const MLoopTri &primitive = mesh_data.looptris[primitive_i]; uv_island.uv_primitives.append(uv_primitive); UVPrimitive *uv_primitive_ptr = &uv_island.uv_primitives.last(); - for (MeshEdge *edge : primitive.edges) { - const MeshUVVert &v1 = get_uv_vert(primitive, edge->vert1); - const MeshUVVert &v2 = get_uv_vert(primitive, edge->vert2); + for (const int edge_i : mesh_data.primitive_to_edge_map[primitive_i]) { + const MeshEdge &edge = mesh_data.edges[edge_i]; + const int loop_1 = get_uv_loop(mesh_data, primitive, edge.vert1); + const int loop_2 = get_uv_loop(mesh_data, primitive, edge.vert2); UVEdge uv_edge_template; - uv_edge_template.vertices[0] = uv_island.lookup_or_create(UVVertex(v1)); - uv_edge_template.vertices[1] = uv_island.lookup_or_create(UVVertex(v2)); + uv_edge_template.vertices[0] = uv_island.lookup_or_create(UVVertex(mesh_data, loop_1)); + uv_edge_template.vertices[1] = uv_island.lookup_or_create(UVVertex(mesh_data, loop_2)); UVEdge *uv_edge = uv_island.lookup_or_create(uv_edge_template); uv_primitive_ptr->edges.append(uv_edge); uv_edge_append_to_uv_vertices(*uv_edge); @@ -493,7 +495,7 @@ static std::optional sharpest_border_corner(UVIsland &island) /** The inner edge of a fan. */ struct InnerEdge { - MeshPrimitive *primitive; + const MLoopTri *primitive; /* UVs order are already applied. So `uvs[0]` matches `primitive->vertices[vert_order[0]]`. */ float2 uvs[3]; int vert_order[3]; @@ -502,23 +504,24 @@ struct InnerEdge { bool found : 1; } flags; - InnerEdge(MeshPrimitive *primitive, MeshVertex *vertex) : primitive(primitive) + InnerEdge(const MeshData &mesh_data, const MLoopTri *primitive, int vertex) + : primitive(primitive) { flags.found = false; /* Reorder so the first edge starts with the given vertex. */ - if (primitive->vertices[1].vertex == vertex) { + if (mesh_data.loops[primitive->tri[1]].v == vertex) { vert_order[0] = 1; vert_order[1] = 2; vert_order[2] = 0; } - else if (primitive->vertices[2].vertex == vertex) { + else if (mesh_data.loops[primitive->tri[2]].v == vertex) { vert_order[0] = 2; vert_order[1] = 0; vert_order[2] = 1; } else { - BLI_assert(primitive->vertices[0].vertex == vertex); + BLI_assert(mesh_data.loops[primitive->tri[0]].v == vertex); vert_order[0] = 0; vert_order[1] = 1; vert_order[2] = 2; @@ -539,29 +542,32 @@ struct Fan { } flags; - Fan(MeshVertex &vertex) + Fan(const MeshData &mesh_data, const int vertex) { flags.full = true; - MeshEdge *current_edge = vertex.edges[0]; - MeshPrimitive *stop_primitive = current_edge->primitives[0]; - MeshPrimitive *previous_primitive = stop_primitive; + int current_edge = mesh_data.vert_to_edge_map[vertex].first(); + const int stop_primitive = mesh_data.edge_to_primitive_map[current_edge].first(); + int previous_primitive = stop_primitive; while (true) { bool stop = false; - for (MeshPrimitive *other : current_edge->primitives) { + for (const int other_primitive_i : mesh_data.edge_to_primitive_map[current_edge]) { if (stop) { break; } - if (other == previous_primitive) { + if (other_primitive_i == previous_primitive) { continue; } - for (MeshEdge *edge : other->edges) { - if (edge == current_edge || (edge->vert1 != &vertex && edge->vert2 != &vertex)) { + const MLoopTri &other_looptri = mesh_data.looptris[other_primitive_i]; + + for (const int edge_i : mesh_data.primitive_to_edge_map[other_primitive_i]) { + const MeshEdge &edge = mesh_data.edges[edge_i]; + if (edge_i == current_edge || (edge.vert1 != vertex && edge.vert2 != vertex)) { continue; } - inner_edges.append(InnerEdge(other, &vertex)); - current_edge = edge; - previous_primitive = other; + inner_edges.append(InnerEdge(mesh_data, &other_looptri, vertex)); + current_edge = edge_i; + previous_primitive = other_primitive_i; stop = true; break; } @@ -587,15 +593,15 @@ struct Fan { return result; } - void mark_already_added_segments(const UVVertex &uv_vertex) + void mark_already_added_segments(const MeshData &mesh_data, const UVVertex &uv_vertex) { for (InnerEdge &fan_edge : inner_edges) { fan_edge.flags.found = false; - const MeshVertex *v0 = fan_edge.primitive->vertices[fan_edge.vert_order[0]].vertex; - const MeshVertex *v1 = fan_edge.primitive->vertices[fan_edge.vert_order[1]].vertex; + const int v0 = mesh_data.loops[fan_edge.primitive->tri[fan_edge.vert_order[0]]].v; + const int v1 = mesh_data.loops[fan_edge.primitive->tri[fan_edge.vert_order[1]]].v; for (const UVEdge *edge : uv_vertex.uv_edges) { - const MeshVertex *e0 = edge->vertices[0]->vertex; - const MeshVertex *e1 = edge->vertices[1]->vertex; + const int e0 = edge->vertices[0]->vertex; + const int e1 = edge->vertices[1]->vertex; if ((e0 == v0 && e1 == v1) || (e0 == v1 && e1 == v0)) { fan_edge.flags.found = true; break; @@ -604,17 +610,17 @@ struct Fan { } } - void init_uv_coordinates(UVVertex &uv_vertex) + void init_uv_coordinates(const MeshData &mesh_data, UVVertex &uv_vertex) { for (InnerEdge &fan_edge : inner_edges) { - int64_t other_v = fan_edge.primitive->vertices[fan_edge.vert_order[0]].vertex->v; - if (other_v == uv_vertex.vertex->v) { - other_v = fan_edge.primitive->vertices[fan_edge.vert_order[1]].vertex->v; + int other_v = mesh_data.loops[fan_edge.primitive->tri[fan_edge.vert_order[0]]].v; + if (other_v == uv_vertex.vertex) { + other_v = mesh_data.loops[fan_edge.primitive->tri[fan_edge.vert_order[1]]].v; } for (UVEdge *edge : uv_vertex.uv_edges) { const UVVertex *other_uv_vertex = edge->get_other_uv_vertex(uv_vertex.vertex); - int64_t other_edge_v = other_uv_vertex->vertex->v; + int64_t other_edge_v = other_uv_vertex->vertex; if (other_v == other_edge_v) { fan_edge.uvs[0] = uv_vertex.uv; fan_edge.uvs[1] = other_uv_vertex->uv; @@ -630,29 +636,31 @@ struct Fan { } }; -static void add_uv_primitive_shared_uv_edge(UVIsland &island, +static void add_uv_primitive_shared_uv_edge(const MeshData &mesh_data, + UVIsland &island, UVVertex *connected_vert_1, UVVertex *connected_vert_2, float2 uv_unconnected, - MeshPrimitive *mesh_primitive) + const int mesh_primitive_i) { - UVPrimitive prim1(mesh_primitive); + UVPrimitive prim1(mesh_primitive_i); + const MLoopTri &looptri = mesh_data.looptris[mesh_primitive_i]; - MeshUVVert *other_vert = mesh_primitive->get_other_uv_vertex(connected_vert_1->vertex, - connected_vert_2->vertex); + const int other_vert_i = primitive_get_other_uv_vertex( + mesh_data, looptri, connected_vert_1->vertex, connected_vert_2->vertex); UVVertex vert_template; vert_template.uv = uv_unconnected; - vert_template.vertex = other_vert->vertex; + vert_template.vertex = other_vert_i; UVVertex *vert_ptr = island.lookup_or_create(vert_template); - const MeshUVVert *mesh_vert_1 = &get_uv_vert(*mesh_primitive, connected_vert_1->vertex); + const int loop_1 = get_uv_loop(mesh_data, looptri, connected_vert_1->vertex); vert_template.uv = connected_vert_1->uv; - vert_template.vertex = mesh_vert_1->vertex; + vert_template.vertex = mesh_data.loops[loop_1].v; UVVertex *vert_1_ptr = island.lookup_or_create(vert_template); - const MeshUVVert *mesh_vert_2 = &get_uv_vert(*mesh_primitive, connected_vert_2->vertex); + const int loop_2 = get_uv_loop(mesh_data, looptri, connected_vert_2->vertex); vert_template.uv = connected_vert_2->uv; - vert_template.vertex = mesh_vert_2->vertex; + vert_template.vertex = mesh_data.loops[loop_2].v; UVVertex *vert_2_ptr = island.lookup_or_create(vert_template); UVEdge edge_template; @@ -670,52 +678,55 @@ static void add_uv_primitive_shared_uv_edge(UVIsland &island, island.uv_primitives.append(prim1); } -static MeshPrimitive *find_fill_border(const MeshVertex &v1, - const MeshVertex &v2, - const MeshVertex &v3) +static int find_fill_border(const MeshData &mesh_data, const int v1, const int v2, const int v3) { - for (MeshEdge *edge : v1.edges) { - for (MeshPrimitive *primitive : edge->primitives) { - if (has_vertex(*primitive, v1) && has_vertex(*primitive, v2) && has_vertex(*primitive, v3)) { - return primitive; + for (const int edge_i : mesh_data.vert_to_edge_map[v1]) { + for (const int primitive_i : mesh_data.edge_to_primitive_map[edge_i]) { + const MLoopTri &looptri = mesh_data.looptris[primitive_i]; + if (has_vertex(mesh_data, looptri, v1) && has_vertex(mesh_data, looptri, v2) && + has_vertex(mesh_data, looptri, v3)) { + return primitive_i; } } } - return nullptr; + return -1; } /** * Find a primitive that can be used to fill give corner. - * Will return nullptr when no primitive can be found. + * Will return -1 when no primitive can be found. */ -static MeshPrimitive *find_fill_border(UVBorderCorner &corner) +static int find_fill_border(const MeshData &mesh_data, UVBorderCorner &corner) { if (corner.first->get_uv_vertex(1) != corner.second->get_uv_vertex(0)) { - return nullptr; + return -1; } if (corner.first->get_uv_vertex(0) == corner.second->get_uv_vertex(1)) { - return nullptr; + return -1; } UVVertex *shared_vert = corner.second->get_uv_vertex(0); - for (MeshEdge *edge : shared_vert->vertex->edges) { - if (corner.first->edge->has_same_vertices(*edge)) { - for (MeshPrimitive *primitive : edge->primitives) { - MeshVertex *other_vert = primitive->get_other_uv_vertex(edge->vert1, edge->vert2)->vertex; + for (const int edge_i : mesh_data.vert_to_edge_map[shared_vert->vertex]) { + const MeshEdge &edge = mesh_data.edges[edge_i]; + if (corner.first->edge->has_same_vertices(edge)) { + for (const int primitive_i : mesh_data.edge_to_primitive_map[edge_i]) { + const MLoopTri &looptri = mesh_data.looptris[primitive_i]; + const int other_vert = primitive_get_other_uv_vertex( + mesh_data, looptri, edge.vert1, edge.vert2); if (other_vert == corner.second->get_uv_vertex(1)->vertex) { - return primitive; + return primitive_i; } } } } - return nullptr; + return -1; } static void add_uv_primitive_fill(UVIsland &island, UVVertex &uv_vertex1, UVVertex &uv_vertex2, UVVertex &uv_vertex3, - MeshPrimitive &fill_primitive) + const int fill_primitive_i) { - UVPrimitive uv_primitive(&fill_primitive); + UVPrimitive uv_primitive(fill_primitive_i); UVEdge edge_template; edge_template.vertices[0] = &uv_vertex1; edge_template.vertices[1] = &uv_vertex2; @@ -731,48 +742,53 @@ static void add_uv_primitive_fill(UVIsland &island, island.uv_primitives.append(uv_primitive); } -static void extend_at_vert(UVIsland &island, UVBorderCorner &corner, float min_uv_distance) +static void extend_at_vert(const MeshData &mesh_data, + UVIsland &island, + UVBorderCorner &corner, + float min_uv_distance) { int border_index = corner.first->border_index; UVBorder &border = island.borders[border_index]; UVVertex *uv_vertex = corner.second->get_uv_vertex(0); - Fan fan(*(uv_vertex->vertex)); + Fan fan(mesh_data, uv_vertex->vertex); if (!fan.flags.full) { return; } - fan.init_uv_coordinates(*uv_vertex); - fan.mark_already_added_segments(*uv_vertex); + fan.init_uv_coordinates(mesh_data, *uv_vertex); + fan.mark_already_added_segments(mesh_data, *uv_vertex); int num_to_add = fan.count_num_to_add(); if (num_to_add == 0) { - MeshPrimitive *fill_primitive_1 = corner.second->uv_primitive->primitive; - MeshPrimitive *fill_primitive_2 = corner.first->uv_primitive->primitive; + int fill_primitive_1_i = corner.second->uv_primitive->primitive_i; + int fill_primitive_2_i = corner.first->uv_primitive->primitive_i; - MeshPrimitive *fill_primitive = find_fill_border(corner); + const int fill_primitive_i = find_fill_border(mesh_data, corner); /* * Although the fill_primitive can fill the missing segment it could lead to a squashed * triangle when the corner angle is near 180 degrees. In order to fix this we will * always add two segments both using the same fill primitive. */ - if (fill_primitive) { - fill_primitive_1 = fill_primitive; - fill_primitive_2 = fill_primitive; + if (fill_primitive_i != -1) { + fill_primitive_1_i = fill_primitive_i; + fill_primitive_2_i = fill_primitive_i; } float2 center_uv = corner.uv(0.5f, min_uv_distance); - add_uv_primitive_shared_uv_edge(island, + add_uv_primitive_shared_uv_edge(mesh_data, + island, corner.first->get_uv_vertex(1), corner.first->get_uv_vertex(0), center_uv, - fill_primitive_1); + fill_primitive_1_i); UVPrimitive &new_prim_1 = island.uv_primitives.last(); - add_uv_primitive_shared_uv_edge(island, + add_uv_primitive_shared_uv_edge(mesh_data, + island, corner.second->get_uv_vertex(0), corner.second->get_uv_vertex(1), center_uv, - fill_primitive_2); + fill_primitive_2_i); UVPrimitive &new_prim_2 = island.uv_primitives.last(); /* Update border after adding the new geometry. */ @@ -798,8 +814,7 @@ static void extend_at_vert(UVIsland &island, UVBorderCorner &corner, float min_u for (int i = 0; i < num_to_add; i++) { float2 old_uv = current_edge->get_other_uv_vertex(uv_vertex->vertex)->uv; - MeshVertex *shared_edge_vertex = - current_edge->get_other_uv_vertex(uv_vertex->vertex)->vertex; + int shared_edge_vertex = current_edge->get_other_uv_vertex(uv_vertex->vertex)->vertex; float factor = (i + 1.0f) / (num_to_add + 1.0f); float2 new_uv = corner.uv(factor, min_uv_distance); @@ -811,15 +826,17 @@ static void extend_at_vert(UVIsland &island, UVBorderCorner &corner, float min_u } /* Find primitive that shares the current edge and the segment edge. */ - MeshPrimitive *fill_primitive = find_fill_border( - *uv_vertex->vertex, - *shared_edge_vertex, - *segment.primitive->vertices[segment.vert_order[1]].vertex); - if (fill_primitive == nullptr) { + const int fill_primitive_i = find_fill_border( + mesh_data, + uv_vertex->vertex, + shared_edge_vertex, + mesh_data.loops[segment.primitive->tri[segment.vert_order[1]]].v); + if (fill_primitive_i == -1) { continue; } - MeshVertex *other_prim_vertex = - fill_primitive->get_other_uv_vertex(uv_vertex->vertex, shared_edge_vertex)->vertex; + const MLoopTri &fill_primitive = mesh_data.looptris[fill_primitive_i]; + const int other_prim_vertex = primitive_get_other_uv_vertex( + mesh_data, fill_primitive, uv_vertex->vertex, shared_edge_vertex); UVVertex uv_vertex_template; uv_vertex_template.vertex = uv_vertex->vertex; @@ -833,7 +850,7 @@ static void extend_at_vert(UVIsland &island, UVBorderCorner &corner, float min_u UVVertex *vertex_3_ptr = island.lookup_or_create(uv_vertex_template); add_uv_primitive_fill( - island, *vertex_1_ptr, *vertex_2_ptr, *vertex_3_ptr, *fill_primitive); + island, *vertex_1_ptr, *vertex_2_ptr, *vertex_3_ptr, fill_primitive_i); segment.flags.found = true; @@ -849,13 +866,15 @@ static void extend_at_vert(UVIsland &island, UVBorderCorner &corner, float min_u { /* Add final segment. */ float2 old_uv = current_edge->get_other_uv_vertex(uv_vertex->vertex)->uv; - MeshVertex *shared_edge_vertex = - current_edge->get_other_uv_vertex(uv_vertex->vertex)->vertex; - MeshPrimitive *fill_primitive = find_fill_border( - *uv_vertex->vertex, *shared_edge_vertex, *corner.second->get_uv_vertex(1)->vertex); - if (fill_primitive) { - MeshVertex *other_prim_vertex = - fill_primitive->get_other_uv_vertex(uv_vertex->vertex, shared_edge_vertex)->vertex; + int shared_edge_vertex = current_edge->get_other_uv_vertex(uv_vertex->vertex)->vertex; + const int fill_primitive_i = find_fill_border(mesh_data, + uv_vertex->vertex, + shared_edge_vertex, + corner.second->get_uv_vertex(1)->vertex); + if (fill_primitive_i != -1) { + const MLoopTri &fill_primitive = mesh_data.looptris[fill_primitive_i]; + const int other_prim_vertex = primitive_get_other_uv_vertex( + mesh_data, fill_primitive, uv_vertex->vertex, shared_edge_vertex); UVVertex uv_vertex_template; uv_vertex_template.vertex = uv_vertex->vertex; @@ -868,7 +887,7 @@ static void extend_at_vert(UVIsland &island, UVBorderCorner &corner, float min_u uv_vertex_template.uv = corner.second->get_uv_vertex(1)->uv; UVVertex *vertex_3_ptr = island.lookup_or_create(uv_vertex_template); add_uv_primitive_fill( - island, *vertex_1_ptr, *vertex_2_ptr, *vertex_3_ptr, *fill_primitive); + island, *vertex_1_ptr, *vertex_2_ptr, *vertex_3_ptr, fill_primitive_i); UVPrimitive &new_prim = island.uv_primitives.last(); UVBorderEdge new_border(new_prim.get_uv_edge(shared_edge_vertex, other_prim_vertex), @@ -912,7 +931,9 @@ static void reset_extendability_flags(UVIsland &island) } } -void UVIsland::extend_border(const UVIslandsMask &mask, const short island_index) +void UVIsland::extend_border(const MeshData &mesh_data, + const UVIslandsMask &mask, + const short island_index) { reset_extendability_flags(*this); @@ -932,7 +953,8 @@ void UVIsland::extend_border(const UVIslandsMask &mask, const short island_index /* Found corner is outside the mask, the corner should not be considered for extension. */ const UVIslandsMask::Tile *tile = mask.find_tile(uv_vertex->uv); if (tile && tile->is_masked(island_index, uv_vertex->uv)) { - extend_at_vert(*this, *extension_corner, tile->get_pixel_size_in_uv_space() * 2.0f); + extend_at_vert( + mesh_data, *this, *extension_corner, tile->get_pixel_size_in_uv_space() * 2.0f); } /* Mark that the vert is extended. */ uv_vertex->flags.is_extended = true; @@ -1071,7 +1093,7 @@ float2 UVBorderCorner::uv(float factor, float min_uv_distance) /** \name UVPrimitive * \{ */ -UVPrimitive::UVPrimitive(MeshPrimitive *primitive) : primitive(primitive) +UVPrimitive::UVPrimitive(const int primitive_i) : primitive_i(primitive_i) { } @@ -1100,16 +1122,17 @@ bool UVPrimitive::has_shared_edge(const UVPrimitive &other) const return false; } -bool UVPrimitive::has_shared_edge(const MeshPrimitive &primitive) const +bool UVPrimitive::has_shared_edge(const MeshData &mesh_data, const int primitive_i) const { for (const UVEdge *uv_edge : edges) { - const MeshUVVert *v1 = &primitive.vertices.last(); - for (int i = 0; i < primitive.vertices.size(); i++) { - const MeshUVVert *v2 = &primitive.vertices[i]; - if (uv_edge->has_shared_edge(*v1, *v2)) { + const MLoopTri &primitive = mesh_data.looptris[primitive_i]; + int loop_1 = primitive.tri[2]; + for (int i = 0; i < 3; i++) { + int loop_2 = primitive.tri[i]; + if (uv_edge->has_shared_edge(mesh_data.uv_map, loop_1, loop_2)) { return true; } - v1 = v2; + loop_1 = loop_2; } } return false; @@ -1118,9 +1141,11 @@ bool UVPrimitive::has_shared_edge(const MeshPrimitive &primitive) const /** * Get the UVVertex in the order that the verts are ordered in the MeshPrimitive. */ -const UVVertex *UVPrimitive::get_uv_vertex(const uint8_t mesh_vert_index) const +const UVVertex *UVPrimitive::get_uv_vertex(const MeshData &mesh_data, + const uint8_t mesh_vert_index) const { - const MeshVertex *mesh_vertex = primitive->vertices[mesh_vert_index].vertex; + const MLoopTri &looptri = mesh_data.looptris[this->primitive_i]; + const int mesh_vertex = mesh_data.loops[looptri.tri[mesh_vert_index]].v; for (const UVEdge *uv_edge : edges) { for (const UVVertex *uv_vert : uv_edge->vertices) { if (uv_vert->vertex == mesh_vertex) { @@ -1149,11 +1174,11 @@ UVEdge *UVPrimitive::get_uv_edge(const float2 uv1, const float2 uv2) const return nullptr; } -UVEdge *UVPrimitive::get_uv_edge(const MeshVertex *v1, const MeshVertex *v2) const +UVEdge *UVPrimitive::get_uv_edge(const int v1, const int v2) const { for (UVEdge *uv_edge : edges) { - const MeshVertex *e1 = uv_edge->vertices[0]->vertex; - const MeshVertex *e2 = uv_edge->vertices[1]->vertex; + const int e1 = uv_edge->vertices[0]->vertex; + const int e2 = uv_edge->vertices[1]->vertex; if ((e1 == v1 && e2 == v2) || (e1 == v2 && e2 == v1)) { return uv_edge; } @@ -1238,16 +1263,16 @@ float UVBorderEdge::length() const /** \name UVIslands * \{ */ -UVIslands::UVIslands(MeshData &mesh_data) +UVIslands::UVIslands(const MeshData &mesh_data) { islands.reserve(mesh_data.uv_island_len); for (int64_t uv_island_id = 0; uv_island_id < mesh_data.uv_island_len; uv_island_id++) { islands.append_as(UVIsland()); UVIsland *uv_island = &islands.last(); - for (MeshPrimitive &primitive : mesh_data.primitives) { - if (primitive.uv_island_id == uv_island_id) { - add_primitive(*uv_island, primitive); + for (const int primitive_i : mesh_data.looptris.index_range()) { + if (mesh_data.uv_island_ids[primitive_i] == uv_island_id) { + add_primitive(mesh_data, *uv_island, primitive_i); } } } @@ -1260,11 +1285,11 @@ void UVIslands::extract_borders() } } -void UVIslands::extend_borders(const UVIslandsMask &islands_mask) +void UVIslands::extend_borders(const MeshData &mesh_data, const UVIslandsMask &islands_mask) { ushort index = 0; for (UVIsland &island : islands) { - island.extend_border(islands_mask, index++); + island.extend_border(mesh_data, islands_mask, index++); } } @@ -1299,15 +1324,16 @@ float UVIslandsMask::Tile::get_pixel_size_in_uv_space() const return min_ff(1.0f / tile_resolution.x, 1.0f / tile_resolution.y); } -static void add_uv_island(UVIslandsMask::Tile &tile, +static void add_uv_island(const MeshData &mesh_data, + UVIslandsMask::Tile &tile, const UVIsland &uv_island, int16_t island_index) { for (const VectorList::UsedVector &uv_primitives : uv_island.uv_primitives) { for (const UVPrimitive &uv_primitive : uv_primitives) { - const MeshPrimitive *mesh_primitive = uv_primitive.primitive; + const MLoopTri &looptri = mesh_data.looptris[uv_primitive.primitive_i]; - rctf uv_bounds = mesh_primitive->uv_bounds(); + rctf uv_bounds = primitive_uv_bounds(looptri, mesh_data.uv_map); rcti buffer_bounds; buffer_bounds.xmin = max_ii( floor((uv_bounds.xmin - tile.udim_offset.x) * tile.mask_resolution.x), 0); @@ -1324,9 +1350,9 @@ static void add_uv_island(UVIslandsMask::Tile &tile, for (int x = buffer_bounds.xmin; x < buffer_bounds.xmax + 1; x++) { float2 uv(float(x) / tile.mask_resolution.x, float(y) / tile.mask_resolution.y); float3 weights; - barycentric_weights_v2(mesh_primitive->vertices[0].uv, - mesh_primitive->vertices[1].uv, - mesh_primitive->vertices[2].uv, + barycentric_weights_v2(mesh_data.uv_map[looptri.tri[0]], + mesh_data.uv_map[looptri.tri[1]], + mesh_data.uv_map[looptri.tri[2]], uv + tile.udim_offset, weights); if (!barycentric_inside_triangle_v2(weights)) { @@ -1341,11 +1367,11 @@ static void add_uv_island(UVIslandsMask::Tile &tile, } } -void UVIslandsMask::add(const UVIslands &uv_islands) +void UVIslandsMask::add(const MeshData &mesh_data, const UVIslands &uv_islands) { for (Tile &tile : tiles) { - for (int index = 0; index < uv_islands.islands.size(); index++) { - add_uv_island(tile, uv_islands.islands[index], index); + for (const int i : uv_islands.islands.index_range()) { + add_uv_island(mesh_data, tile, uv_islands.islands[i], i); } } } diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.hh b/source/blender/blenkernel/intern/pbvh_uv_islands.hh index db1b12cdcb3..b97d07a2146 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.hh +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.hh @@ -31,59 +31,86 @@ #include "BLI_rect.h" #include "BLI_vector.hh" #include "BLI_vector_list.hh" +#include "BLI_virtual_array.hh" #include "DNA_meshdata_types.h" namespace blender::bke::pbvh::uv_islands { struct MeshEdge; -struct MeshPrimitive; struct UVBorder; struct UVEdge; struct UVIslands; struct UVIslandsMask; struct UVPrimitive; struct UVPrimitiveEdge; +struct MeshData; struct UVVertex; -struct MeshVertex { - int64_t v; - Vector edges; -}; - -struct MeshUVVert { - MeshVertex *vertex; - float2 uv; - int64_t loop; -}; - struct MeshEdge { - MeshVertex *vert1; - MeshVertex *vert2; - Vector primitives; + int vert1; + int vert2; }; -/** Represents a triangle in 3d space (MLoopTri). */ -struct MeshPrimitive { - int64_t index; - int64_t poly; - Vector edges; - Vector vertices; +class VertToEdgeMap { + Array> edges_of_vert_; - /** - * UV island this primitive belongs to. This is used to speed up the initial uv island - * extraction and should not be used afterwards. - */ - int64_t uv_island_id; + public: + VertToEdgeMap() = delete; + VertToEdgeMap(const int verts_num) + { + edges_of_vert_.reinitialize(verts_num); + } - /** Get the vertex that is not given. Both given vertices must be part of the MeshPrimitive. */ - MeshUVVert *get_other_uv_vertex(const MeshVertex *v1, const MeshVertex *v2); + void add(const int edge_i, const int v1, const int v2) + { + edges_of_vert_[v1].append(edge_i); + edges_of_vert_[v2].append(edge_i); + } + Span operator[](const int vert_i) const + { + return edges_of_vert_[vert_i]; + } +}; - /** Get the UV bounds for this MeshPrimitive. */ - rctf uv_bounds() const; +class EdgeToPrimitiveMap { + Array> primitives_of_edge_; - /** Is the given MeshPrimitive sharing an edge. */ - bool has_shared_uv_edge(const MeshPrimitive *other) const; + public: + EdgeToPrimitiveMap() = delete; + EdgeToPrimitiveMap(const int edges_num) + { + primitives_of_edge_.reinitialize(edges_num); + } + + void add(const int primitive_i, const int edge_i) + { + primitives_of_edge_[edge_i].append(primitive_i); + } + Span operator[](const int edge_i) const + { + return primitives_of_edge_[edge_i]; + } +}; + +class TriangleToEdgeMap { + Array> edges_of_triangle_; + + public: + TriangleToEdgeMap() = delete; + TriangleToEdgeMap(const int edges_num) + { + edges_of_triangle_.reinitialize(edges_num); + } + + void add(const Span edges, const int tri_i) + { + std::copy(edges.begin(), edges.end(), edges_of_triangle_[tri_i].begin()); + } + Span operator[](const int tri_i) const + { + return edges_of_triangle_[tri_i]; + } }; /** @@ -95,23 +122,32 @@ struct MeshData { const Span looptris; const int64_t verts_num; const Span loops; - const Span mloopuv; + const Span uv_map; + + VertToEdgeMap vert_to_edge_map; - Vector primitives; Vector edges; - Vector vertices; + EdgeToPrimitiveMap edge_to_primitive_map; + + TriangleToEdgeMap primitive_to_edge_map; + + /** + * UV island each primitive belongs to. This is used to speed up the initial uv island + * extraction and should not be used afterwards. + */ + Array uv_island_ids; /** Total number of found uv islands. */ int64_t uv_island_len; public: - explicit MeshData(const Span looptris, - const Span loops, + explicit MeshData(Span looptris, + Span loops, const int verts_num, - const Span mloopuv); + const Span uv_map); }; struct UVVertex { - MeshVertex *vertex; + int vertex; /* Position in uv space. */ float2 uv; @@ -124,22 +160,22 @@ struct UVVertex { } flags; explicit UVVertex(); - explicit UVVertex(const MeshUVVert &vert); + explicit UVVertex(const MeshData &mesh_data, const int loop); }; struct UVEdge { std::array vertices; Vector uv_primitives; - UVVertex *get_other_uv_vertex(const MeshVertex *vertex); - bool has_shared_edge(const MeshUVVert &v1, const MeshUVVert &v2) const; + UVVertex *get_other_uv_vertex(const int vertex_index); + bool has_shared_edge(Span uv_map, const int loop_1, const int loop_2) const; bool has_shared_edge(const UVEdge &other) const; bool has_same_vertices(const MeshEdge &edge) const; bool is_border_edge() const; private: bool has_shared_edge(const UVVertex &v1, const UVVertex &v2) const; - bool has_same_vertices(const MeshVertex &vert1, const MeshVertex &vert2) const; + bool has_same_vertices(const int v1, const int v2) const; bool has_same_uv_vertices(const UVEdge &other) const; }; @@ -147,26 +183,26 @@ struct UVPrimitive { /** * Index of the primitive in the original mesh. */ - MeshPrimitive *primitive; + const int primitive_i; Vector edges; - explicit UVPrimitive(MeshPrimitive *primitive); + explicit UVPrimitive(const int primitive_i); Vector> shared_edges(UVPrimitive &other); bool has_shared_edge(const UVPrimitive &other) const; - bool has_shared_edge(const MeshPrimitive &primitive) const; + bool has_shared_edge(const MeshData &mesh_data, int other_triangle_index) const; /** * Get the UVVertex in the order that the verts are ordered in the MeshPrimitive. */ - const UVVertex *get_uv_vertex(const uint8_t mesh_vert_index) const; + const UVVertex *get_uv_vertex(const MeshData &mesh_data, const uint8_t mesh_vert_index) const; /** * Get the UVEdge that share the given uv coordinates. * Will assert when no UVEdge found. */ UVEdge *get_uv_edge(const float2 uv1, const float2 uv2) const; - UVEdge *get_uv_edge(const MeshVertex *v1, const MeshVertex *v2) const; + UVEdge *get_uv_edge(const int v1, const int v2) const; bool contains_uv_vertex(const UVVertex *uv_vertex) const; const UVVertex *get_other_uv_vertex(const UVVertex *v1, const UVVertex *v2) const; @@ -266,24 +302,26 @@ struct UVIsland { /** Initialize the border attribute. */ void extract_borders(); /** Iterative extend border to fit the mask. */ - void extend_border(const UVIslandsMask &mask, const short island_index); + void extend_border(const MeshData &mesh_data, + const UVIslandsMask &mask, + const short island_index); private: void append(const UVPrimitive &primitive); public: bool has_shared_edge(const UVPrimitive &primitive) const; - bool has_shared_edge(const MeshPrimitive &primitive) const; + bool has_shared_edge(const MeshData &mesh_data, const int primitive_i) const; void extend_border(const UVPrimitive &primitive); }; struct UVIslands { Vector islands; - explicit UVIslands(MeshData &mesh_data); + explicit UVIslands(const MeshData &mesh_data); void extract_borders(); - void extend_borders(const UVIslandsMask &islands_mask); + void extend_borders(const MeshData &mesh_data, const UVIslandsMask &islands_mask); }; /** Mask to find the index of the UVIsland for a given UV coordinate. */ @@ -324,7 +362,7 @@ struct UVIslandsMask { * Add the given UVIslands to the mask. Tiles should be added beforehand using the 'add_tile' * method. */ - void add(const UVIslands &islands); + void add(const MeshData &mesh_data, const UVIslands &islands); void dilate(int max_iterations); }; From 3590e263e09d349f81e131bf80e6b21e0acf07a5 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 12 Jan 2023 08:39:42 +0100 Subject: [PATCH 0607/1522] macOS: Remove user notifications. User notifications in Blender were always annoying and therefore by default turned off. - When tweaking compositor/material tree a notification was shown. - When rendering an animation for each frame a notification was shown. The reason for this was that it was automatically shown when a background job was finished and Blender wasn't the top most application. In stead of migrating user notification to UserNotification.framework it was decided to remove it for now. If in the future notifications should be added back we should start with a design to figure out where notifications makes sense. Reviewed By: sergey, brecht Maniphest Tasks: T103757 Differential Revision: https://developer.blender.org/D16955 --- intern/ghost/intern/GHOST_WindowCocoa.mm | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 849e59cd809..3d0069874e2 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -895,22 +895,13 @@ GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress) return GHOST_kSuccess; } -static void postNotification() -{ - NSUserNotification *notification = [[NSUserNotification alloc] init]; - notification.title = @"Blender Progress Notification"; - notification.informativeText = @"Calculation is finished."; - notification.soundName = NSUserNotificationDefaultSoundName; - [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; - [notification release]; -} - GHOST_TSuccess GHOST_WindowCocoa::endProgressBar() { if (!m_progressBarVisible) return GHOST_kFailure; m_progressBarVisible = false; + /* Reset application icon to remove the progress bar. */ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSImage *dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128, 128)]; @@ -921,15 +912,6 @@ GHOST_TSuccess GHOST_WindowCocoa::endProgressBar() fraction:1.0]; [dockIcon unlockFocus]; [NSApp setApplicationIconImage:dockIcon]; - - // We use notifications to inform the user when the progress reached 100% - // Atm. just fire this when the progressbar ends, the behavior is controlled - // in the NotificationCenter If Blender is not frontmost window, a message - // pops up with sound, in any case an entry in notifications - if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)]) { - postNotification(); - } - [dockIcon release]; [pool drain]; From eeff49a3b18c4a2b25fd7462393cea36fe63d38a Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 12 Jan 2023 08:48:48 +0100 Subject: [PATCH 0608/1522] macOS: Replace PboardTypes with PasteboardTypes. Related to {T103758}. - NSStringPboardType is replaced by NSPasteboardTypeString - NSTIFFPboardType is replaced by NSPasteboardTypeTIFF --- intern/ghost/intern/GHOST_SystemCocoa.mm | 6 +++--- intern/ghost/intern/GHOST_WindowCocoa.mm | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index f8e86e1a720..9dabf704ad6 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1949,7 +1949,7 @@ char *GHOST_SystemCocoa::getClipboard(bool selection) const NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard]; - NSString *textPasted = [pasteBoard stringForType:NSStringPboardType]; + NSString *textPasted = [pasteBoard stringForType:NSPasteboardTypeString]; if (textPasted == nil) { return NULL; @@ -1984,8 +1984,8 @@ void GHOST_SystemCocoa::putClipboard(const char *buffer, bool selection) const @autoreleasepool { NSPasteboard *pasteBoard = NSPasteboard.generalPasteboard; - [pasteBoard declareTypes:@[ NSStringPboardType ] owner:nil]; + [pasteBoard declareTypes:@[ NSPasteboardTypeString ] owner:nil]; NSString *textToCopy = [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding]; - [pasteBoard setString:textToCopy forType:NSStringPboardType]; + [pasteBoard setString:textToCopy forType:NSPasteboardTypeString]; } } diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 3d0069874e2..dd25ce56cf8 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -172,11 +172,11 @@ NSPoint mouseLocation = [sender draggingLocation]; NSPasteboard *draggingPBoard = [sender draggingPasteboard]; - if ([[draggingPBoard types] containsObject:NSTIFFPboardType]) + if ([[draggingPBoard types] containsObject:NSPasteboardTypeTIFF]) m_draggedObjectType = GHOST_kDragnDropTypeBitmap; else if ([[draggingPBoard types] containsObject:NSFilenamesPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeFilenames; - else if ([[draggingPBoard types] containsObject:NSStringPboardType]) + else if ([[draggingPBoard types] containsObject:NSPasteboardTypeString]) m_draggedObjectType = GHOST_kDragnDropTypeString; else return NSDragOperationNone; @@ -235,7 +235,7 @@ case GHOST_kDragnDropTypeBitmap: if ([NSImage canInitWithPasteboard:draggingPBoard]) { droppedImg = [[NSImage alloc] initWithPasteboard:draggingPBoard]; - data = droppedImg; //[draggingPBoard dataForType:NSTIFFPboardType]; + data = droppedImg; //[draggingPBoard dataForType:NSPasteboardTypeTIFF]; } else return NO; @@ -244,7 +244,7 @@ data = [draggingPBoard propertyListForType:NSFilenamesPboardType]; break; case GHOST_kDragnDropTypeString: - data = [draggingPBoard stringForType:NSStringPboardType]; + data = [draggingPBoard stringForType:NSPasteboardTypeString]; break; default: return NO; @@ -388,8 +388,8 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(GHOST_SystemCocoa *systemCocoa, [contentview setAllowedTouchTypes:(NSTouchTypeMaskDirect | NSTouchTypeMaskIndirect)]; [m_window registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, - NSStringPboardType, - NSTIFFPboardType, + NSPasteboardTypeString, + NSPasteboardTypeTIFF, nil]]; if (is_dialog && parentWindow) { From 09a26f26e8a289d80efcba4824211981a0739365 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 12 Jan 2023 20:21:22 +1100 Subject: [PATCH 0609/1522] Cleanup: missing-declarations warnings Also remove duplicate doc-string. --- .../blenkernel/intern/pbvh_uv_islands.cc | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index aac61750d47..8554964fae9 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -31,10 +31,10 @@ static void uv_primitive_append_to_uv_vertices(UVPrimitive &uv_primitive) /** \name Mesh Primitives * \{ */ -int primitive_get_other_uv_vertex(const MeshData &mesh_data, - const MLoopTri &looptri, - const int v1, - const int v2) +static int primitive_get_other_uv_vertex(const MeshData &mesh_data, + const MLoopTri &looptri, + const int v1, + const int v2) { const Span mesh_loops = mesh_data.loops; BLI_assert(ELEM(v1, @@ -54,9 +54,9 @@ int primitive_get_other_uv_vertex(const MeshData &mesh_data, return -1; } -bool primitive_has_shared_uv_edge(const Span uv_map, - const MLoopTri &looptri, - const MLoopTri &other) +static bool primitive_has_shared_uv_edge(const Span uv_map, + const MLoopTri &looptri, + const MLoopTri &other) { int shared_uv_verts = 0; for (const int loop : looptri.tri) { @@ -91,7 +91,7 @@ static bool has_vertex(const MeshData &mesh_data, const MLoopTri &looptri, const return false; } -rctf primitive_uv_bounds(const MLoopTri &looptri, const Span uv_map) +static rctf primitive_uv_bounds(const MLoopTri &looptri, const Span uv_map) { rctf result; BLI_rctf_init_minmax(&result); @@ -1052,7 +1052,6 @@ void UVBorder::update_indexes(uint64_t border_index) } } -/** Remove edge from the border. updates the indexes. */ void UVBorder::remove(int64_t index) { /* Could read the border_index from any border edge as they are consistent. */ From ea1c31a24438442a4fa866d13af1563d76ffa3fc Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Thu, 15 Dec 2022 23:37:14 +0200 Subject: [PATCH 0610/1522] Fix T103074: flipped vertex group meaning in Multi-Modifier Armature. For some reason the Armature modifier in the Multi-Modifier mode interpreted the vertex group in a way essentially opposite to the regular mode. Moreover, this depended not on the Multi-Modifier checkbox, but on whether the mode was actually active. This fixes the flip and adds versioning code to patch old files. One difficulty is that whether the Multi-Modifier flag is valid can be different between the viewport and render. The versioning code assumes any modifier enabled in either to be active. This change is not forward compatible, so min version is also bumped. Differential Revision: https://developer.blender.org/D16787 --- .../blender/blenkernel/BKE_blender_version.h | 4 +- .../blenkernel/intern/armature_deform.c | 6 ++- .../blenloader/intern/versioning_300.cc | 50 ++++++++++++++++--- 3 files changed, 48 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index c95c3a1a934..f5514fcc632 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -25,13 +25,13 @@ extern "C" { /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 7 +#define BLENDER_FILE_SUBVERSION 8 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file * was written with too new a version. */ #define BLENDER_FILE_MIN_VERSION 305 -#define BLENDER_FILE_MIN_SUBVERSION 4 +#define BLENDER_FILE_MIN_SUBVERSION 8 /** User readable version string. */ const char *BKE_blender_version_string(void); diff --git a/source/blender/blenkernel/intern/armature_deform.c b/source/blender/blenkernel/intern/armature_deform.c index 64a3937c191..973fdbd0c57 100644 --- a/source/blender/blenkernel/intern/armature_deform.c +++ b/source/blender/blenkernel/intern/armature_deform.c @@ -270,7 +270,7 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data, float *vec = NULL, (*smat)[3] = NULL; float contrib = 0.0f; float armature_weight = 1.0f; /* default to 1 if no overall def group */ - float prevco_weight = 1.0f; /* weight for optional cached vertexcos */ + float prevco_weight = 0.0f; /* weight for optional cached vertexcos */ if (use_quaternion) { memset(&sumdq, 0, sizeof(DualQuat)); @@ -295,7 +295,9 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data, /* hackish: the blending factor can be used for blending with vert_coords_prev too */ if (vert_coords_prev) { - prevco_weight = armature_weight; + /* This weight specifies the contribution from the coordinates at the start of this + * modifier evaluation, while armature_weight is normally the opposite of that. */ + prevco_weight = 1.0f - armature_weight; armature_weight = 1.0f; } } diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 6b4f374bf0e..ddb9f157d18 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3858,6 +3858,48 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) } } + if (!MAIN_VERSION_ATLEAST(bmain, 305, 8)) { + const int CV_SCULPT_SELECTION_ENABLED = (1 << 1); + LISTBASE_FOREACH (Curves *, curves_id, &bmain->hair_curves) { + curves_id->flag &= ~CV_SCULPT_SELECTION_ENABLED; + } + LISTBASE_FOREACH (Curves *, curves_id, &bmain->hair_curves) { + BKE_id_attribute_rename(&curves_id->id, ".selection_point_float", ".selection", nullptr); + BKE_id_attribute_rename(&curves_id->id, ".selection_curve_float", ".selection", nullptr); + } + + /* Toggle the Invert Vertex Group flag on Armature modifiers in some cases. */ + LISTBASE_FOREACH (Object *, ob, &bmain->objects) { + bool after_armature = false; + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { + if (md->type == eModifierType_Armature) { + ArmatureModifierData *amd = (ArmatureModifierData *)md; + if (amd->multi) { + /* Toggle the invert vertex group flag on operational Multi Modifier entries. */ + if (after_armature && amd->defgrp_name[0]) { + amd->deformflag ^= ARM_DEF_INVERT_VGROUP; + } + } + else { + /* Disabled multi modifiers don't reset propagation, but non-multi ones do. */ + after_armature = false; + } + /* Multi Modifier is only valid and operational after an active Armature modifier. */ + if (md->mode & (eModifierMode_Realtime | eModifierMode_Render)) { + after_armature = true; + } + } + else if (ELEM(md->type, eModifierType_Lattice, eModifierType_MeshDeform)) { + /* These modifiers will also allow a following Multi Modifier to work. */ + after_armature = (md->mode & (eModifierMode_Realtime | eModifierMode_Render)) != 0; + } + else { + after_armature = false; + } + } + } + } + /** * Versioning code until next subversion bump goes here. * @@ -3869,13 +3911,5 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) */ { /* Keep this block, even when empty. */ - const int CV_SCULPT_SELECTION_ENABLED = (1 << 1); - LISTBASE_FOREACH (Curves *, curves_id, &bmain->hair_curves) { - curves_id->flag &= ~CV_SCULPT_SELECTION_ENABLED; - } - LISTBASE_FOREACH (Curves *, curves_id, &bmain->hair_curves) { - BKE_id_attribute_rename(&curves_id->id, ".selection_point_float", ".selection", nullptr); - BKE_id_attribute_rename(&curves_id->id, ".selection_curve_float", ".selection", nullptr); - } } } From ed178f5ff5a9cb02f25faa35271a4ca6c8f07ec2 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Thu, 12 Jan 2023 12:46:53 +0100 Subject: [PATCH 0611/1522] Fix: Potential divide by 0 using GRAPH_OT_ease MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case there is only 1 key on the FCurve, the operator can run into a situation where it divides by 0. It now skips the curve in that case Reviewed by: Sybren A. Stüvel Differential Revision: https://developer.blender.org/D16982 Ref: D16982 --- release/datafiles/locale | 2 +- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- source/blender/editors/animation/keyframes_general.c | 6 ++++++ source/tools | 2 +- 5 files changed, 10 insertions(+), 4 deletions(-) diff --git a/release/datafiles/locale b/release/datafiles/locale index 7084c4ecd97..4f6dbb69893 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 7084c4ecd97d93459d9d23fd90f81589b09be5df +Subproject commit 4f6dbb69893bd6bdf73467effe77ae46c8e4ee37 diff --git a/release/scripts/addons b/release/scripts/addons index a9d4443c244..bf49eeaa14c 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit a9d4443c244f89399ec4bcc427e05a07950528cc +Subproject commit bf49eeaa14c445d3c53068203fdf91bff568fe64 diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index bdcfdd47ec3..0f72f6c85c3 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit bdcfdd47ec3451822b21d1cff2ea2db751093c9a +Subproject commit 0f72f6c85c3743a9072273acb6a8a34b1cf1064b diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index f6b09e60e3c..c356f633053 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -388,6 +388,12 @@ void ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor const float key_x_range = right_key.vec[1][0] - left_x; const float key_y_range = right_key.vec[1][1] - left_y; + /* Happens if there is only 1 key on the FCurve. Needs to be skipped because it + * would be a divide by 0. */ + if (IS_EQF(key_x_range, 0.0f)) { + return; + } + /* In order to have a curve that favors the right key, the curve needs to be mirrored in x and y. * Having an exponent that is a fraction of 1 would produce a similar but inferior result. */ const bool inverted = factor > 0.5; diff --git a/source/tools b/source/tools index e1744b9bd82..3582f5326d0 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit e1744b9bd82527cf7e8af63362b61bd309b5711b +Subproject commit 3582f5326d08ca05c2a19056597e49ec5511d854 From c5f9bf95cdc1d6a3eb2593b4b3ed2560602a4b8f Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Thu, 12 Jan 2023 13:03:55 +0100 Subject: [PATCH 0612/1522] Cleanup: Remove unused function pose_propagate_fcurve Remove the unused function `pose_propagate_fcurve` It was missed in D16771 Reviewed By: Jacques Lucke Differential Revision: https://developer.blender.org/D16937 Ref: D16937 --- source/blender/editors/armature/pose_slide.c | 52 -------------------- 1 file changed, 52 deletions(-) diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c index 86675a1bef2..38762913b3d 100644 --- a/source/blender/editors/armature/pose_slide.c +++ b/source/blender/editors/armature/pose_slide.c @@ -1842,58 +1842,6 @@ static void propagate_curve_values(ListBase /*tPChanFCurveLink*/ *pflinks, } } -/** - * Propagate just works along each F-Curve in turn. - */ -static void UNUSED_FUNCTION(pose_propagate_fcurve)(FCurve *fcu, - float start_frame, - const float end_frame) -{ - /* Skip if no keyframes to edit. */ - if ((fcu->bezt == NULL) || (fcu->totvert < 2)) { - return; - } - - /* Find the reference value from bones directly, which means that the user - * doesn't need to firstly keyframe the pose (though this doesn't mean that - * they can't either). */ - float refVal = evaluate_fcurve(fcu, start_frame); - - /* Find the first keyframe to start propagating from: - * - if there's a keyframe on the current frame, we probably want to save this value there too - * since it may be as of yet un-keyed - * - if starting before the starting frame, don't touch the key, as it may have had some valid - * values - */ - bool keyExists; - const int match = BKE_fcurve_bezt_binarysearch_index( - fcu->bezt, start_frame, fcu->totvert, &keyExists); - - int i; - if (fcu->bezt[match].vec[1][0] < start_frame) { - i = match + 1; - } - else { - i = match; - } - - BezTriple *bezt; - for (bezt = &fcu->bezt[i]; i < fcu->totvert; i++, bezt++) { - /* Additional termination conditions based on the operator 'mode' property go here. */ - /* Stop if keyframe is outside the accepted range. */ - if (bezt->vec[1][0] > end_frame) { - break; - } - - /* Just flatten handles, since values will now be the same either side. */ - /* TODO: perhaps a fade-out modulation of the value is required here (optional once again)? */ - bezt->vec[0][1] = bezt->vec[1][1] = bezt->vec[2][1] = refVal; - - /* Select keyframe to indicate that it's been changed. */ - bezt->f2 |= SELECT; - } -} - static float find_next_key(ListBase *pflinks, const float start_frame) { float target_frame = FLT_MAX; From 16fc9280689aa5b03ded010e1b6c82334e667094 Mon Sep 17 00:00:00 2001 From: Martijn Versteegh Date: Thu, 12 Jan 2023 11:37:41 +0100 Subject: [PATCH 0613/1522] Fix: uninitialized UVs when painting in sculpt mode Because of a mistake in commit 6c774feba2c9 the uv vbo was not initialized in the pbvh. --- source/blender/draw/intern/draw_pbvh.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index 42e2686df82..964d2190177 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -721,6 +721,16 @@ struct PBVHBatches { }); } break; + case CD_PROP_FLOAT2: { + float2 *mloopuv = static_cast( + CustomData_get_layer_named(args->ldata, CD_PROP_FLOAT2, vbo.name.c_str())); + + foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const MLoopTri *tri) { + *static_cast(GPU_vertbuf_raw_step(&access)) = mloopuv[tri->tri[tri_i]]; + }); + break; + } + } } From 589d1be147b02444fed2ebcc4006524c08e929c8 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Thu, 12 Jan 2023 10:16:25 -0300 Subject: [PATCH 0614/1522] Cleanup: rename variables to distinguish between target and source From --> To **Struct Members:** |snapTarget|snap_source |snapPoint|snap_target |snapTargetGrid|snap_target_grid |calcSnap|snap_target_fn |targetSnap|snap_source_fn |applySnap|snap_mode_apply_fn |distance|snap_mode_distance_fn |source_select|source_operation |target_select|target_operation **Functions:** |snap_calc_view3d_fn|snap_target_view3d_fn |snap_calc_uv_fn|snap_target_uv_fn |snap_calc_node_fn|snap_target_node_fn |snap_calc_sequencer_fn|snap_target_sequencer_fn |TargetSnapMedian|snap_source_median_fn |TargetSnapCenter|snap_source_center_fn |TargetSnapClosest|snap_source_closest_fn |TargetSnapActive|snap_source_active_fn **Enums:** |TARGET_INIT|SNAP_SOURCE_FOUND |TARGET_GRID_INIT|SNAP_TARGET_GRID_FOUND |POINT_INIT|SNAP_TARGET_FOUND |MULTI_POINTS|SNAP_MULTI_POINTS **Types:** |eSnapSourceSelect|eSnapSourceOP |eSnapTargetSelect|eSnapTargetOP Also rename Select to Operation. Reviewed By: campbellbarton Differential Revision: https://developer.blender.org/D16967 --- .../ED_transform_snap_object_context.h | 2 +- source/blender/editors/transform/transform.c | 4 +- source/blender/editors/transform/transform.h | 28 +- .../editors/transform/transform_constraints.c | 16 +- .../transform/transform_mode_edge_seq_slide.c | 2 +- .../transform/transform_mode_edge_slide.c | 6 +- .../editors/transform/transform_mode_resize.c | 6 +- .../editors/transform/transform_mode_rotate.c | 6 +- .../transform/transform_mode_translate.c | 24 +- .../transform/transform_mode_vert_slide.c | 6 +- .../blender/editors/transform/transform_ops.c | 6 +- .../editors/transform/transform_snap.cc | 245 +++++++++--------- .../transform/transform_snap_object.cc | 4 +- .../transform/transform_snap_sequencer.c | 16 +- source/blender/makesdna/DNA_scene_types.h | 20 +- 15 files changed, 196 insertions(+), 195 deletions(-) diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h index f9ca578f282..99b7d95c74c 100644 --- a/source/blender/editors/include/ED_transform_snap_object_context.h +++ b/source/blender/editors/include/ED_transform_snap_object_context.h @@ -53,7 +53,7 @@ struct SnapObjectHitDepth { /** parameters that define which objects will be used to snap. */ struct SnapObjectParams { /* Special context sensitive handling for the active or selected object. */ - eSnapTargetSelect snap_target_select; + eSnapTargetOP snap_target_select; /* Geometry for snapping in edit mode. */ eSnapEditType edit_mode_type; /* snap to the closest element, use when using more than one snap type */ diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index ff93bcaf8ca..c9cf572e9ad 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1573,9 +1573,9 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) if ((prop = RNA_struct_find_property(op->ptr, "snap_elements"))) { RNA_property_enum_set(op->ptr, prop, t->tsnap.mode); RNA_boolean_set(op->ptr, "use_snap_project", t->tsnap.project); - RNA_enum_set(op->ptr, "snap_target", t->tsnap.source_select); + RNA_enum_set(op->ptr, "snap_target", t->tsnap.source_operation); - eSnapTargetSelect target = t->tsnap.target_select; + eSnapTargetOP target = t->tsnap.target_operation; RNA_boolean_set(op->ptr, "use_snap_self", (target & SCE_SNAP_TARGET_NOT_ACTIVE) == 0); RNA_boolean_set(op->ptr, "use_snap_edit", (target & SCE_SNAP_TARGET_NOT_EDITED) == 0); RNA_boolean_set(op->ptr, "use_snap_nonedit", (target & SCE_SNAP_TARGET_NOT_NONEDITED) == 0); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 29df931e136..13362cee2b6 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -160,13 +160,13 @@ ENUM_OPERATORS(eTModifier, MOD_NODE_ATTACH) typedef enum eTSnap { SNAP_RESETTED = 0, SNAP_FORCED = 1 << 0, - TARGET_INIT = 1 << 1, + SNAP_SOURCE_FOUND = 1 << 1, /* Special flag for snap to grid. */ - TARGET_GRID_INIT = 1 << 2, - POINT_INIT = 1 << 3, - MULTI_POINTS = 1 << 4, + SNAP_TARGET_GRID_FOUND = 1 << 2, + SNAP_TARGET_FOUND = 1 << 3, + SNAP_MULTI_POINTS = 1 << 4, } eTSnap; -ENUM_OPERATORS(eTSnap, MULTI_POINTS) +ENUM_OPERATORS(eTSnap, SNAP_MULTI_POINTS) /** #TransCon.mode, #TransInfo.con.mode */ typedef enum { @@ -276,9 +276,9 @@ typedef struct TransSnap { /* Method(s) used for snapping source to target */ eSnapMode mode; /* Part of source to snap to target */ - eSnapSourceSelect source_select; + eSnapSourceOP source_operation; /* Determines which objects are possible target */ - eSnapTargetSelect target_select; + eSnapTargetOP target_operation; bool align; bool project; bool peel; @@ -288,25 +288,25 @@ typedef struct TransSnap { /* Snapped Element Type (currently for objects only). */ eSnapMode snapElem; /** snapping from this point (in global-space). */ - float snapTarget[3]; + float snap_source[3]; /** to this point (in global-space). */ - float snapPoint[3]; - float snapTargetGrid[3]; + float snap_target[3]; + float snap_target_grid[3]; float snapNormal[3]; char snapNodeBorder; ListBase points; TransSnapPoint *selectedPoint; double last; - void (*applySnap)(struct TransInfo *, float *); - void (*calcSnap)(struct TransInfo *, float *); - void (*targetSnap)(struct TransInfo *); + void (*snap_target_fn)(struct TransInfo *, float *); + void (*snap_source_fn)(struct TransInfo *); /** * Get the transform distance between two points (used by Closest snap) * * \note Return value can be anything, * where the smallest absolute value defines what's closest. */ - float (*distance)(struct TransInfo *t, const float p1[3], const float p2[3]); + float (*snap_mode_distance_fn)(struct TransInfo *t, const float p1[3], const float p2[3]); + void (*snap_mode_apply_fn)(struct TransInfo *, float *); /** * Re-usable snap context data. diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index b0db9398e80..61adc98c258 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -270,12 +270,12 @@ static void axisProjection(const TransInfo *t, static void constraint_snap_plane_to_edge(const TransInfo *t, const float plane[4], float r_out[3]) { float lambda; - const float *edge_snap_point = t->tsnap.snapPoint; + const float *edge_snap_point = t->tsnap.snap_target; const float *edge_dir = t->tsnap.snapNormal; bool is_aligned = fabsf(dot_v3v3(edge_dir, plane)) < CONSTRAIN_EPSILON; if (!is_aligned && isect_ray_plane_v3(edge_snap_point, edge_dir, plane, &lambda, false)) { madd_v3_v3v3fl(r_out, edge_snap_point, edge_dir, lambda); - sub_v3_v3(r_out, t->tsnap.snapTarget); + sub_v3_v3(r_out, t->tsnap.snap_source); } } @@ -284,13 +284,13 @@ static void UNUSED_FUNCTION(constraint_snap_plane_to_face(const TransInfo *t, float r_out[3])) { float face_plane[4], isect_orig[3], isect_dir[3]; - const float *face_snap_point = t->tsnap.snapPoint; + const float *face_snap_point = t->tsnap.snap_target; const float *face_normal = t->tsnap.snapNormal; plane_from_point_normal_v3(face_plane, face_snap_point, face_normal); bool is_aligned = fabsf(dot_v3v3(plane, face_plane)) > (1.0f - CONSTRAIN_EPSILON); if (!is_aligned && isect_plane_plane_v3(plane, face_plane, isect_orig, isect_dir)) { closest_to_ray_v3(r_out, face_snap_point, isect_orig, isect_dir); - sub_v3_v3(r_out, t->tsnap.snapTarget); + sub_v3_v3(r_out, t->tsnap.snap_source); } } @@ -299,11 +299,11 @@ void transform_constraint_snap_axis_to_edge(const TransInfo *t, float r_out[3]) { float lambda; - const float *edge_snap_point = t->tsnap.snapPoint; + const float *edge_snap_point = t->tsnap.snap_target; const float *edge_dir = t->tsnap.snapNormal; bool is_aligned = fabsf(dot_v3v3(axis, edge_dir)) > (1.0f - CONSTRAIN_EPSILON); if (!is_aligned && - isect_ray_ray_v3(t->tsnap.snapTarget, axis, edge_snap_point, edge_dir, &lambda, NULL)) { + isect_ray_ray_v3(t->tsnap.snap_source, axis, edge_snap_point, edge_dir, &lambda, NULL)) { mul_v3_v3fl(r_out, axis, lambda); } } @@ -314,11 +314,11 @@ void transform_constraint_snap_axis_to_face(const TransInfo *t, { float lambda; float face_plane[4]; - const float *face_snap_point = t->tsnap.snapPoint; + const float *face_snap_point = t->tsnap.snap_target; const float *face_normal = t->tsnap.snapNormal; plane_from_point_normal_v3(face_plane, face_snap_point, face_normal); bool is_aligned = fabsf(dot_v3v3(axis, face_plane)) < CONSTRAIN_EPSILON; - if (!is_aligned && isect_ray_plane_v3(t->tsnap.snapTarget, axis, face_plane, &lambda, false)) { + if (!is_aligned && isect_ray_plane_v3(t->tsnap.snap_source, axis, face_plane, &lambda, false)) { mul_v3_v3fl(r_out, axis, lambda); } } diff --git a/source/blender/editors/transform/transform_mode_edge_seq_slide.c b/source/blender/editors/transform/transform_mode_edge_seq_slide.c index ae824b5a712..4c7670ae302 100644 --- a/source/blender/editors/transform/transform_mode_edge_seq_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_seq_slide.c @@ -110,7 +110,7 @@ static void applySeqSlide(TransInfo *t, const int UNUSED(mval[2])) void initSeqSlide(TransInfo *t) { t->transform = applySeqSlide; - t->tsnap.applySnap = transform_snap_sequencer_apply_translate; + t->tsnap.snap_mode_apply_fn = transform_snap_sequencer_apply_translate; initMouseInputMode(t, &t->mouse, INPUT_VECTOR); diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index 2d4cc7e2c76..6920deea574 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -1272,7 +1272,7 @@ static void edge_slide_snap_apply(TransInfo *t, float *value) } getSnapPoint(t, dvec); - sub_v3_v3(dvec, t->tsnap.snapTarget); + sub_v3_v3(dvec, t->tsnap.snap_source); add_v3_v3v3(snap_point, co_orig, dvec); float perc = *value; @@ -1498,8 +1498,8 @@ void initEdgeSlide_ex( t->mode = TFM_EDGE_SLIDE; t->transform = applyEdgeSlide; t->handleEvent = handleEventEdgeSlide; - t->tsnap.applySnap = edge_slide_snap_apply; - t->tsnap.distance = transform_snap_distance_len_squared_fn; + t->tsnap.snap_mode_apply_fn = edge_slide_snap_apply; + t->tsnap.snap_mode_distance_fn = transform_snap_distance_len_squared_fn; { EdgeSlideParams *slp = MEM_callocN(sizeof(*slp), __func__); diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c index 668e1ed567f..ae90463b7f3 100644 --- a/source/blender/editors/transform/transform_mode_resize.c +++ b/source/blender/editors/transform/transform_mode_resize.c @@ -79,7 +79,7 @@ static void ApplySnapResize(TransInfo *t, float vec[3]) float point[3]; getSnapPoint(t, point); - float dist = ResizeBetween(t, t->tsnap.snapTarget, point); + float dist = ResizeBetween(t, t->tsnap.snap_source, point); if (dist != TRANSFORM_DIST_INVALID) { copy_v3_fl(vec, dist); } @@ -287,8 +287,8 @@ void initResize(TransInfo *t, float mouse_dir_constraint[3]) { t->mode = TFM_RESIZE; t->transform = applyResize; - t->tsnap.applySnap = ApplySnapResize; - t->tsnap.distance = ResizeBetween; + t->tsnap.snap_mode_apply_fn = ApplySnapResize; + t->tsnap.snap_mode_distance_fn = ResizeBetween; if (is_zero_v3(mouse_dir_constraint)) { initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP); diff --git a/source/blender/editors/transform/transform_mode_rotate.c b/source/blender/editors/transform/transform_mode_rotate.c index a56d3b23149..0a49fdefd83 100644 --- a/source/blender/editors/transform/transform_mode_rotate.c +++ b/source/blender/editors/transform/transform_mode_rotate.c @@ -219,7 +219,7 @@ static void ApplySnapRotation(TransInfo *t, float *value) float point[3]; getSnapPoint(t, point); - float dist = RotationBetween(t, t->tsnap.snapTarget, point); + float dist = RotationBetween(t, t->tsnap.snap_source, point); *value = dist; } @@ -429,8 +429,8 @@ void initRotation(TransInfo *t) t->mode = TFM_ROTATION; t->transform = applyRotation; t->transform_matrix = applyRotationMatrix; - t->tsnap.applySnap = ApplySnapRotation; - t->tsnap.distance = RotationBetween; + t->tsnap.snap_mode_apply_fn = ApplySnapRotation; + t->tsnap.snap_mode_distance_fn = RotationBetween; initMouseInputMode(t, &t->mouse, INPUT_ANGLE); diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index 9257512268d..b171b227aa6 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -351,22 +351,22 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_ static void translate_snap_target_grid_ensure(TransInfo *t) { /* Only need to calculate once. */ - if ((t->tsnap.status & TARGET_GRID_INIT) == 0) { + if ((t->tsnap.status & SNAP_TARGET_GRID_FOUND) == 0) { if (t->data_type == &TransConvertType_Cursor3D) { /* Use a fallback when transforming the cursor. * In this case the center is _not_ derived from the cursor which is being transformed. */ - copy_v3_v3(t->tsnap.snapTargetGrid, TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->data->iloc); + copy_v3_v3(t->tsnap.snap_target_grid, TRANS_DATA_CONTAINER_FIRST_SINGLE(t)->data->iloc); } else if (t->around == V3D_AROUND_CURSOR) { /* Use a fallback for cursor selection, * this isn't useful as a global center for absolute grid snapping * since its not based on the position of the selection. */ - tranform_snap_target_median_calc(t, t->tsnap.snapTargetGrid); + tranform_snap_target_median_calc(t, t->tsnap.snap_target_grid); } else { - copy_v3_v3(t->tsnap.snapTargetGrid, t->center_global); + copy_v3_v3(t->tsnap.snap_target_grid, t->center_global); } - t->tsnap.status |= TARGET_GRID_INIT; + t->tsnap.status |= SNAP_TARGET_GRID_FOUND; } } @@ -378,7 +378,7 @@ static void translate_snap_grid_apply(TransInfo *t, { BLI_assert(max_index <= 2); translate_snap_target_grid_ensure(t); - const float *center_global = t->tsnap.snapTargetGrid; + const float *center_global = t->tsnap.snap_target_grid; const float *asp = t->aspect; float in[3]; @@ -440,10 +440,10 @@ static void ApplySnapTranslation(TransInfo *t, float vec[3]) if (t->spacetype == SPACE_NODE) { char border = t->tsnap.snapNodeBorder; if (border & (NODE_LEFT | NODE_RIGHT)) { - vec[0] = point[0] - t->tsnap.snapTarget[0]; + vec[0] = point[0] - t->tsnap.snap_source[0]; } if (border & (NODE_BOTTOM | NODE_TOP)) { - vec[1] = point[1] - t->tsnap.snapTarget[1]; + vec[1] = point[1] - t->tsnap.snap_source[1]; } } else if (t->spacetype == SPACE_SEQ) { @@ -459,7 +459,7 @@ static void ApplySnapTranslation(TransInfo *t, float vec[3]) } } - sub_v3_v3v3(vec, point, t->tsnap.snapTarget); + sub_v3_v3v3(vec, point, t->tsnap.snap_source); } } @@ -499,7 +499,7 @@ static void applyTranslationValue(TransInfo *t, const float vec[3]) FOREACH_TRANS_DATA_CONTAINER (t, tc) { float pivot_local[3]; if (rotate_mode != TRANSLATE_ROTATE_OFF) { - copy_v3_v3(pivot_local, t->tsnap.snapTarget); + copy_v3_v3(pivot_local, t->tsnap.snap_source); /* The pivot has to be in local-space (see T49494) */ if (tc->use_local_mat) { mul_m4_v3(tc->imat, pivot_local); @@ -678,8 +678,8 @@ void initTranslation(TransInfo *t) t->transform = applyTranslation; t->transform_matrix = applyTranslationMatrix; - t->tsnap.applySnap = ApplySnapTranslation; - t->tsnap.distance = transform_snap_distance_len_squared_fn; + t->tsnap.snap_mode_apply_fn = ApplySnapTranslation; + t->tsnap.snap_mode_distance_fn = transform_snap_distance_len_squared_fn; initMouseInputMode(t, &t->mouse, INPUT_VECTOR); diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c index e8813241809..3483f2b2bfa 100644 --- a/source/blender/editors/transform/transform_mode_vert_slide.c +++ b/source/blender/editors/transform/transform_mode_vert_slide.c @@ -532,7 +532,7 @@ static void vert_slide_snap_apply(TransInfo *t, float *value) } getSnapPoint(t, dvec); - sub_v3_v3(dvec, t->tsnap.snapTarget); + sub_v3_v3(dvec, t->tsnap.snap_source); if (t->tsnap.snapElem & (SCE_SNAP_MODE_EDGE | SCE_SNAP_MODE_FACE_RAYCAST)) { float co_dir[3]; sub_v3_v3v3(co_dir, co_curr_3d, co_orig_3d); @@ -610,8 +610,8 @@ void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp) t->mode = TFM_VERT_SLIDE; t->transform = applyVertSlide; t->handleEvent = handleEventVertSlide; - t->tsnap.applySnap = vert_slide_snap_apply; - t->tsnap.distance = transform_snap_distance_len_squared_fn; + t->tsnap.snap_mode_apply_fn = vert_slide_snap_apply; + t->tsnap.snap_mode_distance_fn = transform_snap_distance_len_squared_fn; { VertSlideParams *slp = MEM_callocN(sizeof(*slp), __func__); diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 82791b2a9f5..0da3bf4d85f 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -421,11 +421,11 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event) /* XXX, workaround: active needs to be calculated before transforming, * since we're not reading from 'td->center' in this case. see: T40241 */ - if (t->tsnap.source_select == SCE_SNAP_SOURCE_ACTIVE) { + if (t->tsnap.source_operation == SCE_SNAP_SOURCE_ACTIVE) { /* In camera view, tsnap callback is not set * (see #initSnappingMode() in transform_snap.c, and T40348). */ - if (t->tsnap.targetSnap && ((t->tsnap.status & TARGET_INIT) == 0)) { - t->tsnap.targetSnap(t); + if (t->tsnap.snap_source_fn && ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0)) { + t->tsnap.snap_source_fn(t); } } diff --git a/source/blender/editors/transform/transform_snap.cc b/source/blender/editors/transform/transform_snap.cc index 00ccf1ed632..2f5e1974d0b 100644 --- a/source/blender/editors/transform/transform_snap.cc +++ b/source/blender/editors/transform/transform_snap.cc @@ -61,16 +61,15 @@ static bool doForceIncrementSnap(const TransInfo *t); static void setSnappingCallback(TransInfo *t); -/* static void CalcSnapGrid(TransInfo *t, float *vec); */ -static void snap_calc_view3d_fn(TransInfo *t, float *vec); -static void snap_calc_uv_fn(TransInfo *t, float *vec); -static void snap_calc_node_fn(TransInfo *t, float *vec); -static void snap_calc_sequencer_fn(TransInfo *t, float *vec); +static void snap_target_view3d_fn(TransInfo *t, float *vec); +static void snap_target_uv_fn(TransInfo *t, float *vec); +static void snap_target_node_fn(TransInfo *t, float *vec); +static void snap_target_sequencer_fn(TransInfo *t, float *vec); -static void TargetSnapMedian(TransInfo *t); -static void TargetSnapCenter(TransInfo *t); -static void TargetSnapClosest(TransInfo *t); -static void TargetSnapActive(TransInfo *t); +static void snap_source_median_fn(TransInfo *t); +static void snap_source_center_fn(TransInfo *t); +static void snap_source_closest_fn(TransInfo *t); +static void snap_source_active_fn(TransInfo *t); /** \} */ @@ -78,7 +77,7 @@ static void TargetSnapActive(TransInfo *t); /** \name Implementations * \{ */ -static bool snapNodeTest(View2D *v2d, bNode *node, eSnapTargetSelect snap_target_select); +static bool snapNodeTest(View2D *v2d, bNode *node, eSnapTargetOP snap_target_select); static NodeBorder snapNodeBorder(eSnapMode snap_node_mode); #if 0 @@ -115,8 +114,10 @@ static bool snap_use_backface_culling(const TransInfo *t) bool validSnap(const TransInfo *t) { - return (t->tsnap.status & (POINT_INIT | TARGET_INIT)) == (POINT_INIT | TARGET_INIT) || - (t->tsnap.status & (MULTI_POINTS | TARGET_INIT)) == (MULTI_POINTS | TARGET_INIT); + return (t->tsnap.status & (SNAP_TARGET_FOUND | SNAP_SOURCE_FOUND)) == + (SNAP_TARGET_FOUND | SNAP_SOURCE_FOUND) || + (t->tsnap.status & (SNAP_MULTI_POINTS | SNAP_SOURCE_FOUND)) == + (SNAP_MULTI_POINTS | SNAP_SOURCE_FOUND); } bool transform_snap_is_active(const TransInfo *t) @@ -156,10 +157,10 @@ void drawSnapping(const struct bContext *C, TransInfo *t) return; } - bool draw_target = (t->spacetype == SPACE_VIEW3D) && (t->tsnap.status & TARGET_INIT) && + bool draw_source = (t->spacetype == SPACE_VIEW3D) && (t->tsnap.status & SNAP_SOURCE_FOUND) && (t->tsnap.mode & SCE_SNAP_MODE_EDGE_PERPENDICULAR); - if (!(draw_target || validSnap(t))) { + if (!(draw_source || validSnap(t))) { return; } @@ -216,12 +217,12 @@ void drawSnapping(const struct bContext *C, TransInfo *t) normal = t->tsnap.snapNormal; } - if (draw_target) { - loc_prev = t->tsnap.snapTarget; + if (draw_source) { + loc_prev = t->tsnap.snap_source; } if (validSnap(t)) { - loc_cur = t->tsnap.snapPoint; + loc_cur = t->tsnap.snap_target; } ED_view3d_cursor_snap_draw_util( @@ -234,8 +235,8 @@ void drawSnapping(const struct bContext *C, TransInfo *t) float x, y; const float snap_point[2] = { - t->tsnap.snapPoint[0] / t->aspect[0], - t->tsnap.snapPoint[1] / t->aspect[1], + t->tsnap.snap_target[0] / t->aspect[0], + t->tsnap.snap_target[1] / t->aspect[1], }; UI_view2d_view_to_region_fl(&t->region->v2d, UNPACK2(snap_point), &x, &y); float radius = 2.5f * UI_GetThemeValuef(TH_VERTEX_SIZE) * U.pixelsize; @@ -274,11 +275,11 @@ void drawSnapping(const struct bContext *C, TransInfo *t) ED_node_draw_snap(®ion->v2d, p->co, size, NodeBorder(0), pos); } - if (t->tsnap.status & POINT_INIT) { + if (t->tsnap.status & SNAP_TARGET_FOUND) { immUniformColor4ubv(activeCol); ED_node_draw_snap( - ®ion->v2d, t->tsnap.snapPoint, size, NodeBorder(t->tsnap.snapNodeBorder), pos); + ®ion->v2d, t->tsnap.snap_target, size, NodeBorder(t->tsnap.snapNodeBorder), pos); } immUnbindProgram(); @@ -293,9 +294,9 @@ void drawSnapping(const struct bContext *C, TransInfo *t) immUniformColor4ubv(col); float pixelx = BLI_rctf_size_x(®ion->v2d.cur) / BLI_rcti_size_x(®ion->v2d.mask); immRectf(pos, - t->tsnap.snapPoint[0] - pixelx, + t->tsnap.snap_target[0] - pixelx, region->v2d.cur.ymax, - t->tsnap.snapPoint[0] + pixelx, + t->tsnap.snap_target[0] + pixelx, region->v2d.cur.ymin); immUnbindProgram(); GPU_blend(GPU_BLEND_NONE); @@ -346,7 +347,7 @@ static bool applyFaceProject(TransInfo *t, TransDataContainer *tc, TransData *td } SnapObjectParams snap_object_params{}; - snap_object_params.snap_target_select = t->tsnap.target_select; + snap_object_params.snap_target_select = t->tsnap.target_operation; snap_object_params.edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL; snap_object_params.use_occlusion_test = false; snap_object_params.use_backface_culling = t->tsnap.use_backface_culling; @@ -413,7 +414,7 @@ static void applyFaceNearest(TransInfo *t, TransDataContainer *tc, TransData *td } SnapObjectParams snap_object_params{}; - snap_object_params.snap_target_select = t->tsnap.target_select; + snap_object_params.snap_target_select = t->tsnap.target_operation; snap_object_params.edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL; snap_object_params.use_occlusion_test = false; snap_object_params.use_backface_culling = false; @@ -525,9 +526,9 @@ void transform_snap_mixed_apply(TransInfo *t, float *vec) } if (t->tsnap.status & SNAP_FORCED) { - t->tsnap.targetSnap(t); + t->tsnap.snap_source_fn(t); - t->tsnap.applySnap(t, vec); + t->tsnap.snap_mode_apply_fn(t, vec); } else if (((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) != 0) && transform_snap_is_active(t)) { @@ -536,18 +537,18 @@ void transform_snap_mixed_apply(TransInfo *t, float *vec) /* Time base quirky code to go around find-nearest slowness. */ /* TODO: add exception for object mode, no need to slow it down then. */ if (current - t->tsnap.last >= 0.01) { - if (t->tsnap.calcSnap) { - t->tsnap.calcSnap(t, vec); + if (t->tsnap.snap_target_fn) { + t->tsnap.snap_target_fn(t, vec); } - if (t->tsnap.targetSnap) { - t->tsnap.targetSnap(t); + if (t->tsnap.snap_source_fn) { + t->tsnap.snap_source_fn(t); } t->tsnap.last = current; } if (validSnap(t)) { - t->tsnap.applySnap(t, vec); + t->tsnap.snap_mode_apply_fn(t, vec); } } } @@ -559,8 +560,8 @@ void resetSnapping(TransInfo *t) t->tsnap.align = false; t->tsnap.project = false; t->tsnap.mode = SCE_SNAP_MODE_NONE; - t->tsnap.target_select = SCE_SNAP_TARGET_ALL; - t->tsnap.source_select = SCE_SNAP_SOURCE_CLOSEST; + t->tsnap.target_operation = SCE_SNAP_TARGET_ALL; + t->tsnap.source_operation = SCE_SNAP_SOURCE_CLOSEST; t->tsnap.last = 0; t->tsnap.snapNormal[0] = 0; @@ -682,15 +683,15 @@ static eSnapMode snap_mode_from_spacetype(TransInfo *t) return SCE_SNAP_MODE_INCREMENT; } -static eSnapTargetSelect snap_target_select_from_spacetype(TransInfo *t) +static eSnapTargetOP snap_target_select_from_spacetype(TransInfo *t) { BKE_view_layer_synced_ensure(t->scene, t->view_layer); Base *base_act = BKE_view_layer_active_base_get(t->view_layer); - eSnapTargetSelect ret = SCE_SNAP_TARGET_ALL; + eSnapTargetOP ret = SCE_SNAP_TARGET_ALL; - /* `t->tsnap.target_select` not initialized yet. */ - BLI_assert(t->tsnap.target_select == SCE_SNAP_TARGET_ALL); + /* `t->tsnap.target_operation` not initialized yet. */ + BLI_assert(t->tsnap.target_operation == SCE_SNAP_TARGET_ALL); if (ELEM(t->spacetype, SPACE_VIEW3D, SPACE_IMAGE) && !(t->options & CTX_CAMERA)) { if (base_act && (base_act->object->mode & OB_MODE_PARTICLE_EDIT)) { @@ -778,12 +779,12 @@ static void initSnappingMode(TransInfo *t) void initSnapping(TransInfo *t, wmOperator *op) { ToolSettings *ts = t->settings; - eSnapSourceSelect snap_source = eSnapSourceSelect(ts->snap_target); + eSnapSourceOP snap_source = eSnapSourceOP(ts->snap_target); resetSnapping(t); t->tsnap.mode = snap_mode_from_spacetype(t); t->tsnap.flag = snap_flag_from_spacetype(t); - t->tsnap.target_select = snap_target_select_from_spacetype(t); + t->tsnap.target_operation = snap_target_select_from_spacetype(t); t->tsnap.face_nearest_steps = max_ii(ts->snap_face_nearest_steps, 1); /* if snap property exists */ @@ -803,13 +804,13 @@ void initSnapping(TransInfo *t, wmOperator *op) * geometry is snapped). */ if ((prop = RNA_struct_find_property(op->ptr, "snap_target")) && RNA_property_is_set(op->ptr, prop)) { - snap_source = eSnapSourceSelect(RNA_property_enum_get(op->ptr, prop)); + snap_source = eSnapSourceOP(RNA_property_enum_get(op->ptr, prop)); } if ((prop = RNA_struct_find_property(op->ptr, "snap_point")) && RNA_property_is_set(op->ptr, prop)) { - RNA_property_float_get_array(op->ptr, prop, t->tsnap.snapPoint); - t->tsnap.status |= SNAP_FORCED | POINT_INIT; + RNA_property_float_get_array(op->ptr, prop, t->tsnap.snap_target); + t->tsnap.status |= SNAP_FORCED | SNAP_TARGET_FOUND; } /* snap align only defined in specific cases */ @@ -828,28 +829,28 @@ void initSnapping(TransInfo *t, wmOperator *op) /* use_snap_self is misnamed and should be use_snap_active */ if ((prop = RNA_struct_find_property(op->ptr, "use_snap_self")) && RNA_property_is_set(op->ptr, prop)) { - SET_FLAG_FROM_TEST(t->tsnap.target_select, + SET_FLAG_FROM_TEST(t->tsnap.target_operation, !RNA_property_boolean_get(op->ptr, prop), SCE_SNAP_TARGET_NOT_ACTIVE); } if ((prop = RNA_struct_find_property(op->ptr, "use_snap_edit")) && RNA_property_is_set(op->ptr, prop)) { - SET_FLAG_FROM_TEST(t->tsnap.target_select, + SET_FLAG_FROM_TEST(t->tsnap.target_operation, !RNA_property_boolean_get(op->ptr, prop), SCE_SNAP_TARGET_NOT_EDITED); } if ((prop = RNA_struct_find_property(op->ptr, "use_snap_nonedit")) && RNA_property_is_set(op->ptr, prop)) { - SET_FLAG_FROM_TEST(t->tsnap.target_select, + SET_FLAG_FROM_TEST(t->tsnap.target_operation, !RNA_property_boolean_get(op->ptr, prop), SCE_SNAP_TARGET_NOT_NONEDITED); } if ((prop = RNA_struct_find_property(op->ptr, "use_snap_selectable")) && RNA_property_is_set(op->ptr, prop)) { - SET_FLAG_FROM_TEST(t->tsnap.target_select, + SET_FLAG_FROM_TEST(t->tsnap.target_operation, RNA_property_boolean_get(op->ptr, prop), SCE_SNAP_TARGET_ONLY_SELECTABLE); } @@ -864,21 +865,21 @@ void initSnapping(TransInfo *t, wmOperator *op) t->tsnap.align = ((t->tsnap.flag & SCE_SNAP_ROTATE) != 0); t->tsnap.project = ((t->tsnap.flag & SCE_SNAP_PROJECT) != 0); t->tsnap.peel = ((t->tsnap.flag & SCE_SNAP_PROJECT) != 0); - SET_FLAG_FROM_TEST(t->tsnap.target_select, + SET_FLAG_FROM_TEST(t->tsnap.target_operation, (ts->snap_flag & SCE_SNAP_NOT_TO_ACTIVE), SCE_SNAP_TARGET_NOT_ACTIVE); - SET_FLAG_FROM_TEST(t->tsnap.target_select, + SET_FLAG_FROM_TEST(t->tsnap.target_operation, !(ts->snap_flag & SCE_SNAP_TO_INCLUDE_EDITED), SCE_SNAP_TARGET_NOT_EDITED); - SET_FLAG_FROM_TEST(t->tsnap.target_select, + SET_FLAG_FROM_TEST(t->tsnap.target_operation, !(ts->snap_flag & SCE_SNAP_TO_INCLUDE_NONEDITED), SCE_SNAP_TARGET_NOT_NONEDITED); - SET_FLAG_FROM_TEST(t->tsnap.target_select, + SET_FLAG_FROM_TEST(t->tsnap.target_operation, (ts->snap_flag & SCE_SNAP_TO_ONLY_SELECTABLE), SCE_SNAP_TARGET_ONLY_SELECTABLE); } - t->tsnap.source_select = snap_source; + t->tsnap.source_operation = snap_source; initSnappingMode(t); } @@ -902,7 +903,7 @@ static void setSnappingCallback(TransInfo *t) /* Not with camera selected in camera view. */ return; } - t->tsnap.calcSnap = snap_calc_view3d_fn; + t->tsnap.snap_target_fn = snap_target_view3d_fn; } else if (t->spacetype == SPACE_IMAGE) { SpaceImage *sima = static_cast(t->area->spacedata.first); @@ -912,14 +913,14 @@ static void setSnappingCallback(TransInfo *t) const bool is_uv_editor = sima->mode == SI_MODE_UV; const bool has_edit_object = obact && BKE_object_is_in_editmode(obact); if (is_uv_editor && has_edit_object) { - t->tsnap.calcSnap = snap_calc_uv_fn; + t->tsnap.snap_target_fn = snap_target_uv_fn; } } else if (t->spacetype == SPACE_NODE) { - t->tsnap.calcSnap = snap_calc_node_fn; + t->tsnap.snap_target_fn = snap_target_node_fn; } else if (t->spacetype == SPACE_SEQ) { - t->tsnap.calcSnap = snap_calc_sequencer_fn; + t->tsnap.snap_target_fn = snap_target_sequencer_fn; /* The target is calculated along with the snap point. */ return; } @@ -927,23 +928,23 @@ static void setSnappingCallback(TransInfo *t) return; } - switch (t->tsnap.source_select) { + switch (t->tsnap.source_operation) { case SCE_SNAP_SOURCE_CLOSEST: - t->tsnap.targetSnap = TargetSnapClosest; + t->tsnap.snap_source_fn = snap_source_closest_fn; break; case SCE_SNAP_SOURCE_CENTER: if (!ELEM(t->mode, TFM_ROTATION, TFM_RESIZE)) { - t->tsnap.targetSnap = TargetSnapCenter; + t->tsnap.snap_source_fn = snap_source_center_fn; break; } /* Can't do TARGET_CENTER with these modes, * use TARGET_MEDIAN instead. */ ATTR_FALLTHROUGH; case SCE_SNAP_SOURCE_MEDIAN: - t->tsnap.targetSnap = TargetSnapMedian; + t->tsnap.snap_source_fn = snap_source_median_fn; break; case SCE_SNAP_SOURCE_ACTIVE: - t->tsnap.targetSnap = TargetSnapActive; + t->tsnap.snap_source_fn = snap_source_active_fn; break; } } @@ -951,16 +952,16 @@ static void setSnappingCallback(TransInfo *t) void addSnapPoint(TransInfo *t) { /* Currently only 3D viewport works for snapping points. */ - if (t->tsnap.status & POINT_INIT && t->spacetype == SPACE_VIEW3D) { + if (t->tsnap.status & SNAP_TARGET_FOUND && t->spacetype == SPACE_VIEW3D) { TransSnapPoint *p = MEM_cnew("SnapPoint"); t->tsnap.selectedPoint = p; - copy_v3_v3(p->co, t->tsnap.snapPoint); + copy_v3_v3(p->co, t->tsnap.snap_target); BLI_addtail(&t->tsnap.points, p); - t->tsnap.status |= MULTI_POINTS; + t->tsnap.status |= SNAP_MULTI_POINTS; } } @@ -968,7 +969,7 @@ eRedrawFlag updateSelectedSnapPoint(TransInfo *t) { eRedrawFlag status = TREDRAW_NOTHING; - if (t->tsnap.status & MULTI_POINTS) { + if (t->tsnap.status & SNAP_MULTI_POINTS) { TransSnapPoint *p, *closest_p = nullptr; float dist_min_sq = TRANSFORM_SNAP_MAX_PX; const float mval_fl[2] = {float(t->mval[0]), float(t->mval[1])}; @@ -1004,14 +1005,14 @@ eRedrawFlag updateSelectedSnapPoint(TransInfo *t) void removeSnapPoint(TransInfo *t) { - if (t->tsnap.status & MULTI_POINTS) { + if (t->tsnap.status & SNAP_MULTI_POINTS) { updateSelectedSnapPoint(t); if (t->tsnap.selectedPoint) { BLI_freelinkN(&t->tsnap.points, t->tsnap.selectedPoint); if (BLI_listbase_is_empty(&t->tsnap.points)) { - t->tsnap.status &= ~MULTI_POINTS; + t->tsnap.status &= ~SNAP_MULTI_POINTS; } t->tsnap.selectedPoint = nullptr; @@ -1031,15 +1032,15 @@ void getSnapPoint(const TransInfo *t, float vec[3]) add_v3_v3(vec, p->co); } - if (t->tsnap.status & POINT_INIT) { - add_v3_v3(vec, t->tsnap.snapPoint); + if (t->tsnap.status & SNAP_TARGET_FOUND) { + add_v3_v3(vec, t->tsnap.snap_target); total++; } mul_v3_fl(vec, 1.0f / total); } else { - copy_v3_v3(vec, t->tsnap.snapPoint); + copy_v3_v3(vec, t->tsnap.snap_target); } } @@ -1049,7 +1050,7 @@ void getSnapPoint(const TransInfo *t, float vec[3]) /** \name Calc Snap * \{ */ -static void snap_calc_view3d_fn(TransInfo *t, float * /*vec*/) +static void snap_target_view3d_fn(TransInfo *t, float * /*vec*/) { BLI_assert(t->spacetype == SPACE_VIEW3D); float loc[3]; @@ -1077,19 +1078,19 @@ static void snap_calc_view3d_fn(TransInfo *t, float * /*vec*/) } if (found == true) { - copy_v3_v3(t->tsnap.snapPoint, loc); + copy_v3_v3(t->tsnap.snap_target, loc); copy_v3_v3(t->tsnap.snapNormal, no); - t->tsnap.status |= POINT_INIT; + t->tsnap.status |= SNAP_TARGET_FOUND; } else { - t->tsnap.status &= ~POINT_INIT; + t->tsnap.status &= ~SNAP_TARGET_FOUND; } t->tsnap.snapElem = snap_elem; } -static void snap_calc_uv_fn(TransInfo *t, float * /*vec*/) +static void snap_target_uv_fn(TransInfo *t, float * /*vec*/) { BLI_assert(t->spacetype == SPACE_IMAGE); if (t->tsnap.mode & SCE_SNAP_MODE_VERTEX) { @@ -1103,22 +1104,22 @@ static void snap_calc_uv_fn(TransInfo *t, float * /*vec*/) objects, objects_len, t->mval, - t->tsnap.target_select & SCE_SNAP_TARGET_NOT_SELECTED, + t->tsnap.target_operation & SCE_SNAP_TARGET_NOT_SELECTED, &dist_sq, - t->tsnap.snapPoint)) { - t->tsnap.snapPoint[0] *= t->aspect[0]; - t->tsnap.snapPoint[1] *= t->aspect[1]; + t->tsnap.snap_target)) { + t->tsnap.snap_target[0] *= t->aspect[0]; + t->tsnap.snap_target[1] *= t->aspect[1]; - t->tsnap.status |= POINT_INIT; + t->tsnap.status |= SNAP_TARGET_FOUND; } else { - t->tsnap.status &= ~POINT_INIT; + t->tsnap.status &= ~SNAP_TARGET_FOUND; } MEM_freeN(objects); } } -static void snap_calc_node_fn(TransInfo *t, float * /*vec*/) +static void snap_target_node_fn(TransInfo *t, float * /*vec*/) { BLI_assert(t->spacetype == SPACE_NODE); if (t->tsnap.mode & (SCE_SNAP_MODE_NODE_X | SCE_SNAP_MODE_NODE_Y)) { @@ -1127,25 +1128,25 @@ static void snap_calc_node_fn(TransInfo *t, float * /*vec*/) char node_border; if (snapNodesTransform(t, t->mval, loc, &dist_px, &node_border)) { - copy_v2_v2(t->tsnap.snapPoint, loc); + copy_v2_v2(t->tsnap.snap_target, loc); t->tsnap.snapNodeBorder = node_border; - t->tsnap.status |= POINT_INIT; + t->tsnap.status |= SNAP_TARGET_FOUND; } else { - t->tsnap.status &= ~POINT_INIT; + t->tsnap.status &= ~SNAP_TARGET_FOUND; } } } -static void snap_calc_sequencer_fn(TransInfo *t, float * /*vec*/) +static void snap_target_sequencer_fn(TransInfo *t, float * /*vec*/) { BLI_assert(t->spacetype == SPACE_SEQ); if (transform_snap_sequencer_calc(t)) { - t->tsnap.status |= (POINT_INIT | TARGET_INIT); + t->tsnap.status |= (SNAP_TARGET_FOUND | SNAP_SOURCE_FOUND); } else { - t->tsnap.status &= ~(POINT_INIT | TARGET_INIT); + t->tsnap.status &= ~(SNAP_TARGET_FOUND | SNAP_SOURCE_FOUND); } } @@ -1198,62 +1199,62 @@ static void TargetSnapOffset(TransInfo *t, TransData *td) char border = t->tsnap.snapNodeBorder; if (border & NODE_LEFT) { - t->tsnap.snapTarget[0] -= 0.0f; + t->tsnap.snap_source[0] -= 0.0f; } if (border & NODE_RIGHT) { - t->tsnap.snapTarget[0] += BLI_rctf_size_x(&node->runtime->totr); + t->tsnap.snap_source[0] += BLI_rctf_size_x(&node->runtime->totr); } if (border & NODE_BOTTOM) { - t->tsnap.snapTarget[1] -= BLI_rctf_size_y(&node->runtime->totr); + t->tsnap.snap_source[1] -= BLI_rctf_size_y(&node->runtime->totr); } if (border & NODE_TOP) { - t->tsnap.snapTarget[1] += 0.0f; + t->tsnap.snap_source[1] += 0.0f; } } } -static void TargetSnapCenter(TransInfo *t) +static void snap_source_center_fn(TransInfo *t) { /* Only need to calculate once */ - if ((t->tsnap.status & TARGET_INIT) == 0) { - copy_v3_v3(t->tsnap.snapTarget, t->center_global); + if ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0) { + copy_v3_v3(t->tsnap.snap_source, t->center_global); TargetSnapOffset(t, nullptr); - t->tsnap.status |= TARGET_INIT; + t->tsnap.status |= SNAP_SOURCE_FOUND; } } -static void TargetSnapActive(TransInfo *t) +static void snap_source_active_fn(TransInfo *t) { /* Only need to calculate once */ - if ((t->tsnap.status & TARGET_INIT) == 0) { - if (calculateCenterActive(t, true, t->tsnap.snapTarget)) { + if ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0) { + if (calculateCenterActive(t, true, t->tsnap.snap_source)) { TargetSnapOffset(t, nullptr); - t->tsnap.status |= TARGET_INIT; + t->tsnap.status |= SNAP_SOURCE_FOUND; } /* No active, default to median */ else { - t->tsnap.source_select = SCE_SNAP_SOURCE_MEDIAN; - t->tsnap.targetSnap = TargetSnapMedian; - TargetSnapMedian(t); + t->tsnap.source_operation = SCE_SNAP_SOURCE_MEDIAN; + t->tsnap.snap_source_fn = snap_source_median_fn; + snap_source_median_fn(t); } } } -static void TargetSnapMedian(TransInfo *t) +static void snap_source_median_fn(TransInfo *t) { /* Only need to calculate once. */ - if ((t->tsnap.status & TARGET_INIT) == 0) { - tranform_snap_target_median_calc(t, t->tsnap.snapTarget); - t->tsnap.status |= TARGET_INIT; + if ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0) { + tranform_snap_target_median_calc(t, t->tsnap.snap_source); + t->tsnap.status |= SNAP_SOURCE_FOUND; } } -static void TargetSnapClosest(TransInfo *t) +static void snap_source_closest_fn(TransInfo *t) { /* Only valid if a snap point has been selected. */ - if (t->tsnap.status & POINT_INIT) { + if (t->tsnap.status & SNAP_TARGET_FOUND) { float dist_closest = 0.0f; TransData *closest = nullptr; @@ -1280,11 +1281,11 @@ static void TargetSnapClosest(TransInfo *t) copy_v3_v3(loc, bb->vec[j]); mul_m4_v3(td->ext->obmat, loc); - dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint); + dist = t->tsnap.snap_mode_distance_fn(t, loc, t->tsnap.snap_target); if ((dist != TRANSFORM_DIST_INVALID) && (closest == nullptr || fabsf(dist) < fabsf(dist_closest))) { - copy_v3_v3(t->tsnap.snapTarget, loc); + copy_v3_v3(t->tsnap.snap_source, loc); closest = td; dist_closest = dist; } @@ -1297,11 +1298,11 @@ static void TargetSnapClosest(TransInfo *t) copy_v3_v3(loc, td->center); - dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint); + dist = t->tsnap.snap_mode_distance_fn(t, loc, t->tsnap.snap_target); if ((dist != TRANSFORM_DIST_INVALID) && (closest == nullptr || fabsf(dist) < fabsf(dist_closest))) { - copy_v3_v3(t->tsnap.snapTarget, loc); + copy_v3_v3(t->tsnap.snap_source, loc); closest = td; } } @@ -1322,11 +1323,11 @@ static void TargetSnapClosest(TransInfo *t) mul_m4_v3(tc->mat, loc); } - dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint); + dist = t->tsnap.snap_mode_distance_fn(t, loc, t->tsnap.snap_target); if ((dist != TRANSFORM_DIST_INVALID) && (closest == nullptr || fabsf(dist) < fabsf(dist_closest))) { - copy_v3_v3(t->tsnap.snapTarget, loc); + copy_v3_v3(t->tsnap.snap_source, loc); closest = td; dist_closest = dist; } @@ -1336,7 +1337,7 @@ static void TargetSnapClosest(TransInfo *t) TargetSnapOffset(t, closest); - t->tsnap.status |= TARGET_INIT; + t->tsnap.status |= SNAP_SOURCE_FOUND; } } @@ -1350,12 +1351,12 @@ eSnapMode snapObjectsTransform( TransInfo *t, const float mval[2], float *dist_px, float r_loc[3], float r_no[3]) { SnapObjectParams snap_object_params{}; - snap_object_params.snap_target_select = t->tsnap.target_select; + snap_object_params.snap_target_select = t->tsnap.target_operation; snap_object_params.edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL; snap_object_params.use_occlusion_test = t->settings->snap_mode != SCE_SNAP_MODE_FACE_RAYCAST; snap_object_params.use_backface_culling = t->tsnap.use_backface_culling; - float *target = (t->tsnap.status & TARGET_INIT) ? t->tsnap.snapTarget : t->center_global; + float *target = (t->tsnap.status & SNAP_SOURCE_FOUND) ? t->tsnap.snap_source : t->center_global; return ED_transform_snap_object_project_view3d(t->tsnap.object_context, t->depsgraph, t->region, @@ -1385,7 +1386,7 @@ bool peelObjectsTransform(TransInfo *t, float *r_thickness) { SnapObjectParams snap_object_params{}; - snap_object_params.snap_target_select = t->tsnap.target_select; + snap_object_params.snap_target_select = t->tsnap.target_operation; snap_object_params.edit_mode_type = (t->flag & T_EDIT) != 0 ? SNAP_GEOM_EDIT : SNAP_GEOM_FINAL; ListBase depths_peel = {nullptr}; @@ -1461,7 +1462,7 @@ bool peelObjectsTransform(TransInfo *t, /** \name snap Nodes * \{ */ -static bool snapNodeTest(View2D *v2d, bNode *node, eSnapTargetSelect snap_target_select) +static bool snapNodeTest(View2D *v2d, bNode *node, eSnapTargetOP snap_target_select) { /* node is use for snapping only if a) snap mode matches and b) node is inside the view */ return (((snap_target_select & SCE_SNAP_TARGET_NOT_SELECTED) && !(node->flag & NODE_SELECT)) || @@ -1546,7 +1547,7 @@ static bool snapNodes(ToolSettings *ts, SpaceNode *snode, ARegion *region, const int mval[2], - eSnapTargetSelect snap_target_select, + eSnapTargetOP snap_target_select, float r_loc[2], float *r_dist_px, char *r_node_border) @@ -1573,7 +1574,7 @@ bool snapNodesTransform( static_cast(t->area->spacedata.first), t->region, mval, - t->tsnap.target_select, + t->tsnap.target_operation, r_loc, r_dist_px, r_node_border); diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index d55de8909a5..39e0fa1fc16 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -404,7 +404,7 @@ using IterSnapObjsCallback = eSnapMode (*)(SnapObjectContext *sctx, void *data); static bool snap_object_is_snappable(const SnapObjectContext *sctx, - const eSnapTargetSelect snap_target_select, + const eSnapTargetOP snap_target_select, const Base *base_act, const Base *base) { @@ -471,7 +471,7 @@ static eSnapMode iter_snap_objects(SnapObjectContext *sctx, Scene *scene = DEG_get_input_scene(sctx->runtime.depsgraph); ViewLayer *view_layer = DEG_get_input_view_layer(sctx->runtime.depsgraph); - const eSnapTargetSelect snap_target_select = params->snap_target_select; + const eSnapTargetOP snap_target_select = params->snap_target_select; BKE_view_layer_synced_ensure(scene, view_layer); Base *base_act = BKE_view_layer_active_base_get(view_layer); diff --git a/source/blender/editors/transform/transform_snap_sequencer.c b/source/blender/editors/transform/transform_snap_sequencer.c index 10a51750ed3..0fda2c64867 100644 --- a/source/blender/editors/transform/transform_snap_sequencer.c +++ b/source/blender/editors/transform/transform_snap_sequencer.c @@ -319,14 +319,14 @@ bool transform_snap_sequencer_calc(TransInfo *t) return false; } - t->tsnap.snapPoint[0] = best_target_frame; - t->tsnap.snapTarget[0] = best_source_frame; + t->tsnap.snap_target[0] = best_target_frame; + t->tsnap.snap_source[0] = best_source_frame; return true; } void transform_snap_sequencer_apply_translate(TransInfo *t, float *vec) { - *vec += t->tsnap.snapPoint[0] - t->tsnap.snapTarget[0]; + *vec += t->tsnap.snap_target[0] - t->tsnap.snap_source[0]; } static int transform_snap_sequencer_to_closest_strip_ex(TransInfo *t, int frame_1, int frame_2) @@ -357,11 +357,11 @@ static int transform_snap_sequencer_to_closest_strip_ex(TransInfo *t, int frame_ float snap_offset = 0; if (snap_success) { - t->tsnap.status |= (POINT_INIT | TARGET_INIT); + t->tsnap.status |= (SNAP_TARGET_FOUND | SNAP_SOURCE_FOUND); transform_snap_sequencer_apply_translate(t, &snap_offset); } else { - t->tsnap.status &= ~(POINT_INIT | TARGET_INIT); + t->tsnap.status &= ~(SNAP_TARGET_FOUND | SNAP_SOURCE_FOUND); } return snap_offset; @@ -382,7 +382,7 @@ bool ED_transform_snap_sequencer_to_closest_strip_calc(Scene *scene, t.tsnap.mode = SEQ_tool_settings_snap_mode_get(scene); *r_snap_distance = transform_snap_sequencer_to_closest_strip_ex(&t, frame_1, frame_2); - *r_snap_frame = t.tsnap.snapPoint[0]; + *r_snap_frame = t.tsnap.snap_target[0]; return validSnap(&t); } @@ -393,8 +393,8 @@ void ED_draw_sequencer_snap_point(struct bContext *C, float snap_point) t.mode = TFM_SEQ_SLIDE; t.modifiers = MOD_SNAP; t.spacetype = SPACE_SEQ; - t.tsnap.status = (POINT_INIT | TARGET_INIT); - t.tsnap.snapPoint[0] = snap_point; + t.tsnap.status = (SNAP_TARGET_FOUND | SNAP_SOURCE_FOUND); + t.tsnap.snap_target[0] = snap_point; drawSnapping(C, &t); } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index a42fb09dbf7..ab16b3b986b 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1618,7 +1618,7 @@ typedef struct ToolSettings { short snap_flag_node; short snap_flag_seq; short snap_uv_flag; - /** Default snap source, #eSnapSourceSelect. */ + /** Default snap source, #eSnapSourceOP. */ /** * TODO(@gfxcoder): Rename `snap_target` to `snap_source` to avoid previous ambiguity of * "target" (now, "source" is geometry to be moved and "target" is geometry to which moved @@ -2244,7 +2244,7 @@ typedef enum eSnapFlag { SCE_SNAP_ABS_GRID = (1 << 5), SCE_SNAP_BACKFACE_CULLING = (1 << 6), SCE_SNAP_KEEP_ON_SAME_OBJECT = (1 << 7), - /** see #eSnapTargetSelect */ + /** see #eSnapTargetOP */ SCE_SNAP_TO_INCLUDE_EDITED = (1 << 8), SCE_SNAP_TO_INCLUDE_NONEDITED = (1 << 9), SCE_SNAP_TO_ONLY_SELECTABLE = (1 << 10), @@ -2255,30 +2255,30 @@ typedef enum eSnapFlag { ENUM_OPERATORS(eSnapFlag, SCE_SNAP_BACKFACE_CULLING) #endif -/** See #ToolSettings.snap_target (to be renamed `snap_source`) and #TransSnap.source_select */ -typedef enum eSnapSourceSelect { +/** See #ToolSettings.snap_target (to be renamed `snap_source`) and #TransSnap.source_operation */ +typedef enum eSnapSourceOP { SCE_SNAP_SOURCE_CLOSEST = 0, SCE_SNAP_SOURCE_CENTER = 1, SCE_SNAP_SOURCE_MEDIAN = 2, SCE_SNAP_SOURCE_ACTIVE = 3, -} eSnapSourceSelect; +} eSnapSourceOP; -ENUM_OPERATORS(eSnapSourceSelect, SCE_SNAP_SOURCE_ACTIVE) +ENUM_OPERATORS(eSnapSourceOP, SCE_SNAP_SOURCE_ACTIVE) /** - * #TransSnap.target_select and #ToolSettings.snap_flag + * #TransSnap.target_operation and #ToolSettings.snap_flag * (#SCE_SNAP_NOT_TO_ACTIVE, #SCE_SNAP_TO_INCLUDE_EDITED, #SCE_SNAP_TO_INCLUDE_NONEDITED, * #SCE_SNAP_TO_ONLY_SELECTABLE). */ -typedef enum eSnapTargetSelect { +typedef enum eSnapTargetOP { SCE_SNAP_TARGET_ALL = 0, SCE_SNAP_TARGET_NOT_SELECTED = (1 << 0), SCE_SNAP_TARGET_NOT_ACTIVE = (1 << 1), SCE_SNAP_TARGET_NOT_EDITED = (1 << 2), SCE_SNAP_TARGET_ONLY_SELECTABLE = (1 << 3), SCE_SNAP_TARGET_NOT_NONEDITED = (1 << 4), -} eSnapTargetSelect; -ENUM_OPERATORS(eSnapTargetSelect, SCE_SNAP_TARGET_NOT_NONEDITED) +} eSnapTargetOP; +ENUM_OPERATORS(eSnapTargetOP, SCE_SNAP_TARGET_NOT_NONEDITED) /** #ToolSettings.snap_mode */ typedef enum eSnapMode { From 063caae72e472719fee8c27ff8d70c824617497c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Ch=C3=A9hab?= Date: Thu, 12 Jan 2023 15:35:25 +0100 Subject: [PATCH 0615/1522] GPencil: Fix unreported error in Build modifier In patch D16759 cleanup a else was removed by error which deals with situations where current gpf was copied, so that previous gpf may have MORE strokes than current gpf. Reviewed By: antoniov Differential Revision: https://developer.blender.org/D16986 --- source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c index e4320a7b5a8..2d2d36ab20e 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c @@ -289,6 +289,9 @@ static void build_sequential(Object *ob, if (start_stroke <= tot_strokes) { tot_strokes = tot_strokes - start_stroke; } + else { + start_stroke = 0; + } } /* 2) Compute proportion of time each stroke should occupy. */ From b2746876f2883798cc3487dcda2ba83e92f0d29b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 12 Jan 2023 16:18:55 +0100 Subject: [PATCH 0616/1522] EEVEE: Avoid glitchy displacement on curve geometry This is caused by the partial derivatives not being precise enough to take the tube shape into account. For now we just disable displacement bump for this type of geometry to match cycles. Fixes T101175 Eevee displacement behavior changed --- source/blender/draw/engines/eevee/shaders/surface_frag.glsl | 6 ++++++ .../draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl index 3af422b3877..bf105bd907b 100644 --- a/source/blender/draw/engines/eevee/shaders/surface_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/surface_frag.glsl @@ -21,6 +21,11 @@ vec3 displacement_exec(); /* Return new shading normal. */ vec3 displacement_bump() { +# ifdef HAIR_SHADER + /* Not supported. */ + return normalize(g_data.N); +# else + vec2 dHd; dF_branch(dot(displacement_exec(), g_data.N + dF_impl(g_data.N)), dHd); @@ -38,6 +43,7 @@ vec3 displacement_bump() float facing = FrontFacing ? 1.0 : -1.0; return normalize(abs(det) * g_data.N - facing * sign(det) * surfgrad); +# endif } #endif diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl index 4b53375575c..965780d9bcf 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_nodetree_lib.glsl @@ -277,7 +277,7 @@ void output_aov(vec4 color, float value, uint hash) /* Return new shading normal. */ vec3 displacement_bump() { -# ifdef GPU_FRAGMENT_SHADER +# if defined(GPU_FRAGMENT_SHADER) && !defined(MAT_GEOM_CURVES) vec2 dHd; dF_branch(dot(nodetree_displacement(), g_data.N + dF_impl(g_data.N)), dHd); From b599820418fbfa1cbec88572ed5ff8a6dbce9e13 Mon Sep 17 00:00:00 2001 From: Aras Pranckevicius Date: Thu, 12 Jan 2023 22:47:39 +0200 Subject: [PATCH 0617/1522] OBJ: add split by objects/groups import options (T103839) The new C++ OBJ importer was missing "split by objects" / "split by groups" import settings of the older Python importer. Implements T103839. Added test coverage for all 4 possible combinations of these two options. --- source/blender/editors/io/io_obj.c | 14 +++ .../io/wavefront_obj/IO_wavefront_obj.h | 2 + .../importer/obj_import_file_reader.cc | 56 +++++++--- .../wavefront_obj/importer/obj_import_mesh.cc | 9 +- .../wavefront_obj/tests/obj_importer_tests.cc | 105 ++++++++++++++++-- 5 files changed, 160 insertions(+), 26 deletions(-) diff --git a/source/blender/editors/io/io_obj.c b/source/blender/editors/io/io_obj.c index ce121203972..e1dba4ee954 100644 --- a/source/blender/editors/io/io_obj.c +++ b/source/blender/editors/io/io_obj.c @@ -410,6 +410,8 @@ static int wm_obj_import_exec(bContext *C, wmOperator *op) import_params.clamp_size = RNA_float_get(op->ptr, "clamp_size"); import_params.forward_axis = RNA_enum_get(op->ptr, "forward_axis"); import_params.up_axis = RNA_enum_get(op->ptr, "up_axis"); + import_params.use_split_objects = RNA_boolean_get(op->ptr, "use_split_objects"); + import_params.use_split_groups = RNA_boolean_get(op->ptr, "use_split_groups"); import_params.import_vertex_groups = RNA_boolean_get(op->ptr, "import_vertex_groups"); import_params.validate_meshes = RNA_boolean_get(op->ptr, "validate_meshes"); import_params.relative_paths = ((U.flag & USER_RELPATHS) != 0); @@ -472,6 +474,8 @@ static void ui_obj_import_settings(uiLayout *layout, PointerRNA *imfptr) box = uiLayoutBox(layout); uiItemL(box, IFACE_("Options"), ICON_EXPORT); col = uiLayoutColumn(box, false); + uiItemR(col, imfptr, "use_split_objects", 0, NULL, ICON_NONE); + uiItemR(col, imfptr, "use_split_groups", 0, NULL, ICON_NONE); uiItemR(col, imfptr, "import_vertex_groups", 0, NULL, ICON_NONE); uiItemR(col, imfptr, "validate_meshes", 0, NULL, ICON_NONE); } @@ -531,6 +535,16 @@ void WM_OT_obj_import(struct wmOperatorType *ot) RNA_def_property_update_runtime(prop, (void *)forward_axis_update); prop = RNA_def_enum(ot->srna, "up_axis", io_transform_axis, IO_AXIS_Y, "Up Axis", ""); RNA_def_property_update_runtime(prop, (void *)up_axis_update); + RNA_def_boolean(ot->srna, + "use_split_objects", + true, + "Split By Object", + "Import each OBJ 'o' as a separate object"); + RNA_def_boolean(ot->srna, + "use_split_groups", + false, + "Split By Group", + "Import each OBJ 'g' as a separate object"); RNA_def_boolean(ot->srna, "import_vertex_groups", false, diff --git a/source/blender/io/wavefront_obj/IO_wavefront_obj.h b/source/blender/io/wavefront_obj/IO_wavefront_obj.h index cf6464eeb37..2c039958bee 100644 --- a/source/blender/io/wavefront_obj/IO_wavefront_obj.h +++ b/source/blender/io/wavefront_obj/IO_wavefront_obj.h @@ -68,6 +68,8 @@ struct OBJImportParams { float global_scale; eIOAxis forward_axis; eIOAxis up_axis; + bool use_split_objects; + bool use_split_groups; bool import_vertex_groups; bool validate_meshes; bool relative_paths; diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc index 1a3a333d957..b90a0c99424 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc @@ -363,6 +363,24 @@ static void geom_update_smooth_group(const char *p, const char *end, bool &r_sta r_state_shaded_smooth = smooth != 0; } +static void geom_new_object(const char *p, + const char *end, + bool &r_state_shaded_smooth, + std::string &r_state_group_name, + int &r_state_material_index, + Geometry *&r_curr_geom, + Vector> &r_all_geometries) +{ + r_state_shaded_smooth = false; + r_state_group_name = ""; + /* Reset object-local material index that's used in face infos. + * NOTE: do not reset the material name; that has to carry over + * into the next object if needed. */ + r_state_material_index = -1; + r_curr_geom = create_geometry( + r_curr_geom, GEOM_MESH, StringRef(p, end).trim(), r_all_geometries); +} + OBJParser::OBJParser(const OBJImportParams &import_params, size_t read_buffer_size = 64 * 1024) : import_params_(import_params), read_buffer_size_(read_buffer_size) { @@ -534,22 +552,34 @@ void OBJParser::parse(Vector> &r_all_geometries, } /* Objects. */ else if (parse_keyword(p, end, "o")) { - state_shaded_smooth = false; - state_group_name = ""; - /* Reset object-local material index that's used in face infos. - * NOTE: do not reset the material name; that has to carry over - * into the next object if needed. */ - state_material_index = -1; - curr_geom = create_geometry( - curr_geom, GEOM_MESH, StringRef(p, end).trim(), r_all_geometries); + if (import_params_.use_split_objects) { + geom_new_object(p, + end, + state_shaded_smooth, + state_group_name, + state_material_index, + curr_geom, + r_all_geometries); + } } /* Groups. */ else if (parse_keyword(p, end, "g")) { - geom_update_group(StringRef(p, end).trim(), state_group_name); - int new_index = curr_geom->group_indices_.size(); - state_group_index = curr_geom->group_indices_.lookup_or_add(state_group_name, new_index); - if (new_index == state_group_index) { - curr_geom->group_order_.append(state_group_name); + if (import_params_.use_split_groups) { + geom_new_object(p, + end, + state_shaded_smooth, + state_group_name, + state_material_index, + curr_geom, + r_all_geometries); + } + else { + geom_update_group(StringRef(p, end).trim(), state_group_name); + int new_index = curr_geom->group_indices_.size(); + state_group_index = curr_geom->group_indices_.lookup_or_add(state_group_name, new_index); + if (new_index == state_group_index) { + curr_geom->group_order_.append(state_group_name); + } } } /* Smoothing groups. */ diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc index 6323b5ba1fc..794d307730c 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mesh.cc @@ -53,7 +53,7 @@ Object *MeshFromGeometry::create_mesh(Main *bmain, obj->data = BKE_object_obdata_add_from_type(bmain, OB_MESH, ob_name.c_str()); create_vertices(mesh); - create_polys_loops(mesh, import_params.import_vertex_groups); + create_polys_loops(mesh, import_params.import_vertex_groups && !import_params.use_split_groups); create_edges(mesh); create_uv_verts(mesh); create_normals(mesh); @@ -222,8 +222,11 @@ void MeshFromGeometry::create_polys_loops(Mesh *mesh, bool use_vertex_groups) continue; } const int group_index = curr_face.vertex_group_index; - MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[mloop.v], group_index); - dw->weight = 1.0f; + /* Note: face might not belong to any group */ + if (group_index >= 0 || 1) { + MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[mloop.v], group_index); + dw->weight = 1.0f; + } } } diff --git a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc index 5f5587577a1..f15687e7bef 100644 --- a/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_importer_tests.cc @@ -48,6 +48,19 @@ struct Expectation { class obj_importer_test : public BlendfileLoadingBaseTest { public: + obj_importer_test() + { + params.global_scale = 1.0f; + params.clamp_size = 0; + params.forward_axis = IO_AXIS_NEGATIVE_Z; + params.up_axis = IO_AXIS_Y; + params.validate_meshes = true; + params.use_split_objects = true; + params.use_split_groups = false; + params.import_vertex_groups = false; + params.relative_paths = true; + params.clear_selection = true; + } void import_and_check(const char *path, const Expectation *expect, size_t expect_count, @@ -59,16 +72,6 @@ class obj_importer_test : public BlendfileLoadingBaseTest { return; } - OBJImportParams params; - params.global_scale = 1.0f; - params.clamp_size = 0; - params.forward_axis = IO_AXIS_NEGATIVE_Z; - params.up_axis = IO_AXIS_Y; - params.validate_meshes = true; - params.import_vertex_groups = false; - params.relative_paths = true; - params.clear_selection = true; - std::string obj_path = blender::tests::flags_test_asset_dir() + "/io_tests/obj/" + path; strncpy(params.filepath, obj_path.c_str(), FILE_MAX - 1); const size_t read_buffer_size = 650; @@ -81,6 +84,32 @@ class obj_importer_test : public BlendfileLoadingBaseTest { deg_iter_settings.flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE | DEG_ITER_OBJECT_FLAG_DUPLI; + + constexpr bool print_result_scene = false; + if (print_result_scene) { + printf("Result was:\n"); + DEG_OBJECT_ITER_BEGIN (°_iter_settings, object) { + printf(" {\"%s\", ", object->id.name); + if (object->type == OB_MESH) { + Mesh *mesh = BKE_object_get_evaluated_mesh(object); + const Span positions = mesh->vert_positions(); + printf("OB_MESH, %i, %i, %i, %i, float3(%g, %g, %g), float3(%g, %g, %g)", + mesh->totvert, + mesh->totedge, + mesh->totpoly, + mesh->totloop, + positions.first().x, + positions.first().y, + positions.first().z, + positions.last().x, + positions.last().y, + positions.last().z); + } + printf("},\n"); + } + DEG_OBJECT_ITER_END; + } + size_t object_index = 0; DEG_OBJECT_ITER_BEGIN (°_iter_settings, object) { if (object_index >= expect_count) { @@ -152,6 +181,8 @@ class obj_importer_test : public BlendfileLoadingBaseTest { const int ima_count = BLI_listbase_count(&bfile->main->images); EXPECT_EQ(ima_count, expect_image_count); } + + OBJImportParams params; }; TEST_F(obj_importer_test, import_cube) @@ -784,4 +815,58 @@ TEST_F(obj_importer_test, import_vertices) import_and_check("vertices.obj", expect, std::size(expect), 0); } +TEST_F(obj_importer_test, import_split_options_by_object) +{ + /* Default is to split by object */ + Expectation expect[] = { + {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, + {"OBBox", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, -1, 1)}, + {"OBPyramid", OB_MESH, 5, 8, 5, 16, float3(3, 1, -1), float3(4, 0, 2)}, + }; + import_and_check("split_options.obj", expect, std::size(expect), 0); +} + +TEST_F(obj_importer_test, import_split_options_by_group) +{ + params.use_split_objects = false; + params.use_split_groups = true; + Expectation expect[] = { + {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, + {"OBBoxOne", OB_MESH, 4, 4, 1, 4, float3(1, -1, -1), float3(-1, -1, 1)}, + {"OBBoxTwo", OB_MESH, 6, 7, 2, 8, float3(1, 1, 1), float3(-1, -1, 1)}, + {"OBBoxTwo.001", OB_MESH, 6, 7, 2, 8, float3(1, 1, -1), float3(-1, -1, -1)}, + {"OBPyrBottom", OB_MESH, 4, 4, 1, 4, float3(3, 1, -1), float3(3, -1, -1)}, + {"OBPyrSides", OB_MESH, 5, 8, 4, 12, float3(3, 1, -1), float3(4, 0, 2)}, + {"OBsplit_options", OB_MESH, 4, 4, 1, 4, float3(1, 1, -1), float3(-1, 1, 1)}, + }; + import_and_check("split_options.obj", expect, std::size(expect), 0); +} + +TEST_F(obj_importer_test, import_split_options_by_object_and_group) +{ + params.use_split_objects = true; + params.use_split_groups = true; + Expectation expect[] = { + {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, + {"OBBox", OB_MESH, 4, 4, 1, 4, float3(1, 1, -1), float3(-1, 1, 1)}, + {"OBBoxOne", OB_MESH, 4, 4, 1, 4, float3(1, -1, -1), float3(-1, -1, 1)}, + {"OBBoxTwo", OB_MESH, 6, 7, 2, 8, float3(1, 1, 1), float3(-1, -1, 1)}, + {"OBBoxTwo.001", OB_MESH, 6, 7, 2, 8, float3(1, 1, -1), float3(-1, -1, -1)}, + {"OBPyrBottom", OB_MESH, 4, 4, 1, 4, float3(3, 1, -1), float3(3, -1, -1)}, + {"OBPyrSides", OB_MESH, 5, 8, 4, 12, float3(3, 1, -1), float3(4, 0, 2)}, + }; + import_and_check("split_options.obj", expect, std::size(expect), 0); +} + +TEST_F(obj_importer_test, import_split_options_none) +{ + params.use_split_objects = false; + params.use_split_groups = false; + Expectation expect[] = { + {"OBCube", OB_MESH, 8, 12, 6, 24, float3(1, 1, -1), float3(-1, 1, 1)}, + {"OBsplit_options", OB_MESH, 13, 20, 11, 40, float3(1, 1, -1), float3(4, 0, 2)}, + }; + import_and_check("split_options.obj", expect, std::size(expect), 0); +} + } // namespace blender::io::obj From bbe7183cd39de1417f27d2558bb717dd1aa1081d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 13 Jan 2023 17:48:50 +1100 Subject: [PATCH 0618/1522] GHOST/Wayland: fix threaded event handling The previous fix from T100855 [0] no longer works on my system (3.4.1 release also fails for GNOME/KDE/WLROOTS compositors). Resolve by removing the loop from the wait-on-file handle check. Also reduce locking/unlocking calls. [0]: 37b256e26feb454d9febd84dac1b1ce8b8d84d90 --- intern/ghost/intern/GHOST_SystemWayland.cpp | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index d823db2afd7..ef8ccd66685 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -1669,24 +1669,24 @@ static int ghost_wl_display_event_pump_from_thread(struct wl_display *wl_display else { wl_display_cancel_read(wl_display); } + + server_mutex->unlock(); } else { - int state; - do { - server_mutex->unlock(); - /* Wait for input (unlocked, so as not to block other threads). */ - state = file_descriptor_is_io_ready(fd, GWL_IOR_READ | GWL_IOR_NO_RETRY, INT32_MAX); + server_mutex->unlock(); + + /* Wait for input (unlocked, so as not to block other threads). */ + int state = file_descriptor_is_io_ready(fd, GWL_IOR_READ | GWL_IOR_NO_RETRY, INT32_MAX); + /* Re-check `state` with a lock held, needed to avoid holding the lock. */ + if (state > 0) { server_mutex->lock(); - /* Re-check `state` with a lock held, needed to avoid holding the lock. */ + state = file_descriptor_is_io_ready(fd, GWL_IOR_READ | GWL_IOR_NO_RETRY, 0); if (state > 0) { - state = file_descriptor_is_io_ready(fd, GWL_IOR_READ | GWL_IOR_NO_RETRY, 0); - if (state > 0) { - err = wl_display_dispatch_pending(wl_display); - } + err = wl_display_dispatch_pending(wl_display); } - } while (state > 0); + server_mutex->unlock(); + } } - server_mutex->unlock(); return err; } From 0c2a3054ba92494fb1a63ceea3bf441093fd5b03 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 13 Jan 2023 17:48:52 +1100 Subject: [PATCH 0619/1522] Fix high CPU use when idle under Wayland Recently the event handling thread for Wayland sometimes used 100% of a CPU core while idle. Resolve by waiting for changes to the Wayland file-handle when there are no events to read. --- intern/ghost/intern/GHOST_SystemWayland.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index ef8ccd66685..d9e5b0c4e9d 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -1662,15 +1662,23 @@ static int ghost_wl_display_event_pump_from_thread(struct wl_display *wl_display server_mutex->lock(); int err = 0; if (wl_display_prepare_read(wl_display) == 0) { + bool wait_on_fd = false; /* Use #GWL_IOR_NO_RETRY to ensure #SIGINT will break us out of our wait. */ if (file_descriptor_is_io_ready(fd, GWL_IOR_READ | GWL_IOR_NO_RETRY, 0) > 0) { err = wl_display_read_events(wl_display); } else { wl_display_cancel_read(wl_display); + /* Without this, the thread will loop continuously, 100% CPU. */ + wait_on_fd = true; } server_mutex->unlock(); + + if (wait_on_fd) { + /* Important this runs after unlocking. */ + file_descriptor_is_io_ready(fd, GWL_IOR_READ | GWL_IOR_NO_RETRY, INT32_MAX); + } } else { server_mutex->unlock(); From c158dd560e5399d8bfa7386790e7b43c9f91db8e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 13 Jan 2023 17:48:54 +1100 Subject: [PATCH 0620/1522] WM: reduce CPU use while idle in ED_view3d_datamask When idle, each 3D view made two calls CTX_data_mode_enum(C) from the WM_main loop. While not causing problems it complicated troubleshooting high CPU use while idle in other areas. Access the object via the view layer, giving approx 40x speedup. --- source/blender/editors/include/ED_view3d.h | 6 +-- .../blender/editors/render/render_opengl.cc | 2 +- .../editors/space_view3d/view3d_draw.cc | 38 +++++++++++++------ .../windowmanager/intern/wm_event_system.cc | 4 +- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 12313b3d244..35930d1a9b4 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -1104,15 +1104,13 @@ char ED_view3d_lock_view_from_index(int index); char ED_view3d_axis_view_opposite(char view); bool ED_view3d_lock(struct RegionView3D *rv3d); -void ED_view3d_datamask(const struct bContext *C, - const struct Scene *scene, +void ED_view3d_datamask(const struct ViewLayer *view_layer, const struct View3D *v3d, struct CustomData_MeshMasks *r_cddata_masks); /** * Goes over all modes and view3d settings. */ -void ED_view3d_screen_datamask(const struct bContext *C, - const struct Scene *scene, +void ED_view3d_screen_datamask(const struct ViewLayer *view_layer, const struct bScreen *screen, struct CustomData_MeshMasks *r_cddata_masks); diff --git a/source/blender/editors/render/render_opengl.cc b/source/blender/editors/render/render_opengl.cc index d5e3d1171cd..d91f1a09beb 100644 --- a/source/blender/editors/render/render_opengl.cc +++ b/source/blender/editors/render/render_opengl.cc @@ -809,7 +809,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) 0, sizeof(oglrender->scene->customdata_mask_modal)); ED_view3d_datamask( - C, oglrender->scene, oglrender->v3d, &oglrender->scene->customdata_mask_modal); + oglrender->view_layer, oglrender->v3d, &oglrender->scene->customdata_mask_modal); /* apply immediately in case we're rendering from a script, * running notifiers again will overwrite */ diff --git a/source/blender/editors/space_view3d/view3d_draw.cc b/source/blender/editors/space_view3d/view3d_draw.cc index 91bfc104f5b..95407afbeda 100644 --- a/source/blender/editors/space_view3d/view3d_draw.cc +++ b/source/blender/editors/space_view3d/view3d_draw.cc @@ -2407,11 +2407,13 @@ void ED_view3d_depths_free(ViewDepths *depths) /** \name Custom-data Utilities * \{ */ -void ED_view3d_datamask(const bContext *C, - const Scene * /*scene*/, +void ED_view3d_datamask(const ViewLayer *view_layer, const View3D *v3d, CustomData_MeshMasks *r_cddata_masks) { + /* NOTE(@campbellbarton): as this function runs continuously while idle + * (from #wm_event_do_depsgraph) take care to avoid expensive lookups. + * While they won't hurt performance noticeably, they will increase CPU usage while idle. */ if (ELEM(v3d->shading.type, OB_TEXTURE, OB_MATERIAL, OB_RENDER)) { r_cddata_masks->lmask |= CD_MASK_PROP_FLOAT2 | CD_MASK_PROP_BYTE_COLOR; r_cddata_masks->vmask |= CD_MASK_ORCO | CD_MASK_PROP_COLOR; @@ -2426,26 +2428,38 @@ void ED_view3d_datamask(const bContext *C, } } - if ((CTX_data_mode_enum(C) == CTX_MODE_EDIT_MESH) && - (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT)) { - r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; - } - if (CTX_data_mode_enum(C) == CTX_MODE_SCULPT) { - r_cddata_masks->vmask |= CD_MASK_PAINT_MASK; + Object *obact = BKE_view_layer_active_object_get(view_layer); + if (obact) { + switch (obact->type) { + case OB_MESH: { + switch (obact->mode) { + case OB_MODE_EDIT: { + if (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_WEIGHT) { + r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT; + } + break; + } + case OB_MODE_SCULPT: { + r_cddata_masks->vmask |= CD_MASK_PAINT_MASK; + break; + } + } + break; + } + } } } -void ED_view3d_screen_datamask(const bContext *C, - const Scene *scene, +void ED_view3d_screen_datamask(const ViewLayer *view_layer, const bScreen *screen, CustomData_MeshMasks *r_cddata_masks) { CustomData_MeshMasks_update(r_cddata_masks, &CD_MASK_BAREMESH); - /* Check if we need tfaces & mcols due to view mode. */ + /* Check if we need UV or color data due to the view mode. */ LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) { if (area->spacetype == SPACE_VIEW3D) { - ED_view3d_datamask(C, scene, static_cast(area->spacedata.first), r_cddata_masks); + ED_view3d_datamask(view_layer, static_cast(area->spacedata.first), r_cddata_masks); } } } diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index 14812c4335d..df1bdfdc4aa 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -423,10 +423,10 @@ void wm_event_do_depsgraph(bContext *C, bool is_after_open_file) /* Combine data-masks so one window doesn't disable UVs in another T26448. */ CustomData_MeshMasks win_combine_v3d_datamask = {0}; LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { - const Scene *scene = WM_window_get_active_scene(win); + const ViewLayer *view_layer = WM_window_get_active_view_layer(win); const bScreen *screen = WM_window_get_active_screen(win); - ED_view3d_screen_datamask(C, scene, screen, &win_combine_v3d_datamask); + ED_view3d_screen_datamask(view_layer, screen, &win_combine_v3d_datamask); } /* Update all the dependency graphs of visible view layers. */ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { From daedf19315519d7279b762b72f7cb50bdaf26606 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 12 Jan 2023 23:57:01 -0800 Subject: [PATCH 0621/1522] Sculpt: Fix T103724: missing mask attr existance check for PBVH_GRIDS --- release/datafiles/locale | 2 +- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- source/blender/editors/sculpt_paint/sculpt.cc | 5 +++++ source/tools | 2 +- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/release/datafiles/locale b/release/datafiles/locale index 4f6dbb69893..7084c4ecd97 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 4f6dbb69893bd6bdf73467effe77ae46c8e4ee37 +Subproject commit 7084c4ecd97d93459d9d23fd90f81589b09be5df diff --git a/release/scripts/addons b/release/scripts/addons index bf49eeaa14c..a9d4443c244 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit bf49eeaa14c445d3c53068203fdf91bff568fe64 +Subproject commit a9d4443c244f89399ec4bcc427e05a07950528cc diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index 0f72f6c85c3..bdcfdd47ec3 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit 0f72f6c85c3743a9072273acb6a8a34b1cf1064b +Subproject commit bdcfdd47ec3451822b21d1cff2ea2db751093c9a diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index e1586e00788..dd3e38258dc 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -259,6 +259,11 @@ float SCULPT_vertex_mask_get(SculptSession *ss, PBVHVertRef vertex) } case PBVH_GRIDS: { const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); + + if (key->mask_offset == -1) { + return 0.0f; + } + const int grid_index = vertex.i / key->grid_area; const int vertex_index = vertex.i - grid_index * key->grid_area; CCGElem *elem = BKE_pbvh_get_grids(ss->pbvh)[grid_index]; diff --git a/source/tools b/source/tools index 3582f5326d0..e1744b9bd82 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit 3582f5326d08ca05c2a19056597e49ec5511d854 +Subproject commit e1744b9bd82527cf7e8af63362b61bd309b5711b From bc3da3ad41a906414c589625bb3cd92384ddbcc3 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Fri, 13 Jan 2023 00:10:46 -0800 Subject: [PATCH 0622/1522] Sculpt: fix T103454: SCULPT_vertex_is_occluded is not compatible with filters --- source/blender/editors/sculpt_paint/sculpt.cc | 7 +++++-- source/blender/editors/sculpt_paint/sculpt_filter_mesh.c | 2 ++ source/blender/editors/sculpt_paint/sculpt_intern.h | 4 ++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index dd3e38258dc..af03fe06092 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -6225,9 +6225,12 @@ bool SCULPT_vertex_is_occluded(SculptSession *ss, PBVHVertRef vertex, bool origi copy_v3_v3(co, SCULPT_vertex_co_get(ss, vertex)); float mouse[2]; - ED_view3d_project_float_v2_m4(ss->cache->vc->region, co, mouse, ss->cache->projection_mat); + ViewContext *vc = ss->cache ? ss->cache->vc : &ss->filter_cache->vc; - int depth = SCULPT_raycast_init(ss->cache->vc, mouse, ray_end, ray_start, ray_normal, original); + ED_view3d_project_float_v2_m4( + vc->region, co, mouse, ss->cache ? ss->cache->projection_mat : ss->filter_cache->viewmat); + + int depth = SCULPT_raycast_init(vc, mouse, ray_end, ray_start, ray_normal, original); negate_v3(ray_normal); diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c index f6bf9c0c488..9ffe10360af 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c @@ -152,6 +152,8 @@ void SCULPT_filter_cache_init(bContext *C, Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); ViewContext vc; ED_view3d_viewcontext_init(C, &vc, depsgraph); + + ss->filter_cache->vc = vc; copy_m4_m4(ss->filter_cache->viewmat, vc.rv3d->viewmat); copy_m4_m4(ss->filter_cache->viewmat_inv, vc.rv3d->viewinv); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 6a6fce851e7..700fba4cd40 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -22,6 +22,8 @@ #include "BLI_gsqueue.h" #include "BLI_threads.h" +#include "ED_view3d.h" + #ifdef __cplusplus extern "C" { #endif @@ -486,6 +488,8 @@ typedef struct FilterCache { /* Pre-smoothed colors used by sharpening. Colors are HSL. */ float (*pre_smoothed_color)[4]; + + ViewContext vc; } FilterCache; /** From 2fb829a2deb809af6589a2eec19c16fdf4718de6 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 13 Jan 2023 13:03:02 +0100 Subject: [PATCH 0623/1522] Fix T103837: crash opening a specific file Caused by {rBd397ecae325}. Above commit added a new socket, so `version_geometry_nodes_primitive_uv_maps` was getting the wrong sockect with `->next`. Now get the right one with yet another `->next` (might not be ideal, but searching the right socket with other methods might be overhead?) Maniphest Tasks: T103837 Differential Revision: https://developer.blender.org/D16994 --- source/blender/blenloader/intern/versioning_300.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index ddb9f157d18..0a68a526d0f 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -876,7 +876,7 @@ static void version_geometry_nodes_primitive_uv_maps(bNodeTree &ntree) bNodeSocket *store_attribute_geometry_input = static_cast( store_attribute_node->inputs.first); - bNodeSocket *store_attribute_name_input = store_attribute_geometry_input->next; + bNodeSocket *store_attribute_name_input = store_attribute_geometry_input->next->next; bNodeSocket *store_attribute_value_input = nullptr; LISTBASE_FOREACH (bNodeSocket *, socket, &store_attribute_node->inputs) { if (socket->type == SOCK_VECTOR) { From d4e638baac4352f022f89c6d189f7e7ee46eb073 Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Mon, 9 Jan 2023 18:09:22 +0100 Subject: [PATCH 0624/1522] User Interface: Re-organization of Geometry Nodes Add Node Menu The menus are growing too large. This patches move some categories under sub-menus, and shuffle some entries around. We already had sub-categories split by separators. This change now goes a step further and embrace 3-level menus. Inspired by the "Simpler Add Menu" add-on by Quackers (waiting to hear back to know Quackers real name). Inspired by the "Simpler Add Menu" add-on by Alfonso Martinez II. Differential Revision: https://developer.blender.org/D16993 --- .../startup/bl_ui/node_add_menu_geometry.py | 349 ++++++++++++++---- 1 file changed, 268 insertions(+), 81 deletions(-) diff --git a/release/scripts/startup/bl_ui/node_add_menu_geometry.py b/release/scripts/startup/bl_ui/node_add_menu_geometry.py index cc5f210e536..f86601da88c 100644 --- a/release/scripts/startup/bl_ui/node_add_menu_geometry.py +++ b/release/scripts/startup/bl_ui/node_add_menu_geometry.py @@ -12,9 +12,10 @@ class NODE_MT_geometry_node_GEO_ATTRIBUTE(Menu): def draw(self, _context): layout = self.layout node_add_menu.add_node_type(layout, "GeometryNodeAttributeStatistic") + node_add_menu.add_node_type(layout, "GeometryNodeAttributeDomainSize") + layout.separator() node_add_menu.add_node_type(layout, "GeometryNodeBlurAttribute") node_add_menu.add_node_type(layout, "GeometryNodeCaptureAttribute") - node_add_menu.add_node_type(layout, "GeometryNodeAttributeDomainSize") node_add_menu.add_node_type(layout, "GeometryNodeRemoveAttribute") node_add_menu.add_node_type(layout, "GeometryNodeStoreNamedAttribute") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) @@ -27,12 +28,13 @@ class NODE_MT_geometry_node_GEO_COLOR(Menu): def draw(self, _context): layout = self.layout node_add_menu.add_node_type(layout, "ShaderNodeValToRGB") + node_add_menu.add_node_type(layout, "ShaderNodeRGBCurve") + layout.separator() node_add_menu.add_node_type(layout, "FunctionNodeCombineColor") props = node_add_menu.add_node_type(layout, "ShaderNodeMix", label=iface_("Mix Color")) ops = props.settings.add() ops.name = "data_type" ops.value = "'RGBA'" - node_add_menu.add_node_type(layout, "ShaderNodeRGBCurve") node_add_menu.add_node_type(layout, "FunctionNodeSeparateColor") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) @@ -43,19 +45,23 @@ class NODE_MT_geometry_node_GEO_CURVE(Menu): def draw(self, _context): layout = self.layout - node_add_menu.add_node_type(layout, "GeometryNodeCurveLength") - node_add_menu.add_node_type(layout, "GeometryNodeCurveToMesh") - node_add_menu.add_node_type(layout, "GeometryNodeCurveToPoints") - node_add_menu.add_node_type(layout, "GeometryNodeDeformCurvesOnSurface") - node_add_menu.add_node_type(layout, "GeometryNodeFillCurve") - node_add_menu.add_node_type(layout, "GeometryNodeFilletCurve") - node_add_menu.add_node_type(layout, "GeometryNodeResampleCurve") - node_add_menu.add_node_type(layout, "GeometryNodeReverseCurve") - node_add_menu.add_node_type(layout, "GeometryNodeSampleCurve") - node_add_menu.add_node_type(layout, "GeometryNodeSubdivideCurve") - node_add_menu.add_node_type(layout, "GeometryNodeTrimCurve") + layout.menu("NODE_MT_geometry_node_GEO_CURVE_READ") + layout.menu("NODE_MT_geometry_node_GEO_CURVE_WRITE") layout.separator() + layout.menu("NODE_MT_geometry_node_GEO_CURVE_OPERATIONS") + layout.menu("NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE") + layout.menu("NODE_MT_geometry_node_curve_topology") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + + +class NODE_MT_geometry_node_GEO_CURVE_READ(Menu): + bl_idname = "NODE_MT_geometry_node_GEO_CURVE_READ" + bl_label = "Read" + + def draw(self, _context): + layout = self.layout node_add_menu.add_node_type(layout, "GeometryNodeInputCurveHandlePositions") + node_add_menu.add_node_type(layout, "GeometryNodeCurveLength") node_add_menu.add_node_type(layout, "GeometryNodeInputTangent") node_add_menu.add_node_type(layout, "GeometryNodeInputCurveTilt") node_add_menu.add_node_type(layout, "GeometryNodeCurveEndpointSelection") @@ -64,7 +70,14 @@ class NODE_MT_geometry_node_GEO_CURVE(Menu): node_add_menu.add_node_type(layout, "GeometryNodeSplineLength") node_add_menu.add_node_type(layout, "GeometryNodeSplineParameter") node_add_menu.add_node_type(layout, "GeometryNodeInputSplineResolution") - layout.separator() + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + +class NODE_MT_geometry_node_GEO_CURVE_WRITE(Menu): + bl_idname = "NODE_MT_geometry_node_GEO_CURVE_WRITE" + bl_label = "Write" + + def draw(self, _context): + layout = self.layout node_add_menu.add_node_type(layout, "GeometryNodeSetCurveNormal") node_add_menu.add_node_type(layout, "GeometryNodeSetCurveRadius") node_add_menu.add_node_type(layout, "GeometryNodeSetCurveTilt") @@ -76,9 +89,28 @@ class NODE_MT_geometry_node_GEO_CURVE(Menu): node_add_menu.draw_assets_for_catalog(layout, self.bl_label) +class NODE_MT_geometry_node_GEO_CURVE_OPERATIONS(Menu): + bl_idname = "NODE_MT_geometry_node_GEO_CURVE_OPERATIONS" + bl_label = "Operations" + + def draw(self, _context): + layout = self.layout + node_add_menu.add_node_type(layout, "GeometryNodeCurveToMesh") + node_add_menu.add_node_type(layout, "GeometryNodeCurveToPoints") + node_add_menu.add_node_type(layout, "GeometryNodeDeformCurvesOnSurface") + node_add_menu.add_node_type(layout, "GeometryNodeFillCurve") + node_add_menu.add_node_type(layout, "GeometryNodeFilletCurve") + node_add_menu.add_node_type(layout, "GeometryNodeResampleCurve") + node_add_menu.add_node_type(layout, "GeometryNodeReverseCurve") + node_add_menu.add_node_type(layout, "GeometryNodeSampleCurve") + node_add_menu.add_node_type(layout, "GeometryNodeSubdivideCurve") + node_add_menu.add_node_type(layout, "GeometryNodeTrimCurve") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + + class NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE(Menu): bl_idname = "NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE" - bl_label = "Curve Primitives" + bl_label = "Primitives" def draw(self, _context): layout = self.layout @@ -95,7 +127,7 @@ class NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE(Menu): class NODE_MT_geometry_node_curve_topology(Menu): bl_idname = "NODE_MT_geometry_node_curve_topology" - bl_label = "Curve Topology" + bl_label = "Topology" def draw(self, _context): layout = self.layout @@ -109,25 +141,69 @@ class NODE_MT_geometry_node_GEO_GEOMETRY(Menu): bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY" bl_label = "Geometry" + def draw(self, _context): + layout = self.layout + layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY_READ") + layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY_WRITE") + layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS") + layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY_SAMPLE") + layout.separator() + node_add_menu.add_node_type(layout, "GeometryNodeJoinGeometry") + node_add_menu.add_node_type(layout, "GeometryNodeGeometryToInstance") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + +class NODE_MT_geometry_node_GEO_GEOMETRY_READ(Menu): + bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY_READ" + bl_label = "Read" + + def draw(self, _context): + layout = self.layout + node_add_menu.add_node_type(layout, "GeometryNodeInputID") + node_add_menu.add_node_type(layout, "GeometryNodeInputIndex") + node_add_menu.add_node_type(layout, "GeometryNodeInputNamedAttribute") + node_add_menu.add_node_type(layout, "GeometryNodeInputNormal") + node_add_menu.add_node_type(layout, "GeometryNodeInputPosition") + node_add_menu.add_node_type(layout, "GeometryNodeInputRadius") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + + +class NODE_MT_geometry_node_GEO_GEOMETRY_WRITE(Menu): + bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY_WRITE" + bl_label = "Write" + + def draw(self, _context): + layout = self.layout + node_add_menu.add_node_type(layout, "GeometryNodeSetID") + node_add_menu.add_node_type(layout, "GeometryNodeSetPosition") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + +class NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS(Menu): + bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS" + bl_label = "Operations" + def draw(self, _context): layout = self.layout node_add_menu.add_node_type(layout, "GeometryNodeBoundBox") node_add_menu.add_node_type(layout, "GeometryNodeConvexHull") node_add_menu.add_node_type(layout, "GeometryNodeDeleteGeometry") node_add_menu.add_node_type(layout, "GeometryNodeDuplicateElements") - node_add_menu.add_node_type(layout, "GeometryNodeProximity") - node_add_menu.add_node_type(layout, "GeometryNodeGeometryToInstance") - node_add_menu.add_node_type(layout, "GeometryNodeJoinGeometry") node_add_menu.add_node_type(layout, "GeometryNodeMergeByDistance") + node_add_menu.add_node_type(layout, "GeometryNodeTransform") + layout.separator() + node_add_menu.add_node_type(layout, "GeometryNodeSeparateComponents") + node_add_menu.add_node_type(layout, "GeometryNodeSeparateGeometry") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + +class NODE_MT_geometry_node_GEO_GEOMETRY_SAMPLE(Menu): + bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY_SAMPLE" + bl_label = "Sample" + + def draw(self, _context): + layout = self.layout + node_add_menu.add_node_type(layout, "GeometryNodeProximity") node_add_menu.add_node_type(layout, "GeometryNodeRaycast") node_add_menu.add_node_type(layout, "GeometryNodeSampleIndex") node_add_menu.add_node_type(layout, "GeometryNodeSampleNearest") - node_add_menu.add_node_type(layout, "GeometryNodeSeparateComponents") - node_add_menu.add_node_type(layout, "GeometryNodeSeparateGeometry") - node_add_menu.add_node_type(layout, "GeometryNodeTransform") - layout.separator() - node_add_menu.add_node_type(layout, "GeometryNodeSetID") - node_add_menu.add_node_type(layout, "GeometryNodeSetPosition") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) @@ -135,28 +211,52 @@ class NODE_MT_geometry_node_GEO_INPUT(Menu): bl_idname = "NODE_MT_geometry_node_GEO_INPUT" bl_label = "Input" + def draw(self, _context): + layout = self.layout + layout.menu("NODE_MT_geometry_node_GEO_INPUT_CONSTANT") + layout.menu("NODE_MT_geometry_node_GEO_INPUT_GROUP") + layout.menu("NODE_MT_geometry_node_GEO_INPUT_SCENE") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + + +class NODE_MT_geometry_node_GEO_INPUT_CONSTANT(Menu): + bl_idname = "NODE_MT_geometry_node_GEO_INPUT_CONSTANT" + bl_label = "Constant" + def draw(self, _context): layout = self.layout node_add_menu.add_node_type(layout, "FunctionNodeInputBool") - node_add_menu.add_node_type(layout, "GeometryNodeCollectionInfo") node_add_menu.add_node_type(layout, "FunctionNodeInputColor") node_add_menu.add_node_type(layout, "GeometryNodeInputImage") - node_add_menu.add_node_type(layout, "GeometryNodeImageInfo") node_add_menu.add_node_type(layout, "FunctionNodeInputInt") - node_add_menu.add_node_type(layout, "GeometryNodeIsViewport") node_add_menu.add_node_type(layout, "GeometryNodeInputMaterial") - node_add_menu.add_node_type(layout, "GeometryNodeObjectInfo") - node_add_menu.add_node_type(layout, "GeometryNodeSelfObject") node_add_menu.add_node_type(layout, "FunctionNodeInputString") node_add_menu.add_node_type(layout, "ShaderNodeValue") node_add_menu.add_node_type(layout, "FunctionNodeInputVector") - layout.separator() - node_add_menu.add_node_type(layout, "GeometryNodeInputID") - node_add_menu.add_node_type(layout, "GeometryNodeInputIndex") - node_add_menu.add_node_type(layout, "GeometryNodeInputNamedAttribute") - node_add_menu.add_node_type(layout, "GeometryNodeInputNormal") - node_add_menu.add_node_type(layout, "GeometryNodeInputPosition") - node_add_menu.add_node_type(layout, "GeometryNodeInputRadius") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + + +class NODE_MT_geometry_node_GEO_INPUT_GROUP(Menu): + bl_idname = "NODE_MT_geometry_node_GEO_INPUT_GROUP" + bl_label = "Group" + + def draw(self, _context): + layout = self.layout + node_add_menu.add_node_type(layout, "NodeGroupInput") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + + +class NODE_MT_geometry_node_GEO_INPUT_SCENE(Menu): + bl_idname = "NODE_MT_geometry_node_GEO_INPUT_SCENE" + bl_label = "Scene" + + def draw(self, _context): + layout = self.layout + node_add_menu.add_node_type(layout, "GeometryNodeCollectionInfo") + node_add_menu.add_node_type(layout, "GeometryNodeImageInfo") + node_add_menu.add_node_type(layout, "GeometryNodeIsViewport") + node_add_menu.add_node_type(layout, "GeometryNodeObjectInfo") + node_add_menu.add_node_type(layout, "GeometryNodeSelfObject") node_add_menu.add_node_type(layout, "GeometryNodeInputSceneTime") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) @@ -169,6 +269,7 @@ class NODE_MT_geometry_node_GEO_INSTANCE(Menu): layout = self.layout node_add_menu.add_node_type(layout, "GeometryNodeInstanceOnPoints") node_add_menu.add_node_type(layout, "GeometryNodeInstancesToPoints") + layout.separator() node_add_menu.add_node_type(layout, "GeometryNodeRealizeInstances") node_add_menu.add_node_type(layout, "GeometryNodeRotateInstances") node_add_menu.add_node_type(layout, "GeometryNodeScaleInstances") @@ -199,6 +300,52 @@ class NODE_MT_geometry_node_GEO_MESH(Menu): bl_idname = "NODE_MT_geometry_node_GEO_MESH" bl_label = "Mesh" + def draw(self, _context): + layout = self.layout + layout.menu("NODE_MT_geometry_node_GEO_MESH_READ") + layout.menu("NODE_MT_geometry_node_GEO_MESH_WRITE") + layout.separator() + layout.menu("NODE_MT_geometry_node_GEO_MESH_OPERATIONS") + layout.menu("NODE_MT_category_PRIMITIVES_MESH") + layout.menu("NODE_MT_geometry_node_mesh_topology") + layout.menu("NODE_MT_category_GEO_UV") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + + +class NODE_MT_geometry_node_GEO_MESH_READ(Menu): + bl_idname = "NODE_MT_geometry_node_GEO_MESH_READ" + bl_label = "Read" + + def draw(self, _context): + layout = self.layout + node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeAngle") + node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeNeighbors") + node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeVertices") + node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceArea") + node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceNeighbors") + node_add_menu.add_node_type(layout, "GeometryNodeMeshFaceSetBoundaries") + node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceIsPlanar") + node_add_menu.add_node_type(layout, "GeometryNodeInputShadeSmooth") + node_add_menu.add_node_type(layout, "GeometryNodeInputMeshIsland") + node_add_menu.add_node_type(layout, "GeometryNodeInputShortestEdgePaths") + node_add_menu.add_node_type(layout, "GeometryNodeInputMeshVertexNeighbors") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + + +class NODE_MT_geometry_node_GEO_MESH_WRITE(Menu): + bl_idname = "NODE_MT_geometry_node_GEO_MESH_WRITE" + bl_label = "Write" + + def draw(self, _context): + layout = self.layout + node_add_menu.add_node_type(layout, "GeometryNodeSetShadeSmooth") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + + +class NODE_MT_geometry_node_GEO_MESH_OPERATIONS(Menu): + bl_idname = "NODE_MT_geometry_node_GEO_MESH_OPERATIONS" + bl_label = "Operations" + def draw(self, _context): layout = self.layout node_add_menu.add_node_type(layout, "GeometryNodeDualMesh") @@ -217,26 +364,12 @@ class NODE_MT_geometry_node_GEO_MESH(Menu): node_add_menu.add_node_type(layout, "GeometryNodeSubdivideMesh") node_add_menu.add_node_type(layout, "GeometryNodeSubdivisionSurface") node_add_menu.add_node_type(layout, "GeometryNodeTriangulate") - layout.separator() - node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeAngle") - node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeNeighbors") - node_add_menu.add_node_type(layout, "GeometryNodeInputMeshEdgeVertices") - node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceArea") - node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceNeighbors") - node_add_menu.add_node_type(layout, "GeometryNodeMeshFaceSetBoundaries") - node_add_menu.add_node_type(layout, "GeometryNodeInputMeshFaceIsPlanar") - node_add_menu.add_node_type(layout, "GeometryNodeInputShadeSmooth") - node_add_menu.add_node_type(layout, "GeometryNodeInputMeshIsland") - node_add_menu.add_node_type(layout, "GeometryNodeInputShortestEdgePaths") - node_add_menu.add_node_type(layout, "GeometryNodeInputMeshVertexNeighbors") - layout.separator() - node_add_menu.add_node_type(layout, "GeometryNodeSetShadeSmooth") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) class NODE_MT_category_PRIMITIVES_MESH(Menu): bl_idname = "NODE_MT_category_PRIMITIVES_MESH" - bl_label = "Mesh Primitives" + bl_label = "Primitives" def draw(self, _context): layout = self.layout @@ -253,7 +386,7 @@ class NODE_MT_category_PRIMITIVES_MESH(Menu): class NODE_MT_geometry_node_mesh_topology(Menu): bl_idname = "NODE_MT_geometry_node_mesh_topology" - bl_label = "Mesh Topology" + bl_label = "Topology" def draw(self, _context): layout = self.layout @@ -273,6 +406,7 @@ class NODE_MT_category_GEO_OUTPUT(Menu): def draw(self, _context): layout = self.layout + node_add_menu.add_node_type(layout, "NodeGroupOutput") node_add_menu.add_node_type(layout, "GeometryNodeViewer") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) @@ -285,6 +419,7 @@ class NODE_MT_category_GEO_POINT(Menu): layout = self.layout node_add_menu.add_node_type(layout, "GeometryNodeDistributePointsInVolume") node_add_menu.add_node_type(layout, "GeometryNodeDistributePointsOnFaces") + layout.separator() node_add_menu.add_node_type(layout, "GeometryNodePoints") node_add_menu.add_node_type(layout, "GeometryNodePointsToVertices") node_add_menu.add_node_type(layout, "GeometryNodePointsToVolume") @@ -302,6 +437,7 @@ class NODE_MT_category_GEO_TEXT(Menu): node_add_menu.add_node_type(layout, "GeometryNodeStringJoin") node_add_menu.add_node_type(layout, "FunctionNodeReplaceString") node_add_menu.add_node_type(layout, "FunctionNodeSliceString") + layout.separator() node_add_menu.add_node_type(layout, "FunctionNodeStringLength") node_add_menu.add_node_type(layout, "GeometryNodeStringToCurves") node_add_menu.add_node_type(layout, "FunctionNodeValueToString") @@ -333,23 +469,57 @@ class NODE_MT_category_GEO_UTILITIES(Menu): bl_idname = "NODE_MT_category_GEO_UTILITIES" bl_label = "Utilities" + def draw(self, _context): + layout = self.layout + layout.menu("NODE_MT_geometry_node_GEO_COLOR") + layout.menu("NODE_MT_category_GEO_TEXT") + layout.menu("NODE_MT_category_GEO_VECTOR") + layout.separator() + layout.menu("NODE_MT_category_GEO_UTILITIES_FIELD") + layout.menu("NODE_MT_category_GEO_UTILITIES_MATH") + layout.menu("NODE_MT_category_GEO_UTILITIES_ROTATION") + layout.separator() + node_add_menu.add_node_type(layout, "FunctionNodeRandomValue") + node_add_menu.add_node_type(layout, "GeometryNodeSwitch") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + + +class NODE_MT_category_GEO_UTILITIES_FIELD(Menu): + bl_idname = "NODE_MT_category_GEO_UTILITIES_FIELD" + bl_label = "Field" + def draw(self, _context): layout = self.layout node_add_menu.add_node_type(layout, "GeometryNodeAccumulateField") + node_add_menu.add_node_type(layout, "GeometryNodeFieldAtIndex") + node_add_menu.add_node_type(layout, "GeometryNodeFieldOnDomain") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + + +class NODE_MT_category_GEO_UTILITIES_ROTATION(Menu): + bl_idname = "NODE_MT_category_GEO_UTILITIES_ROTATION" + bl_label = "Rotation" + + def draw(self, _context): + layout = self.layout node_add_menu.add_node_type(layout, "FunctionNodeAlignEulerToVector") + node_add_menu.add_node_type(layout, "FunctionNodeRotateEuler") + node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + +class NODE_MT_category_GEO_UTILITIES_MATH(Menu): + bl_idname = "NODE_MT_category_GEO_UTILITIES_MATH" + bl_label = "Math" + + def draw(self, _context): + layout = self.layout node_add_menu.add_node_type(layout, "FunctionNodeBooleanMath") node_add_menu.add_node_type(layout, "ShaderNodeClamp") node_add_menu.add_node_type(layout, "FunctionNodeCompare") - node_add_menu.add_node_type(layout, "GeometryNodeFieldAtIndex") node_add_menu.add_node_type(layout, "ShaderNodeFloatCurve") node_add_menu.add_node_type(layout, "FunctionNodeFloatToInt") - node_add_menu.add_node_type(layout, "GeometryNodeFieldOnDomain") node_add_menu.add_node_type(layout, "ShaderNodeMapRange") node_add_menu.add_node_type(layout, "ShaderNodeMath") node_add_menu.add_node_type(layout, "ShaderNodeMix") - node_add_menu.add_node_type(layout, "FunctionNodeRandomValue") - node_add_menu.add_node_type(layout, "FunctionNodeRotateEuler") - node_add_menu.add_node_type(layout, "GeometryNodeSwitch") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) @@ -370,11 +540,16 @@ class NODE_MT_category_GEO_VECTOR(Menu): def draw(self, _context): layout = self.layout - node_add_menu.add_node_type(layout, "ShaderNodeCombineXYZ") - node_add_menu.add_node_type(layout, "ShaderNodeSeparateXYZ") node_add_menu.add_node_type(layout, "ShaderNodeVectorCurve") node_add_menu.add_node_type(layout, "ShaderNodeVectorMath") node_add_menu.add_node_type(layout, "ShaderNodeVectorRotate") + layout.separator() + node_add_menu.add_node_type(layout, "ShaderNodeCombineXYZ") + props = node_add_menu.add_node_type(layout, "ShaderNodeMix", label=iface_("Mix Vector")) + ops = props.settings.add() + ops.name = "data_type" + ops.value = "'VECTOR'" + node_add_menu.add_node_type(layout, "ShaderNodeSeparateXYZ") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) @@ -417,25 +592,21 @@ class NODE_MT_geometry_node_add_all(Menu): def draw(self, _context): layout = self.layout layout.menu("NODE_MT_geometry_node_GEO_ATTRIBUTE") - layout.menu("NODE_MT_geometry_node_GEO_COLOR") - layout.menu("NODE_MT_geometry_node_GEO_CURVE") - layout.menu("NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE") - layout.menu("NODE_MT_geometry_node_curve_topology") - layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY") layout.menu("NODE_MT_geometry_node_GEO_INPUT") - layout.menu("NODE_MT_geometry_node_GEO_INSTANCE") - layout.menu("NODE_MT_geometry_node_GEO_MATERIAL") - layout.menu("NODE_MT_geometry_node_GEO_MESH") - layout.menu("NODE_MT_category_PRIMITIVES_MESH") - layout.menu("NODE_MT_geometry_node_mesh_topology") layout.menu("NODE_MT_category_GEO_OUTPUT") + layout.separator() + layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY") + layout.separator() + layout.menu("NODE_MT_geometry_node_GEO_CURVE") + layout.menu("NODE_MT_geometry_node_GEO_INSTANCE") + layout.menu("NODE_MT_geometry_node_GEO_MESH") layout.menu("NODE_MT_category_GEO_POINT") - layout.menu("NODE_MT_category_GEO_TEXT") + layout.menu("NODE_MT_category_GEO_VOLUME") + layout.separator() + layout.menu("NODE_MT_geometry_node_GEO_MATERIAL") layout.menu("NODE_MT_category_GEO_TEXTURE") layout.menu("NODE_MT_category_GEO_UTILITIES") - layout.menu("NODE_MT_category_GEO_UV") - layout.menu("NODE_MT_category_GEO_VECTOR") - layout.menu("NODE_MT_category_GEO_VOLUME") + layout.separator() layout.menu("NODE_MT_category_GEO_GROUP") layout.menu("NODE_MT_category_GEO_LAYOUT") node_add_menu.draw_root_assets(layout) @@ -444,25 +615,41 @@ class NODE_MT_geometry_node_add_all(Menu): classes = ( NODE_MT_geometry_node_add_all, NODE_MT_geometry_node_GEO_ATTRIBUTE, - NODE_MT_geometry_node_GEO_COLOR, + NODE_MT_geometry_node_GEO_INPUT, + NODE_MT_geometry_node_GEO_INPUT_CONSTANT, + NODE_MT_geometry_node_GEO_INPUT_GROUP, + NODE_MT_geometry_node_GEO_INPUT_SCENE, + NODE_MT_category_GEO_OUTPUT, NODE_MT_geometry_node_GEO_CURVE, + NODE_MT_geometry_node_GEO_CURVE_READ, + NODE_MT_geometry_node_GEO_CURVE_WRITE, + NODE_MT_geometry_node_GEO_CURVE_OPERATIONS, NODE_MT_geometry_node_GEO_PRIMITIVES_CURVE, NODE_MT_geometry_node_curve_topology, NODE_MT_geometry_node_GEO_GEOMETRY, - NODE_MT_geometry_node_GEO_INPUT, + NODE_MT_geometry_node_GEO_GEOMETRY_READ, + NODE_MT_geometry_node_GEO_GEOMETRY_WRITE, + NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS, + NODE_MT_geometry_node_GEO_GEOMETRY_SAMPLE, NODE_MT_geometry_node_GEO_INSTANCE, - NODE_MT_geometry_node_GEO_MATERIAL, NODE_MT_geometry_node_GEO_MESH, + NODE_MT_geometry_node_GEO_MESH_READ, + NODE_MT_geometry_node_GEO_MESH_WRITE, + NODE_MT_geometry_node_GEO_MESH_OPERATIONS, + NODE_MT_category_GEO_UV, NODE_MT_category_PRIMITIVES_MESH, NODE_MT_geometry_node_mesh_topology, - NODE_MT_category_GEO_OUTPUT, NODE_MT_category_GEO_POINT, - NODE_MT_category_GEO_TEXT, + NODE_MT_category_GEO_VOLUME, + NODE_MT_geometry_node_GEO_MATERIAL, NODE_MT_category_GEO_TEXTURE, NODE_MT_category_GEO_UTILITIES, - NODE_MT_category_GEO_UV, + NODE_MT_geometry_node_GEO_COLOR, + NODE_MT_category_GEO_TEXT, NODE_MT_category_GEO_VECTOR, - NODE_MT_category_GEO_VOLUME, + NODE_MT_category_GEO_UTILITIES_FIELD, + NODE_MT_category_GEO_UTILITIES_MATH, + NODE_MT_category_GEO_UTILITIES_ROTATION, NODE_MT_category_GEO_GROUP, NODE_MT_category_GEO_LAYOUT, ) From 761e6b1b78da9bcfdb4bafdd2a9db062c8d4963c Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 13 Jan 2023 17:25:20 +0100 Subject: [PATCH 0625/1522] Fix: crash when opening node add menu Differential Revision: https://developer.blender.org/D16995 --- source/blender/editors/space_node/add_menu_assets.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/editors/space_node/add_menu_assets.cc b/source/blender/editors/space_node/add_menu_assets.cc index 912493c3e7e..060e8914194 100644 --- a/source/blender/editors/space_node/add_menu_assets.cc +++ b/source/blender/editors/space_node/add_menu_assets.cc @@ -108,6 +108,9 @@ static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree *node const asset_system::AssetCatalog *catalog = all_library->catalog_service->find_catalog( meta_data.catalog_id); + if (catalog == nullptr) { + return true; + } assets_per_path.add(catalog->path, LibraryAsset{all_library_ref, asset}); return true; }); @@ -121,6 +124,9 @@ static AssetItemTree build_catalog_tree(const bContext &C, const bNodeTree *node } asset_system::AssetCatalog *catalog = all_library->catalog_service->find_catalog( item.get_catalog_id()); + if (catalog == nullptr) { + return; + } catalogs_with_node_assets.insert_item(*catalog); }); From 046d1a414be887bc9959ea9557427788b332674a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 13 Jan 2023 10:47:24 -0600 Subject: [PATCH 0626/1522] Fix: Curves select all operator name The operator is used for edit mode and sculpt mode, so it shouldn't have the sculpt prefix. --- .../presets/keyconfig/keymap_data/blender_default.py | 2 +- release/scripts/startup/bl_ui/space_view3d.py | 6 +++--- source/blender/editors/curves/intern/curves_ops.cc | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index b02454cfa86..c861236c468 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5636,7 +5636,7 @@ def km_sculpt_curves(params): ("curves.set_selection_domain", {"type": 'ONE', "value": 'PRESS'}, {"properties": [("domain", 'POINT')]}), ("curves.set_selection_domain", {"type": 'TWO', "value": 'PRESS'}, {"properties": [("domain", 'CURVE')]}), *_template_paint_radial_control("curves_sculpt"), - *_template_items_select_actions(params, "sculpt_curves.select_all"), + *_template_items_select_actions(params, "curves.select_all"), ("sculpt_curves.min_distance_edit", {"type": 'R', "value": 'PRESS', "shift": True}, {}), ("sculpt_curves.select_grow", {"type": 'A', "value": 'PRESS', "shift": True}, {}), ]) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index bb11ed80ac2..3bb009dd2ad 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2053,9 +2053,9 @@ class VIEW3D_MT_select_sculpt_curves(Menu): def draw(self, _context): layout = self.layout - layout.operator("sculpt_curves.select_all", text="All").action = 'SELECT' - layout.operator("sculpt_curves.select_all", text="None").action = 'DESELECT' - layout.operator("sculpt_curves.select_all", text="Invert").action = 'INVERT' + layout.operator("curves.select_all", text="All").action = 'SELECT' + layout.operator("curves.select_all", text="None").action = 'DESELECT' + layout.operator("curves.select_all", text="Invert").action = 'INVERT' layout.operator("sculpt_curves.select_random", text="Random") layout.operator("sculpt_curves.select_end", text="Endpoints") layout.operator("sculpt_curves.select_grow", text="Grow") diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 9a998b34f3c..1a9bd13a15b 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -923,10 +923,10 @@ static int select_all_exec(bContext *C, wmOperator *op) } // namespace select_all -static void SCULPT_CURVES_OT_select_all(wmOperatorType *ot) +static void CURVES_OT_select_all(wmOperatorType *ot) { ot->name = "(De)select All"; - ot->idname = __func__; + ot->idname = "CURVES_OT_select_all"; ot->description = "(De)select all control points"; ot->exec = select_all::select_all_exec; @@ -1029,6 +1029,6 @@ void ED_operatortypes_curves() WM_operatortype_append(CURVES_OT_convert_from_particle_system); WM_operatortype_append(CURVES_OT_snap_curves_to_surface); WM_operatortype_append(CURVES_OT_set_selection_domain); - WM_operatortype_append(SCULPT_CURVES_OT_select_all); + WM_operatortype_append(CURVES_OT_select_all); WM_operatortype_append(CURVES_OT_surface_set); } From ba714198913cf580293ebd30fb638364b62f854b Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 13 Jan 2023 18:09:10 +0100 Subject: [PATCH 0627/1522] Cleanup: improve const correctness of bvh tree --- source/blender/blenlib/BLI_kdopbvh.h | 33 +++++++++++---------- source/blender/blenlib/intern/BLI_kdopbvh.c | 31 ++++++++++--------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 463c95cf4f3..ac083b71e33 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -203,7 +203,7 @@ BVHTreeOverlap *BLI_bvhtree_overlap_self(const BVHTree *tree, BVHTree_OverlapCallback callback, void *userdata); -int *BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_num); +int *BLI_bvhtree_intersect_plane(const BVHTree *tree, float plane[4], uint *r_intersect_num); /** * Number of times #BLI_bvhtree_insert has been called. @@ -218,20 +218,20 @@ float BLI_bvhtree_get_epsilon(const BVHTree *tree); /** * This function returns the bounding box of the BVH tree. */ -void BLI_bvhtree_get_bounding_box(BVHTree *tree, float r_bb_min[3], float r_bb_max[3]); +void BLI_bvhtree_get_bounding_box(const BVHTree *tree, float r_bb_min[3], float r_bb_max[3]); /** * Find nearest node to the given coordinates * (if nearest is given it will only search nodes where * square distance is smaller than nearest->dist). */ -int BLI_bvhtree_find_nearest_ex(BVHTree *tree, +int BLI_bvhtree_find_nearest_ex(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata, int flag); -int BLI_bvhtree_find_nearest(BVHTree *tree, +int BLI_bvhtree_find_nearest(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, @@ -241,13 +241,13 @@ int BLI_bvhtree_find_nearest(BVHTree *tree, * Find the first node nearby. * Favors speed over quality since it doesn't find the best target node. */ -int BLI_bvhtree_find_nearest_first(BVHTree *tree, +int BLI_bvhtree_find_nearest_first(const BVHTree *tree, const float co[3], float dist_sq, BVHTree_NearestPointCallback callback, void *userdata); -int BLI_bvhtree_ray_cast_ex(BVHTree *tree, +int BLI_bvhtree_ray_cast_ex(const BVHTree *tree, const float co[3], const float dir[3], float radius, @@ -255,7 +255,7 @@ int BLI_bvhtree_ray_cast_ex(BVHTree *tree, BVHTree_RayCastCallback callback, void *userdata, int flag); -int BLI_bvhtree_ray_cast(BVHTree *tree, +int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, @@ -272,7 +272,7 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, * It also avoid redundant argument and return value which aren't meaningful * when collecting multiple hits. */ -void BLI_bvhtree_ray_cast_all_ex(BVHTree *tree, +void BLI_bvhtree_ray_cast_all_ex(const BVHTree *tree, const float co[3], const float dir[3], float radius, @@ -280,7 +280,7 @@ void BLI_bvhtree_ray_cast_all_ex(BVHTree *tree, BVHTree_RayCastCallback callback, void *userdata, int flag); -void BLI_bvhtree_ray_cast_all(BVHTree *tree, +void BLI_bvhtree_ray_cast_all(const BVHTree *tree, const float co[3], const float dir[3], float radius, @@ -296,10 +296,13 @@ float BLI_bvhtree_bb_raycast(const float bv[6], /** * Range query. */ -int BLI_bvhtree_range_query( - BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata); +int BLI_bvhtree_range_query(const BVHTree *tree, + const float co[3], + float radius, + BVHTree_RangeQuery callback, + void *userdata); -int BLI_bvhtree_find_nearest_projected(BVHTree *tree, +int BLI_bvhtree_find_nearest_projected(const BVHTree *tree, float projmat[4][4], float winsize[2], float mval[2], @@ -321,7 +324,7 @@ int BLI_bvhtree_find_nearest_projected(BVHTree *tree, * either from the node with the lower or higher K-DOP axis value. * \param userdata: Argument passed to all callbacks. */ -void BLI_bvhtree_walk_dfs(BVHTree *tree, +void BLI_bvhtree_walk_dfs(const BVHTree *tree, BVHTree_WalkParentCallback walk_parent_cb, BVHTree_WalkLeafCallback walk_leaf_cb, BVHTree_WalkOrderCallback walk_order_cb, @@ -346,7 +349,7 @@ namespace blender { using BVHTree_RayCastCallback_CPP = FunctionRef; -inline void BLI_bvhtree_ray_cast_all_cpp(BVHTree &tree, +inline void BLI_bvhtree_ray_cast_all_cpp(const BVHTree &tree, const float3 co, const float3 dir, float radius, @@ -368,7 +371,7 @@ inline void BLI_bvhtree_ray_cast_all_cpp(BVHTree &tree, using BVHTree_RangeQuery_CPP = FunctionRef; -inline void BLI_bvhtree_range_query_cpp(BVHTree &tree, +inline void BLI_bvhtree_range_query_cpp(const BVHTree &tree, const float3 co, float radius, BVHTree_RangeQuery_CPP fn) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 4e958209f78..d68ea3db013 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -1047,7 +1047,7 @@ float BLI_bvhtree_get_epsilon(const BVHTree *tree) return tree->epsilon; } -void BLI_bvhtree_get_bounding_box(BVHTree *tree, float r_bb_min[3], float r_bb_max[3]) +void BLI_bvhtree_get_bounding_box(const BVHTree *tree, float r_bb_min[3], float r_bb_max[3]) { BVHNode *root = tree->nodes[tree->leaf_num]; if (root != NULL) { @@ -1494,7 +1494,7 @@ static void bvhtree_intersect_plane_dfs_recursive(BVHIntersectPlaneData *__restr } } -int *BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_num) +int *BLI_bvhtree_intersect_plane(const BVHTree *tree, float plane[4], uint *r_intersect_num) { int *intersect = NULL; size_t total = 0; @@ -1641,7 +1641,7 @@ static void heap_find_nearest_begin(BVHNearestData *data, BVHNode *root) } } -int BLI_bvhtree_find_nearest_ex(BVHTree *tree, +int BLI_bvhtree_find_nearest_ex(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, @@ -1690,7 +1690,7 @@ int BLI_bvhtree_find_nearest_ex(BVHTree *tree, return data.nearest.index; } -int BLI_bvhtree_find_nearest(BVHTree *tree, +int BLI_bvhtree_find_nearest(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, @@ -1756,7 +1756,7 @@ static bool dfs_find_duplicate_fast_dfs(BVHNearestData *data, BVHNode *node) return false; } -int BLI_bvhtree_find_nearest_first(BVHTree *tree, +int BLI_bvhtree_find_nearest_first(const BVHTree *tree, const float co[3], const float dist_sq, BVHTree_NearestPointCallback callback, @@ -1971,7 +1971,7 @@ static void bvhtree_ray_cast_data_precalc(BVHRayCastData *data, int flag) #endif } -int BLI_bvhtree_ray_cast_ex(BVHTree *tree, +int BLI_bvhtree_ray_cast_ex(const BVHTree *tree, const float co[3], const float dir[3], float radius, @@ -2016,7 +2016,7 @@ int BLI_bvhtree_ray_cast_ex(BVHTree *tree, return data.hit.index; } -int BLI_bvhtree_ray_cast(BVHTree *tree, +int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, @@ -2055,7 +2055,7 @@ float BLI_bvhtree_bb_raycast(const float bv[6], return dist; } -void BLI_bvhtree_ray_cast_all_ex(BVHTree *tree, +void BLI_bvhtree_ray_cast_all_ex(const BVHTree *tree, const float co[3], const float dir[3], float radius, @@ -2089,7 +2089,7 @@ void BLI_bvhtree_ray_cast_all_ex(BVHTree *tree, } } -void BLI_bvhtree_ray_cast_all(BVHTree *tree, +void BLI_bvhtree_ray_cast_all(const BVHTree *tree, const float co[3], const float dir[3], float radius, @@ -2113,7 +2113,7 @@ void BLI_bvhtree_ray_cast_all(BVHTree *tree, * \{ */ typedef struct RangeQueryData { - BVHTree *tree; + const BVHTree *tree; const float *center; float radius_sq; /* squared radius */ @@ -2154,8 +2154,11 @@ static void dfs_range_query(RangeQueryData *data, BVHNode *node) } } -int BLI_bvhtree_range_query( - BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata) +int BLI_bvhtree_range_query(const BVHTree *tree, + const float co[3], + float radius, + BVHTree_RangeQuery callback, + void *userdata) { BVHNode *root = tree->nodes[tree->leaf_num]; @@ -2307,7 +2310,7 @@ static void bvhtree_nearest_projected_with_clipplane_test_dfs_recursive( } } -int BLI_bvhtree_find_nearest_projected(BVHTree *tree, +int BLI_bvhtree_find_nearest_projected(const BVHTree *tree, float projmat[4][4], float winsize[2], float mval[2], @@ -2421,7 +2424,7 @@ static bool bvhtree_walk_dfs_recursive(BVHTree_WalkData *walk_data, const BVHNod return true; } -void BLI_bvhtree_walk_dfs(BVHTree *tree, +void BLI_bvhtree_walk_dfs(const BVHTree *tree, BVHTree_WalkParentCallback walk_parent_cb, BVHTree_WalkLeafCallback walk_leaf_cb, BVHTree_WalkOrderCallback walk_order_cb, From 4961e5f91d98d68029280ad05118f4ab427461a2 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 13 Jan 2023 11:49:40 -0600 Subject: [PATCH 0628/1522] Geometry Nodes: Rename Interpolate Domain and Field at Index nodes - `Interpolate Domain` -> `Evaluate on Domain` - `Field at Index` -> `Evaluate at Index` These names, discussed in recent geometry nodes submodule meetings, describe actions rather than nouns, which is generally how nodes are supposed to be named. The names are consistent, which is helpful because they're similar conceptually. They also don't require knowledge of the field concept, which we generally try to keep out of the UI in favor of more beginner-friendly concepts. We hope to add the ability to search for nodes with multiple names for 3.5, so the old names can still have search items. --- source/blender/blenkernel/BKE_node.h | 4 ++-- source/blender/makesrna/intern/rna_nodetree.c | 4 ++-- source/blender/nodes/NOD_static_types.h | 8 ++++---- source/blender/nodes/geometry/CMakeLists.txt | 14 +++++++------- .../nodes/geometry/node_geometry_register.cc | 6 +++--- .../nodes/geometry/node_geometry_register.hh | 6 +++--- ...d_at_index.cc => node_geo_evaluate_at_index.cc} | 12 ++++++------ ...te_domain.cc => node_geo_evaluate_on_domain.cc} | 12 ++++++------ 8 files changed, 33 insertions(+), 33 deletions(-) rename source/blender/nodes/geometry/nodes/{node_geo_field_at_index.cc => node_geo_evaluate_at_index.cc} (94%) rename source/blender/nodes/geometry/nodes/{node_geo_interpolate_domain.cc => node_geo_evaluate_on_domain.cc} (94%) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 3cb577fb92e..c99f5cb076e 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -1494,7 +1494,7 @@ struct TexResult; #define GEO_NODE_INPUT_SCENE_TIME 1145 #define GEO_NODE_ACCUMULATE_FIELD 1146 #define GEO_NODE_INPUT_MESH_EDGE_ANGLE 1147 -#define GEO_NODE_FIELD_AT_INDEX 1148 +#define GEO_NODE_EVALUATE_AT_INDEX 1148 #define GEO_NODE_CURVE_PRIMITIVE_ARC 1149 #define GEO_NODE_FLIP_FACES 1150 #define GEO_NODE_SCALE_ELEMENTS 1151 @@ -1509,7 +1509,7 @@ struct TexResult; #define GEO_NODE_INPUT_INSTANCE_SCALE 1160 #define GEO_NODE_VOLUME_CUBE 1161 #define GEO_NODE_POINTS 1162 -#define GEO_NODE_INTERPOLATE_DOMAIN 1163 +#define GEO_NODE_EVALUATE_ON_DOMAIN 1163 #define GEO_NODE_MESH_TO_VOLUME 1164 #define GEO_NODE_UV_UNWRAP 1165 #define GEO_NODE_UV_PACK_ISLANDS 1166 diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index f895a00e23a..b41073393b7 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -10848,7 +10848,7 @@ static void def_geo_realize_instances(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); } -static void def_geo_field_at_index(StructRNA *srna) +static void def_geo_evaluate_at_index(StructRNA *srna) { PropertyRNA *prop; @@ -10867,7 +10867,7 @@ static void def_geo_field_at_index(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_GeometryNode_socket_update"); } -static void def_geo_interpolate_domain(StructRNA *srna) +static void def_geo_evaluate_on_domain(StructRNA *srna) { PropertyRNA *prop; diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index d94b0b56072..479700da7c9 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -314,15 +314,16 @@ DefNode(GeometryNode, GEO_NODE_DUAL_MESH, 0, "DUAL_MESH", DualMesh, "Dual Mesh", DefNode(GeometryNode, GEO_NODE_DUPLICATE_ELEMENTS, def_geo_duplicate_elements, "DUPLICATE_ELEMENTS", DuplicateElements, "Duplicate Elements", "Generate an arbitrary number copies of each selected input element") DefNode(GeometryNode, GEO_NODE_EDGE_PATHS_TO_CURVES, 0, "EDGE_PATHS_TO_CURVES", EdgePathsToCurves, "Edge Paths to Curves", "") DefNode(GeometryNode, GEO_NODE_EDGE_PATHS_TO_SELECTION, 0, "EDGE_PATHS_TO_SELECTION", EdgePathsToSelection, "Edge Paths to Selection", "") +DefNode(GeometryNode, GEO_NODE_EVALUATE_AT_INDEX, def_geo_evaluate_at_index, "FIELD_AT_INDEX", FieldAtIndex, "Evaluate at Index", "Retrieve data of other elements in the context's geometry") +DefNode(GeometryNode, GEO_NODE_EVALUATE_ON_DOMAIN, def_geo_evaluate_on_domain, "FIELD_ON_DOMAIN", FieldOnDomain, "Evaluate on Domain", "Retrieve values from a field on a different domain besides the domain from the context") DefNode(GeometryNode, GEO_NODE_EXTRUDE_MESH, def_geo_extrude_mesh, "EXTRUDE_MESH", ExtrudeMesh, "Extrude Mesh", "Generate new vertices, edges, or faces from selected elements and move them based on an offset while keeping them connected by their boundary") -DefNode(GeometryNode, GEO_NODE_FIELD_AT_INDEX, def_geo_field_at_index, "FIELD_AT_INDEX", FieldAtIndex, "Field at Index", "Retrieve data of other elements in the context's geometry") DefNode(GeometryNode, GEO_NODE_FILL_CURVE, def_geo_curve_fill, "FILL_CURVE", FillCurve, "Fill Curve", "Generate a mesh on the XY plane with faces on the inside of input curves") DefNode(GeometryNode, GEO_NODE_FILLET_CURVE, def_geo_curve_fillet, "FILLET_CURVE", FilletCurve, "Fillet Curve", "Round corners by generating circular arcs on each control point") DefNode(GeometryNode, GEO_NODE_FLIP_FACES, 0, "FLIP_FACES", FlipFaces, "Flip Faces", "Reverse the order of the vertices and edges of selected faces, flipping their normal direction") DefNode(GeometryNode, GEO_NODE_GEOMETRY_TO_INSTANCE, 0, "GEOMETRY_TO_INSTANCE", GeometryToInstance, "Geometry to Instance", "Convert each input geometry into an instance, which can be much faster than the Join Geometry node when the inputs are large") -DefNode(GeometryNode, GEO_NODE_IMAGE, def_geo_image, "IMAGE", InputImage, "Image", "Input image") DefNode(GeometryNode, GEO_NODE_IMAGE_INFO, 0, "IMAGE_INFO", ImageInfo, "Image Info", "Retrieve information about an image") DefNode(GeometryNode, GEO_NODE_IMAGE_TEXTURE, def_geo_image_texture, "IMAGE_TEXTURE", ImageTexture, "Image Texture", "Sample values from an image texture") +DefNode(GeometryNode, GEO_NODE_IMAGE, def_geo_image, "IMAGE", InputImage, "Image", "Input image") DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_HANDLES, 0, "INPUT_CURVE_HANDLES", InputCurveHandlePositions,"Curve Handle Positions", "Retrieve the position of each Bézier control point's handles") DefNode(GeometryNode, GEO_NODE_INPUT_CURVE_TILT, 0, "INPUT_CURVE_TILT", InputCurveTilt, "Curve Tilt", "Retrieve the angle at each control point used to twist the curve's normal around its tangent") DefNode(GeometryNode, GEO_NODE_INPUT_ID, 0, "INPUT_ID", InputID, "ID", "Retrieve a stable random identifier value from the \"id\" attribute on the point domain, or the index if the attribute does not exist") @@ -352,7 +353,6 @@ DefNode(GeometryNode, GEO_NODE_INPUT_SPLINE_RESOLUTION, 0, "INPUT_SPLINE_RESOLUT DefNode(GeometryNode, GEO_NODE_INPUT_TANGENT, 0, "INPUT_TANGENT", InputTangent, "Curve Tangent", "Retrieve the direction of curves at each control point") DefNode(GeometryNode, GEO_NODE_INSTANCE_ON_POINTS, 0, "INSTANCE_ON_POINTS", InstanceOnPoints, "Instance on Points", "Generate a reference to geometry at each of the input points, without duplicating its underlying data") DefNode(GeometryNode, GEO_NODE_INSTANCES_TO_POINTS, 0, "INSTANCES_TO_POINTS",InstancesToPoints, "Instances to Points","Generate points at the origins of instances.\nNote: Nested instances are not affected by this node") -DefNode(GeometryNode, GEO_NODE_INTERPOLATE_DOMAIN, def_geo_interpolate_domain, "FIELD_ON_DOMAIN", FieldOnDomain, "Interpolate Domain", "Retrieve values from a field on a different domain besides the domain from the context") DefNode(GeometryNode, GEO_NODE_IS_VIEWPORT, 0, "IS_VIEWPORT", IsViewport, "Is Viewport", "Retrieve whether the nodes are being evaluated for the viewport rather than the final render") DefNode(GeometryNode, GEO_NODE_JOIN_GEOMETRY, 0, "JOIN_GEOMETRY", JoinGeometry, "Join Geometry", "Merge separately generated geometries into a single one") DefNode(GeometryNode, GEO_NODE_MATERIAL_SELECTION, 0, "MATERIAL_SELECTION", MaterialSelection, "Material Selection", "Provide a selection of faces that use the specified material") @@ -397,9 +397,9 @@ DefNode(GeometryNode, GEO_NODE_SAMPLE_NEAREST, def_geo_sample_nearest, "SAMPLE_N DefNode(GeometryNode, GEO_NODE_SAMPLE_UV_SURFACE, def_geo_sample_uv_surface, "SAMPLE_UV_SURFACE", SampleUVSurface, "Sample UV Surface", "Calculate the interpolated values of a mesh attribute at a UV coordinate") DefNode(GeometryNode, GEO_NODE_SCALE_ELEMENTS, def_geo_scale_elements, "SCALE_ELEMENTS", ScaleElements, "Scale Elements", "Scale groups of connected edges and faces") DefNode(GeometryNode, GEO_NODE_SCALE_INSTANCES, 0, "SCALE_INSTANCES", ScaleInstances, "Scale Instances", "Scale geometry instances in local or global space") +DefNode(GeometryNode, GEO_NODE_SELF_OBJECT, 0, "SELF_OBJECT", SelfObject, "Self Object", "Retrieve the object that contains the geometry nodes modifier currently being executed") DefNode(GeometryNode, GEO_NODE_SEPARATE_COMPONENTS, 0, "SEPARATE_COMPONENTS",SeparateComponents, "Separate Components","Split a geometry into a separate output for each type of data in the geometry") DefNode(GeometryNode, GEO_NODE_SEPARATE_GEOMETRY, def_geo_separate_geometry,"SEPARATE_GEOMETRY", SeparateGeometry, "Separate Geometry", "Split a geometry into two geometry outputs based on a selection") -DefNode(GeometryNode, GEO_NODE_SELF_OBJECT, 0, "SELF_OBJECT", SelfObject, "Self Object", "Retrieve the object that contains the geometry nodes modifier currently being executed") DefNode(GeometryNode, GEO_NODE_SET_CURVE_HANDLES, def_geo_curve_set_handle_positions, "SET_CURVE_HANDLES", SetCurveHandlePositions, "Set Handle Positions", "Set the positions for the handles of Bézier curves") DefNode(GeometryNode, GEO_NODE_SET_CURVE_NORMAL, def_geo_set_curve_normal, "SET_CURVE_NORMAL", SetCurveNormal, "Set Curve Normal", "Set the evaluation mode for curve normals") DefNode(GeometryNode, GEO_NODE_SET_CURVE_RADIUS, 0, "SET_CURVE_RADIUS", SetCurveRadius, "Set Curve Radius", "Set the radius of the curve at each control point") diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt index c6151022ac5..396fd794865 100644 --- a/source/blender/nodes/geometry/CMakeLists.txt +++ b/source/blender/nodes/geometry/CMakeLists.txt @@ -69,21 +69,22 @@ set(SRC nodes/node_geo_edge_paths_to_curves.cc nodes/node_geo_edge_paths_to_selection.cc nodes/node_geo_edge_split.cc + nodes/node_geo_evaluate_at_index.cc + nodes/node_geo_evaluate_on_domain.cc nodes/node_geo_extrude_mesh.cc - nodes/node_geo_field_at_index.cc nodes/node_geo_flip_faces.cc nodes/node_geo_geometry_to_instance.cc - nodes/node_geo_image.cc nodes/node_geo_image_info.cc nodes/node_geo_image_texture.cc + nodes/node_geo_image.cc nodes/node_geo_input_curve_handles.cc nodes/node_geo_input_curve_tilt.cc nodes/node_geo_input_id.cc nodes/node_geo_input_index.cc nodes/node_geo_input_instance_rotation.cc nodes/node_geo_input_instance_scale.cc - nodes/node_geo_input_material.cc nodes/node_geo_input_material_index.cc + nodes/node_geo_input_material.cc nodes/node_geo_input_mesh_edge_angle.cc nodes/node_geo_input_mesh_edge_neighbors.cc nodes/node_geo_input_mesh_edge_vertices.cc @@ -105,7 +106,6 @@ set(SRC nodes/node_geo_input_tangent.cc nodes/node_geo_instance_on_points.cc nodes/node_geo_instances_to_points.cc - nodes/node_geo_interpolate_domain.cc nodes/node_geo_is_viewport.cc nodes/node_geo_join_geometry.cc nodes/node_geo_material_replace.cc @@ -133,17 +133,17 @@ set(SRC nodes/node_geo_mesh_topology_vertex_of_corner.cc nodes/node_geo_object_info.cc nodes/node_geo_offset_point_in_curve.cc - nodes/node_geo_points.cc nodes/node_geo_points_to_vertices.cc nodes/node_geo_points_to_volume.cc + nodes/node_geo_points.cc nodes/node_geo_proximity.cc nodes/node_geo_raycast.cc nodes/node_geo_realize_instances.cc nodes/node_geo_remove_attribute.cc nodes/node_geo_rotate_instances.cc nodes/node_geo_sample_index.cc - nodes/node_geo_sample_nearest.cc nodes/node_geo_sample_nearest_surface.cc + nodes/node_geo_sample_nearest.cc nodes/node_geo_sample_uv_surface.cc nodes/node_geo_scale_elements.cc nodes/node_geo_scale_instances.cc @@ -155,8 +155,8 @@ set(SRC nodes/node_geo_set_curve_radius.cc nodes/node_geo_set_curve_tilt.cc nodes/node_geo_set_id.cc - nodes/node_geo_set_material.cc nodes/node_geo_set_material_index.cc + nodes/node_geo_set_material.cc nodes/node_geo_set_point_radius.cc nodes/node_geo_set_position.cc nodes/node_geo_set_shade_smooth.cc diff --git a/source/blender/nodes/geometry/node_geometry_register.cc b/source/blender/nodes/geometry/node_geometry_register.cc index 6518e8a62f7..6305271ee8f 100644 --- a/source/blender/nodes/geometry/node_geometry_register.cc +++ b/source/blender/nodes/geometry/node_geometry_register.cc @@ -53,13 +53,14 @@ void register_geometry_nodes() register_node_type_geo_edge_paths_to_curves(); register_node_type_geo_edge_paths_to_selection(); register_node_type_geo_edge_split(); + register_node_type_geo_evaluate_at_index(); + register_node_type_geo_evaluate_on_domain(); register_node_type_geo_extrude_mesh(); - register_node_type_geo_field_at_index(); register_node_type_geo_flip_faces(); register_node_type_geo_geometry_to_instance(); - register_node_type_geo_image(); register_node_type_geo_image_info(); register_node_type_geo_image_texture(); + register_node_type_geo_image(); register_node_type_geo_input_curve_handles(); register_node_type_geo_input_curve_tilt(); register_node_type_geo_input_id(); @@ -89,7 +90,6 @@ void register_geometry_nodes() register_node_type_geo_input_tangent(); register_node_type_geo_instance_on_points(); register_node_type_geo_instances_to_points(); - register_node_type_geo_interpolate_domain(); register_node_type_geo_is_viewport(); register_node_type_geo_join_geometry(); register_node_type_geo_material_replace(); diff --git a/source/blender/nodes/geometry/node_geometry_register.hh b/source/blender/nodes/geometry/node_geometry_register.hh index 66ab1d32af0..213bec79045 100644 --- a/source/blender/nodes/geometry/node_geometry_register.hh +++ b/source/blender/nodes/geometry/node_geometry_register.hh @@ -50,13 +50,14 @@ void register_node_type_geo_duplicate_elements(); void register_node_type_geo_edge_paths_to_curves(); void register_node_type_geo_edge_paths_to_selection(); void register_node_type_geo_edge_split(); +void register_node_type_geo_evaluate_at_index(); +void register_node_type_geo_evaluate_on_domain(); void register_node_type_geo_extrude_mesh(); -void register_node_type_geo_field_at_index(); void register_node_type_geo_flip_faces(); void register_node_type_geo_geometry_to_instance(); -void register_node_type_geo_image(); void register_node_type_geo_image_info(); void register_node_type_geo_image_texture(); +void register_node_type_geo_image(); void register_node_type_geo_input_curve_handles(); void register_node_type_geo_input_curve_tilt(); void register_node_type_geo_input_id(); @@ -86,7 +87,6 @@ void register_node_type_geo_input_spline_resolution(); void register_node_type_geo_input_tangent(); void register_node_type_geo_instance_on_points(); void register_node_type_geo_instances_to_points(); -void register_node_type_geo_interpolate_domain(); void register_node_type_geo_is_viewport(); void register_node_type_geo_join_geometry(); void register_node_type_geo_material_replace(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc b/source/blender/nodes/geometry/nodes/node_geo_evaluate_at_index.cc similarity index 94% rename from source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc rename to source/blender/nodes/geometry/nodes/node_geo_evaluate_at_index.cc index 99554c4d10c..75b9d0e49cd 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_field_at_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_evaluate_at_index.cc @@ -16,7 +16,7 @@ namespace blender::nodes { FieldAtIndexInput::FieldAtIndexInput(Field index_field, GField value_field, eAttrDomain value_field_domain) - : bke::GeometryFieldInput(value_field.cpp_type(), "Field at Index"), + : bke::GeometryFieldInput(value_field.cpp_type(), "Evaluate at Index"), index_field_(std::move(index_field)), value_field_(std::move(value_field)), value_field_domain_(value_field_domain) @@ -68,7 +68,7 @@ GVArray FieldAtIndexInput::get_varray_for_context(const bke::GeometryFieldContex } // namespace blender::nodes -namespace blender::nodes::node_geo_field_at_index_cc { +namespace blender::nodes::node_geo_evaluate_at_index_cc { static void node_declare(NodeDeclarationBuilder &b) { @@ -182,15 +182,15 @@ static void node_geo_exec(GeoNodeExecParams params) }); } -} // namespace blender::nodes::node_geo_field_at_index_cc +} // namespace blender::nodes::node_geo_evaluate_at_index_cc -void register_node_type_geo_field_at_index() +void register_node_type_geo_evaluate_at_index() { - namespace file_ns = blender::nodes::node_geo_field_at_index_cc; + namespace file_ns = blender::nodes::node_geo_evaluate_at_index_cc; static bNodeType ntype; - geo_node_type_base(&ntype, GEO_NODE_FIELD_AT_INDEX, "Field at Index", NODE_CLASS_CONVERTER); + geo_node_type_base(&ntype, GEO_NODE_EVALUATE_AT_INDEX, "Evaluate at Index", NODE_CLASS_CONVERTER); ntype.geometry_node_execute = file_ns::node_geo_exec; ntype.declare = file_ns::node_declare; ntype.draw_buttons = file_ns::node_layout; diff --git a/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc b/source/blender/nodes/geometry/nodes/node_geo_evaluate_on_domain.cc similarity index 94% rename from source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc rename to source/blender/nodes/geometry/nodes/node_geo_evaluate_on_domain.cc index 671bf71edf1..83e7feeb668 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_interpolate_domain.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_evaluate_on_domain.cc @@ -11,7 +11,7 @@ #include "NOD_socket_search_link.hh" -namespace blender::nodes::node_geo_interpolate_domain_cc { +namespace blender::nodes::node_geo_evaluate_on_domain_cc { static void node_declare(NodeDeclarationBuilder &b) { @@ -90,7 +90,7 @@ class InterpolateDomain final : public bke::GeometryFieldInput { public: InterpolateDomain(GField field, eAttrDomain domain) - : bke::GeometryFieldInput(field.cpp_type(), "Interpolate Domain"), + : bke::GeometryFieldInput(field.cpp_type(), "Evaluate on Domain"), src_field_(std::move(field)), src_domain_(domain) { @@ -158,16 +158,16 @@ static void node_geo_exec(GeoNodeExecParams params) }); } -} // namespace blender::nodes::node_geo_interpolate_domain_cc +} // namespace blender::nodes::node_geo_evaluate_on_domain_cc -void register_node_type_geo_interpolate_domain() +void register_node_type_geo_evaluate_on_domain() { - namespace file_ns = blender::nodes::node_geo_interpolate_domain_cc; + namespace file_ns = blender::nodes::node_geo_evaluate_on_domain_cc; static bNodeType ntype; geo_node_type_base( - &ntype, GEO_NODE_INTERPOLATE_DOMAIN, "Interpolate Domain", NODE_CLASS_CONVERTER); + &ntype, GEO_NODE_EVALUATE_ON_DOMAIN, "Evaluate on Domain", NODE_CLASS_CONVERTER); ntype.geometry_node_execute = file_ns::node_geo_exec; ntype.declare = file_ns::node_declare; ntype.draw_buttons = file_ns::node_layout; From ef68a37e5d55e17adf4cc8e3349eaf0243dbf15e Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 13 Jan 2023 12:31:27 -0600 Subject: [PATCH 0629/1522] Custom Properties: Add boolean type A proper boolean custom property type is commonly requested. This commit simply adds a new `IDP_BOOLEAN` type that can be used for boolean and boolean array custom properties. This can also be used for exposing boolean node sockets in the geometry nodes modifier. I've just extended the places existing IDProperty types are used, and tested with the custom property edit operator and the python console. Adding another IDProperty type is a straightforward extension of the existing design. Differential Revision: https://developer.blender.org/D12815 --- release/scripts/modules/rna_prop_ui.py | 21 ++-- release/scripts/startup/bl_operators/wm.py | 51 +++++++- source/blender/blenkernel/BKE_idprop.h | 3 + source/blender/blenkernel/intern/idprop.c | 69 ++++++++++- .../blender/blenkernel/intern/idprop_utils.c | 12 ++ source/blender/blenloader/BLO_read_write.h | 2 + source/blender/blenloader/intern/readfile.cc | 5 + .../blenloader/intern/versioning_300.cc | 1 + source/blender/blenloader/intern/writefile.cc | 5 + .../io/alembic/exporter/abc_custom_props.cc | 15 ++- source/blender/io/collada/collada_utils.cpp | 3 + source/blender/makesdna/DNA_ID.h | 18 ++- source/blender/makesrna/intern/rna_ID.c | 9 ++ source/blender/makesrna/intern/rna_access.c | 79 +++++++++++-- source/blender/python/generic/idprop_py_api.c | 92 +++++++++++++-- .../blender/python/generic/idprop_py_ui_api.c | 111 ++++++++++++++++++ 16 files changed, 457 insertions(+), 39 deletions(-) diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py index 5f4a6b8cf38..f6c01bde9cd 100644 --- a/release/scripts/modules/rna_prop_ui.py +++ b/release/scripts/modules/rna_prop_ui.py @@ -81,25 +81,26 @@ def rna_idprop_ui_create( ): """Create and initialize a custom property with limits, defaults and other settings.""" + # Assign the value + item[prop] = default + + rna_idprop_ui_prop_update(item, prop) + ui_data = item.id_properties_ui(prop) proptype, _ = rna_idprop_value_item_type(default) - # Sanitize limits if proptype is bool: - min = soft_min = False - max = soft_max = True + ui_data = item.id_properties_ui(prop) + ui_data.update( + description=description, + default=default, + ) + return if soft_min is None: soft_min = min if soft_max is None: soft_max = max - # Assign the value - item[prop] = default - - rna_idprop_ui_prop_update(item, prop) - - # Update the UI settings. - ui_data = item.id_properties_ui(prop) ui_data.update( subtype=subtype, min=min, diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 39789cba0c4..fe43051281d 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -14,6 +14,7 @@ from bpy.props import ( FloatProperty, IntProperty, StringProperty, + BoolVectorProperty, IntVectorProperty, FloatVectorProperty, ) @@ -1325,6 +1326,8 @@ rna_custom_property_type_items = ( ('FLOAT_ARRAY', "Float Array", "An array of floating-point values"), ('INT', "Integer", "A single integer"), ('INT_ARRAY', "Integer Array", "An array of integers"), + ('BOOL', "Boolean", "A true or false value"), + ('BOOL_ARRAY', "Boolean Array", "An array of true or false values"), ('STRING', "String", "A string value"), ('PYTHON', "Python", "Edit a python value directly, for unsupported property types"), ) @@ -1410,6 +1413,14 @@ class WM_OT_properties_edit(Operator): default=1, ) + # Boolean properties. + + # This property stores values for both array and non-array properties. + default_bool: BoolVectorProperty( + name="Default Value", + size=32, + ) + # Float properties. # This property stores values for both array and non-array properties. @@ -1520,6 +1531,10 @@ class WM_OT_properties_edit(Operator): if is_array: return 'FLOAT_ARRAY' return 'FLOAT' + elif prop_type == bool: + if is_array: + return 'BOOL_ARRAY' + return 'BOOL' elif prop_type == str: if is_array: return 'PYTHON' @@ -1571,8 +1586,10 @@ class WM_OT_properties_edit(Operator): self.default_int = self._convert_new_value_array(rna_data["default"], int, 32) elif self.property_type == 'STRING': self.default_string = rna_data["default"] + elif self.property_type in {'BOOL', 'BOOL_ARRAY'}: + self.default_int = self._convert_new_value_array(rna_data["default"], bool, 32) - if self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY'}: + if self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}: self.array_length = len(item[name]) # The dictionary does not contain the description if it was empty. @@ -1591,16 +1608,26 @@ class WM_OT_properties_edit(Operator): if prop_type_new == 'FLOAT': return self._convert_new_value_single(item[name_old], float) + if prop_type_new == 'BOOL': + return self._convert_new_value_single(item[name_old], bool) + if prop_type_new == 'INT_ARRAY': prop_type_old = self.get_property_type(item, name_old) - if prop_type_old in {'INT', 'FLOAT', 'INT_ARRAY', 'FLOAT_ARRAY'}: + if prop_type_old in {'INT', 'FLOAT', 'INT_ARRAY', 'FLOAT_ARRAY', 'BOOL_ARRAY'}: return self._convert_new_value_array(item[name_old], int, self.array_length) if prop_type_new == 'FLOAT_ARRAY': prop_type_old = self.get_property_type(item, name_old) - if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY'}: + if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}: return self._convert_new_value_array(item[name_old], float, self.array_length) + if prop_type_new == 'BOOL_ARRAY': + prop_type_old = self.get_property_type(item, name_old) + if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY'}: + return self._convert_new_value_array(item[name_old], bool, self.array_length) + else: + return [False] * self.array_length + if prop_type_new == 'STRING': return self.convert_custom_property_to_string(item, name_old) @@ -1622,6 +1649,9 @@ class WM_OT_properties_edit(Operator): self.soft_min_float = float(self.soft_min_int) self.soft_max_float = float(self.soft_max_int) self.default_float = self._convert_new_value_array(self.default_int, float, 32) + elif prop_type_new in {'BOOL', 'BOOL_ARRAY'} and prop_type_old in {'INT', 'INT_ARRAY'}: + self.default_bool = self._convert_new_value_array(self.default_int, bool, 32) + # Don't convert between string and float/int defaults here, it's not expected like the other conversions. # Fill the property's UI data with the values chosen in the operator. @@ -1637,6 +1667,12 @@ class WM_OT_properties_edit(Operator): default=self.default_int[0] if prop_type_new == 'INT' else self.default_int[:self.array_length], description=self.description, ) + if prop_type_new in {'BOOL', 'BOOL_ARRAY'}: + ui_data = item.id_properties_ui(name) + ui_data.update( + default=self.default_bool[0] if prop_type_new == 'BOOL' else self.default_bool[:self.array_length], + description=self.description, + ) elif prop_type_new in {'FLOAT', 'FLOAT_ARRAY'}: ui_data = item.id_properties_ui(name) ui_data.update( @@ -1879,6 +1915,15 @@ class WM_OT_properties_edit(Operator): col.prop(self, "soft_max_int", text="Max") layout.prop(self, "step_int") + elif self.property_type in {'BOOL', 'BOOL_ARRAY'}: + if self.property_type == 'BOOL_ARRAY': + layout.prop(self, "array_length") + col = layout.column(align=True) + col.prop(self, "default_bool", index=0, text="Default") + for i in range(1, self.array_length): + col.prop(self, "default_bool", index=i, text=" ") + else: + layout.prop(self, "default_bool", index=0) elif self.property_type == 'STRING': layout.prop(self, "default_string") diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h index 9ac4b4e4619..84412fd139f 100644 --- a/source/blender/blenkernel/BKE_idprop.h +++ b/source/blender/blenkernel/BKE_idprop.h @@ -243,6 +243,7 @@ void IDP_ClearProperty(struct IDProperty *prop); void IDP_Reset(struct IDProperty *prop, const struct IDProperty *reference); #define IDP_Int(prop) ((prop)->data.val) +#define IDP_Bool(prop) ((prop)->data.val) #define IDP_Array(prop) ((prop)->data.pointer) /* C11 const correctness for casts */ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) @@ -334,6 +335,8 @@ typedef enum eIDPropertyUIDataType { IDP_UI_DATA_TYPE_STRING = 2, /** IDP_ID. */ IDP_UI_DATA_TYPE_ID = 3, + /** IDP_BOOLEAN or IDP_ARRAY with subtype IDP_BOOLEAN. */ + IDP_UI_DATA_TYPE_BOOLEAN = 4, } eIDPropertyUIDataType; bool IDP_ui_data_supported(const struct IDProperty *prop); diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 00e7425c8af..b8f0db0699d 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -50,6 +50,8 @@ static size_t idp_size_table[] = { sizeof(ListBase), /* Group type. */ sizeof(void *), sizeof(double), + 0, + sizeof(int8_t), /* Boolean type. */ }; /* -------------------------------------------------------------------- */ @@ -272,6 +274,12 @@ IDPropertyUIData *IDP_ui_data_copy(const IDProperty *prop) dst->default_array = MEM_dupallocN(src->default_array); break; } + case IDP_UI_DATA_TYPE_BOOLEAN: { + const IDPropertyUIDataBool *src = (const IDPropertyUIDataBool *)prop->ui_data; + IDPropertyUIDataBool *dst = (IDPropertyUIDataBool *)dst_ui_data; + dst->default_array = MEM_dupallocN(src->default_array); + break; + } case IDP_UI_DATA_TYPE_FLOAT: { const IDPropertyUIDataFloat *src = (const IDPropertyUIDataFloat *)prop->ui_data; IDPropertyUIDataFloat *dst = (IDPropertyUIDataFloat *)dst_ui_data; @@ -497,6 +505,7 @@ void IDP_SyncGroupValues(IDProperty *dest, const IDProperty *src) case IDP_INT: case IDP_FLOAT: case IDP_DOUBLE: + case IDP_BOOLEAN: other->data = prop->data; break; case IDP_GROUP: @@ -708,6 +717,8 @@ int IDP_coerce_to_int_or_zero(const IDProperty *prop) return (int)IDP_Double(prop); case IDP_FLOAT: return (int)IDP_Float(prop); + case IDP_BOOLEAN: + return (int)IDP_Bool(prop); default: return 0; } @@ -722,6 +733,8 @@ double IDP_coerce_to_double_or_zero(const IDProperty *prop) return (double)IDP_Float(prop); case IDP_INT: return (double)IDP_Int(prop); + case IDP_BOOLEAN: + return (double)IDP_Bool(prop); default: return 0.0; } @@ -736,6 +749,8 @@ float IDP_coerce_to_float_or_zero(const IDProperty *prop) return (float)IDP_Double(prop); case IDP_INT: return (float)IDP_Int(prop); + case IDP_BOOLEAN: + return (float)IDP_Bool(prop); default: return 0.0f; } @@ -826,6 +841,8 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is return (IDP_Float(prop1) == IDP_Float(prop2)); case IDP_DOUBLE: return (IDP_Double(prop1) == IDP_Double(prop2)); + case IDP_BOOLEAN: + return (IDP_Bool(prop1) == IDP_Bool(prop2)); case IDP_STRING: { return ((prop1->len == prop2->len) && STREQLEN(IDP_String(prop1), IDP_String(prop2), (size_t)prop1->len)); @@ -899,9 +916,12 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char * prop = MEM_callocN(sizeof(IDProperty), "IDProperty double"); *(double *)&prop->data.val = val->d; break; + case IDP_BOOLEAN: + prop = MEM_callocN(sizeof(IDProperty), "IDProperty boolean"); + prop->data.val = (bool)val->i; + break; case IDP_ARRAY: { - /* for now, we only support float and int and double arrays */ - if (ELEM(val->array.type, IDP_FLOAT, IDP_INT, IDP_DOUBLE, IDP_GROUP)) { + if (ELEM(val->array.type, IDP_FLOAT, IDP_INT, IDP_DOUBLE, IDP_GROUP, IDP_BOOLEAN)) { prop = MEM_callocN(sizeof(IDProperty), "IDProperty array"); prop->subtype = val->array.type; if (val->array.len) { @@ -1004,6 +1024,14 @@ void IDP_ui_data_free_unique_contents(IDPropertyUIData *ui_data, } break; } + case IDP_UI_DATA_TYPE_BOOLEAN: { + const IDPropertyUIDataBool *other_bool = (const IDPropertyUIDataBool *)other; + IDPropertyUIDataBool *ui_data_bool = (IDPropertyUIDataBool *)ui_data; + if (ui_data_bool->default_array != other_bool->default_array) { + MEM_SAFE_FREE(ui_data_bool->default_array); + } + break; + } case IDP_UI_DATA_TYPE_FLOAT: { const IDPropertyUIDataFloat *other_float = (const IDPropertyUIDataFloat *)other; IDPropertyUIDataFloat *ui_data_float = (IDPropertyUIDataFloat *)ui_data; @@ -1034,6 +1062,11 @@ void IDP_ui_data_free(IDProperty *prop) MEM_SAFE_FREE(ui_data_int->default_array); break; } + case IDP_UI_DATA_TYPE_BOOLEAN: { + IDPropertyUIDataBool *ui_data_bool = (IDPropertyUIDataBool *)prop->ui_data; + MEM_SAFE_FREE(ui_data_bool->default_array); + break; + } case IDP_UI_DATA_TYPE_FLOAT: { IDPropertyUIDataFloat *ui_data_float = (IDPropertyUIDataFloat *)prop->ui_data; MEM_SAFE_FREE(ui_data_float->default_array); @@ -1173,6 +1206,16 @@ static void write_ui_data(const IDProperty *prop, BlendWriter *writer) BLO_write_struct(writer, IDPropertyUIDataInt, ui_data); break; } + case IDP_UI_DATA_TYPE_BOOLEAN: { + IDPropertyUIDataBool *ui_data_bool = (IDPropertyUIDataBool *)ui_data; + if (prop->type == IDP_ARRAY) { + BLO_write_int8_array(writer, + (uint)ui_data_bool->default_array_len, + (const int8_t *)ui_data_bool->default_array); + } + BLO_write_struct(writer, IDPropertyUIDataBool, ui_data); + break; + } case IDP_UI_DATA_TYPE_FLOAT: { IDPropertyUIDataFloat *ui_data_float = (IDPropertyUIDataFloat *)ui_data; if (prop->type == IDP_ARRAY) { @@ -1285,6 +1328,14 @@ static void read_ui_data(IDProperty *prop, BlendDataReader *reader) } break; } + case IDP_UI_DATA_TYPE_BOOLEAN: { + IDPropertyUIDataBool *ui_data_bool = (IDPropertyUIDataBool *)prop->ui_data; + if (prop->type == IDP_ARRAY) { + BLO_read_int8_array( + reader, ui_data_bool->default_array_len, (int8_t **)&ui_data_bool->default_array); + } + break; + } case IDP_UI_DATA_TYPE_FLOAT: { IDPropertyUIDataFloat *ui_data_float = (IDPropertyUIDataFloat *)prop->ui_data; if (prop->type == IDP_ARRAY) { @@ -1336,10 +1387,13 @@ static void IDP_DirectLinkArray(IDProperty *prop, BlendDataReader *reader) else if (prop->subtype == IDP_DOUBLE) { BLO_read_double_array(reader, prop->len, (double **)&prop->data.pointer); } - else { + else if (ELEM(prop->subtype, IDP_INT, IDP_FLOAT)) { /* also used for floats */ BLO_read_int32_array(reader, prop->len, (int **)&prop->data.pointer); } + else if (prop->subtype == IDP_BOOLEAN) { + BLO_read_int8_array(reader, prop->len, (int8_t **)&prop->data.pointer); + } } static void IDP_DirectLinkString(IDProperty *prop, BlendDataReader *reader) @@ -1392,6 +1446,7 @@ static void IDP_DirectLinkProperty(IDProperty *prop, BlendDataReader *reader) break; case IDP_INT: case IDP_FLOAT: + case IDP_BOOLEAN: case IDP_ID: break; /* Nothing special to do here. */ default: @@ -1502,6 +1557,9 @@ eIDPropertyUIDataType IDP_ui_data_type(const IDProperty *prop) (prop->type == IDP_ARRAY && ELEM(prop->subtype, IDP_FLOAT, IDP_DOUBLE))) { return IDP_UI_DATA_TYPE_FLOAT; } + if (prop->type == IDP_BOOLEAN || (prop->type == IDP_ARRAY && prop->subtype == IDP_BOOLEAN)) { + return IDP_UI_DATA_TYPE_BOOLEAN; + } return IDP_UI_DATA_TYPE_UNSUPPORTED; } @@ -1536,6 +1594,11 @@ IDPropertyUIData *IDP_ui_data_ensure(IDProperty *prop) prop->ui_data = (IDPropertyUIData *)ui_data; break; } + case IDP_UI_DATA_TYPE_BOOLEAN: { + IDPropertyUIDataBool *ui_data = MEM_callocN(sizeof(IDPropertyUIDataBool), __func__); + prop->ui_data = (IDPropertyUIData *)ui_data; + break; + } case IDP_UI_DATA_TYPE_FLOAT: { IDPropertyUIDataFloat *ui_data = MEM_callocN(sizeof(IDPropertyUIDataFloat), __func__); ui_data->min = -FLT_MAX; diff --git a/source/blender/blenkernel/intern/idprop_utils.c b/source/blender/blenkernel/intern/idprop_utils.c index 5b7484ab422..0ade0aa654e 100644 --- a/source/blender/blenkernel/intern/idprop_utils.c +++ b/source/blender/blenkernel/intern/idprop_utils.c @@ -111,6 +111,10 @@ static void idp_repr_fn_recursive(struct ReprState *state, const IDProperty *pro STR_APPEND_FMT("%g", IDP_Double(prop)); break; } + case IDP_BOOLEAN: { + STR_APPEND_FMT("%s", IDP_Bool(prop) ? "True" : "False"); + break; + } case IDP_ARRAY: { STR_APPEND_STR("["); switch (prop->subtype) { @@ -138,6 +142,14 @@ static void idp_repr_fn_recursive(struct ReprState *state, const IDProperty *pro STR_APPEND_FMT("%g", *v); } break; + case IDP_BOOLEAN: + for (const double *v = prop->data.pointer, *v_end = v + prop->len; v != v_end; v++) { + if (v != prop->data.pointer) { + STR_APPEND_STR(", "); + } + STR_APPEND_FMT("%s", IDP_Bool(prop) ? "True" : "False"); + } + break; } STR_APPEND_STR("]"); break; diff --git a/source/blender/blenloader/BLO_read_write.h b/source/blender/blenloader/BLO_read_write.h index 6f39670a226..56b0cc81598 100644 --- a/source/blender/blenloader/BLO_read_write.h +++ b/source/blender/blenloader/BLO_read_write.h @@ -162,6 +162,7 @@ void blo_write_id_struct(BlendWriter *writer, * Write raw data. */ void BLO_write_raw(BlendWriter *writer, size_t size_in_bytes, const void *data_ptr); +void BLO_write_int8_array(BlendWriter *writer, uint num, const int8_t *data_ptr); void BLO_write_int32_array(BlendWriter *writer, uint num, const int32_t *data_ptr); void BLO_write_uint32_array(BlendWriter *writer, uint num, const uint32_t *data_ptr); void BLO_write_float_array(BlendWriter *writer, uint num, const float *data_ptr); @@ -228,6 +229,7 @@ void BLO_read_list(BlendDataReader *reader, struct ListBase *list); /* Update data pointers and correct byte-order if necessary. */ +void BLO_read_int8_array(BlendDataReader *reader, int array_size, int8_t **ptr_p); void BLO_read_int32_array(BlendDataReader *reader, int array_size, int32_t **ptr_p); void BLO_read_uint32_array(BlendDataReader *reader, int array_size, uint32_t **ptr_p); void BLO_read_float_array(BlendDataReader *reader, int array_size, float **ptr_p); diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 91a72fb50c4..f4a5b6dd2fc 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -4976,6 +4976,11 @@ void BLO_read_int32_array(BlendDataReader *reader, int array_size, int32_t **ptr } } +void BLO_read_int8_array(BlendDataReader *reader, int /*array_size*/, int8_t **ptr_p) +{ + BLO_read_data_address(reader, ptr_p); +} + void BLO_read_uint32_array(BlendDataReader *reader, int array_size, uint32_t **ptr_p) { BLO_read_data_address(reader, ptr_p); diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index 0a68a526d0f..ff7c7f4480a 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -248,6 +248,7 @@ static void version_idproperty_ui_data(IDProperty *idprop_group) case IDP_UI_DATA_TYPE_FLOAT: version_idproperty_move_data_float((IDPropertyUIDataFloat *)ui_data, prop_ui_data); break; + case IDP_UI_DATA_TYPE_BOOLEAN: case IDP_UI_DATA_TYPE_UNSUPPORTED: BLI_assert_unreachable(); break; diff --git a/source/blender/blenloader/intern/writefile.cc b/source/blender/blenloader/intern/writefile.cc index 0e3c1645fb4..57ac9d650d9 100644 --- a/source/blender/blenloader/intern/writefile.cc +++ b/source/blender/blenloader/intern/writefile.cc @@ -1639,6 +1639,11 @@ int BLO_get_struct_id_by_name(BlendWriter *writer, const char *struct_name) return struct_id; } +void BLO_write_int8_array(BlendWriter *writer, uint num, const int8_t *data_ptr) +{ + BLO_write_raw(writer, sizeof(int8_t) * size_t(num), data_ptr); +} + void BLO_write_int32_array(BlendWriter *writer, uint num, const int32_t *data_ptr) { BLO_write_raw(writer, sizeof(int32_t) * size_t(num), data_ptr); diff --git a/source/blender/io/alembic/exporter/abc_custom_props.cc b/source/blender/io/alembic/exporter/abc_custom_props.cc index c5cc4631e18..ad7df45dca0 100644 --- a/source/blender/io/alembic/exporter/abc_custom_props.cc +++ b/source/blender/io/alembic/exporter/abc_custom_props.cc @@ -70,6 +70,9 @@ void CustomPropertiesExporter::write(const IDProperty *id_property) set_scalar_property(id_property->name, IDP_Double(id_property)); break; + case IDP_BOOLEAN: + set_scalar_property(id_property->name, IDP_Bool(id_property)); + break; case IDP_ARRAY: write_array(id_property); break; @@ -100,6 +103,11 @@ void CustomPropertiesExporter::write_array(const IDProperty *id_property) set_array_property(id_property->name, array, id_property->len); break; } + case IDP_BOOLEAN: { + const int8_t *array = static_cast(IDP_Array(id_property)); + set_array_property(id_property->name, array, id_property->len); + break; + } } } @@ -165,7 +173,7 @@ void CustomPropertiesExporter::write_idparray_of_numbers(const IDProperty *idp_a BLI_assert(idp_rows[0].type == IDP_ARRAY); const int subtype = idp_rows[0].subtype; - if (!ELEM(subtype, IDP_INT, IDP_FLOAT, IDP_DOUBLE)) { + if (!ELEM(subtype, IDP_INT, IDP_FLOAT, IDP_DOUBLE, IDP_BOOLEAN)) { /* Non-numerical types are not supported. */ return; } @@ -181,6 +189,9 @@ void CustomPropertiesExporter::write_idparray_of_numbers(const IDProperty *idp_a case IDP_DOUBLE: write_idparray_flattened_typed(idp_array); break; + case IDP_BOOLEAN: + write_idparray_flattened_typed(idp_array); + break; } } @@ -192,7 +203,7 @@ void CustomPropertiesExporter::write_idparray_flattened_typed(const IDProperty * const IDProperty *idp_rows = (IDProperty *)IDP_Array(idp_array); BLI_assert(idp_rows[0].type == IDP_ARRAY); - BLI_assert(ELEM(idp_rows[0].subtype, IDP_INT, IDP_FLOAT, IDP_DOUBLE)); + BLI_assert(ELEM(idp_rows[0].subtype, IDP_INT, IDP_FLOAT, IDP_DOUBLE, IDP_BOOLEAN)); const uint64_t num_rows = idp_array->len; std::vector matrix_values; diff --git a/source/blender/io/collada/collada_utils.cpp b/source/blender/io/collada/collada_utils.cpp index 8a093e0c5e1..ae6bb9a541d 100644 --- a/source/blender/io/collada/collada_utils.cpp +++ b/source/blender/io/collada/collada_utils.cpp @@ -718,6 +718,9 @@ float bc_get_property(Bone *bone, std::string key, float def) case IDP_DOUBLE: result = float(IDP_Double(property)); break; + case IDP_BOOLEAN: + result = (float)(IDP_Bool(property)); + break; default: result = def; } diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 8b3a8793883..4e56fbe3dd0 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -68,6 +68,16 @@ typedef struct IDPropertyUIDataInt { int default_value; } IDPropertyUIDataInt; +/* IDP_UI_DATA_TYPE_BOOLEAN Use "int8_t" because DNA does not support "bool". */ +typedef struct IDPropertyUIDataBool { + IDPropertyUIData base; + int8_t *default_array; /* Only for array properties. */ + int default_array_len; + char _pad[3]; + + int8_t default_value; +} IDPropertyUIDataBool; + /* IDP_UI_DATA_TYPE_FLOAT */ typedef struct IDPropertyUIDataFloat { IDPropertyUIData base; @@ -142,8 +152,13 @@ typedef enum eIDPropertyType { IDP_ID = 7, IDP_DOUBLE = 8, IDP_IDPARRAY = 9, + /** + * True or false value, backed by an `int8_t` underlying type for arrays. Values are expected to + * be 0 or 1. + */ + IDP_BOOLEAN = 10, } eIDPropertyType; -#define IDP_NUMTYPES 10 +#define IDP_NUMTYPES 11 /** Used by some IDP utils, keep values in sync with type enum above. */ enum { @@ -155,6 +170,7 @@ enum { IDP_TYPE_FILTER_ID = 1 << 7, IDP_TYPE_FILTER_DOUBLE = 1 << 8, IDP_TYPE_FILTER_IDPARRAY = 1 << 9, + IDP_TYPE_FILTER_BOOLEAN = 1 << 10, }; /*->subtype */ diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 5e9318b65dd..49c388a6cbf 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -1485,6 +1485,15 @@ static void rna_def_ID_properties(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_IDPROPERTY); RNA_def_property_array(prop, 1); + /* IDP_BOOLEAN */ + prop = RNA_def_property(srna, "bool", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_flag(prop, PROP_IDPROPERTY); + RNA_def_property_array(prop, 1); + + prop = RNA_def_property(srna, "bool_array", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_flag(prop, PROP_IDPROPERTY); + RNA_def_property_array(prop, 1); + /* IDP_GROUP */ prop = RNA_def_property(srna, "group", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_IDPROPERTY); diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index a1faab65089..e7187b2822b 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -369,6 +369,9 @@ static bool rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDPr if (idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT) { return false; } + if (idprop->subtype == IDP_BOOLEAN && prop->type != PROP_BOOLEAN) { + return false; + } if (idprop->subtype == IDP_INT && !ELEM(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM)) { return false; } @@ -379,6 +382,11 @@ static bool rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDPr return false; } break; + case IDP_BOOLEAN: + if (prop->type != PROP_BOOLEAN) { + return false; + } + break; case IDP_FLOAT: case IDP_DOUBLE: if (prop->type != PROP_FLOAT) { @@ -414,6 +422,7 @@ static PropertyRNA *typemap[IDP_NUMTYPES] = { &rna_PropertyGroupItem_id, &rna_PropertyGroupItem_double, &rna_PropertyGroupItem_idp_array, + &rna_PropertyGroupItem_bool, }; static PropertyRNA *arraytypemap[IDP_NUMTYPES] = { @@ -426,6 +435,8 @@ static PropertyRNA *arraytypemap[IDP_NUMTYPES] = { &rna_PropertyGroupItem_collection, NULL, &rna_PropertyGroupItem_double_array, + NULL, + (PropertyRNA *)&rna_PropertyGroupItem_bool_array, }; void rna_property_rna_or_id_get(PropertyRNA *prop, @@ -2160,7 +2171,7 @@ bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop) BLI_assert(RNA_property_array_check(prop) == false); if ((idprop = rna_idproperty_check(&prop, ptr))) { - value = IDP_Int(idprop) != 0; + value = IDP_Bool(idprop); } else if (bprop->get) { value = bprop->get(ptr); @@ -2190,7 +2201,7 @@ void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value) BLI_assert(ELEM(value, true, false)); if ((idprop = rna_idproperty_check(&prop, ptr))) { - IDP_Int(idprop) = (int)value; + IDP_Bool(idprop) = value; rna_idproperty_touch(idprop); } else if (bprop->set) { @@ -2207,7 +2218,7 @@ void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value) group = RNA_struct_idprops(ptr, 1); if (group) { - IDP_AddToGroup(group, IDP_New(IDP_INT, &val, prop->identifier)); + IDP_AddToGroup(group, IDP_New(IDP_BOOLEAN, &val, prop->identifier)); } } } @@ -2251,12 +2262,20 @@ void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, bool *va if (prop->arraydimension == 0) { values[0] = RNA_property_boolean_get(ptr, prop); } - else { + else if (idprop->subtype == IDP_INT) { + /* Some boolean IDProperty arrays might be saved in files as an integer + * array property, since the boolean IDProperty type was added later. */ int *values_src = IDP_Array(idprop); for (uint i = 0; i < idprop->len; i++) { values[i] = (bool)values_src[i]; } } + else if (idprop->subtype == IDP_BOOLEAN) { + bool *values_src = IDP_Array(idprop); + for (int i = 0; i < idprop->len; i++) { + values[i] = values_src[i]; + } + } } else if (prop->arraydimension == 0) { values[0] = RNA_property_boolean_get(ptr, prop); @@ -2314,9 +2333,17 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const bo IDP_Int(idprop) = values[0]; } else { - int *values_dst = IDP_Array(idprop); - for (uint i = 0; i < idprop->len; i++) { - values_dst[i] = (int)values[i]; + BLI_assert(idprop->type = IDP_ARRAY); + if (idprop->subtype == IDP_BOOLEAN) { + memcpy(IDP_Array(idprop), values, sizeof(int8_t) * idprop->len); + } + else if (idprop->subtype == IDP_INT) { + /* Support writing to integer and boolean IDProperties, since boolean + RNA properties used to be stored with integer IDProperties. */ + int *values_dst = IDP_Array(idprop); + for (uint i = 0; i < idprop->len; i++) { + values_dst[i] = (int)values[i]; + } } } rna_idproperty_touch(idprop); @@ -2335,15 +2362,15 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const bo IDProperty *group; val.array.len = prop->totarraylength; - val.array.type = IDP_INT; + val.array.type = IDP_BOOLEAN; group = RNA_struct_idprops(ptr, 1); if (group) { idprop = IDP_New(IDP_ARRAY, &val, prop->identifier); IDP_AddToGroup(group, idprop); - int *values_dst = IDP_Array(idprop); + bool *values_dst = IDP_Array(idprop); for (uint i = 0; i < idprop->len; i++) { - values_dst[i] = (int)values[i]; + values_dst[i] = values[i]; } } } @@ -2378,12 +2405,23 @@ void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int inde bool RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop) { + /* TODO: Make defaults work for IDProperties. */ BoolPropertyRNA *bprop = (BoolPropertyRNA *)rna_ensure_property(prop); BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN); BLI_assert(RNA_property_array_check(prop) == false); BLI_assert(ELEM(bprop->defaultvalue, false, true)); + if (prop->magic != RNA_MAGIC) { + const IDProperty *idprop = (const IDProperty *)prop; + BLI_assert(idprop->type == IDP_BOOLEAN); + if (idprop->ui_data) { + const IDPropertyUIDataBool *ui_data = (const IDPropertyUIDataBool *)idprop->ui_data; + return ui_data->default_value; + } + return false; + } + return bprop->defaultvalue; } @@ -2394,7 +2432,26 @@ void RNA_property_boolean_get_default_array(PointerRNA *ptr, PropertyRNA *prop, BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN); BLI_assert(RNA_property_array_check(prop) != false); - if (prop->arraydimension == 0) { + if (prop->magic != RNA_MAGIC) { + const IDProperty *idprop = (const IDProperty *)prop; + if (idprop->ui_data) { + BLI_assert(idprop->type == IDP_ARRAY); + BLI_assert(idprop->subtype == IDP_BOOLEAN); + const IDPropertyUIDataBool *ui_data = (const IDPropertyUIDataBool *)idprop->ui_data; + if (ui_data->default_array) { + rna_property_boolean_fill_default_array_values((bool *)ui_data->default_array, + ui_data->default_array_len, + ui_data->default_value, + idprop->len, + values); + } + else { + rna_property_boolean_fill_default_array_values( + NULL, 0, ui_data->default_value, idprop->len, values); + } + } + } + else if (prop->arraydimension == 0) { values[0] = bprop->defaultvalue; } else { diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index 9a6568355af..08cdbe10233 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -75,6 +75,11 @@ static PyObject *idprop_py_from_idp_double(const IDProperty *prop) return PyFloat_FromDouble(IDP_Double(prop)); } +static PyObject *idprop_py_from_idp_bool(const IDProperty *prop) +{ + return PyBool_FromLong(IDP_Bool(prop)); +} + static PyObject *idprop_py_from_idp_group(ID *id, IDProperty *prop, IDProperty *parent) { BPy_IDProperty *group = PyObject_New(BPy_IDProperty, &BPy_IDGroup_Type); @@ -155,6 +160,8 @@ PyObject *BPy_IDGroup_WrapData(ID *id, IDProperty *prop, IDProperty *parent) return idprop_py_from_idp_float(prop); case IDP_DOUBLE: return idprop_py_from_idp_double(prop); + case IDP_BOOLEAN: + return idprop_py_from_idp_bool(prop); case IDP_GROUP: return idprop_py_from_idp_group(id, prop, parent); case IDP_ARRAY: @@ -333,6 +340,12 @@ static char idp_sequence_type(PyObject *seq_fast) } type = IDP_DOUBLE; } + else if (PyBool_Check(item)) { + if (i != 0 && (type != IDP_BOOLEAN)) { + return -1; + } + type = IDP_BOOLEAN; + } else if (PyLong_Check(item)) { if (type == IDP_IDPARRAY) { /* mixed dict/int */ return -1; @@ -396,6 +409,13 @@ static IDProperty *idp_from_PyFloat(const char *name, PyObject *ob) return IDP_New(IDP_DOUBLE, &val, name); } +static IDProperty *idp_from_PyBool(const char *name, PyObject *ob) +{ + IDPropertyTemplate val = {0}; + val.i = PyC_Long_AsBool(ob); + return IDP_New(IDP_BOOLEAN, &val, name); +} + static IDProperty *idp_from_PyLong(const char *name, PyObject *ob) { IDPropertyTemplate val = {0}; @@ -466,6 +486,9 @@ static const char *idp_format_from_array_type(int type) if (type == IDP_DOUBLE) { return "d"; } + if (type == IDP_BOOLEAN) { + return "b"; + } return NULL; } @@ -549,6 +572,20 @@ static IDProperty *idp_from_PySequence_Fast(const char *name, PyObject *ob) } break; } + case IDP_BOOLEAN: { + prop = IDP_New(IDP_ARRAY, &val, name); + bool *prop_data = IDP_Array(prop); + for (i = 0; i < val.array.len; i++) { + item = ob_seq_fast_items[i]; + const int value = PyC_Long_AsBool(item); + if ((value == -1) && PyErr_Occurred()) { + IDP_FreeProperty(prop); + return NULL; + } + prop_data[i] = (value != 0); + } + break; + } default: /* should never happen */ PyErr_SetString(PyExc_RuntimeError, "internal error with idp array.type"); @@ -642,6 +679,9 @@ static IDProperty *idp_from_PyObject(PyObject *name_obj, PyObject *ob) if (PyFloat_Check(ob)) { return idp_from_PyFloat(name, ob); } + if (PyBool_Check(ob)) { + return idp_from_PyBool(name, ob); + } if (PyLong_Check(ob)) { return idp_from_PyLong(name, ob); } @@ -779,6 +819,8 @@ PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) return idprop_py_from_idp_float(prop); case IDP_DOUBLE: return idprop_py_from_idp_double(prop); + case IDP_BOOLEAN: + return idprop_py_from_idp_bool(prop); case IDP_ID: return idprop_py_from_idp_id(prop); case IDP_ARRAY: { @@ -813,6 +855,13 @@ PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop) } break; } + case IDP_BOOLEAN: { + const int8_t *array = (const int8_t *)IDP_Array(prop); + for (i = 0; i < prop->len; i++) { + PyList_SET_ITEM(seq, i, PyBool_FromLong(array[i])); + } + break; + } default: PyErr_Format( PyExc_RuntimeError, "%s: invalid/corrupt array type '%d'!", __func__, prop->subtype); @@ -1629,20 +1678,23 @@ PyTypeObject BPy_IDGroup_Type = { /** \name ID Array Methods * \{ */ -static PyTypeObject *idp_array_py_type(BPy_IDArray *self, bool *r_is_double) +static PyTypeObject *idp_array_py_type(BPy_IDArray *self, size_t *elem_size) { switch (self->prop->subtype) { case IDP_FLOAT: - *r_is_double = false; + *elem_size = sizeof(float); return &PyFloat_Type; case IDP_DOUBLE: - *r_is_double = true; + *elem_size = sizeof(double); return &PyFloat_Type; + case IDP_BOOLEAN: + *elem_size = sizeof(int8_t); + return &PyBool_Type; case IDP_INT: - *r_is_double = false; + *elem_size = sizeof(int); return &PyLong_Type; default: - *r_is_double = false; + *elem_size = 0; return NULL; } } @@ -1653,7 +1705,7 @@ static PyObject *BPy_IDArray_repr(BPy_IDArray *self) } PyDoc_STRVAR(BPy_IDArray_get_typecode_doc, - "The type of the data in the array {'f': float, 'd': double, 'i': int}."); + "The type of the data in the array {'f': float, 'd': double, 'i': int, 'b': bool}."); static PyObject *BPy_IDArray_get_typecode(BPy_IDArray *self) { switch (self->prop->subtype) { @@ -1663,6 +1715,8 @@ static PyObject *BPy_IDArray_get_typecode(BPy_IDArray *self) return PyUnicode_FromString("d"); case IDP_INT: return PyUnicode_FromString("i"); + case IDP_BOOLEAN: + return PyUnicode_FromString("b"); } PyErr_Format( @@ -1714,6 +1768,8 @@ static PyObject *BPy_IDArray_GetItem(BPy_IDArray *self, Py_ssize_t index) return PyFloat_FromDouble(((double *)IDP_Array(self->prop))[index]); case IDP_INT: return PyLong_FromLong((long)((int *)IDP_Array(self->prop))[index]); + case IDP_BOOLEAN: + return PyBool_FromLong((long)((int8_t *)IDP_Array(self->prop))[index]); } PyErr_Format( @@ -1755,6 +1811,15 @@ static int BPy_IDArray_SetItem(BPy_IDArray *self, Py_ssize_t index, PyObject *va ((int *)IDP_Array(self->prop))[index] = i; break; } + case IDP_BOOLEAN: { + const int i = PyC_Long_AsBool(value); + if (i == -1 && PyErr_Occurred()) { + return -1; + } + + ((int8_t *)IDP_Array(self->prop))[index] = i; + break; + } } return 0; } @@ -1810,6 +1875,13 @@ static PyObject *BPy_IDArray_slice(BPy_IDArray *self, int begin, int end) } break; } + case IDP_BOOLEAN: { + const int8_t *array = (const int8_t *)IDP_Array(prop); + for (count = begin; count < end; count++) { + PyTuple_SET_ITEM(tuple, count - begin, PyBool_FromLong((long)array[count])); + } + break; + } } return tuple; @@ -1818,9 +1890,8 @@ static PyObject *BPy_IDArray_slice(BPy_IDArray *self, int begin, int end) static int BPy_IDArray_ass_slice(BPy_IDArray *self, int begin, int end, PyObject *seq) { IDProperty *prop = self->prop; - bool is_double; - const PyTypeObject *py_type = idp_array_py_type(self, &is_double); - const size_t elem_size = is_double ? sizeof(double) : sizeof(float); + size_t elem_size; + const PyTypeObject *py_type = idp_array_py_type(self, &elem_size); size_t alloc_len; size_t size; void *vec; @@ -1933,6 +2004,9 @@ static int itemsize_by_idarray_type(int array_type) if (array_type == IDP_DOUBLE) { return sizeof(double); } + if (array_type == IDP_BOOLEAN) { + return sizeof(bool); + } return -1; /* should never happen */ } diff --git a/source/blender/python/generic/idprop_py_ui_api.c b/source/blender/python/generic/idprop_py_ui_api.c index 4487a885a6c..78a328ab772 100644 --- a/source/blender/python/generic/idprop_py_ui_api.c +++ b/source/blender/python/generic/idprop_py_ui_api.c @@ -181,6 +181,89 @@ static bool idprop_ui_data_update_int(IDProperty *idprop, PyObject *args, PyObje return true; } +/** + * \note The default value needs special handling because for array IDProperties it can + * be a single value or an array, but for non-array properties it can only be a value. + */ +static bool idprop_ui_data_update_bool_default(IDProperty *idprop, + IDPropertyUIDataBool *ui_data, + PyObject *default_value) +{ + if (PySequence_Check(default_value)) { + if (idprop->type != IDP_ARRAY) { + PyErr_SetString(PyExc_TypeError, "Only array properties can have array default values"); + return false; + } + + Py_ssize_t len = PySequence_Size(default_value); + int8_t *new_default_array = (int8_t *)MEM_malloc_arrayN(len, sizeof(int8_t), __func__); + if (PyC_AsArray(new_default_array, + sizeof(int8_t), + default_value, + len, + &PyBool_Type, + "ui_data_update") == -1) { + MEM_freeN(new_default_array); + return false; + } + + ui_data->default_array_len = len; + ui_data->default_array = new_default_array; + } + else { + const int value = PyC_Long_AsBool(default_value); + if ((value == -1) && PyErr_Occurred()) { + PyErr_SetString(PyExc_ValueError, "Error converting \"default\" argument to integer"); + return false; + } + ui_data->default_value = (value != 0); + } + + return true; +} + +/** + * \return False when parsing fails, in which case caller should return NULL. + */ +static bool idprop_ui_data_update_bool(IDProperty *idprop, PyObject *args, PyObject *kwargs) +{ + const char *rna_subtype = NULL; + const char *description = NULL; + PyObject *default_value = NULL; + const char *kwlist[] = {"default", "subtype", "description", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, + kwargs, + "|$Ozz:update", + (char **)kwlist, + &default_value, + &rna_subtype, + &description)) { + return false; + } + + /* Write to a temporary copy of the UI data in case some part of the parsing fails. */ + IDPropertyUIDataBool *ui_data_orig = (IDPropertyUIDataBool *)idprop->ui_data; + IDPropertyUIDataBool ui_data = *ui_data_orig; + + if (!idprop_ui_data_update_base(&ui_data.base, rna_subtype, description)) { + IDP_ui_data_free_unique_contents(&ui_data.base, IDP_ui_data_type(idprop), &ui_data_orig->base); + return false; + } + + if (!ELEM(default_value, NULL, Py_None)) { + if (!idprop_ui_data_update_bool_default(idprop, &ui_data, default_value)) { + IDP_ui_data_free_unique_contents( + &ui_data.base, IDP_ui_data_type(idprop), &ui_data_orig->base); + return false; + } + } + + /* Write back to the property's UI data. */ + IDP_ui_data_free_unique_contents(&ui_data_orig->base, IDP_ui_data_type(idprop), &ui_data.base); + *ui_data_orig = ui_data; + return true; +} + /** * \note The default value needs special handling because for array IDProperties it can * be a single value or an array, but for non-array properties it can only be a value. @@ -403,6 +486,12 @@ static PyObject *BPy_IDPropertyUIManager_update(BPy_IDPropertyUIManager *self, return NULL; } Py_RETURN_NONE; + case IDP_UI_DATA_TYPE_BOOLEAN: + IDP_ui_data_ensure(property); + if (!idprop_ui_data_update_bool(property, args, kwargs)) { + return NULL; + } + Py_RETURN_NONE; case IDP_UI_DATA_TYPE_FLOAT: IDP_ui_data_ensure(property); if (!idprop_ui_data_update_float(property, args, kwargs)) { @@ -465,6 +554,25 @@ static void idprop_ui_data_to_dict_int(IDProperty *property, PyObject *dict) } } +static void idprop_ui_data_to_dict_bool(IDProperty *property, PyObject *dict) +{ + IDPropertyUIDataBool *ui_data = (IDPropertyUIDataBool *)property->ui_data; + PyObject *item; + + if (property->type == IDP_ARRAY) { + PyObject *list = PyList_New(ui_data->default_array_len); + for (int i = 0; i < ui_data->default_array_len; i++) { + PyList_SET_ITEM(list, i, PyBool_FromLong(ui_data->default_array[i])); + } + PyDict_SetItemString(dict, "default", list); + Py_DECREF(list); + } + else { + PyDict_SetItemString(dict, "default", item = PyBool_FromLong(ui_data->default_value)); + Py_DECREF(item); + } +} + static void idprop_ui_data_to_dict_float(IDProperty *property, PyObject *dict) { IDPropertyUIDataFloat *ui_data = (IDPropertyUIDataFloat *)property->ui_data; @@ -547,6 +655,9 @@ static PyObject *BPy_IDIDPropertyUIManager_as_dict(BPy_IDPropertyUIManager *self case IDP_UI_DATA_TYPE_INT: idprop_ui_data_to_dict_int(property, dict); break; + case IDP_UI_DATA_TYPE_BOOLEAN: + idprop_ui_data_to_dict_bool(property, dict); + break; case IDP_UI_DATA_TYPE_FLOAT: idprop_ui_data_to_dict_float(property, dict); break; From cb92ff7b2d50659f97ff363c842bf109310ff0aa Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 13 Jan 2023 12:49:53 -0600 Subject: [PATCH 0630/1522] Geometry Nodes: Only set soft range for modifier properties Similar to the corresponding properties on node sockets, only adjust the soft range. Because group nodes only have soft limits, groups should generally be able to accept these inputs anyway. The benefit of only using a soft range is that it allows choosing a more user- friendly default range while keeping flexibility. --- source/blender/modifiers/intern/MOD_nodes.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 2c5e02fbbe5..d9198ba9025 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -442,8 +442,8 @@ id_property_create_from_socket(const bNodeSocket &socket) auto property = bke::idprop::create(socket.identifier, value->value); IDPropertyUIDataFloat *ui_data = (IDPropertyUIDataFloat *)IDP_ui_data_ensure(property.get()); ui_data->base.rna_subtype = value->subtype; - ui_data->min = ui_data->soft_min = double(value->min); - ui_data->max = ui_data->soft_max = double(value->max); + ui_data->soft_min = double(value->min); + ui_data->soft_max = double(value->max); ui_data->default_value = value->value; return property; } @@ -453,8 +453,8 @@ id_property_create_from_socket(const bNodeSocket &socket) auto property = bke::idprop::create(socket.identifier, value->value); IDPropertyUIDataInt *ui_data = (IDPropertyUIDataInt *)IDP_ui_data_ensure(property.get()); ui_data->base.rna_subtype = value->subtype; - ui_data->min = ui_data->soft_min = value->min; - ui_data->max = ui_data->soft_max = value->max; + ui_data->soft_min = value->min; + ui_data->soft_max = value->max; ui_data->default_value = value->value; return property; } @@ -465,8 +465,8 @@ id_property_create_from_socket(const bNodeSocket &socket) socket.identifier, Span{value->value[0], value->value[1], value->value[2]}); IDPropertyUIDataFloat *ui_data = (IDPropertyUIDataFloat *)IDP_ui_data_ensure(property.get()); ui_data->base.rna_subtype = value->subtype; - ui_data->min = ui_data->soft_min = double(value->min); - ui_data->max = ui_data->soft_max = double(value->max); + ui_data->soft_min = double(value->min); + ui_data->soft_max = double(value->max); ui_data->default_array = (double *)MEM_mallocN(sizeof(double[3]), "mod_prop_default"); ui_data->default_array_len = 3; for (const int i : IndexRange(3)) { From 2c910cb70af130a175cc646c6f22cc961a464e70 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 13 Jan 2023 14:20:08 -0600 Subject: [PATCH 0631/1522] Modifiers: Only allow geometry nodes for curves and point cloud Effectively this disables two volume modifiers for the new curves object and the point cloud object types. The aim is to simplify the process of using these object types to prove out a node-group-based workflow integrated with the asset browser. We're making the assumption that these two modifiers were used very rarely on the new curves type since that wasn't its purpose, so this breaks backwards compatibility. --- source/blender/blenkernel/intern/object.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index d33f8fe5de7..16aeff19ee9 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -1425,9 +1425,11 @@ bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type) return false; } - /* Only geometry objects should be able to get modifiers T25291. */ - if (ELEM(ob->type, OB_POINTCLOUD, OB_VOLUME, OB_CURVES)) { - return (mti->modifyGeometrySet != nullptr); + if (ELEM(ob->type, OB_POINTCLOUD, OB_CURVES)) { + return modifier_type == eModifierType_Nodes; + } + if (ob->type == OB_VOLUME) { + return mti->modifyGeometrySet != nullptr; } if (ELEM(ob->type, OB_MESH, OB_CURVES_LEGACY, OB_SURF, OB_FONT, OB_LATTICE)) { if (ob->type == OB_LATTICE && (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly) == 0) { From a5c3f5b0bc3339d94b53ed216f6e915b3968658a Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Fri, 13 Jan 2023 21:25:41 +0100 Subject: [PATCH 0632/1522] Fix T103818: Freeze frames in movie strips when timecodes are used Timecodes were generated from read packets, but applied to decoded frames. This works as long as delay between packet read and decoded frame is less than GOP size or if packet does not produce multiple frames. In this case it did not work. Use `pkt_pos`, `pkt_dts` and `pts` from `AVFrame` instead of `AVPacket`. This way delay can be eliminated and timecode files are more reliable. --- source/blender/imbuf/intern/indexer.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index d824b87f493..6d849f54d4c 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -1040,16 +1040,6 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context, } if (next_packet->stream_index == context->videoStream) { - if (next_packet->flags & AV_PKT_FLAG_KEY) { - context->last_seek_pos = context->seek_pos; - context->last_seek_pos_pts = context->seek_pos_pts; - context->last_seek_pos_dts = context->seek_pos_dts; - - context->seek_pos = next_packet->pos; - context->seek_pos_pts = next_packet->pts; - context->seek_pos_dts = next_packet->dts; - } - int ret = avcodec_send_packet(context->iCodecCtx, next_packet); while (ret >= 0) { ret = avcodec_receive_frame(context->iCodecCtx, in_frame); @@ -1062,6 +1052,17 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context, fprintf(stderr, "Error decoding proxy frame: %s\n", av_err2str(ret)); break; } + + if (next_packet->flags & AV_PKT_FLAG_KEY) { + context->last_seek_pos = context->seek_pos; + context->last_seek_pos_pts = context->seek_pos_pts; + context->last_seek_pos_dts = context->seek_pos_dts; + + context->seek_pos = in_frame->pkt_pos; + context->seek_pos_pts = in_frame->pts; + context->seek_pos_dts = in_frame->pkt_dts; + } + index_rebuild_ffmpeg_proc_decoded_frame(context, next_packet, in_frame); } } From dc99c09daadadaf4828d863105b35dcc19b54846 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 13 Jan 2023 14:50:59 -0600 Subject: [PATCH 0633/1522] Cleanup: Use const when accessing custom data layers --- source/blender/blenkernel/BKE_particle.h | 2 +- .../blenkernel/intern/data_transfer.cc | 2 +- .../blenkernel/intern/data_transfer_intern.h | 2 +- source/blender/blenkernel/intern/deform.c | 4 +-- source/blender/blenkernel/intern/particle.cc | 2 +- source/blender/draw/DRW_pbvh.h | 2 +- .../draw/intern/draw_cache_impl_particles.c | 16 ++++----- source/blender/draw/intern/draw_pbvh.cc | 28 ++++++++-------- .../mesh_extractors/extract_mesh_vbo_tan.cc | 33 ++++++++++--------- .../mesh_extractors/extract_mesh_vbo_uv.cc | 2 +- source/blender/editors/mesh/meshtools.cc | 12 ++++--- .../blender/editors/physics/particle_edit.c | 15 +++++---- .../blender/editors/physics/particle_object.c | 2 +- .../editors/sculpt_paint/sculpt_face_set.cc | 3 +- .../spreadsheet_data_source_geometry.cc | 2 +- .../io/alembic/exporter/abc_writer_mesh.cc | 2 +- .../blender/io/usd/intern/usd_writer_mesh.cc | 2 +- source/blender/makesrna/intern/rna_particle.c | 18 +++++----- source/blender/render/intern/bake.cc | 5 +-- 19 files changed, 79 insertions(+), 75 deletions(-) diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 5cf0eced72e..fc9769a94a4 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -584,7 +584,7 @@ void psys_get_texture(struct ParticleSimulationData *sim, void psys_interpolate_face(struct Mesh *mesh, const float (*vert_positions)[3], const float (*vert_normals)[3], - struct MFace *mface, + const struct MFace *mface, struct MTFace *tface, const float (*orcodata)[3], float w[4], diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index b3b8d4730bb..48dd0c84a54 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -512,7 +512,7 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map const int num_elem_dst, const bool use_create, const bool use_delete, - CustomData *cd_src, + const CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst, const int tolayers, diff --git a/source/blender/blenkernel/intern/data_transfer_intern.h b/source/blender/blenkernel/intern/data_transfer_intern.h index defa87e899b..8335f21d0ad 100644 --- a/source/blender/blenkernel/intern/data_transfer_intern.h +++ b/source/blender/blenkernel/intern/data_transfer_intern.h @@ -46,7 +46,7 @@ bool data_transfer_layersmapping_vgroups(struct ListBase *r_map, bool use_delete, struct Object *ob_src, struct Object *ob_dst, - struct CustomData *cd_src, + const struct CustomData *cd_src, struct CustomData *cd_dst, bool use_dupref_dst, int fromlayers, diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index b5c3147b0f1..c2e5434f0e1 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -1217,7 +1217,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map, Object *ob_dst, const MDeformVert *data_src, MDeformVert *data_dst, - CustomData *UNUSED(cd_src), + const CustomData *UNUSED(cd_src), CustomData *cd_dst, const bool UNUSED(use_dupref_dst), const int tolayers, @@ -1365,7 +1365,7 @@ bool data_transfer_layersmapping_vgroups(ListBase *r_map, const bool use_delete, Object *ob_src, Object *ob_dst, - CustomData *cd_src, + const CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst, const int fromlayers, diff --git a/source/blender/blenkernel/intern/particle.cc b/source/blender/blenkernel/intern/particle.cc index 484cb343a97..f871aa324be 100644 --- a/source/blender/blenkernel/intern/particle.cc +++ b/source/blender/blenkernel/intern/particle.cc @@ -1702,7 +1702,7 @@ static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCach void psys_interpolate_face(Mesh *mesh, const float (*vert_positions)[3], const float (*vert_normals)[3], - MFace *mface, + const MFace *mface, MTFace *tface, const float (*orcodata)[3], float w[4], diff --git a/source/blender/draw/DRW_pbvh.h b/source/blender/draw/DRW_pbvh.h index db21f22aeb0..d49e5b6c686 100644 --- a/source/blender/draw/DRW_pbvh.h +++ b/source/blender/draw/DRW_pbvh.h @@ -64,7 +64,7 @@ typedef struct PBVH_GPU_Args { int *prim_indices; int totprim; - bool *hide_poly; + const bool *hide_poly; int node_verts_num; diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index d2f9a634922..5b45fa38704 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -310,8 +310,8 @@ static void particle_calculate_parent_uvs(ParticleSystem *psys, } } if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { - MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); - MFace *mface = &mfaces[num]; + const MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); + const MFace *mface = &mfaces[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]); } @@ -340,8 +340,8 @@ static void particle_calculate_parent_mcol(ParticleSystem *psys, } } if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { - MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); - MFace *mface = &mfaces[num]; + const MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); + const MFace *mface = &mfaces[num]; for (int j = 0; j < num_col_layers; j++) { /* CustomDataLayer CD_MCOL has 4 structs per face. */ psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]); @@ -367,8 +367,8 @@ static void particle_interpolate_children_uvs(ParticleSystem *psys, ChildParticle *particle = &psys->child[child_index]; int num = particle->num; if (num != DMCACHE_NOTFOUND) { - MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); - MFace *mface = &mfaces[num]; + const MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); + const MFace *mface = &mfaces[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]); } @@ -392,8 +392,8 @@ static void particle_interpolate_children_mcol(ParticleSystem *psys, ChildParticle *particle = &psys->child[child_index]; int num = particle->num; if (num != DMCACHE_NOTFOUND) { - MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); - MFace *mface = &mfaces[num]; + const MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); + const MFace *mface = &mfaces[num]; for (int j = 0; j < num_col_layers; j++) { /* CustomDataLayer CD_MCOL has 4 structs per face. */ psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]); diff --git a/source/blender/draw/intern/draw_pbvh.cc b/source/blender/draw/intern/draw_pbvh.cc index 964d2190177..68ef6cef8a6 100644 --- a/source/blender/draw/intern/draw_pbvh.cc +++ b/source/blender/draw/intern/draw_pbvh.cc @@ -595,7 +595,8 @@ struct PBVHBatches { fill_vbo_normal_faces(vbo, args, foreach_faces, &access); break; case CD_PBVH_MASK_TYPE: { - float *mask = static_cast(CustomData_get_layer(args->vdata, CD_PAINT_MASK)); + const float *mask = static_cast( + CustomData_get_layer(args->vdata, CD_PAINT_MASK)); if (mask) { foreach_faces( @@ -613,7 +614,7 @@ struct PBVHBatches { break; } case CD_PBVH_FSET_TYPE: { - int *face_sets = static_cast( + const int *face_sets = static_cast( CustomData_get_layer_named(args->pdata, CD_PROP_INT32, ".sculpt_face_set")); if (face_sets) { @@ -653,13 +654,13 @@ struct PBVHBatches { } case CD_PROP_COLOR: if (vbo.domain == ATTR_DOMAIN_POINT) { - MPropCol *mpropcol = static_cast( + const MPropCol *mpropcol = static_cast( CustomData_get_layer_named(args->vdata, CD_PROP_COLOR, vbo.name.c_str())); foreach_faces( [&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const MLoopTri * /*tri*/) { ushort color[4]; - MPropCol *col = mpropcol + vertex_i; + const MPropCol *col = mpropcol + vertex_i; color[0] = unit_float_to_ushort_clamp(col->color[0]); color[1] = unit_float_to_ushort_clamp(col->color[1]); @@ -670,12 +671,12 @@ struct PBVHBatches { }); } else if (vbo.domain == ATTR_DOMAIN_CORNER) { - MPropCol *mpropcol = static_cast( + const MPropCol *mpropcol = static_cast( CustomData_get_layer_named(args->ldata, CD_PROP_COLOR, vbo.name.c_str())); foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const MLoopTri *tri) { ushort color[4]; - MPropCol *col = mpropcol + tri->tri[tri_i]; + const MPropCol *col = mpropcol + tri->tri[tri_i]; color[0] = unit_float_to_ushort_clamp(col->color[0]); color[1] = unit_float_to_ushort_clamp(col->color[1]); @@ -688,13 +689,13 @@ struct PBVHBatches { break; case CD_PROP_BYTE_COLOR: if (vbo.domain == ATTR_DOMAIN_POINT) { - MLoopCol *mbytecol = static_cast( + const MLoopCol *mbytecol = static_cast( CustomData_get_layer_named(args->vdata, CD_PROP_BYTE_COLOR, vbo.name.c_str())); foreach_faces( [&](int /*buffer_i*/, int /*tri_i*/, int vertex_i, const MLoopTri * /*tri*/) { ushort color[4]; - MLoopCol *col = mbytecol + vertex_i; + const MLoopCol *col = mbytecol + vertex_i; color[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->r]); color[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->g]); @@ -705,12 +706,12 @@ struct PBVHBatches { }); } else if (vbo.domain == ATTR_DOMAIN_CORNER) { - MLoopCol *mbytecol = static_cast( + const MLoopCol *mbytecol = static_cast( CustomData_get_layer_named(args->ldata, CD_PROP_BYTE_COLOR, vbo.name.c_str())); foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const MLoopTri *tri) { ushort color[4]; - MLoopCol *col = mbytecol + tri->tri[tri_i]; + const MLoopCol *col = mbytecol + tri->tri[tri_i]; color[0] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->r]); color[1] = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[col->g]); @@ -722,7 +723,7 @@ struct PBVHBatches { } break; case CD_PROP_FLOAT2: { - float2 *mloopuv = static_cast( + const float2 *mloopuv = static_cast( CustomData_get_layer_named(args->ldata, CD_PROP_FLOAT2, vbo.name.c_str())); foreach_faces([&](int /*buffer_i*/, int tri_i, int /*vertex_i*/, const MLoopTri *tri) { @@ -730,7 +731,6 @@ struct PBVHBatches { }); break; } - } } @@ -972,7 +972,7 @@ struct PBVHBatches { void create_index_faces(PBVH_GPU_Args *args) { - int *mat_index = static_cast( + const int *mat_index = static_cast( CustomData_get_layer_named(args->pdata, CD_PROP_INT32, "material_index")); if (mat_index && args->totprim) { @@ -1062,7 +1062,7 @@ struct PBVHBatches { void create_index_grids(PBVH_GPU_Args *args, bool do_coarse) { - int *mat_index = static_cast( + const int *mat_index = static_cast( CustomData_get_layer_named(args->pdata, CD_PROP_INT32, "material_index")); if (mat_index && args->totprim) { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc index 0ee95b7dcf6..bd1c98b033f 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_tan.cc @@ -40,8 +40,8 @@ static void extract_tan_init_common(const MeshRenderData *mr, CustomData *cd_ldata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->ldata : &mr->me->ldata; CustomData *cd_vdata = (mr->extract_type == MR_EXTRACT_BMESH) ? &mr->bm->vdata : &mr->me->vdata; uint32_t tan_layers = cache->cd_used.tan; - float(*orco)[3] = (float(*)[3])CustomData_get_layer(cd_vdata, CD_ORCO); - bool orco_allocated = false; + const float(*orco)[3] = (const float(*)[3])CustomData_get_layer(cd_vdata, CD_ORCO); + float(*orco_allocated)[3] = nullptr; bool use_orco_tan = cache->cd_used.tan_orco != 0; int tan_len = 0; @@ -76,8 +76,7 @@ static void extract_tan_init_common(const MeshRenderData *mr, } if (use_orco_tan && orco == nullptr) { /* If `orco` is not available compute it ourselves */ - orco_allocated = true; - orco = (float(*)[3])MEM_mallocN(sizeof(*orco) * mr->vert_len, __func__); + orco_allocated = (float(*)[3])MEM_mallocN(sizeof(*orco) * mr->vert_len, __func__); if (mr->extract_type == MR_EXTRACT_BMESH) { BMesh *bm = mr->bm; @@ -85,15 +84,16 @@ static void extract_tan_init_common(const MeshRenderData *mr, const BMVert *eve = BM_vert_at_index(bm, v); /* Exceptional case where #bm_vert_co_get can be avoided, as we want the original coords. * not the distorted ones. */ - copy_v3_v3(orco[v], eve->co); + copy_v3_v3(orco_allocated[v], eve->co); } } else { for (int v = 0; v < mr->vert_len; v++) { - copy_v3_v3(orco[v], mr->vert_positions[v]); + copy_v3_v3(orco_allocated[v], mr->vert_positions[v]); } } - BKE_mesh_orco_verts_transform(mr->me, orco, mr->vert_len, 0); + BKE_mesh_orco_verts_transform(mr->me, orco_allocated, mr->vert_len, 0); + orco = orco_allocated; } /* Start Fresh */ @@ -144,9 +144,7 @@ static void extract_tan_init_common(const MeshRenderData *mr, GPU_vertformat_alias_add(format, "at"); } - if (orco_allocated) { - MEM_SAFE_FREE(orco); - } + MEM_SAFE_FREE(orco_allocated); int v_len = mr->loop_len; if (format->attr_len == 0) { @@ -192,7 +190,7 @@ static void extract_tan_ex_init(const MeshRenderData *mr, short(*tan_data)[4] = (short(*)[4])GPU_vertbuf_get_data(vbo); for (int i = 0; i < tan_len; i++) { const char *name = tangent_names[i]; - float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named( + const float(*layer_data)[4] = (const float(*)[4])CustomData_get_layer_named( &loop_data, CD_TANGENT, name); for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) { normal_float_to_short_v3(*tan_data, layer_data[ml_index]); @@ -201,7 +199,8 @@ static void extract_tan_ex_init(const MeshRenderData *mr, } } if (use_orco_tan) { - float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(&loop_data, CD_TANGENT, 0); + const float(*layer_data)[4] = (const float(*)[4])CustomData_get_layer_n( + &loop_data, CD_TANGENT, 0); for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) { normal_float_to_short_v3(*tan_data, layer_data[ml_index]); (*tan_data)[3] = (layer_data[ml_index][3] > 0.0f) ? SHRT_MAX : SHRT_MIN; @@ -213,7 +212,7 @@ static void extract_tan_ex_init(const MeshRenderData *mr, GPUPackedNormal *tan_data = (GPUPackedNormal *)GPU_vertbuf_get_data(vbo); for (int i = 0; i < tan_len; i++) { const char *name = tangent_names[i]; - float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named( + const float(*layer_data)[4] = (const float(*)[4])CustomData_get_layer_named( &loop_data, CD_TANGENT, name); for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) { *tan_data = GPU_normal_convert_i10_v3(layer_data[ml_index]); @@ -222,7 +221,8 @@ static void extract_tan_ex_init(const MeshRenderData *mr, } } if (use_orco_tan) { - float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(&loop_data, CD_TANGENT, 0); + const float(*layer_data)[4] = (const float(*)[4])CustomData_get_layer_n( + &loop_data, CD_TANGENT, 0); for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) { *tan_data = GPU_normal_convert_i10_v3(layer_data[ml_index]); tan_data->w = (layer_data[ml_index][3] > 0.0f) ? 1 : -2; @@ -291,7 +291,7 @@ static void extract_tan_init_subdiv(const DRWSubdivCache *subdiv_cache, for (int i = 0; i < tan_len; i++) { float(*tan_data)[4] = (float(*)[4])GPU_vertbuf_get_data(coarse_vbo); const char *name = tangent_names[i]; - const float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named( + const float(*layer_data)[4] = (const float(*)[4])CustomData_get_layer_named( &loop_data, CD_TANGENT, name); for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) { copy_v3_v3(*tan_data, layer_data[ml_index]); @@ -308,7 +308,8 @@ static void extract_tan_init_subdiv(const DRWSubdivCache *subdiv_cache, } if (use_orco_tan) { float(*tan_data)[4] = (float(*)[4])GPU_vertbuf_get_data(coarse_vbo); - const float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(&loop_data, CD_TANGENT, 0); + const float(*layer_data)[4] = (const float(*)[4])CustomData_get_layer_n( + &loop_data, CD_TANGENT, 0); for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) { copy_v3_v3(*tan_data, layer_data[ml_index]); (*tan_data)[3] = (layer_data[ml_index][3] > 0.0f) ? 1.0f : -1.0f; diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc index 54dbfa4fbe1..2af8fa40844 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_uv.cc @@ -109,7 +109,7 @@ static void extract_uv_init(const MeshRenderData *mr, } } else { - const float2 *layer_data = static_cast( + const float2 *layer_data = static_cast( CustomData_get_layer_n(cd_ldata, CD_PROP_FLOAT2, i)); for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, uv_data++, layer_data++) { memcpy(uv_data, layer_data, sizeof(*uv_data)); diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc index bf10d51f2e1..a5e61cb8b33 100644 --- a/source/blender/editors/mesh/meshtools.cc +++ b/source/blender/editors/mesh/meshtools.cc @@ -1081,7 +1081,7 @@ static uint mirror_facehash(const void *ptr) return ((v0 * 39) ^ (v1 * 31)); } -static int mirror_facerotation(MFace *a, MFace *b) +static int mirror_facerotation(const MFace *a, const MFace *b) { if (b->v4) { if (a->v1 == b->v1 && a->v2 == b->v2 && a->v3 == b->v3 && a->v4 == b->v4) { @@ -1120,7 +1120,8 @@ static bool mirror_facecmp(const void *a, const void *b) int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval) { Mesh *me = static_cast(ob->data); - MFace mirrormf, *mf, *hashmf; + MFace mirrormf; + const MFace *mf, *hashmf; GHash *fhash; int *mirrorverts, *mirrorfaces; @@ -1135,7 +1136,8 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval) mirrorfaces = static_cast(MEM_callocN(sizeof(int[2]) * totface, "MirrorFaces")); const Span vert_positions = me_eval ? me_eval->vert_positions() : me->vert_positions(); - MFace *mface = (MFace *)CustomData_get_layer(&(me_eval ? me_eval : me)->fdata, CD_MFACE); + const MFace *mface = (const MFace *)CustomData_get_layer(&(me_eval ? me_eval : me)->fdata, + CD_MFACE); ED_mesh_mirror_spatial_table_begin(ob, em, me_eval); @@ -1147,7 +1149,7 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval) fhash = BLI_ghash_new_ex(mirror_facehash, mirror_facecmp, "mirror_facehash gh", me->totface); for (a = 0, mf = mface; a < totface; a++, mf++) { - BLI_ghash_insert(fhash, mf, mf); + BLI_ghash_insert(fhash, (void *)mf, (void *)mf); } for (a = 0, mf = mface; a < totface; a++, mf++) { @@ -1162,7 +1164,7 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, Mesh *me_eval) std::swap(mirrormf.v2, mirrormf.v4); } - hashmf = static_cast(BLI_ghash_lookup(fhash, &mirrormf)); + hashmf = static_cast(BLI_ghash_lookup(fhash, &mirrormf)); if (hashmf) { mirrorfaces[a * 2] = hashmf - mface; mirrorfaces[a * 2 + 1] = mirror_facerotation(&mirrormf, hashmf); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 02569184541..8d804eeaa8e 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -1454,9 +1454,9 @@ void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *UNUSED(ob), Part const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); - MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + const MFace *mfaces = (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); for (i = 0; i < totface; i++, vec += 6, nor += 6) { - MFace *mface = &mfaces[i]; + const MFace *mface = &mfaces[i]; copy_v3_v3(vec, positions[mface->v1]); copy_v3_v3(nor, vert_normals[mface->v1]); @@ -3564,9 +3564,10 @@ static void PE_mirror_x(Depsgraph *depsgraph, Scene *scene, Object *ob, int tagg } if (newtotpart != psys->totpart) { - MFace *mtessface = use_dm_final_indices ? - (MFace *)CustomData_get_layer(&psmd_eval->mesh_final->fdata, CD_MFACE) : - (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE); + const MFace *mtessface = use_dm_final_indices ? + (const MFace *)CustomData_get_layer(&psmd_eval->mesh_final->fdata, + CD_MFACE) : + (const MFace *)CustomData_get_layer(&me->fdata, CD_MFACE); /* allocate new arrays and copy existing */ new_pars = MEM_callocN(newtotpart * sizeof(ParticleData), "ParticleData new"); @@ -4136,7 +4137,7 @@ static int particle_intersect_mesh(Depsgraph *depsgraph, float radius, float *ipoint) { - MFace *mface = NULL; + const MFace *mface = NULL; int i, totface, intersect = 0; float cur_d, cur_uv[2], v1[3], v2[3], v3[3], v4[3], min[3], max[3], p_min[3], p_max[3]; float cur_ipoint[3]; @@ -4173,7 +4174,7 @@ static int particle_intersect_mesh(Depsgraph *depsgraph, } totface = mesh->totface; - mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + mface = (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); /* lets intersect the faces */ diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index ebf030bad71..58ed94fdbb8 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -705,7 +705,7 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, PTCacheEditPoint *edit_point; PTCacheEditKey *ekey; BVHTreeFromMesh bvhtree = {NULL}; - MFace *mface = NULL, *mf; + const MFace *mface = NULL, *mf; const MEdge *medge = NULL, *me; Mesh *mesh, *target_mesh; int numverts; diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index d5e8e1cdf98..d2e20b33f6c 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -613,7 +613,8 @@ static void sculpt_face_sets_init_loop(Object *ob, const int mode) } } else if (mode == SCULPT_FACE_SETS_FROM_FACE_MAPS) { - const int *face_maps = static_cast(CustomData_get_layer(&mesh->pdata, CD_FACEMAP)); + const int *face_maps = static_cast( + CustomData_get_layer(&mesh->pdata, CD_FACEMAP)); for (const int i : IndexRange(mesh->totpoly)) { ss->face_sets[i] = face_maps ? face_maps[i] : 1; } diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc index 9d7f2222d3d..136fb4bfe0e 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc +++ b/source/blender/editors/space_spreadsheet/spreadsheet_data_source_geometry.cc @@ -294,7 +294,7 @@ IndexMask GeometryDataSource::apply_selection_filter(Vector &indices) c BMesh *bm = mesh_orig->edit_mesh->bm; BM_mesh_elem_table_ensure(bm, BM_VERT); - const int *orig_indices = (int *)CustomData_get_layer(&mesh_eval->vdata, CD_ORIGINDEX); + const int *orig_indices = (const int *)CustomData_get_layer(&mesh_eval->vdata, CD_ORIGINDEX); if (orig_indices != nullptr) { /* Use CD_ORIGINDEX layer if it exists. */ VArray selection = attributes_eval.adapt_domain( diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc index dfe744a1197..fb7cef96cc5 100644 --- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc +++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc @@ -537,7 +537,7 @@ static void get_loop_normals(struct Mesh *mesh, } BKE_mesh_calc_normals_split(mesh); - const float(*lnors)[3] = static_cast(CustomData_get_layer(&mesh->ldata, CD_NORMAL)); + const float(*lnors)[3] = static_cast(CustomData_get_layer(&mesh->ldata, CD_NORMAL)); BLI_assert_msg(lnors != nullptr, "BKE_mesh_calc_normals_split() should have computed CD_NORMAL"); normals.resize(mesh->totloop); diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index 45fa0d48d80..3d08f9ac2a9 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -400,7 +400,7 @@ void USDGenericMeshWriter::assign_materials(const HierarchyContext &context, void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_mesh) { pxr::UsdTimeCode timecode = get_export_time_code(); - const float(*lnors)[3] = static_cast(CustomData_get_layer(&mesh->ldata, CD_NORMAL)); + const float(*lnors)[3] = static_cast(CustomData_get_layer(&mesh->ldata, CD_NORMAL)); const Span polys = mesh->polys(); const Span loops = mesh->loops(); diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 1d80123b5d9..fa8fe5cde00 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -397,11 +397,9 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, /* get uvco */ if (r_uv && ELEM(from, PART_FROM_FACE, PART_FROM_VOLUME) && !ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { - MFace *mface; - MTFace *mtface; - mface = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); - mtface = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MTFACE); + const MFace *mface = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); + const MTFace *mtface = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MTFACE); if (mface && mtface) { mtface += num; @@ -565,7 +563,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys } else if (part->from == PART_FROM_VERT) { if (num != DMCACHE_NOTFOUND && num < totvert) { - MFace *mface = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); + const MFace *mface = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); *r_fuv = &particle->fuv; @@ -608,7 +606,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys } else if (part->from == PART_FROM_VERT) { if (num != DMCACHE_NOTFOUND && num < totvert) { - MFace *mface = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); + const MFace *mface = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); *r_fuv = &parent->fuv; @@ -658,8 +656,8 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, zero_v2(r_uv); } else { - MFace *mfaces = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); - MFace *mface = &mfaces[num]; + const MFace *mfaces = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); + const MFace *mface = &mfaces[num]; const MTFace *mtface = (const MTFace *)CustomData_get_layer_n( &modifier->mesh_final->fdata, CD_MTFACE, uv_no); @@ -693,8 +691,8 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, zero_v3(r_mcol); } else { - MFace *mfaces = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); - MFace *mface = &mfaces[num]; + const MFace *mfaces = CustomData_get_layer(&modifier->mesh_final->fdata, CD_MFACE); + const MFace *mface = &mfaces[num]; const MCol *mc = (const MCol *)CustomData_get_layer_n( &modifier->mesh_final->fdata, CD_MCOL, vcol_no); MCol mcol; diff --git a/source/blender/render/intern/bake.cc b/source/blender/render/intern/bake.cc index e1fc33a4b9d..b9c1680f421 100644 --- a/source/blender/render/intern/bake.cc +++ b/source/blender/render/intern/bake.cc @@ -716,11 +716,12 @@ void RE_bake_pixels_populate(Mesh *me, { const float(*mloopuv)[2]; if ((uv_layer == nullptr) || (uv_layer[0] == '\0')) { - mloopuv = static_cast(CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2)); + mloopuv = static_cast(CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2)); } else { int uv_id = CustomData_get_named_layer(&me->ldata, CD_PROP_FLOAT2, uv_layer); - mloopuv = static_cast(CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, uv_id)); + mloopuv = static_cast( + CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, uv_id)); } if (mloopuv == nullptr) { From 0a21a554d5b81791dd7c619610d1855aa23fbf55 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 13 Jan 2023 15:34:01 -0600 Subject: [PATCH 0634/1522] Fix T103304: Incorrect handling of edge crease in subdivision node The crease custom data layer was added to a mutable version of the mesh, but that wasn't used in the rest of the operation. Also the layer wasn't retrieved properly with write access from the custom data API (fixed separately as part of D14140). Also clean up a bit by retrieving attributes from the mesh directly and by tweaking naming a bit. --- .../nodes/node_geo_subdivision_surface.cc | 49 ++++++++++--------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc index 40b49055949..b6e0eeea3ff 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc @@ -69,7 +69,8 @@ static void write_vertex_creases(Mesh &mesh, const VArray &crease_varray) { float *crease; if (CustomData_has_layer(&mesh.vdata, CD_CREASE)) { - crease = static_cast(CustomData_get_layer(&mesh.vdata, CD_CREASE)); + crease = static_cast( + CustomData_duplicate_referenced_layer(&mesh.vdata, CD_CREASE, mesh.totvert)); } else { crease = static_cast( @@ -78,11 +79,11 @@ static void write_vertex_creases(Mesh &mesh, const VArray &crease_varray) materialize_and_clamp_creases(crease_varray, {crease, mesh.totvert}); } -static void write_edge_creases(MeshComponent &mesh, const VArray &crease_varray) +static void write_edge_creases(Mesh &mesh, const VArray &crease_varray) { bke::SpanAttributeWriter attribute = - mesh.attributes_for_write()->lookup_or_add_for_write_only_span("crease", - ATTR_DOMAIN_EDGE); + mesh.attributes_for_write().lookup_or_add_for_write_only_span("crease", + ATTR_DOMAIN_EDGE); materialize_and_clamp_creases(crease_varray, attribute.span); attribute.finish(); } @@ -115,23 +116,22 @@ static void node_geo_exec(GeoNodeExecParams params) } geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (!geometry_set.has_mesh()) { + const Mesh *mesh = geometry_set.get_mesh_for_read(); + if (!mesh) { + return; + } + if (mesh->totvert == 0 || mesh->totedge == 0) { return; } - const Mesh &mesh = *geometry_set.get_mesh_for_read(); - if (mesh.totvert == 0 || mesh.totedge == 0) { - return; - } - - bke::MeshFieldContext point_context{mesh, ATTR_DOMAIN_POINT}; - FieldEvaluator point_evaluator(point_context, mesh.totvert); + bke::MeshFieldContext point_context{*mesh, ATTR_DOMAIN_POINT}; + FieldEvaluator point_evaluator(point_context, mesh->totvert); point_evaluator.add(vertex_crease_field); point_evaluator.evaluate(); const VArray vertex_creases = point_evaluator.get_evaluated(0); - bke::MeshFieldContext edge_context{mesh, ATTR_DOMAIN_EDGE}; - FieldEvaluator edge_evaluator(edge_context, mesh.totedge); + bke::MeshFieldContext edge_context{*mesh, ATTR_DOMAIN_EDGE}; + FieldEvaluator edge_evaluator(edge_context, mesh->totedge); edge_evaluator.add(edge_crease_field); edge_evaluator.evaluate(); const VArray edge_creases = edge_evaluator.get_evaluated(0); @@ -139,8 +139,13 @@ static void node_geo_exec(GeoNodeExecParams params) const bool use_creases = varray_is_nonzero(vertex_creases) || varray_is_nonzero(edge_creases); if (use_creases) { - write_vertex_creases(*geometry_set.get_mesh_for_write(), vertex_creases); - write_edge_creases(geometry_set.get_component_for_write(), edge_creases); + /* Due to the "BKE_subdiv" API, the crease layers must be on the input mesh. But in this node + * they are provided as separate inputs, not as custom data layers. When needed, retrieve the + * mesh with write access and store the new crease values there. */ + Mesh &mesh_for_write = *geometry_set.get_mesh_for_write(); + write_vertex_creases(mesh_for_write, vertex_creases); + write_edge_creases(mesh_for_write, edge_creases); + mesh = &mesh_for_write; } /* Initialize mesh settings. */ @@ -161,25 +166,23 @@ static void node_geo_exec(GeoNodeExecParams params) uv_smooth); /* Apply subdivision to mesh. */ - Subdiv *subdiv = BKE_subdiv_update_from_mesh(nullptr, &subdiv_settings, &mesh); + Subdiv *subdiv = BKE_subdiv_update_from_mesh(nullptr, &subdiv_settings, mesh); /* In case of bad topology, skip to input mesh. */ if (subdiv == nullptr) { return; } - Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, &mesh); - + Mesh *result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh); + BKE_subdiv_free(subdiv); if (use_creases) { /* Remove the layer in case it was created by the node from the field input. The fact * that this node uses #CD_CREASE to input creases to the subdivision code is meant to be * an implementation detail ideally. */ - CustomData_free_layers(&mesh_out->edata, CD_CREASE, mesh_out->totedge); + CustomData_free_layers(&result->edata, CD_CREASE, result->totedge); } - geometry_set.replace_mesh(mesh_out); - - BKE_subdiv_free(subdiv); + geometry_set.replace_mesh(result); }); #endif params.set_output("Mesh", std::move(geometry_set)); From b55b671955f29f4856d182067c534c06fa1497de Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Sat, 14 Jan 2023 10:38:53 +1300 Subject: [PATCH 0635/1522] Cleanup: format --- source/blender/io/alembic/exporter/abc_writer_mesh.cc | 3 ++- source/blender/io/usd/intern/usd_writer_mesh.cc | 3 ++- .../blender/nodes/geometry/nodes/node_geo_evaluate_at_index.cc | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/io/alembic/exporter/abc_writer_mesh.cc b/source/blender/io/alembic/exporter/abc_writer_mesh.cc index fb7cef96cc5..77d42d905c7 100644 --- a/source/blender/io/alembic/exporter/abc_writer_mesh.cc +++ b/source/blender/io/alembic/exporter/abc_writer_mesh.cc @@ -537,7 +537,8 @@ static void get_loop_normals(struct Mesh *mesh, } BKE_mesh_calc_normals_split(mesh); - const float(*lnors)[3] = static_cast(CustomData_get_layer(&mesh->ldata, CD_NORMAL)); + const float(*lnors)[3] = static_cast( + CustomData_get_layer(&mesh->ldata, CD_NORMAL)); BLI_assert_msg(lnors != nullptr, "BKE_mesh_calc_normals_split() should have computed CD_NORMAL"); normals.resize(mesh->totloop); diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index 3d08f9ac2a9..9551fea75fb 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -400,7 +400,8 @@ void USDGenericMeshWriter::assign_materials(const HierarchyContext &context, void USDGenericMeshWriter::write_normals(const Mesh *mesh, pxr::UsdGeomMesh usd_mesh) { pxr::UsdTimeCode timecode = get_export_time_code(); - const float(*lnors)[3] = static_cast(CustomData_get_layer(&mesh->ldata, CD_NORMAL)); + const float(*lnors)[3] = static_cast( + CustomData_get_layer(&mesh->ldata, CD_NORMAL)); const Span polys = mesh->polys(); const Span loops = mesh->loops(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_evaluate_at_index.cc b/source/blender/nodes/geometry/nodes/node_geo_evaluate_at_index.cc index 75b9d0e49cd..65f88f23aff 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_evaluate_at_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_evaluate_at_index.cc @@ -190,7 +190,8 @@ void register_node_type_geo_evaluate_at_index() static bNodeType ntype; - geo_node_type_base(&ntype, GEO_NODE_EVALUATE_AT_INDEX, "Evaluate at Index", NODE_CLASS_CONVERTER); + geo_node_type_base( + &ntype, GEO_NODE_EVALUATE_AT_INDEX, "Evaluate at Index", NODE_CLASS_CONVERTER); ntype.geometry_node_execute = file_ns::node_geo_exec; ntype.declare = file_ns::node_declare; ntype.draw_buttons = file_ns::node_layout; From e35053d369067cdc2d8308c241aa599fd22d8115 Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Fri, 13 Jan 2023 15:44:29 -0600 Subject: [PATCH 0636/1522] Fix T103850: Convex hull node crash with empty geometry components Avoid using components that can contain null pointer. Getting attibute should avoid trying to do it for a null mesh. This fix bypasses working with components. Differential Revision: https://developer.blender.org/D16997 --- .../geometry/nodes/node_geo_convex_hull.cc | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc index 84cc2b49141..3ede378e95a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc @@ -143,10 +143,10 @@ static Mesh *compute_hull(const GeometrySet &geometry_set) Span positions_span; - if (const MeshComponent *component = geometry_set.get_component_for_read()) { + if (const Mesh *mesh = geometry_set.get_mesh_for_read()) { count++; - if (const VArray positions = component->attributes()->lookup( - "position", ATTR_DOMAIN_POINT)) { + if (const VArray positions = mesh->attributes().lookup("position", + ATTR_DOMAIN_POINT)) { if (positions.is_span()) { span_count++; positions_span = positions.get_internal_span(); @@ -155,11 +155,10 @@ static Mesh *compute_hull(const GeometrySet &geometry_set) } } - if (const PointCloudComponent *component = - geometry_set.get_component_for_read()) { + if (const PointCloud *points = geometry_set.get_pointcloud_for_read()) { count++; - if (const VArray positions = component->attributes()->lookup( - "position", ATTR_DOMAIN_POINT)) { + if (const VArray positions = points->attributes().lookup("position", + ATTR_DOMAIN_POINT)) { if (positions.is_span()) { span_count++; positions_span = positions.get_internal_span(); @@ -189,18 +188,17 @@ static Mesh *compute_hull(const GeometrySet &geometry_set) Array positions(total_num); int offset = 0; - if (const MeshComponent *component = geometry_set.get_component_for_read()) { - if (const VArray varray = component->attributes()->lookup("position", - ATTR_DOMAIN_POINT)) { + if (const Mesh *mesh = geometry_set.get_mesh_for_read()) { + if (const VArray varray = mesh->attributes().lookup("position", + ATTR_DOMAIN_POINT)) { varray.materialize(positions.as_mutable_span().slice(offset, varray.size())); offset += varray.size(); } } - if (const PointCloudComponent *component = - geometry_set.get_component_for_read()) { - if (const VArray varray = component->attributes()->lookup("position", - ATTR_DOMAIN_POINT)) { + if (const PointCloud *points = geometry_set.get_pointcloud_for_read()) { + if (const VArray varray = points->attributes().lookup("position", + ATTR_DOMAIN_POINT)) { varray.materialize(positions.as_mutable_span().slice(offset, varray.size())); offset += varray.size(); } From 326e1eeb569f0281d9e0169da09fca402cabe2d0 Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Sat, 14 Jan 2023 11:21:31 +1300 Subject: [PATCH 0637/1522] UV: cleanup Cleanup ahead of D16992 Changes in `seam_connected_recursive`: - Remove redundant `anchor` parameter. - Improve const correctness No functional changes. --- source/blender/editors/mesh/editmesh_utils.c | 21 ++++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 3f1981b1e75..99aa256b3d0 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -899,18 +899,17 @@ static bool loop_uv_match(BMLoop *loop, compare_v2v2(luv_b, luv_d, STD_UV_CONNECT_LIMIT); } -/* Given `anchor` and `edge`, return true if there are edges that fan between them that are +/* Given `luv_anchor` and `needle`, return true if there are edges that fan between them that are * seam-free. */ -static bool seam_connected_recursive(BMVert *anchor, - BMEdge *edge, - float luv_anchor[2], - float luv_fan[2], +static bool seam_connected_recursive(BMEdge *edge, + const float luv_anchor[2], + const float luv_fan[2], BMLoop *needle, GSet *visited, int cd_loop_uv_offset) { + BMVert *anchor = needle->v; BLI_assert(edge->v1 == anchor || edge->v2 == anchor); - BLI_assert(needle->v == anchor || needle->next->v == anchor); if (BM_elem_flag_test(edge, BM_ELEM_SEAM)) { return false; /* Edge is a seam, don't traverse. */ @@ -934,7 +933,7 @@ static bool seam_connected_recursive(BMVert *anchor, float *luv_far = BM_ELEM_CD_GET_FLOAT_P(loop->prev, cd_loop_uv_offset); if (seam_connected_recursive( - anchor, loop->prev->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) { + loop->prev->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) { return true; } } @@ -950,7 +949,7 @@ static bool seam_connected_recursive(BMVert *anchor, float *luv_far = BM_ELEM_CD_GET_FLOAT_P(loop->next->next, cd_loop_uv_offset); if (seam_connected_recursive( - anchor, loop->next->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) { + loop->next->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) { return true; } } @@ -971,10 +970,10 @@ static bool seam_connected(BMLoop *loop_a, BMLoop *loop_b, GSet *visited, int cd BLI_gset_clear(visited, NULL); - float *luv_anchor = BM_ELEM_CD_GET_FLOAT_P(loop_a, cd_loop_uv_offset); - float *luv_fan = BM_ELEM_CD_GET_FLOAT_P(loop_a->next, cd_loop_uv_offset); + const float *luv_anchor = BM_ELEM_CD_GET_FLOAT_P(loop_a, cd_loop_uv_offset); + const float *luv_fan = BM_ELEM_CD_GET_FLOAT_P(loop_a->next, cd_loop_uv_offset); const bool result = seam_connected_recursive( - loop_a->v, loop_a->e, luv_anchor, luv_fan, loop_b, visited, cd_loop_uv_offset); + loop_a->e, luv_anchor, luv_fan, loop_b, visited, cd_loop_uv_offset); return result; } From 4160da187c9ed003354c08d3be2a4cbd504cd973 Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Sat, 14 Jan 2023 10:46:19 +1300 Subject: [PATCH 0638/1522] Fix T103670: correct seam calculation when finding unique uvs Fixes bugs where UV islands with `mark seam` would tear at boundaries. Modify seam_connected to search both it's edges instead of only one, as this could fail if the edge was a seam or did not fan to the other loop. Also fixes bug in `seam_connected_recursive`: - `loop->prev == needle` changed to `loop == needle` Maniphest Tasks: T103787 Reviewed By: Campbell Barton Differential Revision: https://developer.blender.org/D16992 Test File: F14145477, F14137755, T79304 --- source/blender/editors/mesh/editmesh_utils.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 99aa256b3d0..21fb223e1de 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -927,7 +927,7 @@ static bool seam_connected_recursive(BMEdge *edge, continue; /* `loop` is disjoint in UV space. */ } - if (loop->prev == needle) { + if (loop == needle) { return true; /* Success. */ } @@ -971,9 +971,17 @@ static bool seam_connected(BMLoop *loop_a, BMLoop *loop_b, GSet *visited, int cd BLI_gset_clear(visited, NULL); const float *luv_anchor = BM_ELEM_CD_GET_FLOAT_P(loop_a, cd_loop_uv_offset); - const float *luv_fan = BM_ELEM_CD_GET_FLOAT_P(loop_a->next, cd_loop_uv_offset); - const bool result = seam_connected_recursive( - loop_a->e, luv_anchor, luv_fan, loop_b, visited, cd_loop_uv_offset); + const float *luv_next_fan = BM_ELEM_CD_GET_FLOAT_P(loop_a->next, cd_loop_uv_offset); + bool result = seam_connected_recursive( + loop_a->e, luv_anchor, luv_next_fan, loop_b, visited, cd_loop_uv_offset); + if (!result) { + /* Search around `loop_a` in the opposite direction, as one of the edges may be delimited by + * a boundary, seam or disjoint UV, or itself be one of these. See: T103670, T103787. */ + float *luv_prev_fan = BM_ELEM_CD_GET_FLOAT_P(loop_a->prev, cd_loop_uv_offset); + result = seam_connected_recursive( + loop_a->prev->e, luv_anchor, luv_prev_fan, loop_b, visited, cd_loop_uv_offset); + } + return result; } From 3a3d9488a1633bfefabbab422dd22283bca02626 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 13 Jan 2023 17:21:20 -0600 Subject: [PATCH 0639/1522] Refactor: Const correct Custom Data API, prepare for CoW Currently you can retrieve a mutable array from a const CustomData. That makes code unsafe since the compiler can't check for correctness itself. Fix that by introducing a separate function to retrieve mutable arrays from CustomData. The new functions have the `_for_write` suffix that make the code's intention clearer. Because it makes retrieving write access an explicit step, this change also makes proper copy-on-write possible for attributes. Notes: - The previous "duplicate referenced layer" functions are redundant with retrieving layers with write access - The custom data functions that give a specific index only have `for_write` to simplify the API Differential Revision: https://developer.blender.org/D14140 --- source/blender/blenkernel/BKE_customdata.h | 54 +++++++----- source/blender/blenkernel/BKE_key.h | 2 +- source/blender/blenkernel/BKE_mesh.h | 15 ++-- .../blender/blenkernel/intern/DerivedMesh.cc | 42 +++++---- .../blenkernel/intern/attribute_access.cc | 6 +- .../blender/blenkernel/intern/cdderivedmesh.c | 9 +- .../blenkernel/intern/curves_geometry.cc | 3 +- .../blender/blenkernel/intern/customdata.cc | 80 +++++++---------- .../blenkernel/intern/data_transfer.cc | 88 ++++--------------- source/blender/blenkernel/intern/deform.c | 4 +- .../blender/blenkernel/intern/dynamicpaint.c | 11 +-- source/blender/blenkernel/intern/key.cc | 6 +- source/blender/blenkernel/intern/mesh.cc | 8 +- .../blenkernel/intern/mesh_boolean_convert.cc | 9 +- .../blenkernel/intern/mesh_evaluate.cc | 6 +- .../blenkernel/intern/mesh_legacy_convert.cc | 34 ++++--- .../intern/mesh_merge_customdata.cc | 3 +- .../blender/blenkernel/intern/mesh_mirror.cc | 7 +- .../blender/blenkernel/intern/mesh_normals.cc | 3 +- .../blender/blenkernel/intern/mesh_remap.cc | 5 +- .../blenkernel/intern/mesh_validate.cc | 70 ++++++++------- .../blender/blenkernel/intern/mesh_wrapper.cc | 2 +- source/blender/blenkernel/intern/multires.cc | 35 +++++--- .../intern/multires_reshape_subdivide.c | 2 +- .../blenkernel/intern/multires_reshape_util.c | 11 ++- .../blenkernel/intern/multires_unsubdivide.c | 6 +- .../blenkernel/intern/object_facemap.c | 2 +- source/blender/blenkernel/intern/paint.cc | 18 ++-- source/blender/blenkernel/intern/particle.cc | 31 ++++--- .../blenkernel/intern/particle_distribute.c | 17 ++-- source/blender/blenkernel/intern/pbvh.c | 28 +++--- .../blender/blenkernel/intern/subdiv_mesh.cc | 17 ++-- .../blender/blenkernel/intern/subsurf_ccg.c | 6 +- .../blenloader/intern/versioning_250.c | 2 +- .../blenloader/intern/versioning_290.c | 31 +++---- .../blenloader/intern/versioning_defaults.cc | 2 +- .../draw_cache_extract_mesh_render_data.cc | 2 +- .../editors/mesh/editmesh_mask_extract.c | 6 +- source/blender/editors/mesh/mesh_data.cc | 9 +- source/blender/editors/mesh/meshtools.cc | 20 +++-- .../editors/object/object_facemap_ops.c | 6 +- .../blender/editors/object/object_modifier.cc | 2 +- .../blender/editors/sculpt_paint/paint_hide.c | 3 +- .../blender/editors/sculpt_paint/paint_mask.c | 3 +- .../editors/sculpt_paint/sculpt_dyntopo.c | 3 +- .../editors/sculpt_paint/sculpt_face_set.cc | 4 +- .../blender_interface/BlenderFileLoader.cpp | 8 +- .../geometry/intern/mesh_split_edges.cc | 6 +- .../gpu/intern/gpu_shader_builder_stubs.cc | 12 --- .../io/alembic/exporter/abc_writer_hair.cc | 18 ++-- .../io/alembic/intern/abc_customdata.cc | 2 +- .../io/alembic/intern/abc_reader_mesh.cc | 3 +- source/blender/io/collada/MeshImporter.cpp | 9 +- .../blender/io/usd/intern/usd_reader_mesh.cc | 2 +- source/blender/makesrna/intern/rna_curves.c | 13 ++- source/blender/makesrna/intern/rna_mesh.c | 68 +++++++------- source/blender/makesrna/intern/rna_mesh_api.c | 2 +- .../blender/makesrna/intern/rna_pointcloud.c | 6 +- source/blender/modifiers/intern/MOD_array.cc | 14 +-- source/blender/modifiers/intern/MOD_cloth.c | 3 +- .../blender/modifiers/intern/MOD_displace.cc | 3 +- source/blender/modifiers/intern/MOD_explode.c | 40 +++++---- .../blender/modifiers/intern/MOD_multires.cc | 3 +- .../modifiers/intern/MOD_normal_edit.cc | 28 ++++-- .../modifiers/intern/MOD_particleinstance.c | 8 +- source/blender/modifiers/intern/MOD_screw.cc | 7 +- source/blender/modifiers/intern/MOD_skin.c | 5 +- .../modifiers/intern/MOD_solidify_extrude.c | 2 +- .../intern/MOD_solidify_nonmanifold.c | 9 +- .../blender/modifiers/intern/MOD_subsurf.cc | 3 +- .../modifiers/intern/MOD_triangulate.cc | 3 +- .../blender/modifiers/intern/MOD_uvproject.cc | 5 +- source/blender/modifiers/intern/MOD_uvwarp.cc | 5 +- .../modifiers/intern/MOD_weighted_normal.cc | 2 +- .../geometry/nodes/node_geo_extrude_mesh.cc | 3 +- .../nodes/node_geo_subdivision_surface.cc | 2 +- 76 files changed, 524 insertions(+), 503 deletions(-) diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index b97ac9cc9b9..e7161722925 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -283,21 +283,6 @@ bool CustomData_has_layer(const struct CustomData *data, int type); int CustomData_number_of_layers(const struct CustomData *data, int type); int CustomData_number_of_layers_typemask(const struct CustomData *data, eCustomDataMask mask); -/** - * Duplicate data of a layer with flag NOFREE, and remove that flag. - * \return the layer data. - */ -void *CustomData_duplicate_referenced_layer(struct CustomData *data, int type, int totelem); -void *CustomData_duplicate_referenced_layer_n(struct CustomData *data, - int type, - int n, - int totelem); -void *CustomData_duplicate_referenced_layer_named(struct CustomData *data, - int type, - const char *name, - int totelem); -bool CustomData_is_referenced_layer(struct CustomData *data, int type); - /** * Duplicate all the layers with flag NOFREE, and remove the flag from duplicated layers. */ @@ -409,11 +394,15 @@ void CustomData_swap_corners(struct CustomData *data, int index, const int *corn void CustomData_swap(struct CustomData *data, int index_a, int index_b); /** - * Gets a pointer to the data element at index from the first layer of type. - * \return NULL if there is no layer of type. + * Retrieve a pointer to an element of the active layer of the given \a type, chosen by the + * \a index, if it exists. */ -void *CustomData_get(const struct CustomData *data, int index, int type); -void *CustomData_get_n(const struct CustomData *data, int type, int index, int n); +void *CustomData_get_for_write(struct CustomData *data, int index, int type, int totelem); +/** + * Retrieve a pointer to an element of the \a nth layer of the given \a type, chosen by the + * \a index, if it exists. + */ +void *CustomData_get_n_for_write(struct CustomData *data, int type, int index, int n, int totelem); /* BMesh Custom Data Functions. * Should replace edit-mesh ones with these as well, due to more efficient memory alloc. */ @@ -431,12 +420,29 @@ bool CustomData_set_layer_name(struct CustomData *data, int type, int n, const c const char *CustomData_get_layer_name(const struct CustomData *data, int type, int n); /** - * Gets a pointer to the active or first layer of type. - * \return NULL if there is no layer of type. + * Retrieve the data array of the active layer of the given \a type, if it exists. Return null + * otherwise. */ -void *CustomData_get_layer(const struct CustomData *data, int type); -void *CustomData_get_layer_n(const struct CustomData *data, int type, int n); -void *CustomData_get_layer_named(const struct CustomData *data, int type, const char *name); +const void *CustomData_get_layer(const struct CustomData *data, int type); +void *CustomData_get_layer_for_write(struct CustomData *data, int type, int totelem); + +/** + * Retrieve the data array of the \a nth layer of the given \a type, if it exists. Return null + * otherwise. + */ +const void *CustomData_get_layer_n(const struct CustomData *data, int type, int n); +void *CustomData_get_layer_n_for_write(struct CustomData *data, int type, int n, int totelem); + +/** + * Retrieve the data array of the layer with the given \a name and \a type, if it exists. Return + * null otherwise. + */ +const void *CustomData_get_layer_named(const struct CustomData *data, int type, const char *name); +void *CustomData_get_layer_named_for_write(CustomData *data, + int type, + const char *name, + int totelem); + int CustomData_get_offset(const struct CustomData *data, int type); int CustomData_get_offset_named(const CustomData *data, int type, const char *name); int CustomData_get_n_offset(const struct CustomData *data, int type, int n); diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index d89ef744449..d868969f9b9 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -145,7 +145,7 @@ void BKE_keyblock_convert_to_mesh(const struct KeyBlock *kb, * \param r_loop_normals: if non-NULL, an array of vectors, same length as number of loops. */ void BKE_keyblock_mesh_calc_normals(const struct KeyBlock *kb, - const struct Mesh *mesh, + struct Mesh *mesh, float (*r_vert_normals)[3], float (*r_poly_normals)[3], float (*r_loop_normals)[3]); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 4d81507ef1c..ad964184263 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -759,7 +759,8 @@ void BKE_mesh_polygon_flip_ex(const struct MPoly *mpoly, bool use_loop_mdisp_flip); void BKE_mesh_polygon_flip(const struct MPoly *mpoly, struct MLoop *mloop, - struct CustomData *ldata); + struct CustomData *ldata, + int totloop); /** * Flip (invert winding of) all polygons (used to inverse their normals). * @@ -983,7 +984,7 @@ BLI_INLINE const int *BKE_mesh_material_indices(const Mesh *mesh) */ BLI_INLINE int *BKE_mesh_material_indices_for_write(Mesh *mesh) { - int *indices = (int *)CustomData_duplicate_referenced_layer_named( + int *indices = (int *)CustomData_get_layer_named_for_write( &mesh->pdata, CD_PROP_INT32, "material_index", mesh->totpoly); if (indices) { return indices; @@ -998,7 +999,7 @@ BLI_INLINE const float (*BKE_mesh_vert_positions(const Mesh *mesh))[3] } BLI_INLINE float (*BKE_mesh_vert_positions_for_write(Mesh *mesh))[3] { - return (float(*)[3])CustomData_duplicate_referenced_layer_named( + return (float(*)[3])CustomData_get_layer_named_for_write( &mesh->vdata, CD_PROP_FLOAT3, "position", mesh->totvert); } @@ -1008,7 +1009,7 @@ BLI_INLINE const MEdge *BKE_mesh_edges(const Mesh *mesh) } BLI_INLINE MEdge *BKE_mesh_edges_for_write(Mesh *mesh) { - return (MEdge *)CustomData_duplicate_referenced_layer(&mesh->edata, CD_MEDGE, mesh->totedge); + return (MEdge *)CustomData_get_layer_for_write(&mesh->edata, CD_MEDGE, mesh->totedge); } BLI_INLINE const MPoly *BKE_mesh_polys(const Mesh *mesh) @@ -1017,7 +1018,7 @@ BLI_INLINE const MPoly *BKE_mesh_polys(const Mesh *mesh) } BLI_INLINE MPoly *BKE_mesh_polys_for_write(Mesh *mesh) { - return (MPoly *)CustomData_duplicate_referenced_layer(&mesh->pdata, CD_MPOLY, mesh->totpoly); + return (MPoly *)CustomData_get_layer_for_write(&mesh->pdata, CD_MPOLY, mesh->totpoly); } BLI_INLINE const MLoop *BKE_mesh_loops(const Mesh *mesh) @@ -1026,7 +1027,7 @@ BLI_INLINE const MLoop *BKE_mesh_loops(const Mesh *mesh) } BLI_INLINE MLoop *BKE_mesh_loops_for_write(Mesh *mesh) { - return (MLoop *)CustomData_duplicate_referenced_layer(&mesh->ldata, CD_MLOOP, mesh->totloop); + return (MLoop *)CustomData_get_layer_for_write(&mesh->ldata, CD_MLOOP, mesh->totloop); } BLI_INLINE const MDeformVert *BKE_mesh_deform_verts(const Mesh *mesh) @@ -1035,7 +1036,7 @@ BLI_INLINE const MDeformVert *BKE_mesh_deform_verts(const Mesh *mesh) } BLI_INLINE MDeformVert *BKE_mesh_deform_verts_for_write(Mesh *mesh) { - MDeformVert *dvert = (MDeformVert *)CustomData_duplicate_referenced_layer( + MDeformVert *dvert = (MDeformVert *)CustomData_get_layer_for_write( &mesh->vdata, CD_MDEFORMVERT, mesh->totvert); if (dvert) { return dvert; diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 709f52060fc..39a68b72d2a 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -94,8 +94,8 @@ static void editbmesh_calc_modifier_final_normals_or_defer( static float *dm_getVertArray(DerivedMesh *dm) { - float(*positions)[3] = (float(*)[3])CustomData_get_layer_named( - &dm->vertData, CD_PROP_FLOAT3, "position"); + float(*positions)[3] = (float(*)[3])CustomData_get_layer_named_for_write( + &dm->vertData, CD_PROP_FLOAT3, "position", dm->getNumVerts(dm)); if (!positions) { positions = (float(*)[3])CustomData_add_layer_named( @@ -109,7 +109,8 @@ static float *dm_getVertArray(DerivedMesh *dm) static MEdge *dm_getEdgeArray(DerivedMesh *dm) { - MEdge *medge = (MEdge *)CustomData_get_layer(&dm->edgeData, CD_MEDGE); + MEdge *medge = (MEdge *)CustomData_get_layer_for_write( + &dm->edgeData, CD_MEDGE, dm->getNumEdges(dm)); if (!medge) { medge = (MEdge *)CustomData_add_layer( @@ -123,7 +124,8 @@ static MEdge *dm_getEdgeArray(DerivedMesh *dm) static MLoop *dm_getLoopArray(DerivedMesh *dm) { - MLoop *mloop = (MLoop *)CustomData_get_layer(&dm->loopData, CD_MLOOP); + MLoop *mloop = (MLoop *)CustomData_get_layer_for_write( + &dm->loopData, CD_MLOOP, dm->getNumLoops(dm)); if (!mloop) { mloop = (MLoop *)CustomData_add_layer( @@ -137,7 +139,8 @@ static MLoop *dm_getLoopArray(DerivedMesh *dm) static MPoly *dm_getPolyArray(DerivedMesh *dm) { - MPoly *mpoly = (MPoly *)CustomData_get_layer(&dm->polyData, CD_MPOLY); + MPoly *mpoly = (MPoly *)CustomData_get_layer_for_write( + &dm->polyData, CD_MPOLY, dm->getNumPolys(dm)); if (!mpoly) { mpoly = (MPoly *)CustomData_add_layer( @@ -351,7 +354,7 @@ static void mesh_set_only_copy(Mesh *mesh, const CustomData_MeshMasks *mask) void *DM_get_vert_data_layer(DerivedMesh *dm, int type) { - return CustomData_get_layer(&dm->vertData, type); + return CustomData_get_layer_for_write(&dm->vertData, type, dm->getNumVerts(dm)); } void *DM_get_edge_data_layer(DerivedMesh *dm, int type) @@ -360,17 +363,17 @@ void *DM_get_edge_data_layer(DerivedMesh *dm, int type) return dm->getEdgeArray(dm); } - return CustomData_get_layer(&dm->edgeData, type); + return CustomData_get_layer_for_write(&dm->edgeData, type, dm->getNumEdges(dm)); } void *DM_get_poly_data_layer(DerivedMesh *dm, int type) { - return CustomData_get_layer(&dm->polyData, type); + return CustomData_get_layer_for_write(&dm->polyData, type, dm->getNumPolys(dm)); } void *DM_get_loop_data_layer(DerivedMesh *dm, int type) { - return CustomData_get_layer(&dm->loopData, type); + return CustomData_get_layer_for_write(&dm->loopData, type, dm->getNumLoops(dm)); } void DM_copy_vert_data( @@ -499,10 +502,10 @@ static void add_orco_mesh(Object *ob, BMEditMesh *em, Mesh *mesh, Mesh *mesh_orc BKE_mesh_orco_verts_transform((Mesh *)ob->data, orco, totvert, 0); } - if (!(layerorco = (float(*)[3])CustomData_get_layer(&mesh->vdata, layer))) { - CustomData_add_layer(&mesh->vdata, layer, CD_SET_DEFAULT, nullptr, mesh->totvert); - - layerorco = (float(*)[3])CustomData_get_layer(&mesh->vdata, layer); + layerorco = (float(*)[3])CustomData_get_layer_for_write(&mesh->vdata, layer, mesh->totvert); + if (!layerorco) { + layerorco = (float(*)[3])CustomData_add_layer( + &mesh->vdata, layer, CD_SET_DEFAULT, nullptr, mesh->totvert); } memcpy(layerorco, orco, sizeof(float[3]) * totvert); @@ -924,13 +927,16 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph, /* Not worth parallelizing this, * gives less than 0.1% overall speedup in best of best cases... */ - range_vn_i((int *)CustomData_get_layer(&mesh_final->vdata, CD_ORIGINDEX), + range_vn_i((int *)CustomData_get_layer_for_write( + &mesh_final->vdata, CD_ORIGINDEX, mesh_final->totvert), mesh_final->totvert, 0); - range_vn_i((int *)CustomData_get_layer(&mesh_final->edata, CD_ORIGINDEX), + range_vn_i((int *)CustomData_get_layer_for_write( + &mesh_final->edata, CD_ORIGINDEX, mesh_final->totedge), mesh_final->totedge, 0); - range_vn_i((int *)CustomData_get_layer(&mesh_final->pdata, CD_ORIGINDEX), + range_vn_i((int *)CustomData_get_layer_for_write( + &mesh_final->pdata, CD_ORIGINDEX, mesh_final->totpoly), mesh_final->totpoly, 0); } @@ -1932,8 +1938,8 @@ static void mesh_init_origspace(Mesh *mesh) { const float default_osf[4][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}}; - OrigSpaceLoop *lof_array = (OrigSpaceLoop *)CustomData_get_layer(&mesh->ldata, - CD_ORIGSPACE_MLOOP); + OrigSpaceLoop *lof_array = (OrigSpaceLoop *)CustomData_get_layer_for_write( + &mesh->ldata, CD_ORIGSPACE_MLOOP, mesh->totloop); const int numpoly = mesh->totpoly; // const int numloop = mesh->totloop; const Span positions = mesh->vert_positions(); diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index d95c80cf1eb..92bb7247673 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -340,11 +340,11 @@ GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner) void *data = nullptr; if (stored_as_named_attribute_) { - data = CustomData_duplicate_referenced_layer_named( + data = CustomData_get_layer_named_for_write( custom_data, stored_type_, name_.c_str(), element_num); } else { - data = CustomData_duplicate_referenced_layer(custom_data, stored_type_, element_num); + data = CustomData_get_layer_for_write(custom_data, stored_type_, element_num); } if (data == nullptr) { return {}; @@ -461,7 +461,7 @@ GAttributeWriter CustomDataAttributeProvider::try_get_for_write( if (!custom_data_layer_matches_attribute_id(layer, attribute_id)) { continue; } - CustomData_duplicate_referenced_layer_named(custom_data, layer.type, layer.name, element_num); + CustomData_get_layer_named_for_write(custom_data, layer.type, layer.name, element_num); const CPPType *type = custom_data_type_to_cpp_type((eCustomDataType)layer.type); if (type == nullptr) { diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 7370ee6970a..a5d179fb2cb 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -221,13 +221,14 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh, CustomData_merge(&mesh->ldata, &dm->loopData, cddata_masks.lmask, alloctype, mesh->totloop); CustomData_merge(&mesh->pdata, &dm->polyData, cddata_masks.pmask, alloctype, mesh->totpoly); - cddm->vert_positions = CustomData_get_layer_named(&dm->vertData, CD_PROP_FLOAT3, "position"); + cddm->vert_positions = CustomData_get_layer_named_for_write( + &dm->vertData, CD_PROP_FLOAT3, "position", mesh->totvert); /* Though this may be an unnecessary calculation, simply retrieving the layer may return nothing * or dirty normals. */ cddm->vert_normals = BKE_mesh_vertex_normals_ensure(mesh); - cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); - cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP); - cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); + cddm->medge = CustomData_get_layer_for_write(&dm->edgeData, CD_MEDGE, mesh->totedge); + cddm->mloop = CustomData_get_layer_for_write(&dm->loopData, CD_MLOOP, mesh->totloop); + cddm->mpoly = CustomData_get_layer_for_write(&dm->polyData, CD_MPOLY, mesh->totpoly); #if 0 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); #else diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 835b6728e99..65117ab00bb 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -216,8 +216,7 @@ static MutableSpan get_mutable_attribute(CurvesGeometry &curves, const eCustomDataType type = cpp_type_to_custom_data_type(CPPType::get()); CustomData &custom_data = domain_custom_data(curves, domain); - T *data = (T *)CustomData_duplicate_referenced_layer_named( - &custom_data, type, name.c_str(), num); + T *data = (T *)CustomData_get_layer_named_for_write(&custom_data, type, name.c_str(), num); if (data != nullptr) { return {data, num}; } diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index 1d970d35148..a8b8782062e 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -3052,35 +3052,6 @@ static void *customData_duplicate_referenced_layer_index(CustomData *data, return layer->data; } -void *CustomData_duplicate_referenced_layer(CustomData *data, const int type, const int totelem) -{ - int layer_index = CustomData_get_active_layer_index(data, type); - - return customData_duplicate_referenced_layer_index(data, layer_index, totelem); -} - -void *CustomData_duplicate_referenced_layer_n(CustomData *data, - const int type, - const int n, - const int totelem) -{ - /* get the layer index of the desired layer */ - int layer_index = CustomData_get_layer_index_n(data, type, n); - - return customData_duplicate_referenced_layer_index(data, layer_index, totelem); -} - -void *CustomData_duplicate_referenced_layer_named(CustomData *data, - const int type, - const char *name, - const int totelem) -{ - /* get the layer index of the desired layer */ - int layer_index = CustomData_get_named_layer_index(data, type, name); - - return customData_duplicate_referenced_layer_index(data, layer_index, totelem); -} - void CustomData_duplicate_referenced_layers(CustomData *data, const int totelem) { for (int i = 0; i < data->totlayer; i++) { @@ -3089,18 +3060,6 @@ void CustomData_duplicate_referenced_layers(CustomData *data, const int totelem) } } -bool CustomData_is_referenced_layer(CustomData *data, const int type) -{ - int layer_index = CustomData_get_active_layer_index(data, type); - if (layer_index == -1) { - return false; - } - - CustomDataLayer *layer = &data->layers[layer_index]; - - return (layer->flag & CD_FLAG_NOFREE) != 0; -} - void CustomData_free_temporary(CustomData *data, const int totelem) { int i, j; @@ -3415,20 +3374,21 @@ void CustomData_swap(CustomData *data, const int index_a, const int index_b) } } -void *CustomData_get(const CustomData *data, const int index, const int type) +void *CustomData_get_for_write(CustomData *data, const int index, const int type, int totelem) { BLI_assert(index >= 0); - void *layer_data = CustomData_get_layer(data, type); + void *layer_data = CustomData_get_layer_for_write(data, type, totelem); if (!layer_data) { return nullptr; } return POINTER_OFFSET(layer_data, size_t(index) * layerType_getInfo(type)->size); } -void *CustomData_get_n(const CustomData *data, const int type, const int index, const int n) +void *CustomData_get_n_for_write( + CustomData *data, const int type, const int index, const int n, int totelem) { BLI_assert(index >= 0); - void *layer_data = CustomData_get_layer_n(data, type, n); + void *layer_data = CustomData_get_layer_n_for_write(data, type, n, totelem); if (!layer_data) { return nullptr; } @@ -3436,7 +3396,7 @@ void *CustomData_get_n(const CustomData *data, const int type, const int index, return POINTER_OFFSET(layer_data, size_t(index) * layerType_getInfo(type)->size); } -void *CustomData_get_layer(const CustomData *data, const int type) +const void *CustomData_get_layer(const CustomData *data, const int type) { int layer_index = CustomData_get_active_layer_index(data, type); if (layer_index == -1) { @@ -3446,7 +3406,13 @@ void *CustomData_get_layer(const CustomData *data, const int type) return data->layers[layer_index].data; } -void *CustomData_get_layer_n(const CustomData *data, const int type, const int n) +void *CustomData_get_layer_for_write(CustomData *data, const int type, const int totelem) +{ + const int layer_index = CustomData_get_active_layer_index(data, type); + return customData_duplicate_referenced_layer_index(data, layer_index, totelem); +} + +const void *CustomData_get_layer_n(const CustomData *data, const int type, const int n) { int layer_index = CustomData_get_layer_index_n(data, type, n); if (layer_index == -1) { @@ -3456,7 +3422,16 @@ void *CustomData_get_layer_n(const CustomData *data, const int type, const int n return data->layers[layer_index].data; } -void *CustomData_get_layer_named(const CustomData *data, const int type, const char *name) +void *CustomData_get_layer_n_for_write(CustomData *data, + const int type, + const int n, + const int totelem) +{ + const int layer_index = CustomData_get_layer_index_n(data, type, n); + return customData_duplicate_referenced_layer_index(data, layer_index, totelem); +} + +const void *CustomData_get_layer_named(const CustomData *data, const int type, const char *name) { int layer_index = CustomData_get_named_layer_index(data, type, name); if (layer_index == -1) { @@ -3466,6 +3441,15 @@ void *CustomData_get_layer_named(const CustomData *data, const int type, const c return data->layers[layer_index].data; } +void *CustomData_get_layer_named_for_write(CustomData *data, + const int type, + const char *name, + const int totelem) +{ + const int layer_index = CustomData_get_named_layer_index(data, type, name); + return customData_duplicate_referenced_layer_index(data, layer_index, totelem); +} + int CustomData_get_offset(const CustomData *data, const int type) { int layer_index = CustomData_get_active_layer_index(data, type); diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index 48dd0c84a54..39d6cde31e7 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -277,10 +277,11 @@ static void data_transfer_dtdata_type_preprocess(Mesh *me_src, float(*loop_nors_dst)[3]; short(*custom_nors_dst)[2] = static_cast( - CustomData_get_layer(ldata_dst, CD_CUSTOMLOOPNORMAL)); + CustomData_get_layer_for_write(ldata_dst, CD_CUSTOMLOOPNORMAL, me_dst->totloop)); /* Cache loop nors into a temp CDLayer. */ - loop_nors_dst = static_cast(CustomData_get_layer(ldata_dst, CD_NORMAL)); + loop_nors_dst = static_cast( + CustomData_get_layer_for_write(ldata_dst, CD_NORMAL, me_dst->totloop)); const bool do_loop_nors_dst = (loop_nors_dst == nullptr); if (do_loop_nors_dst) { loop_nors_dst = static_cast( @@ -337,9 +338,9 @@ static void data_transfer_dtdata_type_postprocess(Object * /*ob_src*/, const float(*poly_nors_dst)[3] = BKE_mesh_poly_normals_ensure(me_dst); float(*loop_nors_dst)[3] = static_cast( - CustomData_get_layer(ldata_dst, CD_NORMAL)); + CustomData_get_layer_for_write(ldata_dst, CD_NORMAL, me_dst->totloop)); short(*custom_nors_dst)[2] = static_cast( - CustomData_get_layer(ldata_dst, CD_CUSTOMLOOPNORMAL)); + CustomData_get_layer_for_write(ldata_dst, CD_CUSTOMLOOPNORMAL, me_dst->totloop)); if (!custom_nors_dst) { custom_nors_dst = static_cast(CustomData_add_layer( @@ -514,7 +515,6 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map const bool use_delete, const CustomData *cd_src, CustomData *cd_dst, - const bool use_dupref_dst, const int tolayers, const bool *use_layers_src, const int num_layers_src, @@ -571,15 +571,7 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map continue; } data_src = CustomData_get_layer_n(cd_src, cddata_type, idx_src); - /* If dest is a evaluated mesh (from modifier), - * we do not want to overwrite cdlayers of orig mesh! */ - if (use_dupref_dst) { - data_dst = CustomData_duplicate_referenced_layer_n( - cd_dst, cddata_type, idx_src, num_elem_dst); - } - else { - data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_src); - } + data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_src, num_elem_dst); data_transfer_layersmapping_add_item_cd(r_map, cddata_type, mix_mode, @@ -627,15 +619,7 @@ static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map data_dst_to_delete[idx_dst] = false; } if (r_map) { - /* If dest is a evaluated mesh (from modifier), - * we do not want to overwrite cdlayers of orig mesh! */ - if (use_dupref_dst) { - data_dst = CustomData_duplicate_referenced_layer_n( - cd_dst, cddata_type, idx_dst, num_elem_dst); - } - else { - data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst); - } + data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst); data_transfer_layersmapping_add_item_cd(r_map, cddata_type, mix_mode, @@ -677,9 +661,8 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map, const int num_elem_dst, const bool use_create, const bool use_delete, - CustomData *cd_src, + const CustomData *cd_src, CustomData *cd_dst, - const bool use_dupref_dst, const int fromlayers, const int tolayers, cd_datatransfer_interp interp, @@ -697,18 +680,13 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map, return true; } - data_dst = CustomData_get_layer(cd_dst, cddata_type); + data_dst = CustomData_get_layer_for_write(cd_dst, cddata_type, num_elem_dst); if (!data_dst) { if (!use_create) { return true; } data_dst = CustomData_add_layer(cd_dst, cddata_type, CD_SET_DEFAULT, nullptr, num_elem_dst); } - else if (use_dupref_dst && r_map) { - /* If dest is a evaluated mesh (from modifier), - * we do not want to overwrite cdlayers of orig mesh! */ - data_dst = CustomData_duplicate_referenced_layer(cd_dst, cddata_type, num_elem_dst); - } if (r_map) { data_transfer_layersmapping_add_item_cd(r_map, @@ -740,15 +718,7 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map, if (tolayers >= 0) { /* Real-layer index */ idx_dst = tolayers; - /* If dest is a evaluated mesh (from modifier), - * we do not want to overwrite cdlayers of orig mesh! */ - if (use_dupref_dst && r_map) { - data_dst = CustomData_duplicate_referenced_layer_n( - cd_dst, cddata_type, idx_dst, num_elem_dst); - } - else { - data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst); - } + data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst); } else if (tolayers == DT_LAYERS_ACTIVE_DST) { if ((idx_dst = CustomData_get_active_layer(cd_dst, cddata_type)) == -1) { @@ -759,15 +729,7 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map, cd_dst, cddata_type, CD_SET_DEFAULT, nullptr, num_elem_dst); } else { - /* If dest is a evaluated mesh (from modifier), - * we do not want to overwrite cdlayers of orig mesh! */ - if (use_dupref_dst && r_map) { - data_dst = CustomData_duplicate_referenced_layer_n( - cd_dst, cddata_type, idx_dst, num_elem_dst); - } - else { - data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst); - } + data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst); } } else if (tolayers == DT_LAYERS_INDEX_DST) { @@ -782,15 +744,7 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map, CustomData_add_layer(cd_dst, cddata_type, CD_SET_DEFAULT, nullptr, num_elem_dst); } } - /* If dest is a evaluated mesh (from modifier), - * we do not want to overwrite cdlayers of orig mesh! */ - if (use_dupref_dst && r_map) { - data_dst = CustomData_duplicate_referenced_layer_n( - cd_dst, cddata_type, idx_dst, num_elem_dst); - } - else { - data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst); - } + data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst); } else if (tolayers == DT_LAYERS_NAME_DST) { const char *name = CustomData_get_layer_name(cd_src, cddata_type, idx_src); @@ -802,15 +756,7 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map, cd_dst, cddata_type, CD_SET_DEFAULT, nullptr, num_elem_dst, name); idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name); } - /* If dest is a evaluated mesh (from modifier), - * we do not want to overwrite cdlayers of orig mesh! */ - if (use_dupref_dst && r_map) { - data_dst = CustomData_duplicate_referenced_layer_n( - cd_dst, cddata_type, idx_dst, num_elem_dst); - } - else { - data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst); - } + data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst); } else { return false; @@ -853,7 +799,6 @@ static bool data_transfer_layersmapping_cdlayers(ListBase *r_map, use_delete, cd_src, cd_dst, - use_dupref_dst, tolayers, use_layers_src, num_src, @@ -909,7 +854,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, use_delete, cd_src, cd_dst, - me_dst != ob_dst->data, fromlayers, tolayers, interp, @@ -962,7 +906,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, use_delete, cd_src, cd_dst, - me_dst != ob_dst->data, fromlayers, tolayers, interp, @@ -1007,7 +950,8 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, mix_factor, mix_weights, CustomData_get_layer_named(&me_src->edata, CD_PROP_BOOL, "sharp_edge"), - CustomData_get_layer_named(&me_dst->edata, CD_PROP_BOOL, "sharp_edge"), + CustomData_get_layer_named_for_write( + &me_dst->edata, CD_PROP_BOOL, "sharp_edge", me_dst->totedge), interp, interp_data); return true; @@ -1040,7 +984,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, use_delete, cd_src, cd_dst, - me_dst != ob_dst->data, fromlayers, tolayers, interp, @@ -1072,7 +1015,6 @@ static bool data_transfer_layersmapping_generate(ListBase *r_map, use_delete, cd_src, cd_dst, - me_dst != ob_dst->data, fromlayers, tolayers, interp, diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index c2e5434f0e1..8bc98270054 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -1395,10 +1395,10 @@ bool data_transfer_layersmapping_vgroups(ListBase *r_map, const MDeformVert *data_src = CustomData_get_layer(cd_src, CD_MDEFORMVERT); - MDeformVert *data_dst = CustomData_get_layer(cd_dst, CD_MDEFORMVERT); + MDeformVert *data_dst = CustomData_get_layer_for_write(cd_dst, CD_MDEFORMVERT, num_elem_dst); if (data_dst && use_dupref_dst && r_map) { /* If dest is a derivedmesh, we do not want to overwrite cdlayers of org mesh! */ - data_dst = CustomData_duplicate_referenced_layer(cd_dst, CD_MDEFORMVERT, num_elem_dst); + data_dst = CustomData_get_layer_for_write(cd_dst, CD_MDEFORMVERT, num_elem_dst); } if (fromlayers == DT_LAYERS_ACTIVE_SRC || fromlayers >= 0) { diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 21614b53eae..4f24a503a4d 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -1934,8 +1934,8 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * } /* paint layer */ - MLoopCol *mloopcol = CustomData_get_layer_named( - &result->ldata, CD_PROP_BYTE_COLOR, surface->output_name); + MLoopCol *mloopcol = CustomData_get_layer_named_for_write( + &result->ldata, CD_PROP_BYTE_COLOR, surface->output_name, result->totloop); /* 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, @@ -1947,8 +1947,8 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * } /* wet layer */ - MLoopCol *mloopcol_wet = CustomData_get_layer_named( - &result->ldata, CD_PROP_BYTE_COLOR, surface->output_name2); + MLoopCol *mloopcol_wet = CustomData_get_layer_named_for_write( + &result->ldata, CD_PROP_BYTE_COLOR, surface->output_name2, result->totloop); /* 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, @@ -1978,7 +1978,8 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * /* vertex group paint */ else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { int defgrp_index = BKE_object_defgroup_name_index(ob, surface->output_name); - MDeformVert *dvert = CustomData_get_layer(&result->vdata, CD_MDEFORMVERT); + MDeformVert *dvert = CustomData_get_layer_for_write( + &result->vdata, CD_MDEFORMVERT, result->totvert); float *weight = (float *)sData->type_data; /* apply weights into a vertex group, if doesn't exists add a new layer */ diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 0dfb6d2c093..4b3a42e4c8a 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -2222,7 +2222,7 @@ void BKE_keyblock_convert_to_mesh(const KeyBlock *kb, } void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, - const Mesh *mesh, + Mesh *mesh, float (*r_vert_normals)[3], float (*r_poly_normals)[3], float (*r_loop_normals)[3]) @@ -2272,8 +2272,8 @@ void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, vert_normals); } if (loop_normals_needed) { - short(*clnors)[2] = static_cast( - CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL)); /* May be nullptr. */ + short(*clnors)[2] = static_cast(CustomData_get_layer_for_write( + &mesh->ldata, CD_CUSTOMLOOPNORMAL, mesh->totloop)); /* May be nullptr. */ const bool *sharp_edges = static_cast( CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge")); BKE_mesh_normals_loop_split(positions, diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 47832e669ed..23276b524b4 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -1601,7 +1601,7 @@ void BKE_mesh_transform(Mesh *me, const float mat[4][4], bool do_keys) /* don't update normals, caller can do this explicitly. * We do update loop normals though, those may not be auto-generated * (see e.g. STL import script)! */ - float(*lnors)[3] = (float(*)[3])CustomData_duplicate_referenced_layer( + float(*lnors)[3] = (float(*)[3])CustomData_get_layer_for_write( &me->ldata, CD_NORMAL, me->totloop); if (lnors) { float m3[3][3]; @@ -1815,7 +1815,8 @@ static float (*ensure_corner_normal_layer(Mesh &mesh))[3] { float(*r_loop_normals)[3]; if (CustomData_has_layer(&mesh.ldata, CD_NORMAL)) { - r_loop_normals = (float(*)[3])CustomData_get_layer(&mesh.ldata, CD_NORMAL); + r_loop_normals = (float(*)[3])CustomData_get_layer_for_write( + &mesh.ldata, CD_NORMAL, mesh.totloop); memset(r_loop_normals, 0, sizeof(float[3]) * mesh.totloop); } else { @@ -1838,7 +1839,8 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, const float split_angle = (mesh->flag & ME_AUTOSMOOTH) != 0 ? mesh->smoothresh : float(M_PI); /* may be nullptr */ - short(*clnors)[2] = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); + short(*clnors)[2] = (short(*)[2])CustomData_get_layer_for_write( + &mesh->ldata, CD_CUSTOMLOOPNORMAL, mesh->totloop); const bool *sharp_edges = static_cast( CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge")); diff --git a/source/blender/blenkernel/intern/mesh_boolean_convert.cc b/source/blender/blenkernel/intern/mesh_boolean_convert.cc index 8ae08972cad..74033704565 100644 --- a/source/blender/blenkernel/intern/mesh_boolean_convert.cc +++ b/source/blender/blenkernel/intern/mesh_boolean_convert.cc @@ -641,11 +641,14 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh, } int source_layer_type_index = source_layer_i - source_cd->typemap[ty]; BLI_assert(target_layer_type_index != -1 && source_layer_type_index >= 0); + const int size = CustomData_sizeof(ty); for (int j = 0; j < orig_mp->totloop; ++j) { - src_blocks_ofs[j] = CustomData_get_n( - source_cd, ty, orig_mp->loopstart + j, source_layer_type_index); + const void *layer = CustomData_get_layer_n(source_cd, ty, source_layer_type_index); + src_blocks_ofs[j] = POINTER_OFFSET(layer, size * (orig_mp->loopstart + j)); } - void *dst_block_ofs = CustomData_get_n(target_cd, ty, loop_index, target_layer_type_index); + void *dst_layer = CustomData_get_layer_n_for_write( + target_cd, ty, target_layer_type_index, dest_mesh->totloop); + void *dst_block_ofs = POINTER_OFFSET(dst_layer, size * loop_index); CustomData_bmesh_interp_n(target_cd, src_blocks_ofs.data(), weights.data(), diff --git a/source/blender/blenkernel/intern/mesh_evaluate.cc b/source/blender/blenkernel/intern/mesh_evaluate.cc index 629d9e89ed6..3c25cd2e07e 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.cc +++ b/source/blender/blenkernel/intern/mesh_evaluate.cc @@ -595,15 +595,15 @@ void BKE_mesh_polygon_flip_ex(const MPoly *mpoly, } } -void BKE_mesh_polygon_flip(const MPoly *mpoly, MLoop *mloop, CustomData *ldata) +void BKE_mesh_polygon_flip(const MPoly *mpoly, MLoop *mloop, CustomData *ldata, const int totloop) { - MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS); + MDisps *mdisp = (MDisps *)CustomData_get_layer_for_write(ldata, CD_MDISPS, totloop); BKE_mesh_polygon_flip_ex(mpoly, mloop, ldata, nullptr, mdisp, true); } void BKE_mesh_polys_flip(const MPoly *mpoly, MLoop *mloop, CustomData *ldata, int totpoly) { - MDisps *mdisp = (MDisps *)CustomData_get_layer(ldata, CD_MDISPS); + MDisps *mdisp = (MDisps *)CustomData_get_layer_for_write(ldata, CD_MDISPS, totpoly); const MPoly *mp; int i; diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 07fe17794ff..0f95158e430 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -289,6 +289,7 @@ void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh) static void bm_corners_to_loops_ex(ID *id, CustomData *fdata, + const int totface, CustomData *ldata, MFace *mface, int totloop, @@ -300,10 +301,11 @@ static void bm_corners_to_loops_ex(ID *id, MFace *mf = mface + findex; for (int i = 0; i < numTex; i++) { - const MTFace *texface = (const MTFace *)CustomData_get_n(fdata, CD_MTFACE, findex, i); + const MTFace *texface = (const MTFace *)CustomData_get_n_for_write( + fdata, CD_MTFACE, findex, i, totface); blender::float2 *uv = static_cast( - CustomData_get_n(ldata, CD_PROP_FLOAT2, loopstart, i)); + CustomData_get_n_for_write(ldata, CD_PROP_FLOAT2, loopstart, i, totloop)); copy_v2_v2(*uv, texface->uv[0]); uv++; copy_v2_v2(*uv, texface->uv[1]); @@ -318,8 +320,10 @@ static void bm_corners_to_loops_ex(ID *id, } for (int i = 0; i < numCol; i++) { - MLoopCol *mloopcol = (MLoopCol *)CustomData_get_n(ldata, CD_PROP_BYTE_COLOR, loopstart, i); - const MCol *mcol = (const MCol *)CustomData_get_n(fdata, CD_MCOL, findex, i); + MLoopCol *mloopcol = (MLoopCol *)CustomData_get_n_for_write( + ldata, CD_PROP_BYTE_COLOR, loopstart, i, totloop); + const MCol *mcol = (const MCol *)CustomData_get_n_for_write( + fdata, CD_MCOL, findex, i, totface); MESH_MLOOPCOL_FROM_MCOL(mloopcol, &mcol[0]); mloopcol++; @@ -334,9 +338,10 @@ static void bm_corners_to_loops_ex(ID *id, } if (CustomData_has_layer(fdata, CD_TESSLOOPNORMAL)) { - float(*loop_normals)[3] = (float(*)[3])CustomData_get(ldata, loopstart, CD_NORMAL); - const short(*tessloop_normals)[3] = (short(*)[3])CustomData_get( - fdata, findex, CD_TESSLOOPNORMAL); + float(*loop_normals)[3] = (float(*)[3])CustomData_get_for_write( + ldata, loopstart, CD_NORMAL, totloop); + const short(*tessloop_normals)[3] = (short(*)[3])CustomData_get_for_write( + fdata, findex, CD_TESSLOOPNORMAL, totface); const int max = mf->v4 ? 4 : 3; for (int i = 0; i < max; i++, loop_normals++, tessloop_normals++) { @@ -345,8 +350,8 @@ static void bm_corners_to_loops_ex(ID *id, } if (CustomData_has_layer(fdata, CD_MDISPS)) { - MDisps *ld = (MDisps *)CustomData_get(ldata, loopstart, CD_MDISPS); - const MDisps *fd = (const MDisps *)CustomData_get(fdata, findex, CD_MDISPS); + MDisps *ld = (MDisps *)CustomData_get_for_write(ldata, loopstart, CD_MDISPS, totloop); + const MDisps *fd = (const MDisps *)CustomData_get_for_write(fdata, findex, CD_MDISPS, totface); const float(*disps)[3] = fd->disps; int tot = mf->v4 ? 4 : 3; int corners; @@ -443,7 +448,7 @@ static void convert_mfaces_to_mpolys(ID *id, totpoly = totface_i; mpoly = (MPoly *)CustomData_add_layer(pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, totpoly); int *material_indices = static_cast( - CustomData_get_layer_named(pdata, CD_PROP_INT32, "material_index")); + CustomData_get_layer_named_for_write(pdata, CD_PROP_INT32, "material_index", totpoly)); if (material_indices == nullptr) { material_indices = static_cast(CustomData_add_layer_named( pdata, CD_PROP_INT32, CD_SET_DEFAULT, nullptr, totpoly, "material_index")); @@ -515,7 +520,8 @@ static void convert_mfaces_to_mpolys(ID *id, #undef ML - bm_corners_to_loops_ex(id, fdata, ldata, mface, totloop, i, mp->loopstart, numTex, numCol); + bm_corners_to_loops_ex( + id, fdata, totface_i, ldata, mface, totloop, i, mp->loopstart, numTex, numCol); if (polyindex) { *polyindex = i; @@ -804,7 +810,7 @@ static void mesh_loops_to_tessdata(CustomData *fdata, uint(*lidx)[4]; for (i = 0; i < numUV; i++) { - MTFace *texface = (MTFace *)CustomData_get_layer_n(fdata, CD_MTFACE, i); + MTFace *texface = (MTFace *)CustomData_get_layer_n_for_write(fdata, CD_MTFACE, i, num_faces); const blender::float2 *uv = static_cast( CustomData_get_layer_n(ldata, CD_PROP_FLOAT2, i)); @@ -817,7 +823,7 @@ static void mesh_loops_to_tessdata(CustomData *fdata, } for (i = 0; i < numCol; i++) { - MCol(*mcol)[4] = (MCol(*)[4])CustomData_get_layer_n(fdata, CD_MCOL, i); + MCol(*mcol)[4] = (MCol(*)[4])CustomData_get_layer_n_for_write(fdata, CD_MCOL, i, num_faces); const MLoopCol *mloopcol = (const MLoopCol *)CustomData_get_layer_n( ldata, CD_PROP_BYTE_COLOR, i); @@ -1835,7 +1841,7 @@ void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh) using namespace blender; using namespace blender::bke; - const Span verts(static_cast(CustomData_get_layer(&mesh->vdata, CD_MVERT)), + const Span verts(static_cast(CustomData_get_layer(&mesh->vdata, CD_MVERT)), mesh->totvert); MutableSpan positions( static_cast(CustomData_add_layer_named( diff --git a/source/blender/blenkernel/intern/mesh_merge_customdata.cc b/source/blender/blenkernel/intern/mesh_merge_customdata.cc index f219ad3ae19..99a45b137a4 100644 --- a/source/blender/blenkernel/intern/mesh_merge_customdata.cc +++ b/source/blender/blenkernel/intern/mesh_merge_customdata.cc @@ -125,7 +125,8 @@ void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me) Vector mloopuv_layers; mloopuv_layers.reserve(mloopuv_layers_num); for (int a = 0; a < mloopuv_layers_num; a++) { - float2 *mloopuv = static_cast(CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, a)); + float2 *mloopuv = static_cast( + CustomData_get_layer_n_for_write(&me->ldata, CD_PROP_FLOAT2, a, me->totloop)); mloopuv_layers.append_unchecked(mloopuv); } diff --git a/source/blender/blenkernel/intern/mesh_mirror.cc b/source/blender/blenkernel/intern/mesh_mirror.cc index 3f5d18e86b9..21b8ab83ebd 100644 --- a/source/blender/blenkernel/intern/mesh_mirror.cc +++ b/source/blender/blenkernel/intern/mesh_mirror.cc @@ -298,7 +298,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, totshape = CustomData_number_of_layers(&result->vdata, CD_SHAPEKEY); for (a = 0; a < totshape; a++) { float(*cos)[3] = static_cast( - CustomData_get_layer_n(&result->vdata, CD_SHAPEKEY, a)); + CustomData_get_layer_n_for_write(&result->vdata, CD_SHAPEKEY, a, result->totvert)); for (i = maxVerts; i < result->totvert; i++) { mul_m4_v3(mtx, cos[i]); } @@ -361,7 +361,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, for (a = 0; a < totuv; a++) { float(*dmloopuv)[2] = static_cast( - CustomData_get_layer_n(&result->ldata, CD_PROP_FLOAT2, a)); + CustomData_get_layer_n_for_write(&result->ldata, CD_PROP_FLOAT2, a, result->totloop)); int j = maxLoops; dmloopuv += j; /* second set of loops only */ for (; j-- > 0; dmloopuv++) { @@ -397,7 +397,8 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd, float(*loop_normals)[3] = static_cast( MEM_calloc_arrayN(size_t(totloop), sizeof(*loop_normals), __func__)); CustomData *ldata = &result->ldata; - short(*clnors)[2] = static_cast(CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL)); + short(*clnors)[2] = static_cast( + CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, totloop)); MLoopNorSpaceArray lnors_spacearr = {nullptr}; /* The transform matrix of a normal must be diff --git a/source/blender/blenkernel/intern/mesh_normals.cc b/source/blender/blenkernel/intern/mesh_normals.cc index aa5b2d761f7..db700ec3e12 100644 --- a/source/blender/blenkernel/intern/mesh_normals.cc +++ b/source/blender/blenkernel/intern/mesh_normals.cc @@ -1913,7 +1913,8 @@ static void mesh_set_custom_normals(Mesh *mesh, float (*r_custom_nors)[3], const short(*clnors)[2]; const int numloops = mesh->totloop; - clnors = (short(*)[2])CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); + clnors = (short(*)[2])CustomData_get_layer_for_write( + &mesh->ldata, CD_CUSTOMLOOPNORMAL, mesh->totloop); if (clnors != nullptr) { memset(clnors, 0, sizeof(*clnors) * size_t(numloops)); } diff --git a/source/blender/blenkernel/intern/mesh_remap.cc b/source/blender/blenkernel/intern/mesh_remap.cc index 0b073e8d77f..c36fbfb3274 100644 --- a/source/blender/blenkernel/intern/mesh_remap.cc +++ b/source/blender/blenkernel/intern/mesh_remap.cc @@ -1357,10 +1357,11 @@ void BKE_mesh_remap_calc_loops_from_mesh(const int mode, } if (need_lnors_dst) { short(*custom_nors_dst)[2] = static_cast( - CustomData_get_layer(ldata_dst, CD_CUSTOMLOOPNORMAL)); + CustomData_get_layer_for_write(ldata_dst, CD_CUSTOMLOOPNORMAL, numloops_dst)); /* Cache loop normals into a temporary custom data layer. */ - loop_nors_dst = static_cast(CustomData_get_layer(ldata_dst, CD_NORMAL)); + loop_nors_dst = static_cast( + CustomData_get_layer_for_write(ldata_dst, CD_NORMAL, numloops_dst)); const bool do_loop_nors_dst = (loop_nors_dst == nullptr); if (!loop_nors_dst) { loop_nors_dst = static_cast( diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc index e834ef70b4e..478c429e7aa 100644 --- a/source/blender/blenkernel/intern/mesh_validate.cc +++ b/source/blender/blenkernel/intern/mesh_validate.cc @@ -1071,21 +1071,22 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_ MutableSpan polys = me->polys_for_write(); MutableSpan loops = me->loops_for_write(); - BKE_mesh_validate_arrays(me, - reinterpret_cast(positions.data()), - positions.size(), - edges.data(), - edges.size(), - (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE), - me->totface, - loops.data(), - loops.size(), - polys.data(), - polys.size(), - me->deform_verts_for_write().data(), - do_verbose, - true, - &changed); + BKE_mesh_validate_arrays( + me, + reinterpret_cast(positions.data()), + positions.size(), + edges.data(), + edges.size(), + (MFace *)CustomData_get_layer_for_write(&me->fdata, CD_MFACE, me->totface), + me->totface, + loops.data(), + loops.size(), + polys.data(), + polys.size(), + me->deform_verts_for_write().data(), + do_verbose, + true, + &changed); if (changed) { DEG_id_tag_update(&me->id, ID_RECALC_GEOMETRY_ALL_MODES); @@ -1122,21 +1123,22 @@ bool BKE_mesh_is_valid(Mesh *me) MutableSpan polys = me->polys_for_write(); MutableSpan loops = me->loops_for_write(); - is_valid &= BKE_mesh_validate_arrays(me, - reinterpret_cast(positions.data()), - positions.size(), - edges.data(), - edges.size(), - (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE), - me->totface, - loops.data(), - loops.size(), - polys.data(), - polys.size(), - me->deform_verts_for_write().data(), - do_verbose, - do_fixes, - &changed); + is_valid &= BKE_mesh_validate_arrays( + me, + reinterpret_cast(positions.data()), + positions.size(), + edges.data(), + edges.size(), + (MFace *)CustomData_get_layer_for_write(&me->fdata, CD_MFACE, me->totface), + me->totface, + loops.data(), + loops.size(), + polys.data(), + polys.size(), + me->deform_verts_for_write().data(), + do_verbose, + do_fixes, + &changed); if (!me->runtime->vert_normals_dirty) { BLI_assert(me->runtime->vert_normals || me->totvert == 0); @@ -1186,7 +1188,7 @@ void BKE_mesh_strip_loose_faces(Mesh *me) /* NOTE: We need to keep this for edge creation (for now?), and some old `readfile.c` code. */ MFace *f; int a, b; - MFace *mfaces = (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE); + MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&me->fdata, CD_MFACE, me->totface); for (a = b = 0, f = mfaces; a < me->totface; a++, f++) { if (f->v3) { @@ -1323,7 +1325,7 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh) { const int numFaces = mesh->totface; EdgeSet *eh = BLI_edgeset_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(numFaces)); - MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface); MFace *mf = mfaces; for (int i = 0; i < numFaces; i++, mf++) { @@ -1347,8 +1349,8 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh) CustomData_add_layer(&edgeData, CD_MEDGE, CD_SET_DEFAULT, nullptr, numEdges); CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, numEdges); - MEdge *med = (MEdge *)CustomData_get_layer(&edgeData, CD_MEDGE); - int *index = (int *)CustomData_get_layer(&edgeData, CD_ORIGINDEX); + MEdge *med = (MEdge *)CustomData_get_layer_for_write(&edgeData, CD_MEDGE, mesh->totedge); + int *index = (int *)CustomData_get_layer_for_write(&edgeData, CD_ORIGINDEX, mesh->totedge); EdgeSetIterator *ehi = BLI_edgesetIterator_new(eh); for (int i = 0; BLI_edgesetIterator_isDone(ehi) == false; diff --git a/source/blender/blenkernel/intern/mesh_wrapper.cc b/source/blender/blenkernel/intern/mesh_wrapper.cc index 33c67e606b9..9c8c36cacb8 100644 --- a/source/blender/blenkernel/intern/mesh_wrapper.cc +++ b/source/blender/blenkernel/intern/mesh_wrapper.cc @@ -340,7 +340,7 @@ static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me) if (use_clnors) { float(*lnors)[3] = static_cast( - CustomData_get_layer(&subdiv_mesh->ldata, CD_NORMAL)); + CustomData_get_layer_for_write(&subdiv_mesh->ldata, CD_NORMAL, subdiv_mesh->totloop)); BLI_assert(lnors != nullptr); BKE_mesh_set_custom_normals(subdiv_mesh, lnors); CustomData_set_layer_flag(&me->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); diff --git a/source/blender/blenkernel/intern/multires.cc b/source/blender/blenkernel/intern/multires.cc index 890a1379e4c..9b04435b91c 100644 --- a/source/blender/blenkernel/intern/multires.cc +++ b/source/blender/blenkernel/intern/multires.cc @@ -544,7 +544,8 @@ void multiresModifier_set_levels_from_disps(MultiresModifierData *mmd, Object *o static void multires_set_tot_mdisps(Mesh *me, int lvl) { - MDisps *mdisps = static_cast(CustomData_get_layer(&me->ldata, CD_MDISPS)); + MDisps *mdisps = static_cast( + CustomData_get_layer_for_write(&me->ldata, CD_MDISPS, me->totloop)); int i; if (mdisps) { @@ -663,8 +664,10 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl) multires_set_tot_mdisps(me, mmd->totlvl); multiresModifier_ensure_external_read(me, mmd); - mdisps = static_cast(CustomData_get_layer(&me->ldata, CD_MDISPS)); - gpm = static_cast(CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK)); + mdisps = static_cast( + CustomData_get_layer_for_write(&me->ldata, CD_MDISPS, me->totloop)); + gpm = static_cast( + CustomData_get_layer_for_write(&me->ldata, CD_GRID_PAINT_MASK, me->totloop)); multires_force_sculpt_rebuild(ob); @@ -728,7 +731,8 @@ void multiresModifier_del_levels(MultiresModifierData *mmd, multires_set_tot_mdisps(me, mmd->totlvl); multiresModifier_ensure_external_read(me, mmd); - MDisps *mdisps = static_cast(CustomData_get_layer(&me->ldata, CD_MDISPS)); + MDisps *mdisps = static_cast( + CustomData_get_layer_for_write(&me->ldata, CD_MDISPS, me->totloop)); multires_force_sculpt_rebuild(ob); @@ -965,7 +969,8 @@ static void multiresModifier_disp_run( CCGElem **gridData, **subGridData; CCGKey key; const MPoly *mpoly = BKE_mesh_polys(me); - MDisps *mdisps = static_cast(CustomData_get_layer(&me->ldata, CD_MDISPS)); + MDisps *mdisps = static_cast( + CustomData_get_layer_for_write(&me->ldata, CD_MDISPS, me->totloop)); GridPaintMask *grid_paint_mask = nullptr; int *gridOffset; int i, gridSize, dGridSize, dSkip; @@ -973,8 +978,10 @@ static void multiresModifier_disp_run( /* this happens in the dm made by bmesh_mdisps_space_set */ if (dm2 && CustomData_has_layer(&dm2->loopData, CD_MDISPS)) { - mpoly = static_cast(CustomData_get_layer(&dm2->polyData, CD_MPOLY)); - mdisps = static_cast(CustomData_get_layer(&dm2->loopData, CD_MDISPS)); + mpoly = static_cast( + CustomData_get_layer_for_write(&dm2->polyData, CD_MPOLY, dm2->getNumPolys(dm))); + mdisps = static_cast( + CustomData_get_layer_for_write(&dm2->loopData, CD_MDISPS, dm2->getNumLoops(dm))); totloop = dm2->numLoopData; totpoly = dm2->numPolyData; } @@ -1006,7 +1013,7 @@ static void multiresModifier_disp_run( /* multires paint masks */ if (key.has_mask) { grid_paint_mask = static_cast( - CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK)); + CustomData_get_layer_for_write(&me->ldata, CD_GRID_PAINT_MASK, me->totloop)); } /* when adding new faces in edit mode, need to allocate disps */ @@ -1176,7 +1183,8 @@ void multires_modifier_update_hidden(DerivedMesh *dm) CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; BLI_bitmap **grid_hidden = ccgdm->gridHidden; Mesh *me = static_cast(ccgdm->multires.ob->data); - MDisps *mdisps = static_cast(CustomData_get_layer(&me->ldata, CD_MDISPS)); + MDisps *mdisps = static_cast( + CustomData_get_layer_for_write(&me->ldata, CD_MDISPS, me->totloop)); int totlvl = ccgdm->multires.totlvl; int lvl = ccgdm->multires.lvl; @@ -1395,7 +1403,8 @@ static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst) static void multires_apply_uniform_scale(Object *object, const float scale) { Mesh *mesh = (Mesh *)object->data; - MDisps *mdisps = static_cast(CustomData_get_layer(&mesh->ldata, CD_MDISPS)); + MDisps *mdisps = static_cast( + CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop)); for (int i = 0; i < mesh->totloop; i++) { MDisps *grid = &mdisps[i]; for (int j = 0; j < grid->totdisp; j++) { @@ -1479,7 +1488,8 @@ void multires_topology_changed(Mesh *me) int i, grid = 0; CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop); - mdisp = static_cast(CustomData_get_layer(&me->ldata, CD_MDISPS)); + mdisp = static_cast( + CustomData_get_layer_for_write(&me->ldata, CD_MDISPS, me->totloop)); if (!mdisp) { return; @@ -1514,7 +1524,8 @@ void multires_ensure_external_read(struct Mesh *mesh, int top_level) return; } - MDisps *mdisps = static_cast(CustomData_get_layer(&mesh->ldata, CD_MDISPS)); + MDisps *mdisps = static_cast( + CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop)); if (mdisps == nullptr) { mdisps = static_cast( CustomData_add_layer(&mesh->ldata, CD_MDISPS, CD_SET_DEFAULT, nullptr, mesh->totloop)); diff --git a/source/blender/blenkernel/intern/multires_reshape_subdivide.c b/source/blender/blenkernel/intern/multires_reshape_subdivide.c index e3cb6f52a41..4e74835fd9a 100644 --- a/source/blender/blenkernel/intern/multires_reshape_subdivide.c +++ b/source/blender/blenkernel/intern/multires_reshape_subdivide.c @@ -32,7 +32,7 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh) const MPoly *polys = BKE_mesh_polys(mesh); const MLoop *loops = BKE_mesh_loops(mesh); - MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS); + MDisps *mdisps = CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop); const int totpoly = mesh->totpoly; for (int p = 0; p < totpoly; p++) { const MPoly *poly = &polys[p]; diff --git a/source/blender/blenkernel/intern/multires_reshape_util.c b/source/blender/blenkernel/intern/multires_reshape_util.c index 1c33fbb6dd8..dfc9fcfe0c9 100644 --- a/source/blender/blenkernel/intern/multires_reshape_util.c +++ b/source/blender/blenkernel/intern/multires_reshape_util.c @@ -103,8 +103,10 @@ static void context_init_lookup(MultiresReshapeContext *reshape_context) static void context_init_grid_pointers(MultiresReshapeContext *reshape_context) { Mesh *base_mesh = reshape_context->base_mesh; - reshape_context->mdisps = CustomData_get_layer(&base_mesh->ldata, CD_MDISPS); - reshape_context->grid_paint_masks = CustomData_get_layer(&base_mesh->ldata, CD_GRID_PAINT_MASK); + reshape_context->mdisps = CustomData_get_layer_for_write( + &base_mesh->ldata, CD_MDISPS, base_mesh->totloop); + reshape_context->grid_paint_masks = CustomData_get_layer_for_write( + &base_mesh->ldata, CD_GRID_PAINT_MASK, base_mesh->totloop); } static void context_init_commoon(MultiresReshapeContext *reshape_context) @@ -559,7 +561,7 @@ static void ensure_displacement_grid(MDisps *displacement_grid, const int level) static void ensure_displacement_grids(Mesh *mesh, const int grid_level) { const int num_grids = mesh->totloop; - MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS); + MDisps *mdisps = CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop); for (int grid_index = 0; grid_index < num_grids; grid_index++) { ensure_displacement_grid(&mdisps[grid_index], grid_level); } @@ -567,7 +569,8 @@ static void ensure_displacement_grids(Mesh *mesh, const int grid_level) static void ensure_mask_grids(Mesh *mesh, const int level) { - GridPaintMask *grid_paint_masks = CustomData_get_layer(&mesh->ldata, CD_GRID_PAINT_MASK); + GridPaintMask *grid_paint_masks = CustomData_get_layer_for_write( + &mesh->ldata, CD_GRID_PAINT_MASK, mesh->totloop); if (grid_paint_masks == NULL) { return; } diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.c b/source/blender/blenkernel/intern/multires_unsubdivide.c index 28bd199a967..2ef074cd24d 100644 --- a/source/blender/blenkernel/intern/multires_unsubdivide.c +++ b/source/blender/blenkernel/intern/multires_unsubdivide.c @@ -938,7 +938,8 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract( bm_original_mesh, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false); /* Get the mapping data-layer. */ - context->base_to_orig_vmap = CustomData_get_layer_named(&base_mesh->vdata, CD_PROP_INT32, vname); + context->base_to_orig_vmap = CustomData_get_layer_named_for_write( + &base_mesh->vdata, CD_PROP_INT32, vname, base_mesh->totvert); /* Tag the base mesh vertices in the original mesh. */ for (int i = 0; i < base_mesh->totvert; i++) { @@ -1001,7 +1002,8 @@ static void multires_unsubdivide_extract_grids(MultiresUnsubdivideContext *conte int *orig_to_base_vmap = MEM_calloc_arrayN(bm_original_mesh->totvert, sizeof(int), "orig vmap"); int *base_to_orig_vmap = MEM_calloc_arrayN(base_mesh->totvert, sizeof(int), "base vmap"); - context->base_to_orig_vmap = CustomData_get_layer_named(&base_mesh->vdata, CD_PROP_INT32, vname); + context->base_to_orig_vmap = CustomData_get_layer_named_for_write( + &base_mesh->vdata, CD_PROP_INT32, vname, base_mesh->totvert); for (int i = 0; i < base_mesh->totvert; i++) { base_to_orig_vmap[i] = context->base_to_orig_vmap[i]; } diff --git a/source/blender/blenkernel/intern/object_facemap.c b/source/blender/blenkernel/intern/object_facemap.c index 42c57c706a4..de3bb5d4f41 100644 --- a/source/blender/blenkernel/intern/object_facemap.c +++ b/source/blender/blenkernel/intern/object_facemap.c @@ -176,7 +176,7 @@ static void object_fmap_remove_object_mode(Object *ob, bFaceMap *fmap, bool purg Mesh *me = ob->data; if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) { - int *map = CustomData_get_layer(&me->pdata, CD_FACEMAP); + int *map = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly); int i; if (map) { diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 75d9f0d5b89..6628bc782f0 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -1709,7 +1709,8 @@ static void sculpt_update_object( ss->multires.active = false; ss->multires.modifier = nullptr; ss->multires.level = 0; - ss->vmask = static_cast(CustomData_get_layer(&me->vdata, CD_PAINT_MASK)); + ss->vmask = static_cast( + CustomData_get_layer_for_write(&me->vdata, CD_PAINT_MASK, me->totvert)); CustomDataLayer *layer; eAttrDomain domain; @@ -1736,14 +1737,15 @@ static void sculpt_update_object( /* Sculpt Face Sets. */ if (use_face_sets) { - ss->face_sets = static_cast( - CustomData_get_layer_named(&me->pdata, CD_PROP_INT32, ".sculpt_face_set")); + ss->face_sets = static_cast(CustomData_get_layer_named_for_write( + &me->pdata, CD_PROP_INT32, ".sculpt_face_set", me->totpoly)); } else { ss->face_sets = nullptr; } - ss->hide_poly = (bool *)CustomData_get_layer_named(&me->pdata, CD_PROP_BOOL, ".hide_poly"); + ss->hide_poly = (bool *)CustomData_get_layer_named_for_write( + &me->pdata, CD_PROP_BOOL, ".hide_poly", me->totpoly); ss->subdiv_ccg = me_eval->runtime->subdiv_ccg; @@ -1962,14 +1964,14 @@ int *BKE_sculpt_face_sets_ensure(Mesh *mesh) face_sets.finish(); } - return static_cast( - CustomData_get_layer_named(&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set")); + return static_cast(CustomData_get_layer_named_for_write( + &mesh->pdata, CD_PROP_INT32, ".sculpt_face_set", mesh->totpoly)); } bool *BKE_sculpt_hide_poly_ensure(Mesh *mesh) { - bool *hide_poly = static_cast( - CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly")); + bool *hide_poly = static_cast(CustomData_get_layer_named_for_write( + &mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly)); if (hide_poly != nullptr) { return hide_poly; } diff --git a/source/blender/blenkernel/intern/particle.cc b/source/blender/blenkernel/intern/particle.cc index f871aa324be..83b665239fc 100644 --- a/source/blender/blenkernel/intern/particle.cc +++ b/source/blender/blenkernel/intern/particle.cc @@ -1888,7 +1888,8 @@ static float psys_interpolate_value_from_verts( return values[index]; case PART_FROM_FACE: case PART_FROM_VOLUME: { - MFace *mfaces = static_cast(CustomData_get_layer(&mesh->fdata, CD_MFACE)); + MFace *mfaces = static_cast( + CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface)); MFace *mf = &mfaces[index]; return interpolate_particle_value( values[mf->v1], values[mf->v2], values[mf->v3], values[mf->v4], fw, mf->v4); @@ -1981,9 +1982,10 @@ int psys_particle_dm_face_lookup(Mesh *mesh_final, index_mf_to_mpoly_deformed = nullptr; - mtessface_final = static_cast(CustomData_get_layer(&mesh_final->fdata, CD_MFACE)); + mtessface_final = static_cast( + CustomData_get_layer_for_write(&mesh_final->fdata, CD_MFACE, mesh_final->totface)); osface_final = static_cast( - CustomData_get_layer(&mesh_final->fdata, CD_ORIGSPACE)); + CustomData_get_layer_for_write(&mesh_final->fdata, CD_ORIGSPACE, mesh_final->totface)); if (osface_final == nullptr) { /* Assume we don't need osface_final data, and we get a direct 1-1 mapping... */ @@ -2102,7 +2104,7 @@ static int psys_map_index_on_dm(Mesh *mesh, /* modify the original weights to become * weights for the derived mesh face */ OrigSpaceFace *osface = static_cast( - CustomData_get_layer(&mesh->fdata, CD_ORIGSPACE)); + CustomData_get_layer_for_write(&mesh->fdata, CD_ORIGSPACE, mesh->totface)); const MFace *mfaces = static_cast( CustomData_get_layer(&mesh->fdata, CD_MFACE)); const MFace *mface = &mfaces[i]; @@ -2187,10 +2189,12 @@ void psys_particle_on_dm(Mesh *mesh_final, MFace *mface; MTFace *mtface; - MFace *mfaces = static_cast(CustomData_get_layer(&mesh_final->fdata, CD_MFACE)); + MFace *mfaces = static_cast( + CustomData_get_layer_for_write(&mesh_final->fdata, CD_MFACE, mesh_final->totface)); mface = &mfaces[mapindex]; const float(*vert_positions)[3] = BKE_mesh_vert_positions(mesh_final); - mtface = static_cast(CustomData_get_layer(&mesh_final->fdata, CD_MTFACE)); + mtface = static_cast( + CustomData_get_layer_for_write(&mesh_final->fdata, CD_MTFACE, mesh_final->totface)); if (mtface) { mtface += mapindex; @@ -3893,10 +3897,11 @@ static void psys_face_mat(Object *ob, Mesh *mesh, ParticleData *pa, float mat[4] return; } - MFace *mfaces = static_cast(CustomData_get_layer(&mesh->fdata, CD_MFACE)); + MFace *mfaces = static_cast( + CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface)); mface = &mfaces[i]; const OrigSpaceFace *osface = static_cast( - CustomData_get(&mesh->fdata, i, CD_ORIGSPACE)); + CustomData_get_for_write(&mesh->fdata, i, CD_ORIGSPACE, mesh->totface)); if (orco && (orcodata = static_cast(CustomData_get_layer(&mesh->vdata, CD_ORCO)))) { @@ -4204,7 +4209,7 @@ static int get_particle_uv(Mesh *mesh, float *texco, bool from_vert) { - MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface); MFace *mf; const MTFace *tf; int i; @@ -5108,8 +5113,8 @@ void psys_get_dupli_texture(ParticleSystem *psys, const MTFace *mtface = static_cast( CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx)); if (mtface != nullptr) { - const MFace *mface = static_cast( - CustomData_get(&psmd->mesh_final->fdata, cpa->num, CD_MFACE)); + const MFace *mface = static_cast(CustomData_get_for_write( + &psmd->mesh_final->fdata, cpa->num, CD_MFACE, psmd->mesh_final->totface)); mtface += cpa->num; psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv); } @@ -5153,8 +5158,8 @@ void psys_get_dupli_texture(ParticleSystem *psys, if (uv_idx >= 0) { const MTFace *mtface = static_cast( CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx)); - const MFace *mface = static_cast( - CustomData_get(&psmd->mesh_final->fdata, num, CD_MFACE)); + const MFace *mface = static_cast(CustomData_get_for_write( + &psmd->mesh_final->fdata, num, CD_MFACE, psmd->mesh_final->totface)); mtface += num; psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv); } diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index b7e53fac15f..7cec485e6dd 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -179,7 +179,7 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys) int amax = from == PART_FROM_FACE ? 3 : 1; totface = mesh->totface; - mface = mface_array = CustomData_get_layer(&mesh->fdata, CD_MFACE); + mface = mface_array = CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface); for (a = 0; a < amax; a++) { if (a == 0) { @@ -462,7 +462,7 @@ static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, i ParticleThreadContext *ctx = thread->ctx; MFace *mface; - mface = CustomData_get_layer(&ctx->mesh->fdata, CD_MFACE); + mface = CustomData_get_layer_for_write(&ctx->mesh->fdata, CD_MFACE, ctx->mesh->totface); int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */ @@ -523,7 +523,7 @@ static void distribute_from_faces_exec(ParticleTask *thread, ParticleData *pa, i int i; int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls won't need skipping */ - MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface); MFace *mface; pa->num = i = ctx->index[p]; @@ -578,7 +578,7 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, const float(*positions)[3] = BKE_mesh_vert_positions(mesh); pa->num = i = ctx->index[p]; - MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface); mface = &mfaces[i]; switch (distr) { @@ -630,7 +630,7 @@ static void distribute_from_volume_exec(ParticleTask *thread, ParticleData *pa, min_d = FLT_MAX; intersect = 0; - mface = CustomData_get_layer(&mesh->fdata, CD_MFACE); + mface = CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface); for (i = 0; i < tot; i++, mface++) { if (i == pa->num) { continue; @@ -700,7 +700,7 @@ static void distribute_children_exec(ParticleTask *thread, ChildParticle *cpa, i return; } - MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface); mf = &mfaces[ctx->index[p]]; randu = BLI_rng_get_float(thread->rng); @@ -1053,7 +1053,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, orcodata = CustomData_get_layer(&mesh->vdata, CD_ORCO); - MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + MFace *mfaces = (MFace *)CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface); for (i = 0; i < totelem; i++) { MFace *mf = &mfaces[i]; @@ -1114,7 +1114,8 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, } } else { /* PART_FROM_FACE / PART_FROM_VOLUME */ - MFace *mfaces = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + MFace *mfaces = (MFace *)CustomData_get_layer_for_write( + &mesh->fdata, CD_MFACE, mesh->totface); for (i = 0; i < totelem; i++) { MFace *mf = &mfaces[i]; tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3]; diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index 2a8683ecaaa..d18ef62c20c 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -825,7 +825,8 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, pbvh->mesh = mesh; pbvh->header.type = PBVH_FACES; pbvh->mpoly = mpoly; - pbvh->hide_poly = (bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly"); + pbvh->hide_poly = (bool *)CustomData_get_layer_named_for_write( + &mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly); pbvh->material_indices = (const int *)CustomData_get_layer_named( &mesh->pdata, CD_PROP_INT32, "material_index"); pbvh->mloop = mloop; @@ -833,7 +834,8 @@ void BKE_pbvh_build_mesh(PBVH *pbvh, pbvh->vert_positions = vert_positions; BKE_mesh_vertex_normals_ensure(mesh); pbvh->vert_normals = BKE_mesh_vertex_normals_for_write(mesh); - pbvh->hide_vert = (bool *)CustomData_get_layer_named(&mesh->vdata, CD_PROP_BOOL, ".hide_vert"); + pbvh->hide_vert = (bool *)CustomData_get_layer_named_for_write( + &mesh->vdata, CD_PROP_BOOL, ".hide_vert", mesh->totvert); pbvh->vert_bitmap = MEM_calloc_arrayN(totvert, sizeof(bool), "bvh->vert_bitmap"); pbvh->totvert = totvert; @@ -3369,7 +3371,7 @@ void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int m vi->vert_normals = pbvh->vert_normals; vi->hide_vert = pbvh->hide_vert; - vi->vmask = CustomData_get_layer(pbvh->vdata, CD_PAINT_MASK); + vi->vmask = CustomData_get_layer_for_write(pbvh->vdata, CD_PAINT_MASK, pbvh->mesh->totvert); } } @@ -3456,7 +3458,8 @@ bool *BKE_pbvh_get_vert_hide_for_write(PBVH *pbvh) if (pbvh->hide_vert) { return pbvh->hide_vert; } - pbvh->hide_vert = CustomData_get_layer_named(&pbvh->mesh->vdata, CD_PROP_BOOL, ".hide_vert"); + pbvh->hide_vert = CustomData_get_layer_named_for_write( + &pbvh->mesh->vdata, CD_PROP_BOOL, ".hide_vert", pbvh->mesh->totvert); if (pbvh->hide_vert) { return pbvh->hide_vert; } @@ -3478,8 +3481,10 @@ void BKE_pbvh_face_sets_set(PBVH *pbvh, int *face_sets) void BKE_pbvh_update_hide_attributes_from_mesh(PBVH *pbvh) { if (pbvh->header.type == PBVH_FACES) { - pbvh->hide_vert = CustomData_get_layer_named(&pbvh->mesh->vdata, CD_PROP_BOOL, ".hide_vert"); - pbvh->hide_poly = CustomData_get_layer_named(&pbvh->mesh->pdata, CD_PROP_BOOL, ".hide_poly"); + pbvh->hide_vert = CustomData_get_layer_named_for_write( + &pbvh->mesh->vdata, CD_PROP_BOOL, ".hide_vert", pbvh->mesh->totvert); + pbvh->hide_poly = CustomData_get_layer_named_for_write( + &pbvh->mesh->pdata, CD_PROP_BOOL, ".hide_poly", pbvh->mesh->totpoly); } } @@ -3799,8 +3804,8 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh) const MPoly *mp = BKE_mesh_polys(mesh); CCGKey key = pbvh->gridkey; - bool *hide_poly = (bool *)CustomData_get_layer_named( - &mesh->pdata, CD_PROP_BOOL, ".hide_poly"); + bool *hide_poly = (bool *)CustomData_get_layer_named_for_write( + &mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly); bool delete_hide_poly = true; for (int face_index = 0; face_index < mesh->totpoly; face_index++, mp++) { @@ -3818,14 +3823,15 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh) } if (hidden && !hide_poly) { - hide_poly = (bool *)CustomData_get_layer_named(&mesh->pdata, CD_PROP_BOOL, ".hide_poly"); + hide_poly = (bool *)CustomData_get_layer_named_for_write( + &mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly); if (!hide_poly) { CustomData_add_layer_named( &mesh->pdata, CD_PROP_BOOL, CD_CONSTRUCT, NULL, mesh->totpoly, ".hide_poly"); - hide_poly = (bool *)CustomData_get_layer_named( - &mesh->pdata, CD_PROP_BOOL, ".hide_poly"); + hide_poly = (bool *)CustomData_get_layer_named_for_write( + &mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly); } } diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc index 2d1b6dd3f0e..dbb58fd73de 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.cc +++ b/source/blender/blenkernel/intern/subdiv_mesh.cc @@ -79,8 +79,8 @@ static void subdiv_mesh_ctx_cache_uv_layers(SubdivMeshContext *ctx) Mesh *subdiv_mesh = ctx->subdiv_mesh; ctx->num_uv_layers = CustomData_number_of_layers(&subdiv_mesh->ldata, CD_PROP_FLOAT2); for (int layer_index = 0; layer_index < ctx->num_uv_layers; layer_index++) { - ctx->uv_layers[layer_index] = static_cast( - CustomData_get_layer_n(&subdiv_mesh->ldata, CD_PROP_FLOAT2, layer_index)); + ctx->uv_layers[layer_index] = static_cast(CustomData_get_layer_n_for_write( + &subdiv_mesh->ldata, CD_PROP_FLOAT2, layer_index, subdiv_mesh->totloop)); } } @@ -93,19 +93,20 @@ static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx) ctx->subdiv_loops = BKE_mesh_loops_for_write(subdiv_mesh); /* Pointers to original indices layers. */ ctx->vert_origindex = static_cast( - CustomData_get_layer(&subdiv_mesh->vdata, CD_ORIGINDEX)); + CustomData_get_layer_for_write(&subdiv_mesh->vdata, CD_ORIGINDEX, subdiv_mesh->totvert)); ctx->edge_origindex = static_cast( - CustomData_get_layer(&subdiv_mesh->edata, CD_ORIGINDEX)); + CustomData_get_layer_for_write(&subdiv_mesh->edata, CD_ORIGINDEX, subdiv_mesh->totedge)); ctx->loop_origindex = static_cast( - CustomData_get_layer(&subdiv_mesh->ldata, CD_ORIGINDEX)); + CustomData_get_layer_for_write(&subdiv_mesh->ldata, CD_ORIGINDEX, subdiv_mesh->totloop)); ctx->poly_origindex = static_cast( - CustomData_get_layer(&subdiv_mesh->pdata, CD_ORIGINDEX)); + CustomData_get_layer_for_write(&subdiv_mesh->pdata, CD_ORIGINDEX, subdiv_mesh->totpoly)); /* UV layers interpolation. */ subdiv_mesh_ctx_cache_uv_layers(ctx); /* Orco interpolation. */ - ctx->orco = static_cast(CustomData_get_layer(&subdiv_mesh->vdata, CD_ORCO)); + ctx->orco = static_cast( + CustomData_get_layer_for_write(&subdiv_mesh->vdata, CD_ORCO, subdiv_mesh->totvert)); ctx->cloth_orco = static_cast( - CustomData_get_layer(&subdiv_mesh->vdata, CD_CLOTH_ORCO)); + CustomData_get_layer_for_write(&subdiv_mesh->vdata, CD_CLOTH_ORCO, subdiv_mesh->totvert)); } static void subdiv_mesh_prepare_accumulator(SubdivMeshContext *ctx, int num_vertices) diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 910076d8b43..f5835b7fbb8 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -390,8 +390,10 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh * const float(*dmloopuv)[2] = CustomData_get_layer_n(&dm->loopData, CD_PROP_FLOAT2, n); /* need to update both CD_MTFACE & CD_PROP_FLOAT2, hrmf, we could get away with * just tface except applying the modifier then looses subsurf UV */ - MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n); - float(*mloopuv)[2] = CustomData_get_layer_n(&result->loopData, CD_PROP_FLOAT2, n); + MTFace *tface = CustomData_get_layer_n_for_write( + &result->faceData, CD_MTFACE, n, result->numTessFaceData); + float(*mloopuv)[2] = CustomData_get_layer_n_for_write( + &result->loopData, CD_PROP_FLOAT2, n, result->getNumLoops(dm)); if (!dmloopuv || (!tface && !mloopuv)) { return; diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index 217a971d844..da4783e19ea 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -996,7 +996,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) if ((key = blo_do_versions_newlibadr(fd, lib, me->key)) && key->refkey) { data = key->refkey->data; tot = MIN2(me->totvert, key->refkey->totelem); - MVert *verts = (MVert *)CustomData_get_layer(&me->vdata, CD_MVERT); + MVert *verts = (MVert *)CustomData_get_layer_for_write(&me->vdata, CD_MVERT, me->totvert); for (a = 0; a < tot; a++, data += 3) { copy_v3_v3(verts[a].co_legacy, data); } diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index eca1abc2bc9..202b9ea692d 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -821,21 +821,22 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) for (const MPoly *mp = BKE_mesh_polys(me), *mp_end = mp + me->totpoly; mp < mp_end; mp++) { if (mp->totloop == 2) { bool changed; - BKE_mesh_validate_arrays(me, - BKE_mesh_vert_positions_for_write(me), - me->totvert, - BKE_mesh_edges_for_write(me), - me->totedge, - (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE), - me->totface, - BKE_mesh_loops_for_write(me), - me->totloop, - BKE_mesh_polys_for_write(me), - me->totpoly, - BKE_mesh_deform_verts_for_write(me), - false, - true, - &changed); + BKE_mesh_validate_arrays( + me, + BKE_mesh_vert_positions_for_write(me), + me->totvert, + BKE_mesh_edges_for_write(me), + me->totedge, + (MFace *)CustomData_get_layer_for_write(&me->fdata, CD_MFACE, me->totface), + me->totface, + BKE_mesh_loops_for_write(me), + me->totloop, + BKE_mesh_polys_for_write(me), + me->totpoly, + BKE_mesh_deform_verts_for_write(me), + false, + true, + &changed); break; } } diff --git a/source/blender/blenloader/intern/versioning_defaults.cc b/source/blender/blenloader/intern/versioning_defaults.cc index d833e964232..87574e90dab 100644 --- a/source/blender/blenloader/intern/versioning_defaults.cc +++ b/source/blender/blenloader/intern/versioning_defaults.cc @@ -359,7 +359,7 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene) {0.625, 0.75}, {0.375, 0.75}, {0.375, 0.25}, {0.625, 0.25}, {0.625, 0.50}, {0.375, 0.50}, }; float(*mloopuv)[2] = static_cast( - CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2)); + CustomData_get_layer_for_write(&me->ldata, CD_PROP_FLOAT2, me->totloop)); memcpy(mloopuv, uv_values, sizeof(float[2]) * me->totloop); } diff --git a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc index add0a395d70..0937e9feb54 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc +++ b/source/blender/draw/intern/draw_cache_extract_mesh_render_data.cc @@ -367,7 +367,7 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_ mr->loop_normals = static_cast( MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__)); short(*clnors)[2] = static_cast( - CustomData_get_layer(&mr->me->ldata, CD_CUSTOMLOOPNORMAL)); + CustomData_get_layer_for_write(&mr->me->ldata, CD_CUSTOMLOOPNORMAL, mr->me->totloop)); const bool *sharp_edges = static_cast( CustomData_get_layer_named(&mr->me->edata, CD_PROP_BOOL, "sharp_edge")); BKE_mesh_normals_loop_split(reinterpret_cast(mr->vert_positions), diff --git a/source/blender/editors/mesh/editmesh_mask_extract.c b/source/blender/editors/mesh/editmesh_mask_extract.c index 9988bdcb367..969a5cf52ed 100644 --- a/source/blender/editors/mesh/editmesh_mask_extract.c +++ b/source/blender/editors/mesh/editmesh_mask_extract.c @@ -573,8 +573,10 @@ static int paint_mask_slice_exec(bContext *C, wmOperator *op) if (ob->mode == OB_MODE_SCULPT) { SculptSession *ss = ob->sculpt; - ss->face_sets = CustomData_get_layer_named( - &((Mesh *)ob->data)->pdata, CD_PROP_INT32, ".sculpt_face_set"); + ss->face_sets = CustomData_get_layer_named_for_write(&((Mesh *)ob->data)->pdata, + CD_PROP_INT32, + ".sculpt_face_set", + ((Mesh *)ob->data)->totpoly); if (ss->face_sets) { /* Assign a new Face Set ID to the new faces created by the slice operation. */ const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(ob->data); diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index 8b3ecf6f59f..db60f253cb2 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -232,7 +232,7 @@ void ED_mesh_uv_loop_reset_ex(Mesh *me, const int layernum) /* Collect Mesh UVs */ BLI_assert(CustomData_has_layer(&me->ldata, CD_PROP_FLOAT2)); float2 *mloopuv = static_cast( - CustomData_get_layer_n(&me->ldata, CD_PROP_FLOAT2, layernum)); + CustomData_get_layer_n_for_write(&me->ldata, CD_PROP_FLOAT2, layernum, me->totloop)); const MPoly *polys = BKE_mesh_polys(me); for (int i = 0; i < me->totpoly; i++) { @@ -302,7 +302,8 @@ int ED_mesh_uv_add( CustomData_add_layer_named(&me->ldata, CD_PROP_FLOAT2, CD_DUPLICATE, - CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2), + const_cast(static_cast( + CustomData_get_layer(&me->ldata, CD_PROP_FLOAT2))), me->totloop, unique_name); @@ -364,8 +365,8 @@ const bool *ED_mesh_uv_map_pin_layer_get(const Mesh *mesh, const int uv_index) static bool *ensure_corner_boolean_attribute(Mesh &mesh, const blender::StringRefNull name) { - bool *data = static_cast(CustomData_duplicate_referenced_layer_named( - &mesh.ldata, CD_PROP_BOOL, name.c_str(), mesh.totloop)); + bool *data = static_cast( + CustomData_get_layer_named_for_write(&mesh.ldata, CD_PROP_BOOL, name.c_str(), mesh.totloop)); if (!data) { data = static_cast(CustomData_add_layer_named( &mesh.ldata, CD_PROP_BOOL, CD_SET_DEFAULT, nullptr, mesh.totpoly, name.c_str())); diff --git a/source/blender/editors/mesh/meshtools.cc b/source/blender/editors/mesh/meshtools.cc index a5e61cb8b33..b2cbb8c47ea 100644 --- a/source/blender/editors/mesh/meshtools.cc +++ b/source/blender/editors/mesh/meshtools.cc @@ -108,9 +108,10 @@ static void join_mesh_single(Depsgraph *depsgraph, CustomData_copy_data_named(&me->vdata, vdata, 0, *vertofs, me->totvert); /* vertex groups */ - MDeformVert *dvert = (MDeformVert *)CustomData_get(vdata, *vertofs, CD_MDEFORMVERT); - const MDeformVert *dvert_src = (const MDeformVert *)CustomData_get( - &me->vdata, 0, CD_MDEFORMVERT); + MDeformVert *dvert = (MDeformVert *)CustomData_get_for_write( + vdata, *vertofs, CD_MDEFORMVERT, totvert); + const MDeformVert *dvert_src = (const MDeformVert *)CustomData_get_layer(&me->vdata, + CD_MDEFORMVERT); /* Remap to correct new vgroup indices, if needed. */ if (dvert_src) { @@ -254,7 +255,7 @@ static void join_mesh_single(Depsgraph *depsgraph, /* Apply matmap. In case we don't have material indices yet, create them if more than one * material is the result of joining. */ int *material_indices = static_cast( - CustomData_get_layer_named(pdata, CD_PROP_INT32, "material_index")); + CustomData_get_layer_named_for_write(pdata, CD_PROP_INT32, "material_index", totpoly)); if (!material_indices && totcol > 1) { material_indices = (int *)CustomData_add_layer_named( pdata, CD_PROP_INT32, CD_SET_DEFAULT, nullptr, totpoly, "material_index"); @@ -270,8 +271,9 @@ static void join_mesh_single(Depsgraph *depsgraph, } /* Face maps. */ - int *fmap = (int *)CustomData_get(pdata, *polyofs, CD_FACEMAP); - const int *fmap_src = (const int *)CustomData_get(&me->pdata, 0, CD_FACEMAP); + int *fmap = (int *)CustomData_get_for_write(pdata, *polyofs, CD_FACEMAP, totpoly); + const int *fmap_src = (const int *)CustomData_get_for_write( + &me->pdata, 0, CD_FACEMAP, me->totpoly); /* Remap to correct new face-map indices, if needed. */ if (fmap_src) { @@ -300,14 +302,14 @@ static void join_mesh_single(Depsgraph *depsgraph, /* Face Sets IDs are a sparse sequence, so this function offsets all the IDs by face_set_offset and * updates face_set_offset with the maximum ID value. This way, when used in multiple meshes, all * of them will have different IDs for their Face Sets. */ -static void mesh_join_offset_face_sets_ID(const Mesh *mesh, int *face_set_offset) +static void mesh_join_offset_face_sets_ID(Mesh *mesh, int *face_set_offset) { if (!mesh->totpoly) { return; } - int *face_sets = (int *)CustomData_get_layer_named( - &mesh->pdata, CD_PROP_INT32, ".sculpt_face_set"); + int *face_sets = (int *)CustomData_get_layer_named_for_write( + &mesh->pdata, CD_PROP_INT32, ".sculpt_face_set", mesh->totpoly); if (!face_sets) { return; } diff --git a/source/blender/editors/object/object_facemap_ops.c b/source/blender/editors/object/object_facemap_ops.c index 4364375a4e3..23344c38a12 100644 --- a/source/blender/editors/object/object_facemap_ops.c +++ b/source/blender/editors/object/object_facemap_ops.c @@ -52,7 +52,7 @@ void ED_object_facemap_face_add(Object *ob, bFaceMap *fmap, int facenum) Mesh *me = ob->data; /* if there's is no facemap layer then create one */ - if ((facemap = CustomData_get_layer(&me->pdata, CD_FACEMAP)) == NULL) { + if ((facemap = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly)) == NULL) { facemap = CustomData_add_layer(&me->pdata, CD_FACEMAP, CD_SET_DEFAULT, NULL, me->totpoly); } @@ -74,7 +74,7 @@ void ED_object_facemap_face_remove(Object *ob, bFaceMap *fmap, int facenum) int *facemap; Mesh *me = ob->data; - if ((facemap = CustomData_get_layer(&me->pdata, CD_FACEMAP)) == NULL) { + if ((facemap = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly)) == NULL) { return; } @@ -117,7 +117,7 @@ static void object_fmap_remap_object_mode(Object *ob, const int *remap) Mesh *me = ob->data; if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) { - int *map = CustomData_get_layer(&me->pdata, CD_FACEMAP); + int *map = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly); if (map) { for (int i = 0; i < me->totpoly; i++) { if (map[i] != -1) { diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 57d62b3a95b..1bfd156b664 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -2900,7 +2900,7 @@ static Object *modifier_skin_armature_create(Depsgraph *depsgraph, Main *bmain, arm->edbo = MEM_cnew("edbo armature"); MVertSkin *mvert_skin = static_cast( - CustomData_get_layer(&me->vdata, CD_MVERT_SKIN)); + CustomData_get_layer_for_write(&me->vdata, CD_MVERT_SKIN, me->totvert)); int *emap_mem; MeshElemMap *emap; BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me_edges.data(), me->totvert, me->totedge); diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index 09fcbef2180..1ec93d3a713 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -77,7 +77,8 @@ static void partialvis_update_mesh(Object *ob, const int *vert_indices = BKE_pbvh_node_get_vert_indices(node); paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK); - bool *hide_vert = CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".hide_vert"); + bool *hide_vert = CustomData_get_layer_named_for_write( + &me->vdata, CD_PROP_BOOL, ".hide_vert", me->totvert); if (hide_vert == NULL) { hide_vert = CustomData_add_layer_named( &me->vdata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, me->totvert, ".hide_vert"); diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 3ebd5fe799d..c6ffee8ba46 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -1408,7 +1408,8 @@ static void sculpt_gesture_trim_end(bContext *UNUSED(C), SculptGestureContext *s SculptSession *ss = object->sculpt; Mesh *mesh = (Mesh *)object->data; - ss->face_sets = CustomData_get_layer_named(&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set"); + ss->face_sets = CustomData_get_layer_named_for_write( + &mesh->pdata, CD_PROP_INT32, ".sculpt_face_set", mesh->totpoly); if (ss->face_sets) { /* Assign a new Face Set ID to the new faces created by the trim operation. */ const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(object->data); diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c index 192a4545e94..56ae10ef791 100644 --- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c +++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c @@ -173,7 +173,8 @@ static void SCULPT_dynamic_topology_disable_ex( me->face_sets_color_default = 1; /* Sync the visibility to vertices manually as the pmap is still not initialized. */ - bool *hide_vert = (bool *)CustomData_get_layer_named(&me->vdata, CD_PROP_BOOL, ".hide_vert"); + bool *hide_vert = (bool *)CustomData_get_layer_named_for_write( + &me->vdata, CD_PROP_BOOL, ".hide_vert", me->totvert); if (hide_vert != NULL) { memset(hide_vert, 0, sizeof(bool) * me->totvert); } diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.cc b/source/blender/editors/sculpt_paint/sculpt_face_set.cc index d2e20b33f6c..9c2d6a78fab 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.cc +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.cc @@ -74,8 +74,8 @@ int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh) void ED_sculpt_face_sets_initialize_none_to_id(struct Mesh *mesh, const int new_id) { - int *face_sets = static_cast( - CustomData_get_layer_named(&mesh->pdata, CD_PROP_INT32, ".sculpt_face_set")); + int *face_sets = static_cast(CustomData_get_layer_named_for_write( + &mesh->pdata, CD_PROP_INT32, ".sculpt_face_set", mesh->totpoly)); if (!face_sets) { return; } diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 0752b1a7b91..1529c943963 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -421,12 +421,14 @@ void BlenderFileLoader::insertShapeNode(Object *ob, Mesh *me, int id) const float(*lnors)[3] = nullptr; if (CustomData_has_layer(&me->ldata, CD_NORMAL)) { - lnors = (float(*)[3])CustomData_get_layer(&me->ldata, CD_NORMAL); + lnors = (const float(*)[3])CustomData_get_layer(&me->ldata, CD_NORMAL); } // Get other mesh data - const FreestyleEdge *fed = (FreestyleEdge *)CustomData_get_layer(&me->edata, CD_FREESTYLE_EDGE); - const FreestyleFace *ffa = (FreestyleFace *)CustomData_get_layer(&me->pdata, CD_FREESTYLE_FACE); + const FreestyleEdge *fed = (const FreestyleEdge *)CustomData_get_layer(&me->edata, + CD_FREESTYLE_EDGE); + const FreestyleFace *ffa = (const FreestyleFace *)CustomData_get_layer(&me->pdata, + CD_FREESTYLE_FACE); // Compute view matrix Object *ob_camera_eval = DEG_get_evaluated_object(_depsgraph, RE_GetCamera(_re)); diff --git a/source/blender/geometry/intern/mesh_split_edges.cc b/source/blender/geometry/intern/mesh_split_edges.cc index f5470ec225c..91b28652bbe 100644 --- a/source/blender/geometry/intern/mesh_split_edges.cc +++ b/source/blender/geometry/intern/mesh_split_edges.cc @@ -49,10 +49,12 @@ static void add_new_vertices(Mesh &mesh, const Span new_to_old_verts_map) attribute.finish(); } - if (float3 *orco = static_cast(CustomData_get_layer(&mesh.vdata, CD_ORCO))) { + if (float3 *orco = static_cast( + CustomData_get_layer_for_write(&mesh.vdata, CD_ORCO, mesh.totvert))) { copy_to_new_verts({orco, mesh.totvert}, new_to_old_verts_map); } - if (int *orig_indices = static_cast(CustomData_get_layer(&mesh.vdata, CD_ORIGINDEX))) { + if (int *orig_indices = static_cast( + CustomData_get_layer_for_write(&mesh.vdata, CD_ORIGINDEX, mesh.totvert))) { copy_to_new_verts({orig_indices, mesh.totvert}, new_to_old_verts_map); } } diff --git a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc index 49042db50ba..dea62de94f6 100644 --- a/source/blender/gpu/intern/gpu_shader_builder_stubs.cc +++ b/source/blender/gpu/intern/gpu_shader_builder_stubs.cc @@ -208,18 +208,6 @@ bool CustomData_has_layer(const struct CustomData * /*data*/, int /*type*/) return false; } -void *CustomData_get_layer_named(const struct CustomData * /*data*/, - int /*type*/, - const char * /*name*/) -{ - return nullptr; -} - -void *CustomData_get_layer(const struct CustomData * /*data*/, int /*type*/) -{ - return nullptr; -} - /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/io/alembic/exporter/abc_writer_hair.cc b/source/blender/io/alembic/exporter/abc_writer_hair.cc index e4c61a7cb68..1675750cda1 100644 --- a/source/blender/io/alembic/exporter/abc_writer_hair.cc +++ b/source/blender/io/alembic/exporter/abc_writer_hair.cc @@ -120,8 +120,9 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context, float inv_mat[4][4]; invert_m4_m4_safe(inv_mat, context.object->object_to_world); - MTFace *mtface = (MTFace *)CustomData_get_layer(&mesh->fdata, CD_MTFACE); - MFace *mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + MTFace *mtface = (MTFace *)CustomData_get_layer_for_write( + &mesh->fdata, CD_MTFACE, mesh->totface); + const MFace *mface = (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); @@ -153,7 +154,7 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context, if (num < mesh->totface) { /* TODO(Sybren): check whether the NULL check here and if(mface) are actually required */ - MFace *face = mface == nullptr ? nullptr : &mface[num]; + const MFace *face = mface == nullptr ? nullptr : &mface[num]; MTFace *tface = mtface + num; if (mface) { @@ -189,8 +190,8 @@ void ABCHairWriter::write_hair_sample(const HierarchyContext &context, /* iterate over all faces to find a corresponding underlying UV */ for (int n = 0; n < mesh->totface; n++) { - MFace *face = &mface[n]; - MTFace *tface = mtface + n; + const MFace *face = &mface[n]; + const MTFace *tface = mtface + n; uint vtx[4]; vtx[0] = face->v1; vtx[1] = face->v2; @@ -244,8 +245,9 @@ void ABCHairWriter::write_hair_child_sample(const HierarchyContext &context, float inv_mat[4][4]; invert_m4_m4_safe(inv_mat, context.object->object_to_world); - MFace *mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); - MTFace *mtface = (MTFace *)CustomData_get_layer(&mesh->fdata, CD_MTFACE); + const MFace *mface = (const MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + MTFace *mtface = (MTFace *)CustomData_get_layer_for_write( + &mesh->fdata, CD_MTFACE, mesh->totface); const float(*positions)[3] = BKE_mesh_vert_positions(mesh); const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); @@ -271,7 +273,7 @@ void ABCHairWriter::write_hair_child_sample(const HierarchyContext &context, continue; } - MFace *face = &mface[num]; + const MFace *face = &mface[num]; MTFace *tface = mtface + num; float r_uv[2], tmpnor[3], mapfw[4], vec[3]; diff --git a/source/blender/io/alembic/intern/abc_customdata.cc b/source/blender/io/alembic/intern/abc_customdata.cc index 035f49325c4..9e5182c53d4 100644 --- a/source/blender/io/alembic/intern/abc_customdata.cc +++ b/source/blender/io/alembic/intern/abc_customdata.cc @@ -535,7 +535,7 @@ void read_generated_coordinates(const ICompoundProperty &prop, void *cd_data; if (CustomData_has_layer(&mesh->vdata, CD_ORCO)) { - cd_data = CustomData_get_layer(&mesh->vdata, CD_ORCO); + cd_data = CustomData_get_layer_for_write(&mesh->vdata, CD_ORCO, mesh->totvert); } else { cd_data = CustomData_add_layer(&mesh->vdata, CD_ORCO, CD_CONSTRUCT, nullptr, totvert); diff --git a/source/blender/io/alembic/intern/abc_reader_mesh.cc b/source/blender/io/alembic/intern/abc_reader_mesh.cc index 53204fc3e47..11fb191b31c 100644 --- a/source/blender/io/alembic/intern/abc_reader_mesh.cc +++ b/source/blender/io/alembic/intern/abc_reader_mesh.cc @@ -383,7 +383,8 @@ static void *add_customdata_cb(Mesh *mesh, const char *name, int data_type) return nullptr; } - void *cd_ptr = CustomData_get_layer_named(&mesh->ldata, cd_data_type, name); + void *cd_ptr = CustomData_get_layer_named_for_write( + &mesh->ldata, cd_data_type, name, mesh->totloop); if (cd_ptr != nullptr) { /* layer already exists, so just return it. */ return cd_ptr; diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp index 0c8bd29a3c9..aa29bfc3343 100644 --- a/source/blender/io/collada/MeshImporter.cpp +++ b/source/blender/io/collada/MeshImporter.cpp @@ -719,8 +719,9 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, uvset_index++) { /* get mtface by face index and uv set index */ COLLADAFW::IndexList &index_list = *index_list_array_uvcoord[uvset_index]; - blender::float2 *mloopuv = static_cast(CustomData_get_layer_named( - &me->ldata, CD_PROP_FLOAT2, index_list.getName().c_str())); + blender::float2 *mloopuv = static_cast( + CustomData_get_layer_named_for_write( + &me->ldata, CD_PROP_FLOAT2, index_list.getName().c_str(), me->totloop)); if (mloopuv == nullptr) { fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to TEXCOORD [#%s].\n", @@ -762,8 +763,8 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, COLLADAFW::IndexList &color_index_list = *mp->getColorIndices(vcolor_index); COLLADAFW::String colname = extract_vcolname(color_index_list.getName()); - MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_named( - &me->ldata, CD_PROP_BYTE_COLOR, colname.c_str()); + MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_named_for_write( + &me->ldata, CD_PROP_BYTE_COLOR, colname.c_str(), me->totloop); if (mloopcol == nullptr) { fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to VCOLOR [#%s].\n", diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index b88874e57c3..f961fa64a05 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -204,7 +204,7 @@ static void *add_customdata_cb(Mesh *mesh, const char *name, const int data_type } loopdata = &mesh->ldata; - cd_ptr = CustomData_get_layer_named(loopdata, cd_data_type, name); + cd_ptr = CustomData_get_layer_named_for_write(loopdata, cd_data_type, name, mesh->totloop); if (cd_ptr != nullptr) { /* layer already exists, so just return it. */ return cd_ptr; diff --git a/source/blender/makesrna/intern/rna_curves.c b/source/blender/makesrna/intern/rna_curves.c index f19f632519f..11114f298a9 100644 --- a/source/blender/makesrna/intern/rna_curves.c +++ b/source/blender/makesrna/intern/rna_curves.c @@ -77,8 +77,8 @@ static void rna_Curves_curve_offset_data_begin(CollectionPropertyIterator *iter, static float (*get_curves_positions(Curves *curves))[3] { - return (float(*)[3])CustomData_get_layer_named( - &curves->geometry.point_data, CD_PROP_FLOAT3, "position"); + return (float(*)[3])CustomData_get_layer_named_for_write( + &curves->geometry.point_data, CD_PROP_FLOAT3, "position", curves->geometry.point_num); } static const float (*get_curves_positions_const(const Curves *curves))[3] @@ -152,9 +152,9 @@ static float rna_CurvePoint_radius_get(PointerRNA *ptr) static void rna_CurvePoint_radius_set(PointerRNA *ptr, float value) { - const Curves *curves = rna_curves(ptr); - float *radii = (float *)CustomData_get_layer_named( - &curves->geometry.point_data, CD_PROP_FLOAT, "radius"); + Curves *curves = rna_curves(ptr); + float *radii = (float *)CustomData_get_layer_named_for_write( + &curves->geometry.point_data, CD_PROP_FLOAT, "radius", curves->geometry.point_num); if (radii == NULL) { return; } @@ -212,8 +212,7 @@ static void rna_CurveSlice_points_begin(CollectionPropertyIterator *iter, Pointe Curves *curves = rna_curves(ptr); const int offset = rna_CurveSlice_first_point_index_get(ptr); const int size = rna_CurveSlice_points_length_get(ptr); - float(*positions)[3] = (float(*)[3])CustomData_get_layer_named( - &curves->geometry.point_data, CD_PROP_FLOAT3, "position"); + float(*positions)[3] = get_curves_positions(curves); float(*co)[3] = positions + offset; rna_iterator_array_begin(iter, co, sizeof(float[3]), size, 0, NULL); } diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index e1e75d25157..6791a171e8e 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -469,7 +469,7 @@ static bool rna_MeshVertex_hide_get(PointerRNA *ptr) static void rna_MeshVertex_hide_set(PointerRNA *ptr, bool value) { Mesh *mesh = rna_mesh(ptr); - bool *hide_vert = (bool *)CustomData_duplicate_referenced_layer_named( + bool *hide_vert = (bool *)CustomData_get_layer_named_for_write( &mesh->vdata, CD_PROP_BOOL, ".hide_vert", mesh->totvert); if (!hide_vert) { if (!value) { @@ -495,7 +495,7 @@ static bool rna_MeshVertex_select_get(PointerRNA *ptr) static void rna_MeshVertex_select_set(PointerRNA *ptr, bool value) { Mesh *mesh = rna_mesh(ptr); - bool *select_vert = (bool *)CustomData_duplicate_referenced_layer_named( + bool *select_vert = (bool *)CustomData_get_layer_named_for_write( &mesh->vdata, CD_PROP_BOOL, ".select_vert", mesh->totvert); if (!select_vert) { if (!value) { @@ -564,13 +564,13 @@ static void rna_MeshLoop_normal_get(PointerRNA *ptr, float *values) { Mesh *me = rna_mesh(ptr); const int index = rna_MeshLoop_index_get(ptr); - const float(*vec)[3] = CustomData_get(&me->ldata, index, CD_NORMAL); + const float(*layer)[3] = CustomData_get_layer(&me->ldata, CD_NORMAL); - if (!vec) { + if (!layer) { zero_v3(values); } else { - copy_v3_v3(values, (const float *)vec); + copy_v3_v3(values, layer[index]); } } @@ -578,10 +578,10 @@ static void rna_MeshLoop_normal_set(PointerRNA *ptr, const float *values) { Mesh *me = rna_mesh(ptr); const int index = rna_MeshLoop_index_get(ptr); - float(*vec)[3] = CustomData_get(&me->ldata, index, CD_NORMAL); + float(*layer)[3] = CustomData_get_layer_for_write(&me->ldata, CD_NORMAL, me->totloop); - if (vec) { - normalize_v3_v3(*vec, values); + if (layer) { + normalize_v3_v3(*layer, values + index); } } @@ -589,13 +589,13 @@ static void rna_MeshLoop_tangent_get(PointerRNA *ptr, float *values) { Mesh *me = rna_mesh(ptr); const int index = rna_MeshLoop_index_get(ptr); - const float(*vec)[4] = CustomData_get(&me->ldata, index, CD_MLOOPTANGENT); + const float(*layer)[4] = CustomData_get_layer(&me->ldata, CD_MLOOPTANGENT); - if (!vec) { + if (!layer) { zero_v3(values); } else { - copy_v3_v3(values, (const float *)vec); + copy_v3_v3(values, (const float *)(layer + index)); } } @@ -603,21 +603,21 @@ static float rna_MeshLoop_bitangent_sign_get(PointerRNA *ptr) { Mesh *me = rna_mesh(ptr); const int index = rna_MeshLoop_index_get(ptr); - const float(*vec)[4] = CustomData_get(&me->ldata, index, CD_MLOOPTANGENT); + const float(*vec)[4] = CustomData_get_layer(&me->ldata, CD_MLOOPTANGENT); - return (vec) ? (*vec)[3] : 0.0f; + return (vec) ? vec[index][3] : 0.0f; } static void rna_MeshLoop_bitangent_get(PointerRNA *ptr, float *values) { Mesh *me = rna_mesh(ptr); const int index = rna_MeshLoop_index_get(ptr); - const float(*nor)[3] = CustomData_get(&me->ldata, index, CD_NORMAL); - const float(*vec)[4] = CustomData_get(&me->ldata, index, CD_MLOOPTANGENT); + const float(*nor)[3] = CustomData_get_layer(&me->ldata, CD_NORMAL); + const float(*vec)[4] = CustomData_get_layer(&me->ldata, CD_MLOOPTANGENT); if (nor && vec) { - cross_v3_v3v3(values, (const float *)nor, (const float *)vec); - mul_v3_fl(values, (*vec)[3]); + cross_v3_v3v3(values, nor[index], vec[index]); + mul_v3_fl(values, vec[index][3]); } else { zero_v3(values); @@ -645,7 +645,7 @@ static bool rna_MeshPolygon_hide_get(PointerRNA *ptr) static void rna_MeshPolygon_hide_set(PointerRNA *ptr, bool value) { Mesh *mesh = rna_mesh(ptr); - bool *hide_poly = (bool *)CustomData_duplicate_referenced_layer_named( + bool *hide_poly = (bool *)CustomData_get_layer_named_for_write( &mesh->pdata, CD_PROP_BOOL, ".hide_poly", mesh->totpoly); if (!hide_poly) { if (!value) { @@ -671,7 +671,7 @@ static bool rna_MeshPolygon_select_get(PointerRNA *ptr) static void rna_MeshPolygon_select_set(PointerRNA *ptr, bool value) { Mesh *mesh = rna_mesh(ptr); - bool *select_poly = (bool *)CustomData_duplicate_referenced_layer_named( + bool *select_poly = (bool *)CustomData_get_layer_named_for_write( &mesh->pdata, CD_PROP_BOOL, ".select_poly", mesh->totpoly); if (!select_poly) { if (!value) { @@ -723,7 +723,7 @@ static void rna_MeshPolygon_flip(ID *id, MPoly *mp) { Mesh *me = (Mesh *)id; MLoop *loops = BKE_mesh_loops_for_write(me); - BKE_mesh_polygon_flip(mp, loops, &me->ldata); + BKE_mesh_polygon_flip(mp, loops, &me->ldata, me->totloop); BKE_mesh_tessface_clear(me); BKE_mesh_runtime_clear_geometry(me); } @@ -914,25 +914,25 @@ static bool rna_MEdge_freestyle_edge_mark_get(PointerRNA *ptr) { const Mesh *me = rna_mesh(ptr); const int index = rna_MeshEdge_index_get(ptr); - const FreestyleEdge *fed = CustomData_get(&me->edata, index, CD_FREESTYLE_EDGE); + const FreestyleEdge *fed = CustomData_get_layer(&me->edata, CD_FREESTYLE_EDGE); - return fed && (fed->flag & FREESTYLE_EDGE_MARK) != 0; + return fed && (fed[index].flag & FREESTYLE_EDGE_MARK) != 0; } static void rna_MEdge_freestyle_edge_mark_set(PointerRNA *ptr, bool value) { Mesh *me = rna_mesh(ptr); const int index = rna_MeshEdge_index_get(ptr); - FreestyleEdge *fed = CustomData_get(&me->edata, index, CD_FREESTYLE_EDGE); + FreestyleEdge *fed = CustomData_get_layer_for_write(&me->edata, CD_FREESTYLE_EDGE, me->totedge); if (!fed) { fed = CustomData_add_layer(&me->edata, CD_FREESTYLE_EDGE, CD_SET_DEFAULT, NULL, me->totedge); } if (value) { - fed->flag |= FREESTYLE_EDGE_MARK; + fed[index].flag |= FREESTYLE_EDGE_MARK; } else { - fed->flag &= ~FREESTYLE_EDGE_MARK; + fed[index].flag &= ~FREESTYLE_EDGE_MARK; } } @@ -940,25 +940,25 @@ static bool rna_MPoly_freestyle_face_mark_get(PointerRNA *ptr) { const Mesh *me = rna_mesh(ptr); const int index = rna_MeshPolygon_index_get(ptr); - const FreestyleFace *ffa = CustomData_get(&me->pdata, index, CD_FREESTYLE_FACE); + const FreestyleFace *ffa = CustomData_get_layer(&me->pdata, CD_FREESTYLE_FACE); - return ffa && (ffa->flag & FREESTYLE_FACE_MARK) != 0; + return ffa && (ffa[index].flag & FREESTYLE_FACE_MARK) != 0; } static void rna_MPoly_freestyle_face_mark_set(PointerRNA *ptr, bool value) { Mesh *me = rna_mesh(ptr); const int index = rna_MeshPolygon_index_get(ptr); - FreestyleFace *ffa = CustomData_get(&me->pdata, index, CD_FREESTYLE_FACE); + FreestyleFace *ffa = CustomData_get_layer_for_write(&me->pdata, CD_FREESTYLE_FACE, me->totpoly); if (!ffa) { ffa = CustomData_add_layer(&me->pdata, CD_FREESTYLE_FACE, CD_SET_DEFAULT, NULL, me->totpoly); } if (value) { - ffa->flag |= FREESTYLE_FACE_MARK; + ffa[index].flag |= FREESTYLE_FACE_MARK; } else { - ffa->flag &= ~FREESTYLE_FACE_MARK; + ffa[index].flag &= ~FREESTYLE_FACE_MARK; } } @@ -1466,7 +1466,7 @@ static bool rna_MeshEdge_hide_get(PointerRNA *ptr) static void rna_MeshEdge_hide_set(PointerRNA *ptr, bool value) { Mesh *mesh = rna_mesh(ptr); - bool *hide_edge = (bool *)CustomData_duplicate_referenced_layer_named( + bool *hide_edge = (bool *)CustomData_get_layer_named_for_write( &mesh->edata, CD_PROP_BOOL, ".hide_edge", mesh->totedge); if (!hide_edge) { if (!value) { @@ -1492,7 +1492,7 @@ static bool rna_MeshEdge_select_get(PointerRNA *ptr) static void rna_MeshEdge_select_set(PointerRNA *ptr, bool value) { Mesh *mesh = rna_mesh(ptr); - bool *select_edge = (bool *)CustomData_duplicate_referenced_layer_named( + bool *select_edge = (bool *)CustomData_get_layer_named_for_write( &mesh->edata, CD_PROP_BOOL, ".select_edge", mesh->totedge); if (!select_edge) { if (!value) { @@ -1518,7 +1518,7 @@ static bool rna_MeshEdge_use_edge_sharp_get(PointerRNA *ptr) static void rna_MeshEdge_use_edge_sharp_set(PointerRNA *ptr, bool value) { Mesh *mesh = rna_mesh(ptr); - bool *sharp_edge = (bool *)CustomData_duplicate_referenced_layer_named( + bool *sharp_edge = (bool *)CustomData_get_layer_named_for_write( &mesh->edata, CD_PROP_BOOL, "sharp_edge", mesh->totedge); if (!sharp_edge) { if (!value) { @@ -1852,7 +1852,7 @@ static bool get_uv_index_and_layer(const PointerRNA *ptr, /* We don't know from which attribute the RNA pointer is from, so we need to scan them all. */ const int uv_layers_num = CustomData_number_of_layers(&mesh->ldata, CD_PROP_FLOAT2); for (int layer_i = 0; layer_i < uv_layers_num; layer_i++) { - const float(*layer_data)[2] = (float(*)[2])CustomData_get_layer_n( + const float(*layer_data)[2] = (const float(*)[2])CustomData_get_layer_n( &mesh->ldata, CD_PROP_FLOAT2, layer_i); const ptrdiff_t index = uv_coord - layer_data; if (index >= 0 && index < mesh->totloop) { diff --git a/source/blender/makesrna/intern/rna_mesh_api.c b/source/blender/makesrna/intern/rna_mesh_api.c index b36b14b95a4..12b9c805701 100644 --- a/source/blender/makesrna/intern/rna_mesh_api.c +++ b/source/blender/makesrna/intern/rna_mesh_api.c @@ -60,7 +60,7 @@ static void rna_Mesh_calc_tangents(Mesh *mesh, ReportList *reports, const char * float(*r_looptangents)[4]; if (CustomData_has_layer(&mesh->ldata, CD_MLOOPTANGENT)) { - r_looptangents = CustomData_get_layer(&mesh->ldata, CD_MLOOPTANGENT); + r_looptangents = CustomData_get_layer_for_write(&mesh->ldata, CD_MLOOPTANGENT, mesh->totloop); memset(r_looptangents, 0, sizeof(float[4]) * mesh->totloop); } else { diff --git a/source/blender/makesrna/intern/rna_pointcloud.c b/source/blender/makesrna/intern/rna_pointcloud.c index 904d011fa04..49317857441 100644 --- a/source/blender/makesrna/intern/rna_pointcloud.c +++ b/source/blender/makesrna/intern/rna_pointcloud.c @@ -35,7 +35,8 @@ static PointCloud *rna_pointcloud(const PointerRNA *ptr) static float (*get_pointcloud_positions(PointCloud *pointcloud))[3] { - return (float(*)[3])CustomData_get_layer_named(&pointcloud->pdata, CD_PROP_FLOAT3, "position"); + return (float(*)[3])CustomData_get_layer_named_for_write( + &pointcloud->pdata, CD_PROP_FLOAT3, "position", pointcloud->totpoint); } static const float (*get_pointcloud_positions_const(const PointCloud *pointcloud))[3] @@ -110,7 +111,8 @@ static float rna_Point_radius_get(PointerRNA *ptr) static void rna_Point_radius_set(PointerRNA *ptr, float value) { PointCloud *pointcloud = rna_pointcloud(ptr); - float *radii = (float *)CustomData_get_layer_named(&pointcloud->pdata, CD_PROP_FLOAT, "radius"); + float *radii = (float *)CustomData_get_layer_named_for_write( + &pointcloud->pdata, CD_PROP_FLOAT, "radius", pointcloud->totpoint); if (radii == NULL) { return; } diff --git a/source/blender/modifiers/intern/MOD_array.cc b/source/blender/modifiers/intern/MOD_array.cc index 665ed094631..6c15994e865 100644 --- a/source/blender/modifiers/intern/MOD_array.cc +++ b/source/blender/modifiers/intern/MOD_array.cc @@ -329,22 +329,26 @@ static void mesh_merge_transform(Mesh *result, } /* Set #CD_ORIGINDEX. */ - index_orig = static_cast(CustomData_get_layer(&result->vdata, CD_ORIGINDEX)); + index_orig = static_cast( + CustomData_get_layer_for_write(&result->vdata, CD_ORIGINDEX, result->totvert)); if (index_orig) { copy_vn_i(index_orig + cap_verts_index, cap_nverts, ORIGINDEX_NONE); } - index_orig = static_cast(CustomData_get_layer(&result->edata, CD_ORIGINDEX)); + index_orig = static_cast( + CustomData_get_layer_for_write(&result->edata, CD_ORIGINDEX, result->totedge)); if (index_orig) { copy_vn_i(index_orig + cap_edges_index, cap_nedges, ORIGINDEX_NONE); } - index_orig = static_cast(CustomData_get_layer(&result->pdata, CD_ORIGINDEX)); + index_orig = static_cast( + CustomData_get_layer_for_write(&result->pdata, CD_ORIGINDEX, result->totpoly)); if (index_orig) { copy_vn_i(index_orig + cap_polys_index, cap_npolys, ORIGINDEX_NONE); } - index_orig = static_cast(CustomData_get_layer(&result->ldata, CD_ORIGINDEX)); + index_orig = static_cast( + CustomData_get_layer_for_write(&result->ldata, CD_ORIGINDEX, result->totloop)); if (index_orig) { copy_vn_i(index_orig + cap_loops_index, cap_nloops, ORIGINDEX_NONE); } @@ -663,7 +667,7 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd, const int totuv = CustomData_number_of_layers(&result->ldata, CD_PROP_FLOAT2); for (i = 0; i < totuv; i++) { blender::float2 *dmloopuv = static_cast( - CustomData_get_layer_n(&result->ldata, CD_PROP_FLOAT2, i)); + CustomData_get_layer_n_for_write(&result->ldata, CD_PROP_FLOAT2, i, result->totloop)); dmloopuv += chunk_nloops; for (c = 1; c < count; c++) { const float uv_offset[2] = { diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c index dcb4803b08a..379ed32fce5 100644 --- a/source/blender/modifiers/intern/MOD_cloth.c +++ b/source/blender/modifiers/intern/MOD_cloth.c @@ -113,7 +113,8 @@ static void deformVerts(ModifierData *md, clmd->sim_parms->shapekey_rest); if (kb && kb->data != NULL) { float(*layerorco)[3]; - if (!(layerorco = CustomData_get_layer(&mesh_src->vdata, CD_CLOTH_ORCO))) { + if (!(layerorco = CustomData_get_layer_for_write( + &mesh_src->vdata, CD_CLOTH_ORCO, mesh_src->totvert))) { layerorco = CustomData_add_layer( &mesh_src->vdata, CD_CLOTH_ORCO, CD_SET_DEFAULT, NULL, mesh_src->totvert); } diff --git a/source/blender/modifiers/intern/MOD_displace.cc b/source/blender/modifiers/intern/MOD_displace.cc index 402752610eb..304c4be3e02 100644 --- a/source/blender/modifiers/intern/MOD_displace.cc +++ b/source/blender/modifiers/intern/MOD_displace.cc @@ -307,7 +307,8 @@ static void displaceModifier_do(DisplaceModifierData *dmd, BKE_mesh_calc_normals_split(mesh); } - float(*clnors)[3] = static_cast(CustomData_get_layer(ldata, CD_NORMAL)); + float(*clnors)[3] = static_cast( + CustomData_get_layer_for_write(ldata, CD_NORMAL, mesh->totloop)); vert_clnors = static_cast( MEM_malloc_arrayN(verts_num, sizeof(*vert_clnors), __func__)); BKE_mesh_normals_loop_to_vertex( diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 819ffbba26d..9dcbb1f16a0 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -100,7 +100,7 @@ static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *p const bool invert_vgroup = (emd->flag & eExplodeFlag_INVERT_VGROUP) != 0; float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); - mface = (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE); + mface = (MFace *)CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface); totvert = mesh->totvert; totface = mesh->totface; totpart = psmd->psys->totpart; @@ -215,7 +215,7 @@ static const short add_faces[24] = { static MFace *get_dface(Mesh *mesh, Mesh *split, int cur, int i, MFace *mf) { - MFace *mfaces = CustomData_get_layer(&split->fdata, CD_MFACE); + MFace *mfaces = CustomData_get_layer_for_write(&split->fdata, CD_MFACE, split->totface); MFace *df = &mfaces[cur]; CustomData_copy_data(&mesh->fdata, &split->fdata, i, cur, 1); *df = *mf; @@ -284,11 +284,11 @@ static void remap_uvs_3_6_9_12( int l; for (l = 0; l < layers_num; l++) { - mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); + mf = CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface); df1 = mf + cur; df2 = df1 + 1; df3 = df1 + 2; - mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); + mf = CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface); mf += i; copy_v2_v2(df1->uv[0], mf->uv[c0]); @@ -344,10 +344,10 @@ static void remap_uvs_5_10( int l; for (l = 0; l < layers_num; l++) { - mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); + mf = CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface); df1 = mf + cur; df2 = df1 + 1; - mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); + mf = CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface); mf += i; copy_v2_v2(df1->uv[0], mf->uv[c0]); @@ -416,12 +416,12 @@ static void remap_uvs_15( int l; for (l = 0; l < layers_num; l++) { - mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); + mf = CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface); df1 = mf + cur; df2 = df1 + 1; df3 = df1 + 2; df4 = df1 + 3; - mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); + mf = CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface); mf += i; copy_v2_v2(df1->uv[0], mf->uv[c0]); @@ -492,11 +492,11 @@ static void remap_uvs_7_11_13_14( int l; for (l = 0; l < layers_num; l++) { - mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); + mf = CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface); df1 = mf + cur; df2 = df1 + 1; df3 = df1 + 2; - mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); + mf = CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface); mf += i; copy_v2_v2(df1->uv[0], mf->uv[c0]); @@ -552,10 +552,10 @@ static void remap_uvs_19_21_22( int l; for (l = 0; l < layers_num; l++) { - mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); + mf = CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface); df1 = mf + cur; df2 = df1 + 1; - mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); + mf = CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface); mf += i; copy_v2_v2(df1->uv[0], mf->uv[c0]); @@ -614,10 +614,10 @@ static void remap_uvs_23( int l; for (l = 0; l < layers_num; l++) { - mf = CustomData_get_layer_n(&split->fdata, CD_MTFACE, l); + mf = CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface); df1 = mf + cur; df2 = df1 + 1; - mf = CustomData_get_layer_n(&mesh->fdata, CD_MTFACE, l); + mf = CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface); mf += i; copy_v2_v2(df1->uv[0], mf->uv[c0]); @@ -639,7 +639,7 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) { Mesh *split_m; MFace *mf = NULL, *df1 = NULL; - MFace *mface = CustomData_get_layer(&mesh->fdata, CD_MFACE); + MFace *mface = CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface); float *dupve; EdgeHash *edgehash; EdgeHashIterator *ehi; @@ -869,7 +869,7 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) curdupface += add_faces[*fs] + 1; } - MFace *split_mface = CustomData_get_layer(&split_m->fdata, CD_MFACE); + MFace *split_mface = CustomData_get_layer_for_write(&split_m->fdata, CD_MFACE, split_m->totface); for (i = 0; i < curdupface; i++) { mf = &split_mface[i]; BKE_mesh_mface_index_validate(mf, &split_m->fdata, i, ((mf->flag & ME_FACE_SEL) ? 4 : 3)); @@ -909,7 +909,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, totface = mesh->totface; totvert = mesh->totvert; - mface = CustomData_get_layer(&mesh->fdata, CD_MFACE); + mface = CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface); totpart = psmd->psys->totpart; sim.depsgraph = ctx->depsgraph; @@ -971,7 +971,8 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, /* the final duplicated vertices */ explode = BKE_mesh_new_nomain_from_template(mesh, totdup, 0, totface - delface, 0, 0); - MTFace *mtface = CustomData_get_layer_named(&explode->fdata, CD_MTFACE, emd->uvname); + MTFace *mtface = CustomData_get_layer_named_for_write( + &explode->fdata, CD_MTFACE, emd->uvname, explode->totface); /* getting back to object space */ invert_m4_m4(imat, ctx->object->object_to_world); @@ -1029,7 +1030,8 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, BLI_edgehashIterator_free(ehi); /* Map new vertices to faces. */ - MFace *explode_mface = CustomData_get_layer(&explode->fdata, CD_MFACE); + MFace *explode_mface = CustomData_get_layer_for_write( + &explode->fdata, CD_MFACE, explode->totface); for (i = 0, u = 0; i < totface; i++) { MFace source; int orig_v4; diff --git a/source/blender/modifiers/intern/MOD_multires.cc b/source/blender/modifiers/intern/MOD_multires.cc index 8b379f8ac60..737999e6b88 100644 --- a/source/blender/modifiers/intern/MOD_multires.cc +++ b/source/blender/modifiers/intern/MOD_multires.cc @@ -261,7 +261,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * result = multires_as_mesh(mmd, ctx, mesh, subdiv); if (use_clnors) { - float(*lnors)[3] = static_cast(CustomData_get_layer(&result->ldata, CD_NORMAL)); + float(*lnors)[3] = static_cast( + CustomData_get_layer_for_write(&result->ldata, CD_NORMAL, result->totloop)); BLI_assert(lnors != nullptr); BKE_mesh_set_custom_normals(result, lnors); CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); diff --git a/source/blender/modifiers/intern/MOD_normal_edit.cc b/source/blender/modifiers/intern/MOD_normal_edit.cc index 964e62ab79d..0bf1a268577 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.cc +++ b/source/blender/modifiers/intern/MOD_normal_edit.cc @@ -177,12 +177,13 @@ static void mix_normals(const float mix_factor, static bool polygons_check_flip(MLoop *mloop, float (*nos)[3], CustomData *ldata, + const int totloop, const MPoly *mpoly, float (*poly_normals)[3], const int polys_num) { const MPoly *mp; - MDisps *mdisp = static_cast(CustomData_get_layer(ldata, CD_MDISPS)); + MDisps *mdisp = static_cast(CustomData_get_layer_for_write(ldata, CD_MDISPS, totloop)); int i; bool flipped = false; @@ -325,9 +326,13 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, loops_num); } - if (do_polynors_fix && - polygons_check_flip( - mloop, nos, &mesh->ldata, mpoly, BKE_mesh_poly_normals_for_write(mesh), polys_num)) { + if (do_polynors_fix && polygons_check_flip(mloop, + nos, + &mesh->ldata, + mesh->totloop, + mpoly, + BKE_mesh_poly_normals_for_write(mesh), + polys_num)) { /* We need to recompute vertex normals! */ BKE_mesh_normals_tag_dirty(mesh); } @@ -444,9 +449,13 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd, loops_num); } - if (do_polynors_fix && - polygons_check_flip( - mloop, nos, &mesh->ldata, mpoly, BKE_mesh_poly_normals_for_write(mesh), polys_num)) { + if (do_polynors_fix && polygons_check_flip(mloop, + nos, + &mesh->ldata, + mesh->totloop, + mpoly, + BKE_mesh_poly_normals_for_write(mesh), + polys_num)) { BKE_mesh_normals_tag_dirty(mesh); } @@ -553,10 +562,11 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd, bke::SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_span( "sharp_edge", ATTR_DOMAIN_EDGE); - short(*clnors)[2] = static_cast(CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL)); + short(*clnors)[2] = static_cast( + CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, loops_num)); if (use_current_clnors) { clnors = static_cast( - CustomData_duplicate_referenced_layer(ldata, CD_CUSTOMLOOPNORMAL, loops_num)); + CustomData_get_layer_for_write(ldata, CD_CUSTOMLOOPNORMAL, loops_num)); loop_normals = static_cast( MEM_malloc_arrayN(size_t(loops_num), sizeof(*loop_normals), __func__)); diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index e0677751a16..e3682acf84a 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -322,10 +322,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MPoly *mpoly = BKE_mesh_polys_for_write(result); MLoop *mloop = BKE_mesh_loops_for_write(result); - MLoopCol *mloopcols_index = CustomData_get_layer_named( - &result->ldata, CD_PROP_BYTE_COLOR, pimd->index_layer_name); - MLoopCol *mloopcols_value = CustomData_get_layer_named( - &result->ldata, CD_PROP_BYTE_COLOR, pimd->value_layer_name); + MLoopCol *mloopcols_index = CustomData_get_layer_named_for_write( + &result->ldata, CD_PROP_BYTE_COLOR, pimd->index_layer_name, result->totloop); + MLoopCol *mloopcols_value = CustomData_get_layer_named_for_write( + &result->ldata, CD_PROP_BYTE_COLOR, pimd->value_layer_name, result->totloop); int *vert_part_index = NULL; float *vert_part_value = NULL; if (mloopcols_index != NULL) { diff --git a/source/blender/modifiers/intern/MOD_screw.cc b/source/blender/modifiers/intern/MOD_screw.cc index 82592a13faf..0f094f06bd0 100644 --- a/source/blender/modifiers/intern/MOD_screw.cc +++ b/source/blender/modifiers/intern/MOD_screw.cc @@ -394,7 +394,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * CustomData_add_layer(&result->pdata, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, int(maxPolys)); } - int *origindex = static_cast(CustomData_get_layer(&result->pdata, CD_ORIGINDEX)); + int *origindex = static_cast( + CustomData_get_layer_for_write(&result->pdata, CD_ORIGINDEX, result->totpoly)); CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, int(totvert)); @@ -406,8 +407,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * if (mloopuv_layers_tot) { uint uv_lay; for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) { - mloopuv_layers[uv_lay] = static_cast( - CustomData_get_layer_n(&result->ldata, CD_PROP_FLOAT2, int(uv_lay))); + mloopuv_layers[uv_lay] = static_cast(CustomData_get_layer_n_for_write( + &result->ldata, CD_PROP_FLOAT2, int(uv_lay), result->totloop)); } if (ltmd->flag & MOD_SCREW_UV_STRETCH_V) { diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index b7b8c9cbe53..efb8ae8616a 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -922,7 +922,8 @@ static Mesh *subdivide_base(const Mesh *orig) float(*out_vert_positions)[3] = BKE_mesh_vert_positions_for_write(result); MEdge *outedge = BKE_mesh_edges_for_write(result); - MVertSkin *outnode = CustomData_get_layer(&result->vdata, CD_MVERT_SKIN); + MVertSkin *outnode = CustomData_get_layer_for_write( + &result->vdata, CD_MVERT_SKIN, result->totvert); MDeformVert *outdvert = NULL; if (origdvert) { outdvert = BKE_mesh_deform_verts_for_write(result); @@ -1909,7 +1910,7 @@ static void skin_set_orig_indices(Mesh *mesh) static Mesh *base_skin(Mesh *origmesh, SkinModifierData *smd, eSkinErrorFlag *r_error) { Mesh *result; - MVertSkin *nodes; + const MVertSkin *nodes; BMesh *bm; EMat *emat; SkinNode *skin_nodes; diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c index 468f7af4f80..5013166cb3b 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.c +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c @@ -1042,7 +1042,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } /* add faces & edges */ - origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX); + origindex_edge = CustomData_get_layer_for_write(&result->edata, CD_ORIGINDEX, result->totedge); orig_ed = (origindex_edge) ? &origindex_edge[(edges_num * stride) + newEdges] : NULL; MEdge *ed = &medge[(edges_num * stride) + newEdges]; /* start after copied edges */ for (i = 0; i < rimVerts; i++, ed++) { diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index 41217955f85..51043ea89e3 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -1966,10 +1966,13 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, MPoly *mpoly = BKE_mesh_polys_for_write(result); MLoop *mloop = BKE_mesh_loops_for_write(result); - int *origindex_edge = CustomData_get_layer(&result->edata, CD_ORIGINDEX); - int *origindex_poly = CustomData_get_layer(&result->pdata, CD_ORIGINDEX); + int *origindex_edge = CustomData_get_layer_for_write( + &result->edata, CD_ORIGINDEX, result->totedge); + int *origindex_poly = CustomData_get_layer_for_write( + &result->pdata, CD_ORIGINDEX, result->totpoly); - float *result_edge_bweight = CustomData_get_layer(&result->edata, CD_BWEIGHT); + float *result_edge_bweight = CustomData_get_layer_for_write( + &result->edata, CD_BWEIGHT, result->totedge); if (bevel_convex != 0.0f || orig_vert_bweight != NULL) { result_edge_bweight = CustomData_add_layer( &result->edata, CD_BWEIGHT, CD_SET_DEFAULT, NULL, result->totedge); diff --git a/source/blender/modifiers/intern/MOD_subsurf.cc b/source/blender/modifiers/intern/MOD_subsurf.cc index 5e77f0ffa9e..23989e7640c 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.cc +++ b/source/blender/modifiers/intern/MOD_subsurf.cc @@ -265,7 +265,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } if (use_clnors) { - float(*lnors)[3] = static_cast(CustomData_get_layer(&result->ldata, CD_NORMAL)); + float(*lnors)[3] = static_cast( + CustomData_get_layer_for_write(&result->ldata, CD_NORMAL, result->totloop)); BLI_assert(lnors != nullptr); BKE_mesh_set_custom_normals(result, lnors); CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY); diff --git a/source/blender/modifiers/intern/MOD_triangulate.cc b/source/blender/modifiers/intern/MOD_triangulate.cc index 73ec3e25afe..3880bd8a233 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.cc +++ b/source/blender/modifiers/intern/MOD_triangulate.cc @@ -74,7 +74,8 @@ static Mesh *triangulate_mesh(Mesh *mesh, BM_mesh_free(bm); if (keep_clnors) { - float(*lnors)[3] = static_cast(CustomData_get_layer(&result->ldata, CD_NORMAL)); + float(*lnors)[3] = static_cast( + CustomData_get_layer_for_write(&result->ldata, CD_NORMAL, result->totloop)); BLI_assert(lnors != nullptr); BKE_mesh_set_custom_normals(result, lnors); diff --git a/source/blender/modifiers/intern/MOD_uvproject.cc b/source/blender/modifiers/intern/MOD_uvproject.cc index 20b5d45ebcc..1d660a05c44 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.cc +++ b/source/blender/modifiers/intern/MOD_uvproject.cc @@ -184,9 +184,8 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd, polys_num = mesh->totpoly; loops_num = mesh->totloop; - /* make sure we are not modifying the original UV map */ - float(*mloop_uv)[2] = static_cast(CustomData_duplicate_referenced_layer_named( - &mesh->ldata, CD_PROP_FLOAT2, uvname, loops_num)); + float(*mloop_uv)[2] = static_cast( + CustomData_get_layer_named_for_write(&mesh->ldata, CD_PROP_FLOAT2, uvname, loops_num)); coords = BKE_mesh_vert_coords_alloc(mesh, &verts_num); diff --git a/source/blender/modifiers/intern/MOD_uvwarp.cc b/source/blender/modifiers/intern/MOD_uvwarp.cc index ff036597f01..2c11b002fc5 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.cc +++ b/source/blender/modifiers/intern/MOD_uvwarp.cc @@ -197,9 +197,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * polys_num = mesh->totpoly; loops_num = mesh->totloop; - /* make sure we are not modifying the original UV map */ - float(*mloopuv)[2] = static_cast(CustomData_duplicate_referenced_layer_named( - &mesh->ldata, CD_PROP_FLOAT2, uvname, loops_num)); + float(*mloopuv)[2] = static_cast( + CustomData_get_layer_named_for_write(&mesh->ldata, CD_PROP_FLOAT2, uvname, loops_num)); MOD_get_vgroup(ctx->object, mesh, umd->vgroup_name, &dvert, &defgrp_index); UVWarpData data{}; diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.cc b/source/blender/modifiers/intern/MOD_weighted_normal.cc index 416ce19a0c5..f8f84fcd735 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.cc +++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc @@ -614,7 +614,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * const float split_angle = mesh->smoothresh; short(*clnors)[2] = static_cast( - CustomData_get_layer(&result->ldata, CD_CUSTOMLOOPNORMAL)); + CustomData_get_layer_for_write(&result->ldata, CD_CUSTOMLOOPNORMAL, mesh->totloop)); /* Keep info whether we had clnors, * it helps when generating clnor spaces and default normals. */ diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index 1362e6e051c..29a5cb9b83c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -143,7 +143,8 @@ static MutableSpan get_orig_index_layer(Mesh &mesh, const eAttrDomain domai { const bke::AttributeAccessor attributes = mesh.attributes(); CustomData &custom_data = get_customdata(mesh, domain); - if (int *orig_indices = static_cast(CustomData_get_layer(&custom_data, CD_ORIGINDEX))) { + if (int *orig_indices = static_cast(CustomData_get_layer_for_write( + &custom_data, CD_ORIGINDEX, attributes.domain_size(domain)))) { return {orig_indices, attributes.domain_size(domain)}; } return {}; diff --git a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc index b6e0eeea3ff..3c06ce8b3f0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_subdivision_surface.cc @@ -70,7 +70,7 @@ static void write_vertex_creases(Mesh &mesh, const VArray &crease_varray) float *crease; if (CustomData_has_layer(&mesh.vdata, CD_CREASE)) { crease = static_cast( - CustomData_duplicate_referenced_layer(&mesh.vdata, CD_CREASE, mesh.totvert)); + CustomData_get_layer_for_write(&mesh.vdata, CD_CREASE, mesh.totvert)); } else { crease = static_cast( From 325105ee6f68ed21cfa85e89922f9ec669d74efa Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Fri, 13 Jan 2023 19:58:42 -0800 Subject: [PATCH 0640/1522] Sculpt: add support for curves sculpt to paint_init_pivot Uses BKE_object_boundbox_get. --- .../editors/sculpt_paint/curves_sculpt_ops.cc | 1 + .../editors/sculpt_paint/paint_image.cc | 36 +++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc index 797b57dd0ca..f12b94aea8f 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc @@ -286,6 +286,7 @@ static void curves_sculptmode_enter(bContext *C) ob->mode = OB_MODE_SCULPT_CURVES; ED_paint_cursor_start(&curves_sculpt->paint, CURVES_SCULPT_mode_poll_view3d); + paint_init_pivot(ob, scene); /* Necessary to change the object mode on the evaluated object. */ DEG_id_tag_update(&ob->id, ID_RECALC_COPY_ON_WRITE); diff --git a/source/blender/editors/sculpt_paint/paint_image.cc b/source/blender/editors/sculpt_paint/paint_image.cc index a57287b924b..d5efb4fe9c6 100644 --- a/source/blender/editors/sculpt_paint/paint_image.cc +++ b/source/blender/editors/sculpt_paint/paint_image.cc @@ -759,23 +759,47 @@ void PAINT_OT_sample_color(wmOperatorType *ot) /******************** texture paint toggle operator ********************/ -void paint_init_pivot(Object *ob, Scene *scene) +static void paint_init_pivot_mesh(Object *ob, Scene *scene, float location[3]) { - UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; - const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob); if (!me_eval) { me_eval = (const Mesh *)ob->data; } - float location[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; + float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; - if (!BKE_mesh_minmax(me_eval, location, max)) { + if (!BKE_mesh_minmax(me_eval, min, max)) { zero_v3(location); zero_v3(max); } - interp_v3_v3v3(location, location, max, 0.5f); + interp_v3_v3v3(location, min, max, 0.5f); +} + +static void paint_init_pivot_curves(Object *ob, Scene *scene, float location[3]) +{ + const BoundBox *bbox = BKE_object_boundbox_get(ob); + interp_v3_v3v3(location, bbox->vec[0], bbox->vec[6], 0.5f); +} + +void paint_init_pivot(Object *ob, Scene *scene) +{ + UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings; + float location[3]; + + switch (ob->type) { + case OB_MESH: + paint_init_pivot_mesh(ob, scene, location); + break; + case OB_CURVES: + paint_init_pivot_curves(ob, scene, location); + break; + default: + BLI_assert_unreachable(); + ups->last_stroke_valid = false; + return; + } + mul_m4_v3(ob->object_to_world, location); ups->last_stroke_valid = true; From 92773761d33058ec4e0eeb3819e23fb06726b5ea Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Fri, 13 Jan 2023 20:17:03 -0800 Subject: [PATCH 0641/1522] Sculpt: Change expand hotkey to not auto-create mask --- .../scripts/presets/keyconfig/keymap_data/blender_default.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index c861236c468..19a93e0882a 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5053,7 +5053,7 @@ def km_sculpt(params): ("target", "MASK"), ("falloff_type", "GEODESIC"), ("invert", True), - ("use_auto_mask", True), + ("use_auto_mask", False), ("use_mask_preserve", True), ]}), ("sculpt.expand", {"type": 'A', "value": 'PRESS', "shift": True, "alt": True}, From 8126d92073b222ba6647c7988e728895ab3f14a8 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 14 Jan 2023 14:15:21 +0100 Subject: [PATCH 0642/1522] Cleanup: fix compile error in debug build --- .../blender/blenkernel/intern/mesh_runtime.cc | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_runtime.cc b/source/blender/blenkernel/intern/mesh_runtime.cc index b3e416c2b7b..9509eea39e0 100644 --- a/source/blender/blenkernel/intern/mesh_runtime.cc +++ b/source/blender/blenkernel/intern/mesh_runtime.cc @@ -341,22 +341,22 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval) do_fixes, &changed); - is_valid &= BKE_mesh_validate_arrays( - me_eval, - reinterpret_cast(positions.data()), - positions.size(), - edges.data(), - edges.size(), - static_cast(CustomData_get_layer(&me_eval->fdata, CD_MFACE)), - me_eval->totface, - loops.data(), - loops.size(), - polys.data(), - polys.size(), - me_eval->deform_verts_for_write().data(), - do_verbose, - do_fixes, - &changed); + is_valid &= BKE_mesh_validate_arrays(me_eval, + reinterpret_cast(positions.data()), + positions.size(), + edges.data(), + edges.size(), + static_cast(CustomData_get_layer_for_write( + &me_eval->fdata, CD_MFACE, me_eval->totface)), + me_eval->totface, + loops.data(), + loops.size(), + polys.data(), + polys.size(), + me_eval->deform_verts_for_write().data(), + do_verbose, + do_fixes, + &changed); BLI_assert(changed == false); From aea26830dc7b7f68508ad93d07e538652b767903 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 14 Jan 2023 14:16:51 +0100 Subject: [PATCH 0643/1522] Cleanup: use std::get instead of std::get_if `std::get` could not be used due to restrictions on macos. However, the minimum requirement has been lifted in {rB597aecc01644f0063fa4545dabadc5f73387e3d3}. --- .../functions/FN_multi_function_params.hh | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh index caf43714e50..9865a62df1b 100644 --- a/source/blender/functions/FN_multi_function_params.hh +++ b/source/blender/functions/FN_multi_function_params.hh @@ -160,7 +160,7 @@ class ParamsBuilder { BLI_assert(ELEM(signature_->params[param_index].type.category(), ParamCategory::SingleOutput, ParamCategory::SingleMutable)); - return *std::get_if(&actual_params_[param_index]); + return std::get(actual_params_[param_index]); } GVectorArray &computed_vector_array(int param_index) @@ -168,7 +168,7 @@ class ParamsBuilder { BLI_assert(ELEM(signature_->params[param_index].type.category(), ParamCategory::VectorOutput, ParamCategory::VectorMutable)); - return **std::get_if(&actual_params_[param_index]); + return *std::get(actual_params_[param_index]); } ResourceScope &resource_scope() @@ -229,7 +229,7 @@ class MFParams { const GVArray &readonly_single_input(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, ParamCategory::SingleInput); - return *std::get_if(&builder_->actual_params_[param_index]); + return std::get(builder_->actual_params_[param_index]); } /** @@ -241,7 +241,7 @@ class MFParams { bool single_output_is_required(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, ParamCategory::SingleOutput); - return !std::get_if(&builder_->actual_params_[param_index])->is_empty(); + return !std::get(builder_->actual_params_[param_index]).is_empty(); } template @@ -252,7 +252,7 @@ class MFParams { GMutableSpan uninitialized_single_output(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, ParamCategory::SingleOutput); - GMutableSpan span = *std::get_if(&builder_->actual_params_[param_index]); + GMutableSpan span = std::get(builder_->actual_params_[param_index]); if (!span.is_empty()) { return span; } @@ -273,7 +273,7 @@ class MFParams { GMutableSpan uninitialized_single_output_if_required(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, ParamCategory::SingleOutput); - return *std::get_if(&builder_->actual_params_[param_index]); + return std::get(builder_->actual_params_[param_index]); } template @@ -285,7 +285,7 @@ class MFParams { const GVVectorArray &readonly_vector_input(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, ParamCategory::VectorInput); - return **std::get_if(&builder_->actual_params_[param_index]); + return *std::get(builder_->actual_params_[param_index]); } template @@ -296,7 +296,7 @@ class MFParams { GVectorArray &vector_output(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, ParamCategory::VectorOutput); - return **std::get_if(&builder_->actual_params_[param_index]); + return *std::get(builder_->actual_params_[param_index]); } template MutableSpan single_mutable(int param_index, StringRef name = "") @@ -306,7 +306,7 @@ class MFParams { GMutableSpan single_mutable(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, ParamCategory::SingleMutable); - return *std::get_if(&builder_->actual_params_[param_index]); + return std::get(builder_->actual_params_[param_index]); } template @@ -317,7 +317,7 @@ class MFParams { GVectorArray &vector_mutable(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, ParamCategory::VectorMutable); - return **std::get_if(&builder_->actual_params_[param_index]); + return *std::get(builder_->actual_params_[param_index]); } private: From 8625495b1c8240e21abac4d255312ddd76fd794d Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 14 Jan 2023 15:35:44 +0100 Subject: [PATCH 0644/1522] Functions: improve handling of unused multi-function outputs Previously, `ParamsBuilder` lazily allocated an array for an output when it was unused, but the called multi-function wanted to access it. Now, whether the multi-function supports an output to be unused is part of the signature. This way, the allocation can happen earlier when the parameters are build. The benefit is that this makes all methods of `MFParams` thread-safe again, removing the need for a mutex. --- .../functions/FN_multi_function_params.hh | 31 +++++++++-------- .../functions/FN_multi_function_signature.hh | 34 +++++++++++++------ .../functions/intern/multi_function.cc | 13 +++++-- .../functions/intern/multi_function_params.cc | 25 ++++---------- .../function/nodes/node_fn_separate_color.cc | 12 +++---- .../geometry/nodes/node_geo_curve_sample.cc | 8 ++--- .../geometry/nodes/node_geo_image_texture.cc | 2 +- .../geometry/nodes/node_geo_proximity.cc | 2 +- .../nodes/geometry/nodes/node_geo_raycast.cc | 14 ++++---- .../nodes/node_geo_sample_nearest_surface.cc | 2 +- .../nodes/node_geo_sample_uv_surface.cc | 6 ++-- .../shader/nodes/node_shader_sepcomb_xyz.cc | 6 ++-- .../shader/nodes/node_shader_tex_brick.cc | 4 +-- .../shader/nodes/node_shader_tex_checker.cc | 2 +- .../shader/nodes/node_shader_tex_gradient.cc | 2 +- .../shader/nodes/node_shader_tex_magic.cc | 2 +- .../shader/nodes/node_shader_tex_musgrave.cc | 2 +- .../shader/nodes/node_shader_tex_noise.cc | 4 +-- .../shader/nodes/node_shader_tex_voronoi.cc | 16 ++++----- .../shader/nodes/node_shader_tex_wave.cc | 2 +- .../nodes/node_shader_tex_white_noise.cc | 4 +-- 21 files changed, 103 insertions(+), 90 deletions(-) diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh index 9865a62df1b..8f176b36a19 100644 --- a/source/blender/functions/FN_multi_function_params.hh +++ b/source/blender/functions/FN_multi_function_params.hh @@ -32,9 +32,6 @@ class ParamsBuilder { Vector> actual_params_; - std::mutex mutex_; - Vector> dummy_output_spans_; - friend class MFParams; ParamsBuilder(const Signature &signature, const IndexMask mask) @@ -127,9 +124,15 @@ class ParamsBuilder { const ParamType ¶m_type = signature_->params[param_index].type; BLI_assert(param_type.category() == ParamCategory::SingleOutput); const CPPType &type = param_type.data_type().single_type(); - /* An empty span indicates that this is ignored. */ - const GMutableSpan dummy_span{type}; - actual_params_.append_unchecked_as(std::in_place_type, dummy_span); + + if (bool(signature_->params[param_index].flag & ParamFlag::SupportsUnusedOutput)) { + /* An empty span indicates that this is ignored. */ + const GMutableSpan dummy_span{type}; + actual_params_.append_unchecked_as(std::in_place_type, dummy_span); + } + else { + this->add_unused_output_for_unsupporting_function(type); + } } void add_vector_output(GVectorArray &vector_array, StringRef expected_name = "") @@ -210,6 +213,8 @@ class ParamsBuilder { { return actual_params_.size(); } + + void add_unused_output_for_unsupporting_function(const CPPType &type); }; class MFParams { @@ -252,13 +257,11 @@ class MFParams { GMutableSpan uninitialized_single_output(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, ParamCategory::SingleOutput); + BLI_assert( + !bool(builder_->signature_->params[param_index].flag & ParamFlag::SupportsUnusedOutput)); GMutableSpan span = std::get(builder_->actual_params_[param_index]); - if (!span.is_empty()) { - return span; - } - /* The output is ignored by the caller, but the multi-function does not handle this case. So - * create a temporary buffer that the multi-function can write to. */ - return this->ensure_dummy_single_output(param_index); + BLI_assert(span.size() >= builder_->min_array_size_); + return span; } /** @@ -273,6 +276,8 @@ class MFParams { GMutableSpan uninitialized_single_output_if_required(int param_index, StringRef name = "") { this->assert_correct_param(param_index, name, ParamCategory::SingleOutput); + BLI_assert( + bool(builder_->signature_->params[param_index].flag & ParamFlag::SupportsUnusedOutput)); return std::get(builder_->actual_params_[param_index]); } @@ -342,8 +347,6 @@ class MFParams { } #endif } - - GMutableSpan ensure_dummy_single_output(int param_index); }; } // namespace blender::fn::multi_function diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh index 7de7507d851..3f4aade820e 100644 --- a/source/blender/functions/FN_multi_function_signature.hh +++ b/source/blender/functions/FN_multi_function_signature.hh @@ -15,10 +15,22 @@ namespace blender::fn::multi_function { +enum class ParamFlag { + None = 0, + /** + * If set, the multi-function parameter can be accessed using + * #MFParams::uninitialized_single_output_if_required which can result in better performance + * because the output does not have to be computed when it is not needed. + */ + SupportsUnusedOutput = 1 << 0, +}; +ENUM_OPERATORS(ParamFlag, ParamFlag::SupportsUnusedOutput); + struct Signature { struct ParamInfo { ParamType type; const char *name; + ParamFlag flag = ParamFlag::None; }; /** @@ -68,25 +80,27 @@ class SignatureBuilder { /* Output Parameter Types */ - template void single_output(const char *name) + template void single_output(const char *name, const ParamFlag flag = ParamFlag::None) { - this->single_output(name, CPPType::get()); + this->single_output(name, CPPType::get(), flag); } - void single_output(const char *name, const CPPType &type) + void single_output(const char *name, const CPPType &type, const ParamFlag flag = ParamFlag::None) { - this->output(name, DataType::ForSingle(type)); + this->output(name, DataType::ForSingle(type), flag); } - template void vector_output(const char *name) + template void vector_output(const char *name, const ParamFlag flag = ParamFlag::None) { - this->vector_output(name, CPPType::get()); + this->vector_output(name, CPPType::get(), flag); } - void vector_output(const char *name, const CPPType &base_type) + void vector_output(const char *name, + const CPPType &base_type, + const ParamFlag flag = ParamFlag::None) { - this->output(name, DataType::ForVector(base_type)); + this->output(name, DataType::ForVector(base_type), flag); } - void output(const char *name, DataType data_type) + void output(const char *name, DataType data_type, const ParamFlag flag = ParamFlag::None) { - signature_.params.append({ParamType(ParamType::Output, data_type), name}); + signature_.params.append({ParamType(ParamType::Output, data_type), name, flag}); } /* Mutable Parameter Types */ diff --git a/source/blender/functions/intern/multi_function.cc b/source/blender/functions/intern/multi_function.cc index 3d20ce4bac3..d81bb57ebed 100644 --- a/source/blender/functions/intern/multi_function.cc +++ b/source/blender/functions/intern/multi_function.cc @@ -108,11 +108,18 @@ void MultiFunction::call_auto(IndexMask mask, MFParams params, Context context) break; } case ParamCategory::SingleOutput: { - const GMutableSpan span = params.uninitialized_single_output_if_required(param_index); - if (span.is_empty()) { - offset_params.add_ignored_single_output(); + if (bool(signature_ref_->params[param_index].flag & ParamFlag::SupportsUnusedOutput)) { + const GMutableSpan span = params.uninitialized_single_output_if_required(param_index); + if (span.is_empty()) { + offset_params.add_ignored_single_output(); + } + else { + const GMutableSpan sliced_span = span.slice(input_slice_range); + offset_params.add_uninitialized_single_output(sliced_span); + } } else { + const GMutableSpan span = params.uninitialized_single_output(param_index); const GMutableSpan sliced_span = span.slice(input_slice_range); offset_params.add_uninitialized_single_output(sliced_span); } diff --git a/source/blender/functions/intern/multi_function_params.cc b/source/blender/functions/intern/multi_function_params.cc index a85a2ed539c..ce5421e4b8c 100644 --- a/source/blender/functions/intern/multi_function_params.cc +++ b/source/blender/functions/intern/multi_function_params.cc @@ -4,27 +4,16 @@ namespace blender::fn::multi_function { -GMutableSpan MFParams::ensure_dummy_single_output(int param_index) +void ParamsBuilder::add_unused_output_for_unsupporting_function(const CPPType &type) { - /* Lock because we are actually modifying #builder_ and it may be used by multiple threads. */ - std::lock_guard lock{builder_->mutex_}; - - for (const std::pair &items : builder_->dummy_output_spans_) { - if (items.first == param_index) { - return items.second; - } - } - - const CPPType &type = std::get_if(&builder_->actual_params_[param_index])->type(); - void *buffer = builder_->scope_.linear_allocator().allocate( - builder_->min_array_size_ * type.size(), type.alignment()); + void *buffer = scope_.linear_allocator().allocate(type.size() * min_array_size_, + type.alignment()); + const GMutableSpan span{type, buffer, min_array_size_}; + actual_params_.append_unchecked_as(std::in_place_type, span); if (!type.is_trivially_destructible()) { - builder_->scope_.add_destruct_call( - [&type, buffer, mask = builder_->mask_]() { type.destruct_indices(buffer, mask); }); + scope_.add_destruct_call( + [&type, buffer, mask = mask_]() { type.destruct_indices(buffer, mask); }); } - const GMutableSpan span{type, buffer, builder_->min_array_size_}; - builder_->dummy_output_spans_.append({param_index, span}); - return span; } } // namespace blender::fn::multi_function diff --git a/source/blender/nodes/function/nodes/node_fn_separate_color.cc b/source/blender/nodes/function/nodes/node_fn_separate_color.cc index fae7c275f5d..f2bcf41a8d5 100644 --- a/source/blender/nodes/function/nodes/node_fn_separate_color.cc +++ b/source/blender/nodes/function/nodes/node_fn_separate_color.cc @@ -45,10 +45,10 @@ class SeparateRGBAFunction : public mf::MultiFunction { mf::Signature signature; mf::SignatureBuilder builder{"Separate Color", signature}; builder.single_input("Color"); - builder.single_output("Red"); - builder.single_output("Green"); - builder.single_output("Blue"); - builder.single_output("Alpha"); + builder.single_output("Red", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Green", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Blue", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Alpha", mf::ParamFlag::SupportsUnusedOutput); return signature; }(); this->set_signature(&signature); @@ -107,7 +107,7 @@ class SeparateHSVAFunction : public mf::MultiFunction { builder.single_output("Hue"); builder.single_output("Saturation"); builder.single_output("Value"); - builder.single_output("Alpha"); + builder.single_output("Alpha", mf::ParamFlag::SupportsUnusedOutput); return signature; }(); this->set_signature(&signature); @@ -145,7 +145,7 @@ class SeparateHSLAFunction : public mf::MultiFunction { builder.single_output("Hue"); builder.single_output("Saturation"); builder.single_output("Lightness"); - builder.single_output("Alpha"); + builder.single_output("Alpha", mf::ParamFlag::SupportsUnusedOutput); return signature; }(); this->set_signature(&signature); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc index 2ca30b0fef5..5be7ad4a2e8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc @@ -261,10 +261,10 @@ class SampleCurveFunction : public mf::MultiFunction { mf::SignatureBuilder builder{"Sample Curve", signature_}; builder.single_input("Curve Index"); builder.single_input("Length"); - builder.single_output("Position"); - builder.single_output("Tangent"); - builder.single_output("Normal"); - builder.single_output("Value", src_field_.cpp_type()); + builder.single_output("Position", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Tangent", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Normal", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Value", src_field_.cpp_type(), mf::ParamFlag::SupportsUnusedOutput); this->set_signature(&signature_); this->evaluate_source(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc index bca477646c3..75d70f7edf0 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc @@ -69,7 +69,7 @@ class ImageFieldsFunction : public mf::MultiFunction { mf::SignatureBuilder builder{"ImageFunction", signature}; builder.single_input("Vector"); builder.single_output("Color"); - builder.single_output("Alpha"); + builder.single_output("Alpha", mf::ParamFlag::SupportsUnusedOutput); return signature; }(); this->set_signature(&signature); diff --git a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc index 2b7d05c7dff..7dd9784deac 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc @@ -142,7 +142,7 @@ class ProximityFunction : public mf::MultiFunction { mf::Signature signature; mf::SignatureBuilder builder{"Geometry Proximity", signature}; builder.single_input("Source Position"); - builder.single_output("Position"); + builder.single_output("Position", mf::ParamFlag::SupportsUnusedOutput); builder.single_output("Distance"); return signature; }(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc index ab4b48ece42..3ce69dee6c7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc @@ -230,12 +230,13 @@ class RaycastFunction : public mf::MultiFunction { builder.single_input("Source Position"); builder.single_input("Ray Direction"); builder.single_input("Ray Length"); - builder.single_output("Is Hit"); + builder.single_output("Is Hit", mf::ParamFlag::SupportsUnusedOutput); builder.single_output("Hit Position"); - builder.single_output("Hit Normal"); - builder.single_output("Distance"); + builder.single_output("Hit Normal", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Distance", mf::ParamFlag::SupportsUnusedOutput); if (target_data_) { - builder.single_output("Attribute", target_data_->type()); + builder.single_output( + "Attribute", target_data_->type(), mf::ParamFlag::SupportsUnusedOutput); } this->set_signature(&signature_); } @@ -245,9 +246,8 @@ class RaycastFunction : public mf::MultiFunction { /* Hit positions are always necessary for retrieving the attribute from the target if that * output is required, so always retrieve a span from the evaluator in that case (it's * expected that the evaluator is more likely to have a spare buffer that could be used). */ - MutableSpan hit_positions = - (target_data_) ? params.uninitialized_single_output(4, "Hit Position") : - params.uninitialized_single_output_if_required(4, "Hit Position"); + MutableSpan hit_positions = params.uninitialized_single_output(4, + "Hit Position"); Array hit_indices; if (target_data_) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc index 709bd152c33..345783e4079 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc @@ -143,7 +143,7 @@ class SampleNearestSurfaceFunction : public mf::MultiFunction { mf::SignatureBuilder builder{"Sample Nearest Surface", signature_}; builder.single_input("Position"); - builder.single_output("Value", src_field_.cpp_type()); + builder.single_output("Value", src_field_.cpp_type(), mf::ParamFlag::SupportsUnusedOutput); this->set_signature(&signature_); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc index 615f2a5ed8d..f80de0c2695 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc @@ -200,9 +200,9 @@ class ReverseUVSampleFunction : public mf::MultiFunction { mf::Signature signature; mf::SignatureBuilder builder{"Sample UV Surface", signature}; builder.single_input("Sample UV"); - builder.single_output("Is Valid"); - builder.single_output("Triangle Index"); - builder.single_output("Barycentric Weights"); + builder.single_output("Is Valid", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Triangle Index", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Barycentric Weights", mf::ParamFlag::SupportsUnusedOutput); return signature; }(); this->set_signature(&signature); diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc index 33c4d4257b4..4892dcdd574 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc @@ -35,9 +35,9 @@ class MF_SeparateXYZ : public mf::MultiFunction { mf::Signature signature; mf::SignatureBuilder builder{"Separate XYZ", signature}; builder.single_input("XYZ"); - builder.single_output("X"); - builder.single_output("Y"); - builder.single_output("Z"); + builder.single_output("X", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Y", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Z", mf::ParamFlag::SupportsUnusedOutput); return signature; }(); this->set_signature(&signature); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc index 62e1c14714c..6e4256ee8e1 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc @@ -135,8 +135,8 @@ class BrickFunction : public mf::MultiFunction { builder.single_input("Bias"); builder.single_input("Brick Width"); builder.single_input("Row Height"); - builder.single_output("Color"); - builder.single_output("Fac"); + builder.single_output("Color", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Fac", mf::ParamFlag::SupportsUnusedOutput); return signature; }(); this->set_signature(&signature); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc index ee1e3758e24..1b72b1e4c79 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc @@ -55,7 +55,7 @@ class NodeTexChecker : public mf::MultiFunction { builder.single_input("Color1"); builder.single_input("Color2"); builder.single_input("Scale"); - builder.single_output("Color"); + builder.single_output("Color", mf::ParamFlag::SupportsUnusedOutput); builder.single_output("Fac"); return signature; }(); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc index 2c0e22dcbbd..5a3abdf0e33 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc @@ -58,7 +58,7 @@ class GradientFunction : public mf::MultiFunction { mf::Signature signature; mf::SignatureBuilder builder{"GradientFunction", signature}; builder.single_input("Vector"); - builder.single_output("Color"); + builder.single_output("Color", mf::ParamFlag::SupportsUnusedOutput); builder.single_output("Fac"); return signature; }(); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc index 0228ed5535f..7992135c083 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc @@ -62,7 +62,7 @@ class MagicFunction : public mf::MultiFunction { builder.single_input("Scale"); builder.single_input("Distortion"); builder.single_output("Color"); - builder.single_output("Fac"); + builder.single_output("Fac", mf::ParamFlag::SupportsUnusedOutput); return signature; }(); this->set_signature(&signature); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc index 39cbb1ff12e..78ed796e508 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc @@ -190,7 +190,7 @@ class MusgraveFunction : public mf::MultiFunction { builder.single_input("Gain"); } - builder.single_output("Fac"); + builder.single_output("Fac", mf::ParamFlag::SupportsUnusedOutput); return signature; } diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc b/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc index f22c5d87c98..e61c36ba8f2 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc @@ -115,8 +115,8 @@ class NoiseFunction : public mf::MultiFunction { builder.single_input("Roughness"); builder.single_input("Distortion"); - builder.single_output("Fac"); - builder.single_output("Color"); + builder.single_output("Fac", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Color", mf::ParamFlag::SupportsUnusedOutput); return signature; } diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc index 1f1313b44be..964c471b9dd 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc @@ -224,14 +224,14 @@ class VoronoiMinowskiFunction : public mf::MultiFunction { } builder.single_input("Exponent"); builder.single_input("Randomness"); - builder.single_output("Distance"); - builder.single_output("Color"); + builder.single_output("Distance", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Color", mf::ParamFlag::SupportsUnusedOutput); if (dimensions != 1) { - builder.single_output("Position"); + builder.single_output("Position", mf::ParamFlag::SupportsUnusedOutput); } if (ELEM(dimensions, 1, 4)) { - builder.single_output("W"); + builder.single_output("W", mf::ParamFlag::SupportsUnusedOutput); } return signature; @@ -661,14 +661,14 @@ class VoronoiMetricFunction : public mf::MultiFunction { builder.single_input("Smoothness"); } builder.single_input("Randomness"); - builder.single_output("Distance"); - builder.single_output("Color"); + builder.single_output("Distance", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Color", mf::ParamFlag::SupportsUnusedOutput); if (dimensions != 1) { - builder.single_output("Position"); + builder.single_output("Position", mf::ParamFlag::SupportsUnusedOutput); } if (ELEM(dimensions, 1, 4)) { - builder.single_output("W"); + builder.single_output("W", mf::ParamFlag::SupportsUnusedOutput); } return signature; diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc index ffb7cc6350a..68c7d4c5f91 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc @@ -104,7 +104,7 @@ class WaveFunction : public mf::MultiFunction { builder.single_input("Detail Scale"); builder.single_input("Detail Roughness"); builder.single_input("Phase Offset"); - builder.single_output("Color"); + builder.single_output("Color", mf::ParamFlag::SupportsUnusedOutput); builder.single_output("Fac"); return signature; }(); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc index 816143eaa33..4f2eb2eb7d7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc @@ -92,8 +92,8 @@ class WhiteNoiseFunction : public mf::MultiFunction { builder.single_input("W"); } - builder.single_output("Value"); - builder.single_output("Color"); + builder.single_output("Value", mf::ParamFlag::SupportsUnusedOutput); + builder.single_output("Color", mf::ParamFlag::SupportsUnusedOutput); return signature; } From 50980981e32667b1a4478a8013b1c78cf1cc5aa5 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 14 Jan 2023 15:42:52 +0100 Subject: [PATCH 0645/1522] Cleanup: remove MF prefix from some classes in multi-function namespace This was missing in rBeedcf1876a6651c38d8f4daa2e65d1fb81f77c5d. --- source/blender/functions/FN_multi_function.hh | 8 +++---- .../functions/FN_multi_function_builder.hh | 24 +++++++++---------- .../functions/FN_multi_function_param_type.hh | 2 +- .../functions/FN_multi_function_params.hh | 10 ++++---- .../functions/FN_multi_function_procedure.hh | 14 +++++------ .../FN_multi_function_procedure_executor.hh | 2 +- .../functions/FN_multi_function_signature.hh | 4 ++-- .../functions/intern/multi_function.cc | 2 +- .../intern/multi_function_builder.cc | 10 ++++---- .../intern/multi_function_procedure.cc | 18 +++++++------- .../multi_function_procedure_executor.cc | 6 ++--- .../blender/functions/tests/FN_field_test.cc | 2 +- .../functions/tests/FN_multi_function_test.cc | 2 +- .../tests/FN_multi_function_test_common.hh | 14 +++++------ .../nodes/node_fn_align_euler_to_vector.cc | 2 +- .../nodes/node_fn_input_special_characters.cc | 2 +- .../function/nodes/node_fn_separate_color.cc | 6 ++--- .../geometry/nodes/node_geo_curve_sample.cc | 4 ++-- .../geometry/nodes/node_geo_image_texture.cc | 2 +- .../geometry/nodes/node_geo_proximity.cc | 2 +- .../nodes/geometry/nodes/node_geo_raycast.cc | 2 +- .../geometry/nodes/node_geo_sample_index.cc | 2 +- .../geometry/nodes/node_geo_sample_nearest.cc | 2 +- .../nodes/node_geo_sample_nearest_surface.cc | 2 +- .../nodes/node_geo_sample_uv_surface.cc | 4 ++-- .../shader/nodes/node_shader_color_ramp.cc | 2 +- .../nodes/shader/nodes/node_shader_curves.cc | 6 ++--- .../nodes/shader/nodes/node_shader_math.cc | 2 +- .../nodes/shader/nodes/node_shader_mix.cc | 2 +- .../nodes/shader/nodes/node_shader_mix_rgb.cc | 2 +- .../shader/nodes/node_shader_sepcomb_rgb.cc | 2 +- .../shader/nodes/node_shader_sepcomb_xyz.cc | 2 +- .../shader/nodes/node_shader_tex_brick.cc | 2 +- .../shader/nodes/node_shader_tex_checker.cc | 2 +- .../shader/nodes/node_shader_tex_gradient.cc | 2 +- .../shader/nodes/node_shader_tex_magic.cc | 2 +- .../shader/nodes/node_shader_tex_musgrave.cc | 2 +- .../shader/nodes/node_shader_tex_noise.cc | 2 +- .../shader/nodes/node_shader_tex_voronoi.cc | 6 ++--- .../shader/nodes/node_shader_tex_wave.cc | 2 +- .../nodes/node_shader_tex_white_noise.cc | 2 +- 41 files changed, 93 insertions(+), 95 deletions(-) diff --git a/source/blender/functions/FN_multi_function.hh b/source/blender/functions/FN_multi_function.hh index 7a281809e4e..c00b0eb7b40 100644 --- a/source/blender/functions/FN_multi_function.hh +++ b/source/blender/functions/FN_multi_function.hh @@ -18,8 +18,8 @@ * combination of input and output). * * To call a multi-function, one has to provide three things: - * - `MFParams`: This references the input and output arrays that the function works with. The - * arrays are not owned by MFParams. + * - `Params`: This references the input and output arrays that the function works with. The + * arrays are not owned by Params. * - `IndexMask`: An array of indices indicating which indices in the provided arrays should be * touched/processed. * - `Context`: Further information for the called function. @@ -52,8 +52,8 @@ class MultiFunction { * - Automatic index mask offsetting to avoid large temporary intermediate arrays that are mostly * unused. */ - void call_auto(IndexMask mask, MFParams params, Context context) const; - virtual void call(IndexMask mask, MFParams params, Context context) const = 0; + void call_auto(IndexMask mask, Params params, Context context) const; + virtual void call(IndexMask mask, Params params, Context context) const = 0; virtual uint64_t hash() const { diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index bb366ea47ea..b1996ac8f43 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -371,12 +371,12 @@ template /*param_tags*/, std::index_sequence /*indices*/) { - /* Load parameters from #MFParams. */ + /* Load parameters from #Params. */ /* Contains `const GVArrayImpl *` for inputs and `T *` for outputs. */ const auto loaded_params = std::make_tuple([&]() { /* Use `typedef` instead of `using` to work around a compiler bug. */ @@ -453,7 +453,7 @@ inline auto build_multi_function_call_from_element_fn(const ElementFn element_fn const ExecPreset exec_preset, TypeSequence /*param_tags*/) { - return [element_fn, exec_preset](const IndexMask mask, MFParams params) { + return [element_fn, exec_preset](const IndexMask mask, Params params) { execute_element_fn_as_multi_function(element_fn, exec_preset, mask, @@ -481,7 +481,7 @@ template class CustomMF : public MultiFu this->set_signature(&signature_); } - void call(IndexMask mask, MFParams params, Context /*context*/) const override + void call(IndexMask mask, Params params, Context /*context*/) const override { call_fn_(mask, params); } @@ -493,8 +493,8 @@ inline auto build_multi_function_with_n_inputs_one_output(const char *name, const ExecPreset exec_preset, TypeSequence /*in_types*/) { - constexpr auto param_tags = TypeSequence..., - MFParamTag>(); + constexpr auto param_tags = TypeSequence..., + ParamTag>(); auto call_fn = build_multi_function_call_from_element_fn( [element_fn](const In &...in, Out &out) { new (&out) Out(element_fn(in...)); }, exec_preset, @@ -603,7 +603,7 @@ inline auto SM(const char *name, const ElementFn element_fn, const ExecPreset exec_preset = exec_presets::AllSpanOrSingle()) { - constexpr auto param_tags = TypeSequence>(); + constexpr auto param_tags = TypeSequence>(); auto call_fn = detail::build_multi_function_call_from_element_fn( element_fn, exec_preset, param_tags); return detail::CustomMF(name, call_fn, param_tags); @@ -630,7 +630,7 @@ class CustomMF_GenericConstant : public MultiFunction { public: CustomMF_GenericConstant(const CPPType &type, const void *value, bool make_value_copy); ~CustomMF_GenericConstant(); - void call(IndexMask mask, MFParams params, Context context) const override; + void call(IndexMask mask, Params params, Context context) const override; uint64_t hash() const override; bool equals(const MultiFunction &other) const override; }; @@ -646,7 +646,7 @@ class CustomMF_GenericConstantArray : public MultiFunction { public: CustomMF_GenericConstantArray(GSpan array); - void call(IndexMask mask, MFParams params, Context context) const override; + void call(IndexMask mask, Params params, Context context) const override; }; /** @@ -665,7 +665,7 @@ template class CustomMF_Constant : public MultiFunction { this->set_signature(&signature_); } - void call(IndexMask mask, MFParams params, Context /*context*/) const override + void call(IndexMask mask, Params params, Context /*context*/) const override { MutableSpan output = params.uninitialized_single_output(0); mask.to_best_mask_type([&](const auto &mask) { @@ -705,7 +705,7 @@ class CustomMF_DefaultOutput : public MultiFunction { public: CustomMF_DefaultOutput(Span input_types, Span output_types); - void call(IndexMask mask, MFParams params, Context context) const override; + void call(IndexMask mask, Params params, Context context) const override; }; class CustomMF_GenericCopy : public MultiFunction { @@ -714,7 +714,7 @@ class CustomMF_GenericCopy : public MultiFunction { public: CustomMF_GenericCopy(DataType data_type); - void call(IndexMask mask, MFParams params, Context context) const override; + void call(IndexMask mask, Params params, Context context) const override; }; } // namespace blender::fn::multi_function diff --git a/source/blender/functions/FN_multi_function_param_type.hh b/source/blender/functions/FN_multi_function_param_type.hh index a80e7f7ebd9..147adb81718 100644 --- a/source/blender/functions/FN_multi_function_param_type.hh +++ b/source/blender/functions/FN_multi_function_param_type.hh @@ -31,7 +31,7 @@ enum class ParamCategory { VectorMutable, }; -template struct MFParamTag { +template struct ParamTag { static constexpr ParamCategory category = Category; using base_type = T; }; diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh index 8f176b36a19..98e03760d47 100644 --- a/source/blender/functions/FN_multi_function_params.hh +++ b/source/blender/functions/FN_multi_function_params.hh @@ -5,10 +5,10 @@ /** \file * \ingroup fn * - * This file provides an MFParams and ParamsBuilder structure. + * This file provides an Params and ParamsBuilder structure. * * `ParamsBuilder` is used by a function caller to be prepare all parameters that are passed into - * the function. `MFParams` is then used inside the called function to access the parameters. + * the function. `Params` is then used inside the called function to access the parameters. */ #include @@ -32,7 +32,7 @@ class ParamsBuilder { Vector> actual_params_; - friend class MFParams; + friend class Params; ParamsBuilder(const Signature &signature, const IndexMask mask) : signature_(&signature), mask_(mask), min_array_size_(mask.min_array_size()) @@ -217,12 +217,12 @@ class ParamsBuilder { void add_unused_output_for_unsupporting_function(const CPPType &type); }; -class MFParams { +class Params { private: ParamsBuilder *builder_; public: - MFParams(ParamsBuilder &builder) : builder_(&builder) + Params(ParamsBuilder &builder) : builder_(&builder) { } diff --git a/source/blender/functions/FN_multi_function_procedure.hh b/source/blender/functions/FN_multi_function_procedure.hh index b4bdbf37780..c33fdea811f 100644 --- a/source/blender/functions/FN_multi_function_procedure.hh +++ b/source/blender/functions/FN_multi_function_procedure.hh @@ -226,12 +226,12 @@ class ReturnInstruction : public Instruction { /** * Inputs and outputs of the entire procedure network. */ -struct MFParameter { +struct Parameter { ParamType::InterfaceType type; Variable *variable; }; -struct ConstMFParameter { +struct ConstParameter { ParamType::InterfaceType type; const Variable *variable; }; @@ -253,7 +253,7 @@ class Procedure : NonCopyable, NonMovable { Vector dummy_instructions_; Vector return_instructions_; Vector variables_; - Vector params_; + Vector params_; Vector> owned_functions_; Instruction *entry_ = nullptr; @@ -271,7 +271,7 @@ class Procedure : NonCopyable, NonMovable { ReturnInstruction &new_return_instruction(); void add_parameter(ParamType::InterfaceType interface_type, Variable &variable); - Span params() const; + Span params() const; template const MultiFunction &construct_function(Args &&...args); @@ -502,10 +502,10 @@ inline const Instruction *DummyInstruction::next() const /** \name #Procedure Inline Methods * \{ */ -inline Span Procedure::params() const +inline Span Procedure::params() const { - static_assert(sizeof(MFParameter) == sizeof(ConstMFParameter)); - return params_.as_span().cast(); + static_assert(sizeof(Parameter) == sizeof(ConstParameter)); + return params_.as_span().cast(); } inline Instruction *Procedure::entry() diff --git a/source/blender/functions/FN_multi_function_procedure_executor.hh b/source/blender/functions/FN_multi_function_procedure_executor.hh index 514b6fbd224..f09f39a719f 100644 --- a/source/blender/functions/FN_multi_function_procedure_executor.hh +++ b/source/blender/functions/FN_multi_function_procedure_executor.hh @@ -19,7 +19,7 @@ class ProcedureExecutor : public MultiFunction { public: ProcedureExecutor(const Procedure &procedure); - void call(IndexMask mask, MFParams params, Context context) const override; + void call(IndexMask mask, Params params, Context context) const override; private: ExecutionHints get_execution_hints() const override; diff --git a/source/blender/functions/FN_multi_function_signature.hh b/source/blender/functions/FN_multi_function_signature.hh index 3f4aade820e..f5ca6df3a3e 100644 --- a/source/blender/functions/FN_multi_function_signature.hh +++ b/source/blender/functions/FN_multi_function_signature.hh @@ -19,7 +19,7 @@ enum class ParamFlag { None = 0, /** * If set, the multi-function parameter can be accessed using - * #MFParams::uninitialized_single_output_if_required which can result in better performance + * #Params::uninitialized_single_output_if_required which can result in better performance * because the output does not have to be computed when it is not needed. */ SupportsUnusedOutput = 1 << 0, @@ -142,7 +142,7 @@ class SignatureBuilder { } template - void add(MFParamTag /* tag */, const char *name) + void add(ParamTag /* tag */, const char *name) { switch (Category) { case ParamCategory::SingleInput: diff --git a/source/blender/functions/intern/multi_function.cc b/source/blender/functions/intern/multi_function.cc index d81bb57ebed..fedf9a00d13 100644 --- a/source/blender/functions/intern/multi_function.cc +++ b/source/blender/functions/intern/multi_function.cc @@ -52,7 +52,7 @@ static int64_t compute_grain_size(const ExecutionHints &hints, const IndexMask m return grain_size; } -void MultiFunction::call_auto(IndexMask mask, MFParams params, Context context) const +void MultiFunction::call_auto(IndexMask mask, Params params, Context context) const { if (mask.is_empty()) { return; diff --git a/source/blender/functions/intern/multi_function_builder.cc b/source/blender/functions/intern/multi_function_builder.cc index 20186e56e1e..c689bda40fe 100644 --- a/source/blender/functions/intern/multi_function_builder.cc +++ b/source/blender/functions/intern/multi_function_builder.cc @@ -31,7 +31,7 @@ CustomMF_GenericConstant::~CustomMF_GenericConstant() } } -void CustomMF_GenericConstant::call(IndexMask mask, MFParams params, Context /*context*/) const +void CustomMF_GenericConstant::call(IndexMask mask, Params params, Context /*context*/) const { GMutableSpan output = params.uninitialized_single_output(0); type_.fill_construct_indices(value_, output.data(), mask); @@ -62,9 +62,7 @@ CustomMF_GenericConstantArray::CustomMF_GenericConstantArray(GSpan array) : arra this->set_signature(&signature_); } -void CustomMF_GenericConstantArray::call(IndexMask mask, - MFParams params, - Context /*context*/) const +void CustomMF_GenericConstantArray::call(IndexMask mask, Params params, Context /*context*/) const { GVectorArray &vectors = params.vector_output(0); for (int64_t i : mask) { @@ -85,7 +83,7 @@ CustomMF_DefaultOutput::CustomMF_DefaultOutput(Span input_types, } this->set_signature(&signature_); } -void CustomMF_DefaultOutput::call(IndexMask mask, MFParams params, Context /*context*/) const +void CustomMF_DefaultOutput::call(IndexMask mask, Params params, Context /*context*/) const { for (int param_index : this->param_indices()) { ParamType param_type = this->param_type(param_index); @@ -109,7 +107,7 @@ CustomMF_GenericCopy::CustomMF_GenericCopy(DataType data_type) this->set_signature(&signature_); } -void CustomMF_GenericCopy::call(IndexMask mask, MFParams params, Context /*context*/) const +void CustomMF_GenericCopy::call(IndexMask mask, Params params, Context /*context*/) const { const DataType data_type = this->param_type(0).data_type(); switch (data_type.category()) { diff --git a/source/blender/functions/intern/multi_function_procedure.cc b/source/blender/functions/intern/multi_function_procedure.cc index 263d0b0ff62..856aa5aa2aa 100644 --- a/source/blender/functions/intern/multi_function_procedure.cc +++ b/source/blender/functions/intern/multi_function_procedure.cc @@ -373,7 +373,7 @@ bool Procedure::validate_same_variables_in_one_call() const bool Procedure::validate_parameters() const { Set variables; - for (const MFParameter ¶m : params_) { + for (const Parameter ¶m : params_) { /* One variable cannot be used as multiple parameters. */ if (!variables.add(param.variable)) { return false; @@ -430,7 +430,7 @@ bool Procedure::validate_initialization() const } } Set variables_that_should_be_initialized_on_return; - for (const MFParameter ¶m : params_) { + for (const Parameter ¶m : params_) { if (ELEM(param.type, ParamType::Mutable, ParamType::Output)) { variables_that_should_be_initialized_on_return.add_new(param.variable); } @@ -461,7 +461,7 @@ Procedure::InitState Procedure::find_initialization_state_before_instruction( auto check_entry_instruction = [&]() { bool caller_initialized_variable = false; - for (const MFParameter ¶m : params_) { + for (const Parameter ¶m : params_) { if (param.variable == &target_variable) { if (ELEM(param.type, ParamType::Input, ParamType::Mutable)) { caller_initialized_variable = true; @@ -810,14 +810,14 @@ class ProcedureDotExport { { instruction_name_format("Return ", ss); - Vector outgoing_parameters; - for (const ConstMFParameter ¶m : procedure_.params()) { + Vector outgoing_parameters; + for (const ConstParameter ¶m : procedure_.params()) { if (ELEM(param.type, ParamType::Mutable, ParamType::Output)) { outgoing_parameters.append(param); } } for (const int param_index : outgoing_parameters.index_range()) { - const ConstMFParameter ¶m = outgoing_parameters[param_index]; + const ConstParameter ¶m = outgoing_parameters[param_index]; variable_to_string(param.variable, ss); if (param_index < outgoing_parameters.size() - 1) { ss << ", "; @@ -835,14 +835,14 @@ class ProcedureDotExport { { std::stringstream ss; ss << "Entry: "; - Vector incoming_parameters; - for (const ConstMFParameter ¶m : procedure_.params()) { + Vector incoming_parameters; + for (const ConstParameter ¶m : procedure_.params()) { if (ELEM(param.type, ParamType::Input, ParamType::Mutable)) { incoming_parameters.append(param); } } for (const int param_index : incoming_parameters.index_range()) { - const ConstMFParameter ¶m = incoming_parameters[param_index]; + const ConstParameter ¶m = incoming_parameters[param_index]; variable_to_string(param.variable, ss); if (param_index < incoming_parameters.size() - 1) { ss << ", "; diff --git a/source/blender/functions/intern/multi_function_procedure_executor.cc b/source/blender/functions/intern/multi_function_procedure_executor.cc index b25ec3e856b..a2eaa36d107 100644 --- a/source/blender/functions/intern/multi_function_procedure_executor.cc +++ b/source/blender/functions/intern/multi_function_procedure_executor.cc @@ -10,7 +10,7 @@ ProcedureExecutor::ProcedureExecutor(const Procedure &procedure) : procedure_(pr { SignatureBuilder builder("Procedure Executor", signature_); - for (const ConstMFParameter ¶m : procedure.params()) { + for (const ConstParameter ¶m : procedure.params()) { builder.add("Parameter", ParamType(param.type, param.variable->data_type())); } @@ -861,7 +861,7 @@ class VariableStates { void add_initial_variable_states(const ProcedureExecutor &fn, const Procedure &procedure, - MFParams ¶ms) + Params ¶ms) { for (const int param_index : fn.param_indices()) { ParamType param_type = fn.param_type(param_index); @@ -1169,7 +1169,7 @@ class InstructionScheduler { } }; -void ProcedureExecutor::call(IndexMask full_mask, MFParams params, Context context) const +void ProcedureExecutor::call(IndexMask full_mask, Params params, Context context) const { BLI_assert(procedure_.validate()); diff --git a/source/blender/functions/tests/FN_field_test.cc b/source/blender/functions/tests/FN_field_test.cc index 63058249dfc..c535097875d 100644 --- a/source/blender/functions/tests/FN_field_test.cc +++ b/source/blender/functions/tests/FN_field_test.cc @@ -164,7 +164,7 @@ class TwoOutputFunction : public mf::MultiFunction { this->set_signature(&signature_); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &in1 = params.readonly_single_input(0, "In1"); const VArray &in2 = params.readonly_single_input(1, "In2"); diff --git a/source/blender/functions/tests/FN_multi_function_test.cc b/source/blender/functions/tests/FN_multi_function_test.cc index 9be5e224f09..f5e2090b404 100644 --- a/source/blender/functions/tests/FN_multi_function_test.cc +++ b/source/blender/functions/tests/FN_multi_function_test.cc @@ -24,7 +24,7 @@ class AddFunction : public MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, MFParams params, Context /*context*/) const override + void call(IndexMask mask, Params params, Context /*context*/) const override { const VArray &a = params.readonly_single_input(0, "A"); const VArray &b = params.readonly_single_input(1, "B"); diff --git a/source/blender/functions/tests/FN_multi_function_test_common.hh b/source/blender/functions/tests/FN_multi_function_test_common.hh index adf70498fa6..84861ee440c 100644 --- a/source/blender/functions/tests/FN_multi_function_test_common.hh +++ b/source/blender/functions/tests/FN_multi_function_test_common.hh @@ -18,7 +18,7 @@ class AddPrefixFunction : public MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, MFParams params, Context /*context*/) const override + void call(IndexMask mask, Params params, Context /*context*/) const override { const VArray &prefixes = params.readonly_single_input(0, "Prefix"); MutableSpan strings = params.single_mutable(1, "Strings"); @@ -43,7 +43,7 @@ class CreateRangeFunction : public MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, MFParams params, Context /*context*/) const override + void call(IndexMask mask, Params params, Context /*context*/) const override { const VArray &sizes = params.readonly_single_input(0, "Size"); GVectorArray &ranges = params.vector_output(1, "Range"); @@ -70,7 +70,7 @@ class GenericAppendFunction : public MultiFunction { this->set_signature(&signature_); } - void call(IndexMask mask, MFParams params, Context /*context*/) const override + void call(IndexMask mask, Params params, Context /*context*/) const override { GVectorArray &vectors = params.vector_mutable(0, "Vector"); const GVArray &values = params.readonly_single_input(1, "Value"); @@ -98,7 +98,7 @@ class ConcatVectorsFunction : public MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, MFParams params, Context /*context*/) const override + void call(IndexMask mask, Params params, Context /*context*/) const override { GVectorArray &a = params.vector_mutable(0); const GVVectorArray &b = params.readonly_vector_input(1); @@ -120,7 +120,7 @@ class AppendFunction : public MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, MFParams params, Context /*context*/) const override + void call(IndexMask mask, Params params, Context /*context*/) const override { GVectorArray_TypedMutableRef vectors = params.vector_mutable(0); const VArray &values = params.readonly_single_input(1); @@ -145,7 +145,7 @@ class SumVectorFunction : public MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, MFParams params, Context /*context*/) const override + void call(IndexMask mask, Params params, Context /*context*/) const override { const VVectorArray &vectors = params.readonly_vector_input(0); MutableSpan sums = params.uninitialized_single_output(1); @@ -174,7 +174,7 @@ class OptionalOutputsFunction : public MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, MFParams params, Context /*context*/) const override + void call(IndexMask mask, Params params, Context /*context*/) const override { if (params.single_output_is_required(0, "Out 1")) { MutableSpan values = params.uninitialized_single_output(0, "Out 1"); diff --git a/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc b/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc index efea88088cf..f8a1cd3cf1d 100644 --- a/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc +++ b/source/blender/nodes/function/nodes/node_fn_align_euler_to_vector.cc @@ -154,7 +154,7 @@ class MF_AlignEulerToVector : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &input_rotations = params.readonly_single_input(0, "Rotation"); const VArray &factors = params.readonly_single_input(1, "Factor"); diff --git a/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc b/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc index 1392a923136..7bcd2975351 100644 --- a/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc +++ b/source/blender/nodes/function/nodes/node_fn_input_special_characters.cc @@ -24,7 +24,7 @@ class MF_SpecialCharacters : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { MutableSpan lb = params.uninitialized_single_output(0, "Line Break"); MutableSpan tab = params.uninitialized_single_output(1, "Tab"); diff --git a/source/blender/nodes/function/nodes/node_fn_separate_color.cc b/source/blender/nodes/function/nodes/node_fn_separate_color.cc index f2bcf41a8d5..2f29514cd87 100644 --- a/source/blender/nodes/function/nodes/node_fn_separate_color.cc +++ b/source/blender/nodes/function/nodes/node_fn_separate_color.cc @@ -54,7 +54,7 @@ class SeparateRGBAFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &colors = params.readonly_single_input(0, "Color"); @@ -113,7 +113,7 @@ class SeparateHSVAFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &colors = params.readonly_single_input(0, "Color"); @@ -151,7 +151,7 @@ class SeparateHSLAFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &colors = params.readonly_single_input(0, "Color"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc index 5be7ad4a2e8..bd7a8c716ae 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc @@ -223,7 +223,7 @@ class SampleFloatSegmentsFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArraySpan lengths = params.readonly_single_input(0, "Length"); MutableSpan indices = params.uninitialized_single_output(1, "Curve Index"); @@ -270,7 +270,7 @@ class SampleCurveFunction : public mf::MultiFunction { this->evaluate_source(); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { MutableSpan sampled_positions = params.uninitialized_single_output_if_required( 2, "Position"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc index 75d70f7edf0..09b45758cb7 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_image_texture.cc @@ -316,7 +316,7 @@ class ImageFieldsFunction : public mf::MultiFunction { } } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &vectors = params.readonly_single_input(0, "Vector"); MutableSpan r_color = params.uninitialized_single_output( diff --git a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc index 7dd9784deac..121ad6700b9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_proximity.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_proximity.cc @@ -149,7 +149,7 @@ class ProximityFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &src_positions = params.readonly_single_input(0, "Source Position"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc index 3ce69dee6c7..666a10079d3 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_raycast.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_raycast.cc @@ -241,7 +241,7 @@ class RaycastFunction : public mf::MultiFunction { this->set_signature(&signature_); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { /* Hit positions are always necessary for retrieving the attribute from the target if that * output is required, so always retrieve a span from the evaluator in that case (it's diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc index e461d3a8503..4f6062cb553 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc @@ -222,7 +222,7 @@ class SampleIndexFunction : public mf::MultiFunction { src_data_ = &evaluator_->get_evaluated(0); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &indices = params.readonly_single_input(0, "Index"); GMutableSpan dst = params.uninitialized_single_output(1, "Value"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc index 06babe28493..abe5be3c182 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest.cc @@ -252,7 +252,7 @@ class SampleNearestFunction : public mf::MultiFunction { this->set_signature(&signature_); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &positions = params.readonly_single_input(0, "Position"); MutableSpan indices = params.uninitialized_single_output(1, "Index"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc index 345783e4079..092689b6b3b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_nearest_surface.cc @@ -147,7 +147,7 @@ class SampleNearestSurfaceFunction : public mf::MultiFunction { this->set_signature(&signature_); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &positions = params.readonly_single_input(0, "Position"); GMutableSpan dst = params.uninitialized_single_output_if_required(1, "Value"); diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc index f80de0c2695..0b7c574eca6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_uv_surface.cc @@ -138,7 +138,7 @@ class SampleMeshBarycentricFunction : public mf::MultiFunction { this->set_signature(&signature_); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArraySpan triangle_indices = params.readonly_single_input(0, "Triangle Index"); @@ -208,7 +208,7 @@ class ReverseUVSampleFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArraySpan sample_uvs = params.readonly_single_input(0, "Sample UV"); MutableSpan is_valid = params.uninitialized_single_output_if_required(1, diff --git a/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc b/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc index ff414bbf344..ffcbb6b419a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc +++ b/source/blender/nodes/shader/nodes/node_shader_color_ramp.cc @@ -105,7 +105,7 @@ class ColorBandFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &values = params.readonly_single_input(0, "Value"); MutableSpan colors = params.uninitialized_single_output( diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.cc b/source/blender/nodes/shader/nodes/node_shader_curves.cc index 9ae8a6e20f9..b04f569dd6c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_curves.cc +++ b/source/blender/nodes/shader/nodes/node_shader_curves.cc @@ -81,7 +81,7 @@ class CurveVecFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Fac"); const VArray &vec_in = params.readonly_single_input(1, "Vector"); @@ -224,7 +224,7 @@ class CurveRGBFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Fac"); const VArray &col_in = params.readonly_single_input(1, @@ -344,7 +344,7 @@ class CurveFloatFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Factor"); const VArray &val_in = params.readonly_single_input(1, "Value"); diff --git a/source/blender/nodes/shader/nodes/node_shader_math.cc b/source/blender/nodes/shader/nodes/node_shader_math.cc index 8cfcdefefc0..04fd53d73dc 100644 --- a/source/blender/nodes/shader/nodes/node_shader_math.cc +++ b/source/blender/nodes/shader/nodes/node_shader_math.cc @@ -150,7 +150,7 @@ class ClampWrapperFunction : public mf::MultiFunction { this->set_signature(&fn.signature()); } - void call(IndexMask mask, mf::MFParams params, mf::Context context) const override + void call(IndexMask mask, mf::Params params, mf::Context context) const override { fn_.call(mask, params, context); diff --git a/source/blender/nodes/shader/nodes/node_shader_mix.cc b/source/blender/nodes/shader/nodes/node_shader_mix.cc index f23be857421..6f79749411f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix.cc @@ -373,7 +373,7 @@ class MixColorFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Factor"); const VArray &col1 = params.readonly_single_input(1, "A"); diff --git a/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc index 7ae93857f61..9abcc66573b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc +++ b/source/blender/nodes/shader/nodes/node_shader_mix_rgb.cc @@ -111,7 +111,7 @@ class MixRGBFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &fac = params.readonly_single_input(0, "Fac"); const VArray &col1 = params.readonly_single_input(1, diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc index 83982aabee4..d9347cbf0c4 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_rgb.cc @@ -43,7 +43,7 @@ class SeparateRGBFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &colors = params.readonly_single_input(0, "Color"); diff --git a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc index 4892dcdd574..70993d4bf1a 100644 --- a/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc +++ b/source/blender/nodes/shader/nodes/node_shader_sepcomb_xyz.cc @@ -43,7 +43,7 @@ class MF_SeparateXYZ : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &vectors = params.readonly_single_input(0, "XYZ"); MutableSpan xs = params.uninitialized_single_output_if_required(1, "X"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc index 6e4256ee8e1..a330fd892ec 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_brick.cc @@ -201,7 +201,7 @@ class BrickFunction : public mf::MultiFunction { return float2(tint, mortar); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); const VArray &color1_values = params.readonly_single_input( diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc index 1b72b1e4c79..249d1ec84d7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_checker.cc @@ -62,7 +62,7 @@ class NodeTexChecker : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); const VArray &color1 = params.readonly_single_input( diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc index 5a3abdf0e33..333cf51c24b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_gradient.cc @@ -65,7 +65,7 @@ class GradientFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc index 7992135c083..354504566a8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_magic.cc @@ -68,7 +68,7 @@ class MagicFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); const VArray &scale = params.readonly_single_input(1, "Scale"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc index 78ed796e508..1478b33e24c 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_musgrave.cc @@ -195,7 +195,7 @@ class MusgraveFunction : public mf::MultiFunction { return signature; } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { auto get_vector = [&](int param_index) -> VArray { return params.readonly_single_input(param_index, "Vector"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc b/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc index e61c36ba8f2..855f640acc8 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_noise.cc @@ -121,7 +121,7 @@ class NoiseFunction : public mf::MultiFunction { return signature; } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { int param = ELEM(dimensions_, 2, 3, 4) + ELEM(dimensions_, 1, 4); const VArray &scale = params.readonly_single_input(param++, "Scale"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc index 964c471b9dd..c820d166907 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_voronoi.cc @@ -237,7 +237,7 @@ class VoronoiMinowskiFunction : public mf::MultiFunction { return signature; } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { auto get_vector = [&](int param_index) -> VArray { return params.readonly_single_input(param_index, "Vector"); @@ -674,7 +674,7 @@ class VoronoiMetricFunction : public mf::MultiFunction { return signature; } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { auto get_vector = [&](int param_index) -> VArray { return params.readonly_single_input(param_index, "Vector"); @@ -1182,7 +1182,7 @@ class VoronoiEdgeFunction : public mf::MultiFunction { return signature; } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { auto get_vector = [&](int param_index) -> VArray { return params.readonly_single_input(param_index, "Vector"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc index 68c7d4c5f91..8610bebd914 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_wave.cc @@ -111,7 +111,7 @@ class WaveFunction : public mf::MultiFunction { this->set_signature(&signature); } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { const VArray &vector = params.readonly_single_input(0, "Vector"); const VArray &scale = params.readonly_single_input(1, "Scale"); diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc index 4f2eb2eb7d7..c1ac2b3d1fd 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_white_noise.cc @@ -98,7 +98,7 @@ class WhiteNoiseFunction : public mf::MultiFunction { return signature; } - void call(IndexMask mask, mf::MFParams params, mf::Context /*context*/) const override + void call(IndexMask mask, mf::Params params, mf::Context /*context*/) const override { int param = ELEM(dimensions_, 2, 3, 4) + ELEM(dimensions_, 1, 4); From 72cc68e2997c273c8437146637f453178c8469de Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 14 Jan 2023 15:56:43 +0100 Subject: [PATCH 0646/1522] Functions: only allocate resource scope when it is actually used In most cases it is currently not used, so always having it there causes unnecessary overhead. In my test file that causes a 2 % performance improvement. --- .../functions/FN_multi_function_params.hh | 25 +++++++++++-------- .../functions/intern/multi_function_params.cc | 7 +++--- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/source/blender/functions/FN_multi_function_params.hh b/source/blender/functions/FN_multi_function_params.hh index 98e03760d47..5ca9f45009b 100644 --- a/source/blender/functions/FN_multi_function_params.hh +++ b/source/blender/functions/FN_multi_function_params.hh @@ -25,7 +25,7 @@ namespace blender::fn::multi_function { class ParamsBuilder { private: - ResourceScope scope_; + std::unique_ptr scope_; const Signature *signature_; IndexMask mask_; int64_t min_array_size_; @@ -90,13 +90,15 @@ class ParamsBuilder { void add_readonly_vector_input(const GVectorArray &vector_array, StringRef expected_name = "") { - this->add_readonly_vector_input(scope_.construct(vector_array), - expected_name); + this->add_readonly_vector_input( + this->resource_scope().construct(vector_array), + expected_name); } void add_readonly_vector_input(const GSpan single_vector, StringRef expected_name = "") { this->add_readonly_vector_input( - scope_.construct(single_vector, min_array_size_), + this->resource_scope().construct(single_vector, + min_array_size_), expected_name); } void add_readonly_vector_input(const GVVectorArray &ref, StringRef expected_name = "") @@ -174,11 +176,6 @@ class ParamsBuilder { return *std::get(actual_params_[param_index]); } - ResourceScope &resource_scope() - { - return scope_; - } - private: void assert_current_param_type(ParamType param_type, StringRef expected_name = "") { @@ -214,6 +211,14 @@ class ParamsBuilder { return actual_params_.size(); } + ResourceScope &resource_scope() + { + if (!scope_) { + scope_ = std::make_unique(); + } + return *scope_; + } + void add_unused_output_for_unsupporting_function(const CPPType &type); }; @@ -285,7 +290,7 @@ class Params { const VVectorArray &readonly_vector_input(int param_index, StringRef name = "") { const GVVectorArray &vector_array = this->readonly_vector_input(param_index, name); - return builder_->scope_.construct>(vector_array); + return builder_->resource_scope().construct>(vector_array); } const GVVectorArray &readonly_vector_input(int param_index, StringRef name = "") { diff --git a/source/blender/functions/intern/multi_function_params.cc b/source/blender/functions/intern/multi_function_params.cc index ce5421e4b8c..17e41454b5d 100644 --- a/source/blender/functions/intern/multi_function_params.cc +++ b/source/blender/functions/intern/multi_function_params.cc @@ -6,12 +6,13 @@ namespace blender::fn::multi_function { void ParamsBuilder::add_unused_output_for_unsupporting_function(const CPPType &type) { - void *buffer = scope_.linear_allocator().allocate(type.size() * min_array_size_, - type.alignment()); + ResourceScope &scope = this->resource_scope(); + void *buffer = scope.linear_allocator().allocate(type.size() * min_array_size_, + type.alignment()); const GMutableSpan span{type, buffer, min_array_size_}; actual_params_.append_unchecked_as(std::in_place_type, span); if (!type.is_trivially_destructible()) { - scope_.add_destruct_call( + scope.add_destruct_call( [&type, buffer, mask = mask_]() { type.destruct_indices(buffer, mask); }); } } From ff15edc6ab4add3a814f8f80c2a96b1a67def65c Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 14 Jan 2023 19:13:51 +0100 Subject: [PATCH 0647/1522] Cleanup: unify method parameters for virtual arrays This makes `GVArrayImpl` and `VArrayImpl` more similar. Only passing the pointer instead of the span also increases efficiency a little bit. The downside is that a few asserts had to be removed as well. However, in practice the same asserts are in place at a higher level as well (in `VArrayCommon`). --- .../intern/geometry_component_mesh.cc | 12 +-- .../blenlib/BLI_generic_virtual_array.hh | 34 ++++--- source/blender/blenlib/BLI_virtual_array.hh | 95 +++++++------------ 3 files changed, 58 insertions(+), 83 deletions(-) diff --git a/source/blender/blenkernel/intern/geometry_component_mesh.cc b/source/blender/blenkernel/intern/geometry_component_mesh.cc index 7b694be324a..bdb1b0edf8b 100644 --- a/source/blender/blenkernel/intern/geometry_component_mesh.cc +++ b/source/blender/blenkernel/intern/geometry_component_mesh.cc @@ -984,26 +984,26 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl { }); } - void materialize(IndexMask mask, MutableSpan r_span) const override + void materialize(IndexMask mask, float *dst) const override { if (dverts_ == nullptr) { - return r_span.fill_indices(mask, 0.0f); + mask.foreach_index([&](const int i) { dst[i] = 0.0f; }); } threading::parallel_for(mask.index_range(), 4096, [&](const IndexRange range) { for (const int64_t i : mask.slice(range)) { if (const MDeformWeight *weight = this->find_weight_at_index(i)) { - r_span[i] = weight->weight; + dst[i] = weight->weight; } else { - r_span[i] = 0.0f; + dst[i] = 0.0f; } } }); } - void materialize_to_uninitialized(IndexMask mask, MutableSpan r_span) const override + void materialize_to_uninitialized(IndexMask mask, float *dst) const override { - this->materialize(mask, r_span); + this->materialize(mask, dst); } private: diff --git a/source/blender/blenlib/BLI_generic_virtual_array.hh b/source/blender/blenlib/BLI_generic_virtual_array.hh index cba767341c1..cb45da5e495 100644 --- a/source/blender/blenlib/BLI_generic_virtual_array.hh +++ b/source/blender/blenlib/BLI_generic_virtual_array.hh @@ -388,25 +388,24 @@ template class VArrayImpl_For_GVArray : public VArrayImpl { return true; } - void materialize(IndexMask mask, MutableSpan r_span) const override + void materialize(IndexMask mask, T *dst) const override { - varray_.materialize(mask, r_span.data()); + varray_.materialize(mask, dst); } - void materialize_to_uninitialized(IndexMask mask, MutableSpan r_span) const override + void materialize_to_uninitialized(IndexMask mask, T *dst) const override { - varray_.materialize_to_uninitialized(mask, r_span.data()); + varray_.materialize_to_uninitialized(mask, dst); } - void materialize_compressed(IndexMask mask, MutableSpan r_span) const override + void materialize_compressed(IndexMask mask, T *dst) const override { - varray_.materialize_compressed(mask, r_span.data()); + varray_.materialize_compressed(mask, dst); } - void materialize_compressed_to_uninitialized(IndexMask mask, - MutableSpan r_span) const override + void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override { - varray_.materialize_compressed_to_uninitialized(mask, r_span.data()); + varray_.materialize_compressed_to_uninitialized(mask, dst); } }; @@ -539,25 +538,24 @@ template class VMutableArrayImpl_For_GVMutableArray : public VMutabl return true; } - void materialize(IndexMask mask, MutableSpan r_span) const override + void materialize(IndexMask mask, T *dst) const override { - varray_.materialize(mask, r_span.data()); + varray_.materialize(mask, dst); } - void materialize_to_uninitialized(IndexMask mask, MutableSpan r_span) const override + void materialize_to_uninitialized(IndexMask mask, T *dst) const override { - varray_.materialize_to_uninitialized(mask, r_span.data()); + varray_.materialize_to_uninitialized(mask, dst); } - void materialize_compressed(IndexMask mask, MutableSpan r_span) const override + void materialize_compressed(IndexMask mask, T *dst) const override { - varray_.materialize_compressed(mask, r_span.data()); + varray_.materialize_compressed(mask, dst); } - void materialize_compressed_to_uninitialized(IndexMask mask, - MutableSpan r_span) const override + void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override { - varray_.materialize_compressed_to_uninitialized(mask, r_span.data()); + varray_.materialize_compressed_to_uninitialized(mask, dst); } }; diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh index 189cb85d468..819807843df 100644 --- a/source/blender/blenlib/BLI_virtual_array.hh +++ b/source/blender/blenlib/BLI_virtual_array.hh @@ -107,17 +107,16 @@ template class VArrayImpl { * Copy values from the virtual array into the provided span. The index of the value in the * virtual array is the same as the index in the span. */ - virtual void materialize(IndexMask mask, MutableSpan r_span) const + virtual void materialize(IndexMask mask, T *dst) const { - mask.foreach_index([&](const int64_t i) { r_span[i] = this->get(i); }); + mask.foreach_index([&](const int64_t i) { dst[i] = this->get(i); }); } /** * Same as #materialize but #r_span is expected to be uninitialized. */ - virtual void materialize_to_uninitialized(IndexMask mask, MutableSpan r_span) const + virtual void materialize_to_uninitialized(IndexMask mask, T *dst) const { - T *dst = r_span.data(); mask.foreach_index([&](const int64_t i) { new (dst + i) T(this->get(i)); }); } @@ -126,12 +125,11 @@ template class VArrayImpl { * in virtual array is not the same as the index in the output span. Instead, the span is filled * without gaps. */ - virtual void materialize_compressed(IndexMask mask, MutableSpan r_span) const + virtual void materialize_compressed(IndexMask mask, T *dst) const { - BLI_assert(mask.size() == r_span.size()); mask.to_best_mask_type([&](auto best_mask) { for (const int64_t i : IndexRange(best_mask.size())) { - r_span[i] = this->get(best_mask[i]); + dst[i] = this->get(best_mask[i]); } }); } @@ -139,10 +137,8 @@ template class VArrayImpl { /** * Same as #materialize_compressed but #r_span is expected to be uninitialized. */ - virtual void materialize_compressed_to_uninitialized(IndexMask mask, MutableSpan r_span) const + virtual void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const { - BLI_assert(mask.size() == r_span.size()); - T *dst = r_span.data(); mask.to_best_mask_type([&](auto best_mask) { for (const int64_t i : IndexRange(best_mask.size())) { new (dst + i) T(this->get(best_mask[i])); @@ -254,32 +250,27 @@ template class VArrayImpl_For_Span : public VMutableArrayImpl { return data_ == static_cast(other_info.data); } - void materialize(IndexMask mask, MutableSpan r_span) const override + void materialize(IndexMask mask, T *dst) const override { - mask.foreach_index([&](const int64_t i) { r_span[i] = data_[i]; }); + mask.foreach_index([&](const int64_t i) { dst[i] = data_[i]; }); } - void materialize_to_uninitialized(IndexMask mask, MutableSpan r_span) const override + void materialize_to_uninitialized(IndexMask mask, T *dst) const override { - T *dst = r_span.data(); mask.foreach_index([&](const int64_t i) { new (dst + i) T(data_[i]); }); } - void materialize_compressed(IndexMask mask, MutableSpan r_span) const override + void materialize_compressed(IndexMask mask, T *dst) const override { - BLI_assert(mask.size() == r_span.size()); mask.to_best_mask_type([&](auto best_mask) { for (const int64_t i : IndexRange(best_mask.size())) { - r_span[i] = data_[best_mask[i]]; + dst[i] = data_[best_mask[i]]; } }); } - void materialize_compressed_to_uninitialized(IndexMask mask, - MutableSpan r_span) const override + void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override { - BLI_assert(mask.size() == r_span.size()); - T *dst = r_span.data(); mask.to_best_mask_type([&](auto best_mask) { for (const int64_t i : IndexRange(best_mask.size())) { new (dst + i) T(data_[best_mask[i]]); @@ -357,29 +348,24 @@ template class VArrayImpl_For_Single final : public VArrayImpl { return CommonVArrayInfo(CommonVArrayInfo::Type::Single, true, &value_); } - void materialize(IndexMask mask, MutableSpan r_span) const override + void materialize(IndexMask mask, T *dst) const override { - r_span.fill_indices(mask, value_); + mask.foreach_index([&](const int64_t i) { dst[i] = value_; }); } - void materialize_to_uninitialized(IndexMask mask, MutableSpan r_span) const override + void materialize_to_uninitialized(IndexMask mask, T *dst) const override { - T *dst = r_span.data(); mask.foreach_index([&](const int64_t i) { new (dst + i) T(value_); }); } - void materialize_compressed(IndexMask mask, MutableSpan r_span) const override + void materialize_compressed(IndexMask mask, T *dst) const override { - BLI_assert(mask.size() == r_span.size()); - UNUSED_VARS_NDEBUG(mask); - r_span.fill(value_); + initialized_fill_n(dst, mask.size(), value_); } - void materialize_compressed_to_uninitialized(IndexMask mask, - MutableSpan r_span) const override + void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override { - BLI_assert(mask.size() == r_span.size()); - uninitialized_fill_n(r_span.data(), mask.size(), value_); + uninitialized_fill_n(dst, mask.size(), value_); } }; @@ -406,22 +392,18 @@ template class VArrayImpl_For_Func final : public return get_func_(index); } - void materialize(IndexMask mask, MutableSpan r_span) const override + void materialize(IndexMask mask, T *dst) const override { - T *dst = r_span.data(); mask.foreach_index([&](const int64_t i) { dst[i] = get_func_(i); }); } - void materialize_to_uninitialized(IndexMask mask, MutableSpan r_span) const override + void materialize_to_uninitialized(IndexMask mask, T *dst) const override { - T *dst = r_span.data(); mask.foreach_index([&](const int64_t i) { new (dst + i) T(get_func_(i)); }); } - void materialize_compressed(IndexMask mask, MutableSpan r_span) const override + void materialize_compressed(IndexMask mask, T *dst) const override { - BLI_assert(mask.size() == r_span.size()); - T *dst = r_span.data(); mask.to_best_mask_type([&](auto best_mask) { for (const int64_t i : IndexRange(best_mask.size())) { dst[i] = get_func_(best_mask[i]); @@ -429,11 +411,8 @@ template class VArrayImpl_For_Func final : public }); } - void materialize_compressed_to_uninitialized(IndexMask mask, - MutableSpan r_span) const override + void materialize_compressed_to_uninitialized(IndexMask mask, T *dst) const override { - BLI_assert(mask.size() == r_span.size()); - T *dst = r_span.data(); mask.to_best_mask_type([&](auto best_mask) { for (const int64_t i : IndexRange(best_mask.size())) { new (dst + i) T(get_func_(best_mask[i])); @@ -476,22 +455,18 @@ class VArrayImpl_For_DerivedSpan final : public VMutableArrayImpl { SetFunc(data_[index], std::move(value)); } - void materialize(IndexMask mask, MutableSpan r_span) const override + void materialize(IndexMask mask, ElemT *dst) const override { - ElemT *dst = r_span.data(); mask.foreach_index([&](const int64_t i) { dst[i] = GetFunc(data_[i]); }); } - void materialize_to_uninitialized(IndexMask mask, MutableSpan r_span) const override + void materialize_to_uninitialized(IndexMask mask, ElemT *dst) const override { - ElemT *dst = r_span.data(); mask.foreach_index([&](const int64_t i) { new (dst + i) ElemT(GetFunc(data_[i])); }); } - void materialize_compressed(IndexMask mask, MutableSpan r_span) const override + void materialize_compressed(IndexMask mask, ElemT *dst) const override { - BLI_assert(mask.size() == r_span.size()); - ElemT *dst = r_span.data(); mask.to_best_mask_type([&](auto best_mask) { for (const int64_t i : IndexRange(best_mask.size())) { dst[i] = GetFunc(data_[best_mask[i]]); @@ -499,11 +474,8 @@ class VArrayImpl_For_DerivedSpan final : public VMutableArrayImpl { }); } - void materialize_compressed_to_uninitialized(IndexMask mask, - MutableSpan r_span) const override + void materialize_compressed_to_uninitialized(IndexMask mask, ElemT *dst) const override { - BLI_assert(mask.size() == r_span.size()); - ElemT *dst = r_span.data(); mask.to_best_mask_type([&](auto best_mask) { for (const int64_t i : IndexRange(best_mask.size())) { new (dst + i) ElemT(GetFunc(data_[best_mask[i]])); @@ -835,7 +807,7 @@ template class VArrayCommon { void materialize(IndexMask mask, MutableSpan r_span) const { BLI_assert(mask.min_array_size() <= this->size()); - impl_->materialize(mask, r_span); + impl_->materialize(mask, r_span.data()); } void materialize_to_uninitialized(MutableSpan r_span) const @@ -846,18 +818,18 @@ template class VArrayCommon { void materialize_to_uninitialized(IndexMask mask, MutableSpan r_span) const { BLI_assert(mask.min_array_size() <= this->size()); - impl_->materialize_to_uninitialized(mask, r_span); + impl_->materialize_to_uninitialized(mask, r_span.data()); } /** Copy some elements of the virtual array into a span. */ void materialize_compressed(IndexMask mask, MutableSpan r_span) const { - impl_->materialize_compressed(mask, r_span); + impl_->materialize_compressed(mask, r_span.data()); } void materialize_compressed_to_uninitialized(IndexMask mask, MutableSpan r_span) const { - impl_->materialize_compressed_to_uninitialized(mask, r_span); + impl_->materialize_compressed_to_uninitialized(mask, r_span.data()); } /** See #GVArrayImpl::try_assign_GVArray. */ @@ -865,6 +837,11 @@ template class VArrayCommon { { return impl_->try_assign_GVArray(varray); } + + const VArrayImpl *get_implementation() const + { + return impl_; + } }; template class VMutableArray; From 1a79bdfbf120f5fe258a295732fb7ac21df9392d Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 14 Jan 2023 19:40:22 +0100 Subject: [PATCH 0648/1522] BLI: inline index mask slice methods Those are simple enough to be inlined. --- source/blender/blenlib/BLI_index_mask.hh | 11 +++++++++-- source/blender/blenlib/intern/index_mask.cc | 10 ---------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/source/blender/blenlib/BLI_index_mask.hh b/source/blender/blenlib/BLI_index_mask.hh index 2144955f4f5..c37820d648b 100644 --- a/source/blender/blenlib/BLI_index_mask.hh +++ b/source/blender/blenlib/BLI_index_mask.hh @@ -234,8 +234,15 @@ class IndexMask { return indices_.first() >= range.first() && indices_.last() <= range.last(); } - IndexMask slice(int64_t start, int64_t size) const; - IndexMask slice(IndexRange slice) const; + IndexMask slice(const int64_t start, const int64_t size) const + { + return IndexMask(indices_.slice(start, size)); + } + + IndexMask slice(const IndexRange slice) const + { + return IndexMask(indices_.slice(slice)); + } IndexMask slice_safe(int64_t start, int64_t size) const; IndexMask slice_safe(IndexRange slice) const; diff --git a/source/blender/blenlib/intern/index_mask.cc b/source/blender/blenlib/intern/index_mask.cc index 72282bc69f3..adcc2de8bdb 100644 --- a/source/blender/blenlib/intern/index_mask.cc +++ b/source/blender/blenlib/intern/index_mask.cc @@ -5,16 +5,6 @@ namespace blender { -IndexMask IndexMask::slice(int64_t start, int64_t size) const -{ - return this->slice(IndexRange(start, size)); -} - -IndexMask IndexMask::slice(IndexRange slice) const -{ - return IndexMask(indices_.slice(slice)); -} - IndexMask IndexMask::slice_safe(int64_t start, int64_t size) const { return this->slice_safe(IndexRange(start, size)); From cc332264ae07e5a974b62c919716da982f175241 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20M=C3=BCller?= Date: Sat, 14 Jan 2023 22:18:39 +0100 Subject: [PATCH 0649/1522] Audaspace: porting changes from upstream. --- extern/audaspace/CMakeLists.txt | 4 +- extern/audaspace/bindings/C/AUD_Sound.cpp | 11 + extern/audaspace/bindings/C/AUD_Sound.h | 10 + extern/audaspace/bindings/C/AUD_Special.h | 1 + extern/audaspace/bindings/python/setup.py.in | 6 +- extern/audaspace/include/fx/Equalizer.h | 106 +++++ extern/audaspace/src/fx/BinauralReader.cpp | 2 +- extern/audaspace/src/fx/Convolver.cpp | 2 +- extern/audaspace/src/fx/ConvolverReader.cpp | 2 +- extern/audaspace/src/fx/Equalizer.cpp | 367 ++++++++++++++++++ extern/audaspace/src/fx/FFTConvolver.cpp | 2 +- extern/audaspace/src/fx/HRTFLoaderUnix.cpp | 4 +- extern/audaspace/src/fx/HRTFLoaderWindows.cpp | 4 +- 13 files changed, 509 insertions(+), 12 deletions(-) create mode 100644 extern/audaspace/include/fx/Equalizer.h create mode 100644 extern/audaspace/src/fx/Equalizer.cpp diff --git a/extern/audaspace/CMakeLists.txt b/extern/audaspace/CMakeLists.txt index ca1849321e2..1ae2fbfba10 100644 --- a/extern/audaspace/CMakeLists.txt +++ b/extern/audaspace/CMakeLists.txt @@ -513,17 +513,19 @@ if(WITH_FFTW) src/fx/Convolver.cpp src/fx/ConvolverReader.cpp src/fx/ConvolverSound.cpp + src/fx/Equalizer.cpp src/fx/FFTConvolver.cpp src/fx/HRTF.cpp src/fx/ImpulseResponse.cpp src/util/FFTPlan.cpp ) set(FFTW_HDR - include/fx/BinauralSound.h + include/fx/BinauralSound.h include/fx/BinauralReader.h include/fx/Convolver.h include/fx/ConvolverReader.h include/fx/ConvolverSound.h + include/fx/Equalizer.h include/fx/FFTConvolver.h include/fx/HRTF.h include/fx/HRTFLoader.h diff --git a/extern/audaspace/bindings/C/AUD_Sound.cpp b/extern/audaspace/bindings/C/AUD_Sound.cpp index 8a3c9d1bbc9..dbedd0045b5 100644 --- a/extern/audaspace/bindings/C/AUD_Sound.cpp +++ b/extern/audaspace/bindings/C/AUD_Sound.cpp @@ -54,6 +54,7 @@ #ifdef WITH_CONVOLUTION #include "fx/BinauralSound.h" #include "fx/ConvolverSound.h" +#include "fx/Equalizer.h" #endif #include @@ -768,4 +769,14 @@ AUD_API AUD_Sound* AUD_Sound_Binaural(AUD_Sound* sound, AUD_HRTF* hrtfs, AUD_Sou } } +AUD_API AUD_Sound* AUD_Sound_equalize(AUD_Sound* sound, float *definition, int size, float maxFreqEq, int sizeConversion) +{ + assert(sound); + + std::shared_ptr buf = std::shared_ptr(new Buffer(sizeof(float)*size)); + std::memcpy(buf->getBuffer(), definition, sizeof(float)*size); + AUD_Sound *equalizer=new AUD_Sound(new Equalizer(*sound, buf, size, maxFreqEq, sizeConversion)); + return equalizer; +} + #endif diff --git a/extern/audaspace/bindings/C/AUD_Sound.h b/extern/audaspace/bindings/C/AUD_Sound.h index fc73a31e15c..dd4fad85122 100644 --- a/extern/audaspace/bindings/C/AUD_Sound.h +++ b/extern/audaspace/bindings/C/AUD_Sound.h @@ -397,6 +397,16 @@ extern AUD_API AUD_Sound* AUD_Sound_mutable(AUD_Sound* sound); #ifdef WITH_CONVOLUTION extern AUD_API AUD_Sound* AUD_Sound_Convolver(AUD_Sound* sound, AUD_ImpulseResponse* filter, AUD_ThreadPool* threadPool); extern AUD_API AUD_Sound* AUD_Sound_Binaural(AUD_Sound* sound, AUD_HRTF* hrtfs, AUD_Source* source, AUD_ThreadPool* threadPool); + + /** + * Creates an Equalizer for the sound + * \param sound The handle of the sound + * \param definition buffer of size*sizeof(float) with the array of equalization values + * \param maxFreqEq Maximum frequency refered by the array + * \param sizeConversion Size of the transformation. Must be 2^number (for example 1024, 2048,...) + * \return A handle to the Equalizer refered to that sound + */ + extern AUD_API AUD_Sound* AUD_Sound_equalize(AUD_Sound* sound, float *definition, int size, float maxFreqEq, int sizeConversion); #endif #ifdef __cplusplus diff --git a/extern/audaspace/bindings/C/AUD_Special.h b/extern/audaspace/bindings/C/AUD_Special.h index 1d181d33f87..f9a239acd61 100644 --- a/extern/audaspace/bindings/C/AUD_Special.h +++ b/extern/audaspace/bindings/C/AUD_Special.h @@ -53,6 +53,7 @@ extern AUD_API AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, double seconds); * \param buffer The buffer to write to. Must have a size of 3*4*length. * \param length How many samples to read from the sound. * \param samples_per_second How many samples to read per second of the sound. + * \param interrupt Must point to a short that equals 0. If it is set to a non-zero value, the method will be interrupted and return 0. * \return How many samples really have been read. Always <= length. */ extern AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, int samples_per_second, short* interrupt); diff --git a/extern/audaspace/bindings/python/setup.py.in b/extern/audaspace/bindings/python/setup.py.in index 0e6666e06a0..e0fe4a0af42 100644 --- a/extern/audaspace/bindings/python/setup.py.in +++ b/extern/audaspace/bindings/python/setup.py.in @@ -5,12 +5,12 @@ import os import codecs import numpy -from distutils.core import setup, Extension +from setuptools import setup, Extension if len(sys.argv) > 2 and sys.argv[1] == '--build-docs': import subprocess - from distutils.core import Distribution - from distutils.command.build import build + from setuptools import Distribution + from setuptools.command.build import build dist = Distribution() cmd = build(dist) diff --git a/extern/audaspace/include/fx/Equalizer.h b/extern/audaspace/include/fx/Equalizer.h new file mode 100644 index 00000000000..87e24fa4b3f --- /dev/null +++ b/extern/audaspace/include/fx/Equalizer.h @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright 2022 Marcos Perez Gonzalez + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#pragma once + +/** + * @file Equalizer.h + * @ingroup fx + * The Equalizer class. + */ + +#include +#include + +#include "ISound.h" +#include "ImpulseResponse.h" + +AUD_NAMESPACE_BEGIN + +class Buffer; +class ImpulseResponse; +/** + * This class represents a sound that can be modified depending on a given impulse response. + */ +class AUD_API Equalizer : public ISound +{ +private: + /** + * A pointer to the imput sound. + */ + std::shared_ptr m_sound; + + /** + * Local definition of Equalizer + */ + std::shared_ptr m_bufEQ; + + /** + * A pointer to the impulse response. + */ + std::shared_ptr m_impulseResponse; + + /** + * delete copy constructor and operator= + */ + Equalizer(const Equalizer&) = delete; + Equalizer& operator=(const Equalizer&) = delete; + + /** + * Create ImpulseResponse from the definition in the Buffer, + * using at the end a minimum phase change + */ + std::shared_ptr createImpulseResponse(); + + /** + * Create an Impulse Response with minimum phase distortion using Homomorphic + * The input is an Impulse Response + */ + std::shared_ptr minimumPhaseFilterHomomorphic(std::shared_ptr original, int lOriginal, int lWork); + + /** + * Create an Impulse Response with minimum phase distortion using Hilbert + * The input is an Impulse Response + */ + std::shared_ptr minimumPhaseFilterHilbert(std::shared_ptr original, int lOriginal, int lWork); + +public: + /** + * Creates a new Equalizer. + * \param sound The sound that will be equalized + */ + Equalizer(std::shared_ptr sound, std::shared_ptr bufEQ, int externalSizeEq, float maxFreqEq, int sizeConversion); + + virtual ~Equalizer(); + virtual std::shared_ptr createReader(); + + /* + * Length of the external equalizer definition. It must be the number of "float" positions of the Buffer + */ + int external_size_eq; + + /* + * Length of the internal equalizer definition + */ + int filter_length; + + /* + * Maximum frequency used in the equalizer definition + */ + float maxFreqEq; +}; + +AUD_NAMESPACE_END diff --git a/extern/audaspace/src/fx/BinauralReader.cpp b/extern/audaspace/src/fx/BinauralReader.cpp index 2792adada8a..12b8866c470 100644 --- a/extern/audaspace/src/fx/BinauralReader.cpp +++ b/extern/audaspace/src/fx/BinauralReader.cpp @@ -27,7 +27,7 @@ AUD_NAMESPACE_BEGIN BinauralReader::BinauralReader(std::shared_ptr reader, std::shared_ptr hrtfs, std::shared_ptr source, std::shared_ptr threadPool, std::shared_ptr plan) : - m_reader(reader), m_hrtfs(hrtfs), m_source(source), m_N(plan->getSize()), m_threadPool(threadPool), m_position(0), m_eosReader(false), m_eosTail(false), m_transition(false), m_transPos(CROSSFADE_SAMPLES*NUM_OUTCHANNELS) + m_position(0), m_reader(reader), m_hrtfs(hrtfs), m_source(source), m_N(plan->getSize()), m_transition(false), m_transPos(CROSSFADE_SAMPLES*NUM_OUTCHANNELS), m_eosReader(false), m_eosTail(false), m_threadPool(threadPool) { if(m_hrtfs->isEmpty()) AUD_THROW(StateException, "The provided HRTF object is empty"); diff --git a/extern/audaspace/src/fx/Convolver.cpp b/extern/audaspace/src/fx/Convolver.cpp index 24b205e9282..ab0036d9807 100644 --- a/extern/audaspace/src/fx/Convolver.cpp +++ b/extern/audaspace/src/fx/Convolver.cpp @@ -23,7 +23,7 @@ AUD_NAMESPACE_BEGIN Convolver::Convolver(std::shared_ptr>>>> ir, int irLength, std::shared_ptr threadPool, std::shared_ptr plan) : - m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_irBuffers(ir), m_irLength(irLength), m_threadPool(threadPool), m_numThreads(std::min(threadPool->getNumOfThreads(), static_cast(m_irBuffers->size() - 1))), m_tailCounter(0), m_eos(false) + m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_irBuffers(ir), m_numThreads(std::min(threadPool->getNumOfThreads(), static_cast(m_irBuffers->size() - 1))), m_threadPool(threadPool), m_irLength(irLength), m_tailCounter(0), m_eos(false) { m_resetFlag = false; diff --git a/extern/audaspace/src/fx/ConvolverReader.cpp b/extern/audaspace/src/fx/ConvolverReader.cpp index d5d9050f9a1..e79ac393368 100644 --- a/extern/audaspace/src/fx/ConvolverReader.cpp +++ b/extern/audaspace/src/fx/ConvolverReader.cpp @@ -24,7 +24,7 @@ AUD_NAMESPACE_BEGIN ConvolverReader::ConvolverReader(std::shared_ptr reader, std::shared_ptr ir, std::shared_ptr threadPool, std::shared_ptr plan) : - m_reader(reader), m_ir(ir), m_N(plan->getSize()), m_eosReader(false), m_eosTail(false), m_inChannels(reader->getSpecs().channels), m_irChannels(ir->getSpecs().channels), m_threadPool(threadPool), m_position(0) + m_position(0), m_reader(reader), m_ir(ir), m_N(plan->getSize()), m_eosReader(false), m_eosTail(false), m_inChannels(reader->getSpecs().channels), m_irChannels(ir->getSpecs().channels), m_threadPool(threadPool) { m_nChannelThreads = std::min((int)threadPool->getNumOfThreads(), m_inChannels); m_futures.resize(m_nChannelThreads); diff --git a/extern/audaspace/src/fx/Equalizer.cpp b/extern/audaspace/src/fx/Equalizer.cpp new file mode 100644 index 00000000000..3cafcc17625 --- /dev/null +++ b/extern/audaspace/src/fx/Equalizer.cpp @@ -0,0 +1,367 @@ +/******************************************************************************* + * Copyright 2022 Marcos Perez Gonzalez + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ******************************************************************************/ + +#include "fx/Equalizer.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "Exception.h" + +#include "fx/ConvolverReader.h" +#include "fx/ImpulseResponse.h" +#include "util/Buffer.h" +#include "util/FFTPlan.h" +#include "util/ThreadPool.h" + +AUD_NAMESPACE_BEGIN + +Equalizer::Equalizer(std::shared_ptr sound, std::shared_ptr bufEQ, int externalSizeEq, float maxFreqEq, int sizeConversion) : m_sound(sound), m_bufEQ(bufEQ) +{ + this->maxFreqEq = maxFreqEq; + this->external_size_eq = externalSizeEq; + + filter_length = sizeConversion; +} + +Equalizer::~Equalizer() +{ +} + +std::shared_ptr Equalizer::createReader() +{ + std::shared_ptr fp = std::shared_ptr(new FFTPlan(filter_length)); + // 2 threads to start with + return std::shared_ptr(new ConvolverReader(m_sound->createReader(), createImpulseResponse(), std::shared_ptr(new ThreadPool(2)), fp)); +} + +float calculateValueArray(float* data, float minX, float maxX, int length, float posX) +{ + if(posX < minX) + return 1.0; + if(posX > maxX) + return data[length - 1]; + float interval = (maxX - minX) / (float) length; + int idx = (int) ((posX - minX) / interval); + return data[idx]; +} + +void complex_prod(float a, float b, float c, float d, float* r, float* imag) +{ + float prod1 = a * c; + float prod2 = b * d; + float prod3 = (a + b) * (c + d); + + // Real Part + *r = prod1 - prod2; + + // Imaginary Part + *imag = prod3 - (prod1 + prod2); +} + +/** + * The creation of the ImpuseResponse which will be convoluted with the sound + * + * The implementation is based on scikit-signal + */ +std::shared_ptr Equalizer::createImpulseResponse() +{ + std::shared_ptr fp = std::shared_ptr(new FFTPlan(filter_length)); + fftwf_complex* buffer = (fftwf_complex*) fp->getBuffer(); + std::memset(buffer, 0, filter_length * sizeof(fftwf_complex)); + std::shared_ptr soundReader = m_sound.get()->createReader(); + Specs specsSound = soundReader.get()->getSpecs(); + + int sampleRate = specsSound.rate; + + for(unsigned i = 0; i < filter_length / 2; i++) + { + double freq = (((float) i) / (float) filter_length) * (float) sampleRate; + + double dbGain = calculateValueArray(m_bufEQ->getBuffer(), 0.0, maxFreqEq, external_size_eq, freq); + + // gain = 10^(decibels / 20.0) + // 0 db = 1 + // 20 db = 10 + // 40 db = 100 + float gain = (float) pow(10.0, dbGain / 20.0); + + if(i == filter_length / 2 - 1) + { + gain = 0; + } + // IMPORTANT!!!! It is needed for the minimum phase step. + // Without this, the amplitude would be square rooted + // + gain *= gain; + + // Calculation of exponential with std.. or "by hand" + /* + std::complex preShift= std::complex(0.0, -(filter_length - 1) + / 2. * M_PI * freq / ( sampleRate/2)); std::complex shift = + std::exp(preShift); + + std::complex cGain = gain * shift; + */ + + float imaginary_shift = -(filter_length - 1) / 2. * M_PI * freq / (sampleRate / 2); + float cGain_real = gain * cos(imaginary_shift); + float cGain_imag = gain * sin(imaginary_shift); + + int i2 = filter_length - i - 1; + + buffer[i][0] = cGain_real; // Real + buffer[i][1] = cGain_imag; // Imag + + if(i > 0 && i2 < filter_length) + { + buffer[i2][0] = cGain_real; // Real + buffer[i2][1] = cGain_imag; // Imag + } + } + + // In place. From Complex to sample_t + fp->IFFT(buffer); + + // Window Hamming + sample_t* pt_sample_t = (sample_t*) buffer; + float half_filter = ((float) filter_length) / 2.0; + for(int i = 0; i < filter_length; i++) + { + // Centered in filter_length/2 + float window = 0.54 - 0.46 * cos((2 * M_PI * (float) i) / (float) (filter_length - 1)); + pt_sample_t[i] *= window; + } + + std::shared_ptr b2 = std::shared_ptr(new Buffer(filter_length * sizeof(sample_t))); + + sample_t* buffer_real = (sample_t*) buffer; + sample_t* buffer2 = b2->getBuffer(); + float normaliziter = (float) filter_length; + for(int i = 0; i < filter_length; i++) + { + buffer2[i] = (buffer_real[i] / normaliziter); + } + + fp->freeBuffer(buffer); + + // + // Here b2 is the buffer with a "valid" FIR (remember the squared amplitude + // + std::shared_ptr ir_minimum = minimumPhaseFilterHomomorphic(b2, filter_length, -1); + + Specs specsIR; + specsIR.rate = sampleRate; + specsIR.channels = CHANNELS_MONO; + + return std::shared_ptr(new ImpulseResponse(std::shared_ptr(new StreamBuffer(ir_minimum, specsIR)), fp)); +} + +std::shared_ptr Equalizer::minimumPhaseFilterHomomorphic(std::shared_ptr original, int lOriginal, int lWork) +{ + void* b_orig = original->getBuffer(); + + if(lWork < lOriginal || lWork < 0) + { + lWork = (int) pow(2, ceil(log2((float) (2 * (lOriginal - 1) / 0.01)))); + } + + std::shared_ptr fp = std::shared_ptr(new FFTPlan(lWork, 0.1)); + fftwf_complex* buffer = (fftwf_complex*) fp->getBuffer(); + sample_t* b_work = (sample_t*) buffer; + // Padding with 0 + std::memset(b_work, 0, lWork * sizeof(sample_t)); + std::memcpy(b_work, b_orig, lOriginal * sizeof(sample_t)); + + fp->FFT(b_work); + + for(int i = 0; i < lWork / 2; i++) + { + buffer[i][0] = fabs(sqrt(buffer[i][0] * buffer[i][0] + buffer[i][1] * buffer[i][1])); + buffer[i][1] = 0.0; + int conjugate = lWork - i - 1; + buffer[conjugate][0] = buffer[i][0]; + buffer[conjugate][1] = 0.0; + } + + double threshold = pow(10.0, -7); + float logThreshold = (float) log(threshold); + // take 0.25*log(|H|**2) = 0.5*log(|H|) + for(int i = 0; i < lWork; i++) + { + if(buffer[i][0] < threshold) + { + buffer[i][0] = 0.5 * logThreshold; + } + else + { + buffer[i][0] = 0.5 * log(buffer[i][0]); + } + } + + fp->IFFT(buffer); + + // homomorphic filter + int stop = (lOriginal + 1) / 2; + b_work[0] = b_work[0] / (float) lWork; + for(int i = 1; i < stop; i++) + { + b_work[i] = b_work[i] / (float) lWork * 2.0; + } + for(int i = stop; i < lWork; i++) + { + b_work[i] = 0; + } + + fp->FFT(buffer); + // EXP + // e^x = e^ (a+bi)= e^a * e^bi = e^a * (cos b + i sin b) + for(int i = 0; i < lWork / 2; i++) + { + float new_real; + float new_imag; + new_real = exp(buffer[i][0]) * cos(buffer[i][1]); + new_imag = exp(buffer[i][0]) * sin(buffer[i][1]); + + buffer[i][0] = new_real; + buffer[i][1] = new_imag; + int conjugate = lWork - i - 1; + buffer[conjugate][0] = new_real; + buffer[conjugate][1] = new_imag; + } + + // IFFT + fp->IFFT(buffer); + + // Create new clean Buffer with only the result and normalization + int lOut = (lOriginal / 2) + lOriginal % 2; + std::shared_ptr bOut = std::shared_ptr(new Buffer(sizeof(float) * lOut)); + float* bbOut = (float*) bOut->getBuffer(); + + // Copy and normalize + for(int i = 0; i < lOut; i++) + { + bbOut[i] = b_work[i] / (float) lWork; + } + + fp->freeBuffer(buffer); + return bOut; +} + +std::shared_ptr Equalizer::minimumPhaseFilterHilbert(std::shared_ptr original, int lOriginal, int lWork) +{ + void* b_orig = original->getBuffer(); + + if(lWork < lOriginal || lWork < 0) + { + lWork = (int) pow(2, ceil(log2((float) (2 * (lOriginal - 1) / 0.01)))); + } + + std::shared_ptr fp = std::shared_ptr(new FFTPlan(lWork, 0.1)); + fftwf_complex* buffer = (fftwf_complex*) fp->getBuffer(); + sample_t* b_work = (sample_t*) buffer; + // Padding with 0 + std::memset(b_work, 0, lWork * sizeof(sample_t)); + std::memcpy(b_work, b_orig, lOriginal * sizeof(sample_t)); + + fp->FFT(b_work); + float mymax, mymin; + float n_half = (float) (lOriginal >> 1); + for(int i = 0; i < lWork; i++) + { + float w = ((float) i) * 2.0 * M_PI / (float) lWork * n_half; + float f1 = cos(w); + float f2 = sin(w); + float f3, f4; + complex_prod(buffer[i][0], buffer[i][1], f1, f2, &f3, &f4); + buffer[i][0] = f3; + buffer[i][1] = 0.0; + if(i == 0) + { + mymax = f3; + mymin = f3; + } + else + { + if(f3 < mymin) + mymin = f3; + if(f3 > mymax) + mymax = f3; + } + } + float dp = mymax - 1; + float ds = 0 - mymin; + float S = 4.0 / pow(2, (sqrt(1 + dp + ds) + sqrt(1 - dp + ds))); + for(int i = 0; i < lWork; i++) + { + buffer[i][0] = sqrt((buffer[i][0] + ds) * S) + 1.0E-10; + } + + fftwf_complex* buffer_tmp = (fftwf_complex*) std::malloc(lWork * sizeof(fftwf_complex)); + std::memcpy(buffer_tmp, buffer, lWork * sizeof(fftwf_complex)); + + // + // Hilbert transform + // + int midpt = lWork >> 1; + for(int i = 0; i < lWork; i++) + buffer[i][0] = log(buffer[i][0]); + fp->IFFT(buffer); + b_work[0] = 0.0; + for(int i = 1; i < midpt; i++) + { + b_work[i] /= (float) lWork; + } + b_work[midpt] = 0.0; + for(int i = midpt + 1; i < lWork; i++) + { + b_work[i] /= (-1.0 * lWork); + } + + fp->FFT(b_work); + + // Exp + for(int i = 0; i < lWork; i++) + { + float base = exp(buffer[i][0]); + buffer[i][0] = base * cos(buffer[i][1]); + buffer[i][1] = base * sin(buffer[i][1]); + complex_prod(buffer_tmp[i][0], buffer_tmp[i][1], buffer[i][0], buffer[i][1], &(buffer[i][0]), &(buffer[i][1])); + } + std::free(buffer_tmp); + + fp->IFFT(buffer); + + // + // Copy and normalization + // + int n_out = n_half + lOriginal % 2; + std::shared_ptr b_minimum = std::shared_ptr(new Buffer(n_out * sizeof(sample_t))); + std::memcpy(b_minimum->getBuffer(), buffer, n_out * sizeof(sample_t)); + sample_t* b_final = (sample_t*) b_minimum->getBuffer(); + for(int i = 0; i < n_out; i++) + { + b_final[i] /= (float) lWork; + } + return b_minimum; +} + +AUD_NAMESPACE_END diff --git a/extern/audaspace/src/fx/FFTConvolver.cpp b/extern/audaspace/src/fx/FFTConvolver.cpp index 868a1ebbaf3..cf32b2c4f9a 100644 --- a/extern/audaspace/src/fx/FFTConvolver.cpp +++ b/extern/audaspace/src/fx/FFTConvolver.cpp @@ -22,7 +22,7 @@ AUD_NAMESPACE_BEGIN FFTConvolver::FFTConvolver(std::shared_ptr>> ir, std::shared_ptr plan) : - m_plan(plan), m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_tailPos(0), m_irBuffer(ir) + m_plan(plan), m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_irBuffer(ir), m_tailPos(0) { m_tail = (float*)calloc(m_M - 1, sizeof(float)); m_realBufLen = ((m_N / 2) + 1) * 2; diff --git a/extern/audaspace/src/fx/HRTFLoaderUnix.cpp b/extern/audaspace/src/fx/HRTFLoaderUnix.cpp index 12a23913912..00092b1c46b 100644 --- a/extern/audaspace/src/fx/HRTFLoaderUnix.cpp +++ b/extern/audaspace/src/fx/HRTFLoaderUnix.cpp @@ -75,7 +75,7 @@ void HRTFLoader::loadHRTFs(std::shared_ptr hrtfs, char ear, const std::str if(ear == 'L') azim = 360 - azim; } - catch(std::exception& e) + catch(...) { AUD_THROW(FileException, "The HRTF name doesn't follow the naming scheme: " + filename); } @@ -86,4 +86,4 @@ void HRTFLoader::loadHRTFs(std::shared_ptr hrtfs, char ear, const std::str return; } -AUD_NAMESPACE_END \ No newline at end of file +AUD_NAMESPACE_END diff --git a/extern/audaspace/src/fx/HRTFLoaderWindows.cpp b/extern/audaspace/src/fx/HRTFLoaderWindows.cpp index 148f1fa015d..303b409cb6c 100644 --- a/extern/audaspace/src/fx/HRTFLoaderWindows.cpp +++ b/extern/audaspace/src/fx/HRTFLoaderWindows.cpp @@ -78,7 +78,7 @@ void HRTFLoader::loadHRTFs(std::shared_ptr hrtfs, char ear, const std::str if(ear == 'L') azim = 360 - azim; } - catch(std::exception& e) + catch(...) { AUD_THROW(FileException, "The HRTF name doesn't follow the naming scheme: " + filename); } @@ -90,4 +90,4 @@ void HRTFLoader::loadHRTFs(std::shared_ptr hrtfs, char ear, const std::str return; } -AUD_NAMESPACE_END \ No newline at end of file +AUD_NAMESPACE_END From fc9c818531d8684d8fc35e0ee91f46afff507f0e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jan 2023 22:16:15 +1100 Subject: [PATCH 0650/1522] Fix missing view layer sync in recent change to ED_view3d_datamask Call BKE_view_layer_synced_ensure before getting the active object [0] caused an assertion for tests in debug mode. [0]: c158dd560e5399d8bfa7386790e7b43c9f91db8e --- source/blender/editors/include/ED_view3d.h | 6 ++++-- source/blender/editors/render/render_opengl.cc | 6 ++++-- source/blender/editors/space_view3d/view3d_draw.cc | 10 +++++++--- source/blender/windowmanager/intern/wm_event_system.cc | 5 +++-- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 35930d1a9b4..3526db5cb35 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -1104,13 +1104,15 @@ char ED_view3d_lock_view_from_index(int index); char ED_view3d_axis_view_opposite(char view); bool ED_view3d_lock(struct RegionView3D *rv3d); -void ED_view3d_datamask(const struct ViewLayer *view_layer, +void ED_view3d_datamask(const struct Scene *scene, + struct ViewLayer *view_layer, const struct View3D *v3d, struct CustomData_MeshMasks *r_cddata_masks); /** * Goes over all modes and view3d settings. */ -void ED_view3d_screen_datamask(const struct ViewLayer *view_layer, +void ED_view3d_screen_datamask(const struct Scene *scene, + struct ViewLayer *view_layer, const struct bScreen *screen, struct CustomData_MeshMasks *r_cddata_masks); diff --git a/source/blender/editors/render/render_opengl.cc b/source/blender/editors/render/render_opengl.cc index d91f1a09beb..fe50513fa64 100644 --- a/source/blender/editors/render/render_opengl.cc +++ b/source/blender/editors/render/render_opengl.cc @@ -808,8 +808,10 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) memset(&oglrender->scene->customdata_mask_modal, 0, sizeof(oglrender->scene->customdata_mask_modal)); - ED_view3d_datamask( - oglrender->view_layer, oglrender->v3d, &oglrender->scene->customdata_mask_modal); + ED_view3d_datamask(oglrender->scene, + oglrender->view_layer, + oglrender->v3d, + &oglrender->scene->customdata_mask_modal); /* apply immediately in case we're rendering from a script, * running notifiers again will overwrite */ diff --git a/source/blender/editors/space_view3d/view3d_draw.cc b/source/blender/editors/space_view3d/view3d_draw.cc index 95407afbeda..04559fb30dc 100644 --- a/source/blender/editors/space_view3d/view3d_draw.cc +++ b/source/blender/editors/space_view3d/view3d_draw.cc @@ -2407,7 +2407,8 @@ void ED_view3d_depths_free(ViewDepths *depths) /** \name Custom-data Utilities * \{ */ -void ED_view3d_datamask(const ViewLayer *view_layer, +void ED_view3d_datamask(const Scene *scene, + ViewLayer *view_layer, const View3D *v3d, CustomData_MeshMasks *r_cddata_masks) { @@ -2428,6 +2429,7 @@ void ED_view3d_datamask(const ViewLayer *view_layer, } } + BKE_view_layer_synced_ensure(scene, view_layer); Object *obact = BKE_view_layer_active_object_get(view_layer); if (obact) { switch (obact->type) { @@ -2450,7 +2452,8 @@ void ED_view3d_datamask(const ViewLayer *view_layer, } } -void ED_view3d_screen_datamask(const ViewLayer *view_layer, +void ED_view3d_screen_datamask(const Scene *scene, + ViewLayer *view_layer, const bScreen *screen, CustomData_MeshMasks *r_cddata_masks) { @@ -2459,7 +2462,8 @@ void ED_view3d_screen_datamask(const ViewLayer *view_layer, /* Check if we need UV or color data due to the view mode. */ LISTBASE_FOREACH (const ScrArea *, area, &screen->areabase) { if (area->spacetype == SPACE_VIEW3D) { - ED_view3d_datamask(view_layer, static_cast(area->spacedata.first), r_cddata_masks); + ED_view3d_datamask( + scene, view_layer, static_cast(area->spacedata.first), r_cddata_masks); } } } diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index df1bdfdc4aa..c412006b819 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -423,10 +423,11 @@ void wm_event_do_depsgraph(bContext *C, bool is_after_open_file) /* Combine data-masks so one window doesn't disable UVs in another T26448. */ CustomData_MeshMasks win_combine_v3d_datamask = {0}; LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { - const ViewLayer *view_layer = WM_window_get_active_view_layer(win); + const Scene *scene = WM_window_get_active_scene(win); + ViewLayer *view_layer = WM_window_get_active_view_layer(win); const bScreen *screen = WM_window_get_active_screen(win); - ED_view3d_screen_datamask(view_layer, screen, &win_combine_v3d_datamask); + ED_view3d_screen_datamask(scene, view_layer, screen, &win_combine_v3d_datamask); } /* Update all the dependency graphs of visible view layers. */ LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { From 82bd020a3047d43817c06b5d012e52eca0bfd298 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jan 2023 23:29:02 +1100 Subject: [PATCH 0651/1522] CMake: suppress GCC warnings stringop-overread & stringop-overflow As noted in comments, there are a lot of false positives which can't be conveniently suppressed. Many of these warnings were caused by `float x, y, z` being passed as `float[3]` using a pointer to `x`. --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9dfb962a57e..0b2f4eec61a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1427,6 +1427,9 @@ if(CMAKE_COMPILER_IS_GNUCC) add_check_c_compiler_flag(C_WARNINGS C_WARN_TYPE_LIMITS -Wtype-limits) add_check_c_compiler_flag(C_WARNINGS C_WARN_FORMAT_SIGN -Wformat-signedness) add_check_c_compiler_flag(C_WARNINGS C_WARN_RESTRICT -Wrestrict) + # Useful but too many false positives and inconvenient to suppress each occurrence. + add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_STRINGOP_OVERREAD -Wno-stringop-overread) + add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_STRINGOP_OVERFLOW -Wno-stringop-overflow) # C-only. add_check_c_compiler_flag(C_WARNINGS C_WARN_NO_NULL -Wnonnull) @@ -1466,6 +1469,9 @@ if(CMAKE_COMPILER_IS_GNUCC) add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_RESTRICT -Wrestrict) add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_SUGGEST_OVERRIDE -Wno-suggest-override) add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_UNINITIALIZED -Wuninitialized) + # Useful but too many false positives and inconvenient to suppress each occurrence. + add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_STRINGOP_OVERREAD -Wno-stringop-overread) + add_check_cxx_compiler_flag(CXX_WARNINGS CXX_WARN_NO_STRINGOP_OVERFLOW -Wno-stringop-overflow) # causes too many warnings if(NOT APPLE) From 8c7df5fa72ee486c1be02a423491b1fb06ead416 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jan 2023 23:45:56 +1100 Subject: [PATCH 0652/1522] Fix invalid arguments to memcpy in IMB_rectfill_area_replace Passing the pointer to the array doesn't make sense in this case. --- source/blender/imbuf/intern/rectop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c index 81fdac40ee6..65bbb4a7be2 100644 --- a/source/blender/imbuf/intern/rectop.c +++ b/source/blender/imbuf/intern/rectop.c @@ -1112,12 +1112,12 @@ void IMB_rectfill_area_replace( if (ibuf->rect) { uchar *rrect = (uchar *)ibuf->rect + offset; - memcpy(rrect, &col_char, sizeof(uchar) * 4); + memcpy(rrect, col_char, sizeof(uchar[4])); } if (ibuf->rect_float) { float *rrectf = ibuf->rect_float + offset; - memcpy(rrectf, &col, sizeof(float) * 4); + memcpy(rrectf, col, sizeof(float[4])); } } } From bec86c5d15deb8e27ceaf980e776b6a9b23cfaf8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jan 2023 23:52:50 +1100 Subject: [PATCH 0653/1522] Cleanup: remove unused arguments --- source/blender/editors/sculpt_paint/paint_image.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_image.cc b/source/blender/editors/sculpt_paint/paint_image.cc index d5efb4fe9c6..bedf7b588b2 100644 --- a/source/blender/editors/sculpt_paint/paint_image.cc +++ b/source/blender/editors/sculpt_paint/paint_image.cc @@ -759,7 +759,7 @@ void PAINT_OT_sample_color(wmOperatorType *ot) /******************** texture paint toggle operator ********************/ -static void paint_init_pivot_mesh(Object *ob, Scene *scene, float location[3]) +static void paint_init_pivot_mesh(Object *ob, float location[3]) { const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob); if (!me_eval) { @@ -776,7 +776,7 @@ static void paint_init_pivot_mesh(Object *ob, Scene *scene, float location[3]) interp_v3_v3v3(location, min, max, 0.5f); } -static void paint_init_pivot_curves(Object *ob, Scene *scene, float location[3]) +static void paint_init_pivot_curves(Object *ob, float location[3]) { const BoundBox *bbox = BKE_object_boundbox_get(ob); interp_v3_v3v3(location, bbox->vec[0], bbox->vec[6], 0.5f); @@ -789,10 +789,10 @@ void paint_init_pivot(Object *ob, Scene *scene) switch (ob->type) { case OB_MESH: - paint_init_pivot_mesh(ob, scene, location); + paint_init_pivot_mesh(ob, location); break; case OB_CURVES: - paint_init_pivot_curves(ob, scene, location); + paint_init_pivot_curves(ob, location); break; default: BLI_assert_unreachable(); From 0a7c485b6681b046e5268f6901b4a10fc7189626 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 15 Jan 2023 23:55:06 +1100 Subject: [PATCH 0654/1522] Cleanup: remove redundant memset on calloc'ed array --- source/blender/blenkernel/intern/softbody.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 457b8de4592..0500e924d2f 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -1529,7 +1529,6 @@ static void sb_sfesf_threads_run(struct Depsgraph *depsgraph, } sb_threads = MEM_callocN(sizeof(SB_thread_context) * totthread, "SBSpringsThread"); - memset(sb_threads, 0, sizeof(SB_thread_context) * totthread); left = totsprings; dec = totsprings / totthread + 1; for (i = 0; i < totthread; i++) { @@ -2208,7 +2207,6 @@ static void sb_cf_threads_run(Scene *scene, // printf("sb_cf_threads_run spawning %d threads\n", totthread); sb_threads = MEM_callocN(sizeof(SB_thread_context) * totthread, "SBThread"); - memset(sb_threads, 0, sizeof(SB_thread_context) * totthread); left = totpoint; dec = totpoint / totthread + 1; for (i = 0; i < totthread; i++) { From 8b5d5cbf06d1ce8a3b5d877a9147acc7b9cf827e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Fri, 13 Jan 2023 22:58:45 +0100 Subject: [PATCH 0655/1522] BLI: Math: Add sign() function This implement the sign function as simple as possible while giving the the same result as `signum`. --- source/blender/blenlib/BLI_math_base.hh | 5 +++++ source/blender/blenlib/BLI_math_vector.hh | 13 +++++++++++++ .../blender/blenlib/tests/BLI_math_vector_test.cc | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/source/blender/blenlib/BLI_math_base.hh b/source/blender/blenlib/BLI_math_base.hh index 098c53e43d2..fdee18840ce 100644 --- a/source/blender/blenlib/BLI_math_base.hh +++ b/source/blender/blenlib/BLI_math_base.hh @@ -34,6 +34,11 @@ template inline T abs(const T &a) return std::abs(a); } +template inline T sign(const T &a) +{ + return (T(0) < a) - (a < T(0)); +} + template inline T min(const T &a, const T &b) { return std::min(a, b); diff --git a/source/blender/blenlib/BLI_math_vector.hh b/source/blender/blenlib/BLI_math_vector.hh index 1e8f5a3f42a..cab5d16dd9b 100644 --- a/source/blender/blenlib/BLI_math_vector.hh +++ b/source/blender/blenlib/BLI_math_vector.hh @@ -70,6 +70,19 @@ template [[nodiscard]] inline VecBase abs(const V return result; } +/** + * Returns -1 if \a a is less than 0, 0 if \a a is equal to 0, and +1 if \a a is greater than 0. + */ +template +[[nodiscard]] inline VecBase sign(const VecBase &a) +{ + VecBase result; + for (int i = 0; i < Size; i++) { + result[i] = math::sign(a[i]); + } + return result; +} + template [[nodiscard]] inline VecBase min(const VecBase &a, const VecBase &b) { diff --git a/source/blender/blenlib/tests/BLI_math_vector_test.cc b/source/blender/blenlib/tests/BLI_math_vector_test.cc index 5686be975b5..4b05c7a6cd5 100644 --- a/source/blender/blenlib/tests/BLI_math_vector_test.cc +++ b/source/blender/blenlib/tests/BLI_math_vector_test.cc @@ -125,4 +125,13 @@ TEST(math_vector, DivideCeil) EXPECT_FLOAT_EQ(result.z, 0); } +TEST(math_vector, Sign) +{ + const int3 a(-21, 16, 0); + const int3 result = math::sign(a); + EXPECT_FLOAT_EQ(result.x, -1); + EXPECT_FLOAT_EQ(result.y, 1); + EXPECT_FLOAT_EQ(result.z, 0); +} + } // namespace blender::tests From 87bb14ab5fcfc59ad4cc437e4b00f649cf2240c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Sun, 15 Jan 2023 14:24:06 +0100 Subject: [PATCH 0656/1522] Fix T103256 Viewport: Regression: Clipping Region is not working This was caused by a change in UBO name that wasn't propagated through all usage, leading to missing UBO bind. --- .../intern/shaders/common_view_clipping_lib.glsl | 12 ++++++------ source/blender/draw/intern/shaders/draw_view_info.hh | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/source/blender/draw/intern/shaders/common_view_clipping_lib.glsl b/source/blender/draw/intern/shaders/common_view_clipping_lib.glsl index 4ff6a9a3778..12c906ae3e2 100644 --- a/source/blender/draw/intern/shaders/common_view_clipping_lib.glsl +++ b/source/blender/draw/intern/shaders/common_view_clipping_lib.glsl @@ -7,12 +7,12 @@ void view_clipping_distances(vec3 wpos) { # ifdef USE_WORLD_CLIP_PLANES vec4 pos_4d = vec4(wpos, 1.0); - gl_ClipDistance[0] = dot(drw_clipping[0], pos_4d); - gl_ClipDistance[1] = dot(drw_clipping[1], pos_4d); - gl_ClipDistance[2] = dot(drw_clipping[2], pos_4d); - gl_ClipDistance[3] = dot(drw_clipping[3], pos_4d); - gl_ClipDistance[4] = dot(drw_clipping[4], pos_4d); - gl_ClipDistance[5] = dot(drw_clipping[5], pos_4d); + gl_ClipDistance[0] = dot(drw_clipping_[0], pos_4d); + gl_ClipDistance[1] = dot(drw_clipping_[1], pos_4d); + gl_ClipDistance[2] = dot(drw_clipping_[2], pos_4d); + gl_ClipDistance[3] = dot(drw_clipping_[3], pos_4d); + gl_ClipDistance[4] = dot(drw_clipping_[4], pos_4d); + gl_ClipDistance[5] = dot(drw_clipping_[5], pos_4d); # endif } diff --git a/source/blender/draw/intern/shaders/draw_view_info.hh b/source/blender/draw/intern/shaders/draw_view_info.hh index e4a8e06941b..4e1a45934f1 100644 --- a/source/blender/draw/intern/shaders/draw_view_info.hh +++ b/source/blender/draw/intern/shaders/draw_view_info.hh @@ -79,7 +79,7 @@ GPU_SHADER_CREATE_INFO(draw_modelmat_instanced_attr) GPU_SHADER_CREATE_INFO(drw_clipped) /* TODO(fclem): Move to engine side. */ - .uniform_buf(DRW_CLIPPING_UBO_SLOT, "vec4", "drw_clipping[6]", Frequency::PASS) + .uniform_buf(DRW_CLIPPING_UBO_SLOT, "vec4", "drw_clipping_[6]", Frequency::PASS) .define("USE_WORLD_CLIP_PLANES"); /** \} */ From e1aef2e87e9bbfa6a2ccd419e8525f3fc0b86b07 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jan 2023 09:55:41 +1100 Subject: [PATCH 0657/1522] Cleanup: suppress '-Warray-bounds' warnings Changes to overlay_shader.cc workaround a bug in GCC-12.2 (likely a duplicate of [0]). As the workaround involved removing a local variable which most functions already didn't assign, remove it for all functions. An alternative is to add (otherwise redundant) parenthesis, e.g. `&(e_data.sh_data[sh_cfg])`, but this would need to be noted in code-comments, so opt for removing the intermediate variable. [0]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106247 --- .../tests/BLI_linear_allocator_test.cc | 7 ++++ .../draw/engines/overlay/overlay_shader.cc | 35 +++++++++---------- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/source/blender/blenlib/tests/BLI_linear_allocator_test.cc b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc index 2ed1786f9e0..cc6bae0ea0e 100644 --- a/source/blender/blenlib/tests/BLI_linear_allocator_test.cc +++ b/source/blender/blenlib/tests/BLI_linear_allocator_test.cc @@ -58,9 +58,16 @@ TEST(linear_allocator, CopyString) blender::AlignedBuffer<256, 1> buffer; allocator.provide_buffer(buffer); + /* False positive warning with GCC 12.2, + * considers assignment outside of array bounds (`char [0]`). */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" + StringRefNull ref1 = allocator.copy_string("Hello"); StringRefNull ref2 = allocator.copy_string("World"); +#pragma GCC diagnostic pop + EXPECT_EQ(ref1, "Hello"); EXPECT_EQ(ref2, "World"); EXPECT_EQ(ref2.data() - ref1.data(), 6); diff --git a/source/blender/draw/engines/overlay/overlay_shader.cc b/source/blender/draw/engines/overlay/overlay_shader.cc index 9e33d713a9a..58d3e92e764 100644 --- a/source/blender/draw/engines/overlay/overlay_shader.cc +++ b/source/blender/draw/engines/overlay/overlay_shader.cc @@ -705,11 +705,11 @@ GPUShader *OVERLAY_shader_outline_detect(void) GPUShader *OVERLAY_shader_paint_face(void) { const DRWContextState *draw_ctx = DRW_context_state_get(); - eGPUShaderConfig sh_cfg = draw_ctx->sh_cfg; - OVERLAY_Shaders *sh_data = &e_data.sh_data[sh_cfg]; + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->paint_face) { sh_data->paint_face = GPU_shader_create_from_info_name( - sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_paint_face_clipped" : "overlay_paint_face"); + draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_paint_face_clipped" : + "overlay_paint_face"); } return sh_data->paint_face; } @@ -717,11 +717,11 @@ GPUShader *OVERLAY_shader_paint_face(void) GPUShader *OVERLAY_shader_paint_point(void) { const DRWContextState *draw_ctx = DRW_context_state_get(); - eGPUShaderConfig sh_cfg = draw_ctx->sh_cfg; - OVERLAY_Shaders *sh_data = &e_data.sh_data[sh_cfg]; + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->paint_point) { sh_data->paint_point = GPU_shader_create_from_info_name( - sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_paint_point_clipped" : "overlay_paint_point"); + draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_paint_point_clipped" : + "overlay_paint_point"); } return sh_data->paint_point; } @@ -729,11 +729,10 @@ GPUShader *OVERLAY_shader_paint_point(void) GPUShader *OVERLAY_shader_paint_texture(void) { const DRWContextState *draw_ctx = DRW_context_state_get(); - eGPUShaderConfig sh_cfg = draw_ctx->sh_cfg; - OVERLAY_Shaders *sh_data = &e_data.sh_data[sh_cfg]; + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->paint_texture) { sh_data->paint_texture = GPU_shader_create_from_info_name( - sh_cfg ? "overlay_paint_texture_clipped" : "overlay_paint_texture"); + draw_ctx->sh_cfg ? "overlay_paint_texture_clipped" : "overlay_paint_texture"); } return sh_data->paint_texture; } @@ -741,11 +740,10 @@ GPUShader *OVERLAY_shader_paint_texture(void) GPUShader *OVERLAY_shader_paint_vertcol(void) { const DRWContextState *draw_ctx = DRW_context_state_get(); - eGPUShaderConfig sh_cfg = draw_ctx->sh_cfg; - OVERLAY_Shaders *sh_data = &e_data.sh_data[sh_cfg]; + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->paint_vertcol) { sh_data->paint_vertcol = GPU_shader_create_from_info_name( - sh_cfg ? "overlay_paint_vertcol_clipped" : "overlay_paint_vertcol"); + draw_ctx->sh_cfg ? "overlay_paint_vertcol_clipped" : "overlay_paint_vertcol"); } return sh_data->paint_vertcol; } @@ -758,10 +756,10 @@ GPUShader *OVERLAY_shader_paint_weight(const bool shading) }; int index = shading ? 1 : 0; const DRWContextState *draw_ctx = DRW_context_state_get(); - eGPUShaderConfig sh_cfg = draw_ctx->sh_cfg; - OVERLAY_Shaders *sh_data = &e_data.sh_data[sh_cfg]; + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->paint_weight[index]) { - sh_data->paint_weight[index] = GPU_shader_create_from_info_name(info_name[sh_cfg][index]); + sh_data->paint_weight[index] = GPU_shader_create_from_info_name( + info_name[draw_ctx->sh_cfg][index]); } return sh_data->paint_weight[index]; } @@ -769,11 +767,10 @@ GPUShader *OVERLAY_shader_paint_weight(const bool shading) GPUShader *OVERLAY_shader_paint_wire(void) { const DRWContextState *draw_ctx = DRW_context_state_get(); - eGPUShaderConfig sh_cfg = draw_ctx->sh_cfg; - OVERLAY_Shaders *sh_data = &e_data.sh_data[sh_cfg]; + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->paint_wire) { - sh_data->paint_wire = GPU_shader_create_from_info_name(sh_cfg ? "overlay_paint_wire_clipped" : - "overlay_paint_wire"); + sh_data->paint_wire = GPU_shader_create_from_info_name( + draw_ctx->sh_cfg ? "overlay_paint_wire_clipped" : "overlay_paint_wire"); } return sh_data->paint_wire; } From 6d07b459f2981b0d7eae0e89cca80366d3bbbfcb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jan 2023 10:21:32 +1100 Subject: [PATCH 0658/1522] Cleanup: compare to GPU_SHADER_CFG_CLIPPED when checking configurations Don't assume a non-zero eGPUShaderConfig is clipped, as this would cause unexpected behavior if other configurations are added. --- .../draw/engines/overlay/overlay_shader.cc | 204 +++++++++++------- 1 file changed, 122 insertions(+), 82 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_shader.cc b/source/blender/draw/engines/overlay/overlay_shader.cc index 58d3e92e764..5fd009db715 100644 --- a/source/blender/draw/engines/overlay/overlay_shader.cc +++ b/source/blender/draw/engines/overlay/overlay_shader.cc @@ -146,7 +146,8 @@ GPUShader *OVERLAY_shader_depth_only(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->depth_only) { sh_data->depth_only = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_depth_only_clipped" : "overlay_depth_only"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_depth_only_clipped" : + "overlay_depth_only"); } return sh_data->depth_only; } @@ -157,7 +158,8 @@ GPUShader *OVERLAY_shader_edit_mesh_vert(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_mesh_vert) { sh_data->edit_mesh_vert = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_mesh_vert_clipped" : "overlay_edit_mesh_vert"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_mesh_vert_clipped" : + "overlay_edit_mesh_vert"); } return sh_data->edit_mesh_vert; } @@ -169,7 +171,7 @@ GPUShader *OVERLAY_shader_edit_mesh_edge(bool use_flat_interp) GPUShader **sh = use_flat_interp ? &sh_data->edit_mesh_edge_flat : &sh_data->edit_mesh_edge; if (*sh == nullptr) { *sh = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? (use_flat_interp ? "overlay_edit_mesh_edge_flat_clipped" : "overlay_edit_mesh_edge_clipped") : (use_flat_interp ? "overlay_edit_mesh_edge_flat" : "overlay_edit_mesh_edge")); @@ -183,13 +185,13 @@ GPUShader *OVERLAY_shader_armature_sphere(bool use_outline) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (use_outline && !sh_data->armature_sphere_outline) { sh_data->armature_sphere_outline = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_armature_sphere_outline_clipped" : - "overlay_armature_sphere_outline"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_armature_sphere_outline_clipped" : + "overlay_armature_sphere_outline"); } else if (!sh_data->armature_sphere_solid) { sh_data->armature_sphere_solid = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_armature_sphere_solid_clipped" : - "overlay_armature_sphere_solid"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_armature_sphere_solid_clipped" : + "overlay_armature_sphere_solid"); } return use_outline ? sh_data->armature_sphere_outline : sh_data->armature_sphere_solid; } @@ -200,13 +202,13 @@ GPUShader *OVERLAY_shader_armature_shape(bool use_outline) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (use_outline && !sh_data->armature_shape_outline) { sh_data->armature_shape_outline = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_armature_shape_outline_clipped" : - "overlay_armature_shape_outline"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_armature_shape_outline_clipped" : + "overlay_armature_shape_outline"); } else if (!sh_data->armature_shape_solid) { sh_data->armature_shape_solid = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_armature_shape_solid_clipped" : - "overlay_armature_shape_solid"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_armature_shape_solid_clipped" : + "overlay_armature_shape_solid"); } return use_outline ? sh_data->armature_shape_outline : sh_data->armature_shape_solid; } @@ -217,7 +219,8 @@ GPUShader *OVERLAY_shader_armature_shape_wire(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->armature_shape_wire) { sh_data->armature_shape_wire = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_armature_shape_wire_clipped" : "overlay_armature_shape_wire"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_armature_shape_wire_clipped" : + "overlay_armature_shape_wire"); } return sh_data->armature_shape_wire; } @@ -228,13 +231,14 @@ GPUShader *OVERLAY_shader_armature_envelope(bool use_outline) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (use_outline && !sh_data->armature_envelope_outline) { sh_data->armature_envelope_outline = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_armature_envelope_outline_clipped" : - "overlay_armature_envelope_outline"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? + "overlay_armature_envelope_outline_clipped" : + "overlay_armature_envelope_outline"); } else if (!sh_data->armature_envelope_solid) { sh_data->armature_envelope_solid = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_armature_envelope_solid_clipped" : - "overlay_armature_envelope_solid"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_armature_envelope_solid_clipped" : + "overlay_armature_envelope_solid"); } return use_outline ? sh_data->armature_envelope_outline : sh_data->armature_envelope_solid; } @@ -245,7 +249,8 @@ GPUShader *OVERLAY_shader_armature_stick(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->armature_stick) { sh_data->armature_stick = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_armature_stick_clipped" : "overlay_armature_stick"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_armature_stick_clipped" : + "overlay_armature_stick"); } return sh_data->armature_stick; } @@ -256,7 +261,8 @@ GPUShader *OVERLAY_shader_armature_degrees_of_freedom_wire(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->armature_dof_wire) { sh_data->armature_dof_wire = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_armature_dof_wire_clipped" : "overlay_armature_dof_wire"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_armature_dof_wire_clipped" : + "overlay_armature_dof_wire"); } return sh_data->armature_dof_wire; } @@ -267,7 +273,8 @@ GPUShader *OVERLAY_shader_armature_degrees_of_freedom_solid(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->armature_dof_solid) { sh_data->armature_dof_solid = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_armature_dof_solid_clipped" : "overlay_armature_dof_solid"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_armature_dof_solid_clipped" : + "overlay_armature_dof_solid"); } return sh_data->armature_dof_solid; } @@ -278,7 +285,8 @@ GPUShader *OVERLAY_shader_armature_wire(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->armature_wire) { sh_data->armature_wire = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_armature_wire_clipped" : "overlay_armature_wire"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_armature_wire_clipped" : + "overlay_armature_wire"); } return sh_data->armature_wire; } @@ -289,7 +297,8 @@ GPUShader *OVERLAY_shader_edit_curve_handle(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_curve_handle) { sh_data->edit_curve_handle = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_curve_handle_clipped" : "overlay_edit_curve_handle"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_curve_handle_clipped" : + "overlay_edit_curve_handle"); } return sh_data->edit_curve_handle; } @@ -300,7 +309,8 @@ GPUShader *OVERLAY_shader_edit_curve_point(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_curve_point) { sh_data->edit_curve_point = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_curve_point_clipped" : "overlay_edit_curve_point"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_curve_point_clipped" : + "overlay_edit_curve_point"); } return sh_data->edit_curve_point; } @@ -311,7 +321,8 @@ GPUShader *OVERLAY_shader_edit_curve_wire(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_curve_wire) { sh_data->edit_curve_wire = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_curve_wire_clipped" : "overlay_edit_curve_wire"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_curve_wire_clipped" : + "overlay_edit_curve_wire"); } return sh_data->edit_curve_wire; } @@ -322,8 +333,8 @@ GPUShader *OVERLAY_shader_edit_gpencil_guide_point(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_gpencil_guide_point) { sh_data->edit_gpencil_guide_point = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_gpencil_guide_point_clipped" : - "overlay_edit_gpencil_guide_point"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_gpencil_guide_point_clipped" : + "overlay_edit_gpencil_guide_point"); } return sh_data->edit_gpencil_guide_point; } @@ -334,7 +345,8 @@ GPUShader *OVERLAY_shader_edit_gpencil_point(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_gpencil_point) { sh_data->edit_gpencil_point = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_gpencil_point_clipped" : "overlay_edit_gpencil_point"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_gpencil_point_clipped" : + "overlay_edit_gpencil_point"); } return sh_data->edit_gpencil_point; } @@ -345,7 +357,8 @@ GPUShader *OVERLAY_shader_edit_gpencil_wire(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_gpencil_wire) { sh_data->edit_gpencil_wire = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_gpencil_wire_clipped" : "overlay_edit_gpencil_wire"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_gpencil_wire_clipped" : + "overlay_edit_gpencil_wire"); } return sh_data->edit_gpencil_wire; } @@ -356,7 +369,8 @@ GPUShader *OVERLAY_shader_edit_lattice_point(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_lattice_point) { sh_data->edit_lattice_point = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_lattice_point_clipped" : "overlay_edit_lattice_point"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_lattice_point_clipped" : + "overlay_edit_lattice_point"); } return sh_data->edit_lattice_point; } @@ -367,7 +381,8 @@ GPUShader *OVERLAY_shader_edit_lattice_wire(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_lattice_wire) { sh_data->edit_lattice_wire = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_lattice_wire_clipped" : "overlay_edit_lattice_wire"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_lattice_wire_clipped" : + "overlay_edit_lattice_wire"); } return sh_data->edit_lattice_wire; } @@ -378,7 +393,8 @@ GPUShader *OVERLAY_shader_edit_mesh_face(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_mesh_face) { sh_data->edit_mesh_face = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_mesh_face_clipped" : "overlay_edit_mesh_face"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_mesh_face_clipped" : + "overlay_edit_mesh_face"); } return sh_data->edit_mesh_face; } @@ -389,7 +405,8 @@ GPUShader *OVERLAY_shader_edit_mesh_facedot(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_mesh_facedot) { sh_data->edit_mesh_facedot = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_mesh_facedot_clipped" : "overlay_edit_mesh_facedot"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_mesh_facedot_clipped" : + "overlay_edit_mesh_facedot"); } return sh_data->edit_mesh_facedot; } @@ -400,7 +417,8 @@ GPUShader *OVERLAY_shader_edit_mesh_normal(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_mesh_normals) { sh_data->edit_mesh_normals = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_mesh_normal_clipped" : "overlay_edit_mesh_normal"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_mesh_normal_clipped" : + "overlay_edit_mesh_normal"); } return sh_data->edit_mesh_normals; } @@ -411,7 +429,8 @@ GPUShader *OVERLAY_shader_edit_mesh_analysis(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_mesh_analysis) { sh_data->edit_mesh_analysis = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_mesh_analysis_clipped" : "overlay_edit_mesh_analysis"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_mesh_analysis_clipped" : + "overlay_edit_mesh_analysis"); } return sh_data->edit_mesh_analysis; } @@ -422,7 +441,8 @@ GPUShader *OVERLAY_shader_edit_mesh_skin_root(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_mesh_skin_root) { sh_data->edit_mesh_skin_root = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_mesh_skin_root_clipped" : "overlay_edit_mesh_skin_root"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_mesh_skin_root_clipped" : + "overlay_edit_mesh_skin_root"); } return sh_data->edit_mesh_skin_root; } @@ -433,8 +453,8 @@ GPUShader *OVERLAY_shader_edit_particle_strand(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_particle_strand) { sh_data->edit_particle_strand = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_particle_strand_clipped" : - "overlay_edit_particle_strand"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_particle_strand_clipped" : + "overlay_edit_particle_strand"); } return sh_data->edit_particle_strand; } @@ -445,7 +465,8 @@ GPUShader *OVERLAY_shader_edit_particle_point(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->edit_particle_point) { sh_data->edit_particle_point = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_edit_particle_point_clipped" : "overlay_edit_particle_point"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_edit_particle_point_clipped" : + "overlay_edit_particle_point"); } return sh_data->edit_particle_point; } @@ -457,8 +478,9 @@ GPUShader *OVERLAY_shader_extra(bool is_select) GPUShader **sh = (is_select) ? &sh_data->extra_select : &sh_data->extra; if (!*sh) { *sh = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? (is_select ? "overlay_extra_select_clipped" : "overlay_extra_clipped") : - (is_select ? "overlay_extra_select" : "overlay_extra")); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? + (is_select ? "overlay_extra_select_clipped" : "overlay_extra_clipped") : + (is_select ? "overlay_extra_select" : "overlay_extra")); } return *sh; } @@ -469,7 +491,8 @@ GPUShader *OVERLAY_shader_extra_grid(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->extra_lightprobe_grid) { sh_data->extra_lightprobe_grid = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_extra_grid_clipped" : "overlay_extra_grid"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_extra_grid_clipped" : + "overlay_extra_grid"); } return sh_data->extra_lightprobe_grid; } @@ -480,7 +503,8 @@ GPUShader *OVERLAY_shader_extra_groundline(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->extra_groundline) { sh_data->extra_groundline = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_extra_groundline_clipped" : "overlay_extra_groundline"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_extra_groundline_clipped" : + "overlay_extra_groundline"); } return sh_data->extra_groundline; } @@ -520,7 +544,8 @@ GPUShader *OVERLAY_shader_extra_loose_point(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->extra_loose_point) { sh_data->extra_loose_point = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_extra_loose_point_clipped" : "overlay_extra_loose_point"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_extra_loose_point_clipped" : + "overlay_extra_loose_point"); } return sh_data->extra_loose_point; } @@ -531,7 +556,8 @@ GPUShader *OVERLAY_shader_extra_point(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->extra_point) { sh_data->extra_point = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_extra_point_clipped" : "overlay_extra_point"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_extra_point_clipped" : + "overlay_extra_point"); } return sh_data->extra_point; } @@ -542,7 +568,8 @@ GPUShader *OVERLAY_shader_facing(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->facing) { sh_data->facing = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_facing_clipped" : "overlay_facing"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_facing_clipped" : + "overlay_facing"); } return sh_data->facing; } @@ -624,7 +651,8 @@ GPUShader *OVERLAY_shader_motion_path_line(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->motion_path_line) { sh_data->motion_path_line = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_motion_path_line_clipped" : "overlay_motion_path_line"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_motion_path_line_clipped" : + "overlay_motion_path_line"); } return sh_data->motion_path_line; } @@ -635,7 +663,8 @@ GPUShader *OVERLAY_shader_motion_path_vert(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->motion_path_vert) { sh_data->motion_path_vert = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_motion_path_point_clipped" : "overlay_motion_path_point"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_motion_path_point_clipped" : + "overlay_motion_path_point"); } return sh_data->motion_path_vert; } @@ -646,13 +675,13 @@ GPUShader *OVERLAY_shader_outline_prepass(bool use_wire) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (use_wire && !sh_data->outline_prepass_wire) { sh_data->outline_prepass_wire = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_outline_prepass_wire_clipped" : - "overlay_outline_prepass_wire"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_outline_prepass_wire_clipped" : + "overlay_outline_prepass_wire"); } else if (!sh_data->outline_prepass) { sh_data->outline_prepass = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_outline_prepass_mesh_clipped" : - "overlay_outline_prepass_mesh"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_outline_prepass_mesh_clipped" : + "overlay_outline_prepass_mesh"); } return use_wire ? sh_data->outline_prepass_wire : sh_data->outline_prepass; } @@ -663,8 +692,8 @@ GPUShader *OVERLAY_shader_outline_prepass_curves() OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->outline_prepass_curves) { sh_data->outline_prepass_curves = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_outline_prepass_curves_clipped" : - "overlay_outline_prepass_curves"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_outline_prepass_curves_clipped" : + "overlay_outline_prepass_curves"); } return sh_data->outline_prepass_curves; } @@ -675,8 +704,8 @@ GPUShader *OVERLAY_shader_outline_prepass_gpencil(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->outline_prepass_gpencil) { sh_data->outline_prepass_gpencil = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_outline_prepass_gpencil_clipped" : - "overlay_outline_prepass_gpencil"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_outline_prepass_gpencil_clipped" : + "overlay_outline_prepass_gpencil"); } return sh_data->outline_prepass_gpencil; } @@ -687,8 +716,9 @@ GPUShader *OVERLAY_shader_outline_prepass_pointcloud(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->outline_prepass_pointcloud) { sh_data->outline_prepass_pointcloud = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_outline_prepass_pointcloud_clipped" : - "overlay_outline_prepass_pointcloud"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? + "overlay_outline_prepass_pointcloud_clipped" : + "overlay_outline_prepass_pointcloud"); } return sh_data->outline_prepass_pointcloud; } @@ -708,8 +738,8 @@ GPUShader *OVERLAY_shader_paint_face(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->paint_face) { sh_data->paint_face = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_paint_face_clipped" : - "overlay_paint_face"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_paint_face_clipped" : + "overlay_paint_face"); } return sh_data->paint_face; } @@ -720,8 +750,8 @@ GPUShader *OVERLAY_shader_paint_point(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->paint_point) { sh_data->paint_point = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_paint_point_clipped" : - "overlay_paint_point"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_paint_point_clipped" : + "overlay_paint_point"); } return sh_data->paint_point; } @@ -732,7 +762,8 @@ GPUShader *OVERLAY_shader_paint_texture(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->paint_texture) { sh_data->paint_texture = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_paint_texture_clipped" : "overlay_paint_texture"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_paint_texture_clipped" : + "overlay_paint_texture"); } return sh_data->paint_texture; } @@ -743,7 +774,8 @@ GPUShader *OVERLAY_shader_paint_vertcol(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->paint_vertcol) { sh_data->paint_vertcol = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_paint_vertcol_clipped" : "overlay_paint_vertcol"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_paint_vertcol_clipped" : + "overlay_paint_vertcol"); } return sh_data->paint_vertcol; } @@ -770,7 +802,8 @@ GPUShader *OVERLAY_shader_paint_wire(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->paint_wire) { sh_data->paint_wire = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_paint_wire_clipped" : "overlay_paint_wire"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_paint_wire_clipped" : + "overlay_paint_wire"); } return sh_data->paint_wire; } @@ -781,7 +814,8 @@ GPUShader *OVERLAY_shader_particle_dot(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->particle_dot) { sh_data->particle_dot = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_particle_dot_clipped" : "overlay_particle_dot"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_particle_dot_clipped" : + "overlay_particle_dot"); } return sh_data->particle_dot; } @@ -792,7 +826,8 @@ GPUShader *OVERLAY_shader_particle_shape(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->particle_shape) { sh_data->particle_shape = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_particle_shape_clipped" : "overlay_particle_shape"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_particle_shape_clipped" : + "overlay_particle_shape"); } return sh_data->particle_shape; } @@ -803,7 +838,8 @@ GPUShader *OVERLAY_shader_sculpt_mask(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->sculpt_mask) { sh_data->sculpt_mask = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_sculpt_mask_clipped" : "overlay_sculpt_mask"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_sculpt_mask_clipped" : + "overlay_sculpt_mask"); } return sh_data->sculpt_mask; } @@ -814,8 +850,8 @@ GPUShader *OVERLAY_shader_sculpt_curves_selection(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->sculpt_curves_selection) { sh_data->sculpt_curves_selection = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_sculpt_curves_selection_clipped" : - "overlay_sculpt_curves_selection"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_sculpt_curves_selection_clipped" : + "overlay_sculpt_curves_selection"); } return sh_data->sculpt_curves_selection; } @@ -826,8 +862,8 @@ GPUShader *OVERLAY_shader_viewer_attribute_mesh(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->viewer_attribute_mesh) { sh_data->viewer_attribute_mesh = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_viewer_attribute_mesh_clipped" : - "overlay_viewer_attribute_mesh"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_viewer_attribute_mesh_clipped" : + "overlay_viewer_attribute_mesh"); } return sh_data->viewer_attribute_mesh; } @@ -838,7 +874,7 @@ GPUShader *OVERLAY_shader_viewer_attribute_pointcloud(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->viewer_attribute_pointcloud) { sh_data->viewer_attribute_pointcloud = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_viewer_attribute_pointcloud_clipped" : "overlay_viewer_attribute_pointcloud"); } @@ -851,8 +887,8 @@ GPUShader *OVERLAY_shader_viewer_attribute_curve(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->viewer_attribute_curve) { sh_data->viewer_attribute_curve = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_viewer_attribute_curve_clipped" : - "overlay_viewer_attribute_curve"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_viewer_attribute_curve_clipped" : + "overlay_viewer_attribute_curve"); } return sh_data->viewer_attribute_curve; } @@ -863,8 +899,8 @@ GPUShader *OVERLAY_shader_viewer_attribute_curves(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->viewer_attribute_curves) { sh_data->viewer_attribute_curves = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED ? "overlay_viewer_attribute_curves_clipped" : - "overlay_viewer_attribute_curves"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_viewer_attribute_curves_clipped" : + "overlay_viewer_attribute_curves"); } return sh_data->viewer_attribute_curves; } @@ -875,7 +911,8 @@ struct GPUShader *OVERLAY_shader_uniform_color(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->uniform_color) { sh_data->uniform_color = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_uniform_color_clipped" : "overlay_uniform_color"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_uniform_color_clipped" : + "overlay_uniform_color"); } return sh_data->uniform_color; } @@ -886,8 +923,8 @@ struct GPUShader *OVERLAY_shader_uniform_color_pointcloud() OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->uniform_color_pointcloud) { sh_data->uniform_color_pointcloud = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_uniform_color_pointcloud_clipped" : - "overlay_uniform_color_pointcloud"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_uniform_color_pointcloud_clipped" : + "overlay_uniform_color_pointcloud"); } return sh_data->uniform_color_pointcloud; } @@ -947,7 +984,8 @@ GPUShader *OVERLAY_shader_wireframe_select(void) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->wireframe_select) { sh_data->wireframe_select = GPU_shader_create_from_info_name( - draw_ctx->sh_cfg ? "overlay_wireframe_select_clipped" : "overlay_wireframe_select"); + (draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_wireframe_select_clipped" : + "overlay_wireframe_select"); } return sh_data->wireframe_select; } @@ -958,9 +996,11 @@ GPUShader *OVERLAY_shader_wireframe(bool custom_bias) OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; if (!sh_data->wireframe[custom_bias]) { sh_data->wireframe[custom_bias] = GPU_shader_create_from_info_name( - custom_bias ? (draw_ctx->sh_cfg ? "overlay_wireframe_custom_depth_clipped" : - "overlay_wireframe_custom_depth") : - (draw_ctx->sh_cfg ? "overlay_wireframe_clipped" : "overlay_wireframe")); + custom_bias ? ((draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? + "overlay_wireframe_custom_depth_clipped" : + "overlay_wireframe_custom_depth") : + ((draw_ctx->sh_cfg == GPU_SHADER_CFG_CLIPPED) ? "overlay_wireframe_clipped" : + "overlay_wireframe")); } return sh_data->wireframe[custom_bias]; } From 6da7436cce32934516e65e913a12fc78ebfbc136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 16 Jan 2023 00:33:26 +0100 Subject: [PATCH 0659/1522] DRW: Add debug print for matrix type --- .../draw/intern/shaders/common_debug_print_lib.glsl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/draw/intern/shaders/common_debug_print_lib.glsl b/source/blender/draw/intern/shaders/common_debug_print_lib.glsl index 5dc8f490a79..859e44d7dd2 100644 --- a/source/blender/draw/intern/shaders/common_debug_print_lib.glsl +++ b/source/blender/draw/intern/shaders/common_debug_print_lib.glsl @@ -386,3 +386,13 @@ void drw_print_value(bvec4 value) { drw_print_no_endl("bvec4(", value[0], ", ", value[1], ", ", value[2], ", ", value[3], ")"); } + +void drw_print_value(mat4 value) +{ + drw_print("mat4x4("); + drw_print(" ", value[0]); + drw_print(" ", value[1]); + drw_print(" ", value[2]); + drw_print(" ", value[3]); + drw_print(")"); +} From 945d108ab8c50b2d121e06313f2d90d177b7d31d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 16 Jan 2023 00:37:18 +0100 Subject: [PATCH 0660/1522] GPU: Fix uninitialized variable which created asan warning / errors This wasn't really a problem since these are set on first bind or creation. The test `if (enabled_srgb && srgb_) {` was depending on that variable that in certain case, might not have been initialized (because of lazy init). --- source/blender/gpu/opengl/gl_framebuffer.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/gpu/opengl/gl_framebuffer.hh b/source/blender/gpu/opengl/gl_framebuffer.hh index edc05322153..26bd396e558 100644 --- a/source/blender/gpu/opengl/gl_framebuffer.hh +++ b/source/blender/gpu/opengl/gl_framebuffer.hh @@ -34,9 +34,9 @@ class GLFrameBuffer : public FrameBuffer { /** Copy of the GL state. Contains ONLY color attachments enums for slot binding. */ GLenum gl_attachments_[GPU_FB_MAX_COLOR_ATTACHMENT] = {0}; /** Internal frame-buffers are immutable. */ - bool immutable_; + bool immutable_ = false; /** True is the frame-buffer has its first color target using the GPU_SRGB8_A8 format. */ - bool srgb_; + bool srgb_ = false; /** True is the frame-buffer has been bound using the GL_FRAMEBUFFER_SRGB feature. */ bool enabled_srgb_ = false; From 28db19433eace4a39b56de504b9c246c8722f694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 16 Jan 2023 00:39:47 +0100 Subject: [PATCH 0661/1522] GPU: Math: Add floatBitsToOrderedInt and orderedIntBitsToFloat These allow the usage of `atomicMin` and `atomicMax` function with float values as there is no overload for these types in GLSL. This also allows signed 0 preservation. --- .../common/gpu_shader_utildefines_lib.glsl | 19 +++++++++++++++++++ source/blender/gpu/tests/gpu_math_test.glsl | 15 +++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/source/blender/gpu/shaders/common/gpu_shader_utildefines_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_utildefines_lib.glsl index d56603e5ded..b59dcc6f9c3 100644 --- a/source/blender/gpu/shaders/common/gpu_shader_utildefines_lib.glsl +++ b/source/blender/gpu/shaders/common/gpu_shader_utildefines_lib.glsl @@ -93,4 +93,23 @@ uvec4 unpackUvec4x8(uint data) return (uvec4(data) >> uvec4(0u, 8u, 16u, 24u)) & uvec4(0xFFu); } +/** + * Convert from float representation to ordered int allowing min/max atomic operation. + * Based on: https://stackoverflow.com/a/31010352 + */ +int floatBitsToOrderedInt(float value) +{ + /* Floats can be sorted using their bits interpreted as integers for positive values. + * Negative values do not follow int's two's complement ordering which is reversed. + * So we have to XOR all bits except the sign bits in order to reverse the ordering. + * Note that this is highly hardware dependent, but there seems to be no case of GPU where the + * ints ares not two's complement. */ + int int_value = floatBitsToInt(value); + return (int_value < 0) ? (int_value ^ 0x7FFFFFFF) : int_value; +} +float orderedIntBitsToFloat(int int_value) +{ + return intBitsToFloat((int_value < 0) ? (int_value ^ 0x7FFFFFFF) : int_value); +} + #endif /* GPU_SHADER_UTILDEFINES_GLSL */ diff --git a/source/blender/gpu/tests/gpu_math_test.glsl b/source/blender/gpu/tests/gpu_math_test.glsl index b4e9058381b..f61bd00d58e 100644 --- a/source/blender/gpu/tests/gpu_math_test.glsl +++ b/source/blender/gpu/tests/gpu_math_test.glsl @@ -287,4 +287,19 @@ void main() vec4(0.0f, 0.0f, -1.0f, 1.0f))); EXPECT_NEAR(pers2, expect, 1e-4); } + + TEST(math_matrix, OrderedInt) + { + /* Identity. */ + EXPECT_EQ(orderedIntBitsToFloat(floatBitsToOrderedInt(0.5)), 0.5); + EXPECT_EQ(orderedIntBitsToFloat(floatBitsToOrderedInt(-0.5)), -0.5); + EXPECT_EQ(orderedIntBitsToFloat(floatBitsToOrderedInt(0.0)), 0.0); + EXPECT_EQ(orderedIntBitsToFloat(floatBitsToOrderedInt(-0.0)), -0.0); + + EXPECT_GE(floatBitsToOrderedInt(-0.5), floatBitsToOrderedInt(-1.0)); + EXPECT_LE(floatBitsToOrderedInt(0.5), floatBitsToOrderedInt(1.0)); + EXPECT_LE(floatBitsToOrderedInt(-0.5), floatBitsToOrderedInt(1.0)); + EXPECT_GE(floatBitsToOrderedInt(0.5), floatBitsToOrderedInt(-1.0)); + EXPECT_LE(floatBitsToOrderedInt(-0.0), floatBitsToOrderedInt(0.0)); + } } From b03866288728823d74352ba2ba91ade8d08e1d2e Mon Sep 17 00:00:00 2001 From: Sibo Van Gool Date: Mon, 16 Jan 2023 11:06:01 +1100 Subject: [PATCH 0662/1522] Fix T103559: Check for no-face object for particle baking Meshes spawning particles from faces with with UV's/Vertex-colors but no faces would crash de-referencing a NULL pointer. Resolve by adding a check for this case and an assertion if CD_MFACE is NULL when the mesh has polygons. Ref D16947 --- source/blender/draw/intern/draw_cache_impl_particles.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 5b45fa38704..cba06eec76c 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -311,6 +311,11 @@ static void particle_calculate_parent_uvs(ParticleSystem *psys, } if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { const MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); + if (UNLIKELY(mfaces == NULL)) { + BLI_assert_msg(psmd->mesh_final->totpoly == 0, + "A mesh with polygons should always have a generated 'CD_MFACE' layer!"); + return; + } const MFace *mface = &mfaces[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]); @@ -341,6 +346,11 @@ static void particle_calculate_parent_mcol(ParticleSystem *psys, } if (!ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { const MFace *mfaces = CustomData_get_layer(&psmd->mesh_final->fdata, CD_MFACE); + if (UNLIKELY(mfaces == NULL)) { + BLI_assert_msg(psmd->mesh_final->totpoly == 0, + "A mesh with polygons should always have a generated 'CD_MFACE' layer!"); + return; + } const MFace *mface = &mfaces[num]; for (int j = 0; j < num_col_layers; j++) { /* CustomDataLayer CD_MCOL has 4 structs per face. */ From 33c30af74256445c7cc2fece1b4ddfdd9a8233b3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jan 2023 12:41:11 +1100 Subject: [PATCH 0663/1522] Cleanup: comments in struct declarations Use a consistent style for declaring the names of struct members in their declarations. Note that this convention was already used in many places but not everywhere. Remove spaces around the text (matching commented arguments) with the advantage that the the spell checking utility skips these terms. Making it possible to extract & validate these comments automatically. Also use struct names for `bAnimChannelType` & `bConstraintTypeInfo` which were using brief descriptions. --- intern/ghost/intern/GHOST_SystemWayland.cpp | 56 +- source/blender/blenkernel/intern/action.c | 2 +- source/blender/blenkernel/intern/brush.cc | 46 +- source/blender/blenkernel/intern/constraint.c | 722 +++++++------- source/blender/blenkernel/intern/curve.cc | 46 +- source/blender/blenkernel/intern/curves.cc | 46 +- .../blender/blenkernel/intern/customdata.cc | 75 +- source/blender/blenkernel/intern/fmodifier.c | 237 +++-- source/blender/blenkernel/intern/key.cc | 46 +- source/blender/blenkernel/intern/linestyle.cc | 46 +- source/blender/blenkernel/intern/material.cc | 46 +- source/blender/blenkernel/intern/mball.cc | 46 +- source/blender/blenkernel/intern/mesh.cc | 46 +- source/blender/blenkernel/intern/node.cc | 48 +- source/blender/blenkernel/intern/object.cc | 48 +- .../blender/blenkernel/intern/object_dupli.cc | 29 +- source/blender/blenkernel/intern/paint.cc | 92 +- .../blender/blenkernel/intern/pointcloud.cc | 46 +- .../blender/blenkernel/intern/simulation.cc | 46 +- source/blender/blenkernel/intern/texture.cc | 46 +- source/blender/blenkernel/intern/volume.cc | 50 +- source/blender/blenkernel/intern/workspace.cc | 46 +- .../blender/draw/engines/basic/basic_engine.c | 2 +- .../engines/compositor/compositor_engine.cc | 30 +- .../blender/draw/engines/eevee/eevee_engine.c | 2 +- .../draw/engines/external/external_engine.c | 2 +- .../draw/engines/gpencil/gpencil_engine.c | 2 +- .../draw/engines/image/image_engine.cc | 30 +- .../draw/engines/select/select_debug_engine.c | 2 +- .../draw/engines/select/select_engine.c | 2 +- .../draw/engines/workbench/workbench_engine.c | 2 +- source/blender/draw/intern/draw_manager.c | 2 +- .../editors/animation/anim_channels_defines.c | 926 +++++++++--------- .../editors/animation/anim_channels_edit.c | 2 +- .../editors/animation/keyframes_draw.c | 2 +- .../editors/animation/keyframes_keylist.cc | 8 +- .../blender/editors/asset/intern/asset_ops.cc | 10 +- .../blender/editors/include/ED_file_indexer.h | 2 +- .../editors/space_file/file_indexer.cc | 2 +- .../transform/transform_convert_action.c | 8 +- .../transform/transform_convert_armature.c | 16 +- .../transform/transform_convert_cursor.c | 24 +- .../transform/transform_convert_curve.c | 8 +- .../transform/transform_convert_gpencil.c | 8 +- .../transform/transform_convert_graph.c | 8 +- .../transform/transform_convert_lattice.c | 8 +- .../transform/transform_convert_mask.c | 8 +- .../transform/transform_convert_mball.c | 8 +- .../transform/transform_convert_mesh.c | 8 +- .../transform/transform_convert_mesh_edge.c | 8 +- .../transform/transform_convert_mesh_skin.c | 8 +- .../transform/transform_convert_mesh_uv.c | 8 +- .../transform_convert_mesh_vert_cdata.c | 8 +- .../editors/transform/transform_convert_nla.c | 8 +- .../transform/transform_convert_node.cc | 8 +- .../transform/transform_convert_object.c | 8 +- .../transform_convert_object_texspace.c | 8 +- .../transform/transform_convert_paintcurve.c | 8 +- .../transform/transform_convert_particle.c | 8 +- .../transform/transform_convert_sculpt.c | 8 +- .../transform/transform_convert_sequencer.c | 8 +- .../transform_convert_sequencer_image.c | 8 +- .../transform/transform_convert_tracking.c | 8 +- .../blender_interface/FRS_freestyle.cpp | 11 +- .../intern/MOD_gpencilarmature.c | 36 +- .../intern/MOD_gpencilarray.c | 36 +- .../intern/MOD_gpencilbuild.c | 36 +- .../intern/MOD_gpencilcolor.c | 36 +- .../intern/MOD_gpencildash.c | 36 +- .../intern/MOD_gpencilenvelope.c | 36 +- .../intern/MOD_gpencilhook.c | 36 +- .../intern/MOD_gpencillattice.c | 36 +- .../intern/MOD_gpencillength.c | 36 +- .../intern/MOD_gpencillineart.c | 36 +- .../intern/MOD_gpencilmirror.c | 36 +- .../intern/MOD_gpencilmultiply.c | 36 +- .../intern/MOD_gpencilnoise.c | 36 +- .../intern/MOD_gpenciloffset.c | 36 +- .../intern/MOD_gpencilopacity.c | 36 +- .../intern/MOD_gpenciloutline.c | 36 +- .../intern/MOD_gpencilshrinkwrap.c | 36 +- .../intern/MOD_gpencilsimplify.c | 36 +- .../intern/MOD_gpencilsmooth.c | 36 +- .../intern/MOD_gpencilsubdiv.c | 36 +- .../intern/MOD_gpenciltexture.c | 36 +- .../intern/MOD_gpencilthick.c | 36 +- .../intern/MOD_gpenciltime.c | 36 +- .../intern/MOD_gpenciltint.c | 36 +- .../intern/MOD_gpencilweight_angle.c | 36 +- .../intern/MOD_gpencilweight_proximity.c | 36 +- source/blender/makesrna/intern/rna_key.c | 6 +- .../blender/modifiers/intern/MOD_armature.c | 54 +- source/blender/modifiers/intern/MOD_array.cc | 54 +- source/blender/modifiers/intern/MOD_bevel.c | 54 +- .../blender/modifiers/intern/MOD_boolean.cc | 54 +- source/blender/modifiers/intern/MOD_build.c | 54 +- source/blender/modifiers/intern/MOD_cast.c | 54 +- source/blender/modifiers/intern/MOD_cloth.c | 54 +- .../blender/modifiers/intern/MOD_collision.c | 54 +- .../modifiers/intern/MOD_correctivesmooth.c | 54 +- source/blender/modifiers/intern/MOD_curve.c | 54 +- .../modifiers/intern/MOD_datatransfer.cc | 54 +- .../blender/modifiers/intern/MOD_decimate.c | 54 +- .../blender/modifiers/intern/MOD_displace.cc | 54 +- .../modifiers/intern/MOD_dynamicpaint.c | 54 +- .../blender/modifiers/intern/MOD_edgesplit.c | 54 +- source/blender/modifiers/intern/MOD_explode.c | 54 +- source/blender/modifiers/intern/MOD_fluid.c | 54 +- source/blender/modifiers/intern/MOD_hook.c | 54 +- .../modifiers/intern/MOD_laplaciandeform.c | 54 +- .../modifiers/intern/MOD_laplaciansmooth.c | 54 +- source/blender/modifiers/intern/MOD_lattice.c | 54 +- source/blender/modifiers/intern/MOD_mask.cc | 54 +- .../modifiers/intern/MOD_mesh_to_volume.cc | 54 +- .../blender/modifiers/intern/MOD_meshcache.c | 54 +- .../blender/modifiers/intern/MOD_meshdeform.c | 54 +- .../modifiers/intern/MOD_meshsequencecache.cc | 54 +- source/blender/modifiers/intern/MOD_mirror.cc | 54 +- .../blender/modifiers/intern/MOD_multires.cc | 54 +- source/blender/modifiers/intern/MOD_nodes.cc | 54 +- source/blender/modifiers/intern/MOD_none.c | 54 +- .../modifiers/intern/MOD_normal_edit.cc | 54 +- source/blender/modifiers/intern/MOD_ocean.c | 54 +- .../modifiers/intern/MOD_particleinstance.c | 54 +- .../modifiers/intern/MOD_particlesystem.cc | 54 +- source/blender/modifiers/intern/MOD_remesh.c | 54 +- source/blender/modifiers/intern/MOD_screw.cc | 54 +- .../blender/modifiers/intern/MOD_shapekey.c | 54 +- .../blender/modifiers/intern/MOD_shrinkwrap.c | 54 +- .../modifiers/intern/MOD_simpledeform.c | 54 +- source/blender/modifiers/intern/MOD_skin.c | 54 +- source/blender/modifiers/intern/MOD_smooth.c | 54 +- .../blender/modifiers/intern/MOD_softbody.c | 54 +- .../blender/modifiers/intern/MOD_solidify.c | 54 +- .../blender/modifiers/intern/MOD_subsurf.cc | 54 +- source/blender/modifiers/intern/MOD_surface.c | 54 +- .../modifiers/intern/MOD_surfacedeform.c | 54 +- .../modifiers/intern/MOD_triangulate.cc | 54 +- .../blender/modifiers/intern/MOD_uvproject.cc | 54 +- source/blender/modifiers/intern/MOD_uvwarp.cc | 54 +- .../modifiers/intern/MOD_volume_displace.cc | 54 +- .../modifiers/intern/MOD_volume_to_mesh.cc | 54 +- source/blender/modifiers/intern/MOD_warp.c | 54 +- source/blender/modifiers/intern/MOD_wave.cc | 54 +- .../modifiers/intern/MOD_weighted_normal.cc | 54 +- .../modifiers/intern/MOD_weightvgedit.cc | 54 +- .../modifiers/intern/MOD_weightvgmix.cc | 54 +- .../modifiers/intern/MOD_weightvgproximity.cc | 54 +- source/blender/modifiers/intern/MOD_weld.cc | 54 +- .../blender/modifiers/intern/MOD_wireframe.c | 54 +- source/blender/python/intern/bpy_rna.c | 2 +- source/blender/sequencer/intern/modifier.c | 98 +- .../blender/shader_fx/intern/FX_shader_blur.c | 26 +- .../shader_fx/intern/FX_shader_colorize.c | 26 +- .../blender/shader_fx/intern/FX_shader_flip.c | 26 +- .../blender/shader_fx/intern/FX_shader_glow.c | 26 +- .../shader_fx/intern/FX_shader_pixel.c | 26 +- .../blender/shader_fx/intern/FX_shader_rim.c | 26 +- .../shader_fx/intern/FX_shader_shadow.c | 26 +- .../shader_fx/intern/FX_shader_swirl.c | 26 +- .../blender/shader_fx/intern/FX_shader_wave.c | 26 +- 161 files changed, 3806 insertions(+), 3822 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index d9e5b0c4e9d..fbe5159ea78 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -280,41 +280,41 @@ struct GWL_ModifierInfo { }; static const GWL_ModifierInfo g_modifier_info_table[MOD_INDEX_NUM] = { - /* MOD_INDEX_SHIFT */ + /*MOD_INDEX_SHIFT*/ { - /* display_name */ "Shift", - /* xkb_id */ XKB_MOD_NAME_SHIFT, - /* key_l */ GHOST_kKeyLeftShift, - /* key_r */ GHOST_kKeyRightShift, - /* mod_l */ GHOST_kModifierKeyLeftShift, - /* mod_r */ GHOST_kModifierKeyRightShift, + /*display_name*/ "Shift", + /*xkb_id*/ XKB_MOD_NAME_SHIFT, + /*key_l*/ GHOST_kKeyLeftShift, + /*key_r*/ GHOST_kKeyRightShift, + /*mod_l*/ GHOST_kModifierKeyLeftShift, + /*mod_r*/ GHOST_kModifierKeyRightShift, }, - /* MOD_INDEX_ALT */ + /*MOD_INDEX_ALT*/ { - /* display_name */ "Alt", - /* xkb_id */ XKB_MOD_NAME_ALT, - /* key_l */ GHOST_kKeyLeftAlt, - /* key_r */ GHOST_kKeyRightAlt, - /* mod_l */ GHOST_kModifierKeyLeftAlt, - /* mod_r */ GHOST_kModifierKeyRightAlt, + /*display_name*/ "Alt", + /*xkb_id*/ XKB_MOD_NAME_ALT, + /*key_l*/ GHOST_kKeyLeftAlt, + /*key_r*/ GHOST_kKeyRightAlt, + /*mod_l*/ GHOST_kModifierKeyLeftAlt, + /*mod_r*/ GHOST_kModifierKeyRightAlt, }, - /* MOD_INDEX_CTRL */ + /*MOD_INDEX_CTRL*/ { - /* display_name */ "Control", - /* xkb_id */ XKB_MOD_NAME_CTRL, - /* key_l */ GHOST_kKeyLeftControl, - /* key_r */ GHOST_kKeyRightControl, - /* mod_l */ GHOST_kModifierKeyLeftControl, - /* mod_r */ GHOST_kModifierKeyRightControl, + /*display_name*/ "Control", + /*xkb_id*/ XKB_MOD_NAME_CTRL, + /*key_l*/ GHOST_kKeyLeftControl, + /*key_r*/ GHOST_kKeyRightControl, + /*mod_l*/ GHOST_kModifierKeyLeftControl, + /*mod_r*/ GHOST_kModifierKeyRightControl, }, - /* MOD_INDEX_OS */ + /*MOD_INDEX_OS*/ { - /* display_name */ "OS", - /* xkb_id */ XKB_MOD_NAME_LOGO, - /* key_l */ GHOST_kKeyLeftOS, - /* key_r */ GHOST_kKeyRightOS, - /* mod_l */ GHOST_kModifierKeyLeftOS, - /* mod_r */ GHOST_kModifierKeyRightOS, + /*display_name*/ "OS", + /*xkb_id*/ XKB_MOD_NAME_LOGO, + /*key_l*/ GHOST_kKeyLeftOS, + /*key_r*/ GHOST_kKeyRightOS, + /*mod_l*/ GHOST_kModifierKeyLeftOS, + /*mod_r*/ GHOST_kModifierKeyRightOS, }, }; diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index dcd0c25967b..d4a7a7cbb1e 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -294,7 +294,7 @@ static void action_asset_pre_save(void *asset_ptr, struct AssetMetaData *asset_d } static AssetTypeInfo AssetType_AC = { - /* pre_save_fn */ action_asset_pre_save, + /*pre_save_fn*/ action_asset_pre_save, }; IDTypeInfo IDType_ID_AC = { diff --git a/source/blender/blenkernel/intern/brush.cc b/source/blender/blenkernel/intern/brush.cc index 28baa871e12..414a316ba7a 100644 --- a/source/blender/blenkernel/intern/brush.cc +++ b/source/blender/blenkernel/intern/brush.cc @@ -411,33 +411,33 @@ static void brush_undo_preserve(BlendLibReader *reader, ID *id_new, ID *id_old) } IDTypeInfo IDType_ID_BR = { - /* id_code */ ID_BR, - /* id_filter */ FILTER_ID_BR, - /* main_listbase_index */ INDEX_ID_BR, - /* struct_size */ sizeof(Brush), - /* name */ "Brush", - /* name_plural */ "brushes", - /* translation_context */ BLT_I18NCONTEXT_ID_BRUSH, - /* flags */ IDTYPE_FLAGS_NO_ANIMDATA, - /* asset_type_info */ nullptr, + /*id_code*/ ID_BR, + /*id_filter*/ FILTER_ID_BR, + /*main_listbase_index*/ INDEX_ID_BR, + /*struct_size*/ sizeof(Brush), + /*name*/ "Brush", + /*name_plural*/ "brushes", + /*translation_context*/ BLT_I18NCONTEXT_ID_BRUSH, + /*flags*/ IDTYPE_FLAGS_NO_ANIMDATA, + /*asset_type_info*/ nullptr, - /* init_data */ brush_init_data, - /* copy_data */ brush_copy_data, - /* free_data */ brush_free_data, - /* make_local */ brush_make_local, - /* foreach_id */ brush_foreach_id, - /* foreach_cache */ nullptr, - /* foreach_path */ brush_foreach_path, - /* owner_pointer_get */ nullptr, + /*init_data*/ brush_init_data, + /*copy_data*/ brush_copy_data, + /*free_data*/ brush_free_data, + /*make_local*/ brush_make_local, + /*foreach_id*/ brush_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ brush_foreach_path, + /*owner_pointer_get*/ nullptr, - /* blend_write */ brush_blend_write, - /* blend_read_data */ brush_blend_read_data, - /* blend_read_lib */ brush_blend_read_lib, - /* blend_read_expand */ brush_blend_read_expand, + /*blend_write*/ brush_blend_write, + /*blend_read_data*/ brush_blend_read_data, + /*blend_read_lib*/ brush_blend_read_lib, + /*blend_read_expand*/ brush_blend_read_expand, - /* blend_read_undo_preserve */ brush_undo_preserve, + /*blend_read_undo_preserve*/ brush_undo_preserve, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; static RNG *brush_rng; diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 4ebf7d184b3..93ab47651ed 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -787,18 +787,18 @@ static void constraint_target_to_mat4(Object *ob, */ #if 0 static bConstraintTypeInfo CTI_CONSTRNAME = { - CONSTRAINT_TYPE_CONSTRNAME, /* type */ - sizeof(bConstrNameConstraint), /* size */ - "ConstrName", /* name */ - "bConstrNameConstraint", /* struct name */ - constrname_free, /* free data */ - constrname_id_looper, /* id looper */ - constrname_copy, /* copy data */ - constrname_new_data, /* new data */ - constrname_get_tars, /* get constraint targets */ - constrname_flush_tars, /* flush constraint targets */ - constrname_get_tarmat, /* get target matrix */ - constrname_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_CONSTRNAME, + /*size*/ sizeof(bConstrNameConstraint), + /*name*/ "ConstrName", + /*structName*/ "bConstrNameConstraint", + /*free_data*/ constrname_free, + /*id_looper*/ constrname_id_looper, + /*copy_data*/ constrname_copy, + /*new_data*/ constrname_new_data, + /*get_constraint_targets*/ constrname_get_tars, + /*flush_constraint_targets*/ constrname_flush_tars, + /*get_target_matrix*/ constrname_get_tarmat, + /*evaluate_constraint*/ constrname_evaluate, }; #endif @@ -1109,18 +1109,18 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar /* XXX NOTE: con->flag should be CONSTRAINT_SPACEONCE for bone-childof, patched in `readfile.c`. */ static bConstraintTypeInfo CTI_CHILDOF = { - CONSTRAINT_TYPE_CHILDOF, /* type */ - sizeof(bChildOfConstraint), /* size */ - N_("Child Of"), /* name */ - "bChildOfConstraint", /* struct name */ - NULL, /* free data */ - childof_id_looper, /* id looper */ - NULL, /* copy data */ - childof_new_data, /* new data */ - childof_get_tars, /* get constraint targets */ - childof_flush_tars, /* flush constraint targets */ - default_get_tarmat, /* get a target matrix */ - childof_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_CHILDOF, + /*size*/ sizeof(bChildOfConstraint), + /*name*/ N_("Child Of"), + /*structName*/ "bChildOfConstraint", + /*free_data*/ NULL, + /*id_looper*/ childof_id_looper, + /*copy_data*/ NULL, + /*new_data*/ childof_new_data, + /*get_constraint_targets*/ childof_get_tars, + /*flush_constraint_targets*/ childof_flush_tars, + /* get a target matrix */ default_get_tarmat, + /*evaluate_constraint*/ childof_evaluate, }; /* -------- TrackTo Constraint ------- */ @@ -1293,18 +1293,18 @@ static void trackto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar } static bConstraintTypeInfo CTI_TRACKTO = { - CONSTRAINT_TYPE_TRACKTO, /* type */ - sizeof(bTrackToConstraint), /* size */ - N_("Track To"), /* name */ - "bTrackToConstraint", /* struct name */ - NULL, /* free data */ - trackto_id_looper, /* id looper */ - NULL, /* copy data */ - trackto_new_data, /* new data */ - trackto_get_tars, /* get constraint targets */ - trackto_flush_tars, /* flush constraint targets */ - default_get_tarmat, /* get target matrix */ - trackto_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_TRACKTO, + /*size*/ sizeof(bTrackToConstraint), + /*name*/ N_("Track To"), + /*structName*/ "bTrackToConstraint", + /*free_data*/ NULL, + /*id_looper*/ trackto_id_looper, + /*copy_data*/ NULL, + /*new_data*/ trackto_new_data, + /*get_constraint_targets*/ trackto_get_tars, + /*flush_constraint_targets*/ trackto_flush_tars, + /*get_target_matrix*/ default_get_tarmat, + /*evaluate_constraint*/ trackto_evaluate, }; /* --------- Inverse-Kinematics --------- */ @@ -1399,18 +1399,18 @@ static void kinematic_get_tarmat(struct Depsgraph *UNUSED(depsgraph), } static bConstraintTypeInfo CTI_KINEMATIC = { - CONSTRAINT_TYPE_KINEMATIC, /* type */ - sizeof(bKinematicConstraint), /* size */ - N_("IK"), /* name */ - "bKinematicConstraint", /* struct name */ - NULL, /* free data */ - kinematic_id_looper, /* id looper */ - NULL, /* copy data */ - kinematic_new_data, /* new data */ - kinematic_get_tars, /* get constraint targets */ - kinematic_flush_tars, /* flush constraint targets */ - kinematic_get_tarmat, /* get target matrix */ - NULL, /* evaluate - solved as separate loop */ + /*type*/ CONSTRAINT_TYPE_KINEMATIC, + /*size*/ sizeof(bKinematicConstraint), + /*name*/ N_("IK"), + /*structName*/ "bKinematicConstraint", + /*free_data*/ NULL, + /*id_looper*/ kinematic_id_looper, + /*copy_data*/ NULL, + /*new_data*/ kinematic_new_data, + /*get_constraint_targets*/ kinematic_get_tars, + /*flush_constraint_targets*/ kinematic_flush_tars, + /*get_target_matrix*/ kinematic_get_tarmat, + /* evaluate - solved as separate loop */ NULL, }; /* -------- Follow-Path Constraint ---------- */ @@ -1577,18 +1577,18 @@ static void followpath_evaluate(bConstraint *con, bConstraintOb *cob, ListBase * } static bConstraintTypeInfo CTI_FOLLOWPATH = { - CONSTRAINT_TYPE_FOLLOWPATH, /* type */ - sizeof(bFollowPathConstraint), /* size */ - N_("Follow Path"), /* name */ - "bFollowPathConstraint", /* struct name */ - NULL, /* free data */ - followpath_id_looper, /* id looper */ - NULL, /* copy data */ - followpath_new_data, /* new data */ - followpath_get_tars, /* get constraint targets */ - followpath_flush_tars, /* flush constraint targets */ - followpath_get_tarmat, /* get target matrix */ - followpath_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_FOLLOWPATH, + /*size*/ sizeof(bFollowPathConstraint), + /*name*/ N_("Follow Path"), + /*structName*/ "bFollowPathConstraint", + /*free_data*/ NULL, + /*id_looper*/ followpath_id_looper, + /*copy_data*/ NULL, + /*new_data*/ followpath_new_data, + /*get_constraint_targets*/ followpath_get_tars, + /*flush_constraint_targets*/ followpath_flush_tars, + /*get_target_matrix*/ followpath_get_tarmat, + /*evaluate_constraint*/ followpath_evaluate, }; /* --------- Limit Location --------- */ @@ -1630,18 +1630,18 @@ static void loclimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UN } static bConstraintTypeInfo CTI_LOCLIMIT = { - CONSTRAINT_TYPE_LOCLIMIT, /* type */ - sizeof(bLocLimitConstraint), /* size */ - N_("Limit Location"), /* name */ - "bLocLimitConstraint", /* struct name */ - NULL, /* free data */ - NULL, /* id looper */ - NULL, /* copy data */ - NULL, /* new data */ - NULL, /* get constraint targets */ - NULL, /* flush constraint targets */ - NULL, /* get target matrix */ - loclimit_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_LOCLIMIT, + /*size*/ sizeof(bLocLimitConstraint), + /*name*/ N_("Limit Location"), + /*structName*/ "bLocLimitConstraint", + /*free_data*/ NULL, + /*id_looper*/ NULL, + /*copy_data*/ NULL, + /*new_data*/ NULL, + /*get_constraint_targets*/ NULL, + /*flush_constraint_targets*/ NULL, + /*get_target_matrix*/ NULL, + /*evaluate_constraint*/ loclimit_evaluate, }; /* -------- Limit Rotation --------- */ @@ -1711,18 +1711,18 @@ static void rotlimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *UN } static bConstraintTypeInfo CTI_ROTLIMIT = { - CONSTRAINT_TYPE_ROTLIMIT, /* type */ - sizeof(bRotLimitConstraint), /* size */ - N_("Limit Rotation"), /* name */ - "bRotLimitConstraint", /* struct name */ - NULL, /* free data */ - NULL, /* id looper */ - NULL, /* copy data */ - NULL, /* new data */ - NULL, /* get constraint targets */ - NULL, /* flush constraint targets */ - NULL, /* get target matrix */ - rotlimit_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_ROTLIMIT, + /*size*/ sizeof(bRotLimitConstraint), + /*name*/ N_("Limit Rotation"), + /*structName*/ "bRotLimitConstraint", + /*free_data*/ NULL, + /*id_looper*/ NULL, + /*copy_data*/ NULL, + /*new_data*/ NULL, + /*get_constraint_targets*/ NULL, + /*flush_constraint_targets*/ NULL, + /*get_target_matrix*/ NULL, + /*evaluate_constraint*/ rotlimit_evaluate, }; /* --------- Limit Scale --------- */ @@ -1778,18 +1778,18 @@ static void sizelimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *U } static bConstraintTypeInfo CTI_SIZELIMIT = { - CONSTRAINT_TYPE_SIZELIMIT, /* type */ - sizeof(bSizeLimitConstraint), /* size */ - N_("Limit Scale"), /* name */ - "bSizeLimitConstraint", /* struct name */ - NULL, /* free data */ - NULL, /* id looper */ - NULL, /* copy data */ - NULL, /* new data */ - NULL, /* get constraint targets */ - NULL, /* flush constraint targets */ - NULL, /* get target matrix */ - sizelimit_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_SIZELIMIT, + /*size*/ sizeof(bSizeLimitConstraint), + /*name*/ N_("Limit Scale"), + /*structName*/ "bSizeLimitConstraint", + /*free_data*/ NULL, + /*id_looper*/ NULL, + /*copy_data*/ NULL, + /*new_data*/ NULL, + /*get_constraint_targets*/ NULL, + /*flush_constraint_targets*/ NULL, + /*get_target_matrix*/ NULL, + /*evaluate_constraint*/ sizelimit_evaluate, }; /* ----------- Copy Location ------------- */ @@ -1875,18 +1875,18 @@ static void loclike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar } static bConstraintTypeInfo CTI_LOCLIKE = { - CONSTRAINT_TYPE_LOCLIKE, /* type */ - sizeof(bLocateLikeConstraint), /* size */ - N_("Copy Location"), /* name */ - "bLocateLikeConstraint", /* struct name */ - NULL, /* free data */ - loclike_id_looper, /* id looper */ - NULL, /* copy data */ - loclike_new_data, /* new data */ - loclike_get_tars, /* get constraint targets */ - loclike_flush_tars, /* flush constraint targets */ - default_get_tarmat, /* get target matrix */ - loclike_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_LOCLIKE, + /*size*/ sizeof(bLocateLikeConstraint), + /*name*/ N_("Copy Location"), + /*structName*/ "bLocateLikeConstraint", + /*free_data*/ NULL, + /*id_looper*/ loclike_id_looper, + /*copy_data*/ NULL, + /*new_data*/ loclike_new_data, + /*get_constraint_targets*/ loclike_get_tars, + /*flush_constraint_targets*/ loclike_flush_tars, + /*get_target_matrix*/ default_get_tarmat, + /*evaluate_constraint*/ loclike_evaluate, }; /* ----------- Copy Rotation ------------- */ @@ -2052,18 +2052,18 @@ static void rotlike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar } static bConstraintTypeInfo CTI_ROTLIKE = { - CONSTRAINT_TYPE_ROTLIKE, /* type */ - sizeof(bRotateLikeConstraint), /* size */ - N_("Copy Rotation"), /* name */ - "bRotateLikeConstraint", /* struct name */ - NULL, /* free data */ - rotlike_id_looper, /* id looper */ - NULL, /* copy data */ - rotlike_new_data, /* new data */ - rotlike_get_tars, /* get constraint targets */ - rotlike_flush_tars, /* flush constraint targets */ - default_get_tarmat, /* get target matrix */ - rotlike_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_ROTLIKE, + /*size*/ sizeof(bRotateLikeConstraint), + /*name*/ N_("Copy Rotation"), + /*structName*/ "bRotateLikeConstraint", + /*free_data*/ NULL, + /*id_looper*/ rotlike_id_looper, + /*copy_data*/ NULL, + /*new_data*/ rotlike_new_data, + /*get_constraint_targets*/ rotlike_get_tars, + /*flush_constraint_targets*/ rotlike_flush_tars, + /*get_target_matrix*/ default_get_tarmat, + /*evaluate_constraint*/ rotlike_evaluate, }; /* ---------- Copy Scale ---------- */ @@ -2182,18 +2182,18 @@ static void sizelike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *ta } static bConstraintTypeInfo CTI_SIZELIKE = { - CONSTRAINT_TYPE_SIZELIKE, /* type */ - sizeof(bSizeLikeConstraint), /* size */ - N_("Copy Scale"), /* name */ - "bSizeLikeConstraint", /* struct name */ - NULL, /* free data */ - sizelike_id_looper, /* id looper */ - NULL, /* copy data */ - sizelike_new_data, /* new data */ - sizelike_get_tars, /* get constraint targets */ - sizelike_flush_tars, /* flush constraint targets */ - default_get_tarmat, /* get target matrix */ - sizelike_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_SIZELIKE, + /*size*/ sizeof(bSizeLikeConstraint), + /*name*/ N_("Copy Scale"), + /*structName*/ "bSizeLikeConstraint", + /*free_data*/ NULL, + /*id_looper*/ sizelike_id_looper, + /*copy_data*/ NULL, + /*new_data*/ sizelike_new_data, + /*get_constraint_targets*/ sizelike_get_tars, + /*flush_constraint_targets*/ sizelike_flush_tars, + /*get_target_matrix*/ default_get_tarmat, + /*evaluate_constraint*/ sizelike_evaluate, }; /* ----------- Copy Transforms ------------- */ @@ -2288,18 +2288,18 @@ static void translike_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t } static bConstraintTypeInfo CTI_TRANSLIKE = { - CONSTRAINT_TYPE_TRANSLIKE, /* type */ - sizeof(bTransLikeConstraint), /* size */ - N_("Copy Transforms"), /* name */ - "bTransLikeConstraint", /* struct name */ - NULL, /* free data */ - translike_id_looper, /* id looper */ - NULL, /* copy data */ - NULL, /* new data */ - translike_get_tars, /* get constraint targets */ - translike_flush_tars, /* flush constraint targets */ - default_get_tarmat_full_bbone, /* get target matrix */ - translike_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_TRANSLIKE, + /*size*/ sizeof(bTransLikeConstraint), + /*name*/ N_("Copy Transforms"), + /*structName*/ "bTransLikeConstraint", + /*free_data*/ NULL, + /*id_looper*/ translike_id_looper, + /*copy_data*/ NULL, + /*new_data*/ NULL, + /*get_constraint_targets*/ translike_get_tars, + /*flush_constraint_targets*/ translike_flush_tars, + /*get_target_matrix*/ default_get_tarmat_full_bbone, + /*evaluate_constraint*/ translike_evaluate, }; /* ---------- Maintain Volume ---------- */ @@ -2357,18 +2357,18 @@ static void samevolume_evaluate(bConstraint *con, bConstraintOb *cob, ListBase * } static bConstraintTypeInfo CTI_SAMEVOL = { - CONSTRAINT_TYPE_SAMEVOL, /* type */ - sizeof(bSameVolumeConstraint), /* size */ - N_("Maintain Volume"), /* name */ - "bSameVolumeConstraint", /* struct name */ - NULL, /* free data */ - NULL, /* id looper */ - NULL, /* copy data */ - samevolume_new_data, /* new data */ - NULL, /* get constraint targets */ - NULL, /* flush constraint targets */ - NULL, /* get target matrix */ - samevolume_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_SAMEVOL, + /*size*/ sizeof(bSameVolumeConstraint), + /*name*/ N_("Maintain Volume"), + /*structName*/ "bSameVolumeConstraint", + /*free_data*/ NULL, + /*id_looper*/ NULL, + /*copy_data*/ NULL, + /*new_data*/ samevolume_new_data, + /*get_constraint_targets*/ NULL, + /*flush_constraint_targets*/ NULL, + /*get_target_matrix*/ NULL, + /*evaluate_constraint*/ samevolume_evaluate, }; /* ----------- Python Constraint -------------- */ @@ -2489,18 +2489,18 @@ static void pycon_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targe } static bConstraintTypeInfo CTI_PYTHON = { - CONSTRAINT_TYPE_PYTHON, /* type */ - sizeof(bPythonConstraint), /* size */ - N_("Script"), /* name */ - "bPythonConstraint", /* struct name */ - pycon_free, /* free data */ - pycon_id_looper, /* id looper */ - pycon_copy, /* copy data */ - pycon_new_data, /* new data */ - pycon_get_tars, /* get constraint targets */ - NULL, /* flush constraint targets */ - pycon_get_tarmat, /* get target matrix */ - pycon_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_PYTHON, + /*size*/ sizeof(bPythonConstraint), + /*name*/ N_("Script"), + /*structName*/ "bPythonConstraint", + /*free_data*/ pycon_free, + /*id_looper*/ pycon_id_looper, + /*copy_data*/ pycon_copy, + /*new_data*/ pycon_new_data, + /*get_constraint_targets*/ pycon_get_tars, + /*flush_constraint_targets*/ NULL, + /*get_target_matrix*/ pycon_get_tarmat, + /*evaluate_constraint*/ pycon_evaluate, }; /* ----------- Armature Constraint -------------- */ @@ -2741,18 +2741,18 @@ static void armdef_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targ } static bConstraintTypeInfo CTI_ARMATURE = { - CONSTRAINT_TYPE_ARMATURE, /* type */ - sizeof(bArmatureConstraint), /* size */ - N_("Armature"), /* name */ - "bArmatureConstraint", /* struct name */ - armdef_free, /* free data */ - armdef_id_looper, /* id looper */ - armdef_copy, /* copy data */ - NULL, /* new data */ - armdef_get_tars, /* get constraint targets */ - NULL, /* flush constraint targets */ - armdef_get_tarmat, /* get target matrix */ - armdef_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_ARMATURE, + /*size*/ sizeof(bArmatureConstraint), + /*name*/ N_("Armature"), + /*structName*/ "bArmatureConstraint", + /*free_data*/ armdef_free, + /*id_looper*/ armdef_id_looper, + /*copy_data*/ armdef_copy, + /*new_data*/ NULL, + /*get_constraint_targets*/ armdef_get_tars, + /*flush_constraint_targets*/ NULL, + /*get_target_matrix*/ armdef_get_tarmat, + /*evaluate_constraint*/ armdef_evaluate, }; /* -------- Action Constraint ----------- */ @@ -2957,18 +2957,18 @@ static void actcon_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targ } static bConstraintTypeInfo CTI_ACTION = { - CONSTRAINT_TYPE_ACTION, /* type */ - sizeof(bActionConstraint), /* size */ - N_("Action"), /* name */ - "bActionConstraint", /* struct name */ - NULL, /* free data */ - actcon_id_looper, /* id looper */ - NULL, /* copy data */ - actcon_new_data, /* new data */ - actcon_get_tars, /* get constraint targets */ - actcon_flush_tars, /* flush constraint targets */ - actcon_get_tarmat, /* get target matrix */ - actcon_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_ACTION, + /*size*/ sizeof(bActionConstraint), + /*name*/ N_("Action"), + /*structName*/ "bActionConstraint", + /*free_data*/ NULL, + /*id_looper*/ actcon_id_looper, + /*copy_data*/ NULL, + /*new_data*/ actcon_new_data, + /*get_constraint_targets*/ actcon_get_tars, + /*flush_constraint_targets*/ actcon_flush_tars, + /*get_target_matrix*/ actcon_get_tarmat, + /*evaluate_constraint*/ actcon_evaluate, }; /* --------- Locked Track ---------- */ @@ -3273,18 +3273,18 @@ static void locktrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t } static bConstraintTypeInfo CTI_LOCKTRACK = { - CONSTRAINT_TYPE_LOCKTRACK, /* type */ - sizeof(bLockTrackConstraint), /* size */ - N_("Locked Track"), /* name */ - "bLockTrackConstraint", /* struct name */ - NULL, /* free data */ - locktrack_id_looper, /* id looper */ - NULL, /* copy data */ - locktrack_new_data, /* new data */ - locktrack_get_tars, /* get constraint targets */ - locktrack_flush_tars, /* flush constraint targets */ - default_get_tarmat, /* get target matrix */ - locktrack_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_LOCKTRACK, + /*size*/ sizeof(bLockTrackConstraint), + /*name*/ N_("Locked Track"), + /*structName*/ "bLockTrackConstraint", + /*free_data*/ NULL, + /*id_looper*/ locktrack_id_looper, + /*copy_data*/ NULL, + /*new_data*/ locktrack_new_data, + /*get_constraint_targets*/ locktrack_get_tars, + /*flush_constraint_targets*/ locktrack_flush_tars, + /*get_target_matrix*/ default_get_tarmat, + /*evaluate_constraint*/ locktrack_evaluate, }; /* ---------- Limit Distance Constraint ----------- */ @@ -3416,18 +3416,18 @@ static void distlimit_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t } static bConstraintTypeInfo CTI_DISTLIMIT = { - CONSTRAINT_TYPE_DISTLIMIT, /* type */ - sizeof(bDistLimitConstraint), /* size */ - N_("Limit Distance"), /* name */ - "bDistLimitConstraint", /* struct name */ - NULL, /* free data */ - distlimit_id_looper, /* id looper */ - NULL, /* copy data */ - distlimit_new_data, /* new data */ - distlimit_get_tars, /* get constraint targets */ - distlimit_flush_tars, /* flush constraint targets */ - default_get_tarmat, /* get a target matrix */ - distlimit_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_DISTLIMIT, + /*size*/ sizeof(bDistLimitConstraint), + /*name*/ N_("Limit Distance"), + /*structName*/ "bDistLimitConstraint", + /*free_data*/ NULL, + /*id_looper*/ distlimit_id_looper, + /*copy_data*/ NULL, + /*new_data*/ distlimit_new_data, + /*get_constraint_targets*/ distlimit_get_tars, + /*flush_constraint_targets*/ distlimit_flush_tars, + /* get a target matrix */ default_get_tarmat, + /*evaluate_constraint*/ distlimit_evaluate, }; /* ---------- Stretch To ------------ */ @@ -3624,18 +3624,18 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t } static bConstraintTypeInfo CTI_STRETCHTO = { - CONSTRAINT_TYPE_STRETCHTO, /* type */ - sizeof(bStretchToConstraint), /* size */ - N_("Stretch To"), /* name */ - "bStretchToConstraint", /* struct name */ - NULL, /* free data */ - stretchto_id_looper, /* id looper */ - NULL, /* copy data */ - stretchto_new_data, /* new data */ - stretchto_get_tars, /* get constraint targets */ - stretchto_flush_tars, /* flush constraint targets */ - default_get_tarmat, /* get target matrix */ - stretchto_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_STRETCHTO, + /*size*/ sizeof(bStretchToConstraint), + /*name*/ N_("Stretch To"), + /*structName*/ "bStretchToConstraint", + /*free_data*/ NULL, + /*id_looper*/ stretchto_id_looper, + /*copy_data*/ NULL, + /*new_data*/ stretchto_new_data, + /*get_constraint_targets*/ stretchto_get_tars, + /*flush_constraint_targets*/ stretchto_flush_tars, + /*get_target_matrix*/ default_get_tarmat, + /*evaluate_constraint*/ stretchto_evaluate, }; /* ---------- Floor ------------ */ @@ -3755,18 +3755,18 @@ static void minmax_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *targ } static bConstraintTypeInfo CTI_MINMAX = { - CONSTRAINT_TYPE_MINMAX, /* type */ - sizeof(bMinMaxConstraint), /* size */ - N_("Floor"), /* name */ - "bMinMaxConstraint", /* struct name */ - NULL, /* free data */ - minmax_id_looper, /* id looper */ - NULL, /* copy data */ - minmax_new_data, /* new data */ - minmax_get_tars, /* get constraint targets */ - minmax_flush_tars, /* flush constraint targets */ - default_get_tarmat, /* get target matrix */ - minmax_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_MINMAX, + /*size*/ sizeof(bMinMaxConstraint), + /*name*/ N_("Floor"), + /*structName*/ "bMinMaxConstraint", + /*free_data*/ NULL, + /*id_looper*/ minmax_id_looper, + /*copy_data*/ NULL, + /*new_data*/ minmax_new_data, + /*get_constraint_targets*/ minmax_get_tars, + /*flush_constraint_targets*/ minmax_flush_tars, + /*get_target_matrix*/ default_get_tarmat, + /*evaluate_constraint*/ minmax_evaluate, }; /* -------- Clamp To ---------- */ @@ -3941,18 +3941,18 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar } static bConstraintTypeInfo CTI_CLAMPTO = { - CONSTRAINT_TYPE_CLAMPTO, /* type */ - sizeof(bClampToConstraint), /* size */ - N_("Clamp To"), /* name */ - "bClampToConstraint", /* struct name */ - NULL, /* free data */ - clampto_id_looper, /* id looper */ - NULL, /* copy data */ - NULL, /* new data */ - clampto_get_tars, /* get constraint targets */ - clampto_flush_tars, /* flush constraint targets */ - clampto_get_tarmat, /* get target matrix */ - clampto_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_CLAMPTO, + /*size*/ sizeof(bClampToConstraint), + /*name*/ N_("Clamp To"), + /*structName*/ "bClampToConstraint", + /*free_data*/ NULL, + /*id_looper*/ clampto_id_looper, + /*copy_data*/ NULL, + /*new_data*/ NULL, + /*get_constraint_targets*/ clampto_get_tars, + /*flush_constraint_targets*/ clampto_flush_tars, + /*get_target_matrix*/ clampto_get_tarmat, + /*evaluate_constraint*/ clampto_evaluate, }; /* ---------- Transform Constraint ----------- */ @@ -4150,18 +4150,18 @@ static void transform_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t } static bConstraintTypeInfo CTI_TRANSFORM = { - CONSTRAINT_TYPE_TRANSFORM, /* type */ - sizeof(bTransformConstraint), /* size */ - N_("Transformation"), /* name */ - "bTransformConstraint", /* struct name */ - NULL, /* free data */ - transform_id_looper, /* id looper */ - NULL, /* copy data */ - transform_new_data, /* new data */ - transform_get_tars, /* get constraint targets */ - transform_flush_tars, /* flush constraint targets */ - default_get_tarmat, /* get a target matrix */ - transform_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_TRANSFORM, + /*size*/ sizeof(bTransformConstraint), + /*name*/ N_("Transformation"), + /*structName*/ "bTransformConstraint", + /*free_data*/ NULL, + /*id_looper*/ transform_id_looper, + /*copy_data*/ NULL, + /*new_data*/ transform_new_data, + /*get_constraint_targets*/ transform_get_tars, + /*flush_constraint_targets*/ transform_flush_tars, + /* get a target matrix */ default_get_tarmat, + /*evaluate_constraint*/ transform_evaluate, }; /* ---------- Shrinkwrap Constraint ----------- */ @@ -4381,18 +4381,18 @@ static void shrinkwrap_evaluate(bConstraint *UNUSED(con), bConstraintOb *cob, Li } static bConstraintTypeInfo CTI_SHRINKWRAP = { - CONSTRAINT_TYPE_SHRINKWRAP, /* type */ - sizeof(bShrinkwrapConstraint), /* size */ - N_("Shrinkwrap"), /* name */ - "bShrinkwrapConstraint", /* struct name */ - NULL, /* free data */ - shrinkwrap_id_looper, /* id looper */ - NULL, /* copy data */ - shrinkwrap_new_data, /* new data */ - shrinkwrap_get_tars, /* get constraint targets */ - shrinkwrap_flush_tars, /* flush constraint targets */ - shrinkwrap_get_tarmat, /* get a target matrix */ - shrinkwrap_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_SHRINKWRAP, + /*size*/ sizeof(bShrinkwrapConstraint), + /*name*/ N_("Shrinkwrap"), + /*structName*/ "bShrinkwrapConstraint", + /*free_data*/ NULL, + /*id_looper*/ shrinkwrap_id_looper, + /*copy_data*/ NULL, + /*new_data*/ shrinkwrap_new_data, + /*get_constraint_targets*/ shrinkwrap_get_tars, + /*flush_constraint_targets*/ shrinkwrap_flush_tars, + /* get a target matrix */ shrinkwrap_get_tarmat, + /*evaluate_constraint*/ shrinkwrap_evaluate, }; /* --------- Damped Track ---------- */ @@ -4546,18 +4546,18 @@ static void damptrack_do_transform(float matrix[4][4], const float tarvec_in[3], } static bConstraintTypeInfo CTI_DAMPTRACK = { - CONSTRAINT_TYPE_DAMPTRACK, /* type */ - sizeof(bDampTrackConstraint), /* size */ - N_("Damped Track"), /* name */ - "bDampTrackConstraint", /* struct name */ - NULL, /* free data */ - damptrack_id_looper, /* id looper */ - NULL, /* copy data */ - damptrack_new_data, /* new data */ - damptrack_get_tars, /* get constraint targets */ - damptrack_flush_tars, /* flush constraint targets */ - default_get_tarmat, /* get target matrix */ - damptrack_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_DAMPTRACK, + /*size*/ sizeof(bDampTrackConstraint), + /*name*/ N_("Damped Track"), + /*structName*/ "bDampTrackConstraint", + /*free_data*/ NULL, + /*id_looper*/ damptrack_id_looper, + /*copy_data*/ NULL, + /*new_data*/ damptrack_new_data, + /*get_constraint_targets*/ damptrack_get_tars, + /*flush_constraint_targets*/ damptrack_flush_tars, + /*get_target_matrix*/ default_get_tarmat, + /*evaluate_constraint*/ damptrack_evaluate, }; /* ----------- Spline IK ------------ */ @@ -4641,18 +4641,18 @@ static void splineik_get_tarmat(struct Depsgraph *UNUSED(depsgraph), } static bConstraintTypeInfo CTI_SPLINEIK = { - CONSTRAINT_TYPE_SPLINEIK, /* type */ - sizeof(bSplineIKConstraint), /* size */ - N_("Spline IK"), /* name */ - "bSplineIKConstraint", /* struct name */ - splineik_free, /* free data */ - splineik_id_looper, /* id looper */ - splineik_copy, /* copy data */ - splineik_new_data, /* new data */ - splineik_get_tars, /* get constraint targets */ - splineik_flush_tars, /* flush constraint targets */ - splineik_get_tarmat, /* get target matrix */ - NULL, /* evaluate - solved as separate loop */ + /*type*/ CONSTRAINT_TYPE_SPLINEIK, + /*size*/ sizeof(bSplineIKConstraint), + /*name*/ N_("Spline IK"), + /*structName*/ "bSplineIKConstraint", + /*free_data*/ splineik_free, + /*id_looper*/ splineik_id_looper, + /*copy_data*/ splineik_copy, + /*new_data*/ splineik_new_data, + /*get_constraint_targets*/ splineik_get_tars, + /*flush_constraint_targets*/ splineik_flush_tars, + /*get_target_matrix*/ splineik_get_tarmat, + /* evaluate - solved as separate loop */ NULL, }; /* ----------- Pivot ------------- */ @@ -4765,19 +4765,19 @@ static void pivotcon_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *ta } static bConstraintTypeInfo CTI_PIVOT = { - CONSTRAINT_TYPE_PIVOT, /* type */ - sizeof(bPivotConstraint), /* size */ - N_("Pivot"), /* name */ - "bPivotConstraint", /* struct name */ - NULL, /* free data */ - pivotcon_id_looper, /* id looper */ - NULL, /* copy data */ - NULL, - /* new data */ /* XXX: might be needed to get 'normal' pivot behavior... */ - pivotcon_get_tars, /* get constraint targets */ - pivotcon_flush_tars, /* flush constraint targets */ - default_get_tarmat, /* get target matrix */ - pivotcon_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_PIVOT, + /*size*/ sizeof(bPivotConstraint), + /*name*/ N_("Pivot"), + /*structName*/ "bPivotConstraint", + /*free_data*/ NULL, + /*id_looper*/ pivotcon_id_looper, + /*copy_data*/ NULL, + /*new_data*/ NULL, + /* XXX: might be needed to get 'normal' pivot behavior. */ + /*get_constraint_targets*/ pivotcon_get_tars, + /*flush_constraint_targets*/ pivotcon_flush_tars, + /*get_target_matrix*/ default_get_tarmat, + /*evaluate_constraint*/ pivotcon_evaluate, }; /* ----------- Follow Track ------------- */ @@ -5185,18 +5185,18 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase } static bConstraintTypeInfo CTI_FOLLOWTRACK = { - CONSTRAINT_TYPE_FOLLOWTRACK, /* type */ - sizeof(bFollowTrackConstraint), /* size */ - N_("Follow Track"), /* name */ - "bFollowTrackConstraint", /* struct name */ - NULL, /* free data */ - followtrack_id_looper, /* id looper */ - NULL, /* copy data */ - followtrack_new_data, /* new data */ - NULL, /* get constraint targets */ - NULL, /* flush constraint targets */ - NULL, /* get target matrix */ - followtrack_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_FOLLOWTRACK, + /*size*/ sizeof(bFollowTrackConstraint), + /*name*/ N_("Follow Track"), + /*structName*/ "bFollowTrackConstraint", + /*free_data*/ NULL, + /*id_looper*/ followtrack_id_looper, + /*copy_data*/ NULL, + /*new_data*/ followtrack_new_data, + /*get_constraint_targets*/ NULL, + /*flush_constraint_targets*/ NULL, + /*get_target_matrix*/ NULL, + /*evaluate_constraint*/ followtrack_evaluate, }; /* ----------- Camera Solver ------------- */ @@ -5243,18 +5243,18 @@ static void camerasolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase } static bConstraintTypeInfo CTI_CAMERASOLVER = { - CONSTRAINT_TYPE_CAMERASOLVER, /* type */ - sizeof(bCameraSolverConstraint), /* size */ - N_("Camera Solver"), /* name */ - "bCameraSolverConstraint", /* struct name */ - NULL, /* free data */ - camerasolver_id_looper, /* id looper */ - NULL, /* copy data */ - camerasolver_new_data, /* new data */ - NULL, /* get constraint targets */ - NULL, /* flush constraint targets */ - NULL, /* get target matrix */ - camerasolver_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_CAMERASOLVER, + /*size*/ sizeof(bCameraSolverConstraint), + /*name*/ N_("Camera Solver"), + /*structName*/ "bCameraSolverConstraint", + /*free_data*/ NULL, + /*id_looper*/ camerasolver_id_looper, + /*copy_data*/ NULL, + /*new_data*/ camerasolver_new_data, + /*get_constraint_targets*/ NULL, + /*flush_constraint_targets*/ NULL, + /*get_target_matrix*/ NULL, + /*evaluate_constraint*/ camerasolver_evaluate, }; /* ----------- Object Solver ------------- */ @@ -5329,18 +5329,18 @@ static void objectsolver_evaluate(bConstraint *con, bConstraintOb *cob, ListBase } static bConstraintTypeInfo CTI_OBJECTSOLVER = { - CONSTRAINT_TYPE_OBJECTSOLVER, /* type */ - sizeof(bObjectSolverConstraint), /* size */ - N_("Object Solver"), /* name */ - "bObjectSolverConstraint", /* struct name */ - NULL, /* free data */ - objectsolver_id_looper, /* id looper */ - NULL, /* copy data */ - objectsolver_new_data, /* new data */ - NULL, /* get constraint targets */ - NULL, /* flush constraint targets */ - NULL, /* get target matrix */ - objectsolver_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_OBJECTSOLVER, + /*size*/ sizeof(bObjectSolverConstraint), + /*name*/ N_("Object Solver"), + /*structName*/ "bObjectSolverConstraint", + /*free_data*/ NULL, + /*id_looper*/ objectsolver_id_looper, + /*copy_data*/ NULL, + /*new_data*/ objectsolver_new_data, + /*get_constraint_targets*/ NULL, + /*flush_constraint_targets*/ NULL, + /*get_target_matrix*/ NULL, + /*evaluate_constraint*/ objectsolver_evaluate, }; /* ----------- Transform Cache ------------- */ @@ -5426,18 +5426,18 @@ static void transformcache_new_data(void *cdata) } static bConstraintTypeInfo CTI_TRANSFORM_CACHE = { - CONSTRAINT_TYPE_TRANSFORM_CACHE, /* type */ - sizeof(bTransformCacheConstraint), /* size */ - N_("Transform Cache"), /* name */ - "bTransformCacheConstraint", /* struct name */ - transformcache_free, /* free data */ - transformcache_id_looper, /* id looper */ - transformcache_copy, /* copy data */ - transformcache_new_data, /* new data */ - NULL, /* get constraint targets */ - NULL, /* flush constraint targets */ - NULL, /* get target matrix */ - transformcache_evaluate, /* evaluate */ + /*type*/ CONSTRAINT_TYPE_TRANSFORM_CACHE, + /*size*/ sizeof(bTransformCacheConstraint), + /*name*/ N_("Transform Cache"), + /*structName*/ "bTransformCacheConstraint", + /*free_data*/ transformcache_free, + /*id_looper*/ transformcache_id_looper, + /*copy_data*/ transformcache_copy, + /*new_data*/ transformcache_new_data, + /*get_constraint_targets*/ NULL, + /*flush_constraint_targets*/ NULL, + /*get_target_matrix*/ NULL, + /*evaluate_constraint*/ transformcache_evaluate, }; /* ************************* Constraints Type-Info *************************** */ diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index 139d4a45553..be6c7502891 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -304,33 +304,33 @@ static void curve_blend_read_expand(BlendExpander *expander, ID *id) } IDTypeInfo IDType_ID_CU_LEGACY = { - /* id_code */ ID_CU_LEGACY, - /* id_filter */ FILTER_ID_CU_LEGACY, - /* main_listbase_index */ INDEX_ID_CU_LEGACY, - /* struct_size */ sizeof(Curve), - /* name */ "Curve", - /* name_plural */ "curves", - /* translation_context */ BLT_I18NCONTEXT_ID_CURVE_LEGACY, - /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE, - /* asset_type_info */ nullptr, + /*id_code*/ ID_CU_LEGACY, + /*id_filter*/ FILTER_ID_CU_LEGACY, + /*main_listbase_index*/ INDEX_ID_CU_LEGACY, + /*struct_size*/ sizeof(Curve), + /*name*/ "Curve", + /*name_plural*/ "curves", + /*translation_context*/ BLT_I18NCONTEXT_ID_CURVE_LEGACY, + /*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE, + /*asset_type_info*/ nullptr, - /* init_data */ curve_init_data, - /* copy_data */ curve_copy_data, - /* free_data */ curve_free_data, - /* make_local */ nullptr, - /* foreach_id */ curve_foreach_id, - /* foreach_cache */ nullptr, - /* foreach_path */ nullptr, - /* owner_pointer_get */ nullptr, + /*init_data*/ curve_init_data, + /*copy_data*/ curve_copy_data, + /*free_data*/ curve_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ curve_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ nullptr, + /*owner_pointer_get*/ nullptr, - /* blend_write */ curve_blend_write, - /* blend_read_data */ curve_blend_read_data, - /* blend_read_lib */ curve_blend_read_lib, - /* blend_read_expand */ curve_blend_read_expand, + /*blend_write*/ curve_blend_write, + /*blend_read_data*/ curve_blend_read_data, + /*blend_read_lib*/ curve_blend_read_lib, + /*blend_read_expand*/ curve_blend_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; void BKE_curve_editfont_free(Curve *cu) diff --git a/source/blender/blenkernel/intern/curves.cc b/source/blender/blenkernel/intern/curves.cc index 84ffb5e5314..0bdddc9c389 100644 --- a/source/blender/blenkernel/intern/curves.cc +++ b/source/blender/blenkernel/intern/curves.cc @@ -199,33 +199,33 @@ static void curves_blend_read_expand(BlendExpander *expander, ID *id) } IDTypeInfo IDType_ID_CV = { - /* id_code */ ID_CV, - /* id_filter */ FILTER_ID_CV, - /* main_listbase_index */ INDEX_ID_CV, - /* struct_size */ sizeof(Curves), - /* name */ "Curves", - /* name_plural */ "hair_curves", - /* translation_context */ BLT_I18NCONTEXT_ID_CURVES, - /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE, - /* asset_type_info */ nullptr, + /*id_code*/ ID_CV, + /*id_filter*/ FILTER_ID_CV, + /*main_listbase_index*/ INDEX_ID_CV, + /*struct_size*/ sizeof(Curves), + /*name*/ "Curves", + /*name_plural*/ "hair_curves", + /*translation_context*/ BLT_I18NCONTEXT_ID_CURVES, + /*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE, + /*asset_type_info*/ nullptr, - /* init_data */ curves_init_data, - /* copy_data */ curves_copy_data, - /* free_data */ curves_free_data, - /* make_local */ nullptr, - /* foreach_id */ curves_foreach_id, - /* foreach_cache */ nullptr, - /* foreach_path */ nullptr, - /* owner_pointer_get */ nullptr, + /*init_data*/ curves_init_data, + /*copy_data*/ curves_copy_data, + /*free_data*/ curves_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ curves_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ nullptr, + /*owner_pointer_get*/ nullptr, - /* blend_write */ curves_blend_write, - /* blend_read_data */ curves_blend_read_data, - /* blend_read_lib */ curves_blend_read_lib, - /* blend_read_expand */ curves_blend_read_expand, + /*blend_write*/ curves_blend_write, + /*blend_read_data*/ curves_blend_read_data, + /*blend_read_lib*/ curves_blend_read_lib, + /*blend_read_expand*/ curves_blend_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; void *BKE_curves_add(Main *bmain, const char *name) diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index a8b8782062e..b9e6b1c5e6d 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -2028,71 +2028,70 @@ static const char *LAYERTYPENAMES[CD_NUMTYPES] = { }; const CustomData_MeshMasks CD_MASK_BAREMESH = { - /* vmask */ CD_MASK_PROP_FLOAT3, - /* emask */ CD_MASK_MEDGE, - /* fmask */ 0, - /* pmask */ CD_MASK_MPOLY | CD_MASK_FACEMAP, - /* lmask */ CD_MASK_MLOOP, + /*vmask*/ CD_MASK_PROP_FLOAT3, + /*emask*/ CD_MASK_MEDGE, + /*fmask*/ 0, + /*pmask*/ CD_MASK_MPOLY | CD_MASK_FACEMAP, + /*lmask*/ CD_MASK_MLOOP, }; const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = { - /* vmask */ CD_MASK_PROP_FLOAT3 | CD_MASK_ORIGINDEX, - /* emask */ CD_MASK_MEDGE | CD_MASK_ORIGINDEX, - /* fmask */ 0, - /* pmask */ CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_ORIGINDEX, - /* lmask */ CD_MASK_MLOOP, + /*vmask*/ CD_MASK_PROP_FLOAT3 | CD_MASK_ORIGINDEX, + /*emask*/ CD_MASK_MEDGE | CD_MASK_ORIGINDEX, + /*fmask*/ 0, + /*pmask*/ CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_ORIGINDEX, + /*lmask*/ CD_MASK_MLOOP, }; const CustomData_MeshMasks CD_MASK_MESH = { - /* vmask */ (CD_MASK_PROP_FLOAT3 | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | - CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | CD_MASK_CREASE | CD_MASK_BWEIGHT), - /* emask */ + /*vmask*/ (CD_MASK_PROP_FLOAT3 | CD_MASK_MDEFORMVERT | CD_MASK_MVERT_SKIN | + CD_MASK_PAINT_MASK | CD_MASK_PROP_ALL | CD_MASK_CREASE | CD_MASK_BWEIGHT), + /*emask*/ (CD_MASK_MEDGE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_BWEIGHT | CD_MASK_CREASE), - /* fmask */ 0, - /* pmask */ + /*fmask*/ 0, + /*pmask*/ (CD_MASK_MPOLY | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL), - /* lmask */ + /*lmask*/ (CD_MASK_MLOOP | CD_MASK_MDISPS | 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_CREASE | CD_MASK_BWEIGHT), - /* emask */ + /*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_CREASE | CD_MASK_BWEIGHT), + /*emask*/ (CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_BWEIGHT | CD_MASK_PROP_ALL | CD_MASK_CREASE), - /* fmask */ (CD_MASK_ORIGINDEX | CD_MASK_ORIGSPACE | CD_MASK_PREVIEW_MCOL | CD_MASK_TANGENT), - /* pmask */ + /*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), - /* lmask */ + /*lmask*/ (CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP | - CD_MASK_PROP_ALL), /* XXX MISSING CD_MASK_MLOOPTANGENT ? */ + 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_CREASE), - /* emask */ (CD_MASK_BWEIGHT | CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL), - /* fmask */ 0, - /* pmask */ + /*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_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), - /* lmask */ + /*lmask*/ (CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), }; const CustomData_MeshMasks CD_MASK_EVERYTHING = { - /* vmask */ (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_CREASE), - /* emask */ + /*vmask*/ (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_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), - /* fmask */ + /*fmask*/ (CD_MASK_MFACE | CD_MASK_ORIGINDEX | CD_MASK_NORMAL | CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGSPACE | CD_MASK_TANGENT | CD_MASK_TESSLOOPNORMAL | CD_MASK_PREVIEW_MCOL | CD_MASK_PROP_ALL), - /* pmask */ + /*pmask*/ (CD_MASK_MPOLY | CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL), - /* lmask */ + /*lmask*/ (CD_MASK_MLOOP | CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_MLOOPTANGENT | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL), diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 46dc01edbff..46828a43818 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -61,20 +61,19 @@ static CLG_LogRef LOG = {"bke.fmodifier"}; */ #if 0 static FModifierTypeInfo FMI_MODNAME = { - FMODIFIER_TYPE_MODNAME, /* type */ - sizeof(FMod_ModName), /* size */ - FMI_TYPE_SOME_ACTION, /* action type */ - FMI_REQUIRES_SOME_REQUIREMENT, /* requirements */ - "Modifier Name", /* name */ - "FMod_ModName", /* struct name */ - 0, /* storage size */ - fcm_modname_free, /* free data */ - fcm_modname_relink, /* relink data */ - fcm_modname_copy, /* copy data */ - fcm_modname_new_data, /* new data */ - fcm_modname_verify, /* verify */ - fcm_modname_time, /* evaluate time */ - fcm_modname_evaluate, /* evaluate */ + /*type*/ FMODIFIER_TYPE_MODNAME, + /*size*/ sizeof(FMod_ModName), + /*acttype*/ FMI_TYPE_SOME_ACTION, + /*requires*/ FMI_REQUIRES_SOME_REQUIREMENT, + /*name*/ "Modifier Name", + /*structName*/ "FMod_ModName", + /*storage_size*/ 0, + /*free_data*/ fcm_modname_free, + /*copy_data*/ fcm_modname_copy, + /*new_data*/ fcm_modname_new_data, + /*verify_data*/ fcm_modname_verify, + /*evaluate_modifier_time*/ fcm_modname_time, + /*evaluate_modifier*/ fcm_modname_evaluate, }; #endif @@ -226,19 +225,19 @@ static void fcm_generator_evaluate( } static FModifierTypeInfo FMI_GENERATOR = { - FMODIFIER_TYPE_GENERATOR, /* type */ - sizeof(FMod_Generator), /* size */ - FMI_TYPE_GENERATE_CURVE, /* action type */ - FMI_REQUIRES_NOTHING, /* requirements */ - N_("Generator"), /* name */ - "FMod_Generator", /* struct name */ - 0, /* storage size */ - fcm_generator_free, /* free data */ - fcm_generator_copy, /* copy data */ - fcm_generator_new_data, /* new data */ - fcm_generator_verify, /* verify */ - NULL, /* evaluate time */ - fcm_generator_evaluate, /* evaluate */ + /*type*/ FMODIFIER_TYPE_GENERATOR, + /*size*/ sizeof(FMod_Generator), + /*acttype*/ FMI_TYPE_GENERATE_CURVE, + /*requires*/ FMI_REQUIRES_NOTHING, + /*name*/ N_("Generator"), + /*structName*/ "FMod_Generator", + /*storage_size*/ 0, + /*free_data*/ fcm_generator_free, + /*copy_data*/ fcm_generator_copy, + /*new_data*/ fcm_generator_new_data, + /*verify_data*/ fcm_generator_verify, + /*evaluate_modifier_time*/ NULL, + /*evaluate_modifier*/ fcm_generator_evaluate, }; /* Built-In Function Generator F-Curve Modifier --------------------------- */ @@ -356,19 +355,19 @@ static void fcm_fn_generator_evaluate( } static FModifierTypeInfo FMI_FN_GENERATOR = { - FMODIFIER_TYPE_FN_GENERATOR, /* type */ - sizeof(FMod_FunctionGenerator), /* size */ - FMI_TYPE_GENERATE_CURVE, /* action type */ - FMI_REQUIRES_NOTHING, /* requirements */ - N_("Built-In Function"), /* name */ - "FMod_FunctionGenerator", /* struct name */ - 0, /* storage size */ - NULL, /* free data */ - NULL, /* copy data */ - fcm_fn_generator_new_data, /* new data */ - NULL, /* verify */ - NULL, /* evaluate time */ - fcm_fn_generator_evaluate, /* evaluate */ + /*type*/ FMODIFIER_TYPE_FN_GENERATOR, + /*size*/ sizeof(FMod_FunctionGenerator), + /*acttype*/ FMI_TYPE_GENERATE_CURVE, + /*requires*/ FMI_REQUIRES_NOTHING, + /*name*/ N_("Built-In Function"), + /*structName*/ "FMod_FunctionGenerator", + /*storage_size*/ 0, + /*free_data*/ NULL, + /*copy_data*/ NULL, + /*new_data*/ fcm_fn_generator_new_data, + /*verify_data*/ NULL, + /*evaluate_modifier_time*/ NULL, + /*evaluate_modifier*/ fcm_fn_generator_evaluate, }; /* Envelope F-Curve Modifier --------------------------- */ @@ -469,19 +468,19 @@ static void fcm_envelope_evaluate( } static FModifierTypeInfo FMI_ENVELOPE = { - FMODIFIER_TYPE_ENVELOPE, /* type */ - sizeof(FMod_Envelope), /* size */ - FMI_TYPE_REPLACE_VALUES, /* action type */ - 0, /* requirements */ - N_("Envelope"), /* name */ - "FMod_Envelope", /* struct name */ - 0, /* storage size */ - fcm_envelope_free, /* free data */ - fcm_envelope_copy, /* copy data */ - fcm_envelope_new_data, /* new data */ - fcm_envelope_verify, /* verify */ - NULL, /* evaluate time */ - fcm_envelope_evaluate, /* evaluate */ + /*type*/ FMODIFIER_TYPE_ENVELOPE, + /*size*/ sizeof(FMod_Envelope), + /*acttype*/ FMI_TYPE_REPLACE_VALUES, + /*requires*/ 0, + /*name*/ N_("Envelope"), + /*structName*/ "FMod_Envelope", + /*storage_size*/ 0, + /*free_data*/ fcm_envelope_free, + /*copy_data*/ fcm_envelope_copy, + /*new_data*/ fcm_envelope_new_data, + /*verify_data*/ fcm_envelope_verify, + /*evaluate_modifier_time*/ NULL, + /*evaluate_modifier*/ fcm_envelope_evaluate, }; /* exported function for finding points */ @@ -768,19 +767,19 @@ static void fcm_cycles_evaluate(FCurve *UNUSED(fcu), } static FModifierTypeInfo FMI_CYCLES = { - FMODIFIER_TYPE_CYCLES, /* type */ - sizeof(FMod_Cycles), /* size */ - FMI_TYPE_EXTRAPOLATION, /* action type */ - FMI_REQUIRES_ORIGINAL_DATA, /* requirements */ - CTX_N_(BLT_I18NCONTEXT_ID_ACTION, "Cycles"), /* name */ - "FMod_Cycles", /* struct name */ - sizeof(tFCMED_Cycles), /* storage size */ - NULL, /* free data */ - NULL, /* copy data */ - fcm_cycles_new_data, /* new data */ - NULL /*fcm_cycles_verify*/, /* verify */ - fcm_cycles_time, /* evaluate time */ - fcm_cycles_evaluate, /* evaluate */ + /*type*/ FMODIFIER_TYPE_CYCLES, + /*size*/ sizeof(FMod_Cycles), + /*acttype*/ FMI_TYPE_EXTRAPOLATION, + /*requires*/ FMI_REQUIRES_ORIGINAL_DATA, + /*name*/ CTX_N_(BLT_I18NCONTEXT_ID_ACTION, "Cycles"), + /*structName*/ "FMod_Cycles", + /*storage_size*/ sizeof(tFCMED_Cycles), + /*free_data*/ NULL, + /*copy_data*/ NULL, + /*new_data*/ fcm_cycles_new_data, + /*verify_data*/ NULL /*fcm_cycles_verify*/, + /*evaluate_modifier_time*/ fcm_cycles_time, + /*evaluate_modifier*/ fcm_cycles_evaluate, }; /* Noise F-Curve Modifier --------------------------- */ @@ -830,19 +829,19 @@ static void fcm_noise_evaluate( } static FModifierTypeInfo FMI_NOISE = { - FMODIFIER_TYPE_NOISE, /* type */ - sizeof(FMod_Noise), /* size */ - FMI_TYPE_REPLACE_VALUES, /* action type */ - 0, /* requirements */ - N_("Noise"), /* name */ - "FMod_Noise", /* struct name */ - 0, /* storage size */ - NULL, /* free data */ - NULL, /* copy data */ - fcm_noise_new_data, /* new data */ - NULL /*fcm_noise_verify*/, /* verify */ - NULL, /* evaluate time */ - fcm_noise_evaluate, /* evaluate */ + /*type*/ FMODIFIER_TYPE_NOISE, + /*size*/ sizeof(FMod_Noise), + /*acttype*/ FMI_TYPE_REPLACE_VALUES, + /*requires*/ 0, + /*name*/ N_("Noise"), + /*structName*/ "FMod_Noise", + /*storage_size*/ 0, + /*free_data*/ NULL, + /*copy_data*/ NULL, + /*new_data*/ fcm_noise_new_data, + /*verify_data*/ NULL /*fcm_noise_verify*/, + /*evaluate_modifier_time*/ NULL, + /*evaluate_modifier*/ fcm_noise_evaluate, }; /* Python F-Curve Modifier --------------------------- */ @@ -888,19 +887,19 @@ static void fcm_python_evaluate(FCurve *UNUSED(fcu), } static FModifierTypeInfo FMI_PYTHON = { - FMODIFIER_TYPE_PYTHON, /* type */ - sizeof(FMod_Python), /* size */ - FMI_TYPE_GENERATE_CURVE, /* action type */ - FMI_REQUIRES_RUNTIME_CHECK, /* requirements */ - N_("Python"), /* name */ - "FMod_Python", /* struct name */ - 0, /* storage size */ - fcm_python_free, /* free data */ - fcm_python_copy, /* copy data */ - fcm_python_new_data, /* new data */ - NULL /*fcm_python_verify*/, /* verify */ - NULL /*fcm_python_time*/, /* evaluate time */ - fcm_python_evaluate, /* evaluate */ + /*type*/ FMODIFIER_TYPE_PYTHON, + /*size*/ sizeof(FMod_Python), + /*acttype*/ FMI_TYPE_GENERATE_CURVE, + /*requires*/ FMI_REQUIRES_RUNTIME_CHECK, + /*name*/ N_("Python"), + /*structName*/ "FMod_Python", + /*storage_size*/ 0, + /*free_data*/ fcm_python_free, + /*copy_data*/ fcm_python_copy, + /*new_data*/ fcm_python_new_data, + /*verify_data*/ NULL /*fcm_python_verify*/, + /*evaluate_modifier_time*/ NULL /*fcm_python_time*/, + /*evaluate_modifier*/ fcm_python_evaluate, }; /* Limits F-Curve Modifier --------------------------- */ @@ -943,20 +942,19 @@ static void fcm_limits_evaluate(FCurve *UNUSED(fcu), } static FModifierTypeInfo FMI_LIMITS = { - FMODIFIER_TYPE_LIMITS, /* type */ - sizeof(FMod_Limits), /* size */ - FMI_TYPE_GENERATE_CURVE, - /* action type */ /* XXX... err... */ - FMI_REQUIRES_RUNTIME_CHECK, /* requirements */ - N_("Limits"), /* name */ - "FMod_Limits", /* struct name */ - 0, /* storage size */ - NULL, /* free data */ - NULL, /* copy data */ - NULL, /* new data */ - NULL, /* verify */ - fcm_limits_time, /* evaluate time */ - fcm_limits_evaluate, /* evaluate */ + /*type*/ FMODIFIER_TYPE_LIMITS, + /*size*/ sizeof(FMod_Limits), + /*acttype*/ FMI_TYPE_GENERATE_CURVE, + /*requires*/ FMI_REQUIRES_RUNTIME_CHECK, /* XXX... err... */ + /*name*/ N_("Limits"), + /*structName*/ "FMod_Limits", + /*storage_size*/ 0, + /*free_data*/ NULL, + /*copy_data*/ NULL, + /*new_data*/ NULL, + /*verify_data*/ NULL, + /*evaluate_modifier_time*/ fcm_limits_time, + /*evaluate_modifier*/ fcm_limits_evaluate, }; /* Stepped F-Curve Modifier --------------------------- */ @@ -1004,20 +1002,19 @@ static float fcm_stepped_time(FCurve *UNUSED(fcu), } static FModifierTypeInfo FMI_STEPPED = { - FMODIFIER_TYPE_STEPPED, /* type */ - sizeof(FMod_Limits), /* size */ - FMI_TYPE_GENERATE_CURVE, - /* action type */ /* XXX... err... */ - FMI_REQUIRES_RUNTIME_CHECK, /* requirements */ - N_("Stepped"), /* name */ - "FMod_Stepped", /* struct name */ - 0, /* storage size */ - NULL, /* free data */ - NULL, /* copy data */ - fcm_stepped_new_data, /* new data */ - NULL, /* verify */ - fcm_stepped_time, /* evaluate time */ - NULL, /* evaluate */ + /*type*/ FMODIFIER_TYPE_STEPPED, + /*size*/ sizeof(FMod_Limits), + /*acttype*/ FMI_TYPE_GENERATE_CURVE, + /*requires*/ FMI_REQUIRES_RUNTIME_CHECK, /* XXX... err... */ + /*name*/ N_("Stepped"), + /*structName*/ "FMod_Stepped", + /*storage_size*/ 0, + /*free_data*/ NULL, + /*copy_data*/ NULL, + /*new_data*/ fcm_stepped_new_data, + /*verify_data*/ NULL, + /*evaluate_modifier_time*/ fcm_stepped_time, + /*evaluate_modifier*/ NULL, }; /** \} */ diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 4b3a42e4c8a..57d040c5c4f 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -195,35 +195,35 @@ static void shapekey_blend_read_expand(BlendExpander *expander, ID *id) } IDTypeInfo IDType_ID_KE = { - /* id_code */ ID_KE, - /* id_filter */ FILTER_ID_KE, - /* main_listbase_index */ INDEX_ID_KE, - /* struct_size */ sizeof(Key), - /* name */ "Key", - /* name_plural */ "shape_keys", - /* translation_context */ BLT_I18NCONTEXT_ID_SHAPEKEY, - /* flags */ IDTYPE_FLAGS_NO_LIBLINKING, - /* asset_type_info */ nullptr, + /*id_code*/ ID_KE, + /*id_filter*/ FILTER_ID_KE, + /*main_listbase_index*/ INDEX_ID_KE, + /*struct_size*/ sizeof(Key), + /*name*/ "Key", + /*name_plural*/ "shape_keys", + /*translation_context*/ BLT_I18NCONTEXT_ID_SHAPEKEY, + /*flags*/ IDTYPE_FLAGS_NO_LIBLINKING, + /*asset_type_info*/ nullptr, - /* init_data */ nullptr, - /* copy_data */ shapekey_copy_data, - /* free_data */ shapekey_free_data, - /* make_local */ nullptr, - /* foreach_id */ shapekey_foreach_id, - /* foreach_cache */ nullptr, - /* foreach_path */ nullptr, + /*init_data*/ nullptr, + /*copy_data*/ shapekey_copy_data, + /*free_data*/ shapekey_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ shapekey_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ nullptr, /* A bit weird, due to shape-keys not being strictly speaking embedded data... But they also * share a lot with those (non linkable, only ever used by one owner ID, etc.). */ - /* owner_pointer_get */ shapekey_owner_pointer_get, + /*owner_pointer_get*/ shapekey_owner_pointer_get, - /* blend_write */ shapekey_blend_write, - /* blend_read_data */ shapekey_blend_read_data, - /* blend_read_lib */ shapekey_blend_read_lib, - /* blend_read_expand */ shapekey_blend_read_expand, + /*blend_write*/ shapekey_blend_write, + /*blend_read_data*/ shapekey_blend_read_data, + /*blend_read_lib*/ shapekey_blend_read_lib, + /*blend_read_expand*/ shapekey_blend_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; #define KEY_MODE_DUMMY 0 /* use where mode isn't checked for */ diff --git a/source/blender/blenkernel/intern/linestyle.cc b/source/blender/blenkernel/intern/linestyle.cc index 3976331d599..a08e7f34e1d 100644 --- a/source/blender/blenkernel/intern/linestyle.cc +++ b/source/blender/blenkernel/intern/linestyle.cc @@ -732,33 +732,33 @@ static void linestyle_blend_read_expand(BlendExpander *expander, ID *id) } IDTypeInfo IDType_ID_LS = { - /* id_code */ ID_LS, - /* id_filter */ FILTER_ID_LS, - /* main_listbase_index */ INDEX_ID_LS, - /* struct_size */ sizeof(FreestyleLineStyle), - /* name */ "FreestyleLineStyle", - /* name_plural */ "linestyles", - /* translation_context */ BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE, - /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE, - /* asset_type_info */ nullptr, + /*id_code*/ ID_LS, + /*id_filter*/ FILTER_ID_LS, + /*main_listbase_index*/ INDEX_ID_LS, + /*struct_size*/ sizeof(FreestyleLineStyle), + /*name*/ "FreestyleLineStyle", + /*name_plural*/ "linestyles", + /*translation_context*/ BLT_I18NCONTEXT_ID_FREESTYLELINESTYLE, + /*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE, + /*asset_type_info*/ nullptr, - /* init_data */ linestyle_init_data, - /* copy_data */ linestyle_copy_data, - /* free_data */ linestyle_free_data, - /* make_local */ nullptr, - /* foreach_id */ linestyle_foreach_id, - /* foreach_cache */ nullptr, - /* foreach_path */ nullptr, - /* owner_pointer_get */ nullptr, + /*init_data*/ linestyle_init_data, + /*copy_data*/ linestyle_copy_data, + /*free_data*/ linestyle_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ linestyle_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ nullptr, + /*owner_pointer_get*/ nullptr, - /* blend_write */ linestyle_blend_write, - /* blend_read_data */ linestyle_blend_read_data, - /* blend_read_lib */ linestyle_blend_read_lib, - /* blend_read_expand */ linestyle_blend_read_expand, + /*blend_write*/ linestyle_blend_write, + /*blend_read_data*/ linestyle_blend_read_data, + /*blend_read_lib*/ linestyle_blend_read_lib, + /*blend_read_expand*/ linestyle_blend_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; static const char *modifier_name[LS_MODIFIER_NUM] = { diff --git a/source/blender/blenkernel/intern/material.cc b/source/blender/blenkernel/intern/material.cc index 58478dce847..0fd3ec4f8cd 100644 --- a/source/blender/blenkernel/intern/material.cc +++ b/source/blender/blenkernel/intern/material.cc @@ -243,33 +243,33 @@ static void material_blend_read_expand(BlendExpander *expander, ID *id) } IDTypeInfo IDType_ID_MA = { - /* id_code */ ID_MA, - /* id_filter */ FILTER_ID_MA, - /* main_listbase_index */ INDEX_ID_MA, - /* struct_size */ sizeof(Material), - /* name */ "Material", - /* name_plural */ "materials", - /* translation_context */ BLT_I18NCONTEXT_ID_MATERIAL, - /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE, - /* asset_type_info */ nullptr, + /*id_code*/ ID_MA, + /*id_filter*/ FILTER_ID_MA, + /*main_listbase_index*/ INDEX_ID_MA, + /*struct_size*/ sizeof(Material), + /*name*/ "Material", + /*name_plural*/ "materials", + /*translation_context*/ BLT_I18NCONTEXT_ID_MATERIAL, + /*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE, + /*asset_type_info*/ nullptr, - /* init_data */ material_init_data, - /* copy_data */ material_copy_data, - /* free_data */ material_free_data, - /* make_local */ nullptr, - /* foreach_id */ material_foreach_id, - /* foreach_cache */ nullptr, - /* foreach_path */ nullptr, - /* owner_pointer_get */ nullptr, + /*init_data*/ material_init_data, + /*copy_data*/ material_copy_data, + /*free_data*/ material_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ material_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ nullptr, + /*owner_pointer_get*/ nullptr, - /* blend_write */ material_blend_write, - /* blend_read_data */ material_blend_read_data, - /* blend_read_lib */ material_blend_read_lib, - /* blend_read_expand */ material_blend_read_expand, + /*blend_write*/ material_blend_write, + /*blend_read_data*/ material_blend_read_data, + /*blend_read_lib*/ material_blend_read_lib, + /*blend_read_expand*/ material_blend_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; void BKE_gpencil_material_attr_init(Material *ma) diff --git a/source/blender/blenkernel/intern/mball.cc b/source/blender/blenkernel/intern/mball.cc index 6b1394f65ab..c1421db913d 100644 --- a/source/blender/blenkernel/intern/mball.cc +++ b/source/blender/blenkernel/intern/mball.cc @@ -161,33 +161,33 @@ static void metaball_blend_read_expand(BlendExpander *expander, ID *id) } IDTypeInfo IDType_ID_MB = { - /* id_code */ ID_MB, - /* id_filter */ FILTER_ID_MB, - /* main_listbase_index */ INDEX_ID_MB, - /* struct_size */ sizeof(MetaBall), - /* name */ "Metaball", - /* name_plural */ "metaballs", - /* translation_context */ BLT_I18NCONTEXT_ID_METABALL, - /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE, - /* asset_type_info */ nullptr, + /*id_code*/ ID_MB, + /*id_filter*/ FILTER_ID_MB, + /*main_listbase_index*/ INDEX_ID_MB, + /*struct_size*/ sizeof(MetaBall), + /*name*/ "Metaball", + /*name_plural*/ "metaballs", + /*translation_context*/ BLT_I18NCONTEXT_ID_METABALL, + /*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE, + /*asset_type_info*/ nullptr, - /* init_data */ metaball_init_data, - /* copy_data */ metaball_copy_data, - /* free_data */ metaball_free_data, - /* make_local */ nullptr, - /* foreach_id */ metaball_foreach_id, - /* foreach_cache */ nullptr, - /* foreach_path */ nullptr, - /* owner_pointer_get */ nullptr, + /*init_data*/ metaball_init_data, + /*copy_data*/ metaball_copy_data, + /*free_data*/ metaball_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ metaball_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ nullptr, + /*owner_pointer_get*/ nullptr, - /* blend_write */ metaball_blend_write, - /* blend_read_data */ metaball_blend_read_data, - /* blend_read_lib */ metaball_blend_read_lib, - /* blend_read_expand */ metaball_blend_read_expand, + /*blend_write*/ metaball_blend_write, + /*blend_read_data*/ metaball_blend_read_data, + /*blend_read_lib*/ metaball_blend_read_lib, + /*blend_read_expand*/ metaball_blend_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; /* Functions */ diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 23276b524b4..8ee01107c84 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -408,33 +408,33 @@ static void mesh_read_expand(BlendExpander *expander, ID *id) } IDTypeInfo IDType_ID_ME = { - /* id_code */ ID_ME, - /* id_filter */ FILTER_ID_ME, - /* main_listbase_index */ INDEX_ID_ME, - /* struct_size */ sizeof(Mesh), - /* name */ "Mesh", - /* name_plural */ "meshes", - /* translation_context */ BLT_I18NCONTEXT_ID_MESH, - /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE, - /* asset_type_info */ nullptr, + /*id_code*/ ID_ME, + /*id_filter*/ FILTER_ID_ME, + /*main_listbase_index*/ INDEX_ID_ME, + /*struct_size*/ sizeof(Mesh), + /*name*/ "Mesh", + /*name_plural*/ "meshes", + /*translation_context*/ BLT_I18NCONTEXT_ID_MESH, + /*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE, + /*asset_type_info*/ nullptr, - /* init_data */ mesh_init_data, - /* copy_data */ mesh_copy_data, - /* free_data */ mesh_free_data, - /* make_local */ nullptr, - /* foreach_id */ mesh_foreach_id, - /* foreach_cache */ nullptr, - /* foreach_path */ mesh_foreach_path, - /* owner_pointer_get */ nullptr, + /*init_data*/ mesh_init_data, + /*copy_data*/ mesh_copy_data, + /*free_data*/ mesh_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ mesh_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ mesh_foreach_path, + /*owner_pointer_get*/ nullptr, - /* blend_write */ mesh_blend_write, - /* blend_read_data */ mesh_blend_read_data, - /* blend_read_lib */ mesh_blend_read_lib, - /* blend_read_expand */ mesh_read_expand, + /*blend_write*/ mesh_blend_write, + /*blend_read_data*/ mesh_blend_read_data, + /*blend_read_lib*/ mesh_blend_read_lib, + /*blend_read_expand*/ mesh_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; enum { diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index e42a974eba2..9c2ac298fd2 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -1040,37 +1040,37 @@ static void node_tree_asset_pre_save(void *asset_ptr, AssetMetaData *asset_data) } // namespace blender::bke static AssetTypeInfo AssetType_NT = { - /* pre_save_fn */ blender::bke::node_tree_asset_pre_save, + /*pre_save_fn*/ blender::bke::node_tree_asset_pre_save, }; IDTypeInfo IDType_ID_NT = { - /* id_code */ ID_NT, - /* id_filter */ FILTER_ID_NT, - /* main_listbase_index */ INDEX_ID_NT, - /* struct_size */ sizeof(bNodeTree), - /* name */ "NodeTree", - /* name_plural */ "node_groups", - /* translation_context */ BLT_I18NCONTEXT_ID_NODETREE, - /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE, - /* asset_type_info */ &AssetType_NT, + /*id_code*/ ID_NT, + /*id_filter*/ FILTER_ID_NT, + /*main_listbase_index*/ INDEX_ID_NT, + /*struct_size*/ sizeof(bNodeTree), + /*name*/ "NodeTree", + /*name_plural*/ "node_groups", + /*translation_context*/ BLT_I18NCONTEXT_ID_NODETREE, + /*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE, + /*asset_type_info*/ &AssetType_NT, - /* init_data */ ntree_init_data, - /* copy_data */ ntree_copy_data, - /* free_data */ ntree_free_data, - /* make_local */ nullptr, - /* foreach_id */ node_foreach_id, - /* foreach_cache */ node_foreach_cache, - /* foreach_path */ node_foreach_path, - /* owner_pointer_get */ node_owner_pointer_get, + /*init_data*/ ntree_init_data, + /*copy_data*/ ntree_copy_data, + /*free_data*/ ntree_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ node_foreach_id, + /*foreach_cache*/ node_foreach_cache, + /*foreach_path*/ node_foreach_path, + /*owner_pointer_get*/ node_owner_pointer_get, - /* blend_write */ ntree_blend_write, - /* blend_read_data */ ntree_blend_read_data, - /* blend_read_lib */ ntree_blend_read_lib, - /* blend_read_expand */ ntree_blend_read_expand, + /*blend_write*/ ntree_blend_write, + /*blend_read_data*/ ntree_blend_read_data, + /*blend_read_lib*/ ntree_blend_read_lib, + /*blend_read_expand*/ ntree_blend_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype) diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index 16aeff19ee9..dfc2451d7fe 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -1221,37 +1221,37 @@ static void object_asset_pre_save(void *asset_ptr, struct AssetMetaData *asset_d } static AssetTypeInfo AssetType_OB = { - /* pre_save_fn */ object_asset_pre_save, + /*pre_save_fn*/ object_asset_pre_save, }; IDTypeInfo IDType_ID_OB = { - /* id_code */ ID_OB, - /* id_filter */ FILTER_ID_OB, - /* main_listbase_index */ INDEX_ID_OB, - /* struct_size */ sizeof(Object), - /* name */ "Object", - /* name_plural */ "objects", - /* translation_context */ BLT_I18NCONTEXT_ID_OBJECT, - /* flags */ 0, - /* asset_type_info */ &AssetType_OB, + /*id_code*/ ID_OB, + /*id_filter*/ FILTER_ID_OB, + /*main_listbase_index*/ INDEX_ID_OB, + /*struct_size*/ sizeof(Object), + /*name*/ "Object", + /*name_plural*/ "objects", + /*translation_context*/ BLT_I18NCONTEXT_ID_OBJECT, + /*flags*/ 0, + /*asset_type_info*/ &AssetType_OB, - /* init_data */ object_init_data, - /* copy_data */ object_copy_data, - /* free_data */ object_free_data, - /* make_local */ nullptr, - /* foreach_id */ object_foreach_id, - /* foreach_cache */ nullptr, - /* foreach_path */ object_foreach_path, - /* owner_pointer_get */ nullptr, + /*init_data*/ object_init_data, + /*copy_data*/ object_copy_data, + /*free_data*/ object_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ object_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ object_foreach_path, + /*owner_pointer_get*/ nullptr, - /* blend_write */ object_blend_write, - /* blend_read_data */ object_blend_read_data, - /* blend_read_lib */ object_blend_read_lib, - /* blend_read_expand */ object_blend_read_expand, + /*blend_write*/ object_blend_write, + /*blend_read_data*/ object_blend_read_data, + /*blend_read_lib*/ object_blend_read_lib, + /*blend_read_expand*/ object_blend_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ object_lib_override_apply_post, + /*lib_override_apply_post*/ object_lib_override_apply_post, }; void BKE_object_workob_clear(Object *workob) diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index e5d15918a2b..9fdef8525d4 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -529,9 +529,8 @@ static void make_duplis_collection(const DupliContext *ctx) } static const DupliGenerator gen_dupli_collection = { - OB_DUPLICOLLECTION, /* type */ - make_duplis_collection /* make_duplis */ -}; + /*type*/ OB_DUPLICOLLECTION, + /*make_duplis*/ make_duplis_collection}; /** \} */ @@ -744,9 +743,8 @@ static void make_duplis_verts(const DupliContext *ctx) } static const DupliGenerator gen_dupli_verts = { - OB_DUPLIVERTS, /* type */ - make_duplis_verts /* make_duplis */ -}; + /*type*/ OB_DUPLIVERTS, + /*make_duplis*/ make_duplis_verts}; /** \} */ @@ -873,9 +871,8 @@ static void make_duplis_font(const DupliContext *ctx) } static const DupliGenerator gen_dupli_verts_font = { - OB_DUPLIVERTS, /* type */ - make_duplis_font /* make_duplis */ -}; + /*type*/ OB_DUPLIVERTS, + /*make_duplis*/ make_duplis_font}; /** \} */ @@ -1034,8 +1031,8 @@ static void make_duplis_geometry_set(const DupliContext *ctx) } static const DupliGenerator gen_dupli_geometry_set = { - GEOMETRY_SET_DUPLI_GENERATOR_TYPE, - make_duplis_geometry_set, + /*type*/ GEOMETRY_SET_DUPLI_GENERATOR_TYPE, + /*make_duplis*/ make_duplis_geometry_set, }; /** \} */ @@ -1335,9 +1332,8 @@ static void make_duplis_faces(const DupliContext *ctx) } static const DupliGenerator gen_dupli_faces = { - OB_DUPLIFACES, /* type */ - make_duplis_faces /* make_duplis */ -}; + /*type*/ OB_DUPLIFACES, + /*make_duplis*/ make_duplis_faces}; /** \} */ @@ -1685,9 +1681,8 @@ static void make_duplis_particles(const DupliContext *ctx) } static const DupliGenerator gen_dupli_particles = { - OB_DUPLIPARTS, /* type */ - make_duplis_particles /* make_duplis */ -}; + /*type*/ OB_DUPLIPARTS, + /*make_duplis*/ make_duplis_particles}; /** \} */ diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 6628bc782f0..090a3ce0d7e 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -133,33 +133,33 @@ static void palette_undo_preserve(BlendLibReader * /*reader*/, ID *id_new, ID *i } IDTypeInfo IDType_ID_PAL = { - /* id_code */ ID_PAL, - /* id_filter */ FILTER_ID_PAL, - /* main_listbase_index */ INDEX_ID_PAL, - /* struct_size */ sizeof(Palette), - /* name */ "Palette", - /* name_plural */ "palettes", - /* translation_context */ BLT_I18NCONTEXT_ID_PALETTE, - /* flags */ IDTYPE_FLAGS_NO_ANIMDATA, - /* asset_type_info */ nullptr, + /*id_code*/ ID_PAL, + /*id_filter*/ FILTER_ID_PAL, + /*main_listbase_index*/ INDEX_ID_PAL, + /*struct_size*/ sizeof(Palette), + /*name*/ "Palette", + /*name_plural*/ "palettes", + /*translation_context*/ BLT_I18NCONTEXT_ID_PALETTE, + /*flags*/ IDTYPE_FLAGS_NO_ANIMDATA, + /*asset_type_info*/ nullptr, - /* init_data */ palette_init_data, - /* copy_data */ palette_copy_data, - /* free_data */ palette_free_data, - /* make_local */ nullptr, - /* foreach_id */ nullptr, - /* foreach_cache */ nullptr, - /* foreach_path */ nullptr, - /* owner_pointer_get */ nullptr, + /*init_data*/ palette_init_data, + /*copy_data*/ palette_copy_data, + /*free_data*/ palette_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ nullptr, + /*foreach_cache*/ nullptr, + /*foreach_path*/ nullptr, + /*owner_pointer_get*/ nullptr, - /* blend_write */ palette_blend_write, - /* blend_read_data */ palette_blend_read_data, - /* blend_read_lib */ nullptr, - /* blend_read_expand */ nullptr, + /*blend_write*/ palette_blend_write, + /*blend_read_data*/ palette_blend_read_data, + /*blend_read_lib*/ nullptr, + /*blend_read_expand*/ nullptr, - /* blend_read_undo_preserve */ palette_undo_preserve, + /*blend_read_undo_preserve*/ palette_undo_preserve, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; static void paint_curve_copy_data(Main * /*bmain*/, @@ -201,33 +201,33 @@ static void paint_curve_blend_read_data(BlendDataReader *reader, ID *id) } IDTypeInfo IDType_ID_PC = { - /* id_code */ ID_PC, - /* id_filter */ FILTER_ID_PC, - /* main_listbase_index */ INDEX_ID_PC, - /* struct_size */ sizeof(PaintCurve), - /* name */ "PaintCurve", - /* name_plural */ "paint_curves", - /* translation_context */ BLT_I18NCONTEXT_ID_PAINTCURVE, - /* flags */ IDTYPE_FLAGS_NO_ANIMDATA, - /* asset_type_info */ nullptr, + /*id_code*/ ID_PC, + /*id_filter*/ FILTER_ID_PC, + /*main_listbase_index*/ INDEX_ID_PC, + /*struct_size*/ sizeof(PaintCurve), + /*name*/ "PaintCurve", + /*name_plural*/ "paint_curves", + /*translation_context*/ BLT_I18NCONTEXT_ID_PAINTCURVE, + /*flags*/ IDTYPE_FLAGS_NO_ANIMDATA, + /*asset_type_info*/ nullptr, - /* init_data */ nullptr, - /* copy_data */ paint_curve_copy_data, - /* free_data */ paint_curve_free_data, - /* make_local */ nullptr, - /* foreach_id */ nullptr, - /* foreach_cache */ nullptr, - /* foreach_path */ nullptr, - /* owner_pointer_get */ nullptr, + /*init_data*/ nullptr, + /*copy_data*/ paint_curve_copy_data, + /*free_data*/ paint_curve_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ nullptr, + /*foreach_cache*/ nullptr, + /*foreach_path*/ nullptr, + /*owner_pointer_get*/ nullptr, - /* blend_write */ paint_curve_blend_write, - /* blend_read_data */ paint_curve_blend_read_data, - /* blend_read_lib */ nullptr, - /* blend_read_expand */ nullptr, + /*blend_write*/ paint_curve_blend_write, + /*blend_read_data*/ paint_curve_blend_read_data, + /*blend_read_lib*/ nullptr, + /*blend_read_expand*/ nullptr, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; const uchar PAINT_CURSOR_SCULPT[3] = {255, 100, 100}; diff --git a/source/blender/blenkernel/intern/pointcloud.cc b/source/blender/blenkernel/intern/pointcloud.cc index 8207bb2cd05..aa3c2593f34 100644 --- a/source/blender/blenkernel/intern/pointcloud.cc +++ b/source/blender/blenkernel/intern/pointcloud.cc @@ -166,33 +166,33 @@ static void pointcloud_blend_read_expand(BlendExpander *expander, ID *id) } IDTypeInfo IDType_ID_PT = { - /* id_code */ ID_PT, - /* id_filter */ FILTER_ID_PT, - /* main_listbase_index */ INDEX_ID_PT, - /* struct_size */ sizeof(PointCloud), - /* name */ "PointCloud", - /* name_plural */ "pointclouds", - /* translation_context */ BLT_I18NCONTEXT_ID_POINTCLOUD, - /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE, - /* asset_type_info */ nullptr, + /*id_code*/ ID_PT, + /*id_filter*/ FILTER_ID_PT, + /*main_listbase_index*/ INDEX_ID_PT, + /*struct_size*/ sizeof(PointCloud), + /*name*/ "PointCloud", + /*name_plural*/ "pointclouds", + /*translation_context*/ BLT_I18NCONTEXT_ID_POINTCLOUD, + /*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE, + /*asset_type_info*/ nullptr, - /* init_data */ pointcloud_init_data, - /* copy_data */ pointcloud_copy_data, - /* free_data */ pointcloud_free_data, - /* make_local */ nullptr, - /* foreach_id */ pointcloud_foreach_id, - /* foreach_cache */ nullptr, - /* foreach_path */ nullptr, - /* owner_pointer_get */ nullptr, + /*init_data*/ pointcloud_init_data, + /*copy_data*/ pointcloud_copy_data, + /*free_data*/ pointcloud_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ pointcloud_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ nullptr, + /*owner_pointer_get*/ nullptr, - /* blend_write */ pointcloud_blend_write, - /* blend_read_data */ pointcloud_blend_read_data, - /* blend_read_lib */ pointcloud_blend_read_lib, - /* blend_read_expand */ pointcloud_blend_read_expand, + /*blend_write*/ pointcloud_blend_write, + /*blend_read_data*/ pointcloud_blend_read_data, + /*blend_read_lib*/ pointcloud_blend_read_lib, + /*blend_read_expand*/ pointcloud_blend_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; static void pointcloud_random(PointCloud *pointcloud) diff --git a/source/blender/blenkernel/intern/simulation.cc b/source/blender/blenkernel/intern/simulation.cc index 14719c83ee9..c0e67b910f0 100644 --- a/source/blender/blenkernel/intern/simulation.cc +++ b/source/blender/blenkernel/intern/simulation.cc @@ -132,33 +132,33 @@ static void simulation_blend_read_expand(BlendExpander *expander, ID *id) } IDTypeInfo IDType_ID_SIM = { - /* id_code */ ID_SIM, - /* id_filter */ FILTER_ID_SIM, - /* main_listbase_index */ INDEX_ID_SIM, - /* struct_size */ sizeof(Simulation), - /* name */ "Simulation", - /* name_plural */ "simulations", - /* translation_context */ BLT_I18NCONTEXT_ID_SIMULATION, - /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE, - /* asset_type_info */ nullptr, + /*id_code*/ ID_SIM, + /*id_filter*/ FILTER_ID_SIM, + /*main_listbase_index*/ INDEX_ID_SIM, + /*struct_size*/ sizeof(Simulation), + /*name*/ "Simulation", + /*name_plural*/ "simulations", + /*translation_context*/ BLT_I18NCONTEXT_ID_SIMULATION, + /*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE, + /*asset_type_info*/ nullptr, - /* init_data */ simulation_init_data, - /* copy_data */ simulation_copy_data, - /* free_data */ simulation_free_data, - /* make_local */ nullptr, - /* foreach_id */ simulation_foreach_id, - /* foreach_cache */ nullptr, - /* foreach_path */ nullptr, - /* owner_pointer_get */ nullptr, + /*init_data*/ simulation_init_data, + /*copy_data*/ simulation_copy_data, + /*free_data*/ simulation_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ simulation_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ nullptr, + /*owner_pointer_get*/ nullptr, - /* blend_write */ simulation_blend_write, - /* blend_read_data */ simulation_blend_read_data, - /* blend_read_lib */ simulation_blend_read_lib, - /* blend_read_expand */ simulation_blend_read_expand, + /*blend_write*/ simulation_blend_write, + /*blend_read_data*/ simulation_blend_read_data, + /*blend_read_lib*/ simulation_blend_read_lib, + /*blend_read_expand*/ simulation_blend_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; void *BKE_simulation_add(Main *bmain, const char *name) diff --git a/source/blender/blenkernel/intern/texture.cc b/source/blender/blenkernel/intern/texture.cc index d2cecb372a0..ed385fae454 100644 --- a/source/blender/blenkernel/intern/texture.cc +++ b/source/blender/blenkernel/intern/texture.cc @@ -191,33 +191,33 @@ static void texture_blend_read_expand(BlendExpander *expander, ID *id) } IDTypeInfo IDType_ID_TE = { - /* id_code */ ID_TE, - /* id_filter */ FILTER_ID_TE, - /* main_listbase_index */ INDEX_ID_TE, - /* struct_size */ sizeof(Tex), - /* name */ "Texture", - /* name_plural */ "textures", - /* translation_context */ BLT_I18NCONTEXT_ID_TEXTURE, - /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE, - /* asset_type_info */ nullptr, + /*id_code*/ ID_TE, + /*id_filter*/ FILTER_ID_TE, + /*main_listbase_index*/ INDEX_ID_TE, + /*struct_size*/ sizeof(Tex), + /*name*/ "Texture", + /*name_plural*/ "textures", + /*translation_context*/ BLT_I18NCONTEXT_ID_TEXTURE, + /*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE, + /*asset_type_info*/ nullptr, - /* init_data */ texture_init_data, - /* copy_data */ texture_copy_data, - /* free_data */ texture_free_data, - /* make_local */ nullptr, - /* foreach_id */ texture_foreach_id, - /* foreach_cache */ nullptr, - /* foreach_path */ nullptr, - /* owner_pointer_get */ nullptr, + /*init_data*/ texture_init_data, + /*copy_data*/ texture_copy_data, + /*free_data*/ texture_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ texture_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ nullptr, + /*owner_pointer_get*/ nullptr, - /* blend_write */ texture_blend_write, - /* blend_read_data */ texture_blend_read_data, - /* blend_read_lib */ texture_blend_read_lib, - /* blend_read_expand */ texture_blend_read_expand, + /*blend_write*/ texture_blend_write, + /*blend_read_data*/ texture_blend_read_data, + /*blend_read_lib*/ texture_blend_read_lib, + /*blend_read_expand*/ texture_blend_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; void BKE_texture_mtex_foreach_id(LibraryForeachIDData *data, MTex *mtex) diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index 04501e3fe4a..050ba18db9a 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -564,8 +564,8 @@ static void volume_foreach_cache(ID *id, { Volume *volume = (Volume *)id; IDCacheKey key = { - /* id_session_uuid */ id->session_uuid, - /* offset_in_ID */ offsetof(Volume, runtime.grids), + /*id_session_uuid*/ id->session_uuid, + /*offset_in_ID*/ offsetof(Volume, runtime.grids), }; function_callback(id, &key, (void **)&volume->runtime.grids, 0, user_data); @@ -644,33 +644,33 @@ static void volume_blend_read_expand(BlendExpander *expander, ID *id) } IDTypeInfo IDType_ID_VO = { - /* id_code */ ID_VO, - /* id_filter */ FILTER_ID_VO, - /* main_listbase_index */ INDEX_ID_VO, - /* struct_size */ sizeof(Volume), - /* name */ "Volume", - /* name_plural */ "volumes", - /* translation_context */ BLT_I18NCONTEXT_ID_VOLUME, - /* flags */ IDTYPE_FLAGS_APPEND_IS_REUSABLE, - /* asset_type_info */ nullptr, + /*id_code*/ ID_VO, + /*id_filter*/ FILTER_ID_VO, + /*main_listbase_index*/ INDEX_ID_VO, + /*struct_size*/ sizeof(Volume), + /*name*/ "Volume", + /*name_plural*/ "volumes", + /*translation_context*/ BLT_I18NCONTEXT_ID_VOLUME, + /*flags*/ IDTYPE_FLAGS_APPEND_IS_REUSABLE, + /*asset_type_info*/ nullptr, - /* init_data */ volume_init_data, - /* copy_data */ volume_copy_data, - /* free_data */ volume_free_data, - /* make_local */ nullptr, - /* foreach_id */ volume_foreach_id, - /* foreach_cache */ volume_foreach_cache, - /* foreach_path */ volume_foreach_path, - /* owner_pointer_get */ nullptr, + /*init_data*/ volume_init_data, + /*copy_data*/ volume_copy_data, + /*free_data*/ volume_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ volume_foreach_id, + /*foreach_cache*/ volume_foreach_cache, + /*foreach_path*/ volume_foreach_path, + /*owner_pointer_get*/ nullptr, - /* blend_write */ volume_blend_write, - /* blend_read_data */ volume_blend_read_data, - /* blend_read_lib */ volume_blend_read_lib, - /* blend_read_expand */ volume_blend_read_expand, + /*blend_write*/ volume_blend_write, + /*blend_read_data*/ volume_blend_read_data, + /*blend_read_lib*/ volume_blend_read_lib, + /*blend_read_expand*/ volume_blend_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; void BKE_volume_init_grids(Volume *volume) diff --git a/source/blender/blenkernel/intern/workspace.cc b/source/blender/blenkernel/intern/workspace.cc index 6ffef5555fb..4b617a15e7e 100644 --- a/source/blender/blenkernel/intern/workspace.cc +++ b/source/blender/blenkernel/intern/workspace.cc @@ -186,33 +186,33 @@ static void workspace_blend_read_expand(BlendExpander *expander, ID *id) } IDTypeInfo IDType_ID_WS = { - /* id_code */ ID_WS, - /* id_filter */ FILTER_ID_WS, - /* main_listbase_index */ INDEX_ID_WS, - /* struct_size */ sizeof(WorkSpace), - /* name */ "WorkSpace", - /* name_plural */ "workspaces", - /* translation_context */ BLT_I18NCONTEXT_ID_WORKSPACE, - /* flags */ IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_ONLY_APPEND | IDTYPE_FLAGS_NO_ANIMDATA, - /* asset_type_info */ nullptr, + /*id_code*/ ID_WS, + /*id_filter*/ FILTER_ID_WS, + /*main_listbase_index*/ INDEX_ID_WS, + /*struct_size*/ sizeof(WorkSpace), + /*name*/ "WorkSpace", + /*name_plural*/ "workspaces", + /*translation_context*/ BLT_I18NCONTEXT_ID_WORKSPACE, + /*flags*/ IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_ONLY_APPEND | IDTYPE_FLAGS_NO_ANIMDATA, + /*asset_type_info*/ nullptr, - /* init_data */ workspace_init_data, - /* copy_data */ nullptr, - /* free_data */ workspace_free_data, - /* make_local */ nullptr, - /* foreach_id */ workspace_foreach_id, - /* foreach_cache */ nullptr, - /* foreach_path */ nullptr, - /* owner_pointer_get */ nullptr, + /*init_data*/ workspace_init_data, + /*copy_data*/ nullptr, + /*free_data*/ workspace_free_data, + /*make_local*/ nullptr, + /*foreach_id*/ workspace_foreach_id, + /*foreach_cache*/ nullptr, + /*foreach_path*/ nullptr, + /*owner_pointer_get*/ nullptr, - /* blend_write */ workspace_blend_write, - /* blend_read_data */ workspace_blend_read_data, - /* blend_read_lib */ workspace_blend_read_lib, - /* blend_read_expand */ workspace_blend_read_expand, + /*blend_write*/ workspace_blend_write, + /*blend_read_data*/ workspace_blend_read_data, + /*blend_read_lib*/ workspace_blend_read_lib, + /*blend_read_expand*/ workspace_blend_read_expand, - /* blend_read_undo_preserve */ nullptr, + /*blend_read_undo_preserve*/ nullptr, - /* lib_override_apply_post */ nullptr, + /*lib_override_apply_post*/ nullptr, }; /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c index 44857cd87e1..80dc12535a5 100644 --- a/source/blender/draw/engines/basic/basic_engine.c +++ b/source/blender/draw/engines/basic/basic_engine.c @@ -255,7 +255,7 @@ DrawEngineType draw_engine_basic_type = { &basic_data_size, NULL, &basic_engine_free, - NULL, /* instance_free */ + /*instance_free*/ NULL, &basic_cache_init, &basic_cache_populate, &basic_cache_finish, diff --git a/source/blender/draw/engines/compositor/compositor_engine.cc b/source/blender/draw/engines/compositor/compositor_engine.cc index 54a64a7dd00..6c2b0e2f3ff 100644 --- a/source/blender/draw/engines/compositor/compositor_engine.cc +++ b/source/blender/draw/engines/compositor/compositor_engine.cc @@ -249,20 +249,20 @@ extern "C" { static const DrawEngineDataSize compositor_data_size = DRW_VIEWPORT_DATA_SIZE(COMPOSITOR_Data); DrawEngineType draw_engine_compositor_type = { - nullptr, /* next */ - nullptr, /* prev */ - N_("Compositor"), /* idname */ - &compositor_data_size, /* vedata_size */ - &compositor_engine_init, /* engine_init */ - nullptr, /* engine_free */ - &compositor_engine_free, /* instance_free */ - nullptr, /* cache_init */ - nullptr, /* cache_populate */ - nullptr, /* cache_finish */ - &compositor_engine_draw, /* draw_scene */ - &compositor_engine_update, /* view_update */ - nullptr, /* id_update */ - nullptr, /* render_to_image */ - nullptr, /* store_metadata */ + /*next*/ nullptr, + /*prev*/ nullptr, + /*idname*/ N_("Compositor"), + /*vedata_size*/ &compositor_data_size, + /*engine_init*/ &compositor_engine_init, + /*engine_free*/ nullptr, + /*instance_free*/ &compositor_engine_free, + /*cache_init*/ nullptr, + /*cache_populate*/ nullptr, + /*cache_finish*/ nullptr, + /*draw_scene*/ &compositor_engine_draw, + /*view_update*/ &compositor_engine_update, + /*id_update*/ nullptr, + /*render_to_image*/ nullptr, + /*store_metadata*/ nullptr, }; } diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index ff17c02b3ee..0bdee957af2 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -622,7 +622,7 @@ DrawEngineType draw_engine_eevee_type = { &eevee_data_size, &eevee_engine_init, &eevee_engine_free, - NULL, /* instance_free */ + /*instance_free*/ NULL, &eevee_cache_init, &EEVEE_cache_populate, &eevee_cache_finish, diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c index 3f047d8de68..20b515414b8 100644 --- a/source/blender/draw/engines/external/external_engine.c +++ b/source/blender/draw/engines/external/external_engine.c @@ -440,7 +440,7 @@ DrawEngineType draw_engine_external_type = { &external_data_size, &external_engine_init, &external_engine_free, - NULL, /* instance_free */ + /*instance_free*/ NULL, &external_cache_init, &external_cache_populate, &external_cache_finish, diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index 6a4312e572a..16437300dba 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -978,7 +978,7 @@ DrawEngineType draw_engine_gpencil_type = { &GPENCIL_data_size, &GPENCIL_engine_init, &GPENCIL_engine_free, - NULL, /* instance_free */ + /*instance_free*/ NULL, &GPENCIL_cache_init, &GPENCIL_cache_populate, &GPENCIL_cache_finish, diff --git a/source/blender/draw/engines/image/image_engine.cc b/source/blender/draw/engines/image/image_engine.cc index e266135ec18..e055dc5836c 100644 --- a/source/blender/draw/engines/image/image_engine.cc +++ b/source/blender/draw/engines/image/image_engine.cc @@ -185,20 +185,20 @@ extern "C" { using namespace blender::draw::image_engine; DrawEngineType draw_engine_image_type = { - nullptr, /* next */ - nullptr, /* prev */ - N_("UV/Image"), /* idname */ - &IMAGE_data_size, /* vedata_size */ - &IMAGE_engine_init, /* engine_init */ - &IMAGE_engine_free, /* engine_free */ - &IMAGE_instance_free, /* instance_free */ - &IMAGE_cache_init, /* cache_init */ - &IMAGE_cache_populate, /* cache_populate */ - nullptr, /* cache_finish */ - &IMAGE_draw_scene, /* draw_scene */ - nullptr, /* view_update */ - nullptr, /* id_update */ - nullptr, /* render_to_image */ - nullptr, /* store_metadata */ + /*next*/ nullptr, + /*prev*/ nullptr, + /*idname*/ N_("UV/Image"), + /*vedata_size*/ &IMAGE_data_size, + /*engine_init*/ &IMAGE_engine_init, + /*engine_free*/ &IMAGE_engine_free, + /*instance_free*/ &IMAGE_instance_free, + /*cache_init*/ &IMAGE_cache_init, + /*cache_populate*/ &IMAGE_cache_populate, + /*cache_finish*/ nullptr, + /*draw_scene*/ &IMAGE_draw_scene, + /*view_update*/ nullptr, + /*id_update*/ nullptr, + /*render_to_image*/ nullptr, + /*store_metadata*/ nullptr, }; } diff --git a/source/blender/draw/engines/select/select_debug_engine.c b/source/blender/draw/engines/select/select_debug_engine.c index c46f6137149..e221e4771b5 100644 --- a/source/blender/draw/engines/select/select_debug_engine.c +++ b/source/blender/draw/engines/select/select_debug_engine.c @@ -105,7 +105,7 @@ DrawEngineType draw_engine_debug_select_type = { &select_debug_data_size, &select_debug_engine_init, &select_debug_engine_free, - NULL, /* instance_free */ + /*instance_free*/ NULL, NULL, NULL, NULL, diff --git a/source/blender/draw/engines/select/select_engine.c b/source/blender/draw/engines/select/select_engine.c index 2598cc01916..dc8dfbe79fb 100644 --- a/source/blender/draw/engines/select/select_engine.c +++ b/source/blender/draw/engines/select/select_engine.c @@ -330,7 +330,7 @@ DrawEngineType draw_engine_select_type = { &select_data_size, &select_engine_init, &select_engine_free, - NULL, /* instance_free */ + /*instance_free*/ NULL, &select_cache_init, &select_cache_populate, NULL, diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c index 830a9213f5a..9681e8f6cf5 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.c +++ b/source/blender/draw/engines/workbench/workbench_engine.c @@ -672,7 +672,7 @@ DrawEngineType draw_engine_workbench = { &workbench_data_size, &workbench_engine_init, &workbench_engine_free, - NULL, /* instance_free */ + /*instance_free*/ NULL, &workbench_cache_init, &workbench_cache_populate, &workbench_cache_finish, diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 9953da4847d..60d34b99b3d 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2015,7 +2015,7 @@ void DRW_render_to_image(RenderEngine *engine, struct Depsgraph *depsgraph) size[0], size[1], view_layer->name, - /* RR_ALL_VIEWS */ NULL); + /*RR_ALL_VIEWS*/ NULL); RenderLayer *render_layer = render_result->layers.first; for (RenderView *render_view = render_result->views.first; render_view != NULL; render_view = render_view->next) { diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 3a82143cfdf..7d95a3f949a 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -530,21 +530,21 @@ static void *acf_summary_setting_ptr(bAnimListElem *ale, /** All animation summary (dope-sheet only) type define. */ static bAnimChannelType ACF_SUMMARY = { - "Summary", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Summary", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_summary_color, /* backdrop color */ - acf_summary_backdrop, /* backdrop */ - acf_generic_indentation_0, /* indent level */ - NULL, /* offset */ + /*get_backdrop_color*/ acf_summary_color, + /*draw_backdrop*/ acf_summary_backdrop, + /*get_indent_level*/ acf_generic_indentation_0, + /*get_offset*/ NULL, - acf_summary_name, /* name */ - NULL, /* name prop */ - NULL, /* icon */ + /*name*/ acf_summary_name, + /*name_prop*/ NULL, + /*icon*/ NULL, - acf_summary_setting_valid, /* has setting */ - acf_summary_setting_flag, /* flag for setting */ - acf_summary_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_summary_setting_valid, + /*setting_flag*/ acf_summary_setting_flag, + /*setting_ptr*/ acf_summary_setting_ptr, }; /* Scene ------------------------------------------- */ @@ -639,21 +639,21 @@ static void *acf_scene_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings set /** Scene type define. */ static bAnimChannelType ACF_SCENE = { - "Scene", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Scene", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_root_color, /* backdrop color */ - acf_generic_root_backdrop, /* backdrop */ - acf_generic_indentation_0, /* indent level */ - NULL, /* offset */ + /*get_backdrop_color*/ acf_generic_root_color, + /*draw_backdrop*/ acf_generic_root_backdrop, + /*get_indent_level*/ acf_generic_indentation_0, + /*get_offset*/ NULL, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_scene_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_scene_icon, - acf_scene_setting_valid, /* has setting */ - acf_scene_setting_flag, /* flag for setting */ - acf_scene_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_scene_setting_valid, + /*setting_flag*/ acf_scene_setting_flag, + /*setting_ptr*/ acf_scene_setting_ptr, }; /* Object ------------------------------------------- */ @@ -815,21 +815,21 @@ static void *acf_object_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings se /** Object type define. */ static bAnimChannelType ACF_OBJECT = { - "Object", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Object", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_root_color, /* backdrop color */ - acf_generic_root_backdrop, /* backdrop */ - acf_generic_indentation_0, /* indent level */ - NULL, /* offset */ + /*get_backdrop_color*/ acf_generic_root_color, + /*draw_backdrop*/ acf_generic_root_backdrop, + /*get_indent_level*/ acf_generic_indentation_0, + /*get_offset*/ NULL, - acf_object_name, /* name */ - acf_object_name_prop, /* name prop */ - acf_object_icon, /* icon */ + /*name*/ acf_object_name, + /*name_prop*/ acf_object_name_prop, + /*icon*/ acf_object_icon, - acf_object_setting_valid, /* has setting */ - acf_object_setting_flag, /* flag for setting */ - acf_object_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_object_setting_valid, + /*setting_flag*/ acf_object_setting_flag, + /*setting_ptr*/ acf_object_setting_ptr, }; /* Group ------------------------------------------- */ @@ -992,21 +992,21 @@ static void *acf_group_setting_ptr(bAnimListElem *ale, /** Group type define. */ static bAnimChannelType ACF_GROUP = { - "Group", /* type name */ - ACHANNEL_ROLE_CHANNEL, /* role */ + /*channel_type_name*/ "Group", + /*channel_role*/ ACHANNEL_ROLE_CHANNEL, - acf_group_color, /* backdrop color */ - acf_group_backdrop, /* backdrop */ - acf_generic_indentation_0, /* indent level */ - acf_generic_group_offset, /* offset */ + /*get_backdrop_color*/ acf_group_color, + /*draw_backdrop*/ acf_group_backdrop, + /*get_indent_level*/ acf_generic_indentation_0, + /*get_offset*/ acf_generic_group_offset, - acf_group_name, /* name */ - acf_group_name_prop, /* name prop */ - NULL, /* icon */ + /*name*/ acf_group_name, + /*name_prop*/ acf_group_name_prop, + /*icon*/ NULL, - acf_group_setting_valid, /* has setting */ - acf_group_setting_flag, /* flag for setting */ - acf_group_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_group_setting_valid, + /*setting_flag*/ acf_group_setting_flag, + /*setting_ptr*/ acf_group_setting_ptr, }; /* F-Curve ------------------------------------------- */ @@ -1116,22 +1116,22 @@ static void *acf_fcurve_setting_ptr(bAnimListElem *ale, /** F-Curve type define. */ static bAnimChannelType ACF_FCURVE = { - "F-Curve", /* type name */ - ACHANNEL_ROLE_CHANNEL, /* role */ + /*channel_type_name*/ "F-Curve", + /*channel_role*/ ACHANNEL_ROLE_CHANNEL, - acf_generic_channel_color, /* backdrop color */ - acf_generic_channel_backdrop, /* backdrop */ - acf_generic_indentation_flexible, - /* indent level */ /* XXX rename this to f-curves only? */ - acf_generic_group_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_channel_color, + /*draw_backdrop*/ acf_generic_channel_backdrop, + /*get_indent_level*/ acf_generic_indentation_flexible, + /* XXX rename this to f-curves only? */ + /*get_offset*/ acf_generic_group_offset, - acf_fcurve_name, /* name */ - acf_fcurve_name_prop, /* name prop */ - NULL, /* icon */ + /*name*/ acf_fcurve_name, + /*name_prop*/ acf_fcurve_name_prop, + /*icon*/ NULL, - acf_fcurve_setting_valid, /* has setting */ - acf_fcurve_setting_flag, /* flag for setting */ - acf_fcurve_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_fcurve_setting_valid, + /*setting_flag*/ acf_fcurve_setting_flag, + /*setting_ptr*/ acf_fcurve_setting_ptr, }; /* NLA Control FCurves Expander ----------------------- */ @@ -1236,21 +1236,21 @@ static int acf_nla_controls_icon(bAnimListElem *UNUSED(ale)) /** NLA Control F-Curves expander type define. */ static bAnimChannelType ACF_NLACONTROLS = { - "NLA Controls Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "NLA Controls Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_nla_controls_color, /* backdrop color */ - acf_nla_controls_backdrop, /* backdrop */ - acf_generic_indentation_0, /* indent level */ - acf_generic_group_offset, /* offset */ + /*get_backdrop_color*/ acf_nla_controls_color, + /*draw_backdrop*/ acf_nla_controls_backdrop, + /*get_indent_level*/ acf_generic_indentation_0, + /*get_offset*/ acf_generic_group_offset, - acf_nla_controls_name, /* name */ - NULL, /* name prop */ - acf_nla_controls_icon, /* icon */ + /*name*/ acf_nla_controls_name, + /*name_prop*/ NULL, + /*icon*/ acf_nla_controls_icon, - acf_nla_controls_setting_valid, /* has setting */ - acf_nla_controls_setting_flag, /* flag for setting */ - acf_nla_controls_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_nla_controls_setting_valid, + /*setting_flag*/ acf_nla_controls_setting_flag, + /*setting_ptr*/ acf_nla_controls_setting_ptr, }; /* NLA Control F-Curve -------------------------------- */ @@ -1276,21 +1276,21 @@ static void acf_nla_curve_name(bAnimListElem *ale, char *name) /** NLA Control F-Curve type define. */ static bAnimChannelType ACF_NLACURVE = { - "NLA Control F-Curve", /* type name */ - ACHANNEL_ROLE_CHANNEL, /* role */ + /*channel_type_name*/ "NLA Control F-Curve", + /*channel_role*/ ACHANNEL_ROLE_CHANNEL, - acf_generic_channel_color, /* backdrop color */ - acf_generic_channel_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_group_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_channel_color, + /*draw_backdrop*/ acf_generic_channel_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_group_offset, - acf_nla_curve_name, /* name */ - acf_fcurve_name_prop, /* name prop */ - NULL, /* icon */ + /*name*/ acf_nla_curve_name, + /*name_prop*/ acf_fcurve_name_prop, + /*icon*/ NULL, - acf_fcurve_setting_valid, /* has setting */ - acf_fcurve_setting_flag, /* flag for setting */ - acf_fcurve_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_fcurve_setting_valid, + /*setting_flag*/ acf_fcurve_setting_flag, + /*setting_ptr*/ acf_fcurve_setting_ptr, }; /* Object Action Expander ------------------------------------------- */ @@ -1366,21 +1366,21 @@ static void *acf_fillactd_setting_ptr(bAnimListElem *ale, /** Object action expander type define. */ static bAnimChannelType ACF_FILLACTD = { - "Ob-Action Filler", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Ob-Action Filler", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idfill_name_prop, /* name prop */ - acf_fillactd_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idfill_name_prop, + /*icon*/ acf_fillactd_icon, - acf_fillactd_setting_valid, /* has setting */ - acf_fillactd_setting_flag, /* flag for setting */ - acf_fillactd_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_fillactd_setting_valid, + /*setting_flag*/ acf_fillactd_setting_flag, + /*setting_ptr*/ acf_fillactd_setting_ptr, }; /* Drivers Expander ------------------------------------------- */ @@ -1451,21 +1451,21 @@ static void *acf_filldrivers_setting_ptr(bAnimListElem *ale, /** Drivers expander type define. */ static bAnimChannelType ACF_FILLDRIVERS = { - "Drivers Filler", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Drivers Filler", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_filldrivers_name, /* name */ - NULL, /* name prop */ - acf_filldrivers_icon, /* icon */ + /*name*/ acf_filldrivers_name, + /*name_prop*/ NULL, + /*icon*/ acf_filldrivers_icon, - acf_filldrivers_setting_valid, /* has setting */ - acf_filldrivers_setting_flag, /* flag for setting */ - acf_filldrivers_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_filldrivers_setting_valid, + /*setting_flag*/ acf_filldrivers_setting_flag, + /*setting_ptr*/ acf_filldrivers_setting_ptr, }; /* Material Expander ------------------------------------------- */ @@ -1530,21 +1530,21 @@ static void *acf_dsmat_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings set /** Material expander type define. */ static bAnimChannelType ACF_DSMAT = { - "Material Data Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Material Data Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dsmat_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dsmat_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dsmat_setting_flag, /* flag for setting */ - acf_dsmat_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dsmat_setting_flag, + /*setting_ptr*/ acf_dsmat_setting_ptr, }; /* Light Expander ------------------------------------------- */ @@ -1611,21 +1611,21 @@ static void *acf_dslight_setting_ptr(bAnimListElem *ale, /** Light expander type define. */ static bAnimChannelType ACF_DSLIGHT = { - "Light Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Light Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dslight_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dslight_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dslight_setting_flag, /* flag for setting */ - acf_dslight_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dslight_setting_flag, + /*setting_ptr*/ acf_dslight_setting_ptr, }; /* Texture Expander ------------------------------------------- */ @@ -1697,21 +1697,21 @@ static void *acf_dstex_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings set /** Texture expander type define. */ static bAnimChannelType ACF_DSTEX = { - "Texture Data Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Texture Data Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_dstex_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_dstex_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idfill_name_prop, /* name prop */ - acf_dstex_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idfill_name_prop, + /*icon*/ acf_dstex_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dstex_setting_flag, /* flag for setting */ - acf_dstex_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dstex_setting_flag, + /*setting_ptr*/ acf_dstex_setting_ptr, }; /* Camera Expander ------------------------------------------- */ @@ -1780,21 +1780,21 @@ static void *acf_dscachefile_setting_ptr(bAnimListElem *ale, /** CacheFile expander type define.. */ static bAnimChannelType ACF_DSCACHEFILE = { - "Cache File Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Cache File Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idfill_name_prop, /* name prop */ - acf_dscachefile_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idfill_name_prop, + /*icon*/ acf_dscachefile_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dscachefile_setting_flag, /* flag for setting */ - acf_dscachefile_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dscachefile_setting_flag, + /*setting_ptr*/ acf_dscachefile_setting_ptr, }; /* Camera Expander ------------------------------------------- */ @@ -1863,21 +1863,21 @@ static void *acf_dscam_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings set /** Camera expander type define. */ static bAnimChannelType ACF_DSCAM = { - "Camera Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Camera Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idfill_name_prop, /* name prop */ - acf_dscam_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idfill_name_prop, + /*icon*/ acf_dscam_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dscam_setting_flag, /* flag for setting */ - acf_dscam_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dscam_setting_flag, + /*setting_ptr*/ acf_dscam_setting_ptr, }; /* Curve Expander ------------------------------------------- */ @@ -1952,21 +1952,21 @@ static void *acf_dscur_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings set /** Curve expander type define. */ static bAnimChannelType ACF_DSCUR = { - "Curve Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Curve Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dscur_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dscur_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dscur_setting_flag, /* flag for setting */ - acf_dscur_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dscur_setting_flag, + /*setting_ptr*/ acf_dscur_setting_ptr, }; /* Shape Key Expander ------------------------------------------- */ @@ -2050,21 +2050,21 @@ static void *acf_dsskey_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings se /** Shape-key expander type define. */ static bAnimChannelType ACF_DSSKEY = { - "Shape Key Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Shape Key Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dsskey_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dsskey_icon, - acf_dsskey_setting_valid, /* has setting */ - acf_dsskey_setting_flag, /* flag for setting */ - acf_dsskey_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_dsskey_setting_valid, + /*setting_flag*/ acf_dsskey_setting_flag, + /*setting_ptr*/ acf_dsskey_setting_ptr, }; /* World Expander ------------------------------------------- */ @@ -2129,21 +2129,21 @@ static void *acf_dswor_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings set /** World expander type define. */ static bAnimChannelType ACF_DSWOR = { - "World Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "World Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idfill_name_prop, /* name prop */ - acf_dswor_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idfill_name_prop, + /*icon*/ acf_dswor_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dswor_setting_flag, /* flag for setting */ - acf_dswor_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dswor_setting_flag, + /*setting_ptr*/ acf_dswor_setting_ptr, }; /* Particle Expander ------------------------------------------- */ @@ -2208,21 +2208,21 @@ static void *acf_dspart_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings se /** Particle expander type define. */ static bAnimChannelType ACF_DSPART = { - "Particle Data Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Particle Data Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dspart_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dspart_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dspart_setting_flag, /* flag for setting */ - acf_dspart_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dspart_setting_flag, + /*setting_ptr*/ acf_dspart_setting_ptr, }; /* MetaBall Expander ------------------------------------------- */ @@ -2289,21 +2289,21 @@ static void *acf_dsmball_setting_ptr(bAnimListElem *ale, /** Meta-ball expander type define. */ static bAnimChannelType ACF_DSMBALL = { - "Metaball Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Metaball Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dsmball_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dsmball_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dsmball_setting_flag, /* flag for setting */ - acf_dsmball_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dsmball_setting_flag, + /*setting_ptr*/ acf_dsmball_setting_ptr, }; /* Armature Expander ------------------------------------------- */ @@ -2368,21 +2368,21 @@ static void *acf_dsarm_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings set /** Armature expander type define. */ static bAnimChannelType ACF_DSARM = { - "Armature Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Armature Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dsarm_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dsarm_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dsarm_setting_flag, /* flag for setting */ - acf_dsarm_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dsarm_setting_flag, + /*setting_ptr*/ acf_dsarm_setting_ptr, }; /* NodeTree Expander ------------------------------------------- */ @@ -2460,21 +2460,21 @@ static void *acf_dsntree_setting_ptr(bAnimListElem *ale, /** Node tree expander type define. */ static bAnimChannelType ACF_DSNTREE = { - "Node Tree Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Node Tree Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_dsntree_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_dsntree_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dsntree_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dsntree_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dsntree_setting_flag, /* flag for setting */ - acf_dsntree_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dsntree_setting_flag, + /*setting_ptr*/ acf_dsntree_setting_ptr, }; /* LineStyle Expander ------------------------------------------- */ @@ -2541,21 +2541,21 @@ static void *acf_dslinestyle_setting_ptr(bAnimListElem *ale, /** Line Style expander type define. */ static bAnimChannelType ACF_DSLINESTYLE = { - "Line Style Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Line Style Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dslinestyle_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dslinestyle_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dslinestyle_setting_flag, /* flag for setting */ - acf_dslinestyle_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dslinestyle_setting_flag, + /*setting_ptr*/ acf_dslinestyle_setting_ptr, }; /* Mesh Expander ------------------------------------------- */ @@ -2620,22 +2620,22 @@ static void *acf_dsmesh_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings se /** Mesh expander type define. */ static bAnimChannelType ACF_DSMESH = { - "Mesh Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Mesh Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, - /* indent level */ /* XXX this only works for compositing */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /* XXX: this only works for compositing. */ + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dsmesh_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dsmesh_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dsmesh_setting_flag, /* flag for setting */ - acf_dsmesh_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dsmesh_setting_flag, + /*setting_ptr*/ acf_dsmesh_setting_ptr, }; /* Lattice Expander ------------------------------------------- */ @@ -2700,22 +2700,22 @@ static void *acf_dslat_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings set /** Lattice expander type define. */ static bAnimChannelType ACF_DSLAT = { - "Lattice Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Lattice Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, - /* indent level */ /* XXX this only works for compositing */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /* XXX: this only works for compositing. */ + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dslat_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dslat_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dslat_setting_flag, /* flag for setting */ - acf_dslat_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dslat_setting_flag, + /*setting_ptr*/ acf_dslat_setting_ptr, }; /* Speaker Expander ------------------------------------------- */ @@ -2780,21 +2780,21 @@ static void *acf_dsspk_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings set /** Speaker expander type define. */ static bAnimChannelType ACF_DSSPK = { - "Speaker Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Speaker Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dsspk_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dsspk_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dsspk_setting_flag, /* flag for setting */ - acf_dsspk_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dsspk_setting_flag, + /*setting_ptr*/ acf_dsspk_setting_ptr, }; /* Curves Expander ------------------------------------------- */ @@ -2861,22 +2861,21 @@ static void *acf_dscurves_setting_ptr(bAnimListElem *ale, /** Curves expander type define. */ static bAnimChannelType ACF_DSCURVES = { - "Curves Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Curves Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dscurves_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dscurves_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dscurves_setting_flag, /* flag for setting */ - acf_dscurves_setting_ptr /* pointer for setting */ -}; + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dscurves_setting_flag, + /*setting_ptr*/ acf_dscurves_setting_ptr}; /* PointCloud Expander ------------------------------------------- */ @@ -2942,22 +2941,21 @@ static void *acf_dspointcloud_setting_ptr(bAnimListElem *ale, /** Point-cloud expander type define. */ static bAnimChannelType ACF_DSPOINTCLOUD = { - "PointCloud Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "PointCloud Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dspointcloud_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dspointcloud_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dspointcloud_setting_flag, /* flag for setting */ - acf_dspointcloud_setting_ptr /* pointer for setting */ -}; + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dspointcloud_setting_flag, + /*setting_ptr*/ acf_dspointcloud_setting_ptr}; /* Volume Expander ------------------------------------------- */ @@ -3023,22 +3021,21 @@ static void *acf_dsvolume_setting_ptr(bAnimListElem *ale, /** Volume expander type define. */ static bAnimChannelType ACF_DSVOLUME = { - "Volume Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Volume Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dsvolume_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dsvolume_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dsvolume_setting_flag, /* flag for setting */ - acf_dsvolume_setting_ptr /* pointer for setting */ -}; + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dsvolume_setting_flag, + /*setting_ptr*/ acf_dsvolume_setting_ptr}; /* Simulation Expander ----------------------------------------- */ @@ -3102,22 +3099,21 @@ static void *acf_dssimulation_setting_ptr(bAnimListElem *ale, /** Simulation expander type define. */ static bAnimChannelType ACF_DSSIMULATION = { - "Simulation Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Simulation Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dssimulation_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dssimulation_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dssimulation_setting_flag, /* flag for setting */ - acf_dssimulation_setting_ptr /* pointer for setting */ -}; + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dssimulation_setting_flag, + /*setting_ptr*/ acf_dssimulation_setting_ptr}; /* GPencil Expander ------------------------------------------- */ @@ -3183,21 +3179,21 @@ static void *acf_dsgpencil_setting_ptr(bAnimListElem *ale, /** Grease-pencil expander type define. */ static bAnimChannelType ACF_DSGPENCIL = { - "GPencil DS Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "GPencil DS Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idblock_name_prop, /* name prop */ - acf_dsgpencil_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idblock_name_prop, + /*icon*/ acf_dsgpencil_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dsgpencil_setting_flag, /* flag for setting */ - acf_dsgpencil_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dsgpencil_setting_flag, + /*setting_ptr*/ acf_dsgpencil_setting_ptr, }; /* World Expander ------------------------------------------- */ @@ -3264,21 +3260,21 @@ static void *acf_dsmclip_setting_ptr(bAnimListElem *ale, /** Movie-clip expander type define. */ static bAnimChannelType ACF_DSMCLIP = { - "Movieclip Expander", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Movieclip Expander", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_generic_dataexpand_color, /* backdrop color */ - acf_generic_dataexpand_backdrop, /* backdrop */ - acf_generic_indentation_1, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_dataexpand_color, + /*draw_backdrop*/ acf_generic_dataexpand_backdrop, + /*get_indent_level*/ acf_generic_indentation_1, + /*get_offset*/ acf_generic_basic_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idfill_name_prop, /* name prop */ - acf_dsmclip_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idfill_name_prop, + /*icon*/ acf_dsmclip_icon, - acf_generic_dataexpand_setting_valid, /* has setting */ - acf_dsmclip_setting_flag, /* flag for setting */ - acf_dsmclip_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_generic_dataexpand_setting_valid, + /*setting_flag*/ acf_dsmclip_setting_flag, + /*setting_ptr*/ acf_dsmclip_setting_ptr, }; /* ShapeKey Entry ------------------------------------------- */ @@ -3379,21 +3375,21 @@ static void *acf_shapekey_setting_ptr(bAnimListElem *ale, /** Shape-key expander type define. */ static bAnimChannelType ACF_SHAPEKEY = { - "Shape Key", /* type name */ - ACHANNEL_ROLE_CHANNEL, /* role */ + /*channel_type_name*/ "Shape Key", + /*channel_role*/ ACHANNEL_ROLE_CHANNEL, - acf_generic_channel_color, /* backdrop color */ - acf_generic_channel_backdrop, /* backdrop */ - acf_generic_indentation_0, /* indent level */ - acf_generic_basic_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_channel_color, + /*draw_backdrop*/ acf_generic_channel_backdrop, + /*get_indent_level*/ acf_generic_indentation_0, + /*get_offset*/ acf_generic_basic_offset, - acf_shapekey_name, /* name */ - acf_shapekey_name_prop, /* name prop */ - NULL, /* icon */ + /*name*/ acf_shapekey_name, + /*name_prop*/ acf_shapekey_name_prop, + /*icon*/ NULL, - acf_shapekey_setting_valid, /* has setting */ - acf_shapekey_setting_flag, /* flag for setting */ - acf_shapekey_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_shapekey_setting_valid, + /*setting_flag*/ acf_shapekey_setting_flag, + /*setting_ptr*/ acf_shapekey_setting_ptr, }; /* GPencil Datablock ------------------------------------------- */ @@ -3459,21 +3455,21 @@ static void *acf_gpd_setting_ptr(bAnimListElem *ale, /** Grease-pencil data-block type define. */ static bAnimChannelType ACF_GPD = { - "GPencil Datablock", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "GPencil Datablock", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_gpd_color, /* backdrop color */ - acf_group_backdrop, /* backdrop */ - acf_generic_indentation_0, /* indent level */ - acf_generic_group_offset, /* offset */ + /*get_backdrop_color*/ acf_gpd_color, + /*draw_backdrop*/ acf_group_backdrop, + /*get_indent_level*/ acf_generic_indentation_0, + /*get_offset*/ acf_generic_group_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idfill_name_prop, /* name prop */ - acf_gpd_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idfill_name_prop, + /*icon*/ acf_gpd_icon, - acf_gpd_setting_valid, /* has setting */ - acf_gpd_setting_flag, /* flag for setting */ - acf_gpd_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_gpd_setting_valid, + /*setting_flag*/ acf_gpd_setting_flag, + /*setting_ptr*/ acf_gpd_setting_ptr, }; /* GPencil Layer ------------------------------------------- */ @@ -3558,21 +3554,21 @@ static void *acf_gpl_setting_ptr(bAnimListElem *ale, /** Grease-pencil layer type define. */ static bAnimChannelType ACF_GPL = { - "GPencil Layer", /* type name */ - ACHANNEL_ROLE_CHANNEL, /* role */ + /*channel_type_name*/ "GPencil Layer", + /*channel_role*/ ACHANNEL_ROLE_CHANNEL, - acf_gpencil_channel_color, /* backdrop color */ - acf_generic_channel_backdrop, /* backdrop */ - acf_generic_indentation_flexible, /* indent level */ - acf_generic_group_offset, /* offset */ + /*get_backdrop_color*/ acf_gpencil_channel_color, + /*draw_backdrop*/ acf_generic_channel_backdrop, + /*get_indent_level*/ acf_generic_indentation_flexible, + /*get_offset*/ acf_generic_group_offset, - acf_gpl_name, /* name */ - acf_gpl_name_prop, /* name prop */ - NULL, /* icon */ + /*name*/ acf_gpl_name, + /*name_prop*/ acf_gpl_name_prop, + /*icon*/ NULL, - acf_gpl_setting_valid, /* has setting */ - acf_gpl_setting_flag, /* flag for setting */ - acf_gpl_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_gpl_setting_valid, + /*setting_flag*/ acf_gpl_setting_flag, + /*setting_ptr*/ acf_gpl_setting_ptr, }; /* Mask Datablock ------------------------------------------- */ @@ -3640,21 +3636,21 @@ static void *acf_mask_setting_ptr(bAnimListElem *ale, /** Mask data-block type define. */ static bAnimChannelType ACF_MASKDATA = { - "Mask Datablock", /* type name */ - ACHANNEL_ROLE_EXPANDER, /* role */ + /*channel_type_name*/ "Mask Datablock", + /*channel_role*/ ACHANNEL_ROLE_EXPANDER, - acf_mask_color, /* backdrop color */ - acf_group_backdrop, /* backdrop */ - acf_generic_indentation_0, /* indent level */ - acf_generic_group_offset, /* offset */ + /*get_backdrop_color*/ acf_mask_color, + /*draw_backdrop*/ acf_group_backdrop, + /*get_indent_level*/ acf_generic_indentation_0, + /*get_offset*/ acf_generic_group_offset, - acf_generic_idblock_name, /* name */ - acf_generic_idfill_name_prop, /* name prop */ - acf_mask_icon, /* icon */ + /*name*/ acf_generic_idblock_name, + /*name_prop*/ acf_generic_idfill_name_prop, + /*icon*/ acf_mask_icon, - acf_mask_setting_valid, /* has setting */ - acf_mask_setting_flag, /* flag for setting */ - acf_mask_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_mask_setting_valid, + /*setting_flag*/ acf_mask_setting_flag, + /*setting_ptr*/ acf_mask_setting_ptr, }; /* Mask Layer ------------------------------------------- */ @@ -3736,21 +3732,21 @@ static void *acf_masklay_setting_ptr(bAnimListElem *ale, /** Mask layer type define. */ static bAnimChannelType ACF_MASKLAYER = { - "Mask Layer", /* type name */ - ACHANNEL_ROLE_CHANNEL, /* role */ + /*channel_type_name*/ "Mask Layer", + /*channel_role*/ ACHANNEL_ROLE_CHANNEL, - acf_generic_channel_color, /* backdrop color */ - acf_generic_channel_backdrop, /* backdrop */ - acf_generic_indentation_flexible, /* indent level */ - acf_generic_group_offset, /* offset */ + /*get_backdrop_color*/ acf_generic_channel_color, + /*draw_backdrop*/ acf_generic_channel_backdrop, + /*get_indent_level*/ acf_generic_indentation_flexible, + /*get_offset*/ acf_generic_group_offset, - acf_masklay_name, /* name */ - acf_masklay_name_prop, /* name prop */ - NULL, /* icon */ + /*name*/ acf_masklay_name, + /*name_prop*/ acf_masklay_name_prop, + /*icon*/ NULL, - acf_masklay_setting_valid, /* has setting */ - acf_masklay_setting_flag, /* flag for setting */ - acf_masklay_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_masklay_setting_valid, + /*setting_flag*/ acf_masklay_setting_flag, + /*setting_ptr*/ acf_masklay_setting_ptr, }; /* NLA Track ----------------------------------------------- */ @@ -3876,22 +3872,21 @@ static void *acf_nlatrack_setting_ptr(bAnimListElem *ale, /** NLA track type define. */ static bAnimChannelType ACF_NLATRACK = { - "NLA Track", /* type name */ - ACHANNEL_ROLE_CHANNEL, /* role */ + /*channel_type_name*/ "NLA Track", + /*channel_role*/ ACHANNEL_ROLE_CHANNEL, - acf_nlatrack_color, /* backdrop color */ - acf_generic_channel_backdrop, /* backdrop */ - acf_generic_indentation_flexible, /* indent level */ - acf_generic_group_offset, - /* offset */ /* XXX? */ + /*get_backdrop_color*/ acf_nlatrack_color, + /*draw_backdrop*/ acf_generic_channel_backdrop, + /*get_indent_level*/ acf_generic_indentation_flexible, + /*get_offset*/ acf_generic_group_offset, /* XXX? */ - acf_nlatrack_name, /* name */ - acf_nlatrack_name_prop, /* name prop */ - NULL, /* icon */ + /*name*/ acf_nlatrack_name, + /*name_prop*/ acf_nlatrack_name_prop, + /*icon*/ NULL, - acf_nlatrack_setting_valid, /* has setting */ - acf_nlatrack_setting_flag, /* flag for setting */ - acf_nlatrack_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_nlatrack_setting_valid, + /*setting_flag*/ acf_nlatrack_setting_flag, + /*setting_ptr*/ acf_nlatrack_setting_ptr, }; /* NLA Action ----------------------------------------------- */ @@ -4062,23 +4057,22 @@ static void *acf_nlaaction_setting_ptr(bAnimListElem *ale, /* nla action type define */ static bAnimChannelType ACF_NLAACTION = { - "NLA Active Action", /* type name */ - ACHANNEL_ROLE_CHANNEL, /* role */ + /*channel_type_name*/ "NLA Active Action", + /*channel_role*/ ACHANNEL_ROLE_CHANNEL, + /* NOTE: the backdrop handles this too, since it needs special hacks. */ + /*get_backdrop_color*/ acf_nlaaction_color, - acf_nlaaction_color, /* backdrop color (NOTE: the backdrop handles this too, - * since it needs special hacks). */ - acf_nlaaction_backdrop, /* backdrop */ - acf_generic_indentation_flexible, /* indent level */ - acf_generic_group_offset, - /* offset */ /* XXX? */ + /*draw_backdrop*/ acf_nlaaction_backdrop, + /*get_indent_level*/ acf_generic_indentation_flexible, + /*get_offset*/ acf_generic_group_offset, /* XXX? */ - acf_nlaaction_name, /* name */ - acf_nlaaction_name_prop, /* name prop */ - acf_nlaaction_icon, /* icon */ + /*name*/ acf_nlaaction_name, + /*name_prop*/ acf_nlaaction_name_prop, + /*icon*/ acf_nlaaction_icon, - acf_nlaaction_setting_valid, /* has setting */ - acf_nlaaction_setting_flag, /* flag for setting */ - acf_nlaaction_setting_ptr, /* pointer for setting */ + /*has_setting*/ acf_nlaaction_setting_valid, + /*setting_flag*/ acf_nlaaction_setting_flag, + /*setting_ptr*/ acf_nlaaction_setting_ptr, }; /* *********************************************** */ diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index dc1fab35945..aa8b5796645 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -240,7 +240,7 @@ static void select_pchan_for_action_group(bAnimContext *ac, bActionGroup *agrp, } } -static ListBase /* bAnimListElem */ anim_channels_for_selection(bAnimContext *ac) +static ListBase /*bAnimListElem*/ anim_channels_for_selection(bAnimContext *ac) { ListBase anim_data = {NULL, NULL}; diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 6df9dc1e86d..d0b978b7adf 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -480,7 +480,7 @@ static void ED_keylist_draw_list_elem_prepare_for_drawing(AnimKeylistDrawListEle } typedef struct AnimKeylistDrawList { - ListBase /* AnimKeylistDrawListElem */ channels; + ListBase /*AnimKeylistDrawListElem*/ channels; } AnimKeylistDrawList; AnimKeylistDrawList *ED_keylist_draw_list_create(void) diff --git a/source/blender/editors/animation/keyframes_keylist.cc b/source/blender/editors/animation/keyframes_keylist.cc index 9b3cabb6c79..eff12af02d2 100644 --- a/source/blender/editors/animation/keyframes_keylist.cc +++ b/source/blender/editors/animation/keyframes_keylist.cc @@ -61,7 +61,7 @@ struct AnimKeylist { /* Before initializing the runtime, the key_columns list base is used to quickly add columns. * Contains `ActKeyColumn`. Should not be used after runtime is initialized. */ - ListBase /* ActKeyColumn */ key_columns; + ListBase /*ActKeyColumn*/ key_columns; /* Last accessed column in the key_columns list base. Inserting columns are typically done in * order. The last accessed column is used as starting point to search for a location to add or * update the next column. */ @@ -71,9 +71,9 @@ struct AnimKeylist { /* When initializing the runtime the columns from the list base `AnimKeyList.key_columns` are * transferred to an array to support binary searching and index based access. */ blender::Array key_columns; - /* Wrapper around runtime.key_columns so it can still be accessed as a ListBase. Elements are - * owned by runtime.key_columns. */ - ListBase /* ActKeyColumn */ list_wrapper; + /* Wrapper around runtime.key_columns so it can still be accessed as a ListBase. + * Elements are owned by `runtime.key_columns`. */ + ListBase /*ActKeyColumn*/ list_wrapper; } runtime; AnimKeylist() diff --git a/source/blender/editors/asset/intern/asset_ops.cc b/source/blender/editors/asset/intern/asset_ops.cc index cc38bc15364..1303be1a510 100644 --- a/source/blender/editors/asset/intern/asset_ops.cc +++ b/source/blender/editors/asset/intern/asset_ops.cc @@ -908,11 +908,11 @@ static bool has_external_files(Main *bmain, struct ReportList *reports) | BKE_BPATH_TRAVERSE_SKIP_WEAK_REFERENCES); /* Only care about actually used files. */ BPathForeachPathData bpath_data = { - /* bmain */ bmain, - /* callback_function */ &external_file_check_callback, - /* flag */ flag, - /* user_data */ &callback_info, - /* absolute_base_path */ nullptr, + /*bmain*/ bmain, + /*callback_function*/ &external_file_check_callback, + /*flag*/ flag, + /*user_data*/ &callback_info, + /*absolute_base_path*/ nullptr, }; BKE_bpath_foreach_path_main(&bpath_data); diff --git a/source/blender/editors/include/ED_file_indexer.h b/source/blender/editors/include/ED_file_indexer.h index c07196c9fd7..eeb0fb3124f 100644 --- a/source/blender/editors/include/ED_file_indexer.h +++ b/source/blender/editors/include/ED_file_indexer.h @@ -131,7 +131,7 @@ void ED_file_indexer_entries_clear(FileIndexerEntries *indexer_entries); */ void ED_file_indexer_entries_extend_from_datablock_infos( FileIndexerEntries *indexer_entries, - const LinkNode * /* BLODataBlockInfo */ datablock_infos, + const LinkNode * /*BLODataBlockInfo*/ datablock_infos, int idcode); #ifdef __cplusplus diff --git a/source/blender/editors/space_file/file_indexer.cc b/source/blender/editors/space_file/file_indexer.cc index 7670f475599..4ee925c256d 100644 --- a/source/blender/editors/space_file/file_indexer.cc +++ b/source/blender/editors/space_file/file_indexer.cc @@ -55,7 +55,7 @@ extern "C" { void ED_file_indexer_entries_extend_from_datablock_infos( FileIndexerEntries *indexer_entries, - const LinkNode * /* BLODataBlockInfo */ datablock_infos, + const LinkNode * /*BLODataBlockInfo*/ datablock_infos, const int idcode) { for (const LinkNode *ln = datablock_infos; ln; ln = ln->next) { diff --git a/source/blender/editors/transform/transform_convert_action.c b/source/blender/editors/transform/transform_convert_action.c index 560cc18d7d6..bd8f8237bd9 100644 --- a/source/blender/editors/transform/transform_convert_action.c +++ b/source/blender/editors/transform/transform_convert_action.c @@ -936,8 +936,8 @@ static void special_aftertrans_update__actedit(bContext *C, TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_Action = { - /* flags */ (T_POINTS | T_2D_EDIT), - /* createTransData */ createTransActionData, - /* recalcData */ recalcData_actedit, - /* special_aftertrans_update */ special_aftertrans_update__actedit, + /*flags*/ (T_POINTS | T_2D_EDIT), + /*createTransData*/ createTransActionData, + /*recalcData*/ recalcData_actedit, + /*special_aftertrans_update*/ special_aftertrans_update__actedit, }; diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index ada6d1c40b2..b9b78da1993 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -1771,15 +1771,15 @@ static void special_aftertrans_update__pose(bContext *C, TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_EditArmature = { - /* flags */ (T_EDIT | T_POINTS), - /* createTransData */ createTransArmatureVerts, - /* recalcData */ recalcData_edit_armature, - /* special_aftertrans_update */ NULL, + /*flags*/ (T_EDIT | T_POINTS), + /*createTransData*/ createTransArmatureVerts, + /*recalcData*/ recalcData_edit_armature, + /*special_aftertrans_update*/ NULL, }; TransConvertTypeInfo TransConvertType_Pose = { - /* flags */ 0, - /* createTransData */ createTransPose, - /* recalcData */ recalcData_pose, - /* special_aftertrans_update */ special_aftertrans_update__pose, + /*flags*/ 0, + /*createTransData*/ createTransPose, + /*recalcData*/ recalcData_pose, + /*special_aftertrans_update*/ special_aftertrans_update__pose, }; diff --git a/source/blender/editors/transform/transform_convert_cursor.c b/source/blender/editors/transform/transform_convert_cursor.c index 0bf6f06a9f2..2b365d31068 100644 --- a/source/blender/editors/transform/transform_convert_cursor.c +++ b/source/blender/editors/transform/transform_convert_cursor.c @@ -186,22 +186,22 @@ static void recalcData_cursor_view3d(TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_CursorImage = { - /* flags */ T_2D_EDIT, - /* createTransData */ createTransCursor_image, - /* recalcData */ recalcData_cursor_image, - /* special_aftertrans_update */ NULL, + /*flags*/ T_2D_EDIT, + /*createTransData*/ createTransCursor_image, + /*recalcData*/ recalcData_cursor_image, + /*special_aftertrans_update*/ NULL, }; TransConvertTypeInfo TransConvertType_CursorSequencer = { - /* flags */ T_2D_EDIT, - /* createTransData */ createTransCursor_sequencer, - /* recalcData */ recalcData_cursor_sequencer, - /* special_aftertrans_update */ NULL, + /*flags*/ T_2D_EDIT, + /*createTransData*/ createTransCursor_sequencer, + /*recalcData*/ recalcData_cursor_sequencer, + /*special_aftertrans_update*/ NULL, }; TransConvertTypeInfo TransConvertType_Cursor3D = { - /* flags */ 0, - /* createTransData */ createTransCursor_view3d, - /* recalcData */ recalcData_cursor_view3d, - /* special_aftertrans_update */ NULL, + /*flags*/ 0, + /*createTransData*/ createTransCursor_view3d, + /*recalcData*/ recalcData_cursor_view3d, + /*special_aftertrans_update*/ NULL, }; diff --git a/source/blender/editors/transform/transform_convert_curve.c b/source/blender/editors/transform/transform_convert_curve.c index 58ed8ad7d33..b3ee49ef7ed 100644 --- a/source/blender/editors/transform/transform_convert_curve.c +++ b/source/blender/editors/transform/transform_convert_curve.c @@ -449,8 +449,8 @@ static void recalcData_curve(TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_Curve = { - /* flags */ (T_EDIT | T_POINTS), - /* createTransData */ createTransCurveVerts, - /* recalcData */ recalcData_curve, - /* special_aftertrans_update */ NULL, + /*flags*/ (T_EDIT | T_POINTS), + /*createTransData*/ createTransCurveVerts, + /*recalcData*/ recalcData_curve, + /*special_aftertrans_update*/ NULL, }; diff --git a/source/blender/editors/transform/transform_convert_gpencil.c b/source/blender/editors/transform/transform_convert_gpencil.c index 8c23f3c2b96..b4e48674892 100644 --- a/source/blender/editors/transform/transform_convert_gpencil.c +++ b/source/blender/editors/transform/transform_convert_gpencil.c @@ -766,8 +766,8 @@ static void recalcData_gpencil_strokes(TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_GPencil = { - /* flags */ (T_EDIT | T_POINTS), - /* createTransData */ createTransGPencil, - /* recalcData */ recalcData_gpencil_strokes, - /* special_aftertrans_update */ NULL, + /*flags*/ (T_EDIT | T_POINTS), + /*createTransData*/ createTransGPencil, + /*recalcData*/ recalcData_gpencil_strokes, + /*special_aftertrans_update*/ NULL, }; diff --git a/source/blender/editors/transform/transform_convert_graph.c b/source/blender/editors/transform/transform_convert_graph.c index 252c5cc3d37..68c3479fb5d 100644 --- a/source/blender/editors/transform/transform_convert_graph.c +++ b/source/blender/editors/transform/transform_convert_graph.c @@ -1035,8 +1035,8 @@ static void special_aftertrans_update__graph(bContext *C, TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_Graph = { - /* flags */ (T_POINTS | T_2D_EDIT), - /* createTransData */ createTransGraphEditData, - /* recalcData */ recalcData_graphedit, - /* special_aftertrans_update */ special_aftertrans_update__graph, + /*flags*/ (T_POINTS | T_2D_EDIT), + /*createTransData*/ createTransGraphEditData, + /*recalcData*/ recalcData_graphedit, + /*special_aftertrans_update*/ special_aftertrans_update__graph, }; diff --git a/source/blender/editors/transform/transform_convert_lattice.c b/source/blender/editors/transform/transform_convert_lattice.c index bc53ce02996..077199a6257 100644 --- a/source/blender/editors/transform/transform_convert_lattice.c +++ b/source/blender/editors/transform/transform_convert_lattice.c @@ -117,8 +117,8 @@ static void recalcData_lattice(TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_Lattice = { - /* flags */ (T_EDIT | T_POINTS), - /* createTransData */ createTransLatticeVerts, - /* recalcData */ recalcData_lattice, - /* special_aftertrans_update */ NULL, + /*flags*/ (T_EDIT | T_POINTS), + /*createTransData*/ createTransLatticeVerts, + /*recalcData*/ recalcData_lattice, + /*special_aftertrans_update*/ NULL, }; diff --git a/source/blender/editors/transform/transform_convert_mask.c b/source/blender/editors/transform/transform_convert_mask.c index 2dca59a5da1..5a497c925e4 100644 --- a/source/blender/editors/transform/transform_convert_mask.c +++ b/source/blender/editors/transform/transform_convert_mask.c @@ -465,8 +465,8 @@ static void special_aftertrans_update__mask(bContext *C, TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_Mask = { - /* flags */ (T_POINTS | T_2D_EDIT), - /* createTransData */ createTransMaskingData, - /* recalcData */ recalcData_mask_common, - /* special_aftertrans_update */ special_aftertrans_update__mask, + /*flags*/ (T_POINTS | T_2D_EDIT), + /*createTransData*/ createTransMaskingData, + /*recalcData*/ recalcData_mask_common, + /*special_aftertrans_update*/ special_aftertrans_update__mask, }; diff --git a/source/blender/editors/transform/transform_convert_mball.c b/source/blender/editors/transform/transform_convert_mball.c index b4150539a51..adee242457d 100644 --- a/source/blender/editors/transform/transform_convert_mball.c +++ b/source/blender/editors/transform/transform_convert_mball.c @@ -135,8 +135,8 @@ static void recalcData_mball(TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_MBall = { - /* flags */ (T_EDIT | T_POINTS), - /* createTransData */ createTransMBallVerts, - /* recalcData */ recalcData_mball, - /* special_aftertrans_update */ NULL, + /*flags*/ (T_EDIT | T_POINTS), + /*createTransData*/ createTransMBallVerts, + /*recalcData*/ recalcData_mball, + /*special_aftertrans_update*/ NULL, }; diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index 34432004701..5e164dfd8ad 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -2139,8 +2139,8 @@ static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_Mesh = { - /* flags */ (T_EDIT | T_POINTS), - /* createTransData */ createTransEditVerts, - /* recalcData */ recalcData_mesh, - /* special_aftertrans_update */ special_aftertrans_update__mesh, + /*flags*/ (T_EDIT | T_POINTS), + /*createTransData*/ createTransEditVerts, + /*recalcData*/ recalcData_mesh, + /*special_aftertrans_update*/ special_aftertrans_update__mesh, }; diff --git a/source/blender/editors/transform/transform_convert_mesh_edge.c b/source/blender/editors/transform/transform_convert_mesh_edge.c index f8ea8ea9f7d..e5c2c90f957 100644 --- a/source/blender/editors/transform/transform_convert_mesh_edge.c +++ b/source/blender/editors/transform/transform_convert_mesh_edge.c @@ -122,8 +122,8 @@ static void recalcData_mesh_edge(TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_MeshEdge = { - /* flags */ T_EDIT, - /* createTransData */ createTransEdge, - /* recalcData */ recalcData_mesh_edge, - /* special_aftertrans_update */ NULL, + /*flags*/ T_EDIT, + /*createTransData*/ createTransEdge, + /*recalcData*/ recalcData_mesh_edge, + /*special_aftertrans_update*/ NULL, }; diff --git a/source/blender/editors/transform/transform_convert_mesh_skin.c b/source/blender/editors/transform/transform_convert_mesh_skin.c index 1139e61aefb..8bd40561396 100644 --- a/source/blender/editors/transform/transform_convert_mesh_skin.c +++ b/source/blender/editors/transform/transform_convert_mesh_skin.c @@ -292,8 +292,8 @@ static void recalcData_mesh_skin(TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_MeshSkin = { - /* flags */ (T_EDIT | T_POINTS), - /* createTransData */ createTransMeshSkin, - /* recalcData */ recalcData_mesh_skin, - /* special_aftertrans_update */ NULL, + /*flags*/ (T_EDIT | T_POINTS), + /*createTransData*/ createTransMeshSkin, + /*recalcData*/ recalcData_mesh_skin, + /*special_aftertrans_update*/ NULL, }; diff --git a/source/blender/editors/transform/transform_convert_mesh_uv.c b/source/blender/editors/transform/transform_convert_mesh_uv.c index c7d5411f907..f3b8cc59871 100644 --- a/source/blender/editors/transform/transform_convert_mesh_uv.c +++ b/source/blender/editors/transform/transform_convert_mesh_uv.c @@ -470,8 +470,8 @@ static void recalcData_uv(TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_MeshUV = { - /* flags */ (T_EDIT | T_POINTS | T_2D_EDIT), - /* createTransData */ createTransUVs, - /* recalcData */ recalcData_uv, - /* special_aftertrans_update */ NULL, + /*flags*/ (T_EDIT | T_POINTS | T_2D_EDIT), + /*createTransData*/ createTransUVs, + /*recalcData*/ recalcData_uv, + /*special_aftertrans_update*/ NULL, }; diff --git a/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c b/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c index 0d29892cd5e..f1428bdfebc 100644 --- a/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c +++ b/source/blender/editors/transform/transform_convert_mesh_vert_cdata.c @@ -294,8 +294,8 @@ static void recalcData_mesh_cdata(TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_MeshVertCData = { - /* flags */ (T_EDIT | T_POINTS), - /* createTransData */ createTransMeshVertCData, - /* recalcData */ recalcData_mesh_cdata, - /* special_aftertrans_update */ NULL, + /*flags*/ (T_EDIT | T_POINTS), + /*createTransData*/ createTransMeshVertCData, + /*recalcData*/ recalcData_mesh_cdata, + /*special_aftertrans_update*/ NULL, }; diff --git a/source/blender/editors/transform/transform_convert_nla.c b/source/blender/editors/transform/transform_convert_nla.c index ab71fe42f07..f38d25b440b 100644 --- a/source/blender/editors/transform/transform_convert_nla.c +++ b/source/blender/editors/transform/transform_convert_nla.c @@ -542,8 +542,8 @@ static void special_aftertrans_update__nla(bContext *C, TransInfo *UNUSED(t)) /** \} */ TransConvertTypeInfo TransConvertType_NLA = { - /* flags */ (T_POINTS | T_2D_EDIT), - /* createTransData */ createTransNlaData, - /* recalcData */ recalcData_nla, - /* special_aftertrans_update */ special_aftertrans_update__nla, + /*flags*/ (T_POINTS | T_2D_EDIT), + /*createTransData*/ createTransNlaData, + /*recalcData*/ recalcData_nla, + /*special_aftertrans_update*/ special_aftertrans_update__nla, }; diff --git a/source/blender/editors/transform/transform_convert_node.cc b/source/blender/editors/transform/transform_convert_node.cc index 1c35323a154..13095ff6f5a 100644 --- a/source/blender/editors/transform/transform_convert_node.cc +++ b/source/blender/editors/transform/transform_convert_node.cc @@ -303,8 +303,8 @@ static void special_aftertrans_update__node(bContext *C, TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_Node = { - /* flags */ (T_POINTS | T_2D_EDIT), - /* createTransData */ createTransNodeData, - /* recalcData */ flushTransNodes, - /* special_aftertrans_update */ special_aftertrans_update__node, + /*flags*/ (T_POINTS | T_2D_EDIT), + /*createTransData*/ createTransNodeData, + /*recalcData*/ flushTransNodes, + /*special_aftertrans_update*/ special_aftertrans_update__node, }; diff --git a/source/blender/editors/transform/transform_convert_object.c b/source/blender/editors/transform/transform_convert_object.c index 401d72485c8..045b737c4f7 100644 --- a/source/blender/editors/transform/transform_convert_object.c +++ b/source/blender/editors/transform/transform_convert_object.c @@ -1006,8 +1006,8 @@ static void special_aftertrans_update__object(bContext *C, TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_Object = { - /* flags */ 0, - /* createTransData */ createTransObject, - /* recalcData */ recalcData_objects, - /* special_aftertrans_update */ special_aftertrans_update__object, + /*flags*/ 0, + /*createTransData*/ createTransObject, + /*recalcData*/ recalcData_objects, + /*special_aftertrans_update*/ special_aftertrans_update__object, }; diff --git a/source/blender/editors/transform/transform_convert_object_texspace.c b/source/blender/editors/transform/transform_convert_object_texspace.c index cd2a3d6a40b..fb82f1645f5 100644 --- a/source/blender/editors/transform/transform_convert_object_texspace.c +++ b/source/blender/editors/transform/transform_convert_object_texspace.c @@ -110,8 +110,8 @@ static void recalcData_texspace(TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_ObjectTexSpace = { - /* flags */ 0, - /* createTransData */ createTransTexspace, - /* recalcData */ recalcData_texspace, - /* special_aftertrans_update */ NULL, + /*flags*/ 0, + /*createTransData*/ createTransTexspace, + /*recalcData*/ recalcData_texspace, + /*special_aftertrans_update*/ NULL, }; diff --git a/source/blender/editors/transform/transform_convert_paintcurve.c b/source/blender/editors/transform/transform_convert_paintcurve.c index 61b1cb9493b..71593ceed80 100644 --- a/source/blender/editors/transform/transform_convert_paintcurve.c +++ b/source/blender/editors/transform/transform_convert_paintcurve.c @@ -206,8 +206,8 @@ static void flushTransPaintCurve(TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_PaintCurve = { - /* flags */ (T_POINTS | T_2D_EDIT), - /* createTransData */ createTransPaintCurveVerts, - /* recalcData */ flushTransPaintCurve, - /* special_aftertrans_update */ NULL, + /*flags*/ (T_POINTS | T_2D_EDIT), + /*createTransData*/ createTransPaintCurveVerts, + /*recalcData*/ flushTransPaintCurve, + /*special_aftertrans_update*/ NULL, }; diff --git a/source/blender/editors/transform/transform_convert_particle.c b/source/blender/editors/transform/transform_convert_particle.c index f1bda0a5a35..9914a64ab5b 100644 --- a/source/blender/editors/transform/transform_convert_particle.c +++ b/source/blender/editors/transform/transform_convert_particle.c @@ -249,8 +249,8 @@ static void recalcData_particles(TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_Particle = { - /* flags */ T_POINTS, - /* createTransData */ createTransParticleVerts, - /* recalcData */ recalcData_particles, - /* special_aftertrans_update */ NULL, + /*flags*/ T_POINTS, + /*createTransData*/ createTransParticleVerts, + /*recalcData*/ recalcData_particles, + /*special_aftertrans_update*/ NULL, }; diff --git a/source/blender/editors/transform/transform_convert_sculpt.c b/source/blender/editors/transform/transform_convert_sculpt.c index cdbf497c584..cdd46e08c5c 100644 --- a/source/blender/editors/transform/transform_convert_sculpt.c +++ b/source/blender/editors/transform/transform_convert_sculpt.c @@ -120,8 +120,8 @@ static void special_aftertrans_update__sculpt(bContext *C, TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_Sculpt = { - /* flags */ 0, - /* createTransData */ createTransSculpt, - /* recalcData */ recalcData_sculpt, - /* special_aftertrans_update */ special_aftertrans_update__sculpt, + /*flags*/ 0, + /*createTransData*/ createTransSculpt, + /*recalcData*/ recalcData_sculpt, + /*special_aftertrans_update*/ special_aftertrans_update__sculpt, }; diff --git a/source/blender/editors/transform/transform_convert_sequencer.c b/source/blender/editors/transform/transform_convert_sequencer.c index 80c74b81cfa..8a42ac8a73d 100644 --- a/source/blender/editors/transform/transform_convert_sequencer.c +++ b/source/blender/editors/transform/transform_convert_sequencer.c @@ -734,8 +734,8 @@ void transform_convert_sequencer_channel_clamp(TransInfo *t, float r_val[2]) /** \} */ TransConvertTypeInfo TransConvertType_Sequencer = { - /* flags */ (T_POINTS | T_2D_EDIT), - /* createTransData */ createTransSeqData, - /* recalcData */ recalcData_sequencer, - /* special_aftertrans_update */ special_aftertrans_update__sequencer, + /*flags*/ (T_POINTS | T_2D_EDIT), + /*createTransData*/ createTransSeqData, + /*recalcData*/ recalcData_sequencer, + /*special_aftertrans_update*/ special_aftertrans_update__sequencer, }; diff --git a/source/blender/editors/transform/transform_convert_sequencer_image.c b/source/blender/editors/transform/transform_convert_sequencer_image.c index 668cb719b2b..ee80c616bd5 100644 --- a/source/blender/editors/transform/transform_convert_sequencer_image.c +++ b/source/blender/editors/transform/transform_convert_sequencer_image.c @@ -278,8 +278,8 @@ static void special_aftertrans_update__sequencer_image(bContext *UNUSED(C), Tran } TransConvertTypeInfo TransConvertType_SequencerImage = { - /* flags */ (T_POINTS | T_2D_EDIT), - /* createTransData */ createTransSeqImageData, - /* recalcData */ recalcData_sequencer_image, - /* special_aftertrans_update */ special_aftertrans_update__sequencer_image, + /*flags*/ (T_POINTS | T_2D_EDIT), + /*createTransData*/ createTransSeqImageData, + /*recalcData*/ recalcData_sequencer_image, + /*special_aftertrans_update*/ special_aftertrans_update__sequencer_image, }; diff --git a/source/blender/editors/transform/transform_convert_tracking.c b/source/blender/editors/transform/transform_convert_tracking.c index 6aa53291173..0adb3b75aec 100644 --- a/source/blender/editors/transform/transform_convert_tracking.c +++ b/source/blender/editors/transform/transform_convert_tracking.c @@ -779,8 +779,8 @@ static void special_aftertrans_update__movieclip(bContext *C, TransInfo *t) /** \} */ TransConvertTypeInfo TransConvertType_Tracking = { - /* flags */ (T_POINTS | T_2D_EDIT), - /* createTransData */ createTransTrackingData, - /* recalcData */ recalcData_tracking, - /* special_aftertrans_update */ special_aftertrans_update__movieclip, + /*flags*/ (T_POINTS | T_2D_EDIT), + /*createTransData*/ createTransTrackingData, + /*recalcData*/ recalcData_tracking, + /*special_aftertrans_update*/ special_aftertrans_update__movieclip, }; diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp index af9ef7f352e..533ad18d927 100644 --- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp +++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp @@ -72,12 +72,11 @@ static void load_post_callback(struct Main * /*main*/, } static bCallbackFuncStore load_post_callback_funcstore = { - nullptr, /* next */ - nullptr, /* prev */ - load_post_callback, /* func */ - nullptr, /* arg */ - 0 /* alloc */ -}; + /*next*/ nullptr, + /*prev*/ nullptr, + /*func*/ load_post_callback, + /*arg*/ nullptr, + /*alloc*/ 0}; //======================================================= // Initialization diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c index 5163f4d7020..a3665920d15 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c @@ -189,24 +189,24 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Armature = { - /* name */ N_("Armature"), - /* structName */ "ArmatureGpencilModifierData", - /* structSize */ sizeof(ArmatureGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Armature"), + /*structName*/ "ArmatureGpencilModifierData", + /*structSize*/ sizeof(ArmatureGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c index e85011639c2..c8ab376bed9 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarray.c @@ -485,25 +485,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Array = { - /* name */ N_("Array"), - /* structName */ "ArrayGpencilModifierData", - /* structSize */ sizeof(ArrayGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Array"), + /*structName*/ "ArrayGpencilModifierData", + /*structSize*/ sizeof(ArrayGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ NULL, - /* generateStrokes */ generateStrokes, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ NULL, + /*generateStrokes*/ generateStrokes, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c index 2d2d36ab20e..b8afe9144b1 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c @@ -1038,25 +1038,25 @@ static void updateDepsgraph(GpencilModifierData *md, /* ******************************************** */ GpencilModifierTypeInfo modifierType_Gpencil_Build = { - /* name */ N_("Build"), - /* structName */ "BuildGpencilModifierData", - /* structSize */ sizeof(BuildGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_NoApply, + /*name*/ N_("Build"), + /*structName*/ "BuildGpencilModifierData", + /*structSize*/ sizeof(BuildGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_NoApply, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ NULL, - /* generateStrokes */ generateStrokes, - /* bakeModifier */ NULL, - /* remapTime */ NULL, + /*deformStroke*/ NULL, + /*generateStrokes*/ generateStrokes, + /*bakeModifier*/ NULL, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c index 7abbd0661cf..9a237630bc8 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c @@ -204,25 +204,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Color = { - /* name */ N_("Hue/Saturation"), - /* structName */ "ColorGpencilModifierData", - /* structSize */ sizeof(ColorGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Hue/Saturation"), + /*structName*/ "ColorGpencilModifierData", + /*structSize*/ sizeof(ColorGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencildash.c b/source/blender/gpencil_modifiers/intern/MOD_gpencildash.c index 52b0eb79978..2ff2a0eb1fa 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencildash.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencildash.c @@ -367,25 +367,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Dash = { - /* name */ N_("Dot Dash"), - /* structName */ "DashGpencilModifierData", - /* structSize */ sizeof(DashGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Dot Dash"), + /*structName*/ "DashGpencilModifierData", + /*structSize*/ sizeof(DashGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ NULL, - /* generateStrokes */ generateStrokes, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ NULL, + /*generateStrokes*/ generateStrokes, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilenvelope.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilenvelope.c index ec0ed1f6a35..8a88cc0a01e 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilenvelope.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilenvelope.c @@ -645,25 +645,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Envelope = { - /* name */ N_("Envelope"), - /* structName */ "EnvelopeGpencilModifierData", - /* structSize */ sizeof(EnvelopeGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Envelope"), + /*structName*/ "EnvelopeGpencilModifierData", + /*structSize*/ sizeof(EnvelopeGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ generateStrokes, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ generateStrokes, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c index e3b4e1c5e02..04b4ca469af 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c @@ -387,25 +387,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Hook = { - /* name */ N_("Hook"), - /* structName */ "HookGpencilModifierData", - /* structSize */ sizeof(HookGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Hook"), + /*structName*/ "HookGpencilModifierData", + /*structSize*/ sizeof(HookGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c index 7365c59dd5f..051ad2cd1bb 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c @@ -247,25 +247,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Lattice = { - /* name */ N_("Lattice"), - /* structName */ "LatticeGpencilModifierData", - /* structSize */ sizeof(LatticeGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Lattice"), + /*structName*/ "LatticeGpencilModifierData", + /*structSize*/ sizeof(LatticeGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillength.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillength.c index b4dac1557f0..a6e8d417699 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillength.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillength.c @@ -355,25 +355,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Length = { - /* name */ N_("Length"), - /* structName */ "LengthGpencilModifierData", - /* structSize */ sizeof(LengthGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Length"), + /*structName*/ "LengthGpencilModifierData", + /*structSize*/ sizeof(LengthGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c index ec4cf71e00c..b33a6970d1f 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c @@ -809,25 +809,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Lineart = { - /* name. */ "Line Art", - /* structName. */ "LineartGpencilModifierData", - /* structSize. */ sizeof(LineartGpencilModifierData), - /* type. */ eGpencilModifierTypeType_Gpencil, - /* flags. */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ "Line Art", + /*structName*/ "LineartGpencilModifierData", + /*structSize*/ sizeof(LineartGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData. */ copyData, + /*copyData*/ copyData, - /* deformStroke. */ NULL, - /* generateStrokes. */ generateStrokes, - /* bakeModifier. */ bakeModifier, - /* remapTime. */ NULL, + /*deformStroke*/ NULL, + /*generateStrokes*/ generateStrokes, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData. */ initData, - /* freeData. */ NULL, - /* isDisabled. */ isDisabled, - /* updateDepsgraph. */ updateDepsgraph, - /* dependsOnTime. */ NULL, - /* foreachIDLink. */ foreachIDLink, - /* foreachTexLink. */ NULL, - /* panelRegister. */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c index bc91094e80e..65c5c2a8b37 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c @@ -243,25 +243,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Mirror = { - /* name */ N_("Mirror"), - /* structName */ "MirrorGpencilModifierData", - /* structSize */ sizeof(MirrorGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Mirror"), + /*structName*/ "MirrorGpencilModifierData", + /*structSize*/ sizeof(MirrorGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ NULL, - /* generateStrokes */ generateStrokes, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ NULL, + /*generateStrokes*/ generateStrokes, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c index cb4a7893080..ad0fd915c81 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmultiply.c @@ -313,25 +313,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Multiply = { - /* name */ N_("MultipleStrokes"), - /* structName */ "MultiplyGpencilModifierData", - /* structSize */ sizeof(MultiplyGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ 0, + /*name*/ N_("MultipleStrokes"), + /*structName*/ "MultiplyGpencilModifierData", + /*structSize*/ sizeof(MultiplyGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ 0, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ NULL, - /* generateStrokes */ generateStrokes, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ NULL, + /*generateStrokes*/ generateStrokes, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c index 4bbcbf775db..100df37f402 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c @@ -339,25 +339,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Noise = { - /* name */ N_("Noise"), - /* structName */ "NoiseGpencilModifierData", - /* structSize */ sizeof(NoiseGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Noise"), + /*structName*/ "NoiseGpencilModifierData", + /*structSize*/ sizeof(NoiseGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ dependsOnTime, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ dependsOnTime, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c index 1beebc3cbe8..e40c6e9df4d 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c @@ -309,25 +309,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Offset = { - /* name */ N_("Offset"), - /* structName */ "OffsetGpencilModifierData", - /* structSize */ sizeof(OffsetGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Offset"), + /*structName*/ "OffsetGpencilModifierData", + /*structSize*/ sizeof(OffsetGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c index 98f26dbd597..34ae3b460a4 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c @@ -279,25 +279,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Opacity = { - /* name */ N_("Opacity"), - /* structName */ "OpacityGpencilModifierData", - /* structSize */ sizeof(OpacityGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Opacity"), + /*structName*/ "OpacityGpencilModifierData", + /*structSize*/ sizeof(OpacityGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c index dff8d14564a..32a54bbee4c 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloutline.c @@ -324,25 +324,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Outline = { - /* name */ N_("Outline"), - /* structName */ "OutlineGpencilModifierData", - /* structSize */ sizeof(OutlineGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Outline"), + /*structName*/ "OutlineGpencilModifierData", + /*structSize*/ sizeof(OutlineGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ NULL, - /* generateStrokes */ generateStrokes, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ NULL, + /*generateStrokes*/ generateStrokes, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c index 74b7efb1d04..ae0eb5a0a25 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilshrinkwrap.c @@ -306,25 +306,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Shrinkwrap = { - /* name */ N_("Shrinkwrap"), - /* structName */ "ShrinkwrapGpencilModifierData", - /* structSize */ sizeof(ShrinkwrapGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Shrinkwrap"), + /*structName*/ "ShrinkwrapGpencilModifierData", + /*structSize*/ sizeof(ShrinkwrapGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c index 41de8d74257..f1826c3a59d 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c @@ -159,25 +159,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Simplify = { - /* name */ N_("Simplify"), - /* structName */ "SimplifyGpencilModifierData", - /* structSize */ sizeof(SimplifyGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Simplify"), + /*structName*/ "SimplifyGpencilModifierData", + /*structSize*/ sizeof(SimplifyGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c index 977be634490..cba7895c85d 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c @@ -203,25 +203,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Smooth = { - /* name */ N_("Smooth"), - /* structName */ "SmoothGpencilModifierData", - /* structSize */ sizeof(SmoothGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Smooth"), + /*structName*/ "SmoothGpencilModifierData", + /*structSize*/ sizeof(SmoothGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c index b856f7d81dc..091d9b42bb1 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c @@ -124,25 +124,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Subdiv = { - /* name */ N_("Subdivide"), - /* structName */ "SubdivGpencilModifierData", - /* structSize */ sizeof(SubdivGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Subdivide"), + /*structName*/ "SubdivGpencilModifierData", + /*structSize*/ sizeof(SubdivGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltexture.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltexture.c index 16c8365153a..6d1166e9f5b 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltexture.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltexture.c @@ -178,25 +178,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Texture = { - /* name */ N_("TextureMapping"), - /* structName */ "TextureGpencilModifierData", - /* structSize */ sizeof(TextureGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("TextureMapping"), + /*structName*/ "TextureGpencilModifierData", + /*structSize*/ sizeof(TextureGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c index 81343fb5180..cd683544a42 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c @@ -206,25 +206,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Thick = { - /* name */ N_("Thickness"), - /* structName */ "ThickGpencilModifierData", - /* structSize */ sizeof(ThickGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Thickness"), + /*structName*/ "ThickGpencilModifierData", + /*structSize*/ sizeof(ThickGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c index 68773886cf4..ed94581b628 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltime.c @@ -421,25 +421,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Time = { - /* name */ N_("TimeOffset"), - /* structName */ "TimeGpencilModifierData", - /* structSize */ sizeof(TimeGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_NoApply, + /*name*/ N_("TimeOffset"), + /*structName*/ "TimeGpencilModifierData", + /*structSize*/ sizeof(TimeGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_NoApply, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ NULL, - /* generateStrokes */ NULL, - /* bakeModifier */ NULL, - /* remapTime */ remapTime, + /*deformStroke*/ NULL, + /*generateStrokes*/ NULL, + /*bakeModifier*/ NULL, + /*remapTime*/ remapTime, - /* initData */ initData, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c index 8331188fbd8..7ca28e69886 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c @@ -367,25 +367,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_Tint = { - /* name */ N_("Tint"), - /* structName */ "TintGpencilModifierData", - /* structSize */ sizeof(TintGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ eGpencilModifierTypeFlag_SupportsEditmode, + /*name*/ N_("Tint"), + /*structName*/ "TintGpencilModifierData", + /*structSize*/ sizeof(TintGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ eGpencilModifierTypeFlag_SupportsEditmode, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_angle.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_angle.c index e9761732614..ac56b88d221 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_angle.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_angle.c @@ -211,25 +211,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_WeightAngle = { - /* name */ N_("Vertex Weight Angle"), - /* structName */ "WeightAngleGpencilModifierData", - /* structSize */ sizeof(WeightAngleGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ 0, + /*name*/ N_("Vertex Weight Angle"), + /*structName*/ "WeightAngleGpencilModifierData", + /*structSize*/ sizeof(WeightAngleGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ 0, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_proximity.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_proximity.c index ddf852bcd11..f0c7632e828 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_proximity.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilweight_proximity.c @@ -228,25 +228,25 @@ static void panelRegister(ARegionType *region_type) } GpencilModifierTypeInfo modifierType_Gpencil_WeightProximity = { - /* name */ N_("Vertex Weight Proximity"), - /* structName */ "WeightProxGpencilModifierData", - /* structSize */ sizeof(WeightProxGpencilModifierData), - /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ 0, + /*name*/ N_("Vertex Weight Proximity"), + /*structName*/ "WeightProxGpencilModifierData", + /*structSize*/ sizeof(WeightProxGpencilModifierData), + /*type*/ eGpencilModifierTypeType_Gpencil, + /*flags*/ 0, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, - /* remapTime */ NULL, + /*deformStroke*/ deformStroke, + /*generateStrokes*/ NULL, + /*bakeModifier*/ bakeModifier, + /*remapTime*/ NULL, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c index b16d127a643..d8511224f6e 100644 --- a/source/blender/makesrna/intern/rna_key.c +++ b/source/blender/makesrna/intern/rna_key.c @@ -987,7 +987,7 @@ static void rna_def_keyblock(BlenderRNA *brna) RNA_def_function_ui_description(func, "Compute local space vertices' normals for this shape key"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); - parm = RNA_def_property(func, "normals", PROP_FLOAT, /* PROP_DIRECTION */ PROP_NONE); + parm = RNA_def_property(func, "normals", PROP_FLOAT, /*PROP_DIRECTION*/ PROP_NONE); RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_OUTPUT); RNA_def_property_multi_array(parm, 2, NULL); RNA_def_property_range(parm, -1.0f, 1.0f); @@ -996,7 +996,7 @@ static void rna_def_keyblock(BlenderRNA *brna) func = RNA_def_function(srna, "normals_polygon_get", "rna_KeyBlock_normals_poly_calc"); RNA_def_function_ui_description(func, "Compute local space faces' normals for this shape key"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); - parm = RNA_def_property(func, "normals", PROP_FLOAT, /* PROP_DIRECTION */ PROP_NONE); + parm = RNA_def_property(func, "normals", PROP_FLOAT, /*PROP_DIRECTION*/ PROP_NONE); RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_OUTPUT); RNA_def_property_multi_array(parm, 2, NULL); RNA_def_property_range(parm, -1.0f, 1.0f); @@ -1006,7 +1006,7 @@ static void rna_def_keyblock(BlenderRNA *brna) RNA_def_function_ui_description(func, "Compute local space face corners' normals for this shape key"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); - parm = RNA_def_property(func, "normals", PROP_FLOAT, /* PROP_DIRECTION */ PROP_NONE); + parm = RNA_def_property(func, "normals", PROP_FLOAT, /*PROP_DIRECTION*/ PROP_NONE); RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_OUTPUT); RNA_def_property_multi_array(parm, 2, NULL); RNA_def_property_range(parm, -1.0f, 1.0f); diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index e8aac290dd5..98adb456b23 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -260,35 +260,35 @@ static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md) } ModifierTypeInfo modifierType_Armature = { - /* name */ N_("Armature"), - /* structName */ "ArmatureModifierData", - /* structSize */ sizeof(ArmatureModifierData), - /* srna */ &RNA_ArmatureModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | + /*name*/ N_("Armature"), + /*structName*/ "ArmatureModifierData", + /*structSize*/ sizeof(ArmatureModifierData), + /*srna*/ &RNA_ArmatureModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_ARMATURE, + /*icon*/ ICON_MOD_ARMATURE, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ deformVerts, - /* deformMatrices */ deformMatrices, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ deformMatricesEM, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ deformMatrices, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ deformMatricesEM, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_array.cc b/source/blender/modifiers/intern/MOD_array.cc index 6c15994e865..512ef154516 100644 --- a/source/blender/modifiers/intern/MOD_array.cc +++ b/source/blender/modifiers/intern/MOD_array.cc @@ -1000,36 +1000,36 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Array = { - /* name */ N_("Array"), - /* structName */ "ArrayModifierData", - /* structSize */ sizeof(ArrayModifierData), - /* srna */ &RNA_ArrayModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("Array"), + /*structName*/ "ArrayModifierData", + /*structSize*/ sizeof(ArrayModifierData), + /*srna*/ &RNA_ArrayModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_AcceptsCVs, - /* icon */ ICON_MOD_ARRAY, + /*icon*/ ICON_MOD_ARRAY, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ nullptr, - /* freeData */ nullptr, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ nullptr, + /*freeData*/ nullptr, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 48d355d8ca7..f49888a17fd 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -419,32 +419,32 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) } ModifierTypeInfo modifierType_Bevel = { - /* name */ N_("Bevel"), - /* structName */ "BevelModifierData", - /* structSize */ sizeof(BevelModifierData), - /* srna */ &RNA_BevelModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | + /*name*/ N_("Bevel"), + /*structName*/ "BevelModifierData", + /*structSize*/ sizeof(BevelModifierData), + /*srna*/ &RNA_BevelModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_AcceptsCVs, - /* icon */ ICON_MOD_BEVEL, - /* copyData */ copyData, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ dependsOnNormals, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* uiPanel */ panelRegister, - /* blendWrite */ blendWrite, - /* blendRead */ blendRead, + /*icon*/ ICON_MOD_BEVEL, + /*copyData*/ copyData, + /*deformVerts*/ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ dependsOnNormals, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*uiPanel*/ panelRegister, + /*blendWrite*/ blendWrite, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_boolean.cc b/source/blender/modifiers/intern/MOD_boolean.cc index 6175455867e..207eceec431 100644 --- a/source/blender/modifiers/intern/MOD_boolean.cc +++ b/source/blender/modifiers/intern/MOD_boolean.cc @@ -664,35 +664,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Boolean = { - /* name */ N_("Boolean"), - /* structName */ "BooleanModifierData", - /* structSize */ sizeof(BooleanModifierData), - /* srna */ &RNA_BooleanModifier, - /* type */ eModifierTypeType_Nonconstructive, - /* flags */ + /*name*/ N_("Boolean"), + /*structName*/ "BooleanModifierData", + /*structSize*/ sizeof(BooleanModifierData), + /*srna*/ &RNA_BooleanModifier, + /*type*/ eModifierTypeType_Nonconstructive, + /*flags*/ (ModifierTypeFlag)(eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode), - /* icon */ ICON_MOD_BOOLEAN, + /*icon*/ ICON_MOD_BOOLEAN, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ nullptr, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ nullptr, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index c6bda4a707b..b2c9995a928 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -309,34 +309,34 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Build = { - /* name */ N_("Build"), - /* structName */ "BuildModifierData", - /* structSize */ sizeof(BuildModifierData), - /* srna */ &RNA_BuildModifier, - /* type */ eModifierTypeType_Nonconstructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs, - /* icon */ ICON_MOD_BUILD, + /*name*/ N_("Build"), + /*structName*/ "BuildModifierData", + /*structSize*/ sizeof(BuildModifierData), + /*srna*/ &RNA_BuildModifier, + /*type*/ eModifierTypeType_Nonconstructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs, + /*icon*/ ICON_MOD_BUILD, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ NULL, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ NULL, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c index b6e1b5e88c1..cb15ef965f9 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -557,35 +557,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Cast = { - /* name */ N_("Cast"), - /* structName */ "CastModifierData", - /* structSize */ sizeof(CastModifierData), - /* srna */ &RNA_CastModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | + /*name*/ N_("Cast"), + /*structName*/ "CastModifierData", + /*structSize*/ sizeof(CastModifierData), + /*srna*/ &RNA_CastModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_CAST, + /*icon*/ ICON_MOD_CAST, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c index 379ed32fce5..baed03692cb 100644 --- a/source/blender/modifiers/intern/MOD_cloth.c +++ b/source/blender/modifiers/intern/MOD_cloth.c @@ -274,35 +274,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Cloth = { - /* name */ N_("Cloth"), - /* structName */ "ClothModifierData", - /* structSize */ sizeof(ClothModifierData), - /* srna */ &RNA_ClothModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_UsesPointCache | + /*name*/ N_("Cloth"), + /*structName*/ "ClothModifierData", + /*structSize*/ sizeof(ClothModifierData), + /*srna*/ &RNA_ClothModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_UsesPointCache | eModifierTypeFlag_Single, - /* icon */ ICON_MOD_CLOTH, + /*icon*/ ICON_MOD_CLOTH, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index f933bcff360..5f5cbfc342d 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -283,34 +283,34 @@ static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md) } ModifierTypeInfo modifierType_Collision = { - /* name */ N_("Collision"), - /* structName */ "CollisionModifierData", - /* structSize */ sizeof(CollisionModifierData), - /* srna */ &RNA_CollisionModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_Single, - /* icon */ ICON_MOD_PHYSICS, + /*name*/ N_("Collision"), + /*structName*/ "CollisionModifierData", + /*structSize*/ sizeof(CollisionModifierData), + /*srna*/ &RNA_CollisionModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_Single, + /*icon*/ ICON_MOD_PHYSICS, - /* copyData */ NULL, + /*copyData*/ NULL, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ NULL, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ NULL, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c index 5a9f7c657eb..50b6c7fcb32 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.c +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c @@ -842,34 +842,34 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) } ModifierTypeInfo modifierType_CorrectiveSmooth = { - /* name */ N_("CorrectiveSmooth"), - /* structName */ "CorrectiveSmoothModifierData", - /* structSize */ sizeof(CorrectiveSmoothModifierData), - /* srna */ &RNA_CorrectiveSmoothModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_SMOOTH, + /*name*/ N_("CorrectiveSmooth"), + /*structName*/ "CorrectiveSmoothModifierData", + /*structSize*/ sizeof(CorrectiveSmoothModifierData), + /*srna*/ &RNA_CorrectiveSmoothModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, + /*icon*/ ICON_MOD_SMOOTH, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ blendWrite, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ blendWrite, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index 16c97d486da..7672fd20ae5 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -201,35 +201,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Curve = { - /* name */ N_("Curve"), - /* structName */ "CurveModifierData", - /* structSize */ sizeof(CurveModifierData), - /* srna */ &RNA_CurveModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | + /*name*/ N_("Curve"), + /*structName*/ "CurveModifierData", + /*structSize*/ sizeof(CurveModifierData), + /*srna*/ &RNA_CurveModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_CURVE, + /*icon*/ ICON_MOD_CURVE, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_datatransfer.cc b/source/blender/modifiers/intern/MOD_datatransfer.cc index 40411f06ef3..7ac834c804a 100644 --- a/source/blender/modifiers/intern/MOD_datatransfer.cc +++ b/source/blender/modifiers/intern/MOD_datatransfer.cc @@ -480,35 +480,35 @@ static void panelRegister(ARegionType *region_type) #undef DT_TYPES_AFFECT_MESH ModifierTypeInfo modifierType_DataTransfer = { - /* name */ N_("DataTransfer"), - /* structName */ "DataTransferModifierData", - /* structSize */ sizeof(DataTransferModifierData), - /* srna */ &RNA_DataTransferModifier, - /* type */ eModifierTypeType_NonGeometrical, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("DataTransfer"), + /*structName*/ "DataTransferModifierData", + /*structSize*/ sizeof(DataTransferModifierData), + /*srna*/ &RNA_DataTransferModifier, + /*type*/ eModifierTypeType_NonGeometrical, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview, - /* icon */ ICON_MOD_DATA_TRANSFER, + /*icon*/ ICON_MOD_DATA_TRANSFER, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ nullptr, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ dependsOnNormals, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ nullptr, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ dependsOnNormals, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index 059ded4f873..cf698669397 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -269,34 +269,34 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Decimate = { - /* name */ N_("Decimate"), - /* structName */ "DecimateModifierData", - /* structSize */ sizeof(DecimateModifierData), - /* srna */ &RNA_DecimateModifier, - /* type */ eModifierTypeType_Nonconstructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs, - /* icon */ ICON_MOD_DECIM, + /*name*/ N_("Decimate"), + /*structName*/ "DecimateModifierData", + /*structSize*/ sizeof(DecimateModifierData), + /*srna*/ &RNA_DecimateModifier, + /*type*/ eModifierTypeType_Nonconstructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs, + /*icon*/ ICON_MOD_DECIM, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_displace.cc b/source/blender/modifiers/intern/MOD_displace.cc index 304c4be3e02..acbb64dfc55 100644 --- a/source/blender/modifiers/intern/MOD_displace.cc +++ b/source/blender/modifiers/intern/MOD_displace.cc @@ -467,34 +467,34 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Displace = { - /* name */ N_("Displace"), - /* structName */ "DisplaceModifierData", - /* structSize */ sizeof(DisplaceModifierData), - /* srna */ &RNA_DisplaceModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_DISPLACE, + /*name*/ N_("Displace"), + /*structName*/ "DisplaceModifierData", + /*structSize*/ sizeof(DisplaceModifierData), + /*srna*/ &RNA_DisplaceModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, + /*icon*/ ICON_MOD_DISPLACE, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ deformVerts, - /* deformMatrices */ nullptr, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ nullptr, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ nullptr, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ nullptr, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ dependsOnNormals, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ foreachTexLink, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ nullptr, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ dependsOnNormals, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ foreachTexLink, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c index 2f6d0da1fde..fd407883323 100644 --- a/source/blender/modifiers/intern/MOD_dynamicpaint.c +++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c @@ -187,36 +187,36 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_DynamicPaint = { - /* name */ N_("Dynamic Paint"), - /* structName */ "DynamicPaintModifierData", - /* structSize */ sizeof(DynamicPaintModifierData), - /* srna */ &RNA_DynamicPaintModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("Dynamic Paint"), + /*structName*/ "DynamicPaintModifierData", + /*structSize*/ sizeof(DynamicPaintModifierData), + /*srna*/ &RNA_DynamicPaintModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_UsesPointCache | eModifierTypeFlag_Single | eModifierTypeFlag_UsesPreview, - /* icon */ ICON_MOD_DYNAMICPAINT, + /*icon*/ ICON_MOD_DYNAMICPAINT, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ foreachTexLink, - /* freeRuntimeData */ freeRuntimeData, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ foreachTexLink, + /*freeRuntimeData*/ freeRuntimeData, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index b381ff32aa2..7db6c5e172d 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -154,36 +154,36 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_EdgeSplit = { - /* name */ N_("EdgeSplit"), - /* structName */ "EdgeSplitModifierData", - /* structSize */ sizeof(EdgeSplitModifierData), - /* srna */ &RNA_EdgeSplitModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | + /*name*/ N_("EdgeSplit"), + /*structName*/ "EdgeSplitModifierData", + /*structSize*/ sizeof(EdgeSplitModifierData), + /*srna*/ &RNA_EdgeSplitModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* icon */ ICON_MOD_EDGESPLIT, + /*icon*/ ICON_MOD_EDGESPLIT, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ NULL, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ NULL, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 9dcbb1f16a0..ebce5bb105b 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -1218,33 +1218,33 @@ static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md) } ModifierTypeInfo modifierType_Explode = { - /* name */ N_("Explode"), - /* structName */ "ExplodeModifierData", - /* structSize */ sizeof(ExplodeModifierData), - /* srna */ &RNA_ExplodeModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh, - /* icon */ ICON_MOD_EXPLODE, - /* copyData */ copyData, + /*name*/ N_("Explode"), + /*structName*/ "ExplodeModifierData", + /*structSize*/ sizeof(ExplodeModifierData), + /*srna*/ &RNA_ExplodeModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh, + /*icon*/ ICON_MOD_EXPLODE, + /*copyData*/ copyData, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_fluid.c b/source/blender/modifiers/intern/MOD_fluid.c index 0a2b01fe101..5ac4c6b70da 100644 --- a/source/blender/modifiers/intern/MOD_fluid.c +++ b/source/blender/modifiers/intern/MOD_fluid.c @@ -239,34 +239,34 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Fluid = { - /* name */ N_("Fluid"), - /* structName */ "FluidModifierData", - /* structSize */ sizeof(FluidModifierData), - /* srna */ &RNA_FluidModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_Single, - /* icon */ ICON_MOD_FLUIDSIM, + /*name*/ N_("Fluid"), + /*structName*/ "FluidModifierData", + /*structSize*/ sizeof(FluidModifierData), + /*srna*/ &RNA_FluidModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_Single, + /*icon*/ ICON_MOD_FLUIDSIM, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index 231c65998e0..de9167088b2 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -542,34 +542,34 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) } ModifierTypeInfo modifierType_Hook = { - /* name */ N_("Hook"), - /* structName */ "HookModifierData", - /* structSize */ sizeof(HookModifierData), - /* srna */ &RNA_HookModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | + /*name*/ N_("Hook"), + /*structName*/ "HookModifierData", + /*structSize*/ sizeof(HookModifierData), + /*srna*/ &RNA_HookModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_HOOK, - /* copyData */ copyData, + /*icon*/ ICON_HOOK, + /*copyData*/ copyData, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ blendWrite, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ blendWrite, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c index b2b97bc0d08..aa8e7d541f0 100644 --- a/source/blender/modifiers/intern/MOD_laplaciandeform.c +++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c @@ -871,33 +871,33 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) } ModifierTypeInfo modifierType_LaplacianDeform = { - /* name */ N_("LaplacianDeform"), - /* structName */ "LaplacianDeformModifierData", - /* structSize */ sizeof(LaplacianDeformModifierData), - /* srna */ &RNA_LaplacianDeformModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_MESHDEFORM, - /* copyData */ copyData, + /*name*/ N_("LaplacianDeform"), + /*structName*/ "LaplacianDeformModifierData", + /*structSize*/ sizeof(LaplacianDeformModifierData), + /*srna*/ &RNA_LaplacianDeformModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, + /*icon*/ ICON_MOD_MESHDEFORM, + /*copyData*/ copyData, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ blendWrite, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ blendWrite, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c index 1534708ac72..77e0fadf75e 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c @@ -604,34 +604,34 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_LaplacianSmooth = { - /* name */ N_("LaplacianSmooth"), - /* structName */ "LaplacianSmoothModifierData", - /* structSize */ sizeof(LaplacianSmoothModifierData), - /* srna */ &RNA_LaplacianSmoothModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_SMOOTH, + /*name*/ N_("LaplacianSmooth"), + /*structName*/ "LaplacianSmoothModifierData", + /*structSize*/ sizeof(LaplacianSmoothModifierData), + /*srna*/ &RNA_LaplacianSmoothModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, + /*icon*/ ICON_MOD_SMOOTH, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ init_data, - /* requiredDataMask */ required_data_mask, - /* freeData */ NULL, - /* isDisabled */ is_disabled, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ init_data, + /*requiredDataMask*/ required_data_mask, + /*freeData*/ NULL, + /*isDisabled*/ is_disabled, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c index ede2d7b581e..e1b8957e2e7 100644 --- a/source/blender/modifiers/intern/MOD_lattice.c +++ b/source/blender/modifiers/intern/MOD_lattice.c @@ -158,35 +158,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Lattice = { - /* name */ N_("Lattice"), - /* structName */ "LatticeModifierData", - /* structSize */ sizeof(LatticeModifierData), - /* srna */ &RNA_LatticeModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | + /*name*/ N_("Lattice"), + /*structName*/ "LatticeModifierData", + /*structSize*/ sizeof(LatticeModifierData), + /*srna*/ &RNA_LatticeModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_LATTICE, + /*icon*/ ICON_MOD_LATTICE, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc index 9349ddc4aaa..1269907971c 100644 --- a/source/blender/modifiers/intern/MOD_mask.cc +++ b/source/blender/modifiers/intern/MOD_mask.cc @@ -807,36 +807,36 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Mask = { - /* name */ N_("Mask"), - /* structName */ "MaskModifierData", - /* structSize */ sizeof(MaskModifierData), - /* srna */ &RNA_MaskModifier, - /* type */ eModifierTypeType_Nonconstructive, - /* flags */ + /*name*/ N_("Mask"), + /*structName*/ "MaskModifierData", + /*structSize*/ sizeof(MaskModifierData), + /*srna*/ &RNA_MaskModifier, + /*type*/ eModifierTypeType_Nonconstructive, + /*flags*/ (ModifierTypeFlag)(eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode), - /* icon */ ICON_MOD_MASK, + /*icon*/ ICON_MOD_MASK, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ nullptr, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ nullptr, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc index fa7f0690675..22a2b383683 100644 --- a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc +++ b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc @@ -204,34 +204,34 @@ static void modifyGeometrySet(ModifierData *md, } ModifierTypeInfo modifierType_MeshToVolume = { - /* name */ N_("Mesh to Volume"), - /* structName */ "MeshToVolumeModifierData", - /* structSize */ sizeof(MeshToVolumeModifierData), - /* srna */ &RNA_MeshToVolumeModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ static_cast(0), - /* icon */ ICON_VOLUME_DATA, /* TODO: Use correct icon. */ + /*name*/ N_("Mesh to Volume"), + /*structName*/ "MeshToVolumeModifierData", + /*structSize*/ sizeof(MeshToVolumeModifierData), + /*srna*/ &RNA_MeshToVolumeModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ static_cast(0), + /*icon*/ ICON_VOLUME_DATA, /* TODO: Use correct icon. */ - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ nullptr, - /* modifyGeometrySet */ modifyGeometrySet, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ nullptr, + /*modifyGeometrySet*/ modifyGeometrySet, - /* initData */ initData, - /* requiredDataMask */ nullptr, - /* freeData */ nullptr, - /* isDisabled */ nullptr, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ nullptr, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c index b7cb97bec1d..da1e2c9e703 100644 --- a/source/blender/modifiers/intern/MOD_meshcache.c +++ b/source/blender/modifiers/intern/MOD_meshcache.c @@ -402,35 +402,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_MeshCache = { - /* name */ N_("MeshCache"), - /* structName */ "MeshCacheModifierData", - /* structSize */ sizeof(MeshCacheModifierData), - /* srna */ &RNA_MeshCacheModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | + /*name*/ N_("MeshCache"), + /*structName*/ "MeshCacheModifierData", + /*structSize*/ sizeof(MeshCacheModifierData), + /*srna*/ &RNA_MeshCacheModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_MESHDEFORM, /* TODO: Use correct icon. */ + /*icon*/ ICON_MOD_MESHDEFORM, /* TODO: Use correct icon. */ - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ NULL, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ NULL, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index 2aaaee2ccc7..3cbcf9845de 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -646,35 +646,35 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) } ModifierTypeInfo modifierType_MeshDeform = { - /* name */ N_("MeshDeform"), - /* structName */ "MeshDeformModifierData", - /* structSize */ sizeof(MeshDeformModifierData), - /* srna */ &RNA_MeshDeformModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | + /*name*/ N_("MeshDeform"), + /*structName*/ "MeshDeformModifierData", + /*structSize*/ sizeof(MeshDeformModifierData), + /*srna*/ &RNA_MeshDeformModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_MESHDEFORM, + /*icon*/ ICON_MOD_MESHDEFORM, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ blendWrite, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ blendWrite, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.cc b/source/blender/modifiers/intern/MOD_meshsequencecache.cc index 15fa7645430..c8628a7693e 100644 --- a/source/blender/modifiers/intern/MOD_meshsequencecache.cc +++ b/source/blender/modifiers/intern/MOD_meshsequencecache.cc @@ -422,35 +422,35 @@ static void blendRead(BlendDataReader * /*reader*/, ModifierData *md) } ModifierTypeInfo modifierType_MeshSequenceCache = { - /* name */ N_("MeshSequenceCache"), - /* structName */ "MeshSeqCacheModifierData", - /* structSize */ sizeof(MeshSeqCacheModifierData), - /* srna */ &RNA_MeshSequenceCacheModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ + /*name*/ N_("MeshSequenceCache"), + /*structName*/ "MeshSeqCacheModifierData", + /*structSize*/ sizeof(MeshSeqCacheModifierData), + /*srna*/ &RNA_MeshSequenceCacheModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ static_cast(eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs), - /* icon */ ICON_MOD_MESHDEFORM, /* TODO: Use correct icon. */ + /*icon*/ ICON_MOD_MESHDEFORM, /* TODO: Use correct icon. */ - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ nullptr, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ nullptr, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_mirror.cc b/source/blender/modifiers/intern/MOD_mirror.cc index ca65afb7176..b971f98ad95 100644 --- a/source/blender/modifiers/intern/MOD_mirror.cc +++ b/source/blender/modifiers/intern/MOD_mirror.cc @@ -196,38 +196,38 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Mirror = { - /* name */ N_("Mirror"), - /* structName */ "MirrorModifierData", - /* structSize */ sizeof(MirrorModifierData), - /* srna */ &RNA_MirrorModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("Mirror"), + /*structName*/ "MirrorModifierData", + /*structSize*/ sizeof(MirrorModifierData), + /*srna*/ &RNA_MirrorModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_AcceptsCVs | /* this is only the case when 'MOD_MIR_VGROUP' is used */ eModifierTypeFlag_UsesPreview, - /* icon */ ICON_MOD_MIRROR, + /*icon*/ ICON_MOD_MIRROR, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ nullptr, - /* freeData */ nullptr, - /* isDisabled */ nullptr, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ nullptr, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_multires.cc b/source/blender/modifiers/intern/MOD_multires.cc index 737999e6b88..c65774fd5ff 100644 --- a/source/blender/modifiers/intern/MOD_multires.cc +++ b/source/blender/modifiers/intern/MOD_multires.cc @@ -487,35 +487,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Multires = { - /* name */ N_("Multires"), - /* structName */ "MultiresModifierData", - /* structSize */ sizeof(MultiresModifierData), - /* srna */ &RNA_MultiresModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("Multires"), + /*structName*/ "MultiresModifierData", + /*structSize*/ sizeof(MultiresModifierData), + /*srna*/ &RNA_MultiresModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_RequiresOriginalData, - /* icon */ ICON_MOD_MULTIRES, + /*icon*/ ICON_MOD_MULTIRES, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ nullptr, - /* deformMatrices */ deformMatrices, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ deformMatrices, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ nullptr, - /* updateDepsgraph */ nullptr, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ dependsOnNormals, - /* foreachIDLink */ nullptr, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ freeRuntimeData, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ nullptr, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ dependsOnNormals, + /*foreachIDLink*/ nullptr, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ freeRuntimeData, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index d9198ba9025..1261cf56b26 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1907,38 +1907,38 @@ static void requiredDataMask(ModifierData * /*md*/, CustomData_MeshMasks *r_cdda } ModifierTypeInfo modifierType_Nodes = { - /* name */ N_("GeometryNodes"), - /* structName */ "NodesModifierData", - /* structSize */ sizeof(NodesModifierData), - /* srna */ &RNA_NodesModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ + /*name*/ N_("GeometryNodes"), + /*structName*/ "NodesModifierData", + /*structSize*/ sizeof(NodesModifierData), + /*srna*/ &RNA_NodesModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ static_cast(eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_SupportsMapping), - /* icon */ ICON_GEOMETRY_NODES, + /*icon*/ ICON_GEOMETRY_NODES, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ modifyGeometrySet, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ modifyGeometrySet, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ foreachTexLink, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ blendWrite, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ foreachTexLink, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ blendWrite, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_none.c b/source/blender/modifiers/intern/MOD_none.c index 7e1a1b84d01..1cadeadda98 100644 --- a/source/blender/modifiers/intern/MOD_none.c +++ b/source/blender/modifiers/intern/MOD_none.c @@ -28,34 +28,34 @@ static bool isDisabled(const struct Scene *UNUSED(scene), } ModifierTypeInfo modifierType_None = { - /* name */ "None", - /* structName */ "ModifierData", - /* structSize */ sizeof(ModifierData), - /* srna */ &RNA_Modifier, - /* type */ eModifierTypeType_None, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs, - /* icon */ ICON_NONE, + /*name*/ "None", + /*structName*/ "ModifierData", + /*structSize*/ sizeof(ModifierData), + /*srna*/ &RNA_Modifier, + /*type*/ eModifierTypeType_None, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs, + /*icon*/ ICON_NONE, - /* copyData */ NULL, + /*copyData*/ NULL, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ NULL, - /* requiredDataMask */ NULL, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ NULL, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ NULL, + /*requiredDataMask*/ NULL, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ NULL, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_normal_edit.cc b/source/blender/modifiers/intern/MOD_normal_edit.cc index 0bf1a268577..d6089372da6 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.cc +++ b/source/blender/modifiers/intern/MOD_normal_edit.cc @@ -786,35 +786,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_NormalEdit = { - /* name */ N_("NormalEdit"), - /* structName */ "NormalEditModifierData", - /* structSize */ sizeof(NormalEditModifierData), - /* srna */ &RNA_NormalEditModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("NormalEdit"), + /*structName*/ "NormalEditModifierData", + /*structSize*/ sizeof(NormalEditModifierData), + /*srna*/ &RNA_NormalEditModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* icon */ ICON_MOD_NORMALEDIT, + /*icon*/ ICON_MOD_NORMALEDIT, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ nullptr, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ dependsOnNormals, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ nullptr, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ dependsOnNormals, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 4aa896707dd..64a2efc5459 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -698,35 +698,35 @@ static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md) } ModifierTypeInfo modifierType_Ocean = { - /* name */ N_("Ocean"), - /* structName */ "OceanModifierData", - /* structSize */ sizeof(OceanModifierData), - /* srna */ &RNA_OceanModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | + /*name*/ N_("Ocean"), + /*structName*/ "OceanModifierData", + /*structSize*/ sizeof(OceanModifierData), + /*srna*/ &RNA_OceanModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* icon */ ICON_MOD_OCEAN, + /*icon*/ ICON_MOD_OCEAN, - /* copyData */ copyData, - /* deformMatrices_DM */ NULL, + /*copyData*/ copyData, + /*deformMatrices_DM*/ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ dependsOnNormals, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ dependsOnNormals, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index e3682acf84a..7b9c5d3e657 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -633,35 +633,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_ParticleInstance = { - /* name */ N_("ParticleInstance"), - /* structName */ "ParticleInstanceModifierData", - /* structSize */ sizeof(ParticleInstanceModifierData), - /* srna */ &RNA_ParticleInstanceModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("ParticleInstance"), + /*structName*/ "ParticleInstanceModifierData", + /*structSize*/ sizeof(ParticleInstanceModifierData), + /*srna*/ &RNA_ParticleInstanceModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* icon */ ICON_MOD_PARTICLE_INSTANCE, + /*icon*/ ICON_MOD_PARTICLE_INSTANCE, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_particlesystem.cc b/source/blender/modifiers/intern/MOD_particlesystem.cc index 66291520176..bf19553378f 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.cc +++ b/source/blender/modifiers/intern/MOD_particlesystem.cc @@ -298,39 +298,39 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) } ModifierTypeInfo modifierType_ParticleSystem = { - /* name */ N_("ParticleSystem"), - /* structName */ "ParticleSystemModifierData", - /* structSize */ sizeof(ParticleSystemModifierData), - /* srna */ &RNA_ParticleSystemModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("ParticleSystem"), + /*structName*/ "ParticleSystemModifierData", + /*structSize*/ sizeof(ParticleSystemModifierData), + /*srna*/ &RNA_ParticleSystemModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_UsesPointCache #if 0 | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode #endif , - /* icon */ ICON_MOD_PARTICLES, + /*icon*/ ICON_MOD_PARTICLES, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ deformVerts, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ nullptr, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ nullptr, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ nullptr, - /* updateDepsgraph */ nullptr, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ nullptr, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ nullptr, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ nullptr, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c index 220b9e87aff..2a322571dbe 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.c @@ -272,35 +272,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Remesh = { - /* name */ N_("Remesh"), - /* structName */ "RemeshModifierData", - /* structSize */ sizeof(RemeshModifierData), - /* srna */ &RNA_RemeshModifier, - /* type */ eModifierTypeType_Nonconstructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | + /*name*/ N_("Remesh"), + /*structName*/ "RemeshModifierData", + /*structSize*/ sizeof(RemeshModifierData), + /*srna*/ &RNA_RemeshModifier, + /*type*/ eModifierTypeType_Nonconstructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_REMESH, + /*icon*/ ICON_MOD_REMESH, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ NULL, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ NULL, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_screw.cc b/source/blender/modifiers/intern/MOD_screw.cc index 0f094f06bd0..0b3514dcadd 100644 --- a/source/blender/modifiers/intern/MOD_screw.cc +++ b/source/blender/modifiers/intern/MOD_screw.cc @@ -1104,36 +1104,36 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Screw = { - /* name */ N_("Screw"), - /* structName */ "ScrewModifierData", - /* structSize */ sizeof(ScrewModifierData), - /* srna */ &RNA_ScrewModifier, - /* type */ eModifierTypeType_Constructive, + /*name*/ N_("Screw"), + /*structName*/ "ScrewModifierData", + /*structSize*/ sizeof(ScrewModifierData), + /*srna*/ &RNA_ScrewModifier, + /*type*/ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* icon */ ICON_MOD_SCREW, + /*icon*/ ICON_MOD_SCREW, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ nullptr, - /* freeData */ nullptr, - /* isDisabled */ nullptr, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ nullptr, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c index 3649a108ed4..c4993575afe 100644 --- a/source/blender/modifiers/intern/MOD_shapekey.c +++ b/source/blender/modifiers/intern/MOD_shapekey.c @@ -109,35 +109,35 @@ static void deformMatricesEM(ModifierData *UNUSED(md), } ModifierTypeInfo modifierType_ShapeKey = { - /* name */ N_("ShapeKey"), - /* structName */ "ShapeKeyModifierData", - /* structSize */ sizeof(ShapeKeyModifierData), - /* srna */ &RNA_Modifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | + /*name*/ N_("ShapeKey"), + /*structName*/ "ShapeKeyModifierData", + /*structSize*/ sizeof(ShapeKeyModifierData), + /*srna*/ &RNA_Modifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_DOT, + /*icon*/ ICON_DOT, - /* copyData */ NULL, + /*copyData*/ NULL, - /* deformVerts */ deformVerts, - /* deformMatrices */ deformMatrices, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ deformMatricesEM, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ deformMatrices, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ deformMatricesEM, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ NULL, - /* requiredDataMask */ NULL, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ NULL, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ NULL, + /*requiredDataMask*/ NULL, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ NULL, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index b5e66a1af79..8f63be85507 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -251,36 +251,36 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Shrinkwrap = { - /* name */ N_("Shrinkwrap"), - /* structName */ "ShrinkwrapModifierData", - /* structSize */ sizeof(ShrinkwrapModifierData), - /* srna */ &RNA_ShrinkwrapModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | + /*name*/ N_("Shrinkwrap"), + /*structName*/ "ShrinkwrapModifierData", + /*structSize*/ sizeof(ShrinkwrapModifierData), + /*srna*/ &RNA_ShrinkwrapModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* icon */ ICON_MOD_SHRINKWRAP, + /*icon*/ ICON_MOD_SHRINKWRAP, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ dependsOnNormals, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ dependsOnNormals, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index c08853d06a7..296cc2a4d44 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -559,37 +559,37 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_SimpleDeform = { - /* name */ N_("SimpleDeform"), - /* structName */ "SimpleDeformModifierData", - /* structSize */ sizeof(SimpleDeformModifierData), - /* srna */ &RNA_SimpleDeformModifier, - /* type */ eModifierTypeType_OnlyDeform, + /*name*/ N_("SimpleDeform"), + /*structName*/ "SimpleDeformModifierData", + /*structSize*/ sizeof(SimpleDeformModifierData), + /*srna*/ &RNA_SimpleDeformModifier, + /*type*/ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* icon */ ICON_MOD_SIMPLEDEFORM, + /*icon*/ ICON_MOD_SIMPLEDEFORM, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index efb8ae8616a..fa348dcb15e 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -2076,34 +2076,34 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Skin = { - /* name */ N_("Skin"), - /* structName */ "SkinModifierData", - /* structSize */ sizeof(SkinModifierData), - /* srna */ &RNA_SkinModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_SKIN, + /*name*/ N_("Skin"), + /*structName*/ "SkinModifierData", + /*structSize*/ sizeof(SkinModifierData), + /*srna*/ &RNA_SkinModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, + /*icon*/ ICON_MOD_SKIN, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c index 72fc945675c..32cb29bcf52 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -251,35 +251,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Smooth = { - /* name */ N_("Smooth"), - /* structName */ "SmoothModifierData", - /* structSize */ sizeof(SmoothModifierData), - /* srna */ &RNA_SmoothModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | + /*name*/ N_("Smooth"), + /*structName*/ "SmoothModifierData", + /*structSize*/ sizeof(SmoothModifierData), + /*srna*/ &RNA_SmoothModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_SMOOTH, + /*icon*/ ICON_MOD_SMOOTH, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c index ecff6d80893..9437c51534d 100644 --- a/source/blender/modifiers/intern/MOD_softbody.c +++ b/source/blender/modifiers/intern/MOD_softbody.c @@ -86,36 +86,36 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Softbody = { - /* name */ N_("Softbody"), - /* structName */ "SoftbodyModifierData", - /* structSize */ sizeof(SoftbodyModifierData), - /* srna */ &RNA_SoftBodyModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | + /*name*/ N_("Softbody"), + /*structName*/ "SoftbodyModifierData", + /*structSize*/ sizeof(SoftbodyModifierData), + /*srna*/ &RNA_SoftBodyModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_RequiresOriginalData | eModifierTypeFlag_Single | eModifierTypeFlag_UsesPointCache, - /* icon */ ICON_MOD_SOFT, + /*icon*/ ICON_MOD_SOFT, - /* copyData */ NULL, + /*copyData*/ NULL, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ NULL, - /* requiredDataMask */ NULL, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ NULL, + /*requiredDataMask*/ NULL, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 1c1649a5ed8..b13f36ee47d 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -246,37 +246,37 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Solidify = { - /* name */ N_("Solidify"), - /* structName */ "SolidifyModifierData", - /* structSize */ sizeof(SolidifyModifierData), - /* srna */ &RNA_SolidifyModifier, - /* type */ eModifierTypeType_Constructive, + /*name*/ N_("Solidify"), + /*structName*/ "SolidifyModifierData", + /*structSize*/ sizeof(SolidifyModifierData), + /*srna*/ &RNA_SolidifyModifier, + /*type*/ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* icon */ ICON_MOD_SOLIDIFY, + /*icon*/ ICON_MOD_SOLIDIFY, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ dependsOnNormals, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ dependsOnNormals, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/modifiers/intern/MOD_subsurf.cc b/source/blender/modifiers/intern/MOD_subsurf.cc index 23989e7640c..75377f00bb3 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.cc +++ b/source/blender/modifiers/intern/MOD_subsurf.cc @@ -471,36 +471,36 @@ static void blendRead(BlendDataReader * /*reader*/, ModifierData *md) } ModifierTypeInfo modifierType_Subsurf = { - /* name */ N_("Subdivision"), - /* structName */ "SubsurfModifierData", - /* structSize */ sizeof(SubsurfModifierData), - /* srna */ &RNA_SubsurfModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("Subdivision"), + /*structName*/ "SubsurfModifierData", + /*structSize*/ sizeof(SubsurfModifierData), + /*srna*/ &RNA_SubsurfModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_AcceptsCVs, - /* icon */ ICON_MOD_SUBSURF, + /*icon*/ ICON_MOD_SUBSURF, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ nullptr, - /* deformMatrices */ deformMatrices, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ deformMatrices, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ nullptr, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ dependsOnNormals, - /* foreachIDLink */ nullptr, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ freeRuntimeData, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ nullptr, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ dependsOnNormals, + /*foreachIDLink*/ nullptr, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ freeRuntimeData, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c index 00fe739b49c..b48bd20e821 100644 --- a/source/blender/modifiers/intern/MOD_surface.c +++ b/source/blender/modifiers/intern/MOD_surface.c @@ -204,35 +204,35 @@ static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md) } ModifierTypeInfo modifierType_Surface = { - /* name */ N_("Surface"), - /* structName */ "SurfaceModifierData", - /* structSize */ sizeof(SurfaceModifierData), - /* srna */ &RNA_SurfaceModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | + /*name*/ N_("Surface"), + /*structName*/ "SurfaceModifierData", + /*structSize*/ sizeof(SurfaceModifierData), + /*srna*/ &RNA_SurfaceModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_NoUserAdd, - /* icon */ ICON_MOD_PHYSICS, + /*icon*/ ICON_MOD_PHYSICS, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ NULL, - /* freeData */ freeData, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ NULL, + /*freeData*/ freeData, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index 000d44abd99..c43bf19a580 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -1743,34 +1743,34 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) } ModifierTypeInfo modifierType_SurfaceDeform = { - /* name */ N_("SurfaceDeform"), - /* structName */ "SurfaceDeformModifierData", - /* structSize */ sizeof(SurfaceDeformModifierData), - /* srna */ &RNA_SurfaceDeformModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_MESHDEFORM, + /*name*/ N_("SurfaceDeform"), + /*structName*/ "SurfaceDeformModifierData", + /*structSize*/ sizeof(SurfaceDeformModifierData), + /*srna*/ &RNA_SurfaceDeformModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, + /*icon*/ ICON_MOD_MESHDEFORM, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ blendWrite, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ blendWrite, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_triangulate.cc b/source/blender/modifiers/intern/MOD_triangulate.cc index 3880bd8a233..adcf76a949d 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.cc +++ b/source/blender/modifiers/intern/MOD_triangulate.cc @@ -143,36 +143,36 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Triangulate = { - /* name */ N_("Triangulate"), - /* structName */ "TriangulateModifierData", - /* structSize */ sizeof(TriangulateModifierData), - /* srna */ &RNA_TriangulateModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | + /*name*/ N_("Triangulate"), + /*structName*/ "TriangulateModifierData", + /*structSize*/ sizeof(TriangulateModifierData), + /*srna*/ &RNA_TriangulateModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_AcceptsCVs, - /* icon */ ICON_MOD_TRIANGULATE, + /*icon*/ ICON_MOD_TRIANGULATE, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ nullptr, // requiredDataMask, - /* freeData */ nullptr, - /* isDisabled */ nullptr, - /* updateDepsgraph */ nullptr, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ nullptr, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ nullptr, // requiredDataMask, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ nullptr, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ nullptr, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_uvproject.cc b/source/blender/modifiers/intern/MOD_uvproject.cc index 1d660a05c44..9491a6bfb6e 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.cc +++ b/source/blender/modifiers/intern/MOD_uvproject.cc @@ -346,35 +346,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_UVProject = { - /* name */ N_("UVProject"), - /* structName */ "UVProjectModifierData", - /* structSize */ sizeof(UVProjectModifierData), - /* srna */ &RNA_UVProjectModifier, - /* type */ eModifierTypeType_NonGeometrical, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("UVProject"), + /*structName*/ "UVProjectModifierData", + /*structSize*/ sizeof(UVProjectModifierData), + /*srna*/ &RNA_UVProjectModifier, + /*type*/ eModifierTypeType_NonGeometrical, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* icon */ ICON_MOD_UVPROJECT, + /*icon*/ ICON_MOD_UVPROJECT, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ nullptr, - /* isDisabled */ nullptr, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_uvwarp.cc b/source/blender/modifiers/intern/MOD_uvwarp.cc index 2c11b002fc5..5b4f3275d58 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.cc +++ b/source/blender/modifiers/intern/MOD_uvwarp.cc @@ -303,35 +303,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_UVWarp = { - /* name */ N_("UVWarp"), - /* structName */ "UVWarpModifierData", - /* structSize */ sizeof(UVWarpModifierData), - /* srna */ &RNA_UVWarpModifier, - /* type */ eModifierTypeType_NonGeometrical, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | + /*name*/ N_("UVWarp"), + /*structName*/ "UVWarpModifierData", + /*structSize*/ sizeof(UVWarpModifierData), + /*srna*/ &RNA_UVWarpModifier, + /*type*/ eModifierTypeType_NonGeometrical, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* icon */ ICON_MOD_UVPROJECT, /* TODO: Use correct icon. */ + /*icon*/ ICON_MOD_UVPROJECT, /* TODO: Use correct icon. */ - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ nullptr, - /* isDisabled */ nullptr, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_volume_displace.cc b/source/blender/modifiers/intern/MOD_volume_displace.cc index 2d6f8c100e7..33ef740977e 100644 --- a/source/blender/modifiers/intern/MOD_volume_displace.cc +++ b/source/blender/modifiers/intern/MOD_volume_displace.cc @@ -310,34 +310,34 @@ static void modifyGeometrySet(ModifierData *md, } ModifierTypeInfo modifierType_VolumeDisplace = { - /* name */ N_("Volume Displace"), - /* structName */ "VolumeDisplaceModifierData", - /* structSize */ sizeof(VolumeDisplaceModifierData), - /* srna */ &RNA_VolumeDisplaceModifier, - /* type */ eModifierTypeType_NonGeometrical, - /* flags */ static_cast(0), - /* icon */ ICON_VOLUME_DATA, /* TODO: Use correct icon. */ + /*name*/ N_("Volume Displace"), + /*structName*/ "VolumeDisplaceModifierData", + /*structSize*/ sizeof(VolumeDisplaceModifierData), + /*srna*/ &RNA_VolumeDisplaceModifier, + /*type*/ eModifierTypeType_NonGeometrical, + /*flags*/ static_cast(0), + /*icon*/ ICON_VOLUME_DATA, /* TODO: Use correct icon. */ - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ nullptr, - /* modifyGeometrySet */ modifyGeometrySet, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ nullptr, + /*modifyGeometrySet*/ modifyGeometrySet, - /* initData */ initData, - /* requiredDataMask */ nullptr, - /* freeData */ nullptr, - /* isDisabled */ nullptr, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ foreachTexLink, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ nullptr, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ foreachTexLink, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc index 2a8883dc2eb..cefeb6509db 100644 --- a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc +++ b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc @@ -195,34 +195,34 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } ModifierTypeInfo modifierType_VolumeToMesh = { - /* name */ N_("Volume to Mesh"), - /* structName */ "VolumeToMeshModifierData", - /* structSize */ sizeof(VolumeToMeshModifierData), - /* srna */ &RNA_VolumeToMeshModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh, - /* icon */ ICON_VOLUME_DATA, /* TODO: Use correct icon. */ + /*name*/ N_("Volume to Mesh"), + /*structName*/ "VolumeToMeshModifierData", + /*structSize*/ sizeof(VolumeToMeshModifierData), + /*srna*/ &RNA_VolumeToMeshModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh, + /*icon*/ ICON_VOLUME_DATA, /* TODO: Use correct icon. */ - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ nullptr, - /* freeData */ nullptr, - /* isDisabled */ nullptr, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ nullptr, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index 791eed28a71..2dfdd842a0c 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -508,34 +508,34 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) } ModifierTypeInfo modifierType_Warp = { - /* name */ N_("Warp"), - /* structName */ "WarpModifierData", - /* structSize */ sizeof(WarpModifierData), - /* srna */ &RNA_WarpModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | + /*name*/ N_("Warp"), + /*structName*/ "WarpModifierData", + /*structSize*/ sizeof(WarpModifierData), + /*srna*/ &RNA_WarpModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_WARP, - /* copyData */ copyData, + /*icon*/ ICON_MOD_WARP, + /*copyData*/ copyData, - /* deformVerts */ deformVerts, - /* deformMatrices */ NULL, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ NULL, - /* modifyMesh */ NULL, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ NULL, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ NULL, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ foreachTexLink, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ blendWrite, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ foreachTexLink, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ blendWrite, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_wave.cc b/source/blender/modifiers/intern/MOD_wave.cc index dce006bda92..2eaaa78aee8 100644 --- a/source/blender/modifiers/intern/MOD_wave.cc +++ b/source/blender/modifiers/intern/MOD_wave.cc @@ -464,35 +464,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Wave = { - /* name */ N_("Wave"), - /* structName */ "WaveModifierData", - /* structSize */ sizeof(WaveModifierData), - /* srna */ &RNA_WaveModifier, - /* type */ eModifierTypeType_OnlyDeform, - /* flags */ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | + /*name*/ N_("Wave"), + /*structName*/ "WaveModifierData", + /*structSize*/ sizeof(WaveModifierData), + /*srna*/ &RNA_WaveModifier, + /*type*/ eModifierTypeType_OnlyDeform, + /*flags*/ eModifierTypeFlag_AcceptsCVs | eModifierTypeFlag_AcceptsVertexCosOnly | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_WAVE, + /*icon*/ ICON_MOD_WAVE, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ deformVerts, - /* deformMatrices */ nullptr, - /* deformVertsEM */ deformVertsEM, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ nullptr, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ deformVerts, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ deformVertsEM, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ nullptr, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ nullptr, - /* isDisabled */ nullptr, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ dependsOnNormals, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ foreachTexLink, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ dependsOnNormals, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ foreachTexLink, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.cc b/source/blender/modifiers/intern/MOD_weighted_normal.cc index f8f84fcd735..cbf385d20a7 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.cc +++ b/source/blender/modifiers/intern/MOD_weighted_normal.cc @@ -745,35 +745,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_WeightedNormal = { - /* name */ N_("WeightedNormal"), - /* structName */ "WeightedNormalModifierData", - /* structSize */ sizeof(WeightedNormalModifierData), - /* srna */ &RNA_WeightedNormalModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("WeightedNormal"), + /*structName*/ "WeightedNormalModifierData", + /*structSize*/ sizeof(WeightedNormalModifierData), + /*srna*/ &RNA_WeightedNormalModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode, - /* icon */ ICON_MOD_NORMALEDIT, + /*icon*/ ICON_MOD_NORMALEDIT, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ nullptr, - /* isDisabled */ nullptr, - /* updateDepsgraph */ nullptr, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ dependsOnNormals, - /* foreachIDLink */ nullptr, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ nullptr, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ dependsOnNormals, + /*foreachIDLink*/ nullptr, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.cc b/source/blender/modifiers/intern/MOD_weightvgedit.cc index e4fbca633f7..e8a2795aa79 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.cc +++ b/source/blender/modifiers/intern/MOD_weightvgedit.cc @@ -388,35 +388,35 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) } ModifierTypeInfo modifierType_WeightVGEdit = { - /* name */ N_("VertexWeightEdit"), - /* structName */ "WeightVGEditModifierData", - /* structSize */ sizeof(WeightVGEditModifierData), - /* srna */ &RNA_VertexWeightEditModifier, - /* type */ eModifierTypeType_NonGeometrical, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("VertexWeightEdit"), + /*structName*/ "WeightVGEditModifierData", + /*structSize*/ sizeof(WeightVGEditModifierData), + /*srna*/ &RNA_VertexWeightEditModifier, + /*type*/ eModifierTypeType_NonGeometrical, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview, - /* icon */ ICON_MOD_VERTEX_WEIGHT, + /*icon*/ ICON_MOD_VERTEX_WEIGHT, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ foreachTexLink, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ blendWrite, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ foreachTexLink, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ blendWrite, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.cc b/source/blender/modifiers/intern/MOD_weightvgmix.cc index d860e93d535..c766d117db8 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.cc +++ b/source/blender/modifiers/intern/MOD_weightvgmix.cc @@ -490,35 +490,35 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_WeightVGMix = { - /* name */ N_("VertexWeightMix"), - /* structName */ "WeightVGMixModifierData", - /* structSize */ sizeof(WeightVGMixModifierData), - /* srna */ &RNA_VertexWeightMixModifier, - /* type */ eModifierTypeType_NonGeometrical, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("VertexWeightMix"), + /*structName*/ "WeightVGMixModifierData", + /*structSize*/ sizeof(WeightVGMixModifierData), + /*srna*/ &RNA_VertexWeightMixModifier, + /*type*/ eModifierTypeType_NonGeometrical, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview, - /* icon */ ICON_MOD_VERTEX_WEIGHT, + /*icon*/ ICON_MOD_VERTEX_WEIGHT, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ nullptr, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ foreachTexLink, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ nullptr, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ foreachTexLink, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.cc b/source/blender/modifiers/intern/MOD_weightvgproximity.cc index e4e03a2cbc9..917311f68d1 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.cc +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.cc @@ -736,35 +736,35 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) } ModifierTypeInfo modifierType_WeightVGProximity = { - /* name */ N_("VertexWeightProximity"), - /* structName */ "WeightVGProximityModifierData", - /* structSize */ sizeof(WeightVGProximityModifierData), - /* srna */ &RNA_VertexWeightProximityModifier, - /* type */ eModifierTypeType_NonGeometrical, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | + /*name*/ N_("VertexWeightProximity"), + /*structName*/ "WeightVGProximityModifierData", + /*structSize*/ sizeof(WeightVGProximityModifierData), + /*srna*/ &RNA_VertexWeightProximityModifier, + /*type*/ eModifierTypeType_NonGeometrical, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_UsesPreview, - /* icon */ ICON_MOD_VERTEX_WEIGHT, + /*icon*/ ICON_MOD_VERTEX_WEIGHT, - /* copyData */ copyData, + /*copyData*/ copyData, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ freeData, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ dependsOnTime, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ foreachIDLink, - /* foreachTexLink */ foreachTexLink, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ blendWrite, - /* blendRead */ blendRead, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ freeData, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ dependsOnTime, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ foreachIDLink, + /*foreachTexLink*/ foreachTexLink, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ blendWrite, + /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_weld.cc b/source/blender/modifiers/intern/MOD_weld.cc index dc9d361c838..7460110c5ae 100644 --- a/source/blender/modifiers/intern/MOD_weld.cc +++ b/source/blender/modifiers/intern/MOD_weld.cc @@ -179,37 +179,37 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Weld = { - /* name */ N_("Weld"), - /* structName */ "WeldModifierData", - /* structSize */ sizeof(WeldModifierData), - /* srna */ &RNA_WeldModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ + /*name*/ N_("Weld"), + /*structName*/ "WeldModifierData", + /*structSize*/ sizeof(WeldModifierData), + /*srna*/ &RNA_WeldModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ (ModifierTypeFlag)(eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode | eModifierTypeFlag_AcceptsCVs), - /* icon */ ICON_AUTOMERGE_OFF, /* TODO: Use correct icon. */ + /*icon*/ ICON_AUTOMERGE_OFF, /* TODO: Use correct icon. */ - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ nullptr, - /* deformMatrices */ nullptr, - /* deformVertsEM */ nullptr, - /* deformMatricesEM */ nullptr, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ nullptr, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ nullptr, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ nullptr, - /* isDisabled */ nullptr, - /* updateDepsgraph */ nullptr, - /* dependsOnTime */ nullptr, - /* dependsOnNormals */ nullptr, - /* foreachIDLink */ nullptr, - /* foreachTexLink */ nullptr, - /* freeRuntimeData */ nullptr, - /* panelRegister */ panelRegister, - /* blendWrite */ nullptr, - /* blendRead */ nullptr, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ nullptr, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ nullptr, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, + /*panelRegister*/ panelRegister, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c index 85696bed162..8339e1cea76 100644 --- a/source/blender/modifiers/intern/MOD_wireframe.c +++ b/source/blender/modifiers/intern/MOD_wireframe.c @@ -163,34 +163,34 @@ static void panelRegister(ARegionType *region_type) } ModifierTypeInfo modifierType_Wireframe = { - /* name */ N_("Wireframe"), - /* structName */ "WireframeModifierData", - /* structSize */ sizeof(WireframeModifierData), - /* srna */ &RNA_WireframeModifier, - /* type */ eModifierTypeType_Constructive, - /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, - /* icon */ ICON_MOD_WIREFRAME, + /*name*/ N_("Wireframe"), + /*structName*/ "WireframeModifierData", + /*structSize*/ sizeof(WireframeModifierData), + /*srna*/ &RNA_WireframeModifier, + /*type*/ eModifierTypeType_Constructive, + /*flags*/ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsEditmode, + /*icon*/ ICON_MOD_WIREFRAME, - /* copyData */ BKE_modifier_copydata_generic, + /*copyData*/ BKE_modifier_copydata_generic, - /* deformVerts */ NULL, - /* deformMatrices */ NULL, - /* deformVertsEM */ NULL, - /* deformMatricesEM */ NULL, - /* modifyMesh */ modifyMesh, - /* modifyGeometrySet */ NULL, + /*deformVerts*/ NULL, + /*deformMatrices*/ NULL, + /*deformVertsEM*/ NULL, + /*deformMatricesEM*/ NULL, + /*modifyMesh*/ modifyMesh, + /*modifyGeometrySet*/ NULL, - /* initData */ initData, - /* requiredDataMask */ requiredDataMask, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepgraph */ NULL, - /* dependsOnTime */ NULL, - /* dependsOnNormals */ dependsOnNormals, - /* foreachIDLink */ NULL, - /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, - /* panelRegister */ panelRegister, - /* blendWrite */ NULL, - /* blendRead */ NULL, + /*initData*/ initData, + /*requiredDataMask*/ requiredDataMask, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*dependsOnNormals*/ dependsOnNormals, + /*foreachIDLink*/ NULL, + /*foreachTexLink*/ NULL, + /*freeRuntimeData*/ NULL, + /*panelRegister*/ panelRegister, + /*blendWrite*/ NULL, + /*blendRead*/ NULL, }; diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index c61cab5aa6f..1e338ca03b3 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -3378,7 +3378,7 @@ static PySequenceMethods pyrna_prop_array_as_sequence = { /*sq_item*/ (ssizeargfunc)pyrna_prop_array_subscript_int, /*sq_slice*/ NULL, /*sq_ass_item*/ (ssizeobjargproc)prop_subscript_ass_array_int, - /* was_sq_ass_slice */ NULL, /* DEPRECATED. */ + /*was_sq_ass_slice*/ NULL, /* DEPRECATED. */ /*sq_contains*/ (objobjproc)pyrna_prop_array_contains, /*sq_inplace_concat*/ NULL, /*sq_inplace_repeat*/ NULL, diff --git a/source/blender/sequencer/intern/modifier.c b/source/blender/sequencer/intern/modifier.c index a962bcdbd06..150b72e8e87 100644 --- a/source/blender/sequencer/intern/modifier.c +++ b/source/blender/sequencer/intern/modifier.c @@ -626,13 +626,13 @@ static void colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *ma } static SequenceModifierTypeInfo seqModifier_ColorBalance = { - CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Color Balance"), /* name */ - "ColorBalanceModifierData", /* struct_name */ - sizeof(ColorBalanceModifierData), /* struct_size */ - colorBalance_init_data, /* init_data */ - NULL, /* free_data */ - NULL, /* copy_data */ - colorBalance_apply, /* apply */ + /*name*/ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Color Balance"), + /*struct_name*/ "ColorBalanceModifierData", + /*struct_size*/ sizeof(ColorBalanceModifierData), + /*init_data*/ colorBalance_init_data, + /*free_data*/ NULL, + /*copy_data*/ NULL, + /*apply*/ colorBalance_apply, }; /** \} */ @@ -722,13 +722,13 @@ static void whiteBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *ma } static SequenceModifierTypeInfo seqModifier_WhiteBalance = { - CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "White Balance"), /* name */ - "WhiteBalanceModifierData", /* struct_name */ - sizeof(WhiteBalanceModifierData), /* struct_size */ - whiteBalance_init_data, /* init_data */ - NULL, /* free_data */ - NULL, /* copy_data */ - whiteBalance_apply, /* apply */ + /*name*/ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "White Balance"), + /*struct_name*/ "WhiteBalanceModifierData", + /*struct_size*/ sizeof(WhiteBalanceModifierData), + /*init_data*/ whiteBalance_init_data, + /*free_data*/ NULL, + /*copy_data*/ NULL, + /*apply*/ whiteBalance_apply, }; /** \} */ @@ -840,13 +840,13 @@ static void curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *m } static SequenceModifierTypeInfo seqModifier_Curves = { - CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Curves"), /* name */ - "CurvesModifierData", /* struct_name */ - sizeof(CurvesModifierData), /* struct_size */ - curves_init_data, /* init_data */ - curves_free_data, /* free_data */ - curves_copy_data, /* copy_data */ - curves_apply, /* apply */ + /*name*/ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Curves"), + /*struct_name*/ "CurvesModifierData", + /*struct_size*/ sizeof(CurvesModifierData), + /*init_data*/ curves_init_data, + /*free_data*/ curves_free_data, + /*copy_data*/ curves_copy_data, + /*apply*/ curves_apply, }; /** \} */ @@ -964,13 +964,13 @@ static void hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImB } static SequenceModifierTypeInfo seqModifier_HueCorrect = { - CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Hue Correct"), /* name */ - "HueCorrectModifierData", /* struct_name */ - sizeof(HueCorrectModifierData), /* struct_size */ - hue_correct_init_data, /* init_data */ - hue_correct_free_data, /* free_data */ - hue_correct_copy_data, /* copy_data */ - hue_correct_apply, /* apply */ + /*name*/ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Hue Correct"), + /*struct_name*/ "HueCorrectModifierData", + /*struct_size*/ sizeof(HueCorrectModifierData), + /*init_data*/ hue_correct_init_data, + /*free_data*/ hue_correct_free_data, + /*copy_data*/ hue_correct_copy_data, + /*apply*/ hue_correct_apply, }; /** \} */ @@ -1071,13 +1071,13 @@ static void brightcontrast_apply(struct SequenceModifierData *smd, ImBuf *ibuf, } static SequenceModifierTypeInfo seqModifier_BrightContrast = { - CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Bright/Contrast"), /* name */ - "BrightContrastModifierData", /* struct_name */ - sizeof(BrightContrastModifierData), /* struct_size */ - NULL, /* init_data */ - NULL, /* free_data */ - NULL, /* copy_data */ - brightcontrast_apply, /* apply */ + /*name*/ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Bright/Contrast"), + /*struct_name*/ "BrightContrastModifierData", + /*struct_size*/ sizeof(BrightContrastModifierData), + /*init_data*/ NULL, + /*free_data*/ NULL, + /*copy_data*/ NULL, + /*apply*/ brightcontrast_apply, }; /** \} */ @@ -1145,13 +1145,13 @@ static void maskmodifier_apply(struct SequenceModifierData *UNUSED(smd), ImBuf * } static SequenceModifierTypeInfo seqModifier_Mask = { - CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Mask"), /* name */ - "SequencerMaskModifierData", /* struct_name */ - sizeof(SequencerMaskModifierData), /* struct_size */ - NULL, /* init_data */ - NULL, /* free_data */ - NULL, /* copy_data */ - maskmodifier_apply, /* apply */ + /*name*/ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Mask"), + /*struct_name*/ "SequencerMaskModifierData", + /*struct_size*/ sizeof(SequencerMaskModifierData), + /*init_data*/ NULL, + /*free_data*/ NULL, + /*copy_data*/ NULL, + /*apply*/ maskmodifier_apply, }; /** \} */ @@ -1361,13 +1361,13 @@ static void tonemapmodifier_apply(struct SequenceModifierData *smd, ImBuf *ibuf, } static SequenceModifierTypeInfo seqModifier_Tonemap = { - CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Tonemap"), /* name */ - "SequencerTonemapModifierData", /* struct_name */ - sizeof(SequencerTonemapModifierData), /* struct_size */ - tonemapmodifier_init_data, /* init_data */ - NULL, /* free_data */ - NULL, /* copy_data */ - tonemapmodifier_apply, /* apply */ + /*name*/ CTX_N_(BLT_I18NCONTEXT_ID_SEQUENCE, "Tonemap"), + /*struct_name*/ "SequencerTonemapModifierData", + /*struct_size*/ sizeof(SequencerTonemapModifierData), + /*init_data*/ tonemapmodifier_init_data, + /*free_data*/ NULL, + /*copy_data*/ NULL, + /*apply*/ tonemapmodifier_apply, }; /** \} */ diff --git a/source/blender/shader_fx/intern/FX_shader_blur.c b/source/blender/shader_fx/intern/FX_shader_blur.c index 14e9a647105..8bc7b069c6e 100644 --- a/source/blender/shader_fx/intern/FX_shader_blur.c +++ b/source/blender/shader_fx/intern/FX_shader_blur.c @@ -64,19 +64,19 @@ static void panelRegister(ARegionType *region_type) } ShaderFxTypeInfo shaderfx_Type_Blur = { - /* name */ N_("Blur"), - /* structName */ "BlurShaderFxData", - /* structSize */ sizeof(BlurShaderFxData), - /* type */ eShaderFxType_GpencilType, - /* flags */ 0, + /*name*/ N_("Blur"), + /*structName*/ "BlurShaderFxData", + /*structSize*/ sizeof(BlurShaderFxData), + /*type*/ eShaderFxType_GpencilType, + /*flags*/ 0, - /* copyData */ copyData, + /*copyData*/ copyData, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_colorize.c b/source/blender/shader_fx/intern/FX_shader_colorize.c index 5551b16f445..bd36804a61a 100644 --- a/source/blender/shader_fx/intern/FX_shader_colorize.c +++ b/source/blender/shader_fx/intern/FX_shader_colorize.c @@ -71,19 +71,19 @@ static void panelRegister(ARegionType *region_type) } ShaderFxTypeInfo shaderfx_Type_Colorize = { - /* name */ N_("Colorize"), - /* structName */ "ColorizeShaderFxData", - /* structSize */ sizeof(ColorizeShaderFxData), - /* type */ eShaderFxType_GpencilType, - /* flags */ 0, + /*name*/ N_("Colorize"), + /*structName*/ "ColorizeShaderFxData", + /*structSize*/ sizeof(ColorizeShaderFxData), + /*type*/ eShaderFxType_GpencilType, + /*flags*/ 0, - /* copyData */ copyData, + /*copyData*/ copyData, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_flip.c b/source/blender/shader_fx/intern/FX_shader_flip.c index 5b5c12205ca..7d067bbc6f8 100644 --- a/source/blender/shader_fx/intern/FX_shader_flip.c +++ b/source/blender/shader_fx/intern/FX_shader_flip.c @@ -61,19 +61,19 @@ static void panelRegister(ARegionType *region_type) } ShaderFxTypeInfo shaderfx_Type_Flip = { - /* name */ N_("Flip"), - /* structName */ "FlipShaderFxData", - /* structSize */ sizeof(FlipShaderFxData), - /* type */ eShaderFxType_GpencilType, - /* flags */ 0, + /*name*/ N_("Flip"), + /*structName*/ "FlipShaderFxData", + /*structSize*/ sizeof(FlipShaderFxData), + /*type*/ eShaderFxType_GpencilType, + /*flags*/ 0, - /* copyData */ copyData, + /*copyData*/ copyData, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_glow.c b/source/blender/shader_fx/intern/FX_shader_glow.c index b620754225a..9c0e5857f6c 100644 --- a/source/blender/shader_fx/intern/FX_shader_glow.c +++ b/source/blender/shader_fx/intern/FX_shader_glow.c @@ -82,19 +82,19 @@ static void panelRegister(ARegionType *region_type) } ShaderFxTypeInfo shaderfx_Type_Glow = { - /* name */ N_("Glow"), - /* structName */ "GlowShaderFxData", - /* structSize */ sizeof(GlowShaderFxData), - /* type */ eShaderFxType_GpencilType, - /* flags */ 0, + /*name*/ N_("Glow"), + /*structName*/ "GlowShaderFxData", + /*structSize*/ sizeof(GlowShaderFxData), + /*type*/ eShaderFxType_GpencilType, + /*flags*/ 0, - /* copyData */ copyData, + /*copyData*/ copyData, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_pixel.c b/source/blender/shader_fx/intern/FX_shader_pixel.c index 6f43bfb32b7..ed7cf14dde9 100644 --- a/source/blender/shader_fx/intern/FX_shader_pixel.c +++ b/source/blender/shader_fx/intern/FX_shader_pixel.c @@ -62,19 +62,19 @@ static void panelRegister(ARegionType *region_type) } ShaderFxTypeInfo shaderfx_Type_Pixel = { - /* name */ N_("Pixelate"), - /* structName */ "PixelShaderFxData", - /* structSize */ sizeof(PixelShaderFxData), - /* type */ eShaderFxType_GpencilType, - /* flags */ 0, + /*name*/ N_("Pixelate"), + /*structName*/ "PixelShaderFxData", + /*structSize*/ sizeof(PixelShaderFxData), + /*type*/ eShaderFxType_GpencilType, + /*flags*/ 0, - /* copyData */ copyData, + /*copyData*/ copyData, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_rim.c b/source/blender/shader_fx/intern/FX_shader_rim.c index d314724eaca..76aae8302cd 100644 --- a/source/blender/shader_fx/intern/FX_shader_rim.c +++ b/source/blender/shader_fx/intern/FX_shader_rim.c @@ -89,19 +89,19 @@ static void panelRegister(ARegionType *region_type) } ShaderFxTypeInfo shaderfx_Type_Rim = { - /* name */ N_("Rim"), - /* structName */ "RimShaderFxData", - /* structSize */ sizeof(RimShaderFxData), - /* type */ eShaderFxType_GpencilType, - /* flags */ 0, + /*name*/ N_("Rim"), + /*structName*/ "RimShaderFxData", + /*structSize*/ sizeof(RimShaderFxData), + /*type*/ eShaderFxType_GpencilType, + /*flags*/ 0, - /* copyData */ copyData, + /*copyData*/ copyData, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ NULL, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_shadow.c b/source/blender/shader_fx/intern/FX_shader_shadow.c index 4b8b44cc5b0..cbbe182e7fa 100644 --- a/source/blender/shader_fx/intern/FX_shader_shadow.c +++ b/source/blender/shader_fx/intern/FX_shader_shadow.c @@ -159,19 +159,19 @@ static void panelRegister(ARegionType *region_type) } ShaderFxTypeInfo shaderfx_Type_Shadow = { - /* name */ N_("Shadow"), - /* structName */ "ShadowShaderFxData", - /* structSize */ sizeof(ShadowShaderFxData), - /* type */ eShaderFxType_GpencilType, - /* flags */ 0, + /*name*/ N_("Shadow"), + /*structName*/ "ShadowShaderFxData", + /*structSize*/ sizeof(ShadowShaderFxData), + /*type*/ eShaderFxType_GpencilType, + /*flags*/ 0, - /* copyData */ copyData, + /*copyData*/ copyData, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_swirl.c b/source/blender/shader_fx/intern/FX_shader_swirl.c index 059fe0ca8b6..a02acb59c27 100644 --- a/source/blender/shader_fx/intern/FX_shader_swirl.c +++ b/source/blender/shader_fx/intern/FX_shader_swirl.c @@ -90,19 +90,19 @@ static void panelRegister(ARegionType *region_type) } ShaderFxTypeInfo shaderfx_Type_Swirl = { - /* name */ N_("Swirl"), - /* structName */ "SwirlShaderFxData", - /* structSize */ sizeof(SwirlShaderFxData), - /* type */ eShaderFxType_GpencilType, - /* flags */ 0, + /*name*/ N_("Swirl"), + /*structName*/ "SwirlShaderFxData", + /*structSize*/ sizeof(SwirlShaderFxData), + /*type*/ eShaderFxType_GpencilType, + /*flags*/ 0, - /* copyData */ copyData, + /*copyData*/ copyData, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ isDisabled, - /* updateDepsgraph */ updateDepsgraph, - /* dependsOnTime */ NULL, - /* foreachIDLink */ foreachIDLink, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ isDisabled, + /*updateDepsgraph*/ updateDepsgraph, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ foreachIDLink, + /*panelRegister*/ panelRegister, }; diff --git a/source/blender/shader_fx/intern/FX_shader_wave.c b/source/blender/shader_fx/intern/FX_shader_wave.c index 947bf58ec7c..ef5c626241c 100644 --- a/source/blender/shader_fx/intern/FX_shader_wave.c +++ b/source/blender/shader_fx/intern/FX_shader_wave.c @@ -63,19 +63,19 @@ static void panelRegister(ARegionType *region_type) } ShaderFxTypeInfo shaderfx_Type_Wave = { - /* name */ N_("WaveDistortion"), - /* structName */ "WaveShaderFxData", - /* structSize */ sizeof(WaveShaderFxData), - /* type */ eShaderFxType_GpencilType, - /* flags */ 0, + /*name*/ N_("WaveDistortion"), + /*structName*/ "WaveShaderFxData", + /*structSize*/ sizeof(WaveShaderFxData), + /*type*/ eShaderFxType_GpencilType, + /*flags*/ 0, - /* copyData */ copyData, + /*copyData*/ copyData, - /* initData */ initData, - /* freeData */ NULL, - /* isDisabled */ NULL, - /* updateDepsgraph */ NULL, - /* dependsOnTime */ NULL, - /* foreachIDLink */ NULL, - /* panelRegister */ panelRegister, + /*initData*/ initData, + /*freeData*/ NULL, + /*isDisabled*/ NULL, + /*updateDepsgraph*/ NULL, + /*dependsOnTime*/ NULL, + /*foreachIDLink*/ NULL, + /*panelRegister*/ panelRegister, }; From eeb6a3dc056ffd64d1f9034f017beda02388dd47 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jan 2023 13:25:05 +1100 Subject: [PATCH 0664/1522] Clenaup: comments places awkwardly before code --- source/blender/blenlib/intern/mesh_intersect.cc | 3 ++- source/blender/editors/space_sequencer/sequencer_draw.c | 3 ++- source/blender/modifiers/intern/MOD_volume_displace.cc | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/source/blender/blenlib/intern/mesh_intersect.cc b/source/blender/blenlib/intern/mesh_intersect.cc index 8dcb513cb9f..d4d86e678c5 100644 --- a/source/blender/blenlib/intern/mesh_intersect.cc +++ b/source/blender/blenlib/intern/mesh_intersect.cc @@ -2030,7 +2030,8 @@ static Array polyfill_triangulate_poly(Face *f, IMeshArena *arena) } return Array{f0, f1}; } - /* Project along negative face normal so (x,y) can be used in 2d. */ float axis_mat[3][3]; + /* Project along negative face normal so (x,y) can be used in 2d. */ + float axis_mat[3][3]; float(*projverts)[2]; uint(*tris)[3]; const int totfilltri = flen - 2; diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 120fbbbf062..5d74ca96613 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -978,7 +978,8 @@ static void draw_sequence_extensions_overlay( immUniformColor4ubv(col); immRectf(pos, x2, y2 + pixely, strip_content_end, y2 + SEQ_STRIP_OFSBOTTOM); - /* Outline. */ immUniformColor3ubv(blend_col); + /* Outline. */ + immUniformColor3ubv(blend_col); imm_draw_box_wire_2d(pos, x2, y2 + pixely, strip_content_end, y2 + SEQ_STRIP_OFSBOTTOM); } GPU_blend(GPU_BLEND_NONE); diff --git a/source/blender/modifiers/intern/MOD_volume_displace.cc b/source/blender/modifiers/intern/MOD_volume_displace.cc index 33ef740977e..4982669c976 100644 --- a/source/blender/modifiers/intern/MOD_volume_displace.cc +++ b/source/blender/modifiers/intern/MOD_volume_displace.cc @@ -231,7 +231,8 @@ struct DisplaceGridOp { openvdb::tools::foreach (temp_grid->beginValueOn(), displace_op, true, - /* Disable sharing of the operator. */ false); + /* Disable sharing of the operator. */ + false); /* It is likely that we produced too many active cells. Those are removed here, to avoid * slowing down subsequent operations. */ From 2467becade76fafa4a6c5d3031048d3d8767b774 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jan 2023 13:57:10 +1100 Subject: [PATCH 0665/1522] Cleanup: spelling in comments --- source/blender/blenkernel/BKE_customdata.h | 4 ++-- source/blender/blenkernel/BKE_particle.h | 10 ++++++---- source/blender/blenkernel/intern/constraint.c | 6 +++--- source/blender/blenkernel/intern/dynamicpaint.c | 10 +++++----- source/blender/blenkernel/intern/mesh_remap.cc | 4 ++-- .../blenkernel/intern/particle_distribute.c | 5 +++-- source/blender/blenkernel/intern/softbody.c | 6 +++--- source/blender/blenloader/intern/versioning_250.c | 2 +- source/blender/blenloader/intern/versioning_290.c | 5 ++--- source/blender/blenloader/intern/versioning_300.cc | 4 ++-- .../blenloader/intern/versioning_defaults.cc | 2 +- source/blender/draw/intern/draw_manager.c | 2 +- .../editors/transform/transform_convert_armature.c | 4 ++-- .../editors/transform/transform_mode_resize.c | 6 ++---- .../gpencil_modifiers/intern/MOD_gpencilbuild.c | 8 ++++---- source/blender/io/collada/MeshImporter.cpp | 4 ++-- source/blender/makesdna/DNA_scene_types.h | 14 +++++++------- source/blender/makesrna/intern/rna_particle.c | 4 ++-- source/blender/modifiers/intern/MOD_ocean.c | 2 +- .../modifiers/intern/MOD_solidify_extrude.c | 2 +- .../windowmanager/intern/wm_event_system.cc | 4 +++- 21 files changed, 55 insertions(+), 53 deletions(-) diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index e7161722925..905eb43179a 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -681,7 +681,7 @@ typedef struct CustomDataTransferLayerMap { /** If non-NULL, array of weights, one for each dest item, replaces mix_factor. */ const float *mix_weights; - /** Data source array (can be regular CD data, vertices/edges/etc., keyblocks...). */ + /** Data source array (can be regular CD data, vertices/edges/etc., key-blocks...). */ const void *data_src; /** Data dest array (same type as dat_src). */ void *data_dst; @@ -699,7 +699,7 @@ typedef struct CustomDataTransferLayerMap { /** For bit-flag transfer, flag(s) to affect in transferred data. */ uint64_t data_flag; - /** Opaque pointer, to be used by specific interp callback (e.g. transformspace for normals). */ + /** Opaque pointer, to be used by specific interp callback (e.g. transform-space for normals). */ void *interp_data; cd_datatransfer_interp interp; diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index fc9769a94a4..f295979f23c 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -210,10 +210,12 @@ typedef struct ParticleCollision { ParticleCollisionElement pce; - /* total_time is the amount of time in this subframe - * inv_total_time is the opposite - * inv_timestep is the inverse of the amount of time in this frame */ - float total_time, inv_total_time, inv_timestep; + /** The amount of time in this sub-frame. */ + float total_time; + /** The inverse of `total_time`. */ + float inv_total_time; + /** The inverse of the amount of time in this frame. */ + float inv_timestep; float radius; float co1[3], co2[3]; diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 93ab47651ed..fbaadca09cd 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -124,7 +124,7 @@ bConstraintOb *BKE_constraints_make_evalob( /* create regardless of whether we have any data! */ cob = MEM_callocN(sizeof(bConstraintOb), "bConstraintOb"); - /* for system time, part of deglobalization, code nicer later with local time (ton) */ + /* NOTE(@ton): For system time, part of de-globalization, code nicer later with local time. */ cob->scene = scene; cob->depsgraph = depsgraph; @@ -236,7 +236,7 @@ void BKE_constraints_clear_evalob(bConstraintOb *cob) } } - /* free tempolary struct */ + /* Free temporary struct. */ MEM_freeN(cob); } @@ -3842,7 +3842,7 @@ static void clampto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar * be used that doesn't lazy initialize to avoid thread safety issues in the future. */ BKE_object_minmax(ct->tar, curveMin, curveMax, true); - /* get targetmatrix */ + /* Get target-matrix. */ if (data->tar->runtime.curve_cache && data->tar->runtime.curve_cache->anim_path_accum_length) { float vec[4], totmat[4][4]; float curvetime; diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 4f24a503a4d..705e5d56f9b 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -507,7 +507,7 @@ static float mixColors( static void scene_setSubframe(Scene *scene, float subframe) { - /* dynamic paint subframes must be done on previous frame */ + /* Dynamic paint sub-frames must be done on previous frame. */ scene->r.cfra -= 1; scene->r.subframe = subframe; } @@ -1139,7 +1139,7 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str brush->smudge_strength = 0.3f; brush->max_velocity = 1.0f; - /* Paint proximity falloff colorramp. */ + /* Paint proximity falloff color-ramp. */ { CBData *ramp; @@ -1659,7 +1659,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface /* vertex color layer */ else if (surface->init_color_type == MOD_DPAINT_INITIAL_VERTEXCOLOR) { - /* for vertex surface, just copy colors from mcol */ + /* For vertex surface, just copy colors from #MLoopCol. */ if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { const MLoop *mloop = BKE_mesh_loops(mesh); const int totloop = mesh->totloop; @@ -2787,7 +2787,7 @@ int dynamicPaint_createUVSurface(Scene *scene, float *progress, bool *do_update) { - /* Antialias jitter point relative coords */ + /* Anti-alias jitter point relative coords. */ const int aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1; char uvname[MAX_CUSTOMDATA_LAYER_NAME]; uint32_t active_points = 0; @@ -5333,7 +5333,7 @@ static void dynamic_paint_effect_drip_cb(void *__restrict userdata, const uint n_trgt = (uint)n_target[n_idx]; - /* Sort of spinlock, but only for given ePoint. + /* Sort of spin-lock, but only for given ePoint. * Since the odds a same ePoint is modified at the same time by several threads is very low, * this is much more efficient than a global spin lock. */ const uint epointlock_idx = n_trgt / 8; diff --git a/source/blender/blenkernel/intern/mesh_remap.cc b/source/blender/blenkernel/intern/mesh_remap.cc index c36fbfb3274..c32a9c067ac 100644 --- a/source/blender/blenkernel/intern/mesh_remap.cc +++ b/source/blender/blenkernel/intern/mesh_remap.cc @@ -448,9 +448,9 @@ struct IslandResult { * This only concerns loops, currently (because of islands), and 'sampled' edges/polys norproj. */ -/* At most n raycasts per 'real' ray. */ +/** At most N ray-casts per 'real' ray. */ #define MREMAP_RAYCAST_APPROXIMATE_NR 3 -/* Each approximated raycasts will have n times bigger radius than previous one. */ +/** Each approximated ray-casts will have n times bigger radius than previous one. */ #define MREMAP_RAYCAST_APPROXIMATE_FAC 5.0f /* min 16 rays/face, max 400. */ diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 7cec485e6dd..085f2cc8ddb 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -316,9 +316,10 @@ static void distribute_grid(Mesh *mesh, ParticleSystem *psys) } } -/* modified copy from rayshade.c */ static void hammersley_create(float *out, int n, int seed, float amount) { + /* This code is originally from a modified copy from `rayshade.c` + * (a file that's no longer included). */ RNG *rng; double ofs[2], t; @@ -917,7 +918,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, } /* XXX This distribution code is totally broken in case from == PART_FROM_CHILD, - * it's always using finaldm even if use_modifier_stack is unset... + * it's always using `final_mesh` even if use_modifier_stack is unset... * But making things consistent here break all existing edited * hair systems, so better wait for complete rewrite. */ diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 0500e924d2f..b322a0a803d 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -377,7 +377,7 @@ static void ccd_mesh_update(Object *ob, ccd_Mesh *pccd_M) pccd_M->bbmin[0] = pccd_M->bbmin[1] = pccd_M->bbmin[2] = 1e30f; pccd_M->bbmax[0] = pccd_M->bbmax[1] = pccd_M->bbmax[2] = -1e30f; - /* blow it up with forcefield ranges */ + /* Blow it up with force-field ranges. */ hull = max_ff(ob->pd->pdef_sbift, ob->pd->pdef_sboft); /* rotate current to previous */ @@ -848,7 +848,7 @@ static void renew_softbody(Object *ob, int totpoint, int totspring) } else { bp->goal = 0.0f; - /* so this will definily be below SOFTGOALSNAP */ + /* So this will definitely be below #SOFTGOALSNAP. */ } bp->nofsprings = 0; @@ -1793,7 +1793,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], return deflected; } -/* sandbox to plug in various deflection algos */ +/* Sandbox to plug in various deflection algorithms. */ static int sb_deflect_face(Object *ob, float *actpos, float *facenormal, diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index da4783e19ea..5d2072e0fd9 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -1465,7 +1465,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *bmain) } /* sequencer changes */ } - if (bmain->versionfile <= 251) { /* 2.5.1 had no subversions */ + if (bmain->versionfile <= 251) { /* 2.5.1 had no sub-versions */ bScreen *screen; /* Blender 2.5.2 - subversion 0 introduced a new setting: V3D_HIDE_OVERLAYS. diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c index 202b9ea692d..10f72f22b8e 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.c @@ -1101,9 +1101,8 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) continue; } - /* The substep method changed from "per second" to "per frame". - * To get the new value simply divide the old bullet sim fps with the scene fps. - */ + /* The sub-step method changed from "per second" to "per frame". + * To get the new value simply divide the old bullet sim FPS with the scene FPS. */ rbw->substeps_per_frame /= FPS; if (rbw->substeps_per_frame <= 0) { diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc index ff7c7f4480a..4c45e1433ab 100644 --- a/source/blender/blenloader/intern/versioning_300.cc +++ b/source/blender/blenloader/intern/versioning_300.cc @@ -3843,8 +3843,8 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain) LISTBASE_FOREACH (Light *, light, &bmain->lights) { light->radius = light->area_size; } - /* Grease Pencil Build modifier: Set default value for new natural drawspeed factor and maximum - * gap. */ + /* Grease Pencil Build modifier: + * Set default value for new natural draw-speed factor and maximum gap. */ if (!DNA_struct_elem_find(fd->filesdna, "BuildGpencilModifierData", "float", "speed_fac") || !DNA_struct_elem_find(fd->filesdna, "BuildGpencilModifierData", "float", "speed_maxgap")) { LISTBASE_FOREACH (Object *, ob, &bmain->objects) { diff --git a/source/blender/blenloader/intern/versioning_defaults.cc b/source/blender/blenloader/intern/versioning_defaults.cc index 87574e90dab..f6fe45ddcdf 100644 --- a/source/blender/blenloader/intern/versioning_defaults.cc +++ b/source/blender/blenloader/intern/versioning_defaults.cc @@ -494,7 +494,7 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template) return; } - /* Workspaces. */ + /* Work-spaces. */ LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) { LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { LISTBASE_FOREACH (WorkSpace *, workspace, &bmain->workspaces) { diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 60d34b99b3d..43a2e89b989 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1474,7 +1474,7 @@ void DRW_draw_callbacks_post_scene(void) /* XXX: Or should we use a proper draw/overlay engine for this case? */ if (do_annotations) { GPU_depth_test(GPU_DEPTH_NONE); - /* XXX: as scene->gpd is not copied for COW yet */ + /* XXX: as `scene->gpd` is not copied for COW yet. */ ED_annotation_draw_view3d(DEG_get_input_scene(depsgraph), depsgraph, v3d, region, true); GPU_depth_test(GPU_DEPTH_LESS_EQUAL); } diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index b9b78da1993..d3bebfe8c72 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -343,8 +343,8 @@ static short pose_grab_with_ik_add(bPoseChannel *pchan) /* we only include bones that are part of a continual connected chain */ do { - /* here, we set ik-settings for bone from pchan->protectflag */ - /* XXX: careful with quats/axis-angle rotations where we're locking 4d components. */ + /* Here, we set IK-settings for bone from `pchan->protectflag`. */ + /* XXX: careful with quaternion/axis-angle rotations where we're locking 4D components. */ if (pchan->protectflag & OB_LOCK_ROTX) { pchan->ikflag |= BONE_IK_NO_XDOF_TEMP; } diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c index ae90463b7f3..355da21c253 100644 --- a/source/blender/editors/transform/transform_mode_resize.c +++ b/source/blender/editors/transform/transform_mode_resize.c @@ -268,10 +268,8 @@ static void applyResize(TransInfo *t, const int UNUSED(mval[2])) ElementResize(t, tc, td, mat); } - /* In proportional edit it can happen that */ - /* vertices in the radius of the brush end */ - /* outside the clipping area */ - /* XXX HACK - dg */ + /* XXX(@dg): In proportional edit it can happen that vertices + * in the radius of the brush end outside the clipping area. */ if (t->flag & T_PROP_EDIT) { clipUVData(t); } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c index b8afe9144b1..ac0286d6c36 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c @@ -278,7 +278,7 @@ static void build_sequential(Object *ob, /* Recycled counter. */ size_t i; Scene *scene = DEG_get_evaluated_scene(depsgraph); - /* Framerate of scene. */ + /* Frame-rate of scene. */ const float fps = (((float)scene->r.frs_sec) / scene->r.frs_sec_base); /* 1) Determine which strokes to start with (& adapt total number of strokes to build). */ @@ -379,9 +379,9 @@ static void build_sequential(Object *ob, float deltatime = fabs(cell->gps->points[j].time - last_pointtime); /* Do we need to sanitize previous points? */ if (0 < zeropoints) { - /* Only correct if timegap bigger than MIN_CORRECTGAP. */ + /* Only correct if time-gap bigger than #GP_BUILD_CORRECTGAP. */ if (GP_BUILD_CORRECTGAP < deltatime) { - /* Cycling backwards through zeropoints to fix them. */ + /* Cycling backwards through zero-points to fix them. */ for (int k = 0; k < zeropoints; k++) { float linear_fill = interpf( deltatime, 0, ((float)k + 1) / (zeropoints + 1)); /* Factor = Proportion. */ @@ -393,7 +393,7 @@ static void build_sequential(Object *ob, } } - /* Normal behaviour with time data */ + /* Normal behavior with time data. */ idx_times[curpoint] = sumtime + deltatime; sumtime = idx_times[curpoint]; last_pointtime = cell->gps->points[j].time; diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp index aa29bfc3343..096376cfe19 100644 --- a/source/blender/io/collada/MeshImporter.cpp +++ b/source/blender/io/collada/MeshImporter.cpp @@ -654,8 +654,8 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, if (collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) { uint grouped_vertex_count = mp->getGroupedVertexElementsCount(); for (uint group_index = 0; group_index < grouped_vertex_count; group_index++) { - uint first_vertex = position_indices[0]; /* Store first trifan vertex */ - uint first_normal = normal_indices[0]; /* Store first trifan vertex normal */ + uint first_vertex = position_indices[0]; /* Store first triangle-fan vertex. */ + uint first_normal = normal_indices[0]; /* Store first triangle-fan vertex normal. */ uint vertex_count = mp->getGroupedVerticesVertexCount(group_index); for (uint vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++) { diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index ab16b3b986b..a4076a4c4e6 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -431,7 +431,7 @@ typedef struct ImageFormatData { /** OpenEXR. */ char exr_codec; - /** Cineon. */ + /** CINEON. */ char cineon_flag; short cineon_white, cineon_black; float cineon_gamma; @@ -657,7 +657,7 @@ typedef struct RenderData { /** Frames as in 'images'. */ int cfra, sfra, efra; - /** Subframe offset from cfra, in 0.0-1.0. */ + /** Sub-frame offset from `cfra`, in 0.0-1.0. */ float subframe; /** Start+end frames of preview range. */ int psfra, pefra; @@ -719,13 +719,13 @@ typedef struct RenderData { /** * What to do with the sky/background. - * Picks sky/premul blending for the background. + * Picks sky/pre-multiply blending for the background. */ char alphamode; char _pad0[1]; - /** Render border to render sub-resions. */ + /** Render border to render sub-regions. */ rctf border; /* Information on different layers to be rendered. */ @@ -1928,7 +1928,7 @@ typedef struct Scene { void *sound_scrub_handle; void *speaker_handles; - /** (runtime) info/cache used for presenting playback framerate info to the user. */ + /** (runtime) info/cache used for presenting playback frame-rate info to the user. */ void *fps_info; /** None of the dependency graph vars is mean to be saved. */ @@ -2000,7 +2000,7 @@ typedef struct Scene { /* Use preview range. */ #define SCER_PRV_RANGE (1 << 0) #define SCER_LOCK_FRAME_SELECTION (1 << 1) -/* Show/use subframes (for checking motion blur). */ +/** Show/use sub-frames (for checking motion blur). */ #define SCER_SHOW_SUBFRAME (1 << 3) /** #RenderData.mode. */ @@ -2560,7 +2560,7 @@ typedef enum eGPencil_Flags { GP_TOOL_FLAG_PAINT_ONBACK = (1 << 2), /** Show compact list of colors. */ GP_TOOL_FLAG_THUMBNAIL_LIST = (1 << 3), - /** Generate wheight data for new strokes. */ + /** Generate weight data for new strokes. */ GP_TOOL_FLAG_CREATE_WEIGHTS = (1 << 4), /** Auto-merge with last stroke. */ GP_TOOL_FLAG_AUTOMERGE_STROKE = (1 << 5), diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index fa8fe5cde00..b4032ec8ab1 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -2976,7 +2976,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "effector_amount", PROP_INT, PROP_UNSIGNED); /* In theory PROP_ANIMATABLE perhaps should be cleared, * but animating this can give some interesting results! */ - RNA_def_property_range(prop, 0, 10000); /* 10000 effectors will bel SLOW, but who knows */ + RNA_def_property_range(prop, 0, 10000); /* 10000 effectors will be SLOW, but who knows */ RNA_def_property_ui_range(prop, 0, 100, 1, -1); RNA_def_property_ui_text( prop, "Effector Number", "How many particles are effectors (0 is all particles)"); @@ -4015,7 +4015,7 @@ static void rna_def_particle_system(BlenderRNA *brna) RNA_def_parameter_flags(parm, PROP_THICK_WRAP, 0); RNA_def_function_output(func, parm); - /* extract hair mcols */ + /* Extract hair vertex-colors. */ func = RNA_def_function(srna, "mcol_on_emitter", "rna_ParticleSystem_mcol_on_emitter"); RNA_def_function_flag(func, FUNC_USE_REPORTS); RNA_def_function_ui_description(func, "Obtain mcol for all particles"); diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 64a2efc5459..9081ebd85fb 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -366,7 +366,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes float(*positions)[3] = BKE_mesh_vert_positions_for_write(result); const MPoly *polys = BKE_mesh_polys(result); - /* add vcols before displacement - allows lookup based on position */ + /* Add vertex-colors before displacement: allows lookup based on position. */ if (omd->flag & MOD_OCEAN_GENERATE_FOAM) { const int polys_num = result->totpoly; diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.c index 5013166cb3b..0e3368577d4 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.c +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.c @@ -352,7 +352,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex * (so that winding of copied face get reversed, so that normals get reversed * and point in expected direction...). * If we also copy data here, then this data get overwritten - * (and allocated memory becomes memleak). */ + * (and allocated memory becomes a memory leak). */ CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)polys_num); CustomData_copy_data(&mesh->pdata, &result->pdata, 0, (int)polys_num, (int)polys_num); diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index c412006b819..05fe351c385 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -2666,7 +2666,9 @@ static int wm_handler_fileselect_do(bContext *C, wm_window_close(C, wm, win); - CTX_wm_window_set(C, root_win); /* #wm_window_close() nullptrs. */ + /* #wm_window_close() sets the context's window to null. */ + CTX_wm_window_set(C, root_win); + /* Some operators expect a drawable context (for #EVT_FILESELECT_EXEC). */ wm_window_make_drawable(wm, root_win); /* Ensure correct cursor position, otherwise, popups may close immediately after From cc5fefffe61c96646760af833d17bab580969d8e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jan 2023 14:05:49 +1100 Subject: [PATCH 0666/1522] Cleanup: quiet array-bounds warning in GCC 12.2 --- source/blender/editors/armature/armature_edit.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index 3c0617a1dfc..2ec0ea57e71 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -388,18 +388,21 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op) ED_armature_ebone_to_mat3(ebone, mat); copy_v3_v3(vec, mat[2]); } - else { /* Axis */ - BLI_assert(type <= 5); + else if (type < 6) { /* NOTE: always true, check to quiet GCC12.2 `-Warray-bounds`. */ + /* Axis */ if (type < 3) { vec[type] = 1.0f; } else { - /* Use casting to quiet -Warray-bounds warning in gcc. */ - vec[(int)type - 2] = -1.0f; + vec[type - 2] = -1.0f; } mul_m3_v3(imat, vec); normalize_v3(vec); } + else { + /* The previous block should handle all remaining cases. */ + BLI_assert_unreachable(); + } if (axis_flip) { negate_v3(vec); From 6a7ecec6e101faf3392e88dc07e2c1e2251ece1a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jan 2023 14:20:46 +1100 Subject: [PATCH 0667/1522] Cleanup: avoid returning large structs from functions Return BezTriple as a const pointer from utility functions instead of by a value since it's a large struct. --- .../editors/animation/keyframes_general.c | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c index c356f633053..49e40b39902 100644 --- a/source/blender/editors/animation/keyframes_general.c +++ b/source/blender/editors/animation/keyframes_general.c @@ -282,15 +282,15 @@ ListBase find_fcurve_segments(FCurve *fcu) return segments; } -static BezTriple fcurve_segment_start_get(FCurve *fcu, int index) +static const BezTriple *fcurve_segment_start_get(FCurve *fcu, int index) { - BezTriple start_bezt = index - 1 >= 0 ? fcu->bezt[index - 1] : fcu->bezt[index]; + const BezTriple *start_bezt = index - 1 >= 0 ? &fcu->bezt[index - 1] : &fcu->bezt[index]; return start_bezt; } -static BezTriple fcurve_segment_end_get(FCurve *fcu, int index) +static const BezTriple *fcurve_segment_end_get(FCurve *fcu, int index) { - BezTriple end_bezt = index < fcu->totvert ? fcu->bezt[index] : fcu->bezt[index - 1]; + const BezTriple *end_bezt = index < fcu->totvert ? &fcu->bezt[index] : &fcu->bezt[index - 1]; return end_bezt; } @@ -299,7 +299,7 @@ static BezTriple fcurve_segment_end_get(FCurve *fcu, int index) void blend_to_neighbor_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor) { const float blend_factor = fabs(factor * 2 - 1); - BezTriple target_bezt; + const BezTriple *target_bezt; /* Find which key to blend towards. */ if (factor < 0.5f) { target_bezt = fcurve_segment_start_get(fcu, segment->start_index); @@ -309,7 +309,7 @@ void blend_to_neighbor_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const } /* Blend each key individually. */ for (int i = segment->start_index; i < segment->start_index + segment->length; i++) { - fcu->bezt[i].vec[1][1] = interpf(target_bezt.vec[1][1], fcu->bezt[i].vec[1][1], blend_factor); + fcu->bezt[i].vec[1][1] = interpf(target_bezt->vec[1][1], fcu->bezt[i].vec[1][1], blend_factor); } } @@ -379,14 +379,14 @@ void blend_to_default_fcurve(PointerRNA *id_ptr, FCurve *fcu, const float factor void ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor) { - const BezTriple left_key = fcurve_segment_start_get(fcu, segment->start_index); - const float left_x = left_key.vec[1][0]; - const float left_y = left_key.vec[1][1]; + const BezTriple *left_key = fcurve_segment_start_get(fcu, segment->start_index); + const float left_x = left_key->vec[1][0]; + const float left_y = left_key->vec[1][1]; - const BezTriple right_key = fcurve_segment_end_get(fcu, segment->start_index + segment->length); + const BezTriple *right_key = fcurve_segment_end_get(fcu, segment->start_index + segment->length); - const float key_x_range = right_key.vec[1][0] - left_x; - const float key_y_range = right_key.vec[1][1] - left_y; + const float key_x_range = right_key->vec[1][0] - left_x; + const float key_y_range = right_key->vec[1][1] - left_y; /* Happens if there is only 1 key on the FCurve. Needs to be skipped because it * would be a divide by 0. */ @@ -419,11 +419,12 @@ void ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor void breakdown_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor) { - BezTriple left_bezt = fcurve_segment_start_get(fcu, segment->start_index); - BezTriple right_bezt = fcurve_segment_end_get(fcu, segment->start_index + segment->length); + const BezTriple *left_bezt = fcurve_segment_start_get(fcu, segment->start_index); + const BezTriple *right_bezt = fcurve_segment_end_get(fcu, + segment->start_index + segment->length); for (int i = segment->start_index; i < segment->start_index + segment->length; i++) { - fcu->bezt[i].vec[1][1] = interpf(right_bezt.vec[1][1], left_bezt.vec[1][1], factor); + fcu->bezt[i].vec[1][1] = interpf(right_bezt->vec[1][1], left_bezt->vec[1][1], factor); } } From a294c353701f26d81b3f87ae4d9c8d2d55c88ebf Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jan 2023 14:49:49 +1100 Subject: [PATCH 0668/1522] Docs: expand on doc-string for seam_connected_recursive Also use const UVs where possible. --- source/blender/editors/mesh/editmesh_utils.c | 35 +++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 21fb223e1de..764344fbd68 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -899,14 +899,29 @@ static bool loop_uv_match(BMLoop *loop, compare_v2v2(luv_b, luv_d, STD_UV_CONNECT_LIMIT); } -/* Given `luv_anchor` and `needle`, return true if there are edges that fan between them that are - * seam-free. */ +/** + * Utility function to implement #seam_connected. + * + * Given `edge`, `luv_anchor` & `luv_fan` find if `needle` is connected without + * seams or disjoint UVs which would delimit causing them not to be considered connected. + * + * \note The term *anchor* is used for the vertex at the center of a face-fan + * which is being stepped over. Even though every connected face may have a different UV, + * loops are only stepped onto which match the initial `luv_anchor`. + * + * \param edge: Search for `needle` in all loops connected to `edge` (recursively). + * \param luv_anchor: The UV of the anchor (vertex that's being stepped around). + * \param luv_fan: The UV of the outer edge, this changes as the fan is stepped over. + * \param visited: A set of edges to prevent recursing down the same edge multiple times. + * \param cd_loop_uv_offset: The UV layer. + * \return true if there are edges that fan between them that are seam-free. + * */ static bool seam_connected_recursive(BMEdge *edge, const float luv_anchor[2], const float luv_fan[2], - BMLoop *needle, + const BMLoop *needle, GSet *visited, - int cd_loop_uv_offset) + const int cd_loop_uv_offset) { BMVert *anchor = needle->v; BLI_assert(edge->v1 == anchor || edge->v2 == anchor); @@ -931,7 +946,7 @@ static bool seam_connected_recursive(BMEdge *edge, return true; /* Success. */ } - float *luv_far = BM_ELEM_CD_GET_FLOAT_P(loop->prev, cd_loop_uv_offset); + const float *luv_far = BM_ELEM_CD_GET_FLOAT_P(loop->prev, cd_loop_uv_offset); if (seam_connected_recursive( loop->prev->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) { return true; @@ -947,7 +962,7 @@ static bool seam_connected_recursive(BMEdge *edge, return true; /* Success. */ } - float *luv_far = BM_ELEM_CD_GET_FLOAT_P(loop->next->next, cd_loop_uv_offset); + const float *luv_far = BM_ELEM_CD_GET_FLOAT_P(loop->next->next, cd_loop_uv_offset); if (seam_connected_recursive( loop->next->e, luv_anchor, luv_far, needle, visited, cd_loop_uv_offset)) { return true; @@ -958,8 +973,10 @@ static bool seam_connected_recursive(BMEdge *edge, return false; } -/* Given `loop_a` and `loop_b` originate from the same vertex and share a UV, - * return true if there are edges that fan between them that are seam-free. +/** + * Given `loop_a` and `loop_b` originate from the same vertex and share a UV, + * + * \return true if there are edges that fan between them that are seam-free. * return false otherwise. */ static bool seam_connected(BMLoop *loop_a, BMLoop *loop_b, GSet *visited, int cd_loop_uv_offset) @@ -977,7 +994,7 @@ static bool seam_connected(BMLoop *loop_a, BMLoop *loop_b, GSet *visited, int cd if (!result) { /* Search around `loop_a` in the opposite direction, as one of the edges may be delimited by * a boundary, seam or disjoint UV, or itself be one of these. See: T103670, T103787. */ - float *luv_prev_fan = BM_ELEM_CD_GET_FLOAT_P(loop_a->prev, cd_loop_uv_offset); + const float *luv_prev_fan = BM_ELEM_CD_GET_FLOAT_P(loop_a->prev, cd_loop_uv_offset); result = seam_connected_recursive( loop_a->prev->e, luv_anchor, luv_prev_fan, loop_b, visited, cd_loop_uv_offset); } From 5cbc8ce3b14558cf208f30cc01aea55e00816003 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 16 Jan 2023 15:15:47 +1100 Subject: [PATCH 0669/1522] Fix ASAN error when Wayland fell back to X11 An alternative fix to [0] which caused an error with ASAN (freeing an GHOST_ISystem instead of a GHOST_System). Reported by @Baardaap in chat, I'm unable to reproduce the issue. Instead of calling the destructor directly, add a private method that deletes data before raising an exception. [0]: fd36221930e35efd2c09af8fb91234a510e3b9dc --- intern/ghost/intern/GHOST_SystemWayland.cpp | 15 ++++++++++----- intern/ghost/intern/GHOST_SystemWayland.h | 6 ++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index fbe5159ea78..6a163d8661e 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -5328,7 +5328,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) /* Connect to the Wayland server. */ display_->wl_display = wl_display_connect(nullptr); if (!display_->wl_display) { - this->~GHOST_SystemWayland(); + display_destroy_and_free_all(); throw std::runtime_error("Wayland: unable to connect to display!"); } @@ -5372,7 +5372,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) "WAYLAND found but libdecor was not, install libdecor for Wayland support, " "falling back to X11\n"); # endif - this->~GHOST_SystemWayland(); + display_destroy_and_free_all(); throw std::runtime_error("Wayland: unable to find libdecor!"); use_libdecor = true; @@ -5389,7 +5389,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) GWL_LibDecor_System &decor = *display_->libdecor; decor.context = libdecor_new(display_->wl_display, &libdecor_interface); if (!decor.context) { - this->~GHOST_SystemWayland(); + display_destroy_and_free_all(); throw std::runtime_error("Wayland: unable to create window decorations!"); } } @@ -5400,7 +5400,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) { GWL_XDG_Decor_System &decor = *display_->xdg_decor; if (!decor.shell) { - this->~GHOST_SystemWayland(); + display_destroy_and_free_all(); throw std::runtime_error("Wayland: unable to access xdg_shell!"); } } @@ -5410,7 +5410,7 @@ GHOST_SystemWayland::GHOST_SystemWayland(bool background) #endif } -GHOST_SystemWayland::~GHOST_SystemWayland() +void GHOST_SystemWayland::display_destroy_and_free_all() { gwl_display_destroy(display_); @@ -5420,6 +5420,11 @@ GHOST_SystemWayland::~GHOST_SystemWayland() #endif } +GHOST_SystemWayland::~GHOST_SystemWayland() +{ + display_destroy_and_free_all(); +} + GHOST_TSuccess GHOST_SystemWayland::init() { GHOST_TSuccess success = GHOST_System::init(); diff --git a/intern/ghost/intern/GHOST_SystemWayland.h b/intern/ghost/intern/GHOST_SystemWayland.h index c745d3b1d36..44026d5efad 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.h +++ b/intern/ghost/intern/GHOST_SystemWayland.h @@ -242,5 +242,11 @@ class GHOST_SystemWayland : public GHOST_System { #endif private: + /** + * Support freeing the internal data separately from the destructor + * so it can be called when WAYLAND isn't running (immediately before raising an exception). + */ + void display_destroy_and_free_all(); + struct GWL_Display *display_; }; From ff814ec5f687aac769a12327f9f38f7291385530 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 16 Jan 2023 11:12:14 +0100 Subject: [PATCH 0670/1522] Metal: Fix read from uninitialized memory. Implementation didn't count the string terminator when allocating memory to store `msl_patch_default`. The string terminator could be overwritted by other memory adding some undefined behavior. --- source/blender/gpu/metal/mtl_shader_generator.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm index fc37263d239..93429800888 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.mm +++ b/source/blender/gpu/metal/mtl_shader_generator.mm @@ -521,7 +521,7 @@ char *MSLGeneratorInterface::msl_patch_default_get() std::stringstream ss_patch; ss_patch << datatoc_mtl_shader_defines_msl << std::endl; ss_patch << datatoc_mtl_shader_shared_h << std::endl; - size_t len = strlen(ss_patch.str().c_str()); + size_t len = strlen(ss_patch.str().c_str()) + 1; msl_patch_default = (char *)malloc(len * sizeof(char)); strcpy(msl_patch_default, ss_patch.str().c_str()); From 9a1f0443cbc38d7969d172a8a343a55b1b999207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Ch=C3=A9hab?= Date: Mon, 16 Jan 2023 12:02:48 +0100 Subject: [PATCH 0671/1522] Fix Unreported: GPencil Separating strokes creates negative times Separating strokes using "selected points" didn't take into account that points->time can be 0 and thus created points with negative values in points->time, which should be an impossibility. This patch fixes this in BKE_gpencil_stroke_delete_tagged_points. Also, it makes the build modifier's new drawspeed immune to (erroneous) negative time values, should they arise in other situations. Reviewed By: antoniov Differential Revision: https://developer.blender.org/D17006 --- source/blender/blenkernel/intern/gpencil_geom.cc | 3 ++- source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc index e209c772fa0..8115920f938 100644 --- a/source/blender/blenkernel/intern/gpencil_geom.cc +++ b/source/blender/blenkernel/intern/gpencil_geom.cc @@ -3216,7 +3216,8 @@ bGPDstroke *BKE_gpencil_stroke_delete_tagged_points(bGPdata *gpd, pts = new_stroke->points; for (j = 0; j < new_stroke->totpoints; j++, pts++) { - pts->time -= delta; + /* Some points have time = 0, so check to not get negative time values.*/ + pts->time = max_ff(pts->time - delta, 0.0f); /* set flag for select again later */ if (select == true) { pts->flag &= ~GP_SPOINT_SELECT; diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c index ac0286d6c36..d5aa97987af 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c @@ -370,7 +370,7 @@ static void build_sequential(Object *ob, } /* Entering subsequent points */ else { - if (cell->gps->points[j].time == 0) { + if (cell->gps->points[j].time <= 0) { idx_times[curpoint] = sumtime; zeropoints++; } From 5320372c34522b1c399049a2014bc770a140dabc Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Mon, 16 Jan 2023 12:23:50 +0100 Subject: [PATCH 0672/1522] User Inteface: Missing separator in Geometry Nodes > Add Node > Geometry menu This separator was missing in the original change in the menus (d4e638baac4). --- release/scripts/startup/bl_ui/node_add_menu_geometry.py | 1 + 1 file changed, 1 insertion(+) diff --git a/release/scripts/startup/bl_ui/node_add_menu_geometry.py b/release/scripts/startup/bl_ui/node_add_menu_geometry.py index f86601da88c..54f667ccef3 100644 --- a/release/scripts/startup/bl_ui/node_add_menu_geometry.py +++ b/release/scripts/startup/bl_ui/node_add_menu_geometry.py @@ -145,6 +145,7 @@ class NODE_MT_geometry_node_GEO_GEOMETRY(Menu): layout = self.layout layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY_READ") layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY_WRITE") + layout.separator() layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS") layout.menu("NODE_MT_geometry_node_GEO_GEOMETRY_SAMPLE") layout.separator() From 154d3e95f862fd680879267b03bb050ffa178d05 Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Mon, 16 Jan 2023 12:40:00 +0100 Subject: [PATCH 0673/1522] Fix: don't set default value for unused socket in geometry nodes Setting the default value resulted in an incorrect tooltip. Differential Revision: https://developer.blender.org/D16957 --- .../blender/nodes/geometry/nodes/node_geo_attribute_capture.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc index a07cd1437d6..3f994805682 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc @@ -147,7 +147,6 @@ static void node_geo_exec(GeoNodeExecParams params) if (!attribute_id) { params.set_output("Geometry", geometry_set); - params.set_default_remaining_outputs(); return; } From 8cc558814d43bcfe67c22eb3826e6a9ab91161db Mon Sep 17 00:00:00 2001 From: Dalai Felinto Date: Mon, 16 Jan 2023 14:39:10 +0100 Subject: [PATCH 0674/1522] Cleanup: make format --- release/scripts/startup/bl_ui/node_add_menu_geometry.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/release/scripts/startup/bl_ui/node_add_menu_geometry.py b/release/scripts/startup/bl_ui/node_add_menu_geometry.py index 54f667ccef3..2554734d903 100644 --- a/release/scripts/startup/bl_ui/node_add_menu_geometry.py +++ b/release/scripts/startup/bl_ui/node_add_menu_geometry.py @@ -72,6 +72,7 @@ class NODE_MT_geometry_node_GEO_CURVE_READ(Menu): node_add_menu.add_node_type(layout, "GeometryNodeInputSplineResolution") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + class NODE_MT_geometry_node_GEO_CURVE_WRITE(Menu): bl_idname = "NODE_MT_geometry_node_GEO_CURVE_WRITE" bl_label = "Write" @@ -153,6 +154,7 @@ class NODE_MT_geometry_node_GEO_GEOMETRY(Menu): node_add_menu.add_node_type(layout, "GeometryNodeGeometryToInstance") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + class NODE_MT_geometry_node_GEO_GEOMETRY_READ(Menu): bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY_READ" bl_label = "Read" @@ -178,6 +180,7 @@ class NODE_MT_geometry_node_GEO_GEOMETRY_WRITE(Menu): node_add_menu.add_node_type(layout, "GeometryNodeSetPosition") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + class NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS(Menu): bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS" bl_label = "Operations" @@ -195,6 +198,7 @@ class NODE_MT_geometry_node_GEO_GEOMETRY_OPERATIONS(Menu): node_add_menu.add_node_type(layout, "GeometryNodeSeparateGeometry") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + class NODE_MT_geometry_node_GEO_GEOMETRY_SAMPLE(Menu): bl_idname = "NODE_MT_geometry_node_GEO_GEOMETRY_SAMPLE" bl_label = "Sample" @@ -507,6 +511,7 @@ class NODE_MT_category_GEO_UTILITIES_ROTATION(Menu): node_add_menu.add_node_type(layout, "FunctionNodeRotateEuler") node_add_menu.draw_assets_for_catalog(layout, self.bl_label) + class NODE_MT_category_GEO_UTILITIES_MATH(Menu): bl_idname = "NODE_MT_category_GEO_UTILITIES_MATH" bl_label = "Math" From debd912bef5ac0ba89eb4adae6756614eb9dfe4f Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Mon, 16 Jan 2023 12:14:27 -0300 Subject: [PATCH 0675/1522] Fix T103906: Crash when canceling transform operation with the mirror options set Caused by rB3b761901b6d6. Some mirror transdata values were not being initialized. --- source/blender/editors/transform/transform_convert_mesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index 5e164dfd8ad..f7ce586df39 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -1563,7 +1563,7 @@ static void createTransEditVerts(bContext *UNUSED(C), TransInfo *t) if (mirror_data.vert_map) { tc->data_mirror_len = mirror_data.mirror_elem_len; - tc->data_mirror = MEM_mallocN(mirror_data.mirror_elem_len * sizeof(*tc->data_mirror), + tc->data_mirror = MEM_callocN(mirror_data.mirror_elem_len * sizeof(*tc->data_mirror), __func__); BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) { From a84a8a528da89677dc16551dbf545eb1891c4c40 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 11 Jan 2023 16:16:21 +0100 Subject: [PATCH 0676/1522] Cycles: remove SSE3 and AVX kernel optimization levels While keeping SSE2, SSE4.1 and AVX2. This does not affect hardware support, it only slightly reduces performance for some older CPUs. To reduce maintenance cost and improve compile times. Differential Revision: https://developer.blender.org/D16978 --- intern/cycles/CMakeLists.txt | 25 +----------------- intern/cycles/blender/addon/properties.py | 2 -- intern/cycles/blender/addon/ui.py | 2 -- intern/cycles/blender/python.cpp | 2 -- intern/cycles/device/cpu/device.cpp | 2 -- intern/cycles/device/cpu/kernel.cpp | 3 +-- intern/cycles/device/cpu/kernel_function.h | 21 +-------------- intern/cycles/kernel/CMakeLists.txt | 7 ----- intern/cycles/kernel/device/cpu/kernel.h | 6 ----- .../cycles/kernel/device/cpu/kernel_avx.cpp | 26 ------------------- .../cycles/kernel/device/cpu/kernel_sse3.cpp | 23 ---------------- intern/cycles/test/CMakeLists.txt | 13 ---------- intern/cycles/util/debug.cpp | 2 -- intern/cycles/util/debug.h | 14 ++-------- intern/cycles/util/optimization.h | 9 ------- intern/cycles/util/system.h | 2 -- 16 files changed, 5 insertions(+), 154 deletions(-) delete mode 100644 intern/cycles/kernel/device/cpu/kernel_avx.cpp delete mode 100644 intern/cycles/kernel/device/cpu/kernel_sse3.cpp diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index 53e87fc5c3a..366d38cc94c 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -85,15 +85,11 @@ elseif(WIN32 AND MSVC AND NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") # there is no /arch:SSE3, but intrinsics are available anyway if(CMAKE_CL_64) set(CYCLES_SSE2_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS}") - set(CYCLES_SSE3_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS}") set(CYCLES_SSE41_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS}") - set(CYCLES_AVX_KERNEL_FLAGS "${CYCLES_AVX_ARCH_FLAGS} ${CYCLES_KERNEL_FLAGS}") set(CYCLES_AVX2_KERNEL_FLAGS "${CYCLES_AVX2_ARCH_FLAGS} ${CYCLES_KERNEL_FLAGS}") else() set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 ${CYCLES_KERNEL_FLAGS}") - set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 ${CYCLES_KERNEL_FLAGS}") set(CYCLES_SSE41_KERNEL_FLAGS "/arch:SSE2 ${CYCLES_KERNEL_FLAGS}") - set(CYCLES_AVX_KERNEL_FLAGS "${CYCLES_AVX_ARCH_FLAGS} ${CYCLES_KERNEL_FLAGS}") set(CYCLES_AVX2_KERNEL_FLAGS "${CYCLES_AVX2_ARCH_FLAGS} ${CYCLES_KERNEL_FLAGS}") endif() @@ -126,11 +122,7 @@ elseif(CMAKE_COMPILER_IS_GNUCC OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) endif() set(CYCLES_SSE2_KERNEL_FLAGS "${CYCLES_KERNEL_FLAGS} -msse -msse2") - set(CYCLES_SSE3_KERNEL_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS} -msse3 -mssse3") - set(CYCLES_SSE41_KERNEL_FLAGS "${CYCLES_SSE3_KERNEL_FLAGS} -msse4.1") - if(CXX_HAS_AVX) - set(CYCLES_AVX_KERNEL_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS} -mavx") - endif() + set(CYCLES_SSE41_KERNEL_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS} -msse3 -mssse3 -msse4.1") if(CXX_HAS_AVX2) set(CYCLES_AVX2_KERNEL_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS} -mavx -mavx2 -mfma -mlzcnt -mbmi -mbmi2 -mf16c") endif() @@ -144,13 +136,8 @@ elseif(WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Intel") if(CXX_HAS_SSE) set(CYCLES_SSE2_KERNEL_FLAGS "/QxSSE2") - set(CYCLES_SSE3_KERNEL_FLAGS "/QxSSSE3") set(CYCLES_SSE41_KERNEL_FLAGS "/QxSSE4.1") - if(CXX_HAS_AVX) - set(CYCLES_AVX_KERNEL_FLAGS "/arch:AVX") - endif() - if(CXX_HAS_AVX2) set(CYCLES_AVX2_KERNEL_FLAGS "/QxCORE-AVX2") endif() @@ -174,13 +161,8 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel") set(CYCLES_SSE2_KERNEL_FLAGS "-xsse2") endif() - set(CYCLES_SSE3_KERNEL_FLAGS "-xssse3") set(CYCLES_SSE41_KERNEL_FLAGS "-xsse4.1") - if(CXX_HAS_AVX) - set(CYCLES_AVX_KERNEL_FLAGS "-xavx") - endif() - if(CXX_HAS_AVX2) set(CYCLES_AVX2_KERNEL_FLAGS "-xcore-avx2") endif() @@ -190,15 +172,10 @@ endif() if(CXX_HAS_SSE) add_definitions( -DWITH_KERNEL_SSE2 - -DWITH_KERNEL_SSE3 -DWITH_KERNEL_SSE41 ) endif() -if(CXX_HAS_AVX) - add_definitions(-DWITH_KERNEL_AVX) -endif() - if(CXX_HAS_AVX2) add_definitions(-DWITH_KERNEL_AVX2) endif() diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 9ec663eb258..9c1cb0a1b4a 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -951,9 +951,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): return _cycles.debug_flags_update(scene) debug_use_cpu_avx2: BoolProperty(name="AVX2", default=True) - debug_use_cpu_avx: BoolProperty(name="AVX", default=True) debug_use_cpu_sse41: BoolProperty(name="SSE41", default=True) - debug_use_cpu_sse3: BoolProperty(name="SSE3", default=True) debug_use_cpu_sse2: BoolProperty(name="SSE2", default=True) debug_bvh_layout: EnumProperty( name="BVH Layout", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 102e014297f..81f940529d1 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -2112,9 +2112,7 @@ class CYCLES_RENDER_PT_debug(CyclesDebugButtonsPanel, Panel): row = col.row(align=True) row.prop(cscene, "debug_use_cpu_sse2", toggle=True) - row.prop(cscene, "debug_use_cpu_sse3", toggle=True) row.prop(cscene, "debug_use_cpu_sse41", toggle=True) - row.prop(cscene, "debug_use_cpu_avx", toggle=True) row.prop(cscene, "debug_use_cpu_avx2", toggle=True) col.prop(cscene, "debug_bvh_layout", text="BVH") diff --git a/intern/cycles/blender/python.cpp b/intern/cycles/blender/python.cpp index 96cb204be4b..ebbdc8abf7f 100644 --- a/intern/cycles/blender/python.cpp +++ b/intern/cycles/blender/python.cpp @@ -63,9 +63,7 @@ static void debug_flags_sync_from_scene(BL::Scene b_scene) PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); /* Synchronize CPU flags. */ flags.cpu.avx2 = get_boolean(cscene, "debug_use_cpu_avx2"); - flags.cpu.avx = get_boolean(cscene, "debug_use_cpu_avx"); flags.cpu.sse41 = get_boolean(cscene, "debug_use_cpu_sse41"); - flags.cpu.sse3 = get_boolean(cscene, "debug_use_cpu_sse3"); flags.cpu.sse2 = get_boolean(cscene, "debug_use_cpu_sse2"); flags.cpu.bvh_layout = (BVHLayout)get_enum(cscene, "debug_bvh_layout"); /* Synchronize CUDA flags. */ diff --git a/intern/cycles/device/cpu/device.cpp b/intern/cycles/device/cpu/device.cpp index 9b249063aec..580f70b25d7 100644 --- a/intern/cycles/device/cpu/device.cpp +++ b/intern/cycles/device/cpu/device.cpp @@ -45,9 +45,7 @@ string device_cpu_capabilities() { string capabilities = ""; capabilities += system_cpu_support_sse2() ? "SSE2 " : ""; - capabilities += system_cpu_support_sse3() ? "SSE3 " : ""; capabilities += system_cpu_support_sse41() ? "SSE41 " : ""; - capabilities += system_cpu_support_avx() ? "AVX " : ""; capabilities += system_cpu_support_avx2() ? "AVX2" : ""; if (capabilities[capabilities.size() - 1] == ' ') capabilities.resize(capabilities.size() - 1); diff --git a/intern/cycles/device/cpu/kernel.cpp b/intern/cycles/device/cpu/kernel.cpp index 3e078129bca..4ca68e875a3 100644 --- a/intern/cycles/device/cpu/kernel.cpp +++ b/intern/cycles/device/cpu/kernel.cpp @@ -9,8 +9,7 @@ CCL_NAMESPACE_BEGIN #define KERNEL_FUNCTIONS(name) \ KERNEL_NAME_EVAL(cpu, name), KERNEL_NAME_EVAL(cpu_sse2, name), \ - KERNEL_NAME_EVAL(cpu_sse3, name), KERNEL_NAME_EVAL(cpu_sse41, name), \ - KERNEL_NAME_EVAL(cpu_avx, name), KERNEL_NAME_EVAL(cpu_avx2, name) + KERNEL_NAME_EVAL(cpu_sse41, name), KERNEL_NAME_EVAL(cpu_avx2, name) #define REGISTER_KERNEL(name) name(KERNEL_FUNCTIONS(name)) #define REGISTER_KERNEL_FILM_CONVERT(name) \ diff --git a/intern/cycles/device/cpu/kernel_function.h b/intern/cycles/device/cpu/kernel_function.h index 6171f582518..4875f66f8a8 100644 --- a/intern/cycles/device/cpu/kernel_function.h +++ b/intern/cycles/device/cpu/kernel_function.h @@ -17,13 +17,10 @@ template class CPUKernelFunction { public: CPUKernelFunction(FunctionType kernel_default, FunctionType kernel_sse2, - FunctionType kernel_sse3, FunctionType kernel_sse41, - FunctionType kernel_avx, FunctionType kernel_avx2) { - kernel_info_ = get_best_kernel_info( - kernel_default, kernel_sse2, kernel_sse3, kernel_sse41, kernel_avx, kernel_avx2); + kernel_info_ = get_best_kernel_info(kernel_default, kernel_sse2, kernel_sse41, kernel_avx2); } template inline auto operator()(Args... args) const @@ -60,16 +57,12 @@ template class CPUKernelFunction { KernelInfo get_best_kernel_info(FunctionType kernel_default, FunctionType kernel_sse2, - FunctionType kernel_sse3, FunctionType kernel_sse41, - FunctionType kernel_avx, FunctionType kernel_avx2) { /* Silence warnings about unused variables when compiling without some architectures. */ (void)kernel_sse2; - (void)kernel_sse3; (void)kernel_sse41; - (void)kernel_avx; (void)kernel_avx2; #ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2 @@ -78,24 +71,12 @@ template class CPUKernelFunction { } #endif -#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_AVX - if (DebugFlags().cpu.has_avx() && system_cpu_support_avx()) { - return KernelInfo("AVX", kernel_avx); - } -#endif - #ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41 if (DebugFlags().cpu.has_sse41() && system_cpu_support_sse41()) { return KernelInfo("SSE4.1", kernel_sse41); } #endif -#ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE3 - if (DebugFlags().cpu.has_sse3() && system_cpu_support_sse3()) { - return KernelInfo("SSE3", kernel_sse3); - } -#endif - #ifdef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2 if (DebugFlags().cpu.has_sse2() && system_cpu_support_sse2()) { return KernelInfo("SSE2", kernel_sse2); diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 5ba1b683d6b..3ae468efd1f 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -14,9 +14,7 @@ set(INC_SYS set(SRC_KERNEL_DEVICE_CPU device/cpu/kernel.cpp device/cpu/kernel_sse2.cpp - device/cpu/kernel_sse3.cpp device/cpu/kernel_sse41.cpp - device/cpu/kernel_avx.cpp device/cpu/kernel_avx2.cpp ) @@ -940,14 +938,9 @@ set_source_files_properties(device/cpu/kernel.cpp PROPERTIES COMPILE_FLAGS "${CY if(CXX_HAS_SSE) set_source_files_properties(device/cpu/kernel_sse2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS}") - set_source_files_properties(device/cpu/kernel_sse3.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE3_KERNEL_FLAGS}") set_source_files_properties(device/cpu/kernel_sse41.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE41_KERNEL_FLAGS}") endif() -if(CXX_HAS_AVX) - set_source_files_properties(device/cpu/kernel_avx.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}") -endif() - if(CXX_HAS_AVX2) set_source_files_properties(device/cpu/kernel_avx2.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}") endif() diff --git a/intern/cycles/kernel/device/cpu/kernel.h b/intern/cycles/kernel/device/cpu/kernel.h index 647b405140a..e43d7375eea 100644 --- a/intern/cycles/kernel/device/cpu/kernel.h +++ b/intern/cycles/kernel/device/cpu/kernel.h @@ -35,15 +35,9 @@ void kernel_global_memory_copy(KernelGlobalsCPU *kg, const char *name, void *mem #define KERNEL_ARCH cpu_sse2 #include "kernel/device/cpu/kernel_arch.h" -#define KERNEL_ARCH cpu_sse3 -#include "kernel/device/cpu/kernel_arch.h" - #define KERNEL_ARCH cpu_sse41 #include "kernel/device/cpu/kernel_arch.h" -#define KERNEL_ARCH cpu_avx -#include "kernel/device/cpu/kernel_arch.h" - #define KERNEL_ARCH cpu_avx2 #include "kernel/device/cpu/kernel_arch.h" diff --git a/intern/cycles/kernel/device/cpu/kernel_avx.cpp b/intern/cycles/kernel/device/cpu/kernel_avx.cpp deleted file mode 100644 index 872ad5ce7e2..00000000000 --- a/intern/cycles/kernel/device/cpu/kernel_avx.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2011-2022 Blender Foundation */ - -/* Optimized CPU kernel entry points. This file is compiled with AVX - * optimization flags and nearly all functions inlined, while kernel.cpp - * is compiled without for other CPU's. */ - -#include "util/optimization.h" - -#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_AVX -# define KERNEL_STUB -#else -/* SSE optimization disabled for now on 32 bit, see bug T36316. */ -# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86))) -# define __KERNEL_SSE__ -# define __KERNEL_SSE2__ -# define __KERNEL_SSE3__ -# define __KERNEL_SSSE3__ -# define __KERNEL_SSE41__ -# define __KERNEL_AVX__ -# endif -#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_AVX */ - -#include "kernel/device/cpu/kernel.h" -#define KERNEL_ARCH cpu_avx -#include "kernel/device/cpu/kernel_arch_impl.h" diff --git a/intern/cycles/kernel/device/cpu/kernel_sse3.cpp b/intern/cycles/kernel/device/cpu/kernel_sse3.cpp deleted file mode 100644 index eb78b61a723..00000000000 --- a/intern/cycles/kernel/device/cpu/kernel_sse3.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 - * Copyright 2011-2022 Blender Foundation */ - -/* Optimized CPU kernel entry points. This file is compiled with SSE3/SSSE3 - * optimization flags and nearly all functions inlined, while kernel.cpp - * is compiled without for other CPU's. */ - -#include "util/optimization.h" - -#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE3 -# define KERNEL_STUB -#else -/* SSE optimization disabled for now on 32 bit, see bug T36316. */ -# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86))) -# define __KERNEL_SSE2__ -# define __KERNEL_SSE3__ -# define __KERNEL_SSSE3__ -# endif -#endif /* WITH_CYCLES_OPTIMIZED_KERNEL_SSE3 */ - -#include "kernel/device/cpu/kernel.h" -#define KERNEL_ARCH cpu_sse3 -#include "kernel/device/cpu/kernel_arch_impl.h" diff --git a/intern/cycles/test/CMakeLists.txt b/intern/cycles/test/CMakeLists.txt index 34e5a4770ea..cdf8f7db0bb 100644 --- a/intern/cycles/test/CMakeLists.txt +++ b/intern/cycles/test/CMakeLists.txt @@ -45,19 +45,6 @@ set(SRC # Disable AVX tests on macOS. Rosetta has problems running them, and other # platforms should be enough to verify AVX operations are implemented correctly. if(NOT APPLE) - if(CXX_HAS_SSE) - list(APPEND SRC - util_float8_sse2_test.cpp - ) - set_source_files_properties(util_float8_avx_test.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_SSE2_KERNEL_FLAGS}") - endif() - - if(CXX_HAS_AVX) - list(APPEND SRC - util_float8_avx_test.cpp - ) - set_source_files_properties(util_float8_avx_test.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX_KERNEL_FLAGS}") - endif() if(CXX_HAS_AVX2) list(APPEND SRC util_float8_avx2_test.cpp diff --git a/intern/cycles/util/debug.cpp b/intern/cycles/util/debug.cpp index 8210e21f951..e7cf7b545b8 100644 --- a/intern/cycles/util/debug.cpp +++ b/intern/cycles/util/debug.cpp @@ -29,9 +29,7 @@ void DebugFlags::CPU::reset() } while (0) CHECK_CPU_FLAGS(avx2, "CYCLES_CPU_NO_AVX2"); - CHECK_CPU_FLAGS(avx, "CYCLES_CPU_NO_AVX"); CHECK_CPU_FLAGS(sse41, "CYCLES_CPU_NO_SSE41"); - CHECK_CPU_FLAGS(sse3, "CYCLES_CPU_NO_SSE3"); CHECK_CPU_FLAGS(sse2, "CYCLES_CPU_NO_SSE2"); #undef STRINGIFY diff --git a/intern/cycles/util/debug.h b/intern/cycles/util/debug.h index ab200649f59..9ee09f08581 100644 --- a/intern/cycles/util/debug.h +++ b/intern/cycles/util/debug.h @@ -26,9 +26,7 @@ class DebugFlags { /* Flags describing which instructions sets are allowed for use. */ bool avx2 = true; - bool avx = true; bool sse41 = true; - bool sse3 = true; bool sse2 = true; /* Check functions to see whether instructions up to the given one @@ -36,19 +34,11 @@ class DebugFlags { */ bool has_avx2() { - return has_avx() && avx2; - } - bool has_avx() - { - return has_sse41() && avx; + return has_sse41() && avx2; } bool has_sse41() { - return has_sse3() && sse41; - } - bool has_sse3() - { - return has_sse2() && sse3; + return has_sse2() && sse41; } bool has_sse2() { diff --git a/intern/cycles/util/optimization.h b/intern/cycles/util/optimization.h index 19b96510c47..b6194dc0382 100644 --- a/intern/cycles/util/optimization.h +++ b/intern/cycles/util/optimization.h @@ -17,9 +17,6 @@ # ifdef WITH_KERNEL_SSE2 # define WITH_CYCLES_OPTIMIZED_KERNEL_SSE2 # endif -# ifdef WITH_KERNEL_SSE3 -# define WITH_CYCLES_OPTIMIZED_KERNEL_SSE3 -# endif /* x86-64 * @@ -30,15 +27,9 @@ /* SSE2 is always available on x86-64 CPUs, so auto enable */ # define __KERNEL_SSE2__ /* no SSE2 kernel on x86-64, part of regular kernel */ -# ifdef WITH_KERNEL_SSE3 -# define WITH_CYCLES_OPTIMIZED_KERNEL_SSE3 -# endif # ifdef WITH_KERNEL_SSE41 # define WITH_CYCLES_OPTIMIZED_KERNEL_SSE41 # endif -# ifdef WITH_KERNEL_AVX -# define WITH_CYCLES_OPTIMIZED_KERNEL_AVX -# endif # ifdef WITH_KERNEL_AVX2 # define WITH_CYCLES_OPTIMIZED_KERNEL_AVX2 # endif diff --git a/intern/cycles/util/system.h b/intern/cycles/util/system.h index 2152b89ed24..66140cabf84 100644 --- a/intern/cycles/util/system.h +++ b/intern/cycles/util/system.h @@ -17,9 +17,7 @@ int system_console_width(); std::string system_cpu_brand_string(); int system_cpu_bits(); bool system_cpu_support_sse2(); -bool system_cpu_support_sse3(); bool system_cpu_support_sse41(); -bool system_cpu_support_avx(); bool system_cpu_support_avx2(); size_t system_physical_ram(); From c66da0b267e6eb46a3cd1c62284658a476e8f5ae Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 16 Jan 2023 17:49:21 +0100 Subject: [PATCH 0677/1522] Docs: change readme.rst to README.md, as Gitea can't render rst --- README.md | 38 ++++++++++++++++++++++++++++++++++++++ readme.rst | 41 ----------------------------------------- 2 files changed, 38 insertions(+), 41 deletions(-) create mode 100644 README.md delete mode 100644 readme.rst diff --git a/README.md b/README.md new file mode 100644 index 00000000000..c1916806d76 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ + + +Blender +======= + +Blender is the free and open source 3D creation suite. +It supports the entirety of the 3D pipeline-modeling, rigging, animation, simulation, rendering, compositing, +motion tracking and video editing. + +![Blender screenshot](https://code.blender.org/wp-content/uploads/2018/12/springrg.jpg "Blender screenshot") + +Project Pages +------------- + +- [Main Website](http://www.blender.org) +- [Reference Manual](https://docs.blender.org/manual/en/latest/index.html) +- [User Community](https://www.blender.org/community/) + +Development +----------- + +- [Build Instructions](https://wiki.blender.org/wiki/Building_Blender) +- [Code Review & Bug Tracker](https://developer.blender.org) +- [Developer Forum](https://devtalk.blender.org) +- [Developer Documentation](https://wiki.blender.org) + + +License +------- + +Blender as a whole is licensed under the GNU General Public License, Version 3. +Individual files may have a different, but compatible license. + +See [blender.org/about/license](https://www.blender.org/about/license) for details. diff --git a/readme.rst b/readme.rst deleted file mode 100644 index 6d03d004be4..00000000000 --- a/readme.rst +++ /dev/null @@ -1,41 +0,0 @@ - -.. Keep this document short & concise, - linking to external resources instead of including content in-line. - See 'release/text/readme.html' for the end user read-me. - - -Blender -======= - -Blender is the free and open source 3D creation suite. -It supports the entirety of the 3D pipeline-modeling, rigging, animation, simulation, rendering, compositing, -motion tracking and video editing. - -.. figure:: https://code.blender.org/wp-content/uploads/2018/12/springrg.jpg - :scale: 50 % - :align: center - - -Project Pages -------------- - -- `Main Website `__ -- `Reference Manual `__ -- `User Community `__ - -Development ------------ - -- `Build Instructions `__ -- `Code Review & Bug Tracker `__ -- `Developer Forum `__ -- `Developer Documentation `__ - - -License -------- - -Blender as a whole is licensed under the GNU General Public License, Version 3. -Individual files may have a different, but compatible license. - -See `blender.org/about/license `__ for details. From b82f7814c4f386c05215d7dc85d526fa10e2b4e1 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Mon, 16 Jan 2023 18:41:06 +0100 Subject: [PATCH 0678/1522] Fix: Draw: Incorrect culling in the new Draw Manager ViewCullingData::corners (vec4) was casted to a BoundingBox (vec3), so the frustum corners were uploaded in the wrong format to the GPU. Now the ViewCullingData::corners are used directly without casting, since the BoundBox API is not really needed. Reviewed By: fclem Differential Revision: https://developer.blender.org/D17008 --- source/blender/draw/intern/draw_view.cc | 58 +++++++++++++------------ source/blender/draw/intern/draw_view.hh | 5 ++- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/source/blender/draw/intern/draw_view.cc b/source/blender/draw/intern/draw_view.cc index 2e303aa9295..82f614f20f2 100644 --- a/source/blender/draw/intern/draw_view.cc +++ b/source/blender/draw/intern/draw_view.cc @@ -24,16 +24,14 @@ void View::sync(const float4x4 &view_mat, const float4x4 &win_mat, int view_id) is_inverted_ = (is_negative_m4(view_mat.ptr()) == is_negative_m4(win_mat.ptr())); - BoundBox &bound_box = *reinterpret_cast(&culling_[view_id].corners); - BoundSphere &bound_sphere = *reinterpret_cast(&culling_[view_id].bound_sphere); - frustum_boundbox_calc(bound_box, view_id); + frustum_boundbox_calc(view_id); frustum_culling_planes_calc(view_id); - frustum_culling_sphere_calc(bound_box, bound_sphere, view_id); + frustum_culling_sphere_calc(view_id); dirty_ = true; } -void View::frustum_boundbox_calc(BoundBox &bbox, int view_id) +void View::frustum_boundbox_calc(int view_id) { /* Extract the 8 corners from a Projection Matrix. */ #if 0 /* Equivalent to this but it has accuracy problems. */ @@ -43,16 +41,18 @@ void View::frustum_boundbox_calc(BoundBox &bbox, int view_id) } #endif + MutableSpan corners = {culling_[view_id].corners, ARRAY_SIZE(culling_[view_id].corners)}; + float left, right, bottom, top, near, far; bool is_persp = data_[view_id].winmat[3][3] == 0.0f; projmat_dimensions(data_[view_id].winmat.ptr(), &left, &right, &bottom, &top, &near, &far); - bbox.vec[0][2] = bbox.vec[3][2] = bbox.vec[7][2] = bbox.vec[4][2] = -near; - bbox.vec[0][0] = bbox.vec[3][0] = left; - bbox.vec[4][0] = bbox.vec[7][0] = right; - bbox.vec[0][1] = bbox.vec[4][1] = bottom; - bbox.vec[7][1] = bbox.vec[3][1] = top; + corners[0][2] = corners[3][2] = corners[7][2] = corners[4][2] = -near; + corners[0][0] = corners[3][0] = left; + corners[4][0] = corners[7][0] = right; + corners[0][1] = corners[4][1] = bottom; + corners[7][1] = corners[3][1] = top; /* Get the coordinates of the far plane. */ if (is_persp) { @@ -63,15 +63,16 @@ void View::frustum_boundbox_calc(BoundBox &bbox, int view_id) top *= sca_far; } - bbox.vec[1][2] = bbox.vec[2][2] = bbox.vec[6][2] = bbox.vec[5][2] = -far; - bbox.vec[1][0] = bbox.vec[2][0] = left; - bbox.vec[6][0] = bbox.vec[5][0] = right; - bbox.vec[1][1] = bbox.vec[5][1] = bottom; - bbox.vec[2][1] = bbox.vec[6][1] = top; + corners[1][2] = corners[2][2] = corners[6][2] = corners[5][2] = -far; + corners[1][0] = corners[2][0] = left; + corners[6][0] = corners[5][0] = right; + corners[1][1] = corners[5][1] = bottom; + corners[2][1] = corners[6][1] = top; /* Transform into world space. */ - for (int i = 0; i < 8; i++) { - mul_m4_v3(data_[view_id].viewinv.ptr(), bbox.vec[i]); + for (float4 &corner : corners) { + mul_m4_v3(data_[view_id].viewinv.ptr(), corner); + corner.w = 1.0; } } @@ -87,19 +88,22 @@ void View::frustum_culling_planes_calc(int view_id) culling_[view_id].planes[2]); /* Normalize. */ - for (int p = 0; p < 6; p++) { - culling_[view_id].planes[p].w /= normalize_v3(culling_[view_id].planes[p]); + for (float4 &plane : culling_[view_id].planes) { + plane.w /= normalize_v3(plane); } } -void View::frustum_culling_sphere_calc(const BoundBox &bbox, BoundSphere &bsphere, int view_id) +void View::frustum_culling_sphere_calc(int view_id) { + BoundSphere &bsphere = *reinterpret_cast(&culling_[view_id].bound_sphere); + Span corners = {culling_[view_id].corners, ARRAY_SIZE(culling_[view_id].corners)}; + /* Extract Bounding Sphere */ if (data_[view_id].winmat[3][3] != 0.0f) { /* Orthographic */ /* The most extreme points on the near and far plane. (normalized device coords). */ - const float *nearpoint = bbox.vec[0]; - const float *farpoint = bbox.vec[6]; + const float *nearpoint = corners[0]; + const float *farpoint = corners[6]; /* just use median point */ mid_v3_v3v3(bsphere.center, farpoint, nearpoint); @@ -113,12 +117,12 @@ void View::frustum_culling_sphere_calc(const BoundBox &bbox, BoundSphere &bspher /* center of each clipping plane */ float mid_min[3], mid_max[3]; - mid_v3_v3v3(mid_min, bbox.vec[3], bbox.vec[4]); - mid_v3_v3v3(mid_max, bbox.vec[2], bbox.vec[5]); + mid_v3_v3v3(mid_min, corners[3], corners[4]); + mid_v3_v3v3(mid_max, corners[2], corners[5]); /* square length of the diagonals of each clipping plane */ - float a_sq = len_squared_v3v3(bbox.vec[3], bbox.vec[4]); - float b_sq = len_squared_v3v3(bbox.vec[2], bbox.vec[5]); + float a_sq = len_squared_v3v3(corners[3], corners[4]); + float b_sq = len_squared_v3v3(corners[2], corners[5]); /* distance squared between clipping planes */ float h_sq = len_squared_v3v3(mid_min, mid_max); @@ -132,7 +136,7 @@ void View::frustum_culling_sphere_calc(const BoundBox &bbox, BoundSphere &bspher interp_v3_v3v3(bsphere.center, mid_min, mid_max, fac); /* distance from the center to one of the points of the far plane (1, 2, 5, 6) */ - bsphere.radius = len_v3v3(bsphere.center, bbox.vec[1]); + bsphere.radius = len_v3v3(bsphere.center, corners[1]); } else { /* Perspective with asymmetrical frustum. */ diff --git a/source/blender/draw/intern/draw_view.hh b/source/blender/draw/intern/draw_view.hh index cded44e5a56..3a3191e2a62 100644 --- a/source/blender/draw/intern/draw_view.hh +++ b/source/blender/draw/intern/draw_view.hh @@ -139,9 +139,10 @@ class View { void update_viewport_size(); - void frustum_boundbox_calc(BoundBox &bbox, int view_id); + /* WARNING: These 3 functions must be called in order */ + void frustum_boundbox_calc(int view_id); void frustum_culling_planes_calc(int view_id); - void frustum_culling_sphere_calc(const BoundBox &bbox, BoundSphere &bsphere, int view_id); + void frustum_culling_sphere_calc(int view_id); }; } // namespace blender::draw From a219507d57f2a9c1e26fbef1675d43536ffde27c Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 16 Jan 2023 12:06:29 -0600 Subject: [PATCH 0679/1522] Cleanup: Add documentation to curve legacy conversion functions --- source/blender/blenkernel/BKE_curve_legacy_convert.hh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/blender/blenkernel/BKE_curve_legacy_convert.hh b/source/blender/blenkernel/BKE_curve_legacy_convert.hh index 88f93282f25..e7996faa0c5 100644 --- a/source/blender/blenkernel/BKE_curve_legacy_convert.hh +++ b/source/blender/blenkernel/BKE_curve_legacy_convert.hh @@ -13,7 +13,14 @@ struct Curves; namespace blender::bke { +/** + * Convert the old curve type to the new data type. Caller owns the returned pointer. + */ Curves *curve_legacy_to_curves(const Curve &curve_legacy); +/** + * Convert the old curve type to the new data type using a specific list of #Nurb for the actual + * geometry data. Caller owns the returned pointer. + */ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_list); } // namespace blender::bke From c55767b32ee15e9deead502f72ba067eb793ff0d Mon Sep 17 00:00:00 2001 From: Mattias Fredriksson Date: Mon, 16 Jan 2023 12:22:20 -0600 Subject: [PATCH 0680/1522] Fix T103632: Single point trim samples curve end point incorrectly Trim erronously samples the next to last control point when it should sample the last control point on the curve. This only happens when reducing the curve to a single point. These changes should correct the behavior. Differential Revision: https://developer.blender.org/D17003 --- source/blender/geometry/intern/trim_curves.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc index 94bd212d70e..361415aa540 100644 --- a/source/blender/geometry/intern/trim_curves.cc +++ b/source/blender/geometry/intern/trim_curves.cc @@ -885,10 +885,15 @@ static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves, if (end_length <= start_length) { /* Single point. */ dst_curve_size[curve_i] = 1; - src_ranges[curve_i] = bke::curves::IndexRangeCyclic::get_range_from_size( - start_points[curve_i].index, - start_points[curve_i].is_controlpoint(), /* Only iterate if control point. */ - point_count); + if (start_points[curve_i].is_controlpoint()) { + /* Only iterate if control point. */ + const int single_point_index = start_points[curve_i].parameter == 1.0f ? + start_points[curve_i].next_index : + start_points[curve_i].index; + src_ranges[curve_i] = bke::curves::IndexRangeCyclic::get_range_from_size( + single_point_index, 1, point_count); + } + /* else: leave empty range */ } else { /* Split. */ From 93ca4eeec135b2c0fe77b70cd982ed0e93e414cf Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 16 Jan 2023 19:40:25 +0100 Subject: [PATCH 0681/1522] Cleanup: remove unused functions --- intern/cycles/util/system.cpp | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/intern/cycles/util/system.cpp b/intern/cycles/util/system.cpp index 3183ac06f26..c1c496380c5 100644 --- a/intern/cycles/util/system.cpp +++ b/intern/cycles/util/system.cpp @@ -204,24 +204,12 @@ bool system_cpu_support_sse2() return caps.sse2; } -bool system_cpu_support_sse3() -{ - CPUCapabilities &caps = system_cpu_capabilities(); - return caps.sse3; -} - bool system_cpu_support_sse41() { CPUCapabilities &caps = system_cpu_capabilities(); return caps.sse41; } -bool system_cpu_support_avx() -{ - CPUCapabilities &caps = system_cpu_capabilities(); - return caps.avx; -} - bool system_cpu_support_avx2() { CPUCapabilities &caps = system_cpu_capabilities(); @@ -234,20 +222,11 @@ bool system_cpu_support_sse2() return false; } -bool system_cpu_support_sse3() -{ - return false; -} - bool system_cpu_support_sse41() { return false; } -bool system_cpu_support_avx() -{ - return false; -} bool system_cpu_support_avx2() { return false; From e0e6afb76604f89ceb68582876addeb2f23e6ca3 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 16 Jan 2023 13:14:03 -0600 Subject: [PATCH 0682/1522] Geometry Nodes: Parallelize mesh and curve edit hint transformation Previously transforming and translating meshes (used by the object info and transform geometry nodes) was single threaded. Now use the same code path as other geometry types which already includes multithreading. I observed a 5x performance improvement for a 4 million vert mesh on a Ryzen 7950x. --- .../nodes/node_geo_transform_geometry.cc | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc index 425546c3406..281ffc768ef 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc @@ -55,13 +55,15 @@ static void transform_positions(MutableSpan positions, const float4x4 &m static void translate_mesh(Mesh &mesh, const float3 translation) { if (!math::is_zero(translation)) { - BKE_mesh_translate(&mesh, translation, false); + translate_positions(mesh.vert_positions_for_write(), translation); + BKE_mesh_tag_coords_changed_uniformly(&mesh); } } static void transform_mesh(Mesh &mesh, const float4x4 &transform) { - BKE_mesh_transform(&mesh, transform.values, false); + transform_positions(mesh.vert_positions_for_write(), transform); + BKE_mesh_tag_coords_changed(&mesh); } static void translate_pointcloud(PointCloud &pointcloud, const float3 translation) @@ -162,16 +164,17 @@ static void translate_volume(GeoNodeExecParams ¶ms, static void transform_curve_edit_hints(bke::CurvesEditHints &edit_hints, const float4x4 &transform) { if (edit_hints.positions.has_value()) { - for (float3 &pos : *edit_hints.positions) { - pos = transform * pos; - } + transform_positions(*edit_hints.positions, transform); } float3x3 deform_mat; copy_m3_m4(deform_mat.values, transform.values); if (edit_hints.deform_mats.has_value()) { - for (float3x3 &mat : *edit_hints.deform_mats) { - mat = deform_mat * mat; - } + MutableSpan deform_mats = *edit_hints.deform_mats; + threading::parallel_for(deform_mats.index_range(), 1024, [&](const IndexRange range) { + for (const int64_t i : range) { + deform_mats[i] = deform_mat * deform_mats[i]; + } + }); } else { edit_hints.deform_mats.emplace(edit_hints.curves_id_orig.geometry.point_num, deform_mat); @@ -181,9 +184,7 @@ static void transform_curve_edit_hints(bke::CurvesEditHints &edit_hints, const f static void translate_curve_edit_hints(bke::CurvesEditHints &edit_hints, const float3 &translation) { if (edit_hints.positions.has_value()) { - for (float3 &pos : *edit_hints.positions) { - pos += translation; - } + translate_positions(*edit_hints.positions, translation); } } From 6f6cc269a4e04d7ce254499ca1982dcec5247bf9 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 16 Jan 2023 14:41:28 -0600 Subject: [PATCH 0683/1522] Cleanup: Move sculpt_dyntopo.c to C++ See T103343 --- .../editors/sculpt_paint/CMakeLists.txt | 2 +- .../{sculpt_dyntopo.c => sculpt_dyntopo.cc} | 83 ++++++++++--------- .../editors/sculpt_paint/sculpt_intern.h | 1 + 3 files changed, 44 insertions(+), 42 deletions(-) rename source/blender/editors/sculpt_paint/{sculpt_dyntopo.c => sculpt_dyntopo.cc} (86%) diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index d1a80e3e068..62a07310106 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -66,7 +66,7 @@ set(SRC sculpt_brush_types.c sculpt_cloth.c sculpt_detail.c - sculpt_dyntopo.c + sculpt_dyntopo.cc sculpt_expand.c sculpt_face_set.cc sculpt_filter_color.c diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.cc similarity index 86% rename from source/blender/editors/sculpt_paint/sculpt_dyntopo.c rename to source/blender/editors/sculpt_paint/sculpt_dyntopo.cc index 56ae10ef791..a77b73ebaae 100644 --- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c +++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.cc @@ -5,9 +5,10 @@ * \ingroup edsculpt */ -#include "MEM_guardedalloc.h" +#include +#include -#include "BLI_task.h" +#include "MEM_guardedalloc.h" #include "BLT_translation.h" @@ -41,14 +42,17 @@ #include "bmesh.h" #include "bmesh_tools.h" -#include -#include - void SCULPT_dynamic_topology_triangulate(BMesh *bm) { if (bm->totloop != bm->totface * 3) { - BM_mesh_triangulate( - bm, MOD_TRIANGULATE_QUAD_BEAUTY, MOD_TRIANGULATE_NGON_EARCLIP, 4, false, NULL, NULL, NULL); + BM_mesh_triangulate(bm, + MOD_TRIANGULATE_QUAD_BEAUTY, + MOD_TRIANGULATE_NGON_EARCLIP, + 4, + false, + nullptr, + nullptr, + nullptr); } } @@ -59,7 +63,7 @@ void SCULPT_pbvh_clear(Object *ob) /* Clear out any existing DM and PBVH. */ if (ss->pbvh) { BKE_pbvh_free(ss->pbvh); - ss->pbvh = NULL; + ss->pbvh = nullptr; } MEM_SAFE_FREE(ss->pmap); @@ -75,7 +79,7 @@ void SCULPT_pbvh_clear(Object *ob) void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob) { SculptSession *ss = ob->sculpt; - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me); SCULPT_pbvh_clear(ob); @@ -87,19 +91,16 @@ void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene BKE_mesh_mselect_clear(me); /* Create triangles-only BMesh. */ - ss->bm = BM_mesh_create(&allocsize, - &((struct BMeshCreateParams){ - .use_toolflags = false, - })); + BMeshCreateParams create_params{}; + create_params.use_toolflags = false; + ss->bm = BM_mesh_create(&allocsize, &create_params); - BM_mesh_bm_from_me(ss->bm, - me, - (&(struct BMeshFromMeshParams){ - .calc_face_normal = true, - .calc_vert_normal = true, - .use_shapekey = true, - .active_shapekey = ob->shapenr, - })); + BMeshFromMeshParams convert_params{}; + convert_params.calc_face_normal = true; + convert_params.calc_vert_normal = true; + convert_params.use_shapekey = true; + convert_params.active_shapekey = ob->shapenr; + BM_mesh_bm_from_me(ss->bm, me, &convert_params); SCULPT_dynamic_topology_triangulate(ss->bm); BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK); @@ -129,7 +130,7 @@ static void SCULPT_dynamic_topology_disable_ex( Main *bmain, Depsgraph *depsgraph, Scene *scene, Object *ob, SculptUndoNode *unode) { SculptSession *ss = ob->sculpt; - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); if (ss->attrs.dyntopo_node_id_vertex) { BKE_sculpt_attribute_destroy(ob, ss->attrs.dyntopo_node_id_vertex); @@ -175,7 +176,7 @@ static void SCULPT_dynamic_topology_disable_ex( /* Sync the visibility to vertices manually as the pmap is still not initialized. */ bool *hide_vert = (bool *)CustomData_get_layer_named_for_write( &me->vdata, CD_PROP_BOOL, ".hide_vert", me->totvert); - if (hide_vert != NULL) { + if (hide_vert != nullptr) { memset(hide_vert, 0, sizeof(bool) * me->totvert); } } @@ -183,14 +184,14 @@ static void SCULPT_dynamic_topology_disable_ex( /* Clear data. */ me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY; - /* Typically valid but with global-undo they can be NULL, see: T36234. */ + /* Typically valid but with global-undo they can be nullptr, see: T36234. */ if (ss->bm) { BM_mesh_free(ss->bm); - ss->bm = NULL; + ss->bm = nullptr; } if (ss->bm_log) { BM_log_free(ss->bm_log); - ss->bm_log = NULL; + ss->bm_log = nullptr; } BKE_particlesystem_reset_all(ob); @@ -217,14 +218,14 @@ void sculpt_dynamic_topology_disable_with_undo(Main *bmain, Object *ob) { SculptSession *ss = ob->sculpt; - if (ss->bm != NULL) { + if (ss->bm != nullptr) { /* May be false in background mode. */ - const bool use_undo = G.background ? (ED_undo_stack_get() != NULL) : true; + const bool use_undo = G.background ? (ED_undo_stack_get() != nullptr) : true; if (use_undo) { SCULPT_undo_push_begin_ex(ob, "Dynamic topology disable"); - SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_END); + SCULPT_undo_push_node(ob, nullptr, SCULPT_UNDO_DYNTOPO_END); } - SCULPT_dynamic_topology_disable_ex(bmain, depsgraph, scene, ob, NULL); + SCULPT_dynamic_topology_disable_ex(bmain, depsgraph, scene, ob, nullptr); if (use_undo) { SCULPT_undo_push_end(ob); } @@ -237,21 +238,21 @@ static void sculpt_dynamic_topology_enable_with_undo(Main *bmain, Object *ob) { SculptSession *ss = ob->sculpt; - if (ss->bm == NULL) { + if (ss->bm == nullptr) { /* May be false in background mode. */ - const bool use_undo = G.background ? (ED_undo_stack_get() != NULL) : true; + const bool use_undo = G.background ? (ED_undo_stack_get() != nullptr) : true; if (use_undo) { SCULPT_undo_push_begin_ex(ob, "Dynamic topology enable"); } SCULPT_dynamic_topology_enable_ex(bmain, depsgraph, scene, ob); if (use_undo) { - SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_DYNTOPO_BEGIN); + SCULPT_undo_push_node(ob, nullptr, SCULPT_UNDO_DYNTOPO_BEGIN); SCULPT_undo_push_end(ob); } } } -static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(op)) +static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator * /*op*/) { Main *bmain = CTX_data_main(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); @@ -269,7 +270,7 @@ static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(o } WM_cursor_wait(false); - WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL); + WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, nullptr); return OPERATOR_FINISHED; } @@ -297,7 +298,7 @@ static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, enum eDynTopoW uiItemS(layout); } - uiItemFullO_ptr(layout, ot, IFACE_("OK"), ICON_NONE, NULL, WM_OP_EXEC_DEFAULT, 0, NULL); + uiItemFullO_ptr(layout, ot, IFACE_("OK"), ICON_NONE, nullptr, WM_OP_EXEC_DEFAULT, 0, nullptr); UI_popup_menu_end(C, pup); @@ -306,12 +307,12 @@ static int dyntopo_warning_popup(bContext *C, wmOperatorType *ot, enum eDynTopoW enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob) { - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); SculptSession *ss = ob->sculpt; - enum eDynTopoWarnFlag flag = 0; + enum eDynTopoWarnFlag flag = eDynTopoWarnFlag(0); - BLI_assert(ss->bm == NULL); + BLI_assert(ss->bm == nullptr); UNUSED_VARS_NDEBUG(ss); for (int i = 0; i < CD_NUMTYPES; i++) { @@ -334,7 +335,7 @@ enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob) /* Exception for shape keys because we can edit those. */ for (; md; md = md->next) { - const ModifierTypeInfo *mti = BKE_modifier_get_info(md->type); + const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type)); if (!BKE_modifier_is_enabled(scene, md, eModifierMode_Realtime)) { continue; } @@ -351,7 +352,7 @@ enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob) static int sculpt_dynamic_topology_toggle_invoke(bContext *C, wmOperator *op, - const wmEvent *UNUSED(event)) + const wmEvent * /*event*/) { Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 700fba4cd40..dc487aeeb9f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -1303,6 +1303,7 @@ enum eDynTopoWarnFlag { DYNTOPO_WARN_LDATA = (1 << 2), DYNTOPO_WARN_MODIFIER = (1 << 3), }; +ENUM_OPERATORS(eDynTopoWarnFlag, DYNTOPO_WARN_MODIFIER); /** Enable dynamic topology; mesh will be triangulated */ void SCULPT_dynamic_topology_enable_ex(struct Main *bmain, From 39c6953462d9652ad54952100dc83a32e925553d Mon Sep 17 00:00:00 2001 From: Colin Basnett Date: Mon, 16 Jan 2023 12:54:25 -0800 Subject: [PATCH 0684/1522] UI: Fix alignment of custom properties edit & remove buttons This fixes the UI alignment issues that were introduced by {D12815} with the addition of the boolean custom properties. Reviewed By: HooglyBoogly Differential Revision: https://developer.blender.org/D17012 --- release/scripts/modules/rna_prop_ui.py | 1 + 1 file changed, 1 insertion(+) diff --git a/release/scripts/modules/rna_prop_ui.py b/release/scripts/modules/rna_prop_ui.py index f6c01bde9cd..8b889d8ca4b 100644 --- a/release/scripts/modules/rna_prop_ui.py +++ b/release/scripts/modules/rna_prop_ui.py @@ -181,6 +181,7 @@ def draw(layout, context, context_member, property_type, *, use_edit=True): value_column.prop(rna_item, '["%s"]' % escape_identifier(key), text="") operator_row = value_row.row() + operator_row.alignment = 'RIGHT' # Do not allow editing of overridden properties (we cannot use a poll function # of the operators here since they's have no access to the specific property). From 6d12d43a054898bbffbe18912e3252652d551362 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 16 Jan 2023 15:08:14 -0600 Subject: [PATCH 0685/1522] Mesh: Skip conversion from legacy data if reading new format Under some circumstances (loading autosaves), we end up reading from files that were saved with the new mesh format (after T95965). When that happens we should skip the conversion from the old format to avoid data-loss. This will also give forward compatibility when we stop saving in the old format completely in 4.0. Here I mostly just check if the attributes in the new format already exist. Along with checking for the null status of `Mesh::mvert`, that should cover the majority of cases. Fixes T103878 Differential Revision: https://developer.blender.org/D17011 --- .../blenkernel/intern/mesh_legacy_convert.cc | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index 0f95158e430..be68bfe7c65 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -1239,6 +1239,9 @@ void BKE_mesh_legacy_face_set_from_generic(Mesh *mesh, void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh) { using namespace blender; + if (mesh->attributes().contains(".sculpt_face_set")) { + return; + } for (CustomDataLayer &layer : MutableSpan(mesh->pdata.layers, mesh->pdata.totlayer)) { if (layer.type == CD_SCULPT_FACE_SETS) { BLI_strncpy(layer.name, ".sculpt_face_set", sizeof(layer.name)); @@ -1290,21 +1293,25 @@ void BKE_mesh_legacy_bevel_weight_from_layers(Mesh *mesh) void BKE_mesh_legacy_bevel_weight_to_layers(Mesh *mesh) { using namespace blender; - const Span verts(mesh->mvert, mesh->totvert); - if (mesh->cd_flag & ME_CDFLAG_VERT_BWEIGHT) { - float *weights = static_cast( - CustomData_add_layer(&mesh->vdata, CD_BWEIGHT, CD_CONSTRUCT, nullptr, verts.size())); - for (const int i : verts.index_range()) { - weights[i] = verts[i].bweight_legacy / 255.0f; + if (mesh->mvert && !CustomData_has_layer(&mesh->vdata, CD_BWEIGHT)) { + const Span verts(mesh->mvert, mesh->totvert); + if (mesh->cd_flag & ME_CDFLAG_VERT_BWEIGHT) { + float *weights = static_cast( + CustomData_add_layer(&mesh->vdata, CD_BWEIGHT, CD_CONSTRUCT, nullptr, verts.size())); + for (const int i : verts.index_range()) { + weights[i] = verts[i].bweight_legacy / 255.0f; + } } } const Span edges = mesh->edges(); - if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) { - float *weights = static_cast( - CustomData_add_layer(&mesh->edata, CD_BWEIGHT, CD_CONSTRUCT, nullptr, edges.size())); - for (const int i : edges.index_range()) { - weights[i] = edges[i].bweight_legacy / 255.0f; + if (!CustomData_has_layer(&mesh->edata, CD_BWEIGHT)) { + if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) { + float *weights = static_cast( + CustomData_add_layer(&mesh->edata, CD_BWEIGHT, CD_CONSTRUCT, nullptr, edges.size())); + for (const int i : edges.index_range()) { + weights[i] = edges[i].bweight_legacy / 255.0f; + } } } } @@ -1337,6 +1344,9 @@ void BKE_mesh_legacy_edge_crease_from_layers(Mesh *mesh) void BKE_mesh_legacy_edge_crease_to_layers(Mesh *mesh) { using namespace blender; + if (CustomData_has_layer(&mesh->edata, CD_CREASE)) { + return; + } const Span edges = mesh->edges(); if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) { float *creases = static_cast( @@ -1376,6 +1386,9 @@ void BKE_mesh_legacy_sharp_edges_from_flags(Mesh *mesh) using namespace blender::bke; const Span edges = mesh->edges(); MutableAttributeAccessor attributes = mesh->attributes_for_write(); + if (attributes.contains("sharp_edge")) { + return; + } if (std::any_of( edges.begin(), edges.end(), [](const MEdge &edge) { return edge.flag & ME_SHARP; })) { SpanAttributeWriter sharp_edges = attributes.lookup_or_add_for_write_only_span( @@ -1434,7 +1447,10 @@ void BKE_mesh_legacy_convert_flags_to_hide_layers(Mesh *mesh) using namespace blender; using namespace blender::bke; MutableAttributeAccessor attributes = mesh->attributes_for_write(); - + if (!mesh->mvert || attributes.contains(".hide_vert") || attributes.contains(".hide_edge") || + attributes.contains(".hide_poly")) { + return; + } const Span verts(mesh->mvert, mesh->totvert); if (std::any_of(verts.begin(), verts.end(), [](const MVert &vert) { return vert.flag_legacy & ME_HIDE; @@ -1502,6 +1518,9 @@ void BKE_mesh_legacy_convert_mpoly_to_material_indices(Mesh *mesh) using namespace blender; using namespace blender::bke; MutableAttributeAccessor attributes = mesh->attributes_for_write(); + if (attributes.contains("material_index")) { + return; + } const Span polys = mesh->polys(); if (std::any_of( polys.begin(), polys.end(), [](const MPoly &poly) { return poly.mat_nr_legacy != 0; })) { @@ -1737,6 +1756,10 @@ void BKE_mesh_legacy_convert_flags_to_selection_layers(Mesh *mesh) using namespace blender; using namespace blender::bke; MutableAttributeAccessor attributes = mesh->attributes_for_write(); + if (!mesh->mvert || attributes.contains(".select_vert") || attributes.contains(".select_edge") || + attributes.contains(".select_poly")) { + return; + } const Span verts(mesh->mvert, mesh->totvert); if (std::any_of(verts.begin(), verts.end(), [](const MVert &vert) { @@ -1840,6 +1863,9 @@ void BKE_mesh_legacy_convert_verts_to_positions(Mesh *mesh) { using namespace blender; using namespace blender::bke; + if (!mesh->mvert || CustomData_get_layer_named(&mesh->vdata, CD_PROP_FLOAT3, "position")) { + return; + } const Span verts(static_cast(CustomData_get_layer(&mesh->vdata, CD_MVERT)), mesh->totvert); From 70260960994d6cce3a33dfc16b4911a6cab9d4f2 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 16 Jan 2023 15:47:10 -0600 Subject: [PATCH 0686/1522] Nodes: Use dynamic declarations for group nodes Since a year and a half ago we've been switching to a new way to represent what sockets a node should have called "declarations" that's easier to use, clearer, and more flexible for upcoming features like dynamic socket counts or generic type sockets. All builtin nodes with a static set of sockets have switched, but one missing area has been group nodes and group input/output nodes. These nodes have **dynamic** declarations which change based on their properties or the group they're inside of. This patch addresses that, in preparation for using the same dynamic declaration feature for simulation nodes. Generally there shouldn't be user-visible differences, but one benefit is that user-created socket descriptions are now visible directly in the node editor for group nodes and group input/output nodes. The commit contains a few changes: - Add a node type callback for building dynamic declarations with different arguments - Add an `Extend` socket declaration for the "virtual" sockets used for connecting new links - A similar `Custom` socket declaration is used for addon-defined socket - Simplify the node update loop to use the declaration to build update sockets - Replace the "group update" functions with the declaration building - Move the node group input/output link creation to link drag operator - Make the field status part of group node declarations (not for group input/output nodes though) - Some fixes for declarations to make them update and build properly Differential Revision: https://developer.blender.org/D16850 --- source/blender/blenkernel/BKE_node.h | 23 +- source/blender/blenkernel/intern/node.cc | 6 +- .../blenkernel/intern/node_tree_update.cc | 36 +- .../editors/space_node/link_drag_search.cc | 3 +- .../blender/editors/space_node/node_group.cc | 40 +- .../editors/space_node/node_relationships.cc | 8 +- source/blender/makesrna/intern/rna_nodetree.c | 9 +- source/blender/nodes/NOD_common.h | 16 +- source/blender/nodes/NOD_node_declaration.hh | 9 + source/blender/nodes/NOD_socket.h | 10 + .../blender/nodes/NOD_socket_declarations.hh | 31 ++ .../composite/nodes/node_composite_common.cc | 2 +- .../nodes/geometry/nodes/node_geo_common.cc | 32 +- source/blender/nodes/intern/node_common.cc | 430 ++++++++---------- .../blender/nodes/intern/node_declaration.cc | 9 + source/blender/nodes/intern/node_socket.cc | 79 ++-- .../nodes/intern/node_socket_declarations.cc | 116 +++++ source/blender/nodes/intern/node_util.cc | 11 +- source/blender/nodes/intern/node_util.h | 2 +- .../nodes/intern/socket_search_link.cc | 5 +- .../nodes/shader/nodes/node_shader_common.cc | 2 +- .../texture/nodes/node_texture_common.cc | 2 +- 22 files changed, 510 insertions(+), 371 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index c99f5cb076e..c40839361e2 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -104,6 +104,7 @@ namespace nodes { class DNode; class NodeMultiFunctionBuilder; class GeoNodeExecParams; +class NodeDeclaration; class NodeDeclarationBuilder; class GatherLinkSearchOpParams; } // namespace nodes @@ -118,6 +119,9 @@ using CPPTypeHandle = blender::CPPType; using NodeMultiFunctionBuildFunction = void (*)(blender::nodes::NodeMultiFunctionBuilder &builder); using NodeGeometryExecFunction = void (*)(blender::nodes::GeoNodeExecParams params); using NodeDeclareFunction = void (*)(blender::nodes::NodeDeclarationBuilder &builder); +using NodeDeclareDynamicFunction = void (*)(const bNodeTree &tree, + const bNode &node, + blender::nodes::NodeDeclaration &r_declaration); using SocketGetCPPValueFunction = void (*)(const struct bNodeSocket &socket, void *r_value); using SocketGetGeometryNodesCPPValueFunction = void (*)(const struct bNodeSocket &socket, void *r_value); @@ -137,6 +141,7 @@ typedef void *NodeGetCompositorShaderNodeFunction; typedef void *NodeMultiFunctionBuildFunction; typedef void *NodeGeometryExecFunction; typedef void *NodeDeclareFunction; +typedef void *NodeDeclareDynamicFunction; typedef void *NodeGatherSocketLinkOperationsFunction; typedef void *SocketGetCPPTypeFunction; typedef void *SocketGetGeometryNodesCPPTypeFunction; @@ -173,11 +178,6 @@ typedef struct bNodeSocketType { struct bNode *node, struct bNodeSocket *sock, const char *data_path); - void (*interface_verify_socket)(struct bNodeTree *ntree, - const struct bNodeSocket *interface_socket, - struct bNode *node, - struct bNodeSocket *sock, - const char *data_path); void (*interface_from_socket)(struct bNodeTree *ntree, struct bNodeSocket *interface_socket, const struct bNode *node, @@ -306,8 +306,8 @@ typedef struct bNodeType { const struct bNodeTree *nodetree, const char **r_disabled_hint); - /* optional handling of link insertion */ - void (*insert_link)(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link); + /* optional handling of link insertion. Returns false if the link shouldn't be created. */ + bool (*insert_link)(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link); void (*free_self)(struct bNodeType *ntype); @@ -344,8 +344,13 @@ typedef struct bNodeType { /* Declares which sockets the node has. */ NodeDeclareFunction declare; - /* Different nodes of this type can have different declarations. */ - bool declaration_is_dynamic; + /** + * Declare which sockets the node has for declarations that aren't static per node type. + * In other words, defining this callback means that different nodes of this type can have + * different declarations and different sockets. + */ + NodeDeclareDynamicFunction declare_dynamic; + /* Declaration to be used when it is not dynamic. */ NodeDeclarationHandle *fixed_declaration; diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 9c2ac298fd2..cb650c038e4 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -1378,7 +1378,7 @@ void nodeRegisterType(bNodeType *nt) BLI_assert(nt->idname[0] != '\0'); BLI_assert(nt->poll != nullptr); - if (nt->declare && !nt->declaration_is_dynamic) { + if (nt->declare && !nt->declare_dynamic) { if (nt->fixed_declaration == nullptr) { nt->fixed_declaration = new blender::nodes::NodeDeclaration(); blender::nodes::build_node_declaration(*nt, *nt->fixed_declaration); @@ -2990,7 +2990,7 @@ void node_free_node(bNodeTree *ntree, bNode *node) MEM_freeN(node->prop); } - if (node->typeinfo->declaration_is_dynamic) { + if (node->typeinfo->declare_dynamic) { delete node->runtime->declaration; } @@ -3602,7 +3602,7 @@ bool nodeDeclarationEnsureOnOutdatedNode(bNodeTree * /*ntree*/, bNode *node) if (node->typeinfo->declare == nullptr) { return false; } - if (node->typeinfo->declaration_is_dynamic) { + if (node->typeinfo->declare_dynamic) { node->runtime->declaration = new blender::nodes::NodeDeclaration(); blender::nodes::build_node_declaration(*node->typeinfo, *node->runtime->declaration); } diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc index 397556e23fc..2943bea830b 100644 --- a/source/blender/blenkernel/intern/node_tree_update.cc +++ b/source/blender/blenkernel/intern/node_tree_update.cc @@ -22,6 +22,7 @@ #include "MOD_nodes.h" #include "NOD_node_declaration.hh" +#include "NOD_socket.h" #include "NOD_texture.h" #include "DEG_depsgraph_query.h" @@ -538,7 +539,6 @@ class NodeTreeMainUpdater { void update_individual_nodes(bNodeTree &ntree) { - Vector group_inout_nodes; for (bNode *node : ntree.all_nodes()) { nodeDeclarationEnsure(&ntree, node); if (this->should_update_individual_node(ntree, *node)) { @@ -549,18 +549,9 @@ class NodeTreeMainUpdater { if (ntype.updatefunc) { ntype.updatefunc(&ntree, node); } - } - if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) { - group_inout_nodes.append(node); - } - } - /* The update function of group input/output nodes may add new interface sockets. When that - * happens, all the input/output nodes have to be updated again. In the future it would be - * better to move this functionality out of the node update function into the operator that's - * supposed to create the new interface socket. */ - if (ntree.runtime->changed_flag & NTREE_CHANGED_INTERFACE) { - for (bNode *node : group_inout_nodes) { - node->typeinfo->updatefunc(&ntree, node); + if (ntype.declare_dynamic) { + nodes::update_node_declaration_and_sockets(ntree, *node); + } } } } @@ -574,23 +565,8 @@ class NodeTreeMainUpdater { return true; } if (ntree.runtime->changed_flag & NTREE_CHANGED_LINK) { - ntree.ensure_topology_cache(); - /* Node groups currently always rebuilt their sockets when they are updated. - * So avoid calling the update method when no new link was added to it. */ - if (node.type == NODE_GROUP_INPUT) { - if (node.output_sockets().last()->is_directly_linked()) { - return true; - } - } - else if (node.type == NODE_GROUP_OUTPUT) { - if (node.input_sockets().last()->is_directly_linked()) { - return true; - } - } - else { - /* Currently we have no way to tell if a node needs to be updated when a link changed. */ - return true; - } + /* Currently we have no way to tell if a node needs to be updated when a link changed. */ + return true; } if (ntree.runtime->changed_flag & NTREE_CHANGED_INTERFACE) { if (ELEM(node.type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) { diff --git a/source/blender/editors/space_node/link_drag_search.cc b/source/blender/editors/space_node/link_drag_search.cc index 08d9f6ecc4f..73be1a58a86 100644 --- a/source/blender/editors/space_node/link_drag_search.cc +++ b/source/blender/editors/space_node/link_drag_search.cc @@ -13,6 +13,7 @@ #include "BKE_node_tree_update.h" #include "BKE_screen.h" +#include "NOD_socket.h" #include "NOD_socket_search_link.hh" #include "BLT_translation.h" @@ -198,7 +199,7 @@ static void search_link_ops_for_asset_metadata(const bNodeTree &node_tree, DEG_relations_tag_update(&bmain); /* Create the inputs and outputs on the new node. */ - node.typeinfo->group_update_func(¶ms.node_tree, &node); + nodes::update_node_declaration_and_sockets(params.node_tree, node); bNodeSocket *new_node_socket = bke::node_find_enabled_socket( node, in_out, socket_property->name); diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc index d89600cca0b..ca0361e82dc 100644 --- a/source/blender/editors/space_node/node_group.cc +++ b/source/blender/editors/space_node/node_group.cc @@ -933,9 +933,9 @@ static void node_group_make_insert_selected(const bContext &C, } nodeRebuildIDVector(&ntree); - node_group_update(&ntree, gnode); - node_group_input_update(&group, input_node); - node_group_output_update(&group, output_node); + /* Update input and output node first, since the group node declaration can depend on them. */ + nodes::update_node_declaration_and_sockets(group, *input_node); + nodes::update_node_declaration_and_sockets(group, *output_node); /* move nodes in the group to the center */ for (bNode *node : nodes_to_move) { @@ -956,6 +956,7 @@ static void node_group_make_insert_selected(const bContext &C, nodeRemLink(&ntree, link); } + /* Handle links to the new group inputs. */ for (const auto item : input_links.items()) { const char *interface_identifier = item.value.interface_socket->identifier; bNodeSocket *input_socket = node_group_input_find_socket(input_node, interface_identifier); @@ -969,23 +970,17 @@ static void node_group_make_insert_selected(const bContext &C, link->fromnode = input_node; link->fromsock = input_socket; } - - /* Add a new link outside of the group. */ - bNodeSocket *group_node_socket = node_group_find_input_socket(gnode, interface_identifier); - nodeAddLink(&ntree, item.value.from_node, item.key, gnode, group_node_socket); } + /* Handle links to new group outputs. */ for (const OutputLinkInfo &info : output_links) { /* Create a new link inside of the group. */ const char *io_identifier = info.interface_socket->identifier; bNodeSocket *output_sock = node_group_output_find_socket(output_node, io_identifier); nodeAddLink(&group, info.link->fromnode, info.link->fromsock, output_node, output_sock); - - /* Reconnect the link to the group node instead of the node now inside the group. */ - info.link->fromnode = gnode; - info.link->fromsock = node_group_find_output_socket(gnode, io_identifier); } + /* Handle new links inside the group. */ for (const NewInternalLinkInfo &info : new_internal_links) { const char *io_identifier = info.interface_socket->identifier; if (info.socket->in_out == SOCK_IN) { @@ -997,6 +992,25 @@ static void node_group_make_insert_selected(const bContext &C, nodeAddLink(&group, info.node, info.socket, output_node, output_socket); } } + + bke::node_field_inferencing::update_field_inferencing(group); + nodes::update_node_declaration_and_sockets(ntree, *gnode); + + /* Add new links to inputs outside of the group. */ + for (const auto item : input_links.items()) { + const char *interface_identifier = item.value.interface_socket->identifier; + bNodeSocket *group_node_socket = node_group_find_input_socket(gnode, interface_identifier); + nodeAddLink(&ntree, item.value.from_node, item.key, gnode, group_node_socket); + } + + /* Add new links to outputs outside the group. */ + for (const OutputLinkInfo &info : output_links) { + /* Reconnect the link to the group node instead of the node now inside the group. */ + info.link->fromnode = gnode; + info.link->fromsock = node_group_find_output_socket(gnode, info.interface_socket->identifier); + } + + ED_node_tree_propagate_change(&C, bmain, nullptr); } static bNode *node_group_make_from_nodes(const bContext &C, @@ -1051,8 +1065,6 @@ static int node_group_make_exec(bContext *C, wmOperator *op) } } - ED_node_tree_propagate_change(C, bmain, nullptr); - WM_event_add_notifier(C, NC_NODE | NA_ADDED, nullptr); /* We broke relations in node tree, need to rebuild them in the graphs. */ @@ -1105,7 +1117,6 @@ static int node_group_insert_exec(bContext *C, wmOperator *op) SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree = snode->edittree; const char *node_idname = node_group_idname(C); - Main *bmain = CTX_data_main(C); ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); @@ -1137,7 +1148,6 @@ static int node_group_insert_exec(bContext *C, wmOperator *op) nodeSetActive(ntree, gnode); ED_node_tree_push(snode, ngroup, gnode); - ED_node_tree_propagate_change(C, bmain, nullptr); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index c3ed050e8e4..e012d7b6da4 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -902,10 +902,14 @@ static void add_dragged_links_to_tree(bContext &C, bNodeLinkDrag &nldrag) /* Before actually adding the link let nodes perform special link insertion handling. */ bNodeLink *new_link = MEM_new(__func__, link); if (link.fromnode->typeinfo->insert_link) { - link.fromnode->typeinfo->insert_link(&ntree, link.fromnode, new_link); + if (!link.fromnode->typeinfo->insert_link(&ntree, link.fromnode, new_link)) { + continue; + } } if (link.tonode->typeinfo->insert_link) { - link.tonode->typeinfo->insert_link(&ntree, link.tonode, new_link); + if (!link.tonode->typeinfo->insert_link(&ntree, link.tonode, new_link)) { + continue; + } } /* Add link to the node tree. */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index b41073393b7..eeb88be0fe2 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -1738,7 +1738,7 @@ static void rna_Node_update_reg(bNodeTree *ntree, bNode *node) RNA_parameter_list_free(&list); } -static void rna_Node_insert_link(bNodeTree *ntree, bNode *node, bNodeLink *link) +static bool rna_Node_insert_link(bNodeTree *ntree, bNode *node, bNodeLink *link) { extern FunctionRNA rna_Node_insert_link_func; @@ -1754,6 +1754,7 @@ static void rna_Node_insert_link(bNodeTree *ntree, bNode *node, bNodeLink *link) node->typeinfo->rna_ext.call(NULL, &ptr, func, &list); RNA_parameter_list_free(&list); + return true; } static void rna_Node_init(const bContext *C, PointerRNA *ptr) @@ -3386,9 +3387,6 @@ static StructRNA *rna_NodeCustomGroup_register(Main *bmain, return NULL; } - /* this updates the group node instance from the tree's interface */ - nt->group_update_func = node_group_update; - nodeRegisterType(nt); /* update while blender is running */ @@ -3412,7 +3410,6 @@ static StructRNA *rna_GeometryNodeCustomGroup_register(Main *bmain, return NULL; } - nt->group_update_func = node_group_update; nt->type = NODE_CUSTOM_GROUP; register_node_type_geo_custom_group(nt); @@ -3441,7 +3438,6 @@ static StructRNA *rna_ShaderNodeCustomGroup_register(Main *bmain, return NULL; } - nt->group_update_func = node_group_update; nt->type = NODE_CUSTOM_GROUP; register_node_type_sh_custom_group(nt); @@ -3467,7 +3463,6 @@ static StructRNA *rna_CompositorNodeCustomGroup_register(Main *bmain, return NULL; } - nt->group_update_func = node_group_update; nt->type = NODE_CUSTOM_GROUP; register_node_type_cmp_custom_group(nt); diff --git a/source/blender/nodes/NOD_common.h b/source/blender/nodes/NOD_common.h index ecc5fe54071..7b6244042f8 100644 --- a/source/blender/nodes/NOD_common.h +++ b/source/blender/nodes/NOD_common.h @@ -17,16 +17,24 @@ extern "C" { struct bNodeSocket *node_group_find_input_socket(struct bNode *groupnode, const char *identifier); struct bNodeSocket *node_group_find_output_socket(struct bNode *groupnode, const char *identifier); -/** Make sure all group node in ntree, which use ngroup, are sync'd. */ -void node_group_update(struct bNodeTree *ntree, struct bNode *node); struct bNodeSocket *node_group_input_find_socket(struct bNode *node, const char *identifier); struct bNodeSocket *node_group_output_find_socket(struct bNode *node, const char *identifier); -void node_group_input_update(struct bNodeTree *ntree, struct bNode *node); -void node_group_output_update(struct bNodeTree *ntree, struct bNode *node); void node_internal_links_create(struct bNodeTree *ntree, struct bNode *node); #ifdef __cplusplus } #endif + +#ifdef __cplusplus + +namespace blender::nodes { + +void node_group_declare_dynamic(const bNodeTree &node_tree, + const bNode &node, + NodeDeclaration &r_declaration); + +} // namespace blender::nodes + +#endif diff --git a/source/blender/nodes/NOD_node_declaration.hh b/source/blender/nodes/NOD_node_declaration.hh index 8a7606df777..e58c4138f40 100644 --- a/source/blender/nodes/NOD_node_declaration.hh +++ b/source/blender/nodes/NOD_node_declaration.hh @@ -160,6 +160,7 @@ class SocketDeclaration { InputSocketFieldType input_field_type = InputSocketFieldType::None; OutputFieldDependency output_field_dependency; + private: /** The priority of the input for determining the domain of the node. See * realtime_compositor::InputDescriptor for more information. */ int compositor_domain_priority_ = 0; @@ -461,6 +462,11 @@ class NodeDeclaration { Vector outputs; std::unique_ptr anonymous_attribute_relations_; + /** Leave the sockets in place, even if they don't match the declaration. Used for dynamic + * declarations when the information used to build the declaration is missing, but might become + * available again in the future. */ + bool skip_updating_sockets = false; + friend NodeDeclarationBuilder; bool matches(const bNode &node) const; @@ -523,6 +529,9 @@ void id_or_index(const bNode &node, void *r_value); } // namespace implicit_field_inputs void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declaration); +void build_node_declaration_dynamic(const bNodeTree &node_tree, + const bNode &node, + NodeDeclaration &r_declaration); template typename SocketDeclarationBuilder::Self &SocketDeclarationBuilder< diff --git a/source/blender/nodes/NOD_socket.h b/source/blender/nodes/NOD_socket.h index b456797031c..a803014f8cd 100644 --- a/source/blender/nodes/NOD_socket.h +++ b/source/blender/nodes/NOD_socket.h @@ -36,3 +36,13 @@ void register_standard_node_socket_types(void); #ifdef __cplusplus } #endif + +#ifdef __cplusplus + +namespace blender::nodes { + +void update_node_declaration_and_sockets(bNodeTree &ntree, bNode &node); + +} // namespace blender::nodes + +#endif diff --git a/source/blender/nodes/NOD_socket_declarations.hh b/source/blender/nodes/NOD_socket_declarations.hh index 9ddbacdad0c..cac4e63a100 100644 --- a/source/blender/nodes/NOD_socket_declarations.hh +++ b/source/blender/nodes/NOD_socket_declarations.hh @@ -104,6 +104,7 @@ class Bool : public SocketDeclaration { bNodeSocket &build(bNodeTree &ntree, bNode &node) const override; bool matches(const bNodeSocket &socket) const override; + bNodeSocket &update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const override; bool can_connect(const bNodeSocket &socket) const override; }; @@ -124,6 +125,7 @@ class Color : public SocketDeclaration { bNodeSocket &build(bNodeTree &ntree, bNode &node) const override; bool matches(const bNodeSocket &socket) const override; + bNodeSocket &update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const override; bool can_connect(const bNodeSocket &socket) const override; }; @@ -144,6 +146,7 @@ class String : public SocketDeclaration { bNodeSocket &build(bNodeTree &ntree, bNode &node) const override; bool matches(const bNodeSocket &socket) const override; + bNodeSocket &update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const override; bool can_connect(const bNodeSocket &socket) const override; }; @@ -216,6 +219,34 @@ class Shader : public SocketDeclaration { class ShaderBuilder : public SocketDeclarationBuilder { }; +class ExtendBuilder; + +class Extend : public SocketDeclaration { + private: + friend ExtendBuilder; + + public: + using Builder = ExtendBuilder; + + bNodeSocket &build(bNodeTree &ntree, bNode &node) const override; + bool matches(const bNodeSocket &socket) const override; + bNodeSocket &update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const override; + bool can_connect(const bNodeSocket &socket) const override; +}; + +class ExtendBuilder : public SocketDeclarationBuilder { +}; + +class Custom : public SocketDeclaration { + public: + const char *idname_; + + bNodeSocket &build(bNodeTree &ntree, bNode &node) const override; + bool matches(const bNodeSocket &socket) const override; + bNodeSocket &update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const override; + bool can_connect(const bNodeSocket &socket) const override; +}; + /* -------------------------------------------------------------------- */ /** \name #FloatBuilder Inline Methods * \{ */ diff --git a/source/blender/nodes/composite/nodes/node_composite_common.cc b/source/blender/nodes/composite/nodes/node_composite_common.cc index cd119684a79..5c3a2c87b9f 100644 --- a/source/blender/nodes/composite/nodes/node_composite_common.cc +++ b/source/blender/nodes/composite/nodes/node_composite_common.cc @@ -32,7 +32,7 @@ void register_node_type_cmp_group() node_type_size(&ntype, 140, 60, 400); ntype.labelfunc = node_group_label; - ntype.group_update_func = node_group_update; + ntype.declare_dynamic = blender::nodes::node_group_declare_dynamic; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_common.cc b/source/blender/nodes/geometry/nodes/node_geo_common.cc index 90fb7e10570..6830d819b34 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_common.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_common.cc @@ -3,11 +3,41 @@ #include "BKE_node.h" #include "NOD_geometry.h" +#include "NOD_node_declaration.hh" #include "NOD_common.h" #include "node_common.h" #include "node_geometry_util.hh" +namespace blender::nodes { + +static void node_declare(const bNodeTree &node_tree, + const bNode &node, + NodeDeclaration &r_declaration) +{ + const bNodeTree *group = reinterpret_cast(node.id); + if (!group) { + return; + } + node_group_declare_dynamic(node_tree, node, r_declaration); + if (!node.id) { + return; + } + if (ID_IS_LINKED(&group->id) && (group->id.tag & LIB_TAG_MISSING)) { + return; + } + + const FieldInferencingInterface &field_interface = *group->runtime->field_inferencing_interface; + for (const int i : r_declaration.inputs.index_range()) { + r_declaration.inputs[i]->input_field_type = field_interface.inputs[i]; + } + for (const int i : r_declaration.outputs.index_range()) { + r_declaration.outputs[i]->output_field_dependency = field_interface.outputs[i]; + } +} + +} // namespace blender::nodes + void register_node_type_geo_group() { static bNodeType ntype; @@ -23,7 +53,7 @@ void register_node_type_geo_group() node_type_size(&ntype, 140, 60, 400); ntype.labelfunc = node_group_label; - ntype.group_update_func = node_group_update; + ntype.declare_dynamic = blender::nodes::node_declare; nodeRegisterType(&ntype); } diff --git a/source/blender/nodes/intern/node_common.cc b/source/blender/nodes/intern/node_common.cc index 509921837cc..8652493b49b 100644 --- a/source/blender/nodes/intern/node_common.cc +++ b/source/blender/nodes/intern/node_common.cc @@ -30,7 +30,11 @@ #include "MEM_guardedalloc.h" #include "NOD_common.h" +#include "NOD_node_declaration.hh" #include "NOD_register.hh" +#include "NOD_socket.h" +#include "NOD_socket_declarations.hh" +#include "NOD_socket_declarations_geometry.hh" #include "node_common.h" #include "node_util.h" @@ -120,124 +124,124 @@ bool nodeGroupPoll(const bNodeTree *nodetree, return true; } -static void add_new_socket_from_interface(bNodeTree &node_tree, - bNode &node, - const bNodeSocket &interface_socket, - const eNodeSocketInOut in_out) -{ - bNodeSocket *socket = nodeAddSocket(&node_tree, - &node, - in_out, - interface_socket.idname, - interface_socket.identifier, - interface_socket.name); +namespace blender::nodes { - if (interface_socket.typeinfo->interface_init_socket) { - interface_socket.typeinfo->interface_init_socket( - &node_tree, &interface_socket, &node, socket, "interface"); +static SocketDeclarationPtr declaration_for_interface_socket(const bNodeSocket &io_socket) +{ + SocketDeclarationPtr dst; + switch (io_socket.type) { + case SOCK_FLOAT: { + const auto &value = *io_socket.default_value_typed(); + std::unique_ptr decl = std::make_unique(); + decl->subtype = PropertySubType(io_socket.typeinfo->subtype); + decl->default_value = value.value; + decl->soft_min_value = value.min; + decl->soft_max_value = value.max; + dst = std::move(decl); + break; + } + case SOCK_VECTOR: { + const auto &value = *io_socket.default_value_typed(); + std::unique_ptr decl = std::make_unique(); + decl->subtype = PropertySubType(io_socket.typeinfo->subtype); + decl->default_value = value.value; + decl->soft_min_value = value.min; + decl->soft_max_value = value.max; + dst = std::move(decl); + break; + } + case SOCK_RGBA: { + const auto &value = *io_socket.default_value_typed(); + std::unique_ptr decl = std::make_unique(); + decl->default_value = value.value; + dst = std::move(decl); + break; + } + case SOCK_SHADER: { + std::unique_ptr decl = std::make_unique(); + dst = std::move(decl); + break; + } + case SOCK_BOOLEAN: { + const auto &value = *io_socket.default_value_typed(); + std::unique_ptr decl = std::make_unique(); + decl->default_value = value.value; + dst = std::move(decl); + break; + } + case SOCK_INT: { + const auto &value = *io_socket.default_value_typed(); + std::unique_ptr decl = std::make_unique(); + decl->subtype = PropertySubType(io_socket.typeinfo->subtype); + decl->default_value = value.value; + decl->soft_min_value = value.min; + decl->soft_max_value = value.max; + dst = std::move(decl); + break; + } + case SOCK_STRING: { + const auto &value = *io_socket.default_value_typed(); + std::unique_ptr decl = std::make_unique(); + decl->default_value = value.value; + dst = std::move(decl); + break; + } + case SOCK_OBJECT: + dst = std::make_unique(); + break; + case SOCK_IMAGE: + dst = std::make_unique(); + break; + case SOCK_GEOMETRY: + dst = std::make_unique(); + break; + case SOCK_COLLECTION: + dst = std::make_unique(); + break; + case SOCK_TEXTURE: + dst = std::make_unique(); + break; + case SOCK_MATERIAL: + dst = std::make_unique(); + break; + case SOCK_CUSTOM: + std::unique_ptr decl = std::make_unique(); + decl->idname_ = io_socket.idname; + dst = std::move(decl); + break; + } + dst->name = io_socket.name; + dst->identifier = io_socket.identifier; + dst->in_out = eNodeSocketInOut(io_socket.in_out); + dst->description = io_socket.description; + dst->hide_value = io_socket.flag & SOCK_HIDE_VALUE; + dst->compact = io_socket.flag & SOCK_COMPACT; + return dst; +} + +void node_group_declare_dynamic(const bNodeTree & /*node_tree*/, + const bNode &node, + NodeDeclaration &r_declaration) +{ + const bNodeTree *group = reinterpret_cast(node.id); + if (!group) { + return; + } + if (ID_IS_LINKED(&group->id) && (group->id.tag & LIB_TAG_MISSING)) { + r_declaration.skip_updating_sockets = true; + return; + } + r_declaration.skip_updating_sockets = false; + + LISTBASE_FOREACH (const bNodeSocket *, input, &group->inputs) { + r_declaration.inputs.append(declaration_for_interface_socket(*input)); + } + LISTBASE_FOREACH (const bNodeSocket *, output, &group->outputs) { + r_declaration.outputs.append(declaration_for_interface_socket(*output)); } } -static void update_socket_to_match_interface(bNodeTree &node_tree, - bNode &node, - bNodeSocket &socket_to_update, - const bNodeSocket &interface_socket) -{ - strcpy(socket_to_update.name, interface_socket.name); - - const int mask = SOCK_HIDE_VALUE; - socket_to_update.flag = (socket_to_update.flag & ~mask) | (interface_socket.flag & mask); - - /* Update socket type if necessary */ - if (socket_to_update.typeinfo != interface_socket.typeinfo) { - nodeModifySocketType(&node_tree, &node, &socket_to_update, interface_socket.idname); - } - - if (interface_socket.typeinfo->interface_verify_socket) { - interface_socket.typeinfo->interface_verify_socket( - &node_tree, &interface_socket, &node, &socket_to_update, "interface"); - } -} - -/** - * Used for group nodes and group input/output nodes to update the list of input or output sockets - * on a node to match the provided interface. Assumes that \a verify_lb is the node's matching - * input or output socket list, depending on whether the node is a group input/output or a group - * node. - */ -static void group_verify_socket_list(bNodeTree &node_tree, - bNode &node, - const ListBase &interface_sockets, - ListBase &verify_lb, - const eNodeSocketInOut in_out, - const bool ensure_extend_socket_exists) -{ - ListBase old_sockets = verify_lb; - Vector ordered_old_sockets = old_sockets; - BLI_listbase_clear(&verify_lb); - - LISTBASE_FOREACH (const bNodeSocket *, interface_socket, &interface_sockets) { - bNodeSocket *matching_socket = find_matching_socket(old_sockets, interface_socket->identifier); - if (matching_socket) { - /* If a socket with the same identifier exists in the previous socket list, update it - * with the correct name, type, etc. Then move it from the old list to the new one. */ - update_socket_to_match_interface(node_tree, node, *matching_socket, *interface_socket); - BLI_remlink(&old_sockets, matching_socket); - BLI_addtail(&verify_lb, matching_socket); - } - else { - /* If there was no socket with the same identifier already, simply create a new socket - * based on the interface socket, which will already add it to the new list. */ - add_new_socket_from_interface(node_tree, node, *interface_socket, in_out); - } - } - - if (ensure_extend_socket_exists) { - bNodeSocket *last_socket = static_cast(old_sockets.last); - if (last_socket != nullptr && STREQ(last_socket->identifier, "__extend__")) { - BLI_remlink(&old_sockets, last_socket); - BLI_addtail(&verify_lb, last_socket); - } - else { - nodeAddSocket(&node_tree, &node, in_out, "NodeSocketVirtual", "__extend__", ""); - } - } - - /* Remove leftover sockets that didn't match the node group's interface. */ - LISTBASE_FOREACH_MUTABLE (bNodeSocket *, unused_socket, &old_sockets) { - nodeRemoveSocket(&node_tree, &node, unused_socket); - } - - { - /* Check if new sockets match the old sockets. */ - int index; - LISTBASE_FOREACH_INDEX (bNodeSocket *, new_socket, &verify_lb, index) { - if (index < ordered_old_sockets.size()) { - if (ordered_old_sockets[index] != new_socket) { - BKE_ntree_update_tag_interface(&node_tree); - break; - } - } - } - } -} - -void node_group_update(struct bNodeTree *ntree, struct bNode *node) -{ - /* check inputs and outputs, and remove or insert them */ - if (node->id == nullptr) { - nodeRemoveAllSockets(ntree, node); - } - else if (ID_IS_LINKED(node->id) && (node->id->tag & LIB_TAG_MISSING)) { - /* Missing data-block, leave sockets unchanged so that when it comes back - * the links remain valid. */ - } - else { - bNodeTree *ngroup = (bNodeTree *)node->id; - group_verify_socket_list(*ntree, *node, ngroup->inputs, node->inputs, SOCK_IN, false); - group_verify_socket_list(*ntree, *node, ngroup->outputs, node->outputs, SOCK_OUT, false); - } -} +} // namespace blender::nodes /** \} */ @@ -419,16 +423,6 @@ bool BKE_node_is_connected_to_output(const bNodeTree *ntree, const bNode *node) /** \name Node #GROUP_INPUT / #GROUP_OUTPUT * \{ */ -static bool is_group_extension_socket(const bNode *node, const bNodeSocket *socket) -{ - return socket->type == SOCK_CUSTOM && ELEM(node->type, NODE_GROUP_OUTPUT, NODE_GROUP_INPUT); -} - -static void node_group_input_init(bNodeTree *ntree, bNode *node) -{ - node_group_input_update(ntree, node); -} - bNodeSocket *node_group_input_find_socket(bNode *node, const char *identifier) { bNodeSocket *sock; @@ -440,59 +434,83 @@ bNodeSocket *node_group_input_find_socket(bNode *node, const char *identifier) return nullptr; } -void node_group_input_update(bNodeTree *ntree, bNode *node) +namespace blender::nodes { + +static SocketDeclarationPtr extend_declaration(const eNodeSocketInOut in_out) { - bNodeSocket *extsock = (bNodeSocket *)node->outputs.last; - /* Adding a tree socket and verifying will remove the extension socket! - * This list caches the existing links from the extension socket - * so they can be recreated after verification. */ - Vector temp_links; - - /* find links from the extension socket and store them */ - LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { - if (nodeLinkIsHidden(link)) { - continue; - } - - if (link->fromsock == extsock) { - temp_links.append(*link); - nodeRemLink(ntree, link); - } - } - - /* find valid link to expose */ - bNodeLink *exposelink = nullptr; - for (bNodeLink &link : temp_links) { - /* XXX Multiple sockets can be connected to the extension socket at once, - * in that case the arbitrary first link determines name and type. - * This could be improved by choosing the "best" type among all links, - * whatever that means. - */ - if (!is_group_extension_socket(link.tonode, link.tosock)) { - exposelink = &link; - break; - } - } - - if (exposelink) { - bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket( - ntree, exposelink->tonode, exposelink->tosock); - - node_group_input_update(ntree, node); - bNodeSocket *newsock = node_group_input_find_socket(node, gsock->identifier); - - /* redirect links from the extension socket */ - for (bNodeLink &link : temp_links) { - bNodeLink *newlink = nodeAddLink(ntree, node, newsock, link.tonode, link.tosock); - if (newlink->tosock->flag & SOCK_MULTI_INPUT) { - newlink->multi_input_socket_index = link.multi_input_socket_index; - } - } - } - - group_verify_socket_list(*ntree, *node, ntree->inputs, node->outputs, SOCK_OUT, true); + std::unique_ptr decl = std::make_unique(); + decl->name = ""; + decl->identifier = "__extend__"; + decl->in_out = in_out; + return decl; } +static void group_input_declare_dynamic(const bNodeTree &node_tree, + const bNode & /*node*/, + NodeDeclaration &r_declaration) +{ + LISTBASE_FOREACH (const bNodeSocket *, input, &node_tree.inputs) { + r_declaration.outputs.append(declaration_for_interface_socket(*input)); + r_declaration.outputs.last()->in_out = SOCK_OUT; + } + r_declaration.outputs.append(extend_declaration(SOCK_OUT)); +} + +static void group_output_declare_dynamic(const bNodeTree &node_tree, + const bNode & /*node*/, + NodeDeclaration &r_declaration) +{ + LISTBASE_FOREACH (const bNodeSocket *, input, &node_tree.outputs) { + r_declaration.inputs.append(declaration_for_interface_socket(*input)); + r_declaration.inputs.last()->in_out = SOCK_IN; + } + r_declaration.inputs.append(extend_declaration(SOCK_IN)); +} + +static bool group_input_insert_link(bNodeTree *ntree, bNode *node, bNodeLink *link) +{ + BLI_assert(link->tonode != node); + BLI_assert(link->tosock->in_out == SOCK_IN); + if (link->fromsock->identifier != StringRef("__extend__")) { + return true; + } + if (link->tosock->identifier == StringRef("__extend__")) { + /* Don't connect to other "extend" sockets. */ + return false; + } + const bNodeSocket *io_socket = ntreeAddSocketInterfaceFromSocket( + ntree, link->tonode, link->tosock); + if (!io_socket) { + return false; + } + update_node_declaration_and_sockets(*ntree, *node); + link->fromsock = node_group_input_find_socket(node, io_socket->identifier); + return true; +} + +static bool group_output_insert_link(bNodeTree *ntree, bNode *node, bNodeLink *link) +{ + BLI_assert(link->fromnode != node); + BLI_assert(link->fromsock->in_out == SOCK_OUT); + if (link->tosock->identifier != StringRef("__extend__")) { + return true; + } + if (link->fromsock->identifier == StringRef("__extend__")) { + /* Don't connect to other "extend" sockets. */ + return false; + } + const bNodeSocket *io_socket = ntreeAddSocketInterfaceFromSocket( + ntree, link->fromnode, link->fromsock); + if (!io_socket) { + return false; + } + update_node_declaration_and_sockets(*ntree, *node); + link->tosock = node_group_output_find_socket(node, io_socket->identifier); + return true; +} + +} // namespace blender::nodes + void register_node_type_group_input() { /* used for all tree types, needs dynamic allocation */ @@ -501,17 +519,12 @@ void register_node_type_group_input() node_type_base(ntype, NODE_GROUP_INPUT, "Group Input", NODE_CLASS_INTERFACE); node_type_size(ntype, 140, 80, 400); - ntype->initfunc = node_group_input_init; - ntype->updatefunc = node_group_input_update; + ntype->declare_dynamic = blender::nodes::group_input_declare_dynamic; + ntype->insert_link = blender::nodes::group_input_insert_link; nodeRegisterType(ntype); } -static void node_group_output_init(bNodeTree *ntree, bNode *node) -{ - node_group_output_update(ntree, node); -} - bNodeSocket *node_group_output_find_socket(bNode *node, const char *identifier) { bNodeSocket *sock; @@ -523,57 +536,6 @@ bNodeSocket *node_group_output_find_socket(bNode *node, const char *identifier) return nullptr; } -void node_group_output_update(bNodeTree *ntree, bNode *node) -{ - bNodeSocket *extsock = (bNodeSocket *)node->inputs.last; - /* Adding a tree socket and verifying will remove the extension socket! - * This list caches the existing links to the extension socket - * so they can be recreated after verification. */ - Vector temp_links; - - /* find links to the extension socket and store them */ - LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { - if (nodeLinkIsHidden(link)) { - continue; - } - - if (link->tosock == extsock) { - temp_links.append(*link); - nodeRemLink(ntree, link); - } - } - - /* find valid link to expose */ - bNodeLink *exposelink = nullptr; - for (bNodeLink &link : temp_links) { - /* XXX Multiple sockets can be connected to the extension socket at once, - * in that case the arbitrary first link determines name and type. - * This could be improved by choosing the "best" type among all links, - * whatever that means. - */ - if (!is_group_extension_socket(link.fromnode, link.fromsock)) { - exposelink = &link; - break; - } - } - - if (exposelink) { - /* XXX what if connecting virtual to virtual socket?? */ - bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket( - ntree, exposelink->fromnode, exposelink->fromsock); - - node_group_output_update(ntree, node); - bNodeSocket *newsock = node_group_output_find_socket(node, gsock->identifier); - - /* redirect links to the extension socket */ - for (bNodeLink &link : temp_links) { - nodeAddLink(ntree, link.fromnode, link.fromsock, node, newsock); - } - } - - group_verify_socket_list(*ntree, *node, ntree->outputs, node->inputs, SOCK_IN, true); -} - void register_node_type_group_output() { /* used for all tree types, needs dynamic allocation */ @@ -582,8 +544,8 @@ void register_node_type_group_output() node_type_base(ntype, NODE_GROUP_OUTPUT, "Group Output", NODE_CLASS_INTERFACE); node_type_size(ntype, 140, 80, 400); - ntype->initfunc = node_group_output_init; - ntype->updatefunc = node_group_output_update; + ntype->declare_dynamic = blender::nodes::group_output_declare_dynamic; + ntype->insert_link = blender::nodes::group_output_insert_link; ntype->no_muting = true; diff --git a/source/blender/nodes/intern/node_declaration.cc b/source/blender/nodes/intern/node_declaration.cc index 3538710bb3a..da51b760887 100644 --- a/source/blender/nodes/intern/node_declaration.cc +++ b/source/blender/nodes/intern/node_declaration.cc @@ -16,6 +16,15 @@ void build_node_declaration(const bNodeType &typeinfo, NodeDeclaration &r_declar node_decl_builder.finalize(); } +void build_node_declaration_dynamic(const bNodeTree &node_tree, + const bNode &node, + NodeDeclaration &r_declaration) +{ + r_declaration.inputs.clear(); + r_declaration.outputs.clear(); + node.typeinfo->declare_dynamic(node_tree, node, r_declaration); +} + void NodeDeclarationBuilder::finalize() { if (is_function_node_) { diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index 9110813b4d7..2fbf14b4760 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -19,6 +19,7 @@ #include "BKE_lib_id.h" #include "BKE_node.h" #include "BKE_node_runtime.hh" +#include "BKE_node_tree_update.h" #include "DNA_collection_types.h" #include "DNA_material_types.h" @@ -171,6 +172,8 @@ static void verify_socket_template_list(bNodeTree *ntree, } } +namespace blender::nodes { + static void refresh_socket_list(bNodeTree &ntree, bNode &node, ListBase &sockets, @@ -232,6 +235,7 @@ static void refresh_socket_list(bNodeTree &ntree, } } new_sockets.add_new(new_socket); + BKE_ntree_update_tag_socket_new(&ntree, new_socket); } LISTBASE_FOREACH_MUTABLE (bNodeSocket *, old_socket, &sockets) { if (!new_sockets.contains(old_socket)) { @@ -249,10 +253,29 @@ static void refresh_node(bNodeTree &ntree, blender::nodes::NodeDeclaration &node_decl, bool do_id_user) { - refresh_socket_list(ntree, node, node.inputs, node_decl.inputs, do_id_user); - refresh_socket_list(ntree, node, node.outputs, node_decl.outputs, do_id_user); + if (node_decl.skip_updating_sockets) { + return; + } + if (!node_decl.matches(node)) { + refresh_socket_list(ntree, node, node.inputs, node_decl.inputs, do_id_user); + refresh_socket_list(ntree, node, node.outputs, node_decl.outputs, do_id_user); + } + nodeSocketDeclarationsUpdate(&node); } +void update_node_declaration_and_sockets(bNodeTree &ntree, bNode &node) +{ + if (node.typeinfo->declare_dynamic) { + if (!node.runtime->declaration) { + node.runtime->declaration = new NodeDeclaration(); + } + build_node_declaration_dynamic(ntree, node, *node.runtime->declaration); + } + refresh_node(ntree, node, *node.runtime->declaration, true); +} + +} // namespace blender::nodes + void node_verify_sockets(bNodeTree *ntree, bNode *node, bool do_id_user) { bNodeType *ntype = node->typeinfo; @@ -261,10 +284,7 @@ void node_verify_sockets(bNodeTree *ntree, bNode *node, bool do_id_user) } if (ntype->declare != nullptr) { nodeDeclarationEnsureOnOutdatedNode(ntree, node); - if (!node->runtime->declaration->matches(*node)) { - refresh_node(*ntree, *node, *node->runtime->declaration, do_id_user); - } - nodeSocketDeclarationsUpdate(node); + refresh_node(*ntree, *node, *node->runtime->declaration, do_id_user); return; } /* Don't try to match socket lists when there are no templates. @@ -499,52 +519,6 @@ static void standard_node_socket_interface_init_socket(bNodeTree * /*ntree*/, node_socket_copy_default_value(sock, interface_socket); } -/* copies settings that are not changed for each socket instance */ -static void standard_node_socket_interface_verify_socket(bNodeTree * /*ntree*/, - const bNodeSocket *interface_socket, - bNode * /*node*/, - bNodeSocket *sock, - const char * /*data_path*/) -{ - /* sanity check */ - if (sock->type != interface_socket->typeinfo->type) { - return; - } - - /* make sure both exist */ - if (!interface_socket->default_value) { - return; - } - node_socket_init_default_value(sock); - - switch (interface_socket->typeinfo->type) { - case SOCK_FLOAT: { - bNodeSocketValueFloat *toval = (bNodeSocketValueFloat *)sock->default_value; - const bNodeSocketValueFloat *fromval = (const bNodeSocketValueFloat *) - interface_socket->default_value; - toval->min = fromval->min; - toval->max = fromval->max; - break; - } - case SOCK_INT: { - bNodeSocketValueInt *toval = (bNodeSocketValueInt *)sock->default_value; - const bNodeSocketValueInt *fromval = (const bNodeSocketValueInt *) - interface_socket->default_value; - toval->min = fromval->min; - toval->max = fromval->max; - break; - } - case SOCK_VECTOR: { - bNodeSocketValueVector *toval = (bNodeSocketValueVector *)sock->default_value; - const bNodeSocketValueVector *fromval = (const bNodeSocketValueVector *) - interface_socket->default_value; - toval->min = fromval->min; - toval->max = fromval->max; - break; - } - } -} - static void standard_node_socket_interface_from_socket(bNodeTree * /*ntree*/, bNodeSocket *stemp, const bNode * /*node*/, @@ -592,7 +566,6 @@ static bNodeSocketType *make_standard_socket_type(int type, int subtype) stype->interface_init_socket = standard_node_socket_interface_init_socket; stype->interface_from_socket = standard_node_socket_interface_from_socket; - stype->interface_verify_socket = standard_node_socket_interface_verify_socket; stype->use_link_limits_of_type = true; stype->input_link_limit = 1; diff --git a/source/blender/nodes/intern/node_socket_declarations.cc b/source/blender/nodes/intern/node_socket_declarations.cc index 5d722ea28da..5fd4c4aad0d 100644 --- a/source/blender/nodes/intern/node_socket_declarations.cc +++ b/source/blender/nodes/intern/node_socket_declarations.cc @@ -234,6 +234,14 @@ bool Vector::matches(const bNodeSocket &socket) const if (socket.typeinfo->subtype != this->subtype) { return false; } + const bNodeSocketValueVector &value = *static_cast( + socket.default_value); + if (value.min != this->soft_min_value) { + return false; + } + if (value.max != this->soft_max_value) { + return false; + } return true; } @@ -257,6 +265,8 @@ bNodeSocket &Vector::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket this->set_common_flags(socket); bNodeSocketValueVector &value = *(bNodeSocketValueVector *)socket.default_value; value.subtype = this->subtype; + value.min = this->soft_min_value; + value.max = this->soft_max_value; STRNCPY(socket.name, this->name.c_str()); return socket; } @@ -301,6 +311,17 @@ bool Bool::can_connect(const bNodeSocket &socket) const return basic_types_can_connect(*this, socket); } +bNodeSocket &Bool::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const +{ + if (socket.type != SOCK_BOOLEAN) { + BLI_assert(socket.in_out == this->in_out); + return this->build(ntree, node); + } + this->set_common_flags(socket); + STRNCPY(socket.name, this->name.c_str()); + return socket; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -346,6 +367,17 @@ bool Color::can_connect(const bNodeSocket &socket) const return basic_types_can_connect(*this, socket); } +bNodeSocket &Color::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const +{ + if (socket.type != SOCK_RGBA) { + BLI_assert(socket.in_out == this->in_out); + return this->build(ntree, node); + } + this->set_common_flags(socket); + STRNCPY(socket.name, this->name.c_str()); + return socket; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -382,6 +414,17 @@ bool String::can_connect(const bNodeSocket &socket) const return sockets_can_connect(*this, socket) && socket.type == SOCK_STRING; } +bNodeSocket &String::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket &socket) const +{ + if (socket.type != SOCK_STRING) { + BLI_assert(socket.in_out == this->in_out); + return this->build(ntree, node); + } + this->set_common_flags(socket); + STRNCPY(socket.name, this->name.c_str()); + return socket; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -542,4 +585,77 @@ bool Shader::can_connect(const bNodeSocket &socket) const /** \} */ +/* -------------------------------------------------------------------- */ +/** \name #Extend + * \{ */ + +bNodeSocket &Extend::build(bNodeTree &ntree, bNode &node) const +{ + bNodeSocket &socket = *nodeAddSocket(&ntree, + &node, + this->in_out, + "NodeSocketVirtual", + this->identifier.c_str(), + this->name.c_str()); + return socket; +} + +bool Extend::matches(const bNodeSocket &socket) const +{ + if (socket.identifier != this->identifier) { + return false; + } + return true; +} + +bool Extend::can_connect(const bNodeSocket & /*socket*/) const +{ + return false; +} + +bNodeSocket &Extend::update_or_build(bNodeTree & /*ntree*/, + bNode & /*node*/, + bNodeSocket &socket) const +{ + return socket; +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name #Custom + * \{ */ + +bNodeSocket &Custom::build(bNodeTree &ntree, bNode &node) const +{ + bNodeSocket &socket = *nodeAddSocket( + &ntree, &node, this->in_out, idname_, this->identifier.c_str(), this->name.c_str()); + return socket; +} + +bool Custom::matches(const bNodeSocket &socket) const +{ + if (!this->matches_common_data(socket)) { + return false; + } + if (socket.type != SOCK_CUSTOM) { + return false; + } + return true; +} + +bool Custom::can_connect(const bNodeSocket &socket) const +{ + return sockets_can_connect(*this, socket) && STREQ(socket.idname, idname_); +} + +bNodeSocket &Custom::update_or_build(bNodeTree & /*ntree*/, + bNode & /*node*/, + bNodeSocket &socket) const +{ + return socket; +} + +/** \} */ + } // namespace blender::nodes::decl diff --git a/source/blender/nodes/intern/node_util.cc b/source/blender/nodes/intern/node_util.cc index 61ff81fa346..d56e82a23eb 100644 --- a/source/blender/nodes/intern/node_util.cc +++ b/source/blender/nodes/intern/node_util.cc @@ -324,19 +324,19 @@ static bNodeSocket *node_find_linkable_socket(bNodeTree *ntree, return nullptr; } -void node_insert_link_default(bNodeTree *ntree, bNode *node, bNodeLink *link) +bool node_insert_link_default(bNodeTree *ntree, bNode *node, bNodeLink *link) { bNodeSocket *socket = link->tosock; if (node != link->tonode) { - return; + return true; } /* If we're not at the link limit of the target socket, we can skip * trying to move existing links to another socket. */ const int to_link_limit = nodeSocketLinkLimit(socket); if (socket->runtime->total_inputs + 1 < to_link_limit) { - return; + return true; } LISTBASE_FOREACH_MUTABLE (bNodeLink *, to_link, &ntree->links) { @@ -345,16 +345,17 @@ void node_insert_link_default(bNodeTree *ntree, bNode *node, bNodeLink *link) if (new_socket && new_socket != socket) { /* Attempt to redirect the existing link to the new socket. */ to_link->tosock = new_socket; - return; + return true; } if (new_socket == nullptr) { /* No possible replacement, remove the existing link. */ nodeRemLink(ntree, to_link); - return; + return true; } } } + return true; } /** \} */ diff --git a/source/blender/nodes/intern/node_util.h b/source/blender/nodes/intern/node_util.h index 0a2a7a70091..b0f62eee849 100644 --- a/source/blender/nodes/intern/node_util.h +++ b/source/blender/nodes/intern/node_util.h @@ -74,7 +74,7 @@ void node_combsep_color_label(const ListBase *sockets, NodeCombSepColorMode mode * already linked (and if its not an Multi Input Socket), we try to find a replacement socket for * the link that we try to overwrite and connect that previous link to the new socket. */ -void node_insert_link_default(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link); +bool node_insert_link_default(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link); float node_socket_get_float(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock); void node_socket_set_float(struct bNodeTree *ntree, diff --git a/source/blender/nodes/intern/socket_search_link.cc b/source/blender/nodes/intern/socket_search_link.cc index 907dd987400..06ca17b43b5 100644 --- a/source/blender/nodes/intern/socket_search_link.cc +++ b/source/blender/nodes/intern/socket_search_link.cc @@ -132,9 +132,8 @@ void search_link_ops_for_basic_node(GatherLinkSearchOpParams ¶ms) return; } - if (node_type.declaration_is_dynamic) { - /* Dynamic declarations (whatever they end up being) aren't supported - * by this function, but still avoid a crash in release builds. */ + if (node_type.declare_dynamic) { + /* Dynamic declarations aren't supported here, but avoid crashing in release builds. */ BLI_assert_unreachable(); return; } diff --git a/source/blender/nodes/shader/nodes/node_shader_common.cc b/source/blender/nodes/shader/nodes/node_shader_common.cc index 48937b1213b..ac918ba0fdd 100644 --- a/source/blender/nodes/shader/nodes/node_shader_common.cc +++ b/source/blender/nodes/shader/nodes/node_shader_common.cc @@ -95,7 +95,7 @@ void register_node_type_sh_group() node_type_size(&ntype, 140, 60, 400); ntype.labelfunc = node_group_label; - ntype.group_update_func = node_group_update; + ntype.declare_dynamic = blender::nodes::node_group_declare_dynamic; ntype.gpu_fn = gpu_group_execute; nodeRegisterType(&ntype); diff --git a/source/blender/nodes/texture/nodes/node_texture_common.cc b/source/blender/nodes/texture/nodes/node_texture_common.cc index 603e2d39046..988195d852a 100644 --- a/source/blender/nodes/texture/nodes/node_texture_common.cc +++ b/source/blender/nodes/texture/nodes/node_texture_common.cc @@ -157,7 +157,7 @@ void register_node_type_tex_group(void) node_type_size(&ntype, 140, 60, 400); ntype.labelfunc = node_group_label; - ntype.group_update_func = node_group_update; + ntype.declare_dynamic = blender::nodes::node_group_declare_dynamic; ntype.init_exec_fn = group_initexec; ntype.free_exec_fn = group_freeexec; ntype.exec_fn = group_execute; From 6769acbbba7f0beb50dafcae3f49de9caee55787 Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Tue, 17 Jan 2023 11:14:52 +1300 Subject: [PATCH 0687/1522] BLI_math: simplify matrix multiply logic Improve safety and correctness of matrix multiplication by using temporary storage if one of the inputs is also the output. No functional changes. Differential Revision: https://developer.blender.org/D16876 Reviewed By: Campbell Barton, Sergey Sharybin --- source/blender/blenlib/BLI_math_matrix.h | 6 +- source/blender/blenlib/intern/math_matrix.c | 228 +++++++----------- .../intern/lineart/lineart_cpu.cc | 6 +- .../intern/lineart/lineart_shadow.c | 2 +- 4 files changed, 94 insertions(+), 148 deletions(-) diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 538474f58b6..1278bc90e44 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -83,16 +83,12 @@ void mul_m3_m4m4(float R[3][3], const float A[4][4], const float B[4][4]); /** * Special matrix multiplies - * - uniq: `R <-- AB`, R is neither A nor B * - pre: `R <-- AR` * - post: `R <-- RB`. */ -void mul_m3_m3m3_uniq(float R[3][3], const float A[3][3], const float B[3][3]); void mul_m3_m3_pre(float R[3][3], const float A[3][3]); void mul_m3_m3_post(float R[3][3], const float B[3][3]); -void mul_m4_m4m4_uniq(float R[4][4], const float A[4][4], const float B[4][4]); -void mul_m4_m4m4_db_uniq(double R[4][4], const double A[4][4], const double B[4][4]); -void mul_m4db_m4db_m4fl_uniq(double R[4][4], const double A[4][4], const float B[4][4]); +void mul_m4db_m4db_m4fl(double R[4][4], const double A[4][4], const float B[4][4]); void mul_m4_m4_pre(float R[4][4], const float A[4][4]); void mul_m4_m4_post(float R[4][4], const float B[4][4]); diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index d997eae26fb..7322a9facec 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -257,22 +257,14 @@ void shuffle_m4(float R[4][4], const int index[4]) void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4]) { - if (A == R) { - mul_m4_m4_post(R, B); + if (R == A || R == B) { + float T[4][4]; + mul_m4_m4m4(T, A, B); + copy_m4_m4(R, T); + return; } - else if (B == R) { - mul_m4_m4_pre(R, A); - } - else { - mul_m4_m4m4_uniq(R, A, B); - } -} -void mul_m4_m4m4_uniq(float R[4][4], const float A[4][4], const float B[4][4]) -{ - BLI_assert(!ELEM(R, A, B)); - - /* Matrix product: `R[j][k] = A[j][i] . B[i][k]`. */ + /* Matrix product: `R[j][k] = B[j][i] . A[i][k]`. */ #ifdef BLI_HAVE_SSE2 __m128 A0 = _mm_loadu_ps(A[0]); __m128 A1 = _mm_loadu_ps(A[1]); @@ -313,39 +305,16 @@ void mul_m4_m4m4_uniq(float R[4][4], const float A[4][4], const float B[4][4]) #endif } -void mul_m4_m4m4_db_uniq(double R[4][4], const double A[4][4], const double B[4][4]) +void mul_m4db_m4db_m4fl(double R[4][4], const double A[4][4], const float B[4][4]) { - BLI_assert(!ELEM(R, A, B)); + if (R == A) { + double T[4][4]; + mul_m4db_m4db_m4fl(T, A, B); + copy_m4_m4_db(R, T); + return; + } - /* Matrix product: `R[j][k] = A[j][i] . B[i][k]`. */ - - R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0] + B[0][3] * A[3][0]; - R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1] + B[0][3] * A[3][1]; - R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2] + B[0][3] * A[3][2]; - R[0][3] = B[0][0] * A[0][3] + B[0][1] * A[1][3] + B[0][2] * A[2][3] + B[0][3] * A[3][3]; - - R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0] + B[1][3] * A[3][0]; - R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1] + B[1][3] * A[3][1]; - R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2] + B[1][3] * A[3][2]; - R[1][3] = B[1][0] * A[0][3] + B[1][1] * A[1][3] + B[1][2] * A[2][3] + B[1][3] * A[3][3]; - - R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0] + B[2][3] * A[3][0]; - R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1] + B[2][3] * A[3][1]; - R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2] + B[2][3] * A[3][2]; - R[2][3] = B[2][0] * A[0][3] + B[2][1] * A[1][3] + B[2][2] * A[2][3] + B[2][3] * A[3][3]; - - R[3][0] = B[3][0] * A[0][0] + B[3][1] * A[1][0] + B[3][2] * A[2][0] + B[3][3] * A[3][0]; - R[3][1] = B[3][0] * A[0][1] + B[3][1] * A[1][1] + B[3][2] * A[2][1] + B[3][3] * A[3][1]; - R[3][2] = B[3][0] * A[0][2] + B[3][1] * A[1][2] + B[3][2] * A[2][2] + B[3][3] * A[3][2]; - R[3][3] = B[3][0] * A[0][3] + B[3][1] * A[1][3] + B[3][2] * A[2][3] + B[3][3] * A[3][3]; -} - -void mul_m4db_m4db_m4fl_uniq(double R[4][4], const double A[4][4], const float B[4][4]) -{ - /* Remove second check since types don't match. */ - BLI_assert(!ELEM(R, A /*, B */)); - - /* Matrix product: `R[j][k] = A[j][i] . B[i][k]`. */ + /* Matrix product: `R[j][k] = B[j][i] . A[i][k]`. */ R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0] + B[0][3] * A[3][0]; R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1] + B[0][3] * A[3][1]; @@ -370,53 +339,32 @@ void mul_m4db_m4db_m4fl_uniq(double R[4][4], const double A[4][4], const float B void mul_m4_m4_pre(float R[4][4], const float A[4][4]) { - BLI_assert(A != R); - float B[4][4]; - copy_m4_m4(B, R); - mul_m4_m4m4_uniq(R, A, B); + mul_m4_m4m4(R, A, R); } void mul_m4_m4_post(float R[4][4], const float B[4][4]) { - BLI_assert(B != R); - float A[4][4]; - copy_m4_m4(A, R); - mul_m4_m4m4_uniq(R, A, B); -} - -void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3]) -{ - if (A == R) { - mul_m3_m3_post(R, B); - } - else if (B == R) { - mul_m3_m3_pre(R, A); - } - else { - mul_m3_m3m3_uniq(R, A, B); - } + mul_m4_m4m4(R, R, B); } void mul_m3_m3_pre(float R[3][3], const float A[3][3]) { - BLI_assert(A != R); - float B[3][3]; - copy_m3_m3(B, R); - mul_m3_m3m3_uniq(R, A, B); + mul_m3_m3m3(R, A, R); } void mul_m3_m3_post(float R[3][3], const float B[3][3]) { - BLI_assert(B != R); - float A[3][3]; - copy_m3_m3(A, R); - mul_m3_m3m3_uniq(R, A, B); + mul_m3_m3m3(R, R, B); } -void mul_m3_m3m3_uniq(float R[3][3], const float A[3][3], const float B[3][3]) +void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3]) { - BLI_assert(!ELEM(R, A, B)); - + if (R == A || R == B) { + float T[3][3]; + mul_m3_m3m3(T, A, B); + copy_m3_m3(R, T); + return; + } R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0]; R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1]; R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2]; @@ -432,88 +380,90 @@ void mul_m3_m3m3_uniq(float R[3][3], const float A[3][3], const float B[3][3]) void mul_m4_m4m3(float R[4][4], const float A[4][4], const float B[3][3]) { - float B_[3][3], A_[4][4]; + if (R == A) { + float T[4][4]; + mul_m4_m4m3(T, A, B); + copy_m4_m4(R, T); + return; + } - /* copy so it works when R is the same pointer as A or B */ - /* TODO: avoid copying when matrices are different */ - copy_m4_m4(A_, A); - copy_m3_m3(B_, B); - - R[0][0] = B_[0][0] * A_[0][0] + B_[0][1] * A_[1][0] + B_[0][2] * A_[2][0]; - R[0][1] = B_[0][0] * A_[0][1] + B_[0][1] * A_[1][1] + B_[0][2] * A_[2][1]; - R[0][2] = B_[0][0] * A_[0][2] + B_[0][1] * A_[1][2] + B_[0][2] * A_[2][2]; - R[1][0] = B_[1][0] * A_[0][0] + B_[1][1] * A_[1][0] + B_[1][2] * A_[2][0]; - R[1][1] = B_[1][0] * A_[0][1] + B_[1][1] * A_[1][1] + B_[1][2] * A_[2][1]; - R[1][2] = B_[1][0] * A_[0][2] + B_[1][1] * A_[1][2] + B_[1][2] * A_[2][2]; - R[2][0] = B_[2][0] * A_[0][0] + B_[2][1] * A_[1][0] + B_[2][2] * A_[2][0]; - R[2][1] = B_[2][0] * A_[0][1] + B_[2][1] * A_[1][1] + B_[2][2] * A_[2][1]; - R[2][2] = B_[2][0] * A_[0][2] + B_[2][1] * A_[1][2] + B_[2][2] * A_[2][2]; + R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0]; + R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1]; + R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2]; + R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0]; + R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1]; + R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2]; + R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0]; + R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1]; + R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2]; } void mul_m3_m3m4(float R[3][3], const float A[3][3], const float B[4][4]) { - float B_[4][4], A_[3][3]; + if (R == A) { + float T[3][3]; + mul_m3_m3m4(T, A, B); + copy_m3_m3(R, T); + return; + } - /* copy so it works when R is the same pointer as A or B */ - /* TODO: avoid copying when matrices are different */ - copy_m3_m3(A_, A); - copy_m4_m4(B_, B); + /* Matrix product: `R[j][k] = B[j][i] . A[i][k]`. */ - /* R[i][j] = B_[i][k] * A_[k][j] */ - R[0][0] = B_[0][0] * A_[0][0] + B_[0][1] * A_[1][0] + B_[0][2] * A_[2][0]; - R[0][1] = B_[0][0] * A_[0][1] + B_[0][1] * A_[1][1] + B_[0][2] * A_[2][1]; - R[0][2] = B_[0][0] * A_[0][2] + B_[0][1] * A_[1][2] + B_[0][2] * A_[2][2]; + R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0]; + R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1]; + R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2]; - R[1][0] = B_[1][0] * A_[0][0] + B_[1][1] * A_[1][0] + B_[1][2] * A_[2][0]; - R[1][1] = B_[1][0] * A_[0][1] + B_[1][1] * A_[1][1] + B_[1][2] * A_[2][1]; - R[1][2] = B_[1][0] * A_[0][2] + B_[1][1] * A_[1][2] + B_[1][2] * A_[2][2]; + R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0]; + R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1]; + R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2]; - R[2][0] = B_[2][0] * A_[0][0] + B_[2][1] * A_[1][0] + B_[2][2] * A_[2][0]; - R[2][1] = B_[2][0] * A_[0][1] + B_[2][1] * A_[1][1] + B_[2][2] * A_[2][1]; - R[2][2] = B_[2][0] * A_[0][2] + B_[2][1] * A_[1][2] + B_[2][2] * A_[2][2]; + R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0]; + R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1]; + R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2]; } void mul_m3_m4m3(float R[3][3], const float A[4][4], const float B[3][3]) { - float B_[3][3], A_[4][4]; + if (R == B) { + float T[3][3]; + mul_m3_m4m3(T, A, B); + copy_m3_m3(R, T); + return; + } - /* copy so it works when R is the same pointer as A or B */ - /* TODO: avoid copying when matrices are different */ - copy_m4_m4(A_, A); - copy_m3_m3(B_, B); + /* Matrix product: `R[j][k] = B[j][i] . A[i][k]`. */ - /* R[i][j] = B[i][k] * A[k][j] */ - R[0][0] = B_[0][0] * A_[0][0] + B_[0][1] * A_[1][0] + B_[0][2] * A_[2][0]; - R[0][1] = B_[0][0] * A_[0][1] + B_[0][1] * A_[1][1] + B_[0][2] * A_[2][1]; - R[0][2] = B_[0][0] * A_[0][2] + B_[0][1] * A_[1][2] + B_[0][2] * A_[2][2]; + R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0]; + R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1]; + R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2]; - R[1][0] = B_[1][0] * A_[0][0] + B_[1][1] * A_[1][0] + B_[1][2] * A_[2][0]; - R[1][1] = B_[1][0] * A_[0][1] + B_[1][1] * A_[1][1] + B_[1][2] * A_[2][1]; - R[1][2] = B_[1][0] * A_[0][2] + B_[1][1] * A_[1][2] + B_[1][2] * A_[2][2]; + R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0]; + R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1]; + R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2]; - R[2][0] = B_[2][0] * A_[0][0] + B_[2][1] * A_[1][0] + B_[2][2] * A_[2][0]; - R[2][1] = B_[2][0] * A_[0][1] + B_[2][1] * A_[1][1] + B_[2][2] * A_[2][1]; - R[2][2] = B_[2][0] * A_[0][2] + B_[2][1] * A_[1][2] + B_[2][2] * A_[2][2]; + R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0]; + R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1]; + R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2]; } void mul_m4_m3m4(float R[4][4], const float A[3][3], const float B[4][4]) { - float B_[4][4], A_[3][3]; + if (R == B) { + float T[4][4]; + mul_m4_m3m4(T, A, B); + copy_m4_m4(R, T); + return; + } - /* copy so it works when R is the same pointer as A or B */ - /* TODO: avoid copying when matrices are different */ - copy_m3_m3(A_, A); - copy_m4_m4(B_, B); - - R[0][0] = B_[0][0] * A_[0][0] + B_[0][1] * A_[1][0] + B_[0][2] * A_[2][0]; - R[0][1] = B_[0][0] * A_[0][1] + B_[0][1] * A_[1][1] + B_[0][2] * A_[2][1]; - R[0][2] = B_[0][0] * A_[0][2] + B_[0][1] * A_[1][2] + B_[0][2] * A_[2][2]; - R[1][0] = B_[1][0] * A_[0][0] + B_[1][1] * A_[1][0] + B_[1][2] * A_[2][0]; - R[1][1] = B_[1][0] * A_[0][1] + B_[1][1] * A_[1][1] + B_[1][2] * A_[2][1]; - R[1][2] = B_[1][0] * A_[0][2] + B_[1][1] * A_[1][2] + B_[1][2] * A_[2][2]; - R[2][0] = B_[2][0] * A_[0][0] + B_[2][1] * A_[1][0] + B_[2][2] * A_[2][0]; - R[2][1] = B_[2][0] * A_[0][1] + B_[2][1] * A_[1][1] + B_[2][2] * A_[2][1]; - R[2][2] = B_[2][0] * A_[0][2] + B_[2][1] * A_[1][2] + B_[2][2] * A_[2][2]; + R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0]; + R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1]; + R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2]; + R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0]; + R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1]; + R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2]; + R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0]; + R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1]; + R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2]; } void mul_m3_m4m4(float R[3][3], const float A[4][4], const float B[4][4]) @@ -1304,7 +1254,7 @@ void mul_m4_m4m4_aligned_scale(float R[4][4], const float A[4][4], const float B mat4_to_loc_rot_size(loc_b, rot_b, size_b, B); mul_v3_m4v3(loc_r, A, loc_b); - mul_m3_m3m3_uniq(rot_r, rot_a, rot_b); + mul_m3_m3m3(rot_r, rot_a, rot_b); mul_v3_v3v3(size_r, size_a, size_b); loc_rot_size_to_mat4(R, loc_r, rot_r, size_r); @@ -1320,7 +1270,7 @@ void mul_m4_m4m4_split_channels(float R[4][4], const float A[4][4], const float mat4_to_loc_rot_size(loc_b, rot_b, size_b, B); add_v3_v3v3(loc_r, loc_a, loc_b); - mul_m3_m3m3_uniq(rot_r, rot_a, rot_b); + mul_m3_m3m3(rot_r, rot_a, rot_b); mul_v3_v3v3(size_r, size_a, size_b); loc_rot_size_to_mat4(R, loc_r, rot_r, size_r); diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index 60279e687cc..695452f43ed 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -2447,8 +2447,8 @@ static void lineart_object_load_single_instance(LineartData *ld, /* Prepare the matrix used for transforming this specific object (instance). This has to be * done before mesh boundbox check because the function needs that. */ - mul_m4db_m4db_m4fl_uniq(obi->model_view_proj, ld->conf.view_projection, use_mat); - mul_m4db_m4db_m4fl_uniq(obi->model_view, ld->conf.view, use_mat); + mul_m4db_m4db_m4fl(obi->model_view_proj, ld->conf.view_projection, use_mat); + mul_m4db_m4db_m4fl(obi->model_view, ld->conf.view, use_mat); if (!ELEM(ob->type, OB_MESH, OB_MBALL, OB_CURVES_LEGACY, OB_SURF, OB_FONT)) { return; @@ -2524,7 +2524,7 @@ void lineart_main_load_geometries(Depsgraph *depsgraph, } invert_m4_m4(inv, ld->conf.cam_obmat); - mul_m4db_m4db_m4fl_uniq(result, proj, inv); + mul_m4db_m4db_m4fl(result, proj, inv); copy_m4_m4_db(proj, result); copy_m4_m4_db(ld->conf.view_projection, proj); diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c index 9d825a4e993..19bc69b5566 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_shadow.c @@ -1226,7 +1226,7 @@ bool lineart_main_try_generate_shadow(Depsgraph *depsgraph, proj, -ld->w, ld->w, -ld->h, ld->h, ld->conf.near_clip, ld->conf.far_clip); } invert_m4_m4(inv, ld->conf.cam_obmat); - mul_m4db_m4db_m4fl_uniq(result, proj, inv); + mul_m4db_m4db_m4fl(result, proj, inv); copy_m4_m4_db(proj, result); copy_m4_m4_db(ld->conf.view_projection, proj); unit_m4_db(view); From 647a7da17dccca02cd31d9d8cd216b997edd5bfc Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 16 Jan 2023 16:51:10 -0600 Subject: [PATCH 0688/1522] Curves: Avoid adding curve type attribute when setting default The default curve type when there is no "curve_type" attribute is Catmull ROM. In order to avoid allocating an entire array of values just to set this default type, remove the attribute instead. This will be less important when we can store attributes as single values. Also fix a curve utility API comment. --- source/blender/blenkernel/BKE_curves_utils.hh | 2 +- source/blender/blenkernel/intern/curves_geometry.cc | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_curves_utils.hh b/source/blender/blenkernel/BKE_curves_utils.hh index 1e06cb2d4c7..77998b24a32 100644 --- a/source/blender/blenkernel/BKE_curves_utils.hh +++ b/source/blender/blenkernel/BKE_curves_utils.hh @@ -519,7 +519,7 @@ void fill_points(const CurvesGeometry &curves, } /** - * Copy only the information on the point domain, but not the offsets or any point attributes, + * Copy only the attributes on the curve domain, but not the offsets or any point attributes, * meant for operations that change the number of points but not the number of curves. * \warning The returned curves have invalid offsets! */ diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 65117ab00bb..0dc6a24fd9e 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -242,7 +242,14 @@ MutableSpan CurvesGeometry::curve_types_for_write() void CurvesGeometry::fill_curve_types(const CurveType type) { - this->curve_types_for_write().fill(type); + if (type == CURVE_TYPE_CATMULL_ROM) { + /* Avoid creating the attribute for Catmull Rom which is the default when the attribute doesn't + * exist anyway. */ + this->attributes_for_write().remove("curve_type"); + } + else { + this->curve_types_for_write().fill(type); + } this->runtime->type_counts.fill(0); this->runtime->type_counts[type] = this->curves_num(); this->tag_topology_changed(); From 7241ab6ede0b184468a812554663531e68c0fda9 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 16 Jan 2023 16:58:24 -0600 Subject: [PATCH 0689/1522] Revert "Fix: don't set default value for unused socket in geometry nodes" This reverts commit 154d3e95f862fd680879267b03bb050ffa178d05. This caused crashes in the mouse house and flower shop benchmark files. A proper solution will be investigated soon. --- .../blender/nodes/geometry/nodes/node_geo_attribute_capture.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc index 3f994805682..a07cd1437d6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_capture.cc @@ -147,6 +147,7 @@ static void node_geo_exec(GeoNodeExecParams params) if (!attribute_id) { params.set_output("Geometry", geometry_set); + params.set_default_remaining_outputs(); return; } From 9789835db8690098b392c160c2abd34f4d8e17e2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 17 Jan 2023 11:51:07 +1100 Subject: [PATCH 0690/1522] Docs: improve ID property doc-strings Add some clarifications and reference enum types from DNA. --- source/blender/blenkernel/BKE_idprop.h | 3 + source/blender/blenkernel/intern/idprop.c | 24 ++++---- source/blender/makesdna/DNA_ID.h | 74 +++++++++++++---------- 3 files changed, 58 insertions(+), 43 deletions(-) diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h index 84412fd139f..22470b7a629 100644 --- a/source/blender/blenkernel/BKE_idprop.h +++ b/source/blender/blenkernel/BKE_idprop.h @@ -28,12 +28,15 @@ typedef union IDPropertyTemplate { double d; struct { const char *str; + /** String length (including the null byte): `strlen(str) + 1`. */ int len; + /** #eIDPropertySubType */ char subtype; } string; struct ID *id; struct { int len; + /** #eIDPropertyType */ char type; } array; struct { diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index b8f0db0699d..156ad97c923 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -39,19 +39,19 @@ static CLG_LogRef LOG = {"bke.idprop"}; -/* Local size table. */ +/** Local size table, aligned with #eIDPropertyType. */ static size_t idp_size_table[] = { - 1, /*strings*/ - sizeof(int), - sizeof(float), - sizeof(float[3]), /* Vector type, deprecated. */ - sizeof(float[16]), /* Matrix type, deprecated. */ - 0, /* Arrays don't have a fixed size. */ - sizeof(ListBase), /* Group type. */ - sizeof(void *), - sizeof(double), - 0, - sizeof(int8_t), /* Boolean type. */ + 1, /* #IDP_STRING */ + sizeof(int), /* #IDP_INT */ + sizeof(float), /* #IDP_FLOAT */ + sizeof(float[3]), /* DEPRECATED (was vector). */ + sizeof(float[16]), /* DEPRECATED (was matrix). */ + 0, /* #IDP_ARRAY (no fixed size). */ + sizeof(ListBase), /* #IDP_GROUP */ + sizeof(void *), /* #IDP_ID */ + sizeof(double), /* #IDP_DOUBLE */ + 0, /* #IDP_IDPARRAY (no fixed size). */ + sizeof(int8_t), /* #IDP_BOOLEAN */ }; /* -------------------------------------------------------------------- */ diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 4e56fbe3dd0..43317bc0466 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -45,9 +45,9 @@ typedef struct DrawDataList { } DrawDataList; typedef struct IDPropertyUIData { - /** Tooltip / property description pointer. Owned by the IDProperty. */ + /** Tool-tip / property description pointer. Owned by the #IDProperty. */ char *description; - /** RNA subtype, used for every type except string properties (PropertySubType). */ + /** RNA `subtype`, used for every type except string properties (#PropertySubType). */ int rna_subtype; char _pad[4]; @@ -68,7 +68,7 @@ typedef struct IDPropertyUIDataInt { int default_value; } IDPropertyUIDataInt; -/* IDP_UI_DATA_TYPE_BOOLEAN Use "int8_t" because DNA does not support "bool". */ +/** For #IDP_UI_DATA_TYPE_BOOLEAN Use `int8_t` because DNA does not support `bool`. */ typedef struct IDPropertyUIDataBool { IDPropertyUIData base; int8_t *default_array; /* Only for array properties. */ @@ -78,7 +78,7 @@ typedef struct IDPropertyUIDataBool { int8_t default_value; } IDPropertyUIDataBool; -/* IDP_UI_DATA_TYPE_FLOAT */ +/** For #IDP_UI_DATA_TYPE_FLOAT */ typedef struct IDPropertyUIDataFloat { IDPropertyUIData base; double *default_array; /* Only for array properties. */ @@ -95,13 +95,13 @@ typedef struct IDPropertyUIDataFloat { double default_value; } IDPropertyUIDataFloat; -/* IDP_UI_DATA_TYPE_STRING */ +/** For #IDP_UI_DATA_TYPE_STRING */ typedef struct IDPropertyUIDataString { IDPropertyUIData base; char *default_value; } IDPropertyUIDataString; -/* IDP_UI_DATA_TYPE_ID */ +/** For #IDP_UI_DATA_TYPE_ID. */ typedef struct IDPropertyUIDataID { IDPropertyUIData base; } IDPropertyUIDataID; @@ -109,15 +109,22 @@ typedef struct IDPropertyUIDataID { typedef struct IDPropertyData { void *pointer; ListBase group; - /** NOTE: we actually fit a double into these two 32bit integers. */ + /** NOTE: a `double` is written into two 32bit integers. */ int val, val2; } IDPropertyData; typedef struct IDProperty { struct IDProperty *next, *prev; - char type, subtype; + /** #eIDPropertyType */ + char type; + /** + * #eIDPropertySubType when `type` is #IDP_STRING. + * #eIDPropertyType for all other types. + */ + char subtype; + /** #IDP_FLAG_GHOST and others. */ short flag; - /** MAX_IDPROP_NAME. */ + /** Size matches #MAX_IDPROP_NAME. */ char name[64]; /* saved is used to indicate if this struct has been saved yet. @@ -126,13 +133,16 @@ typedef struct IDProperty { /** NOTE: alignment for 64 bits. */ IDPropertyData data; - /* Array length, also (this is important!) string length + 1. - * the idea is to be able to reuse array realloc functions on strings. */ + /** + * Array length, and importantly string length + 1. + * the idea is to be able to reuse array reallocation functions on strings. + */ int len; - - /* Strings and arrays are both buffered, though the buffer isn't saved. */ - /* totallen is total length of allocated array/string, including a buffer. - * Note that the buffering is mild; the code comes from python's list implementation. */ + /** + * Strings and arrays are both buffered, though the buffer isn't saved. + * `totallen` is total length of allocated array/string, including a buffer. + * \note the buffering is mild; see #IDP_ResizeIDPArray for details. + */ int totallen; IDPropertyUIData *ui_data; @@ -141,7 +151,7 @@ typedef struct IDProperty { #define MAX_IDPROP_NAME 64 #define DEFAULT_ALLOC_FOR_NULL_STRINGS 64 -/*->type*/ +/** #IDProperty.type */ typedef enum eIDPropertyType { IDP_STRING = 0, IDP_INT = 1, @@ -173,27 +183,29 @@ enum { IDP_TYPE_FILTER_BOOLEAN = 1 << 10, }; -/*->subtype */ - -/* IDP_STRING */ -enum { +/** #IDProperty.subtype for #IDP_STRING properties. */ +typedef enum eIDPropertySubType { IDP_STRING_SUB_UTF8 = 0, /* default */ IDP_STRING_SUB_BYTE = 1, /* arbitrary byte array, _not_ null terminated */ -}; +} eIDPropertySubType; -/*->flag*/ +/** #IDProperty.flag. */ enum { - /** This IDProp may be statically overridden. - * Should only be used/be relevant for custom properties. */ + /** + * This #IDProperty may be statically overridden. + * Should only be used/be relevant for custom properties. + */ IDP_FLAG_OVERRIDABLE_LIBRARY = 1 << 0, - - /** This collection item IDProp has been inserted in a local override. + /** + * This collection item #IDProperty has been inserted in a local override. * This is used by internal code to distinguish between library-originated items and - * local-inserted ones, as many operations are not allowed on the former. */ + * local-inserted ones, as many operations are not allowed on the former. + */ IDP_FLAG_OVERRIDELIBRARY_LOCAL = 1 << 1, - - /** This means the property is set but RNA will return false when checking - * 'RNA_property_is_set', currently this is a runtime flag */ + /** + * This means the property is set but RNA will return false when checking + * #RNA_property_is_set, currently this is a runtime flag. + */ IDP_FLAG_GHOST = 1 << 7, }; @@ -208,7 +220,7 @@ typedef struct IDOverrideLibraryPropertyOperation { short operation; short flag; - /** Runtime, tags are common to both IDOverrideProperty and IDOverridePropertyOperation. */ + /** Runtime, tags are common to both #IDOverrideProperty and #IDOverridePropertyOperation. */ short tag; char _pad0[2]; From 962c3cf6b190a570ba6d2c5efdaca952f48b3299 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 17 Jan 2023 12:00:34 +1100 Subject: [PATCH 0691/1522] Cleanup: remove unused IDProperty members Remove: - IDPropertyTemplate.matrix_or_vector Matrix & vector types have been deprecated, this wasn't used. - IDProperty.saved This was added preemptively but never used, replace with a pad so as not to hint at a feature that doesn't exist. --- source/blender/blenkernel/BKE_idprop.h | 4 ---- source/blender/makesdna/DNA_ID.h | 5 ++--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h index 22470b7a629..32239a30312 100644 --- a/source/blender/blenkernel/BKE_idprop.h +++ b/source/blender/blenkernel/BKE_idprop.h @@ -39,10 +39,6 @@ typedef union IDPropertyTemplate { /** #eIDPropertyType */ char type; } array; - struct { - int matvec_size; - const float *example; - } matrix_or_vector; } IDPropertyTemplate; /* ----------- Property Array Type ---------- */ diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 43317bc0466..1e43321836f 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -127,9 +127,8 @@ typedef struct IDProperty { /** Size matches #MAX_IDPROP_NAME. */ char name[64]; - /* saved is used to indicate if this struct has been saved yet. - * seemed like a good idea as a '_pad' var was needed anyway :) */ - int saved; + char _pad0[4]; + /** NOTE: alignment for 64 bits. */ IDPropertyData data; From 8082b96a759b497888ac82d9eaf29c2643de631d Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Tue, 17 Jan 2023 09:40:08 +0100 Subject: [PATCH 0692/1522] Tracking: fix inverted pie menu items for pattern match of track The two items had their effects inverted. Reviewed By: sebastian_k Differential Revision: https://developer.blender.org/D16438 --- release/scripts/startup/bl_ui/space_clip.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py index 5bf68cb04de..076cd322360 100644 --- a/release/scripts/startup/bl_ui/space_clip.py +++ b/release/scripts/startup/bl_ui/space_clip.py @@ -1750,11 +1750,11 @@ class CLIP_MT_marker_pie(Menu): # Match Keyframe prop = pie.operator("wm.context_set_enum", text="Match Previous", icon='KEYFRAME_HLT') prop.data_path = "space_data.clip.tracking.tracks.active.pattern_match" - prop.value = 'KEYFRAME' + prop.value = 'PREV_FRAME' # Match Previous Frame prop = pie.operator("wm.context_set_enum", text="Match Keyframe", icon='KEYFRAME') prop.data_path = "space_data.clip.tracking.tracks.active.pattern_match" - prop.value = 'PREV_FRAME' + prop.value = 'KEYFRAME' class CLIP_MT_tracking_pie(Menu): From 2c6ed49c0343840a8ff05f326e5db4dd3a218775 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 17 Jan 2023 13:07:05 +0100 Subject: [PATCH 0693/1522] Cleanup: Rename confusing region variable `scaleare` reads like "scale area", but should read "scale region". --- source/blender/editors/screen/screen_ops.c | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index bd6d6d27d7c..a064f4632b5 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2586,21 +2586,21 @@ typedef struct RegionMoveData { } RegionMoveData; -static int area_max_regionsize(ScrArea *area, ARegion *scalear, AZEdge edge) +static int area_max_regionsize(ScrArea *area, ARegion *scale_region, AZEdge edge) { int dist; /* regions in regions. */ - if (scalear->alignment & RGN_SPLIT_PREV) { - const int align = RGN_ALIGN_ENUM_FROM_MASK(scalear->alignment); + if (scale_region->alignment & RGN_SPLIT_PREV) { + const int align = RGN_ALIGN_ENUM_FROM_MASK(scale_region->alignment); if (ELEM(align, RGN_ALIGN_TOP, RGN_ALIGN_BOTTOM)) { - ARegion *region = scalear->prev; - dist = region->winy + scalear->winy - U.pixelsize; + ARegion *region = scale_region->prev; + dist = region->winy + scale_region->winy - U.pixelsize; } else /* if (ELEM(align, RGN_ALIGN_LEFT, RGN_ALIGN_RIGHT)) */ { - ARegion *region = scalear->prev; - dist = region->winx + scalear->winx - U.pixelsize; + ARegion *region = scale_region->prev; + dist = region->winx + scale_region->winx - U.pixelsize; } } else { @@ -2614,23 +2614,23 @@ static int area_max_regionsize(ScrArea *area, ARegion *scalear, AZEdge edge) /* Subtract the width of regions on opposite side * prevents dragging regions into other opposite regions. */ LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { - if (region == scalear) { + if (region == scale_region) { continue; } - if (scalear->alignment == RGN_ALIGN_LEFT && region->alignment == RGN_ALIGN_RIGHT) { + if (scale_region->alignment == RGN_ALIGN_LEFT && region->alignment == RGN_ALIGN_RIGHT) { dist -= region->winx; } - else if (scalear->alignment == RGN_ALIGN_RIGHT && region->alignment == RGN_ALIGN_LEFT) { + else if (scale_region->alignment == RGN_ALIGN_RIGHT && region->alignment == RGN_ALIGN_LEFT) { dist -= region->winx; } - else if (scalear->alignment == RGN_ALIGN_TOP && + else if (scale_region->alignment == RGN_ALIGN_TOP && (region->alignment == RGN_ALIGN_BOTTOM || ELEM( region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER, RGN_TYPE_FOOTER))) { dist -= region->winy; } - else if (scalear->alignment == RGN_ALIGN_BOTTOM && + else if (scale_region->alignment == RGN_ALIGN_BOTTOM && (region->alignment == RGN_ALIGN_TOP || ELEM( region->regiontype, RGN_TYPE_HEADER, RGN_TYPE_TOOL_HEADER, RGN_TYPE_FOOTER))) { From 03fab057f1e456a13191c13a6aa2454ecd60a442 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 17 Jan 2023 13:11:56 +0100 Subject: [PATCH 0694/1522] Cleanup: correct asserts --- source/blender/blenlib/intern/array_utils.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/blenlib/intern/array_utils.cc b/source/blender/blenlib/intern/array_utils.cc index 1b5b071f0cd..1e1ef354461 100644 --- a/source/blender/blenlib/intern/array_utils.cc +++ b/source/blender/blenlib/intern/array_utils.cc @@ -10,7 +10,8 @@ void copy(const GVArray &src, const int64_t grain_size) { BLI_assert(src.type() == dst.type()); - BLI_assert(src.size() == dst.size()); + BLI_assert(src.size() >= selection.min_array_size()); + BLI_assert(dst.size() >= selection.min_array_size()); threading::parallel_for(selection.index_range(), grain_size, [&](const IndexRange range) { src.materialize_to_uninitialized(selection.slice(range), dst.data()); }); From b5105085139227a713f154446ff6a3255cb8be99 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 17 Jan 2023 13:29:55 +0100 Subject: [PATCH 0695/1522] Geometry Nodes: optimize Sample Index node with constant index Previously, the node would always evaluate the input field on the entire geometry domain. This is good when most indices will be accessed afterwards. However, it is quite a bad when only a single index is used. Now the field is only evaluated for that one index. --- .../geometry/nodes/node_geo_sample_index.cc | 39 ++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc index 4f6062cb553..850b2cfdd66 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc @@ -299,12 +299,39 @@ static void node_geo_exec(GeoNodeExecParams params) const eCustomDataType data_type = eCustomDataType(storage.data_type); const eAttrDomain domain = eAttrDomain(storage.domain); - auto fn = std::make_shared(std::move(geometry), - get_input_attribute_field(params, data_type), - domain, - bool(storage.clamp)); - auto op = FieldOperation::Create(std::move(fn), {params.extract_input>("Index")}); - output_attribute_field(params, GField(std::move(op))); + GField value_field = get_input_attribute_field(params, data_type); + ValueOrField index_value_or_field = params.extract_input>("Index"); + const CPPType &cpp_type = value_field.cpp_type(); + + GField output_field; + if (index_value_or_field.is_field()) { + /* If the index is a field, the output has to be a field that still depends on the input. */ + auto fn = std::make_shared( + std::move(geometry), std::move(value_field), domain, bool(storage.clamp)); + auto op = FieldOperation::Create(std::move(fn), {index_value_or_field.as_field()}); + output_field = GField(std::move(op)); + } + else if (const GeometryComponent *component = find_source_component(geometry, domain)) { + /* Optimization for the case when the index is a single value. Here only that one index has to + * be evaluated. */ + const int index = index_value_or_field.as_value(); + const IndexMask mask = IndexRange(index, 1); + bke::GeometryFieldContext geometry_context(*component, domain); + FieldEvaluator evaluator(geometry_context, &mask); + evaluator.add(value_field); + evaluator.evaluate(); + const GVArray &data = evaluator.get_evaluated(0); + BUFFER_FOR_CPP_TYPE_VALUE(cpp_type, buffer); + data.get_to_uninitialized(index, buffer); + output_field = fn::make_constant_field(cpp_type, cpp_type.default_value()); + cpp_type.destruct(buffer); + } + else { + /* Output default value if there is no geometry. */ + output_field = fn::make_constant_field(cpp_type, cpp_type.default_value()); + } + + output_attribute_field(params, std::move(output_field)); } } // namespace blender::nodes::node_geo_sample_index_cc From 8b660e1cbfb7f2dba55d3fb4f327c8678e9799b3 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 17 Jan 2023 13:43:38 +0100 Subject: [PATCH 0696/1522] Cleanup: use defaulted constructor --- source/blender/blenlib/BLI_color.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenlib/BLI_color.hh b/source/blender/blenlib/BLI_color.hh index 0256cec667c..f334ade6dda 100644 --- a/source/blender/blenlib/BLI_color.hh +++ b/source/blender/blenlib/BLI_color.hh @@ -248,7 +248,7 @@ class ColorSceneLinearByteEncoded4b final template class ColorTheme4 final : public ColorRGBA { public: - constexpr ColorTheme4() : ColorRGBA(){}; + constexpr ColorTheme4() = default; constexpr ColorTheme4(const ChannelStorageType *rgba) : ColorRGBA(rgba) From f8328ec172af4da655a9bfeaefd23d4e2f864ad5 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Tue, 17 Jan 2023 15:10:36 +0100 Subject: [PATCH 0697/1522] Fix: Draw: Freeze Culling Bind the frozen culling data as well. Reviewed By: fclem Differential Revision: https://developer.blender.org/D17010 --- source/blender/draw/intern/draw_view.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_view.cc b/source/blender/draw/intern/draw_view.cc index 82f614f20f2..5028b24c541 100644 --- a/source/blender/draw/intern/draw_view.cc +++ b/source/blender/draw/intern/draw_view.cc @@ -258,7 +258,8 @@ void View::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool d GPU_shader_uniform_1i(shader, "visibility_word_per_draw", word_per_draw); GPU_storagebuf_bind(bounds, GPU_shader_get_ssbo(shader, "bounds_buf")); GPU_storagebuf_bind(visibility_buf_, GPU_shader_get_ssbo(shader, "visibility_buf")); - GPU_uniformbuf_bind((frozen_) ? data_freeze_ : data_, DRW_VIEW_UBO_SLOT); + GPU_uniformbuf_bind(frozen_ ? data_freeze_ : data_, DRW_VIEW_UBO_SLOT); + GPU_uniformbuf_bind(frozen_ ? culling_freeze_ : culling_, DRW_VIEW_CULLING_UBO_SLOT); GPU_compute_dispatch(shader, divide_ceil_u(resource_len, DRW_VISIBILITY_GROUP_SIZE), 1, 1); GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE); } @@ -266,6 +267,7 @@ void View::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool d if (frozen_) { /* Bind back the non frozen data. */ GPU_uniformbuf_bind(data_, DRW_VIEW_UBO_SLOT); + GPU_uniformbuf_bind(culling_, DRW_VIEW_CULLING_UBO_SLOT); } GPU_debug_group_end(); From e144af1f7cd3e0bf4f3f3ddf4810300afb916ac2 Mon Sep 17 00:00:00 2001 From: "Kevin C. Burke" Date: Tue, 17 Jan 2023 15:43:07 +0100 Subject: [PATCH 0698/1522] GPencil: Provide Option for Fill in Material Popover The Grease Pencil Material Popover currently has a color picker for the Stroke of a Material using Solid style, but not one for a Fill using Solid style. With the default Grease Pencil Materials, the current popover only shows the Stroke color for the grey "Solid Fill" material (which doesn't have its Stroke enabled) instead of the more useful Fill color. This patch shows a Stroke color picker when the Material has Stroke enabled and the style is Solid. This is the same for the Fill. Reviewed By: antoniov, mendio Differential Revision: https://developer.blender.org/D17004 --- .../startup/bl_ui/properties_grease_pencil_common.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index e0f5d65db16..1403bb0d07e 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -565,9 +565,11 @@ class GreasePencilMaterialsPanel: if is_view3d and ma is not None and ma.grease_pencil is not None: gpcolor = ma.grease_pencil - if gpcolor.stroke_style == 'SOLID': - row = layout.row() - row.prop(gpcolor, "color", text="Stroke Color") + col = layout.column(align=True) + if gpcolor.show_stroke and gpcolor.stroke_style == 'SOLID': + col.prop(gpcolor, "color", text="Stroke Color") + if gpcolor.show_fill and gpcolor.fill_style == 'SOLID': + col.prop(gpcolor, "fill_color", text="Fill Color") else: space = context.space_data From 7df5d7c7a70963f72a71e2f19507218b51d0f188 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 17 Jan 2023 09:15:33 -0600 Subject: [PATCH 0699/1522] Cleanup: Curves selection boolean to float comparison The conversion from float to boolean is now handled by the attribute API. --- source/blender/draw/intern/draw_cache_impl_curves.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index 751fb95ce74..ba47ea576e0 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -339,13 +339,13 @@ static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id, switch (curves_id.selection_domain) { case ATTR_DOMAIN_POINT: for (const int point_i : selection.index_range()) { - const float point_selection = (selection[point_i] > 0.0f) ? 1.0f : 0.0f; + const float point_selection = selection[point_i] ? 1.0f : 0.0f; GPU_vertbuf_attr_set(cache.edit_points_data, color, point_i, &point_selection); } break; case ATTR_DOMAIN_CURVE: for (const int curve_i : curves.curves_range()) { - const float curve_selection = (selection[curve_i] > 0.0f) ? 1.0f : 0.0f; + const float curve_selection = selection[curve_i] ? 1.0f : 0.0f; const IndexRange points = curves.points_for_curve(curve_i); for (const int point_i : points) { GPU_vertbuf_attr_set(cache.edit_points_data, color, point_i, &curve_selection); From f8b11528b29b1f7565475679715e1e0c80e266de Mon Sep 17 00:00:00 2001 From: Michael Kowalski Date: Tue, 17 Jan 2023 10:24:43 -0500 Subject: [PATCH 0700/1522] USD export: ensure edit mode changes are exported Code authored by Charles Wardlaw. Reviewed by Bastien, Sybren and makowalski. Differential Revision: https://developer.blender.org/D15916 --- source/blender/io/usd/intern/usd_writer_mesh.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index 9551fea75fb..7f3444d88f4 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -18,6 +18,7 @@ #include "BKE_lib_id.h" #include "BKE_material.h" #include "BKE_mesh.h" +#include "BKE_mesh_wrapper.h" #include "BKE_modifier.h" #include "BKE_object.h" @@ -151,6 +152,8 @@ void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh) write_visibility(context, timecode, usd_mesh); USDMeshData usd_mesh_data; + /* Ensure data exists if currently in edit mode. */ + BKE_mesh_wrapper_ensure_mdata(mesh); get_geometry_data(mesh, usd_mesh_data); if (usd_export_context_.export_params.use_instancing && context.is_instance()) { From 50105b29524d9ca771e9e93c7286a0f4d21723ed Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 17 Jan 2023 09:50:06 -0600 Subject: [PATCH 0701/1522] Fix T103911: Editing boolean custom property UI data resets value The old value wasn't retrieved for boolean array properties. --- release/scripts/startup/bl_operators/wm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index fe43051281d..291e412ee75 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1623,7 +1623,7 @@ class WM_OT_properties_edit(Operator): if prop_type_new == 'BOOL_ARRAY': prop_type_old = self.get_property_type(item, name_old) - if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY'}: + if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}: return self._convert_new_value_array(item[name_old], bool, self.array_length) else: return [False] * self.array_length From 0e89d2431840386fe9bdc2f11bd83dbfb5847ba2 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 17 Jan 2023 09:51:09 -0600 Subject: [PATCH 0702/1522] Cleanup: Use elif in custom property edit operator, reduce whitespace --- release/scripts/startup/bl_operators/wm.py | 24 ++++++++-------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 291e412ee75..b8f5fc596c3 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1588,8 +1588,7 @@ class WM_OT_properties_edit(Operator): self.default_string = rna_data["default"] elif self.property_type in {'BOOL', 'BOOL_ARRAY'}: self.default_int = self._convert_new_value_array(rna_data["default"], bool, 32) - - if self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}: + elif self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}: self.array_length = len(item[name]) # The dictionary does not contain the description if it was empty. @@ -1604,33 +1603,26 @@ class WM_OT_properties_edit(Operator): def _get_converted_value(self, item, name_old, prop_type_new): if prop_type_new == 'INT': return self._convert_new_value_single(item[name_old], int) - - if prop_type_new == 'FLOAT': + elif prop_type_new == 'FLOAT': return self._convert_new_value_single(item[name_old], float) - - if prop_type_new == 'BOOL': + elif prop_type_new == 'BOOL': return self._convert_new_value_single(item[name_old], bool) - - if prop_type_new == 'INT_ARRAY': + elif prop_type_new == 'INT_ARRAY': prop_type_old = self.get_property_type(item, name_old) if prop_type_old in {'INT', 'FLOAT', 'INT_ARRAY', 'FLOAT_ARRAY', 'BOOL_ARRAY'}: return self._convert_new_value_array(item[name_old], int, self.array_length) - - if prop_type_new == 'FLOAT_ARRAY': + elif prop_type_new == 'FLOAT_ARRAY': prop_type_old = self.get_property_type(item, name_old) if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}: return self._convert_new_value_array(item[name_old], float, self.array_length) - - if prop_type_new == 'BOOL_ARRAY': + elif prop_type_new == 'BOOL_ARRAY': prop_type_old = self.get_property_type(item, name_old) if prop_type_old in {'INT', 'FLOAT', 'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}: return self._convert_new_value_array(item[name_old], bool, self.array_length) else: return [False] * self.array_length - - if prop_type_new == 'STRING': + elif prop_type_new == 'STRING': return self.convert_custom_property_to_string(item, name_old) - # If all else fails, create an empty string property. That should avoid errors later on anyway. return "" @@ -1667,7 +1659,7 @@ class WM_OT_properties_edit(Operator): default=self.default_int[0] if prop_type_new == 'INT' else self.default_int[:self.array_length], description=self.description, ) - if prop_type_new in {'BOOL', 'BOOL_ARRAY'}: + elif prop_type_new in {'BOOL', 'BOOL_ARRAY'}: ui_data = item.id_properties_ui(name) ui_data.update( default=self.default_bool[0] if prop_type_new == 'BOOL' else self.default_bool[:self.array_length], From d411de96f7d979209b4be6379836314aafc8aeba Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 17 Jan 2023 17:08:30 +0100 Subject: [PATCH 0703/1522] Fix T103936: Regression: Track To constraint broken Caused by 6769acbbba7f. Some of the matrix variants are rather obscure from the semantic: they don't really fully initialize the output: as in, they only write to an upper-left 3x3 block. A quick solution to fix the very commonly used constraint. It feels that it is possible to minimize about of copy operations. --- source/blender/blenlib/intern/math_matrix.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 7322a9facec..b8eaeb5c654 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -382,6 +382,12 @@ void mul_m4_m4m3(float R[4][4], const float A[4][4], const float B[3][3]) { if (R == A) { float T[4][4]; + /* The mul_m4_m4m3 only writes to the upper-left 3x3 block, so make it so the rest of the + * matrix is copied from the input to the output. + * + * TODO(sergey): It does sound a bit redundant from the number of copy operations, so there is + * a potential for optimization. */ + copy_m4_m4(T, A); mul_m4_m4m3(T, A, B); copy_m4_m4(R, T); return; @@ -450,6 +456,12 @@ void mul_m4_m3m4(float R[4][4], const float A[3][3], const float B[4][4]) { if (R == B) { float T[4][4]; + /* The mul_m4_m4m3 only writes to the upper-left 3x3 block, so make it so the rest of the + * matrix is copied from the input to the output. + * + * TODO(sergey): It does sound a bit redundant from the number of copy operations, so there is + * a potential for optimization. */ + copy_m4_m4(T, B); mul_m4_m3m4(T, A, B); copy_m4_m4(R, T); return; From 873794b196a2f346d5f78ab3f1a60008cf544545 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 17 Jan 2023 10:20:16 -0600 Subject: [PATCH 0704/1522] Fix T103937: Applying modifier resets shape keys The order of arguments to memcpy was reversed, which is sadly possible because the constness `KeyBlock` of keyblock doesn't propagate to pointers it contains. --- source/blender/blenkernel/intern/key.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/key.cc b/source/blender/blenkernel/intern/key.cc index 57d040c5c4f..7d835c2464d 100644 --- a/source/blender/blenkernel/intern/key.cc +++ b/source/blender/blenkernel/intern/key.cc @@ -2218,7 +2218,7 @@ void BKE_keyblock_convert_to_mesh(const KeyBlock *kb, const int totvert) { const int tot = min_ii(kb->totelem, totvert); - memcpy(kb->data, vert_positions, sizeof(float[3]) * tot); + memcpy(vert_positions, kb->data, sizeof(float[3]) * tot); } void BKE_keyblock_mesh_calc_normals(const KeyBlock *kb, From 400f022989c318a7f3cf392164713bf12e93251e Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 17 Jan 2023 10:31:07 -0600 Subject: [PATCH 0705/1522] Geometry Nodes: Add warning to set material node with no faces The node can't do anything in this case, which isn't always obvious. Resolves T103133 --- .../geometry/nodes/node_geo_set_material.cc | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_material.cc b/source/blender/nodes/geometry/nodes/node_geo_set_material.cc index e6e3eadff03..aa2930cfed9 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_material.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_material.cc @@ -65,22 +65,27 @@ static void node_geo_exec(GeoNodeExecParams params) GeometrySet geometry_set = params.extract_input("Geometry"); /* Only add the warnings once, even if there are many unique instances. */ + bool no_faces_warning = false; bool point_selection_warning = false; bool volume_selection_warning = false; bool curves_selection_warning = false; geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { - if (geometry_set.has_mesh()) { - MeshComponent &mesh_component = geometry_set.get_component_for_write(); - Mesh &mesh = *mesh_component.get_for_write(); + if (Mesh *mesh = geometry_set.get_mesh_for_write()) { + if (mesh->totpoly == 0) { + if (mesh->totvert > 0) { + no_faces_warning = true; + } + } + else { + bke::MeshFieldContext field_context{*mesh, ATTR_DOMAIN_FACE}; + fn::FieldEvaluator selection_evaluator{field_context, mesh->totpoly}; + selection_evaluator.add(selection_field); + selection_evaluator.evaluate(); + const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0); - bke::MeshFieldContext field_context{mesh, ATTR_DOMAIN_FACE}; - fn::FieldEvaluator selection_evaluator{field_context, mesh.totpoly}; - selection_evaluator.add(selection_field); - selection_evaluator.evaluate(); - const IndexMask selection = selection_evaluator.get_evaluated_as_mask(0); - - assign_material_to_faces(mesh, selection, material); + assign_material_to_faces(*mesh, selection, material); + } } if (Volume *volume = geometry_set.get_volume_for_write()) { BKE_id_material_eval_assign(&volume->id, 1, material); @@ -102,6 +107,10 @@ static void node_geo_exec(GeoNodeExecParams params) } }); + if (no_faces_warning) { + params.error_message_add(NodeWarningType::Info, + TIP_("Mesh has no faces for material assignment")); + } if (volume_selection_warning) { params.error_message_add( NodeWarningType::Info, From 543bf28fb1ff736293900d154dfb3a5da84df28a Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Tue, 17 Jan 2023 17:19:20 +0100 Subject: [PATCH 0706/1522] Refactor: renamed I -> wi, omega_in -> wo in Cycles wi is the viewing direction, and wo is the illumination direction. Under this notation, BSDF sampling always samples from wi and outputs wo, which is consistent with most of the papers and mitsuba. This order is reversed compared with PBRT, although PBRT also traces from the camera. --- intern/cycles/kernel/closure/bsdf.h | 139 +++---- .../kernel/closure/bsdf_ashikhmin_shirley.h | 34 +- .../kernel/closure/bsdf_ashikhmin_velvet.h | 54 +-- intern/cycles/kernel/closure/bsdf_diffuse.h | 36 +- .../cycles/kernel/closure/bsdf_diffuse_ramp.h | 20 +- intern/cycles/kernel/closure/bsdf_hair.h | 58 +-- .../kernel/closure/bsdf_hair_principled.h | 27 +- .../cycles/kernel/closure/bsdf_microfacet.h | 356 +++++++++--------- .../kernel/closure/bsdf_microfacet_multi.h | 88 ++--- .../cycles/kernel/closure/bsdf_oren_nayar.h | 18 +- .../cycles/kernel/closure/bsdf_phong_ramp.h | 38 +- .../kernel/closure/bsdf_principled_diffuse.h | 22 +- .../kernel/closure/bsdf_principled_sheen.h | 26 +- .../cycles/kernel/closure/bsdf_reflection.h | 16 +- .../cycles/kernel/closure/bsdf_refraction.h | 12 +- intern/cycles/kernel/closure/bsdf_toon.h | 50 +-- .../cycles/kernel/closure/bsdf_transparent.h | 10 +- intern/cycles/kernel/closure/bssrdf.h | 2 +- intern/cycles/kernel/closure/emissive.h | 19 +- intern/cycles/kernel/closure/volume.h | 24 +- intern/cycles/kernel/geom/curve.h | 2 +- intern/cycles/kernel/geom/curve_intersect.h | 4 +- intern/cycles/kernel/geom/shader_data.h | 16 +- intern/cycles/kernel/integrator/guiding.h | 42 +-- intern/cycles/kernel/integrator/mnee.h | 14 +- .../cycles/kernel/integrator/shade_surface.h | 10 +- .../cycles/kernel/integrator/shade_volume.h | 23 +- .../cycles/kernel/integrator/surface_shader.h | 53 ++- .../cycles/kernel/integrator/volume_shader.h | 28 +- intern/cycles/kernel/light/triangle.h | 6 +- intern/cycles/kernel/osl/closures_setup.h | 66 ++-- intern/cycles/kernel/osl/osl.h | 4 +- intern/cycles/kernel/osl/services.cpp | 4 +- .../osl/shaders/node_principled_bsdf.osl | 4 +- intern/cycles/kernel/sample/mapping.h | 12 +- intern/cycles/kernel/svm/closure.h | 12 +- intern/cycles/kernel/svm/displace.h | 2 +- intern/cycles/kernel/svm/fresnel.h | 6 +- intern/cycles/kernel/svm/geometry.h | 2 +- intern/cycles/kernel/svm/tex_coord.h | 12 +- intern/cycles/kernel/svm/wireframe.h | 4 +- intern/cycles/kernel/types.h | 4 +- release/datafiles/locale | 2 +- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- source/tools | 2 +- 46 files changed, 672 insertions(+), 715 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index 6de645cd1fe..2f53454d7dd 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -102,10 +102,9 @@ ccl_device_inline float shift_cos_in(float cos_in, const float frequency_multipl return val; } -ccl_device_inline bool bsdf_is_transmission(ccl_private const ShaderClosure *sc, - const float3 omega_in) +ccl_device_inline bool bsdf_is_transmission(ccl_private const ShaderClosure *sc, const float3 wo) { - return dot(sc->N, omega_in) < 0.0f; + return dot(sc->N, wo) < 0.0f; } ccl_device_inline int bsdf_sample(KernelGlobals kg, @@ -114,7 +113,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness, ccl_private float *eta) @@ -126,43 +125,43 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, switch (sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: - label = bsdf_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_diffuse_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; #if defined(__SVM__) || defined(__OSL__) case CLOSURE_BSDF_OREN_NAYAR_ID: - label = bsdf_oren_nayar_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_oren_nayar_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; # ifdef __OSL__ case CLOSURE_BSDF_PHONG_RAMP_ID: label = bsdf_phong_ramp_sample( - sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness); + sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness); *eta = 1.0f; break; case CLOSURE_BSDF_DIFFUSE_RAMP_ID: - label = bsdf_diffuse_ramp_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_diffuse_ramp_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; # endif case CLOSURE_BSDF_TRANSLUCENT_ID: - label = bsdf_translucent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_translucent_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; case CLOSURE_BSDF_REFLECTION_ID: - label = bsdf_reflection_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, eta); + label = bsdf_reflection_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf, eta); *sampled_roughness = zero_float2(); break; case CLOSURE_BSDF_REFRACTION_ID: - label = bsdf_refraction_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, eta); + label = bsdf_refraction_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf, eta); *sampled_roughness = zero_float2(); break; case CLOSURE_BSDF_TRANSPARENT_ID: - label = bsdf_transparent_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_transparent_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); *sampled_roughness = zero_float2(); *eta = 1.0f; break; @@ -171,85 +170,65 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: label = bsdf_microfacet_ggx_sample( - kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness, eta); + kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); break; case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: - label = bsdf_microfacet_multi_ggx_sample(kg, - sc, - Ng, - sd->I, - randu, - randv, - eval, - omega_in, - pdf, - &sd->lcg_state, - sampled_roughness, - eta); + label = bsdf_microfacet_multi_ggx_sample( + kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, &sd->lcg_state, sampled_roughness, eta); break; case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: - label = bsdf_microfacet_multi_ggx_glass_sample(kg, - sc, - Ng, - sd->I, - randu, - randv, - eval, - omega_in, - pdf, - &sd->lcg_state, - sampled_roughness, - eta); + label = bsdf_microfacet_multi_ggx_glass_sample( + kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, &sd->lcg_state, sampled_roughness, eta); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: label = bsdf_microfacet_beckmann_sample( - kg, sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness, eta); + kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: label = bsdf_ashikhmin_shirley_sample( - sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness); + sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness); *eta = 1.0f; break; case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - label = bsdf_ashikhmin_velvet_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_ashikhmin_velvet_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; case CLOSURE_BSDF_DIFFUSE_TOON_ID: - label = bsdf_diffuse_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_diffuse_toon_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; case CLOSURE_BSDF_GLOSSY_TOON_ID: - label = bsdf_glossy_toon_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_glossy_toon_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); // double check if this is valid *sampled_roughness = one_float2(); *eta = 1.0f; break; case CLOSURE_BSDF_HAIR_REFLECTION_ID: label = bsdf_hair_reflection_sample( - sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness); + sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness); *eta = 1.0f; break; case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: label = bsdf_hair_transmission_sample( - sc, Ng, sd->I, randu, randv, eval, omega_in, pdf, sampled_roughness); + sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness); *eta = 1.0f; break; case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: label = bsdf_principled_hair_sample( - kg, sc, sd, randu, randv, eval, omega_in, pdf, sampled_roughness, eta); + kg, sc, sd, randu, randv, eval, wo, pdf, sampled_roughness, eta); break; case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID: - label = bsdf_principled_diffuse_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_principled_diffuse_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID: - label = bsdf_principled_sheen_sample(sc, Ng, sd->I, randu, randv, eval, omega_in, pdf); + label = bsdf_principled_sheen_sample(sc, Ng, sd->wi, randu, randv, eval, wo, pdf); *sampled_roughness = one_float2(); *eta = 1.0f; break; @@ -274,12 +253,12 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, const float frequency_multiplier = kernel_data_fetch(objects, sd->object).shadow_terminator_shading_offset; if (frequency_multiplier > 1.0f) { - const float cosNI = dot(*omega_in, sc->N); - *eval *= shift_cos_in(cosNI, frequency_multiplier); + const float cosNO = dot(*wo, sc->N); + *eval *= shift_cos_in(cosNO, frequency_multiplier); } if (label & LABEL_DIFFUSE) { if (!isequal(sc->N, sd->N)) { - *eval *= bump_shadowing_term(sd->N, sc->N, *omega_in); + *eval *= bump_shadowing_term(sd->N, sc->N, *wo); } } } @@ -426,7 +405,7 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg, ccl_device_inline int bsdf_label(const KernelGlobals kg, ccl_private const ShaderClosure *sc, - const float3 omega_in) + const float3 wo) { /* For curves use the smooth normal, particularly for ribbons the geometric * normal gives too much darkening otherwise. */ @@ -482,8 +461,8 @@ ccl_device_inline int bsdf_label(const KernelGlobals kg, } case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: - label = (bsdf_is_transmission(sc, omega_in)) ? LABEL_TRANSMIT | LABEL_GLOSSY : - LABEL_REFLECT | LABEL_GLOSSY; + label = (bsdf_is_transmission(sc, wo)) ? LABEL_TRANSMIT | LABEL_GLOSSY : + LABEL_REFLECT | LABEL_GLOSSY; break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: label = LABEL_REFLECT | LABEL_GLOSSY; @@ -504,7 +483,7 @@ ccl_device_inline int bsdf_label(const KernelGlobals kg, label = LABEL_TRANSMIT | LABEL_GLOSSY; break; case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: - if (bsdf_is_transmission(sc, omega_in)) + if (bsdf_is_transmission(sc, wo)) label = LABEL_TRANSMIT | LABEL_GLOSSY; else label = LABEL_REFLECT | LABEL_GLOSSY; @@ -543,83 +522,83 @@ ccl_device_inline bsdf_eval(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private const ShaderClosure *sc, - const float3 omega_in, + const float3 wo, ccl_private float *pdf) { Spectrum eval = zero_spectrum(); switch (sc->type) { case CLOSURE_BSDF_DIFFUSE_ID: - eval = bsdf_diffuse_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_diffuse_eval(sc, sd->wi, wo, pdf); break; #if defined(__SVM__) || defined(__OSL__) case CLOSURE_BSDF_OREN_NAYAR_ID: - eval = bsdf_oren_nayar_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_oren_nayar_eval(sc, sd->wi, wo, pdf); break; # ifdef __OSL__ case CLOSURE_BSDF_PHONG_RAMP_ID: - eval = bsdf_phong_ramp_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_phong_ramp_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_DIFFUSE_RAMP_ID: - eval = bsdf_diffuse_ramp_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_diffuse_ramp_eval(sc, sd->wi, wo, pdf); break; # endif case CLOSURE_BSDF_TRANSLUCENT_ID: - eval = bsdf_translucent_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_translucent_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_REFLECTION_ID: - eval = bsdf_reflection_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_reflection_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_REFRACTION_ID: - eval = bsdf_refraction_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_refraction_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_TRANSPARENT_ID: - eval = bsdf_transparent_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_transparent_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_MICROFACET_GGX_ID: case CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID: case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: - eval = bsdf_microfacet_ggx_eval(sc, sd->N, sd->I, omega_in, pdf); + eval = bsdf_microfacet_ggx_eval(sc, sd->N, sd->wi, wo, pdf); break; case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: - eval = bsdf_microfacet_multi_ggx_eval(sc, sd->N, sd->I, omega_in, pdf, &sd->lcg_state); + eval = bsdf_microfacet_multi_ggx_eval(sc, sd->N, sd->wi, wo, pdf, &sd->lcg_state); break; case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID: - eval = bsdf_microfacet_multi_ggx_glass_eval(sc, sd->I, omega_in, pdf, &sd->lcg_state); + eval = bsdf_microfacet_multi_ggx_glass_eval(sc, sd->wi, wo, pdf, &sd->lcg_state); break; case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: - eval = bsdf_microfacet_beckmann_eval(sc, sd->N, sd->I, omega_in, pdf); + eval = bsdf_microfacet_beckmann_eval(sc, sd->N, sd->wi, wo, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: - eval = bsdf_ashikhmin_shirley_eval(sc, sd->N, sd->I, omega_in, pdf); + eval = bsdf_ashikhmin_shirley_eval(sc, sd->N, sd->wi, wo, pdf); break; case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: - eval = bsdf_ashikhmin_velvet_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_ashikhmin_velvet_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_DIFFUSE_TOON_ID: - eval = bsdf_diffuse_toon_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_diffuse_toon_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_GLOSSY_TOON_ID: - eval = bsdf_glossy_toon_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_glossy_toon_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: - eval = bsdf_principled_hair_eval(kg, sd, sc, omega_in, pdf); + eval = bsdf_principled_hair_eval(kg, sd, sc, wo, pdf); break; case CLOSURE_BSDF_HAIR_REFLECTION_ID: - eval = bsdf_hair_reflection_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_hair_reflection_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_HAIR_TRANSMISSION_ID: - eval = bsdf_hair_transmission_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_hair_transmission_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID: - eval = bsdf_principled_diffuse_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_principled_diffuse_eval(sc, sd->wi, wo, pdf); break; case CLOSURE_BSDF_PRINCIPLED_SHEEN_ID: - eval = bsdf_principled_sheen_eval(sc, sd->I, omega_in, pdf); + eval = bsdf_principled_sheen_eval(sc, sd->wi, wo, pdf); break; #endif default: @@ -628,7 +607,7 @@ ccl_device_inline if (CLOSURE_IS_BSDF_DIFFUSE(sc->type)) { if (!isequal(sc->N, sd->N)) { - eval *= bump_shadowing_term(sd->N, sc->N, omega_in); + eval *= bump_shadowing_term(sd->N, sc->N, wo); } } @@ -636,9 +615,9 @@ ccl_device_inline const float frequency_multiplier = kernel_data_fetch(objects, sd->object).shadow_terminator_shading_offset; if (frequency_multiplier > 1.0f) { - const float cosNI = dot(omega_in, sc->N); - if (cosNI >= 0.0f) { - eval *= shift_cos_in(cosNI, frequency_multiplier); + const float cosNO = dot(wo, sc->N); + if (cosNO >= 0.0f) { + eval *= shift_cos_in(cosNO, frequency_multiplier); } } diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h index db02dad3909..32f6ae17d1c 100644 --- a/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h +++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_shirley.h @@ -41,20 +41,20 @@ ccl_device_inline float bsdf_ashikhmin_shirley_roughness_to_exponent(float rough ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval(ccl_private const ShaderClosure *sc, const float3 Ng, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - const float cosNgI = dot(Ng, omega_in); + const float cosNgO = dot(Ng, wo); float3 N = bsdf->N; - float NdotI = dot(N, I); /* in Cycles/OSL convention I is omega_out */ - float NdotO = dot(N, omega_in); /* and consequently we use for O omaga_in ;) */ + float NdotI = dot(N, wi); + float NdotO = dot(N, wo); float out = 0.0f; - if ((cosNgI < 0.0f) || fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f || + if ((cosNgO < 0.0f) || fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f || !(NdotI > 0.0f && NdotO > 0.0f)) { *pdf = 0.0f; return zero_spectrum(); @@ -62,15 +62,15 @@ ccl_device_forceinline Spectrum bsdf_ashikhmin_shirley_eval(ccl_private const Sh NdotI = fmaxf(NdotI, 1e-6f); NdotO = fmaxf(NdotO, 1e-6f); - float3 H = normalize(omega_in + I); - float HdotI = fmaxf(fabsf(dot(H, I)), 1e-6f); + float3 H = normalize(wi + wo); + float HdotI = fmaxf(fabsf(dot(H, wi)), 1e-6f); float HdotN = fmaxf(dot(H, N), 1e-6f); /* pump from original paper * (first derivative disc., but cancels the HdotI in the pdf nicely) */ - float pump = 1.0f / fmaxf(1e-6f, (HdotI * fmaxf(NdotO, NdotI))); + float pump = 1.0f / fmaxf(1e-6f, (HdotI * fmaxf(NdotI, NdotO))); /* pump from d-brdf paper */ - /*float pump = 1.0f / fmaxf(1e-4f, ((NdotO + NdotI) * (NdotO*NdotI))); */ + /*float pump = 1.0f / fmaxf(1e-4f, ((NdotI + NdotO) * (NdotI * NdotO))); */ float n_x = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_x); float n_y = bsdf_ashikhmin_shirley_roughness_to_exponent(bsdf->alpha_y); @@ -124,11 +124,11 @@ ccl_device_inline void bsdf_ashikhmin_shirley_sample_first_quadrant(float n_x, ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness) { @@ -137,7 +137,7 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc float3 N = bsdf->N; int label = LABEL_REFLECT | LABEL_GLOSSY; - float NdotI = dot(N, I); + float NdotI = dot(N, wi); if (!(NdotI > 0.0f)) { *pdf = 0.0f; *eval = zero_spectrum(); @@ -198,12 +198,12 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc /* half vector to world space */ float3 H = h.x * X + h.y * Y + h.z * N; - float HdotI = dot(H, I); + float HdotI = dot(H, wi); if (HdotI < 0.0f) H = -H; - /* reflect I on H to get omega_in */ - *omega_in = -I + (2.0f * HdotI) * H; + /* reflect wi on H to get wo */ + *wo = -wi + (2.0f * HdotI) * H; if (fmaxf(bsdf->alpha_x, bsdf->alpha_y) <= 1e-4f) { /* Some high number for MIS. */ @@ -213,7 +213,7 @@ ccl_device int bsdf_ashikhmin_shirley_sample(ccl_private const ShaderClosure *sc } else { /* leave the rest to eval */ - *eval = bsdf_ashikhmin_shirley_eval(sc, N, I, *omega_in, pdf); + *eval = bsdf_ashikhmin_shirley_eval(sc, N, wi, *wo, pdf); } return label; diff --git a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h index ac2183e0848..382686cde1c 100644 --- a/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h +++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h @@ -32,35 +32,35 @@ ccl_device int bsdf_ashikhmin_velvet_setup(ccl_private VelvetBsdf *bsdf) } ccl_device Spectrum bsdf_ashikhmin_velvet_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const VelvetBsdf *bsdf = (ccl_private const VelvetBsdf *)sc; float m_invsigma2 = bsdf->invsigma2; float3 N = bsdf->N; - float cosNO = dot(N, I); - float cosNI = dot(N, omega_in); - if (!(cosNO > 0 && cosNI > 0)) { + float cosNI = dot(N, wi); + float cosNO = dot(N, wo); + if (!(cosNI > 0 && cosNO > 0)) { *pdf = 0.0f; return zero_spectrum(); } - float3 H = normalize(omega_in + I); + float3 H = normalize(wi + wo); float cosNH = dot(N, H); - float cosHO = fabsf(dot(I, H)); + float cosHI = fabsf(dot(wi, H)); - if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) { + if (!(fabsf(cosNH) < 1.0f - 1e-5f && cosHI > 1e-5f)) { *pdf = 0.0f; return zero_spectrum(); } - float cosNHdivHO = cosNH / cosHO; - cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f); + float cosNHdivHI = cosNH / cosHI; + cosNHdivHI = fmaxf(cosNHdivHI, 1e-5f); - float fac1 = 2 * fabsf(cosNHdivHO * cosNO); - float fac2 = 2 * fabsf(cosNHdivHO * cosNI); + float fac1 = 2 * fabsf(cosNHdivHI * cosNI); + float fac2 = 2 * fabsf(cosNHdivHI * cosNO); float sinNH2 = 1 - cosNH * cosNH; float sinNH4 = sinNH2 * sinNH2; @@ -69,7 +69,7 @@ ccl_device Spectrum bsdf_ashikhmin_velvet_eval(ccl_private const ShaderClosure * float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4; float G = fminf(1.0f, fminf(fac1, fac2)); // TODO: derive G from D analytically - float out = 0.25f * (D * G) / cosNO; + float out = 0.25f * (D * G) / cosNI; *pdf = 0.5f * M_1_PI_F; return make_spectrum(out); @@ -77,11 +77,11 @@ ccl_device Spectrum bsdf_ashikhmin_velvet_eval(ccl_private const ShaderClosure * ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf) { ccl_private const VelvetBsdf *bsdf = (ccl_private const VelvetBsdf *)sc; @@ -90,32 +90,32 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc, // we are viewing the surface from above - send a ray out with uniform // distribution over the hemisphere - sample_uniform_hemisphere(N, randu, randv, omega_in, pdf); + sample_uniform_hemisphere(N, randu, randv, wo, pdf); - if (!(dot(Ng, *omega_in) > 0)) { + if (!(dot(Ng, *wo) > 0)) { *pdf = 0.0f; *eval = zero_spectrum(); return LABEL_NONE; } - float3 H = normalize(*omega_in + I); + float3 H = normalize(wi + *wo); - float cosNI = dot(N, *omega_in); - float cosNO = dot(N, I); + float cosNI = dot(N, wi); + float cosNO = dot(N, *wo); + float cosHI = fabsf(dot(wi, H)); float cosNH = dot(N, H); - float cosHO = fabsf(dot(I, H)); - if (!(fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f - 1e-5f && cosHO > 1e-5f)) { + if (!(fabsf(cosNI) > 1e-5f && fabsf(cosNH) < 1.0f - 1e-5f && cosHI > 1e-5f)) { *pdf = 0.0f; *eval = zero_spectrum(); return LABEL_NONE; } - float cosNHdivHO = cosNH / cosHO; - cosNHdivHO = fmaxf(cosNHdivHO, 1e-5f); + float cosNHdivHI = cosNH / cosHI; + cosNHdivHI = fmaxf(cosNHdivHI, 1e-5f); - float fac1 = 2 * fabsf(cosNHdivHO * cosNO); - float fac2 = 2 * fabsf(cosNHdivHO * cosNI); + float fac1 = 2 * fabsf(cosNHdivHI * cosNI); + float fac2 = 2 * fabsf(cosNHdivHI * cosNO); float sinNH2 = 1 - cosNH * cosNH; float sinNH4 = sinNH2 * sinNH2; @@ -124,7 +124,7 @@ ccl_device int bsdf_ashikhmin_velvet_sample(ccl_private const ShaderClosure *sc, float D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * M_1_PI_F / sinNH4; float G = fminf(1.0f, fminf(fac1, fac2)); // TODO: derive G from D analytically - float power = 0.25f * (D * G) / cosNO; + float power = 0.25f * (D * G) / cosNI; *eval = make_spectrum(power); diff --git a/intern/cycles/kernel/closure/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h index 827b762f4c7..ac6cba76c30 100644 --- a/intern/cycles/kernel/closure/bsdf_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_diffuse.h @@ -27,34 +27,34 @@ ccl_device int bsdf_diffuse_setup(ccl_private DiffuseBsdf *bsdf) } ccl_device Spectrum bsdf_diffuse_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc; float3 N = bsdf->N; - float cos_pi = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F; - *pdf = cos_pi; - return make_spectrum(cos_pi); + float cosNO = fmaxf(dot(N, wo), 0.0f) * M_1_PI_F; + *pdf = cosNO; + return make_spectrum(cosNO); } ccl_device int bsdf_diffuse_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf) { ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc; float3 N = bsdf->N; // distribution over the hemisphere - sample_cos_hemisphere(N, randu, randv, omega_in, pdf); + sample_cos_hemisphere(N, randu, randv, wo, pdf); - if (dot(Ng, *omega_in) > 0.0f) { + if (dot(Ng, *wo) > 0.0f) { *eval = make_spectrum(*pdf); } else { @@ -73,25 +73,25 @@ ccl_device int bsdf_translucent_setup(ccl_private DiffuseBsdf *bsdf) } ccl_device Spectrum bsdf_translucent_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc; float3 N = bsdf->N; - float cos_pi = fmaxf(-dot(N, omega_in), 0.0f) * M_1_PI_F; - *pdf = cos_pi; - return make_spectrum(cos_pi); + float cosNO = fmaxf(-dot(N, wo), 0.0f) * M_1_PI_F; + *pdf = cosNO; + return make_spectrum(cosNO); } ccl_device int bsdf_translucent_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf) { ccl_private const DiffuseBsdf *bsdf = (ccl_private const DiffuseBsdf *)sc; @@ -99,8 +99,8 @@ ccl_device int bsdf_translucent_sample(ccl_private const ShaderClosure *sc, // we are viewing the surface from the right side - send a ray out with cosine // distribution over the hemisphere - sample_cos_hemisphere(-N, randu, randv, omega_in, pdf); - if (dot(Ng, *omega_in) < 0) { + sample_cos_hemisphere(-N, randu, randv, wo, pdf); + if (dot(Ng, *wo) < 0) { *eval = make_spectrum(*pdf); } else { diff --git a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h index e955ed00b92..6721f497646 100644 --- a/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h +++ b/intern/cycles/kernel/closure/bsdf_diffuse_ramp.h @@ -48,17 +48,17 @@ ccl_device void bsdf_diffuse_ramp_blur(ccl_private ShaderClosure *sc, float roug } ccl_device Spectrum bsdf_diffuse_ramp_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { const DiffuseRampBsdf *bsdf = (const DiffuseRampBsdf *)sc; float3 N = bsdf->N; - float cos_pi = fmaxf(dot(N, omega_in), 0.0f); - if (cos_pi >= 0.0f) { - *pdf = cos_pi * M_1_PI_F; - return rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, cos_pi) * M_1_PI_F); + float cosNO = fmaxf(dot(N, wo), 0.0f); + if (cosNO >= 0.0f) { + *pdf = cosNO * M_1_PI_F; + return rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, cosNO) * M_1_PI_F); } else { *pdf = 0.0f; @@ -68,20 +68,20 @@ ccl_device Spectrum bsdf_diffuse_ramp_eval(ccl_private const ShaderClosure *sc, ccl_device int bsdf_diffuse_ramp_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf) { const DiffuseRampBsdf *bsdf = (const DiffuseRampBsdf *)sc; float3 N = bsdf->N; // distribution over the hemisphere - sample_cos_hemisphere(N, randu, randv, omega_in, pdf); + sample_cos_hemisphere(N, randu, randv, wo, pdf); - if (dot(Ng, *omega_in) > 0.0f) { + if (dot(Ng, *wo) > 0.0f) { *eval = rgb_to_spectrum(bsdf_diffuse_ramp_get_color(bsdf->colors, *pdf * M_PI_F) * M_1_PI_F); } else { diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h index 989714bd695..029408ff7e4 100644 --- a/intern/cycles/kernel/closure/bsdf_hair.h +++ b/intern/cycles/kernel/closure/bsdf_hair.h @@ -38,12 +38,12 @@ ccl_device int bsdf_hair_transmission_setup(ccl_private HairBsdf *bsdf) } ccl_device Spectrum bsdf_hair_reflection_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc; - if (dot(bsdf->N, omega_in) < 0.0f) { + if (dot(bsdf->N, wo) < 0.0f) { *pdf = 0.0f; return zero_spectrum(); } @@ -53,16 +53,16 @@ ccl_device Spectrum bsdf_hair_reflection_eval(ccl_private const ShaderClosure *s float roughness1 = bsdf->roughness1; float roughness2 = bsdf->roughness2; - float Iz = dot(Tg, I); - float3 locy = normalize(I - Tg * Iz); + float Iz = dot(Tg, wi); + float3 locy = normalize(wi - Tg * Iz); float theta_r = M_PI_2_F - fast_acosf(Iz); - float omega_in_z = dot(Tg, omega_in); - float3 omega_in_y = normalize(omega_in - Tg * omega_in_z); + float wo_z = dot(Tg, wo); + float3 wo_y = normalize(wo - Tg * wo_z); - float theta_i = M_PI_2_F - fast_acosf(omega_in_z); - float cosphi_i = dot(omega_in_y, locy); + float theta_i = M_PI_2_F - fast_acosf(wo_z); + float cosphi_i = dot(wo_y, locy); if (M_PI_2_F - fabsf(theta_i) < 0.001f || cosphi_i < 0.0f) { *pdf = 0.0f; @@ -90,12 +90,12 @@ ccl_device Spectrum bsdf_hair_reflection_eval(ccl_private const ShaderClosure *s } ccl_device Spectrum bsdf_hair_transmission_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const HairBsdf *bsdf = (ccl_private const HairBsdf *)sc; - if (dot(bsdf->N, omega_in) >= 0.0f) { + if (dot(bsdf->N, wo) >= 0.0f) { *pdf = 0.0f; return zero_spectrum(); } @@ -104,16 +104,16 @@ ccl_device Spectrum bsdf_hair_transmission_eval(ccl_private const ShaderClosure float3 Tg = bsdf->T; float roughness1 = bsdf->roughness1; float roughness2 = bsdf->roughness2; - float Iz = dot(Tg, I); - float3 locy = normalize(I - Tg * Iz); + float Iz = dot(Tg, wi); + float3 locy = normalize(wi - Tg * Iz); float theta_r = M_PI_2_F - fast_acosf(Iz); - float omega_in_z = dot(Tg, omega_in); - float3 omega_in_y = normalize(omega_in - Tg * omega_in_z); + float wo_z = dot(Tg, wo); + float3 wo_y = normalize(wo - Tg * wo_z); - float theta_i = M_PI_2_F - fast_acosf(omega_in_z); - float phi_i = fast_acosf(dot(omega_in_y, locy)); + float theta_i = M_PI_2_F - fast_acosf(wo_z); + float phi_i = fast_acosf(dot(wo_y, locy)); if (M_PI_2_F - fabsf(theta_i) < 0.001f) { *pdf = 0.0f; @@ -142,11 +142,11 @@ ccl_device Spectrum bsdf_hair_transmission_eval(ccl_private const ShaderClosure ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness) { @@ -156,8 +156,8 @@ ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc, float roughness1 = bsdf->roughness1; float roughness2 = bsdf->roughness2; *sampled_roughness = make_float2(roughness1, roughness2); - float Iz = dot(Tg, I); - float3 locy = normalize(I - Tg * Iz); + float Iz = dot(Tg, wi); + float3 locy = normalize(wi - Tg * Iz); float3 locx = cross(locy, Tg); float theta_r = M_PI_2_F - fast_acosf(Iz); @@ -182,7 +182,7 @@ ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc, float sinphi, cosphi; fast_sincosf(phi, &sinphi, &cosphi); - *omega_in = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg; + *wo = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg; *pdf = fabsf(phi_pdf * theta_pdf); if (M_PI_2_F - fabsf(theta_i) < 0.001f) @@ -195,11 +195,11 @@ ccl_device int bsdf_hair_reflection_sample(ccl_private const ShaderClosure *sc, ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness) { @@ -209,8 +209,8 @@ ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc float roughness1 = bsdf->roughness1; float roughness2 = bsdf->roughness2; *sampled_roughness = make_float2(roughness1, roughness2); - float Iz = dot(Tg, I); - float3 locy = normalize(I - Tg * Iz); + float Iz = dot(Tg, wi); + float3 locy = normalize(wi - Tg * Iz); float3 locx = cross(locy, Tg); float theta_r = M_PI_2_F - fast_acosf(Iz); @@ -235,7 +235,7 @@ ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc float sinphi, cosphi; fast_sincosf(phi, &sinphi, &cosphi); - *omega_in = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg; + *wo = (cosphi * costheta_i) * locy - (sinphi * costheta_i) * locx + (sintheta_i)*Tg; *pdf = fabsf(phi_pdf * theta_pdf); if (M_PI_2_F - fabsf(theta_i) < 0.001f) { @@ -247,7 +247,7 @@ ccl_device int bsdf_hair_transmission_sample(ccl_private const ShaderClosure *sc /* TODO(sergey): Should always be negative, but seems some precision issue * is involved here. */ - kernel_assert(dot(locy, *omega_in) < 1e-4f); + kernel_assert(dot(locy, *wo) < 1e-4f); return LABEL_TRANSMIT | LABEL_GLOSSY; } diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h index 5a6465c7af6..a9e8abe0475 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_principled.h +++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h @@ -179,7 +179,7 @@ ccl_device int bsdf_principled_hair_setup(ccl_private ShaderData *sd, /* Compute local frame, aligned to curve tangent and ray direction. */ float3 X = safe_normalize(sd->dPdu); - float3 Y = safe_normalize(cross(X, sd->I)); + float3 Y = safe_normalize(cross(X, sd->wi)); float3 Z = safe_normalize(cross(X, Y)); /* h -1..0..1 means the rays goes from grazing the hair, to hitting it at @@ -259,7 +259,7 @@ ccl_device_inline void hair_alpha_angles(float sin_theta_i, ccl_device Spectrum bsdf_principled_hair_eval(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private const ShaderClosure *sc, - const float3 omega_in, + const float3 wo, ccl_private float *pdf) { kernel_assert(isfinite_safe(sd->P) && isfinite_safe(sd->ray_length)); @@ -271,12 +271,13 @@ ccl_device Spectrum bsdf_principled_hair_eval(KernelGlobals kg, kernel_assert(fabsf(dot(X, Y)) < 1e-3f); const float3 Z = safe_normalize(cross(X, Y)); - const float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z)); - const float3 wi = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z)); + /* local_I is the illumination direction. */ + const float3 local_O = make_float3(dot(sd->wi, X), dot(sd->wi, Y), dot(sd->wi, Z)); + const float3 local_I = make_float3(dot(wo, X), dot(wo, Y), dot(wo, Z)); - const float sin_theta_o = wo.x; + const float sin_theta_o = local_O.x; const float cos_theta_o = cos_from_sin(sin_theta_o); - const float phi_o = atan2f(wo.z, wo.y); + const float phi_o = atan2f(local_O.z, local_O.y); const float sin_theta_t = sin_theta_o / bsdf->eta; const float cos_theta_t = cos_from_sin(sin_theta_t); @@ -295,9 +296,9 @@ ccl_device Spectrum bsdf_principled_hair_eval(KernelGlobals kg, hair_attenuation( kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap, Ap_energy); - const float sin_theta_i = wi.x; + const float sin_theta_i = local_I.x; const float cos_theta_i = cos_from_sin(sin_theta_i); - const float phi_i = atan2f(wi.z, wi.y); + const float phi_i = atan2f(local_I.z, local_I.y); const float phi = phi_i - phi_o; @@ -343,7 +344,7 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness, ccl_private float *eta) @@ -359,16 +360,16 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg, kernel_assert(fabsf(dot(X, Y)) < 1e-3f); const float3 Z = safe_normalize(cross(X, Y)); - const float3 wo = make_float3(dot(sd->I, X), dot(sd->I, Y), dot(sd->I, Z)); + const float3 local_O = make_float3(dot(sd->wi, X), dot(sd->wi, Y), dot(sd->wi, Z)); float2 u[2]; u[0] = make_float2(randu, randv); u[1].x = lcg_step_float(&sd->lcg_state); u[1].y = lcg_step_float(&sd->lcg_state); - const float sin_theta_o = wo.x; + const float sin_theta_o = local_O.x; const float cos_theta_o = cos_from_sin(sin_theta_o); - const float phi_o = atan2f(wo.z, wo.y); + const float phi_o = atan2f(local_O.z, local_O.y); const float sin_theta_t = sin_theta_o / bsdf->eta; const float cos_theta_t = cos_from_sin(sin_theta_t); @@ -458,7 +459,7 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg, *eval = F; *pdf = F_energy; - *omega_in = X * sin_theta_i + Y * cos_theta_i * cosf(phi_i) + Z * cos_theta_i * sinf(phi_i); + *wo = X * sin_theta_i + Y * cos_theta_i * cosf(phi_i) + Z * cos_theta_i * sinf(phi_i); return LABEL_GLOSSY | ((p == 0) ? LABEL_REFLECT : LABEL_TRANSMIT); } diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index dcd55dc9bd7..611d45b73cc 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -175,7 +175,7 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, } ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, - const float3 omega_i, + const float3 wi, const float alpha_x, const float alpha_y, const float randu, @@ -183,26 +183,26 @@ ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, bool beckmann, ccl_private float *G1i) { - /* 1. stretch omega_i */ - float3 omega_i_ = make_float3(alpha_x * omega_i.x, alpha_y * omega_i.y, omega_i.z); - omega_i_ = normalize(omega_i_); + /* 1. stretch wi */ + float3 wi_ = make_float3(alpha_x * wi.x, alpha_y * wi.y, wi.z); + wi_ = normalize(wi_); - /* get polar coordinates of omega_i_ */ + /* get polar coordinates of wi_ */ float costheta_ = 1.0f; float sintheta_ = 0.0f; float cosphi_ = 1.0f; float sinphi_ = 0.0f; - if (omega_i_.z < 0.99999f) { - costheta_ = omega_i_.z; + if (wi_.z < 0.99999f) { + costheta_ = wi_.z; sintheta_ = safe_sqrtf(1.0f - costheta_ * costheta_); float invlen = 1.0f / sintheta_; - cosphi_ = omega_i_.x * invlen; - sinphi_ = omega_i_.y * invlen; + cosphi_ = wi_.x * invlen; + sinphi_ = wi_.y * invlen; } - /* 2. sample P22_{omega_i}(x_slope, y_slope, 1, 1) */ + /* 2. sample P22_{wi}(x_slope, y_slope, 1, 1) */ float slope_x, slope_y; if (beckmann) { @@ -265,7 +265,7 @@ ccl_device_forceinline void bsdf_microfacet_fresnel_color(ccl_private const Shad float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); bsdf->extra->fresnel_color = interpolate_fresnel_color( - sd->I, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0); + sd->wi, bsdf->N, bsdf->ior, F0, bsdf->extra->cspec0); if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { bsdf->extra->fresnel_color *= 0.25f * bsdf->extra->clearcoat; @@ -359,13 +359,13 @@ ccl_device void bsdf_microfacet_ggx_blur(ccl_private ShaderClosure *sc, float ro ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const MicrofacetBsdf *bsdf, const float3 N, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf, const float alpha_x, const float alpha_y, - const float cosNO, - const float cosNI) + const float cosNI, + const float cosNO) { if (!(cosNI > 0 && cosNO > 0)) { *pdf = 0.0f; @@ -373,9 +373,9 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const Microface } /* get half vector */ - float3 m = normalize(omega_in + I); + float3 m = normalize(wi + wo); float alpha2 = alpha_x * alpha_y; - float D, G1o, G1i; + float D, G1i, G1o; if (alpha_x == alpha_y) { /* isotropic @@ -399,8 +399,8 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const Microface } /* eq. 34: now calculate G1(i,m) and G1(o,m) */ - G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); + G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); } else { /* anisotropic */ @@ -420,33 +420,33 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const Microface D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4); /* G1(i,m) and G1(o,m) */ - float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO); - float cosPhiO = dot(I, X); - float sinPhiO = dot(I, Y); - - float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) + - (sinPhiO * sinPhiO) * (alpha_y * alpha_y); - alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO; - - G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2)); - float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI); - float cosPhiI = dot(omega_in, X); - float sinPhiI = dot(omega_in, Y); + float cosPhiI = dot(wi, X); + float sinPhiI = dot(wi, Y); float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) + (sinPhiI * sinPhiI) * (alpha_y * alpha_y); alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI; G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); + + float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO); + float cosPhiO = dot(wo, X); + float sinPhiO = dot(wo, Y); + + float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) + + (sinPhiO * sinPhiO) * (alpha_y * alpha_y); + alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO; + + G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2)); } - float G = G1o * G1i; + float G = G1i * G1o; /* eq. 20 */ - float common = D * 0.25f / cosNO; + float common = D * 0.25f / cosNI; - Spectrum F = reflection_color(bsdf, omega_in, m); + Spectrum F = reflection_color(bsdf, wo, m); if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { F *= 0.25f * bsdf->extra->clearcoat; } @@ -454,38 +454,38 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const Microface Spectrum out = F * G * common; /* eq. 2 in distribution of visible normals sampling - * `pm = Dw = G1o * dot(m, I) * D / dot(N, I);` */ + * `pm = Dw = G1i * dot(m, I) * D / dot(N, I);` */ /* eq. 38 - but see also: * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf * `pdf = pm * 0.25 / dot(m, I);` */ - *pdf = G1o * common; + *pdf = G1i * common; return out; } ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const MicrofacetBsdf *bsdf, const float3 N, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf, const float alpha_x, const float alpha_y, - const float cosNO, - const float cosNI) + const float cosNI, + const float cosNO) { - if (cosNO <= 0 || cosNI >= 0) { + if (cosNI <= 0 || cosNO >= 0) { *pdf = 0.0f; return zero_spectrum(); /* vectors on same side -- not possible */ } /* compute half-vector of the refraction (eq. 16) */ float m_eta = bsdf->ior; - float3 ht = -(m_eta * omega_in + I); + float3 ht = -(m_eta * wo + wi); float3 Ht = normalize(ht); - float cosHO = dot(Ht, I); - float cosHI = dot(Ht, omega_in); + float cosHI = dot(Ht, wi); + float cosHO = dot(Ht, wo); - float D, G1o, G1i; + float D, G1i, G1o; /* eq. 33: first we calculate D(m) with m=Ht: */ float alpha2 = alpha_x * alpha_y; @@ -496,61 +496,61 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const Microfac D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); /* eq. 34: now calculate G1(i,m) and G1(o,m) */ - G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); + G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - float G = G1o * G1i; + float G = G1i * G1o; /* probability */ float Ht2 = dot(ht, ht); /* eq. 2 in distribution of visible normals sampling - * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */ + * pm = Dw = G1i * dot(m, I) * D / dot(N, I); */ - /* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNO * Ht2) - * pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2 */ - float common = D * (m_eta * m_eta) / (cosNO * Ht2); + /* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNI * Ht2) + * pdf = pm * (m_eta * m_eta) * fabsf(cosHO) / Ht2 */ + float common = D * (m_eta * m_eta) / (cosNI * Ht2); float out = G * fabsf(cosHI * cosHO) * common; - *pdf = G1o * fabsf(cosHO * cosHI) * common; + *pdf = G1i * fabsf(cosHI * cosHO) * common; return make_spectrum(out); } ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc, const float3 Ng, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; const float alpha_x = bsdf->alpha_x; const float alpha_y = bsdf->alpha_y; - const float cosNgI = dot(Ng, omega_in); + const float cosNgO = dot(Ng, wo); - if (((cosNgI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) { + if (((cosNgO < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) { *pdf = 0.0f; return zero_spectrum(); } const float3 N = bsdf->N; - const float cosNO = dot(N, I); - const float cosNI = dot(N, omega_in); + const float cosNI = dot(N, wi); + const float cosNO = dot(N, wo); - return (cosNgI < 0.0f) ? bsdf_microfacet_ggx_eval_transmit( - bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) : + return (cosNgO < 0.0f) ? bsdf_microfacet_ggx_eval_transmit( + bsdf, N, wi, wo, pdf, alpha_x, alpha_y, cosNI, cosNO) : bsdf_microfacet_ggx_eval_reflect( - bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI); + bsdf, N, wi, wo, pdf, alpha_x, alpha_y, cosNI, cosNO); } ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness, ccl_private float *eta) @@ -566,8 +566,8 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, float3 N = bsdf->N; int label; - float cosNO = dot(N, I); - if (cosNO > 0) { + float cosNI = dot(N, wi); + if (cosNI > 0) { float3 X, Y, Z = N; if (alpha_x == alpha_y) @@ -577,26 +577,26 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, /* importance sampling with distribution of visible normals. vectors are * transformed to local space before and after */ - float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO); + float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cosNI); float3 local_m; - float G1o; + float G1i; local_m = microfacet_sample_stretched( - kg, local_I, alpha_x, alpha_y, randu, randv, false, &G1o); + kg, local_I, alpha_x, alpha_y, randu, randv, false, &G1i); float3 m = X * local_m.x + Y * local_m.y + Z * local_m.z; float cosThetaM = local_m.z; /* reflection or refraction? */ if (!m_refractive) { - float cosMO = dot(m, I); + float cosMI = dot(m, wi); label = LABEL_REFLECT | LABEL_GLOSSY; - if (cosMO > 0) { + if (cosMI > 0) { /* eq. 39 - compute actual reflected direction */ - *omega_in = 2 * cosMO * m - I; + *wo = 2 * cosMI * m - wi; - if (dot(Ng, *omega_in) > 0) { + if (dot(Ng, *wo) > 0) { if (alpha_x * alpha_y <= 1e-7f) { /* some high number for MIS */ *pdf = 1e6f; @@ -607,7 +607,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, /* if fresnel is used, calculate the color with reflection_color(...) */ if (use_fresnel) { - *eval *= reflection_color(bsdf, *omega_in, m); + *eval *= reflection_color(bsdf, *wo, m); } label = LABEL_REFLECT | LABEL_SINGULAR; @@ -616,7 +616,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, /* microfacet normal is visible to this ray */ /* eq. 33 */ float alpha2 = alpha_x * alpha_y; - float D, G1i; + float D, G1o; if (alpha_x == alpha_y) { /* isotropic */ @@ -624,8 +624,8 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, float cosThetaM4 = cosThetaM2 * cosThetaM2; float tanThetaM2 = 1 / (cosThetaM2)-1; - /* eval BRDF*cosNI */ - float cosNI = dot(N, *omega_in); + /* eval BRDF*cosNO */ + float cosNO = dot(N, *wo); if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { /* use GTR1 for clearcoat */ @@ -634,16 +634,16 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */ alpha2 = 0.0625f; - /* recalculate G1o */ - G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); + /* recalculate G1i */ + G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); } else { /* use GTR2 otherwise */ D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); } - /* eq. 34: now calculate G1(i,m) */ - G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); + /* eq. 34: now calculate G1(o,m) */ + G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); } else { /* anisotropic distribution */ @@ -658,27 +658,27 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4); - /* calculate G1(i,m) */ - float cosNI = dot(N, *omega_in); + /* calculate G1(o,m) */ + float cosNO = dot(N, *wo); - float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI); - float cosPhiI = dot(*omega_in, X); - float sinPhiI = dot(*omega_in, Y); + float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO); + float cosPhiO = dot(*wo, X); + float sinPhiO = dot(*wo, Y); - float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) + - (sinPhiI * sinPhiI) * (alpha_y * alpha_y); - alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI; + float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) + + (sinPhiO * sinPhiO) * (alpha_y * alpha_y); + alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO; - G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); + G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2)); } /* see eval function for derivation */ - float common = (G1o * D) * 0.25f / cosNO; + float common = (G1i * D) * 0.25f / cosNI; *pdf = common; - Spectrum F = reflection_color(bsdf, *omega_in, m); + Spectrum F = reflection_color(bsdf, *wo, m); - *eval = G1i * common * F; + *eval = G1o * common * F; } if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { @@ -694,16 +694,14 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, else { label = LABEL_TRANSMIT | LABEL_GLOSSY; - /* CAUTION: the i and o variables are inverted relative to the paper - * eq. 39 - compute actual refractive direction */ float3 R, T; float m_eta = bsdf->ior, fresnel; bool inside; - fresnel = fresnel_dielectric(m_eta, m, I, &R, &T, &inside); + fresnel = fresnel_dielectric(m_eta, m, wi, &R, &T, &inside); if (!inside && fresnel != 1.0f) { - *omega_in = T; + *wo = T; if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) { /* some high number for MIS */ @@ -719,22 +717,22 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, float tanThetaM2 = 1 / (cosThetaM2)-1; float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - /* eval BRDF*cosNI */ - float cosNI = dot(N, *omega_in); + /* eval BRDF*cosNO */ + float cosNO = dot(N, *wo); - /* eq. 34: now calculate G1(i,m) */ - float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); + /* eq. 34: now calculate G1(o,m) */ + float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); /* eq. 21 */ - float cosHI = dot(m, *omega_in); - float cosHO = dot(m, I); - float Ht2 = m_eta * cosHI + cosHO; + float cosHO = dot(m, *wo); + float cosHI = dot(m, wi); + float Ht2 = m_eta * cosHO + cosHI; Ht2 *= Ht2; /* see eval function for derivation */ - float common = (G1o * D) * (m_eta * m_eta) / (cosNO * Ht2); - float out = G1i * fabsf(cosHI * cosHO) * common; - *pdf = cosHO * fabsf(cosHI) * common; + float common = (G1i * D) * (m_eta * m_eta) / (cosNO * Ht2); + float out = G1o * fabsf(cosHI * cosHO) * common; + *pdf = cosHI * fabsf(cosHO) * common; *eval = make_spectrum(out); } @@ -823,24 +821,24 @@ ccl_device_inline float bsdf_beckmann_aniso_G1( ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const MicrofacetBsdf *bsdf, const float3 N, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf, const float alpha_x, const float alpha_y, - const float cosNO, - const float cosNI) + const float cosNI, + const float cosNO) { - if (!(cosNO > 0 && cosNI > 0)) { + if (!(cosNI > 0 && cosNO > 0)) { *pdf = 0.0f; return zero_spectrum(); } /* get half vector */ - float3 m = normalize(omega_in + I); + float3 m = normalize(wi + wo); float alpha2 = alpha_x * alpha_y; - float D, G1o, G1i; + float D, G1i, G1o; if (alpha_x == alpha_y) { /* isotropic @@ -853,8 +851,8 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const Micr D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4); /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */ - G1o = bsdf_beckmann_G1(alpha_x, cosNO); G1i = bsdf_beckmann_G1(alpha_x, cosNI); + G1o = bsdf_beckmann_G1(alpha_x, cosNO); } else { /* anisotropic */ @@ -873,48 +871,48 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const Micr D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4); /* G1(i,m) and G1(o,m) */ - G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(I, X), dot(I, Y)); - G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(omega_in, X), dot(omega_in, Y)); + G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(wi, X), dot(wi, Y)); + G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(wo, X), dot(wo, Y)); } - float G = G1o * G1i; + float G = G1i * G1o; /* eq. 20 */ - float common = D * 0.25f / cosNO; + float common = D * 0.25f / cosNI; float out = G * common; /* eq. 2 in distribution of visible normals sampling - * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */ + * pm = Dw = G1i * dot(m, I) * D / dot(N, I); */ /* eq. 38 - but see also: * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf * pdf = pm * 0.25 / dot(m, I); */ - *pdf = G1o * common; + *pdf = G1i * common; return make_spectrum(out); } ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const MicrofacetBsdf *bsdf, const float3 N, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf, const float alpha_x, const float alpha_y, - const float cosNO, - const float cosNI) + const float cosNI, + const float cosNO) { - if (cosNO <= 0 || cosNI >= 0) { + if (cosNI <= 0 || cosNO >= 0) { *pdf = 0.0f; return zero_spectrum(); } const float m_eta = bsdf->ior; /* compute half-vector of the refraction (eq. 16) */ - float3 ht = -(m_eta * omega_in + I); + float3 ht = -(m_eta * wo + wi); float3 Ht = normalize(ht); - float cosHO = dot(Ht, I); - float cosHI = dot(Ht, omega_in); + float cosHI = dot(Ht, wi); + float cosHO = dot(Ht, wo); /* eq. 25: first we calculate D(m) with m=Ht: */ float alpha2 = alpha_x * alpha_y; @@ -925,60 +923,60 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const Mic float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4); /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */ - float G1o = bsdf_beckmann_G1(alpha_x, cosNO); float G1i = bsdf_beckmann_G1(alpha_x, cosNI); - float G = G1o * G1i; + float G1o = bsdf_beckmann_G1(alpha_x, cosNO); + float G = G1i * G1o; /* probability */ float Ht2 = dot(ht, ht); /* eq. 2 in distribution of visible normals sampling - * pm = Dw = G1o * dot(m, I) * D / dot(N, I); */ + * pm = Dw = G1i * dot(m, I) * D / dot(N, I); */ - /* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNO * Ht2) - * pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2 */ - float common = D * (m_eta * m_eta) / (cosNO * Ht2); + /* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNI * Ht2) + * pdf = pm * (m_eta * m_eta) * fabsf(cosHO) / Ht2 */ + float common = D * (m_eta * m_eta) / (cosNI * Ht2); float out = G * fabsf(cosHI * cosHO) * common; - *pdf = G1o * fabsf(cosHO * cosHI) * common; + *pdf = G1i * fabsf(cosHI * cosHO) * common; return make_spectrum(out); } ccl_device Spectrum bsdf_microfacet_beckmann_eval(ccl_private const ShaderClosure *sc, const float3 Ng, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; const float alpha_x = bsdf->alpha_x; const float alpha_y = bsdf->alpha_y; - const float cosNgI = dot(Ng, omega_in); + const float cosNgO = dot(Ng, wo); - if (((cosNgI < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) { + if (((cosNgO < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) { *pdf = 0.0f; return zero_spectrum(); } const float3 N = bsdf->N; - const float cosNO = dot(N, I); - const float cosNI = dot(N, omega_in); + const float cosNI = dot(N, wi); + const float cosNO = dot(N, wo); - return (cosNI < 0.0f) ? bsdf_microfacet_beckmann_eval_transmit( - bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI) : + return (cosNO < 0.0f) ? bsdf_microfacet_beckmann_eval_transmit( + bsdf, N, wi, wo, pdf, alpha_x, alpha_y, cosNI, cosNO) : bsdf_microfacet_beckmann_eval_reflect( - bsdf, N, I, omega_in, pdf, alpha_x, alpha_y, cosNO, cosNI); + bsdf, N, wi, wo, pdf, alpha_x, alpha_y, cosNI, cosNO); } ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness, ccl_private float *eta) @@ -993,8 +991,8 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, *sampled_roughness = make_float2(alpha_x, alpha_y); *eta = m_refractive ? 1.0f / bsdf->ior : bsdf->ior; - float cosNO = dot(N, I); - if (cosNO > 0) { + float cosNI = dot(N, wi); + if (cosNI > 0) { float3 X, Y, Z = N; if (alpha_x == alpha_y) @@ -1004,11 +1002,11 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, /* importance sampling with distribution of visible normals. vectors are * transformed to local space before and after */ - float3 local_I = make_float3(dot(X, I), dot(Y, I), cosNO); + float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cosNI); float3 local_m; - float G1o; + float G1i; - local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_x, randu, randv, true, &G1o); + local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_x, randu, randv, true, &G1i); float3 m = X * local_m.x + Y * local_m.y + Z * local_m.z; float cosThetaM = local_m.z; @@ -1016,13 +1014,13 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, /* reflection or refraction? */ if (!m_refractive) { label = LABEL_REFLECT | LABEL_GLOSSY; - float cosMO = dot(m, I); + float cosMI = dot(m, wi); - if (cosMO > 0) { + if (cosMI > 0) { /* eq. 39 - compute actual reflected direction */ - *omega_in = 2 * cosMO * m - I; + *wo = 2 * cosMI * m - wi; - if (dot(Ng, *omega_in) > 0) { + if (dot(Ng, *wo) > 0) { if (alpha_x * alpha_y <= 1e-7f) { /* some high number for MIS */ *pdf = 1e6f; @@ -1033,7 +1031,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, /* microfacet normal is visible to this ray * eq. 25 */ float alpha2 = alpha_x * alpha_y; - float D, G1i; + float D, G1o; if (alpha_x == alpha_y) { /* Isotropic distribution. */ @@ -1042,11 +1040,11 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, float tanThetaM2 = 1 / (cosThetaM2)-1; D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4); - /* eval BRDF*cosNI */ - float cosNI = dot(N, *omega_in); + /* eval BRDF*cosNO */ + float cosNO = dot(N, *wo); - /* eq. 26, 27: now calculate G1(i,m) */ - G1i = bsdf_beckmann_G1(alpha_x, cosNI); + /* eq. 26, 27: now calculate G1(o,m) */ + G1o = bsdf_beckmann_G1(alpha_x, cosNO); } else { /* anisotropic distribution */ @@ -1060,17 +1058,17 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4); - /* G1(i,m) */ - G1i = bsdf_beckmann_aniso_G1( - alpha_x, alpha_y, dot(*omega_in, N), dot(*omega_in, X), dot(*omega_in, Y)); + /* G1(o,m) */ + G1o = bsdf_beckmann_aniso_G1( + alpha_x, alpha_y, dot(*wo, N), dot(*wo, X), dot(*wo, Y)); } - float G = G1o * G1i; + float G = G1i * G1o; /* see eval function for derivation */ - float common = D * 0.25f / cosNO; + float common = D * 0.25f / cosNI; float out = G * common; - *pdf = G1o * common; + *pdf = G1i * common; *eval = make_spectrum(out); } @@ -1084,16 +1082,14 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, else { label = LABEL_TRANSMIT | LABEL_GLOSSY; - /* CAUTION: the i and o variables are inverted relative to the paper - * eq. 39 - compute actual refractive direction */ float3 R, T; float m_eta = bsdf->ior, fresnel; bool inside; - fresnel = fresnel_dielectric(m_eta, m, I, &R, &T, &inside); + fresnel = fresnel_dielectric(m_eta, m, wi, &R, &T, &inside); if (!inside && fresnel != 1.0f) { - *omega_in = T; + *wo = T; if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) { /* some high number for MIS */ @@ -1109,23 +1105,23 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, float tanThetaM2 = 1 / (cosThetaM2)-1; float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4); - /* eval BRDF*cosNI */ - float cosNI = dot(N, *omega_in); + /* eval BRDF*cosNO */ + float cosNO = dot(N, *wo); - /* eq. 26, 27: now calculate G1(i,m) */ - float G1i = bsdf_beckmann_G1(alpha_x, cosNI); - float G = G1o * G1i; + /* eq. 26, 27: now calculate G1(o,m) */ + float G1o = bsdf_beckmann_G1(alpha_x, cosNO); + float G = G1i * G1o; /* eq. 21 */ - float cosHI = dot(m, *omega_in); - float cosHO = dot(m, I); - float Ht2 = m_eta * cosHI + cosHO; + float cosHI = dot(m, wi); + float cosHO = dot(m, *wo); + float Ht2 = m_eta * cosHO + cosHI; Ht2 *= Ht2; /* see eval function for derivation */ - float common = D * (m_eta * m_eta) / (cosNO * Ht2); - float out = G * fabsf(cosHI * cosHO) * common; - *pdf = G1o * cosHO * fabsf(cosHI) * common; + float common = D * (m_eta * m_eta) / (cosNI * Ht2); + float out = G * fabsf(cosHO * cosHI) * common; + *pdf = G1i * cosHI * fabsf(cosHO) * common; *eval = make_spectrum(out); } diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h index 29e1473160e..51fcd3340c6 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h @@ -417,15 +417,15 @@ ccl_device int bsdf_microfacet_multi_ggx_refraction_setup(ccl_private Microfacet ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosure *sc, const float3 Ng, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf, ccl_private uint *lcg_state) { ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - const float cosNgI = dot(Ng, omega_in); + const float cosNgO = dot(Ng, wo); - if ((cosNgI < 0.0f) || bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { + if ((cosNgO < 0.0f) || bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { *pdf = 0.0f; return zero_spectrum(); } @@ -434,7 +434,7 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosu Z = bsdf->N; /* Ensure that the both directions are on the outside w.r.t. the shading normal. */ - if (dot(Z, I) <= 0.0f || dot(Z, omega_in) <= 0.0f) { + if (dot(Z, wi) <= 0.0f || dot(Z, wo) <= 0.0f) { *pdf = 0.0f; return zero_spectrum(); } @@ -447,21 +447,21 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosu else make_orthonormals(Z, &X, &Y); - float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z)); - float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z)); + float3 local_I = make_float3(dot(wi, X), dot(wi, Y), dot(wi, Z)); + float3 local_O = make_float3(dot(wo, X), dot(wo, Y), dot(wo, Z)); if (is_aniso) - *pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y)); + *pdf = mf_ggx_aniso_pdf(local_I, local_O, make_float2(bsdf->alpha_x, bsdf->alpha_y)); else - *pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x); + *pdf = mf_ggx_pdf(local_I, local_O, bsdf->alpha_x); if (*pdf <= 0.f) { *pdf = 0.f; return make_float3(0.f, 0.f, 0.f); } - return mf_eval_glossy(localI, - localO, + return mf_eval_glossy(local_I, + local_O, true, bsdf->extra->color, bsdf->alpha_x, @@ -475,11 +475,11 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_eval(ccl_private const ShaderClosu ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg, ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private uint *lcg_state, ccl_private float2 *sampled_roughness, @@ -491,7 +491,7 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg, Z = bsdf->N; /* Ensure that the view direction is on the outside w.r.t. the shading normal. */ - if (dot(Z, I) <= 0.0f) { + if (dot(Z, wi) <= 0.0f) { *pdf = 0.0f; return LABEL_NONE; } @@ -499,8 +499,8 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg, /* Special case: Extremely low roughness. * Don't bother with microfacets, just do specular reflection. */ if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { - *omega_in = 2 * dot(Z, I) * Z - I; - if (dot(Ng, *omega_in) <= 0.0f) { + *wo = 2 * dot(Z, wi) * Z - wi; + if (dot(Ng, *wo) <= 0.0f) { *pdf = 0.0f; return LABEL_NONE; } @@ -520,11 +520,11 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg, else make_orthonormals(Z, &X, &Y); - float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z)); - float3 localO; + float3 local_I = make_float3(dot(wi, X), dot(wi, Y), dot(wi, Z)); + float3 local_O; - *eval = mf_sample_glossy(localI, - &localO, + *eval = mf_sample_glossy(local_I, + &local_O, bsdf->extra->color, bsdf->alpha_x, bsdf->alpha_y, @@ -532,18 +532,18 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg, bsdf->ior, use_fresnel, bsdf->extra->cspec0); - *omega_in = X * localO.x + Y * localO.y + Z * localO.z; + *wo = X * local_O.x + Y * local_O.y + Z * local_O.z; /* Ensure that the light direction is on the outside w.r.t. the geometry normal. */ - if (dot(Ng, *omega_in) <= 0.0f) { + if (dot(Ng, *wo) <= 0.0f) { *pdf = 0.0f; return LABEL_NONE; } if (is_aniso) - *pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y)); + *pdf = mf_ggx_aniso_pdf(local_I, local_O, make_float2(bsdf->alpha_x, bsdf->alpha_y)); else - *pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x); + *pdf = mf_ggx_pdf(local_I, local_O, bsdf->alpha_x); *pdf = fmaxf(0.f, *pdf); *eval *= *pdf; @@ -581,8 +581,8 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private Microfa } ccl_device Spectrum bsdf_microfacet_multi_ggx_glass_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf, ccl_private uint *lcg_state) { @@ -597,17 +597,17 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_glass_eval(ccl_private const Shade Z = bsdf->N; make_orthonormals(Z, &X, &Y); - float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z)); - float3 localO = make_float3(dot(omega_in, X), dot(omega_in, Y), dot(omega_in, Z)); + float3 local_I = make_float3(dot(wi, X), dot(wi, Y), dot(wi, Z)); + float3 local_O = make_float3(dot(wo, X), dot(wo, Y), dot(wo, Z)); - const bool is_transmission = localO.z < 0.0f; + const bool is_transmission = local_O.z < 0.0f; const bool use_fresnel = !is_transmission && (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID); - *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior); + *pdf = mf_glass_pdf(local_I, local_O, bsdf->alpha_x, bsdf->ior); kernel_assert(*pdf >= 0.f); - return mf_eval_glass(localI, - localO, + return mf_eval_glass(local_I, + local_O, !is_transmission, bsdf->extra->color, bsdf->alpha_x, @@ -621,11 +621,11 @@ ccl_device Spectrum bsdf_microfacet_multi_ggx_glass_eval(ccl_private const Shade ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg, ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private uint *lcg_state, ccl_private float2 *sampled_roughness, @@ -642,16 +642,16 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg, if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) { float3 R, T; bool inside; - float fresnel = fresnel_dielectric(bsdf->ior, Z, I, &R, &T, &inside); + float fresnel = fresnel_dielectric(bsdf->ior, Z, wi, &R, &T, &inside); *pdf = 1e6f; *eval = make_spectrum(1e6f); if (randu < fresnel) { - *omega_in = R; + *wo = R; return LABEL_REFLECT | LABEL_SINGULAR; } else { - *omega_in = T; + *wo = T; return LABEL_TRANSMIT | LABEL_SINGULAR; } } @@ -660,11 +660,11 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg, make_orthonormals(Z, &X, &Y); - float3 localI = make_float3(dot(I, X), dot(I, Y), dot(I, Z)); - float3 localO; + float3 local_I = make_float3(dot(wi, X), dot(wi, Y), dot(wi, Z)); + float3 local_O; - *eval = mf_sample_glass(localI, - &localO, + *eval = mf_sample_glass(local_I, + &local_O, bsdf->extra->color, bsdf->alpha_x, bsdf->alpha_y, @@ -672,12 +672,12 @@ ccl_device int bsdf_microfacet_multi_ggx_glass_sample(KernelGlobals kg, bsdf->ior, use_fresnel, bsdf->extra->cspec0); - *pdf = mf_glass_pdf(localI, localO, bsdf->alpha_x, bsdf->ior); + *pdf = mf_glass_pdf(local_I, local_O, bsdf->alpha_x, bsdf->ior); kernel_assert(*pdf >= 0.f); *eval *= *pdf; - *omega_in = X * localO.x + Y * localO.y + Z * localO.z; - if (localO.z * localI.z > 0.0f) { + *wo = X * local_O.x + Y * local_O.y + Z * local_O.z; + if (local_O.z * local_I.z > 0.0f) { return LABEL_REFLECT | LABEL_GLOSSY; } else { diff --git a/intern/cycles/kernel/closure/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h index 6912d5b3f18..3f6074be53c 100644 --- a/intern/cycles/kernel/closure/bsdf_oren_nayar.h +++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h @@ -48,14 +48,14 @@ ccl_device int bsdf_oren_nayar_setup(ccl_private OrenNayarBsdf *bsdf) } ccl_device Spectrum bsdf_oren_nayar_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const OrenNayarBsdf *bsdf = (ccl_private const OrenNayarBsdf *)sc; - if (dot(bsdf->N, omega_in) > 0.0f) { + if (dot(bsdf->N, wo) > 0.0f) { *pdf = 0.5f * M_1_PI_F; - return bsdf_oren_nayar_get_intensity(sc, bsdf->N, I, omega_in); + return bsdf_oren_nayar_get_intensity(sc, bsdf->N, wi, wo); } else { *pdf = 0.0f; @@ -65,18 +65,18 @@ ccl_device Spectrum bsdf_oren_nayar_eval(ccl_private const ShaderClosure *sc, ccl_device int bsdf_oren_nayar_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf) { ccl_private const OrenNayarBsdf *bsdf = (ccl_private const OrenNayarBsdf *)sc; - sample_uniform_hemisphere(bsdf->N, randu, randv, omega_in, pdf); + sample_uniform_hemisphere(bsdf->N, randu, randv, wo, pdf); - if (dot(Ng, *omega_in) > 0.0f) { - *eval = bsdf_oren_nayar_get_intensity(sc, bsdf->N, I, *omega_in); + if (dot(Ng, *wo) > 0.0f) { + *eval = bsdf_oren_nayar_get_intensity(sc, bsdf->N, wi, *wo); } else { *pdf = 0.0f; diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h index 04bc165af30..5e2b9aad233 100644 --- a/intern/cycles/kernel/closure/bsdf_phong_ramp.h +++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h @@ -45,23 +45,23 @@ ccl_device int bsdf_phong_ramp_setup(ccl_private PhongRampBsdf *bsdf) } ccl_device Spectrum bsdf_phong_ramp_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc; float m_exponent = bsdf->exponent; - float cosNI = dot(bsdf->N, omega_in); - float cosNO = dot(bsdf->N, I); + float cosNI = dot(bsdf->N, wi); + float cosNO = dot(bsdf->N, wo); if (cosNI > 0 && cosNO > 0) { // reflect the view vector - float3 R = (2 * cosNO) * bsdf->N - I; - float cosRI = dot(R, omega_in); - if (cosRI > 0) { - float cosp = powf(cosRI, m_exponent); + float3 R = (2 * cosNI) * bsdf->N - wi; + float cosRO = dot(R, wo); + if (cosRO > 0) { + float cosp = powf(cosRO, m_exponent); float common = 0.5f * M_1_PI_F * cosp; - float out = cosNI * (m_exponent + 2) * common; + float out = cosNO * (m_exponent + 2) * common; *pdf = (m_exponent + 1) * common; return rgb_to_spectrum(bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out); } @@ -77,39 +77,39 @@ ccl_device_inline float phong_ramp_exponent_to_roughness(float exponent) ccl_device int bsdf_phong_ramp_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness) { ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc; - float cosNO = dot(bsdf->N, I); + float cosNI = dot(bsdf->N, wi); float m_exponent = bsdf->exponent; const float m_roughness = phong_ramp_exponent_to_roughness(m_exponent); *sampled_roughness = make_float2(m_roughness, m_roughness); - if (cosNO > 0) { + if (cosNI > 0) { // reflect the view vector - float3 R = (2 * cosNO) * bsdf->N - I; + float3 R = (2 * cosNI) * bsdf->N - wi; float3 T, B; make_orthonormals(R, &T, &B); float phi = M_2PI_F * randu; float cosTheta = powf(randv, 1 / (m_exponent + 1)); float sinTheta2 = 1 - cosTheta * cosTheta; float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0; - *omega_in = (cosf(phi) * sinTheta) * T + (sinf(phi) * sinTheta) * B + (cosTheta)*R; - if (dot(Ng, *omega_in) > 0.0f) { + *wo = (cosf(phi) * sinTheta) * T + (sinf(phi) * sinTheta) * B + (cosTheta)*R; + if (dot(Ng, *wo) > 0.0f) { // common terms for pdf and eval - float cosNI = dot(bsdf->N, *omega_in); + float cosNO = dot(bsdf->N, *wo); // make sure the direction we chose is still in the right hemisphere - if (cosNI > 0) { + if (cosNO > 0) { float cosp = powf(cosTheta, m_exponent); float common = 0.5f * M_1_PI_F * cosp; *pdf = (m_exponent + 1) * common; - float out = cosNI * (m_exponent + 2) * common; + float out = cosNO * (m_exponent + 2) * common; *eval = rgb_to_spectrum(bsdf_phong_ramp_get_color(bsdf->colors, cosp) * out); } } diff --git a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h index be8ee78fcac..a63492eadd9 100644 --- a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h @@ -110,17 +110,17 @@ ccl_device int bsdf_principled_diffuse_setup(ccl_private PrincipledDiffuseBsdf * } ccl_device Spectrum bsdf_principled_diffuse_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)sc; const float3 N = bsdf->N; - if (dot(N, omega_in) > 0.0f) { - const float3 V = I; // outgoing - const float3 L = omega_in; // incoming - *pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F; + if (dot(N, wo) > 0.0f) { + const float3 V = wi; + const float3 L = wo; + *pdf = fmaxf(dot(N, wo), 0.0f) * M_1_PI_F; return bsdf_principled_diffuse_compute_brdf(bsdf, N, V, L, pdf); } else { @@ -131,21 +131,21 @@ ccl_device Spectrum bsdf_principled_diffuse_eval(ccl_private const ShaderClosure ccl_device int bsdf_principled_diffuse_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf) { ccl_private const PrincipledDiffuseBsdf *bsdf = (ccl_private const PrincipledDiffuseBsdf *)sc; float3 N = bsdf->N; - sample_cos_hemisphere(N, randu, randv, omega_in, pdf); + sample_cos_hemisphere(N, randu, randv, wo, pdf); - if (dot(Ng, *omega_in) > 0) { - *eval = bsdf_principled_diffuse_compute_brdf(bsdf, N, I, *omega_in, pdf); + if (dot(Ng, *wo) > 0) { + *eval = bsdf_principled_diffuse_compute_brdf(bsdf, N, wi, *wo, pdf); } else { *pdf = 0.0f; diff --git a/intern/cycles/kernel/closure/bsdf_principled_sheen.h b/intern/cycles/kernel/closure/bsdf_principled_sheen.h index f6499cc437c..06296f1cef5 100644 --- a/intern/cycles/kernel/closure/bsdf_principled_sheen.h +++ b/intern/cycles/kernel/closure/bsdf_principled_sheen.h @@ -54,25 +54,25 @@ ccl_device int bsdf_principled_sheen_setup(ccl_private const ShaderData *sd, ccl_private PrincipledSheenBsdf *bsdf) { bsdf->type = CLOSURE_BSDF_PRINCIPLED_SHEEN_ID; - bsdf->avg_value = calculate_avg_principled_sheen_brdf(bsdf->N, sd->I); + bsdf->avg_value = calculate_avg_principled_sheen_brdf(bsdf->N, sd->wi); bsdf->sample_weight *= bsdf->avg_value; return SD_BSDF | SD_BSDF_HAS_EVAL; } ccl_device Spectrum bsdf_principled_sheen_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const PrincipledSheenBsdf *bsdf = (ccl_private const PrincipledSheenBsdf *)sc; const float3 N = bsdf->N; - if (dot(N, omega_in) > 0.0f) { - const float3 V = I; // outgoing - const float3 L = omega_in; // incoming + if (dot(N, wo) > 0.0f) { + const float3 V = wi; + const float3 L = wo; const float3 H = normalize(L + V); - *pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F; + *pdf = fmaxf(dot(N, wo), 0.0f) * M_1_PI_F; return calculate_principled_sheen_brdf(N, V, L, H, pdf); } else { @@ -83,23 +83,23 @@ ccl_device Spectrum bsdf_principled_sheen_eval(ccl_private const ShaderClosure * ccl_device int bsdf_principled_sheen_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf) { ccl_private const PrincipledSheenBsdf *bsdf = (ccl_private const PrincipledSheenBsdf *)sc; float3 N = bsdf->N; - sample_cos_hemisphere(N, randu, randv, omega_in, pdf); + sample_cos_hemisphere(N, randu, randv, wo, pdf); - if (dot(Ng, *omega_in) > 0) { - float3 H = normalize(I + *omega_in); + if (dot(Ng, *wo) > 0) { + float3 H = normalize(wi + *wo); - *eval = calculate_principled_sheen_brdf(N, I, *omega_in, H, pdf); + *eval = calculate_principled_sheen_brdf(N, wi, *wo, H, pdf); } else { *eval = zero_spectrum(); diff --git a/intern/cycles/kernel/closure/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h index 2f761974e9a..71ee5f389d2 100644 --- a/intern/cycles/kernel/closure/bsdf_reflection.h +++ b/intern/cycles/kernel/closure/bsdf_reflection.h @@ -19,8 +19,8 @@ ccl_device int bsdf_reflection_setup(ccl_private MicrofacetBsdf *bsdf) } ccl_device Spectrum bsdf_reflection_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { *pdf = 0.0f; @@ -29,11 +29,11 @@ ccl_device Spectrum bsdf_reflection_eval(ccl_private const ShaderClosure *sc, ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private float *eta) { @@ -42,10 +42,10 @@ ccl_device int bsdf_reflection_sample(ccl_private const ShaderClosure *sc, *eta = bsdf->ior; // only one direction is possible - float cosNO = dot(N, I); - if (cosNO > 0) { - *omega_in = (2 * cosNO) * N - I; - if (dot(Ng, *omega_in) > 0) { + float cosNI = dot(N, wi); + if (cosNI > 0) { + *wo = (2 * cosNI) * N - wi; + if (dot(Ng, *wo) > 0) { /* Some high number for MIS. */ *pdf = 1e6f; *eval = make_spectrum(1e6f); diff --git a/intern/cycles/kernel/closure/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h index e4f66245a0b..f4beff81dd1 100644 --- a/intern/cycles/kernel/closure/bsdf_refraction.h +++ b/intern/cycles/kernel/closure/bsdf_refraction.h @@ -19,8 +19,8 @@ ccl_device int bsdf_refraction_setup(ccl_private MicrofacetBsdf *bsdf) } ccl_device Spectrum bsdf_refraction_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { *pdf = 0.0f; @@ -29,11 +29,11 @@ ccl_device Spectrum bsdf_refraction_eval(ccl_private const ShaderClosure *sc, ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private float *eta) { @@ -46,13 +46,13 @@ ccl_device int bsdf_refraction_sample(ccl_private const ShaderClosure *sc, float3 R, T; bool inside; float fresnel; - fresnel = fresnel_dielectric(m_eta, N, I, &R, &T, &inside); + fresnel = fresnel_dielectric(m_eta, N, wi, &R, &T, &inside); if (!inside && fresnel != 1.0f) { /* Some high number for MIS. */ *pdf = 1e6f; *eval = make_spectrum(1e6f); - *omega_in = T; + *wo = T; } else { *pdf = 0.0f; diff --git a/intern/cycles/kernel/closure/bsdf_toon.h b/intern/cycles/kernel/closure/bsdf_toon.h index 9f78c86b3b7..1b109da0e4f 100644 --- a/intern/cycles/kernel/closure/bsdf_toon.h +++ b/intern/cycles/kernel/closure/bsdf_toon.h @@ -50,17 +50,17 @@ ccl_device float bsdf_toon_get_sample_angle(float max_angle, float smooth) } ccl_device Spectrum bsdf_diffuse_toon_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc; - float cosNI = dot(bsdf->N, omega_in); + float cosNO = dot(bsdf->N, wo); - if (cosNI >= 0.0f) { + if (cosNO >= 0.0f) { float max_angle = bsdf->size * M_PI_2_F; float smooth = bsdf->smooth * M_PI_2_F; - float angle = safe_acosf(fmaxf(cosNI, 0.0f)); + float angle = safe_acosf(fmaxf(cosNO, 0.0f)); float eval = bsdf_toon_get_intensity(max_angle, smooth, angle); @@ -78,11 +78,11 @@ ccl_device Spectrum bsdf_diffuse_toon_eval(ccl_private const ShaderClosure *sc, ccl_device int bsdf_diffuse_toon_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf) { ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc; @@ -92,9 +92,9 @@ ccl_device int bsdf_diffuse_toon_sample(ccl_private const ShaderClosure *sc, float angle = sample_angle * randu; if (sample_angle > 0.0f) { - sample_uniform_cone(bsdf->N, sample_angle, randu, randv, omega_in, pdf); + sample_uniform_cone(bsdf->N, sample_angle, randu, randv, wo, pdf); - if (dot(Ng, *omega_in) > 0.0f) { + if (dot(Ng, *wo) > 0.0f) { *eval = make_spectrum(*pdf * bsdf_toon_get_intensity(max_angle, smooth, angle)); } else { @@ -122,22 +122,22 @@ ccl_device int bsdf_glossy_toon_setup(ccl_private ToonBsdf *bsdf) } ccl_device Spectrum bsdf_glossy_toon_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc; float max_angle = bsdf->size * M_PI_2_F; float smooth = bsdf->smooth * M_PI_2_F; - float cosNI = dot(bsdf->N, omega_in); - float cosNO = dot(bsdf->N, I); + float cosNI = dot(bsdf->N, wi); + float cosNO = dot(bsdf->N, wo); if (cosNI > 0 && cosNO > 0) { /* reflect the view vector */ - float3 R = (2 * cosNO) * bsdf->N - I; - float cosRI = dot(R, omega_in); + float3 R = (2 * cosNI) * bsdf->N - wi; + float cosRO = dot(R, wo); - float angle = safe_acosf(fmaxf(cosRI, 0.0f)); + float angle = safe_acosf(fmaxf(cosRO, 0.0f)); float eval = bsdf_toon_get_intensity(max_angle, smooth, angle); float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth); @@ -151,32 +151,32 @@ ccl_device Spectrum bsdf_glossy_toon_eval(ccl_private const ShaderClosure *sc, ccl_device int bsdf_glossy_toon_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf) { ccl_private const ToonBsdf *bsdf = (ccl_private const ToonBsdf *)sc; float max_angle = bsdf->size * M_PI_2_F; float smooth = bsdf->smooth * M_PI_2_F; - float cosNO = dot(bsdf->N, I); + float cosNI = dot(bsdf->N, wi); - if (cosNO > 0) { + if (cosNI > 0) { /* reflect the view vector */ - float3 R = (2 * cosNO) * bsdf->N - I; + float3 R = (2 * cosNI) * bsdf->N - wi; float sample_angle = bsdf_toon_get_sample_angle(max_angle, smooth); float angle = sample_angle * randu; - sample_uniform_cone(R, sample_angle, randu, randv, omega_in, pdf); + sample_uniform_cone(R, sample_angle, randu, randv, wo, pdf); - if (dot(Ng, *omega_in) > 0.0f) { - float cosNI = dot(bsdf->N, *omega_in); + if (dot(Ng, *wo) > 0.0f) { + float cosNO = dot(bsdf->N, *wo); /* make sure the direction we chose is still in the right hemisphere */ - if (cosNI > 0) { + if (cosNO > 0) { *eval = make_spectrum(*pdf * bsdf_toon_get_intensity(max_angle, smooth, angle)); } else { diff --git a/intern/cycles/kernel/closure/bsdf_transparent.h b/intern/cycles/kernel/closure/bsdf_transparent.h index 9306e82b579..9c7607e2e97 100644 --- a/intern/cycles/kernel/closure/bsdf_transparent.h +++ b/intern/cycles/kernel/closure/bsdf_transparent.h @@ -60,8 +60,8 @@ ccl_device void bsdf_transparent_setup(ccl_private ShaderData *sd, } ccl_device Spectrum bsdf_transparent_eval(ccl_private const ShaderClosure *sc, - const float3 I, - const float3 omega_in, + const float3 wi, + const float3 wo, ccl_private float *pdf) { *pdf = 0.0f; @@ -70,15 +70,15 @@ ccl_device Spectrum bsdf_transparent_eval(ccl_private const ShaderClosure *sc, ccl_device int bsdf_transparent_sample(ccl_private const ShaderClosure *sc, float3 Ng, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf) { // only one direction is possible - *omega_in = -I; + *wo = -wi; *pdf = 1; *eval = one_spectrum(); return LABEL_TRANSMIT | LABEL_TRANSPARENT; diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h index 7131d9d8f38..f03e3ad507e 100644 --- a/intern/cycles/kernel/closure/bssrdf.h +++ b/intern/cycles/kernel/closure/bssrdf.h @@ -293,7 +293,7 @@ ccl_device int bssrdf_setup(ccl_private ShaderData *sd, /* Ad-hoc weight adjustment to avoid retro-reflection taking away half the * samples from BSSRDF. */ - bsdf->sample_weight *= bsdf_principled_diffuse_retro_reflection_sample_weight(bsdf, sd->I); + bsdf->sample_weight *= bsdf_principled_diffuse_retro_reflection_sample_weight(bsdf, sd->wi); } } diff --git a/intern/cycles/kernel/closure/emissive.h b/intern/cycles/kernel/closure/emissive.h index d896721f77b..36af7377504 100644 --- a/intern/cycles/kernel/closure/emissive.h +++ b/intern/cycles/kernel/closure/emissive.h @@ -36,27 +36,24 @@ ccl_device void emission_setup(ccl_private ShaderData *sd, const Spectrum weight } } -/* return the probability distribution function in the direction I, +/* return the probability distribution function in the direction wi, * given the parameters and the light's surface normal. This MUST match * the PDF computed by sample(). */ -ccl_device float emissive_pdf(const float3 Ng, const float3 I) +ccl_device float emissive_pdf(const float3 Ng, const float3 wi) { - float cosNO = fabsf(dot(Ng, I)); - return (cosNO > 0.0f) ? 1.0f : 0.0f; + float cosNI = fabsf(dot(Ng, wi)); + return (cosNI > 0.0f) ? 1.0f : 0.0f; } -ccl_device void emissive_sample(const float3 Ng, - float randu, - float randv, - ccl_private float3 *omega_out, - ccl_private float *pdf) +ccl_device void emissive_sample( + const float3 Ng, float randu, float randv, ccl_private float3 *wi, ccl_private float *pdf) { /* todo: not implemented and used yet */ } -ccl_device Spectrum emissive_simple_eval(const float3 Ng, const float3 I) +ccl_device Spectrum emissive_simple_eval(const float3 Ng, const float3 wi) { - float res = emissive_pdf(Ng, I); + float res = emissive_pdf(Ng, wi); return make_spectrum(res); } diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h index 9dbb5154457..e6af2c01fcc 100644 --- a/intern/cycles/kernel/closure/volume.h +++ b/intern/cycles/kernel/closure/volume.h @@ -49,18 +49,18 @@ ccl_device int volume_henyey_greenstein_setup(ccl_private HenyeyGreensteinVolume } ccl_device Spectrum volume_henyey_greenstein_eval_phase(ccl_private const ShaderVolumeClosure *svc, - const float3 I, - float3 omega_in, + const float3 wi, + float3 wo, ccl_private float *pdf) { float g = svc->g; - /* note that I points towards the viewer */ + /* note that wi points towards the viewer */ if (fabsf(g) < 1e-3f) { *pdf = M_1_PI_F * 0.25f; } else { - float cos_theta = dot(-I, omega_in); + float cos_theta = dot(-wi, wo); *pdf = single_peaked_henyey_greenstein(cos_theta, g); } @@ -100,17 +100,17 @@ henyey_greenstrein_sample(float3 D, float g, float randu, float randv, ccl_priva } ccl_device int volume_henyey_greenstein_sample(ccl_private const ShaderVolumeClosure *svc, - float3 I, + float3 wi, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf) { float g = svc->g; - /* note that I points towards the viewer and so is used negated */ - *omega_in = henyey_greenstrein_sample(-I, g, randu, randv, pdf); + /* note that wi points towards the viewer and so is used negated */ + *wo = henyey_greenstrein_sample(-wi, g, randu, randv, pdf); *eval = make_spectrum(*pdf); /* perfect importance sampling */ return LABEL_VOLUME_SCATTER; @@ -120,10 +120,10 @@ ccl_device int volume_henyey_greenstein_sample(ccl_private const ShaderVolumeClo ccl_device Spectrum volume_phase_eval(ccl_private const ShaderData *sd, ccl_private const ShaderVolumeClosure *svc, - float3 omega_in, + float3 wo, ccl_private float *pdf) { - return volume_henyey_greenstein_eval_phase(svc, sd->I, omega_in, pdf); + return volume_henyey_greenstein_eval_phase(svc, sd->wi, wo, pdf); } ccl_device int volume_phase_sample(ccl_private const ShaderData *sd, @@ -131,10 +131,10 @@ ccl_device int volume_phase_sample(ccl_private const ShaderData *sd, float randu, float randv, ccl_private Spectrum *eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf) { - return volume_henyey_greenstein_sample(svc, sd->I, randu, randv, eval, omega_in, pdf); + return volume_henyey_greenstein_sample(svc, sd->wi, randu, randv, eval, wo, pdf); } /* Volume sampling utilities. */ diff --git a/intern/cycles/kernel/geom/curve.h b/intern/cycles/kernel/geom/curve.h index e243adfde21..307da6e8ac8 100644 --- a/intern/cycles/kernel/geom/curve.h +++ b/intern/cycles/kernel/geom/curve.h @@ -252,7 +252,7 @@ ccl_device float3 curve_tangent_normal(KernelGlobals kg, ccl_private const Shade if (sd->type & PRIMITIVE_CURVE) { - tgN = -(-sd->I - sd->dPdu * (dot(sd->dPdu, -sd->I) / len_squared(sd->dPdu))); + tgN = -(-sd->wi - sd->dPdu * (dot(sd->dPdu, -sd->wi) / len_squared(sd->dPdu))); tgN = normalize(tgN); /* need to find suitable scaled gd for corrected normal */ diff --git a/intern/cycles/kernel/geom/curve_intersect.h b/intern/cycles/kernel/geom/curve_intersect.h index 97644aacaa8..747d4ba4c3f 100644 --- a/intern/cycles/kernel/geom/curve_intersect.h +++ b/intern/cycles/kernel/geom/curve_intersect.h @@ -738,7 +738,7 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg, /* NOTE: It is possible that P will be the same as P_inside (precision issues, or very small * radius). In this case use the view direction to approximate the normal. */ const float3 P_inside = float4_to_float3(catmull_rom_basis_eval(P_curve, sd->u)); - const float3 N = (!isequal(P, P_inside)) ? normalize(P - P_inside) : -sd->I; + const float3 N = (!isequal(P, P_inside)) ? normalize(P - P_inside) : -sd->wi; sd->N = N; sd->v = 0.0f; @@ -757,7 +757,7 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg, } sd->P = P; - sd->Ng = (sd->type & PRIMITIVE_CURVE_RIBBON) ? sd->I : sd->N; + sd->Ng = (sd->type & PRIMITIVE_CURVE_RIBBON) ? sd->wi : sd->N; sd->dPdv = cross(sd->dPdu, sd->Ng); sd->shader = kernel_data_fetch(curves, sd->prim).shader_id; } diff --git a/intern/cycles/kernel/geom/shader_data.h b/intern/cycles/kernel/geom/shader_data.h index b67d19365a3..eb05121b7cd 100644 --- a/intern/cycles/kernel/geom/shader_data.h +++ b/intern/cycles/kernel/geom/shader_data.h @@ -55,7 +55,7 @@ ccl_device_inline void shader_setup_from_ray(KernelGlobals kg, #endif /* Read ray data into shader globals. */ - sd->I = -ray->D; + sd->wi = -ray->D; #ifdef __HAIR__ if (sd->type & PRIMITIVE_CURVE) { @@ -111,7 +111,7 @@ ccl_device_inline void shader_setup_from_ray(KernelGlobals kg, sd->flag = kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).flags; /* backfacing test */ - bool backfacing = (dot(sd->Ng, sd->I) < 0.0f); + bool backfacing = (dot(sd->Ng, sd->wi) < 0.0f); if (backfacing) { sd->flag |= SD_BACKFACING; @@ -152,7 +152,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals kg, sd->P = P; sd->N = Ng; sd->Ng = Ng; - sd->I = I; + sd->wi = I; sd->shader = shader; if (prim != PRIM_NONE) sd->type = PRIMITIVE_TRIANGLE; @@ -185,7 +185,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals kg, object_position_transform_auto(kg, sd, &sd->P); object_normal_transform_auto(kg, sd, &sd->Ng); sd->N = sd->Ng; - object_dir_transform_auto(kg, sd, &sd->I); + object_dir_transform_auto(kg, sd, &sd->wi); } if (sd->type == PRIMITIVE_TRIANGLE) { @@ -227,7 +227,7 @@ ccl_device_inline void shader_setup_from_sample(KernelGlobals kg, /* backfacing test */ if (sd->prim != PRIM_NONE) { - bool backfacing = (dot(sd->Ng, sd->I) < 0.0f); + bool backfacing = (dot(sd->Ng, sd->wi) < 0.0f); if (backfacing) { sd->flag |= SD_BACKFACING; @@ -341,7 +341,7 @@ ccl_device void shader_setup_from_curve(KernelGlobals kg, } /* No view direction, normals or bitangent. */ - sd->I = zero_float3(); + sd->wi = zero_float3(); sd->N = zero_float3(); sd->Ng = zero_float3(); #ifdef __DPDU__ @@ -372,7 +372,7 @@ ccl_device_inline void shader_setup_from_background(KernelGlobals kg, sd->P = ray_D; sd->N = -ray_D; sd->Ng = -ray_D; - sd->I = -ray_D; + sd->wi = -ray_D; sd->shader = kernel_data.background.surface_shader; sd->flag = kernel_data_fetch(shaders, (sd->shader & SHADER_MASK)).flags; sd->object_flag = 0; @@ -412,7 +412,7 @@ ccl_device_inline void shader_setup_from_volume(KernelGlobals kg, sd->P = ray->P + ray->D * ray->tmin; sd->N = -ray->D; sd->Ng = -ray->D; - sd->I = -ray->D; + sd->wi = -ray->D; sd->shader = SHADER_NONE; sd->flag = 0; sd->object_flag = 0; diff --git a/intern/cycles/kernel/integrator/guiding.h b/intern/cycles/kernel/integrator/guiding.h index 634bba2a9b4..93c80539140 100644 --- a/intern/cycles/kernel/integrator/guiding.h +++ b/intern/cycles/kernel/integrator/guiding.h @@ -44,7 +44,7 @@ ccl_device_forceinline void guiding_record_surface_segment(KernelGlobals kg, state->guiding.path_segment = kg->opgl_path_segment_storage->NextSegment(); openpgl::cpp::SetPosition(state->guiding.path_segment, guiding_point3f(sd->P)); - openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(sd->I)); + openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(sd->wi)); openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false); openpgl::cpp::SetScatteredContribution(state->guiding.path_segment, zero); openpgl::cpp::SetDirectContribution(state->guiding.path_segment, zero); @@ -60,7 +60,7 @@ ccl_device_forceinline void guiding_record_surface_bounce(KernelGlobals kg, const Spectrum weight, const float pdf, const float3 N, - const float3 omega_in, + const float3 wo, const float2 roughness, const float eta) { @@ -78,7 +78,7 @@ ccl_device_forceinline void guiding_record_surface_bounce(KernelGlobals kg, openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(one_float3())); openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false); openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(normal)); - openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(omega_in)); + openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(wo)); openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, pdf); openpgl::cpp::SetScatteringWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb)); openpgl::cpp::SetIsDelta(state->guiding.path_segment, is_delta); @@ -113,7 +113,7 @@ ccl_device_forceinline void guiding_record_surface_emission(KernelGlobals kg, ccl_device_forceinline void guiding_record_bssrdf_segment(KernelGlobals kg, IntegratorState state, const float3 P, - const float3 I) + const float3 wi) { #if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 1 if (!kernel_data.integrator.train_guiding) { @@ -124,7 +124,7 @@ ccl_device_forceinline void guiding_record_bssrdf_segment(KernelGlobals kg, state->guiding.path_segment = kg->opgl_path_segment_storage->NextSegment(); openpgl::cpp::SetPosition(state->guiding.path_segment, guiding_point3f(P)); - openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(I)); + openpgl::cpp::SetDirectionOut(state->guiding.path_segment, guiding_vec3f(wi)); openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, true); openpgl::cpp::SetScatteredContribution(state->guiding.path_segment, zero); openpgl::cpp::SetDirectContribution(state->guiding.path_segment, zero); @@ -166,7 +166,7 @@ ccl_device_forceinline void guiding_record_bssrdf_bounce(KernelGlobals kg, IntegratorState state, const float pdf, const float3 N, - const float3 omega_in, + const float3 wo, const Spectrum weight, const Spectrum albedo) { @@ -181,7 +181,7 @@ ccl_device_forceinline void guiding_record_bssrdf_bounce(KernelGlobals kg, openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, false); openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(normal)); - openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(omega_in)); + openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(wo)); openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, pdf); openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb)); #endif @@ -222,7 +222,7 @@ ccl_device_forceinline void guiding_record_volume_bounce(KernelGlobals kg, ccl_private const ShaderData *sd, const Spectrum weight, const float pdf, - const float3 omega_in, + const float3 wo, const float roughness) { #if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4 @@ -237,7 +237,7 @@ ccl_device_forceinline void guiding_record_volume_bounce(KernelGlobals kg, openpgl::cpp::SetVolumeScatter(state->guiding.path_segment, true); openpgl::cpp::SetTransmittanceWeight(state->guiding.path_segment, guiding_vec3f(one_float3())); openpgl::cpp::SetNormal(state->guiding.path_segment, guiding_vec3f(normal)); - openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(omega_in)); + openpgl::cpp::SetDirectionIn(state->guiding.path_segment, guiding_vec3f(wo)); openpgl::cpp::SetPDFDirectionIn(state->guiding.path_segment, pdf); openpgl::cpp::SetScatteringWeight(state->guiding.path_segment, guiding_vec3f(weight_rgb)); openpgl::cpp::SetIsDelta(state->guiding.path_segment, false); @@ -467,13 +467,13 @@ ccl_device_forceinline bool guiding_bsdf_init(KernelGlobals kg, ccl_device_forceinline float guiding_bsdf_sample(KernelGlobals kg, IntegratorState state, const float2 rand_bsdf, - ccl_private float3 *omega_in) + ccl_private float3 *wo) { #if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4 - pgl_vec3f wo; + pgl_vec3f pgl_wo; const pgl_point2f rand = openpgl::cpp::Point2(rand_bsdf.x, rand_bsdf.y); - const float pdf = kg->opgl_surface_sampling_distribution->SamplePDF(rand, wo); - *omega_in = make_float3(wo.x, wo.y, wo.z); + const float pdf = kg->opgl_surface_sampling_distribution->SamplePDF(rand, pgl_wo); + *wo = make_float3(pgl_wo.x, pgl_wo.y, pgl_wo.z); return pdf; #else return 0.0f; @@ -482,10 +482,10 @@ ccl_device_forceinline float guiding_bsdf_sample(KernelGlobals kg, ccl_device_forceinline float guiding_bsdf_pdf(KernelGlobals kg, IntegratorState state, - const float3 omega_in) + const float3 wo) { #if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4 - return kg->opgl_surface_sampling_distribution->PDF(guiding_vec3f(omega_in)); + return kg->opgl_surface_sampling_distribution->PDF(guiding_vec3f(wo)); #else return 0.0f; #endif @@ -520,13 +520,13 @@ ccl_device_forceinline bool guiding_phase_init(KernelGlobals kg, ccl_device_forceinline float guiding_phase_sample(KernelGlobals kg, IntegratorState state, const float2 rand_phase, - ccl_private float3 *omega_in) + ccl_private float3 *wo) { #if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4 - pgl_vec3f wo; + pgl_vec3f pgl_wo; const pgl_point2f rand = openpgl::cpp::Point2(rand_phase.x, rand_phase.y); - const float pdf = kg->opgl_volume_sampling_distribution->SamplePDF(rand, wo); - *omega_in = make_float3(wo.x, wo.y, wo.z); + const float pdf = kg->opgl_volume_sampling_distribution->SamplePDF(rand, pgl_wo); + *wo = make_float3(pgl_wo.x, pgl_wo.y, pgl_wo.z); return pdf; #else return 0.0f; @@ -535,10 +535,10 @@ ccl_device_forceinline float guiding_phase_sample(KernelGlobals kg, ccl_device_forceinline float guiding_phase_pdf(KernelGlobals kg, IntegratorState state, - const float3 omega_in) + const float3 wo) { #if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4 - return kg->opgl_volume_sampling_distribution->PDF(guiding_vec3f(omega_in)); + return kg->opgl_volume_sampling_distribution->PDF(guiding_vec3f(wo)); #else return 0.0f; #endif diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h index debbce497dc..9eb72390d98 100644 --- a/intern/cycles/kernel/integrator/mnee.h +++ b/intern/cycles/kernel/integrator/mnee.h @@ -607,11 +607,11 @@ ccl_device_forceinline Spectrum mnee_eval_bsdf_contribution(ccl_private ShaderCl { ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)closure; - float cosNO = dot(bsdf->N, wi); - float cosNI = dot(bsdf->N, wo); + float cosNI = dot(bsdf->N, wi); + float cosNO = dot(bsdf->N, wo); float3 Ht = normalize(-(bsdf->ior * wo + wi)); - float cosHO = dot(Ht, wi); + float cosHI = dot(Ht, wi); float alpha2 = bsdf->alpha_x * bsdf->alpha_y; float cosThetaM = dot(bsdf->N, Ht); @@ -619,12 +619,12 @@ ccl_device_forceinline Spectrum mnee_eval_bsdf_contribution(ccl_private ShaderCl float G; if (bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) { /* Eq. 26, 27: now calculate G1(i,m) and G1(o,m). */ - G = bsdf_beckmann_G1(bsdf->alpha_x, cosNO) * bsdf_beckmann_G1(bsdf->alpha_x, cosNI); + G = bsdf_beckmann_G1(bsdf->alpha_x, cosNI) * bsdf_beckmann_G1(bsdf->alpha_x, cosNO); } else { /* bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID assumed */ /* Eq. 34: now calculate G1(i,m) and G1(o,m). */ - G = (2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNO * cosNO) / (cosNO * cosNO)))) * - (2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNI * cosNI) / (cosNI * cosNI)))); + G = (2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNI * cosNI) / (cosNI * cosNI)))) * + (2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNO * cosNO) / (cosNO * cosNO)))); } /* @@ -635,7 +635,7 @@ ccl_device_forceinline Spectrum mnee_eval_bsdf_contribution(ccl_private ShaderCl * contribution = bsdf_do * |do/dh| * |n.wo / n.h| / pdf_dh * = (1 - F) * G * |h.wi / (n.wi * n.h^2)| */ - return bsdf->weight * G * fabsf(cosHO / (cosNO * sqr(cosThetaM))); + return bsdf->weight * G * fabsf(cosHI / (cosNI * sqr(cosThetaM))); } /* Compute transfer matrix determinant |T1| = |dx1/dxn| (and |dh/dx| in the process) */ diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 3410195cd19..21a6f2d4e36 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -364,7 +364,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( /* BSDF closure, sample direction. */ float bsdf_pdf = 0.0f, unguided_bsdf_pdf = 0.0f; BsdfEval bsdf_eval ccl_optional_struct_init; - float3 bsdf_omega_in ccl_optional_struct_init; + float3 bsdf_wo ccl_optional_struct_init; int label; float2 bsdf_sampled_roughness = make_float2(1.0f, 1.0f); @@ -378,7 +378,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( sc, rand_bsdf, &bsdf_eval, - &bsdf_omega_in, + &bsdf_wo, &bsdf_pdf, &unguided_bsdf_pdf, &bsdf_sampled_roughness, @@ -398,7 +398,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( sc, rand_bsdf, &bsdf_eval, - &bsdf_omega_in, + &bsdf_wo, &bsdf_pdf, &bsdf_sampled_roughness, &bsdf_eta); @@ -416,7 +416,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( } else { /* Setup ray with changed origin and direction. */ - const float3 D = normalize(bsdf_omega_in); + const float3 D = normalize(bsdf_wo); INTEGRATOR_STATE_WRITE(state, ray, P) = integrate_surface_ray_offset(kg, sd, sd->P, D); INTEGRATOR_STATE_WRITE(state, ray, D) = D; INTEGRATOR_STATE_WRITE(state, ray, tmin) = 0.0f; @@ -455,7 +455,7 @@ ccl_device_forceinline int integrate_surface_bsdf_bssrdf_bounce( bsdf_weight, bsdf_pdf, sd->N, - normalize(bsdf_omega_in), + normalize(bsdf_wo), bsdf_sampled_roughness, bsdf_eta); diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h index 624aeb5edee..75962ce5499 100644 --- a/intern/cycles/kernel/integrator/shade_volume.h +++ b/intern/cycles/kernel/integrator/shade_volume.h @@ -912,7 +912,7 @@ ccl_device_forceinline bool integrate_volume_phase_scatter( /* Phase closure, sample direction. */ float phase_pdf = 0.0f, unguided_phase_pdf = 0.0f; BsdfEval phase_eval ccl_optional_struct_init; - float3 phase_omega_in ccl_optional_struct_init; + float3 phase_wo ccl_optional_struct_init; float sampled_roughness = 1.0f; int label; @@ -924,7 +924,7 @@ ccl_device_forceinline bool integrate_volume_phase_scatter( svc, rand_phase, &phase_eval, - &phase_omega_in, + &phase_wo, &phase_pdf, &unguided_phase_pdf, &sampled_roughness); @@ -938,15 +938,8 @@ ccl_device_forceinline bool integrate_volume_phase_scatter( else # endif { - label = volume_shader_phase_sample(kg, - sd, - phases, - svc, - rand_phase, - &phase_eval, - &phase_omega_in, - &phase_pdf, - &sampled_roughness); + label = volume_shader_phase_sample( + kg, sd, phases, svc, rand_phase, &phase_eval, &phase_wo, &phase_pdf, &sampled_roughness); if (phase_pdf == 0.0f || bsdf_eval_is_zero(&phase_eval)) { return false; @@ -957,7 +950,7 @@ ccl_device_forceinline bool integrate_volume_phase_scatter( /* Setup ray. */ INTEGRATOR_STATE_WRITE(state, ray, P) = sd->P; - INTEGRATOR_STATE_WRITE(state, ray, D) = normalize(phase_omega_in); + INTEGRATOR_STATE_WRITE(state, ray, D) = normalize(phase_wo); INTEGRATOR_STATE_WRITE(state, ray, tmin) = 0.0f; INTEGRATOR_STATE_WRITE(state, ray, tmax) = FLT_MAX; # ifdef __RAY_DIFFERENTIALS__ @@ -971,7 +964,7 @@ ccl_device_forceinline bool integrate_volume_phase_scatter( /* Add phase function sampling data to the path segment. */ guiding_record_volume_bounce( - kg, state, sd, phase_weight, phase_pdf, normalize(phase_omega_in), sampled_roughness); + kg, state, sd, phase_weight, phase_pdf, normalize(phase_wo), sampled_roughness); /* Update throughput. */ const Spectrum throughput = INTEGRATOR_STATE(state, path, throughput); @@ -1076,7 +1069,7 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg, float3 transmittance_weight = spectrum_to_rgb( safe_divide_color(result.indirect_throughput, initial_throughput)); guiding_record_volume_transmission(kg, state, transmittance_weight); - guiding_record_volume_segment(kg, state, direct_P, sd.I); + guiding_record_volume_segment(kg, state, direct_P, sd.wi); guiding_generated_new_segment = true; unlit_throughput = result.indirect_throughput / continuation_probability; rand_phase_guiding = path_state_rng_1D(kg, &rng_state, PRNG_VOLUME_PHASE_GUIDING_DISTANCE); @@ -1139,7 +1132,7 @@ ccl_device VolumeIntegrateEvent volume_integrate(KernelGlobals kg, # if defined(__PATH_GUIDING__) # if PATH_GUIDING_LEVEL >= 1 if (!guiding_generated_new_segment) { - guiding_record_volume_segment(kg, state, sd.P, sd.I); + guiding_record_volume_segment(kg, state, sd.P, sd.wi); } # endif # if PATH_GUIDING_LEVEL >= 4 diff --git a/intern/cycles/kernel/integrator/surface_shader.h b/intern/cycles/kernel/integrator/surface_shader.h index 5e47a34f77e..86e20e88a0a 100644 --- a/intern/cycles/kernel/integrator/surface_shader.h +++ b/intern/cycles/kernel/integrator/surface_shader.h @@ -174,14 +174,14 @@ ccl_device_inline void surface_shader_prepare_closures(KernelGlobals kg, #if 0 ccl_device_inline void surface_shader_validate_bsdf_sample(const KernelGlobals kg, const ShaderClosure *sc, - const float3 omega_in, + const float3 wo, const int org_label, const float2 org_roughness, const float org_eta) { /* Validate the the bsdf_label and bsdf_roughness_eta functions * by estimating the values after a bsdf sample. */ - const int comp_label = bsdf_label(kg, sc, omega_in); + const int comp_label = bsdf_label(kg, sc, wo); kernel_assert(org_label == comp_label); float2 comp_roughness; @@ -218,7 +218,7 @@ ccl_device_forceinline bool _surface_shader_exclude(ClosureType type, uint light ccl_device_inline float _surface_shader_bsdf_eval_mis(KernelGlobals kg, ccl_private ShaderData *sd, - const float3 omega_in, + const float3 wo, ccl_private const ShaderClosure *skip_sc, ccl_private BsdfEval *result_eval, float sum_pdf, @@ -237,7 +237,7 @@ ccl_device_inline float _surface_shader_bsdf_eval_mis(KernelGlobals kg, if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) { if (CLOSURE_IS_BSDF(sc->type) && !_surface_shader_exclude(sc->type, light_shader_flags)) { float bsdf_pdf = 0.0f; - Spectrum eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf); + Spectrum eval = bsdf_eval(kg, sd, sc, wo, &bsdf_pdf); if (bsdf_pdf != 0.0f) { bsdf_eval_accum(result_eval, sc->type, eval * sc->weight); @@ -254,7 +254,7 @@ ccl_device_inline float _surface_shader_bsdf_eval_mis(KernelGlobals kg, ccl_device_inline float surface_shader_bsdf_eval_pdfs(const KernelGlobals kg, ccl_private ShaderData *sd, - const float3 omega_in, + const float3 wo, ccl_private BsdfEval *result_eval, ccl_private float *pdfs, const uint light_shader_flags) @@ -270,7 +270,7 @@ ccl_device_inline float surface_shader_bsdf_eval_pdfs(const KernelGlobals kg, if (CLOSURE_IS_BSDF_OR_BSSRDF(sc->type)) { if (CLOSURE_IS_BSDF(sc->type) && !_surface_shader_exclude(sc->type, light_shader_flags)) { float bsdf_pdf = 0.0f; - Spectrum eval = bsdf_eval(kg, sd, sc, omega_in, &bsdf_pdf); + Spectrum eval = bsdf_eval(kg, sd, sc, wo, &bsdf_pdf); kernel_assert(bsdf_pdf >= 0.0f); if (bsdf_pdf != 0.0f) { bsdf_eval_accum(result_eval, sc->type, eval * sc->weight); @@ -310,20 +310,20 @@ ccl_device_inline surface_shader_bsdf_eval(KernelGlobals kg, IntegratorState state, ccl_private ShaderData *sd, - const float3 omega_in, + const float3 wo, ccl_private BsdfEval *bsdf_eval, const uint light_shader_flags) { bsdf_eval_init(bsdf_eval, CLOSURE_NONE_ID, zero_spectrum()); float pdf = _surface_shader_bsdf_eval_mis( - kg, sd, omega_in, NULL, bsdf_eval, 0.0f, 0.0f, light_shader_flags); + kg, sd, wo, NULL, bsdf_eval, 0.0f, 0.0f, light_shader_flags); #if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4 if (state->guiding.use_surface_guiding) { const float guiding_sampling_prob = state->guiding.surface_guiding_sampling_prob; const float bssrdf_sampling_prob = state->guiding.bssrdf_sampling_prob; - const float guide_pdf = guiding_bsdf_pdf(kg, state, omega_in); + const float guide_pdf = guiding_bsdf_pdf(kg, state, wo); pdf = (guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob)) + (1.0f - guiding_sampling_prob) * pdf; } @@ -407,7 +407,7 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, ccl_private const ShaderClosure *sc, const float2 rand_bsdf, ccl_private BsdfEval *bsdf_eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *bsdf_pdf, ccl_private float *unguided_bsdf_pdf, ccl_private float2 *sampled_rougness, @@ -443,14 +443,14 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, if (sample_guiding) { /* Sample guiding distribution. */ - guide_pdf = guiding_bsdf_sample(kg, state, rand_bsdf, omega_in); + guide_pdf = guiding_bsdf_sample(kg, state, rand_bsdf, wo); *bsdf_pdf = 0.0f; if (guide_pdf != 0.0f) { float unguided_bsdf_pdfs[MAX_CLOSURE]; *unguided_bsdf_pdf = surface_shader_bsdf_eval_pdfs( - kg, sd, *omega_in, bsdf_eval, unguided_bsdf_pdfs, 0); + kg, sd, *wo, bsdf_eval, unguided_bsdf_pdfs, 0); *bsdf_pdf = (guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob)) + ((1.0f - guiding_sampling_prob) * (*unguided_bsdf_pdf)); float sum_pdfs = 0.0f; @@ -471,7 +471,7 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, * the sum of all unguided_bsdf_pdfs is just < 1.0f. */ idx = (rand_bsdf_guiding > sum_pdfs) ? sd->num_closure - 1 : idx; - label = bsdf_label(kg, &sd->closure[idx], *omega_in); + label = bsdf_label(kg, &sd->closure[idx], *wo); } } @@ -483,19 +483,11 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, else { /* Sample BSDF. */ *bsdf_pdf = 0.0f; - label = bsdf_sample(kg, - sd, - sc, - rand_bsdf.x, - rand_bsdf.y, - &eval, - omega_in, - unguided_bsdf_pdf, - sampled_rougness, - eta); + label = bsdf_sample( + kg, sd, sc, rand_bsdf.x, rand_bsdf.y, &eval, wo, unguided_bsdf_pdf, sampled_rougness, eta); # if 0 if (*unguided_bsdf_pdf > 0.0f) { - surface_shader_validate_bsdf_sample(kg, sc, *omega_in, label, sampled_roughness, eta); + surface_shader_validate_bsdf_sample(kg, sc, *wo, label, sampled_roughness, eta); } # endif @@ -507,13 +499,13 @@ ccl_device int surface_shader_bsdf_guided_sample_closure(KernelGlobals kg, if (sd->num_closure > 1) { float sweight = sc->sample_weight; *unguided_bsdf_pdf = _surface_shader_bsdf_eval_mis( - kg, sd, *omega_in, sc, bsdf_eval, (*unguided_bsdf_pdf) * sweight, sweight, 0); + kg, sd, *wo, sc, bsdf_eval, (*unguided_bsdf_pdf) * sweight, sweight, 0); kernel_assert(reduce_min(bsdf_eval_sum(bsdf_eval)) >= 0.0f); } *bsdf_pdf = *unguided_bsdf_pdf; if (use_surface_guiding) { - guide_pdf = guiding_bsdf_pdf(kg, state, *omega_in); + guide_pdf = guiding_bsdf_pdf(kg, state, *wo); *bsdf_pdf *= 1.0f - guiding_sampling_prob; *bsdf_pdf += guiding_sampling_prob * guide_pdf * (1.0f - bssrdf_sampling_prob); } @@ -533,7 +525,7 @@ ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg, ccl_private const ShaderClosure *sc, const float2 rand_bsdf, ccl_private BsdfEval *bsdf_eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private float2 *sampled_roughness, ccl_private float *eta) @@ -546,15 +538,14 @@ ccl_device int surface_shader_bsdf_sample_closure(KernelGlobals kg, *pdf = 0.0f; label = bsdf_sample( - kg, sd, sc, rand_bsdf.x, rand_bsdf.y, &eval, omega_in, pdf, sampled_roughness, eta); + kg, sd, sc, rand_bsdf.x, rand_bsdf.y, &eval, wo, pdf, sampled_roughness, eta); if (*pdf != 0.0f) { bsdf_eval_init(bsdf_eval, sc->type, eval * sc->weight); if (sd->num_closure > 1) { float sweight = sc->sample_weight; - *pdf = _surface_shader_bsdf_eval_mis( - kg, sd, *omega_in, sc, bsdf_eval, *pdf * sweight, sweight, 0); + *pdf = _surface_shader_bsdf_eval_mis(kg, sd, *wo, sc, bsdf_eval, *pdf * sweight, sweight, 0); } } else { @@ -758,7 +749,7 @@ ccl_device Spectrum surface_shader_background(ccl_private const ShaderData *sd) ccl_device Spectrum surface_shader_emission(ccl_private const ShaderData *sd) { if (sd->flag & SD_EMISSION) { - return emissive_simple_eval(sd->Ng, sd->I) * sd->closure_emission_background; + return emissive_simple_eval(sd->Ng, sd->wi) * sd->closure_emission_background; } else { return zero_spectrum(); diff --git a/intern/cycles/kernel/integrator/volume_shader.h b/intern/cycles/kernel/integrator/volume_shader.h index 625205e9931..45804859d7c 100644 --- a/intern/cycles/kernel/integrator/volume_shader.h +++ b/intern/cycles/kernel/integrator/volume_shader.h @@ -202,7 +202,7 @@ ccl_device_inline ccl_private const ShaderVolumeClosure *volume_shader_phase_pic ccl_device_inline float _volume_shader_phase_eval_mis(ccl_private const ShaderData *sd, ccl_private const ShaderVolumePhases *phases, - const float3 omega_in, + const float3 wo, int skip_phase, ccl_private BsdfEval *result_eval, float sum_pdf, @@ -214,7 +214,7 @@ ccl_device_inline float _volume_shader_phase_eval_mis(ccl_private const ShaderDa ccl_private const ShaderVolumeClosure *svc = &phases->closure[i]; float phase_pdf = 0.0f; - Spectrum eval = volume_phase_eval(sd, svc, omega_in, &phase_pdf); + Spectrum eval = volume_phase_eval(sd, svc, wo, &phase_pdf); if (phase_pdf != 0.0f) { bsdf_eval_accum(result_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval); @@ -230,11 +230,11 @@ ccl_device_inline float _volume_shader_phase_eval_mis(ccl_private const ShaderDa ccl_device float volume_shader_phase_eval(KernelGlobals kg, ccl_private const ShaderData *sd, ccl_private const ShaderVolumeClosure *svc, - const float3 omega_in, + const float3 wo, ccl_private BsdfEval *phase_eval) { float phase_pdf = 0.0f; - Spectrum eval = volume_phase_eval(sd, svc, omega_in, &phase_pdf); + Spectrum eval = volume_phase_eval(sd, svc, wo, &phase_pdf); if (phase_pdf != 0.0f) { bsdf_eval_accum(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval); @@ -247,17 +247,17 @@ ccl_device float volume_shader_phase_eval(KernelGlobals kg, IntegratorState state, ccl_private const ShaderData *sd, ccl_private const ShaderVolumePhases *phases, - const float3 omega_in, + const float3 wo, ccl_private BsdfEval *phase_eval) { bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, zero_spectrum()); - float pdf = _volume_shader_phase_eval_mis(sd, phases, omega_in, -1, phase_eval, 0.0f, 0.0f); + float pdf = _volume_shader_phase_eval_mis(sd, phases, wo, -1, phase_eval, 0.0f, 0.0f); # if defined(__PATH_GUIDING__) && PATH_GUIDING_LEVEL >= 4 if (state->guiding.use_volume_guiding) { const float guiding_sampling_prob = state->guiding.volume_guiding_sampling_prob; - const float guide_pdf = guiding_phase_pdf(kg, state, omega_in); + const float guide_pdf = guiding_phase_pdf(kg, state, wo); pdf = (guiding_sampling_prob * guide_pdf) + (1.0f - guiding_sampling_prob) * pdf; } # endif @@ -272,7 +272,7 @@ ccl_device int volume_shader_phase_guided_sample(KernelGlobals kg, ccl_private const ShaderVolumeClosure *svc, const float2 rand_phase, ccl_private BsdfEval *phase_eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *phase_pdf, ccl_private float *unguided_phase_pdf, ccl_private float *sampled_roughness) @@ -304,11 +304,11 @@ ccl_device int volume_shader_phase_guided_sample(KernelGlobals kg, if (sample_guiding) { /* Sample guiding distribution. */ - guide_pdf = guiding_phase_sample(kg, state, rand_phase, omega_in); + guide_pdf = guiding_phase_sample(kg, state, rand_phase, wo); *phase_pdf = 0.0f; if (guide_pdf != 0.0f) { - *unguided_phase_pdf = volume_shader_phase_eval(kg, sd, svc, *omega_in, phase_eval); + *unguided_phase_pdf = volume_shader_phase_eval(kg, sd, svc, *wo, phase_eval); *phase_pdf = (guiding_sampling_prob * guide_pdf) + ((1.0f - guiding_sampling_prob) * (*unguided_phase_pdf)); label = LABEL_VOLUME_SCATTER; @@ -318,14 +318,14 @@ ccl_device int volume_shader_phase_guided_sample(KernelGlobals kg, /* Sample phase. */ *phase_pdf = 0.0f; label = volume_phase_sample( - sd, svc, rand_phase.x, rand_phase.y, &eval, omega_in, unguided_phase_pdf); + sd, svc, rand_phase.x, rand_phase.y, &eval, wo, unguided_phase_pdf); if (*unguided_phase_pdf != 0.0f) { bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval); *phase_pdf = *unguided_phase_pdf; if (use_volume_guiding) { - guide_pdf = guiding_phase_pdf(kg, state, *omega_in); + guide_pdf = guiding_phase_pdf(kg, state, *wo); *phase_pdf *= 1.0f - guiding_sampling_prob; *phase_pdf += guiding_sampling_prob * guide_pdf; } @@ -349,7 +349,7 @@ ccl_device int volume_shader_phase_sample(KernelGlobals kg, ccl_private const ShaderVolumeClosure *svc, float2 rand_phase, ccl_private BsdfEval *phase_eval, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf, ccl_private float *sampled_roughness) { @@ -357,7 +357,7 @@ ccl_device int volume_shader_phase_sample(KernelGlobals kg, Spectrum eval = zero_spectrum(); *pdf = 0.0f; - int label = volume_phase_sample(sd, svc, rand_phase.x, rand_phase.y, &eval, omega_in, pdf); + int label = volume_phase_sample(sd, svc, rand_phase.x, rand_phase.y, &eval, wo, pdf); if (*pdf != 0.0f) { bsdf_eval_init(phase_eval, CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID, eval); diff --git a/intern/cycles/kernel/light/triangle.h b/intern/cycles/kernel/light/triangle.h index 7a9a395c2b6..298a94566fc 100644 --- a/intern/cycles/kernel/light/triangle.h +++ b/intern/cycles/kernel/light/triangle.h @@ -63,7 +63,7 @@ ccl_device_forceinline float triangle_light_pdf(KernelGlobals kg, const float3 e2 = V[2] - V[1]; const float longest_edge_squared = max(len_squared(e0), max(len_squared(e1), len_squared(e2))); const float3 N = cross(e0, e1); - const float distance_to_plane = fabsf(dot(N, sd->I * t)) / dot(N, N); + const float distance_to_plane = fabsf(dot(N, sd->wi * t)) / dot(N, N); const float area = 0.5f * len(N); float pdf; @@ -71,7 +71,7 @@ ccl_device_forceinline float triangle_light_pdf(KernelGlobals kg, if (longest_edge_squared > distance_to_plane * distance_to_plane) { /* sd contains the point on the light source * calculate Px, the point that we're shading */ - const float3 Px = sd->P + sd->I * t; + const float3 Px = sd->P + sd->wi * t; const float3 v0_p = V[0] - Px; const float3 v1_p = V[1] - Px; const float3 v2_p = V[2] - Px; @@ -99,7 +99,7 @@ ccl_device_forceinline float triangle_light_pdf(KernelGlobals kg, return 0.0f; } - pdf = triangle_light_pdf_area_sampling(sd->Ng, sd->I, t) / area; + pdf = triangle_light_pdf_area_sampling(sd->Ng, sd->wi, t) / area; } /* Belongs in distribution.h but can reuse computations here. */ diff --git a/intern/cycles/kernel/osl/closures_setup.h b/intern/cycles/kernel/osl/closures_setup.h index ceaf56ccba6..a65947b2496 100644 --- a/intern/cycles/kernel/osl/closures_setup.h +++ b/intern/cycles/kernel/osl/closures_setup.h @@ -80,7 +80,7 @@ ccl_device void osl_closure_diffuse_setup(KernelGlobals kg, return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); sd->flag |= bsdf_diffuse_setup(bsdf); } @@ -101,7 +101,7 @@ ccl_device void osl_closure_oren_nayar_setup(KernelGlobals kg, return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->roughness = closure->roughness; sd->flag |= bsdf_oren_nayar_setup(bsdf); @@ -123,7 +123,7 @@ ccl_device void osl_closure_translucent_setup(KernelGlobals kg, return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); sd->flag |= bsdf_translucent_setup(bsdf); } @@ -144,7 +144,7 @@ ccl_device void osl_closure_reflection_setup(KernelGlobals kg, return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); sd->flag |= bsdf_reflection_setup(bsdf); } @@ -165,7 +165,7 @@ ccl_device void osl_closure_refraction_setup(KernelGlobals kg, return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->ior = closure->ior; sd->flag |= bsdf_refraction_setup(bsdf); @@ -199,7 +199,7 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg, return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = closure->alpha_y; bsdf->ior = closure->ior; @@ -257,7 +257,7 @@ ccl_device void osl_closure_microfacet_ggx_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; sd->flag |= bsdf_microfacet_ggx_isotropic_setup(bsdf); @@ -280,7 +280,7 @@ ccl_device void osl_closure_microfacet_ggx_aniso_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = closure->alpha_y; bsdf->T = closure->T; @@ -305,7 +305,7 @@ ccl_device void osl_closure_microfacet_ggx_refraction_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->ior = closure->ior; @@ -337,7 +337,7 @@ ccl_device void osl_closure_microfacet_ggx_fresnel_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = bsdf->alpha_x; bsdf->ior = closure->ior; @@ -375,7 +375,7 @@ ccl_device void osl_closure_microfacet_ggx_aniso_fresnel_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = closure->alpha_y; bsdf->ior = closure->ior; @@ -418,7 +418,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = bsdf->alpha_x; bsdf->ior = 1.0f; @@ -459,7 +459,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_glass_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = bsdf->alpha_x; bsdf->ior = closure->ior; @@ -500,7 +500,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = closure->alpha_y; bsdf->ior = 1.0f; @@ -543,7 +543,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_fresnel_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = bsdf->alpha_x; bsdf->ior = closure->ior; @@ -584,7 +584,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_glass_fresnel_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = bsdf->alpha_x; bsdf->ior = closure->ior; @@ -625,7 +625,7 @@ ccl_device void osl_closure_microfacet_multi_ggx_aniso_fresnel_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = closure->alpha_y; bsdf->ior = closure->ior; @@ -659,7 +659,7 @@ ccl_device void osl_closure_microfacet_beckmann_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; sd->flag |= bsdf_microfacet_beckmann_isotropic_setup(bsdf); @@ -682,7 +682,7 @@ ccl_device void osl_closure_microfacet_beckmann_aniso_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = closure->alpha_y; bsdf->T = closure->T; @@ -707,7 +707,7 @@ ccl_device void osl_closure_microfacet_beckmann_refraction_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->ior = closure->ior; @@ -733,7 +733,7 @@ ccl_device void osl_closure_ashikhmin_velvet_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->sigma = closure->sigma; sd->flag |= bsdf_ashikhmin_velvet_setup(bsdf); @@ -756,7 +756,7 @@ ccl_device void osl_closure_ashikhmin_shirley_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->alpha_x; bsdf->alpha_y = closure->alpha_y; bsdf->T = closure->T; @@ -780,7 +780,7 @@ ccl_device void osl_closure_diffuse_toon_setup(KernelGlobals kg, return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->size = closure->size; bsdf->smooth = closure->smooth; @@ -803,7 +803,7 @@ ccl_device void osl_closure_glossy_toon_setup(KernelGlobals kg, return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->size = closure->size; bsdf->smooth = closure->smooth; @@ -829,7 +829,7 @@ ccl_device void osl_closure_principled_diffuse_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->roughness = closure->roughness; sd->flag |= bsdf_principled_diffuse_setup(bsdf); @@ -852,7 +852,7 @@ ccl_device void osl_closure_principled_sheen_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->avg_value = 0.0f; sd->flag |= bsdf_principled_sheen_setup(sd, bsdf); @@ -876,7 +876,7 @@ ccl_device void osl_closure_principled_clearcoat_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->alpha_x = closure->clearcoat_roughness; bsdf->alpha_y = closure->clearcoat_roughness; bsdf->ior = 1.5f; @@ -948,7 +948,7 @@ ccl_device void osl_closure_diffuse_ramp_setup(KernelGlobals kg, return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8); if (!bsdf->colors) { @@ -973,7 +973,7 @@ ccl_device void osl_closure_phong_ramp_setup(KernelGlobals kg, return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->exponent = closure->exponent; bsdf->colors = (float3 *)closure_alloc_extra(sd, sizeof(float3) * 8); @@ -1024,7 +1024,7 @@ ccl_device void osl_closure_bssrdf_setup(KernelGlobals kg, /* create one closure per color channel */ bssrdf->albedo = closure->albedo; - bssrdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bssrdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bssrdf->roughness = closure->roughness; bssrdf->anisotropy = clamp(closure->anisotropy, 0.0f, 0.9f); @@ -1049,7 +1049,7 @@ ccl_device void osl_closure_hair_reflection_setup(KernelGlobals kg, return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->T = closure->T; bsdf->roughness1 = closure->roughness1; bsdf->roughness2 = closure->roughness2; @@ -1075,7 +1075,7 @@ ccl_device void osl_closure_hair_transmission_setup( return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->T = closure->T; bsdf->roughness1 = closure->roughness1; bsdf->roughness2 = closure->roughness2; @@ -1107,7 +1107,7 @@ ccl_device void osl_closure_principled_hair_setup(KernelGlobals kg, return; } - bsdf->N = ensure_valid_reflection(sd->Ng, sd->I, closure->N); + bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N); bsdf->sigma = closure->sigma; bsdf->v = closure->v; bsdf->s = closure->s; diff --git a/intern/cycles/kernel/osl/osl.h b/intern/cycles/kernel/osl/osl.h index cc5c81ad027..ffaf87b7048 100644 --- a/intern/cycles/kernel/osl/osl.h +++ b/intern/cycles/kernel/osl/osl.h @@ -25,13 +25,13 @@ ccl_device_inline void shaderdata_to_shaderglobals(KernelGlobals kg, ccl_private ShaderGlobals *globals) { const differential3 dP = differential_from_compact(sd->Ng, sd->dP); - const differential3 dI = differential_from_compact(sd->I, sd->dI); + const differential3 dI = differential_from_compact(sd->wi, sd->dI); /* copy from shader data to shader globals */ globals->P = sd->P; globals->dPdx = dP.dx; globals->dPdy = dP.dy; - globals->I = sd->I; + globals->I = sd->wi; globals->dIdx = dI.dx; globals->dIdy = dI.dy; globals->N = sd->N; diff --git a/intern/cycles/kernel/osl/services.cpp b/intern/cycles/kernel/osl/services.cpp index 3fd098de4bb..95d58875b91 100644 --- a/intern/cycles/kernel/osl/services.cpp +++ b/intern/cycles/kernel/osl/services.cpp @@ -1720,8 +1720,8 @@ bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, return set_attribute_float3(f, type, derivatives, val); } else if (name == u_I) { - const differential3 dI = differential_from_compact(sd->I, sd->dI); - float3 f[3] = {sd->I, dI.dx, dI.dy}; + const differential3 dI = differential_from_compact(sd->wi, sd->dI); + float3 f[3] = {sd->wi, dI.dx, dI.dy}; return set_attribute_float3(f, type, derivatives, val); } else if (name == u_u) { diff --git a/intern/cycles/kernel/osl/shaders/node_principled_bsdf.osl b/intern/cycles/kernel/osl/shaders/node_principled_bsdf.osl index 9f8e7a68b9b..2499f90bc03 100644 --- a/intern/cycles/kernel/osl/shaders/node_principled_bsdf.osl +++ b/intern/cycles/kernel/osl/shaders/node_principled_bsdf.osl @@ -111,8 +111,8 @@ shader node_principled_bsdf(string distribution = "Multiscatter GGX", float eta = backfacing() ? 1.0 / f : f; if (distribution == "GGX" || Roughness <= 5e-2) { - float cosNO = dot(Normal, I); - float Fr = fresnel_dielectric_cos(cosNO, eta); + float cosNI = dot(Normal, I); + float Fr = fresnel_dielectric_cos(cosNI, eta); float refl_roughness = Roughness; if (Roughness <= 1e-2) diff --git a/intern/cycles/kernel/sample/mapping.h b/intern/cycles/kernel/sample/mapping.h index fc0e512b803..94e691aa1a8 100644 --- a/intern/cycles/kernel/sample/mapping.h +++ b/intern/cycles/kernel/sample/mapping.h @@ -33,19 +33,19 @@ ccl_device void make_orthonormals_tangent(const float3 N, /* sample direction with cosine weighted distributed in hemisphere */ ccl_device_inline void sample_cos_hemisphere( - const float3 N, float randu, float randv, ccl_private float3 *omega_in, ccl_private float *pdf) + const float3 N, float randu, float randv, ccl_private float3 *wo, ccl_private float *pdf) { to_unit_disk(&randu, &randv); float costheta = sqrtf(max(1.0f - randu * randu - randv * randv, 0.0f)); float3 T, B; make_orthonormals(N, &T, &B); - *omega_in = randu * T + randv * B + costheta * N; + *wo = randu * T + randv * B + costheta * N; *pdf = costheta * M_1_PI_F; } /* sample direction uniformly distributed in hemisphere */ ccl_device_inline void sample_uniform_hemisphere( - const float3 N, float randu, float randv, ccl_private float3 *omega_in, ccl_private float *pdf) + const float3 N, float randu, float randv, ccl_private float3 *wo, ccl_private float *pdf) { float z = randu; float r = sqrtf(max(0.0f, 1.0f - z * z)); @@ -55,7 +55,7 @@ ccl_device_inline void sample_uniform_hemisphere( float3 T, B; make_orthonormals(N, &T, &B); - *omega_in = x * T + y * B + z * N; + *wo = x * T + y * B + z * N; *pdf = 0.5f * M_1_PI_F; } @@ -64,7 +64,7 @@ ccl_device_inline void sample_uniform_cone(const float3 N, float angle, float randu, float randv, - ccl_private float3 *omega_in, + ccl_private float3 *wo, ccl_private float *pdf) { float zMin = cosf(angle); @@ -76,7 +76,7 @@ ccl_device_inline void sample_uniform_cone(const float3 N, float3 T, B; make_orthonormals(N, &T, &B); - *omega_in = x * T + y * B + z * N; + *wo = x * T + y * B + z * N; *pdf = M_1_2PI_F / (1.0f - zMin); } diff --git a/intern/cycles/kernel/svm/closure.h b/intern/cycles/kernel/svm/closure.h index d18f2cc0854..afd83ceca7c 100644 --- a/intern/cycles/kernel/svm/closure.h +++ b/intern/cycles/kernel/svm/closure.h @@ -102,7 +102,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, float3 N = stack_valid(data_node.x) ? stack_load_float3(stack, data_node.x) : sd->N; if (!(sd->type & PRIMITIVE_CURVE)) { - N = ensure_valid_reflection(sd->Ng, sd->I, N); + N = ensure_valid_reflection(sd->Ng, sd->wi, N); } float param1 = (stack_valid(param1_offset)) ? stack_load_float(stack, param1_offset) : @@ -162,8 +162,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, float ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; // calculate fresnel for refraction - float cosNO = dot(N, sd->I); - float fresnel = fresnel_dielectric_cos(cosNO, ior); + float cosNI = dot(N, sd->wi); + float fresnel = fresnel_dielectric_cos(cosNI, ior); // calculate weights of the diffuse and specular part float diffuse_weight = (1.0f - saturatef(metallic)) * (1.0f - saturatef(transmission)); @@ -185,7 +185,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, stack_load_float3(stack, data_cn_ssr.x) : sd->N; if (!(sd->type & PRIMITIVE_CURVE)) { - clearcoat_normal = ensure_valid_reflection(sd->Ng, sd->I, clearcoat_normal); + clearcoat_normal = ensure_valid_reflection(sd->Ng, sd->wi, clearcoat_normal); } float3 subsurface_radius = stack_valid(data_cn_ssr.y) ? stack_load_float3(stack, data_cn_ssr.y) : @@ -652,8 +652,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg, eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; /* fresnel */ - float cosNO = dot(N, sd->I); - float fresnel = fresnel_dielectric_cos(cosNO, eta); + float cosNI = dot(N, sd->wi); + float fresnel = fresnel_dielectric_cos(cosNI, eta); float roughness = sqr(param1); /* reflection */ diff --git a/intern/cycles/kernel/svm/displace.h b/intern/cycles/kernel/svm/displace.h index 230f8c73820..d2be8c4844b 100644 --- a/intern/cycles/kernel/svm/displace.h +++ b/intern/cycles/kernel/svm/displace.h @@ -71,7 +71,7 @@ ccl_device_noinline void svm_node_set_bump(KernelGlobals kg, object_normal_transform(kg, sd, &normal_out); } - normal_out = ensure_valid_reflection(sd->Ng, sd->I, normal_out); + normal_out = ensure_valid_reflection(sd->Ng, sd->wi, normal_out); stack_store_float3(stack, node.w, normal_out); } else diff --git a/intern/cycles/kernel/svm/fresnel.h b/intern/cycles/kernel/svm/fresnel.h index 4b68b70799b..e5970740798 100644 --- a/intern/cycles/kernel/svm/fresnel.h +++ b/intern/cycles/kernel/svm/fresnel.h @@ -22,7 +22,7 @@ ccl_device_noinline void svm_node_fresnel(ccl_private ShaderData *sd, eta = fmaxf(eta, 1e-5f); eta = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta; - float f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta); + float f = fresnel_dielectric_cos(dot(sd->wi, normal_in), eta); stack_store_float(stack, out_offset, f); } @@ -50,10 +50,10 @@ ccl_device_noinline void svm_node_layer_weight(ccl_private ShaderData *sd, float eta = fmaxf(1.0f - blend, 1e-5f); eta = (sd->flag & SD_BACKFACING) ? eta : 1.0f / eta; - f = fresnel_dielectric_cos(dot(sd->I, normal_in), eta); + f = fresnel_dielectric_cos(dot(sd->wi, normal_in), eta); } else { - f = fabsf(dot(sd->I, normal_in)); + f = fabsf(dot(sd->wi, normal_in)); if (blend != 0.5f) { blend = clamp(blend, 0.0f, 1.0f - 1e-5f); diff --git a/intern/cycles/kernel/svm/geometry.h b/intern/cycles/kernel/svm/geometry.h index cbd87d84409..829b0ab8566 100644 --- a/intern/cycles/kernel/svm/geometry.h +++ b/intern/cycles/kernel/svm/geometry.h @@ -28,7 +28,7 @@ ccl_device_noinline void svm_node_geometry(KernelGlobals kg, break; #endif case NODE_GEOM_I: - data = sd->I; + data = sd->wi; break; case NODE_GEOM_Ng: data = sd->Ng; diff --git a/intern/cycles/kernel/svm/tex_coord.h b/intern/cycles/kernel/svm/tex_coord.h index 8154c542e6f..b294616603d 100644 --- a/intern/cycles/kernel/svm/tex_coord.h +++ b/intern/cycles/kernel/svm/tex_coord.h @@ -64,9 +64,9 @@ ccl_device_noinline int svm_node_tex_coord(KernelGlobals kg, } case NODE_TEXCO_REFLECTION: { if (sd->object != OBJECT_NONE) - data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I; + data = 2.0f * dot(sd->N, sd->wi) * sd->N - sd->wi; else - data = sd->I; + data = sd->wi; break; } case NODE_TEXCO_DUPLI_GENERATED: { @@ -146,9 +146,9 @@ ccl_device_noinline int svm_node_tex_coord_bump_dx(KernelGlobals kg, } case NODE_TEXCO_REFLECTION: { if (sd->object != OBJECT_NONE) - data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I; + data = 2.0f * dot(sd->N, sd->wi) * sd->N - sd->wi; else - data = sd->I; + data = sd->wi; break; } case NODE_TEXCO_DUPLI_GENERATED: { @@ -231,9 +231,9 @@ ccl_device_noinline int svm_node_tex_coord_bump_dy(KernelGlobals kg, } case NODE_TEXCO_REFLECTION: { if (sd->object != OBJECT_NONE) - data = 2.0f * dot(sd->N, sd->I) * sd->N - sd->I; + data = 2.0f * dot(sd->N, sd->wi) * sd->N - sd->wi; else - data = sd->I; + data = sd->wi; break; } case NODE_TEXCO_DUPLI_GENERATED: { diff --git a/intern/cycles/kernel/svm/wireframe.h b/intern/cycles/kernel/svm/wireframe.h index 91fadf4cfc4..cae850419e9 100644 --- a/intern/cycles/kernel/svm/wireframe.h +++ b/intern/cycles/kernel/svm/wireframe.h @@ -47,8 +47,8 @@ ccl_device_inline float wireframe(KernelGlobals kg, if (pixel_size) { // Project the derivatives of P to the viewing plane defined // by I so we have a measure of how big is a pixel at this point - float pixelwidth_x = len(dP.dx - dot(dP.dx, sd->I) * sd->I); - float pixelwidth_y = len(dP.dy - dot(dP.dy, sd->I) * sd->I); + float pixelwidth_x = len(dP.dx - dot(dP.dx, sd->wi) * sd->wi); + float pixelwidth_y = len(dP.dy - dot(dP.dy, sd->wi) * sd->wi); // Take the average of both axis' length pixelwidth = (pixelwidth_x + pixelwidth_y) * 0.5f; } diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index ff75e70ba6b..72a9c65f303 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -888,7 +888,7 @@ typedef struct ccl_align(16) ShaderData /* true geometric normal */ float3 Ng; /* view/incoming direction */ - float3 I; + float3 wi; /* shader id */ int shader; /* booleans describing shader, see ShaderDataFlag */ @@ -920,7 +920,7 @@ typedef struct ccl_align(16) ShaderData #ifdef __RAY_DIFFERENTIALS__ /* Radius of differential of P. */ float dP; - /* Radius of differential of I. */ + /* Radius of differential of wi. */ float dI; /* differential of u, v */ differential du; diff --git a/release/datafiles/locale b/release/datafiles/locale index 7084c4ecd97..f1425d8a7fc 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 7084c4ecd97d93459d9d23fd90f81589b09be5df +Subproject commit f1425d8a7fc38e8111c2a9e125f0e7877dcd0fdf diff --git a/release/scripts/addons b/release/scripts/addons index a9d4443c244..bf49eeaa14c 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit a9d4443c244f89399ec4bcc427e05a07950528cc +Subproject commit bf49eeaa14c445d3c53068203fdf91bff568fe64 diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index bdcfdd47ec3..0f72f6c85c3 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit bdcfdd47ec3451822b21d1cff2ea2db751093c9a +Subproject commit 0f72f6c85c3743a9072273acb6a8a34b1cf1064b diff --git a/source/tools b/source/tools index e1744b9bd82..3582f5326d0 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit e1744b9bd82527cf7e8af63362b61bd309b5711b +Subproject commit 3582f5326d08ca05c2a19056597e49ec5511d854 From 34326fec02709ffaeba4d4b59f24cb0c53e721a8 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 17 Jan 2023 18:29:25 +0100 Subject: [PATCH 0707/1522] Fix: sample index node outputs default value Error in rBb5105085139227a713f154446ff6a3255cb8be99. --- source/blender/nodes/geometry/nodes/node_geo_sample_index.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc index 850b2cfdd66..2ac19b02f9c 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc @@ -323,7 +323,7 @@ static void node_geo_exec(GeoNodeExecParams params) const GVArray &data = evaluator.get_evaluated(0); BUFFER_FOR_CPP_TYPE_VALUE(cpp_type, buffer); data.get_to_uninitialized(index, buffer); - output_field = fn::make_constant_field(cpp_type, cpp_type.default_value()); + output_field = fn::make_constant_field(cpp_type, buffer); cpp_type.destruct(buffer); } else { From 1d253b6652518a68731a5d8a5909c8b29174b894 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 17 Jan 2023 18:40:28 +0100 Subject: [PATCH 0708/1522] Fix T103945: incorrect anonymous attribute references The case where the same field group input is evaluated on more than one geometry inputs was not handled correctly. --- .../nodes/intern/geometry_nodes_lazy_function.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 4aec8d405ea..54f8c3c912d 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -2250,15 +2250,18 @@ struct GeometryNodesLazyFunctionGraphBuilder { AttributeReferenceKey key; key.type = AttributeReferenceKeyType::InputField; key.index = relation.field_input; - r_attribute_reference_keys.add_new(key); - AttributeReferenceInfo info; - lf::OutputSocket &lf_field_socket = *const_cast( - mapping_->group_input_sockets[relation.field_input]); - info.lf_attribute_set_socket = &add_get_attributes_node(lf_field_socket); + const int key_index = r_attribute_reference_keys.index_of_or_add(key); + if (key_index >= r_attribute_reference_infos.size()) { + AttributeReferenceInfo info; + lf::OutputSocket &lf_field_socket = *const_cast( + mapping_->group_input_sockets[relation.field_input]); + info.lf_attribute_set_socket = &add_get_attributes_node(lf_field_socket); + r_attribute_reference_infos.append(info); + } + AttributeReferenceInfo &info = r_attribute_reference_infos[key_index]; for (const bNode *bnode : btree_.group_input_nodes()) { info.initial_geometry_sockets.append(&bnode->output_socket(relation.geometry_input)); } - r_attribute_reference_infos.append(std::move(info)); } /* Find group outputs that attributes need to be propagated to. */ for (const aal::PropagateRelation &relation : tree_relations.propagate_relations) { From 665732115ec5779e121333fb3a9f34f141c1d06b Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 17 Jan 2023 19:31:00 +0100 Subject: [PATCH 0709/1522] Gitea: add separate issue templates for bug, design and todo --- .../{issue_template.yaml => issue_template/bug.yaml} | 1 + .gitea/issue_template/design.yaml | 10 ++++++++++ .gitea/issue_template/todo.yaml | 10 ++++++++++ 3 files changed, 21 insertions(+) rename .gitea/{issue_template.yaml => issue_template/bug.yaml} (99%) create mode 100644 .gitea/issue_template/design.yaml create mode 100644 .gitea/issue_template/todo.yaml diff --git a/.gitea/issue_template.yaml b/.gitea/issue_template/bug.yaml similarity index 99% rename from .gitea/issue_template.yaml rename to .gitea/issue_template/bug.yaml index 08b98a0112e..41cc6a4ed74 100644 --- a/.gitea/issue_template.yaml +++ b/.gitea/issue_template/bug.yaml @@ -27,6 +27,7 @@ body: If a report is tagged with Needs Information from User and it has no reply after a week, we will assume the issue is gone and close the report. - type: textarea + id: body attributes: label: "Description" value: | diff --git a/.gitea/issue_template/design.yaml b/.gitea/issue_template/design.yaml new file mode 100644 index 00000000000..b482c8fad42 --- /dev/null +++ b/.gitea/issue_template/design.yaml @@ -0,0 +1,10 @@ +name: Design +about: Create a design task (for developers only) +labels: + - design +ref: master +body: + - type: textarea + id: body + attributes: + label: "Description" diff --git a/.gitea/issue_template/todo.yaml b/.gitea/issue_template/todo.yaml new file mode 100644 index 00000000000..8c08d897b2b --- /dev/null +++ b/.gitea/issue_template/todo.yaml @@ -0,0 +1,10 @@ +name: To Do +about: Create a to do task (for developers only) +labels: + - todo +ref: master +body: + - type: textarea + id: body + attributes: + label: "Description" From d76a0e98baecfca4e691fd29bcf027d8cc1e07bf Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 17 Jan 2023 12:16:38 -0600 Subject: [PATCH 0710/1522] Fix: Avoid node reevaluations for selection and parenting Since 90ea1b76434fe175e9, node trees have been reevaluated after many selection operations because nodes are sorted based on the selection status and an update tag was added for that. However, for years the node order was allowed to be different between the original and evaluated copy of node trees. Though it is a bit sketchy to have that difference in the evaluated node tree, reevaluations for just selection are very bad, so use a "smaller" update tag and add a comment for justification. Differential Revision: https://developer.blender.org/D17023 --- source/blender/blenkernel/intern/node_tree_update.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/node_tree_update.cc b/source/blender/blenkernel/intern/node_tree_update.cc index 2943bea830b..374d67bbfa8 100644 --- a/source/blender/blenkernel/intern/node_tree_update.cc +++ b/source/blender/blenkernel/intern/node_tree_update.cc @@ -1131,7 +1131,11 @@ void BKE_ntree_update_tag_node_removed(bNodeTree *ntree) void BKE_ntree_update_tag_node_reordered(bNodeTree *ntree) { - add_tree_tag(ntree, NTREE_CHANGED_ANY); + /* Don't add a tree update tag to avoid reevaluations for trivial operations like selection or + * parenting that typically influence the node order. This means the node order can be different + * for original and evaluated trees. A different solution might avoid sorting nodes based on UI + * states like selection, which would require not tying the node order to the drawing order. */ + ntree->runtime->topology_cache_mutex.tag_dirty(); } void BKE_ntree_update_tag_node_mute(bNodeTree *ntree, bNode *node) From df5456123377cb5ad5940af1b9a71ede481309d3 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 17 Jan 2023 12:17:07 -0600 Subject: [PATCH 0711/1522] Cleanup: Fix incorrect comments in mesh extrude node --- .../blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc index 29a5cb9b83c..28691252729 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_extrude_mesh.cc @@ -87,10 +87,6 @@ static void save_selection_as_attribute(Mesh &mesh, attribute.finish(); } -/** - * \note Some areas in this file rely on the new sections of attributes from #CustomData_realloc - * to be zeroed. - */ static void expand_mesh(Mesh &mesh, const int vert_expand, const int edge_expand, @@ -389,7 +385,7 @@ static void extrude_mesh_edges(Mesh &mesh, const Array> edge_to_poly_map = mesh_calculate_polys_of_edge(mesh); /* Find the offsets on the vertex domain for translation. This must be done before the mesh's - * custom data layers are reallocated, in case the virtual array references on of them. */ + * custom data layers are reallocated, in case the virtual array references one of them. */ Array vert_offsets; if (!edge_offsets.is_single()) { vert_offsets.reinitialize(orig_vert_size); @@ -1367,8 +1363,6 @@ static void node_geo_exec(GeoNodeExecParams params) break; } } - - BLI_assert(BKE_mesh_is_valid(mesh)); } }); From 85ea74ad77ee067d037630bd59deda62e99aab4e Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 17 Jan 2023 12:43:31 -0600 Subject: [PATCH 0712/1522] Cleanup: Remove unnecessary curves RNA verification disabling There is no SDNA data for `position_data` anymore after e9f82d3dc7eebadcc52fdc43. --- source/blender/makesrna/intern/rna_curves.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_curves.c b/source/blender/makesrna/intern/rna_curves.c index 11114f298a9..3db4695a9b9 100644 --- a/source/blender/makesrna/intern/rna_curves.c +++ b/source/blender/makesrna/intern/rna_curves.c @@ -338,7 +338,6 @@ static void rna_def_curves(BlenderRNA *brna) /* Direct access to built-in attributes. */ - RNA_define_verify_sdna(0); prop = RNA_def_property(srna, "position_data", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_funcs(prop, "rna_Curves_position_data_begin", @@ -351,7 +350,6 @@ static void rna_def_curves(BlenderRNA *brna) NULL); RNA_def_property_struct_type(prop, "FloatVectorAttributeValue"); RNA_def_property_update(prop, 0, "rna_Curves_update_data"); - RNA_define_verify_sdna(1); prop = RNA_def_property(srna, "curve_offset_data", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "geometry.curve_offsets", NULL); From d42d4e339f20a0eb95b9f333159edea446e8b364 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 17 Jan 2023 12:45:51 -0600 Subject: [PATCH 0713/1522] Cleanup: Remove unnecessary includes in geometry set header --- source/blender/blenkernel/BKE_geometry_fields.hh | 1 - source/blender/blenkernel/BKE_geometry_set.hh | 4 ---- source/blender/blenkernel/BKE_geometry_set_instances.hh | 2 ++ source/blender/nodes/geometry/node_geometry_util.hh | 1 + source/blender/nodes/intern/node_socket.cc | 1 + 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/BKE_geometry_fields.hh b/source/blender/blenkernel/BKE_geometry_fields.hh index 5f5333beb63..019ff41184b 100644 --- a/source/blender/blenkernel/BKE_geometry_fields.hh +++ b/source/blender/blenkernel/BKE_geometry_fields.hh @@ -8,7 +8,6 @@ * Common field utilities and field definitions for geometry components. */ -#include "BKE_attribute.h" #include "BKE_geometry_set.hh" #include "FN_field.hh" diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh index 42d773055fa..f450ffe33e8 100644 --- a/source/blender/blenkernel/BKE_geometry_set.hh +++ b/source/blender/blenkernel/BKE_geometry_set.hh @@ -10,16 +10,12 @@ #include #include -#include "BLI_float4x4.hh" #include "BLI_function_ref.hh" -#include "BLI_hash.hh" #include "BLI_map.hh" #include "BLI_math_vector_types.hh" -#include "BLI_set.hh" #include "BLI_user_counter.hh" #include "BLI_vector_set.hh" -#include "BKE_anonymous_attribute_id.hh" #include "BKE_attribute.hh" #include "BKE_geometry_set.h" diff --git a/source/blender/blenkernel/BKE_geometry_set_instances.hh b/source/blender/blenkernel/BKE_geometry_set_instances.hh index 6d4b9a2128c..3e9fb1d0379 100644 --- a/source/blender/blenkernel/BKE_geometry_set_instances.hh +++ b/source/blender/blenkernel/BKE_geometry_set_instances.hh @@ -2,6 +2,8 @@ #pragma once +#include "BLI_float4x4.hh" + #include "BKE_geometry_set.hh" namespace blender::bke { diff --git a/source/blender/nodes/geometry/node_geometry_util.hh b/source/blender/nodes/geometry/node_geometry_util.hh index 68205c3ce6b..84dbd8e1fef 100644 --- a/source/blender/nodes/geometry/node_geometry_util.hh +++ b/source/blender/nodes/geometry/node_geometry_util.hh @@ -4,6 +4,7 @@ #include +#include "BLI_float4x4.hh" #include "BLI_math_vector_types.hh" #include "BLI_utildefines.h" diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index 2fbf14b4760..814ad1c80e1 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -11,6 +11,7 @@ #include "BLI_color.hh" #include "BLI_listbase.h" +#include "BLI_math_vector.h" #include "BLI_math_vector_types.hh" #include "BLI_string.h" #include "BLI_utildefines.h" From 17768b3df19a91388a71df6fdd3c29c0543b706a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 17 Jan 2023 21:02:28 +0100 Subject: [PATCH 0714/1522] BLI: Math: Fix perspective matrix function The port missed this one component that should have been left to 0.0. --- source/blender/blenlib/BLI_math_matrix.hh | 1 + .../blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl | 1 + 2 files changed, 2 insertions(+) diff --git a/source/blender/blenlib/BLI_math_matrix.hh b/source/blender/blenlib/BLI_math_matrix.hh index 79699e082f6..d6a5e907111 100644 --- a/source/blender/blenlib/BLI_math_matrix.hh +++ b/source/blender/blenlib/BLI_math_matrix.hh @@ -1136,6 +1136,7 @@ MatBase perspective(T left, T right, T bottom, T top, T near_clip, T fa mat[2][2] = -(far_clip + near_clip) / z_delta; mat[2][3] = -1.0f; mat[3][2] = (-2.0f * near_clip * far_clip) / z_delta; + mat[3][3] = 0.0f; } return mat; } diff --git a/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl index 1ed8eb46f19..b3712f4077c 100644 --- a/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl +++ b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl @@ -1343,6 +1343,7 @@ mat4x4 projection_perspective( mat[2][2] = -(far_clip + near_clip) / z_delta; mat[2][3] = -1.0; mat[3][2] = (-2.0 * near_clip * far_clip) / z_delta; + mat[3][3] = 0.0; } return mat; } From dcb37959d467cdf3d24e7e1d7ebec7c1a5e92925 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Tue, 17 Jan 2023 17:21:39 -0300 Subject: [PATCH 0715/1522] Fix roation snap failing with zero angle Due to precision issues, the cosine value calculated with `dot_v3v3(start, end)` can be outside the -1, 1 range causing `acosf` to return `nan(ind)`. Use `angle_signed_on_axis_v3v3_v3` instead. It returns more accurate values, deduplicates code, and avoids these `nan` issues. --- .../editors/transform/transform_mode_rotate.c | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/source/blender/editors/transform/transform_mode_rotate.c b/source/blender/editors/transform/transform_mode_rotate.c index 0a49fdefd83..713902f6c62 100644 --- a/source/blender/editors/transform/transform_mode_rotate.c +++ b/source/blender/editors/transform/transform_mode_rotate.c @@ -171,27 +171,11 @@ static float RotationBetween(TransInfo *t, const float p1[3], const float p2[3]) /* Angle around a constraint axis (error prone, will need debug). */ if (t->con.applyRot != NULL && (t->con.mode & CON_APPLY)) { - float axis[3], tmp[3]; + float axis[3]; t->con.applyRot(t, NULL, NULL, axis, NULL); - project_v3_v3v3(tmp, end, axis); - sub_v3_v3v3(end, end, tmp); - - project_v3_v3v3(tmp, start, axis); - sub_v3_v3v3(start, start, tmp); - - normalize_v3(end); - normalize_v3(start); - - cross_v3_v3v3(tmp, start, end); - - if (dot_v3v3(tmp, axis) < 0.0f) { - angle = -acosf(dot_v3v3(start, end)); - } - else { - angle = acosf(dot_v3v3(start, end)); - } + angle = -angle_signed_on_axis_v3v3_v3(start, end, axis); } else { float mtx[3][3]; From 301119619c96aac2c6c3ec3a83bc16c5b3110469 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 17 Jan 2023 14:40:01 -0600 Subject: [PATCH 0716/1522] Curves: Remove attribute retrieval, deduplicate evaluation logic Avoid calling `interpolate_to_evaluate` while evaluating normals, which has to look up attributes by name for every curve. Also avoid duplicating the curve type switch in a few functions. I didn't observe a performance difference, but theoretically this could reduce overhead for many small curves. --- .../blenkernel/intern/curves_geometry.cc | 135 +++++++++++------- 1 file changed, 81 insertions(+), 54 deletions(-) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 0dc6a24fd9e..133521bc298 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -716,14 +716,57 @@ static void rotate_directions_around_axes(MutableSpan directions, } } +static void evaluate_generic_data_for_curve( + const int curve_index, + const IndexRange points, + const VArray &types, + const VArray &cyclic, + const VArray &resolution, + const Span bezier_evaluated_offsets, + const Span nurbs_basis_cache, + const VArray &nurbs_orders, + const Span nurbs_weights, + const GSpan src, + GMutableSpan dst) +{ + switch (types[curve_index]) { + case CURVE_TYPE_CATMULL_ROM: + curves::catmull_rom::interpolate_to_evaluated( + src, cyclic[curve_index], resolution[curve_index], dst); + break; + case CURVE_TYPE_POLY: + dst.copy_from(src); + break; + case CURVE_TYPE_BEZIER: + curves::bezier::interpolate_to_evaluated(src, bezier_evaluated_offsets.slice(points), dst); + break; + case CURVE_TYPE_NURBS: + curves::nurbs::interpolate_to_evaluated(nurbs_basis_cache[curve_index], + nurbs_orders[curve_index], + nurbs_weights.slice_safe(points), + src, + dst); + break; + } +} + Span CurvesGeometry::evaluated_normals() const { this->runtime->normal_cache_mutex.ensure([&]() { - const Span evaluated_tangents = this->evaluated_tangents(); + const VArray types = this->curve_types(); const VArray cyclic = this->cyclic(); const VArray normal_mode = this->normal_mode(); - const VArray types = this->curve_types(); + const VArray resolution = this->resolution(); + const VArray nurbs_orders = this->nurbs_orders(); + const Span nurbs_weights = this->nurbs_weights(); + + const Span evaluated_tangents = this->evaluated_tangents(); const VArray tilt = this->tilt(); + VArraySpan tilt_span; + const bool use_tilt = !(tilt.is_single() && tilt.get_internal_single() == 0.0f); + if (use_tilt) { + tilt_span = tilt; + } this->runtime->evaluated_normal_cache.resize(this->evaluated_points_num()); MutableSpan evaluated_normals = this->runtime->evaluated_normal_cache; @@ -748,19 +791,26 @@ Span CurvesGeometry::evaluated_normals() const /* If the "tilt" attribute exists, rotate the normals around the tangents by the * evaluated angles. We can avoid copying the tilts to evaluate them for poly curves. */ - if (!(tilt.is_single() && tilt.get_internal_single() == 0.0f)) { + if (use_tilt) { const IndexRange points = this->points_for_curve(curve_index); - Span curve_tilt = tilt.get_internal_span().slice(points); if (types[curve_index] == CURVE_TYPE_POLY) { rotate_directions_around_axes(evaluated_normals.slice(evaluated_points), evaluated_tangents.slice(evaluated_points), - curve_tilt); + tilt_span.slice(points)); } else { - evaluated_tilts.clear(); - evaluated_tilts.resize(evaluated_points.size()); - this->interpolate_to_evaluated( - curve_index, curve_tilt, evaluated_tilts.as_mutable_span()); + evaluated_tilts.reinitialize(evaluated_points.size()); + evaluate_generic_data_for_curve(curve_index, + points, + types, + cyclic, + resolution, + this->runtime->bezier_evaluated_offsets.as_span(), + this->runtime->nurbs_basis_cache.as_span(), + nurbs_orders, + nurbs_weights, + tilt_span.slice(points), + evaluated_tilts.as_mutable_span()); rotate_directions_around_axes(evaluated_normals.slice(evaluated_points), evaluated_tangents.slice(evaluated_points), evaluated_tilts.as_span()); @@ -781,27 +831,17 @@ void CurvesGeometry::interpolate_to_evaluated(const int curve_index, const IndexRange points = this->points_for_curve(curve_index); BLI_assert(src.size() == points.size()); BLI_assert(dst.size() == this->evaluated_points_for_curve(curve_index).size()); - switch (this->curve_types()[curve_index]) { - case CURVE_TYPE_CATMULL_ROM: - curves::catmull_rom::interpolate_to_evaluated( - src, this->cyclic()[curve_index], this->resolution()[curve_index], dst); - return; - case CURVE_TYPE_POLY: - dst.type().copy_assign_n(src.data(), dst.data(), src.size()); - return; - case CURVE_TYPE_BEZIER: - curves::bezier::interpolate_to_evaluated( - src, this->runtime->bezier_evaluated_offsets.as_span().slice(points), dst); - return; - case CURVE_TYPE_NURBS: - curves::nurbs::interpolate_to_evaluated(this->runtime->nurbs_basis_cache[curve_index], - this->nurbs_orders()[curve_index], - this->nurbs_weights().slice_safe(points), - src, - dst); - return; - } - BLI_assert_unreachable(); + evaluate_generic_data_for_curve(curve_index, + points, + this->curve_types(), + this->cyclic(), + this->resolution(), + this->runtime->bezier_evaluated_offsets.as_span(), + this->runtime->nurbs_basis_cache.as_span(), + this->nurbs_orders(), + this->nurbs_weights(), + src, + dst); } void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst) const @@ -818,30 +858,17 @@ void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst) for (const int curve_index : curves_range) { const IndexRange points = this->points_for_curve(curve_index); const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); - switch (types[curve_index]) { - case CURVE_TYPE_CATMULL_ROM: - curves::catmull_rom::interpolate_to_evaluated(src.slice(points), - cyclic[curve_index], - resolution[curve_index], - dst.slice(evaluated_points)); - continue; - case CURVE_TYPE_POLY: - dst.slice(evaluated_points).copy_from(src.slice(points)); - continue; - case CURVE_TYPE_BEZIER: - curves::bezier::interpolate_to_evaluated( - src.slice(points), - this->runtime->bezier_evaluated_offsets.as_span().slice(points), - dst.slice(evaluated_points)); - continue; - case CURVE_TYPE_NURBS: - curves::nurbs::interpolate_to_evaluated(this->runtime->nurbs_basis_cache[curve_index], - nurbs_orders[curve_index], - nurbs_weights.slice_safe(points), - src.slice(points), - dst.slice(evaluated_points)); - continue; - } + evaluate_generic_data_for_curve(curve_index, + points, + types, + cyclic, + resolution, + this->runtime->bezier_evaluated_offsets, + this->runtime->nurbs_basis_cache, + nurbs_orders, + nurbs_weights, + src.slice(points), + dst.slice(evaluated_points)); } }); } From 737e7a63b1664d7cff0fdd9587ed6a4f2ccffe7e Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 18 Jan 2023 00:05:33 +0100 Subject: [PATCH 0717/1522] Fix: incorrect curve type counts after adding curves of same type --- source/blender/blenkernel/intern/curves_geometry.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 133521bc298..3d4f81019a7 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -263,7 +263,7 @@ void CurvesGeometry::fill_curve_types(const IndexMask selection, const CurveType } if (std::optional single_type = this->curve_types().get_if_single()) { if (single_type == type) { - /* No need for an array if the types are already a single with the correct type. */ + this->fill_curve_types(type); return; } } From bdb34c98041dd1185a9c5f599e89bf04cfa9c0ea Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Jan 2023 01:33:33 +0100 Subject: [PATCH 0718/1522] Gitea: add more complete pull request template --- .gitea/pull_request_template.md | 4 ---- .gitea/pull_request_template.yaml | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) delete mode 100644 .gitea/pull_request_template.md create mode 100644 .gitea/pull_request_template.yaml diff --git a/.gitea/pull_request_template.md b/.gitea/pull_request_template.md deleted file mode 100644 index a6614b8ef00..00000000000 --- a/.gitea/pull_request_template.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -name: Pull Request -about: Submit a pull request ---- diff --git a/.gitea/pull_request_template.yaml b/.gitea/pull_request_template.yaml new file mode 100644 index 00000000000..f7c3242f55c --- /dev/null +++ b/.gitea/pull_request_template.yaml @@ -0,0 +1,19 @@ +name: Pull Request +about: Contribute code to Blender +ref: master +body: + - type: markdown + attributes: + value: | + Guides to [Contributing Code](https://wiki.blender.org/index.php/Dev:Doc/Process/Contributing_Code) and effective [Code Review](https://wiki.blender.org/index.php/Dev:Doc/Tools/Code_Review). + + By submitting code here, **you agree that the code is (compatible with) GNU GPL v2 or later**. + + - type: textarea + id: body + attributes: + label: "Description" + value: | + Description of the problem that is addressed in the patch. + + Description of the proposed solution and its implementation. From d45ad0acd344f5d8e2fcc2838c7f1525da24d246 Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Tue, 17 Jan 2023 19:25:26 -0600 Subject: [PATCH 0719/1522] Geometry Nodes: Show supported geometry types tooltip without computing Socket declarations exist all the time and it would be useful to use them for tooltips at all times, not just when there is a computed log. Differential Revision: https://developer.blender.org/D16846 --- .../blender/editors/space_node/node_draw.cc | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index ef284c3e3bf..d3b34c408cf 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -900,8 +900,7 @@ static void create_inspection_string_for_field_info(const bNodeSocket &socket, } static void create_inspection_string_for_geometry_info(const geo_log::GeometryInfoLog &value_log, - std::stringstream &ss, - const nodes::decl::Geometry *socket_decl) + std::stringstream &ss) { Span component_types = value_log.component_types; if (component_types.is_empty()) { @@ -917,7 +916,6 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn ss << TIP_("Geometry:\n"); for (GeometryComponentType type : component_types) { - const char *line_end = (type == component_types.last()) ? "" : ".\n"; switch (type) { case GEO_COMPONENT_TYPE_MESH: { const geo_log::GeometryInfoLog::MeshInfo &mesh_info = *value_log.mesh_info; @@ -928,7 +926,7 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn to_string(mesh_info.verts_num).c_str(), to_string(mesh_info.edges_num).c_str(), to_string(mesh_info.faces_num).c_str()); - ss << line << line_end; + ss << line; break; } case GEO_COMPONENT_TYPE_POINT_CLOUD: { @@ -939,7 +937,7 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn sizeof(line), TIP_("\u2022 Point Cloud: %s points"), to_string(pointcloud_info.points_num).c_str()); - ss << line << line_end; + ss << line; break; } case GEO_COMPONENT_TYPE_CURVE: { @@ -949,7 +947,7 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn sizeof(line), TIP_("\u2022 Curve: %s splines"), to_string(curve_info.splines_num).c_str()); - ss << line << line_end; + ss << line; break; } case GEO_COMPONENT_TYPE_INSTANCES: { @@ -959,11 +957,11 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn sizeof(line), TIP_("\u2022 Instances: %s"), to_string(instances_info.instances_num).c_str()); - ss << line << line_end; + ss << line; break; } case GEO_COMPONENT_TYPE_VOLUME: { - ss << TIP_("\u2022 Volume") << line_end; + ss << TIP_("\u2022 Volume"); break; } case GEO_COMPONENT_TYPE_EDIT: { @@ -975,26 +973,38 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn TIP_("\u2022 Edit Curves: %s, %s"), edit_info.has_deformed_positions ? TIP_("positions") : TIP_("no positions"), edit_info.has_deform_matrices ? TIP_("matrices") : TIP_("no matrices")); - ss << line << line_end; + ss << line; } break; } } + if (type != component_types.last()) { + ss << ".\n"; + } } +} +static void create_inspection_string_for_geometry_socket(std::stringstream &ss, + const nodes::decl::Geometry *socket_decl, + const bool after_log) +{ /* If the geometry declaration is null, as is the case for input to group output, * or it is an output socket don't show supported types. */ if (socket_decl == nullptr || socket_decl->in_out == SOCK_OUT) { return; } + if (after_log) { + ss << ".\n\n"; + } + Span supported_types = socket_decl->supported_types(); if (supported_types.is_empty()) { - ss << ".\n\n" << TIP_("Supported: All Types"); + ss << TIP_("Supported: All Types"); return; } - ss << ".\n\n" << TIP_("Supported: "); + ss << TIP_("Supported: "); for (GeometryComponentType type : supported_types) { switch (type) { case GEO_COMPONENT_TYPE_MESH: { @@ -1021,7 +1031,9 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn break; } } - ss << ((type == supported_types.last()) ? "" : ", "); + if (type != supported_types.last()) { + ss << ", "; + } } } @@ -1036,9 +1048,6 @@ static std::optional create_socket_inspection_string(TreeDrawContex tree_draw_ctx.geo_tree_log->ensure_socket_values(); ValueLog *value_log = tree_draw_ctx.geo_tree_log->find_socket_value_log(socket); - if (value_log == nullptr) { - return std::nullopt; - } std::stringstream ss; if (const geo_log::GenericValueLog *generic_value_log = dynamic_cast(value_log)) { @@ -1050,10 +1059,13 @@ static std::optional create_socket_inspection_string(TreeDrawContex } else if (const geo_log::GeometryInfoLog *geo_value_log = dynamic_cast(value_log)) { - create_inspection_string_for_geometry_info( - *geo_value_log, - ss, - dynamic_cast(socket.runtime->declaration)); + create_inspection_string_for_geometry_info(*geo_value_log, ss); + } + + if (const nodes::decl::Geometry *socket_decl = dynamic_cast( + socket.runtime->declaration)) { + const bool after_log = value_log != nullptr; + create_inspection_string_for_geometry_socket(ss, socket_decl, after_log); } std::string str = ss.str(); From 9179362e7b05d334ec8490bcdd6d04c05af4a81a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Tue, 17 Jan 2023 19:43:36 -0600 Subject: [PATCH 0720/1522] Geometry Nodes: Prefer evaluate at index value input in search Give the "Value" input a higher search weight than the "Index" input, since it's more likely that users will want to connect to that. Based on feedback from Simon Thommes. --- .../geometry/nodes/node_geo_evaluate_at_index.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_evaluate_at_index.cc b/source/blender/nodes/geometry/nodes/node_geo_evaluate_at_index.cc index 65f88f23aff..68d309c0bf4 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_evaluate_at_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_evaluate_at_index.cc @@ -131,9 +131,6 @@ static void node_update(bNodeTree *ntree, bNode *node) static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { - const NodeDeclaration &declaration = *params.node_type().fixed_declaration; - search_link_ops_for_declarations(params, declaration.inputs.as_span().take_front(1)); - const bNodeType &node_type = params.node_type(); const std::optional type = node_data_type_to_custom_data_type( (eNodeSocketDatatype)params.other_socket().type); @@ -143,6 +140,14 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) node.custom2 = *type; params.update_and_connect_available_socket(node, "Value"); }); + params.add_item( + IFACE_("Index"), + [node_type, type](LinkSearchOpParams ¶ms) { + bNode &node = params.add_node(node_type); + node.custom2 = *type; + params.update_and_connect_available_socket(node, "Index"); + }, + -1); } } From 44dd3308a5b66fbd9bc4dc39304690f64da8d971 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 18 Jan 2023 13:47:00 +1100 Subject: [PATCH 0721/1522] DNA: move Collection members into their own Runtime struct Also add static assert that COLLECTION_COLOR_TOT has the correct number of items in the enum. --- .../blenkernel/intern/blendfile_link_append.c | 3 +- source/blender/blenkernel/intern/collection.c | 100 +++++++++--------- source/blender/blenkernel/intern/layer.cc | 6 +- source/blender/blenkernel/intern/scene.cc | 2 +- .../editors/interface/interface_templates.cc | 5 +- .../blender/editors/object/object_relations.c | 2 +- .../space_outliner/outliner_collections.cc | 2 +- .../space_outliner/outliner_dragdrop.cc | 2 +- .../editors/space_outliner/outliner_draw.cc | 2 +- .../tree/tree_display_libraries.cc | 2 +- .../blender/makesdna/DNA_collection_types.h | 90 +++++++++------- .../blender/makesrna/intern/rna_collection.c | 3 + 12 files changed, 121 insertions(+), 98 deletions(-) diff --git a/source/blender/blenkernel/intern/blendfile_link_append.c b/source/blender/blenkernel/intern/blendfile_link_append.c index 3f3c1028d10..49b480fcb64 100644 --- a/source/blender/blenkernel/intern/blendfile_link_append.c +++ b/source/blender/blenkernel/intern/blendfile_link_append.c @@ -574,7 +574,8 @@ static void loose_data_instantiate_obdata_preprocess( * (return false). */ static bool loose_data_instantiate_collection_parents_check_recursive(Collection *collection) { - for (CollectionParent *parent_collection = collection->parents.first; parent_collection != NULL; + for (CollectionParent *parent_collection = collection->runtime.parents.first; + parent_collection != NULL; parent_collection = parent_collection->next) { if ((parent_collection->collection->id.tag & LIB_TAG_DOIT) != 0) { return true; diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 53ef78525c2..1ca870bd397 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -114,12 +114,12 @@ static void collection_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons collection_dst->flag &= ~COLLECTION_HAS_OBJECT_CACHE; collection_dst->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED; - BLI_listbase_clear(&collection_dst->object_cache); - BLI_listbase_clear(&collection_dst->object_cache_instanced); + BLI_listbase_clear(&collection_dst->runtime.object_cache); + BLI_listbase_clear(&collection_dst->runtime.object_cache_instanced); BLI_listbase_clear(&collection_dst->gobject); BLI_listbase_clear(&collection_dst->children); - BLI_listbase_clear(&collection_dst->parents); + BLI_listbase_clear(&collection_dst->runtime.parents); LISTBASE_FOREACH (CollectionChild *, child, &collection_src->children) { collection_child_add(collection_dst, child->collection, flag, false); @@ -138,7 +138,7 @@ static void collection_free_data(ID *id) BLI_freelistN(&collection->gobject); BLI_freelistN(&collection->children); - BLI_freelistN(&collection->parents); + BLI_freelistN(&collection->runtime.parents); BKE_collection_object_cache_free(collection); } @@ -148,7 +148,7 @@ static void collection_foreach_id(ID *id, LibraryForeachIDData *data) Collection *collection = (Collection *)id; BKE_LIB_FOREACHID_PROCESS_ID( - data, collection->owner_id, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF); + data, collection->runtime.owner_id, IDWALK_CB_LOOPBACK | IDWALK_CB_NEVER_SELF); LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) { BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, cob->ob, IDWALK_CB_USER); @@ -157,7 +157,7 @@ static void collection_foreach_id(ID *id, LibraryForeachIDData *data) BKE_LIB_FOREACHID_PROCESS_IDSUPER( data, child->collection, IDWALK_CB_NEVER_SELF | IDWALK_CB_USER); } - LISTBASE_FOREACH (CollectionParent *, parent, &collection->parents) { + LISTBASE_FOREACH (CollectionParent *, parent, &collection->runtime.parents) { /* XXX This is very weak. The whole idea of keeping pointers to private IDs is very bad * anyway... */ const int cb_flag = ((parent->collection != NULL && @@ -178,11 +178,12 @@ static ID **collection_owner_pointer_get(ID *id) Collection *master_collection = (Collection *)id; BLI_assert((master_collection->flag & COLLECTION_IS_MASTER) != 0); - BLI_assert(master_collection->owner_id != NULL); - BLI_assert(GS(master_collection->owner_id->name) == ID_SCE); - BLI_assert(((Scene *)master_collection->owner_id)->master_collection == master_collection); + BLI_assert(master_collection->runtime.owner_id != NULL); + BLI_assert(GS(master_collection->runtime.owner_id->name) == ID_SCE); + BLI_assert(((Scene *)master_collection->runtime.owner_id)->master_collection == + master_collection); - return &master_collection->owner_id; + return &master_collection->runtime.owner_id; } void BKE_collection_blend_write_nolib(BlendWriter *writer, Collection *collection) @@ -208,10 +209,10 @@ static void collection_blend_write(BlendWriter *writer, ID *id, const void *id_a /* Clean up, important in undo case to reduce false detection of changed data-blocks. */ collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED; - collection->tag = 0; - BLI_listbase_clear(&collection->object_cache); - BLI_listbase_clear(&collection->object_cache_instanced); - BLI_listbase_clear(&collection->parents); + collection->runtime.tag = 0; + BLI_listbase_clear(&collection->runtime.object_cache); + BLI_listbase_clear(&collection->runtime.object_cache_instanced); + BLI_listbase_clear(&collection->runtime.parents); /* write LibData */ BLO_write_id_struct(writer, Collection, id_address, &collection->id); @@ -258,7 +259,7 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect } collection->id.flag |= LIB_EMBEDDED_DATA; } - collection->owner_id = owner_id; + collection->runtime.owner_id = owner_id; BLO_read_list(reader, &collection->gobject); BLO_read_list(reader, &collection->children); @@ -268,10 +269,10 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED; - collection->tag = 0; - BLI_listbase_clear(&collection->object_cache); - BLI_listbase_clear(&collection->object_cache_instanced); - BLI_listbase_clear(&collection->parents); + collection->runtime.tag = 0; + BLI_listbase_clear(&collection->runtime.object_cache); + BLI_listbase_clear(&collection->runtime.object_cache_instanced); + BLI_listbase_clear(&collection->runtime.parents); #ifdef USE_COLLECTION_COMPAT_28 /* This runs before the very first doversion. */ @@ -543,7 +544,7 @@ bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy) else { /* Link child collections into parent collection. */ LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { - LISTBASE_FOREACH (CollectionParent *, cparent, &collection->parents) { + LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime.parents) { Collection *parent = cparent->collection; collection_child_add(parent, child->collection, 0, true); } @@ -552,7 +553,7 @@ bool BKE_collection_delete(Main *bmain, Collection *collection, bool hierarchy) CollectionObject *cob = collection->gobject.first; while (cob != NULL) { /* Link child object into parent collections. */ - LISTBASE_FOREACH (CollectionParent *, cparent, &collection->parents) { + LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime.parents) { Collection *parent = cparent->collection; collection_object_add(bmain, parent, cob->ob, 0, true); } @@ -816,13 +817,13 @@ ListBase BKE_collection_object_cache_get(Collection *collection) BLI_mutex_lock(&cache_lock); if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE)) { - collection_object_cache_fill(&collection->object_cache, collection, 0, false); + collection_object_cache_fill(&collection->runtime.object_cache, collection, 0, false); collection->flag |= COLLECTION_HAS_OBJECT_CACHE; } BLI_mutex_unlock(&cache_lock); } - return collection->object_cache; + return collection->runtime.object_cache; } ListBase BKE_collection_object_cache_instanced_get(Collection *collection) @@ -832,13 +833,14 @@ ListBase BKE_collection_object_cache_instanced_get(Collection *collection) BLI_mutex_lock(&cache_lock); if (!(collection->flag & COLLECTION_HAS_OBJECT_CACHE_INSTANCED)) { - collection_object_cache_fill(&collection->object_cache_instanced, collection, 0, true); + collection_object_cache_fill( + &collection->runtime.object_cache_instanced, collection, 0, true); collection->flag |= COLLECTION_HAS_OBJECT_CACHE_INSTANCED; } BLI_mutex_unlock(&cache_lock); } - return collection->object_cache_instanced; + return collection->runtime.object_cache_instanced; } static void collection_object_cache_free(Collection *collection) @@ -846,10 +848,10 @@ static void collection_object_cache_free(Collection *collection) /* Clear own cache an for all parents, since those are affected by changes as well. */ collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED; - BLI_freelistN(&collection->object_cache); - BLI_freelistN(&collection->object_cache_instanced); + BLI_freelistN(&collection->runtime.object_cache); + BLI_freelistN(&collection->runtime.object_cache_instanced); - LISTBASE_FOREACH (CollectionParent *, parent, &collection->parents) { + LISTBASE_FOREACH (CollectionParent *, parent, &collection->runtime.parents) { collection_object_cache_free(parent->collection); } } @@ -884,7 +886,7 @@ Collection *BKE_collection_master_add(Scene *scene) Collection *master_collection = BKE_libblock_alloc( NULL, ID_GR, BKE_SCENE_COLLECTION_NAME, LIB_ID_CREATE_NO_MAIN); master_collection->id.flag |= LIB_EMBEDDED_DATA; - master_collection->owner_id = &scene->id; + master_collection->runtime.owner_id = &scene->id; master_collection->flag |= COLLECTION_IS_MASTER; master_collection->color_tag = COLLECTION_COLOR_NONE; @@ -1024,7 +1026,7 @@ static void collection_tag_update_parent_recursive(Main *bmain, DEG_id_tag_update_ex(bmain, &collection->id, flag); - LISTBASE_FOREACH (CollectionParent *, collection_parent, &collection->parents) { + LISTBASE_FOREACH (CollectionParent *, collection_parent, &collection->runtime.parents) { if (collection_parent->collection->flag & COLLECTION_IS_MASTER) { /* We don't care about scene/master collection here. */ continue; @@ -1045,7 +1047,7 @@ static Collection *collection_parent_editable_find_recursive(const ViewLayer *vi return NULL; } - LISTBASE_FOREACH (CollectionParent *, collection_parent, &collection->parents) { + LISTBASE_FOREACH (CollectionParent *, collection_parent, &collection->runtime.parents) { if (!ID_IS_LINKED(collection_parent->collection) && !ID_IS_OVERRIDE_LIBRARY(collection_parent->collection)) { if (view_layer != NULL && @@ -1344,9 +1346,9 @@ static void collection_null_children_remove(Collection *collection) static void collection_missing_parents_remove(Collection *collection) { - LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &collection->parents) { + LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &collection->runtime.parents) { if ((parent->collection == NULL) || !collection_find_child(parent->collection, collection)) { - BLI_freelinkN(&collection->parents, parent); + BLI_freelinkN(&collection->runtime.parents, parent); } } } @@ -1380,11 +1382,11 @@ void BKE_collections_child_remove_nulls(Main *bmain, } } else { - LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &child_collection->parents) { + LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &child_collection->runtime.parents) { collection_null_children_remove(parent->collection); if (!collection_find_child(parent->collection, child_collection)) { - BLI_freelinkN(&child_collection->parents, parent); + BLI_freelinkN(&child_collection->runtime.parents, parent); } } } @@ -1420,7 +1422,7 @@ bool BKE_collection_is_in_scene(Collection *collection) return true; } - LISTBASE_FOREACH (CollectionParent *, cparent, &collection->parents) { + LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime.parents) { if (BKE_collection_is_in_scene(cparent->collection)) { return true; } @@ -1474,7 +1476,7 @@ bool BKE_collection_cycle_find(Collection *new_ancestor, Collection *collection) collection = new_ancestor; } - LISTBASE_FOREACH (CollectionParent *, parent, &new_ancestor->parents) { + LISTBASE_FOREACH (CollectionParent *, parent, &new_ancestor->runtime.parents) { if (BKE_collection_cycle_find(parent->collection, collection)) { return true; } @@ -1514,7 +1516,7 @@ static bool collection_cycle_fix_recursive(Main *bmain, { bool cycles_found = false; - LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &parent_collection->parents) { + LISTBASE_FOREACH_MUTABLE (CollectionParent *, parent, &parent_collection->runtime.parents) { if (BKE_collection_cycle_find(parent->collection, collection)) { BKE_collection_child_remove(bmain, parent->collection, parent_collection); cycles_found = true; @@ -1560,7 +1562,7 @@ bool BKE_collection_has_collection(const Collection *parent, const Collection *c static CollectionParent *collection_find_parent(Collection *child, Collection *collection) { - return BLI_findptr(&child->parents, collection, offsetof(CollectionParent, collection)); + return BLI_findptr(&child->runtime.parents, collection, offsetof(CollectionParent, collection)); } static bool collection_child_add(Collection *parent, @@ -1584,7 +1586,7 @@ static bool collection_child_add(Collection *parent, if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) { CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), "CollectionParent"); cparent->collection = parent; - BLI_addtail(&collection->parents, cparent); + BLI_addtail(&collection->runtime.parents, cparent); } if (add_us) { @@ -1604,7 +1606,7 @@ static bool collection_child_remove(Collection *parent, Collection *collection) } CollectionParent *cparent = collection_find_parent(collection, parent); - BLI_freelinkN(&collection->parents, cparent); + BLI_freelinkN(&collection->runtime.parents, cparent); BLI_freelinkN(&parent->children, child); id_us_min(&collection->id); @@ -1664,19 +1666,19 @@ void BKE_collection_parent_relations_rebuild(Collection *collection) BLI_assert(collection_find_parent(child->collection, collection) == NULL); CollectionParent *cparent = MEM_callocN(sizeof(CollectionParent), __func__); cparent->collection = collection; - BLI_addtail(&child->collection->parents, cparent); + BLI_addtail(&child->collection->runtime.parents, cparent); } } static void collection_parents_rebuild_recursive(Collection *collection) { /* A same collection may be child of several others, no need to process it more than once. */ - if ((collection->tag & COLLECTION_TAG_RELATION_REBUILD) == 0) { + if ((collection->runtime.tag & COLLECTION_TAG_RELATION_REBUILD) == 0) { return; } BKE_collection_parent_relations_rebuild(collection); - collection->tag &= ~COLLECTION_TAG_RELATION_REBUILD; + collection->runtime.tag &= ~COLLECTION_TAG_RELATION_REBUILD; LISTBASE_FOREACH (CollectionChild *, child, &collection->children) { /* See comment above in `BKE_collection_parent_relations_rebuild`. */ @@ -1691,9 +1693,9 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain) { /* Only collections not in bmain (master ones in scenes) have no parent... */ LISTBASE_FOREACH (Collection *, collection, &bmain->collections) { - BLI_freelistN(&collection->parents); + BLI_freelistN(&collection->runtime.parents); - collection->tag |= COLLECTION_TAG_RELATION_REBUILD; + collection->runtime.tag |= COLLECTION_TAG_RELATION_REBUILD; } /* Scene's master collections will be 'root' parent of most of our collections, so start with @@ -1702,8 +1704,8 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain) /* This function can be called from readfile.c, when this pointer is not guaranteed to be NULL. */ if (scene->master_collection != NULL) { - BLI_assert(BLI_listbase_is_empty(&scene->master_collection->parents)); - scene->master_collection->tag |= COLLECTION_TAG_RELATION_REBUILD; + BLI_assert(BLI_listbase_is_empty(&scene->master_collection->runtime.parents)); + scene->master_collection->runtime.tag |= COLLECTION_TAG_RELATION_REBUILD; collection_parents_rebuild_recursive(scene->master_collection); } } @@ -1711,7 +1713,7 @@ void BKE_main_collections_parent_relations_rebuild(Main *bmain) /* We may have parent chains outside of scene's master_collection context? At least, readfile's * lib_link_collection_data() seems to assume that, so do the same here. */ LISTBASE_FOREACH (Collection *, collection, &bmain->collections) { - if (collection->tag & COLLECTION_TAG_RELATION_REBUILD) { + if (collection->runtime.tag & COLLECTION_TAG_RELATION_REBUILD) { /* NOTE: we do not have easy access to 'which collections is root' info in that case, which * means test for cycles in collection relationships may fail here. I don't think that is an * issue in practice here, but worth keeping in mind... */ diff --git a/source/blender/blenkernel/intern/layer.cc b/source/blender/blenkernel/intern/layer.cc index 95c341212d1..40b80ddbd10 100644 --- a/source/blender/blenkernel/intern/layer.cc +++ b/source/blender/blenkernel/intern/layer.cc @@ -626,7 +626,8 @@ static bool layer_collection_hidden(ViewLayer *view_layer, LayerCollection *lc) } /* Restriction flags stay set, so we need to check parents */ - CollectionParent *parent = static_cast(lc->collection->parents.first); + CollectionParent *parent = static_cast( + lc->collection->runtime.parents.first); if (parent) { lc = BKE_layer_collection_first_from_scene_collection(view_layer, parent->collection); @@ -662,7 +663,8 @@ bool BKE_layer_collection_activate(ViewLayer *view_layer, LayerCollection *lc) LayerCollection *BKE_layer_collection_activate_parent(ViewLayer *view_layer, LayerCollection *lc) { - CollectionParent *parent = static_cast(lc->collection->parents.first); + CollectionParent *parent = static_cast( + lc->collection->runtime.parents.first); if (parent) { lc = BKE_layer_collection_first_from_scene_collection(view_layer, parent->collection); diff --git a/source/blender/blenkernel/intern/scene.cc b/source/blender/blenkernel/intern/scene.cc index 124de007ade..cdffbcea527 100644 --- a/source/blender/blenkernel/intern/scene.cc +++ b/source/blender/blenkernel/intern/scene.cc @@ -277,7 +277,7 @@ static void scene_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int (ID *)scene_src->master_collection, (ID **)&scene_dst->master_collection, flag_private_id_data); - scene_dst->master_collection->owner_id = &scene_dst->id; + scene_dst->master_collection->runtime.owner_id = &scene_dst->id; } /* View Layers */ diff --git a/source/blender/editors/interface/interface_templates.cc b/source/blender/editors/interface/interface_templates.cc index 4a0999e26df..91c8911b97d 100644 --- a/source/blender/editors/interface/interface_templates.cc +++ b/source/blender/editors/interface/interface_templates.cc @@ -609,7 +609,7 @@ static void template_id_liboverride_hierarchy_collection_root_find_recursive( *r_collection_parent_best = collection; } } - for (CollectionParent *iter = static_cast(collection->parents.first); + for (CollectionParent *iter = static_cast(collection->runtime.parents.first); iter != nullptr; iter = iter->next) { if (iter->collection->id.lib != collection->id.lib && ID_IS_LINKED(iter->collection)) { @@ -628,7 +628,8 @@ static void template_id_liboverride_hierarchy_collections_tag_recursive( /* Tag all local parents of the root collection, so that usages of the root collection and other * linked ones can be replaced by the local overrides in those parents too. */ if (do_parents) { - for (CollectionParent *iter = static_cast(root_collection->parents.first); + for (CollectionParent *iter = + static_cast(root_collection->runtime.parents.first); iter != nullptr; iter = iter->next) { if (ID_IS_LINKED(iter->collection)) { diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 10068def991..5315e89c62d 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2435,7 +2435,7 @@ static int make_override_library_exec(bContext *C, wmOperator *op) case ID_GR: { Collection *collection_root = (Collection *)id_root; LISTBASE_FOREACH_MUTABLE ( - CollectionParent *, collection_parent, &collection_root->parents) { + CollectionParent *, collection_parent, &collection_root->runtime.parents) { if (ID_IS_LINKED(collection_parent->collection) || !BKE_view_layer_has_collection(view_layer, collection_parent->collection)) { continue; diff --git a/source/blender/editors/space_outliner/outliner_collections.cc b/source/blender/editors/space_outliner/outliner_collections.cc index 7eceb9c11b9..9a557627abb 100644 --- a/source/blender/editors/space_outliner/outliner_collections.cc +++ b/source/blender/editors/space_outliner/outliner_collections.cc @@ -368,7 +368,7 @@ void outliner_collection_delete( skip = true; } else { - LISTBASE_FOREACH (CollectionParent *, cparent, &collection->parents) { + LISTBASE_FOREACH (CollectionParent *, cparent, &collection->runtime.parents) { Collection *parent = cparent->collection; if (ID_IS_LINKED(parent) || ID_IS_OVERRIDE_LIBRARY(parent)) { skip = true; diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.cc b/source/blender/editors/space_outliner/outliner_dragdrop.cc index 3b07c6da5fa..4be4233b24b 100644 --- a/source/blender/editors/space_outliner/outliner_dragdrop.cc +++ b/source/blender/editors/space_outliner/outliner_dragdrop.cc @@ -1235,7 +1235,7 @@ static char *collection_drop_tooltip(bContext *C, /* Test if we are moving within same parent collection. */ bool same_level = false; - LISTBASE_FOREACH (CollectionParent *, parent, &data.to->parents) { + LISTBASE_FOREACH (CollectionParent *, parent, &data.to->runtime.parents) { if (data.from == parent->collection) { same_level = true; } diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc index df96d530abf..7b9f830a248 100644 --- a/source/blender/editors/space_outliner/outliner_draw.cc +++ b/source/blender/editors/space_outliner/outliner_draw.cc @@ -560,7 +560,7 @@ void outliner_collection_isolate_flag(Scene *scene, else { CollectionParent *parent; Collection *child = collection; - while ((parent = static_cast(child->parents.first))) { + while ((parent = static_cast(child->runtime.parents.first))) { if (parent->collection->flag & COLLECTION_IS_MASTER) { break; } diff --git a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc index 405f1dd73f4..16258899f2e 100644 --- a/source/blender/editors/space_outliner/tree/tree_display_libraries.cc +++ b/source/blender/editors/space_outliner/tree/tree_display_libraries.cc @@ -189,7 +189,7 @@ bool TreeDisplayLibraries::library_id_filter_poll(const Library *lib, ID *id) co Collection *collection = (Collection *)id; bool has_non_scene_parent = false; - for (CollectionParent *cparent : List(collection->parents)) { + for (CollectionParent *cparent : List(collection->runtime.parents)) { if (!(cparent->collection->flag & COLLECTION_IS_MASTER)) { has_non_scene_parent = true; } diff --git a/source/blender/makesdna/DNA_collection_types.h b/source/blender/makesdna/DNA_collection_types.h index 75bfc2575a5..d97d3d17182 100644 --- a/source/blender/makesdna/DNA_collection_types.h +++ b/source/blender/makesdna/DNA_collection_types.h @@ -44,12 +44,31 @@ enum eCollectionLineArt_Flags { COLLECTION_LRT_USE_INTERSECTION_PRIORITY = (1 << 1), }; +typedef struct Collection_Runtime { + /** The ID owning this collection, in case it is an embedded one. */ + ID *owner_id; + + /** + * Cache of objects in this collection and all its children. + * This is created on demand when e.g. some physics simulation needs it, + * we don't want to have it for every collections due to memory usage reasons. + */ + ListBase object_cache; + + /** Need this for line art sub-collection selections. */ + ListBase object_cache_instanced; + + /** List of collections that are a parent of this data-block. */ + ListBase parents; + + uint8_t tag; + + char _pad0[7]; +} Collection_Runtime; + typedef struct Collection { ID id; - /** The ID owning this node tree, in case it is an embedded one. */ - ID *owner_id; - /** CollectionObject. */ ListBase gobject; /** CollectionChild. */ @@ -60,56 +79,51 @@ typedef struct Collection { unsigned int layer DNA_DEPRECATED; float instance_offset[3]; - short flag; - /* Runtime-only, always cleared on file load. */ - short tag; + uint8_t flag; + int8_t color_tag; - short lineart_usage; /* eCollectionLineArt_Usage */ - unsigned char lineart_flags; /* eCollectionLineArt_Flags */ - unsigned char lineart_intersection_mask; - unsigned char lineart_intersection_priority; - char _pad[5]; + char _pad0[2]; - int16_t color_tag; + uint8_t lineart_usage; /* #eCollectionLineArt_Usage */ + uint8_t lineart_flags; /* #eCollectionLineArt_Flags */ + uint8_t lineart_intersection_mask; + uint8_t lineart_intersection_priority; - /* Runtime. Cache of objects in this collection and all its - * children. This is created on demand when e.g. some physics - * simulation needs it, we don't want to have it for every - * collections due to memory usage reasons. */ - ListBase object_cache; - - /* Need this for line art sub-collection selections. */ - ListBase object_cache_instanced; - - /* Runtime. List of collections that are a parent of this - * datablock. */ - ListBase parents; - - /* Deprecated */ struct SceneCollection *collection DNA_DEPRECATED; struct ViewLayer *view_layer DNA_DEPRECATED; + + /* Keep last. */ + Collection_Runtime runtime; } Collection; -/* Collection->flag */ +/** #Collection.flag */ enum { - COLLECTION_HIDE_VIEWPORT = (1 << 0), /* Disable in viewports. */ - COLLECTION_HIDE_SELECT = (1 << 1), /* Not selectable in viewport. */ - /* COLLECTION_DISABLED_DEPRECATED = (1 << 2), */ /* Not used anymore */ - COLLECTION_HIDE_RENDER = (1 << 3), /* Disable in renders. */ - COLLECTION_HAS_OBJECT_CACHE = (1 << 4), /* Runtime: object_cache is populated. */ - COLLECTION_IS_MASTER = (1 << 5), /* Is master collection embedded in the scene. */ - COLLECTION_HAS_OBJECT_CACHE_INSTANCED = (1 << 6), /* for object_cache_instanced. */ + /** Disable in viewports. */ + COLLECTION_HIDE_VIEWPORT = (1 << 0), + /** Not selectable in viewport. */ + COLLECTION_HIDE_SELECT = (1 << 1), + // COLLECTION_DISABLED_DEPRECATED = (1 << 2), /* DIRTY */ + /** Disable in renders. */ + COLLECTION_HIDE_RENDER = (1 << 3), + /** Runtime: object_cache is populated. */ + COLLECTION_HAS_OBJECT_CACHE = (1 << 4), + /** Is master collection embedded in the scene. */ + COLLECTION_IS_MASTER = (1 << 5), + /** for object_cache_instanced. */ + COLLECTION_HAS_OBJECT_CACHE_INSTANCED = (1 << 6), }; -/* Collection->tag */ +/** #Collection_Runtime.tag */ enum { - /* That code (BKE_main_collections_parent_relations_rebuild and the like) + /** + * That code (#BKE_main_collections_parent_relations_rebuild and the like) * is called from very low-level places, like e.g ID remapping... - * Using a generic tag like LIB_TAG_DOIT for this is just impossible, we need our very own. */ + * Using a generic tag like #LIB_TAG_DOIT for this is just impossible, we need our very own. + */ COLLECTION_TAG_RELATION_REBUILD = (1 << 0), }; -/* Collection->color_tag. */ +/** #Collection.color_tag */ typedef enum CollectionColorTag { COLLECTION_COLOR_NONE = -1, COLLECTION_COLOR_01, diff --git a/source/blender/makesrna/intern/rna_collection.c b/source/blender/makesrna/intern/rna_collection.c index 833495dce7a..4fbefb68d6b 100644 --- a/source/blender/makesrna/intern/rna_collection.c +++ b/source/blender/makesrna/intern/rna_collection.c @@ -31,6 +31,9 @@ const EnumPropertyItem rna_enum_collection_color_items[] = { {COLLECTION_COLOR_08, "COLOR_08", ICON_COLLECTION_COLOR_08, "Color 08", ""}, {0, NULL, 0, NULL, NULL}, }; +/* Minus 1 for NONE & 1 for the NULL sentinel. */ +BLI_STATIC_ASSERT(ARRAY_SIZE(rna_enum_collection_color_items) - 2 == COLLECTION_COLOR_TOT, + "Collection color total is an invalid size"); #ifdef RNA_RUNTIME From fd2bf32dc7d15d34dc1b99dae1a8605f25db1951 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 18 Jan 2023 14:10:29 +1100 Subject: [PATCH 0722/1522] Cleanup: use memset instead of clearing individual runtime members --- source/blender/blenkernel/intern/collection.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 1ca870bd397..621d8e5df8e 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -209,10 +209,8 @@ static void collection_blend_write(BlendWriter *writer, ID *id, const void *id_a /* Clean up, important in undo case to reduce false detection of changed data-blocks. */ collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED; - collection->runtime.tag = 0; - BLI_listbase_clear(&collection->runtime.object_cache); - BLI_listbase_clear(&collection->runtime.object_cache_instanced); - BLI_listbase_clear(&collection->runtime.parents); + + memset(&collection->runtime, 0, sizeof(collection->runtime)); /* write LibData */ BLO_write_id_struct(writer, Collection, id_address, &collection->id); @@ -259,6 +257,8 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect } collection->id.flag |= LIB_EMBEDDED_DATA; } + + memset(&collection->runtime, 0, sizeof(collection->runtime)); collection->runtime.owner_id = owner_id; BLO_read_list(reader, &collection->gobject); @@ -269,10 +269,6 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED; - collection->runtime.tag = 0; - BLI_listbase_clear(&collection->runtime.object_cache); - BLI_listbase_clear(&collection->runtime.object_cache_instanced); - BLI_listbase_clear(&collection->runtime.parents); #ifdef USE_COLLECTION_COMPAT_28 /* This runs before the very first doversion. */ From b380d25053801670502d3d1a7f9e9ff4eeb44811 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 18 Jan 2023 14:16:36 +1100 Subject: [PATCH 0723/1522] Cleanup: define COLLECTION_FLAG_ALL_RUNTIME, use in file read/write --- source/blender/blenkernel/intern/collection.c | 17 ++++++----------- source/blender/makesdna/DNA_collection_types.h | 3 +++ 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index 621d8e5df8e..de785ddd38d 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -112,8 +112,7 @@ static void collection_copy_data(Main *bmain, ID *id_dst, const ID *id_src, cons collection_dst->preview = NULL; } - collection_dst->flag &= ~COLLECTION_HAS_OBJECT_CACHE; - collection_dst->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED; + collection_dst->flag &= ~(COLLECTION_HAS_OBJECT_CACHE | COLLECTION_HAS_OBJECT_CACHE_INSTANCED); BLI_listbase_clear(&collection_dst->runtime.object_cache); BLI_listbase_clear(&collection_dst->runtime.object_cache_instanced); @@ -206,11 +205,9 @@ static void collection_blend_write(BlendWriter *writer, ID *id, const void *id_a { Collection *collection = (Collection *)id; - /* Clean up, important in undo case to reduce false detection of changed data-blocks. */ - collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; - collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED; - memset(&collection->runtime, 0, sizeof(collection->runtime)); + /* Clean up, important in undo case to reduce false detection of changed data-blocks. */ + collection->flag &= ~COLLECTION_FLAG_ALL_RUNTIME; /* write LibData */ BLO_write_id_struct(writer, Collection, id_address, &collection->id); @@ -259,6 +256,8 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect } memset(&collection->runtime, 0, sizeof(collection->runtime)); + collection->flag &= ~COLLECTION_FLAG_ALL_RUNTIME; + collection->runtime.owner_id = owner_id; BLO_read_list(reader, &collection->gobject); @@ -267,9 +266,6 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect BLO_read_data_address(reader, &collection->preview); BKE_previewimg_blend_read(reader, collection->preview); - collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; - collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED; - #ifdef USE_COLLECTION_COMPAT_28 /* This runs before the very first doversion. */ BLO_read_data_address(reader, &collection->collection); @@ -842,8 +838,7 @@ ListBase BKE_collection_object_cache_instanced_get(Collection *collection) static void collection_object_cache_free(Collection *collection) { /* Clear own cache an for all parents, since those are affected by changes as well. */ - collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE; - collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE_INSTANCED; + collection->flag &= ~(COLLECTION_HAS_OBJECT_CACHE | COLLECTION_HAS_OBJECT_CACHE_INSTANCED); BLI_freelistN(&collection->runtime.object_cache); BLI_freelistN(&collection->runtime.object_cache_instanced); diff --git a/source/blender/makesdna/DNA_collection_types.h b/source/blender/makesdna/DNA_collection_types.h index d97d3d17182..8ec6626f4b3 100644 --- a/source/blender/makesdna/DNA_collection_types.h +++ b/source/blender/makesdna/DNA_collection_types.h @@ -113,6 +113,9 @@ enum { COLLECTION_HAS_OBJECT_CACHE_INSTANCED = (1 << 6), }; +#define COLLECTION_FLAG_ALL_RUNTIME \ + (COLLECTION_HAS_OBJECT_CACHE | COLLECTION_HAS_OBJECT_CACHE_INSTANCED) + /** #Collection_Runtime.tag */ enum { /** From 1c470dbd7219a0edc2c06323b8144f9a22c50b72 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 18 Jan 2023 15:43:20 +1100 Subject: [PATCH 0724/1522] Cleanup: replace BLI_findptr with BKE_collection_has_object Also swap the order of checks in collection_object_add to perform the comparison before calling collection_find_child_recursive. --- source/blender/blenkernel/intern/collection.c | 4 ++-- source/blender/editors/object/object_edit.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/collection.c b/source/blender/blenkernel/intern/collection.c index de785ddd38d..8b430546644 100644 --- a/source/blender/blenkernel/intern/collection.c +++ b/source/blender/blenkernel/intern/collection.c @@ -1064,8 +1064,8 @@ static bool collection_object_add( { if (ob->instance_collection) { /* Cyclic dependency check. */ - if (collection_find_child_recursive(ob->instance_collection, collection) || - ob->instance_collection == collection) { + if ((ob->instance_collection == collection) || + collection_find_child_recursive(ob->instance_collection, collection)) { return false; } } diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index e9b176daf4a..b1cebc32513 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1876,8 +1876,7 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) Object *single_object = BLI_listbase_is_single(&objects) ? ((LinkData *)objects.first)->data : NULL; - if ((single_object != NULL) && is_link && - BLI_findptr(&collection->gobject, single_object, offsetof(CollectionObject, ob))) { + if ((single_object != NULL) && is_link && BKE_collection_has_object(collection, single_object)) { BKE_reportf(op->reports, RPT_ERROR, "%s already in %s", From 988bc3dddf741ee95d154e0049eb96fb48006c12 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 18 Jan 2023 17:17:29 +1100 Subject: [PATCH 0725/1522] Cleanup: keep dna_rename_defs sorted --- .../blender/makesdna/intern/dna_rename_defs.h | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h index dce7d353fe6..e5057755995 100644 --- a/source/blender/makesdna/intern/dna_rename_defs.h +++ b/source/blender/makesdna/intern/dna_rename_defs.h @@ -84,33 +84,33 @@ DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, line_types, edge_types) DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_flags, mask_switches) DNA_STRUCT_RENAME_ELEM(LineartGpencilModifierData, transparency_mask, material_mask_bits) DNA_STRUCT_RENAME_ELEM(MDefCell, totinfluence, influences_num) +DNA_STRUCT_RENAME_ELEM(MEdge, bweight, bweight_legacy) +DNA_STRUCT_RENAME_ELEM(MEdge, crease, crease_legacy) +DNA_STRUCT_RENAME_ELEM(MPoly, mat_nr, mat_nr_legacy) +DNA_STRUCT_RENAME_ELEM(MVert, bweight, bweight_legacy) +DNA_STRUCT_RENAME_ELEM(MVert, co, co_legacy) +DNA_STRUCT_RENAME_ELEM(MVert, flag, flag_legacy) DNA_STRUCT_RENAME_ELEM(MaskLayer, restrictflag, visibility_flag) DNA_STRUCT_RENAME_ELEM(MaterialLineArt, transparency_mask, material_mask_bits) DNA_STRUCT_RENAME_ELEM(MeshDeformModifierData, totcagevert, cage_verts_num) DNA_STRUCT_RENAME_ELEM(MeshDeformModifierData, totinfluence, influences_num) DNA_STRUCT_RENAME_ELEM(MeshDeformModifierData, totvert, verts_num) DNA_STRUCT_RENAME_ELEM(MovieClip, name, filepath) -DNA_STRUCT_RENAME_ELEM(MovieTracking, tracks, tracks_legacy) +DNA_STRUCT_RENAME_ELEM(MovieTracking, act_plane_track, act_plane_track_legacy) +DNA_STRUCT_RENAME_ELEM(MovieTracking, act_track, act_track_legacy) DNA_STRUCT_RENAME_ELEM(MovieTracking, plane_tracks, plane_tracks_legacy) DNA_STRUCT_RENAME_ELEM(MovieTracking, reconstruction, reconstruction_legacy) -DNA_STRUCT_RENAME_ELEM(MovieTracking, act_track, act_track_legacy) -DNA_STRUCT_RENAME_ELEM(MovieTracking, act_plane_track, act_plane_track_legacy) +DNA_STRUCT_RENAME_ELEM(MovieTracking, tracks, tracks_legacy) DNA_STRUCT_RENAME_ELEM(MovieTrackingCamera, principal, principal_legacy) DNA_STRUCT_RENAME_ELEM(NodeCryptomatte, num_inputs, inputs_num) DNA_STRUCT_RENAME_ELEM(Object, col, color) DNA_STRUCT_RENAME_ELEM(Object, dup_group, instance_collection) DNA_STRUCT_RENAME_ELEM(Object, dupfacesca, instance_faces_scale) +DNA_STRUCT_RENAME_ELEM(Object, imat, world_to_object) +DNA_STRUCT_RENAME_ELEM(Object, obmat, object_to_world) DNA_STRUCT_RENAME_ELEM(Object, restrictflag, visibility_flag) DNA_STRUCT_RENAME_ELEM(Object, size, scale) -DNA_STRUCT_RENAME_ELEM(Object, obmat, object_to_world) -DNA_STRUCT_RENAME_ELEM(Object, imat, world_to_object) DNA_STRUCT_RENAME_ELEM(Object_Runtime, crazyspace_num_verts, crazyspace_verts_num) -DNA_STRUCT_RENAME_ELEM(MEdge, bweight, bweight_legacy) -DNA_STRUCT_RENAME_ELEM(MEdge, crease, crease_legacy) -DNA_STRUCT_RENAME_ELEM(MPoly, mat_nr, mat_nr_legacy) -DNA_STRUCT_RENAME_ELEM(MVert, co, co_legacy) -DNA_STRUCT_RENAME_ELEM(MVert, bweight, bweight_legacy) -DNA_STRUCT_RENAME_ELEM(MVert, flag, flag_legacy) DNA_STRUCT_RENAME_ELEM(ParticleSettings, child_nbr, child_percent) DNA_STRUCT_RENAME_ELEM(ParticleSettings, dup_group, instance_collection) DNA_STRUCT_RENAME_ELEM(ParticleSettings, dup_ob, instance_object) From 07af7e2266676f2493b593d0c69e8668571dd0cf Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 18 Jan 2023 17:17:31 +1100 Subject: [PATCH 0726/1522] Cleanup: remove unused MetaBalle.disp & rot --- source/blender/blenkernel/intern/mball.cc | 5 ----- source/blender/makesdna/DNA_meta_types.h | 9 ++++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/mball.cc b/source/blender/blenkernel/intern/mball.cc index c1421db913d..c5025e51eb8 100644 --- a/source/blender/blenkernel/intern/mball.cc +++ b/source/blender/blenkernel/intern/mball.cc @@ -85,9 +85,6 @@ static void metaball_free_data(ID *id) MEM_SAFE_FREE(metaball->mat); BLI_freelistN(&metaball->elems); - if (metaball->disp.first) { - BKE_displist_free(&metaball->disp); - } } static void metaball_foreach_id(ID *id, LibraryForeachIDData *data) @@ -103,7 +100,6 @@ static void metaball_blend_write(BlendWriter *writer, ID *id, const void *id_add MetaBall *mb = (MetaBall *)id; /* Clean up, important in undo case to reduce false detection of changed datablocks. */ - BLI_listbase_clear(&mb->disp); mb->editelems = nullptr; /* Must always be cleared (meta's don't have their own edit-data). */ mb->needs_flush_to_id = 0; @@ -134,7 +130,6 @@ static void metaball_blend_read_data(BlendDataReader *reader, ID *id) BLO_read_list(reader, &(mb->elems)); - BLI_listbase_clear(&mb->disp); mb->editelems = nullptr; /* Must always be cleared (meta's don't have their own edit-data). */ mb->needs_flush_to_id = 0; diff --git a/source/blender/makesdna/DNA_meta_types.h b/source/blender/makesdna/DNA_meta_types.h index b4a66a46efe..5650fe91696 100644 --- a/source/blender/makesdna/DNA_meta_types.h +++ b/source/blender/makesdna/DNA_meta_types.h @@ -54,7 +54,6 @@ typedef struct MetaBall { struct AnimData *adt; ListBase elems; - ListBase disp; /** Not saved in files, note we use pointer for editmode check. */ ListBase *editelems; /** Old animation system, deprecated for 2.5. */ @@ -76,10 +75,8 @@ typedef struct MetaBall { */ char needs_flush_to_id; - /* texture space, copied as one block in editobject.c */ float loc[3]; float size[3]; - float rot[3]; /** Display and render res. */ float wiresize, rendersize; @@ -89,9 +86,11 @@ typedef struct MetaBall { * but these may also have their own thresh as an offset */ float thresh; - /* used in editmode */ - // ListBase edit_elems; + char _pad0[4]; + + /** The active meta-element (used in edit-mode). */ MetaElem *lastelem; + } MetaBall; /* **************** METABALL ********************* */ From 9e5e2aa775a9d7082ee2a1da8468cd5f46760caa Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 18 Jan 2023 17:17:32 +1100 Subject: [PATCH 0727/1522] Cleanup: rename Mesh/Curve/MetaBall loc/size/texflag Struct members loc/size were misleading as they read as if the object data stored object level transform channels. Rename these to match RNA with a `texspace_*` prefix to make it clear these struct members only apply to texture-space transform. Also rename ME_AUTOSPACE & ME_AUTOSPACE_EVALUATED to ME_TEXSPACE_FLAG_AUTO & ME_TEXSPACE_FLAG_AUTO_EVALUATED. --- source/blender/blenkernel/BKE_mesh.h | 10 +- source/blender/blenkernel/BKE_object.h | 6 +- source/blender/blenkernel/intern/curve.cc | 43 ++++---- source/blender/blenkernel/intern/mesh.cc | 100 +++++++++--------- .../blender/blenkernel/intern/mesh_convert.cc | 6 +- source/blender/blenkernel/intern/object.cc | 33 +++--- source/blender/blenkernel/intern/particle.cc | 14 +-- .../draw/engines/overlay/overlay_extra.cc | 8 +- .../blender/draw/intern/draw_manager_data.cc | 33 +++--- source/blender/draw/intern/draw_resource.hh | 8 +- source/blender/editors/curve/editcurve.c | 28 ++--- .../transform_convert_object_texspace.c | 6 +- source/blender/makesdna/DNA_curve_defaults.h | 4 +- source/blender/makesdna/DNA_curve_types.h | 13 ++- source/blender/makesdna/DNA_mesh_defaults.h | 4 +- source/blender/makesdna/DNA_mesh_types.h | 12 +-- source/blender/makesdna/DNA_meta_defaults.h | 4 +- source/blender/makesdna/DNA_meta_types.h | 14 +-- .../blender/makesdna/intern/dna_rename_defs.h | 9 ++ source/blender/makesrna/intern/rna_curve.c | 20 ++-- source/blender/makesrna/intern/rna_mesh.c | 26 ++--- source/blender/makesrna/intern/rna_meta.c | 18 ++-- 22 files changed, 221 insertions(+), 198 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index ad964184263..dc595ff0ce1 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -247,11 +247,13 @@ struct BoundBox *BKE_mesh_boundbox_get(struct Object *ob); void BKE_mesh_texspace_calc(struct Mesh *me); void BKE_mesh_texspace_ensure(struct Mesh *me); -void BKE_mesh_texspace_get(struct Mesh *me, float r_loc[3], float r_size[3]); +void BKE_mesh_texspace_get(struct Mesh *me, + float r_texspace_location[3], + float r_texspace_size[3]); void BKE_mesh_texspace_get_reference(struct Mesh *me, - char **r_texflag, - float **r_loc, - float **r_size); + char **r_texspace_flag, + float **r_texspace_location, + float **r_texspace_size); void BKE_mesh_texspace_copy_from_object(struct Mesh *me, struct Object *ob); /** diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index cfad8c5cfdb..963b0b87118 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -507,9 +507,9 @@ void BKE_object_handle_update_ex(struct Depsgraph *depsgraph, void BKE_object_sculpt_data_create(struct Object *ob); bool BKE_object_obdata_texspace_get(struct Object *ob, - char **r_texflag, - float **r_loc, - float **r_size); + char **r_texspace_flag, + float **r_texspace_location, + float **r_texspace_size); struct Mesh *BKE_object_get_evaluated_mesh_no_subsurf(const struct Object *object); /** Get evaluated mesh for given object. */ diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index be6c7502891..1ac0e27a4a3 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -258,7 +258,7 @@ static void curve_blend_read_data(BlendDataReader *reader, ID *id) switch_endian_knots(nu); } } - cu->texflag &= ~CU_AUTOSPACE_EVALUATED; + cu->texspace_flag &= ~CU_TEXSPACE_FLAG_AUTO_EVALUATED; BLO_read_data_address(reader, &cu->bevel_profile); if (cu->bevel_profile != nullptr) { @@ -517,7 +517,7 @@ BoundBox *BKE_curve_boundbox_get(Object *ob) void BKE_curve_texspace_calc(Curve *cu) { - if (cu->texflag & CU_AUTOSPACE) { + if (cu->texspace_flag & CU_TEXSPACE_FLAG_AUTO) { float min[3], max[3]; INIT_MINMAX(min, max); @@ -526,35 +526,36 @@ void BKE_curve_texspace_calc(Curve *cu) max[0] = max[1] = max[2] = 1.0f; } - float loc[3], size[3]; - mid_v3_v3v3(loc, min, max); + float texspace_location[3], texspace_size[3]; + mid_v3_v3v3(texspace_location, min, max); - size[0] = (max[0] - min[0]) / 2.0f; - size[1] = (max[1] - min[1]) / 2.0f; - size[2] = (max[2] - min[2]) / 2.0f; + texspace_size[0] = (max[0] - min[0]) / 2.0f; + texspace_size[1] = (max[1] - min[1]) / 2.0f; + texspace_size[2] = (max[2] - min[2]) / 2.0f; for (int a = 0; a < 3; a++) { - if (size[a] == 0.0f) { - size[a] = 1.0f; + if (texspace_size[a] == 0.0f) { + texspace_size[a] = 1.0f; } - else if (size[a] > 0.0f && size[a] < 0.00001f) { - size[a] = 0.00001f; + else if (texspace_size[a] > 0.0f && texspace_size[a] < 0.00001f) { + texspace_size[a] = 0.00001f; } - else if (size[a] < 0.0f && size[a] > -0.00001f) { - size[a] = -0.00001f; + else if (texspace_size[a] < 0.0f && texspace_size[a] > -0.00001f) { + texspace_size[a] = -0.00001f; } } - copy_v3_v3(cu->loc, loc); - copy_v3_v3(cu->size, size); + copy_v3_v3(cu->texspace_location, texspace_location); + copy_v3_v3(cu->texspace_size, texspace_size); - cu->texflag |= CU_AUTOSPACE_EVALUATED; + cu->texspace_flag |= CU_TEXSPACE_FLAG_AUTO_EVALUATED; } } void BKE_curve_texspace_ensure(Curve *cu) { - if ((cu->texflag & CU_AUTOSPACE) && !(cu->texflag & CU_AUTOSPACE_EVALUATED)) { + if ((cu->texspace_flag & CU_TEXSPACE_FLAG_AUTO) && + (cu->texspace_flag & CU_TEXSPACE_FLAG_AUTO_EVALUATED) == 0) { BKE_curve_texspace_calc(cu); } } @@ -5508,10 +5509,10 @@ void BKE_curve_eval_geometry(Depsgraph *depsgraph, Curve *curve) BKE_curve_texspace_calc(curve); if (DEG_is_active(depsgraph)) { Curve *curve_orig = (Curve *)DEG_get_original_id(&curve->id); - if (curve->texflag & CU_AUTOSPACE_EVALUATED) { - curve_orig->texflag |= CU_AUTOSPACE_EVALUATED; - copy_v3_v3(curve_orig->loc, curve->loc); - copy_v3_v3(curve_orig->size, curve->size); + if (curve->texspace_flag & CU_TEXSPACE_FLAG_AUTO_EVALUATED) { + curve_orig->texspace_flag |= CU_TEXSPACE_FLAG_AUTO_EVALUATED; + copy_v3_v3(curve_orig->texspace_location, curve->texspace_location); + copy_v3_v3(curve_orig->texspace_size, curve->texspace_size); } } } diff --git a/source/blender/blenkernel/intern/mesh.cc b/source/blender/blenkernel/intern/mesh.cc index 8ee01107c84..71275444028 100644 --- a/source/blender/blenkernel/intern/mesh.cc +++ b/source/blender/blenkernel/intern/mesh.cc @@ -360,7 +360,7 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id) BLO_read_data_address(reader, &mesh->active_color_attribute); BLO_read_data_address(reader, &mesh->default_color_attribute); - mesh->texflag &= ~ME_AUTOSPACE_EVALUATED; + mesh->texspace_flag &= ~ME_TEXSPACE_FLAG_AUTO_EVALUATED; mesh->edit_mesh = nullptr; mesh->runtime = new blender::bke::MeshRuntime(); @@ -1029,9 +1029,9 @@ void BKE_mesh_copy_parameters(Mesh *me_dst, const Mesh *me_src) me_dst->face_sets_color_default = me_src->face_sets_color_default; /* Copy texture space. */ - me_dst->texflag = me_src->texflag; - copy_v3_v3(me_dst->loc, me_src->loc); - copy_v3_v3(me_dst->size, me_src->size); + me_dst->texspace_flag = me_src->texspace_flag; + copy_v3_v3(me_dst->texspace_location, me_src->texspace_location); + copy_v3_v3(me_dst->texspace_size, me_src->texspace_size); me_dst->vertex_group_active_index = me_src->vertex_group_active_index; me_dst->attributes_active_index = me_src->attributes_active_index; @@ -1228,7 +1228,7 @@ BoundBox *BKE_mesh_boundbox_get(Object *ob) void BKE_mesh_texspace_calc(Mesh *me) { - if (me->texflag & ME_AUTOSPACE) { + if (me->texspace_flag & ME_TEXSPACE_FLAG_AUTO) { float min[3], max[3]; INIT_MINMAX(min, max); @@ -1237,75 +1237,79 @@ void BKE_mesh_texspace_calc(Mesh *me) max[0] = max[1] = max[2] = 1.0f; } - float loc[3], size[3]; - mid_v3_v3v3(loc, min, max); + float texspace_location[3], texspace_size[3]; + mid_v3_v3v3(texspace_location, min, max); - size[0] = (max[0] - min[0]) / 2.0f; - size[1] = (max[1] - min[1]) / 2.0f; - size[2] = (max[2] - min[2]) / 2.0f; + texspace_size[0] = (max[0] - min[0]) / 2.0f; + texspace_size[1] = (max[1] - min[1]) / 2.0f; + texspace_size[2] = (max[2] - min[2]) / 2.0f; for (int a = 0; a < 3; a++) { - if (size[a] == 0.0f) { - size[a] = 1.0f; + if (texspace_size[a] == 0.0f) { + texspace_size[a] = 1.0f; } - else if (size[a] > 0.0f && size[a] < 0.00001f) { - size[a] = 0.00001f; + else if (texspace_size[a] > 0.0f && texspace_size[a] < 0.00001f) { + texspace_size[a] = 0.00001f; } - else if (size[a] < 0.0f && size[a] > -0.00001f) { - size[a] = -0.00001f; + else if (texspace_size[a] < 0.0f && texspace_size[a] > -0.00001f) { + texspace_size[a] = -0.00001f; } } - copy_v3_v3(me->loc, loc); - copy_v3_v3(me->size, size); + copy_v3_v3(me->texspace_location, texspace_location); + copy_v3_v3(me->texspace_size, texspace_size); - me->texflag |= ME_AUTOSPACE_EVALUATED; + me->texspace_flag |= ME_TEXSPACE_FLAG_AUTO_EVALUATED; } } void BKE_mesh_texspace_ensure(Mesh *me) { - if ((me->texflag & ME_AUTOSPACE) && !(me->texflag & ME_AUTOSPACE_EVALUATED)) { + if ((me->texspace_flag & ME_TEXSPACE_FLAG_AUTO) && + !(me->texspace_flag & ME_TEXSPACE_FLAG_AUTO_EVALUATED)) { BKE_mesh_texspace_calc(me); } } -void BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_size[3]) +void BKE_mesh_texspace_get(Mesh *me, float r_texspace_location[3], float r_texspace_size[3]) { BKE_mesh_texspace_ensure(me); - if (r_loc) { - copy_v3_v3(r_loc, me->loc); + if (r_texspace_location) { + copy_v3_v3(r_texspace_location, me->texspace_location); } - if (r_size) { - copy_v3_v3(r_size, me->size); + if (r_texspace_size) { + copy_v3_v3(r_texspace_size, me->texspace_size); } } -void BKE_mesh_texspace_get_reference(Mesh *me, char **r_texflag, float **r_loc, float **r_size) +void BKE_mesh_texspace_get_reference(Mesh *me, + char **r_texspace_flag, + float **r_texspace_location, + float **r_texspace_size) { BKE_mesh_texspace_ensure(me); - if (r_texflag != nullptr) { - *r_texflag = &me->texflag; + if (r_texspace_flag != nullptr) { + *r_texspace_flag = &me->texspace_flag; } - if (r_loc != nullptr) { - *r_loc = me->loc; + if (r_texspace_location != nullptr) { + *r_texspace_location = me->texspace_location; } - if (r_size != nullptr) { - *r_size = me->size; + if (r_texspace_size != nullptr) { + *r_texspace_size = me->texspace_size; } } void BKE_mesh_texspace_copy_from_object(Mesh *me, Object *ob) { - float *texloc, *texsize; - char *texflag; + float *texspace_location, *texspace_size; + char *texspace_flag; - if (BKE_object_obdata_texspace_get(ob, &texflag, &texloc, &texsize)) { - me->texflag = *texflag; - copy_v3_v3(me->loc, texloc); - copy_v3_v3(me->size, texsize); + if (BKE_object_obdata_texspace_get(ob, &texspace_flag, &texspace_location, &texspace_size)) { + me->texspace_flag = *texspace_flag; + copy_v3_v3(me->texspace_location, texspace_location); + copy_v3_v3(me->texspace_size, texspace_size); } } @@ -1329,22 +1333,22 @@ float (*BKE_mesh_orco_verts_get(Object *ob))[3] void BKE_mesh_orco_verts_transform(Mesh *me, float (*orco)[3], int totvert, int invert) { - float loc[3], size[3]; + float texspace_location[3], texspace_size[3]; - BKE_mesh_texspace_get(me->texcomesh ? me->texcomesh : me, loc, size); + BKE_mesh_texspace_get(me->texcomesh ? me->texcomesh : me, texspace_location, texspace_size); if (invert) { for (int a = 0; a < totvert; a++) { float *co = orco[a]; - madd_v3_v3v3v3(co, loc, co, size); + madd_v3_v3v3v3(co, texspace_location, co, texspace_size); } } else { for (int a = 0; a < totvert; a++) { float *co = orco[a]; - co[0] = (co[0] - loc[0]) / size[0]; - co[1] = (co[1] - loc[1]) / size[1]; - co[2] = (co[2] - loc[2]) / size[2]; + co[0] = (co[0] - texspace_location[0]) / texspace_size[0]; + co[1] = (co[1] - texspace_location[1]) / texspace_size[1]; + co[2] = (co[2] - texspace_location[2]) / texspace_size[2]; } } } @@ -1889,10 +1893,10 @@ void BKE_mesh_eval_geometry(Depsgraph *depsgraph, Mesh *mesh) } if (DEG_is_active(depsgraph)) { Mesh *mesh_orig = (Mesh *)DEG_get_original_id(&mesh->id); - if (mesh->texflag & ME_AUTOSPACE_EVALUATED) { - mesh_orig->texflag |= ME_AUTOSPACE_EVALUATED; - copy_v3_v3(mesh_orig->loc, mesh->loc); - copy_v3_v3(mesh_orig->size, mesh->size); + if (mesh->texspace_flag & ME_TEXSPACE_FLAG_AUTO_EVALUATED) { + mesh_orig->texspace_flag |= ME_TEXSPACE_FLAG_AUTO_EVALUATED; + copy_v3_v3(mesh_orig->texspace_location, mesh->texspace_location); + copy_v3_v3(mesh_orig->texspace_size, mesh->texspace_size); } } } diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index 4f74f070e81..ffc3365b908 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -401,9 +401,9 @@ static Mesh *mesh_nurbs_displist_to_mesh(const Curve *cu, const ListBase *dispba */ static void mesh_copy_texture_space_from_curve_type(const Curve *cu, Mesh *me) { - me->texflag = cu->texflag & ~CU_AUTOSPACE; - copy_v3_v3(me->loc, cu->loc); - copy_v3_v3(me->size, cu->size); + me->texspace_flag = cu->texspace_flag & ~CU_TEXSPACE_FLAG_AUTO; + copy_v3_v3(me->texspace_location, cu->texspace_location); + copy_v3_v3(me->texspace_size, cu->texspace_size); BKE_mesh_texspace_calc(me); } diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index dfc2451d7fe..3534156c3fd 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -4360,42 +4360,45 @@ void BKE_object_sculpt_data_create(Object *ob) ob->sculpt->mode_type = (eObjectMode)ob->mode; } -bool BKE_object_obdata_texspace_get(Object *ob, char **r_texflag, float **r_loc, float **r_size) +bool BKE_object_obdata_texspace_get(Object *ob, + char **r_texspace_flag, + float **r_texspace_location, + float **r_texspace_size) { - if (ob->data == nullptr) { return false; } switch (GS(((ID *)ob->data)->name)) { case ID_ME: { - BKE_mesh_texspace_get_reference((Mesh *)ob->data, r_texflag, r_loc, r_size); + BKE_mesh_texspace_get_reference( + (Mesh *)ob->data, r_texspace_flag, r_texspace_location, r_texspace_size); break; } case ID_CU_LEGACY: { Curve *cu = (Curve *)ob->data; BKE_curve_texspace_ensure(cu); - if (r_texflag) { - *r_texflag = &cu->texflag; + if (r_texspace_flag) { + *r_texspace_flag = &cu->texspace_flag; } - if (r_loc) { - *r_loc = cu->loc; + if (r_texspace_location) { + *r_texspace_location = cu->texspace_location; } - if (r_size) { - *r_size = cu->size; + if (r_texspace_size) { + *r_texspace_size = cu->texspace_size; } break; } case ID_MB: { MetaBall *mb = (MetaBall *)ob->data; - if (r_texflag) { - *r_texflag = &mb->texflag; + if (r_texspace_flag) { + *r_texspace_flag = &mb->texspace_flag; } - if (r_loc) { - *r_loc = mb->loc; + if (r_texspace_location) { + *r_texspace_location = mb->texspace_location; } - if (r_size) { - *r_size = mb->size; + if (r_texspace_size) { + *r_texspace_size = mb->texspace_size; } break; } diff --git a/source/blender/blenkernel/intern/particle.cc b/source/blender/blenkernel/intern/particle.cc index 83b665239fc..296ef405da2 100644 --- a/source/blender/blenkernel/intern/particle.cc +++ b/source/blender/blenkernel/intern/particle.cc @@ -4451,15 +4451,15 @@ void psys_get_texture( texvec); BKE_mesh_texspace_ensure(me); - sub_v3_v3(texvec, me->loc); - if (me->size[0] != 0.0f) { - texvec[0] /= me->size[0]; + sub_v3_v3(texvec, me->texspace_location); + if (me->texspace_size[0] != 0.0f) { + texvec[0] /= me->texspace_size[0]; } - if (me->size[1] != 0.0f) { - texvec[1] /= me->size[1]; + if (me->texspace_size[1] != 0.0f) { + texvec[1] /= me->texspace_size[1]; } - if (me->size[2] != 0.0f) { - texvec[2] /= me->size[2]; + if (me->texspace_size[2] != 0.0f) { + texvec[2] /= me->texspace_size[2]; } break; case TEXCO_PARTICLE: diff --git a/source/blender/draw/engines/overlay/overlay_extra.cc b/source/blender/draw/engines/overlay/overlay_extra.cc index 9d46a0a274b..c366e64347c 100644 --- a/source/blender/draw/engines/overlay/overlay_extra.cc +++ b/source/blender/draw/engines/overlay/overlay_extra.cc @@ -460,14 +460,14 @@ static void OVERLAY_texture_space(OVERLAY_ExtraCallBuffers *cb, Object *ob, cons case ID_CU_LEGACY: { Curve *cu = (Curve *)ob_data; BKE_curve_texspace_ensure(cu); - texcoloc = cu->loc; - texcosize = cu->size; + texcoloc = cu->texspace_location; + texcosize = cu->texspace_size; break; } case ID_MB: { MetaBall *mb = (MetaBall *)ob_data; - texcoloc = mb->loc; - texcosize = mb->size; + texcoloc = mb->texspace_location; + texcosize = mb->texspace_size; break; } case ID_CV: diff --git a/source/blender/draw/intern/draw_manager_data.cc b/source/blender/draw/intern/draw_manager_data.cc index 5b4e0792577..4e6c5ae1a65 100644 --- a/source/blender/draw/intern/draw_manager_data.cc +++ b/source/blender/draw/intern/draw_manager_data.cc @@ -627,33 +627,36 @@ void DRW_shgroup_buffer_texture_ref(DRWShadingGroup *shgroup, static void drw_call_calc_orco(Object *ob, float (*r_orcofacs)[4]) { ID *ob_data = (ob) ? static_cast(ob->data) : nullptr; - float loc[3], size[3]; - float *texcoloc = nullptr; - float *texcosize = nullptr; + struct { + float texspace_location[3], texspace_size[3]; + } static_buf; + float *texspace_location = nullptr; + float *texspace_size = nullptr; if (ob_data != nullptr) { switch (GS(ob_data->name)) { case ID_VO: { BoundBox *bbox = BKE_volume_boundbox_get(ob); - mid_v3_v3v3(loc, bbox->vec[0], bbox->vec[6]); - sub_v3_v3v3(size, bbox->vec[0], bbox->vec[6]); - texcoloc = loc; - texcosize = size; + mid_v3_v3v3(static_buf.texspace_location, bbox->vec[0], bbox->vec[6]); + sub_v3_v3v3(static_buf.texspace_size, bbox->vec[0], bbox->vec[6]); + texspace_location = static_buf.texspace_location; + texspace_size = static_buf.texspace_size; break; } case ID_ME: - BKE_mesh_texspace_get_reference((Mesh *)ob_data, nullptr, &texcoloc, &texcosize); + BKE_mesh_texspace_get_reference( + (Mesh *)ob_data, nullptr, &texspace_location, &texspace_size); break; case ID_CU_LEGACY: { Curve *cu = (Curve *)ob_data; BKE_curve_texspace_ensure(cu); - texcoloc = cu->loc; - texcosize = cu->size; + texspace_location = cu->texspace_location; + texspace_size = cu->texspace_size; break; } case ID_MB: { MetaBall *mb = (MetaBall *)ob_data; - texcoloc = mb->loc; - texcosize = mb->size; + texspace_location = mb->texspace_location; + texspace_size = mb->texspace_size; break; } default: @@ -661,10 +664,10 @@ static void drw_call_calc_orco(Object *ob, float (*r_orcofacs)[4]) } } - if ((texcoloc != nullptr) && (texcosize != nullptr)) { - mul_v3_v3fl(r_orcofacs[1], texcosize, 2.0f); + if ((texspace_location != nullptr) && (texspace_size != nullptr)) { + mul_v3_v3fl(r_orcofacs[1], texspace_size, 2.0f); invert_v3(r_orcofacs[1]); - sub_v3_v3v3(r_orcofacs[0], texcoloc, texcosize); + sub_v3_v3v3(r_orcofacs[0], texspace_location, texspace_size); negate_v3(r_orcofacs[0]); mul_v3_v3(r_orcofacs[0], r_orcofacs[1]); /* result in a nice MADD in the shader */ } diff --git a/source/blender/draw/intern/draw_resource.hh b/source/blender/draw/intern/draw_resource.hh index 654caa878dd..f819cae320f 100644 --- a/source/blender/draw/intern/draw_resource.hh +++ b/source/blender/draw/intern/draw_resource.hh @@ -114,14 +114,14 @@ inline void ObjectInfos::sync(const blender::draw::ObjectRef ref, bool is_active case ID_CU_LEGACY: { Curve &cu = *static_cast(ref.object->data); BKE_curve_texspace_ensure(&cu); - orco_add = cu.loc; - orco_mul = cu.size; + orco_add = cu.texspace_location; + orco_mul = cu.texspace_size; break; } case ID_MB: { MetaBall &mb = *static_cast(ref.object->data); - orco_add = mb.loc; - orco_mul = mb.size; + orco_add = mb.texspace_location; + orco_mul = mb.texspace_size; break; } default: diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index f9377503630..f7107650f8c 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -7115,7 +7115,7 @@ static int match_texture_space_exec(bContext *C, wmOperator *UNUSED(op)) Object *object = CTX_data_active_object(C); Object *object_eval = DEG_get_evaluated_object(depsgraph, object); Curve *curve = (Curve *)object->data; - float min[3], max[3], size[3], loc[3]; + float min[3], max[3], texspace_size[3], texspace_location[3]; int a; BLI_assert(object_eval->runtime.curve_cache != NULL); @@ -7123,28 +7123,28 @@ static int match_texture_space_exec(bContext *C, wmOperator *UNUSED(op)) INIT_MINMAX(min, max); BKE_displist_minmax(&object_eval->runtime.curve_cache->disp, min, max); - mid_v3_v3v3(loc, min, max); + mid_v3_v3v3(texspace_location, min, max); - size[0] = (max[0] - min[0]) / 2.0f; - size[1] = (max[1] - min[1]) / 2.0f; - size[2] = (max[2] - min[2]) / 2.0f; + texspace_size[0] = (max[0] - min[0]) / 2.0f; + texspace_size[1] = (max[1] - min[1]) / 2.0f; + texspace_size[2] = (max[2] - min[2]) / 2.0f; for (a = 0; a < 3; a++) { - if (size[a] == 0.0f) { - size[a] = 1.0f; + if (texspace_size[a] == 0.0f) { + texspace_size[a] = 1.0f; } - else if (size[a] > 0.0f && size[a] < 0.00001f) { - size[a] = 0.00001f; + else if (texspace_size[a] > 0.0f && texspace_size[a] < 0.00001f) { + texspace_size[a] = 0.00001f; } - else if (size[a] < 0.0f && size[a] > -0.00001f) { - size[a] = -0.00001f; + else if (texspace_size[a] < 0.0f && texspace_size[a] > -0.00001f) { + texspace_size[a] = -0.00001f; } } - copy_v3_v3(curve->loc, loc); - copy_v3_v3(curve->size, size); + copy_v3_v3(curve->texspace_location, texspace_location); + copy_v3_v3(curve->texspace_size, texspace_size); - curve->texflag &= ~CU_AUTOSPACE; + curve->texspace_flag &= ~CU_TEXSPACE_FLAG_AUTO; WM_event_add_notifier(C, NC_GEOM | ND_DATA, curve); DEG_id_tag_update(&curve->id, ID_RECALC_GEOMETRY); diff --git a/source/blender/editors/transform/transform_convert_object_texspace.c b/source/blender/editors/transform/transform_convert_object_texspace.c index fb82f1645f5..2da379a6c69 100644 --- a/source/blender/editors/transform/transform_convert_object_texspace.c +++ b/source/blender/editors/transform/transform_convert_object_texspace.c @@ -36,7 +36,7 @@ static void createTransTexspace(bContext *UNUSED(C), TransInfo *t) TransData *td; Object *ob; ID *id; - char *texflag; + char *texspace_flag; BKE_view_layer_synced_ensure(t->scene, t->view_layer); ob = BKE_view_layer_active_object_get(view_layer); @@ -72,9 +72,9 @@ static void createTransTexspace(bContext *UNUSED(C), TransInfo *t) normalize_m3(td->axismtx); pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); - if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size)) { + if (BKE_object_obdata_texspace_get(ob, &texspace_flag, &td->loc, &td->ext->size)) { ob->dtx |= OB_TEXSPACE; - *texflag &= ~ME_AUTOSPACE; + *texspace_flag &= ~ME_TEXSPACE_FLAG_AUTO; } copy_v3_v3(td->iloc, td->loc); diff --git a/source/blender/makesdna/DNA_curve_defaults.h b/source/blender/makesdna/DNA_curve_defaults.h index 4d1b6a97791..57c06cbb9f7 100644 --- a/source/blender/makesdna/DNA_curve_defaults.h +++ b/source/blender/makesdna/DNA_curve_defaults.h @@ -15,7 +15,7 @@ #define _DNA_DEFAULT_Curve \ { \ - .size = {1, 1, 1}, \ + .texspace_size = {1, 1, 1}, \ .flag = CU_DEFORM_BOUNDS_OFF | CU_PATH_RADIUS, \ .pathlen = 100, \ .resolu = 12, \ @@ -26,7 +26,7 @@ .linedist = 1.0, \ .fsize = 1.0, \ .ulheight = 0.05, \ - .texflag = CU_AUTOSPACE, \ + .texspace_flag = CU_TEXSPACE_FLAG_AUTO, \ .smallcaps_scale = 0.75f, \ /* This one seems to be the best one in most cases, at least for curve deform. */ \ .twist_mode = CU_TWIST_MINIMUM, \ diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 5862c3a6707..d8fdcd4e6e5 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -211,14 +211,13 @@ typedef struct Curve { struct CurveProfile *bevel_profile; - /* texture space, copied as one block in editobject.c */ - float loc[3]; - float size[3]; + float texspace_location[3]; + float texspace_size[3]; /** Creation-time type of curve datablock. */ short type; - char texflag; + char texspace_flag; char _pad0[7]; short twist_mode; float twist_smooth, smallcaps_scale; @@ -313,10 +312,10 @@ typedef struct Curve { /* **************** CURVE ********************* */ -/** #Curve.texflag */ +/** #Curve.texspace_flag */ enum { - CU_AUTOSPACE = 1, - CU_AUTOSPACE_EVALUATED = 2, + CU_TEXSPACE_FLAG_AUTO = 1 << 0, + CU_TEXSPACE_FLAG_AUTO_EVALUATED = 1 << 1, }; /** #Curve.flag */ diff --git a/source/blender/makesdna/DNA_mesh_defaults.h b/source/blender/makesdna/DNA_mesh_defaults.h index 30fe387b05a..32a85e73b84 100644 --- a/source/blender/makesdna/DNA_mesh_defaults.h +++ b/source/blender/makesdna/DNA_mesh_defaults.h @@ -15,9 +15,9 @@ #define _DNA_DEFAULT_Mesh \ { \ - .size = {1.0f, 1.0f, 1.0f}, \ + .texspace_size = {1.0f, 1.0f, 1.0f}, \ .smoothresh = DEG2RADF(30), \ - .texflag = ME_AUTOSPACE, \ + .texspace_flag = ME_TEXSPACE_FLAG_AUTO, \ .remesh_voxel_size = 0.1f, \ .remesh_voxel_adaptivity = 0.0f, \ .face_sets_color_seed = 0, \ diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 78d228bb681..ef2f73ddffb 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -127,9 +127,9 @@ typedef struct Mesh { struct Mesh *texcomesh; /** Texture space location and size, used for procedural coordinates when rendering. */ - float loc[3]; - float size[3]; - char texflag; + float texspace_location[3]; + float texspace_size[3]; + char texspace_flag; /** Various flags used when editing the mesh. */ char editflag; @@ -303,10 +303,10 @@ typedef struct TFace { /* **************** MESH ********************* */ -/** #Mesh.texflag */ +/** #Mesh.texspace_flag */ enum { - ME_AUTOSPACE = 1, - ME_AUTOSPACE_EVALUATED = 2, + ME_TEXSPACE_FLAG_AUTO = 1 << 0, + ME_TEXSPACE_FLAG_AUTO_EVALUATED = 1 << 1, }; /** #Mesh.editflag */ diff --git a/source/blender/makesdna/DNA_meta_defaults.h b/source/blender/makesdna/DNA_meta_defaults.h index 4ac692d4a10..56acdfaf686 100644 --- a/source/blender/makesdna/DNA_meta_defaults.h +++ b/source/blender/makesdna/DNA_meta_defaults.h @@ -15,8 +15,8 @@ #define _DNA_DEFAULT_MetaBall \ { \ - .size = {1, 1, 1}, \ - .texflag = MB_AUTOSPACE, \ + .texspace_size = {1, 1, 1}, \ + .texspace_flag = MB_TEXSPACE_FLAG_AUTO, \ .wiresize = 0.4f, \ .rendersize = 0.2f, \ .thresh = 0.6f, \ diff --git a/source/blender/makesdna/DNA_meta_types.h b/source/blender/makesdna/DNA_meta_types.h index 5650fe91696..b18931b32fa 100644 --- a/source/blender/makesdna/DNA_meta_types.h +++ b/source/blender/makesdna/DNA_meta_types.h @@ -65,8 +65,8 @@ typedef struct MetaBall { /** Flag is enum for updates, flag2 is bit-flags for settings. */ char flag, flag2; short totcol; - /** Used to store MB_AUTOSPACE. */ - char texflag; + /** Used to store #MB_TEXTURE_FLAG_AUTO. */ + char texspace_flag; char _pad[2]; /** @@ -75,8 +75,8 @@ typedef struct MetaBall { */ char needs_flush_to_id; - float loc[3]; - float size[3]; + float texspace_location[3]; + float texspace_size[3]; /** Display and render res. */ float wiresize, rendersize; @@ -95,8 +95,10 @@ typedef struct MetaBall { /* **************** METABALL ********************* */ -/* texflag */ -#define MB_AUTOSPACE 1 +/** #MetaBall.texspace_flag */ +enum { + MB_TEXSPACE_FLAG_AUTO = 1 << 0, +}; /* mb->flag */ #define MB_UPDATE_ALWAYS 0 diff --git a/source/blender/makesdna/intern/dna_rename_defs.h b/source/blender/makesdna/intern/dna_rename_defs.h index e5057755995..ab543eb611f 100644 --- a/source/blender/makesdna/intern/dna_rename_defs.h +++ b/source/blender/makesdna/intern/dna_rename_defs.h @@ -60,6 +60,9 @@ DNA_STRUCT_RENAME_ELEM(Collection, dupli_ofs, instance_offset) DNA_STRUCT_RENAME_ELEM(Curve, ext1, extrude) DNA_STRUCT_RENAME_ELEM(Curve, ext2, bevel_radius) DNA_STRUCT_RENAME_ELEM(Curve, len_wchar, len_char32) +DNA_STRUCT_RENAME_ELEM(Curve, loc, texspace_location) +DNA_STRUCT_RENAME_ELEM(Curve, size, texspace_size) +DNA_STRUCT_RENAME_ELEM(Curve, texflag, texspace_flag) DNA_STRUCT_RENAME_ELEM(Curve, width, offset) DNA_STRUCT_RENAME_ELEM(CurvesGeometry, curve_size, curve_num) DNA_STRUCT_RENAME_ELEM(CurvesGeometry, point_size, point_num) @@ -92,9 +95,15 @@ DNA_STRUCT_RENAME_ELEM(MVert, co, co_legacy) DNA_STRUCT_RENAME_ELEM(MVert, flag, flag_legacy) DNA_STRUCT_RENAME_ELEM(MaskLayer, restrictflag, visibility_flag) DNA_STRUCT_RENAME_ELEM(MaterialLineArt, transparency_mask, material_mask_bits) +DNA_STRUCT_RENAME_ELEM(Mesh, loc, texspace_location) +DNA_STRUCT_RENAME_ELEM(Mesh, size, texspace_size) +DNA_STRUCT_RENAME_ELEM(Mesh, texflag, texspace_flag) DNA_STRUCT_RENAME_ELEM(MeshDeformModifierData, totcagevert, cage_verts_num) DNA_STRUCT_RENAME_ELEM(MeshDeformModifierData, totinfluence, influences_num) DNA_STRUCT_RENAME_ELEM(MeshDeformModifierData, totvert, verts_num) +DNA_STRUCT_RENAME_ELEM(MetaBall, loc, texspace_location) +DNA_STRUCT_RENAME_ELEM(MetaBall, size, texspace_size) +DNA_STRUCT_RENAME_ELEM(MetaBall, texflag, texspace_flag) DNA_STRUCT_RENAME_ELEM(MovieClip, name, filepath) DNA_STRUCT_RENAME_ELEM(MovieTracking, act_plane_track, act_plane_track_legacy) DNA_STRUCT_RENAME_ELEM(MovieTracking, act_track, act_track_legacy) diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 05ec71a47b9..d6ec43ba39d 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -260,7 +260,7 @@ static void rna_Curve_texspace_set(Main *UNUSED(bmain), Scene *UNUSED(scene), Po { Curve *cu = (Curve *)ptr->data; - if (cu->texflag & CU_AUTOSPACE) { + if (cu->texspace_flag & CU_TEXSPACE_FLAG_AUTO) { BKE_curve_texspace_calc(cu); } } @@ -268,23 +268,23 @@ static void rna_Curve_texspace_set(Main *UNUSED(bmain), Scene *UNUSED(scene), Po static int rna_Curve_texspace_editable(PointerRNA *ptr, const char **UNUSED(r_info)) { Curve *cu = (Curve *)ptr->data; - return (cu->texflag & CU_AUTOSPACE) ? 0 : PROP_EDITABLE; + return (cu->texspace_flag & CU_TEXSPACE_FLAG_AUTO) ? 0 : PROP_EDITABLE; } -static void rna_Curve_texspace_loc_get(PointerRNA *ptr, float *values) +static void rna_Curve_texspace_location_get(PointerRNA *ptr, float *values) { Curve *cu = (Curve *)ptr->data; BKE_curve_texspace_ensure(cu); - copy_v3_v3(values, cu->loc); + copy_v3_v3(values, cu->texspace_location); } -static void rna_Curve_texspace_loc_set(PointerRNA *ptr, const float *values) +static void rna_Curve_texspace_location_set(PointerRNA *ptr, const float *values) { Curve *cu = (Curve *)ptr->data; - copy_v3_v3(cu->loc, values); + copy_v3_v3(cu->texspace_location, values); } static void rna_Curve_texspace_size_get(PointerRNA *ptr, float *values) @@ -293,14 +293,14 @@ static void rna_Curve_texspace_size_get(PointerRNA *ptr, float *values) BKE_curve_texspace_ensure(cu); - copy_v3_v3(values, cu->size); + copy_v3_v3(values, cu->texspace_size); } static void rna_Curve_texspace_size_set(PointerRNA *ptr, const float *values) { Curve *cu = (Curve *)ptr->data; - copy_v3_v3(cu->size, values); + copy_v3_v3(cu->texspace_size, values); } static void rna_Curve_material_index_range( @@ -1805,7 +1805,7 @@ static void rna_def_curve(BlenderRNA *brna) /* texture space */ prop = RNA_def_property(srna, "use_auto_texspace", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "texflag", CU_AUTOSPACE); + RNA_def_property_boolean_sdna(prop, NULL, "texspace_flag", CU_TEXSPACE_FLAG_AUTO); RNA_def_property_ui_text( prop, "Auto Texture Space", @@ -1818,7 +1818,7 @@ static void rna_def_curve(BlenderRNA *brna) RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT); RNA_def_property_editable_func(prop, "rna_Curve_texspace_editable"); RNA_def_property_float_funcs( - prop, "rna_Curve_texspace_loc_get", "rna_Curve_texspace_loc_set", NULL); + prop, "rna_Curve_texspace_location_get", "rna_Curve_texspace_location_set", NULL); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); prop = RNA_def_property(srna, "texspace_size", PROP_FLOAT, PROP_XYZ); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 6791a171e8e..f1247c551a0 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -804,7 +804,7 @@ static void rna_MeshLoopColor_color_set(PointerRNA *ptr, const float *values) static int rna_Mesh_texspace_editable(PointerRNA *ptr, const char **UNUSED(r_info)) { Mesh *me = (Mesh *)ptr->data; - return (me->texflag & ME_AUTOSPACE) ? 0 : PROP_EDITABLE; + return (me->texspace_flag & ME_TEXSPACE_FLAG_AUTO) ? 0 : PROP_EDITABLE; } static void rna_Mesh_texspace_size_get(PointerRNA *ptr, float values[3]) @@ -813,16 +813,16 @@ static void rna_Mesh_texspace_size_get(PointerRNA *ptr, float values[3]) BKE_mesh_texspace_ensure(me); - copy_v3_v3(values, me->size); + copy_v3_v3(values, me->texspace_size); } -static void rna_Mesh_texspace_loc_get(PointerRNA *ptr, float values[3]) +static void rna_Mesh_texspace_location_get(PointerRNA *ptr, float values[3]) { Mesh *me = (Mesh *)ptr->data; BKE_mesh_texspace_ensure(me); - copy_v3_v3(values, me->loc); + copy_v3_v3(values, me->texspace_location); } static void rna_MeshVertex_groups_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) @@ -850,10 +850,10 @@ static void rna_MeshVertex_undeformed_co_get(PointerRNA *ptr, float values[3]) if (orco) { const int index = rna_MeshVertex_index_get(ptr); /* orco is normalized to 0..1, we do inverse to match the vertex position */ - float loc[3], size[3]; + float texspace_location[3], texspace_size[3]; - BKE_mesh_texspace_get(me->texcomesh ? me->texcomesh : me, loc, size); - madd_v3_v3v3v3(values, loc, orco[index], size); + BKE_mesh_texspace_get(me->texcomesh ? me->texcomesh : me, texspace_location, texspace_size); + madd_v3_v3v3v3(values, texspace_location, orco[index], texspace_size); } else { copy_v3_v3(values, position); @@ -3095,21 +3095,21 @@ void rna_def_texmat_common(StructRNA *srna, const char *texspace_editable) /* texture space */ prop = RNA_def_property(srna, "auto_texspace", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "texflag", ME_AUTOSPACE); + RNA_def_property_boolean_sdna(prop, NULL, "texspace_flag", ME_TEXSPACE_FLAG_AUTO); RNA_def_property_ui_text( prop, "Auto Texture Space", "Adjust active object's texture space automatically when transforming object"); prop = RNA_def_property(srna, "texspace_location", PROP_FLOAT, PROP_TRANSLATION); - RNA_def_property_float_sdna(prop, NULL, "loc"); + RNA_def_property_float_sdna(prop, NULL, "texspace_location"); RNA_def_property_ui_text(prop, "Texture Space Location", "Texture space location"); - RNA_def_property_float_funcs(prop, "rna_Mesh_texspace_loc_get", NULL, NULL); + RNA_def_property_float_funcs(prop, "rna_Mesh_texspace_location_get", NULL, NULL); RNA_def_property_editable_func(prop, texspace_editable); RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); prop = RNA_def_property(srna, "texspace_size", PROP_FLOAT, PROP_XYZ); - RNA_def_property_float_sdna(prop, NULL, "size"); + RNA_def_property_float_sdna(prop, NULL, "texspace_size"); RNA_def_property_flag(prop, PROP_PROPORTIONAL); RNA_def_property_ui_text(prop, "Texture Space Size", "Texture space size"); RNA_def_property_float_funcs(prop, "rna_Mesh_texspace_size_get", NULL, NULL); @@ -4349,7 +4349,7 @@ static void rna_def_mesh(BlenderRNA *brna) /* texture space */ prop = RNA_def_property(srna, "use_auto_texspace", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "texflag", ME_AUTOSPACE); + RNA_def_property_boolean_sdna(prop, NULL, "texspace_flag", ME_TEXSPACE_FLAG_AUTO); RNA_def_property_ui_text( prop, "Auto Texture Space", @@ -4362,7 +4362,7 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Texture Space Location", "Texture space location"); RNA_def_property_editable_func(prop, "rna_Mesh_texspace_editable"); RNA_def_property_float_funcs( - prop, "rna_Mesh_texspace_loc_get", "rna_Mesh_texspace_loc_set", NULL); + prop, "rna_Mesh_texspace_location_get", "rna_Mesh_texspace_location_set", NULL); RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); # endif diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c index 75188f29fac..03e422df7da 100644 --- a/source/blender/makesrna/intern/rna_meta.c +++ b/source/blender/makesrna/intern/rna_meta.c @@ -38,23 +38,23 @@ static int rna_Meta_texspace_editable(PointerRNA *ptr, const char **UNUSED(r_info)) { MetaBall *mb = (MetaBall *)ptr->data; - return (mb->texflag & MB_AUTOSPACE) ? 0 : PROP_EDITABLE; + return (mb->texspace_flag & MB_TEXSPACE_FLAG_AUTO) ? 0 : PROP_EDITABLE; } -static void rna_Meta_texspace_loc_get(PointerRNA *ptr, float *values) +static void rna_Meta_texspace_location_get(PointerRNA *ptr, float *values) { MetaBall *mb = (MetaBall *)ptr->data; /* tex_space_mball() needs object.. ugh */ - copy_v3_v3(values, mb->loc); + copy_v3_v3(values, mb->texspace_location); } -static void rna_Meta_texspace_loc_set(PointerRNA *ptr, const float *values) +static void rna_Meta_texspace_location_set(PointerRNA *ptr, const float *values) { MetaBall *mb = (MetaBall *)ptr->data; - copy_v3_v3(mb->loc, values); + copy_v3_v3(mb->texspace_location, values); } static void rna_Meta_texspace_size_get(PointerRNA *ptr, float *values) @@ -63,14 +63,14 @@ static void rna_Meta_texspace_size_get(PointerRNA *ptr, float *values) /* tex_space_mball() needs object.. ugh */ - copy_v3_v3(values, mb->size); + copy_v3_v3(values, mb->texspace_size); } static void rna_Meta_texspace_size_set(PointerRNA *ptr, const float *values) { MetaBall *mb = (MetaBall *)ptr->data; - copy_v3_v3(mb->size, values); + copy_v3_v3(mb->texspace_size, values); } static void rna_MetaBall_redraw_data(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) @@ -358,7 +358,7 @@ static void rna_def_metaball(BlenderRNA *brna) /* texture space */ prop = RNA_def_property(srna, "use_auto_texspace", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "texflag", MB_AUTOSPACE); + RNA_def_property_boolean_sdna(prop, NULL, "texspace_flag", MB_TEXSPACE_FLAG_AUTO); RNA_def_property_ui_text( prop, "Auto Texture Space", @@ -369,7 +369,7 @@ static void rna_def_metaball(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Texture Space Location", "Texture space location"); RNA_def_property_editable_func(prop, "rna_Meta_texspace_editable"); RNA_def_property_float_funcs( - prop, "rna_Meta_texspace_loc_get", "rna_Meta_texspace_loc_set", NULL); + prop, "rna_Meta_texspace_location_get", "rna_Meta_texspace_location_set", NULL); RNA_def_property_update(prop, 0, "rna_MetaBall_update_data"); prop = RNA_def_property(srna, "texspace_size", PROP_FLOAT, PROP_XYZ); From ca3e19f4c529fd2389f5da56ab039163778ec1e1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 18 Jan 2023 18:27:49 +1100 Subject: [PATCH 0728/1522] Fixes for 'make check_pep8' target - Skip files in dirs starting with '.' (`.git` was being searched). - Update --disable list for pylint. --- tests/python/pep8.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/python/pep8.py b/tests/python/pep8.py index 2583bec8256..6b046f5a6af 100644 --- a/tests/python/pep8.py +++ b/tests/python/pep8.py @@ -26,7 +26,8 @@ FORCE_PEP8_ALL = False def file_list_py(path): - for dirpath, _dirnames, filenames in os.walk(path): + for dirpath, dirnames, filenames in os.walk(path): + dirnames[:] = [d for d in dirnames if not d.startswith(".")] for filename in filenames: if filename.endswith((".py", ".cfg")): yield os.path.join(dirpath, filename) @@ -93,12 +94,11 @@ def check_files_pylint(files): "--disable=" "C0111," # missing doc string "C0103," # invalid name + "C0209," # Formatting a regular string which could be a f-string + "C0302," # Too many lines in module "C0413," # import should be placed at the top + "C0415," # Import outside toplevel "W0613," # unused argument, may add this back - # but happens a lot for 'context' for eg. - "W0232," # class has no __init__, Operator/Panel/Menu etc - "W0142," # Used * or ** magic - # even needed in some cases "R0902," # Too many instance attributes "R0903," # Too many statements "R0911," # Too many return statements From 60d9de767db6f14b274fd2ecf5462097bd119b49 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 18 Jan 2023 18:41:13 +1100 Subject: [PATCH 0729/1522] Cleanup: remove redundant forward declarations for structs --- source/blender/asset_system/AS_asset_library.h | 1 - source/blender/blenfont/BLF_api.h | 1 - source/blender/blenfont/intern/blf_internal.h | 1 - source/blender/blenkernel/BKE_animsys.h | 1 - source/blender/blenkernel/BKE_blendfile_link_append.h | 4 ---- source/blender/blenkernel/BKE_bpath.h | 1 - source/blender/blenkernel/BKE_brush.h | 1 - source/blender/blenkernel/BKE_collision.h | 1 - source/blender/blenkernel/BKE_curves.h | 1 - source/blender/blenkernel/BKE_displist.h | 1 - source/blender/blenkernel/BKE_geometry_set.h | 1 - source/blender/blenkernel/BKE_geometry_set.hh | 2 -- source/blender/blenkernel/BKE_gpencil.h | 1 - source/blender/blenkernel/BKE_gpencil_geom.h | 1 - source/blender/blenkernel/BKE_image.h | 1 - source/blender/blenkernel/BKE_image_partial_update.hh | 1 - source/blender/blenkernel/BKE_mesh.h | 1 - source/blender/blenkernel/BKE_mesh_wrapper.h | 1 - source/blender/blenkernel/BKE_multires.h | 2 -- source/blender/blenkernel/BKE_node.h | 10 ---------- source/blender/blenkernel/BKE_object.h | 2 -- source/blender/blenkernel/BKE_particle.h | 1 - source/blender/blenkernel/BKE_pointcloud.h | 1 - source/blender/blenkernel/BKE_subsurf.h | 1 - source/blender/blenkernel/intern/library.c | 1 - source/blender/blenkernel/intern/pbvh_uv_islands.hh | 1 - source/blender/blenloader/BLO_read_write.h | 1 - source/blender/blenloader/BLO_readfile.h | 2 -- source/blender/blenloader/intern/readfile.h | 1 - source/blender/bmesh/intern/bmesh_mesh.h | 3 --- source/blender/bmesh/intern/bmesh_mesh_normals.h | 2 ++ source/blender/bmesh/intern/bmesh_polygon.h | 1 - .../depsgraph/intern/builder/deg_builder_nodes.h | 1 - .../depsgraph/intern/builder/deg_builder_relations.h | 1 - source/blender/draw/DRW_pbvh.h | 3 --- .../draw/engines/eevee_next/eevee_cryptomatte.hh | 1 - source/blender/draw/engines/image/image_private.hh | 2 -- source/blender/draw/intern/draw_cache_impl.h | 3 --- source/blender/draw/intern/draw_command_shared.hh | 2 -- source/blender/draw/intern/draw_curves_private.h | 2 -- source/blender/draw/intern/draw_shader_shared.h | 1 - source/blender/draw/intern/draw_subdivision.h | 1 - source/blender/draw/intern/draw_view.h | 2 -- source/blender/editors/asset/ED_asset_handle.h | 2 -- source/blender/editors/asset/ED_asset_list.h | 1 - source/blender/editors/asset/ED_asset_list.hh | 2 -- .../blender/editors/asset/ED_asset_temp_id_consumer.h | 2 -- source/blender/editors/include/ED_armature.h | 1 - source/blender/editors/include/ED_curves_sculpt.h | 2 -- source/blender/editors/include/ED_file_indexer.h | 1 - source/blender/editors/include/ED_fileselect.h | 1 - source/blender/editors/include/ED_gizmo_library.h | 1 - source/blender/editors/include/ED_keyframes_keylist.h | 1 - source/blender/editors/include/ED_node.h | 2 -- source/blender/editors/include/ED_node.hh | 1 + source/blender/editors/include/ED_object.h | 1 - source/blender/editors/include/ED_sculpt.h | 3 --- source/blender/editors/include/ED_select_utils.h | 1 - source/blender/editors/include/ED_spreadsheet.h | 5 ----- source/blender/editors/include/ED_util.h | 1 - source/blender/editors/include/UI_abstract_view.hh | 1 - source/blender/editors/include/UI_grid_view.hh | 2 -- source/blender/editors/include/UI_interface.h | 3 --- source/blender/editors/interface/interface_handlers.cc | 2 ++ source/blender/editors/space_node/node_intern.hh | 2 -- .../space_spreadsheet/spreadsheet_column_values.hh | 2 -- source/blender/editors/space_view3d/view3d_intern.h | 1 - source/blender/editors/space_view3d/view3d_navigate.h | 1 - source/blender/editors/transform/transform.h | 1 - source/blender/editors/transform/transform_convert.h | 1 - source/blender/editors/transform/transform_mode.h | 1 - source/blender/gpu/GPU_shader.h | 1 - source/blender/gpu/GPU_storage_buffer.h | 2 -- source/blender/gpu/GPU_viewport.h | 2 -- source/blender/imbuf/IMB_colormanagement.h | 1 - source/blender/io/usd/intern/usd_reader_prim.h | 1 + source/blender/io/usd/intern/usd_writer_material.h | 3 --- source/blender/io/usd/usd.h | 1 - source/blender/makesdna/DNA_node_types.h | 2 -- source/blender/makesdna/DNA_view3d_types.h | 1 - source/blender/makesdna/DNA_windowmanager_types.h | 1 - source/blender/makesrna/intern/rna_internal.h | 2 -- source/blender/modifiers/MOD_nodes.h | 1 - source/blender/nodes/NOD_geometry_exec.hh | 2 -- source/blender/nodes/NOD_geometry_nodes_log.hh | 2 -- source/blender/python/generic/idprop_py_ui_api.h | 1 - source/blender/python/gpu/gpu_py_offscreen.h | 1 - source/blender/python/intern/bpy_capi_utils.h | 1 - source/blender/render/RE_texture_margin.h | 1 - source/blender/render/intern/pipeline.h | 1 - source/blender/render/intern/render_result.h | 2 -- source/blender/sequencer/SEQ_channels.h | 1 - source/blender/sequencer/SEQ_iterator.h | 1 - source/blender/sequencer/SEQ_sequencer.h | 1 - source/blender/sequencer/SEQ_transform.h | 1 - source/blender/sequencer/SEQ_utils.h | 1 - source/blender/sequencer/intern/effects.h | 1 - source/blender/windowmanager/WM_api.h | 2 -- 98 files changed, 6 insertions(+), 146 deletions(-) diff --git a/source/blender/asset_system/AS_asset_library.h b/source/blender/asset_system/AS_asset_library.h index 0a67df2ecbf..870d2041655 100644 --- a/source/blender/asset_system/AS_asset_library.h +++ b/source/blender/asset_system/AS_asset_library.h @@ -7,7 +7,6 @@ #pragma once struct IDRemapper; -struct Main; #ifdef __cplusplus extern "C" { diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index 01b6d1d8942..558fd5f1dc2 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -28,7 +28,6 @@ extern "C" { struct ColorManagedDisplay; struct ResultBLF; -struct rctf; struct rcti; int BLF_init(void); diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h index 2f3f7b52233..cbdfa191877 100644 --- a/source/blender/blenfont/intern/blf_internal.h +++ b/source/blender/blenfont/intern/blf_internal.h @@ -11,7 +11,6 @@ struct FontBLF; struct GlyphBLF; struct GlyphCacheBLF; struct ResultBLF; -struct rctf; struct rcti; /* Max number of FontBLFs in memory. Take care that every font has a glyph cache per size/dpi, diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index 91ecfe09f38..46aacf1e7fd 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -33,7 +33,6 @@ struct PointerRNA; struct PropertyRNA; struct bAction; struct bActionGroup; -struct bContext; /* Container for data required to do FCurve and Driver evaluation. */ typedef struct AnimationEvalContext { diff --git a/source/blender/blenkernel/BKE_blendfile_link_append.h b/source/blender/blenkernel/BKE_blendfile_link_append.h index bd00ed51d99..0f54760e03a 100644 --- a/source/blender/blenkernel/BKE_blendfile_link_append.h +++ b/source/blender/blenkernel/BKE_blendfile_link_append.h @@ -13,11 +13,7 @@ struct BlendHandle; struct ID; struct Library; struct LibraryLink_Params; -struct Main; struct ReportList; -struct Scene; -struct View3D; -struct ViewLayer; typedef struct BlendfileLinkAppendContext BlendfileLinkAppendContext; typedef struct BlendfileLinkAppendContextItem BlendfileLinkAppendContextItem; diff --git a/source/blender/blenkernel/BKE_bpath.h b/source/blender/blenkernel/BKE_bpath.h index 555cddd34bd..20fd0758370 100644 --- a/source/blender/blenkernel/BKE_bpath.h +++ b/source/blender/blenkernel/BKE_bpath.h @@ -19,7 +19,6 @@ extern "C" { #endif struct ID; -struct ListBase; struct Main; struct ReportList; diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h index a763b3d12c2..369b7e56a6c 100644 --- a/source/blender/blenkernel/BKE_brush.h +++ b/source/blender/blenkernel/BKE_brush.h @@ -18,7 +18,6 @@ extern "C" { struct Brush; struct ImBuf; struct ImagePool; -struct Object; struct Main; struct MTex; struct Scene; diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h index 01e0a0ce062..8e566f08b5d 100644 --- a/source/blender/blenkernel/BKE_collision.h +++ b/source/blender/blenkernel/BKE_collision.h @@ -16,7 +16,6 @@ struct CollisionModifierData; struct Depsgraph; struct MVertTri; struct Object; -struct Scene; //////////////////////////////////////// // used for collisions in collision.c diff --git a/source/blender/blenkernel/BKE_curves.h b/source/blender/blenkernel/BKE_curves.h index 71a0562e1df..83a0ba201f8 100644 --- a/source/blender/blenkernel/BKE_curves.h +++ b/source/blender/blenkernel/BKE_curves.h @@ -15,7 +15,6 @@ extern "C" { struct BoundBox; struct Curves; -struct CustomDataLayer; struct Depsgraph; struct Main; struct Object; diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 6551e732300..410cc0b473a 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -43,7 +43,6 @@ enum { struct Depsgraph; struct ListBase; -struct Mesh; struct Object; struct Scene; diff --git a/source/blender/blenkernel/BKE_geometry_set.h b/source/blender/blenkernel/BKE_geometry_set.h index 97e69f3fe1f..c3403e66cab 100644 --- a/source/blender/blenkernel/BKE_geometry_set.h +++ b/source/blender/blenkernel/BKE_geometry_set.h @@ -10,7 +10,6 @@ extern "C" { #endif -struct Collection; struct GeometrySet; struct Object; diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh index f450ffe33e8..72f77c889c1 100644 --- a/source/blender/blenkernel/BKE_geometry_set.hh +++ b/source/blender/blenkernel/BKE_geometry_set.hh @@ -20,10 +20,8 @@ #include "BKE_geometry_set.h" struct Curves; -struct Collection; struct Curve; struct Mesh; -struct Object; struct PointCloud; struct Volume; diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h index dc7a5ab003a..55ca1c38af4 100644 --- a/source/blender/blenkernel/BKE_gpencil.h +++ b/source/blender/blenkernel/BKE_gpencil.h @@ -16,7 +16,6 @@ struct Brush; struct CurveMapping; struct Depsgraph; struct GHash; -struct GPencilUpdateCache; struct ListBase; struct MDeformVert; struct Main; diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h index 976961f27ae..70b12477b43 100644 --- a/source/blender/blenkernel/BKE_gpencil_geom.h +++ b/source/blender/blenkernel/BKE_gpencil_geom.h @@ -14,7 +14,6 @@ extern "C" { struct Depsgraph; struct Main; struct Object; -struct RegionView3D; struct Scene; struct bGPDcurve; struct bGPDframe; diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index eb43ce823ac..f00da370ccf 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -565,7 +565,6 @@ struct PartialUpdateUser *BKE_image_partial_update_create(const struct Image *im void BKE_image_partial_update_free(struct PartialUpdateUser *user); /* --- partial updater (image side) --- */ -struct PartialUpdateRegister; void BKE_image_partial_update_register_free(struct Image *image); /** \brief Mark a region of the image to update. */ diff --git a/source/blender/blenkernel/BKE_image_partial_update.hh b/source/blender/blenkernel/BKE_image_partial_update.hh index 8f962ace268..8e914940b3a 100644 --- a/source/blender/blenkernel/BKE_image_partial_update.hh +++ b/source/blender/blenkernel/BKE_image_partial_update.hh @@ -23,7 +23,6 @@ #include "DNA_image_types.h" extern "C" { -struct PartialUpdateRegister; struct PartialUpdateUser; } diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index dc595ff0ce1..557b70b8a11 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -40,7 +40,6 @@ struct MPoly; struct Main; struct MemArena; struct Mesh; -struct ModifierData; struct Object; struct PointCloud; struct Scene; diff --git a/source/blender/blenkernel/BKE_mesh_wrapper.h b/source/blender/blenkernel/BKE_mesh_wrapper.h index b4742583b03..a9b9bb96178 100644 --- a/source/blender/blenkernel/BKE_mesh_wrapper.h +++ b/source/blender/blenkernel/BKE_mesh_wrapper.h @@ -8,7 +8,6 @@ struct BMEditMesh; struct CustomData_MeshMasks; struct Mesh; -struct Object; #ifdef __cplusplus extern "C" { diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 57e87ddddd8..5e5ca8b4ee6 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -24,8 +24,6 @@ struct Object; struct Scene; struct SubdivCCG; -struct MLoop; -struct MLoopTri; struct MPoly; /** diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index c40839361e2..dc5b1791bdb 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -29,27 +29,19 @@ extern "C" { /* not very important, but the stack solver likes to know a maximum */ #define MAX_SOCKET 512 -struct ARegion; struct BlendDataReader; struct BlendExpander; struct BlendLibReader; struct BlendWriter; -struct ColorManagedDisplaySettings; -struct ColorManagedViewSettings; -struct CryptomatteSession; struct FreestyleLineStyle; struct GPUMaterial; struct GPUNodeStack; struct ID; struct ImBuf; -struct ImageFormatData; struct Light; -struct ListBase; -struct MTex; struct Main; struct Material; struct PointerRNA; -struct RenderData; struct Scene; struct SpaceNode; struct Tex; @@ -1355,8 +1347,6 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i /** \name Texture Nodes * \{ */ -struct TexResult; - #define TEX_NODE_OUTPUT 401 #define TEX_NODE_CHECKER 402 #define TEX_NODE_TEXTURE 403 diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 963b0b87118..c77faf98b25 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -20,7 +20,6 @@ struct Base; struct BoundBox; struct Curve; struct Depsgraph; -struct GeometrySet; struct GpencilModifierData; struct HookGpencilModifierData; struct HookModifierData; @@ -33,7 +32,6 @@ struct Object; struct RegionView3D; struct RigidBodyWorld; struct Scene; -struct ShaderFxData; struct SubsurfModifierData; struct View3D; struct ViewLayer; diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index f295979f23c..ad7045a8c2e 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -31,7 +31,6 @@ struct CustomData_MeshMasks; struct Depsgraph; struct EdgeHash; struct KDTree_3d; -struct LatticeDeformData; struct LinkNode; struct MCol; struct MFace; diff --git a/source/blender/blenkernel/BKE_pointcloud.h b/source/blender/blenkernel/BKE_pointcloud.h index 48be080968d..c6a72af6fab 100644 --- a/source/blender/blenkernel/BKE_pointcloud.h +++ b/source/blender/blenkernel/BKE_pointcloud.h @@ -20,7 +20,6 @@ extern "C" { #endif struct BoundBox; -struct CustomDataLayer; struct Depsgraph; struct Main; struct Object; diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h index 557a71fd06b..3630c95ec76 100644 --- a/source/blender/blenkernel/BKE_subsurf.h +++ b/source/blender/blenkernel/BKE_subsurf.h @@ -24,7 +24,6 @@ struct CCGVert; struct DMFlagMat; struct DerivedMesh; struct EdgeHash; -struct MPoly; struct Mesh; struct MeshElemMap; struct Object; diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 516fb9b75b6..ee50c4ae753 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -32,7 +32,6 @@ /* Unused currently. */ // static CLG_LogRef LOG = {.identifier = "bke.library"}; -struct BlendWriter; struct BlendDataReader; static void library_runtime_reset(Library *lib) diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.hh b/source/blender/blenkernel/intern/pbvh_uv_islands.hh index b97d07a2146..9496b564516 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.hh +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.hh @@ -43,7 +43,6 @@ struct UVEdge; struct UVIslands; struct UVIslandsMask; struct UVPrimitive; -struct UVPrimitiveEdge; struct MeshData; struct UVVertex; diff --git a/source/blender/blenloader/BLO_read_write.h b/source/blender/blenloader/BLO_read_write.h index 56b0cc81598..35768cb7e7a 100644 --- a/source/blender/blenloader/BLO_read_write.h +++ b/source/blender/blenloader/BLO_read_write.h @@ -42,7 +42,6 @@ typedef struct BlendWriter BlendWriter; struct BlendFileReadReport; struct Main; -struct ReportList; /* -------------------------------------------------------------------- */ /** \name Blend Write API diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 4c34b628a6d..850aff20a1b 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -16,13 +16,11 @@ extern "C" { struct BHead; struct BlendThumbnail; -struct Collection; struct FileData; struct LinkNode; struct ListBase; struct Main; struct MemFile; -struct Object; struct ReportList; struct Scene; struct UserDef; diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h index a0f19512753..027f1453581 100644 --- a/source/blender/blenloader/intern/readfile.h +++ b/source/blender/blenloader/intern/readfile.h @@ -23,7 +23,6 @@ extern "C" { #endif -struct BLI_mmap_file; struct BLOCacheStorage; struct IDNameLib_Map; struct Key; diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h index d72ecfca338..a4cfa00aeb3 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.h +++ b/source/blender/bmesh/intern/bmesh_mesh.h @@ -13,9 +13,6 @@ extern "C" { #endif struct BMAllocTemplate; -struct BMLoopNorEditDataArray; -struct BMPartialUpdate; -struct MLoopNorSpaceArray; void BM_mesh_elem_toolflags_ensure(BMesh *bm); void BM_mesh_elem_toolflags_clear(BMesh *bm); diff --git a/source/blender/bmesh/intern/bmesh_mesh_normals.h b/source/blender/bmesh/intern/bmesh_mesh_normals.h index f92d7e3fbfd..51768af2ab0 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_normals.h +++ b/source/blender/bmesh/intern/bmesh_mesh_normals.h @@ -12,6 +12,8 @@ extern "C" { #endif +struct BMPartialUpdate; + struct BMeshNormalsUpdate_Params { /** * When calculating tessellation as well as normals, tessellate & calculate face normals diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index d9f48b4887b..6262f185eca 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -6,7 +6,6 @@ * \ingroup bmesh */ -struct BMPartialUpdate; struct Heap; #include "BLI_compiler_attrs.h" diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index a8efe8fca9f..f944b836563 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -45,7 +45,6 @@ struct World; struct bAction; struct bArmature; struct bConstraint; -struct bGPdata; struct bNodeSocket; struct bNodeTree; struct bPoseChannel; diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 901e4a1acbb..3473ac55a1e 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -62,7 +62,6 @@ struct World; struct bAction; struct bArmature; struct bConstraint; -struct bGPdata; struct bNodeSocket; struct bNodeTree; struct bPoseChannel; diff --git a/source/blender/draw/DRW_pbvh.h b/source/blender/draw/DRW_pbvh.h index d49e5b6c686..00c76b641ee 100644 --- a/source/blender/draw/DRW_pbvh.h +++ b/source/blender/draw/DRW_pbvh.h @@ -17,17 +17,14 @@ extern "C" { #endif -struct GPUViewport; struct PBVHAttrReq; struct GPUBatch; struct PBVHNode; struct GSet; struct DMFlagMat; -struct Object; struct Mesh; struct MLoopTri; struct CustomData; -struct MEdge; struct MLoop; struct MPoly; struct SubdivCCG; diff --git a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh index 86ab3d97b4b..daeb9a08e35 100644 --- a/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh +++ b/source/blender/draw/engines/eevee_next/eevee_cryptomatte.hh @@ -20,7 +20,6 @@ extern "C" { struct Material; -struct CryptomatteSession; } namespace blender::eevee { diff --git a/source/blender/draw/engines/image/image_private.hh b/source/blender/draw/engines/image/image_private.hh index 8241b7e288e..4780eea5bf5 100644 --- a/source/blender/draw/engines/image/image_private.hh +++ b/source/blender/draw/engines/image/image_private.hh @@ -16,8 +16,6 @@ /* Forward declarations */ extern "C" { -struct GPUTexture; -struct ImBuf; struct Image; } diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h index 73ca5821ff0..8cc53b48af8 100644 --- a/source/blender/draw/intern/draw_cache_impl.h +++ b/source/blender/draw/intern/draw_cache_impl.h @@ -8,10 +8,8 @@ #pragma once struct GPUBatch; -struct GPUIndexBuf; struct GPUMaterial; struct GPUVertBuf; -struct ListBase; struct ModifierData; struct PTCacheEdit; struct ParticleSystem; @@ -21,7 +19,6 @@ struct Curve; struct Curves; struct Lattice; struct Mesh; -struct MetaBall; struct PointCloud; struct Volume; struct bGPdata; diff --git a/source/blender/draw/intern/draw_command_shared.hh b/source/blender/draw/intern/draw_command_shared.hh index 9fbbe23f0ce..4bb9aa777f3 100644 --- a/source/blender/draw/intern/draw_command_shared.hh +++ b/source/blender/draw/intern/draw_command_shared.hh @@ -11,8 +11,6 @@ namespace blender::draw::command { -struct RecordingState; - #endif /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/intern/draw_curves_private.h b/source/blender/draw/intern/draw_curves_private.h index 36deca46e94..9d02eedbbc3 100644 --- a/source/blender/draw/intern/draw_curves_private.h +++ b/source/blender/draw/intern/draw_curves_private.h @@ -18,9 +18,7 @@ extern "C" { struct Curves; struct GPUVertBuf; -struct GPUIndexBuf; struct GPUBatch; -struct GPUTexture; #define MAX_THICKRES 2 /* see eHairType */ #define MAX_HAIR_SUBDIV 4 /* see hair_subdiv rna */ diff --git a/source/blender/draw/intern/draw_shader_shared.h b/source/blender/draw/intern/draw_shader_shared.h index 23ded2ea5e9..3d0b3930121 100644 --- a/source/blender/draw/intern/draw_shader_shared.h +++ b/source/blender/draw/intern/draw_shader_shared.h @@ -27,7 +27,6 @@ typedef struct DRWDebugDrawBuffer DRWDebugDrawBuffer; /* C++ only forward declarations. */ struct Object; struct ViewLayer; -struct ID; struct GPUUniformAttr; struct GPULayerAttr; diff --git a/source/blender/draw/intern/draw_subdivision.h b/source/blender/draw/intern/draw_subdivision.h index 5133abc9257..a0e96ba4eeb 100644 --- a/source/blender/draw/intern/draw_subdivision.h +++ b/source/blender/draw/intern/draw_subdivision.h @@ -19,7 +19,6 @@ struct MeshBatchCache; struct MeshBufferCache; struct MeshRenderData; struct Object; -struct Scene; struct Subdiv; struct ToolSettings; diff --git a/source/blender/draw/intern/draw_view.h b/source/blender/draw/intern/draw_view.h index d4a6f8a1a85..29825b11832 100644 --- a/source/blender/draw/intern/draw_view.h +++ b/source/blender/draw/intern/draw_view.h @@ -7,8 +7,6 @@ #pragma once -struct ARegion; - void DRW_draw_region_info(void); void DRW_clear_background(void); void DRW_draw_cursor(void); diff --git a/source/blender/editors/asset/ED_asset_handle.h b/source/blender/editors/asset/ED_asset_handle.h index c11f94a3259..7bbba9b379e 100644 --- a/source/blender/editors/asset/ED_asset_handle.h +++ b/source/blender/editors/asset/ED_asset_handle.h @@ -19,8 +19,6 @@ extern "C" { #endif struct AssetHandle; -struct AssetLibraryReference; -struct bContext; const char *ED_asset_handle_get_name(const struct AssetHandle *asset); struct AssetMetaData *ED_asset_handle_get_metadata(const struct AssetHandle *asset); diff --git a/source/blender/editors/asset/ED_asset_list.h b/source/blender/editors/asset/ED_asset_list.h index 635dc3bff32..30f961421a5 100644 --- a/source/blender/editors/asset/ED_asset_list.h +++ b/source/blender/editors/asset/ED_asset_list.h @@ -10,7 +10,6 @@ extern "C" { #endif -struct AssetFilterSettings; struct AssetHandle; struct AssetLibraryReference; struct ID; diff --git a/source/blender/editors/asset/ED_asset_list.hh b/source/blender/editors/asset/ED_asset_list.hh index c99890974d5..524fee274f8 100644 --- a/source/blender/editors/asset/ED_asset_list.hh +++ b/source/blender/editors/asset/ED_asset_list.hh @@ -12,8 +12,6 @@ struct AssetHandle; struct AssetLibraryReference; -struct FileDirEntry; -struct bContext; namespace blender::asset_system { class AssetLibrary; diff --git a/source/blender/editors/asset/ED_asset_temp_id_consumer.h b/source/blender/editors/asset/ED_asset_temp_id_consumer.h index d6ed2509a32..e166aecb13a 100644 --- a/source/blender/editors/asset/ED_asset_temp_id_consumer.h +++ b/source/blender/editors/asset/ED_asset_temp_id_consumer.h @@ -20,10 +20,8 @@ extern "C" { typedef struct AssetTempIDConsumer AssetTempIDConsumer; struct AssetHandle; -struct AssetLibraryReference; struct Main; struct ReportList; -struct bContext; AssetTempIDConsumer *ED_asset_temp_id_consumer_create(const struct AssetHandle *handle); void ED_asset_temp_id_consumer_free(AssetTempIDConsumer **consumer); diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index fb1c1912801..fcbaf9e115d 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -31,7 +31,6 @@ struct SelectPick_Params; struct UndoType; struct View3D; struct ViewLayer; -struct bAction; struct bArmature; struct bContext; struct bPoseChannel; diff --git a/source/blender/editors/include/ED_curves_sculpt.h b/source/blender/editors/include/ED_curves_sculpt.h index 66f57670cec..8aab1533e25 100644 --- a/source/blender/editors/include/ED_curves_sculpt.h +++ b/source/blender/editors/include/ED_curves_sculpt.h @@ -10,8 +10,6 @@ extern "C" { #endif -struct Curves; - void ED_operatortypes_sculpt_curves(void); #ifdef __cplusplus diff --git a/source/blender/editors/include/ED_file_indexer.h b/source/blender/editors/include/ED_file_indexer.h index eeb0fb3124f..981a6015a94 100644 --- a/source/blender/editors/include/ED_file_indexer.h +++ b/source/blender/editors/include/ED_file_indexer.h @@ -22,7 +22,6 @@ extern "C" { * `filelist_setindexer` function. */ -struct AssetLibraryReference; struct LinkNode; /** diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index 9d5d8dd54cb..d4470c017bd 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -17,7 +17,6 @@ struct ARegion; struct FileAssetSelectParams; struct FileDirEntry; struct FileSelectParams; -struct Scene; struct ScrArea; struct SpaceFile; struct bContext; diff --git a/source/blender/editors/include/ED_gizmo_library.h b/source/blender/editors/include/ED_gizmo_library.h index 31c1f93f5bc..9d65e23415c 100644 --- a/source/blender/editors/include/ED_gizmo_library.h +++ b/source/blender/editors/include/ED_gizmo_library.h @@ -32,7 +32,6 @@ void ED_gizmotypes_snap_3d(void); struct Object; struct bContext; struct wmGizmo; -struct wmWindowManager; /* -------------------------------------------------------------------- */ /* Shape Presets diff --git a/source/blender/editors/include/ED_keyframes_keylist.h b/source/blender/editors/include/ED_keyframes_keylist.h index 251b6e4d83d..7aaeb41572b 100644 --- a/source/blender/editors/include/ED_keyframes_keylist.h +++ b/source/blender/editors/include/ED_keyframes_keylist.h @@ -15,7 +15,6 @@ extern "C" { struct AnimData; struct CacheFile; -struct DLRBT_Tree; struct FCurve; struct MaskLayer; struct Object; diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index f996a9f4591..d6f2fb10fe2 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -14,13 +14,11 @@ extern "C" { struct ID; struct Main; struct Scene; -struct ScrArea; struct SpaceNode; struct Tex; struct View2D; struct bContext; struct bNode; -struct bNodeSocket; struct bNodeSocketType; struct bNodeTree; struct bNodeTreeType; diff --git a/source/blender/editors/include/ED_node.hh b/source/blender/editors/include/ED_node.hh index ff88eedb5a4..385430d3856 100644 --- a/source/blender/editors/include/ED_node.hh +++ b/source/blender/editors/include/ED_node.hh @@ -8,6 +8,7 @@ struct SpaceNode; struct ARegion; struct Main; +struct bNodeSocket; struct bNodeTree; struct rcti; diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 9e8d9636a29..798175b7cb8 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -35,7 +35,6 @@ struct bContext; struct bFaceMap; struct bPoseChannel; struct uiLayout; -struct wmEvent; struct wmKeyConfig; struct wmOperator; struct wmOperatorType; diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index bc4e3b88586..fca7476fcf3 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -17,9 +17,6 @@ struct UndoType; struct ViewContext; struct bContext; struct rcti; -struct wmMsgSubscribeKey; -struct wmMsgSubscribeValue; -struct wmRegionMessageSubscribeParams; struct wmOperator; /* sculpt.cc */ diff --git a/source/blender/editors/include/ED_select_utils.h b/source/blender/editors/include/ED_select_utils.h index 8c856794ec8..a3ac86ab041 100644 --- a/source/blender/editors/include/ED_select_utils.h +++ b/source/blender/editors/include/ED_select_utils.h @@ -13,7 +13,6 @@ extern "C" { #endif struct KDTree_1d; -struct wmOperator; struct wmOperatorType; enum { diff --git a/source/blender/editors/include/ED_spreadsheet.h b/source/blender/editors/include/ED_spreadsheet.h index 736da367a44..924c8bdd611 100644 --- a/source/blender/editors/include/ED_spreadsheet.h +++ b/source/blender/editors/include/ED_spreadsheet.h @@ -3,12 +3,7 @@ #pragma once struct ID; -struct Main; -struct Object; -struct SpaceNode; struct SpaceSpreadsheet; -struct bContext; -struct bNode; #ifdef __cplusplus extern "C" { diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index 98a9746292b..42406f727ed 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -14,7 +14,6 @@ extern "C" { #endif -struct GPUBatch; struct IDRemapper; struct Main; struct bContext; diff --git a/source/blender/editors/include/UI_abstract_view.hh b/source/blender/editors/include/UI_abstract_view.hh index dfddace8899..e2f395ec203 100644 --- a/source/blender/editors/include/UI_abstract_view.hh +++ b/source/blender/editors/include/UI_abstract_view.hh @@ -27,7 +27,6 @@ struct bContext; struct uiBlock; -struct uiBut; struct uiLayout; struct uiViewItemHandle; struct wmDrag; diff --git a/source/blender/editors/include/UI_grid_view.hh b/source/blender/editors/include/UI_grid_view.hh index 402c0c8512f..6f3dfa1978b 100644 --- a/source/blender/editors/include/UI_grid_view.hh +++ b/source/blender/editors/include/UI_grid_view.hh @@ -17,12 +17,10 @@ #include "UI_resources.h" struct bContext; -struct PreviewImage; struct uiBlock; struct uiButViewItem; struct uiLayout; struct View2D; -struct wmNotifier; namespace blender::ui { diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 0705052921e..cdc41ef2183 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -22,10 +22,8 @@ extern "C" { struct ARegion; struct AssetFilterSettings; struct AssetHandle; -struct AssetMetaData; struct AutoComplete; struct EnumPropertyItem; -struct FileDirEntry; struct FileSelectParams; struct ID; struct IDProperty; @@ -48,7 +46,6 @@ struct bNodeTree; struct bScreen; struct rctf; struct rcti; -struct uiBlockInteraction_Handle; struct uiButSearch; struct uiFontStyle; struct uiList; diff --git a/source/blender/editors/interface/interface_handlers.cc b/source/blender/editors/interface/interface_handlers.cc index 44a14f254c0..63e415b07aa 100644 --- a/source/blender/editors/interface/interface_handlers.cc +++ b/source/blender/editors/interface/interface_handlers.cc @@ -150,6 +150,8 @@ /** \name Local Prototypes * \{ */ +struct uiBlockInteraction_Handle; + static int ui_do_but_EXIT(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event); static bool ui_but_find_select_in_enum__cmp(const uiBut *but_a, const uiBut *but_b); static void ui_textedit_string_set(uiBut *but, uiHandleButtonData *data, const char *str); diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index fe7af557f2f..f9804144fb0 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -19,8 +19,6 @@ #include "UI_view2d.h" struct ARegion; -struct ARegionType; -struct Main; struct NodeInsertOfsData; struct View2D; struct bContext; diff --git a/source/blender/editors/space_spreadsheet/spreadsheet_column_values.hh b/source/blender/editors/space_spreadsheet/spreadsheet_column_values.hh index 7cf9238d34e..31902c11518 100644 --- a/source/blender/editors/space_spreadsheet/spreadsheet_column_values.hh +++ b/source/blender/editors/space_spreadsheet/spreadsheet_column_values.hh @@ -9,8 +9,6 @@ namespace blender::ed::spreadsheet { -struct CellDrawParams; - eSpreadsheetColumnValueType cpp_type_to_column_type(const CPPType &type); /** diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 08d42471998..bfc2cf5214a 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -28,7 +28,6 @@ struct wmGizmoGroupType; struct wmGizmoType; struct wmKeyConfig; struct wmOperatorType; -struct wmWindowManager; /* view3d_header.c */ diff --git a/source/blender/editors/space_view3d/view3d_navigate.h b/source/blender/editors/space_view3d/view3d_navigate.h index 7342b8cc7cb..46dacbc606f 100644 --- a/source/blender/editors/space_view3d/view3d_navigate.h +++ b/source/blender/editors/space_view3d/view3d_navigate.h @@ -28,7 +28,6 @@ struct View3D; struct bContext; struct rcti; struct wmEvent; -struct wmOperator; enum eV3D_OpPropFlag { V3D_OP_PROP_MOUSE_CO = (1 << 0), diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 13362cee2b6..637e4ef3b6e 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -28,7 +28,6 @@ extern "C" { * \{ */ struct ARegion; -struct BMPartialUpdate; struct Depsgraph; struct NumInput; struct Object; diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h index c3d2a1d86d9..dd1e305762d 100644 --- a/source/blender/editors/transform/transform_convert.h +++ b/source/blender/editors/transform/transform_convert.h @@ -17,7 +17,6 @@ extern "C" { struct BMEditMesh; struct BMesh; struct BezTriple; -struct FCurve; struct ListBase; struct Object; struct TransData; diff --git a/source/blender/editors/transform/transform_mode.h b/source/blender/editors/transform/transform_mode.h index b782d27a3c6..6fc82a484bd 100644 --- a/source/blender/editors/transform/transform_mode.h +++ b/source/blender/editors/transform/transform_mode.h @@ -8,7 +8,6 @@ #pragma once -struct AnimData; struct LinkNode; struct TransData; struct TransDataContainer; diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 5a6db911ee5..3cf64edaa6e 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -11,7 +11,6 @@ extern "C" { #endif -struct GPUIndexBuf; struct GPUVertBuf; /** Opaque type hiding #blender::gpu::shader::ShaderCreateInfo */ diff --git a/source/blender/gpu/GPU_storage_buffer.h b/source/blender/gpu/GPU_storage_buffer.h index 8837a7c7647..8ed60d9000a 100644 --- a/source/blender/gpu/GPU_storage_buffer.h +++ b/source/blender/gpu/GPU_storage_buffer.h @@ -20,8 +20,6 @@ extern "C" { #endif -struct ListBase; - /** Opaque type hiding blender::gpu::StorageBuf. */ typedef struct GPUStorageBuf GPUStorageBuf; diff --git a/source/blender/gpu/GPU_viewport.h b/source/blender/gpu/GPU_viewport.h index be989635f84..2f326c2f680 100644 --- a/source/blender/gpu/GPU_viewport.h +++ b/source/blender/gpu/GPU_viewport.h @@ -25,8 +25,6 @@ typedef struct GHash GHash; typedef struct GPUViewport GPUViewport; struct DRWData; -struct DefaultFramebufferList; -struct DefaultTextureList; struct GPUFrameBuffer; GPUViewport *GPU_viewport_create(void); diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h index 2fb1d814c83..c60fc7d5563 100644 --- a/source/blender/imbuf/IMB_colormanagement.h +++ b/source/blender/imbuf/IMB_colormanagement.h @@ -19,7 +19,6 @@ extern "C" { struct ColorManagedColorspaceSettings; struct ColorManagedDisplaySettings; struct ColorManagedViewSettings; -struct ColorManagedOutputSettings; struct ColormanageProcessor; struct EnumPropertyItem; struct ImBuf; diff --git a/source/blender/io/usd/intern/usd_reader_prim.h b/source/blender/io/usd/intern/usd_reader_prim.h index c44c4a14ad7..377228929ff 100644 --- a/source/blender/io/usd/intern/usd_reader_prim.h +++ b/source/blender/io/usd/intern/usd_reader_prim.h @@ -10,6 +10,7 @@ #include #include +struct CacheFile; struct Main; struct Material; struct Object; diff --git a/source/blender/io/usd/intern/usd_writer_material.h b/source/blender/io/usd/intern/usd_writer_material.h index 3e9b84477d5..fdfd13871ff 100644 --- a/source/blender/io/usd/intern/usd_writer_material.h +++ b/source/blender/io/usd/intern/usd_writer_material.h @@ -9,9 +9,6 @@ #include struct Material; -struct USDExportParams; -struct bNode; -struct bNodeTree; namespace blender::io::usd { diff --git a/source/blender/io/usd/usd.h b/source/blender/io/usd/usd.h index 98979eb9c13..9d5cda64424 100644 --- a/source/blender/io/usd/usd.h +++ b/source/blender/io/usd/usd.h @@ -10,7 +10,6 @@ extern "C" { #endif struct CacheArchiveHandle; -struct CacheFile; struct CacheReader; struct Object; struct bContext; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index c0ea55885d0..6e39ad0d4f7 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -53,10 +53,8 @@ struct bGPdata; struct bNodeInstanceHash; struct bNodeLink; struct bNodePreview; -struct bNodeTreeExec; struct bNodeType; struct bNode; -struct uiBlock; #define NODE_MAXSTR 64 diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 0b7c483b7d0..4c5ba4c43f8 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -12,7 +12,6 @@ struct Object; struct RenderEngine; struct SmoothView3DStore; struct SpaceLink; -struct ViewDepths; struct bGPdata; struct wmTimer; diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 6e5bb593d22..3c2fd5af543 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -23,7 +23,6 @@ struct wmWindow; struct wmWindowManager; struct wmEvent; -struct wmGesture; struct wmKeyConfig; struct wmKeyMap; struct wmMsgBus; diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 57aea23024f..b39bc6de7e5 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -20,11 +20,9 @@ extern "C" { #define RNA_MAGIC ((int)~0) -struct AssetLibraryReference; struct FreestyleSettings; struct ID; struct IDOverrideLibrary; -struct IDOverrideLibraryenOperation; struct IDProperty; struct Main; struct Object; diff --git a/source/blender/modifiers/MOD_nodes.h b/source/blender/modifiers/MOD_nodes.h index 4a3ccd8ecd1..b3c353e2347 100644 --- a/source/blender/modifiers/MOD_nodes.h +++ b/source/blender/modifiers/MOD_nodes.h @@ -2,7 +2,6 @@ #pragma once -struct Main; struct NodesModifierData; struct Object; diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh index 088e076be35..208d51f13d3 100644 --- a/source/blender/nodes/NOD_geometry_exec.hh +++ b/source/blender/nodes/NOD_geometry_exec.hh @@ -14,8 +14,6 @@ #include "NOD_derived_node_tree.hh" #include "NOD_geometry_nodes_lazy_function.hh" -struct ModifierData; - namespace blender::nodes { using bke::AnonymousAttributeFieldInput; diff --git a/source/blender/nodes/NOD_geometry_nodes_log.hh b/source/blender/nodes/NOD_geometry_nodes_log.hh index 95e54f1b9a5..3d453de4b78 100644 --- a/source/blender/nodes/NOD_geometry_nodes_log.hh +++ b/source/blender/nodes/NOD_geometry_nodes_log.hh @@ -40,8 +40,6 @@ #include "DNA_node_types.h" struct SpaceNode; -struct SpaceSpreadsheet; -struct NodesModifierData; namespace blender::nodes::geo_eval_log { diff --git a/source/blender/python/generic/idprop_py_ui_api.h b/source/blender/python/generic/idprop_py_ui_api.h index e3017c9ad0a..2a14960cd79 100644 --- a/source/blender/python/generic/idprop_py_ui_api.h +++ b/source/blender/python/generic/idprop_py_ui_api.h @@ -6,7 +6,6 @@ #pragma once -struct ID; struct IDProperty; extern PyTypeObject BPy_IDPropertyUIManager_Type; diff --git a/source/blender/python/gpu/gpu_py_offscreen.h b/source/blender/python/gpu/gpu_py_offscreen.h index b9fbc6aab3c..f8b49ac15a5 100644 --- a/source/blender/python/gpu/gpu_py_offscreen.h +++ b/source/blender/python/gpu/gpu_py_offscreen.h @@ -12,7 +12,6 @@ extern PyTypeObject BPyGPUOffScreen_Type; #define BPyGPUOffScreen_Check(v) (Py_TYPE(v) == &BPyGPUOffScreen_Type) -struct GPUOffscreen; struct GPUViewport; typedef struct BPyGPUOffScreen { diff --git a/source/blender/python/intern/bpy_capi_utils.h b/source/blender/python/intern/bpy_capi_utils.h index 73a5d2ebc79..7e24446eae5 100644 --- a/source/blender/python/intern/bpy_capi_utils.h +++ b/source/blender/python/intern/bpy_capi_utils.h @@ -14,7 +14,6 @@ extern "C" { #endif -struct EnumPropertyItem; struct ReportList; /* error reporting */ diff --git a/source/blender/render/RE_texture_margin.h b/source/blender/render/RE_texture_margin.h index fd8e41adb3a..62d3782c85e 100644 --- a/source/blender/render/RE_texture_margin.h +++ b/source/blender/render/RE_texture_margin.h @@ -11,7 +11,6 @@ extern "C" { #endif struct DerivedMesh; -struct IMBuf; struct ImBuf; struct Mesh; diff --git a/source/blender/render/intern/pipeline.h b/source/blender/render/intern/pipeline.h index e5da3cb8830..8ee29096dd1 100644 --- a/source/blender/render/intern/pipeline.h +++ b/source/blender/render/intern/pipeline.h @@ -7,7 +7,6 @@ #pragma once -struct ListBase; struct Render; struct RenderData; struct RenderLayer; diff --git a/source/blender/render/intern/render_result.h b/source/blender/render/intern/render_result.h index 6e971d45d31..6075dd3d396 100644 --- a/source/blender/render/intern/render_result.h +++ b/source/blender/render/intern/render_result.h @@ -18,10 +18,8 @@ struct ImBuf; struct ListBase; struct Render; struct RenderData; -struct RenderEngine; struct RenderLayer; struct RenderResult; -struct Scene; struct rcti; #ifdef __cplusplus diff --git a/source/blender/sequencer/SEQ_channels.h b/source/blender/sequencer/SEQ_channels.h index 197ad5e55de..83d055ab59c 100644 --- a/source/blender/sequencer/SEQ_channels.h +++ b/source/blender/sequencer/SEQ_channels.h @@ -13,7 +13,6 @@ extern "C" { struct Editing; struct ListBase; -struct Scene; struct SeqTimelineChannel; struct Sequence; diff --git a/source/blender/sequencer/SEQ_iterator.h b/source/blender/sequencer/SEQ_iterator.h index e5adb2a33b1..76475f4b964 100644 --- a/source/blender/sequencer/SEQ_iterator.h +++ b/source/blender/sequencer/SEQ_iterator.h @@ -13,7 +13,6 @@ extern "C" { #include "BLI_ghash.h" -struct Editing; struct GSet; struct GSetIterator; struct Sequence; diff --git a/source/blender/sequencer/SEQ_sequencer.h b/source/blender/sequencer/SEQ_sequencer.h index a77ca1c7baf..c795e6a684e 100644 --- a/source/blender/sequencer/SEQ_sequencer.h +++ b/source/blender/sequencer/SEQ_sequencer.h @@ -21,7 +21,6 @@ struct Depsgraph; struct Editing; struct Scene; struct Sequence; -struct SequenceLookup; struct SequencerToolSettings; /* RNA enums, just to be more readable */ diff --git a/source/blender/sequencer/SEQ_transform.h b/source/blender/sequencer/SEQ_transform.h index 30cf472f55b..28202dd252a 100644 --- a/source/blender/sequencer/SEQ_transform.h +++ b/source/blender/sequencer/SEQ_transform.h @@ -11,7 +11,6 @@ extern "C" { #endif -struct Editing; struct ListBase; struct Scene; struct SeqCollection; diff --git a/source/blender/sequencer/SEQ_utils.h b/source/blender/sequencer/SEQ_utils.h index 24ca7559166..f1679012ef3 100644 --- a/source/blender/sequencer/SEQ_utils.h +++ b/source/blender/sequencer/SEQ_utils.h @@ -16,7 +16,6 @@ extern "C" { struct ListBase; struct Mask; struct Scene; -struct SeqRenderData; struct Sequence; struct StripElem; diff --git a/source/blender/sequencer/intern/effects.h b/source/blender/sequencer/intern/effects.h index c15701a2047..5ec6cb9eb19 100644 --- a/source/blender/sequencer/intern/effects.h +++ b/source/blender/sequencer/intern/effects.h @@ -12,7 +12,6 @@ extern "C" { #endif struct Scene; -struct SeqRenderData; struct Sequence; struct SeqEffectHandle seq_effect_get_sequence_blend(struct Sequence *seq); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 37dce4db61d..ee0cba5ec7c 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -26,7 +26,6 @@ extern "C" { struct ARegion; struct AssetHandle; -struct AssetLibraryReference; struct GHashIterator; struct GPUViewport; struct ID; @@ -39,7 +38,6 @@ struct MenuType; struct PointerRNA; struct PropertyRNA; struct ScrArea; -struct SelectPick_Params; struct View3D; struct ViewLayer; struct bContext; From c1d360f7fb88ea842829d84c2bbf345e956f58ad Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Wed, 18 Jan 2023 10:38:01 +0100 Subject: [PATCH 0730/1522] Fix urls in LTS script. The urls were missing /release/, leading to 404 links on the LTS download page. --- release/lts/create_download_urls.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/lts/create_download_urls.py b/release/lts/create_download_urls.py index 753e05c98b4..c6b01acdf60 100755 --- a/release/lts/create_download_urls.py +++ b/release/lts/create_download_urls.py @@ -41,7 +41,7 @@ def get_download_url(version: Version, file_name: str) -> str: """ Get the download url for the given version and file_name """ - return (f"https://www.blender.org/download/Blender{version.major}" + return (f"https://www.blender.org/download/release/Blender{version.major}" f".{version.minor}/{file_name}") From 2c2178549b6c80154184958a55978e1aac7af6fc Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 18 Jan 2023 11:52:27 +0100 Subject: [PATCH 0731/1522] Curves: add OffsetIndices abstraction This changes how we access the points that correspond to each curve in a `CurvesGeometry`. Previously, `CurvesGeometry::points_for_curve(int curve_index) -> IndexRange` was called for every curve in many loops. Now one has to call `CurvesGeometry::points_by_curve() -> OffsetIndices` before the loop and use the returned value inside the loop. While this is a little bit more verbose in general, it has some benefits: * Better standardization of how "offset indices" are used. The new data structure can be used independent of curves. * Allows for better data oriented design. Generally, we want to retrieve all the arrays we need for a loop first and then do the processing. Accessing the old `CurvesGeometry::points_for_curve(...)` did not follow that design because it hid the underlying offset array. * Makes it easier to pass the offsets to a function without having to pass the entire `CurvesGeometry`. * Can improve performance in theory due to one less memory access because `this` does not have to be dereferenced every time. This likely doesn't have a noticable impact in practice. Differential Revision: https://developer.blender.org/D17025 --- source/blender/blenkernel/BKE_curves.hh | 46 +++--------- source/blender/blenkernel/BKE_curves_utils.hh | 5 -- .../blenkernel/intern/curve_legacy_convert.cc | 7 +- .../intern/curve_to_mesh_convert.cc | 3 +- .../blenkernel/intern/curves_geometry.cc | 48 ++++++++----- .../blender/blenkernel/intern/curves_utils.cc | 35 ++++------ .../intern/geometry_component_curves.cc | 3 +- source/blender/blenlib/BLI_offset_indices.hh | 70 +++++++++++++++++++ source/blender/blenlib/CMakeLists.txt | 2 + .../blender/blenlib/intern/offset_indices.cc | 19 +++++ .../draw/intern/draw_cache_impl_curves.cc | 14 ++-- source/blender/draw/intern/draw_curves.cc | 2 +- .../editors/curves/intern/curves_add.cc | 3 +- .../editors/curves/intern/curves_ops.cc | 11 +-- .../editors/curves/intern/curves_selection.cc | 3 +- .../sculpt_paint/curves_sculpt_brush.cc | 4 +- .../sculpt_paint/curves_sculpt_comb.cc | 12 ++-- .../sculpt_paint/curves_sculpt_delete.cc | 9 ++- .../sculpt_paint/curves_sculpt_grow_shrink.cc | 15 ++-- .../editors/sculpt_paint/curves_sculpt_ops.cc | 11 +-- .../sculpt_paint/curves_sculpt_pinch.cc | 12 ++-- .../sculpt_paint/curves_sculpt_puff.cc | 15 ++-- .../curves_sculpt_selection_paint.cc | 6 +- .../sculpt_paint/curves_sculpt_slide.cc | 3 +- .../sculpt_paint/curves_sculpt_smooth.cc | 9 ++- .../sculpt_paint/curves_sculpt_snake_hook.cc | 6 +- .../geometry/intern/add_curves_on_mesh.cc | 13 ++-- .../blender/geometry/intern/fillet_curves.cc | 19 +++-- .../geometry/intern/resample_curves.cc | 30 ++++---- .../blender/geometry/intern/set_curve_type.cc | 41 ++++++----- .../geometry/intern/subdivide_curves.cc | 25 ++++--- source/blender/geometry/intern/trim_curves.cc | 47 ++++++++----- .../geometry/nodes/node_geo_blur_attribute.cc | 5 +- .../node_geo_curve_endpoint_selection.cc | 3 +- .../node_geo_curve_handle_type_selection.cc | 3 +- .../geometry/nodes/node_geo_curve_sample.cc | 3 +- .../nodes/node_geo_curve_spline_parameter.cc | 9 ++- ...node_geo_curve_topology_points_of_curve.cc | 8 ++- .../node_geo_deform_curves_on_surface.cc | 4 +- .../nodes/node_geo_duplicate_elements.cc | 24 ++++--- .../nodes/node_geo_input_spline_length.cc | 3 +- .../geometry/nodes/node_geo_input_tangent.cc | 3 +- .../nodes/node_geo_offset_point_in_curve.cc | 6 +- 43 files changed, 399 insertions(+), 220 deletions(-) create mode 100644 source/blender/blenlib/BLI_offset_indices.hh create mode 100644 source/blender/blenlib/intern/offset_indices.cc diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index 1ed872c8ab8..6569629c71f 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -18,6 +18,7 @@ #include "BLI_generic_virtual_array.hh" #include "BLI_index_mask.hh" #include "BLI_math_vector_types.hh" +#include "BLI_offset_indices.hh" #include "BLI_shared_cache.hh" #include "BLI_span.hh" #include "BLI_task.hh" @@ -164,23 +165,17 @@ class CurvesGeometry : public ::CurvesGeometry { IndexRange points_range() const; IndexRange curves_range() const; - /** - * Number of control points in the indexed curve. - */ - int points_num_for_curve(const int index) const; - /** * The index of the first point in every curve. The size of this span is one larger than the - * number of curves. Consider using #points_for_curve rather than using the offsets directly. + * number of curves. Consider using #points_by_curve rather than using the offsets directly. */ Span offsets() const; MutableSpan offsets_for_write(); /** - * Access a range of indices of point data for a specific curve. + * The offsets of every curve into arrays on the points domain. */ - IndexRange points_for_curve(int index) const; - IndexRange points_for_curves(IndexRange curves) const; + OffsetIndices points_by_curve() const; /** The type (#CurveType) of each curve, or potentially a single if all are the same type. */ VArray curve_types() const; @@ -852,16 +847,6 @@ inline IndexRange CurvesGeometry::curves_range() const return IndexRange(this->curves_num()); } -inline int CurvesGeometry::points_num_for_curve(const int index) const -{ - BLI_assert(this->curve_num > 0); - BLI_assert(this->curve_num > index); - BLI_assert(this->curve_offsets != nullptr); - const int offset = this->curve_offsets[index]; - const int offset_next = this->curve_offsets[index + 1]; - return offset_next - offset; -} - inline bool CurvesGeometry::is_single_type(const CurveType type) const { return this->curve_type_counts()[type] == this->curves_num(); @@ -884,25 +869,9 @@ inline const std::array &CurvesGeometry::curve_type_counts return this->runtime->type_counts; } -inline IndexRange CurvesGeometry::points_for_curve(const int index) const +inline OffsetIndices CurvesGeometry::points_by_curve() const { - /* Offsets are not allocated when there are no curves. */ - BLI_assert(this->curve_num > 0); - BLI_assert(this->curve_num > index); - BLI_assert(this->curve_offsets != nullptr); - const int offset = this->curve_offsets[index]; - const int offset_next = this->curve_offsets[index + 1]; - return {offset, offset_next - offset}; -} - -inline IndexRange CurvesGeometry::points_for_curves(const IndexRange curves) const -{ - /* Offsets are not allocated when there are no curves. */ - BLI_assert(this->curve_num > 0); - BLI_assert(this->curve_offsets != nullptr); - const int offset = this->curve_offsets[curves.start()]; - const int offset_next = this->curve_offsets[curves.one_after_last()]; - return {offset, offset_next - offset}; + return OffsetIndices({this->curve_offsets, this->curve_num + 1}); } inline int CurvesGeometry::evaluated_points_num() const @@ -928,7 +897,8 @@ inline IndexRange CurvesGeometry::evaluated_points_for_curves(const IndexRange c inline Span CurvesGeometry::bezier_evaluated_offsets_for_curve(const int curve_index) const { - const IndexRange points = this->points_for_curve(curve_index); + const OffsetIndices points_by_curve = this->points_by_curve(); + const IndexRange points = points_by_curve[curve_index]; return this->runtime->bezier_evaluated_offsets.as_span().slice(points); } diff --git a/source/blender/blenkernel/BKE_curves_utils.hh b/source/blender/blenkernel/BKE_curves_utils.hh index 77998b24a32..144f934414a 100644 --- a/source/blender/blenkernel/BKE_curves_utils.hh +++ b/source/blender/blenkernel/BKE_curves_utils.hh @@ -532,11 +532,6 @@ void fill_curve_counts(const bke::CurvesGeometry &curves, Span curve_ranges, MutableSpan counts); -/** - * Turn an array of sizes into the offset at each index including all previous sizes. - */ -void accumulate_counts_to_offsets(MutableSpan counts_to_offsets, int start_offset = 0); - IndexMask indices_for_type(const VArray &types, const std::array &type_counts, const CurveType type, diff --git a/source/blender/blenkernel/intern/curve_legacy_convert.cc b/source/blender/blenkernel/intern/curve_legacy_convert.cc index 938dcbd6269..f82d931114e 100644 --- a/source/blender/blenkernel/intern/curve_legacy_convert.cc +++ b/source/blender/blenkernel/intern/curve_legacy_convert.cc @@ -108,6 +108,7 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_ return curves_id; } + const OffsetIndices points_by_curve = curves.points_by_curve(); MutableSpan positions = curves.positions_for_write(); SpanAttributeWriter radius_attribute = curves_attributes.lookup_or_add_for_write_only_span("radius", ATTR_DOMAIN_POINT); @@ -119,7 +120,7 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_ for (const int curve_i : selection.slice(range)) { const Nurb &src_curve = *src_curves[curve_i]; const Span src_points(src_curve.bp, src_curve.pntsu); - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int i : src_points.index_range()) { const BPoint &bp = src_points[i]; @@ -146,7 +147,7 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_ for (const int curve_i : selection.slice(range)) { const Nurb &src_curve = *src_curves[curve_i]; const Span src_points(src_curve.bezt, src_curve.pntsu); - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; resolutions[curve_i] = src_curve.resolu; @@ -174,7 +175,7 @@ Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_ for (const int curve_i : selection.slice(range)) { const Nurb &src_curve = *src_curves[curve_i]; const Span src_points(src_curve.bp, src_curve.pntsu); - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; resolutions[curve_i] = src_curve.resolu; nurbs_orders[curve_i] = src_curve.orderu; diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index 481e3018942..9fd35fbfb65 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -633,10 +633,11 @@ static void write_sharp_bezier_edges(const CurvesInfo &curves_info, sharp_edges = mesh_attributes.lookup_or_add_for_write_span("sharp_edge", ATTR_DOMAIN_EDGE); + const OffsetIndices profile_points_by_curve = profile.points_by_curve(); const VArray types = profile.curve_types(); foreach_curve_combination(curves_info, offsets, [&](const CombinationInfo &info) { if (types[info.i_profile] == CURVE_TYPE_BEZIER) { - const IndexRange points = profile.points_for_curve(info.i_profile); + const IndexRange points = profile_points_by_curve[info.i_profile]; mark_bezier_vector_edges_sharp(points.size(), info.main_segment_num, profile.bezier_evaluated_offsets_for_curve(info.i_profile), diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 3d4f81019a7..3ca951858c6 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -457,6 +457,7 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves, MutableSpan offsets, MutableSpan bezier_evaluated_offsets) { + const OffsetIndices points_by_curve = curves.points_by_curve(); VArray types = curves.curve_types(); VArray resolution = curves.resolution(); VArray cyclic = curves.cyclic(); @@ -468,7 +469,7 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves, VArray nurbs_knots_modes = curves.nurbs_knots_modes(); build_offsets(offsets, [&](const int curve_index) -> int { - const IndexRange points = curves.points_for_curve(curve_index); + const IndexRange points = points_by_curve[curve_index]; switch (types[curve_index]) { case CURVE_TYPE_CATMULL_ROM: return curves::catmull_rom::calculate_evaluated_num( @@ -533,9 +534,10 @@ IndexMask CurvesGeometry::indices_for_curve_type(const CurveType type, Array CurvesGeometry::point_to_curve_map() const { + const OffsetIndices points_by_curve = this->points_by_curve(); Array map(this->points_num()); for (const int i : this->curves_range()) { - map.as_mutable_span().slice(this->points_for_curve(i)).fill(i); + map.as_mutable_span().slice(points_by_curve[i]).fill(i); } return map; } @@ -552,13 +554,14 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const this->runtime->nurbs_basis_cache.resize(this->curves_num()); MutableSpan basis_caches(this->runtime->nurbs_basis_cache); + const OffsetIndices points_by_curve = this->points_by_curve(); VArray cyclic = this->cyclic(); VArray orders = this->nurbs_orders(); VArray knots_modes = this->nurbs_knots_modes(); threading::parallel_for(nurbs_mask.index_range(), 64, [&](const IndexRange range) { for (const int curve_index : nurbs_mask.slice(range)) { - const IndexRange points = this->points_for_curve(curve_index); + const IndexRange points = points_by_curve[curve_index]; const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); const int8_t order = orders[curve_index]; @@ -597,6 +600,7 @@ Span CurvesGeometry::evaluated_positions() const MutableSpan evaluated_positions = this->runtime->evaluated_position_cache; this->runtime->evaluated_positions_span = evaluated_positions; + const OffsetIndices points_by_curve = this->points_by_curve(); VArray types = this->curve_types(); VArray cyclic = this->cyclic(); VArray resolution = this->resolution(); @@ -613,7 +617,7 @@ Span CurvesGeometry::evaluated_positions() const threading::parallel_for(this->curves_range(), 128, [&](IndexRange curves_range) { for (const int curve_index : curves_range) { - const IndexRange points = this->points_for_curve(curve_index); + const IndexRange points = points_by_curve[curve_index]; const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); switch (types[curve_index]) { @@ -677,6 +681,7 @@ Span CurvesGeometry::evaluated_tangents() const Vector bezier_indices; const IndexMask bezier_mask = this->indices_for_curve_type(CURVE_TYPE_BEZIER, bezier_indices); if (!bezier_mask.is_empty()) { + const OffsetIndices points_by_curve = this->points_by_curve(); const Span positions = this->positions(); const Span handles_left = this->handle_positions_left(); const Span handles_right = this->handle_positions_right(); @@ -686,7 +691,7 @@ Span CurvesGeometry::evaluated_tangents() const if (cyclic[curve_index]) { continue; } - const IndexRange points = this->points_for_curve(curve_index); + const IndexRange points = points_by_curve[curve_index]; const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); const float epsilon = 1e-6f; @@ -753,6 +758,7 @@ static void evaluate_generic_data_for_curve( Span CurvesGeometry::evaluated_normals() const { this->runtime->normal_cache_mutex.ensure([&]() { + const OffsetIndices points_by_curve = this->points_by_curve(); const VArray types = this->curve_types(); const VArray cyclic = this->cyclic(); const VArray normal_mode = this->normal_mode(); @@ -792,7 +798,7 @@ Span CurvesGeometry::evaluated_normals() const /* If the "tilt" attribute exists, rotate the normals around the tangents by the * evaluated angles. We can avoid copying the tilts to evaluate them for poly curves. */ if (use_tilt) { - const IndexRange points = this->points_for_curve(curve_index); + const IndexRange points = points_by_curve[curve_index]; if (types[curve_index] == CURVE_TYPE_POLY) { rotate_directions_around_axes(evaluated_normals.slice(evaluated_points), evaluated_tangents.slice(evaluated_points), @@ -828,7 +834,8 @@ void CurvesGeometry::interpolate_to_evaluated(const int curve_index, { BLI_assert(this->runtime->offsets_cache_mutex.is_cached()); BLI_assert(this->runtime->nurbs_basis_cache_mutex.is_cached()); - const IndexRange points = this->points_for_curve(curve_index); + const OffsetIndices points_by_curve = this->points_by_curve(); + const IndexRange points = points_by_curve[curve_index]; BLI_assert(src.size() == points.size()); BLI_assert(dst.size() == this->evaluated_points_for_curve(curve_index).size()); evaluate_generic_data_for_curve(curve_index, @@ -848,6 +855,7 @@ void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst) { BLI_assert(this->runtime->offsets_cache_mutex.is_cached()); BLI_assert(this->runtime->nurbs_basis_cache_mutex.is_cached()); + const OffsetIndices points_by_curve = this->points_by_curve(); const VArray types = this->curve_types(); const VArray resolution = this->resolution(); const VArray cyclic = this->cyclic(); @@ -856,7 +864,7 @@ void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst) threading::parallel_for(this->curves_range(), 512, [&](IndexRange curves_range) { for (const int curve_index : curves_range) { - const IndexRange points = this->points_for_curve(curve_index); + const IndexRange points = points_by_curve[curve_index]; const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); evaluate_generic_data_for_curve(curve_index, points, @@ -973,6 +981,7 @@ void CurvesGeometry::calculate_bezier_auto_handles() if (this->handle_positions_left().is_empty() || this->handle_positions_right().is_empty()) { return; } + const OffsetIndices points_by_curve = this->points_by_curve(); const VArray types = this->curve_types(); const VArray cyclic = this->cyclic(); const VArraySpan types_left{this->handle_types_left()}; @@ -984,7 +993,7 @@ void CurvesGeometry::calculate_bezier_auto_handles() threading::parallel_for(this->curves_range(), 128, [&](IndexRange range) { for (const int i_curve : range) { if (types[i_curve] == CURVE_TYPE_BEZIER) { - const IndexRange points = this->points_for_curve(i_curve); + const IndexRange points = points_by_curve[i_curve]; curves::bezier::calculate_auto_handles(cyclic[i_curve], types_left.slice(points), types_right.slice(points), @@ -1071,10 +1080,11 @@ static void copy_with_map(const GSpan src, const Span map, GMutableSpan dst */ static Array build_point_to_curve_map(const CurvesGeometry &curves) { + const OffsetIndices points_by_curve = curves.points_by_curve(); Array point_to_curve_map(curves.points_num()); threading::parallel_for(curves.curves_range(), 1024, [&](const IndexRange curves_range) { for (const int i_curve : curves_range) { - point_to_curve_map.as_mutable_span().slice(curves.points_for_curve(i_curve)).fill(i_curve); + point_to_curve_map.as_mutable_span().slice(points_by_curve[i_curve]).fill(i_curve); } }); return point_to_curve_map; @@ -1202,6 +1212,7 @@ static CurvesGeometry copy_with_removed_curves( const IndexMask curves_to_delete, const AnonymousAttributePropagationInfo &propagation_info) { + const OffsetIndices old_points_by_curve = curves.points_by_curve(); const Span old_offsets = curves.offsets(); const Vector old_curve_ranges = curves_to_delete.extract_ranges_invert( curves.curves_range(), nullptr); @@ -1214,7 +1225,7 @@ static CurvesGeometry copy_with_removed_curves( new_curve_ranges.append(IndexRange(new_tot_curves, curve_range.size())); new_tot_curves += curve_range.size(); - const IndexRange old_point_range = curves.points_for_curves(curve_range); + const IndexRange old_point_range = old_points_by_curve[curve_range]; old_point_ranges.append(old_point_range); new_point_ranges.append(IndexRange(new_tot_points, old_point_range.size())); new_tot_points += old_point_range.size(); @@ -1319,9 +1330,10 @@ static void reverse_curve_point_data(const CurvesGeometry &curves, const IndexMask curve_selection, MutableSpan data) { + const OffsetIndices points_by_curve = curves.points_by_curve(); threading::parallel_for(curve_selection.index_range(), 256, [&](IndexRange range) { for (const int curve_i : curve_selection.slice(range)) { - data.slice(curves.points_for_curve(curve_i)).reverse(); + data.slice(points_by_curve[curve_i]).reverse(); } }); } @@ -1332,9 +1344,10 @@ static void reverse_swap_curve_point_data(const CurvesGeometry &curves, MutableSpan data_a, MutableSpan data_b) { + const OffsetIndices points_by_curve = curves.points_by_curve(); threading::parallel_for(curve_selection.index_range(), 256, [&](IndexRange range) { for (const int curve_i : curve_selection.slice(range)) { - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; MutableSpan a = data_a.slice(points); MutableSpan b = data_b.slice(points); for (const int i : IndexRange(points.size() / 2)) { @@ -1440,9 +1453,10 @@ static void adapt_curve_domain_point_to_curve_impl(const CurvesGeometry &curves, { attribute_math::DefaultMixer mixer(r_values); + const OffsetIndices points_by_curve = curves.points_by_curve(); threading::parallel_for(curves.curves_range(), 128, [&](const IndexRange range) { for (const int i_curve : range) { - for (const int i_point : curves.points_for_curve(i_curve)) { + for (const int i_point : points_by_curve[i_curve]) { mixer.mix_in(i_curve, old_values[i_point]); } } @@ -1462,9 +1476,10 @@ void adapt_curve_domain_point_to_curve_impl(const CurvesGeometry &curves, const VArray &old_values, MutableSpan r_values) { + const OffsetIndices points_by_curve = curves.points_by_curve(); r_values.fill(true); for (const int i_curve : IndexRange(curves.curves_num())) { - for (const int i_point : curves.points_for_curve(i_curve)) { + for (const int i_point : points_by_curve[i_curve]) { if (!old_values[i_point]) { r_values[i_curve] = false; break; @@ -1500,8 +1515,9 @@ static void adapt_curve_domain_curve_to_point_impl(const CurvesGeometry &curves, const VArray &old_values, MutableSpan r_values) { + const OffsetIndices points_by_curve = curves.points_by_curve(); for (const int i_curve : IndexRange(curves.curves_num())) { - r_values.slice(curves.points_for_curve(i_curve)).fill(old_values[i_curve]); + r_values.slice(points_by_curve[i_curve]).fill(old_values[i_curve]); } } diff --git a/source/blender/blenkernel/intern/curves_utils.cc b/source/blender/blenkernel/intern/curves_utils.cc index f5a69a995a3..598f654b298 100644 --- a/source/blender/blenkernel/intern/curves_utils.cc +++ b/source/blender/blenkernel/intern/curves_utils.cc @@ -14,39 +14,30 @@ void fill_curve_counts(const bke::CurvesGeometry &curves, const Span curve_ranges, MutableSpan counts) { + const OffsetIndices points_by_curve = curves.points_by_curve(); threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange ranges_range) { for (const IndexRange curves_range : curve_ranges.slice(ranges_range)) { threading::parallel_for(curves_range, 4096, [&](IndexRange range) { for (const int i : range) { - counts[i] = curves.points_for_curve(i).size(); + counts[i] = points_by_curve.size(i); } }); } }); } -void accumulate_counts_to_offsets(MutableSpan counts_to_offsets, const int start_offset) -{ - int offset = start_offset; - for (const int i : counts_to_offsets.index_range().drop_back(1)) { - const int count = counts_to_offsets[i]; - BLI_assert(count > 0); - counts_to_offsets[i] = offset; - offset += count; - } - counts_to_offsets.last() = offset; -} - void copy_point_data(const CurvesGeometry &src_curves, const CurvesGeometry &dst_curves, const Span curve_ranges, const GSpan src, GMutableSpan dst) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange range) { for (const IndexRange range : curve_ranges.slice(range)) { - const IndexRange src_points = src_curves.points_for_curves(range); - const IndexRange dst_points = dst_curves.points_for_curves(range); + const IndexRange src_points = src_points_by_curve[range]; + const IndexRange dst_points = dst_points_by_curve[range]; /* The arrays might be large, so a threaded copy might make sense here too. */ dst.slice(dst_points).copy_from(src.slice(src_points)); } @@ -59,10 +50,12 @@ void copy_point_data(const CurvesGeometry &src_curves, const GSpan src, GMutableSpan dst) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(src_curve_selection.index_range(), 512, [&](IndexRange range) { for (const int i : src_curve_selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(i); - const IndexRange dst_points = dst_curves.points_for_curve(i); + const IndexRange src_points = src_points_by_curve[i]; + const IndexRange dst_points = dst_points_by_curve[i]; /* The arrays might be large, so a threaded copy might make sense here too. */ dst.slice(dst_points).copy_from(src.slice(src_points)); } @@ -76,10 +69,11 @@ void fill_points(const CurvesGeometry &curves, { BLI_assert(*value.type() == dst.type()); const CPPType &type = dst.type(); + const OffsetIndices points_by_curve = curves.points_by_curve(); threading::parallel_for(curve_selection.index_range(), 512, [&](IndexRange range) { for (const int i : curve_selection.slice(range)) { - const IndexRange points = curves.points_for_curve(i); - type.fill_assign_n(value.get(), dst.slice(curves.points_for_curve(i)).data(), points.size()); + const IndexRange points = points_by_curve[i]; + type.fill_assign_n(value.get(), dst.slice(points).data(), points.size()); } }); } @@ -91,9 +85,10 @@ void fill_points(const CurvesGeometry &curves, { BLI_assert(*value.type() == dst.type()); const CPPType &type = dst.type(); + const OffsetIndices points_by_curve = curves.points_by_curve(); threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange range) { for (const IndexRange range : curve_ranges.slice(range)) { - const IndexRange points = curves.points_for_curves(range); + const IndexRange points = points_by_curve[range]; type.fill_assign_n(value.get(), dst.slice(points).data(), points.size()); } }); diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index 075a6838704..4443a5c02c3 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -143,6 +143,7 @@ namespace blender::bke { static Array curve_normal_point_domain(const bke::CurvesGeometry &curves) { + const OffsetIndices points_by_curve = curves.points_by_curve(); const VArray types = curves.curve_types(); const VArray resolutions = curves.resolution(); const VArray curves_cyclic = curves.cyclic(); @@ -158,7 +159,7 @@ static Array curve_normal_point_domain(const bke::CurvesGeometry &curves Vector nurbs_tangents; for (const int i_curve : range) { - const IndexRange points = curves.points_for_curve(i_curve); + const IndexRange points = points_by_curve[i_curve]; const IndexRange evaluated_points = curves.evaluated_points_for_curve(i_curve); MutableSpan curve_normals = results.as_mutable_span().slice(points); diff --git a/source/blender/blenlib/BLI_offset_indices.hh b/source/blender/blenlib/BLI_offset_indices.hh new file mode 100644 index 00000000000..75526ed1025 --- /dev/null +++ b/source/blender/blenlib/BLI_offset_indices.hh @@ -0,0 +1,70 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include "BLI_index_range.hh" +#include "BLI_span.hh" + +namespace blender::offset_indices { + +/** + * References an array of ascending indices. A pair of consecutive indices encode an index range. + * Another common way to store the same kind of data is to store the start and size of every range + * separately. Using offsets instead halves the memory consumption. The downside is that the + * array has to be one element longer than the total number of ranges. The extra element is + * necessary to be able to get the last index range without requiring an extra branch for the case. + * + * This class is a thin wrapper around such an array that makes it easy to retrieve the index range + * at a specific index. + */ +template class OffsetIndices { + private: + static_assert(std::is_integral_v); + + Span offsets_; + + public: + OffsetIndices(const Span offsets) : offsets_(offsets) + { + BLI_assert(std::is_sorted(offsets_.begin(), offsets_.end())); + } + + T size(const int64_t index) const + { + BLI_assert(index >= 0); + BLI_assert(index < offsets_.size() - 1); + const int64_t begin = offsets_[index]; + const int64_t end = offsets_[index + 1]; + const int64_t size = end - begin; + return size; + } + + IndexRange operator[](const int64_t index) const + { + BLI_assert(index >= 0); + BLI_assert(index < offsets_.size() - 1); + const int64_t begin = offsets_[index]; + const int64_t end = offsets_[index + 1]; + const int64_t size = end - begin; + return IndexRange(begin, size); + } + + IndexRange operator[](const IndexRange indices) const + { + const int64_t begin = offsets_[indices.start()]; + const int64_t end = offsets_[indices.one_after_last()]; + const int64_t size = end - begin; + return IndexRange(begin, size); + } +}; + +/** + * Turn an array of sizes into the offset at each index including all previous sizes. + */ +void accumulate_counts_to_offsets(MutableSpan counts_to_offsets, int start_offset = 0); + +} // namespace blender::offset_indices + +namespace blender { +using offset_indices::OffsetIndices; +} diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 5ea563c1736..26a425ad3c9 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -117,6 +117,7 @@ set(SRC intern/mesh_intersect.cc intern/noise.c intern/noise.cc + intern/offset_indices.cc intern/path_util.c intern/polyfill_2d.c intern/polyfill_2d_beautify.c @@ -294,6 +295,7 @@ set(SRC BLI_multi_value_map.hh BLI_noise.h BLI_noise.hh + BLI_offset_indices.hh BLI_parameter_pack_utils.hh BLI_path_util.h BLI_polyfill_2d.h diff --git a/source/blender/blenlib/intern/offset_indices.cc b/source/blender/blenlib/intern/offset_indices.cc new file mode 100644 index 00000000000..fee57e32ffa --- /dev/null +++ b/source/blender/blenlib/intern/offset_indices.cc @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BLI_offset_indices.hh" + +namespace blender::offset_indices { + +void accumulate_counts_to_offsets(MutableSpan counts_to_offsets, const int start_offset) +{ + int offset = start_offset; + for (const int i : counts_to_offsets.index_range().drop_back(1)) { + const int count = counts_to_offsets[i]; + BLI_assert(count > 0); + counts_to_offsets[i] = offset; + offset += count; + } + counts_to_offsets.last() = offset; +} + +} // namespace blender::offset_indices diff --git a/source/blender/draw/intern/draw_cache_impl_curves.cc b/source/blender/draw/intern/draw_cache_impl_curves.cc index ba47ea576e0..0203554db4a 100644 --- a/source/blender/draw/intern/draw_cache_impl_curves.cc +++ b/source/blender/draw/intern/draw_cache_impl_curves.cc @@ -238,11 +238,12 @@ static void curves_batch_cache_fill_segments_proc_pos( using namespace blender; /* TODO: use hair radius layer if available. */ const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); + const OffsetIndices points_by_curve = curves.points_by_curve(); const Span positions = curves.positions(); threading::parallel_for(curves.curves_range(), 1024, [&](const IndexRange range) { for (const int i_curve : range) { - const IndexRange points = curves.points_for_curve(i_curve); + const IndexRange points = points_by_curve[i_curve]; Span curve_positions = positions.slice(points); MutableSpan curve_posTime_data = posTime_data.slice(points); @@ -334,6 +335,8 @@ static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id, GPU_vertbuf_init_with_format(cache.edit_points_data, &format_data); GPU_vertbuf_data_alloc(cache.edit_points_data, curves.points_num()); + const OffsetIndices points_by_curve = curves.points_by_curve(); + const VArray selection = curves.attributes().lookup_or_default( ".selection", eAttrDomain(curves_id.selection_domain), true); switch (curves_id.selection_domain) { @@ -346,7 +349,7 @@ static void curves_batch_cache_ensure_edit_points_data(const Curves &curves_id, case ATTR_DOMAIN_CURVE: for (const int curve_i : curves.curves_range()) { const float curve_selection = selection[curve_i] ? 1.0f : 0.0f; - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int point_i : points) { GPU_vertbuf_attr_set(cache.edit_points_data, color, point_i, &curve_selection); } @@ -367,8 +370,10 @@ static void curves_batch_cache_ensure_edit_lines(const Curves &curves_id, Curves GPUIndexBufBuilder elb; GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, index_len, vert_len); + const OffsetIndices points_by_curve = curves.points_by_curve(); + for (const int i : curves.curves_range()) { - const IndexRange points = curves.points_for_curve(i); + const IndexRange points = points_by_curve[i]; for (const int i_point : points) { GPU_indexbuf_add_generic_vert(&elb, i_point); } @@ -460,9 +465,10 @@ static void curves_batch_cache_fill_strands_data(const Curves &curves_id, { const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap( curves_id.geometry); + const blender::OffsetIndices points_by_curve = curves.points_by_curve(); for (const int i : IndexRange(curves.curves_num())) { - const IndexRange points = curves.points_for_curve(i); + const IndexRange points = points_by_curve[i]; *(uint *)GPU_vertbuf_raw_step(&data_step) = points.start(); *(ushort *)GPU_vertbuf_raw_step(&seg_step) = points.size() - 1; diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc index 62493df95f9..166d3ac8426 100644 --- a/source/blender/draw/intern/draw_curves.cc +++ b/source/blender/draw/intern/draw_curves.cc @@ -334,7 +334,7 @@ DRWShadingGroup *DRW_shgroup_curves_create_sub(Object *object, if (curves.curves_num() >= 1) { blender::VArray radii = curves.attributes().lookup_or_default( "radius", ATTR_DOMAIN_POINT, 0.005f); - const blender::IndexRange first_curve_points = curves.points_for_curve(0); + const blender::IndexRange first_curve_points = curves.points_by_curve()[0]; const float first_radius = radii[first_curve_points.first()]; const float last_radius = radii[first_curve_points.last()]; const float middle_radius = radii[first_curve_points.size() / 2]; diff --git a/source/blender/editors/curves/intern/curves_add.cc b/source/blender/editors/curves/intern/curves_add.cc index edcd1e32cc1..37a989b3234 100644 --- a/source/blender/editors/curves/intern/curves_add.cc +++ b/source/blender/editors/curves/intern/curves_add.cc @@ -112,8 +112,9 @@ bke::CurvesGeometry primitive_random_sphere(const int curves_size, const int poi RandomNumberGenerator rng; + const OffsetIndices points_by_curve = curves.points_by_curve(); for (const int i : curves.curves_range()) { - const IndexRange points = curves.points_for_curve(i); + const IndexRange points = points_by_curve[i]; MutableSpan curve_positions = positions.slice(points); MutableSpan curve_radii = radius.span.slice(points); diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 1a9bd13a15b..d084317014d 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -286,11 +286,12 @@ static void try_convert_single_object(Object &curves_ob, const bke::CurvesSurfaceTransforms transforms{curves_ob, &surface_ob}; const MFace *mfaces = (const MFace *)CustomData_get_layer(&surface_me.fdata, CD_MFACE); + const OffsetIndices points_by_curve = curves.points_by_curve(); const Span positions = surface_me.vert_positions(); for (const int new_hair_i : IndexRange(hair_num)) { const int curve_i = new_hair_i; - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const float3 &root_pos_cu = positions_cu[points.first()]; const float3 root_pos_su = transforms.curves_to_surface * root_pos_cu; @@ -440,6 +441,7 @@ static bke::CurvesGeometry particles_to_curves(Object &object, ParticleSystem &p const float4x4 world_to_object_mat = object_to_world_mat.inverted(); MutableSpan positions = curves.positions_for_write(); + const OffsetIndices points_by_curve = curves.points_by_curve(); const auto copy_hair_to_curves = [&](const Span hair_cache, const Span indices_to_transfer, @@ -448,7 +450,7 @@ static bke::CurvesGeometry particles_to_curves(Object &object, ParticleSystem &p for (const int i : range) { const int hair_i = indices_to_transfer[i]; const int curve_i = i + curve_index_offset; - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const Span keys{hair_cache[hair_i], points.size()}; for (const int key_i : keys.index_range()) { const float3 key_pos_wo = keys[key_i].co; @@ -554,6 +556,7 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, .typed(); } + const OffsetIndices points_by_curve = curves.points_by_curve(); MutableSpan positions_cu = curves.positions_for_write(); MutableSpan surface_uv_coords = curves.surface_uv_coords_for_write(); @@ -567,7 +570,7 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange curves_range) { for (const int curve_i : curves_range) { - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const int first_point_i = points.first(); const float3 old_first_point_pos_cu = positions_cu[first_point_i]; const float3 old_first_point_pos_su = transforms.curves_to_surface * @@ -625,7 +628,7 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob, threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange curves_range) { for (const int curve_i : curves_range) { - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const int first_point_i = points.first(); const float3 old_first_point_pos_cu = positions_cu[first_point_i]; diff --git a/source/blender/editors/curves/intern/curves_selection.cc b/source/blender/editors/curves/intern/curves_selection.cc index b36d18b5fbb..b9b3be976c5 100644 --- a/source/blender/editors/curves/intern/curves_selection.cc +++ b/source/blender/editors/curves/intern/curves_selection.cc @@ -32,9 +32,10 @@ static IndexMask retrieve_selected_curves(const bke::CurvesGeometry &curves, if (selection.is_single()) { return selection.get_internal_single() ? IndexMask(curves_range) : IndexMask(); } + const OffsetIndices points_by_curve = curves.points_by_curve(); return index_mask_ops::find_indices_based_on_predicate( curves_range, 512, r_indices, [&](const int64_t curve_i) { - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; /* The curve is selected if any of its points are selected. */ Array point_selection(points.size()); selection.materialize_compressed(points, point_selection); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc index 8172eb8a5d7..ead9b988829 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_brush.cc @@ -91,6 +91,8 @@ static std::optional find_curves_brush_position(const CurvesGeometry &cu } }; + const OffsetIndices points_by_curve = curves.points_by_curve(); + BrushPositionCandidate best_candidate = threading::parallel_reduce( curves.curves_range(), 128, @@ -99,7 +101,7 @@ static std::optional find_curves_brush_position(const CurvesGeometry &cu BrushPositionCandidate best_candidate = init; for (const int curve_i : curves_range) { - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; if (points.size() == 1) { const float3 &pos_cu = positions[points.first()]; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc index 024e4ac3849..c9b273aacb8 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_comb.cc @@ -189,6 +189,7 @@ struct CombOperationExecutor { MutableSpan positions_cu_orig = curves_orig_->positions_for_write(); const bke::crazyspace::GeometryDeformation deformation = bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *curves_ob_orig_); + const OffsetIndices points_by_curve = curves_orig_->points_by_curve(); float4x4 projection; ED_view3d_ob_project_mat_get(ctx_.rv3d, curves_ob_orig_, projection.values); @@ -200,7 +201,7 @@ struct CombOperationExecutor { Vector &local_changed_curves = r_changed_curves.local(); for (const int curve_i : curve_selection_.slice(range)) { bool curve_changed = false; - const IndexRange points = curves_orig_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int point_i : points.drop_front(1)) { const float3 old_pos_cu = deformation.positions[point_i]; const float3 old_symm_pos_cu = brush_transform_inv * old_pos_cu; @@ -295,12 +296,13 @@ struct CombOperationExecutor { const bke::crazyspace::GeometryDeformation deformation = bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *curves_ob_orig_); + const OffsetIndices points_by_curve = curves_orig_->points_by_curve(); threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { Vector &local_changed_curves = r_changed_curves.local(); for (const int curve_i : curve_selection_.slice(range)) { bool curve_changed = false; - const IndexRange points = curves_orig_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int point_i : points.drop_front(1)) { const float3 pos_old_cu = deformation.positions[point_i]; @@ -359,10 +361,11 @@ struct CombOperationExecutor { void initialize_segment_lengths() { const Span positions_cu = curves_orig_->positions(); + const OffsetIndices points_by_curve = curves_orig_->points_by_curve(); self_->segment_lengths_cu_.reinitialize(curves_orig_->points_num()); threading::parallel_for(curves_orig_->curves_range(), 128, [&](const IndexRange range) { for (const int curve_i : range) { - const IndexRange points = curves_orig_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int point_i : points.drop_back(1)) { const float3 &p1_cu = positions_cu[point_i]; const float3 &p2_cu = positions_cu[point_i + 1]; @@ -379,12 +382,13 @@ struct CombOperationExecutor { void restore_segment_lengths(EnumerableThreadSpecific> &changed_curves) { const Span expected_lengths_cu = self_->segment_lengths_cu_; + const OffsetIndices points_by_curve = curves_orig_->points_by_curve(); MutableSpan positions_cu = curves_orig_->positions_for_write(); threading::parallel_for_each(changed_curves, [&](const Vector &changed_curves) { threading::parallel_for(changed_curves.index_range(), 256, [&](const IndexRange range) { for (const int curve_i : changed_curves.as_span().slice(range)) { - const IndexRange points = curves_orig_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int segment_i : points.drop_back(1)) { const float3 &p1_cu = positions_cu[segment_i]; float3 &p2_cu = positions_cu[segment_i + 1]; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc index bad5b3ede71..08d61dad219 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_delete.cc @@ -140,10 +140,11 @@ struct DeleteOperationExecutor { /* Remove deleted curves from the stored deformed positions. */ const Vector ranges_to_keep = mask_to_delete.extract_ranges_invert( curves_->curves_range()); + const OffsetIndices points_by_curve = curves_->points_by_curve(); Vector new_deformed_positions; for (const IndexRange curves_range : ranges_to_keep) { new_deformed_positions.extend( - self_->deformed_positions_.as_span().slice(curves_->points_for_curves(curves_range))); + self_->deformed_positions_.as_span().slice(points_by_curve[curves_range])); } self_->deformed_positions_ = std::move(new_deformed_positions); @@ -172,10 +173,11 @@ struct DeleteOperationExecutor { const float brush_radius_re = brush_radius_base_re_ * brush_radius_factor_; const float brush_radius_sq_re = pow2f(brush_radius_re); + const OffsetIndices points_by_curve = curves_->points_by_curve(); threading::parallel_for(curve_selection_.index_range(), 512, [&](const IndexRange range) { for (const int curve_i : curve_selection_.slice(range)) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; if (points.size() == 1) { const float3 pos_cu = brush_transform_inv * self_->deformed_positions_[points.first()]; float2 pos_re; @@ -231,10 +233,11 @@ struct DeleteOperationExecutor { { const float brush_radius_cu = self_->brush_3d_.radius_cu * brush_radius_factor_; const float brush_radius_sq_cu = pow2f(brush_radius_cu); + const OffsetIndices points_by_curve = curves_->points_by_curve(); threading::parallel_for(curve_selection_.index_range(), 512, [&](const IndexRange range) { for (const int curve_i : curve_selection_.slice(range)) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; if (points.size() == 1) { const float3 &pos_cu = self_->deformed_positions_[points.first()]; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc index 4e9bc2fba2c..f84305de426 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_grow_shrink.cc @@ -88,13 +88,14 @@ class ShrinkCurvesEffect : public CurvesEffect { const Span curve_indices, const Span move_distances_cu) override { + const OffsetIndices points_by_curve = curves.points_by_curve(); MutableSpan positions_cu = curves.positions_for_write(); threading::parallel_for(curve_indices.index_range(), 256, [&](const IndexRange range) { ParameterizationBuffers data; for (const int influence_i : range) { const int curve_i = curve_indices[influence_i]; const float move_distance_cu = move_distances_cu[influence_i]; - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; this->shrink_curve(positions_cu.slice(points), move_distance_cu, data); } }); @@ -137,13 +138,14 @@ class ExtrapolateCurvesEffect : public CurvesEffect { const Span curve_indices, const Span move_distances_cu) override { + const OffsetIndices points_by_curve = curves.points_by_curve(); MutableSpan positions_cu = curves.positions_for_write(); threading::parallel_for(curve_indices.index_range(), 256, [&](const IndexRange range) { MoveAndResampleBuffers resample_buffer; for (const int influence_i : range) { const int curve_i = curve_indices[influence_i]; const float move_distance_cu = move_distances_cu[influence_i]; - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; if (points.size() <= 1) { continue; } @@ -178,12 +180,13 @@ class ScaleCurvesEffect : public CurvesEffect { const Span curve_indices, const Span move_distances_cu) override { + const OffsetIndices points_by_curve = curves.points_by_curve(); MutableSpan positions_cu = curves.positions_for_write(); threading::parallel_for(curve_indices.index_range(), 256, [&](const IndexRange range) { for (const int influence_i : range) { const int curve_i = curve_indices[influence_i]; const float move_distance_cu = move_distances_cu[influence_i]; - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const float old_length = this->compute_poly_curve_length(positions_cu.slice(points)); const float length_diff = scale_up_ ? move_distance_cu : -move_distance_cu; @@ -342,6 +345,7 @@ struct CurvesEffectOperationExecutor { { const bke::crazyspace::GeometryDeformation deformation = bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_); + const OffsetIndices points_by_curve = curves_->points_by_curve(); float4x4 projection; ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); @@ -360,7 +364,7 @@ struct CurvesEffectOperationExecutor { Influences &local_influences = influences_for_thread.local(); for (const int curve_i : curves_range) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const float curve_selection_factor = curve_selection_factors_[curve_i]; @@ -452,12 +456,13 @@ struct CurvesEffectOperationExecutor { const Vector symmetry_brush_transforms = get_symmetry_brush_transforms( eCurvesSymmetryType(curves_id_->symmetry)); + const OffsetIndices points_by_curve = curves_->points_by_curve(); threading::parallel_for(curves_->curves_range(), 256, [&](const IndexRange curves_range) { Influences &local_influences = influences_for_thread.local(); for (const int curve_i : curves_range) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; float max_move_distance_cu = 0.0f; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc index f12b94aea8f..444ab821cf1 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc @@ -370,13 +370,14 @@ static int select_random_exec(bContext *C, wmOperator *op) if (!was_anything_selected) { selection.fill(1.0f); } + const OffsetIndices points_by_curve = curves.points_by_curve(); switch (curves_id->selection_domain) { case ATTR_DOMAIN_POINT: { if (partial) { if (constant_per_curve) { for (const int curve_i : curves.curves_range()) { const float random_value = next_partial_random_value(); - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int point_i : points) { selection[point_i] *= random_value; } @@ -393,7 +394,7 @@ static int select_random_exec(bContext *C, wmOperator *op) if (constant_per_curve) { for (const int curve_i : curves.curves_range()) { const bool random_value = next_bool_random_value(); - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; if (!random_value) { selection.slice(points).fill(0.0f); } @@ -547,6 +548,7 @@ static int select_end_exec(bContext *C, wmOperator *op) if (!was_anything_selected) { curves::fill_selection_true(selection.span); } + const OffsetIndices points_by_curve = curves.points_by_curve(); selection.span.type().to_static_type_tag([&](auto type_tag) { using T = typename decltype(type_tag)::type; if constexpr (std::is_void_v) { @@ -556,7 +558,7 @@ static int select_end_exec(bContext *C, wmOperator *op) MutableSpan selection_typed = selection.span.typed(); threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) { for (const int curve_i : range) { - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; if (end_points) { selection_typed.slice(points.drop_back(amount)).fill(T(0)); } @@ -667,6 +669,7 @@ static int select_grow_update(bContext *C, wmOperator *op, const float mouse_dif const float distance = curve_op_data->pixel_to_distance_factor * mouse_diff_x; bke::SpanAttributeWriter selection = float_selection_ensure(curves_id); + const OffsetIndices points_by_curve = curves.points_by_curve(); /* Grow or shrink selection based on precomputed distances. */ switch (selection.domain) { @@ -680,7 +683,7 @@ static int select_grow_update(bContext *C, wmOperator *op, const float mouse_dif /* Propagate grown point selection to the curve selection. */ MutableSpan curves_selection = selection.span; for (const int curve_i : curves.curves_range()) { - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const Span points_selection = new_points_selection.as_span().slice(points); const float max_selection = *std::max_element(points_selection.begin(), points_selection.end()); diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc b/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc index 1677a7499c6..db1ad9c7bfb 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_pinch.cc @@ -160,6 +160,7 @@ struct PinchOperationExecutor { const bke::crazyspace::GeometryDeformation deformation = bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_); + const OffsetIndices points_by_curve = curves_->points_by_curve(); float4x4 projection; ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); @@ -169,7 +170,7 @@ struct PinchOperationExecutor { threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { for (const int curve_i : curve_selection_.slice(range)) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int point_i : points.drop_front(1)) { const float3 old_pos_cu = deformation.positions[point_i]; const float3 old_symm_pos_cu = brush_transform_inv * old_pos_cu; @@ -236,10 +237,11 @@ struct PinchOperationExecutor { const bke::crazyspace::GeometryDeformation deformation = bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_); + const OffsetIndices points_by_curve = curves_->points_by_curve(); threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { for (const int curve_i : curve_selection_.slice(range)) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int point_i : points.drop_front(1)) { const float3 old_pos_cu = deformation.positions[point_i]; @@ -269,10 +271,11 @@ struct PinchOperationExecutor { void initialize_segment_lengths() { const Span positions_cu = curves_->positions(); + const OffsetIndices points_by_curve = curves_->points_by_curve(); self_->segment_lengths_cu_.reinitialize(curves_->points_num()); threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { for (const int curve_i : curve_selection_.slice(range)) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int point_i : points.drop_back(1)) { const float3 &p1_cu = positions_cu[point_i]; const float3 &p2_cu = positions_cu[point_i + 1]; @@ -286,6 +289,7 @@ struct PinchOperationExecutor { void restore_segment_lengths(const Span changed_curves) { const Span expected_lengths_cu = self_->segment_lengths_cu_; + const OffsetIndices points_by_curve = curves_->points_by_curve(); MutableSpan positions_cu = curves_->positions_for_write(); threading::parallel_for(changed_curves.index_range(), 256, [&](const IndexRange range) { @@ -293,7 +297,7 @@ struct PinchOperationExecutor { if (!changed_curves[curve_i]) { continue; } - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int segment_i : IndexRange(points.size() - 1)) { const float3 &p1_cu = positions_cu[points[segment_i]]; float3 &p2_cu = positions_cu[points[segment_i] + 1]; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc index 2e84574bdae..e44e97bc840 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc @@ -182,11 +182,12 @@ struct PuffOperationExecutor { const bke::crazyspace::GeometryDeformation deformation = bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_); + const OffsetIndices points_by_curve = curves_->points_by_curve(); threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { for (const int curve_selection_i : range) { const int curve_i = curve_selection_[curve_selection_i]; - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const float3 first_pos_cu = brush_transform_inv * deformation.positions[points[0]]; float2 prev_pos_re; ED_view3d_project_float_v2_m4(ctx_.region, first_pos_cu, prev_pos_re, projection.values); @@ -242,11 +243,12 @@ struct PuffOperationExecutor { const bke::crazyspace::GeometryDeformation deformation = bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_); + const OffsetIndices points_by_curve = curves_->points_by_curve(); threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { for (const int curve_selection_i : range) { const int curve_i = curve_selection_[curve_selection_i]; - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int point_i : points.drop_front(1)) { const float3 &prev_pos_cu = deformation.positions[point_i - 1]; const float3 &pos_cu = deformation.positions[point_i]; @@ -269,13 +271,14 @@ struct PuffOperationExecutor { void puff(const Span curve_weights) { BLI_assert(curve_weights.size() == curve_selection_.size()); + const OffsetIndices points_by_curve = curves_->points_by_curve(); MutableSpan positions_cu = curves_->positions_for_write(); threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { Vector accumulated_lengths_cu; for (const int curve_selection_i : range) { const int curve_i = curve_selection_[curve_selection_i]; - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const int first_point_i = points[0]; const float3 first_pos_cu = positions_cu[first_point_i]; const float3 first_pos_su = transforms_.curves_to_surface * first_pos_cu; @@ -336,11 +339,12 @@ struct PuffOperationExecutor { void initialize_segment_lengths() { + const OffsetIndices points_by_curve = curves_->points_by_curve(); const Span positions_cu = curves_->positions(); self_->segment_lengths_cu_.reinitialize(curves_->points_num()); threading::parallel_for(curves_->curves_range(), 128, [&](const IndexRange range) { for (const int curve_i : range) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int point_i : points.drop_back(1)) { const float3 &p1_cu = positions_cu[point_i]; const float3 &p2_cu = positions_cu[point_i + 1]; @@ -354,11 +358,12 @@ struct PuffOperationExecutor { void restore_segment_lengths() { const Span expected_lengths_cu = self_->segment_lengths_cu_; + const OffsetIndices points_by_curve = curves_->points_by_curve(); MutableSpan positions_cu = curves_->positions_for_write(); threading::parallel_for(curves_->curves_range(), 256, [&](const IndexRange range) { for (const int curve_i : range) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int segment_i : points.drop_back(1)) { const float3 &p1_cu = positions_cu[segment_i]; float3 &p2_cu = positions_cu[segment_i + 1]; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc b/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc index c6fdb4a0926..190249c7c27 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection_paint.cc @@ -263,6 +263,7 @@ struct SelectionPaintOperationExecutor { const bke::crazyspace::GeometryDeformation deformation = bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_); + const OffsetIndices points_by_curve = curves_->points_by_curve(); float4x4 projection; ED_view3d_ob_project_mat_get(ctx_.rv3d, object_, projection.values); @@ -273,7 +274,7 @@ struct SelectionPaintOperationExecutor { threading::parallel_for(curves_->curves_range(), 1024, [&](const IndexRange curves_range) { for (const int curve_i : curves_range) { const float max_weight = threading::parallel_reduce( - curves_->points_for_curve(curve_i).drop_back(1), + points_by_curve[curve_i].drop_back(1), 1024, 0.0f, [&](const IndexRange segment_range, const float init) { @@ -330,6 +331,7 @@ struct SelectionPaintOperationExecutor { { const bke::crazyspace::GeometryDeformation deformation = bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_); + const OffsetIndices points_by_curve = curves_->points_by_curve(); const float brush_radius_cu = self_->brush_3d_.radius_cu; const float brush_radius_sq_cu = pow2f(brush_radius_cu); @@ -337,7 +339,7 @@ struct SelectionPaintOperationExecutor { threading::parallel_for(curves_->curves_range(), 1024, [&](const IndexRange curves_range) { for (const int curve_i : curves_range) { const float max_weight = threading::parallel_reduce( - curves_->points_for_curve(curve_i).drop_back(1), + points_by_curve[curve_i].drop_back(1), 1024, 0.0f, [&](const IndexRange segment_range, const float init) { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc index f21813d777c..6d716ad06a9 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_slide.cc @@ -317,6 +317,7 @@ struct SlideOperationExecutor { const Span positions_orig_su = surface_orig_->vert_positions(); const Span loops_orig = surface_orig_->loops(); + const OffsetIndices points_by_curve = curves_orig_->points_by_curve(); MutableSpan positions_orig_cu = curves_orig_->positions_for_write(); MutableSpan surface_uv_coords = curves_orig_->surface_uv_coords_for_write(); @@ -334,7 +335,7 @@ struct SlideOperationExecutor { threading::parallel_for(slide_curves.index_range(), 256, [&](const IndexRange range) { for (const SlideCurveInfo &slide_curve_info : slide_curves.slice(range)) { const int curve_i = slide_curve_info.curve_i; - const IndexRange points = curves_orig_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const int first_point_i = points[0]; const float3 old_first_pos_eval_cu = self_->initial_deformed_positions_cu_[first_point_i]; diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc b/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc index 9ef6333ad22..eb80b2e4025 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_smooth.cc @@ -138,10 +138,11 @@ struct SmoothOperationExecutor { const bke::crazyspace::GeometryDeformation deformation = bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_); + const OffsetIndices points_by_curve = curves_->points_by_curve(); threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { for (const int curve_i : curve_selection_.slice(range)) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int point_i : points) { const float3 &pos_cu = brush_transform_inv * deformation.positions[point_i]; float2 pos_re; @@ -194,10 +195,11 @@ struct SmoothOperationExecutor { const float brush_radius_sq_cu = pow2f(brush_radius_cu); const bke::crazyspace::GeometryDeformation deformation = bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_); + const OffsetIndices points_by_curve = curves_->points_by_curve(); threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { for (const int curve_i : curve_selection_.slice(range)) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int point_i : points) { const float3 &pos_cu = deformation.positions[point_i]; const float dist_to_brush_sq_cu = math::distance_squared(pos_cu, brush_pos_cu); @@ -221,11 +223,12 @@ struct SmoothOperationExecutor { void smooth(const Span point_smooth_factors) { + const OffsetIndices points_by_curve = curves_->points_by_curve(); MutableSpan positions = curves_->positions_for_write(); threading::parallel_for(curve_selection_.index_range(), 256, [&](const IndexRange range) { Vector old_positions; for (const int curve_i : curve_selection_.slice(range)) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; old_positions.clear(); old_positions.extend(positions.slice(points)); for (const int i : IndexRange(points.size()).drop_front(1).drop_back(1)) { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc index dbba292ecb3..c00bc07c3dc 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_snake_hook.cc @@ -179,6 +179,7 @@ struct SnakeHookOperatorExecutor { const float4x4 brush_transform_inv = brush_transform.inverted(); const bke::crazyspace::GeometryDeformation deformation = bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_); + const OffsetIndices points_by_curve = curves_->points_by_curve(); MutableSpan positions_cu = curves_->positions_for_write(); @@ -191,7 +192,7 @@ struct SnakeHookOperatorExecutor { threading::parallel_for(curves_->curves_range(), 256, [&](const IndexRange curves_range) { MoveAndResampleBuffers resample_buffer; for (const int curve_i : curves_range) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const int last_point_i = points.last(); const float3 old_pos_cu = deformation.positions[last_point_i]; const float3 old_symm_pos_cu = brush_transform_inv * old_pos_cu; @@ -264,6 +265,7 @@ struct SnakeHookOperatorExecutor { { const bke::crazyspace::GeometryDeformation deformation = bke::crazyspace::get_evaluated_curves_deformation(*ctx_.depsgraph, *object_); + const OffsetIndices points_by_curve = curves_->points_by_curve(); MutableSpan positions_cu = curves_->positions_for_write(); const float3 brush_diff_cu = brush_end_cu - brush_start_cu; @@ -272,7 +274,7 @@ struct SnakeHookOperatorExecutor { threading::parallel_for(curves_->curves_range(), 256, [&](const IndexRange curves_range) { MoveAndResampleBuffers resample_buffer; for (const int curve_i : curves_range) { - const IndexRange points = curves_->points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const int last_point_i = points.last(); const float3 old_pos_cu = deformation.positions[last_point_i]; diff --git a/source/blender/geometry/intern/add_curves_on_mesh.cc b/source/blender/geometry/intern/add_curves_on_mesh.cc index 0b66b00937e..e0f5076021b 100644 --- a/source/blender/geometry/intern/add_curves_on_mesh.cc +++ b/source/blender/geometry/intern/add_curves_on_mesh.cc @@ -117,11 +117,12 @@ static void interpolate_position_without_interpolation( const float4x4 &surface_to_curves_normal_mat) { const int added_curves_num = root_positions_cu.size(); + const OffsetIndices points_by_curve = curves.points_by_curve(); MutableSpan positions_cu = curves.positions_for_write(); threading::parallel_for(IndexRange(added_curves_num), 256, [&](const IndexRange range) { for (const int i : range) { const int curve_i = old_curves_num + i; - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const float3 &root_cu = root_positions_cu[i]; const float length = new_lengths_cu[i]; const float3 &normal_su = new_normals_su[i]; @@ -147,13 +148,14 @@ static void interpolate_position_with_interpolation(CurvesGeometry &curves, MutableSpan positions_cu = curves.positions_for_write(); const int added_curves_num = root_positions_cu.size(); + const OffsetIndices points_by_curve = curves.points_by_curve(); const Span uv_coords = curves.surface_uv_coords(); threading::parallel_for(IndexRange(added_curves_num), 256, [&](const IndexRange range) { for (const int added_curve_i : range) { const NeighborCurves &neighbors = neighbors_per_curve[added_curve_i]; const int curve_i = old_curves_num + added_curve_i; - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; const float length_cu = new_lengths_cu[added_curve_i]; const float3 &normal_su = new_normals_su[added_curve_i]; @@ -188,7 +190,7 @@ static void interpolate_position_with_interpolation(CurvesGeometry &curves, float normal_rotation_cu[3][3]; rotation_between_vecs_to_mat3(normal_rotation_cu, neighbor_normal_cu, normal_cu); - const IndexRange neighbor_points = curves.points_for_curve(neighbor_curve_i); + const IndexRange neighbor_points = points_by_curve[neighbor_curve_i]; const float3 &neighbor_root_cu = positions_cu[neighbor_points[0]]; /* Sample the positions on neighbors and mix them into the final positions of the curve. @@ -289,7 +291,7 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, interpolate_from_neighbors( neighbors_per_curve, inputs.fallback_point_count, - [&](const int curve_i) { return curves.points_for_curve(curve_i).size(); }, + [&](const int curve_i) { return curve_offsets[curve_i + 1] - curve_offsets[curve_i]; }, new_point_counts_per_curve); } else { @@ -314,11 +316,12 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, /* Determine length of new curves. */ Array new_lengths_cu(added_curves_num); if (inputs.interpolate_length) { + const OffsetIndices points_by_curve = curves.points_by_curve(); interpolate_from_neighbors( neighbors_per_curve, inputs.fallback_curve_length, [&](const int curve_i) { - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; float length = 0.0f; for (const int segment_i : points.drop_back(1)) { const float3 &p1 = positions_cu[segment_i]; diff --git a/source/blender/geometry/intern/fillet_curves.cc b/source/blender/geometry/intern/fillet_curves.cc index ff8240013fd..6b1c0adb648 100644 --- a/source/blender/geometry/intern/fillet_curves.cc +++ b/source/blender/geometry/intern/fillet_curves.cc @@ -41,10 +41,12 @@ static void duplicate_fillet_point_data(const bke::CurvesGeometry &src_curves, const Span src, MutableSpan dst) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(curve_selection.index_range(), 512, [&](IndexRange range) { for (const int curve_i : curve_selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(curve_i); - const IndexRange dst_points = dst_curves.points_for_curve(curve_i); + const IndexRange src_points = src_points_by_curve[curve_i]; + const IndexRange dst_points = dst_points_by_curve[curve_i]; const Span offsets = point_offsets.slice(curve_dst_offsets(src_points, curve_i)); threaded_slice_fill(src.slice(src_points), offsets, dst.slice(dst_points)); } @@ -76,9 +78,10 @@ static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, { /* Fill the offsets array with the curve point counts, then accumulate them to form offsets. */ bke::curves::fill_curve_counts(src_curves, unselected_ranges, dst_curve_offsets); + const OffsetIndices points_by_curve = src_curves.points_by_curve(); threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int curve_i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(curve_i); + const IndexRange src_points = points_by_curve[curve_i]; const IndexRange offsets_range = curve_dst_offsets(src_points, curve_i); MutableSpan point_offsets = dst_point_offsets.slice(offsets_range); @@ -103,12 +106,12 @@ static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, } }); - bke::curves::accumulate_counts_to_offsets(point_offsets); + offset_indices::accumulate_counts_to_offsets(point_offsets); dst_curve_offsets[curve_i] = point_offsets.last(); } }); - bke::curves::accumulate_counts_to_offsets(dst_curve_offsets); + offset_indices::accumulate_counts_to_offsets(dst_curve_offsets); } static void calculate_directions(const Span positions, MutableSpan directions) @@ -450,6 +453,8 @@ static bke::CurvesGeometry fillet_curves( dst_handles_r = dst_curves.handle_positions_right_for_write(); } + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(curve_selection.index_range(), 512, [&](IndexRange range) { Array directions; Array angles; @@ -457,9 +462,9 @@ static bke::CurvesGeometry fillet_curves( Array input_radii_buffer; for (const int curve_i : curve_selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(curve_i); + const IndexRange src_points = src_points_by_curve[curve_i]; const Span offsets = point_offsets.slice(curve_dst_offsets(src_points, curve_i)); - const IndexRange dst_points = dst_curves.points_for_curve(curve_i); + const IndexRange dst_points = dst_points_by_curve[curve_i]; const Span src_positions = positions.slice(src_points); directions.reinitialize(src_points.size()); diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc index eff67a5d1ba..f028c64cdd1 100644 --- a/source/blender/geometry/intern/resample_curves.cc +++ b/source/blender/geometry/intern/resample_curves.cc @@ -229,8 +229,9 @@ static void normalize_curve_point_data(const CurvesGeometry &curves, const IndexMask curve_selection, MutableSpan data) { + const OffsetIndices points_by_curve = curves.points_by_curve(); for (const int i_curve : curve_selection) { - normalize_span(data.slice(curves.points_for_curve(i_curve))); + normalize_span(data.slice(points_by_curve[i_curve])); } } @@ -262,7 +263,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, /* Fill the counts for the curves that aren't selected and accumulate the counts into offsets. */ bke::curves::fill_curve_counts(src_curves, unselected_ranges, dst_offsets); - bke::curves::accumulate_counts_to_offsets(dst_offsets); + offset_indices::accumulate_counts_to_offsets(dst_offsets); dst_curves.resize(dst_offsets.last(), dst_curves.curves_num()); /* All resampled curves are poly curves. */ @@ -286,6 +287,9 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, Array sample_indices(dst_curves.points_num()); Array sample_factors(dst_curves.points_num()); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + /* Use a "for each group of curves: for each attribute: for each curve" pattern to work on * smaller sections of data that ideally fit into CPU cache better than simply one attribute at a * time or one curve at a time. */ @@ -297,7 +301,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, /* Gather uniform samples based on the accumulated lengths of the original curve. */ for (const int i_curve : sliced_selection) { const bool cyclic = curves_cyclic[i_curve]; - const IndexRange dst_points = dst_curves.points_for_curve(i_curve); + const IndexRange dst_points = dst_points_by_curve[i_curve]; const Span lengths = src_curves.evaluated_lengths_for_curve(i_curve, cyclic); if (lengths.is_empty()) { /* Handle curves with only one evaluated point. */ @@ -321,8 +325,8 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, MutableSpan dst = attributes.dst[i_attribute].typed(); for (const int i_curve : sliced_selection) { - const IndexRange src_points = src_curves.points_for_curve(i_curve); - const IndexRange dst_points = dst_curves.points_for_curve(i_curve); + const IndexRange src_points = src_points_by_curve[i_curve]; + const IndexRange dst_points = dst_points_by_curve[i_curve]; if (curve_types[i_curve] == CURVE_TYPE_POLY) { length_parameterize::interpolate(src.slice(src_points), @@ -349,7 +353,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, auto interpolate_evaluated_data = [&](const Span src, MutableSpan dst) { for (const int i_curve : sliced_selection) { const IndexRange src_points = src_curves.evaluated_points_for_curve(i_curve); - const IndexRange dst_points = dst_curves.points_for_curve(i_curve); + const IndexRange dst_points = dst_points_by_curve[i_curve]; length_parameterize::interpolate(src.slice(src_points), sample_indices.as_span().slice(dst_points), sample_factors.as_span().slice(dst_points), @@ -372,7 +376,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, /* Fill the default value for non-interpolating attributes that still must be copied. */ for (GMutableSpan dst : attributes.dst_no_interpolation) { for (const int i_curve : sliced_selection) { - const IndexRange dst_points = dst_curves.points_for_curve(i_curve); + const IndexRange dst_points = dst_points_by_curve[i_curve]; dst.type().value_initialize_n(dst.slice(dst_points).data(), dst_points.size()); } } @@ -438,7 +442,7 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, } }); bke::curves::fill_curve_counts(src_curves, unselected_ranges, dst_offsets); - bke::curves::accumulate_counts_to_offsets(dst_offsets); + offset_indices::accumulate_counts_to_offsets(dst_offsets); dst_curves.resize(dst_offsets.last(), dst_curves.curves_num()); @@ -449,6 +453,8 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, AttributesForInterpolation attributes; gather_point_attributes_to_interpolate(src_curves, dst_curves, attributes, output_ids); + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(selection.index_range(), 512, [&](IndexRange selection_range) { const IndexMask sliced_selection = selection.slice(selection_range); @@ -460,8 +466,8 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, MutableSpan dst = attributes.dst[i_attribute].typed(); for (const int i_curve : sliced_selection) { - const IndexRange src_points = src_curves.points_for_curve(i_curve); - const IndexRange dst_points = dst_curves.points_for_curve(i_curve); + const IndexRange src_points = src_points_by_curve[i_curve]; + const IndexRange dst_points = dst_points_by_curve[i_curve]; src_curves.interpolate_to_evaluated( i_curve, src.slice(src_points), dst.slice(dst_points)); } @@ -471,7 +477,7 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, auto copy_evaluated_data = [&](const Span src, MutableSpan dst) { for (const int i_curve : sliced_selection) { const IndexRange src_points = src_curves.evaluated_points_for_curve(i_curve); - const IndexRange dst_points = dst_curves.points_for_curve(i_curve); + const IndexRange dst_points = dst_points_by_curve[i_curve]; dst.slice(dst_points).copy_from(src.slice(src_points)); } }; @@ -491,7 +497,7 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, /* Fill the default value for non-interpolating attributes that still must be copied. */ for (GMutableSpan dst : attributes.dst_no_interpolation) { for (const int i_curve : sliced_selection) { - const IndexRange dst_points = dst_curves.points_for_curve(i_curve); + const IndexRange dst_points = dst_points_by_curve[i_curve]; dst.type().value_initialize_n(dst.slice(dst_points).data(), dst_points.size()); } } diff --git a/source/blender/geometry/intern/set_curve_type.cc b/source/blender/geometry/intern/set_curve_type.cc index ab35f90b279..85f6325ea13 100644 --- a/source/blender/geometry/intern/set_curve_type.cc +++ b/source/blender/geometry/intern/set_curve_type.cc @@ -279,9 +279,10 @@ static int to_nurbs_size(const CurveType src_type, const int src_size) static void retrieve_curve_sizes(const bke::CurvesGeometry &curves, MutableSpan sizes) { + const OffsetIndices points_by_curve = curves.points_by_curve(); threading::parallel_for(curves.curves_range(), 4096, [&](IndexRange range) { for (const int i : range) { - sizes[i] = curves.points_for_curve(i).size(); + sizes[i] = points_by_curve[i].size(); } }); } @@ -307,7 +308,7 @@ static bke::CurvesGeometry convert_curves_to_bezier( CurveType(src_types[i]), src_cyclic[i], KnotsMode(src_knot_modes[i]), dst_offsets[i]); } }); - bke::curves::accumulate_counts_to_offsets(dst_offsets); + offset_indices::accumulate_counts_to_offsets(dst_offsets); dst_curves.resize(dst_offsets.last(), dst_curves.curves_num()); const bke::AttributeAccessor src_attributes = src_curves.attributes(); @@ -332,6 +333,9 @@ static bke::CurvesGeometry convert_curves_to_bezier( MutableSpan dst_types_r = dst_curves.handle_types_right_for_write(); MutableSpan dst_weights = dst_curves.nurbs_weights_for_write(); + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); + auto catmull_rom_to_bezier = [&](IndexMask selection) { bke::curves::fill_points(dst_curves, selection, BEZIER_HANDLE_ALIGN, dst_types_l); bke::curves::fill_points(dst_curves, selection, BEZIER_HANDLE_ALIGN, dst_types_r); @@ -339,8 +343,8 @@ static bke::CurvesGeometry convert_curves_to_bezier( threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(i); - const IndexRange dst_points = dst_curves.points_for_curve(i); + const IndexRange src_points = src_points_by_curve[i]; + const IndexRange dst_points = dst_points_by_curve[i]; catmull_rom_to_bezier_handles(src_positions.slice(src_points), src_cyclic[i], dst_handles_l.slice(dst_points), @@ -392,8 +396,8 @@ static bke::CurvesGeometry convert_curves_to_bezier( threading::parallel_for(selection.index_range(), 64, [&](IndexRange range) { for (const int i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(i); - const IndexRange dst_points = dst_curves.points_for_curve(i); + const IndexRange src_points = src_points_by_curve[i]; + const IndexRange dst_points = dst_points_by_curve[i]; const Span src_curve_positions = src_positions.slice(src_points); if (dst_points.size() == 1) { const float3 &position = src_positions[src_points.first()]; @@ -430,8 +434,8 @@ static bke::CurvesGeometry convert_curves_to_bezier( for (bke::AttributeTransferData &attribute : generic_attributes) { threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(i); - const IndexRange dst_points = dst_curves.points_for_curve(i); + const IndexRange src_points = src_points_by_curve[i]; + const IndexRange dst_points = dst_points_by_curve[i]; nurbs_to_bezier_assign(attribute.src.slice(src_points), KnotsMode(src_knot_modes[i]), attribute.dst.span.slice(dst_points)); @@ -482,7 +486,7 @@ static bke::CurvesGeometry convert_curves_to_nurbs( dst_offsets[i] = to_nurbs_size(CurveType(src_types[i]), dst_offsets[i]); } }); - bke::curves::accumulate_counts_to_offsets(dst_offsets); + offset_indices::accumulate_counts_to_offsets(dst_offsets); dst_curves.resize(dst_offsets.last(), dst_curves.curves_num()); const bke::AttributeAccessor src_attributes = src_curves.attributes(); @@ -508,6 +512,9 @@ static bke::CurvesGeometry convert_curves_to_nurbs( } }; + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); + auto catmull_rom_to_nurbs = [&](IndexMask selection) { dst_curves.nurbs_orders_for_write().fill_indices(selection, 4); dst_curves.nurbs_knots_modes_for_write().fill_indices(selection, NURBS_KNOT_MODE_BEZIER); @@ -515,8 +522,8 @@ static bke::CurvesGeometry convert_curves_to_nurbs( threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(i); - const IndexRange dst_points = dst_curves.points_for_curve(i); + const IndexRange src_points = src_points_by_curve[i]; + const IndexRange dst_points = dst_points_by_curve[i]; catmull_rom_to_nurbs_positions( src_positions.slice(src_points), src_cyclic[i], dst_positions.slice(dst_points)); } @@ -525,8 +532,8 @@ static bke::CurvesGeometry convert_curves_to_nurbs( for (bke::AttributeTransferData &attribute : generic_attributes) { threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(i); - const IndexRange dst_points = dst_curves.points_for_curve(i); + const IndexRange src_points = src_points_by_curve[i]; + const IndexRange dst_points = dst_points_by_curve[i]; bezier_generic_to_nurbs(attribute.src.slice(src_points), attribute.dst.span.slice(dst_points)); } @@ -572,8 +579,8 @@ static bke::CurvesGeometry convert_curves_to_nurbs( threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(i); - const IndexRange dst_points = dst_curves.points_for_curve(i); + const IndexRange src_points = src_points_by_curve[i]; + const IndexRange dst_points = dst_points_by_curve[i]; bezier_positions_to_nurbs(src_positions.slice(src_points), src_handles_l.slice(src_points), src_handles_r.slice(src_points), @@ -584,8 +591,8 @@ static bke::CurvesGeometry convert_curves_to_nurbs( for (bke::AttributeTransferData &attribute : generic_attributes) { threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(i); - const IndexRange dst_points = dst_curves.points_for_curve(i); + const IndexRange src_points = src_points_by_curve[i]; + const IndexRange dst_points = dst_points_by_curve[i]; bezier_generic_to_nurbs(attribute.src.slice(src_points), attribute.dst.span.slice(dst_points)); } diff --git a/source/blender/geometry/intern/subdivide_curves.cc b/source/blender/geometry/intern/subdivide_curves.cc index e69a8398653..15c3f40e6b2 100644 --- a/source/blender/geometry/intern/subdivide_curves.cc +++ b/source/blender/geometry/intern/subdivide_curves.cc @@ -31,9 +31,10 @@ static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, { /* Fill the array with each curve's point count, then accumulate them to the offsets. */ bke::curves::fill_curve_counts(src_curves, unselected_ranges, dst_curve_offsets); + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) { for (const int curve_i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(curve_i); + const IndexRange src_points = src_points_by_curve[curve_i]; const IndexRange src_segments = curve_dst_offsets(src_points, curve_i); MutableSpan point_offsets = dst_point_offsets.slice(src_segments); @@ -54,11 +55,11 @@ static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, } } - bke::curves::accumulate_counts_to_offsets(point_offsets); + offset_indices::accumulate_counts_to_offsets(point_offsets); dst_curve_offsets[curve_i] = point_offsets.last(); } }); - bke::curves::accumulate_counts_to_offsets(dst_curve_offsets); + offset_indices::accumulate_counts_to_offsets(dst_curve_offsets); } template @@ -79,13 +80,15 @@ static void subdivide_attribute_linear(const bke::CurvesGeometry &src_curves, const Span src, MutableSpan dst) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(selection.index_range(), 512, [&](IndexRange selection_range) { for (const int curve_i : selection.slice(selection_range)) { - const IndexRange src_points = src_curves.points_for_curve(curve_i); + const IndexRange src_points = src_points_by_curve[curve_i]; const IndexRange src_segments = curve_dst_offsets(src_points, curve_i); const Span offsets = point_offsets.slice(src_segments); - const IndexRange dst_points = dst_curves.points_for_curve(curve_i); + const IndexRange dst_points = dst_points_by_curve[curve_i]; const Span curve_src = src.slice(src_points); MutableSpan curve_dst = dst.slice(dst_points); @@ -126,11 +129,13 @@ static void subdivide_attribute_catmull_rom(const bke::CurvesGeometry &src_curve const Span src, MutableSpan dst) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(selection.index_range(), 512, [&](IndexRange selection_range) { for (const int curve_i : selection.slice(selection_range)) { - const IndexRange src_points = src_curves.points_for_curve(curve_i); + const IndexRange src_points = src_points_by_curve[curve_i]; const IndexRange src_segments = curve_dst_offsets(src_points, curve_i); - const IndexRange dst_points = dst_curves.points_for_curve(curve_i); + const IndexRange dst_points = dst_points_by_curve[curve_i]; bke::curves::catmull_rom::interpolate_to_evaluated(src.slice(src_points), cyclic[curve_i], @@ -367,19 +372,21 @@ bke::CurvesGeometry subdivide_curves( const VArraySpan src_types_r{src_curves.handle_types_right()}; const Span src_handles_l = src_curves.handle_positions_left(); const Span src_handles_r = src_curves.handle_positions_right(); + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); MutableSpan dst_positions = dst_curves.positions_for_write(); MutableSpan dst_types_l = dst_curves.handle_types_left_for_write(); MutableSpan dst_types_r = dst_curves.handle_types_right_for_write(); MutableSpan dst_handles_l = dst_curves.handle_positions_left_for_write(); MutableSpan dst_handles_r = dst_curves.handle_positions_right_for_write(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int curve_i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(curve_i); + const IndexRange src_points = src_points_by_curve[curve_i]; const IndexRange src_segments = curve_dst_offsets(src_points, curve_i); - const IndexRange dst_points = dst_curves.points_for_curve(curve_i); + const IndexRange dst_points = dst_points_by_curve[curve_i]; subdivide_bezier_positions(src_positions.slice(src_points), src_types_l.slice(src_points), src_types_r.slice(src_points), diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc index 361415aa540..eaa0cb35973 100644 --- a/source/blender/geometry/intern/trim_curves.cc +++ b/source/blender/geometry/intern/trim_curves.cc @@ -191,6 +191,7 @@ static void fill_bezier_data(bke::CurvesGeometry &dst_curves, const IndexMask se if (!dst_curves.has_curve_with_type(CURVE_TYPE_BEZIER)) { return; } + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); MutableSpan handle_positions_left = dst_curves.handle_positions_left_for_write(); MutableSpan handle_positions_right = dst_curves.handle_positions_right_for_write(); MutableSpan handle_types_left = dst_curves.handle_types_left_for_write(); @@ -198,7 +199,7 @@ static void fill_bezier_data(bke::CurvesGeometry &dst_curves, const IndexMask se threading::parallel_for(selection.index_range(), 4096, [&](const IndexRange range) { for (const int64_t curve_i : selection.slice(range)) { - const IndexRange points = dst_curves.points_for_curve(curve_i); + const IndexRange points = dst_points_by_curve[curve_i]; handle_types_right.slice(points).fill(int8_t(BEZIER_HANDLE_FREE)); handle_types_left.slice(points).fill(int8_t(BEZIER_HANDLE_FREE)); handle_positions_left.slice(points).fill({0.0f, 0.0f, 0.0f}); @@ -587,18 +588,20 @@ static void trim_attribute_linear(const bke::CurvesGeometry &src_curves, const Span src_ranges, MutableSpan transfer_attributes) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); for (bke::AttributeTransferData &attribute : transfer_attributes) { attribute_math::convert_to_static_type(attribute.meta_data.data_type, [&](auto dummy) { using T = decltype(dummy); threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) { for (const int64_t curve_i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(curve_i); + const IndexRange src_points = src_points_by_curve[curve_i]; sample_interval_linear(attribute.src.template typed().slice(src_points), attribute.dst.span.typed(), src_ranges[curve_i], - dst_curves.points_for_curve(curve_i), + dst_points_by_curve[curve_i], start_points[curve_i], end_points[curve_i]); } @@ -615,13 +618,15 @@ static void trim_polygonal_curves(const bke::CurvesGeometry &src_curves, const Span src_ranges, MutableSpan transfer_attributes) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); const Span src_positions = src_curves.positions(); MutableSpan dst_positions = dst_curves.positions_for_write(); threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) { for (const int64_t curve_i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(curve_i); - const IndexRange dst_points = dst_curves.points_for_curve(curve_i); + const IndexRange src_points = src_points_by_curve[curve_i]; + const IndexRange dst_points = dst_points_by_curve[curve_i]; sample_interval_linear(src_positions.slice(src_points), dst_positions, @@ -650,14 +655,16 @@ static void trim_catmull_rom_curves(const bke::CurvesGeometry &src_curves, const Span src_ranges, MutableSpan transfer_attributes) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); const Span src_positions = src_curves.positions(); const VArray src_cyclic = src_curves.cyclic(); MutableSpan dst_positions = dst_curves.positions_for_write(); threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) { for (const int64_t curve_i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(curve_i); - const IndexRange dst_points = dst_curves.points_for_curve(curve_i); + const IndexRange src_points = src_points_by_curve[curve_i]; + const IndexRange dst_points = dst_points_by_curve[curve_i]; sample_interval_catmull_rom(src_positions.slice(src_points), dst_positions, @@ -677,8 +684,8 @@ static void trim_catmull_rom_curves(const bke::CurvesGeometry &src_curves, threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) { for (const int64_t curve_i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(curve_i); - const IndexRange dst_points = dst_curves.points_for_curve(curve_i); + const IndexRange src_points = src_points_by_curve[curve_i]; + const IndexRange dst_points = dst_points_by_curve[curve_i]; sample_interval_catmull_rom(attribute.src.template typed().slice(src_points), attribute.dst.span.typed(), @@ -701,12 +708,14 @@ static void trim_bezier_curves(const bke::CurvesGeometry &src_curves, const Span src_ranges, MutableSpan transfer_attributes) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); const Span src_positions = src_curves.positions(); const VArraySpan src_types_l{src_curves.handle_types_left()}; const VArraySpan src_types_r{src_curves.handle_types_right()}; const Span src_handles_l = src_curves.handle_positions_left(); const Span src_handles_r = src_curves.handle_positions_right(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); MutableSpan dst_positions = dst_curves.positions_for_write(); MutableSpan dst_types_l = dst_curves.handle_types_left_for_write(); MutableSpan dst_types_r = dst_curves.handle_types_right_for_write(); @@ -715,8 +724,8 @@ static void trim_bezier_curves(const bke::CurvesGeometry &src_curves, threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) { for (const int64_t curve_i : selection.slice(range)) { - const IndexRange src_points = src_curves.points_for_curve(curve_i); - const IndexRange dst_points = dst_curves.points_for_curve(curve_i); + const IndexRange src_points = src_points_by_curve[curve_i]; + const IndexRange dst_points = dst_points_by_curve[curve_i]; sample_interval_bezier(src_positions.slice(src_points), src_handles_l.slice(src_points), @@ -752,12 +761,14 @@ static void trim_evaluated_curves(const bke::CurvesGeometry &src_curves, const Span src_ranges, MutableSpan transfer_attributes) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); const Span src_eval_positions = src_curves.evaluated_positions(); MutableSpan dst_positions = dst_curves.positions_for_write(); threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) { for (const int64_t curve_i : selection.slice(range)) { - const IndexRange dst_points = dst_curves.points_for_curve(curve_i); + const IndexRange dst_points = dst_points_by_curve[curve_i]; const IndexRange src_evaluated_points = src_curves.evaluated_points_for_curve(curve_i); sample_interval_linear(src_eval_positions.slice(src_evaluated_points), @@ -782,11 +793,11 @@ static void trim_evaluated_curves(const bke::CurvesGeometry &src_curves, GArray<> evaluated_data(CPPType::get(), src_evaluated_points.size()); GMutableSpan evaluated_span = evaluated_data.as_mutable_span(); src_curves.interpolate_to_evaluated( - curve_i, attribute.src.slice(src_curves.points_for_curve(curve_i)), evaluated_span); + curve_i, attribute.src.slice(src_points_by_curve[curve_i]), evaluated_span); sample_interval_linear(evaluated_span.typed(), attribute.dst.span.typed(), src_ranges[curve_i], - dst_curves.points_for_curve(curve_i), + dst_points_by_curve[curve_i], start_points[curve_i], end_points[curve_i]); } @@ -824,6 +835,7 @@ static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves, MutableSpan end_points, MutableSpan src_ranges) { + const OffsetIndices points_by_curve = curves.points_by_curve(); const VArray src_cyclic = curves.cyclic(); const VArray resolution = curves.resolution(); const VArray curve_types = curves.curve_types(); @@ -840,7 +852,7 @@ static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves, } else { dst_curve_types[curve_i] = curve_type; - point_count = curves.points_num_for_curve(curve_i); + point_count = points_by_curve.size(curve_i); } if (point_count == 1) { /* Single point. */ @@ -976,15 +988,16 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, /* Transfer copied curves parameters. */ const VArray src_curve_types = src_curves.curve_types(); + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); threading::parallel_for( inverse_selection.index_range(), 4096, [&](const IndexRange selection_range) { for (const int64_t curve_i : inverse_selection.slice(selection_range)) { - dst_curve_offsets[curve_i] = src_curves.points_num_for_curve(curve_i); + dst_curve_offsets[curve_i] = src_points_by_curve.size(curve_i); dst_curve_types[curve_i] = src_curve_types[curve_i]; } }); /* Finalize and update the geometry container. */ - bke::curves::accumulate_counts_to_offsets(dst_curve_offsets); + offset_indices::accumulate_counts_to_offsets(dst_curve_offsets); dst_curves.resize(dst_curves.offsets().last(), dst_curves.curves_num()); dst_curves.update_curve_types(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc index 891ac2614ef..48062516784 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc @@ -304,13 +304,14 @@ static void blur_on_curve_exec(const bke::CurvesGeometry &curves, MutableSpan src = main_buffer; MutableSpan dst = tmp_buffer; + const OffsetIndices points_by_curve = curves.points_by_curve(); const VArray cyclic = curves.cyclic(); for ([[maybe_unused]] const int iteration : IndexRange(iterations)) { attribute_math::DefaultMixer mixer{dst, IndexMask(0)}; threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) { for (const int curve_i : range) { - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; if (points.size() == 1) { /* No mixing possible. */ const int point_i = points[0]; @@ -347,7 +348,7 @@ static void blur_on_curve_exec(const bke::CurvesGeometry &curves, mixer.mix_in(last_i, src[last_i - 1], last_neighbor_weight); } } - mixer.finalize(curves.points_for_curves(range)); + mixer.finalize(points_by_curve[range]); }); std::swap(src, dst); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc index 7eb958fe576..7c433522300 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_endpoint_selection.cc @@ -61,10 +61,11 @@ class EndpointFieldInput final : public bke::CurvesFieldInput { Array selection(curves.points_num(), false); MutableSpan selection_span = selection.as_mutable_span(); + const OffsetIndices points_by_curve = curves.points_by_curve(); devirtualize_varray2(start_size, end_size, [&](const auto &start_size, const auto &end_size) { threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange curves_range) { for (const int i : curves_range) { - const IndexRange points = curves.points_for_curve(i); + const IndexRange points = points_by_curve[i]; const int start = std::max(start_size[i], 0); const int end = std::max(end_size[i], 0); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc index 9f0d40bb0d7..60d8539c8cb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_handle_type_selection.cc @@ -52,12 +52,13 @@ static void select_by_handle_type(const bke::CurvesGeometry &curves, const GeometryNodeCurveHandleMode mode, const MutableSpan r_selection) { + const OffsetIndices points_by_curve = curves.points_by_curve(); VArray curve_types = curves.curve_types(); VArray left = curves.handle_types_left(); VArray right = curves.handle_types_right(); for (const int i_curve : curves.curves_range()) { - const IndexRange points = curves.points_for_curve(i_curve); + const IndexRange points = points_by_curve[i_curve]; if (curve_types[i_curve] != CURVE_TYPE_BEZIER) { r_selection.slice(points).fill(false); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc index bd7a8c716ae..4839c2929d6 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc @@ -312,6 +312,7 @@ class SampleCurveFunction : public mf::MultiFunction { evaluated_normals = curves.evaluated_normals(); } + const OffsetIndices points_by_curve = curves.points_by_curve(); const VArray curve_indices = params.readonly_single_input(0, "Curve Index"); const VArraySpan lengths = params.readonly_single_input(1, "Length"); const VArray cyclic = curves.cyclic(); @@ -377,7 +378,7 @@ class SampleCurveFunction : public mf::MultiFunction { } } if (!sampled_values.is_empty()) { - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; src_original_values.reinitialize(points.size()); source_data_->materialize_compressed_to_uninitialized(points, src_original_values.data()); src_evaluated_values.reinitialize(curves.evaluated_points_for_curve(curve_i).size()); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc index 159a4661df0..8b8f436c36a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc @@ -58,6 +58,7 @@ static Array accumulated_lengths_curve_domain(const bke::CurvesGeometry & static Array curve_length_point_domain(const bke::CurvesGeometry &curves) { curves.ensure_evaluated_lengths(); + const OffsetIndices points_by_curve = curves.points_by_curve(); const VArray types = curves.curve_types(); const VArray resolutions = curves.resolution(); const VArray cyclic = curves.cyclic(); @@ -66,7 +67,7 @@ static Array curve_length_point_domain(const bke::CurvesGeometry &curves) threading::parallel_for(curves.curves_range(), 128, [&](IndexRange range) { for (const int i_curve : range) { - const IndexRange points = curves.points_for_curve(i_curve); + const IndexRange points = points_by_curve[i_curve]; const Span evaluated_lengths = curves.evaluated_lengths_for_curve(i_curve, cyclic[i_curve]); MutableSpan lengths = result.as_mutable_span().slice(points); @@ -114,10 +115,11 @@ static VArray construct_curve_parameter_varray(const bke::CurvesGeometry if (domain == ATTR_DOMAIN_POINT) { Array result = curve_length_point_domain(curves); MutableSpan lengths = result.as_mutable_span(); + const OffsetIndices points_by_curve = curves.points_by_curve(); threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange range) { for (const int i_curve : range) { - MutableSpan curve_lengths = lengths.slice(curves.points_for_curve(i_curve)); + MutableSpan curve_lengths = lengths.slice(points_by_curve[i_curve]); const float total_length = curve_lengths.last(); if (total_length > 0.0f) { const float factor = 1.0f / total_length; @@ -193,9 +195,10 @@ static VArray construct_index_on_spline_varray(const bke::CurvesGeometry &c if (domain == ATTR_DOMAIN_POINT) { Array result(curves.points_num()); MutableSpan span = result.as_mutable_span(); + const OffsetIndices points_by_curve = curves.points_by_curve(); threading::parallel_for(curves.curves_range(), 1024, [&](IndexRange range) { for (const int i_curve : range) { - MutableSpan indices = span.slice(curves.points_for_curve(i_curve)); + MutableSpan indices = span.slice(points_by_curve[i_curve]); for (const int i : indices.index_range()) { indices[i] = i; } diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc index 4ffada76497..0f9c14b0fee 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc @@ -62,6 +62,7 @@ class PointsOfCurveInput final : public bke::CurvesFieldInput { point_evaluator.add(sort_weight_); point_evaluator.evaluate(); const VArray all_sort_weights = point_evaluator.get_evaluated(0); + const OffsetIndices points_by_curve = curves.points_by_curve(); Array point_of_curve(mask.min_array_size()); threading::parallel_for(mask.index_range(), 256, [&](const IndexRange range) { @@ -77,7 +78,7 @@ class PointsOfCurveInput final : public bke::CurvesFieldInput { continue; } - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; /* Retrieve the weights for each point. */ sort_weights.reinitialize(points.size()); @@ -142,8 +143,9 @@ class CurvePointCountInput final : public bke::CurvesFieldInput { if (domain != ATTR_DOMAIN_CURVE) { return {}; } - return VArray::ForFunc(curves.curves_num(), [&, curves](const int64_t curve_i) { - return curves.points_num_for_curve(curve_i); + const OffsetIndices points_by_curve = curves.points_by_curve(); + return VArray::ForFunc(curves.curves_num(), [points_by_curve](const int64_t curve_i) { + return points_by_curve.size(curve_i); }); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc index f748c7384ad..4de87ba775b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc @@ -74,6 +74,8 @@ static void deform_curves(const CurvesGeometry &curves, const Span surface_loops_new = surface_mesh_new.loops(); const Span surface_looptris_new = surface_mesh_new.looptris(); + const OffsetIndices points_by_curve = curves.points_by_curve(); + threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) { for (const int curve_i : range) { const ReverseUVSampler::Result &surface_sample_old = surface_samples_old[curve_i]; @@ -197,7 +199,7 @@ static void deform_curves(const CurvesGeometry &curves, const float4x4 curve_transform = surface_to_curves * surface_transform * curves_to_surface; /* Actually transform all points. */ - const IndexRange points = curves.points_for_curve(curve_i); + const IndexRange points = points_by_curve[curve_i]; for (const int point_i : points) { const float3 old_point_pos = r_positions[point_i]; const float3 new_point_pos = curve_transform * old_point_pos; diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index 0dfebb1362c..b3017a569eb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -235,6 +235,9 @@ static void copy_curve_attributes_without_id( Map attributes = gather_attributes_without_id( geometry_set, GEO_COMPONENT_TYPE_CURVE, propagation_info); + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); + for (const Map::Item entry : attributes.items()) { const AttributeIDRef attribute_id = entry.key; GAttributeReader src_attribute = src_curves.attributes().lookup(attribute_id); @@ -265,9 +268,9 @@ static void copy_curve_attributes_without_id( threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i_selection : range) { const int i_src_curve = selection[i_selection]; - const Span curve_src = src.slice(src_curves.points_for_curve(i_src_curve)); + const Span curve_src = src.slice(src_points_by_curve[i_src_curve]); for (const int i_dst_curve : range_for_offsets_index(curve_offsets, i_selection)) { - dst.slice(dst_curves.points_for_curve(i_dst_curve)).copy_from(curve_src); + dst.slice(dst_points_by_curve[i_dst_curve]).copy_from(curve_src); } } }); @@ -305,15 +308,17 @@ static void copy_stable_id_curves(const bke::CurvesGeometry &src_curves, VArraySpan src{src_attribute.varray.typed()}; MutableSpan dst = dst_attribute.span.typed(); + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); + threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i_selection : range) { const int i_src_curve = selection[i_selection]; - const Span curve_src = src.slice(src_curves.points_for_curve(i_src_curve)); + const Span curve_src = src.slice(src_points_by_curve[i_src_curve]); const IndexRange duplicates_range = range_for_offsets_index(curve_offsets, i_selection); for (const int i_duplicate : IndexRange(duplicates_range.size()).drop_front(1)) { const int i_dst_curve = duplicates_range[i_duplicate]; - copy_hashed_ids( - curve_src, i_duplicate, dst.slice(dst_curves.points_for_curve(i_dst_curve))); + copy_hashed_ids(curve_src, i_duplicate, dst.slice(dst_points_by_curve[i_dst_curve])); } } }); @@ -344,6 +349,8 @@ static void duplicate_curves(GeometrySet &geometry_set, const VArray counts = evaluator.get_evaluated(0); const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); + const OffsetIndices points_by_curve = curves.points_by_curve(); + /* The offset in the result curve domain at every selected input curve. */ Array curve_offsets(selection.size() + 1); Array point_offsets(selection.size() + 1); @@ -355,7 +362,7 @@ static void duplicate_curves(GeometrySet &geometry_set, curve_offsets[i_curve] = dst_curves_num; point_offsets[i_curve] = dst_points_num; dst_curves_num += count; - dst_points_num += count * curves.points_for_curve(selection[i_curve]).size(); + dst_points_num += count * points_by_curve.size(selection[i_curve]); } curve_offsets.last() = dst_curves_num; point_offsets.last() = dst_points_num; @@ -368,7 +375,7 @@ static void duplicate_curves(GeometrySet &geometry_set, threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i_selection : range) { const int i_src_curve = selection[i_selection]; - const IndexRange src_curve_range = curves.points_for_curve(i_src_curve); + const IndexRange src_curve_range = points_by_curve[i_src_curve]; const IndexRange dst_curves_range = range_for_offsets_index(curve_offsets, i_selection); MutableSpan dst_offsets = all_dst_offsets.slice(dst_curves_range); for (const int i_duplicate : IndexRange(dst_curves_range.size())) { @@ -814,10 +821,11 @@ static void duplicate_points_curve(GeometrySet &geometry_set, Array offsets = accumulate_counts_to_offsets(selection, counts); const int dst_num = offsets.last(); + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); Array point_to_curve_map(src_curves.points_num()); threading::parallel_for(src_curves.curves_range(), 1024, [&](const IndexRange range) { for (const int i_curve : range) { - const IndexRange points = src_curves.points_for_curve(i_curve); + const IndexRange points = src_points_by_curve[i_curve]; point_to_curve_map.as_mutable_span().slice(points).fill(i_curve); } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc index 5a42949d4c8..ee247672a3b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_spline_length.cc @@ -19,7 +19,8 @@ static void node_declare(NodeDeclarationBuilder &b) static VArray construct_curve_point_count_gvarray(const bke::CurvesGeometry &curves, const eAttrDomain domain) { - auto count_fn = [curves](int64_t i) { return curves.points_for_curve(i).size(); }; + const OffsetIndices points_by_curve = curves.points_by_curve(); + auto count_fn = [points_by_curve](int64_t i) { return points_by_curve.size(i); }; if (domain == ATTR_DOMAIN_CURVE) { return VArray::ForFunc(curves.curves_num(), count_fn); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc index aa27fa70e64..d036599df1a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc @@ -15,6 +15,7 @@ static void node_declare(NodeDeclarationBuilder &b) static Array curve_tangent_point_domain(const bke::CurvesGeometry &curves) { + const OffsetIndices points_by_curve = curves.points_by_curve(); const VArray types = curves.curve_types(); const VArray resolutions = curves.resolution(); const VArray cyclic = curves.cyclic(); @@ -26,7 +27,7 @@ static Array curve_tangent_point_domain(const bke::CurvesGeometry &curve threading::parallel_for(curves.curves_range(), 128, [&](IndexRange range) { for (const int i_curve : range) { - const IndexRange points = curves.points_for_curve(i_curve); + const IndexRange points = points_by_curve[i_curve]; const IndexRange evaluated_points = curves.evaluated_points_for_curve(i_curve); MutableSpan curve_tangents = results.as_mutable_span().slice(points); diff --git a/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc index ff6df94ceba..99a58140025 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_offset_point_in_curve.cc @@ -61,6 +61,7 @@ class ControlPointNeighborFieldInput final : public bke::CurvesFieldInput { const eAttrDomain domain, const IndexMask mask) const final { + const OffsetIndices points_by_curve = curves.points_by_curve(); const VArray cyclic = curves.cyclic(); const Array parent_curves = curves.point_to_curve_map(); @@ -76,7 +77,7 @@ class ControlPointNeighborFieldInput final : public bke::CurvesFieldInput { for (const int i_selection : mask) { const int i_point = std::clamp(indices[i_selection], 0, curves.points_num() - 1); const int i_curve = parent_curves[i_point]; - const IndexRange curve_points = curves.points_for_curve(i_curve); + const IndexRange curve_points = points_by_curve[i_curve]; const int offset_point = i_point + offsets[i_point]; if (cyclic[i_curve]) { @@ -116,6 +117,7 @@ class OffsetValidFieldInput final : public bke::CurvesFieldInput { const IndexMask mask) const final { const VArray cyclic = curves.cyclic(); + const OffsetIndices points_by_curve = curves.points_by_curve(); const Array parent_curves = curves.point_to_curve_map(); const bke::CurvesFieldContext context{curves, domain}; @@ -135,7 +137,7 @@ class OffsetValidFieldInput final : public bke::CurvesFieldInput { } const int i_curve = parent_curves[i_point]; - const IndexRange curve_points = curves.points_for_curve(i_curve); + const IndexRange curve_points = points_by_curve[i_curve]; if (cyclic[i_curve]) { output[i_selection] = true; continue; From 973db6b5c119f9c9bba50b8e6e082eca099f6909 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Jan 2023 12:49:08 +0100 Subject: [PATCH 0732/1522] Gitea: make bug report template more compact And split text before and after description field to reduce long distance between title and description. --- .gitea/issue_template/bug.yaml | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/.gitea/issue_template/bug.yaml b/.gitea/issue_template/bug.yaml index 41cc6a4ed74..94f61f6701b 100644 --- a/.gitea/issue_template/bug.yaml +++ b/.gitea/issue_template/bug.yaml @@ -7,24 +7,14 @@ body: - type: markdown attributes: value: | - ### First time bug reporting? - Read [these tips](https://wiki.blender.org/wiki/Process/Bug_Reports) and watch this **[How to Report a Bug](https://www.youtube.com/watch?v=JTD0OJq_rF4)** video to make a complete, valid bug report. Remember to write your bug report in **English**. + ### Instructions + First time reporting? See [tips](https://wiki.blender.org/wiki/Process/Bug_Reports) and [walkthrough video](https://www.youtube.com/watch?v=JTD0OJq_rF4). - ### What not to report here - For feature requests, feedback, questions or issues building Blender, see [communication channels](https://wiki.blender.org/wiki/Communication/Contact#User_Feedback_and_Requests). - - ### Please verify - * Always test with the latest official release from [blender.org](https://www.blender.org/) and daily build from [builder.blender.org](https://builder.blender.org/). - * Please use `Help > Report a Bug` in Blender to automatically fill system information and exact Blender version. - * Test [previous Blender versions](https://download.blender.org/release/) to find the latest version that was working as expected. - * Find steps to redo the bug consistently without any non-official add-ons, and include a **small and simple .blend file** to demonstrate the bug. + * Use **Help > Report a Bug** in Blender to automatically fill system information and exact Blender version. + * Test [daily builds](https://builder.blender.org/) to verify if the issue is already fixed. + * Test [previous versions](https://download.blender.org/release/) to find an older working version. + * For feature requests, feedback, questions or issues building Blender, see [communication channels](https://wiki.blender.org/wiki/Communication/Contact#User_Feedback_and_Requests). * If there are multiple bugs, make multiple bug reports. - * Sometimes, driver or software upgrades cause problems. On Windows, try a clean install of the graphics drivers. - - ### Help the developers - Bug fixing is important, the developers will handle a report swiftly. For that reason, we need your help to carefully provide instructions that others can follow quickly. You do your half of the work, then we do our half! - - If a report is tagged with Needs Information from User and it has no reply after a week, we will assume the issue is gone and close the report. - type: textarea id: body @@ -44,3 +34,9 @@ body: **Exact steps for others to reproduce the error** Based on the default startup or an attached .blend file (as simple as possible). + - type: markdown + attributes: + value: | + ### Help the developers + + Bug fixing is important, the developers will handle a report swiftly. For that reason, carefully provide exact steps and a **small and simple .blend file** to reproduce the problem. You do your half of the work, then we do our half! From 6e6ae1733579bf56ee6269ff25114ac1de46b44f Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Wed, 18 Jan 2023 13:08:33 +0100 Subject: [PATCH 0733/1522] Fix reversed `cosNI` and `cosNO` in Cycles anisotropic beckmann G1 --- intern/cycles/kernel/closure/bsdf_microfacet.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 611d45b73cc..90ae42dd7a6 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -871,8 +871,8 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const Micr D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4); /* G1(i,m) and G1(o,m) */ - G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(wi, X), dot(wi, Y)); - G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(wo, X), dot(wo, Y)); + G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(wi, X), dot(wi, Y)); + G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(wo, X), dot(wo, Y)); } float G = G1i * G1o; From cf50a3eabce47810d38c093be63919487dfbe42c Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Wed, 18 Jan 2023 13:24:00 +0100 Subject: [PATCH 0734/1522] Cleanup: remove is_same method for virtual arrays This abstraction is rarely used. It could be replaced by some more general "query" API in the future. For now it's easier to just compare pointers in the Set Position node where this was used. This is possible now, because mesh positions are stored as flat `float3` arrays (previously, they were stored as `MVert` with some other data interleaved). --- source/blender/blenlib/BLI_virtual_array.hh | 57 ------------------- .../geometry/nodes/node_geo_set_position.cc | 13 ++++- 2 files changed, 10 insertions(+), 60 deletions(-) diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh index 819807843df..c57c1dae961 100644 --- a/source/blender/blenlib/BLI_virtual_array.hh +++ b/source/blender/blenlib/BLI_virtual_array.hh @@ -156,15 +156,6 @@ template class VArrayImpl { { return false; } - - /** - * Return true when the other virtual array should be considered to be the same, e.g. because it - * shares the same underlying memory. - */ - virtual bool is_same(const VArrayImpl & /*other*/) const - { - return false; - } }; /** Similar to #VArrayImpl, but adds methods that allow modifying the referenced elements. */ @@ -238,18 +229,6 @@ template class VArrayImpl_For_Span : public VMutableArrayImpl { return CommonVArrayInfo(CommonVArrayInfo::Type::Span, true, data_); } - bool is_same(const VArrayImpl &other) const final - { - if (other.size() != this->size_) { - return false; - } - const CommonVArrayInfo other_info = other.common_info(); - if (other_info.type != CommonVArrayInfo::Type::Span) { - return false; - } - return data_ == static_cast(other_info.data); - } - void materialize(IndexMask mask, T *dst) const override { mask.foreach_index([&](const int64_t i) { dst[i] = data_[i]; }); @@ -482,23 +461,6 @@ class VArrayImpl_For_DerivedSpan final : public VMutableArrayImpl { } }); } - - bool is_same(const VArrayImpl &other) const override - { - if (other.size() != this->size_) { - return false; - } - if (const VArrayImpl_For_DerivedSpan *other_typed = - dynamic_cast *>(&other)) { - return other_typed->data_ == data_; - } - if (const VArrayImpl_For_DerivedSpan *other_typed = - dynamic_cast *>( - &other)) { - return other_typed->data_ == data_; - } - return false; - } }; template class VArrayCommon { return *static_cast(info.data); } - /** - * Return true when the other virtual references the same underlying memory. - */ - bool is_same(const VArrayCommon &other) const - { - if (!*this || !other) { - return false; - } - /* Check in both directions in case one does not know how to compare to the other - * implementation. */ - if (impl_->is_same(*other.impl_)) { - return true; - } - if (other.impl_->is_same(*impl_)) { - return true; - } - return false; - } - /** Copy the entire virtual array into a span. */ void materialize(MutableSpan r_span) const { diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index caa911a5f45..2ad126567d1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -29,9 +29,16 @@ static void set_computed_position_and_offset(GeometryComponent &component, const IndexMask selection) { MutableAttributeAccessor attributes = *component.attributes_for_write(); - const VArray positions_read_only = attributes.lookup("position"); - if (in_positions.is_same(positions_read_only)) { + /* Optimize the case when `in_positions` references the original positions array. */ + const VArray positions_read_only = attributes.lookup("position"); + bool positions_are_original = false; + if (positions_read_only.is_span() && in_positions.is_span()) { + positions_are_original = positions_read_only.get_internal_span().data() == + in_positions.get_internal_span().data(); + } + + if (positions_are_original) { if (const std::optional offset = in_offsets.get_if_single()) { if (math::is_zero(*offset)) { return; @@ -81,7 +88,7 @@ static void set_computed_position_and_offset(GeometryComponent &component, default: { AttributeWriter positions = attributes.lookup_for_write("position"); MutableVArraySpan out_positions_span = positions.varray; - if (in_positions.is_same(positions_read_only)) { + if (positions_are_original) { devirtualize_varray(in_offsets, [&](const auto in_offsets) { threading::parallel_for( selection.index_range(), grain_size, [&](const IndexRange range) { From 21b3689fb9cfdb1f67cebceb927b1afa5564a059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Jan 2023 14:19:27 +0100 Subject: [PATCH 0735/1522] DRW: GPU Wrappers: Add swap to storage buffers, empty framebuffer and fixes Also add an assert to mip_view to avoid incorrect usage. --- source/blender/draw/intern/DRW_gpu_wrapper.hh | 41 ++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/source/blender/draw/intern/DRW_gpu_wrapper.hh b/source/blender/draw/intern/DRW_gpu_wrapper.hh index 5f11beecc15..3e53f1510f6 100644 --- a/source/blender/draw/intern/DRW_gpu_wrapper.hh +++ b/source/blender/draw/intern/DRW_gpu_wrapper.hh @@ -366,6 +366,14 @@ class StorageArrayBuffer : public detail::StorageCommon { { return this->len_; } + + static void swap(StorageArrayBuffer &a, StorageArrayBuffer &b) + { + SWAP(T *, a.data_, b.data_); + SWAP(GPUStorageBuf *, a.ssbo_, b.ssbo_); + SWAP(int64_t, a.len_, b.len_); + SWAP(const char *, a.name_, b.name_); + } }; template< @@ -426,6 +434,12 @@ class StorageVectorBuffer : public StorageArrayBuffer { /* Avoid confusion with the other clear. */ void clear_to_zero() = delete; + + static void swap(StorageVectorBuffer &a, StorageVectorBuffer &b) + { + StorageArrayBuffer::swap(a, b); + SWAP(int64_t, a.item_len_, b.item_len_); + } }; template< @@ -671,6 +685,9 @@ class Texture : NonCopyable { GPUTexture *mip_view(int miplvl) { + BLI_assert_msg(miplvl < mip_views_.size(), + "Incorrect mip level requested. " + "Might be missing call to ensure_mip_views()."); return mip_views_[miplvl]; } @@ -766,7 +783,7 @@ class Texture : NonCopyable { int3 size(int miplvl = 0) const { - int3 size(0); + int3 size(1); GPU_texture_get_mipmap_size(tx_, miplvl, size); return size; } @@ -995,8 +1012,7 @@ class TextureRef : public Texture { * Dummy type to bind texture as image. * It is just a GPUTexture in disguise. */ -class Image { -}; +class Image {}; static inline Image *as_image(GPUTexture *tex) { @@ -1048,8 +1064,23 @@ class Framebuffer : NonCopyable { GPUAttachment color7 = GPU_ATTACHMENT_NONE, GPUAttachment color8 = GPU_ATTACHMENT_NONE) { - GPU_framebuffer_ensure_config( - &fb_, {depth, color1, color2, color3, color4, color5, color6, color7, color8}); + if (fb_ == NULL) { + fb_ = GPU_framebuffer_create(name_); + } + GPUAttachment config[] = { + depth, color1, color2, color3, color4, color5, color6, color7, color8}; + GPU_framebuffer_config_array(fb_, config, sizeof(config) / sizeof(GPUAttachment)); + } + + /** + * Empty frame-buffer configuration. + */ + void ensure(int2 target_size) + { + if (fb_ == NULL) { + fb_ = GPU_framebuffer_create(name_); + } + GPU_framebuffer_default_size(fb_, UNPACK2(target_size)); } Framebuffer &operator=(Framebuffer &&a) From 493e3230b425ef4cdd33572b7c8547a2538bd4de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Jan 2023 14:20:56 +0100 Subject: [PATCH 0736/1522] DRW: Fix display print Wrong uniform for viewport size. --- source/blender/draw/intern/draw_debug.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_debug.cc b/source/blender/draw/intern/draw_debug.cc index e4fadad2b8e..fc20c00e0cc 100644 --- a/source/blender/draw/intern/draw_debug.cc +++ b/source/blender/draw/intern/draw_debug.cc @@ -558,7 +558,7 @@ void DebugDraw::display_prints() int slot = GPU_shader_get_builtin_ssbo(shader, GPU_STORAGE_BUFFER_DEBUG_PRINT); float f_viewport[4]; GPU_viewport_size_get_f(f_viewport); - GPU_shader_uniform_2fv(shader, "viewport_size", f_viewport); + GPU_shader_uniform_2fv(shader, "viewport_size", &f_viewport[2]); if (gpu_print_buf_used) { GPU_debug_group_begin("GPU"); From efe51f02200d155791ea7e99793e78967bab8c84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Jan 2023 14:24:25 +0100 Subject: [PATCH 0737/1522] DRW: View: Allow for GPU side specification of view bounds This allows an engine to perform GPU side view specification and let the draw manager extract the culling informations (bounds). To this end, the matrices ubo gets exposed to be able to write to it. `compute_procedural_bounds()` need to be explicitely called before any main pass using the culling result. --- source/blender/draw/CMakeLists.txt | 1 + source/blender/draw/intern/draw_shader.cc | 10 ++ source/blender/draw/intern/draw_shader.h | 1 + source/blender/draw/intern/draw_view.cc | 24 ++++ source/blender/draw/intern/draw_view.hh | 17 ++- .../shaders/draw_view_finalize_comp.glsl | 135 ++++++++++++++++++ .../draw/intern/shaders/draw_view_info.hh | 8 ++ 7 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 source/blender/draw/intern/shaders/draw_view_finalize_comp.glsl diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 2093c8a2331..2c4d2b65ea5 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -530,6 +530,7 @@ set(GLSL_SRC intern/shaders/draw_debug_print_display_frag.glsl intern/shaders/draw_debug_print_display_vert.glsl intern/shaders/draw_resource_finalize_comp.glsl + intern/shaders/draw_view_finalize_comp.glsl intern/shaders/draw_visibility_comp.glsl intern/draw_command_shared.hh diff --git a/source/blender/draw/intern/draw_shader.cc b/source/blender/draw/intern/draw_shader.cc index 72392ddb9ab..c0d87fa42ab 100644 --- a/source/blender/draw/intern/draw_shader.cc +++ b/source/blender/draw/intern/draw_shader.cc @@ -24,6 +24,7 @@ static struct { struct GPUShader *debug_print_display_sh; struct GPUShader *debug_draw_display_sh; struct GPUShader *draw_visibility_compute_sh; + struct GPUShader *draw_view_finalize_sh; struct GPUShader *draw_resource_finalize_sh; struct GPUShader *draw_command_generate_sh; } e_data = {{nullptr}}; @@ -121,6 +122,14 @@ GPUShader *DRW_shader_draw_visibility_compute_get() return e_data.draw_visibility_compute_sh; } +GPUShader *DRW_shader_draw_view_finalize_get() +{ + if (e_data.draw_view_finalize_sh == nullptr) { + e_data.draw_view_finalize_sh = GPU_shader_create_from_info_name("draw_view_finalize"); + } + return e_data.draw_view_finalize_sh; +} + GPUShader *DRW_shader_draw_resource_finalize_get() { if (e_data.draw_resource_finalize_sh == nullptr) { @@ -147,6 +156,7 @@ void DRW_shaders_free() DRW_SHADER_FREE_SAFE(e_data.debug_print_display_sh); DRW_SHADER_FREE_SAFE(e_data.debug_draw_display_sh); DRW_SHADER_FREE_SAFE(e_data.draw_visibility_compute_sh); + DRW_SHADER_FREE_SAFE(e_data.draw_view_finalize_sh); DRW_SHADER_FREE_SAFE(e_data.draw_resource_finalize_sh); DRW_SHADER_FREE_SAFE(e_data.draw_command_generate_sh); } diff --git a/source/blender/draw/intern/draw_shader.h b/source/blender/draw/intern/draw_shader.h index 3b8c0425fa9..e4c71812471 100644 --- a/source/blender/draw/intern/draw_shader.h +++ b/source/blender/draw/intern/draw_shader.h @@ -33,6 +33,7 @@ struct GPUShader *DRW_shader_curves_refine_get(CurvesEvalShader type, struct GPUShader *DRW_shader_debug_print_display_get(void); struct GPUShader *DRW_shader_debug_draw_display_get(void); struct GPUShader *DRW_shader_draw_visibility_compute_get(void); +struct GPUShader *DRW_shader_draw_view_finalize_get(void); struct GPUShader *DRW_shader_draw_resource_finalize_get(void); struct GPUShader *DRW_shader_draw_command_generate_get(void); diff --git a/source/blender/draw/intern/draw_view.cc b/source/blender/draw/intern/draw_view.cc index 5028b24c541..58212d2b17f 100644 --- a/source/blender/draw/intern/draw_view.cc +++ b/source/blender/draw/intern/draw_view.cc @@ -207,6 +207,16 @@ void View::frustum_culling_sphere_calc(int view_id) } } +void View::disable(IndexRange range) +{ + /* Set bounding sphere to -1.0f radius will bypass the culling test and treat every instance as + * invisible. */ + range = IndexRange(view_len_).intersect(range); + for (auto view_id : range) { + reinterpret_cast(&culling_[view_id].bound_sphere)->radius = -1.0f; + } +} + void View::bind() { if (dirty_ && !procedural_) { @@ -219,6 +229,20 @@ void View::bind() GPU_uniformbuf_bind(culling_, DRW_VIEW_CULLING_UBO_SLOT); } +void View::compute_procedural_bounds() +{ + GPU_debug_group_begin("View.compute_procedural_bounds"); + + GPUShader *shader = DRW_shader_draw_view_finalize_get(); + GPU_shader_bind(shader); + GPU_uniformbuf_bind_as_ssbo(culling_, GPU_shader_get_ssbo(shader, "view_culling_buf")); + GPU_uniformbuf_bind(data_, DRW_VIEW_UBO_SLOT); + GPU_compute_dispatch(shader, 1, 1, 1); + GPU_memory_barrier(GPU_BARRIER_UNIFORM); + + GPU_debug_group_end(); +} + void View::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool debug_freeze) { if (debug_freeze && frozen_ == false) { diff --git a/source/blender/draw/intern/draw_view.hh b/source/blender/draw/intern/draw_view.hh index 3a3191e2a62..e18abf94fce 100644 --- a/source/blender/draw/intern/draw_view.hh +++ b/source/blender/draw/intern/draw_view.hh @@ -57,7 +57,7 @@ class View { View(const char *name, int view_len = 1, bool procedural = false) : visibility_buf_(name), debug_name_(name), view_len_(view_len), procedural_(procedural) { - BLI_assert(view_len < DRW_VIEW_MAX); + BLI_assert(view_len <= DRW_VIEW_MAX); } /* For compatibility with old system. Will be removed at some point. */ @@ -72,6 +72,16 @@ class View { void sync(const float4x4 &view_mat, const float4x4 &win_mat, int view_id = 0); + /** Disable a range in the multi-view array. Disabled view will not produce any instances. */ + void disable(IndexRange range); + + /** + * Update culling data using a compute shader. + * This is to be used if the matrices were updated externally + * on the GPU (not using the `sync()` method). + **/ + void compute_procedural_bounds(); + bool is_persp(int view_id = 0) const { BLI_assert(view_id < view_len_); @@ -132,6 +142,11 @@ class View { return (view_len_ == 1) ? 0 : divide_ceil_u(view_len_, 32); } + UniformArrayBuffer &matrices_ubo_get() + { + return data_; + } + private: /** Called from draw manager. */ void bind(); diff --git a/source/blender/draw/intern/shaders/draw_view_finalize_comp.glsl b/source/blender/draw/intern/shaders/draw_view_finalize_comp.glsl new file mode 100644 index 00000000000..f3af010a47c --- /dev/null +++ b/source/blender/draw/intern/shaders/draw_view_finalize_comp.glsl @@ -0,0 +1,135 @@ + +/** + * Compute culling data for each views of a given view buffer. + */ + +#pragma BLENDER_REQUIRE(common_math_lib.glsl) + +void projmat_dimensions(mat4 winmat, + out float r_left, + out float r_right, + out float r_bottom, + out float r_top, + out float r_near, + out float r_far) +{ + const bool is_persp = winmat[3][3] == 0.0; + if (is_persp) { + float near = winmat[3][2] / (winmat[2][2] - 1.0); + r_left = near * ((winmat[2][0] - 1.0) / winmat[0][0]); + r_right = near * ((winmat[2][0] + 1.0) / winmat[0][0]); + r_bottom = near * ((winmat[2][1] - 1.0) / winmat[1][1]); + r_top = near * ((winmat[2][1] + 1.0) / winmat[1][1]); + r_near = near; + r_far = winmat[3][2] / (winmat[2][2] + 1.0); + } + else { + r_left = (-winmat[3][0] - 1.0) / winmat[0][0]; + r_right = (-winmat[3][0] + 1.0) / winmat[0][0]; + r_bottom = (-winmat[3][1] - 1.0) / winmat[1][1]; + r_top = (-winmat[3][1] + 1.0) / winmat[1][1]; + r_near = (winmat[3][2] + 1.0) / winmat[2][2]; + r_far = (winmat[3][2] - 1.0) / winmat[2][2]; + } +} + +void frustum_boundbox_calc(mat4 winmat, mat4 viewinv, out vec4 corners[8]) +{ + float left, right, bottom, top, near, far; + bool is_persp = winmat[3][3] == 0.0; + + projmat_dimensions(winmat, left, right, bottom, top, near, far); + + corners[0][2] = corners[3][2] = corners[7][2] = corners[4][2] = -near; + corners[0][0] = corners[3][0] = left; + corners[4][0] = corners[7][0] = right; + corners[0][1] = corners[4][1] = bottom; + corners[7][1] = corners[3][1] = top; + + /* Get the coordinates of the far plane. */ + if (is_persp) { + float sca_far = far / near; + left *= sca_far; + right *= sca_far; + bottom *= sca_far; + top *= sca_far; + } + + corners[1][2] = corners[2][2] = corners[6][2] = corners[5][2] = -far; + corners[1][0] = corners[2][0] = left; + corners[6][0] = corners[5][0] = right; + corners[1][1] = corners[5][1] = bottom; + corners[2][1] = corners[6][1] = top; + + /* Transform into world space. */ + for (int i = 0; i < 8; i++) { + corners[i].xyz = transform_point(viewinv, corners[i].xyz); + } +} + +void planes_from_projmat(mat4 mat, + out vec4 left, + out vec4 right, + out vec4 bottom, + out vec4 top, + out vec4 near, + out vec4 far) +{ + /* References: + * + * https://fgiesen.wordpress.com/2012/08/31/frustum-planes-from-the-projection-matrix/ + * http://www8.cs.umu.se/kurser/5DV051/HT12/lab/plane_extraction.pdf + */ + mat = transpose(mat); + left = mat[3] + mat[0]; + right = mat[3] - mat[0]; + bottom = mat[3] + mat[1]; + top = mat[3] - mat[1]; + near = mat[3] + mat[2]; + far = mat[3] - mat[2]; +} + +void frustum_culling_planes_calc(mat4 winmat, mat4 viewmat, out vec4 planes[6]) +{ + mat4 persmat = winmat * viewmat; + planes_from_projmat(persmat, planes[0], planes[5], planes[1], planes[3], planes[4], planes[2]); + + /* Normalize. */ + for (int p = 0; p < 6; p++) { + planes[p] /= length(planes[p].xyz); + } +} + +vec4 frustum_culling_sphere_calc(vec4 corners[8]) +{ + /* Extract Bounding Sphere */ + /* TODO(fclem): This is significantly less precise than CPU, but it isn't used in most cases. */ + + vec4 bsphere; + bsphere.xyz = (corners[0].xyz + corners[6].xyz) * 0.5; + bsphere.w = 0.0; + for (int i = 0; i < 8; i++) { + bsphere.w = max(bsphere.w, distance(bsphere.xyz, corners[i].xyz)); + } + return bsphere; +} + +void main() +{ + drw_view_id = int(gl_LocalInvocationID.x); + + /* Invalid views are disabled. */ + if (all(equal(drw_view.viewinv[2].xyz, vec3(0.0)))) { + /* Views with negative radius are treated as disabled. */ + view_culling_buf[drw_view_id].bound_sphere = vec4(-1.0); + return; + } + + frustum_boundbox_calc(drw_view.winmat, drw_view.viewinv, view_culling_buf[drw_view_id].corners); + + frustum_culling_planes_calc( + drw_view.winmat, drw_view.viewmat, view_culling_buf[drw_view_id].planes); + + view_culling_buf[drw_view_id].bound_sphere = frustum_culling_sphere_calc( + view_culling_buf[drw_view_id].corners); +} diff --git a/source/blender/draw/intern/shaders/draw_view_info.hh b/source/blender/draw/intern/shaders/draw_view_info.hh index 4e1a45934f1..e18bd469ff0 100644 --- a/source/blender/draw/intern/shaders/draw_view_info.hh +++ b/source/blender/draw/intern/shaders/draw_view_info.hh @@ -156,6 +156,14 @@ GPU_SHADER_CREATE_INFO(draw_resource_finalize) .push_constant(Type::INT, "resource_len") .compute_source("draw_resource_finalize_comp.glsl"); +GPU_SHADER_CREATE_INFO(draw_view_finalize) + .do_static_compilation(true) + .local_group_size(64) /* DRW_VIEW_MAX */ + .define("DRW_VIEW_LEN", "64") + .storage_buf(0, Qualifier::READ_WRITE, "ViewCullingData", "view_culling_buf[DRW_VIEW_LEN]") + .compute_source("draw_view_finalize_comp.glsl") + .additional_info("draw_view"); + GPU_SHADER_CREATE_INFO(draw_visibility_compute) .do_static_compilation(true) .local_group_size(DRW_VISIBILITY_GROUP_SIZE) From 9c54f2655d704bff0a4f39f3fda227b8bb558898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Jan 2023 14:30:47 +0100 Subject: [PATCH 0738/1522] DRW: Add double buffering of objects matrices, bounds, and infos This allows easy delta calculation and access to last known position of deleted objects. --- source/blender/draw/intern/draw_command.cc | 38 +++++++++++++------ source/blender/draw/intern/draw_command.hh | 19 +++++++++- source/blender/draw/intern/draw_manager.cc | 44 ++++++++++++---------- source/blender/draw/intern/draw_manager.hh | 26 ++++++------- source/blender/draw/intern/draw_pass.hh | 6 ++- 5 files changed, 87 insertions(+), 46 deletions(-) diff --git a/source/blender/draw/intern/draw_command.cc b/source/blender/draw/intern/draw_command.cc index 8c89c28a628..0455e2ab9d6 100644 --- a/source/blender/draw/intern/draw_command.cc +++ b/source/blender/draw/intern/draw_command.cc @@ -11,6 +11,7 @@ #include "GPU_debug.h" #include "draw_command.hh" +#include "draw_pass.hh" #include "draw_shader.h" #include "draw_view.hh" @@ -530,15 +531,20 @@ std::string StencilSet::serialize() const /** \name Commands buffers binding / command / resource ID generation * \{ */ -void DrawCommandBuf::bind(RecordingState &state, - Vector &headers, - Vector &commands) +void DrawCommandBuf::finalize_commands(Vector &headers, + Vector &commands, + SubPassVector &sub_passes, + uint &resource_id_count, + ResourceIdBuf &resource_id_buf) { - UNUSED_VARS(headers, commands); - - resource_id_count_ = 0; - for (const Header &header : headers) { + if (header.type == Type::SubPass) { + /** WARNING: Recursive. */ + auto &sub = sub_passes[int64_t(header.index)]; + finalize_commands( + sub.headers_, sub.commands_, sub_passes, resource_id_count, resource_id_buf); + } + if (header.type != Type::Draw) { continue; } @@ -559,18 +565,28 @@ void DrawCommandBuf::bind(RecordingState &state, if (cmd.handle.raw > 0) { /* Save correct offset to start of resource_id buffer region for this draw. */ - uint instance_first = resource_id_count_; - resource_id_count_ += cmd.instance_len; + uint instance_first = resource_id_count; + resource_id_count += cmd.instance_len; /* Ensure the buffer is big enough. */ - resource_id_buf_.get_or_resize(resource_id_count_ - 1); + resource_id_buf.get_or_resize(resource_id_count - 1); /* Copy the resource id for all instances. */ uint index = cmd.handle.resource_index(); for (int i = instance_first; i < (instance_first + cmd.instance_len); i++) { - resource_id_buf_[i] = index; + resource_id_buf[i] = index; } } } +} + +void DrawCommandBuf::bind(RecordingState &state, + Vector &headers, + Vector &commands, + SubPassVector &sub_passes) +{ + resource_id_count_ = 0; + + finalize_commands(headers, commands, sub_passes, resource_id_count_, resource_id_buf_); resource_id_buf_.push_update(); diff --git a/source/blender/draw/intern/draw_command.hh b/source/blender/draw/intern/draw_command.hh index 760531899f4..45a7ff417ac 100644 --- a/source/blender/draw/intern/draw_command.hh +++ b/source/blender/draw/intern/draw_command.hh @@ -21,6 +21,12 @@ #include "draw_state.h" #include "draw_view.hh" +/* Forward declarations. */ +namespace blender::draw::detail { +template class SubPassVector; +template class PassBase; +} // namespace blender::draw::detail + namespace blender::draw::command { class DrawCommandBuf; @@ -411,6 +417,7 @@ class DrawCommandBuf { private: using ResourceIdBuf = StorageArrayBuffer; + using SubPassVector = detail::SubPassVector, 16>; /** Array of resource id. One per instance. Generated on GPU and send to GPU. */ ResourceIdBuf resource_id_buf_; @@ -436,7 +443,17 @@ class DrawCommandBuf { commands[index].draw = {batch, instance_len, vertex_len, vertex_first, handle}; } - void bind(RecordingState &state, Vector &headers, Vector &commands); + void bind(RecordingState &state, + Vector &headers, + Vector &commands, + SubPassVector &sub_passes); + + private: + static void finalize_commands(Vector &headers, + Vector &commands, + SubPassVector &sub_passes, + uint &resource_id_count, + ResourceIdBuf &resource_id_buf); }; /** \} */ diff --git a/source/blender/draw/intern/draw_manager.cc b/source/blender/draw/intern/draw_manager.cc index 37ed1de1dfe..7bf83872344 100644 --- a/source/blender/draw/intern/draw_manager.cc +++ b/source/blender/draw/intern/draw_manager.cc @@ -27,6 +27,10 @@ Manager::~Manager() void Manager::begin_sync() { + matrix_buf.swap(); + bounds_buf.swap(); + infos_buf.swap(); + /* TODO: This means the reference is kept until further redraw or manager tear-down. Instead, * they should be released after each draw loop. But for now, mimics old DRW behavior. */ for (GPUTexture *texture : acquired_textures) { @@ -39,9 +43,9 @@ void Manager::begin_sync() #ifdef DEBUG /* Detect uninitialized data. */ - memset(matrix_buf.data(), 0xF0, resource_len_ * sizeof(*matrix_buf.data())); - memset(bounds_buf.data(), 0xF0, resource_len_ * sizeof(*bounds_buf.data())); - memset(infos_buf.data(), 0xF0, resource_len_ * sizeof(*infos_buf.data())); + memset(matrix_buf.current().data(), 0xF0, resource_len_ * sizeof(*matrix_buf.current().data())); + memset(bounds_buf.current().data(), 0xF0, resource_len_ * sizeof(*bounds_buf.current().data())); + memset(infos_buf.current().data(), 0xF0, resource_len_ * sizeof(*infos_buf.current().data())); #endif resource_len_ = 0; attribute_len_ = 0; @@ -88,9 +92,9 @@ void Manager::end_sync() sync_layer_attributes(); - matrix_buf.push_update(); - bounds_buf.push_update(); - infos_buf.push_update(); + matrix_buf.current().push_update(); + bounds_buf.current().push_update(); + infos_buf.current().push_update(); attributes_buf.push_update(); layer_attributes_buf.push_update(); attributes_buf_legacy.push_update(); @@ -104,9 +108,9 @@ void Manager::end_sync() GPUShader *shader = DRW_shader_draw_resource_finalize_get(); GPU_shader_bind(shader); GPU_shader_uniform_1i(shader, "resource_len", resource_len_); - GPU_storagebuf_bind(matrix_buf, GPU_shader_get_ssbo(shader, "matrix_buf")); - GPU_storagebuf_bind(bounds_buf, GPU_shader_get_ssbo(shader, "bounds_buf")); - GPU_storagebuf_bind(infos_buf, GPU_shader_get_ssbo(shader, "infos_buf")); + GPU_storagebuf_bind(matrix_buf.current(), GPU_shader_get_ssbo(shader, "matrix_buf")); + GPU_storagebuf_bind(bounds_buf.current(), GPU_shader_get_ssbo(shader, "bounds_buf")); + GPU_storagebuf_bind(infos_buf.current(), GPU_shader_get_ssbo(shader, "infos_buf")); GPU_compute_dispatch(shader, thread_groups, 1, 1); GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE); @@ -130,8 +134,8 @@ void Manager::debug_bind() void Manager::resource_bind() { - GPU_storagebuf_bind(matrix_buf, DRW_OBJ_MAT_SLOT); - GPU_storagebuf_bind(infos_buf, DRW_OBJ_INFOS_SLOT); + GPU_storagebuf_bind(matrix_buf.current(), DRW_OBJ_MAT_SLOT); + GPU_storagebuf_bind(infos_buf.current(), DRW_OBJ_INFOS_SLOT); GPU_storagebuf_bind(attributes_buf, DRW_OBJ_ATTR_SLOT); GPU_uniformbuf_bind(layer_attributes_buf, DRW_LAYER_ATTR_UBO_SLOT); /* 2 is the hardcoded location of the uniform attr UBO. */ @@ -148,7 +152,7 @@ void Manager::submit(PassSimple &pass, View &view) command::RecordingState state; state.inverted_view = view.is_inverted(); - pass.draw_commands_buf_.bind(state, pass.headers_, pass.commands_); + pass.draw_commands_buf_.bind(state, pass.headers_, pass.commands_, pass.sub_passes_); resource_bind(); @@ -166,7 +170,7 @@ void Manager::submit(PassMain &pass, View &view) bool freeze_culling = (U.experimental.use_viewport_debug && DST.draw_ctx.v3d && (DST.draw_ctx.v3d->debug_flag & V3D_DEBUG_FREEZE_CULLING) != 0); - view.compute_visibility(bounds_buf, resource_len_, freeze_culling); + view.compute_visibility(bounds_buf.current(), resource_len_, freeze_culling); command::RecordingState state; state.inverted_view = view.is_inverted(); @@ -198,7 +202,7 @@ void Manager::submit(PassSimple &pass) command::RecordingState state; - pass.draw_commands_buf_.bind(state, pass.headers_, pass.commands_); + pass.draw_commands_buf_.bind(state, pass.headers_, pass.commands_, pass.sub_passes_); resource_bind(); @@ -239,14 +243,14 @@ Manager::SubmitDebugOutput Manager::submit_debug(PassMain &pass, View &view) Manager::DataDebugOutput Manager::data_debug() { - matrix_buf.read(); - bounds_buf.read(); - infos_buf.read(); + matrix_buf.current().read(); + bounds_buf.current().read(); + infos_buf.current().read(); Manager::DataDebugOutput output; - output.matrices = {matrix_buf.data(), resource_len_}; - output.bounds = {bounds_buf.data(), resource_len_}; - output.infos = {infos_buf.data(), resource_len_}; + output.matrices = {matrix_buf.current().data(), resource_len_}; + output.bounds = {bounds_buf.current().data(), resource_len_}; + output.infos = {infos_buf.current().data(), resource_len_}; return output; } diff --git a/source/blender/draw/intern/draw_manager.hh b/source/blender/draw/intern/draw_manager.hh index 0a865179cee..51d5c841711 100644 --- a/source/blender/draw/intern/draw_manager.hh +++ b/source/blender/draw/intern/draw_manager.hh @@ -72,9 +72,9 @@ class Manager { * Buffers containing all object data. Referenced by resource index. * Exposed as public members for shader access after sync. */ - ObjectMatricesBuf matrix_buf; - ObjectBoundsBuf bounds_buf; - ObjectInfosBuf infos_buf; + SwapChain matrix_buf; + SwapChain bounds_buf; + SwapChain infos_buf; /** * Object Attributes are reference by indirection data inside ObjectInfos. @@ -193,17 +193,17 @@ class Manager { inline ResourceHandle Manager::resource_handle(const ObjectRef ref) { bool is_active_object = (ref.dupli_object ? ref.dupli_parent : ref.object) == object_active; - matrix_buf.get_or_resize(resource_len_).sync(*ref.object); - bounds_buf.get_or_resize(resource_len_).sync(*ref.object); - infos_buf.get_or_resize(resource_len_).sync(ref, is_active_object); + matrix_buf.current().get_or_resize(resource_len_).sync(*ref.object); + bounds_buf.current().get_or_resize(resource_len_).sync(*ref.object); + infos_buf.current().get_or_resize(resource_len_).sync(ref, is_active_object); return ResourceHandle(resource_len_++, (ref.object->transflag & OB_NEG_SCALE) != 0); } inline ResourceHandle Manager::resource_handle(const float4x4 &model_matrix) { - matrix_buf.get_or_resize(resource_len_).sync(model_matrix); - bounds_buf.get_or_resize(resource_len_).sync(); - infos_buf.get_or_resize(resource_len_).sync(); + matrix_buf.current().get_or_resize(resource_len_).sync(model_matrix); + bounds_buf.current().get_or_resize(resource_len_).sync(); + infos_buf.current().get_or_resize(resource_len_).sync(); return ResourceHandle(resource_len_++, false); } @@ -211,9 +211,9 @@ inline ResourceHandle Manager::resource_handle(const float4x4 &model_matrix, const float3 &bounds_center, const float3 &bounds_half_extent) { - matrix_buf.get_or_resize(resource_len_).sync(model_matrix); - bounds_buf.get_or_resize(resource_len_).sync(bounds_center, bounds_half_extent); - infos_buf.get_or_resize(resource_len_).sync(); + matrix_buf.current().get_or_resize(resource_len_).sync(model_matrix); + bounds_buf.current().get_or_resize(resource_len_).sync(bounds_center, bounds_half_extent); + infos_buf.current().get_or_resize(resource_len_).sync(); return ResourceHandle(resource_len_++, false); } @@ -221,7 +221,7 @@ inline void Manager::extract_object_attributes(ResourceHandle handle, const ObjectRef &ref, Span materials) { - ObjectInfos &infos = infos_buf.get_or_resize(handle.resource_index()); + ObjectInfos &infos = infos_buf.current().get_or_resize(handle.resource_index()); infos.object_attrs_offset = attribute_len_; /* Simple cache solution to avoid duplicates. */ diff --git a/source/blender/draw/intern/draw_pass.hh b/source/blender/draw/intern/draw_pass.hh index 8523b9ae5e6..6244218f3ff 100644 --- a/source/blender/draw/intern/draw_pass.hh +++ b/source/blender/draw/intern/draw_pass.hh @@ -55,12 +55,15 @@ #include "intern/gpu_codegen.h" namespace blender::draw { - using namespace blender::draw; using namespace blender::draw::command; class Manager; +namespace command { +class DrawCommandBuf; +} + /* -------------------------------------------------------------------- */ /** \name Pass API * \{ */ @@ -112,6 +115,7 @@ template< typename DrawCommandBufType> class PassBase { friend Manager; + friend DrawCommandBuf; /** Will use texture own sampler state. */ static constexpr eGPUSamplerState sampler_auto = GPU_SAMPLER_MAX; From e6be3f96d80bf559571a1af0b77ed7f7d86263c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Jan 2023 14:31:13 +0100 Subject: [PATCH 0739/1522] DRW: Fix DRW_VIEW_FROM_RESOURCE_ID --- source/blender/draw/intern/draw_shader_shared.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/intern/draw_shader_shared.h b/source/blender/draw/intern/draw_shader_shared.h index 3d0b3930121..3b1afa0e6cb 100644 --- a/source/blender/draw/intern/draw_shader_shared.h +++ b/source/blender/draw/intern/draw_shader_shared.h @@ -70,6 +70,7 @@ typedef enum eObjectInfoFlag eObjectInfoFlag; # define drw_view_id 0 # define DRW_VIEW_LEN 1 # define DRW_VIEW_SHIFT 0 +# define DRW_VIEW_FROM_RESOURCE_ID #else /* Multi-view case. */ @@ -90,7 +91,7 @@ uint drw_view_id = 0; (DRW_VIEW_LEN > 2) ? 2 : \ 1) # define DRW_VIEW_MASK ~(0xFFFFFFFFu << DRW_VIEW_SHIFT) -# define DRW_VIEW_FROM_RESOURCE_ID (drw_ResourceID & DRW_VIEW_MASK) +# define DRW_VIEW_FROM_RESOURCE_ID drw_view_id = (drw_ResourceID & DRW_VIEW_MASK) #endif struct ViewCullingData { From df74a9b624644ae6a716ddea23172a60e7f610eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Jan 2023 14:31:54 +0100 Subject: [PATCH 0740/1522] DRW: Tests: Add test for PassSimple::Sub --- source/blender/draw/tests/draw_pass_test.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/draw/tests/draw_pass_test.cc b/source/blender/draw/tests/draw_pass_test.cc index cf05e332d02..8671b77ad4a 100644 --- a/source/blender/draw/tests/draw_pass_test.cc +++ b/source/blender/draw/tests/draw_pass_test.cc @@ -163,6 +163,9 @@ static void test_draw_pass_simple_draw() pass.draw_procedural(GPU_PRIM_POINTS, 6, 60, 6, {5}); pass.draw_procedural(GPU_PRIM_TRIS, 3, 70, 7, {6}); + PassSimple::Sub &sub = pass.sub("sub"); + sub.draw_procedural(GPU_PRIM_TRIS, 3, 80, 8, {8}); + std::string result = pass.serialize(); std::stringstream expected; expected << ".test.simple_draw" << std::endl; @@ -174,6 +177,8 @@ static void test_draw_pass_simple_draw() expected << " .draw(inst_len=1, vert_len=50, vert_first=5, res_id=5)" << std::endl; expected << " .draw(inst_len=6, vert_len=60, vert_first=6, res_id=5)" << std::endl; expected << " .draw(inst_len=3, vert_len=70, vert_first=7, res_id=6)" << std::endl; + expected << " .sub" << std::endl; + expected << " .draw(inst_len=3, vert_len=80, vert_first=8, res_id=8)" << std::endl; EXPECT_EQ(result, expected.str()); From 9e5ada315f68f20fb288fad351f2fa3e0edf0ba9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Jan 2023 14:34:24 +0100 Subject: [PATCH 0741/1522] DRW: Protect `common_math_lib.glsl` from duplicated declaration This avoid most issues when including this header along with some of the newer `gpu_shader_math_*_lib.glsl`. --- .../draw/intern/shaders/common_math_lib.glsl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/source/blender/draw/intern/shaders/common_math_lib.glsl b/source/blender/draw/intern/shaders/common_math_lib.glsl index 4846d81f6f1..6011f3398a6 100644 --- a/source/blender/draw/intern/shaders/common_math_lib.glsl +++ b/source/blender/draw/intern/shaders/common_math_lib.glsl @@ -30,6 +30,8 @@ mat3 mul(mat3 m1, mat3 m2) { return m1 * m2; } +/* WORKAROUND: To be removed once we port all code to use gpu_shader_math_base_lib.glsl. */ +#ifndef GPU_SHADER_MATH_MATRIX_LIB_GLSL vec3 transform_direction(mat4 m, vec3 v) { return mat3(m) * v; @@ -43,6 +45,7 @@ vec3 project_point(mat4 m, vec3 v) vec4 tmp = m * vec4(v, 1.0); return tmp.xyz / tmp.w; } +#endif mat2 rot2_from_angle(float a) { @@ -113,12 +116,15 @@ float pow8(float x) { return sqr(sqr(sqr(x))); } float len_squared(vec3 a) { return dot(a, a); } float len_squared(vec2 a) { return dot(a, a); } +/* WORKAROUND: To be removed once we port all code to use gpu_shader_math_base_lib.glsl. */ +#ifndef GPU_SHADER_UTILDEFINES_GLSL bool flag_test(uint flag, uint val) { return (flag & val) != 0u; } bool flag_test(int flag, uint val) { return flag_test(uint(flag), val); } bool flag_test(int flag, int val) { return (flag & val) != 0; } void set_flag_from_test(inout uint value, bool test, uint flag) { if (test) { value |= flag; } else { value &= ~flag; } } void set_flag_from_test(inout int value, bool test, int flag) { if (test) { value |= flag; } else { value &= ~flag; } } +#endif #define weighted_sum(val0, val1, val2, val3, weights) ((val0 * weights[0] + val1 * weights[1] + val2 * weights[2] + val3 * weights[3]) * safe_rcp(sum(weights))) #define weighted_sum_array(val, weights) ((val[0] * weights[0] + val[1] * weights[1] + val[2] * weights[2] + val[3] * weights[3]) * safe_rcp(sum(weights))) @@ -134,6 +140,8 @@ void set_flag_from_test(inout int value, bool test, int flag) { if (test) { valu #define in_texture_range(texel, tex) \ (all(greaterThanEqual(texel, ivec2(0))) && all(lessThan(texel, textureSize(tex, 0).xy))) +/* WORKAROUND: To be removed once we port all code to use gpu_shader_math_base_lib.glsl. */ +#ifndef GPU_SHADER_MATH_BASE_LIB_GLSL uint divide_ceil(uint visible_count, uint divisor) { return (visible_count + (divisor - 1u)) / divisor; @@ -143,11 +151,15 @@ int divide_ceil(int visible_count, int divisor) { return (visible_count + (divisor - 1)) / divisor; } +#endif +/* WORKAROUND: To be removed once we port all code to use gpu_shader_math_base_lib.glsl. */ +#ifndef GPU_SHADER_MATH_VECTOR_LIB_GLSL ivec2 divide_ceil(ivec2 visible_count, ivec2 divisor) { return (visible_count + (divisor - 1)) / divisor; } +#endif uint bit_field_mask(uint bit_width, uint bit_min) { @@ -156,6 +168,8 @@ uint bit_field_mask(uint bit_width, uint bit_min) return ~mask << bit_min; } +/* WORKAROUND: To be removed once we port all code to use gpu_shader_math_base_lib.glsl. */ +#ifndef GPU_SHADER_UTILDEFINES_GLSL uvec2 unpackUvec2x16(uint data) { return (uvec2(data) >> uvec2(0u, 16u)) & uvec2(0xFFFFu); @@ -177,7 +191,10 @@ uint packUvec4x8(uvec4 data) data = (data & 0xFFu) << uvec4(0u, 8u, 16u, 24u); return data.x | data.y | data.z | data.w; } +#endif +/* WORKAROUND: To be removed once we port all code to use gpu_shader_math_base_lib.glsl. */ +#ifndef GPU_SHADER_MATH_VECTOR_LIB_GLSL float distance_squared(vec2 a, vec2 b) { a -= b; @@ -189,6 +206,7 @@ float distance_squared(vec3 a, vec3 b) a -= b; return dot(a, a); } +#endif vec3 safe_normalize(vec3 v) { From 534214e65c9551972e23ec21a83bad555e3ce8e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Jan 2023 14:36:19 +0100 Subject: [PATCH 0742/1522] DRW: Make intersect lib not dependent on common_view_lib.glsl This declares view intersection functions only if the view lib if required. --- .../intern/shaders/common_intersect_lib.glsl | 49 ++++++++++++++++++- .../intern/shaders/draw_visibility_comp.glsl | 1 + 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/intern/shaders/common_intersect_lib.glsl b/source/blender/draw/intern/shaders/common_intersect_lib.glsl index d1416e220a4..e23216ec2e2 100644 --- a/source/blender/draw/intern/shaders/common_intersect_lib.glsl +++ b/source/blender/draw/intern/shaders/common_intersect_lib.glsl @@ -4,7 +4,6 @@ * Results are meant to be conservative. */ -#pragma BLENDER_REQUIRE(common_view_lib.glsl) #pragma BLENDER_REQUIRE(common_math_geom_lib.glsl) #pragma BLENDER_REQUIRE(common_shape_lib.glsl) @@ -127,6 +126,8 @@ IsectFrustum isect_data_setup(Frustum shape) /** \name View Intersection functions. * \{ */ +#ifdef COMMON_VIEW_LIB_GLSL + bool intersect_view(Pyramid pyramid) { bool intersects = true; @@ -276,6 +277,8 @@ bool intersect_view(Sphere sphere) return intersects; } +#endif + /** \} */ /* ---------------------------------------------------------------------- */ @@ -327,6 +330,50 @@ bool intersect(IsectPyramid i_pyramid, Box box) return intersects; } +bool intersect(IsectPyramid i_pyramid, IsectBox i_box) +{ + bool intersects = true; + + /* Do Box vertices vs Pyramid planes. */ + for (int p = 0; p < 5; ++p) { + bool is_any_vertex_on_positive_side = false; + for (int v = 0; v < 8; ++v) { + float test = dot(i_pyramid.planes[p], vec4(i_box.corners[v], 1.0)); + if (test > 0.0) { + is_any_vertex_on_positive_side = true; + break; + } + } + bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side; + if (all_vertex_on_negative_side) { + intersects = false; + break; + } + } + + if (!intersects) { + return intersects; + } + + /* Now do Pyramid vertices vs Box planes. */ + for (int p = 0; p < 6; ++p) { + bool is_any_vertex_on_positive_side = false; + for (int v = 0; v < 5; ++v) { + float test = dot(i_box.planes[p], vec4(i_pyramid.corners[v], 1.0)); + if (test > 0.0) { + is_any_vertex_on_positive_side = true; + break; + } + } + bool all_vertex_on_negative_side = !is_any_vertex_on_positive_side; + if (all_vertex_on_negative_side) { + intersects = false; + break; + } + } + return intersects; +} + bool intersect(IsectFrustum i_frustum, Pyramid pyramid) { bool intersects = true; diff --git a/source/blender/draw/intern/shaders/draw_visibility_comp.glsl b/source/blender/draw/intern/shaders/draw_visibility_comp.glsl index 7e89120a79f..580805c8479 100644 --- a/source/blender/draw/intern/shaders/draw_visibility_comp.glsl +++ b/source/blender/draw/intern/shaders/draw_visibility_comp.glsl @@ -4,6 +4,7 @@ */ /* TODO(fclem): This could be augmented by a 2 pass occlusion culling system. */ +#pragma BLENDER_REQUIRE(common_view_lib.glsl) #pragma BLENDER_REQUIRE(common_math_lib.glsl) #pragma BLENDER_REQUIRE(common_intersect_lib.glsl) From c412d2dcfe73c8ce790b68b234707dfeec08ab37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Jan 2023 14:50:18 +0100 Subject: [PATCH 0743/1522] DRW: View: Allow disabling view test by setting bound sphere radius to -1 --- .../blender/draw/intern/shaders/draw_visibility_comp.glsl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/intern/shaders/draw_visibility_comp.glsl b/source/blender/draw/intern/shaders/draw_visibility_comp.glsl index 580805c8479..f3ca51dbf6b 100644 --- a/source/blender/draw/intern/shaders/draw_visibility_comp.glsl +++ b/source/blender/draw/intern/shaders/draw_visibility_comp.glsl @@ -38,7 +38,11 @@ void main() Sphere inscribed_sphere = Sphere(bounds.bounding_sphere.xyz, bounds._inner_sphere_radius); for (drw_view_id = 0; drw_view_id < view_len; drw_view_id++) { - if (intersect_view(inscribed_sphere) == true) { + if (drw_view_culling.bound_sphere.w == -1.0) { + /* View disabled. */ + mask_visibility_bit(drw_view_id); + } + else if (intersect_view(inscribed_sphere) == true) { /* Visible. */ } else if (intersect_view(bounding_sphere) == false) { From 6f206f713e5acf39ec89c66608c8440dbc482e83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Wed, 18 Jan 2023 15:36:41 +0100 Subject: [PATCH 0744/1522] BLI: Math: Fix matrix tests failling Regression introduced in rB17768b3df19a --- source/blender/blenlib/tests/BLI_math_matrix_test.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/blenlib/tests/BLI_math_matrix_test.cc b/source/blender/blenlib/tests/BLI_math_matrix_test.cc index 71c99a00807..4a9f7936444 100644 --- a/source/blender/blenlib/tests/BLI_math_matrix_test.cc +++ b/source/blender/blenlib/tests/BLI_math_matrix_test.cc @@ -430,7 +430,7 @@ TEST(math_matrix, MatrixTransform) result = transform_direction(m3, p); EXPECT_V3_NEAR(result, expect, 1e-5); - expect = {-0.5, -1, -1.7222222}; + expect = {-0.333333, -0.666666, -1.14814}; result = project_point(pers4, p); EXPECT_V3_NEAR(result, expect, 1e-5); @@ -457,13 +457,13 @@ TEST(math_matrix, MatrixProjection) expect = transpose(float4x4({-0.8f, 0.0f, 0.2f, 0.0f}, {0.0f, -0.666667f, 0.333333f, 0.0f}, {0.0f, 0.0f, -2.33333f, 0.666667f}, - {0.0f, 0.0f, -1.0f, 1.0f})); + {0.0f, 0.0f, -1.0f, 0.0f})); EXPECT_M4_NEAR(pers1, expect, 1e-5); expect = transpose(float4x4({4.0f, 0.0f, 0.2f, 0.0f}, {0.0f, 3.33333f, 0.333333f, 0.0f}, {0.0f, 0.0f, -2.33333f, 0.666667f}, - {0.0f, 0.0f, -1.0f, 1.0f})); + {0.0f, 0.0f, -1.0f, 0.0f})); EXPECT_M4_NEAR(pers2, expect, 1e-5); } From e8d1d1486e3d9d8495af4c0903d6eb3e24a92094 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Jan 2023 13:42:55 +0100 Subject: [PATCH 0745/1522] Fix T103960: build issue with GCC 13 in Cycles thread code --- intern/cycles/util/thread.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/intern/cycles/util/thread.cpp b/intern/cycles/util/thread.cpp index f4949aa2b44..7f1e8eb4159 100644 --- a/intern/cycles/util/thread.cpp +++ b/intern/cycles/util/thread.cpp @@ -6,6 +6,8 @@ #include "util/system.h" #include "util/windows.h" +#include + CCL_NAMESPACE_BEGIN thread::thread(function run_cb) : run_cb_(run_cb), joined_(false) From 9ccec5715e95aa267a4db50b52e0cad59e65de33 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Jan 2023 13:48:44 +0100 Subject: [PATCH 0746/1522] Gitea: layout and wording tweaks to issue and pull request templates --- .gitea/issue_template/bug.yaml | 6 +++--- .gitea/issue_template/config.yaml | 1 + .gitea/pull_request_template.yaml | 6 ++++-- 3 files changed, 8 insertions(+), 5 deletions(-) create mode 100644 .gitea/issue_template/config.yaml diff --git a/.gitea/issue_template/bug.yaml b/.gitea/issue_template/bug.yaml index 94f61f6701b..fd0c35da87b 100644 --- a/.gitea/issue_template/bug.yaml +++ b/.gitea/issue_template/bug.yaml @@ -10,10 +10,10 @@ body: ### Instructions First time reporting? See [tips](https://wiki.blender.org/wiki/Process/Bug_Reports) and [walkthrough video](https://www.youtube.com/watch?v=JTD0OJq_rF4). - * Use **Help > Report a Bug** in Blender to automatically fill system information and exact Blender version. + * Use **Help > Report a Bug** in Blender to fill system information and exact Blender version. * Test [daily builds](https://builder.blender.org/) to verify if the issue is already fixed. * Test [previous versions](https://download.blender.org/release/) to find an older working version. - * For feature requests, feedback, questions or issues building Blender, see [communication channels](https://wiki.blender.org/wiki/Communication/Contact#User_Feedback_and_Requests). + * For feature requests, feedback, questions or build issues, see [communication channels](https://wiki.blender.org/wiki/Communication/Contact#User_Feedback_and_Requests). * If there are multiple bugs, make multiple bug reports. - type: textarea @@ -39,4 +39,4 @@ body: value: | ### Help the developers - Bug fixing is important, the developers will handle a report swiftly. For that reason, carefully provide exact steps and a **small and simple .blend file** to reproduce the problem. You do your half of the work, then we do our half! + Bug fixing is important, the developers will handle reports swiftly. For that reason, carefully provide exact steps and a **small and simple .blend file** to reproduce the problem. You do your half of the work, then we do our half! diff --git a/.gitea/issue_template/config.yaml b/.gitea/issue_template/config.yaml new file mode 100644 index 00000000000..3ba13e0cec6 --- /dev/null +++ b/.gitea/issue_template/config.yaml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.gitea/pull_request_template.yaml b/.gitea/pull_request_template.yaml index f7c3242f55c..2690223f366 100644 --- a/.gitea/pull_request_template.yaml +++ b/.gitea/pull_request_template.yaml @@ -5,9 +5,11 @@ body: - type: markdown attributes: value: | - Guides to [Contributing Code](https://wiki.blender.org/index.php/Dev:Doc/Process/Contributing_Code) and effective [Code Review](https://wiki.blender.org/index.php/Dev:Doc/Tools/Code_Review). + ### Instructions - By submitting code here, **you agree that the code is (compatible with) GNU GPL v2 or later**. + Guides to [contributing code](https://wiki.blender.org/index.php/Dev:Doc/Process/Contributing_Code) and effective [code review](https://wiki.blender.org/index.php/Dev:Doc/Tools/Code_Review). + + By submitting code here, you agree that the code is (compatible with) GNU GPL v2 or later. - type: textarea id: body From 8707cab70b6959c70be793882d63711ddc36dd17 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 18 Jan 2023 16:58:09 +0100 Subject: [PATCH 0747/1522] Gitea: don't reference branch in issues by default --- .gitea/issue_template/bug.yaml | 1 - .gitea/issue_template/design.yaml | 1 - .gitea/issue_template/todo.yaml | 1 - .gitea/pull_request_template.yaml | 1 - 4 files changed, 4 deletions(-) diff --git a/.gitea/issue_template/bug.yaml b/.gitea/issue_template/bug.yaml index fd0c35da87b..9c4618c3223 100644 --- a/.gitea/issue_template/bug.yaml +++ b/.gitea/issue_template/bug.yaml @@ -2,7 +2,6 @@ name: Bug Report about: File a bug report labels: - bug -ref: master body: - type: markdown attributes: diff --git a/.gitea/issue_template/design.yaml b/.gitea/issue_template/design.yaml index b482c8fad42..8c2c6deef29 100644 --- a/.gitea/issue_template/design.yaml +++ b/.gitea/issue_template/design.yaml @@ -2,7 +2,6 @@ name: Design about: Create a design task (for developers only) labels: - design -ref: master body: - type: textarea id: body diff --git a/.gitea/issue_template/todo.yaml b/.gitea/issue_template/todo.yaml index 8c08d897b2b..e7fecf043ca 100644 --- a/.gitea/issue_template/todo.yaml +++ b/.gitea/issue_template/todo.yaml @@ -2,7 +2,6 @@ name: To Do about: Create a to do task (for developers only) labels: - todo -ref: master body: - type: textarea id: body diff --git a/.gitea/pull_request_template.yaml b/.gitea/pull_request_template.yaml index 2690223f366..6affe8cf8d2 100644 --- a/.gitea/pull_request_template.yaml +++ b/.gitea/pull_request_template.yaml @@ -1,6 +1,5 @@ name: Pull Request about: Contribute code to Blender -ref: master body: - type: markdown attributes: From e4e91bf8301ace526c7bab8bfd2b06eeecf47e20 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Wed, 18 Jan 2023 18:17:02 +0100 Subject: [PATCH 0748/1522] Fix crash when listing assets repeatedly in node search menus When doing partial reloads of asset libraries (only reload assets from the current file, e.g. after undo re-allocated ID pointers), we'd end up with assets that don't have their asset data read correctly. It would execute a branch that didn't set the asset library object necessary to create and store asset representations. Steps to reproduce were: * Open .blend file with geometry node assets in there * In a geometry node editor, press Shift+A to open the add menu * Cancel * Move a node * Undo * Press Shift+A again --- source/blender/editors/space_file/filelist.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc index 22986672650..7a982914878 100644 --- a/source/blender/editors/space_file/filelist.cc +++ b/source/blender/editors/space_file/filelist.cc @@ -3724,7 +3724,8 @@ static void filelist_readjob_load_asset_library_data(FileListReadJob *job_params return; } if (tmp_filelist->asset_library != nullptr) { - /* Asset library already loaded. */ + /* Asset library itself is already loaded. Load assets into this. */ + job_params->load_asset_library = tmp_filelist->asset_library; return; } From d3aaa7d52365d751852c065cb8bd3db991b3f2af Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Wed, 18 Jan 2023 12:41:09 -0700 Subject: [PATCH 0749/1522] Fix: Build issue with VS2019 fix by @JacquesLucke I just sprinkled it to all places it needed to be. --- source/blender/blenkernel/intern/curves_geometry.cc | 8 ++++---- source/blender/geometry/intern/subdivide_curves.cc | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 3ca951858c6..b2cd7cf5cae 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -554,7 +554,7 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const this->runtime->nurbs_basis_cache.resize(this->curves_num()); MutableSpan basis_caches(this->runtime->nurbs_basis_cache); - const OffsetIndices points_by_curve = this->points_by_curve(); + const OffsetIndices points_by_curve = this->points_by_curve(); VArray cyclic = this->cyclic(); VArray orders = this->nurbs_orders(); VArray knots_modes = this->nurbs_knots_modes(); @@ -600,7 +600,7 @@ Span CurvesGeometry::evaluated_positions() const MutableSpan evaluated_positions = this->runtime->evaluated_position_cache; this->runtime->evaluated_positions_span = evaluated_positions; - const OffsetIndices points_by_curve = this->points_by_curve(); + const OffsetIndices points_by_curve = this->points_by_curve(); VArray types = this->curve_types(); VArray cyclic = this->cyclic(); VArray resolution = this->resolution(); @@ -681,7 +681,7 @@ Span CurvesGeometry::evaluated_tangents() const Vector bezier_indices; const IndexMask bezier_mask = this->indices_for_curve_type(CURVE_TYPE_BEZIER, bezier_indices); if (!bezier_mask.is_empty()) { - const OffsetIndices points_by_curve = this->points_by_curve(); + const OffsetIndices points_by_curve = this->points_by_curve(); const Span positions = this->positions(); const Span handles_left = this->handle_positions_left(); const Span handles_right = this->handle_positions_right(); @@ -758,7 +758,7 @@ static void evaluate_generic_data_for_curve( Span CurvesGeometry::evaluated_normals() const { this->runtime->normal_cache_mutex.ensure([&]() { - const OffsetIndices points_by_curve = this->points_by_curve(); + const OffsetIndices points_by_curve = this->points_by_curve(); const VArray types = this->curve_types(); const VArray cyclic = this->cyclic(); const VArray normal_mode = this->normal_mode(); diff --git a/source/blender/geometry/intern/subdivide_curves.cc b/source/blender/geometry/intern/subdivide_curves.cc index 15c3f40e6b2..cdb0ed59b00 100644 --- a/source/blender/geometry/intern/subdivide_curves.cc +++ b/source/blender/geometry/intern/subdivide_curves.cc @@ -372,14 +372,14 @@ bke::CurvesGeometry subdivide_curves( const VArraySpan src_types_r{src_curves.handle_types_right()}; const Span src_handles_l = src_curves.handle_positions_left(); const Span src_handles_r = src_curves.handle_positions_right(); - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); MutableSpan dst_positions = dst_curves.positions_for_write(); MutableSpan dst_types_l = dst_curves.handle_types_left_for_write(); MutableSpan dst_types_r = dst_curves.handle_types_right_for_write(); MutableSpan dst_handles_l = dst_curves.handle_positions_left_for_write(); MutableSpan dst_handles_r = dst_curves.handle_positions_right_for_write(); - const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int curve_i : selection.slice(range)) { From 6c4e3a9e517840bb69260f2ad46748e1dc655e32 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 18 Jan 2023 16:41:10 -0600 Subject: [PATCH 0750/1522] Curves: Deduplicate and parallelize point to curve map creation There is a utility method on `CurvesGeometry` to build a map of the curve for each point. Use that in two more places and make sure its implementation is multithreaded, which gives a slight speedup in a simple test file. --- .../blenkernel/intern/curves_geometry.cc | 25 +++++-------------- .../nodes/node_geo_duplicate_elements.cc | 9 +------ 2 files changed, 7 insertions(+), 27 deletions(-) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index b2cd7cf5cae..0f24d9ea640 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -536,9 +536,11 @@ Array CurvesGeometry::point_to_curve_map() const { const OffsetIndices points_by_curve = this->points_by_curve(); Array map(this->points_num()); - for (const int i : this->curves_range()) { - map.as_mutable_span().slice(points_by_curve[i]).fill(i); - } + threading::parallel_for(this->curves_range(), 1024, [&](const IndexRange range) { + for (const int i_curve : range) { + map.as_mutable_span().slice(points_by_curve[i_curve]).fill(i_curve); + } + }); return map; } @@ -1075,28 +1077,13 @@ static void copy_with_map(const GSpan src, const Span map, GMutableSpan dst }); } -/** - * Builds an array that for every point, contains the corresponding curve index. - */ -static Array build_point_to_curve_map(const CurvesGeometry &curves) -{ - const OffsetIndices points_by_curve = curves.points_by_curve(); - Array point_to_curve_map(curves.points_num()); - threading::parallel_for(curves.curves_range(), 1024, [&](const IndexRange curves_range) { - for (const int i_curve : curves_range) { - point_to_curve_map.as_mutable_span().slice(points_by_curve[i_curve]).fill(i_curve); - } - }); - return point_to_curve_map; -} - static CurvesGeometry copy_with_removed_points( const CurvesGeometry &curves, const IndexMask points_to_delete, const AnonymousAttributePropagationInfo &propagation_info) { /* Use a map from points to curves to facilitate using an #IndexMask input. */ - const Array point_to_curve_map = build_point_to_curve_map(curves); + const Array point_to_curve_map = curves.point_to_curve_map(); const Vector copy_point_ranges = points_to_delete.extract_ranges_invert( curves.points_range()); diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index b3017a569eb..480fd516360 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -821,14 +821,7 @@ static void duplicate_points_curve(GeometrySet &geometry_set, Array offsets = accumulate_counts_to_offsets(selection, counts); const int dst_num = offsets.last(); - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); - Array point_to_curve_map(src_curves.points_num()); - threading::parallel_for(src_curves.curves_range(), 1024, [&](const IndexRange range) { - for (const int i_curve : range) { - const IndexRange points = src_points_by_curve[i_curve]; - point_to_curve_map.as_mutable_span().slice(points).fill(i_curve); - } - }); + const Array point_to_curve_map = src_curves.point_to_curve_map(); Curves *new_curves_id = bke::curves_new_nomain(dst_num, dst_num); bke::curves_copy_parameters(src_curves_id, *new_curves_id); From 83f9218801d4b6c8dd5e20897df47f562c04cea7 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 18 Jan 2023 18:14:44 -0600 Subject: [PATCH 0751/1522] Cleanup: Remove unused/redundant includes from curves/pointcloud draw --- source/blender/draw/intern/draw_attributes.h | 1 - source/blender/draw/intern/draw_curves.cc | 2 -- source/blender/draw/intern/draw_pointcloud.cc | 6 ------ 3 files changed, 9 deletions(-) diff --git a/source/blender/draw/intern/draw_attributes.h b/source/blender/draw/intern/draw_attributes.h index 00621c711bf..223c2a26c60 100644 --- a/source/blender/draw/intern/draw_attributes.h +++ b/source/blender/draw/intern/draw_attributes.h @@ -14,7 +14,6 @@ #endif #include "DNA_customdata_types.h" -#include "DNA_meshdata_types.h" #include "BKE_attribute.h" diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc index 166d3ac8426..8bb786827f3 100644 --- a/source/blender/draw/intern/draw_curves.cc +++ b/source/blender/draw/intern/draw_curves.cc @@ -11,10 +11,8 @@ #include "BLI_utildefines.h" #include "DNA_curves_types.h" -#include "DNA_customdata_types.h" #include "BKE_curves.hh" -#include "BKE_geometry_set.hh" #include "GPU_batch.h" #include "GPU_capabilities.h" diff --git a/source/blender/draw/intern/draw_pointcloud.cc b/source/blender/draw/intern/draw_pointcloud.cc index 582dc690cee..4f228addffb 100644 --- a/source/blender/draw/intern/draw_pointcloud.cc +++ b/source/blender/draw/intern/draw_pointcloud.cc @@ -3,19 +3,13 @@ /** \file * \ingroup draw - * - * \brief Contains procedural GPU hair drawing methods. */ #include "BLI_string_utils.h" #include "BLI_utildefines.h" -#include "DNA_customdata_types.h" #include "DNA_pointcloud_types.h" -#include "BKE_curves.hh" -#include "BKE_geometry_set.hh" - #include "GPU_batch.h" #include "GPU_capabilities.h" #include "GPU_compute.h" From 163d4aa094d1407c474bbef6895a793425f8c00b Mon Sep 17 00:00:00 2001 From: Jesse Yurkovich Date: Wed, 18 Jan 2023 21:25:55 -0800 Subject: [PATCH 0752/1522] Fix T103707: Use beauty fill for the UV select overlap operator The original code used `BLI_polyfill_calc` which can create degenerate triangles during triangulation per T103913. This causes the subsequent overlap test to produce incorrect results in certain cases. Change to using a "beauty" fill instead. Differential Revision: https://developer.blender.org/D17015 --- source/blender/editors/uvedit/uvedit_select.c | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index a54d62b11b0..dc68b2c6475 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -22,11 +22,14 @@ #include "BLI_alloca.h" #include "BLI_blenlib.h" #include "BLI_hash.h" +#include "BLI_heap.h" #include "BLI_kdopbvh.h" #include "BLI_kdtree.h" #include "BLI_lasso_2d.h" #include "BLI_math.h" +#include "BLI_memarena.h" #include "BLI_polyfill_2d.h" +#include "BLI_polyfill_2d_beautify.h" #include "BLI_utildefines.h" #include "BKE_context.h" @@ -4359,6 +4362,9 @@ static int uv_select_overlap(bContext *C, const bool extend) float(*uv_verts)[2] = MEM_mallocN(sizeof(*uv_verts) * face_len_alloc, "UvOverlapCoords"); uint(*indices)[3] = MEM_mallocN(sizeof(*indices) * (face_len_alloc - 2), "UvOverlapTris"); + MemArena *arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); + Heap *heap = BLI_heap_new_ex(BLI_POLYFILL_ALLOC_NGON_RESERVE); + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(obedit); @@ -4393,7 +4399,14 @@ static int uv_select_overlap(bContext *C, const bool extend) copy_v2_v2(uv_verts[vert_index], luv); } - BLI_polyfill_calc(uv_verts, face_len, 0, indices); + /* The winding order of the coordinates is not guaranteed, determine it automatically. */ + const int coords_sign = 0; + BLI_polyfill_calc_arena(uv_verts, face_len, coords_sign, indices, arena); + + /* A beauty fill is necessary to remove degenerate triangles that may be produced from the + * above polyfill (see T103913), otherwise the overlap tests can fail. + */ + BLI_polyfill_beautify(uv_verts, face_len, indices, arena, heap); for (int t = 0; t < tri_len; t++) { overlap_data[data_index].ob_index = ob_index; @@ -4413,10 +4426,15 @@ static int uv_select_overlap(bContext *C, const bool extend) BLI_bvhtree_insert(uv_tree, data_index, &tri[0][0], 3); data_index++; } + + BLI_memarena_clear(arena); + BLI_heap_clear(heap, NULL); } } BLI_assert(data_index == uv_tri_len); + BLI_memarena_free(arena); + BLI_heap_free(heap, NULL); MEM_freeN(uv_verts); MEM_freeN(indices); From 9676dce3171eb57a0f27512a07f09766959bb656 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 19 Jan 2023 17:07:17 +1100 Subject: [PATCH 0753/1522] Cleanup: CMake indentation --- build_files/build_environment/cmake/usd.cmake | 2 +- build_files/cmake/macros.cmake | 4 +-- intern/cycles/kernel/CMakeLists.txt | 36 +++++++++---------- source/creator/CMakeLists.txt | 22 ++++++------ 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/build_files/build_environment/cmake/usd.cmake b/build_files/build_environment/cmake/usd.cmake index 98c7931808f..04000951166 100644 --- a/build_files/build_environment/cmake/usd.cmake +++ b/build_files/build_environment/cmake/usd.cmake @@ -29,7 +29,7 @@ elseif(UNIX) set(USD_PLATFORM_FLAGS -DPYTHON_INCLUDE_DIR=${LIBDIR}/python/include/python${PYTHON_SHORT_VERSION}/ -DPYTHON_LIBRARY=${LIBDIR}/tbb/lib/${LIBPREFIX}${TBB_LIBRARY}${SHAREDLIBEXT} - ) + ) if(APPLE) set(USD_SHARED_LINKER_FLAGS "-Xlinker -undefined -Xlinker dynamic_lookup") diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 9965f892395..1b440c7aaed 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -1115,7 +1115,7 @@ function(find_python_package # endif() # Not set, so initialize. else() - string(REPLACE "." ";" _PY_VER_SPLIT "${PYTHON_VERSION}") + string(REPLACE "." ";" _PY_VER_SPLIT "${PYTHON_VERSION}") list(GET _PY_VER_SPLIT 0 _PY_VER_MAJOR) # re-cache @@ -1275,7 +1275,7 @@ macro(add_bundled_libraries library_dir) list(APPEND PLATFORM_BUNDLED_LIBRARY_DIRS ${_library_dir}) unset(_all_library_versions) unset(_library_dir) - endif() + endif() endmacro() macro(windows_install_shared_manifest) diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 3ae468efd1f..78bd71988c0 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -732,25 +732,25 @@ if(WITH_CYCLES_DEVICE_ONEAPI) endif() # SYCL_CPP_FLAGS is a variable that the user can set to pass extra compiler options set(sycl_compiler_flags - ${CMAKE_CURRENT_SOURCE_DIR}/${SRC_KERNEL_DEVICE_ONEAPI} - -fsycl - -fsycl-unnamed-lambda - -fdelayed-template-parsing - -mllvm -inlinedefault-threshold=250 - -mllvm -inlinehint-threshold=350 - -fsycl-device-code-split=per_kernel - -fsycl-max-parallel-link-jobs=${SYCL_OFFLINE_COMPILER_PARALLEL_JOBS} - -shared - -DWITH_ONEAPI - -ffast-math - -DNDEBUG - -O2 - -o ${cycles_kernel_oneapi_lib} - -I${CMAKE_CURRENT_SOURCE_DIR}/.. - ${SYCL_CPP_FLAGS} - ) + ${CMAKE_CURRENT_SOURCE_DIR}/${SRC_KERNEL_DEVICE_ONEAPI} + -fsycl + -fsycl-unnamed-lambda + -fdelayed-template-parsing + -mllvm -inlinedefault-threshold=250 + -mllvm -inlinehint-threshold=350 + -fsycl-device-code-split=per_kernel + -fsycl-max-parallel-link-jobs=${SYCL_OFFLINE_COMPILER_PARALLEL_JOBS} + -shared + -DWITH_ONEAPI + -ffast-math + -DNDEBUG + -O2 + -o ${cycles_kernel_oneapi_lib} + -I${CMAKE_CURRENT_SOURCE_DIR}/.. + ${SYCL_CPP_FLAGS} + ) - if (WITH_CYCLES_ONEAPI_HOST_TASK_EXECUTION) + if(WITH_CYCLES_ONEAPI_HOST_TASK_EXECUTION) list(APPEND sycl_compiler_flags -DWITH_ONEAPI_SYCL_HOST_TASK) endif() diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 1cf908b4821..fa3ab5d3b86 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -617,16 +617,16 @@ if(UNIX AND NOT APPLE) # Remove from old location, so existing builds don't start with software # OpenGL now that the lib/ folder is used for other libraries. install( - CODE - "file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libGL.so)\n - file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libGL.so.1)\n - file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libGL.so.1.5.0)\n - file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libGLU.so)\n - file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libGLU.so.1)\n - file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libGLU.so.1.3.1)\n - file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libglapi.so)\n - file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libglapi.so.0)\n - file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libglapi.so.0.0.0)\n + CODE "\ + file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libGL.so)\n + file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libGL.so.1)\n + file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libGL.so.1.5.0)\n + file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libGLU.so)\n + file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libGLU.so.1)\n + file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libGLU.so.1.3.1)\n + file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libglapi.so)\n + file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libglapi.so.0)\n + file(REMOVE ${CMAKE_BINARY_DIR}/bin/lib/libglapi.so.0.0.0)\n " ) endif() @@ -1071,7 +1071,7 @@ elseif(WIN32) ) if(EXISTS ${LIBDIR}/openimageio/lib/python${PYTHON_VERSION}/site-packages) #this will only exist for 3.5+ - install( + install( DIRECTORY ${LIBDIR}/openimageio/lib/python${PYTHON_VERSION}/site-packages/ DESTINATION ${TARGETDIR_VER}/python/lib/site-packages/ CONFIGURATIONS Release;RelWithDebInfo;MinSizeRel From c2120b8c4f31988ea4b7ff3235da12bba644f1fb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 19 Jan 2023 17:07:19 +1100 Subject: [PATCH 0754/1522] CMake: suppress missing-variable-declarations warnings with Clang Code generated by wayland-scanner contained missing declarations. --- intern/ghost/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index fd706d758a3..ac7dd6ca5cf 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -360,6 +360,15 @@ elseif(WITH_GHOST_X11 OR WITH_GHOST_WAYLAND) COMMAND ${WAYLAND_SCANNER} private-code ${PROT_DEF} ${INC_DST}/${_name}-client-protocol.c DEPENDS ${INC_DST}/${_name}-client-protocol.h ) + + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + # Prevent warnings/failure to compile with generated `WL_PRIVATE` declarations. + set_source_files_properties( + "${INC_DST}/${_name}-client-protocol.c" + PROPERTIES COMPILE_FLAGS "-Wno-missing-variable-declarations" + ) + endif() + list(APPEND SRC ${INC_DST}/${_name}-client-protocol.c ${INC_DST}/${_name}-client-protocol.h From 978a7459f121c2a1491687ccc83b0caddc7d6d1f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 19 Jan 2023 17:07:20 +1100 Subject: [PATCH 0755/1522] CMake: support multi-line strings for the help_features target --- .../cmake/cmake_print_build_options.py | 78 +++++++++++++++++-- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/build_files/cmake/cmake_print_build_options.py b/build_files/cmake/cmake_print_build_options.py index 3dc2951680a..7a30bb5da2b 100644 --- a/build_files/cmake/cmake_print_build_options.py +++ b/build_files/cmake/cmake_print_build_options.py @@ -6,18 +6,80 @@ import re import sys +from typing import Optional + cmakelists_file = sys.argv[-1] -def main(): +def count_backslashes_before_pos(file_data: str, pos: int) -> int: + slash_count = 0 + pos -= 1 + while pos >= 0: + if file_data[pos] != '\\': + break + pos -= 1 + slash_count += 1 + return slash_count + + +def extract_cmake_string_at_pos(file_data: str, pos_beg: int) -> Optional[str]: + assert file_data[pos_beg - 1] == '"' + + pos = pos_beg + # Dummy assignment. + pos_end = pos_beg + while True: + pos_next = file_data.find('"', pos) + if pos_next == -1: + raise Exception("Un-terminated string (parse error?)") + + count_slashes = count_backslashes_before_pos(file_data, pos_next) + if (count_slashes % 2) == 0: + pos_end = pos_next + # Found the closing quote. + break + + # The quote was back-slash escaped, step over it. + pos = pos_next + 1 + file_data[pos_next] + + assert file_data[pos_end] == '"' + + if pos_beg == pos_end: + return None + + # See: https://cmake.org/cmake/help/latest/manual/cmake-language.7.html#escape-sequences + text = file_data[pos_beg: pos_end].replace( + # Handle back-slash literals. + "\\\\", "\\", + ).replace( + # Handle tabs. + "\\t", "\t", + ).replace( + # Handle escaped quotes. + "\\\"", "\"", + ).replace( + # Handle tabs. + "\\;", ";", + ).replace( + # Handle trailing newlines. + "\\\n", "", + ) + + return text + + +def main() -> None: options = [] - for l in open(cmakelists_file, 'r').readlines(): - if not l.lstrip().startswith('#'): - l_option = re.sub(r'.*\boption\s*\(\s*(WITH_[a-zA-Z0-9_]+)\s+\"(.*)\"\s*.*', r'\g<1> - \g<2>', l) - if l_option != l: - l_option = l_option.strip() - if l_option.startswith('WITH_'): - options.append(l_option) + with open(cmakelists_file, 'r', encoding="utf-8") as fh: + file_data = fh.read() + for m in re.finditer(r"^\s*option\s*\(\s*(WITH_[a-zA-Z0-9_]+)\s+(\")", file_data, re.MULTILINE): + option_name = m.group(1) + option_descr = extract_cmake_string_at_pos(file_data, m.span(2)[1]) + if option_descr is None: + # Possibly a parsing error, at least show something. + option_descr = "(UNDOCUMENTED)" + options.append("{:s}: {:s}".format(option_name, option_descr)) print('\n'.join(options)) From 8b7d2d8eb2055ffe26ec242524788706b0817a4c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 19 Jan 2023 17:07:21 +1100 Subject: [PATCH 0756/1522] CMake: use BULLET_LIBRARIES for both extern_bullet and system libraries There was no need to differentiate between these and it made the CMake files more verbose. --- CMakeLists.txt | 14 ++++++++------ intern/rigidbody/CMakeLists.txt | 1 - source/blender/blenkernel/CMakeLists.txt | 7 ------- source/blender/bmesh/CMakeLists.txt | 6 ------ source/blender/modifiers/CMakeLists.txt | 8 +++----- source/blender/nodes/CMakeLists.txt | 6 ------ source/blender/nodes/geometry/CMakeLists.txt | 6 ------ 7 files changed, 11 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b2f4eec61a..252b2d13450 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1262,12 +1262,14 @@ endif() # ----------------------------------------------------------------------------- # Configure Bullet -if(WITH_BULLET AND WITH_SYSTEM_BULLET) - find_package(Bullet) - set_and_warn_library_found("Bullet" BULLET_FOUND WITH_BULLET) -else() - set(BULLET_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/extern/bullet2/src") - # set(BULLET_LIBRARIES "") +if(WITH_BULLET) + if(WITH_SYSTEM_BULLET) + find_package(Bullet) + set_and_warn_library_found("Bullet" BULLET_FOUND WITH_BULLET) + else() + set(BULLET_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/extern/bullet2/src") + set(BULLET_LIBRARIES "extern_bullet") + endif() endif() diff --git a/intern/rigidbody/CMakeLists.txt b/intern/rigidbody/CMakeLists.txt index b6911129de4..ef5d7f66040 100644 --- a/intern/rigidbody/CMakeLists.txt +++ b/intern/rigidbody/CMakeLists.txt @@ -20,7 +20,6 @@ set(SRC ) set(LIB - extern_bullet ${BULLET_LIBRARIES} ) diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 7e11481b9c8..15c44589291 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -577,13 +577,6 @@ if(WITH_BULLET) list(APPEND INC ../../../intern/rigidbody ) - - if(NOT WITH_SYSTEM_BULLET) - list(APPEND LIB - extern_bullet - ) - endif() - list(APPEND LIB bf_intern_rigidbody diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index b7370a6e8d7..83bbc8cbf02 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -179,12 +179,6 @@ if(WITH_BULLET) ${BULLET_INCLUDE_DIRS} ../../../intern/rigidbody ) - if(NOT WITH_SYSTEM_BULLET) - list(APPEND LIB - extern_bullet - ) - endif() - list(APPEND LIB ${BULLET_LIBRARIES} ) diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index 910876fa361..30ddca5e47d 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -158,11 +158,9 @@ if(WITH_OPENSUBDIV) endif() if(WITH_BULLET) - if(NOT WITH_SYSTEM_BULLET) - list(APPEND LIB - extern_bullet - ) - endif() + list(APPEND LIB + ${BULLET_LIBRARIES} + ) add_definitions(-DWITH_BULLET) endif() diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 27da5f6cf8e..e6c0510e9f5 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -92,12 +92,6 @@ if(WITH_BULLET) ${BULLET_INCLUDE_DIRS} ../../../intern/rigidbody ) - if(NOT WITH_SYSTEM_BULLET) - list(APPEND LIB - extern_bullet - ) - endif() - list(APPEND LIB ${BULLET_LIBRARIES} ) diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt index 396fd794865..eecc79f2b12 100644 --- a/source/blender/nodes/geometry/CMakeLists.txt +++ b/source/blender/nodes/geometry/CMakeLists.txt @@ -196,12 +196,6 @@ if(WITH_BULLET) ${BULLET_INCLUDE_DIRS} ../../../../intern/rigidbody ) - if(NOT WITH_SYSTEM_BULLET) - list(APPEND LIB - extern_bullet - ) - endif() - list(APPEND LIB ${BULLET_LIBRARIES} ) From 66dee44088e9d46cffb4731faf1e76fda3396b10 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 19 Jan 2023 17:07:23 +1100 Subject: [PATCH 0757/1522] CMake: quiet references to undeclared variable warnings These warnings can reveal errors in logic, so quiet them by checking if the features are enabled before using variables or by assigning empty strings in some cases. - Check CMAKE_THREAD_LIBS_INIT is set before use as CMake docs note that this may be left unset if it's not needed. - Remove BOOST/OPENVDB/VULKAN references when disable. - Define INC_SYS even when empty. - Remove PNG_INC from freetype (not defined anywhere). --- CMakeLists.txt | 2 + build_files/cmake/Modules/FindOptiX.cmake | 6 +- .../cmake/Modules/FindPythonLibsUnix.cmake | 2 + build_files/cmake/macros.cmake | 4 +- .../cmake/platform/platform_unix.cmake | 18 ++- extern/mantaflow/CMakeLists.txt | 24 ++-- intern/cycles/cmake/macros.cmake | 16 ++- intern/cycles/graph/CMakeLists.txt | 3 + intern/cycles/integrator/CMakeLists.txt | 3 + intern/cycles/session/CMakeLists.txt | 3 + intern/guardedalloc/CMakeLists.txt | 9 +- source/blender/blendthumb/CMakeLists.txt | 4 +- source/blender/blenkernel/CMakeLists.txt | 13 ++- .../realtime_compositor/CMakeLists.txt | 2 + source/blender/draw/CMakeLists.txt | 7 +- .../blender/editors/animation/CMakeLists.txt | 2 + .../blender/editors/armature/CMakeLists.txt | 3 + source/blender/editors/curve/CMakeLists.txt | 3 + .../editors/gizmo_library/CMakeLists.txt | 3 + source/blender/editors/gpencil/CMakeLists.txt | 3 + .../blender/editors/interface/CMakeLists.txt | 3 + source/blender/editors/mask/CMakeLists.txt | 3 + source/blender/editors/object/CMakeLists.txt | 3 + source/blender/editors/physics/CMakeLists.txt | 3 + source/blender/editors/screen/CMakeLists.txt | 3 + source/blender/editors/sound/CMakeLists.txt | 15 ++- .../editors/space_action/CMakeLists.txt | 3 + .../editors/space_buttons/CMakeLists.txt | 3 + .../blender/editors/space_clip/CMakeLists.txt | 3 + .../editors/space_console/CMakeLists.txt | 3 + .../blender/editors/space_file/CMakeLists.txt | 3 + .../editors/space_graph/CMakeLists.txt | 18 ++- .../editors/space_image/CMakeLists.txt | 3 + .../blender/editors/space_info/CMakeLists.txt | 3 + .../blender/editors/space_nla/CMakeLists.txt | 2 + .../editors/space_outliner/CMakeLists.txt | 2 + .../editors/space_script/CMakeLists.txt | 2 + .../editors/space_sequencer/CMakeLists.txt | 15 ++- .../editors/space_spreadsheet/CMakeLists.txt | 3 + .../editors/space_statusbar/CMakeLists.txt | 2 + .../blender/editors/space_text/CMakeLists.txt | 2 + .../editors/space_topbar/CMakeLists.txt | 2 + .../editors/space_view3d/CMakeLists.txt | 2 + .../blender/editors/transform/CMakeLists.txt | 3 +- source/blender/editors/undo/CMakeLists.txt | 3 + source/blender/editors/util/CMakeLists.txt | 2 + source/blender/editors/uvedit/CMakeLists.txt | 2 + source/blender/freestyle/CMakeLists.txt | 1 - source/blender/gpu/CMakeLists.txt | 25 ++--- .../blender/imbuf/intern/oiio/CMakeLists.txt | 16 ++- source/blender/io/alembic/CMakeLists.txt | 15 ++- source/blender/io/gpencil/CMakeLists.txt | 9 +- source/blender/makesdna/intern/CMakeLists.txt | 4 +- source/blender/makesrna/intern/CMakeLists.txt | 17 +-- source/blender/nodes/composite/CMakeLists.txt | 2 + source/blender/nodes/function/CMakeLists.txt | 2 + source/blender/nodes/texture/CMakeLists.txt | 2 + source/blender/render/CMakeLists.txt | 2 + source/blender/sequencer/CMakeLists.txt | 13 ++- source/blender/windowmanager/CMakeLists.txt | 13 ++- tests/CMakeLists.txt | 2 +- tests/python/CMakeLists.txt | 103 ++++++++++-------- 62 files changed, 325 insertions(+), 142 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 252b2d13450..2acae1d7b26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -993,6 +993,8 @@ set(PLATFORM_LINKLIBS "") # - CMAKE_EXE_LINKER_FLAGS_DEBUG set(PLATFORM_LINKFLAGS "") set(PLATFORM_LINKFLAGS_DEBUG "") +set(PLATFORM_LINKFLAGS_RELEASE "") +set(PLATFORM_LINKFLAGS_EXECUTABLE "") if(NOT CMAKE_BUILD_TYPE MATCHES "Release") if(WITH_COMPILER_ASAN) diff --git a/build_files/cmake/Modules/FindOptiX.cmake b/build_files/cmake/Modules/FindOptiX.cmake index bb671ed6495..f6838f0583f 100644 --- a/build_files/cmake/Modules/FindOptiX.cmake +++ b/build_files/cmake/Modules/FindOptiX.cmake @@ -17,9 +17,13 @@ ENDIF() SET(_optix_SEARCH_DIRS ${OPTIX_ROOT_DIR} - "$ENV{PROGRAMDATA}/NVIDIA Corporation/OptiX SDK 7.3.0" ) +# TODO: Which environment uses this? +if(DEFINED ENV{PROGRAMDATA}) + list(APPEND _optix_SEARCH_DIRS "$ENV{PROGRAMDATA}/NVIDIA Corporation/OptiX SDK 7.3.0") +endif() + FIND_PATH(OPTIX_INCLUDE_DIR NAMES optix.h diff --git a/build_files/cmake/Modules/FindPythonLibsUnix.cmake b/build_files/cmake/Modules/FindPythonLibsUnix.cmake index b222ed85a4f..5d40a4f1277 100644 --- a/build_files/cmake/Modules/FindPythonLibsUnix.cmake +++ b/build_files/cmake/Modules/FindPythonLibsUnix.cmake @@ -67,6 +67,8 @@ ENDIF() STRING(REPLACE "." "" PYTHON_VERSION_NO_DOTS ${PYTHON_VERSION}) +SET(_PYTHON_ABI_FLAGS "") + SET(_python_SEARCH_DIRS ${PYTHON_ROOT_DIR} "$ENV{HOME}/py${PYTHON_VERSION_NO_DOTS}" diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 1b440c7aaed..44081ee5d81 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -550,7 +550,9 @@ function(setup_platform_linker_libs endif() if(WIN32 AND NOT UNIX) - target_link_libraries(${target} ${PTHREADS_LIBRARIES}) + if(DEFINED PTHREADS_LIBRARIES) + target_link_libraries(${target} ${PTHREADS_LIBRARIES}) + endif() endif() # target_link_libraries(${target} ${PLATFORM_LINKLIBS} ${CMAKE_DL_LIBS}) diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index 787d0f87002..4f84fe262f5 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -430,10 +430,13 @@ if(WITH_OPENIMAGEIO) ${PNG_LIBRARIES} ${JPEG_LIBRARIES} ${ZLIB_LIBRARIES} - ${BOOST_LIBRARIES} ) + set(OPENIMAGEIO_DEFINITIONS "") + if(WITH_BOOST) + list(APPEND OPENIMAGEIO_LIBRARIES "${BOOST_LIBRARIES}") + endif() if(WITH_IMAGE_TIFF) list(APPEND OPENIMAGEIO_LIBRARIES "${TIFF_LIBRARY}") endif() @@ -451,7 +454,7 @@ add_bundled_libraries(openimageio/lib) if(WITH_OPENCOLORIO) find_package_wrapper(OpenColorIO 2.0.0) - set(OPENCOLORIO_DEFINITIONS) + set(OPENCOLORIO_DEFINITIONS "") set_and_warn_library_found("OpenColorIO" OPENCOLORIO_FOUND WITH_OPENCOLORIO) endif() add_bundled_libraries(opencolorio/lib) @@ -551,9 +554,14 @@ else() endif() find_package(Threads REQUIRED) -list(APPEND PLATFORM_LINKLIBS ${CMAKE_THREAD_LIBS_INIT}) -# used by other platforms -set(PTHREADS_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) +# `FindThreads` documentation notes that this may be empty +# with the system libraries provide threading functionality. +if(CMAKE_THREAD_LIBS_INIT) + list(APPEND PLATFORM_LINKLIBS ${CMAKE_THREAD_LIBS_INIT}) + # used by other platforms + set(PTHREADS_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) +endif() + if(CMAKE_DL_LIBS) list(APPEND PLATFORM_LINKLIBS ${CMAKE_DL_LIBS}) diff --git a/extern/mantaflow/CMakeLists.txt b/extern/mantaflow/CMakeLists.txt index 06767e9af1e..2c503071184 100644 --- a/extern/mantaflow/CMakeLists.txt +++ b/extern/mantaflow/CMakeLists.txt @@ -13,10 +13,12 @@ endif() # Exporting functions from the blender binary gives linker warnings on Apple arm64 systems. # Silence them here. -if(APPLE AND ("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64")) - if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - string(APPEND CMAKE_C_FLAGS " -fvisibility=hidden") - string(APPEND CMAKE_CXX_FLAGS " -fvisibility=hidden") +if(APPLE) + if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64") + if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + string(APPEND CMAKE_C_FLAGS " -fvisibility=hidden") + string(APPEND CMAKE_CXX_FLAGS " -fvisibility=hidden") + endif() endif() endif() @@ -261,9 +263,11 @@ set(LIB blender_add_lib(extern_mantaflow "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") -# The VDB libs above are only added to as INTERFACE libs by blender_add_lib, -# meaning extern_mantaflow itself actually does not have a dependency on the -# openvdb libraries, and CMAKE is free to link the vdb libs before -# extern_mantaflow causing linker errors on linux. By explicitly declaring -# a dependency here, cmake will do the right thing. -target_link_libraries(extern_mantaflow PRIVATE ${OPENVDB_LIBRARIES}) +if(WITH_OPENVDB) + # The VDB libs above are only added to as INTERFACE libs by blender_add_lib, + # meaning extern_mantaflow itself actually does not have a dependency on the + # openvdb libraries, and CMAKE is free to link the vdb libs before + # extern_mantaflow causing linker errors on linux. By explicitly declaring + # a dependency here, cmake will do the right thing. + target_link_libraries(extern_mantaflow PRIVATE ${OPENVDB_LIBRARIES}) +endif() diff --git a/intern/cycles/cmake/macros.cmake b/intern/cycles/cmake/macros.cmake index d1a929f2b35..0753e8cc592 100644 --- a/intern/cycles/cmake/macros.cmake +++ b/intern/cycles/cmake/macros.cmake @@ -111,8 +111,10 @@ macro(cycles_external_libraries_append libraries) endif() if(WITH_OPENIMAGEDENOISE) list(APPEND ${libraries} ${OPENIMAGEDENOISE_LIBRARIES}) - if(APPLE AND "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64") - list(APPEND ${libraries} "-framework Accelerate") + if(APPLE) + if("${CMAKE_OSX_ARCHITECTURES}" STREQUAL "arm64") + list(APPEND ${libraries} "-framework Accelerate") + endif() endif() endif() if(WITH_ALEMBIC) @@ -136,7 +138,15 @@ macro(cycles_external_libraries_append libraries) ${PYTHON_LIBRARIES} ${ZLIB_LIBRARIES} ${CMAKE_DL_LIBS} - ${PTHREADS_LIBRARIES} + ) + + if(DEFINED PTHREADS_LIBRARIES) + list(APPEND ${libraries} + ${PTHREADS_LIBRARIES} + ) + endif() + + list(APPEND ${libraries} ${PLATFORM_LINKLIBS} ) diff --git a/intern/cycles/graph/CMakeLists.txt b/intern/cycles/graph/CMakeLists.txt index ca4f996ed5d..d183b77c6ab 100644 --- a/intern/cycles/graph/CMakeLists.txt +++ b/intern/cycles/graph/CMakeLists.txt @@ -5,6 +5,9 @@ set(INC .. ) +set(INC_SYS +) + set(SRC node.cpp node_type.cpp diff --git a/intern/cycles/integrator/CMakeLists.txt b/intern/cycles/integrator/CMakeLists.txt index 9869a8744a3..0559a3e9401 100644 --- a/intern/cycles/integrator/CMakeLists.txt +++ b/intern/cycles/integrator/CMakeLists.txt @@ -5,6 +5,9 @@ set(INC .. ) +set(INC_SYS +) + set(SRC adaptive_sampling.cpp denoiser.cpp diff --git a/intern/cycles/session/CMakeLists.txt b/intern/cycles/session/CMakeLists.txt index 4f3a0a99ee1..9f4b4e3cc36 100644 --- a/intern/cycles/session/CMakeLists.txt +++ b/intern/cycles/session/CMakeLists.txt @@ -5,6 +5,9 @@ set(INC .. ) +set(INC_SYS +) + set(SRC buffers.cpp denoising.cpp diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt index 5d766d8543d..63310f858b1 100644 --- a/intern/guardedalloc/CMakeLists.txt +++ b/intern/guardedalloc/CMakeLists.txt @@ -41,10 +41,11 @@ if(WIN32 AND NOT UNIX) list(APPEND INC_SYS ${PTHREADS_INC} ) - - list(APPEND LIB - ${PTHREADS_LIBRARIES} - ) + if(DEFINED PTHREADS_LIBRARIES) + list(APPEND LIB + ${PTHREADS_LIBRARIES} + ) + endif() endif() # Jemalloc 5.0.0+ needs extra configuration. diff --git a/source/blender/blendthumb/CMakeLists.txt b/source/blender/blendthumb/CMakeLists.txt index 6160d225d45..5a5bc20fed7 100644 --- a/source/blender/blendthumb/CMakeLists.txt +++ b/source/blender/blendthumb/CMakeLists.txt @@ -50,5 +50,7 @@ else() add_executable(blender-thumbnailer ${SRC} ${SRC_CMD}) setup_platform_linker_flags(blender-thumbnailer) target_link_libraries(blender-thumbnailer bf_blenlib) - target_link_libraries(blender-thumbnailer ${PTHREADS_LIBRARIES}) + if(DEFINED PTHREADS_LIBRARIES) + target_link_libraries(blender-thumbnailer ${PTHREADS_LIBRARIES}) + endif() endif() diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 15c44589291..8a3c6877787 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -559,15 +559,16 @@ if(WIN32) endif() if(WITH_AUDASPACE) - add_definitions(-DWITH_AUDASPACE) - list(APPEND INC_SYS ${AUDASPACE_C_INCLUDE_DIRS} ) - list(APPEND LIB - ${AUDASPACE_C_LIBRARIES} - ${AUDASPACE_PY_LIBRARIES} - ) + if(WITH_SYSTEM_AUDASPACE) + list(APPEND LIB + ${AUDASPACE_C_LIBRARIES} + ${AUDASPACE_PY_LIBRARIES} + ) + endif() + add_definitions(-DWITH_AUDASPACE) endif() if(WITH_BULLET) diff --git a/source/blender/compositor/realtime_compositor/CMakeLists.txt b/source/blender/compositor/realtime_compositor/CMakeLists.txt index f9739972690..38e5c6be88c 100644 --- a/source/blender/compositor/realtime_compositor/CMakeLists.txt +++ b/source/blender/compositor/realtime_compositor/CMakeLists.txt @@ -16,6 +16,8 @@ set(INC ../../../../intern/guardedalloc ) +set(INC_SYS +) set(SRC intern/compile_state.cc diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 2c4d2b65ea5..2ced6f2d1bf 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -35,7 +35,6 @@ set(INC # dna_type_offsets.h ${CMAKE_CURRENT_BINARY_DIR}/../makesdna/intern - ${OPENSUBDIV_INCLUDE_DIRS} ) set(SRC @@ -724,6 +723,12 @@ if(WITH_DRAW_DEBUG) add_definitions(-DWITH_DRAW_DEBUG) endif() +if(WITH_OPENSUBDIV) + list(APPEND INC_SYS + ${OPENSUBDIV_INCLUDE_DIRS} + ) +endif() + if(WITH_MOD_FLUID) list(APPEND INC ../../../intern/mantaflow/extern diff --git a/source/blender/editors/animation/CMakeLists.txt b/source/blender/editors/animation/CMakeLists.txt index a72b2874f95..66db6eb7924 100644 --- a/source/blender/editors/animation/CMakeLists.txt +++ b/source/blender/editors/animation/CMakeLists.txt @@ -17,6 +17,8 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) set(SRC anim_channels_defines.c diff --git a/source/blender/editors/armature/CMakeLists.txt b/source/blender/editors/armature/CMakeLists.txt index 23e446f98da..acc84259c3b 100644 --- a/source/blender/editors/armature/CMakeLists.txt +++ b/source/blender/editors/armature/CMakeLists.txt @@ -19,6 +19,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC armature_add.c armature_edit.c diff --git a/source/blender/editors/curve/CMakeLists.txt b/source/blender/editors/curve/CMakeLists.txt index 0cedc05981b..90a77750860 100644 --- a/source/blender/editors/curve/CMakeLists.txt +++ b/source/blender/editors/curve/CMakeLists.txt @@ -17,6 +17,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC curve_ops.c editcurve.c diff --git a/source/blender/editors/gizmo_library/CMakeLists.txt b/source/blender/editors/gizmo_library/CMakeLists.txt index 84181b5f95d..861ab1a40c5 100644 --- a/source/blender/editors/gizmo_library/CMakeLists.txt +++ b/source/blender/editors/gizmo_library/CMakeLists.txt @@ -18,6 +18,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC gizmo_draw_utils.c gizmo_geometry.h diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt index 866df16f3d6..d3dde9ea800 100644 --- a/source/blender/editors/gpencil/CMakeLists.txt +++ b/source/blender/editors/gpencil/CMakeLists.txt @@ -18,6 +18,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC annotate_draw.c annotate_paint.c diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt index e3c809b6ccd..5b1a17a0ac6 100644 --- a/source/blender/editors/interface/CMakeLists.txt +++ b/source/blender/editors/interface/CMakeLists.txt @@ -26,6 +26,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC eyedroppers/eyedropper_color.cc eyedroppers/eyedropper_colorband.cc diff --git a/source/blender/editors/mask/CMakeLists.txt b/source/blender/editors/mask/CMakeLists.txt index 593eeb6c69d..1239d53ae4e 100644 --- a/source/blender/editors/mask/CMakeLists.txt +++ b/source/blender/editors/mask/CMakeLists.txt @@ -13,6 +13,9 @@ set(INC ../../../../intern/guardedalloc ) +set(INC_SYS +) + set(SRC mask_add.c mask_draw.c diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index 17365cc5488..040d67a60f4 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -29,6 +29,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC object_add.cc object_bake.c diff --git a/source/blender/editors/physics/CMakeLists.txt b/source/blender/editors/physics/CMakeLists.txt index e56d58c2135..2231a727cf6 100644 --- a/source/blender/editors/physics/CMakeLists.txt +++ b/source/blender/editors/physics/CMakeLists.txt @@ -17,6 +17,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC dynamicpaint_ops.c particle_boids.c diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt index bde73402277..bf236192fd8 100644 --- a/source/blender/editors/screen/CMakeLists.txt +++ b/source/blender/editors/screen/CMakeLists.txt @@ -20,6 +20,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC area.c area_query.c diff --git a/source/blender/editors/sound/CMakeLists.txt b/source/blender/editors/sound/CMakeLists.txt index 34607610250..d325792c0c9 100644 --- a/source/blender/editors/sound/CMakeLists.txt +++ b/source/blender/editors/sound/CMakeLists.txt @@ -30,15 +30,18 @@ set(LIB ) if(WITH_AUDASPACE) + list(APPEND LIB + bf_intern_audaspace + ) list(APPEND INC_SYS ${AUDASPACE_C_INCLUDE_DIRS} ) - list(APPEND LIB - bf_intern_audaspace - - ${AUDASPACE_C_LIBRARIES} - ${AUDASPACE_PY_LIBRARIES} - ) + if(WITH_SYSTEM_AUDASPACE) + list(APPEND LIB + ${AUDASPACE_C_LIBRARIES} + ${AUDASPACE_PY_LIBRARIES} + ) + endif() add_definitions(-DWITH_AUDASPACE) endif() diff --git a/source/blender/editors/space_action/CMakeLists.txt b/source/blender/editors/space_action/CMakeLists.txt index 3ec814ada48..dcd63e57a14 100644 --- a/source/blender/editors/space_action/CMakeLists.txt +++ b/source/blender/editors/space_action/CMakeLists.txt @@ -19,6 +19,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC action_buttons.c action_data.c diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index 09803d8b1d0..d973f96424d 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -19,6 +19,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC buttons_context.c buttons_ops.c diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt index 6a2b5cbfc8d..15f1e130a64 100644 --- a/source/blender/editors/space_clip/CMakeLists.txt +++ b/source/blender/editors/space_clip/CMakeLists.txt @@ -22,6 +22,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC clip_buttons.c clip_dopesheet_draw.c diff --git a/source/blender/editors/space_console/CMakeLists.txt b/source/blender/editors/space_console/CMakeLists.txt index 51523bcb383..c7f5116ba0e 100644 --- a/source/blender/editors/space_console/CMakeLists.txt +++ b/source/blender/editors/space_console/CMakeLists.txt @@ -16,6 +16,9 @@ set(INC ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern ) +set(INC_SYS +) + set(SRC console_draw.c console_ops.c diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt index 2c3b775f796..06f4f81e8b8 100644 --- a/source/blender/editors/space_file/CMakeLists.txt +++ b/source/blender/editors/space_file/CMakeLists.txt @@ -24,6 +24,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC asset_catalog_tree_view.cc file_draw.c diff --git a/source/blender/editors/space_graph/CMakeLists.txt b/source/blender/editors/space_graph/CMakeLists.txt index f67434b0f6d..23dab593435 100644 --- a/source/blender/editors/space_graph/CMakeLists.txt +++ b/source/blender/editors/space_graph/CMakeLists.txt @@ -19,6 +19,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC graph_buttons.c graph_draw.c @@ -39,15 +42,18 @@ set(LIB ) if(WITH_AUDASPACE) + list(APPEND LIB + bf_intern_audaspace + ) list(APPEND INC_SYS ${AUDASPACE_C_INCLUDE_DIRS} ) - list(APPEND LIB - bf_intern_audaspace - - ${AUDASPACE_C_LIBRARIES} - ${AUDASPACE_PY_LIBRARIES} - ) + if(WITH_SYSTEM_AUDASPACE) + list(APPEND LIB + ${AUDASPACE_C_LIBRARIES} + ${AUDASPACE_PY_LIBRARIES} + ) + endif() add_definitions(-DWITH_AUDASPACE) endif() diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt index f0915243bbc..8b822c4fc2a 100644 --- a/source/blender/editors/space_image/CMakeLists.txt +++ b/source/blender/editors/space_image/CMakeLists.txt @@ -25,6 +25,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC image_buttons.c image_draw.c diff --git a/source/blender/editors/space_info/CMakeLists.txt b/source/blender/editors/space_info/CMakeLists.txt index 03314158813..7c108c416d3 100644 --- a/source/blender/editors/space_info/CMakeLists.txt +++ b/source/blender/editors/space_info/CMakeLists.txt @@ -22,6 +22,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC info_draw.c info_ops.c diff --git a/source/blender/editors/space_nla/CMakeLists.txt b/source/blender/editors/space_nla/CMakeLists.txt index 5df0ebb3b28..3e2195835b8 100644 --- a/source/blender/editors/space_nla/CMakeLists.txt +++ b/source/blender/editors/space_nla/CMakeLists.txt @@ -19,6 +19,8 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) set(SRC nla_buttons.c diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt index d1998f15757..78163b13fcb 100644 --- a/source/blender/editors/space_outliner/CMakeLists.txt +++ b/source/blender/editors/space_outliner/CMakeLists.txt @@ -22,6 +22,8 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) set(SRC outliner_collections.cc diff --git a/source/blender/editors/space_script/CMakeLists.txt b/source/blender/editors/space_script/CMakeLists.txt index 8902703b6ea..04c9a505393 100644 --- a/source/blender/editors/space_script/CMakeLists.txt +++ b/source/blender/editors/space_script/CMakeLists.txt @@ -15,6 +15,8 @@ set(INC ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern ) +set(INC_SYS +) set(SRC script_edit.c diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt index 5466beca255..842ba8d7fe8 100644 --- a/source/blender/editors/space_sequencer/CMakeLists.txt +++ b/source/blender/editors/space_sequencer/CMakeLists.txt @@ -24,6 +24,8 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) set(SRC sequencer_add.c @@ -52,15 +54,16 @@ set(LIB ) if(WITH_AUDASPACE) - add_definitions(-DWITH_AUDASPACE) - list(APPEND INC_SYS ${AUDASPACE_C_INCLUDE_DIRS} ) - list(APPEND LIB - ${AUDASPACE_C_LIBRARIES} - ${AUDASPACE_PY_LIBRARIES} - ) + if(WITH_SYSTEM_AUDASPACE) + list(APPEND LIB + ${AUDASPACE_C_LIBRARIES} + ${AUDASPACE_PY_LIBRARIES} + ) + endif() + add_definitions(-DWITH_AUDASPACE) endif() diff --git a/source/blender/editors/space_spreadsheet/CMakeLists.txt b/source/blender/editors/space_spreadsheet/CMakeLists.txt index 08032ddbaeb..d927cc5c7c5 100644 --- a/source/blender/editors/space_spreadsheet/CMakeLists.txt +++ b/source/blender/editors/space_spreadsheet/CMakeLists.txt @@ -23,6 +23,9 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) + set(SRC space_spreadsheet.cc spreadsheet_cache.cc diff --git a/source/blender/editors/space_statusbar/CMakeLists.txt b/source/blender/editors/space_statusbar/CMakeLists.txt index f73e03815a3..aca1c2995f6 100644 --- a/source/blender/editors/space_statusbar/CMakeLists.txt +++ b/source/blender/editors/space_statusbar/CMakeLists.txt @@ -18,6 +18,8 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) set(SRC space_statusbar.c diff --git a/source/blender/editors/space_text/CMakeLists.txt b/source/blender/editors/space_text/CMakeLists.txt index dfd6111e067..6cdc7f4aa67 100644 --- a/source/blender/editors/space_text/CMakeLists.txt +++ b/source/blender/editors/space_text/CMakeLists.txt @@ -17,6 +17,8 @@ set(INC ${CMAKE_CURRENT_BINARY_DIR}/../../makesdna/intern ) +set(INC_SYS +) set(SRC space_text.c diff --git a/source/blender/editors/space_topbar/CMakeLists.txt b/source/blender/editors/space_topbar/CMakeLists.txt index a0854bd688c..03a7bd90a69 100644 --- a/source/blender/editors/space_topbar/CMakeLists.txt +++ b/source/blender/editors/space_topbar/CMakeLists.txt @@ -18,6 +18,8 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) set(SRC space_topbar.c diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 579e27b9259..78eec9b9dfa 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -25,6 +25,8 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) set(SRC drawobject.c diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt index bcd87ff9572..c73585d549e 100644 --- a/source/blender/editors/transform/CMakeLists.txt +++ b/source/blender/editors/transform/CMakeLists.txt @@ -19,7 +19,8 @@ set(INC # RNA_prototypes.h ${CMAKE_BINARY_DIR}/source/blender/makesrna ) - +set(INC_SYS +) set(SRC transform.c diff --git a/source/blender/editors/undo/CMakeLists.txt b/source/blender/editors/undo/CMakeLists.txt index 271d05e9c04..11101bb6b25 100644 --- a/source/blender/editors/undo/CMakeLists.txt +++ b/source/blender/editors/undo/CMakeLists.txt @@ -14,6 +14,9 @@ set(INC ../../bmesh ) +set(INC_SYS +) + set(SRC ed_undo.c memfile_undo.c diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index c15db57d3b7..f06e99da3bd 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -22,6 +22,8 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) set(SRC ed_draw.c diff --git a/source/blender/editors/uvedit/CMakeLists.txt b/source/blender/editors/uvedit/CMakeLists.txt index 9a9f79b7972..d2bc0018c25 100644 --- a/source/blender/editors/uvedit/CMakeLists.txt +++ b/source/blender/editors/uvedit/CMakeLists.txt @@ -18,6 +18,8 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) set(SRC uvedit_buttons.c diff --git a/source/blender/freestyle/CMakeLists.txt b/source/blender/freestyle/CMakeLists.txt index 8f9e493023c..ec1b6376d04 100644 --- a/source/blender/freestyle/CMakeLists.txt +++ b/source/blender/freestyle/CMakeLists.txt @@ -556,7 +556,6 @@ set(INC set(INC_SYS ${PYTHON_INCLUDE_DIRS} - ${PNG_INC} ) add_definitions(-DWITH_FREESTYLE) diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index f93317cdc28..4faa3aa718c 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -43,7 +43,6 @@ set(INC set(INC_SYS ${Epoxy_INCLUDE_DIRS} - ${VULKAN_INCLUDE_DIRS} ) set(SRC @@ -267,6 +266,10 @@ set(METAL_SRC metal/mtl_vertex_buffer.hh ) +set(LIB + ${Epoxy_LIBRARIES} +) + # Select Backend source based on availability if(WITH_OPENGL) list(APPEND SRC ${OPENGL_SRC}) @@ -276,27 +279,23 @@ if(WITH_METAL_BACKEND) list(APPEND SRC ${METAL_SRC}) endif() -set(LIB - ${Epoxy_LIBRARIES} - ${VULKAN_LIBRARIES} -) if(WITH_VULKAN_BACKEND) - list(APPEND SRC ${VULKAN_SRC}) - - add_definitions(-DWITH_VULKAN_BACKEND) - - list(APPEND INC_SYS - ${VULKAN_INCLUDE_DIRS} - ) - list(APPEND INC ../../../extern/vulkan_memory_allocator/ ) + list(APPEND INC_SYS + ${VULKAN_INCLUDE_DIRS} + ) + list(APPEND SRC + ${VULKAN_SRC} + ) list(APPEND LIB + ${VULKAN_LIBRARIES} extern_vulkan_memory_allocator ) + add_definitions(-DWITH_VULKAN_BACKEND) endif() set(MSL_SRC diff --git a/source/blender/imbuf/intern/oiio/CMakeLists.txt b/source/blender/imbuf/intern/oiio/CMakeLists.txt index fc864f7f11a..b694f6b51a7 100644 --- a/source/blender/imbuf/intern/oiio/CMakeLists.txt +++ b/source/blender/imbuf/intern/oiio/CMakeLists.txt @@ -28,8 +28,13 @@ set(LIB if(WITH_OPENIMAGEIO) list(APPEND INC_SYS ${OPENIMAGEIO_INCLUDE_DIRS} - ${BOOST_INCLUDE_DIR} ) + if(WITH_BOOST) + list(APPEND INC_SYS + ${BOOST_INCLUDE_DIR} + ) + endif() + list(APPEND LIB ${OPENIMAGEIO_LIBRARIES} ${PUGIXML_LIBRARIES} @@ -43,10 +48,11 @@ if(WITH_OPENIMAGEIO) ) endif() - list(APPEND LIB - ${BOOST_LIBRARIES} - ) - + if(WITH_BOOST) + list(APPEND LIB + ${BOOST_LIBRARIES} + ) + endif() add_definitions(-DWITH_OPENIMAGEIO) endif() diff --git a/source/blender/io/alembic/CMakeLists.txt b/source/blender/io/alembic/CMakeLists.txt index fd24ab7cbaf..199666983ac 100644 --- a/source/blender/io/alembic/CMakeLists.txt +++ b/source/blender/io/alembic/CMakeLists.txt @@ -20,10 +20,15 @@ set(INC set(INC_SYS ${ALEMBIC_INCLUDE_DIRS} - ${BOOST_INCLUDE_DIR} ${OPENEXR_INCLUDE_DIRS} ) +if(WITH_BOOST) + list(APPEND INC_SYS + ${BOOST_INCLUDE_DIR} + ) +endif() + set(SRC intern/abc_axis_conversion.cc intern/abc_customdata.cc @@ -92,9 +97,11 @@ set(LIB ${OPENEXR_LIBRARIES} ) -list(APPEND LIB - ${BOOST_LIBRARIES} -) +if(WITH_BOOST) + list(APPEND LIB + ${BOOST_LIBRARIES} + ) +endif() blender_add_lib(bf_alembic "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/io/gpencil/CMakeLists.txt b/source/blender/io/gpencil/CMakeLists.txt index 54bf52dc546..c1317cc27fd 100644 --- a/source/blender/io/gpencil/CMakeLists.txt +++ b/source/blender/io/gpencil/CMakeLists.txt @@ -74,9 +74,10 @@ if(WITH_HARU) add_definitions(-DWITH_HARU) endif() - -list(APPEND LIB - ${BOOST_LIBRARIES} -) +if(WITH_BOOST) + list(APPEND LIB + ${BOOST_LIBRARIES} + ) +endif() blender_add_lib(bf_gpencil "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/makesdna/intern/CMakeLists.txt b/source/blender/makesdna/intern/CMakeLists.txt index a7164ddc959..944aec1f8bd 100644 --- a/source/blender/makesdna/intern/CMakeLists.txt +++ b/source/blender/makesdna/intern/CMakeLists.txt @@ -70,7 +70,9 @@ blender_target_include_dirs(makesdna ${INC}) blender_target_include_dirs_sys(makesdna ${INC_SYS}) if(WIN32 AND NOT UNIX) - target_link_libraries(makesdna ${PTHREADS_LIBRARIES}) + if(DEFINED PTHREADS_LIBRARIES) + target_link_libraries(makesdna ${PTHREADS_LIBRARIES}) + endif() endif() # Output dna.c diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt index 87dfb05366c..adf139f3e6a 100644 --- a/source/blender/makesrna/intern/CMakeLists.txt +++ b/source/blender/makesrna/intern/CMakeLists.txt @@ -271,15 +271,16 @@ if(WITH_IMAGE_WEBP) endif() if(WITH_AUDASPACE) - add_definitions(-DWITH_AUDASPACE) - list(APPEND INC_SYS ${AUDASPACE_C_INCLUDE_DIRS} ) - list(APPEND LIB - ${AUDASPACE_C_LIBRARIES} - ${AUDASPACE_PY_LIBRARIES} - ) + if(WITH_SYSTEM_AUDASPACE) + list(APPEND LIB + ${AUDASPACE_C_LIBRARIES} + ${AUDASPACE_PY_LIBRARIES} + ) + endif() + add_definitions(-DWITH_AUDASPACE) endif() if(WITH_CODEC_FFMPEG) @@ -405,7 +406,9 @@ target_link_libraries(makesrna bf_dna) target_link_libraries(makesrna bf_dna_blenlib) if(WIN32 AND NOT UNIX) - target_link_libraries(makesrna ${PTHREADS_LIBRARIES}) + if(DEFINED PTHREADS_LIBRARIES) + target_link_libraries(makesrna ${PTHREADS_LIBRARIES}) + endif() endif() # Output `rna_*_gen.c`. diff --git a/source/blender/nodes/composite/CMakeLists.txt b/source/blender/nodes/composite/CMakeLists.txt index 110bf237018..6fb4e9ba753 100644 --- a/source/blender/nodes/composite/CMakeLists.txt +++ b/source/blender/nodes/composite/CMakeLists.txt @@ -28,6 +28,8 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) set(SRC nodes/node_composite_alpha_over.cc diff --git a/source/blender/nodes/function/CMakeLists.txt b/source/blender/nodes/function/CMakeLists.txt index c95201ddfd7..481ab82602b 100644 --- a/source/blender/nodes/function/CMakeLists.txt +++ b/source/blender/nodes/function/CMakeLists.txt @@ -16,6 +16,8 @@ set(INC ../../../../intern/guardedalloc ) +set(INC_SYS +) set(SRC nodes/node_fn_align_euler_to_vector.cc diff --git a/source/blender/nodes/texture/CMakeLists.txt b/source/blender/nodes/texture/CMakeLists.txt index 74602962f25..364230ad068 100644 --- a/source/blender/nodes/texture/CMakeLists.txt +++ b/source/blender/nodes/texture/CMakeLists.txt @@ -20,6 +20,8 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) +set(INC_SYS +) set(SRC nodes/node_texture_at.cc diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index 9adaeaecf64..5a57129e6d7 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -24,6 +24,8 @@ set(INC ../../../intern/mantaflow/extern ) +set(INC_SYS +) set(SRC intern/bake.cc diff --git a/source/blender/sequencer/CMakeLists.txt b/source/blender/sequencer/CMakeLists.txt index 30aec24a024..76a3a060e19 100644 --- a/source/blender/sequencer/CMakeLists.txt +++ b/source/blender/sequencer/CMakeLists.txt @@ -90,15 +90,16 @@ set(LIB ) if(WITH_AUDASPACE) - add_definitions(-DWITH_AUDASPACE) - list(APPEND INC_SYS ${AUDASPACE_C_INCLUDE_DIRS} ) - list(APPEND LIB - ${AUDASPACE_C_LIBRARIES} - ${AUDASPACE_PY_LIBRARIES} - ) + if(WITH_SYSTEM_AUDASPACE) + list(APPEND LIB + ${AUDASPACE_C_LIBRARIES} + ${AUDASPACE_PY_LIBRARIES} + ) + endif() + add_definitions(-DWITH_AUDASPACE) endif() blender_add_lib(bf_sequencer "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index 16f69dac1bf..7dca7ce7ead 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -106,15 +106,16 @@ set(LIB ) if(WITH_AUDASPACE) - add_definitions(-DWITH_AUDASPACE) - list(APPEND INC_SYS ${AUDASPACE_C_INCLUDE_DIRS} ) - list(APPEND LIB - ${AUDASPACE_C_LIBRARIES} - ${AUDASPACE_PY_LIBRARIES} - ) + if(WITH_SYSTEM_AUDASPACE) + list(APPEND LIB + ${AUDASPACE_C_LIBRARIES} + ${AUDASPACE_PY_LIBRARIES} + ) + endif() + add_definitions(-DWITH_AUDASPACE) endif() if(WITH_CYCLES) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9f634af7143..6dcfeecc654 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -32,7 +32,7 @@ endif() # Include these arguments before all others, they must not interfere with Python execution. -set(TEST_PYTHON_EXE_EXTRA_ARGS) +set(TEST_PYTHON_EXE_EXTRA_ARGS "") # Check if this a Blender managed Python installation, if so, don't add `*.pyc` files. if(LIBDIR) diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index cc16a5641e1..201d7fb8b48 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -26,11 +26,14 @@ function(add_blender_test testname) COMMAND "${TEST_BLENDER_EXE}" ${TEST_BLENDER_EXE_PARAMS} ${ARGN} ) - # Don't fail tests on leaks since these often happen in external libraries - # that we can't fix. - set_tests_properties(${testname} PROPERTIES ENVIRONMENT - LSAN_OPTIONS=exitcode=0:$ENV{LSAN_OPTIONS} - ) + # Don't fail tests on leaks since these often happen in external libraries that we can't fix. + set(_lsan_options "exitcode=0") + if(DEFINED ENV{LSAN_OPTIONS}) + set(_lsan_options "${_lsan_options}:$ENV{LSAN_OPTIONS}") + endif() + set_tests_properties(${testname} PROPERTIES ENVIRONMENT "LSAN_OPTIONS=${_lsan_options}") + unset(_lsan_options) + if(PLATFORM_ENV_INSTALL) set_tests_properties(${testname} PROPERTIES ENVIRONMENT "${PLATFORM_ENV_INSTALL}") endif() @@ -47,9 +50,14 @@ function(add_python_test testname testscript) COMMAND ${TEST_PYTHON_EXE} ${TEST_PYTHON_EXE_EXTRA_ARGS} ${testscript} ${ARGN} WORKING_DIRECTORY $ ) - set_tests_properties(${testname} PROPERTIES ENVIRONMENT - LSAN_OPTIONS=exitcode=0:$ENV{LSAN_OPTIONS} - ) + + set(_lsan_options "exitcode=0") + if(DEFINED ENV{LSAN_OPTIONS}) + set(_lsan_options "${_lsan_options}:$ENV{LSAN_OPTIONS}") + endif() + set_tests_properties(${testname} PROPERTIES ENVIRONMENT "LSAN_OPTIONS=${_lsan_options}") + unset(_lsan_options) + if(PLATFORM_ENV_INSTALL) set_tests_properties(${testname} PROPERTIES ENVIRONMENT "${PLATFORM_ENV_INSTALL}") endif() @@ -639,20 +647,24 @@ endif() # SVG Import if(True) - set(_svg_render_tests complex path) + if(NOT OPENIMAGEIO_IDIFF) + message(WARNING "Disabling SVG tests because OIIO idiff does not exist") + else() + set(_svg_render_tests complex path) - foreach(render_test ${_svg_render_tests}) - add_python_test( - io_curve_svg_${render_test} - ${CMAKE_CURRENT_LIST_DIR}/bl_io_curve_svg_test.py - -blender "${TEST_BLENDER_EXE}" - -testdir "${TEST_SRC_DIR}/io_tests/svg/${render_test}" - -idiff "${OPENIMAGEIO_IDIFF}" - -outdir "${TEST_OUT_DIR}/io_curve_svg" - ) - endforeach() + foreach(render_test ${_svg_render_tests}) + add_python_test( + io_curve_svg_${render_test} + ${CMAKE_CURRENT_LIST_DIR}/bl_io_curve_svg_test.py + -blender "${TEST_BLENDER_EXE}" + -testdir "${TEST_SRC_DIR}/io_tests/svg/${render_test}" + -idiff "${OPENIMAGEIO_IDIFF}" + -outdir "${TEST_OUT_DIR}/io_curve_svg" + ) + endforeach() - unset(_svg_render_tests) + unset(_svg_render_tests) + endif() endif() if(WITH_CYCLES OR WITH_OPENGL_RENDER_TESTS) @@ -715,6 +727,7 @@ if(WITH_CYCLES OR WITH_OPENGL_RENDER_TESTS) # Cycles if(WITH_CYCLES) + set(_cycles_blacklist "") if(NOT WITH_CYCLES_OSL) set(_cycles_blacklist OSL) endif() @@ -735,6 +748,7 @@ if(WITH_CYCLES OR WITH_OPENGL_RENDER_TESTS) ) endforeach() endforeach() + unset(_cycles_blacklist) endif() if(WITH_OPENGL_RENDER_TESTS) @@ -766,32 +780,35 @@ if(WITH_CYCLES OR WITH_OPENGL_RENDER_TESTS) endif() if(WITH_COMPOSITOR_CPU) - set(compositor_tests - color - converter - filter - input - output - vector + if(NOT OPENIMAGEIO_IDIFF) + message(WARNING "Disabling Compositor CPU tests because OIIO idiff does not exist") + else() + set(compositor_tests + color + converter + filter + input + output + vector - multiple_node_setups - ) - - if(WITH_LIBMV) - list(APPEND compositor_tests distort matte) - endif() - - foreach(comp_test ${compositor_tests}) - add_python_test( - compositor_${comp_test}_test - ${CMAKE_CURRENT_LIST_DIR}/compositor_render_tests.py - -blender "${TEST_BLENDER_EXE}" - -testdir "${TEST_SRC_DIR}/compositor/${comp_test}" - -idiff "${OPENIMAGEIO_IDIFF}" - -outdir "${TEST_OUT_DIR}/compositor" + multiple_node_setups ) - endforeach() + if(WITH_LIBMV) + list(APPEND compositor_tests distort matte) + endif() + + foreach(comp_test ${compositor_tests}) + add_python_test( + compositor_${comp_test}_test + ${CMAKE_CURRENT_LIST_DIR}/compositor_render_tests.py + -blender "${TEST_BLENDER_EXE}" + -testdir "${TEST_SRC_DIR}/compositor/${comp_test}" + -idiff "${OPENIMAGEIO_IDIFF}" + -outdir "${TEST_OUT_DIR}/compositor" + ) + endforeach() + endif() endif() set(geo_node_tests From bc502f3b19099a97748cf6f91f2e213915d613c0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 19 Jan 2023 17:07:24 +1100 Subject: [PATCH 0758/1522] CMake: add WITH_LIBS_PRECOMPILED option (UNIX only) This makes it convenient to build blender without referencing pre-compiled libraries which don't always work on newer Linux systems. Previously I had to rename ../lib while creating the CMakeCache.txt to ensure my systems libraries would be used. This change ensures LIBDIR is undefined when WITH_LIBS_PRECOMPILED is disabled, so any accidental use warns with CMake's `--warn-unused-vars` argument is given. --- CMakeLists.txt | 25 ++++-- build_files/cmake/Modules/FindMoltenVK.cmake | 6 +- build_files/cmake/macros.cmake | 2 +- .../platform/platform_old_libs_update.cmake | 7 +- .../cmake/platform/platform_unix.cmake | 78 +++++++++++-------- source/creator/CMakeLists.txt | 11 ++- tests/CMakeLists.txt | 2 +- 7 files changed, 86 insertions(+), 45 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2acae1d7b26..94bad8c20fc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -399,6 +399,26 @@ mark_as_advanced(WITH_SYSTEM_GLOG) # Freestyle option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON) +# Libraries. +if(UNIX AND NOT APPLE) + # Optionally build without pre-compiled libraries. + # NOTE: this could be supported on all platforms however in practice UNIX is the only platform + # that has good support for detecting installed libraries. + option(WITH_LIBS_PRECOMPILED "\ +Detect and link against pre-compiled libraries (typically found under \"../lib/\"). \ +Disabling this option will use the system libraries although cached paths \ +that point to pre-compiled libraries will be left as-is." + ON + ) + mark_as_advanced(WITH_LIBS_PRECOMPILED) + + option(WITH_STATIC_LIBS "Try to link with static libraries, as much as possible, to make blender more portable across distributions" OFF) + if(WITH_STATIC_LIBS) + option(WITH_BOOST_ICU "Boost uses ICU library (required for linking with static Boost built with libicu)." OFF) + mark_as_advanced(WITH_BOOST_ICU) + endif() +endif() + # Misc if(WIN32 OR APPLE) option(WITH_INPUT_IME "Enable Input Method Editor (IME) for complex Asian character input" ON) @@ -406,11 +426,6 @@ endif() option(WITH_INPUT_NDOF "Enable NDOF input devices (SpaceNavigator and friends)" ON) if(UNIX AND NOT APPLE) option(WITH_INSTALL_PORTABLE "Install redistributable runtime, otherwise install into CMAKE_INSTALL_PREFIX" ON) - option(WITH_STATIC_LIBS "Try to link with static libraries, as much as possible, to make blender more portable across distributions" OFF) - if(WITH_STATIC_LIBS) - option(WITH_BOOST_ICU "Boost uses ICU library (required for linking with static Boost built with libicu)." OFF) - mark_as_advanced(WITH_BOOST_ICU) - endif() endif() option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON) diff --git a/build_files/cmake/Modules/FindMoltenVK.cmake b/build_files/cmake/Modules/FindMoltenVK.cmake index 07584e51ae5..aaaa6bcd87c 100644 --- a/build_files/cmake/Modules/FindMoltenVK.cmake +++ b/build_files/cmake/Modules/FindMoltenVK.cmake @@ -19,9 +19,13 @@ ENDIF() SET(_moltenvk_SEARCH_DIRS ${MOLTENVK_ROOT_DIR} - ${LIBDIR}/vulkan/MoltenVK ) +# FIXME: These finder modules typically don't use LIBDIR, +# this should be set by `./build_files/cmake/platform/` instead. +IF(DEFINED LIBDIR) + SET(_moltenvk_SEARCH_DIRS ${_moltenvk_SEARCH_DIRS} ${LIBDIR}/vulkan/MoltenVK) +ENDIF() FIND_PATH(MOLTENVK_INCLUDE_DIR NAMES diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake index 44081ee5d81..dc7c101f91a 100644 --- a/build_files/cmake/macros.cmake +++ b/build_files/cmake/macros.cmake @@ -1264,7 +1264,7 @@ endmacro() # Utility to gather and install precompiled shared libraries. macro(add_bundled_libraries library_dir) - if(EXISTS ${LIBDIR}) + if(DEFINED LIBDIR) set(_library_dir ${LIBDIR}/${library_dir}) if(WIN32) file(GLOB _all_library_versions ${_library_dir}/*\.dll) diff --git a/build_files/cmake/platform/platform_old_libs_update.cmake b/build_files/cmake/platform/platform_old_libs_update.cmake index ab27dd89385..d71b5d45818 100644 --- a/build_files/cmake/platform/platform_old_libs_update.cmake +++ b/build_files/cmake/platform/platform_old_libs_update.cmake @@ -1,7 +1,12 @@ # SPDX-License-Identifier: GPL-2.0-or-later # Copyright 2022 Blender Foundation. All rights reserved. -# Auto update existing CMake caches for new libraries +# Auto update existing CMake caches for new libraries. + +# Assert that `LIBDIR` is defined. +if(NOT (DEFINED LIBDIR)) + message(FATAL_ERROR "Logical error, expected 'LIBDIR' to be defined!") +endif() # Clear cached variables whose name matches `pattern`. function(unset_cache_variables pattern) diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake index 4f84fe262f5..1d8f264d8f1 100644 --- a/build_files/cmake/platform/platform_unix.cmake +++ b/build_files/cmake/platform/platform_unix.cmake @@ -4,38 +4,52 @@ # Libraries configuration for any *nix system including Linux and Unix (excluding APPLE). # Detect precompiled library directory -if(NOT DEFINED LIBDIR) - # Path to a locally compiled libraries. - set(LIBDIR_NAME ${CMAKE_SYSTEM_NAME}_${CMAKE_SYSTEM_PROCESSOR}) - string(TOLOWER ${LIBDIR_NAME} LIBDIR_NAME) - set(LIBDIR_NATIVE_ABI ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_NAME}) - # Path to precompiled libraries with known glibc 2.28 ABI. - set(LIBDIR_GLIBC228_ABI ${CMAKE_SOURCE_DIR}/../lib/linux_x86_64_glibc_228) +if(NOT WITH_LIBS_PRECOMPILED) + unset(LIBDIR) +else() + if(NOT DEFINED LIBDIR) + # Path to a locally compiled libraries. + set(LIBDIR_NAME ${CMAKE_SYSTEM_NAME}_${CMAKE_SYSTEM_PROCESSOR}) + string(TOLOWER ${LIBDIR_NAME} LIBDIR_NAME) + set(LIBDIR_NATIVE_ABI ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_NAME}) - # Choose the best suitable libraries. - if(EXISTS ${LIBDIR_NATIVE_ABI}) - set(LIBDIR ${LIBDIR_NATIVE_ABI}) - set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True) - elseif(EXISTS ${LIBDIR_GLIBC228_ABI}) - set(LIBDIR ${LIBDIR_GLIBC228_ABI}) - if(WITH_MEM_JEMALLOC) - # jemalloc provides malloc hooks. - set(WITH_LIBC_MALLOC_HOOK_WORKAROUND False) - else() + # Path to precompiled libraries with known glibc 2.28 ABI. + set(LIBDIR_GLIBC228_ABI ${CMAKE_SOURCE_DIR}/../lib/linux_x86_64_glibc_228) + + # Choose the best suitable libraries. + if(EXISTS ${LIBDIR_NATIVE_ABI}) + set(LIBDIR ${LIBDIR_NATIVE_ABI}) set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True) + elseif(EXISTS ${LIBDIR_GLIBC228_ABI}) + set(LIBDIR ${LIBDIR_GLIBC228_ABI}) + if(WITH_MEM_JEMALLOC) + # jemalloc provides malloc hooks. + set(WITH_LIBC_MALLOC_HOOK_WORKAROUND False) + else() + set(WITH_LIBC_MALLOC_HOOK_WORKAROUND True) + endif() endif() + + # Avoid namespace pollustion. + unset(LIBDIR_NATIVE_ABI) + unset(LIBDIR_GLIBC228_ABI) endif() - # Avoid namespace pollustion. - unset(LIBDIR_NATIVE_ABI) - unset(LIBDIR_GLIBC228_ABI) + if(NOT (EXISTS ${LIBDIR})) + message(STATUS + "Unable to find LIBDIR: ${LIBDIR}, system libraries may be used " + "(disable WITH_LIBS_PRECOMPILED to suppress this message)." + ) + unset(LIBDIR) + endif() endif() + # Support restoring this value once pre-compiled libraries have been handled. set(WITH_STATIC_LIBS_INIT ${WITH_STATIC_LIBS}) -if(EXISTS ${LIBDIR}) +if(DEFINED LIBDIR) message(STATUS "Using pre-compiled LIBDIR: ${LIBDIR}") file(GLOB LIB_SUBDIRS ${LIBDIR}/*) @@ -85,7 +99,7 @@ endmacro() # These are libraries that may be precompiled. For this we disable searching in # the system directories so that we don't accidentally use them instead. -if(EXISTS ${LIBDIR}) +if(DEFINED LIBDIR) without_system_libs_begin() endif() @@ -114,7 +128,7 @@ endfunction() if(NOT WITH_SYSTEM_FREETYPE) # FreeType compiled with Brotli compression for woff2. find_package_wrapper(Freetype REQUIRED) - if(EXISTS ${LIBDIR}) + if(DEFINED LIBDIR) find_package_wrapper(Brotli REQUIRED) # NOTE: This is done on WIN32 & APPLE but fails on some Linux systems. @@ -141,7 +155,7 @@ if(WITH_PYTHON) if(WITH_PYTHON_MODULE AND NOT WITH_INSTALL_PORTABLE) # Installing into `site-packages`, warn when installing into `./../lib/` # which script authors almost certainly don't want. - if(EXISTS ${LIBDIR}) + if(DEFINED LIBDIR) path_is_prefix(LIBDIR PYTHON_SITE_PACKAGES _is_prefix) if(_is_prefix) message(WARNING " @@ -217,7 +231,7 @@ if(WITH_CODEC_SNDFILE) endif() if(WITH_CODEC_FFMPEG) - if(EXISTS ${LIBDIR}) + if(DEFINED LIBDIR) set(FFMPEG_ROOT_DIR ${LIBDIR}/ffmpeg) # Override FFMPEG components to also include static library dependencies # included with precompiled libraries, and to ensure correct link order. @@ -232,7 +246,7 @@ if(WITH_CODEC_FFMPEG) vpx x264 xvidcore) - if(EXISTS ${LIBDIR}/ffmpeg/lib/libaom.a) + if((DEFINED LIBDIR) AND (EXISTS ${LIBDIR}/ffmpeg/lib/libaom.a)) list(APPEND FFMPEG_FIND_COMPONENTS aom) endif() elseif(FFMPEG) @@ -469,7 +483,7 @@ if(WITH_OPENIMAGEDENOISE) endif() if(WITH_LLVM) - if(EXISTS ${LIBDIR}) + if(DEFINED LIBDIR) set(LLVM_STATIC ON) endif() @@ -483,7 +497,7 @@ if(WITH_LLVM) endif() # Symbol conflicts with same UTF library used by OpenCollada - if(EXISTS ${LIBDIR}) + if(DEFINED LIBDIR) if(WITH_OPENCOLLADA AND (${LLVM_VERSION} VERSION_LESS "4.0.0")) list(REMOVE_ITEM OPENCOLLADA_LIBRARIES ${OPENCOLLADA_UTF_LIBRARY}) endif() @@ -539,7 +553,7 @@ if(WITH_CYCLES AND WITH_CYCLES_PATH_GUIDING) endif() endif() -if(EXISTS ${LIBDIR}) +if(DEFINED LIBDIR) without_system_libs_end() endif() @@ -583,7 +597,7 @@ add_definitions(-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE # # Keep last, so indirectly linked libraries don't override our own pre-compiled libs. -if(EXISTS ${LIBDIR}) +if(DEFINED LIBDIR) # Clear the prefix path as it causes the `LIBDIR` to override system locations. unset(CMAKE_PREFIX_PATH) @@ -639,7 +653,7 @@ if(WITH_GHOST_WAYLAND) # When dynamically linked WAYLAND is used and `${LIBDIR}/wayland` is present, # there is no need to search for the libraries as they are not needed for building. # Only the headers are needed which can reference the known paths. - if(EXISTS "${LIBDIR}/wayland" AND WITH_GHOST_WAYLAND_DYNLOAD) + if((DEFINED LIBDIR) AND (EXISTS "${LIBDIR}/wayland" AND WITH_GHOST_WAYLAND_DYNLOAD)) set(_use_system_wayland OFF) else() set(_use_system_wayland ON) @@ -703,7 +717,7 @@ if(WITH_GHOST_WAYLAND) add_definitions(-DWITH_GHOST_WAYLAND_LIBDECOR) endif() - if(EXISTS "${LIBDIR}/wayland/bin/wayland-scanner") + if((DEFINED LIBDIR) AND (EXISTS "${LIBDIR}/wayland/bin/wayland-scanner")) set(WAYLAND_SCANNER "${LIBDIR}/wayland/bin/wayland-scanner") else() pkg_get_variable(WAYLAND_SCANNER wayland-scanner wayland_scanner) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index fa3ab5d3b86..a0816f41724 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -605,7 +605,10 @@ if(UNIX AND NOT APPLE) ) endif() - if(EXISTS ${LIBDIR}/mesa) + # NOTE: there is a bug in CMake 3.25.1 where `LIBDIR` is reported as undefined. + if(NOT DEFINED LIBDIR) + # Pass. + elseif(EXISTS ${LIBDIR}/mesa) install(DIRECTORY ${LIBDIR}/mesa/lib/ DESTINATION "lib/mesa/") install( @@ -665,7 +668,7 @@ if(UNIX AND NOT APPLE) DESTINATION ${TARGETDIR_VER}/python/bin ) - if(EXISTS ${LIBDIR}) + if(DEFINED LIBDIR) # Precompiled libraries, copy over complete lib directory. install_dir( ${PYTHON_LIBPATH} @@ -1499,7 +1502,7 @@ endif() # Always install USD shared library and datafiles regardless if Blender # itself uses them, the bundled Python module still needs it. -if(LIBDIR AND TARGETDIR_LIB) +if((DEFINED LIBDIR) AND TARGETDIR_LIB) # On windows the usd library sits in ./blender.shared copy the files # relative to the location of the USD dll, if the dll does not exist # assume we are linking against the static 3.5 lib. @@ -1556,7 +1559,7 @@ endif() # Always install MaterialX files regardless if Blender itself uses them, the # bundled Python module still needs it. -if(WITH_MATERIALX AND LIBDIR AND TARGETDIR_LIB) +if((DEFINED LIBDIR) AND TARGETDIR_LIB AND WITH_MATERIALX ) install( DIRECTORY ${LIBDIR}/materialx/libraries DESTINATION "${TARGETDIR_LIB}/materialx" diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 6dcfeecc654..ff3587d93c2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -35,7 +35,7 @@ endif() set(TEST_PYTHON_EXE_EXTRA_ARGS "") # Check if this a Blender managed Python installation, if so, don't add `*.pyc` files. -if(LIBDIR) +if(DEFINED LIBDIR) path_is_prefix(LIBDIR TEST_PYTHON_EXE _is_prefix) if(_is_prefix) # Keep the Python in Blender's SVN LIBDIR pristine, to avoid conflicts on updating. From 66595e29e21b1c8b4397b8deaa91b07b5e1d9810 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 19 Jan 2023 17:07:29 +1100 Subject: [PATCH 0759/1522] Cleanup: remove/comment unused code, simplify casts Remove simple counters where they aren't used, comment in some cases. Also add missing include. --- .../blender/blenkernel/intern/curveprofile.cc | 1 + source/blender/blenkernel/intern/customdata.cc | 1 - source/blender/blenkernel/intern/gpencil.c | 2 -- .../blender/blenkernel/intern/gpencil_curve.c | 4 ++-- source/blender/blenkernel/intern/layer.cc | 3 +-- source/blender/blenkernel/intern/paint.cc | 2 -- source/blender/blenlib/intern/scanfill_utils.c | 2 -- source/blender/blenlib/tests/BLI_task_test.cc | 2 -- source/blender/bmesh/intern/bmesh_interp.c | 4 +--- source/blender/bmesh/tools/bmesh_intersect.c | 3 +-- .../engines/compositor/compositor_engine.cc | 2 ++ .../draw/engines/workbench/workbench_shader.cc | 1 - source/blender/editors/animation/fmodifier_ui.c | 3 +-- .../editors/interface/interface_layout.cc | 2 -- .../editors/interface/interface_templates.cc | 17 ++++++++--------- source/blender/editors/mesh/editmesh_rip.c | 1 + source/blender/editors/screen/area.c | 7 ------- .../editors/space_node/node_relationships.cc | 6 +++--- source/blender/editors/uvedit/uvedit_islands.cc | 2 +- .../freestyle/intern/stroke/Operators.cpp | 4 ++-- .../blender/geometry/intern/uv_parametrizer.cc | 2 -- .../intern/lineart/lineart_cpu.cc | 4 ++-- source/blender/makesrna/intern/rna_path.cc | 2 -- .../modifiers/intern/MOD_solidify_nonmanifold.c | 6 ++---- source/blender/render/intern/pipeline.cc | 1 - source/blender/render/intern/render_result.cc | 2 -- 26 files changed, 28 insertions(+), 58 deletions(-) diff --git a/source/blender/blenkernel/intern/curveprofile.cc b/source/blender/blenkernel/intern/curveprofile.cc index db0cf16d467..11fc4238e6a 100644 --- a/source/blender/blenkernel/intern/curveprofile.cc +++ b/source/blender/blenkernel/intern/curveprofile.cc @@ -760,6 +760,7 @@ static void create_samples(CurveProfile *profile, } BLI_assert(n_added == n_segments); /* n_added is just used for this assert, could remove it. */ + UNUSED_VARS_NDEBUG(n_added); /* Sample the points and add them to the locations table. */ for (int i_sample = 0, i = 0; i < totedges; i++) { diff --git a/source/blender/blenkernel/intern/customdata.cc b/source/blender/blenkernel/intern/customdata.cc index b9e6b1c5e6d..227c1ee1bee 100644 --- a/source/blender/blenkernel/intern/customdata.cc +++ b/source/blender/blenkernel/intern/customdata.cc @@ -5284,7 +5284,6 @@ const blender::CPPType *custom_data_type_to_cpp_type(const eCustomDataType type) default: return nullptr; } - return nullptr; } eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type) diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 5409bf61274..97e3ff43cd9 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -1566,7 +1566,6 @@ bGPDlayer *BKE_gpencil_layer_active_get(bGPdata *gpd) bGPDlayer *BKE_gpencil_layer_get_by_name(bGPdata *gpd, char *name, int first_if_not_found) { bGPDlayer *gpl; - int i = 0; /* error checking */ if (ELEM(NULL, gpd, gpd->layers.first)) { @@ -1578,7 +1577,6 @@ bGPDlayer *BKE_gpencil_layer_get_by_name(bGPdata *gpd, char *name, int first_if_ if (STREQ(name, gpl->info)) { return gpl; } - i++; } /* no such layer */ diff --git a/source/blender/blenkernel/intern/gpencil_curve.c b/source/blender/blenkernel/intern/gpencil_curve.c index a0a579e6d65..bf73b9d6ed6 100644 --- a/source/blender/blenkernel/intern/gpencil_curve.c +++ b/source/blender/blenkernel/intern/gpencil_curve.c @@ -971,7 +971,7 @@ static float *gpencil_stroke_points_from_editcurve_adaptive_resolu( MEM_freeN(segment_point_lengths); *r_points_len = points_len; - return (float(*))r_points; + return (float *)r_points; } /** @@ -1012,7 +1012,7 @@ static float *gpencil_stroke_points_from_editcurve_fixed_resolu(bGPDcurve_point } *r_points_len = points_len; - return (float(*))r_points; + return (float *)r_points; } void BKE_gpencil_stroke_update_geometry_from_editcurve(bGPDstroke *gps, diff --git a/source/blender/blenkernel/intern/layer.cc b/source/blender/blenkernel/intern/layer.cc index 40b80ddbd10..9e452662055 100644 --- a/source/blender/blenkernel/intern/layer.cc +++ b/source/blender/blenkernel/intern/layer.cc @@ -636,8 +636,6 @@ static bool layer_collection_hidden(ViewLayer *view_layer, LayerCollection *lc) } return false; - - return false; } LayerCollection *BKE_layer_collection_from_index(ViewLayer *view_layer, const int index) @@ -1210,6 +1208,7 @@ static void layer_collection_sync(ViewLayer *view_layer, layer_resync->layer->layer_collections = new_lb_layer; BLI_assert(BLI_listbase_count(&layer_resync->collection->children) - skipped_children == BLI_listbase_count(&new_lb_layer)); + UNUSED_VARS_NDEBUG(skipped_children); /* Update bases etc. for objects. */ layer_collection_objects_sync(view_layer, diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 090a3ce0d7e..1d416eec1e8 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -2629,8 +2629,6 @@ bool BKE_sculpt_attribute_exists(Object *ob, CustomData *cdata = sculpt_get_cdata(ob, domain); return CustomData_get_named_layer_index(cdata, proptype, name) != -1; - - return false; } static SculptAttribute *sculpt_alloc_attr(SculptSession *ss) diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c index 6bf3c4719f6..28b89a79fb0 100644 --- a/source/blender/blenlib/intern/scanfill_utils.c +++ b/source/blender/blenlib/intern/scanfill_utils.c @@ -361,7 +361,6 @@ bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx, { const uint poly_num = (uint)sf_ctx->poly_nr + 1; uint eed_index = 0; - int totvert_new = 0; bool changed = false; PolyInfo *poly_info; @@ -453,7 +452,6 @@ bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx, if (eve->user_flag != 1) { BLI_remlink(&sf_ctx->fillvertbase, eve); BLI_addtail(remvertbase, eve); - totvert_new--; } else { eve->user_flag = 0; diff --git a/source/blender/blenlib/tests/BLI_task_test.cc b/source/blender/blenlib/tests/BLI_task_test.cc index 63bb767466f..b7ee6962aec 100644 --- a/source/blender/blenlib/tests/BLI_task_test.cc +++ b/source/blender/blenlib/tests/BLI_task_test.cc @@ -196,11 +196,9 @@ TEST(task, MempoolIterTLS) int i; /* Add numbers negative `1..ITEMS_NUM` inclusive. */ - int items_num = 0; for (i = 0; i < ITEMS_NUM; i++) { data[i] = (int *)BLI_mempool_alloc(mempool); *data[i] = -(i + 1); - items_num++; } TaskParallelSettings settings; diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index f666c9f940d..f96fc734fbc 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -149,14 +149,12 @@ void BM_face_interp_from_face_ex(BMesh *bm, float *w = BLI_array_alloca(w, f_src->len); float co[2]; - int i; if (f_src != f_dst) { BM_elem_attrs_copy(bm, bm, f_src, f_dst); } /* interpolate */ - i = 0; l_iter = l_first = BM_FACE_FIRST_LOOP(f_dst); do { mul_v2_m3v3(co, axis_mat, l_iter->v->co); @@ -165,7 +163,7 @@ void BM_face_interp_from_face_ex(BMesh *bm, if (do_vertex) { CustomData_bmesh_interp(&bm->vdata, blocks_v, w, NULL, f_src->len, l_iter->v->head.data); } - } while ((void)i++, (l_iter = l_iter->next) != l_first); + } while ((l_iter = l_iter->next) != l_first); } void BM_face_interp_from_face(BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex) diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c index a6dd914a016..e15122a11e3 100644 --- a/source/blender/bmesh/tools/bmesh_intersect.c +++ b/source/blender/bmesh/tools/bmesh_intersect.c @@ -1342,10 +1342,9 @@ bool BM_mesh_intersect(BMesh *bm, GHASH_ITER (gh_iter, s.face_edges) { struct LinkBase *e_ls_base = BLI_ghashIterator_getValue(&gh_iter); LinkNode **node_prev_p; - uint i; node_prev_p = &e_ls_base->list; - for (i = 0, node = e_ls_base->list; node; i++, node = node->next) { + for (node = e_ls_base->list; node; node = node->next) { BMEdge *e = node->link; if (BM_elem_flag_test(e, BM_ELEM_TAG)) { /* allocated by arena, don't free */ diff --git a/source/blender/draw/engines/compositor/compositor_engine.cc b/source/blender/draw/engines/compositor/compositor_engine.cc index 6c2b0e2f3ff..64d483768c2 100644 --- a/source/blender/draw/engines/compositor/compositor_engine.cc +++ b/source/blender/draw/engines/compositor/compositor_engine.cc @@ -29,6 +29,8 @@ #include "GPU_texture.h" +#include "compositor_engine.h" /* Own include. */ + namespace blender::draw::compositor { class TexturePool : public realtime_compositor::TexturePool { diff --git a/source/blender/draw/engines/workbench/workbench_shader.cc b/source/blender/draw/engines/workbench/workbench_shader.cc index acfe5adf728..021c7df9d58 100644 --- a/source/blender/draw/engines/workbench/workbench_shader.cc +++ b/source/blender/draw/engines/workbench/workbench_shader.cc @@ -67,7 +67,6 @@ static const char *workbench_lighting_mode_to_str(int light) return "_matcap"; case V3D_LIGHTING_FLAT: return "_flat"; - return ""; } } diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index d2f0ee622c4..4a562f2b420 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -887,8 +887,7 @@ void ANIM_fmodifier_panels(const bContext *C, if (!panels_match) { UI_panels_free_instanced(C, region); - FModifier *fcm = fmodifiers->first; - for (int i = 0; fcm; i++, fcm = fcm->next) { + for (FModifier *fcm = fmodifiers->first; fcm; fcm = fcm->next) { char panel_idname[MAX_NAME]; panel_id_fn(fcm, panel_idname); diff --git a/source/blender/editors/interface/interface_layout.cc b/source/blender/editors/interface/interface_layout.cc index f4b96899545..04546639039 100644 --- a/source/blender/editors/interface/interface_layout.cc +++ b/source/blender/editors/interface/interface_layout.cc @@ -4197,11 +4197,9 @@ static void ui_litem_layout_column_flow(uiLayout *litem) /* compute max needed width and total height */ int toth = 0; - int totitem = 0; LISTBASE_FOREACH (uiItem *, item, &litem->items) { ui_item_size(item, &itemw, &itemh); toth += itemh; - totitem++; } /* compute sizes */ diff --git a/source/blender/editors/interface/interface_templates.cc b/source/blender/editors/interface/interface_templates.cc index 91c8911b97d..79ff2a32503 100644 --- a/source/blender/editors/interface/interface_templates.cc +++ b/source/blender/editors/interface/interface_templates.cc @@ -2291,8 +2291,7 @@ void uiTemplateModifiers(uiLayout * /*layout*/, bContext *C) if (!panels_match) { UI_panels_free_instanced(C, region); - ModifierData *md = static_cast(modifiers->first); - for (int i = 0; md; i++, md = md->next) { + for (ModifierData *md = static_cast(modifiers->first); md; md = md->next) { const ModifierTypeInfo *mti = BKE_modifier_get_info(ModifierType(md->type)); if (mti->panelRegister == nullptr) { continue; @@ -2451,9 +2450,10 @@ void uiTemplateConstraints(uiLayout * /*layout*/, bContext *C, bool use_bone_con if (!panels_match) { UI_panels_free_instanced(C, region); - bConstraint *con = (constraints == nullptr) ? nullptr : - static_cast(constraints->first); - for (int i = 0; con; i++, con = con->next) { + for (bConstraint *con = + (constraints == nullptr) ? nullptr : static_cast(constraints->first); + con; + con = con->next) { /* Don't show invalid/legacy constraints. */ if (con->type == CONSTRAINT_TYPE_NULL) { continue; @@ -2543,8 +2543,8 @@ void uiTemplateGpencilModifiers(uiLayout * /*layout*/, bContext *C) if (!panels_match) { UI_panels_free_instanced(C, region); - GpencilModifierData *md = static_cast(modifiers->first); - for (int i = 0; md; i++, md = md->next) { + for (GpencilModifierData *md = static_cast(modifiers->first); md; + md = md->next) { const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info( GpencilModifierType(md->type)); if (mti->panelRegister == nullptr) { @@ -2617,8 +2617,7 @@ void uiTemplateShaderFx(uiLayout * /*layout*/, bContext *C) if (!panels_match) { UI_panels_free_instanced(C, region); - ShaderFxData *fx = static_cast(shaderfx->first); - for (int i = 0; fx; i++, fx = fx->next) { + for (ShaderFxData *fx = static_cast(shaderfx->first); fx; fx = fx->next) { char panel_idname[MAX_NAME]; shaderfx_panel_id(fx, panel_idname); diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 2e7fbb0200d..533b2b43b16 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -291,6 +291,7 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm) BM_edge_loop_pair(e_last, &lp->l_a, &lp->l_b); BLI_assert(tot == uid_end - uid_start); + UNUSED_VARS_NDEBUG(tot); #if 0 printf("%s: found contiguous edge loop of (%d)\n", __func__, uid_end - uid_start); diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index af97b37acc1..305439724d0 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -983,13 +983,6 @@ static void region_azone_tab_plus(ScrArea *area, AZone *az, ARegion *region) const float tab_size_x = 0.7f * U.widget_unit; const float tab_size_y = 0.4f * U.widget_unit; - int tot = 0; - LISTBASE_FOREACH (AZone *, azt, &area->actionzones) { - if (azt->edge == az->edge) { - tot++; - } - } - switch (az->edge) { case AE_TOP_TO_BOTTOMRIGHT: { int add = (region->winrct.ymax == area->totrct.ymin) ? 1 : 0; diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index e012d7b6da4..a591c8308a4 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -347,7 +347,7 @@ static void snode_autoconnect(SpaceNode &snode, const bool allow_multiple, const return a->locx < b->locx; }); - int numlinks = 0; + // int numlinks = 0; /* UNUSED */ for (const int i : sorted_nodes.as_mutable_span().drop_back(1).index_range()) { bool has_selected_inputs = false; @@ -374,7 +374,7 @@ static void snode_autoconnect(SpaceNode &snode, const bool allow_multiple, const } if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) { - numlinks++; + // numlinks++; } } } @@ -398,7 +398,7 @@ static void snode_autoconnect(SpaceNode &snode, const bool allow_multiple, const } if (snode_autoconnect_input(snode, node_fr, sock_fr, node_to, sock_to, replace)) { - numlinks++; + // numlinks++; break; } } diff --git a/source/blender/editors/uvedit/uvedit_islands.cc b/source/blender/editors/uvedit/uvedit_islands.cc index 85ee80fe851..ed0e4933965 100644 --- a/source/blender/editors/uvedit/uvedit_islands.cc +++ b/source/blender/editors/uvedit/uvedit_islands.cc @@ -377,7 +377,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene, } } - struct SharedUVLoopData user_data = {0}; + struct SharedUVLoopData user_data = {{0}}; user_data.offsets = uv_offsets; user_data.use_seams = use_seams; diff --git a/source/blender/freestyle/intern/stroke/Operators.cpp b/source/blender/freestyle/intern/stroke/Operators.cpp index 93524e6ebe5..c55db18015b 100644 --- a/source/blender/freestyle/intern/stroke/Operators.cpp +++ b/source/blender/freestyle/intern/stroke/Operators.cpp @@ -875,13 +875,13 @@ static int __recursiveSplit(Chain *_curve, ++it; // real mean = 0.0f; // soc unused - real variance = 0.0f; - uint count = 0; + // uint count = 0; CurveInternal::CurvePointIterator next = it; ++next; bool bsplit = false; for (; ((it != end) && (next != end)); ++it, ++next) { - ++count; + // ++count; it0d = it.castToInterface0DIterator(); if (pred0d(it0d) < 0) { return -1; diff --git a/source/blender/geometry/intern/uv_parametrizer.cc b/source/blender/geometry/intern/uv_parametrizer.cc index 03accc5dd2e..cd97001bab6 100644 --- a/source/blender/geometry/intern/uv_parametrizer.cc +++ b/source/blender/geometry/intern/uv_parametrizer.cc @@ -1168,7 +1168,6 @@ static float p_edge_boundary_angle(PEdge *e) PEdge *we; PVert *v, *v1, *v2; float angle; - int n = 0; v = e->vert; @@ -1182,7 +1181,6 @@ static float p_edge_boundary_angle(PEdge *e) angle -= angle_v3v3v3(v1->co, v->co, v2->co); we = we->next->next->pair; - n++; } while (we && (we != v->edge)); return angle; diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index 695452f43ed..4361ec0f86d 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -4506,7 +4506,7 @@ LineartBoundingArea *MOD_lineart_get_bounding_area(LineartData *ld, double x, do static void lineart_add_triangles_worker(TaskPool *__restrict /*pool*/, LineartIsecThread *th) { LineartData *ld = th->ld; - int _dir_control = 0; + // int _dir_control = 0; /* UNUSED */ while (lineart_schedule_new_triangle_task(th)) { for (LineartElementLinkNode *eln = th->pending_from; eln != th->pending_to->next; eln = eln->next) { @@ -4522,7 +4522,7 @@ static void lineart_add_triangles_worker(TaskPool *__restrict /*pool*/, LineartI continue; } if (lineart_get_triangle_bounding_areas(ld, tri, &y1, &y2, &x1, &x2)) { - _dir_control++; + // _dir_control++; for (co = x1; co <= x2; co++) { for (r = y1; r <= y2; r++) { lineart_bounding_area_link_triangle(ld, diff --git a/source/blender/makesrna/intern/rna_path.cc b/source/blender/makesrna/intern/rna_path.cc index e3898bbd682..420c8907107 100644 --- a/source/blender/makesrna/intern/rna_path.cc +++ b/source/blender/makesrna/intern/rna_path.cc @@ -757,7 +757,6 @@ static char *rna_idp_path_create(IDP_Chain *child_link) char *path; bool is_first = true; - int tot = 0; IDP_Chain *link = child_link; /* reverse the list */ @@ -768,7 +767,6 @@ static char *rna_idp_path_create(IDP_Chain *child_link) link->up = link_prev; link_prev = link; link = link_next; - tot++; } for (link = link_prev; link; link = link->up) { diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c index 51043ea89e3..d364e92174e 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c @@ -1401,8 +1401,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, gs_ptr = orig_vert_groups_arr; for (uint i = 0; i < verts_num; i++, gs_ptr++) { if (*gs_ptr) { - EdgeGroup *g = *gs_ptr; - for (uint j = 0; g->valid; j++, g++) { + for (EdgeGroup *g = *gs_ptr; g->valid; g++) { if (!g->is_singularity) { float *nor = g->no; /* During vertex position calculation, the algorithm decides if it wants to disable the @@ -2003,8 +2002,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, for (uint i = 0; i < verts_num; i++, gs_ptr++) { EdgeGroup *gs = *gs_ptr; if (gs) { - EdgeGroup *g = gs; - for (uint j = 0; g->valid; j++, g++) { + for (EdgeGroup *g = gs; g->valid; g++) { if (g->new_vert != MOD_SOLIDIFY_EMPTY_TAG) { CustomData_copy_data(&mesh->vdata, &result->vdata, (int)i, (int)g->new_vert, 1); copy_v3_v3(vert_positions[g->new_vert], g->co); diff --git a/source/blender/render/intern/pipeline.cc b/source/blender/render/intern/pipeline.cc index 5cd151189da..fe527bc9bc8 100644 --- a/source/blender/render/intern/pipeline.cc +++ b/source/blender/render/intern/pipeline.cc @@ -2520,7 +2520,6 @@ bool RE_layers_have_name(struct RenderResult *result) default: return true; } - return false; } bool RE_passes_have_name(struct RenderLayer *rl) diff --git a/source/blender/render/intern/render_result.cc b/source/blender/render/intern/render_result.cc index 1cd95831ddf..62b1ab158b1 100644 --- a/source/blender/render/intern/render_result.cc +++ b/source/blender/render/intern/render_result.cc @@ -767,7 +767,6 @@ void render_result_single_layer_end(Render *re) BLI_remlink(&re->result->layers, rl); /* reconstruct render result layers */ - int nr = 0; LISTBASE_FOREACH (ViewLayer *, view_layer, &re->scene->view_layers) { if (STREQ(view_layer->name, re->single_view_layer)) { BLI_addtail(&re->result->layers, rl); @@ -779,7 +778,6 @@ void render_result_single_layer_end(Render *re) BLI_addtail(&re->result->layers, rlpush); } } - nr++; } } From cac6b6f388812cb3f0d0e2515fa4ac7f13335903 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 19 Jan 2023 08:18:27 +0100 Subject: [PATCH 0760/1522] BGL_Wrap: disable calls on non-opengl backends. Goal of this patch is to stop the invocation of OpenGL calls via the bgl module on a none OpenGL GPU backend, report this as a python deprecation warning and report this to the user. ## Deprecation warning to developers ``` >>> import bgl >>> bgl.glUseProgram(0) :1: DeprecationWarning: 'bgl.glUseProgram' is deprecated and will be removed in Blender 3.7. Report or update your script to use 'gpu' module. ``` ## Deprecation message to users The message to the user is shown as part of the Info Space and as a message box. {F14159203 width=100%} {F14158674 width=100%} During implementation we tried several ideas: # Use python warning as errors: This isn't fine grained enough and can show incorrect information to the user. # Throw deprecation as error and use sys.excepthook to report the user message. This required a custom exception class to identify the bgl deprecation and a CPython handler function to be set during python initialization. Although this is the most flexible there was a disconnect between the exception class, exception function and the excepthook registration. # A variant how we handle autoexec failures. A flag is stored in Global and when set the user message is reported. Not that flexible, but code is more connected to the boolean stored in the Global struct. Although using Global struct isn't nice I chose this solution due to its traceability. It is clear to developers reading the code how the mechanism works by using search all functionality of your IDE. Reviewed By: MichaelPW, campbellbarton Maniphest Tasks: T103863 Differential Revision: https://developer.blender.org/D16996 --- source/blender/blenkernel/BKE_global.h | 7 ++ source/blender/python/generic/CMakeLists.txt | 1 + source/blender/python/generic/bgl.c | 66 +++++++++++++++++- .../windowmanager/intern/wm_event_system.cc | 3 + .../blender/windowmanager/intern/wm_window.c | 69 +++++++++++++++++++ .../windowmanager/intern/wm_window_private.h | 12 ++++ 6 files changed, 155 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h index f3acb7d3746..23cbd73cf36 100644 --- a/source/blender/blenkernel/BKE_global.h +++ b/source/blender/blenkernel/BKE_global.h @@ -139,6 +139,13 @@ typedef struct Global { * Typically Python drivers. */ char autoexec_fail[200]; + + /** + * Has there been an opengl deprecation call detected when running on a none OpenGL backend. + */ + bool opengl_deprecation_usage_detected; + const char *opengl_deprecation_usage_filename; + int opengl_deprecation_usage_lineno; } Global; /* **************** GLOBAL ********************* */ diff --git a/source/blender/python/generic/CMakeLists.txt b/source/blender/python/generic/CMakeLists.txt index 27b7ad28943..96345a2fa34 100644 --- a/source/blender/python/generic/CMakeLists.txt +++ b/source/blender/python/generic/CMakeLists.txt @@ -8,6 +8,7 @@ set(INC ../../makesdna ../../makesrna ../../../../intern/guardedalloc + ../../../../intern/clog ) set(INC_SYS diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c index fe64b247d43..c77dabfb539 100644 --- a/source/blender/python/generic/bgl.c +++ b/source/blender/python/generic/bgl.c @@ -12,17 +12,55 @@ #include +#include "BLI_string.h" #include "BLI_utildefines.h" + #include "MEM_guardedalloc.h" +#include "GPU_context.h" #include "GPU_state.h" +#include "py_capi_utils.h" + +#include "BKE_global.h" + #include "../generic/py_capi_utils.h" #include #include "bgl.h" +#include "CLG_log.h" + +static CLG_LogRef LOG = {"bgl"}; + +/* -------------------------------------------------------------------- */ +/** \name Local utility defines for wrapping OpenGL + * \{ */ + +static void report_deprecated_call(const char *function_name) +{ + char message[256]; + SNPRINTF(message, + "'bgl.gl%s' is deprecated and will be removed in Blender 3.7. Report or update your " + "script to use 'gpu' module.", + function_name); + CLOG_WARN(&LOG, "%s", message); + PyErr_WarnEx(PyExc_DeprecationWarning, message, 1); +} + +static void report_deprecated_call_to_user(void) +{ + /* Only report the first deprecated usage. */ + if (G.opengl_deprecation_usage_detected) { + return; + } + G.opengl_deprecation_usage_detected = true; + PyC_FileAndNum(&G.opengl_deprecation_usage_filename, &G.opengl_deprecation_usage_lineno); +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Local utility defines for wrapping OpenGL * \{ */ @@ -366,14 +404,17 @@ typedef struct BufferOrOffset { #define ret_def_void #define ret_set_void +#define ret_default_void #define ret_ret_void return Py_INCREF(Py_None), Py_None #define ret_def_GLint int ret_int #define ret_set_GLint ret_int = +#define ret_default_GLint -1 #define ret_ret_GLint return PyLong_FromLong(ret_int) #define ret_def_GLuint uint ret_uint #define ret_set_GLuint ret_uint = +#define ret_default_GLuint 0 #define ret_ret_GLuint return PyLong_FromLong((long)ret_uint) #if 0 @@ -390,14 +431,19 @@ typedef struct BufferOrOffset { #define ret_def_GLenum uint ret_uint #define ret_set_GLenum ret_uint = +#define ret_default_GLenum 0 #define ret_ret_GLenum return PyLong_FromLong((long)ret_uint) #define ret_def_GLboolean uchar ret_bool #define ret_set_GLboolean ret_bool = +#define ret_default_GLboolean GL_FALSE #define ret_ret_GLboolean return PyLong_FromLong((long)ret_bool) -#define ret_def_GLstring const uchar *ret_str +#define ret_def_GLstring \ + const char *default_GLstring = ""; \ + const uchar *ret_str #define ret_set_GLstring ret_str = +#define ret_default_GLstring (const uchar *)default_GLstring #define ret_ret_GLstring \ if (ret_str) { \ @@ -1071,11 +1117,19 @@ static PyObject *Buffer_repr(Buffer *self) { \ arg_def arg_list; \ ret_def_##ret; \ + report_deprecated_call(#funcname); \ if (!PyArg_ParseTuple(args, arg_str arg_list, arg_ref arg_list)) { \ return NULL; \ } \ - GPU_bgl_start(); \ - ret_set_##ret gl##funcname(arg_var arg_list); \ + const bool has_opengl_backend = GPU_backend_get_type() == GPU_BACKEND_OPENGL; \ + if (has_opengl_backend) { \ + GPU_bgl_start(); \ + ret_set_##ret gl##funcname(arg_var arg_list); \ + } \ + else { \ + report_deprecated_call_to_user(); \ + ret_set_##ret ret_default_##ret; \ + } \ ret_ret_##ret; \ } #else @@ -2589,6 +2643,12 @@ PyObject *BPyInit_bgl(void) return NULL; /* should never happen */ } + if (GPU_backend_get_type() != GPU_BACKEND_OPENGL) { + CLOG_ERROR(&LOG, + "'bgl' imported without an OpenGL backend. Please update your add-ons to use the " + "'gpu' module. In Blender 3.7 'bgl' will be removed."); + } + PyModule_AddObject(submodule, "Buffer", (PyObject *)&BGL_bufferType); Py_INCREF((PyObject *)&BGL_bufferType); diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index 05fe351c385..9004bfc0e4b 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -77,6 +77,7 @@ #include "wm_event_types.h" #include "wm_surface.h" #include "wm_window.h" +#include "wm_window_private.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" @@ -704,6 +705,8 @@ void wm_event_do_notifiers(bContext *C) /* Auto-run warning. */ wm_test_autorun_warning(C); + /* Deprecation warning. */ + wm_test_opengl_deprecation_warning(C); GPU_render_end(); } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 74907917193..a73b9f6f51c 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1646,6 +1646,75 @@ GHOST_TDrawingContextType wm_ghost_drawing_context_type(const eGPUBackendType gp return GHOST_kDrawingContextTypeNone; } +static uiBlock *block_create_opengl_usage_warning(struct bContext *C, + struct ARegion *region, + void *UNUSED(arg1)) +{ + uiBlock *block = UI_block_begin(C, region, "autorun_warning_popup", UI_EMBOSS); + UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP); + UI_block_emboss_set(block, UI_EMBOSS); + + uiLayout *layout = uiItemsAlertBox(block, 44, ALERT_ICON_ERROR); + + /* Title and explanation text. */ + uiLayout *col = uiLayoutColumn(layout, false); + uiItemL_ex(col, TIP_("Python script uses OpenGL for drawing."), ICON_NONE, true, false); + uiItemL(col, TIP_("This may lead to unexpected behavior"), ICON_NONE); + uiItemL(col, + TIP_("One of the add-ons or scripts is using OpenGL and will not work correct on Metal."), + ICON_NONE); + uiItemL(col, + TIP_("Please contact the developer of the add-on to migrate to use 'gpu' module."), + ICON_NONE); + if (G.opengl_deprecation_usage_filename) { + char location[1024]; + SNPRINTF( + location, "%s:%d", G.opengl_deprecation_usage_filename, G.opengl_deprecation_usage_lineno); + uiItemL(col, location, ICON_NONE); + } + uiItemL(col, TIP_("See system tab in preferences to switch to OpenGL backend."), ICON_NONE); + + uiItemS(layout); + + UI_block_bounds_set_centered(block, 14 * U.dpi_fac); + + return block; +} + +void wm_test_opengl_deprecation_warning(bContext *C) +{ + static bool message_shown = false; + + /* Exit when no failure detected. */ + if (!G.opengl_deprecation_usage_detected) { + return; + } + + /* Have we already shown a message during this Blender session. bgl calls are done in a draw + * handler that will run many times. */ + if (message_shown) { + return; + } + + wmWindowManager *wm = CTX_wm_manager(C); + wmWindow *win = (wm->winactive) ? wm->winactive : wm->windows.first; + + BKE_report( + &wm->reports, + RPT_ERROR, + TIP_("One of the add-ons or script is using OpenGL and will not work correct on Metal. " + "Please contact the developer of the add-on to migrate to use 'gpu' module.")); + + if (win) { + wmWindow *prevwin = CTX_wm_window(C); + CTX_wm_window_set(C, win); + UI_popup_block_invoke(C, block_create_opengl_usage_warning, NULL, NULL); + CTX_wm_window_set(C, prevwin); + } + + message_shown = true; +} + eWM_CapabilitiesFlag WM_capabilities_flag(void) { static eWM_CapabilitiesFlag flag = -1; diff --git a/source/blender/windowmanager/intern/wm_window_private.h b/source/blender/windowmanager/intern/wm_window_private.h index dad3e749817..d855f2b6007 100644 --- a/source/blender/windowmanager/intern/wm_window_private.h +++ b/source/blender/windowmanager/intern/wm_window_private.h @@ -12,6 +12,12 @@ #include "GPU_context.h" +#ifdef __cplusplus +extern "C" { +#endif + +struct bContext; + /* *************** Message box *************** */ /* `WM_ghost_show_message_box` is implemented in `wm_windows.c` it is * defined here as it was implemented to be used for showing @@ -26,3 +32,9 @@ void WM_ghost_show_message_box(const char *title, GHOST_DialogOptions dialog_options); GHOST_TDrawingContextType wm_ghost_drawing_context_type(const eGPUBackendType gpu_backend); + +void wm_test_opengl_deprecation_warning(struct bContext *C); + +#ifdef __cplusplus +} +#endif From 41b33f89689b78dbffd230d7884dab8a3da5ea0b Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 19 Jan 2023 08:23:05 +0100 Subject: [PATCH 0761/1522] Fix spelling mistake in previous commit. --- source/blender/windowmanager/intern/wm_window.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index a73b9f6f51c..0077c8e2259 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1660,9 +1660,10 @@ static uiBlock *block_create_opengl_usage_warning(struct bContext *C, uiLayout *col = uiLayoutColumn(layout, false); uiItemL_ex(col, TIP_("Python script uses OpenGL for drawing."), ICON_NONE, true, false); uiItemL(col, TIP_("This may lead to unexpected behavior"), ICON_NONE); - uiItemL(col, - TIP_("One of the add-ons or scripts is using OpenGL and will not work correct on Metal."), - ICON_NONE); + uiItemL( + col, + TIP_("One of the add-ons or scripts is using OpenGL and will not work correct on Metal."), + ICON_NONE); uiItemL(col, TIP_("Please contact the developer of the add-on to migrate to use 'gpu' module."), ICON_NONE); @@ -1702,7 +1703,7 @@ void wm_test_opengl_deprecation_warning(bContext *C) BKE_report( &wm->reports, RPT_ERROR, - TIP_("One of the add-ons or script is using OpenGL and will not work correct on Metal. " + TIP_("One of the add-ons or scripts is using OpenGL and will not work correct on Metal. " "Please contact the developer of the add-on to migrate to use 'gpu' module.")); if (win) { From 3f627c38a2bc4aff0cd44155ee043bd09ba5f283 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 19 Jan 2023 08:25:28 +0100 Subject: [PATCH 0762/1522] Fix test cases by reducing the severity of the bgl error message to warning. --- source/blender/python/generic/bgl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/python/generic/bgl.c b/source/blender/python/generic/bgl.c index c77dabfb539..f62f427542d 100644 --- a/source/blender/python/generic/bgl.c +++ b/source/blender/python/generic/bgl.c @@ -2644,9 +2644,9 @@ PyObject *BPyInit_bgl(void) } if (GPU_backend_get_type() != GPU_BACKEND_OPENGL) { - CLOG_ERROR(&LOG, - "'bgl' imported without an OpenGL backend. Please update your add-ons to use the " - "'gpu' module. In Blender 3.7 'bgl' will be removed."); + CLOG_WARN(&LOG, + "'bgl' imported without an OpenGL backend. Please update your add-ons to use the " + "'gpu' module. In Blender 3.7 'bgl' will be removed."); } PyModule_AddObject(submodule, "Buffer", (PyObject *)&BGL_bufferType); From 93d84e87b26c85f814f4a2537e73387628491b68 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Thu, 5 Jan 2023 16:05:51 +0100 Subject: [PATCH 0763/1522] Fix T103400: Transfer Mesh Data Layout broken for color attributes This was the case when using the operator outside of the modifiers panel. Caused by {rBeae36be372a6}. In above commit, `DT_layer_items` shared both `DT_TYPE_MPROPCOL_LOOP` | `DT_TYPE_MLOOPCOL_LOOP` in a single EnumPropertyItem value "Colors". This is a bit unusual, but probably allowed. As a consequence, checks for specific datatypes would fail when selecting such EnumPropertyItem: - `DT_DATATYPE_IS_MULTILAYERS` (uses `ELEM` to check distinct entries -- would return false) - `BKE_object_data_transfer_dttype_to_srcdst_index` (would return `DT_MULTILAYER_INDEX_INVALID`) These places have now been corrected to take these "special" values into account. Another issue was that multiple EnumPropertyItems with the same value could be created in dt_add_vcol_layers() if attributes of the same domain, but different color types are in play (could lead to crashes) and that has also been corrected. Also: above commit did not give the choice of transfering color attributes from the vertex domain (only face corner attributes could be chosen), this has now been added. DT_layer_vert_items (used from the modifier) already had this included so this was only an issue when using the operator outside of the modifiers panel. Since we now feature two domains, the single "VCOL" in the enum has been split into "COLOR_VERTEX" and "COLOR_CORNER". This will break existing scripts calling bpy.ops.object.datalayout_transfer and will be marked as a breaking change in the release notes. NOTE: there is another bug here when attributes of the same domain, but different color types are in play and you want to transfer just a single specific layer (but that is for a separate commit) Maniphest Tasks: T103400 Differential Revision: https://developer.blender.org/D16935 --- source/blender/blenkernel/BKE_data_transfer.h | 2 ++ .../blender/blenkernel/intern/data_transfer.cc | 2 ++ .../editors/object/object_data_transfer.c | 18 +++++++++++++----- source/blender/makesrna/intern/rna_modifier.c | 4 ++-- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/BKE_data_transfer.h b/source/blender/blenkernel/BKE_data_transfer.h index 1b6c1dc4205..518b5146b18 100644 --- a/source/blender/blenkernel/BKE_data_transfer.h +++ b/source/blender/blenkernel/BKE_data_transfer.h @@ -92,8 +92,10 @@ int BKE_object_data_transfer_dttype_to_srcdst_index(int dtdata_type); DT_TYPE_SHAPEKEY, \ DT_TYPE_MPROPCOL_VERT, \ DT_TYPE_MLOOPCOL_VERT, \ + DT_TYPE_MPROPCOL_VERT | DT_TYPE_MLOOPCOL_VERT, \ DT_TYPE_MPROPCOL_LOOP, \ DT_TYPE_MLOOPCOL_LOOP, \ + DT_TYPE_MPROPCOL_LOOP | DT_TYPE_MLOOPCOL_LOOP, \ DT_TYPE_UV) enum { diff --git a/source/blender/blenkernel/intern/data_transfer.cc b/source/blender/blenkernel/intern/data_transfer.cc index 39d6cde31e7..740af7fa4db 100644 --- a/source/blender/blenkernel/intern/data_transfer.cc +++ b/source/blender/blenkernel/intern/data_transfer.cc @@ -237,9 +237,11 @@ int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type) return DT_MULTILAYER_INDEX_UV; case DT_TYPE_MPROPCOL_VERT: case DT_TYPE_MLOOPCOL_VERT: + case DT_TYPE_MPROPCOL_VERT | DT_TYPE_MLOOPCOL_VERT: return DT_MULTILAYER_INDEX_VCOL_VERT; case DT_TYPE_MPROPCOL_LOOP: case DT_TYPE_MLOOPCOL_LOOP: + case DT_TYPE_MPROPCOL_LOOP | DT_TYPE_MLOOPCOL_LOOP: return DT_MULTILAYER_INDEX_VCOL_LOOP; default: return DT_MULTILAYER_INDEX_INVALID; diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c index 5f1af79c446..b5bea5b49f6 100644 --- a/source/blender/editors/object/object_data_transfer.c +++ b/source/blender/editors/object/object_data_transfer.c @@ -60,6 +60,11 @@ static const EnumPropertyItem DT_layer_items[] = { {DT_TYPE_SKIN, "SKIN", 0, "Skin Weight", "Transfer skin weights"}, #endif {DT_TYPE_BWEIGHT_VERT, "BEVEL_WEIGHT_VERT", 0, "Bevel Weight", "Transfer bevel weights"}, + {DT_TYPE_MPROPCOL_VERT | DT_TYPE_MLOOPCOL_VERT, + "COLOR_VERTEX", + 0, + "Colors", + "Color Attributes"}, RNA_ENUM_ITEM_HEADING(N_("Edge Data"), NULL), {DT_TYPE_SHARP_EDGE, "SHARP_EDGE", 0, "Sharp", "Transfer sharp mark"}, @@ -74,7 +79,11 @@ static const EnumPropertyItem DT_layer_items[] = { RNA_ENUM_ITEM_HEADING(N_("Face Corner Data"), NULL), {DT_TYPE_LNOR, "CUSTOM_NORMAL", 0, "Custom Normals", "Transfer custom normals"}, - {DT_TYPE_MPROPCOL_LOOP | DT_TYPE_MLOOPCOL_LOOP, "VCOL", 0, "Colors", "Color Attributes"}, + {DT_TYPE_MPROPCOL_LOOP | DT_TYPE_MLOOPCOL_LOOP, + "COLOR_CORNER", + 0, + "Colors", + "Color Attributes"}, {DT_TYPE_UV, "UV", 0, "UVs", "Transfer UV layers"}, RNA_ENUM_ITEM_HEADING(N_("Face Data"), NULL), @@ -93,7 +102,7 @@ static void dt_add_vcol_layers(CustomData *cdata, int *r_totitem) { int types[2] = {CD_PROP_COLOR, CD_PROP_BYTE_COLOR}; - + int idx = 0; for (int i = 0; i < 2; i++) { eCustomDataType type = types[i]; @@ -106,9 +115,8 @@ static void dt_add_vcol_layers(CustomData *cdata, RNA_enum_item_add_separator(r_item, r_totitem); for (int j = 0; j < num_data; j++) { - EnumPropertyItem tmp_item; - - tmp_item.value = j; + EnumPropertyItem tmp_item = {0}; + tmp_item.value = idx++; tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(cdata, type, j); RNA_enum_item_add(r_item, r_totitem, &tmp_item); } diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 090ef1e5e28..0639ad29db4 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -6391,7 +6391,7 @@ static void rna_def_modifier_datatransfer(BlenderRNA *brna) # endif {DT_TYPE_BWEIGHT_VERT, "BEVEL_WEIGHT_VERT", 0, "Bevel Weight", "Transfer bevel weights"}, {DT_TYPE_MPROPCOL_VERT | DT_TYPE_MLOOPCOL_VERT, - "VCOL", + "COLOR_VERTEX", 0, "Colors", "Transfer color attributes"}, @@ -6410,7 +6410,7 @@ static void rna_def_modifier_datatransfer(BlenderRNA *brna) static const EnumPropertyItem DT_layer_loop_items[] = { {DT_TYPE_LNOR, "CUSTOM_NORMAL", 0, "Custom Normals", "Transfer custom normals"}, {DT_TYPE_MPROPCOL_LOOP | DT_TYPE_MLOOPCOL_LOOP, - "VCOL", + "COLOR_CORNER", 0, "Colors", "Transfer color attributes"}, From 71b5799852c0f57ce4c52052d469fc6c7b58ddcf Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 19 Jan 2023 09:46:45 +0100 Subject: [PATCH 0764/1522] Code-style: Remove double semicolons at end of statement. --- source/blender/python/gpu/gpu_py_shader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c index 87f09098d46..9352e7cc9b1 100644 --- a/source/blender/python/gpu/gpu_py_shader.c +++ b/source/blender/python/gpu/gpu_py_shader.c @@ -625,7 +625,7 @@ static PyObject *pygpu_shader_attrs_info_get(BPyGPUShader *self, PyObject *UNUSE { uint attr_len = GPU_shader_get_attribute_len(self->shader); int location_test = 0, attrs_added = 0; - ; + PyObject *ret = PyTuple_New(attr_len); while (attrs_added < attr_len) { char name[256]; From 2907227db2c91a55d9b55f5d06e82f0547200bb9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 19 Jan 2023 20:33:44 +1100 Subject: [PATCH 0765/1522] Fix T103880: Crash with Line Art Grease-Pencil modifier The line art modifier added a wmNotifier in it's GpencilModifierTypeInfo.generateStrokes callback which isn't thread-safe when called from the depsgraph. This was from the original inclusion of the feature [0] however a more recent optimization to notifier lookups [1] made the crash occur more frequently. Remove the notifier as modifiers should not be adding WM level events and it works without it. [0]: 3e87d8a4315d794efff659e40f0bb9e34e2aec8a [1]: 0aaff9a07d3bdf8588cef15d502aeb4fdab22e5e --- source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c index b33a6970d1f..88c7ab9d96c 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c @@ -44,9 +44,6 @@ #include "MOD_gpencil_ui_common.h" #include "lineart/MOD_lineart.h" -#include "WM_api.h" -#include "WM_types.h" - static void initData(GpencilModifierData *md) { LineartGpencilModifierData *gpmd = (LineartGpencilModifierData *)md; @@ -168,8 +165,6 @@ static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Objec * cache. */ lmd->cache = gpd->runtime.lineart_cache; } - - WM_main_add_notifier(NA_EDITED | NC_GPENCIL, NULL); } static void bakeModifier(Main *UNUSED(bmain), From eb657633ed85ba6eca16617ac579baf21a6824d5 Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Thu, 19 Jan 2023 11:22:16 +0100 Subject: [PATCH 0766/1522] Fix anisotropic Beckmann using isotropic sampling --- intern/cycles/kernel/closure/bsdf_microfacet.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 90ae42dd7a6..ed438b1f483 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -1006,7 +1006,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, float3 local_m; float G1i; - local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_x, randu, randv, true, &G1i); + local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_y, randu, randv, true, &G1i); float3 m = X * local_m.x + Y * local_m.y + Z * local_m.z; float cosThetaM = local_m.z; From a3c38667f0f8195ed560b32db5630ccaceb42d54 Mon Sep 17 00:00:00 2001 From: Pratik Borhade Date: Thu, 19 Jan 2023 16:04:15 +0530 Subject: [PATCH 0767/1522] Fix T103881: Unlink operation crash in Blender File view Similar to rBe97443478e32 and rBe772087ed664, exit early when texture, collection and world ID has no parent to unlink from. Reviewed by: Severin, lichtwerk Differential Revision: https://developer.blender.org/D17017 --- .../editors/space_outliner/outliner_tools.cc | 42 +++++++++++++++++-- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc index 01579eb0499..35373c510e3 100644 --- a/source/blender/editors/space_outliner/outliner_tools.cc +++ b/source/blender/editors/space_outliner/outliner_tools.cc @@ -329,13 +329,24 @@ static void unlink_material_fn(bContext * /*C*/, } static void unlink_texture_fn(bContext * /*C*/, - ReportList * /*reports*/, + ReportList *reports, Scene * /*scene*/, TreeElement *te, TreeStoreElem *tsep, - TreeStoreElem * /*tselem*/, + TreeStoreElem *tselem, void * /*user_data*/) { + if (!tsep || !TSE_IS_REAL_ID(tsep)) { + /* Valid case, no parent element of the texture or it is not an ID (could be a #TSE_ID_BASE + * for example) so there's no data to unlink from. */ + BKE_reportf(reports, + RPT_WARNING, + "Cannot unlink texture '%s'. It's not clear which freestyle line style it should " + "be unlinked from, there's no freestyle line style as parent in the Outliner tree", + tselem->id->name + 2); + return; + } + MTex **mtex = nullptr; int a; @@ -358,7 +369,7 @@ static void unlink_texture_fn(bContext * /*C*/, } static void unlink_collection_fn(bContext *C, - ReportList * /*reports*/, + ReportList *reports, Scene * /*scene*/, TreeElement * /*te*/, TreeStoreElem *tsep, @@ -368,6 +379,18 @@ static void unlink_collection_fn(bContext *C, Main *bmain = CTX_data_main(C); Collection *collection = (Collection *)tselem->id; + if (!tsep || !TSE_IS_REAL_ID(tsep)) { + /* Valid case, no parent element of the collection or it is not an ID (could be a #TSE_ID_BASE + * for example) so there's no data to unlink from. */ + BKE_reportf(reports, + RPT_WARNING, + "Cannot unlink collection '%s'. It's not clear which scene, collection or " + "instance empties it should be unlinked from, there's no scene, collection or " + "instance empties as parent in the Outliner tree", + tselem->id->name + 2); + return; + } + if (tsep) { if (GS(tsep->id->name) == ID_OB) { Object *ob = (Object *)tsep->id; @@ -449,13 +472,24 @@ static void unlink_object_fn(bContext *C, } static void unlink_world_fn(bContext * /*C*/, - ReportList * /*reports*/, + ReportList *reports, Scene * /*scene*/, TreeElement * /*te*/, TreeStoreElem *tsep, TreeStoreElem *tselem, void * /*user_data*/) { + if (!tsep || !TSE_IS_REAL_ID(tsep)) { + /* Valid case, no parent element of the world or it is not an ID (could be a #TSE_ID_BASE + * for example) so there's no data to unlink from. */ + BKE_reportf(reports, + RPT_WARNING, + "Cannot unlink world '%s'. It's not clear which scene it should be unlinked from, " + "there's no scene as parent in the Outliner tree", + tselem->id->name + 2); + return; + } + Scene *parscene = (Scene *)tsep->id; World *wo = (World *)tselem->id; From 320757bc6111bf7c652068368b92312c994838f8 Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Thu, 19 Jan 2023 12:06:14 +0100 Subject: [PATCH 0768/1522] Refactor microfacet BSDF to reduce repetition --- .../cycles/kernel/closure/bsdf_microfacet.h | 1001 +++++------------ intern/cycles/kernel/integrator/mnee.h | 8 +- 2 files changed, 293 insertions(+), 716 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index ed438b1f483..377cf836fb8 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -43,17 +43,18 @@ ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals kg, ccl_private float *slope_y, ccl_private float *G1i) { - /* special case (normal incidence) */ + /* Special case (normal incidence). */ if (cos_theta_i >= 0.99999f) { const float r = sqrtf(-logf(randu)); const float phi = M_2PI_F * randv; *slope_x = r * cosf(phi); *slope_y = r * sinf(phi); *G1i = 1.0f; + return; } - /* precomputations */ + /* Precomputations. */ const float tan_theta_i = sin_theta_i / cos_theta_i; const float inv_a = tan_theta_i; const float cot_theta_i = 1.0f / tan_theta_i; @@ -129,7 +130,7 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, ccl_private float *slope_y, ccl_private float *G1i) { - /* special case (normal incidence) */ + /* Special case (normal incidence). */ if (cos_theta_i >= 0.99999f) { const float r = sqrtf(randu / (1.0f - randu)); const float phi = M_2PI_F * randv; @@ -140,13 +141,13 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, return; } - /* precomputations */ + /* Precomputations. */ const float tan_theta_i = sin_theta_i / cos_theta_i; const float G1_inv = 0.5f * (1.0f + safe_sqrtf(1.0f + tan_theta_i * tan_theta_i)); *G1i = 1.0f / G1_inv; - /* sample slope_x */ + /* Sample slope_x. */ const float A = 2.0f * randu * G1_inv - 1.0f; const float AA = A * A; const float tmp = 1.0f / (AA - 1.0f); @@ -157,7 +158,7 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, const float slope_x_2 = B * tmp + D; *slope_x = (A < 0.0f || slope_x_2 * tan_theta_i > 1.0f) ? slope_x_1 : slope_x_2; - /* sample slope_y */ + /* Sample slope_y. */ float S; if (randv > 0.5f) { @@ -187,7 +188,7 @@ ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, float3 wi_ = make_float3(alpha_x * wi.x, alpha_y * wi.y, wi.z); wi_ = normalize(wi_); - /* get polar coordinates of wi_ */ + /* Compute polar coordinates of wi_. */ float costheta_ = 1.0f; float sintheta_ = 0.0f; float cosphi_ = 1.0f; @@ -238,26 +239,85 @@ ccl_device_forceinline Spectrum reflection_color(ccl_private const MicrofacetBsd float3 H) { Spectrum F = one_spectrum(); - bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID || - bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID); + + bool use_clearcoat = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID; + bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID || use_clearcoat); + if (use_fresnel) { float F0 = fresnel_dielectric_cos(1.0f, bsdf->ior); F = interpolate_fresnel_color(L, H, bsdf->ior, F0, bsdf->extra->cspec0); } + if (use_clearcoat) { + F *= 0.25f * bsdf->extra->clearcoat; + } + return F; } -ccl_device_forceinline float D_GTR1(float NdotH, float alpha) +/* Generalized Trowbridge-Reitz for clearcoat. */ +ccl_device_forceinline float bsdf_clearcoat_D(float alpha2, float cos_NH) { - if (alpha >= 1.0f) + if (alpha2 >= 1.0f) { return M_1_PI_F; - float alpha2 = alpha * alpha; - float t = 1.0f + (alpha2 - 1.0f) * NdotH * NdotH; + } + + const float t = 1.0f + (alpha2 - 1.0f) * cos_NH * cos_NH; return (alpha2 - 1.0f) / (M_PI_F * logf(alpha2) * t); } +/* Monodirectional shadowing-masking term. */ +template ccl_device_inline float bsdf_G1_from_sqr_alpha_tan_n(float sqr_alpha_tan_n) +{ + if (!beckmann) { /* GGX. */ + return 2.0f / (1.0f + sqrtf(1.0f + sqr_alpha_tan_n)); + } + + const float a = inversesqrtf(sqr_alpha_tan_n); + return (a > 1.6f) ? 1.0f : ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f); +} + +template ccl_device_inline float bsdf_G1(float alpha2, float cos_N) +{ + return bsdf_G1_from_sqr_alpha_tan_n(alpha2 * + fmaxf(1.0f / (cos_N * cos_N) - 1.0f, 0.0f)); +} + +template +ccl_device_inline float bsdf_aniso_G1(float alpha_x, float alpha_y, float3 V) +{ + return bsdf_G1_from_sqr_alpha_tan_n((sqr(alpha_x * V.x) + sqr(alpha_y * V.y)) / + sqr(V.z)); +} + +/* Smith's separable shadowing-masking term. */ +template ccl_device_inline float bsdf_G(float alpha2, float cos_NI, float cos_NO) +{ + return bsdf_G1(alpha2, cos_NI) * bsdf_G1(alpha2, cos_NO); +} + +/* Normal distribution function. */ +template ccl_device_inline float bsdf_D(float alpha2, float cos_NH) +{ + const float cos_NH2 = sqr(cos_NH); + + return beckmann ? expf((1.0f - 1.0f / cos_NH2) / alpha2) / (M_PI_F * alpha2 * sqr(cos_NH2)) : + alpha2 / (M_PI_F * sqr(1.0f + (alpha2 - 1.0f) * cos_NH2)); +} + +template +ccl_device_inline float bsdf_aniso_D(float alpha_x, float alpha_y, float3 H) +{ + H /= make_float3(alpha_x, alpha_y, 1.0f); + + const float cos_NH2 = sqr(H.z); + const float alpha2 = alpha_x * alpha_y; + + return beckmann ? expf(-(sqr(H.x) + sqr(H.y)) / cos_NH2) / (M_PI_F * alpha2 * sqr(cos_NH2)) : + M_1_PI_F / (alpha2 * sqr(len_squared(H))); +} + ccl_device_forceinline void bsdf_microfacet_fresnel_color(ccl_private const ShaderData *sd, ccl_private MicrofacetBsdf *bsdf) { @@ -274,6 +334,217 @@ ccl_device_forceinline void bsdf_microfacet_fresnel_color(ccl_private const Shad bsdf->sample_weight *= average(bsdf->extra->fresnel_color); } +template +ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, + const float3 Ng, + const float3 wi, + const float3 wo, + ccl_private float *pdf) +{ + ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; + const bool m_refractive = (bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) || + (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID); + + const float3 N = bsdf->N; + const float cos_NI = dot(N, wi); + const float cos_NO = dot(N, wo); + const float cos_NgO = dot(Ng, wo); + + const float alpha_x = bsdf->alpha_x; + const float alpha_y = bsdf->alpha_y; + + if ((cos_NI <= 0) || ((cos_NgO < 0.0f) != m_refractive) || ((cos_NO < 0.0f) != m_refractive) || + (alpha_x * alpha_y <= 1e-7f)) { + *pdf = 0.0f; + return zero_spectrum(); + } + + /* Compute half vector. */ + float3 H = m_refractive ? -(bsdf->ior * wo + wi) : (wi + wo); + const float inv_len_H = 1.0f / len(H); + H *= inv_len_H; + + const float cos_NH = dot(N, H); + float D, G1i, G1o; + + /* TODO: add support for anisotropic transmission. */ + if (alpha_x == alpha_y || m_refractive) { /* Isotropic. */ + float alpha2 = alpha_x * alpha_y; + + if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { + D = bsdf_clearcoat_D(alpha2, cos_NH); + + /* The masking-shadowing term for clearcoat has a fixed alpha of 0.25 + * => alpha2 = 0.25 * 0.25 */ + alpha2 = 0.0625f; + } + else { + D = bsdf_D(alpha2, cos_NH); + } + + G1i = bsdf_G1(alpha2, cos_NI); + G1o = bsdf_G1(alpha2, cos_NO); + } + else { /* Anisotropic. */ + float3 X, Y; + make_orthonormals_tangent(N, bsdf->T, &X, &Y); + + const float3 local_H = make_float3(dot(X, H), dot(Y, H), cos_NH); + const float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI); + const float3 local_O = make_float3(dot(X, wo), dot(Y, wo), cos_NO); + + D = bsdf_aniso_D(alpha_x, alpha_y, local_H); + + G1i = bsdf_aniso_G1(alpha_x, alpha_y, local_I); + G1o = bsdf_aniso_G1(alpha_x, alpha_y, local_O); + } + + const float common = G1i * D / cos_NI * + (m_refractive ? + sqr(bsdf->ior * inv_len_H) * fabsf(dot(H, wi) * dot(H, wo)) : + 0.25f); + + *pdf = common; + + const Spectrum F = m_refractive ? one_spectrum() : reflection_color(bsdf, wo, H); + + return F * G1o * common; +} + +template +ccl_device int bsdf_microfacet_sample(KernelGlobals kg, + ccl_private const ShaderClosure *sc, + float3 Ng, + float3 wi, + float randu, + float randv, + ccl_private Spectrum *eval, + ccl_private float3 *wo, + ccl_private float *pdf, + ccl_private float2 *sampled_roughness, + ccl_private float *eta) +{ + ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; + + const float m_eta = bsdf->ior; + const bool m_refractive = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID) || + (bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID); + int label = m_refractive ? LABEL_TRANSMIT : LABEL_REFLECT; + + const float3 N = bsdf->N; + const float cos_NI = dot(N, wi); + if (cos_NI <= 0) { + return label | LABEL_GLOSSY; + } + + float3 X, Y; + const float alpha_x = bsdf->alpha_x; + const float alpha_y = bsdf->alpha_y; + if (alpha_x == alpha_y) { + make_orthonormals(N, &X, &Y); + } + else { + make_orthonormals_tangent(N, bsdf->T, &X, &Y); + } + + /* Importance sampling with distribution of visible normals. Vectors are transformed to local + * space before and after sampling. */ + float G1i; + const float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI); + const float3 local_H = microfacet_sample_stretched( + kg, local_I, alpha_x, alpha_y, randu, randv, beckmann, &G1i); + + const float3 H = X * local_H.x + Y * local_H.y + N * local_H.z; + const float cos_NH = local_H.z; + const float cos_HI = dot(H, wi); + + bool valid = beckmann; + if (m_refractive) { + float3 R, T; + bool inside; + + float fresnel = fresnel_dielectric(m_eta, H, wi, &R, &T, &inside); + *wo = T; + + valid = !inside && fresnel != 1.0f; + } + else { + /* Eq. 39 - compute actual reflected direction */ + *wo = 2 * cos_HI * H - wi; + + valid = dot(Ng, *wo) > 0; + } + + if (!valid) { + *eval = zero_spectrum(); + *pdf = 0.0f; + return label | LABEL_GLOSSY; + } + + if (alpha_x * alpha_y <= 1e-7f || (m_refractive && fabsf(m_eta - 1.0f) < 1e-4f)) { + label |= LABEL_SINGULAR; + /* Some high number for MIS. */ + *pdf = 1e6f; + *eval = make_spectrum(1e6f); + + bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID || + bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID); + + if (use_fresnel && !m_refractive) { + *eval *= reflection_color(bsdf, *wo, H); + } + } + else { + label |= LABEL_GLOSSY; + float cos_NO = dot(N, *wo); + float D, G1o; + + /* TODO: add support for anisotropic transmission. */ + if (alpha_x == alpha_y || m_refractive) { /* Isotropic. */ + float alpha2 = alpha_x * alpha_y; + + if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { + D = bsdf_clearcoat_D(alpha2, cos_NH); + + /* The masking-shadowing term for clearcoat has a fixed alpha of 0.25 + * => alpha2 = 0.25 * 0.25 */ + alpha2 = 0.0625f; + + /* Recalculate G1i. */ + G1i = bsdf_G1(alpha2, cos_NI); + } + else { + D = bsdf_D(alpha2, cos_NH); + } + + G1o = bsdf_G1(alpha2, cos_NO); + } + else { /* Anisotropic. */ + const float3 local_O = make_float3(dot(X, *wo), dot(Y, *wo), cos_NO); + + D = bsdf_aniso_D(alpha_x, alpha_y, local_H); + + G1o = bsdf_aniso_G1(alpha_x, alpha_y, local_O); + } + + const float cos_HO = dot(H, *wo); + const float common = G1i * D / cos_NI * + (m_refractive ? fabsf(cos_HI * cos_HO) / sqr(cos_HO + cos_HI / m_eta) : + 0.25f); + + *pdf = common; + + Spectrum F = m_refractive ? one_spectrum() : reflection_color(bsdf, *wo, H); + + *eval = G1o * common * F; + } + + *sampled_roughness = make_float2(alpha_x, alpha_y); + *eta = m_refractive ? 1.0f / m_eta : m_eta; + + return label; +} + /* GGX microfacet with Smith shadow-masking from: * * Microfacet Models for Refraction through Rough Surfaces @@ -357,190 +628,13 @@ ccl_device void bsdf_microfacet_ggx_blur(ccl_private ShaderClosure *sc, float ro bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y); } -ccl_device Spectrum bsdf_microfacet_ggx_eval_reflect(ccl_private const MicrofacetBsdf *bsdf, - const float3 N, - const float3 wi, - const float3 wo, - ccl_private float *pdf, - const float alpha_x, - const float alpha_y, - const float cosNI, - const float cosNO) -{ - if (!(cosNI > 0 && cosNO > 0)) { - *pdf = 0.0f; - return zero_spectrum(); - } - - /* get half vector */ - float3 m = normalize(wi + wo); - float alpha2 = alpha_x * alpha_y; - float D, G1i, G1o; - - if (alpha_x == alpha_y) { - /* isotropic - * eq. 20: (F*G*D)/(4*in*on) - * eq. 33: first we calculate D(m) */ - float cosThetaM = dot(N, m); - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - - if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { - /* use GTR1 for clearcoat */ - D = D_GTR1(cosThetaM, bsdf->alpha_x); - - /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */ - alpha2 = 0.0625f; - } - else { - /* use GTR2 otherwise */ - D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - } - - /* eq. 34: now calculate G1(i,m) and G1(o,m) */ - G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - } - else { - /* anisotropic */ - float3 X, Y, Z = N; - make_orthonormals_tangent(Z, bsdf->T, &X, &Y); - - /* distribution */ - float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m)); - float slope_x = -local_m.x / (local_m.z * alpha_x); - float slope_y = -local_m.y / (local_m.z * alpha_y); - float slope_len = 1 + slope_x * slope_x + slope_y * slope_y; - - float cosThetaM = local_m.z; - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - - D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4); - - /* G1(i,m) and G1(o,m) */ - float tanThetaI2 = (1 - cosNI * cosNI) / (cosNI * cosNI); - float cosPhiI = dot(wi, X); - float sinPhiI = dot(wi, Y); - - float alphaI2 = (cosPhiI * cosPhiI) * (alpha_x * alpha_x) + - (sinPhiI * sinPhiI) * (alpha_y * alpha_y); - alphaI2 /= cosPhiI * cosPhiI + sinPhiI * sinPhiI; - - G1i = 2 / (1 + safe_sqrtf(1 + alphaI2 * tanThetaI2)); - - float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO); - float cosPhiO = dot(wo, X); - float sinPhiO = dot(wo, Y); - - float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) + - (sinPhiO * sinPhiO) * (alpha_y * alpha_y); - alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO; - - G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2)); - } - - float G = G1i * G1o; - - /* eq. 20 */ - float common = D * 0.25f / cosNI; - - Spectrum F = reflection_color(bsdf, wo, m); - if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { - F *= 0.25f * bsdf->extra->clearcoat; - } - - Spectrum out = F * G * common; - - /* eq. 2 in distribution of visible normals sampling - * `pm = Dw = G1i * dot(m, I) * D / dot(N, I);` */ - - /* eq. 38 - but see also: - * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - * `pdf = pm * 0.25 / dot(m, I);` */ - *pdf = G1i * common; - - return out; -} - -ccl_device Spectrum bsdf_microfacet_ggx_eval_transmit(ccl_private const MicrofacetBsdf *bsdf, - const float3 N, - const float3 wi, - const float3 wo, - ccl_private float *pdf, - const float alpha_x, - const float alpha_y, - const float cosNI, - const float cosNO) -{ - if (cosNI <= 0 || cosNO >= 0) { - *pdf = 0.0f; - return zero_spectrum(); /* vectors on same side -- not possible */ - } - /* compute half-vector of the refraction (eq. 16) */ - float m_eta = bsdf->ior; - float3 ht = -(m_eta * wo + wi); - float3 Ht = normalize(ht); - float cosHI = dot(Ht, wi); - float cosHO = dot(Ht, wo); - - float D, G1i, G1o; - - /* eq. 33: first we calculate D(m) with m=Ht: */ - float alpha2 = alpha_x * alpha_y; - float cosThetaM = dot(N, Ht); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - - /* eq. 34: now calculate G1(i,m) and G1(o,m) */ - G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - - float G = G1i * G1o; - - /* probability */ - float Ht2 = dot(ht, ht); - - /* eq. 2 in distribution of visible normals sampling - * pm = Dw = G1i * dot(m, I) * D / dot(N, I); */ - - /* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNI * Ht2) - * pdf = pm * (m_eta * m_eta) * fabsf(cosHO) / Ht2 */ - float common = D * (m_eta * m_eta) / (cosNI * Ht2); - float out = G * fabsf(cosHI * cosHO) * common; - *pdf = G1i * fabsf(cosHI * cosHO) * common; - - return make_spectrum(out); -} - ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc, const float3 Ng, const float3 wi, const float3 wo, ccl_private float *pdf) { - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - const float alpha_x = bsdf->alpha_x; - const float alpha_y = bsdf->alpha_y; - const float cosNgO = dot(Ng, wo); - - if (((cosNgO < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) { - *pdf = 0.0f; - return zero_spectrum(); - } - - const float3 N = bsdf->N; - const float cosNI = dot(N, wi); - const float cosNO = dot(N, wo); - - return (cosNgO < 0.0f) ? bsdf_microfacet_ggx_eval_transmit( - bsdf, N, wi, wo, pdf, alpha_x, alpha_y, cosNI, cosNO) : - bsdf_microfacet_ggx_eval_reflect( - bsdf, N, wi, wo, pdf, alpha_x, alpha_y, cosNI, cosNO); + return bsdf_microfacet_eval(sc, Ng, wi, wo, pdf); } ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, @@ -555,198 +649,8 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, ccl_private float2 *sampled_roughness, ccl_private float *eta) { - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - float alpha_x = bsdf->alpha_x; - float alpha_y = bsdf->alpha_y; - bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID; - - *sampled_roughness = make_float2(alpha_x, alpha_y); - *eta = m_refractive ? 1.0f / bsdf->ior : bsdf->ior; - - float3 N = bsdf->N; - int label; - - float cosNI = dot(N, wi); - if (cosNI > 0) { - float3 X, Y, Z = N; - - if (alpha_x == alpha_y) - make_orthonormals(Z, &X, &Y); - else - make_orthonormals_tangent(Z, bsdf->T, &X, &Y); - - /* importance sampling with distribution of visible normals. vectors are - * transformed to local space before and after */ - float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cosNI); - float3 local_m; - float G1i; - - local_m = microfacet_sample_stretched( - kg, local_I, alpha_x, alpha_y, randu, randv, false, &G1i); - - float3 m = X * local_m.x + Y * local_m.y + Z * local_m.z; - float cosThetaM = local_m.z; - - /* reflection or refraction? */ - if (!m_refractive) { - float cosMI = dot(m, wi); - label = LABEL_REFLECT | LABEL_GLOSSY; - - if (cosMI > 0) { - /* eq. 39 - compute actual reflected direction */ - *wo = 2 * cosMI * m - wi; - - if (dot(Ng, *wo) > 0) { - if (alpha_x * alpha_y <= 1e-7f) { - /* some high number for MIS */ - *pdf = 1e6f; - *eval = make_spectrum(1e6f); - - bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_FRESNEL_ID || - bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID); - - /* if fresnel is used, calculate the color with reflection_color(...) */ - if (use_fresnel) { - *eval *= reflection_color(bsdf, *wo, m); - } - - label = LABEL_REFLECT | LABEL_SINGULAR; - } - else { - /* microfacet normal is visible to this ray */ - /* eq. 33 */ - float alpha2 = alpha_x * alpha_y; - float D, G1o; - - if (alpha_x == alpha_y) { - /* isotropic */ - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float tanThetaM2 = 1 / (cosThetaM2)-1; - - /* eval BRDF*cosNO */ - float cosNO = dot(N, *wo); - - if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { - /* use GTR1 for clearcoat */ - D = D_GTR1(cosThetaM, bsdf->alpha_x); - - /* the alpha value for clearcoat is a fixed 0.25 => alpha2 = 0.25 * 0.25 */ - alpha2 = 0.0625f; - - /* recalculate G1i */ - G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI))); - } - else { - /* use GTR2 otherwise */ - D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - } - - /* eq. 34: now calculate G1(o,m) */ - G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - } - else { - /* anisotropic distribution */ - float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m)); - float slope_x = -local_m.x / (local_m.z * alpha_x); - float slope_y = -local_m.y / (local_m.z * alpha_y); - float slope_len = 1 + slope_x * slope_x + slope_y * slope_y; - - float cosThetaM = local_m.z; - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - - D = 1 / ((slope_len * slope_len) * M_PI_F * alpha2 * cosThetaM4); - - /* calculate G1(o,m) */ - float cosNO = dot(N, *wo); - - float tanThetaO2 = (1 - cosNO * cosNO) / (cosNO * cosNO); - float cosPhiO = dot(*wo, X); - float sinPhiO = dot(*wo, Y); - - float alphaO2 = (cosPhiO * cosPhiO) * (alpha_x * alpha_x) + - (sinPhiO * sinPhiO) * (alpha_y * alpha_y); - alphaO2 /= cosPhiO * cosPhiO + sinPhiO * sinPhiO; - - G1o = 2 / (1 + safe_sqrtf(1 + alphaO2 * tanThetaO2)); - } - - /* see eval function for derivation */ - float common = (G1i * D) * 0.25f / cosNI; - *pdf = common; - - Spectrum F = reflection_color(bsdf, *wo, m); - - *eval = G1o * common * F; - } - - if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) { - *eval *= 0.25f * bsdf->extra->clearcoat; - } - } - else { - *eval = zero_spectrum(); - *pdf = 0.0f; - } - } - } - else { - label = LABEL_TRANSMIT | LABEL_GLOSSY; - - float3 R, T; - float m_eta = bsdf->ior, fresnel; - bool inside; - - fresnel = fresnel_dielectric(m_eta, m, wi, &R, &T, &inside); - - if (!inside && fresnel != 1.0f) { - *wo = T; - - if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) { - /* some high number for MIS */ - *pdf = 1e6f; - *eval = make_spectrum(1e6f); - label = LABEL_TRANSMIT | LABEL_SINGULAR; - } - else { - /* eq. 33 */ - float alpha2 = alpha_x * alpha_y; - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float tanThetaM2 = 1 / (cosThetaM2)-1; - float D = alpha2 / (M_PI_F * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2)); - - /* eval BRDF*cosNO */ - float cosNO = dot(N, *wo); - - /* eq. 34: now calculate G1(o,m) */ - float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO))); - - /* eq. 21 */ - float cosHO = dot(m, *wo); - float cosHI = dot(m, wi); - float Ht2 = m_eta * cosHO + cosHI; - Ht2 *= Ht2; - - /* see eval function for derivation */ - float common = (G1i * D) * (m_eta * m_eta) / (cosNO * Ht2); - float out = G1o * fabsf(cosHI * cosHO) * common; - *pdf = cosHI * fabsf(cosHO) * common; - - *eval = make_spectrum(out); - } - } - else { - *eval = zero_spectrum(); - *pdf = 0.0f; - } - } - } - else { - label = (m_refractive) ? LABEL_TRANSMIT | LABEL_GLOSSY : LABEL_REFLECT | LABEL_GLOSSY; - } - return label; + return bsdf_microfacet_sample( + kg, sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); } /* Beckmann microfacet with Smith shadow-masking from: @@ -788,185 +692,13 @@ ccl_device void bsdf_microfacet_beckmann_blur(ccl_private ShaderClosure *sc, flo bsdf->alpha_y = fmaxf(roughness, bsdf->alpha_y); } -ccl_device_inline float bsdf_beckmann_G1(float alpha, float cos_n) -{ - cos_n *= cos_n; - float invA = alpha * safe_sqrtf((1.0f - cos_n) / cos_n); - if (invA < 0.625f) { - return 1.0f; - } - - float a = 1.0f / invA; - return ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f); -} - -ccl_device_inline float bsdf_beckmann_aniso_G1( - float alpha_x, float alpha_y, float cos_n, float cos_phi, float sin_phi) -{ - cos_n *= cos_n; - sin_phi *= sin_phi; - cos_phi *= cos_phi; - alpha_x *= alpha_x; - alpha_y *= alpha_y; - - float alphaO2 = (cos_phi * alpha_x + sin_phi * alpha_y) / (cos_phi + sin_phi); - float invA = safe_sqrtf(alphaO2 * (1 - cos_n) / cos_n); - if (invA < 0.625f) { - return 1.0f; - } - - float a = 1.0f / invA; - return ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f); -} - -ccl_device Spectrum bsdf_microfacet_beckmann_eval_reflect(ccl_private const MicrofacetBsdf *bsdf, - const float3 N, - const float3 wi, - const float3 wo, - ccl_private float *pdf, - const float alpha_x, - const float alpha_y, - const float cosNI, - const float cosNO) -{ - if (!(cosNI > 0 && cosNO > 0)) { - *pdf = 0.0f; - return zero_spectrum(); - } - - /* get half vector */ - float3 m = normalize(wi + wo); - - float alpha2 = alpha_x * alpha_y; - float D, G1i, G1o; - - if (alpha_x == alpha_y) { - /* isotropic - * eq. 20: (F*G*D)/(4*in*on) - * eq. 25: first we calculate D(m) */ - float cosThetaM = dot(N, m); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4); - - /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */ - G1i = bsdf_beckmann_G1(alpha_x, cosNI); - G1o = bsdf_beckmann_G1(alpha_x, cosNO); - } - else { - /* anisotropic */ - float3 X, Y, Z = N; - make_orthonormals_tangent(Z, bsdf->T, &X, &Y); - - /* distribution */ - float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m)); - float slope_x = -local_m.x / (local_m.z * alpha_x); - float slope_y = -local_m.y / (local_m.z * alpha_y); - - float cosThetaM = local_m.z; - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - - D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4); - - /* G1(i,m) and G1(o,m) */ - G1i = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNI, dot(wi, X), dot(wi, Y)); - G1o = bsdf_beckmann_aniso_G1(alpha_x, alpha_y, cosNO, dot(wo, X), dot(wo, Y)); - } - - float G = G1i * G1o; - - /* eq. 20 */ - float common = D * 0.25f / cosNI; - float out = G * common; - - /* eq. 2 in distribution of visible normals sampling - * pm = Dw = G1i * dot(m, I) * D / dot(N, I); */ - - /* eq. 38 - but see also: - * eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf - * pdf = pm * 0.25 / dot(m, I); */ - *pdf = G1i * common; - - return make_spectrum(out); -} - -ccl_device Spectrum bsdf_microfacet_beckmann_eval_transmit(ccl_private const MicrofacetBsdf *bsdf, - const float3 N, - const float3 wi, - const float3 wo, - ccl_private float *pdf, - const float alpha_x, - const float alpha_y, - const float cosNI, - const float cosNO) -{ - if (cosNI <= 0 || cosNO >= 0) { - *pdf = 0.0f; - return zero_spectrum(); - } - - const float m_eta = bsdf->ior; - /* compute half-vector of the refraction (eq. 16) */ - float3 ht = -(m_eta * wo + wi); - float3 Ht = normalize(ht); - float cosHI = dot(Ht, wi); - float cosHO = dot(Ht, wo); - - /* eq. 25: first we calculate D(m) with m=Ht: */ - float alpha2 = alpha_x * alpha_y; - float cosThetaM = min(dot(N, Ht), 1.0f); - float cosThetaM2 = cosThetaM * cosThetaM; - float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4); - - /* eq. 26, 27: now calculate G1(i,m) and G1(o,m) */ - float G1i = bsdf_beckmann_G1(alpha_x, cosNI); - float G1o = bsdf_beckmann_G1(alpha_x, cosNO); - float G = G1i * G1o; - - /* probability */ - float Ht2 = dot(ht, ht); - - /* eq. 2 in distribution of visible normals sampling - * pm = Dw = G1i * dot(m, I) * D / dot(N, I); */ - - /* out = fabsf(cosHI * cosHO) * (m_eta * m_eta) * G * D / (cosNI * Ht2) - * pdf = pm * (m_eta * m_eta) * fabsf(cosHO) / Ht2 */ - float common = D * (m_eta * m_eta) / (cosNI * Ht2); - float out = G * fabsf(cosHI * cosHO) * common; - *pdf = G1i * fabsf(cosHI * cosHO) * common; - - return make_spectrum(out); -} - ccl_device Spectrum bsdf_microfacet_beckmann_eval(ccl_private const ShaderClosure *sc, const float3 Ng, const float3 wi, const float3 wo, ccl_private float *pdf) { - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - const bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - const float alpha_x = bsdf->alpha_x; - const float alpha_y = bsdf->alpha_y; - const float cosNgO = dot(Ng, wo); - - if (((cosNgO < 0.0f) != m_refractive) || alpha_x * alpha_y <= 1e-7f) { - *pdf = 0.0f; - return zero_spectrum(); - } - - const float3 N = bsdf->N; - const float cosNI = dot(N, wi); - const float cosNO = dot(N, wo); - - return (cosNO < 0.0f) ? bsdf_microfacet_beckmann_eval_transmit( - bsdf, N, wi, wo, pdf, alpha_x, alpha_y, cosNI, cosNO) : - bsdf_microfacet_beckmann_eval_reflect( - bsdf, N, wi, wo, pdf, alpha_x, alpha_y, cosNI, cosNO); + return bsdf_microfacet_eval(sc, Ng, wi, wo, pdf); } ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, @@ -981,161 +713,8 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, ccl_private float2 *sampled_roughness, ccl_private float *eta) { - ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc; - float alpha_x = bsdf->alpha_x; - float alpha_y = bsdf->alpha_y; - bool m_refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID; - float3 N = bsdf->N; - int label; - - *sampled_roughness = make_float2(alpha_x, alpha_y); - *eta = m_refractive ? 1.0f / bsdf->ior : bsdf->ior; - - float cosNI = dot(N, wi); - if (cosNI > 0) { - float3 X, Y, Z = N; - - if (alpha_x == alpha_y) - make_orthonormals(Z, &X, &Y); - else - make_orthonormals_tangent(Z, bsdf->T, &X, &Y); - - /* importance sampling with distribution of visible normals. vectors are - * transformed to local space before and after */ - float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cosNI); - float3 local_m; - float G1i; - - local_m = microfacet_sample_stretched(kg, local_I, alpha_x, alpha_y, randu, randv, true, &G1i); - - float3 m = X * local_m.x + Y * local_m.y + Z * local_m.z; - float cosThetaM = local_m.z; - - /* reflection or refraction? */ - if (!m_refractive) { - label = LABEL_REFLECT | LABEL_GLOSSY; - float cosMI = dot(m, wi); - - if (cosMI > 0) { - /* eq. 39 - compute actual reflected direction */ - *wo = 2 * cosMI * m - wi; - - if (dot(Ng, *wo) > 0) { - if (alpha_x * alpha_y <= 1e-7f) { - /* some high number for MIS */ - *pdf = 1e6f; - *eval = make_spectrum(1e6f); - label = LABEL_REFLECT | LABEL_SINGULAR; - } - else { - /* microfacet normal is visible to this ray - * eq. 25 */ - float alpha2 = alpha_x * alpha_y; - float D, G1o; - - if (alpha_x == alpha_y) { - /* Isotropic distribution. */ - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float tanThetaM2 = 1 / (cosThetaM2)-1; - D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4); - - /* eval BRDF*cosNO */ - float cosNO = dot(N, *wo); - - /* eq. 26, 27: now calculate G1(o,m) */ - G1o = bsdf_beckmann_G1(alpha_x, cosNO); - } - else { - /* anisotropic distribution */ - float3 local_m = make_float3(dot(X, m), dot(Y, m), dot(Z, m)); - float slope_x = -local_m.x / (local_m.z * alpha_x); - float slope_y = -local_m.y / (local_m.z * alpha_y); - - float cosThetaM = local_m.z; - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - - D = expf(-slope_x * slope_x - slope_y * slope_y) / (M_PI_F * alpha2 * cosThetaM4); - - /* G1(o,m) */ - G1o = bsdf_beckmann_aniso_G1( - alpha_x, alpha_y, dot(*wo, N), dot(*wo, X), dot(*wo, Y)); - } - - float G = G1i * G1o; - - /* see eval function for derivation */ - float common = D * 0.25f / cosNI; - float out = G * common; - *pdf = G1i * common; - - *eval = make_spectrum(out); - } - } - else { - *eval = zero_spectrum(); - *pdf = 0.0f; - } - } - } - else { - label = LABEL_TRANSMIT | LABEL_GLOSSY; - - float3 R, T; - float m_eta = bsdf->ior, fresnel; - bool inside; - - fresnel = fresnel_dielectric(m_eta, m, wi, &R, &T, &inside); - - if (!inside && fresnel != 1.0f) { - *wo = T; - - if (alpha_x * alpha_y <= 1e-7f || fabsf(m_eta - 1.0f) < 1e-4f) { - /* some high number for MIS */ - *pdf = 1e6f; - *eval = make_spectrum(1e6f); - label = LABEL_TRANSMIT | LABEL_SINGULAR; - } - else { - /* eq. 33 */ - float alpha2 = alpha_x * alpha_y; - float cosThetaM2 = cosThetaM * cosThetaM; - float cosThetaM4 = cosThetaM2 * cosThetaM2; - float tanThetaM2 = 1 / (cosThetaM2)-1; - float D = expf(-tanThetaM2 / alpha2) / (M_PI_F * alpha2 * cosThetaM4); - - /* eval BRDF*cosNO */ - float cosNO = dot(N, *wo); - - /* eq. 26, 27: now calculate G1(o,m) */ - float G1o = bsdf_beckmann_G1(alpha_x, cosNO); - float G = G1i * G1o; - - /* eq. 21 */ - float cosHI = dot(m, wi); - float cosHO = dot(m, *wo); - float Ht2 = m_eta * cosHO + cosHI; - Ht2 *= Ht2; - - /* see eval function for derivation */ - float common = D * (m_eta * m_eta) / (cosNI * Ht2); - float out = G * fabsf(cosHO * cosHI) * common; - *pdf = G1i * cosHI * fabsf(cosHO) * common; - - *eval = make_spectrum(out); - } - } - else { - *eval = zero_spectrum(); - *pdf = 0.0f; - } - } - } - else { - label = (m_refractive) ? LABEL_TRANSMIT | LABEL_GLOSSY : LABEL_REFLECT | LABEL_GLOSSY; - } - return label; + return bsdf_microfacet_sample( + kg, sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); } CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h index 9eb72390d98..3344e685499 100644 --- a/intern/cycles/kernel/integrator/mnee.h +++ b/intern/cycles/kernel/integrator/mnee.h @@ -616,15 +616,13 @@ ccl_device_forceinline Spectrum mnee_eval_bsdf_contribution(ccl_private ShaderCl float alpha2 = bsdf->alpha_x * bsdf->alpha_y; float cosThetaM = dot(bsdf->N, Ht); + /* Now calculate G1(i, m) and G1(o, m). */ float G; if (bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) { - /* Eq. 26, 27: now calculate G1(i,m) and G1(o,m). */ - G = bsdf_beckmann_G1(bsdf->alpha_x, cosNI) * bsdf_beckmann_G1(bsdf->alpha_x, cosNO); + G = bsdf_G(alpha2, cosNI, cosNO); } else { /* bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID assumed */ - /* Eq. 34: now calculate G1(i,m) and G1(o,m). */ - G = (2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNI * cosNI) / (cosNI * cosNI)))) * - (2.f / (1.f + safe_sqrtf(1.f + alpha2 * (1.f - cosNO * cosNO) / (cosNO * cosNO)))); + G = bsdf_G(alpha2, cosNI, cosNO); } /* From 203bacbe4acc26060fa0a6703dcef2ab87e8b7d9 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Thu, 19 Jan 2023 14:38:49 +0100 Subject: [PATCH 0769/1522] Fix T103809: Using Preview Range Breaks Normalized FCurve Display When using the "normalized" display of FCurves in the Graph Editor, and also turning on the preview range, the normalized display would break. The preview frame range was assumed to be bezt indices, which is only true when every frame has a key. Reviewed by: Colin Basnett Differential Revision: https://developer.blender.org/D16987 Ref: D16987 --- source/blender/editors/animation/anim_draw.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 329bc2b46eb..779b63d7e9b 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -343,8 +343,12 @@ static void fcurve_scene_coord_range_get(Scene *scene, int end = fcu->totvert; if (use_preview_only) { - start = scene->r.psfra; - end = min_ii(scene->r.pefra + 1, fcu->totvert); + /* Preview frame ranges need to be converted to bezt array indices. */ + bool replace = false; + start = BKE_fcurve_bezt_binarysearch_index( + fcu->bezt, scene->r.psfra, fcu->totvert, &replace); + + end = BKE_fcurve_bezt_binarysearch_index(fcu->bezt, scene->r.pefra, fcu->totvert, &replace); } if (fcu->bezt) { From 7f81d18ffecabffc7dc000117230631e6f433eae Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 19 Jan 2023 15:10:49 +0100 Subject: [PATCH 0770/1522] Metal: Fix crash when using `batch_for_shader`. `batch_for_shader` is an utility function that creates the correct vertex buffer based on the given shader. In the shader interface the `attr_types_` contains the GPUType for each location in the vertex buffer. When using Metal, the `attr_types_` was never updated, resulting in using incorrect or non-existing data types. This patch fixes this by updating the `attr_types_` when building the shader interface. Reviewed By: fclem Differential Revision: https://developer.blender.org/D17042 --- source/blender/gpu/metal/mtl_shader_generator.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm index 93429800888..006e0fbd9cf 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.mm +++ b/source/blender/gpu/metal/mtl_shader_generator.mm @@ -2607,6 +2607,10 @@ MTLShaderInterface *MSLGeneratorInterface::bake_shader_interface(const char *nam c_offset); c_offset += size; } + + /* Used in `GPU_shader_get_attribute_info`. */ + interface->attr_types_[this->vertex_input_attributes[attribute].layout_location] = uint8_t( + this->vertex_input_attributes[attribute].type); } /* Prepare Interface Default Uniform Block. */ From 9b7c2cca3df808eb0948e0e7e24fb18b11cb7476 Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Thu, 19 Jan 2023 12:48:29 +0100 Subject: [PATCH 0771/1522] Refactor: replace `bool beckmann` with `enum MicrofacetType` for readability Differential Revision: https://developer.blender.org/D17044 --- .../cycles/kernel/closure/bsdf_microfacet.h | 91 +++++++++++-------- intern/cycles/kernel/integrator/mnee.h | 4 +- 2 files changed, 55 insertions(+), 40 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 377cf836fb8..25238698614 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -16,6 +16,11 @@ CCL_NAMESPACE_BEGIN +enum MicrofacetType { + BECKMANN, + GGX, +}; + typedef struct MicrofacetExtra { Spectrum color, cspec0; Spectrum fresnel_color; @@ -175,13 +180,13 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, *slope_y = S * z * safe_sqrtf(1.0f + (*slope_x) * (*slope_x)); } +template ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, const float3 wi, const float alpha_x, const float alpha_y, const float randu, const float randv, - bool beckmann, ccl_private float *G1i) { /* 1. stretch wi */ @@ -206,7 +211,7 @@ ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, /* 2. sample P22_{wi}(x_slope, y_slope, 1, 1) */ float slope_x, slope_y; - if (beckmann) { + if constexpr (m_type == MicrofacetType::BECKMANN) { microfacet_beckmann_sample_slopes( kg, costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i); } @@ -268,45 +273,51 @@ ccl_device_forceinline float bsdf_clearcoat_D(float alpha2, float cos_NH) } /* Monodirectional shadowing-masking term. */ -template ccl_device_inline float bsdf_G1_from_sqr_alpha_tan_n(float sqr_alpha_tan_n) +template +ccl_device_inline float bsdf_G1_from_sqr_alpha_tan_n(float sqr_alpha_tan_n) { - if (!beckmann) { /* GGX. */ + if constexpr (m_type == MicrofacetType::GGX) { return 2.0f / (1.0f + sqrtf(1.0f + sqr_alpha_tan_n)); } + /* m_type == MicrofacetType::BECKMANN */ const float a = inversesqrtf(sqr_alpha_tan_n); return (a > 1.6f) ? 1.0f : ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f); } -template ccl_device_inline float bsdf_G1(float alpha2, float cos_N) +template ccl_device_inline float bsdf_G1(float alpha2, float cos_N) { - return bsdf_G1_from_sqr_alpha_tan_n(alpha2 * - fmaxf(1.0f / (cos_N * cos_N) - 1.0f, 0.0f)); + return bsdf_G1_from_sqr_alpha_tan_n(alpha2 * fmaxf(1.0f / (cos_N * cos_N) - 1.0f, 0.0f)); } -template +template ccl_device_inline float bsdf_aniso_G1(float alpha_x, float alpha_y, float3 V) { - return bsdf_G1_from_sqr_alpha_tan_n((sqr(alpha_x * V.x) + sqr(alpha_y * V.y)) / - sqr(V.z)); + return bsdf_G1_from_sqr_alpha_tan_n((sqr(alpha_x * V.x) + sqr(alpha_y * V.y)) / + sqr(V.z)); } /* Smith's separable shadowing-masking term. */ -template ccl_device_inline float bsdf_G(float alpha2, float cos_NI, float cos_NO) +template +ccl_device_inline float bsdf_G(float alpha2, float cos_NI, float cos_NO) { - return bsdf_G1(alpha2, cos_NI) * bsdf_G1(alpha2, cos_NO); + return bsdf_G1(alpha2, cos_NI) * bsdf_G1(alpha2, cos_NO); } /* Normal distribution function. */ -template ccl_device_inline float bsdf_D(float alpha2, float cos_NH) +template ccl_device_inline float bsdf_D(float alpha2, float cos_NH) { const float cos_NH2 = sqr(cos_NH); - return beckmann ? expf((1.0f - 1.0f / cos_NH2) / alpha2) / (M_PI_F * alpha2 * sqr(cos_NH2)) : - alpha2 / (M_PI_F * sqr(1.0f + (alpha2 - 1.0f) * cos_NH2)); + if constexpr (m_type == MicrofacetType::BECKMANN) { + return expf((1.0f - 1.0f / cos_NH2) / alpha2) / (M_PI_F * alpha2 * sqr(cos_NH2)); + } + + /* m_type == MicrofacetType::GGX */ + return alpha2 / (M_PI_F * sqr(1.0f + (alpha2 - 1.0f) * cos_NH2)); } -template +template ccl_device_inline float bsdf_aniso_D(float alpha_x, float alpha_y, float3 H) { H /= make_float3(alpha_x, alpha_y, 1.0f); @@ -314,8 +325,12 @@ ccl_device_inline float bsdf_aniso_D(float alpha_x, float alpha_y, float3 H) const float cos_NH2 = sqr(H.z); const float alpha2 = alpha_x * alpha_y; - return beckmann ? expf(-(sqr(H.x) + sqr(H.y)) / cos_NH2) / (M_PI_F * alpha2 * sqr(cos_NH2)) : - M_1_PI_F / (alpha2 * sqr(len_squared(H))); + if constexpr (m_type == MicrofacetType::BECKMANN) { + return expf(-(sqr(H.x) + sqr(H.y)) / cos_NH2) / (M_PI_F * alpha2 * sqr(cos_NH2)); + } + + /* m_type == MicrofacetType::GGX */ + return M_1_PI_F / (alpha2 * sqr(len_squared(H))); } ccl_device_forceinline void bsdf_microfacet_fresnel_color(ccl_private const ShaderData *sd, @@ -334,7 +349,7 @@ ccl_device_forceinline void bsdf_microfacet_fresnel_color(ccl_private const Shad bsdf->sample_weight *= average(bsdf->extra->fresnel_color); } -template +template ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, const float3 Ng, const float3 wi, @@ -379,11 +394,11 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, alpha2 = 0.0625f; } else { - D = bsdf_D(alpha2, cos_NH); + D = bsdf_D(alpha2, cos_NH); } - G1i = bsdf_G1(alpha2, cos_NI); - G1o = bsdf_G1(alpha2, cos_NO); + G1i = bsdf_G1(alpha2, cos_NI); + G1o = bsdf_G1(alpha2, cos_NO); } else { /* Anisotropic. */ float3 X, Y; @@ -393,10 +408,10 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, const float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI); const float3 local_O = make_float3(dot(X, wo), dot(Y, wo), cos_NO); - D = bsdf_aniso_D(alpha_x, alpha_y, local_H); + D = bsdf_aniso_D(alpha_x, alpha_y, local_H); - G1i = bsdf_aniso_G1(alpha_x, alpha_y, local_I); - G1o = bsdf_aniso_G1(alpha_x, alpha_y, local_O); + G1i = bsdf_aniso_G1(alpha_x, alpha_y, local_I); + G1o = bsdf_aniso_G1(alpha_x, alpha_y, local_O); } const float common = G1i * D / cos_NI * @@ -411,7 +426,7 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, return F * G1o * common; } -template +template ccl_device int bsdf_microfacet_sample(KernelGlobals kg, ccl_private const ShaderClosure *sc, float3 Ng, @@ -451,14 +466,14 @@ ccl_device int bsdf_microfacet_sample(KernelGlobals kg, * space before and after sampling. */ float G1i; const float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI); - const float3 local_H = microfacet_sample_stretched( - kg, local_I, alpha_x, alpha_y, randu, randv, beckmann, &G1i); + const float3 local_H = microfacet_sample_stretched( + kg, local_I, alpha_x, alpha_y, randu, randv, &G1i); const float3 H = X * local_H.x + Y * local_H.y + N * local_H.z; const float cos_NH = local_H.z; const float cos_HI = dot(H, wi); - bool valid = beckmann; + bool valid = false; if (m_refractive) { float3 R, T; bool inside; @@ -511,20 +526,20 @@ ccl_device int bsdf_microfacet_sample(KernelGlobals kg, alpha2 = 0.0625f; /* Recalculate G1i. */ - G1i = bsdf_G1(alpha2, cos_NI); + G1i = bsdf_G1(alpha2, cos_NI); } else { - D = bsdf_D(alpha2, cos_NH); + D = bsdf_D(alpha2, cos_NH); } - G1o = bsdf_G1(alpha2, cos_NO); + G1o = bsdf_G1(alpha2, cos_NO); } else { /* Anisotropic. */ const float3 local_O = make_float3(dot(X, *wo), dot(Y, *wo), cos_NO); - D = bsdf_aniso_D(alpha_x, alpha_y, local_H); + D = bsdf_aniso_D(alpha_x, alpha_y, local_H); - G1o = bsdf_aniso_G1(alpha_x, alpha_y, local_O); + G1o = bsdf_aniso_G1(alpha_x, alpha_y, local_O); } const float cos_HO = dot(H, *wo); @@ -634,7 +649,7 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc const float3 wo, ccl_private float *pdf) { - return bsdf_microfacet_eval(sc, Ng, wi, wo, pdf); + return bsdf_microfacet_eval(sc, Ng, wi, wo, pdf); } ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, @@ -649,7 +664,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, ccl_private float2 *sampled_roughness, ccl_private float *eta) { - return bsdf_microfacet_sample( + return bsdf_microfacet_sample( kg, sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); } @@ -698,7 +713,7 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval(ccl_private const ShaderClosur const float3 wo, ccl_private float *pdf) { - return bsdf_microfacet_eval(sc, Ng, wi, wo, pdf); + return bsdf_microfacet_eval(sc, Ng, wi, wo, pdf); } ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, @@ -713,7 +728,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, ccl_private float2 *sampled_roughness, ccl_private float *eta) { - return bsdf_microfacet_sample( + return bsdf_microfacet_sample( kg, sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); } diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h index 3344e685499..b6b07ad83a1 100644 --- a/intern/cycles/kernel/integrator/mnee.h +++ b/intern/cycles/kernel/integrator/mnee.h @@ -619,10 +619,10 @@ ccl_device_forceinline Spectrum mnee_eval_bsdf_contribution(ccl_private ShaderCl /* Now calculate G1(i, m) and G1(o, m). */ float G; if (bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) { - G = bsdf_G(alpha2, cosNI, cosNO); + G = bsdf_G(alpha2, cosNI, cosNO); } else { /* bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID assumed */ - G = bsdf_G(alpha2, cosNI, cosNO); + G = bsdf_G(alpha2, cosNI, cosNO); } /* From 90c6674f281bdf064b2c9607d3b07777f81f41ef Mon Sep 17 00:00:00 2001 From: Michael Kowalski Date: Thu, 19 Jan 2023 10:57:22 -0500 Subject: [PATCH 0772/1522] Fix T102615: crash on USD export for scenes with point clouds or hair Code authored by Michael B Johnson (drwave). Reviewed by Sybren and makowalski. This patch addresses a crash that occurs when exporting a scene to a USD file, when that scene includes a point cloud object or hair. Added OB_POINTCLOUD and OB_CURVES enums and a default case statement in the switch statement in USDHierarchyIterator::create_data_writer, to avoid dereferencing a NULL pointer. Differential Revision: https://developer.blender.org/D16776 --- source/blender/io/usd/intern/usd_hierarchy_iterator.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/io/usd/intern/usd_hierarchy_iterator.cc b/source/blender/io/usd/intern/usd_hierarchy_iterator.cc index fbfda975055..abf6c0cb0f9 100644 --- a/source/blender/io/usd/intern/usd_hierarchy_iterator.cc +++ b/source/blender/io/usd/intern/usd_hierarchy_iterator.cc @@ -118,10 +118,15 @@ AbstractHierarchyWriter *USDHierarchyIterator::create_data_writer(const Hierarch case OB_LATTICE: case OB_ARMATURE: case OB_GPENCIL: + case OB_POINTCLOUD: + case OB_CURVES: return nullptr; case OB_TYPE_MAX: BLI_assert_msg(0, "OB_TYPE_MAX should not be used"); return nullptr; + default: + BLI_assert_unreachable(); + return nullptr; } if (!data_writer->is_supported(context)) { From 25ce7056171f849b724ada0787b35504c3e16dca Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Thu, 19 Jan 2023 12:31:40 -0300 Subject: [PATCH 0773/1522] Merge by Distance: split code into more specialized functions Split the algorithms that find duplicates. This improves readability and helps us find areas for optimization. It may also facilitate the implementation of generic utilities. No functional changes. Differential Revision: https://developer.blender.org/D16918 --- .../geometry/intern/mesh_merge_by_distance.cc | 608 ++++++++++-------- 1 file changed, 325 insertions(+), 283 deletions(-) diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc index b9addd8dd57..0d1cdf93133 100644 --- a/source/blender/geometry/intern/mesh_merge_by_distance.cc +++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc @@ -15,7 +15,7 @@ #include "GEO_mesh_merge_by_distance.hh" -//#define USE_WELD_DEBUG +// #define USE_WELD_DEBUG namespace blender::geometry { @@ -404,13 +404,15 @@ static void weld_vert_groups_setup(Span wvert, * \return r_edge_dest_map: First step to create map of indices pointing edges that will be merged. * \return r_edge_ctx_map: Map of indices pointing original edges to weld context edges. */ -static Vector weld_edge_ctx_alloc(Span medge, - Span vert_dest_map, - MutableSpan r_edge_dest_map, - MutableSpan r_edge_ctx_map) +static Vector weld_edge_ctx_alloc_and_find_collapsed(Span medge, + Span vert_dest_map, + MutableSpan r_edge_dest_map, + MutableSpan r_edge_ctx_map, + int *r_edge_collapsed_len) { /* Edge Context. */ int wedge_len = 0; + int edge_collapsed_len = 0; Vector wedge; wedge.reserve(medge.size()); @@ -426,8 +428,17 @@ static Vector weld_edge_ctx_alloc(Span medge, we.vert_b = (v_dest_2 != OUT_OF_CONTEXT) ? v_dest_2 : v2; we.edge_dest = OUT_OF_CONTEXT; we.edge_orig = i; + + if (we.vert_a == we.vert_b) { + we.flag = ELEM_COLLAPSED; + edge_collapsed_len++; + r_edge_dest_map[i] = ELEM_COLLAPSED; + } + else { + r_edge_dest_map[i] = i; + } + wedge.append(we); - r_edge_dest_map[i] = i; r_edge_ctx_map[i] = wedge_len++; } else { @@ -436,6 +447,7 @@ static Vector weld_edge_ctx_alloc(Span medge, } } + *r_edge_collapsed_len = edge_collapsed_len; return wedge; } @@ -449,30 +461,30 @@ static Vector weld_edge_ctx_alloc(Span medge, * \return r_wedge: Weld edges. `flag` and `edge_dest` members will be set here. * \return r_edge_kill_len: Number of edges to be destroyed by merging or collapsing. */ -static void weld_edge_ctx_setup(MutableSpan r_vlinks, - MutableSpan r_edge_dest_map, - MutableSpan r_wedge, - int *r_edge_kill_len) +static void weld_edge_find_doubles(int remain_edge_ctx_len, + MutableSpan r_vlinks, + MutableSpan r_edge_dest_map, + MutableSpan r_wedge, + int *r_edge_kill_len) { + if (remain_edge_ctx_len == 0) { + return; + } + /* Setup Edge Overlap. */ - int edge_kill_len = 0; + int edge_double_len = 0; r_vlinks.fill(0); for (WeldEdge &we : r_wedge) { - int dst_vert_a = we.vert_a; - int dst_vert_b = we.vert_b; - - if (dst_vert_a == dst_vert_b) { - BLI_assert(we.edge_dest == OUT_OF_CONTEXT); - r_edge_dest_map[we.edge_orig] = ELEM_COLLAPSED; - we.flag = ELEM_COLLAPSED; - edge_kill_len++; + if (we.flag == ELEM_COLLAPSED) { + BLI_assert(r_edge_dest_map[we.edge_orig] == ELEM_COLLAPSED); continue; } - r_vlinks[dst_vert_a]++; - r_vlinks[dst_vert_b]++; + BLI_assert(we.vert_a != we.vert_b); + r_vlinks[we.vert_a]++; + r_vlinks[we.vert_b]++; } int link_len = 0; @@ -482,80 +494,79 @@ static void weld_edge_ctx_setup(MutableSpan r_vlinks, } r_vlinks.last() = link_len; - if (link_len > 0) { - Array link_edge_buffer(link_len); + BLI_assert(link_len > 0); + Array link_edge_buffer(link_len); - /* Use a reverse for loop to ensure that indexes are assigned in ascending order. */ - for (int i = r_wedge.size(); i--;) { - const WeldEdge &we = r_wedge[i]; - if (we.flag == ELEM_COLLAPSED) { - continue; - } - - int dst_vert_a = we.vert_a; - int dst_vert_b = we.vert_b; - - link_edge_buffer[--r_vlinks[dst_vert_a]] = i; - link_edge_buffer[--r_vlinks[dst_vert_b]] = i; + /* Use a reverse for loop to ensure that indexes are assigned in ascending order. */ + for (int i = r_wedge.size(); i--;) { + const WeldEdge &we = r_wedge[i]; + if (we.flag == ELEM_COLLAPSED) { + continue; } - for (const int i : r_wedge.index_range()) { - const WeldEdge &we = r_wedge[i]; - if (we.edge_dest != OUT_OF_CONTEXT) { - /* No need to retest edges. - * (Already includes collapsed edges). */ - continue; - } + int dst_vert_a = we.vert_a; + int dst_vert_b = we.vert_b; - int dst_vert_a = we.vert_a; - int dst_vert_b = we.vert_b; - - const int link_a = r_vlinks[dst_vert_a]; - const int link_b = r_vlinks[dst_vert_b]; - - int edges_len_a = r_vlinks[dst_vert_a + 1] - link_a; - int edges_len_b = r_vlinks[dst_vert_b + 1] - link_b; - - if (edges_len_a <= 1 || edges_len_b <= 1) { - continue; - } - - int *edges_ctx_a = &link_edge_buffer[link_a]; - int *edges_ctx_b = &link_edge_buffer[link_b]; - int edge_orig = we.edge_orig; - - for (; edges_len_a--; edges_ctx_a++) { - int e_ctx_a = *edges_ctx_a; - if (e_ctx_a == i) { - continue; - } - while (edges_len_b && *edges_ctx_b < e_ctx_a) { - edges_ctx_b++; - edges_len_b--; - } - if (edges_len_b == 0) { - break; - } - int e_ctx_b = *edges_ctx_b; - if (e_ctx_a == e_ctx_b) { - WeldEdge *we_b = &r_wedge[e_ctx_b]; - BLI_assert(ELEM(we_b->vert_a, dst_vert_a, dst_vert_b)); - BLI_assert(ELEM(we_b->vert_b, dst_vert_a, dst_vert_b)); - BLI_assert(we_b->edge_dest == OUT_OF_CONTEXT); - BLI_assert(we_b->edge_orig != edge_orig); - r_edge_dest_map[we_b->edge_orig] = edge_orig; - we_b->edge_dest = edge_orig; - edge_kill_len++; - } - } - } - -#ifdef USE_WELD_DEBUG - weld_assert_edge_kill_len(r_wedge, edge_kill_len); -#endif + link_edge_buffer[--r_vlinks[dst_vert_a]] = i; + link_edge_buffer[--r_vlinks[dst_vert_b]] = i; } - *r_edge_kill_len = edge_kill_len; + for (const int i : r_wedge.index_range()) { + const WeldEdge &we = r_wedge[i]; + if (we.edge_dest != OUT_OF_CONTEXT) { + /* No need to retest edges. + * (Already includes collapsed edges). */ + continue; + } + + int dst_vert_a = we.vert_a; + int dst_vert_b = we.vert_b; + + const int link_a = r_vlinks[dst_vert_a]; + const int link_b = r_vlinks[dst_vert_b]; + + int edges_len_a = r_vlinks[dst_vert_a + 1] - link_a; + int edges_len_b = r_vlinks[dst_vert_b + 1] - link_b; + + if (edges_len_a <= 1 || edges_len_b <= 1) { + continue; + } + + int *edges_ctx_a = &link_edge_buffer[link_a]; + int *edges_ctx_b = &link_edge_buffer[link_b]; + int edge_orig = we.edge_orig; + + for (; edges_len_a--; edges_ctx_a++) { + int e_ctx_a = *edges_ctx_a; + if (e_ctx_a == i) { + continue; + } + while (edges_len_b && *edges_ctx_b < e_ctx_a) { + edges_ctx_b++; + edges_len_b--; + } + if (edges_len_b == 0) { + break; + } + int e_ctx_b = *edges_ctx_b; + if (e_ctx_a == e_ctx_b) { + WeldEdge *we_b = &r_wedge[e_ctx_b]; + BLI_assert(ELEM(we_b->vert_a, dst_vert_a, dst_vert_b)); + BLI_assert(ELEM(we_b->vert_b, dst_vert_a, dst_vert_b)); + BLI_assert(we_b->edge_dest == OUT_OF_CONTEXT); + BLI_assert(we_b->edge_orig != edge_orig); + r_edge_dest_map[we_b->edge_orig] = edge_orig; + we_b->edge_dest = edge_orig; + edge_double_len++; + } + } + } + + *r_edge_kill_len += edge_double_len; + +#ifdef USE_WELD_DEBUG + weld_assert_edge_kill_len(r_wedge, *r_edge_kill_len); +#endif } /** @@ -995,204 +1006,225 @@ static void weld_poly_split_recursive(Span vert_dest_map, * done to reduce allocations. * \return r_weld_mesh: Loop and poly members will be configured here. */ -static void weld_poly_loop_ctx_setup(Span mloop, +static void weld_poly_loop_ctx_setup_collapsed_and_split(Span mloop, #ifdef USE_WELD_DEBUG - Span mpoly, + Span mpoly, #endif - const int mvert_len, - Span vert_dest_map, - const int remain_edge_ctx_len, - MutableSpan r_vlinks, - WeldMesh *r_weld_mesh) + Span vert_dest_map, + const int remain_edge_ctx_len, + WeldMesh *r_weld_mesh) { - WeldPoly *wpoly = r_weld_mesh->wpoly.data(); - MutableSpan wloop = r_weld_mesh->wloop; - int poly_kill_len = 0; - int loop_kill_len = 0; - - Span loop_map = r_weld_mesh->loop_map; - - if (remain_edge_ctx_len) { - - /* Setup Poly/Loop. */ - /* `wpoly.size()` may change during the loop, - * so make it clear that we are only working with the original wpolys. */ - IndexRange wpoly_original_range = r_weld_mesh->wpoly.index_range(); - for (const int i : wpoly_original_range) { - WeldPoly &wp = wpoly[i]; - const int ctx_loops_len = wp.loops.len; - const int ctx_loops_ofs = wp.loops.offs; - - int poly_loop_len = wp.loop_len; - int ctx_verts_len = 0; - WeldLoop *wl = &wloop[ctx_loops_ofs]; - for (int l = ctx_loops_len; l--; wl++) { - const int edge_dest = wl->edge; - if (edge_dest == ELEM_COLLAPSED) { - wl->flag = ELEM_COLLAPSED; - if (poly_loop_len == 3) { - wp.flag = ELEM_COLLAPSED; - poly_kill_len++; - loop_kill_len += 3; - poly_loop_len = 0; - break; - } - loop_kill_len++; - poly_loop_len--; - } - else { - const int vert_dst = wl->vert; - if (vert_dest_map[vert_dst] != OUT_OF_CONTEXT) { - ctx_verts_len++; - } - } - } - - if (poly_loop_len) { - wp.loop_len = poly_loop_len; -#ifdef USE_WELD_DEBUG - weld_assert_poly_len(&wp, wloop); -#endif - - weld_poly_split_recursive(vert_dest_map, -#ifdef USE_WELD_DEBUG - mloop, -#endif - ctx_verts_len, - &wp, - r_weld_mesh, - &poly_kill_len, - &loop_kill_len); - } - } - -#ifdef USE_WELD_DEBUG - weld_assert_poly_and_loop_kill_len(r_weld_mesh, mloop, mpoly, poly_kill_len, loop_kill_len); -#endif - - /* Setup Polygon Overlap. */ - - r_vlinks.fill(0); - - for (const WeldPoly &wp : r_weld_mesh->wpoly) { - WeldLoopOfPolyIter iter; - if (weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr)) { - while (weld_iter_loop_of_poly_next(iter)) { - r_vlinks[iter.v]++; - } - } - } - - int link_len = 0; - for (const int i : IndexRange(mvert_len)) { - link_len += r_vlinks[i]; - r_vlinks[i] = link_len; - } - r_vlinks[mvert_len] = link_len; - - if (link_len) { - Array link_poly_buffer(link_len); - - /* Use a reverse for loop to ensure that indexes are assigned in ascending order. */ - for (int i = r_weld_mesh->wpoly.size(); i--;) { - const WeldPoly &wp = wpoly[i]; - WeldLoopOfPolyIter iter; - if (weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr)) { - while (weld_iter_loop_of_poly_next(iter)) { - link_poly_buffer[--r_vlinks[iter.v]] = i; - } - } - } - - int polys_len_a, polys_len_b, *polys_ctx_a, *polys_ctx_b, p_ctx_a, p_ctx_b; - polys_len_b = p_ctx_b = 0; /* silence warnings */ - - for (const int i : IndexRange(r_weld_mesh->wpoly.size())) { - const WeldPoly &wp = wpoly[i]; - if (wp.poly_dst != OUT_OF_CONTEXT) { - /* No need to retest poly. - * (Already includes collapsed polygons). */ - continue; - } - - WeldLoopOfPolyIter iter; - weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr); - weld_iter_loop_of_poly_next(iter); - const int link_a = r_vlinks[iter.v]; - polys_len_a = r_vlinks[iter.v + 1] - link_a; - if (polys_len_a == 1) { - BLI_assert(link_poly_buffer[link_a] == i); - continue; - } - int wp_loop_len = wp.loop_len; - polys_ctx_a = &link_poly_buffer[link_a]; - for (; polys_len_a--; polys_ctx_a++) { - p_ctx_a = *polys_ctx_a; - if (p_ctx_a == i) { - continue; - } - - WeldPoly *wp_tmp = &wpoly[p_ctx_a]; - if (wp_tmp->loop_len != wp_loop_len) { - continue; - } - - WeldLoopOfPolyIter iter_b = iter; - while (weld_iter_loop_of_poly_next(iter_b)) { - const int link_b = r_vlinks[iter_b.v]; - polys_len_b = r_vlinks[iter_b.v + 1] - link_b; - if (polys_len_b == 1) { - BLI_assert(link_poly_buffer[link_b] == i); - polys_len_b = 0; - break; - } - - polys_ctx_b = &link_poly_buffer[link_b]; - for (; polys_len_b; polys_len_b--, polys_ctx_b++) { - p_ctx_b = *polys_ctx_b; - if (p_ctx_b < p_ctx_a) { - continue; - } - if (p_ctx_b >= p_ctx_a) { - if (p_ctx_b > p_ctx_a) { - polys_len_b = 0; - } - break; - } - } - if (polys_len_b == 0) { - break; - } - } - if (polys_len_b == 0) { - continue; - } - BLI_assert(p_ctx_a > i); - BLI_assert(p_ctx_a == p_ctx_b); - BLI_assert(wp_tmp->poly_dst == OUT_OF_CONTEXT); - BLI_assert(wp_tmp != &wp); - wp_tmp->poly_dst = wp.poly_orig; - loop_kill_len += wp_tmp->loop_len; - poly_kill_len++; - } - } - } - } - else { - poly_kill_len = r_weld_mesh->wpoly.size(); - loop_kill_len = r_weld_mesh->wloop.size(); + if (remain_edge_ctx_len == 0) { + r_weld_mesh->poly_kill_len = r_weld_mesh->wpoly.size(); + r_weld_mesh->loop_kill_len = r_weld_mesh->wloop.size(); for (WeldPoly &wp : r_weld_mesh->wpoly) { wp.flag = ELEM_COLLAPSED; } + + return; } + WeldPoly *wpoly = r_weld_mesh->wpoly.data(); + MutableSpan wloop = r_weld_mesh->wloop; + + int poly_kill_len = 0; + int loop_kill_len = 0; + + /* Setup Poly/Loop. */ + /* `wpoly.size()` may change during the loop, + * so make it clear that we are only working with the original wpolys. */ + IndexRange wpoly_original_range = r_weld_mesh->wpoly.index_range(); + for (const int i : wpoly_original_range) { + WeldPoly &wp = wpoly[i]; + const int ctx_loops_len = wp.loops.len; + const int ctx_loops_ofs = wp.loops.offs; + + int poly_loop_len = wp.loop_len; + int ctx_verts_len = 0; + WeldLoop *wl = &wloop[ctx_loops_ofs]; + for (int l = ctx_loops_len; l--; wl++) { + const int edge_dest = wl->edge; + if (edge_dest == ELEM_COLLAPSED) { + wl->flag = ELEM_COLLAPSED; + if (poly_loop_len == 3) { + wp.flag = ELEM_COLLAPSED; + poly_kill_len++; + loop_kill_len += 3; + poly_loop_len = 0; + break; + } + loop_kill_len++; + poly_loop_len--; + } + else { + const int vert_dst = wl->vert; + if (vert_dest_map[vert_dst] != OUT_OF_CONTEXT) { + ctx_verts_len++; + } + } + } + + if (poly_loop_len) { + wp.loop_len = poly_loop_len; #ifdef USE_WELD_DEBUG - weld_assert_poly_and_loop_kill_len(r_weld_mesh, mloop, mpoly, poly_kill_len, loop_kill_len); + weld_assert_poly_len(&wp, wloop); #endif + weld_poly_split_recursive(vert_dest_map, +#ifdef USE_WELD_DEBUG + mloop, +#endif + ctx_verts_len, + &wp, + r_weld_mesh, + &poly_kill_len, + &loop_kill_len); + } + } + r_weld_mesh->poly_kill_len = poly_kill_len; r_weld_mesh->loop_kill_len = loop_kill_len; + +#ifdef USE_WELD_DEBUG + weld_assert_poly_and_loop_kill_len( + r_weld_mesh, mloop, mpoly, r_weld_mesh->poly_kill_len, r_weld_mesh->loop_kill_len); +#endif +} + +static void weld_poly_find_doubles(Span mloop, +#ifdef USE_WELD_DEBUG + const Span mpoly, +#endif + const int mvert_len, + MutableSpan r_vlinks, + WeldMesh *r_weld_mesh) +{ + if (r_weld_mesh->poly_kill_len == r_weld_mesh->wpoly.size()) { + return; + } + + WeldPoly *wpoly = r_weld_mesh->wpoly.data(); + MutableSpan wloop = r_weld_mesh->wloop; + Span loop_map = r_weld_mesh->loop_map; + int poly_kill_len = r_weld_mesh->poly_kill_len; + int loop_kill_len = r_weld_mesh->loop_kill_len; + + /* Setup Polygon Overlap. */ + + r_vlinks.fill(0); + + for (const WeldPoly &wp : r_weld_mesh->wpoly) { + WeldLoopOfPolyIter iter; + if (weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr)) { + while (weld_iter_loop_of_poly_next(iter)) { + r_vlinks[iter.v]++; + } + } + } + + int link_len = 0; + for (const int i : IndexRange(mvert_len)) { + link_len += r_vlinks[i]; + r_vlinks[i] = link_len; + } + r_vlinks[mvert_len] = link_len; + + if (link_len) { + Array link_poly_buffer(link_len); + + /* Use a reverse for loop to ensure that indexes are assigned in ascending order. */ + for (int i = r_weld_mesh->wpoly.size(); i--;) { + const WeldPoly &wp = wpoly[i]; + WeldLoopOfPolyIter iter; + if (weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr)) { + while (weld_iter_loop_of_poly_next(iter)) { + link_poly_buffer[--r_vlinks[iter.v]] = i; + } + } + } + + int polys_len_a, polys_len_b, *polys_ctx_a, *polys_ctx_b, p_ctx_a, p_ctx_b; + polys_len_b = p_ctx_b = 0; /* silence warnings */ + + for (const int i : IndexRange(r_weld_mesh->wpoly.size())) { + const WeldPoly &wp = wpoly[i]; + if (wp.poly_dst != OUT_OF_CONTEXT) { + /* No need to retest poly. + * (Already includes collapsed polygons). */ + continue; + } + + WeldLoopOfPolyIter iter; + weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr); + weld_iter_loop_of_poly_next(iter); + const int link_a = r_vlinks[iter.v]; + polys_len_a = r_vlinks[iter.v + 1] - link_a; + if (polys_len_a == 1) { + BLI_assert(link_poly_buffer[link_a] == i); + continue; + } + int wp_loop_len = wp.loop_len; + polys_ctx_a = &link_poly_buffer[link_a]; + for (; polys_len_a--; polys_ctx_a++) { + p_ctx_a = *polys_ctx_a; + if (p_ctx_a == i) { + continue; + } + + WeldPoly *wp_tmp = &wpoly[p_ctx_a]; + if (wp_tmp->loop_len != wp_loop_len) { + continue; + } + + WeldLoopOfPolyIter iter_b = iter; + while (weld_iter_loop_of_poly_next(iter_b)) { + const int link_b = r_vlinks[iter_b.v]; + polys_len_b = r_vlinks[iter_b.v + 1] - link_b; + if (polys_len_b == 1) { + BLI_assert(link_poly_buffer[link_b] == i); + polys_len_b = 0; + break; + } + + polys_ctx_b = &link_poly_buffer[link_b]; + for (; polys_len_b; polys_len_b--, polys_ctx_b++) { + p_ctx_b = *polys_ctx_b; + if (p_ctx_b < p_ctx_a) { + continue; + } + if (p_ctx_b >= p_ctx_a) { + if (p_ctx_b > p_ctx_a) { + polys_len_b = 0; + } + break; + } + } + if (polys_len_b == 0) { + break; + } + } + if (polys_len_b == 0) { + continue; + } + BLI_assert(p_ctx_a > i); + BLI_assert(p_ctx_a == p_ctx_b); + BLI_assert(wp_tmp->poly_dst == OUT_OF_CONTEXT); + BLI_assert(wp_tmp != &wp); + wp_tmp->poly_dst = wp.poly_orig; + loop_kill_len += wp_tmp->loop_len; + poly_kill_len++; + } + } + } + + r_weld_mesh->poly_kill_len = poly_kill_len; + r_weld_mesh->loop_kill_len = loop_kill_len; + +#ifdef USE_WELD_DEBUG + weld_assert_poly_and_loop_kill_len( + r_weld_mesh, mloop, mpoly, r_weld_mesh->poly_kill_len, r_weld_mesh->loop_kill_len); +#endif } /** \} */ @@ -1217,24 +1249,34 @@ static void weld_mesh_context_create(const Mesh &mesh, Array edge_dest_map(edges.size()); Array edge_ctx_map(edges.size()); - Vector wedge = weld_edge_ctx_alloc(edges, vert_dest_map, edge_dest_map, edge_ctx_map); + Vector wedge = weld_edge_ctx_alloc_and_find_collapsed( + edges, vert_dest_map, edge_dest_map, edge_ctx_map, &r_weld_mesh->edge_kill_len); /* Add +1 to allow calculation of the length of the last group. */ Array v_links(mvert_len + 1); - weld_edge_ctx_setup(v_links, edge_dest_map, wedge, &r_weld_mesh->edge_kill_len); + weld_edge_find_doubles(wedge.size() - r_weld_mesh->edge_kill_len, + v_links, + edge_dest_map, + wedge, + &r_weld_mesh->edge_kill_len); weld_poly_loop_ctx_alloc(polys, loops, vert_dest_map, edge_dest_map, r_weld_mesh); - weld_poly_loop_ctx_setup(loops, + weld_poly_loop_ctx_setup_collapsed_and_split(loops, #ifdef USE_WELD_DEBUG - polys, - + polys, #endif - mvert_len, - vert_dest_map, - wedge.size() - r_weld_mesh->edge_kill_len, - v_links, - r_weld_mesh); + vert_dest_map, + wedge.size() - r_weld_mesh->edge_kill_len, + r_weld_mesh); + + weld_poly_find_doubles(loops, +#ifdef USE_WELD_DEBUG + polys, +#endif + mvert_len, + v_links, + r_weld_mesh); weld_vert_groups_setup(wvert, vert_dest_map, From 12a3de96bbc9085748af53f61ac7a9fc6405844f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 19 Jan 2023 17:32:09 +0100 Subject: [PATCH 0774/1522] Fix T103972: crash with cloth simulation rest shape key and subdivision surface --- source/blender/blenkernel/intern/subdiv_mesh.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/subdiv_mesh.cc b/source/blender/blenkernel/intern/subdiv_mesh.cc index dbb58fd73de..dbeefcb1e7b 100644 --- a/source/blender/blenkernel/intern/subdiv_mesh.cc +++ b/source/blender/blenkernel/intern/subdiv_mesh.cc @@ -471,11 +471,11 @@ static void subdiv_vertex_orco_evaluate(const SubdivMeshContext *ctx, if (ctx->orco) { copy_v3_v3(ctx->orco[subdiv_vertex_index], vertex_data); if (ctx->cloth_orco) { - copy_v3_v3(ctx->orco[subdiv_vertex_index], vertex_data + 3); + copy_v3_v3(ctx->cloth_orco[subdiv_vertex_index], vertex_data + 3); } } else if (ctx->cloth_orco) { - copy_v3_v3(ctx->orco[subdiv_vertex_index], vertex_data); + copy_v3_v3(ctx->cloth_orco[subdiv_vertex_index], vertex_data); } } } From 2a41e0822ad8af7aa68ab112cec8557a5b1f64fe Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 11:14:56 -0600 Subject: [PATCH 0775/1522] Fix T103911: Custom property edit gets wrong existing default The array length was wrong for all types after 0e89d2431840386fe9b, and a typo meant that the boolean defaults were assigned to the int defaults. --- release/scripts/startup/bl_operators/wm.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index b8f5fc596c3..cb881ad024e 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1587,8 +1587,9 @@ class WM_OT_properties_edit(Operator): elif self.property_type == 'STRING': self.default_string = rna_data["default"] elif self.property_type in {'BOOL', 'BOOL_ARRAY'}: - self.default_int = self._convert_new_value_array(rna_data["default"], bool, 32) - elif self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}: + self.default_bool = self._convert_new_value_array(rna_data["default"], bool, 32) + + if self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}: self.array_length = len(item[name]) # The dictionary does not contain the description if it was empty. From e7af2503c5f325fdf24ade8a53f31d8409f6e580 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 11:53:32 -0600 Subject: [PATCH 0776/1522] Cleanup: Fix unused variable warning in merge by distance --- .../geometry/intern/mesh_merge_by_distance.cc | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc index 0d1cdf93133..5374a6c08cd 100644 --- a/source/blender/geometry/intern/mesh_merge_by_distance.cc +++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc @@ -1006,13 +1006,14 @@ static void weld_poly_split_recursive(Span vert_dest_map, * done to reduce allocations. * \return r_weld_mesh: Loop and poly members will be configured here. */ -static void weld_poly_loop_ctx_setup_collapsed_and_split(Span mloop, +static void weld_poly_loop_ctx_setup_collapsed_and_split( #ifdef USE_WELD_DEBUG - Span mpoly, + Span mloop, + Span mpoly, #endif - Span vert_dest_map, - const int remain_edge_ctx_len, - WeldMesh *r_weld_mesh) + Span vert_dest_map, + const int remain_edge_ctx_len, + WeldMesh *r_weld_mesh) { if (remain_edge_ctx_len == 0) { r_weld_mesh->poly_kill_len = r_weld_mesh->wpoly.size(); @@ -1262,13 +1263,14 @@ static void weld_mesh_context_create(const Mesh &mesh, weld_poly_loop_ctx_alloc(polys, loops, vert_dest_map, edge_dest_map, r_weld_mesh); - weld_poly_loop_ctx_setup_collapsed_and_split(loops, + weld_poly_loop_ctx_setup_collapsed_and_split( #ifdef USE_WELD_DEBUG - polys, + loops, + polys, #endif - vert_dest_map, - wedge.size() - r_weld_mesh->edge_kill_len, - r_weld_mesh); + vert_dest_map, + wedge.size() - r_weld_mesh->edge_kill_len, + r_weld_mesh); weld_poly_find_doubles(loops, #ifdef USE_WELD_DEBUG From 08b3426df9e5b5dd3c7cc042197bea3ea2398e75 Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Thu, 19 Jan 2023 17:55:53 +0000 Subject: [PATCH 0777/1522] Cycles: Occupancy tuning for new higher end M2 machines This patch adds occupancy tuning for the newly announced high-end M2 machines, giving 10-15% render speedup over a pre-tuned build. Reviewed By: brecht Differential Revision: https://developer.blender.org/D17037 --- intern/cycles/device/metal/kernel.mm | 12 ++++++++++++ intern/cycles/device/metal/queue.mm | 3 ++- intern/cycles/device/metal/util.h | 1 + intern/cycles/device/metal/util.mm | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/intern/cycles/device/metal/kernel.mm b/intern/cycles/device/metal/kernel.mm index e4ce5e19f63..48bdf2f0ef1 100644 --- a/intern/cycles/device/metal/kernel.mm +++ b/intern/cycles/device/metal/kernel.mm @@ -49,6 +49,18 @@ struct ShaderCache { if (MetalInfo::get_device_vendor(mtlDevice) == METAL_GPU_APPLE) { switch (MetalInfo::get_apple_gpu_architecture(mtlDevice)) { default: + case APPLE_M2_BIG: + occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_COMPACT_SHADOW_STATES] = {384, 128}; + occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INIT_FROM_CAMERA] = {640, 128}; + occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INTERSECT_CLOSEST] = {1024, 64}; + occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW] = {704, 704}; + occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INTERSECT_SUBSURFACE] = {640, 32}; + occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_QUEUED_PATHS_ARRAY] = {896, 768}; + occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SHADE_BACKGROUND] = {512, 128}; + occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW] = {32, 32}; + occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE] = {768, 576}; + occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_SORTED_PATHS_ARRAY] = {896, 768}; + break; case APPLE_M2: occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_COMPACT_SHADOW_STATES] = {32, 32}; occupancy_tuning[DEVICE_KERNEL_INTEGRATOR_INIT_FROM_CAMERA] = {832, 32}; diff --git a/intern/cycles/device/metal/queue.mm b/intern/cycles/device/metal/queue.mm index 837be0b0c23..f335844c3f9 100644 --- a/intern/cycles/device/metal/queue.mm +++ b/intern/cycles/device/metal/queue.mm @@ -278,7 +278,8 @@ int MetalDeviceQueue::num_concurrent_states(const size_t state_size) const if (metal_device_->device_vendor == METAL_GPU_APPLE) { result *= 4; - if (MetalInfo::get_apple_gpu_architecture(metal_device_->mtlDevice) == APPLE_M2) { + /* Increasing the state count doesn't notably benefit M1-family systems. */ + if (MetalInfo::get_apple_gpu_architecture(metal_device_->mtlDevice) != APPLE_M1) { size_t system_ram = system_physical_ram(); size_t allocated_so_far = [metal_device_->mtlDevice currentAllocatedSize]; size_t max_recommended_working_set = [metal_device_->mtlDevice recommendedMaxWorkingSetSize]; diff --git a/intern/cycles/device/metal/util.h b/intern/cycles/device/metal/util.h index a988d01d361..c30c4ccd9bc 100644 --- a/intern/cycles/device/metal/util.h +++ b/intern/cycles/device/metal/util.h @@ -29,6 +29,7 @@ enum AppleGPUArchitecture { APPLE_UNKNOWN, APPLE_M1, APPLE_M2, + APPLE_M2_BIG, }; /* Contains static Metal helper functions. */ diff --git a/intern/cycles/device/metal/util.mm b/intern/cycles/device/metal/util.mm index f47638fac15..984e7a70c76 100644 --- a/intern/cycles/device/metal/util.mm +++ b/intern/cycles/device/metal/util.mm @@ -52,7 +52,7 @@ AppleGPUArchitecture MetalInfo::get_apple_gpu_architecture(id device) return APPLE_M1; } else if (strstr(device_name, "M2")) { - return APPLE_M2; + return get_apple_gpu_core_count(device) <= 10 ? APPLE_M2 : APPLE_M2_BIG; } return APPLE_UNKNOWN; } From e270a198a548fcacc9dfecbda29c55fe7a05b5c9 Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Thu, 19 Jan 2023 17:57:26 +0000 Subject: [PATCH 0778/1522] Cycles: Markup to disable specialisation of kernel data fields (Metal) This patch adds markup to specify that certain kernel data constants should not be specialised. Currently it is used for `tabulated_sobol_sequence_size` and `sobol_index_mask` which change frequently based on the aa sample count, trash the shader cache, and have little bearing on performance. Reviewed By: brecht Differential Revision: https://developer.blender.org/D16968 --- intern/cycles/device/metal/device_impl.mm | 13 +++++++++++-- intern/cycles/device/metal/kernel.mm | 12 ++++++++---- intern/cycles/kernel/data_template.h | 8 ++++++-- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm index 87614f656c3..917945fbdb6 100644 --- a/intern/cycles/device/metal/device_impl.mm +++ b/intern/cycles/device/metal/device_impl.mm @@ -327,10 +327,19 @@ void MetalDevice::make_source(MetalPipelineType pso_type, const uint kernel_feat # define KERNEL_STRUCT_BEGIN(name, parent) \ string_replace_same_length(source, "kernel_data." #parent ".", "kernel_data_" #parent "_"); + bool next_member_is_specialized = true; + +# define KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE next_member_is_specialized = false; + /* Add constants to md5 so that 'get_best_pipeline' is able to return a suitable match. */ # define KERNEL_STRUCT_MEMBER(parent, _type, name) \ - baked_constants += string(#parent "." #name "=") + \ - to_string(_type(launch_params.data.parent.name)) + "\n"; + if (next_member_is_specialized) { \ + baked_constants += string(#parent "." #name "=") + \ + to_string(_type(launch_params.data.parent.name)) + "\n"; \ + } else { \ + string_replace(source, "kernel_data_" #parent "_" #name, "kernel_data." #parent ".__unused_" #name); \ + next_member_is_specialized = true; \ + } # include "kernel/data_template.h" diff --git a/intern/cycles/device/metal/kernel.mm b/intern/cycles/device/metal/kernel.mm index 48bdf2f0ef1..febce2840ea 100644 --- a/intern/cycles/device/metal/kernel.mm +++ b/intern/cycles/device/metal/kernel.mm @@ -460,13 +460,17 @@ static MTLFunctionConstantValues *GetConstantValues(KernelData const *data = nul if (!data) { data = &zero_data; } - int zero_int = 0; - [constant_values setConstantValue:&zero_int type:MTLDataType_int atIndex:Kernel_DummyConstant]; + [constant_values setConstantValue:&zero_data type:MTLDataType_int atIndex:Kernel_DummyConstant]; + + bool next_member_is_specialized = true; + +# define KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE next_member_is_specialized = false; # define KERNEL_STRUCT_MEMBER(parent, _type, name) \ - [constant_values setConstantValue:&data->parent.name \ + [constant_values setConstantValue:next_member_is_specialized ? (void*)&data->parent.name : (void*)&zero_data \ type:MTLDataType_##_type \ - atIndex:KernelData_##parent##_##name]; + atIndex:KernelData_##parent##_##name]; \ + next_member_is_specialized = true; # include "kernel/data_template.h" diff --git a/intern/cycles/kernel/data_template.h b/intern/cycles/kernel/data_template.h index ddc462e02f6..dceae4b77c1 100644 --- a/intern/cycles/kernel/data_template.h +++ b/intern/cycles/kernel/data_template.h @@ -10,6 +10,10 @@ #ifndef KERNEL_STRUCT_MEMBER # define KERNEL_STRUCT_MEMBER(parent, type, name) #endif +#ifndef KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE +# define KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE +#endif + /* Background. */ @@ -179,8 +183,8 @@ KERNEL_STRUCT_MEMBER(integrator, float, sample_clamp_indirect) KERNEL_STRUCT_MEMBER(integrator, int, use_caustics) /* Sampling pattern. */ KERNEL_STRUCT_MEMBER(integrator, int, sampling_pattern) -KERNEL_STRUCT_MEMBER(integrator, int, tabulated_sobol_sequence_size) -KERNEL_STRUCT_MEMBER(integrator, int, sobol_index_mask) +KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE KERNEL_STRUCT_MEMBER(integrator, int, tabulated_sobol_sequence_size) +KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE KERNEL_STRUCT_MEMBER(integrator, int, sobol_index_mask) KERNEL_STRUCT_MEMBER(integrator, float, scrambling_distance) /* Volume render. */ KERNEL_STRUCT_MEMBER(integrator, int, use_volumes) From 9066f2e0437a45d66f3b6a4bb0de7acf5ec40030 Mon Sep 17 00:00:00 2001 From: Patrick Mours Date: Wed, 18 Jan 2023 17:28:03 +0100 Subject: [PATCH 0779/1522] Cycles: Add support for OSL texture intrinsic on the GPU This makes it possible to use `texture` and `texture3d` in custom OSL shaders with a constant image file name as argument on the GPU, where previously texturing was only possible through Cycles nodes. For constant file name arguments, OSL calls `OSL::RendererServices::get_texture_handle()` with the file name string to convert it into an opaque handle for use on the GPU. That is now used to load the respective image file using the Cycles image manager and generate a SVM handle that can be used on the GPU. Some care is necessary as the renderer services class is shared across multiple Cycles instances, whereas the Cycles image manager is local to each. Maniphest Tasks: T101222 Differential Revision: https://developer.blender.org/D17032 --- intern/cycles/kernel/osl/services.cpp | 54 ++++++++++++++--- intern/cycles/kernel/osl/services.h | 14 +++++ intern/cycles/kernel/osl/services_gpu.h | 81 ++++++++++++++----------- intern/cycles/kernel/osl/types.h | 15 +++-- intern/cycles/kernel/svm/ies.h | 2 + intern/cycles/scene/image.cpp | 5 ++ intern/cycles/scene/image.h | 2 + intern/cycles/scene/osl.cpp | 26 ++++++++ 8 files changed, 152 insertions(+), 47 deletions(-) diff --git a/intern/cycles/kernel/osl/services.cpp b/intern/cycles/kernel/osl/services.cpp index 95d58875b91..92708df3162 100644 --- a/intern/cycles/kernel/osl/services.cpp +++ b/intern/cycles/kernel/osl/services.cpp @@ -20,6 +20,7 @@ #include "kernel/osl/globals.h" #include "kernel/osl/services.h" +#include "kernel/osl/types.h" #include "util/foreach.h" #include "util/log.h" @@ -119,6 +120,8 @@ ustring OSLRenderServices::u_u("u"); ustring OSLRenderServices::u_v("v"); ustring OSLRenderServices::u_empty; +ImageManager *OSLRenderServices::image_manager = nullptr; + OSLRenderServices::OSLRenderServices(OSL::TextureSystem *texture_system, int device_type) : OSL::RendererServices(texture_system), device_type_(device_type) { @@ -1154,7 +1157,7 @@ TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(ustring file /* For non-OIIO textures, just return a pointer to our own OSLTextureHandle. */ if (it != textures.end()) { if (it->second->type != OSLTextureHandle::OIIO) { - return (TextureSystem::TextureHandle *)it->second.get(); + return reinterpret_cast(it->second.get()); } } @@ -1173,16 +1176,53 @@ TextureSystem::TextureHandle *OSLRenderServices::get_texture_handle(ustring file /* Assign OIIO texture handle and return. */ it->second->oiio_handle = handle; - return (TextureSystem::TextureHandle *)it->second.get(); + return reinterpret_cast(it->second.get()); } else { - if (it != textures.end() && it->second->type == OSLTextureHandle::SVM && - it->second->svm_slots[0].w == -1) { - return reinterpret_cast( - static_cast(it->second->svm_slots[0].y + 1)); + /* Construct GPU texture handle for existing textures. */ + if (it != textures.end()) { + switch (it->second->type) { + case OSLTextureHandle::OIIO: + return NULL; + case OSLTextureHandle::SVM: + if (!it->second->handle.empty() && it->second->handle.get_manager() != image_manager) { + it.clear(); + break; + } + return reinterpret_cast(OSL_TEXTURE_HANDLE_TYPE_SVM | + it->second->svm_slots[0].y); + case OSLTextureHandle::IES: + if (!it->second->handle.empty() && it->second->handle.get_manager() != image_manager) { + it.clear(); + break; + } + return reinterpret_cast(OSL_TEXTURE_HANDLE_TYPE_IES | + it->second->svm_slots[0].y); + case OSLTextureHandle::AO: + return reinterpret_cast( + OSL_TEXTURE_HANDLE_TYPE_AO_OR_BEVEL | 1); + case OSLTextureHandle::BEVEL: + return reinterpret_cast( + OSL_TEXTURE_HANDLE_TYPE_AO_OR_BEVEL | 2); + } } - return NULL; + if (!image_manager) { + return NULL; + } + + /* Load new textures using SVM image manager. */ + ImageHandle handle = image_manager->add_image(filename.string(), ImageParams()); + if (handle.empty()) { + return NULL; + } + + if (!textures.insert(filename, new OSLTextureHandle(handle))) { + return NULL; + } + + return reinterpret_cast(OSL_TEXTURE_HANDLE_TYPE_SVM | + handle.svm_slot()); } } diff --git a/intern/cycles/kernel/osl/services.h b/intern/cycles/kernel/osl/services.h index 9d875ae8e94..747eb242d8c 100644 --- a/intern/cycles/kernel/osl/services.h +++ b/intern/cycles/kernel/osl/services.h @@ -16,6 +16,8 @@ #include #include +#include "scene/image.h" + #ifdef WITH_PTEX class PtexCache; #endif @@ -54,10 +56,20 @@ struct OSLTextureHandle : public OIIO::RefCnt { { } + OSLTextureHandle(const ImageHandle &handle) + : type(SVM), + svm_slots(handle.get_svm_slots()), + oiio_handle(nullptr), + processor(nullptr), + handle(handle) + { + } + Type type; vector svm_slots; OSL::TextureSystem::TextureHandle *oiio_handle; ColorSpaceProcessor *processor; + ImageHandle handle; }; typedef OIIO::intrusive_ptr OSLTextureHandleRef; @@ -324,6 +336,8 @@ class OSLRenderServices : public OSL::RendererServices { * shading system. */ OSLTextureHandleMap textures; + static ImageManager *image_manager; + private: int device_type_; }; diff --git a/intern/cycles/kernel/osl/services_gpu.h b/intern/cycles/kernel/osl/services_gpu.h index b9ffd959f1a..2fa4299d3f9 100644 --- a/intern/cycles/kernel/osl/services_gpu.h +++ b/intern/cycles/kernel/osl/services_gpu.h @@ -1443,6 +1443,8 @@ OSL_NOISE_IMPL(osl_snoise, snoise) /* Texturing */ +#include "kernel/svm/ies.h" + ccl_device_extern ccl_private OSLTextureOptions *osl_get_texture_options( ccl_private ShaderGlobals *sg) { @@ -1548,25 +1550,31 @@ ccl_device_extern bool osl_texture(ccl_private ShaderGlobals *sg, ccl_private float *dalphady, ccl_private void *errormessage) { - if (!texture_handle) { - return false; + const unsigned int type = OSL_TEXTURE_HANDLE_TYPE(texture_handle); + const unsigned int slot = OSL_TEXTURE_HANDLE_SLOT(texture_handle); + + switch (type) { + case OSL_TEXTURE_HANDLE_TYPE_SVM: { + const float4 rgba = kernel_tex_image_interp(nullptr, slot, s, 1.0f - t); + if (nchannels > 0) + result[0] = rgba.x; + if (nchannels > 1) + result[1] = rgba.y; + if (nchannels > 2) + result[2] = rgba.z; + if (alpha) + *alpha = rgba.w; + return true; + } + case OSL_TEXTURE_HANDLE_TYPE_IES: { + if (nchannels > 0) + result[0] = kernel_ies_interp(nullptr, slot, s, t); + return true; + } + default: { + return false; + } } - - /* Only SVM textures are supported. */ - int id = static_cast(reinterpret_cast(texture_handle) - 1); - - const float4 rgba = kernel_tex_image_interp(nullptr, id, s, 1.0f - t); - - if (nchannels > 0) - result[0] = rgba.x; - if (nchannels > 1) - result[1] = rgba.y; - if (nchannels > 2) - result[2] = rgba.z; - if (alpha) - *alpha = rgba.w; - - return true; } ccl_device_extern bool osl_texture3d(ccl_private ShaderGlobals *sg, @@ -1586,25 +1594,26 @@ ccl_device_extern bool osl_texture3d(ccl_private ShaderGlobals *sg, ccl_private float *dalphady, ccl_private void *errormessage) { - if (!texture_handle) { - return false; + const unsigned int type = OSL_TEXTURE_HANDLE_TYPE(texture_handle); + const unsigned int slot = OSL_TEXTURE_HANDLE_SLOT(texture_handle); + + switch (type) { + case OSL_TEXTURE_HANDLE_TYPE_SVM: { + const float4 rgba = kernel_tex_image_interp_3d(nullptr, slot, *P, INTERPOLATION_NONE); + if (nchannels > 0) + result[0] = rgba.x; + if (nchannels > 1) + result[1] = rgba.y; + if (nchannels > 2) + result[2] = rgba.z; + if (alpha) + *alpha = rgba.w; + return true; + } + default: { + return false; + } } - - /* Only SVM textures are supported. */ - int id = static_cast(reinterpret_cast(texture_handle) - 1); - - const float4 rgba = kernel_tex_image_interp_3d(nullptr, id, *P, INTERPOLATION_NONE); - - if (nchannels > 0) - result[0] = rgba.x; - if (nchannels > 1) - result[1] = rgba.y; - if (nchannels > 2) - result[2] = rgba.z; - if (alpha) - *alpha = rgba.w; - - return true; } ccl_device_extern bool osl_environment(ccl_private ShaderGlobals *sg, diff --git a/intern/cycles/kernel/osl/types.h b/intern/cycles/kernel/osl/types.h index 692c2349a30..528f07ad58c 100644 --- a/intern/cycles/kernel/osl/types.h +++ b/intern/cycles/kernel/osl/types.h @@ -90,10 +90,17 @@ struct ShaderGlobals { int backfacing; }; -struct OSLNoiseOptions { -}; +struct OSLNoiseOptions {}; -struct OSLTextureOptions { -}; +struct OSLTextureOptions {}; + +#define OSL_TEXTURE_HANDLE_TYPE_IES ((uintptr_t)0x2 << 30) +#define OSL_TEXTURE_HANDLE_TYPE_SVM ((uintptr_t)0x1 << 30) +#define OSL_TEXTURE_HANDLE_TYPE_AO_OR_BEVEL ((uintptr_t)0x3 << 30) + +#define OSL_TEXTURE_HANDLE_TYPE(handle) \ + ((unsigned int)((uintptr_t)(handle) & ((uintptr_t)0x3 << 30))) +#define OSL_TEXTURE_HANDLE_SLOT(handle) \ + ((unsigned int)((uintptr_t)(handle) & ((uintptr_t)0x3FFFFFFF))) CCL_NAMESPACE_END diff --git a/intern/cycles/kernel/svm/ies.h b/intern/cycles/kernel/svm/ies.h index 3648cb580d5..b40e04df62c 100644 --- a/intern/cycles/kernel/svm/ies.h +++ b/intern/cycles/kernel/svm/ies.h @@ -84,6 +84,7 @@ ccl_device_inline float kernel_ies_interp(KernelGlobals kg, int slot, float h_an return max(cubic_interp(a, b, c, d, h_frac), 0.0f); } +#ifdef __SVM__ ccl_device_noinline void svm_node_ies(KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, @@ -105,5 +106,6 @@ ccl_device_noinline void svm_node_ies(KernelGlobals kg, stack_store_float(stack, fac_offset, fac); } } +#endif CCL_NAMESPACE_END diff --git a/intern/cycles/scene/image.cpp b/intern/cycles/scene/image.cpp index a5c794bc762..925583f88b5 100644 --- a/intern/cycles/scene/image.cpp +++ b/intern/cycles/scene/image.cpp @@ -222,6 +222,11 @@ VDBImageLoader *ImageHandle::vdb_loader(const int tile_index) const return NULL; } +ImageManager *ImageHandle::get_manager() const +{ + return manager; +} + bool ImageHandle::operator==(const ImageHandle &other) const { return manager == other.manager && tile_slots == other.tile_slots; diff --git a/intern/cycles/scene/image.h b/intern/cycles/scene/image.h index da47d8144bc..36bfe17a69d 100644 --- a/intern/cycles/scene/image.h +++ b/intern/cycles/scene/image.h @@ -153,6 +153,8 @@ class ImageHandle { VDBImageLoader *vdb_loader(const int tile_index = 0) const; + ImageManager *get_manager() const; + protected: vector tile_slots; ImageManager *manager; diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp index 9afd6577b10..335e72bec40 100644 --- a/intern/cycles/scene/osl.cpp +++ b/intern/cycles/scene/osl.cpp @@ -184,9 +184,19 @@ void OSLShaderManager::device_update_specific(Device *device, * is being freed after the Session is freed. */ thread_scoped_lock lock(ss_shared_mutex); + + /* Set current image manager during the lock, so that there is no conflict with other shader + * manager instances. + * + * It is used in "OSLRenderServices::get_texture_handle" called during optimization below to + * load images for the GPU. */ + OSLRenderServices::image_manager = scene->image_manager; + for (const auto &[device_type, ss] : ss_shared) { ss->optimize_all_groups(); } + + OSLRenderServices::image_manager = nullptr; } /* load kernels */ @@ -213,6 +223,22 @@ void OSLShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *s og->bump_state.clear(); og->background_state.reset(); }); + + /* Remove any textures specific to an image manager from shared render services textures, since + * the image manager may get destroyed next. */ + for (const auto &[device_type, ss] : ss_shared) { + OSLRenderServices *services = static_cast(ss->renderer()); + + for (auto it = services->textures.begin(); it != services->textures.end(); ++it) { + if (it->second->handle.get_manager() == scene->image_manager) { + /* Don't lock again, since the iterator already did so. */ + services->textures.erase(it->first, false); + it.clear(); + /* Iterator was invalidated, start from the beginning again. */ + it = services->textures.begin(); + } + } + } } void OSLShaderManager::texture_system_init() From fa67b84c348b36fdc25da11c428738e9f1f8a860 Mon Sep 17 00:00:00 2001 From: Nate Rupsis Date: Thu, 19 Jan 2023 13:42:23 -0500 Subject: [PATCH 0780/1522] NLA: Udating Blend-in and Blend-out values to clamp on NLA strip Transform Previously, transforming a clip (scaling, repeat, etc) wouldn't re-calculate the blend-in and blend-out values, leading to over / undershoot, and a visual clip artifact Old: {F14045003} This patch adds re-calculation logic (new `BKE_nlastrip_recalculate_blend()` method) to the blend-in/out on transformations to clamp values, and avoid over/under shoot. The `BKE_nlastrip_recalculate_blend()` encapsulates the existing logic for both the `rna_NlaStrip_blend_in_set()` and `rna_NlaStrip_blend_out_set()` methods into a single BKE method that we an execute as needed. The fact that blend-in is first decreased, is strictly on the order of calculation. My suspicion is that //if// the blend-in / blend-our values were working as intended, the RNA set methods would update in order, and we'd experience the same thing. In short, the choice here was to linearly combine the logic, without making any assumptions of my own. while talking things over with @sybren and @RiggingDojo, they are fine with how this currently works, but there a desire to update how the two values interact with each (ratio scale, etc) in the future. New: {F14045024} {F14045025} Reviewed By: sybren Maniphest Tasks: T101369 Differential Revision: https://developer.blender.org/D16720 --- source/blender/blenkernel/BKE_nla.h | 7 +++ source/blender/blenkernel/CMakeLists.txt | 3 +- source/blender/blenkernel/intern/nla.c | 25 +++++++++++ source/blender/blenkernel/intern/nla_test.cc | 45 ++++++++++++++++++++ source/blender/makesrna/intern/rna_nla.c | 2 + 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 source/blender/blenkernel/intern/nla_test.cc diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h index 41980999a18..3d304859e1b 100644 --- a/source/blender/blenkernel/BKE_nla.h +++ b/source/blender/blenkernel/BKE_nla.h @@ -10,6 +10,8 @@ /** Temp constant defined for these functions only. */ #define NLASTRIP_MIN_LEN_THRESH 0.1f +#include "DNA_listBase.h" + #ifdef __cplusplus extern "C" { #endif @@ -295,6 +297,11 @@ void BKE_nlastrip_recalculate_bounds(struct NlaStrip *strip); */ void BKE_nlastrip_recalculate_bounds_sync_action(struct NlaStrip *strip); +/** + * Recalculate the Blendin and Blendout values after a strip transform update. + */ +void BKE_nlastrip_recalculate_blend(struct NlaStrip *strip); + /** * Find (and set) a unique name for a strip from the whole AnimData block * Uses a similar method to the BLI method, but is implemented differently diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 8a3c6877787..70da6b22672 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -837,6 +837,7 @@ if(WITH_GTESTS) intern/lib_id_remapper_test.cc intern/lib_id_test.cc intern/lib_remap_test.cc + intern/nla_test.cc intern/tracking_test.cc ) set(TEST_INC @@ -847,4 +848,4 @@ if(WITH_GTESTS) # RNA_prototypes.h add_dependencies(bf_blenkernel_tests bf_rna) -endif() +endif() \ No newline at end of file diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 5cdfe98f2e0..1ff7fc21b01 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -1521,6 +1521,30 @@ void BKE_nlastrip_recalculate_bounds(NlaStrip *strip) nlastrip_fix_resize_overlaps(strip); } +void BKE_nlastrip_recalculate_blend(NlaStrip *strip) +{ + + /* check if values need to be re-calculated. */ + if (strip->blendin == 0 && strip->blendout == 0) { + return; + } + + const double strip_len = strip->end - strip->start; + double blend_in = strip->blendin; + double blend_out = strip->blendout; + + double blend_in_max = strip_len - blend_out; + + CLAMP_MIN(blend_in_max, 0); + + /* blend-out is limited to the length of the strip. */ + CLAMP(blend_in, 0, blend_in_max); + CLAMP(blend_out, 0, strip_len - blend_in); + + strip->blendin = blend_in; + strip->blendout = blend_out; +} + /* Animated Strips ------------------------------------------- */ bool BKE_nlatrack_has_animated_strips(NlaTrack *nlt) @@ -1854,6 +1878,7 @@ void BKE_nla_validate_state(AnimData *adt) for (strip = nlt->strips.first; strip; strip = strip->next) { /* auto-blending first */ BKE_nlastrip_validate_autoblends(nlt, strip); + BKE_nlastrip_recalculate_blend(strip); } } } diff --git a/source/blender/blenkernel/intern/nla_test.cc b/source/blender/blenkernel/intern/nla_test.cc new file mode 100644 index 00000000000..e6875fff1ce --- /dev/null +++ b/source/blender/blenkernel/intern/nla_test.cc @@ -0,0 +1,45 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 Blender Foundation. All rights reserved. */ + +#include "BKE_nla.h" + +#include "DNA_nla_types.h" +#include "DNA_anim_types.h" + +#include "MEM_guardedalloc.h" + +#include "testing/testing.h" + + +namespace blender::bke::tests { + +TEST(nla_strip, BKE_nlastrip_recalculate_blend) +{ + + NlaStrip strip = { + .blendin = 4.0, + .blendout = 5.0, + .start = 1, + .end = 10 + }; + + /* Scaling a strip up doesn't affect the blend in/out value */ + strip.end = 20; + BKE_nlastrip_recalculate_blend(&strip); + EXPECT_FLOAT_EQ(strip.blendin, 4.0); + EXPECT_FLOAT_EQ(strip.blendout, 5.0); + + /* Scaling a strip down affects the blend-in value before the blend-out value */ + strip.end = 7; + BKE_nlastrip_recalculate_blend(&strip); + EXPECT_FLOAT_EQ(strip.blendin, 1.0); + EXPECT_FLOAT_EQ(strip.blendout, 5.0); + + /* Scaling a strip down to nothing updates the blend in/out values accordingly */ + strip.end = 1.1; + BKE_nlastrip_recalculate_blend(&strip); + EXPECT_FLOAT_EQ(strip.blendin, 0.0); + EXPECT_FLOAT_EQ(strip.blendout, 0.1); +} + +} // namespace blender::bke::tests diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index a61f6fb8c2e..3d8b5159323 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -157,6 +157,8 @@ static void rna_NlaStrip_transform_update(Main *bmain, Scene *scene, PointerRNA } } + BKE_nlastrip_recalculate_blend(strip); + rna_NlaStrip_update(bmain, scene, ptr); } From f71bfe465538e6add595804f14fa2731fc8f7b64 Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Thu, 19 Jan 2023 20:02:35 +0100 Subject: [PATCH 0781/1522] Fix anisotropic Beckmann regression test failing on Metal The lookup table method on CPU and the numerical root finding method on GPU give quite different results. This commit deletes the Beckmann lookup table and uses numerical root finding on all devices. For the numerical root finding, a combined bisection-Newton method with precision control is used. Differential Revision: https://developer.blender.org/D17050 --- .../cycles/kernel/closure/bsdf_microfacet.h | 55 ++++---- intern/cycles/kernel/types.h | 5 +- intern/cycles/scene/shader.cpp | 128 ------------------ intern/cycles/scene/shader.h | 4 - release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- 6 files changed, 30 insertions(+), 166 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 25238698614..83051f08f40 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -71,7 +71,6 @@ ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals kg, *G1i = G1; -#if defined(__KERNEL_GPU__) /* Based on paper from Wenzel Jakob * An Improved Visible Normal Sampling Routine for the Beckmann Distribution * @@ -87,38 +86,38 @@ ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals kg, * exp(-ierf(x)^2) ~= 1 - x * x * solve y = 1 + b + K * (1 - b * b) */ - float K = tan_theta_i * SQRT_PI_INV; - float y_approx = randu * (1.0f + erf_a + K * (1 - erf_a * erf_a)); - float y_exact = randu * (1.0f + erf_a + K * exp_a2); + const float K = tan_theta_i * SQRT_PI_INV; + const float y_approx = randu * (1.0f + erf_a + K * (1 - erf_a * erf_a)); + const float y_exact = randu * (1.0f + erf_a + K * exp_a2); float b = K > 0 ? (0.5f - sqrtf(K * (K - y_approx + 1.0f) + 0.25f)) / K : y_approx - 1.0f; - /* Perform newton step to refine toward the true root. */ float inv_erf = fast_ierff(b); - float value = 1.0f + b + K * expf(-inv_erf * inv_erf) - y_exact; - /* Check if we are close enough already, - * this also avoids NaNs as we get close to the root. - */ - if (fabsf(value) > 1e-6f) { - b -= value / (1.0f - inv_erf * tan_theta_i); /* newton step 1. */ - inv_erf = fast_ierff(b); - value = 1.0f + b + K * expf(-inv_erf * inv_erf) - y_exact; - b -= value / (1.0f - inv_erf * tan_theta_i); /* newton step 2. */ - /* Compute the slope from the refined value. */ - *slope_x = fast_ierff(b); - } - else { - /* We are close enough already. */ - *slope_x = inv_erf; - } - *slope_y = fast_ierff(2.0f * randv - 1.0f); -#else - /* Use precomputed table on CPU, it gives better performance. */ - int beckmann_table_offset = kernel_data.tables.beckmann_offset; + float2 begin = make_float2(-1.0f, -y_exact); + float2 end = make_float2(erf_a, 1.0f + erf_a + K * exp_a2 - y_exact); + float2 current = make_float2(b, 1.0f + b + K * expf(-sqr(inv_erf)) - y_exact); - *slope_x = lookup_table_read_2D( - kg, randu, cos_theta_i, beckmann_table_offset, BECKMANN_TABLE_SIZE, BECKMANN_TABLE_SIZE); + /* Find root in a monotonic interval using newton method, under given precision and maximal + * iterations. Falls back to bisection if newton step produces results outside of the valid + * interval.*/ + const float precision = 1e-6f; + const int max_iter = 3; + int iter = 0; + while (fabsf(current.y) > precision && iter++ < max_iter) { + if (signf(begin.y) == signf(current.y)) { + begin.x = current.x; + begin.y = current.y; + } + else { + end.x = current.x; + } + const float newton_x = current.x - current.y / (1.0f - inv_erf * tan_theta_i); + current.x = (newton_x >= begin.x && newton_x <= end.x) ? newton_x : 0.5f * (begin.x + end.x); + inv_erf = fast_ierff(current.x); + current.y = 1.0f + current.x + K * expf(-sqr(inv_erf)) - y_exact; + } + + *slope_x = inv_erf; *slope_y = fast_ierff(2.0f * randv - 1.0f); -#endif } /* GGX microfacet importance sampling from: diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 72a9c65f303..4075980076f 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -34,8 +34,6 @@ CCL_NAMESPACE_BEGIN #define VOLUME_BOUNDS_MAX 1024 -#define BECKMANN_TABLE_SIZE 256 - #define SHADER_NONE (~0) #define OBJECT_NONE (~0) #define PRIM_NONE (~0) @@ -1187,9 +1185,8 @@ typedef enum KernelBVHLayout { #include "kernel/data_template.h" typedef struct KernelTables { - int beckmann_offset; int filter_table_offset; - int pad1, pad2; + int pad1, pad2, pad3; } KernelTables; static_assert_align(KernelTables, 16); diff --git a/intern/cycles/scene/shader.cpp b/intern/cycles/scene/shader.cpp index e03b77917ef..f0faa91b4be 100644 --- a/intern/cycles/scene/shader.cpp +++ b/intern/cycles/scene/shader.cpp @@ -32,114 +32,6 @@ namespace OCIO = OCIO_NAMESPACE; CCL_NAMESPACE_BEGIN thread_mutex ShaderManager::lookup_table_mutex; -vector ShaderManager::beckmann_table; -bool ShaderManager::beckmann_table_ready = false; - -/* Beckmann sampling precomputed table, see bsdf_microfacet.h */ - -/* 2D slope distribution (alpha = 1.0) */ -static float beckmann_table_P22(const float slope_x, const float slope_y) -{ - return expf(-(slope_x * slope_x + slope_y * slope_y)); -} - -/* maximal slope amplitude (range that contains 99.99% of the distribution) */ -static float beckmann_table_slope_max() -{ - return 6.0; -} - -/* MSVC 2015 needs this ugly hack to prevent a codegen bug on x86 - * see T50176 for details - */ -#if defined(_MSC_VER) && (_MSC_VER == 1900) -# define MSVC_VOLATILE volatile -#else -# define MSVC_VOLATILE -#endif - -/* Paper used: Importance Sampling Microfacet-Based BSDFs with the - * Distribution of Visible Normals. Supplemental Material 2/2. - * - * http://hal.inria.fr/docs/01/00/66/20/ANNEX/supplemental2.pdf - */ -static void beckmann_table_rows(float *table, int row_from, int row_to) -{ - /* allocate temporary data */ - const int DATA_TMP_SIZE = 512; - vector slope_x(DATA_TMP_SIZE); - vector CDF_P22_omega_i(DATA_TMP_SIZE); - - /* loop over incident directions */ - for (int index_theta = row_from; index_theta < row_to; index_theta++) { - /* incident vector */ - const float cos_theta = index_theta / (BECKMANN_TABLE_SIZE - 1.0f); - const float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta); - - /* for a given incident vector - * integrate P22_{omega_i}(x_slope, 1, 1), Eq. (10) */ - slope_x[0] = (double)-beckmann_table_slope_max(); - CDF_P22_omega_i[0] = 0; - - for (MSVC_VOLATILE int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x) { - /* slope_x */ - slope_x[index_slope_x] = (double)(-beckmann_table_slope_max() + - 2.0f * beckmann_table_slope_max() * index_slope_x / - (DATA_TMP_SIZE - 1.0f)); - - /* dot product with incident vector */ - float dot_product = fmaxf(0.0f, -(float)slope_x[index_slope_x] * sin_theta + cos_theta); - /* marginalize P22_{omega_i}(x_slope, 1, 1), Eq. (10) */ - float P22_omega_i = 0.0f; - - for (int j = 0; j < 100; ++j) { - float slope_y = -beckmann_table_slope_max() + - 2.0f * beckmann_table_slope_max() * j * (1.0f / 99.0f); - P22_omega_i += dot_product * beckmann_table_P22((float)slope_x[index_slope_x], slope_y); - } - - /* CDF of P22_{omega_i}(x_slope, 1, 1), Eq. (10) */ - CDF_P22_omega_i[index_slope_x] = CDF_P22_omega_i[index_slope_x - 1] + (double)P22_omega_i; - } - - /* renormalize CDF_P22_omega_i */ - for (int index_slope_x = 1; index_slope_x < DATA_TMP_SIZE; ++index_slope_x) - CDF_P22_omega_i[index_slope_x] /= CDF_P22_omega_i[DATA_TMP_SIZE - 1]; - - /* loop over random number U1 */ - int index_slope_x = 0; - - for (int index_U = 0; index_U < BECKMANN_TABLE_SIZE; ++index_U) { - const double U = 0.0000001 + 0.9999998 * index_U / (double)(BECKMANN_TABLE_SIZE - 1); - - /* inverse CDF_P22_omega_i, solve Eq.(11) */ - while (CDF_P22_omega_i[index_slope_x] <= U) - ++index_slope_x; - - const double interp = (CDF_P22_omega_i[index_slope_x] - U) / - (CDF_P22_omega_i[index_slope_x] - CDF_P22_omega_i[index_slope_x - 1]); - - /* store value */ - table[index_U + index_theta * BECKMANN_TABLE_SIZE] = - (float)(interp * slope_x[index_slope_x - 1] + (1.0 - interp) * slope_x[index_slope_x]); - } - } -} - -#undef MSVC_VOLATILE - -static void beckmann_table_build(vector &table) -{ - table.resize(BECKMANN_TABLE_SIZE * BECKMANN_TABLE_SIZE); - - /* multithreaded build */ - TaskPool pool; - - for (int i = 0; i < BECKMANN_TABLE_SIZE; i += 8) - pool.push(function_bind(&beckmann_table_rows, &table[0], i, i + 8)); - - pool.wait_work(); -} /* Shader */ @@ -491,7 +383,6 @@ bool Shader::need_update_geometry() const ShaderManager::ShaderManager() { update_flags = UPDATE_ALL; - beckmann_table_offset = TABLE_OFFSET_INVALID; init_xyz_transforms(); } @@ -663,22 +554,6 @@ void ShaderManager::device_update_common(Device * /*device*/, dscene->shaders.copy_to_device(); - /* lookup tables */ - KernelTables *ktables = &dscene->data.tables; - - /* beckmann lookup table */ - if (beckmann_table_offset == TABLE_OFFSET_INVALID) { - if (!beckmann_table_ready) { - thread_scoped_lock lock(lookup_table_mutex); - if (!beckmann_table_ready) { - beckmann_table_build(beckmann_table); - beckmann_table_ready = true; - } - } - beckmann_table_offset = scene->lookup_tables->add_table(dscene, beckmann_table); - } - ktables->beckmann_offset = (int)beckmann_table_offset; - /* integrator */ KernelIntegrator *kintegrator = &dscene->data.integrator; kintegrator->use_volumes = has_volumes; @@ -700,8 +575,6 @@ void ShaderManager::device_update_common(Device * /*device*/, void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene) { - scene->lookup_tables->remove_table(&beckmann_table_offset); - dscene->shaders.free(); } @@ -844,7 +717,6 @@ uint ShaderManager::get_kernel_features(Scene *scene) void ShaderManager::free_memory() { - beckmann_table.free_memory(); #ifdef WITH_OSL OSLShaderManager::free_memory(); diff --git a/intern/cycles/scene/shader.h b/intern/cycles/scene/shader.h index 8f59eefae05..fab09fcd9d3 100644 --- a/intern/cycles/scene/shader.h +++ b/intern/cycles/scene/shader.h @@ -232,10 +232,6 @@ class ShaderManager { AttributeIDMap unique_attribute_id; static thread_mutex lookup_table_mutex; - static vector beckmann_table; - static bool beckmann_table_ready; - - size_t beckmann_table_offset; uint get_graph_kernel_features(ShaderGraph *graph); diff --git a/release/scripts/addons b/release/scripts/addons index bf49eeaa14c..6fcd157f249 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit bf49eeaa14c445d3c53068203fdf91bff568fe64 +Subproject commit 6fcd157f2497d9ba4ba82191cb2abf3de11a0394 diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index 0f72f6c85c3..9d538629bb8 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit 0f72f6c85c3743a9072273acb6a8a34b1cf1064b +Subproject commit 9d538629bb8a425991c7d10a49bab1ba0788c18f From d3ea9316475a605f250d28482a132fce40ce46d4 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 13:35:37 -0600 Subject: [PATCH 0782/1522] Fix: Compile error from designated initializers in C++ --- source/blender/blenkernel/intern/nla_test.cc | 41 +++++++++----------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/source/blender/blenkernel/intern/nla_test.cc b/source/blender/blenkernel/intern/nla_test.cc index e6875fff1ce..2f670ef69e5 100644 --- a/source/blender/blenkernel/intern/nla_test.cc +++ b/source/blender/blenkernel/intern/nla_test.cc @@ -3,43 +3,40 @@ #include "BKE_nla.h" -#include "DNA_nla_types.h" #include "DNA_anim_types.h" +#include "DNA_nla_types.h" #include "MEM_guardedalloc.h" #include "testing/testing.h" - namespace blender::bke::tests { TEST(nla_strip, BKE_nlastrip_recalculate_blend) { - - NlaStrip strip = { - .blendin = 4.0, - .blendout = 5.0, - .start = 1, - .end = 10 - }; + NlaStrip strip{}; + strip.blendin = 4.0; + strip.blendout = 5.0; + strip.start = 1; + strip.end = 10; /* Scaling a strip up doesn't affect the blend in/out value */ - strip.end = 20; - BKE_nlastrip_recalculate_blend(&strip); - EXPECT_FLOAT_EQ(strip.blendin, 4.0); - EXPECT_FLOAT_EQ(strip.blendout, 5.0); + strip.end = 20; + BKE_nlastrip_recalculate_blend(&strip); + EXPECT_FLOAT_EQ(strip.blendin, 4.0); + EXPECT_FLOAT_EQ(strip.blendout, 5.0); /* Scaling a strip down affects the blend-in value before the blend-out value */ - strip.end = 7; - BKE_nlastrip_recalculate_blend(&strip); - EXPECT_FLOAT_EQ(strip.blendin, 1.0); - EXPECT_FLOAT_EQ(strip.blendout, 5.0); + strip.end = 7; + BKE_nlastrip_recalculate_blend(&strip); + EXPECT_FLOAT_EQ(strip.blendin, 1.0); + EXPECT_FLOAT_EQ(strip.blendout, 5.0); - /* Scaling a strip down to nothing updates the blend in/out values accordingly */ - strip.end = 1.1; - BKE_nlastrip_recalculate_blend(&strip); - EXPECT_FLOAT_EQ(strip.blendin, 0.0); - EXPECT_FLOAT_EQ(strip.blendout, 0.1); + /* Scaling a strip down to nothing updates the blend in/out values accordingly */ + strip.end = 1.1; + BKE_nlastrip_recalculate_blend(&strip); + EXPECT_FLOAT_EQ(strip.blendin, 0.0); + EXPECT_FLOAT_EQ(strip.blendout, 0.1); } } // namespace blender::bke::tests From 38a45e46bc910c68ae3aa349c1ef3c72a34b6fc8 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 13:48:20 -0600 Subject: [PATCH 0783/1522] Cleanup: Use OffsetIndices class in more cases The same logic from D17025 is used in other places in the curve code. This patch uses the class for the evaluated point offsets and the Bezier control point offsets. This helps to standardize the behavior and make it easier to read. Previously the Bezier control point offsets used a slightly different standard where the first point was the first offset, just so they could have the same size as the number of points. However two nodes used a helper function to use the same `OffsetIndices` system, so switch to that there too. That requires removing the subtraction by one to find the actual offset. Also add const when accessing data arrays from curves, for consistency. Differential Revision: https://developer.blender.org/D17038 --- source/blender/blenkernel/BKE_curves.hh | 82 +++++------- .../blender/blenkernel/intern/curve_bezier.cc | 72 +++++------ .../blenkernel/intern/curve_catmull_rom.cc | 6 +- .../intern/curve_to_mesh_convert.cc | 32 +++-- .../blenkernel/intern/curves_geometry.cc | 117 ++++++++++-------- .../intern/geometry_component_curves.cc | 7 +- source/blender/blenlib/BLI_offset_indices.hh | 23 ++++ .../draw/intern/draw_cache_impl_curve.cc | 32 ++--- .../blender/geometry/intern/fillet_curves.cc | 52 ++++---- .../geometry/intern/resample_curves.cc | 44 +++---- .../geometry/intern/subdivide_curves.cc | 75 ++++++----- source/blender/geometry/intern/trim_curves.cc | 66 +++++----- .../geometry/nodes/node_geo_curve_fill.cc | 9 +- .../geometry/nodes/node_geo_curve_sample.cc | 5 +- .../nodes/node_geo_curve_spline_parameter.cc | 6 +- .../geometry/nodes/node_geo_input_tangent.cc | 5 +- 16 files changed, 323 insertions(+), 310 deletions(-) diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh index 6569629c71f..1b52fe709ac 100644 --- a/source/blender/blenkernel/BKE_curves.hh +++ b/source/blender/blenkernel/BKE_curves.hh @@ -30,17 +30,6 @@ namespace blender::bke { -template)> -constexpr IndexRange offsets_to_range(Span offsets, int64_t index) -{ - BLI_assert(index >= 0); - BLI_assert(index < offsets.size()); - - const int offset = offsets[index]; - const int offset_next = offsets[index + 1]; - return {offset, offset_next - offset}; -} - namespace curves::nurbs { struct BasisCache { @@ -81,7 +70,7 @@ class CurvesGeometryRuntime { * evaluated points, Bezier curve vector segments, different resolutions per curve, etc. */ mutable Vector evaluated_offsets_cache; - mutable Vector bezier_evaluated_offsets; + mutable Vector all_bezier_evaluated_offsets; mutable CacheMutex offsets_cache_mutex; mutable Vector nurbs_basis_cache; @@ -303,25 +292,14 @@ class CurvesGeometry : public ::CurvesGeometry { int evaluated_points_num() const; /** - * Access a range of indices of point data for a specific curve. - * Call #evaluated_offsets() first to ensure that the evaluated offsets cache is current. + * The offsets of every curve's evaluated points. */ - IndexRange evaluated_points_for_curve(int index) const; - IndexRange evaluated_points_for_curves(IndexRange curves) const; + OffsetIndices evaluated_points_by_curve() const; /** - * The index of the first evaluated point for every curve. The size of this span is one larger - * than the number of curves. Consider using #evaluated_points_for_curve rather than using the - * offsets directly. - */ - Span evaluated_offsets() const; - - /** Makes sure the data described by #evaluated_offsets if necessary. */ - void ensure_evaluated_offsets() const; - - /** - * Retrieve offsets into a Bezier curve's evaluated points for each control point. - * Call #ensure_evaluated_offsets() first to ensure that the evaluated offsets cache is current. + * Retrieve offsets into a Bezier curve's evaluated points for each control point. Stored in the + * same format as #OffsetIndices. Call #evaluated_points_by_curve() first to ensure that the + * evaluated offsets cache is current. */ Span bezier_evaluated_offsets_for_curve(int curve_index) const; @@ -489,6 +467,17 @@ inline float3 decode_surface_bary_coord(const float2 &v) return {v.x, v.y, 1.0f - v.x - v.y}; } +/** + * Return a range used to retrieve values from an array of values stored per point, but with an + * extra element at the end of each curve. This is useful for offsets within curves, where it is + * convenient to store the first 0 and have the last offset be the total result curve size, using + * the same rules as #OffsetIndices. + */ +inline IndexRange per_curve_point_offsets_range(const IndexRange points, const int curve_index) +{ + return {curve_index + points.start(), points.size() + 1}; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -567,8 +556,9 @@ bool point_is_sharp(Span handle_types_left, Span handle_types_ri * point edges generate the number of edges specified by the resolution, vector segments only * generate one edge. * - * The size of the offsets array must be the same as the number of points. The value at each index - * is the evaluated point offset including the following segment. + * The expectations for the result \a evaluated_offsets are the same as for #OffsetIndices, so the + * size must be one greater than the number of points. The value at each index is the evaluated + * point at the start of that segment. */ void calculate_evaluated_offsets(Span handle_types_left, Span handle_types_right, @@ -668,7 +658,7 @@ void evaluate_segment(const float3 &point_0, void calculate_evaluated_positions(Span positions, Span handles_left, Span handles_right, - Span evaluated_offsets, + OffsetIndices evaluated_offsets, MutableSpan evaluated_positions); /** @@ -676,7 +666,7 @@ void calculate_evaluated_positions(Span positions, * #evaluated_offsets. Unlike other curve types, for Bezier curves generic data and positions * are treated separately, since attribute values aren't stored for the handle control points. */ -void interpolate_to_evaluated(GSpan src, Span evaluated_offsets, GMutableSpan dst); +void interpolate_to_evaluated(GSpan src, OffsetIndices evaluated_offsets, GMutableSpan dst); } // namespace bezier @@ -702,12 +692,12 @@ int calculate_evaluated_num(int points_num, bool cyclic, int resolution); void interpolate_to_evaluated(GSpan src, bool cyclic, int resolution, GMutableSpan dst); /** - * Evaluate the Catmull Rom curve. The size of each segment and its offset in the #dst span - * is encoded in #evaluated_offsets, with the same method as #CurvesGeometry::offsets(). + * Evaluate the Catmull Rom curve. The placement of each segment in the #dst span is desribed by + * #evaluated_offsets. */ void interpolate_to_evaluated(const GSpan src, const bool cyclic, - const Span evaluated_offsets, + const OffsetIndices evaluated_offsets, GMutableSpan dst); void calculate_basis(const float parameter, float4 &r_weights); @@ -877,36 +867,22 @@ inline OffsetIndices CurvesGeometry::points_by_curve() const inline int CurvesGeometry::evaluated_points_num() const { /* This could avoid calculating offsets in the future in simple circumstances. */ - return this->evaluated_offsets().last(); -} - -inline IndexRange CurvesGeometry::evaluated_points_for_curve(int index) const -{ - BLI_assert(this->runtime->offsets_cache_mutex.is_cached()); - return offsets_to_range(this->runtime->evaluated_offsets_cache.as_span(), index); -} - -inline IndexRange CurvesGeometry::evaluated_points_for_curves(const IndexRange curves) const -{ - BLI_assert(this->runtime->offsets_cache_mutex.is_cached()); - BLI_assert(this->curve_num > 0); - const int offset = this->runtime->evaluated_offsets_cache[curves.start()]; - const int offset_next = this->runtime->evaluated_offsets_cache[curves.one_after_last()]; - return {offset, offset_next - offset}; + return this->evaluated_points_by_curve().total_size(); } inline Span CurvesGeometry::bezier_evaluated_offsets_for_curve(const int curve_index) const { const OffsetIndices points_by_curve = this->points_by_curve(); const IndexRange points = points_by_curve[curve_index]; - return this->runtime->bezier_evaluated_offsets.as_span().slice(points); + const IndexRange range = curves::per_curve_point_offsets_range(points, curve_index); + return this->runtime->all_bezier_evaluated_offsets.as_span().slice(range); } inline IndexRange CurvesGeometry::lengths_range_for_curve(const int curve_index, const bool cyclic) const { BLI_assert(cyclic == this->cyclic()[curve_index]); - const IndexRange points = this->evaluated_points_for_curve(curve_index); + const IndexRange points = this->evaluated_points_by_curve()[curve_index]; const int start = points.start() + curve_index; return {start, curves::segments_num(points.size(), cyclic)}; } diff --git a/source/blender/blenkernel/intern/curve_bezier.cc b/source/blender/blenkernel/intern/curve_bezier.cc index 3aa87be3787..460c96196ea 100644 --- a/source/blender/blenkernel/intern/curve_bezier.cc +++ b/source/blender/blenkernel/intern/curve_bezier.cc @@ -33,20 +33,21 @@ void calculate_evaluated_offsets(const Span handle_types_left, MutableSpan evaluated_offsets) { const int size = handle_types_left.size(); - BLI_assert(evaluated_offsets.size() == size); + BLI_assert(evaluated_offsets.size() == size + 1); + evaluated_offsets.first() = 0; if (size == 1) { - evaluated_offsets.first() = 1; + evaluated_offsets.last() = 1; return; } int offset = 0; - for (const int i : IndexRange(size - 1)) { - offset += segment_is_vector(handle_types_left, handle_types_right, i) ? 1 : resolution; evaluated_offsets[i] = offset; + offset += segment_is_vector(handle_types_left, handle_types_right, i) ? 1 : resolution; } + evaluated_offsets.last(1) = offset; if (cyclic) { offset += last_cyclic_segment_is_vector(handle_types_left, handle_types_right) ? 1 : resolution; @@ -233,12 +234,11 @@ void evaluate_segment(const float3 &point_0, void calculate_evaluated_positions(const Span positions, const Span handles_left, const Span handles_right, - const Span evaluated_offsets, + const OffsetIndices evaluated_offsets, MutableSpan evaluated_positions) { - BLI_assert(evaluated_offsets.last() == evaluated_positions.size()); - BLI_assert(evaluated_offsets.size() == positions.size()); - if (evaluated_offsets.last() == 1) { + BLI_assert(evaluated_offsets.total_size() == evaluated_positions.size()); + if (evaluated_offsets.total_size() == 1) { evaluated_positions.first() = positions.first(); return; } @@ -248,29 +248,29 @@ void calculate_evaluated_positions(const Span positions, handles_right.first(), handles_left[1], positions[1], - evaluated_positions.take_front(evaluated_offsets.first())); + evaluated_positions.slice(evaluated_offsets[0])); /* Give each task fewer segments as the resolution gets larger. */ const int grain_size = std::max(evaluated_positions.size() / positions.size() * 32, 1); - threading::parallel_for( - positions.index_range().drop_back(1).drop_front(1), grain_size, [&](IndexRange range) { - for (const int i : range) { - const IndexRange evaluated_range = offsets_to_range(evaluated_offsets, i - 1); - if (evaluated_range.size() == 1) { - evaluated_positions[evaluated_range.first()] = positions[i]; - } - else { - evaluate_segment(positions[i], - handles_right[i], - handles_left[i + 1], - positions[i + 1], - evaluated_positions.slice(evaluated_range)); - } - } - }); + const IndexRange inner_segments = positions.index_range().drop_back(1).drop_front(1); + threading::parallel_for(inner_segments, grain_size, [&](IndexRange range) { + for (const int i : range) { + const IndexRange evaluated_range = evaluated_offsets[i]; + if (evaluated_range.size() == 1) { + evaluated_positions[evaluated_range.first()] = positions[i]; + } + else { + evaluate_segment(positions[i], + handles_right[i], + handles_left[i + 1], + positions[i + 1], + evaluated_positions.slice(evaluated_range)); + } + } + }); /* Evaluate the final cyclic segment if necessary. */ - const IndexRange last_segment_points = offsets_to_range(evaluated_offsets, positions.size() - 2); + const IndexRange last_segment_points = evaluated_offsets[positions.index_range().last()]; if (last_segment_points.size() == 1) { evaluated_positions.last() = positions.last(); } @@ -295,34 +295,34 @@ static inline void linear_interpolation(const T &a, const T &b, MutableSpan d template static void interpolate_to_evaluated(const Span src, - const Span evaluated_offsets, + const OffsetIndices evaluated_offsets, MutableSpan dst) { BLI_assert(!src.is_empty()); - BLI_assert(evaluated_offsets.size() == src.size()); - BLI_assert(evaluated_offsets.last() == dst.size()); + BLI_assert(evaluated_offsets.total_size() == dst.size()); if (src.size() == 1) { BLI_assert(dst.size() == 1); dst.first() = src.first(); return; } - linear_interpolation(src.first(), src[1], dst.take_front(evaluated_offsets.first())); + linear_interpolation(src.first(), src[1], dst.slice(evaluated_offsets[0])); threading::parallel_for( src.index_range().drop_back(1).drop_front(1), 512, [&](IndexRange range) { for (const int i : range) { - const IndexRange segment_points = offsets_to_range(evaluated_offsets, i - 1); - linear_interpolation(src[i], src[i + 1], dst.slice(segment_points)); + const IndexRange segment = evaluated_offsets[i]; + linear_interpolation(src[i], src[i + 1], dst.slice(segment)); } }); - const IndexRange last_segment_points(evaluated_offsets.last(1), - evaluated_offsets.last() - evaluated_offsets.last(1)); - linear_interpolation(src.last(), src.first(), dst.slice(last_segment_points)); + const IndexRange last_segment = evaluated_offsets[src.index_range().last()]; + linear_interpolation(src.last(), src.first(), dst.slice(last_segment)); } -void interpolate_to_evaluated(const GSpan src, const Span evaluated_offsets, GMutableSpan dst) +void interpolate_to_evaluated(const GSpan src, + const OffsetIndices evaluated_offsets, + GMutableSpan dst) { attribute_math::convert_to_static_type(src.type(), [&](auto dummy) { using T = decltype(dummy); diff --git a/source/blender/blenkernel/intern/curve_catmull_rom.cc b/source/blender/blenkernel/intern/curve_catmull_rom.cc index 8247d9451e4..28f213ff68c 100644 --- a/source/blender/blenkernel/intern/curve_catmull_rom.cc +++ b/source/blender/blenkernel/intern/curve_catmull_rom.cc @@ -123,7 +123,7 @@ static void interpolate_to_evaluated(const Span src, template static void interpolate_to_evaluated(const Span src, const bool cyclic, - const Span evaluated_offsets, + const OffsetIndices evaluated_offsets, MutableSpan dst) { @@ -131,7 +131,7 @@ static void interpolate_to_evaluated(const Span src, src, cyclic, [evaluated_offsets](const int segment_i) -> IndexRange { - return bke::offsets_to_range(evaluated_offsets, segment_i); + return evaluated_offsets[segment_i]; }, dst); } @@ -149,7 +149,7 @@ void interpolate_to_evaluated(const GSpan src, void interpolate_to_evaluated(const GSpan src, const bool cyclic, - const Span evaluated_offsets, + const OffsetIndices evaluated_offsets, GMutableSpan dst) { attribute_math::convert_to_static_type(src.type(), [&](auto dummy) { diff --git a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc index 9fd35fbfb65..23dcda10d8a 100644 --- a/source/blender/blenkernel/intern/curve_to_mesh_convert.cc +++ b/source/blender/blenkernel/intern/curve_to_mesh_convert.cc @@ -166,7 +166,7 @@ static void mark_bezier_vector_edges_sharp(const int profile_point_num, for (const int i : IndexRange(profile_point_num).drop_front(1)) { if (curves::bezier::point_is_sharp(handle_types_left, handle_types_right, i)) { - const int offset = main_edges_start + main_segment_num * control_point_offsets[i - 1]; + const int offset = main_edges_start + main_segment_num * control_point_offsets[i]; sharp_edges.slice(offset, main_segment_num).fill(true); } } @@ -246,8 +246,8 @@ static ResultOffsets calculate_result_offsets(const CurvesInfo &info, const bool result.main_indices.reinitialize(result.total); result.profile_indices.reinitialize(result.total); - info.main.ensure_evaluated_offsets(); - info.profile.ensure_evaluated_offsets(); + const OffsetIndices main_offsets = info.main.evaluated_points_by_curve(); + const OffsetIndices profile_offsets = info.profile.evaluated_points_by_curve(); int mesh_index = 0; int vert_offset = 0; @@ -256,7 +256,7 @@ static ResultOffsets calculate_result_offsets(const CurvesInfo &info, const bool int poly_offset = 0; for (const int i_main : info.main.curves_range()) { const bool main_cyclic = info.main_cyclic[i_main]; - const int main_point_num = info.main.evaluated_points_for_curve(i_main).size(); + const int main_point_num = main_offsets.size(i_main); const int main_segment_num = curves::segments_num(main_point_num, main_cyclic); for (const int i_profile : info.profile.curves_range()) { result.vert[mesh_index] = vert_offset; @@ -268,7 +268,7 @@ static ResultOffsets calculate_result_offsets(const CurvesInfo &info, const bool result.profile_indices[mesh_index] = i_profile; const bool profile_cyclic = info.profile_cyclic[i_profile]; - const int profile_point_num = info.profile.evaluated_points_for_curve(i_profile).size(); + const int profile_point_num = profile_offsets.size(i_profile); const int profile_segment_num = curves::segments_num(profile_point_num, profile_cyclic); const bool has_caps = fill_caps && !main_cyclic && profile_cyclic; @@ -377,13 +377,19 @@ static void foreach_curve_combination(const CurvesInfo &info, const ResultOffsets &offsets, const Fn &fn) { + const OffsetIndices main_offsets = info.main.evaluated_points_by_curve(); + const OffsetIndices profile_offsets = info.profile.evaluated_points_by_curve(); + const OffsetIndices vert_offsets(offsets.vert); + const OffsetIndices edge_offsets(offsets.edge); + const OffsetIndices poly_offsets(offsets.poly); + const OffsetIndices loop_offsets(offsets.loop); threading::parallel_for(IndexRange(offsets.total), 512, [&](IndexRange range) { for (const int i : range) { const int i_main = offsets.main_indices[i]; const int i_profile = offsets.profile_indices[i]; - const IndexRange main_points = info.main.evaluated_points_for_curve(i_main); - const IndexRange profile_points = info.profile.evaluated_points_for_curve(i_profile); + const IndexRange main_points = main_offsets[i_main]; + const IndexRange profile_points = profile_offsets[i_profile]; const bool main_cyclic = info.main_cyclic[i_main]; const bool profile_cyclic = info.profile_cyclic[i_profile]; @@ -399,10 +405,10 @@ static void foreach_curve_combination(const CurvesInfo &info, profile_cyclic, curves::segments_num(main_points.size(), main_cyclic), curves::segments_num(profile_points.size(), profile_cyclic), - offsets_to_range(offsets.vert.as_span(), i), - offsets_to_range(offsets.edge.as_span(), i), - offsets_to_range(offsets.poly.as_span(), i), - offsets_to_range(offsets.loop.as_span(), i)}); + vert_offsets[i], + edge_offsets[i], + poly_offsets[i], + loop_offsets[i]}); } }); } @@ -570,7 +576,7 @@ static void copy_profile_point_domain_attribute_to_mesh(const CurvesInfo &curves template static void copy_indices_to_offset_ranges(const VArray &src, const Span curve_indices, - const Span mesh_offsets, + const OffsetIndices mesh_offsets, MutableSpan dst) { /* This unnecessarily instantiates the "is single" case (which should be handled elsewhere if @@ -579,7 +585,7 @@ static void copy_indices_to_offset_ranges(const VArray &src, devirtualize_varray(src, [&](const auto &src) { threading::parallel_for(curve_indices.index_range(), 512, [&](IndexRange range) { for (const int i : range) { - dst.slice(offsets_to_range(mesh_offsets, i)).fill(src[curve_indices[i]]); + dst.slice(mesh_offsets[i]).fill(src[curve_indices[i]]); } }); }); diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 0f24d9ea640..5944c557941 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -455,18 +455,18 @@ template void build_offsets(MutableSpan offsets, const Co static void calculate_evaluated_offsets(const CurvesGeometry &curves, MutableSpan offsets, - MutableSpan bezier_evaluated_offsets) + MutableSpan all_bezier_offsets) { const OffsetIndices points_by_curve = curves.points_by_curve(); - VArray types = curves.curve_types(); - VArray resolution = curves.resolution(); - VArray cyclic = curves.cyclic(); + const VArray types = curves.curve_types(); + const VArray resolution = curves.resolution(); + const VArray cyclic = curves.cyclic(); - VArraySpan handle_types_left{curves.handle_types_left()}; - VArraySpan handle_types_right{curves.handle_types_right()}; + const VArraySpan handle_types_left{curves.handle_types_left()}; + const VArraySpan handle_types_right{curves.handle_types_right()}; - VArray nurbs_orders = curves.nurbs_orders(); - VArray nurbs_knots_modes = curves.nurbs_knots_modes(); + const VArray nurbs_orders = curves.nurbs_orders(); + const VArray nurbs_knots_modes = curves.nurbs_knots_modes(); build_offsets(offsets, [&](const int curve_index) -> int { const IndexRange points = points_by_curve[curve_index]; @@ -476,13 +476,15 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves, points.size(), cyclic[curve_index], resolution[curve_index]); case CURVE_TYPE_POLY: return points.size(); - case CURVE_TYPE_BEZIER: + case CURVE_TYPE_BEZIER: { + const IndexRange offsets = curves::per_curve_point_offsets_range(points, curve_index); curves::bezier::calculate_evaluated_offsets(handle_types_left.slice(points), handle_types_right.slice(points), cyclic[curve_index], resolution[curve_index], - bezier_evaluated_offsets.slice(points)); - return bezier_evaluated_offsets[points.last()]; + all_bezier_offsets.slice(offsets)); + return all_bezier_offsets[offsets.last()]; + } case CURVE_TYPE_NURBS: return curves::nurbs::calculate_evaluated_num(points.size(), nurbs_orders[curve_index], @@ -495,27 +497,24 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves, }); } -void CurvesGeometry::ensure_evaluated_offsets() const +OffsetIndices CurvesGeometry::evaluated_points_by_curve() const { this->runtime->offsets_cache_mutex.ensure([&]() { this->runtime->evaluated_offsets_cache.resize(this->curves_num() + 1); if (this->has_curve_with_type(CURVE_TYPE_BEZIER)) { - this->runtime->bezier_evaluated_offsets.resize(this->points_num()); + this->runtime->all_bezier_evaluated_offsets.resize(this->points_num() + this->curves_num()); } else { - this->runtime->bezier_evaluated_offsets.clear_and_shrink(); + this->runtime->all_bezier_evaluated_offsets.clear_and_shrink(); } - calculate_evaluated_offsets( - *this, this->runtime->evaluated_offsets_cache, this->runtime->bezier_evaluated_offsets); + calculate_evaluated_offsets(*this, + this->runtime->evaluated_offsets_cache, + this->runtime->all_bezier_evaluated_offsets); }); -} -Span CurvesGeometry::evaluated_offsets() const -{ - this->ensure_evaluated_offsets(); - return this->runtime->evaluated_offsets_cache; + return OffsetIndices(this->runtime->evaluated_offsets_cache); } IndexMask CurvesGeometry::indices_for_curve_type(const CurveType type, @@ -557,14 +556,15 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const MutableSpan basis_caches(this->runtime->nurbs_basis_cache); const OffsetIndices points_by_curve = this->points_by_curve(); - VArray cyclic = this->cyclic(); - VArray orders = this->nurbs_orders(); - VArray knots_modes = this->nurbs_knots_modes(); + const OffsetIndices evaluated_points_by_curve = this->evaluated_points_by_curve(); + const VArray cyclic = this->cyclic(); + const VArray orders = this->nurbs_orders(); + const VArray knots_modes = this->nurbs_knots_modes(); threading::parallel_for(nurbs_mask.index_range(), 64, [&](const IndexRange range) { for (const int curve_index : nurbs_mask.slice(range)) { const IndexRange points = points_by_curve[curve_index]; - const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); + const IndexRange evaluated_points = evaluated_points_by_curve[curve_index]; const int8_t order = orders[curve_index]; const bool is_cyclic = cyclic[curve_index]; @@ -603,24 +603,25 @@ Span CurvesGeometry::evaluated_positions() const this->runtime->evaluated_positions_span = evaluated_positions; const OffsetIndices points_by_curve = this->points_by_curve(); - VArray types = this->curve_types(); - VArray cyclic = this->cyclic(); - VArray resolution = this->resolution(); - Span positions = this->positions(); + const OffsetIndices evaluated_points_by_curve = this->evaluated_points_by_curve(); + const VArray types = this->curve_types(); + const VArray cyclic = this->cyclic(); + const VArray resolution = this->resolution(); + const Span positions = this->positions(); - Span handle_positions_left = this->handle_positions_left(); - Span handle_positions_right = this->handle_positions_right(); - Span bezier_evaluated_offsets = this->runtime->bezier_evaluated_offsets; + const Span handle_positions_left = this->handle_positions_left(); + const Span handle_positions_right = this->handle_positions_right(); + const Span all_bezier_evaluated_offsets = this->runtime->all_bezier_evaluated_offsets; - VArray nurbs_orders = this->nurbs_orders(); - Span nurbs_weights = this->nurbs_weights(); + const VArray nurbs_orders = this->nurbs_orders(); + const Span nurbs_weights = this->nurbs_weights(); this->ensure_nurbs_basis_cache(); threading::parallel_for(this->curves_range(), 128, [&](IndexRange curves_range) { for (const int curve_index : curves_range) { const IndexRange points = points_by_curve[curve_index]; - const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); + const IndexRange evaluated_points = evaluated_points_by_curve[curve_index]; switch (types[curve_index]) { case CURVE_TYPE_CATMULL_ROM: @@ -633,22 +634,23 @@ Span CurvesGeometry::evaluated_positions() const case CURVE_TYPE_POLY: evaluated_positions.slice(evaluated_points).copy_from(positions.slice(points)); break; - case CURVE_TYPE_BEZIER: + case CURVE_TYPE_BEZIER: { + const IndexRange offsets = curves::per_curve_point_offsets_range(points, curve_index); curves::bezier::calculate_evaluated_positions( positions.slice(points), handle_positions_left.slice(points), handle_positions_right.slice(points), - bezier_evaluated_offsets.slice(points), + all_bezier_evaluated_offsets.slice(offsets), evaluated_positions.slice(evaluated_points)); break; - case CURVE_TYPE_NURBS: { + } + case CURVE_TYPE_NURBS: curves::nurbs::interpolate_to_evaluated(this->runtime->nurbs_basis_cache[curve_index], nurbs_orders[curve_index], nurbs_weights.slice_safe(points), positions.slice(points), evaluated_positions.slice(evaluated_points)); break; - } default: BLI_assert_unreachable(); break; @@ -662,6 +664,7 @@ Span CurvesGeometry::evaluated_positions() const Span CurvesGeometry::evaluated_tangents() const { this->runtime->tangent_cache_mutex.ensure([&]() { + const OffsetIndices evaluated_points_by_curve = this->evaluated_points_by_curve(); const Span evaluated_positions = this->evaluated_positions(); const VArray cyclic = this->cyclic(); @@ -670,7 +673,7 @@ Span CurvesGeometry::evaluated_tangents() const threading::parallel_for(this->curves_range(), 128, [&](IndexRange curves_range) { for (const int curve_index : curves_range) { - const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); + const IndexRange evaluated_points = evaluated_points_by_curve[curve_index]; curves::poly::calculate_tangents(evaluated_positions.slice(evaluated_points), cyclic[curve_index], tangents.slice(evaluated_points)); @@ -694,7 +697,7 @@ Span CurvesGeometry::evaluated_tangents() const continue; } const IndexRange points = points_by_curve[curve_index]; - const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); + const IndexRange evaluated_points = evaluated_points_by_curve[curve_index]; const float epsilon = 1e-6f; if (!math::almost_equal_relative( @@ -729,7 +732,7 @@ static void evaluate_generic_data_for_curve( const VArray &types, const VArray &cyclic, const VArray &resolution, - const Span bezier_evaluated_offsets, + const Span all_bezier_evaluated_offsets, const Span nurbs_basis_cache, const VArray &nurbs_orders, const Span nurbs_weights, @@ -744,9 +747,12 @@ static void evaluate_generic_data_for_curve( case CURVE_TYPE_POLY: dst.copy_from(src); break; - case CURVE_TYPE_BEZIER: - curves::bezier::interpolate_to_evaluated(src, bezier_evaluated_offsets.slice(points), dst); + case CURVE_TYPE_BEZIER: { + const IndexRange offsets = curves::per_curve_point_offsets_range(points, curve_index); + curves::bezier::interpolate_to_evaluated( + src, all_bezier_evaluated_offsets.slice(offsets), dst); break; + } case CURVE_TYPE_NURBS: curves::nurbs::interpolate_to_evaluated(nurbs_basis_cache[curve_index], nurbs_orders[curve_index], @@ -761,6 +767,7 @@ Span CurvesGeometry::evaluated_normals() const { this->runtime->normal_cache_mutex.ensure([&]() { const OffsetIndices points_by_curve = this->points_by_curve(); + const OffsetIndices evaluated_points_by_curve = this->evaluated_points_by_curve(); const VArray types = this->curve_types(); const VArray cyclic = this->cyclic(); const VArray normal_mode = this->normal_mode(); @@ -784,7 +791,7 @@ Span CurvesGeometry::evaluated_normals() const Vector evaluated_tilts; for (const int curve_index : curves_range) { - const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); + const IndexRange evaluated_points = evaluated_points_by_curve[curve_index]; switch (normal_mode[curve_index]) { case NORMAL_MODE_Z_UP: curves::poly::calculate_normals_z_up(evaluated_tangents.slice(evaluated_points), @@ -813,7 +820,7 @@ Span CurvesGeometry::evaluated_normals() const types, cyclic, resolution, - this->runtime->bezier_evaluated_offsets.as_span(), + this->runtime->all_bezier_evaluated_offsets.as_span(), this->runtime->nurbs_basis_cache.as_span(), nurbs_orders, nurbs_weights, @@ -839,13 +846,13 @@ void CurvesGeometry::interpolate_to_evaluated(const int curve_index, const OffsetIndices points_by_curve = this->points_by_curve(); const IndexRange points = points_by_curve[curve_index]; BLI_assert(src.size() == points.size()); - BLI_assert(dst.size() == this->evaluated_points_for_curve(curve_index).size()); + BLI_assert(dst.size() == this->evaluated_points_by_curve().size(curve_index)); evaluate_generic_data_for_curve(curve_index, points, this->curve_types(), this->cyclic(), this->resolution(), - this->runtime->bezier_evaluated_offsets.as_span(), + this->runtime->all_bezier_evaluated_offsets.as_span(), this->runtime->nurbs_basis_cache.as_span(), this->nurbs_orders(), this->nurbs_weights(), @@ -858,6 +865,7 @@ void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst) BLI_assert(this->runtime->offsets_cache_mutex.is_cached()); BLI_assert(this->runtime->nurbs_basis_cache_mutex.is_cached()); const OffsetIndices points_by_curve = this->points_by_curve(); + const OffsetIndices evaluated_points_by_curve = this->evaluated_points_by_curve(); const VArray types = this->curve_types(); const VArray resolution = this->resolution(); const VArray cyclic = this->cyclic(); @@ -867,13 +875,13 @@ void CurvesGeometry::interpolate_to_evaluated(const GSpan src, GMutableSpan dst) threading::parallel_for(this->curves_range(), 512, [&](IndexRange curves_range) { for (const int curve_index : curves_range) { const IndexRange points = points_by_curve[curve_index]; - const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); + const IndexRange evaluated_points = evaluated_points_by_curve[curve_index]; evaluate_generic_data_for_curve(curve_index, points, types, cyclic, resolution, - this->runtime->bezier_evaluated_offsets, + this->runtime->all_bezier_evaluated_offsets, this->runtime->nurbs_basis_cache, nurbs_orders, nurbs_weights, @@ -892,13 +900,14 @@ void CurvesGeometry::ensure_evaluated_lengths() const this->runtime->evaluated_length_cache.resize(total_num); MutableSpan evaluated_lengths = this->runtime->evaluated_length_cache; - Span evaluated_positions = this->evaluated_positions(); - VArray curves_cyclic = this->cyclic(); + const OffsetIndices evaluated_points_by_curve = this->evaluated_points_by_curve(); + const Span evaluated_positions = this->evaluated_positions(); + const VArray curves_cyclic = this->cyclic(); threading::parallel_for(this->curves_range(), 128, [&](IndexRange curves_range) { for (const int curve_index : curves_range) { const bool cyclic = curves_cyclic[curve_index]; - const IndexRange evaluated_points = this->evaluated_points_for_curve(curve_index); + const IndexRange evaluated_points = evaluated_points_by_curve[curve_index]; const IndexRange lengths_range = this->lengths_range_for_curve(curve_index, cyclic); length_parameterize::accumulate_lengths(evaluated_positions.slice(evaluated_points), cyclic, @@ -910,7 +919,7 @@ void CurvesGeometry::ensure_evaluated_lengths() const void CurvesGeometry::ensure_can_interpolate_to_evaluated() const { - this->ensure_evaluated_offsets(); + this->evaluated_points_by_curve(); this->ensure_nurbs_basis_cache(); } diff --git a/source/blender/blenkernel/intern/geometry_component_curves.cc b/source/blender/blenkernel/intern/geometry_component_curves.cc index 4443a5c02c3..e775a2a00a9 100644 --- a/source/blender/blenkernel/intern/geometry_component_curves.cc +++ b/source/blender/blenkernel/intern/geometry_component_curves.cc @@ -144,6 +144,7 @@ namespace blender::bke { static Array curve_normal_point_domain(const bke::CurvesGeometry &curves) { const OffsetIndices points_by_curve = curves.points_by_curve(); + const OffsetIndices evaluated_points_by_curve = curves.evaluated_points_by_curve(); const VArray types = curves.curve_types(); const VArray resolutions = curves.resolution(); const VArray curves_cyclic = curves.cyclic(); @@ -160,7 +161,7 @@ static Array curve_normal_point_domain(const bke::CurvesGeometry &curves for (const int i_curve : range) { const IndexRange points = points_by_curve[i_curve]; - const IndexRange evaluated_points = curves.evaluated_points_for_curve(i_curve); + const IndexRange evaluated_points = evaluated_points_by_curve[i_curve]; MutableSpan curve_normals = results.as_mutable_span().slice(points); @@ -181,7 +182,7 @@ static Array curve_normal_point_domain(const bke::CurvesGeometry &curves curve_normals.first() = normals.first(); const Span offsets = curves.bezier_evaluated_offsets_for_curve(i_curve); for (const int i : IndexRange(points.size()).drop_front(1)) { - curve_normals[i] = normals[offsets[i - 1]]; + curve_normals[i] = normals[offsets[i]]; } break; } @@ -242,7 +243,7 @@ static VArray construct_curve_length_gvarray(const CurvesGeometry &curves { curves.ensure_evaluated_lengths(); - VArray cyclic = curves.cyclic(); + const VArray cyclic = curves.cyclic(); VArray lengths = VArray::ForFunc( curves.curves_num(), [&curves, cyclic = std::move(cyclic)](int64_t index) { return curves.evaluated_length_total_for_curve(index, cyclic[index]); diff --git a/source/blender/blenlib/BLI_offset_indices.hh b/source/blender/blenlib/BLI_offset_indices.hh index 75526ed1025..9685266e687 100644 --- a/source/blender/blenlib/BLI_offset_indices.hh +++ b/source/blender/blenlib/BLI_offset_indices.hh @@ -39,6 +39,18 @@ template class OffsetIndices { return size; } + /** Return the total number of elements in the the referenced arrays. */ + T total_size() const + { + return offsets_.last(); + } + + /** Return the number of ranges encoded by the offsets. */ + T ranges_num() const + { + return offsets_.size() - 1; + } + IndexRange operator[](const int64_t index) const { BLI_assert(index >= 0); @@ -56,6 +68,17 @@ template class OffsetIndices { const int64_t size = end - begin; return IndexRange(begin, size); } + + /** + * Return a subset of the offsets desribing the specified range of source elements. + * This is a slice into the source ranges rather than the indexed elements described by the + * offset values. + */ + OffsetIndices slice(const IndexRange range) const + { + BLI_assert(offsets_.index_range().drop_back(1).contains(range.last())); + return OffsetIndices(offsets_.slice(range.start(), range.one_after_last())); + } }; /** diff --git a/source/blender/draw/intern/draw_cache_impl_curve.cc b/source/blender/draw/intern/draw_cache_impl_curve.cc index 3e2fab001f7..ab8399216ec 100644 --- a/source/blender/draw/intern/draw_cache_impl_curve.cc +++ b/source/blender/draw/intern/draw_cache_impl_curve.cc @@ -42,6 +42,7 @@ using blender::Array; using blender::ColorGeometry4f; using blender::float3; using blender::IndexRange; +using blender::OffsetIndices; using blender::Span; /* See: edit_curve_point_vert.glsl for duplicate includes. */ @@ -103,14 +104,14 @@ static void curve_eval_render_wire_verts_edges_len_get(const blender::bke::Curve int *r_vert_len, int *r_edge_len) { - *r_curve_len = curves.curves_num(); - *r_vert_len = curves.evaluated_points_num(); - - *r_edge_len = 0; + const OffsetIndices points_by_curve = curves.evaluated_points_by_curve(); const blender::VArray cyclic = curves.cyclic(); + + *r_curve_len = curves.curves_num(); + *r_vert_len = points_by_curve.total_size(); + *r_edge_len = 0; for (const int i : curves.curves_range()) { - const IndexRange points = curves.evaluated_points_for_curve(i); - *r_edge_len += blender::bke::curves::segments_num(points.size(), cyclic[i]); + *r_edge_len += blender::bke::curves::segments_num(points_by_curve.size(i), cyclic[i]); } } @@ -480,6 +481,7 @@ static void curve_create_curves_pos(CurveRenderData *rdata, GPUVertBuf *vbo_curv static void curve_create_attribute(CurveRenderData *rdata, GPUVertBuf *vbo_attr) { + using namespace blender; if (rdata->curve_eval == nullptr) { return; } @@ -493,18 +495,17 @@ static void curve_create_attribute(CurveRenderData *rdata, GPUVertBuf *vbo_attr) GPU_vertbuf_init_with_format(vbo_attr, &format); GPU_vertbuf_data_alloc(vbo_attr, vert_len); - const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap( - rdata->curve_eval->geometry); + const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(rdata->curve_eval->geometry); curves.ensure_can_interpolate_to_evaluated(); - const blender::VArraySpan colors = curves.attributes().lookup( + const VArraySpan colors = curves.attributes().lookup( ".viewer", ATTR_DOMAIN_POINT); ColorGeometry4f *vbo_data = static_cast(GPU_vertbuf_get_data(vbo_attr)); - curves.interpolate_to_evaluated(colors, - blender::MutableSpan{vbo_data, vert_len}); + curves.interpolate_to_evaluated(colors, MutableSpan{vbo_data, vert_len}); } static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_curve_lines) { + using namespace blender; if (rdata->curve_eval == nullptr) { return; } @@ -518,11 +519,12 @@ static void curve_create_curves_lines(CurveRenderData *rdata, GPUIndexBuf *ibo_c GPUIndexBufBuilder elb; GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, index_len, vert_len); - const blender::bke::CurvesGeometry &curves = blender::bke::CurvesGeometry::wrap( - rdata->curve_eval->geometry); - const blender::VArray cyclic = curves.cyclic(); + const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(rdata->curve_eval->geometry); + const OffsetIndices points_by_curve = curves.evaluated_points_by_curve(); + const VArray cyclic = curves.cyclic(); + for (const int i : curves.curves_range()) { - const IndexRange points = curves.evaluated_points_for_curve(i); + const IndexRange points = points_by_curve[i]; if (cyclic[i] && points.size() > 1) { GPU_indexbuf_add_generic_vert(&elb, points.last()); } diff --git a/source/blender/geometry/intern/fillet_curves.cc b/source/blender/geometry/intern/fillet_curves.cc index 6b1c0adb648..1bb33f0e80f 100644 --- a/source/blender/geometry/intern/fillet_curves.cc +++ b/source/blender/geometry/intern/fillet_curves.cc @@ -13,22 +13,14 @@ namespace blender::geometry { -/** - * Return a range used to retrieve values from an array of values stored per point, but with an - * extra element at the end of each curve. This is useful for offsets within curves, where it is - * convenient to store the first 0 and have the last offset be the total result curve size. - */ -static IndexRange curve_dst_offsets(const IndexRange points, const int curve_index) -{ - return {curve_index + points.start(), points.size() + 1}; -} - template -static void threaded_slice_fill(const Span src, const Span offsets, MutableSpan dst) +static void threaded_slice_fill(const Span src, + const OffsetIndices offsets, + MutableSpan dst) { threading::parallel_for(src.index_range(), 512, [&](IndexRange range) { for (const int i : range) { - dst.slice(bke::offsets_to_range(offsets, i)).fill(src[i]); + dst.slice(offsets[i]).fill(src[i]); } }); } @@ -37,7 +29,7 @@ template static void duplicate_fillet_point_data(const bke::CurvesGeometry &src_curves, const bke::CurvesGeometry &dst_curves, const IndexMask curve_selection, - const Span point_offsets, + const Span all_point_offsets, const Span src, MutableSpan dst) { @@ -47,7 +39,8 @@ static void duplicate_fillet_point_data(const bke::CurvesGeometry &src_curves, for (const int curve_i : curve_selection.slice(range)) { const IndexRange src_points = src_points_by_curve[curve_i]; const IndexRange dst_points = dst_points_by_curve[curve_i]; - const Span offsets = point_offsets.slice(curve_dst_offsets(src_points, curve_i)); + const IndexRange offsets_range = bke::curves::per_curve_point_offsets_range(src_points, curve_i); + const OffsetIndices offsets(all_point_offsets.slice(offsets_range)); threaded_slice_fill(src.slice(src_points), offsets, dst.slice(dst_points)); } }); @@ -56,14 +49,14 @@ static void duplicate_fillet_point_data(const bke::CurvesGeometry &src_curves, static void duplicate_fillet_point_data(const bke::CurvesGeometry &src_curves, const bke::CurvesGeometry &dst_curves, const IndexMask selection, - const Span point_offsets, + const Span all_point_offsets, const GSpan src, GMutableSpan dst) { attribute_math::convert_to_static_type(dst.type(), [&](auto dummy) { using T = decltype(dummy); duplicate_fillet_point_data( - src_curves, dst_curves, selection, point_offsets, src.typed(), dst.typed()); + src_curves, dst_curves, selection, all_point_offsets, src.typed(), dst.typed()); }); } @@ -82,7 +75,7 @@ static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int curve_i : selection.slice(range)) { const IndexRange src_points = points_by_curve[curve_i]; - const IndexRange offsets_range = curve_dst_offsets(src_points, curve_i); + const IndexRange offsets_range = bke::curves::per_curve_point_offsets_range(src_points, curve_i); MutableSpan point_offsets = dst_point_offsets.slice(offsets_range); MutableSpan point_counts = point_offsets.drop_back(1); @@ -235,13 +228,13 @@ static void calculate_fillet_positions(const Span src_positions, const Span angles, const Span radii, const Span directions, - const Span dst_offsets, + const OffsetIndices dst_offsets, MutableSpan dst) { const int i_src_last = src_positions.index_range().last(); threading::parallel_for(src_positions.index_range(), 512, [&](IndexRange range) { for (const int i_src : range) { - const IndexRange arc = bke::offsets_to_range(dst_offsets, i_src); + const IndexRange arc = dst_offsets[i_src]; const float3 &src = src_positions[i_src]; if (arc.size() == 1) { dst[arc.first()] = src; @@ -292,7 +285,7 @@ static void calculate_bezier_handles_bezier_mode(const Span src_handles_ const Span angles, const Span radii, const Span directions, - const Span dst_offsets, + const OffsetIndices dst_offsets, const Span dst_positions, MutableSpan dst_handles_l, MutableSpan dst_handles_r, @@ -303,7 +296,7 @@ static void calculate_bezier_handles_bezier_mode(const Span src_handles_ const int i_dst_last = dst_positions.index_range().last(); threading::parallel_for(src_handles_l.index_range(), 512, [&](IndexRange range) { for (const int i_src : range) { - const IndexRange arc = bke::offsets_to_range(dst_offsets, i_src); + const IndexRange arc = dst_offsets[i_src]; if (arc.size() == 1) { dst_handles_l[arc.first()] = src_handles_l[i_src]; dst_handles_r[arc.first()] = src_handles_r[i_src]; @@ -354,7 +347,7 @@ static void calculate_bezier_handles_poly_mode(const Span src_handles_l, const Span src_handles_r, const Span src_types_l, const Span src_types_r, - const Span dst_offsets, + const OffsetIndices dst_offsets, const Span dst_positions, MutableSpan dst_handles_l, MutableSpan dst_handles_r, @@ -364,7 +357,7 @@ static void calculate_bezier_handles_poly_mode(const Span src_handles_l, const int i_dst_last = dst_positions.index_range().last(); threading::parallel_for(src_handles_l.index_range(), 512, [&](IndexRange range) { for (const int i_src : range) { - const IndexRange arc = bke::offsets_to_range(dst_offsets, i_src); + const IndexRange arc = dst_offsets[i_src]; if (arc.size() == 1) { dst_handles_l[arc.first()] = src_handles_l[i_src]; dst_handles_r[arc.first()] = src_handles_r[i_src]; @@ -427,7 +420,7 @@ static bke::CurvesGeometry fillet_curves( cyclic, dst_curves.offsets_for_write(), dst_point_offsets); - const Span point_offsets = dst_point_offsets.as_span(); + const Span all_point_offsets = dst_point_offsets.as_span(); dst_curves.resize(dst_curves.offsets().last(), dst_curves.curves_num()); bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write(); @@ -463,7 +456,8 @@ static bke::CurvesGeometry fillet_curves( for (const int curve_i : curve_selection.slice(range)) { const IndexRange src_points = src_points_by_curve[curve_i]; - const Span offsets = point_offsets.slice(curve_dst_offsets(src_points, curve_i)); + const IndexRange offsets_range = bke::curves::per_curve_point_offsets_range(src_points, curve_i); + const OffsetIndices offsets(all_point_offsets.slice(offsets_range)); const IndexRange dst_points = dst_points_by_curve[curve_i]; const Span src_positions = positions.slice(src_points); @@ -528,8 +522,12 @@ static bke::CurvesGeometry fillet_curves( ATTR_DOMAIN_MASK_POINT, propagation_info, {"position", "handle_type_left", "handle_type_right", "handle_right", "handle_left"})) { - duplicate_fillet_point_data( - src_curves, dst_curves, curve_selection, point_offsets, attribute.src, attribute.dst.span); + duplicate_fillet_point_data(src_curves, + dst_curves, + curve_selection, + all_point_offsets, + attribute.src, + attribute.dst.span); attribute.dst.finish(); } diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc index f028c64cdd1..64827fb6143 100644 --- a/source/blender/geometry/intern/resample_curves.cc +++ b/source/blender/geometry/intern/resample_curves.cc @@ -225,11 +225,10 @@ static void normalize_span(MutableSpan data) } } -static void normalize_curve_point_data(const CurvesGeometry &curves, - const IndexMask curve_selection, +static void normalize_curve_point_data(const IndexMask curve_selection, + const OffsetIndices points_by_curve, MutableSpan data) { - const OffsetIndices points_by_curve = curves.points_by_curve(); for (const int i_curve : curve_selection) { normalize_span(data.slice(points_by_curve[i_curve])); } @@ -252,7 +251,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, src_curves.curves_num()); MutableSpan dst_offsets = dst_curves.offsets_for_write(); - bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE}; + const bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE}; fn::FieldEvaluator evaluator{field_context, src_curves.curves_num()}; evaluator.set_selection(selection_field); evaluator.add_with_destination(count_field, dst_offsets.drop_back(1)); @@ -269,9 +268,11 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, /* All resampled curves are poly curves. */ dst_curves.fill_curve_types(selection, CURVE_TYPE_POLY); - VArray curves_cyclic = src_curves.cyclic(); - VArray curve_types = src_curves.curve_types(); - Span evaluated_positions = src_curves.evaluated_positions(); + const OffsetIndices evaluated_points_by_curve = src_curves.evaluated_points_by_curve(); + const VArray curves_cyclic = src_curves.cyclic(); + const VArray curve_types = src_curves.curve_types(); + const Span evaluated_positions = src_curves.evaluated_positions(); + MutableSpan dst_positions = dst_curves.positions_for_write(); AttributesForInterpolation attributes; @@ -335,7 +336,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, dst.slice(dst_points)); } else { - const int evaluated_size = src_curves.evaluated_points_for_curve(i_curve).size(); + const int evaluated_size = evaluated_points_by_curve.size(i_curve); evaluated_buffer.clear(); evaluated_buffer.resize(sizeof(T) * evaluated_size); MutableSpan evaluated = evaluated_buffer.as_mutable_span().cast(); @@ -352,7 +353,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, auto interpolate_evaluated_data = [&](const Span src, MutableSpan dst) { for (const int i_curve : sliced_selection) { - const IndexRange src_points = src_curves.evaluated_points_for_curve(i_curve); + const IndexRange src_points = evaluated_points_by_curve[i_curve]; const IndexRange dst_points = dst_points_by_curve[i_curve]; length_parameterize::interpolate(src.slice(src_points), sample_indices.as_span().slice(dst_points), @@ -366,11 +367,11 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, if (!attributes.dst_tangents.is_empty()) { interpolate_evaluated_data(attributes.src_evaluated_tangents, attributes.dst_tangents); - normalize_curve_point_data(dst_curves, sliced_selection, attributes.dst_tangents); + normalize_curve_point_data(sliced_selection, dst_points_by_curve, attributes.dst_tangents); } if (!attributes.dst_normals.is_empty()) { interpolate_evaluated_data(attributes.src_evaluated_normals, attributes.dst_normals); - normalize_curve_point_data(dst_curves, sliced_selection, attributes.dst_normals); + normalize_curve_point_data(sliced_selection, dst_points_by_curve, attributes.dst_normals); } /* Fill the default value for non-interpolating attributes that still must be copied. */ @@ -413,15 +414,15 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, const fn::Field &selection_field, const ResampleCurvesOutputAttributeIDs &output_ids) { - src_curves.ensure_evaluated_offsets(); - - bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE}; + const bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE}; fn::FieldEvaluator evaluator{field_context, src_curves.curves_num()}; evaluator.set_selection(selection_field); evaluator.evaluate(); const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); const Vector unselected_ranges = selection.extract_ranges_invert( src_curves.curves_range(), nullptr); + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices src_evaluated_points_by_curve = src_curves.evaluated_points_by_curve(); CurvesGeometry dst_curves(0, src_curves.curves_num()); @@ -433,16 +434,16 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, src_curves.curves_num()); /* All resampled curves are poly curves. */ dst_curves.fill_curve_types(selection, CURVE_TYPE_POLY); - MutableSpan dst_offsets = dst_curves.offsets_for_write(); - src_curves.ensure_can_interpolate_to_evaluated(); + MutableSpan dst_offsets = dst_curves.offsets_for_write(); threading::parallel_for(selection.index_range(), 4096, [&](IndexRange range) { for (const int i : selection.slice(range)) { - dst_offsets[i] = src_curves.evaluated_points_for_curve(i).size(); + dst_offsets[i] = src_evaluated_points_by_curve.size(i); } }); bke::curves::fill_curve_counts(src_curves, unselected_ranges, dst_offsets); offset_indices::accumulate_counts_to_offsets(dst_offsets); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); dst_curves.resize(dst_offsets.last(), dst_curves.curves_num()); @@ -453,8 +454,7 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, AttributesForInterpolation attributes; gather_point_attributes_to_interpolate(src_curves, dst_curves, attributes, output_ids); - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); - const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); + src_curves.ensure_can_interpolate_to_evaluated(); threading::parallel_for(selection.index_range(), 512, [&](IndexRange selection_range) { const IndexMask sliced_selection = selection.slice(selection_range); @@ -476,7 +476,7 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, auto copy_evaluated_data = [&](const Span src, MutableSpan dst) { for (const int i_curve : sliced_selection) { - const IndexRange src_points = src_curves.evaluated_points_for_curve(i_curve); + const IndexRange src_points = src_evaluated_points_by_curve[i_curve]; const IndexRange dst_points = dst_points_by_curve[i_curve]; dst.slice(dst_points).copy_from(src.slice(src_points)); } @@ -487,11 +487,11 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, if (!attributes.dst_tangents.is_empty()) { copy_evaluated_data(attributes.src_evaluated_tangents, attributes.dst_tangents); - normalize_curve_point_data(dst_curves, sliced_selection, attributes.dst_tangents); + normalize_curve_point_data(sliced_selection, dst_points_by_curve, attributes.dst_tangents); } if (!attributes.dst_normals.is_empty()) { copy_evaluated_data(attributes.src_evaluated_normals, attributes.dst_normals); - normalize_curve_point_data(dst_curves, sliced_selection, attributes.dst_normals); + normalize_curve_point_data(sliced_selection, dst_points_by_curve, attributes.dst_normals); } /* Fill the default value for non-interpolating attributes that still must be copied. */ diff --git a/source/blender/geometry/intern/subdivide_curves.cc b/source/blender/geometry/intern/subdivide_curves.cc index cdb0ed59b00..667146bd457 100644 --- a/source/blender/geometry/intern/subdivide_curves.cc +++ b/source/blender/geometry/intern/subdivide_curves.cc @@ -11,16 +11,6 @@ namespace blender::geometry { -/** - * Return a range used to retrieve values from an array of values stored per point, but with an - * extra element at the end of each curve. This is useful for offsets within curves, where it is - * convenient to store the first 0 and have the last offset be the total result curve size. - */ -static IndexRange curve_dst_offsets(const IndexRange points, const int curve_index) -{ - return {curve_index + points.start(), points.size() + 1}; -} - static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, const IndexMask selection, const Span unselected_ranges, @@ -35,7 +25,8 @@ static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) { for (const int curve_i : selection.slice(range)) { const IndexRange src_points = src_points_by_curve[curve_i]; - const IndexRange src_segments = curve_dst_offsets(src_points, curve_i); + const IndexRange src_segments = bke::curves::per_curve_point_offsets_range(src_points, + curve_i); MutableSpan point_offsets = dst_point_offsets.slice(src_segments); MutableSpan point_counts = point_offsets.drop_back(1); @@ -76,7 +67,7 @@ template static void subdivide_attribute_linear(const bke::CurvesGeometry &src_curves, const bke::CurvesGeometry &dst_curves, const IndexMask selection, - const Span point_offsets, + const Span all_point_offsets, const Span src, MutableSpan dst) { @@ -85,22 +76,21 @@ static void subdivide_attribute_linear(const bke::CurvesGeometry &src_curves, threading::parallel_for(selection.index_range(), 512, [&](IndexRange selection_range) { for (const int curve_i : selection.slice(selection_range)) { const IndexRange src_points = src_points_by_curve[curve_i]; - const IndexRange src_segments = curve_dst_offsets(src_points, curve_i); - const Span offsets = point_offsets.slice(src_segments); - + const IndexRange src_segments = bke::curves::per_curve_point_offsets_range(src_points, + curve_i); + const OffsetIndices curve_offsets = all_point_offsets.slice(src_segments); const IndexRange dst_points = dst_points_by_curve[curve_i]; const Span curve_src = src.slice(src_points); MutableSpan curve_dst = dst.slice(dst_points); threading::parallel_for(curve_src.index_range().drop_back(1), 1024, [&](IndexRange range) { for (const int i : range) { - const IndexRange segment_points = bke::offsets_to_range(offsets, i); + const IndexRange segment_points = curve_offsets[src_segments[i]]; linear_interpolation(curve_src[i], curve_src[i + 1], curve_dst.slice(segment_points)); } }); - const IndexRange dst_last_segment = dst_points.slice( - bke::offsets_to_range(offsets, src_points.size() - 1)); + const IndexRange dst_last_segment = dst_points.slice(curve_offsets[src_points.size() - 1]); linear_interpolation(curve_src.last(), curve_src.first(), dst.slice(dst_last_segment)); } }); @@ -109,14 +99,14 @@ static void subdivide_attribute_linear(const bke::CurvesGeometry &src_curves, static void subdivide_attribute_linear(const bke::CurvesGeometry &src_curves, const bke::CurvesGeometry &dst_curves, const IndexMask selection, - const Span point_offsets, + const Span all_point_offsets, const GSpan src, GMutableSpan dst) { attribute_math::convert_to_static_type(dst.type(), [&](auto dummy) { using T = decltype(dummy); subdivide_attribute_linear( - src_curves, dst_curves, selection, point_offsets, src.typed(), dst.typed()); + src_curves, dst_curves, selection, all_point_offsets, src.typed(), dst.typed()); }); } @@ -124,7 +114,7 @@ template static void subdivide_attribute_catmull_rom(const bke::CurvesGeometry &src_curves, const bke::CurvesGeometry &dst_curves, const IndexMask selection, - const Span point_offsets, + const Span all_point_offsets, const Span cyclic, const Span src, MutableSpan dst) @@ -134,12 +124,12 @@ static void subdivide_attribute_catmull_rom(const bke::CurvesGeometry &src_curve threading::parallel_for(selection.index_range(), 512, [&](IndexRange selection_range) { for (const int curve_i : selection.slice(selection_range)) { const IndexRange src_points = src_points_by_curve[curve_i]; - const IndexRange src_segments = curve_dst_offsets(src_points, curve_i); + const IndexRange src_segments = bke::curves::per_curve_point_offsets_range(src_points, + curve_i); const IndexRange dst_points = dst_points_by_curve[curve_i]; - bke::curves::catmull_rom::interpolate_to_evaluated(src.slice(src_points), cyclic[curve_i], - point_offsets.slice(src_segments), + all_point_offsets.slice(src_segments), dst.slice(dst_points)); } }); @@ -148,15 +138,20 @@ static void subdivide_attribute_catmull_rom(const bke::CurvesGeometry &src_curve static void subdivide_attribute_catmull_rom(const bke::CurvesGeometry &src_curves, const bke::CurvesGeometry &dst_curves, const IndexMask selection, - const Span point_offsets, + const Span all_point_offsets, const Span cyclic, const GSpan src, GMutableSpan dst) { attribute_math::convert_to_static_type(dst.type(), [&](auto dummy) { using T = decltype(dummy); - subdivide_attribute_catmull_rom( - src_curves, dst_curves, selection, point_offsets, cyclic, src.typed(), dst.typed()); + subdivide_attribute_catmull_rom(src_curves, + dst_curves, + selection, + all_point_offsets, + cyclic, + src.typed(), + dst.typed()); }); } @@ -231,7 +226,7 @@ static void subdivide_bezier_positions(const Span src_positions, const Span src_types_r, const Span src_handles_l, const Span src_handles_r, - const Span evaluated_offsets, + const OffsetIndices evaluated_offsets, const bool cyclic, MutableSpan dst_positions, MutableSpan dst_types_l, @@ -241,7 +236,7 @@ static void subdivide_bezier_positions(const Span src_positions, { threading::parallel_for(src_positions.index_range().drop_back(1), 512, [&](IndexRange range) { for (const int segment_i : range) { - const IndexRange segment = bke::offsets_to_range(evaluated_offsets, segment_i); + const IndexRange segment = evaluated_offsets[segment_i]; subdivide_bezier_segment(src_positions[segment_i], src_handles_r[segment_i], src_handles_l[segment_i + 1], @@ -260,7 +255,7 @@ static void subdivide_bezier_positions(const Span src_positions, if (cyclic) { const int last_index = src_positions.index_range().last(); - const IndexRange segment = bke::offsets_to_range(evaluated_offsets, last_index); + const IndexRange segment = evaluated_offsets[last_index]; const HandleType type_prev = HandleType(src_types_r.last()); const HandleType type_next = HandleType(src_types_l.first()); subdivide_bezier_segment(src_positions.last(), @@ -325,9 +320,9 @@ bke::CurvesGeometry subdivide_curves( * * Storing the leading zero is unnecessary but makes the array a bit simpler to use by avoiding * a check for the first segment, and because some existing utilities also use leading zeros. */ - Array dst_point_offsets(src_curves.points_num() + src_curves.curves_num()); + Array all_point_offset_data(src_curves.points_num() + src_curves.curves_num()); #ifdef DEBUG - dst_point_offsets.fill(-1); + all_point_offset_data.fill(-1); #endif calculate_result_offsets(src_curves, selection, @@ -335,8 +330,8 @@ bke::CurvesGeometry subdivide_curves( cuts, cyclic, dst_curves.offsets_for_write(), - dst_point_offsets); - const Span point_offsets = dst_point_offsets.as_span(); + all_point_offset_data); + const Span all_point_offsets(all_point_offset_data); dst_curves.resize(dst_curves.offsets().last(), dst_curves.curves_num()); @@ -349,7 +344,7 @@ bke::CurvesGeometry subdivide_curves( subdivide_attribute_catmull_rom(src_curves, dst_curves, selection, - point_offsets, + all_point_offsets, cyclic, attribute.src, attribute.dst.span); @@ -361,7 +356,7 @@ bke::CurvesGeometry subdivide_curves( for (auto &attribute : bke::retrieve_attributes_for_transfer( src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info)) { subdivide_attribute_linear( - src_curves, dst_curves, selection, point_offsets, attribute.src, attribute.dst.span); + src_curves, dst_curves, selection, all_point_offsets, attribute.src, attribute.dst.span); attribute.dst.finish(); } }; @@ -384,15 +379,15 @@ bke::CurvesGeometry subdivide_curves( threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int curve_i : selection.slice(range)) { const IndexRange src_points = src_points_by_curve[curve_i]; - const IndexRange src_segments = curve_dst_offsets(src_points, curve_i); - + const IndexRange src_segments = bke::curves::per_curve_point_offsets_range(src_points, + curve_i); const IndexRange dst_points = dst_points_by_curve[curve_i]; subdivide_bezier_positions(src_positions.slice(src_points), src_types_l.slice(src_points), src_types_r.slice(src_points), src_handles_l.slice(src_points), src_handles_r.slice(src_points), - point_offsets.slice(src_segments), + all_point_offsets.slice(src_segments), cyclic[curve_i], dst_positions.slice(dst_points), dst_types_l.slice(dst_points), @@ -412,7 +407,7 @@ bke::CurvesGeometry subdivide_curves( "handle_right", "handle_left"})) { subdivide_attribute_linear( - src_curves, dst_curves, selection, point_offsets, attribute.src, attribute.dst.span); + src_curves, dst_curves, selection, all_point_offsets, attribute.src, attribute.dst.span); attribute.dst.finish(); } }; diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc index eaa0cb35973..0879718a73a 100644 --- a/source/blender/geometry/intern/trim_curves.cc +++ b/source/blender/geometry/intern/trim_curves.cc @@ -107,30 +107,29 @@ static bke::curves::CurvePoint lookup_point_bezier(const Span bezier_offset /* Find the segment index from the offset mapping. */ const int *offset = std::upper_bound(bezier_offsets.begin(), bezier_offsets.end(), eval_index); - const int left = offset - bezier_offsets.begin(); + const int left = offset - bezier_offsets.begin() - 1; const int right = left == last_index ? 0 : left + 1; - const int prev_offset = left == 0 ? 0 : bezier_offsets[int64_t(left) - 1]; + const int prev_offset = bezier_offsets[left]; const float offset_in_segment = eval_factor + (eval_index - prev_offset); - const int segment_resolution = bezier_offsets[left] - prev_offset; + const int segment_resolution = bezier_offsets[left + 1] - prev_offset; const float parameter = std::clamp(offset_in_segment / segment_resolution, 0.0f, 1.0f); return {{left, right}, parameter}; } -static bke::curves::CurvePoint lookup_point_bezier(const bke::CurvesGeometry &src_curves, - const int64_t curve_index, - const Span accumulated_lengths, - const float sample_length, - const bool cyclic, - const int resolution, - const int num_curve_points) +static bke::curves::CurvePoint lookup_point_bezier( + const bke::CurvesGeometry &src_curves, + const OffsetIndices evaluated_points_by_curve, + const int64_t curve_index, + const Span accumulated_lengths, + const float sample_length, + const bool cyclic, + const int resolution, + const int num_curve_points) { if (bke::curves::bezier::has_vector_handles( - num_curve_points, - src_curves.evaluated_points_for_curve(curve_index).size(), - cyclic, - resolution)) { + num_curve_points, evaluated_points_by_curve.size(curve_index), cyclic, resolution)) { const Span bezier_offsets = src_curves.bezier_evaluated_offsets_for_curve(curve_index); return lookup_point_bezier( bezier_offsets, accumulated_lengths, sample_length, cyclic, num_curve_points); @@ -141,14 +140,16 @@ static bke::curves::CurvePoint lookup_point_bezier(const bke::CurvesGeometry &sr } } -static bke::curves::CurvePoint lookup_curve_point(const bke::CurvesGeometry &src_curves, - const CurveType curve_type, - const int64_t curve_index, - const Span accumulated_lengths, - const float sample_length, - const bool cyclic, - const int resolution, - const int num_curve_points) +static bke::curves::CurvePoint lookup_curve_point( + const bke::CurvesGeometry &src_curves, + const OffsetIndices evaluated_points_by_curve, + const CurveType curve_type, + const int64_t curve_index, + const Span accumulated_lengths, + const float sample_length, + const bool cyclic, + const int resolution, + const int num_curve_points) { if (num_curve_points == 1) { return {{0, 0}, 0.0f}; @@ -160,6 +161,7 @@ static bke::curves::CurvePoint lookup_curve_point(const bke::CurvesGeometry &src } else if (curve_type == CURVE_TYPE_BEZIER) { return lookup_point_bezier(src_curves, + evaluated_points_by_curve, curve_index, accumulated_lengths, sample_length, @@ -173,10 +175,8 @@ static bke::curves::CurvePoint lookup_curve_point(const bke::CurvesGeometry &src else { /* Handle evaluated curve. */ BLI_assert(resolution > 0); - return lookup_point_polygonal(accumulated_lengths, - sample_length, - cyclic, - src_curves.evaluated_points_for_curve(curve_index).size()); + return lookup_point_polygonal( + accumulated_lengths, sample_length, cyclic, evaluated_points_by_curve.size(curve_index)); } } @@ -762,15 +762,15 @@ static void trim_evaluated_curves(const bke::CurvesGeometry &src_curves, MutableSpan transfer_attributes) { const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices src_evaluated_points_by_curve = src_curves.evaluated_points_by_curve(); const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); const Span src_eval_positions = src_curves.evaluated_positions(); MutableSpan dst_positions = dst_curves.positions_for_write(); threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) { for (const int64_t curve_i : selection.slice(range)) { + const IndexRange src_evaluated_points = src_evaluated_points_by_curve[curve_i]; const IndexRange dst_points = dst_points_by_curve[curve_i]; - const IndexRange src_evaluated_points = src_curves.evaluated_points_for_curve(curve_i); - sample_interval_linear(src_eval_positions.slice(src_evaluated_points), dst_positions, src_ranges[curve_i], @@ -789,8 +789,7 @@ static void trim_evaluated_curves(const bke::CurvesGeometry &src_curves, threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) { for (const int64_t curve_i : selection.slice(range)) { /* Interpolate onto the evaluated point domain and sample the evaluated domain. */ - const IndexRange src_evaluated_points = src_curves.evaluated_points_for_curve(curve_i); - GArray<> evaluated_data(CPPType::get(), src_evaluated_points.size()); + GArray<> evaluated_data(CPPType::get(), src_evaluated_points_by_curve.size(curve_i)); GMutableSpan evaluated_span = evaluated_data.as_mutable_span(); src_curves.interpolate_to_evaluated( curve_i, attribute.src.slice(src_points_by_curve[curve_i]), evaluated_span); @@ -836,6 +835,7 @@ static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves, MutableSpan src_ranges) { const OffsetIndices points_by_curve = curves.points_by_curve(); + const OffsetIndices evaluated_points_by_curve = curves.evaluated_points_by_curve(); const VArray src_cyclic = curves.cyclic(); const VArray resolution = curves.resolution(); const VArray curve_types = curves.curve_types(); @@ -848,7 +848,7 @@ static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves, int point_count; if (curve_type == CURVE_TYPE_NURBS) { dst_curve_types[curve_i] = CURVE_TYPE_POLY; - point_count = curves.evaluated_points_for_curve(curve_i).size(); + point_count = evaluated_points_by_curve.size(curve_i); } else { dst_curve_types[curve_i] = curve_type; @@ -885,6 +885,7 @@ static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves, } start_points[curve_i] = lookup_curve_point(curves, + evaluated_points_by_curve, curve_type, curve_i, lengths, @@ -920,6 +921,7 @@ static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves, else { /* General case. */ end_points[curve_i] = lookup_curve_point(curves, + evaluated_points_by_curve, curve_type, curve_i, lengths, @@ -968,7 +970,6 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, Array src_ranges(src_curves.curves_num()); if (src_curves.has_curve_with_type({CURVE_TYPE_BEZIER, CURVE_TYPE_NURBS})) { - src_curves.ensure_evaluated_offsets(); if (src_curves.has_curve_with_type(CURVE_TYPE_NURBS)) { src_curves.evaluated_positions(); } @@ -1059,7 +1060,6 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, }; auto trim_evaluated = [&](const IndexMask selection) { /* Ensure evaluated positions are available. */ - src_curves.ensure_evaluated_offsets(); src_curves.evaluated_positions(); trim_evaluated_curves(src_curves, dst_curves, diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc index acd888c6780..c09a128a3c1 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_fill.cc @@ -43,15 +43,16 @@ static void node_init(bNodeTree * /*tree*/, bNode *node) static meshintersect::CDT_result do_cdt(const bke::CurvesGeometry &curves, const CDT_output_type output_type) { + const OffsetIndices points_by_curve = curves.evaluated_points_by_curve(); + const Span positions = curves.evaluated_positions(); + meshintersect::CDT_input input; input.need_ids = false; - input.vert.reinitialize(curves.evaluated_points_num()); + input.vert.reinitialize(points_by_curve.total_size()); input.face.reinitialize(curves.curves_num()); - Span positions = curves.evaluated_positions(); - for (const int i_curve : curves.curves_range()) { - const IndexRange points = curves.evaluated_points_for_curve(i_curve); + const IndexRange points = points_by_curve[i_curve]; for (const int i : points) { input.vert[i] = double2(positions[i].x, positions[i].y); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc index 4839c2929d6..9b703f952bb 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_sample.cc @@ -313,6 +313,7 @@ class SampleCurveFunction : public mf::MultiFunction { } const OffsetIndices points_by_curve = curves.points_by_curve(); + const OffsetIndices evaluated_points_by_curve = curves.evaluated_points_by_curve(); const VArray curve_indices = params.readonly_single_input(0, "Curve Index"); const VArraySpan lengths = params.readonly_single_input(1, "Length"); const VArray cyclic = curves.cyclic(); @@ -354,7 +355,7 @@ class SampleCurveFunction : public mf::MultiFunction { sample_indices_and_factors_to_compressed( accumulated_lengths, lengths, length_mode_, mask, indices, factors); - const IndexRange evaluated_points = curves.evaluated_points_for_curve(curve_i); + const IndexRange evaluated_points = evaluated_points_by_curve[curve_i]; if (!sampled_positions.is_empty()) { length_parameterize::interpolate_to_masked( evaluated_positions.slice(evaluated_points), @@ -381,7 +382,7 @@ class SampleCurveFunction : public mf::MultiFunction { const IndexRange points = points_by_curve[curve_i]; src_original_values.reinitialize(points.size()); source_data_->materialize_compressed_to_uninitialized(points, src_original_values.data()); - src_evaluated_values.reinitialize(curves.evaluated_points_for_curve(curve_i).size()); + src_evaluated_values.reinitialize(evaluated_points.size()); curves.interpolate_to_evaluated(curve_i, src_original_values, src_evaluated_values); attribute_math::convert_to_static_type(source_data_->type(), [&](auto dummy) { using T = decltype(dummy); diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc index 8b8f436c36a..9e9bccb004e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_spline_parameter.cc @@ -35,7 +35,7 @@ static Array accumulated_lengths_curve_domain(const bke::CurvesGeometry & curves.ensure_evaluated_lengths(); Array lengths(curves.curves_num()); - VArray cyclic = curves.cyclic(); + const VArray cyclic = curves.cyclic(); float length = 0.0f; for (const int i : curves.curves_range()) { lengths[i] = length; @@ -86,7 +86,7 @@ static Array curve_length_point_domain(const bke::CurvesGeometry &curves) case CURVE_TYPE_BEZIER: { const Span offsets = curves.bezier_evaluated_offsets_for_curve(i_curve); for (const int i : IndexRange(points.size()).drop_back(1)) { - lengths[i + 1] = evaluated_lengths[offsets[i] - 1]; + lengths[i + 1] = evaluated_lengths[offsets[i + 1] - 1]; } break; } @@ -110,7 +110,7 @@ static VArray construct_curve_parameter_varray(const bke::CurvesGeometry const IndexMask /*mask*/, const eAttrDomain domain) { - VArray cyclic = curves.cyclic(); + const VArray cyclic = curves.cyclic(); if (domain == ATTR_DOMAIN_POINT) { Array result = curve_length_point_domain(curves); diff --git a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc index d036599df1a..0ec26a60ebd 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_input_tangent.cc @@ -16,6 +16,7 @@ static void node_declare(NodeDeclarationBuilder &b) static Array curve_tangent_point_domain(const bke::CurvesGeometry &curves) { const OffsetIndices points_by_curve = curves.points_by_curve(); + const OffsetIndices evaluated_points_by_curve = curves.evaluated_points_by_curve(); const VArray types = curves.curve_types(); const VArray resolutions = curves.resolution(); const VArray cyclic = curves.cyclic(); @@ -28,7 +29,7 @@ static Array curve_tangent_point_domain(const bke::CurvesGeometry &curve threading::parallel_for(curves.curves_range(), 128, [&](IndexRange range) { for (const int i_curve : range) { const IndexRange points = points_by_curve[i_curve]; - const IndexRange evaluated_points = curves.evaluated_points_for_curve(i_curve); + const IndexRange evaluated_points = evaluated_points_by_curve[i_curve]; MutableSpan curve_tangents = results.as_mutable_span().slice(points); @@ -49,7 +50,7 @@ static Array curve_tangent_point_domain(const bke::CurvesGeometry &curve curve_tangents.first() = tangents.first(); const Span offsets = curves.bezier_evaluated_offsets_for_curve(i_curve); for (const int i : IndexRange(points.size()).drop_front(1)) { - curve_tangents[i] = tangents[offsets[i - 1]]; + curve_tangents[i] = tangents[offsets[i]]; } break; } From 76673e5fcfc814a8aca2ecd1f5d9cdf37a6a96d5 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 13:48:54 -0600 Subject: [PATCH 0784/1522] Cleanup: Use OffsetIndices abstraction in duplicate elements node --- .../nodes/node_geo_duplicate_elements.cc | 201 ++++++++++-------- 1 file changed, 107 insertions(+), 94 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc index 480fd516360..90f089ae3df 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_duplicate_elements.cc @@ -3,6 +3,7 @@ #include "BLI_array_utils.hh" #include "BLI_map.hh" #include "BLI_noise.hh" +#include "BLI_offset_indices.hh" #include "BLI_span.hh" #include "BLI_task.hh" @@ -75,36 +76,27 @@ static Map gather_attributes_without_id( return attributes; }; -static IndexRange range_for_offsets_index(const Span offsets, const int index) +static OffsetIndices accumulate_counts_to_offsets(const IndexMask selection, + const VArray &counts, + Array &r_offset_data) { - return {offsets[index], offsets[index + 1] - offsets[index]}; -} - -static Array accumulate_counts_to_offsets(const IndexMask selection, - const VArray &counts) -{ - Array offsets(selection.size() + 1); - int total = 0; - for (const int i : selection.index_range()) { - offsets[i] = total; - total += std::max(counts[selection[i]], 0); - } - offsets.last() = total; - return offsets; + r_offset_data.reinitialize(selection.size() + 1); + counts.materialize_compressed(selection, r_offset_data); + offset_indices::accumulate_counts_to_offsets(r_offset_data); + return OffsetIndices(r_offset_data); } /* Utility functions for threaded copying of attribute data where possible. */ template -static void threaded_slice_fill(Span offsets, +static void threaded_slice_fill(const OffsetIndices offsets, const IndexMask selection, - Span src, + const Span src, MutableSpan dst) { - BLI_assert(offsets.last() == dst.size()); - BLI_assert(selection.size() == offsets.size() - 1); - threading::parallel_for(IndexRange(offsets.size() - 1), 512, [&](IndexRange range) { + BLI_assert(offsets.total_size() == dst.size()); + threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i : range) { - dst.slice(range_for_offsets_index(offsets, i)).fill(src[selection[i]]); + dst.slice(offsets[i]).fill(src[selection[i]]); } }); } @@ -116,20 +108,20 @@ static void copy_hashed_ids(const Span src, const int hash, MutableSpan offsets, +static void threaded_id_offset_copy(const OffsetIndices offsets, const Span src, - MutableSpan dst) + MutableSpan all_dst) { - BLI_assert(offsets.last() == dst.size()); - threading::parallel_for(IndexRange(offsets.size() - 1), 512, [&](IndexRange range) { + BLI_assert(offsets.total_size() == all_dst.size()); + threading::parallel_for(IndexRange(offsets.ranges_num()), 512, [&](IndexRange range) { for (const int i : range) { - dst[offsets[i]] = src[i]; - const int count = offsets[i + 1] - offsets[i]; - if (count == 0) { + MutableSpan dst = all_dst.slice(offsets[i]); + if (dst.is_empty()) { continue; } - for (const int i_duplicate : IndexRange(1, count - 1)) { - dst[offsets[i] + i_duplicate] = noise::hash(src[i], i_duplicate); + dst.first() = src[i]; + for (const int i_duplicate : dst.index_range().drop_front(1)) { + dst[i_duplicate] = noise::hash(src[i], i_duplicate); } } }); @@ -140,13 +132,12 @@ static void create_duplicate_index_attribute(bke::MutableAttributeAccessor attri const eAttrDomain output_domain, const IndexMask selection, const IndexAttributes &attribute_outputs, - const Span offsets) + const OffsetIndices offsets) { SpanAttributeWriter duplicate_indices = attributes.lookup_or_add_for_write_only_span( attribute_outputs.duplicate_index.get(), output_domain); for (const int i : IndexRange(selection.size())) { - const IndexRange range = range_for_offsets_index(offsets, i); - MutableSpan indices = duplicate_indices.span.slice(range); + MutableSpan indices = duplicate_indices.span.slice(offsets[i]); for (const int i : indices.index_range()) { indices[i] = i; } @@ -158,7 +149,7 @@ static void create_duplicate_index_attribute(bke::MutableAttributeAccessor attri * Copy the stable ids to the first duplicate and create new ids based on a hash of the original id * and the duplicate number. This function is used for the point domain elements. */ -static void copy_stable_id_point(const Span offsets, +static void copy_stable_id_point(const OffsetIndices offsets, const bke::AttributeAccessor src_attributes, bke::MutableAttributeAccessor dst_attributes) { @@ -181,7 +172,7 @@ static void copy_stable_id_point(const Span offsets, static void copy_attributes_without_id(GeometrySet &geometry_set, const GeometryComponentType component_type, const eAttrDomain domain, - const Span offsets, + const OffsetIndices offsets, const IndexMask selection, const AnonymousAttributePropagationInfo &propagation_info, const bke::AttributeAccessor src_attributes, @@ -228,7 +219,7 @@ static void copy_curve_attributes_without_id( const GeometrySet &geometry_set, const bke::CurvesGeometry &src_curves, const IndexMask selection, - const Span curve_offsets, + const OffsetIndices curve_offsets, const AnonymousAttributePropagationInfo &propagation_info, bke::CurvesGeometry &dst_curves) { @@ -269,7 +260,7 @@ static void copy_curve_attributes_without_id( for (const int i_selection : range) { const int i_src_curve = selection[i_selection]; const Span curve_src = src.slice(src_points_by_curve[i_src_curve]); - for (const int i_dst_curve : range_for_offsets_index(curve_offsets, i_selection)) { + for (const int i_dst_curve : curve_offsets[i_selection]) { dst.slice(dst_points_by_curve[i_dst_curve]).copy_from(curve_src); } } @@ -291,7 +282,7 @@ static void copy_curve_attributes_without_id( */ static void copy_stable_id_curves(const bke::CurvesGeometry &src_curves, const IndexMask selection, - const Span curve_offsets, + const OffsetIndices offsets, bke::CurvesGeometry &dst_curves) { GAttributeReader src_attribute = src_curves.attributes().lookup("id"); @@ -315,8 +306,8 @@ static void copy_stable_id_curves(const bke::CurvesGeometry &src_curves, for (const int i_selection : range) { const int i_src_curve = selection[i_selection]; const Span curve_src = src.slice(src_points_by_curve[i_src_curve]); - const IndexRange duplicates_range = range_for_offsets_index(curve_offsets, i_selection); - for (const int i_duplicate : IndexRange(duplicates_range.size()).drop_front(1)) { + const IndexRange duplicates_range = offsets[i_selection]; + for (const int i_duplicate : IndexRange(offsets.size(i_selection)).drop_front(1)) { const int i_dst_curve = duplicates_range[i_duplicate]; copy_hashed_ids(curve_src, i_duplicate, dst.slice(dst_points_by_curve[i_dst_curve])); } @@ -352,20 +343,23 @@ static void duplicate_curves(GeometrySet &geometry_set, const OffsetIndices points_by_curve = curves.points_by_curve(); /* The offset in the result curve domain at every selected input curve. */ - Array curve_offsets(selection.size() + 1); - Array point_offsets(selection.size() + 1); + Array curve_offset_data(selection.size() + 1); + Array point_offset_data(selection.size() + 1); int dst_curves_num = 0; int dst_points_num = 0; for (const int i_curve : selection.index_range()) { const int count = std::max(counts[selection[i_curve]], 0); - curve_offsets[i_curve] = dst_curves_num; - point_offsets[i_curve] = dst_points_num; + curve_offset_data[i_curve] = dst_curves_num; + point_offset_data[i_curve] = dst_points_num; dst_curves_num += count; dst_points_num += count * points_by_curve.size(selection[i_curve]); } - curve_offsets.last() = dst_curves_num; - point_offsets.last() = dst_points_num; + curve_offset_data.last() = dst_curves_num; + point_offset_data.last() = dst_points_num; + + const OffsetIndices curve_offsets(curve_offset_data); + const OffsetIndices point_offsets(point_offset_data); Curves *new_curves_id = bke::curves_new_nomain(dst_points_num, dst_curves_num); bke::curves_copy_parameters(curves_id, *new_curves_id); @@ -376,10 +370,10 @@ static void duplicate_curves(GeometrySet &geometry_set, for (const int i_selection : range) { const int i_src_curve = selection[i_selection]; const IndexRange src_curve_range = points_by_curve[i_src_curve]; - const IndexRange dst_curves_range = range_for_offsets_index(curve_offsets, i_selection); + const IndexRange dst_curves_range = curve_offsets[i_selection]; MutableSpan dst_offsets = all_dst_offsets.slice(dst_curves_range); for (const int i_duplicate : IndexRange(dst_curves_range.size())) { - dst_offsets[i_duplicate] = point_offsets[i_selection] + + dst_offsets[i_duplicate] = point_offsets[i_selection].start() + src_curve_range.size() * i_duplicate; } } @@ -417,7 +411,7 @@ static void copy_face_attributes_without_id( const Span edge_mapping, const Span vert_mapping, const Span loop_mapping, - const Span offsets, + const OffsetIndices offsets, const IndexMask selection, const AnonymousAttributePropagationInfo &propagation_info, const bke::AttributeAccessor src_attributes, @@ -477,7 +471,7 @@ static void copy_face_attributes_without_id( */ static void copy_stable_id_faces(const Mesh &mesh, const IndexMask selection, - const Span poly_offsets, + const OffsetIndices poly_offsets, const Span vert_mapping, const bke::AttributeAccessor src_attributes, bke::MutableAttributeAccessor dst_attributes) @@ -498,7 +492,7 @@ static void copy_stable_id_faces(const Mesh &mesh, const Span polys = mesh.polys(); int loop_index = 0; for (const int i_poly : selection.index_range()) { - const IndexRange range = range_for_offsets_index(poly_offsets, i_poly); + const IndexRange range = poly_offsets[i_poly]; if (range.size() == 0) { continue; } @@ -546,14 +540,16 @@ static void duplicate_faces(GeometrySet &geometry_set, int total_polys = 0; int total_loops = 0; - Array offsets(selection.size() + 1); + Array offset_data(selection.size() + 1); for (const int i_selection : selection.index_range()) { const int count = std::max(counts[selection[i_selection]], 0); - offsets[i_selection] = total_polys; + offset_data[i_selection] = total_polys; total_polys += count; total_loops += count * polys[selection[i_selection]].totloop; } - offsets[selection.size()] = total_polys; + offset_data[selection.size()] = total_polys; + + const OffsetIndices duplicates(offset_data); Mesh *new_mesh = BKE_mesh_new_nomain(total_loops, total_loops, 0, total_loops, total_polys); MutableSpan new_edges = new_mesh->edges_for_write(); @@ -567,7 +563,7 @@ static void duplicate_faces(GeometrySet &geometry_set, int poly_index = 0; int loop_index = 0; for (const int i_selection : selection.index_range()) { - const IndexRange poly_range = range_for_offsets_index(offsets, i_selection); + const IndexRange poly_range = duplicates[i_selection]; const MPoly &source = polys[selection[i_selection]]; for ([[maybe_unused]] const int i_duplicate : IndexRange(poly_range.size())) { @@ -600,18 +596,25 @@ static void duplicate_faces(GeometrySet &geometry_set, edge_mapping, vert_mapping, loop_mapping, - offsets, + duplicates, selection, propagation_info, mesh.attributes(), new_mesh->attributes_for_write()); - copy_stable_id_faces( - mesh, selection, offsets, vert_mapping, mesh.attributes(), new_mesh->attributes_for_write()); + copy_stable_id_faces(mesh, + selection, + duplicates, + vert_mapping, + mesh.attributes(), + new_mesh->attributes_for_write()); if (attribute_outputs.duplicate_index) { - create_duplicate_index_attribute( - new_mesh->attributes_for_write(), ATTR_DOMAIN_FACE, selection, attribute_outputs, offsets); + create_duplicate_index_attribute(new_mesh->attributes_for_write(), + ATTR_DOMAIN_FACE, + selection, + attribute_outputs, + duplicates); } geometry_set.replace_mesh(new_mesh); @@ -630,7 +633,7 @@ static void duplicate_faces(GeometrySet &geometry_set, static void copy_edge_attributes_without_id( GeometrySet &geometry_set, const Span point_mapping, - const Span offsets, + const OffsetIndices offsets, const IndexMask selection, const AnonymousAttributePropagationInfo &propagation_info, const bke::AttributeAccessor src_attributes, @@ -680,7 +683,7 @@ static void copy_edge_attributes_without_id( */ static void copy_stable_id_edges(const Mesh &mesh, const IndexMask selection, - const Span edge_offsets, + const OffsetIndices offsets, const bke::AttributeAccessor src_attributes, bke::MutableAttributeAccessor dst_attributes) { @@ -700,7 +703,7 @@ static void copy_stable_id_edges(const Mesh &mesh, MutableSpan dst = dst_attribute.span.typed(); threading::parallel_for(IndexRange(selection.size()), 1024, [&](IndexRange range) { for (const int i_selection : range) { - const IndexRange edge_range = range_for_offsets_index(edge_offsets, i_selection); + const IndexRange edge_range = offsets[i_selection]; if (edge_range.size() == 0) { continue; } @@ -739,16 +742,19 @@ static void duplicate_edges(GeometrySet &geometry_set, const VArray counts = evaluator.get_evaluated(0); const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); - Array edge_offsets = accumulate_counts_to_offsets(selection, counts); + Array offset_data; + const OffsetIndices duplicates = accumulate_counts_to_offsets( + selection, counts, offset_data); + const int output_edges_num = duplicates.total_size(); - Mesh *new_mesh = BKE_mesh_new_nomain(edge_offsets.last() * 2, edge_offsets.last(), 0, 0, 0); + Mesh *new_mesh = BKE_mesh_new_nomain(output_edges_num * 2, output_edges_num, 0, 0, 0); MutableSpan new_edges = new_mesh->edges_for_write(); - Array vert_orig_indices(edge_offsets.last() * 2); + Array vert_orig_indices(output_edges_num * 2); threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) { for (const int i_selection : range) { const MEdge &edge = edges[selection[i_selection]]; - const IndexRange edge_range = range_for_offsets_index(edge_offsets, i_selection); + const IndexRange edge_range = duplicates[i_selection]; const IndexRange vert_range(edge_range.start() * 2, edge_range.size() * 2); for (const int i_duplicate : IndexRange(edge_range.size())) { @@ -760,7 +766,7 @@ static void duplicate_edges(GeometrySet &geometry_set, threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) { for (const int i_selection : range) { - const IndexRange edge_range = range_for_offsets_index(edge_offsets, i_selection); + const IndexRange edge_range = duplicates[i_selection]; const IndexRange vert_range(edge_range.start() * 2, edge_range.size() * 2); for (const int i_duplicate : IndexRange(edge_range.size())) { MEdge &new_edge = new_edges[edge_range[i_duplicate]]; @@ -772,21 +778,21 @@ static void duplicate_edges(GeometrySet &geometry_set, copy_edge_attributes_without_id(geometry_set, vert_orig_indices, - edge_offsets, + duplicates, selection, propagation_info, mesh.attributes(), new_mesh->attributes_for_write()); copy_stable_id_edges( - mesh, selection, edge_offsets, mesh.attributes(), new_mesh->attributes_for_write()); + mesh, selection, duplicates, mesh.attributes(), new_mesh->attributes_for_write()); if (attribute_outputs.duplicate_index) { create_duplicate_index_attribute(new_mesh->attributes_for_write(), ATTR_DOMAIN_EDGE, selection, attribute_outputs, - edge_offsets); + duplicates); } geometry_set.replace_mesh(new_mesh); @@ -818,8 +824,10 @@ static void duplicate_points_curve(GeometrySet &geometry_set, const VArray counts = evaluator.get_evaluated(0); const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); - Array offsets = accumulate_counts_to_offsets(selection, counts); - const int dst_num = offsets.last(); + Array offset_data; + const OffsetIndices duplicates = accumulate_counts_to_offsets( + selection, counts, offset_data); + const int dst_num = duplicates.total_size(); const Array point_to_curve_map = src_curves.point_to_curve_map(); @@ -862,13 +870,12 @@ static void duplicate_points_curve(GeometrySet &geometry_set, threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i_selection : range) { const T &src_value = src[point_to_curve_map[selection[i_selection]]]; - const IndexRange duplicate_range = range_for_offsets_index(offsets, i_selection); - dst.slice(duplicate_range).fill(src_value); + dst.slice(duplicates[i_selection]).fill(src_value); } }); break; case ATTR_DOMAIN_POINT: - threaded_slice_fill(offsets, selection, src, dst); + threaded_slice_fill(duplicates, selection, src, dst); break; default: break; @@ -877,14 +884,14 @@ static void duplicate_points_curve(GeometrySet &geometry_set, dst_attribute.finish(); } - copy_stable_id_point(offsets, src_curves.attributes(), new_curves.attributes_for_write()); + copy_stable_id_point(duplicates, src_curves.attributes(), new_curves.attributes_for_write()); if (attribute_outputs.duplicate_index) { create_duplicate_index_attribute(new_curves.attributes_for_write(), ATTR_DOMAIN_POINT, selection, attribute_outputs, - offsets.as_span()); + duplicates); } geometry_set.replace_curves(new_curves_id); @@ -912,27 +919,29 @@ static void duplicate_points_mesh(GeometrySet &geometry_set, const VArray counts = evaluator.get_evaluated(0); const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); - Array offsets = accumulate_counts_to_offsets(selection, counts); + Array offset_data; + const OffsetIndices duplicates = accumulate_counts_to_offsets( + selection, counts, offset_data); - Mesh *new_mesh = BKE_mesh_new_nomain(offsets.last(), 0, 0, 0, 0); + Mesh *new_mesh = BKE_mesh_new_nomain(duplicates.total_size(), 0, 0, 0, 0); copy_attributes_without_id(geometry_set, GEO_COMPONENT_TYPE_MESH, ATTR_DOMAIN_POINT, - offsets, + duplicates, selection, propagation_info, mesh.attributes(), new_mesh->attributes_for_write()); - copy_stable_id_point(offsets, mesh.attributes(), new_mesh->attributes_for_write()); + copy_stable_id_point(duplicates, mesh.attributes(), new_mesh->attributes_for_write()); if (attribute_outputs.duplicate_index) { create_duplicate_index_attribute(new_mesh->attributes_for_write(), ATTR_DOMAIN_POINT, selection, attribute_outputs, - offsets.as_span()); + duplicates); } geometry_set.replace_mesh(new_mesh); @@ -960,27 +969,29 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set, const VArray counts = evaluator.get_evaluated(0); const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); - Array offsets = accumulate_counts_to_offsets(selection, counts); + Array offset_data; + const OffsetIndices duplicates = accumulate_counts_to_offsets( + selection, counts, offset_data); - PointCloud *pointcloud = BKE_pointcloud_new_nomain(offsets.last()); + PointCloud *pointcloud = BKE_pointcloud_new_nomain(duplicates.total_size()); copy_attributes_without_id(geometry_set, GEO_COMPONENT_TYPE_POINT_CLOUD, ATTR_DOMAIN_POINT, - offsets, + duplicates, selection, propagation_info, src_points.attributes(), pointcloud->attributes_for_write()); - copy_stable_id_point(offsets, src_points.attributes(), pointcloud->attributes_for_write()); + copy_stable_id_point(duplicates, src_points.attributes(), pointcloud->attributes_for_write()); if (attribute_outputs.duplicate_index) { create_duplicate_index_attribute(pointcloud->attributes_for_write(), ATTR_DOMAIN_POINT, selection, attribute_outputs, - offsets); + duplicates); } geometry_set.replace_pointcloud(pointcloud); } @@ -1053,17 +1064,19 @@ static void duplicate_instances(GeometrySet &geometry_set, IndexMask selection = evaluator.get_evaluated_selection_as_mask(); const VArray counts = evaluator.get_evaluated(0); - Array offsets = accumulate_counts_to_offsets(selection, counts); - if (offsets.last() == 0) { + Array offset_data; + const OffsetIndices duplicates = accumulate_counts_to_offsets( + selection, counts, offset_data); + if (duplicates.total_size() == 0) { geometry_set.clear(); return; } std::unique_ptr dst_instances = std::make_unique(); - dst_instances->resize(offsets.last()); + dst_instances->resize(duplicates.total_size()); for (const int i_selection : selection.index_range()) { - const IndexRange range = range_for_offsets_index(offsets, i_selection); + const IndexRange range = duplicates[i_selection]; if (range.size() == 0) { continue; } @@ -1078,7 +1091,7 @@ static void duplicate_instances(GeometrySet &geometry_set, copy_attributes_without_id(geometry_set, GEO_COMPONENT_TYPE_INSTANCES, ATTR_DOMAIN_INSTANCE, - offsets, + duplicates, selection, propagation_info, src_instances.attributes(), @@ -1089,7 +1102,7 @@ static void duplicate_instances(GeometrySet &geometry_set, ATTR_DOMAIN_INSTANCE, selection, attribute_outputs, - offsets); + duplicates); } geometry_set = GeometrySet::create_with_instances(dst_instances.release()); From 4cfa4f7551ee537bdefd99c0b3d93243fdcb729b Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 14:14:12 -0600 Subject: [PATCH 0785/1522] Geometry Nodes: Parallelize flip faces node I observed a 2x performance improvement for a large mesh. --- .../geometry/nodes/node_geo_flip_faces.cc | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc index e88ade18764..561579aef88 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_flip_faces.cc @@ -1,11 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BLI_task.hh" + #include "BKE_mesh.h" #include "BKE_mesh_runtime.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" - #include "BKE_attribute_math.hh" #include "node_geometry_util.hh" @@ -33,16 +32,18 @@ static void mesh_flip_faces(Mesh &mesh, const Field &selection_field) const Span polys = mesh.polys(); MutableSpan loops = mesh.loops_for_write(); - for (const int i : selection.index_range()) { - const MPoly &poly = polys[selection[i]]; - int start = poly.loopstart; - for (const int j : IndexRange(poly.totloop / 2)) { - const int index1 = start + j + 1; - const int index2 = start + poly.totloop - j - 1; - std::swap(loops[index1].v, loops[index2].v); - std::swap(loops[index1 - 1].e, loops[index2].e); + threading::parallel_for(selection.index_range(), 1024, [&](const IndexRange range) { + for (const int i : selection.slice(range)) { + const IndexRange poly(polys[i].loopstart, polys[i].totloop); + int start = poly.start(); + for (const int j : IndexRange(poly.size() / 2)) { + const int index1 = start + j + 1; + const int index2 = start + poly.size() - j - 1; + std::swap(loops[index1].v, loops[index2].v); + std::swap(loops[index1 - 1].e, loops[index2].e); + } } - } + }); MutableAttributeAccessor attributes = mesh.attributes_for_write(); attributes.for_all( @@ -56,10 +57,12 @@ static void mesh_flip_faces(Mesh &mesh, const Field &selection_field) attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) { using T = decltype(dummy); MutableSpan dst_span = attribute.span.typed(); - for (const int j : selection.index_range()) { - const MPoly &poly = polys[selection[j]]; - dst_span.slice(poly.loopstart + 1, poly.totloop - 1).reverse(); - } + threading::parallel_for(selection.index_range(), 1024, [&](const IndexRange range) { + for (const int i : selection.slice(range)) { + const IndexRange poly(polys[i].loopstart, polys[i].totloop); + dst_span.slice(poly.drop_front(1)).reverse(); + } + }); }); attribute.finish(); } From e12498e44e22b723c8772ef1ff0055a91cce6bef Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 14:16:31 -0600 Subject: [PATCH 0786/1522] Cleanup: Avoid reallocations when evaluating curve in trim node Use the same method as the resample node to use a single vector for each thread. This avoids an allocation for each attribute of each curve. --- source/blender/geometry/intern/resample_curves.cc | 4 +--- source/blender/geometry/intern/trim_curves.cc | 12 +++++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc index 64827fb6143..eac1d7d8d81 100644 --- a/source/blender/geometry/intern/resample_curves.cc +++ b/source/blender/geometry/intern/resample_curves.cc @@ -336,9 +336,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, dst.slice(dst_points)); } else { - const int evaluated_size = evaluated_points_by_curve.size(i_curve); - evaluated_buffer.clear(); - evaluated_buffer.resize(sizeof(T) * evaluated_size); + evaluated_buffer.reinitialize(sizeof(T) * evaluated_points_by_curve.size(i_curve)); MutableSpan evaluated = evaluated_buffer.as_mutable_span().cast(); src_curves.interpolate_to_evaluated(i_curve, src.slice(src_points), evaluated); diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc index 0879718a73a..1ab330c3c0a 100644 --- a/source/blender/geometry/intern/trim_curves.cc +++ b/source/blender/geometry/intern/trim_curves.cc @@ -787,13 +787,15 @@ static void trim_evaluated_curves(const bke::CurvesGeometry &src_curves, using T = decltype(dummy); threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) { + Vector evaluated_buffer; for (const int64_t curve_i : selection.slice(range)) { + const IndexRange src_points = src_points_by_curve[curve_i]; + /* Interpolate onto the evaluated point domain and sample the evaluated domain. */ - GArray<> evaluated_data(CPPType::get(), src_evaluated_points_by_curve.size(curve_i)); - GMutableSpan evaluated_span = evaluated_data.as_mutable_span(); - src_curves.interpolate_to_evaluated( - curve_i, attribute.src.slice(src_points_by_curve[curve_i]), evaluated_span); - sample_interval_linear(evaluated_span.typed(), + evaluated_buffer.reinitialize(sizeof(T) * src_evaluated_points_by_curve.size(curve_i)); + MutableSpan evaluated = evaluated_buffer.as_mutable_span().cast(); + src_curves.interpolate_to_evaluated(curve_i, attribute.src.slice(src_points), evaluated); + sample_interval_linear(evaluated, attribute.dst.span.typed(), src_ranges[curve_i], dst_points_by_curve[curve_i], From dfd63bf1e47ee4558ac0eb84c2ae3e8a31d8401d Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 14:29:14 -0600 Subject: [PATCH 0787/1522] Curves: Avoid reallocations when evaluating NURBS curves I didn't detect a noticeable performance difference in a basic test, but this is better in principle anyway. --- source/blender/blenkernel/intern/curves_geometry.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 5944c557941..52da64634b5 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -562,6 +562,7 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const const VArray knots_modes = this->nurbs_knots_modes(); threading::parallel_for(nurbs_mask.index_range(), 64, [&](const IndexRange range) { + Vector knots; for (const int curve_index : nurbs_mask.slice(range)) { const IndexRange points = points_by_curve[curve_index]; const IndexRange evaluated_points = evaluated_points_by_curve[curve_index]; @@ -575,8 +576,7 @@ void CurvesGeometry::ensure_nurbs_basis_cache() const continue; } - const int knots_num = curves::nurbs::knots_num(points.size(), order, is_cyclic); - Array knots(knots_num); + knots.reinitialize(curves::nurbs::knots_num(points.size(), order, is_cyclic)); curves::nurbs::calculate_knots(points.size(), mode, order, is_cyclic, knots); curves::nurbs::calculate_basis_cache(points.size(), evaluated_points.size(), From 9233b609eb94785739689227c45fbed1ee10a7cc Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 15:08:58 -0600 Subject: [PATCH 0788/1522] Cleanup: Use utility function for copying curve domain data Standardizing the process of creating a new CurvesGeometry with different curve sizes based on an existing curves is helpful, since there are a few methods to simplify the process that aren't obvious at first, like filling the offsets with sizes directly and accumulating them to become sizes. Also, in the trim curves node, avoid creating the curve types attribute all the time. Use the special API functions for the types which do some optimizations automatically. Also use a more consistent method to copy the curve domain data, and correct some comments. --- source/blender/blenkernel/BKE_curves_utils.hh | 17 +++-- .../geometry/intern/resample_curves.cc | 22 +----- source/blender/geometry/intern/trim_curves.cc | 71 ++++++------------- 3 files changed, 35 insertions(+), 75 deletions(-) diff --git a/source/blender/blenkernel/BKE_curves_utils.hh b/source/blender/blenkernel/BKE_curves_utils.hh index 144f934414a..c8b8510a938 100644 --- a/source/blender/blenkernel/BKE_curves_utils.hh +++ b/source/blender/blenkernel/BKE_curves_utils.hh @@ -76,14 +76,17 @@ struct CurvePoint : public CurveSegment { * [0, range_size) can be iterated over an arbitrary amount of times in between. */ class IndexRangeCyclic { - /* Index to the start and end of the iterated range. + /** + * Index to the start and end of the iterated range. */ int start_ = 0; int end_ = 0; - /* Size of the underlying iterable range. + /** + * Size of the underlying iterable range. */ int range_size_ = 0; - /* Number of times the range end is passed when the range is iterated. + /** + * Number of times the range end is passed when the range is iterated. */ int cycles_ = 0; @@ -519,8 +522,12 @@ void fill_points(const CurvesGeometry &curves, } /** - * Copy only the attributes on the curve domain, but not the offsets or any point attributes, - * meant for operations that change the number of points but not the number of curves. + * Create new curves with the same number of curves as the input, but no points. Copy all curve + * domain attributes to the new curves, except the offsets encoding the size of each curve. + * + * Used for operations that change the number of points but not the number of curves, allowing + * creation of the new offsets directly inside the new array. + * * \warning The returned curves have invalid offsets! */ bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves); diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc index eac1d7d8d81..77e136ae886 100644 --- a/source/blender/geometry/intern/resample_curves.cc +++ b/source/blender/geometry/intern/resample_curves.cc @@ -239,16 +239,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, const fn::Field &count_field, const ResampleCurvesOutputAttributeIDs &output_ids) { - /* Create the new curves without any points and evaluate the final count directly - * into the offsets array, in order to be accumulated into offsets later. */ - CurvesGeometry dst_curves = CurvesGeometry(0, src_curves.curves_num()); - - /* Directly copy curve attributes, since they stay the same (except for curve types). */ - CustomData_copy(&src_curves.curve_data, - &dst_curves.curve_data, - CD_MASK_ALL, - CD_DUPLICATE, - src_curves.curves_num()); + CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves); MutableSpan dst_offsets = dst_curves.offsets_for_write(); const bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE}; @@ -422,17 +413,8 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); const OffsetIndices src_evaluated_points_by_curve = src_curves.evaluated_points_by_curve(); - CurvesGeometry dst_curves(0, src_curves.curves_num()); - - /* Directly copy curve attributes, since they stay the same (except for curve types). */ - CustomData_copy(&src_curves.curve_data, - &dst_curves.curve_data, - CD_MASK_ALL, - CD_DUPLICATE, - src_curves.curves_num()); - /* All resampled curves are poly curves. */ + CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves); dst_curves.fill_curve_types(selection, CURVE_TYPE_POLY); - MutableSpan dst_offsets = dst_curves.offsets_for_write(); threading::parallel_for(selection.index_range(), 4096, [&](IndexRange range) { for (const int i : selection.slice(range)) { diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc index 1ab330c3c0a..2e3247f0885 100644 --- a/source/blender/geometry/intern/trim_curves.cc +++ b/source/blender/geometry/intern/trim_curves.cc @@ -822,8 +822,7 @@ static float trim_sample_length(const Span accumulated_lengths, } /** - * Compute the selection for the given curve type. Tracks indices for splitting the selection if - * there are curves reduced to a single point. + * Compute the selected range of points for every selected curve. */ static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves, const IndexMask selection, @@ -831,7 +830,6 @@ static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves, const VArray &ends, const GeometryNodeCurveSampleMode mode, MutableSpan dst_curve_size, - MutableSpan dst_curve_types, MutableSpan start_points, MutableSpan end_points, MutableSpan src_ranges) @@ -841,19 +839,18 @@ static void compute_curve_trim_parameters(const bke::CurvesGeometry &curves, const VArray src_cyclic = curves.cyclic(); const VArray resolution = curves.resolution(); const VArray curve_types = curves.curve_types(); + curves.ensure_can_interpolate_to_evaluated(); - /* Compute. */ threading::parallel_for(selection.index_range(), 128, [&](const IndexRange selection_range) { for (const int64_t curve_i : selection.slice(selection_range)) { CurveType curve_type = CurveType(curve_types[curve_i]); int point_count; if (curve_type == CURVE_TYPE_NURBS) { - dst_curve_types[curve_i] = CURVE_TYPE_POLY; + /* The result curve is a poly curve. */ point_count = evaluated_points_by_curve.size(curve_i); } else { - dst_curve_types[curve_i] = curve_type; point_count = points_by_curve.size(curve_i); } if (point_count == 1) { @@ -959,50 +956,29 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, BLI_assert(starts.size() == ends.size()); src_curves.ensure_evaluated_lengths(); - Vector inverse_selection_indices; - const IndexMask inverse_selection = selection.invert(src_curves.curves_range(), - inverse_selection_indices); + const Vector inverse_selection = selection.extract_ranges_invert( + src_curves.curves_range()); - /* Create destination curves. */ - bke::CurvesGeometry dst_curves(0, src_curves.curves_num()); + bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves); MutableSpan dst_curve_offsets = dst_curves.offsets_for_write(); - MutableSpan dst_curve_types = dst_curves.curve_types_for_write(); - Array start_points(src_curves.curves_num()); - Array end_points(src_curves.curves_num()); - Array src_ranges(src_curves.curves_num()); + Array start_points(src_curves.curves_num()); + Array end_points(src_curves.curves_num()); + Array src_ranges(src_curves.curves_num()); - if (src_curves.has_curve_with_type({CURVE_TYPE_BEZIER, CURVE_TYPE_NURBS})) { - if (src_curves.has_curve_with_type(CURVE_TYPE_NURBS)) { - src_curves.evaluated_positions(); - } - } - - /* Compute destination curves. */ compute_curve_trim_parameters(src_curves, selection, starts, ends, mode, dst_curve_offsets, - dst_curve_types, start_points, end_points, src_ranges); + bke::curves::fill_curve_counts(src_curves, inverse_selection, dst_curve_offsets); - /* Transfer copied curves parameters. */ - const VArray src_curve_types = src_curves.curve_types(); - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); - threading::parallel_for( - inverse_selection.index_range(), 4096, [&](const IndexRange selection_range) { - for (const int64_t curve_i : inverse_selection.slice(selection_range)) { - dst_curve_offsets[curve_i] = src_points_by_curve.size(curve_i); - dst_curve_types[curve_i] = src_curve_types[curve_i]; - } - }); /* Finalize and update the geometry container. */ offset_indices::accumulate_counts_to_offsets(dst_curve_offsets); dst_curves.resize(dst_curves.offsets().last(), dst_curves.curves_num()); - dst_curves.update_curve_types(); /* Populate curve domain. */ const bke::AttributeAccessor src_attributes = src_curves.attributes(); @@ -1013,12 +989,6 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, transfer_curve_skip.remove("nurbs_order"); transfer_curve_skip.remove("knots_mode"); } - bke::copy_attribute_domain(src_attributes, - dst_attributes, - selection, - ATTR_DOMAIN_CURVE, - propagation_info, - transfer_curve_skip); /* Fetch custom point domain attributes for transfer (copy). */ Vector transfer_attributes = bke::retrieve_attributes_for_transfer( @@ -1061,6 +1031,7 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, transfer_attributes); }; auto trim_evaluated = [&](const IndexMask selection) { + dst_curves.fill_curve_types(selection, CURVE_TYPE_POLY); /* Ensure evaluated positions are available. */ src_curves.evaluated_positions(); trim_evaluated_curves(src_curves, @@ -1087,16 +1058,15 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, } /* Copy unselected */ - if (!inverse_selection.is_empty()) { - transfer_curve_skip.remove("cyclic"); - bke::copy_attribute_domain(src_attributes, - dst_attributes, - inverse_selection, - ATTR_DOMAIN_CURVE, - propagation_info, - transfer_curve_skip); - /* Trim curves are no longer cyclic. If all curves are trimmed, this will be set implicitly. */ - dst_curves.cyclic_for_write().fill_indices(selection, false); + if (inverse_selection.is_empty()) { + /* Since all curves were trimmed, none of them are cyclic and the attribute can be removed. */ + dst_curves.attributes_for_write().remove("cyclic"); + } + else { + /* Only trimmed curves are no longer cyclic. */ + if (dst_curves.attributes().contains("cyclic")) { + dst_curves.cyclic_for_write().fill_indices(selection, false); + } Set copy_point_skip; if (!dst_curves.has_curve_with_type(CURVE_TYPE_NURBS) && @@ -1116,6 +1086,7 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, } } + dst_curves.remove_attributes_based_on_types(); dst_curves.tag_topology_changed(); return dst_curves; } From 8d63293c46e9bd68f5fbeddae12a0d433461e2f1 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 15:22:54 -0600 Subject: [PATCH 0789/1522] Curves: Avoid building evaluated point offsets for poly curves When all the curves are poly curves, skip the work of building a separate array of offsets for the evaluated points (which are the same as the control points). This saves 1-4ms on every reevaluation in test files with many curves. --- source/blender/blenkernel/intern/curves_geometry.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 52da64634b5..26a4f41db48 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -499,6 +499,14 @@ static void calculate_evaluated_offsets(const CurvesGeometry &curves, OffsetIndices CurvesGeometry::evaluated_points_by_curve() const { + if (this->is_single_type(CURVE_TYPE_POLY)) { + /* When all the curves are poly curves, the evaluated offsets are the same as the control + * point offsets, so it's possible to completely avoid building a new offsets array. */ + this->runtime->offsets_cache_mutex.ensure( + [&]() { this->runtime->evaluated_offsets_cache.clear_and_shrink(); }); + return this->points_by_curve(); + } + this->runtime->offsets_cache_mutex.ensure([&]() { this->runtime->evaluated_offsets_cache.resize(this->curves_num() + 1); From 7db00d4ef7381830852edc471c9fbd9b39d44fa0 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 15:31:16 -0600 Subject: [PATCH 0790/1522] Cleanup: Rename curves utility function "Fill" usually refers to setting a single value. This copies the sizes from curves offsets to a separate array. --- source/blender/blenkernel/BKE_curves_utils.hh | 8 ++++---- source/blender/blenkernel/intern/curves_utils.cc | 8 ++++---- source/blender/geometry/intern/fillet_curves.cc | 2 +- source/blender/geometry/intern/resample_curves.cc | 4 ++-- source/blender/geometry/intern/subdivide_curves.cc | 2 +- source/blender/geometry/intern/trim_curves.cc | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/BKE_curves_utils.hh b/source/blender/blenkernel/BKE_curves_utils.hh index c8b8510a938..6caf716c063 100644 --- a/source/blender/blenkernel/BKE_curves_utils.hh +++ b/source/blender/blenkernel/BKE_curves_utils.hh @@ -533,11 +533,11 @@ void fill_points(const CurvesGeometry &curves, bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves); /** - * Copy the size of every curve in #curve_ranges to the corresponding index in #counts. + * Copy the number of points in every curve in #curve_ranges to the corresponding index in #sizes. */ -void fill_curve_counts(const bke::CurvesGeometry &curves, - Span curve_ranges, - MutableSpan counts); +void copy_curve_sizes(const bke::CurvesGeometry &curves, + Span curve_ranges, + MutableSpan sizes); IndexMask indices_for_type(const VArray &types, const std::array &type_counts, diff --git a/source/blender/blenkernel/intern/curves_utils.cc b/source/blender/blenkernel/intern/curves_utils.cc index 598f654b298..ef2518cbc3f 100644 --- a/source/blender/blenkernel/intern/curves_utils.cc +++ b/source/blender/blenkernel/intern/curves_utils.cc @@ -10,16 +10,16 @@ namespace blender::bke::curves { -void fill_curve_counts(const bke::CurvesGeometry &curves, - const Span curve_ranges, - MutableSpan counts) +void copy_curve_sizes(const bke::CurvesGeometry &curves, + const Span curve_ranges, + MutableSpan sizes) { const OffsetIndices points_by_curve = curves.points_by_curve(); threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange ranges_range) { for (const IndexRange curves_range : curve_ranges.slice(ranges_range)) { threading::parallel_for(curves_range, 4096, [&](IndexRange range) { for (const int i : range) { - counts[i] = points_by_curve.size(i); + sizes[i] = points_by_curve.size(i); } }); } diff --git a/source/blender/geometry/intern/fillet_curves.cc b/source/blender/geometry/intern/fillet_curves.cc index 1bb33f0e80f..f666a6b6b40 100644 --- a/source/blender/geometry/intern/fillet_curves.cc +++ b/source/blender/geometry/intern/fillet_curves.cc @@ -70,7 +70,7 @@ static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, MutableSpan dst_point_offsets) { /* Fill the offsets array with the curve point counts, then accumulate them to form offsets. */ - bke::curves::fill_curve_counts(src_curves, unselected_ranges, dst_curve_offsets); + bke::curves::copy_curve_sizes(src_curves, unselected_ranges, dst_curve_offsets); const OffsetIndices points_by_curve = src_curves.points_by_curve(); threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int curve_i : selection.slice(range)) { diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc index 77e136ae886..00bd1898674 100644 --- a/source/blender/geometry/intern/resample_curves.cc +++ b/source/blender/geometry/intern/resample_curves.cc @@ -252,7 +252,7 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, src_curves.curves_range(), nullptr); /* Fill the counts for the curves that aren't selected and accumulate the counts into offsets. */ - bke::curves::fill_curve_counts(src_curves, unselected_ranges, dst_offsets); + bke::curves::copy_curve_sizes(src_curves, unselected_ranges, dst_offsets); offset_indices::accumulate_counts_to_offsets(dst_offsets); dst_curves.resize(dst_offsets.last(), dst_curves.curves_num()); @@ -421,7 +421,7 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, dst_offsets[i] = src_evaluated_points_by_curve.size(i); } }); - bke::curves::fill_curve_counts(src_curves, unselected_ranges, dst_offsets); + bke::curves::copy_curve_sizes(src_curves, unselected_ranges, dst_offsets); offset_indices::accumulate_counts_to_offsets(dst_offsets); const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); diff --git a/source/blender/geometry/intern/subdivide_curves.cc b/source/blender/geometry/intern/subdivide_curves.cc index 667146bd457..99a20b1122d 100644 --- a/source/blender/geometry/intern/subdivide_curves.cc +++ b/source/blender/geometry/intern/subdivide_curves.cc @@ -20,7 +20,7 @@ static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, MutableSpan dst_point_offsets) { /* Fill the array with each curve's point count, then accumulate them to the offsets. */ - bke::curves::fill_curve_counts(src_curves, unselected_ranges, dst_curve_offsets); + bke::curves::copy_curve_sizes(src_curves, unselected_ranges, dst_curve_offsets); const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) { for (const int curve_i : selection.slice(range)) { diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc index 2e3247f0885..3097c2e8c4a 100644 --- a/source/blender/geometry/intern/trim_curves.cc +++ b/source/blender/geometry/intern/trim_curves.cc @@ -974,7 +974,7 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, start_points, end_points, src_ranges); - bke::curves::fill_curve_counts(src_curves, inverse_selection, dst_curve_offsets); + bke::curves::copy_curve_sizes(src_curves, inverse_selection, dst_curve_offsets); /* Finalize and update the geometry container. */ offset_indices::accumulate_counts_to_offsets(dst_curve_offsets); From baf69b064b91e8300830ab4e7d9a86060d80f7d6 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 15:35:58 -0600 Subject: [PATCH 0791/1522] Geometry Nodes: Avoid creating cyclic attribute when redundant The default when there is no cyclic attribute is that none of the curves are cyclic. In the mesh to curve node, avoid creating the attribute with just false to save time and memory usage. Also avoid looking up the attribute twice in the trim node. --- .../blender/geometry/intern/mesh_to_curve_convert.cc | 10 +++++++--- source/blender/geometry/intern/trim_curves.cc | 5 +++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/source/blender/geometry/intern/mesh_to_curve_convert.cc b/source/blender/geometry/intern/mesh_to_curve_convert.cc index 06bef16dec7..22c925a1310 100644 --- a/source/blender/geometry/intern/mesh_to_curve_convert.cc +++ b/source/blender/geometry/intern/mesh_to_curve_convert.cc @@ -30,12 +30,16 @@ bke::CurvesGeometry create_curve_from_vert_indices( curves.offsets_for_write().last() = vert_indices.size(); curves.fill_curve_types(CURVE_TYPE_POLY); - curves.cyclic_for_write().fill(false); - curves.cyclic_for_write().slice(cyclic_curves).fill(true); - const bke::AttributeAccessor mesh_attributes = mesh.attributes(); bke::MutableAttributeAccessor curves_attributes = curves.attributes_for_write(); + if (!cyclic_curves.is_empty()) { + bke::SpanAttributeWriter cyclic = curves_attributes.lookup_or_add_for_write_span( + "cyclic", ATTR_DOMAIN_CURVE); + cyclic.span.slice(cyclic_curves).fill(true); + cyclic.finish(); + } + Set source_attribute_ids = mesh_attributes.all_ids(); for (const bke::AttributeIDRef &attribute_id : source_attribute_ids) { diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc index 3097c2e8c4a..b7faf54bdc5 100644 --- a/source/blender/geometry/intern/trim_curves.cc +++ b/source/blender/geometry/intern/trim_curves.cc @@ -1064,8 +1064,9 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, } else { /* Only trimmed curves are no longer cyclic. */ - if (dst_curves.attributes().contains("cyclic")) { - dst_curves.cyclic_for_write().fill_indices(selection, false); + if (bke::SpanAttributeWriter cyclic = dst_attributes.lookup_for_write_span("cyclic")) { + cyclic.span.fill_indices(selection, false); + cyclic.finish(); } Set copy_point_skip; From 190d66b51e4db98d7e9dc69e01c972b7da498e40 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 15:37:36 -0600 Subject: [PATCH 0792/1522] Cleanup: Remove unused attribute API function While we do need higher level utilities for copying attributes between geometries, this currently isn't used and it's not clear that it will be the right abstraction in the end. --- source/blender/blenkernel/BKE_attribute.hh | 14 -------- .../blenkernel/intern/attribute_access.cc | 32 ------------------- 2 files changed, 46 deletions(-) diff --git a/source/blender/blenkernel/BKE_attribute.hh b/source/blender/blenkernel/BKE_attribute.hh index 0ff120328d3..afa9f1fba23 100644 --- a/source/blender/blenkernel/BKE_attribute.hh +++ b/source/blender/blenkernel/BKE_attribute.hh @@ -753,20 +753,6 @@ Vector retrieve_attributes_for_transfer( const AnonymousAttributePropagationInfo &propagation_info, const Set &skip = {}); -/** - * Copy attributes for the domain based on the elementwise mask. - * - * \param mask_indices: Indexed elements to copy from the source data-block. - * \param domain: Attribute domain to transfer. - * \param skip: Named attributes to ignore/skip. - */ -void copy_attribute_domain(AttributeAccessor src_attributes, - MutableAttributeAccessor dst_attributes, - IndexMask selection, - eAttrDomain domain, - const AnonymousAttributePropagationInfo &propagation_info, - const Set &skip = {}); - bool allow_procedural_attribute_access(StringRef attribute_name); extern const char *no_procedural_access_message; diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index 92bb7247673..8a6e1486701 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -913,38 +913,6 @@ Vector retrieve_attributes_for_transfer( return attributes; } -void copy_attribute_domain(const AttributeAccessor src_attributes, - MutableAttributeAccessor dst_attributes, - const IndexMask selection, - const eAttrDomain domain, - const AnonymousAttributePropagationInfo &propagation_info, - const Set &skip) -{ - src_attributes.for_all( - [&](const bke::AttributeIDRef &id, const bke::AttributeMetaData &meta_data) { - if (meta_data.domain != domain) { - return true; - } - if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) { - return true; - } - if (skip.contains(id.name())) { - return true; - } - - const GVArray src = src_attributes.lookup(id, meta_data.domain); - BLI_assert(src); - - /* Copy attribute. */ - GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( - id, domain, meta_data.data_type); - array_utils::copy(src, selection, dst.span); - dst.finish(); - - return true; - }); -} - } // namespace blender::bke /** \} */ From 670b3c5013d107bde5504f2ef5930fb604888ffc Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 19 Jan 2023 22:36:07 +0100 Subject: [PATCH 0793/1522] Cleanup: compiler warnings --- intern/cycles/kernel/data_template.h | 1 + source/blender/modifiers/intern/MOD_ocean.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/intern/cycles/kernel/data_template.h b/intern/cycles/kernel/data_template.h index dceae4b77c1..f1589a4d10b 100644 --- a/intern/cycles/kernel/data_template.h +++ b/intern/cycles/kernel/data_template.h @@ -220,4 +220,5 @@ KERNEL_STRUCT_END(KernelSVMUsage) #undef KERNEL_STRUCT_BEGIN #undef KERNEL_STRUCT_MEMBER +#undef KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE #undef KERNEL_STRUCT_END diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 9081ebd85fb..cad2f57e45a 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -336,7 +336,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes } /* do ocean simulation */ - if (omd->cached == true) { + if (omd->cached) { if (!omd->oceancache) { init_cache_data(ob, omd, resolution); } @@ -403,7 +403,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes const float v = OCEAN_CO(size_co_inv, vco[1]); float foam; - if (omd->oceancache && omd->cached == true) { + if (omd->oceancache && omd->cached) { BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v); foam = ocr.foam; CLAMP(foam, 0.0f, 1.0f); @@ -450,7 +450,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes const float u = OCEAN_CO(size_co_inv, vco[0]); const float v = OCEAN_CO(size_co_inv, vco[1]); - if (omd->oceancache && omd->cached == true) { + if (omd->oceancache && omd->cached) { BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra_for_cache, u, v); } else { From fe552bf236fcbff92f54299e575c5eda74cfb57f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 19 Jan 2023 22:30:10 +0100 Subject: [PATCH 0794/1522] Cleanup: make format --- intern/cycles/device/metal/device_impl.mm | 8 +++++--- intern/cycles/device/metal/kernel.mm | 3 ++- intern/cycles/kernel/data_template.h | 8 +++++--- intern/cycles/kernel/osl/types.h | 6 ++++-- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/intern/cycles/device/metal/device_impl.mm b/intern/cycles/device/metal/device_impl.mm index 917945fbdb6..453418386a4 100644 --- a/intern/cycles/device/metal/device_impl.mm +++ b/intern/cycles/device/metal/device_impl.mm @@ -335,9 +335,11 @@ void MetalDevice::make_source(MetalPipelineType pso_type, const uint kernel_feat # define KERNEL_STRUCT_MEMBER(parent, _type, name) \ if (next_member_is_specialized) { \ baked_constants += string(#parent "." #name "=") + \ - to_string(_type(launch_params.data.parent.name)) + "\n"; \ - } else { \ - string_replace(source, "kernel_data_" #parent "_" #name, "kernel_data." #parent ".__unused_" #name); \ + to_string(_type(launch_params.data.parent.name)) + "\n"; \ + } \ + else { \ + string_replace( \ + source, "kernel_data_" #parent "_" #name, "kernel_data." #parent ".__unused_" #name); \ next_member_is_specialized = true; \ } diff --git a/intern/cycles/device/metal/kernel.mm b/intern/cycles/device/metal/kernel.mm index febce2840ea..6312c5f88ee 100644 --- a/intern/cycles/device/metal/kernel.mm +++ b/intern/cycles/device/metal/kernel.mm @@ -467,7 +467,8 @@ static MTLFunctionConstantValues *GetConstantValues(KernelData const *data = nul # define KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE next_member_is_specialized = false; # define KERNEL_STRUCT_MEMBER(parent, _type, name) \ - [constant_values setConstantValue:next_member_is_specialized ? (void*)&data->parent.name : (void*)&zero_data \ + [constant_values setConstantValue:next_member_is_specialized ? (void *)&data->parent.name : \ + (void *)&zero_data \ type:MTLDataType_##_type \ atIndex:KernelData_##parent##_##name]; \ next_member_is_specialized = true; diff --git a/intern/cycles/kernel/data_template.h b/intern/cycles/kernel/data_template.h index f1589a4d10b..fd25644e56b 100644 --- a/intern/cycles/kernel/data_template.h +++ b/intern/cycles/kernel/data_template.h @@ -14,7 +14,6 @@ # define KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE #endif - /* Background. */ KERNEL_STRUCT_BEGIN(KernelBackground, background) @@ -183,9 +182,12 @@ KERNEL_STRUCT_MEMBER(integrator, float, sample_clamp_indirect) KERNEL_STRUCT_MEMBER(integrator, int, use_caustics) /* Sampling pattern. */ KERNEL_STRUCT_MEMBER(integrator, int, sampling_pattern) -KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE KERNEL_STRUCT_MEMBER(integrator, int, tabulated_sobol_sequence_size) -KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE KERNEL_STRUCT_MEMBER(integrator, int, sobol_index_mask) KERNEL_STRUCT_MEMBER(integrator, float, scrambling_distance) +/* Sobol pattern. */ +KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE +KERNEL_STRUCT_MEMBER(integrator, int, tabulated_sobol_sequence_size) +KERNEL_STRUCT_MEMBER_DONT_SPECIALIZE +KERNEL_STRUCT_MEMBER(integrator, int, sobol_index_mask) /* Volume render. */ KERNEL_STRUCT_MEMBER(integrator, int, use_volumes) KERNEL_STRUCT_MEMBER(integrator, int, volume_max_steps) diff --git a/intern/cycles/kernel/osl/types.h b/intern/cycles/kernel/osl/types.h index 528f07ad58c..67d0073f48d 100644 --- a/intern/cycles/kernel/osl/types.h +++ b/intern/cycles/kernel/osl/types.h @@ -90,9 +90,11 @@ struct ShaderGlobals { int backfacing; }; -struct OSLNoiseOptions {}; +struct OSLNoiseOptions { +}; -struct OSLTextureOptions {}; +struct OSLTextureOptions { +}; #define OSL_TEXTURE_HANDLE_TYPE_IES ((uintptr_t)0x2 << 30) #define OSL_TEXTURE_HANDLE_TYPE_SVM ((uintptr_t)0x1 << 30) From 2ab72f6db8319b564dc6e3e6c0a6c26d253fda30 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 15:49:49 -0600 Subject: [PATCH 0795/1522] Fix T103964: Assert on mouse hover of empty node editor The reverse iteration added in e091291b5b5f525cd8d3 didn't handle the case where there are no nodes properly. Thanks to Iliya Katueshenock for investigating this. --- source/blender/editors/space_node/node_draw.cc | 4 +++- source/blender/editors/space_node/node_edit.cc | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index d3b34c408cf..bc4b6d416c1 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -2621,8 +2621,10 @@ int node_get_resize_cursor(NodeResizeDirection directions) static const bNode *find_node_under_cursor(SpaceNode &snode, const float2 &cursor) { - /* Check nodes front to back. */ const Span nodes = snode.edittree->all_nodes(); + if (nodes.is_empty()) { + return nullptr; + } for (int i = nodes.index_range().last(); i >= 0; i--) { if (BLI_rctf_isect_pt(&nodes[i]->runtime->totr, cursor[0], cursor[1])) { return nodes[i]; diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index d93b93d8f8c..fc039746639 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -1135,8 +1135,11 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode, /* Sockets haven't been drawn yet, e.g. when the file is currently opening. */ return nullptr; } - const Span nodes = snode.edittree->all_nodes(); + if (nodes.is_empty()) { + return nullptr; + } + for (int i = nodes.index_range().last(); i >= 0; i--) { bNode &node = *nodes[i]; From 79053a6ff74a10ef7f51f4b7c5b0e5e5a542eb5a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 15:54:47 -0600 Subject: [PATCH 0796/1522] Cleanup: Move several modifiers files to C++ For continued refactoring of the Mesh data structure. See T103343. --- source/blender/modifiers/CMakeLists.txt | 24 +- .../intern/{MOD_build.c => MOD_build.cc} | 71 +- ...ectivesmooth.c => MOD_correctivesmooth.cc} | 171 ++--- .../intern/{MOD_explode.c => MOD_explode.cc} | 191 +++--- ...placiansmooth.c => MOD_laplaciansmooth.cc} | 109 ++- .../intern/{MOD_ocean.c => MOD_ocean.cc} | 167 ++--- ...icleinstance.c => MOD_particleinstance.cc} | 122 ++-- .../intern/{MOD_remesh.c => MOD_remesh.cc} | 111 ++-- .../{MOD_solidify.c => MOD_solidify.cc} | 78 +-- ...dify_extrude.c => MOD_solidify_extrude.cc} | 178 ++--- ...manifold.c => MOD_solidify_nonmanifold.cc} | 628 +++++++++--------- ...D_solidify_util.h => MOD_solidify_util.hh} | 4 +- ...D_surfacedeform.c => MOD_surfacedeform.cc} | 370 +++++------ 13 files changed, 1134 insertions(+), 1090 deletions(-) rename source/blender/modifiers/intern/{MOD_build.c => MOD_build.cc} (85%) rename source/blender/modifiers/intern/{MOD_correctivesmooth.c => MOD_correctivesmooth.cc} (84%) rename source/blender/modifiers/intern/{MOD_explode.c => MOD_explode.cc} (84%) rename source/blender/modifiers/intern/{MOD_laplaciansmooth.c => MOD_laplaciansmooth.cc} (87%) rename source/blender/modifiers/intern/{MOD_ocean.c => MOD_ocean.cc} (79%) rename source/blender/modifiers/intern/{MOD_particleinstance.c => MOD_particleinstance.cc} (84%) rename source/blender/modifiers/intern/{MOD_remesh.c => MOD_remesh.cc} (70%) rename source/blender/modifiers/intern/{MOD_solidify.c => MOD_solidify.cc} (77%) rename source/blender/modifiers/intern/{MOD_solidify_extrude.c => MOD_solidify_extrude.cc} (86%) rename source/blender/modifiers/intern/{MOD_solidify_nonmanifold.c => MOD_solidify_nonmanifold.cc} (84%) rename source/blender/modifiers/intern/{MOD_solidify_util.h => MOD_solidify_util.hh} (87%) rename source/blender/modifiers/intern/{MOD_surfacedeform.c => MOD_surfacedeform.cc} (87%) diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index 30ddca5e47d..a0cf583153b 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -37,22 +37,22 @@ set(SRC intern/MOD_array.cc intern/MOD_bevel.c intern/MOD_boolean.cc - intern/MOD_build.c + intern/MOD_build.cc intern/MOD_cast.c intern/MOD_cloth.c intern/MOD_collision.c - intern/MOD_correctivesmooth.c + intern/MOD_correctivesmooth.cc intern/MOD_curve.c intern/MOD_datatransfer.cc intern/MOD_decimate.c intern/MOD_displace.cc intern/MOD_dynamicpaint.c intern/MOD_edgesplit.c - intern/MOD_explode.c + intern/MOD_explode.cc intern/MOD_fluid.c intern/MOD_hook.c intern/MOD_laplaciandeform.c - intern/MOD_laplaciansmooth.c + intern/MOD_laplaciansmooth.cc intern/MOD_lattice.c intern/MOD_mask.cc intern/MOD_mesh_to_volume.cc @@ -67,10 +67,10 @@ set(SRC intern/MOD_nodes.cc intern/MOD_none.c intern/MOD_normal_edit.cc - intern/MOD_ocean.c - intern/MOD_particleinstance.c + intern/MOD_ocean.cc + intern/MOD_particleinstance.cc intern/MOD_particlesystem.cc - intern/MOD_remesh.c + intern/MOD_remesh.cc intern/MOD_screw.cc intern/MOD_shapekey.c intern/MOD_shrinkwrap.c @@ -78,12 +78,12 @@ set(SRC intern/MOD_skin.c intern/MOD_smooth.c intern/MOD_softbody.c - intern/MOD_solidify.c - intern/MOD_solidify_extrude.c - intern/MOD_solidify_nonmanifold.c + intern/MOD_solidify.cc + intern/MOD_solidify_extrude.cc + intern/MOD_solidify_nonmanifold.cc intern/MOD_subsurf.cc intern/MOD_surface.c - intern/MOD_surfacedeform.c + intern/MOD_surfacedeform.cc intern/MOD_triangulate.cc intern/MOD_ui_common.c intern/MOD_util.cc @@ -104,7 +104,7 @@ set(SRC MOD_modifiertypes.h MOD_nodes.h intern/MOD_meshcache_util.h - intern/MOD_solidify_util.h + intern/MOD_solidify_util.hh intern/MOD_ui_common.h intern/MOD_util.h intern/MOD_weightvg_util.h diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.cc similarity index 85% rename from source/blender/modifiers/intern/MOD_build.c rename to source/blender/modifiers/intern/MOD_build.cc index b2c9995a928..ae69677a2d6 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.cc @@ -48,18 +48,17 @@ static void initData(ModifierData *md) MEMCPY_STRUCT_AFTER(bmd, DNA_struct_default_get(BuildModifierData), modifier); } -static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *UNUSED(md)) +static bool dependsOnTime(Scene * /*scene*/, ModifierData * /*md*/) { return true; } -static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh) { Mesh *result; BuildModifierData *bmd = (BuildModifierData *)md; int i, j, k; int faces_dst_num, edges_dst_num, loops_dst_num = 0; - int *vertMap, *edgeMap, *faceMap; float frac; MPoly *mpoly_dst; MLoop *ml_dst; @@ -79,15 +78,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct const MPoly *mpoly_src = BKE_mesh_polys(mesh); const MLoop *mloop_src = BKE_mesh_loops(mesh); - vertMap = MEM_malloc_arrayN(vert_src_num, sizeof(*vertMap), "build modifier vertMap"); - edgeMap = MEM_malloc_arrayN(edge_src_num, sizeof(*edgeMap), "build modifier edgeMap"); - faceMap = MEM_malloc_arrayN(poly_src_num, sizeof(*faceMap), "build modifier faceMap"); + int *vertMap = static_cast(MEM_malloc_arrayN(vert_src_num, sizeof(int), __func__)); + int *edgeMap = static_cast(MEM_malloc_arrayN(edge_src_num, sizeof(int), __func__)); + int *faceMap = static_cast(MEM_malloc_arrayN(poly_src_num, sizeof(int), __func__)); range_vn_i(vertMap, vert_src_num, 0); range_vn_i(edgeMap, edge_src_num, 0); range_vn_i(faceMap, poly_src_num, 0); - struct Scene *scene = DEG_get_input_scene(ctx->depsgraph); + Scene *scene = DEG_get_input_scene(ctx->depsgraph); frac = (BKE_scene_ctime_get(scene) - bmd->start) / bmd->length; CLAMP(frac, 0.0f, 1.0f); if (bmd->flag & MOD_BUILD_FLAG_REVERSE) { @@ -253,9 +252,9 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct } } - BLI_ghash_free(vertHash, NULL, NULL); - BLI_ghash_free(edgeHash, NULL, NULL); - BLI_ghash_free(edgeHash2, NULL, NULL); + BLI_ghash_free(vertHash, nullptr, nullptr); + BLI_ghash_free(edgeHash, nullptr, nullptr); + BLI_ghash_free(edgeHash2, nullptr, nullptr); MEM_freeN(vertMap); MEM_freeN(edgeMap); @@ -265,40 +264,40 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct return result; } -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiLayoutSetPropSep(layout, true); - uiItemR(layout, ptr, "frame_start", 0, NULL, ICON_NONE); - uiItemR(layout, ptr, "frame_duration", 0, NULL, ICON_NONE); - uiItemR(layout, ptr, "use_reverse", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "frame_start", 0, nullptr, ICON_NONE); + uiItemR(layout, ptr, "frame_duration", 0, nullptr, ICON_NONE); + uiItemR(layout, ptr, "use_reverse", 0, nullptr, ICON_NONE); modifier_panel_end(layout, ptr); } -static void random_panel_header_draw(const bContext *UNUSED(C), Panel *panel) +static void random_panel_header_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); - uiItemR(layout, ptr, "use_random_order", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "use_random_order", 0, nullptr, ICON_NONE); } -static void random_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void random_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiLayoutSetPropSep(layout, true); uiLayoutSetActive(layout, RNA_boolean_get(ptr, "use_random_order")); - uiItemR(layout, ptr, "seed", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "seed", 0, nullptr, ICON_NONE); } static void panelRegister(ARegionType *region_type) @@ -319,24 +318,24 @@ ModifierTypeInfo modifierType_Build = { /*copyData*/ BKE_modifier_copydata_generic, - /*deformVerts*/ NULL, - /*deformMatrices*/ NULL, - /*deformVertsEM*/ NULL, - /*deformMatricesEM*/ NULL, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, /*modifyMesh*/ modifyMesh, - /*modifyGeometrySet*/ NULL, + /*modifyGeometrySet*/ nullptr, /*initData*/ initData, - /*requiredDataMask*/ NULL, - /*freeData*/ NULL, - /*isDisabled*/ NULL, - /*updateDepsgraph*/ NULL, + /*requiredDataMask*/ nullptr, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ nullptr, /*dependsOnTime*/ dependsOnTime, - /*dependsOnNormals*/ NULL, - /*foreachIDLink*/ NULL, - /*foreachTexLink*/ NULL, - /*freeRuntimeData*/ NULL, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ nullptr, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, /*panelRegister*/ panelRegister, - /*blendWrite*/ NULL, - /*blendRead*/ NULL, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.cc similarity index 84% rename from source/blender/modifiers/intern/MOD_correctivesmooth.c rename to source/blender/modifiers/intern/MOD_correctivesmooth.cc index 50b6c7fcb32..83b51187c6b 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.c +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.cc @@ -62,7 +62,7 @@ static void initData(ModifierData *md) MEMCPY_STRUCT_AFTER(csmd, DNA_struct_default_get(CorrectiveSmoothModifierData), modifier); - csmd->delta_cache.deltas = NULL; + csmd->delta_cache.deltas = nullptr; } static void copyData(const ModifierData *md, ModifierData *target, const int flag) @@ -73,10 +73,10 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla BKE_modifier_copydata_generic(md, target, flag); if (csmd->bind_coords) { - tcsmd->bind_coords = MEM_dupallocN(csmd->bind_coords); + tcsmd->bind_coords = static_cast(MEM_dupallocN(csmd->bind_coords)); } - tcsmd->delta_cache.deltas = NULL; + tcsmd->delta_cache.deltas = nullptr; tcsmd->delta_cache.deltas_num = 0; } @@ -135,7 +135,8 @@ static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights) const uint medge_num = (uint)mesh->totedge; /* Flag boundary edges so only boundaries are set to 1. */ - uint8_t *boundaries = MEM_calloc_arrayN(medge_num, sizeof(*boundaries), __func__); + uint8_t *boundaries = static_cast( + MEM_calloc_arrayN(medge_num, sizeof(*boundaries), __func__)); for (uint i = 0; i < mpoly_num; i++) { const MPoly *p = &mpoly[i]; @@ -174,13 +175,14 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd, const uint edges_num = (uint)mesh->totedge; const MEdge *edges = BKE_mesh_edges(mesh); - float *vertex_edge_count_div; struct SmoothingData_Simple { float delta[3]; - } *smooth_data = MEM_calloc_arrayN(verts_num, sizeof(*smooth_data), __func__); + }; + SmoothingData_Simple *smooth_data = MEM_cnew_array(verts_num, __func__); - vertex_edge_count_div = MEM_calloc_arrayN(verts_num, sizeof(float), __func__); + float *vertex_edge_count_div = static_cast( + MEM_calloc_arrayN(verts_num, sizeof(float), __func__)); /* calculate as floats to avoid int->float conversion in #smooth_iter */ for (i = 0; i < edges_num; i++) { @@ -190,7 +192,7 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd, /* a little confusing, but we can include 'lambda' and smoothing weight * here to avoid multiplying for every iteration */ - if (smooth_weights == NULL) { + if (smooth_weights == nullptr) { for (i = 0; i < verts_num; i++) { vertex_edge_count_div[i] = lambda * (vertex_edge_count_div[i] ? (1.0f / vertex_edge_count_div[i]) : @@ -210,8 +212,8 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd, while (iterations--) { for (i = 0; i < edges_num; i++) { - struct SmoothingData_Simple *sd_v1; - struct SmoothingData_Simple *sd_v2; + SmoothingData_Simple *sd_v1; + SmoothingData_Simple *sd_v2; float edge_dir[3]; sub_v3_v3v3(edge_dir, vertexCos[edges[i].v2], vertexCos[edges[i].v1]); @@ -224,7 +226,7 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd, } for (i = 0; i < verts_num; i++) { - struct SmoothingData_Simple *sd = &smooth_data[i]; + SmoothingData_Simple *sd = &smooth_data[i]; madd_v3_v3fl(vertexCos[i], sd->delta, vertex_edge_count_div[i]); /* zero for the next iteration (saves memset on entire array) */ memset(sd, 0, sizeof(*sd)); @@ -251,16 +253,18 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, * and 2.0 rarely spikes, double the value for consistent behavior. */ const float lambda = csmd->lambda * 2.0f; const MEdge *edges = BKE_mesh_edges(mesh); - float *vertex_edge_count; uint i; struct SmoothingData_Weighted { float delta[3]; float edge_length_sum; - } *smooth_data = MEM_calloc_arrayN(verts_num, sizeof(*smooth_data), __func__); + }; + SmoothingData_Weighted *smooth_data = MEM_cnew_array(verts_num, + __func__); /* calculate as floats to avoid int->float conversion in #smooth_iter */ - vertex_edge_count = MEM_calloc_arrayN(verts_num, sizeof(float), __func__); + float *vertex_edge_count = static_cast( + MEM_calloc_arrayN(verts_num, sizeof(float), __func__)); for (i = 0; i < edges_num; i++) { vertex_edge_count[edges[i].v1] += 1.0f; vertex_edge_count[edges[i].v2] += 1.0f; @@ -271,8 +275,8 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, while (iterations--) { for (i = 0; i < edges_num; i++) { - struct SmoothingData_Weighted *sd_v1; - struct SmoothingData_Weighted *sd_v2; + SmoothingData_Weighted *sd_v1; + SmoothingData_Weighted *sd_v2; float edge_dir[3]; float edge_dist; @@ -292,10 +296,10 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, sd_v2->edge_length_sum += edge_dist; } - if (smooth_weights == NULL) { + if (smooth_weights == nullptr) { /* fast-path */ for (i = 0; i < verts_num; i++) { - struct SmoothingData_Weighted *sd = &smooth_data[i]; + SmoothingData_Weighted *sd = &smooth_data[i]; /* Divide by sum of all neighbor distances (weighted) and amount of neighbors, * (mean average). */ const float div = sd->edge_length_sum * vertex_edge_count[i]; @@ -316,7 +320,7 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, } else { for (i = 0; i < verts_num; i++) { - struct SmoothingData_Weighted *sd = &smooth_data[i]; + SmoothingData_Weighted *sd = &smooth_data[i]; const float div = sd->edge_length_sum * vertex_edge_count[i]; if (div > eps) { const float lambda_w = lambda * smooth_weights[i]; @@ -358,11 +362,11 @@ static void smooth_verts(CorrectiveSmoothModifierData *csmd, float (*vertexCos)[3], uint verts_num) { - float *smooth_weights = NULL; + float *smooth_weights = nullptr; if (dvert || (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY)) { - smooth_weights = MEM_malloc_arrayN(verts_num, sizeof(float), __func__); + smooth_weights = static_cast(MEM_malloc_arrayN(verts_num, sizeof(float), __func__)); if (dvert) { mesh_get_weights(dvert, @@ -372,7 +376,7 @@ static void smooth_verts(CorrectiveSmoothModifierData *csmd, smooth_weights); } else { - copy_vn_fl(smooth_weights, (int)verts_num, 1.0f); + copy_vn_fl(smooth_weights, int(verts_num), 1.0f); } if (csmd->flag & MOD_CORRECTIVESMOOTH_PIN_BOUNDARY) { @@ -423,9 +427,9 @@ static bool calc_tangent_loop(const float v_dir_prev[3], /** * \param r_tangent_spaces: Loop aligned array of tangents. - * \param r_tangent_weights: Loop aligned array of weights (may be NULL). + * \param r_tangent_weights: Loop aligned array of weights (may be nullptr). * \param r_tangent_weights_per_vertex: Vertex aligned array, accumulating weights for each loop - * (may be NULL). + * (may be nullptr). */ static void calc_tangent_spaces(const Mesh *mesh, const float (*vertexCos)[3], @@ -439,8 +443,8 @@ static void calc_tangent_spaces(const Mesh *mesh, const MLoop *mloop = BKE_mesh_loops(mesh); uint i; - if (r_tangent_weights_per_vertex != NULL) { - copy_vn_fl(r_tangent_weights_per_vertex, (int)mvert_num, 0.0f); + if (r_tangent_weights_per_vertex != nullptr) { + copy_vn_fl(r_tangent_weights_per_vertex, int(mvert_num), 0.0f); } for (i = 0; i < mpoly_num; i++) { @@ -470,14 +474,14 @@ static void calc_tangent_spaces(const Mesh *mesh, normalize_v3(v_dir_next); if (calc_tangent_loop(v_dir_prev, v_dir_next, ts)) { - if (r_tangent_weights != NULL) { + if (r_tangent_weights != nullptr) { const float weight = fabsf(acosf(dot_v3v3(v_dir_next, v_dir_prev))); r_tangent_weights[l_index] = weight; r_tangent_weights_per_vertex[l_curr->v] += weight; } } else { - if (r_tangent_weights != NULL) { + if (r_tangent_weights != nullptr) { r_tangent_weights[l_index] = 0; } } @@ -518,12 +522,12 @@ static void calc_deltas(CorrectiveSmoothModifierData *csmd, const MLoop *mloop = BKE_mesh_loops(mesh); const uint loops_num = (uint)mesh->totloop; - float(*smooth_vertex_coords)[3] = MEM_dupallocN(rest_coords); - float(*tangent_spaces)[3][3]; + float(*smooth_vertex_coords)[3] = static_cast(MEM_dupallocN(rest_coords)); uint l_index; - tangent_spaces = MEM_malloc_arrayN(loops_num, sizeof(float[3][3]), __func__); + float(*tangent_spaces)[3][3] = static_cast( + MEM_malloc_arrayN(loops_num, sizeof(float[3][3]), __func__)); if (csmd->delta_cache.deltas_num != loops_num) { MEM_SAFE_FREE(csmd->delta_cache.deltas); @@ -532,17 +536,18 @@ static void calc_deltas(CorrectiveSmoothModifierData *csmd, /* allocate deltas if they have not yet been allocated, otherwise we will just write over them */ if (!csmd->delta_cache.deltas) { csmd->delta_cache.deltas_num = loops_num; - csmd->delta_cache.deltas = MEM_malloc_arrayN(loops_num, sizeof(float[3]), __func__); + csmd->delta_cache.deltas = static_cast( + MEM_malloc_arrayN(loops_num, sizeof(float[3]), __func__)); } smooth_verts(csmd, mesh, dvert, defgrp_index, smooth_vertex_coords, verts_num); - calc_tangent_spaces(mesh, smooth_vertex_coords, tangent_spaces, NULL, NULL); + calc_tangent_spaces(mesh, smooth_vertex_coords, tangent_spaces, nullptr, nullptr); - copy_vn_fl(&csmd->delta_cache.deltas[0][0], (int)loops_num * 3, 0.0f); + copy_vn_fl(&csmd->delta_cache.deltas[0][0], int(loops_num) * 3, 0.0f); for (l_index = 0; l_index < loops_num; l_index++) { - const int v_index = (int)mloop[l_index].v; + const int v_index = int(mloop[l_index].v); float delta[3]; sub_v3_v3v3(delta, rest_coords[v_index], smooth_vertex_coords[v_index]); @@ -563,7 +568,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, Mesh *mesh, float (*vertexCos)[3], uint verts_num, - struct BMEditMesh *em) + BMEditMesh *em) { CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md; @@ -577,7 +582,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, const uint loops_num = (uint)mesh->totloop; bool use_only_smooth = (csmd->flag & MOD_CORRECTIVESMOOTH_ONLY_SMOOTH) != 0; - const MDeformVert *dvert = NULL; + const MDeformVert *dvert = nullptr; int defgrp_index; MOD_get_vgroup(ob, mesh, csmd->defgrp_name, &dvert, &defgrp_index); @@ -587,14 +592,14 @@ static void correctivesmooth_modifier_do(ModifierData *md, /* signal to recalculate, whoever sets MUST also free bind coords */ (csmd->bind_coords_num == (uint)-1)) { if (DEG_is_active(depsgraph)) { - BLI_assert(csmd->bind_coords == NULL); - csmd->bind_coords = MEM_dupallocN(vertexCos); + BLI_assert(csmd->bind_coords == nullptr); + csmd->bind_coords = static_cast(MEM_dupallocN(vertexCos)); csmd->bind_coords_num = verts_num; - BLI_assert(csmd->bind_coords != NULL); + BLI_assert(csmd->bind_coords != nullptr); /* Copy bound data to the original modifier. */ CorrectiveSmoothModifierData *csmd_orig = (CorrectiveSmoothModifierData *) BKE_modifier_get_original(ob, &csmd->modifier); - csmd_orig->bind_coords = MEM_dupallocN(csmd->bind_coords); + csmd_orig->bind_coords = static_cast(MEM_dupallocN(csmd->bind_coords)); csmd_orig->bind_coords_num = csmd->bind_coords_num; } else { @@ -607,7 +612,8 @@ static void correctivesmooth_modifier_do(ModifierData *md, return; } - if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) && (csmd->bind_coords == NULL)) { + if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) && + (csmd->bind_coords == nullptr)) { BKE_modifier_set_error(ob, md, "Bind data required"); goto error; } @@ -653,7 +659,8 @@ static void correctivesmooth_modifier_do(ModifierData *md, else { int me_numVerts; rest_coords = em ? BKE_editmesh_vert_coords_alloc_orco(em, &me_numVerts) : - BKE_mesh_vert_coords_alloc(ob->data, &me_numVerts); + BKE_mesh_vert_coords_alloc(static_cast(ob->data), + &me_numVerts); BLI_assert((uint)me_numVerts == verts_num); is_rest_coords_alloc = true; @@ -688,15 +695,14 @@ static void correctivesmooth_modifier_do(ModifierData *md, { uint l_index; - float(*tangent_spaces)[3][3]; - float *tangent_weights; - - float *tangent_weights_per_vertex; const float scale = csmd->scale; - tangent_spaces = MEM_malloc_arrayN(loops_num, sizeof(float[3][3]), __func__); - tangent_weights = MEM_malloc_arrayN(loops_num, sizeof(float), __func__); - tangent_weights_per_vertex = MEM_malloc_arrayN(verts_num, sizeof(float), __func__); + float(*tangent_spaces)[3][3] = static_cast( + MEM_malloc_arrayN(loops_num, sizeof(float[3][3]), __func__)); + float *tangent_weights = static_cast( + MEM_malloc_arrayN(loops_num, sizeof(float), __func__)); + float *tangent_weights_per_vertex = static_cast( + MEM_malloc_arrayN(verts_num, sizeof(float), __func__)); calc_tangent_spaces( mesh, vertexCos, tangent_spaces, tangent_weights, tangent_weights_per_vertex); @@ -738,39 +744,40 @@ static void deformVerts(ModifierData *md, float (*vertexCos)[3], int verts_num) { - Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false); + Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false); correctivesmooth_modifier_do( - md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)verts_num, NULL); + md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)verts_num, nullptr); - if (!ELEM(mesh_src, NULL, mesh)) { - BKE_id_free(NULL, mesh_src); + if (!ELEM(mesh_src, nullptr, mesh)) { + BKE_id_free(nullptr, mesh_src); } } static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, - struct BMEditMesh *editData, + BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], int verts_num) { - Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false); + Mesh *mesh_src = MOD_deform_mesh_eval_get( + ctx->object, editData, mesh, nullptr, verts_num, false); /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ - if (mesh_src != NULL) { + if (mesh_src != nullptr) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } correctivesmooth_modifier_do( md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)verts_num, editData); - if (!ELEM(mesh_src, NULL, mesh)) { - BKE_id_free(NULL, mesh_src); + if (!ELEM(mesh_src, nullptr, mesh)) { + BKE_id_free(nullptr, mesh_src); } } -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; @@ -780,16 +787,16 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); uiItemR(layout, ptr, "factor", 0, IFACE_("Factor"), ICON_NONE); - uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NONE); - uiItemR(layout, ptr, "scale", 0, NULL, ICON_NONE); - uiItemR(layout, ptr, "smooth_type", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "iterations", 0, nullptr, ICON_NONE); + uiItemR(layout, ptr, "scale", 0, nullptr, ICON_NONE); + uiItemR(layout, ptr, "smooth_type", 0, nullptr, ICON_NONE); - modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL); + modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr); - uiItemR(layout, ptr, "use_only_smooth", 0, NULL, ICON_NONE); - uiItemR(layout, ptr, "use_pin_boundary", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "use_only_smooth", 0, nullptr, ICON_NONE); + uiItemR(layout, ptr, "use_pin_boundary", 0, nullptr, ICON_NONE); - uiItemR(layout, ptr, "rest_source", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "rest_source", 0, nullptr, ICON_NONE); if (RNA_enum_get(ptr, "rest_source") == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) { uiItemO(layout, (RNA_boolean_get(ptr, "is_bind") ? IFACE_("Unbind") : IFACE_("Bind")), @@ -817,13 +824,13 @@ static void blendWrite(BlendWriter *writer, const ID *id_owner, const ModifierDa /* Modifier coming from linked data cannot be bound from an override, so we can remove all * binding data, can save a significant amount of memory. */ csmd.bind_coords_num = 0; - csmd.bind_coords = NULL; + csmd.bind_coords = nullptr; } } BLO_write_struct_at_address(writer, CorrectiveSmoothModifierData, md, &csmd); - if (csmd.bind_coords != NULL) { + if (csmd.bind_coords != nullptr) { BLO_write_float3_array(writer, csmd.bind_coords_num, (float *)csmd.bind_coords); } } @@ -833,11 +840,11 @@ static void blendRead(BlendDataReader *reader, ModifierData *md) CorrectiveSmoothModifierData *csmd = (CorrectiveSmoothModifierData *)md; if (csmd->bind_coords) { - BLO_read_float3_array(reader, (int)csmd->bind_coords_num, (float **)&csmd->bind_coords); + BLO_read_float3_array(reader, int(csmd->bind_coords_num), (float **)&csmd->bind_coords); } /* runtime only */ - csmd->delta_cache.deltas = NULL; + csmd->delta_cache.deltas = nullptr; csmd->delta_cache.deltas_num = 0; } @@ -853,22 +860,22 @@ ModifierTypeInfo modifierType_CorrectiveSmooth = { /*copyData*/ copyData, /*deformVerts*/ deformVerts, - /*deformMatrices*/ NULL, + /*deformMatrices*/ nullptr, /*deformVertsEM*/ deformVertsEM, - /*deformMatricesEM*/ NULL, - /*modifyMesh*/ NULL, - /*modifyGeometrySet*/ NULL, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ nullptr, + /*modifyGeometrySet*/ nullptr, /*initData*/ initData, /*requiredDataMask*/ requiredDataMask, /*freeData*/ freeData, - /*isDisabled*/ NULL, - /*updateDepsgraph*/ NULL, - /*dependsOnTime*/ NULL, - /*dependsOnNormals*/ NULL, - /*foreachIDLink*/ NULL, - /*foreachTexLink*/ NULL, - /*freeRuntimeData*/ NULL, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ nullptr, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ nullptr, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, /*panelRegister*/ panelRegister, /*blendWrite*/ blendWrite, /*blendRead*/ blendRead, diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.cc similarity index 84% rename from source/blender/modifiers/intern/MOD_explode.c rename to source/blender/modifiers/intern/MOD_explode.cc index ebce5bb105b..8183db3ca1d 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.cc @@ -72,9 +72,9 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla BKE_modifier_copydata_generic(md, target, flag); - temd->facepa = NULL; + temd->facepa = nullptr; } -static bool dependsOnTime(struct Scene *UNUSED(scene), ModifierData *UNUSED(md)) +static bool dependsOnTime(Scene * /*scene*/, ModifierData * /*md*/) { return true; } @@ -90,12 +90,12 @@ static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_ma static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *psmd, Mesh *mesh) { ParticleSystem *psys = psmd->psys; - MFace *fa = NULL, *mface = NULL; + MFace *fa = nullptr, *mface = nullptr; ParticleData *pa; KDTree_3d *tree; RNG *rng; float center[3], co[3]; - int *facepa = NULL, *vertpa = NULL, totvert = 0, totface = 0, totpart = 0; + int *facepa = nullptr, *vertpa = nullptr, totvert = 0, totface = 0, totpart = 0; int i, p, v1, v2, v3, v4 = 0; const bool invert_vgroup = (emd->flag & eExplodeFlag_INVERT_VGROUP) != 0; @@ -110,9 +110,9 @@ static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *p if (emd->facepa) { MEM_freeN(emd->facepa); } - facepa = emd->facepa = MEM_calloc_arrayN(totface, sizeof(int), "explode_facepa"); + facepa = emd->facepa = static_cast(MEM_calloc_arrayN(totface, sizeof(int), __func__)); - vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa"); + vertpa = static_cast(MEM_calloc_arrayN(totvert, sizeof(int), __func__)); /* initialize all faces & verts to no particle */ for (i = 0; i < totface; i++) { @@ -124,7 +124,7 @@ static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *p /* set protected verts */ if (emd->vgroup) { - const MDeformVert *dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT); + const MDeformVert *dvert = BKE_mesh_deform_verts(mesh); if (dvert) { const int defgrp_index = emd->vgroup - 1; for (i = 0; i < totvert; i++, dvert++) { @@ -149,10 +149,10 @@ static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *p pa->fuv, pa->foffset, co, - NULL, - NULL, - NULL, - NULL); + nullptr, + nullptr, + nullptr, + nullptr); BLI_kdtree_3d_insert(tree, p, co); } BLI_kdtree_3d_balance(tree); @@ -169,7 +169,7 @@ static void createFacepa(ExplodeModifierData *emd, ParticleSystemModifierData *p mul_v3_fl(center, 1.0f / 3.0f); } - p = BLI_kdtree_3d_find_nearest(tree, center, NULL); + p = BLI_kdtree_3d_find_nearest(tree, center, nullptr); v1 = vertpa[fa->v1]; v2 = vertpa[fa->v2]; @@ -215,7 +215,8 @@ static const short add_faces[24] = { static MFace *get_dface(Mesh *mesh, Mesh *split, int cur, int i, MFace *mf) { - MFace *mfaces = CustomData_get_layer_for_write(&split->fdata, CD_MFACE, split->totface); + MFace *mfaces = static_cast( + CustomData_get_layer_for_write(&split->fdata, CD_MFACE, split->totface)); MFace *df = &mfaces[cur]; CustomData_copy_data(&mesh->fdata, &split->fdata, i, cur, 1); *df = *mf; @@ -284,11 +285,13 @@ static void remap_uvs_3_6_9_12( int l; for (l = 0; l < layers_num; l++) { - mf = CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface); + mf = static_cast( + CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface)); df1 = mf + cur; df2 = df1 + 1; df3 = df1 + 2; - mf = CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface); + mf = static_cast( + CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface)); mf += i; copy_v2_v2(df1->uv[0], mf->uv[c0]); @@ -344,10 +347,12 @@ static void remap_uvs_5_10( int l; for (l = 0; l < layers_num; l++) { - mf = CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface); + mf = static_cast( + CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface)); df1 = mf + cur; df2 = df1 + 1; - mf = CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface); + mf = static_cast( + CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface)); mf += i; copy_v2_v2(df1->uv[0], mf->uv[c0]); @@ -416,12 +421,14 @@ static void remap_uvs_15( int l; for (l = 0; l < layers_num; l++) { - mf = CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface); + mf = static_cast( + CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface)); df1 = mf + cur; df2 = df1 + 1; df3 = df1 + 2; df4 = df1 + 3; - mf = CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface); + mf = static_cast( + CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface)); mf += i; copy_v2_v2(df1->uv[0], mf->uv[c0]); @@ -492,11 +499,13 @@ static void remap_uvs_7_11_13_14( int l; for (l = 0; l < layers_num; l++) { - mf = CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface); + mf = static_cast( + CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface)); df1 = mf + cur; df2 = df1 + 1; df3 = df1 + 2; - mf = CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface); + mf = static_cast( + CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface)); mf += i; copy_v2_v2(df1->uv[0], mf->uv[c0]); @@ -552,10 +561,12 @@ static void remap_uvs_19_21_22( int l; for (l = 0; l < layers_num; l++) { - mf = CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface); + mf = static_cast( + CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface)); df1 = mf + cur; df2 = df1 + 1; - mf = CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface); + mf = static_cast( + CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface)); mf += i; copy_v2_v2(df1->uv[0], mf->uv[c0]); @@ -614,10 +625,12 @@ static void remap_uvs_23( int l; for (l = 0; l < layers_num; l++) { - mf = CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface); + mf = static_cast( + CustomData_get_layer_n_for_write(&split->fdata, CD_MTFACE, l, split->totface)); df1 = mf + cur; df2 = df1 + 1; - mf = CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface); + mf = static_cast( + CustomData_get_layer_n_for_write(&mesh->fdata, CD_MTFACE, l, mesh->totface)); mf += i; copy_v2_v2(df1->uv[0], mf->uv[c0]); @@ -638,16 +651,17 @@ static void remap_uvs_23( static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) { Mesh *split_m; - MFace *mf = NULL, *df1 = NULL; - MFace *mface = CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface); + MFace *mf = nullptr, *df1 = nullptr; + MFace *mface = static_cast( + CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface)); float *dupve; EdgeHash *edgehash; EdgeHashIterator *ehi; int totvert = mesh->totvert; int totface = mesh->totface; - int *facesplit = MEM_calloc_arrayN(totface, sizeof(int), "explode_facesplit"); - int *vertpa = MEM_calloc_arrayN(totvert, sizeof(int), "explode_vertpa2"); + int *facesplit = static_cast(MEM_calloc_arrayN(totface, sizeof(int), __func__)); + int *vertpa = static_cast(MEM_calloc_arrayN(totvert, sizeof(int), __func__)); int *facepa = emd->facepa; int *fs, totesplit = 0, totfsplit = 0, curdupface = 0; int i, v1, v2, v3, v4, esplit, v[4] = {0, 0, 0, 0}, /* To quite gcc barking... */ @@ -674,12 +688,12 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) v3 = vertpa[mf->v3]; if (v1 != v2) { - BLI_edgehash_reinsert(edgehash, mf->v1, mf->v2, NULL); + BLI_edgehash_reinsert(edgehash, mf->v1, mf->v2, nullptr); (*fs) |= 1; } if (v2 != v3) { - BLI_edgehash_reinsert(edgehash, mf->v2, mf->v3, NULL); + BLI_edgehash_reinsert(edgehash, mf->v2, mf->v3, nullptr); (*fs) |= 2; } @@ -687,25 +701,25 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) v4 = vertpa[mf->v4]; if (v3 != v4) { - BLI_edgehash_reinsert(edgehash, mf->v3, mf->v4, NULL); + BLI_edgehash_reinsert(edgehash, mf->v3, mf->v4, nullptr); (*fs) |= 4; } if (v1 != v4) { - BLI_edgehash_reinsert(edgehash, mf->v1, mf->v4, NULL); + BLI_edgehash_reinsert(edgehash, mf->v1, mf->v4, nullptr); (*fs) |= 8; } /* mark center vertex as a fake edge split */ if (*fs == 15) { - BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL); + BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, nullptr); } } else { (*fs) |= 16; /* mark face as tri */ if (v1 != v3) { - BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, NULL); + BLI_edgehash_reinsert(edgehash, mf->v1, mf->v3, nullptr); (*fs) |= 4; } } @@ -742,7 +756,8 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) * later interpreted as tri's, for this to work right I think we probably * have to stop using tessface. */ - facepa = MEM_calloc_arrayN((totface + (totfsplit * 2)), sizeof(int), "explode_facepa"); + facepa = static_cast( + MEM_calloc_arrayN((totface + (totfsplit * 2)), sizeof(int), __func__)); // memcpy(facepa, emd->facepa, totface*sizeof(int)); emd->facepa = facepa; @@ -869,13 +884,14 @@ static Mesh *cutEdges(ExplodeModifierData *emd, Mesh *mesh) curdupface += add_faces[*fs] + 1; } - MFace *split_mface = CustomData_get_layer_for_write(&split_m->fdata, CD_MFACE, split_m->totface); + MFace *split_mface = static_cast( + CustomData_get_layer_for_write(&split_m->fdata, CD_MFACE, split_m->totface)); for (i = 0; i < curdupface; i++) { mf = &split_mface[i]; BKE_mesh_mface_index_validate(mf, &split_m->fdata, i, ((mf->flag & ME_FACE_SEL) ? 4 : 3)); } - BLI_edgehash_free(edgehash, NULL); + BLI_edgehash_free(edgehash, nullptr); MEM_freeN(facesplit); MEM_freeN(vertpa); @@ -891,14 +907,14 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, Mesh *to_explode) { Mesh *explode, *mesh = to_explode; - MFace *mf = NULL, *mface; + MFace *mf = nullptr, *mface; // ParticleSettings *part=psmd->psys->part; /* UNUSED */ - ParticleSimulationData sim = {NULL}; - ParticleData *pa = NULL, *pars = psmd->psys->particles; + ParticleSimulationData sim = {nullptr}; + ParticleData *pa = nullptr, *pars = psmd->psys->particles; ParticleKey state, birth; EdgeHash *vertpahash; EdgeHashIterator *ehi; - float *vertco = NULL, imat[4][4]; + float *vertco = nullptr, imat[4][4]; float rot[4]; float ctime; // float timestep; @@ -909,7 +925,8 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, totface = mesh->totface; totvert = mesh->totvert; - mface = CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface); + mface = static_cast( + CustomData_get_layer_for_write(&mesh->fdata, CD_MFACE, mesh->totface)); totpart = psmd->psys->totpart; sim.depsgraph = ctx->depsgraph; @@ -937,12 +954,12 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, } } else { - pa = NULL; + pa = nullptr; } /* do mindex + totvert to ensure the vertex index to be the first * with BLI_edgehashIterator_getKey */ - if (pa == NULL || ctime < pa->time) { + if (pa == nullptr || ctime < pa->time) { mindex = totvert + totpart; } else { @@ -952,11 +969,11 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, mf = &mface[i]; /* set face vertices to exist in particle group */ - BLI_edgehash_reinsert(vertpahash, mf->v1, mindex, NULL); - BLI_edgehash_reinsert(vertpahash, mf->v2, mindex, NULL); - BLI_edgehash_reinsert(vertpahash, mf->v3, mindex, NULL); + BLI_edgehash_reinsert(vertpahash, mf->v1, mindex, nullptr); + BLI_edgehash_reinsert(vertpahash, mf->v2, mindex, nullptr); + BLI_edgehash_reinsert(vertpahash, mf->v3, mindex, nullptr); if (mf->v4) { - BLI_edgehash_reinsert(vertpahash, mf->v4, mindex, NULL); + BLI_edgehash_reinsert(vertpahash, mf->v4, mindex, nullptr); } } @@ -971,8 +988,8 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, /* the final duplicated vertices */ explode = BKE_mesh_new_nomain_from_template(mesh, totdup, 0, totface - delface, 0, 0); - MTFace *mtface = CustomData_get_layer_named_for_write( - &explode->fdata, CD_MTFACE, emd->uvname, explode->totface); + MTFace *mtface = static_cast(CustomData_get_layer_named_for_write( + &explode->fdata, CD_MTFACE, emd->uvname, explode->totface)); /* getting back to object space */ invert_m4_m4(imat, ctx->object->object_to_world); @@ -1024,14 +1041,14 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, mul_m4_v3(imat, vertco); } else { - pa = NULL; + pa = nullptr; } } BLI_edgehashIterator_free(ehi); /* Map new vertices to faces. */ - MFace *explode_mface = CustomData_get_layer_for_write( - &explode->fdata, CD_MFACE, explode->totface); + MFace *explode_mface = static_cast( + CustomData_get_layer_for_write(&explode->fdata, CD_MFACE, explode->totface)); for (i = 0, u = 0; i < totface; i++) { MFace source; int orig_v4; @@ -1050,7 +1067,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, } } else { - pa = NULL; + pa = nullptr; } source = mface[i]; @@ -1059,7 +1076,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, orig_v4 = source.v4; /* Same as above in the first loop over mesh's faces. */ - if (pa == NULL || ctime < pa->time) { + if (pa == nullptr || ctime < pa->time) { mindex = totvert + totpart; } else { @@ -1079,7 +1096,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, /* override uv channel for particle age */ if (mtface) { - float age = (pa != NULL) ? (ctime - pa->time) / pa->lifetime : 0.0f; + float age = (pa != nullptr) ? (ctime - pa->time) / pa->lifetime : 0.0f; /* Clamp to this range to avoid flipping to the other side of the coordinates. */ CLAMP(age, 0.001f, 0.999f); @@ -1094,7 +1111,7 @@ static Mesh *explodeMesh(ExplodeModifierData *emd, } /* cleanup */ - BLI_edgehash_free(vertpahash, NULL); + BLI_edgehash_free(vertpahash, nullptr); /* finalization */ BKE_mesh_calc_edges_tessface(explode); @@ -1110,7 +1127,7 @@ static ParticleSystemModifierData *findPrecedingParticlesystem(Object *ob, Modif ModifierData *md; ParticleSystemModifierData *psmd = NULL; - for (md = ob->modifiers.first; emd != md; md = md->next) { + for (md = static_cast(ob->modifiers.first); emd != md; md = md->next) { if (md->type == eModifierType_ParticleSystem) { psmd = (ParticleSystemModifierData *)md; } @@ -1125,20 +1142,20 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * if (psmd) { ParticleSystem *psys = psmd->psys; - if (psys == NULL || psys->totpart == 0) { + if (psys == nullptr || psys->totpart == 0) { return mesh; } - if (psys->part == NULL || psys->particles == NULL) { + if (psys->part == nullptr || psys->particles == nullptr) { return mesh; } - if (psmd->mesh_final == NULL) { + if (psmd->mesh_final == nullptr) { return mesh; } BKE_mesh_tessface_ensure(mesh); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ /* 1. find faces to be exploded if needed */ - if (emd->facepa == NULL || psmd->flag & eParticleSystemFlag_Pars || + if (emd->facepa == nullptr || psmd->flag & eParticleSystemFlag_Pars || emd->flag & eExplodeFlag_CalcFaces || MEM_allocN_len(emd->facepa) / sizeof(int) != mesh->totface) { if (psmd->flag & eParticleSystemFlag_Pars) { @@ -1158,7 +1175,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MEM_freeN(emd->facepa); emd->facepa = facepa; - BKE_id_free(NULL, split_m); + BKE_id_free(nullptr, split_m); return explode; } @@ -1167,7 +1184,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * return mesh; } -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *row, *col; uiLayout *layout = panel->layout; @@ -1181,24 +1198,24 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); - uiItemPointerR(layout, ptr, "particle_uv", &obj_data_ptr, "uv_layers", NULL, ICON_NONE); + uiItemPointerR(layout, ptr, "particle_uv", &obj_data_ptr, "uv_layers", nullptr, ICON_NONE); row = uiLayoutRowWithHeading(layout, true, IFACE_("Show")); - uiItemR(row, ptr, "show_alive", toggles_flag, NULL, ICON_NONE); - uiItemR(row, ptr, "show_dead", toggles_flag, NULL, ICON_NONE); - uiItemR(row, ptr, "show_unborn", toggles_flag, NULL, ICON_NONE); + uiItemR(row, ptr, "show_alive", toggles_flag, nullptr, ICON_NONE); + uiItemR(row, ptr, "show_dead", toggles_flag, nullptr, ICON_NONE); + uiItemR(row, ptr, "show_unborn", toggles_flag, nullptr, ICON_NONE); uiLayoutSetPropSep(layout, true); col = uiLayoutColumn(layout, false); - uiItemR(col, ptr, "use_edge_cut", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "use_size", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "use_edge_cut", 0, nullptr, ICON_NONE); + uiItemR(col, ptr, "use_size", 0, nullptr, ICON_NONE); - modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL); + modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr); row = uiLayoutRow(layout, false); uiLayoutSetActive(row, has_vertex_group); - uiItemR(row, ptr, "protect", 0, NULL, ICON_NONE); + uiItemR(row, ptr, "protect", 0, nullptr, ICON_NONE); uiItemO(layout, IFACE_("Refresh"), ICON_NONE, "OBJECT_OT_explode_refresh"); @@ -1210,11 +1227,11 @@ static void panelRegister(ARegionType *region_type) modifier_panel_register(region_type, eModifierType_Explode, panel_draw); } -static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md) +static void blendRead(BlendDataReader * /*reader*/, ModifierData *md) { ExplodeModifierData *psmd = (ExplodeModifierData *)md; - psmd->facepa = NULL; + psmd->facepa = nullptr; } ModifierTypeInfo modifierType_Explode = { @@ -1227,24 +1244,24 @@ ModifierTypeInfo modifierType_Explode = { /*icon*/ ICON_MOD_EXPLODE, /*copyData*/ copyData, - /*deformVerts*/ NULL, - /*deformMatrices*/ NULL, - /*deformVertsEM*/ NULL, - /*deformMatricesEM*/ NULL, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, /*modifyMesh*/ modifyMesh, - /*modifyGeometrySet*/ NULL, + /*modifyGeometrySet*/ nullptr, /*initData*/ initData, /*requiredDataMask*/ requiredDataMask, /*freeData*/ freeData, - /*isDisabled*/ NULL, - /*updateDepsgraph*/ NULL, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ nullptr, /*dependsOnTime*/ dependsOnTime, - /*dependsOnNormals*/ NULL, - /*foreachIDLink*/ NULL, - /*foreachTexLink*/ NULL, - /*freeRuntimeData*/ NULL, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ nullptr, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, /*panelRegister*/ panelRegister, - /*blendWrite*/ NULL, + /*blendWrite*/ nullptr, /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.cc similarity index 87% rename from source/blender/modifiers/intern/MOD_laplaciansmooth.c rename to source/blender/modifiers/intern/MOD_laplaciansmooth.cc index 77e0fadf75e..704235713e0 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.cc @@ -39,7 +39,7 @@ #include "eigen_capi.h" -struct BLaplacianSystem { +struct LaplacianSystem { float *eweights; /* Length weights per Edge */ float (*fweights)[3]; /* Cotangent weights per face */ float *ring_areas; /* Total area per ring. */ @@ -64,7 +64,6 @@ struct BLaplacianSystem { float min_area; float vert_centroid[3]; }; -typedef struct BLaplacianSystem LaplacianSystem; static float compute_volume(const float center[3], float (*vertexCos)[3], @@ -97,10 +96,10 @@ static void delete_laplacian_system(LaplacianSystem *sys) if (sys->context) { EIG_linear_solver_delete(sys->context); } - sys->vertexCos = NULL; - sys->mpoly = NULL; - sys->mloop = NULL; - sys->medges = NULL; + sys->vertexCos = nullptr; + sys->mpoly = nullptr; + sys->mloop = nullptr; + sys->medges = nullptr; MEM_freeN(sys); } @@ -122,20 +121,20 @@ static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numVerts) { LaplacianSystem *sys; - sys = MEM_callocN(sizeof(LaplacianSystem), "ModLaplSmoothSystem"); + sys = static_cast(MEM_callocN(sizeof(LaplacianSystem), __func__)); sys->edges_num = a_numEdges; sys->polys_num = a_numPolys; sys->loops_num = a_numLoops; sys->verts_num = a_numVerts; - sys->eweights = MEM_calloc_arrayN(sys->edges_num, sizeof(float), __func__); - sys->fweights = MEM_calloc_arrayN(sys->loops_num, sizeof(float[3]), __func__); - sys->ne_ed_num = MEM_calloc_arrayN(sys->verts_num, sizeof(short), __func__); - sys->ne_fa_num = MEM_calloc_arrayN(sys->verts_num, sizeof(short), __func__); - sys->ring_areas = MEM_calloc_arrayN(sys->verts_num, sizeof(float), __func__); - sys->vlengths = MEM_calloc_arrayN(sys->verts_num, sizeof(float), __func__); - sys->vweights = MEM_calloc_arrayN(sys->verts_num, sizeof(float), __func__); - sys->zerola = MEM_calloc_arrayN(sys->verts_num, sizeof(bool), __func__); + sys->eweights = MEM_cnew_array(sys->edges_num, __func__); + sys->fweights = MEM_cnew_array(sys->loops_num, __func__); + sys->ne_ed_num = MEM_cnew_array(sys->verts_num, __func__); + sys->ne_fa_num = MEM_cnew_array(sys->verts_num, __func__); + sys->ring_areas = MEM_cnew_array(sys->verts_num, __func__); + sys->vlengths = MEM_cnew_array(sys->verts_num, __func__); + sys->vweights = MEM_cnew_array(sys->verts_num, __func__); + sys->zerola = MEM_cnew_array(sys->verts_num, __func__); return sys; } @@ -350,15 +349,15 @@ static void validate_solution(LaplacianSystem *sys, short flag, float lambda, fl lam = sys->ne_ed_num[i] == sys->ne_fa_num[i] ? (lambda >= 0.0f ? 1.0f : -1.0f) : (lambda_border >= 0.0f ? 1.0f : -1.0f); if (flag & MOD_LAPLACIANSMOOTH_X) { - sys->vertexCos[i][0] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 0, i) - + sys->vertexCos[i][0] += lam * (float(EIG_linear_solver_variable_get(sys->context, 0, i)) - sys->vertexCos[i][0]); } if (flag & MOD_LAPLACIANSMOOTH_Y) { - sys->vertexCos[i][1] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 1, i) - + sys->vertexCos[i][1] += lam * (float(EIG_linear_solver_variable_get(sys->context, 1, i)) - sys->vertexCos[i][1]); } if (flag & MOD_LAPLACIANSMOOTH_Z) { - sys->vertexCos[i][2] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 2, i) - + sys->vertexCos[i][2] += lam * (float(EIG_linear_solver_variable_get(sys->context, 2, i)) - sys->vertexCos[i][2]); } } @@ -374,8 +373,8 @@ static void laplaciansmoothModifier_do( LaplacianSmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int verts_num) { LaplacianSystem *sys; - const MDeformVert *dvert = NULL; - const MDeformVert *dv = NULL; + const MDeformVert *dvert = nullptr; + const MDeformVert *dv = nullptr; float w, wpaint; int i, iter; int defgrp_index; @@ -412,7 +411,7 @@ static void laplaciansmoothModifier_do( } } if (iter == 0 && verts_num > 0) { - mul_v3_fl(sys->vert_centroid, 1.0f / (float)verts_num); + mul_v3_fl(sys->vert_centroid, 1.0f / float(verts_num)); } dv = dvert; @@ -478,7 +477,7 @@ static void laplaciansmoothModifier_do( } } EIG_linear_solver_delete(sys->context); - sys->context = NULL; + sys->context = nullptr; delete_laplacian_system(sys); } @@ -492,9 +491,7 @@ static void init_data(ModifierData *md) MEMCPY_STRUCT_AFTER(smd, DNA_struct_default_get(LaplacianSmoothModifierData), modifier); } -static bool is_disabled(const struct Scene *UNUSED(scene), - ModifierData *md, - bool UNUSED(useRenderParams)) +static bool is_disabled(const Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/) { LaplacianSmoothModifierData *smd = (LaplacianSmoothModifierData *)md; short flag; @@ -531,19 +528,19 @@ static void deformVerts(ModifierData *md, return; } - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false); laplaciansmoothModifier_do( (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num); - if (!ELEM(mesh_src, NULL, mesh)) { - BKE_id_free(NULL, mesh_src); + if (!ELEM(mesh_src, nullptr, mesh)) { + BKE_id_free(nullptr, mesh_src); } } static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, - struct BMEditMesh *editData, + BMEditMesh *editData, Mesh *mesh, float (*vertexCos)[3], int verts_num) @@ -554,22 +551,22 @@ static void deformVertsEM(ModifierData *md, return; } - mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, nullptr, verts_num, false); /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ - if (mesh_src != NULL) { + if (mesh_src != nullptr) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } laplaciansmoothModifier_do( (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num); - if (!ELEM(mesh_src, NULL, mesh)) { - BKE_id_free(NULL, mesh_src); + if (!ELEM(mesh_src, nullptr, mesh)) { + BKE_id_free(nullptr, mesh_src); } } -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *row; uiLayout *layout = panel->layout; @@ -580,20 +577,20 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); - uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "iterations", 0, nullptr, ICON_NONE); row = uiLayoutRowWithHeading(layout, true, IFACE_("Axis")); - uiItemR(row, ptr, "use_x", toggles_flag, NULL, ICON_NONE); - uiItemR(row, ptr, "use_y", toggles_flag, NULL, ICON_NONE); - uiItemR(row, ptr, "use_z", toggles_flag, NULL, ICON_NONE); + uiItemR(row, ptr, "use_x", toggles_flag, nullptr, ICON_NONE); + uiItemR(row, ptr, "use_y", toggles_flag, nullptr, ICON_NONE); + uiItemR(row, ptr, "use_z", toggles_flag, nullptr, ICON_NONE); - uiItemR(layout, ptr, "lambda_factor", 0, NULL, ICON_NONE); - uiItemR(layout, ptr, "lambda_border", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "lambda_factor", 0, nullptr, ICON_NONE); + uiItemR(layout, ptr, "lambda_border", 0, nullptr, ICON_NONE); - uiItemR(layout, ptr, "use_volume_preserve", 0, NULL, ICON_NONE); - uiItemR(layout, ptr, "use_normalized", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "use_volume_preserve", 0, nullptr, ICON_NONE); + uiItemR(layout, ptr, "use_normalized", 0, nullptr, ICON_NONE); - modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL); + modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr); modifier_panel_end(layout, ptr); } @@ -615,23 +612,23 @@ ModifierTypeInfo modifierType_LaplacianSmooth = { /*copyData*/ BKE_modifier_copydata_generic, /*deformVerts*/ deformVerts, - /*deformMatrices*/ NULL, + /*deformMatrices*/ nullptr, /*deformVertsEM*/ deformVertsEM, - /*deformMatricesEM*/ NULL, - /*modifyMesh*/ NULL, - /*modifyGeometrySet*/ NULL, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ nullptr, + /*modifyGeometrySet*/ nullptr, /*initData*/ init_data, /*requiredDataMask*/ required_data_mask, - /*freeData*/ NULL, + /*freeData*/ nullptr, /*isDisabled*/ is_disabled, - /*updateDepsgraph*/ NULL, - /*dependsOnTime*/ NULL, - /*dependsOnNormals*/ NULL, - /*foreachIDLink*/ NULL, - /*foreachTexLink*/ NULL, - /*freeRuntimeData*/ NULL, + /*updateDepsgraph*/ nullptr, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ nullptr, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, /*panelRegister*/ panelRegister, - /*blendWrite*/ NULL, - /*blendRead*/ NULL, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.cc similarity index 79% rename from source/blender/modifiers/intern/MOD_ocean.c rename to source/blender/modifiers/intern/MOD_ocean.cc index cad2f57e45a..d5ae1caf703 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.cc @@ -45,7 +45,7 @@ #include "MOD_ui_common.h" #ifdef WITH_OCEANSIM -static void init_cache_data(Object *ob, struct OceanModifierData *omd, const int resolution) +static void init_cache_data(Object *ob, OceanModifierData *omd, const int resolution) { const char *relbase = BKE_modifier_path_relbase_from_global(ob); @@ -60,7 +60,7 @@ static void init_cache_data(Object *ob, struct OceanModifierData *omd, const int resolution); } -static void simulate_ocean_modifier(struct OceanModifierData *omd) +static void simulate_ocean_modifier(OceanModifierData *omd) { BKE_ocean_simulate(omd->ocean, omd->time, omd->wave_scale, omd->chop_amount); } @@ -115,7 +115,7 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla /* The oceancache object will be recreated for this copy * automatically when cached=true */ - tomd->oceancache = NULL; + tomd->oceancache = nullptr; tomd->ocean = BKE_ocean_add(); if (BKE_ocean_init_from_modifier(tomd->ocean, tomd, tomd->viewport_resolution)) { @@ -139,8 +139,7 @@ static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_ma } } #else /* WITH_OCEANSIM */ -static void requiredDataMask(ModifierData *UNUSED(md), - CustomData_MeshMasks *UNUSED(r_cddata_masks)) +static void requiredDataMask(ModifierData * /*md*/, CustomData_MeshMasks * /*r_cddata_masks*/) { } #endif /* WITH_OCEANSIM */ @@ -153,7 +152,7 @@ static bool dependsOnNormals(ModifierData *md) #ifdef WITH_OCEANSIM -typedef struct GenerateOceanGeometryData { +struct GenerateOceanGeometryData { float (*vert_positions)[3]; MPoly *mpolys; MLoop *mloops; @@ -164,13 +163,13 @@ typedef struct GenerateOceanGeometryData { float ox, oy; float sx, sy; float ix, iy; -} GenerateOceanGeometryData; +}; static void generate_ocean_geometry_verts(void *__restrict userdata, const int y, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - GenerateOceanGeometryData *gogd = userdata; + GenerateOceanGeometryData *gogd = static_cast(userdata); int x; for (x = 0; x <= gogd->res_x; x++) { @@ -184,9 +183,9 @@ static void generate_ocean_geometry_verts(void *__restrict userdata, static void generate_ocean_geometry_polys(void *__restrict userdata, const int y, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - GenerateOceanGeometryData *gogd = userdata; + GenerateOceanGeometryData *gogd = static_cast(userdata); int x; for (x = 0; x < gogd->res_x; x++) { @@ -213,9 +212,9 @@ static void generate_ocean_geometry_polys(void *__restrict userdata, static void generate_ocean_geometry_uvs(void *__restrict userdata, const int y, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - GenerateOceanGeometryData *gogd = userdata; + GenerateOceanGeometryData *gogd = static_cast(userdata); int x; for (x = 0; x < gogd->res_x; x++) { @@ -288,8 +287,8 @@ static Mesh *generate_ocean_geometry(OceanModifierData *omd, Mesh *mesh_orig, co /* add uvs */ if (CustomData_number_of_layers(&result->ldata, CD_PROP_FLOAT2) < MAX_MTFACE) { - gogd.mloopuvs = CustomData_add_layer_named( - &result->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, NULL, polys_num * 4, "UVMap"); + gogd.mloopuvs = static_cast(CustomData_add_layer_named( + &result->ldata, CD_PROP_FLOAT2, CD_SET_DEFAULT, nullptr, polys_num * 4, "UVMap")); if (gogd.mloopuvs) { /* unlikely to fail */ gogd.ix = 1.0 / gogd.rx; @@ -309,11 +308,11 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes BKE_modifier_set_error(ctx->object, md, "Failed to allocate memory"); return mesh; } - int cfra_scene = (int)DEG_get_ctime(ctx->depsgraph); + int cfra_scene = int(DEG_get_ctime(ctx->depsgraph)); Object *ob = ctx->object; bool allocated_ocean = false; - Mesh *result = NULL; + Mesh *result = nullptr; OceanResult ocr; const int resolution = (ctx->flag & MOD_APPLY_RENDER) ? omd->resolution : @@ -343,7 +342,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes BKE_ocean_simulate_cache(omd->oceancache, cfra_scene); } else { - /* omd->ocean is NULL on an original object (in contrast to an evaluated one). + /* omd->ocean is nullptr on an original object (in contrast to an evaluated one). * We can create a new one, but we have to free it as well once we're done. * This function is only called on an original object when applying the modifier * using the 'Apply Modifier' button, and thus it is not called frequently for @@ -356,7 +355,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes result = generate_ocean_geometry(omd, mesh, resolution); } else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) { - result = (Mesh *)BKE_id_copy_ex(NULL, &mesh->id, NULL, LIB_ID_COPY_LOCALIZE); + result = (Mesh *)BKE_id_copy_ex(nullptr, &mesh->id, nullptr, LIB_ID_COPY_LOCALIZE); } cfra_for_cache = cfra_scene; @@ -372,17 +371,21 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes const int polys_num = result->totpoly; const int loops_num = result->totloop; const MLoop *mloops = BKE_mesh_loops(result); - MLoopCol *mloopcols = CustomData_add_layer_named( - &result->ldata, CD_PROP_BYTE_COLOR, CD_SET_DEFAULT, NULL, loops_num, omd->foamlayername); + MLoopCol *mloopcols = static_cast(CustomData_add_layer_named(&result->ldata, + CD_PROP_BYTE_COLOR, + CD_SET_DEFAULT, + nullptr, + loops_num, + omd->foamlayername)); - MLoopCol *mloopcols_spray = NULL; + MLoopCol *mloopcols_spray = nullptr; if (omd->flag & MOD_OCEAN_GENERATE_SPRAY) { - mloopcols_spray = CustomData_add_layer_named(&result->ldata, - CD_PROP_BYTE_COLOR, - CD_SET_DEFAULT, - NULL, - loops_num, - omd->spraylayername); + mloopcols_spray = static_cast(CustomData_add_layer_named(&result->ldata, + CD_PROP_BYTE_COLOR, + CD_SET_DEFAULT, + nullptr, + loops_num, + omd->spraylayername)); } if (mloopcols) { /* unlikely to fail */ @@ -392,7 +395,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes const MLoop *ml = &mloops[mp->loopstart]; MLoopCol *mlcol = &mloopcols[mp->loopstart]; - MLoopCol *mlcolspray = NULL; + MLoopCol *mlcolspray = nullptr; if (omd->flag & MOD_OCEAN_GENERATE_SPRAY) { mlcolspray = &mloopcols_spray[mp->loopstart]; } @@ -470,7 +473,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes if (allocated_ocean) { BKE_ocean_free(omd->ocean); - omd->ocean = NULL; + omd->ocean = nullptr; } # undef OCEAN_CO @@ -478,7 +481,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes return result; } #else /* WITH_OCEANSIM */ -static Mesh *doOcean(ModifierData *UNUSED(md), const ModifierEvalContext *UNUSED(ctx), Mesh *mesh) +static Mesh *doOcean(ModifierData * /*md*/, const ModifierEvalContext * /*ctx*/, Mesh *mesh) { return mesh; } @@ -489,7 +492,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * return doOcean(md, ctx, mesh); } // #define WITH_OCEANSIM -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; #ifdef WITH_OCEANSIM @@ -501,7 +504,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); col = uiLayoutColumn(layout, false); - uiItemR(col, ptr, "geometry_mode", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "geometry_mode", 0, nullptr, ICON_NONE); if (RNA_enum_get(ptr, "geometry_mode") == MOD_OCEAN_GEOM_GENERATE) { sub = uiLayoutColumn(col, true); uiItemR(sub, ptr, "repeat_x", 0, IFACE_("Repeat X"), ICON_NONE); @@ -512,15 +515,15 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(sub, ptr, "viewport_resolution", 0, IFACE_("Resolution Viewport"), ICON_NONE); uiItemR(sub, ptr, "resolution", 0, IFACE_("Render"), ICON_NONE); - uiItemR(col, ptr, "time", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "time", 0, nullptr, ICON_NONE); - uiItemR(col, ptr, "depth", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "size", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "spatial_size", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "depth", 0, nullptr, ICON_NONE); + uiItemR(col, ptr, "size", 0, nullptr, ICON_NONE); + uiItemR(col, ptr, "spatial_size", 0, nullptr, ICON_NONE); - uiItemR(col, ptr, "random_seed", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "random_seed", 0, nullptr, ICON_NONE); - uiItemR(col, ptr, "use_normals", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "use_normals", 0, nullptr, ICON_NONE); modifier_panel_end(layout, ptr); @@ -530,20 +533,20 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) } #ifdef WITH_OCEANSIM -static void waves_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void waves_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col, *sub; uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiLayoutSetPropSep(layout, true); col = uiLayoutColumn(layout, false); uiItemR(col, ptr, "wave_scale", 0, IFACE_("Scale"), ICON_NONE); - uiItemR(col, ptr, "wave_scale_min", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "choppiness", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "wind_velocity", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "wave_scale_min", 0, nullptr, ICON_NONE); + uiItemR(col, ptr, "choppiness", 0, nullptr, ICON_NONE); + uiItemR(col, ptr, "wind_velocity", 0, nullptr, ICON_NONE); uiItemS(layout); @@ -552,24 +555,24 @@ static void waves_panel_draw(const bContext *UNUSED(C), Panel *panel) sub = uiLayoutColumn(col, false); uiLayoutSetActive(sub, RNA_float_get(ptr, "wave_alignment") > 0.0f); uiItemR(sub, ptr, "wave_direction", 0, IFACE_("Direction"), ICON_NONE); - uiItemR(sub, ptr, "damping", 0, NULL, ICON_NONE); + uiItemR(sub, ptr, "damping", 0, nullptr, ICON_NONE); } -static void foam_panel_draw_header(const bContext *UNUSED(C), Panel *panel) +static void foam_panel_draw_header(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiItemR(layout, ptr, "use_foam", 0, IFACE_("Foam"), ICON_NONE); } -static void foam_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void foam_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col; uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); bool use_foam = RNA_boolean_get(ptr, "use_foam"); @@ -581,12 +584,12 @@ static void foam_panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(col, ptr, "foam_coverage", 0, IFACE_("Coverage"), ICON_NONE); } -static void spray_panel_draw_header(const bContext *UNUSED(C), Panel *panel) +static void spray_panel_draw_header(const bContext * /*C*/, Panel *panel) { uiLayout *row; uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); bool use_foam = RNA_boolean_get(ptr, "use_foam"); @@ -595,12 +598,12 @@ static void spray_panel_draw_header(const bContext *UNUSED(C), Panel *panel) uiItemR(row, ptr, "use_spray", 0, CTX_IFACE_(BLT_I18NCONTEXT_ID_MESH, "Spray"), ICON_NONE); } -static void spray_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void spray_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col; uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); bool use_foam = RNA_boolean_get(ptr, "use_foam"); bool use_spray = RNA_boolean_get(ptr, "use_spray"); @@ -613,31 +616,31 @@ static void spray_panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(col, ptr, "invert_spray", 0, IFACE_("Invert"), ICON_NONE); } -static void spectrum_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void spectrum_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col; uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); int spectrum = RNA_enum_get(ptr, "spectrum"); uiLayoutSetPropSep(layout, true); col = uiLayoutColumn(layout, false); - uiItemR(col, ptr, "spectrum", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "spectrum", 0, nullptr, ICON_NONE); if (ELEM(spectrum, MOD_OCEAN_SPECTRUM_TEXEL_MARSEN_ARSLOE, MOD_OCEAN_SPECTRUM_JONSWAP)) { - uiItemR(col, ptr, "sharpen_peak_jonswap", UI_ITEM_R_SLIDER, NULL, ICON_NONE); - uiItemR(col, ptr, "fetch_jonswap", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "sharpen_peak_jonswap", UI_ITEM_R_SLIDER, nullptr, ICON_NONE); + uiItemR(col, ptr, "fetch_jonswap", 0, nullptr, ICON_NONE); } } -static void bake_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void bake_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col; uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiLayoutSetPropSep(layout, true); @@ -650,17 +653,17 @@ static void bake_panel_draw(const bContext *UNUSED(C), Panel *panel) "OBJECT_OT_ocean_bake", IFACE_("Delete Bake"), ICON_NONE, - NULL, + nullptr, WM_OP_EXEC_DEFAULT, 0, &op_ptr); RNA_boolean_set(&op_ptr, "free", true); } else { - uiItemO(layout, NULL, ICON_NONE, "OBJECT_OT_ocean_bake"); + uiItemO(layout, nullptr, ICON_NONE, "OBJECT_OT_ocean_bake"); } - uiItemR(layout, ptr, "filepath", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "filepath", 0, nullptr, ICON_NONE); col = uiLayoutColumn(layout, true); uiLayoutSetEnabled(col, !is_cached); @@ -669,7 +672,7 @@ static void bake_panel_draw(const bContext *UNUSED(C), Panel *panel) col = uiLayoutColumn(layout, false); uiLayoutSetActive(col, use_foam); - uiItemR(col, ptr, "bake_foam_fade", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "bake_foam_fade", 0, nullptr, ICON_NONE); } #endif /* WITH_OCEANSIM */ @@ -677,24 +680,24 @@ static void panelRegister(ARegionType *region_type) { PanelType *panel_type = modifier_panel_register(region_type, eModifierType_Ocean, panel_draw); #ifdef WITH_OCEANSIM - modifier_subpanel_register(region_type, "waves", "Waves", NULL, waves_panel_draw, panel_type); + modifier_subpanel_register(region_type, "waves", "Waves", nullptr, waves_panel_draw, panel_type); PanelType *foam_panel = modifier_subpanel_register( region_type, "foam", "", foam_panel_draw_header, foam_panel_draw, panel_type); modifier_subpanel_register( region_type, "spray", "", spray_panel_draw_header, spray_panel_draw, foam_panel); modifier_subpanel_register( - region_type, "spectrum", "Spectrum", NULL, spectrum_panel_draw, panel_type); - modifier_subpanel_register(region_type, "bake", "Bake", NULL, bake_panel_draw, panel_type); + region_type, "spectrum", "Spectrum", nullptr, spectrum_panel_draw, panel_type); + modifier_subpanel_register(region_type, "bake", "Bake", nullptr, bake_panel_draw, panel_type); #else UNUSED_VARS(panel_type); #endif /* WITH_OCEANSIM */ } -static void blendRead(BlendDataReader *UNUSED(reader), ModifierData *md) +static void blendRead(BlendDataReader * /*reader*/, ModifierData *md) { OceanModifierData *omd = (OceanModifierData *)md; - omd->oceancache = NULL; - omd->ocean = NULL; + omd->oceancache = nullptr; + omd->ocean = nullptr; } ModifierTypeInfo modifierType_Ocean = { @@ -708,25 +711,25 @@ ModifierTypeInfo modifierType_Ocean = { /*icon*/ ICON_MOD_OCEAN, /*copyData*/ copyData, - /*deformMatrices_DM*/ NULL, + /*deformMatrices_DM*/ nullptr, - /*deformMatrices*/ NULL, - /*deformVertsEM*/ NULL, - /*deformMatricesEM*/ NULL, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, /*modifyMesh*/ modifyMesh, - /*modifyGeometrySet*/ NULL, + /*modifyGeometrySet*/ nullptr, /*initData*/ initData, /*requiredDataMask*/ requiredDataMask, /*freeData*/ freeData, - /*isDisabled*/ NULL, - /*updateDepsgraph*/ NULL, - /*dependsOnTime*/ NULL, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ nullptr, + /*dependsOnTime*/ nullptr, /*dependsOnNormals*/ dependsOnNormals, - /*foreachIDLink*/ NULL, - /*foreachTexLink*/ NULL, - /*freeRuntimeData*/ NULL, + /*foreachIDLink*/ nullptr, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, /*panelRegister*/ panelRegister, - /*blendWrite*/ NULL, + /*blendWrite*/ nullptr, /*blendRead*/ blendRead, }; diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.cc similarity index 84% rename from source/blender/modifiers/intern/MOD_particleinstance.c rename to source/blender/modifiers/intern/MOD_particleinstance.cc index 7b9c5d3e657..8e3856942ac 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.cc @@ -61,7 +61,7 @@ static void requiredDataMask(ModifierData *md, CustomData_MeshMasks *r_cddata_ma } } -static bool isDisabled(const struct Scene *scene, ModifierData *md, bool useRenderParams) +static bool isDisabled(const Scene *scene, ModifierData *md, bool useRenderParams) { ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; ParticleSystem *psys; @@ -76,15 +76,16 @@ static bool isDisabled(const struct Scene *scene, ModifierData *md, bool useRend return true; } - psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1); - if (psys == NULL) { + psys = static_cast(BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1)); + if (psys == nullptr) { return true; } /* If the psys modifier is disabled we cannot use its data. * First look up the psys modifier from the object, then check if it is enabled. */ - for (ob_md = pimd->ob->modifiers.first; ob_md; ob_md = ob_md->next) { + for (ob_md = static_cast(pimd->ob->modifiers.first); ob_md; + ob_md = ob_md->next) { if (ob_md->type == eModifierType_ParticleSystem) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)ob_md; if (psmd->psys == psys) { @@ -112,7 +113,7 @@ static bool isDisabled(const struct Scene *scene, ModifierData *md, bool useRend static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; - if (pimd->ob != NULL) { + if (pimd->ob != nullptr) { DEG_add_object_relation( ctx->node, pimd->ob, DEG_OB_COMP_TRANSFORM, "Particle Instance Modifier"); DEG_add_object_relation( @@ -166,10 +167,10 @@ static bool particle_skip(ParticleInstanceModifierData *pimd, ParticleSystem *ps totpart = psys->totpart + psys->totchild; /* TODO: make randomization optional? */ - randp = (int)(psys_frand(psys, 3578 + p) * totpart) % totpart; + randp = int(psys_frand(psys, 3578 + p) * totpart) % totpart; - minp = (int)(totpart * pimd->particle_offset) % (totpart + 1); - maxp = (int)(totpart * (pimd->particle_offset + pimd->particle_amount)) % (totpart + 1); + minp = int(totpart * pimd->particle_offset) % (totpart + 1); + maxp = int(totpart * (pimd->particle_offset + pimd->particle_amount)) % (totpart + 1); if (maxp > minp) { return randp < minp || randp >= maxp; @@ -194,16 +195,16 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * { Mesh *result; ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; - struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); + Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph); ParticleSimulationData sim; - ParticleSystem *psys = NULL; - ParticleData *pa = NULL; + ParticleSystem *psys = nullptr; + ParticleData *pa = nullptr; int totvert, totpoly, totloop, totedge; int maxvert, maxpoly, maxloop, maxedge, part_end = 0, part_start; int k, p, p_skip; short track = ctx->object->trackflag % 3, trackneg, axis = pimd->axis; float max_co = 0.0, min_co = 0.0, temp_co[3]; - float *size = NULL; + float *size = nullptr; float spacemat[4][4]; const bool use_parents = pimd->flag & eParticleInstanceFlag_Parents; const bool use_children = pimd->flag & eParticleInstanceFlag_Children; @@ -212,13 +213,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * trackneg = ((ctx->object->trackflag > 2) ? 1 : 0); if (pimd->ob == ctx->object) { - pimd->ob = NULL; + pimd->ob = nullptr; return mesh; } if (pimd->ob) { - psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1); - if (psys == NULL || psys->totpart == 0) { + psys = static_cast(BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1)); + if (psys == nullptr || psys->totpart == 0) { return mesh; } } @@ -249,7 +250,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * if (pimd->flag & eParticleInstanceFlag_UseSize) { float *si; - si = size = MEM_calloc_arrayN(part_end, sizeof(float), "particle size array"); + si = size = static_cast(MEM_calloc_arrayN(part_end, sizeof(float), __func__)); if (pimd->flag & eParticleInstanceFlag_Parents) { for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++, si++) { @@ -261,7 +262,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * ChildParticle *cpa = psys->child; for (p = 0; p < psys->totchild; p++, cpa++, si++) { - *si = psys_get_child_size(psys, cpa, 0.0f, NULL); + *si = psys_get_child_size(psys, cpa, 0.0f, nullptr); } } } @@ -322,17 +323,17 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * MPoly *mpoly = BKE_mesh_polys_for_write(result); MLoop *mloop = BKE_mesh_loops_for_write(result); - MLoopCol *mloopcols_index = CustomData_get_layer_named_for_write( - &result->ldata, CD_PROP_BYTE_COLOR, pimd->index_layer_name, result->totloop); - MLoopCol *mloopcols_value = CustomData_get_layer_named_for_write( - &result->ldata, CD_PROP_BYTE_COLOR, pimd->value_layer_name, result->totloop); - int *vert_part_index = NULL; - float *vert_part_value = NULL; - if (mloopcols_index != NULL) { - vert_part_index = MEM_calloc_arrayN(maxvert, sizeof(int), "vertex part index array"); + MLoopCol *mloopcols_index = static_cast(CustomData_get_layer_named_for_write( + &result->ldata, CD_PROP_BYTE_COLOR, pimd->index_layer_name, result->totloop)); + MLoopCol *mloopcols_value = static_cast(CustomData_get_layer_named_for_write( + &result->ldata, CD_PROP_BYTE_COLOR, pimd->value_layer_name, result->totloop)); + int *vert_part_index = nullptr; + float *vert_part_value = nullptr; + if (mloopcols_index != nullptr) { + vert_part_index = MEM_cnew_array(maxvert, "vertex part index array"); } if (mloopcols_value) { - vert_part_value = MEM_calloc_arrayN(maxvert, sizeof(float), "vertex part value array"); + vert_part_value = MEM_cnew_array(maxvert, "vertex part value array"); } for (p = part_start, p_skip = 0; p < part_end; p++) { @@ -352,10 +353,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * CustomData_copy_data(&mesh->vdata, &result->vdata, k, vindex, 1); - if (vert_part_index != NULL) { + if (vert_part_index != nullptr) { vert_part_index[vindex] = p; } - if (vert_part_value != NULL) { + if (vert_part_value != nullptr) { vert_part_value[vindex] = p_random; } @@ -495,12 +496,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * ml->v = inML->v + (p_skip * totvert); ml->e = inML->e + (p_skip * totedge); const int ml_index = (ml - mloop); - if (mloopcols_index != NULL) { + if (mloopcols_index != nullptr) { const int part_index = vert_part_index[ml->v]; store_float_in_vcol(&mloopcols_index[ml_index], - (float)part_index / (float)(psys->totpart - 1)); + float(part_index) / float(psys->totpart - 1)); } - if (mloopcols_value != NULL) { + if (mloopcols_value != nullptr) { const float part_value = vert_part_value[ml->v]; store_float_in_vcol(&mloopcols_value[ml_index], part_value); } @@ -522,7 +523,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * return result; } -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *row; uiLayout *layout = panel->layout; @@ -535,7 +536,7 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); - uiItemR(layout, ptr, "object", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "object", 0, nullptr, ICON_NONE); if (!RNA_pointer_is_null(&particle_obj_ptr)) { uiItemPointerR(layout, ptr, @@ -552,14 +553,14 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemS(layout); row = uiLayoutRowWithHeading(layout, true, IFACE_("Create Instances")); - uiItemR(row, ptr, "use_normal", toggles_flag, NULL, ICON_NONE); - uiItemR(row, ptr, "use_children", toggles_flag, NULL, ICON_NONE); - uiItemR(row, ptr, "use_size", toggles_flag, NULL, ICON_NONE); + uiItemR(row, ptr, "use_normal", toggles_flag, nullptr, ICON_NONE); + uiItemR(row, ptr, "use_children", toggles_flag, nullptr, ICON_NONE); + uiItemR(row, ptr, "use_size", toggles_flag, nullptr, ICON_NONE); row = uiLayoutRowWithHeading(layout, true, IFACE_("Show")); - uiItemR(row, ptr, "show_alive", toggles_flag, NULL, ICON_NONE); - uiItemR(row, ptr, "show_dead", toggles_flag, NULL, ICON_NONE); - uiItemR(row, ptr, "show_unborn", toggles_flag, NULL, ICON_NONE); + uiItemR(row, ptr, "show_alive", toggles_flag, nullptr, ICON_NONE); + uiItemR(row, ptr, "show_dead", toggles_flag, nullptr, ICON_NONE); + uiItemR(row, ptr, "show_unborn", toggles_flag, nullptr, ICON_NONE); uiItemR(layout, ptr, "particle_amount", 0, IFACE_("Amount"), ICON_NONE); uiItemR(layout, ptr, "particle_offset", 0, IFACE_("Offset"), ICON_NONE); @@ -568,21 +569,21 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(layout, ptr, "space", 0, IFACE_("Coordinate Space"), ICON_NONE); row = uiLayoutRow(layout, true); - uiItemR(row, ptr, "axis", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemR(row, ptr, "axis", UI_ITEM_R_EXPAND, nullptr, ICON_NONE); modifier_panel_end(layout, ptr); } -static void path_panel_draw_header(const bContext *UNUSED(C), Panel *panel) +static void path_panel_draw_header(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; - PointerRNA *ptr = modifier_panel_get_property_pointers(panel, NULL); + PointerRNA *ptr = modifier_panel_get_property_pointers(panel, nullptr); uiItemR(layout, ptr, "use_path", 0, IFACE_("Create Along Paths"), ICON_NONE); } -static void path_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void path_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col; uiLayout *layout = panel->layout; @@ -595,16 +596,16 @@ static void path_panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetActive(layout, RNA_boolean_get(ptr, "use_path")); col = uiLayoutColumn(layout, true); - uiItemR(col, ptr, "position", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(col, ptr, "position", UI_ITEM_R_SLIDER, nullptr, ICON_NONE); uiItemR(col, ptr, "random_position", UI_ITEM_R_SLIDER, IFACE_("Random"), ICON_NONE); col = uiLayoutColumn(layout, true); - uiItemR(col, ptr, "rotation", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(col, ptr, "rotation", UI_ITEM_R_SLIDER, nullptr, ICON_NONE); uiItemR(col, ptr, "random_rotation", UI_ITEM_R_SLIDER, IFACE_("Random"), ICON_NONE); - uiItemR(layout, ptr, "use_preserve_shape", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "use_preserve_shape", 0, nullptr, ICON_NONE); } -static void layers_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void layers_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col; uiLayout *layout = panel->layout; @@ -629,7 +630,8 @@ static void panelRegister(ARegionType *region_type) region_type, eModifierType_ParticleInstance, panel_draw); modifier_subpanel_register( region_type, "paths", "", path_panel_draw_header, path_panel_draw, panel_type); - modifier_subpanel_register(region_type, "layers", "Layers", NULL, layers_panel_draw, panel_type); + modifier_subpanel_register( + region_type, "layers", "Layers", nullptr, layers_panel_draw, panel_type); } ModifierTypeInfo modifierType_ParticleInstance = { @@ -644,24 +646,24 @@ ModifierTypeInfo modifierType_ParticleInstance = { /*copyData*/ BKE_modifier_copydata_generic, - /*deformVerts*/ NULL, - /*deformMatrices*/ NULL, - /*deformVertsEM*/ NULL, - /*deformMatricesEM*/ NULL, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, /*modifyMesh*/ modifyMesh, - /*modifyGeometrySet*/ NULL, + /*modifyGeometrySet*/ nullptr, /*initData*/ initData, /*requiredDataMask*/ requiredDataMask, - /*freeData*/ NULL, + /*freeData*/ nullptr, /*isDisabled*/ isDisabled, /*updateDepsgraph*/ updateDepsgraph, - /*dependsOnTime*/ NULL, - /*dependsOnNormals*/ NULL, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, /*foreachIDLink*/ foreachIDLink, - /*foreachTexLink*/ NULL, - /*freeRuntimeData*/ NULL, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, /*panelRegister*/ panelRegister, - /*blendWrite*/ NULL, - /*blendRead*/ NULL, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.cc similarity index 70% rename from source/blender/modifiers/intern/MOD_remesh.c rename to source/blender/modifiers/intern/MOD_remesh.cc index 2a322571dbe..d35f4095acf 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.cc @@ -7,10 +7,9 @@ #include "MEM_guardedalloc.h" -#include "BLI_utildefines.h" - #include "BLI_math_base.h" #include "BLI_threads.h" +#include "BLI_utildefines.h" #include "BLT_translation.h" @@ -36,8 +35,8 @@ #include "MOD_modifiertypes.h" #include "MOD_ui_common.h" -#include -#include +#include +#include #ifdef WITH_MOD_REMESH # include "BLI_math_vector.h" @@ -60,14 +59,14 @@ static void init_dualcon_mesh(DualConInput *input, Mesh *mesh) { memset(input, 0, sizeof(DualConInput)); - input->co = (void *)BKE_mesh_vert_positions(mesh); + input->co = (DualConCo)BKE_mesh_vert_positions(mesh); input->co_stride = sizeof(float[3]); input->totco = mesh->totvert; - input->mloop = (void *)BKE_mesh_loops(mesh); + input->mloop = (DualConLoop)BKE_mesh_loops(mesh); input->loop_stride = sizeof(MLoop); - input->looptri = (void *)BKE_mesh_runtime_looptri_ensure(mesh); + input->looptri = (DualConTri)BKE_mesh_runtime_looptri_ensure(mesh); input->tri_stride = sizeof(MLoopTri); input->tottri = BKE_mesh_runtime_looptri_len(mesh); @@ -90,8 +89,8 @@ static void *dualcon_alloc_output(int totvert, int totquad) { DualConOutput *output; - if (!(output = MEM_callocN(sizeof(DualConOutput), "DualConOutput"))) { - return NULL; + if (!(output = MEM_cnew(__func__))) { + return nullptr; } output->mesh = BKE_mesh_new_nomain(totvert, 0, 0, 4 * totquad, totquad); @@ -104,7 +103,7 @@ static void *dualcon_alloc_output(int totvert, int totquad) static void dualcon_add_vert(void *output_v, const float co[3]) { - DualConOutput *output = output_v; + DualConOutput *output = static_cast(output_v); BLI_assert(output->curvert < output->mesh->totvert); @@ -114,7 +113,7 @@ static void dualcon_add_vert(void *output_v, const float co[3]) static void dualcon_add_quad(void *output_v, const int vert_indices[4]) { - DualConOutput *output = output_v; + DualConOutput *output = static_cast(output_v); Mesh *mesh = output->mesh; int i; @@ -133,25 +132,25 @@ static void dualcon_add_quad(void *output_v, const int vert_indices[4]) output->curface++; } -static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh) +static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext * /*ctx*/, Mesh *mesh) { RemeshModifierData *rmd; DualConOutput *output; DualConInput input; Mesh *result; - DualConFlags flags = 0; - DualConMode mode = 0; + DualConFlags flags = DualConFlags(0); + DualConMode mode = DualConMode(0); rmd = (RemeshModifierData *)md; if (rmd->mode == MOD_REMESH_VOXEL) { /* OpenVDB modes. */ if (rmd->voxel_size == 0.0f) { - return NULL; + return nullptr; } result = BKE_mesh_remesh_voxel(mesh, rmd->voxel_size, rmd->adaptivity, 0.0f); - if (result == NULL) { - return NULL; + if (result == nullptr) { + return nullptr; } } else { @@ -159,7 +158,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) init_dualcon_mesh(&input, mesh); if (rmd->flag & MOD_REMESH_FLOOD_FILL) { - flags |= DUALCON_FLOOD_FILL; + flags = DualConFlags(flags | DUALCON_FLOOD_FILL); } switch (rmd->mode) { @@ -182,16 +181,16 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) * This was identified when changing the task isolation's during T76553. */ static ThreadMutex dualcon_mutex = BLI_MUTEX_INITIALIZER; BLI_mutex_lock(&dualcon_mutex); - output = dualcon(&input, - dualcon_alloc_output, - dualcon_add_vert, - dualcon_add_quad, - flags, - mode, - rmd->threshold, - rmd->hermite_num, - rmd->scale, - rmd->depth); + output = static_cast(dualcon(&input, + dualcon_alloc_output, + dualcon_add_vert, + dualcon_add_quad, + flags, + mode, + rmd->threshold, + rmd->hermite_num, + rmd->scale, + rmd->depth)); BLI_mutex_unlock(&dualcon_mutex); result = output->mesh; @@ -215,16 +214,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx) #else /* !WITH_MOD_REMESH */ -static Mesh *modifyMesh(ModifierData *UNUSED(md), - const ModifierEvalContext *UNUSED(ctx), - Mesh *mesh) +static Mesh *modifyMesh(ModifierData * /*md*/, const ModifierEvalContext * /*ctx*/, Mesh *mesh) { return mesh; } #endif /* !WITH_MOD_REMESH */ -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; #ifdef WITH_MOD_REMESH @@ -235,29 +232,29 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) int mode = RNA_enum_get(ptr, "mode"); - uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, NULL, ICON_NONE); + uiItemR(layout, ptr, "mode", UI_ITEM_R_EXPAND, nullptr, ICON_NONE); uiLayoutSetPropSep(layout, true); col = uiLayoutColumn(layout, false); if (mode == MOD_REMESH_VOXEL) { - uiItemR(col, ptr, "voxel_size", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "adaptivity", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "voxel_size", 0, nullptr, ICON_NONE); + uiItemR(col, ptr, "adaptivity", 0, nullptr, ICON_NONE); } else { - uiItemR(col, ptr, "octree_depth", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "scale", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "octree_depth", 0, nullptr, ICON_NONE); + uiItemR(col, ptr, "scale", 0, nullptr, ICON_NONE); if (mode == MOD_REMESH_SHARP_FEATURES) { - uiItemR(col, ptr, "sharpness", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "sharpness", 0, nullptr, ICON_NONE); } - uiItemR(layout, ptr, "use_remove_disconnected", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "use_remove_disconnected", 0, nullptr, ICON_NONE); row = uiLayoutRow(layout, false); uiLayoutSetActive(row, RNA_boolean_get(ptr, "use_remove_disconnected")); - uiItemR(layout, ptr, "threshold", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "threshold", 0, nullptr, ICON_NONE); } - uiItemR(layout, ptr, "use_smooth_shade", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "use_smooth_shade", 0, nullptr, ICON_NONE); modifier_panel_end(layout, ptr); @@ -283,24 +280,24 @@ ModifierTypeInfo modifierType_Remesh = { /*copyData*/ BKE_modifier_copydata_generic, - /*deformVerts*/ NULL, - /*deformMatrices*/ NULL, - /*deformVertsEM*/ NULL, - /*deformMatricesEM*/ NULL, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, /*modifyMesh*/ modifyMesh, - /*modifyGeometrySet*/ NULL, + /*modifyGeometrySet*/ nullptr, /*initData*/ initData, - /*requiredDataMask*/ NULL, - /*freeData*/ NULL, - /*isDisabled*/ NULL, - /*updateDepsgraph*/ NULL, - /*dependsOnTime*/ NULL, - /*dependsOnNormals*/ NULL, - /*foreachIDLink*/ NULL, - /*foreachTexLink*/ NULL, - /*freeRuntimeData*/ NULL, + /*requiredDataMask*/ nullptr, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ nullptr, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, + /*foreachIDLink*/ nullptr, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, /*panelRegister*/ panelRegister, - /*blendWrite*/ NULL, - /*blendRead*/ NULL, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.cc similarity index 77% rename from source/blender/modifiers/intern/MOD_solidify.c rename to source/blender/modifiers/intern/MOD_solidify.cc index b13f36ee47d..4dabb5d4e59 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.cc @@ -5,7 +5,7 @@ * \ingroup modifiers */ -#include +#include #include "BLI_utildefines.h" @@ -29,7 +29,7 @@ #include "MOD_modifiertypes.h" #include "MOD_ui_common.h" -#include "MOD_solidify_util.h" +#include "MOD_solidify_util.hh" static bool dependsOnNormals(ModifierData *md) { @@ -78,7 +78,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * return mesh; } -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *sub, *row, *col; uiLayout *layout = panel->layout; @@ -91,32 +91,32 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); - uiItemR(layout, ptr, "solidify_mode", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "solidify_mode", 0, nullptr, ICON_NONE); if (solidify_mode == MOD_SOLIDIFY_MODE_NONMANIFOLD) { uiItemR(layout, ptr, "nonmanifold_thickness_mode", 0, IFACE_("Thickness Mode"), ICON_NONE); uiItemR(layout, ptr, "nonmanifold_boundary_mode", 0, IFACE_("Boundary"), ICON_NONE); } - uiItemR(layout, ptr, "thickness", 0, NULL, ICON_NONE); - uiItemR(layout, ptr, "offset", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "thickness", 0, nullptr, ICON_NONE); + uiItemR(layout, ptr, "offset", 0, nullptr, ICON_NONE); if (solidify_mode == MOD_SOLIDIFY_MODE_NONMANIFOLD) { - uiItemR(layout, ptr, "nonmanifold_merge_threshold", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "nonmanifold_merge_threshold", 0, nullptr, ICON_NONE); } else { - uiItemR(layout, ptr, "use_even_offset", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "use_even_offset", 0, nullptr, ICON_NONE); } col = uiLayoutColumnWithHeading(layout, false, CTX_IFACE_(BLT_I18NCONTEXT_ID_MESH, "Rim")); uiItemR(col, ptr, "use_rim", 0, IFACE_("Fill"), ICON_NONE); sub = uiLayoutColumn(col, false); uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_rim")); - uiItemR(sub, ptr, "use_rim_only", 0, NULL, ICON_NONE); + uiItemR(sub, ptr, "use_rim_only", 0, nullptr, ICON_NONE); uiItemS(layout); - modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL); + modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr); row = uiLayoutRow(layout, false); uiLayoutSetActive(row, has_vertex_group); uiItemR(row, ptr, "thickness_vertex_group", 0, IFACE_("Factor"), ICON_NONE); @@ -124,13 +124,13 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) if (solidify_mode == MOD_SOLIDIFY_MODE_NONMANIFOLD) { row = uiLayoutRow(layout, false); uiLayoutSetActive(row, has_vertex_group); - uiItemR(row, ptr, "use_flat_faces", 0, NULL, ICON_NONE); + uiItemR(row, ptr, "use_flat_faces", 0, nullptr, ICON_NONE); } modifier_panel_end(layout, ptr); } -static void normals_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void normals_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col; uiLayout *layout = panel->layout; @@ -149,7 +149,7 @@ static void normals_panel_draw(const bContext *UNUSED(C), Panel *panel) } } -static void materials_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void materials_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col; uiLayout *layout = panel->layout; @@ -159,14 +159,14 @@ static void materials_panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); - uiItemR(layout, ptr, "material_offset", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "material_offset", 0, nullptr, ICON_NONE); col = uiLayoutColumn(layout, true); uiLayoutSetActive(col, RNA_boolean_get(ptr, "use_rim")); uiItemR( col, ptr, "material_offset_rim", 0, CTX_IFACE_(BLT_I18NCONTEXT_ID_MESH, "Rim"), ICON_NONE); } -static void edge_data_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void edge_data_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *layout = panel->layout; @@ -184,10 +184,10 @@ static void edge_data_panel_draw(const bContext *UNUSED(C), Panel *panel) uiItemR(col, ptr, "edge_crease_outer", 0, IFACE_("Outer"), ICON_NONE); uiItemR(col, ptr, "edge_crease_rim", 0, CTX_IFACE_(BLT_I18NCONTEXT_ID_MESH, "Rim"), ICON_NONE); } - uiItemR(layout, ptr, "bevel_convex", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(layout, ptr, "bevel_convex", UI_ITEM_R_SLIDER, nullptr, ICON_NONE); } -static void clamp_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void clamp_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *row, *col; uiLayout *layout = panel->layout; @@ -198,13 +198,13 @@ static void clamp_panel_draw(const bContext *UNUSED(C), Panel *panel) uiLayoutSetPropSep(layout, true); col = uiLayoutColumn(layout, false); - uiItemR(col, ptr, "thickness_clamp", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "thickness_clamp", 0, nullptr, ICON_NONE); row = uiLayoutRow(col, false); uiLayoutSetActive(row, RNA_float_get(ptr, "thickness_clamp") > 0.0f); - uiItemR(row, ptr, "use_thickness_angle_clamp", 0, NULL, ICON_NONE); + uiItemR(row, ptr, "use_thickness_angle_clamp", 0, nullptr, ICON_NONE); } -static void vertex_group_panel_draw(const bContext *UNUSED(C), Panel *panel) +static void vertex_group_panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col; uiLayout *layout = panel->layout; @@ -230,17 +230,17 @@ static void panelRegister(ARegionType *region_type) { PanelType *panel_type = modifier_panel_register(region_type, eModifierType_Solidify, panel_draw); modifier_subpanel_register( - region_type, "normals", "Normals", NULL, normals_panel_draw, panel_type); + region_type, "normals", "Normals", nullptr, normals_panel_draw, panel_type); modifier_subpanel_register( - region_type, "materials", "Materials", NULL, materials_panel_draw, panel_type); + region_type, "materials", "Materials", nullptr, materials_panel_draw, panel_type); modifier_subpanel_register( - region_type, "edge_data", "Edge Data", NULL, edge_data_panel_draw, panel_type); + region_type, "edge_data", "Edge Data", nullptr, edge_data_panel_draw, panel_type); modifier_subpanel_register( - region_type, "clamp", "Thickness Clamp", NULL, clamp_panel_draw, panel_type); + region_type, "clamp", "Thickness Clamp", nullptr, clamp_panel_draw, panel_type); modifier_subpanel_register(region_type, "vertex_groups", "Output Vertex Groups", - NULL, + nullptr, vertex_group_panel_draw, panel_type); } @@ -259,24 +259,24 @@ ModifierTypeInfo modifierType_Solidify = { /*copyData*/ BKE_modifier_copydata_generic, - /*deformVerts*/ NULL, - /*deformMatrices*/ NULL, - /*deformVertsEM*/ NULL, - /*deformMatricesEM*/ NULL, + /*deformVerts*/ nullptr, + /*deformMatrices*/ nullptr, + /*deformVertsEM*/ nullptr, + /*deformMatricesEM*/ nullptr, /*modifyMesh*/ modifyMesh, - /*modifyGeometrySet*/ NULL, + /*modifyGeometrySet*/ nullptr, /*initData*/ initData, /*requiredDataMask*/ requiredDataMask, - /*freeData*/ NULL, - /*isDisabled*/ NULL, - /*updateDepsgraph*/ NULL, - /*dependsOnTime*/ NULL, + /*freeData*/ nullptr, + /*isDisabled*/ nullptr, + /*updateDepsgraph*/ nullptr, + /*dependsOnTime*/ nullptr, /*dependsOnNormals*/ dependsOnNormals, - /*foreachIDLink*/ NULL, - /*foreachTexLink*/ NULL, - /*freeRuntimeData*/ NULL, + /*foreachIDLink*/ nullptr, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, /*panelRegister*/ panelRegister, - /*blendWrite*/ NULL, - /*blendRead*/ NULL, + /*blendWrite*/ nullptr, + /*blendRead*/ nullptr, }; diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.c b/source/blender/modifiers/intern/MOD_solidify_extrude.cc similarity index 86% rename from source/blender/modifiers/intern/MOD_solidify_extrude.c rename to source/blender/modifiers/intern/MOD_solidify_extrude.cc index 0e3368577d4..48cdbc89f38 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.c +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.cc @@ -21,7 +21,7 @@ #include "BKE_particle.h" #include "MOD_modifiertypes.h" -#include "MOD_solidify_util.h" /* own include */ +#include "MOD_solidify_util.hh" /* own include */ #include "MOD_util.h" #ifdef __GNUC__ @@ -38,10 +38,10 @@ /* *** derived mesh high quality normal calculation function *** */ /* could be exposed for other functions to use */ -typedef struct EdgeFaceRef { +struct EdgeFaceRef { int p1; /* init as -1 */ int p2; -} EdgeFaceRef; +}; BLI_INLINE bool edgeref_is_init(const EdgeFaceRef *edge_ref) { @@ -73,8 +73,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, const MPoly *mp = mpoly; { - EdgeFaceRef *edge_ref_array = MEM_calloc_arrayN( - (size_t)edges_num, sizeof(EdgeFaceRef), "Edge Connectivity"); + EdgeFaceRef *edge_ref_array = MEM_cnew_array((size_t)edges_num, __func__); EdgeFaceRef *edge_ref; float edge_normal[3]; @@ -156,10 +155,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex Mesh *result; const SolidifyModifierData *smd = (SolidifyModifierData *)md; - const uint verts_num = (uint)mesh->totvert; - const uint edges_num = (uint)mesh->totedge; - const uint polys_num = (uint)mesh->totpoly; - const uint loops_num = (uint)mesh->totloop; + const uint verts_num = uint(mesh->totvert); + const uint edges_num = uint(mesh->totedge); + const uint polys_num = uint(mesh->totpoly); + const uint loops_num = uint(mesh->totloop); uint newLoops = 0, newPolys = 0, newEdges = 0, newVerts = 0, rimVerts = 0; /* Only use material offsets if we have 2 or more materials. */ @@ -169,20 +168,19 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex /* use for edges */ /* over-alloc new_vert_arr, old_vert_arr */ - uint *new_vert_arr = NULL; + uint *new_vert_arr = nullptr; STACK_DECLARE(new_vert_arr); - uint *new_edge_arr = NULL; + uint *new_edge_arr = nullptr; STACK_DECLARE(new_edge_arr); - uint *old_vert_arr = MEM_calloc_arrayN( - verts_num, sizeof(*old_vert_arr), "old_vert_arr in solidify"); + uint *old_vert_arr = MEM_cnew_array(verts_num, "old_vert_arr in solidify"); - uint *edge_users = NULL; - int *edge_order = NULL; + uint *edge_users = nullptr; + int *edge_order = nullptr; - float(*vert_nors)[3] = NULL; - const float(*poly_nors)[3] = NULL; + float(*vert_nors)[3] = nullptr; + const float(*poly_nors)[3] = nullptr; const bool need_poly_normals = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) || (smd->flag & MOD_SOLIDIFY_EVEN) || @@ -236,12 +234,13 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex #define INVALID_UNUSED ((uint)-1) #define INVALID_PAIR ((uint)-2) - new_vert_arr = MEM_malloc_arrayN(verts_num, 2 * sizeof(*new_vert_arr), __func__); - new_edge_arr = MEM_malloc_arrayN( - ((edges_num * 2) + verts_num), sizeof(*new_edge_arr), __func__); + new_vert_arr = static_cast( + MEM_malloc_arrayN(verts_num, 2 * sizeof(*new_vert_arr), __func__)); + new_edge_arr = static_cast( + MEM_malloc_arrayN(((edges_num * 2) + verts_num), sizeof(*new_edge_arr), __func__)); - edge_users = MEM_malloc_arrayN(edges_num, sizeof(*edge_users), "solid_mod edges"); - edge_order = MEM_malloc_arrayN(edges_num, sizeof(*edge_order), "solid_mod order"); + edge_users = static_cast(MEM_malloc_arrayN(edges_num, sizeof(*edge_users), __func__)); + edge_order = static_cast(MEM_malloc_arrayN(edges_num, sizeof(*edge_order), __func__)); /* save doing 2 loops here... */ #if 0 @@ -317,7 +316,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex #endif if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) { - vert_nors = MEM_calloc_arrayN(verts_num, sizeof(float[3]), "mod_solid_vno_hq"); + vert_nors = static_cast(MEM_calloc_arrayN(verts_num, sizeof(float[3]), __func__)); mesh_calc_hq_normal(mesh, poly_nors, vert_nors @@ -329,11 +328,11 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } result = BKE_mesh_new_nomain_from_template(mesh, - (int)((verts_num * stride) + newVerts), - (int)((edges_num * stride) + newEdges + rimVerts), + int((verts_num * stride) + newVerts), + int((edges_num * stride) + newEdges + rimVerts), 0, - (int)((loops_num * stride) + newLoops), - (int)((polys_num * stride) + newPolys)); + int((loops_num * stride) + newLoops), + int((polys_num * stride) + newPolys)); float(*vert_positions)[3] = BKE_mesh_vert_positions_for_write(result); MEdge *medge = BKE_mesh_edges_for_write(result); @@ -341,35 +340,35 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex MLoop *mloop = BKE_mesh_loops_for_write(result); if (do_shell) { - CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)verts_num); - CustomData_copy_data(&mesh->vdata, &result->vdata, 0, (int)verts_num, (int)verts_num); + CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, int(verts_num)); + CustomData_copy_data(&mesh->vdata, &result->vdata, 0, int(verts_num), int(verts_num)); - CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)edges_num); - CustomData_copy_data(&mesh->edata, &result->edata, 0, (int)edges_num, (int)edges_num); + CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, int(edges_num)); + CustomData_copy_data(&mesh->edata, &result->edata, 0, int(edges_num), int(edges_num)); - CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)loops_num); + CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, int(loops_num)); /* DO NOT copy here the 'copied' part of loop data, we want to reverse loops * (so that winding of copied face get reversed, so that normals get reversed * and point in expected direction...). * If we also copy data here, then this data get overwritten * (and allocated memory becomes a memory leak). */ - CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)polys_num); - CustomData_copy_data(&mesh->pdata, &result->pdata, 0, (int)polys_num, (int)polys_num); + CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, int(polys_num)); + CustomData_copy_data(&mesh->pdata, &result->pdata, 0, int(polys_num), int(polys_num)); } else { int i, j; - CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, (int)verts_num); - for (i = 0, j = (int)verts_num; i < verts_num; i++) { + CustomData_copy_data(&mesh->vdata, &result->vdata, 0, 0, int(verts_num)); + for (i = 0, j = int(verts_num); i < verts_num; i++) { if (old_vert_arr[i] != INVALID_UNUSED) { CustomData_copy_data(&mesh->vdata, &result->vdata, i, j, 1); j++; } } - CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, (int)edges_num); + CustomData_copy_data(&mesh->edata, &result->edata, 0, 0, int(edges_num)); - for (i = 0, j = (int)edges_num; i < edges_num; i++) { + for (i = 0, j = int(edges_num); i < edges_num; i++) { if (!ELEM(edge_users[i], INVALID_UNUSED, INVALID_PAIR)) { MEdge *ed_src, *ed_dst; CustomData_copy_data(&mesh->edata, &result->edata, i, j, 1); @@ -383,14 +382,14 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } /* will be created later */ - CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, (int)loops_num); - CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, (int)polys_num); + CustomData_copy_data(&mesh->ldata, &result->ldata, 0, 0, int(loops_num)); + CustomData_copy_data(&mesh->pdata, &result->pdata, 0, 0, int(polys_num)); } - float *result_edge_bweight = NULL; + float *result_edge_bweight = nullptr; if (do_bevel_convex) { - result_edge_bweight = CustomData_add_layer( - &result->edata, CD_BWEIGHT, CD_SET_DEFAULT, NULL, result->totedge); + result_edge_bweight = static_cast(CustomData_add_layer( + &result->edata, CD_BWEIGHT, CD_SET_DEFAULT, nullptr, result->totedge)); } /* initializes: (i_end, do_shell_align, mv). */ @@ -483,17 +482,17 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex float ofs_new_vgroup; /* for clamping */ - float *vert_lens = NULL; - float *vert_angs = NULL; + float *vert_lens = nullptr; + float *vert_angs = nullptr; const float offset = fabsf(smd->offset) * smd->offset_clamp; const float offset_sq = offset * offset; /* for bevel weight */ - float *edge_angs = NULL; + float *edge_angs = nullptr; if (do_clamp) { - vert_lens = MEM_malloc_arrayN(verts_num, sizeof(float), "vert_lens"); - copy_vn_fl(vert_lens, (int)verts_num, FLT_MAX); + vert_lens = static_cast(MEM_malloc_arrayN(verts_num, sizeof(float), "vert_lens")); + copy_vn_fl(vert_lens, int(verts_num), FLT_MAX); for (uint i = 0; i < edges_num; i++) { const float ed_len_sq = len_squared_v3v3(vert_positions[medge[i].v1], vert_positions[medge[i].v2]); @@ -505,17 +504,18 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex if (do_angle_clamp || do_bevel_convex) { uint eidx; if (do_angle_clamp) { - vert_angs = MEM_malloc_arrayN(verts_num, sizeof(float), "vert_angs"); - copy_vn_fl(vert_angs, (int)verts_num, 0.5f * M_PI); + vert_angs = static_cast(MEM_malloc_arrayN(verts_num, sizeof(float), "vert_angs")); + copy_vn_fl(vert_angs, int(verts_num), 0.5f * M_PI); } if (do_bevel_convex) { - edge_angs = MEM_malloc_arrayN(edges_num, sizeof(float), "edge_angs"); + edge_angs = static_cast(MEM_malloc_arrayN(edges_num, sizeof(float), "edge_angs")); if (!do_rim) { - edge_users = MEM_malloc_arrayN(edges_num, sizeof(*edge_users), "solid_mod edges"); + edge_users = static_cast( + MEM_malloc_arrayN(edges_num, sizeof(*edge_users), "solid_mod edges")); } } - uint(*edge_user_pairs)[2] = MEM_malloc_arrayN( - edges_num, sizeof(*edge_user_pairs), "edge_user_pairs"); + uint(*edge_user_pairs)[2] = static_cast( + MEM_malloc_arrayN(edges_num, sizeof(*edge_user_pairs), "edge_user_pairs")); for (eidx = 0; eidx < edges_num; eidx++) { edge_user_pairs[eidx][0] = INVALID_UNUSED; edge_user_pairs[eidx][1] = INVALID_UNUSED; @@ -589,7 +589,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } if (do_clamp && offset > FLT_EPSILON) { /* always reset because we may have set before */ - if (dvert == NULL) { + if (dvert == nullptr) { ofs_new_vgroup = ofs_new; } if (do_angle_clamp) { @@ -641,7 +641,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } if (do_clamp && offset > FLT_EPSILON) { /* always reset because we may have set before */ - if (dvert == NULL) { + if (dvert == nullptr) { ofs_new_vgroup = ofs_orig; } if (do_angle_clamp) { @@ -706,14 +706,15 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex const bool check_non_manifold = (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) != 0; #endif /* same as EM_solidify() in editmesh_lib.c */ - float *vert_angles = MEM_calloc_arrayN( - verts_num, sizeof(float[2]), "mod_solid_pair"); /* 2 in 1 */ + float *vert_angles = static_cast( + MEM_calloc_arrayN(verts_num, sizeof(float[2]), "mod_solid_pair")); /* 2 in 1 */ float *vert_accum = vert_angles + verts_num; uint vidx; uint i; - if (vert_nors == NULL) { - vert_nors = MEM_malloc_arrayN(verts_num, sizeof(float[3]), "mod_solid_vno"); + if (vert_nors == nullptr) { + vert_nors = static_cast( + MEM_malloc_arrayN(verts_num, sizeof(float[3]), "mod_solid_vno")); for (i = 0; i < verts_num; i++) { copy_v3_v3(vert_nors[i], mesh_vert_normals[i]); } @@ -792,24 +793,27 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex } /* for angle clamp */ - float *vert_angs = NULL; + float *vert_angs = nullptr; /* for bevel convex */ - float *edge_angs = NULL; + float *edge_angs = nullptr; if (do_angle_clamp || do_bevel_convex) { uint eidx; if (do_angle_clamp) { - vert_angs = MEM_malloc_arrayN(verts_num, sizeof(float), "vert_angs even"); - copy_vn_fl(vert_angs, (int)verts_num, 0.5f * M_PI); + vert_angs = static_cast( + MEM_malloc_arrayN(verts_num, sizeof(float), "vert_angs even")); + copy_vn_fl(vert_angs, int(verts_num), 0.5f * M_PI); } if (do_bevel_convex) { - edge_angs = MEM_malloc_arrayN(edges_num, sizeof(float), "edge_angs even"); + edge_angs = static_cast( + MEM_malloc_arrayN(edges_num, sizeof(float), "edge_angs even")); if (!do_rim) { - edge_users = MEM_malloc_arrayN(edges_num, sizeof(*edge_users), "solid_mod edges"); + edge_users = static_cast( + MEM_malloc_arrayN(edges_num, sizeof(*edge_users), "solid_mod edges")); } } - uint(*edge_user_pairs)[2] = MEM_malloc_arrayN( - edges_num, sizeof(*edge_user_pairs), "edge_user_pairs"); + uint(*edge_user_pairs)[2] = static_cast( + MEM_malloc_arrayN(edges_num, sizeof(*edge_user_pairs), "edge_user_pairs")); for (eidx = 0; eidx < edges_num; eidx++) { edge_user_pairs[eidx][0] = INVALID_UNUSED; edge_user_pairs[eidx][1] = INVALID_UNUSED; @@ -863,9 +867,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex const float clamp_fac = 1 + (do_angle_clamp ? fabsf(smd->offset_fac) : 0); const float offset = fabsf(smd->offset) * smd->offset_clamp * clamp_fac; if (offset > FLT_EPSILON) { - float *vert_lens_sq = MEM_malloc_arrayN(verts_num, sizeof(float), "vert_lens_sq"); + float *vert_lens_sq = static_cast( + MEM_malloc_arrayN(verts_num, sizeof(float), "vert_lens_sq")); const float offset_sq = offset * offset; - copy_vn_fl(vert_lens_sq, (int)verts_num, FLT_MAX); + copy_vn_fl(vert_lens_sq, int(verts_num), FLT_MAX); for (i = 0; i < edges_num; i++) { const float ed_len = len_squared_v3v3(vert_positions[medge[i].v1], vert_positions[medge[i].v2]); @@ -986,7 +991,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex MDeformVert *dst_dvert = BKE_mesh_deform_verts_for_write(result); /* Ultimate security check. */ - if (dst_dvert != NULL) { + if (dst_dvert != nullptr) { if (rim_defgrp_index != -1) { for (uint i = 0; i < rimVerts; i++) { @@ -1022,9 +1027,9 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex * do_side_normals is always false. */ const bool do_side_normals = !BKE_mesh_vertex_normals_are_dirty(result); /* annoying to allocate these since we only need the edge verts, */ - float(*edge_vert_nos)[3] = do_side_normals ? - MEM_calloc_arrayN(verts_num, sizeof(float[3]), __func__) : - NULL; + float(*edge_vert_nos)[3] = do_side_normals ? static_cast(MEM_calloc_arrayN( + verts_num, sizeof(float[3]), __func__)) : + nullptr; float nor[3]; #endif const float crease_rim = smd->crease_rim; @@ -1035,15 +1040,16 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex int *orig_ed; uint j; - float *result_edge_crease = NULL; + float *result_edge_crease = nullptr; if (crease_rim || crease_outer || crease_inner) { result_edge_crease = (float *)CustomData_add_layer( - &result->edata, CD_CREASE, CD_SET_DEFAULT, NULL, result->totedge); + &result->edata, CD_CREASE, CD_SET_DEFAULT, nullptr, result->totedge); } /* add faces & edges */ - origindex_edge = CustomData_get_layer_for_write(&result->edata, CD_ORIGINDEX, result->totedge); - orig_ed = (origindex_edge) ? &origindex_edge[(edges_num * stride) + newEdges] : NULL; + origindex_edge = static_cast( + CustomData_get_layer_for_write(&result->edata, CD_ORIGINDEX, result->totedge)); + orig_ed = (origindex_edge) ? &origindex_edge[(edges_num * stride) + newEdges] : nullptr; MEdge *ed = &medge[(edges_num * stride) + newEdges]; /* start after copied edges */ for (i = 0; i < rimVerts; i++, ed++) { ed->v1 = new_vert_arr[i]; @@ -1082,8 +1088,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex /* copy most of the face settings */ CustomData_copy_data( - &mesh->pdata, &result->pdata, (int)pidx, (int)((polys_num * stride) + i), 1); - mp->loopstart = (int)(j + (loops_num * stride)); + &mesh->pdata, &result->pdata, int(pidx), int((polys_num * stride) + i), 1); + mp->loopstart = int(j + (loops_num * stride)); mp->flag = mpoly[pidx].flag; /* notice we use 'mp->totloop' which is later overwritten, @@ -1097,14 +1103,10 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex mp->totloop = 4; - CustomData_copy_data( - &mesh->ldata, &result->ldata, k2, (int)((loops_num * stride) + j + 0), 1); - CustomData_copy_data( - &mesh->ldata, &result->ldata, k1, (int)((loops_num * stride) + j + 1), 1); - CustomData_copy_data( - &mesh->ldata, &result->ldata, k1, (int)((loops_num * stride) + j + 2), 1); - CustomData_copy_data( - &mesh->ldata, &result->ldata, k2, (int)((loops_num * stride) + j + 3), 1); + CustomData_copy_data(&mesh->ldata, &result->ldata, k2, int((loops_num * stride) + j + 0), 1); + CustomData_copy_data(&mesh->ldata, &result->ldata, k1, int((loops_num * stride) + j + 1), 1); + CustomData_copy_data(&mesh->ldata, &result->ldata, k1, int((loops_num * stride) + j + 2), 1); + CustomData_copy_data(&mesh->ldata, &result->ldata, k2, int((loops_num * stride) + j + 3), 1); if (flip == false) { ml[j].v = ed->v1; diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc similarity index 84% rename from source/blender/modifiers/intern/MOD_solidify_nonmanifold.c rename to source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc index d364e92174e..2b07998932b 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.c +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc @@ -19,7 +19,7 @@ #include "BKE_particle.h" #include "MOD_modifiertypes.h" -#include "MOD_solidify_util.h" /* Own include. */ +#include "MOD_solidify_util.hh" /* Own include. */ #include "MOD_util.h" #ifdef __GNUC__ @@ -75,34 +75,36 @@ static float clamp_nonzero(const float value, const float epsilon) /* Data structures for manifold solidify. */ -typedef struct NewFaceRef { +struct NewEdgeRef; + +struct NewFaceRef { const MPoly *face; uint index; bool reversed; - struct NewEdgeRef **link_edges; -} NewFaceRef; + NewEdgeRef **link_edges; +}; -typedef struct OldEdgeFaceRef { +struct OldEdgeFaceRef { uint *faces; uint faces_len; bool *faces_reversed; uint used; -} OldEdgeFaceRef; +}; -typedef struct OldVertEdgeRef { +struct OldVertEdgeRef { uint *edges; uint edges_len; -} OldVertEdgeRef; +}; -typedef struct NewEdgeRef { +struct NewEdgeRef { uint old_edge; NewFaceRef *faces[2]; struct EdgeGroup *link_edge_groups[2]; float angle; uint new_edge; -} NewEdgeRef; +}; -typedef struct EdgeGroup { +struct EdgeGroup { bool valid; NewEdgeRef **edges; uint edges_len; @@ -115,18 +117,18 @@ typedef struct EdgeGroup { float co[3]; float no[3]; uint new_vert; -} EdgeGroup; +}; -typedef struct FaceKeyPair { +struct FaceKeyPair { float angle; NewFaceRef *face; -} FaceKeyPair; +}; static int comp_float_int_pair(const void *a, const void *b) { FaceKeyPair *x = (FaceKeyPair *)a; FaceKeyPair *y = (FaceKeyPair *)b; - return (int)(x->angle > y->angle) - (int)(x->angle < y->angle); + return int(x->angle > y->angle) - int(x->angle < y->angle); } /* NOLINTNEXTLINE: readability-function-size */ @@ -137,9 +139,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, Mesh *result; const SolidifyModifierData *smd = (SolidifyModifierData *)md; - const uint verts_num = (uint)mesh->totvert; - const uint edges_num = (uint)mesh->totedge; - const uint polys_num = (uint)mesh->totpoly; + const uint verts_num = uint(mesh->totvert); + const uint edges_num = uint(mesh->totedge); + const uint polys_num = uint(mesh->totpoly); if (polys_num == 0 && verts_num != 0) { return mesh; @@ -190,9 +192,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const MLoop *orig_mloop = BKE_mesh_loops(mesh); /* These might be null. */ - const float *orig_vert_bweight = CustomData_get_layer(&mesh->vdata, CD_BWEIGHT); - const float *orig_edge_bweight = CustomData_get_layer(&mesh->edata, CD_BWEIGHT); - const float *orig_edge_crease = CustomData_get_layer(&mesh->edata, CD_CREASE); + const float *orig_vert_bweight = static_cast( + CustomData_get_layer(&mesh->vdata, CD_BWEIGHT)); + const float *orig_edge_bweight = static_cast( + CustomData_get_layer(&mesh->edata, CD_BWEIGHT)); + const float *orig_edge_crease = static_cast( + CustomData_get_layer(&mesh->edata, CD_CREASE)); uint new_verts_num = 0; uint new_edges_num = 0; @@ -202,15 +207,16 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, #define MOD_SOLIDIFY_EMPTY_TAG ((uint)-1) /* Calculate only face normals. Copied because they are modified directly below. */ - float(*poly_nors)[3] = MEM_malloc_arrayN(polys_num, sizeof(float[3]), __func__); + float(*poly_nors)[3] = static_cast( + MEM_malloc_arrayN(polys_num, sizeof(float[3]), __func__)); memcpy(poly_nors, BKE_mesh_poly_normals_ensure(mesh), sizeof(float[3]) * polys_num); - NewFaceRef *face_sides_arr = MEM_malloc_arrayN( - polys_num * 2, sizeof(*face_sides_arr), "face_sides_arr in solidify"); + NewFaceRef *face_sides_arr = static_cast( + MEM_malloc_arrayN(polys_num * 2, sizeof(*face_sides_arr), __func__)); bool *null_faces = (smd->nonmanifold_offset_mode == MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS) ? - MEM_calloc_arrayN(polys_num, sizeof(*null_faces), "null_faces in solidify") : - NULL; + static_cast(MEM_calloc_arrayN(polys_num, sizeof(*null_faces), __func__)) : + nullptr; uint largest_ngon = 3; /* Calculate face to #NewFaceRef map. */ { @@ -232,27 +238,39 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } } - NewEdgeRef **link_edges = MEM_calloc_arrayN( - (uint)mp->totloop, sizeof(*link_edges), "NewFaceRef::link_edges in solidify"); - face_sides_arr[i * 2] = (NewFaceRef){ - .face = mp, .index = i, .reversed = false, .link_edges = link_edges}; - link_edges = MEM_calloc_arrayN( - (uint)mp->totloop, sizeof(*link_edges), "NewFaceRef::link_edges in solidify"); - face_sides_arr[i * 2 + 1] = (NewFaceRef){ - .face = mp, .index = i, .reversed = true, .link_edges = link_edges}; + NewEdgeRef **link_edges = static_cast( + MEM_calloc_arrayN(uint(mp->totloop), sizeof(*link_edges), __func__)); + + NewFaceRef new_face_ref_a{}; + new_face_ref_a.face = mp; + new_face_ref_a.index = i; + new_face_ref_a.reversed = false; + new_face_ref_a.link_edges = link_edges; + face_sides_arr[i * 2] = new_face_ref_a; + + link_edges = static_cast( + MEM_calloc_arrayN(uint(mp->totloop), sizeof(*link_edges), __func__)); + + NewFaceRef new_face_ref_b{}; + new_face_ref_b.face = mp; + new_face_ref_b.index = i; + new_face_ref_b.reversed = true; + new_face_ref_b.link_edges = link_edges; + face_sides_arr[i * 2 + 1] = new_face_ref_b; + if (mp->totloop > largest_ngon) { - largest_ngon = (uint)mp->totloop; + largest_ngon = uint(mp->totloop); } /* add to final mesh face count */ if (do_shell) { new_polys_num += 2; - new_loops_num += (uint)mp->totloop * 2; + new_loops_num += uint(mp->totloop * 2); } } } - uint *edge_adj_faces_len = MEM_calloc_arrayN( - edges_num, sizeof(*edge_adj_faces_len), "edge_adj_faces_len in solidify"); + uint *edge_adj_faces_len = static_cast( + MEM_calloc_arrayN(edges_num, sizeof(*edge_adj_faces_len), __func__)); /* Count for each edge how many faces it has adjacent. */ { const MPoly *mp = orig_mpoly; @@ -265,16 +283,16 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } /* Original edge to #NewEdgeRef map. */ - NewEdgeRef ***orig_edge_data_arr = MEM_calloc_arrayN( - edges_num, sizeof(*orig_edge_data_arr), "orig_edge_data_arr in solidify"); + NewEdgeRef ***orig_edge_data_arr = static_cast( + MEM_calloc_arrayN(edges_num, sizeof(*orig_edge_data_arr), __func__)); /* Original edge length cache. */ - float *orig_edge_lengths = MEM_calloc_arrayN( - edges_num, sizeof(*orig_edge_lengths), "orig_edge_lengths in solidify"); + float *orig_edge_lengths = static_cast( + MEM_calloc_arrayN(edges_num, sizeof(*orig_edge_lengths), __func__)); /* Edge groups for every original vert. */ - EdgeGroup **orig_vert_groups_arr = MEM_calloc_arrayN( - verts_num, sizeof(*orig_vert_groups_arr), "orig_vert_groups_arr in solidify"); + EdgeGroup **orig_vert_groups_arr = static_cast( + MEM_calloc_arrayN(verts_num, sizeof(*orig_vert_groups_arr), __func__)); /* vertex map used to map duplicates. */ - uint *vm = MEM_malloc_arrayN(verts_num, sizeof(*vm), "orig_vert_map in solidify"); + uint *vm = static_cast(MEM_malloc_arrayN(verts_num, sizeof(*vm), __func__)); for (uint i = 0; i < verts_num; i++) { vm[i] = i; } @@ -286,11 +304,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, bool has_singularities = false; /* Vert edge adjacent map. */ - OldVertEdgeRef **vert_adj_edges = MEM_calloc_arrayN( - verts_num, sizeof(*vert_adj_edges), "vert_adj_edges in solidify"); + OldVertEdgeRef **vert_adj_edges = static_cast( + MEM_calloc_arrayN(verts_num, sizeof(*vert_adj_edges), __func__)); /* Original vertex positions (changed for degenerated geometry). */ - float(*orig_mvert_co)[3] = MEM_malloc_arrayN( - verts_num, sizeof(*orig_mvert_co), "orig_mvert_co in solidify"); + float(*orig_mvert_co)[3] = static_cast( + MEM_malloc_arrayN(verts_num, sizeof(*orig_mvert_co), __func__)); /* Fill in the original vertex positions. */ for (uint i = 0; i < verts_num; i++) { orig_mvert_co[i][0] = orig_vert_positions[i][0]; @@ -300,8 +318,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Create edge to #NewEdgeRef map. */ { - OldEdgeFaceRef **edge_adj_faces = MEM_calloc_arrayN( - edges_num, sizeof(*edge_adj_faces), "edge_adj_faces in solidify"); + OldEdgeFaceRef **edge_adj_faces = static_cast( + MEM_calloc_arrayN(edges_num, sizeof(*edge_adj_faces), __func__)); /* Create link_faces for edges. */ { @@ -312,20 +330,21 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const uint edge = ml->e; const bool reversed = orig_medge[edge].v2 != ml->v; OldEdgeFaceRef *old_face_edge_ref = edge_adj_faces[edge]; - if (old_face_edge_ref == NULL) { + if (old_face_edge_ref == nullptr) { const uint len = edge_adj_faces_len[edge]; BLI_assert(len > 0); - uint *adj_faces = MEM_malloc_arrayN( - len, sizeof(*adj_faces), "OldEdgeFaceRef::faces in solidify"); - bool *adj_faces_reversed = MEM_malloc_arrayN( - len, sizeof(*adj_faces_reversed), "OldEdgeFaceRef::reversed in solidify"); + uint *adj_faces = static_cast( + MEM_malloc_arrayN(len, sizeof(*adj_faces), __func__)); + bool *adj_faces_reversed = static_cast( + MEM_malloc_arrayN(len, sizeof(*adj_faces_reversed), __func__)); adj_faces[0] = i; for (uint k = 1; k < len; k++) { adj_faces[k] = MOD_SOLIDIFY_EMPTY_TAG; } adj_faces_reversed[0] = reversed; - OldEdgeFaceRef *ref = MEM_mallocN(sizeof(*ref), "OldEdgeFaceRef in solidify"); - *ref = (OldEdgeFaceRef){adj_faces, len, adj_faces_reversed, 1}; + OldEdgeFaceRef *ref = static_cast( + MEM_mallocN(sizeof(*ref), __func__)); + *ref = OldEdgeFaceRef{adj_faces, len, adj_faces_reversed, 1}; edge_adj_faces[edge] = ref; } else { @@ -342,17 +361,17 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } float edgedir[3] = {0, 0, 0}; - uint *vert_adj_edges_len = MEM_calloc_arrayN( - verts_num, sizeof(*vert_adj_edges_len), "vert_adj_edges_len in solidify"); + uint *vert_adj_edges_len = static_cast( + MEM_calloc_arrayN(verts_num, sizeof(*vert_adj_edges_len), __func__)); /* Calculate edge lengths and len vert_adj edges. */ { - bool *face_singularity = MEM_calloc_arrayN( - polys_num, sizeof(*face_singularity), "face_sides_arr in solidify"); + bool *face_singularity = static_cast( + MEM_calloc_arrayN(polys_num, sizeof(*face_singularity), __func__)); const float merge_tolerance_sqr = smd->merge_tolerance * smd->merge_tolerance; - uint *combined_verts = MEM_calloc_arrayN( - verts_num, sizeof(*combined_verts), "combined_verts in solidify"); + uint *combined_verts = static_cast( + MEM_calloc_arrayN(verts_num, sizeof(*combined_verts), __func__)); const MEdge *ed = orig_medge; for (uint i = 0; i < edges_num; i++, ed++) { @@ -420,7 +439,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, MEM_freeN(edge_adj_faces[i]->faces); MEM_freeN(edge_adj_faces[i]->faces_reversed); MEM_freeN(edge_adj_faces[i]); - edge_adj_faces[i] = NULL; + edge_adj_faces[i] = nullptr; } else { orig_edge_lengths[i] = sqrtf(orig_edge_lengths[i]); @@ -441,7 +460,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (!face_singularity[face]) { bool is_singularity = true; for (uint k = 0; k < orig_mpoly[face].totloop; k++) { - if (vm[orig_mloop[((uint)orig_mpoly[face].loopstart) + k].v] != v1) { + if (vm[orig_mloop[(uint(orig_mpoly[face].loopstart)) + k].v] != v1) { is_singularity = false; break; } @@ -464,7 +483,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, MEM_freeN(edge_adj_faces[i]->faces); MEM_freeN(edge_adj_faces[i]->faces_reversed); MEM_freeN(edge_adj_faces[i]); - edge_adj_faces[i] = NULL; + edge_adj_faces[i] = nullptr; } } @@ -485,15 +504,16 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const uint len = vert_adj_edges_len[vert]; if (len > 0) { OldVertEdgeRef *old_edge_vert_ref = vert_adj_edges[vert]; - if (old_edge_vert_ref == NULL) { - uint *adj_edges = MEM_calloc_arrayN( - len, sizeof(*adj_edges), "OldVertEdgeRef::edges in solidify"); + if (old_edge_vert_ref == nullptr) { + uint *adj_edges = static_cast( + MEM_calloc_arrayN(len, sizeof(*adj_edges), __func__)); adj_edges[0] = i; for (uint k = 1; k < len; k++) { adj_edges[k] = MOD_SOLIDIFY_EMPTY_TAG; } - OldVertEdgeRef *ref = MEM_mallocN(sizeof(*ref), "OldVertEdgeRef in solidify"); - *ref = (OldVertEdgeRef){adj_edges, 1}; + OldVertEdgeRef *ref = static_cast( + MEM_mallocN(sizeof(*ref), __func__)); + *ref = OldVertEdgeRef{adj_edges, 1}; vert_adj_edges[vert] = ref; } else { @@ -550,10 +570,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, new_loops_num -= 4 * j; } const uint len = i_adj_faces->faces_len + invalid_adj_faces->faces_len - 2 * j; - uint *adj_faces = MEM_malloc_arrayN( - len, sizeof(*adj_faces), "OldEdgeFaceRef::faces in solidify"); - bool *adj_faces_loops_reversed = MEM_malloc_arrayN( - len, sizeof(*adj_faces_loops_reversed), "OldEdgeFaceRef::reversed in solidify"); + uint *adj_faces = static_cast( + MEM_malloc_arrayN(len, sizeof(*adj_faces), __func__)); + bool *adj_faces_loops_reversed = static_cast( + MEM_malloc_arrayN(len, sizeof(*adj_faces_loops_reversed), __func__)); /* Clean merge of adj_faces. */ j = 0; for (uint k = 0; k < i_adj_faces->faces_len; k++) { @@ -671,7 +691,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, edge_adj_faces_len[e]--; if (edge_adj_faces_len[e] == 0) { e_adj_faces->used--; - edge_adj_faces[e] = NULL; + edge_adj_faces[e] = nullptr; } } else if (e_adj_faces->used > 1) { @@ -680,7 +700,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, edge_adj_faces_len[n]--; if (edge_adj_faces_len[n] == 0) { edge_adj_faces[n]->used--; - edge_adj_faces[n] = NULL; + edge_adj_faces[n] = nullptr; } break; } @@ -691,7 +711,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } if (do_shell) { new_polys_num -= 2; - new_loops_num -= 2 * (uint)del_loops; + new_loops_num -= 2 * uint(del_loops); } break; } @@ -758,8 +778,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const uint *adj_faces_faces = adj_faces->faces; const bool *adj_faces_reversed = adj_faces->faces_reversed; uint new_edges_len = 0; - FaceKeyPair *sorted_faces = MEM_malloc_arrayN( - adj_len, sizeof(*sorted_faces), "sorted_faces in solidify"); + FaceKeyPair *sorted_faces = static_cast( + MEM_malloc_arrayN(adj_len, sizeof(*sorted_faces), __func__)); if (adj_len > 1) { new_edges_len = adj_len; /* Get keys for sorting. */ @@ -814,9 +834,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } /* Create a list of new edges and fill it. */ - NewEdgeRef **new_edges = MEM_malloc_arrayN( - new_edges_len + 1, sizeof(*new_edges), "new_edges in solidify"); - new_edges[new_edges_len] = NULL; + NewEdgeRef **new_edges = static_cast( + MEM_malloc_arrayN(new_edges_len + 1, sizeof(*new_edges), __func__)); + new_edges[new_edges_len] = nullptr; NewFaceRef *faces[2]; for (uint j = 0; j < new_edges_len; j++) { float angle; @@ -833,26 +853,33 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, else { faces[0] = sorted_faces[0].face->reversed ? sorted_faces[0].face - j : sorted_faces[0].face + j; - faces[1] = NULL; + faces[1] = nullptr; angle = 0; } - NewEdgeRef *edge_data = MEM_mallocN(sizeof(*edge_data), "edge_data in solidify"); + NewEdgeRef *edge_data = static_cast( + MEM_mallocN(sizeof(*edge_data), __func__)); uint edge_data_edge_index = MOD_SOLIDIFY_EMPTY_TAG; if (do_shell || (adj_len == 1 && do_rim)) { edge_data_edge_index = 0; } - *edge_data = (NewEdgeRef){.old_edge = i, - .faces = {faces[0], faces[1]}, - .link_edge_groups = {NULL, NULL}, - .angle = angle, - .new_edge = edge_data_edge_index}; + + NewEdgeRef new_edge_ref{}; + new_edge_ref.old_edge = i; + new_edge_ref.faces[0] = faces[0]; + new_edge_ref.faces[1] = faces[1]; + new_edge_ref.link_edge_groups[0] = nullptr; + new_edge_ref.link_edge_groups[1] = nullptr; + new_edge_ref.angle = angle; + new_edge_ref.new_edge = edge_data_edge_index; + *edge_data = new_edge_ref; + new_edges[j] = edge_data; for (uint k = 0; k < 2; k++) { - if (faces[k] != NULL) { + if (faces[k] != nullptr) { const MLoop *ml = orig_mloop + faces[k]->face->loopstart; for (int l = 0; l < faces[k]->face->totloop; l++, ml++) { if (edge_adj_faces[ml->e] == edge_adj_faces[i]) { - if (ml->e != i && orig_edge_data_arr[ml->e] == NULL) { + if (ml->e != i && orig_edge_data_arr[ml->e] == nullptr) { orig_edge_data_arr[ml->e] = new_edges; } faces[k]->link_edges[l] = edge_data; @@ -890,7 +917,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, { OldVertEdgeRef **adj_edges_ptr = vert_adj_edges; for (uint i = 0; i < verts_num; i++, adj_edges_ptr++) { - if (*adj_edges_ptr != NULL && (*adj_edges_ptr)->edges_len >= 2) { + if (*adj_edges_ptr != nullptr && (*adj_edges_ptr)->edges_len >= 2) { EdgeGroup *edge_groups; int eg_index = -1; @@ -915,8 +942,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } } } - NewEdgeRef **unassigned_edges = MEM_malloc_arrayN( - unassigned_edges_len, sizeof(*unassigned_edges), "unassigned_edges in solidify"); + NewEdgeRef **unassigned_edges = static_cast( + MEM_malloc_arrayN(unassigned_edges_len, sizeof(*unassigned_edges), __func__)); for (uint j = 0, k = 0; j < tot_adj_edges; j++) { NewEdgeRef **new_edges = orig_edge_data_arr[adj_edges[j]]; if (new_edges) { @@ -930,36 +957,36 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* An edge group will always contain min 2 edges * so max edge group count can be calculated. */ uint edge_groups_len = unassigned_edges_len / 2; - edge_groups = MEM_calloc_arrayN( - edge_groups_len + 1, sizeof(*edge_groups), "edge_groups in solidify"); + edge_groups = static_cast( + MEM_calloc_arrayN(edge_groups_len + 1, sizeof(*edge_groups), __func__)); uint assigned_edges_len = 0; - NewEdgeRef *found_edge = NULL; + NewEdgeRef *found_edge = nullptr; uint found_edge_index = 0; bool insert_at_start = false; uint eg_capacity = 5; - NewFaceRef *eg_track_faces[2] = {NULL, NULL}; - NewFaceRef *last_open_edge_track = NULL; + NewFaceRef *eg_track_faces[2] = {nullptr, nullptr}; + NewFaceRef *last_open_edge_track = nullptr; while (assigned_edges_len < unassigned_edges_len) { - found_edge = NULL; + found_edge = nullptr; insert_at_start = false; if (eg_index >= 0 && edge_groups[eg_index].edges_len == 0) { /* Called every time a new group was started in the last iteration. */ /* Find an unused edge to start the next group * and setup variables to start creating it. */ uint j = 0; - NewEdgeRef *edge = NULL; + NewEdgeRef *edge = nullptr; while (!edge && j < unassigned_edges_len) { edge = unassigned_edges[j++]; if (edge && last_open_edge_track && - (edge->faces[0] != last_open_edge_track || edge->faces[1] != NULL)) { - edge = NULL; + (edge->faces[0] != last_open_edge_track || edge->faces[1] != nullptr)) { + edge = nullptr; } } if (!edge && last_open_edge_track) { topo_groups++; - last_open_edge_track = NULL; + last_open_edge_track = nullptr; edge_groups[eg_index].topo_group++; j = 0; while (!edge && j < unassigned_edges_len) { @@ -970,13 +997,13 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, topo_groups++; edge_groups[eg_index].topo_group++; } - BLI_assert(edge != NULL); + BLI_assert(edge != nullptr); found_edge_index = j - 1; found_edge = edge; if (!last_open_edge_track && vm[orig_medge[edge->old_edge].v1] == i) { eg_track_faces[0] = edge->faces[0]; eg_track_faces[1] = edge->faces[1]; - if (edge->faces[1] == NULL) { + if (edge->faces[1] == nullptr) { last_open_edge_track = edge->faces[0]->reversed ? edge->faces[0] - 1 : edge->faces[0] + 1; } @@ -996,7 +1023,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, insert_at_start = false; eg_track_faces[1] = edge->faces[1]; found_edge = edge; - if (edge->faces[1] == NULL) { + if (edge->faces[1] == nullptr) { edge_groups[eg_index].is_orig_closed = false; last_open_edge_track = edge->faces[0]->reversed ? edge->faces[0] - 1 : edge->faces[0] + 1; @@ -1007,12 +1034,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, insert_at_start = true; eg_track_faces[0] = edge->faces[1]; found_edge = edge; - if (edge->faces[1] == NULL) { + if (edge->faces[1] == nullptr) { edge_groups[eg_index].is_orig_closed = false; } break; } - if (edge->faces[1] != NULL) { + if (edge->faces[1] != nullptr) { if (edge->faces[1] == eg_track_faces[1]) { insert_at_start = false; eg_track_faces[1] = edge->faces[0]; @@ -1030,13 +1057,13 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } } if (found_edge) { - unassigned_edges[found_edge_index] = NULL; + unassigned_edges[found_edge_index] = nullptr; assigned_edges_len++; const uint needed_capacity = edge_groups[eg_index].edges_len + 1; if (needed_capacity > eg_capacity) { eg_capacity = needed_capacity + 1; - NewEdgeRef **new_eg = MEM_calloc_arrayN( - eg_capacity, sizeof(*new_eg), "edge_group realloc in solidify"); + NewEdgeRef **new_eg = static_cast( + MEM_calloc_arrayN(eg_capacity, sizeof(*new_eg), __func__)); if (insert_at_start) { memcpy(new_eg + 1, edge_groups[eg_index].edges, @@ -1059,8 +1086,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, found_edge; edge_groups[eg_index].edges_len++; if (edge_groups[eg_index].edges[edge_groups[eg_index].edges_len - 1]->faces[1] != - NULL) { - last_open_edge_track = NULL; + nullptr) { + last_open_edge_track = nullptr; } if (edge_groups[eg_index].edges_len > 3) { contains_long_groups = true; @@ -1072,24 +1099,26 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, eg_index++; BLI_assert(eg_index < edge_groups_len); eg_capacity = 5; - NewEdgeRef **edges = MEM_calloc_arrayN( - eg_capacity, sizeof(*edges), "edge_group in solidify"); - edge_groups[eg_index] = (EdgeGroup){ - .valid = true, - .edges = edges, - .edges_len = 0, - .open_face_edge = MOD_SOLIDIFY_EMPTY_TAG, - .is_orig_closed = true, - .is_even_split = false, - .split = 0, - .is_singularity = false, - .topo_group = topo_groups, - .co = {0.0f, 0.0f, 0.0f}, - .no = {0.0f, 0.0f, 0.0f}, - .new_vert = MOD_SOLIDIFY_EMPTY_TAG, - }; - eg_track_faces[0] = NULL; - eg_track_faces[1] = NULL; + NewEdgeRef **edges = static_cast( + MEM_calloc_arrayN(eg_capacity, sizeof(*edges), __func__)); + + EdgeGroup edge_group{}; + edge_group.valid = true; + edge_group.edges = edges; + edge_group.edges_len = 0; + edge_group.open_face_edge = MOD_SOLIDIFY_EMPTY_TAG; + edge_group.is_orig_closed = true; + edge_group.is_even_split = false; + edge_group.split = 0; + edge_group.is_singularity = false; + edge_group.topo_group = topo_groups; + zero_v3(edge_group.co); + zero_v3(edge_group.no); + edge_group.new_vert = MOD_SOLIDIFY_EMPTY_TAG; + edge_groups[eg_index] = edge_group; + + eg_track_faces[0] = nullptr; + eg_track_faces[1] = nullptr; } } /* #eg_index is the number of groups from here on. */ @@ -1112,8 +1141,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const uint edges_len = edge_groups[j + add_index].edges_len; if (edges_len > 3) { bool has_doubles = false; - bool *doubles = MEM_calloc_arrayN( - edges_len, sizeof(*doubles), "doubles in solidify"); + bool *doubles = static_cast( + MEM_calloc_arrayN(edges_len, sizeof(*doubles), __func__)); EdgeGroup g = edge_groups[j + add_index]; for (uint k = 0; k < edges_len; k++) { for (uint l = k + 1; l < edges_len; l++) { @@ -1136,78 +1165,80 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, while (real_k < edges_len || (g.is_orig_closed && (real_k <= - (first_unique_end == -1 ? 0 : first_unique_end) + (int)edges_len || + (first_unique_end == -1 ? 0 : first_unique_end) + int(edges_len) || first_split != last_split))) { const uint k = real_k % edges_len; if (!doubles[k]) { if (first_unique_end != -1 && unique_start == -1) { - unique_start = (int)real_k; + unique_start = int(real_k); } } else if (first_unique_end == -1) { - first_unique_end = (int)k; + first_unique_end = int(k); } else if (unique_start != -1) { - const uint split = (((uint)unique_start + real_k + 1) / 2) % edges_len; - const bool is_even_split = (((uint)unique_start + real_k) & 1); + const uint split = ((uint(unique_start) + real_k + 1) / 2) % edges_len; + const bool is_even_split = ((uint(unique_start) + real_k) & 1); if (last_split != -1) { /* Override g on first split (no insert). */ if (prior_splits != splits) { memmove(edge_groups + j + add_index + 1, edge_groups + j + add_index, - ((uint)eg_index - j) * sizeof(*edge_groups)); + (uint(eg_index) - j) * sizeof(*edge_groups)); add_index++; } if (last_split > split) { - const uint edges_len_group = (split + edges_len) - (uint)last_split; - NewEdgeRef **edges = MEM_malloc_arrayN( - edges_len_group, sizeof(*edges), "edge_group split in solidify"); + const uint edges_len_group = (split + edges_len) - uint(last_split); + NewEdgeRef **edges = static_cast( + MEM_malloc_arrayN(edges_len_group, sizeof(*edges), __func__)); memcpy(edges, g.edges + last_split, - (edges_len - (uint)last_split) * sizeof(*edges)); - memcpy(edges + (edges_len - (uint)last_split), + (edges_len - uint(last_split)) * sizeof(*edges)); + memcpy(edges + (edges_len - uint(last_split)), g.edges, split * sizeof(*edges)); - edge_groups[j + add_index] = (EdgeGroup){ - .valid = true, - .edges = edges, - .edges_len = edges_len_group, - .open_face_edge = MOD_SOLIDIFY_EMPTY_TAG, - .is_orig_closed = g.is_orig_closed, - .is_even_split = is_even_split, - .split = add_index - prior_index + 1 + (uint)!g.is_orig_closed, - .is_singularity = false, - .topo_group = g.topo_group, - .co = {0.0f, 0.0f, 0.0f}, - .no = {0.0f, 0.0f, 0.0f}, - .new_vert = MOD_SOLIDIFY_EMPTY_TAG, - }; + + EdgeGroup edge_group{}; + edge_group.valid = true; + edge_group.edges = edges; + edge_group.edges_len = edges_len_group; + edge_group.open_face_edge = MOD_SOLIDIFY_EMPTY_TAG; + edge_group.is_orig_closed = g.is_orig_closed; + edge_group.is_even_split = is_even_split; + edge_group.split = add_index - prior_index + 1 + uint(!g.is_orig_closed); + edge_group.is_singularity = false; + edge_group.topo_group = g.topo_group; + zero_v3(edge_group.co); + zero_v3(edge_group.no); + edge_group.new_vert = MOD_SOLIDIFY_EMPTY_TAG; + edge_groups[j + add_index] = edge_group; } else { - const uint edges_len_group = split - (uint)last_split; - NewEdgeRef **edges = MEM_malloc_arrayN( - edges_len_group, sizeof(*edges), "edge_group split in solidify"); + const uint edges_len_group = split - uint(last_split); + NewEdgeRef **edges = static_cast( + MEM_malloc_arrayN(edges_len_group, sizeof(*edges), __func__)); memcpy(edges, g.edges + last_split, edges_len_group * sizeof(*edges)); - edge_groups[j + add_index] = (EdgeGroup){ - .valid = true, - .edges = edges, - .edges_len = edges_len_group, - .open_face_edge = MOD_SOLIDIFY_EMPTY_TAG, - .is_orig_closed = g.is_orig_closed, - .is_even_split = is_even_split, - .split = add_index - prior_index + 1 + (uint)!g.is_orig_closed, - .is_singularity = false, - .topo_group = g.topo_group, - .co = {0.0f, 0.0f, 0.0f}, - .no = {0.0f, 0.0f, 0.0f}, - .new_vert = MOD_SOLIDIFY_EMPTY_TAG, - }; + + EdgeGroup edge_group{}; + edge_group.valid = true; + edge_group.edges = edges; + edge_group.edges_len = edges_len_group; + edge_group.open_face_edge = MOD_SOLIDIFY_EMPTY_TAG; + edge_group.is_orig_closed = g.is_orig_closed; + edge_group.is_even_split = is_even_split; + edge_group.split = add_index - prior_index + 1 + uint(!g.is_orig_closed); + edge_group.is_singularity = false; + edge_group.topo_group = g.topo_group; + zero_v3(edge_group.co); + zero_v3(edge_group.no); + edge_group.new_vert = MOD_SOLIDIFY_EMPTY_TAG; + edge_groups[j + add_index] = edge_group; } splits++; } - last_split = (int)split; + last_split = int(split); if (first_split == -1) { - first_split = (int)split; + first_split = int(split); first_even_split = is_even_split; } unique_start = -1; @@ -1219,57 +1250,56 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (prior_splits != splits) { memmove(edge_groups + (j + prior_index + 1), edge_groups + (j + prior_index), - ((uint)eg_index + add_index - (j + prior_index)) * + (uint(eg_index) + add_index - (j + prior_index)) * sizeof(*edge_groups)); memmove(edge_groups + (j + add_index + 2), edge_groups + (j + add_index + 1), - ((uint)eg_index - j) * sizeof(*edge_groups)); + (uint(eg_index) - j) * sizeof(*edge_groups)); add_index++; } else { memmove(edge_groups + (j + add_index + 2), edge_groups + (j + add_index + 1), - ((uint)eg_index - j - 1) * sizeof(*edge_groups)); + (uint(eg_index) - j - 1) * sizeof(*edge_groups)); } - NewEdgeRef **edges = MEM_malloc_arrayN( - (uint)first_split, sizeof(*edges), "edge_group split in solidify"); - memcpy(edges, g.edges, (uint)first_split * sizeof(*edges)); - edge_groups[j + prior_index] = (EdgeGroup){ - .valid = true, - .edges = edges, - .edges_len = (uint)first_split, - .open_face_edge = MOD_SOLIDIFY_EMPTY_TAG, - .is_orig_closed = g.is_orig_closed, - .is_even_split = first_even_split, - .split = 1, - .is_singularity = false, - .topo_group = g.topo_group, - .co = {0.0f, 0.0f, 0.0f}, - .no = {0.0f, 0.0f, 0.0f}, - .new_vert = MOD_SOLIDIFY_EMPTY_TAG, - }; + NewEdgeRef **edges = static_cast( + MEM_malloc_arrayN(uint(first_split), sizeof(*edges), __func__)); + memcpy(edges, g.edges, uint(first_split) * sizeof(*edges)); + + EdgeGroup edge_group_a{}; + edge_group_a.valid = true, edge_group_a.edges = edges, + edge_group_a.edges_len = uint(first_split), + edge_group_a.open_face_edge = MOD_SOLIDIFY_EMPTY_TAG, + edge_group_a.is_orig_closed = g.is_orig_closed, + edge_group_a.is_even_split = first_even_split, edge_group_a.split = 1, + edge_group_a.is_singularity = false, edge_group_a.topo_group = g.topo_group, + zero_v3(edge_group_a.co); + zero_v3(edge_group_a.no); + edge_group_a.new_vert = MOD_SOLIDIFY_EMPTY_TAG, + edge_groups[j + prior_index] = edge_group_a; + add_index++; splits++; - edges = MEM_malloc_arrayN(edges_len - (uint)last_split, - sizeof(*edges), - "edge_group split in solidify"); + edges = static_cast(MEM_malloc_arrayN( + edges_len - uint(last_split), sizeof(*edges), __func__)); memcpy(edges, g.edges + last_split, - (edges_len - (uint)last_split) * sizeof(*edges)); - edge_groups[j + add_index] = (EdgeGroup){ - .valid = true, - .edges = edges, - .edges_len = (edges_len - (uint)last_split), - .open_face_edge = MOD_SOLIDIFY_EMPTY_TAG, - .is_orig_closed = g.is_orig_closed, - .is_even_split = false, - .split = add_index - prior_index + 1, - .is_singularity = false, - .topo_group = g.topo_group, - .co = {0.0f, 0.0f, 0.0f}, - .no = {0.0f, 0.0f, 0.0f}, - .new_vert = MOD_SOLIDIFY_EMPTY_TAG, - }; + (edges_len - uint(last_split)) * sizeof(*edges)); + + EdgeGroup edge_group_b{}; + edge_group_b.valid = true; + edge_group_b.edges = edges; + edge_group_b.edges_len = (edges_len - uint(last_split)); + edge_group_b.open_face_edge = MOD_SOLIDIFY_EMPTY_TAG; + edge_group_b.is_orig_closed = g.is_orig_closed; + edge_group_b.is_even_split = false; + edge_group_b.split = add_index - prior_index + 1; + edge_group_b.is_singularity = false; + edge_group_b.topo_group = g.topo_group; + zero_v3(edge_group_b.co); + zero_v3(edge_group_b.no); + edge_group_b.new_vert = MOD_SOLIDIFY_EMPTY_TAG; + edge_groups[j + add_index] = edge_group_b; } if (prior_splits != splits) { MEM_freeN(g.edges); @@ -1299,7 +1329,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, for (EdgeGroup *g = edge_groups; g->valid; g++) { NewEdgeRef **e = g->edges; for (uint j = 0; j < g->edges_len; j++, e++) { - const uint flip = (uint)(vm[orig_medge[(*e)->old_edge].v2] == i); + const uint flip = uint(vm[orig_medge[(*e)->old_edge].v2] == i); BLI_assert(flip || vm[orig_medge[(*e)->old_edge].v1] == i); (*e)->link_edge_groups[flip] = g; } @@ -1314,7 +1344,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, added = g->split; } } - open_edges += (uint)(added < last_added); + open_edges += uint(added < last_added); if (!first_set) { first_set = true; first_added = added; @@ -1324,8 +1354,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (new_verts > 2) { new_polys_num++; new_edges_num += new_verts; - open_edges += (uint)(first_added < last_added); - open_edges -= (uint)(open_edges && !contains_open_splits); + open_edges += uint(first_added < last_added); + open_edges -= uint(open_edges && !contains_open_splits); if (do_shell && do_rim) { new_loops_num += new_verts * 2; } @@ -1338,7 +1368,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } else if (new_verts == 2) { new_edges_num++; - new_loops_num += 2u - (uint)(!(do_rim && do_shell) && contains_open_splits); + new_loops_num += 2u - uint(!(do_rim && do_shell) && contains_open_splits); } new_verts = 0; contains_open_splits = false; @@ -1373,10 +1403,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Calculate EdgeGroup vertex coordinates. */ { - float *face_weight = NULL; + float *face_weight = nullptr; if (do_flat_faces) { - face_weight = MEM_malloc_arrayN(polys_num, sizeof(*face_weight), "face_weight in solidify"); + face_weight = static_cast( + MEM_malloc_arrayN(polys_num, sizeof(*face_weight), __func__)); const MPoly *mp = orig_mpoly; for (uint i = 0; i < polys_num; i++, mp++) { @@ -1415,11 +1446,11 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, bool approximate_free_direction = false; /* Constraints Method. */ if (smd->nonmanifold_offset_mode == MOD_SOLIDIFY_NONMANIFOLD_OFFSET_MODE_CONSTRAINTS) { - NewEdgeRef *first_edge = NULL; + NewEdgeRef *first_edge = nullptr; NewEdgeRef **edge_ptr = g->edges; /* Contains normal and offset [nx, ny, nz, ofs]. */ - float(*planes_queue)[4] = MEM_malloc_arrayN( - g->edges_len + 1, sizeof(*planes_queue), "planes_queue in solidify"); + float(*planes_queue)[4] = static_cast( + MEM_malloc_arrayN(g->edges_len + 1, sizeof(*planes_queue), __func__)); uint queue_index = 0; float fallback_nor[3]; @@ -1431,7 +1462,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, NewEdgeRef *edge = *edge_ptr; for (uint l = 0; l < 2; l++) { NewFaceRef *face = edge->faces[l]; - if (face && (first_edge == NULL || + if (face && (first_edge == nullptr || (first_edge->faces[0] != face && first_edge->faces[1] != face))) { float ofs = face->reversed ? ofs_back_clamped : ofs_front_clamped; /* Use face_weight here to make faces thinner. */ @@ -1631,7 +1662,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, else { float total_angle = 0; float total_angle_back = 0; - NewEdgeRef *first_edge = NULL; + NewEdgeRef *first_edge = nullptr; NewEdgeRef **edge_ptr = g->edges; float face_nor[3]; float nor_back[3] = {0, 0, 0}; @@ -1643,7 +1674,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, NewEdgeRef *edge = *edge_ptr; for (uint l = 0; l < 2; l++) { NewFaceRef *face = edge->faces[l]; - if (face && (first_edge == NULL || + if (face && (first_edge == nullptr || (first_edge->faces[0] != face && first_edge->faces[1] != face))) { float angle = 1.0f; float ofs = face->reversed ? -ofs_back_clamped : ofs_front_clamped; @@ -1903,14 +1934,14 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Correction for adjacent one sided groups around a vert to * prevent edge duplicates and null polys. */ - uint(*singularity_edges)[2] = NULL; + uint(*singularity_edges)[2] = nullptr; uint totsingularity = 0; if (has_singularities) { has_singularities = false; uint i = 0; uint singularity_edges_len = 1; - singularity_edges = MEM_malloc_arrayN( - singularity_edges_len, sizeof(*singularity_edges), "singularity_edges in solidify"); + singularity_edges = static_cast( + MEM_malloc_arrayN(singularity_edges_len, sizeof(*singularity_edges), __func__)); for (NewEdgeRef ***new_edges = orig_edge_data_arr; i < edges_num; i++, new_edges++) { if (*new_edges && (do_shell || edge_adj_faces_len[i] == 1) && (**new_edges)->old_edge == i) { for (NewEdgeRef **l = *new_edges; *l; l++) { @@ -1930,10 +1961,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, has_singularities = true; if (singularity_edges_len <= totsingularity) { singularity_edges_len = totsingularity + 1; - singularity_edges = MEM_reallocN_id(singularity_edges, - singularity_edges_len * - sizeof(*singularity_edges), - "singularity_edges in solidify"); + singularity_edges = static_cast( + MEM_reallocN_id(singularity_edges, + singularity_edges_len * sizeof(*singularity_edges), + __func__)); } singularity_edges[totsingularity][0] = v1; singularity_edges[totsingularity][1] = v2; @@ -1953,43 +1984,40 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } /* Create Mesh *result with proper capacity. */ - result = BKE_mesh_new_nomain_from_template(mesh, - (int)(new_verts_num), - (int)(new_edges_num), - 0, - (int)(new_loops_num), - (int)(new_polys_num)); + result = BKE_mesh_new_nomain_from_template( + mesh, int(new_verts_num), int(new_edges_num), 0, int(new_loops_num), int(new_polys_num)); float(*vert_positions)[3] = BKE_mesh_vert_positions_for_write(result); MEdge *medge = BKE_mesh_edges_for_write(result); MPoly *mpoly = BKE_mesh_polys_for_write(result); MLoop *mloop = BKE_mesh_loops_for_write(result); - int *origindex_edge = CustomData_get_layer_for_write( - &result->edata, CD_ORIGINDEX, result->totedge); - int *origindex_poly = CustomData_get_layer_for_write( - &result->pdata, CD_ORIGINDEX, result->totpoly); + int *origindex_edge = static_cast( + CustomData_get_layer_for_write(&result->edata, CD_ORIGINDEX, result->totedge)); + int *origindex_poly = static_cast( + CustomData_get_layer_for_write(&result->pdata, CD_ORIGINDEX, result->totpoly)); - float *result_edge_bweight = CustomData_get_layer_for_write( - &result->edata, CD_BWEIGHT, result->totedge); - if (bevel_convex != 0.0f || orig_vert_bweight != NULL) { - result_edge_bweight = CustomData_add_layer( - &result->edata, CD_BWEIGHT, CD_SET_DEFAULT, NULL, result->totedge); + float *result_edge_bweight = static_cast( + CustomData_get_layer_for_write(&result->edata, CD_BWEIGHT, result->totedge)); + if (bevel_convex != 0.0f || orig_vert_bweight != nullptr) { + result_edge_bweight = static_cast(CustomData_add_layer( + &result->edata, CD_BWEIGHT, CD_SET_DEFAULT, nullptr, result->totedge)); } /* Checks that result has dvert data. */ - MDeformVert *dst_dvert = NULL; + MDeformVert *dst_dvert = nullptr; if (shell_defgrp_index != -1 || rim_defgrp_index != -1) { dst_dvert = BKE_mesh_deform_verts_for_write(result); } /* Get vertex crease layer and ensure edge creases are active if vertex creases are found, since * they will introduce edge creases in the used custom interpolation method. */ - const float *vertex_crease = CustomData_get_layer(&mesh->vdata, CD_CREASE); - float *result_edge_crease = NULL; + const float *vertex_crease = static_cast( + CustomData_get_layer(&mesh->vdata, CD_CREASE)); + float *result_edge_crease = nullptr; if (vertex_crease) { result_edge_crease = (float *)CustomData_add_layer( - &result->edata, CD_CREASE, CD_SET_DEFAULT, NULL, result->totedge); + &result->edata, CD_CREASE, CD_SET_DEFAULT, nullptr, result->totedge); /* delete all vertex creases in the result if a rim is used. */ if (do_rim) { CustomData_free_layers(&result->vdata, CD_CREASE, result->totvert); @@ -2004,7 +2032,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (gs) { for (EdgeGroup *g = gs; g->valid; g++) { if (g->new_vert != MOD_SOLIDIFY_EMPTY_TAG) { - CustomData_copy_data(&mesh->vdata, &result->vdata, (int)i, (int)g->new_vert, 1); + CustomData_copy_data(&mesh->vdata, &result->vdata, int(i), int(g->new_vert), 1); copy_v3_v3(vert_positions[g->new_vert], g->co); } } @@ -2037,7 +2065,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, else { edge_index++; } - CustomData_copy_data(&mesh->edata, &result->edata, (int)i, (int)insert, 1); + CustomData_copy_data(&mesh->edata, &result->edata, int(i), int(insert), 1); BLI_assert(v1 != MOD_SOLIDIFY_EMPTY_TAG); BLI_assert(v2 != MOD_SOLIDIFY_EMPTY_TAG); medge[insert].v1 = v1; @@ -2051,7 +2079,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, result_edge_bweight[insert] = orig_edge_bweight ? orig_edge_bweight[(*l)->old_edge] : 0.0f; } - if (bevel_convex != 0.0f && (*l)->faces[1] != NULL) { + if (bevel_convex != 0.0f && (*l)->faces[1] != nullptr) { result_edge_bweight[insert] = clamp_f( result_edge_bweight[insert] + ((*l)->angle > M_PI + FLT_EPSILON ? @@ -2100,7 +2128,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, for (EdgeGroup *g = gs; g->valid; g++) { NewEdgeRef **e = g->edges; for (uint j = 0; j < g->edges_len; j++, e++) { - printf("%u/%d, ", (*e)->old_edge, (int)(*e)->new_edge); + printf("%u/%d, ", (*e)->old_edge, int(*e)->new_edge); } printf("(tg:%u)(s:%u,c:%d)\n", g->topo_group, g->split, g->is_orig_closed); } @@ -2120,8 +2148,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (gs) { EdgeGroup *g = gs; EdgeGroup *g2 = gs; - EdgeGroup *last_g = NULL; - EdgeGroup *first_g = NULL; + EdgeGroup *last_g = nullptr; + EdgeGroup *first_g = nullptr; float mv_crease = vertex_crease ? vertex_crease[i] : 0.0f; float mv_bweight = orig_vert_bweight ? orig_vert_bweight[i] : 0.0f; /* Data calculation cache. */ @@ -2197,8 +2225,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, last_g->open_face_edge = edge_index; CustomData_copy_data(&mesh->edata, &result->edata, - (int)last_g->edges[0]->old_edge, - (int)edge_index, + int(last_g->edges[0]->old_edge), + int(edge_index), 1); if (origindex_edge) { origindex_edge[edge_index] = ORIGINDEX_NONE; @@ -2229,8 +2257,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (j > 2) { CustomData_copy_data(&mesh->edata, &result->edata, - (int)last_g->edges[0]->old_edge, - (int)edge_index, + int(last_g->edges[0]->old_edge), + int(edge_index), 1); if (origindex_edge) { origindex_edge[edge_index] = ORIGINDEX_NONE; @@ -2250,7 +2278,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, edge_index++; /* Loop data. */ - int *loops = MEM_malloc_arrayN(j, sizeof(*loops), "loops in solidify"); + int *loops = static_cast(MEM_malloc_arrayN(j, sizeof(*loops), __func__)); /* The result material index is from consensus. */ short most_mat_nr = 0; uint most_mat_nr_face = 0; @@ -2289,12 +2317,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } } CustomData_copy_data( - &mesh->pdata, &result->pdata, (int)most_mat_nr_face, (int)poly_index, 1); + &mesh->pdata, &result->pdata, int(most_mat_nr_face), int(poly_index), 1); if (origindex_poly) { origindex_poly[poly_index] = ORIGINDEX_NONE; } - mpoly[poly_index].loopstart = (int)loop_index; - mpoly[poly_index].totloop = (int)j; + mpoly[poly_index].loopstart = int(loop_index); + mpoly[poly_index].totloop = int(j); dst_material_index[poly_index] = most_mat_nr + (g->is_orig_closed || !do_rim ? 0 : mat_ofs_rim); CLAMP(dst_material_index[poly_index], 0, mat_nr_max); @@ -2317,7 +2345,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, if (!do_flip) { for (uint k = 0; k < j; k++) { - CustomData_copy_data(&mesh->ldata, &result->ldata, loops[k], (int)loop_index, 1); + CustomData_copy_data(&mesh->ldata, &result->ldata, loops[k], int(loop_index), 1); mloop[loop_index].v = medge[edge_index - j + k].v1; mloop[loop_index++].e = edge_index - j + k; } @@ -2325,7 +2353,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, else { for (uint k = 1; k <= j; k++) { CustomData_copy_data( - &mesh->ldata, &result->ldata, loops[j - k], (int)loop_index, 1); + &mesh->ldata, &result->ldata, loops[j - k], int(loop_index), 1); mloop[loop_index].v = medge[edge_index - k].v2; mloop[loop_index++].e = edge_index - k; } @@ -2334,8 +2362,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } /* Reset everything for the next poly. */ j = 0; - last_g = NULL; - first_g = NULL; + last_g = nullptr; + first_g = nullptr; last_max_crease = 0; first_max_crease = 0; last_max_bweight = 0; @@ -2368,9 +2396,9 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const uint orig_face_index = (*new_edges)->faces[0]->index; const MPoly *face = (*new_edges)->faces[0]->face; CustomData_copy_data( - &mesh->pdata, &result->pdata, (int)(*new_edges)->faces[0]->index, (int)poly_index, 1); - mpoly[poly_index].loopstart = (int)loop_index; - mpoly[poly_index].totloop = 4 - (int)(v1_singularity || v2_singularity); + &mesh->pdata, &result->pdata, int((*new_edges)->faces[0]->index), int(poly_index), 1); + mpoly[poly_index].loopstart = int(loop_index); + mpoly[poly_index].totloop = 4 - int(v1_singularity || v2_singularity); dst_material_index[poly_index] = (src_material_index ? src_material_index[orig_face_index] : 0) + mat_ofs_rim; CLAMP(dst_material_index[poly_index], 0, mat_nr_max); @@ -2384,10 +2412,10 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const uint old_v2 = vm[orig_medge[edge1->old_edge].v2]; for (uint j = 0; j < face->totloop; j++, ml++) { if (vm[ml->v] == old_v1) { - loop1 = face->loopstart + (int)j; + loop1 = face->loopstart + int(j); } else if (vm[ml->v] == old_v2) { - loop2 = face->loopstart + (int)j; + loop2 = face->loopstart + int(j); } } BLI_assert(loop1 != -1 && loop2 != -1); @@ -2398,7 +2426,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, BKE_defvert_ensure_index(&dst_dvert[medge[edge1->new_edge].v1], rim_defgrp_index) ->weight = 1.0f; } - CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); + CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, int(loop_index), 1); mloop[loop_index].v = medge[edge1->new_edge].v1; mloop[loop_index++].e = edge1->new_edge; @@ -2408,7 +2436,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, BKE_defvert_ensure_index(&dst_dvert[medge[edge1->new_edge].v2], rim_defgrp_index) ->weight = 1.0f; } - CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); + CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, int(loop_index), 1); mloop[loop_index].v = medge[edge1->new_edge].v2; open_face_edge = medge + open_face_edge_index; if (ELEM(medge[edge2->new_edge].v2, open_face_edge->v1, open_face_edge->v2)) { @@ -2423,7 +2451,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, BKE_defvert_ensure_index(&dst_dvert[medge[edge2->new_edge].v2], rim_defgrp_index) ->weight = 1.0f; } - CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); + CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, int(loop_index), 1); mloop[loop_index].v = medge[edge2->new_edge].v2; mloop[loop_index++].e = edge2->new_edge; @@ -2433,7 +2461,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, BKE_defvert_ensure_index(&dst_dvert[medge[edge2->new_edge].v1], rim_defgrp_index) ->weight = 1.0f; } - CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); + CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, int(loop_index), 1); mloop[loop_index].v = medge[edge2->new_edge].v1; open_face_edge = medge + open_face_edge_index; if (ELEM(medge[edge1->new_edge].v1, open_face_edge->v1, open_face_edge->v2)) { @@ -2451,7 +2479,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, BKE_defvert_ensure_index(&dst_dvert[medge[edge1->new_edge].v1], rim_defgrp_index) ->weight = 1.0f; } - CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); + CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, int(loop_index), 1); mloop[loop_index].v = medge[edge1->new_edge].v1; open_face_edge = medge + open_face_edge_index; if (ELEM(medge[edge2->new_edge].v1, open_face_edge->v1, open_face_edge->v2)) { @@ -2466,7 +2494,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, BKE_defvert_ensure_index(&dst_dvert[medge[edge2->new_edge].v1], rim_defgrp_index) ->weight = 1.0f; } - CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, (int)loop_index, 1); + CustomData_copy_data(&mesh->ldata, &result->ldata, loop1, int(loop_index), 1); mloop[loop_index].v = medge[edge2->new_edge].v1; mloop[loop_index++].e = edge2->new_edge; @@ -2476,7 +2504,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, BKE_defvert_ensure_index(&dst_dvert[medge[edge2->new_edge].v2], rim_defgrp_index) ->weight = 1.0f; } - CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); + CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, int(loop_index), 1); mloop[loop_index].v = medge[edge2->new_edge].v2; open_face_edge = medge + open_face_edge_index; if (ELEM(medge[edge1->new_edge].v2, open_face_edge->v1, open_face_edge->v2)) { @@ -2491,7 +2519,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, BKE_defvert_ensure_index(&dst_dvert[medge[edge1->new_edge].v2], rim_defgrp_index) ->weight = 1.0f; } - CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, (int)loop_index, 1); + CustomData_copy_data(&mesh->ldata, &result->ldata, loop2, int(loop_index), 1); mloop[loop_index].v = medge[edge1->new_edge].v2; mloop[loop_index++].e = edge1->new_edge; } @@ -2502,12 +2530,12 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, /* Make faces. */ if (do_shell) { NewFaceRef *fr = face_sides_arr; - uint *face_loops = MEM_malloc_arrayN( - largest_ngon * 2, sizeof(*face_loops), "face_loops in solidify"); - uint *face_verts = MEM_malloc_arrayN( - largest_ngon * 2, sizeof(*face_verts), "face_verts in solidify"); - uint *face_edges = MEM_malloc_arrayN( - largest_ngon * 2, sizeof(*face_edges), "face_edges in solidify"); + uint *face_loops = static_cast( + MEM_malloc_arrayN(largest_ngon * 2, sizeof(*face_loops), __func__)); + uint *face_verts = static_cast( + MEM_malloc_arrayN(largest_ngon * 2, sizeof(*face_verts), __func__)); + uint *face_edges = static_cast( + MEM_malloc_arrayN(largest_ngon * 2, sizeof(*face_edges), __func__)); for (uint i = 0; i < polys_num * 2; i++, fr++) { const uint loopstart = (uint)fr->face->loopstart; uint totloop = (uint)fr->face->totloop; @@ -2560,22 +2588,22 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } } if (k > 2 && valid_edges > 2) { - CustomData_copy_data(&mesh->pdata, &result->pdata, (int)(i / 2), (int)poly_index, 1); - mpoly[poly_index].loopstart = (int)loop_index; - mpoly[poly_index].totloop = (int)k; + CustomData_copy_data(&mesh->pdata, &result->pdata, int(i / 2), int(poly_index), 1); + mpoly[poly_index].loopstart = int(loop_index); + mpoly[poly_index].totloop = int(k); dst_material_index[poly_index] = (src_material_index ? src_material_index[fr->index] : 0) + (fr->reversed != do_flip ? mat_ofs : 0); CLAMP(dst_material_index[poly_index], 0, mat_nr_max); mpoly[poly_index].flag = fr->face->flag; if (fr->reversed != do_flip) { - for (int l = (int)k - 1; l >= 0; l--) { + for (int l = int(k) - 1; l >= 0; l--) { if (shell_defgrp_index != -1) { BKE_defvert_ensure_index(&dst_dvert[face_verts[l]], shell_defgrp_index)->weight = 1.0f; } CustomData_copy_data( - &mesh->ldata, &result->ldata, (int)face_loops[l], (int)loop_index, 1); + &mesh->ldata, &result->ldata, int(face_loops[l]), int(loop_index), 1); mloop[loop_index].v = face_verts[l]; mloop[loop_index++].e = face_edges[l]; } @@ -2584,7 +2612,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, uint l = k - 1; for (uint next_l = 0; next_l < k; next_l++) { CustomData_copy_data( - &mesh->ldata, &result->ldata, (int)face_loops[l], (int)loop_index, 1); + &mesh->ldata, &result->ldata, int(face_loops[l]), int(loop_index), 1); mloop[loop_index].v = face_verts[l]; mloop[loop_index++].e = face_edges[next_l]; l = next_l; diff --git a/source/blender/modifiers/intern/MOD_solidify_util.h b/source/blender/modifiers/intern/MOD_solidify_util.hh similarity index 87% rename from source/blender/modifiers/intern/MOD_solidify_util.h rename to source/blender/modifiers/intern/MOD_solidify_util.hh index 2d279302f25..36192134187 100644 --- a/source/blender/modifiers/intern/MOD_solidify_util.h +++ b/source/blender/modifiers/intern/MOD_solidify_util.hh @@ -6,13 +6,13 @@ #pragma once -/* MOD_solidify_extrude.c */ +/* MOD_solidify_extrude.cc */ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh); -/* MOD_solidify_nonmanifold.c */ +/* MOD_solidify_nonmanifold.cc */ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.cc similarity index 87% rename from source/blender/modifiers/intern/MOD_surfacedeform.c rename to source/blender/modifiers/intern/MOD_surfacedeform.cc index c43bf19a580..5ee9f4d5690 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.cc @@ -5,7 +5,6 @@ * \ingroup modifiers */ -#include "BLI_alloca.h" #include "BLI_math.h" #include "BLI_math_geom.h" #include "BLI_task.h" @@ -47,45 +46,45 @@ #include "MOD_ui_common.h" #include "MOD_util.h" -typedef struct SDefAdjacency { - struct SDefAdjacency *next; +struct SDefAdjacency { + SDefAdjacency *next; uint index; -} SDefAdjacency; +}; -typedef struct SDefAdjacencyArray { +struct SDefAdjacencyArray { SDefAdjacency *first; uint num; /* Careful, this is twice the number of polygons (avoids an extra loop) */ -} SDefAdjacencyArray; +}; /** * Polygons per edge (only 2, any more will exit calculation). */ -typedef struct SDefEdgePolys { +struct SDefEdgePolys { uint polys[2], num; -} SDefEdgePolys; +}; -typedef struct SDefBindCalcData { - BVHTreeFromMesh *const treeData; - const SDefAdjacencyArray *const vert_edges; - const SDefEdgePolys *const edge_polys; - SDefVert *const bind_verts; - const MLoopTri *const looptri; - const MPoly *const mpoly; - const MEdge *const medge; - const MLoop *const mloop; +struct SDefBindCalcData { + BVHTreeFromMesh *treeData; + const SDefAdjacencyArray *vert_edges; + const SDefEdgePolys *edge_polys; + SDefVert *bind_verts; + const MLoopTri *looptri; + const MPoly *mpoly; + const MEdge *medge; + const MLoop *mloop; /** Coordinates to bind to, transformed into local space (compatible with `vertexCos`). */ - float (*const targetCos)[3]; + float (*targetCos)[3]; /** Coordinates to bind (reference to the modifiers input argument). */ - float (*const vertexCos)[3]; + const float (*vertexCos)[3]; float imat[4][4]; - const float falloff; + float falloff; int success; /** Vertex group lookup data. */ - const MDeformVert *const dvert; - int const defgrp_index; - bool const invert_vgroup; - bool const sparse_bind; -} SDefBindCalcData; + const MDeformVert *dvert; + int defgrp_index; + bool invert_vgroup; + bool sparse_bind; +}; /** * This represents the relationship between a point (a source coordinate) @@ -94,7 +93,7 @@ typedef struct SDefBindCalcData { * \note Some of these values could be de-duplicated however these are only * needed once when running bind, so optimizing this structure isn't a priority. */ -typedef struct SDefBindPoly { +struct SDefBindPoly { /** Coordinates copied directly from the modifiers input. */ float (*coords)[3]; /** Coordinates projected into 2D space using `normal`. */ @@ -148,23 +147,23 @@ typedef struct SDefBindPoly { uint dominant_edge; /** When true `point_v2` is inside `coords_v2`. */ bool inside; -} SDefBindPoly; +}; -typedef struct SDefBindWeightData { +struct SDefBindWeightData { SDefBindPoly *bind_polys; uint polys_num; uint binds_num; -} SDefBindWeightData; +}; -typedef struct SDefDeformData { - const SDefVert *const bind_verts; - float (*const targetCos)[3]; - float (*const vertexCos)[3]; - const MDeformVert *const dvert; - int const defgrp_index; - bool const invert_vgroup; - float const strength; -} SDefDeformData; +struct SDefDeformData { + const SDefVert *bind_verts; + float (*targetCos)[3]; + float (*vertexCos)[3]; + const MDeformVert *dvert; + int defgrp_index; + bool invert_vgroup; + float strength; +}; /* Bind result values */ enum { @@ -229,20 +228,21 @@ static void copyData(const ModifierData *md, ModifierData *target, const int fla BKE_modifier_copydata_generic(md, target, flag); if (smd->verts) { - tsmd->verts = MEM_dupallocN(smd->verts); + tsmd->verts = static_cast(MEM_dupallocN(smd->verts)); for (int i = 0; i < smd->bind_verts_num; i++) { if (smd->verts[i].binds) { - tsmd->verts[i].binds = MEM_dupallocN(smd->verts[i].binds); + tsmd->verts[i].binds = static_cast(MEM_dupallocN(smd->verts[i].binds)); for (int j = 0; j < smd->verts[i].binds_num; j++) { if (smd->verts[i].binds[j].vert_inds) { - tsmd->verts[i].binds[j].vert_inds = MEM_dupallocN(smd->verts[i].binds[j].vert_inds); + tsmd->verts[i].binds[j].vert_inds = static_cast( + MEM_dupallocN(smd->verts[i].binds[j].vert_inds)); } if (smd->verts[i].binds[j].vert_weights) { - tsmd->verts[i].binds[j].vert_weights = MEM_dupallocN( - smd->verts[i].binds[j].vert_weights); + tsmd->verts[i].binds[j].vert_weights = static_cast( + MEM_dupallocN(smd->verts[i].binds[j].vert_weights)); } } } @@ -260,7 +260,7 @@ static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *u static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; - if (smd->target != NULL) { + if (smd->target != nullptr) { DEG_add_object_relation( ctx->node, smd->target, DEG_OB_COMP_GEOMETRY, "Surface Deform Modifier"); } @@ -368,10 +368,10 @@ BLI_INLINE void sortPolyVertsTri(uint *indices, BLI_INLINE uint nearestVert(SDefBindCalcData *const data, const float point_co[3]) { - BVHTreeNearest nearest = { - .dist_sq = FLT_MAX, - .index = -1, - }; + BVHTreeNearest nearest{}; + nearest.dist_sq = FLT_MAX; + nearest.index = -1; + const MPoly *poly; const MEdge *edge; const MLoop *loop; @@ -489,19 +489,20 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, float tot_weight = 0.0f; int inf_weight_flags = 0; - bwdata = MEM_callocN(sizeof(*bwdata), "SDefBindWeightData"); - if (bwdata == NULL) { + bwdata = static_cast(MEM_callocN(sizeof(*bwdata), "SDefBindWeightData")); + if (bwdata == nullptr) { data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; - return NULL; + return nullptr; } bwdata->polys_num = data->vert_edges[nearest].num / 2; - bpoly = MEM_calloc_arrayN(bwdata->polys_num, sizeof(*bpoly), "SDefBindPoly"); - if (bpoly == NULL) { + bpoly = static_cast( + MEM_calloc_arrayN(bwdata->polys_num, sizeof(*bpoly), "SDefBindPoly")); + if (bpoly == nullptr) { freeBindData(bwdata); data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; - return NULL; + return nullptr; } bwdata->bind_polys = bpoly; @@ -531,8 +532,8 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, int is_poly_valid; bpoly->index = edge_polys[edge_ind].polys[i]; - bpoly->coords = NULL; - bpoly->coords_v2 = NULL; + bpoly->coords = nullptr; + bpoly->coords_v2 = nullptr; /* Copy poly data */ poly = &data->mpoly[bpoly->index]; @@ -541,20 +542,20 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, bpoly->verts_num = poly->totloop; bpoly->loopstart = poly->loopstart; - bpoly->coords = MEM_malloc_arrayN( - poly->totloop, sizeof(*bpoly->coords), "SDefBindPolyCoords"); - if (bpoly->coords == NULL) { + bpoly->coords = static_cast( + MEM_malloc_arrayN(poly->totloop, sizeof(*bpoly->coords), "SDefBindPolyCoords")); + if (bpoly->coords == nullptr) { freeBindData(bwdata); data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; - return NULL; + return nullptr; } - bpoly->coords_v2 = MEM_malloc_arrayN( - poly->totloop, sizeof(*bpoly->coords_v2), "SDefBindPolyCoords_v2"); - if (bpoly->coords_v2 == NULL) { + bpoly->coords_v2 = static_cast( + MEM_malloc_arrayN(poly->totloop, sizeof(*bpoly->coords_v2), "SDefBindPolyCoords_v2")); + if (bpoly->coords_v2 == nullptr) { freeBindData(bwdata); data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; - return NULL; + return nullptr; } for (int j = 0; j < poly->totloop; j++, loop++) { @@ -595,7 +596,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, if (is_poly_valid != MOD_SDEF_BIND_RESULT_SUCCESS) { freeBindData(bwdata); data->success = is_poly_valid; - return NULL; + return nullptr; } bpoly->inside = isect_point_poly_v2( @@ -651,7 +652,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, bpoly->corner_edgemid_angles[1] < FLT_EPSILON) { freeBindData(bwdata); data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR; - return NULL; + return nullptr; } /* Check for infinite weights, and compute angular data otherwise. */ @@ -709,7 +710,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, bpoly->point_edgemid_angles[0] + bpoly->point_edgemid_angles[1] < FLT_EPSILON) { freeBindData(bwdata); data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR; - return NULL; + return nullptr; } } } @@ -783,7 +784,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, if (isnan(corner_angle_weights[0]) || isnan(corner_angle_weights[1])) { freeBindData(bwdata); data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR; - return NULL; + return nullptr; } /* Find which edge the point is closer to */ @@ -800,7 +801,7 @@ BLI_INLINE SDefBindWeightData *computeBindWeights(SDefBindCalcData *const data, if (bpoly->dominant_angle_weight < 0 || bpoly->dominant_angle_weight > 1) { freeBindData(bwdata); data->success = MOD_SDEF_BIND_RESULT_GENERIC_ERR; - return NULL; + return nullptr; } bpoly->dominant_angle_weight = sinf(bpoly->dominant_angle_weight * M_PI_2); @@ -940,7 +941,7 @@ BLI_INLINE float computeNormalDisplacement(const float point_co[3], static void bindVert(void *__restrict userdata, const int index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { SDefBindCalcData *const data = (SDefBindCalcData *)userdata; float point_co[3]; @@ -954,7 +955,7 @@ static void bindVert(void *__restrict userdata, sdvert->vertex_idx = index; if (data->success != MOD_SDEF_BIND_RESULT_SUCCESS) { - sdvert->binds = NULL; + sdvert->binds = nullptr; sdvert->binds_num = 0; return; } @@ -971,7 +972,7 @@ static void bindVert(void *__restrict userdata, } if (weight <= 0) { - sdvert->binds = NULL; + sdvert->binds = nullptr; sdvert->binds_num = 0; return; } @@ -980,14 +981,15 @@ static void bindVert(void *__restrict userdata, copy_v3_v3(point_co, data->vertexCos[index]); bwdata = computeBindWeights(data, point_co); - if (bwdata == NULL) { - sdvert->binds = NULL; + if (bwdata == nullptr) { + sdvert->binds = nullptr; sdvert->binds_num = 0; return; } - sdvert->binds = MEM_calloc_arrayN(bwdata->binds_num, sizeof(*sdvert->binds), "SDefVertBindData"); - if (sdvert->binds == NULL) { + sdvert->binds = static_cast( + MEM_calloc_arrayN(bwdata->binds_num, sizeof(*sdvert->binds), "SDefVertBindData")); + if (sdvert->binds == nullptr) { data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; sdvert->binds_num = 0; return; @@ -1008,16 +1010,16 @@ static void bindVert(void *__restrict userdata, sdbind->verts_num = bpoly->verts_num; sdbind->mode = MOD_SDEF_MODE_NGON; - sdbind->vert_weights = MEM_malloc_arrayN( - bpoly->verts_num, sizeof(*sdbind->vert_weights), "SDefNgonVertWeights"); - if (sdbind->vert_weights == NULL) { + sdbind->vert_weights = static_cast(MEM_malloc_arrayN( + bpoly->verts_num, sizeof(*sdbind->vert_weights), "SDefNgonVertWeights")); + if (sdbind->vert_weights == nullptr) { data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; return; } - sdbind->vert_inds = MEM_malloc_arrayN( - bpoly->verts_num, sizeof(*sdbind->vert_inds), "SDefNgonVertInds"); - if (sdbind->vert_inds == NULL) { + sdbind->vert_inds = static_cast( + MEM_malloc_arrayN(bpoly->verts_num, sizeof(*sdbind->vert_inds), "SDefNgonVertInds")); + if (sdbind->vert_inds == nullptr) { data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; return; } @@ -1048,16 +1050,16 @@ static void bindVert(void *__restrict userdata, sdbind->verts_num = bpoly->verts_num; sdbind->mode = MOD_SDEF_MODE_CENTROID; - sdbind->vert_weights = MEM_malloc_arrayN( - 3, sizeof(*sdbind->vert_weights), "SDefCentVertWeights"); - if (sdbind->vert_weights == NULL) { + sdbind->vert_weights = static_cast( + MEM_malloc_arrayN(3, sizeof(*sdbind->vert_weights), "SDefCentVertWeights")); + if (sdbind->vert_weights == nullptr) { data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; return; } - sdbind->vert_inds = MEM_malloc_arrayN( - bpoly->verts_num, sizeof(*sdbind->vert_inds), "SDefCentVertInds"); - if (sdbind->vert_inds == NULL) { + sdbind->vert_inds = static_cast( + MEM_malloc_arrayN(bpoly->verts_num, sizeof(*sdbind->vert_inds), "SDefCentVertInds")); + if (sdbind->vert_inds == nullptr) { data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; return; } @@ -1095,16 +1097,16 @@ static void bindVert(void *__restrict userdata, sdbind->verts_num = bpoly->verts_num; sdbind->mode = MOD_SDEF_MODE_LOOPTRI; - sdbind->vert_weights = MEM_malloc_arrayN( - 3, sizeof(*sdbind->vert_weights), "SDefTriVertWeights"); - if (sdbind->vert_weights == NULL) { + sdbind->vert_weights = static_cast( + MEM_malloc_arrayN(3, sizeof(*sdbind->vert_weights), "SDefTriVertWeights")); + if (sdbind->vert_weights == nullptr) { data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; return; } - sdbind->vert_inds = MEM_malloc_arrayN( - bpoly->verts_num, sizeof(*sdbind->vert_inds), "SDefTriVertInds"); - if (sdbind->vert_inds == NULL) { + sdbind->vert_inds = static_cast( + MEM_malloc_arrayN(bpoly->verts_num, sizeof(*sdbind->vert_inds), "SDefTriVertInds")); + if (sdbind->vert_inds == nullptr) { data->success = MOD_SDEF_BIND_RESULT_MEM_ERR; return; } @@ -1154,8 +1156,8 @@ static void compactSparseBinds(SurfaceDeformModifierData *smd) } } - smd->verts = MEM_reallocN_id( - smd->verts, sizeof(*smd->verts) * smd->bind_verts_num, "SDefBindVerts (sparse)"); + smd->verts = static_cast(MEM_reallocN_id( + smd->verts, sizeof(*smd->verts) * smd->bind_verts_num, "SDefBindVerts (sparse)")); } static bool surfacedeformBind(Object *ob, @@ -1168,51 +1170,52 @@ static bool surfacedeformBind(Object *ob, Mesh *target, Mesh *mesh) { - BVHTreeFromMesh treeData = {NULL}; + BVHTreeFromMesh treeData = {nullptr}; const float(*positions)[3] = BKE_mesh_vert_positions(target); const MPoly *mpoly = BKE_mesh_polys(target); const MEdge *medge = BKE_mesh_edges(target); const MLoop *mloop = BKE_mesh_loops(target); uint tedges_num = target->totedge; int adj_result; - SDefAdjacencyArray *vert_edges; - SDefAdjacency *adj_array; - SDefEdgePolys *edge_polys; - vert_edges = MEM_calloc_arrayN(target_verts_num, sizeof(*vert_edges), "SDefVertEdgeMap"); - if (vert_edges == NULL) { + SDefAdjacencyArray *vert_edges = static_cast( + MEM_calloc_arrayN(target_verts_num, sizeof(*vert_edges), "SDefVertEdgeMap")); + if (vert_edges == nullptr) { BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); return false; } - adj_array = MEM_malloc_arrayN(tedges_num, 2 * sizeof(*adj_array), "SDefVertEdge"); - if (adj_array == NULL) { + SDefAdjacency *adj_array = static_cast( + MEM_malloc_arrayN(tedges_num, 2 * sizeof(*adj_array), "SDefVertEdge")); + if (adj_array == nullptr) { BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); MEM_freeN(vert_edges); return false; } - edge_polys = MEM_calloc_arrayN(tedges_num, sizeof(*edge_polys), "SDefEdgeFaceMap"); - if (edge_polys == NULL) { + SDefEdgePolys *edge_polys = static_cast( + MEM_calloc_arrayN(tedges_num, sizeof(*edge_polys), "SDefEdgeFaceMap")); + if (edge_polys == nullptr) { BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); MEM_freeN(vert_edges); MEM_freeN(adj_array); return false; } - smd_orig->verts = MEM_malloc_arrayN(verts_num, sizeof(*smd_orig->verts), "SDefBindVerts"); - if (smd_orig->verts == NULL) { + smd_orig->verts = static_cast( + MEM_malloc_arrayN(verts_num, sizeof(*smd_orig->verts), "SDefBindVerts")); + if (smd_orig->verts == nullptr) { BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); freeAdjacencyMap(vert_edges, adj_array, edge_polys); return false; } BKE_bvhtree_from_mesh_get(&treeData, target, BVHTREE_FROM_LOOPTRI, 2); - if (treeData.tree == NULL) { + if (treeData.tree == nullptr) { BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); freeAdjacencyMap(vert_edges, adj_array, edge_polys); MEM_freeN(smd_orig->verts); - smd_orig->verts = NULL; + smd_orig->verts = nullptr; return false; } @@ -1225,7 +1228,7 @@ static bool surfacedeformBind(Object *ob, freeAdjacencyMap(vert_edges, adj_array, edge_polys); free_bvhtree_from_mesh(&treeData); MEM_freeN(smd_orig->verts); - smd_orig->verts = NULL; + smd_orig->verts = nullptr; return false; } @@ -1239,27 +1242,26 @@ static bool surfacedeformBind(Object *ob, const bool invert_vgroup = (smd_orig->flags & MOD_SDEF_INVERT_VGROUP) != 0; const bool sparse_bind = (smd_orig->flags & MOD_SDEF_SPARSE_BIND) != 0; - SDefBindCalcData data = { - .treeData = &treeData, - .vert_edges = vert_edges, - .edge_polys = edge_polys, - .mpoly = mpoly, - .medge = medge, - .mloop = mloop, - .looptri = BKE_mesh_runtime_looptri_ensure(target), - .targetCos = MEM_malloc_arrayN( - target_verts_num, sizeof(float[3]), "SDefTargetBindVertArray"), - .bind_verts = smd_orig->verts, - .vertexCos = vertexCos, - .falloff = smd_orig->falloff, - .success = MOD_SDEF_BIND_RESULT_SUCCESS, - .dvert = dvert, - .defgrp_index = defgrp_index, - .invert_vgroup = invert_vgroup, - .sparse_bind = sparse_bind, - }; + SDefBindCalcData data{}; + data.treeData = &treeData; + data.vert_edges = vert_edges; + data.edge_polys = edge_polys; + data.mpoly = mpoly; + data.medge = medge; + data.mloop = mloop; + data.looptri = BKE_mesh_runtime_looptri_ensure(target); + data.targetCos = static_cast( + MEM_malloc_arrayN(target_verts_num, sizeof(float[3]), "SDefTargetBindVertArray")); + data.bind_verts = smd_orig->verts; + data.vertexCos = vertexCos; + data.falloff = smd_orig->falloff; + data.success = MOD_SDEF_BIND_RESULT_SUCCESS; + data.dvert = dvert; + data.defgrp_index = defgrp_index; + data.invert_vgroup = invert_vgroup; + data.sparse_bind = sparse_bind; - if (data.targetCos == NULL) { + if (data.targetCos == nullptr) { BKE_modifier_set_error(ob, (ModifierData *)smd_eval, "Out of memory"); freeData((ModifierData *)smd_orig); return false; @@ -1324,7 +1326,7 @@ static bool surfacedeformBind(Object *ob, static void deformVert(void *__restrict userdata, const int index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { const SDefDeformData *const data = (SDefDeformData *)userdata; const SDefBind *sdbind = data->bind_verts[index].binds; @@ -1352,28 +1354,21 @@ static void deformVert(void *__restrict userdata, zero_v3(offset); - /* Allocate a `coords_buffer` that fits all the temp-data. */ int max_verts = 0; for (int j = 0; j < sdbind_num; j++) { max_verts = MAX2(max_verts, sdbind[j].verts_num); } - const bool big_buffer = max_verts > 256; - float(*coords_buffer)[3]; - - if (UNLIKELY(big_buffer)) { - coords_buffer = MEM_malloc_arrayN(max_verts, sizeof(*coords_buffer), __func__); - } - else { - coords_buffer = BLI_array_alloca(coords_buffer, max_verts); - } + /* Allocate a `coords_buffer` that fits all the temp-data. */ + blender::Array coords_buffer(max_verts); for (int j = 0; j < sdbind_num; j++, sdbind++) { for (int k = 0; k < sdbind->verts_num; k++) { copy_v3_v3(coords_buffer[k], data->targetCos[sdbind->vert_inds[k]]); } - normal_poly_v3(norm, coords_buffer, sdbind->verts_num); + normal_poly_v3( + norm, reinterpret_cast(coords_buffer.data()), sdbind->verts_num); zero_v3(temp); switch (sdbind->mode) { @@ -1396,7 +1391,8 @@ static void deformVert(void *__restrict userdata, /* ---------- centroid mode ---------- */ case MOD_SDEF_MODE_CENTROID: { float cent[3]; - mid_v3_v3_array(cent, coords_buffer, sdbind->verts_num); + mid_v3_v3_array( + cent, reinterpret_cast(coords_buffer.data()), sdbind->verts_num); madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[0]], sdbind->vert_weights[0]); madd_v3_v3fl(temp, data->targetCos[sdbind->vert_inds[1]], sdbind->vert_weights[1]); @@ -1415,10 +1411,6 @@ static void deformVert(void *__restrict userdata, /* Add the offset to start coord multiplied by the strength and weight values. */ madd_v3_v3fl(vertexCos, offset, data->strength * weight); - - if (UNLIKELY(big_buffer)) { - MEM_freeN(coords_buffer); - } } static void surfacedeformModifier_do(ModifierData *md, @@ -1434,7 +1426,7 @@ static void surfacedeformModifier_do(ModifierData *md, /* Exit function if bind flag is not set (free bind data if any). */ if (!(smd->flags & MOD_SDEF_BIND)) { - if (smd->verts != NULL) { + if (smd->verts != nullptr) { if (!DEG_is_active(ctx->depsgraph)) { BKE_modifier_set_error(ob, md, "Attempt to bind from inactive dependency graph"); return; @@ -1456,7 +1448,7 @@ static void surfacedeformModifier_do(ModifierData *md, target_polys_num = BKE_mesh_wrapper_poly_len(target); /* If not bound, execute bind. */ - if (smd->verts == NULL) { + if (smd->verts == nullptr) { if (!DEG_is_active(ctx->depsgraph)) { BKE_modifier_set_error(ob, md, "Attempt to unbind from inactive dependency graph"); return; @@ -1541,17 +1533,17 @@ static void surfacedeformModifier_do(ModifierData *md, const bool invert_vgroup = (smd->flags & MOD_SDEF_INVERT_VGROUP) != 0; /* Actual vertex location update starts here */ - SDefDeformData data = { - .bind_verts = smd->verts, - .targetCos = MEM_malloc_arrayN(target_verts_num, sizeof(float[3]), "SDefTargetVertArray"), - .vertexCos = vertexCos, - .dvert = dvert, - .defgrp_index = defgrp_index, - .invert_vgroup = invert_vgroup, - .strength = smd->strength, - }; + SDefDeformData data{}; + data.bind_verts = smd->verts; + data.targetCos = static_cast( + MEM_malloc_arrayN(target_verts_num, sizeof(float[3]), "SDefTargetVertArray")); + data.vertexCos = vertexCos; + data.dvert = dvert; + data.defgrp_index = defgrp_index; + data.invert_vgroup = invert_vgroup; + data.strength = smd->strength; - if (data.targetCos != NULL) { + if (data.targetCos != nullptr) { BKE_mesh_wrapper_vert_coords_copy_with_mat4( target, data.targetCos, target_verts_num, smd->mat); @@ -1571,48 +1563,48 @@ static void deformVerts(ModifierData *md, int verts_num) { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; - Mesh *mesh_src = NULL; + Mesh *mesh_src = nullptr; if (smd->defgrp_name[0] != '\0') { /* Only need to use mesh_src when a vgroup is used. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false); } surfacedeformModifier_do(md, ctx, vertexCos, verts_num, ctx->object, mesh_src); - if (!ELEM(mesh_src, NULL, mesh)) { - BKE_id_free(NULL, mesh_src); + if (!ELEM(mesh_src, nullptr, mesh)) { + BKE_id_free(nullptr, mesh_src); } } static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, - struct BMEditMesh *em, + BMEditMesh *em, Mesh *mesh, float (*vertexCos)[3], int verts_num) { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; - Mesh *mesh_src = NULL; + Mesh *mesh_src = nullptr; if (smd->defgrp_name[0] != '\0') { /* Only need to use mesh_src when a vgroup is used. */ - mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, NULL, verts_num, false); + mesh_src = MOD_deform_mesh_eval_get(ctx->object, em, mesh, nullptr, verts_num, false); } /* TODO(@campbellbarton): use edit-mode data only (remove this line). */ - if (mesh_src != NULL) { + if (mesh_src != nullptr) { BKE_mesh_wrapper_ensure_mdata(mesh_src); } surfacedeformModifier_do(md, ctx, vertexCos, verts_num, ctx->object, mesh_src); - if (!ELEM(mesh_src, NULL, mesh)) { - BKE_id_free(NULL, mesh_src); + if (!ELEM(mesh_src, nullptr, mesh)) { + BKE_id_free(nullptr, mesh_src); } } -static bool isDisabled(const Scene *UNUSED(scene), ModifierData *md, bool UNUSED(useRenderParams)) +static bool isDisabled(const Scene * /*scene*/, ModifierData *md, bool /*useRenderParams*/) { SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md; @@ -1621,11 +1613,11 @@ static bool isDisabled(const Scene *UNUSED(scene), ModifierData *md, bool UNUSED * * In other cases it should be impossible to have a type mismatch. */ - return (smd->target == NULL || smd->target->type != OB_MESH) && - !(smd->verts != NULL && !(smd->flags & MOD_SDEF_BIND)); + return (smd->target == nullptr || smd->target->type != OB_MESH) && + !(smd->verts != nullptr && !(smd->flags & MOD_SDEF_BIND)); } -static void panel_draw(const bContext *UNUSED(C), Panel *panel) +static void panel_draw(const bContext * /*C*/, Panel *panel) { uiLayout *col; uiLayout *layout = panel->layout; @@ -1641,17 +1633,17 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel) col = uiLayoutColumn(layout, false); uiLayoutSetActive(col, !is_bound); - uiItemR(col, ptr, "target", 0, NULL, ICON_NONE); - uiItemR(col, ptr, "falloff", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "target", 0, nullptr, ICON_NONE); + uiItemR(col, ptr, "falloff", 0, nullptr, ICON_NONE); - uiItemR(layout, ptr, "strength", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "strength", 0, nullptr, ICON_NONE); - modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL); + modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", nullptr); col = uiLayoutColumn(layout, false); uiLayoutSetEnabled(col, !is_bound); uiLayoutSetActive(col, !is_bound && RNA_string_length(ptr, "vertex_group") != 0); - uiItemR(col, ptr, "use_sparse_bind", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "use_sparse_bind", 0, nullptr, ICON_NONE); uiItemS(layout); @@ -1683,13 +1675,13 @@ static void blendWrite(BlendWriter *writer, const ID *id_owner, const ModifierDa /* Modifier coming from linked data cannot be bound from an override, so we can remove all * binding data, can save a significant amount of memory. */ smd.bind_verts_num = 0; - smd.verts = NULL; + smd.verts = nullptr; } } BLO_write_struct_at_address(writer, SurfaceDeformModifierData, md, &smd); - if (smd.verts != NULL) { + if (smd.verts != nullptr) { SDefVert *bind_verts = smd.verts; BLO_write_struct_array(writer, SDefVert, smd.bind_verts_num, bind_verts); @@ -1754,22 +1746,22 @@ ModifierTypeInfo modifierType_SurfaceDeform = { /*copyData*/ copyData, /*deformVerts*/ deformVerts, - /*deformMatrices*/ NULL, + /*deformMatrices*/ nullptr, /*deformVertsEM*/ deformVertsEM, - /*deformMatricesEM*/ NULL, - /*modifyMesh*/ NULL, - /*modifyGeometrySet*/ NULL, + /*deformMatricesEM*/ nullptr, + /*modifyMesh*/ nullptr, + /*modifyGeometrySet*/ nullptr, /*initData*/ initData, /*requiredDataMask*/ requiredDataMask, /*freeData*/ freeData, /*isDisabled*/ isDisabled, /*updateDepsgraph*/ updateDepsgraph, - /*dependsOnTime*/ NULL, - /*dependsOnNormals*/ NULL, + /*dependsOnTime*/ nullptr, + /*dependsOnNormals*/ nullptr, /*foreachIDLink*/ foreachIDLink, - /*foreachTexLink*/ NULL, - /*freeRuntimeData*/ NULL, + /*foreachTexLink*/ nullptr, + /*freeRuntimeData*/ nullptr, /*panelRegister*/ panelRegister, /*blendWrite*/ blendWrite, /*blendRead*/ blendRead, From bbeb37696d21e6c3461d7ae75dd4db932ce2dc6d Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Fri, 20 Jan 2023 11:43:28 +1300 Subject: [PATCH 0797/1522] Cleanup: format --- release/scripts/startup/bl_operators/wm.py | 2 +- source/blender/draw/intern/DRW_gpu_wrapper.hh | 3 ++- source/blender/geometry/intern/fillet_curves.cc | 9 ++++++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index cb881ad024e..e82694249fd 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1588,7 +1588,7 @@ class WM_OT_properties_edit(Operator): self.default_string = rna_data["default"] elif self.property_type in {'BOOL', 'BOOL_ARRAY'}: self.default_bool = self._convert_new_value_array(rna_data["default"], bool, 32) - + if self.property_type in {'FLOAT_ARRAY', 'INT_ARRAY', 'BOOL_ARRAY'}: self.array_length = len(item[name]) diff --git a/source/blender/draw/intern/DRW_gpu_wrapper.hh b/source/blender/draw/intern/DRW_gpu_wrapper.hh index 3e53f1510f6..0bb005dd160 100644 --- a/source/blender/draw/intern/DRW_gpu_wrapper.hh +++ b/source/blender/draw/intern/DRW_gpu_wrapper.hh @@ -1012,7 +1012,8 @@ class TextureRef : public Texture { * Dummy type to bind texture as image. * It is just a GPUTexture in disguise. */ -class Image {}; +class Image { +}; static inline Image *as_image(GPUTexture *tex) { diff --git a/source/blender/geometry/intern/fillet_curves.cc b/source/blender/geometry/intern/fillet_curves.cc index f666a6b6b40..0107eafba9d 100644 --- a/source/blender/geometry/intern/fillet_curves.cc +++ b/source/blender/geometry/intern/fillet_curves.cc @@ -39,7 +39,8 @@ static void duplicate_fillet_point_data(const bke::CurvesGeometry &src_curves, for (const int curve_i : curve_selection.slice(range)) { const IndexRange src_points = src_points_by_curve[curve_i]; const IndexRange dst_points = dst_points_by_curve[curve_i]; - const IndexRange offsets_range = bke::curves::per_curve_point_offsets_range(src_points, curve_i); + const IndexRange offsets_range = bke::curves::per_curve_point_offsets_range(src_points, + curve_i); const OffsetIndices offsets(all_point_offsets.slice(offsets_range)); threaded_slice_fill(src.slice(src_points), offsets, dst.slice(dst_points)); } @@ -75,7 +76,8 @@ static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int curve_i : selection.slice(range)) { const IndexRange src_points = points_by_curve[curve_i]; - const IndexRange offsets_range = bke::curves::per_curve_point_offsets_range(src_points, curve_i); + const IndexRange offsets_range = bke::curves::per_curve_point_offsets_range(src_points, + curve_i); MutableSpan point_offsets = dst_point_offsets.slice(offsets_range); MutableSpan point_counts = point_offsets.drop_back(1); @@ -456,7 +458,8 @@ static bke::CurvesGeometry fillet_curves( for (const int curve_i : curve_selection.slice(range)) { const IndexRange src_points = src_points_by_curve[curve_i]; - const IndexRange offsets_range = bke::curves::per_curve_point_offsets_range(src_points, curve_i); + const IndexRange offsets_range = bke::curves::per_curve_point_offsets_range(src_points, + curve_i); const OffsetIndices offsets(all_point_offsets.slice(offsets_range)); const IndexRange dst_points = dst_points_by_curve[curve_i]; const Span src_positions = positions.slice(src_points); From 203ab983ceb7d791eae6d702f614f596314026d7 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 16:55:37 -0600 Subject: [PATCH 0798/1522] Geometry Nodes: Rename node and socket for "Group ID" convention Based on discussion about T102962, rename the "Face Set Boundaries" node to "Face Group Boundaries" and the Accumulate Field node's "Group Index" socket to "Group ID". This convention of "__ Group" and "Group ID" will be used more in other nodes in the future. This commit doesn't affect forwards or backwards compatibility. --- source/blender/blenkernel/BKE_node.h | 2 +- source/blender/nodes/NOD_static_types.h | 2 +- source/blender/nodes/geometry/CMakeLists.txt | 2 +- .../nodes/geometry/node_geometry_register.cc | 2 +- .../nodes/geometry/node_geometry_register.hh | 2 +- .../geometry/nodes/node_geo_accumulate_field.cc | 4 ++-- ...c => node_geo_mesh_face_group_boundaries.cc} | 17 +++++++++-------- 7 files changed, 16 insertions(+), 15 deletions(-) rename source/blender/nodes/geometry/nodes/{node_geo_mesh_face_set_boundaries.cc => node_geo_mesh_face_group_boundaries.cc} (82%) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index dc5b1791bdb..d2f4c6e3b6e 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -1512,7 +1512,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i #define GEO_NODE_INPUT_SHORTEST_EDGE_PATHS 1168 #define GEO_NODE_EDGE_PATHS_TO_CURVES 1169 #define GEO_NODE_EDGE_PATHS_TO_SELECTION 1170 -#define GEO_NODE_MESH_FACE_SET_BOUNDARIES 1171 +#define GEO_NODE_MESH_FACE_GROUP_BOUNDARIES 1171 #define GEO_NODE_DISTRIBUTE_POINTS_IN_VOLUME 1172 #define GEO_NODE_SELF_OBJECT 1173 #define GEO_NODE_SAMPLE_INDEX 1174 diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 479700da7c9..b9f747b2e4f 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -358,7 +358,7 @@ DefNode(GeometryNode, GEO_NODE_JOIN_GEOMETRY, 0, "JOIN_GEOMETRY", JoinGeometry, DefNode(GeometryNode, GEO_NODE_MATERIAL_SELECTION, 0, "MATERIAL_SELECTION", MaterialSelection, "Material Selection", "Provide a selection of faces that use the specified material") DefNode(GeometryNode, GEO_NODE_MERGE_BY_DISTANCE, def_geo_merge_by_distance,"MERGE_BY_DISTANCE", MergeByDistance, "Merge by Distance", "Merge vertices or points within a given distance") DefNode(GeometryNode, GEO_NODE_MESH_BOOLEAN, def_geo_boolean, "MESH_BOOLEAN", MeshBoolean, "Mesh Boolean", "Cut, subtract, or join multiple mesh inputs") -DefNode(GeometryNode, GEO_NODE_MESH_FACE_SET_BOUNDARIES, 0, "MESH_FACE_SET_BOUNDARIES", MeshFaceSetBoundaries, "Face Set Boundaries", "Find edges on the boundaries between face sets") +DefNode(GeometryNode, GEO_NODE_MESH_FACE_GROUP_BOUNDARIES, 0, "MESH_FACE_SET_BOUNDARIES", MeshFaceSetBoundaries, "Face Group Boundaries", "Find edges on the boundaries between groups of faces with the same ID value") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CIRCLE, def_geo_mesh_circle, "MESH_PRIMITIVE_CIRCLE", MeshCircle, "Mesh Circle", "Generate a circular ring of edges") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CONE, def_geo_mesh_cone, "MESH_PRIMITIVE_CONE",MeshCone, "Cone", "Generate a cone mesh") DefNode(GeometryNode, GEO_NODE_MESH_PRIMITIVE_CUBE, 0, "MESH_PRIMITIVE_CUBE",MeshCube, "Cube", "Generate a cuboid mesh with variable side lengths and subdivisions") diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt index eecc79f2b12..8012b463a54 100644 --- a/source/blender/nodes/geometry/CMakeLists.txt +++ b/source/blender/nodes/geometry/CMakeLists.txt @@ -111,7 +111,7 @@ set(SRC nodes/node_geo_material_replace.cc nodes/node_geo_material_selection.cc nodes/node_geo_merge_by_distance.cc - nodes/node_geo_mesh_face_set_boundaries.cc + nodes/node_geo_mesh_face_group_boundaries.cc nodes/node_geo_mesh_primitive_circle.cc nodes/node_geo_mesh_primitive_cone.cc nodes/node_geo_mesh_primitive_cube.cc diff --git a/source/blender/nodes/geometry/node_geometry_register.cc b/source/blender/nodes/geometry/node_geometry_register.cc index 6305271ee8f..8d24d9bd732 100644 --- a/source/blender/nodes/geometry/node_geometry_register.cc +++ b/source/blender/nodes/geometry/node_geometry_register.cc @@ -95,7 +95,7 @@ void register_geometry_nodes() register_node_type_geo_material_replace(); register_node_type_geo_material_selection(); register_node_type_geo_merge_by_distance(); - register_node_type_geo_mesh_face_set_boundaries(); + register_node_type_geo_mesh_face_group_boundaries(); register_node_type_geo_mesh_primitive_circle(); register_node_type_geo_mesh_primitive_cone(); register_node_type_geo_mesh_primitive_cube(); diff --git a/source/blender/nodes/geometry/node_geometry_register.hh b/source/blender/nodes/geometry/node_geometry_register.hh index 213bec79045..ca64e7b9904 100644 --- a/source/blender/nodes/geometry/node_geometry_register.hh +++ b/source/blender/nodes/geometry/node_geometry_register.hh @@ -92,7 +92,7 @@ void register_node_type_geo_join_geometry(); void register_node_type_geo_material_replace(); void register_node_type_geo_material_selection(); void register_node_type_geo_merge_by_distance(); -void register_node_type_geo_mesh_face_set_boundaries(); +void register_node_type_geo_mesh_face_group_boundaries(); void register_node_type_geo_mesh_primitive_circle(); void register_node_type_geo_mesh_primitive_cone(); void register_node_type_geo_mesh_primitive_cube(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc b/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc index 1293dd9c0d2..f7a8496868e 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_accumulate_field.cc @@ -34,7 +34,7 @@ static void node_declare(NodeDeclarationBuilder &b) .default_value(1) .supports_field() .description(N_(value_in_description)); - b.add_input(N_("Group Index")) + b.add_input(N_("Group ID"), "Group Index") .supports_field() .description( N_("An index used to group values together for multiple separate accumulations")); @@ -182,7 +182,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) 0); params.add_item( - IFACE_("Group Index"), + IFACE_("Group ID"), [type](LinkSearchOpParams ¶ms) { bNode &node = params.add_node("GeometryNodeAccumulateField"); node_storage(node).data_type = *type; diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_group_boundaries.cc similarity index 82% rename from source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc rename to source/blender/nodes/geometry/nodes/node_geo_mesh_face_group_boundaries.cc index aedd77b0653..a2befdb31b2 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_face_set_boundaries.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_face_group_boundaries.cc @@ -7,11 +7,11 @@ #include "node_geometry_util.hh" -namespace blender::nodes::node_geo_mesh_face_set_boundaries_cc { +namespace blender::nodes::node_geo_mesh_face_group_boundaries_cc { static void node_declare(NodeDeclarationBuilder &b) { - b.add_input(N_("Face Set")) + b.add_input(N_("Face Group ID"), "Face Set") .default_value(0) .hide_value() .supports_field() @@ -19,7 +19,7 @@ static void node_declare(NodeDeclarationBuilder &b) "same value are in the same region")); b.add_output(N_("Boundary Edges")) .field_source_reference_all() - .description(N_("The edges that lie on the boundaries between the different face sets")); + .description(N_("The edges that lie on the boundaries between the different face groups")); } class BoundaryFieldInput final : public bke::MeshFieldInput { @@ -28,7 +28,7 @@ class BoundaryFieldInput final : public bke::MeshFieldInput { public: BoundaryFieldInput(const Field face_set) - : bke::MeshFieldInput(CPPType::get(), "Boundary Field"), face_set_(face_set) + : bke::MeshFieldInput(CPPType::get(), "Face Group Boundaries"), face_set_(face_set) { category_ = Category::Generated; } @@ -84,15 +84,16 @@ static void node_geo_exec(GeoNodeExecParams params) params.set_output("Boundary Edges", std::move(face_set_boundaries)); } -} // namespace blender::nodes::node_geo_mesh_face_set_boundaries_cc +} // namespace blender::nodes::node_geo_mesh_face_group_boundaries_cc -void register_node_type_geo_mesh_face_set_boundaries() +void register_node_type_geo_mesh_face_group_boundaries() { - namespace file_ns = blender::nodes::node_geo_mesh_face_set_boundaries_cc; + namespace file_ns = blender::nodes::node_geo_mesh_face_group_boundaries_cc; static bNodeType ntype; geo_node_type_base( - &ntype, GEO_NODE_MESH_FACE_SET_BOUNDARIES, "Face Set Boundaries", NODE_CLASS_INPUT); + &ntype, GEO_NODE_MESH_FACE_GROUP_BOUNDARIES, "Face Group Boundaries", NODE_CLASS_INPUT); + node_type_size_preset(&ntype, NODE_SIZE_MIDDLE); ntype.declare = file_ns::node_declare; ntype.geometry_node_execute = file_ns::node_geo_exec; nodeRegisterType(&ntype); From 241d87e9f41983daf757cbd126e35f0910c3a094 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 17:43:55 -0600 Subject: [PATCH 0799/1522] Curves: Add RNA access to evaluated normals per control point Add an RNA API function that gives an array of the normals for every control point. The normals depend on the `normal_mode` attribute, which can currently be minumum twist or Z-up, though more options are planned. Normals are currently evaluated on the evaluated points and then sampled back to the control points. Because that can be expensive, a normal mode that only does a first evaluation on control points may be important The function is intended to be used by Cycles, so it doesn't have to implement the calculation of normals itself. They can be interpolated between control points and normalized. For best performance, the function should only be called once, since it does the full calculation for every control point every time it is called. Differential Revision: https://developer.blender.org/D17024 --- source/blender/editors/curves/CMakeLists.txt | 1 + .../editors/curves/intern/curves_data.cc | 23 ++++++++++ source/blender/editors/include/ED_curves.h | 14 +++++++ source/blender/makesrna/intern/rna_curves.c | 42 +++++++++++++++++++ source/blender/makesrna/intern/rna_mesh.c | 2 +- 5 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 source/blender/editors/curves/intern/curves_data.cc diff --git a/source/blender/editors/curves/CMakeLists.txt b/source/blender/editors/curves/CMakeLists.txt index 4d81b4454ac..bba85f9c77a 100644 --- a/source/blender/editors/curves/CMakeLists.txt +++ b/source/blender/editors/curves/CMakeLists.txt @@ -21,6 +21,7 @@ set(INC set(SRC intern/curves_add.cc + intern/curves_data.cc intern/curves_ops.cc intern/curves_selection.cc ) diff --git a/source/blender/editors/curves/intern/curves_data.cc b/source/blender/editors/curves/intern/curves_data.cc new file mode 100644 index 00000000000..bcec7156bf3 --- /dev/null +++ b/source/blender/editors/curves/intern/curves_data.cc @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BKE_curves.hh" +#include "BKE_geometry_fields.hh" + +#include "ED_curves.h" + +float (*ED_curves_point_normals_array_create(const Curves *curves_id))[3] +{ + using namespace blender; + const bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry); + const int size = curves.points_num(); + + float3 *data = static_cast(MEM_malloc_arrayN(size, sizeof(float3), __func__)); + + const bke::CurvesFieldContext context(curves, ATTR_DOMAIN_POINT); + fn::FieldEvaluator evaluator(context, size); + fn::Field field(std::make_shared()); + evaluator.add_with_destination(std::move(field), {data, size}); + evaluator.evaluate(); + + return reinterpret_cast(data); +} diff --git a/source/blender/editors/include/ED_curves.h b/source/blender/editors/include/ED_curves.h index 7d2bad635b5..bf6b78676b9 100644 --- a/source/blender/editors/include/ED_curves.h +++ b/source/blender/editors/include/ED_curves.h @@ -7,13 +7,27 @@ #pragma once struct bContext; +struct Curves; #ifdef __cplusplus extern "C" { #endif +/* -------------------------------------------------------------------- */ +/** \name C Wrappers + * \{ */ + void ED_operatortypes_curves(void); +/** + * Return an owning pointer to an array of point normals the same size as the number of control + * points. The normals depend on the normal mode for each curve and the "tilt" attribute and may be + * calculated for the evaluated points and sampled back to the control points. + */ +float (*ED_curves_point_normals_array_create(const struct Curves *curves_id))[3]; + +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/makesrna/intern/rna_curves.c b/source/blender/makesrna/intern/rna_curves.c index 3db4695a9b9..7560e1a60cb 100644 --- a/source/blender/makesrna/intern/rna_curves.c +++ b/source/blender/makesrna/intern/rna_curves.c @@ -50,6 +50,8 @@ const EnumPropertyItem rna_enum_curve_normal_modes[] = { # include "DEG_depsgraph.h" +# include "ED_curves.h" + # include "WM_api.h" # include "WM_types.h" @@ -217,6 +219,14 @@ static void rna_CurveSlice_points_begin(CollectionPropertyIterator *iter, Pointe rna_iterator_array_begin(iter, co, sizeof(float[3]), size, 0, NULL); } +static void rna_Curves_normals_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + Curves *curves = rna_curves(ptr); + float(*positions)[3] = ED_curves_point_normals_array_create(curves); + const int size = curves->geometry.point_num; + rna_iterator_array_begin(iter, positions, sizeof(float[3]), size, true, NULL); +} + static void rna_Curves_update_data(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene), PointerRNA *ptr) @@ -268,6 +278,20 @@ static void rna_def_curves_point(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Index", "Index of this points"); } +/* Defines a read-only vector type since normals can not be modified manually. */ +static void rna_def_read_only_float_vector(BlenderRNA *brna) +{ + StructRNA *srna = RNA_def_struct(brna, "FloatVectorValueReadOnly", NULL); + RNA_def_struct_sdna(srna, "vec3f"); + RNA_def_struct_ui_text(srna, "Read-Only Vector", ""); + + PropertyRNA *prop = RNA_def_property(srna, "vector", PROP_FLOAT, PROP_DIRECTION); + RNA_def_property_ui_text(prop, "Vector", "3D vector"); + RNA_def_property_float_sdna(prop, NULL, "x"); + RNA_def_property_array(prop, 3); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); +} + static void rna_def_curves_curve(BlenderRNA *brna) { StructRNA *srna; @@ -365,6 +389,24 @@ static void rna_def_curves(BlenderRNA *brna) NULL); RNA_def_property_update(prop, 0, "rna_Curves_update_data"); + rna_def_read_only_float_vector(brna); + + prop = RNA_def_property(srna, "normals", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "FloatVectorValueReadOnly"); + /* `lookup_int` isn't provided since the entire normals array is allocated and calculated when + * it's accessed. */ + RNA_def_property_collection_funcs(prop, + "rna_Curves_normals_begin", + "rna_iterator_array_next", + "rna_iterator_array_end", + "rna_iterator_array_get", + "rna_Curves_position_data_length", + NULL, + NULL, + NULL); + RNA_def_property_ui_text( + prop, "Normals", "The curve normal value at each of the curve's control points"); + /* materials */ prop = RNA_def_property(srna, "materials", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "mat", "totcol"); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index f1247c551a0..7c8e7431652 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -3239,7 +3239,7 @@ static void rna_def_mesh_polygons(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } -/* Defines a read-only vector type since normals should not be modified manually. */ +/* Defines a read-only vector type since normals can not be modified manually. */ static void rna_def_normal_layer_value(BlenderRNA *brna) { StructRNA *srna = RNA_def_struct(brna, "MeshNormalValue", NULL); From 05bdef7ce64fe3125b95d72d80f1f4f60c2b1274 Mon Sep 17 00:00:00 2001 From: Jeffrey Liu Date: Thu, 19 Jan 2023 18:22:47 -0600 Subject: [PATCH 0800/1522] Fix T103094: Cycles ignores small suns in Nishita sky The background evaluation samples the sky discretely, so if the sun is too small, it can be missed in the evaluation. To solve this, the sun is ignored during the background evaluation and its contribution is computed separately. --- intern/cycles/kernel/bake/bake.h | 5 +- .../cycles/kernel/integrator/shade_surface.h | 1 - .../cycles/kernel/integrator/shade_volume.h | 1 - .../kernel/osl/shaders/node_sky_texture.osl | 5 +- intern/cycles/kernel/svm/sky.h | 17 +++-- intern/cycles/kernel/svm/svm.h | 2 +- intern/cycles/kernel/types.h | 46 +++++++------- intern/cycles/scene/light.cpp | 15 ++++- intern/cycles/scene/osl.cpp | 18 +++--- intern/cycles/scene/shader_nodes.cpp | 62 +++++++++++++++++++ intern/cycles/scene/shader_nodes.h | 2 + release/scripts/addons | 2 +- 12 files changed, 130 insertions(+), 46 deletions(-) diff --git a/intern/cycles/kernel/bake/bake.h b/intern/cycles/kernel/bake/bake.h index 384ca9168f0..899aa783289 100644 --- a/intern/cycles/kernel/bake/bake.h +++ b/intern/cycles/kernel/bake/bake.h @@ -63,8 +63,9 @@ ccl_device void kernel_background_evaluate(KernelGlobals kg, shader_setup_from_background(kg, &sd, ray_P, ray_D, ray_time); /* Evaluate shader. - * This is being evaluated for all BSDFs, so path flag does not contain a specific type. */ - const uint32_t path_flag = PATH_RAY_EMISSION; + * This is being evaluated for all BSDFs, so path flag does not contain a specific type. + * However, we want to flag the ray visibility to ignore the sun in the background map. */ + const uint32_t path_flag = PATH_RAY_EMISSION | PATH_RAY_IMPORTANCE_BAKE; surface_shader_eval( kg, INTEGRATOR_STATE_NULL, &sd, NULL, path_flag); diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 21a6f2d4e36..09433caa063 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -264,7 +264,6 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg, /* Copy state from main path to shadow path. */ uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag); - shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0; const Spectrum unlit_throughput = INTEGRATOR_STATE(state, path, throughput); const Spectrum throughput = unlit_throughput * bsdf_eval_sum(&bsdf_eval); diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h index 75962ce5499..98dc5603a78 100644 --- a/intern/cycles/kernel/integrator/shade_volume.h +++ b/intern/cycles/kernel/integrator/shade_volume.h @@ -838,7 +838,6 @@ ccl_device_forceinline void integrate_volume_direct_light( const uint16_t bounce = INTEGRATOR_STATE(state, path, bounce); const uint16_t transparent_bounce = INTEGRATOR_STATE(state, path, transparent_bounce); uint32_t shadow_flag = INTEGRATOR_STATE(state, path, flag); - shadow_flag |= (is_light) ? PATH_RAY_SHADOW_FOR_LIGHT : 0; const Spectrum throughput_phase = throughput * bsdf_eval_sum(&phase_eval); if (kernel_data.kernel_features & KERNEL_FEATURE_LIGHT_PASSES) { diff --git a/intern/cycles/kernel/osl/shaders/node_sky_texture.osl b/intern/cycles/kernel/osl/shaders/node_sky_texture.osl index 1373db04a31..763f73a35d7 100644 --- a/intern/cycles/kernel/osl/shaders/node_sky_texture.osl +++ b/intern/cycles/kernel/osl/shaders/node_sky_texture.osl @@ -135,8 +135,9 @@ color sky_radiance_nishita(vector dir, float nishita_data[10], string filename) float half_angular = angular_diameter / 2.0; float dir_elevation = M_PI_2 - direction[0]; - /* if ray inside sun disc render it, otherwise render sky */ - if (sun_dir_angle < half_angular && sun_disc == 1) { + /* if ray inside sun disc render it, otherwise render sky. + * alternatively, ignore the sun if we're evaluating the background texture. */ + if (sun_dir_angle < half_angular && sun_disc == 1 && raytype("importance_bake") != 1) { /* get 2 pixels data */ color pixel_bottom = color(nishita_data[0], nishita_data[1], nishita_data[2]); color pixel_top = color(nishita_data[3], nishita_data[4], nishita_data[5]); diff --git a/intern/cycles/kernel/svm/sky.h b/intern/cycles/kernel/svm/sky.h index 1638e783a69..92b292d660d 100644 --- a/intern/cycles/kernel/svm/sky.h +++ b/intern/cycles/kernel/svm/sky.h @@ -118,6 +118,7 @@ ccl_device float3 geographical_to_direction(float lat, float lon) ccl_device float3 sky_radiance_nishita(KernelGlobals kg, float3 dir, + uint32_t path_flag, float3 pixel_bottom, float3 pixel_top, ccl_private float *nishita_data, @@ -140,8 +141,9 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals kg, float half_angular = angular_diameter / 2.0f; float dir_elevation = M_PI_2_F - direction.x; - /* if ray inside sun disc render it, otherwise render sky */ - if (sun_disc && sun_dir_angle < half_angular) { + /* if ray inside sun disc render it, otherwise render sky. + * alternatively, ignore the sun if we're evaluating the background texture. */ + if (sun_disc && sun_dir_angle < half_angular && !(path_flag & PATH_RAY_IMPORTANCE_BAKE)) { /* get 2 pixels data */ float y; @@ -197,8 +199,12 @@ ccl_device float3 sky_radiance_nishita(KernelGlobals kg, return xyz_to_rgb_clamped(kg, xyz); } -ccl_device_noinline int svm_node_tex_sky( - KernelGlobals kg, ccl_private ShaderData *sd, ccl_private float *stack, uint4 node, int offset) +ccl_device_noinline int svm_node_tex_sky(KernelGlobals kg, + ccl_private ShaderData *sd, + uint32_t path_flag, + ccl_private float *stack, + uint4 node, + int offset) { /* Load data */ uint dir_offset = node.y; @@ -310,7 +316,8 @@ ccl_device_noinline int svm_node_tex_sky( uint texture_id = __float_as_uint(data.z); /* Compute Sky */ - f = sky_radiance_nishita(kg, dir, pixel_bottom, pixel_top, nishita_data, texture_id); + f = sky_radiance_nishita( + kg, dir, path_flag, pixel_bottom, pixel_top, nishita_data, texture_id); } stack_store_float3(stack, out_offset, f); diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h index 3ca632c5f0b..96b2b82d8af 100644 --- a/intern/cycles/kernel/svm/svm.h +++ b/intern/cycles/kernel/svm/svm.h @@ -463,7 +463,7 @@ ccl_device void svm_eval_nodes(KernelGlobals kg, svm_node_tex_environment(kg, sd, stack, node); break; SVM_CASE(NODE_TEX_SKY) - offset = svm_node_tex_sky(kg, sd, stack, node, offset); + offset = svm_node_tex_sky(kg, sd, path_flag, stack, node, offset); break; SVM_CASE(NODE_TEX_GRADIENT) svm_node_tex_gradient(sd, stack, node); diff --git a/intern/cycles/kernel/types.h b/intern/cycles/kernel/types.h index 4075980076f..4fad62d757d 100644 --- a/intern/cycles/kernel/types.h +++ b/intern/cycles/kernel/types.h @@ -206,23 +206,24 @@ enum PathRayFlag : uint32_t { PATH_RAY_SINGULAR = (1U << 5U), PATH_RAY_TRANSPARENT = (1U << 6U), PATH_RAY_VOLUME_SCATTER = (1U << 7U), + PATH_RAY_IMPORTANCE_BAKE = (1U << 8U), /* Shadow ray visibility. */ - PATH_RAY_SHADOW_OPAQUE = (1U << 8U), - PATH_RAY_SHADOW_TRANSPARENT = (1U << 9U), + PATH_RAY_SHADOW_OPAQUE = (1U << 9U), + PATH_RAY_SHADOW_TRANSPARENT = (1U << 10U), PATH_RAY_SHADOW = (PATH_RAY_SHADOW_OPAQUE | PATH_RAY_SHADOW_TRANSPARENT), /* Subset of flags used for ray visibility for intersection. * * NOTE: SHADOW_CATCHER macros below assume there are no more than * 16 visibility bits. */ - PATH_RAY_ALL_VISIBILITY = ((1U << 10U) - 1U), + PATH_RAY_ALL_VISIBILITY = ((1U << 11U) - 1U), /* Special flag to tag unaligned BVH nodes. * Only set and used in BVH nodes to distinguish how to interpret bounding box information stored * in the node (either it should be intersected as AABB or as OBBU). * So this can overlap with path flags. */ - PATH_RAY_NODE_UNALIGNED = (1U << 10U), + PATH_RAY_NODE_UNALIGNED = (1U << 11U), /* -------------------------------------------------------------------- * Path flags. @@ -230,60 +231,59 @@ enum PathRayFlag : uint32_t { /* Surface had transmission component at previous bounce. Used for light tree * traversal and culling to be consistent with MIS PDF at the next bounce. */ - PATH_RAY_MIS_HAD_TRANSMISSION = (1U << 10U), + PATH_RAY_MIS_HAD_TRANSMISSION = (1U << 11U), /* Don't apply multiple importance sampling weights to emission from * lamp or surface hits, because they were not direct light sampled. */ - PATH_RAY_MIS_SKIP = (1U << 11U), + PATH_RAY_MIS_SKIP = (1U << 12U), /* Diffuse bounce earlier in the path, skip SSS to improve performance * and avoid branching twice with disk sampling SSS. */ - PATH_RAY_DIFFUSE_ANCESTOR = (1U << 12U), + PATH_RAY_DIFFUSE_ANCESTOR = (1U << 13U), /* Single pass has been written. */ - PATH_RAY_SINGLE_PASS_DONE = (1U << 13U), + PATH_RAY_SINGLE_PASS_DONE = (1U << 14U), /* Zero background alpha, for camera or transparent glass rays. */ - PATH_RAY_TRANSPARENT_BACKGROUND = (1U << 14U), + PATH_RAY_TRANSPARENT_BACKGROUND = (1U << 15U), /* Terminate ray immediately at next bounce. */ - PATH_RAY_TERMINATE_ON_NEXT_SURFACE = (1U << 15U), - PATH_RAY_TERMINATE_IN_NEXT_VOLUME = (1U << 16U), + PATH_RAY_TERMINATE_ON_NEXT_SURFACE = (1U << 16U), + PATH_RAY_TERMINATE_IN_NEXT_VOLUME = (1U << 17U), /* Ray is to be terminated, but continue with transparent bounces and * emission as long as we encounter them. This is required to make the * MIS between direct and indirect light rays match, as shadow rays go * through transparent surfaces to reach emission too. */ - PATH_RAY_TERMINATE_AFTER_TRANSPARENT = (1U << 17U), + PATH_RAY_TERMINATE_AFTER_TRANSPARENT = (1U << 18U), /* Terminate ray immediately after volume shading. */ - PATH_RAY_TERMINATE_AFTER_VOLUME = (1U << 18U), + PATH_RAY_TERMINATE_AFTER_VOLUME = (1U << 19U), /* Ray is to be terminated. */ PATH_RAY_TERMINATE = (PATH_RAY_TERMINATE_ON_NEXT_SURFACE | PATH_RAY_TERMINATE_IN_NEXT_VOLUME | PATH_RAY_TERMINATE_AFTER_TRANSPARENT | PATH_RAY_TERMINATE_AFTER_VOLUME), /* Path and shader is being evaluated for direct lighting emission. */ - PATH_RAY_EMISSION = (1U << 19U), + PATH_RAY_EMISSION = (1U << 20U), /* Perform subsurface scattering. */ - PATH_RAY_SUBSURFACE_RANDOM_WALK = (1U << 20U), - PATH_RAY_SUBSURFACE_DISK = (1U << 21U), - PATH_RAY_SUBSURFACE_USE_FRESNEL = (1U << 22U), - PATH_RAY_SUBSURFACE_BACKFACING = (1U << 23U), + PATH_RAY_SUBSURFACE_RANDOM_WALK = (1U << 21U), + PATH_RAY_SUBSURFACE_DISK = (1U << 22U), + PATH_RAY_SUBSURFACE_USE_FRESNEL = (1U << 23U), + PATH_RAY_SUBSURFACE_BACKFACING = (1U << 24U), PATH_RAY_SUBSURFACE = (PATH_RAY_SUBSURFACE_RANDOM_WALK | PATH_RAY_SUBSURFACE_DISK | PATH_RAY_SUBSURFACE_USE_FRESNEL | PATH_RAY_SUBSURFACE_BACKFACING), /* Contribute to denoising features. */ - PATH_RAY_DENOISING_FEATURES = (1U << 24U), + PATH_RAY_DENOISING_FEATURES = (1U << 25U), /* Render pass categories. */ - PATH_RAY_SURFACE_PASS = (1U << 25U), - PATH_RAY_VOLUME_PASS = (1U << 26U), + PATH_RAY_SURFACE_PASS = (1U << 26U), + PATH_RAY_VOLUME_PASS = (1U << 27U), PATH_RAY_ANY_PASS = (PATH_RAY_SURFACE_PASS | PATH_RAY_VOLUME_PASS), - /* Shadow ray is for a light or surface, or AO. */ - PATH_RAY_SHADOW_FOR_LIGHT = (1U << 27U), + /* Shadow ray is for AO. */ PATH_RAY_SHADOW_FOR_AO = (1U << 28U), /* A shadow catcher object was hit and the path was split into two. */ diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index 9070c444f63..92649563ebd 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -721,6 +721,7 @@ void LightManager::device_update_background(Device *device, int2 environment_res = make_int2(0, 0); Shader *shader = scene->background->get_shader(scene); int num_suns = 0; + float sun_average_radiance = 0.0f; foreach (ShaderNode *node, shader->graph->nodes) { if (node->type == EnvironmentTextureNode::get_node_type()) { EnvironmentTextureNode *env = (EnvironmentTextureNode *)node; @@ -762,6 +763,7 @@ void LightManager::device_update_background(Device *device, /* empirical value */ kbackground->sun_weight = 4.0f; + sun_average_radiance = sky->get_sun_average_radiance(); environment_res.x = max(environment_res.x, 512); environment_res.y = max(environment_res.y, 256); num_suns++; @@ -830,7 +832,18 @@ void LightManager::device_update_background(Device *device, float cdf_total = marg_cdf[res.y - 1].y + marg_cdf[res.y - 1].x / res.y; marg_cdf[res.y].x = cdf_total; - background_light->set_average_radiance(cdf_total * M_PI_2_F); + float map_average_radiance = cdf_total * M_PI_2_F; + if (sun_average_radiance > 0.0f) { + /* The weighting here is just a heuristic that was empirically determined. + * The sun's average radiance is much higher than the map's average radiance, + * but we don't want to weight the background light too much becaused + * visibility is not accounted for anyways. */ + background_light->set_average_radiance(0.8f * map_average_radiance + + 0.2f * sun_average_radiance); + } + else { + background_light->set_average_radiance(map_average_radiance); + } if (cdf_total > 0.0f) for (int i = 1; i < res.y; i++) diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp index 335e72bec40..73a8553c5d5 100644 --- a/intern/cycles/scene/osl.cpp +++ b/intern/cycles/scene/osl.cpp @@ -305,14 +305,15 @@ void OSLShaderManager::shading_system_init() /* our own ray types */ static const char *raytypes[] = { - "camera", /* PATH_RAY_CAMERA */ - "reflection", /* PATH_RAY_REFLECT */ - "refraction", /* PATH_RAY_TRANSMIT */ - "diffuse", /* PATH_RAY_DIFFUSE */ - "glossy", /* PATH_RAY_GLOSSY */ - "singular", /* PATH_RAY_SINGULAR */ - "transparent", /* PATH_RAY_TRANSPARENT */ - "volume_scatter", /* PATH_RAY_VOLUME_SCATTER */ + "camera", /* PATH_RAY_CAMERA */ + "reflection", /* PATH_RAY_REFLECT */ + "refraction", /* PATH_RAY_TRANSMIT */ + "diffuse", /* PATH_RAY_DIFFUSE */ + "glossy", /* PATH_RAY_GLOSSY */ + "singular", /* PATH_RAY_SINGULAR */ + "transparent", /* PATH_RAY_TRANSPARENT */ + "volume_scatter", /* PATH_RAY_VOLUME_SCATTER */ + "importance_bake", /* PATH_RAY_IMPORTANCE_BAKE */ "shadow", /* PATH_RAY_SHADOW_OPAQUE */ "shadow", /* PATH_RAY_SHADOW_TRANSPARENT */ @@ -341,7 +342,6 @@ void OSLShaderManager::shading_system_init() "__unused__", "__unused__", "__unused__", - "__unused__", }; const int nraytypes = sizeof(raytypes) / sizeof(raytypes[0]); diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp index 8cd64cd189e..1b7d66eeff1 100644 --- a/intern/cycles/scene/shader_nodes.cpp +++ b/intern/cycles/scene/shader_nodes.cpp @@ -779,6 +779,68 @@ static void sky_texture_precompute_nishita(SunSky *sunsky, sunsky->nishita_data[9] = sun_intensity; } +float SkyTextureNode::get_sun_average_radiance() +{ + float clamped_altitude = clamp(altitude, 1.0f, 59999.0f); + float angular_diameter = get_sun_size(); + + float pix_bottom[3]; + float pix_top[3]; + SKY_nishita_skymodel_precompute_sun(sun_elevation, + angular_diameter, + clamped_altitude, + air_density, + dust_density, + pix_bottom, + pix_top); + + /* Approximate the direction's elevation as the sun's elevation. */ + float dir_elevation = sun_elevation; + float half_angular = angular_diameter / 2.0f; + float3 pixel_bottom = make_float3(pix_bottom[0], pix_bottom[1], pix_bottom[2]); + float3 pixel_top = make_float3(pix_top[0], pix_top[1], pix_top[2]); + + /* Same code as in the sun evaluation shader. */ + float3 xyz = make_float3(0.0f, 0.0f, 0.0f); + float y = 0.0f; + if (sun_elevation - half_angular > 0.0f) { + if (sun_elevation + half_angular > 0.0f) { + y = ((dir_elevation - sun_elevation) / angular_diameter) + 0.5f; + xyz = interp(pixel_bottom, pixel_top, y) * sun_intensity; + } + } + else { + if (sun_elevation + half_angular > 0.0f) { + y = dir_elevation / (sun_elevation + half_angular); + xyz = interp(pixel_bottom, pixel_top, y) * sun_intensity; + } + } + + /* We first approximate the sun's contribution by + * multiplying the evaluated point by the square of the angular diameter. + * Then we scale the approximation using a piecewise function (determined empirically). */ + float sun_contribution = average(xyz) * sqr(angular_diameter); + + float first_point = 0.8f / 180.0f * M_PI_F; + float second_point = 1.0f / 180.0f * M_PI_F; + float third_point = M_PI_2_F; + if (angular_diameter < first_point) { + sun_contribution *= 1.0f; + } + else if (angular_diameter < second_point) { + float diff = angular_diameter - first_point; + float slope = (0.8f - 1.0f) / (second_point - first_point); + sun_contribution *= 1.0f + slope * diff; + } + else { + float diff = angular_diameter - 1.0f / 180.0f * M_PI_F; + float slope = (0.45f - 0.8f) / (third_point - second_point); + sun_contribution *= 0.8f + slope * diff; + } + + return sun_contribution; +} + NODE_DEFINE(SkyTextureNode) { NodeType *type = NodeType::add("sky_texture", create, NodeType::SHADER); diff --git a/intern/cycles/scene/shader_nodes.h b/intern/cycles/scene/shader_nodes.h index fa9210ff5cc..35c5a7a61ac 100644 --- a/intern/cycles/scene/shader_nodes.h +++ b/intern/cycles/scene/shader_nodes.h @@ -174,6 +174,8 @@ class SkyTextureNode : public TextureNode { /* Clamping for numerical precision. */ return fmaxf(sun_size, 0.0005f); } + + float get_sun_average_radiance(); }; class OutputNode : public ShaderNode { diff --git a/release/scripts/addons b/release/scripts/addons index 6fcd157f249..c0a678d3686 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 6fcd157f2497d9ba4ba82191cb2abf3de11a0394 +Subproject commit c0a678d3686a591eb3041cc72b60aec2857d389a From 9889918fd4de7a8db9702628de787c840673d85b Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 19 Jan 2023 16:53:43 -0800 Subject: [PATCH 0801/1522] Sculpt: New API for keeping track of topology islands Mesh islands (shells) are now calculated on an as-needed basis and cached inside of a temp attribute, `sculpt_topology_island_key`. This attribute is updated as needed when geometry changes (e.g. the trim brush) or when mesh visibility changes. This replaces the old behavior where the "topology" automasking mode would walk the entire mesh on every stroke. --- source/blender/blenkernel/BKE_paint.h | 3 + source/blender/blenkernel/BKE_pbvh.h | 22 ++++++ .../blender/editors/sculpt_paint/paint_hide.c | 2 + .../blender/editors/sculpt_paint/paint_mask.c | 1 + source/blender/editors/sculpt_paint/sculpt.cc | 77 +++++++++++++++++++ .../sculpt_paint/sculpt_automasking.cc | 49 +++--------- .../editors/sculpt_paint/sculpt_intern.h | 22 ++++++ .../blender/editors/sculpt_paint/sculpt_ops.c | 2 + 8 files changed, 139 insertions(+), 39 deletions(-) diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 55c89e2d6b1..aefb33357a2 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -559,6 +559,8 @@ typedef struct SculptAttributePointers { SculptAttribute *automasking_stroke_id; SculptAttribute *automasking_cavity; + SculptAttribute *topology_island_key; /* CD_PROP_INT8 */ + /* BMesh */ SculptAttribute *dyntopo_node_id_vertex; SculptAttribute *dyntopo_node_id_face; @@ -756,6 +758,7 @@ typedef struct SculptSession { int last_automasking_settings_hash; uchar last_automask_stroke_id; + bool islands_valid; /* Is attrs.topology_island_key valid? */ } SculptSession; void BKE_sculptsession_free(struct Object *ob); diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 0e7eb957fd9..5a63b9bb126 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -74,18 +74,40 @@ struct PBVHPublic { * to be vertices. This is not true of edges or faces which are pulled from * the base mesh. */ + +#ifdef __cplusplus +/* A few C++ methods to play nice with sets and maps. */ +# define PBVH_REF_CXX_METHODS(Class) \ + bool operator==(const Class b) const \ + { \ + return i == b.i; \ + } \ + uint64_t hash() const \ + { \ + return i; \ + } +#else +# define PBVH_REF_CXX_METHODS(cls) +#endif + typedef struct PBVHVertRef { intptr_t i; + + PBVH_REF_CXX_METHODS(PBVHVertRef) } PBVHVertRef; /* NOTE: edges in PBVH_GRIDS are always pulled from the base mesh. */ typedef struct PBVHEdgeRef { intptr_t i; + + PBVH_REF_CXX_METHODS(PBVHVertRef) } PBVHEdgeRef; /* NOTE: faces in PBVH_GRIDS are always puled from the base mesh. */ typedef struct PBVHFaceRef { intptr_t i; + + PBVH_REF_CXX_METHODS(PBVHVertRef) } PBVHFaceRef; #define PBVH_REF_NONE -1LL diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index 1ec93d3a713..2c6d3357894 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -378,6 +378,8 @@ static int hide_show_exec(bContext *C, wmOperator *op) /* End undo. */ SCULPT_undo_push_end(ob); + SCULPT_topology_islands_invalidate(ob->sculpt); + /* Ensure that edges and faces get hidden as well (not used by * sculpt but it looks wrong when entering editmode otherwise). */ if (pbvh_type == PBVH_FACES) { diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index c6ffee8ba46..26d3b4fead9 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -1385,6 +1385,7 @@ static void sculpt_gesture_trim_begin(bContext *C, SculptGestureContext *sgconte Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); sculpt_gesture_trim_calculate_depth(sgcontext); sculpt_gesture_trim_geometry_generate(sgcontext); + SCULPT_topology_islands_invalidate(ss); BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, true, false, false); SCULPT_undo_push_node(sgcontext->vc.obact, NULL, SCULPT_UNDO_GEOMETRY); } diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index af03fe06092..a26cf16b78a 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -17,10 +17,12 @@ #include "BLI_ghash.h" #include "BLI_gsqueue.h" #include "BLI_math.h" +#include "BLI_set.hh" #include "BLI_task.h" #include "BLI_task.hh" #include "BLI_timeit.hh" #include "BLI_utildefines.h" +#include "BLI_vector.hh" #include "DNA_brush_types.h" #include "DNA_customdata_types.h" @@ -75,6 +77,8 @@ using blender::float3; using blender::MutableSpan; +using blender::Set; +using blender::Vector; /* -------------------------------------------------------------------- */ /** \name Sculpt PBVH Abstraction API @@ -412,6 +416,8 @@ void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visibl void SCULPT_face_visibility_all_invert(SculptSession *ss) { + SCULPT_topology_islands_invalidate(ss); + BLI_assert(ss->face_sets != nullptr); BLI_assert(ss->hide_poly != nullptr); switch (BKE_pbvh_type(ss->pbvh)) { @@ -435,6 +441,8 @@ void SCULPT_face_visibility_all_invert(SculptSession *ss) void SCULPT_face_visibility_all_set(SculptSession *ss, bool visible) { + SCULPT_topology_islands_invalidate(ss); + switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: case PBVH_GRIDS: @@ -626,6 +634,9 @@ void SCULPT_visibility_sync_all_from_faces(Object *ob) { SculptSession *ss = ob->sculpt; Mesh *mesh = BKE_object_get_original_mesh(ob); + + SCULPT_topology_islands_invalidate(ss); + switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { /* We may have adjusted the ".hide_poly" attribute, now make the hide status attributes for @@ -6301,4 +6312,70 @@ void SCULPT_face_set_set(SculptSession *ss, PBVHFaceRef face, int fset) } } +int SCULPT_vertex_island_get(SculptSession *ss, PBVHVertRef vertex) +{ + if (ss->attrs.topology_island_key) { + return *static_cast(SCULPT_vertex_attr_get(vertex, ss->attrs.topology_island_key)); + } + + return -1; +} + +void SCULPT_topology_islands_invalidate(SculptSession *ss) +{ + ss->islands_valid = false; +} + +void SCULPT_topology_islands_ensure(Object *ob) +{ + SculptSession *ss = ob->sculpt; + + if (ss->attrs.topology_island_key && ss->islands_valid && + BKE_pbvh_type(ss->pbvh) != PBVH_BMESH) { + return; + } + + SculptAttributeParams params; + params.permanent = params.stroke_only = params.simple_array = false; + + ss->attrs.topology_island_key = BKE_sculpt_attribute_ensure( + ob, ATTR_DOMAIN_POINT, CD_PROP_INT8, SCULPT_ATTRIBUTE_NAME(topology_island_key), ¶ms); + SCULPT_vertex_random_access_ensure(ss); + + int totvert = SCULPT_vertex_count_get(ss); + Set visit; + Vector stack; + uint8_t island_nr = 0; + + for (int i = 0; i < totvert; i++) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + if (visit.contains(vertex)) { + continue; + } + + stack.clear(); + stack.append(vertex); + visit.add(vertex); + + while (stack.size()) { + PBVHVertRef vertex2 = stack.pop_last(); + SculptVertexNeighborIter ni; + + *static_cast( + SCULPT_vertex_attr_get(vertex2, ss->attrs.topology_island_key)) = island_nr; + + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex2, ni) { + if (visit.add(ni.vertex) && SCULPT_vertex_any_face_visible_get(ss, ni.vertex)) { + stack.append(ni.vertex); + } + } + SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); + } + + island_nr++; + } + + ss->islands_valid = true; +} /** \} */ diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.cc b/source/blender/editors/sculpt_paint/sculpt_automasking.cc index 67c3e4bfd74..dcd8a72eb51 100644 --- a/source/blender/editors/sculpt_paint/sculpt_automasking.cc +++ b/source/blender/editors/sculpt_paint/sculpt_automasking.cc @@ -181,9 +181,6 @@ static bool SCULPT_automasking_needs_factors_cache(const Sculpt *sd, const Brush { const int automasking_flags = sculpt_automasking_mode_effective_bits(sd, brush); - if (automasking_flags & BRUSH_AUTOMASKING_TOPOLOGY) { - return true; - } if (automasking_flags & (BRUSH_AUTOMASKING_BOUNDARY_EDGES | BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS | BRUSH_AUTOMASKING_VIEW_NORMAL)) { @@ -540,6 +537,11 @@ float SCULPT_automasking_factor_get(AutomaskingCache *automasking, return automasking_factor_end(ss, automasking, vert, 0.0f); } + if (automasking->settings.flags & BRUSH_AUTOMASKING_TOPOLOGY && + SCULPT_vertex_island_get(ss, vert) != automasking->settings.initial_island_nr) { + return 0.0f; + } + if (automasking->settings.flags & BRUSH_AUTOMASKING_FACE_SETS) { if (!SCULPT_vertex_has_face_set(ss, vert, automasking->settings.initial_face_set)) { return 0.0f; @@ -615,41 +617,6 @@ static bool automask_floodfill_cb( SCULPT_vertex_co_get(ss, to_v), data->location, data->radius, data->symm)); } -static void SCULPT_topology_automasking_init(Sculpt *sd, Object *ob) -{ - SculptSession *ss = ob->sculpt; - Brush *brush = BKE_paint_brush(&sd->paint); - - if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) { - BLI_assert_unreachable(); - return; - } - - const int totvert = SCULPT_vertex_count_get(ss); - for (int i : IndexRange(totvert)) { - PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); - - (*(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor)) = 0.0f; - } - - /* Flood fill automask to connected vertices. Limited to vertices inside - * the brush radius if the tool requires it. */ - SculptFloodFill flood; - SCULPT_floodfill_init(ss, &flood); - const float radius = ss->cache ? ss->cache->radius : FLT_MAX; - SCULPT_floodfill_add_active(sd, ob, ss, &flood, radius); - - AutomaskFloodFillData fdata = {0}; - - fdata.radius = radius; - fdata.use_radius = ss->cache && sculpt_automasking_is_constrained_by_radius(brush); - fdata.symm = SCULPT_mesh_symmetry_xyz_get(ob); - - copy_v3_v3(fdata.location, SCULPT_active_vertex_co_get(ss)); - SCULPT_floodfill_execute(ss, &flood, automask_floodfill_cb, &fdata); - SCULPT_floodfill_free(&flood); -} - static void sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob) { SculptSession *ss = ob->sculpt; @@ -827,6 +794,11 @@ AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object bool use_stroke_id = false; int mode = sculpt_automasking_mode_effective_bits(sd, brush); + if (mode & BRUSH_AUTOMASKING_TOPOLOGY && ss->active_vertex.i != PBVH_REF_NONE) { + SCULPT_topology_islands_ensure(ob); + automasking->settings.initial_island_nr = SCULPT_vertex_island_get(ss, ss->active_vertex); + } + if ((mode & BRUSH_AUTOMASKING_VIEW_OCCLUSION) && (mode & BRUSH_AUTOMASKING_VIEW_NORMAL)) { use_stroke_id = true; @@ -919,7 +891,6 @@ AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object /* Additive modes. */ if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_TOPOLOGY)) { SCULPT_vertex_random_access_ensure(ss); - SCULPT_topology_automasking_init(sd, ob); } if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_FACE_SETS)) { SCULPT_vertex_random_access_ensure(ss); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index dc487aeeb9f..760f05ac105 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -410,6 +410,7 @@ typedef struct AutomaskingSettings { /* Flags from eAutomasking_flag. */ int flags; int initial_face_set; + int initial_island_nr; float cavity_factor; int cavity_blur_steps; @@ -1941,6 +1942,27 @@ bool SCULPT_tool_can_reuse_automask(int sculpt_tool); void SCULPT_ensure_valid_pivot(const struct Object *ob, struct Scene *scene); +/* -------------------------------------------------------------------- */ +/** \name Topology island API + * \{ + * Each mesh island shell gets its own integer + * key; these are temporary and internally limited to 8 bits. + * Uses the `ss->topology_island_key` attribute. + */ + +/* Ensures vertex island keys exist and are valid. */ +void SCULPT_topology_islands_ensure(struct Object *ob); + +/* Mark vertex island keys as invalid. Call when adding or hiding + * geometry. + */ +void SCULPT_topology_islands_invalidate(SculptSession *ss); + +/* Get vertex island key.*/ +int SCULPT_vertex_island_get(SculptSession *ss, PBVHVertRef vertex); + +/** \} */ + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.c b/source/blender/editors/sculpt_paint/sculpt_ops.c index 34dd6efaab5..35fd8ffc663 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.c +++ b/source/blender/editors/sculpt_paint/sculpt_ops.c @@ -1323,6 +1323,8 @@ static int sculpt_reveal_all_exec(bContext *C, wmOperator *op) } } + SCULPT_topology_islands_invalidate(ss); + if (!with_bmesh) { /* As an optimization, free the hide attribute when making all geometry visible. This allows * reduced memory usage without manually clearing it later, and allows sculpt operations to From 8b5c2d9ef109014ef64d8c170fd3e0554e8fef79 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 19 Jan 2023 17:27:40 -0800 Subject: [PATCH 0802/1522] Sculpt: Restrict expand to active mesh islands for geodesic and topology Fixes bug where other islands sometimes get their masks cleared (or filled) in strange circumstances. Still need to figure out the correct behavior for spherical falloff. --- .../editors/sculpt_paint/sculpt_expand.c | 33 +++++++++++++++++++ .../editors/sculpt_paint/sculpt_intern.h | 3 ++ 2 files changed, 36 insertions(+) diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index a05dc8c7c66..b71f52acbdb 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -390,6 +390,22 @@ static BLI_bitmap *sculpt_expand_boundary_from_enabled(SculptSession *ss, return boundary_verts; } +static void sculpt_expand_check_topology_islands(Object *ob) +{ + SculptSession *ss = ob->sculpt; + + ss->expand_cache->check_islands = ELEM(ss->expand_cache->falloff_type, + SCULPT_EXPAND_FALLOFF_GEODESIC, + SCULPT_EXPAND_FALLOFF_TOPOLOGY, + SCULPT_EXPAND_FALLOFF_BOUNDARY_TOPOLOGY); + + if (ss->expand_cache->check_islands) { + SCULPT_topology_islands_ensure(ob); + ss->expand_cache->initial_island_key = SCULPT_vertex_island_get( + ss, ss->expand_cache->initial_active_vertex); + } +} + /* Functions implementing different algorithms for initializing falloff values. */ /** @@ -1250,6 +1266,11 @@ static void sculpt_expand_mask_update_task_cb(void *__restrict userdata, const float initial_mask = *vd.mask; const bool enabled = sculpt_expand_state_get(ss, expand_cache, vd.vertex); + if (expand_cache->check_islands && + SCULPT_vertex_island_get(ss, vd.vertex) != expand_cache->initial_island_key) { + continue; + } + float new_mask; if (enabled) { @@ -1842,6 +1863,9 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event return OPERATOR_FINISHED; } case SCULPT_EXPAND_MODAL_FALLOFF_GEODESIC: { + expand_cache->falloff_gradient = SCULPT_EXPAND_MODAL_FALLOFF_GEODESIC; + sculpt_expand_check_topology_islands(ob); + sculpt_expand_falloff_factors_from_vertex_and_symm_create( expand_cache, sd, @@ -1851,6 +1875,9 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event break; } case SCULPT_EXPAND_MODAL_FALLOFF_TOPOLOGY: { + expand_cache->falloff_gradient = SCULPT_EXPAND_FALLOFF_TOPOLOGY; + sculpt_expand_check_topology_islands(ob); + sculpt_expand_falloff_factors_from_vertex_and_symm_create( expand_cache, sd, @@ -1860,6 +1887,9 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event break; } case SCULPT_EXPAND_MODAL_FALLOFF_TOPOLOGY_DIAGONALS: { + expand_cache->falloff_gradient = SCULPT_EXPAND_MODAL_FALLOFF_TOPOLOGY_DIAGONALS; + sculpt_expand_check_topology_islands(ob); + sculpt_expand_falloff_factors_from_vertex_and_symm_create( expand_cache, sd, @@ -1869,6 +1899,7 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event break; } case SCULPT_EXPAND_MODAL_FALLOFF_SPHERICAL: { + expand_cache->check_islands = false; sculpt_expand_falloff_factors_from_vertex_and_symm_create( expand_cache, sd, @@ -2213,6 +2244,8 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even sculpt_expand_falloff_factors_from_vertex_and_symm_create( ss->expand_cache, sd, ob, ss->expand_cache->initial_active_vertex, falloff_type); + sculpt_expand_check_topology_islands(ob); + /* Initial mesh data update, resets all target data in the sculpt mesh. */ sculpt_expand_update_for_vertex(C, ob, ss->expand_cache->initial_active_vertex); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 760f05ac105..b053b2764ca 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -818,6 +818,9 @@ typedef struct ExpandCache { float *original_mask; int *original_face_sets; float (*original_colors)[4]; + + int initial_island_key; + bool check_islands; } ExpandCache; /** \} */ From 8a6c6a5dc5189e41348943749eef5aa30434d046 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 19 Jan 2023 17:30:17 -0800 Subject: [PATCH 0803/1522] Cleanup: Remove unused functions in sculpt automasking code --- .../sculpt_paint/sculpt_automasking.cc | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.cc b/source/blender/editors/sculpt_paint/sculpt_automasking.cc index dcd8a72eb51..3edc99d32c1 100644 --- a/source/blender/editors/sculpt_paint/sculpt_automasking.cc +++ b/source/blender/editors/sculpt_paint/sculpt_automasking.cc @@ -585,19 +585,6 @@ void SCULPT_automasking_cache_free(AutomaskingCache *automasking) MEM_SAFE_FREE(automasking); } -static bool sculpt_automasking_is_constrained_by_radius(Brush *br) -{ - /* 2D falloff is not constrained by radius. */ - if (br->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { - return false; - } - - if (ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE)) { - return true; - } - return false; -} - struct AutomaskFloodFillData { float radius; bool use_radius; @@ -605,18 +592,6 @@ struct AutomaskFloodFillData { char symm; }; -static bool automask_floodfill_cb( - SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool /*is_duplicate*/, void *userdata) -{ - AutomaskFloodFillData *data = (AutomaskFloodFillData *)userdata; - - *(float *)SCULPT_vertex_attr_get(to_v, ss->attrs.automasking_factor) = 1.0f; - *(float *)SCULPT_vertex_attr_get(from_v, ss->attrs.automasking_factor) = 1.0f; - return (!data->use_radius || - SCULPT_is_vertex_inside_brush_radius_symm( - SCULPT_vertex_co_get(ss, to_v), data->location, data->radius, data->symm)); -} - static void sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob) { SculptSession *ss = ob->sculpt; From 0e35d5c0957e962792beb103bb3f59ceacdf0f0b Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 19 Jan 2023 17:49:53 -0800 Subject: [PATCH 0804/1522] Sculpt: Expand now waits for click before invoking when called from menu --- .../scripts/presets/keyconfig/keymap_data/blender_default.py | 1 + source/blender/editors/sculpt_paint/sculpt_expand.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 19a93e0882a..19093e51ec5 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -6269,6 +6269,7 @@ def km_sculpt_expand_modal(_params): ("CANCEL", {"type": 'ESC', "value": 'PRESS', "any": True}, None), ("CANCEL", {"type": 'RIGHTMOUSE', "value": 'PRESS', "any": True}, None), ("CONFIRM", {"type": 'LEFTMOUSE', "value": 'PRESS', "any": True}, None), + ("CONFIRM", {"type": 'LEFTMOUSE', "value": 'RELEASE', "any": True}, None), ("INVERT", {"type": 'F', "value": 'PRESS', "any": True}, None), ("PRESERVE", {"type": 'E', "value": 'PRESS', "any": True}, None), ("GRADIENT", {"type": 'G', "value": 'PRESS', "any": True}, None), diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index b71f52acbdb..069f943dc41 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -2334,7 +2334,7 @@ void SCULPT_OT_expand(wmOperatorType *ot) ot->cancel = sculpt_expand_cancel; ot->poll = SCULPT_mode_poll; - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_DEPENDS_ON_CURSOR; static EnumPropertyItem prop_sculpt_expand_falloff_type_items[] = { {SCULPT_EXPAND_FALLOFF_GEODESIC, "GEODESIC", 0, "Geodesic", ""}, From 4fa6ce09734d113b4fe0d2745b07a0cd9331f6d2 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 19 Jan 2023 17:55:25 -0800 Subject: [PATCH 0805/1522] Sculpt: Expand NORMALS and TOPOLOGY_DIAGNAL falloff now check islands Prevents disconnect parts of the mesh from having their masks filled. --- source/blender/editors/sculpt_paint/sculpt_expand.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index 069f943dc41..e1980f0ff6b 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -397,7 +397,9 @@ static void sculpt_expand_check_topology_islands(Object *ob) ss->expand_cache->check_islands = ELEM(ss->expand_cache->falloff_type, SCULPT_EXPAND_FALLOFF_GEODESIC, SCULPT_EXPAND_FALLOFF_TOPOLOGY, - SCULPT_EXPAND_FALLOFF_BOUNDARY_TOPOLOGY); + SCULPT_EXPAND_FALLOFF_TOPOLOGY_DIAGONALS, + SCULPT_EXPAND_FALLOFF_BOUNDARY_TOPOLOGY, + SCULPT_EXPAND_FALLOFF_NORMALS); if (ss->expand_cache->check_islands) { SCULPT_topology_islands_ensure(ob); From da21e035d33535ce8740f8b563deb73f9e52245e Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 19 Jan 2023 18:04:34 -0800 Subject: [PATCH 0806/1522] Sculpt: Fix T103923: Expand face sets now taking visibility into account The code was never ported from the old system of encoding visibility as negative face set values. --- source/blender/editors/sculpt_paint/sculpt_expand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index e1980f0ff6b..683eeed5111 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -256,7 +256,7 @@ static bool sculpt_expand_state_get(SculptSession *ss, */ static bool sculpt_expand_face_state_get(SculptSession *ss, ExpandCache *expand_cache, const int f) { - if (expand_cache->original_face_sets[f] <= 0) { + if (ss->hide_poly && ss->hide_poly[f]) { return false; } From fcb0425f64c4b3652e513420fd7b1a59951e39a3 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 19 Jan 2023 18:22:59 -0800 Subject: [PATCH 0807/1522] Sculpt: Remove old connected component API in favor of new island API --- source/blender/blenkernel/BKE_paint.h | 3 - source/blender/blenkernel/intern/paint.cc | 1 - source/blender/editors/sculpt_paint/sculpt.cc | 64 +------------------ .../editors/sculpt_paint/sculpt_expand.c | 18 ++---- .../editors/sculpt_paint/sculpt_intern.h | 11 ++-- .../editors/sculpt_paint/sculpt_mask_init.c | 4 +- 6 files changed, 15 insertions(+), 86 deletions(-) diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index aefb33357a2..1a380addfbb 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -392,9 +392,6 @@ typedef struct SculptPersistentBase { } SculptPersistentBase; typedef struct SculptVertexInfo { - /* Indexed by vertex, stores and ID of its topologically connected component. */ - int *connected_component; - /* Indexed by base mesh vertex index, stores if that vertex is a boundary. */ BLI_bitmap *boundary; } SculptVertexInfo; diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 1d416eec1e8..0ee517311d2 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -1454,7 +1454,6 @@ static void sculptsession_free_pbvh(Object *object) MEM_SAFE_FREE(ss->preview_vert_list); ss->preview_vert_count = 0; - MEM_SAFE_FREE(ss->vertex_info.connected_component); MEM_SAFE_FREE(ss->vertex_info.boundary); MEM_SAFE_FREE(ss->fake_neighbors.fake_neighbor_index); diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index a26cf16b78a..676f2de49ef 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -3351,7 +3351,6 @@ static void sculpt_topology_update(Sculpt *sd, /* Free index based vertex info as it will become invalid after modifying the topology during the * stroke. */ MEM_SAFE_FREE(ss->vertex_info.boundary); - MEM_SAFE_FREE(ss->vertex_info.connected_component); PBVHTopologyUpdateMode mode = PBVHTopologyUpdateMode(0); float location[3]; @@ -5928,14 +5927,6 @@ enum { SCULPT_TOPOLOGY_ID_DEFAULT, }; -static int SCULPT_vertex_get_connected_component(SculptSession *ss, PBVHVertRef vertex) -{ - if (ss->vertex_info.connected_component) { - return ss->vertex_info.connected_component[vertex.i]; - } - return SCULPT_TOPOLOGY_ID_DEFAULT; -} - static void SCULPT_fake_neighbor_init(SculptSession *ss, const float max_dist) { const int totvert = SCULPT_vertex_count_get(ss); @@ -5981,7 +5972,7 @@ static void do_fake_neighbor_search_task_cb(void *__restrict userdata, PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - int vd_topology_id = SCULPT_vertex_get_connected_component(ss, vd.vertex); + int vd_topology_id = SCULPT_vertex_island_get(ss, vd.vertex); if (vd_topology_id != nvtd->current_topology_id && ss->fake_neighbors.fake_neighbor_index[vd.index] == FAKE_NEIGHBOR_NONE) { float distance_squared = len_squared_v3v3(vd.co, data->nearest_vertex_search_co); @@ -6044,7 +6035,7 @@ static PBVHVertRef SCULPT_fake_neighbor_search(Sculpt *sd, NearestVertexFakeNeighborTLSData nvtd; nvtd.nearest_vertex.i = -1; nvtd.nearest_vertex_distance_squared = FLT_MAX; - nvtd.current_topology_id = SCULPT_vertex_get_connected_component(ss, vertex); + nvtd.current_topology_id = SCULPT_vertex_island_get(ss, vertex); TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -6062,55 +6053,6 @@ struct SculptTopologyIDFloodFillData { int next_id; }; -static bool SCULPT_connected_components_floodfill_cb( - SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool /*is_duplicate*/, void *userdata) -{ - SculptTopologyIDFloodFillData *data = static_cast(userdata); - - int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); - int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); - - ss->vertex_info.connected_component[from_v_i] = data->next_id; - ss->vertex_info.connected_component[to_v_i] = data->next_id; - return true; -} - -void SCULPT_connected_components_ensure(Object *ob) -{ - SculptSession *ss = ob->sculpt; - - /* Topology IDs already initialized. They only need to be recalculated when the PBVH is - * rebuild. - */ - if (ss->vertex_info.connected_component) { - return; - } - - const int totvert = SCULPT_vertex_count_get(ss); - ss->vertex_info.connected_component = static_cast( - MEM_malloc_arrayN(totvert, sizeof(int), "topology ID")); - - for (int i = 0; i < totvert; i++) { - ss->vertex_info.connected_component[i] = SCULPT_TOPOLOGY_ID_NONE; - } - - int next_id = 0; - for (int i = 0; i < totvert; i++) { - PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); - - if (ss->vertex_info.connected_component[i] == SCULPT_TOPOLOGY_ID_NONE) { - SculptFloodFill flood; - SCULPT_floodfill_init(ss, &flood); - SCULPT_floodfill_add_initial(&flood, vertex); - SculptTopologyIDFloodFillData data; - data.next_id = next_id; - SCULPT_floodfill_execute(ss, &flood, SCULPT_connected_components_floodfill_cb, &data); - SCULPT_floodfill_free(&flood); - next_id++; - } - } -} - void SCULPT_boundary_info_ensure(Object *object) { SculptSession *ss = object->sculpt; @@ -6159,7 +6101,7 @@ void SCULPT_fake_neighbors_ensure(Sculpt *sd, Object *ob, const float max_dist) return; } - SCULPT_connected_components_ensure(ob); + SCULPT_topology_islands_ensure(ob); SCULPT_fake_neighbor_init(ss, max_dist); for (int i = 0; i < totvert; i++) { diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index 683eeed5111..028ac847529 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -133,10 +133,8 @@ static bool sculpt_expand_is_vert_in_active_component(SculptSession *ss, ExpandCache *expand_cache, const PBVHVertRef v) { - int v_i = BKE_pbvh_vertex_to_index(ss->pbvh, v); - for (int i = 0; i < EXPAND_SYMM_AREAS; i++) { - if (ss->vertex_info.connected_component[v_i] == expand_cache->active_connected_components[i]) { + if (SCULPT_vertex_island_get(ss, v) == expand_cache->active_connected_islands[i]) { return true; } } @@ -403,8 +401,6 @@ static void sculpt_expand_check_topology_islands(Object *ob) if (ss->expand_cache->check_islands) { SCULPT_topology_islands_ensure(ob); - ss->expand_cache->initial_island_key = SCULPT_vertex_island_get( - ss, ss->expand_cache->initial_active_vertex); } } @@ -1269,7 +1265,7 @@ static void sculpt_expand_mask_update_task_cb(void *__restrict userdata, const bool enabled = sculpt_expand_state_get(ss, expand_cache, vd.vertex); if (expand_cache->check_islands && - SCULPT_vertex_island_get(ss, vd.vertex) != expand_cache->initial_island_key) { + !sculpt_expand_is_vert_in_active_component(ss, expand_cache, vd.vertex)) { continue; } @@ -1632,7 +1628,7 @@ static void sculpt_expand_find_active_connected_components_from_vert( { SculptSession *ss = ob->sculpt; for (int i = 0; i < EXPAND_SYMM_AREAS; i++) { - expand_cache->active_connected_components[i] = EXPAND_ACTIVE_COMPONENT_NONE; + expand_cache->active_connected_islands[i] = EXPAND_ACTIVE_COMPONENT_NONE; } const char symm = SCULPT_mesh_symmetry_xyz_get(ob); @@ -1644,10 +1640,8 @@ static void sculpt_expand_find_active_connected_components_from_vert( const PBVHVertRef symm_vertex = sculpt_expand_get_vertex_index_for_symmetry_pass( ob, symm_it, initial_vertex); - int symm_vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, symm_vertex); - - expand_cache->active_connected_components[(int)symm_it] = - ss->vertex_info.connected_component[symm_vertex_i]; + expand_cache->active_connected_islands[(int)symm_it] = SCULPT_vertex_island_get( + ss, symm_vertex); } } @@ -1727,8 +1721,8 @@ static void sculpt_expand_move_propagation_origin(bContext *C, static void sculpt_expand_ensure_sculptsession_data(Object *ob) { SculptSession *ss = ob->sculpt; + SCULPT_topology_islands_ensure(ob); SCULPT_vertex_random_access_ensure(ss); - SCULPT_connected_components_ensure(ob); SCULPT_boundary_info_ensure(ob); if (!ss->tex_pool) { ss->tex_pool = BKE_image_pool_new(); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index b053b2764ca..ffd1554be89 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -744,11 +744,11 @@ typedef struct ExpandCache { * initial position of Expand. */ float original_mouse_move[2]; - /* Active components checks. */ - /* Indexed by symmetry pass index, contains the connected component ID found in - * SculptSession->vertex_info.connected_component. Other connected components not found in this + /* Active island checks. */ + /* Indexed by symmetry pass index, contains the connected island ID for that + * symmetry pass. Other connected island IDs not found in this * array will be ignored by Expand. */ - int active_connected_components[EXPAND_SYMM_AREAS]; + int active_connected_islands[EXPAND_SYMM_AREAS]; /* Snapping. */ /* GSet containing all Face Sets IDs that Expand will use to snap the new data. */ @@ -819,7 +819,6 @@ typedef struct ExpandCache { int *original_face_sets; float (*original_colors)[4]; - int initial_island_key; bool check_islands; } ExpandCache; /** \} */ @@ -1028,8 +1027,6 @@ void SCULPT_boundary_info_ensure(Object *object); /* Boundary Info needs to be initialized in order to use this function. */ bool SCULPT_vertex_is_boundary(const SculptSession *ss, PBVHVertRef vertex); -void SCULPT_connected_components_ensure(Object *ob); - /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_init.c b/source/blender/editors/sculpt_paint/sculpt_mask_init.c index 99a7bb8a926..a4f29fd758a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_mask_init.c +++ b/source/blender/editors/sculpt_paint/sculpt_mask_init.c @@ -95,7 +95,7 @@ static void mask_init_task_cb(void *__restrict userdata, break; } case SCULPT_MASK_INIT_RANDOM_PER_LOOSE_PART: - *vd.mask = BLI_hash_int_01(ss->vertex_info.connected_component[vd.index] + seed); + *vd.mask = BLI_hash_int_01(SCULPT_vertex_island_get(ss, vd.vertex) + seed); break; } } @@ -128,7 +128,7 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op) SCULPT_undo_push_begin(ob, op); if (mode == SCULPT_MASK_INIT_RANDOM_PER_LOOSE_PART) { - SCULPT_connected_components_ensure(ob); + SCULPT_topology_islands_ensure(ob); } SculptThreadedTaskData data = { From 1184501d5ce147024faa93dca1e79b64140f8723 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 19 Jan 2023 18:32:40 -0800 Subject: [PATCH 0808/1522] Sculpt: Fix T103948: Automasking stroke id not being updated --- source/blender/editors/sculpt_paint/sculpt_automasking.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.cc b/source/blender/editors/sculpt_paint/sculpt_automasking.cc index 3edc99d32c1..62c27a5ffeb 100644 --- a/source/blender/editors/sculpt_paint/sculpt_automasking.cc +++ b/source/blender/editors/sculpt_paint/sculpt_automasking.cc @@ -522,7 +522,7 @@ float SCULPT_automasking_factor_get(AutomaskingCache *automasking, factor *= sculpt_automasking_cavity_factor(automasking, ss, vert); } - return factor * mask; + return automasking_factor_end(ss, automasking, vert, factor * mask); } uchar stroke_id = ss->attrs.automasking_stroke_id ? From ebb519652cecad93867f13c4c21bd8ef58f15909 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Jan 2023 12:46:06 +1100 Subject: [PATCH 0809/1522] Object: add functionality to access the object as an index for operators Add: - ED_object_in_mode_to_index - ED_object_in_mode_from_index Useful for operators that act on a non-active object in multi-edit mode, so the index can be stored for the operators exec function to read back the value when redoing an action. Needed to resolve T102680. --- source/blender/editors/include/ED_object.h | 25 +++++++++++ source/blender/editors/object/object_edit.c | 46 +++++++++++++++++++++ 2 files changed, 71 insertions(+) diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 798175b7cb8..82f8505509a 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -507,6 +507,31 @@ void ED_object_posemode_set_for_weight_paint(struct bContext *C, struct Object *ob, bool is_mode_set); +/** + * Return the index of an object in a mode (typically edit/pose mode). + * + * Useful for operators with multi-mode editing to be able to redo an action on an object + * by it's index which (unlike pointers) the operator can store for redo. + * + * The indices aren't intended to be useful from Python scripts, + * although they are not prevented from passing them in, this is mainly to enable redo. + * For scripts it's more convenient to set the object active before operating on it. + * + * \note The active object is always index 0. + */ +int ED_object_in_mode_to_index(const struct Scene *scene, + struct ViewLayer *view_layer, + eObjectMode mode, + const struct Object *ob); + +/** + * Access the object from the index returned by #ED_object_in_mode_to_index. + */ +Object *ED_object_in_mode_from_index(const struct Scene *scene, + struct ViewLayer *view_layer, + eObjectMode mode, + int index); + /* object_modifier.c */ enum { diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index b1cebc32513..2939c31bc5c 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -217,6 +217,52 @@ Object **ED_object_array_in_mode_or_selected(bContext *C, /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Object Index Lookup/Creation + * \{ */ + +int ED_object_in_mode_to_index(const Scene *scene, + ViewLayer *view_layer, + const eObjectMode mode, + const Object *ob) +{ + BLI_assert(ob != NULL); + /* NOTE: the `v3d` is always NULL because the purpose of this function is to return + * a reusable index, using the `v3d` only increases the chance the index may become invalid. */ + int index = -1; + int i = 0; + FOREACH_BASE_IN_MODE_BEGIN (scene, view_layer, NULL, -1, mode, base_iter) { + if (base_iter->object == ob) { + index = i; + break; + } + i++; + } + FOREACH_BASE_IN_MODE_END; + return index; +} + +Object *ED_object_in_mode_from_index(const Scene *scene, + ViewLayer *view_layer, + const eObjectMode mode, + int index) +{ + BLI_assert(index >= 0); + Object *ob = NULL; + int i = 0; + FOREACH_BASE_IN_MODE_BEGIN (scene, view_layer, NULL, -1, mode, base_iter) { + if (index == i) { + ob = base_iter->object; + break; + } + i++; + } + FOREACH_BASE_IN_MODE_END; + return ob; +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Hide Operator * \{ */ From a0706d6cf0000813568c05ebae1dfabf9c721002 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Jan 2023 12:51:50 +1100 Subject: [PATCH 0810/1522] Fix T102680: UV Pick shortest Path wrong for multi-object editing Path selection support from [0] didn't account for multiple objects in edit-mode. Now picking the UV also picks the object to operate on. [0]: ea5fe7abc183c1e53d327f97280f589499fe60bb --- source/blender/editors/uvedit/uvedit_path.c | 238 +++++++++++--------- 1 file changed, 136 insertions(+), 102 deletions(-) diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c index 82d8c536fba..1e50ddba3a3 100644 --- a/source/blender/editors/uvedit/uvedit_path.c +++ b/source/blender/editors/uvedit/uvedit_path.c @@ -38,6 +38,7 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +#include "ED_object.h" #include "ED_screen.h" #include "ED_transform.h" #include "ED_uvedit.h" @@ -559,136 +560,159 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve op_params.track_active = true; Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( + scene, view_layer, CTX_wm_view3d(C), &objects_len); float co[2]; const ARegion *region = CTX_wm_region(C); - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); - BMesh *bm = em->bm; - const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); - - float aspect_y; - { - float aspx, aspy; - ED_uvedit_get_aspect(obedit, &aspx, &aspy); - aspect_y = aspx / aspy; - } - UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &co[0], &co[1]); BMElem *ele_src = NULL, *ele_dst = NULL; + /* Detect the hit. */ + UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); + bool hit_found = false; if (uv_selectmode == UV_SELECT_FACE) { - UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); - if (!uv_find_nearest_face(scene, obedit, co, &hit)) { - return OPERATOR_CANCELLED; + if (uv_find_nearest_face_multi(scene, objects, objects_len, co, &hit)) { + hit_found = true; } - - BMFace *f_src = BM_mesh_active_face_get(bm, false, false); - /* Check selection? */ - - ele_src = (BMElem *)f_src; - ele_dst = (BMElem *)hit.efa; - } - - else if (uv_selectmode & UV_SELECT_EDGE) { - UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); - if (!uv_find_nearest_edge(scene, obedit, co, 0.0f, &hit)) { - return OPERATOR_CANCELLED; - } - - BMLoop *l_src = NULL; - if (ts->uv_flag & UV_SYNC_SELECTION) { - BMEdge *e_src = BM_mesh_active_edge_get(bm); - if (e_src != NULL) { - l_src = uv_find_nearest_loop_from_edge(scene, obedit, e_src, co); - } - } - else { - l_src = ED_uvedit_active_edge_loop_get(bm); - if (l_src != NULL) { - if (!uvedit_uv_select_test(scene, l_src, offsets) && - !uvedit_uv_select_test(scene, l_src->next, offsets)) { - l_src = NULL; - } - ele_src = (BMElem *)l_src; - } - } - ele_src = (BMElem *)l_src; - ele_dst = (BMElem *)hit.l; - } - else { - UvNearestHit hit = UV_NEAREST_HIT_INIT_MAX(®ion->v2d); - if (!uv_find_nearest_vert(scene, obedit, co, 0.0f, &hit)) { - return OPERATOR_CANCELLED; - } - - BMLoop *l_src = NULL; - if (ts->uv_flag & UV_SYNC_SELECTION) { - BMVert *v_src = BM_mesh_active_vert_get(bm); - if (v_src != NULL) { - l_src = uv_find_nearest_loop_from_vert(scene, obedit, v_src, co); - } - } - else { - l_src = ED_uvedit_active_vert_loop_get(bm); - if (l_src != NULL) { - if (!uvedit_uv_select_test(scene, l_src, offsets)) { - l_src = NULL; - } - } - } - ele_src = (BMElem *)l_src; - ele_dst = (BMElem *)hit.l; - } - - if (ele_src == NULL || ele_dst == NULL) { - return OPERATOR_CANCELLED; - } - - uv_shortest_path_pick_ex( - scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets); - - /* To support redo. */ - int index; - if (uv_selectmode & UV_SELECT_FACE) { - BM_mesh_elem_index_ensure(bm, BM_FACE); - index = BM_elem_index_get(ele_dst); } else if (uv_selectmode & UV_SELECT_EDGE) { - BM_mesh_elem_index_ensure(bm, BM_LOOP); - index = BM_elem_index_get(ele_dst); + if (uv_find_nearest_edge_multi(scene, objects, objects_len, co, 0.0f, &hit)) { + hit_found = true; + } } else { - BM_mesh_elem_index_ensure(bm, BM_LOOP); - index = BM_elem_index_get(ele_dst); + if (uv_find_nearest_vert_multi(scene, objects, objects_len, co, 0.0f, &hit)) { + hit_found = true; + } } - RNA_int_set(op->ptr, "index", index); - return OPERATOR_FINISHED; + bool changed = false; + if (hit_found) { + /* This may not be the active object. */ + Object *obedit = hit.ob; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); + + /* Respond to the hit. */ + if (uv_selectmode == UV_SELECT_FACE) { + /* Face selection. */ + BMFace *f_src = BM_mesh_active_face_get(bm, false, false); + /* Check selection? */ + ele_src = (BMElem *)f_src; + ele_dst = (BMElem *)hit.efa; + } + else if (uv_selectmode & UV_SELECT_EDGE) { + /* Edge selection. */ + BMLoop *l_src = NULL; + if (ts->uv_flag & UV_SYNC_SELECTION) { + BMEdge *e_src = BM_mesh_active_edge_get(bm); + if (e_src != NULL) { + l_src = uv_find_nearest_loop_from_edge(scene, obedit, e_src, co); + } + } + else { + l_src = ED_uvedit_active_edge_loop_get(bm); + if (l_src != NULL) { + if (!uvedit_uv_select_test(scene, l_src, offsets) && + !uvedit_uv_select_test(scene, l_src->next, offsets)) { + l_src = NULL; + } + ele_src = (BMElem *)l_src; + } + } + ele_src = (BMElem *)l_src; + ele_dst = (BMElem *)hit.l; + } + else { + /* Vertex selection. */ + BMLoop *l_src = NULL; + if (ts->uv_flag & UV_SYNC_SELECTION) { + BMVert *v_src = BM_mesh_active_vert_get(bm); + if (v_src != NULL) { + l_src = uv_find_nearest_loop_from_vert(scene, obedit, v_src, co); + } + } + else { + l_src = ED_uvedit_active_vert_loop_get(bm); + if (l_src != NULL) { + if (!uvedit_uv_select_test(scene, l_src, offsets)) { + l_src = NULL; + } + } + } + ele_src = (BMElem *)l_src; + ele_dst = (BMElem *)hit.l; + } + + if (ele_src && ele_dst) { + /* Always use the active object, not `obedit` as the active defines the UV display. */ + float aspect_y; + { + float aspx, aspy; + ED_uvedit_get_aspect(CTX_data_edit_object(C), &aspx, &aspy); + aspect_y = aspx / aspy; + } + + uv_shortest_path_pick_ex( + scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets); + + /* Store the object and it's index so redo is possible. */ + int index; + if (uv_selectmode & UV_SELECT_FACE) { + BM_mesh_elem_index_ensure(bm, BM_FACE); + index = BM_elem_index_get(ele_dst); + } + else if (uv_selectmode & UV_SELECT_EDGE) { + BM_mesh_elem_index_ensure(bm, BM_LOOP); + index = BM_elem_index_get(ele_dst); + } + else { + BM_mesh_elem_index_ensure(bm, BM_LOOP); + index = BM_elem_index_get(ele_dst); + } + + const int object_index = ED_object_in_mode_to_index(scene, view_layer, OB_MODE_EDIT, obedit); + BLI_assert(object_index != -1); + RNA_int_set(op->ptr, "object_index", object_index); + RNA_int_set(op->ptr, "index", index); + changed = true; + } + } + + MEM_freeN(objects); + + return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op) { Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); const char uv_selectmode = ED_uvedit_select_mode_get(scene); - Object *obedit = CTX_data_edit_object(C); + + const int object_index = RNA_int_get(op->ptr, "object_index"); + const int index = RNA_int_get(op->ptr, "index"); + if (object_index == -1) { + return OPERATOR_CANCELLED; + } + + Object *obedit = ED_object_in_mode_from_index(scene, view_layer, OB_MODE_EDIT, object_index); + if (obedit == NULL) { + return OPERATOR_CANCELLED; + } + BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); - float aspect_y; - { - float aspx, aspy; - ED_uvedit_get_aspect(obedit, &aspx, &aspy); - aspect_y = aspx / aspy; - } - - const int index = RNA_int_get(op->ptr, "index"); - BMElem *ele_src, *ele_dst; if (uv_selectmode & UV_SELECT_FACE) { @@ -719,6 +743,14 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op) } } + /* Always use the active object, not `obedit` as the active defines the UV display. */ + float aspect_y; + { + float aspx, aspy; + ED_uvedit_get_aspect(CTX_data_edit_object(C), &aspx, &aspy); + aspect_y = aspx / aspy; + } + struct PathSelectParams op_params; path_select_params_from_op(op, &op_params); op_params.track_active = true; @@ -752,6 +784,8 @@ void UV_OT_shortest_path_pick(wmOperatorType *ot) path_select_properties(ot); /* use for redo */ + prop = RNA_def_int(ot->srna, "object_index", -1, -1, INT_MAX, "", "", 0, INT_MAX); + RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); prop = RNA_def_int(ot->srna, "index", -1, -1, INT_MAX, "", "", 0, INT_MAX); RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } From d0010d48c7f4edff2fdc0591d71c832c9d546964 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Jan 2023 13:12:28 +1100 Subject: [PATCH 0811/1522] Cleanup: add ED_uvedit_get_aspect_y utility function This avoids having to perform the aspect division inline. --- source/blender/editors/include/ED_uvedit.h | 7 ++++++ .../blender/editors/uvedit/uvedit_islands.cc | 9 +------- source/blender/editors/uvedit/uvedit_path.c | 23 +++---------------- .../editors/uvedit/uvedit_smart_stitch.c | 5 ++-- .../editors/uvedit/uvedit_unwrap_ops.c | 11 ++++++--- 5 files changed, 21 insertions(+), 34 deletions(-) diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 7aa745abdf6..349975e1181 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -273,6 +273,13 @@ struct BMLoop **ED_uvedit_selected_verts(const struct Scene *scene, int *r_verts_len); void ED_uvedit_get_aspect(struct Object *obedit, float *r_aspx, float *r_aspy); + +/** + * Return the X / Y aspect (wider aspects are over 1, taller are below 1). + * Apply this aspect by multiplying with the Y axis (X aspect is always 1 & unchanged). + */ +float ED_uvedit_get_aspect_y(struct Object *obedit); + void ED_uvedit_get_aspect_from_material(Object *ob, const int material_index, float *r_aspx, diff --git a/source/blender/editors/uvedit/uvedit_islands.cc b/source/blender/editors/uvedit/uvedit_islands.cc index ed0e4933965..ad4527affb8 100644 --- a/source/blender/editors/uvedit/uvedit_islands.cc +++ b/source/blender/editors/uvedit/uvedit_islands.cc @@ -675,14 +675,7 @@ void ED_uvedit_pack_islands_multi(const Scene *scene, continue; } - float aspect_y = 1.0f; - if (params->correct_aspect) { - float aspx, aspy; - ED_uvedit_get_aspect(obedit, &aspx, &aspy); - if (aspx != aspy) { - aspect_y = aspx / aspy; - } - } + const float aspect_y = params->correct_aspect ? ED_uvedit_get_aspect_y(obedit) : 1.0f; bool only_selected_faces = params->only_selected_faces; bool only_selected_uvs = params->only_selected_uvs; diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c index 1e50ddba3a3..e8ba3b0cffd 100644 --- a/source/blender/editors/uvedit/uvedit_path.c +++ b/source/blender/editors/uvedit/uvedit_path.c @@ -653,13 +653,7 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve if (ele_src && ele_dst) { /* Always use the active object, not `obedit` as the active defines the UV display. */ - float aspect_y; - { - float aspx, aspy; - ED_uvedit_get_aspect(CTX_data_edit_object(C), &aspx, &aspy); - aspect_y = aspx / aspy; - } - + const float aspect_y = ED_uvedit_get_aspect_y(CTX_data_edit_object(C)); uv_shortest_path_pick_ex( scene, depsgraph, obedit, &op_params, ele_src, ele_dst, aspect_y, offsets); @@ -744,12 +738,7 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op) } /* Always use the active object, not `obedit` as the active defines the UV display. */ - float aspect_y; - { - float aspx, aspy; - ED_uvedit_get_aspect(CTX_data_edit_object(C), &aspx, &aspy); - aspect_y = aspx / aspy; - } + const float aspect_y = ED_uvedit_get_aspect_y(CTX_data_edit_object(C)); struct PathSelectParams op_params; path_select_params_from_op(op, &op_params); @@ -803,13 +792,7 @@ static int uv_shortest_path_select_exec(bContext *C, wmOperator *op) const char uv_selectmode = ED_uvedit_select_mode_get(scene); bool found_valid_elements = false; - float aspect_y; - { - Object *obedit = CTX_data_edit_object(C); - float aspx, aspy; - ED_uvedit_get_aspect(obedit, &aspx, &aspy); - aspect_y = aspx / aspy; - } + const float aspect_y = ED_uvedit_get_aspect_y(CTX_data_edit_object(C)); ViewLayer *view_layer = CTX_data_view_layer(C); uint objects_len = 0; diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index e6d895bd826..7a05ffafbcb 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -130,6 +130,7 @@ typedef struct UvEdge { /* stitch state object */ typedef struct StitchState { + /** The `aspect[0] / aspect[1]`. */ float aspect; /* object for editmesh */ Object *obedit; @@ -1827,7 +1828,6 @@ static StitchState *stitch_init(bContext *C, StitchState *state; Scene *scene = CTX_data_scene(C); ToolSettings *ts = scene->toolsettings; - float aspx, aspy; BMEditMesh *em = BKE_editmesh_from_object(obedit); const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); @@ -1850,8 +1850,7 @@ static StitchState *stitch_init(bContext *C, return NULL; } - ED_uvedit_get_aspect(obedit, &aspx, &aspy); - state->aspect = aspx / aspy; + state->aspect = ED_uvedit_get_aspect_y(obedit); int unique_uvs = state->element_map->total_unique_uvs; state->total_separate_uvs = unique_uvs; diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 1ab398c185c..e5b3d8998c0 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -281,6 +281,13 @@ void ED_uvedit_get_aspect(Object *ob, float *r_aspx, float *r_aspy) ED_uvedit_get_aspect_from_material(ob, efa->mat_nr, r_aspx, r_aspy); } +float ED_uvedit_get_aspect_y(Object *ob) +{ + float aspect[2]; + ED_uvedit_get_aspect(ob, &aspect[0], &aspect[1]); + return aspect[0] / aspect[1]; +} + static bool uvedit_is_face_affected(const Scene *scene, BMFace *efa, const UnwrapOptions *options, @@ -1548,9 +1555,7 @@ static void shrink_loop_uv_by_aspect_ratio(BMFace *efa, static void correct_uv_aspect(Object *ob, BMEditMesh *em) { const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); - float aspx, aspy; - ED_uvedit_get_aspect(ob, &aspx, &aspy); - const float aspect_y = aspx / aspy; + const float aspect_y = ED_uvedit_get_aspect_y(ob); if (aspect_y == 1.0f) { /* Scaling by 1.0 has no effect. */ return; From b73814c65cbe8fef6ef5f8ae16d4d1fd4ecbcf20 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Jan 2023 13:22:00 +1100 Subject: [PATCH 0812/1522] Cleanup: use function style casts for C++ --- .../modifiers/intern/MOD_correctivesmooth.cc | 30 +++++++++---------- source/blender/modifiers/intern/MOD_ocean.cc | 2 +- .../modifiers/intern/MOD_solidify_extrude.cc | 10 +++---- .../intern/MOD_solidify_nonmanifold.cc | 16 +++++----- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.cc b/source/blender/modifiers/intern/MOD_correctivesmooth.cc index 83b51187c6b..bf98483ce8a 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.cc +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.cc @@ -131,8 +131,8 @@ static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights) const MPoly *mpoly = BKE_mesh_polys(mesh); const MLoop *mloop = BKE_mesh_loops(mesh); - const uint mpoly_num = (uint)mesh->totpoly; - const uint medge_num = (uint)mesh->totedge; + const uint mpoly_num = uint(mesh->totpoly); + const uint medge_num = uint(mesh->totedge); /* Flag boundary edges so only boundaries are set to 1. */ uint8_t *boundaries = static_cast( @@ -144,7 +144,7 @@ static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights) int j; for (j = 0; j < totloop; j++) { uint8_t *e_value = &boundaries[mloop[p->loopstart + j].e]; - *e_value |= (uint8_t)((*e_value) + 1); + *e_value |= uint8_t((*e_value) + 1); } } @@ -173,7 +173,7 @@ static void smooth_iter__simple(CorrectiveSmoothModifierData *csmd, const float lambda = csmd->lambda; uint i; - const uint edges_num = (uint)mesh->totedge; + const uint edges_num = uint(mesh->totedge); const MEdge *edges = BKE_mesh_edges(mesh); struct SmoothingData_Simple { @@ -248,7 +248,7 @@ static void smooth_iter__length_weight(CorrectiveSmoothModifierData *csmd, uint iterations) { const float eps = FLT_EPSILON * 10.0f; - const uint edges_num = (uint)mesh->totedge; + const uint edges_num = uint(mesh->totedge); /* NOTE: the way this smoothing method works, its approx half as strong as the simple-smooth, * and 2.0 rarely spikes, double the value for consistent behavior. */ const float lambda = csmd->lambda * 2.0f; @@ -384,7 +384,7 @@ static void smooth_verts(CorrectiveSmoothModifierData *csmd, } } - smooth_iter(csmd, mesh, vertexCos, verts_num, smooth_weights, (uint)csmd->repeat); + smooth_iter(csmd, mesh, vertexCos, verts_num, smooth_weights, uint(csmd->repeat)); if (smooth_weights) { MEM_freeN(smooth_weights); @@ -437,8 +437,8 @@ static void calc_tangent_spaces(const Mesh *mesh, float *r_tangent_weights, float *r_tangent_weights_per_vertex) { - const uint mpoly_num = (uint)mesh->totpoly; - const uint mvert_num = (uint)mesh->totvert; + const uint mpoly_num = uint(mesh->totpoly); + const uint mvert_num = uint(mesh->totvert); const MPoly *mpoly = BKE_mesh_polys(mesh); const MLoop *mloop = BKE_mesh_loops(mesh); uint i; @@ -462,7 +462,7 @@ static void calc_tangent_spaces(const Mesh *mesh, normalize_v3(v_dir_prev); for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) { - uint l_index = (uint)(l_curr - mloop); + uint l_index = uint(l_curr - mloop); float(*ts)[3] = r_tangent_spaces[l_index]; /* re-use the previous value */ @@ -520,7 +520,7 @@ static void calc_deltas(CorrectiveSmoothModifierData *csmd, uint verts_num) { const MLoop *mloop = BKE_mesh_loops(mesh); - const uint loops_num = (uint)mesh->totloop; + const uint loops_num = uint(mesh->totloop); float(*smooth_vertex_coords)[3] = static_cast(MEM_dupallocN(rest_coords)); @@ -579,7 +579,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, (((ID *)ob->data)->recalc & ID_RECALC_ALL)); const MLoop *mloop = BKE_mesh_loops(mesh); - const uint loops_num = (uint)mesh->totloop; + const uint loops_num = uint(mesh->totloop); bool use_only_smooth = (csmd->flag & MOD_CORRECTIVESMOOTH_ONLY_SMOOTH) != 0; const MDeformVert *dvert = nullptr; @@ -590,7 +590,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, /* if rest bind_coords not are defined, set them (only run during bind) */ if ((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_BIND) && /* signal to recalculate, whoever sets MUST also free bind coords */ - (csmd->bind_coords_num == (uint)-1)) { + (csmd->bind_coords_num == uint(-1))) { if (DEG_is_active(depsgraph)) { BLI_assert(csmd->bind_coords == nullptr); csmd->bind_coords = static_cast(MEM_dupallocN(vertexCos)); @@ -633,7 +633,7 @@ static void correctivesmooth_modifier_do(ModifierData *md, goto error; } else { - uint me_numVerts = (uint)((em) ? em->bm->totvert : ((Mesh *)ob->data)->totvert); + uint me_numVerts = uint((em) ? em->bm->totvert : ((Mesh *)ob->data)->totvert); if (me_numVerts != verts_num) { BKE_modifier_set_error( @@ -747,7 +747,7 @@ static void deformVerts(ModifierData *md, Mesh *mesh_src = MOD_deform_mesh_eval_get(ctx->object, nullptr, mesh, nullptr, verts_num, false); correctivesmooth_modifier_do( - md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)verts_num, nullptr); + md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, uint(verts_num), nullptr); if (!ELEM(mesh_src, nullptr, mesh)) { BKE_id_free(nullptr, mesh_src); @@ -770,7 +770,7 @@ static void deformVertsEM(ModifierData *md, } correctivesmooth_modifier_do( - md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, (uint)verts_num, editData); + md, ctx->depsgraph, ctx->object, mesh_src, vertexCos, uint(verts_num), editData); if (!ELEM(mesh_src, nullptr, mesh)) { BKE_id_free(nullptr, mesh_src); diff --git a/source/blender/modifiers/intern/MOD_ocean.cc b/source/blender/modifiers/intern/MOD_ocean.cc index d5ae1caf703..6ca8c25ef28 100644 --- a/source/blender/modifiers/intern/MOD_ocean.cc +++ b/source/blender/modifiers/intern/MOD_ocean.cc @@ -416,7 +416,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes foam = BKE_ocean_jminus_to_foam(ocr.Jminus, omd->foam_coverage); } - mlcol->r = mlcol->g = mlcol->b = (char)(foam * 255); + mlcol->r = mlcol->g = mlcol->b = char(foam * 255); /* This needs to be set (render engine uses) */ mlcol->a = 255; diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.cc b/source/blender/modifiers/intern/MOD_solidify_extrude.cc index 48cdbc89f38..cbca9c3527d 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.cc +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.cc @@ -73,7 +73,7 @@ static void mesh_calc_hq_normal(Mesh *mesh, const MPoly *mp = mpoly; { - EdgeFaceRef *edge_ref_array = MEM_cnew_array((size_t)edges_num, __func__); + EdgeFaceRef *edge_ref_array = MEM_cnew_array(size_t(edges_num), __func__); EdgeFaceRef *edge_ref; float edge_normal[3]; @@ -231,8 +231,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex uint eidx; uint i; -#define INVALID_UNUSED ((uint)-1) -#define INVALID_PAIR ((uint)-2) +#define INVALID_UNUSED uint(-1) +#define INVALID_PAIR uint(-2) new_vert_arr = static_cast( MEM_malloc_arrayN(verts_num, 2 * sizeof(*new_vert_arr), __func__)); @@ -530,7 +530,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex eidx = ml_prev->e; const MEdge *ed = orig_medge + eidx; BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) && ELEM(ml->v, ed->v1, ed->v2)); - char flip = (char)((ml_prev->v > ml->v) == (ed->v1 < ed->v2)); + char flip = char((ml_prev->v > ml->v) == (ed->v1 < ed->v2)); if (edge_user_pairs[eidx][flip] == INVALID_UNUSED) { edge_user_pairs[eidx][flip] = i; } @@ -827,7 +827,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex eidx = ml_prev->e; const MEdge *ed = orig_medge + eidx; BLI_assert(ELEM(ml_prev->v, ed->v1, ed->v2) && ELEM(ml->v, ed->v1, ed->v2)); - char flip = (char)((ml_prev->v > ml->v) == (ed->v1 < ed->v2)); + char flip = char((ml_prev->v > ml->v) == (ed->v1 < ed->v2)); if (edge_user_pairs[eidx][flip] == INVALID_UNUSED) { edge_user_pairs[eidx][flip] = i; } diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc index 2b07998932b..53ebf814a26 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc @@ -204,7 +204,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, uint new_loops_num = 0; uint new_polys_num = 0; -#define MOD_SOLIDIFY_EMPTY_TAG ((uint)-1) +#define MOD_SOLIDIFY_EMPTY_TAG uint(-1) /* Calculate only face normals. Copied because they are modified directly below. */ float(*poly_nors)[3] = static_cast( @@ -420,7 +420,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, mul_v3_fl(edgedir, (combined_verts[v2] + 1) / - (float)(combined_verts[v1] + combined_verts[v2] + 2)); + float(combined_verts[v1] + combined_verts[v2] + 2)); add_v3_v3(orig_mvert_co[v1], edgedir); for (uint j = v2; j < verts_num; j++) { if (vm[j] == v2) { @@ -2537,8 +2537,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, uint *face_edges = static_cast( MEM_malloc_arrayN(largest_ngon * 2, sizeof(*face_edges), __func__)); for (uint i = 0; i < polys_num * 2; i++, fr++) { - const uint loopstart = (uint)fr->face->loopstart; - uint totloop = (uint)fr->face->totloop; + const uint loopstart = uint(fr->face->loopstart); + uint totloop = uint(fr->face->totloop); uint valid_edges = 0; uint k = 0; while (totloop > 0 && (!fr->link_edges[totloop - 1] || @@ -2547,14 +2547,14 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, } if (totloop > 0) { NewEdgeRef *prior_edge = fr->link_edges[totloop - 1]; - uint prior_flip = (uint)(vm[orig_medge[prior_edge->old_edge].v1] == - vm[orig_mloop[loopstart + (totloop - 1)].v]); + uint prior_flip = uint(vm[orig_medge[prior_edge->old_edge].v1] == + vm[orig_mloop[loopstart + (totloop - 1)].v]); for (uint j = 0; j < totloop; j++) { NewEdgeRef *new_edge = fr->link_edges[j]; if (new_edge && new_edge->new_edge != MOD_SOLIDIFY_EMPTY_TAG) { valid_edges++; - const uint flip = (uint)(vm[orig_medge[new_edge->old_edge].v2] == - vm[orig_mloop[loopstart + j].v]); + const uint flip = uint(vm[orig_medge[new_edge->old_edge].v2] == + vm[orig_mloop[loopstart + j].v]); BLI_assert(flip || vm[orig_medge[new_edge->old_edge].v1] == vm[orig_mloop[loopstart + j].v]); /* The vert that's in the current loop. */ From 92734d868b1b046298bbcbdca4ab2039ec922e63 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Jan 2023 13:50:15 +1100 Subject: [PATCH 0813/1522] PyDoc: resolve bpy.types & bpy.ops expanding sub-modules inline The bpy.types page was unreasonably long (over 17k lines). Resolve by setting the `maxdepth` for this and the `bpy.ops` page too. This problem showed up in v3.4 release and may be caused by changes to Sphinx's default behavior as there doesn't seem to be any change that would cause this in the generated docs. --- doc/python_api/sphinx_doc_gen.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index b070a54407c..74bee60d662 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -2098,6 +2098,8 @@ def write_rst_types_index(basepath): fw(title_string("Types (bpy.types)", "=")) fw(".. module:: bpy.types\n\n") fw(".. toctree::\n") + # Only show top-level entries (avoids unreasonably large pages). + fw(" :maxdepth: 1\n") fw(" :glob:\n\n") fw(" bpy.types.*\n\n") @@ -2124,6 +2126,8 @@ def write_rst_ops_index(basepath): write_example_ref("", fw, "bpy.ops") fw(".. toctree::\n") fw(" :caption: Submodules\n") + # Only show top-level entries (avoids unreasonably large pages). + fw(" :maxdepth: 1\n") fw(" :glob:\n\n") fw(" bpy.ops.*\n\n") file.close() From 6672b5373f172e32351ee4d233c8a434ff95417a Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Fri, 20 Jan 2023 13:18:38 +1300 Subject: [PATCH 0814/1522] Fix T103971: uv packing wasn't ignoring uv islands on hidden faces Fixes the packing operators that use ED_uvedit_pack_islands_multi Also fixes UV Select Similar with hidden UV islands. Packing operators using GEO_uv_parametrizer should remain unchanged. Add a check to BM_elem_flag_test(efa, BM_ELEM_HIDDEN). Note that BM_mesh_calc_face_groups doesn't easily support XOR of flags, requiring logic to be moved to a preprocess step on BM_ELEM_TAG. Regression in rBe3075f3cf7ce. Differential Revision: https://developer.blender.org/D17055 --- .../blender/editors/uvedit/uvedit_islands.cc | 57 ++++++++++++------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/source/blender/editors/uvedit/uvedit_islands.cc b/source/blender/editors/uvedit/uvedit_islands.cc index ad4527affb8..2d1db757fb5 100644 --- a/source/blender/editors/uvedit/uvedit_islands.cc +++ b/source/blender/editors/uvedit/uvedit_islands.cc @@ -335,6 +335,35 @@ static bool bm_loop_uv_shared_edge_check(const BMLoop *l_a, const BMLoop *l_b, v return BM_loop_uv_share_edge_check((BMLoop *)l_a, (BMLoop *)l_b, data->offsets.uv); } +/** + * returns true if `BMFace *efa` is able to be affected by a packing operation, given various + * parameters. + * + * Checks if it's (not) hidden, and optionally selected, and/or UV selected. + * + * Will eventually be superseded by `BM_uv_element_map_create()`. + * + * Loosely based on`uvedit_is_face_affected`, but "bug-compatible" with previous code. + */ +static bool uvedit_is_face_affected_for_calc_uv_islands(const Scene *scene, + BMFace *efa, + const bool only_selected_faces, + const bool only_selected_uvs, + const BMUVOffsets &uv_offsets) +{ + if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + return false; + } + if (only_selected_faces) { + if (only_selected_uvs) { + return BM_elem_flag_test(efa, BM_ELEM_SELECT) && + uvedit_face_select_test(scene, efa, uv_offsets); + } + return BM_elem_flag_test(efa, BM_ELEM_SELECT); + } + return true; +} + /** * Calculate islands and add them to \a island_list returning the number of items added. */ @@ -356,25 +385,13 @@ int bm_mesh_calc_uv_islands(const Scene *scene, int(*group_index)[2]; - /* Calculate the tag to use. */ - uchar hflag_face_test = 0; - if (only_selected_faces) { - if (only_selected_uvs) { - BMFace *f; - BMIter iter; - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - bool value = false; - if (BM_elem_flag_test(f, BM_ELEM_SELECT) && - uvedit_face_select_test(scene, f, uv_offsets)) { - value = true; - } - BM_elem_flag_set(f, BM_ELEM_TAG, value); - } - hflag_face_test = BM_ELEM_TAG; - } - else { - hflag_face_test = BM_ELEM_SELECT; - } + /* Set the tag for `BM_mesh_calc_face_groups`. */ + BMFace *f; + BMIter iter; + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + const bool face_affected = uvedit_is_face_affected_for_calc_uv_islands( + scene, f, only_selected_faces, only_selected_uvs, uv_offsets); + BM_elem_flag_set(f, BM_ELEM_TAG, face_affected); } struct SharedUVLoopData user_data = {{0}}; @@ -387,7 +404,7 @@ int bm_mesh_calc_uv_islands(const Scene *scene, nullptr, bm_loop_uv_shared_edge_check, &user_data, - hflag_face_test, + BM_ELEM_TAG, BM_EDGE); for (int i = 0; i < group_len; i++) { From 06c836c9114ed2a19de750aeedfc3623f14a961d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Jan 2023 14:42:51 +1100 Subject: [PATCH 0815/1522] WM: rename safe areas preset add operator The name SAFE_AREAS_OT_preset_add lead to "Safe Areas" having it's own section in the operator API docs. Name CAMERA_OT_safe_areas_preset_add instead. Keep "safe_areas" as the preset directory for users with existing presets. --- release/scripts/startup/bl_operators/presets.py | 8 ++++---- release/scripts/startup/bl_ui/properties_data_camera.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/release/scripts/startup/bl_operators/presets.py b/release/scripts/startup/bl_operators/presets.py index e4b9021926e..f8146308600 100644 --- a/release/scripts/startup/bl_operators/presets.py +++ b/release/scripts/startup/bl_operators/presets.py @@ -317,11 +317,11 @@ class AddPresetCamera(AddPresetBase, Operator): return preset_values -class AddPresetSafeAreas(AddPresetBase, Operator): +class AddPresetCameraSafeAreas(AddPresetBase, Operator): """Add or remove a Safe Areas Preset""" - bl_idname = "safe_areas.preset_add" + bl_idname = "camera.safe_areas_preset_add" bl_label = "Add Safe Area Preset" - preset_menu = "SAFE_AREAS_PT_presets" + preset_menu = "CAMERA_PT_safe_areas_presets" preset_defines = [ "safe_areas = bpy.context.scene.safe_areas" @@ -691,7 +691,7 @@ classes = ( AddPresetNodeColor, AddPresetOperator, AddPresetRender, - AddPresetSafeAreas, + AddPresetCameraSafeAreas, AddPresetTrackingCamera, AddPresetTrackingSettings, AddPresetTrackingTrackColor, diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 963ffc60806..0a9a16999b8 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -24,11 +24,11 @@ class CAMERA_PT_presets(PresetPanel, Panel): COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} -class SAFE_AREAS_PT_presets(PresetPanel, Panel): +class CAMERA_PT_safe_areas_presets(PresetPanel, Panel): bl_label = "Camera Presets" preset_subdir = "safe_areas" preset_operator = "script.execute_preset" - preset_add_operator = "safe_areas.preset_add" + preset_add_operator = "camera.safe_areas_preset_add" COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} @@ -427,7 +427,7 @@ class DATA_PT_camera_safe_areas(CameraButtonsPanel, Panel): self.layout.prop(cam, "show_safe_areas", text="") def draw_header_preset(self, _context): - SAFE_AREAS_PT_presets.draw_panel_header(self.layout) + CAMERA_PT_safe_areas_presets.draw_panel_header(self.layout) def draw(self, context): layout = self.layout @@ -503,7 +503,7 @@ def draw_display_safe_settings(layout, safe_data, settings): classes = ( CAMERA_PT_presets, - SAFE_AREAS_PT_presets, + CAMERA_PT_safe_areas_presets, DATA_PT_context_camera, DATA_PT_lens, DATA_PT_camera_dof, From 844cca998435b5e37b2d9c607c24efc21929d8e0 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Jan 2023 15:19:32 +1100 Subject: [PATCH 0816/1522] Cleanup: spelling in comments --- intern/cycles/scene/light.cpp | 4 ++-- source/blender/blenkernel/BKE_nla.h | 2 +- source/blender/blenkernel/BKE_node.h | 2 +- source/blender/blenkernel/intern/DerivedMesh.cc | 5 +++-- source/blender/blenkernel/intern/dynamicpaint.c | 12 ++++++------ source/blender/blenkernel/intern/particle.cc | 3 ++- source/blender/blenkernel/intern/softbody.c | 5 +++-- source/blender/blenlib/BLI_offset_indices.hh | 2 +- source/blender/bmesh/intern/bmesh_interp.c | 4 ++-- source/blender/draw/intern/draw_manager.c | 2 +- source/blender/editors/include/ED_view3d.h | 3 ++- source/blender/editors/include/UI_interface.h | 4 ++-- source/blender/editors/mesh/editmesh_utils.c | 2 +- source/blender/editors/physics/particle_object.c | 2 +- source/blender/editors/space_file/filelist.cc | 2 +- .../transform/transform_convert_armature.c | 2 +- source/blender/editors/uvedit/uvedit_islands.cc | 15 +++++---------- source/blender/editors/uvedit/uvedit_select.c | 6 +++--- .../blender/editors/uvedit/uvedit_smart_stitch.c | 2 +- source/blender/editors/uvedit/uvedit_unwrap_ops.c | 4 ++-- source/blender/geometry/intern/trim_curves.cc | 2 +- .../windowmanager/intern/wm_event_system.cc | 2 +- 22 files changed, 43 insertions(+), 44 deletions(-) diff --git a/intern/cycles/scene/light.cpp b/intern/cycles/scene/light.cpp index 92649563ebd..fa710e8b250 100644 --- a/intern/cycles/scene/light.cpp +++ b/intern/cycles/scene/light.cpp @@ -836,8 +836,8 @@ void LightManager::device_update_background(Device *device, if (sun_average_radiance > 0.0f) { /* The weighting here is just a heuristic that was empirically determined. * The sun's average radiance is much higher than the map's average radiance, - * but we don't want to weight the background light too much becaused - * visibility is not accounted for anyways. */ + * but we don't want to weight the background light too much because + * visibility is not accounted for anyway. */ background_light->set_average_radiance(0.8f * map_average_radiance + 0.2f * sun_average_radiance); } diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h index 3d304859e1b..dd558dc197c 100644 --- a/source/blender/blenkernel/BKE_nla.h +++ b/source/blender/blenkernel/BKE_nla.h @@ -298,7 +298,7 @@ void BKE_nlastrip_recalculate_bounds(struct NlaStrip *strip); void BKE_nlastrip_recalculate_bounds_sync_action(struct NlaStrip *strip); /** - * Recalculate the Blendin and Blendout values after a strip transform update. + * Recalculate the blend-in and blend-out values after a strip transform update. */ void BKE_nlastrip_recalculate_blend(struct NlaStrip *strip); diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index d2f4c6e3b6e..915ca87621a 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -360,7 +360,7 @@ typedef struct bNodeType { ExtensionRNA rna_ext; } bNodeType; -/* nodetype->nclass, for add-menu and themes */ +/** #bNodeType.nclass (for add-menu and themes). */ #define NODE_CLASS_INPUT 0 #define NODE_CLASS_OUTPUT 1 #define NODE_CLASS_OP_COLOR 3 diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index 39a68b72d2a..565009fe08f 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -1220,11 +1220,12 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final, } } else { - /* Same as mesh_calc_modifiers. If using loop normals, poly nors have already been computed. */ + /* Same as #mesh_calc_modifiers. + * If using loop normals, poly normals have already been computed. */ BKE_mesh_ensure_normals_for_display(mesh_final); /* Some modifiers, like data-transfer, may generate those data, we do not want to keep them, - * as they are used by display code when available (i.e. even if autosmooth is disabled). */ + * as they are used by display code when available (i.e. even if auto-smooth is disabled). */ if (CustomData_has_layer(&mesh_final->ldata, CD_NORMAL)) { CustomData_free_layers(&mesh_final->ldata, CD_NORMAL, mesh_final->totloop); } diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index 705e5d56f9b..eff08db9f46 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -922,7 +922,7 @@ static void surface_freeUnusedData(DynamicPaintSurface *surface) return; } - /* free bakedata if not active or surface is baked */ + /* Free bake-data if not active or surface is baked. */ if (!(surface->flags & MOD_DPAINT_ACTIVE) || (surface->pointcache && surface->pointcache->flag & PTCACHE_BAKED)) { free_bakeData(surface->data); @@ -1071,7 +1071,7 @@ DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *c BKE_modifier_path_init( surface->image_output_path, sizeof(surface->image_output_path), "cache_dynamicpaint"); - /* Using ID_BRUSH i18n context, as we have no physics/dpaint one for now... */ + /* Using ID_BRUSH i18n context, as we have no physics/dynamic-paint one for now. */ dynamicPaintSurface_setUniqueName(surface, CTX_DATA_(BLT_I18NCONTEXT_ID_BRUSH, "Surface")); surface->effector_weights = BKE_effector_add_weights(NULL); @@ -5067,7 +5067,7 @@ static void dynamic_paint_prepare_effect_cb(void *__restrict userdata, /* if global gravity is enabled, add it too */ if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { - /* also divide by 10 to about match default grav + /* also divide by 10 to about match default gravity * with default force strength (1.0). */ madd_v3_v3fl(forc, scene->physics_settings.gravity, @@ -5139,9 +5139,9 @@ static int dynamicPaint_prepareEffectStep(struct Depsgraph *depsgraph, } /* Get number of required steps using average point distance - * so that just a few ultra close pixels won't increase substeps to max. */ + * so that just a few ultra close pixels won't increase sub-steps to max. */ - /* adjust number of required substep by fastest active effect */ + /* Adjust number of required sub-step by fastest active effect. */ if (surface->effect & MOD_DPAINT_EFFECT_DO_SPREAD) { spread_speed = surface->spread_speed; } @@ -5811,7 +5811,7 @@ static void dynamic_paint_surface_pre_step_cb(void *__restrict userdata, pPoint->state = DPAINT_PAINT_WET; } - /* in case of just dryed paint, just mix it to the dry layer and mark it empty */ + /* In case of just dried paint, just mix it to the dry layer and mark it empty. */ else if (pPoint->state > 0) { float f_color[4]; blendColors(pPoint->color, pPoint->color[3], pPoint->e_color, pPoint->e_color[3], f_color); diff --git a/source/blender/blenkernel/intern/particle.cc b/source/blender/blenkernel/intern/particle.cc index 296ef405da2..99dfd7fe138 100644 --- a/source/blender/blenkernel/intern/particle.cc +++ b/source/blender/blenkernel/intern/particle.cc @@ -3513,7 +3513,8 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re } } - /* lattices have to be calculated separately to avoid mixups between effector calculations */ + /* Lattices have to be calculated separately to avoid mix-ups between effector calculations. + */ if (psys->lattice_deform_data) { for (k = 0, ca = cache[p]; k <= segments; k++, ca++) { BKE_lattice_deform_data_eval_co( diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index b322a0a803d..83b5fd45d2f 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -2550,11 +2550,12 @@ static void softbody_swap_state(Object *ob, float *ppos, float *pvel) } #endif -/* care for bodypoints taken out of the 'ordinary' solver step +/** + * Care for body-points taken out of the 'ordinary' solver step * because they are screwed to goal by bolts * they just need to move along with the goal in time * we need to adjust them on sub frame timing in solver - * so now when frame is done .. put 'em to the position at the end of frame + * so now when frame is done .. put them to the position at the end of frame. */ static void softbody_apply_goalsnap(Object *ob) { diff --git a/source/blender/blenlib/BLI_offset_indices.hh b/source/blender/blenlib/BLI_offset_indices.hh index 9685266e687..4ae2bde3705 100644 --- a/source/blender/blenlib/BLI_offset_indices.hh +++ b/source/blender/blenlib/BLI_offset_indices.hh @@ -70,7 +70,7 @@ template class OffsetIndices { } /** - * Return a subset of the offsets desribing the specified range of source elements. + * Return a subset of the offsets describing the specified range of source elements. * This is a slice into the source ranges rather than the indexed elements described by the * offset values. */ diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index f96fc734fbc..16db91595ec 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -875,8 +875,8 @@ void BM_uv_map_ensure_select_and_pin_attrs(BMesh *bm) { const int nr_uv_layers = CustomData_number_of_layers(&bm->ldata, CD_PROP_FLOAT2); for (int l = 0; l < nr_uv_layers; l++) { - /* NOTE: you can't re-use the returnvalue of CustomData_get_layer_name() because adding layers - * can invalidate that. */ + /* NOTE: you can't re-use the return-value of #CustomData_get_layer_name() + * because adding layers can invalidate that. */ char name[MAX_CUSTOMDATA_LAYER_NAME]; BM_data_layer_ensure_named( bm, diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 43a2e89b989..0cb89d94d41 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2246,7 +2246,7 @@ void DRW_draw_render_loop_2d_ex(struct Depsgraph *depsgraph, drw_engines_draw_scene(); - /* Fix 3D view being "laggy" on macos and win+nvidia. (See T56996, T61474) */ + /* Fix 3D view being "laggy" on MACOS and MS-Windows+NVIDIA. (See T56996, T61474) */ if (GPU_type_matches_ex(GPU_DEVICE_ANY, GPU_OS_ANY, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) { GPU_flush(); } diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 3526db5cb35..def080b267e 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -75,7 +75,8 @@ typedef struct ViewContext { typedef struct ViewDepths { unsigned short w, h; - short x, y; /* only for temp use for sub-rects, added to region->winx/y */ + /* only for temp use for sub-rectangles, added to `region->winx/winy`. */ + short x, y; float *depths; double depth_range[2]; } ViewDepths; diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index cdc41ef2183..108f8e46966 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -394,7 +394,7 @@ typedef enum { UI_BTYPE_SEPR_LINE = 55 << 9, /** Dynamically fill available space. */ UI_BTYPE_SEPR_SPACER = 56 << 9, - /** Resize handle (resize uilist). */ + /** Resize handle (resize UI-list). */ UI_BTYPE_GRIP = 57 << 9, UI_BTYPE_DECORATOR = 58 << 9, /* An item a view (see #ui::AbstractViewItem). */ @@ -459,7 +459,7 @@ void UI_draw_safe_areas(uint pos, const float title_aspect[2], const float action_aspect[2]); -/** State for scrolldrawing. */ +/** State for scroll-drawing. */ enum { UI_SCROLL_PRESSED = 1 << 0, UI_SCROLL_ARROWS = 1 << 1, diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 764344fbd68..27a43ab93a0 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -887,7 +887,7 @@ static void bm_uv_build_islands(UvElementMap *element_map, MEM_SAFE_FREE(map); } -/* return true if `loop` has UV co-ordinates which match `luv_a` and `luv_b` */ +/** Return true if `loop` has UV co-ordinates which match `luv_a` and `luv_b`. */ static bool loop_uv_match(BMLoop *loop, const float luv_a[2], const float luv_b[2], diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index 58ed94fdbb8..8c26b9caf91 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -415,7 +415,7 @@ void PARTICLE_OT_dupliob_refresh(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/************************ move up particle dupliweight operator *********************/ +/************************ move up particle dupli-weight operator *********************/ static int dupliob_move_up_exec(bContext *C, wmOperator *UNUSED(op)) { diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc index 7a982914878..57a4c5c052a 100644 --- a/source/blender/editors/space_file/filelist.cc +++ b/source/blender/editors/space_file/filelist.cc @@ -3876,7 +3876,7 @@ static void filelist_readjob_all_asset_library(FileListReadJob *job_params, filelist_readjob_main_assets_add_items(job_params, stop, do_update, progress); - /* When only doing partialy reload for main data, we're done. */ + /* When only doing partially reload for main data, we're done. */ if (job_params->only_main_data) { return; } diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index d3bebfe8c72..31d0dea3b96 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -864,7 +864,7 @@ static void createTransPose(bContext *UNUSED(C), TransInfo *t) } } - /* initialize initial auto=ik chainlen's? */ + /* Initialize initial auto=IK chain-length's? */ if (t->flag & T_AUTOIK) { transform_autoik_update(t, 0); } diff --git a/source/blender/editors/uvedit/uvedit_islands.cc b/source/blender/editors/uvedit/uvedit_islands.cc index 2d1db757fb5..612d173772e 100644 --- a/source/blender/editors/uvedit/uvedit_islands.cc +++ b/source/blender/editors/uvedit/uvedit_islands.cc @@ -336,14 +336,13 @@ static bool bm_loop_uv_shared_edge_check(const BMLoop *l_a, const BMLoop *l_b, v } /** - * returns true if `BMFace *efa` is able to be affected by a packing operation, given various - * parameters. + * Returns true if `efa` is able to be affected by a packing operation, given various parameters. * * Checks if it's (not) hidden, and optionally selected, and/or UV selected. * * Will eventually be superseded by `BM_uv_element_map_create()`. * - * Loosely based on`uvedit_is_face_affected`, but "bug-compatible" with previous code. + * Loosely based on `uvedit_is_face_affected`, but "bug-compatible" with previous code. */ static bool uvedit_is_face_affected_for_calc_uv_islands(const Scene *scene, BMFace *efa, @@ -462,8 +461,7 @@ static float pack_islands_margin_fraction(const blender::Vector &i * First, use a robust search procedure to bracket the root within a factor of 10. * Then, use a modified-secant method to converge. * - * This is a specialized solver using domain knowledge to accelerate convergence. - */ + * This is a specialized solver using domain knowledge to accelerate convergence. */ float scale_low = 0.0f; float value_low = 0.0f; @@ -570,11 +568,8 @@ static float calc_margin_from_aabb_length_sum(const blender::Vectorbounds_rect); diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index dc68b2c6475..7595577e160 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -4399,13 +4399,13 @@ static int uv_select_overlap(bContext *C, const bool extend) copy_v2_v2(uv_verts[vert_index], luv); } - /* The winding order of the coordinates is not guaranteed, determine it automatically. */ + /* The UV coordinates winding could be positive of negative, + * determine it automatically. */ const int coords_sign = 0; BLI_polyfill_calc_arena(uv_verts, face_len, coords_sign, indices, arena); /* A beauty fill is necessary to remove degenerate triangles that may be produced from the - * above polyfill (see T103913), otherwise the overlap tests can fail. - */ + * above poly-fill (see T103913), otherwise the overlap tests can fail. */ BLI_polyfill_beautify(uv_verts, face_len, indices, arena, heap); for (int t = 0; t < tri_len; t++) { diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 7a05ffafbcb..189ba7575f5 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -949,7 +949,7 @@ static int stitch_process_data(StitchStateContainer *ssc, bool is_active_state = (state == ssc->states[ssc->active_object_index]); char stitch_midpoints = ssc->midpoints; - /* used to map uv indices to uvaverage indices for selection */ + /* Used to map UV indices to UV-average indices for selection. */ uint *uvfinal_map = NULL; /* per face preview position in preview buffer */ PreviewPosition *preview_position = NULL; diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index e5b3d8998c0..8cd4445d0ff 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -595,10 +595,10 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, /* Modifier initialization data, will control what type of subdivision will happen. */ SubsurfModifierData smd = {{NULL}}; - /* holds a map to editfaces for every subsurfed MFace. + /* Holds a map to edit-faces for every subdivision-surface polygon. * These will be used to get hidden/ selected flags etc. */ BMFace **faceMap; - /* similar to the above, we need a way to map edges to their original ones */ + /* Similar to the above, we need a way to map edges to their original ones. */ BMEdge **edgeMap; const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc index b7faf54bdc5..82b8199a168 100644 --- a/source/blender/geometry/intern/trim_curves.cc +++ b/source/blender/geometry/intern/trim_curves.cc @@ -527,7 +527,7 @@ static void sample_interval_bezier(const Span src_positions, start_point_insert.position, parameter); - /* Update startpoint handle. */ + /* Update start-point handle. */ dst_handles_l[dst_range.first()] = end_point_insert.handle_next; } else { diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index 9004bfc0e4b..bf549cd00c9 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -5591,7 +5591,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, void } else if (event.keymodifier == EVT_UNKNOWNKEY) { /* This case happens with an external number-pad, and also when using 'dead keys' - * (to compose complex latin characters e.g.), it's not really clear why. + * (to compose complex Latin characters e.g.), it's not really clear why. * Since it's impossible to map a key modifier to an unknown key, * it shouldn't harm to clear it. */ event_state->keymodifier = event.keymodifier = 0; From 1e8cc72f85f0c759696176011ce13f0e7475d0a4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Jan 2023 15:20:02 +1100 Subject: [PATCH 0817/1522] Cleanup: corrections, clarification to do comments --- source/blender/editors/include/UI_interface.h | 2 +- source/blender/editors/mesh/editmesh_utils.c | 1 + source/blender/editors/transform/transform_snap_object.cc | 4 ++-- source/blender/io/collada/MeshImporter.cpp | 1 - source/blender/modifiers/intern/MOD_solidify_extrude.cc | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 108f8e46966..db3f0dc41fb 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -2036,7 +2036,7 @@ enum { UI_TEMPLATE_OP_PROPS_NO_SPLIT_LAYOUT = 1 << 4, }; -/* used for transp checkers */ +/* Used for transparent checkers shown under color buttons that have an alpha component. */ #define UI_ALPHA_CHECKER_DARK 100 #define UI_ALPHA_CHECKER_LIGHT 160 diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 27a43ab93a0..f54284ef81a 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -912,6 +912,7 @@ static bool loop_uv_match(BMLoop *loop, * \param edge: Search for `needle` in all loops connected to `edge` (recursively). * \param luv_anchor: The UV of the anchor (vertex that's being stepped around). * \param luv_fan: The UV of the outer edge, this changes as the fan is stepped over. + * \param needle: Search for this loop, also defines the vertex at the center of the face-fan. * \param visited: A set of edges to prevent recursing down the same edge multiple times. * \param cd_loop_uv_offset: The UV layer. * \return true if there are edges that fan between them that are seam-free. diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index 39e0fa1fc16..923c1a2ff99 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -63,13 +63,13 @@ enum eViewProj { VIEW_PROJ_PERSP = -1, }; -/* SnapObjectContext.cache.editmesh_map */ +/** #SnapObjectContext.editmesh_caches */ struct SnapData_EditMesh { /* Verts, Edges. */ BVHTree *bvhtree[2]; bool cached[2]; - /* Looptris. */ + /* BVH tree from #BMEditMesh.looptris. */ BVHTreeFromEditMesh treedata_editmesh; blender::bke::MeshRuntime *mesh_runtime; diff --git a/source/blender/io/collada/MeshImporter.cpp b/source/blender/io/collada/MeshImporter.cpp index 096376cfe19..52eb852e1ed 100644 --- a/source/blender/io/collada/MeshImporter.cpp +++ b/source/blender/io/collada/MeshImporter.cpp @@ -717,7 +717,6 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, for (uint uvset_index = 0; uvset_index < index_list_array_uvcoord.getCount(); uvset_index++) { - /* get mtface by face index and uv set index */ COLLADAFW::IndexList &index_list = *index_list_array_uvcoord[uvset_index]; blender::float2 *mloopuv = static_cast( CustomData_get_layer_named_for_write( diff --git a/source/blender/modifiers/intern/MOD_solidify_extrude.cc b/source/blender/modifiers/intern/MOD_solidify_extrude.cc index cbca9c3527d..2c51c430e1e 100644 --- a/source/blender/modifiers/intern/MOD_solidify_extrude.cc +++ b/source/blender/modifiers/intern/MOD_solidify_extrude.cc @@ -392,7 +392,7 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex &result->edata, CD_BWEIGHT, CD_SET_DEFAULT, nullptr, result->totedge)); } - /* initializes: (i_end, do_shell_align, mv). */ + /* Initializes: (`i_end`, `do_shell_align`, `vert_index`). */ #define INIT_VERT_ARRAY_OFFSETS(test) \ if (((ofs_new >= ofs_orig) == do_flip) == test) { \ i_end = verts_num; \ From bbc35fef25b369e4008e233da979879d0b3f0dbb Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 19 Jan 2023 21:40:50 -0600 Subject: [PATCH 0818/1522] Cleanup: Remove remaining subdiv/subsurf files to C++ For continued refactoring of the Mesh data structure. See T103343. --- source/blender/blenkernel/BKE_multires.h | 2 +- source/blender/blenkernel/CMakeLists.txt | 28 +- .../blenkernel/intern/{subdiv.c => subdiv.cc} | 32 +- .../{subdiv_ccg_mask.c => subdiv_ccg_mask.cc} | 30 +- ..._ccg_material.c => subdiv_ccg_material.cc} | 8 +- ...subdiv_converter.c => subdiv_converter.cc} | 2 +- .../blenkernel/intern/subdiv_converter.h | 8 + ...verter_mesh.c => subdiv_converter_mesh.cc} | 75 ++-- .../{subdiv_deform.c => subdiv_deform.cc} | 51 +-- ..._displacement.c => subdiv_displacement.cc} | 6 +- ...ires.c => subdiv_displacement_multires.cc} | 56 +-- .../intern/{subdiv_eval.c => subdiv_eval.cc} | 44 +- .../{subdiv_foreach.c => subdiv_foreach.cc} | 64 +-- .../{subdiv_stats.c => subdiv_stats.cc} | 0 .../{subdiv_topology.c => subdiv_topology.cc} | 2 +- .../intern/{subsurf_ccg.c => subsurf_ccg.cc} | 386 +++++++++--------- 16 files changed, 406 insertions(+), 388 deletions(-) rename source/blender/blenkernel/intern/{subdiv.c => subdiv.cc} (90%) rename source/blender/blenkernel/intern/{subdiv_ccg_mask.c => subdiv_ccg_mask.cc} (86%) rename source/blender/blenkernel/intern/{subdiv_ccg_material.c => subdiv_ccg_material.cc} (87%) rename source/blender/blenkernel/intern/{subdiv_converter.c => subdiv_converter.cc} (96%) rename source/blender/blenkernel/intern/{subdiv_converter_mesh.c => subdiv_converter_mesh.cc} (81%) rename source/blender/blenkernel/intern/{subdiv_deform.c => subdiv_deform.cc} (82%) rename source/blender/blenkernel/intern/{subdiv_displacement.c => subdiv_displacement.cc} (73%) rename source/blender/blenkernel/intern/{subdiv_displacement_multires.c => subdiv_displacement_multires.cc} (91%) rename source/blender/blenkernel/intern/{subdiv_eval.c => subdiv_eval.cc} (91%) rename source/blender/blenkernel/intern/{subdiv_foreach.c => subdiv_foreach.cc} (98%) rename source/blender/blenkernel/intern/{subdiv_stats.c => subdiv_stats.cc} (100%) rename source/blender/blenkernel/intern/{subdiv_topology.c => subdiv_topology.cc} (84%) rename source/blender/blenkernel/intern/{subsurf_ccg.c => subsurf_ccg.cc} (83%) diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 5e5ca8b4ee6..7c8c13ac8b2 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -41,7 +41,7 @@ void multires_flush_sculpt_updates(struct Object *object); void multires_force_sculpt_rebuild(struct Object *object); void multires_force_external_reload(struct Object *object); -/* internal, only called in subsurf_ccg.c */ +/* internal, only called in subsurf_ccg.cc */ void multires_modifier_update_mdisps(struct DerivedMesh *dm, struct Scene *scene); void multires_modifier_update_hidden(struct DerivedMesh *dm); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 70da6b22672..77c16b6924c 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -268,22 +268,22 @@ set(SRC intern/sound.c intern/speaker.c intern/studiolight.c - intern/subdiv.c + intern/subdiv.cc intern/subdiv_ccg.cc - intern/subdiv_ccg_mask.c - intern/subdiv_ccg_material.c - intern/subdiv_converter.c - intern/subdiv_converter_mesh.c - intern/subdiv_deform.c - intern/subdiv_displacement.c - intern/subdiv_displacement_multires.c - intern/subdiv_eval.c - intern/subdiv_foreach.c + intern/subdiv_ccg_mask.cc + intern/subdiv_ccg_material.cc + intern/subdiv_converter.cc + intern/subdiv_converter_mesh.cc + intern/subdiv_deform.cc + intern/subdiv_displacement.cc + intern/subdiv_displacement_multires.cc + intern/subdiv_eval.cc + intern/subdiv_foreach.cc intern/subdiv_mesh.cc intern/subdiv_modifier.cc - intern/subdiv_stats.c - intern/subdiv_topology.c - intern/subsurf_ccg.c + intern/subdiv_stats.cc + intern/subdiv_topology.cc + intern/subsurf_ccg.cc intern/text.c intern/text_suggestions.c intern/texture.cc @@ -848,4 +848,4 @@ if(WITH_GTESTS) # RNA_prototypes.h add_dependencies(bf_blenkernel_tests bf_rna) -endif() \ No newline at end of file +endif() diff --git a/source/blender/blenkernel/intern/subdiv.c b/source/blender/blenkernel/intern/subdiv.cc similarity index 90% rename from source/blender/blenkernel/intern/subdiv.c rename to source/blender/blenkernel/intern/subdiv.cc index 9098c010747..50d6248f0b5 100644 --- a/source/blender/blenkernel/intern/subdiv.c +++ b/source/blender/blenkernel/intern/subdiv.cc @@ -96,7 +96,7 @@ bool BKE_subdiv_settings_equal(const SubdivSettings *settings_a, const SubdivSet /* Creation from scratch. */ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, - struct OpenSubdiv_Converter *converter) + OpenSubdiv_Converter *converter) { SubdivStats stats; BKE_subdiv_stats_init(&stats); @@ -104,7 +104,7 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, OpenSubdiv_TopologyRefinerSettings topology_refiner_settings; topology_refiner_settings.level = settings->level; topology_refiner_settings.is_adaptive = settings->is_adaptive; - struct OpenSubdiv_TopologyRefiner *osd_topology_refiner = NULL; + OpenSubdiv_TopologyRefiner *osd_topology_refiner = nullptr; if (converter->getNumVertices(converter) != 0) { osd_topology_refiner = openSubdiv_createTopologyRefinerFromConverter( converter, &topology_refiner_settings); @@ -114,11 +114,11 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, * The thing here is: OpenSubdiv can only deal with faces, but our * side of subdiv also deals with loose vertices and edges. */ } - Subdiv *subdiv = MEM_callocN(sizeof(Subdiv), "subdiv from converter"); + Subdiv *subdiv = MEM_cnew(__func__); subdiv->settings = *settings; subdiv->topology_refiner = osd_topology_refiner; - subdiv->evaluator = NULL; - subdiv->displacement_evaluator = NULL; + subdiv->evaluator = nullptr; + subdiv->displacement_evaluator = nullptr; BKE_subdiv_stats_end(&stats, SUBDIV_STATS_TOPOLOGY_REFINER_CREATION_TIME); subdiv->stats = stats; return subdiv; @@ -127,7 +127,7 @@ Subdiv *BKE_subdiv_new_from_converter(const SubdivSettings *settings, Subdiv *BKE_subdiv_new_from_mesh(const SubdivSettings *settings, const Mesh *mesh) { if (mesh->totvert == 0) { - return NULL; + return nullptr; } OpenSubdiv_Converter converter; BKE_subdiv_converter_init_for_mesh(&converter, settings, mesh); @@ -144,7 +144,7 @@ Subdiv *BKE_subdiv_update_from_converter(Subdiv *subdiv, { /* Check if the existing descriptor can be re-used. */ bool can_reuse_subdiv = true; - if (subdiv != NULL && subdiv->topology_refiner != NULL) { + if (subdiv != nullptr && subdiv->topology_refiner != nullptr) { if (!BKE_subdiv_settings_equal(&subdiv->settings, settings)) { can_reuse_subdiv = false; } @@ -162,7 +162,7 @@ Subdiv *BKE_subdiv_update_from_converter(Subdiv *subdiv, return subdiv; } /* Create new subdiv. */ - if (subdiv != NULL) { + if (subdiv != nullptr) { BKE_subdiv_free(subdiv); } return BKE_subdiv_new_from_converter(settings, converter); @@ -183,7 +183,7 @@ Subdiv *BKE_subdiv_update_from_mesh(Subdiv *subdiv, void BKE_subdiv_free(Subdiv *subdiv) { - if (subdiv->evaluator != NULL) { + if (subdiv->evaluator != nullptr) { const eOpenSubdivEvaluator evaluator_type = subdiv->evaluator->type; if (evaluator_type != OPENSUBDIV_EVALUATOR_CPU) { /* Let the draw code do the freeing, to ensure that the OpenGL context is valid. */ @@ -192,11 +192,11 @@ void BKE_subdiv_free(Subdiv *subdiv) } openSubdiv_deleteEvaluator(subdiv->evaluator); } - if (subdiv->topology_refiner != NULL) { + if (subdiv->topology_refiner != nullptr) { openSubdiv_deleteTopologyRefiner(subdiv->topology_refiner); } BKE_subdiv_displacement_detach(subdiv); - if (subdiv->cache_.face_ptex_offset != NULL) { + if (subdiv->cache_.face_ptex_offset != nullptr) { MEM_freeN(subdiv->cache_.face_ptex_offset); } MEM_freeN(subdiv); @@ -208,16 +208,16 @@ void BKE_subdiv_free(Subdiv *subdiv) int *BKE_subdiv_face_ptex_offset_get(Subdiv *subdiv) { - if (subdiv->cache_.face_ptex_offset != NULL) { + if (subdiv->cache_.face_ptex_offset != nullptr) { return subdiv->cache_.face_ptex_offset; } OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; - if (topology_refiner == NULL) { - return NULL; + if (topology_refiner == nullptr) { + return nullptr; } const int num_coarse_faces = topology_refiner->getNumFaces(topology_refiner); - subdiv->cache_.face_ptex_offset = MEM_malloc_arrayN( - num_coarse_faces + 1, sizeof(int), "subdiv face_ptex_offset"); + subdiv->cache_.face_ptex_offset = static_cast( + MEM_malloc_arrayN(num_coarse_faces + 1, sizeof(int), __func__)); int ptex_offset = 0; for (int face_index = 0; face_index < num_coarse_faces; face_index++) { const int num_ptex_faces = topology_refiner->getNumFacePtexFaces(topology_refiner, face_index); diff --git a/source/blender/blenkernel/intern/subdiv_ccg_mask.c b/source/blender/blenkernel/intern/subdiv_ccg_mask.cc similarity index 86% rename from source/blender/blenkernel/intern/subdiv_ccg_mask.c rename to source/blender/blenkernel/intern/subdiv_ccg_mask.cc index 86891f0fa6e..538c4c5eaf4 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg_mask.c +++ b/source/blender/blenkernel/intern/subdiv_ccg_mask.cc @@ -5,7 +5,7 @@ * \ingroup bke */ -#include +#include #include "BKE_subdiv_ccg.h" @@ -22,12 +22,12 @@ #include "MEM_guardedalloc.h" -typedef struct PolyCornerIndex { +struct PolyCornerIndex { int poly_index; int corner; -} PolyCornerIndex; +}; -typedef struct GridPaintMaskData { +struct GridPaintMaskData { // int grid_size; const MPoly *mpoly; const GridPaintMask *grid_paint_mask; @@ -38,7 +38,7 @@ typedef struct GridPaintMaskData { * there we only have one ptex. */ PolyCornerIndex *ptex_poly_corner; -} GridPaintMaskData; +}; static int mask_get_grid_and_coord(SubdivCCGMaskEvaluator *mask_evaluator, const int ptex_face_index, @@ -48,7 +48,7 @@ static int mask_get_grid_and_coord(SubdivCCGMaskEvaluator *mask_evaluator, float *grid_u, float *grid_v) { - GridPaintMaskData *data = mask_evaluator->user_data; + GridPaintMaskData *data = static_cast(mask_evaluator->user_data); const PolyCornerIndex *poly_corner = &data->ptex_poly_corner[ptex_face_index]; const MPoly *poly = &data->mpoly[poly_corner->poly_index]; const int start_grid_index = poly->loopstart + poly_corner->corner; @@ -70,7 +70,7 @@ BLI_INLINE float read_mask_grid(const GridPaintMask *mask_grid, const float grid_u, const float grid_v) { - if (mask_grid->data == NULL) { + if (mask_grid->data == nullptr) { return 0; } const int grid_size = BKE_subdiv_grid_size_from_level(mask_grid->level); @@ -92,7 +92,7 @@ static float eval_mask(SubdivCCGMaskEvaluator *mask_evaluator, static void free_mask_data(SubdivCCGMaskEvaluator *mask_evaluator) { - GridPaintMaskData *data = mask_evaluator->user_data; + GridPaintMaskData *data = static_cast(mask_evaluator->user_data); MEM_freeN(data->ptex_poly_corner); MEM_freeN(data); } @@ -113,12 +113,12 @@ static int count_num_ptex_faces(const Mesh *mesh) static void mask_data_init_mapping(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh) { - GridPaintMaskData *data = mask_evaluator->user_data; + GridPaintMaskData *data = static_cast(mask_evaluator->user_data); const MPoly *mpoly = BKE_mesh_polys(mesh); const int num_ptex_faces = count_num_ptex_faces(mesh); /* Allocate memory. */ - data->ptex_poly_corner = MEM_malloc_arrayN( - num_ptex_faces, sizeof(*data->ptex_poly_corner), "ptex poly corner"); + data->ptex_poly_corner = static_cast( + MEM_malloc_arrayN(num_ptex_faces, sizeof(*data->ptex_poly_corner), __func__)); /* Fill in offsets. */ int ptex_face_index = 0; PolyCornerIndex *ptex_poly_corner = data->ptex_poly_corner; @@ -141,9 +141,10 @@ static void mask_data_init_mapping(SubdivCCGMaskEvaluator *mask_evaluator, const static void mask_init_data(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh) { - GridPaintMaskData *data = mask_evaluator->user_data; + GridPaintMaskData *data = static_cast(mask_evaluator->user_data); data->mpoly = BKE_mesh_polys(mesh); - data->grid_paint_mask = CustomData_get_layer(&mesh->ldata, CD_GRID_PAINT_MASK); + data->grid_paint_mask = static_cast( + CustomData_get_layer(&mesh->ldata, CD_GRID_PAINT_MASK)); mask_data_init_mapping(mask_evaluator, mesh); } @@ -153,8 +154,7 @@ static void mask_init_functions(SubdivCCGMaskEvaluator *mask_evaluator) mask_evaluator->free = free_mask_data; } -bool BKE_subdiv_ccg_mask_init_from_paint(SubdivCCGMaskEvaluator *mask_evaluator, - const struct Mesh *mesh) +bool BKE_subdiv_ccg_mask_init_from_paint(SubdivCCGMaskEvaluator *mask_evaluator, const Mesh *mesh) { if (!CustomData_get_layer(&mesh->ldata, CD_GRID_PAINT_MASK)) { return false; diff --git a/source/blender/blenkernel/intern/subdiv_ccg_material.c b/source/blender/blenkernel/intern/subdiv_ccg_material.cc similarity index 87% rename from source/blender/blenkernel/intern/subdiv_ccg_material.c rename to source/blender/blenkernel/intern/subdiv_ccg_material.cc index 891e1d1b630..23f5371b504 100644 --- a/source/blender/blenkernel/intern/subdiv_ccg_material.c +++ b/source/blender/blenkernel/intern/subdiv_ccg_material.cc @@ -13,11 +13,11 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" -typedef struct CCGMaterialFromMeshData { +struct CCGMaterialFromMeshData { const Mesh *mesh; const MPoly *polys; const int *material_indices; -} CCGMaterialFromMeshData; +}; static DMFlagMat subdiv_ccg_material_flags_eval( SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator, const int coarse_face_index) @@ -40,8 +40,8 @@ static void subdiv_ccg_material_flags_free( void BKE_subdiv_ccg_material_flags_init_from_mesh( SubdivCCGMaterialFlagsEvaluator *material_flags_evaluator, const Mesh *mesh) { - CCGMaterialFromMeshData *data = MEM_mallocN(sizeof(CCGMaterialFromMeshData), - "ccg material eval"); + CCGMaterialFromMeshData *data = static_cast( + MEM_mallocN(sizeof(CCGMaterialFromMeshData), __func__)); data->mesh = mesh; data->material_indices = (const int *)CustomData_get_layer_named( &mesh->pdata, CD_PROP_INT32, "material_index"); diff --git a/source/blender/blenkernel/intern/subdiv_converter.c b/source/blender/blenkernel/intern/subdiv_converter.cc similarity index 96% rename from source/blender/blenkernel/intern/subdiv_converter.c rename to source/blender/blenkernel/intern/subdiv_converter.cc index 1d92d845b36..33c14fc50a9 100644 --- a/source/blender/blenkernel/intern/subdiv_converter.c +++ b/source/blender/blenkernel/intern/subdiv_converter.cc @@ -11,7 +11,7 @@ #include "opensubdiv_converter_capi.h" -void BKE_subdiv_converter_free(struct OpenSubdiv_Converter *converter) +void BKE_subdiv_converter_free(OpenSubdiv_Converter *converter) { if (converter->freeUserData) { converter->freeUserData(converter); diff --git a/source/blender/blenkernel/intern/subdiv_converter.h b/source/blender/blenkernel/intern/subdiv_converter.h index 88be0306461..1f1674bc87e 100644 --- a/source/blender/blenkernel/intern/subdiv_converter.h +++ b/source/blender/blenkernel/intern/subdiv_converter.h @@ -9,6 +9,10 @@ #include "BKE_subdiv.h" +#ifdef __cplusplus +extern "C" { +#endif + /* NOTE: Was initially used to get proper enumerator types, but this makes * it tricky to compile without OpenSubdiv. */ /* #include "opensubdiv_converter_capi.h" */ @@ -34,3 +38,7 @@ int BKE_subdiv_converter_vtx_boundary_interpolation_from_settings(const SubdivSe /* TODO(sergey): Find a way to make it OpenSubdiv_FVarLinearInterpolation, * without breaking compilation without OpenSubdiv. */ int BKE_subdiv_converter_fvar_linear_from_settings(const SubdivSettings *settings); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/blenkernel/intern/subdiv_converter_mesh.c b/source/blender/blenkernel/intern/subdiv_converter_mesh.cc similarity index 81% rename from source/blender/blenkernel/intern/subdiv_converter_mesh.c rename to source/blender/blenkernel/intern/subdiv_converter_mesh.cc index 64d31ed7f58..05fa391dcaa 100644 --- a/source/blender/blenkernel/intern/subdiv_converter_mesh.c +++ b/source/blender/blenkernel/intern/subdiv_converter_mesh.cc @@ -7,7 +7,7 @@ #include "subdiv_converter.h" -#include +#include #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -31,7 +31,7 @@ * This forces Catmark scheme with all edges marked as infinitely sharp. */ #define BUGGY_SIMPLE_SCHEME_WORKAROUND 1 -typedef struct ConverterStorage { +struct ConverterStorage { SubdivSettings settings; const Mesh *mesh; const float (*vert_positions)[3]; @@ -66,7 +66,7 @@ typedef struct ConverterStorage { /* Number of non-loose elements. */ int num_manifold_vertices; int num_manifold_edges; -} ConverterStorage; +}; static OpenSubdiv_SchemeType get_scheme_type(const OpenSubdiv_Converter *converter) { @@ -74,7 +74,7 @@ static OpenSubdiv_SchemeType get_scheme_type(const OpenSubdiv_Converter *convert (void)converter; return OSD_SCHEME_CATMARK; #else - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); if (storage->settings.is_simple) { return OSD_SCHEME_BILINEAR; } @@ -85,45 +85,47 @@ static OpenSubdiv_SchemeType get_scheme_type(const OpenSubdiv_Converter *convert } static OpenSubdiv_VtxBoundaryInterpolation get_vtx_boundary_interpolation( - const struct OpenSubdiv_Converter *converter) + const OpenSubdiv_Converter *converter) { - ConverterStorage *storage = converter->user_data; - return BKE_subdiv_converter_vtx_boundary_interpolation_from_settings(&storage->settings); + ConverterStorage *storage = static_cast(converter->user_data); + return OpenSubdiv_VtxBoundaryInterpolation( + BKE_subdiv_converter_vtx_boundary_interpolation_from_settings(&storage->settings)); } static OpenSubdiv_FVarLinearInterpolation get_fvar_linear_interpolation( const OpenSubdiv_Converter *converter) { - ConverterStorage *storage = converter->user_data; - return BKE_subdiv_converter_fvar_linear_from_settings(&storage->settings); + ConverterStorage *storage = static_cast(converter->user_data); + return OpenSubdiv_FVarLinearInterpolation( + BKE_subdiv_converter_fvar_linear_from_settings(&storage->settings)); } -static bool specifies_full_topology(const OpenSubdiv_Converter *UNUSED(converter)) +static bool specifies_full_topology(const OpenSubdiv_Converter * /*converter*/) { return false; } static int get_num_faces(const OpenSubdiv_Converter *converter) { - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); return storage->mesh->totpoly; } static int get_num_edges(const OpenSubdiv_Converter *converter) { - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); return storage->num_manifold_edges; } static int get_num_vertices(const OpenSubdiv_Converter *converter) { - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); return storage->num_manifold_vertices; } static int get_num_face_vertices(const OpenSubdiv_Converter *converter, int manifold_face_index) { - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); return storage->polys[manifold_face_index].totloop; } @@ -131,7 +133,7 @@ static void get_face_vertices(const OpenSubdiv_Converter *converter, int manifold_face_index, int *manifold_face_vertices) { - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); const MPoly *poly = &storage->polys[manifold_face_index]; const MLoop *mloop = storage->loops; for (int corner = 0; corner < poly->totloop; corner++) { @@ -144,7 +146,7 @@ static void get_edge_vertices(const OpenSubdiv_Converter *converter, int manifold_edge_index, int *manifold_edge_vertices) { - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); const int edge_index = storage->manifold_edge_index_reverse[manifold_edge_index]; const MEdge *edge = &storage->edges[edge_index]; manifold_edge_vertices[0] = storage->manifold_vertex_index[edge->v1]; @@ -153,7 +155,7 @@ static void get_edge_vertices(const OpenSubdiv_Converter *converter, static float get_edge_sharpness(const OpenSubdiv_Converter *converter, int manifold_edge_index) { - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); #if BUGGY_SIMPLE_SCHEME_WORKAROUND if (storage->settings.is_simple) { return 10.0f; @@ -169,7 +171,7 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter, int manif static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter, int manifold_vertex_index) { - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); #if BUGGY_SIMPLE_SCHEME_WORKAROUND if (storage->settings.is_simple) { return true; @@ -181,7 +183,7 @@ static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter, static float get_vertex_sharpness(const OpenSubdiv_Converter *converter, int manifold_vertex_index) { - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); if (!storage->settings.use_creases || storage->cd_vertex_crease == NULL) { return 0.0f; } @@ -191,23 +193,24 @@ static float get_vertex_sharpness(const OpenSubdiv_Converter *converter, int man static int get_num_uv_layers(const OpenSubdiv_Converter *converter) { - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); const Mesh *mesh = storage->mesh; return CustomData_number_of_layers(&mesh->ldata, CD_PROP_FLOAT2); } static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int layer_index) { - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); const Mesh *mesh = storage->mesh; - const float(*mloopuv)[2] = CustomData_get_layer_n(&mesh->ldata, CD_PROP_FLOAT2, layer_index); + const float(*mloopuv)[2] = static_cast( + CustomData_get_layer_n(&mesh->ldata, CD_PROP_FLOAT2, layer_index)); const int num_poly = mesh->totpoly; const int num_vert = mesh->totvert; const float limit[2] = {STD_UV_CONNECT_LIMIT, STD_UV_CONNECT_LIMIT}; /* Initialize memory required for the operations. */ if (storage->loop_uv_indices == NULL) { - storage->loop_uv_indices = MEM_malloc_arrayN( - mesh->totloop, sizeof(int), "loop uv vertex index"); + storage->loop_uv_indices = static_cast( + MEM_malloc_arrayN(mesh->totloop, sizeof(int), "loop uv vertex index")); } UvVertMap *uv_vert_map = BKE_mesh_uv_vert_map_create( storage->polys, @@ -241,13 +244,13 @@ static void precalc_uv_layer(const OpenSubdiv_Converter *converter, const int la BKE_mesh_uv_vert_map_free(uv_vert_map); } -static void finish_uv_layer(const OpenSubdiv_Converter *UNUSED(converter)) +static void finish_uv_layer(const OpenSubdiv_Converter * /*converter*/) { } static int get_num_uvs(const OpenSubdiv_Converter *converter) { - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); return storage->num_uv_coordinates; } @@ -255,14 +258,14 @@ static int get_face_corner_uv_index(const OpenSubdiv_Converter *converter, const int face_index, const int corner) { - ConverterStorage *storage = converter->user_data; + ConverterStorage *storage = static_cast(converter->user_data); const MPoly *mp = &storage->polys[face_index]; return storage->loop_uv_indices[mp->loopstart + corner]; } static void free_user_data(const OpenSubdiv_Converter *converter) { - ConverterStorage *user_data = converter->user_data; + ConverterStorage *user_data = static_cast(converter->user_data); MEM_SAFE_FREE(user_data->loop_uv_indices); MEM_freeN(user_data->manifold_vertex_index); MEM_freeN(user_data->infinite_sharp_vertices_map); @@ -315,11 +318,12 @@ static void initialize_manifold_index_array(const BLI_bitmap *used_map, { int *indices = NULL; if (r_indices != NULL) { - indices = MEM_malloc_arrayN(num_elements, sizeof(int), "manifold indices"); + indices = static_cast(MEM_malloc_arrayN(num_elements, sizeof(int), "manifold indices")); } int *indices_reverse = NULL; if (r_indices_reverse != NULL) { - indices_reverse = MEM_malloc_arrayN(num_elements, sizeof(int), "manifold indices reverse"); + indices_reverse = static_cast( + MEM_malloc_arrayN(num_elements, sizeof(int), "manifold indices reverse")); } int offset = 0; for (int i = 0; i < num_elements; i++) { @@ -392,21 +396,24 @@ static void init_user_data(OpenSubdiv_Converter *converter, const SubdivSettings *settings, const Mesh *mesh) { - ConverterStorage *user_data = MEM_mallocN(sizeof(ConverterStorage), __func__); + ConverterStorage *user_data = static_cast( + MEM_mallocN(sizeof(ConverterStorage), __func__)); user_data->settings = *settings; user_data->mesh = mesh; user_data->vert_positions = BKE_mesh_vert_positions(mesh); user_data->edges = BKE_mesh_edges(mesh); user_data->polys = BKE_mesh_polys(mesh); user_data->loops = BKE_mesh_loops(mesh); - user_data->cd_vertex_crease = CustomData_get_layer(&mesh->vdata, CD_CREASE); - user_data->cd_edge_crease = CustomData_get_layer(&mesh->edata, CD_CREASE); + user_data->cd_vertex_crease = static_cast( + CustomData_get_layer(&mesh->vdata, CD_CREASE)); + user_data->cd_edge_crease = static_cast( + CustomData_get_layer(&mesh->edata, CD_CREASE)); user_data->loop_uv_indices = NULL; initialize_manifold_indices(user_data); converter->user_data = user_data; } -void BKE_subdiv_converter_init_for_mesh(struct OpenSubdiv_Converter *converter, +void BKE_subdiv_converter_init_for_mesh(OpenSubdiv_Converter *converter, const SubdivSettings *settings, const Mesh *mesh) { diff --git a/source/blender/blenkernel/intern/subdiv_deform.c b/source/blender/blenkernel/intern/subdiv_deform.cc similarity index 82% rename from source/blender/blenkernel/intern/subdiv_deform.c rename to source/blender/blenkernel/intern/subdiv_deform.cc index 4924125bc4d..b5a0d6cb040 100644 --- a/source/blender/blenkernel/intern/subdiv_deform.c +++ b/source/blender/blenkernel/intern/subdiv_deform.cc @@ -27,7 +27,7 @@ /** \name Subdivision context * \{ */ -typedef struct SubdivDeformContext { +struct SubdivDeformContext { const Mesh *coarse_mesh; Subdiv *subdiv; @@ -45,15 +45,15 @@ typedef struct SubdivDeformContext { int *accumulated_counters; bool have_displacement; -} SubdivDeformContext; +}; static void subdiv_mesh_prepare_accumulator(SubdivDeformContext *ctx, int num_vertices) { if (!ctx->have_displacement) { return; } - ctx->accumulated_counters = MEM_calloc_arrayN( - num_vertices, sizeof(*ctx->accumulated_counters), "subdiv accumulated counters"); + ctx->accumulated_counters = static_cast( + MEM_calloc_arrayN(num_vertices, sizeof(*ctx->accumulated_counters), __func__)); } static void subdiv_mesh_context_free(SubdivDeformContext *ctx) @@ -98,46 +98,47 @@ static void subdiv_accumulate_vertex_displacement(SubdivDeformContext *ctx, * \{ */ static bool subdiv_mesh_topology_info(const SubdivForeachContext *foreach_context, - const int UNUSED(num_vertices), - const int UNUSED(num_edges), - const int UNUSED(num_loops), - const int UNUSED(num_polygons), - const int *UNUSED(subdiv_polygon_offset)) + const int /*num_vertices*/, + const int /*num_edges*/, + const int /*num_loops*/, + const int /*num_polygons*/, + const int * /*subdiv_polygon_offset*/) { - SubdivDeformContext *subdiv_context = foreach_context->user_data; + SubdivDeformContext *subdiv_context = static_cast( + foreach_context->user_data); subdiv_mesh_prepare_accumulator(subdiv_context, subdiv_context->coarse_mesh->totvert); return true; } static void subdiv_mesh_vertex_every_corner(const SubdivForeachContext *foreach_context, - void *UNUSED(tls), + void * /*tls*/, const int ptex_face_index, const float u, const float v, const int coarse_vertex_index, - const int UNUSED(coarse_poly_index), - const int UNUSED(coarse_corner), - const int UNUSED(subdiv_vertex_index)) + const int /*coarse_poly_index*/, + const int /*coarse_corner*/, + const int /*subdiv_vertex_index*/) { - SubdivDeformContext *ctx = foreach_context->user_data; + SubdivDeformContext *ctx = static_cast(foreach_context->user_data); subdiv_accumulate_vertex_displacement(ctx, ptex_face_index, u, v, coarse_vertex_index); } static void subdiv_mesh_vertex_corner(const SubdivForeachContext *foreach_context, - void *UNUSED(tls), + void * /*tls*/, const int ptex_face_index, const float u, const float v, const int coarse_vertex_index, - const int UNUSED(coarse_poly_index), - const int UNUSED(coarse_corner), - const int UNUSED(subdiv_vertex_index)) + const int /*coarse_poly_index*/, + const int /*coarse_corner*/, + const int /*subdiv_vertex_index*/) { - SubdivDeformContext *ctx = foreach_context->user_data; + SubdivDeformContext *ctx = static_cast(foreach_context->user_data); BLI_assert(coarse_vertex_index != ORIGINDEX_NONE); BLI_assert(coarse_vertex_index < ctx->num_verts); float inv_num_accumulated = 1.0f; - if (ctx->accumulated_counters != NULL) { + if (ctx->accumulated_counters != nullptr) { inv_num_accumulated = 1.0f / ctx->accumulated_counters[coarse_vertex_index]; } /* Displacement is accumulated in subdiv vertex position. @@ -179,8 +180,8 @@ static void setup_foreach_callbacks(const SubdivDeformContext *subdiv_context, /** \name Public entry point * \{ */ -void BKE_subdiv_deform_coarse_vertices(struct Subdiv *subdiv, - const struct Mesh *coarse_mesh, +void BKE_subdiv_deform_coarse_vertices(Subdiv *subdiv, + const Mesh *coarse_mesh, float (*vertex_cos)[3], int num_verts) { @@ -188,7 +189,7 @@ void BKE_subdiv_deform_coarse_vertices(struct Subdiv *subdiv, /* Make sure evaluator is up to date with possible new topology, and that * is refined for the new positions of coarse vertices. */ if (!BKE_subdiv_eval_begin_from_mesh( - subdiv, coarse_mesh, vertex_cos, SUBDIV_EVALUATOR_TYPE_CPU, NULL)) { + subdiv, coarse_mesh, vertex_cos, SUBDIV_EVALUATOR_TYPE_CPU, nullptr)) { /* This could happen in two situations: * - OpenSubdiv is disabled. * - Something totally bad happened, and OpenSubdiv rejected our @@ -206,7 +207,7 @@ void BKE_subdiv_deform_coarse_vertices(struct Subdiv *subdiv, subdiv_context.subdiv = subdiv; subdiv_context.vertex_cos = vertex_cos; subdiv_context.num_verts = num_verts; - subdiv_context.have_displacement = (subdiv->displacement_evaluator != NULL); + subdiv_context.have_displacement = (subdiv->displacement_evaluator != nullptr); SubdivForeachContext foreach_context; setup_foreach_callbacks(&subdiv_context, &foreach_context); diff --git a/source/blender/blenkernel/intern/subdiv_displacement.c b/source/blender/blenkernel/intern/subdiv_displacement.cc similarity index 73% rename from source/blender/blenkernel/intern/subdiv_displacement.c rename to source/blender/blenkernel/intern/subdiv_displacement.cc index 693c64a18a4..cab5ed6c89e 100644 --- a/source/blender/blenkernel/intern/subdiv_displacement.c +++ b/source/blender/blenkernel/intern/subdiv_displacement.cc @@ -13,12 +13,12 @@ void BKE_subdiv_displacement_detach(Subdiv *subdiv) { - if (subdiv->displacement_evaluator == NULL) { + if (subdiv->displacement_evaluator == nullptr) { return; } - if (subdiv->displacement_evaluator->free != NULL) { + if (subdiv->displacement_evaluator->free != nullptr) { subdiv->displacement_evaluator->free(subdiv->displacement_evaluator); } MEM_freeN(subdiv->displacement_evaluator); - subdiv->displacement_evaluator = NULL; + subdiv->displacement_evaluator = nullptr; } diff --git a/source/blender/blenkernel/intern/subdiv_displacement_multires.c b/source/blender/blenkernel/intern/subdiv_displacement_multires.cc similarity index 91% rename from source/blender/blenkernel/intern/subdiv_displacement_multires.c rename to source/blender/blenkernel/intern/subdiv_displacement_multires.cc index 398a4083ee2..b076a4b7ad5 100644 --- a/source/blender/blenkernel/intern/subdiv_displacement_multires.c +++ b/source/blender/blenkernel/intern/subdiv_displacement_multires.cc @@ -5,7 +5,7 @@ * \ingroup bke */ -#include +#include #include "BKE_subdiv.h" @@ -24,12 +24,12 @@ #include "MEM_guardedalloc.h" -typedef struct PolyCornerIndex { +struct PolyCornerIndex { int poly_index; int corner; -} PolyCornerIndex; +}; -typedef struct MultiresDisplacementData { +struct MultiresDisplacementData { Subdiv *subdiv; int grid_size; /* Mesh is used to read external displacement. */ @@ -49,7 +49,7 @@ typedef struct MultiresDisplacementData { /* Sanity check, is used in debug builds. * Controls that initialize() was called prior to eval_displacement(). */ bool is_initialized; -} MultiresDisplacementData; +}; /* Denotes which grid to use to average value of the displacement read from the * grid which corresponds to the ptex face. */ @@ -68,7 +68,8 @@ static int displacement_get_grid_and_coord(SubdivDisplacement *displacement, float *grid_u, float *grid_v) { - MultiresDisplacementData *data = displacement->user_data; + MultiresDisplacementData *data = static_cast( + displacement->user_data); const PolyCornerIndex *poly_corner = &data->ptex_poly_corner[ptex_face_index]; const MPoly *poly = &data->mpoly[poly_corner->poly_index]; const int start_grid_index = poly->loopstart + poly_corner->corner; @@ -91,7 +92,8 @@ static const MDisps *displacement_get_other_grid(SubdivDisplacement *displacemen const int corner, const int corner_delta) { - MultiresDisplacementData *data = displacement->user_data; + MultiresDisplacementData *data = static_cast( + displacement->user_data); const PolyCornerIndex *poly_corner = &data->ptex_poly_corner[ptex_face_index]; const MPoly *poly = &data->mpoly[poly_corner->poly_index]; const int effective_corner = (poly->totloop == 4) ? corner : poly_corner->corner; @@ -105,7 +107,7 @@ BLI_INLINE eAverageWith read_displacement_grid(const MDisps *displacement_grid, const float grid_v, float r_tangent_D[3]) { - if (displacement_grid->disps == NULL) { + if (displacement_grid->disps == nullptr) { zero_v3(r_tangent_D); return AVERAGE_WITH_NONE; } @@ -216,7 +218,8 @@ static void average_with_other(SubdivDisplacement *displacement, const int corner_delta, float r_D[3]) { - MultiresDisplacementData *data = displacement->user_data; + MultiresDisplacementData *data = static_cast( + displacement->user_data); const MDisps *other_displacement_grid = displacement_get_other_grid( displacement, ptex_face_index, corner, corner_delta); int other_ptex_face_index, other_corner_index; @@ -239,11 +242,12 @@ static void average_with_other(SubdivDisplacement *displacement, static void average_with_all(SubdivDisplacement *displacement, const int ptex_face_index, const int corner, - const float UNUSED(grid_u), - const float UNUSED(grid_v), + const float /*grid_u*/, + const float /*grid_v*/, float r_D[3]) { - MultiresDisplacementData *data = displacement->user_data; + MultiresDisplacementData *data = static_cast( + displacement->user_data); const PolyCornerIndex *poly_corner = &data->ptex_poly_corner[ptex_face_index]; const MPoly *poly = &data->mpoly[poly_corner->poly_index]; const int num_corners = poly->totloop; @@ -256,7 +260,7 @@ static void average_with_next(SubdivDisplacement *displacement, const int ptex_face_index, const int corner, const float grid_u, - const float UNUSED(grid_v), + const float /*grid_v*/, float r_D[3]) { average_with_other(displacement, ptex_face_index, corner, 0.0f, grid_u, 1, r_D); @@ -265,7 +269,7 @@ static void average_with_next(SubdivDisplacement *displacement, static void average_with_prev(SubdivDisplacement *displacement, const int ptex_face_index, const int corner, - const float UNUSED(grid_u), + const float /*grid_u*/, const float grid_v, float r_D[3]) { @@ -314,7 +318,8 @@ static int displacement_get_face_corner(MultiresDisplacementData *data, static void initialize(SubdivDisplacement *displacement) { - MultiresDisplacementData *data = displacement->user_data; + MultiresDisplacementData *data = static_cast( + displacement->user_data); multiresModifier_ensure_external_read(data->mesh, data->mmd); data->is_initialized = true; } @@ -327,7 +332,8 @@ static void eval_displacement(SubdivDisplacement *displacement, const float dPdv[3], float r_D[3]) { - MultiresDisplacementData *data = displacement->user_data; + MultiresDisplacementData *data = static_cast( + displacement->user_data); BLI_assert(data->is_initialized); const int grid_size = data->grid_size; /* Get displacement in tangent space. */ @@ -351,7 +357,8 @@ static void eval_displacement(SubdivDisplacement *displacement, static void free_displacement(SubdivDisplacement *displacement) { - MultiresDisplacementData *data = displacement->user_data; + MultiresDisplacementData *data = static_cast( + displacement->user_data); MEM_freeN(data->ptex_poly_corner); MEM_freeN(data); } @@ -371,12 +378,13 @@ static int count_num_ptex_faces(const Mesh *mesh) static void displacement_data_init_mapping(SubdivDisplacement *displacement, const Mesh *mesh) { - MultiresDisplacementData *data = displacement->user_data; + MultiresDisplacementData *data = static_cast( + displacement->user_data); const MPoly *mpoly = BKE_mesh_polys(mesh); const int num_ptex_faces = count_num_ptex_faces(mesh); /* Allocate memory. */ - data->ptex_poly_corner = MEM_malloc_arrayN( - num_ptex_faces, sizeof(*data->ptex_poly_corner), "ptex poly corner"); + data->ptex_poly_corner = static_cast( + MEM_malloc_arrayN(num_ptex_faces, sizeof(*data->ptex_poly_corner), "ptex poly corner")); /* Fill in offsets. */ int ptex_face_index = 0; PolyCornerIndex *ptex_poly_corner = data->ptex_poly_corner; @@ -402,13 +410,14 @@ static void displacement_init_data(SubdivDisplacement *displacement, Mesh *mesh, const MultiresModifierData *mmd) { - MultiresDisplacementData *data = displacement->user_data; + MultiresDisplacementData *data = static_cast( + displacement->user_data); data->subdiv = subdiv; data->grid_size = BKE_subdiv_grid_size_from_level(mmd->totlvl); data->mesh = mesh; data->mmd = mmd; data->mpoly = BKE_mesh_polys(mesh); - data->mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS); + data->mdisps = static_cast(CustomData_get_layer(&mesh->ldata, CD_MDISPS)); data->face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv); data->is_initialized = false; displacement_data_init_mapping(displacement, mesh); @@ -433,8 +442,7 @@ void BKE_subdiv_displacement_attach_from_multires(Subdiv *subdiv, return; } /* Allocate all required memory. */ - SubdivDisplacement *displacement = MEM_callocN(sizeof(SubdivDisplacement), - "multires displacement"); + SubdivDisplacement *displacement = MEM_cnew("multires displacement"); displacement->user_data = MEM_callocN(sizeof(MultiresDisplacementData), "multires displacement data"); displacement_init_data(displacement, subdiv, mesh, mmd); diff --git a/source/blender/blenkernel/intern/subdiv_eval.c b/source/blender/blenkernel/intern/subdiv_eval.cc similarity index 91% rename from source/blender/blenkernel/intern/subdiv_eval.c rename to source/blender/blenkernel/intern/subdiv_eval.cc index 302eeacbf2e..b8cda67f642 100644 --- a/source/blender/blenkernel/intern/subdiv_eval.c +++ b/source/blender/blenkernel/intern/subdiv_eval.cc @@ -53,19 +53,19 @@ bool BKE_subdiv_eval_begin(Subdiv *subdiv, const OpenSubdiv_EvaluatorSettings *settings) { BKE_subdiv_stats_reset(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); - if (subdiv->topology_refiner == NULL) { + if (subdiv->topology_refiner == nullptr) { /* Happens on input mesh with just loose geometry, * or when OpenSubdiv is disabled */ return false; } - if (subdiv->evaluator == NULL) { + if (subdiv->evaluator == nullptr) { eOpenSubdivEvaluator opensubdiv_evaluator_type = opensubdiv_evalutor_from_subdiv_evaluator_type(evaluator_type); BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); subdiv->evaluator = openSubdiv_createEvaluatorFromTopologyRefiner( subdiv->topology_refiner, opensubdiv_evaluator_type, evaluator_cache); BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_EVALUATOR_CREATE); - if (subdiv->evaluator == NULL) { + if (subdiv->evaluator == nullptr) { return false; } } @@ -97,7 +97,8 @@ static void set_coarse_positions(Subdiv *subdiv, } } /* Use a temporary buffer so we do not upload vertices one at a time to the GPU. */ - float(*buffer)[3] = MEM_mallocN(sizeof(float[3]) * mesh->totvert, "subdiv tmp coarse positions"); + float(*buffer)[3] = static_cast( + MEM_mallocN(sizeof(float[3]) * mesh->totvert, __func__)); int manifold_vertex_count = 0; for (int vertex_index = 0, manifold_vertex_index = 0; vertex_index < mesh->totvert; vertex_index++) { @@ -105,7 +106,7 @@ static void set_coarse_positions(Subdiv *subdiv, continue; } const float *vertex_co; - if (coarse_vertex_cos != NULL) { + if (coarse_vertex_cos != nullptr) { vertex_co = coarse_vertex_cos[vertex_index]; } else { @@ -122,20 +123,20 @@ static void set_coarse_positions(Subdiv *subdiv, } /* Context which is used to fill face varying data in parallel. */ -typedef struct FaceVaryingDataFromUVContext { +struct FaceVaryingDataFromUVContext { OpenSubdiv_TopologyRefiner *topology_refiner; const Mesh *mesh; const MPoly *polys; const float (*mloopuv)[2]; float (*buffer)[2]; int layer_index; -} FaceVaryingDataFromUVContext; +}; static void set_face_varying_data_from_uv_task(void *__restrict userdata, const int face_index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - FaceVaryingDataFromUVContext *ctx = userdata; + FaceVaryingDataFromUVContext *ctx = static_cast(userdata); OpenSubdiv_TopologyRefiner *topology_refiner = ctx->topology_refiner; const int layer_index = ctx->layer_index; const MPoly *mpoly = &ctx->polys[face_index]; @@ -164,7 +165,8 @@ static void set_face_varying_data_from_uv(Subdiv *subdiv, const int num_fvar_values = topology_refiner->getNumFVarValues(topology_refiner, layer_index); /* Use a temporary buffer so we do not upload UVs one at a time to the GPU. */ - float(*buffer)[2] = MEM_mallocN(sizeof(float[2]) * num_fvar_values, "temp UV storage"); + float(*buffer)[2] = static_cast( + MEM_mallocN(sizeof(float[2]) * num_fvar_values, __func__)); FaceVaryingDataFromUVContext ctx; ctx.topology_refiner = topology_refiner; @@ -188,8 +190,10 @@ static void set_face_varying_data_from_uv(Subdiv *subdiv, static void set_vertex_data_from_orco(Subdiv *subdiv, const Mesh *mesh) { - const float(*orco)[3] = CustomData_get_layer(&mesh->vdata, CD_ORCO); - const float(*cloth_orco)[3] = CustomData_get_layer(&mesh->vdata, CD_CLOTH_ORCO); + const float(*orco)[3] = static_cast( + CustomData_get_layer(&mesh->vdata, CD_ORCO)); + const float(*cloth_orco)[3] = static_cast( + CustomData_get_layer(&mesh->vdata, CD_CLOTH_ORCO)); if (orco || cloth_orco) { OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; @@ -241,7 +245,7 @@ bool BKE_subdiv_eval_refine_from_mesh(Subdiv *subdiv, const Mesh *mesh, const float (*coarse_vertex_cos)[3]) { - if (subdiv->evaluator == NULL) { + if (subdiv->evaluator == nullptr) { /* NOTE: This situation is supposed to be handled by begin(). */ BLI_assert_msg(0, "Is not supposed to happen"); return false; @@ -251,7 +255,8 @@ bool BKE_subdiv_eval_refine_from_mesh(Subdiv *subdiv, /* Set face-varying data to UV maps. */ const int num_uv_layers = CustomData_number_of_layers(&mesh->ldata, CD_PROP_FLOAT2); for (int layer_index = 0; layer_index < num_uv_layers; layer_index++) { - const float(*mloopuv)[2] = CustomData_get_layer_n(&mesh->ldata, CD_PROP_FLOAT2, layer_index); + const float(*mloopuv)[2] = static_cast( + CustomData_get_layer_n(&mesh->ldata, CD_PROP_FLOAT2, layer_index)); set_face_varying_data_from_uv(subdiv, mesh, mloopuv, layer_index); } /* Set vertex data to orco. */ @@ -265,10 +270,10 @@ bool BKE_subdiv_eval_refine_from_mesh(Subdiv *subdiv, void BKE_subdiv_eval_init_displacement(Subdiv *subdiv) { - if (subdiv->displacement_evaluator == NULL) { + if (subdiv->displacement_evaluator == nullptr) { return; } - if (subdiv->displacement_evaluator->initialize == NULL) { + if (subdiv->displacement_evaluator->initialize == nullptr) { return; } subdiv->displacement_evaluator->initialize(subdiv->displacement_evaluator); @@ -281,7 +286,8 @@ void BKE_subdiv_eval_init_displacement(Subdiv *subdiv) void BKE_subdiv_eval_limit_point( Subdiv *subdiv, const int ptex_face_index, const float u, const float v, float r_P[3]) { - BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, r_P, NULL, NULL); + BKE_subdiv_eval_limit_point_and_derivatives( + subdiv, ptex_face_index, u, v, r_P, nullptr, nullptr); } void BKE_subdiv_eval_limit_point_and_derivatives(Subdiv *subdiv, @@ -305,7 +311,7 @@ void BKE_subdiv_eval_limit_point_and_derivatives(Subdiv *subdiv, * which there must be proper derivatives. This might break continuity of normals, but is better * that giving totally unusable derivatives. */ - if (r_dPdu != NULL && r_dPdv != NULL) { + if (r_dPdu != nullptr && r_dPdv != nullptr) { if ((is_zero_v3(r_dPdu) || is_zero_v3(r_dPdv)) || equals_v3v3(r_dPdu, r_dPdv)) { subdiv->evaluator->evaluateLimit(subdiv->evaluator, ptex_face_index, @@ -356,7 +362,7 @@ void BKE_subdiv_eval_displacement(Subdiv *subdiv, const float dPdv[3], float r_D[3]) { - if (subdiv->displacement_evaluator == NULL) { + if (subdiv->displacement_evaluator == nullptr) { zero_v3(r_D); return; } diff --git a/source/blender/blenkernel/intern/subdiv_foreach.c b/source/blender/blenkernel/intern/subdiv_foreach.cc similarity index 98% rename from source/blender/blenkernel/intern/subdiv_foreach.c rename to source/blender/blenkernel/intern/subdiv_foreach.cc index e851c969de8..c39c8717968 100644 --- a/source/blender/blenkernel/intern/subdiv_foreach.c +++ b/source/blender/blenkernel/intern/subdiv_foreach.cc @@ -65,7 +65,7 @@ BLI_INLINE int ptex_face_resolution_get(const MPoly *poly, int resolution) /** \name Context which is passed to all threaded tasks * \{ */ -typedef struct SubdivForeachTaskContext { +struct SubdivForeachTaskContext { const Mesh *coarse_mesh; const MEdge *coarse_edges; const MPoly *coarse_polys; @@ -109,7 +109,7 @@ typedef struct SubdivForeachTaskContext { * were already evaluated. */ BLI_bitmap *coarse_edges_used_map; -} SubdivForeachTaskContext; +}; /** \} */ @@ -120,7 +120,7 @@ typedef struct SubdivForeachTaskContext { static void *subdiv_foreach_tls_alloc(SubdivForeachTaskContext *ctx) { const SubdivForeachContext *foreach_context = ctx->foreach_context; - void *tls = NULL; + void *tls = nullptr; if (foreach_context->user_data_tls_size != 0) { tls = MEM_mallocN(foreach_context->user_data_tls_size, "tls"); memcpy(tls, foreach_context->user_data_tls, foreach_context->user_data_tls_size); @@ -130,10 +130,10 @@ static void *subdiv_foreach_tls_alloc(SubdivForeachTaskContext *ctx) static void subdiv_foreach_tls_free(SubdivForeachTaskContext *ctx, void *tls) { - if (tls == NULL) { + if (tls == nullptr) { return; } - if (ctx->foreach_context != NULL) { + if (ctx->foreach_context != nullptr) { ctx->foreach_context->user_data_tls_free(tls); } MEM_freeN(tls); @@ -260,12 +260,12 @@ static void subdiv_foreach_ctx_init(Subdiv *subdiv, SubdivForeachTaskContext *ct /* Allocate maps and offsets. */ ctx->coarse_vertices_used_map = BLI_BITMAP_NEW(coarse_mesh->totvert, "vertices used map"); ctx->coarse_edges_used_map = BLI_BITMAP_NEW(coarse_mesh->totedge, "edges used map"); - ctx->subdiv_vertex_offset = MEM_malloc_arrayN( - coarse_mesh->totpoly, sizeof(*ctx->subdiv_vertex_offset), "vertex_offset"); - ctx->subdiv_edge_offset = MEM_malloc_arrayN( - coarse_mesh->totpoly, sizeof(*ctx->subdiv_edge_offset), "subdiv_edge_offset"); - ctx->subdiv_polygon_offset = MEM_malloc_arrayN( - coarse_mesh->totpoly, sizeof(*ctx->subdiv_polygon_offset), "subdiv_edge_offset"); + ctx->subdiv_vertex_offset = static_cast(MEM_malloc_arrayN( + coarse_mesh->totpoly, sizeof(*ctx->subdiv_vertex_offset), "vertex_offset")); + ctx->subdiv_edge_offset = static_cast(MEM_malloc_arrayN( + coarse_mesh->totpoly, sizeof(*ctx->subdiv_edge_offset), "subdiv_edge_offset")); + ctx->subdiv_polygon_offset = static_cast(MEM_malloc_arrayN( + coarse_mesh->totpoly, sizeof(*ctx->subdiv_polygon_offset), "subdiv_edge_offset")); /* Initialize all offsets. */ subdiv_foreach_ctx_init_offsets(ctx); /* Calculate number of geometry in the result subdivision mesh. */ @@ -399,7 +399,7 @@ static void subdiv_foreach_every_corner_vertices_special(SubdivForeachTaskContex static void subdiv_foreach_every_corner_vertices(SubdivForeachTaskContext *ctx, void *tls) { - if (ctx->foreach_context->vertex_every_corner == NULL) { + if (ctx->foreach_context->vertex_every_corner == nullptr) { return; } const Mesh *coarse_mesh = ctx->coarse_mesh; @@ -576,7 +576,7 @@ static void subdiv_foreach_every_edge_vertices_special(SubdivForeachTaskContext static void subdiv_foreach_every_edge_vertices(SubdivForeachTaskContext *ctx, void *tls) { - if (ctx->foreach_context->vertex_every_edge == NULL) { + if (ctx->foreach_context->vertex_every_edge == nullptr) { return; } const Mesh *coarse_mesh = ctx->coarse_mesh; @@ -672,7 +672,7 @@ static void subdiv_foreach_inner_vertices(SubdivForeachTaskContext *ctx, /* Traverse all vertices which are emitted from given coarse polygon. */ static void subdiv_foreach_vertices(SubdivForeachTaskContext *ctx, void *tls, const int poly_index) { - if (ctx->foreach_context->vertex_inner != NULL) { + if (ctx->foreach_context->vertex_inner != nullptr) { subdiv_foreach_inner_vertices(ctx, tls, &ctx->coarse_polys[poly_index]); } } @@ -1664,7 +1664,7 @@ static void subdiv_foreach_loose_vertices_task(void *__restrict userdata, const int coarse_vertex_index, const TaskParallelTLS *__restrict tls) { - SubdivForeachTaskContext *ctx = userdata; + SubdivForeachTaskContext *ctx = static_cast(userdata); if (BLI_BITMAP_TEST_BOOL(ctx->coarse_vertices_used_map, coarse_vertex_index)) { /* Vertex is not loose, was handled when handling polygons. */ return; @@ -1678,7 +1678,7 @@ static void subdiv_foreach_vertices_of_loose_edges_task(void *__restrict userdat const int coarse_edge_index, const TaskParallelTLS *__restrict tls) { - SubdivForeachTaskContext *ctx = userdata; + SubdivForeachTaskContext *ctx = static_cast(userdata); if (BLI_BITMAP_TEST_BOOL(ctx->coarse_edges_used_map, coarse_edge_index)) { /* Vertex is not loose, was handled when handling polygons. */ return; @@ -1720,7 +1720,7 @@ static void subdiv_foreach_vertices_of_loose_edges_task(void *__restrict userdat static void subdiv_foreach_single_geometry_vertices(SubdivForeachTaskContext *ctx, void *tls) { - if (ctx->foreach_context->vertex_corner == NULL) { + if (ctx->foreach_context->vertex_corner == nullptr) { return; } const Mesh *coarse_mesh = ctx->coarse_mesh; @@ -1759,10 +1759,10 @@ static void subdiv_foreach_single_thread_tasks(SubdivForeachTaskContext *ctx) subdiv_foreach_tls_free(ctx, tls); const SubdivForeachContext *foreach_context = ctx->foreach_context; - const bool is_loose_geometry_tagged = (foreach_context->vertex_every_edge != NULL && - foreach_context->vertex_every_corner != NULL); - const bool is_loose_geometry_tags_needed = (foreach_context->vertex_loose != NULL || - foreach_context->vertex_of_loose_edge != NULL); + const bool is_loose_geometry_tagged = (foreach_context->vertex_every_edge != nullptr && + foreach_context->vertex_every_corner != nullptr); + const bool is_loose_geometry_tags_needed = (foreach_context->vertex_loose != nullptr || + foreach_context->vertex_of_loose_edge != nullptr); if (is_loose_geometry_tagged && is_loose_geometry_tags_needed) { subdiv_foreach_mark_non_loose_geometry(ctx); } @@ -1772,17 +1772,17 @@ static void subdiv_foreach_task(void *__restrict userdata, const int poly_index, const TaskParallelTLS *__restrict tls) { - SubdivForeachTaskContext *ctx = userdata; + SubdivForeachTaskContext *ctx = static_cast(userdata); /* Traverse hi-poly vertex coordinates and normals. */ subdiv_foreach_vertices(ctx, tls->userdata_chunk, poly_index); /* Traverse mesh geometry for the given base poly index. */ - if (ctx->foreach_context->edge != NULL) { + if (ctx->foreach_context->edge != nullptr) { subdiv_foreach_edges(ctx, tls->userdata_chunk, poly_index); } - if (ctx->foreach_context->loop != NULL) { + if (ctx->foreach_context->loop != nullptr) { subdiv_foreach_loops(ctx, tls->userdata_chunk, poly_index); } - if (ctx->foreach_context->poly != NULL) { + if (ctx->foreach_context->poly != nullptr) { subdiv_foreach_polys(ctx, tls->userdata_chunk, poly_index); } } @@ -1791,13 +1791,13 @@ static void subdiv_foreach_boundary_edges_task(void *__restrict userdata, const int edge_index, const TaskParallelTLS *__restrict tls) { - SubdivForeachTaskContext *ctx = userdata; + SubdivForeachTaskContext *ctx = static_cast(userdata); subdiv_foreach_boundary_edges(ctx, tls->userdata_chunk, edge_index); } static void subdiv_foreach_free(const void *__restrict userdata, void *__restrict userdata_chunk) { - const SubdivForeachTaskContext *ctx = userdata; + const SubdivForeachTaskContext *ctx = static_cast(userdata); ctx->foreach_context->user_data_tls_free(userdata_chunk); } @@ -1814,7 +1814,7 @@ bool BKE_subdiv_foreach_subdiv_geometry(Subdiv *subdiv, ctx.settings = mesh_settings; ctx.foreach_context = context; subdiv_foreach_ctx_init(subdiv, &ctx); - if (context->topology_info != NULL) { + if (context->topology_info != nullptr) { if (!context->topology_info(context, ctx.num_subdiv_vertices, ctx.num_subdiv_edges, @@ -1833,7 +1833,7 @@ bool BKE_subdiv_foreach_subdiv_geometry(Subdiv *subdiv, parallel_range_settings.userdata_chunk = context->user_data_tls; parallel_range_settings.userdata_chunk_size = context->user_data_tls_size; parallel_range_settings.min_iter_per_thread = 1; - if (context->user_data_tls_free != NULL) { + if (context->user_data_tls_free != nullptr) { parallel_range_settings.func_free = subdiv_foreach_free; } @@ -1845,21 +1845,21 @@ bool BKE_subdiv_foreach_subdiv_geometry(Subdiv *subdiv, BLI_task_parallel_range( 0, coarse_mesh->totpoly, &ctx, subdiv_foreach_task, ¶llel_range_settings); - if (context->vertex_loose != NULL) { + if (context->vertex_loose != nullptr) { BLI_task_parallel_range(0, coarse_mesh->totvert, &ctx, subdiv_foreach_loose_vertices_task, ¶llel_range_settings); } - if (context->vertex_of_loose_edge != NULL) { + if (context->vertex_of_loose_edge != nullptr) { BLI_task_parallel_range(0, coarse_mesh->totedge, &ctx, subdiv_foreach_vertices_of_loose_edges_task, ¶llel_range_settings); } - if (context->edge != NULL) { + if (context->edge != nullptr) { BLI_task_parallel_range(0, coarse_mesh->totedge, &ctx, diff --git a/source/blender/blenkernel/intern/subdiv_stats.c b/source/blender/blenkernel/intern/subdiv_stats.cc similarity index 100% rename from source/blender/blenkernel/intern/subdiv_stats.c rename to source/blender/blenkernel/intern/subdiv_stats.cc diff --git a/source/blender/blenkernel/intern/subdiv_topology.c b/source/blender/blenkernel/intern/subdiv_topology.cc similarity index 84% rename from source/blender/blenkernel/intern/subdiv_topology.c rename to source/blender/blenkernel/intern/subdiv_topology.cc index 8dcd4b3517c..fc2cc1b7026 100644 --- a/source/blender/blenkernel/intern/subdiv_topology.c +++ b/source/blender/blenkernel/intern/subdiv_topology.cc @@ -11,7 +11,7 @@ #include "opensubdiv_topology_refiner_capi.h" -int BKE_subdiv_topology_num_fvar_layers_get(const struct Subdiv *subdiv) +int BKE_subdiv_topology_num_fvar_layers_get(const Subdiv *subdiv) { OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner; return topology_refiner->getNumFVarChannels(topology_refiner); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.cc similarity index 83% rename from source/blender/blenkernel/intern/subsurf_ccg.c rename to source/blender/blenkernel/intern/subsurf_ccg.cc index f5835b7fbb8..a7342bb93b0 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.cc @@ -5,18 +5,11 @@ * \ingroup bke */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -# ifdef __GNUC__ -# pragma GCC diagnostic ignored "-Wvla" -# endif -# define USE_DYNSIZE -#endif - -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include "atomic_ops.h" @@ -36,6 +29,7 @@ #include "BLI_task.h" #include "BLI_threads.h" #include "BLI_utildefines.h" +#include "BLI_vector.hh" #include "BKE_ccg.h" #include "BKE_cdderivedmesh.h" @@ -49,10 +43,6 @@ #include "BKE_scene.h" #include "BKE_subsurf.h" -#ifndef USE_DYNSIZE -# include "BLI_array.h" -#endif - #include "CCGSubSurf.h" /* assumes MLoop's are laid out 4 for each poly, in order */ @@ -66,26 +56,26 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, static void *arena_alloc(CCGAllocatorHDL a, int numBytes) { - return BLI_memarena_alloc(a, numBytes); + return BLI_memarena_alloc(reinterpret_cast(a), numBytes); } static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) { - void *p2 = BLI_memarena_alloc(a, newSize); + void *p2 = BLI_memarena_alloc(reinterpret_cast(a), newSize); if (ptr) { memcpy(p2, ptr, oldSize); } return p2; } -static void arena_free(CCGAllocatorHDL UNUSED(a), void *UNUSED(ptr)) +static void arena_free(CCGAllocatorHDL /*a*/, void * /*ptr*/) { /* do nothing */ } static void arena_release(CCGAllocatorHDL a) { - BLI_memarena_free(a); + BLI_memarena_free(reinterpret_cast(a)); } typedef enum { @@ -96,6 +86,7 @@ typedef enum { CCG_ALLOC_MASK = 8, CCG_SIMPLE_SUBDIV = 16, } CCGFlags; +ENUM_OPERATORS(CCGFlags, CCG_SIMPLE_SUBDIV); static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int numLayers, CCGFlags flags) { @@ -111,7 +102,7 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int numLaye if (prevSS) { int oldUseAging; - ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL); + ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, nullptr, nullptr, nullptr); if ((oldUseAging != useAging) || (ccgSubSurf_getSimpleSubdiv(prevSS) != !!(flags & CCG_SIMPLE_SUBDIV))) { @@ -153,7 +144,7 @@ static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int numLaye ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator); } else { - ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL); + ccgSS = ccgSubSurf_new(&ifc, subdivLevels, nullptr, nullptr); } if (useAging) { @@ -240,7 +231,7 @@ static int getFaceIndex( } static void get_face_uv_map_vert( - UvVertMap *vmap, struct MPoly *mpoly, struct MLoop *ml, int fi, CCGVertHDL *fverts) + UvVertMap *vmap, MPoly *mpoly, MLoop *ml, int fi, CCGVertHDL *fverts) { UvMapVert *v, *nv; int j, nverts = mpoly[fi].totloop; @@ -271,11 +262,8 @@ static int ss_sync_from_uv(CCGSubSurf *ss, int i, seam; UvMapVert *v; UvVertMap *vmap; + blender::Vector fverts; float limit[2]; -#ifndef USE_DYNSIZE - CCGVertHDL *fverts = NULL; - BLI_array_declare(fverts); -#endif EdgeSet *eset; float uv[3] = {0.0f, 0.0f, 0.0f}; /* only first 2 values are written into */ @@ -285,7 +273,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, * Also, initially intention is to treat merged vertices from mirror modifier as seams. * This fixes a very old regression (2.49 was correct here) */ vmap = BKE_mesh_uv_vert_map_create( - mpoly, NULL, NULL, mloop, mloopuv, totface, totvert, limit, false, true); + mpoly, nullptr, nullptr, mloop, mloopuv, totface, totvert, limit, false, true); if (!vmap) { return 0; } @@ -304,7 +292,7 @@ static int ss_sync_from_uv(CCGSubSurf *ss, } } - seam = (v != NULL); + seam = (v != nullptr); for (v = BKE_mesh_uv_vert_map_get_vert(vmap, i); v; v = v->next) { if (v->separate) { @@ -330,14 +318,9 @@ static int ss_sync_from_uv(CCGSubSurf *ss, /* uint *fv = &mp->v1; */ MLoop *ml = mloop + mp->loopstart; -#ifdef USE_DYNSIZE - CCGVertHDL fverts[nverts]; -#else - BLI_array_clear(fverts); - BLI_array_grow_items(fverts, nverts); -#endif + fverts.reinitialize(nverts); - get_face_uv_map_vert(vmap, mpoly, ml, i, fverts); + get_face_uv_map_vert(vmap, mpoly, ml, i, fverts.data()); for (j = 0, j_next = nverts - 1; j < nverts; j_next = j++) { uint v0 = POINTER_AS_UINT(fverts[j_next]); @@ -362,21 +345,12 @@ static int ss_sync_from_uv(CCGSubSurf *ss, int nverts = mp->totloop; CCGFace *f; -#ifdef USE_DYNSIZE - CCGVertHDL fverts[nverts]; -#else - BLI_array_clear(fverts); - BLI_array_grow_items(fverts, nverts); -#endif + fverts.reinitialize(nverts); - get_face_uv_map_vert(vmap, mpoly, ml, i, fverts); - ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), nverts, fverts, &f); + get_face_uv_map_vert(vmap, mpoly, ml, i, fverts.data()); + ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), nverts, fverts.data(), &f); } -#ifndef USE_DYNSIZE - BLI_array_free(fverts); -#endif - BKE_mesh_uv_vert_map_free(vmap); ccgSubSurf_processSync(ss); @@ -387,20 +361,21 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh * { CCGFaceIterator fi; int index, gridSize, gridFaces, /*edgeSize,*/ totface, x, y, S; - const float(*dmloopuv)[2] = CustomData_get_layer_n(&dm->loopData, CD_PROP_FLOAT2, n); + const float(*dmloopuv)[2] = static_cast( + CustomData_get_layer_n(&dm->loopData, CD_PROP_FLOAT2, n)); /* need to update both CD_MTFACE & CD_PROP_FLOAT2, hrmf, we could get away with * just tface except applying the modifier then looses subsurf UV */ - MTFace *tface = CustomData_get_layer_n_for_write( - &result->faceData, CD_MTFACE, n, result->numTessFaceData); - float(*mloopuv)[2] = CustomData_get_layer_n_for_write( - &result->loopData, CD_PROP_FLOAT2, n, result->getNumLoops(dm)); + MTFace *tface = static_cast( + CustomData_get_layer_n_for_write(&result->faceData, CD_MTFACE, n, result->numTessFaceData)); + float(*mloopuv)[2] = static_cast(CustomData_get_layer_n_for_write( + &result->loopData, CD_PROP_FLOAT2, n, result->getNumLoops(dm))); if (!dmloopuv || (!tface && !mloopuv)) { return; } /* create a CCGSubSurf from uv's */ - CCGSubSurf *uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 2, CCG_USE_ARENA); + CCGSubSurf *uvss = _getSubSurf(nullptr, ccgSubSurf_getSubdivisionLevels(ss), 2, CCG_USE_ARENA); if (!ss_sync_from_uv(uvss, ss, dm, dmloopuv)) { ccgSubSurf_free(uvss); @@ -414,7 +389,8 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh * gridFaces = gridSize - 1; /* make a map from original faces to CCGFaces */ - CCGFace **faceMap = MEM_mallocN(totface * sizeof(*faceMap), "facemapuv"); + CCGFace **faceMap = static_cast( + MEM_mallocN(totface * sizeof(*faceMap), "facemapuv")); for (ccgSubSurf_initFaceIterator(uvss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) { CCGFace *f = ccgFaceIterator_getCurrent(&fi); @@ -430,7 +406,8 @@ static void set_subsurf_legacy_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh * int numVerts = ccgSubSurf_getFaceNumVerts(f); for (S = 0; S < numVerts; S++) { - float(*faceGridData)[2] = ccgSubSurf_getFaceGridDataArray(uvss, f, S); + float(*faceGridData)[2] = static_cast( + ccgSubSurf_getFaceGridDataArray(uvss, f, S)); for (y = 0; y < gridFaces; y++) { for (x = 0; x < gridFaces; x++) { @@ -472,16 +449,16 @@ static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, #define SUB_ELEMS_FACE 50 typedef float FaceVertWeight[SUB_ELEMS_FACE][SUB_ELEMS_FACE]; -typedef struct FaceVertWeightEntry { +struct FaceVertWeightEntry { FaceVertWeight *weight; float *w; int valid; -} FaceVertWeightEntry; +}; -typedef struct WeightTable { +struct WeightTable { FaceVertWeightEntry *weight_table; int len; -} WeightTable; +}; static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen) { @@ -496,14 +473,15 @@ static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen) MEM_freeN(wtable->weight_table); } - wtable->weight_table = tmp; + wtable->weight_table = static_cast(tmp); wtable->len = faceLen + 1; } if (!wtable->weight_table[faceLen].valid) { wtable->weight_table[faceLen].valid = 1; - wtable->weight_table[faceLen].w = w = MEM_callocN( - sizeof(float) * faceLen * faceLen * (gridCuts + 2) * (gridCuts + 2), "weight table alloc"); + wtable->weight_table[faceLen].w = w = static_cast( + MEM_callocN(sizeof(float) * faceLen * faceLen * (gridCuts + 2) * (gridCuts + 2), + "weight table alloc")); fac = 1.0f / (float)faceLen; for (i = 0; i < faceLen; i++) { @@ -560,10 +538,7 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss, int useFlatSubdiv) { float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss); -#ifndef USE_DYNSIZE - CCGVertHDL *fVerts = NULL; - BLI_array_declare(fVerts); -#endif + blender::Vector fverts; float(*positions)[3] = (float(*)[3])dm->getVertArray(dm); MEdge *medge = dm->getEdgeArray(dm); MEdge *me; @@ -610,23 +585,18 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss, for (i = 0; i < dm->numPolyData; i++, mp++) { CCGFace *f; -#ifdef USE_DYNSIZE - CCGVertHDL fVerts[mp->totloop]; -#else - BLI_array_clear(fVerts); - BLI_array_grow_items(fVerts, mp->totloop); -#endif + fverts.reinitialize(mp->totloop); ml = mloop + mp->loopstart; for (j = 0; j < mp->totloop; j++, ml++) { - fVerts[j] = POINTER_FROM_UINT(ml->v); + fverts[j] = POINTER_FROM_UINT(ml->v); } /* This is very bad, means mesh is internally inconsistent. * it is not really possible to continue without modifying * other parts of code significantly to handle missing faces. * since this really shouldn't even be possible we just bail. */ - if (ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), mp->totloop, fVerts, &f) == + if (ccgSubSurf_syncFace(ss, POINTER_FROM_INT(i), mp->totloop, fverts.data(), &f) == eCCGError_InvalidValue) { static int hasGivenError = 0; @@ -644,17 +614,13 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss, } ccgSubSurf_processSync(ss); - -#ifndef USE_DYNSIZE - BLI_array_free(fVerts); -#endif } static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm, float (*vertexCos)[3], int use_flat_subdiv, - bool UNUSED(use_subdiv_uvs)) + bool /*use_subdiv_uvs*/) { ss_sync_ccg_from_derivedmesh(ss, dm, vertexCos, use_flat_subdiv); } @@ -718,7 +684,7 @@ static void UNUSED_FUNCTION(ccgDM_getMinMax)(DerivedMesh *dm, float r_min[3], fl for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) { CCGVert *v = ccgVertIterator_getCurrent(&vi); - float *co = ccgSubSurf_getVertData(ss, v); + float *co = static_cast(ccgSubSurf_getVertData(ss, v)); minmax_v3_v3v3(co, r_min, r_max); } @@ -726,7 +692,7 @@ static void UNUSED_FUNCTION(ccgDM_getMinMax)(DerivedMesh *dm, float r_min[3], fl for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); - CCGElem *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + CCGElem *edgeData = static_cast(ccgSubSurf_getEdgeDataArray(ss, e)); for (i = 0; i < edgeSize; i++) { minmax_v3_v3v3(CCG_elem_offset_co(&key, edgeData, i), r_min, r_max); @@ -739,7 +705,7 @@ static void UNUSED_FUNCTION(ccgDM_getMinMax)(DerivedMesh *dm, float r_min[3], fl int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); for (S = 0; S < numVerts; S++) { - CCGElem *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); + CCGElem *faceGridData = static_cast(ccgSubSurf_getFaceGridDataArray(ss, f, S)); for (y = 0; y < gridSize; y++) { for (x = 0; x < gridSize; x++) { @@ -812,13 +778,13 @@ static CCGElem *get_vertex_elem(CCGDerivedMesh *ccgdm, int vertNum) offset = vertNum - ccgdm->faceMap[i].startVert; if (offset < 1) { - return ccgSubSurf_getFaceCenterData(f); + return static_cast(ccgSubSurf_getFaceCenterData(f)); } if (offset < gridSideEnd) { offset -= 1; grid = offset / gridSideVerts; x = offset % gridSideVerts + 1; - return ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x); + return static_cast(ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x)); } if (offset < gridInternalEnd) { offset -= gridSideEnd; @@ -826,7 +792,7 @@ static CCGElem *get_vertex_elem(CCGDerivedMesh *ccgdm, int vertNum) offset %= gridInternalVerts; y = offset / gridSideVerts + 1; x = offset % gridSideVerts + 1; - return ccgSubSurf_getFaceGridData(ss, f, grid, x, y); + return static_cast(ccgSubSurf_getFaceGridData(ss, f, grid, x, y)); } } if ((vertNum < ccgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) { @@ -843,7 +809,7 @@ static CCGElem *get_vertex_elem(CCGDerivedMesh *ccgdm, int vertNum) e = ccgdm->edgeMap[i].edge; x = vertNum - ccgdm->edgeMap[i].startVert + 1; - return ccgSubSurf_getEdgeData(ss, e, x); + return static_cast(ccgSubSurf_getEdgeData(ss, e, x)); } /* this vert comes from vert data */ @@ -851,7 +817,7 @@ static CCGElem *get_vertex_elem(CCGDerivedMesh *ccgdm, int vertNum) i = vertNum - ccgdm->vertMap[0].startVert; v = ccgdm->vertMap[i].vert; - return ccgSubSurf_getVertData(ss, v); + return static_cast(ccgSubSurf_getVertData(ss, v)); } static void ccgDM_getFinalVertCo(DerivedMesh *dm, int vertNum, float r_co[3]) @@ -901,12 +867,12 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, float (*r_positions)[3]) CCGFace *f = ccgdm->faceMap[index].face; int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - vd = ccgSubSurf_getFaceCenterData(f); + vd = static_cast(ccgSubSurf_getFaceCenterData(f)); ccgDM_to_MVert(r_positions[i++], &key, vd); for (S = 0; S < numVerts; S++) { for (x = 1; x < gridSize - 1; x++) { - vd = ccgSubSurf_getFaceGridEdgeData(ss, f, S, x); + vd = static_cast(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x)); ccgDM_to_MVert(r_positions[i++], &key, vd); } } @@ -914,7 +880,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, float (*r_positions)[3]) for (S = 0; S < numVerts; S++) { for (y = 1; y < gridSize - 1; y++) { for (x = 1; x < gridSize - 1; x++) { - vd = ccgSubSurf_getFaceGridData(ss, f, S, x, y); + vd = static_cast(ccgSubSurf_getFaceGridData(ss, f, S, x, y)); ccgDM_to_MVert(r_positions[i++], &key, vd); } } @@ -930,7 +896,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, float (*r_positions)[3]) /* NOTE(@campbellbarton): This gives errors with `--debug-fpe` the normals don't seem to be * unit length. This is most likely caused by edges with no faces which are now zeroed out, * see comment in: `ccgSubSurf__calcVertNormals()`. */ - vd = ccgSubSurf_getEdgeData(ss, e, x); + vd = static_cast(ccgSubSurf_getEdgeData(ss, e, x)); ccgDM_to_MVert(r_positions[i++], &key, vd); } } @@ -939,7 +905,7 @@ static void ccgDM_copyFinalVertArray(DerivedMesh *dm, float (*r_positions)[3]) for (index = 0; index < totvert; index++) { CCGVert *v = ccgdm->vertMap[index].vert; - vd = ccgSubSurf_getVertData(ss, v); + vd = static_cast(ccgSubSurf_getVertData(ss, v)); ccgDM_to_MVert(r_positions[i++], &key, vd); } } @@ -1017,20 +983,20 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) } } -typedef struct CopyFinalLoopArrayData { +struct CopyFinalLoopArrayData { CCGDerivedMesh *ccgdm; MLoop *mloop; int grid_size; int *grid_offset; int edge_size; size_t mloop_index; -} CopyFinalLoopArrayData; +}; static void copyFinalLoopArray_task_cb(void *__restrict userdata, const int iter, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - CopyFinalLoopArrayData *data = userdata; + CopyFinalLoopArrayData *data = static_cast(userdata); CCGDerivedMesh *ccgdm = data->ccgdm; CCGSubSurf *ss = ccgdm->ss; const int grid_size = data->grid_size; @@ -1157,12 +1123,12 @@ static void ccgDM_release(DerivedMesh *dm) /* Check that mmd still exists */ if (!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0) { - ccgdm->multires.mmd = NULL; + ccgdm->multires.mmd = nullptr; } if (ccgdm->multires.mmd) { if (ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED) { - multires_modifier_update_mdisps(dm, NULL); + multires_modifier_update_mdisps(dm, nullptr); } if (ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED) { multires_modifier_update_hidden(dm); @@ -1171,7 +1137,7 @@ static void ccgDM_release(DerivedMesh *dm) } if (ccgdm->ehash) { - BLI_edgehash_free(ccgdm->ehash, NULL); + BLI_edgehash_free(ccgdm->ehash, nullptr); } if (ccgdm->reverseFaceMap) { @@ -1232,7 +1198,7 @@ static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type) /* Avoid re-creation if the layer exists already */ BLI_rw_mutex_lock(&ccgdm->origindex_cache_rwlock, THREAD_LOCK_READ); - origindex = DM_get_vert_data_layer(dm, CD_ORIGINDEX); + origindex = static_cast(DM_get_vert_data_layer(dm, CD_ORIGINDEX)); BLI_rw_mutex_unlock(&ccgdm->origindex_cache_rwlock); if (origindex) { return origindex; @@ -1240,8 +1206,8 @@ static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type) BLI_rw_mutex_lock(&ccgdm->origindex_cache_rwlock, THREAD_LOCK_WRITE); - origindex = CustomData_add_layer( - &dm->vertData, CD_ORIGINDEX, CD_SET_DEFAULT, NULL, dm->numVertData); + origindex = static_cast(CustomData_add_layer( + &dm->vertData, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, dm->numVertData)); totorig = ccgSubSurf_getNumVerts(ss); totnone = dm->numVertData - totorig; @@ -1274,13 +1240,13 @@ static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type) int edgeSize = ccgSubSurf_getEdgeSize(ss); /* Avoid re-creation if the layer exists already */ - origindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX); + origindex = static_cast(DM_get_edge_data_layer(dm, CD_ORIGINDEX)); if (origindex) { return origindex; } - origindex = CustomData_add_layer( - &dm->edgeData, CD_ORIGINDEX, CD_SET_DEFAULT, NULL, dm->numEdgeData); + origindex = static_cast(CustomData_add_layer( + &dm->edgeData, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, dm->numEdgeData)); totedge = ccgSubSurf_getNumEdges(ss); totorig = totedge * (edgeSize - 1); @@ -1317,13 +1283,13 @@ static void *ccgDM_get_poly_data_layer(DerivedMesh *dm, int type) int gridFaces = ccgSubSurf_getGridSize(ss) - 1; /* Avoid re-creation if the layer exists already */ - origindex = DM_get_poly_data_layer(dm, CD_ORIGINDEX); + origindex = static_cast(DM_get_poly_data_layer(dm, CD_ORIGINDEX)); if (origindex) { return origindex; } - origindex = CustomData_add_layer( - &dm->polyData, CD_ORIGINDEX, CD_SET_DEFAULT, NULL, dm->numPolyData); + origindex = static_cast(CustomData_add_layer( + &dm->polyData, CD_ORIGINDEX, CD_SET_DEFAULT, nullptr, dm->numPolyData)); totface = ccgSubSurf_getNumFaces(ss); @@ -1384,7 +1350,7 @@ static void ccgdm_create_grids(DerivedMesh *dm) // gridSize = ccgDM_getGridSize(dm); /* UNUSED */ /* compute offset into grid array for each face */ - gridOffset = MEM_mallocN(sizeof(int) * numFaces, "ccgdm.gridOffset"); + gridOffset = static_cast(MEM_mallocN(sizeof(int) * numFaces, "ccgdm.gridOffset")); for (gIndex = 0, index = 0; index < numFaces; index++) { CCGFace *f = ccgdm->faceMap[index].face; @@ -1395,18 +1361,21 @@ static void ccgdm_create_grids(DerivedMesh *dm) } /* compute grid data */ - gridData = MEM_mallocN(sizeof(CCGElem *) * numGrids, "ccgdm.gridData"); - gridFaces = MEM_mallocN(sizeof(CCGFace *) * numGrids, "ccgdm.gridFaces"); - gridFlagMats = MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlagMats"); + gridData = static_cast(MEM_mallocN(sizeof(CCGElem *) * numGrids, "ccgdm.gridData")); + gridFaces = static_cast( + MEM_mallocN(sizeof(CCGFace *) * numGrids, "ccgdm.gridFaces")); + gridFlagMats = static_cast( + MEM_mallocN(sizeof(DMFlagMat) * numGrids, "ccgdm.gridFlagMats")); - ccgdm->gridHidden = MEM_callocN(sizeof(*ccgdm->gridHidden) * numGrids, "ccgdm.gridHidden"); + ccgdm->gridHidden = static_cast( + MEM_callocN(sizeof(*ccgdm->gridHidden) * numGrids, "ccgdm.gridHidden")); for (gIndex = 0, index = 0; index < numFaces; index++) { CCGFace *f = ccgdm->faceMap[index].face; int numVerts = ccgSubSurf_getFaceNumVerts(f); for (S = 0; S < numVerts; S++, gIndex++) { - gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S); + gridData[gIndex] = static_cast(ccgSubSurf_getFaceGridDataArray(ss, f, S)); gridFaces[gIndex] = f; gridFlagMats[gIndex] = ccgdm->faceFlags[index]; } @@ -1466,7 +1435,7 @@ static void ccgDM_recalcLoopTri(DerivedMesh *dm) DM_ensure_looptri_data(dm); MLoopTri *mlooptri = dm->looptris.array_wip; - BLI_assert(tottri == 0 || mlooptri != NULL); + BLI_assert(tottri == 0 || mlooptri != nullptr); BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num); BLI_assert(tottri == dm->looptris.num); @@ -1486,9 +1455,9 @@ static void ccgDM_recalcLoopTri(DerivedMesh *dm) lt->poly = poly_index; } - BLI_assert(dm->looptris.array == NULL); + BLI_assert(dm->looptris.array == nullptr); atomic_cas_ptr((void **)&dm->looptris.array, dm->looptris.array, dm->looptris.array_wip); - dm->looptris.array_wip = NULL; + dm->looptris.array_wip = nullptr; } static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm) @@ -1530,7 +1499,8 @@ static void create_ccgdm_maps(CCGDerivedMesh *ccgdm, CCGSubSurf *ss) int totvert, totedge, totface; totvert = ccgSubSurf_getNumVerts(ss); - ccgdm->vertMap = MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap"); + ccgdm->vertMap = static_cast( + MEM_mallocN(totvert * sizeof(*ccgdm->vertMap), "vertMap")); for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) { CCGVert *v = ccgVertIterator_getCurrent(&vi); @@ -1539,7 +1509,8 @@ static void create_ccgdm_maps(CCGDerivedMesh *ccgdm, CCGSubSurf *ss) } totedge = ccgSubSurf_getNumEdges(ss); - ccgdm->edgeMap = MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap"); + ccgdm->edgeMap = static_cast( + MEM_mallocN(totedge * sizeof(*ccgdm->edgeMap), "edgeMap")); for (ccgSubSurf_initEdgeIterator(ss, &ei); !ccgEdgeIterator_isStopped(&ei); ccgEdgeIterator_next(&ei)) { CCGEdge *e = ccgEdgeIterator_getCurrent(&ei); @@ -1548,7 +1519,8 @@ static void create_ccgdm_maps(CCGDerivedMesh *ccgdm, CCGSubSurf *ss) } totface = ccgSubSurf_getNumFaces(ss); - ccgdm->faceMap = MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap"); + ccgdm->faceMap = static_cast( + MEM_mallocN(totface * sizeof(*ccgdm->faceMap), "faceMap")); for (ccgSubSurf_initFaceIterator(ss, &fi); !ccgFaceIterator_isStopped(&fi); ccgFaceIterator_next(&fi)) { CCGFace *f = ccgFaceIterator_getCurrent(&fi); @@ -1573,20 +1545,17 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, int vertNum = 0, edgeNum = 0, faceNum = 0; short *edgeFlags = ccgdm->edgeFlags; DMFlagMat *faceFlags = ccgdm->faceFlags; - int *polyidx = NULL; -#ifndef USE_DYNSIZE - int *loopidx = NULL, *vertidx = NULL; - BLI_array_declare(loopidx); - BLI_array_declare(vertidx); -#endif + int *polyidx = nullptr; + blender::Vector loopidx; + blender::Vector vertidx; int loopindex, loopindex2; int edgeSize; int gridSize; int gridFaces, gridCuts; int gridSideEdges; int gridInternalEdges; - WeightTable wtable = {NULL}; - MEdge *medge = NULL; + WeightTable wtable = {nullptr}; + MEdge *medge = nullptr; bool has_edge_cd; edgeSize = ccgSubSurf_getEdgeSize(ss); @@ -1599,15 +1568,15 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, medge = dm->getEdgeArray(dm); - const MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); - const int *material_indices = CustomData_get_layer_named( - &dm->polyData, CD_MPOLY, "material_index"); - const int *base_polyOrigIndex = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX); + const MPoly *mpoly = static_cast(CustomData_get_layer(&dm->polyData, CD_MPOLY)); + const int *material_indices = static_cast( + CustomData_get_layer_named(&dm->polyData, CD_MPOLY, "material_index")); + const int *base_polyOrigIndex = static_cast( + CustomData_get_layer(&dm->polyData, CD_ORIGINDEX)); - int *vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX); - int *edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX); - - int *polyOrigIndex = DM_get_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX); + int *vertOrigIndex = static_cast(DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX)); + int *edgeOrigIndex = static_cast(DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX)); + int *polyOrigIndex = static_cast(DM_get_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX)); has_edge_cd = ((ccgdm->dm.edgeData.totlayer - (edgeOrigIndex ? 1 : 0)) != 0); @@ -1620,9 +1589,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, int g2_wid = gridCuts + 2; float *w, *w2; int s, x, y; -#ifdef USE_DYNSIZE - int loopidx[numVerts], vertidx[numVerts]; -#endif + w = get_ss_weights(&wtable, gridCuts, numVerts); ccgdm->faceMap[index].startVert = vertNum; @@ -1636,18 +1603,12 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, /* set the face base vert */ *((int *)ccgSubSurf_getFaceUserData(ss, f)) = vertNum; -#ifndef USE_DYNSIZE - BLI_array_clear(loopidx); - BLI_array_grow_items(loopidx, numVerts); -#endif + loopidx.reinitialize(numVerts); for (s = 0; s < numVerts; s++) { loopidx[s] = loopindex++; } -#ifndef USE_DYNSIZE - BLI_array_clear(vertidx); - BLI_array_grow_items(vertidx, numVerts); -#endif + vertidx.reinitialize(numVerts); for (s = 0; s < numVerts; s++) { CCGVert *v = ccgSubSurf_getFaceVert(f, s); vertidx[s] = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v)); @@ -1655,7 +1616,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, /* I think this is for interpolating the center vert? */ w2 = w; // + numVerts*(g2_wid-1) * (g2_wid-1); //numVerts*((g2_wid-1) * g2_wid+g2_wid-1); - DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum); + DM_interp_vert_data(dm, &ccgdm->dm, vertidx.data(), w2, numVerts, vertNum); if (vertOrigIndex) { *vertOrigIndex = ORIGINDEX_NONE; vertOrigIndex++; @@ -1667,7 +1628,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, for (s = 0; s < numVerts; s++) { for (x = 1; x < gridFaces; x++) { w2 = w + s * numVerts * g2_wid * g2_wid + x * numVerts; - DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum); + DM_interp_vert_data(dm, &ccgdm->dm, vertidx.data(), w2, numVerts, vertNum); if (vertOrigIndex) { *vertOrigIndex = ORIGINDEX_NONE; @@ -1683,7 +1644,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, for (y = 1; y < gridFaces; y++) { for (x = 1; x < gridFaces; x++) { w2 = w + s * numVerts * g2_wid * g2_wid + (y * g2_wid + x) * numVerts; - DM_interp_vert_data(dm, &ccgdm->dm, vertidx, w2, numVerts, vertNum); + DM_interp_vert_data(dm, &ccgdm->dm, vertidx.data(), w2, numVerts, vertNum); if (vertOrigIndex) { *vertOrigIndex = ORIGINDEX_NONE; @@ -1706,23 +1667,43 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, for (y = 0; y < gridFaces; y++) { for (x = 0; x < gridFaces; x++) { w2 = w + s * numVerts * g2_wid * g2_wid + (y * g2_wid + x) * numVerts; - CustomData_interp( - &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2); + CustomData_interp(&dm->loopData, + &ccgdm->dm.loopData, + loopidx.data(), + w2, + nullptr, + numVerts, + loopindex2); loopindex2++; w2 = w + s * numVerts * g2_wid * g2_wid + ((y + 1) * g2_wid + (x)) * numVerts; - CustomData_interp( - &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2); + CustomData_interp(&dm->loopData, + &ccgdm->dm.loopData, + loopidx.data(), + w2, + nullptr, + numVerts, + loopindex2); loopindex2++; w2 = w + s * numVerts * g2_wid * g2_wid + ((y + 1) * g2_wid + (x + 1)) * numVerts; - CustomData_interp( - &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2); + CustomData_interp(&dm->loopData, + &ccgdm->dm.loopData, + loopidx.data(), + w2, + nullptr, + numVerts, + loopindex2); loopindex2++; w2 = w + s * numVerts * g2_wid * g2_wid + ((y)*g2_wid + (x + 1)) * numVerts; - CustomData_interp( - &dm->loopData, &ccgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2); + CustomData_interp(&dm->loopData, + &ccgdm->dm.loopData, + loopidx.data(), + w2, + nullptr, + numVerts, + loopindex2); loopindex2++; /* Copy over poly data, e.g. #CD_FACEMAP. */ @@ -1832,10 +1813,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, vertNum++; } -#ifndef USE_DYNSIZE - BLI_array_free(vertidx); - BLI_array_free(loopidx); -#endif free_ss_weights(&wtable); BLI_assert(vertNum == ccgSubSurf_getNumFinalVerts(ss)); @@ -1851,7 +1828,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, { const int totedge = ccgSubSurf_getNumEdges(ss); const int totface = ccgSubSurf_getNumFaces(ss); - CCGDerivedMesh *ccgdm = MEM_callocN(sizeof(*ccgdm), "ccgdm"); + CCGDerivedMesh *ccgdm = MEM_cnew(__func__); BLI_assert(totedge == ccgSubSurf_getNumEdges(ss)); BLI_assert(totface == ccgSubSurf_getNumFaces(ss)); @@ -1864,8 +1841,8 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, ccgSubSurf_getNumFinalFaces(ss) * 4, ccgSubSurf_getNumFinalFaces(ss)); - ccgdm->reverseFaceMap = MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss), - "reverseFaceMap"); + ccgdm->reverseFaceMap = static_cast( + MEM_callocN(sizeof(int) * ccgSubSurf_getNumFinalFaces(ss), "reverseFaceMap")); create_ccgdm_maps(ccgdm, ss); @@ -1876,8 +1853,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, ccgdm->useSubsurfUv = useSubsurfUv; /* CDDM hack. */ - ccgdm->edgeFlags = MEM_callocN(sizeof(short) * totedge, "edgeFlags"); - ccgdm->faceFlags = MEM_callocN(sizeof(DMFlagMat) * totface, "faceFlags"); + ccgdm->edgeFlags = static_cast(MEM_callocN(sizeof(short) * totedge, "edgeFlags")); + ccgdm->faceFlags = static_cast( + MEM_callocN(sizeof(DMFlagMat) * totface, "faceFlags")); set_ccgdm_all_geometry(ccgdm, ss, dm, useSubsurfUv != 0); @@ -1895,14 +1873,16 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, /***/ -struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm, - struct SubsurfModifierData *smd, - const struct Scene *scene, - float (*vertCos)[3], - SubsurfFlags flags) +DerivedMesh *subsurf_make_derived_from_derived(DerivedMesh *dm, + SubsurfModifierData *smd, + const Scene *scene, + float (*vertCos)[3], + SubsurfFlags flags) { - const int useSimple = (smd->subdivType == ME_SIMPLE_SUBSURF) ? CCG_SIMPLE_SUBDIV : 0; - const CCGFlags useAging = (smd->flags & eSubsurfModifierFlag_DebugIncr) ? CCG_USE_AGING : 0; + const CCGFlags useSimple = (smd->subdivType == ME_SIMPLE_SUBSURF) ? CCG_SIMPLE_SUBDIV : + CCGFlags(0); + const CCGFlags useAging = (smd->flags & eSubsurfModifierFlag_DebugIncr) ? CCG_USE_AGING : + CCGFlags(0); const int useSubsurfUv = (smd->uv_smooth != SUBSURF_UV_SMOOTH_NONE); const int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges); const bool ignore_simplify = (flags & SUBSURF_IGNORE_SIMPLIFY); @@ -1911,25 +1891,30 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm, /* NOTE: editmode calculation can only run once per * modifier stack evaluation (uses freed cache) T36299. */ if (flags & SUBSURF_FOR_EDIT_MODE) { - int levels = (scene != NULL && !ignore_simplify) ? + int levels = (scene != nullptr && !ignore_simplify) ? get_render_subsurf_level(&scene->r, smd->levels, false) : smd->levels; /* TODO(sergey): Same as emCache below. */ if ((flags & SUBSURF_IN_EDIT_MODE) && smd->mCache) { - ccgSubSurf_free(smd->mCache); - smd->mCache = NULL; + ccgSubSurf_free(static_cast(smd->mCache)); + smd->mCache = nullptr; } - smd->emCache = _getSubSurf(smd->emCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS); + smd->emCache = _getSubSurf(static_cast(smd->emCache), + levels, + 3, + useSimple | useAging | CCG_CALC_NORMALS); - ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple, useSubsurfUv); - result = getCCGDerivedMesh(smd->emCache, drawInteriorEdges, useSubsurfUv, dm); + ss_sync_from_derivedmesh( + static_cast(smd->emCache), dm, vertCos, useSimple, useSubsurfUv); + result = getCCGDerivedMesh( + static_cast(smd->emCache), drawInteriorEdges, useSubsurfUv, dm); } else if (flags & SUBSURF_USE_RENDER_PARAMS) { /* Do not use cache in render mode. */ CCGSubSurf *ss; - int levels = (scene != NULL && !ignore_simplify) ? + int levels = (scene != nullptr && !ignore_simplify) ? get_render_subsurf_level(&scene->r, smd->renderLevels, true) : smd->renderLevels; @@ -1937,7 +1922,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm, return dm; } - ss = _getSubSurf(NULL, levels, 3, useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS); + ss = _getSubSurf(nullptr, levels, 3, useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv); @@ -1947,7 +1932,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm, } else { int useIncremental = (smd->flags & eSubsurfModifierFlag_Incremental); - int levels = (scene != NULL && !ignore_simplify) ? + int levels = (scene != nullptr && !ignore_simplify) ? get_render_subsurf_level(&scene->r, smd->levels, false) : smd->levels; CCGSubSurf *ss; @@ -1964,25 +1949,28 @@ struct DerivedMesh *subsurf_make_derived_from_derived(struct DerivedMesh *dm, * mode, so now we have a parameter to verify it. - brecht */ if (!(flags & SUBSURF_IN_EDIT_MODE) && smd->emCache) { - ccgSubSurf_free(smd->emCache); - smd->emCache = NULL; + ccgSubSurf_free(static_cast(smd->emCache)); + smd->emCache = nullptr; } if (useIncremental && (flags & SUBSURF_IS_FINAL_CALC)) { - smd->mCache = ss = _getSubSurf( - smd->mCache, levels, 3, useSimple | useAging | CCG_CALC_NORMALS); + smd->mCache = ss = _getSubSurf(static_cast(smd->mCache), + levels, + 3, + useSimple | useAging | CCG_CALC_NORMALS); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple, useSubsurfUv); - result = getCCGDerivedMesh(smd->mCache, drawInteriorEdges, useSubsurfUv, dm); + result = getCCGDerivedMesh( + static_cast(smd->mCache), drawInteriorEdges, useSubsurfUv, dm); } else { CCGFlags ccg_flags = useSimple | CCG_USE_ARENA | CCG_CALC_NORMALS; - CCGSubSurf *prevSS = NULL; + CCGSubSurf *prevSS = nullptr; - if (smd->mCache && (flags & SUBSURF_IS_FINAL_CALC)) { - ccgSubSurf_free(smd->mCache); - smd->mCache = NULL; + if ((smd->mCache) && (flags & SUBSURF_IS_FINAL_CALC)) { + ccgSubSurf_free(static_cast(smd->mCache)); + smd->mCache = nullptr; } if (flags & SUBSURF_ALLOC_PAINT_MASK) { @@ -2017,12 +2005,12 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3]) * calculated vert positions is incorrect for the verts * on the boundary of the mesh. */ - CCGSubSurf *ss = _getSubSurf(NULL, 1, 3, CCG_USE_ARENA); + CCGSubSurf *ss = _getSubSurf(nullptr, 1, 3, CCG_USE_ARENA); float edge_sum[3], face_sum[3]; CCGVertIterator vi; DerivedMesh *dm = CDDM_from_mesh(me); - ss_sync_from_derivedmesh(ss, dm, NULL, 0, 0); + ss_sync_from_derivedmesh(ss, dm, nullptr, 0, 0); for (ccgSubSurf_initVertIterator(ss, &vi); !ccgVertIterator_isStopped(&vi); ccgVertIterator_next(&vi)) { @@ -2030,7 +2018,6 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3]) int idx = POINTER_AS_INT(ccgSubSurf_getVertVertHandle(v)); int N = ccgSubSurf_getVertNumEdges(v); int numFaces = ccgSubSurf_getVertNumFaces(v); - float *co; int i; zero_v3(edge_sum); @@ -2038,11 +2025,12 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3]) for (i = 0; i < N; i++) { CCGEdge *e = ccgSubSurf_getVertEdge(v, i); - add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1)); + add_v3_v3v3( + edge_sum, edge_sum, static_cast(ccgSubSurf_getEdgeData(ss, e, 1))); } for (i = 0; i < numFaces; i++) { CCGFace *f = ccgSubSurf_getVertFace(v, i); - add_v3_v3(face_sum, ccgSubSurf_getFaceCenterData(f)); + add_v3_v3(face_sum, static_cast(ccgSubSurf_getFaceCenterData(f))); } /* ad-hoc correction for boundary vertices, to at least avoid them @@ -2051,7 +2039,7 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3]) mul_v3_fl(face_sum, (float)N / (float)numFaces); } - co = ccgSubSurf_getVertData(ss, v); + const float *co = static_cast(ccgSubSurf_getVertData(ss, v)); r_positions[idx][0] = (co[0] * N * N + edge_sum[0] * 4 + face_sum[0]) / (N * (N + 5)); r_positions[idx][1] = (co[1] * N * N + edge_sum[1] * 4 + face_sum[1]) / (N * (N + 5)); r_positions[idx][2] = (co[2] * N * N + edge_sum[2] * 4 + face_sum[2]) / (N * (N + 5)); From 721bd5e6cf2328230ae9f7104e5380f21b5e9e7f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Jan 2023 17:58:02 +1100 Subject: [PATCH 0819/1522] Fix invalid swapBuffer calls & outdated window decorations on Wayland Swap-buffers was being deferred (to prevent it being called from the event handling thread) however when it was called the OpenGL context might not be active (especially with multiple windows). Moving the cursor between windows made eglSwapBuffers report: EGL Error (0x300D): EGL_BAD_SURFACE. Resolve this by removing swapBuffer calls and instead add a GHOST_kEventWindowUpdateDecor event intended for redrawing client-side-decoration. Besides the warning, this results an error with LIBDECOR window frames not redrawing when a window became inactive. --- intern/ghost/GHOST_Types.h | 2 + intern/ghost/intern/GHOST_WindowWayland.cpp | 61 ++++++++++--------- intern/ghost/intern/GHOST_WindowWayland.h | 1 + .../blender/windowmanager/intern/wm_window.c | 16 +++++ 4 files changed, 51 insertions(+), 29 deletions(-) diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h index 3932bc76af0..e950f9bc679 100644 --- a/intern/ghost/GHOST_Types.h +++ b/intern/ghost/GHOST_Types.h @@ -198,6 +198,8 @@ typedef enum { GHOST_kEventWindowActivate, GHOST_kEventWindowDeactivate, GHOST_kEventWindowUpdate, + /** Client side window decorations have changed and need to be redrawn. */ + GHOST_kEventWindowUpdateDecor, GHOST_kEventWindowSize, GHOST_kEventWindowMove, GHOST_kEventWindowDPIHintChanged, diff --git a/intern/ghost/intern/GHOST_WindowWayland.cpp b/intern/ghost/intern/GHOST_WindowWayland.cpp index 9c179a6394f..f486fc319c8 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.cpp +++ b/intern/ghost/intern/GHOST_WindowWayland.cpp @@ -311,10 +311,9 @@ enum eGWL_PendingWindowActions { # ifdef GHOST_OPENGL_ALPHA PENDING_OPAQUE_SET, # endif - PENDING_SWAP_BUFFERS, PENDING_SCALE_UPDATE, }; -# define PENDING_NUM (PENDING_SWAP_BUFFERS + 1) +# define PENDING_NUM (PENDING_SCALE_UPDATE + 1) static void gwl_window_pending_actions_tag(GWL_Window *win, enum eGWL_PendingWindowActions type) { @@ -338,9 +337,6 @@ static void gwl_window_pending_actions_handle(GWL_Window *win) if (win->pending_actions[PENDING_SCALE_UPDATE].exchange(false)) { win->ghost_window->outputs_changed_update_scale(); } - if (win->pending_actions[PENDING_SWAP_BUFFERS].exchange(false)) { - win->ghost_window->swapBuffers(); - } } #endif /* USE_EVENT_BACKGROUND_THREAD */ @@ -356,8 +352,6 @@ static void gwl_window_frame_update_from_pending_lockfree(GWL_Window *win) #endif - bool do_redraw = false; - if (win->frame_pending.size[0] != 0 && win->frame_pending.size[1] != 0) { if ((win->frame.size[0] != win->frame_pending.size[0]) || (win->frame.size[1] != win->frame_pending.size[1])) { @@ -365,9 +359,6 @@ static void gwl_window_frame_update_from_pending_lockfree(GWL_Window *win) } } - bool is_active_ghost = (win->ghost_window == - win->ghost_system->getWindowManager()->getActiveWindow()); - if (win->frame_pending.is_active) { win->ghost_window->activate(); } @@ -375,10 +366,6 @@ static void gwl_window_frame_update_from_pending_lockfree(GWL_Window *win) win->ghost_window->deactivate(); } - if (is_active_ghost != win->frame_pending.is_active) { - do_redraw = true; - } - win->frame_pending.size[0] = win->frame.size[0]; win->frame_pending.size[1] = win->frame.size[1]; @@ -387,15 +374,6 @@ static void gwl_window_frame_update_from_pending_lockfree(GWL_Window *win) /* Signal not to apply the scale unless it's configured. */ win->frame_pending.size[0] = 0; win->frame_pending.size[1] = 0; - - if (do_redraw) { -#ifdef USE_EVENT_BACKGROUND_THREAD - /* Could swap buffers, use pending to a redundant call in some cases. */ - gwl_window_pending_actions_tag(win, PENDING_SWAP_BUFFERS); -#else - win->ghost_window->swapBuffers(); -#endif - } } static void gwl_window_frame_update_from_pending(GWL_Window *win) @@ -621,12 +599,11 @@ static void frame_handle_commit(struct libdecor_frame * /*frame*/, void *data) { CLOG_INFO(LOG, 2, "commit"); +# if 0 GWL_Window *win = static_cast(data); - -# ifdef USE_EVENT_BACKGROUND_THREAD - gwl_window_pending_actions_tag(win, PENDING_SWAP_BUFFERS); + win->ghost_window->notify_decor_redraw(); # else - win->ghost_window->swapBuffers(); + (void)data; # endif } @@ -1321,8 +1298,17 @@ GHOST_TSuccess GHOST_WindowWayland::activate() return GHOST_kFailure; } } - return system_->pushEvent_maybe_pending( + const GHOST_TSuccess success = system_->pushEvent_maybe_pending( new GHOST_Event(system_->getMilliSeconds(), GHOST_kEventWindowActivate, this)); +#ifdef WITH_GHOST_WAYLAND_LIBDECOR + if (success == GHOST_kSuccess) { + if (use_libdecor) { + /* Ensure there is a swap-buffers, needed for the updated window borders to refresh. */ + notify_decor_redraw(); + } + } +#endif + return success; } GHOST_TSuccess GHOST_WindowWayland::deactivate() @@ -1335,8 +1321,17 @@ GHOST_TSuccess GHOST_WindowWayland::deactivate() { system_->getWindowManager()->setWindowInactive(this); } - return system_->pushEvent_maybe_pending( + const GHOST_TSuccess success = system_->pushEvent_maybe_pending( new GHOST_Event(system_->getMilliSeconds(), GHOST_kEventWindowDeactivate, this)); +#ifdef WITH_GHOST_WAYLAND_LIBDECOR + if (success == GHOST_kSuccess) { + if (use_libdecor) { + /* Ensure there is a swap-buffers, needed for the updated window borders to refresh. */ + notify_decor_redraw(); + } + } +#endif + return success; } GHOST_TSuccess GHOST_WindowWayland::notify_size() @@ -1358,6 +1353,14 @@ GHOST_TSuccess GHOST_WindowWayland::notify_size() new GHOST_Event(system_->getMilliSeconds(), GHOST_kEventWindowSize, this)); } +GHOST_TSuccess GHOST_WindowWayland::notify_decor_redraw() +{ + /* NOTE: we want to `swapBuffers`, however this may run from a thread and + * when this windows OpenGL context is not active, so send and update event instead. */ + return system_->pushEvent_maybe_pending( + new GHOST_Event(system_->getMilliSeconds(), GHOST_kEventWindowUpdateDecor, this)); +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/intern/ghost/intern/GHOST_WindowWayland.h b/intern/ghost/intern/GHOST_WindowWayland.h index 326c1d5e994..c5554f70200 100644 --- a/intern/ghost/intern/GHOST_WindowWayland.h +++ b/intern/ghost/intern/GHOST_WindowWayland.h @@ -150,6 +150,7 @@ class GHOST_WindowWayland : public GHOST_Window { GHOST_TSuccess activate(); GHOST_TSuccess deactivate(); GHOST_TSuccess notify_size(); + GHOST_TSuccess notify_decor_redraw(); /* WAYLAND utility functions. */ diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 0077c8e2259..2e5e370ae06 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1229,6 +1229,22 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt break; } + case GHOST_kEventWindowUpdateDecor: { + if (G.debug & G_DEBUG_EVENTS) { + printf("%s: ghost redraw decor %d\n", __func__, win->winid); + } + + wm_window_make_drawable(wm, win); +#if 0 + /* NOTE(@campbellbarton): Ideally we could swap-buffers to avoid a full redraw. + * however this causes window flickering on resize with LIBDECOR under WAYLAND. */ + wm_window_swap_buffers(win); +#else + WM_event_add_notifier(C, NC_WINDOW, NULL); +#endif + + break; + } case GHOST_kEventWindowSize: case GHOST_kEventWindowMove: { GHOST_TWindowState state = GHOST_GetWindowState(win->ghostwin); From 884e14ac93855ae107ee0fff52354d85cfc33515 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 20 Jan 2023 10:28:58 +0100 Subject: [PATCH 0820/1522] 3D Texturing: Adding print_debug for visually inspecting the generated geometry. During 3D texturing the uv islands are extended in order to fix seam bleeding for manifold parts of the input mesh. This patch adds a `print_debug` method on UVIsland that generates a python script. This script can be copy-past into the Python Console to show the generated geometry. This script can be extended to show the extracted border and use face colors for showing internal decisions. --- .../blender/blenkernel/intern/pbvh_pixels.cc | 6 +- .../blenkernel/intern/pbvh_uv_islands.cc | 69 ++++++++++++++++++- .../blenkernel/intern/pbvh_uv_islands.hh | 8 ++- 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index 39651349ae9..b1d635f566e 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -366,7 +366,11 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image const VArraySpan uv_map = attributes.lookup(active_uv_name, ATTR_DOMAIN_CORNER); uv_islands::MeshData mesh_data( - {pbvh->looptri, pbvh->totprim}, {pbvh->mloop, mesh->totloop}, pbvh->totvert, uv_map); + {pbvh->looptri, pbvh->totprim}, + {pbvh->mloop, mesh->totloop}, + pbvh->totvert, + uv_map, + {static_cast(static_cast(pbvh->vert_positions)), pbvh->totvert}); uv_islands::UVIslands islands(mesh_data); uv_islands::UVIslandsMask uv_masks; diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index 8554964fae9..0c00f57c49f 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -210,11 +210,13 @@ static void mesh_data_init(MeshData &mesh_data) MeshData::MeshData(const Span looptris, const Span loops, const int verts_num, - const Span uv_map) + const Span uv_map, + const Span vertex_positions) : looptris(looptris), verts_num(verts_num), loops(loops), uv_map(uv_map), + vertex_positions(vertex_positions), vert_to_edge_map(verts_num), edge_to_primitive_map(0), primitive_to_edge_map(looptris.size()) @@ -961,6 +963,63 @@ void UVIsland::extend_border(const MeshData &mesh_data, } } +void UVIsland::print_debug(const MeshData &mesh_data) const +{ + std::stringstream ss; + ss << "#### Start UVIsland ####\n"; + ss << "import bpy\n"; + ss << "import bpy_extras.object_utils\n"; + ss << "import mathutils\n"; + + ss << "uvisland_vertices = [\n"; + for (const float3 &vertex_position : mesh_data.vertex_positions) { + ss << " mathutils.Vector((" << vertex_position.x << ", " << vertex_position.y << ", " + << vertex_position.z << ")),\n"; + } + ss << "]\n"; + + ss << "uvisland_edges = []\n"; + + ss << "uvisland_faces = [\n"; + for (const VectorList::UsedVector &uvprimitives : uv_primitives) { + for (const UVPrimitive &uvprimitive : uvprimitives) { + ss << " [" << uvprimitive.edges[0]->vertices[0]->vertex << ", " + << uvprimitive.edges[0]->vertices[1]->vertex << ", " + << uvprimitive + .get_other_uv_vertex(uvprimitive.edges[0]->vertices[0], + uvprimitive.edges[0]->vertices[1]) + ->vertex + << "],\n"; + } + } + ss << "]\n"; + + ss << "uvisland_uvs = [\n"; + for (const VectorList::UsedVector &uvprimitives : uv_primitives) { + for (const UVPrimitive &uvprimitive : uvprimitives) { + float2 uv = uvprimitive.edges[0]->vertices[0]->uv; + ss << " " << uv.x << ", " << uv.y << ",\n"; + uv = uvprimitive.edges[0]->vertices[1]->uv; + ss << " " << uv.x << ", " << uv.y << ",\n"; + uv = uvprimitive + .get_other_uv_vertex(uvprimitive.edges[0]->vertices[0], + uvprimitive.edges[0]->vertices[1]) + ->uv; + ss << " " << uv.x << ", " << uv.y << ",\n"; + } + } + ss << "]\n"; + + ss << "uvisland_mesh = bpy.data.meshes.new(name='UVIsland')\n"; + ss << "uvisland_mesh.from_pydata(uvisland_vertices, uvisland_edges, uvisland_faces)\n"; + ss << "uv_map = uvisland_mesh.attributes.new('UVMap', 'FLOAT2', 'CORNER')\n"; + ss << "uv_map.data.foreach_set('vector', uvisland_uvs)\n"; + ss << "bpy_extras.object_utils.object_data_add(bpy.context, uvisland_mesh)\n"; + ss << "#### End UVIsland ####\n\n\n"; + + std::cout << ss.str(); +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -1289,6 +1348,14 @@ void UVIslands::extend_borders(const MeshData &mesh_data, const UVIslandsMask &i ushort index = 0; for (UVIsland &island : islands) { island.extend_border(mesh_data, islands_mask, index++); + island.print_debug(mesh_data); + } +} + +void UVIslands::print_debug(const MeshData &mesh_data) const +{ + for (const UVIsland &island : islands) { + island.print_debug(mesh_data); } } diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.hh b/source/blender/blenkernel/intern/pbvh_uv_islands.hh index 9496b564516..c1a0a4da5d8 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.hh +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.hh @@ -122,6 +122,7 @@ struct MeshData { const int64_t verts_num; const Span loops; const Span uv_map; + const Span vertex_positions; VertToEdgeMap vert_to_edge_map; @@ -142,7 +143,8 @@ struct MeshData { explicit MeshData(Span looptris, Span loops, const int verts_num, - const Span uv_map); + const Span uv_map, + const Span vertex_positions); }; struct UVVertex { @@ -312,6 +314,9 @@ struct UVIsland { bool has_shared_edge(const UVPrimitive &primitive) const; bool has_shared_edge(const MeshData &mesh_data, const int primitive_i) const; void extend_border(const UVPrimitive &primitive); + + /** Print a python script to the console that generates a mesh representing this UVIsland. */ + void print_debug(const MeshData &mesh_data) const; }; struct UVIslands { @@ -321,6 +326,7 @@ struct UVIslands { void extract_borders(); void extend_borders(const MeshData &mesh_data, const UVIslandsMask &islands_mask); + void print_debug(const MeshData &mesh_data) const; }; /** Mask to find the index of the UVIsland for a given UV coordinate. */ From 244522d6cb61ccafda8a70227e698d884e58b75d Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 20 Jan 2023 11:15:37 +0100 Subject: [PATCH 0821/1522] 3D Texturing: Remove actual invocation of print_debug. Was a mistake as only the function should have landed in master. --- source/blender/blenkernel/intern/pbvh_uv_islands.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index 0c00f57c49f..16091b32917 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -1348,7 +1348,6 @@ void UVIslands::extend_borders(const MeshData &mesh_data, const UVIslandsMask &i ushort index = 0; for (UVIsland &island : islands) { island.extend_border(mesh_data, islands_mask, index++); - island.print_debug(mesh_data); } } From d072764809cb29d357073cbd9d187436fe328ec1 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 20 Jan 2023 11:55:56 +0100 Subject: [PATCH 0822/1522] Add RNA path functions to AssetMetaData and AssetTag structures. --- source/blender/makesrna/intern/rna_asset.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source/blender/makesrna/intern/rna_asset.c b/source/blender/makesrna/intern/rna_asset.c index 76751f1d9f1..b95800fe934 100644 --- a/source/blender/makesrna/intern/rna_asset.c +++ b/source/blender/makesrna/intern/rna_asset.c @@ -31,6 +31,11 @@ # include "RNA_access.h" +static char *rna_AssetMetaData_path(const PointerRNA *UNUSED(ptr)) +{ + return BLI_strdup("asset_data"); +} + static bool rna_AssetMetaData_editable_from_owner_id(const ID *owner_id, const AssetMetaData *asset_data, const char **r_info) @@ -56,6 +61,12 @@ int rna_AssetMetaData_editable(PointerRNA *ptr, const char **r_info) 0; } +static char *rna_AssetTag_path(const PointerRNA *ptr) +{ + const AssetTag *asset_tag = ptr->data; + return BLI_sprintfN("asset_data.tags['%s']", asset_tag->name); +} + static int rna_AssetTag_editable(PointerRNA *ptr, const char **r_info) { AssetTag *asset_tag = ptr->data; @@ -310,6 +321,7 @@ static void rna_def_asset_tag(BlenderRNA *brna) PropertyRNA *prop; srna = RNA_def_struct(brna, "AssetTag", NULL); + RNA_def_struct_path_func(srna, "rna_AssetTag_path"); RNA_def_struct_ui_text(srna, "Asset Tag", "User defined tag (name token)"); prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); @@ -361,6 +373,7 @@ static void rna_def_asset_data(BlenderRNA *brna) PropertyRNA *prop; srna = RNA_def_struct(brna, "AssetMetaData", NULL); + RNA_def_struct_path_func(srna, "rna_AssetMetaData_path"); RNA_def_struct_ui_text(srna, "Asset Data", "Additional data stored for an asset data-block"); // RNA_def_struct_ui_icon(srna, ICON_ASSET); /* TODO: Icon doesn't exist! */ /* The struct has custom properties, but no pointer properties to other IDs! */ From 85908e9edf3dfefdc36714f07a554f480ff5d230 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 20 Jan 2023 12:09:29 +0100 Subject: [PATCH 0823/1522] Geometry Nodes: new Interpolate Curves node This adds a new `Interpolate Curves` node. It allows generating new curves between a set of existing guide curves. This is essential for procedural hair. Usage: - One has to provide a set of guide curves and a set of root positions for the generated curves. New curves are created starting from these root positions. The N closest guide curves are used for the interpolation. - An additional up vector can be provided for every guide curve and root position. This is typically a surface normal or nothing. This allows generating child curves that are properly oriented based on the surface orientation. - Sometimes a point should only be interpolated using a subset of the guides. This can be achieved using the `Guide Group ID` and `Point Group ID` inputs. The curve generated at a specific point will only take the guides with the same id into account. This allows e.g. for hair parting. - The `Max Neighbors` input limits how many guide curves are taken into account for every interpolated curve. Differential Revision: https://developer.blender.org/D16642 --- .../startup/bl_ui/node_add_menu_geometry.py | 1 + source/blender/blenkernel/BKE_node.h | 2 + .../blenlib/BLI_length_parameterize.hh | 2 +- source/blender/blenlib/BLI_task.hh | 2 +- .../blender/blenlib/intern/offset_indices.cc | 2 +- source/blender/nodes/NOD_static_types.h | 2 + source/blender/nodes/geometry/CMakeLists.txt | 1 + .../nodes/geometry/node_geometry_register.cc | 1 + .../nodes/geometry/node_geometry_register.hh | 1 + .../nodes/node_geo_interpolate_curves.cc | 862 ++++++++++++++++++ tests/python/CMakeLists.txt | 1 + 11 files changed, 874 insertions(+), 3 deletions(-) create mode 100644 source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc diff --git a/release/scripts/startup/bl_ui/node_add_menu_geometry.py b/release/scripts/startup/bl_ui/node_add_menu_geometry.py index 2554734d903..cdbd05b74a3 100644 --- a/release/scripts/startup/bl_ui/node_add_menu_geometry.py +++ b/release/scripts/startup/bl_ui/node_add_menu_geometry.py @@ -101,6 +101,7 @@ class NODE_MT_geometry_node_GEO_CURVE_OPERATIONS(Menu): node_add_menu.add_node_type(layout, "GeometryNodeDeformCurvesOnSurface") node_add_menu.add_node_type(layout, "GeometryNodeFillCurve") node_add_menu.add_node_type(layout, "GeometryNodeFilletCurve") + node_add_menu.add_node_type(layout, "GeometryNodeInterpolateCurves") node_add_menu.add_node_type(layout, "GeometryNodeResampleCurve") node_add_menu.add_node_type(layout, "GeometryNodeReverseCurve") node_add_menu.add_node_type(layout, "GeometryNodeSampleCurve") diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 915ca87621a..386fe7fc77f 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -1562,6 +1562,8 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i /** \} */ +#define GEO_NODE_INTERPOLATE_CURVES 2000 + void BKE_node_system_init(void); void BKE_node_system_exit(void); diff --git a/source/blender/blenlib/BLI_length_parameterize.hh b/source/blender/blenlib/BLI_length_parameterize.hh index d81bcbe1e7a..df00e004060 100644 --- a/source/blender/blenlib/BLI_length_parameterize.hh +++ b/source/blender/blenlib/BLI_length_parameterize.hh @@ -105,7 +105,7 @@ inline void sample_at_length(const Span accumulated_segment_lengths, BLI_assert(lengths.size() > 0); BLI_assert(sample_length >= 0.0f); - BLI_assert(sample_length <= lengths.last()); + BLI_assert(sample_length <= lengths.last() + 0.00001f); if (hint != nullptr && hint->segment_index >= 0) { const float length_in_segment = sample_length - hint->segment_start; diff --git a/source/blender/blenlib/BLI_task.hh b/source/blender/blenlib/BLI_task.hh index e7d9a21439a..c726691ad46 100644 --- a/source/blender/blenlib/BLI_task.hh +++ b/source/blender/blenlib/BLI_task.hh @@ -37,7 +37,7 @@ namespace blender::threading { template -void parallel_for_each(Range &range, const Function &function) +void parallel_for_each(Range &&range, const Function &function) { #ifdef WITH_TBB tbb::parallel_for_each(range, function); diff --git a/source/blender/blenlib/intern/offset_indices.cc b/source/blender/blenlib/intern/offset_indices.cc index fee57e32ffa..2ac11fe631e 100644 --- a/source/blender/blenlib/intern/offset_indices.cc +++ b/source/blender/blenlib/intern/offset_indices.cc @@ -9,7 +9,7 @@ void accumulate_counts_to_offsets(MutableSpan counts_to_offsets, const int int offset = start_offset; for (const int i : counts_to_offsets.index_range().drop_back(1)) { const int count = counts_to_offsets[i]; - BLI_assert(count > 0); + BLI_assert(count >= 0); counts_to_offsets[i] = offset; offset += count; } diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index b9f747b2e4f..33fc7249fad 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -430,6 +430,8 @@ DefNode(GeometryNode, GEO_NODE_VIEWER, def_geo_viewer, "VIEWER", Viewer, "Viewer DefNode(GeometryNode, GEO_NODE_VOLUME_CUBE, 0, "VOLUME_CUBE", VolumeCube, "Volume Cube", "Generate a dense volume with a field that controls the density at each grid voxel based on its position") DefNode(GeometryNode, GEO_NODE_VOLUME_TO_MESH, def_geo_volume_to_mesh, "VOLUME_TO_MESH", VolumeToMesh, "Volume to Mesh", "Generate a mesh on the \"surface\" of a volume") +DefNode(GeometryNode, GEO_NODE_INTERPOLATE_CURVES, 0, "INTERPOLATE_CURVES", InterpolateCurves, "Interpolate Curves", "Generate new curves on points by interpolating between existing curves") + /* undefine macros */ #undef DefNode diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt index 8012b463a54..9fd3feff27e 100644 --- a/source/blender/nodes/geometry/CMakeLists.txt +++ b/source/blender/nodes/geometry/CMakeLists.txt @@ -106,6 +106,7 @@ set(SRC nodes/node_geo_input_tangent.cc nodes/node_geo_instance_on_points.cc nodes/node_geo_instances_to_points.cc + nodes/node_geo_interpolate_curves.cc nodes/node_geo_is_viewport.cc nodes/node_geo_join_geometry.cc nodes/node_geo_material_replace.cc diff --git a/source/blender/nodes/geometry/node_geometry_register.cc b/source/blender/nodes/geometry/node_geometry_register.cc index 8d24d9bd732..149fb6752ab 100644 --- a/source/blender/nodes/geometry/node_geometry_register.cc +++ b/source/blender/nodes/geometry/node_geometry_register.cc @@ -90,6 +90,7 @@ void register_geometry_nodes() register_node_type_geo_input_tangent(); register_node_type_geo_instance_on_points(); register_node_type_geo_instances_to_points(); + register_node_type_geo_interpolate_curves(); register_node_type_geo_is_viewport(); register_node_type_geo_join_geometry(); register_node_type_geo_material_replace(); diff --git a/source/blender/nodes/geometry/node_geometry_register.hh b/source/blender/nodes/geometry/node_geometry_register.hh index ca64e7b9904..5984bfa83ce 100644 --- a/source/blender/nodes/geometry/node_geometry_register.hh +++ b/source/blender/nodes/geometry/node_geometry_register.hh @@ -87,6 +87,7 @@ void register_node_type_geo_input_spline_resolution(); void register_node_type_geo_input_tangent(); void register_node_type_geo_instance_on_points(); void register_node_type_geo_instances_to_points(); +void register_node_type_geo_interpolate_curves(); void register_node_type_geo_is_viewport(); void register_node_type_geo_join_geometry(); void register_node_type_geo_material_replace(); diff --git a/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc new file mode 100644 index 00000000000..2142fa666cb --- /dev/null +++ b/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc @@ -0,0 +1,862 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "node_geometry_util.hh" + +#include "BLI_kdtree.h" +#include "BLI_length_parameterize.hh" +#include "BLI_task.hh" + +#include "BKE_curves.hh" +#include "BKE_curves_utils.hh" + +#include "DNA_pointcloud_types.h" + +namespace blender::nodes::node_geo_interpolate_curves_cc { + +static void node_declare(NodeDeclarationBuilder &b) +{ + b.add_input(N_("Guide Curves")) + .description(N_("Base curves that new curves are interpolated between")); + b.add_input(N_("Guide Up")) + .field_on({0}) + .hide_value() + .description(N_("Optional up vector that is typically a surface normal")); + b.add_input(N_("Guide Group ID")) + .field_on({0}) + .hide_value() + .description(N_("Splits guides into separate groups. New curves interpolate existing curves " + "from a single group")); + b.add_input(N_("Points")) + .description(N_("First control point positions for new interpolated curves")); + b.add_input(N_("Point Up")) + .field_on({3}) + .hide_value() + .description(N_("Optional up vector that is typically a surface normal")); + b.add_input(N_("Point Group ID")) + .field_on({3}) + .hide_value() + .description(N_("The curve group to interpolate in")); + b.add_input(N_("Max Neighbors")) + .default_value(4) + .min(1) + .description(N_( + "Maximum amount of close guide curves that are taken into account for interpolation")); + b.add_output(N_("Curves")).propagate_all(); + b.add_output(N_("Closest Index")) + .field_on_all() + .description(N_("Index of the closest guide curve for each generated curve")); + b.add_output(N_("Closest Weight")) + .field_on_all() + .description(N_("Weight of the closest guide curve for each generated curve")); +} + +/** + * Guides are split into groups. Every point will only interpolate between guides within the group + * with the same id. + */ +static MultiValueMap separate_guides_by_group(const VArray &guide_group_ids) +{ + MultiValueMap guides_by_group; + for (const int curve_i : guide_group_ids.index_range()) { + const int group = guide_group_ids[curve_i]; + guides_by_group.add(group, curve_i); + } + return guides_by_group; +} + +/** + * Checks if all curves within a group have the same number of points. If yes, a better + * interpolation algorithm can be used, that does not require resampling curves. + */ +static Map compute_points_per_curve_by_group( + const MultiValueMap &guides_by_group, const bke::CurvesGeometry &guide_curves) +{ + const OffsetIndices points_by_curve = guide_curves.points_by_curve(); + Map points_per_curve_by_group; + for (const auto &[group, guide_curve_indices] : guides_by_group.items()) { + int group_control_points = points_by_curve.size(guide_curve_indices[0]); + for (const int guide_curve_i : guide_curve_indices.as_span().drop_front(1)) { + const int control_points = points_by_curve.size(guide_curve_i); + if (group_control_points != control_points) { + group_control_points = -1; + break; + } + } + if (group_control_points != -1) { + points_per_curve_by_group.add(group, group_control_points); + } + } + return points_per_curve_by_group; +} + +/** + * Build a kdtree for every guide group. + */ +static Map build_kdtrees_for_root_positions( + const MultiValueMap &guides_by_group, const bke::CurvesGeometry &guide_curves) +{ + Map kdtrees; + const Span positions = guide_curves.positions(); + const Span offsets = guide_curves.offsets(); + + for (const auto item : guides_by_group.items()) { + const int group = item.key; + const Span guide_indices = item.value; + + KDTree_3d *kdtree = BLI_kdtree_3d_new(guide_indices.size()); + kdtrees.add_new(group, kdtree); + + for (const int curve_i : guide_indices) { + const int first_point_i = offsets[curve_i]; + const float3 &root_pos = positions[first_point_i]; + BLI_kdtree_3d_insert(kdtree, curve_i, root_pos); + } + } + threading::parallel_for_each(kdtrees.values(), + [](KDTree_3d *kdtree) { BLI_kdtree_3d_balance(kdtree); }); + return kdtrees; +} + +/** + * For every start point of newly generated curves, find the closest guide curves within the same + * group and compute a weight for each of them. + */ +static void find_neighbor_guides(const Span positions, + const VArray point_group_ids, + const Map kdtrees, + const MultiValueMap &guides_by_group, + const int max_neighbor_count, + MutableSpan r_all_neighbor_indices, + MutableSpan r_all_neighbor_weights, + MutableSpan r_all_neighbor_counts) +{ + threading::parallel_for(positions.index_range(), 128, [&](const IndexRange range) { + for (const int child_curve_i : range) { + const float3 &position = positions[child_curve_i]; + const int group = point_group_ids[child_curve_i]; + const KDTree_3d *kdtree = kdtrees.lookup_default(group, nullptr); + if (kdtree == nullptr) { + r_all_neighbor_counts[child_curve_i] = 0; + continue; + } + + const int num_guides_in_group = guides_by_group.lookup(group).size(); + /* Finding an additional neighbor that currently has weight zero is necessary to ensure that + * curves close by but with different guides still look similar. Otherwise there can be + * visible artifacts. */ + const bool use_extra_neighbor = num_guides_in_group > max_neighbor_count; + const int neighbors_to_find = max_neighbor_count + use_extra_neighbor; + + Vector nearest_n(neighbors_to_find); + const int num_neighbors = BLI_kdtree_3d_find_nearest_n( + kdtree, position, nearest_n.data(), neighbors_to_find); + if (num_neighbors == 0) { + r_all_neighbor_counts[child_curve_i] = 0; + continue; + } + + const IndexRange neighbors_range{child_curve_i * max_neighbor_count, max_neighbor_count}; + MutableSpan neighbor_indices = r_all_neighbor_indices.slice(neighbors_range); + MutableSpan neighbor_weights = r_all_neighbor_weights.slice(neighbors_range); + + float tot_weight = 0.0f; + /* A different weighting algorithm is necessary for smooth transitions when desired. */ + if (use_extra_neighbor) { + /* Find the distance to the guide with the largest distance. At this distance, the weight + * should become zero. */ + const float max_distance = std::max_element( + nearest_n.begin(), + nearest_n.begin() + num_neighbors, + [](const KDTreeNearest_3d &a, const KDTreeNearest_3d &b) { + return a.dist < b.dist; + }) + ->dist; + if (max_distance == 0.0f) { + r_all_neighbor_counts[child_curve_i] = 1; + neighbor_indices[0] = nearest_n[0].index; + neighbor_weights[0] = 1.0f; + continue; + } + + int neighbor_counter = 0; + for (const int neighbor_i : IndexRange(num_neighbors)) { + const KDTreeNearest_3d &nearest = nearest_n[neighbor_i]; + /* Goal for this weight calculation: + * - As distance gets closer to zero, it should become very large. + * - At `max_distance` the weight should be zero. */ + const float weight = (max_distance - nearest.dist) / std::max(nearest.dist, 0.000001f); + if (weight > 0.0f) { + tot_weight += weight; + neighbor_indices[neighbor_counter] = nearest.index; + neighbor_weights[neighbor_counter] = weight; + neighbor_counter++; + } + } + r_all_neighbor_counts[child_curve_i] = neighbor_counter; + } + else { + int neighbor_counter = 0; + for (const int neighbor_i : IndexRange(num_neighbors)) { + const KDTreeNearest_3d &nearest = nearest_n[neighbor_i]; + /* Goal for this weight calculation: + * - As the distance gets closer to zero, it should become very large. + * - As the distance gets larger, the weight should become zero. */ + const float weight = 1.0f / std::max(nearest.dist, 0.000001f); + if (weight > 0.0f) { + tot_weight += weight; + neighbor_indices[neighbor_counter] = nearest.index; + neighbor_weights[neighbor_counter] = weight; + neighbor_counter++; + } + } + r_all_neighbor_counts[child_curve_i] = neighbor_counter; + } + if (tot_weight > 0.0f) { + /* Normalize weights so that their sum is 1. */ + const float weight_factor = 1.0f / tot_weight; + for (float &weight : neighbor_weights.take_front(r_all_neighbor_counts[child_curve_i])) { + weight *= weight_factor; + } + } + } + }); +} + +/** + * Compute how many points each generated curve will have. This is determined by looking at + * neighboring points. + */ +static void compute_point_counts_per_child(const bke::CurvesGeometry &guide_curves, + const VArray &point_group_ids, + const Map &points_per_curve_by_group, + const Span all_neighbor_indices, + const Span all_neighbor_weights, + const Span all_neighbor_counts, + const int max_neighbors, + MutableSpan r_points_per_child, + MutableSpan r_use_direct_interpolation) +{ + const OffsetIndices guide_points_by_curve = guide_curves.points_by_curve(); + threading::parallel_for(r_points_per_child.index_range(), 512, [&](const IndexRange range) { + int points_sum = 0; + for (const int child_curve_i : range) { + const int neighbor_count = all_neighbor_counts[child_curve_i]; + if (neighbor_count == 0) { + r_points_per_child[child_curve_i] = 1; + r_use_direct_interpolation[child_curve_i] = false; + continue; + } + const int group = point_group_ids[child_curve_i]; + const int points_per_curve_in_group = points_per_curve_by_group.lookup_default(group, -1); + if (points_per_curve_in_group != -1) { + r_points_per_child[child_curve_i] = points_per_curve_in_group; + points_sum += points_per_curve_in_group; + r_use_direct_interpolation[child_curve_i] = true; + continue; + } + const IndexRange neighbors_range{child_curve_i * max_neighbors, neighbor_count}; + const Span neighbor_weights = all_neighbor_weights.slice(neighbors_range); + const Span neighbor_indices = all_neighbor_indices.slice(neighbors_range); + + float neighbor_points_weighted_sum = 0.0f; + for (const int neighbor_i : IndexRange(neighbor_count)) { + const int neighbor_index = neighbor_indices[neighbor_i]; + const float neighbor_weight = neighbor_weights[neighbor_i]; + const int neighbor_points = guide_points_by_curve.size(neighbor_index); + neighbor_points_weighted_sum += neighbor_weight * float(neighbor_points); + } + const int points_in_child = std::max(1, roundf(neighbor_points_weighted_sum)); + r_points_per_child[child_curve_i] = points_in_child; + r_use_direct_interpolation[child_curve_i] = false; + points_sum += r_points_per_child[child_curve_i]; + } + }); +} + +/** + * Prepares parameterized guide curves so that they can be used efficiently during interpolation. + */ +static void parameterize_guide_curves(const bke::CurvesGeometry &guide_curves, + Array &r_parameterized_guide_offsets, + Array &r_parameterized_guide_lengths) +{ + r_parameterized_guide_offsets.reinitialize(guide_curves.curves_num() + 1); + const OffsetIndices guide_points_by_curve = guide_curves.points_by_curve(); + threading::parallel_for(guide_curves.curves_range(), 1024, [&](const IndexRange range) { + for (const int guide_curve_i : range) { + r_parameterized_guide_offsets[guide_curve_i] = length_parameterize::segments_num( + guide_points_by_curve.size(guide_curve_i), false); + } + }); + offset_indices::accumulate_counts_to_offsets(r_parameterized_guide_offsets); + const OffsetIndices parameterize_offsets{r_parameterized_guide_offsets}; + + r_parameterized_guide_lengths.reinitialize(r_parameterized_guide_offsets.last()); + const Span guide_positions = guide_curves.positions(); + threading::parallel_for(guide_curves.curves_range(), 256, [&](const IndexRange range) { + for (const int guide_curve_i : range) { + const IndexRange points = guide_points_by_curve[guide_curve_i]; + const IndexRange lengths_range = parameterize_offsets[guide_curve_i]; + length_parameterize::accumulate_lengths( + guide_positions.slice(points), + false, + r_parameterized_guide_lengths.as_mutable_span().slice(lengths_range)); + } + }); +} + +/** + * Initialize child curve positions by interpolating between guide curves. + */ +static void interpolate_curve_shapes(bke::CurvesGeometry &child_curves, + const bke::CurvesGeometry &guide_curves, + const int max_neighbors, + const Span all_neighbor_indices, + const Span all_neighbor_weights, + const Span all_neighbor_counts, + const VArray &guides_up, + const VArray &points_up, + const Span point_positions, + const OffsetIndices parameterized_guide_offsets, + const Span parameterized_guide_lengths, + const Span use_direct_interpolation_per_child) +{ + const OffsetIndices guide_points_by_curve = guide_curves.points_by_curve(); + const OffsetIndices child_points_by_curve = child_curves.points_by_curve(); + const MutableSpan children_positions = child_curves.positions_for_write(); + const Span guide_positions = guide_curves.positions(); + + threading::parallel_for(child_curves.curves_range(), 128, [&](const IndexRange range) { + Vector sample_lengths; + Vector sample_segments; + Vector sample_factors; + + for (const int child_curve_i : range) { + const IndexRange points = child_points_by_curve[child_curve_i]; + const int neighbor_count = all_neighbor_counts[child_curve_i]; + const float3 child_up = points_up[child_curve_i]; + BLI_assert(math::is_unit_scale(child_up)); + const float3 &child_root_position = point_positions[child_curve_i]; + MutableSpan child_positions = children_positions.slice(points); + + child_positions.fill(child_root_position); + if (neighbor_count == 0) { + /* Creates a curve with a single point at the root position. */ + continue; + } + + const IndexRange neighbors_range{child_curve_i * max_neighbors, neighbor_count}; + const Span neighbor_weights = all_neighbor_weights.slice(neighbors_range); + const Span neighbor_indices = all_neighbor_indices.slice(neighbors_range); + + const bool use_direct_interpolation = use_direct_interpolation_per_child[child_curve_i]; + + for (const int neighbor_i : IndexRange(neighbor_count)) { + const int neighbor_index = neighbor_indices[neighbor_i]; + const float neighbor_weight = neighbor_weights[neighbor_i]; + const IndexRange guide_points = guide_points_by_curve[neighbor_index]; + const Span neighbor_positions = guide_positions.slice(guide_points); + const float3 &neighbor_root = neighbor_positions[0]; + const float3 neighbor_up = guides_up[neighbor_index]; + BLI_assert(math::is_unit_scale(neighbor_up)); + + const bool is_same_up_vector = neighbor_up == child_up; + + float3x3 normal_rotation; + if (!is_same_up_vector) { + rotation_between_vecs_to_mat3(normal_rotation.ptr(), neighbor_up, child_up); + } + + if (use_direct_interpolation) { + /* In this method, the control point positions are interpolated directly instead of + * looking at evaluated points. This is much faster than the method below but only works + * if all guides have the same number of points. */ + for (const int i : IndexRange(points.size())) { + const float3 &neighbor_pos = neighbor_positions[i]; + const float3 relative_to_root = neighbor_pos - neighbor_root; + float3 rotated_relative = relative_to_root; + if (!is_same_up_vector) { + rotated_relative = normal_rotation * rotated_relative; + } + child_positions[i] += neighbor_weight * rotated_relative; + } + } + else { + /* This method is used when guide curves have different amounts of control points. In + * this case, some additional interpolation is necessary compared to the method above. */ + + const Span lengths = parameterized_guide_lengths.slice( + parameterized_guide_offsets[neighbor_index]); + const float neighbor_length = lengths.last(); + + sample_lengths.reinitialize(points.size()); + const float sample_length_factor = safe_divide(neighbor_length, points.size() - 1); + for (const int i : sample_lengths.index_range()) { + sample_lengths[i] = i * sample_length_factor; + } + + sample_segments.reinitialize(points.size()); + sample_factors.reinitialize(points.size()); + length_parameterize::sample_at_lengths( + lengths, sample_lengths, sample_segments, sample_factors); + + for (const int i : IndexRange(points.size())) { + const int segment = sample_segments[i]; + const float factor = sample_factors[i]; + const float3 sample_pos = math::interpolate( + neighbor_positions[segment], neighbor_positions[segment + 1], factor); + const float3 relative_to_root = sample_pos - neighbor_root; + float3 rotated_relative = relative_to_root; + if (!is_same_up_vector) { + rotated_relative = normal_rotation * rotated_relative; + } + child_positions[i] += neighbor_weight * rotated_relative; + } + } + } + } + }); + + /* Can only create catmull rom curves for now. */ + child_curves.fill_curve_types(CURVE_TYPE_CATMULL_ROM); +} + +/** + * Propagate attributes from the guides and source points to the child curves. + */ +static void interpolate_curve_attributes(bke::CurvesGeometry &child_curves, + const bke::CurvesGeometry &guide_curves, + const AttributeAccessor &point_attributes, + const AnonymousAttributePropagationInfo &propagation_info, + const int max_neighbors, + const Span all_neighbor_indices, + const Span all_neighbor_weights, + const Span all_neighbor_counts, + const OffsetIndices parameterized_guide_offsets, + const Span parameterized_guide_lengths, + const Span use_direct_interpolation_per_child) +{ + const AttributeAccessor guide_curve_attributes = guide_curves.attributes(); + MutableAttributeAccessor children_attributes = child_curves.attributes_for_write(); + + const OffsetIndices child_points_by_curve = child_curves.points_by_curve(); + const OffsetIndices guide_points_by_curve = guide_curves.points_by_curve(); + + /* Interpolate attributes from guide curves to child curves. Attributes stay on the same domain + * that they had on the guides. */ + guide_curve_attributes.for_all([&](const AttributeIDRef &id, + const AttributeMetaData &meta_data) { + if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) { + return true; + } + if (meta_data.data_type == CD_PROP_STRING) { + return true; + } + if (guide_curve_attributes.is_builtin(id) && + !ELEM(id.name(), "radius", "tilt", "resolution")) { + return true; + } + + if (meta_data.domain == ATTR_DOMAIN_CURVE) { + const GVArraySpan src_generic = guide_curve_attributes.lookup( + id, ATTR_DOMAIN_CURVE, meta_data.data_type); + + GSpanAttributeWriter dst_generic = children_attributes.lookup_or_add_for_write_only_span( + id, ATTR_DOMAIN_CURVE, meta_data.data_type); + if (!dst_generic) { + return true; + } + attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) { + using T = decltype(dummy); + const Span src = src_generic.typed(); + MutableSpan dst = dst_generic.span.typed(); + + attribute_math::DefaultMixer mixer(dst); + threading::parallel_for(child_curves.curves_range(), 256, [&](const IndexRange range) { + for (const int child_curve_i : range) { + const int neighbor_count = all_neighbor_counts[child_curve_i]; + const IndexRange neighbors_range{child_curve_i * max_neighbors, neighbor_count}; + const Span neighbor_weights = all_neighbor_weights.slice(neighbors_range); + const Span neighbor_indices = all_neighbor_indices.slice(neighbors_range); + + for (const int neighbor_i : IndexRange(neighbor_count)) { + const int neighbor_index = neighbor_indices[neighbor_i]; + const float neighbor_weight = neighbor_weights[neighbor_i]; + mixer.mix_in(child_curve_i, src[neighbor_index], neighbor_weight); + } + } + mixer.finalize(range); + }); + }); + + dst_generic.finish(); + } + else { + BLI_assert(meta_data.domain == ATTR_DOMAIN_POINT); + const GVArraySpan src_generic = guide_curve_attributes.lookup( + id, ATTR_DOMAIN_POINT, meta_data.data_type); + GSpanAttributeWriter dst_generic = children_attributes.lookup_or_add_for_write_only_span( + id, ATTR_DOMAIN_POINT, meta_data.data_type); + if (!dst_generic) { + return true; + } + + attribute_math::convert_to_static_type(meta_data.data_type, [&](auto dummy) { + using T = decltype(dummy); + const Span src = src_generic.typed(); + MutableSpan dst = dst_generic.span.typed(); + + attribute_math::DefaultMixer mixer(dst); + threading::parallel_for(child_curves.curves_range(), 256, [&](const IndexRange range) { + Vector sample_lengths; + Vector sample_segments; + Vector sample_factors; + for (const int child_curve_i : range) { + const IndexRange points = child_points_by_curve[child_curve_i]; + const int neighbor_count = all_neighbor_counts[child_curve_i]; + const IndexRange neighbors_range{child_curve_i * max_neighbors, neighbor_count}; + const Span neighbor_weights = all_neighbor_weights.slice(neighbors_range); + const Span neighbor_indices = all_neighbor_indices.slice(neighbors_range); + const bool use_direct_interpolation = + use_direct_interpolation_per_child[child_curve_i]; + + for (const int neighbor_i : IndexRange(neighbor_count)) { + const int neighbor_index = neighbor_indices[neighbor_i]; + const float neighbor_weight = neighbor_weights[neighbor_i]; + const IndexRange guide_points = guide_points_by_curve[neighbor_index]; + + if (use_direct_interpolation) { + for (const int i : IndexRange(points.size())) { + mixer.mix_in(points[i], src[guide_points[i]], neighbor_weight); + } + } + else { + const Span lengths = parameterized_guide_lengths.slice( + parameterized_guide_offsets[neighbor_index]); + const float neighbor_length = lengths.last(); + + sample_lengths.reinitialize(points.size()); + const float sample_length_factor = safe_divide(neighbor_length, points.size() - 1); + for (const int i : sample_lengths.index_range()) { + sample_lengths[i] = i * sample_length_factor; + } + + sample_segments.reinitialize(points.size()); + sample_factors.reinitialize(points.size()); + length_parameterize::sample_at_lengths( + lengths, sample_lengths, sample_segments, sample_factors); + + for (const int i : IndexRange(points.size())) { + const int segment = sample_segments[i]; + const float factor = sample_factors[i]; + const T value = math::interpolate( + src[guide_points[segment]], src[guide_points[segment + 1]], factor); + mixer.mix_in(points[i], value, neighbor_weight); + } + } + } + } + mixer.finalize(child_points_by_curve[range]); + }); + }); + + dst_generic.finish(); + } + + return true; + }); + + /* Interpolate attributes from the points to child curves. All attributes become curve + * attributes. */ + point_attributes.for_all([&](const AttributeIDRef &id, const AttributeMetaData &meta_data) { + if (point_attributes.is_builtin(id) && !children_attributes.is_builtin(id)) { + return true; + } + if (guide_curve_attributes.contains(id)) { + return true; + } + if (id.is_anonymous() && !propagation_info.propagate(id.anonymous_id())) { + return true; + } + if (meta_data.data_type == CD_PROP_STRING) { + return true; + } + + const GVArray src = point_attributes.lookup(id, ATTR_DOMAIN_POINT, meta_data.data_type); + GSpanAttributeWriter dst = children_attributes.lookup_or_add_for_write_only_span( + id, ATTR_DOMAIN_CURVE, meta_data.data_type); + if (!dst) { + return true; + } + src.materialize(dst.span.data()); + dst.finish(); + return true; + }); +} + +static void store_output_attributes(bke::CurvesGeometry &child_curves, + const AutoAnonymousAttributeID weight_attribute_id, + const AutoAnonymousAttributeID index_attribute_id, + const int max_neighbors, + const Span all_neighbor_counts, + const Span all_neighbor_indices, + const Span all_neighbor_weights) +{ + if (!weight_attribute_id && !index_attribute_id) { + return; + } + SpanAttributeWriter weight_attribute; + if (weight_attribute_id) { + weight_attribute = + child_curves.attributes_for_write().lookup_or_add_for_write_only_span( + *weight_attribute_id, ATTR_DOMAIN_CURVE); + } + SpanAttributeWriter index_attribute; + if (index_attribute_id) { + index_attribute = child_curves.attributes_for_write().lookup_or_add_for_write_only_span( + *index_attribute_id, ATTR_DOMAIN_CURVE); + } + threading::parallel_for(child_curves.curves_range(), 512, [&](const IndexRange range) { + for (const int child_curve_i : range) { + const int neighbor_count = all_neighbor_counts[child_curve_i]; + + int closest_index; + float closest_weight; + if (neighbor_count == 0) { + closest_index = 0; + closest_weight = 0.0f; + } + else { + const IndexRange neighbors_range{child_curve_i * max_neighbors, neighbor_count}; + const Span neighbor_weights = all_neighbor_weights.slice(neighbors_range); + const Span neighbor_indices = all_neighbor_indices.slice(neighbors_range); + const int max_index = std::max_element(neighbor_weights.begin(), neighbor_weights.end()) - + neighbor_weights.begin(); + closest_index = neighbor_indices[max_index]; + closest_weight = neighbor_weights[max_index]; + } + if (index_attribute) { + index_attribute.span[child_curve_i] = closest_index; + } + if (weight_attribute) { + weight_attribute.span[child_curve_i] = closest_weight; + } + } + }); + if (index_attribute) { + index_attribute.finish(); + } + if (weight_attribute) { + weight_attribute.finish(); + } +} + +static GeometrySet generate_interpolated_curves( + const Curves &guide_curves_id, + const AttributeAccessor &point_attributes, + const VArray &guides_up, + const VArray &points_up, + const VArray &guide_group_ids, + const VArray &point_group_ids, + const int max_neighbors, + const AnonymousAttributePropagationInfo &propagation_info, + const AutoAnonymousAttributeID &index_attribute_id, + const AutoAnonymousAttributeID &weight_attribute_id) +{ + const bke::CurvesGeometry &guide_curves = bke::CurvesGeometry::wrap(guide_curves_id.geometry); + + const MultiValueMap guides_by_group = separate_guides_by_group(guide_group_ids); + const Map points_per_curve_by_group = compute_points_per_curve_by_group( + guides_by_group, guide_curves); + + Map kdtrees = build_kdtrees_for_root_positions(guides_by_group, guide_curves); + BLI_SCOPED_DEFER([&]() { + for (KDTree_3d *kdtree : kdtrees.values()) { + BLI_kdtree_3d_free(kdtree); + } + }); + + const VArraySpan point_positions = point_attributes.lookup("position"); + const int num_child_curves = point_attributes.domain_size(ATTR_DOMAIN_POINT); + + /* The set of guides per child are stored in a flattened array to allow fast access, reduce + * memory consumption and reduce number of allocations. */ + Array all_neighbor_indices(num_child_curves * max_neighbors); + Array all_neighbor_weights(num_child_curves * max_neighbors); + Array all_neighbor_counts(num_child_curves); + + find_neighbor_guides(point_positions, + point_group_ids, + kdtrees, + guides_by_group, + max_neighbors, + all_neighbor_indices, + all_neighbor_weights, + all_neighbor_counts); + + Curves *child_curves_id = bke::curves_new_nomain(0, num_child_curves); + bke::CurvesGeometry &child_curves = bke::CurvesGeometry::wrap(child_curves_id->geometry); + MutableSpan children_curve_offsets = child_curves.offsets_for_write(); + + Array use_direct_interpolation_per_child(num_child_curves); + compute_point_counts_per_child(guide_curves, + point_group_ids, + points_per_curve_by_group, + all_neighbor_indices, + all_neighbor_weights, + all_neighbor_counts, + max_neighbors, + children_curve_offsets.drop_back(1), + use_direct_interpolation_per_child); + offset_indices::accumulate_counts_to_offsets(children_curve_offsets); + const int num_child_points = children_curve_offsets.last(); + child_curves.resize(num_child_points, num_child_curves); + + /* Stores parameterization of all guide curves in flat arrays. */ + Array parameterized_guide_offsets; + Array parameterized_guide_lengths; + parameterize_guide_curves( + guide_curves, parameterized_guide_offsets, parameterized_guide_lengths); + + interpolate_curve_shapes(child_curves, + guide_curves, + max_neighbors, + all_neighbor_indices, + all_neighbor_weights, + all_neighbor_counts, + guides_up, + points_up, + point_positions, + OffsetIndices(parameterized_guide_offsets), + parameterized_guide_lengths, + use_direct_interpolation_per_child); + interpolate_curve_attributes(child_curves, + guide_curves, + point_attributes, + propagation_info, + max_neighbors, + all_neighbor_indices, + all_neighbor_weights, + all_neighbor_counts, + OffsetIndices(parameterized_guide_offsets), + parameterized_guide_lengths, + use_direct_interpolation_per_child); + + store_output_attributes(child_curves, + weight_attribute_id, + index_attribute_id, + max_neighbors, + all_neighbor_counts, + all_neighbor_indices, + all_neighbor_weights); + + return GeometrySet::create_with_curves(child_curves_id); +} + +static void node_geo_exec(GeoNodeExecParams params) +{ + GeometrySet guide_curves_geometry = params.extract_input("Guide Curves"); + const GeometrySet points_geometry = params.extract_input("Points"); + + if (!guide_curves_geometry.has_curves()) { + params.set_default_remaining_outputs(); + return; + } + const GeometryComponent *points_component = + points_geometry.get_component_for_read(); + if (points_component == nullptr) { + points_component = points_geometry.get_component_for_read(); + } + if (points_component == nullptr || points_geometry.is_empty()) { + params.set_default_remaining_outputs(); + return; + } + + const int max_neighbors = std::max(1, params.extract_input("Max Neighbors")); + + static auto normalize_fn = mf::build::SI1_SO( + "Normalize", + [](const float3 &v) { return math::normalize(v); }, + mf::build::exec_presets::AllSpanOrSingle()); + + /* Normalize up fields so that is done as part of field evaluation. */ + Field guides_up_field( + FieldOperation::Create(normalize_fn, {params.extract_input>("Guide Up")})); + Field points_up_field( + FieldOperation::Create(normalize_fn, {params.extract_input>("Point Up")})); + + Field guide_group_field = params.extract_input>("Guide Group ID"); + Field point_group_field = params.extract_input>("Point Group ID"); + + const Curves &guide_curves_id = *guide_curves_geometry.get_curves_for_read(); + + bke::CurvesFieldContext curves_context{bke::CurvesGeometry::wrap(guide_curves_id.geometry), + ATTR_DOMAIN_CURVE}; + fn::FieldEvaluator curves_evaluator{curves_context, guide_curves_id.geometry.curve_num}; + curves_evaluator.add(guides_up_field); + curves_evaluator.add(guide_group_field); + curves_evaluator.evaluate(); + const VArray guides_up = curves_evaluator.get_evaluated(0); + const VArray guide_group_ids = curves_evaluator.get_evaluated(1); + + bke::GeometryFieldContext points_context(*points_component, ATTR_DOMAIN_POINT); + fn::FieldEvaluator points_evaluator{points_context, + points_component->attribute_domain_size(ATTR_DOMAIN_POINT)}; + points_evaluator.add(points_up_field); + points_evaluator.add(point_group_field); + points_evaluator.evaluate(); + const VArray points_up = points_evaluator.get_evaluated(0); + const VArray point_group_ids = points_evaluator.get_evaluated(1); + + const AnonymousAttributePropagationInfo propagation_info = params.get_output_propagation_info( + "Curves"); + + AutoAnonymousAttributeID index_attribute_id = params.get_output_anonymous_attribute_id_if_needed( + "Closest Index"); + AutoAnonymousAttributeID weight_attribute_id = + params.get_output_anonymous_attribute_id_if_needed("Closest Weight"); + + GeometrySet new_curves = generate_interpolated_curves(guide_curves_id, + *points_component->attributes(), + guides_up, + points_up, + guide_group_ids, + point_group_ids, + max_neighbors, + propagation_info, + index_attribute_id, + weight_attribute_id); + + GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(guide_curves_geometry); + if (const auto *curve_edit_data = + guide_curves_geometry.get_component_for_read()) { + new_curves.add(*curve_edit_data); + } + + params.set_output("Curves", std::move(new_curves)); + if (index_attribute_id) { + params.set_output("Closest Index", + AnonymousAttributeFieldInput::Create(std::move(index_attribute_id), + params.attribute_producer_name())); + } + if (weight_attribute_id) { + params.set_output("Closest Weight", + AnonymousAttributeFieldInput::Create( + std::move(weight_attribute_id), params.attribute_producer_name())); + } +} + +} // namespace blender::nodes::node_geo_interpolate_curves_cc + +void register_node_type_geo_interpolate_curves() +{ + namespace file_ns = blender::nodes::node_geo_interpolate_curves_cc; + + static bNodeType ntype; + + geo_node_type_base( + &ntype, GEO_NODE_INTERPOLATE_CURVES, "Interpolate Curves", NODE_CLASS_GEOMETRY); + ntype.geometry_node_execute = file_ns::node_geo_exec; + ntype.declare = file_ns::node_declare; + nodeRegisterType(&ntype); +} diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 201d7fb8b48..2dc3e560e35 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -815,6 +815,7 @@ set(geo_node_tests attributes curve_primitives curves + curves/interpolate_curves geometry instance mesh_primitives From 127eb2e328bbbbaf089176c73ad4e50f54a3600d Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 20 Jan 2023 12:16:49 +0100 Subject: [PATCH 0824/1522] Fix: wrong identifier int for interpolate curves node This does not break existing files, because the idname is the ground truth. --- source/blender/blenkernel/BKE_node.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 386fe7fc77f..d57857bfdf3 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -1533,6 +1533,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i #define GEO_NODE_IMAGE_INFO 1189 #define GEO_NODE_BLUR_ATTRIBUTE 1190 #define GEO_NODE_IMAGE 1191 +#define GEO_NODE_INTERPOLATE_CURVES 1192 /** \} */ @@ -1562,8 +1563,6 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i /** \} */ -#define GEO_NODE_INTERPOLATE_CURVES 2000 - void BKE_node_system_init(void); void BKE_node_system_exit(void); From 5218391701b7a49f24c93078994aa44d82e1c1c2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Jan 2023 22:29:07 +1100 Subject: [PATCH 0825/1522] Fix assertion in UV path select Existing path selection & new path picking included without UV's. Now limit objects to those with UV's. Also remove use of CTX_wm_view3d(C) in the UV editor it would be NULL, but it doesn't makes sense to use the 3D viewport for UV operations even if it was available. --- source/blender/editors/uvedit/uvedit_path.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c index e8ba3b0cffd..00d86fef831 100644 --- a/source/blender/editors/uvedit/uvedit_path.c +++ b/source/blender/editors/uvedit/uvedit_path.c @@ -562,8 +562,8 @@ static int uv_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmEve Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); ViewLayer *view_layer = CTX_data_view_layer(C); uint objects_len = 0; - Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( - scene, view_layer, CTX_wm_view3d(C), &objects_len); + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( + scene, view_layer, NULL, &objects_len); float co[2]; @@ -796,8 +796,8 @@ static int uv_shortest_path_select_exec(bContext *C, wmOperator *op) ViewLayer *view_layer = CTX_data_view_layer(C); uint objects_len = 0; - Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( - scene, view_layer, CTX_wm_view3d(C), &objects_len); + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( + scene, view_layer, NULL, &objects_len); for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(obedit); From 453e47eb423306af5f6929ad79e7e6d17c7c656d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 20 Jan 2023 22:30:25 +1100 Subject: [PATCH 0826/1522] Cleanup: suppress clang-tidy warning --- source/blender/editors/uvedit/uvedit_path.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/editors/uvedit/uvedit_path.c b/source/blender/editors/uvedit/uvedit_path.c index 00d86fef831..274196f79a4 100644 --- a/source/blender/editors/uvedit/uvedit_path.c +++ b/source/blender/editors/uvedit/uvedit_path.c @@ -709,6 +709,7 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op) BMElem *ele_src, *ele_dst; + /* NOLINTBEGIN: bugprone-assignment-in-if-condition */ if (uv_selectmode & UV_SELECT_FACE) { if (index < 0 || index >= bm->totface) { return OPERATOR_CANCELLED; @@ -736,6 +737,7 @@ static int uv_shortest_path_pick_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } } + /* NOLINTEND: bugprone-assignment-in-if-condition */ /* Always use the active object, not `obedit` as the active defines the UV display. */ const float aspect_y = ED_uvedit_get_aspect_y(CTX_data_edit_object(C)); From 31a505d1a5ead4522460aaaef595ad1dea8841f6 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 20 Jan 2023 13:39:10 +0100 Subject: [PATCH 0827/1522] Functions: add debug utility for lazy function graphs This makes it easier to print information about a socket. Just the socket name is sometimes not enough information to know where it is in the graph. --- source/blender/functions/FN_lazy_function_graph.hh | 1 + source/blender/functions/intern/lazy_function_graph.cc | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/source/blender/functions/FN_lazy_function_graph.hh b/source/blender/functions/FN_lazy_function_graph.hh index 6d66afafe82..a532f0dc7c3 100644 --- a/source/blender/functions/FN_lazy_function_graph.hh +++ b/source/blender/functions/FN_lazy_function_graph.hh @@ -78,6 +78,7 @@ class Socket : NonCopyable, NonMovable { const CPPType &type() const; std::string name() const; + std::string detailed_name() const; }; class InputSocket : public Socket { diff --git a/source/blender/functions/intern/lazy_function_graph.cc b/source/blender/functions/intern/lazy_function_graph.cc index e07cce7204b..0047359ed26 100644 --- a/source/blender/functions/intern/lazy_function_graph.cc +++ b/source/blender/functions/intern/lazy_function_graph.cc @@ -147,6 +147,14 @@ std::string Socket::name() const return fallback_name; } +std::string Socket::detailed_name() const +{ + std::stringstream ss; + ss << node_->name() << ":" << (is_input_ ? "IN" : "OUT") << ":" << index_in_node_ << ":" + << this->name(); + return ss.str(); +} + std::string Node::name() const { if (this->is_function()) { From b6278c5a9670a550051b9e51f81541392ab16e4a Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 20 Jan 2023 14:15:22 +0100 Subject: [PATCH 0828/1522] Fix: crash when subdividing curves This was an error in rB38a45e46bc910c68ae3. --- source/blender/geometry/intern/subdivide_curves.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/geometry/intern/subdivide_curves.cc b/source/blender/geometry/intern/subdivide_curves.cc index 99a20b1122d..f062f720366 100644 --- a/source/blender/geometry/intern/subdivide_curves.cc +++ b/source/blender/geometry/intern/subdivide_curves.cc @@ -85,7 +85,7 @@ static void subdivide_attribute_linear(const bke::CurvesGeometry &src_curves, threading::parallel_for(curve_src.index_range().drop_back(1), 1024, [&](IndexRange range) { for (const int i : range) { - const IndexRange segment_points = curve_offsets[src_segments[i]]; + const IndexRange segment_points = curve_offsets[i]; linear_interpolation(curve_src[i], curve_src[i + 1], curve_dst.slice(segment_points)); } }); From d79abb5d4f559fad4d2e057c7d163334ac9c30d8 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 20 Jan 2023 14:33:06 +0100 Subject: [PATCH 0829/1522] Fix: missing clamping in single mode in Sample Index node --- .../geometry/nodes/node_geo_sample_index.cc | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc index 2ac19b02f9c..b6267d2439a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_sample_index.cc @@ -298,6 +298,7 @@ static void node_geo_exec(GeoNodeExecParams params) const NodeGeometrySampleIndex &storage = node_storage(params.node()); const eCustomDataType data_type = eCustomDataType(storage.data_type); const eAttrDomain domain = eAttrDomain(storage.domain); + const bool use_clamp = bool(storage.clamp); GField value_field = get_input_attribute_field(params, data_type); ValueOrField index_value_or_field = params.extract_input>("Index"); @@ -307,24 +308,33 @@ static void node_geo_exec(GeoNodeExecParams params) if (index_value_or_field.is_field()) { /* If the index is a field, the output has to be a field that still depends on the input. */ auto fn = std::make_shared( - std::move(geometry), std::move(value_field), domain, bool(storage.clamp)); + std::move(geometry), std::move(value_field), domain, use_clamp); auto op = FieldOperation::Create(std::move(fn), {index_value_or_field.as_field()}); output_field = GField(std::move(op)); } else if (const GeometryComponent *component = find_source_component(geometry, domain)) { /* Optimization for the case when the index is a single value. Here only that one index has to * be evaluated. */ - const int index = index_value_or_field.as_value(); - const IndexMask mask = IndexRange(index, 1); - bke::GeometryFieldContext geometry_context(*component, domain); - FieldEvaluator evaluator(geometry_context, &mask); - evaluator.add(value_field); - evaluator.evaluate(); - const GVArray &data = evaluator.get_evaluated(0); - BUFFER_FOR_CPP_TYPE_VALUE(cpp_type, buffer); - data.get_to_uninitialized(index, buffer); - output_field = fn::make_constant_field(cpp_type, buffer); - cpp_type.destruct(buffer); + const int domain_size = component->attribute_domain_size(domain); + int index = index_value_or_field.as_value(); + if (use_clamp) { + index = std::clamp(index, 0, domain_size - 1); + } + if (index >= 0 && index < domain_size) { + const IndexMask mask = IndexRange(index, 1); + bke::GeometryFieldContext geometry_context(*component, domain); + FieldEvaluator evaluator(geometry_context, &mask); + evaluator.add(value_field); + evaluator.evaluate(); + const GVArray &data = evaluator.get_evaluated(0); + BUFFER_FOR_CPP_TYPE_VALUE(cpp_type, buffer); + data.get_to_uninitialized(index, buffer); + output_field = fn::make_constant_field(cpp_type, buffer); + cpp_type.destruct(buffer); + } + else { + output_field = fn::make_constant_field(cpp_type, cpp_type.default_value()); + } } else { /* Output default value if there is no geometry. */ From c006ba83e0b296983b53d924cfbd0c69aad12de6 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 20 Jan 2023 14:38:09 +0100 Subject: [PATCH 0830/1522] Fix: execution graph for geometry nodes contained cycles leading to crash The `fix_link_cycles` function added in rB2ffd08e95249df2a068dd did not handle the case correctly when there are multiple cycles going through the same socket. --- .../intern/geometry_nodes_lazy_function.cc | 47 +++++++++++++++---- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 54f8c3c912d..64551249e29 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -2571,28 +2571,31 @@ struct GeometryNodesLazyFunctionGraphBuilder { Array socket_states(sockets_num); - Stack lf_sockets_to_check; + Vector lf_sockets_to_check; for (lf::Node *lf_node : lf_graph_->nodes()) { if (lf_node->is_function()) { for (lf::OutputSocket *lf_socket : lf_node->outputs()) { if (lf_socket->targets().is_empty()) { - lf_sockets_to_check.push(lf_socket); + lf_sockets_to_check.append(lf_socket); } } } if (lf_node->outputs().is_empty()) { for (lf::InputSocket *lf_socket : lf_node->inputs()) { - lf_sockets_to_check.push(lf_socket); + lf_sockets_to_check.append(lf_socket); } } } Vector lf_socket_stack; while (!lf_sockets_to_check.is_empty()) { - lf::Socket *lf_inout_socket = lf_sockets_to_check.peek(); + lf::Socket *lf_inout_socket = lf_sockets_to_check.last(); lf::Node &lf_node = lf_inout_socket->node(); SocketState &state = socket_states[lf_inout_socket->index_in_graph()]; - lf_socket_stack.append(lf_inout_socket); - state.in_stack = true; + + if (!state.in_stack) { + lf_socket_stack.append(lf_inout_socket); + state.in_stack = true; + } Vector lf_origin_sockets; if (lf_inout_socket->is_input()) { @@ -2616,10 +2619,24 @@ struct GeometryNodesLazyFunctionGraphBuilder { } bool pushed_socket = false; + bool detected_cycle = false; for (lf::Socket *lf_origin_socket : lf_origin_sockets) { if (socket_states[lf_origin_socket->index_in_graph()].in_stack) { + /* A cycle has been detected. The cycle is broken by removing a link and replacing it + * with a constant "true" input. This can only affect inputs which determine whether a + * specific value is used. Therefore, setting it to a constant true can result in more + * computation later, but does not change correctness. + * + * After the cycle is broken, the cycle-detection is "rolled back" to the socket where + * the first socket of the cycle was found. This is necessary in case another cycle goes + * through this socket. */ + + detected_cycle = true; + const int index_in_socket_stack = lf_socket_stack.first_index_of(lf_origin_socket); + const int index_in_sockets_to_check = lf_sockets_to_check.first_index_of( + lf_origin_socket); const Span cycle = lf_socket_stack.as_span().drop_front( - lf_socket_stack.first_index_of(lf_origin_socket)); + index_in_socket_stack); bool broke_cycle = false; for (lf::Socket *lf_cycle_socket : cycle) { @@ -2631,23 +2648,35 @@ struct GeometryNodesLazyFunctionGraphBuilder { lf_cycle_input_socket.set_default_value(&static_true); broke_cycle = true; } + /* This is actually removed from the stack when it is resized below. */ + SocketState &lf_cycle_socket_state = socket_states[lf_cycle_socket->index_in_graph()]; + lf_cycle_socket_state.in_stack = false; } if (!broke_cycle) { BLI_assert_unreachable(); } + /* Roll back algorithm by removing the sockets that corresponded to the cycle from the + * stacks. */ + lf_socket_stack.resize(index_in_socket_stack); + /* The +1 is there so that the socket itself is not removed. */ + lf_sockets_to_check.resize(index_in_sockets_to_check + 1); + break; } else if (!socket_states[lf_origin_socket->index_in_graph()].done) { - lf_sockets_to_check.push(lf_origin_socket); + lf_sockets_to_check.append(lf_origin_socket); pushed_socket = true; } } + if (detected_cycle) { + continue; + } if (pushed_socket) { continue; } state.done = true; state.in_stack = false; - lf_sockets_to_check.pop(); + lf_sockets_to_check.pop_last(); lf_socket_stack.pop_last(); } } From c8a10c43b13e109ec1bd78eedeea318be2c22980 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 20 Jan 2023 14:44:37 +0100 Subject: [PATCH 0831/1522] Geometry Nodes: show number of curve points in socket inspection tooltip This was not done originally, because one had to iterate over all curves to get the number of points which had some overhead. Now the number of points is stored all the time anyway. --- source/blender/editors/space_node/node_draw.cc | 3 ++- source/blender/nodes/NOD_geometry_nodes_log.hh | 1 + source/blender/nodes/intern/geometry_nodes_log.cc | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index bc4b6d416c1..53a86e23ce1 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -945,7 +945,8 @@ static void create_inspection_string_for_geometry_info(const geo_log::GeometryIn char line[256]; BLI_snprintf(line, sizeof(line), - TIP_("\u2022 Curve: %s splines"), + TIP_("\u2022 Curve: %s points, %s splines"), + to_string(curve_info.points_num).c_str(), to_string(curve_info.splines_num).c_str()); ss << line; break; diff --git a/source/blender/nodes/NOD_geometry_nodes_log.hh b/source/blender/nodes/NOD_geometry_nodes_log.hh index 3d453de4b78..9f28bad1630 100644 --- a/source/blender/nodes/NOD_geometry_nodes_log.hh +++ b/source/blender/nodes/NOD_geometry_nodes_log.hh @@ -126,6 +126,7 @@ class GeometryInfoLog : public ValueLog { int verts_num, edges_num, faces_num; }; struct CurveInfo { + int points_num; int splines_num; }; struct PointCloudInfo { diff --git a/source/blender/nodes/intern/geometry_nodes_log.cc b/source/blender/nodes/intern/geometry_nodes_log.cc index 66ccab2f77f..919159a31de 100644 --- a/source/blender/nodes/intern/geometry_nodes_log.cc +++ b/source/blender/nodes/intern/geometry_nodes_log.cc @@ -89,6 +89,7 @@ GeometryInfoLog::GeometryInfoLog(const GeometrySet &geometry_set) case GEO_COMPONENT_TYPE_CURVE: { const CurveComponent &curve_component = *(const CurveComponent *)component; CurveInfo &info = this->curve_info.emplace(); + info.points_num = curve_component.attribute_domain_size(ATTR_DOMAIN_POINT); info.splines_num = curve_component.attribute_domain_size(ATTR_DOMAIN_CURVE); break; } From c07fdad03deb2d86d7c5b43028f5f2f8190ee5da Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 20 Jan 2023 07:59:38 -0600 Subject: [PATCH 0832/1522] Cleanup: Move multires files to C++ For continued refactoring of the Mesh data structure. See T103343. --- source/blender/blenkernel/BKE_multires.h | 4 +- source/blender/blenkernel/CMakeLists.txt | 20 +- ...multires_reshape.c => multires_reshape.cc} | 56 ++- ..._base.c => multires_reshape_apply_base.cc} | 24 +- ..._reshape_ccg.c => multires_reshape_ccg.cc} | 14 +- ...pe_smooth.c => multires_reshape_smooth.cc} | 368 +++++++++--------- ...divide.c => multires_reshape_subdivide.cc} | 7 +- ...eshape_util.c => multires_reshape_util.cc} | 155 ++++---- ..._vertcos.c => multires_reshape_vertcos.cc} | 102 +++-- .../{multires_subdiv.c => multires_subdiv.cc} | 0 ..._unsubdivide.c => multires_unsubdivide.cc} | 117 +++--- ...es_versioning.c => multires_versioning.cc} | 15 +- .../blenkernel/intern/subdiv_converter.h | 8 - 13 files changed, 455 insertions(+), 435 deletions(-) rename source/blender/blenkernel/intern/{multires_reshape.c => multires_reshape.cc} (83%) rename source/blender/blenkernel/intern/{multires_reshape_apply_base.c => multires_reshape_apply_base.cc} (90%) rename source/blender/blenkernel/intern/{multires_reshape_ccg.c => multires_reshape_ccg.cc} (86%) rename source/blender/blenkernel/intern/{multires_reshape_smooth.c => multires_reshape_smooth.cc} (83%) rename source/blender/blenkernel/intern/{multires_reshape_subdivide.c => multires_reshape_subdivide.cc} (91%) rename source/blender/blenkernel/intern/{multires_reshape_util.c => multires_reshape_util.cc} (84%) rename source/blender/blenkernel/intern/{multires_reshape_vertcos.c => multires_reshape_vertcos.cc} (71%) rename source/blender/blenkernel/intern/{multires_subdiv.c => multires_subdiv.cc} (100%) rename source/blender/blenkernel/intern/{multires_unsubdivide.c => multires_unsubdivide.cc} (92%) rename source/blender/blenkernel/intern/{multires_versioning.c => multires_versioning.cc} (81%) diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 7c8c13ac8b2..5faafbe957c 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -156,7 +156,7 @@ void old_mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float int mdisp_rot_face_to_crn( struct MPoly *mpoly, int face_side, float u, float v, float *x, float *y); -/* Reshaping, define in multires_reshape.c */ +/* Reshaping, define in multires_reshape.cc */ bool multiresModifier_reshapeFromVertcos(struct Depsgraph *depsgraph, struct Object *object, @@ -204,7 +204,7 @@ void multiresModifier_subdivide_to_level(struct Object *object, int top_level, eMultiresSubdivideModeType mode); -/* Subdivision integration, defined in multires_subdiv.c */ +/* Subdivision integration, defined in multires_subdiv.cc */ struct SubdivSettings; struct SubdivToMeshSettings; diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 77c16b6924c..bfef13649e3 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -216,16 +216,16 @@ set(SRC intern/modifier.cc intern/movieclip.c intern/multires.cc - intern/multires_reshape.c - intern/multires_reshape_apply_base.c - intern/multires_reshape_ccg.c - intern/multires_reshape_smooth.c - intern/multires_reshape_subdivide.c - intern/multires_reshape_util.c - intern/multires_reshape_vertcos.c - intern/multires_subdiv.c - intern/multires_unsubdivide.c - intern/multires_versioning.c + intern/multires_reshape.cc + intern/multires_reshape_apply_base.cc + intern/multires_reshape_ccg.cc + intern/multires_reshape_smooth.cc + intern/multires_reshape_subdivide.cc + intern/multires_reshape_util.cc + intern/multires_reshape_vertcos.cc + intern/multires_subdiv.cc + intern/multires_unsubdivide.cc + intern/multires_versioning.cc intern/nla.c intern/node.cc intern/node_runtime.cc diff --git a/source/blender/blenkernel/intern/multires_reshape.c b/source/blender/blenkernel/intern/multires_reshape.cc similarity index 83% rename from source/blender/blenkernel/intern/multires_reshape.c rename to source/blender/blenkernel/intern/multires_reshape.cc index 17e4860ab1b..522e7632b94 100644 --- a/source/blender/blenkernel/intern/multires_reshape.c +++ b/source/blender/blenkernel/intern/multires_reshape.cc @@ -30,9 +30,9 @@ /** \name Reshape from object * \{ */ -bool multiresModifier_reshapeFromVertcos(struct Depsgraph *depsgraph, - struct Object *object, - struct MultiresModifierData *mmd, +bool multiresModifier_reshapeFromVertcos(Depsgraph *depsgraph, + Object *object, + MultiresModifierData *mmd, const float (*vert_coords)[3], const int num_vert_coords) { @@ -41,7 +41,7 @@ bool multiresModifier_reshapeFromVertcos(struct Depsgraph *depsgraph, return false; } multires_reshape_store_original_grids(&reshape_context); - multires_reshape_ensure_grids(object->data, reshape_context.top.level); + multires_reshape_ensure_grids(static_cast(object->data), reshape_context.top.level); if (!multires_reshape_assign_final_coords_from_vertcos( &reshape_context, vert_coords, num_vert_coords)) { multires_reshape_context_free(&reshape_context); @@ -53,13 +53,13 @@ bool multiresModifier_reshapeFromVertcos(struct Depsgraph *depsgraph, return true; } -bool multiresModifier_reshapeFromObject(struct Depsgraph *depsgraph, - struct MultiresModifierData *mmd, - struct Object *dst, - struct Object *src) +bool multiresModifier_reshapeFromObject(Depsgraph *depsgraph, + MultiresModifierData *mmd, + Object *dst, + Object *src) { - struct Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); - struct Object *src_eval = DEG_get_evaluated_object(depsgraph, src); + Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); + Object *src_eval = DEG_get_evaluated_object(depsgraph, src); Mesh *src_mesh_eval = mesh_get_eval_final(depsgraph, scene_eval, src_eval, &CD_MASK_BAREMESH); int num_deformed_verts; @@ -79,10 +79,10 @@ bool multiresModifier_reshapeFromObject(struct Depsgraph *depsgraph, /** \name Reshape from modifier * \{ */ -bool multiresModifier_reshapeFromDeformModifier(struct Depsgraph *depsgraph, - struct Object *object, - struct MultiresModifierData *mmd, - struct ModifierData *deform_md) +bool multiresModifier_reshapeFromDeformModifier(Depsgraph *depsgraph, + Object *object, + MultiresModifierData *mmd, + ModifierData *deform_md) { MultiresModifierData highest_mmd = *mmd; highest_mmd.sculptlvl = highest_mmd.totlvl; @@ -96,14 +96,14 @@ bool multiresModifier_reshapeFromDeformModifier(struct Depsgraph *depsgraph, float(*deformed_verts)[3] = BKE_mesh_vert_coords_alloc(multires_mesh, &num_deformed_verts); /* Apply deformation modifier on the multires, */ - const ModifierEvalContext modifier_ctx = { - .depsgraph = depsgraph, - .object = object, - .flag = MOD_APPLY_USECACHE | MOD_APPLY_IGNORE_SIMPLIFY, - }; + ModifierEvalContext modifier_ctx{}; + modifier_ctx.depsgraph = depsgraph; + modifier_ctx.object = object; + modifier_ctx.flag = MOD_APPLY_USECACHE | MOD_APPLY_IGNORE_SIMPLIFY; + BKE_modifier_deform_verts( deform_md, &modifier_ctx, multires_mesh, deformed_verts, multires_mesh->totvert); - BKE_id_free(NULL, multires_mesh); + BKE_id_free(nullptr, multires_mesh); /* Reshaping */ bool result = multiresModifier_reshapeFromVertcos( @@ -121,9 +121,7 @@ bool multiresModifier_reshapeFromDeformModifier(struct Depsgraph *depsgraph, /** \name Reshape from grids * \{ */ -bool multiresModifier_reshapeFromCCG(const int tot_level, - Mesh *coarse_mesh, - struct SubdivCCG *subdiv_ccg) +bool multiresModifier_reshapeFromCCG(const int tot_level, Mesh *coarse_mesh, SubdivCCG *subdiv_ccg) { MultiresReshapeContext reshape_context; if (!multires_reshape_context_create_from_ccg( @@ -159,8 +157,8 @@ void multiresModifier_subdivide(Object *object, multiresModifier_subdivide_to_level(object, mmd, top_level, mode); } -void multiresModifier_subdivide_to_level(struct Object *object, - struct MultiresModifierData *mmd, +void multiresModifier_subdivide_to_level(Object *object, + MultiresModifierData *mmd, const int top_level, const eMultiresSubdivideModeType mode) { @@ -168,7 +166,7 @@ void multiresModifier_subdivide_to_level(struct Object *object, return; } - Mesh *coarse_mesh = object->data; + Mesh *coarse_mesh = static_cast(object->data); if (coarse_mesh->totloop == 0) { /* If there are no loops in the mesh implies there is no CD_MDISPS as well. So can early output * from here as there is nothing to subdivide. */ @@ -182,7 +180,7 @@ void multiresModifier_subdivide_to_level(struct Object *object, const bool has_mdisps = CustomData_has_layer(&coarse_mesh->ldata, CD_MDISPS); if (!has_mdisps) { CustomData_add_layer( - &coarse_mesh->ldata, CD_MDISPS, CD_SET_DEFAULT, NULL, coarse_mesh->totloop); + &coarse_mesh->ldata, CD_MDISPS, CD_SET_DEFAULT, nullptr, coarse_mesh->totloop); } /* NOTE: Subdivision happens from the top level of the existing multires modifier. If it is set @@ -238,9 +236,7 @@ void multiresModifier_subdivide_to_level(struct Object *object, /** \name Apply base * \{ */ -void multiresModifier_base_apply(struct Depsgraph *depsgraph, - Object *object, - MultiresModifierData *mmd) +void multiresModifier_base_apply(Depsgraph *depsgraph, Object *object, MultiresModifierData *mmd) { multires_force_sculpt_rebuild(object); diff --git a/source/blender/blenkernel/intern/multires_reshape_apply_base.c b/source/blender/blenkernel/intern/multires_reshape_apply_base.cc similarity index 90% rename from source/blender/blenkernel/intern/multires_reshape_apply_base.c rename to source/blender/blenkernel/intern/multires_reshape_apply_base.cc index 0da5d814992..d491f30a1ad 100644 --- a/source/blender/blenkernel/intern/multires_reshape_apply_base.c +++ b/source/blender/blenkernel/intern/multires_reshape_apply_base.cc @@ -81,8 +81,8 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape base_mesh->totpoly, base_mesh->totloop); - float(*origco)[3] = MEM_calloc_arrayN( - base_mesh->totvert, sizeof(float[3]), "multires apply base origco"); + float(*origco)[3] = static_cast( + MEM_calloc_arrayN(base_mesh->totvert, sizeof(float[3]), __func__)); for (int i = 0; i < base_mesh->totvert; i++) { copy_v3_v3(origco[i], base_positions[i]); } @@ -115,15 +115,15 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape for (int j = 0; j < pmap[i].count; j++) { const MPoly *p = &reshape_context->base_polys[pmap[i].indices[j]]; MPoly fake_poly; - MLoop *fake_loops; - float(*fake_co)[3]; float no[3]; /* Set up poly, loops, and coords in order to call BKE_mesh_calc_poly_normal(). */ fake_poly.totloop = p->totloop; fake_poly.loopstart = 0; - fake_loops = MEM_malloc_arrayN(p->totloop, sizeof(MLoop), "fake_loops"); - fake_co = MEM_malloc_arrayN(p->totloop, sizeof(float[3]), "fake_co"); + MLoop *fake_loops = static_cast( + MEM_malloc_arrayN(p->totloop, sizeof(MLoop), __func__)); + float(*fake_co)[3] = static_cast( + MEM_malloc_arrayN(p->totloop, sizeof(float[3]), __func__)); for (int k = 0; k < p->totloop; k++) { const int vndx = reshape_context->base_loops[p->loopstart + k].v; @@ -165,20 +165,20 @@ void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape void multires_reshape_apply_base_refine_from_base(MultiresReshapeContext *reshape_context) { - BKE_subdiv_eval_refine_from_mesh(reshape_context->subdiv, reshape_context->base_mesh, NULL); + BKE_subdiv_eval_refine_from_mesh(reshape_context->subdiv, reshape_context->base_mesh, nullptr); } void multires_reshape_apply_base_refine_from_deform(MultiresReshapeContext *reshape_context) { - struct Depsgraph *depsgraph = reshape_context->depsgraph; + Depsgraph *depsgraph = reshape_context->depsgraph; Object *object = reshape_context->object; MultiresModifierData *mmd = reshape_context->mmd; - BLI_assert(depsgraph != NULL); - BLI_assert(object != NULL); - BLI_assert(mmd != NULL); + BLI_assert(depsgraph != nullptr); + BLI_assert(object != nullptr); + BLI_assert(mmd != nullptr); float(*deformed_verts)[3] = BKE_multires_create_deformed_base_mesh_vert_coords( - depsgraph, object, mmd, NULL); + depsgraph, object, mmd, nullptr); BKE_subdiv_eval_refine_from_mesh( reshape_context->subdiv, reshape_context->base_mesh, deformed_verts); diff --git a/source/blender/blenkernel/intern/multires_reshape_ccg.c b/source/blender/blenkernel/intern/multires_reshape_ccg.cc similarity index 86% rename from source/blender/blenkernel/intern/multires_reshape_ccg.c rename to source/blender/blenkernel/intern/multires_reshape_ccg.cc index 6001aa715d5..d9723b7e684 100644 --- a/source/blender/blenkernel/intern/multires_reshape_ccg.c +++ b/source/blender/blenkernel/intern/multires_reshape_ccg.cc @@ -7,7 +7,7 @@ #include "multires_reshape.h" -#include +#include #include "BLI_utildefines.h" @@ -15,21 +15,21 @@ #include "BKE_subdiv_ccg.h" bool multires_reshape_assign_final_coords_from_ccg(const MultiresReshapeContext *reshape_context, - struct SubdivCCG *subdiv_ccg) + SubdivCCG *subdiv_ccg) { CCGKey reshape_level_key; BKE_subdiv_ccg_key(&reshape_level_key, subdiv_ccg, reshape_context->reshape.level); const int reshape_grid_size = reshape_context->reshape.grid_size; - const float reshape_grid_size_1_inv = 1.0f / (((float)reshape_grid_size) - 1.0f); + const float reshape_grid_size_1_inv = 1.0f / ((float(reshape_grid_size)) - 1.0f); int num_grids = subdiv_ccg->num_grids; for (int grid_index = 0; grid_index < num_grids; ++grid_index) { CCGElem *ccg_grid = subdiv_ccg->grids[grid_index]; for (int y = 0; y < reshape_grid_size; ++y) { - const float v = (float)y * reshape_grid_size_1_inv; + const float v = float(y) * reshape_grid_size_1_inv; for (int x = 0; x < reshape_grid_size; ++x) { - const float u = (float)x * reshape_grid_size_1_inv; + const float u = float(x) * reshape_grid_size_1_inv; GridCoord grid_coord; grid_coord.grid_index = grid_index; @@ -39,7 +39,7 @@ bool multires_reshape_assign_final_coords_from_ccg(const MultiresReshapeContext ReshapeGridElement grid_element = multires_reshape_grid_element_for_grid_coord( reshape_context, &grid_coord); - BLI_assert(grid_element.displacement != NULL); + BLI_assert(grid_element.displacement != nullptr); memcpy(grid_element.displacement, CCG_grid_elem_co(&reshape_level_key, ccg_grid, x, y), sizeof(float[3])); @@ -66,7 +66,7 @@ bool multires_reshape_assign_final_coords_from_ccg(const MultiresReshapeContext /* NOTE: There is a known bug in Undo code that results in first Sculpt step * after a Memfile one to never be undone (see T83806). This might be the root cause of * this inconsistency. */ - if (reshape_level_key.has_mask && grid_element.mask != NULL) { + if (reshape_level_key.has_mask && grid_element.mask != nullptr) { *grid_element.mask = *CCG_grid_elem_mask(&reshape_level_key, ccg_grid, x, y); } } diff --git a/source/blender/blenkernel/intern/multires_reshape_smooth.c b/source/blender/blenkernel/intern/multires_reshape_smooth.cc similarity index 83% rename from source/blender/blenkernel/intern/multires_reshape_smooth.c rename to source/blender/blenkernel/intern/multires_reshape_smooth.cc index 1463404069f..a248251946a 100644 --- a/source/blender/blenkernel/intern/multires_reshape_smooth.c +++ b/source/blender/blenkernel/intern/multires_reshape_smooth.cc @@ -41,19 +41,19 @@ * Used to store pre-calculated information which is expensive or impossible to evaluate when * traversing the final limit surface. */ -typedef struct SurfacePoint { +struct SurfacePoint { float P[3]; float tangent_matrix[3][3]; -} SurfacePoint; +}; -typedef struct SurfaceGrid { +struct SurfaceGrid { SurfacePoint *points; -} SurfaceGrid; +}; /* Geometry elements which are used to simplify creation of topology refiner at the sculpt level. * Contains a limited subset of information needed to construct topology refiner. */ -typedef struct Vertex { +struct Vertex { /* All grid coordinates which the vertex corresponding to. * For a vertices which are created from inner points of grids there is always one coordinate. */ int num_grid_coords; @@ -61,36 +61,36 @@ typedef struct Vertex { float sharpness; bool is_infinite_sharp; -} Vertex; +}; -typedef struct Corner { +struct Corner { const Vertex *vertex; int grid_index; -} Corner; +}; -typedef struct Face { +struct Face { int start_corner_index; int num_corners; -} Face; +}; -typedef struct Edge { +struct Edge { int v1; int v2; float sharpness; -} Edge; +}; /* Storage of data which is linearly interpolated from the reshape level to the top level. */ -typedef struct LinearGridElement { +struct LinearGridElement { float mask; -} LinearGridElement; +}; -typedef struct LinearGrid { +struct LinearGrid { LinearGridElement *elements; -} LinearGrid; +}; -typedef struct LinearGrids { +struct LinearGrids { int num_grids; int level; @@ -102,11 +102,11 @@ typedef struct LinearGrids { /* Elements for all grids are allocated in a single array, for the allocation performance. */ LinearGridElement *elements_storage; -} LinearGrids; +}; /* Context which holds all information eeded during propagation and smoothing. */ -typedef struct MultiresReshapeSmoothContext { +struct MultiresReshapeSmoothContext { const MultiresReshapeContext *reshape_context; /* Geometry at a reshape multires level. */ @@ -158,7 +158,7 @@ typedef struct MultiresReshapeSmoothContext { * NOTE: Uses same enumerator type as Subdivide operator, since the values are the same and * decoupling type just adds extra headache to convert one enumerator to another. */ eMultiresSubdivideModeType smoothing_type; -} MultiresReshapeSmoothContext; +}; /** \} */ @@ -171,8 +171,8 @@ static void linear_grids_init(LinearGrids *linear_grids) linear_grids->num_grids = 0; linear_grids->level = 0; - linear_grids->grids = NULL; - linear_grids->elements_storage = NULL; + linear_grids->grids = nullptr; + linear_grids->elements_storage = nullptr; } static void linear_grids_allocate(LinearGrids *linear_grids, int num_grids, int level) @@ -185,9 +185,10 @@ static void linear_grids_allocate(LinearGrids *linear_grids, int num_grids, int linear_grids->level = level; linear_grids->grid_size = grid_size; - linear_grids->grids = MEM_malloc_arrayN(num_grids, sizeof(LinearGrid), "linear grids"); - linear_grids->elements_storage = MEM_calloc_arrayN( - num_grid_elements, sizeof(LinearGridElement), "linear elements storage"); + linear_grids->grids = static_cast( + MEM_malloc_arrayN(num_grids, sizeof(LinearGrid), __func__)); + linear_grids->elements_storage = static_cast( + MEM_calloc_arrayN(num_grid_elements, sizeof(LinearGridElement), __func__)); for (int i = 0; i < num_grids; ++i) { const size_t element_offset = grid_area * i; @@ -252,11 +253,12 @@ static void base_surface_grids_allocate(MultiresReshapeSmoothContext *reshape_sm const int grid_size = reshape_context->top.grid_size; const int grid_area = grid_size * grid_size; - SurfaceGrid *surface_grid = MEM_malloc_arrayN(num_grids, sizeof(SurfaceGrid), "delta grids"); + SurfaceGrid *surface_grid = static_cast( + MEM_malloc_arrayN(num_grids, sizeof(SurfaceGrid), __func__)); for (int grid_index = 0; grid_index < num_grids; ++grid_index) { - surface_grid[grid_index].points = MEM_calloc_arrayN( - grid_area, sizeof(SurfacePoint), "delta grid displacement"); + surface_grid[grid_index].points = static_cast( + MEM_calloc_arrayN(grid_area, sizeof(SurfacePoint), __func__)); } reshape_smooth_context->base_surface_grids = surface_grid; @@ -264,7 +266,7 @@ static void base_surface_grids_allocate(MultiresReshapeSmoothContext *reshape_sm static void base_surface_grids_free(MultiresReshapeSmoothContext *reshape_smooth_context) { - if (reshape_smooth_context->base_surface_grids == NULL) { + if (reshape_smooth_context->base_surface_grids == nullptr) { return; } @@ -308,13 +310,13 @@ static void base_surface_grids_write(const MultiresReshapeSmoothContext *reshape /** \name Evaluation of subdivision surface at a reshape level * \{ */ -typedef void (*ForeachTopLevelGridCoordCallback)( - const MultiresReshapeSmoothContext *reshape_smooth_context, - const PTexCoord *ptex_coord, - const GridCoord *grid_coord, - void *userdata_v); +using ForeachTopLevelGridCoordCallback = + void (*)(const MultiresReshapeSmoothContext *reshape_smooth_context, + const PTexCoord *ptex_coord, + const GridCoord *grid_coord, + void *userdata_v); -typedef struct ForeachTopLevelGridCoordTaskData { +struct ForeachHighLevelCoordTaskData { const MultiresReshapeSmoothContext *reshape_smooth_context; int inner_grid_size; @@ -322,7 +324,7 @@ typedef struct ForeachTopLevelGridCoordTaskData { ForeachTopLevelGridCoordCallback callback; void *callback_userdata_v; -} ForeachHighLevelCoordTaskData; +}; /* Find grid index which given face was created for. */ static int get_face_grid_index(const MultiresReshapeSmoothContext *reshape_smooth_context, @@ -349,7 +351,7 @@ static GridCoord *vertex_grid_coord_with_grid_index(const Vertex *vertex, const return &vertex->grid_coords[i]; } } - return NULL; + return nullptr; } /* Get grid coordinates which correspond to corners of the given face. @@ -367,7 +369,7 @@ static void grid_coords_from_face_verts(const MultiresReshapeSmoothContext *resh const int corner_index = face->start_corner_index + i; const Corner *corner = &reshape_smooth_context->geometry.corners[corner_index]; grid_coords[i] = vertex_grid_coord_with_grid_index(corner->vertex, grid_index); - BLI_assert(grid_coords[i] != NULL); + BLI_assert(grid_coords[i] != nullptr); } } @@ -406,9 +408,9 @@ static void interpolate_grid_coord(GridCoord *result, static void foreach_toplevel_grid_coord_task(void *__restrict userdata_v, const int face_index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - ForeachHighLevelCoordTaskData *data = userdata_v; + ForeachHighLevelCoordTaskData *data = static_cast(userdata_v); const MultiresReshapeSmoothContext *reshape_smooth_context = data->reshape_smooth_context; const int inner_grid_size = data->inner_grid_size; @@ -419,9 +421,9 @@ static void foreach_toplevel_grid_coord_task(void *__restrict userdata_v, grid_coords_from_face_verts(reshape_smooth_context, face, face_grid_coords); for (int y = 0; y < inner_grid_size; ++y) { - const float ptex_v = (float)y * inner_grid_size_1_inv; + const float ptex_v = float(y) * inner_grid_size_1_inv; for (int x = 0; x < inner_grid_size; ++x) { - const float ptex_u = (float)x * inner_grid_size_1_inv; + const float ptex_u = float(x) * inner_grid_size_1_inv; PTexCoord ptex_coord; ptex_coord.ptex_face_index = face_index; @@ -446,7 +448,7 @@ static void foreach_toplevel_grid_coord(const MultiresReshapeSmoothContext *resh ForeachHighLevelCoordTaskData data; data.reshape_smooth_context = reshape_smooth_context; data.inner_grid_size = (1 << level_difference) + 1; - data.inner_grid_size_1_inv = 1.0f / (float)(data.inner_grid_size - 1); + data.inner_grid_size_1_inv = 1.0f / float(data.inner_grid_size - 1); data.callback = callback; data.callback_userdata_v = callback_userdata_v; @@ -508,30 +510,30 @@ static void context_init(MultiresReshapeSmoothContext *reshape_smooth_context, reshape_smooth_context->reshape_context = reshape_context; reshape_smooth_context->geometry.num_vertices = 0; - reshape_smooth_context->geometry.vertices = NULL; + reshape_smooth_context->geometry.vertices = nullptr; reshape_smooth_context->geometry.max_edges = 0; reshape_smooth_context->geometry.num_edges = 0; - reshape_smooth_context->geometry.edges = NULL; + reshape_smooth_context->geometry.edges = nullptr; reshape_smooth_context->geometry.num_corners = 0; - reshape_smooth_context->geometry.corners = NULL; + reshape_smooth_context->geometry.corners = nullptr; reshape_smooth_context->geometry.num_faces = 0; - reshape_smooth_context->geometry.faces = NULL; + reshape_smooth_context->geometry.faces = nullptr; linear_grids_init(&reshape_smooth_context->linear_delta_grids); - reshape_smooth_context->non_loose_base_edge_map = NULL; - reshape_smooth_context->reshape_subdiv = NULL; - reshape_smooth_context->base_surface_grids = NULL; + reshape_smooth_context->non_loose_base_edge_map = nullptr; + reshape_smooth_context->reshape_subdiv = nullptr; + reshape_smooth_context->base_surface_grids = nullptr; reshape_smooth_context->smoothing_type = mode; } static void context_free_geometry(MultiresReshapeSmoothContext *reshape_smooth_context) { - if (reshape_smooth_context->geometry.vertices != NULL) { + if (reshape_smooth_context->geometry.vertices != nullptr) { for (int i = 0; i < reshape_smooth_context->geometry.num_vertices; ++i) { MEM_SAFE_FREE(reshape_smooth_context->geometry.vertices[i].grid_coords); } @@ -546,7 +548,7 @@ static void context_free_geometry(MultiresReshapeSmoothContext *reshape_smooth_c static void context_free_subdiv(MultiresReshapeSmoothContext *reshape_smooth_context) { - if (reshape_smooth_context->reshape_subdiv == NULL) { + if (reshape_smooth_context->reshape_subdiv == nullptr) { return; } BKE_subdiv_free(reshape_smooth_context->reshape_subdiv); @@ -566,29 +568,30 @@ static bool foreach_topology_info(const SubdivForeachContext *foreach_context, const int num_edges, const int num_loops, const int num_polygons, - const int *UNUSED(subdiv_polygon_offset)) + const int * /*subdiv_polygon_offset*/) { - MultiresReshapeSmoothContext *reshape_smooth_context = foreach_context->user_data; + MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(foreach_context->user_data); const int max_edges = reshape_smooth_context->smoothing_type == MULTIRES_SUBDIVIDE_LINEAR ? num_edges : reshape_smooth_context->geometry.max_edges; /* NOTE: Calloc so the counters are re-set to 0 "for free". */ reshape_smooth_context->geometry.num_vertices = num_vertices; - reshape_smooth_context->geometry.vertices = MEM_calloc_arrayN( - num_vertices, sizeof(Vertex), "smooth vertices"); + reshape_smooth_context->geometry.vertices = static_cast( + MEM_calloc_arrayN(num_vertices, sizeof(Vertex), "smooth vertices")); reshape_smooth_context->geometry.max_edges = max_edges; - reshape_smooth_context->geometry.edges = MEM_malloc_arrayN( - max_edges, sizeof(Edge), "smooth edges"); + reshape_smooth_context->geometry.edges = static_cast( + MEM_malloc_arrayN(max_edges, sizeof(Edge), "smooth edges")); reshape_smooth_context->geometry.num_corners = num_loops; - reshape_smooth_context->geometry.corners = MEM_malloc_arrayN( - num_loops, sizeof(Corner), "smooth corners"); + reshape_smooth_context->geometry.corners = static_cast( + MEM_malloc_arrayN(num_loops, sizeof(Corner), "smooth corners")); reshape_smooth_context->geometry.num_faces = num_polygons; - reshape_smooth_context->geometry.faces = MEM_malloc_arrayN( - num_polygons, sizeof(Face), "smooth faces"); + reshape_smooth_context->geometry.faces = static_cast( + MEM_malloc_arrayN(num_polygons, sizeof(Face), "smooth faces")); return true; } @@ -598,14 +601,15 @@ static void foreach_single_vertex(const SubdivForeachContext *foreach_context, const int coarse_vertex_index, const int subdiv_vertex_index) { - const MultiresReshapeSmoothContext *reshape_smooth_context = foreach_context->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(foreach_context->user_data); BLI_assert(subdiv_vertex_index < reshape_smooth_context->geometry.num_vertices); Vertex *vertex = &reshape_smooth_context->geometry.vertices[subdiv_vertex_index]; - vertex->grid_coords = MEM_reallocN(vertex->grid_coords, - sizeof(Vertex) * (vertex->num_grid_coords + 1)); + vertex->grid_coords = static_cast( + MEM_reallocN(vertex->grid_coords, sizeof(Vertex) * (vertex->num_grid_coords + 1))); vertex->grid_coords[vertex->num_grid_coords] = *grid_coord; ++vertex->num_grid_coords; @@ -616,7 +620,7 @@ static void foreach_single_vertex(const SubdivForeachContext *foreach_context, const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context; const float *cd_vertex_crease = reshape_context->cd_vertex_crease; - if (cd_vertex_crease == NULL) { + if (cd_vertex_crease == nullptr) { return; } @@ -630,13 +634,14 @@ static void foreach_single_vertex(const SubdivForeachContext *foreach_context, vertex->sharpness = BKE_subdiv_crease_to_sharpness_f(crease); } -/* TODO(sergey): De-duplicate with similar function in multires_reshape_vertcos.c */ +/* TODO(sergey): De-duplicate with similar function in multires_reshape_vertcos.cc */ static void foreach_vertex(const SubdivForeachContext *foreach_context, const PTexCoord *ptex_coord, const int coarse_vertex_index, const int subdiv_vertex_index) { - const MultiresReshapeSmoothContext *reshape_smooth_context = foreach_context->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(foreach_context->user_data); const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context; const GridCoord grid_coord = multires_reshape_ptex_coord_to_grid(reshape_context, ptex_coord); @@ -681,72 +686,70 @@ static void foreach_vertex(const SubdivForeachContext *foreach_context, } } -static void foreach_vertex_inner(const struct SubdivForeachContext *foreach_context, - void *UNUSED(tls), +static void foreach_vertex_inner(const SubdivForeachContext *foreach_context, + void * /*tls*/, const int ptex_face_index, const float ptex_face_u, const float ptex_face_v, - const int UNUSED(coarse_poly_index), - const int UNUSED(coarse_corner), + const int /*coarse_poly_index*/, + const int /*coarse_corner*/, const int subdiv_vertex_index) { - const PTexCoord ptex_coord = { - .ptex_face_index = ptex_face_index, - .u = ptex_face_u, - .v = ptex_face_v, - }; + PTexCoord ptex_coord{}; + ptex_coord.ptex_face_index = ptex_face_index; + ptex_coord.u = ptex_face_u; + ptex_coord.v = ptex_face_v; foreach_vertex(foreach_context, &ptex_coord, -1, subdiv_vertex_index); } -static void foreach_vertex_every_corner(const struct SubdivForeachContext *foreach_context, - void *UNUSED(tls_v), +static void foreach_vertex_every_corner(const SubdivForeachContext *foreach_context, + void * /*tls_v*/, const int ptex_face_index, const float ptex_face_u, const float ptex_face_v, const int coarse_vertex_index, - const int UNUSED(coarse_face_index), - const int UNUSED(coarse_face_corner), + const int /*coarse_face_index*/, + const int /*coarse_face_corner*/, const int subdiv_vertex_index) { - const PTexCoord ptex_coord = { - .ptex_face_index = ptex_face_index, - .u = ptex_face_u, - .v = ptex_face_v, - }; + PTexCoord ptex_coord{}; + ptex_coord.ptex_face_index = ptex_face_index; + ptex_coord.u = ptex_face_u; + ptex_coord.v = ptex_face_v; foreach_vertex(foreach_context, &ptex_coord, coarse_vertex_index, subdiv_vertex_index); } -static void foreach_vertex_every_edge(const struct SubdivForeachContext *foreach_context, - void *UNUSED(tls_v), +static void foreach_vertex_every_edge(const SubdivForeachContext *foreach_context, + void * /*tls_v*/, const int ptex_face_index, const float ptex_face_u, const float ptex_face_v, - const int UNUSED(coarse_edge_index), - const int UNUSED(coarse_face_index), - const int UNUSED(coarse_face_corner), + const int /*coarse_edge_index*/, + const int /*coarse_face_index*/, + const int /*coarse_face_corner*/, const int subdiv_vertex_index) { - const PTexCoord ptex_coord = { - .ptex_face_index = ptex_face_index, - .u = ptex_face_u, - .v = ptex_face_v, - }; + PTexCoord ptex_coord{}; + ptex_coord.ptex_face_index = ptex_face_index; + ptex_coord.u = ptex_face_u; + ptex_coord.v = ptex_face_v; foreach_vertex(foreach_context, &ptex_coord, -1, subdiv_vertex_index); } -static void foreach_loop(const struct SubdivForeachContext *foreach_context, - void *UNUSED(tls), - const int UNUSED(ptex_face_index), - const float UNUSED(ptex_face_u), - const float UNUSED(ptex_face_v), - const int UNUSED(coarse_loop_index), +static void foreach_loop(const SubdivForeachContext *foreach_context, + void * /*tls*/, + const int /*ptex_face_index*/, + const float /*ptex_face_u*/, + const float /*ptex_face_v*/, + const int /*coarse_loop_index*/, const int coarse_poly_index, const int coarse_corner, const int subdiv_loop_index, const int subdiv_vertex_index, - const int UNUSED(subdiv_edge_index)) + const int /*subdiv_edge_index*/) { - MultiresReshapeSmoothContext *reshape_smooth_context = foreach_context->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(foreach_context->user_data); const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context; BLI_assert(subdiv_loop_index < reshape_smooth_context->geometry.num_corners); @@ -759,13 +762,14 @@ static void foreach_loop(const struct SubdivForeachContext *foreach_context, } static void foreach_poly(const SubdivForeachContext *foreach_context, - void *UNUSED(tls), - const int UNUSED(coarse_poly_index), + void * /*tls*/, + const int /*coarse_poly_index*/, const int subdiv_poly_index, const int start_loop_index, const int num_loops) { - MultiresReshapeSmoothContext *reshape_smooth_context = foreach_context->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(foreach_context->user_data); BLI_assert(subdiv_poly_index < reshape_smooth_context->geometry.num_faces); @@ -774,13 +778,14 @@ static void foreach_poly(const SubdivForeachContext *foreach_context, face->num_corners = num_loops; } -static void foreach_vertex_of_loose_edge(const struct SubdivForeachContext *foreach_context, - void *UNUSED(tls), - const int UNUSED(coarse_edge_index), - const float UNUSED(u), +static void foreach_vertex_of_loose_edge(const SubdivForeachContext *foreach_context, + void * /*tls*/, + const int /*coarse_edge_index*/, + const float /*u*/, const int vertex_index) { - const MultiresReshapeSmoothContext *reshape_smooth_context = foreach_context->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(foreach_context->user_data); Vertex *vertex = &reshape_smooth_context->geometry.vertices[vertex_index]; if (vertex->num_grid_coords != 0) { @@ -804,19 +809,20 @@ static void store_edge(MultiresReshapeSmoothContext *reshape_smooth_context, edge->sharpness = BKE_subdiv_crease_to_sharpness_char(crease); } -static void foreach_edge(const struct SubdivForeachContext *foreach_context, - void *UNUSED(tls), +static void foreach_edge(const SubdivForeachContext *foreach_context, + void * /*tls*/, const int coarse_edge_index, - const int UNUSED(subdiv_edge_index), + const int /*subdiv_edge_index*/, const bool is_loose, const int subdiv_v1, const int subdiv_v2) { - MultiresReshapeSmoothContext *reshape_smooth_context = foreach_context->user_data; + MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(foreach_context->user_data); if (reshape_smooth_context->smoothing_type == MULTIRES_SUBDIVIDE_LINEAR) { if (!is_loose) { - store_edge(reshape_smooth_context, subdiv_v1, subdiv_v2, (char)255); + store_edge(reshape_smooth_context, subdiv_v1, subdiv_v2, char(255)); } return; } @@ -875,17 +881,16 @@ static void geometry_create(MultiresReshapeSmoothContext *reshape_smooth_context { const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context; - SubdivForeachContext foreach_context = { - .topology_info = foreach_topology_info, - .vertex_inner = foreach_vertex_inner, - .vertex_every_corner = foreach_vertex_every_corner, - .vertex_every_edge = foreach_vertex_every_edge, - .loop = foreach_loop, - .poly = foreach_poly, - .vertex_of_loose_edge = foreach_vertex_of_loose_edge, - .edge = foreach_edge, - .user_data = reshape_smooth_context, - }; + SubdivForeachContext foreach_context{}; + foreach_context.topology_info = foreach_topology_info; + foreach_context.vertex_inner = foreach_vertex_inner; + foreach_context.vertex_every_corner = foreach_vertex_every_corner; + foreach_context.vertex_every_edge = foreach_vertex_every_edge; + foreach_context.loop = foreach_loop; + foreach_context.poly = foreach_poly; + foreach_context.vertex_of_loose_edge = foreach_vertex_of_loose_edge; + foreach_context.edge = foreach_edge; + foreach_context.user_data = reshape_smooth_context; geometry_init_loose_information(reshape_smooth_context); @@ -904,53 +909,60 @@ static void geometry_create(MultiresReshapeSmoothContext *reshape_smooth_context /** \name Generation of OpenSubdiv evaluator for topology created form reshape level * \{ */ -static OpenSubdiv_SchemeType get_scheme_type(const OpenSubdiv_Converter *UNUSED(converter)) +static OpenSubdiv_SchemeType get_scheme_type(const OpenSubdiv_Converter * /*converter*/) { return OSD_SCHEME_CATMARK; } static OpenSubdiv_VtxBoundaryInterpolation get_vtx_boundary_interpolation( - const struct OpenSubdiv_Converter *converter) + const OpenSubdiv_Converter *converter) { - const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(converter->user_data); const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context; const SubdivSettings *settings = &reshape_context->subdiv->settings; - return BKE_subdiv_converter_vtx_boundary_interpolation_from_settings(settings); + return OpenSubdiv_VtxBoundaryInterpolation( + BKE_subdiv_converter_vtx_boundary_interpolation_from_settings(settings)); } static OpenSubdiv_FVarLinearInterpolation get_fvar_linear_interpolation( const OpenSubdiv_Converter *converter) { - const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(converter->user_data); const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context; const SubdivSettings *settings = &reshape_context->subdiv->settings; - return BKE_subdiv_converter_fvar_linear_from_settings(settings); + return OpenSubdiv_FVarLinearInterpolation( + BKE_subdiv_converter_fvar_linear_from_settings(settings)); } -static bool specifies_full_topology(const OpenSubdiv_Converter *UNUSED(converter)) +static bool specifies_full_topology(const OpenSubdiv_Converter * /*converter*/) { return false; } static int get_num_faces(const OpenSubdiv_Converter *converter) { - const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(converter->user_data); return reshape_smooth_context->geometry.num_faces; } static int get_num_vertices(const OpenSubdiv_Converter *converter) { - const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(converter->user_data); return reshape_smooth_context->geometry.num_vertices; } static int get_num_face_vertices(const OpenSubdiv_Converter *converter, int face_index) { - const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(converter->user_data); BLI_assert(face_index < reshape_smooth_context->geometry.num_faces); const Face *face = &reshape_smooth_context->geometry.faces[face_index]; @@ -961,7 +973,8 @@ static void get_face_vertices(const OpenSubdiv_Converter *converter, int face_index, int *face_vertices) { - const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(converter->user_data); BLI_assert(face_index < reshape_smooth_context->geometry.num_faces); const Face *face = &reshape_smooth_context->geometry.faces[face_index]; @@ -973,9 +986,10 @@ static void get_face_vertices(const OpenSubdiv_Converter *converter, } } -static int get_num_edges(const struct OpenSubdiv_Converter *converter) +static int get_num_edges(const OpenSubdiv_Converter *converter) { - const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(converter->user_data); return reshape_smooth_context->geometry.num_edges; } @@ -983,7 +997,8 @@ static void get_edge_vertices(const OpenSubdiv_Converter *converter, const int edge_index, int edge_vertices[2]) { - const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(converter->user_data); BLI_assert(edge_index < reshape_smooth_context->geometry.num_edges); const Edge *edge = &reshape_smooth_context->geometry.edges[edge_index]; @@ -993,7 +1008,8 @@ static void get_edge_vertices(const OpenSubdiv_Converter *converter, static float get_edge_sharpness(const OpenSubdiv_Converter *converter, const int edge_index) { - const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(converter->user_data); BLI_assert(edge_index < reshape_smooth_context->geometry.num_edges); const Edge *edge = &reshape_smooth_context->geometry.edges[edge_index]; @@ -1002,7 +1018,8 @@ static float get_edge_sharpness(const OpenSubdiv_Converter *converter, const int static float get_vertex_sharpness(const OpenSubdiv_Converter *converter, const int vertex_index) { - const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(converter->user_data); BLI_assert(vertex_index < reshape_smooth_context->geometry.num_vertices); const Vertex *vertex = &reshape_smooth_context->geometry.vertices[vertex_index]; @@ -1011,7 +1028,8 @@ static float get_vertex_sharpness(const OpenSubdiv_Converter *converter, const i static bool is_infinite_sharp_vertex(const OpenSubdiv_Converter *converter, int vertex_index) { - const MultiresReshapeSmoothContext *reshape_smooth_context = converter->user_data; + const MultiresReshapeSmoothContext *reshape_smooth_context = + static_cast(converter->user_data); BLI_assert(vertex_index < reshape_smooth_context->geometry.num_vertices); @@ -1033,27 +1051,27 @@ static void converter_init(const MultiresReshapeSmoothContext *reshape_smooth_co converter->getNumFaceVertices = get_num_face_vertices; converter->getFaceVertices = get_face_vertices; - converter->getFaceEdges = NULL; + converter->getFaceEdges = nullptr; converter->getEdgeVertices = get_edge_vertices; - converter->getNumEdgeFaces = NULL; - converter->getEdgeFaces = NULL; + converter->getNumEdgeFaces = nullptr; + converter->getEdgeFaces = nullptr; converter->getEdgeSharpness = get_edge_sharpness; - converter->getNumVertexEdges = NULL; - converter->getVertexEdges = NULL; - converter->getNumVertexFaces = NULL; - converter->getVertexFaces = NULL; + converter->getNumVertexEdges = nullptr; + converter->getVertexEdges = nullptr; + converter->getNumVertexFaces = nullptr; + converter->getVertexFaces = nullptr; converter->isInfiniteSharpVertex = is_infinite_sharp_vertex; converter->getVertexSharpness = get_vertex_sharpness; - converter->getNumUVLayers = NULL; - converter->precalcUVLayer = NULL; - converter->finishUVLayer = NULL; - converter->getNumUVCoordinates = NULL; - converter->getFaceCornerUVIndex = NULL; + converter->getNumUVLayers = nullptr; + converter->precalcUVLayer = nullptr; + converter->finishUVLayer = nullptr; + converter->getNumUVCoordinates = nullptr; + converter->getFaceCornerUVIndex = nullptr; - converter->freeUserData = NULL; + converter->freeUserData = nullptr; converter->user_data = (void *)reshape_smooth_context; } @@ -1070,7 +1088,7 @@ static void reshape_subdiv_create(MultiresReshapeSmoothContext *reshape_smooth_c Subdiv *reshape_subdiv = BKE_subdiv_new_from_converter(settings, &converter); OpenSubdiv_EvaluatorSettings evaluator_settings = {0}; - BKE_subdiv_eval_begin(reshape_subdiv, SUBDIV_EVALUATOR_TYPE_CPU, NULL, &evaluator_settings); + BKE_subdiv_eval_begin(reshape_subdiv, SUBDIV_EVALUATOR_TYPE_CPU, nullptr, &evaluator_settings); reshape_smooth_context->reshape_subdiv = reshape_subdiv; @@ -1107,7 +1125,7 @@ BLI_INLINE const GridCoord *reshape_subdiv_refine_vertex_grid_coord(const Vertex /* This is a loose vertex, the coordinate is not important. */ /* TODO(sergey): Once the subdiv_foreach() supports properly ignoring loose elements this * should become an assert instead. */ - return NULL; + return nullptr; } /* NOTE: All grid coordinates will point to the same object position, so can be simple and use * first grid coordinate. */ @@ -1122,7 +1140,7 @@ static void reshape_subdiv_refine_orig_P( const GridCoord *grid_coord = reshape_subdiv_refine_vertex_grid_coord(vertex); /* Check whether this is a loose vertex. */ - if (grid_coord == NULL) { + if (grid_coord == nullptr) { zero_v3(r_P); return; } @@ -1152,7 +1170,7 @@ static void reshape_subdiv_refine_final_P( const GridCoord *grid_coord = reshape_subdiv_refine_vertex_grid_coord(vertex); /* Check whether this is a loose vertex. */ - if (grid_coord == NULL) { + if (grid_coord == nullptr) { zero_v3(r_P); return; } @@ -1225,7 +1243,7 @@ static LinearGridElement linear_grid_element_final_get( LinearGridElement linear_grid_element; linear_grid_element_init(&linear_grid_element); - if (final_grid_element.mask != NULL) { + if (final_grid_element.mask != nullptr) { linear_grid_element.mask = *final_grid_element.mask; } @@ -1247,7 +1265,7 @@ static void linear_grid_element_delta_interpolate( const int reshape_level = reshape_context->reshape.level; const int reshape_level_grid_size = BKE_subdiv_grid_size_from_level(reshape_level); const int reshape_level_grid_size_1 = reshape_level_grid_size - 1; - const float reshape_level_grid_size_1_inv = 1.0f / (float)(reshape_level_grid_size_1); + const float reshape_level_grid_size_1_inv = 1.0f / float(reshape_level_grid_size_1); const float x_f = grid_coord->u * reshape_level_grid_size_1; const float y_f = grid_coord->v * reshape_level_grid_size_1; @@ -1282,9 +1300,9 @@ static void linear_grid_element_delta_interpolate( static void evaluate_linear_delta_grids_callback( const MultiresReshapeSmoothContext *reshape_smooth_context, - const PTexCoord *UNUSED(ptex_coord), + const PTexCoord * /*ptex_coord*/, const GridCoord *grid_coord, - void *UNUSED(userdata_v)) + void * /*userdata_v*/) { LinearGridElement *linear_delta_element = linear_grid_element_get( &reshape_smooth_context->linear_delta_grids, grid_coord); @@ -1300,7 +1318,8 @@ static void evaluate_linear_delta_grids(MultiresReshapeSmoothContext *reshape_sm linear_grids_allocate(&reshape_smooth_context->linear_delta_grids, num_grids, top_level); - foreach_toplevel_grid_coord(reshape_smooth_context, evaluate_linear_delta_grids_callback, NULL); + foreach_toplevel_grid_coord( + reshape_smooth_context, evaluate_linear_delta_grids_callback, nullptr); } static void propagate_linear_data_delta(const MultiresReshapeSmoothContext *reshape_smooth_context, @@ -1315,7 +1334,7 @@ static void propagate_linear_data_delta(const MultiresReshapeSmoothContext *resh const ReshapeConstGridElement orig_grid_element = multires_reshape_orig_grid_element_for_grid_coord(reshape_context, grid_coord); - if (final_grid_element->mask != NULL) { + if (final_grid_element->mask != nullptr) { *final_grid_element->mask = clamp_f( orig_grid_element.mask + linear_delta_element->mask, 0.0f, 1.0f); } @@ -1331,7 +1350,7 @@ static void evaluate_base_surface_grids_callback( const MultiresReshapeSmoothContext *reshape_smooth_context, const PTexCoord *ptex_coord, const GridCoord *grid_coord, - void *UNUSED(userdata_v)) + void * /*userdata_v*/) { float limit_P[3]; float tangent_matrix[3][3]; @@ -1343,7 +1362,8 @@ static void evaluate_base_surface_grids_callback( static void evaluate_base_surface_grids(const MultiresReshapeSmoothContext *reshape_smooth_context) { - foreach_toplevel_grid_coord(reshape_smooth_context, evaluate_base_surface_grids_callback, NULL); + foreach_toplevel_grid_coord( + reshape_smooth_context, evaluate_base_surface_grids_callback, nullptr); } /** \} */ @@ -1383,7 +1403,7 @@ static void evaluate_higher_grid_positions_with_details_callback( const MultiresReshapeSmoothContext *reshape_smooth_context, const PTexCoord *ptex_coord, const GridCoord *grid_coord, - void *UNUSED(userdata_v)) + void * /*userdata_v*/) { const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context; @@ -1433,14 +1453,14 @@ static void evaluate_higher_grid_positions_with_details( const MultiresReshapeSmoothContext *reshape_smooth_context) { foreach_toplevel_grid_coord( - reshape_smooth_context, evaluate_higher_grid_positions_with_details_callback, NULL); + reshape_smooth_context, evaluate_higher_grid_positions_with_details_callback, nullptr); } static void evaluate_higher_grid_positions_callback( const MultiresReshapeSmoothContext *reshape_smooth_context, const PTexCoord *ptex_coord, const GridCoord *grid_coord, - void *UNUSED(userdata_v)) + void * /*userdata_v*/) { const MultiresReshapeContext *reshape_context = reshape_smooth_context->reshape_context; Subdiv *reshape_subdiv = reshape_smooth_context->reshape_subdiv; @@ -1463,7 +1483,7 @@ static void evaluate_higher_grid_positions( const MultiresReshapeSmoothContext *reshape_smooth_context) { foreach_toplevel_grid_coord( - reshape_smooth_context, evaluate_higher_grid_positions_callback, NULL); + reshape_smooth_context, evaluate_higher_grid_positions_callback, nullptr); } /** \} */ diff --git a/source/blender/blenkernel/intern/multires_reshape_subdivide.c b/source/blender/blenkernel/intern/multires_reshape_subdivide.cc similarity index 91% rename from source/blender/blenkernel/intern/multires_reshape_subdivide.c rename to source/blender/blenkernel/intern/multires_reshape_subdivide.cc index 4e74835fd9a..c65b78cb160 100644 --- a/source/blender/blenkernel/intern/multires_reshape_subdivide.c +++ b/source/blender/blenkernel/intern/multires_reshape_subdivide.cc @@ -32,7 +32,8 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh) const MPoly *polys = BKE_mesh_polys(mesh); const MLoop *loops = BKE_mesh_loops(mesh); - MDisps *mdisps = CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop); + MDisps *mdisps = static_cast( + CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop)); const int totpoly = mesh->totpoly; for (int p = 0; p < totpoly; p++) { const MPoly *poly = &polys[p]; @@ -63,7 +64,7 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh) void multires_subdivide_create_tangent_displacement_linear_grids(Object *object, MultiresModifierData *mmd) { - Mesh *coarse_mesh = object->data; + Mesh *coarse_mesh = static_cast(object->data); multires_force_sculpt_rebuild(object); MultiresReshapeContext reshape_context; @@ -73,7 +74,7 @@ void multires_subdivide_create_tangent_displacement_linear_grids(Object *object, const bool has_mdisps = CustomData_has_layer(&coarse_mesh->ldata, CD_MDISPS); if (!has_mdisps) { CustomData_add_layer( - &coarse_mesh->ldata, CD_MDISPS, CD_SET_DEFAULT, NULL, coarse_mesh->totloop); + &coarse_mesh->ldata, CD_MDISPS, CD_SET_DEFAULT, nullptr, coarse_mesh->totloop); } if (new_top_level == 1) { diff --git a/source/blender/blenkernel/intern/multires_reshape_util.c b/source/blender/blenkernel/intern/multires_reshape_util.cc similarity index 84% rename from source/blender/blenkernel/intern/multires_reshape_util.c rename to source/blender/blenkernel/intern/multires_reshape_util.cc index dfc9fcfe0c9..aa0fcbb7147 100644 --- a/source/blender/blenkernel/intern/multires_reshape_util.c +++ b/source/blender/blenkernel/intern/multires_reshape_util.cc @@ -39,7 +39,7 @@ Subdiv *multires_reshape_create_subdiv(Depsgraph *depsgraph, { Mesh *base_mesh; - if (depsgraph != NULL) { + if (depsgraph != nullptr) { Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); Object *object_eval = DEG_get_evaluated_object(depsgraph, object); base_mesh = mesh_get_eval_deform(depsgraph, scene_eval, object_eval, &CD_MASK_BAREMESH); @@ -51,9 +51,10 @@ Subdiv *multires_reshape_create_subdiv(Depsgraph *depsgraph, SubdivSettings subdiv_settings; BKE_multires_subdiv_settings_init(&subdiv_settings, mmd); Subdiv *subdiv = BKE_subdiv_new_from_mesh(&subdiv_settings, base_mesh); - if (!BKE_subdiv_eval_begin_from_mesh(subdiv, base_mesh, NULL, SUBDIV_EVALUATOR_TYPE_CPU, NULL)) { + if (!BKE_subdiv_eval_begin_from_mesh( + subdiv, base_mesh, nullptr, SUBDIV_EVALUATOR_TYPE_CPU, nullptr)) { BKE_subdiv_free(subdiv); - return NULL; + return nullptr; } return subdiv; } @@ -69,8 +70,8 @@ static void context_init_lookup(MultiresReshapeContext *reshape_context) const MPoly *mpoly = reshape_context->base_polys; const int num_faces = base_mesh->totpoly; - reshape_context->face_start_grid_index = MEM_malloc_arrayN( - num_faces, sizeof(int), "face_start_grid_index"); + reshape_context->face_start_grid_index = static_cast( + MEM_malloc_arrayN(num_faces, sizeof(int), "face_start_grid_index")); int num_grids = 0; int num_ptex_faces = 0; for (int face_index = 0; face_index < num_faces; ++face_index) { @@ -80,10 +81,10 @@ static void context_init_lookup(MultiresReshapeContext *reshape_context) num_ptex_faces += (num_corners == 4) ? 1 : num_corners; } - reshape_context->grid_to_face_index = MEM_malloc_arrayN( - num_grids, sizeof(int), "grid_to_face_index"); - reshape_context->ptex_start_grid_index = MEM_malloc_arrayN( - num_ptex_faces, sizeof(int), "ptex_start_grid_index"); + reshape_context->grid_to_face_index = static_cast( + MEM_malloc_arrayN(num_grids, sizeof(int), "grid_to_face_index")); + reshape_context->ptex_start_grid_index = static_cast( + MEM_malloc_arrayN(num_ptex_faces, sizeof(int), "ptex_start_grid_index")); for (int face_index = 0, grid_index = 0, ptex_index = 0; face_index < num_faces; ++face_index) { const int num_corners = mpoly[face_index].totloop; const int num_face_ptex_faces = (num_corners == 4) ? 1 : num_corners; @@ -103,16 +104,16 @@ static void context_init_lookup(MultiresReshapeContext *reshape_context) static void context_init_grid_pointers(MultiresReshapeContext *reshape_context) { Mesh *base_mesh = reshape_context->base_mesh; - reshape_context->mdisps = CustomData_get_layer_for_write( - &base_mesh->ldata, CD_MDISPS, base_mesh->totloop); - reshape_context->grid_paint_masks = CustomData_get_layer_for_write( - &base_mesh->ldata, CD_GRID_PAINT_MASK, base_mesh->totloop); + reshape_context->mdisps = static_cast( + CustomData_get_layer_for_write(&base_mesh->ldata, CD_MDISPS, base_mesh->totloop)); + reshape_context->grid_paint_masks = static_cast( + CustomData_get_layer_for_write(&base_mesh->ldata, CD_GRID_PAINT_MASK, base_mesh->totloop)); } static void context_init_commoon(MultiresReshapeContext *reshape_context) { - BLI_assert(reshape_context->subdiv != NULL); - BLI_assert(reshape_context->base_mesh != NULL); + BLI_assert(reshape_context->subdiv != nullptr); + BLI_assert(reshape_context->base_mesh != nullptr); reshape_context->face_ptex_offset = BKE_subdiv_face_ptex_offset_get(reshape_context->subdiv); @@ -122,7 +123,7 @@ static void context_init_commoon(MultiresReshapeContext *reshape_context) static bool context_is_valid(MultiresReshapeContext *reshape_context) { - if (reshape_context->mdisps == NULL) { + if (reshape_context->mdisps == nullptr) { /* Multi-resolution displacement has been removed before current changes were applies. */ return false; } @@ -159,7 +160,7 @@ bool multires_reshape_context_create_from_base_mesh(MultiresReshapeContext *resh reshape_context->base_polys = BKE_mesh_polys(base_mesh); reshape_context->base_loops = BKE_mesh_loops(base_mesh); - reshape_context->subdiv = multires_reshape_create_subdiv(NULL, object, mmd); + reshape_context->subdiv = multires_reshape_create_subdiv(nullptr, object, mmd); reshape_context->need_free_subdiv = true; reshape_context->reshape.level = multires_get_level( @@ -207,8 +208,10 @@ bool multires_reshape_context_create_from_object(MultiresReshapeContext *reshape reshape_context->top.level = mmd->totlvl; reshape_context->top.grid_size = BKE_subdiv_grid_size_from_level(reshape_context->top.level); - reshape_context->cd_vertex_crease = CustomData_get_layer(&base_mesh->vdata, CD_CREASE); - reshape_context->cd_edge_crease = CustomData_get_layer(&base_mesh->edata, CD_CREASE); + reshape_context->cd_vertex_crease = static_cast( + CustomData_get_layer(&base_mesh->vdata, CD_CREASE)); + reshape_context->cd_edge_crease = static_cast( + CustomData_get_layer(&base_mesh->edata, CD_CREASE)); context_init_commoon(reshape_context); @@ -244,11 +247,11 @@ bool multires_reshape_context_create_from_ccg(MultiresReshapeContext *reshape_co } bool multires_reshape_context_create_from_modifier(MultiresReshapeContext *reshape_context, - struct Object *object, - struct MultiresModifierData *mmd, + Object *object, + MultiresModifierData *mmd, int top_level) { - Subdiv *subdiv = multires_reshape_create_subdiv(NULL, object, mmd); + Subdiv *subdiv = multires_reshape_create_subdiv(nullptr, object, mmd); const bool result = multires_reshape_context_create_from_subdiv( reshape_context, object, mmd, subdiv, top_level); @@ -259,9 +262,9 @@ bool multires_reshape_context_create_from_modifier(MultiresReshapeContext *resha } bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape_context, - struct Object *object, - struct MultiresModifierData *mmd, - struct Subdiv *subdiv, + Object *object, + MultiresModifierData *mmd, + Subdiv *subdiv, int top_level) { context_zero(reshape_context); @@ -297,17 +300,17 @@ void multires_reshape_free_original_grids(MultiresReshapeContext *reshape_contex MDisps *orig_mdisps = reshape_context->orig.mdisps; GridPaintMask *orig_grid_paint_masks = reshape_context->orig.grid_paint_masks; - if (orig_mdisps == NULL && orig_grid_paint_masks == NULL) { + if (orig_mdisps == nullptr && orig_grid_paint_masks == nullptr) { return; } const int num_grids = reshape_context->num_grids; for (int grid_index = 0; grid_index < num_grids; grid_index++) { - if (orig_mdisps != NULL) { + if (orig_mdisps != nullptr) { MDisps *orig_grid = &orig_mdisps[grid_index]; MEM_SAFE_FREE(orig_grid->disps); } - if (orig_grid_paint_masks != NULL) { + if (orig_grid_paint_masks != nullptr) { GridPaintMask *orig_paint_mask_grid = &orig_grid_paint_masks[grid_index]; MEM_SAFE_FREE(orig_paint_mask_grid->data); } @@ -316,8 +319,8 @@ void multires_reshape_free_original_grids(MultiresReshapeContext *reshape_contex MEM_SAFE_FREE(orig_mdisps); MEM_SAFE_FREE(orig_grid_paint_masks); - reshape_context->orig.mdisps = NULL; - reshape_context->orig.grid_paint_masks = NULL; + reshape_context->orig.mdisps = nullptr; + reshape_context->orig.grid_paint_masks = nullptr; } void multires_reshape_context_free(MultiresReshapeContext *reshape_context) @@ -447,19 +450,19 @@ void multires_reshape_tangent_matrix_for_corner(const MultiresReshapeContext *re ReshapeGridElement multires_reshape_grid_element_for_grid_coord( const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord) { - ReshapeGridElement grid_element = {NULL, NULL}; + ReshapeGridElement grid_element = {nullptr, nullptr}; const int grid_size = reshape_context->top.grid_size; const int grid_x = lround(grid_coord->u * (grid_size - 1)); const int grid_y = lround(grid_coord->v * (grid_size - 1)); const int grid_element_index = grid_y * grid_size + grid_x; - if (reshape_context->mdisps != NULL) { + if (reshape_context->mdisps != nullptr) { MDisps *displacement_grid = &reshape_context->mdisps[grid_coord->grid_index]; grid_element.displacement = displacement_grid->disps[grid_element_index]; } - if (reshape_context->grid_paint_masks != NULL) { + if (reshape_context->grid_paint_masks != nullptr) { GridPaintMask *grid_paint_mask = &reshape_context->grid_paint_masks[grid_coord->grid_index]; grid_element.mask = &grid_paint_mask->data[grid_element_index]; } @@ -480,9 +483,9 @@ ReshapeConstGridElement multires_reshape_orig_grid_element_for_grid_coord( ReshapeConstGridElement grid_element = {{0.0f, 0.0f, 0.0f}, 0.0f}; const MDisps *mdisps = reshape_context->orig.mdisps; - if (mdisps != NULL) { + if (mdisps != nullptr) { const MDisps *displacement_grid = &mdisps[grid_coord->grid_index]; - if (displacement_grid->disps != NULL) { + if (displacement_grid->disps != nullptr) { const int grid_size = BKE_subdiv_grid_size_from_level(displacement_grid->level); const int grid_x = lround(grid_coord->u * (grid_size - 1)); const int grid_y = lround(grid_coord->v * (grid_size - 1)); @@ -492,9 +495,9 @@ ReshapeConstGridElement multires_reshape_orig_grid_element_for_grid_coord( } const GridPaintMask *grid_paint_masks = reshape_context->orig.grid_paint_masks; - if (grid_paint_masks != NULL) { + if (grid_paint_masks != nullptr) { const GridPaintMask *paint_mask_grid = &grid_paint_masks[grid_coord->grid_index]; - if (paint_mask_grid->data != NULL) { + if (paint_mask_grid->data != nullptr) { const int grid_size = BKE_subdiv_grid_size_from_level(paint_mask_grid->level); const int grid_x = lround(grid_coord->u * (grid_size - 1)); const int grid_y = lround(grid_coord->v * (grid_size - 1)); @@ -540,8 +543,9 @@ static void allocate_displacement_grid(MDisps *displacement_grid, const int leve { const int grid_size = BKE_subdiv_grid_size_from_level(level); const int grid_area = grid_size * grid_size; - float(*disps)[3] = MEM_calloc_arrayN(grid_area, sizeof(float[3]), "multires disps"); - if (displacement_grid->disps != NULL) { + float(*disps)[3] = static_cast( + MEM_calloc_arrayN(grid_area, sizeof(float[3]), "multires disps")); + if (displacement_grid->disps != nullptr) { MEM_freeN(displacement_grid->disps); } /* TODO(sergey): Preserve data on the old level. */ @@ -552,7 +556,7 @@ static void allocate_displacement_grid(MDisps *displacement_grid, const int leve static void ensure_displacement_grid(MDisps *displacement_grid, const int level) { - if (displacement_grid->disps != NULL && displacement_grid->level >= level) { + if (displacement_grid->disps != nullptr && displacement_grid->level >= level) { return; } allocate_displacement_grid(displacement_grid, level); @@ -561,7 +565,8 @@ static void ensure_displacement_grid(MDisps *displacement_grid, const int level) static void ensure_displacement_grids(Mesh *mesh, const int grid_level) { const int num_grids = mesh->totloop; - MDisps *mdisps = CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop); + MDisps *mdisps = static_cast( + CustomData_get_layer_for_write(&mesh->ldata, CD_MDISPS, mesh->totloop)); for (int grid_index = 0; grid_index < num_grids; grid_index++) { ensure_displacement_grid(&mdisps[grid_index], grid_level); } @@ -569,9 +574,9 @@ static void ensure_displacement_grids(Mesh *mesh, const int grid_level) static void ensure_mask_grids(Mesh *mesh, const int level) { - GridPaintMask *grid_paint_masks = CustomData_get_layer_for_write( - &mesh->ldata, CD_GRID_PAINT_MASK, mesh->totloop); - if (grid_paint_masks == NULL) { + GridPaintMask *grid_paint_masks = static_cast( + CustomData_get_layer_for_write(&mesh->ldata, CD_GRID_PAINT_MASK, mesh->totloop)); + if (grid_paint_masks == nullptr) { return; } const int num_grids = mesh->totloop; @@ -587,7 +592,8 @@ static void ensure_mask_grids(Mesh *mesh, const int level) MEM_freeN(grid_paint_mask->data); } /* TODO(sergey): Preserve data on the old level. */ - grid_paint_mask->data = MEM_calloc_arrayN(grid_area, sizeof(float), "gpm.data"); + grid_paint_mask->data = static_cast( + MEM_calloc_arrayN(grid_area, sizeof(float), "gpm.data")); } } @@ -608,10 +614,10 @@ void multires_reshape_store_original_grids(MultiresReshapeContext *reshape_conte const MDisps *mdisps = reshape_context->mdisps; const GridPaintMask *grid_paint_masks = reshape_context->grid_paint_masks; - MDisps *orig_mdisps = MEM_dupallocN(mdisps); - GridPaintMask *orig_grid_paint_masks = NULL; - if (grid_paint_masks != NULL) { - orig_grid_paint_masks = MEM_dupallocN(grid_paint_masks); + MDisps *orig_mdisps = static_cast(MEM_dupallocN(mdisps)); + GridPaintMask *orig_grid_paint_masks = nullptr; + if (grid_paint_masks != nullptr) { + orig_grid_paint_masks = static_cast(MEM_dupallocN(grid_paint_masks)); } const int num_grids = reshape_context->num_grids; @@ -621,13 +627,14 @@ void multires_reshape_store_original_grids(MultiresReshapeContext *reshape_conte * data when accessed during reshape process. * Reshape process will ensure all grids are on top level, but that happens on separate set of * grids which eventually replaces original one. */ - if (orig_grid->disps != NULL) { - orig_grid->disps = MEM_dupallocN(orig_grid->disps); + if (orig_grid->disps != nullptr) { + orig_grid->disps = static_cast(MEM_dupallocN(orig_grid->disps)); } - if (orig_grid_paint_masks != NULL) { + if (orig_grid_paint_masks != nullptr) { GridPaintMask *orig_paint_mask_grid = &orig_grid_paint_masks[grid_index]; - if (orig_paint_mask_grid->data != NULL) { - orig_paint_mask_grid->data = MEM_dupallocN(orig_paint_mask_grid->data); + if (orig_paint_mask_grid->data != nullptr) { + orig_paint_mask_grid->data = static_cast( + MEM_dupallocN(orig_paint_mask_grid->data)); } } } @@ -636,11 +643,11 @@ void multires_reshape_store_original_grids(MultiresReshapeContext *reshape_conte reshape_context->orig.grid_paint_masks = orig_grid_paint_masks; } -typedef void (*ForeachGridCoordinateCallback)(const MultiresReshapeContext *reshape_context, - const GridCoord *grid_coord, - void *userdata_v); +using ForeachGridCoordinateCallback = void (*)(const MultiresReshapeContext *reshape_context, + const GridCoord *grid_coord, + void *userdata_v); -typedef struct ForeachGridCoordinateTaskData { +struct ForeachGridCoordinateTaskData { const MultiresReshapeContext *reshape_context; int grid_size; @@ -648,27 +655,27 @@ typedef struct ForeachGridCoordinateTaskData { ForeachGridCoordinateCallback callback; void *callback_userdata_v; -} ForeachGridCoordinateTaskData; +}; static void foreach_grid_face_coordinate_task(void *__restrict userdata_v, const int face_index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - ForeachGridCoordinateTaskData *data = userdata_v; + ForeachGridCoordinateTaskData *data = static_cast(userdata_v); const MultiresReshapeContext *reshape_context = data->reshape_context; const MPoly *mpoly = reshape_context->base_polys; const int grid_size = data->grid_size; - const float grid_size_1_inv = 1.0f / (((float)grid_size) - 1.0f); + const float grid_size_1_inv = 1.0f / ((float(grid_size)) - 1.0f); const int num_corners = mpoly[face_index].totloop; int grid_index = reshape_context->face_start_grid_index[face_index]; for (int corner = 0; corner < num_corners; ++corner, ++grid_index) { for (int y = 0; y < grid_size; ++y) { - const float v = (float)y * grid_size_1_inv; + const float v = float(y) * grid_size_1_inv; for (int x = 0; x < grid_size; ++x) { - const float u = (float)x * grid_size_1_inv; + const float u = float(x) * grid_size_1_inv; GridCoord grid_coord; grid_coord.grid_index = grid_index; @@ -690,7 +697,7 @@ static void foreach_grid_coordinate(const MultiresReshapeContext *reshape_contex ForeachGridCoordinateTaskData data; data.reshape_context = reshape_context; data.grid_size = BKE_subdiv_grid_size_from_level(level); - data.grid_size_1_inv = 1.0f / (((float)data.grid_size) - 1.0f); + data.grid_size_1_inv = 1.0f / ((float(data.grid_size)) - 1.0f); data.callback = callback; data.callback_userdata_v = userdata_v; @@ -707,7 +714,7 @@ static void foreach_grid_coordinate(const MultiresReshapeContext *reshape_contex static void object_grid_element_to_tangent_displacement( const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord, - void *UNUSED(userdata_v)) + void * /*userdata_v*/) { float P[3]; float tangent_matrix[3][3]; @@ -734,7 +741,7 @@ void multires_reshape_object_grids_to_tangent_displacement( foreach_grid_coordinate(reshape_context, reshape_context->top.level, object_grid_element_to_tangent_displacement, - NULL); + nullptr); } /** \} */ @@ -748,7 +755,7 @@ void multires_reshape_object_grids_to_tangent_displacement( static void assign_final_coords_from_mdisps(const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord, - void *UNUSED(userdata_v)) + void * /*userdata_v*/) { float P[3]; float tangent_matrix[3][3]; @@ -766,12 +773,12 @@ void multires_reshape_assign_final_coords_from_mdisps( const MultiresReshapeContext *reshape_context) { foreach_grid_coordinate( - reshape_context, reshape_context->top.level, assign_final_coords_from_mdisps, NULL); + reshape_context, reshape_context->top.level, assign_final_coords_from_mdisps, nullptr); } static void assign_final_elements_from_orig_mdisps(const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord, - void *UNUSED(userdata_v)) + void * /*userdata_v*/) { float P[3]; float tangent_matrix[3][3]; @@ -787,7 +794,7 @@ static void assign_final_elements_from_orig_mdisps(const MultiresReshapeContext grid_coord); add_v3_v3v3(grid_element.displacement, P, D); - if (grid_element.mask != NULL) { + if (grid_element.mask != nullptr) { *grid_element.mask = orig_grid_element.mask; } } @@ -795,8 +802,10 @@ static void assign_final_elements_from_orig_mdisps(const MultiresReshapeContext void multires_reshape_assign_final_elements_from_orig_mdisps( const MultiresReshapeContext *reshape_context) { - foreach_grid_coordinate( - reshape_context, reshape_context->top.level, assign_final_elements_from_orig_mdisps, NULL); + foreach_grid_coordinate(reshape_context, + reshape_context->top.level, + assign_final_elements_from_orig_mdisps, + nullptr); } /** \} */ diff --git a/source/blender/blenkernel/intern/multires_reshape_vertcos.c b/source/blender/blenkernel/intern/multires_reshape_vertcos.cc similarity index 71% rename from source/blender/blenkernel/intern/multires_reshape_vertcos.c rename to source/blender/blenkernel/intern/multires_reshape_vertcos.cc index 7cf853e0374..f50fc5cebb8 100644 --- a/source/blender/blenkernel/intern/multires_reshape_vertcos.c +++ b/source/blender/blenkernel/intern/multires_reshape_vertcos.cc @@ -15,12 +15,12 @@ #include "BKE_subdiv_foreach.h" #include "BKE_subdiv_mesh.h" -typedef struct MultiresReshapeAssignVertcosContext { +struct MultiresReshapeAssignVertcosContext { const MultiresReshapeContext *reshape_context; const float (*vert_coords)[3]; - const int num_vert_coords; -} MultiresReshapeAssignVertcosContext; + int num_vert_coords; +}; /** * Set single displacement grid value at a reshape level to a corresponding vertex coordinate. @@ -31,21 +31,23 @@ static void multires_reshape_vertcos_foreach_single_vertex( const GridCoord *grid_coord, const int subdiv_vertex_index) { - MultiresReshapeAssignVertcosContext *reshape_vertcos_context = foreach_context->user_data; + MultiresReshapeAssignVertcosContext *reshape_vertcos_context = + static_cast(foreach_context->user_data); const float *coordinate = reshape_vertcos_context->vert_coords[subdiv_vertex_index]; ReshapeGridElement grid_element = multires_reshape_grid_element_for_grid_coord( reshape_vertcos_context->reshape_context, grid_coord); - BLI_assert(grid_element.displacement != NULL); + BLI_assert(grid_element.displacement != nullptr); copy_v3_v3(grid_element.displacement, coordinate); } -/* TODO(sergey): De-duplicate with similar function in multires_reshape_smooth.c */ +/* TODO(sergey): De-duplicate with similar function in multires_reshape_smooth.cc */ static void multires_reshape_vertcos_foreach_vertex(const SubdivForeachContext *foreach_context, const PTexCoord *ptex_coord, const int subdiv_vertex_index) { - const MultiresReshapeAssignVertcosContext *reshape_vertcos_context = foreach_context->user_data; + const MultiresReshapeAssignVertcosContext *reshape_vertcos_context = + static_cast(foreach_context->user_data); const MultiresReshapeContext *reshape_context = reshape_vertcos_context->reshape_context; const GridCoord grid_coord = multires_reshape_ptex_coord_to_grid(reshape_context, ptex_coord); @@ -95,12 +97,13 @@ static void multires_reshape_vertcos_foreach_vertex(const SubdivForeachContext * static bool multires_reshape_vertcos_foreach_topology_info( const SubdivForeachContext *foreach_context, const int num_vertices, - const int UNUSED(num_edges), - const int UNUSED(num_loops), - const int UNUSED(num_polygons), - const int *UNUSED(subdiv_polygon_offset)) + const int /*num_edges*/, + const int /*num_loops*/, + const int /*num_polygons*/, + const int * /*subdiv_polygon_offset*/) { - MultiresReshapeAssignVertcosContext *reshape_vertcos_context = foreach_context->user_data; + MultiresReshapeAssignVertcosContext *reshape_vertcos_context = + static_cast(foreach_context->user_data); if (num_vertices != reshape_vertcos_context->num_vert_coords) { return false; } @@ -110,59 +113,56 @@ static bool multires_reshape_vertcos_foreach_topology_info( /* SubdivForeachContext::vertex_inner() */ static void multires_reshape_vertcos_foreach_vertex_inner( const SubdivForeachContext *foreach_context, - void *UNUSED(tls_v), + void * /*tls_v*/, const int ptex_face_index, const float ptex_face_u, const float ptex_face_v, - const int UNUSED(coarse_face_index), - const int UNUSED(coarse_face_corner), + const int /*coarse_face_index*/, + const int /*coarse_face_corner*/, const int subdiv_vertex_index) { - const PTexCoord ptex_coord = { - .ptex_face_index = ptex_face_index, - .u = ptex_face_u, - .v = ptex_face_v, - }; + PTexCoord ptex_coord{}; + ptex_coord.ptex_face_index = ptex_face_index; + ptex_coord.u = ptex_face_u; + ptex_coord.v = ptex_face_v; multires_reshape_vertcos_foreach_vertex(foreach_context, &ptex_coord, subdiv_vertex_index); } /* SubdivForeachContext::vertex_every_corner() */ static void multires_reshape_vertcos_foreach_vertex_every_corner( - const struct SubdivForeachContext *foreach_context, - void *UNUSED(tls_v), + const SubdivForeachContext *foreach_context, + void * /*tls_v*/, const int ptex_face_index, const float ptex_face_u, const float ptex_face_v, - const int UNUSED(coarse_vertex_index), - const int UNUSED(coarse_face_index), - const int UNUSED(coarse_face_corner), + const int /*coarse_vertex_index*/, + const int /*coarse_face_index*/, + const int /*coarse_face_corner*/, const int subdiv_vertex_index) { - const PTexCoord ptex_coord = { - .ptex_face_index = ptex_face_index, - .u = ptex_face_u, - .v = ptex_face_v, - }; + PTexCoord ptex_coord{}; + ptex_coord.ptex_face_index = ptex_face_index; + ptex_coord.u = ptex_face_u; + ptex_coord.v = ptex_face_v; multires_reshape_vertcos_foreach_vertex(foreach_context, &ptex_coord, subdiv_vertex_index); } /* SubdivForeachContext::vertex_every_edge() */ static void multires_reshape_vertcos_foreach_vertex_every_edge( - const struct SubdivForeachContext *foreach_context, - void *UNUSED(tls_v), + const SubdivForeachContext *foreach_context, + void * /*tls_v*/, const int ptex_face_index, const float ptex_face_u, const float ptex_face_v, - const int UNUSED(coarse_edge_index), - const int UNUSED(coarse_face_index), - const int UNUSED(coarse_face_corner), + const int /*coarse_edge_index*/, + const int /*coarse_face_index*/, + const int /*coarse_face_corner*/, const int subdiv_vertex_index) { - const PTexCoord ptex_coord = { - .ptex_face_index = ptex_face_index, - .u = ptex_face_u, - .v = ptex_face_v, - }; + PTexCoord ptex_coord{}; + ptex_coord.ptex_face_index = ptex_face_index; + ptex_coord.u = ptex_face_u; + ptex_coord.v = ptex_face_v; multires_reshape_vertcos_foreach_vertex(foreach_context, &ptex_coord, subdiv_vertex_index); } @@ -171,19 +171,17 @@ bool multires_reshape_assign_final_coords_from_vertcos( const float (*vert_coords)[3], const int num_vert_coords) { - MultiresReshapeAssignVertcosContext reshape_vertcos_context = { - .reshape_context = reshape_context, - .vert_coords = vert_coords, - .num_vert_coords = num_vert_coords, - }; + MultiresReshapeAssignVertcosContext reshape_vertcos_context{}; + reshape_vertcos_context.reshape_context = reshape_context; + reshape_vertcos_context.vert_coords = vert_coords; + reshape_vertcos_context.num_vert_coords = num_vert_coords; - SubdivForeachContext foreach_context = { - .topology_info = multires_reshape_vertcos_foreach_topology_info, - .vertex_inner = multires_reshape_vertcos_foreach_vertex_inner, - .vertex_every_edge = multires_reshape_vertcos_foreach_vertex_every_edge, - .vertex_every_corner = multires_reshape_vertcos_foreach_vertex_every_corner, - .user_data = &reshape_vertcos_context, - }; + SubdivForeachContext foreach_context{}; + foreach_context.topology_info = multires_reshape_vertcos_foreach_topology_info; + foreach_context.vertex_inner = multires_reshape_vertcos_foreach_vertex_inner; + foreach_context.vertex_every_edge = multires_reshape_vertcos_foreach_vertex_every_edge; + foreach_context.vertex_every_corner = multires_reshape_vertcos_foreach_vertex_every_corner; + foreach_context.user_data = &reshape_vertcos_context; SubdivToMeshSettings mesh_settings; mesh_settings.resolution = (1 << reshape_context->reshape.level) + 1; diff --git a/source/blender/blenkernel/intern/multires_subdiv.c b/source/blender/blenkernel/intern/multires_subdiv.cc similarity index 100% rename from source/blender/blenkernel/intern/multires_subdiv.c rename to source/blender/blenkernel/intern/multires_subdiv.cc diff --git a/source/blender/blenkernel/intern/multires_unsubdivide.c b/source/blender/blenkernel/intern/multires_unsubdivide.cc similarity index 92% rename from source/blender/blenkernel/intern/multires_unsubdivide.c rename to source/blender/blenkernel/intern/multires_unsubdivide.cc index 2ef074cd24d..d78ba10c7ba 100644 --- a/source/blender/blenkernel/intern/multires_unsubdivide.c +++ b/source/blender/blenkernel/intern/multires_unsubdivide.cc @@ -90,7 +90,7 @@ static BMVert *unsubdivide_find_any_pole(BMesh *bm, int *elem_id, int elem) { BMIter iter; BMVert *v; - BMVert *pole = NULL; + BMVert *pole = nullptr; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (is_vertex_in_id(v, elem_id, elem) && is_vertex_pole_three(v)) { return v; @@ -161,7 +161,8 @@ static bool is_vertex_diagonal(BMVert *from_v, BMVert *to_v) */ static void unsubdivide_face_center_vertex_tag(BMesh *bm, BMVert *initial_vertex) { - bool *visited_verts = MEM_calloc_arrayN(bm->totvert, sizeof(bool), "visited vertices"); + bool *visited_verts = static_cast( + MEM_calloc_arrayN(bm->totvert, sizeof(bool), "visited vertices")); GSQueue *queue; queue = BLI_gsqueue_new(sizeof(BMVert *)); @@ -290,14 +291,14 @@ static bool unsubdivide_tag_disconnected_mesh_element(BMesh *bm, int *elem_id, i * part of the base mesh. If it isn't, then there is no solution. */ GSQueue *initial_vertex = BLI_gsqueue_new(sizeof(BMVert *)); BMVert *initial_vertex_pole = unsubdivide_find_any_pole(bm, elem_id, elem); - if (initial_vertex_pole != NULL) { + if (initial_vertex_pole != nullptr) { BLI_gsqueue_push(initial_vertex, &initial_vertex_pole); } /* Also try from the different 4 vertices of a quad in the current * disconnected element ID. If a solution exists the search should return a valid solution from * one of these vertices. */ - BMFace *f, *init_face = NULL; + BMFace *f, *init_face = nullptr; BMVert *v; BMIter iter_a, iter_b; BM_ITER_MESH (f, &iter_a, bm, BM_FACES_OF_MESH) { @@ -307,7 +308,7 @@ static bool unsubdivide_tag_disconnected_mesh_element(BMesh *bm, int *elem_id, i break; } } - if (init_face != NULL) { + if (init_face != nullptr) { break; } } @@ -352,7 +353,8 @@ static bool unsubdivide_tag_disconnected_mesh_element(BMesh *bm, int *elem_id, i */ static int unsubdivide_init_elem_ids(BMesh *bm, int *elem_id) { - bool *visited_verts = MEM_calloc_arrayN(bm->totvert, sizeof(bool), "visited vertices"); + bool *visited_verts = static_cast( + MEM_calloc_arrayN(bm->totvert, sizeof(bool), "visited vertices")); int current_id = 0; for (int i = 0; i < bm->totvert; i++) { if (!visited_verts[i]) { @@ -459,7 +461,7 @@ static bool multires_unsubdivide_single_level(BMesh *bm) BM_mesh_elem_table_ensure(bm, BM_VERT); /* Build disconnected elements IDs. Each disconnected mesh element is evaluated separately. */ - int *elem_id = MEM_calloc_arrayN(bm->totvert, sizeof(int), " ELEM ID"); + int *elem_id = static_cast(MEM_calloc_arrayN(bm->totvert, sizeof(int), " ELEM ID")); const int tot_ids = unsubdivide_init_elem_ids(bm, elem_id); bool valid_tag_found = true; @@ -495,7 +497,7 @@ static BMEdge *edge_step(BMVert *v, BMEdge *edge, BMVert **r_next_vertex) { BMIter iter; BMEdge *test_edge; - if (edge == NULL) { + if (edge == nullptr) { (*r_next_vertex) = v; return edge; } @@ -505,7 +507,7 @@ static BMEdge *edge_step(BMVert *v, BMEdge *edge, BMVert **r_next_vertex) return test_edge; } } - return NULL; + return nullptr; } static BMFace *face_step(BMEdge *edge, BMFace *f) @@ -539,7 +541,7 @@ static BMEdge *get_initial_edge_y(BMFace *f, BMEdge *edge_x, BMVert *initial_ver } } } - return NULL; + return nullptr; } /** @@ -662,7 +664,8 @@ static void store_grid_data(MultiresUnsubdivideContext *context, const int grid_size = BKE_ccg_gridsize(context->num_original_levels); const int face_grid_size = BKE_ccg_gridsize(context->num_original_levels + 1); const int face_grid_area = face_grid_size * face_grid_size; - float(*face_grid)[3] = MEM_calloc_arrayN(face_grid_area, sizeof(float[3]), "face_grid"); + float(*face_grid)[3] = static_cast( + MEM_calloc_arrayN(face_grid_area, sizeof(float[3]), "face_grid")); for (int i = 0; i < poly->totloop; i++) { const int loop_index = poly->loopstart + i; @@ -715,8 +718,8 @@ static void multires_unsubdivide_extract_single_grid_from_face_edge( const int grid_size = BKE_ccg_gridsize(context->num_new_levels); const int unsubdiv_grid_size = grid->grid_size = BKE_ccg_gridsize(context->num_total_levels); grid->grid_size = unsubdiv_grid_size; - grid->grid_co = MEM_calloc_arrayN( - unsubdiv_grid_size * unsubdiv_grid_size, sizeof(float[3]), "grids coordinates"); + grid->grid_co = static_cast(MEM_calloc_arrayN( + unsubdiv_grid_size * unsubdiv_grid_size, sizeof(float[3]), "grids coordinates")); /* Get the vertex on the corner of the grid. This vertex was tagged previously as it also exist * on the base mesh. */ @@ -861,17 +864,15 @@ static void multires_unsubdivide_get_grid_corners_on_base_mesh(BMFace *f1, static BMesh *get_bmesh_from_mesh(Mesh *mesh) { const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(mesh); - BMesh *bm = BM_mesh_create(&allocsize, - &((struct BMeshCreateParams){ - .use_toolflags = true, - })); - BM_mesh_bm_from_me(bm, - mesh, - (&(struct BMeshFromMeshParams){ - .calc_face_normal = true, - .calc_vert_normal = true, - })); + BMeshCreateParams bm_create_params{}; + bm_create_params.use_toolflags = true; + BMesh *bm = BM_mesh_create(&allocsize, &bm_create_params); + + BMeshFromMeshParams bm_from_me_params{}; + bm_from_me_params.calc_face_normal = true; + bm_from_me_params.calc_vert_normal = true; + BM_mesh_bm_from_me(bm, mesh, &bm_from_me_params); return bm; } @@ -901,11 +902,11 @@ static void multires_unsubdivide_add_original_index_datalayers(Mesh *mesh) { multires_unsubdivide_free_original_datalayers(mesh); - int *l_index = CustomData_add_layer_named( - &mesh->ldata, CD_PROP_INT32, CD_SET_DEFAULT, NULL, mesh->totloop, lname); + int *l_index = static_cast(CustomData_add_layer_named( + &mesh->ldata, CD_PROP_INT32, CD_SET_DEFAULT, nullptr, mesh->totloop, lname)); - int *v_index = CustomData_add_layer_named( - &mesh->vdata, CD_PROP_INT32, CD_SET_DEFAULT, NULL, mesh->totvert, vname); + int *v_index = static_cast(CustomData_add_layer_named( + &mesh->vdata, CD_PROP_INT32, CD_SET_DEFAULT, nullptr, mesh->totvert, vname)); /* Initialize these data-layer with the indices in the current mesh. */ for (int i = 0; i < mesh->totloop; i++) { @@ -938,8 +939,8 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract( bm_original_mesh, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false); /* Get the mapping data-layer. */ - context->base_to_orig_vmap = CustomData_get_layer_named_for_write( - &base_mesh->vdata, CD_PROP_INT32, vname, base_mesh->totvert); + context->base_to_orig_vmap = static_cast(CustomData_get_layer_named_for_write( + &base_mesh->vdata, CD_PROP_INT32, vname, base_mesh->totvert)); /* Tag the base mesh vertices in the original mesh. */ for (int i = 0; i < base_mesh->totvert; i++) { @@ -949,7 +950,8 @@ static void multires_unsubdivide_prepare_original_bmesh_for_extract( } /* Create a map from loop index to poly index for the original mesh. */ - context->loop_to_face_map = MEM_calloc_arrayN(original_mesh->totloop, sizeof(int), "loop map"); + context->loop_to_face_map = static_cast( + MEM_calloc_arrayN(original_mesh->totloop, sizeof(int), "loop map")); for (int i = 0; i < original_mesh->totpoly; i++) { const MPoly *poly = &original_polys[i]; @@ -993,17 +995,19 @@ static void multires_unsubdivide_extract_grids(MultiresUnsubdivideContext *conte BMesh *bm_original_mesh = context->bm_original_mesh; context->num_grids = base_mesh->totloop; - context->base_mesh_grids = MEM_calloc_arrayN( - base_mesh->totloop, sizeof(MultiresUnsubdivideGrid), "grids"); + context->base_mesh_grids = static_cast( + MEM_calloc_arrayN(base_mesh->totloop, sizeof(MultiresUnsubdivideGrid), "grids")); /* Based on the existing indices in the data-layers, generate two vertex indices maps. */ /* From vertex index in original to vertex index in base and from vertex index in base to vertex * index in original. */ - int *orig_to_base_vmap = MEM_calloc_arrayN(bm_original_mesh->totvert, sizeof(int), "orig vmap"); - int *base_to_orig_vmap = MEM_calloc_arrayN(base_mesh->totvert, sizeof(int), "base vmap"); + int *orig_to_base_vmap = static_cast( + MEM_calloc_arrayN(bm_original_mesh->totvert, sizeof(int), "orig vmap")); + int *base_to_orig_vmap = static_cast( + MEM_calloc_arrayN(base_mesh->totvert, sizeof(int), "base vmap")); - context->base_to_orig_vmap = CustomData_get_layer_named_for_write( - &base_mesh->vdata, CD_PROP_INT32, vname, base_mesh->totvert); + context->base_to_orig_vmap = static_cast(CustomData_get_layer_named_for_write( + &base_mesh->vdata, CD_PROP_INT32, vname, base_mesh->totvert)); for (int i = 0; i < base_mesh->totvert; i++) { base_to_orig_vmap[i] = context->base_to_orig_vmap[i]; } @@ -1099,7 +1103,7 @@ static void multires_unsubdivide_extract_grids(MultiresUnsubdivideContext *conte static void multires_unsubdivide_private_extract_data_free(MultiresUnsubdivideContext *context) { - if (context->bm_original_mesh != NULL) { + if (context->bm_original_mesh != nullptr) { BM_mesh_free(context->bm_original_mesh); } MEM_SAFE_FREE(context->loop_to_face_map); @@ -1107,7 +1111,7 @@ static void multires_unsubdivide_private_extract_data_free(MultiresUnsubdivideCo void multires_unsubdivide_context_init(MultiresUnsubdivideContext *context, Mesh *original_mesh, - struct MultiresModifierData *mmd) + MultiresModifierData *mmd) { context->original_mesh = original_mesh; context->num_new_levels = 0; @@ -1143,12 +1147,10 @@ bool multires_unsubdivide_to_basemesh(MultiresUnsubdivideContext *context) /* Store the new base-mesh as a mesh in context, free bmesh. */ context->base_mesh = BKE_mesh_new_nomain(0, 0, 0, 0, 0); - BM_mesh_bm_to_me(NULL, - bm_base_mesh, - context->base_mesh, - (&(struct BMeshToMeshParams){ - .calc_object_remap = true, - })); + + BMeshToMeshParams bm_to_me_params{}; + bm_to_me_params.calc_object_remap = true; + BM_mesh_bm_to_me(nullptr, bm_base_mesh, context->base_mesh, &bm_to_me_params); BM_mesh_free(bm_base_mesh); /* Initialize bmesh and maps for the original mesh and extract the grids. */ @@ -1181,8 +1183,8 @@ static void multires_create_grids_in_unsubdivided_base_mesh(MultiresUnsubdivideC if (CustomData_has_layer(&base_mesh->ldata, CD_MDISPS)) { CustomData_free_layers(&base_mesh->ldata, CD_MDISPS, base_mesh->totloop); } - MDisps *mdisps = CustomData_add_layer( - &base_mesh->ldata, CD_MDISPS, CD_SET_DEFAULT, NULL, base_mesh->totloop); + MDisps *mdisps = static_cast(CustomData_add_layer( + &base_mesh->ldata, CD_MDISPS, CD_SET_DEFAULT, nullptr, base_mesh->totloop)); const int totdisp = pow_i(BKE_ccg_gridsize(context->num_total_levels), 2); const int totloop = base_mesh->totloop; @@ -1191,7 +1193,8 @@ static void multires_create_grids_in_unsubdivided_base_mesh(MultiresUnsubdivideC /* Allocate the MDISPS grids and copy the extracted data from context. */ for (int i = 0; i < totloop; i++) { - float(*disps)[3] = MEM_calloc_arrayN(totdisp, sizeof(float[3]), "multires disps"); + float(*disps)[3] = static_cast( + MEM_calloc_arrayN(totdisp, sizeof(float[3]), __func__)); if (mdisps[i].disps) { MEM_freeN(mdisps[i].disps); @@ -1209,13 +1212,13 @@ static void multires_create_grids_in_unsubdivided_base_mesh(MultiresUnsubdivideC } } -int multiresModifier_rebuild_subdiv(struct Depsgraph *depsgraph, - struct Object *object, - struct MultiresModifierData *mmd, +int multiresModifier_rebuild_subdiv(Depsgraph *depsgraph, + Object *object, + MultiresModifierData *mmd, int rebuild_limit, bool switch_view_to_lower_level) { - Mesh *mesh = object->data; + Mesh *mesh = static_cast(object->data); multires_force_sculpt_rebuild(object); @@ -1255,24 +1258,24 @@ int multiresModifier_rebuild_subdiv(struct Depsgraph *depsgraph, } /* Copy the new base mesh to the original mesh. */ - BKE_mesh_nomain_to_mesh(unsubdiv_context.base_mesh, object->data, object); - Mesh *base_mesh = object->data; + Mesh *base_mesh = static_cast(object->data); + BKE_mesh_nomain_to_mesh(unsubdiv_context.base_mesh, base_mesh, object); multires_create_grids_in_unsubdivided_base_mesh(&unsubdiv_context, base_mesh); /* Update the levels in the modifier. Force always to display at level 0 as it contains the new * created level. */ - mmd->totlvl = (char)unsubdiv_context.num_total_levels; + mmd->totlvl = char(unsubdiv_context.num_total_levels); if (switch_view_to_lower_level) { mmd->sculptlvl = 0; mmd->lvl = 0; } else { - mmd->sculptlvl = (char)(mmd->sculptlvl + unsubdiv_context.num_new_levels); - mmd->lvl = (char)(mmd->lvl + unsubdiv_context.num_new_levels); + mmd->sculptlvl = char(mmd->sculptlvl + unsubdiv_context.num_new_levels); + mmd->lvl = char(mmd->lvl + unsubdiv_context.num_new_levels); } - mmd->renderlvl = (char)(mmd->renderlvl + unsubdiv_context.num_new_levels); + mmd->renderlvl = char(mmd->renderlvl + unsubdiv_context.num_new_levels); /* Create a reshape context to convert the MDISPS data to tangent displacement. It can be the * same as the previous one as a new Subdivision needs to be created for the new base mesh. */ diff --git a/source/blender/blenkernel/intern/multires_versioning.c b/source/blender/blenkernel/intern/multires_versioning.cc similarity index 81% rename from source/blender/blenkernel/intern/multires_versioning.c rename to source/blender/blenkernel/intern/multires_versioning.cc index b7888b9e33a..9f1cc3c8e04 100644 --- a/source/blender/blenkernel/intern/multires_versioning.c +++ b/source/blender/blenkernel/intern/multires_versioning.cc @@ -18,14 +18,14 @@ #include "opensubdiv_converter_capi.h" #include "subdiv_converter.h" -static float simple_to_catmull_clark_get_edge_sharpness( - const OpenSubdiv_Converter *UNUSED(converter), int UNUSED(manifold_edge_index)) +static float simple_to_catmull_clark_get_edge_sharpness(const OpenSubdiv_Converter * /*converter*/, + int /*manifold_edge_index*/) { return 10.0f; } static bool simple_to_catmull_clark_is_infinite_sharp_vertex( - const OpenSubdiv_Converter *UNUSED(converter), int UNUSED(manifold_vertex_index)) + const OpenSubdiv_Converter * /*converter*/, int /*manifold_vertex_index*/) { return true; } @@ -35,7 +35,7 @@ static Subdiv *subdiv_for_simple_to_catmull_clark(Object *object, MultiresModifi SubdivSettings subdiv_settings; BKE_multires_subdiv_settings_init(&subdiv_settings, mmd); - Mesh *base_mesh = object->data; + const Mesh *base_mesh = static_cast(object->data); OpenSubdiv_Converter converter; BKE_subdiv_converter_init_for_mesh(&converter, &subdiv_settings, base_mesh); @@ -45,9 +45,10 @@ static Subdiv *subdiv_for_simple_to_catmull_clark(Object *object, MultiresModifi Subdiv *subdiv = BKE_subdiv_new_from_converter(&subdiv_settings, &converter); BKE_subdiv_converter_free(&converter); - if (!BKE_subdiv_eval_begin_from_mesh(subdiv, base_mesh, NULL, SUBDIV_EVALUATOR_TYPE_CPU, NULL)) { + if (!BKE_subdiv_eval_begin_from_mesh( + subdiv, base_mesh, nullptr, SUBDIV_EVALUATOR_TYPE_CPU, nullptr)) { BKE_subdiv_free(subdiv); - return NULL; + return nullptr; } return subdiv; @@ -55,7 +56,7 @@ static Subdiv *subdiv_for_simple_to_catmull_clark(Object *object, MultiresModifi void multires_do_versions_simple_to_catmull_clark(Object *object, MultiresModifierData *mmd) { - const Mesh *base_mesh = object->data; + const Mesh *base_mesh = static_cast(object->data); if (base_mesh->totloop == 0) { return; } diff --git a/source/blender/blenkernel/intern/subdiv_converter.h b/source/blender/blenkernel/intern/subdiv_converter.h index 1f1674bc87e..88be0306461 100644 --- a/source/blender/blenkernel/intern/subdiv_converter.h +++ b/source/blender/blenkernel/intern/subdiv_converter.h @@ -9,10 +9,6 @@ #include "BKE_subdiv.h" -#ifdef __cplusplus -extern "C" { -#endif - /* NOTE: Was initially used to get proper enumerator types, but this makes * it tricky to compile without OpenSubdiv. */ /* #include "opensubdiv_converter_capi.h" */ @@ -38,7 +34,3 @@ int BKE_subdiv_converter_vtx_boundary_interpolation_from_settings(const SubdivSe /* TODO(sergey): Find a way to make it OpenSubdiv_FVarLinearInterpolation, * without breaking compilation without OpenSubdiv. */ int BKE_subdiv_converter_fvar_linear_from_settings(const SubdivSettings *settings); - -#ifdef __cplusplus -} -#endif From d650162ecd47d6c12e1d66ffbd413e4f3acb120d Mon Sep 17 00:00:00 2001 From: Falk David Date: Fri, 20 Jan 2023 16:32:25 +0100 Subject: [PATCH 0833/1522] Curves: Add initial undo system This adds an `UndoType` for the `Curves` object, for edit mode. For now, this will only store the `CurvesGeometry` at every step. Other properties such as the `selection_domain` or the `surface` object will have to be dealt with in subsequent commits. Differential Revision: https://developer.blender.org/D16979 --- source/blender/editors/curves/CMakeLists.txt | 2 + .../editors/curves/intern/curves_ops.cc | 25 +++- .../editors/curves/intern/curves_undo.cc | 141 ++++++++++++++++++ source/blender/editors/include/ED_curves.h | 3 + source/blender/editors/undo/CMakeLists.txt | 1 + .../blender/editors/undo/undo_system_types.c | 2 + 6 files changed, 168 insertions(+), 6 deletions(-) create mode 100644 source/blender/editors/curves/intern/curves_undo.cc diff --git a/source/blender/editors/curves/CMakeLists.txt b/source/blender/editors/curves/CMakeLists.txt index bba85f9c77a..873df89b40c 100644 --- a/source/blender/editors/curves/CMakeLists.txt +++ b/source/blender/editors/curves/CMakeLists.txt @@ -12,6 +12,7 @@ set(INC ../../makesdna ../../makesrna ../../windowmanager + ../../../../intern/clog ../../../../intern/guardedalloc ../../bmesh @@ -24,6 +25,7 @@ set(SRC intern/curves_data.cc intern/curves_ops.cc intern/curves_selection.cc + intern/curves_undo.cc ) set(LIB diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index d084317014d..24aa362b973 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -60,7 +60,7 @@ namespace blender::ed::curves { -static bool object_has_editable_curves(const Main &bmain, const Object &object) +bool object_has_editable_curves(const Main &bmain, const Object &object) { if (object.type != OB_CURVES) { return false; @@ -95,7 +95,10 @@ VectorSet get_unique_editable_curves(const bContext &C) return unique_curves; } -static bool curves_poll_impl(bContext *C, const bool check_editable, const bool check_surface) +static bool curves_poll_impl(bContext *C, + const bool check_editable, + const bool check_surface, + const bool check_edit_mode) { Object *object = CTX_data_active_object(C); if (object == nullptr || object->type != OB_CURVES) { @@ -113,27 +116,37 @@ static bool curves_poll_impl(bContext *C, const bool check_editable, const bool return false; } } + if (check_edit_mode) { + if ((object->mode & OB_MODE_EDIT) == 0) { + return false; + } + } return true; } +bool editable_curves_in_edit_mode_poll(bContext *C) +{ + return curves_poll_impl(C, true, false, true); +} + bool editable_curves_with_surface_poll(bContext *C) { - return curves_poll_impl(C, true, true); + return curves_poll_impl(C, true, true, false); } bool curves_with_surface_poll(bContext *C) { - return curves_poll_impl(C, false, true); + return curves_poll_impl(C, false, true, false); } bool editable_curves_poll(bContext *C) { - return curves_poll_impl(C, false, false); + return curves_poll_impl(C, false, false, false); } bool curves_poll(bContext *C) { - return curves_poll_impl(C, false, false); + return curves_poll_impl(C, false, false, false); } using bke::CurvesGeometry; diff --git a/source/blender/editors/curves/intern/curves_undo.cc b/source/blender/editors/curves/intern/curves_undo.cc new file mode 100644 index 00000000000..551fbadfefc --- /dev/null +++ b/source/blender/editors/curves/intern/curves_undo.cc @@ -0,0 +1,141 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup edcurves + */ + +#include "BKE_context.h" +#include "BKE_curves.hh" +#include "BKE_main.h" +#include "BKE_object.h" +#include "BKE_undo_system.h" + +#include "CLG_log.h" + +#include "DEG_depsgraph.h" + +#include "ED_curves.h" +#include "ED_undo.h" + +#include "MEM_guardedalloc.h" + +#include "WM_api.h" +#include "WM_types.h" + +static CLG_LogRef LOG = {"ed.undo.curves"}; + +namespace blender::ed::curves::undo { + +/* -------------------------------------------------------------------- */ +/** \name Implements ED Undo System + * + * \note This is similar for all edit-mode types. + * \{ */ + +struct StepObject { + UndoRefID_Object obedit_ref = {}; + bke::CurvesGeometry geometry = {}; +}; + +struct CurvesUndoStep { + UndoStep step; + Array objects; +}; + +static bool step_encode(bContext *C, Main *bmain, UndoStep *us_p) +{ + CurvesUndoStep *us = reinterpret_cast(us_p); + + const Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + uint objects_num = 0; + Object **objects = ED_undo_editmode_objects_from_view_layer(scene, view_layer, &objects_num); + + new (&us->objects) Array(objects_num); + + threading::parallel_for(us->objects.index_range(), 8, [&](const IndexRange range) { + for (const int i : range) { + Object *ob = objects[i]; + const Curves &curves_id = *static_cast(ob->data); + StepObject &object = us->objects[i]; + + object.obedit_ref.ptr = ob; + object.geometry = bke::CurvesGeometry::wrap(curves_id.geometry); + } + }); + MEM_SAFE_FREE(objects); + + bmain->is_memfile_undo_flush_needed = true; + + return true; +} + +static void step_decode( + bContext *C, Main *bmain, UndoStep *us_p, const eUndoStepDir /*dir*/, bool /*is_final*/) +{ + CurvesUndoStep *us = reinterpret_cast(us_p); + + ED_undo_object_editmode_restore_helper(C, + &us->objects.first().obedit_ref.ptr, + us->objects.size(), + sizeof(decltype(us->objects)::value_type)); + + BLI_assert(BKE_object_is_in_editmode(us->objects.first().obedit_ref.ptr)); + + for (const StepObject &object : us->objects) { + Curves &curves_id = *static_cast(object.obedit_ref.ptr->data); + + /* Overwrite the curves geometry. */ + bke::CurvesGeometry::wrap(curves_id.geometry) = object.geometry; + + DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY); + } + + ED_undo_object_set_active_or_warn(CTX_data_scene(C), + CTX_data_view_layer(C), + us->objects.first().obedit_ref.ptr, + us_p->name, + &LOG); + + bmain->is_memfile_undo_flush_needed = true; + + WM_event_add_notifier(C, NC_GEOM | ND_DATA, nullptr); +} + +static void step_free(UndoStep *us_p) +{ + CurvesUndoStep *us = reinterpret_cast(us_p); + us->objects.~Array(); +} + +static void foreach_ID_ref(UndoStep *us_p, + UndoTypeForEachIDRefFn foreach_ID_ref_fn, + void *user_data) +{ + CurvesUndoStep *us = reinterpret_cast(us_p); + + for (const StepObject &object : us->objects) { + foreach_ID_ref_fn(user_data, ((UndoRefID *)&object.obedit_ref)); + } +} + +/** \} */ + +} // namespace blender::ed::curves::undo + +void ED_curves_undosys_type(UndoType *ut) +{ + using namespace blender::ed; + + ut->name = "Edit Curves"; + ut->poll = curves::editable_curves_in_edit_mode_poll; + ut->step_encode = curves::undo::step_encode; + ut->step_decode = curves::undo::step_decode; + ut->step_free = curves::undo::step_free; + + ut->step_foreach_ID_ref = curves::undo::foreach_ID_ref; + + ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE; + + ut->step_size = sizeof(curves::undo::CurvesUndoStep); +} diff --git a/source/blender/editors/include/ED_curves.h b/source/blender/editors/include/ED_curves.h index bf6b78676b9..74eb290e98a 100644 --- a/source/blender/editors/include/ED_curves.h +++ b/source/blender/editors/include/ED_curves.h @@ -18,6 +18,7 @@ extern "C" { * \{ */ void ED_operatortypes_curves(void); +void ED_curves_undosys_type(struct UndoType *ut); /** * Return an owning pointer to an array of point normals the same size as the number of control @@ -43,6 +44,7 @@ float (*ED_curves_point_normals_array_create(const struct Curves *curves_id))[3] namespace blender::ed::curves { +bool object_has_editable_curves(const Main &bmain, const Object &object); bke::CurvesGeometry primitive_random_sphere(int curves_size, int points_per_curve); VectorSet get_unique_editable_curves(const bContext &C); void ensure_surface_deformation_node_exists(bContext &C, Object &curves_ob); @@ -52,6 +54,7 @@ void ensure_surface_deformation_node_exists(bContext &C, Object &curves_ob); * \{ */ bool editable_curves_with_surface_poll(bContext *C); +bool editable_curves_in_edit_mode_poll(bContext *C); bool curves_with_surface_poll(bContext *C); bool editable_curves_poll(bContext *C); bool curves_poll(bContext *C); diff --git a/source/blender/editors/undo/CMakeLists.txt b/source/blender/editors/undo/CMakeLists.txt index 11101bb6b25..cfebb2cab1c 100644 --- a/source/blender/editors/undo/CMakeLists.txt +++ b/source/blender/editors/undo/CMakeLists.txt @@ -29,6 +29,7 @@ set(LIB bf_blenkernel bf_blenlib bf_editor_curve + bf_editor_curves bf_editor_lattice bf_editor_mesh bf_editor_metaball diff --git a/source/blender/editors/undo/undo_system_types.c b/source/blender/editors/undo/undo_system_types.c index a4d6df9b5c2..af74a7f3c04 100644 --- a/source/blender/editors/undo/undo_system_types.c +++ b/source/blender/editors/undo/undo_system_types.c @@ -10,6 +10,7 @@ #include "ED_armature.h" #include "ED_curve.h" +#include "ED_curves.h" #include "ED_lattice.h" #include "ED_mball.h" #include "ED_mesh.h" @@ -32,6 +33,7 @@ void ED_undosys_type_init(void) BKE_undosys_type_append(ED_lattice_undosys_type); BKE_undosys_type_append(ED_mball_undosys_type); BKE_undosys_type_append(ED_mesh_undosys_type); + BKE_undosys_type_append(ED_curves_undosys_type); /* Paint Modes */ BKE_UNDOSYS_TYPE_IMAGE = BKE_undosys_type_append(ED_image_undosys_type); From 70ca15670d9f6d7179d1fe150939582c91174c29 Mon Sep 17 00:00:00 2001 From: Falk David Date: Fri, 20 Jan 2023 16:40:51 +0100 Subject: [PATCH 0834/1522] Curves: Edit mode selection operators This adds the following operators to edit mode: - `select_all` - `select_random` - `select_end` Differential Revision: https://developer.blender.org/D17047 --- .../bl_keymap_utils/keymap_hierarchy.py | 1 + .../keyconfig/keymap_data/blender_default.py | 8 + release/scripts/startup/bl_ui/space_view3d.py | 12 +- .../editors/curves/intern/curves_ops.cc | 227 +++++++++++------- .../editors/curves/intern/curves_selection.cc | 183 +++++++++++++- source/blender/editors/include/ED_curves.h | 37 ++- .../editors/sculpt_paint/curves_sculpt_ops.cc | 87 +------ source/blender/editors/space_api/spacetypes.c | 1 + .../editors/space_view3d/space_view3d.cc | 3 + 9 files changed, 368 insertions(+), 191 deletions(-) diff --git a/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py b/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py index 7172d7809f2..f183877749c 100644 --- a/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py +++ b/release/scripts/modules/bl_keymap_utils/keymap_hierarchy.py @@ -55,6 +55,7 @@ _km_hierarchy = [ ('Curve', 'EMPTY', 'WINDOW', [ _km_expand_from_toolsystem('VIEW_3D', 'EDIT_CURVE'), ]), + ('Curves', 'EMPTY', 'WINDOW', []), ('Armature', 'EMPTY', 'WINDOW', [ _km_expand_from_toolsystem('VIEW_3D', 'EDIT_ARMATURE'), ]), diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 19093e51ec5..4149377581c 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -5615,6 +5615,14 @@ def km_curves(params): {"items": items}, ) + items.extend([ + ("curves.set_selection_domain", {"type": 'ONE', "value": 'PRESS'}, {"properties": [("domain", 'POINT')]}), + ("curves.set_selection_domain", {"type": 'TWO', "value": 'PRESS'}, {"properties": [("domain", 'CURVE')]}), + ("curves.disable_selection", {"type": 'ONE', "value": 'PRESS', "alt": True}, None), + ("curves.disable_selection", {"type": 'TWO', "value": 'PRESS', "alt": True}, None), + *_template_items_select_actions(params, "curves.select_all"), + ]) + return keymap diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 3bb009dd2ad..938399485d3 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -718,7 +718,7 @@ class VIEW3D_HT_header(Header): if object_mode == 'PARTICLE_EDIT': row = layout.row() row.prop(tool_settings.particle_edit, "select_mode", text="", expand=True) - elif object_mode == 'SCULPT_CURVES' and obj.type == 'CURVES': + elif object_mode in {'EDIT', 'SCULPT_CURVES'} and obj.type == 'CURVES': curves = obj.data row = layout.row(align=True) @@ -2044,7 +2044,13 @@ class VIEW3D_MT_select_edit_curves(Menu): bl_label = "Select" def draw(self, _context): - pass + layout = self.layout + + layout.operator("curves.select_all", text="All").action = 'SELECT' + layout.operator("curves.select_all", text="None").action = 'DESELECT' + layout.operator("curves.select_all", text="Invert").action = 'INVERT' + layout.operator("curves.select_random", text="Random") + layout.operator("curves.select_end", text="Endpoints") class VIEW3D_MT_select_sculpt_curves(Menu): @@ -2057,7 +2063,7 @@ class VIEW3D_MT_select_sculpt_curves(Menu): layout.operator("curves.select_all", text="None").action = 'DESELECT' layout.operator("curves.select_all", text="Invert").action = 'INVERT' layout.operator("sculpt_curves.select_random", text="Random") - layout.operator("sculpt_curves.select_end", text="Endpoints") + layout.operator("curves.select_end", text="Endpoints") layout.operator("sculpt_curves.select_grow", text="Grow") diff --git a/source/blender/editors/curves/intern/curves_ops.cc b/source/blender/editors/curves/intern/curves_ops.cc index 24aa362b973..d0a68774c71 100644 --- a/source/blender/editors/curves/intern/curves_ops.cc +++ b/source/blender/editors/curves/intern/curves_ops.cc @@ -7,7 +7,10 @@ #include #include "BLI_array_utils.hh" +#include "BLI_devirtualize_parameters.hh" #include "BLI_index_mask_ops.hh" +#include "BLI_kdtree.h" +#include "BLI_rand.hh" #include "BLI_utildefines.h" #include "BLI_vector_set.hh" @@ -15,6 +18,7 @@ #include "ED_object.h" #include "ED_screen.h" #include "ED_select_utils.h" +#include "ED_view3d.h" #include "WM_api.h" @@ -48,6 +52,9 @@ #include "RNA_enum_types.h" #include "RNA_prototypes.h" +#include "UI_interface.h" +#include "UI_resources.h" + #include "GEO_reverse_uv_sampler.hh" /** @@ -820,77 +827,13 @@ static void CURVES_OT_set_selection_domain(wmOperatorType *ot) RNA_def_property_flag(prop, (PropertyFlag)(PROP_HIDDEN | PROP_SKIP_SAVE)); } -static bool contains(const VArray &varray, const bool value) -{ - const CommonVArrayInfo info = varray.common_info(); - if (info.type == CommonVArrayInfo::Type::Single) { - return *static_cast(info.data) == value; - } - if (info.type == CommonVArrayInfo::Type::Span) { - const Span span(static_cast(info.data), varray.size()); - return threading::parallel_reduce( - span.index_range(), - 4096, - false, - [&](const IndexRange range, const bool init) { - return init || span.slice(range).contains(value); - }, - [&](const bool a, const bool b) { return a || b; }); - } - return threading::parallel_reduce( - varray.index_range(), - 2048, - false, - [&](const IndexRange range, const bool init) { - if (init) { - return init; - } - /* Alternatively, this could use #materialize to retrieve many values at once. */ - for (const int64_t i : range) { - if (varray[i] == value) { - return true; - } - } - return false; - }, - [&](const bool a, const bool b) { return a || b; }); -} - -bool has_anything_selected(const Curves &curves_id) -{ - const CurvesGeometry &curves = CurvesGeometry::wrap(curves_id.geometry); - const VArray selection = curves.attributes().lookup(".selection"); - return !selection || contains(selection, true); -} - static bool has_anything_selected(const Span curves_ids) { return std::any_of(curves_ids.begin(), curves_ids.end(), [](const Curves *curves_id) { - return has_anything_selected(*curves_id); + return has_anything_selected(CurvesGeometry::wrap(curves_id->geometry)); }); } -namespace select_all { - -static void invert_selection(MutableSpan selection) -{ - threading::parallel_for(selection.index_range(), 2048, [&](IndexRange range) { - for (const int i : range) { - selection[i] = 1.0f - selection[i]; - } - }); -} - -static void invert_selection(GMutableSpan selection) -{ - if (selection.type().is()) { - array_utils::invert_booleans(selection.typed()); - } - else if (selection.type().is()) { - invert_selection(selection.typed()); - } -} - static int select_all_exec(bContext *C, wmOperator *op) { int action = RNA_enum_get(op->ptr, "action"); @@ -902,31 +845,10 @@ static int select_all_exec(bContext *C, wmOperator *op) } for (Curves *curves_id : unique_curves) { - CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry); - bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); - if (action == SEL_SELECT) { - /* As an optimization, just remove the selection attributes when everything is selected. */ - attributes.remove(".selection"); - } - else if (!attributes.contains(".selection")) { - BLI_assert(ELEM(action, SEL_INVERT, SEL_DESELECT)); - /* If the attribute doesn't exist and it's either deleted or inverted, create - * it with nothing selected, since that means everything was selected before. */ - attributes.add(".selection", - eAttrDomain(curves_id->selection_domain), - CD_PROP_BOOL, - bke::AttributeInitDefaultValue()); - } - else { - bke::GSpanAttributeWriter selection = attributes.lookup_for_write_span(".selection"); - if (action == SEL_DESELECT) { - fill_selection_false(selection.span); - } - else if (action == SEL_INVERT) { - invert_selection(selection.span); - } - selection.finish(); - } + /* (De)select all the curves. */ + select_all(CurvesGeometry::wrap(curves_id->geometry), + eAttrDomain(curves_id->selection_domain), + action); /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic * attribute for now. */ @@ -937,15 +859,13 @@ static int select_all_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -} // namespace select_all - static void CURVES_OT_select_all(wmOperatorType *ot) { ot->name = "(De)select All"; ot->idname = "CURVES_OT_select_all"; ot->description = "(De)select all control points"; - ot->exec = select_all::select_all_exec; + ot->exec = select_all_exec; ot->poll = editable_curves_poll; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -953,6 +873,117 @@ static void CURVES_OT_select_all(wmOperatorType *ot) WM_operator_properties_select_all(ot); } +static int select_random_exec(bContext *C, wmOperator *op) +{ + VectorSet unique_curves = curves::get_unique_editable_curves(*C); + + const int seed = RNA_int_get(op->ptr, "seed"); + const float probability = RNA_float_get(op->ptr, "probability"); + + for (Curves *curves_id : unique_curves) { + CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry); + select_random(curves, eAttrDomain(curves_id->selection_domain), uint32_t(seed), probability); + + /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic + * attribute for now. */ + DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id); + } + return OPERATOR_FINISHED; +} + +static void select_random_ui(bContext * /*C*/, wmOperator *op) +{ + uiLayout *layout = op->layout; + + uiItemR(layout, op->ptr, "seed", 0, nullptr, ICON_NONE); + uiItemR(layout, op->ptr, "probability", UI_ITEM_R_SLIDER, "Probability", ICON_NONE); +} + +static void CURVES_OT_select_random(wmOperatorType *ot) +{ + ot->name = "Select Random"; + ot->idname = __func__; + ot->description = "Randomizes existing selection or create new random selection"; + + ot->exec = select_random_exec; + ot->poll = curves::editable_curves_poll; + ot->ui = select_random_ui; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_int(ot->srna, + "seed", + 0, + INT32_MIN, + INT32_MAX, + "Seed", + "Source of randomness", + INT32_MIN, + INT32_MAX); + RNA_def_float(ot->srna, + "probability", + 0.5f, + 0.0f, + 1.0f, + "Probability", + "Chance of every point or curve being included in the selection", + 0.0f, + 1.0f); +} + +static bool select_end_poll(bContext *C) +{ + if (!curves::editable_curves_poll(C)) { + return false; + } + const Curves *curves_id = static_cast(CTX_data_active_object(C)->data); + if (curves_id->selection_domain != ATTR_DOMAIN_POINT) { + CTX_wm_operator_poll_msg_set(C, "Only available in point selection mode"); + return false; + } + return true; +} + +static int select_end_exec(bContext *C, wmOperator *op) +{ + VectorSet unique_curves = curves::get_unique_editable_curves(*C); + const bool end_points = RNA_boolean_get(op->ptr, "end_points"); + const int amount = RNA_int_get(op->ptr, "amount"); + + for (Curves *curves_id : unique_curves) { + CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry); + select_ends(curves, eAttrDomain(curves_id->selection_domain), amount, end_points); + + /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic + * attribute for now. */ + DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id); + } + + return OPERATOR_FINISHED; +} + +static void CURVES_OT_select_end(wmOperatorType *ot) +{ + ot->name = "Select End"; + ot->idname = __func__; + ot->description = "Select end points of curves"; + + ot->exec = select_end_exec; + ot->poll = select_end_poll; + + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, + "end_points", + true, + "End Points", + "Select points at the end of the curve as opposed to the beginning"); + RNA_def_int( + ot->srna, "amount", 1, 0, INT32_MAX, "Amount", "Number of points to select", 0, INT32_MAX); +} + namespace surface_set { static bool surface_set_poll(bContext *C) @@ -1046,5 +1077,15 @@ void ED_operatortypes_curves() WM_operatortype_append(CURVES_OT_snap_curves_to_surface); WM_operatortype_append(CURVES_OT_set_selection_domain); WM_operatortype_append(CURVES_OT_select_all); + WM_operatortype_append(CURVES_OT_select_random); + WM_operatortype_append(CURVES_OT_select_end); WM_operatortype_append(CURVES_OT_surface_set); } + +void ED_keymap_curves(wmKeyConfig *keyconf) +{ + using namespace blender::ed::curves; + /* Only set in editmode curves, by space_view3d listener. */ + wmKeyMap *keymap = WM_keymap_ensure(keyconf, "Curves", 0, 0); + keymap->poll = editable_curves_poll; +} diff --git a/source/blender/editors/curves/intern/curves_selection.cc b/source/blender/editors/curves/intern/curves_selection.cc index b9b3be976c5..9ed25473a0c 100644 --- a/source/blender/editors/curves/intern/curves_selection.cc +++ b/source/blender/editors/curves/intern/curves_selection.cc @@ -4,13 +4,16 @@ * \ingroup edcurves */ +#include "BLI_array_utils.hh" #include "BLI_index_mask_ops.hh" +#include "BLI_rand.hh" #include "BKE_attribute.hh" #include "BKE_curves.hh" #include "ED_curves.h" #include "ED_object.h" +#include "ED_select_utils.h" namespace blender::ed::curves { @@ -69,31 +72,32 @@ IndexMask retrieve_selected_points(const Curves &curves_id, Vector &r_i return retrieve_selected_points(curves, r_indices); } -void ensure_selection_attribute(Curves &curves_id, const eCustomDataType create_type) +bke::GSpanAttributeWriter ensure_selection_attribute(bke::CurvesGeometry &curves, + const eAttrDomain selection_domain, + const eCustomDataType create_type) { - bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id.geometry); bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); if (attributes.contains(".selection")) { - return; + return attributes.lookup_for_write_span(".selection"); } - const eAttrDomain domain = eAttrDomain(curves_id.selection_domain); - const int domain_size = attributes.domain_size(domain); + const int domain_size = attributes.domain_size(selection_domain); switch (create_type) { case CD_PROP_BOOL: attributes.add(".selection", - domain, + selection_domain, CD_PROP_BOOL, bke::AttributeInitVArray(VArray::ForSingle(true, domain_size))); break; case CD_PROP_FLOAT: attributes.add(".selection", - domain, + selection_domain, CD_PROP_FLOAT, bke::AttributeInitVArray(VArray::ForSingle(1.0f, domain_size))); break; default: BLI_assert_unreachable(); } + return attributes.lookup_for_write_span(".selection"); } void fill_selection_false(GMutableSpan selection) @@ -105,6 +109,7 @@ void fill_selection_false(GMutableSpan selection) selection.typed().fill(0.0f); } } + void fill_selection_true(GMutableSpan selection) { if (selection.type().is()) { @@ -115,4 +120,168 @@ void fill_selection_true(GMutableSpan selection) } } +static bool contains(const VArray &varray, const bool value) +{ + const CommonVArrayInfo info = varray.common_info(); + if (info.type == CommonVArrayInfo::Type::Single) { + return *static_cast(info.data) == value; + } + if (info.type == CommonVArrayInfo::Type::Span) { + const Span span(static_cast(info.data), varray.size()); + return threading::parallel_reduce( + span.index_range(), + 4096, + false, + [&](const IndexRange range, const bool init) { + return init || span.slice(range).contains(value); + }, + [&](const bool a, const bool b) { return a || b; }); + } + return threading::parallel_reduce( + varray.index_range(), + 2048, + false, + [&](const IndexRange range, const bool init) { + if (init) { + return init; + } + /* Alternatively, this could use #materialize to retrieve many values at once. */ + for (const int64_t i : range) { + if (varray[i] == value) { + return true; + } + } + return false; + }, + [&](const bool a, const bool b) { return a || b; }); +} + +bool has_anything_selected(const bke::CurvesGeometry &curves) +{ + const VArray selection = curves.attributes().lookup(".selection"); + return !selection || contains(selection, true); +} + +static void invert_selection(MutableSpan selection) +{ + threading::parallel_for(selection.index_range(), 2048, [&](IndexRange range) { + for (const int i : range) { + selection[i] = 1.0f - selection[i]; + } + }); +} + +static void invert_selection(GMutableSpan selection) +{ + if (selection.type().is()) { + array_utils::invert_booleans(selection.typed()); + } + else if (selection.type().is()) { + invert_selection(selection.typed()); + } +} + +void select_all(bke::CurvesGeometry &curves, const eAttrDomain selection_domain, int action) +{ + bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); + if (action == SEL_SELECT) { + /* As an optimization, just remove the selection attributes when everything is selected. */ + attributes.remove(".selection"); + } + else { + bke::GSpanAttributeWriter selection = ensure_selection_attribute( + curves, selection_domain, CD_PROP_BOOL); + if (action == SEL_DESELECT) { + fill_selection_false(selection.span); + } + else if (action == SEL_INVERT) { + invert_selection(selection.span); + } + selection.finish(); + } +} + +void select_ends(bke::CurvesGeometry &curves, + const eAttrDomain selection_domain, + int amount, + bool end_points) +{ + const bool was_anything_selected = has_anything_selected(curves); + bke::GSpanAttributeWriter selection = ensure_selection_attribute( + curves, selection_domain, CD_PROP_BOOL); + if (!was_anything_selected) { + fill_selection_true(selection.span); + } + selection.span.type().to_static_type_tag([&](auto type_tag) { + using T = typename decltype(type_tag)::type; + if constexpr (std::is_void_v) { + BLI_assert_unreachable(); + } + else { + MutableSpan selection_typed = selection.span.typed(); + threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) { + for (const int curve_i : range) { + const OffsetIndices points_by_curve = curves.points_by_curve(); + if (end_points) { + selection_typed.slice(points_by_curve[curve_i].drop_back(amount)).fill(T(0)); + } + else { + selection_typed.slice(points_by_curve[curve_i].drop_front(amount)).fill(T(0)); + } + } + }); + } + }); + selection.finish(); +} + +void select_random(bke::CurvesGeometry &curves, + const eAttrDomain selection_domain, + uint32_t random_seed, + float probability) +{ + RandomNumberGenerator rng{random_seed}; + const auto next_bool_random_value = [&]() { return rng.get_float() <= probability; }; + + const bool was_anything_selected = has_anything_selected(curves); + bke::GSpanAttributeWriter selection = ensure_selection_attribute( + curves, selection_domain, CD_PROP_BOOL); + if (!was_anything_selected) { + curves::fill_selection_true(selection.span); + } + selection.span.type().to_static_type_tag([&](auto type_tag) { + using T = typename decltype(type_tag)::type; + if constexpr (std::is_void_v) { + BLI_assert_unreachable(); + } + else { + MutableSpan selection_typed = selection.span.typed(); + switch (selection_domain) { + case ATTR_DOMAIN_POINT: { + for (const int point_i : selection_typed.index_range()) { + const bool random_value = next_bool_random_value(); + if (!random_value) { + selection_typed[point_i] = T(0); + } + } + + break; + } + case ATTR_DOMAIN_CURVE: { + for (const int curve_i : curves.curves_range()) { + const bool random_value = next_bool_random_value(); + if (!random_value) { + selection_typed[curve_i] = T(0); + } + } + break; + } + default: + BLI_assert_unreachable(); + } + } + }); + selection.finish(); +} + } // namespace blender::ed::curves diff --git a/source/blender/editors/include/ED_curves.h b/source/blender/editors/include/ED_curves.h index 74eb290e98a..9cb673ff9e4 100644 --- a/source/blender/editors/include/ED_curves.h +++ b/source/blender/editors/include/ED_curves.h @@ -19,6 +19,7 @@ extern "C" { void ED_operatortypes_curves(void); void ED_curves_undosys_type(struct UndoType *ut); +void ED_keymap_curves(struct wmKeyConfig *keyconf); /** * Return an owning pointer to an array of point normals the same size as the number of control @@ -80,7 +81,7 @@ void fill_selection_true(GMutableSpan span); /** * Return true if any element is selected, on either domain with either type. */ -bool has_anything_selected(const Curves &curves_id); +bool has_anything_selected(const bke::CurvesGeometry &curves); /** * Find curves that have any point selected (a selection factor greater than zero), @@ -97,8 +98,40 @@ IndexMask retrieve_selected_points(const Curves &curves_id, Vector &r_i /** * If the ".selection" attribute doesn't exist, create it with the requested type (bool or float). */ -void ensure_selection_attribute(Curves &curves_id, const eCustomDataType create_type); +bke::GSpanAttributeWriter ensure_selection_attribute(bke::CurvesGeometry &curves, + const eAttrDomain selection_domain, + const eCustomDataType create_type); +/** + * (De)select all the curves. + * + * \param action: One of SEL_TOGGLE, SEL_SELECT, SEL_DESELECT, or SEL_INVERT. See + * "ED_select_utils.h". + */ +void select_all(bke::CurvesGeometry &curves, const eAttrDomain selection_domain, int action); + +/** + * Select the ends (front or back) of all the curves. + * + * \param amount: The amount of points to select from the front or back. + * \param end_points: If true, select the last point(s), if false, select the first point(s). + */ +void select_ends(bke::CurvesGeometry &curves, + const eAttrDomain selection_domain, + int amount, + bool end_points); + +/** + * Select random points or curves. + * + * \param random_seed: The seed for the \a RandomNumberGenerator. + * \param probability: Determins how likely a point/curve will be selected. If set to 0.0, nothing + * will be selected, if set to 1.0 everything will be selected. + */ +void select_random(bke::CurvesGeometry &curves, + const eAttrDomain selection_domain, + uint32_t random_seed, + float probability); /** \} */ } // namespace blender::ed::curves diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc index 444ab821cf1..39575015381 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc @@ -363,7 +363,7 @@ static int select_random_exec(bContext *C, wmOperator *op) for (Curves *curves_id : unique_curves) { CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry); - const bool was_anything_selected = curves::has_anything_selected(*curves_id); + const bool was_anything_selected = curves::has_anything_selected(curves); bke::SpanAttributeWriter attribute = float_selection_ensure(*curves_id); MutableSpan selection = attribute.span; @@ -517,90 +517,6 @@ static void SCULPT_CURVES_OT_select_random(wmOperatorType *ot) "Constant per Curve", "The generated random number is the same for every control point of a curve"); } - -namespace select_end { -static bool select_end_poll(bContext *C) -{ - if (!curves::editable_curves_poll(C)) { - return false; - } - const Curves *curves_id = static_cast(CTX_data_active_object(C)->data); - if (curves_id->selection_domain != ATTR_DOMAIN_POINT) { - CTX_wm_operator_poll_msg_set(C, "Only available in point selection mode"); - return false; - } - return true; -} - -static int select_end_exec(bContext *C, wmOperator *op) -{ - VectorSet unique_curves = curves::get_unique_editable_curves(*C); - const bool end_points = RNA_boolean_get(op->ptr, "end_points"); - const int amount = RNA_int_get(op->ptr, "amount"); - - for (Curves *curves_id : unique_curves) { - CurvesGeometry &curves = CurvesGeometry::wrap(curves_id->geometry); - bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); - - const bool was_anything_selected = curves::has_anything_selected(*curves_id); - curves::ensure_selection_attribute(*curves_id, CD_PROP_BOOL); - bke::GSpanAttributeWriter selection = attributes.lookup_for_write_span(".selection"); - if (!was_anything_selected) { - curves::fill_selection_true(selection.span); - } - const OffsetIndices points_by_curve = curves.points_by_curve(); - selection.span.type().to_static_type_tag([&](auto type_tag) { - using T = typename decltype(type_tag)::type; - if constexpr (std::is_void_v) { - BLI_assert_unreachable(); - } - else { - MutableSpan selection_typed = selection.span.typed(); - threading::parallel_for(curves.curves_range(), 256, [&](const IndexRange range) { - for (const int curve_i : range) { - const IndexRange points = points_by_curve[curve_i]; - if (end_points) { - selection_typed.slice(points.drop_back(amount)).fill(T(0)); - } - else { - selection_typed.slice(points.drop_front(amount)).fill(T(0)); - } - } - }); - } - }); - selection.finish(); - - /* Use #ID_RECALC_GEOMETRY instead of #ID_RECALC_SELECT because it is handled as a generic - * attribute for now. */ - DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, curves_id); - } - - return OPERATOR_FINISHED; -} -} // namespace select_end - -static void SCULPT_CURVES_OT_select_end(wmOperatorType *ot) -{ - ot->name = "Select End"; - ot->idname = __func__; - ot->description = "Select end points of curves"; - - ot->exec = select_end::select_end_exec; - ot->poll = select_end::select_end_poll; - - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_boolean(ot->srna, - "end_points", - true, - "End Points", - "Select points at the end of the curve as opposed to the beginning"); - RNA_def_int( - ot->srna, "amount", 1, 0, INT32_MAX, "Amount", "Number of points to select", 0, INT32_MAX); -} - namespace select_grow { struct GrowOperatorDataPerCurve : NonCopyable, NonMovable { @@ -1263,7 +1179,6 @@ void ED_operatortypes_sculpt_curves() WM_operatortype_append(SCULPT_CURVES_OT_brush_stroke); WM_operatortype_append(CURVES_OT_sculptmode_toggle); WM_operatortype_append(SCULPT_CURVES_OT_select_random); - WM_operatortype_append(SCULPT_CURVES_OT_select_end); WM_operatortype_append(SCULPT_CURVES_OT_select_grow); WM_operatortype_append(SCULPT_CURVES_OT_min_distance_edit); } diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 3d964a95bc0..9690d8bd860 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -186,6 +186,7 @@ void ED_spacetypes_keymap(wmKeyConfig *keyconf) ED_keymap_mesh(keyconf); ED_keymap_uvedit(keyconf); ED_keymap_curve(keyconf); + ED_keymap_curves(keyconf); ED_keymap_armature(keyconf); ED_keymap_physics(keyconf); ED_keymap_metaball(keyconf); diff --git a/source/blender/editors/space_view3d/space_view3d.cc b/source/blender/editors/space_view3d/space_view3d.cc index 05fb0c6a720..396e75f6b4e 100644 --- a/source/blender/editors/space_view3d/space_view3d.cc +++ b/source/blender/editors/space_view3d/space_view3d.cc @@ -407,6 +407,9 @@ static void view3d_main_region_init(wmWindowManager *wm, ARegion *region) keymap = WM_keymap_ensure(wm->defaultconf, "Curve", 0, 0); WM_event_add_keymap_handler(®ion->handlers, keymap); + keymap = WM_keymap_ensure(wm->defaultconf, "Curves", 0, 0); + WM_event_add_keymap_handler(®ion->handlers, keymap); + keymap = WM_keymap_ensure(wm->defaultconf, "Image Paint", 0, 0); WM_event_add_keymap_handler(®ion->handlers, keymap); From f31f7e3ef0bd0a079182328eef5458fcef38f7b0 Mon Sep 17 00:00:00 2001 From: Thomas Dinges Date: Fri, 20 Jan 2023 17:36:48 +0100 Subject: [PATCH 0835/1522] Cleanup: Remove unused light_sample_is_light() function. This also fixes compile warnings on MSVC. --- intern/cycles/kernel/integrator/shade_surface.h | 2 -- intern/cycles/kernel/integrator/shade_volume.h | 1 - intern/cycles/kernel/light/sample.h | 7 ------- 3 files changed, 10 deletions(-) diff --git a/intern/cycles/kernel/integrator/shade_surface.h b/intern/cycles/kernel/integrator/shade_surface.h index 09433caa063..dbeb5f91ce7 100644 --- a/intern/cycles/kernel/integrator/shade_surface.h +++ b/intern/cycles/kernel/integrator/shade_surface.h @@ -235,8 +235,6 @@ ccl_device_forceinline void integrate_surface_direct_light(KernelGlobals kg, light_sample_to_surface_shadow_ray(kg, sd, &ls, &ray); } - const bool is_light = light_sample_is_light(&ls); - /* Branch off shadow kernel. */ IntegratorShadowState shadow_state = integrator_shadow_path_init( kg, state, DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW, false); diff --git a/intern/cycles/kernel/integrator/shade_volume.h b/intern/cycles/kernel/integrator/shade_volume.h index 98dc5603a78..5b460a2fe7a 100644 --- a/intern/cycles/kernel/integrator/shade_volume.h +++ b/intern/cycles/kernel/integrator/shade_volume.h @@ -821,7 +821,6 @@ ccl_device_forceinline void integrate_volume_direct_light( /* Create shadow ray. */ Ray ray ccl_optional_struct_init; light_sample_to_volume_shadow_ray(kg, sd, &ls, P, &ray); - const bool is_light = light_sample_is_light(&ls); /* Branch off shadow kernel. */ IntegratorShadowState shadow_state = integrator_shadow_path_init( diff --git a/intern/cycles/kernel/light/sample.h b/intern/cycles/kernel/light/sample.h index 423024c6b3d..f56ca19e968 100644 --- a/intern/cycles/kernel/light/sample.h +++ b/intern/cycles/kernel/light/sample.h @@ -88,13 +88,6 @@ light_sample_shader_eval(KernelGlobals kg, return eval; } -/* Test if light sample is from a light or emission from geometry. */ -ccl_device_inline bool light_sample_is_light(ccl_private const LightSample *ccl_restrict ls) -{ - /* return if it's a lamp for shadow pass */ - return (ls->prim == PRIM_NONE && ls->type != LIGHT_BACKGROUND); -} - /* Early path termination of shadow rays. */ ccl_device_inline bool light_sample_terminate(KernelGlobals kg, ccl_private const LightSample *ccl_restrict ls, From 60ea01aa30d36a5bb81649142d38786d00fa3481 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 20 Jan 2023 11:55:43 -0600 Subject: [PATCH 0836/1522] Cleanup: Move four sculpt/paint files to C++ For continued refactoring of the Mesh data structure. See T103343. --- .../editors/sculpt_paint/CMakeLists.txt | 8 +- .../{paint_mask.c => paint_mask.cc} | 324 +++++++++--------- ...eight_ops.c => paint_vertex_weight_ops.cc} | 158 +++++---- .../{sculpt_expand.c => sculpt_expand.cc} | 141 ++++---- .../{sculpt_geodesic.c => sculpt_geodesic.cc} | 17 +- 5 files changed, 335 insertions(+), 313 deletions(-) rename source/blender/editors/sculpt_paint/{paint_mask.c => paint_mask.cc} (88%) rename source/blender/editors/sculpt_paint/{paint_vertex_weight_ops.c => paint_vertex_weight_ops.cc} (87%) rename source/blender/editors/sculpt_paint/{sculpt_expand.c => sculpt_expand.cc} (94%) rename source/blender/editors/sculpt_paint/{sculpt_geodesic.c => sculpt_geodesic.cc} (96%) diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index 62a07310106..35fc4ba705e 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -51,14 +51,14 @@ set(SRC paint_image_2d_curve_mask.cc paint_image_ops_paint.cc paint_image_proj.cc - paint_mask.c + paint_mask.cc paint_ops.c paint_stroke.c paint_utils.c paint_vertex.cc paint_vertex_color_ops.cc paint_vertex_proj.c - paint_vertex_weight_ops.c + paint_vertex_weight_ops.cc paint_vertex_weight_utils.c sculpt.cc sculpt_automasking.cc @@ -67,12 +67,12 @@ set(SRC sculpt_cloth.c sculpt_detail.c sculpt_dyntopo.cc - sculpt_expand.c + sculpt_expand.cc sculpt_face_set.cc sculpt_filter_color.c sculpt_filter_mask.c sculpt_filter_mesh.c - sculpt_geodesic.c + sculpt_geodesic.cc sculpt_mask_expand.c sculpt_mask_init.c sculpt_multiplane_scrape.c diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.cc similarity index 88% rename from source/blender/editors/sculpt_paint/paint_mask.c rename to source/blender/editors/sculpt_paint/paint_mask.cc index 26d3b4fead9..c0f4ddf4218 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.cc @@ -5,6 +5,8 @@ * \ingroup edsculpt */ +#include + #include "MEM_guardedalloc.h" #include "DNA_mesh_types.h" @@ -13,7 +15,6 @@ #include "DNA_object_types.h" #include "DNA_vec_types.h" -#include "BLI_alloca.h" #include "BLI_bitmap_draw_2d.h" #include "BLI_lasso_2d.h" #include "BLI_math_geom.h" @@ -53,8 +54,6 @@ /* For undo push. */ #include "sculpt_intern.h" -#include - static const EnumPropertyItem mode_items[] = { {PAINT_MASK_FLOOD_VALUE, "VALUE", @@ -84,7 +83,7 @@ static void mask_flood_fill_set_elem(float *elem, PaintMaskFloodMode mode, float } } -typedef struct MaskTaskData { +struct MaskTaskData { Object *ob; PBVH *pbvh; PBVHNode **nodes; @@ -96,13 +95,13 @@ typedef struct MaskTaskData { bool front_faces_only; float view_normal[3]; -} MaskTaskData; +}; static void mask_flood_fill_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - MaskTaskData *data = userdata; + MaskTaskData *data = static_cast(userdata); PBVHNode *node = data->nodes[i]; @@ -136,15 +135,13 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) const Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - PaintMaskFloodMode mode; - float value; PBVH *pbvh; PBVHNode **nodes; int totnode; bool multires; - mode = RNA_enum_get(op->ptr, "mode"); - value = RNA_float_get(op->ptr, "value"); + PaintMaskFloodMode mode = PaintMaskFloodMode(RNA_enum_get(op->ptr, "mode")); + float value = RNA_float_get(op->ptr, "value"); MultiresModifierData *mmd = BKE_sculpt_multires_active(scene, ob); BKE_sculpt_mask_layers_ensure(depsgraph, CTX_data_main(C), ob, mmd); @@ -153,18 +150,17 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) pbvh = ob->sculpt->pbvh; multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS); - BKE_pbvh_search_gather(pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(pbvh, nullptr, nullptr, &nodes, &totnode); SCULPT_undo_push_begin(ob, op); - MaskTaskData data = { - .ob = ob, - .pbvh = pbvh, - .nodes = nodes, - .multires = multires, - .mode = mode, - .value = value, - }; + MaskTaskData data{}; + data.ob = ob; + data.pbvh = pbvh; + data.nodes = nodes; + data.multires = multires; + data.mode = mode; + data.value = value; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -187,7 +183,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot) +void PAINT_OT_mask_flood_fill(wmOperatorType *ot) { /* Identifiers. */ ot->name = "Mask Flood Fill"; @@ -201,7 +197,7 @@ void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot) ot->flag = OPTYPE_REGISTER; /* RNA. */ - RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", NULL); + RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", nullptr); RNA_def_float( ot->srna, "value", @@ -216,13 +212,13 @@ void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot) /* Sculpt Gesture Operators. */ -typedef enum eSculptGestureShapeType { +enum eSculptGestureShapeType { SCULPT_GESTURE_SHAPE_BOX, SCULPT_GESTURE_SHAPE_LASSO, SCULPT_GESTURE_SHAPE_LINE, -} eMaskGesturesShapeType; +}; -typedef struct LassoGestureData { +struct LassoGestureData { float projviewobjmat[4][4]; rcti boundbox; @@ -230,9 +226,9 @@ typedef struct LassoGestureData { /* 2D bitmap to test if a vertex is affected by the lasso shape. */ BLI_bitmap *mask_px; -} LassoGestureData; +}; -typedef struct LineGestureData { +struct LineGestureData { /* Plane aligned to the gesture line. */ float true_plane[4]; float plane[4]; @@ -244,11 +240,11 @@ typedef struct LineGestureData { bool use_side_planes; bool flip; -} LineGestureData; +}; struct SculptGestureOperation; -typedef struct SculptGestureContext { +struct SculptGestureContext { SculptSession *ss; ViewContext vc; @@ -257,10 +253,10 @@ typedef struct SculptGestureContext { ePaintSymmetryFlags symmpass; /* Operation parameters. */ - eMaskGesturesShapeType shape_type; + eSculptGestureShapeType shape_type; bool front_faces_only; - struct SculptGestureOperation *operation; + SculptGestureOperation *operation; /* Gesture data. */ /* Screen space points that represent the gesture shape. */ @@ -294,19 +290,19 @@ typedef struct SculptGestureContext { /* Task Callback Data. */ PBVHNode **nodes; int totnode; -} SculptGestureContext; +}; -typedef struct SculptGestureOperation { +struct SculptGestureOperation { /* Initial setup (data updates, special undo push...). */ - void (*sculpt_gesture_begin)(struct bContext *, SculptGestureContext *); + void (*sculpt_gesture_begin)(bContext *, SculptGestureContext *); /* Apply the gesture action for each symmetry pass. */ - void (*sculpt_gesture_apply_for_symmetry_pass)(struct bContext *, SculptGestureContext *); + void (*sculpt_gesture_apply_for_symmetry_pass)(bContext *, SculptGestureContext *); /* Remaining actions after finishing the symmetry passes iterations * (updating data-layers, tagging PBVH updates...). */ - void (*sculpt_gesture_end)(struct bContext *, SculptGestureContext *); -} SculptGestureOperation; + void (*sculpt_gesture_end)(bContext *, SculptGestureContext *); +}; static void sculpt_gesture_operator_properties(wmOperatorType *ot) { @@ -340,7 +336,7 @@ static void sculpt_gesture_context_init_common(bContext *C, sgcontext->ss = ob->sculpt; /* Symmetry. */ - sgcontext->symm = SCULPT_mesh_symmetry_xyz_get(ob); + sgcontext->symm = ePaintSymmetryFlags(SCULPT_mesh_symmetry_xyz_get(ob)); /* View Normal. */ float mat[3][3]; @@ -359,7 +355,7 @@ static void sculpt_gesture_context_init_common(bContext *C, static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data) { - SculptGestureContext *mcontext = user_data; + SculptGestureContext *mcontext = static_cast(user_data); LassoGestureData *lasso = &mcontext->lasso; int index = (y * lasso->width) + x; int index_end = (y * lasso->width) + x_end; @@ -370,8 +366,7 @@ static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data) static SculptGestureContext *sculpt_gesture_init_from_lasso(bContext *C, wmOperator *op) { - SculptGestureContext *sgcontext = MEM_callocN(sizeof(SculptGestureContext), - "sculpt gesture context lasso"); + SculptGestureContext *sgcontext = MEM_cnew(__func__); sgcontext->shape_type = SCULPT_GESTURE_SHAPE_LASSO; sculpt_gesture_context_init_common(C, op, sgcontext); @@ -380,7 +375,7 @@ static SculptGestureContext *sculpt_gesture_init_from_lasso(bContext *C, wmOpera const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len); if (!mcoords) { - return NULL; + return nullptr; } ED_view3d_ob_project_mat_get( @@ -407,7 +402,8 @@ static SculptGestureContext *sculpt_gesture_init_from_lasso(bContext *C, wmOpera sgcontext->vc.obact, &sgcontext->lasso.boundbox); - sgcontext->gesture_points = MEM_malloc_arrayN(mcoords_len, sizeof(float[2]), "trim points"); + sgcontext->gesture_points = static_cast( + MEM_malloc_arrayN(mcoords_len, sizeof(float[2]), "trim points")); sgcontext->tot_gesture_points = mcoords_len; for (int i = 0; i < mcoords_len; i++) { sgcontext->gesture_points[i][0] = mcoords[i][0]; @@ -421,8 +417,7 @@ static SculptGestureContext *sculpt_gesture_init_from_lasso(bContext *C, wmOpera static SculptGestureContext *sculpt_gesture_init_from_box(bContext *C, wmOperator *op) { - SculptGestureContext *sgcontext = MEM_callocN(sizeof(SculptGestureContext), - "sculpt gesture context box"); + SculptGestureContext *sgcontext = MEM_cnew(__func__); sgcontext->shape_type = SCULPT_GESTURE_SHAPE_BOX; sculpt_gesture_context_init_common(C, op, sgcontext); @@ -434,7 +429,8 @@ static SculptGestureContext *sculpt_gesture_init_from_box(bContext *C, wmOperato ED_view3d_clipping_calc( &bb, sgcontext->true_clip_planes, sgcontext->vc.region, sgcontext->vc.obact, &rect); - sgcontext->gesture_points = MEM_calloc_arrayN(4, sizeof(float[2]), "trim points"); + sgcontext->gesture_points = static_cast( + MEM_calloc_arrayN(4, sizeof(float[2]), "trim points")); sgcontext->tot_gesture_points = 4; sgcontext->gesture_points[0][0] = rect.xmax; @@ -497,8 +493,7 @@ static void sculpt_gesture_line_calculate_plane_points(SculptGestureContext *sgc static SculptGestureContext *sculpt_gesture_init_from_line(bContext *C, wmOperator *op) { - SculptGestureContext *sgcontext = MEM_callocN(sizeof(SculptGestureContext), - "sculpt gesture context line"); + SculptGestureContext *sgcontext = MEM_cnew(__func__); sgcontext->shape_type = SCULPT_GESTURE_SHAPE_LINE; sculpt_gesture_context_init_common(C, op, sgcontext); @@ -600,8 +595,10 @@ static void sculpt_gesture_update_effected_nodes_by_line_plane(SculptGestureCont copy_v4_v4(clip_planes[1], sgcontext->line.side_plane[0]); copy_v4_v4(clip_planes[2], sgcontext->line.side_plane[1]); - const int num_planes = sgcontext->line.use_side_planes ? 3 : 1; - PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = num_planes}; + PBVHFrustumPlanes frustum{}; + frustum.planes = clip_planes; + frustum.num_planes = sgcontext->line.use_side_planes ? 3 : 1; + BKE_pbvh_search_gather(ss->pbvh, BKE_pbvh_node_frustum_contain_AABB, &frustum, @@ -615,7 +612,11 @@ static void sculpt_gesture_update_effected_nodes_by_clip_planes(SculptGestureCon float clip_planes[4][4]; copy_m4_m4(clip_planes, sgcontext->clip_planes); negate_m4(clip_planes); - PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = 4}; + + PBVHFrustumPlanes frustum{}; + frustum.planes = clip_planes; + frustum.num_planes = 4; + BKE_pbvh_search_gather(ss->pbvh, BKE_pbvh_node_frustum_contain_AABB, &frustum, @@ -709,9 +710,9 @@ static void sculpt_gesture_apply(bContext *C, SculptGestureContext *sgcontext, w operation->sculpt_gesture_begin(C, sgcontext); - for (ePaintSymmetryFlags symmpass = 0; symmpass <= sgcontext->symm; symmpass++) { + for (int symmpass = 0; symmpass <= sgcontext->symm; symmpass++) { if (SCULPT_is_symmetry_iteration_valid(symmpass, sgcontext->symm)) { - sculpt_gesture_flip_for_symmetry_pass(sgcontext, symmpass); + sculpt_gesture_flip_for_symmetry_pass(sgcontext, ePaintSymmetryFlags(symmpass)); sculpt_gesture_update_effected_nodes(sgcontext); operation->sculpt_gesture_apply_for_symmetry_pass(C, sgcontext); @@ -730,11 +731,11 @@ static void sculpt_gesture_apply(bContext *C, SculptGestureContext *sgcontext, w /* Face Set Gesture Operation. */ -typedef struct SculptGestureFaceSetOperation { +struct SculptGestureFaceSetOperation { SculptGestureOperation op; int new_face_set_id; -} SculptGestureFaceSetOperation; +}; static void sculpt_gesture_face_set_begin(bContext *C, SculptGestureContext *sgcontext) { @@ -744,9 +745,9 @@ static void sculpt_gesture_face_set_begin(bContext *C, SculptGestureContext *sgc static void face_set_gesture_apply_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptGestureContext *sgcontext = userdata; + SculptGestureContext *sgcontext = static_cast(userdata); SculptGestureFaceSetOperation *face_set_operation = (SculptGestureFaceSetOperation *) sgcontext->operation; PBVHNode *node = sgcontext->nodes[i]; @@ -768,7 +769,7 @@ static void face_set_gesture_apply_task_cb(void *__restrict userdata, } } -static void sculpt_gesture_face_set_apply_for_symmetry_pass(bContext *UNUSED(C), +static void sculpt_gesture_face_set_apply_for_symmetry_pass(bContext * /*C*/, SculptGestureContext *sgcontext) { TaskParallelSettings settings; @@ -777,16 +778,17 @@ static void sculpt_gesture_face_set_apply_for_symmetry_pass(bContext *UNUSED(C), 0, sgcontext->totnode, sgcontext, face_set_gesture_apply_task_cb, &settings); } -static void sculpt_gesture_face_set_end(bContext *UNUSED(C), SculptGestureContext *sgcontext) +static void sculpt_gesture_face_set_end(bContext * /*C*/, SculptGestureContext *sgcontext) { BKE_pbvh_update_vertex_data(sgcontext->ss->pbvh, PBVH_UpdateVisibility); } static void sculpt_gesture_init_face_set_properties(SculptGestureContext *sgcontext, - wmOperator *UNUSED(op)) + wmOperator * /*op*/) { - struct Mesh *mesh = BKE_mesh_from_object(sgcontext->vc.obact); - sgcontext->operation = MEM_callocN(sizeof(SculptGestureFaceSetOperation), "Face Set Operation"); + Mesh *mesh = BKE_mesh_from_object(sgcontext->vc.obact); + sgcontext->operation = reinterpret_cast( + MEM_cnew(__func__)); sgcontext->ss->face_sets = BKE_sculpt_face_sets_ensure(mesh); @@ -803,12 +805,12 @@ static void sculpt_gesture_init_face_set_properties(SculptGestureContext *sgcont /* Mask Gesture Operation. */ -typedef struct SculptGestureMaskOperation { +struct SculptGestureMaskOperation { SculptGestureOperation op; PaintMaskFloodMode mode; float value; -} SculptGestureMaskOperation; +}; static void sculpt_gesture_mask_begin(bContext *C, SculptGestureContext *sgcontext) { @@ -818,9 +820,9 @@ static void sculpt_gesture_mask_begin(bContext *C, SculptGestureContext *sgconte static void mask_gesture_apply_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptGestureContext *sgcontext = userdata; + SculptGestureContext *sgcontext = static_cast(userdata); SculptGestureMaskOperation *mask_operation = (SculptGestureMaskOperation *)sgcontext->operation; Object *ob = sgcontext->vc.obact; PBVHNode *node = sgcontext->nodes[i]; @@ -856,7 +858,7 @@ static void mask_gesture_apply_task_cb(void *__restrict userdata, } } -static void sculpt_gesture_mask_apply_for_symmetry_pass(bContext *UNUSED(C), +static void sculpt_gesture_mask_apply_for_symmetry_pass(bContext * /*C*/, SculptGestureContext *sgcontext) { TaskParallelSettings settings; @@ -877,7 +879,8 @@ static void sculpt_gesture_init_mask_properties(bContext *C, SculptGestureContext *sgcontext, wmOperator *op) { - sgcontext->operation = MEM_callocN(sizeof(SculptGestureMaskOperation), "Mask Operation"); + sgcontext->operation = reinterpret_cast( + MEM_cnew(__func__)); SculptGestureMaskOperation *mask_operation = (SculptGestureMaskOperation *)sgcontext->operation; @@ -891,13 +894,13 @@ static void sculpt_gesture_init_mask_properties(bContext *C, sculpt_gesture_mask_apply_for_symmetry_pass; mask_operation->op.sculpt_gesture_end = sculpt_gesture_mask_end; - mask_operation->mode = RNA_enum_get(op->ptr, "mode"); + mask_operation->mode = PaintMaskFloodMode(RNA_enum_get(op->ptr, "mode")); mask_operation->value = RNA_float_get(op->ptr, "value"); } static void paint_mask_gesture_operator_properties(wmOperatorType *ot) { - RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", NULL); + RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", nullptr); RNA_def_float( ot->srna, "value", @@ -912,12 +915,12 @@ static void paint_mask_gesture_operator_properties(wmOperatorType *ot) /* Trim Gesture Operation. */ -typedef enum eSculptTrimOperationType { +enum eSculptTrimOperationType { SCULPT_GESTURE_TRIM_INTERSECT, SCULPT_GESTURE_TRIM_DIFFERENCE, SCULPT_GESTURE_TRIM_UNION, SCULPT_GESTURE_TRIM_JOIN, -} eSculptTrimOperationType; +}; /* Intersect is not exposed in the UI because it does not work correctly with symmetry (it deletes * the symmetrical part of the mesh in the first symmetry pass). */ @@ -933,13 +936,13 @@ static EnumPropertyItem prop_trim_operation_types[] = { 0, "Join", "Join the new mesh as separate geometry, without performing any boolean operation"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; -typedef enum eSculptTrimOrientationType { +enum eSculptTrimOrientationType { SCULPT_GESTURE_TRIM_ORIENTATION_VIEW, SCULPT_GESTURE_TRIM_ORIENTATION_SURFACE, -} eSculptTrimOrientationType; +}; static EnumPropertyItem prop_trim_orientation_types[] = { {SCULPT_GESTURE_TRIM_ORIENTATION_VIEW, "VIEW", @@ -951,13 +954,13 @@ static EnumPropertyItem prop_trim_orientation_types[] = { 0, "Surface", "Use the surface normal to orientate the trimming shape"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; -typedef enum eSculptTrimExtrudeMode { +enum eSculptTrimExtrudeMode { SCULPT_GESTURE_TRIM_EXTRUDE_PROJECT, SCULPT_GESTURE_TRIM_EXTRUDE_FIXED -} eSculptTrimExtrudeMode; +}; static EnumPropertyItem prop_trim_extrude_modes[] = { {SCULPT_GESTURE_TRIM_EXTRUDE_PROJECT, @@ -966,10 +969,10 @@ static EnumPropertyItem prop_trim_extrude_modes[] = { "Project", "Project back faces when extruding"}, {SCULPT_GESTURE_TRIM_EXTRUDE_FIXED, "FIXED", 0, "Fixed", "Extrude back faces by fixed amount"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; -typedef struct SculptGestureTrimOperation { +struct SculptGestureTrimOperation { SculptGestureOperation op; Mesh *mesh; @@ -983,7 +986,7 @@ typedef struct SculptGestureTrimOperation { eSculptTrimOperationType mode; eSculptTrimOrientationType orientation; eSculptTrimExtrudeMode extrude_mode; -} SculptGestureTrimOperation; +}; static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext) { @@ -991,31 +994,29 @@ static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext) Mesh *trim_mesh = trim_operation->mesh; const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(trim_mesh); - BMesh *bm; - bm = BM_mesh_create(&allocsize, - &((struct BMeshCreateParams){ - .use_toolflags = true, - })); - BM_mesh_bm_from_me(bm, - trim_mesh, - (&(struct BMeshFromMeshParams){ - .calc_face_normal = true, - .calc_vert_normal = true, - })); + BMeshCreateParams bm_create_params{}; + bm_create_params.use_toolflags = true; + BMesh *bm = BM_mesh_create(&allocsize, &bm_create_params); + + BMeshFromMeshParams bm_from_me_params{}; + bm_from_me_params.calc_face_normal = true; + bm_from_me_params.calc_vert_normal = true; + BM_mesh_bm_from_me(bm, trim_mesh, &bm_from_me_params); + BM_mesh_elem_hflag_enable_all(bm, BM_FACE, BM_ELEM_TAG, false); BMO_op_callf(bm, (BMO_FLAG_DEFAULTS & ~BMO_FLAG_RESPECT_HIDE), "recalc_face_normals faces=%hf", BM_ELEM_TAG); BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false); - Mesh *result = BKE_mesh_from_bmesh_nomain(bm, - (&(struct BMeshToMeshParams){ - .calc_object_remap = false, - }), - trim_mesh); + + BMeshToMeshParams convert_params{}; + convert_params.calc_object_remap = false; + Mesh *result = BKE_mesh_from_bmesh_nomain(bm, &convert_params, trim_mesh); + BM_mesh_free(bm); - BKE_id_free(NULL, trim_mesh); + BKE_id_free(nullptr, trim_mesh); trim_operation->mesh = result; } @@ -1142,7 +1143,8 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex const int trim_totpolys = (2 * (tot_screen_points - 2)) + (2 * tot_screen_points); trim_operation->mesh = BKE_mesh_new_nomain( trim_totverts, 0, 0, trim_totpolys * 3, trim_totpolys); - trim_operation->true_mesh_co = MEM_malloc_arrayN(trim_totverts, sizeof(float[3]), "mesh orco"); + trim_operation->true_mesh_co = static_cast( + MEM_malloc_arrayN(trim_totverts, sizeof(float[3]), "mesh orco")); float depth_front = trim_operation->depth_front; float depth_back = trim_operation->depth_back; @@ -1213,7 +1215,8 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex /* Get the triangulation for the front/back poly. */ const int tot_tris_face = tot_screen_points - 2; - uint(*r_tris)[3] = MEM_malloc_arrayN(tot_tris_face, sizeof(uint[3]), "tris"); + uint(*r_tris)[3] = static_cast( + MEM_malloc_arrayN(tot_tris_face, sizeof(uint[3]), "tris")); BLI_polyfill_calc(screen_points, tot_screen_points, 0, r_tris); /* Write the front face triangle indices. */ @@ -1222,7 +1225,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex MPoly *mp = polys; MLoop *ml = loops; for (int i = 0; i < tot_tris_face; i++, mp++, ml += 3) { - mp->loopstart = (int)(ml - loops); + mp->loopstart = int(ml - loops); mp->totloop = 3; ml[0].v = r_tris[i][0]; ml[1].v = r_tris[i][1]; @@ -1231,7 +1234,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex /* Write the back face triangle indices. */ for (int i = 0; i < tot_tris_face; i++, mp++, ml += 3) { - mp->loopstart = (int)(ml - loops); + mp->loopstart = int(ml - loops); mp->totloop = 3; ml[0].v = r_tris[i][0] + tot_screen_points; ml[1].v = r_tris[i][1] + tot_screen_points; @@ -1242,7 +1245,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex /* Write the indices for the lateral triangles. */ for (int i = 0; i < tot_screen_points; i++, mp++, ml += 3) { - mp->loopstart = (int)(ml - loops); + mp->loopstart = int(ml - loops); mp->totloop = 3; int current_index = i; int next_index = current_index + 1; @@ -1255,7 +1258,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex } for (int i = 0; i < tot_screen_points; i++, mp++, ml += 3) { - mp->loopstart = (int)(ml - loops); + mp->loopstart = int(ml - loops); mp->totloop = 3; int current_index = i; int next_index = current_index + 1; @@ -1274,11 +1277,11 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex static void sculpt_gesture_trim_geometry_free(SculptGestureContext *sgcontext) { SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; - BKE_id_free(NULL, trim_operation->mesh); + BKE_id_free(nullptr, trim_operation->mesh); MEM_freeN(trim_operation->true_mesh_co); } -static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data)) +static int bm_face_isect_pair(BMFace *f, void * /*user_data*/) { return BM_elem_flag_test(f, BM_ELEM_DRAW) ? 1 : 0; } @@ -1289,30 +1292,21 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext) Mesh *sculpt_mesh = BKE_mesh_from_object(sgcontext->vc.obact); Mesh *trim_mesh = trim_operation->mesh; - BMesh *bm; const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(sculpt_mesh, trim_mesh); - bm = BM_mesh_create(&allocsize, - &((struct BMeshCreateParams){ - .use_toolflags = false, - })); - BM_mesh_bm_from_me(bm, - trim_mesh, - &((struct BMeshFromMeshParams){ - .calc_face_normal = true, - .calc_vert_normal = true, - })); + BMeshCreateParams bm_create_params{}; + bm_create_params.use_toolflags = false; + BMesh *bm = BM_mesh_create(&allocsize, &bm_create_params); - BM_mesh_bm_from_me(bm, - sculpt_mesh, - &((struct BMeshFromMeshParams){ - .calc_face_normal = true, - .calc_vert_normal = true, - })); + BMeshFromMeshParams bm_from_me_params{}; + bm_from_me_params.calc_face_normal = true; + bm_from_me_params.calc_vert_normal = true; + BM_mesh_bm_from_me(bm, trim_mesh, &bm_from_me_params); + BM_mesh_bm_from_me(bm, sculpt_mesh, &bm_from_me_params); const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop); - BMLoop *(*looptris)[3]; - looptris = MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__); + BMLoop *(*looptris)[3] = static_cast( + MEM_malloc_arrayN(looptris_tot, sizeof(*looptris), __func__)); BM_mesh_calc_tessellation_beauty(bm, looptris); BMIter iter; @@ -1323,7 +1317,7 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext) * we could calculate on the fly too (before calling split). */ const short ob_src_totcol = trim_mesh->totcol; - short *material_remap = BLI_array_alloca(material_remap, ob_src_totcol ? ob_src_totcol : 1); + blender::Array material_remap(ob_src_totcol ? ob_src_totcol : 1); BMFace *efa; i = 0; @@ -1360,19 +1354,27 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext) BLI_assert(false); break; } - BM_mesh_boolean( - bm, looptris, looptris_tot, bm_face_isect_pair, NULL, 2, true, true, false, boolean_mode); + BM_mesh_boolean(bm, + looptris, + looptris_tot, + bm_face_isect_pair, + nullptr, + 2, + true, + true, + false, + boolean_mode); } MEM_freeN(looptris); - Mesh *result = BKE_mesh_from_bmesh_nomain(bm, - (&(struct BMeshToMeshParams){ - .calc_object_remap = false, - }), - sculpt_mesh); + BMeshToMeshParams convert_params{}; + convert_params.calc_object_remap = false; + Mesh *result = BKE_mesh_from_bmesh_nomain(bm, &convert_params, sculpt_mesh); + BM_mesh_free(bm); - BKE_mesh_nomain_to_mesh(result, sgcontext->vc.obact->data, sgcontext->vc.obact); + BKE_mesh_nomain_to_mesh( + result, static_cast(sgcontext->vc.obact->data), sgcontext->vc.obact); } static void sculpt_gesture_trim_begin(bContext *C, SculptGestureContext *sgcontext) @@ -1387,10 +1389,10 @@ static void sculpt_gesture_trim_begin(bContext *C, SculptGestureContext *sgconte sculpt_gesture_trim_geometry_generate(sgcontext); SCULPT_topology_islands_invalidate(ss); BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, true, false, false); - SCULPT_undo_push_node(sgcontext->vc.obact, NULL, SCULPT_UNDO_GEOMETRY); + SCULPT_undo_push_node(sgcontext->vc.obact, nullptr, SCULPT_UNDO_GEOMETRY); } -static void sculpt_gesture_trim_apply_for_symmetry_pass(bContext *UNUSED(C), +static void sculpt_gesture_trim_apply_for_symmetry_pass(bContext * /*C*/, SculptGestureContext *sgcontext) { SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; @@ -1403,30 +1405,31 @@ static void sculpt_gesture_trim_apply_for_symmetry_pass(bContext *UNUSED(C), sculpt_gesture_apply_trim(sgcontext); } -static void sculpt_gesture_trim_end(bContext *UNUSED(C), SculptGestureContext *sgcontext) +static void sculpt_gesture_trim_end(bContext * /*C*/, SculptGestureContext *sgcontext) { Object *object = sgcontext->vc.obact; SculptSession *ss = object->sculpt; Mesh *mesh = (Mesh *)object->data; - ss->face_sets = CustomData_get_layer_named_for_write( - &mesh->pdata, CD_PROP_INT32, ".sculpt_face_set", mesh->totpoly); + ss->face_sets = static_cast(CustomData_get_layer_named_for_write( + &mesh->pdata, CD_PROP_INT32, ".sculpt_face_set", mesh->totpoly)); if (ss->face_sets) { /* Assign a new Face Set ID to the new faces created by the trim operation. */ - const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(object->data); - ED_sculpt_face_sets_initialize_none_to_id(object->data, next_face_set_id); + const int next_face_set_id = ED_sculpt_face_sets_find_next_available_id(mesh); + ED_sculpt_face_sets_initialize_none_to_id(mesh, next_face_set_id); } sculpt_gesture_trim_geometry_free(sgcontext); - SCULPT_undo_push_node(sgcontext->vc.obact, NULL, SCULPT_UNDO_GEOMETRY); - BKE_mesh_batch_cache_dirty_tag(sgcontext->vc.obact->data, BKE_MESH_BATCH_DIRTY_ALL); + SCULPT_undo_push_node(sgcontext->vc.obact, nullptr, SCULPT_UNDO_GEOMETRY); + BKE_mesh_batch_cache_dirty_tag(mesh, BKE_MESH_BATCH_DIRTY_ALL); DEG_id_tag_update(&sgcontext->vc.obact->id, ID_RECALC_GEOMETRY); } static void sculpt_gesture_init_trim_properties(SculptGestureContext *sgcontext, wmOperator *op) { - sgcontext->operation = MEM_callocN(sizeof(SculptGestureTrimOperation), "Trim Operation"); + sgcontext->operation = reinterpret_cast( + MEM_cnew(__func__)); SculptGestureTrimOperation *trim_operation = (SculptGestureTrimOperation *)sgcontext->operation; @@ -1435,10 +1438,12 @@ static void sculpt_gesture_init_trim_properties(SculptGestureContext *sgcontext, sculpt_gesture_trim_apply_for_symmetry_pass; trim_operation->op.sculpt_gesture_end = sculpt_gesture_trim_end; - trim_operation->mode = RNA_enum_get(op->ptr, "trim_mode"); + trim_operation->mode = eSculptTrimOperationType(RNA_enum_get(op->ptr, "trim_mode")); trim_operation->use_cursor_depth = RNA_boolean_get(op->ptr, "use_cursor_depth"); - trim_operation->orientation = RNA_enum_get(op->ptr, "trim_orientation"); - trim_operation->extrude_mode = RNA_enum_get(op->ptr, "trim_extrude_mode"); + trim_operation->orientation = eSculptTrimOrientationType( + RNA_enum_get(op->ptr, "trim_orientation")); + trim_operation->extrude_mode = eSculptTrimExtrudeMode( + RNA_enum_get(op->ptr, "trim_extrude_mode")); /* If the cursor was not over the mesh, force the orientation to view. */ if (!sgcontext->ss->gesture_initial_hit) { @@ -1453,7 +1458,7 @@ static void sculpt_trim_gesture_operator_properties(wmOperatorType *ot) prop_trim_operation_types, SCULPT_GESTURE_TRIM_DIFFERENCE, "Trim Mode", - NULL); + nullptr); RNA_def_boolean( ot->srna, "use_cursor_depth", @@ -1465,20 +1470,20 @@ static void sculpt_trim_gesture_operator_properties(wmOperatorType *ot) prop_trim_orientation_types, SCULPT_GESTURE_TRIM_ORIENTATION_VIEW, "Shape Orientation", - NULL); + nullptr); RNA_def_enum(ot->srna, "trim_extrude_mode", prop_trim_extrude_modes, SCULPT_GESTURE_TRIM_EXTRUDE_FIXED, "Extrude Mode", - NULL); + nullptr); } /* Project Gesture Operation. */ -typedef struct SculptGestureProjectOperation { +struct SculptGestureProjectOperation { SculptGestureOperation operation; -} SculptGestureProjectOperation; +}; static void sculpt_gesture_project_begin(bContext *C, SculptGestureContext *sgcontext) { @@ -1488,9 +1493,9 @@ static void sculpt_gesture_project_begin(bContext *C, SculptGestureContext *sgco static void project_line_gesture_apply_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptGestureContext *sgcontext = userdata; + SculptGestureContext *sgcontext = static_cast(userdata); PBVHNode *node = sgcontext->nodes[i]; PBVHVertexIter vd; @@ -1526,7 +1531,7 @@ static void project_line_gesture_apply_task_cb(void *__restrict userdata, } } -static void sculpt_gesture_project_apply_for_symmetry_pass(bContext *UNUSED(C), +static void sculpt_gesture_project_apply_for_symmetry_pass(bContext * /*C*/, SculptGestureContext *sgcontext) { TaskParallelSettings settings; @@ -1558,9 +1563,10 @@ static void sculpt_gesture_project_end(bContext *C, SculptGestureContext *sgcont } static void sculpt_gesture_init_project_properties(SculptGestureContext *sgcontext, - wmOperator *UNUSED(op)) + wmOperator * /*op*/) { - sgcontext->operation = MEM_callocN(sizeof(SculptGestureFaceSetOperation), "Project Operation"); + sgcontext->operation = reinterpret_cast( + MEM_cnew(__func__)); SculptGestureProjectOperation *project_operation = (SculptGestureProjectOperation *) sgcontext->operation; @@ -1662,7 +1668,7 @@ static int sculpt_trim_gesture_box_invoke(bContext *C, wmOperator *op, const wmE SculptSession *ss = ob->sculpt; SculptCursorGeometryInfo sgi; - const float mval_fl[2] = {UNPACK2(event->mval)}; + const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])}; SCULPT_vertex_random_access_ensure(ss); ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false); if (ss->gesture_initial_hit) { @@ -1703,7 +1709,7 @@ static int sculpt_trim_gesture_lasso_invoke(bContext *C, wmOperator *op, const w SculptSession *ss = ob->sculpt; SculptCursorGeometryInfo sgi; - const float mval_fl[2] = {UNPACK2(event->mval)}; + const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])}; SCULPT_vertex_random_access_ensure(ss); ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false); if (ss->gesture_initial_hit) { diff --git a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.cc similarity index 87% rename from source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c rename to source/blender/editors/sculpt_paint/paint_vertex_weight_ops.cc index 816e779cd06..1e6a70c8bb2 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.c +++ b/source/blender/editors/sculpt_paint/paint_vertex_weight_ops.cc @@ -52,34 +52,35 @@ struct WPaintPrev { /* previous vertex weights */ - struct MDeformVert *wpaint_prev; + MDeformVert *wpaint_prev; /* allocation size of prev buffers */ int tot; }; -static void wpaint_prev_init(struct WPaintPrev *wpp) +static void wpaint_prev_init(WPaintPrev *wpp) { - wpp->wpaint_prev = NULL; + wpp->wpaint_prev = nullptr; wpp->tot = 0; } -static void wpaint_prev_create(struct WPaintPrev *wpp, MDeformVert *dverts, int dcount) +static void wpaint_prev_create(WPaintPrev *wpp, MDeformVert *dverts, int dcount) { wpaint_prev_init(wpp); if (dverts && dcount) { - wpp->wpaint_prev = MEM_mallocN(sizeof(MDeformVert) * dcount, "wpaint prev"); + wpp->wpaint_prev = static_cast( + MEM_malloc_arrayN(dcount, sizeof(MDeformVert), __func__)); wpp->tot = dcount; BKE_defvert_array_copy(wpp->wpaint_prev, dverts, dcount); } } -static void wpaint_prev_destroy(struct WPaintPrev *wpp) +static void wpaint_prev_destroy(WPaintPrev *wpp) { if (wpp->wpaint_prev) { BKE_defvert_array_free(wpp->wpaint_prev, wpp->tot); } - wpp->wpaint_prev = NULL; + wpp->wpaint_prev = nullptr; wpp->tot = 0; } @@ -102,7 +103,7 @@ static int weight_from_bones_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); Object *armob = BKE_modifiers_is_deformed_by_armature(ob); - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); int type = RNA_enum_get(op->ptr, "type"); ED_object_vgroup_calc_from_armature( @@ -124,7 +125,7 @@ void PAINT_OT_weight_from_bones(wmOperatorType *ot) 0, "From Envelopes", "Weights from envelopes with user defined radius"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; /* identifiers */ @@ -203,7 +204,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even float vgroup_weight = BKE_defvert_find_weight(&dvert[v_idx_best], vgroup_active); const int defbase_tot = BLI_listbase_count(&me->vertex_group_names); bool use_lock_relative = ts->wpaint_lock_relative; - bool *defbase_locked = NULL, *defbase_unlocked = NULL; + bool *defbase_locked = nullptr, *defbase_unlocked = nullptr; if (use_lock_relative) { defbase_locked = BKE_object_defgroup_lock_flags_get(vc.obact, defbase_tot); @@ -257,7 +258,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even if (changed) { /* not really correct since the brush didn't change, but redraws the toolbar */ - WM_main_add_notifier(NC_BRUSH | NA_EDITED, NULL); /* ts->wpaint->paint.brush */ + WM_main_add_notifier(NC_BRUSH | NA_EDITED, nullptr); /* ts->wpaint->paint.brush */ return OPERATOR_FINISHED; } @@ -303,8 +304,8 @@ static bool weight_paint_sample_enum_itemf__helper(const MDeformVert *dvert, return found; } static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, - PointerRNA *UNUSED(ptr), - PropertyRNA *UNUSED(prop), + PointerRNA * /*ptr*/, + PropertyRNA * /*prop*/, bool *r_free) { if (C) { @@ -323,7 +324,7 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, if (me && dverts && vc.v3d && vc.rv3d && me->vertex_group_names.first) { const int defbase_tot = BLI_listbase_count(&me->vertex_group_names); const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; - int *groups = MEM_callocN(defbase_tot * sizeof(int), "groups"); + int *groups = static_cast(MEM_callocN(defbase_tot * sizeof(int), "groups")); bool found = false; uint index; @@ -357,11 +358,13 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, MEM_freeN(groups); } else { - EnumPropertyItem *item = NULL, item_tmp = {0}; + EnumPropertyItem *item = nullptr, item_tmp = {0}; int totitem = 0; int i = 0; bDeformGroup *dg; - for (dg = me->vertex_group_names.first; dg && i < defbase_tot; i++, dg = dg->next) { + for (dg = static_cast(me->vertex_group_names.first); + dg && i < defbase_tot; + i++, dg = dg->next) { if (groups[i]) { item_tmp.identifier = item_tmp.name = dg->name; item_tmp.value = i; @@ -402,7 +405,7 @@ void PAINT_OT_weight_sample_group(wmOperatorType *ot) /* TODO: we could make this a menu into #OBJECT_OT_vertex_group_set_active * rather than its own operator */ - PropertyRNA *prop = NULL; + PropertyRNA *prop = nullptr; /* identifiers */ ot->name = "Weight Paint Sample Group"; @@ -434,7 +437,7 @@ void PAINT_OT_weight_sample_group(wmOperatorType *ot) /* fills in the selected faces with the current weight and vertex group */ static bool weight_paint_set(Object *ob, float paintweight) { - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); const MPoly *mp; MDeformWeight *dw, *dw_prev; int vgroup_active, vgroup_mirror = -1; @@ -448,7 +451,7 @@ static bool weight_paint_set(Object *ob, float paintweight) const MLoop *loops = BKE_mesh_loops(me); MDeformVert *dvert = BKE_mesh_deform_verts_for_write(me); - if (me->totpoly == 0 || dvert == NULL) { + if (me->totpoly == 0 || dvert == nullptr) { return false; } @@ -459,7 +462,7 @@ static bool weight_paint_set(Object *ob, float paintweight) vgroup_mirror = ED_wpaint_mirror_vgroup_ensure(ob, vgroup_active); } - struct WPaintPrev wpp; + WPaintPrev wpp; wpaint_prev_create(&wpp, dvert, me->totvert); const bool *select_vert = (const bool *)CustomData_get_layer_named( @@ -490,7 +493,7 @@ static bool weight_paint_set(Object *ob, float paintweight) if (me->symmetry & ME_SYMMETRY_X) { /* x mirror painting */ - int j = mesh_get_x_mirror_vert(ob, NULL, vidx, topology); + int j = mesh_get_x_mirror_vert(ob, nullptr, vidx, topology); if (j >= 0) { /* copy, not paint again */ if (vgroup_mirror != -1) { @@ -528,13 +531,13 @@ static bool weight_paint_set(Object *ob, float paintweight) static int weight_paint_set_exec(bContext *C, wmOperator *op) { - struct Scene *scene = CTX_data_scene(C); + Scene *scene = CTX_data_scene(C); Object *obact = CTX_data_active_object(C); ToolSettings *ts = CTX_data_tool_settings(C); Brush *brush = BKE_paint_brush(&ts->wpaint->paint); float vgroup_weight = BKE_brush_weight_get(scene, brush); - if (ED_wpaint_ensure_data(C, op->reports, WPAINT_ENSURE_MIRROR, NULL) == false) { + if (ED_wpaint_ensure_data(C, op->reports, WPAINT_ENSURE_MIRROR, nullptr) == false) { return OPERATOR_CANCELLED; } @@ -567,23 +570,25 @@ void PAINT_OT_weight_set(wmOperatorType *ot) * \{ */ /* *** VGroups Gradient *** */ -typedef struct WPGradient_vertStore { - float sco[2]; - float weight_orig; - enum { +struct WPGradient_vertStore { + enum Flag { VGRAD_STORE_NOP = 0, VGRAD_STORE_DW_EXIST = (1 << 0), VGRAD_STORE_IS_MODIFIED = (1 << 1) - } flag; -} WPGradient_vertStore; + }; + float sco[2]; + float weight_orig; + Flag flag; +}; +ENUM_OPERATORS(WPGradient_vertStore::Flag, WPGradient_vertStore::VGRAD_STORE_IS_MODIFIED); -typedef struct WPGradient_vertStoreBase { - struct WPaintPrev wpp; +struct WPGradient_vertStoreBase { + WPaintPrev wpp; WPGradient_vertStore elem[0]; -} WPGradient_vertStoreBase; +}; -typedef struct WPGradient_userData { - struct ARegion *region; +struct WPGradient_userData { + ARegion *region; Scene *scene; Mesh *me; MDeformVert *dvert; @@ -603,16 +608,17 @@ typedef struct WPGradient_userData { bool use_vgroup_restrict; short type; float weightpaint; -} WPGradient_userData; +}; static void gradientVert_update(WPGradient_userData *grad_data, int index) { WPGradient_vertStore *vs = &grad_data->vert_cache->elem[index]; /* Optionally restrict to assigned vertices only. */ - if (grad_data->use_vgroup_restrict && ((vs->flag & VGRAD_STORE_DW_EXIST) == 0)) { + if (grad_data->use_vgroup_restrict && + ((vs->flag & WPGradient_vertStore::VGRAD_STORE_DW_EXIST) == 0)) { /* In this case the vertex will never have been touched. */ - BLI_assert((vs->flag & VGRAD_STORE_IS_MODIFIED) == 0); + BLI_assert((vs->flag & WPGradient_vertStore::VGRAD_STORE_IS_MODIFIED) == 0); return; } @@ -641,12 +647,12 @@ static void gradientVert_update(WPGradient_userData *grad_data, int index) tool, vs->weight_orig, grad_data->weightpaint, alpha * grad_data->brush->alpha); CLAMP(testw, 0.0f, 1.0f); dw->weight = testw; - vs->flag |= VGRAD_STORE_IS_MODIFIED; + vs->flag |= WPGradient_vertStore::VGRAD_STORE_IS_MODIFIED; } else { MDeformVert *dv = &grad_data->dvert[index]; - if (vs->flag & VGRAD_STORE_DW_EXIST) { - /* normally we NULL check, but in this case we know it exists */ + if (vs->flag & WPGradient_vertStore::VGRAD_STORE_DW_EXIST) { + /* normally we nullptr check, but in this case we know it exists */ MDeformWeight *dw = BKE_defvert_find_index(dv, grad_data->def_nr); dw->weight = vs->weight_orig; } @@ -657,16 +663,16 @@ static void gradientVert_update(WPGradient_userData *grad_data, int index) BKE_defvert_remove_group(dv, dw); } } - vs->flag &= ~VGRAD_STORE_IS_MODIFIED; + vs->flag &= ~WPGradient_vertStore::VGRAD_STORE_IS_MODIFIED; } } static void gradientVertUpdate__mapFunc(void *userData, int index, - const float UNUSED(co[3]), - const float UNUSED(no[3])) + const float /*co*/[3], + const float /*no*/[3]) { - WPGradient_userData *grad_data = userData; + WPGradient_userData *grad_data = static_cast(userData); WPGradient_vertStore *vs = &grad_data->vert_cache->elem[index]; if (vs->sco[0] == FLT_MAX) { @@ -679,9 +685,9 @@ static void gradientVertUpdate__mapFunc(void *userData, static void gradientVertInit__mapFunc(void *userData, int index, const float co[3], - const float UNUSED(no[3])) + const float /*no*/[3]) { - WPGradient_userData *grad_data = userData; + WPGradient_userData *grad_data = static_cast(userData); WPGradient_vertStore *vs = &grad_data->vert_cache->elem[index]; if (grad_data->use_select && (grad_data->select_vert && !grad_data->select_vert[index])) { @@ -709,11 +715,11 @@ static void gradientVertInit__mapFunc(void *userData, const MDeformWeight *dw = BKE_defvert_find_index(dv, grad_data->def_nr); if (dw) { vs->weight_orig = dw->weight; - vs->flag = VGRAD_STORE_DW_EXIST; + vs->flag = WPGradient_vertStore::VGRAD_STORE_DW_EXIST; } else { vs->weight_orig = 0.0f; - vs->flag = VGRAD_STORE_NOP; + vs->flag = WPGradient_vertStore::VGRAD_STORE_NOP; } BLI_BITMAP_ENABLE(grad_data->vert_visit, index); gradientVert_update(grad_data, index); @@ -721,8 +727,9 @@ static void gradientVertInit__mapFunc(void *userData, static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEvent *event) { - wmGesture *gesture = op->customdata; - WPGradient_vertStoreBase *vert_cache = gesture->user_data.data; + wmGesture *gesture = static_cast(op->customdata); + WPGradient_vertStoreBase *vert_cache = static_cast( + gesture->user_data.data); int ret = WM_gesture_straightline_modal(C, op, event); if (ret & OPERATOR_RUNNING_MODAL) { @@ -736,8 +743,8 @@ static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEven if (ret & OPERATOR_CANCELLED) { Object *ob = CTX_data_active_object(C); - if (vert_cache != NULL) { - Mesh *me = ob->data; + if (vert_cache != nullptr) { + Mesh *me = static_cast(ob->data); if (vert_cache->wpp.wpaint_prev) { MDeformVert *dvert = BKE_mesh_deform_verts_for_write(me); BKE_defvert_array_free_elems(dvert, me->totvert); @@ -760,27 +767,27 @@ static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEven static int paint_weight_gradient_exec(bContext *C, wmOperator *op) { - wmGesture *gesture = op->customdata; + wmGesture *gesture = static_cast(op->customdata); WPGradient_vertStoreBase *vert_cache; - struct ARegion *region = CTX_wm_region(C); + ARegion *region = CTX_wm_region(C); Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); MDeformVert *dverts = BKE_mesh_deform_verts_for_write(me); int x_start = RNA_int_get(op->ptr, "xstart"); int y_start = RNA_int_get(op->ptr, "ystart"); int x_end = RNA_int_get(op->ptr, "xend"); int y_end = RNA_int_get(op->ptr, "yend"); - const float sco_start[2] = {x_start, y_start}; - const float sco_end[2] = {x_end, y_end}; - const bool is_interactive = (gesture != NULL); + const float sco_start[2] = {float(x_start), float(y_start)}; + const float sco_end[2] = {float(x_end), float(y_end)}; + const bool is_interactive = (gesture != nullptr); Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - WPGradient_userData data = {NULL}; + WPGradient_userData data = {nullptr}; if (is_interactive) { - if (gesture->user_data.data == NULL) { + if (gesture->user_data.data == nullptr) { gesture->user_data.data = MEM_mallocN(sizeof(WPGradient_vertStoreBase) + (sizeof(WPGradient_vertStore) * me->totvert), __func__); @@ -796,21 +803,22 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) } } - vert_cache = gesture->user_data.data; + vert_cache = static_cast(gesture->user_data.data); } else { - if (ED_wpaint_ensure_data(C, op->reports, 0, NULL) == false) { + if (ED_wpaint_ensure_data(C, op->reports, eWPaintFlag(0), nullptr) == false) { return OPERATOR_CANCELLED; } data.is_init = true; - vert_cache = MEM_mallocN( - sizeof(WPGradient_vertStoreBase) + (sizeof(WPGradient_vertStore) * me->totvert), __func__); + vert_cache = static_cast(MEM_mallocN( + sizeof(WPGradient_vertStoreBase) + (sizeof(WPGradient_vertStore) * me->totvert), + __func__)); } data.region = region; data.scene = scene; - data.me = ob->data; + data.me = me; data.dvert = dverts; data.select_vert = (const bool *)CustomData_get_layer_named( &me->vdata, CD_PROP_BOOL, ".select_vert"); @@ -820,13 +828,13 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) data.def_nr = BKE_object_defgroup_active_index_get(ob) - 1; data.use_select = (me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0; data.vert_cache = vert_cache; - data.vert_visit = NULL; + data.vert_visit = nullptr; data.type = RNA_enum_get(op->ptr, "type"); { ToolSettings *ts = CTX_data_tool_settings(C); VPaint *wp = ts->wpaint; - struct Brush *brush = BKE_paint_brush(&wp->paint); + Brush *brush = BKE_paint_brush(&wp->paint); BKE_curvemapping_init(brush->curve); @@ -835,7 +843,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) data.use_vgroup_restrict = (ts->wpaint->flag & VP_FLAG_VGROUP_RESTRICT) != 0; } - ED_view3d_init_mats_rv3d(ob, region->regiondata); + ED_view3d_init_mats_rv3d(ob, static_cast(region->regiondata)); Scene *scene_eval = DEG_get_evaluated_scene(depsgraph); Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); @@ -851,7 +859,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) BKE_mesh_foreach_mapped_vert(me_eval, gradientVertInit__mapFunc, &data, MESH_FOREACH_NOP); MEM_freeN(data.vert_visit); - data.vert_visit = NULL; + data.vert_visit = nullptr; } else { BKE_mesh_foreach_mapped_vert(me_eval, gradientVertUpdate__mapFunc, &data, MESH_FOREACH_NOP); @@ -867,10 +875,10 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op) if (scene->toolsettings->auto_normalize) { const int vgroup_num = BLI_listbase_count(&me->vertex_group_names); bool *vgroup_validmap = BKE_object_defgroup_validmap_get(ob, vgroup_num); - if (vgroup_validmap != NULL) { + if (vgroup_validmap != nullptr) { MDeformVert *dvert = dverts; for (int i = 0; i < me->totvert; i++) { - if ((data.vert_cache->elem[i].flag & VGRAD_STORE_IS_MODIFIED) != 0) { + if ((data.vert_cache->elem[i].flag & WPGradient_vertStore::VGRAD_STORE_IS_MODIFIED) != 0) { BKE_defvert_normalize_lock_single(&dvert[i], vgroup_validmap, vgroup_num, data.def_nr); } } @@ -885,17 +893,17 @@ static int paint_weight_gradient_invoke(bContext *C, wmOperator *op, const wmEve { int ret; - if (ED_wpaint_ensure_data(C, op->reports, 0, NULL) == false) { + if (ED_wpaint_ensure_data(C, op->reports, eWPaintFlag(0), nullptr) == false) { return OPERATOR_CANCELLED; } ret = WM_gesture_straightline_invoke(C, op, event); if (ret & OPERATOR_RUNNING_MODAL) { - struct ARegion *region = CTX_wm_region(C); + ARegion *region = CTX_wm_region(C); if (region->regiontype == RGN_TYPE_WINDOW) { /* TODO: hard-coded, extend `WM_gesture_straightline_*`. */ if (event->type == LEFTMOUSE && event->val == KM_PRESS) { - wmGesture *gesture = op->customdata; + wmGesture *gesture = static_cast(op->customdata); gesture->is_active = true; } } @@ -909,7 +917,7 @@ void PAINT_OT_weight_gradient(wmOperatorType *ot) static const EnumPropertyItem gradient_types[] = { {WPAINT_GRADIENT_TYPE_LINEAR, "LINEAR", 0, "Linear", ""}, {WPAINT_GRADIENT_TYPE_RADIAL, "RADIAL", 0, "Radial", ""}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; PropertyRNA *prop; diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.cc similarity index 94% rename from source/blender/editors/sculpt_paint/sculpt_expand.c rename to source/blender/editors/sculpt_paint/sculpt_expand.cc index 028ac847529..532466ab426 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.cc @@ -5,6 +5,9 @@ * \ingroup edsculpt */ +#include +#include + #include "MEM_guardedalloc.h" #include "BLI_linklist_stack.h" @@ -48,9 +51,6 @@ #include "bmesh.h" -#include -#include - /* Sculpt Expand. */ /* Operator for creating selections and patterns in Sculpt Mode. Expand can create masks, face sets * and fill vertex colors. */ @@ -421,8 +421,8 @@ static PBVHVertRef sculpt_expand_get_vertex_index_for_symmetry_pass( } else { float location[3]; - flip_v3_v3(location, SCULPT_vertex_co_get(ss, original_vertex), symm_it); - symm_vertex = SCULPT_nearest_vertex_get(NULL, ob, location, FLT_MAX, false); + flip_v3_v3(location, SCULPT_vertex_co_get(ss, original_vertex), ePaintSymmetryFlags(symm_it)); + symm_vertex = SCULPT_nearest_vertex_get(nullptr, ob, location, FLT_MAX, false); } return symm_vertex; } @@ -440,12 +440,12 @@ static float *sculpt_expand_geodesic_falloff_create(Sculpt *sd, Object *ob, cons * Topology: Initializes the falloff using a flood-fill operation, * increasing the falloff value by 1 when visiting a new vertex. */ -typedef struct ExpandFloodFillData { +struct ExpandFloodFillData { float original_normal[3]; float edge_sensitivity; float *dists; float *edge_factor; -} ExpandFloodFillData; +}; static bool expand_topology_floodfill_cb( SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata) @@ -453,7 +453,7 @@ static bool expand_topology_floodfill_cb( int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); - ExpandFloodFillData *data = userdata; + ExpandFloodFillData *data = static_cast(userdata); if (!is_duplicate) { const float to_it = data->dists[from_v_i] + 1.0f; data->dists[to_v_i] = to_it; @@ -468,7 +468,7 @@ static float *sculpt_expand_topology_falloff_create(Sculpt *sd, Object *ob, cons { SculptSession *ss = ob->sculpt; const int totvert = SCULPT_vertex_count_get(ss); - float *dists = MEM_calloc_arrayN(totvert, sizeof(float), "topology dist"); + float *dists = static_cast(MEM_calloc_arrayN(totvert, sizeof(float), __func__)); SculptFloodFill flood; SCULPT_floodfill_init(ss, &flood); @@ -494,7 +494,7 @@ static bool mask_expand_normal_floodfill_cb( int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); - ExpandFloodFillData *data = userdata; + ExpandFloodFillData *data = static_cast(userdata); if (!is_duplicate) { float current_normal[3], prev_normal[3]; SCULPT_vertex_normal_get(ss, to_v, current_normal); @@ -521,8 +521,8 @@ static float *sculpt_expand_normal_falloff_create(Sculpt *sd, { SculptSession *ss = ob->sculpt; const int totvert = SCULPT_vertex_count_get(ss); - float *dists = MEM_malloc_arrayN(totvert, sizeof(float), "normal dist"); - float *edge_factor = MEM_callocN(sizeof(float) * totvert, "mask edge factor"); + float *dists = static_cast(MEM_malloc_arrayN(totvert, sizeof(float), __func__)); + float *edge_factor = static_cast(MEM_callocN(sizeof(float) * totvert, __func__)); for (int i = 0; i < totvert; i++) { edge_factor[i] = 1.0f; } @@ -568,7 +568,7 @@ static float *sculpt_expand_spherical_falloff_create(Object *ob, const PBVHVertR SculptSession *ss = ob->sculpt; const int totvert = SCULPT_vertex_count_get(ss); - float *dists = MEM_malloc_arrayN(totvert, sizeof(float), "spherical dist"); + float *dists = static_cast(MEM_malloc_arrayN(totvert, sizeof(float), __func__)); for (int i = 0; i < totvert; i++) { dists[i] = FLT_MAX; } @@ -602,7 +602,7 @@ static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const P { SculptSession *ss = ob->sculpt; const int totvert = SCULPT_vertex_count_get(ss); - float *dists = MEM_calloc_arrayN(totvert, sizeof(float), "spherical dist"); + float *dists = static_cast(MEM_calloc_arrayN(totvert, sizeof(float), __func__)); BLI_bitmap *visited_verts = BLI_BITMAP_NEW(totvert, "visited verts"); GSQueue *queue = BLI_gsqueue_new(sizeof(PBVHVertRef)); @@ -616,7 +616,7 @@ static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const P const PBVHVertRef symm_vertex = sculpt_expand_get_vertex_index_for_symmetry_pass( ob, symm_it, v); - SculptBoundary *boundary = SCULPT_boundary_data_init(ob, NULL, symm_vertex, FLT_MAX); + SculptBoundary *boundary = SCULPT_boundary_data_init(ob, nullptr, symm_vertex, FLT_MAX); if (!boundary) { continue; } @@ -666,7 +666,7 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const PBVHVertR { SculptSession *ss = ob->sculpt; const int totvert = SCULPT_vertex_count_get(ss); - float *dists = MEM_calloc_arrayN(totvert, sizeof(float), "spherical dist"); + float *dists = static_cast(MEM_calloc_arrayN(totvert, sizeof(float), __func__)); /* This algorithm uses mesh data (polys and loops), so this falloff type can't be initialized for * Multires. It also does not make sense to implement it for dyntopo as the result will be the @@ -822,11 +822,11 @@ static void sculpt_expand_mesh_face_falloff_from_vertex_falloff(SculptSession *s Mesh *mesh, ExpandCache *expand_cache) { - BLI_assert(expand_cache->vert_falloff != NULL); + BLI_assert(expand_cache->vert_falloff != nullptr); if (!expand_cache->face_falloff) { - expand_cache->face_falloff = MEM_malloc_arrayN( - mesh->totpoly, sizeof(float), "face falloff factors"); + expand_cache->face_falloff = static_cast( + MEM_malloc_arrayN(mesh->totpoly, sizeof(float), __func__)); } if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) { @@ -869,7 +869,7 @@ static void sculpt_expand_geodesics_from_state_boundary(Object *ob, MEM_SAFE_FREE(expand_cache->face_falloff); expand_cache->vert_falloff = SCULPT_geodesic_distances_create(ob, initial_verts, FLT_MAX); - BLI_gset_free(initial_verts, NULL); + BLI_gset_free(initial_verts, nullptr); } /** @@ -886,7 +886,7 @@ static void sculpt_expand_topology_from_state_boundary(Object *ob, SculptSession *ss = ob->sculpt; const int totvert = SCULPT_vertex_count_get(ss); - float *dists = MEM_calloc_arrayN(totvert, sizeof(float), "topology dist"); + float *dists = static_cast(MEM_calloc_arrayN(totvert, sizeof(float), __func__)); BLI_bitmap *boundary_verts = sculpt_expand_boundary_from_enabled(ss, enabled_verts, false); SculptFloodFill flood; @@ -939,7 +939,8 @@ static void sculpt_expand_resursion_step_add(Object *ob, sculpt_expand_update_max_vert_falloff_value(ss, expand_cache); if (expand_cache->target == SCULPT_EXPAND_TARGET_FACE_SETS) { - sculpt_expand_mesh_face_falloff_from_vertex_falloff(ss, ob->data, expand_cache); + sculpt_expand_mesh_face_falloff_from_vertex_falloff( + ss, static_cast(ob->data), expand_cache); sculpt_expand_update_max_face_falloff_factor(ss, expand_cache); } @@ -1069,7 +1070,8 @@ static void sculpt_expand_falloff_factors_from_vertex_and_symm_create( /* Update max falloff values and propagate to base mesh faces if needed. */ sculpt_expand_update_max_vert_falloff_value(ss, expand_cache); if (expand_cache->target == SCULPT_EXPAND_TARGET_FACE_SETS) { - sculpt_expand_mesh_face_falloff_from_vertex_falloff(ss, ob->data, expand_cache); + sculpt_expand_mesh_face_falloff_from_vertex_falloff( + ss, static_cast(ob->data), expand_cache); sculpt_expand_update_max_face_falloff_factor(ss, expand_cache); } } @@ -1113,7 +1115,7 @@ static void sculpt_expand_snap_initialize_from_enabled(SculptSession *ss, } if (any_disabled) { const int face_set = expand_cache->original_face_sets[p]; - BLI_gset_remove(expand_cache->snap_enabled_face_sets, POINTER_FROM_INT(face_set), NULL); + BLI_gset_remove(expand_cache->snap_enabled_face_sets, POINTER_FROM_INT(face_set), nullptr); } } @@ -1128,7 +1130,7 @@ static void sculpt_expand_snap_initialize_from_enabled(SculptSession *ss, static void sculpt_expand_cache_data_free(ExpandCache *expand_cache) { if (expand_cache->snap_enabled_face_sets) { - BLI_gset_free(expand_cache->snap_enabled_face_sets, NULL); + BLI_gset_free(expand_cache->snap_enabled_face_sets, nullptr); } MEM_SAFE_FREE(expand_cache->nodes); MEM_SAFE_FREE(expand_cache->vert_falloff); @@ -1143,9 +1145,9 @@ static void sculpt_expand_cache_data_free(ExpandCache *expand_cache) static void sculpt_expand_cache_free(SculptSession *ss) { sculpt_expand_cache_data_free(ss->expand_cache); - /* Needs to be set to NULL as the paint cursor relies on checking this pointer detecting if an + /* Needs to be set to nullptr as the paint cursor relies on checking this pointer detecting if an * expand operation is running. */ - ss->expand_cache = NULL; + ss->expand_cache = nullptr; } /** @@ -1155,7 +1157,7 @@ static void sculpt_expand_restore_face_set_data(SculptSession *ss, ExpandCache * { PBVHNode **nodes; int totnode; - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); for (int n = 0; n < totnode; n++) { PBVHNode *node = nodes[n]; BKE_pbvh_node_mark_redraw(node); @@ -1170,7 +1172,7 @@ static void sculpt_expand_restore_color_data(SculptSession *ss, ExpandCache *exp { PBVHNode **nodes; int totnode; - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); for (int n = 0; n < totnode; n++) { PBVHNode *node = nodes[n]; PBVHVertexIter vd; @@ -1187,7 +1189,7 @@ static void sculpt_expand_restore_mask_data(SculptSession *ss, ExpandCache *expa { PBVHNode **nodes; int totnode; - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); for (int n = 0; n < totnode; n++) { PBVHNode *node = nodes[n]; PBVHVertexIter vd; @@ -1232,7 +1234,7 @@ static void sculpt_expand_restore_original_state(bContext *C, /** * Cancel operator callback. */ -static void sculpt_expand_cancel(bContext *C, wmOperator *UNUSED(op)) +static void sculpt_expand_cancel(bContext *C, wmOperator * /*op*/) { Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; @@ -1250,9 +1252,9 @@ static void sculpt_expand_cancel(bContext *C, wmOperator *UNUSED(op)) */ static void sculpt_expand_mask_update_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; PBVHNode *node = data->nodes[i]; ExpandCache *expand_cache = ss->expand_cache; @@ -1329,9 +1331,9 @@ static void sculpt_expand_face_sets_update(SculptSession *ss, ExpandCache *expan */ static void sculpt_expand_colors_update_task_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - SculptThreadedTaskData *data = userdata; + SculptThreadedTaskData *data = static_cast(userdata); SculptSession *ss = data->ob->sculpt; PBVHNode *node = data->nodes[i]; ExpandCache *expand_cache = ss->expand_cache; @@ -1362,7 +1364,7 @@ static void sculpt_expand_colors_update_task_cb(void *__restrict userdata, IMB_blend_color_float(final_color, expand_cache->original_colors[vd.index], final_fill_color, - expand_cache->blend_mode); + IMB_BlendMode(expand_cache->blend_mode)); if (equals_v4v4(initial_color, final_color)) { continue; @@ -1405,8 +1407,10 @@ static void sculpt_expand_original_state_store(Object *ob, ExpandCache *expand_c const int totface = ss->totfaces; /* Face Sets are always stored as they are needed for snapping. */ - expand_cache->initial_face_sets = MEM_malloc_arrayN(totface, sizeof(int), "initial face set"); - expand_cache->original_face_sets = MEM_malloc_arrayN(totface, sizeof(int), "original face set"); + expand_cache->initial_face_sets = static_cast( + MEM_malloc_arrayN(totface, sizeof(int), "initial face set")); + expand_cache->original_face_sets = static_cast( + MEM_malloc_arrayN(totface, sizeof(int), "original face set")); if (ss->face_sets) { for (int i = 0; i < totface; i++) { expand_cache->initial_face_sets[i] = ss->face_sets[i]; @@ -1419,7 +1423,8 @@ static void sculpt_expand_original_state_store(Object *ob, ExpandCache *expand_c } if (expand_cache->target == SCULPT_EXPAND_TARGET_MASK) { - expand_cache->original_mask = MEM_malloc_arrayN(totvert, sizeof(float), "initial mask"); + expand_cache->original_mask = static_cast( + MEM_malloc_arrayN(totvert, sizeof(float), "initial mask")); for (int i = 0; i < totvert; i++) { PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); @@ -1428,7 +1433,8 @@ static void sculpt_expand_original_state_store(Object *ob, ExpandCache *expand_c } if (expand_cache->target == SCULPT_EXPAND_TARGET_COLORS) { - expand_cache->original_colors = MEM_malloc_arrayN(totvert, sizeof(float[4]), "initial colors"); + expand_cache->original_colors = static_cast( + MEM_malloc_arrayN(totvert, sizeof(float[4]), "initial colors")); for (int i = 0; i < totvert; i++) { PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); @@ -1483,11 +1489,10 @@ static void sculpt_expand_update_for_vertex(bContext *C, Object *ob, const PBVHV } /* Update the mesh sculpt data. */ - SculptThreadedTaskData data = { - .sd = sd, - .ob = ob, - .nodes = expand_cache->nodes, - }; + SculptThreadedTaskData data{}; + data.sd = sd; + data.ob = ob; + data.nodes = expand_cache->nodes; TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, expand_cache->totnode); @@ -1597,7 +1602,7 @@ static void sculpt_expand_finish(bContext *C) /* Tag all nodes to redraw to avoid artifacts after the fast partial updates. */ PBVHNode **nodes; int totnode; - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); for (int n = 0; n < totnode; n++) { BKE_pbvh_node_mark_update_mask(nodes[n]); } @@ -1616,7 +1621,7 @@ static void sculpt_expand_finish(bContext *C) } sculpt_expand_cache_free(ss); - ED_workspace_status_text(C, NULL); + ED_workspace_status_text(C, nullptr); } /** @@ -1640,8 +1645,8 @@ static void sculpt_expand_find_active_connected_components_from_vert( const PBVHVertRef symm_vertex = sculpt_expand_get_vertex_index_for_symmetry_pass( ob, symm_it, initial_vertex); - expand_cache->active_connected_islands[(int)symm_it] = SCULPT_vertex_island_get( - ss, symm_vertex); + expand_cache->active_connected_islands[int(symm_it)] = SCULPT_vertex_island_get(ss, + symm_vertex); } } @@ -1679,7 +1684,8 @@ static void sculpt_expand_set_initial_components_for_mouse(bContext *C, expand_cache->next_face_set = SCULPT_active_face_set_get(ss); } else { - expand_cache->next_face_set = ED_sculpt_face_sets_find_next_available_id(ob->data); + expand_cache->next_face_set = ED_sculpt_face_sets_find_next_available_id( + static_cast(ob->data)); } } @@ -1699,7 +1705,7 @@ static void sculpt_expand_move_propagation_origin(bContext *C, { Sculpt *sd = CTX_data_tool_settings(C)->sculpt; - const float mval_fl[2] = {UNPACK2(event->mval)}; + const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])}; float move_disp[2]; sub_v2_v2v2(move_disp, mval_fl, expand_cache->initial_mouse_move); @@ -1767,7 +1773,7 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event sculpt_expand_ensure_sculptsession_data(ob); /* Update and get the active vertex (and face) from the cursor. */ - const float mval_fl[2] = {UNPACK2(event->mval)}; + const float mval_fl[2] = {float(event->mval[0]), float(event->mval[1])}; const PBVHVertRef target_expand_vertex = sculpt_expand_target_vertex_update_and_get( C, ob, mval_fl); @@ -1802,8 +1808,8 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event if (expand_cache->snap) { expand_cache->snap = false; if (expand_cache->snap_enabled_face_sets) { - BLI_gset_free(expand_cache->snap_enabled_face_sets, NULL); - expand_cache->snap_enabled_face_sets = NULL; + BLI_gset_free(expand_cache->snap_enabled_face_sets, nullptr); + expand_cache->snap_enabled_face_sets = nullptr; } } else { @@ -1916,7 +1922,7 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event case SCULPT_EXPAND_MODAL_TEXTURE_DISTORTION_INCREASE: { if (expand_cache->texture_distortion_strength == 0.0f) { const MTex *mask_tex = BKE_brush_mask_texture_get(expand_cache->brush, OB_MODE_SCULPT); - if (mask_tex->tex == NULL) { + if (mask_tex->tex == nullptr) { BKE_report(op->reports, RPT_WARNING, "Active brush does not contain any texture to distort the expand boundary"); @@ -2067,7 +2073,7 @@ static void sculpt_expand_cache_initial_config_set(bContext *C, expand_cache->preserve = RNA_boolean_get(op->ptr, "use_mask_preserve"); expand_cache->auto_mask = RNA_boolean_get(op->ptr, "use_auto_mask"); expand_cache->falloff_gradient = RNA_boolean_get(op->ptr, "use_falloff_gradient"); - expand_cache->target = RNA_enum_get(op->ptr, "target"); + expand_cache->target = eSculptExpandTargetType(RNA_enum_get(op->ptr, "target")); expand_cache->modify_active_face_set = RNA_boolean_get(op->ptr, "use_modify_active"); expand_cache->reposition_pivot = RNA_boolean_get(op->ptr, "use_reposition_pivot"); expand_cache->max_geodesic_move_preview = RNA_int_get(op->ptr, "max_geodesic_move_preview"); @@ -2099,7 +2105,7 @@ static void sculpt_expand_undo_push(Object *ob, ExpandCache *expand_cache) SculptSession *ss = ob->sculpt; PBVHNode **nodes; int totnode; - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &totnode); switch (expand_cache->target) { case SCULPT_EXPAND_TARGET_MASK: @@ -2132,7 +2138,7 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even SCULPT_stroke_id_next(ob); /* Create and configure the Expand Cache. */ - ss->expand_cache = MEM_callocN(sizeof(ExpandCache), "expand cache"); + ss->expand_cache = MEM_cnew(__func__); sculpt_expand_cache_initial_config_set(C, op, ss->expand_cache); /* Update object. */ @@ -2168,7 +2174,7 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even /* TODO: implement SCULPT_vertex_mask_set and use it here. */ - BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &nodes_num); + BKE_pbvh_search_gather(ss->pbvh, nullptr, nullptr, &nodes, &nodes_num); for (int i = 0; i < nodes_num; i++) { PBVHVertexIter vd; @@ -2192,8 +2198,8 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even return OPERATOR_CANCELLED; } + Mesh *mesh = static_cast(ob->data); if (ss->expand_cache->target == SCULPT_EXPAND_TARGET_FACE_SETS) { - Mesh *mesh = ob->data; ss->face_sets = BKE_sculpt_face_sets_ensure(mesh); } @@ -2211,12 +2217,12 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even sculpt_expand_undo_push(ob, ss->expand_cache); /* Set the initial element for expand from the event position. */ - const float mouse[2] = {event->mval[0], event->mval[1]}; + const float mouse[2] = {float(event->mval[0]), float(event->mval[1])}; sculpt_expand_set_initial_components_for_mouse(C, ob, ss->expand_cache, mouse); /* Cache PBVH nodes. */ BKE_pbvh_search_gather( - ss->pbvh, NULL, NULL, &ss->expand_cache->nodes, &ss->expand_cache->totnode); + ss->pbvh, nullptr, nullptr, &ss->expand_cache->nodes, &ss->expand_cache->totnode); /* Store initial state. */ sculpt_expand_original_state_store(ob, ss->expand_cache); @@ -2225,12 +2231,13 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even sculpt_expand_delete_face_set_id(ss->expand_cache->initial_face_sets, ss, ss->expand_cache, - ob->data, + mesh, ss->expand_cache->next_face_set); } /* Initialize the falloff. */ - eSculptExpandFalloffType falloff_type = RNA_enum_get(op->ptr, "falloff_type"); + eSculptExpandFalloffType falloff_type = eSculptExpandFalloffType( + RNA_enum_get(op->ptr, "falloff_type")); /* When starting from a boundary vertex, set the initial falloff to boundary. */ if (SCULPT_vertex_is_boundary(ss, ss->expand_cache->initial_active_vertex)) { @@ -2302,7 +2309,7 @@ void sculpt_expand_modal_keymap(wmKeyConfig *keyconf) 0, "Texture Distortion Decrease", ""}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static const char *name = "Sculpt Expand Modal"; @@ -2345,14 +2352,14 @@ void SCULPT_OT_expand(wmOperatorType *ot) {SCULPT_EXPAND_FALLOFF_BOUNDARY_TOPOLOGY, "BOUNDARY_TOPOLOGY", 0, "Boundary Topology", ""}, {SCULPT_EXPAND_FALLOFF_BOUNDARY_FACE_SET, "BOUNDARY_FACE_SET", 0, "Boundary Face Set", ""}, {SCULPT_EXPAND_FALLOFF_ACTIVE_FACE_SET, "ACTIVE_FACE_SET", 0, "Active Face Set", ""}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static EnumPropertyItem prop_sculpt_expand_target_type_items[] = { {SCULPT_EXPAND_TARGET_MASK, "MASK", 0, "Mask", ""}, {SCULPT_EXPAND_TARGET_FACE_SETS, "FACE_SETS", 0, "Face Sets", ""}, {SCULPT_EXPAND_TARGET_COLORS, "COLOR", 0, "Color", ""}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; RNA_def_enum(ot->srna, diff --git a/source/blender/editors/sculpt_paint/sculpt_geodesic.c b/source/blender/editors/sculpt_paint/sculpt_geodesic.cc similarity index 96% rename from source/blender/editors/sculpt_paint/sculpt_geodesic.c rename to source/blender/editors/sculpt_paint/sculpt_geodesic.cc index 89cf2fda27e..a8cac7dd7e5 100644 --- a/source/blender/editors/sculpt_paint/sculpt_geodesic.c +++ b/source/blender/editors/sculpt_paint/sculpt_geodesic.cc @@ -5,6 +5,9 @@ * \ingroup edsculpt */ +#include +#include + #include "MEM_guardedalloc.h" #include "BLI_linklist_stack.h" @@ -29,8 +32,6 @@ #include "bmesh.h" -#include -#include #define SCULPT_GEODESIC_VERTEX_NONE -1 /* Propagate distance from v1 and v2 to v0. */ @@ -90,7 +91,7 @@ static float *SCULPT_geodesic_mesh_create(Object *ob, const MPoly *polys = BKE_mesh_polys(mesh); const MLoop *loops = BKE_mesh_loops(mesh); - float *dists = MEM_malloc_arrayN(totvert, sizeof(float), "distances"); + float *dists = static_cast(MEM_malloc_arrayN(totvert, sizeof(float), __func__)); BLI_bitmap *edge_tag = BLI_BITMAP_NEW(totedge, "edge tag"); if (!ss->epmap) { @@ -242,7 +243,7 @@ static float *SCULPT_geodesic_fallback_create(Object *ob, GSet *initial_verts) SculptSession *ss = ob->sculpt; Mesh *mesh = BKE_object_get_original_mesh(ob); const int totvert = mesh->totvert; - float *dists = MEM_malloc_arrayN(totvert, sizeof(float), "distances"); + float *dists = static_cast(MEM_malloc_arrayN(totvert, sizeof(float), __func__)); int first_affected = SCULPT_GEODESIC_VERTEX_NONE; GSetIterator gs_iter; GSET_ITER (gs_iter, initial_verts) { @@ -279,7 +280,7 @@ float *SCULPT_geodesic_distances_create(Object *ob, GSet *initial_verts, const f return SCULPT_geodesic_fallback_create(ob, initial_verts); } BLI_assert(false); - return NULL; + return nullptr; } float *SCULPT_geodesic_from_vertex_and_symm(Sculpt *sd, @@ -300,7 +301,7 @@ float *SCULPT_geodesic_from_vertex_and_symm(Sculpt *sd, } else { float location[3]; - flip_v3_v3(location, SCULPT_vertex_co_get(ss, vertex), i); + flip_v3_v3(location, SCULPT_vertex_co_get(ss, vertex), ePaintSymmetryFlags(i)); v = SCULPT_nearest_vertex_get(sd, ob, location, FLT_MAX, false); } if (v.i != PBVH_REF_NONE) { @@ -310,7 +311,7 @@ float *SCULPT_geodesic_from_vertex_and_symm(Sculpt *sd, } float *dists = SCULPT_geodesic_distances_create(ob, initial_verts, limit_radius); - BLI_gset_free(initial_verts, NULL); + BLI_gset_free(initial_verts, nullptr); return dists; } @@ -320,6 +321,6 @@ float *SCULPT_geodesic_from_vertex(Object *ob, const PBVHVertRef vertex, const f BLI_gset_add(initial_verts, POINTER_FROM_INT(BKE_pbvh_vertex_to_index(ob->sculpt->pbvh, vertex))); float *dists = SCULPT_geodesic_distances_create(ob, initial_verts, limit_radius); - BLI_gset_free(initial_verts, NULL); + BLI_gset_free(initial_verts, nullptr); return dists; } From 37dfce550f10462b4d2e5bf8185d21ea01a1eb9f Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 20 Jan 2023 20:15:31 +0100 Subject: [PATCH 0837/1522] Fix Cycles CUDA compiler warning with if constexpr This is a C++17 feature, compiler should be able to figure this out without the hint. --- .../cycles/kernel/closure/bsdf_microfacet.h | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 83051f08f40..80c47bc9542 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -210,7 +210,7 @@ ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, /* 2. sample P22_{wi}(x_slope, y_slope, 1, 1) */ float slope_x, slope_y; - if constexpr (m_type == MicrofacetType::BECKMANN) { + if (m_type == MicrofacetType::BECKMANN) { microfacet_beckmann_sample_slopes( kg, costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i); } @@ -275,13 +275,14 @@ ccl_device_forceinline float bsdf_clearcoat_D(float alpha2, float cos_NH) template ccl_device_inline float bsdf_G1_from_sqr_alpha_tan_n(float sqr_alpha_tan_n) { - if constexpr (m_type == MicrofacetType::GGX) { + if (m_type == MicrofacetType::GGX) { return 2.0f / (1.0f + sqrtf(1.0f + sqr_alpha_tan_n)); } - - /* m_type == MicrofacetType::BECKMANN */ - const float a = inversesqrtf(sqr_alpha_tan_n); - return (a > 1.6f) ? 1.0f : ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f); + else { + /* m_type == MicrofacetType::BECKMANN */ + const float a = inversesqrtf(sqr_alpha_tan_n); + return (a > 1.6f) ? 1.0f : ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f); + } } template ccl_device_inline float bsdf_G1(float alpha2, float cos_N) @@ -308,12 +309,13 @@ template ccl_device_inline float bsdf_D(float alpha2, flo { const float cos_NH2 = sqr(cos_NH); - if constexpr (m_type == MicrofacetType::BECKMANN) { + if (m_type == MicrofacetType::BECKMANN) { return expf((1.0f - 1.0f / cos_NH2) / alpha2) / (M_PI_F * alpha2 * sqr(cos_NH2)); } - - /* m_type == MicrofacetType::GGX */ - return alpha2 / (M_PI_F * sqr(1.0f + (alpha2 - 1.0f) * cos_NH2)); + else { + /* m_type == MicrofacetType::GGX */ + return alpha2 / (M_PI_F * sqr(1.0f + (alpha2 - 1.0f) * cos_NH2)); + } } template @@ -324,12 +326,13 @@ ccl_device_inline float bsdf_aniso_D(float alpha_x, float alpha_y, float3 H) const float cos_NH2 = sqr(H.z); const float alpha2 = alpha_x * alpha_y; - if constexpr (m_type == MicrofacetType::BECKMANN) { + if (m_type == MicrofacetType::BECKMANN) { return expf(-(sqr(H.x) + sqr(H.y)) / cos_NH2) / (M_PI_F * alpha2 * sqr(cos_NH2)); } - - /* m_type == MicrofacetType::GGX */ - return M_1_PI_F / (alpha2 * sqr(len_squared(H))); + else { + /* m_type == MicrofacetType::GGX */ + return M_1_PI_F / (alpha2 * sqr(len_squared(H))); + } } ccl_device_forceinline void bsdf_microfacet_fresnel_color(ccl_private const ShaderData *sd, From 244c87dd680c4f5b5acfcd088aaae0e04298c4f5 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 20 Jan 2023 21:27:13 +0100 Subject: [PATCH 0838/1522] Geometry Nodes: avoid geometry copy if nothing is selected in Set Position node This improves performance in cases where the Set Position node is "turned off" by passing `false` into the selection input. It's possible that the node still takes some time in this case currently, because it is destructing the input fields which may reference geometries that need to be destructed as well. We could potentially change this node (and others) so that the field inputs are only requested when the selection is not a constant `false`. --- .../geometry/nodes/node_geo_set_position.cc | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc index 2ad126567d1..4f6a256620a 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_set_position.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_set_position.cc @@ -116,19 +116,22 @@ static void set_computed_position_and_offset(GeometryComponent &component, } } -static void set_position_in_component(GeometryComponent &component, +static void set_position_in_component(GeometrySet &geometry, + GeometryComponentType component_type, const Field &selection_field, const Field &position_field, const Field &offset_field) { - eAttrDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ? ATTR_DOMAIN_INSTANCE : - ATTR_DOMAIN_POINT; - bke::GeometryFieldContext field_context{component, domain}; + const GeometryComponent &component = *geometry.get_component_for_read(component_type); + const eAttrDomain domain = component.type() == GEO_COMPONENT_TYPE_INSTANCES ? + ATTR_DOMAIN_INSTANCE : + ATTR_DOMAIN_POINT; const int domain_size = component.attribute_domain_size(domain); if (domain_size == 0) { return; } + bke::GeometryFieldContext field_context{component, domain}; fn::FieldEvaluator evaluator{field_context, domain_size}; evaluator.set_selection(selection_field); evaluator.add(position_field); @@ -136,10 +139,14 @@ static void set_position_in_component(GeometryComponent &component, evaluator.evaluate(); const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); + if (selection.is_empty()) { + return; + } + GeometryComponent &mutable_component = geometry.get_component_for_write(component_type); const VArray positions_input = evaluator.get_evaluated(0); const VArray offsets_input = evaluator.get_evaluated(1); - set_computed_position_and_offset(component, positions_input, offsets_input, selection); + set_computed_position_and_offset(mutable_component, positions_input, offsets_input, selection); } static void node_geo_exec(GeoNodeExecParams params) @@ -154,8 +161,7 @@ static void node_geo_exec(GeoNodeExecParams params) GEO_COMPONENT_TYPE_CURVE, GEO_COMPONENT_TYPE_INSTANCES}) { if (geometry.has(type)) { - set_position_in_component( - geometry.get_component_for_write(type), selection_field, position_field, offset_field); + set_position_in_component(geometry, type, selection_field, position_field, offset_field); } } From 453724894ea5c0f02ffd90ff3a9508477259e73b Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 20 Jan 2023 15:34:13 -0600 Subject: [PATCH 0839/1522] Fix T103704: Particle hair doesn't fall back to active UV Caused by 05952aa94d33eeb504fa, which removed the use of the active tessface UV pointer on meshes but didn't replace it properly with the equivalend custom data API function. --- source/blender/blenkernel/intern/particle.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/particle.cc b/source/blender/blenkernel/intern/particle.cc index 99dfd7fe138..514accf098b 100644 --- a/source/blender/blenkernel/intern/particle.cc +++ b/source/blender/blenkernel/intern/particle.cc @@ -4216,7 +4216,9 @@ static int get_particle_uv(Mesh *mesh, int i; tf = static_cast(CustomData_get_layer_named(&mesh->fdata, CD_MTFACE, name)); - + if (tf == nullptr) { + tf = static_cast(CustomData_get_layer(&mesh->fdata, CD_MTFACE)); + } if (tf == nullptr) { return 0; } From a82c12ae32d94e2ec15a5ad81012ab9f93ab2b33 Mon Sep 17 00:00:00 2001 From: Martijn Versteegh Date: Sat, 21 Jan 2023 00:03:42 +0100 Subject: [PATCH 0840/1522] Add collection properties to MeshUVLoopLayer to access UV and the associated bool attributes (Python API). This adds 4 collection properties to MeshUVLoopLayer to eventually replace the (MeshUVLoop) .data property. The added properties are: .uv .vertex_selection .edge_selection .pin The direct access to the separate arrays is much more efficient than the access via MeshUVLoop. Differential Revision: https://developer.blender.org/D16998 --- source/blender/makesrna/intern/rna_mesh.c | 175 +++++++++++++++++++++- 1 file changed, 171 insertions(+), 4 deletions(-) diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 7c8e7431652..18f89636f1b 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -986,16 +986,128 @@ static char *rna_MeshUVLoopLayer_path(const PointerRNA *ptr) static void rna_MeshUVLoopLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { - Mesh *me = rna_mesh(ptr); + Mesh *mesh = rna_mesh(ptr); CustomDataLayer *layer = (CustomDataLayer *)ptr->data; rna_iterator_array_begin( - iter, layer->data, sizeof(float[2]), (me->edit_mesh) ? 0 : me->totloop, 0, NULL); + iter, layer->data, sizeof(float[2]), (mesh->edit_mesh) ? 0 : mesh->totloop, 0, NULL); } static int rna_MeshUVLoopLayer_data_length(PointerRNA *ptr) +{ + Mesh *mesh = rna_mesh(ptr); + return (mesh->edit_mesh) ? 0 : mesh->totloop; +} + +static MBoolProperty *MeshUVLoopLayer_get_bool_layer(Mesh *mesh, char const *name) +{ + void *layer = CustomData_get_layer_named_for_write( + &mesh->ldata, CD_PROP_BOOL, name, mesh->totloop); + if (layer == NULL) { + layer = CustomData_add_layer_named( + &mesh->ldata, CD_PROP_BOOL, CD_SET_DEFAULT, NULL, mesh->totloop, name); + } + + BLI_assert(layer); + + return (MBoolProperty *)layer; +} + +static void bool_layer_begin(CollectionPropertyIterator *iter, + PointerRNA *ptr, + const char *(*layername_func)(const char *uv_name, char *name)) +{ + char bool_layer_name[MAX_CUSTOMDATA_LAYER_NAME]; + Mesh *mesh = rna_mesh(ptr); + CustomDataLayer *layer = (CustomDataLayer *)ptr->data; + layername_func(layer->name, bool_layer_name); + + rna_iterator_array_begin(iter, + MeshUVLoopLayer_get_bool_layer(mesh, bool_layer_name), + sizeof(MBoolProperty), + (mesh->edit_mesh) ? 0 : mesh->totloop, + 0, + NULL); +} + +static int bool_layer_lookup_int(PointerRNA *ptr, + int index, + PointerRNA *r_ptr, + const char *(*layername_func)(const char *uv_name, char *name)) +{ + char bool_layer_name[MAX_CUSTOMDATA_LAYER_NAME]; + Mesh *mesh = rna_mesh(ptr); + if (mesh->edit_mesh || index < 0 || index >= mesh->totloop) { + return 0; + } + CustomDataLayer *layer = (CustomDataLayer *)ptr->data; + layername_func(layer->name, bool_layer_name); + + r_ptr->owner_id = &mesh->id; + r_ptr->type = &RNA_BoolAttributeValue; + r_ptr->data = MeshUVLoopLayer_get_bool_layer(mesh, bool_layer_name) + index; + return 1; +} + +/* Collection accessors for vert_select. */ +static void rna_MeshUVLoopLayer_vert_select_begin(CollectionPropertyIterator *iter, + PointerRNA *ptr) +{ + bool_layer_begin(iter, ptr, BKE_uv_map_vert_select_name_get); +} + +static int rna_MeshUVLoopLayer_vert_select_lookup_int(PointerRNA *ptr, + int index, + PointerRNA *r_ptr) +{ + return bool_layer_lookup_int(ptr, index, r_ptr, BKE_uv_map_vert_select_name_get); +} + +/* Collection accessors for edge_select. */ +static void rna_MeshUVLoopLayer_edge_select_begin(CollectionPropertyIterator *iter, + PointerRNA *ptr) +{ + bool_layer_begin(iter, ptr, BKE_uv_map_edge_select_name_get); +} + +static int rna_MeshUVLoopLayer_edge_select_lookup_int(PointerRNA *ptr, + int index, + PointerRNA *r_ptr) +{ + return bool_layer_lookup_int(ptr, index, r_ptr, BKE_uv_map_edge_select_name_get); +} + +/* Collection accessors for pin. */ +static void rna_MeshUVLoopLayer_pin_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) +{ + bool_layer_begin(iter, ptr, BKE_uv_map_pin_name_get); +} + +static int rna_MeshUVLoopLayer_pin_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr) +{ + return bool_layer_lookup_int(ptr, index, r_ptr, BKE_uv_map_pin_name_get); +} + +static void rna_MeshUVLoopLayer_uv_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) { Mesh *me = rna_mesh(ptr); - return (me->edit_mesh) ? 0 : me->totloop; + CustomDataLayer *layer = (CustomDataLayer *)ptr->data; + + rna_iterator_array_begin( + iter, layer->data, sizeof(float[2]), (me->edit_mesh) ? 0 : me->totloop, 0, NULL); +} + +int rna_MeshUVLoopLayer_uv_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr) +{ + Mesh *mesh = rna_mesh(ptr); + if (mesh->edit_mesh || index < 0 || index >= mesh->totloop) { + return 0; + } + CustomDataLayer *layer = (CustomDataLayer *)ptr->data; + + r_ptr->owner_id = &mesh->id; + r_ptr->type = &RNA_Float2AttributeValue; + r_ptr->data = (float *)layer->data + 2 * index; + return 1; } static bool rna_MeshUVLoopLayer_active_render_get(PointerRNA *ptr) @@ -2801,8 +2913,63 @@ static void rna_def_mloopuv(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Active Clone", "Set the map as active for cloning"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all"); + prop = RNA_def_property(srna, "uv", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "Float2AttributeValue"); + RNA_def_property_ui_text(prop, "UV", "UV coordinates on face corners")); + RNA_def_property_collection_funcs(prop, + "rna_MeshUVLoopLayer_uv_begin", + "rna_iterator_array_next", + "rna_iterator_array_end", + "rna_iterator_array_get", + "rna_MeshUVLoopLayer_data_length", + "rna_MeshUVLoopLayer_uv_lookup_int", + NULL, + NULL); + + prop = RNA_def_property(srna, "vertex_selection", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "BoolAttributeValue"); + RNA_def_property_ui_text( + prop, "UV Vertex Selection", "Selection state of the face corner the UV editor"); + RNA_def_property_collection_funcs(prop, + "rna_MeshUVLoopLayer_vert_select_begin", + "rna_iterator_array_next", + "rna_iterator_array_end", + "rna_iterator_array_get", + "rna_MeshUVLoopLayer_data_length", + "rna_MeshUVLoopLayer_vert_select_lookup_int", + NULL, + NULL); + + prop = RNA_def_property(srna, "edge_selection", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "BoolAttributeValue"); + RNA_def_property_ui_text( + prop, "UV Edge Selection", "Selection state of the edge in the UV editor"); + RNA_def_property_collection_funcs(prop, + "rna_MeshUVLoopLayer_edge_select_begin", + "rna_iterator_array_next", + "rna_iterator_array_end", + "rna_iterator_array_get", + "rna_MeshUVLoopLayer_data_length", + "rna_MeshUVLoopLayer_edge_select_lookup_int", + NULL, + NULL); + + prop = RNA_def_property(srna, "pin", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "BoolAttributeValue"); + RNA_def_property_ui_text(prop, "UV Pin", "UV pinned state in the uv editor"); + RNA_def_property_collection_funcs(prop, + "rna_MeshUVLoopLayer_pin_begin", + "rna_iterator_array_next", + "rna_iterator_array_end", + "rna_iterator_array_get", + "rna_MeshUVLoopLayer_data_length", + "rna_MeshUVLoopLayer_pin_lookup_int", + NULL, + NULL); + srna = RNA_def_struct(brna, "MeshUVLoop", NULL); - RNA_def_struct_ui_text(srna, "Mesh UV Layer", "Layer of UV coordinates in a Mesh data-block"); + RNA_def_struct_ui_text( + srna, "Mesh UV Layer", "(Deprecated) Layer of UV coordinates in a Mesh data-block"); RNA_def_struct_path_func(srna, "rna_MeshUVLoop_path"); prop = RNA_def_property(srna, "uv", PROP_FLOAT, PROP_XYZ); From 6a22230db4eee17d36af676f3c8828b8a9316a7e Mon Sep 17 00:00:00 2001 From: Martijn Versteegh Date: Sat, 21 Jan 2023 00:22:17 +0100 Subject: [PATCH 0841/1522] Fix : accidentally committed typo, roo many closing brackets. Ooops --- source/blender/makesrna/intern/rna_mesh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 18f89636f1b..5ab36c1aa7d 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -2915,7 +2915,7 @@ static void rna_def_mloopuv(BlenderRNA *brna) prop = RNA_def_property(srna, "uv", PROP_COLLECTION, PROP_NONE); RNA_def_property_struct_type(prop, "Float2AttributeValue"); - RNA_def_property_ui_text(prop, "UV", "UV coordinates on face corners")); + RNA_def_property_ui_text(prop, "UV", "UV coordinates on face corners"); RNA_def_property_collection_funcs(prop, "rna_MeshUVLoopLayer_uv_begin", "rna_iterator_array_next", From 2ea47e0def6a1d572879cdfcc1af66f926a1e5cf Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 20 Jan 2023 17:36:07 -0600 Subject: [PATCH 0842/1522] Geometry Nodes: Use checkbox for exposed boolean sockets This uses the changes from ef68a37e5d55e17adf4c to create IDProperties for exposed boolean sockets with a boolean type instead of an integer with a [0,1] range. Existing properties and values are converted automatically. For forward compatibility, the properties are switched to the integer type for saving. Otherwise older versions crash immediately when opening a newer file. The "Use Attribute" IDProperties aren't changed here, since that wouldn't have a visible benefit. Differential Revision: https://developer.blender.org/D12816 --- source/blender/blenkernel/BKE_idprop.hh | 3 + .../blenkernel/intern/idprop_create.cc | 9 +++ source/blender/modifiers/intern/MOD_nodes.cc | 73 ++++++++++++++----- 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/source/blender/blenkernel/BKE_idprop.hh b/source/blender/blenkernel/BKE_idprop.hh index ce11a56ad5f..10110517402 100644 --- a/source/blender/blenkernel/BKE_idprop.hh +++ b/source/blender/blenkernel/BKE_idprop.hh @@ -32,6 +32,9 @@ class IDPropertyDeleter { } }; +/** \brief Allocate a new IDProperty of type IDP_BOOLEAN, set its name and value. */ +std::unique_ptr create_bool(StringRefNull prop_name, bool value); + /** \brief Allocate a new IDProperty of type IDP_INT, set its name and value. */ std::unique_ptr create(StringRefNull prop_name, int32_t value); diff --git a/source/blender/blenkernel/intern/idprop_create.cc b/source/blender/blenkernel/intern/idprop_create.cc index 8a6e5cdcc50..cac4f736c69 100644 --- a/source/blender/blenkernel/intern/idprop_create.cc +++ b/source/blender/blenkernel/intern/idprop_create.cc @@ -21,6 +21,15 @@ std::unique_ptr create(const StringRefNull prop_n return std::unique_ptr(property); } +std::unique_ptr create_bool(const StringRefNull prop_name, + bool value) +{ + IDPropertyTemplate prop_template{0}; + prop_template.i = value; + IDProperty *property = IDP_New(IDP_BOOLEAN, &prop_template, prop_name.c_str()); + return std::unique_ptr(property); +} + std::unique_ptr create(const StringRefNull prop_name, float value) { IDPropertyTemplate prop_template{0}; diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 1261cf56b26..9c63ee7ce15 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -496,10 +496,8 @@ id_property_create_from_socket(const bNodeSocket &socket) case SOCK_BOOLEAN: { const bNodeSocketValueBoolean *value = static_cast( socket.default_value); - auto property = bke::idprop::create(socket.identifier, int(value->value)); - IDPropertyUIDataInt *ui_data = (IDPropertyUIDataInt *)IDP_ui_data_ensure(property.get()); - ui_data->min = ui_data->soft_min = 0; - ui_data->max = ui_data->soft_max = 1; + auto property = bke::idprop::create_bool(socket.identifier, value->value); + IDPropertyUIDataBool *ui_data = (IDPropertyUIDataBool *)IDP_ui_data_ensure(property.get()); ui_data->default_value = value->value != 0; return property; } @@ -553,7 +551,7 @@ static bool id_property_type_matches_socket(const bNodeSocket &socket, const IDP case SOCK_RGBA: return property.type == IDP_ARRAY && property.subtype == IDP_FLOAT && property.len == 4; case SOCK_BOOLEAN: - return property.type == IDP_INT; + return property.type == IDP_BOOLEAN; case SOCK_STRING: return property.type == IDP_STRING; case SOCK_OBJECT: @@ -601,7 +599,7 @@ static void init_socket_cpp_value_from_property(const IDProperty &property, break; } case SOCK_BOOLEAN: { - bool value = IDP_Int(&property) != 0; + const bool value = IDP_Bool(&property); new (r_value) ValueOrField(value); break; } @@ -682,16 +680,23 @@ void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd) if (old_properties != nullptr) { IDProperty *old_prop = IDP_GetPropertyFromGroup(old_properties, socket->identifier); - if (old_prop != nullptr && id_property_type_matches_socket(*socket, *old_prop)) { - /* #IDP_CopyPropertyContent replaces the UI data as well, which we don't (we only - * want to replace the values). So release it temporarily and replace it after. */ - IDPropertyUIData *ui_data = new_prop->ui_data; - new_prop->ui_data = nullptr; - IDP_CopyPropertyContent(new_prop, old_prop); - if (new_prop->ui_data != nullptr) { - IDP_ui_data_free(new_prop); + if (old_prop != nullptr) { + if (id_property_type_matches_socket(*socket, *old_prop)) { + /* #IDP_CopyPropertyContent replaces the UI data as well, which we don't (we only + * want to replace the values). So release it temporarily and replace it after. */ + IDPropertyUIData *ui_data = new_prop->ui_data; + new_prop->ui_data = nullptr; + IDP_CopyPropertyContent(new_prop, old_prop); + if (new_prop->ui_data != nullptr) { + IDP_ui_data_free(new_prop); + } + new_prop->ui_data = ui_data; + } + else if (old_prop->type == IDP_INT && new_prop->type == IDP_BOOLEAN) { + /* Support versioning from integer to boolean property values. The actual value is stored + * in the same variable for both types. */ + new_prop->data.val = old_prop->data.val != 0; } - new_prop->ui_data = ui_data; } } @@ -1575,9 +1580,17 @@ static void add_attribute_search_or_value_buttons(const bContext &C, uiLayout *split = uiLayoutSplit(layout, 0.4f, false); uiLayout *name_row = uiLayoutRow(split, false); uiLayoutSetAlignment(name_row, UI_LAYOUT_ALIGN_RIGHT); - uiItemL(name_row, socket.name, ICON_NONE); + if (socket.type == SOCK_BOOLEAN) { + uiItemL(name_row, "", ICON_NONE); + } + else { + uiItemL(name_row, socket.name, ICON_NONE); + } uiLayout *prop_row = uiLayoutRow(split, true); + if (socket.type == SOCK_BOOLEAN) { + uiLayoutSetAlignment(prop_row, UI_LAYOUT_ALIGN_LEFT); + } PointerRNA props; uiItemFullO(prop_row, @@ -1594,10 +1607,10 @@ static void add_attribute_search_or_value_buttons(const bContext &C, const int use_attribute = RNA_int_get(md_ptr, rna_path_use_attribute.c_str()) != 0; if (use_attribute) { add_attribute_search_button(C, prop_row, nmd, md_ptr, rna_path_attribute_name, socket, false); - uiItemL(layout, "", ICON_BLANK1); } else { - uiItemR(prop_row, md_ptr, rna_path.c_str(), 0, "", ICON_NONE); + const char *name = socket.type == SOCK_BOOLEAN ? socket.name : ""; + uiItemR(prop_row, md_ptr, rna_path.c_str(), 0, name, ICON_NONE); uiItemDecoratorR(layout, md_ptr, rna_path.c_str(), -1); } } @@ -1854,9 +1867,33 @@ static void blendWrite(BlendWriter *writer, const ID * /*id_owner*/, const Modif BLO_write_struct(writer, NodesModifierData, nmd); if (nmd->settings.properties != nullptr) { + /* Boolean properties are added automatically for boolean node group inputs. Integer properties + * are automatically converted to boolean sockets where applicable as well. However, boolean + * properties will crash old versions of Blender, so convert them to integer properties for + * writing. The actual value is stored in the same variable for both types */ + Map boolean_props; + LISTBASE_FOREACH (IDProperty *, prop, &nmd->settings.properties->data.group) { + if (prop->type == IDP_BOOLEAN) { + boolean_props.add_new(prop, reinterpret_cast(prop->ui_data)); + prop->type = IDP_INT; + prop->ui_data = nullptr; + } + } + /* Note that the property settings are based on the socket type info * and don't necessarily need to be written, but we can't just free them. */ IDP_BlendWrite(writer, nmd->settings.properties); + + LISTBASE_FOREACH (IDProperty *, prop, &nmd->settings.properties->data.group) { + if (prop->type == IDP_INT) { + if (IDPropertyUIDataBool **ui_data = boolean_props.lookup_ptr(prop)) { + prop->type = IDP_BOOLEAN; + if (ui_data) { + prop->ui_data = reinterpret_cast(*ui_data); + } + } + } + } } } From 68625431d5d0b2e178df506fc0fabe81e9b44fcb Mon Sep 17 00:00:00 2001 From: Leon Schittek Date: Fri, 20 Jan 2023 17:41:34 -0600 Subject: [PATCH 0843/1522] Geometry Nodes: Adjust modifier UI to put field toggles on the right This also fixes the layout of boolean properties with the field toggle visible. This was discussed in the most recent geometry nodes submodule meeting. --- source/blender/modifiers/intern/MOD_nodes.cc | 30 ++++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 9c63ee7ce15..e487abc4248 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1580,7 +1580,9 @@ static void add_attribute_search_or_value_buttons(const bContext &C, uiLayout *split = uiLayoutSplit(layout, 0.4f, false); uiLayout *name_row = uiLayoutRow(split, false); uiLayoutSetAlignment(name_row, UI_LAYOUT_ALIGN_RIGHT); - if (socket.type == SOCK_BOOLEAN) { + + const int use_attribute = RNA_int_get(md_ptr, rna_path_use_attribute.c_str()) != 0; + if (socket.type == SOCK_BOOLEAN && !use_attribute) { uiItemL(name_row, "", ICON_NONE); } else { @@ -1589,7 +1591,18 @@ static void add_attribute_search_or_value_buttons(const bContext &C, uiLayout *prop_row = uiLayoutRow(split, true); if (socket.type == SOCK_BOOLEAN) { - uiLayoutSetAlignment(prop_row, UI_LAYOUT_ALIGN_LEFT); + uiLayoutSetPropSep(prop_row, false); + uiLayoutSetAlignment(prop_row, UI_LAYOUT_ALIGN_EXPAND); + } + + if (use_attribute) { + add_attribute_search_button(C, prop_row, nmd, md_ptr, rna_path_attribute_name, socket, false); + uiItemL(layout, "", ICON_BLANK1); + } + else { + const char *name = socket.type == SOCK_BOOLEAN ? socket.name : ""; + uiItemR(prop_row, md_ptr, rna_path.c_str(), 0, name, ICON_NONE); + uiItemDecoratorR(layout, md_ptr, rna_path.c_str(), -1); } PointerRNA props; @@ -1603,16 +1616,6 @@ static void add_attribute_search_or_value_buttons(const bContext &C, &props); RNA_string_set(&props, "modifier_name", nmd.modifier.name); RNA_string_set(&props, "prop_path", rna_path_use_attribute.c_str()); - - const int use_attribute = RNA_int_get(md_ptr, rna_path_use_attribute.c_str()) != 0; - if (use_attribute) { - add_attribute_search_button(C, prop_row, nmd, md_ptr, rna_path_attribute_name, socket, false); - } - else { - const char *name = socket.type == SOCK_BOOLEAN ? socket.name : ""; - uiItemR(prop_row, md_ptr, rna_path.c_str(), 0, name, ICON_NONE); - uiItemDecoratorR(layout, md_ptr, rna_path.c_str(), -1); - } } /* Drawing the properties manually with #uiItemR instead of #uiDefAutoButsRNA allows using @@ -1678,6 +1681,9 @@ static void draw_property_for_socket(const bContext &C, } } } + if (!input_has_attribute_toggle(*nmd->node_group, socket_index)) { + uiItemL(row, "", ICON_BLANK1); + } } static void draw_property_for_output_socket(const bContext &C, From 25864d3dfc6be77b9b0f3757a648b90620776091 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Mon, 9 Jan 2023 00:19:26 -0500 Subject: [PATCH 0844/1522] Cleanup: Use ampersand instead of "and" for labels UI guideline is use '&' for labels, use "and" for descriptions. --- source/blender/draw/intern/draw_color_management.cc | 2 +- source/blender/makesrna/intern/rna_space.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/draw/intern/draw_color_management.cc b/source/blender/draw/intern/draw_color_management.cc index eab86226be5..a5d73f93780 100644 --- a/source/blender/draw/intern/draw_color_management.cc +++ b/source/blender/draw/intern/draw_color_management.cc @@ -62,7 +62,7 @@ static eDRWColorManagementType drw_color_management_type_for_space_image(const S { Image *image = sima.image; - /* Use inverse logic as there isn't a setting for `Color And Alpha`. */ + /* Use inverse logic as there isn't a setting for `Color & Alpha`. */ const eSpaceImage_Flag display_channels_mode = static_cast(sima.flag); const bool display_color_channel = (display_channels_mode & (SI_SHOW_ALPHA | SI_SHOW_ZBUF)) == 0; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 15ed20ce354..a5f2f4a0892 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -371,7 +371,7 @@ static const EnumPropertyItem display_channels_items[] = { {SI_USE_ALPHA, "COLOR_ALPHA", ICON_IMAGE_RGB_ALPHA, - "Color and Alpha", + "Color & Alpha", "Display image with RGB colors and alpha transparency"}, {0, "COLOR", ICON_IMAGE_RGB, "Color", "Display image with RGB colors"}, {SI_SHOW_ALPHA, "ALPHA", ICON_IMAGE_ALPHA, "Alpha", "Display alpha transparency channel"}, @@ -5773,7 +5773,7 @@ static void rna_def_space_sequencer(BlenderRNA *brna) {SEQ_USE_ALPHA, "COLOR_ALPHA", ICON_IMAGE_RGB_ALPHA, - "Color and Alpha", + "Color & Alpha", "Display image with RGB colors and alpha transparency"}, {0, "COLOR", ICON_IMAGE_RGB, "Color", "Display image with RGB colors"}, {0, NULL, 0, NULL, NULL}, @@ -7363,7 +7363,7 @@ static void rna_def_space_node(BlenderRNA *brna) {SNODE_USE_ALPHA, "COLOR_ALPHA", ICON_IMAGE_RGB_ALPHA, - "Color and Alpha", + "Color & Alpha", "Display image with RGB colors and alpha transparency"}, {0, "COLOR", ICON_IMAGE_RGB, "Color", "Display image with RGB colors"}, {SNODE_SHOW_ALPHA, "ALPHA", ICON_IMAGE_ALPHA, "Alpha", "Display alpha transparency channel"}, From b5bb38400f6663563ab348857b95fe9b7e1d7d92 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Fri, 20 Jan 2023 21:42:24 -0500 Subject: [PATCH 0845/1522] Python API: Set defaults for Denoise Node Fixes T103898 --- source/blender/makesrna/intern/rna_nodetree.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index eeb88be0fe2..e007457297e 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -9197,11 +9197,13 @@ static void def_cmp_denoise(StructRNA *srna) prop = RNA_def_property(srna, "use_hdr", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "hdr", 0); + RNA_def_property_boolean_default(prop, true); RNA_def_property_ui_text(prop, "HDR", "Process HDR images"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "prefilter", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prefilter_items); + RNA_def_property_enum_default(prop, CMP_NODE_DENOISE_PREFILTER_ACCURATE); RNA_def_property_ui_text(prop, "", "Denoising prefilter"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } From 6aa29549e889679112fd55f8d4a867c860646387 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 20 Jan 2023 11:51:43 +0100 Subject: [PATCH 0846/1522] Fix T103887: Line Art Vertex Weight Transfer to target group broken Caused by {rB841df831e89d} and {rB3558bb8eae75}. These commits moved flags from `eLineArtGPencilModifierFlags` to `eLineartMainFlags`, but later on in code, these were still evaluated from the modifiers `flags` (instead of `calculation_flags`). This resulted in a false condition (`match_output` was assumed true but it wasnt), leading to a wrong codepath taken. This is now corrected (`calculation_flags` need to be passed around for this as well). Maniphest Tasks: T103887 Differential Revision: https://developer.blender.org/D17062 --- .../gpencil_modifiers/intern/MOD_gpencillineart.c | 3 ++- .../gpencil_modifiers/intern/lineart/MOD_lineart.h | 3 ++- .../gpencil_modifiers/intern/lineart/lineart_cpu.cc | 13 ++++++++----- .../gpencil_modifiers/intern/lineart/lineart_ops.c | 3 ++- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c index 88c7ab9d96c..995dc268123 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c @@ -89,7 +89,8 @@ static void generate_strokes_actual( lmd->silhouette_selection, lmd->source_vertex_group, lmd->vgname, - lmd->flags); + lmd->flags, + lmd->calculation_flags); } static bool isModifierDisabled(GpencilModifierData *md) diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h index 9cd88e2d523..8909e9c8ccb 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h +++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h @@ -923,7 +923,8 @@ void MOD_lineart_gpencil_generate(LineartCache *cache, uint8_t silhouette_mode, const char *source_vgname, const char *vgname, - int modifier_flags); + int modifier_flags, + int modifier_calculation_flags); /** * Length is in image space. diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc index 4361ec0f86d..fe8621bb9fe 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.cc @@ -5156,7 +5156,8 @@ static void lineart_gpencil_generate(LineartCache *cache, uchar silhouette_mode, const char *source_vgname, const char *vgname, - int modifier_flags) + int modifier_flags, + int modifier_calculation_flags) { if (cache == nullptr) { if (G.debug_value == 4000) { @@ -5182,8 +5183,8 @@ static void lineart_gpencil_generate(LineartCache *cache, /* (!orig_col && !orig_ob) means the whole scene is selected. */ int enabled_types = cache->all_enabled_edge_types; - bool invert_input = modifier_flags & LRT_GPENCIL_INVERT_SOURCE_VGROUP; - bool match_output = modifier_flags & LRT_GPENCIL_MATCH_OUTPUT_VGROUP; + bool invert_input = modifier_calculation_flags & LRT_GPENCIL_INVERT_SOURCE_VGROUP; + bool match_output = modifier_calculation_flags & LRT_GPENCIL_MATCH_OUTPUT_VGROUP; bool inverse_silhouette = modifier_flags & LRT_GPENCIL_INVERT_SILHOUETTE_FILTER; LISTBASE_FOREACH (LineartEdgeChain *, ec, &cache->chains) { @@ -5381,7 +5382,8 @@ void MOD_lineart_gpencil_generate(LineartCache *cache, uchar silhouette_mode, const char *source_vgname, const char *vgname, - int modifier_flags) + int modifier_flags, + int modifier_calculation_flags) { if (!gpl || !gpf || !ob) { @@ -5427,5 +5429,6 @@ void MOD_lineart_gpencil_generate(LineartCache *cache, silhouette_mode, source_vgname, vgname, - modifier_flags); + modifier_flags, + modifier_calculation_flags); } diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c index 6f44cc68a19..45ceb646361 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_ops.c @@ -136,7 +136,8 @@ static bool bake_strokes(Object *ob, lmd->silhouette_selection, lmd->source_vertex_group, lmd->vgname, - lmd->flags); + lmd->flags, + lmd->calculation_flags); if (!(lmd->flags & LRT_GPENCIL_USE_CACHE)) { /* Clear local cache. */ From 65f68ee023ea344783050a2b36788ee18cccdf8a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 21 Jan 2023 23:09:20 +1100 Subject: [PATCH 0847/1522] Cleanup: compiler warnings --- source/blender/blenkernel/intern/subsurf_ccg.cc | 2 +- source/blender/editors/include/ED_curves.h | 1 + source/blender/editors/sculpt_paint/sculpt_expand.cc | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/subsurf_ccg.cc b/source/blender/blenkernel/intern/subsurf_ccg.cc index a7342bb93b0..a3c634bff89 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.cc +++ b/source/blender/blenkernel/intern/subsurf_ccg.cc @@ -1094,7 +1094,7 @@ static void ccgDM_copyFinalPolyArray(DerivedMesh *dm, MPoly *mpoly) for (index = 0; index < totface; index++) { CCGFace *f = ccgdm->faceMap[index].face; int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - int flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH; + char flag = (faceFlags) ? faceFlags[index].flag : char(ME_SMOOTH); for (S = 0; S < numVerts; S++) { for (y = 0; y < gridSize - 1; y++) { diff --git a/source/blender/editors/include/ED_curves.h b/source/blender/editors/include/ED_curves.h index 9cb673ff9e4..9c76713e3f4 100644 --- a/source/blender/editors/include/ED_curves.h +++ b/source/blender/editors/include/ED_curves.h @@ -8,6 +8,7 @@ struct bContext; struct Curves; +struct UndoType; #ifdef __cplusplus extern "C" { diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.cc b/source/blender/editors/sculpt_paint/sculpt_expand.cc index 532466ab426..a125545c010 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.cc +++ b/source/blender/editors/sculpt_paint/sculpt_expand.cc @@ -1865,7 +1865,7 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event return OPERATOR_FINISHED; } case SCULPT_EXPAND_MODAL_FALLOFF_GEODESIC: { - expand_cache->falloff_gradient = SCULPT_EXPAND_MODAL_FALLOFF_GEODESIC; + expand_cache->falloff_gradient = true; sculpt_expand_check_topology_islands(ob); sculpt_expand_falloff_factors_from_vertex_and_symm_create( @@ -1889,7 +1889,7 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event break; } case SCULPT_EXPAND_MODAL_FALLOFF_TOPOLOGY_DIAGONALS: { - expand_cache->falloff_gradient = SCULPT_EXPAND_MODAL_FALLOFF_TOPOLOGY_DIAGONALS; + expand_cache->falloff_gradient = true; sculpt_expand_check_topology_islands(ob); sculpt_expand_falloff_factors_from_vertex_and_symm_create( From cbd15d387f8418d85048a3051e64e510a18d10a9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 21 Jan 2023 23:09:22 +1100 Subject: [PATCH 0848/1522] GHOST/Wayland: don't send activate/deactivate on pointer enter/leave This isn't correct as window activation is handled separately from the cursor entering/leaving a window. This would call de-activate when the cursor moved outside the window even though the window remained focused. Rely on focus changes which already handle activate/deactivate events. --- intern/ghost/intern/GHOST_SystemWayland.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 6a163d8661e..3911014d8cb 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -2586,8 +2586,6 @@ static void pointer_handle_enter(void *data, GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface); - win->activate(); - GWL_Seat *seat = static_cast(data); seat->cursor_source_serial = serial; seat->pointer.serial = serial; @@ -2627,8 +2625,6 @@ static void pointer_handle_leave(void *data, static_cast(data)->pointer.wl_surface_window = nullptr; if (wl_surface && ghost_wl_surface_own(wl_surface)) { CLOG_INFO(LOG, 2, "leave"); - GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface); - win->deactivate(); } else { CLOG_INFO(LOG, 2, "leave (skipped)"); From 0b17d171d77d5b3bcf5fc1a95fc57f89385dbf20 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sat, 21 Jan 2023 12:13:34 -0600 Subject: [PATCH 0849/1522] Cleanup: Move three modifier related files to C++ For continued refactoring of the Mesh data structure. See T103343. --- source/blender/blenkernel/CMakeLists.txt | 6 +- .../{cdderivedmesh.c => cdderivedmesh.cc} | 32 +- .../{dynamicpaint.c => dynamicpaint.cc} | 994 +++++++++--------- .../blenkernel/intern/{fluid.c => fluid.cc} | 323 +++--- .../blender/editors/armature/CMakeLists.txt | 2 +- .../{meshlaplacian.c => meshlaplacian.cc} | 127 ++- .../blender/editors/armature/meshlaplacian.h | 8 + source/blender/editors/include/ED_armature.h | 2 +- .../blender/editors/physics/physics_intern.h | 2 +- 9 files changed, 782 insertions(+), 714 deletions(-) rename source/blender/blenkernel/intern/{cdderivedmesh.c => cdderivedmesh.cc} (90%) rename source/blender/blenkernel/intern/{dynamicpaint.c => dynamicpaint.cc} (88%) rename source/blender/blenkernel/intern/{fluid.c => fluid.cc} (95%) rename source/blender/editors/armature/{meshlaplacian.c => meshlaplacian.cc} (91%) diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index bfef13649e3..8a714d8d911 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -89,7 +89,7 @@ set(SRC intern/cachefile.c intern/callbacks.c intern/camera.c - intern/cdderivedmesh.c + intern/cdderivedmesh.cc intern/cloth.cc intern/collection.c intern/collision.c @@ -121,7 +121,7 @@ set(SRC intern/data_transfer.cc intern/deform.c intern/displist.cc - intern/dynamicpaint.c + intern/dynamicpaint.cc intern/editlattice.c intern/editmesh.cc intern/editmesh_bvh.c @@ -131,7 +131,7 @@ set(SRC intern/fcurve.c intern/fcurve_cache.c intern/fcurve_driver.c - intern/fluid.c + intern/fluid.cc intern/fmodifier.c intern/freestyle.c intern/geometry_component_curves.cc diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.cc similarity index 90% rename from source/blender/blenkernel/intern/cdderivedmesh.c rename to source/blender/blenkernel/intern/cdderivedmesh.cc index a5d179fb2cb..9cf5f7ecedf 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.cc @@ -7,6 +7,10 @@ * BKE_cdderivedmesh.h contains the function prototypes for this file. */ +#include +#include +#include + #include "atomic_ops.h" #include "BLI_math.h" @@ -29,11 +33,7 @@ #include "MEM_guardedalloc.h" -#include -#include -#include - -typedef struct { +struct CDDerivedMesh { DerivedMesh dm; /* these point to data in the DerivedMesh custom data layers, @@ -52,7 +52,7 @@ typedef struct { /* Mesh connectivity */ MeshElemMap *pmap; int *pmap_mem; -} CDDerivedMesh; +}; /**************** DerivedMesh interface functions ****************/ static int cdDM_getNumVerts(DerivedMesh *dm) @@ -157,11 +157,8 @@ static void cdDM_release(DerivedMesh *dm) /**************** CDDM interface functions ****************/ static CDDerivedMesh *cdDM_create(const char *desc) { - CDDerivedMesh *cddm; - DerivedMesh *dm; - - cddm = MEM_callocN(sizeof(*cddm), desc); - dm = &cddm->dm; + CDDerivedMesh *cddm = MEM_cnew(desc); + DerivedMesh *dm = &cddm->dm; dm->getNumVerts = cdDM_getNumVerts; dm->getNumEdges = cdDM_getNumEdges; @@ -221,14 +218,17 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh, CustomData_merge(&mesh->ldata, &dm->loopData, cddata_masks.lmask, alloctype, mesh->totloop); CustomData_merge(&mesh->pdata, &dm->polyData, cddata_masks.pmask, alloctype, mesh->totpoly); - cddm->vert_positions = CustomData_get_layer_named_for_write( - &dm->vertData, CD_PROP_FLOAT3, "position", mesh->totvert); + cddm->vert_positions = static_cast(CustomData_get_layer_named_for_write( + &dm->vertData, CD_PROP_FLOAT3, "position", mesh->totvert)); /* Though this may be an unnecessary calculation, simply retrieving the layer may return nothing * or dirty normals. */ cddm->vert_normals = BKE_mesh_vertex_normals_ensure(mesh); - cddm->medge = CustomData_get_layer_for_write(&dm->edgeData, CD_MEDGE, mesh->totedge); - cddm->mloop = CustomData_get_layer_for_write(&dm->loopData, CD_MLOOP, mesh->totloop); - cddm->mpoly = CustomData_get_layer_for_write(&dm->polyData, CD_MPOLY, mesh->totpoly); + cddm->medge = static_cast( + CustomData_get_layer_for_write(&dm->edgeData, CD_MEDGE, mesh->totedge)); + cddm->mloop = static_cast( + CustomData_get_layer_for_write(&dm->loopData, CD_MLOOP, mesh->totloop)); + cddm->mpoly = static_cast( + CustomData_get_layer_for_write(&dm->polyData, CD_MPOLY, mesh->totpoly)); #if 0 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); #else diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.cc similarity index 88% rename from source/blender/blenkernel/intern/dynamicpaint.c rename to source/blender/blenkernel/intern/dynamicpaint.cc index eff08db9f46..4c6cad1f5e6 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.cc @@ -127,16 +127,16 @@ BLI_INLINE void value_dissolve(float *r_value, /***************************** Internal Structs ***************************/ -typedef struct Bounds2D { +struct Bounds2D { float min[2], max[2]; -} Bounds2D; +}; -typedef struct Bounds3D { +struct Bounds3D { float min[3], max[3]; bool valid; -} Bounds3D; +}; -typedef struct VolumeGrid { +struct VolumeGrid { int dim[3]; /** whole grid bounds */ Bounds3D grid_bounds; @@ -151,29 +151,29 @@ typedef struct VolumeGrid { int *t_index; int *temp_t_index; -} VolumeGrid; +}; -typedef struct Vec3f { +struct Vec3f { float v[3]; -} Vec3f; +}; -typedef struct BakeAdjPoint { +struct BakeAdjPoint { /** vector pointing towards this neighbor */ float dir[3]; /** distance to */ float dist; -} BakeAdjPoint; +}; /** Surface data used while processing a frame */ -typedef struct PaintBakeNormal { +struct PaintBakeNormal { /** current pixel world-space inverted normal */ float invNorm[3]; /** normal directional scale for displace mapping */ float normal_scale; -} PaintBakeNormal; +}; /** Temp surface data used to process a frame */ -typedef struct PaintBakeData { +struct PaintBakeData { /* point space data */ PaintBakeNormal *bNormal; /** index to start reading point sample realCoord */ @@ -206,10 +206,10 @@ typedef struct PaintBakeData { float prev_obmat[4][4]; /** flag to check if surface was cleared/reset -> have to redo velocity etc. */ int clear; -} PaintBakeData; +}; /** UV Image sequence format point */ -typedef struct PaintUVPoint { +struct PaintUVPoint { /* Pixel / mesh data */ /** tri index on domain derived mesh */ uint tri_index; @@ -219,18 +219,18 @@ typedef struct PaintUVPoint { /** If this pixel isn't uv mapped to any face, but its neighboring pixel is. */ uint neighbor_pixel; -} PaintUVPoint; +}; -typedef struct ImgSeqFormatData { +struct ImgSeqFormatData { PaintUVPoint *uv_p; Vec3f *barycentricWeights; /* b-weights for all pixel samples */ -} ImgSeqFormatData; +}; /* adjacency data flags */ #define ADJ_ON_MESH_EDGE (1 << 0) #define ADJ_BORDER_PIXEL (1 << 1) -typedef struct PaintAdjData { +struct PaintAdjData { /** Array of neighboring point indexes, for single sample use (n_index + neigh_num). */ int *n_target; /** Index to start reading n_target for each point. */ @@ -245,27 +245,27 @@ typedef struct PaintAdjData { int *border; /** Size of border. */ int total_border; -} PaintAdjData; +}; /************************* Runtime evaluation store ***************************/ void dynamicPaint_Modifier_free_runtime(DynamicPaintRuntime *runtime_data) { - if (runtime_data == NULL) { + if (runtime_data == nullptr) { return; } if (runtime_data->canvas_mesh) { - BKE_id_free(NULL, runtime_data->canvas_mesh); + BKE_id_free(nullptr, runtime_data->canvas_mesh); } if (runtime_data->brush_mesh) { - BKE_id_free(NULL, runtime_data->brush_mesh); + BKE_id_free(nullptr, runtime_data->brush_mesh); } MEM_freeN(runtime_data); } static DynamicPaintRuntime *dynamicPaint_Modifier_runtime_ensure(DynamicPaintModifierData *pmd) { - if (pmd->modifier.runtime == NULL) { + if (pmd->modifier.runtime == nullptr) { pmd->modifier.runtime = MEM_callocN(sizeof(DynamicPaintRuntime), "dynamic paint runtime"); } return (DynamicPaintRuntime *)pmd->modifier.runtime; @@ -273,8 +273,8 @@ static DynamicPaintRuntime *dynamicPaint_Modifier_runtime_ensure(DynamicPaintMod static Mesh *dynamicPaint_canvas_mesh_get(DynamicPaintCanvasSettings *canvas) { - if (canvas->pmd->modifier.runtime == NULL) { - return NULL; + if (canvas->pmd->modifier.runtime == nullptr) { + return nullptr; } DynamicPaintRuntime *runtime_data = (DynamicPaintRuntime *)canvas->pmd->modifier.runtime; return runtime_data->canvas_mesh; @@ -282,8 +282,8 @@ static Mesh *dynamicPaint_canvas_mesh_get(DynamicPaintCanvasSettings *canvas) static Mesh *dynamicPaint_brush_mesh_get(DynamicPaintBrushSettings *brush) { - if (brush->pmd->modifier.runtime == NULL) { - return NULL; + if (brush->pmd->modifier.runtime == nullptr) { + return nullptr; } DynamicPaintRuntime *runtime_data = (DynamicPaintRuntime *)brush->pmd->modifier.runtime; return runtime_data->brush_mesh; @@ -316,10 +316,10 @@ static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface) DynamicPaintSurface *get_activeSurface(DynamicPaintCanvasSettings *canvas) { - return BLI_findlink(&canvas->surfaces, canvas->active_sur); + return static_cast(BLI_findlink(&canvas->surfaces, canvas->active_sur)); } -bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object *ob, int output) +bool dynamicPaint_outputLayerExists(DynamicPaintSurface *surface, Object *ob, int output) { const char *name; @@ -335,7 +335,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; + Mesh *me = static_cast(ob->data); return (CustomData_get_named_layer_index(&me->ldata, CD_PROP_BYTE_COLOR, name) != -1); } if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { @@ -348,8 +348,9 @@ bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object static bool surface_duplicateOutputExists(void *arg, const char *name) { - DynamicPaintSurface *t_surface = arg; - DynamicPaintSurface *surface = t_surface->canvas->surfaces.first; + DynamicPaintSurface *t_surface = static_cast(arg); + DynamicPaintSurface *surface = static_cast( + t_surface->canvas->surfaces.first); for (; surface; surface = surface->next) { if (surface != t_surface && surface->type == t_surface->type && @@ -387,8 +388,9 @@ static void surface_setUniqueOutputName(DynamicPaintSurface *surface, char *base static bool surface_duplicateNameExists(void *arg, const char *name) { - DynamicPaintSurface *t_surface = arg; - DynamicPaintSurface *surface = t_surface->canvas->surfaces.first; + DynamicPaintSurface *t_surface = static_cast(arg); + DynamicPaintSurface *surface = static_cast( + t_surface->canvas->surfaces.first); for (; surface; surface = surface->next) { if (surface != t_surface && STREQ(name, surface->name)) { @@ -406,7 +408,7 @@ void dynamicPaintSurface_setUniqueName(DynamicPaintSurface *surface, const char surface_duplicateNameExists, surface, name, '.', surface->name, sizeof(surface->name)); } -void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface) +void dynamicPaintSurface_updateType(DynamicPaintSurface *surface) { if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { surface->output_name[0] = '\0'; @@ -516,7 +518,7 @@ static int surface_getBrushFlags(DynamicPaintSurface *surface, Depsgraph *depsgr { uint numobjects; Object **objects = BKE_collision_objects_create( - depsgraph, NULL, surface->brush_group, &numobjects, eModifierType_DynamicPaint); + depsgraph, nullptr, surface->brush_group, &numobjects, eModifierType_DynamicPaint); int flags = 0; @@ -622,26 +624,26 @@ static void freeGrid(PaintSurfaceData *data) } MEM_freeN(bData->grid); - bData->grid = NULL; + bData->grid = nullptr; } static void grid_bound_insert_cb_ex(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict tls) { - PaintBakeData *bData = userdata; + PaintBakeData *bData = static_cast(userdata); - Bounds3D *grid_bound = tls->userdata_chunk; + Bounds3D *grid_bound = static_cast(tls->userdata_chunk); boundInsert(grid_bound, bData->realCoord[bData->s_pos[i]].v); } -static void grid_bound_insert_reduce(const void *__restrict UNUSED(userdata), +static void grid_bound_insert_reduce(const void *__restrict /*userdata*/, void *__restrict chunk_join, void *__restrict chunk) { - Bounds3D *join = chunk_join; - Bounds3D *grid_bound = chunk; + Bounds3D *join = static_cast(chunk_join); + Bounds3D *grid_bound = static_cast(chunk); boundInsert(join, grid_bound->min); boundInsert(join, grid_bound->max); @@ -651,10 +653,10 @@ static void grid_cell_points_cb_ex(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict tls) { - PaintBakeData *bData = userdata; + PaintBakeData *bData = static_cast(userdata); VolumeGrid *grid = bData->grid; int *temp_t_index = grid->temp_t_index; - int *s_num = tls->userdata_chunk; + int *s_num = static_cast(tls->userdata_chunk); int co[3]; @@ -672,12 +674,12 @@ static void grid_cell_points_reduce(const void *__restrict userdata, void *__restrict chunk_join, void *__restrict chunk) { - const PaintBakeData *bData = userdata; + const PaintBakeData *bData = static_cast(userdata); const VolumeGrid *grid = bData->grid; const int grid_cells = grid->dim[0] * grid->dim[1] * grid->dim[2]; - int *join_s_num = chunk_join; - int *s_num = chunk; + int *join_s_num = static_cast(chunk_join); + int *s_num = static_cast(chunk); /* calculate grid indexes */ for (int i = 0; i < grid_cells; i++) { @@ -687,9 +689,9 @@ static void grid_cell_points_reduce(const void *__restrict userdata, static void grid_cell_bounds_cb(void *__restrict userdata, const int x, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - PaintBakeData *bData = userdata; + PaintBakeData *bData = static_cast(userdata); VolumeGrid *grid = bData->grid; float *dim = bData->dim; int *grid_dim = grid->dim; @@ -708,20 +710,20 @@ static void grid_cell_bounds_cb(void *__restrict userdata, } } -static void surfaceGenerateGrid(struct DynamicPaintSurface *surface) +static void surfaceGenerateGrid(DynamicPaintSurface *surface) { PaintSurfaceData *sData = surface->data; PaintBakeData *bData = sData->bData; VolumeGrid *grid; int grid_cells, axis = 3; - int *temp_t_index = NULL; - int *temp_s_num = NULL; + int *temp_t_index = nullptr; + int *temp_s_num = nullptr; if (bData->grid) { freeGrid(sData); } - bData->grid = MEM_callocN(sizeof(VolumeGrid), "Surface Grid"); + bData->grid = MEM_cnew(__func__); grid = bData->grid; { @@ -758,7 +760,7 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface) if (axis == 0 || max_fff(td[0], td[1], td[2]) < 0.0001f) { MEM_freeN(bData->grid); - bData->grid = NULL; + bData->grid = nullptr; return; } @@ -777,14 +779,18 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface) grid_cells = grid->dim[0] * grid->dim[1] * grid->dim[2]; /* allocate memory for grids */ - grid->bounds = MEM_callocN(sizeof(Bounds3D) * grid_cells, "Surface Grid Bounds"); - grid->s_pos = MEM_callocN(sizeof(int) * grid_cells, "Surface Grid Position"); + grid->bounds = static_cast( + MEM_callocN(sizeof(Bounds3D) * grid_cells, "Surface Grid Bounds")); + grid->s_pos = static_cast( + MEM_callocN(sizeof(int) * grid_cells, "Surface Grid Position")); - grid->s_num = MEM_callocN(sizeof(int) * grid_cells, "Surface Grid Points"); - temp_s_num = MEM_callocN(sizeof(int) * grid_cells, "Temp Surface Grid Points"); - grid->t_index = MEM_callocN(sizeof(int) * sData->total_points, "Surface Grid Target Ids"); - grid->temp_t_index = temp_t_index = MEM_callocN(sizeof(int) * sData->total_points, - "Temp Surface Grid Target Ids"); + grid->s_num = static_cast(MEM_callocN(sizeof(int) * grid_cells, "Surface Grid Points")); + temp_s_num = static_cast( + MEM_callocN(sizeof(int) * grid_cells, "Temp Surface Grid Points")); + grid->t_index = static_cast( + MEM_callocN(sizeof(int) * sData->total_points, "Surface Grid Target Ids")); + grid->temp_t_index = temp_t_index = static_cast( + MEM_callocN(sizeof(int) * sData->total_points, "Temp Surface Grid Target Ids")); /* in case of an allocation failure abort here */ if (!grid->bounds || !grid->s_pos || !grid->s_num || !grid->t_index || !temp_s_num || @@ -840,7 +846,7 @@ static void surfaceGenerateGrid(struct DynamicPaintSurface *surface) /***************************** Freeing data ******************************/ -void dynamicPaint_freeBrush(struct DynamicPaintModifierData *pmd) +void dynamicPaint_freeBrush(DynamicPaintModifierData *pmd) { if (pmd->brush) { if (pmd->brush->paint_ramp) { @@ -851,7 +857,7 @@ void dynamicPaint_freeBrush(struct DynamicPaintModifierData *pmd) } MEM_freeN(pmd->brush); - pmd->brush = NULL; + pmd->brush = nullptr; } } @@ -874,7 +880,7 @@ static void dynamicPaint_freeAdjData(PaintSurfaceData *data) MEM_freeN(data->adj_data->border); } MEM_freeN(data->adj_data); - data->adj_data = NULL; + data->adj_data = nullptr; } } @@ -911,7 +917,7 @@ static void free_bakeData(PaintSurfaceData *data) } MEM_freeN(data->bData); - data->bData = NULL; + data->bData = nullptr; } } @@ -958,7 +964,7 @@ void dynamicPaint_freeSurfaceData(DynamicPaintSurface *surface) free_bakeData(data); MEM_freeN(surface->data); - surface->data = NULL; + surface->data = nullptr; } void dynamicPaint_freeSurface(const DynamicPaintModifierData *pmd, DynamicPaintSurface *surface) @@ -967,7 +973,7 @@ void dynamicPaint_freeSurface(const DynamicPaintModifierData *pmd, DynamicPaintS if ((pmd->modifier.flag & eModifierFlag_SharedCaches) == 0) { BKE_ptcache_free_list(&(surface->ptcaches)); } - surface->pointcache = NULL; + surface->pointcache = nullptr; MEM_SAFE_FREE(surface->effector_weights); @@ -980,8 +986,8 @@ void dynamicPaint_freeCanvas(DynamicPaintModifierData *pmd) { if (pmd->canvas) { /* Free surface data */ - DynamicPaintSurface *surface = pmd->canvas->surfaces.first; - DynamicPaintSurface *next_surface = NULL; + DynamicPaintSurface *surface = static_cast(pmd->canvas->surfaces.first); + DynamicPaintSurface *next_surface = nullptr; while (surface) { next_surface = surface->next; @@ -990,18 +996,18 @@ void dynamicPaint_freeCanvas(DynamicPaintModifierData *pmd) } MEM_freeN(pmd->canvas); - pmd->canvas = NULL; + pmd->canvas = nullptr; } } void dynamicPaint_Modifier_free(DynamicPaintModifierData *pmd) { - if (pmd == NULL) { + if (pmd == nullptr) { return; } dynamicPaint_freeCanvas(pmd); dynamicPaint_freeBrush(pmd); - dynamicPaint_Modifier_free_runtime(pmd->modifier.runtime); + dynamicPaint_Modifier_free_runtime(static_cast(pmd->modifier.runtime)); } /***************************** Initialize and reset ******************************/ @@ -1009,9 +1015,9 @@ void dynamicPaint_Modifier_free(DynamicPaintModifierData *pmd) DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *canvas, Scene *scene) { - DynamicPaintSurface *surface = MEM_callocN(sizeof(DynamicPaintSurface), "DynamicPaintSurface"); + DynamicPaintSurface *surface = MEM_cnew(__func__); if (!surface) { - return NULL; + return nullptr; } surface->canvas = canvas; @@ -1074,7 +1080,7 @@ DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *c /* Using ID_BRUSH i18n context, as we have no physics/dynamic-paint one for now. */ dynamicPaintSurface_setUniqueName(surface, CTX_DATA_(BLT_I18NCONTEXT_ID_BRUSH, "Surface")); - surface->effector_weights = BKE_effector_add_weights(NULL); + surface->effector_weights = BKE_effector_add_weights(nullptr); dynamicPaintSurface_updateType(surface); @@ -1083,7 +1089,7 @@ DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *c return surface; } -bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, struct Scene *scene) +bool dynamicPaint_createType(DynamicPaintModifierData *pmd, int type, Scene *scene) { if (pmd) { if (type == MOD_DYNAMICPAINT_TYPE_CANVAS) { @@ -1092,8 +1098,7 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str dynamicPaint_freeCanvas(pmd); } - canvas = pmd->canvas = MEM_callocN(sizeof(DynamicPaintCanvasSettings), - "DynamicPaint Canvas"); + canvas = pmd->canvas = MEM_cnew(__func__); if (!canvas) { return false; } @@ -1110,13 +1115,13 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str dynamicPaint_freeBrush(pmd); } - brush = pmd->brush = MEM_callocN(sizeof(DynamicPaintBrushSettings), "DynamicPaint Paint"); + brush = pmd->brush = MEM_cnew(__func__); if (!brush) { return false; } brush->pmd = pmd; - brush->psys = NULL; + brush->psys = nullptr; brush->flags = MOD_DPAINT_ABS_ALPHA | MOD_DPAINT_RAMP_ALPHA; brush->collision = MOD_DPAINT_COL_VOLUME; @@ -1178,17 +1183,17 @@ bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, str return true; } -void dynamicPaint_Modifier_copy(const struct DynamicPaintModifierData *pmd, - struct DynamicPaintModifierData *tpmd, +void dynamicPaint_Modifier_copy(const DynamicPaintModifierData *pmd, + DynamicPaintModifierData *tpmd, int flag) { /* Init modifier */ tpmd->type = pmd->type; if (pmd->canvas) { - dynamicPaint_createType(tpmd, MOD_DYNAMICPAINT_TYPE_CANVAS, NULL); + dynamicPaint_createType(tpmd, MOD_DYNAMICPAINT_TYPE_CANVAS, nullptr); } if (pmd->brush) { - dynamicPaint_createType(tpmd, MOD_DYNAMICPAINT_TYPE_BRUSH, NULL); + dynamicPaint_createType(tpmd, MOD_DYNAMICPAINT_TYPE_BRUSH, nullptr); } /* Copy data */ @@ -1197,14 +1202,16 @@ void dynamicPaint_Modifier_copy(const struct DynamicPaintModifierData *pmd, tpmd->canvas->pmd = tpmd; /* free default surface */ if (tpmd->canvas->surfaces.first) { - dynamicPaint_freeSurface(tpmd, tpmd->canvas->surfaces.first); + dynamicPaint_freeSurface(tpmd, + static_cast(tpmd->canvas->surfaces.first)); } tpmd->canvas->active_sur = pmd->canvas->active_sur; /* copy existing surfaces */ - for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) { - DynamicPaintSurface *t_surface = dynamicPaint_createNewSurface(tpmd->canvas, NULL); + for (surface = static_cast(pmd->canvas->surfaces.first); surface; + surface = surface->next) { + DynamicPaintSurface *t_surface = dynamicPaint_createNewSurface(tpmd->canvas, nullptr); if (flag & LIB_ID_COPY_SET_COPIED_ON_WRITE) { /* TODO(sergey): Consider passing some tips to the surface * creation to avoid this allocate-and-free cache behavior. */ @@ -1217,7 +1224,8 @@ void dynamicPaint_Modifier_copy(const struct DynamicPaintModifierData *pmd, /* surface settings */ t_surface->brush_group = surface->brush_group; MEM_freeN(t_surface->effector_weights); - t_surface->effector_weights = MEM_dupallocN(surface->effector_weights); + t_surface->effector_weights = static_cast( + MEM_dupallocN(surface->effector_weights)); BLI_strncpy(t_surface->name, surface->name, sizeof(t_surface->name)); t_surface->format = surface->format; @@ -1332,7 +1340,7 @@ static void dynamicPaint_allocateSurfaceType(DynamicPaintSurface *surface) break; } - if (sData->type_data == NULL) { + if (sData->type_data == nullptr) { setError(surface->canvas, N_("Not enough free memory")); } } @@ -1375,17 +1383,21 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b } /* allocate memory */ - ad = sData->adj_data = MEM_callocN(sizeof(PaintAdjData), "Surface Adj Data"); + ad = sData->adj_data = MEM_cnew(__func__); if (!ad) { return; } - ad->n_index = MEM_callocN(sizeof(int) * sData->total_points, "Surface Adj Index"); - ad->n_num = MEM_callocN(sizeof(int) * sData->total_points, "Surface Adj Counts"); - temp_data = MEM_callocN(sizeof(int) * sData->total_points, "Temp Adj Data"); - ad->n_target = MEM_callocN(sizeof(int) * neigh_points, "Surface Adj Targets"); - ad->flags = MEM_callocN(sizeof(int) * sData->total_points, "Surface Adj Flags"); + ad->n_index = static_cast( + MEM_callocN(sizeof(int) * sData->total_points, "Surface Adj Index")); + ad->n_num = static_cast( + MEM_callocN(sizeof(int) * sData->total_points, "Surface Adj Counts")); + temp_data = static_cast(MEM_callocN(sizeof(int) * sData->total_points, "Temp Adj Data")); + ad->n_target = static_cast( + MEM_callocN(sizeof(int) * neigh_points, "Surface Adj Targets")); + ad->flags = static_cast( + MEM_callocN(sizeof(int) * sData->total_points, "Surface Adj Flags")); ad->total_targets = neigh_points; - ad->border = NULL; + ad->border = nullptr; ad->total_border = 0; /* in case of allocation error, free memory */ @@ -1464,22 +1476,23 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b MEM_freeN(temp_data); } -typedef struct DynamicPaintSetInitColorData { +struct DynamicPaintSetInitColorData { const DynamicPaintSurface *surface; const MLoop *mloop; const float (*mloopuv)[2]; const MLoopTri *mlooptri; const MLoopCol *mloopcol; - struct ImagePool *pool; + ImagePool *pool; - const bool scene_color_manage; -} DynamicPaintSetInitColorData; + bool scene_color_manage; +}; -static void dynamic_paint_set_init_color_tex_to_vcol_cb( - void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls)) +static void dynamic_paint_set_init_color_tex_to_vcol_cb(void *__restrict userdata, + const int i, + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintSetInitColorData *data = userdata; + const DynamicPaintSetInitColorData *data = static_cast(userdata); const PaintSurfaceData *sData = data->surface->data; PaintPoint *pPoint = (PaintPoint *)sData->type_data; @@ -1487,7 +1500,7 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb( const MLoop *mloop = data->mloop; const MLoopTri *mlooptri = data->mlooptri; const float(*mloopuv)[2] = data->mloopuv; - struct ImagePool *pool = data->pool; + ImagePool *pool = data->pool; Tex *tex = data->surface->init_texture; const bool scene_color_manage = data->scene_color_manage; @@ -1511,10 +1524,11 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb( } } -static void dynamic_paint_set_init_color_tex_to_imseq_cb( - void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls)) +static void dynamic_paint_set_init_color_tex_to_imseq_cb(void *__restrict userdata, + const int i, + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintSetInitColorData *data = userdata; + const DynamicPaintSetInitColorData *data = static_cast(userdata); const PaintSurfaceData *sData = data->surface->data; PaintPoint *pPoint = (PaintPoint *)sData->type_data; @@ -1543,7 +1557,7 @@ static void dynamic_paint_set_init_color_tex_to_imseq_cb( uv_final[0] = uv_final[0] * 2.0f - 1.0f; uv_final[1] = uv_final[1] * 2.0f - 1.0f; - multitex_ext_safe(tex, uv_final, &texres, NULL, scene_color_manage, false); + multitex_ext_safe(tex, uv_final, &texres, nullptr, scene_color_manage, false); /* apply color */ copy_v3_v3(pPoint[i].color, texres.trgba); @@ -1551,9 +1565,9 @@ static void dynamic_paint_set_init_color_tex_to_imseq_cb( } static void dynamic_paint_set_init_color_vcol_to_imseq_cb( - void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls)) + void *__restrict userdata, const int i, const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintSetInitColorData *data = userdata; + const DynamicPaintSetInitColorData *data = static_cast(userdata); const PaintSurfaceData *sData = data->surface->data; PaintPoint *pPoint = (PaintPoint *)sData->type_data; @@ -1616,7 +1630,8 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface /* get uv map */ CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, surface->init_layername, uvname); - const float(*mloopuv)[2] = CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname); + const float(*mloopuv)[2] = static_cast( + CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname)); if (!mloopuv) { return; @@ -1627,14 +1642,14 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { struct ImagePool *pool = BKE_image_pool_new(); - DynamicPaintSetInitColorData data = { - .surface = surface, - .mloop = mloop, - .mlooptri = mlooptri, - .mloopuv = mloopuv, - .pool = pool, - .scene_color_manage = scene_color_manage, - }; + DynamicPaintSetInitColorData data{}; + data.surface = surface; + data.mloop = mloop; + data.mlooptri = mlooptri; + data.mloopuv = mloopuv; + data.pool = pool; + data.scene_color_manage = scene_color_manage; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (tottri > 1000); @@ -1643,12 +1658,12 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface BKE_image_pool_free(pool); } else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { - DynamicPaintSetInitColorData data = { - .surface = surface, - .mlooptri = mlooptri, - .mloopuv = mloopuv, - .scene_color_manage = scene_color_manage, - }; + DynamicPaintSetInitColorData data{}; + data.surface = surface; + data.mlooptri = mlooptri; + data.mloopuv = mloopuv; + data.scene_color_manage = scene_color_manage; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (sData->total_points > 1000); @@ -1663,8 +1678,8 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { const MLoop *mloop = BKE_mesh_loops(mesh); const int totloop = mesh->totloop; - const MLoopCol *col = CustomData_get_layer_named( - &mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername); + const MLoopCol *col = static_cast( + CustomData_get_layer_named(&mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername)); if (!col) { return; } @@ -1675,17 +1690,17 @@ 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); - const MLoopCol *col = CustomData_get_layer_named( - &mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername); + const MLoopCol *col = static_cast( + CustomData_get_layer_named(&mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername)); if (!col) { return; } - DynamicPaintSetInitColorData data = { - .surface = surface, - .mlooptri = mlooptri, - .mloopcol = col, - }; + DynamicPaintSetInitColorData data{}; + data.surface = surface; + data.mlooptri = mlooptri; + data.mloopcol = col; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (sData->total_points > 1000); @@ -1741,7 +1756,7 @@ bool dynamicPaint_resetSurface(const Scene *scene, DynamicPaintSurface *surface) } /* allocate memory */ - surface->data = MEM_callocN(sizeof(PaintSurfaceData), "PaintSurfaceData"); + surface->data = MEM_cnew(__func__); if (!surface->data) { return false; } @@ -1771,7 +1786,7 @@ static bool dynamicPaint_checkSurfaceData(const Scene *scene, DynamicPaintSurfac /***************************** Modifier processing ******************************/ -typedef struct DynamicPaintModifierApplyData { +struct DynamicPaintModifierApplyData { const DynamicPaintSurface *surface; Object *ob; @@ -1783,13 +1798,14 @@ typedef struct DynamicPaintModifierApplyData { float (*fcolor)[4]; MLoopCol *mloopcol; MLoopCol *mloopcol_wet; -} DynamicPaintModifierApplyData; +}; static void dynamic_paint_apply_surface_displace_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintModifierApplyData *data = userdata; + const DynamicPaintModifierApplyData *data = static_cast( + userdata); const DynamicPaintSurface *surface = data->surface; @@ -1810,11 +1826,11 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh /* displace paint */ if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) { - DynamicPaintModifierApplyData data = { - .surface = surface, - .vert_positions = BKE_mesh_vert_positions_for_write(result), - .vert_normals = BKE_mesh_vertex_normals_ensure(result), - }; + DynamicPaintModifierApplyData data{}; + data.surface = surface; + data.vert_positions = BKE_mesh_vert_positions_for_write(result); + data.vert_normals = BKE_mesh_vertex_normals_ensure(result); + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (sData->total_points > 10000); @@ -1823,10 +1839,12 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh } } -static void dynamic_paint_apply_surface_vpaint_blend_cb( - void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls)) +static void dynamic_paint_apply_surface_vpaint_blend_cb(void *__restrict userdata, + const int i, + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintModifierApplyData *data = userdata; + const DynamicPaintModifierApplyData *data = static_cast( + userdata); PaintPoint *pPoint = (PaintPoint *)data->surface->data->type_data; float(*fcolor)[4] = data->fcolor; @@ -1838,9 +1856,10 @@ static void dynamic_paint_apply_surface_vpaint_blend_cb( static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata, const int p_index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintModifierApplyData *data = userdata; + const DynamicPaintModifierApplyData *data = static_cast( + userdata); const MLoop *mloop = data->mloop; const MPoly *mpoly = data->mpoly; @@ -1874,9 +1893,10 @@ static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata, static void dynamic_paint_apply_surface_wave_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintModifierApplyData *data = userdata; + const DynamicPaintModifierApplyData *data = static_cast( + userdata); PaintWavePoint *wPoint = (PaintWavePoint *)data->surface->data->type_data; @@ -1896,7 +1916,8 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * DynamicPaintSurface *surface; /* loop through surfaces */ - for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) { + for (surface = static_cast(pmd->canvas->surfaces.first); surface; + surface = surface->next) { PaintSurfaceData *sData = surface->data; if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && sData) { @@ -1915,13 +1936,13 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * const int totpoly = result->totpoly; /* paint is stored on dry and wet layers, so mix final color first */ - float(*fcolor)[4] = MEM_callocN(sizeof(*fcolor) * sData->total_points, - "Temp paint color"); + float(*fcolor)[4] = static_cast( + MEM_callocN(sizeof(*fcolor) * sData->total_points, "Temp paint color")); + + DynamicPaintModifierApplyData data{}; + data.surface = surface; + data.fcolor = fcolor; - DynamicPaintModifierApplyData data = { - .surface = surface, - .fcolor = fcolor, - }; { TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); @@ -1934,29 +1955,30 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * } /* paint layer */ - MLoopCol *mloopcol = CustomData_get_layer_named_for_write( - &result->ldata, CD_PROP_BYTE_COLOR, surface->output_name, result->totloop); + MLoopCol *mloopcol = static_cast(CustomData_get_layer_named_for_write( + &result->ldata, CD_PROP_BYTE_COLOR, surface->output_name, result->totloop)); /* 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_PROP_BYTE_COLOR, - CD_SET_DEFAULT, - NULL, - totloop, - surface->output_name); + mloopcol = static_cast(CustomData_add_layer_named(&result->ldata, + CD_PROP_BYTE_COLOR, + CD_SET_DEFAULT, + nullptr, + totloop, + surface->output_name)); } /* wet layer */ - MLoopCol *mloopcol_wet = CustomData_get_layer_named_for_write( - &result->ldata, CD_PROP_BYTE_COLOR, surface->output_name2, result->totloop); + MLoopCol *mloopcol_wet = static_cast(CustomData_get_layer_named_for_write( + &result->ldata, CD_PROP_BYTE_COLOR, surface->output_name2, result->totloop)); /* 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_PROP_BYTE_COLOR, - CD_SET_DEFAULT, - NULL, - totloop, - surface->output_name2); + mloopcol_wet = static_cast( + CustomData_add_layer_named(&result->ldata, + CD_PROP_BYTE_COLOR, + CD_SET_DEFAULT, + nullptr, + totloop, + surface->output_name2)); } data.ob = ob; @@ -1978,14 +2000,14 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * /* vertex group paint */ else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { int defgrp_index = BKE_object_defgroup_name_index(ob, surface->output_name); - MDeformVert *dvert = CustomData_get_layer_for_write( - &result->vdata, CD_MDEFORMVERT, result->totvert); + MDeformVert *dvert = static_cast( + CustomData_get_layer_for_write(&result->vdata, CD_MDEFORMVERT, result->totvert)); float *weight = (float *)sData->type_data; /* apply weights into a vertex group, if doesn't exists add a new layer */ if (defgrp_index != -1 && !dvert && (surface->output_name[0] != '\0')) { - dvert = CustomData_add_layer( - &result->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, sData->total_points); + dvert = static_cast(CustomData_add_layer( + &result->vdata, CD_MDEFORMVERT, CD_SET_DEFAULT, nullptr, sData->total_points)); } if (defgrp_index != -1 && dvert) { for (int i = 0; i < sData->total_points; i++) { @@ -1993,9 +2015,9 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * MDeformWeight *def_weight = BKE_defvert_find_index(dv, defgrp_index); /* skip if weight value is 0 and no existing weight is found */ - if ((def_weight != NULL) || (weight[i] != 0.0f)) { + if ((def_weight != nullptr) || (weight[i] != 0.0f)) { /* if not found, add a weight for it */ - if (def_weight == NULL) { + if (def_weight == nullptr) { def_weight = BKE_defvert_ensure_index(dv, defgrp_index); } @@ -2007,11 +2029,11 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * } /* wave simulation */ else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) { - DynamicPaintModifierApplyData data = { - .surface = surface, - .vert_positions = BKE_mesh_vert_positions_for_write(result), - .vert_normals = BKE_mesh_vertex_normals_ensure(result), - }; + DynamicPaintModifierApplyData data{}; + data.surface = surface; + data.vert_positions = BKE_mesh_vert_positions_for_write(result); + data.vert_normals = BKE_mesh_vertex_normals_ensure(result); + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (sData->total_points > 1000); @@ -2032,8 +2054,8 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * /* make a copy of mesh to use as brush data */ else if (pmd->brush && pmd->type == MOD_DYNAMICPAINT_TYPE_BRUSH) { DynamicPaintRuntime *runtime_data = dynamicPaint_Modifier_runtime_ensure(pmd); - if (runtime_data->brush_mesh != NULL) { - BKE_id_free(NULL, runtime_data->brush_mesh); + if (runtime_data->brush_mesh != nullptr) { + BKE_id_free(nullptr, runtime_data->brush_mesh); } runtime_data->brush_mesh = BKE_mesh_copy_for_eval(result, false); } @@ -2052,8 +2074,8 @@ void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface) static void canvas_copyMesh(DynamicPaintCanvasSettings *canvas, Mesh *mesh) { DynamicPaintRuntime *runtime = dynamicPaint_Modifier_runtime_ensure(canvas->pmd); - if (runtime->canvas_mesh != NULL) { - BKE_id_free(NULL, runtime->canvas_mesh); + if (runtime->canvas_mesh != nullptr) { + BKE_id_free(nullptr, runtime->canvas_mesh); } runtime->canvas_mesh = BKE_mesh_copy_for_eval(mesh, false); @@ -2062,15 +2084,12 @@ static void canvas_copyMesh(DynamicPaintCanvasSettings *canvas, Mesh *mesh) /* * Updates derived mesh copy and processes dynamic paint step / caches. */ -static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, - struct Depsgraph *depsgraph, - Scene *scene, - Object *ob, - Mesh *mesh) +static void dynamicPaint_frameUpdate( + DynamicPaintModifierData *pmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *mesh) { if (pmd->canvas) { DynamicPaintCanvasSettings *canvas = pmd->canvas; - DynamicPaintSurface *surface = canvas->surfaces.first; + DynamicPaintSurface *surface = static_cast(canvas->surfaces.first); /* update derived mesh copy */ canvas_copyMesh(canvas, mesh); @@ -2095,7 +2114,7 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, } /* make sure surface is valid */ - no_surface_data = surface->data == NULL; + no_surface_data = surface->data == nullptr; if (!dynamicPaint_checkSurfaceData(scene, surface)) { continue; } @@ -2113,7 +2132,7 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, BKE_ptcache_id_from_dynamicpaint(&pid, ob, surface); pid.cache->startframe = surface->start_frame; pid.cache->endframe = surface->end_frame; - BKE_ptcache_id_time(&pid, scene, (float)scene->r.cfra, NULL, NULL, NULL); + BKE_ptcache_id_time(&pid, scene, (float)scene->r.cfra, nullptr, nullptr, nullptr); /* reset non-baked cache at first frame */ if ((int)scene->r.cfra == surface->start_frame && !(cache->flag & PTCACHE_BAKED)) { @@ -2150,11 +2169,8 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, } } -Mesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, - struct Depsgraph *depsgraph, - Scene *scene, - Object *ob, - Mesh *mesh) +Mesh *dynamicPaint_Modifier_do( + DynamicPaintModifierData *pmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *mesh) { /* Update canvas data for a new frame */ dynamicPaint_frameUpdate(pmd, depsgraph, scene, ob, mesh); @@ -2173,7 +2189,7 @@ Mesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, 0.0f, 0.0f, -0.2f, -0.4f, 0.2f, 0.4f, 0.4f, -0.2f, -0.4f, 0.3f, \ } -typedef struct DynamicPaintCreateUVSurfaceData { +struct DynamicPaintCreateUVSurfaceData { const DynamicPaintSurface *surface; PaintUVPoint *tempPoints; @@ -2182,16 +2198,18 @@ typedef struct DynamicPaintCreateUVSurfaceData { const MLoopTri *mlooptri; const float (*mloopuv)[2]; const MLoop *mloop; - const int tottri; + int tottri; const Bounds2D *faceBB; uint32_t *active_points; -} DynamicPaintCreateUVSurfaceData; +}; -static void dynamic_paint_create_uv_surface_direct_cb( - void *__restrict userdata, const int ty, const TaskParallelTLS *__restrict UNUSED(tls)) +static void dynamic_paint_create_uv_surface_direct_cb(void *__restrict userdata, + const int ty, + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintCreateUVSurfaceData *data = userdata; + const DynamicPaintCreateUVSurfaceData *data = + static_cast(userdata); const DynamicPaintSurface *surface = data->surface; PaintUVPoint *tempPoints = data->tempPoints; @@ -2283,10 +2301,12 @@ static void dynamic_paint_create_uv_surface_direct_cb( } } -static void dynamic_paint_create_uv_surface_neighbor_cb( - void *__restrict userdata, const int ty, const TaskParallelTLS *__restrict UNUSED(tls)) +static void dynamic_paint_create_uv_surface_neighbor_cb(void *__restrict userdata, + const int ty, + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintCreateUVSurfaceData *data = userdata; + const DynamicPaintCreateUVSurfaceData *data = + static_cast(userdata); const DynamicPaintSurface *surface = data->surface; PaintUVPoint *tempPoints = data->tempPoints; @@ -2402,13 +2422,13 @@ static float dist_squared_to_looptri_uv_edges(const MLoopTri *mlooptri, return min_distance; } -typedef struct DynamicPaintFindIslandBorderData { +struct DynamicPaintFindIslandBorderData { const MeshElemMap *vert_to_looptri_map; int w, h, px, py; int best_index; float best_weight; -} DynamicPaintFindIslandBorderData; +}; static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceData *data, DynamicPaintFindIslandBorderData *bdata, @@ -2474,15 +2494,14 @@ static int dynamic_paint_find_neighbor_pixel(const DynamicPaintCreateUVSurfaceDa * TODO: Implement something more accurate / optimized? */ { - DynamicPaintFindIslandBorderData bdata = { - .vert_to_looptri_map = vert_to_looptri_map, - .w = w, - .h = h, - .px = px, - .py = py, - .best_index = NOT_FOUND, - .best_weight = 1.0f, - }; + DynamicPaintFindIslandBorderData bdata{}; + bdata.vert_to_looptri_map = vert_to_looptri_map; + bdata.w = w; + bdata.h = h; + bdata.px = px; + bdata.py = py; + bdata.best_index = NOT_FOUND; + bdata.best_weight = 1.0f; float pixel[2]; @@ -2692,8 +2711,10 @@ static bool dynamicPaint_pointHasNeighbor(PaintAdjData *ed, int index, int neigh * I.e. if A is neighbor of B, B is neighbor of A. */ static bool dynamicPaint_symmetrizeAdjData(PaintAdjData *ed, int active_points) { - int *new_n_index = MEM_callocN(sizeof(int) * active_points, "Surface Adj Index"); - int *new_n_num = MEM_callocN(sizeof(int) * active_points, "Surface Adj Counts"); + int *new_n_index = static_cast( + MEM_callocN(sizeof(int) * active_points, "Surface Adj Index")); + int *new_n_num = static_cast( + MEM_callocN(sizeof(int) * active_points, "Surface Adj Counts")); if (new_n_num && new_n_index) { /* Count symmetrized neighbors */ @@ -2722,7 +2743,8 @@ static bool dynamicPaint_symmetrizeAdjData(PaintAdjData *ed, int active_points) } /* Allocate a new target map */ - int *new_n_target = MEM_callocN(sizeof(int) * total_targets, "Surface Adj Targets"); + int *new_n_target = static_cast( + MEM_callocN(sizeof(int) * total_targets, "Surface Adj Targets")); if (new_n_target) { /* Copy existing neighbors to the new map */ @@ -2797,13 +2819,13 @@ int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintCanvasSettings *canvas = surface->canvas; Mesh *mesh = dynamicPaint_canvas_mesh_get(canvas); - PaintUVPoint *tempPoints = NULL; - Vec3f *tempWeights = NULL; - const MLoopTri *mlooptri = NULL; - const float(*mloopuv)[2] = NULL; - const MLoop *mloop = NULL; + PaintUVPoint *tempPoints = nullptr; + Vec3f *tempWeights = nullptr; + const MLoopTri *mlooptri = nullptr; + const float(*mloopuv)[2] = nullptr; + const MLoop *mloop = nullptr; - Bounds2D *faceBB = NULL; + Bounds2D *faceBB = nullptr; int *final_index; *progress = 0.0f; @@ -2823,7 +2845,8 @@ int dynamicPaint_createUVSurface(Scene *scene, /* get uv map */ if (CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) { CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, surface->uvlayer_name, uvname); - mloopuv = CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname); + mloopuv = static_cast( + CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname)); } /* Check for validity */ @@ -2846,22 +2869,25 @@ int dynamicPaint_createUVSurface(Scene *scene, if (surface->data) { dynamicPaint_freeSurfaceData(surface); } - sData = surface->data = MEM_callocN(sizeof(PaintSurfaceData), "PaintSurfaceData"); + sData = surface->data = MEM_cnew(__func__); if (!surface->data) { return setError(canvas, N_("Not enough free memory")); } - tempPoints = MEM_callocN(w * h * sizeof(*tempPoints), "Temp PaintUVPoint"); + tempPoints = static_cast( + MEM_callocN(w * h * sizeof(*tempPoints), "Temp PaintUVPoint")); if (!tempPoints) { error = true; } - final_index = MEM_callocN(w * h * sizeof(*final_index), "Temp UV Final Indexes"); + final_index = static_cast( + MEM_callocN(w * h * sizeof(*final_index), "Temp UV Final Indexes")); if (!final_index) { error = true; } - tempWeights = MEM_mallocN(w * h * aa_samples * sizeof(*tempWeights), "Temp bWeights"); + tempWeights = static_cast( + MEM_mallocN(w * h * aa_samples * sizeof(*tempWeights), "Temp bWeights")); if (!tempWeights) { error = true; } @@ -2871,7 +2897,7 @@ int dynamicPaint_createUVSurface(Scene *scene, * the pixel-inside-a-face search. */ if (!error) { - faceBB = MEM_mallocN(tottri * sizeof(*faceBB), "MPCanvasFaceBB"); + faceBB = static_cast(MEM_mallocN(tottri * sizeof(*faceBB), "MPCanvasFaceBB")); if (!faceBB) { error = true; } @@ -2894,16 +2920,16 @@ int dynamicPaint_createUVSurface(Scene *scene, *do_update = true; /* Loop through every pixel and check if pixel is uv-mapped on a canvas face. */ - DynamicPaintCreateUVSurfaceData data = { - .surface = surface, - .tempPoints = tempPoints, - .tempWeights = tempWeights, - .mlooptri = mlooptri, - .mloopuv = mloopuv, - .mloop = mloop, - .tottri = tottri, - .faceBB = faceBB, - }; + DynamicPaintCreateUVSurfaceData data{}; + data.surface = surface; + data.tempPoints = tempPoints; + data.tempWeights = tempWeights; + data.mlooptri = mlooptri; + data.mloopuv = mloopuv; + data.mloop = mloop; + data.tottri = tottri; + data.faceBB = faceBB; + { TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); @@ -3008,7 +3034,8 @@ int dynamicPaint_createUVSurface(Scene *scene, } /* Create a list of border pixels */ - ed->border = MEM_callocN(sizeof(int) * total_border, "Border Pixel Index"); + ed->border = static_cast( + MEM_callocN(sizeof(int) * total_border, "Border Pixel Index")); if (ed->border) { ed->total_border = total_border; @@ -3068,11 +3095,12 @@ int dynamicPaint_createUVSurface(Scene *scene, *do_update = true; /* Create final surface data without inactive points */ - ImgSeqFormatData *f_data = MEM_callocN(sizeof(*f_data), "ImgSeqFormatData"); + ImgSeqFormatData *f_data = MEM_cnew(__func__); if (f_data) { - f_data->uv_p = MEM_callocN(active_points * sizeof(*f_data->uv_p), "PaintUVPoint"); - f_data->barycentricWeights = MEM_callocN( - active_points * aa_samples * sizeof(*f_data->barycentricWeights), "PaintUVPoint"); + f_data->uv_p = static_cast( + MEM_callocN(active_points * sizeof(*f_data->uv_p), "PaintUVPoint")); + f_data->barycentricWeights = static_cast(MEM_callocN( + active_points * aa_samples * sizeof(*f_data->barycentricWeights), "PaintUVPoint")); if (!f_data->uv_p || !f_data->barycentricWeights) { error = 1; @@ -3166,15 +3194,17 @@ int dynamicPaint_createUVSurface(Scene *scene, /* * Outputs an image file from uv surface data. */ -typedef struct DynamicPaintOutputSurfaceImageData { +struct DynamicPaintOutputSurfaceImageData { const DynamicPaintSurface *surface; ImBuf *ibuf; -} DynamicPaintOutputSurfaceImageData; +}; -static void dynamic_paint_output_surface_image_paint_cb( - void *__restrict userdata, const int index, const TaskParallelTLS *__restrict UNUSED(tls)) +static void dynamic_paint_output_surface_image_paint_cb(void *__restrict userdata, + const int index, + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintOutputSurfaceImageData *data = userdata; + const DynamicPaintOutputSurfaceImageData *data = + static_cast(userdata); const DynamicPaintSurface *surface = data->surface; const PaintPoint *point = &((PaintPoint *)surface->data->type_data)[index]; @@ -3194,9 +3224,10 @@ static void dynamic_paint_output_surface_image_paint_cb( } static void dynamic_paint_output_surface_image_displace_cb( - void *__restrict userdata, const int index, const TaskParallelTLS *__restrict UNUSED(tls)) + void *__restrict userdata, const int index, const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintOutputSurfaceImageData *data = userdata; + const DynamicPaintOutputSurfaceImageData *data = + static_cast(userdata); const DynamicPaintSurface *surface = data->surface; float depth = ((float *)surface->data->type_data)[index]; @@ -3219,10 +3250,12 @@ static void dynamic_paint_output_surface_image_displace_cb( ibuf->rect_float[pos + 3] = 1.0f; } -static void dynamic_paint_output_surface_image_wave_cb( - void *__restrict userdata, const int index, const TaskParallelTLS *__restrict UNUSED(tls)) +static void dynamic_paint_output_surface_image_wave_cb(void *__restrict userdata, + const int index, + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintOutputSurfaceImageData *data = userdata; + const DynamicPaintOutputSurfaceImageData *data = + static_cast(userdata); const DynamicPaintSurface *surface = data->surface; const PaintWavePoint *wPoint = &((PaintWavePoint *)surface->data->type_data)[index]; @@ -3243,10 +3276,12 @@ static void dynamic_paint_output_surface_image_wave_cb( ibuf->rect_float[pos + 3] = 1.0f; } -static void dynamic_paint_output_surface_image_wetmap_cb( - void *__restrict userdata, const int index, const TaskParallelTLS *__restrict UNUSED(tls)) +static void dynamic_paint_output_surface_image_wetmap_cb(void *__restrict userdata, + const int index, + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintOutputSurfaceImageData *data = userdata; + const DynamicPaintOutputSurfaceImageData *data = + static_cast(userdata); const DynamicPaintSurface *surface = data->surface; const PaintPoint *point = &((PaintPoint *)surface->data->type_data)[index]; @@ -3263,7 +3298,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, const char *filepath, short output_layer) { - ImBuf *ibuf = NULL; + ImBuf *ibuf = nullptr; PaintSurfaceData *sData = surface->data; /* OpenEXR or PNG */ int format = (surface->image_fileformat & MOD_DPAINT_IMGFORMAT_OPENEXR) ? R_IMF_IMTYPE_OPENEXR : @@ -3289,15 +3324,15 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, /* Init image buffer */ ibuf = IMB_allocImBuf(surface->image_resolution, surface->image_resolution, 32, IB_rectfloat); - if (ibuf == NULL) { + if (ibuf == nullptr) { setError(surface->canvas, N_("Image save failed: not enough free memory")); return; } - DynamicPaintOutputSurfaceImageData data = { - .surface = surface, - .ibuf = ibuf, - }; + DynamicPaintOutputSurfaceImageData data{}; + data.surface = surface; + data.ibuf = ibuf; + switch (surface->type) { case MOD_DPAINT_SURFACE_T_PAINT: switch (output_layer) { @@ -3700,7 +3735,7 @@ static bool meshBrush_boundsIntersect(Bounds3D *b1, } /* calculate velocity for mesh vertices */ -typedef struct DynamicPaintBrushVelocityData { +struct DynamicPaintBrushVelocityData { Vec3f *brush_vel; const float (*positions_p)[3]; @@ -3709,14 +3744,15 @@ typedef struct DynamicPaintBrushVelocityData { float (*obmat)[4]; float (*prev_obmat)[4]; - const float timescale; -} DynamicPaintBrushVelocityData; + float timescale; +}; static void dynamic_paint_brush_velocity_compute_cb(void *__restrict userdata, const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintBrushVelocityData *data = userdata; + const DynamicPaintBrushVelocityData *data = static_cast( + userdata); Vec3f *brush_vel = data->brush_vel; @@ -3793,8 +3829,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, numOfVerts_c = mesh_c->totvert; float(*positions_c)[3] = BKE_mesh_vert_positions_for_write(mesh_c); - (*brushVel) = (struct Vec3f *)MEM_mallocN(numOfVerts_c * sizeof(Vec3f), - "Dynamic Paint brush velocity"); + (*brushVel) = (Vec3f *)MEM_mallocN(numOfVerts_c * sizeof(Vec3f), "Dynamic Paint brush velocity"); if (!(*brushVel)) { return; } @@ -3805,21 +3840,21 @@ static void dynamicPaint_brushMeshCalculateVelocity(Depsgraph *depsgraph, } /* calculate speed */ - DynamicPaintBrushVelocityData data = { - .brush_vel = *brushVel, - .positions_p = positions_p, - .positions_c = positions_c, - .obmat = ob->object_to_world, - .prev_obmat = prev_obmat, - .timescale = timescale, - }; + DynamicPaintBrushVelocityData data{}; + data.brush_vel = *brushVel; + data.positions_p = positions_p; + data.positions_c = positions_c; + data.obmat = ob->object_to_world; + data.prev_obmat = prev_obmat; + data.timescale = timescale; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (numOfVerts_c > 10000); BLI_task_parallel_range( 0, numOfVerts_c, &data, dynamic_paint_brush_velocity_compute_cb, &settings); - BKE_id_free(NULL, mesh_p); + BKE_id_free(nullptr, mesh_p); } /* calculate velocity for object center point */ @@ -3870,37 +3905,38 @@ static void dynamicPaint_brushObjectCalculateVelocity( mul_v3_fl(brushVel->v, 1.0f / timescale); } -typedef struct DynamicPaintPaintData { +struct DynamicPaintPaintData { const DynamicPaintSurface *surface; const DynamicPaintBrushSettings *brush; Object *brushOb; const Scene *scene; - const float timescale; - const int c_index; + float timescale; + int c_index; Mesh *mesh; const float (*positions)[3]; const MLoop *mloop; const MLoopTri *mlooptri; - const float brush_radius; + float brush_radius; const float *avg_brushNor; const Vec3f *brushVelocity; const ParticleSystem *psys; - const float solidradius; + float solidradius; void *treeData; float *pointCoord; -} DynamicPaintPaintData; +}; /* * Paint a brush object mesh to the surface */ -static void dynamic_paint_paint_mesh_cell_point_cb_ex( - void *__restrict userdata, const int id, const TaskParallelTLS *__restrict UNUSED(tls)) +static void dynamic_paint_paint_mesh_cell_point_cb_ex(void *__restrict userdata, + const int id, + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintPaintData *data = userdata; + const DynamicPaintPaintData *data = static_cast(userdata); const DynamicPaintSurface *surface = data->surface; const PaintSurfaceData *sData = surface->data; @@ -3919,7 +3955,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex( const float *avg_brushNor = data->avg_brushNor; const Vec3f *brushVelocity = data->brushVelocity; - BVHTreeFromMesh *treeData = data->treeData; + BVHTreeFromMesh *treeData = static_cast(data->treeData); const int index = grid->t_index[grid->s_pos[c_index] + id]; const int samples = bData->s_num[index]; @@ -3987,9 +4023,9 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex( /* For optimization sake, hit point normal isn't calculated in ray cast loop */ const int vtri[3] = { - mloop[mlooptri[hit.index].tri[0]].v, - mloop[mlooptri[hit.index].tri[1]].v, - mloop[mlooptri[hit.index].tri[2]].v, + int(mloop[mlooptri[hit.index].tri[0]].v), + int(mloop[mlooptri[hit.index].tri[1]].v), + int(mloop[mlooptri[hit.index].tri[2]].v), }; float dot; @@ -4236,10 +4272,10 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, { PaintSurfaceData *sData = surface->data; PaintBakeData *bData = sData->bData; - Mesh *mesh = NULL; - Vec3f *brushVelocity = NULL; - const MLoopTri *mlooptri = NULL; - const MLoop *mloop = NULL; + Mesh *mesh = nullptr; + Vec3f *brushVelocity = nullptr; + const MLoopTri *mlooptri = nullptr; + const MLoop *mloop = nullptr; if (brush->flags & MOD_DPAINT_USES_VELOCITY) { dynamicPaint_brushMeshCalculateVelocity( @@ -4247,12 +4283,12 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, } Mesh *brush_mesh = dynamicPaint_brush_mesh_get(brush); - if (brush_mesh == NULL) { + if (brush_mesh == nullptr) { return false; } { - BVHTreeFromMesh treeData = {NULL}; + BVHTreeFromMesh treeData = {nullptr}; float avg_brushNor[3] = {0.0f}; const float brush_radius = brush->paint_distance * surface->radius_scale; int numOfVerts; @@ -4309,22 +4345,22 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, } /* loop through cell points and process brush */ - DynamicPaintPaintData data = { - .surface = surface, - .brush = brush, - .brushOb = brushOb, - .scene = scene, - .timescale = timescale, - .c_index = c_index, - .mesh = mesh, - .positions = positions, - .mloop = mloop, - .mlooptri = mlooptri, - .brush_radius = brush_radius, - .avg_brushNor = avg_brushNor, - .brushVelocity = brushVelocity, - .treeData = &treeData, - }; + DynamicPaintPaintData data{}; + data.surface = surface; + data.brush = brush; + data.brushOb = brushOb; + data.scene = scene; + data.timescale = timescale; + data.c_index = c_index; + data.mesh = mesh; + data.positions = positions; + data.mloop = mloop; + data.mlooptri = mlooptri; + data.brush_radius = brush_radius; + data.avg_brushNor = avg_brushNor; + data.brushVelocity = brushVelocity; + data.treeData = &treeData; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (grid->s_num[c_index] > 250); @@ -4338,7 +4374,7 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, } /* free bvh tree */ free_bvhtree_from_mesh(&treeData); - BKE_id_free(NULL, mesh); + BKE_id_free(nullptr, mesh); } /* free brush velocity data */ @@ -4353,9 +4389,9 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, * Paint a particle system to the surface */ static void dynamic_paint_paint_particle_cell_point_cb_ex( - void *__restrict userdata, const int id, const TaskParallelTLS *__restrict UNUSED(tls)) + void *__restrict userdata, const int id, const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintPaintData *data = userdata; + const DynamicPaintPaintData *data = static_cast(userdata); const DynamicPaintSurface *surface = data->surface; const PaintSurfaceData *sData = surface->data; @@ -4369,7 +4405,7 @@ static void dynamic_paint_paint_particle_cell_point_cb_ex( const float timescale = data->timescale; const int c_index = data->c_index; - KDTree_3d *tree = data->treeData; + KDTree_3d *tree = static_cast(data->treeData); const float solidradius = data->solidradius; const float smooth = brush->particle_smooth * surface->radius_scale; @@ -4614,15 +4650,15 @@ static bool dynamicPaint_paintParticles(DynamicPaintSurface *surface, } /* loop through cell points */ - DynamicPaintPaintData data = { - .surface = surface, - .brush = brush, - .psys = psys, - .solidradius = solidradius, - .timescale = timescale, - .c_index = c_index, - .treeData = tree, - }; + DynamicPaintPaintData data{}; + data.surface = surface; + data.brush = brush; + data.psys = psys; + data.solidradius = solidradius; + data.timescale = timescale; + data.c_index = c_index; + data.treeData = tree; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (grid->s_num[c_index] > 250); @@ -4641,9 +4677,9 @@ static bool dynamicPaint_paintParticles(DynamicPaintSurface *surface, /* paint a single point of defined proximity radius to the surface */ static void dynamic_paint_paint_single_point_cb_ex(void *__restrict userdata, const int index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintPaintData *data = userdata; + const DynamicPaintPaintData *data = static_cast(userdata); const DynamicPaintSurface *surface = data->surface; const PaintSurfaceData *sData = surface->data; @@ -4755,17 +4791,17 @@ static bool dynamicPaint_paintSinglePoint( /* * Loop through every surface point */ - DynamicPaintPaintData data = { - .surface = surface, - .brush = brush, - .brushOb = brushOb, - .scene = scene, - .timescale = timescale, - .positions = positions, - .brush_radius = brush_radius, - .brushVelocity = &brushVel, - .pointCoord = pointCoord, - }; + DynamicPaintPaintData data{}; + data.surface = surface; + data.brush = brush; + data.brushOb = brushOb; + data.scene = scene; + data.timescale = timescale; + data.positions = positions; + data.brush_radius = brush_radius; + data.brushVelocity = &brushVel; + data.pointCoord = pointCoord; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (sData->total_points > 1000); @@ -4783,9 +4819,9 @@ static bool dynamicPaint_paintSinglePoint( static void dynamic_paint_prepare_adjacency_cb(void *__restrict userdata, const int index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - PaintSurfaceData *sData = userdata; + PaintSurfaceData *sData = static_cast(userdata); PaintBakeData *bData = sData->bData; BakeAdjPoint *bNeighs = bData->bNeighs; PaintAdjData *adj_data = sData->adj_data; @@ -4822,8 +4858,8 @@ static void dynamicPaint_prepareAdjacencyData(DynamicPaintSurface *surface, cons if (bData->bNeighs) { MEM_freeN(bData->bNeighs); } - bNeighs = bData->bNeighs = MEM_mallocN(sData->adj_data->total_targets * sizeof(*bNeighs), - "PaintEffectBake"); + bNeighs = bData->bNeighs = static_cast( + MEM_mallocN(sData->adj_data->total_targets * sizeof(*bNeighs), "PaintEffectBake")); if (!bNeighs) { return; } @@ -5013,26 +5049,26 @@ static void dynamicPaint_doSmudge(DynamicPaintSurface *surface, } } -typedef struct DynamicPaintEffectData { +struct DynamicPaintEffectData { const DynamicPaintSurface *surface; Scene *scene; float *force; ListBase *effectors; const void *prevPoint; - const float eff_scale; + float eff_scale; uint8_t *point_locks; - const float wave_speed; - const float wave_scale; - const float wave_max_slope; + float wave_speed; + float wave_scale; + float wave_max_slope; - const float dt; - const float min_dist; - const float damp_factor; - const bool reset_wave; -} DynamicPaintEffectData; + float dt; + float min_dist; + float damp_factor; + bool reset_wave; +}; /* * Prepare data required by effects for current frame. @@ -5040,9 +5076,9 @@ typedef struct DynamicPaintEffectData { */ static void dynamic_paint_prepare_effect_cb(void *__restrict userdata, const int index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintEffectData *data = userdata; + const DynamicPaintEffectData *data = static_cast(userdata); const DynamicPaintSurface *surface = data->surface; const PaintSurfaceData *sData = surface->data; @@ -5062,7 +5098,8 @@ static void dynamic_paint_prepare_effect_cb(void *__restrict userdata, EffectedPoint epoint; pd_point_from_loc(scene, realCoord[bData->s_pos[index]].v, vel, index, &epoint); epoint.vel_to_sec = 1.0f; - BKE_effectors_apply(effectors, NULL, surface->effector_weights, &epoint, forc, NULL, NULL); + BKE_effectors_apply( + effectors, nullptr, surface->effector_weights, &epoint, forc, nullptr, nullptr); } /* if global gravity is enabled, add it too */ @@ -5094,7 +5131,7 @@ static void dynamic_paint_prepare_effect_cb(void *__restrict userdata, force[index * 4 + 3] = normalize_v3_v3(&force[index * 4], forc); } -static int dynamicPaint_prepareEffectStep(struct Depsgraph *depsgraph, +static int dynamicPaint_prepareEffectStep(Depsgraph *depsgraph, DynamicPaintSurface *surface, Scene *scene, Object *ob, @@ -5111,18 +5148,19 @@ static int dynamicPaint_prepareEffectStep(struct Depsgraph *depsgraph, /* Init force data if required */ if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) { ListBase *effectors = BKE_effectors_create( - depsgraph, ob, NULL, surface->effector_weights, false); + depsgraph, ob, nullptr, surface->effector_weights, false); /* allocate memory for force data (dir vector + strength) */ - *force = MEM_mallocN(sizeof(float[4]) * sData->total_points, "PaintEffectForces"); + *force = static_cast( + MEM_mallocN(sizeof(float[4]) * sData->total_points, "PaintEffectForces")); if (*force) { - DynamicPaintEffectData data = { - .surface = surface, - .scene = scene, - .force = *force, - .effectors = effectors, - }; + DynamicPaintEffectData data{}; + data.surface = surface; + data.scene = scene; + data.force = *force; + data.effectors = effectors; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (sData->total_points > 1000); @@ -5163,9 +5201,9 @@ static int dynamicPaint_prepareEffectStep(struct Depsgraph *depsgraph, */ static void dynamic_paint_effect_spread_cb(void *__restrict userdata, const int index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintEffectData *data = userdata; + const DynamicPaintEffectData *data = static_cast(userdata); const DynamicPaintSurface *surface = data->surface; const PaintSurfaceData *sData = surface->data; @@ -5177,7 +5215,7 @@ static void dynamic_paint_effect_spread_cb(void *__restrict userdata, const int numOfNeighs = sData->adj_data->n_num[index]; BakeAdjPoint *bNeighs = sData->bData->bNeighs; PaintPoint *pPoint = &((PaintPoint *)sData->type_data)[index]; - const PaintPoint *prevPoint = data->prevPoint; + const PaintPoint *prevPoint = static_cast(data->prevPoint); const float eff_scale = data->eff_scale; const int *n_index = sData->adj_data->n_index; @@ -5222,9 +5260,9 @@ static void dynamic_paint_effect_spread_cb(void *__restrict userdata, static void dynamic_paint_effect_shrink_cb(void *__restrict userdata, const int index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintEffectData *data = userdata; + const DynamicPaintEffectData *data = static_cast(userdata); const DynamicPaintSurface *surface = data->surface; const PaintSurfaceData *sData = surface->data; @@ -5236,7 +5274,7 @@ static void dynamic_paint_effect_shrink_cb(void *__restrict userdata, const int numOfNeighs = sData->adj_data->n_num[index]; BakeAdjPoint *bNeighs = sData->bData->bNeighs; PaintPoint *pPoint = &((PaintPoint *)sData->type_data)[index]; - const PaintPoint *prevPoint = data->prevPoint; + const PaintPoint *prevPoint = static_cast(data->prevPoint); const float eff_scale = data->eff_scale; const int *n_index = sData->adj_data->n_index; @@ -5280,9 +5318,9 @@ static void dynamic_paint_effect_shrink_cb(void *__restrict userdata, static void dynamic_paint_effect_drip_cb(void *__restrict userdata, const int index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintEffectData *data = userdata; + const DynamicPaintEffectData *data = static_cast(userdata); const DynamicPaintSurface *surface = data->surface; const PaintSurfaceData *sData = surface->data; @@ -5293,7 +5331,7 @@ static void dynamic_paint_effect_drip_cb(void *__restrict userdata, BakeAdjPoint *bNeighs = sData->bData->bNeighs; PaintPoint *pPoint = &((PaintPoint *)sData->type_data)[index]; - const PaintPoint *prevPoint = data->prevPoint; + const PaintPoint *prevPoint = static_cast(data->prevPoint); const PaintPoint *pPoint_prev = &prevPoint[index]; const float *force = data->force; const float eff_scale = data->eff_scale; @@ -5430,13 +5468,13 @@ static void dynamicPaint_doEffectStep( timescale; /* Copy current surface to the previous points array to read unmodified values */ - memcpy(prevPoint, sData->type_data, sData->total_points * sizeof(struct PaintPoint)); + memcpy(prevPoint, sData->type_data, sData->total_points * sizeof(PaintPoint)); + + DynamicPaintEffectData data{}; + data.surface = surface; + data.prevPoint = prevPoint; + data.eff_scale = eff_scale; - DynamicPaintEffectData data = { - .surface = surface, - .prevPoint = prevPoint, - .eff_scale = eff_scale, - }; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (sData->total_points > 1000); @@ -5452,13 +5490,13 @@ static void dynamicPaint_doEffectStep( timescale; /* Copy current surface to the previous points array to read unmodified values */ - memcpy(prevPoint, sData->type_data, sData->total_points * sizeof(struct PaintPoint)); + memcpy(prevPoint, sData->type_data, sData->total_points * sizeof(PaintPoint)); + + DynamicPaintEffectData data{}; + data.surface = surface; + data.prevPoint = prevPoint; + data.eff_scale = eff_scale; - DynamicPaintEffectData data = { - .surface = surface, - .prevPoint = prevPoint, - .eff_scale = eff_scale, - }; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (sData->total_points > 1000); @@ -5474,18 +5512,19 @@ static void dynamicPaint_doEffectStep( /* Same as #BLI_bitmask, but handled atomically as 'ePoint' locks. */ const size_t point_locks_size = (sData->total_points / 8) + 1; - uint8_t *point_locks = MEM_callocN(sizeof(*point_locks) * point_locks_size, __func__); + uint8_t *point_locks = static_cast( + MEM_callocN(sizeof(*point_locks) * point_locks_size, __func__)); /* Copy current surface to the previous points array to read unmodified values */ - memcpy(prevPoint, sData->type_data, sData->total_points * sizeof(struct PaintPoint)); + memcpy(prevPoint, sData->type_data, sData->total_points * sizeof(PaintPoint)); + + DynamicPaintEffectData data{}; + data.surface = surface; + data.prevPoint = prevPoint; + data.eff_scale = eff_scale; + data.force = force; + data.point_locks = point_locks; - DynamicPaintEffectData data = { - .surface = surface, - .prevPoint = prevPoint, - .eff_scale = eff_scale, - .force = force, - .point_locks = point_locks, - }; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (sData->total_points > 1000); @@ -5498,9 +5537,9 @@ static void dynamicPaint_doEffectStep( static void dynamic_paint_border_cb(void *__restrict userdata, const int b_index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintEffectData *data = userdata; + const DynamicPaintEffectData *data = static_cast(userdata); const DynamicPaintSurface *surface = data->surface; const PaintSurfaceData *sData = surface->data; @@ -5565,9 +5604,8 @@ static void dynamicPaint_doBorderStep(DynamicPaintSurface *surface) } /* Don't use prevPoint, relying on the condition that neighbors are never border pixels. */ - DynamicPaintEffectData data = { - .surface = surface, - }; + DynamicPaintEffectData data{}; + data.surface = surface; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); @@ -5578,14 +5616,14 @@ static void dynamicPaint_doBorderStep(DynamicPaintSurface *surface) static void dynamic_paint_wave_step_cb(void *__restrict userdata, const int index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintEffectData *data = userdata; + const DynamicPaintEffectData *data = static_cast(userdata); const DynamicPaintSurface *surface = data->surface; const PaintSurfaceData *sData = surface->data; BakeAdjPoint *bNeighs = sData->bData->bNeighs; - const PaintWavePoint *prevPoint = data->prevPoint; + const PaintWavePoint *prevPoint = static_cast(data->prevPoint); const float wave_speed = data->wave_speed; const float wave_scale = data->wave_scale; @@ -5691,7 +5729,8 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal const float wave_scale = CANVAS_REL_SIZE / canvas_size; /* allocate memory */ - PaintWavePoint *prevPoint = MEM_mallocN(sData->total_points * sizeof(PaintWavePoint), __func__); + PaintWavePoint *prevPoint = static_cast( + MEM_mallocN(sData->total_points * sizeof(PaintWavePoint), __func__)); if (!prevPoint) { return; } @@ -5721,17 +5760,17 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal /* copy previous frame data */ memcpy(prevPoint, sData->type_data, sData->total_points * sizeof(PaintWavePoint)); - DynamicPaintEffectData data = { - .surface = surface, - .prevPoint = prevPoint, - .wave_speed = wave_speed, - .wave_scale = wave_scale, - .wave_max_slope = wave_max_slope, - .dt = dt, - .min_dist = min_dist, - .damp_factor = damp_factor, - .reset_wave = (ss == steps - 1), - }; + DynamicPaintEffectData data{}; + data.surface = surface; + data.prevPoint = prevPoint; + data.wave_speed = wave_speed; + data.wave_scale = wave_scale; + data.wave_max_slope = wave_max_slope; + data.dt = dt; + data.min_dist = min_dist; + data.damp_factor = damp_factor; + data.reset_wave = (ss == steps - 1); + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (sData->total_points > 1000); @@ -5750,16 +5789,17 @@ static bool dynamic_paint_surface_needs_dry_dissolve(DynamicPaintSurface *surfac (surface->flags & MOD_DPAINT_DISSOLVE))); } -typedef struct DynamicPaintDissolveDryData { +struct DynamicPaintDissolveDryData { const DynamicPaintSurface *surface; - const float timescale; -} DynamicPaintDissolveDryData; + float timescale; +}; static void dynamic_paint_surface_pre_step_cb(void *__restrict userdata, const int index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintDissolveDryData *data = userdata; + const DynamicPaintDissolveDryData *data = static_cast( + userdata); const DynamicPaintSurface *surface = data->surface; const PaintSurfaceData *sData = surface->data; @@ -5877,7 +5917,7 @@ static bool dynamicPaint_surfaceHasMoved(DynamicPaintSurface *surface, Object *o } /* Prepare for surface step by creating PaintBakeNormal data */ -typedef struct DynamicPaintGenerateBakeData { +struct DynamicPaintGenerateBakeData { const DynamicPaintSurface *surface; Object *ob; @@ -5885,15 +5925,16 @@ typedef struct DynamicPaintGenerateBakeData { const float (*vert_normals)[3]; const Vec3f *canvas_verts; - const bool do_velocity_data; - const bool new_bdata; -} DynamicPaintGenerateBakeData; + bool do_velocity_data; + bool new_bdata; +}; static void dynamic_paint_generate_bake_data_cb(void *__restrict userdata, const int index, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - const DynamicPaintGenerateBakeData *data = userdata; + const DynamicPaintGenerateBakeData *data = static_cast( + userdata); const DynamicPaintSurface *surface = data->surface; const PaintSurfaceData *sData = surface->data; @@ -6035,16 +6076,16 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface, } } - canvas_verts = (struct Vec3f *)MEM_mallocN(canvasNumOfVerts * sizeof(struct Vec3f), - "Dynamic Paint transformed canvas verts"); + canvas_verts = (Vec3f *)MEM_mallocN(canvasNumOfVerts * sizeof(Vec3f), + "Dynamic Paint transformed canvas verts"); if (!canvas_verts) { return false; } /* allocate memory if required */ if (!bData) { - sData->bData = bData = (struct PaintBakeData *)MEM_callocN(sizeof(struct PaintBakeData), - "Dynamic Paint bake data"); + sData->bData = bData = (PaintBakeData *)MEM_callocN(sizeof(PaintBakeData), + "Dynamic Paint bake data"); if (!bData) { if (canvas_verts) { MEM_freeN(canvas_verts); @@ -6053,14 +6094,16 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface, } /* Init bdata */ - bData->bNormal = (struct PaintBakeNormal *)MEM_mallocN( - sData->total_points * sizeof(struct PaintBakeNormal), "Dynamic Paint step data"); - bData->s_pos = MEM_mallocN(sData->total_points * sizeof(uint), "Dynamic Paint bData s_pos"); - bData->s_num = MEM_mallocN(sData->total_points * sizeof(uint), "Dynamic Paint bData s_num"); - bData->realCoord = (struct Vec3f *)MEM_mallocN(surface_totalSamples(surface) * sizeof(Vec3f), - "Dynamic Paint point coords"); - bData->prev_positions = MEM_mallocN(canvasNumOfVerts * sizeof(float[3]), - "Dynamic Paint bData prev_positions"); + bData->bNormal = (PaintBakeNormal *)MEM_mallocN(sData->total_points * sizeof(PaintBakeNormal), + "Dynamic Paint step data"); + bData->s_pos = static_cast( + MEM_mallocN(sData->total_points * sizeof(uint), "Dynamic Paint bData s_pos")); + bData->s_num = static_cast( + MEM_mallocN(sData->total_points * sizeof(uint), "Dynamic Paint bData s_num")); + bData->realCoord = (Vec3f *)MEM_mallocN(surface_totalSamples(surface) * sizeof(Vec3f), + "Dynamic Paint point coords"); + bData->prev_positions = static_cast( + MEM_mallocN(canvasNumOfVerts * sizeof(float[3]), "Dynamic Paint bData prev_positions")); /* if any allocation failed, free everything */ if (!bData->bNormal || !bData->s_pos || !bData->s_num || !bData->realCoord || !canvas_verts) { @@ -6087,12 +6130,12 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface, } if (do_velocity_data && !bData->velocity) { - bData->velocity = (struct Vec3f *)MEM_callocN(sData->total_points * sizeof(Vec3f), - "Dynamic Paint velocity"); + bData->velocity = (Vec3f *)MEM_callocN(sData->total_points * sizeof(Vec3f), + "Dynamic Paint velocity"); } if (do_accel_data && !bData->prev_velocity) { - bData->prev_velocity = (struct Vec3f *)MEM_mallocN(sData->total_points * sizeof(Vec3f), - "Dynamic Paint prev velocity"); + bData->prev_velocity = (Vec3f *)MEM_mallocN(sData->total_points * sizeof(Vec3f), + "Dynamic Paint prev velocity"); /* copy previous vel */ if (bData->prev_velocity && bData->velocity) { memcpy(bData->prev_velocity, bData->velocity, sData->total_points * sizeof(Vec3f)); @@ -6112,15 +6155,15 @@ static bool dynamicPaint_generateBakeData(DynamicPaintSurface *surface, /* * Prepare each surface point for a new step */ - DynamicPaintGenerateBakeData data = { - .surface = surface, - .ob = ob, - .positions = positions, - .vert_normals = BKE_mesh_vertex_normals_ensure(mesh), - .canvas_verts = canvas_verts, - .do_velocity_data = do_velocity_data, - .new_bdata = new_bdata, - }; + DynamicPaintGenerateBakeData data{}; + data.surface = surface; + data.ob = ob; + data.positions = positions; + data.vert_normals = BKE_mesh_vertex_normals_ensure(mesh); + data.canvas_verts = canvas_verts; + data.do_velocity_data = do_velocity_data; + data.new_bdata = new_bdata; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (sData->total_points > 1000); @@ -6164,10 +6207,10 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph, } if (dynamic_paint_surface_needs_dry_dissolve(surface)) { - DynamicPaintDissolveDryData data = { - .surface = surface, - .timescale = timescale, - }; + DynamicPaintDissolveDryData data{}; + data.surface = surface; + data.timescale = timescale; + TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); settings.use_threading = (sData->total_points > 1000); @@ -6181,7 +6224,7 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph, { uint numobjects; Object **objects = BKE_collision_objects_create( - depsgraph, NULL, surface->brush_group, &numobjects, eModifierType_DynamicPaint); + depsgraph, nullptr, surface->brush_group, &numobjects, eModifierType_DynamicPaint); /* backup current scene frame */ int scene_frame = scene->r.cfra; @@ -6200,8 +6243,8 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph, /* calculate brush speed vectors if required */ if (surface->type == MOD_DPAINT_SURFACE_T_PAINT && brush->flags & MOD_DPAINT_DO_SMUDGE) { - bData->brush_velocity = MEM_callocN(sizeof(float[4]) * sData->total_points, - "Dynamic Paint brush velocity"); + bData->brush_velocity = static_cast(MEM_callocN( + sizeof(float[4]) * sData->total_points, "Dynamic Paint brush velocity")); /* init adjacency data if not already */ if (!sData->adj_data) { dynamicPaint_initAdjacencyData(surface, true); @@ -6271,7 +6314,7 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph, dynamicPaint_doSmudge(surface, brush, timescale); } MEM_freeN(bData->brush_velocity); - bData->brush_velocity = NULL; + bData->brush_velocity = nullptr; } } } @@ -6291,11 +6334,11 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph, if (surface->effect && surface->type == MOD_DPAINT_SURFACE_T_PAINT) { int steps = 1, s; PaintPoint *prevPoint; - float *force = NULL; + float *force = nullptr; /* Allocate memory for surface previous points to read unchanged values from */ - prevPoint = MEM_mallocN(sData->total_points * sizeof(struct PaintPoint), - "PaintSurfaceDataCopy"); + prevPoint = static_cast( + MEM_mallocN(sData->total_points * sizeof(PaintPoint), "PaintSurfaceDataCopy")); if (!prevPoint) { return setError(canvas, N_("Not enough free memory")); } @@ -6324,11 +6367,8 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph, return ret; } -int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, - struct Depsgraph *depsgraph, - Scene *scene, - Object *cObject, - int frame) +int dynamicPaint_calculateFrame( + DynamicPaintSurface *surface, Depsgraph *depsgraph, Scene *scene, Object *cObject, int frame) { float timescale = 1.0f; diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.cc similarity index 95% rename from source/blender/blenkernel/intern/fluid.c rename to source/blender/blenkernel/intern/fluid.cc index b95d82e83d8..20f3171271a 100644 --- a/source/blender/blenkernel/intern/fluid.c +++ b/source/blender/blenkernel/intern/fluid.cc @@ -34,10 +34,10 @@ #ifdef WITH_FLUID -# include -# include -# include -# include /* memset */ +# include +# include +# include +# include /* memset */ # include "DNA_customdata_types.h" # include "DNA_light_types.h" @@ -80,7 +80,7 @@ /** Max value for phi initialization */ #define PHI_MAX 9999.0f -static void fluid_modifier_reset_ex(struct FluidModifierData *fmd, bool need_lock); +static void fluid_modifier_reset_ex(FluidModifierData *fmd, bool need_lock); #ifdef WITH_FLUID // #define DEBUG_PRINT @@ -93,11 +93,6 @@ static CLG_LogRef LOG = {"bke.fluid"}; static ThreadMutex object_update_lock = BLI_MUTEX_INITIALIZER; -struct FluidModifierData; -struct Mesh; -struct Object; -struct Scene; - # define ADD_IF_LOWER_POS(a, b) (min_ff((a) + (b), max_ff((a), (b)))) # define ADD_IF_LOWER_NEG(a, b) (max_ff((a) + (b), min_ff((a), (b)))) # define ADD_IF_LOWER(a, b) (((b) > 0) ? ADD_IF_LOWER_POS((a), (b)) : ADD_IF_LOWER_NEG((a), (b))) @@ -108,7 +103,7 @@ bool BKE_fluid_reallocate_fluid(FluidDomainSettings *fds, int res[3], int free_o manta_free(fds->fluid); } if (!min_iii(res[0], res[1], res[2])) { - fds->fluid = NULL; + fds->fluid = nullptr; } else { fds->fluid = manta_init(res, fds->fmd); @@ -118,7 +113,7 @@ bool BKE_fluid_reallocate_fluid(FluidDomainSettings *fds, int res[3], int free_o fds->res_noise[2] = res[2] * fds->noise_scale; } - return (fds->fluid != NULL); + return (fds->fluid != nullptr); } void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds, @@ -130,7 +125,7 @@ void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds, int o_shift[3], int n_shift[3]) { - struct MANTA *fluid_old = fds->fluid; + MANTA *fluid_old = fds->fluid; const int block_size = fds->noise_scale; int new_shift[3] = {0}; sub_v3_v3v3_int(new_shift, n_shift, o_shift); @@ -563,7 +558,7 @@ static int get_light(Scene *scene, ViewLayer *view_layer, float *light) BKE_view_layer_synced_ensure(scene, view_layer); LISTBASE_FOREACH (Base *, base_tmp, BKE_view_layer_object_bases_get(view_layer)) { if (base_tmp->object->type == OB_LAMP) { - Light *la = base_tmp->object->data; + Light *la = static_cast(base_tmp->object->data); if (la->type == LA_LOCAL) { copy_v3_v3(light, base_tmp->object->object_to_world[3]); @@ -640,7 +635,7 @@ static bool is_static_object(Object *ob) /** \name Bounding Box * \{ */ -typedef struct FluidObjectBB { +struct FluidObjectBB { float *influence; float *velocity; float *distances; @@ -648,7 +643,7 @@ typedef struct FluidObjectBB { int min[3], max[3], res[3]; int hmin[3], hmax[3], hres[3]; int total_cells, valid; -} FluidObjectBB; +}; static void bb_boundInsert(FluidObjectBB *bb, const float point[3]) { @@ -685,15 +680,19 @@ static void bb_allocateData(FluidObjectBB *bb, bool use_velocity, bool use_influ bb->total_cells = res[0] * res[1] * res[2]; copy_v3_v3_int(bb->res, res); - bb->numobjs = MEM_calloc_arrayN(bb->total_cells, sizeof(float), "fluid_bb_numobjs"); + bb->numobjs = static_cast( + MEM_calloc_arrayN(bb->total_cells, sizeof(float), "fluid_bb_numobjs")); if (use_influence) { - bb->influence = MEM_calloc_arrayN(bb->total_cells, sizeof(float), "fluid_bb_influence"); + bb->influence = static_cast( + MEM_calloc_arrayN(bb->total_cells, sizeof(float), "fluid_bb_influence")); } if (use_velocity) { - bb->velocity = MEM_calloc_arrayN(bb->total_cells, sizeof(float[3]), "fluid_bb_velocity"); + bb->velocity = static_cast( + MEM_calloc_arrayN(bb->total_cells, sizeof(float[3]), "fluid_bb_velocity")); } - bb->distances = MEM_malloc_arrayN(bb->total_cells, sizeof(float), "fluid_bb_distances"); + bb->distances = static_cast( + MEM_malloc_arrayN(bb->total_cells, sizeof(float), "fluid_bb_distances")); copy_vn_fl(bb->distances, bb->total_cells, FLT_MAX); bb->valid = true; @@ -810,7 +809,7 @@ static void bb_combineMaps(FluidObjectBB *output, /** \name Effectors * \{ */ -BLI_INLINE void apply_effector_fields(FluidEffectorSettings *UNUSED(fes), +BLI_INLINE void apply_effector_fields(FluidEffectorSettings * /*fes*/, int index, float src_distance_value, float *dest_phi_in, @@ -935,7 +934,7 @@ static void update_velocities(FluidEffectorSettings *fes, } } -typedef struct ObstaclesFromDMData { +struct ObstaclesFromDMData { FluidEffectorSettings *fes; const float (*vert_positions)[3]; @@ -948,13 +947,13 @@ typedef struct ObstaclesFromDMData { bool has_velocity; float *vert_vel; int *min, *max, *res; -} ObstaclesFromDMData; +}; static void obstacles_from_mesh_task_cb(void *__restrict userdata, const int z, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - ObstaclesFromDMData *data = userdata; + ObstaclesFromDMData *data = static_cast(userdata); FluidObjectBB *bb = data->bb; for (int x = data->min[0]; x < data->max[0]; x++) { @@ -999,10 +998,10 @@ static void obstacles_from_mesh(Object *coll_ob, { if (fes->mesh) { const MLoopTri *looptri; - BVHTreeFromMesh tree_data = {NULL}; + BVHTreeFromMesh tree_data = {nullptr}; int numverts, i; - float *vert_vel = NULL; + float *vert_vel = nullptr; bool has_velocity = false; Mesh *me = BKE_mesh_copy_for_eval(fes->mesh, false); @@ -1016,14 +1015,16 @@ static void obstacles_from_mesh(Object *coll_ob, /* TODO(sebbas): Make initialization of vertex velocities optional? */ { - vert_vel = MEM_callocN(sizeof(float[3]) * numverts, "manta_obs_velocity"); + vert_vel = static_cast( + MEM_callocN(sizeof(float[3]) * numverts, "manta_obs_velocity")); if (fes->numverts != numverts || !fes->verts_old) { if (fes->verts_old) { MEM_freeN(fes->verts_old); } - fes->verts_old = MEM_callocN(sizeof(float[3]) * numverts, "manta_obs_verts_old"); + fes->verts_old = static_cast( + MEM_callocN(sizeof(float[3]) * numverts, "manta_obs_verts_old")); fes->numverts = numverts; } else { @@ -1055,7 +1056,7 @@ static void obstacles_from_mesh(Object *coll_ob, /* Set emission map. * Use 3 cell diagonals as margin (3 * 1.732 = 5.196). */ int bounds_margin = (int)ceil(5.196); - clamp_bounds_in_domain(fds, bb->min, bb->max, NULL, NULL, bounds_margin, dt); + clamp_bounds_in_domain(fds, bb->min, bb->max, nullptr, nullptr, bounds_margin, dt); bb_allocateData(bb, true, false); /* Setup loop bounds. */ @@ -1069,19 +1070,18 @@ static void obstacles_from_mesh(Object *coll_ob, bool use_effector = fes->flags & FLUID_EFFECTOR_USE_EFFEC; if (use_effector && BKE_bvhtree_from_mesh_get(&tree_data, me, BVHTREE_FROM_LOOPTRI, 4)) { - ObstaclesFromDMData data = { - .fes = fes, - .vert_positions = positions, - .mloop = mloop, - .mlooptri = looptri, - .tree = &tree_data, - .bb = bb, - .has_velocity = has_velocity, - .vert_vel = vert_vel, - .min = min, - .max = max, - .res = res, - }; + ObstaclesFromDMData data{}; + data.fes = fes; + data.vert_positions = positions; + data.mloop = mloop; + data.mlooptri = looptri; + data.tree = &tree_data; + data.bb = bb; + data.has_velocity = has_velocity; + data.vert_vel = vert_vel; + data.min = min; + data.max = max; + data.res = res; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); @@ -1094,7 +1094,7 @@ static void obstacles_from_mesh(Object *coll_ob, if (vert_vel) { MEM_freeN(vert_vel); } - BKE_id_free(NULL, me); + BKE_id_free(nullptr, me); } } @@ -1153,7 +1153,7 @@ static void update_obstacleflags(FluidDomainSettings *fds, static bool escape_effectorobject(Object *flowobj, FluidDomainSettings *fds, - FluidEffectorSettings *UNUSED(fes), + FluidEffectorSettings * /*fes*/, int frame) { bool is_static = is_static_object(flowobj); @@ -1176,7 +1176,7 @@ static bool escape_effectorobject(Object *flowobj, static void compute_obstaclesemission(Scene *scene, FluidObjectBB *bb_maps, - struct Depsgraph *depsgraph, + Depsgraph *depsgraph, float dt, Object **effecobjs, int frame, @@ -1223,7 +1223,7 @@ static void compute_obstaclesemission(Scene *scene, for (int subframe = 0; subframe <= subframes; subframe++) { /* Temporary emission map used when subframes are enabled, i.e. at least one subframe. */ - FluidObjectBB bb_temp = {NULL}; + FluidObjectBB bb_temp = {nullptr}; /* Set scene time */ /* Handle emission subframe */ @@ -1284,8 +1284,8 @@ static void update_obstacles(Depsgraph *depsgraph, int frame, float dt) { - FluidObjectBB *bb_maps = NULL; - Object **effecobjs = NULL; + FluidObjectBB *bb_maps = nullptr; + Object **effecobjs = nullptr; uint numeffecobjs = 0; bool is_resume = (fds->cache_frame_pause_data == frame); bool is_first_frame = (frame == fds->cache_frame_start); @@ -1298,7 +1298,8 @@ static void update_obstacles(Depsgraph *depsgraph, ensure_obstaclefields(fds); /* Allocate effector map for each effector object. */ - bb_maps = MEM_callocN(sizeof(struct FluidObjectBB) * numeffecobjs, "fluid_effector_bb_maps"); + bb_maps = static_cast( + MEM_callocN(sizeof(FluidObjectBB) * numeffecobjs, "fluid_effector_bb_maps")); /* Initialize effector map for each effector object. */ compute_obstaclesemission(scene, @@ -1459,7 +1460,7 @@ static void update_obstacles(Depsgraph *depsgraph, /** \name Flow * \{ */ -typedef struct EmitFromParticlesData { +struct EmitFromParticlesData { FluidFlowSettings *ffs; KDTree_3d *tree; @@ -1469,13 +1470,13 @@ typedef struct EmitFromParticlesData { float solid; float smooth; -} EmitFromParticlesData; +}; static void emit_from_particles_task_cb(void *__restrict userdata, const int z, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - EmitFromParticlesData *data = userdata; + EmitFromParticlesData *data = static_cast(userdata); FluidFlowSettings *ffs = data->ffs; FluidObjectBB *bb = data->bb; @@ -1527,7 +1528,7 @@ static void emit_from_particles(Object *flow_ob, /* radius based flow */ const float solid = ffs->particle_size * 0.5f; const float smooth = 0.5f; /* add 0.5 cells of linear falloff to reduce aliasing */ - KDTree_3d *tree = NULL; + KDTree_3d *tree = nullptr; sim.depsgraph = depsgraph; sim.scene = scene; @@ -1545,10 +1546,10 @@ static void emit_from_particles(Object *flow_ob, totchild = psys->totchild * psys->part->disp / 100; } - particle_pos = MEM_callocN(sizeof(float[3]) * (totpart + totchild), - "manta_flow_particles_pos"); - particle_vel = MEM_callocN(sizeof(float[3]) * (totpart + totchild), - "manta_flow_particles_vel"); + particle_pos = static_cast( + MEM_callocN(sizeof(float[3]) * (totpart + totchild), "manta_flow_particles_pos")); + particle_vel = static_cast( + MEM_callocN(sizeof(float[3]) * (totpart + totchild), "manta_flow_particles_vel")); /* setup particle radius emission if enabled */ if (ffs->flags & FLUID_FLOW_USE_PART_SIZE) { @@ -1600,7 +1601,7 @@ static void emit_from_particles(Object *flow_ob, } /* set emission map */ - clamp_bounds_in_domain(fds, bb->min, bb->max, NULL, NULL, bounds_margin, dt); + clamp_bounds_in_domain(fds, bb->min, bb->max, nullptr, nullptr, bounds_margin, dt); bb_allocateData(bb, ffs->flags & FLUID_FLOW_INITVELOCITY, true); if (!(ffs->flags & FLUID_FLOW_USE_PART_SIZE)) { @@ -1646,17 +1647,16 @@ static void emit_from_particles(Object *flow_ob, BLI_kdtree_3d_balance(tree); - EmitFromParticlesData data = { - .ffs = ffs, - .tree = tree, - .bb = bb, - .particle_vel = particle_vel, - .min = min, - .max = max, - .res = res, - .solid = solid, - .smooth = smooth, - }; + EmitFromParticlesData data{}; + data.ffs = ffs; + data.tree = tree; + data.bb = bb; + data.particle_vel = particle_vel; + data.min = min; + data.max = max; + data.res = res; + data.solid = solid; + data.smooth = smooth; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); @@ -1920,7 +1920,7 @@ static void sample_mesh(FluidFlowSettings *ffs, tex_co[1] = tex_co[1] * 2.0f - 1.0f; tex_co[2] = ffs->texture_offset; } - BKE_texture_get_value(NULL, ffs->noise_texture, tex_co, &texres, false); + BKE_texture_get_value(nullptr, ffs->noise_texture, tex_co, &texres, false); emission_strength *= texres.tin; } } @@ -1976,7 +1976,7 @@ static void sample_mesh(FluidFlowSettings *ffs, influence_map[index] = MAX2(volume_factor, emission_strength); } -typedef struct EmitFromDMData { +struct EmitFromDMData { FluidDomainSettings *fds; FluidFlowSettings *ffs; @@ -1995,13 +1995,13 @@ typedef struct EmitFromDMData { float *vert_vel; float *flow_center; int *min, *max, *res; -} EmitFromDMData; +}; static void emit_from_mesh_task_cb(void *__restrict userdata, const int z, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - EmitFromDMData *data = userdata; + EmitFromDMData *data = static_cast(userdata); FluidObjectBB *bb = data->bb; for (int x = data->min[0]; x < data->max[0]; x++) { @@ -2051,10 +2051,10 @@ static void emit_from_mesh( Object *flow_ob, FluidDomainSettings *fds, FluidFlowSettings *ffs, FluidObjectBB *bb, float dt) { if (ffs->mesh) { - BVHTreeFromMesh tree_data = {NULL}; + BVHTreeFromMesh tree_data = {nullptr}; int i; - float *vert_vel = NULL; + float *vert_vel = nullptr; bool has_velocity = false; int defgrp_index = ffs->vgroup_density - 1; @@ -2070,17 +2070,19 @@ static void emit_from_mesh( const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(me); const int numverts = me->totvert; const MDeformVert *dvert = BKE_mesh_deform_verts(me); - const float(*mloopuv)[2] = CustomData_get_layer_named( - &me->ldata, CD_PROP_FLOAT2, ffs->uvlayer_name); + const float(*mloopuv)[2] = static_cast( + CustomData_get_layer_named(&me->ldata, CD_PROP_FLOAT2, ffs->uvlayer_name)); if (ffs->flags & FLUID_FLOW_INITVELOCITY) { - vert_vel = MEM_callocN(sizeof(float[3]) * numverts, "manta_flow_velocity"); + vert_vel = static_cast( + MEM_callocN(sizeof(float[3]) * numverts, "manta_flow_velocity")); if (ffs->numverts != numverts || !ffs->verts_old) { if (ffs->verts_old) { MEM_freeN(ffs->verts_old); } - ffs->verts_old = MEM_callocN(sizeof(float[3]) * numverts, "manta_flow_verts_old"); + ffs->verts_old = static_cast( + MEM_callocN(sizeof(float[3]) * numverts, "manta_flow_verts_old")); ffs->numverts = numverts; } else { @@ -2122,7 +2124,7 @@ static void emit_from_mesh( /* Set emission map. * Use 3 cell diagonals as margin (3 * 1.732 = 5.196). */ int bounds_margin = (int)ceil(5.196); - clamp_bounds_in_domain(fds, bb->min, bb->max, NULL, NULL, bounds_margin, dt); + clamp_bounds_in_domain(fds, bb->min, bb->max, nullptr, nullptr, bounds_margin, dt); bb_allocateData(bb, ffs->flags & FLUID_FLOW_INITVELOCITY, true); /* Setup loop bounds. */ @@ -2136,25 +2138,24 @@ static void emit_from_mesh( bool use_flow = ffs->flags & FLUID_FLOW_USE_INFLOW; if (use_flow && BKE_bvhtree_from_mesh_get(&tree_data, me, BVHTREE_FROM_LOOPTRI, 4)) { - EmitFromDMData data = { - .fds = fds, - .ffs = ffs, - .vert_positions = positions, - .vert_normals = vert_normals, - .mloop = mloop, - .mlooptri = mlooptri, - .mloopuv = mloopuv, - .dvert = dvert, - .defgrp_index = defgrp_index, - .tree = &tree_data, - .bb = bb, - .has_velocity = has_velocity, - .vert_vel = vert_vel, - .flow_center = flow_center, - .min = min, - .max = max, - .res = res, - }; + EmitFromDMData data{}; + data.fds = fds; + data.ffs = ffs; + data.vert_positions = positions; + data.vert_normals = vert_normals; + data.mloop = mloop; + data.mlooptri = mlooptri; + data.mloopuv = mloopuv; + data.dvert = dvert; + data.defgrp_index = defgrp_index; + data.tree = &tree_data; + data.bb = bb; + data.has_velocity = has_velocity; + data.vert_vel = vert_vel; + data.flow_center = flow_center; + data.min = min; + data.max = max; + data.res = res; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); @@ -2167,7 +2168,7 @@ static void emit_from_mesh( if (vert_vel) { MEM_freeN(vert_vel); } - BKE_id_free(NULL, me); + BKE_id_free(nullptr, me); } } @@ -2692,7 +2693,7 @@ static bool escape_flowsobject(Object *flowobj, static void compute_flowsemission(Scene *scene, FluidObjectBB *bb_maps, - struct Depsgraph *depsgraph, + Depsgraph *depsgraph, float dt, Object **flowobjs, int frame, @@ -2738,7 +2739,7 @@ static void compute_flowsemission(Scene *scene, /* Emission loop. When not using subframes this will loop only once. */ for (int subframe = 0; subframe <= subframes; subframe++) { /* Temporary emission map used when subframes are enabled, i.e. at least one subframe. */ - FluidObjectBB bb_temp = {NULL}; + FluidObjectBB bb_temp = {nullptr}; /* Set scene time */ if ((subframe < subframes || time_per_frame + dt + FLT_EPSILON < frame_length) && @@ -2812,7 +2813,7 @@ static void compute_flowsemission(Scene *scene, # endif } -static void update_flowsfluids(struct Depsgraph *depsgraph, +static void update_flowsfluids(Depsgraph *depsgraph, Scene *scene, Object *ob, FluidDomainSettings *fds, @@ -2821,8 +2822,8 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, int frame, float dt) { - FluidObjectBB *bb_maps = NULL; - Object **flowobjs = NULL; + FluidObjectBB *bb_maps = nullptr; + Object **flowobjs = nullptr; uint numflowobjs = 0; bool is_resume = (fds->cache_frame_pause_data == frame); bool is_first_frame = (fds->cache_frame_start == frame); @@ -2835,7 +2836,8 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, ensure_flowsfields(fds); /* Allocate emission map for each flow object. */ - bb_maps = MEM_callocN(sizeof(struct FluidObjectBB) * numflowobjs, "fluid_flow_bb_maps"); + bb_maps = static_cast( + MEM_callocN(sizeof(FluidObjectBB) * numflowobjs, "fluid_flow_bb_maps")); /* Initialize emission map for each flow object. */ compute_flowsemission(scene, @@ -3082,7 +3084,7 @@ static void update_flowsfluids(struct Depsgraph *depsgraph, } } -typedef struct UpdateEffectorsData { +struct UpdateEffectorsData { Scene *scene; FluidDomainSettings *fds; ListBase *effectors; @@ -3097,13 +3099,13 @@ typedef struct UpdateEffectorsData { float *velocity_z; int *flags; float *phi_obs_in; -} UpdateEffectorsData; +}; static void update_effectors_task_cb(void *__restrict userdata, const int x, - const TaskParallelTLS *__restrict UNUSED(tls)) + const TaskParallelTLS *__restrict /*tls*/) { - UpdateEffectorsData *data = userdata; + UpdateEffectorsData *data = static_cast(userdata); FluidDomainSettings *fds = data->fds; for (int y = 0; y < fds->res[1]; y++) { @@ -3141,7 +3143,7 @@ static void update_effectors_task_cb(void *__restrict userdata, /* Do effectors. */ pd_point_from_loc(data->scene, voxel_center, vel, index, &epoint); BKE_effectors_apply( - data->effectors, NULL, fds->effector_weights, &epoint, retvel, NULL, NULL); + data->effectors, nullptr, fds->effector_weights, &epoint, retvel, nullptr, nullptr); /* Convert retvel to local space. */ mag = len_v3(retvel); @@ -3168,12 +3170,12 @@ static void update_effectors_task_cb(void *__restrict userdata, } static void update_effectors( - Depsgraph *depsgraph, Scene *scene, Object *ob, FluidDomainSettings *fds, float UNUSED(dt)) + Depsgraph *depsgraph, Scene *scene, Object *ob, FluidDomainSettings *fds, float /*dt*/) { ListBase *effectors; /* make sure smoke flow influence is 0.0f */ fds->effector_weights->weight[PFIELD_FLUIDFLOW] = 0.0f; - effectors = BKE_effectors_create(depsgraph, ob, NULL, fds->effector_weights, false); + effectors = BKE_effectors_create(depsgraph, ob, nullptr, fds->effector_weights, false); if (effectors) { /* Precalculate wind forces. */ @@ -3231,7 +3233,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, int num_verts, num_faces; if (!fds->fluid) { - return NULL; + return nullptr; } num_verts = manta_liquid_get_num_verts(fds->fluid); @@ -3243,12 +3245,12 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, # endif if (!num_verts || !num_faces) { - return NULL; + return nullptr; } me = BKE_mesh_new_nomain(num_verts, 0, 0, num_faces * 3, num_faces); if (!me) { - return NULL; + return nullptr; } float(*positions)[3] = BKE_mesh_vert_positions_for_write(me); mpolys = BKE_mesh_polys_for_write(me); @@ -3277,13 +3279,13 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, /* Velocities. */ /* If needed, vertex velocities will be read too. */ bool use_speedvectors = fds->flags & FLUID_DOMAIN_USE_SPEED_VECTORS; - float(*velarray)[3] = NULL; + float(*velarray)[3] = nullptr; float time_mult = fds->dx / (DT_DEFAULT * (25.0f / FPS)); if (use_speedvectors) { CustomDataLayer *velocity_layer = BKE_id_attribute_new( - &me->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT, NULL); - velarray = velocity_layer->data; + &me->id, "velocity", CD_PROP_FLOAT3, ATTR_DOMAIN_POINT, nullptr); + velarray = static_cast(velocity_layer->data); } /* Loop for vertices and normals. */ @@ -3620,7 +3622,7 @@ static void fluid_modifier_processFlow(FluidModifierData *fmd, if (fmd->flow) { if (fmd->flow->mesh) { - BKE_id_free(NULL, fmd->flow->mesh); + BKE_id_free(nullptr, fmd->flow->mesh); } fmd->flow->mesh = BKE_mesh_copy_for_eval(me, false); } @@ -3647,7 +3649,7 @@ static void fluid_modifier_processEffector(FluidModifierData *fmd, if (fmd->effector) { if (fmd->effector->mesh) { - BKE_id_free(NULL, fmd->effector->mesh); + BKE_id_free(nullptr, fmd->effector->mesh); } fmd->effector->mesh = BKE_mesh_copy_for_eval(me, false); } @@ -3669,10 +3671,10 @@ static void fluid_modifier_processDomain(FluidModifierData *fmd, const int scene_framenr) { FluidDomainSettings *fds = fmd->domain; - Object *guide_parent = NULL; - Object **objs = NULL; + Object *guide_parent = nullptr; + Object **objs = nullptr; uint numobj = 0; - FluidModifierData *fmd_parent = NULL; + FluidModifierData *fmd_parent = nullptr; bool is_startframe, has_advanced; is_startframe = (scene_framenr == fds->cache_frame_start); @@ -4089,7 +4091,7 @@ static void fluid_modifier_process( } } -struct Mesh *BKE_fluid_modifier_do( +Mesh *BKE_fluid_modifier_do( FluidModifierData *fmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *me) { /* Optimization: Do not update viewport during bakes (except in replay mode) @@ -4100,13 +4102,13 @@ struct Mesh *BKE_fluid_modifier_do( if (!G.moving) { /* Lock so preview render does not read smoke data while it gets modified. */ if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) { - BLI_rw_mutex_lock(fmd->domain->fluid_mutex, THREAD_LOCK_WRITE); + BLI_rw_mutex_lock(static_cast(fmd->domain->fluid_mutex), THREAD_LOCK_WRITE); } fluid_modifier_process(fmd, depsgraph, scene, ob, me); if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain) { - BLI_rw_mutex_unlock(fmd->domain->fluid_mutex); + BLI_rw_mutex_unlock(static_cast(fmd->domain->fluid_mutex)); } if (fmd->domain) { @@ -4136,7 +4138,7 @@ struct Mesh *BKE_fluid_modifier_do( } } - Mesh *result = NULL; + Mesh *result = nullptr; if (fmd->type & MOD_FLUID_TYPE_DOMAIN && fmd->domain) { if (needs_viewport_update) { /* Return generated geometry depending on domain type. */ @@ -4367,7 +4369,7 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, } } -float BKE_fluid_get_velocity_at(struct Object *ob, float position[3], float velocity[3]) +float BKE_fluid_get_velocity_at(Object *ob, float position[3], float velocity[3]) { FluidModifierData *fmd = (FluidModifierData *)BKE_modifiers_findby_type(ob, eModifierType_Fluid); zero_v3(velocity); @@ -4450,8 +4452,8 @@ int BKE_fluid_get_data_flags(FluidDomainSettings *fds) return flags; } -void BKE_fluid_particle_system_create(struct Main *bmain, - struct Object *ob, +void BKE_fluid_particle_system_create(Main *bmain, + Object *ob, const char *pset_name, const char *parts_name, const char *psys_name, @@ -4463,7 +4465,7 @@ void BKE_fluid_particle_system_create(struct Main *bmain, /* add particle system */ part = BKE_particlesettings_add(bmain, pset_name); - psys = MEM_callocN(sizeof(ParticleSystem), "particle_system"); + psys = MEM_cnew(__func__); part->type = psys_type; part->totpart = 0; @@ -4483,12 +4485,12 @@ void BKE_fluid_particle_system_create(struct Main *bmain, BKE_modifier_unique_name(&ob->modifiers, (ModifierData *)pfmd); } -void BKE_fluid_particle_system_destroy(struct Object *ob, const int particle_type) +void BKE_fluid_particle_system_destroy(Object *ob, const int particle_type) { ParticleSystemModifierData *pfmd; ParticleSystem *psys, *next_psys; - for (psys = ob->particlesystem.first; psys; psys = next_psys) { + for (psys = static_cast(ob->particlesystem.first); psys; psys = next_psys) { next_psys = psys->next; if (psys->part->type == particle_type) { /* clear modifier */ @@ -4608,7 +4610,7 @@ void BKE_fluid_domain_type_set(Object *object, FluidDomainSettings *settings, in settings->type = type; } -void BKE_fluid_flow_behavior_set(Object *UNUSED(object), FluidFlowSettings *settings, int behavior) +void BKE_fluid_flow_behavior_set(Object * /*object*/, FluidFlowSettings *settings, int behavior) { settings->behavior = behavior; } @@ -4628,7 +4630,7 @@ void BKE_fluid_flow_type_set(Object *object, FluidFlowSettings *settings, int ty settings->type = type; } -void BKE_fluid_effector_type_set(Object *UNUSED(object), FluidEffectorSettings *settings, int type) +void BKE_fluid_effector_type_set(Object * /*object*/, FluidEffectorSettings *settings, int type) { settings->type = type; } @@ -4688,14 +4690,14 @@ static void fluid_modifier_freeDomain(FluidModifierData *fmd) } if (fmd->domain->fluid_mutex) { - BLI_rw_mutex_free(fmd->domain->fluid_mutex); + BLI_rw_mutex_free(static_cast(fmd->domain->fluid_mutex)); } MEM_SAFE_FREE(fmd->domain->effector_weights); if (!(fmd->modifier.flag & eModifierFlag_SharedCaches)) { BKE_ptcache_free_list(&(fmd->domain->ptcaches[0])); - fmd->domain->point_cache[0] = NULL; + fmd->domain->point_cache[0] = nullptr; } if (fmd->domain->coba) { @@ -4703,7 +4705,7 @@ static void fluid_modifier_freeDomain(FluidModifierData *fmd) } MEM_freeN(fmd->domain); - fmd->domain = NULL; + fmd->domain = nullptr; } } @@ -4711,16 +4713,16 @@ static void fluid_modifier_freeFlow(FluidModifierData *fmd) { if (fmd->flow) { if (fmd->flow->mesh) { - BKE_id_free(NULL, fmd->flow->mesh); + BKE_id_free(nullptr, fmd->flow->mesh); } - fmd->flow->mesh = NULL; + fmd->flow->mesh = nullptr; MEM_SAFE_FREE(fmd->flow->verts_old); fmd->flow->numverts = 0; fmd->flow->flags &= ~FLUID_FLOW_NEEDS_UPDATE; MEM_freeN(fmd->flow); - fmd->flow = NULL; + fmd->flow = nullptr; } } @@ -4728,20 +4730,20 @@ static void fluid_modifier_freeEffector(FluidModifierData *fmd) { if (fmd->effector) { if (fmd->effector->mesh) { - BKE_id_free(NULL, fmd->effector->mesh); + BKE_id_free(nullptr, fmd->effector->mesh); } - fmd->effector->mesh = NULL; + fmd->effector->mesh = nullptr; MEM_SAFE_FREE(fmd->effector->verts_old); fmd->effector->numverts = 0; fmd->effector->flags &= ~FLUID_EFFECTOR_NEEDS_UPDATE; MEM_freeN(fmd->effector); - fmd->effector = NULL; + fmd->effector = nullptr; } } -static void fluid_modifier_reset_ex(struct FluidModifierData *fmd, bool need_lock) +static void fluid_modifier_reset_ex(FluidModifierData *fmd, bool need_lock) { if (!fmd) { return; @@ -4750,16 +4752,17 @@ static void fluid_modifier_reset_ex(struct FluidModifierData *fmd, bool need_loc if (fmd->domain) { if (fmd->domain->fluid) { if (need_lock) { - BLI_rw_mutex_lock(fmd->domain->fluid_mutex, THREAD_LOCK_WRITE); + BLI_rw_mutex_lock(static_cast(fmd->domain->fluid_mutex), + THREAD_LOCK_WRITE); } #ifdef WITH_FLUID manta_free(fmd->domain->fluid); #endif - fmd->domain->fluid = NULL; + fmd->domain->fluid = nullptr; if (need_lock) { - BLI_rw_mutex_unlock(fmd->domain->fluid_mutex); + BLI_rw_mutex_unlock(static_cast(fmd->domain->fluid_mutex)); } } @@ -4779,7 +4782,7 @@ static void fluid_modifier_reset_ex(struct FluidModifierData *fmd, bool need_loc } } -void BKE_fluid_modifier_reset(struct FluidModifierData *fmd) +void BKE_fluid_modifier_reset(FluidModifierData *fmd) { fluid_modifier_reset_ex(fmd, true); } @@ -4795,7 +4798,7 @@ void BKE_fluid_modifier_free(FluidModifierData *fmd) fluid_modifier_freeEffector(fmd); } -void BKE_fluid_modifier_create_type_data(struct FluidModifierData *fmd) +void BKE_fluid_modifier_create_type_data(FluidModifierData *fmd) { if (!fmd) { return; @@ -4819,7 +4822,7 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *fmd) fmd->domain->openvdb_compression = VDB_COMPRESSION_ZIP; #endif - fmd->domain->effector_weights = BKE_effector_add_weights(NULL); + fmd->domain->effector_weights = BKE_effector_add_weights(nullptr); fmd->domain->fluid_mutex = BLI_rw_mutex_alloc(); char cache_name[64]; @@ -4831,7 +4834,7 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *fmd) fmd->domain->point_cache[0] = BKE_ptcache_add(&(fmd->domain->ptcaches[0])); fmd->domain->point_cache[0]->flag |= PTCACHE_DISK_CACHE; fmd->domain->point_cache[0]->step = 1; - fmd->domain->point_cache[1] = NULL; /* Deprecated */ + fmd->domain->point_cache[1] = nullptr; /* Deprecated */ } else if (fmd->type & MOD_FLUID_TYPE_FLOW) { if (fmd->flow) { @@ -4851,9 +4854,7 @@ void BKE_fluid_modifier_create_type_data(struct FluidModifierData *fmd) } } -void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd, - struct FluidModifierData *tfmd, - const int flag) +void BKE_fluid_modifier_copy(const FluidModifierData *fmd, FluidModifierData *tfmd, const int flag) { tfmd->type = fmd->type; tfmd->time = fmd->time; @@ -4871,7 +4872,7 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd, if (tfds->effector_weights) { MEM_freeN(tfds->effector_weights); } - tfds->effector_weights = MEM_dupallocN(fds->effector_weights); + tfds->effector_weights = static_cast(MEM_dupallocN(fds->effector_weights)); /* adaptive domain options */ tfds->adapt_margin = fds->adapt_margin; @@ -5002,7 +5003,7 @@ void BKE_fluid_modifier_copy(const struct FluidModifierData *fmd, tfds->display_thickness = fds->display_thickness; tfds->show_gridlines = fds->show_gridlines; if (fds->coba) { - tfds->coba = MEM_dupallocN(fds->coba); + tfds->coba = static_cast(MEM_dupallocN(fds->coba)); } tfds->vector_scale = fds->vector_scale; tfds->vector_draw_type = fds->vector_draw_type; diff --git a/source/blender/editors/armature/CMakeLists.txt b/source/blender/editors/armature/CMakeLists.txt index acc84259c3b..4eb07c3bdee 100644 --- a/source/blender/editors/armature/CMakeLists.txt +++ b/source/blender/editors/armature/CMakeLists.txt @@ -32,7 +32,7 @@ set(SRC armature_skinning.c armature_utils.c editarmature_undo.c - meshlaplacian.c + meshlaplacian.cc pose_edit.c pose_group.c pose_lib_2.c diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.cc similarity index 91% rename from source/blender/editors/armature/meshlaplacian.c rename to source/blender/editors/armature/meshlaplacian.cc index 133741d172f..5c9c6b9ec78 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.cc @@ -12,7 +12,6 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "BLI_alloca.h" #include "BLI_edgehash.h" #include "BLI_math.h" #include "BLI_memarena.h" @@ -36,10 +35,10 @@ #include "meshlaplacian.h" /* ************* XXX *************** */ -static void waitcursor(int UNUSED(val)) +static void waitcursor(int /*val*/) { } -static void progress_bar(int UNUSED(dummy_val), const char *UNUSED(dummy)) +static void progress_bar(int /*dummy_val*/, const char * /*dummy*/) { } static void start_progress_bar(void) @@ -206,11 +205,14 @@ static LaplacianSystem *laplacian_system_construct_begin(int verts_num, int face { LaplacianSystem *sys; - sys = MEM_callocN(sizeof(LaplacianSystem), "LaplacianSystem"); + sys = MEM_cnew(__func__); - sys->verts = MEM_callocN(sizeof(float *) * verts_num, "LaplacianSystemVerts"); - sys->vpinned = MEM_callocN(sizeof(char) * verts_num, "LaplacianSystemVpinned"); - sys->faces = MEM_callocN(sizeof(int[3]) * faces_num, "LaplacianSystemFaces"); + sys->verts = static_cast( + MEM_callocN(sizeof(float *) * verts_num, "LaplacianSystemVerts")); + sys->vpinned = static_cast( + MEM_callocN(sizeof(char) * verts_num, "LaplacianSystemVpinned")); + sys->faces = static_cast( + MEM_callocN(sizeof(int[3]) * faces_num, "LaplacianSystemFaces")); sys->verts_num = 0; sys->faces_num = 0; @@ -251,7 +253,8 @@ static void laplacian_system_construct_end(LaplacianSystem *sys) laplacian_begin_solve(sys, 0); - sys->varea = MEM_callocN(sizeof(float) * verts_num, "LaplacianSystemVarea"); + sys->varea = static_cast( + MEM_callocN(sizeof(float) * verts_num, "LaplacianSystemVarea")); sys->edgehash = BLI_edgehash_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(sys->faces_num)); @@ -284,7 +287,8 @@ static void laplacian_system_construct_end(LaplacianSystem *sys) } if (sys->storeweights) { - sys->fweights = MEM_callocN(sizeof(float[3]) * faces_num, "LaplacianFWeight"); + sys->fweights = static_cast( + MEM_callocN(sizeof(float[3]) * faces_num, "LaplacianFWeight")); } for (a = 0, face = sys->faces; a < faces_num; a++, face++) { @@ -292,12 +296,12 @@ static void laplacian_system_construct_end(LaplacianSystem *sys) } MEM_freeN(sys->faces); - sys->faces = NULL; + sys->faces = nullptr; MEM_SAFE_FREE(sys->varea); - BLI_edgehash_free(sys->edgehash, NULL); - sys->edgehash = NULL; + BLI_edgehash_free(sys->edgehash, nullptr); + sys->edgehash = nullptr; } static void laplacian_system_delete(LaplacianSystem *sys) @@ -389,10 +393,10 @@ static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTr #ifdef USE_KDOPBVH_WATERTIGHT if (isect_ray_tri_watertight_v3( - data->start, ray->isect_precalc, UNPACK3(vtri_co), &dist_test, NULL)) + data->start, ray->isect_precalc, UNPACK3(vtri_co), &dist_test, nullptr)) #else UNUSED_VARS(ray); - if (isect_ray_tri_v3(data->start, data->vec, UNPACK3(vtri_co), &dist_test, NULL)) + if (isect_ray_tri_v3(data->start, data->vec, UNPACK3(vtri_co), &dist_test, nullptr)) #endif { if (dist_test < hit->dist) { @@ -417,7 +421,8 @@ static void heat_ray_tree_create(LaplacianSystem *sys) int a; sys->heat.bvhtree = BLI_bvhtree_new(tris_num, 0.0f, 4, 6); - sys->heat.vltree = MEM_callocN(sizeof(MLoopTri *) * verts_num, "HeatVFaces"); + sys->heat.vltree = static_cast( + MEM_callocN(sizeof(MLoopTri *) * verts_num, "HeatVFaces")); for (a = 0; a < tris_num; a++) { const MLoopTri *lt = &looptri[a]; @@ -453,7 +458,7 @@ static int heat_ray_source_visible(LaplacianSystem *sys, int vertex, int source) int visible; lt = sys->heat.vltree[vertex]; - if (lt == NULL) { + if (lt == nullptr) { return 1; } @@ -553,7 +558,8 @@ static void heat_calc_vnormals(LaplacianSystem *sys) float fnor[3]; int a, v1, v2, v3, (*face)[3]; - sys->heat.vert_normals = MEM_callocN(sizeof(float[3]) * sys->verts_num, "HeatVNors"); + sys->heat.vert_normals = static_cast( + MEM_callocN(sizeof(float[3]) * sys->verts_num, "HeatVNors")); for (a = 0, face = sys->faces; a < sys->faces_num; a++, face++) { v1 = (*face)[0]; @@ -581,9 +587,9 @@ static void heat_laplacian_create(LaplacianSystem *sys) int a; /* heat specific definitions */ - sys->heat.mindist = MEM_callocN(sizeof(float) * verts_num, "HeatMinDist"); - sys->heat.H = MEM_callocN(sizeof(float) * verts_num, "HeatH"); - sys->heat.p = MEM_callocN(sizeof(float) * verts_num, "HeatP"); + sys->heat.mindist = static_cast(MEM_callocN(sizeof(float) * verts_num, "HeatMinDist")); + sys->heat.H = static_cast(MEM_callocN(sizeof(float) * verts_num, "HeatH")); + sys->heat.p = static_cast(MEM_callocN(sizeof(float) * verts_num, "HeatP")); /* add verts and faces to laplacian */ for (a = 0; a < verts_num; a++) { @@ -648,7 +654,7 @@ void heat_bone_weighting(Object *ob, const MPoly *mp; const MLoop *ml; float solution, weight; - int *vertsflipped = NULL, *mask = NULL; + int *vertsflipped = nullptr, *mask = nullptr; int a, tris_num, j, bbone, firstsegment, lastsegment; bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0; @@ -658,14 +664,14 @@ void heat_bone_weighting(Object *ob, bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0; bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0; - *error_str = NULL; + *error_str = nullptr; /* bone heat needs triangulated faces */ tris_num = poly_to_tri_count(me->totpoly, me->totloop); /* count triangles and create mask */ if (ob->mode & OB_MODE_WEIGHT_PAINT && (use_face_sel || use_vert_sel)) { - mask = MEM_callocN(sizeof(int) * me->totvert, "heat_bone_weighting mask"); + mask = static_cast(MEM_callocN(sizeof(int) * me->totvert, "heat_bone_weighting mask")); /* (added selectedVerts content for vertex mask, they used to just equal 1) */ if (use_vert_sel) { @@ -698,7 +704,8 @@ void heat_bone_weighting(Object *ob, sys = laplacian_system_construct_begin(me->totvert, tris_num, 1); sys->heat.tris_num = poly_to_tri_count(me->totpoly, me->totloop); - mlooptri = MEM_mallocN(sizeof(*sys->heat.mlooptri) * sys->heat.tris_num, __func__); + mlooptri = static_cast( + MEM_mallocN(sizeof(*sys->heat.mlooptri) * sys->heat.tris_num, __func__)); BKE_mesh_recalc_looptri(loops, polys, vert_positions, me->totloop, me->totpoly, mlooptri); @@ -716,9 +723,9 @@ void heat_bone_weighting(Object *ob, laplacian_system_construct_end(sys); if (dgroupflip) { - vertsflipped = MEM_callocN(sizeof(int) * me->totvert, "vertsflipped"); + vertsflipped = static_cast(MEM_callocN(sizeof(int) * me->totvert, "vertsflipped")); for (a = 0; a < me->totvert; a++) { - vertsflipped[a] = mesh_get_x_mirror_vert(ob, NULL, a, use_topology); + vertsflipped[a] = mesh_get_x_mirror_vert(ob, nullptr, a, use_topology); } } @@ -799,7 +806,7 @@ void heat_bone_weighting(Object *ob, } } } - else if (*error_str == NULL) { + else if (*error_str == nullptr) { *error_str = N_("Bone Heat Weighting: failed to find solution for one or more bones"); break; } @@ -950,7 +957,7 @@ static void harmonic_ray_callback(void *userdata, const BVHTreeRay *ray, BVHTreeRayHit *hit) { - struct MeshRayCallbackData *data = userdata; + MeshRayCallbackData *data = static_cast(userdata); MeshDeformBind *mdb = data->mdb; const MLoop *mloop = mdb->cagemesh_cache.mloop; const MLoopTri *looptri = mdb->cagemesh_cache.looptri, *lt; @@ -966,7 +973,7 @@ static void harmonic_ray_callback(void *userdata, face[2] = mdb->cagecos[mloop[lt->tri[2]].v]; bool isect_ray_tri = isect_ray_tri_watertight_v3( - ray->origin, ray->isect_precalc, UNPACK3(face), &dist, NULL); + ray->origin, ray->isect_precalc, UNPACK3(face), &dist, nullptr); if (!isect_ray_tri || dist > isec->vec_length) { return; @@ -1004,8 +1011,8 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float end[3], vec_normal[3]; /* happens binding when a cage has no faces */ - if (UNLIKELY(mdb->bvhtree == NULL)) { - return NULL; + if (UNLIKELY(mdb->bvhtree == nullptr)) { + return nullptr; } /* setup isec */ @@ -1034,10 +1041,11 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, const float len = isect_mdef.lambda; MDefBoundIsect *isect; - float(*mp_cagecos)[3] = BLI_array_alloca(mp_cagecos, mp->totloop); + blender::Array mp_cagecos(mp->totloop); /* create MDefBoundIsect, and extra for 'poly_weights[]' */ - isect = BLI_memarena_alloc(mdb->memarena, sizeof(*isect) + (sizeof(float) * mp->totloop)); + isect = static_cast( + BLI_memarena_alloc(mdb->memarena, sizeof(*isect) + (sizeof(float) * mp->totloop))); /* compute intersection coordinate */ madd_v3_v3v3fl(isect->co, co1, isect_mdef.vec, len); @@ -1053,12 +1061,15 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, copy_v3_v3(mp_cagecos[i], cagecos[mloop[mp->loopstart + i].v]); } - interp_weights_poly_v3(isect->poly_weights, mp_cagecos, mp->totloop, isect->co); + interp_weights_poly_v3(isect->poly_weights, + reinterpret_cast(mp_cagecos.data()), + mp->totloop, + isect->co); return isect; } - return NULL; + return nullptr; } static int meshdeform_inside_cage(MeshDeformBind *mdb, float *co) @@ -1150,7 +1161,7 @@ static void meshdeform_bind_floodfill(MeshDeformBind *mdb) int *stack, *tag = mdb->tag; int a, b, i, xyz[3], stacksize, size = mdb->size; - stack = MEM_callocN(sizeof(int) * mdb->size3, "MeshDeformBindStack"); + stack = static_cast(MEM_callocN(sizeof(int) * mdb->size3, __func__)); /* we know lower left corner is EXTERIOR because of padding */ tag[0] = MESHDEFORM_TAG_EXTERIOR; @@ -1230,8 +1241,8 @@ static float meshdeform_boundary_phi(const MeshDeformBind *mdb, static float meshdeform_interp_w(MeshDeformBind *mdb, const float *gridvec, - float *UNUSED(vec), - int UNUSED(cagevert)) + float * /*vec*/, + int /*cagevert*/) { float dvec[3], ivec[3], result = 0.0f; float totweight = 0.0f; @@ -1419,7 +1430,7 @@ static void meshdeform_matrix_add_semibound_phi( } static void meshdeform_matrix_add_exterior_phi( - MeshDeformBind *mdb, int x, int y, int z, int UNUSED(cagevert)) + MeshDeformBind *mdb, int x, int y, int z, int /*cagevert*/) { float phi, totweight; int i, a, acenter; @@ -1453,7 +1464,7 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind char message[256]; /* setup variable indices */ - mdb->varidx = MEM_callocN(sizeof(int) * mdb->size3, "MeshDeformDSvaridx"); + mdb->varidx = static_cast(MEM_callocN(sizeof(int) * mdb->size3, "MeshDeformDSvaridx")); for (a = 0, totvar = 0; a < mdb->size3; a++) { mdb->varidx[a] = (mdb->tag[a] == MESHDEFORM_TAG_EXTERIOR) ? -1 : totvar++; } @@ -1531,7 +1542,8 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind /* dynamic bind */ for (b = 0; b < mdb->size3; b++) { if (mdb->phi[b] >= MESHDEFORM_MIN_INFLUENCE) { - inf = BLI_memarena_alloc(mdb->memarena, sizeof(*inf)); + inf = static_cast( + BLI_memarena_alloc(mdb->memarena, sizeof(*inf))); inf->vertex = a; inf->weight = mdb->phi[b]; inf->next = mdb->dyngrid[b]; @@ -1594,20 +1606,23 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin /* allocate memory */ mdb->size = (2 << (mmd->gridsize - 1)) + 2; mdb->size3 = mdb->size * mdb->size * mdb->size; - mdb->tag = MEM_callocN(sizeof(int) * mdb->size3, "MeshDeformBindTag"); - mdb->phi = MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindPhi"); - mdb->totalphi = MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindTotalPhi"); - mdb->boundisect = MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect"); - mdb->semibound = MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound"); + mdb->tag = static_cast(MEM_callocN(sizeof(int) * mdb->size3, "MeshDeformBindTag")); + mdb->phi = static_cast(MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindPhi")); + mdb->totalphi = static_cast( + MEM_callocN(sizeof(float) * mdb->size3, "MeshDeformBindTotalPhi")); + mdb->boundisect = static_cast( + MEM_callocN(sizeof(*mdb->boundisect) * mdb->size3, "MDefBoundIsect")); + mdb->semibound = static_cast(MEM_callocN(sizeof(int) * mdb->size3, "MDefSemiBound")); mdb->bvhtree = BKE_bvhtree_from_mesh_get(&mdb->bvhdata, mdb->cagemesh, BVHTREE_FROM_LOOPTRI, 4); - mdb->inside = MEM_callocN(sizeof(int) * mdb->verts_num, "MDefInside"); + mdb->inside = static_cast(MEM_callocN(sizeof(int) * mdb->verts_num, "MDefInside")); if (mmd->flag & MOD_MDEF_DYNAMIC_BIND) { - mdb->dyngrid = MEM_callocN(sizeof(MDefBindInfluence *) * mdb->size3, "MDefDynGrid"); + mdb->dyngrid = static_cast( + MEM_callocN(sizeof(MDefBindInfluence *) * mdb->size3, "MDefDynGrid")); } else { - mdb->weights = MEM_callocN(sizeof(float) * mdb->verts_num * mdb->cage_verts_num, - "MDefWeights"); + mdb->weights = static_cast( + MEM_callocN(sizeof(float) * mdb->verts_num * mdb->cage_verts_num, "MDefWeights")); } mdb->memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "harmonic coords arena"); @@ -1697,8 +1712,10 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin } /* convert MDefBindInfluences to smaller MDefInfluences */ - mmd->dyngrid = MEM_callocN(sizeof(MDefCell) * mdb->size3, "MDefDynGrid"); - mmd->dyninfluences = MEM_callocN(sizeof(MDefInfluence) * mmd->influences_num, "MDefInfluence"); + mmd->dyngrid = static_cast( + MEM_callocN(sizeof(MDefCell) * mdb->size3, "MDefDynGrid")); + mmd->dyninfluences = static_cast( + MEM_callocN(sizeof(MDefInfluence) * mmd->influences_num, "MDefInfluence")); offset = 0; for (a = 0; a < mdb->size3; a++) { cell = &mmd->dyngrid[a]; @@ -1764,12 +1781,14 @@ void ED_mesh_deform_bind_callback(Object *object, BKE_mesh_wrapper_ensure_mdata(cagemesh); /* get mesh and cage mesh */ - mdb.vertexcos = MEM_callocN(sizeof(float[3]) * verts_num, "MeshDeformCos"); + mdb.vertexcos = static_cast( + MEM_callocN(sizeof(float[3]) * verts_num, "MeshDeformCos")); mdb.verts_num = verts_num; mdb.cagemesh = cagemesh; mdb.cage_verts_num = mdb.cagemesh->totvert; - mdb.cagecos = MEM_callocN(sizeof(*mdb.cagecos) * mdb.cage_verts_num, "MeshDeformBindCos"); + mdb.cagecos = static_cast( + MEM_callocN(sizeof(*mdb.cagecos) * mdb.cage_verts_num, "MeshDeformBindCos")); copy_m4_m4(mdb.cagemat, cagemat); const float(*positions)[3] = BKE_mesh_vert_positions(mdb.cagemesh); diff --git a/source/blender/editors/armature/meshlaplacian.h b/source/blender/editors/armature/meshlaplacian.h index d45909872b8..3d5ce1d9d29 100644 --- a/source/blender/editors/armature/meshlaplacian.h +++ b/source/blender/editors/armature/meshlaplacian.h @@ -7,6 +7,10 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + //#define RIGID_DEFORM struct Mesh; @@ -51,6 +55,10 @@ void rigid_deform_iteration(void); void rigid_deform_end(int cancel); #endif +#ifdef __cplusplus +} +#endif + /* Harmonic Coordinates */ /* ED_mesh_deform_bind_callback(...) defined in ED_armature.h */ diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index fcbaf9e115d..128ba43e3ec 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -359,7 +359,7 @@ void ED_pose_bone_select_tag_update(struct Object *ob); */ void ED_pose_bone_select(struct Object *ob, struct bPoseChannel *pchan, bool select); -/* meshlaplacian.c */ +/* meshlaplacian.cc */ void ED_mesh_deform_bind_callback(struct Object *object, struct MeshDeformModifierData *mmd, diff --git a/source/blender/editors/physics/physics_intern.h b/source/blender/editors/physics/physics_intern.h index da0b293e908..7c2aee9f4cb 100644 --- a/source/blender/editors/physics/physics_intern.h +++ b/source/blender/editors/physics/physics_intern.h @@ -114,7 +114,7 @@ void FLUID_OT_bake_guides(struct wmOperatorType *ot); void FLUID_OT_free_guides(struct wmOperatorType *ot); void FLUID_OT_pause_bake(struct wmOperatorType *ot); -/* dynamicpaint.c */ +/* dynamicpaint.cc */ void DPAINT_OT_bake(struct wmOperatorType *ot); /** From 50387964b6f17c0fd4d6221aef3daca4f9abb772 Mon Sep 17 00:00:00 2001 From: Falk David Date: Sat, 21 Jan 2023 20:38:36 +0100 Subject: [PATCH 0850/1522] Curves: Add initial transform support This adds basic support for the transform operators for curves. Differential Revision: https://developer.blender.org/D17063 --- release/scripts/startup/bl_ui/space_view3d.py | 5 +- .../editors/curves/intern/curves_selection.cc | 3 +- source/blender/editors/include/ED_curves.h | 1 + .../blender/editors/transform/CMakeLists.txt | 1 + .../editors/transform/transform_convert.c | 5 + .../editors/transform/transform_convert.h | 4 + .../transform/transform_convert_curves.cc | 102 ++++++++++++++++++ 7 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 source/blender/editors/transform/transform_convert_curves.cc diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 938399485d3..2f5b70bb3da 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -5332,7 +5332,10 @@ class VIEW3D_MT_edit_curves(Menu): bl_label = "Curves" def draw(self, _context): - pass + layout = self.layout + + layout.menu("VIEW3D_MT_transform") + layout.separator() class VIEW3D_MT_object_mode_pie(Menu): diff --git a/source/blender/editors/curves/intern/curves_selection.cc b/source/blender/editors/curves/intern/curves_selection.cc index 9ed25473a0c..f74ac53de9a 100644 --- a/source/blender/editors/curves/intern/curves_selection.cc +++ b/source/blender/editors/curves/intern/curves_selection.cc @@ -56,8 +56,7 @@ IndexMask retrieve_selected_curves(const Curves &curves_id, Vector &r_i return retrieve_selected_curves(curves, r_indices); } -static IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, - Vector &r_indices) +IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, Vector &r_indices) { return index_mask_ops::find_indices_from_virtual_array( curves.points_range(), diff --git a/source/blender/editors/include/ED_curves.h b/source/blender/editors/include/ED_curves.h index 9c76713e3f4..5c7cadd9d75 100644 --- a/source/blender/editors/include/ED_curves.h +++ b/source/blender/editors/include/ED_curves.h @@ -94,6 +94,7 @@ IndexMask retrieve_selected_curves(const Curves &curves_id, Vector &r_i * Find points that are selected (a selection factor greater than zero), * or points in curves with a selection factor greater than zero). */ +IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, Vector &r_indices); IndexMask retrieve_selected_points(const Curves &curves_id, Vector &r_indices); /** diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt index c73585d549e..f5985a4729b 100644 --- a/source/blender/editors/transform/CMakeLists.txt +++ b/source/blender/editors/transform/CMakeLists.txt @@ -30,6 +30,7 @@ set(SRC transform_convert_armature.c transform_convert_cursor.c transform_convert_curve.c + transform_convert_curves.cc transform_convert_gpencil.c transform_convert_graph.c transform_convert_lattice.c diff --git a/source/blender/editors/transform/transform_convert.c b/source/blender/editors/transform/transform_convert.c index b02d1ed06c4..a2161daa58c 100644 --- a/source/blender/editors/transform/transform_convert.c +++ b/source/blender/editors/transform/transform_convert.c @@ -713,6 +713,7 @@ static void init_proportional_edit(TransInfo *t) if (!ELEM(t->data_type, &TransConvertType_Action, &TransConvertType_Curve, + &TransConvertType_Curves, &TransConvertType_Graph, &TransConvertType_GPencil, &TransConvertType_Lattice, @@ -784,6 +785,7 @@ static void init_TransDataContainers(TransInfo *t, &TransConvertType_Pose, &TransConvertType_EditArmature, &TransConvertType_Curve, + &TransConvertType_Curves, &TransConvertType_GPencil, &TransConvertType_Lattice, &TransConvertType_MBall, @@ -959,6 +961,9 @@ static TransConvertTypeInfo *convert_type_get(const TransInfo *t, Object **r_obj if (t->obedit_type == OB_ARMATURE) { return &TransConvertType_EditArmature; } + if (t->obedit_type == OB_CURVES) { + return &TransConvertType_Curves; + } return NULL; } if (ob && (ob->mode & OB_MODE_POSE)) { diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h index dd1e305762d..126f29f4fb4 100644 --- a/source/blender/editors/transform/transform_convert.h +++ b/source/blender/editors/transform/transform_convert.h @@ -134,6 +134,10 @@ extern TransConvertTypeInfo TransConvertType_Cursor3D; extern TransConvertTypeInfo TransConvertType_Curve; +/* transform_convert_curves.cc */ + +extern TransConvertTypeInfo TransConvertType_Curves; + /* transform_convert_graph.c */ extern TransConvertTypeInfo TransConvertType_Graph; diff --git a/source/blender/editors/transform/transform_convert_curves.cc b/source/blender/editors/transform/transform_convert_curves.cc new file mode 100644 index 00000000000..63eaba6de54 --- /dev/null +++ b/source/blender/editors/transform/transform_convert_curves.cc @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup edtransform + */ + +#include "BLI_array.hh" +#include "BLI_index_mask_ops.hh" +#include "BLI_span.hh" + +#include "BKE_curves.hh" + +#include "ED_curves.h" + +#include "MEM_guardedalloc.h" + +#include "transform.h" +#include "transform_convert.h" + +/* -------------------------------------------------------------------- */ +/** \name Curve/Surfaces Transform Creation + * \{ */ + +namespace blender::ed::transform::curves { + +static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t) +{ + MutableSpan trans_data_contrainers(t->data_container, t->data_container_len); + Array> selected_indices_per_object(t->data_container_len); + Array selection_per_object(t->data_container_len); + + /* Count selected elements per object and create TransData structs. */ + for (const int i : trans_data_contrainers.index_range()) { + TransDataContainer &tc = trans_data_contrainers[i]; + Curves *curves_id = static_cast(tc.obedit->data); + bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry); + + selection_per_object[i] = ed::curves::retrieve_selected_points(curves, + selected_indices_per_object[i]); + + tc.data_len = selection_per_object[i].size(); + if (tc.data_len > 0) { + tc.data = MEM_cnew_array(tc.data_len, __func__); + } + } + + /* Populate TransData structs. */ + for (const int i : trans_data_contrainers.index_range()) { + TransDataContainer &tc = trans_data_contrainers[i]; + if (tc.data_len == 0) { + continue; + } + Curves *curves_id = static_cast(tc.obedit->data); + bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry); + IndexMask selected_indices = selection_per_object[i]; + + float mtx[3][3], smtx[3][3]; + copy_m3_m4(mtx, tc.obedit->object_to_world); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); + + MutableSpan positions = curves.positions_for_write(); + threading::parallel_for(selected_indices.index_range(), 1024, [&](const IndexRange range) { + for (const int selection_i : range) { + TransData *td = &tc.data[selection_i]; + float *elem = reinterpret_cast(&positions[selected_indices[selection_i]]); + copy_v3_v3(td->iloc, elem); + copy_v3_v3(td->center, td->iloc); + td->loc = elem; + + td->flag = TD_SELECTED; + td->ext = nullptr; + + copy_m3_m3(td->smtx, smtx); + copy_m3_m3(td->mtx, mtx); + } + }); + } +} + +static void recalcData_curves(TransInfo *t) +{ + Span trans_data_contrainers(t->data_container, t->data_container_len); + for (const TransDataContainer &tc : trans_data_contrainers) { + Curves *curves_id = static_cast(tc.obedit->data); + bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry); + + curves.calculate_bezier_auto_handles(); + curves.tag_positions_changed(); + DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY); + } +} + +} // namespace blender::ed::transform::curves + +/** \} */ + +TransConvertTypeInfo TransConvertType_Curves = { + /*flags*/ (T_EDIT | T_POINTS), + /*createTransData*/ blender::ed::transform::curves::createTransCurvesVerts, + /*recalcData*/ blender::ed::transform::curves::recalcData_curves, + /*special_aftertrans_update*/ nullptr, +}; From 3d6fd2906be0adac2f42528f55a53e0cac1d5896 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sat, 21 Jan 2023 15:30:16 -0600 Subject: [PATCH 0851/1522] Cleanup: Move versioning_290.c to C++ Ref T103343 --- source/blender/blenloader/CMakeLists.txt | 2 +- .../{versioning_290.c => versioning_290.cc} | 214 +++++++++--------- .../blenloader/intern/versioning_common.cc | 2 +- 3 files changed, 108 insertions(+), 110 deletions(-) rename source/blender/blenloader/intern/{versioning_290.c => versioning_290.cc} (90%) diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index a7e99e7df2e..c660360bde7 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -43,7 +43,7 @@ set(SRC intern/versioning_260.c intern/versioning_270.c intern/versioning_280.c - intern/versioning_290.c + intern/versioning_290.cc intern/versioning_300.cc intern/versioning_400.cc intern/versioning_common.cc diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.cc similarity index 90% rename from source/blender/blenloader/intern/versioning_290.c rename to source/blender/blenloader/intern/versioning_290.cc index 10f72f22b8e..9c968e905cf 100644 --- a/source/blender/blenloader/intern/versioning_290.c +++ b/source/blender/blenloader/intern/versioning_290.cc @@ -6,7 +6,6 @@ /* allow readfile to use deprecated functionality */ #define DNA_DEPRECATED_ALLOW -#include "BLI_alloca.h" #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_string.h" @@ -73,16 +72,16 @@ static eSpaceSeq_Proxy_RenderSize get_sequencer_render_size(Main *bmain) { - eSpaceSeq_Proxy_RenderSize render_size = 100; + eSpaceSeq_Proxy_RenderSize render_size = eSpaceSeq_Proxy_RenderSize(100); - for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { switch (sl->spacetype) { case SPACE_SEQ: { SpaceSeq *sseq = (SpaceSeq *)sl; if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { - render_size = sseq->render_size; + render_size = eSpaceSeq_Proxy_RenderSize(sseq->render_size); break; } } @@ -96,7 +95,7 @@ static eSpaceSeq_Proxy_RenderSize get_sequencer_render_size(Main *bmain) static bool can_use_proxy(const Sequence *seq, int psize) { - if (seq->strip->proxy == NULL) { + if (seq->strip->proxy == nullptr) { return false; } short size_flags = seq->strip->proxy->build_size_flags; @@ -110,7 +109,7 @@ static void seq_convert_transform_animation(const Sequence *seq, const int image_size, const int scene_size) { - if (scene->adt == NULL || scene->adt->action == NULL) { + if (scene->adt == nullptr || scene->adt->action == nullptr) { return; } @@ -121,7 +120,7 @@ static void seq_convert_transform_animation(const Sequence *seq, /* Convert offset animation, but only if crop is not used. */ if ((seq->flag & use_transform_flag) != 0 && (seq->flag & use_crop_flag) == 0) { FCurve *fcu = BKE_fcurve_find(&scene->adt->action->curves, path, 0); - if (fcu != NULL && !BKE_fcurve_is_empty(fcu)) { + if (fcu != nullptr && !BKE_fcurve_is_empty(fcu)) { BezTriple *bezt = fcu->bezt; for (int i = 0; i < fcu->totvert; i++, bezt++) { /* Same math as with old_image_center_*, but simplified. */ @@ -142,11 +141,11 @@ static void seq_convert_transform_crop(const Scene *scene, Sequence *seq, const eSpaceSeq_Proxy_RenderSize render_size) { - if (seq->strip->transform == NULL) { - seq->strip->transform = MEM_callocN(sizeof(struct StripTransform), "StripTransform"); + if (seq->strip->transform == nullptr) { + seq->strip->transform = MEM_cnew(__func__); } - if (seq->strip->crop == NULL) { - seq->strip->crop = MEM_callocN(sizeof(struct StripCrop), "StripCrop"); + if (seq->strip->crop == nullptr) { + seq->strip->crop = MEM_cnew(__func__); } StripCrop *c = seq->strip->crop; @@ -161,7 +160,7 @@ static void seq_convert_transform_crop(const Scene *scene, const uint32_t use_crop_flag = (1 << 17); const StripElem *s_elem = seq->strip->stripdata; - if (s_elem != NULL) { + if (s_elem != nullptr) { image_size_x = s_elem->orig_width; image_size_y = s_elem->orig_height; @@ -186,8 +185,8 @@ static void seq_convert_transform_crop(const Scene *scene, t->xofs = t->yofs = 0; /* Reverse scale to fit for strips not using offset. */ - float project_aspect = (float)scene->r.xsch / (float)scene->r.ysch; - float image_aspect = (float)image_size_x / (float)image_size_y; + float project_aspect = float(scene->r.xsch) / float(scene->r.ysch); + float image_aspect = float(image_size_x) / float(image_size_y); if (project_aspect > image_aspect) { t->scale_x = project_aspect / image_aspect; } @@ -207,8 +206,8 @@ static void seq_convert_transform_crop(const Scene *scene, int cropped_image_size_x = image_size_x - c->right - c->left; int cropped_image_size_y = image_size_y - c->top - c->bottom; c->bottom = c->top = c->left = c->right = 0; - t->scale_x *= (float)image_size_x / (float)cropped_image_size_x; - t->scale_y *= (float)image_size_y / (float)cropped_image_size_y; + t->scale_x *= float(image_size_x) / float(cropped_image_size_x); + t->scale_y *= float(image_size_y) / float(cropped_image_size_y); } if ((seq->flag & use_transform_flag) != 0) { @@ -217,8 +216,8 @@ static void seq_convert_transform_crop(const Scene *scene, old_image_center_y = image_size_y / 2 - c->bottom + t->yofs; /* Preserve original image size. */ - t->scale_x = t->scale_y = MAX2((float)image_size_x / (float)scene->r.xsch, - (float)image_size_y / (float)scene->r.ysch); + t->scale_x = t->scale_y = MAX2(float(image_size_x) / float(scene->r.xsch), + float(image_size_y) / float(scene->r.ysch)); /* Convert crop. */ if ((seq->flag & use_crop_flag) != 0) { @@ -265,12 +264,12 @@ static void seq_convert_transform_animation_2(const Scene *scene, const char *path, const float scale_to_fit_factor) { - if (scene->adt == NULL || scene->adt->action == NULL) { + if (scene->adt == nullptr || scene->adt->action == nullptr) { return; } FCurve *fcu = BKE_fcurve_find(&scene->adt->action->curves, path, 0); - if (fcu != NULL && !BKE_fcurve_is_empty(fcu)) { + if (fcu != nullptr && !BKE_fcurve_is_empty(fcu)) { BezTriple *bezt = fcu->bezt; for (int i = 0; i < fcu->totvert; i++, bezt++) { /* Same math as with old_image_center_*, but simplified. */ @@ -286,7 +285,7 @@ static void seq_convert_transform_crop_2(const Scene *scene, const eSpaceSeq_Proxy_RenderSize render_size) { const StripElem *s_elem = seq->strip->stripdata; - if (s_elem == NULL) { + if (s_elem == nullptr) { return; } @@ -301,8 +300,8 @@ static void seq_convert_transform_crop_2(const Scene *scene, } /* Calculate scale factor, so image fits in preview area with original aspect ratio. */ - const float scale_to_fit_factor = MIN2((float)scene->r.xsch / (float)image_size_x, - (float)scene->r.ysch / (float)image_size_y); + const float scale_to_fit_factor = MIN2(float(scene->r.xsch) / float(image_size_x), + float(scene->r.ysch) / float(image_size_y)); t->scale_x *= scale_to_fit_factor; t->scale_y *= scale_to_fit_factor; c->top /= scale_to_fit_factor; @@ -351,7 +350,7 @@ static void seq_update_meta_disp_range(Scene *scene) { Editing *ed = SEQ_editing_get(scene); - if (ed == NULL) { + if (ed == nullptr) { return; } @@ -411,7 +410,7 @@ static void version_node_socket_duplicate(bNodeTree *ntree, } } -void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) +void do_versions_after_linking_290(Main *bmain, ReportList * /*reports*/) { if (!MAIN_VERSION_ATLEAST(bmain, 290, 1)) { /* Patch old grease pencil modifiers material filter. */ @@ -421,8 +420,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Array: { ArrayGpencilModifierData *gpmd = (ArrayGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -430,8 +429,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Color: { ColorGpencilModifierData *gpmd = (ColorGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -439,8 +438,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Hook: { HookGpencilModifierData *gpmd = (HookGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -448,8 +447,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Lattice: { LatticeGpencilModifierData *gpmd = (LatticeGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -457,8 +456,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Mirror: { MirrorGpencilModifierData *gpmd = (MirrorGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -466,8 +465,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Multiply: { MultiplyGpencilModifierData *gpmd = (MultiplyGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -475,8 +474,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Noise: { NoiseGpencilModifierData *gpmd = (NoiseGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -484,8 +483,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Offset: { OffsetGpencilModifierData *gpmd = (OffsetGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -493,8 +492,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Opacity: { OpacityGpencilModifierData *gpmd = (OpacityGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -502,8 +501,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Simplify: { SimplifyGpencilModifierData *gpmd = (SimplifyGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -511,8 +510,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Smooth: { SmoothGpencilModifierData *gpmd = (SmoothGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -520,8 +519,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Subdiv: { SubdivGpencilModifierData *gpmd = (SubdivGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -529,8 +528,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Texture: { TextureGpencilModifierData *gpmd = (TextureGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -538,8 +537,8 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) case eGpencilModifierType_Thick: { ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md; if (gpmd->materialname[0] != '\0') { - gpmd->material = BLI_findstring( - &bmain->materials, gpmd->materialname, offsetof(ID, name) + 2); + gpmd->material = static_cast( + BLI_findstring(&bmain->materials, gpmd->materialname, offsetof(ID, name) + 2)); gpmd->materialname[0] = '\0'; } break; @@ -551,15 +550,15 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) } /* Patch first frame for old files. */ - Scene *scene = bmain->scenes.first; - if (scene != NULL) { + Scene *scene = static_cast(bmain->scenes.first); + if (scene != nullptr) { LISTBASE_FOREACH (Object *, ob, &bmain->objects) { if (ob->type != OB_GPENCIL) { continue; } - bGPdata *gpd = ob->data; + bGPdata *gpd = static_cast(ob->data); LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { - bGPDframe *gpf = gpl->frames.first; + bGPDframe *gpf = static_cast(gpl->frames.first); if (gpf && gpf->framenum > scene->r.sfra) { bGPDframe *gpf_dup = BKE_gpencil_frame_duplicate(gpf, true); gpf_dup->framenum = scene->r.sfra; @@ -600,8 +599,7 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) /* Convert all Multires displacement to Catmull-Clark subdivision limit surface. */ if (!MAIN_VERSION_ATLEAST(bmain, 292, 1)) { LISTBASE_FOREACH (Object *, ob, &bmain->objects) { - ModifierData *md; - for (md = ob->modifiers.first; md; md = md->next) { + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_Multires) { MultiresModifierData *mmd = (MultiresModifierData *)md; if (mmd->simple) { @@ -617,7 +615,7 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) eSpaceSeq_Proxy_RenderSize render_size = get_sequencer_render_size(bmain); LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { - if (scene->ed != NULL) { + if (scene->ed != nullptr) { seq_convert_transform_crop_lb(scene, &scene->ed->seqbase, render_size); } } @@ -628,12 +626,12 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) * Armature obdata. */ LISTBASE_FOREACH (Object *, ob, &bmain->objects) { if (ob->type == OB_ARMATURE) { - BKE_pose_rebuild(bmain, ob, ob->data, true); + BKE_pose_rebuild(bmain, ob, static_cast(ob->data), true); } } /* Wet Paint Radius Factor */ - for (Brush *br = bmain->brushes.first; br; br = br->id.next) { + LISTBASE_FOREACH (Brush *, br, &bmain->brushes) { if (br->ob_mode & OB_MODE_SCULPT && br->wet_paint_radius_factor == 0.0f) { br->wet_paint_radius_factor = 1.0f; } @@ -641,7 +639,7 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports)) eSpaceSeq_Proxy_RenderSize render_size = get_sequencer_render_size(bmain); LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { - if (scene->ed != NULL) { + if (scene->ed != nullptr) { seq_convert_transform_crop_lb_2(scene, &scene->ed->seqbase, render_size); } } @@ -797,12 +795,12 @@ static void version_node_join_geometry_for_multi_input_socket(bNodeTree *ntree) { LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { if (link->tonode->type == GEO_NODE_JOIN_GEOMETRY && !(link->tosock->flag & SOCK_MULTI_INPUT)) { - link->tosock = link->tonode->inputs.first; + link->tosock = static_cast(link->tonode->inputs.first); } } LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == GEO_NODE_JOIN_GEOMETRY) { - bNodeSocket *socket = node->inputs.first; + bNodeSocket *socket = static_cast(node->inputs.first); socket->flag |= SOCK_MULTI_INPUT; socket->limit = 4095; nodeRemoveSocket(ntree, node, socket->next); @@ -811,7 +809,7 @@ static void version_node_join_geometry_for_multi_input_socket(bNodeTree *ntree) } /* NOLINTNEXTLINE: readability-function-size */ -void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) +void blo_do_versions_290(FileData *fd, Library * /*lib*/, Main *bmain) { UNUSED_VARS(fd); @@ -854,7 +852,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!DNA_struct_elem_find(fd->filesdna, "SpaceImage", "float", "uv_opacity")) { - for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_IMAGE) { @@ -869,7 +867,8 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Init Grease Pencil new random curves. */ if (!DNA_struct_elem_find(fd->filesdna, "BrushGpencilSettings", "float", "random_hue")) { LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) { - if ((brush->gpencil_settings) && (brush->gpencil_settings->curve_rand_pressure == NULL)) { + if ((brush->gpencil_settings) && + (brush->gpencil_settings->curve_rand_pressure == nullptr)) { brush->gpencil_settings->curve_rand_pressure = BKE_curvemapping_add( 1, 0.0f, 0.0f, 1.0f, 1.0f); brush->gpencil_settings->curve_rand_strength = BKE_curvemapping_add( @@ -923,7 +922,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 290, 6)) { /* Transition to saving expansion for all of a modifier's sub-panels. */ if (!DNA_struct_elem_find(fd->filesdna, "ModifierData", "short", "ui_expand_flag")) { - for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (Object *, object, &bmain->objects) { LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->mode & eModifierMode_Expanded_DEPRECATED) { md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT; @@ -951,7 +950,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Transition to saving expansion for all of a constraint's sub-panels. */ if (!DNA_struct_elem_find(fd->filesdna, "bConstraint", "short", "ui_expand_flag")) { - for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (Object *, object, &bmain->objects) { LISTBASE_FOREACH (bConstraint *, con, &object->constraints) { if (con->flag & CONSTRAINT_EXPAND_DEPRECATED) { con->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT; @@ -965,7 +964,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Transition to saving expansion for all of grease pencil modifier's sub-panels. */ if (!DNA_struct_elem_find(fd->filesdna, "GpencilModifierData", "short", "ui_expand_flag")) { - for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (Object *, object, &bmain->objects) { LISTBASE_FOREACH (GpencilModifierData *, md, &object->greasepencil_modifiers) { if (md->mode & eGpencilModifierMode_Expanded_DEPRECATED) { md->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT; @@ -979,7 +978,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Transition to saving expansion for all of an effect's sub-panels. */ if (!DNA_struct_elem_find(fd->filesdna, "ShaderFxData", "short", "ui_expand_flag")) { - for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (Object *, object, &bmain->objects) { LISTBASE_FOREACH (ShaderFxData *, fx, &object->shader_fx) { if (fx->mode & eShaderFxMode_Expanded_DEPRECATED) { fx->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT; @@ -993,7 +992,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Refactor bevel profile type to use an enum. */ if (!DNA_struct_elem_find(fd->filesdna, "BevelModifierData", "short", "profile_type")) { - for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (Object *, object, &bmain->objects) { LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Bevel) { BevelModifierData *bmd = (BevelModifierData *)md; @@ -1006,7 +1005,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } /* Change ocean modifier values from [0, 10] to [0, 1] ranges. */ - for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (Object *, object, &bmain->objects) { LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Ocean) { OceanModifierData *omd = (OceanModifierData *)md; @@ -1037,7 +1036,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Refactor bevel affect type to use an enum. */ if (!DNA_struct_elem_find(fd->filesdna, "BevelModifierData", "char", "affect_type")) { - for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (Object *, object, &bmain->objects) { LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Bevel) { BevelModifierData *bmd = (BevelModifierData *)md; @@ -1052,7 +1051,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Initialize additional velocity parameter for #CacheFile's. */ if (!DNA_struct_elem_find( fd->filesdna, "MeshSeqCacheModifierData", "float", "velocity_scale")) { - for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (Object *, object, &bmain->objects) { LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_MeshSequenceCache) { MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md; @@ -1063,15 +1062,14 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!DNA_struct_elem_find(fd->filesdna, "CacheFile", "char", "velocity_unit")) { - for (CacheFile *cache_file = bmain->cachefiles.first; cache_file != NULL; - cache_file = cache_file->id.next) { + LISTBASE_FOREACH (CacheFile *, cache_file, &bmain->cachefiles) { BLI_strncpy(cache_file->velocity_name, ".velocities", sizeof(cache_file->velocity_name)); cache_file->velocity_unit = CACHEFILE_VELOCITY_UNIT_SECOND; } } if (!DNA_struct_elem_find(fd->filesdna, "OceanModifierData", "int", "viewport_resolution")) { - for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (Object *, object, &bmain->objects) { LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Ocean) { OceanModifierData *omd = (OceanModifierData *)md; @@ -1094,10 +1092,10 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } if (!MAIN_VERSION_ATLEAST(bmain, 291, 2)) { - for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { RigidBodyWorld *rbw = scene->rigidbody_world; - if (rbw == NULL) { + if (rbw == nullptr) { continue; } @@ -1111,8 +1109,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } /* PointCloud attributes. */ - for (PointCloud *pointcloud = bmain->pointclouds.first; pointcloud != NULL; - pointcloud = pointcloud->id.next) { + LISTBASE_FOREACH (PointCloud *, pointcloud, &bmain->pointclouds) { do_versions_point_attributes(&pointcloud->pdata); } @@ -1130,7 +1127,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } /* Solver and Collections for Boolean. */ - for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (Object *, object, &bmain->objects) { LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type == eModifierType_Boolean) { BooleanModifierData *bmd = (BooleanModifierData *)md; @@ -1160,10 +1157,10 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 291, 5)) { /* Fix fcurves to allow for new bezier handles behavior (T75881 and D8752). */ - for (bAction *act = bmain->actions.first; act; act = act->id.next) { - for (FCurve *fcu = act->curves.first; fcu; fcu = fcu->next) { + LISTBASE_FOREACH (bAction *, act, &bmain->actions) { + LISTBASE_FOREACH (FCurve *, fcu, &act->curves) { /* Only need to fix Bezier curves with at least 2 key-frames. */ - if (fcu->totvert < 2 || fcu->bezt == NULL) { + if (fcu->totvert < 2 || fcu->bezt == nullptr) { continue; } do_versions_291_fcurve_handles_limit(fcu); @@ -1184,7 +1181,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) /* Add custom profile and bevel mode to curve bevels. */ if (!DNA_struct_elem_find(fd->filesdna, "Curve", "char", "bevel_mode")) { LISTBASE_FOREACH (Curve *, curve, &bmain->curves) { - if (curve->bevobj != NULL) { + if (curve->bevobj != nullptr) { curve->bevel_mode = CU_BEV_MODE_OBJECT; } else { @@ -1198,7 +1195,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_Fluid) { FluidModifierData *fmd = (FluidModifierData *)md; - if (fmd->domain != NULL) { + if (fmd->domain != nullptr) { if (!fmd->domain->coba_field && fmd->domain->type == FLUID_DOMAIN_TYPE_LIQUID) { fmd->domain->coba_field = FLUID_DOMAIN_FIELD_PHI; } @@ -1216,7 +1213,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 291, 6)) { /* Darken Inactive Overlay. */ if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "fade_alpha")) { - for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { @@ -1239,7 +1236,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } /* Alembic importer: allow vertex interpolation by default. */ - for (Object *object = bmain->objects.first; object != NULL; object = object->id.next) { + LISTBASE_FOREACH (Object *, object, &bmain->objects) { LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) { if (md->type != eModifierType_MeshSequenceCache) { continue; @@ -1264,11 +1261,11 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) WorkSpaceDataRelation *, relation, &workspace->hook_layout_relations) { relation->parent = blo_read_get_new_globaldata_address(fd, relation->parent); BLI_assert(relation->parentid == 0); - if (relation->parent != NULL) { + if (relation->parent != nullptr) { LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) { - wmWindow *win = BLI_findptr( - &wm->windows, relation->parent, offsetof(wmWindow, workspace_hook)); - if (win != NULL) { + wmWindow *win = static_cast( + BLI_findptr(&wm->windows, relation->parent, offsetof(wmWindow, workspace_hook))); + if (win != nullptr) { relation->parentid = win->winid; break; } @@ -1310,7 +1307,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 291, 9)) { /* Remove options of legacy UV/Image editor */ - for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { switch (sl->spacetype) { @@ -1370,7 +1367,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 292, 5)) { /* Initialize the opacity of the overlay wireframe */ if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "wireframe_opacity")) { - for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) { + LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { @@ -1401,7 +1398,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_WeightVGProximity) { WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *)md; - if (wmd->cmap_curve == NULL) { + if (wmd->cmap_curve == nullptr) { wmd->cmap_curve = BKE_curvemapping_add(1, 0.0, 0.0, 1.0, 1.0); BKE_curvemapping_init(wmd->cmap_curve); } @@ -1442,7 +1439,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } /* EEVEE/Cycles Volumes consistency */ - for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) { + LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { /* Remove Volume Transmittance render pass from each view layer. */ LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) { view_layer->eevee.render_passes &= ~EEVEE_RENDER_PASS_UNUSED_8; @@ -1471,7 +1468,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) if (node->type == CMP_NODE_CRYPTOMATTE_LEGACY) { NodeCryptomatte *storage = (NodeCryptomatte *)node->storage; char *matte_id = storage->matte_id; - if (matte_id == NULL || strlen(storage->matte_id) == 0) { + if (matte_id == nullptr || strlen(storage->matte_id) == 0) { continue; } BKE_cryptomatte_matte_id_to_entries(storage, storage->matte_id); @@ -1505,7 +1502,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) } LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { - if (scene->toolsettings->sequencer_tool_settings == NULL) { + if (scene->toolsettings->sequencer_tool_settings == nullptr) { scene->toolsettings->sequencer_tool_settings = SEQ_tool_settings_init(); } } @@ -1530,7 +1527,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { if (md->type == eModifierType_Fluid) { FluidModifierData *fmd = (FluidModifierData *)md; - if (fmd->domain != NULL) { + if (fmd->domain != nullptr) { fmd->domain->viscosity_value = 0.05; } } @@ -1549,7 +1546,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) if (node->type != CMP_NODE_SETALPHA) { continue; } - NodeSetAlpha *storage = MEM_callocN(sizeof(NodeSetAlpha), "NodeSetAlpha"); + NodeSetAlpha *storage = MEM_cnew("NodeSetAlpha"); storage->mode = CMP_NODE_SETALPHA_MODE_REPLACE_ALPHA; node->storage = storage; } @@ -1559,7 +1556,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { Editing *ed = SEQ_editing_get(scene); - if (ed == NULL) { + if (ed == nullptr) { continue; } ed->cache_flag = (SEQ_CACHE_STORE_RAW | SEQ_CACHE_STORE_FINAL_OUT); @@ -1575,7 +1572,8 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { if (node->type == CMP_NODE_OUTPUT_FILE) { LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) { - NodeImageMultiFileSocket *simf = sock->storage; + NodeImageMultiFileSocket *simf = static_cast( + sock->storage); simf->save_as_render = true; } } @@ -1617,7 +1615,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) continue; } LISTBASE_FOREACH (bNode *, node, &ntree->nodes) { - if (node->type == GEO_NODE_OBJECT_INFO && node->storage == NULL) { + if (node->type == GEO_NODE_OBJECT_INFO && node->storage == nullptr) { NodeGeometryObjectInfo *data = (NodeGeometryObjectInfo *)MEM_callocN( sizeof(NodeGeometryObjectInfo), __func__); data->transform_space = GEO_NODE_TRANSFORM_SPACE_RELATIVE; @@ -1767,7 +1765,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) &sl->regionbase; ARegion *new_footer = do_versions_add_region_if_not_found( regionbase, RGN_TYPE_FOOTER, "footer for spreadsheet", RGN_TYPE_HEADER); - if (new_footer != NULL) { + if (new_footer != nullptr) { new_footer->alignment = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_TOP : RGN_ALIGN_BOTTOM; } @@ -1842,7 +1840,7 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain) if (!MAIN_VERSION_ATLEAST(bmain, 293, 18)) { if (!DNA_struct_elem_find(fd->filesdna, "bArmature", "float", "axes_position")) { /* Convert the axes draw position to its old default (tip of bone). */ - LISTBASE_FOREACH (struct bArmature *, arm, &bmain->armatures) { + LISTBASE_FOREACH (bArmature *, arm, &bmain->armatures) { arm->axes_position = 1.0; } } diff --git a/source/blender/blenloader/intern/versioning_common.cc b/source/blender/blenloader/intern/versioning_common.cc index 7bbcfa8a203..80df0a2ba74 100644 --- a/source/blender/blenloader/intern/versioning_common.cc +++ b/source/blender/blenloader/intern/versioning_common.cc @@ -184,7 +184,7 @@ void version_node_socket_index_animdata(Main *bmain, /* The for loop for the input ids is at the top level otherwise we lose the animation * keyframe data. Not sure what causes that, so I (Sybren) moved the code here from - * versioning_290.c as-is (structure-wise). */ + * versioning_290.cc as-is (structure-wise). */ for (int input_index = total_number_of_sockets - 1; input_index >= socket_index_orig; input_index--) { FOREACH_NODETREE_BEGIN (bmain, ntree, owner_id) { From f2bb044fdba43139c26d3ce2de41965af1dfab0f Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Sat, 21 Jan 2023 15:44:58 -0600 Subject: [PATCH 0852/1522] Cleanup: Move six mesh-related files to C++ For continued refactoring of the Mesh data structure. See T103343. --- source/blender/blenkernel/CMakeLists.txt | 2 +- .../blenkernel/intern/{deform.c => deform.cc} | 215 +++---- source/blender/editors/object/CMakeLists.txt | 4 +- .../object/{object_bake.c => object_bake.cc} | 78 ++- .../{object_bake_api.c => object_bake_api.cc} | 239 ++++---- .../editors/space_view3d/CMakeLists.txt | 2 +- .../{drawobject.c => drawobject.cc} | 26 +- source/blender/editors/uvedit/CMakeLists.txt | 2 +- ...edit_unwrap_ops.c => uvedit_unwrap_ops.cc} | 538 +++++++++--------- 9 files changed, 557 insertions(+), 549 deletions(-) rename source/blender/blenkernel/intern/{deform.c => deform.cc} (88%) rename source/blender/editors/object/{object_bake.c => object_bake.cc} (88%) rename source/blender/editors/object/{object_bake_api.c => object_bake_api.cc} (90%) rename source/blender/editors/space_view3d/{drawobject.c => drawobject.cc} (78%) rename source/blender/editors/uvedit/{uvedit_unwrap_ops.c => uvedit_unwrap_ops.cc} (86%) diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 8a714d8d911..8d6fe6c3cf7 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -119,7 +119,7 @@ set(SRC intern/customdata.cc intern/customdata_file.c intern/data_transfer.cc - intern/deform.c + intern/deform.cc intern/displist.cc intern/dynamicpaint.cc intern/editlattice.c diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.cc similarity index 88% rename from source/blender/blenkernel/intern/deform.c rename to source/blender/blenkernel/intern/deform.cc index 8bc98270054..a01c6d724a4 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.cc @@ -5,11 +5,11 @@ * \ingroup bke */ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include "MEM_guardedalloc.h" @@ -46,7 +46,7 @@ bDeformGroup *BKE_object_defgroup_new(Object *ob, const char *name) BLI_assert(OB_TYPE_SUPPORT_VGROUP(ob->type)); - defgroup = MEM_callocN(sizeof(bDeformGroup), __func__); + defgroup = MEM_cnew(__func__); BLI_strncpy(defgroup->name, name, sizeof(defgroup->name)); @@ -62,31 +62,26 @@ bDeformGroup *BKE_object_defgroup_new(Object *ob, const char *name) void BKE_defgroup_copy_list(ListBase *outbase, const ListBase *inbase) { - bDeformGroup *defgroup, *defgroupn; - BLI_listbase_clear(outbase); - - for (defgroup = inbase->first; defgroup; defgroup = defgroup->next) { - defgroupn = BKE_defgroup_duplicate(defgroup); + LISTBASE_FOREACH (const bDeformGroup *, defgroup, inbase) { + bDeformGroup *defgroupn = BKE_defgroup_duplicate(defgroup); BLI_addtail(outbase, defgroupn); } } bDeformGroup *BKE_defgroup_duplicate(const bDeformGroup *ingroup) { - bDeformGroup *outgroup; - if (!ingroup) { BLI_assert(0); - return NULL; + return nullptr; } - outgroup = MEM_callocN(sizeof(bDeformGroup), "copy deformGroup"); + bDeformGroup *outgroup = MEM_cnew(__func__); /* For now, just copy everything over. */ memcpy(outgroup, ingroup, sizeof(bDeformGroup)); - outgroup->next = outgroup->prev = NULL; + outgroup->next = outgroup->prev = nullptr; return outgroup; } @@ -132,10 +127,10 @@ void BKE_defvert_copy(MDeformVert *dvert_dst, const MDeformVert *dvert_src) } if (dvert_src->totweight) { - dvert_dst->dw = MEM_dupallocN(dvert_src->dw); + dvert_dst->dw = static_cast(MEM_dupallocN(dvert_src->dw)); } else { - dvert_dst->dw = NULL; + dvert_dst->dw = nullptr; } dvert_dst->totweight = dvert_src->totweight; @@ -157,7 +152,7 @@ void BKE_defvert_copy_index(MDeformVert *dvert_dst, dw_dst->weight = dw_src->weight; } else { - /* Source was NULL, assign zero (could also remove). */ + /* Source was nullptr, assign zero (could also remove). */ dw_dst = BKE_defvert_find_index(dvert_dst, defgroup_dst); if (dw_dst) { @@ -307,7 +302,7 @@ void BKE_defvert_normalize_lock_single(MDeformVert *dvert, } } else { - MDeformWeight *dw_lock = NULL; + MDeformWeight *dw_lock = nullptr; MDeformWeight *dw; uint i; float tot_weight = 0.0f; @@ -423,7 +418,7 @@ void BKE_defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int for (dw = dvert->dw, i = 0; i < totweight; dw++, i++) { if (dw->def_nr < flip_map_num) { if (flip_map[dw->def_nr] >= 0) { - /* error checkers complain of this but we'll never get NULL return */ + /* error checkers complain of this but we'll never get nullptr return */ dw_cpy = BKE_defvert_ensure_index(dvert, flip_map[dw->def_nr]); dw = &dvert->dw[i]; /* in case array got realloced */ @@ -441,7 +436,7 @@ void BKE_defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int bool BKE_object_supports_vertex_groups(const Object *ob) { const ID *id = (const ID *)ob->data; - if (id == NULL) { + if (id == nullptr) { return false; } @@ -467,7 +462,7 @@ const ListBase *BKE_id_defgroup_list_get(const ID *id) BLI_assert_unreachable(); } } - return NULL; + return nullptr; } static const int *object_defgroup_active_index_get_p(const Object *ob) @@ -487,7 +482,7 @@ static const int *object_defgroup_active_index_get_p(const Object *ob) return &gpd->vertex_group_active_index; } } - return NULL; + return nullptr; } ListBase *BKE_id_defgroup_list_get_mutable(ID *id) @@ -498,38 +493,38 @@ ListBase *BKE_id_defgroup_list_get_mutable(ID *id) bDeformGroup *BKE_object_defgroup_find_name(const Object *ob, const char *name) { - if (name == NULL || name[0] == '\0') { - return NULL; + if (name == nullptr || name[0] == '\0') { + return nullptr; } const ListBase *defbase = BKE_object_defgroup_list(ob); - return BLI_findstring(defbase, name, offsetof(bDeformGroup, name)); + return static_cast(BLI_findstring(defbase, name, offsetof(bDeformGroup, name))); } int BKE_id_defgroup_name_index(const ID *id, const char *name) { int index; - if (!BKE_id_defgroup_name_find(id, name, &index, NULL)) { + if (!BKE_id_defgroup_name_find(id, name, &index, nullptr)) { return -1; } return index; } -bool BKE_id_defgroup_name_find(const struct ID *id, +bool BKE_id_defgroup_name_find(const ID *id, const char *name, int *r_index, - struct bDeformGroup **r_group) + bDeformGroup **r_group) { - if (name == NULL || name[0] == '\0') { + if (name == nullptr || name[0] == '\0') { return false; } const ListBase *defbase = BKE_id_defgroup_list_get(id); int index; LISTBASE_FOREACH_INDEX (bDeformGroup *, group, defbase, index) { if (STREQ(name, group->name)) { - if (r_index != NULL) { + if (r_index != nullptr) { *r_index = index; } - if (r_group != NULL) { + if (r_group != nullptr) { *r_group = group; } return true; @@ -582,19 +577,19 @@ static int *object_defgroup_unlocked_flip_map_ex(const Object *ob, *r_flip_map_num = defbase_num; if (defbase_num == 0) { - return NULL; + return nullptr; } bDeformGroup *dg; char name_flip[sizeof(dg->name)]; int i, flip_num; - int *map = MEM_mallocN(defbase_num * sizeof(int), __func__); + int *map = static_cast(MEM_mallocN(defbase_num * sizeof(int), __func__)); for (i = 0; i < defbase_num; i++) { map[i] = -1; } - for (dg = defbase->first, i = 0; dg; dg = dg->next, i++) { + for (dg = static_cast(defbase->first), i = 0; dg; dg = dg->next, i++) { if (map[i] == -1) { /* may be calculated previously */ /* in case no valid value is found, use this */ @@ -642,18 +637,17 @@ int *BKE_object_defgroup_flip_map_single(const Object *ob, *r_flip_map_num = defbase_num; if (defbase_num == 0) { - return NULL; + return nullptr; } - bDeformGroup *dg; - char name_flip[sizeof(dg->name)]; - int i, flip_num, *map = MEM_mallocN(defbase_num * sizeof(int), __func__); + char name_flip[sizeof(bDeformGroup::name)]; + int i, flip_num, *map = static_cast(MEM_mallocN(defbase_num * sizeof(int), __func__)); for (i = 0; i < defbase_num; i++) { map[i] = use_default ? i : -1; } - dg = BLI_findlink(defbase, defgroup); + bDeformGroup *dg = static_cast(BLI_findlink(defbase, defgroup)); BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip)); if (!STREQ(name_flip, dg->name)) { @@ -671,7 +665,7 @@ int *BKE_object_defgroup_flip_map_single(const Object *ob, int BKE_object_defgroup_flip_index(const Object *ob, int index, const bool use_default) { const ListBase *defbase = BKE_object_defgroup_list(ob); - bDeformGroup *dg = BLI_findlink(defbase, index); + bDeformGroup *dg = static_cast(BLI_findlink(defbase, index)); int flip_index = -1; if (dg) { @@ -691,7 +685,7 @@ static bool defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object * const ListBase *defbase = BKE_object_defgroup_list(ob); bDeformGroup *curdef; - for (curdef = defbase->first; curdef; curdef = curdef->next) { + for (curdef = static_cast(defbase->first); curdef; curdef = curdef->next) { if (dg != curdef) { if (STREQ(curdef->name, name)) { return true; @@ -702,46 +696,42 @@ static bool defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object * return false; } +struct DeformGroupUniqueNameData { + Object *ob; + bDeformGroup *dg; +}; + static bool defgroup_unique_check(void *arg, const char *name) { - struct { - Object *ob; - void *dg; - } *data = arg; + DeformGroupUniqueNameData *data = static_cast(arg); return defgroup_find_name_dupe(name, data->dg, data->ob); } void BKE_object_defgroup_unique_name(bDeformGroup *dg, Object *ob) { - struct { - Object *ob; - void *dg; - } data; - data.ob = ob; - data.dg = dg; - + DeformGroupUniqueNameData data{ob, dg}; BLI_uniquename_cb(defgroup_unique_check, &data, DATA_("Group"), '.', dg->name, sizeof(dg->name)); } -float BKE_defvert_find_weight(const struct MDeformVert *dvert, const int defgroup) +float BKE_defvert_find_weight(const MDeformVert *dvert, const int defgroup) { MDeformWeight *dw = BKE_defvert_find_index(dvert, defgroup); return dw ? dw->weight : 0.0f; } -float BKE_defvert_array_find_weight_safe(const struct MDeformVert *dvert, +float BKE_defvert_array_find_weight_safe(const MDeformVert *dvert, const int index, const int defgroup) { /* Invalid defgroup index means the vgroup selected is invalid, * does not exist, in that case it is OK to return 1.0 * (i.e. maximum weight, as if no vgroup was selected). - * But in case of valid defgroup and NULL dvert data pointer, it means that vgroup **is** valid, - * and just totally empty, so we shall return '0.0' value then! */ + * But in case of valid defgroup and nullptr dvert data pointer, it means that vgroup **is** + * valid, and just totally empty, so we shall return '0.0' value then! */ if (defgroup == -1) { return 1.0f; } - if (dvert == NULL) { + if (dvert == nullptr) { return 0.0f; } @@ -764,7 +754,7 @@ MDeformWeight *BKE_defvert_find_index(const MDeformVert *dvert, const int defgro BLI_assert(0); } - return NULL; + return nullptr; } MDeformWeight *BKE_defvert_ensure_index(MDeformVert *dvert, const int defgroup) @@ -774,7 +764,7 @@ MDeformWeight *BKE_defvert_ensure_index(MDeformVert *dvert, const int defgroup) /* do this check always, this function is used to check for it */ if (!dvert || defgroup < 0) { BLI_assert(0); - return NULL; + return nullptr; } dw_new = BKE_defvert_find_index(dvert, defgroup); @@ -782,7 +772,8 @@ MDeformWeight *BKE_defvert_ensure_index(MDeformVert *dvert, const int defgroup) return dw_new; } - dw_new = MEM_mallocN(sizeof(MDeformWeight) * (dvert->totweight + 1), "deformWeight"); + dw_new = static_cast( + MEM_mallocN(sizeof(MDeformWeight) * (dvert->totweight + 1), __func__)); if (dvert->dw) { memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight); MEM_freeN(dvert->dw); @@ -810,8 +801,8 @@ void BKE_defvert_add_index_notest(MDeformVert *dvert, const int defgroup, const return; } - dw_new = MEM_callocN(sizeof(MDeformWeight) * (dvert->totweight + 1), - "defvert_add_to group, new deformWeight"); + dw_new = static_cast( + MEM_callocN(sizeof(MDeformWeight) * (dvert->totweight + 1), __func__)); if (dvert->dw) { memcpy(dw_new, dvert->dw, sizeof(MDeformWeight) * dvert->totweight); MEM_freeN(dvert->dw); @@ -838,18 +829,19 @@ void BKE_defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw) * this deform weight, and reshuffle the others. */ if (dvert->totweight) { - BLI_assert(dvert->dw != NULL); + BLI_assert(dvert->dw != nullptr); if (i != dvert->totweight) { dvert->dw[i] = dvert->dw[dvert->totweight]; } - dvert->dw = MEM_reallocN(dvert->dw, sizeof(MDeformWeight) * dvert->totweight); + dvert->dw = static_cast( + MEM_reallocN(dvert->dw, sizeof(MDeformWeight) * dvert->totweight)); } else { /* If there are no other deform weights left then just remove this one. */ MEM_freeN(dvert->dw); - dvert->dw = NULL; + dvert->dw = nullptr; } } } @@ -877,7 +869,7 @@ int BKE_defvert_find_shared(const MDeformVert *dvert_a, const MDeformVert *dvert return -1; } -bool BKE_defvert_is_weight_zero(const struct MDeformVert *dvert, const int defgroup_tot) +bool BKE_defvert_is_weight_zero(const MDeformVert *dvert, const int defgroup_tot) { MDeformWeight *dw = dvert->dw; for (int i = dvert->totweight; i != 0; i--, dw++) { @@ -891,14 +883,14 @@ bool BKE_defvert_is_weight_zero(const struct MDeformVert *dvert, const int defgr return true; } -float BKE_defvert_total_selected_weight(const struct MDeformVert *dv, +float BKE_defvert_total_selected_weight(const MDeformVert *dv, int defbase_num, const bool *defbase_sel) { float total = 0.0f; const MDeformWeight *dw = dv->dw; - if (defbase_sel == NULL) { + if (defbase_sel == nullptr) { return total; } @@ -913,7 +905,7 @@ float BKE_defvert_total_selected_weight(const struct MDeformVert *dv, return total; } -float BKE_defvert_multipaint_collective_weight(const struct MDeformVert *dv, +float BKE_defvert_multipaint_collective_weight(const MDeformVert *dv, const int defbase_num, const bool *defbase_sel, const int defbase_sel_num, @@ -959,7 +951,7 @@ float BKE_defvert_calc_lock_relative_weight(float weight, } float BKE_defvert_lock_relative_weight(const float weight, - const struct MDeformVert *dv, + const MDeformVert *dv, const int defbase_num, const bool *defbase_locked, const bool *defbase_unlocked) @@ -991,7 +983,8 @@ void BKE_defvert_array_copy(MDeformVert *dst, const MDeformVert *src, int totver for (int i = 0; i < totvert; i++) { if (src[i].dw) { - dst[i].dw = MEM_mallocN(sizeof(MDeformWeight) * src[i].totweight, "copy_deformWeight"); + dst[i].dw = static_cast( + MEM_mallocN(sizeof(MDeformWeight) * src[i].totweight, __func__)); memcpy(dst[i].dw, src[i].dw, sizeof(MDeformWeight) * src[i].totweight); } } @@ -1059,7 +1052,8 @@ void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert, { if (dvert && defgroup != -1) { int i = edges_num; - float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)verts_num, __func__); + float *tmp_weights = static_cast( + MEM_mallocN(sizeof(*tmp_weights) * (size_t)verts_num, __func__)); BKE_defvert_extract_vgroup_to_vertweights( dvert, defgroup, verts_num, invert_vgroup, tmp_weights); @@ -1087,7 +1081,8 @@ void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert, { if (dvert && defgroup != -1) { int i = loops_num; - float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)verts_num, __func__); + float *tmp_weights = static_cast( + MEM_mallocN(sizeof(*tmp_weights) * (size_t)verts_num, __func__)); BKE_defvert_extract_vgroup_to_vertweights( dvert, defgroup, verts_num, invert_vgroup, tmp_weights); @@ -1109,7 +1104,7 @@ void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert, const int defgroup, const int verts_num, const MLoop *loops, - const int UNUSED(loops_num), + const int /*loops_num*/, const MPoly *polys, const int polys_num, const bool invert_vgroup, @@ -1117,7 +1112,8 @@ void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert, { if (dvert && defgroup != -1) { int i = polys_num; - float *tmp_weights = MEM_mallocN(sizeof(*tmp_weights) * (size_t)verts_num, __func__); + float *tmp_weights = static_cast( + MEM_mallocN(sizeof(*tmp_weights) * (size_t)verts_num, __func__)); BKE_defvert_extract_vgroup_to_vertweights( dvert, defgroup, verts_num, invert_vgroup, tmp_weights); @@ -1131,7 +1127,7 @@ void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert, for (; j--; ml++) { w += tmp_weights[ml->v]; } - r_weights[i] = w / (float)mp->totloop; + r_weights[i] = w / float(mp->totloop); } MEM_freeN(tmp_weights); @@ -1217,9 +1213,9 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map, Object *ob_dst, const MDeformVert *data_src, MDeformVert *data_dst, - const CustomData *UNUSED(cd_src), + const CustomData * /*cd_src*/, CustomData *cd_dst, - const bool UNUSED(use_dupref_dst), + const bool /*use_dupref_dst*/, const int tolayers, const bool *use_layers_src, const int num_layers_src) @@ -1231,7 +1227,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map, const int tot_dst = BLI_listbase_count(dst_defbase); - const size_t elem_size = sizeof(*((MDeformVert *)NULL)); + const size_t elem_size = sizeof(*((MDeformVert *)nullptr)); switch (tolayers) { case DT_LAYERS_INDEX_DST: @@ -1258,15 +1254,15 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map, } else if (use_delete && idx_dst > idx_src) { while (idx_dst-- > idx_src) { - BKE_object_defgroup_remove(ob_dst, dst_defbase->last); + BKE_object_defgroup_remove(ob_dst, static_cast(dst_defbase->last)); } } if (r_map) { /* At this stage, we **need** a valid CD_MDEFORMVERT layer on dest! * Again, use_create is not relevant in this case */ if (!data_dst) { - data_dst = CustomData_add_layer( - cd_dst, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, num_elem_dst); + data_dst = static_cast( + CustomData_add_layer(cd_dst, CD_MDEFORMVERT, CD_SET_DEFAULT, nullptr, num_elem_dst)); } while (idx_src--) { @@ -1287,7 +1283,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map, 0, 0, vgroups_datatransfer_interp, - NULL); + nullptr); } } break; @@ -1296,7 +1292,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map, if (use_delete) { /* Remove all unused dst vgroups first, simpler in this case. */ - for (dg_dst = dst_defbase->first; dg_dst;) { + for (dg_dst = static_cast(dst_defbase->first); dg_dst;) { bDeformGroup *dg_dst_next = dg_dst->next; if (BKE_object_defgroup_name_index(ob_src, dg_dst->name) == -1) { @@ -1306,7 +1302,8 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map, } } - for (idx_src = 0, dg_src = src_list->first; idx_src < num_layers_src; + for (idx_src = 0, dg_src = static_cast(src_list->first); + idx_src < num_layers_src; idx_src++, dg_src = dg_src->next) { if (!use_layers_src[idx_src]) { continue; @@ -1326,8 +1323,8 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map, /* At this stage, we **need** a valid CD_MDEFORMVERT layer on dest! * use_create is not relevant in this case */ if (!data_dst) { - data_dst = CustomData_add_layer( - cd_dst, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, num_elem_dst); + data_dst = static_cast(CustomData_add_layer( + cd_dst, CD_MDEFORMVERT, CD_SET_DEFAULT, nullptr, num_elem_dst)); } data_transfer_layersmapping_add_item(r_map, @@ -1344,7 +1341,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map, 0, 0, vgroups_datatransfer_interp, - NULL); + nullptr); } } break; @@ -1373,13 +1370,13 @@ bool data_transfer_layersmapping_vgroups(ListBase *r_map, { int idx_src, idx_dst; - const size_t elem_size = sizeof(*((MDeformVert *)NULL)); + const size_t elem_size = sizeof(*((MDeformVert *)nullptr)); /* NOTE: * VGroups are a bit hairy, since their layout is defined on object level (ob->defbase), * while their actual data is a (mesh) CD layer. - * This implies we may have to handle data layout itself while having NULL data itself, - * and even have to support NULL data_src in transfer data code + * This implies we may have to handle data layout itself while having nullptr data itself, + * and even have to support nullptr data_src in transfer data code * (we always create a data_dst, though). * * NOTE: Above comment is outdated, but this function was written when that was true. @@ -1393,12 +1390,15 @@ bool data_transfer_layersmapping_vgroups(ListBase *r_map, return true; } - const MDeformVert *data_src = CustomData_get_layer(cd_src, CD_MDEFORMVERT); + const MDeformVert *data_src = static_cast( + CustomData_get_layer(cd_src, CD_MDEFORMVERT)); - MDeformVert *data_dst = CustomData_get_layer_for_write(cd_dst, CD_MDEFORMVERT, num_elem_dst); + MDeformVert *data_dst = static_cast( + CustomData_get_layer_for_write(cd_dst, CD_MDEFORMVERT, num_elem_dst)); if (data_dst && use_dupref_dst && r_map) { /* If dest is a derivedmesh, we do not want to overwrite cdlayers of org mesh! */ - data_dst = CustomData_get_layer_for_write(cd_dst, CD_MDEFORMVERT, num_elem_dst); + data_dst = static_cast( + CustomData_get_layer_for_write(cd_dst, CD_MDEFORMVERT, num_elem_dst)); } if (fromlayers == DT_LAYERS_ACTIVE_SRC || fromlayers >= 0) { @@ -1430,7 +1430,7 @@ bool data_transfer_layersmapping_vgroups(ListBase *r_map, if (!use_create) { return true; } - dg_src = BLI_findlink(src_defbase, idx_src); + dg_src = static_cast(BLI_findlink(src_defbase, idx_src)); BKE_object_defgroup_add_name(ob_dst, dg_src->name); idx_dst = BKE_object_defgroup_active_index_get(ob_dst) - 1; } @@ -1449,7 +1449,7 @@ bool data_transfer_layersmapping_vgroups(ListBase *r_map, } } else if (tolayers == DT_LAYERS_NAME_DST) { - bDeformGroup *dg_src = BLI_findlink(src_defbase, idx_src); + bDeformGroup *dg_src = static_cast(BLI_findlink(src_defbase, idx_src)); if ((idx_dst = BKE_object_defgroup_name_index(ob_dst, dg_src->name)) == -1) { if (!use_create) { return true; @@ -1466,8 +1466,8 @@ bool data_transfer_layersmapping_vgroups(ListBase *r_map, /* At this stage, we **need** a valid CD_MDEFORMVERT layer on dest! * use_create is not relevant in this case */ if (!data_dst) { - data_dst = CustomData_add_layer( - cd_dst, CD_MDEFORMVERT, CD_SET_DEFAULT, NULL, num_elem_dst); + data_dst = static_cast( + CustomData_add_layer(cd_dst, CD_MDEFORMVERT, CD_SET_DEFAULT, nullptr, num_elem_dst)); } data_transfer_layersmapping_add_item(r_map, @@ -1484,12 +1484,12 @@ bool data_transfer_layersmapping_vgroups(ListBase *r_map, 0, 0, vgroups_datatransfer_interp, - NULL); + nullptr); } } else { int num_src, num_sel_unused; - bool *use_layers_src = NULL; + bool *use_layers_src = nullptr; bool ret = false; switch (fromlayers) { @@ -1588,7 +1588,7 @@ void BKE_defbase_blend_write(BlendWriter *writer, const ListBase *defbase) void BKE_defvert_blend_write(BlendWriter *writer, int count, const MDeformVert *dvlist) { - if (dvlist == NULL) { + if (dvlist == nullptr) { return; } @@ -1605,22 +1605,23 @@ void BKE_defvert_blend_write(BlendWriter *writer, int count, const MDeformVert * void BKE_defvert_blend_read(BlendDataReader *reader, int count, MDeformVert *mdverts) { - if (mdverts == NULL) { + if (mdverts == nullptr) { return; } for (int i = count; i > 0; i--, mdverts++) { /* Convert to vertex group allocation system. */ MDeformWeight *dw; - if (mdverts->dw && (dw = BLO_read_get_new_data_address(reader, mdverts->dw))) { + if (mdverts->dw && + (dw = static_cast(BLO_read_get_new_data_address(reader, mdverts->dw)))) { const size_t dw_len = sizeof(MDeformWeight) * mdverts->totweight; void *dw_tmp = MEM_mallocN(dw_len, __func__); memcpy(dw_tmp, dw, dw_len); - mdverts->dw = dw_tmp; + mdverts->dw = static_cast(dw_tmp); MEM_freeN(dw); } else { - mdverts->dw = NULL; + mdverts->dw = nullptr; mdverts->totweight = 0; } } diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index 040d67a60f4..f768652824e 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -34,8 +34,8 @@ set(INC_SYS set(SRC object_add.cc - object_bake.c - object_bake_api.c + object_bake.cc + object_bake_api.cc object_collection.c object_constraint.c object_data_transfer.c diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.cc similarity index 88% rename from source/blender/editors/object/object_bake.c rename to source/blender/editors/object/object_bake.cc index 46dd6132bbb..30805ff8ad2 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.cc @@ -5,7 +5,7 @@ * \ingroup edobj */ -#include +#include #include "MEM_guardedalloc.h" @@ -56,14 +56,15 @@ static Image *bake_object_image_get(Object *ob, int mat_nr) { - Image *image = NULL; - ED_object_get_active_image(ob, mat_nr + 1, &image, NULL, NULL, NULL); + Image *image = nullptr; + ED_object_get_active_image(ob, mat_nr + 1, &image, nullptr, nullptr, nullptr); return image; } static Image **bake_object_image_get_array(Object *ob) { - Image **image_array = MEM_mallocN(sizeof(Material *) * ob->totcol, __func__); + Image **image_array = static_cast( + MEM_mallocN(sizeof(Material *) * ob->totcol, __func__)); for (int i = 0; i < ob->totcol; i++) { image_array[i] = bake_object_image_get(ob, i); } @@ -74,8 +75,8 @@ static Image **bake_object_image_get_array(Object *ob) /* holder of per-object data needed for bake job * needed to make job totally thread-safe */ -typedef struct MultiresBakerJobData { - struct MultiresBakerJobData *next, *prev; +struct MultiresBakerJobData { + MultiresBakerJobData *next, *prev; /* material aligned image array (for per-face bake image) */ struct { Image **array; @@ -84,10 +85,10 @@ typedef struct MultiresBakerJobData { DerivedMesh *lores_dm, *hires_dm; int lvl, tot_lvl; ListBase images; -} MultiresBakerJobData; +}; /* data passing to multires-baker job */ -typedef struct { +struct MultiresBakeJob { Scene *scene; ListBase data; /** Clear the images before baking */ @@ -108,7 +109,7 @@ typedef struct { int threads; /** User scale used to scale displacement when baking derivative map. */ float user_scale; -} MultiresBakeJob; +}; static bool multiresbake_check(bContext *C, wmOperator *op) { @@ -178,7 +179,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op) BKE_imageuser_default(&iuser); iuser.tile = tile->tile_number; - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, nullptr); if (!ibuf) { BKE_report( @@ -187,7 +188,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op) ok = false; } else { - if (ibuf->rect == NULL && ibuf->rect_float == NULL) { + if (ibuf->rect == nullptr && ibuf->rect_float == nullptr) { ok = false; } @@ -200,7 +201,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op) } } - BKE_image_release_ibuf(ima, ibuf, NULL); + BKE_image_release_ibuf(ima, ibuf, nullptr); } } } @@ -234,7 +235,7 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l DM_set_only_copy(cddm, &CD_MASK_BAREMESH); tmp_mmd.lvl = mmd->lvl; tmp_mmd.sculptlvl = mmd->lvl; - dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, 0); + dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, MultiresFlags(0)); cddm->release(cddm); @@ -261,7 +262,7 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l tmp_mmd.lvl = mmd->totlvl; tmp_mmd.sculptlvl = mmd->totlvl; - dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, 0); + dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, MultiresFlags(0)); cddm->release(cddm); return dm; @@ -287,7 +288,7 @@ static void clear_single_image(Image *image, ClearFlag flag) BKE_imageuser_default(&iuser); iuser.tile = tile->tile_number; - ImBuf *ibuf = BKE_image_acquire_ibuf(image, &iuser, NULL); + ImBuf *ibuf = BKE_image_acquire_ibuf(image, &iuser, nullptr); if (flag == CLEAR_TANGENT_NORMAL) { IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid); @@ -301,7 +302,7 @@ static void clear_single_image(Image *image, ClearFlag flag) image->id.tag |= LIB_TAG_DOIT; - BKE_image_release_ibuf(image, ibuf, NULL); + BKE_image_release_ibuf(image, ibuf, nullptr); } } } @@ -342,7 +343,7 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) if (scene->r.bake_flag & R_BAKE_CLEAR) { /* clear images */ CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { - ClearFlag clear_flag = 0; + ClearFlag clear_flag = ClearFlag(0); ob = base->object; // me = (Mesh *)ob->data; @@ -364,7 +365,7 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) } CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { - MultiresBakeRender bkr = {NULL}; + MultiresBakeRender bkr = {nullptr}; ob = base->object; @@ -439,14 +440,13 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) // bkj->reports = op->reports; CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { - MultiresBakerJobData *data; int lvl; ob = base->object; multires_flush_sculpt_updates(ob); - data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data"); + MultiresBakerJobData *data = MEM_cnew(__func__); data->ob_image.array = bake_object_image_get_array(ob); data->ob_image.len = ob->totcol; @@ -464,14 +464,14 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) static void multiresbake_startjob(void *bkv, bool *stop, bool *do_update, float *progress) { MultiresBakerJobData *data; - MultiresBakeJob *bkj = bkv; + MultiresBakeJob *bkj = static_cast(bkv); int baked_objects = 0, tot_obj; tot_obj = BLI_listbase_count(&bkj->data); if (bkj->bake_clear) { /* clear images */ - for (data = bkj->data.first; data; data = data->next) { - ClearFlag clear_flag = 0; + for (data = static_cast(bkj->data.first); data; data = data->next) { + ClearFlag clear_flag = ClearFlag(0); if (bkj->mode == RE_BAKE_NORMALS) { clear_flag = CLEAR_TANGENT_NORMAL; @@ -484,8 +484,8 @@ static void multiresbake_startjob(void *bkv, bool *stop, bool *do_update, float } } - for (data = bkj->data.first; data; data = data->next) { - MultiresBakeRender bkr = {NULL}; + for (data = static_cast(bkj->data.first); data; data = data->next) { + MultiresBakeRender bkr = {nullptr}; /* copy data stored in job descriptor */ bkr.scene = bkj->scene; @@ -526,18 +526,18 @@ static void multiresbake_startjob(void *bkv, bool *stop, bool *do_update, float static void multiresbake_freejob(void *bkv) { - MultiresBakeJob *bkj = bkv; + MultiresBakeJob *bkj = static_cast(bkv); MultiresBakerJobData *data, *next; LinkData *link; - data = bkj->data.first; + data = static_cast(bkj->data.first); while (data) { next = data->next; data->lores_dm->release(data->lores_dm); data->hires_dm->release(data->hires_dm); /* delete here, since this delete will be called from main thread */ - for (link = data->images.first; link; link = link->next) { + for (link = static_cast(data->images.first); link; link = link->next) { Image *ima = (Image *)link->data; BKE_image_partial_update_mark_full_update(ima); } @@ -556,14 +556,12 @@ static void multiresbake_freejob(void *bkv) static int multiresbake_image_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - MultiresBakeJob *bkr; - wmJob *wm_job; if (!multiresbake_check(C, op)) { return OPERATOR_CANCELLED; } - bkr = MEM_callocN(sizeof(MultiresBakeJob), "MultiresBakeJob data"); + MultiresBakeJob *bkr = MEM_cnew(__func__); init_multiresbake_job(C, bkr); if (!bkr->data.first) { @@ -572,15 +570,15 @@ static int multiresbake_image_exec(bContext *C, wmOperator *op) } /* setup job */ - wm_job = WM_jobs_get(CTX_wm_manager(C), - CTX_wm_window(C), - scene, - "Multires Bake", - WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, - WM_JOB_TYPE_OBJECT_BAKE_TEXTURE); + wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C), + CTX_wm_window(C), + scene, + "Multires Bake", + WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, + WM_JOB_TYPE_OBJECT_BAKE_TEXTURE); WM_jobs_customdata_set(wm_job, bkr, multiresbake_freejob); WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO: only draw bake image, can we enforce this. */ - WM_jobs_callbacks(wm_job, multiresbake_startjob, NULL, NULL, NULL); + WM_jobs_callbacks(wm_job, multiresbake_startjob, nullptr, nullptr, nullptr); G.is_break = false; @@ -596,7 +594,7 @@ static int multiresbake_image_exec(bContext *C, wmOperator *op) /* ****************** render BAKING ********************** */ /** Catch escape key to cancel. */ -static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) +static int objects_bake_render_modal(bContext *C, wmOperator * /*op*/, const wmEvent *event) { /* no running blender, remove handler and pass through */ if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_BAKE_TEXTURE)) { @@ -620,7 +618,7 @@ static bool is_multires_bake(Scene *scene) return 0; } -static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(_event)) +static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { Scene *scene = CTX_data_scene(C); int result = OPERATOR_CANCELLED; diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.cc similarity index 90% rename from source/blender/editors/object/object_bake_api.c rename to source/blender/editors/object/object_bake_api.cc index 0b0e7eb55aa..453432cb1e7 100644 --- a/source/blender/editors/object/object_bake_api.c +++ b/source/blender/editors/object/object_bake_api.cc @@ -65,7 +65,7 @@ /* prototypes */ static void bake_set_props(wmOperator *op, Scene *scene); -typedef struct BakeAPIRender { +struct BakeAPIRender { /* Data to work on. */ Main *main; Scene *scene; @@ -113,13 +113,13 @@ typedef struct BakeAPIRender { ReportList *reports; int result; ScrArea *area; -} BakeAPIRender; +}; /* callbacks */ static void bake_progress_update(void *bjv, float progress) { - BakeAPIRender *bj = bjv; + BakeAPIRender *bj = static_cast(bjv); if (bj->progress && *bj->progress != progress) { *bj->progress = progress; @@ -130,7 +130,7 @@ static void bake_progress_update(void *bjv, float progress) } /** Catch escape key to cancel. */ -static int bake_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) +static int bake_modal(bContext *C, wmOperator * /*op*/, const wmEvent *event) { /* no running blender, remove handler and pass through */ if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_BAKE)) { @@ -151,7 +151,7 @@ static int bake_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) * for exec() when there is no render job * NOTE: this won't check for the escape key being pressed, but doing so isn't thread-safe. */ -static bool bake_break(void *UNUSED(rjv)) +static bool bake_break(void * /*rjv*/) { if (G.is_break) { return true; @@ -162,7 +162,7 @@ static bool bake_break(void *UNUSED(rjv)) static void bake_update_image(ScrArea *area, Image *image) { if (area && area->spacetype == SPACE_IMAGE) { /* in case the user changed while baking */ - SpaceImage *sima = area->spacedata.first; + SpaceImage *sima = static_cast(area->spacedata.first); if (sima) { sima->image = image; } @@ -186,7 +186,7 @@ static bool write_internal_bake_pixels(Image *image, ImBuf *ibuf; void *lock; bool is_float; - char *mask_buffer = NULL; + char *mask_buffer = nullptr; const size_t pixels_num = (size_t)width * (size_t)height; ImageUser iuser; @@ -199,11 +199,11 @@ static bool write_internal_bake_pixels(Image *image, } if (margin > 0 || !is_clear) { - mask_buffer = MEM_callocN(sizeof(char) * pixels_num, "Bake Mask"); + mask_buffer = static_cast(MEM_callocN(sizeof(char) * pixels_num, "Bake Mask")); RE_bake_mask_fill(pixel_array, pixels_num, mask_buffer); } - is_float = (ibuf->rect_float != NULL); + is_float = (ibuf->rect_float != nullptr); /* colormanagement conversions */ if (!is_noncolor) { @@ -296,7 +296,7 @@ static bool write_internal_bake_pixels(Image *image, imb_freemipmapImBuf(ibuf); } - BKE_image_release_ibuf(image, ibuf, NULL); + BKE_image_release_ibuf(image, ibuf, nullptr); if (mask_buffer) { MEM_freeN(mask_buffer); @@ -332,7 +332,7 @@ static bool write_external_bake_pixels(const char *filepath, char const *uv_layer, const float uv_offset[2]) { - ImBuf *ibuf = NULL; + ImBuf *ibuf = nullptr; bool ok = false; bool is_float; @@ -382,10 +382,10 @@ static bool write_external_bake_pixels(const char *filepath, /* margins */ if (margin > 0) { - char *mask_buffer = NULL; + char *mask_buffer = nullptr; const size_t pixels_num = (size_t)width * (size_t)height; - mask_buffer = MEM_callocN(sizeof(char) * pixels_num, "Bake Mask"); + mask_buffer = static_cast(MEM_callocN(sizeof(char) * pixels_num, "Bake Mask")); RE_bake_mask_fill(pixel_array, pixels_num, mask_buffer); RE_bake_margin(ibuf, mask_buffer, margin, margin_type, mesh_eval, uv_layer, uv_offset); @@ -429,7 +429,7 @@ static bool bake_object_check(const Scene *scene, BKE_view_layer_synced_ensure(scene, view_layer); Base *base = BKE_view_layer_base_find(view_layer, ob); - if (base == NULL) { + if (base == nullptr) { BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is not in view layer", ob->id.name + 2); return false; } @@ -468,11 +468,11 @@ static bool bake_object_check(const Scene *scene, } for (int i = 0; i < ob->totcol; i++) { - const bNodeTree *ntree = NULL; - const bNode *node = NULL; + const bNodeTree *ntree = nullptr; + const bNode *node = nullptr; const int mat_nr = i + 1; Image *image; - ED_object_get_active_image(ob, mat_nr, &image, NULL, &node, &ntree); + ED_object_get_active_image(ob, mat_nr, &image, nullptr, &node, &ntree); if (image) { @@ -514,7 +514,7 @@ static bool bake_object_check(const Scene *scene, } else { Material *mat = BKE_object_material_get(ob, mat_nr); - if (mat != NULL) { + if (mat != nullptr) { BKE_reportf(reports, RPT_INFO, "No active image found in material \"%s\" (%d) for object \"%s\"", @@ -614,7 +614,8 @@ static bool bake_objects_check(Main *bmain, return false; } - for (link = selected_objects->first; link; link = link->next) { + for (link = static_cast(selected_objects->first); link; + link = link->next) { Object *ob_iter = (Object *)link->ptr.data; if (ob_iter == ob) { @@ -643,8 +644,10 @@ static bool bake_objects_check(Main *bmain, return false; } - for (link = selected_objects->first; link; link = link->next) { - if (!bake_object_check(scene, view_layer, link->ptr.data, target, reports)) { + for (link = static_cast(selected_objects->first); link; + link = link->next) { + if (!bake_object_check( + scene, view_layer, static_cast(link->ptr.data), target, reports)) { return false; } } @@ -655,8 +658,7 @@ static bool bake_objects_check(Main *bmain, /* it needs to be called after bake_objects_check since the image tagging happens there */ static void bake_targets_clear(Main *bmain, const bool is_tangent) { - Image *image; - for (image = bmain->images.first; image; image = image->id.next) { + LISTBASE_FOREACH (Image *, image, &bmain->images) { if ((image->id.tag & LIB_TAG_DOIT) != 0) { RE_bake_ibuf_clear(image, is_tangent); } @@ -704,17 +706,17 @@ static bool bake_targets_init_image_textures(const BakeAPIRender *bkr, /* Allocate material mapping. */ targets->materials_num = materials_num; - targets->material_to_image = MEM_callocN(sizeof(Image *) * targets->materials_num, - "BakeTargets.material_to_image"); + targets->material_to_image = static_cast( + MEM_callocN(sizeof(Image *) * targets->materials_num, __func__)); /* Error handling and tag (in case multiple materials share the same image). */ BKE_main_id_tag_idcode(bkr->main, ID_IM, LIB_TAG_DOIT, false); - targets->images = NULL; + targets->images = nullptr; for (int i = 0; i < materials_num; i++) { Image *image; - ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL); + ED_object_get_active_image(ob, i + 1, &image, nullptr, nullptr, nullptr); targets->material_to_image[i] = image; @@ -723,8 +725,8 @@ static bool bake_targets_init_image_textures(const BakeAPIRender *bkr, if (image && !(image->id.tag & LIB_TAG_DOIT)) { LISTBASE_FOREACH (ImageTile *, tile, &image->tiles) { /* Add bake image. */ - targets->images = MEM_recallocN(targets->images, - sizeof(BakeImage) * (targets->images_num + 1)); + targets->images = static_cast( + MEM_recallocN(targets->images, sizeof(BakeImage) * (targets->images_num + 1))); targets->images[targets->images_num].image = image; targets->images[targets->images_num].tile_number = tile->tile_number; targets->images_num++; @@ -878,7 +880,7 @@ static bool bake_targets_output_external(const BakeAPIRender *bkr, bake->im_format.imtype, true, false, - NULL); + nullptr); if (bkr->is_automatic_name) { BLI_path_suffix(name, FILE_MAX, ob->id.name + 2, "_"); @@ -949,7 +951,7 @@ static bool bake_targets_init_vertex_colors(Main *bmain, return false; } - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); if (!BKE_id_attributes_color_find(&me->id, me->active_color_attribute)) { BKE_report(reports, RPT_ERROR, "No active color attribute to bake to"); return false; @@ -958,18 +960,18 @@ static bool bake_targets_init_vertex_colors(Main *bmain, /* Ensure mesh and editmesh topology are in sync. */ ED_object_editmode_load(bmain, ob); - targets->images = MEM_callocN(sizeof(BakeImage), "BakeTargets.images"); + targets->images = MEM_cnew(__func__); targets->images_num = 1; - targets->material_to_image = MEM_callocN(sizeof(int) * ob->totcol, - "BakeTargets.material_to_image"); + targets->material_to_image = static_cast( + MEM_callocN(sizeof(Image *) * ob->totcol, __func__)); targets->materials_num = ob->totcol; BakeImage *bk_image = &targets->images[0]; bk_image->width = me->totloop; bk_image->height = 1; bk_image->offset = 0; - bk_image->image = NULL; + bk_image->image = nullptr; targets->pixels_num = bk_image->width * bk_image->height; @@ -1009,7 +1011,7 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets, Mesh *me_eval, BakePixel *pixel_array) { - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); const int pixels_num = targets->pixels_num; /* Initialize blank pixels. */ @@ -1029,7 +1031,7 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets, /* Populate through adjacent triangles, first triangle wins. */ const int tottri = poly_to_tri_count(me_eval->totpoly, me_eval->totloop); - MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__); + MLoopTri *looptri = static_cast(MEM_mallocN(sizeof(*looptri) * tottri, __func__)); const MLoop *loops = BKE_mesh_loops(me_eval); BKE_mesh_recalc_looptri(loops, @@ -1040,8 +1042,10 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets, looptri); /* For mapping back to original mesh in case there are modifiers. */ - const int *vert_origindex = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX); - const int *poly_origindex = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX); + const int *vert_origindex = static_cast( + CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX)); + const int *poly_origindex = static_cast( + CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX)); const MPoly *orig_polys = BKE_mesh_polys(me); const MLoop *orig_loops = BKE_mesh_loops(me); @@ -1053,7 +1057,7 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets, uint v = loops[l].v; /* Map back to original loop if there are modifiers. */ - if (vert_origindex != NULL && poly_origindex != NULL) { + if (vert_origindex != nullptr && poly_origindex != nullptr) { l = find_original_loop( orig_polys, orig_loops, vert_origindex, poly_origindex, lt->poly, v); if (l == ORIGINDEX_NONE || l >= me->totloop) { @@ -1129,11 +1133,11 @@ static void convert_float_color_to_byte_color(const MPropCol *float_colors, static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) { - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); BMEditMesh *em = me->edit_mesh; CustomDataLayer *active_color_layer = BKE_id_attributes_color_find(&me->id, me->active_color_attribute); - BLI_assert(active_color_layer != NULL); + BLI_assert(active_color_layer != nullptr); const eAttrDomain domain = BKE_id_attribute_domain(&me->id, active_color_layer); const int channels_num = targets->channels_num; @@ -1144,10 +1148,12 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) const int totvert = me->totvert; const int totloop = me->totloop; - MPropCol *mcol = MEM_malloc_arrayN(totvert, sizeof(MPropCol), __func__); + MPropCol *mcol = static_cast( + MEM_malloc_arrayN(totvert, sizeof(MPropCol), __func__)); /* Accumulate float vertex colors in scene linear color space. */ - int *num_loops_for_vertex = MEM_callocN(sizeof(int) * me->totvert, "num_loops_for_vertex"); + int *num_loops_for_vertex = static_cast( + MEM_callocN(sizeof(int) * me->totvert, "num_loops_for_vertex")); memset(mcol, 0, sizeof(MPropCol) * me->totvert); const MLoop *mloop = BKE_mesh_loops(me); @@ -1177,7 +1183,8 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) memcpy(data, &mcol[i], sizeof(MPropCol)); } else { - convert_float_color_to_byte_color(&mcol[i], 1, is_noncolor, data); + convert_float_color_to_byte_color( + &mcol[i], 1, is_noncolor, static_cast(data)); } i++; } @@ -1188,7 +1195,8 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) memcpy(active_color_layer->data, mcol, sizeof(MPropCol) * me->totvert); } else { - convert_float_color_to_byte_color(mcol, totvert, is_noncolor, active_color_layer->data); + convert_float_color_to_byte_color( + mcol, totvert, is_noncolor, static_cast(active_color_layer->data)); } } @@ -1218,7 +1226,8 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) memcpy(data, &color, sizeof(MPropCol)); } else { - convert_float_color_to_byte_color(&color, 1, is_noncolor, data); + convert_float_color_to_byte_color( + &color, 1, is_noncolor, static_cast(data)); } } } @@ -1226,14 +1235,14 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob) else { /* Copy to mesh. */ if (active_color_layer->type == CD_PROP_COLOR) { - MPropCol *colors = active_color_layer->data; + MPropCol *colors = static_cast(active_color_layer->data); for (int i = 0; i < me->totloop; i++) { zero_v4(colors[i].color); bake_result_add_to_rgba(colors[i].color, &result[i * channels_num], channels_num); } } else { - MLoopCol *colors = active_color_layer->data; + MLoopCol *colors = static_cast(active_color_layer->data); for (int i = 0; i < me->totloop; i++) { MPropCol color; zero_v4(color.color); @@ -1281,8 +1290,8 @@ static bool bake_targets_init(const BakeAPIRender *bkr, targets->is_noncolor = is_noncolor_pass(bkr->pass_type); targets->channels_num = RE_pass_depth(bkr->pass_type); - targets->result = MEM_callocN(sizeof(float) * targets->channels_num * targets->pixels_num, - "bake return pixels"); + targets->result = static_cast(MEM_callocN( + sizeof(float) * targets->channels_num * targets->pixels_num, "bake return pixels")); return true; } @@ -1352,23 +1361,23 @@ static int bake(const BakeAPIRender *bkr, int op_result = OPERATOR_CANCELLED; bool ok = false; - Object *ob_cage = NULL; - Object *ob_cage_eval = NULL; - Object *ob_low_eval = NULL; + Object *ob_cage = nullptr; + Object *ob_cage_eval = nullptr; + Object *ob_low_eval = nullptr; - BakeHighPolyData *highpoly = NULL; + BakeHighPolyData *highpoly = nullptr; int tot_highpoly = 0; - Mesh *me_low_eval = NULL; - Mesh *me_cage_eval = NULL; + Mesh *me_low_eval = nullptr; + Mesh *me_cage_eval = nullptr; - MultiresModifierData *mmd_low = NULL; + MultiresModifierData *mmd_low = nullptr; int mmd_flags_low = 0; - BakePixel *pixel_array_low = NULL; - BakePixel *pixel_array_high = NULL; + BakePixel *pixel_array_low = nullptr; + BakePixel *pixel_array_high = nullptr; - BakeTargets targets = {NULL}; + BakeTargets targets = {nullptr}; const bool preserve_origindex = (bkr->target == R_BAKE_TARGET_VERTEX_COLORS); @@ -1395,8 +1404,9 @@ static int bake(const BakeAPIRender *bkr, CollectionPointerLink *link; tot_highpoly = 0; - for (link = selected_objects->first; link; link = link->next) { - Object *ob_iter = link->ptr.data; + for (link = static_cast(selected_objects->first); link; + link = link->next) { + Object *ob_iter = static_cast(link->ptr.data); if (ob_iter == ob_low) { continue; @@ -1406,9 +1416,10 @@ static int bake(const BakeAPIRender *bkr, } if (bkr->is_cage && bkr->custom_cage[0] != '\0') { - ob_cage = BLI_findstring(&bmain->objects, bkr->custom_cage, offsetof(ID, name) + 2); + ob_cage = static_cast( + BLI_findstring(&bmain->objects, bkr->custom_cage, offsetof(ID, name) + 2)); - if (ob_cage == NULL || ob_cage->type != OB_MESH) { + if (ob_cage == nullptr || ob_cage->type != OB_MESH) { BKE_report(reports, RPT_ERROR, "No valid cage object"); goto cleanup; } @@ -1445,8 +1456,9 @@ static int bake(const BakeAPIRender *bkr, /* Populate the pixel array with the face data. Except if we use a cage, then * it is populated later with the cage mesh (smoothed version of the mesh). */ - pixel_array_low = MEM_mallocN(sizeof(BakePixel) * targets.pixels_num, "bake pixels low poly"); - if ((bkr->is_selected_to_active && (ob_cage == NULL) && bkr->is_cage) == false) { + pixel_array_low = static_cast( + MEM_mallocN(sizeof(BakePixel) * targets.pixels_num, "bake pixels low poly")); + if ((bkr->is_selected_to_active && (ob_cage == nullptr) && bkr->is_cage) == false) { bake_targets_populate_pixels(bkr, &targets, ob_low, me_low_eval, pixel_array_low); } @@ -1469,7 +1481,7 @@ static int bake(const BakeAPIRender *bkr, else if (bkr->is_cage) { bool is_changed = false; - ModifierData *md = ob_low_eval->modifiers.first; + ModifierData *md = static_cast(ob_low_eval->modifiers.first); while (md) { ModifierData *md_next = md->next; @@ -1498,15 +1510,17 @@ static int bake(const BakeAPIRender *bkr, BKE_object_handle_data_update(depsgraph, scene, ob_low_eval); } - me_cage_eval = BKE_mesh_new_from_object(NULL, ob_low_eval, false, preserve_origindex); + me_cage_eval = BKE_mesh_new_from_object(nullptr, ob_low_eval, false, preserve_origindex); bake_targets_populate_pixels(bkr, &targets, ob_low, me_cage_eval, pixel_array_low); } - highpoly = MEM_callocN(sizeof(BakeHighPolyData) * tot_highpoly, "bake high poly objects"); + highpoly = static_cast( + MEM_callocN(sizeof(BakeHighPolyData) * tot_highpoly, "bake high poly objects")); /* populate highpoly array */ - for (link = selected_objects->first; link; link = link->next) { - Object *ob_iter = link->ptr.data; + for (link = static_cast(selected_objects->first); link; + link = link->next) { + Object *ob_iter = static_cast(link->ptr.data); if (ob_iter == ob_low) { continue; @@ -1518,7 +1532,7 @@ static int bake(const BakeAPIRender *bkr, highpoly[i].ob_eval->visibility_flag &= ~OB_HIDE_RENDER; highpoly[i].ob_eval->base_flag |= (BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT | BASE_ENABLED_RENDER); - highpoly[i].me = BKE_mesh_new_from_object(NULL, highpoly[i].ob_eval, false, false); + highpoly[i].me = BKE_mesh_new_from_object(nullptr, highpoly[i].ob_eval, false, false); /* Low-poly to high-poly transformation matrix. */ copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->object_to_world); @@ -1531,7 +1545,7 @@ static int bake(const BakeAPIRender *bkr, BLI_assert(i == tot_highpoly); - if (ob_cage != NULL) { + if (ob_cage != nullptr) { ob_cage_eval->visibility_flag |= OB_HIDE_RENDER; ob_cage_eval->base_flag &= ~(BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT | BASE_ENABLED_RENDER); @@ -1540,8 +1554,8 @@ static int bake(const BakeAPIRender *bkr, ob_low_eval->base_flag &= ~(BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT | BASE_ENABLED_RENDER); /* populate the pixel arrays with the corresponding face data for each high poly object */ - pixel_array_high = MEM_mallocN(sizeof(BakePixel) * targets.pixels_num, - "bake pixels high poly"); + pixel_array_high = static_cast( + MEM_mallocN(sizeof(BakePixel) * targets.pixels_num, "bake pixels high poly")); if (!RE_bake_pixels_populate_from_objects( me_low_eval, @@ -1550,7 +1564,7 @@ static int bake(const BakeAPIRender *bkr, highpoly, tot_highpoly, targets.pixels_num, - ob_cage != NULL, + ob_cage != nullptr, bkr->cage_extrusion, bkr->max_ray_distance, ob_low_eval->object_to_world, @@ -1637,8 +1651,8 @@ static int bake(const BakeAPIRender *bkr, } else { /* From multi-resolution. */ - Mesh *me_nores = NULL; - ModifierData *md = NULL; + Mesh *me_nores = nullptr; + ModifierData *md = nullptr; int mode; BKE_object_eval_reset(ob_low_eval); @@ -1649,7 +1663,7 @@ static int bake(const BakeAPIRender *bkr, md->mode &= ~eModifierMode_Render; /* Evaluate modifiers again. */ - me_nores = BKE_mesh_new_from_object(NULL, ob_low_eval, false, false); + me_nores = BKE_mesh_new_from_object(nullptr, ob_low_eval, false, false); bake_targets_populate_pixels(bkr, &targets, ob_low, me_nores, pixel_array_low); } @@ -1662,7 +1676,7 @@ static int bake(const BakeAPIRender *bkr, ob_low_eval->object_to_world); if (md) { - BKE_id_free(NULL, &me_nores->id); + BKE_id_free(nullptr, &me_nores->id); md->mode = mode; } } @@ -1694,8 +1708,8 @@ cleanup: if (highpoly) { for (int i = 0; i < tot_highpoly; i++) { - if (highpoly[i].me != NULL) { - BKE_id_free(NULL, &highpoly[i].me->id); + if (highpoly[i].me != nullptr) { + BKE_id_free(nullptr, &highpoly[i].me->id); } } MEM_freeN(highpoly); @@ -1715,12 +1729,12 @@ cleanup: bake_targets_free(&targets); - if (me_low_eval != NULL) { - BKE_id_free(NULL, &me_low_eval->id); + if (me_low_eval != nullptr) { + BKE_id_free(nullptr, &me_low_eval->id); } - if (me_cage_eval != NULL) { - BKE_id_free(NULL, &me_cage_eval->id); + if (me_cage_eval != nullptr) { + BKE_id_free(nullptr, &me_cage_eval->id); } DEG_graph_free(depsgraph); @@ -1738,12 +1752,12 @@ static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr) bkr->main = CTX_data_main(C); bkr->view_layer = CTX_data_view_layer(C); bkr->scene = CTX_data_scene(C); - bkr->area = screen ? BKE_screen_find_big_area(screen, SPACE_IMAGE, 10) : NULL; + bkr->area = screen ? BKE_screen_find_big_area(screen, SPACE_IMAGE, 10) : nullptr; - bkr->pass_type = RNA_enum_get(op->ptr, "type"); + bkr->pass_type = eScenePassType(RNA_enum_get(op->ptr, "type")); bkr->pass_filter = RNA_enum_get(op->ptr, "pass_filter"); bkr->margin = RNA_int_get(op->ptr, "margin"); - bkr->margin_type = RNA_enum_get(op->ptr, "margin_type"); + bkr->margin_type = eBakeMarginType(RNA_enum_get(op->ptr, "margin_type")); bkr->save_mode = (eBakeSaveMode)RNA_enum_get(op->ptr, "save_mode"); bkr->target = (eBakeTarget)RNA_enum_get(op->ptr, "target"); @@ -1759,9 +1773,9 @@ static void bake_init_api_data(wmOperator *op, bContext *C, BakeAPIRender *bkr) bkr->max_ray_distance = RNA_float_get(op->ptr, "max_ray_distance"); bkr->normal_space = RNA_enum_get(op->ptr, "normal_space"); - bkr->normal_swizzle[0] = RNA_enum_get(op->ptr, "normal_r"); - bkr->normal_swizzle[1] = RNA_enum_get(op->ptr, "normal_g"); - bkr->normal_swizzle[2] = RNA_enum_get(op->ptr, "normal_b"); + bkr->normal_swizzle[0] = eBakeNormalSwizzle(RNA_enum_get(op->ptr, "normal_r")); + bkr->normal_swizzle[1] = eBakeNormalSwizzle(RNA_enum_get(op->ptr, "normal_g")); + bkr->normal_swizzle[2] = eBakeNormalSwizzle(RNA_enum_get(op->ptr, "normal_b")); bkr->width = RNA_int_get(op->ptr, "width"); bkr->height = RNA_int_get(op->ptr, "height"); @@ -1800,7 +1814,7 @@ static int bake_exec(bContext *C, wmOperator *op) { Render *re; int result = OPERATOR_CANCELLED; - BakeAPIRender bkr = {NULL}; + BakeAPIRender bkr = {nullptr}; Scene *scene = CTX_data_scene(C); G.is_break = false; @@ -1812,7 +1826,7 @@ static int bake_exec(bContext *C, wmOperator *op) re = bkr.render; /* setup new render */ - RE_test_break_cb(re, NULL, bake_break); + RE_test_break_cb(re, nullptr, bake_break); if (!bake_pass_filter_check(bkr.pass_type, bkr.pass_filter, bkr.reports)) { goto finally; @@ -1843,13 +1857,14 @@ static int bake_exec(bContext *C, wmOperator *op) else { CollectionPointerLink *link; bkr.is_clear = bkr.is_clear && BLI_listbase_is_single(&bkr.selected_objects); - for (link = bkr.selected_objects.first; link; link = link->next) { - Object *ob_iter = link->ptr.data; - result = bake(&bkr, ob_iter, NULL, bkr.reports); + for (link = static_cast(bkr.selected_objects.first); link; + link = link->next) { + Object *ob_iter = static_cast(link->ptr.data); + result = bake(&bkr, ob_iter, nullptr, bkr.reports); } } - RE_SetReports(re, NULL); + RE_SetReports(re, nullptr); finally: G.is_rendering = false; @@ -1857,7 +1872,7 @@ finally: return result; } -static void bake_startjob(void *bkv, bool *UNUSED(stop), bool *do_update, float *progress) +static void bake_startjob(void *bkv, bool * /*stop*/, bool *do_update, float *progress) { BakeAPIRender *bkr = (BakeAPIRender *)bkv; @@ -1896,9 +1911,10 @@ static void bake_startjob(void *bkv, bool *UNUSED(stop), bool *do_update, float else { CollectionPointerLink *link; bkr->is_clear = bkr->is_clear && BLI_listbase_is_single(&bkr->selected_objects); - for (link = bkr->selected_objects.first; link; link = link->next) { - Object *ob_iter = link->ptr.data; - bkr->result = bake(bkr, ob_iter, NULL, bkr->reports); + for (link = static_cast(bkr->selected_objects.first); link; + link = link->next) { + Object *ob_iter = static_cast(link->ptr.data); + bkr->result = bake(bkr, ob_iter, nullptr, bkr->reports); if (bkr->result == OPERATOR_CANCELLED) { return; @@ -1906,7 +1922,7 @@ static void bake_startjob(void *bkv, bool *UNUSED(stop), bool *do_update, float } } - RE_SetReports(bkr->render, NULL); + RE_SetReports(bkr->render, nullptr); } static void bake_job_complete(void *bkv) @@ -2037,10 +2053,9 @@ static void bake_set_props(wmOperator *op, Scene *scene) } } -static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int bake_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { wmJob *wm_job; - BakeAPIRender *bkr; Render *re; Scene *scene = CTX_data_scene(C); @@ -2051,7 +2066,7 @@ static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event) return OPERATOR_CANCELLED; } - bkr = MEM_mallocN(sizeof(BakeAPIRender), "render bake"); + BakeAPIRender *bkr = static_cast(MEM_mallocN(sizeof(BakeAPIRender), __func__)); /* init bake render */ bake_init_api_data(op, C, bkr); @@ -2059,7 +2074,7 @@ static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event) re = bkr->render; /* setup new render */ - RE_test_break_cb(re, NULL, bake_break); + RE_test_break_cb(re, nullptr, bake_break); RE_progress_cb(re, bkr, bake_progress_update); /* setup job */ @@ -2074,7 +2089,7 @@ static int bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event) WM_jobs_timer( wm_job, 0.5, (bkr->target == R_BAKE_TARGET_VERTEX_COLORS) ? NC_GEOM | ND_DATA : NC_IMAGE, 0); WM_jobs_callbacks_ex( - wm_job, bake_startjob, NULL, NULL, NULL, bake_job_complete, bake_job_canceled); + wm_job, bake_startjob, nullptr, nullptr, nullptr, bake_job_complete, bake_job_canceled); G.is_break = false; G.is_rendering = true; @@ -2121,7 +2136,7 @@ void OBJECT_OT_bake(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_ENUM_FLAG); RNA_def_string_file_path(ot->srna, "filepath", - NULL, + nullptr, FILE_MAX, "File Path", "Image filepath to use when saving externally"); @@ -2185,7 +2200,7 @@ void OBJECT_OT_bake(wmOperatorType *ot) 1.0f); RNA_def_string(ot->srna, "cage_object", - NULL, + nullptr, MAX_NAME, "Cage Object", "Object to use as cage, instead of calculating the cage from the active object " @@ -2245,7 +2260,7 @@ void OBJECT_OT_bake(wmOperatorType *ot) "Automatically name the output file with the pass type"); RNA_def_string(ot->srna, "uv_layer", - NULL, + nullptr, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX, "UV Layer", "UV layer to override active"); diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 78eec9b9dfa..a3b4e670795 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -29,7 +29,7 @@ set(INC_SYS ) set(SRC - drawobject.c + drawobject.cc space_view3d.cc view3d_buttons.c view3d_camera_control.c diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.cc similarity index 78% rename from source/blender/editors/space_view3d/drawobject.c rename to source/blender/editors/space_view3d/drawobject.cc index f19464e4e1e..94e2c94227b 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.cc @@ -53,11 +53,11 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, return; } - const Mesh *me = ob->data; + const Mesh *me = static_cast(ob->data); { Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval); - if (me_eval != NULL) { + if (me_eval != nullptr) { me = me_eval; } } @@ -65,7 +65,7 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, GPU_front_facing(ob->transflag & OB_NEG_SCALE); /* Just to create the data to pass to immediate mode! (sigh) */ - const int *facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP); + const int *facemap_data = static_cast(CustomData_get_layer(&me->pdata, CD_FACEMAP)); if (facemap_data) { GPU_blend(GPU_BLEND_ALPHA); @@ -76,7 +76,7 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, int mpoly_len = me->totpoly; int mloop_len = me->totloop; - facemap_data = CustomData_get_layer(&me->pdata, CD_FACEMAP); + facemap_data = static_cast(CustomData_get_layer(&me->pdata, CD_FACEMAP)); /* Make a batch and free it each time for now. */ const int looptris_len = poly_to_tri_count(mpoly_len, mloop_len); @@ -100,9 +100,12 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, for (mp = polys, i = 0; i < mpoly_len; i++, mp++) { if (facemap_data[i] == facemap) { for (int j = 2; j < mp->totloop; j++) { - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), positions[loops[mlt->tri[0]].v]); - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), positions[loops[mlt->tri[1]].v]); - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), positions[loops[mlt->tri[2]].v]); + copy_v3_v3(static_cast(GPU_vertbuf_raw_step(&pos_step)), + positions[loops[mlt->tri[0]].v]); + copy_v3_v3(static_cast(GPU_vertbuf_raw_step(&pos_step)), + positions[loops[mlt->tri[1]].v]); + copy_v3_v3(static_cast(GPU_vertbuf_raw_step(&pos_step)), + positions[loops[mlt->tri[2]].v]); vbo_len_used += 3; mlt++; } @@ -120,9 +123,10 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, const MLoop *ml_a = ml_start + 1; const MLoop *ml_b = ml_start + 2; for (int j = 2; j < mp->totloop; j++) { - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), positions[ml_start->v]); - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), positions[ml_a->v]); - copy_v3_v3(GPU_vertbuf_raw_step(&pos_step), positions[ml_b->v]); + copy_v3_v3(static_cast(GPU_vertbuf_raw_step(&pos_step)), + positions[ml_start->v]); + copy_v3_v3(static_cast(GPU_vertbuf_raw_step(&pos_step)), positions[ml_a->v]); + copy_v3_v3(static_cast(GPU_vertbuf_raw_step(&pos_step)), positions[ml_b->v]); vbo_len_used += 3; ml_a++; @@ -136,7 +140,7 @@ void ED_draw_object_facemap(Depsgraph *depsgraph, GPU_vertbuf_data_resize(vbo_pos, vbo_len_used); } - GPUBatch *draw_batch = GPU_batch_create(GPU_PRIM_TRIS, vbo_pos, NULL); + GPUBatch *draw_batch = GPU_batch_create(GPU_PRIM_TRIS, vbo_pos, nullptr); GPU_batch_program_set_builtin(draw_batch, GPU_SHADER_3D_UNIFORM_COLOR); GPU_batch_uniform_4fv(draw_batch, "color", col); GPU_batch_draw(draw_batch); diff --git a/source/blender/editors/uvedit/CMakeLists.txt b/source/blender/editors/uvedit/CMakeLists.txt index d2bc0018c25..ed3f165026d 100644 --- a/source/blender/editors/uvedit/CMakeLists.txt +++ b/source/blender/editors/uvedit/CMakeLists.txt @@ -32,7 +32,7 @@ set(SRC uvedit_rip.c uvedit_select.c uvedit_smart_stitch.c - uvedit_unwrap_ops.c + uvedit_unwrap_ops.cc uvedit_clipboard_graph_iso.hh uvedit_intern.h diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc similarity index 86% rename from source/blender/editors/uvedit/uvedit_unwrap_ops.c rename to source/blender/editors/uvedit/uvedit_unwrap_ops.cc index 8cd4445d0ff..7a99fec413c 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc @@ -5,9 +5,9 @@ * \ingroup eduv */ -#include -#include -#include +#include +#include +#include #include "MEM_guardedalloc.h" @@ -18,8 +18,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "BLI_alloca.h" -#include "BLI_array.h" +#include "BLI_array.hh" #include "BLI_linklist.h" #include "BLI_listbase.h" #include "BLI_math.h" @@ -27,6 +26,7 @@ #include "BLI_string.h" #include "BLI_utildefines.h" #include "BLI_uvproject.h" +#include "BLI_vector.hh" #include "BLT_translation.h" @@ -77,7 +77,7 @@ static void modifier_unwrap_state(Object *obedit, const Scene *scene, bool *r_us ModifierData *md; bool subsurf = (scene->toolsettings->uvcalc_flag & UVCALC_USESUBSURF) != 0; - md = obedit->modifiers.first; + md = static_cast(obedit->modifiers.first); /* subsurf will take the modifier settings only if modifier is first or right after mirror */ if (subsurf) { @@ -103,7 +103,7 @@ static bool ED_uvedit_ensure_uvs(Object *obedit) BMIter iter; if (em && em->bm->totface && !CustomData_has_layer(&em->bm->ldata, CD_PROP_FLOAT2)) { - ED_mesh_uv_add(obedit->data, NULL, true, true, NULL); + ED_mesh_uv_add(static_cast(obedit->data), nullptr, true, true, nullptr); } /* Happens when there are no faces. */ @@ -137,7 +137,7 @@ static bool ED_uvedit_ensure_uvs(Object *obedit) * \{ */ static void ED_uvedit_udim_params_from_image_space(const SpaceImage *sima, - struct UVPackIsland_Params *r_params) + UVPackIsland_Params *r_params) { if (!sima) { return; /* Nothing to do. */ @@ -147,7 +147,8 @@ static void ED_uvedit_udim_params_from_image_space(const SpaceImage *sima, * the tiled image is considered. */ const Image *image = sima->image; if (image && image->source == IMA_SRC_TILED) { - ImageTile *active_tile = BLI_findlink(&image->tiles, image->active_tile_index); + ImageTile *active_tile = static_cast( + BLI_findlink(&image->tiles, image->active_tile_index)); if (active_tile) { r_params->udim_base_offset[0] = (active_tile->tile_number - 1001) % 10; r_params->udim_base_offset[1] = (active_tile->tile_number - 1001) / 10; @@ -168,7 +169,7 @@ static void ED_uvedit_udim_params_from_image_space(const SpaceImage *sima, /** \name Parametrizer Conversion * \{ */ -typedef struct UnwrapOptions { +struct UnwrapOptions { /** Connectivity based on UV coordinates instead of seams. */ bool topology_from_uvs; /** Also use seams as well as UV coordinates (only valid when `topology_from_uvs` is enabled). */ @@ -187,12 +188,12 @@ typedef struct UnwrapOptions { bool correct_aspect; /** Treat unselected uvs as if they were pinned. */ bool pin_unselected; -} UnwrapOptions; +}; -typedef struct UnwrapResultInfo { +struct UnwrapResultInfo { int count_changed; int count_failed; -} UnwrapResultInfo; +}; static bool uvedit_have_selection(const Scene *scene, BMEditMesh *em, const UnwrapOptions *options) { @@ -261,14 +262,14 @@ void ED_uvedit_get_aspect_from_material(Object *ob, return; } Image *ima; - ED_object_get_active_image(ob, material_index + 1, &ima, NULL, NULL, NULL); - ED_image_get_uv_aspect(ima, NULL, r_aspx, r_aspy); + ED_object_get_active_image(ob, material_index + 1, &ima, nullptr, nullptr, nullptr); + ED_image_get_uv_aspect(ima, nullptr, r_aspx, r_aspy); } void ED_uvedit_get_aspect(Object *ob, float *r_aspx, float *r_aspy) { BMEditMesh *em = BKE_editmesh_from_object(ob); - BLI_assert(em != NULL); + BLI_assert(em != nullptr); bool sloppy = true; bool selected = false; BMFace *efa = BM_mesh_active_face_get(em->bm, sloppy, selected); @@ -345,11 +346,11 @@ static void construct_param_handle_face_add(ParamHandle *handle, const UnwrapOptions *options, const BMUVOffsets offsets) { - ParamKey *vkeys = BLI_array_alloca(vkeys, efa->len); - bool *pin = BLI_array_alloca(pin, efa->len); - bool *select = BLI_array_alloca(select, efa->len); - const float **co = BLI_array_alloca(co, efa->len); - float **uv = BLI_array_alloca(uv, efa->len); + blender::Array vkeys(efa->len); + blender::Array pin(efa->len); + blender::Array select(efa->len); + blender::Array co(efa->len); + blender::Array uv(efa->len); int i; BMIter liter; @@ -370,7 +371,8 @@ static void construct_param_handle_face_add(ParamHandle *handle, } } - GEO_uv_parametrizer_face_add(handle, face_index, i, vkeys, co, uv, pin, select); + GEO_uv_parametrizer_face_add( + handle, face_index, i, vkeys.data(), co.data(), uv.data(), pin.data(), select.data()); } /* Set seams on UV Parametrizer based on options. */ @@ -458,7 +460,7 @@ static ParamHandle *construct_param_handle(const Scene *scene, GEO_uv_parametrizer_construct_end(handle, options->fill_holes, options->topology_from_uvs, - result_info ? &result_info->count_failed : NULL); + result_info ? &result_info->count_failed : nullptr); return handle; } @@ -520,7 +522,8 @@ static ParamHandle *construct_param_handle_multi(const Scene *scene, offset += bm->totface; } - GEO_uv_parametrizer_construct_end(handle, options->fill_holes, options->topology_from_uvs, NULL); + GEO_uv_parametrizer_construct_end( + handle, options->fill_holes, options->topology_from_uvs, nullptr); return handle; } @@ -536,7 +539,7 @@ static void texface_from_original_index(const Scene *scene, BMLoop *l; BMIter liter; - *r_uv = NULL; + *r_uv = nullptr; *r_pin = 0; *r_select = 1; @@ -559,7 +562,8 @@ static Mesh *subdivide_edit_mesh(const Object *object, const BMEditMesh *em, const SubsurfModifierData *smd) { - Mesh *me_from_em = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL, object->data); + Mesh *me_from_em = BKE_mesh_from_bmesh_for_eval_nomain( + em->bm, nullptr, static_cast(object->data)); BKE_mesh_ensure_default_orig_index_customdata(me_from_em); SubdivSettings settings = BKE_subsurf_modifier_settings_init(smd, false); @@ -571,9 +575,9 @@ static Mesh *subdivide_edit_mesh(const Object *object, mesh_settings.resolution = (1 << smd->levels) + 1; mesh_settings.use_optimal_display = (smd->flags & eSubsurfModifierFlag_ControlEdges); - Subdiv *subdiv = BKE_subdiv_update_from_mesh(NULL, &settings, me_from_em); + Subdiv *subdiv = BKE_subdiv_update_from_mesh(nullptr, &settings, me_from_em); Mesh *result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, me_from_em); - BKE_id_free(NULL, me_from_em); + BKE_id_free(nullptr, me_from_em); BKE_subdiv_free(subdiv); return result; } @@ -590,10 +594,9 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, UnwrapResultInfo *result_info) { /* pointers to modifier data for unwrap control */ - ModifierData *md; SubsurfModifierData *smd_real; /* Modifier initialization data, will control what type of subdivision will happen. */ - SubsurfModifierData smd = {{NULL}}; + SubsurfModifierData smd = {{nullptr}}; /* Holds a map to edit-faces for every subdivision-surface polygon. * These will be used to get hidden/ selected flags etc. */ @@ -616,7 +619,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, } /* number of subdivisions to perform */ - md = ob->modifiers.first; + ModifierData *md = static_cast(ob->modifiers.first); smd_real = (SubsurfModifierData *)md; smd.levels = smd_real->levels; @@ -631,11 +634,15 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, const MPoly *subsurfedPolys = BKE_mesh_polys(subdiv_mesh); const MLoop *subsurfedLoops = BKE_mesh_loops(subdiv_mesh); - const int *origVertIndices = CustomData_get_layer(&subdiv_mesh->vdata, CD_ORIGINDEX); - const int *origEdgeIndices = CustomData_get_layer(&subdiv_mesh->edata, CD_ORIGINDEX); - const int *origPolyIndices = CustomData_get_layer(&subdiv_mesh->pdata, CD_ORIGINDEX); + const int *origVertIndices = static_cast( + CustomData_get_layer(&subdiv_mesh->vdata, CD_ORIGINDEX)); + const int *origEdgeIndices = static_cast( + CustomData_get_layer(&subdiv_mesh->edata, CD_ORIGINDEX)); + const int *origPolyIndices = static_cast( + CustomData_get_layer(&subdiv_mesh->pdata, CD_ORIGINDEX)); - faceMap = MEM_mallocN(subdiv_mesh->totpoly * sizeof(BMFace *), "unwrap_edit_face_map"); + faceMap = static_cast( + MEM_mallocN(subdiv_mesh->totpoly * sizeof(BMFace *), "unwrap_edit_face_map")); BM_mesh_elem_index_ensure(em->bm, BM_VERT); BM_mesh_elem_table_ensure(em->bm, BM_EDGE | BM_FACE); @@ -645,14 +652,15 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, faceMap[i] = BM_face_at_index(em->bm, origPolyIndices[i]); } - edgeMap = MEM_mallocN(subdiv_mesh->totedge * sizeof(BMEdge *), "unwrap_edit_edge_map"); + edgeMap = static_cast( + MEM_mallocN(subdiv_mesh->totedge * sizeof(BMEdge *), "unwrap_edit_edge_map")); /* map subsurfed edges to original editEdges */ for (int i = 0; i < subdiv_mesh->totedge; i++) { /* not all edges correspond to an old edge */ edgeMap[i] = (origEdgeIndices[i] != ORIGINDEX_NONE) ? BM_edge_at_index(em->bm, origEdgeIndices[i]) : - NULL; + nullptr; } /* Prepare and feed faces to the solver */ @@ -708,7 +716,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, /* these are calculated from original mesh too */ for (int i = 0; i < subdiv_mesh->totedge; i++) { - if ((edgeMap[i] != NULL) && BM_elem_flag_test(edgeMap[i], BM_ELEM_SEAM)) { + if ((edgeMap[i] != nullptr) && BM_elem_flag_test(edgeMap[i], BM_ELEM_SEAM)) { const MEdge *edge = &subsurfedEdges[i]; ParamKey vkeys[2]; vkeys[0] = (ParamKey)edge->v1; @@ -720,12 +728,12 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, GEO_uv_parametrizer_construct_end(handle, options->fill_holes, options->topology_from_uvs, - result_info ? &result_info->count_failed : NULL); + result_info ? &result_info->count_failed : nullptr); /* cleanup */ MEM_freeN(faceMap); MEM_freeN(edgeMap); - BKE_id_free(NULL, subdiv_mesh); + BKE_id_free(nullptr, subdiv_mesh); return handle; } @@ -736,7 +744,7 @@ static ParamHandle *construct_param_handle_subsurfed(const Scene *scene, /** \name Minimize Stretch Operator * \{ */ -typedef struct MinStretch { +struct MinStretch { const Scene *scene; Object **objects_edit; uint objects_len; @@ -745,20 +753,19 @@ typedef struct MinStretch { double lasttime; int i, iterations; wmTimer *timer; -} MinStretch; +}; static bool minimize_stretch_init(bContext *C, wmOperator *op) { const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - const UnwrapOptions options = { - .topology_from_uvs = true, - .fill_holes = RNA_boolean_get(op->ptr, "fill_holes"), - .only_selected_faces = true, - .only_selected_uvs = true, - .correct_aspect = true, - }; + UnwrapOptions options{}; + options.topology_from_uvs = true; + options.fill_holes = RNA_boolean_get(op->ptr, "fill_holes"); + options.only_selected_faces = true; + options.only_selected_uvs = true; + options.correct_aspect = true; uint objects_len = 0; Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( @@ -769,7 +776,7 @@ static bool minimize_stretch_init(bContext *C, wmOperator *op) return false; } - MinStretch *ms = MEM_callocN(sizeof(MinStretch), "MinStretch"); + MinStretch *ms = MEM_cnew(__func__); ms->scene = scene; ms->objects_edit = objects; ms->objects_len = objects_len; @@ -791,7 +798,7 @@ static bool minimize_stretch_init(bContext *C, wmOperator *op) static void minimize_stretch_iteration(bContext *C, wmOperator *op, bool interactive) { - MinStretch *ms = op->customdata; + MinStretch *ms = static_cast(op->customdata); ScrArea *area = CTX_wm_area(C); const Scene *scene = CTX_data_scene(C); ToolSettings *ts = scene->toolsettings; @@ -824,7 +831,7 @@ static void minimize_stretch_iteration(bContext *C, wmOperator *op, bool interac continue; } - DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY); + DEG_id_tag_update(static_cast(obedit->data), ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); } } @@ -832,14 +839,14 @@ static void minimize_stretch_iteration(bContext *C, wmOperator *op, bool interac static void minimize_stretch_exit(bContext *C, wmOperator *op, bool cancel) { - MinStretch *ms = op->customdata; + MinStretch *ms = static_cast(op->customdata); ScrArea *area = CTX_wm_area(C); const Scene *scene = CTX_data_scene(C); ToolSettings *ts = scene->toolsettings; const bool synced_selection = (ts->uv_flag & UV_SYNC_SELECTION) != 0; - ED_area_status_text(area, NULL); - ED_workspace_status_text(C, NULL); + ED_area_status_text(area, nullptr); + ED_workspace_status_text(C, nullptr); if (ms->timer) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), ms->timer); @@ -863,13 +870,13 @@ static void minimize_stretch_exit(bContext *C, wmOperator *op, bool cancel) continue; } - DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY); + DEG_id_tag_update(static_cast(obedit->data), ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); } MEM_freeN(ms->objects_edit); MEM_freeN(ms); - op->customdata = NULL; + op->customdata = nullptr; } static int minimize_stretch_exec(bContext *C, wmOperator *op) @@ -889,17 +896,15 @@ static int minimize_stretch_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } -static int minimize_stretch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int minimize_stretch_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { - MinStretch *ms; - if (!minimize_stretch_init(C, op)) { return OPERATOR_CANCELLED; } minimize_stretch_iteration(C, op, true); - ms = op->customdata; + MinStretch *ms = static_cast(op->customdata); WM_event_add_modal_handler(C, op); ms->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f); @@ -908,7 +913,7 @@ static int minimize_stretch_invoke(bContext *C, wmOperator *op, const wmEvent *U static int minimize_stretch_modal(bContext *C, wmOperator *op, const wmEvent *event) { - MinStretch *ms = op->customdata; + MinStretch *ms = static_cast(op->customdata); switch (event->type) { case EVT_ESCKEY: @@ -1026,13 +1031,12 @@ static int pack_islands_exec(bContext *C, wmOperator *op) const Scene *scene = CTX_data_scene(C); const SpaceImage *sima = CTX_wm_space_image(C); - const UnwrapOptions options = { - .topology_from_uvs = true, - .only_selected_faces = true, - .only_selected_uvs = true, - .fill_holes = false, - .correct_aspect = true, - }; + UnwrapOptions options{}; + options.topology_from_uvs = true; + options.only_selected_faces = true; + options.only_selected_uvs = true; + options.fill_holes = false; + options.correct_aspect = true; uint objects_len = 0; Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( @@ -1053,20 +1057,20 @@ static int pack_islands_exec(bContext *C, wmOperator *op) RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); } - struct UVPackIsland_Params pack_island_params = { - .rotate = RNA_boolean_get(op->ptr, "rotate"), - .only_selected_uvs = options.only_selected_uvs, - .only_selected_faces = options.only_selected_faces, - .use_seams = !options.topology_from_uvs || options.topology_from_uvs_use_seams, - .correct_aspect = options.correct_aspect, - .ignore_pinned = false, - .pin_unselected = options.pin_unselected, - .margin_method = RNA_enum_get(op->ptr, "margin_method"), - .margin = RNA_float_get(op->ptr, "margin"), - }; + UVPackIsland_Params pack_island_params{}; + pack_island_params.rotate = RNA_boolean_get(op->ptr, "rotate"); + pack_island_params.only_selected_uvs = options.only_selected_uvs; + pack_island_params.only_selected_faces = options.only_selected_faces; + pack_island_params.use_seams = !options.topology_from_uvs || options.topology_from_uvs_use_seams; + pack_island_params.correct_aspect = options.correct_aspect; + pack_island_params.ignore_pinned = false; + pack_island_params.pin_unselected = options.pin_unselected; + pack_island_params.margin_method = eUVPackIsland_MarginMethod( + RNA_enum_get(op->ptr, "margin_method")); + pack_island_params.margin = RNA_float_get(op->ptr, "margin"); - struct UVMapUDIM_Params closest_udim_buf; - struct UVMapUDIM_Params *closest_udim = NULL; + UVMapUDIM_Params closest_udim_buf; + UVMapUDIM_Params *closest_udim = nullptr; if (udim_source == PACK_UDIM_SRC_ACTIVE) { ED_uvedit_udim_params_from_image_space(sima, &pack_island_params); } @@ -1079,7 +1083,7 @@ static int pack_islands_exec(bContext *C, wmOperator *op) } ED_uvedit_pack_islands_multi( - scene, objects, objects_len, NULL, closest_udim, &pack_island_params); + scene, objects, objects_len, nullptr, closest_udim, &pack_island_params); MEM_freeN(objects); return OPERATOR_FINISHED; @@ -1097,7 +1101,7 @@ static const EnumPropertyItem pack_margin_method_items[] = { 0, "Fraction", "Specify a precise fraction of final UV output"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; void UV_OT_pack_islands(wmOperatorType *ot) @@ -1109,7 +1113,7 @@ void UV_OT_pack_islands(wmOperatorType *ot) 0, "Active UDIM", "Pack islands to active UDIM image tile or UDIM grid tile where 2D cursor is located"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; /* identifiers */ ot->name = "Pack Islands"; @@ -1149,13 +1153,12 @@ static int average_islands_scale_exec(bContext *C, wmOperator *op) ToolSettings *ts = scene->toolsettings; const bool synced_selection = (ts->uv_flag & UV_SYNC_SELECTION) != 0; - const UnwrapOptions options = { - .topology_from_uvs = true, - .only_selected_faces = true, - .only_selected_uvs = true, - .fill_holes = false, - .correct_aspect = true, - }; + UnwrapOptions options{}; + options.topology_from_uvs = true; + options.only_selected_faces = true; + options.only_selected_uvs = true; + options.fill_holes = false; + options.correct_aspect = true; uint objects_len = 0; Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( @@ -1183,7 +1186,7 @@ static int average_islands_scale_exec(bContext *C, wmOperator *op) continue; } - DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY); + DEG_id_tag_update(static_cast(obedit->data), ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); } MEM_freeN(objects); @@ -1217,11 +1220,11 @@ void UV_OT_average_islands_scale(wmOperatorType *ot) static struct { ParamHandle **handles; uint len, len_alloc; -} g_live_unwrap = {NULL}; +} g_live_unwrap = {nullptr}; void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) { - ParamHandle *handle = NULL; + ParamHandle *handle = nullptr; BMEditMesh *em = BKE_editmesh_from_object(obedit); const bool abf = (scene->toolsettings->unwrapper == 0); bool use_subsurf; @@ -1232,34 +1235,33 @@ void ED_uvedit_live_unwrap_begin(Scene *scene, Object *obedit) return; } - const UnwrapOptions options = { - .topology_from_uvs = false, - .only_selected_faces = false, - .only_selected_uvs = false, - .fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0, - .correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0, - }; + UnwrapOptions options{}; + options.topology_from_uvs = false; + options.only_selected_faces = false; + options.only_selected_uvs = false; + options.fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0; + options.correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0; if (use_subsurf) { - handle = construct_param_handle_subsurfed(scene, obedit, em, &options, NULL); + handle = construct_param_handle_subsurfed(scene, obedit, em, &options, nullptr); } else { - handle = construct_param_handle(scene, obedit, em->bm, &options, NULL); + handle = construct_param_handle(scene, obedit, em->bm, &options, nullptr); } GEO_uv_parametrizer_lscm_begin(handle, true, abf); /* Create or increase size of g_live_unwrap.handles array */ - if (g_live_unwrap.handles == NULL) { + if (g_live_unwrap.handles == nullptr) { g_live_unwrap.len_alloc = 32; - g_live_unwrap.handles = MEM_mallocN(sizeof(ParamHandle *) * g_live_unwrap.len_alloc, - "uvedit_live_unwrap_liveHandles"); + g_live_unwrap.handles = static_cast(MEM_mallocN( + sizeof(ParamHandle *) * g_live_unwrap.len_alloc, "uvedit_live_unwrap_liveHandles")); g_live_unwrap.len = 0; } if (g_live_unwrap.len >= g_live_unwrap.len_alloc) { g_live_unwrap.len_alloc *= 2; - g_live_unwrap.handles = MEM_reallocN(g_live_unwrap.handles, - sizeof(ParamHandle *) * g_live_unwrap.len_alloc); + g_live_unwrap.handles = static_cast( + MEM_reallocN(g_live_unwrap.handles, sizeof(ParamHandle *) * g_live_unwrap.len_alloc)); } g_live_unwrap.handles[g_live_unwrap.len] = handle; g_live_unwrap.len++; @@ -1269,7 +1271,7 @@ void ED_uvedit_live_unwrap_re_solve(void) { if (g_live_unwrap.handles) { for (int i = 0; i < g_live_unwrap.len; i++) { - GEO_uv_parametrizer_lscm_solve(g_live_unwrap.handles[i], NULL, NULL); + GEO_uv_parametrizer_lscm_solve(g_live_unwrap.handles[i], nullptr, nullptr); GEO_uv_parametrizer_flush(g_live_unwrap.handles[i]); } } @@ -1286,7 +1288,7 @@ void ED_uvedit_live_unwrap_end(short cancel) GEO_uv_parametrizer_delete(g_live_unwrap.handles[i]); } MEM_freeN(g_live_unwrap.handles); - g_live_unwrap.handles = NULL; + g_live_unwrap.handles = nullptr; g_live_unwrap.len = 0; g_live_unwrap.len_alloc = 0; } @@ -1334,7 +1336,7 @@ static void uv_map_transform_calc_center_median(BMEditMesh *em, float r_center[3 center_accum_num += 1; } } - mul_v3_fl(r_center, 1.0f / (float)center_accum_num); + mul_v3_fl(r_center, 1.0f / float(center_accum_num)); } static void uv_map_transform_center(const Scene *scene, @@ -1429,14 +1431,14 @@ static void uv_map_rotation_matrix_ex(float result[4][4], /* Compensate front/side.. against opengl x,y,z world definition. * This is "a sledgehammer to crack a nut" (overkill), a few plus minus 1 will do here. * I wanted to keep the reason here, so we're rotating. */ - sideangle = (float)M_PI * (sideangledeg + 180.0f) / 180.0f; + sideangle = float(M_PI) * (sideangledeg + 180.0f) / 180.0f; rotside[0][0] = cosf(sideangle); rotside[0][1] = -sinf(sideangle); rotside[1][0] = sinf(sideangle); rotside[1][1] = cosf(sideangle); rotside[2][2] = 1.0f; - upangle = (float)M_PI * upangledeg / 180.0f; + upangle = float(M_PI) * upangledeg / 180.0f; rotup[1][1] = cosf(upangle) / radius; rotup[1][2] = -sinf(upangle) / radius; rotup[2][1] = sinf(upangle) / radius; @@ -1490,18 +1492,18 @@ static void uv_transform_properties(wmOperatorType *ot, int radius) 0, "Align to Object", "Align according to object transform"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static const EnumPropertyItem align_items[] = { {POLAR_ZX, "POLAR_ZX", 0, "Polar ZX", "Polar 0 is X"}, {POLAR_ZY, "POLAR_ZY", 0, "Polar ZY", "Polar 0 is Y"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static const EnumPropertyItem pole_items[] = { {PINCH, "PINCH", 0, "Pinch", "UVs are pinched at the poles"}, {FAN, "FAN", 0, "Fan", "UVs are fanned at the poles"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; RNA_def_enum(ot->srna, @@ -1577,9 +1579,8 @@ static void correct_uv_aspect_per_face(Object *ob, BMEditMesh *em) return; } - float *material_aspect_y = BLI_array_alloca(material_aspect_y, materials_num); + blender::Array material_aspect_y(materials_num, -1); /* Lazily initialize aspect ratio for materials. */ - copy_vn_fl(material_aspect_y, materials_num, -1.0f); const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_PROP_FLOAT2); @@ -1803,8 +1804,8 @@ static void uvedit_unwrap(const Scene *scene, GEO_uv_parametrizer_lscm_begin(handle, false, scene->toolsettings->unwrapper == 0); GEO_uv_parametrizer_lscm_solve(handle, - result_info ? &result_info->count_changed : NULL, - result_info ? &result_info->count_failed : NULL); + result_info ? &result_info->count_changed : nullptr, + result_info ? &result_info->count_failed : nullptr); GEO_uv_parametrizer_lscm_end(handle); GEO_uv_parametrizer_average(handle, true, false, false); @@ -1823,7 +1824,7 @@ static void uvedit_unwrap_multi(const Scene *scene, for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *obedit = objects[ob_index]; uvedit_unwrap(scene, obedit, options, result_info); - DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY); + DEG_id_tag_update(static_cast(obedit->data), ID_RECALC_GEOMETRY); WM_main_add_notifier(NC_GEOM | ND_DATA, obedit->data); } } @@ -1831,27 +1832,28 @@ static void uvedit_unwrap_multi(const Scene *scene, void ED_uvedit_live_unwrap(const Scene *scene, Object **objects, int objects_len) { if (scene->toolsettings->edge_mode_live_unwrap) { - const UnwrapOptions options = { - .topology_from_uvs = false, - .only_selected_faces = false, - .only_selected_uvs = false, - .fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0, - .correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0, - }; - uvedit_unwrap_multi(scene, objects, objects_len, &options, NULL); + UnwrapOptions options{}; + options.topology_from_uvs = false; + options.only_selected_faces = false; + options.only_selected_uvs = false; + options.fill_holes = (scene->toolsettings->uvcalc_flag & UVCALC_FILLHOLES) != 0; + options.correct_aspect = (scene->toolsettings->uvcalc_flag & UVCALC_NO_ASPECT_CORRECT) == 0; + uvedit_unwrap_multi(scene, objects, objects_len, &options, nullptr); - const struct UVPackIsland_Params pack_island_params = { - .rotate = true, - .only_selected_uvs = options.only_selected_uvs, - .only_selected_faces = options.only_selected_faces, - .use_seams = !options.topology_from_uvs || options.topology_from_uvs_use_seams, - .correct_aspect = options.correct_aspect, - .ignore_pinned = true, - .pin_unselected = options.pin_unselected, - .margin_method = ED_UVPACK_MARGIN_SCALED, - .margin = scene->toolsettings->uvcalc_margin, - }; - ED_uvedit_pack_islands_multi(scene, objects, objects_len, NULL, NULL, &pack_island_params); + UVPackIsland_Params pack_island_params{}; + pack_island_params.rotate = true, + pack_island_params.only_selected_uvs = options.only_selected_uvs, + pack_island_params.only_selected_faces = options.only_selected_faces, + pack_island_params.use_seams = !options.topology_from_uvs || + options.topology_from_uvs_use_seams, + pack_island_params.correct_aspect = options.correct_aspect, + pack_island_params.ignore_pinned = true, + pack_island_params.pin_unselected = options.pin_unselected, + pack_island_params.margin_method = ED_UVPACK_MARGIN_SCALED, + pack_island_params.margin = scene->toolsettings->uvcalc_margin, + + ED_uvedit_pack_islands_multi( + scene, objects, objects_len, nullptr, nullptr, &pack_island_params); } } @@ -1875,13 +1877,12 @@ static int unwrap_exec(bContext *C, wmOperator *op) Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( scene, view_layer, CTX_wm_view3d(C), &objects_len); - UnwrapOptions options = { - .topology_from_uvs = false, - .only_selected_faces = true, - .only_selected_uvs = false, - .fill_holes = RNA_boolean_get(op->ptr, "fill_holes"), - .correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"), - }; + UnwrapOptions options{}; + options.topology_from_uvs = false; + options.only_selected_faces = true; + options.only_selected_uvs = false; + options.fill_holes = RNA_boolean_get(op->ptr, "fill_holes"); + options.correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"); if (CTX_wm_space_image(C)) { /* Inside the UV Editor, only unwrap selected UVs. */ @@ -1982,24 +1983,24 @@ static int unwrap_exec(bContext *C, wmOperator *op) } /* execute unwrap */ - UnwrapResultInfo result_info = { - .count_changed = 0, - .count_failed = 0, - }; + UnwrapResultInfo result_info{}; + result_info.count_changed = 0; + result_info.count_failed = 0; uvedit_unwrap_multi(scene, objects, objects_len, &options, &result_info); - const struct UVPackIsland_Params pack_island_params = { - .rotate = true, - .only_selected_uvs = options.only_selected_uvs, - .only_selected_faces = options.only_selected_faces, - .use_seams = !options.topology_from_uvs || options.topology_from_uvs_use_seams, - .correct_aspect = options.correct_aspect, - .ignore_pinned = true, - .pin_unselected = options.pin_unselected, - .margin_method = RNA_enum_get(op->ptr, "margin_method"), - .margin = RNA_float_get(op->ptr, "margin"), - }; - ED_uvedit_pack_islands_multi(scene, objects, objects_len, NULL, NULL, &pack_island_params); + UVPackIsland_Params pack_island_params{}; + pack_island_params.rotate = true; + pack_island_params.only_selected_uvs = options.only_selected_uvs; + pack_island_params.only_selected_faces = options.only_selected_faces; + pack_island_params.use_seams = !options.topology_from_uvs || options.topology_from_uvs_use_seams; + pack_island_params.correct_aspect = options.correct_aspect; + pack_island_params.ignore_pinned = true; + pack_island_params.pin_unselected = options.pin_unselected; + pack_island_params.margin_method = eUVPackIsland_MarginMethod( + RNA_enum_get(op->ptr, "margin_method")); + pack_island_params.margin = RNA_float_get(op->ptr, "margin"); + + ED_uvedit_pack_islands_multi(scene, objects, objects_len, nullptr, nullptr, &pack_island_params); MEM_freeN(objects); @@ -2024,7 +2025,7 @@ void UV_OT_unwrap(wmOperatorType *ot) static const EnumPropertyItem method_items[] = { {0, "ANGLE_BASED", 0, "Angle Based", ""}, {1, "CONFORMAL", 0, "Conformal", ""}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; /* identifiers */ @@ -2081,10 +2082,10 @@ void UV_OT_unwrap(wmOperatorType *ot) /* Ignore all areas below this, as the UVs get zeroed. */ static const float smart_uv_project_area_ignore = 1e-12f; -typedef struct ThickFace { +struct ThickFace { float area; BMFace *efa; -} ThickFace; +}; static int smart_uv_project_thickface_area_cmp_fn(const void *tf_a_p, const void *tf_b_p) { @@ -2107,26 +2108,22 @@ static int smart_uv_project_thickface_area_cmp_fn(const void *tf_a_p, const void return 0; } -static uint smart_uv_project_calculate_project_normals(const ThickFace *thick_faces, - const uint thick_faces_len, - BMesh *bm, - const float project_angle_limit_half_cos, - const float project_angle_limit_cos, - const float area_weight, - float (**r_project_normal_array)[3]) +static blender::Vector smart_uv_project_calculate_project_normals( + const ThickFace *thick_faces, + const uint thick_faces_len, + BMesh *bm, + const float project_angle_limit_half_cos, + const float project_angle_limit_cos, + const float area_weight) { if (UNLIKELY(thick_faces_len == 0)) { - *r_project_normal_array = NULL; - return 0; + return {}; } const float *project_normal = thick_faces[0].efa->no; - const ThickFace **project_thick_faces = NULL; - BLI_array_declare(project_thick_faces); - - float(*project_normal_array)[3] = NULL; - BLI_array_declare(project_normal_array); + blender::Vector project_thick_faces; + blender::Vector project_normal_array; BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false); @@ -2137,7 +2134,7 @@ static uint smart_uv_project_calculate_project_normals(const ThickFace *thick_fa } if (dot_v3v3(thick_faces[f_index].efa->no, project_normal) > project_angle_limit_half_cos) { - BLI_array_append(project_thick_faces, &thick_faces[f_index]); + project_thick_faces.append(&thick_faces[f_index]); BM_elem_flag_set(thick_faces[f_index].efa, BM_ELEM_TAG, true); } } @@ -2145,22 +2142,19 @@ static uint smart_uv_project_calculate_project_normals(const ThickFace *thick_fa float average_normal[3] = {0.0f, 0.0f, 0.0f}; if (area_weight <= 0.0f) { - for (int f_proj_index = 0; f_proj_index < BLI_array_len(project_thick_faces); - f_proj_index++) { + for (int f_proj_index = 0; f_proj_index < project_thick_faces.size(); f_proj_index++) { const ThickFace *tf = project_thick_faces[f_proj_index]; add_v3_v3(average_normal, tf->efa->no); } } else if (area_weight >= 1.0f) { - for (int f_proj_index = 0; f_proj_index < BLI_array_len(project_thick_faces); - f_proj_index++) { + for (int f_proj_index = 0; f_proj_index < project_thick_faces.size(); f_proj_index++) { const ThickFace *tf = project_thick_faces[f_proj_index]; madd_v3_v3fl(average_normal, tf->efa->no, tf->area); } } else { - for (int f_proj_index = 0; f_proj_index < BLI_array_len(project_thick_faces); - f_proj_index++) { + for (int f_proj_index = 0; f_proj_index < project_thick_faces.size(); f_proj_index++) { const ThickFace *tf = project_thick_faces[f_proj_index]; const float area_blend = (tf->area * area_weight) + (1.0f - area_weight); madd_v3_v3fl(average_normal, tf->efa->no, area_blend); @@ -2169,8 +2163,7 @@ static uint smart_uv_project_calculate_project_normals(const ThickFace *thick_fa /* Avoid NAN. */ if (normalize_v3(average_normal) != 0.0f) { - float(*normal)[3] = BLI_array_append_ret(project_normal_array); - copy_v3_v3(*normal, average_normal); + project_normal_array.append(average_normal); } /* Find the most unique angle that points away from other normals. */ @@ -2183,7 +2176,7 @@ static uint smart_uv_project_calculate_project_normals(const ThickFace *thick_fa } float angle_test = -1.0f; - for (int p_index = 0; p_index < BLI_array_len(project_normal_array); p_index++) { + for (int p_index = 0; p_index < project_normal_array.size(); p_index++) { angle_test = max_ff(angle_test, dot_v3v3(project_normal_array[p_index], thick_faces[f_index].efa->no)); } @@ -2196,22 +2189,20 @@ static uint smart_uv_project_calculate_project_normals(const ThickFace *thick_fa if (anble_best < project_angle_limit_cos) { project_normal = thick_faces[angle_best_index].efa->no; - BLI_array_clear(project_thick_faces); - BLI_array_append(project_thick_faces, &thick_faces[angle_best_index]); + project_thick_faces.clear(); + project_thick_faces.append(&thick_faces[angle_best_index]); BM_elem_flag_enable(thick_faces[angle_best_index].efa, BM_ELEM_TAG); } else { - if (BLI_array_len(project_normal_array) >= 1) { + if (project_normal_array.size() >= 1) { break; } } } - BLI_array_free(project_thick_faces); BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false); - *r_project_normal_array = project_normal_array; - return BLI_array_len(project_normal_array); + return project_normal_array; } static int smart_project_exec(bContext *C, wmOperator *op) @@ -2219,7 +2210,7 @@ static int smart_project_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - /* May be NULL. */ + /* May be nullptr. */ View3D *v3d = CTX_wm_view3d(C); bool only_selected_uvs = false; @@ -2242,7 +2233,8 @@ static int smart_project_exec(bContext *C, wmOperator *op) Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( scene, view_layer, v3d, &objects_len); - Object **objects_changed = MEM_mallocN(sizeof(*objects_changed) * objects_len, __func__); + Object **objects_changed = static_cast( + MEM_mallocN(sizeof(*objects_changed) * objects_len, __func__)); uint object_changed_len = 0; BMFace *efa; @@ -2260,7 +2252,8 @@ static int smart_project_exec(bContext *C, wmOperator *op) const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm); BLI_assert(offsets.uv >= 0); - ThickFace *thick_faces = MEM_mallocN(sizeof(*thick_faces) * em->bm->totface, __func__); + ThickFace *thick_faces = static_cast( + MEM_mallocN(sizeof(*thick_faces) * em->bm->totface, __func__)); uint thick_faces_len = 0; BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { @@ -2298,25 +2291,23 @@ static int smart_project_exec(bContext *C, wmOperator *op) thick_faces_len -= 1; } - float(*project_normal_array)[3] = NULL; - int project_normals_len = smart_uv_project_calculate_project_normals( - thick_faces, - thick_faces_len, - em->bm, - project_angle_limit_half_cos, - project_angle_limit_cos, - area_weight, - &project_normal_array); + blender::Vector project_normal_array = + smart_uv_project_calculate_project_normals(thick_faces, + thick_faces_len, + em->bm, + project_angle_limit_half_cos, + project_angle_limit_cos, + area_weight); - if (project_normals_len == 0) { + if (project_normal_array.size() == 0) { MEM_freeN(thick_faces); - BLI_assert(project_normal_array == NULL); + BLI_assert(project_normal_array == nullptr); continue; } /* After finding projection vectors, we find the uv positions. */ - LinkNode **thickface_project_groups = MEM_callocN( - sizeof(*thickface_project_groups) * project_normals_len, __func__); + LinkNode **thickface_project_groups = static_cast( + MEM_callocN(sizeof(*thickface_project_groups) * project_normal_array.size(), __func__)); BLI_memarena_clear(arena); @@ -2326,7 +2317,7 @@ static int smart_project_exec(bContext *C, wmOperator *op) float angle_best = dot_v3v3(f_normal, project_normal_array[0]); uint angle_best_index = 0; - for (int p_index = 1; p_index < project_normals_len; p_index++) { + for (int p_index = 1; p_index < project_normal_array.size(); p_index++) { const float angle_test = dot_v3v3(f_normal, project_normal_array[p_index]); if (angle_test > angle_best) { angle_best = angle_test; @@ -2338,8 +2329,8 @@ static int smart_project_exec(bContext *C, wmOperator *op) &thickface_project_groups[angle_best_index], &thick_faces[f_index], arena); } - for (int p_index = 0; p_index < project_normals_len; p_index++) { - if (thickface_project_groups[p_index] == NULL) { + for (int p_index = 0; p_index < project_normal_array.size(); p_index++) { + if (thickface_project_groups[p_index] == nullptr) { continue; } @@ -2347,7 +2338,7 @@ static int smart_project_exec(bContext *C, wmOperator *op) axis_dominant_v3_to_m3(axis_mat, project_normal_array[p_index]); for (LinkNode *list = thickface_project_groups[p_index]; list; list = list->next) { - ThickFace *tf = list->link; + ThickFace *tf = static_cast(list->link); BMIter liter; BMLoop *l; BM_ITER_ELEM (l, &liter, tf->efa, BM_LOOPS_OF_FACE) { @@ -2359,7 +2350,6 @@ static int smart_project_exec(bContext *C, wmOperator *op) } MEM_freeN(thick_faces); - MEM_freeN(project_normal_array); /* No need to free the lists in 'thickface_project_groups' values as the 'arena' is used. */ MEM_freeN(thickface_project_groups); @@ -2382,16 +2372,17 @@ static int smart_project_exec(bContext *C, wmOperator *op) /* Depsgraph refresh functions are called here. */ const bool correct_aspect = RNA_boolean_get(op->ptr, "correct_aspect"); - const struct UVPackIsland_Params params = { - .rotate = true, - .only_selected_uvs = only_selected_uvs, - .only_selected_faces = true, - .correct_aspect = correct_aspect, - .use_seams = true, - .margin_method = RNA_enum_get(op->ptr, "margin_method"), - .margin = RNA_float_get(op->ptr, "island_margin"), - }; - ED_uvedit_pack_islands_multi(scene, objects_changed, object_changed_len, NULL, NULL, ¶ms); + UVPackIsland_Params params{}; + params.rotate = true; + params.only_selected_uvs = only_selected_uvs; + params.only_selected_faces = true; + params.correct_aspect = correct_aspect; + params.use_seams = true; + params.margin_method = eUVPackIsland_MarginMethod(RNA_enum_get(op->ptr, "margin_method")); + params.margin = RNA_float_get(op->ptr, "island_margin"); + + ED_uvedit_pack_islands_multi( + scene, objects_changed, object_changed_len, nullptr, nullptr, ¶ms); /* #ED_uvedit_pack_islands_multi only supports `per_face_aspect = false`. */ const bool per_face_aspect = false; @@ -2424,7 +2415,7 @@ void UV_OT_smart_project(wmOperatorType *ot) prop = RNA_def_float_rotation(ot->srna, "angle_limit", 0, - NULL, + nullptr, DEG2RADF(0.0f), DEG2RADF(90.0f), "Angle Limit", @@ -2469,7 +2460,7 @@ void UV_OT_smart_project(wmOperatorType *ot) static int uv_from_view_exec(bContext *C, wmOperator *op); -static int uv_from_view_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int uv_from_view_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -2478,11 +2469,11 @@ static int uv_from_view_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSE prop = RNA_struct_find_property(op->ptr, "camera_bounds"); if (!RNA_property_is_set(op->ptr, prop)) { - RNA_property_boolean_set(op->ptr, prop, (camera != NULL)); + RNA_property_boolean_set(op->ptr, prop, (camera != nullptr)); } prop = RNA_struct_find_property(op->ptr, "correct_aspect"); if (!RNA_property_is_set(op->ptr, prop)) { - RNA_property_boolean_set(op->ptr, prop, (camera == NULL)); + RNA_property_boolean_set(op->ptr, prop, (camera == nullptr)); } return uv_from_view_exec(C, op); @@ -2505,7 +2496,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) const bool use_orthographic = RNA_boolean_get(op->ptr, "orthographic"); - /* NOTE: objects that aren't touched are set to NULL (to skip clipping). */ + /* NOTE: objects that aren't touched are set to nullptr (to skip clipping). */ uint objects_len = 0; Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( scene, view_layer, v3d, &objects_len); @@ -2551,7 +2542,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) } else if (camera) { const bool camera_bounds = RNA_boolean_get(op->ptr, "camera_bounds"); - struct ProjCameraInfo *uci = BLI_uvproject_camera_info( + ProjCameraInfo *uci = BLI_uvproject_camera_info( v3d->camera, obedit->object_to_world, camera_bounds ? (scene->r.xsch * scene->r.xasp) : 1.0f, @@ -2592,7 +2583,7 @@ static int uv_from_view_exec(bContext *C, wmOperator *op) if (changed) { changed_multi = true; - DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY); + DEG_id_tag_update(static_cast(obedit->data), ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); } else { @@ -2624,7 +2615,7 @@ static bool uv_from_view_poll(bContext *C) return 0; } - return (rv3d != NULL); + return (rv3d != nullptr); } void UV_OT_project_from_view(wmOperatorType *ot) @@ -2657,7 +2648,7 @@ void UV_OT_project_from_view(wmOperatorType *ot) /** \name Reset UV Operator * \{ */ -static int reset_exec(bContext *C, wmOperator *UNUSED(op)) +static int reset_exec(bContext *C, wmOperator * /*op*/) { const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); @@ -2682,7 +2673,7 @@ static int reset_exec(bContext *C, wmOperator *UNUSED(op)) ED_mesh_uv_loop_reset(C, me); - DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY); + DEG_id_tag_update(static_cast(obedit->data), ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); } MEM_freeN(objects); @@ -2731,7 +2722,7 @@ static void uv_map_mirror(BMFace *efa, float right_u = -1.0e30f; BMLoop *l; BMIter liter; - float **uvs = BLI_array_alloca(uvs, efa->len); + blender::Array uvs(efa->len); int j; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) { float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); @@ -2811,7 +2802,7 @@ static void uv_sphere_project(BMFace *efa, const bool fan, const int cd_loop_uv_offset) { - bool *regular = BLI_array_alloca(regular, efa->len); + blender::Array regular(efa->len); int i; BMLoop *l; BMIter iter; @@ -2823,7 +2814,7 @@ static void uv_sphere_project(BMFace *efa, regular[i] = map_to_sphere(&luv[0], &luv[1], pv[0], pv[1], pv[2]); } - uv_map_mirror(efa, regular, fan, cd_loop_uv_offset); + uv_map_mirror(efa, regular.data(), fan, cd_loop_uv_offset); } static int sphere_project_exec(bContext *C, wmOperator *op) @@ -2860,7 +2851,7 @@ static int sphere_project_exec(bContext *C, wmOperator *op) float center[3], rotmat[3][3]; uv_map_transform(C, op, rotmat); - uv_map_transform_center(scene, v3d, obedit, em, center, NULL); + uv_map_transform_center(scene, v3d, obedit, em, center, nullptr); const bool fan = RNA_enum_get(op->ptr, "pole"); @@ -2882,7 +2873,7 @@ static int sphere_project_exec(bContext *C, wmOperator *op) const bool per_face_aspect = true; uv_map_clip_correct(scene, &obedit, 1, op, per_face_aspect, only_selected_uvs); - DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY); + DEG_id_tag_update(static_cast(obedit->data), ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); } MEM_freeN(objects); @@ -2920,7 +2911,7 @@ static void uv_cylinder_project(BMFace *efa, const bool fan, const int cd_loop_uv_offset) { - bool *regular = BLI_array_alloca(regular, efa->len); + blender::Array regular(efa->len); int i; BMLoop *l; BMIter iter; @@ -2932,7 +2923,7 @@ static void uv_cylinder_project(BMFace *efa, regular[i] = map_to_tube(&luv[0], &luv[1], pv[0], pv[1], pv[2]); } - uv_map_mirror(efa, regular, fan, cd_loop_uv_offset); + uv_map_mirror(efa, regular.data(), fan, cd_loop_uv_offset); } static int cylinder_project_exec(bContext *C, wmOperator *op) @@ -2969,7 +2960,7 @@ static int cylinder_project_exec(bContext *C, wmOperator *op) float center[3], rotmat[3][3]; uv_map_transform(C, op, rotmat); - uv_map_transform_center(scene, v3d, obedit, em, center, NULL); + uv_map_transform_center(scene, v3d, obedit, em, center, nullptr); const bool fan = RNA_enum_get(op->ptr, "pole"); @@ -2989,7 +2980,7 @@ static int cylinder_project_exec(bContext *C, wmOperator *op) const bool per_face_aspect = true; uv_map_clip_correct(scene, &obedit, 1, op, per_face_aspect, only_selected_uvs); - DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY); + DEG_id_tag_update(static_cast(obedit->data), ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); } MEM_freeN(objects); @@ -3101,7 +3092,7 @@ static int cube_project_exec(bContext *C, wmOperator *op) } float bounds[2][3]; - float(*bounds_buf)[3] = NULL; + float(*bounds_buf)[3] = nullptr; if (!RNA_property_is_set(op->ptr, prop_cube_size)) { bounds_buf = bounds; @@ -3127,7 +3118,7 @@ static int cube_project_exec(bContext *C, wmOperator *op) const bool per_face_aspect = true; uv_map_clip_correct(scene, &obedit, 1, op, per_face_aspect, only_selected_uvs); - DEG_id_tag_update(obedit->data, ID_RECALC_GEOMETRY); + DEG_id_tag_update(static_cast(obedit->data), ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); } MEM_freeN(objects); @@ -3169,45 +3160,44 @@ void UV_OT_cube_project(wmOperatorType *ot) void ED_uvedit_add_simple_uvs(Main *bmain, const Scene *scene, Object *ob) { - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); bool sync_selection = (scene->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0; - BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default, - &((struct BMeshCreateParams){ - .use_toolflags = false, - })); + BMeshCreateParams create_params{}; + create_params.use_toolflags = false; + BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default, &create_params); /* turn sync selection off, * since we are not in edit mode we need to ensure only the uv flags are tested */ scene->toolsettings->uv_flag &= ~UV_SYNC_SELECTION; - ED_mesh_uv_ensure(me, NULL); + ED_mesh_uv_ensure(me, nullptr); + + BMeshFromMeshParams bm_from_me_params{}; + bm_from_me_params.calc_face_normal = true; + bm_from_me_params.calc_vert_normal = true; + BM_mesh_bm_from_me(bm, me, &bm_from_me_params); - BM_mesh_bm_from_me(bm, - me, - (&(struct BMeshFromMeshParams){ - .calc_face_normal = true, - .calc_vert_normal = true, - })); /* Select all UVs for cube_project. */ ED_uvedit_select_all(bm); /* A cube size of 2.0 maps [-1..1] vertex coords to [0.0..1.0] in UV coords. */ - uvedit_unwrap_cube_project(scene, bm, 2.0, false, false, NULL); + uvedit_unwrap_cube_project(scene, bm, 2.0, false, false, nullptr); /* Pack UVs. */ - const struct UVPackIsland_Params params = { - .rotate = true, - .only_selected_uvs = false, - .only_selected_faces = false, - .correct_aspect = false, - .use_seams = true, - .margin_method = ED_UVPACK_MARGIN_SCALED, - .margin = 0.001f, - }; - ED_uvedit_pack_islands_multi(scene, &ob, 1, &bm, NULL, ¶ms); + UVPackIsland_Params params{}; + params.rotate = true; + params.only_selected_uvs = false; + params.only_selected_faces = false; + params.correct_aspect = false; + params.use_seams = true; + params.margin_method = ED_UVPACK_MARGIN_SCALED; + params.margin = 0.001f; + + ED_uvedit_pack_islands_multi(scene, &ob, 1, &bm, nullptr, ¶ms); /* Write back from BMesh to Mesh. */ - BM_mesh_bm_to_me(bmain, bm, me, (&(struct BMeshToMeshParams){0})); + BMeshToMeshParams bm_to_me_params{}; + BM_mesh_bm_to_me(bmain, bm, me, &bm_to_me_params); BM_mesh_free(bm); if (sync_selection) { From 8d98d5c4027e3dca85e87fb20e2485b5c88838cc Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 21 Jan 2023 23:56:11 +0100 Subject: [PATCH 0853/1522] Cleanup: fix compiling in debug mode --- source/blender/editors/uvedit/uvedit_unwrap_ops.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc index 7a99fec413c..d95655cef45 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc @@ -2301,7 +2301,6 @@ static int smart_project_exec(bContext *C, wmOperator *op) if (project_normal_array.size() == 0) { MEM_freeN(thick_faces); - BLI_assert(project_normal_array == nullptr); continue; } From 3f1886d0b788d043917ec86702b4b480f8d5dd2e Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 22 Jan 2023 00:03:25 +0100 Subject: [PATCH 0854/1522] Functions: align chunk sizes in multi-function evaluation This can improve performance in some circumstances when there are vectorized and/or unrolled loops. I especially noticed that this helps a lot while working on D16970 (got a 10-20% speedup there by avoiding running into the non-vectorized fallback loop too often). --- source/blender/blenlib/BLI_task.hh | 30 ++++ .../functions/intern/multi_function.cc | 128 ++++++++++-------- 2 files changed, 101 insertions(+), 57 deletions(-) diff --git a/source/blender/blenlib/BLI_task.hh b/source/blender/blenlib/BLI_task.hh index c726691ad46..60585e35099 100644 --- a/source/blender/blenlib/BLI_task.hh +++ b/source/blender/blenlib/BLI_task.hh @@ -71,6 +71,36 @@ void parallel_for(IndexRange range, int64_t grain_size, const Function &function function(range); } +/** + * Same as #parallel_for but tries to make the sub-range sizes multiples of the given alignment. + * This can improve performance when the range is processed using vectorized and/or unrolled loops, + * because the fallback loop that processes remaining values is used less often. A disadvantage of + * using this instead of #parallel_for is that the size differences between sub-ranges can be + * larger, which means that work is distributed less evenly. + */ +template +void parallel_for_aligned(const IndexRange range, + const int64_t grain_size, + const int64_t alignment, + const Function &function) +{ + const int64_t global_begin = range.start(); + const int64_t global_end = range.one_after_last(); + const int64_t alignment_mask = ~(alignment - 1); + parallel_for(range, grain_size, [&](const IndexRange unaligned_range) { + /* Move the sub-range boundaries down to the next aligned index. The "global" begin and end + * remain fixed though. */ + const int64_t unaligned_begin = unaligned_range.start(); + const int64_t unaligned_end = unaligned_range.one_after_last(); + const int64_t aligned_begin = std::max(global_begin, unaligned_begin & alignment_mask); + const int64_t aligned_end = unaligned_end == global_end ? + unaligned_end : + std::max(global_begin, unaligned_end & alignment_mask); + const IndexRange aligned_range{aligned_begin, aligned_end - aligned_begin}; + function(aligned_range); + }); +} + template Value parallel_reduce(IndexRange range, int64_t grain_size, diff --git a/source/blender/functions/intern/multi_function.cc b/source/blender/functions/intern/multi_function.cc index fedf9a00d13..2f83ab08879 100644 --- a/source/blender/functions/intern/multi_function.cc +++ b/source/blender/functions/intern/multi_function.cc @@ -52,6 +52,16 @@ static int64_t compute_grain_size(const ExecutionHints &hints, const IndexMask m return grain_size; } +static int64_t compute_alignment(const int64_t grain_size) +{ + if (grain_size <= 512) { + /* Don't use a number that's too large, or otherwise the work will be split quite unevenly. */ + return 8; + } + /* It's not common that more elements are processed in a loop at once. */ + return 32; +} + void MultiFunction::call_auto(IndexMask mask, Params params, Context context) const { if (mask.is_empty()) { @@ -71,71 +81,75 @@ void MultiFunction::call_auto(IndexMask mask, Params params, Context context) co return; } - threading::parallel_for(mask.index_range(), grain_size, [&](const IndexRange sub_range) { - const IndexMask sliced_mask = mask.slice(sub_range); - if (!hints.allocates_array) { - /* There is no benefit to changing indices in this case. */ - this->call(sliced_mask, params, context); - return; - } - if (sliced_mask[0] < grain_size) { - /* The indices are low, no need to offset them. */ - this->call(sliced_mask, params, context); - return; - } - const int64_t input_slice_start = sliced_mask[0]; - const int64_t input_slice_size = sliced_mask.last() - input_slice_start + 1; - const IndexRange input_slice_range{input_slice_start, input_slice_size}; - - Vector offset_mask_indices; - const IndexMask offset_mask = mask.slice_and_offset(sub_range, offset_mask_indices); - - ParamsBuilder offset_params{*this, offset_mask.min_array_size()}; - - /* Slice all parameters so that for the actual function call. */ - for (const int param_index : this->param_indices()) { - const ParamType param_type = this->param_type(param_index); - switch (param_type.category()) { - case ParamCategory::SingleInput: { - const GVArray &varray = params.readonly_single_input(param_index); - offset_params.add_readonly_single_input(varray.slice(input_slice_range)); - break; + const int64_t alignment = compute_alignment(grain_size); + threading::parallel_for_aligned( + mask.index_range(), grain_size, alignment, [&](const IndexRange sub_range) { + const IndexMask sliced_mask = mask.slice(sub_range); + if (!hints.allocates_array) { + /* There is no benefit to changing indices in this case. */ + this->call(sliced_mask, params, context); + return; } - case ParamCategory::SingleMutable: { - const GMutableSpan span = params.single_mutable(param_index); - const GMutableSpan sliced_span = span.slice(input_slice_range); - offset_params.add_single_mutable(sliced_span); - break; + if (sliced_mask[0] < grain_size) { + /* The indices are low, no need to offset them. */ + this->call(sliced_mask, params, context); + return; } - case ParamCategory::SingleOutput: { - if (bool(signature_ref_->params[param_index].flag & ParamFlag::SupportsUnusedOutput)) { - const GMutableSpan span = params.uninitialized_single_output_if_required(param_index); - if (span.is_empty()) { - offset_params.add_ignored_single_output(); + const int64_t input_slice_start = sliced_mask[0]; + const int64_t input_slice_size = sliced_mask.last() - input_slice_start + 1; + const IndexRange input_slice_range{input_slice_start, input_slice_size}; + + Vector offset_mask_indices; + const IndexMask offset_mask = mask.slice_and_offset(sub_range, offset_mask_indices); + + ParamsBuilder offset_params{*this, offset_mask.min_array_size()}; + + /* Slice all parameters so that for the actual function call. */ + for (const int param_index : this->param_indices()) { + const ParamType param_type = this->param_type(param_index); + switch (param_type.category()) { + case ParamCategory::SingleInput: { + const GVArray &varray = params.readonly_single_input(param_index); + offset_params.add_readonly_single_input(varray.slice(input_slice_range)); + break; } - else { + case ParamCategory::SingleMutable: { + const GMutableSpan span = params.single_mutable(param_index); const GMutableSpan sliced_span = span.slice(input_slice_range); - offset_params.add_uninitialized_single_output(sliced_span); + offset_params.add_single_mutable(sliced_span); + break; + } + case ParamCategory::SingleOutput: { + if (bool(signature_ref_->params[param_index].flag & + ParamFlag::SupportsUnusedOutput)) { + const GMutableSpan span = params.uninitialized_single_output_if_required( + param_index); + if (span.is_empty()) { + offset_params.add_ignored_single_output(); + } + else { + const GMutableSpan sliced_span = span.slice(input_slice_range); + offset_params.add_uninitialized_single_output(sliced_span); + } + } + else { + const GMutableSpan span = params.uninitialized_single_output(param_index); + const GMutableSpan sliced_span = span.slice(input_slice_range); + offset_params.add_uninitialized_single_output(sliced_span); + } + break; + } + case ParamCategory::VectorInput: + case ParamCategory::VectorMutable: + case ParamCategory::VectorOutput: { + BLI_assert_unreachable(); + break; } } - else { - const GMutableSpan span = params.uninitialized_single_output(param_index); - const GMutableSpan sliced_span = span.slice(input_slice_range); - offset_params.add_uninitialized_single_output(sliced_span); - } - break; } - case ParamCategory::VectorInput: - case ParamCategory::VectorMutable: - case ParamCategory::VectorOutput: { - BLI_assert_unreachable(); - break; - } - } - } - this->call(offset_mask, offset_params, context); - }); + this->call(offset_mask, offset_params, context); + }); } std::string MultiFunction::debug_name() const From 96dfa68e5f6597f180794fc5bba68cb39c064540 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 22 Jan 2023 00:13:47 +0100 Subject: [PATCH 0855/1522] Cleanup: extract function that slices parameters for multi-function call --- .../functions/intern/multi_function.cc | 98 ++++++++++--------- 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/source/blender/functions/intern/multi_function.cc b/source/blender/functions/intern/multi_function.cc index 2f83ab08879..7cf79cc4b81 100644 --- a/source/blender/functions/intern/multi_function.cc +++ b/source/blender/functions/intern/multi_function.cc @@ -62,6 +62,54 @@ static int64_t compute_alignment(const int64_t grain_size) return 32; } +static void add_sliced_parameters(const Signature &signature, + Params &full_params, + const IndexRange slice_range, + ParamsBuilder &r_sliced_params) +{ + for (const int param_index : signature.params.index_range()) { + const ParamType ¶m_type = signature.params[param_index].type; + switch (param_type.category()) { + case ParamCategory::SingleInput: { + const GVArray &varray = full_params.readonly_single_input(param_index); + r_sliced_params.add_readonly_single_input(varray.slice(slice_range)); + break; + } + case ParamCategory::SingleMutable: { + const GMutableSpan span = full_params.single_mutable(param_index); + const GMutableSpan sliced_span = span.slice(slice_range); + r_sliced_params.add_single_mutable(sliced_span); + break; + } + case ParamCategory::SingleOutput: { + if (bool(signature.params[param_index].flag & ParamFlag::SupportsUnusedOutput)) { + const GMutableSpan span = full_params.uninitialized_single_output_if_required( + param_index); + if (span.is_empty()) { + r_sliced_params.add_ignored_single_output(); + } + else { + const GMutableSpan sliced_span = span.slice(slice_range); + r_sliced_params.add_uninitialized_single_output(sliced_span); + } + } + else { + const GMutableSpan span = full_params.uninitialized_single_output(param_index); + const GMutableSpan sliced_span = span.slice(slice_range); + r_sliced_params.add_uninitialized_single_output(sliced_span); + } + break; + } + case ParamCategory::VectorInput: + case ParamCategory::VectorMutable: + case ParamCategory::VectorOutput: { + BLI_assert_unreachable(); + break; + } + } + } +} + void MultiFunction::call_auto(IndexMask mask, Params params, Context context) const { if (mask.is_empty()) { @@ -102,53 +150,9 @@ void MultiFunction::call_auto(IndexMask mask, Params params, Context context) co Vector offset_mask_indices; const IndexMask offset_mask = mask.slice_and_offset(sub_range, offset_mask_indices); - ParamsBuilder offset_params{*this, offset_mask.min_array_size()}; - - /* Slice all parameters so that for the actual function call. */ - for (const int param_index : this->param_indices()) { - const ParamType param_type = this->param_type(param_index); - switch (param_type.category()) { - case ParamCategory::SingleInput: { - const GVArray &varray = params.readonly_single_input(param_index); - offset_params.add_readonly_single_input(varray.slice(input_slice_range)); - break; - } - case ParamCategory::SingleMutable: { - const GMutableSpan span = params.single_mutable(param_index); - const GMutableSpan sliced_span = span.slice(input_slice_range); - offset_params.add_single_mutable(sliced_span); - break; - } - case ParamCategory::SingleOutput: { - if (bool(signature_ref_->params[param_index].flag & - ParamFlag::SupportsUnusedOutput)) { - const GMutableSpan span = params.uninitialized_single_output_if_required( - param_index); - if (span.is_empty()) { - offset_params.add_ignored_single_output(); - } - else { - const GMutableSpan sliced_span = span.slice(input_slice_range); - offset_params.add_uninitialized_single_output(sliced_span); - } - } - else { - const GMutableSpan span = params.uninitialized_single_output(param_index); - const GMutableSpan sliced_span = span.slice(input_slice_range); - offset_params.add_uninitialized_single_output(sliced_span); - } - break; - } - case ParamCategory::VectorInput: - case ParamCategory::VectorMutable: - case ParamCategory::VectorOutput: { - BLI_assert_unreachable(); - break; - } - } - } - - this->call(offset_mask, offset_params, context); + ParamsBuilder sliced_params{*this, offset_mask.min_array_size()}; + add_sliced_parameters(*signature_ref_, params, input_slice_range, sliced_params); + this->call(offset_mask, sliced_params, context); }); } From c2a28f9f6cfad66b945700e5d62bd25765083241 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 22 Jan 2023 02:03:44 +0100 Subject: [PATCH 0856/1522] Cleanup: quiet compiler warnings --- source/blender/blenkernel/intern/image_partial_update.cc | 2 +- source/blender/blenkernel/intern/multires.cc | 2 +- source/blender/blenkernel/intern/multires_reshape.cc | 2 +- source/blender/editors/object/object_bake.cc | 4 ++-- source/blender/makesdna/DNA_modifier_types.h | 2 ++ .../nodes/geometry/nodes/node_geo_interpolate_curves.cc | 3 --- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/intern/image_partial_update.cc b/source/blender/blenkernel/intern/image_partial_update.cc index ecf55d6b694..4de807c0706 100644 --- a/source/blender/blenkernel/intern/image_partial_update.cc +++ b/source/blender/blenkernel/intern/image_partial_update.cc @@ -276,7 +276,7 @@ struct TileChangeset { const int chunk_len = chunk_x_len * chunk_y_len; for (int chunk_index = 0; chunk_index < chunk_len; chunk_index++) { - chunk_dirty_flags_[chunk_index] = chunk_dirty_flags_[chunk_index] | + chunk_dirty_flags_[chunk_index] = chunk_dirty_flags_[chunk_index] || other.chunk_dirty_flags_[chunk_index]; } has_dirty_chunks_ |= other.has_dirty_chunks_; diff --git a/source/blender/blenkernel/intern/multires.cc b/source/blender/blenkernel/intern/multires.cc index 9b04435b91c..2c5c7ba72ee 100644 --- a/source/blender/blenkernel/intern/multires.cc +++ b/source/blender/blenkernel/intern/multires.cc @@ -751,7 +751,7 @@ static DerivedMesh *multires_dm_create_local(Scene *scene, bool alloc_paint_mask, MultiresFlags flags) { - MultiresModifierData mmd = {{nullptr}}; + MultiresModifierData mmd{}; mmd.lvl = lvl; mmd.sculptlvl = lvl; diff --git a/source/blender/blenkernel/intern/multires_reshape.cc b/source/blender/blenkernel/intern/multires_reshape.cc index 522e7632b94..536dade7463 100644 --- a/source/blender/blenkernel/intern/multires_reshape.cc +++ b/source/blender/blenkernel/intern/multires_reshape.cc @@ -84,7 +84,7 @@ bool multiresModifier_reshapeFromDeformModifier(Depsgraph *depsgraph, MultiresModifierData *mmd, ModifierData *deform_md) { - MultiresModifierData highest_mmd = *mmd; + MultiresModifierData highest_mmd = blender::dna::shallow_copy(*mmd); highest_mmd.sculptlvl = highest_mmd.totlvl; highest_mmd.lvl = highest_mmd.totlvl; highest_mmd.renderlvl = highest_mmd.totlvl; diff --git a/source/blender/editors/object/object_bake.cc b/source/blender/editors/object/object_bake.cc index 30805ff8ad2..da16c1eae60 100644 --- a/source/blender/editors/object/object_bake.cc +++ b/source/blender/editors/object/object_bake.cc @@ -221,7 +221,7 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l DerivedMesh *dm; MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); Mesh *me = (Mesh *)ob->data; - MultiresModifierData tmp_mmd = *mmd; + MultiresModifierData tmp_mmd = blender::dna::shallow_copy(*mmd); *lvl = mmd->lvl; @@ -246,7 +246,7 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l { Mesh *me = (Mesh *)ob->data; MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); - MultiresModifierData tmp_mmd = *mmd; + MultiresModifierData tmp_mmd = blender::dna::shallow_copy(*mmd); DerivedMesh *cddm = CDDM_from_mesh(me); DerivedMesh *dm; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index aa7df999cf5..fe35fea77ed 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -1094,6 +1094,8 @@ typedef struct ExplodeModifierData { } ExplodeModifierData; typedef struct MultiresModifierData { + DNA_DEFINE_CXX_METHODS(MultiresModifierData) + ModifierData modifier; char lvl, sculptlvl, renderlvl, totlvl; diff --git a/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc index 2142fa666cb..c4f275334a8 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc @@ -238,7 +238,6 @@ static void compute_point_counts_per_child(const bke::CurvesGeometry &guide_curv { const OffsetIndices guide_points_by_curve = guide_curves.points_by_curve(); threading::parallel_for(r_points_per_child.index_range(), 512, [&](const IndexRange range) { - int points_sum = 0; for (const int child_curve_i : range) { const int neighbor_count = all_neighbor_counts[child_curve_i]; if (neighbor_count == 0) { @@ -250,7 +249,6 @@ static void compute_point_counts_per_child(const bke::CurvesGeometry &guide_curv const int points_per_curve_in_group = points_per_curve_by_group.lookup_default(group, -1); if (points_per_curve_in_group != -1) { r_points_per_child[child_curve_i] = points_per_curve_in_group; - points_sum += points_per_curve_in_group; r_use_direct_interpolation[child_curve_i] = true; continue; } @@ -268,7 +266,6 @@ static void compute_point_counts_per_child(const bke::CurvesGeometry &guide_curv const int points_in_child = std::max(1, roundf(neighbor_points_weighted_sum)); r_points_per_child[child_curve_i] = points_in_child; r_use_direct_interpolation[child_curve_i] = false; - points_sum += r_points_per_child[child_curve_i]; } }); } From 4fcbfcfc96c0a3fe0a12eadcdfc56525e51eec2a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 22 Jan 2023 20:48:16 +1100 Subject: [PATCH 0857/1522] Cleanup: GCC compiler warning --- source/blender/editors/uvedit/uvedit_unwrap_ops.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc index d95655cef45..208268c71c1 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc @@ -1347,7 +1347,8 @@ static void uv_map_transform_center(const Scene *scene, float r_bounds[2][3]) { /* only operates on the edit object - this is all that's needed now */ - const int around = (v3d) ? scene->toolsettings->transform_pivot_point : V3D_AROUND_CENTER_BOUNDS; + const int around = (v3d) ? scene->toolsettings->transform_pivot_point : + int(V3D_AROUND_CENTER_BOUNDS); float bounds[2][3]; INIT_MINMAX(bounds[0], bounds[1]); From 00ac2ddca23ee7391da775563edb5685ccbf6a33 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 22 Jan 2023 20:48:17 +1100 Subject: [PATCH 0858/1522] Fix T103722: Stuck modifiers for wheel events over unfocused windows Regression in [0] caused mouse wheel events over windows without focus to use the modifier state at the point the window was de-activated. Now un-focused windows have all events release, when focused again modifier press events are set again. [0]: 8bc76bf4b957c51ddc5a13c6305f05c64b218a27 --- .../blender/windowmanager/intern/wm_window.c | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 2e5e370ae06..7e245236fe0 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -89,6 +89,20 @@ */ #define USE_WIN_ACTIVATE +/** + * When the window is de-activated, release all held modifiers. + * + * Needed so events generated over unfocused (non-active) windows don't have modifiers held. + * Since modifier press/release events aren't send to unfocused windows it's best to assume + * modifiers are not pressed. This means when modifiers *are* held, events will incorrectly + * reported as not being held. Since this is standard behavior for Linux/MS-Window, + * opt to use this. + * + * NOTE(@campbellbarton): Events generated for non-active windows are rare, + * this happens when using the mouse-wheel over an unfocused window, see: T103722. + */ +#define USE_WIN_DEACTIVATE + /* the global to talk to ghost */ static GHOST_SystemHandle g_system = NULL; #if !(defined(WIN32) || defined(__APPLE__)) @@ -1130,6 +1144,41 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt switch (type) { case GHOST_kEventWindowDeactivate: +#ifdef USE_WIN_DEACTIVATE + /* Release all held modifiers before de-activating the window. */ + if (win->eventstate->modifier != 0) { + const uint8_t keymodifier_eventstate = win->eventstate->modifier; + const uint8_t keymodifier_l = wm_ghost_modifier_query(MOD_SIDE_LEFT); + const uint8_t keymodifier_r = wm_ghost_modifier_query(MOD_SIDE_RIGHT); + /* NOTE(@campbellbarton): when non-zero, there are modifiers held in + * `win->eventstate` which are not considered held by the GHOST internal state. + * While this should not happen, it's important all modifier held in event-state + * receive release events. Without this, so any events generated while the window + * is *not* active will have modifiers held. */ + const uint8_t keymodifier_unhandled = keymodifier_eventstate & + ~(keymodifier_l | keymodifier_r); + const uint8_t keymodifier_sided[2] = { + keymodifier_l | keymodifier_unhandled, + keymodifier_r, + }; + GHOST_TEventKeyData kdata = { + .key = GHOST_kKeyUnknown, + .utf8_buf = {'\0'}, + .is_repeat = false, + }; + for (int i = 0; i < ARRAY_SIZE(g_modifier_table); i++) { + if (keymodifier_eventstate & g_modifier_table[i].flag) { + for (int side = 0; side < 2; side++) { + if ((keymodifier_sided[side] & g_modifier_table[i].flag) == 0) { + kdata.key = g_modifier_table[i].ghost_key_pair[side]; + wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, &kdata); + } + } + } + } + } +#endif /* USE_WIN_DEACTIVATE */ + wm_event_add_ghostevent(wm, win, type, data); win->active = 0; /* XXX */ break; From 537db96fb7e35c3dbc731df3546a842f7ec606a4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 22 Jan 2023 21:06:10 +1100 Subject: [PATCH 0859/1522] GHOST/NDOF: don't send button events when there is no active window NDOF events without an active window were ignored and printed warnings in the console. --- intern/ghost/intern/GHOST_NDOFManager.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/intern/ghost/intern/GHOST_NDOFManager.cpp b/intern/ghost/intern/GHOST_NDOFManager.cpp index 5484da82a18..ffd9c57803c 100644 --- a/intern/ghost/intern/GHOST_NDOFManager.cpp +++ b/intern/ghost/intern/GHOST_NDOFManager.cpp @@ -464,12 +464,17 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, uint64_t tim ndof_button_names[button]); GHOST_IWindow *window = system_.getWindowManager()->getActiveWindow(); - const GHOST_TKey key = ghost_map_keyboard_from_ndof_buttom(button); - if (key != GHOST_kKeyUnknown) { - sendKeyEvent(key, press, time, window); - } - else { - sendButtonEvent(button, press, time, window); + + /* Delivery will fail, so don't bother sending. + * Do, however update the buttons internal depressed state. */ + if (window != nullptr) { + const GHOST_TKey key = ghost_map_keyboard_from_ndof_buttom(button); + if (key != GHOST_kKeyUnknown) { + sendKeyEvent(key, press, time, window); + } + else { + sendButtonEvent(button, press, time, window); + } } int mask = 1 << button_number; @@ -547,9 +552,11 @@ bool GHOST_NDOFManager::sendMotionEvent() GHOST_IWindow *window = system_.getWindowManager()->getActiveWindow(); + /* Delivery will fail, so don't bother sending. */ if (window == nullptr) { - motion_state_ = GHOST_kNotStarted; /* Avoid large `dt` times when changing windows. */ - return false; /* Delivery will fail, so don't bother sending. */ + /* Avoid large `dt` times when changing windows. */ + motion_state_ = GHOST_kNotStarted; + return false; } GHOST_EventNDOFMotion *event = new GHOST_EventNDOFMotion(motion_time_, window); From b544199c566bbb9529b5925ce96ae2d2abbf04c1 Mon Sep 17 00:00:00 2001 From: Howard Trickey Date: Sun, 22 Jan 2023 10:28:12 -0500 Subject: [PATCH 0860/1522] Fix T102532: bevel spikes with loop slide. There's a compromise of a code parameter called BEVEL_GOOD_ANGLE, and bugs T44961, T86768, T95335, and this one, are all about problems with various values of that parameter. If an angle of an adjacent non-beveled edge is too close to that of the beveled edge, then you get spikes. The BEVEL_GOOD_ANGLE says that if you are within that angle difference, then no bevel happens. If the value is too small then one gets spikes for certain models people build; if the value is too large, then other people are annoyed that no bevel happens. Hopefully this compromise in this commit is the final one I will do before switching to Bevel v2, where none of this should be an issue. --- source/blender/bmesh/tools/bmesh_bevel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index d3888e31da6..9e17efb2cd0 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -1506,7 +1506,7 @@ static void offset_meet(BevelParams *bp, * Update: changed again from 0.0001f to fix bug T95335. * Original two bugs remained fixed. */ -#define BEVEL_GOOD_ANGLE 0.001f +#define BEVEL_GOOD_ANGLE 0.1f /** * Calculate the meeting point between e1 and e2 (one of which should have zero offsets), From 3a2899cc31777308dd16d1f0e6916499564df711 Mon Sep 17 00:00:00 2001 From: Howard Trickey Date: Sun, 22 Jan 2023 12:48:45 -0500 Subject: [PATCH 0861/1522] Fix T103942 ASAN crash in math_boolean function. The code in questions comes from Shewchuk's triangle code, which hasn't been updated to fix the out-of-buffer access problem that ASAN finds in the delaunay unit test. The problem is benign: the code would exit the loop before using the value fetched from beyond the end of the buffer, but to make ASAN happy, I put in a couple extra tests to not fetch values that aren't going to be used. --- source/blender/blenlib/intern/math_boolean.cc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/source/blender/blenlib/intern/math_boolean.cc b/source/blender/blenlib/intern/math_boolean.cc index 689c23ce092..7c0cf165174 100644 --- a/source/blender/blenlib/intern/math_boolean.cc +++ b/source/blender/blenlib/intern/math_boolean.cc @@ -501,11 +501,15 @@ static int fast_expansion_sum_zeroelim( while ((eindex < elen) && (findex < flen)) { if ((fnow > enow) == (fnow > -enow)) { Two_Sum(Q, enow, Qnew, hh); - enow = e[++eindex]; + if (++eindex < elen) { + enow = e[eindex]; + } } else { Two_Sum(Q, fnow, Qnew, hh); - fnow = f[++findex]; + if (++findex < flen) { + fnow = f[findex]; + } } Q = Qnew; if (hh != 0.0) { @@ -515,7 +519,9 @@ static int fast_expansion_sum_zeroelim( } while (eindex < elen) { Two_Sum(Q, enow, Qnew, hh); - enow = e[++eindex]; + if (++eindex < elen) { + enow = e[eindex]; + } Q = Qnew; if (hh != 0.0) { h[hindex++] = hh; @@ -523,7 +529,9 @@ static int fast_expansion_sum_zeroelim( } while (findex < flen) { Two_Sum(Q, fnow, Qnew, hh); - fnow = f[++findex]; + if (++findex < flen) { + fnow = f[findex]; + } Q = Qnew; if (hh != 0.0) { h[hindex++] = hh; From e2006f15a94253dadeef487f552f84ad950727e9 Mon Sep 17 00:00:00 2001 From: Erik Abrahamsson Date: Sun, 22 Jan 2023 23:32:19 +0100 Subject: [PATCH 0862/1522] Fix T103618: GN Transform modifies source VDB grid The call to BKE_volume_grid_openvdb_for_write() was accidentally removed in D15806. This adds it to BKE_volume_grid_transform_matrix_set() to avoid that it happens again when that function is used. Differential Revision: D16949 --- source/blender/blenkernel/BKE_volume.h | 4 +++- source/blender/blenkernel/intern/volume.cc | 6 ++++-- .../nodes/geometry/nodes/node_geo_transform_geometry.cc | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/BKE_volume.h b/source/blender/blenkernel/BKE_volume.h index 00b5993c5eb..d300d08da91 100644 --- a/source/blender/blenkernel/BKE_volume.h +++ b/source/blender/blenkernel/BKE_volume.h @@ -114,7 +114,9 @@ int BKE_volume_grid_channels(const struct VolumeGrid *grid); * Transformation from index space to object space. */ void BKE_volume_grid_transform_matrix(const struct VolumeGrid *grid, float mat[4][4]); -void BKE_volume_grid_transform_matrix_set(struct VolumeGrid *volume_grid, const float mat[4][4]); +void BKE_volume_grid_transform_matrix_set(const struct Volume *volume, + struct VolumeGrid *volume_grid, + const float mat[4][4]); /* Volume Editing * diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index 050ba18db9a..0d8d66d69a9 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -1474,7 +1474,9 @@ void BKE_volume_grid_transform_matrix(const VolumeGrid *volume_grid, float mat[4 #endif } -void BKE_volume_grid_transform_matrix_set(struct VolumeGrid *volume_grid, const float mat[4][4]) +void BKE_volume_grid_transform_matrix_set(const Volume *volume, + VolumeGrid *volume_grid, + const float mat[4][4]) { #ifdef WITH_OPENVDB openvdb::math::Mat4f mat_openvdb; @@ -1483,7 +1485,7 @@ void BKE_volume_grid_transform_matrix_set(struct VolumeGrid *volume_grid, const mat_openvdb(col, row) = mat[col][row]; } } - openvdb::GridBase::Ptr grid = volume_grid->grid(); + openvdb::GridBase::Ptr grid = BKE_volume_grid_openvdb_for_write(volume, volume_grid, false); grid->setTransform(std::make_shared( std::make_shared(mat_openvdb))); #else diff --git a/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc index 281ffc768ef..123b02daf02 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_transform_geometry.cc @@ -142,7 +142,7 @@ static void transform_volume(GeoNodeExecParams ¶ms, normalize_v3(grid_matrix.values[2]); } } - BKE_volume_grid_transform_matrix_set(volume_grid, grid_matrix.values); + BKE_volume_grid_transform_matrix_set(&volume, volume_grid, grid_matrix.values); } if (found_too_small_scale) { params.error_message_add(NodeWarningType::Warning, From 4bef5f3df700b43012667c58a74a25a2e252a670 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 23 Jan 2023 00:32:39 +0100 Subject: [PATCH 0863/1522] Cleanup: move some undo related files to C++ For continued testing in D14139. Also see T103343. --- source/blender/blenkernel/BKE_undo_system.h | 3 +- source/blender/blenkernel/CMakeLists.txt | 6 +- .../{blender_undo.c => blender_undo.cc} | 20 +- .../intern/{blendfile.c => blendfile.cc} | 149 +++-- .../intern/{undo_system.c => undo_system.cc} | 153 ++--- source/blender/blenloader/BLO_readfile.h | 1 + .../tests/blendfile_loading_base_test.cc | 2 +- .../blender/editors/armature/CMakeLists.txt | 2 +- ...itarmature_undo.c => editarmature_undo.cc} | 25 +- source/blender/editors/curve/CMakeLists.txt | 2 +- source/blender/editors/curve/curve_intern.h | 10 +- .../{editcurve_undo.c => editcurve_undo.cc} | 32 +- source/blender/editors/gpencil/CMakeLists.txt | 2 +- .../{gpencil_undo.c => gpencil_undo.cc} | 22 +- source/blender/editors/include/ED_armature.h | 2 +- source/blender/editors/include/ED_curve.h | 2 +- source/blender/editors/include/ED_sculpt.h | 2 +- source/blender/editors/include/ED_text.h | 2 +- .../editors/sculpt_paint/CMakeLists.txt | 2 +- .../{sculpt_undo.c => sculpt_undo.cc} | 153 +++-- .../blender/editors/space_text/CMakeLists.txt | 2 +- .../blender/editors/space_text/text_intern.h | 8 + .../space_text/{text_undo.c => text_undo.cc} | 33 +- source/blender/editors/undo/CMakeLists.txt | 9 +- .../editors/undo/{ed_undo.c => ed_undo.cc} | 116 ++-- .../undo/{memfile_undo.c => memfile_undo.cc} | 44 +- .../undo/{undo_intern.h => undo_intern.hh} | 2 +- ...do_system_types.c => undo_system_types.cc} | 2 +- .../editors/uvedit/uvedit_clipboard.cc | 4 +- source/blender/windowmanager/CMakeLists.txt | 8 +- source/blender/windowmanager/WM_api.h | 2 +- source/blender/windowmanager/WM_types.h | 2 +- .../intern/{wm_files.c => wm_files.cc} | 628 +++++++++--------- .../{wm_init_exit.c => wm_init_exit.cc} | 63 +- .../intern/wm_platform_support.h | 8 + .../blender/windowmanager/intern/wm_window.c | 2 +- source/blender/windowmanager/wm.h | 2 +- source/blender/windowmanager/wm_files.h | 2 +- 38 files changed, 786 insertions(+), 743 deletions(-) rename source/blender/blenkernel/intern/{blender_undo.c => blender_undo.cc} (85%) rename source/blender/blenkernel/intern/{blendfile.c => blendfile.cc} (88%) rename source/blender/blenkernel/intern/{undo_system.c => undo_system.cc} (86%) rename source/blender/editors/armature/{editarmature_undo.c => editarmature_undo.cc} (90%) rename source/blender/editors/curve/{editcurve_undo.c => editcurve_undo.cc} (89%) rename source/blender/editors/gpencil/{gpencil_undo.c => gpencil_undo.cc} (85%) rename source/blender/editors/sculpt_paint/{sculpt_undo.c => sculpt_undo.cc} (91%) rename source/blender/editors/space_text/{text_undo.c => text_undo.cc} (86%) rename source/blender/editors/undo/{ed_undo.c => ed_undo.cc} (89%) rename source/blender/editors/undo/{memfile_undo.c => memfile_undo.cc} (90%) rename source/blender/editors/undo/{undo_intern.h => undo_intern.hh} (91%) rename source/blender/editors/undo/{undo_system_types.c => undo_system_types.cc} (98%) rename source/blender/windowmanager/intern/{wm_files.c => wm_files.cc} (87%) rename source/blender/windowmanager/intern/{wm_init_exit.c => wm_init_exit.cc} (91%) diff --git a/source/blender/blenkernel/BKE_undo_system.h b/source/blender/blenkernel/BKE_undo_system.h index 5d1a27f8ba0..365a3a86b7c 100644 --- a/source/blender/blenkernel/BKE_undo_system.h +++ b/source/blender/blenkernel/BKE_undo_system.h @@ -93,6 +93,7 @@ typedef enum eUndoPushReturn { UNDO_PUSH_RET_SUCCESS = (1 << 0), UNDO_PUSH_RET_OVERRIDE_CHANGED = (1 << 1), } eUndoPushReturn; +ENUM_OPERATORS(eUndoPushReturn, UNDO_PUSH_RET_OVERRIDE_CHANGED) typedef void (*UndoTypeForEachIDRefFn)(void *user_data, struct UndoRefID *id_ref); @@ -137,7 +138,7 @@ typedef struct UndoType { /** * The size of the undo struct 'inherited' from #UndoStep for that specific type. Used for - * generic allocation in BKE's `undo_system.c`. */ + * generic allocation in BKE's `undo_system.cc`. */ size_t step_size; } UndoType; diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 8d6fe6c3cf7..1f4ab73911a 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -78,9 +78,9 @@ set(SRC intern/autoexec.c intern/blender.c intern/blender_copybuffer.c - intern/blender_undo.c + intern/blender_undo.cc intern/blender_user_menu.c - intern/blendfile.c + intern/blendfile.cc intern/blendfile_link_append.c intern/boids.c intern/bpath.c @@ -296,7 +296,7 @@ set(SRC intern/tracking_stabilize.c intern/tracking_util.c intern/type_conversions.cc - intern/undo_system.c + intern/undo_system.cc intern/unit.c intern/vfont.c intern/vfontdata_freetype.c diff --git a/source/blender/blenkernel/intern/blender_undo.c b/source/blender/blenkernel/intern/blender_undo.cc similarity index 85% rename from source/blender/blenkernel/intern/blender_undo.c rename to source/blender/blenkernel/intern/blender_undo.cc index f22dfc6054a..9f548c539c7 100644 --- a/source/blender/blenkernel/intern/blender_undo.c +++ b/source/blender/blenkernel/intern/blender_undo.cc @@ -63,10 +63,10 @@ bool BKE_memfile_undo_decode(MemFileUndoData *mfu, G.fileflags |= G_FILE_NO_UI; if (UNDO_DISK) { - const struct BlendFileReadParams params = {0}; - BlendFileReadReport bf_reports = {.reports = NULL}; + const BlendFileReadParams params{}; + BlendFileReadReport bf_reports{}; struct BlendFileData *bfd = BKE_blendfile_read(mfu->filepath, ¶ms, &bf_reports); - if (bfd != NULL) { + if (bfd != nullptr) { BKE_blendfile_read_setup(C, bfd, ¶ms, &bf_reports); success = true; } @@ -77,10 +77,11 @@ bool BKE_memfile_undo_decode(MemFileUndoData *mfu, if (!use_old_bmain_data) { params.skip_flags |= BLO_READ_SKIP_UNDO_OLD_MAIN; } + BlendFileReadReport blend_file_read_report{}; struct BlendFileData *bfd = BKE_blendfile_read_from_memfile( - bmain, &mfu->memfile, ¶ms, NULL); - if (bfd != NULL) { - BKE_blendfile_read_setup(C, bfd, ¶ms, &(BlendFileReadReport){NULL}); + bmain, &mfu->memfile, ¶ms, nullptr); + if (bfd != nullptr) { + BKE_blendfile_read_setup(C, bfd, ¶ms, &blend_file_read_report); success = true; } } @@ -100,7 +101,7 @@ bool BKE_memfile_undo_decode(MemFileUndoData *mfu, MemFileUndoData *BKE_memfile_undo_encode(Main *bmain, MemFileUndoData *mfu_prev) { - MemFileUndoData *mfu = MEM_callocN(sizeof(MemFileUndoData), __func__); + MemFileUndoData *mfu = MEM_cnew(__func__); /* Include recovery information since undo-data is written out as #BLENDER_QUIT_FILE. */ const int fileflags = G.fileflags | G_FILE_RECOVER_WRITE; @@ -118,13 +119,14 @@ MemFileUndoData *BKE_memfile_undo_encode(Main *bmain, MemFileUndoData *mfu_prev) BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter); BLI_path_join(filepath, sizeof(filepath), BKE_tempdir_session(), numstr); + const BlendFileWriteParams blend_file_write_params{}; /* success = */ /* UNUSED */ BLO_write_file( - bmain, filepath, fileflags, &(const struct BlendFileWriteParams){0}, NULL); + bmain, filepath, fileflags, &blend_file_write_params, nullptr); BLI_strncpy(mfu->filepath, filepath, sizeof(mfu->filepath)); } else { - MemFile *prevfile = (mfu_prev) ? &(mfu_prev->memfile) : NULL; + MemFile *prevfile = (mfu_prev) ? &(mfu_prev->memfile) : nullptr; if (prevfile) { BLO_memfile_clear_future(prevfile); } diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.cc similarity index 88% rename from source/blender/blenkernel/intern/blendfile.c rename to source/blender/blenkernel/intern/blendfile.cc index f4421fc0d1c..9ccd3e7541a 100644 --- a/source/blender/blenkernel/intern/blendfile.c +++ b/source/blender/blenkernel/intern/blendfile.cc @@ -83,7 +83,7 @@ static bool blendfile_or_libraries_versions_atleast(Main *bmain, return true; } -static bool foreach_path_clean_cb(BPathForeachPathData *UNUSED(bpath_data), +static bool foreach_path_clean_cb(BPathForeachPathData * /*bpath_data*/, char *path_dst, const char *path_src) { @@ -95,12 +95,13 @@ static bool foreach_path_clean_cb(BPathForeachPathData *UNUSED(bpath_data), /* make sure path names are correct for OS */ static void clean_paths(Main *bmain) { - BKE_bpath_foreach_path_main(&(BPathForeachPathData){ - .bmain = bmain, - .callback_function = foreach_path_clean_cb, - .flag = BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE, - .user_data = NULL, - }); + BPathForeachPathData foreach_path_data{}; + foreach_path_data.bmain = bmain; + foreach_path_data.callback_function = foreach_path_clean_cb; + foreach_path_data.flag = BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE; + foreach_path_data.user_data = nullptr; + + BKE_bpath_foreach_path_main(&foreach_path_data); LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { BLI_path_slash_native(scene->r.pic); @@ -110,7 +111,7 @@ static void clean_paths(Main *bmain) static bool wm_scene_is_visible(wmWindowManager *wm, Scene *scene) { wmWindow *win; - for (win = wm->windows.first; win; win = win->next) { + for (win = static_cast(wm->windows.first); win; win = win->next) { if (win->scene == scene) { return true; } @@ -123,7 +124,7 @@ static void setup_app_userdef(BlendFileData *bfd) if (bfd->user) { /* only here free userdef themes... */ BKE_blender_userdef_data_set_and_free(bfd->user); - bfd->user = NULL; + bfd->user = nullptr; /* Security issue: any blend file could include a USER block. * @@ -151,7 +152,7 @@ static void setup_app_data(bContext *C, BlendFileReadReport *reports) { Main *bmain = G_MAIN; - Scene *curscene = NULL; + Scene *curscene = nullptr; const bool recover = (G.fileflags & G_FILE_RECOVER_READ) != 0; const bool is_startup = params->is_startup; enum { @@ -161,12 +162,12 @@ static void setup_app_data(bContext *C, } mode; if (params->undo_direction != STEP_INVALID) { - BLI_assert(bfd->curscene != NULL); + BLI_assert(bfd->curscene != nullptr); mode = LOAD_UNDO; } - /* may happen with library files - UNDO file should never have NULL curscene (but may have a - * NULL curscreen)... */ - else if (ELEM(NULL, bfd->curscreen, bfd->curscene)) { + /* may happen with library files - UNDO file should never have nullptr curscene (but may have a + * nullptr curscreen)... */ + else if (ELEM(nullptr, bfd->curscreen, bfd->curscene)) { BKE_report(reports->reports, RPT_WARNING, "Library file, loading empty scene"); mode = LOAD_UI_OFF; } @@ -205,7 +206,7 @@ static void setup_app_data(bContext *C, * see: T43424 */ wmWindow *win; - bScreen *curscreen = NULL; + bScreen *curscreen = nullptr; ViewLayer *cur_view_layer; bool track_undo_scene; @@ -213,10 +214,10 @@ static void setup_app_data(bContext *C, SWAP(ListBase, bmain->wm, bfd->main->wm); SWAP(ListBase, bmain->workspaces, bfd->main->workspaces); SWAP(ListBase, bmain->screens, bfd->main->screens); - if (bmain->name_map != NULL) { + if (bmain->name_map != nullptr) { BKE_main_namemap_destroy(&bmain->name_map); } - if (bfd->main->name_map != NULL) { + if (bfd->main->name_map != nullptr) { BKE_main_namemap_destroy(&bfd->main->name_map); } @@ -250,14 +251,14 @@ static void setup_app_data(bContext *C, track_undo_scene = (mode == LOAD_UNDO && curscreen && curscene && bfd->main->wm.first); - if (curscene == NULL) { - curscene = bfd->main->scenes.first; + if (curscene == nullptr) { + curscene = static_cast(bfd->main->scenes.first); } /* empty file, we add a scene to make Blender work */ - if (curscene == NULL) { + if (curscene == nullptr) { curscene = BKE_scene_add(bfd->main, "Empty"); } - if (cur_view_layer == NULL) { + if (cur_view_layer == nullptr) { /* fallback to scene layer */ cur_view_layer = BKE_view_layer_default_view(curscene); } @@ -267,7 +268,7 @@ static void setup_app_data(bContext *C, * replace it with 'curscene' if its needed */ } /* and we enforce curscene to be in current screen */ - else if (win) { /* The window may be NULL in background-mode. */ + else if (win) { /* The window may be nullptr in background-mode. */ win->scene = curscene; } @@ -278,7 +279,7 @@ static void setup_app_data(bContext *C, } if (track_undo_scene) { - wmWindowManager *wm = bfd->main->wm.first; + wmWindowManager *wm = static_cast(bfd->main->wm.first); if (wm_scene_is_visible(wm, bfd->curscene) == false) { curscene = bfd->curscene; win->scene = curscene; @@ -296,7 +297,7 @@ static void setup_app_data(bContext *C, BKE_blender_globals_main_replace(bfd->main); bmain = G_MAIN; - bfd->main = NULL; + bfd->main = nullptr; CTX_data_main_set(C, bmain); @@ -306,12 +307,12 @@ static void setup_app_data(bContext *C, CTX_data_scene_set(C, curscene); } else { - CTX_wm_manager_set(C, bmain->wm.first); + CTX_wm_manager_set(C, static_cast(bmain->wm.first)); CTX_wm_screen_set(C, bfd->curscreen); CTX_data_scene_set(C, bfd->curscene); - CTX_wm_area_set(C, NULL); - CTX_wm_region_set(C, NULL); - CTX_wm_menu_set(C, NULL); + CTX_wm_area_set(C, nullptr); + CTX_wm_region_set(C, nullptr); + CTX_wm_menu_set(C, nullptr); curscene = bfd->curscene; } @@ -320,7 +321,7 @@ static void setup_app_data(bContext *C, G.fileflags = (G.fileflags & fileflags_keep) | (bfd->fileflags & ~fileflags_keep); /* this can happen when active scene was lib-linked, and doesn't exist anymore */ - if (CTX_data_scene(C) == NULL) { + if (CTX_data_scene(C) == nullptr) { wmWindow *win = CTX_wm_window(C); /* in case we don't even have a local scene, add one */ @@ -328,7 +329,7 @@ static void setup_app_data(bContext *C, BKE_scene_add(bmain, "Empty"); } - CTX_data_scene_set(C, bmain->scenes.first); + CTX_data_scene_set(C, static_cast(bmain->scenes.first)); win->scene = CTX_data_scene(C); curscene = CTX_data_scene(C); } @@ -384,7 +385,7 @@ static void setup_app_data(bContext *C, /* baseflags, groups, make depsgraph, etc */ /* first handle case if other windows have different scenes visible */ if (mode == LOAD_UI) { - wmWindowManager *wm = bmain->wm.first; + wmWindowManager *wm = static_cast(bmain->wm.first); if (wm) { LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { @@ -435,7 +436,7 @@ static void setup_app_data(bContext *C, reports->duration.lib_overrides_resync; /* We need to rebuild some of the deleted override rules (for UI feedback purpose). */ - BKE_lib_override_library_main_operations_create(bmain, true, NULL); + BKE_lib_override_library_main_operations_create(bmain, true, nullptr); } } @@ -487,7 +488,7 @@ void BKE_blendfile_read_setup(bContext *C, const struct BlendFileReadParams *params, BlendFileReadReport *reports) { - BKE_blendfile_read_setup_ex(C, bfd, params, reports, false, NULL); + BKE_blendfile_read_setup_ex(C, bfd, params, reports, false, nullptr); } struct BlendFileData *BKE_blendfile_read(const char *filepath, @@ -499,7 +500,7 @@ struct BlendFileData *BKE_blendfile_read(const char *filepath, printf("Read blend: %s\n", filepath); } - BlendFileData *bfd = BLO_read_from_file(filepath, params->skip_flags, reports); + BlendFileData *bfd = BLO_read_from_file(filepath, eBLOReadSkip(params->skip_flags), reports); if (bfd) { handle_subversion_warning(bfd->main, reports); } @@ -514,7 +515,8 @@ struct BlendFileData *BKE_blendfile_read_from_memory(const void *filebuf, const struct BlendFileReadParams *params, ReportList *reports) { - BlendFileData *bfd = BLO_read_from_memory(filebuf, filelength, params->skip_flags, reports); + BlendFileData *bfd = BLO_read_from_memory( + filebuf, filelength, eBLOReadSkip(params->skip_flags), reports); if (bfd) { /* Pass. */ } @@ -595,11 +597,13 @@ void BKE_blendfile_read_make_empty(bContext *C) UserDef *BKE_blendfile_userdef_read(const char *filepath, ReportList *reports) { BlendFileData *bfd; - UserDef *userdef = NULL; + UserDef *userdef = nullptr; - bfd = BLO_read_from_file(filepath, - BLO_READ_SKIP_ALL & ~BLO_READ_SKIP_USERDEF, - &(struct BlendFileReadReport){.reports = reports}); + BlendFileReadReport blend_file_read_reports{}; + blend_file_read_reports.reports = reports; + + bfd = BLO_read_from_file( + filepath, BLO_READ_SKIP_ALL & ~BLO_READ_SKIP_USERDEF, &blend_file_read_reports); if (bfd) { if (bfd->user) { userdef = bfd->user; @@ -616,7 +620,7 @@ UserDef *BKE_blendfile_userdef_read_from_memory(const void *filebuf, ReportList *reports) { BlendFileData *bfd; - UserDef *userdef = NULL; + UserDef *userdef = nullptr; bfd = BLO_read_from_memory( filebuf, filelength, BLO_READ_SKIP_ALL & ~BLO_READ_SKIP_USERDEF, reports); @@ -636,7 +640,7 @@ UserDef *BKE_blendfile_userdef_read_from_memory(const void *filebuf, UserDef *BKE_blendfile_userdef_from_defaults(void) { - UserDef *userdef = MEM_mallocN(sizeof(*userdef), __func__); + UserDef *userdef = MEM_cnew(__func__); memcpy(userdef, &U_default, sizeof(*userdef)); /* Add-ons. */ @@ -663,7 +667,7 @@ UserDef *BKE_blendfile_userdef_from_defaults(void) /* Theme. */ { - bTheme *btheme = MEM_mallocN(sizeof(*btheme), __func__); + bTheme *btheme = static_cast(MEM_mallocN(sizeof(*btheme), __func__)); memcpy(btheme, &U_theme_default, sizeof(*btheme)); BLI_addtail(&userdef->themes, btheme); @@ -696,16 +700,13 @@ UserDef *BKE_blendfile_userdef_from_defaults(void) bool BKE_blendfile_userdef_write(const char *filepath, ReportList *reports) { - Main *mainb = MEM_callocN(sizeof(Main), "empty main"); + Main *mainb = MEM_cnew
("empty main"); bool ok = false; - if (BLO_write_file(mainb, - filepath, - 0, - &(const struct BlendFileWriteParams){ - .use_userdef = true, - }, - reports)) { + BlendFileWriteParams params{}; + params.use_userdef = true; + + if (BLO_write_file(mainb, filepath, 0, ¶ms, reports)) { ok = true; } @@ -721,9 +722,9 @@ bool BKE_blendfile_userdef_write_app_template(const char *filepath, ReportList * * falling back to the defaults. * If the preferences exists but file reading fails - the file can be assumed corrupt * so overwriting the file is OK. */ - UserDef *userdef_default = BLI_exists(filepath) ? BKE_blendfile_userdef_read(filepath, NULL) : - NULL; - if (userdef_default == NULL) { + UserDef *userdef_default = BLI_exists(filepath) ? BKE_blendfile_userdef_read(filepath, nullptr) : + nullptr; + if (userdef_default == nullptr) { userdef_default = BKE_blendfile_userdef_from_defaults(); } @@ -742,7 +743,7 @@ bool BKE_blendfile_userdef_write_all(ReportList *reports) bool ok = true; const bool use_template_userpref = BKE_appdir_app_template_has_userpref(U.app_template); - if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL))) { + if ((cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, nullptr))) { bool ok_write; BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_USERPREF_FILE); @@ -806,18 +807,19 @@ WorkspaceConfigFileData *BKE_blendfile_workspace_config_read(const char *filepat ReportList *reports) { BlendFileData *bfd; - WorkspaceConfigFileData *workspace_config = NULL; + WorkspaceConfigFileData *workspace_config = nullptr; if (filepath) { - bfd = BLO_read_from_file( - filepath, BLO_READ_SKIP_USERDEF, &(struct BlendFileReadReport){.reports = reports}); + BlendFileReadReport blend_file_read_reports{}; + blend_file_read_reports.reports = reports; + bfd = BLO_read_from_file(filepath, BLO_READ_SKIP_USERDEF, &blend_file_read_reports); } else { bfd = BLO_read_from_memory(filebuf, filelength, BLO_READ_SKIP_USERDEF, reports); } if (bfd) { - workspace_config = MEM_callocN(sizeof(*workspace_config), __func__); + workspace_config = MEM_cnew(__func__); workspace_config->main = bfd->main; /* Only 2.80+ files have actual workspaces, don't try to use screens @@ -839,7 +841,8 @@ bool BKE_blendfile_workspace_config_write(Main *bmain, const char *filepath, Rep BKE_blendfile_write_partial_begin(bmain); - for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) { + for (WorkSpace *workspace = static_cast(bmain->workspaces.first); workspace; + workspace = static_cast(workspace->id.next)) { BKE_blendfile_write_partial_tag_ID(&workspace->id, true); } @@ -880,10 +883,10 @@ void BKE_blendfile_write_partial_tag_ID(ID *id, bool set) } } -static void blendfile_write_partial_cb(void *UNUSED(handle), Main *UNUSED(bmain), void *vid) +static void blendfile_write_partial_cb(void * /*handle*/, Main * /*bmain*/, void *vid) { if (vid) { - ID *id = vid; + ID *id = static_cast(vid); /* only tag for need-expand if not done, prevents eternal loops */ if ((id->tag & LIB_TAG_DOIT) == 0) { id->tag |= LIB_TAG_NEED_EXPAND | LIB_TAG_DOIT; @@ -901,11 +904,11 @@ bool BKE_blendfile_write_partial(Main *bmain_src, const int remap_mode, ReportList *reports) { - Main *bmain_dst = MEM_callocN(sizeof(Main), "copybuffer"); + Main *bmain_dst = MEM_cnew
("copybuffer"); ListBase *lbarray_dst[INDEX_ID_MAX], *lbarray_src[INDEX_ID_MAX]; int a, retval; - void *path_list_backup = NULL; + void *path_list_backup = nullptr; const eBPathForeachFlag path_list_flag = (BKE_BPATH_FOREACH_PATH_SKIP_LINKED | BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE); @@ -914,7 +917,7 @@ bool BKE_blendfile_write_partial(Main *bmain_src, STRNCPY(bmain_dst->filepath, bmain_src->filepath); BLO_main_expander(blendfile_write_partial_cb); - BLO_expand_main(NULL, bmain_src); + BLO_expand_main(nullptr, bmain_src); /* move over all tagged blocks */ set_listbasepointers(bmain_src, lbarray_src); @@ -923,8 +926,8 @@ bool BKE_blendfile_write_partial(Main *bmain_src, ID *id, *nextid; ListBase *lb_dst = lbarray_dst[a], *lb_src = lbarray_src[a]; - for (id = lb_src->first; id; id = nextid) { - nextid = id->next; + for (id = static_cast(lb_src->first); id; id = nextid) { + nextid = static_cast(id->next); if (id->tag & LIB_TAG_DOIT) { BLI_remlink(lb_src, id); BLI_addtail(lb_dst, id); @@ -946,13 +949,9 @@ bool BKE_blendfile_write_partial(Main *bmain_src, } /* save the buffer */ - retval = BLO_write_file(bmain_dst, - filepath, - write_flags, - &(const struct BlendFileWriteParams){ - .remap_mode = remap_mode, - }, - reports); + BlendFileWriteParams blend_file_write_params{}; + blend_file_write_params.remap_mode = eBLO_WritePathRemap(remap_mode); + retval = BLO_write_file(bmain_dst, filepath, write_flags, &blend_file_write_params, reports); if (path_list_backup) { BKE_bpath_list_restore(bmain_dst, path_list_flag, path_list_backup); @@ -966,9 +965,9 @@ bool BKE_blendfile_write_partial(Main *bmain_src, ID *id; ListBase *lb_dst = lbarray_dst[a], *lb_src = lbarray_src[a]; - while ((id = BLI_pophead(lb_src))) { + while ((id = static_cast(BLI_pophead(lb_src)))) { BLI_addtail(lb_dst, id); - id_sort_by_name(lb_dst, id, NULL); + id_sort_by_name(lb_dst, id, nullptr); } } diff --git a/source/blender/blenkernel/intern/undo_system.c b/source/blender/blenkernel/intern/undo_system.cc similarity index 86% rename from source/blender/blenkernel/intern/undo_system.c rename to source/blender/blenkernel/intern/undo_system.cc index 0c0de957773..946d94f1503 100644 --- a/source/blender/blenkernel/intern/undo_system.c +++ b/source/blender/blenkernel/intern/undo_system.cc @@ -52,14 +52,14 @@ static CLG_LogRef LOG = {"bke.undosys"}; /** \name Undo Types * \{ */ -const UndoType *BKE_UNDOSYS_TYPE_IMAGE = NULL; -const UndoType *BKE_UNDOSYS_TYPE_MEMFILE = NULL; -const UndoType *BKE_UNDOSYS_TYPE_PAINTCURVE = NULL; -const UndoType *BKE_UNDOSYS_TYPE_PARTICLE = NULL; -const UndoType *BKE_UNDOSYS_TYPE_SCULPT = NULL; -const UndoType *BKE_UNDOSYS_TYPE_TEXT = NULL; +const UndoType *BKE_UNDOSYS_TYPE_IMAGE = nullptr; +const UndoType *BKE_UNDOSYS_TYPE_MEMFILE = nullptr; +const UndoType *BKE_UNDOSYS_TYPE_PAINTCURVE = nullptr; +const UndoType *BKE_UNDOSYS_TYPE_PARTICLE = nullptr; +const UndoType *BKE_UNDOSYS_TYPE_SCULPT = nullptr; +const UndoType *BKE_UNDOSYS_TYPE_TEXT = nullptr; -static ListBase g_undo_types = {NULL, NULL}; +static ListBase g_undo_types = {nullptr, nullptr}; static const UndoType *BKE_undosys_type_from_context(bContext *C) { @@ -69,7 +69,7 @@ static const UndoType *BKE_undosys_type_from_context(bContext *C) return ut; } } - return NULL; + return nullptr; } /** \} */ @@ -115,13 +115,13 @@ static bool g_undo_callback_running = false; * * \{ */ -static void undosys_id_ref_store(void *UNUSED(user_data), UndoRefID *id_ref) +static void undosys_id_ref_store(void * /*user_data*/, UndoRefID *id_ref) { BLI_assert(id_ref->name[0] == '\0'); if (id_ref->ptr) { BLI_strncpy(id_ref->name, id_ref->ptr->name, sizeof(id_ref->name)); /* Not needed, just prevents stale data access. */ - id_ref->ptr = NULL; + id_ref->ptr = nullptr; } } @@ -129,7 +129,7 @@ static void undosys_id_ref_resolve(void *user_data, UndoRefID *id_ref) { /* NOTE: we could optimize this, * for now it's not too bad since it only runs when we access undo! */ - Main *bmain = user_data; + Main *bmain = static_cast
(user_data); ListBase *lb = which_libbase(bmain, GS(id_ref->name)); LISTBASE_FOREACH (ID *, id, lb) { if (STREQ(id_ref->name, id->name) && !ID_IS_LINKED(id)) { @@ -146,7 +146,7 @@ static bool undosys_step_encode(bContext *C, Main *bmain, UndoStack *ustack, Und bool ok = us->type->step_encode(C, bmain, us); UNDO_NESTED_CHECK_END; if (ok) { - if (us->type->step_foreach_ID_ref != NULL) { + if (us->type->step_foreach_ID_ref != nullptr) { /* Don't use from context yet because sometimes context is fake and * not all members are filled in. */ us->type->step_foreach_ID_ref(us, undosys_id_ref_store, bmain); @@ -221,7 +221,7 @@ static void undosys_step_free_and_unlink(UndoStack *ustack, UndoStep *us) #ifdef WITH_GLOBAL_UNDO_CORRECT_ORDER if (ustack->step_active_memfile == us) { - ustack->step_active_memfile = NULL; + ustack->step_active_memfile = nullptr; } #endif } @@ -235,7 +235,7 @@ static void undosys_step_free_and_unlink(UndoStack *ustack, UndoStep *us) #ifndef NDEBUG static void undosys_stack_validate(UndoStack *ustack, bool expect_non_empty) { - if (ustack->step_active != NULL) { + if (ustack->step_active != nullptr) { BLI_assert(!BLI_listbase_is_empty(&ustack->steps)); BLI_assert(BLI_findindex(&ustack->steps, ustack->step_active) != -1); } @@ -244,14 +244,14 @@ static void undosys_stack_validate(UndoStack *ustack, bool expect_non_empty) } } #else -static void undosys_stack_validate(UndoStack *UNUSED(ustack), bool UNUSED(expect_non_empty)) +static void undosys_stack_validate(UndoStack * /*ustack*/, bool /*expect_non_empty*/) { } #endif UndoStack *BKE_undosys_stack_create(void) { - UndoStack *ustack = MEM_callocN(sizeof(UndoStack), __func__); + UndoStack *ustack = MEM_cnew(__func__); return ustack; } @@ -265,12 +265,12 @@ void BKE_undosys_stack_clear(UndoStack *ustack) { UNDO_NESTED_ASSERT(false); CLOG_INFO(&LOG, 1, "steps=%d", BLI_listbase_count(&ustack->steps)); - for (UndoStep *us = ustack->steps.last, *us_prev; us; us = us_prev) { + for (UndoStep *us = static_cast(ustack->steps.last), *us_prev; us; us = us_prev) { us_prev = us->prev; undosys_step_free_and_unlink(ustack, us); } BLI_listbase_clear(&ustack->steps); - ustack->step_active = NULL; + ustack->step_active = nullptr; } void BKE_undosys_stack_clear_active(UndoStack *ustack) @@ -280,10 +280,10 @@ void BKE_undosys_stack_clear_active(UndoStack *ustack) if (us) { ustack->step_active = us->prev; - bool is_not_empty = ustack->step_active != NULL; + bool is_not_empty = ustack->step_active != nullptr; while (ustack->steps.last != ustack->step_active) { - UndoStep *us_iter = ustack->steps.last; + UndoStep *us_iter = static_cast(ustack->steps.last); undosys_step_free_and_unlink(ustack, us_iter); undosys_stack_validate(ustack, is_not_empty); } @@ -297,7 +297,7 @@ static void undosys_stack_clear_all_last(UndoStack *ustack, UndoStep *us) bool is_not_empty = true; UndoStep *us_iter; do { - us_iter = ustack->steps.last; + us_iter = static_cast(ustack->steps.last); BLI_assert(us_iter != ustack->step_active); undosys_step_free_and_unlink(ustack, us_iter); undosys_stack_validate(ustack, is_not_empty); @@ -315,7 +315,7 @@ static void undosys_stack_clear_all_first(UndoStack *ustack, UndoStep *us, UndoS bool is_not_empty = true; UndoStep *us_iter; do { - us_iter = ustack->steps.first; + us_iter = static_cast(ustack->steps.first); if (us_iter == us_exclude) { us_iter = us_iter->next; } @@ -329,7 +329,7 @@ static void undosys_stack_clear_all_first(UndoStack *ustack, UndoStep *us, UndoS static bool undosys_stack_push_main(UndoStack *ustack, const char *name, struct Main *bmain) { UNDO_NESTED_ASSERT(false); - BLI_assert(ustack->step_init == NULL); + BLI_assert(ustack->step_init == nullptr); CLOG_INFO(&LOG, 1, "'%s'", name); bContext *C_temp = CTX_create(); CTX_data_main_set(C_temp, bmain); @@ -348,7 +348,7 @@ void BKE_undosys_stack_init_from_main(UndoStack *ustack, struct Main *bmain) void BKE_undosys_stack_init_from_context(UndoStack *ustack, bContext *C) { const UndoType *ut = BKE_undosys_type_from_context(C); - if (!ELEM(ut, NULL, BKE_UNDOSYS_TYPE_MEMFILE)) { + if (!ELEM(ut, nullptr, BKE_UNDOSYS_TYPE_MEMFILE)) { BKE_undosys_step_push_with_type(ustack, C, IFACE_("Original Mode"), ut); } } @@ -356,7 +356,8 @@ void BKE_undosys_stack_init_from_context(UndoStack *ustack, bContext *C) bool BKE_undosys_stack_has_undo(const UndoStack *ustack, const char *name) { if (name) { - const UndoStep *us = BLI_rfindstring(&ustack->steps, name, offsetof(UndoStep, name)); + const UndoStep *us = static_cast( + BLI_rfindstring(&ustack->steps, name, offsetof(UndoStep, name))); return us && us->prev; } @@ -391,11 +392,11 @@ void BKE_undosys_stack_limit_steps_and_memory(UndoStack *ustack, int steps, size CLOG_INFO(&LOG, 1, "steps=%d, memory_limit=%zu", steps, memory_limit); UndoStep *us; - UndoStep *us_exclude = NULL; + UndoStep *us_exclude = nullptr; /* keep at least two (original + other) */ size_t data_size_all = 0; size_t us_count = 0; - for (us = ustack->steps.last; us && us->prev; us = us->prev) { + for (us = static_cast(ustack->steps.last); us && us->prev; us = us->prev) { if (memory_limit) { data_size_all += us->data_size; if (data_size_all > memory_limit) { @@ -447,7 +448,7 @@ UndoStep *BKE_undosys_step_push_init_with_type(UndoStack *ustack, { UNDO_NESTED_ASSERT(false); /* We could detect and clean this up (but it should never happen!). */ - BLI_assert(ustack->step_init == NULL); + BLI_assert(ustack->step_init == nullptr); if (ut->step_encode_init) { undosys_stack_validate(ustack, false); @@ -455,8 +456,8 @@ UndoStep *BKE_undosys_step_push_init_with_type(UndoStack *ustack, undosys_stack_clear_all_last(ustack, ustack->step_active->next); } - UndoStep *us = MEM_callocN(ut->step_size, __func__); - if (name != NULL) { + UndoStep *us = static_cast(MEM_callocN(ut->step_size, __func__)); + if (name != nullptr) { BLI_strncpy(us->name, name, sizeof(us->name)); } us->type = ut; @@ -467,17 +468,17 @@ UndoStep *BKE_undosys_step_push_init_with_type(UndoStack *ustack, return us; } - return NULL; + return nullptr; } UndoStep *BKE_undosys_step_push_init(UndoStack *ustack, bContext *C, const char *name) { UNDO_NESTED_ASSERT(false); /* We could detect and clean this up (but it should never happen!). */ - BLI_assert(ustack->step_init == NULL); + BLI_assert(ustack->step_init == nullptr); const UndoType *ut = BKE_undosys_type_from_context(C); - if (ut == NULL) { - return NULL; + if (ut == nullptr) { + return nullptr; } return BKE_undosys_step_push_init_with_type(ustack, C, name, ut); } @@ -487,11 +488,11 @@ eUndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack, const char *name, const UndoType *ut) { - BLI_assert((ut->flags & UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE) == 0 || C != NULL); + BLI_assert((ut->flags & UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE) == 0 || C != nullptr); UNDO_NESTED_ASSERT(false); undosys_stack_validate(ustack, false); - bool is_not_empty = ustack->step_active != NULL; + bool is_not_empty = ustack->step_active != nullptr; eUndoPushReturn retval = UNDO_PUSH_RET_FAILURE; /* Might not be final place for this to be called - probably only want to call it from some @@ -502,9 +503,9 @@ eUndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack, retval |= UNDO_PUSH_RET_OVERRIDE_CHANGED; } - /* Remove all undo-steps after (also when 'ustack->step_active == NULL'). */ + /* Remove all undo-steps after (also when 'ustack->step_active == nullptr'). */ while (ustack->steps.last != ustack->step_active) { - UndoStep *us_iter = ustack->steps.last; + UndoStep *us_iter = static_cast(ustack->steps.last); undosys_step_free_and_unlink(ustack, us_iter); undosys_stack_validate(ustack, is_not_empty); } @@ -514,17 +515,17 @@ eUndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack, } #ifdef WITH_GLOBAL_UNDO_ENSURE_UPDATED - if (ut->step_foreach_ID_ref != NULL) { + if (ut->step_foreach_ID_ref != nullptr) { if (G_MAIN->is_memfile_undo_written == false) { const char *name_internal = "MemFile Internal (pre)"; /* Don't let 'step_init' cause issues when adding memfile undo step. */ void *step_init = ustack->step_init; - ustack->step_init = NULL; + ustack->step_init = nullptr; const bool ok = undosys_stack_push_main(ustack, name_internal, G_MAIN); /* Restore 'step_init'. */ - ustack->step_init = step_init; + ustack->step_init = static_cast(step_init); if (ok) { - UndoStep *us = ustack->steps.last; + UndoStep *us = static_cast(ustack->steps.last); BLI_assert(STREQ(us->name, name_internal)); us->skip = true; # ifdef WITH_GLOBAL_UNDO_CORRECT_ORDER @@ -537,8 +538,10 @@ eUndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack, bool use_memfile_step = false; { - UndoStep *us = ustack->step_init ? ustack->step_init : MEM_callocN(ut->step_size, __func__); - ustack->step_init = NULL; + UndoStep *us = ustack->step_init ? + ustack->step_init : + static_cast(MEM_callocN(ut->step_size, __func__)); + ustack->step_init = nullptr; if (us->name[0] == '\0') { BLI_strncpy(us->name, name, sizeof(us->name)); } @@ -566,7 +569,7 @@ eUndoPushReturn BKE_undosys_step_push_with_type(UndoStack *ustack, const char *name_internal = us_prev->name; const bool ok = undosys_stack_push_main(ustack, name_internal, G_MAIN); if (ok) { - UndoStep *us = ustack->steps.last; + UndoStep *us = static_cast(ustack->steps.last); BLI_assert(STREQ(us->name, name_internal)); us_prev->skip = true; #ifdef WITH_GLOBAL_UNDO_CORRECT_ORDER @@ -591,8 +594,8 @@ eUndoPushReturn BKE_undosys_step_push(UndoStack *ustack, bContext *C, const char UNDO_NESTED_ASSERT(false); const UndoType *ut = ustack->step_init ? ustack->step_init->type : BKE_undosys_type_from_context(C); - if (ut == NULL) { - return false; + if (ut == nullptr) { + return UNDO_PUSH_RET_FAILURE; } return BKE_undosys_step_push_with_type(ustack, C, name, ut); } @@ -627,40 +630,40 @@ UndoStep *BKE_undosys_step_find_by_name_with_type(UndoStack *ustack, const char *name, const UndoType *ut) { - for (UndoStep *us = ustack->steps.last; us; us = us->prev) { + for (UndoStep *us = static_cast(ustack->steps.last); us; us = us->prev) { if (us->type == ut) { if (STREQ(name, us->name)) { return us; } } } - return NULL; + return nullptr; } UndoStep *BKE_undosys_step_find_by_name(UndoStack *ustack, const char *name) { - return BLI_rfindstring(&ustack->steps, name, offsetof(UndoStep, name)); + return static_cast(BLI_rfindstring(&ustack->steps, name, offsetof(UndoStep, name))); } UndoStep *BKE_undosys_step_find_by_type(UndoStack *ustack, const UndoType *ut) { - for (UndoStep *us = ustack->steps.last; us; us = us->prev) { + for (UndoStep *us = static_cast(ustack->steps.last); us; us = us->prev) { if (us->type == ut) { return us; } } - return NULL; + return nullptr; } eUndoStepDir BKE_undosys_step_calc_direction(const UndoStack *ustack, const UndoStep *us_target, const UndoStep *us_reference) { - if (us_reference == NULL) { + if (us_reference == nullptr) { us_reference = ustack->step_active; } - BLI_assert(us_reference != NULL); + BLI_assert(us_reference != nullptr); /* Note that we use heuristics to make this lookup as fast as possible in most common cases, * assuming that: @@ -676,12 +679,12 @@ eUndoStepDir BKE_undosys_step_calc_direction(const UndoStack *ustack, } /* Search forward, and then backward. */ - for (UndoStep *us_iter = us_reference->next; us_iter != NULL; us_iter = us_iter->next) { + for (UndoStep *us_iter = us_reference->next; us_iter != nullptr; us_iter = us_iter->next) { if (us_iter == us_target) { return STEP_REDO; } } - for (UndoStep *us_iter = us_reference->prev; us_iter != NULL; us_iter = us_iter->prev) { + for (UndoStep *us_iter = us_reference->prev; us_iter != nullptr; us_iter = us_iter->prev) { if (us_iter == us_target) { return STEP_UNDO; } @@ -718,16 +721,16 @@ bool BKE_undosys_step_load_data_ex(UndoStack *ustack, const bool use_skip) { UNDO_NESTED_ASSERT(false); - if (us_target == NULL) { - CLOG_ERROR(&LOG, "called with a NULL target step"); + if (us_target == nullptr) { + CLOG_ERROR(&LOG, "called with a nullptr target step"); return false; } undosys_stack_validate(ustack, true); - if (us_reference == NULL) { + if (us_reference == nullptr) { us_reference = ustack->step_active; } - if (us_reference == NULL) { + if (us_reference == nullptr) { CLOG_ERROR(&LOG, "could not find a valid initial active target step as reference"); return false; } @@ -742,10 +745,10 @@ bool BKE_undosys_step_load_data_ex(UndoStack *ustack, * the one passed as parameter. */ UndoStep *us_target_active = us_target; if (use_skip) { - while (us_target_active != NULL && us_target_active->skip) { + while (us_target_active != nullptr && us_target_active->skip) { us_target_active = (undo_dir == -1) ? us_target_active->prev : us_target_active->next; } - if (us_target_active == NULL) { + if (us_target_active == nullptr) { CLOG_INFO(&LOG, 2, "undo/redo did not find a step after stepping over skip-steps " @@ -765,9 +768,9 @@ bool BKE_undosys_step_load_data_ex(UndoStack *ustack, /* Undo/Redo steps until we reach given target step (or beyond if it has to be skipped), * from given reference step. */ bool is_processing_extra_skipped_steps = false; - for (UndoStep *us_iter = undosys_step_iter_first(us_reference, undo_dir); us_iter != NULL; + for (UndoStep *us_iter = undosys_step_iter_first(us_reference, undo_dir); us_iter != nullptr; us_iter = (undo_dir == -1) ? us_iter->prev : us_iter->next) { - BLI_assert(us_iter != NULL); + BLI_assert(us_iter != nullptr); const bool is_final = (us_iter == us_target_active); @@ -802,12 +805,12 @@ bool BKE_undosys_step_load_data_ex(UndoStack *ustack, bool BKE_undosys_step_load_data(UndoStack *ustack, bContext *C, UndoStep *us_target) { /* Note that here we do not skip 'skipped' steps by default. */ - return BKE_undosys_step_load_data_ex(ustack, C, us_target, NULL, false); + return BKE_undosys_step_load_data_ex(ustack, C, us_target, nullptr, false); } void BKE_undosys_step_load_from_index(UndoStack *ustack, bContext *C, const int index) { - UndoStep *us_target = BLI_findlink(&ustack->steps, index); + UndoStep *us_target = static_cast(BLI_findlink(&ustack->steps, index)); BLI_assert(us_target->skip == false); if (us_target == ustack->step_active) { return; @@ -823,7 +826,7 @@ bool BKE_undosys_step_undo_with_data_ex(UndoStack *ustack, /* In case there is no active step, we consider we just load given step, so reference must be * itself (due to weird 'load current active step in undo case' thing, see comments in * #BKE_undosys_step_load_data_ex). */ - UndoStep *us_reference = ustack->step_active != NULL ? ustack->step_active : us_target; + UndoStep *us_reference = ustack->step_active != nullptr ? ustack->step_active : us_target; BLI_assert(BKE_undosys_step_calc_direction(ustack, us_target, us_reference) == -1); @@ -837,7 +840,7 @@ bool BKE_undosys_step_undo_with_data(UndoStack *ustack, bContext *C, UndoStep *u bool BKE_undosys_step_undo(UndoStack *ustack, bContext *C) { - if (ustack->step_active != NULL) { + if (ustack->step_active != nullptr) { return BKE_undosys_step_undo_with_data(ustack, C, ustack->step_active->prev); } return false; @@ -850,7 +853,7 @@ bool BKE_undosys_step_redo_with_data_ex(UndoStack *ustack, { /* In case there is no active step, we consider we just load given step, so reference must be * the previous one. */ - UndoStep *us_reference = ustack->step_active != NULL ? ustack->step_active : us_target->prev; + UndoStep *us_reference = ustack->step_active != nullptr ? ustack->step_active : us_target->prev; BLI_assert(BKE_undosys_step_calc_direction(ustack, us_target, us_reference) == 1); @@ -864,7 +867,7 @@ bool BKE_undosys_step_redo_with_data(UndoStack *ustack, bContext *C, UndoStep *u bool BKE_undosys_step_redo(UndoStack *ustack, bContext *C) { - if (ustack->step_active != NULL) { + if (ustack->step_active != nullptr) { return BKE_undosys_step_redo_with_data(ustack, C, ustack->step_active->next); } return false; @@ -872,9 +875,7 @@ bool BKE_undosys_step_redo(UndoStack *ustack, bContext *C) UndoType *BKE_undosys_type_append(void (*undosys_fn)(UndoType *)) { - UndoType *ut; - - ut = MEM_callocN(sizeof(UndoType), __func__); + UndoType *ut = MEM_cnew(__func__); undosys_fn(ut); @@ -886,7 +887,7 @@ UndoType *BKE_undosys_type_append(void (*undosys_fn)(UndoType *)) void BKE_undosys_type_free_all(void) { UndoType *ut; - while ((ut = BLI_pophead(&g_undo_types))) { + while ((ut = static_cast(BLI_pophead(&g_undo_types)))) { MEM_freeN(ut); } } @@ -924,7 +925,7 @@ void BKE_undosys_stack_group_end(UndoStack *ustack) BLI_assert(ustack->group_level >= 0); if (ustack->group_level == 0) { - if (LIKELY(ustack->step_active != NULL)) { + if (LIKELY(ustack->step_active != nullptr)) { ustack->step_active->skip = false; } } @@ -944,7 +945,7 @@ static void UNUSED_FUNCTION(BKE_undosys_foreach_ID_ref(UndoStack *ustack, { LISTBASE_FOREACH (UndoStep *, us, &ustack->steps) { const UndoType *ut = us->type; - if (ut->step_foreach_ID_ref != NULL) { + if (ut->step_foreach_ID_ref != nullptr) { ut->step_foreach_ID_ref(us, foreach_ID_ref_fn, user_data); } } diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 850aff20a1b..8b5f9d10044 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -122,6 +122,7 @@ typedef enum eBLOReadSkip { /** Do not attempt to re-use IDs from old bmain for unchanged ones in case of undo. */ BLO_READ_SKIP_UNDO_OLD_MAIN = (1 << 2), } eBLOReadSkip; +ENUM_OPERATORS(eBLOReadSkip, BLO_READ_SKIP_UNDO_OLD_MAIN) #define BLO_READ_SKIP_ALL (BLO_READ_SKIP_USERDEF | BLO_READ_SKIP_DATA) /** diff --git a/source/blender/blenloader/tests/blendfile_loading_base_test.cc b/source/blender/blenloader/tests/blendfile_loading_base_test.cc index b657970d45f..6f190ce427e 100644 --- a/source/blender/blenloader/tests/blendfile_loading_base_test.cc +++ b/source/blender/blenloader/tests/blendfile_loading_base_test.cc @@ -81,7 +81,7 @@ void BlendfileLoadingBaseTest::TearDownTestCase() G.main->wm.first = nullptr; } - /* Copied from WM_exit_ex() in wm_init_exit.c, and cherry-picked those lines that match the + /* Copied from WM_exit_ex() in wm_init_exit.cc, and cherry-picked those lines that match the * allocation/initialization done in SetUpTestCase(). */ BKE_blender_free(); RNA_exit(); diff --git a/source/blender/editors/armature/CMakeLists.txt b/source/blender/editors/armature/CMakeLists.txt index 4eb07c3bdee..87df2c4bff0 100644 --- a/source/blender/editors/armature/CMakeLists.txt +++ b/source/blender/editors/armature/CMakeLists.txt @@ -31,7 +31,7 @@ set(SRC armature_select.c armature_skinning.c armature_utils.c - editarmature_undo.c + editarmature_undo.cc meshlaplacian.cc pose_edit.c pose_group.c diff --git a/source/blender/editors/armature/editarmature_undo.c b/source/blender/editors/armature/editarmature_undo.cc similarity index 90% rename from source/blender/editors/armature/editarmature_undo.c rename to source/blender/editors/armature/editarmature_undo.cc index 379ad4f5376..9db59042663 100644 --- a/source/blender/editors/armature/editarmature_undo.c +++ b/source/blender/editors/armature/editarmature_undo.cc @@ -60,7 +60,7 @@ static void undoarm_to_editarm(UndoArmature *uarm, bArmature *arm) arm->act_edbone = ebone->temp.ebone; } else { - arm->act_edbone = NULL; + arm->act_edbone = nullptr; } ED_armature_ebone_listbase_temp_clear(arm->edbo); @@ -102,12 +102,12 @@ static Object *editarm_object_from_context(bContext *C) BKE_view_layer_synced_ensure(scene, view_layer); Object *obedit = BKE_view_layer_edit_object_get(view_layer); if (obedit && obedit->type == OB_ARMATURE) { - bArmature *arm = obedit->data; - if (arm->edbo != NULL) { + bArmature *arm = static_cast(obedit->data); + if (arm->edbo != nullptr) { return obedit; } } - return NULL; + return nullptr; } /** \} */ @@ -132,7 +132,7 @@ typedef struct ArmatureUndoStep { static bool armature_undosys_poll(bContext *C) { - return editarm_object_from_context(C) != NULL; + return editarm_object_from_context(C) != nullptr; } static bool armature_undosys_step_encode(struct bContext *C, struct Main *bmain, UndoStep *us_p) @@ -146,7 +146,8 @@ static bool armature_undosys_step_encode(struct bContext *C, struct Main *bmain, uint objects_len = 0; Object **objects = ED_undo_editmode_objects_from_view_layer(scene, view_layer, &objects_len); - us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__); + us->elems = static_cast( + MEM_callocN(sizeof(*us->elems) * objects_len, __func__)); us->elems_len = objects_len; for (uint i = 0; i < objects_len; i++) { @@ -154,7 +155,7 @@ static bool armature_undosys_step_encode(struct bContext *C, struct Main *bmain, ArmatureUndoStep_Elem *elem = &us->elems[i]; elem->obedit_ref.ptr = ob; - bArmature *arm = elem->obedit_ref.ptr->data; + bArmature *arm = static_cast(elem->obedit_ref.ptr->data); undoarm_from_editarm(&elem->data, arm); arm->needs_flush_to_id = 1; us->step.data_size += elem->data.undo_size; @@ -169,8 +170,8 @@ static bool armature_undosys_step_encode(struct bContext *C, struct Main *bmain, static void armature_undosys_step_decode(struct bContext *C, struct Main *bmain, UndoStep *us_p, - const eUndoStepDir UNUSED(dir), - bool UNUSED(is_final)) + const eUndoStepDir /*dir*/, + bool /*is_final*/) { ArmatureUndoStep *us = (ArmatureUndoStep *)us_p; @@ -182,8 +183,8 @@ static void armature_undosys_step_decode(struct bContext *C, for (uint i = 0; i < us->elems_len; i++) { ArmatureUndoStep_Elem *elem = &us->elems[i]; Object *obedit = elem->obedit_ref.ptr; - bArmature *arm = obedit->data; - if (arm->edbo == NULL) { + bArmature *arm = static_cast(obedit->data); + if (arm->edbo == nullptr) { /* Should never fail, may not crash but can give odd behavior. */ CLOG_ERROR(&LOG, "name='%s', failed to enter edit-mode for object '%s', undo state invalid", @@ -205,7 +206,7 @@ static void armature_undosys_step_decode(struct bContext *C, bmain->is_memfile_undo_flush_needed = true; - WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, nullptr); } static void armature_undosys_step_free(UndoStep *us_p) diff --git a/source/blender/editors/curve/CMakeLists.txt b/source/blender/editors/curve/CMakeLists.txt index 90a77750860..6b46c822e86 100644 --- a/source/blender/editors/curve/CMakeLists.txt +++ b/source/blender/editors/curve/CMakeLists.txt @@ -28,7 +28,7 @@ set(SRC editcurve_pen.c editcurve_query.c editcurve_select.c - editcurve_undo.c + editcurve_undo.cc editfont.c editfont_undo.c diff --git a/source/blender/editors/curve/curve_intern.h b/source/blender/editors/curve/curve_intern.h index 38fe2d92772..f52fd03aaae 100644 --- a/source/blender/editors/curve/curve_intern.h +++ b/source/blender/editors/curve/curve_intern.h @@ -15,6 +15,10 @@ struct Object; struct ViewContext; struct wmOperatorType; +#ifdef __cplusplus +extern "C" { +#endif + /* editfont.c */ enum { @@ -129,7 +133,7 @@ void CURVE_OT_cyclic_toggle(struct wmOperatorType *ot); void CURVE_OT_match_texture_space(struct wmOperatorType *ot); -/* exported for editcurve_undo.c */ +/* exported for editcurve_undo.cc */ struct GHash *ED_curve_keyindex_hash_duplicate(struct GHash *keyindex); void ED_curve_keyindex_update_nurb(struct EditNurb *editnurb, struct Nurb *nu, struct Nurb *newnu); @@ -227,3 +231,7 @@ void CURVE_OT_draw(struct wmOperatorType *ot); void CURVE_OT_pen(struct wmOperatorType *ot); struct wmKeyMap *curve_pen_modal_keymap(struct wmKeyConfig *keyconf); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/editors/curve/editcurve_undo.c b/source/blender/editors/curve/editcurve_undo.cc similarity index 89% rename from source/blender/editors/curve/editcurve_undo.c rename to source/blender/editors/curve/editcurve_undo.cc index 3f53a88ba5d..41b5f54ac6e 100644 --- a/source/blender/editors/curve/editcurve_undo.c +++ b/source/blender/editors/curve/editcurve_undo.cc @@ -84,7 +84,7 @@ static void undocurve_to_editcurve(Main *bmain, UndoCurve *ucu, Curve *cu, short } /* Copy. */ - for (nu = undobase->first; nu; nu = nu->next) { + for (nu = static_cast(undobase->first); nu; nu = nu->next) { newnu = BKE_nurb_duplicate(nu); if (editnurb->keyindex) { @@ -126,7 +126,7 @@ static void undocurve_from_editcurve(UndoCurve *ucu, Curve *cu, const short shap } /* Copy. */ - for (nu = nubase->first; nu; nu = nu->next) { + for (nu = static_cast(nubase->first); nu; nu = nu->next) { newnu = BKE_nurb_duplicate(nu); if (ucu->undoIndex) { @@ -165,12 +165,12 @@ static Object *editcurve_object_from_context(bContext *C) BKE_view_layer_synced_ensure(scene, view_layer); Object *obedit = BKE_view_layer_edit_object_get(view_layer); if (obedit && ELEM(obedit->type, OB_CURVES_LEGACY, OB_SURF)) { - Curve *cu = obedit->data; - if (BKE_curve_editNurbs_get(cu) != NULL) { + Curve *cu = static_cast(obedit->data); + if (BKE_curve_editNurbs_get(cu) != nullptr) { return obedit; } } - return NULL; + return nullptr; } /** \} */ @@ -195,7 +195,7 @@ typedef struct CurveUndoStep { static bool curve_undosys_poll(bContext *C) { Object *obedit = editcurve_object_from_context(C); - return (obedit != NULL); + return (obedit != nullptr); } static bool curve_undosys_step_encode(struct bContext *C, struct Main *bmain, UndoStep *us_p) @@ -209,16 +209,17 @@ static bool curve_undosys_step_encode(struct bContext *C, struct Main *bmain, Un uint objects_len = 0; Object **objects = ED_undo_editmode_objects_from_view_layer(scene, view_layer, &objects_len); - us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__); + us->elems = static_cast( + MEM_callocN(sizeof(*us->elems) * objects_len, __func__)); us->elems_len = objects_len; for (uint i = 0; i < objects_len; i++) { Object *ob = objects[i]; - Curve *cu = ob->data; + Curve *cu = static_cast(ob->data); CurveUndoStep_Elem *elem = &us->elems[i]; elem->obedit_ref.ptr = ob; - undocurve_from_editcurve(&elem->data, ob->data, ob->shapenr); + undocurve_from_editcurve(&elem->data, static_cast(ob->data), ob->shapenr); cu->editnurb->needs_flush_to_id = 1; us->step.data_size += elem->data.undo_size; } @@ -232,8 +233,8 @@ static bool curve_undosys_step_encode(struct bContext *C, struct Main *bmain, Un static void curve_undosys_step_decode(struct bContext *C, struct Main *bmain, UndoStep *us_p, - const eUndoStepDir UNUSED(dir), - bool UNUSED(is_final)) + const eUndoStepDir /*dir*/, + bool /*is_final*/) { CurveUndoStep *us = (CurveUndoStep *)us_p; @@ -245,8 +246,8 @@ static void curve_undosys_step_decode(struct bContext *C, for (uint i = 0; i < us->elems_len; i++) { CurveUndoStep_Elem *elem = &us->elems[i]; Object *obedit = elem->obedit_ref.ptr; - Curve *cu = obedit->data; - if (cu->editnurb == NULL) { + Curve *cu = static_cast(obedit->data); + if (cu->editnurb == nullptr) { /* Should never fail, may not crash but can give odd behavior. */ CLOG_ERROR(&LOG, "name='%s', failed to enter edit-mode for object '%s', undo state invalid", @@ -254,7 +255,8 @@ static void curve_undosys_step_decode(struct bContext *C, obedit->id.name); continue; } - undocurve_to_editcurve(bmain, &elem->data, obedit->data, &obedit->shapenr); + undocurve_to_editcurve( + bmain, &elem->data, static_cast(obedit->data), &obedit->shapenr); cu->editnurb->needs_flush_to_id = 1; DEG_id_tag_update(&cu->id, ID_RECALC_GEOMETRY); } @@ -268,7 +270,7 @@ static void curve_undosys_step_decode(struct bContext *C, bmain->is_memfile_undo_flush_needed = true; - WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, nullptr); } static void curve_undosys_step_free(UndoStep *us_p) diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt index d3dde9ea800..af2ad0b7536 100644 --- a/source/blender/editors/gpencil/CMakeLists.txt +++ b/source/blender/editors/gpencil/CMakeLists.txt @@ -46,7 +46,7 @@ set(SRC gpencil_primitive.c gpencil_sculpt_paint.c gpencil_select.c - gpencil_undo.c + gpencil_undo.cc gpencil_utils.c gpencil_uv.c gpencil_vertex_ops.c diff --git a/source/blender/editors/gpencil/gpencil_undo.c b/source/blender/editors/gpencil/gpencil_undo.cc similarity index 85% rename from source/blender/editors/gpencil/gpencil_undo.c rename to source/blender/editors/gpencil/gpencil_undo.cc index d6399852603..1062c2edc6b 100644 --- a/source/blender/editors/gpencil/gpencil_undo.c +++ b/source/blender/editors/gpencil/gpencil_undo.cc @@ -38,8 +38,8 @@ typedef struct bGPundonode { struct bGPdata *gpd; } bGPundonode; -static ListBase undo_nodes = {NULL, NULL}; -static bGPundonode *cur_node = NULL; +static ListBase undo_nodes = {nullptr, nullptr}; +static bGPundonode *cur_node = nullptr; int ED_gpencil_session_active(void) { @@ -48,9 +48,9 @@ int ED_gpencil_session_active(void) int ED_undo_gpencil_step(bContext *C, const int step) { - bGPdata **gpd_ptr = NULL, *new_gpd = NULL; + bGPdata **gpd_ptr = nullptr, *new_gpd = nullptr; - gpd_ptr = ED_gpencil_data_get_pointers(C, NULL); + gpd_ptr = ED_gpencil_data_get_pointers(C, nullptr); const eUndoStepDir undo_step = (eUndoStepDir)step; if (undo_step == STEP_UNDO) { @@ -89,7 +89,7 @@ int ED_undo_gpencil_step(bContext *C, const int step) new_gpd->flag |= GP_DATA_CACHE_IS_DIRTY; } - WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, NULL); + WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, nullptr); return OPERATOR_FINISHED; } @@ -104,7 +104,7 @@ static void gpencil_undo_free_node(bGPundonode *undo_node) /* HACK: animdata wasn't duplicated, so it shouldn't be freed here, * or else the real copy will segfault when accessed */ - undo_node->gpd->adt = NULL; + undo_node->gpd->adt = nullptr; BKE_gpencil_free_data(undo_node->gpd, false); MEM_freeN(undo_node->gpd); @@ -138,7 +138,7 @@ void gpencil_undo_push(bGPdata *gpd) /* remove anything older than n-steps before cur_node */ int steps = 0; - undo_node = (cur_node) ? cur_node : undo_nodes.last; + undo_node = (cur_node) ? cur_node : static_cast(undo_nodes.last); while (undo_node) { bGPundonode *prev_node = undo_node->prev; @@ -153,8 +153,8 @@ void gpencil_undo_push(bGPdata *gpd) } /* create new undo node */ - undo_node = MEM_callocN(sizeof(bGPundonode), "gpencil undo node"); - undo_node->gpd = BKE_gpencil_data_duplicate(NULL, gpd, true); + undo_node = MEM_cnew("gpencil undo node"); + undo_node->gpd = BKE_gpencil_data_duplicate(nullptr, gpd, true); cur_node = undo_node; @@ -163,7 +163,7 @@ void gpencil_undo_push(bGPdata *gpd) void gpencil_undo_finish(void) { - bGPundonode *undo_node = undo_nodes.first; + bGPundonode *undo_node = static_cast(undo_nodes.first); while (undo_node) { gpencil_undo_free_node(undo_node); @@ -172,5 +172,5 @@ void gpencil_undo_finish(void) BLI_freelistN(&undo_nodes); - cur_node = NULL; + cur_node = nullptr; } diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 128ba43e3ec..13908d63bb6 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -205,7 +205,7 @@ void ED_object_vgroup_calc_from_armature(struct ReportList *reports, int mode, bool mirror); -/* editarmature_undo.c */ +/* editarmature_undo.cc */ /** Export for ED_undo_sys. */ void ED_armature_undosys_type(struct UndoType *ut); diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h index 061b783797d..0fdea54c302 100644 --- a/source/blender/editors/include/ED_curve.h +++ b/source/blender/editors/include/ED_curve.h @@ -81,7 +81,7 @@ bool ED_curve_select_all(struct EditNurb *editnurb); bool ED_curve_select_swap(struct EditNurb *editnurb, bool hide_handles); int ED_curve_select_count(const struct View3D *v3d, const struct EditNurb *editnurb); -/* editcurve_undo.c */ +/* editcurve_undo.cc */ /** Export for ED_undo_sys */ void ED_curve_undosys_type(struct UndoType *ut); diff --git a/source/blender/editors/include/ED_sculpt.h b/source/blender/editors/include/ED_sculpt.h index fca7476fcf3..4e356499a1f 100644 --- a/source/blender/editors/include/ED_sculpt.h +++ b/source/blender/editors/include/ED_sculpt.h @@ -37,7 +37,7 @@ void ED_sculpt_init_transform(struct bContext *C, const char *undo_name); void ED_sculpt_end_transform(struct bContext *C, struct Object *ob); -/* sculpt_undo.c */ +/* sculpt_undo.cc */ /** Export for ED_undo_sys. */ void ED_sculpt_undosys_type(struct UndoType *ut); diff --git a/source/blender/editors/include/ED_text.h b/source/blender/editors/include/ED_text.h index 3f1ce8fe0ad..5b79f938bdf 100644 --- a/source/blender/editors/include/ED_text.h +++ b/source/blender/editors/include/ED_text.h @@ -33,7 +33,7 @@ bool ED_text_region_location_from_cursor(struct SpaceText *st, const int cursor_co[2], int r_pixel_co[2]); -/* text_undo.c */ +/* text_undo.cc */ /** Export for ED_undo_sys. */ void ED_text_undosys_type(struct UndoType *ut); diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index 35fc4ba705e..a165bbaf5ef 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -82,7 +82,7 @@ set(SRC sculpt_pose.c sculpt_smooth.c sculpt_transform.c - sculpt_undo.c + sculpt_undo.cc sculpt_uv.c curves_sculpt_intern.h diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.cc similarity index 91% rename from source/blender/editors/sculpt_paint/sculpt_undo.c rename to source/blender/editors/sculpt_paint/sculpt_undo.cc index 4b971fa6663..e27c9058751 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -300,7 +300,7 @@ struct PartialUpdateData { */ static void update_cb_partial(PBVHNode *node, void *userdata) { - struct PartialUpdateData *data = userdata; + PartialUpdateData *data = static_cast(userdata); if (BKE_pbvh_type(data->pbvh) == PBVH_GRIDS) { int *node_grid_indices; int totgrid; @@ -637,10 +637,11 @@ static bool sculpt_undo_restore_face_sets(bContext *C, return modified; } -static void sculpt_undo_bmesh_restore_generic_task_cb( - void *__restrict userdata, const int n, const TaskParallelTLS *__restrict UNUSED(tls)) +static void sculpt_undo_bmesh_restore_generic_task_cb(void *__restrict userdata, + const int n, + const TaskParallelTLS *__restrict /*tls*/) { - PBVHNode **nodes = userdata; + PBVHNode **nodes = static_cast(userdata); BKE_pbvh_node_mark_redraw(nodes[n]); } @@ -680,15 +681,15 @@ static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode, Object *ob, static void sculpt_undo_bmesh_enable(Object *ob, SculptUndoNode *unode) { SculptSession *ss = ob->sculpt; - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); SCULPT_pbvh_clear(ob); /* Create empty BMesh and enable logging. */ - ss->bm = BM_mesh_create(&bm_mesh_allocsize_default, - &((struct BMeshCreateParams){ - .use_toolflags = false, - })); + BMeshCreateParams bmesh_create_params{}; + bmesh_create_params.use_toolflags = false; + + ss->bm = BM_mesh_create(&bm_mesh_allocsize_default, &bmesh_create_params); BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK); me->flag |= ME_SCULPT_DYNAMIC_TOPOLOGY; @@ -738,7 +739,7 @@ static void sculpt_undo_bmesh_restore_end(bContext *C, static void sculpt_undo_geometry_store_data(SculptUndoNodeGeometry *geometry, Object *object) { - Mesh *mesh = object->data; + Mesh *mesh = static_cast(object->data); BLI_assert(!geometry->is_initialized); geometry->is_initialized = true; @@ -756,7 +757,7 @@ static void sculpt_undo_geometry_store_data(SculptUndoNodeGeometry *geometry, Ob static void sculpt_undo_geometry_restore_data(SculptUndoNodeGeometry *geometry, Object *object) { - Mesh *mesh = object->data; + Mesh *mesh = static_cast(object->data); BLI_assert(geometry->is_initialized); @@ -865,7 +866,8 @@ static void sculpt_undo_refine_subdiv(Depsgraph *depsgraph, float(*deformed_verts)[3] = BKE_multires_create_deformed_base_mesh_vert_coords( depsgraph, object, ss->multires.modifier, NULL); - BKE_subdiv_eval_refine_from_mesh(subdiv, object->data, deformed_verts); + BKE_subdiv_eval_refine_from_mesh( + subdiv, static_cast(object->data), deformed_verts); MEM_freeN(deformed_verts); } @@ -886,7 +888,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase bool need_refine_subdiv = false; bool clear_automask_cache = false; - for (unode = lb->first; unode; unode = unode->next) { + for (unode = static_cast(lb->first); unode; unode = unode->next) { if (!ELEM(unode->type, SCULPT_UNDO_COLOR, SCULPT_UNDO_MASK)) { clear_automask_cache = true; } @@ -919,7 +921,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase BKE_sculpt_update_object_for_edit(depsgraph, ob, false, need_mask, false); } - if (sculpt_undo_bmesh_restore(C, lb->first, ob, ss)) { + if (sculpt_undo_bmesh_restore(C, static_cast(lb->first), ob, ss)) { return; } } @@ -934,7 +936,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase char *undo_modified_grids = NULL; bool use_multires_undo = false; - for (unode = lb->first; unode; unode = unode->next) { + for (unode = static_cast(lb->first); unode; unode = unode->next) { if (!STREQ(unode->idname, ob->id.name)) { continue; @@ -964,7 +966,8 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase break; case SCULPT_UNDO_HIDDEN: if (modified_hidden_verts == NULL) { - modified_hidden_verts = MEM_calloc_arrayN(ss->totvert, sizeof(bool), __func__); + modified_hidden_verts = static_cast( + MEM_calloc_arrayN(ss->totvert, sizeof(bool), __func__)); } if (sculpt_undo_restore_hidden(C, unode, modified_hidden_verts)) { rebuild = true; @@ -973,7 +976,8 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase break; case SCULPT_UNDO_MASK: if (modified_mask_verts == NULL) { - modified_mask_verts = MEM_calloc_arrayN(ss->totvert, sizeof(bool), __func__); + modified_mask_verts = static_cast( + MEM_calloc_arrayN(ss->totvert, sizeof(bool), __func__)); } if (sculpt_undo_restore_mask(C, unode, modified_mask_verts)) { update = true; @@ -982,8 +986,8 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase break; case SCULPT_UNDO_FACE_SETS: if (modified_face_set_faces == NULL) { - modified_face_set_faces = MEM_calloc_arrayN( - BKE_pbvh_num_faces(ss->pbvh), sizeof(bool), __func__); + modified_face_set_faces = static_cast( + MEM_calloc_arrayN(BKE_pbvh_num_faces(ss->pbvh), sizeof(bool), __func__)); } if (sculpt_undo_restore_face_sets(C, unode, modified_face_set_faces)) { update = true; @@ -992,7 +996,8 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase break; case SCULPT_UNDO_COLOR: if (modified_color_verts == NULL) { - modified_color_verts = MEM_calloc_arrayN(ss->totvert, sizeof(bool), __func__); + modified_color_verts = static_cast( + MEM_calloc_arrayN(ss->totvert, sizeof(bool), __func__)); } if (sculpt_undo_restore_color(C, unode, modified_color_verts)) { update = true; @@ -1014,7 +1019,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase } if (use_multires_undo) { - for (unode = lb->first; unode; unode = unode->next) { + for (unode = static_cast(lb->first); unode; unode = unode->next) { if (!STREQ(unode->idname, ob->id.name)) { continue; } @@ -1023,7 +1028,8 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase } if (undo_modified_grids == NULL) { - undo_modified_grids = MEM_callocN(sizeof(char) * unode->maxgrid, "undo_grids"); + undo_modified_grids = static_cast( + MEM_callocN(sizeof(char) * unode->maxgrid, "undo_grids")); } for (int i = 0; i < unode->totgrid; i++) { @@ -1041,15 +1047,14 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase /* We update all nodes still, should be more clever, but also * needs to work correct when exiting/entering sculpt mode and * the nodes get recreated, though in that case it could do all. */ - struct PartialUpdateData data = { - .rebuild = rebuild, - .pbvh = ss->pbvh, - .modified_grids = undo_modified_grids, - .modified_hidden_verts = modified_hidden_verts, - .modified_mask_verts = modified_mask_verts, - .modified_color_verts = modified_color_verts, - .modified_face_set_faces = modified_face_set_faces, - }; + PartialUpdateData data{}; + data.rebuild = rebuild; + data.pbvh = ss->pbvh; + data.modified_grids = undo_modified_grids; + data.modified_hidden_verts = modified_hidden_verts; + data.modified_mask_verts = modified_mask_verts; + data.modified_color_verts = modified_color_verts; + data.modified_face_set_faces = modified_face_set_faces; BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb_partial, &data); BKE_pbvh_update_bounds(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw); @@ -1085,7 +1090,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase ss->shapekey_active || ss->deform_modifiers_active; if (tag_update) { - Mesh *mesh = ob->data; + Mesh *mesh = static_cast(ob->data); BKE_mesh_tag_coords_changed(mesh); BKE_sculptsession_free_deformMats(ss); @@ -1108,7 +1113,7 @@ static void sculpt_undo_restore_list(bContext *C, Depsgraph *depsgraph, ListBase static void sculpt_undo_free_list(ListBase *lb) { - SculptUndoNode *unode = lb->first; + SculptUndoNode *unode = static_cast(lb->first); while (unode != NULL) { SculptUndoNode *unode_next = unode->next; if (unode->co) { @@ -1219,23 +1224,24 @@ SculptUndoNode *SCULPT_undo_get_first_node() return NULL; } - return usculpt->nodes.first; + return static_cast(usculpt->nodes.first); } static size_t sculpt_undo_alloc_and_store_hidden(PBVH *pbvh, SculptUndoNode *unode) { - PBVHNode *node = unode->node; + PBVHNode *node = static_cast(unode->node); BLI_bitmap **grid_hidden = BKE_pbvh_grid_hidden(pbvh); int *grid_indices, totgrid; BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, NULL, NULL); size_t alloc_size = sizeof(*unode->grid_hidden) * (size_t)totgrid; - unode->grid_hidden = MEM_callocN(alloc_size, "unode->grid_hidden"); + unode->grid_hidden = static_cast(MEM_callocN(alloc_size, "unode->grid_hidden")); for (int i = 0; i < totgrid; i++) { if (grid_hidden[grid_indices[i]]) { - unode->grid_hidden[i] = MEM_dupallocN(grid_hidden[grid_indices[i]]); + unode->grid_hidden[i] = static_cast( + MEM_dupallocN(grid_hidden[grid_indices[i]])); alloc_size += MEM_allocN_len(unode->grid_hidden[i]); } else { @@ -1251,7 +1257,7 @@ static size_t sculpt_undo_alloc_and_store_hidden(PBVH *pbvh, SculptUndoNode *uno static SculptUndoNode *sculpt_undo_alloc_node_type(Object *object, SculptUndoType type) { const size_t alloc_size = sizeof(SculptUndoNode); - SculptUndoNode *unode = MEM_callocN(alloc_size, "SculptUndoNode"); + SculptUndoNode *unode = static_cast(MEM_callocN(alloc_size, "SculptUndoNode")); BLI_strncpy(unode->idname, object->id.name, sizeof(unode->idname)); unode->type = type; @@ -1283,13 +1289,14 @@ static void sculpt_undo_store_faces(SculptSession *ss, SculptUndoNode *unode) unode->faces_num = 0; PBVHFaceIter fd; - BKE_pbvh_face_iter_begin (ss->pbvh, unode->node, fd) { + BKE_pbvh_face_iter_begin (ss->pbvh, static_cast(unode->node), fd) { unode->faces_num++; } BKE_pbvh_face_iter_end(fd); - unode->faces = MEM_malloc_arrayN(sizeof(*unode->faces), unode->faces_num, __func__); - BKE_pbvh_face_iter_begin (ss->pbvh, unode->node, fd) { + unode->faces = static_cast( + MEM_malloc_arrayN(sizeof(*unode->faces), unode->faces_num, __func__)); + BKE_pbvh_face_iter_begin (ss->pbvh, static_cast(unode->node), fd) { unode->faces[fd.i] = fd.face; } BKE_pbvh_face_iter_end(fd); @@ -1324,7 +1331,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt BKE_pbvh_node_num_loops(ss->pbvh, node, &totloop); - unode->loop_index = MEM_calloc_arrayN(totloop, sizeof(int), __func__); + unode->loop_index = static_cast(MEM_calloc_arrayN(totloop, sizeof(int), __func__)); unode->maxloop = 0; unode->totloop = totloop; @@ -1341,12 +1348,12 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt switch (type) { case SCULPT_UNDO_COORDS: { size_t alloc_size = sizeof(*unode->co) * (size_t)allvert; - unode->co = MEM_callocN(alloc_size, "SculptUndoNode.co"); + unode->co = static_cast(MEM_callocN(alloc_size, "SculptUndoNode.co")); usculpt->undo_size += alloc_size; /* Needed for original data lookup. */ alloc_size = sizeof(*unode->no) * (size_t)allvert; - unode->no = MEM_callocN(alloc_size, "SculptUndoNode.no"); + unode->no = static_cast(MEM_callocN(alloc_size, "SculptUndoNode.no")); usculpt->undo_size += alloc_size; break; } @@ -1363,7 +1370,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt } case SCULPT_UNDO_MASK: { const size_t alloc_size = sizeof(*unode->mask) * (size_t)allvert; - unode->mask = MEM_callocN(alloc_size, "SculptUndoNode.mask"); + unode->mask = static_cast(MEM_callocN(alloc_size, "SculptUndoNode.mask")); usculpt->undo_size += alloc_size; break; } @@ -1371,15 +1378,15 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt /* Allocate vertex colors, even for loop colors we still * need this for original data lookup. */ const size_t alloc_size = sizeof(*unode->col) * (size_t)allvert; - unode->col = MEM_callocN(alloc_size, "SculptUndoNode.col"); + unode->col = static_cast(MEM_callocN(alloc_size, "SculptUndoNode.col")); usculpt->undo_size += alloc_size; /* Allocate loop colors separately too. */ if (ss->vcol_domain == ATTR_DOMAIN_CORNER) { size_t alloc_size_loop = sizeof(float) * 4 * (size_t)unode->totloop; - unode->loop_col = MEM_calloc_arrayN( - unode->totloop, sizeof(float) * 4, "SculptUndoNode.loop_col"); + unode->loop_col = static_cast( + MEM_calloc_arrayN(unode->totloop, sizeof(float) * 4, "SculptUndoNode.loop_col")); usculpt->undo_size += alloc_size_loop; } break; @@ -1405,7 +1412,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt unode->gridsize = gridsize; const size_t alloc_size = sizeof(*unode->grids) * (size_t)totgrid; - unode->grids = MEM_callocN(alloc_size, "SculptUndoNode.grids"); + unode->grids = static_cast(MEM_callocN(alloc_size, "SculptUndoNode.grids")); usculpt->undo_size += alloc_size; } else { @@ -1413,13 +1420,13 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt unode->maxvert = ss->totvert; const size_t alloc_size = sizeof(*unode->index) * (size_t)allvert; - unode->index = MEM_callocN(alloc_size, "SculptUndoNode.index"); + unode->index = static_cast(MEM_callocN(alloc_size, "SculptUndoNode.index")); usculpt->undo_size += alloc_size; } if (ss->deform_modifiers_active) { const size_t alloc_size = sizeof(*unode->orig_co) * (size_t)allvert; - unode->orig_co = MEM_callocN(alloc_size, "undoSculpt orig_cos"); + unode->orig_co = static_cast(MEM_callocN(alloc_size, "undoSculpt orig_cos")); usculpt->undo_size += alloc_size; } @@ -1431,7 +1438,7 @@ static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode) SculptSession *ss = ob->sculpt; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin (ss->pbvh, unode->node, vd, PBVH_ITER_ALL) { + BKE_pbvh_vertex_iter_begin (ss->pbvh, static_cast(unode->node), vd, PBVH_ITER_ALL) { copy_v3_v3(unode->co[vd.i], vd.co); if (vd.no) { copy_v3_v3(unode->no[vd.i], vd.no); @@ -1450,7 +1457,7 @@ static void sculpt_undo_store_coords(Object *ob, SculptUndoNode *unode) static void sculpt_undo_store_hidden(Object *ob, SculptUndoNode *unode) { PBVH *pbvh = ob->sculpt->pbvh; - PBVHNode *node = unode->node; + PBVHNode *node = static_cast(unode->node); const bool *hide_vert = BKE_pbvh_get_vert_hide(pbvh); if (hide_vert == NULL) { @@ -1476,7 +1483,7 @@ static void sculpt_undo_store_mask(Object *ob, SculptUndoNode *unode) SculptSession *ss = ob->sculpt; PBVHVertexIter vd; - BKE_pbvh_vertex_iter_begin (ss->pbvh, unode->node, vd, PBVH_ITER_ALL) { + BKE_pbvh_vertex_iter_begin (ss->pbvh, static_cast(unode->node), vd, PBVH_ITER_ALL) { unode->mask[vd.i] = *vd.mask; } BKE_pbvh_vertex_iter_end; @@ -1489,7 +1496,7 @@ static void sculpt_undo_store_color(Object *ob, SculptUndoNode *unode) BLI_assert(BKE_pbvh_type(ss->pbvh) == PBVH_FACES); int allvert; - BKE_pbvh_node_num_verts(ss->pbvh, unode->node, NULL, &allvert); + BKE_pbvh_node_num_verts(ss->pbvh, static_cast(unode->node), NULL, &allvert); /* NOTE: even with loop colors we still store (derived) * vertex colors for original data lookup. */ @@ -1525,10 +1532,11 @@ static SculptUndoNode *sculpt_undo_geometry_push(Object *object, SculptUndoType static void sculpt_undo_store_face_sets(SculptSession *ss, SculptUndoNode *unode) { - unode->face_sets = MEM_malloc_arrayN(sizeof(*unode->face_sets), unode->faces_num, __func__); + unode->face_sets = static_cast( + MEM_malloc_arrayN(sizeof(*unode->face_sets), unode->faces_num, __func__)); PBVHFaceIter fd; - BKE_pbvh_face_iter_begin (ss->pbvh, unode->node, fd) { + BKE_pbvh_face_iter_begin (ss->pbvh, static_cast(unode->node), fd) { unode->face_sets[fd.i] = fd.face_set ? *fd.face_set : SCULPT_FACE_SET_NONE; } BKE_pbvh_face_iter_end(fd); @@ -1540,10 +1548,10 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt SculptSession *ss = ob->sculpt; PBVHVertexIter vd; - SculptUndoNode *unode = usculpt->nodes.first; + SculptUndoNode *unode = static_cast(usculpt->nodes.first); if (unode == NULL) { - unode = MEM_callocN(sizeof(*unode), __func__); + unode = MEM_cnew(__func__); BLI_strncpy(unode->idname, ob->id.name, sizeof(unode->idname)); unode->type = type; @@ -1593,7 +1601,7 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob, PBVHNode *node, Sculpt BKE_pbvh_vertex_iter_end; GSET_ITER (gs_iter, faces) { - BMFace *f = BLI_gsetIterator_getKey(&gs_iter); + BMFace *f = static_cast(BLI_gsetIterator_getKey(&gs_iter)); BM_log_face_modified(ss->bm_log, f); } break; @@ -1655,13 +1663,13 @@ SculptUndoNode *SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType const int *loop_indices; int allvert, allloop; - BKE_pbvh_node_num_verts(ss->pbvh, unode->node, NULL, &allvert); + BKE_pbvh_node_num_verts(ss->pbvh, static_cast(unode->node), NULL, &allvert); const int *vert_indices = BKE_pbvh_node_get_vert_indices(node); memcpy(unode->index, vert_indices, sizeof(int) * allvert); if (unode->loop_index) { - BKE_pbvh_node_num_loops(ss->pbvh, unode->node, &allloop); - BKE_pbvh_node_get_loops(ss->pbvh, unode->node, &loop_indices, NULL); + BKE_pbvh_node_num_loops(ss->pbvh, static_cast(unode->node), &allloop); + BKE_pbvh_node_get_loops(ss->pbvh, static_cast(unode->node), &loop_indices, NULL); if (allloop) { memcpy(unode->loop_index, loop_indices, sizeof(int) * allloop); @@ -1750,7 +1758,7 @@ void SCULPT_undo_push_begin_ex(Object *ob, const char *name) /* If possible, we need to tag the object and its geometry data as 'changed in the future' in * the previous undo step if it's a memfile one. */ ED_undosys_stack_memfile_id_changed_tag(ustack, &ob->id); - ED_undosys_stack_memfile_id_changed_tag(ustack, ob->data); + ED_undosys_stack_memfile_id_changed_tag(ustack, static_cast(ob->data)); } /* Special case, we never read from this. */ @@ -1783,7 +1791,7 @@ void SCULPT_undo_push_end_ex(struct Object *ob, const bool use_nested_undo) SculptUndoNode *unode; /* We don't need normals in the undo stack. */ - for (unode = usculpt->nodes.first; unode; unode = unode->next) { + for (unode = static_cast(usculpt->nodes.first); unode; unode = unode->next) { if (unode->no) { usculpt->undo_size -= MEM_allocN_len(unode->no); MEM_freeN(unode->no); @@ -1792,7 +1800,7 @@ void SCULPT_undo_push_end_ex(struct Object *ob, const bool use_nested_undo) } /* We could remove this and enforce all callers run in an operator using 'OPTYPE_UNDO'. */ - wmWindowManager *wm = G_MAIN->wm.first; + wmWindowManager *wm = static_cast(G_MAIN->wm.first); if (wm->op_undo_depth == 0 || use_nested_undo) { UndoStack *ustack = ED_undo_stack_get(); BKE_undosys_step_push(ustack, NULL, NULL); @@ -1840,7 +1848,8 @@ static void sculpt_undo_set_active_layer(struct bContext *C, SculptAttrRef *attr if (!layer) { layer = BKE_id_attribute_search(&me->id, attr->name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL); if (layer) { - if (ED_geometry_attribute_convert(me, attr->name, attr->type, attr->domain, NULL)) { + if (ED_geometry_attribute_convert( + me, attr->name, eCustomDataType(attr->type), attr->domain, NULL)) { layer = BKE_id_attribute_find(&me->id, attr->name, attr->type, attr->domain); } } @@ -1868,23 +1877,21 @@ static void sculpt_undo_set_active_layer(struct bContext *C, SculptAttrRef *attr } } -static void sculpt_undosys_step_encode_init(struct bContext *UNUSED(C), UndoStep *us_p) +static void sculpt_undosys_step_encode_init(struct bContext * /*C*/, UndoStep *us_p) { SculptUndoStep *us = (SculptUndoStep *)us_p; /* Dummy, memory is cleared anyway. */ BLI_listbase_clear(&us->data.nodes); } -static bool sculpt_undosys_step_encode(struct bContext *UNUSED(C), - struct Main *bmain, - UndoStep *us_p) +static bool sculpt_undosys_step_encode(struct bContext * /*C*/, struct Main *bmain, UndoStep *us_p) { /* Dummy, encoding is done along the way by adding tiles * to the current 'SculptUndoStep' added by encode_init. */ SculptUndoStep *us = (SculptUndoStep *)us_p; us->step.data_size = us->data.undo_size; - SculptUndoNode *unode = us->data.nodes.last; + SculptUndoNode *unode = static_cast(us->data.nodes.last); if (unode && unode->type == SCULPT_UNDO_DYNTOPO_END) { us->step.use_memfile_step = true; } @@ -2002,7 +2009,7 @@ static void sculpt_undosys_step_decode( * (some) evaluated data. */ BKE_scene_graph_evaluated_ensure(depsgraph, bmain); - Mesh *me = ob->data; + Mesh *me = static_cast(ob->data); /* Don't add sculpt topology undo steps when reading back undo state. * The undo steps must enter/exit for us. */ me->flag &= ~ME_SCULPT_DYNAMIC_TOPOLOGY; diff --git a/source/blender/editors/space_text/CMakeLists.txt b/source/blender/editors/space_text/CMakeLists.txt index 6cdc7f4aa67..6fa06b46fc4 100644 --- a/source/blender/editors/space_text/CMakeLists.txt +++ b/source/blender/editors/space_text/CMakeLists.txt @@ -32,7 +32,7 @@ set(SRC text_format_py.c text_header.c text_ops.c - text_undo.c + text_undo.cc text_format.h text_intern.h diff --git a/source/blender/editors/space_text/text_intern.h b/source/blender/editors/space_text/text_intern.h index 16ed1742f25..9c66503584a 100644 --- a/source/blender/editors/space_text/text_intern.h +++ b/source/blender/editors/space_text/text_intern.h @@ -17,6 +17,10 @@ struct TextLine; struct bContext; struct wmOperatorType; +#ifdef __cplusplus +extern "C" { +#endif + /* text_draw.c */ void draw_text_main(struct SpaceText *st, struct ARegion *region); @@ -176,3 +180,7 @@ void TEXT_OT_autocomplete(struct wmOperatorType *ot); /* space_text.c */ extern const char *text_context_dir[]; /* doc access */ + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/editors/space_text/text_undo.c b/source/blender/editors/space_text/text_undo.cc similarity index 86% rename from source/blender/editors/space_text/text_undo.c rename to source/blender/editors/space_text/text_undo.cc index 035a9f29dc3..39b90841cfe 100644 --- a/source/blender/editors/space_text/text_undo.c +++ b/source/blender/editors/space_text/text_undo.cc @@ -61,16 +61,17 @@ static void text_state_encode(TextState *state, Text *text, BArrayStore *buffer_ { size_t buf_len = 0; uchar *buf = (uchar *)txt_to_buf_for_undo(text, &buf_len); - state->buf_array_state = BLI_array_store_state_add(buffer_store, buf, buf_len, NULL); + state->buf_array_state = BLI_array_store_state_add(buffer_store, buf, buf_len, nullptr); MEM_freeN(buf); - state->cursor_line = txt_get_span(text->lines.first, text->curl); + state->cursor_line = txt_get_span(static_cast(text->lines.first), text->curl); state->cursor_column = text->curc; if (txt_has_sel(text)) { state->cursor_line_select = (text->curl == text->sell) ? state->cursor_line : - txt_get_span(text->lines.first, text->sell); + txt_get_span(static_cast(text->lines.first), + text->sell); state->cursor_column_select = text->selc; } else { @@ -83,7 +84,8 @@ static void text_state_decode(TextState *state, Text *text) { size_t buf_len; { - const uchar *buf = BLI_array_store_state_data_get_alloc(state->buf_array_state, &buf_len); + const uchar *buf = static_cast( + BLI_array_store_state_data_get_alloc(state->buf_array_state, &buf_len)); txt_from_buf_for_undo(text, (const char *)buf, buf_len); MEM_freeN((void *)buf); } @@ -115,12 +117,12 @@ typedef struct TextUndoStep { static struct { BArrayStore *buffer_store; int users; -} g_text_buffers = {NULL}; +} g_text_buffers = {nullptr}; static size_t text_undosys_step_encode_to_state(TextState *state, Text *text) { BLI_assert(BLI_array_is_zeroed(state, 1)); - if (g_text_buffers.buffer_store == NULL) { + if (g_text_buffers.buffer_store == nullptr) { g_text_buffers.buffer_store = BLI_array_store_create(1, ARRAY_CHUNK_SIZE); } g_text_buffers.users += 1; @@ -132,7 +134,7 @@ static size_t text_undosys_step_encode_to_state(TextState *state, Text *text) return BLI_array_store_calc_size_compacted_get(g_text_buffers.buffer_store) - total_size_prev; } -static bool text_undosys_poll(bContext *UNUSED(C)) +static bool text_undosys_poll(bContext * /*C*/) { /* Only use when operators initialized. */ UndoStack *ustack = ED_undo_stack_get(); @@ -165,9 +167,7 @@ static void text_undosys_step_encode_init(struct bContext *C, UndoStep *us_p) us->text_ref.ptr = text; } -static bool text_undosys_step_encode(struct bContext *C, - struct Main *UNUSED(bmain), - UndoStep *us_p) +static bool text_undosys_step_encode(struct bContext *C, struct Main * /*bmain*/, UndoStep *us_p) { TextUndoStep *us = (TextUndoStep *)us_p; @@ -183,7 +183,7 @@ static bool text_undosys_step_encode(struct bContext *C, } static void text_undosys_step_decode(struct bContext *C, - struct Main *UNUSED(bmain), + struct Main * /*bmain*/, UndoStep *us_p, const eUndoStepDir dir, bool is_final) @@ -194,7 +194,7 @@ static void text_undosys_step_decode(struct bContext *C, Text *text = us->text_ref.ptr; TextState *state; - if ((us->states[0].buf_array_state != NULL) && (dir == STEP_UNDO) && !is_final) { + if ((us->states[0].buf_array_state != nullptr) && (dir == STEP_UNDO) && !is_final) { state = &us->states[0]; } else { @@ -224,7 +224,7 @@ static void text_undosys_step_free(UndoStep *us_p) g_text_buffers.users -= 1; if (g_text_buffers.users == 0) { BLI_array_store_destroy(g_text_buffers.buffer_store); - g_text_buffers.buffer_store = NULL; + g_text_buffers.buffer_store = nullptr; } } } @@ -264,12 +264,13 @@ UndoStep *ED_text_undo_push_init(bContext *C) { UndoStack *ustack = ED_undo_stack_get(); Main *bmain = CTX_data_main(C); - wmWindowManager *wm = bmain->wm.first; + wmWindowManager *wm = static_cast(bmain->wm.first); if (wm->op_undo_depth <= 1) { - UndoStep *us_p = BKE_undosys_step_push_init_with_type(ustack, C, NULL, BKE_UNDOSYS_TYPE_TEXT); + UndoStep *us_p = BKE_undosys_step_push_init_with_type( + ustack, C, nullptr, BKE_UNDOSYS_TYPE_TEXT); return us_p; } - return NULL; + return nullptr; } /** \} */ diff --git a/source/blender/editors/undo/CMakeLists.txt b/source/blender/editors/undo/CMakeLists.txt index cfebb2cab1c..eebc517603b 100644 --- a/source/blender/editors/undo/CMakeLists.txt +++ b/source/blender/editors/undo/CMakeLists.txt @@ -2,6 +2,7 @@ set(INC ../include + ../../asset_system ../../blenkernel ../../blenlib ../../blenloader @@ -18,11 +19,11 @@ set(INC_SYS ) set(SRC - ed_undo.c - memfile_undo.c - undo_system_types.c + ed_undo.cc + memfile_undo.cc + undo_system_types.cc - undo_intern.h + undo_intern.hh ) set(LIB diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.cc similarity index 89% rename from source/blender/editors/undo/ed_undo.c rename to source/blender/editors/undo/ed_undo.cc index db0eaa36047..25f6d2aa274 100644 --- a/source/blender/editors/undo/ed_undo.c +++ b/source/blender/editors/undo/ed_undo.cc @@ -67,7 +67,7 @@ bool ED_undo_is_state_valid(bContext *C) wmWindowManager *wm = CTX_wm_manager(C); /* Currently only checks matching begin/end calls. */ - if (wm->undo_stack == NULL) { + if (wm->undo_stack == nullptr) { /* No undo stack is valid, nothing to do. */ return true; } @@ -75,7 +75,7 @@ bool ED_undo_is_state_valid(bContext *C) /* If this fails #ED_undo_grouped_begin, #ED_undo_grouped_end calls don't match. */ return false; } - if (wm->undo_stack->step_active != NULL) { + if (wm->undo_stack->step_active != nullptr) { if (wm->undo_stack->step_active->skip == true) { /* Skip is only allowed between begin/end calls, * a state that should never happen in main event loop. */ @@ -113,7 +113,7 @@ void ED_undo_push(bContext *C, const char *str) * * For this reason we need to handle the undo step even when undo steps is set to zero. */ - if ((steps <= 0) && wm->undo_stack->step_init != NULL) { + if ((steps <= 0) && wm->undo_stack->step_init != nullptr) { steps = 1; } if (steps <= 0) { @@ -121,9 +121,9 @@ void ED_undo_push(bContext *C, const char *str) } if (G.background) { /* Python developers may have explicitly created the undo stack in background mode, - * otherwise allow it to be NULL, see: T60934. - * Otherwise it must never be NULL, even when undo is disabled. */ - if (wm->undo_stack == NULL) { + * otherwise allow it to be nullptr, see: T60934. + * Otherwise it must never be nullptr, even when undo is disabled. */ + if (wm->undo_stack == nullptr) { return; } } @@ -131,7 +131,7 @@ void ED_undo_push(bContext *C, const char *str) eUndoPushReturn push_retval; /* Only apply limit if this is the last undo step. */ - if (wm->undo_stack->step_active && (wm->undo_stack->step_active->next == NULL)) { + if (wm->undo_stack->step_active && (wm->undo_stack->step_active->next == nullptr)) { BKE_undosys_stack_limit_steps_and_memory(wm->undo_stack, steps - 1, 0); } @@ -147,7 +147,7 @@ void ED_undo_push(bContext *C, const char *str) } if (push_retval & UNDO_PUSH_RET_OVERRIDE_CHANGED) { - WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL); + WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, nullptr); } } @@ -170,7 +170,7 @@ static void ed_undo_step_pre(bContext *C, WM_jobs_kill_all(wm); if (G.debug & G_DEBUG_IO) { - if (bmain->lock != NULL) { + if (bmain->lock != nullptr) { BKE_report(reports, RPT_INFO, "Checking sanity of current .blend file *BEFORE* undo step"); BLO_main_validate_libraries(bmain, reports); } @@ -179,7 +179,7 @@ static void ed_undo_step_pre(bContext *C, if (area && (area->spacetype == SPACE_VIEW3D)) { Object *obact = CTX_data_active_object(C); if (obact && (obact->type == OB_GPENCIL)) { - ED_gpencil_toggle_brush_cursor(C, false, NULL); + ED_gpencil_toggle_brush_cursor(C, false, nullptr); } } @@ -210,15 +210,15 @@ static void ed_undo_step_post(bContext *C, ScrArea *area = CTX_wm_area(C); /* Set special modes for grease pencil */ - if (area != NULL && (area->spacetype == SPACE_VIEW3D)) { + if (area != nullptr && (area->spacetype == SPACE_VIEW3D)) { Object *obact = CTX_data_active_object(C); if (obact && (obact->type == OB_GPENCIL)) { /* set cursor */ if ((obact->mode & OB_MODE_ALL_PAINT_GPENCIL)) { - ED_gpencil_toggle_brush_cursor(C, true, NULL); + ED_gpencil_toggle_brush_cursor(C, true, nullptr); } else { - ED_gpencil_toggle_brush_cursor(C, false, NULL); + ED_gpencil_toggle_brush_cursor(C, false, nullptr); } /* set workspace mode */ Base *basact = CTX_data_active_base(C); @@ -235,14 +235,14 @@ static void ed_undo_step_post(bContext *C, } if (G.debug & G_DEBUG_IO) { - if (bmain->lock != NULL) { + if (bmain->lock != nullptr) { BKE_report(reports, RPT_INFO, "Checking sanity of current .blend file *AFTER* undo step"); BLO_main_validate_libraries(bmain, reports); } } - WM_event_add_notifier(C, NC_WINDOW, NULL); - WM_event_add_notifier(C, NC_WM | ND_UNDO, NULL); + WM_event_add_notifier(C, NC_WINDOW, nullptr); + WM_event_add_notifier(C, NC_WM | ND_UNDO, nullptr); WM_toolsystem_refresh_active(C); WM_toolsystem_refresh_screen_all(bmain); @@ -298,7 +298,7 @@ static int ed_undo_step_direction(bContext *C, enum eUndoStepDir step, ReportLis */ static int ed_undo_step_by_name(bContext *C, const char *undo_name, ReportList *reports) { - BLI_assert(undo_name != NULL); + BLI_assert(undo_name != nullptr); /* FIXME: See comments in `ed_undo_step_direction`. */ if (ED_gpencil_session_active()) { @@ -307,20 +307,21 @@ static int ed_undo_step_by_name(bContext *C, const char *undo_name, ReportList * wmWindowManager *wm = CTX_wm_manager(C); UndoStep *undo_step_from_name = BKE_undosys_step_find_by_name(wm->undo_stack, undo_name); - if (undo_step_from_name == NULL) { + if (undo_step_from_name == nullptr) { CLOG_ERROR(&LOG, "Step name='%s' not found in current undo stack", undo_name); return OPERATOR_CANCELLED; } UndoStep *undo_step_target = undo_step_from_name->prev; - if (undo_step_target == NULL) { + if (undo_step_target == nullptr) { CLOG_ERROR(&LOG, "Step name='%s' cannot be undone", undo_name); return OPERATOR_CANCELLED; } - const int undo_dir_i = BKE_undosys_step_calc_direction(wm->undo_stack, undo_step_target, NULL); + const int undo_dir_i = BKE_undosys_step_calc_direction( + wm->undo_stack, undo_step_target, nullptr); BLI_assert(ELEM(undo_dir_i, -1, 1)); const enum eUndoStepDir undo_dir = (undo_dir_i == -1) ? STEP_UNDO : STEP_REDO; @@ -332,7 +333,7 @@ static int ed_undo_step_by_name(bContext *C, const char *undo_name, ReportList * ed_undo_step_pre(C, wm, undo_dir, reports); - BKE_undosys_step_load_data_ex(wm->undo_stack, C, undo_step_target, NULL, true); + BKE_undosys_step_load_data_ex(wm->undo_stack, C, undo_step_target, nullptr, true); ed_undo_step_post(C, wm, undo_dir, reports); @@ -390,11 +391,11 @@ void ED_undo_grouped_push(bContext *C, const char *str) void ED_undo_pop(bContext *C) { - ed_undo_step_direction(C, STEP_UNDO, NULL); + ed_undo_step_direction(C, STEP_UNDO, nullptr); } void ED_undo_redo(bContext *C) { - ed_undo_step_direction(C, STEP_REDO, NULL); + ed_undo_step_direction(C, STEP_REDO, nullptr); } void ED_undo_push_op(bContext *C, wmOperator *op) @@ -431,10 +432,10 @@ bool ED_undo_is_memfile_compatible(const bContext *C) * (this matches 2.7x behavior). */ const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - if (view_layer != NULL) { + if (view_layer != nullptr) { BKE_view_layer_synced_ensure(scene, view_layer); Object *obact = BKE_view_layer_active_object_get(view_layer); - if (obact != NULL) { + if (obact != nullptr) { if (obact->mode & OB_MODE_EDIT) { return false; } @@ -447,10 +448,10 @@ bool ED_undo_is_legacy_compatible_for_property(struct bContext *C, ID *id) { const Scene *scene = CTX_data_scene(C); ViewLayer *view_layer = CTX_data_view_layer(C); - if (view_layer != NULL) { + if (view_layer != nullptr) { BKE_view_layer_synced_ensure(scene, view_layer); Object *obact = BKE_view_layer_active_object_get(view_layer); - if (obact != NULL) { + if (obact != nullptr) { if (obact->mode & OB_MODE_ALL_PAINT) { /* Don't store property changes when painting * (only do undo pushes on brush strokes which each paint operator handles on its own). */ @@ -458,7 +459,7 @@ bool ED_undo_is_legacy_compatible_for_property(struct bContext *C, ID *id) return false; } if (obact->mode & OB_MODE_EDIT) { - if ((id == NULL) || (obact->data == NULL) || + if ((id == nullptr) || (obact->data == nullptr) || (GS(id->name) != GS(((ID *)obact->data)->name))) { /* No undo push on id type mismatch in edit-mode. */ CLOG_INFO(&LOG, 1, "skipping undo for edit-mode"); @@ -472,7 +473,7 @@ bool ED_undo_is_legacy_compatible_for_property(struct bContext *C, ID *id) UndoStack *ED_undo_stack_get(void) { - wmWindowManager *wm = G_MAIN->wm.first; + wmWindowManager *wm = static_cast(G_MAIN->wm.first); return wm->undo_stack; } @@ -514,7 +515,7 @@ static int ed_undo_push_exec(bContext *C, wmOperator *op) * NOTE: since the undo stack isn't initialized on startup, background mode behavior * won't match regular usage, this is just for scripts to do explicit undo pushes. */ wmWindowManager *wm = CTX_wm_manager(C); - if (wm->undo_stack == NULL) { + if (wm->undo_stack == nullptr) { wm->undo_stack = BKE_undosys_stack_create(); } } @@ -533,7 +534,7 @@ static int ed_redo_exec(bContext *C, wmOperator *op) return ret; } -static int ed_undo_redo_exec(bContext *C, wmOperator *UNUSED(op)) +static int ed_undo_redo_exec(bContext *C, wmOperator * /*op*/) { wmOperator *last_op = WM_operator_last_redo(C); int ret = ED_undo_operator_repeat(C, last_op); @@ -550,7 +551,7 @@ static int ed_undo_redo_exec(bContext *C, wmOperator *UNUSED(op)) static bool ed_undo_is_init_poll(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); - if (wm->undo_stack == NULL) { + if (wm->undo_stack == nullptr) { /* This message is intended for Python developers, * it will be part of the exception when attempting to call undo in background mode. */ CTX_wm_operator_poll_msg_set( @@ -583,7 +584,7 @@ static bool ed_undo_poll(bContext *C) return false; } UndoStack *undo_stack = CTX_wm_manager(C)->undo_stack; - return (undo_stack->step_active != NULL) && (undo_stack->step_active->prev != NULL); + return (undo_stack->step_active != nullptr) && (undo_stack->step_active->prev != nullptr); } void ED_OT_undo(wmOperatorType *ot) @@ -626,7 +627,7 @@ static bool ed_redo_poll(bContext *C) return false; } UndoStack *undo_stack = CTX_wm_manager(C)->undo_stack; - return (undo_stack->step_active != NULL) && (undo_stack->step_active->next != NULL); + return (undo_stack->step_active != nullptr) && (undo_stack->step_active->next != nullptr); } void ED_OT_redo(wmOperatorType *ot) @@ -724,18 +725,18 @@ int ED_undo_operator_repeat(bContext *C, wmOperator *op) CTX_wm_region_set(C, region_orig); } else { - CLOG_WARN(&LOG, "called with NULL 'op'"); + CLOG_WARN(&LOG, "called with nullptr 'op'"); } return ret; } -void ED_undo_operator_repeat_cb(bContext *C, void *arg_op, void *UNUSED(arg_unused)) +void ED_undo_operator_repeat_cb(bContext *C, void *arg_op, void * /*arg_unused*/) { ED_undo_operator_repeat(C, (wmOperator *)arg_op); } -void ED_undo_operator_repeat_cb_evt(bContext *C, void *arg_op, int UNUSED(arg_unused)) +void ED_undo_operator_repeat_cb_evt(bContext *C, void *arg_op, int /*arg_unused*/) { ED_undo_operator_repeat(C, (wmOperator *)arg_op); } @@ -758,14 +759,14 @@ static int undo_history_exec(bContext *C, wmOperator *op) if (ret & OPERATOR_FINISHED) { ed_undo_refresh_for_op(C); - WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_WINDOW, nullptr); return OPERATOR_FINISHED; } } return OPERATOR_CANCELLED; } -static int undo_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int undo_history_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { PropertyRNA *prop = RNA_struct_find_property(op->ptr, "item"); if (RNA_property_is_set(op->ptr, prop)) { @@ -804,7 +805,7 @@ void ED_undo_object_set_active_or_warn( Object *ob_prev = BKE_view_layer_active_object_get(view_layer); if (ob_prev != ob) { Base *base = BKE_view_layer_base_find(view_layer, ob); - if (base != NULL) { + if (base != nullptr) { view_layer->basact = base; ED_object_base_active_refresh(G_MAIN, scene, view_layer); } @@ -831,13 +832,14 @@ void ED_undo_object_editmode_restore_helper(struct bContext *C, ((ID *)bases[i]->object->data)->tag |= LIB_TAG_DOIT; } Object **ob_p = object_array; - for (uint i = 0; i < object_array_len; i++, ob_p = POINTER_OFFSET(ob_p, object_array_stride)) { + for (uint i = 0; i < object_array_len; + i++, ob_p = static_cast(POINTER_OFFSET(ob_p, object_array_stride))) { Object *obedit = *ob_p; ED_object_editmode_enter_ex(bmain, scene, obedit, EM_NO_CONTEXT); ((ID *)obedit->data)->tag &= ~LIB_TAG_DOIT; } for (uint i = 0; i < bases_len; i++) { - ID *id = bases[i]->object->data; + ID *id = static_cast(bases[i]->object->data); if (id->tag & LIB_TAG_DOIT) { ED_object_editmode_exit_ex(bmain, scene, bases[i]->object, EM_FREEDATA); /* Ideally we would know the selection state it was before entering edit-mode, @@ -870,7 +872,7 @@ static int undo_editmode_objects_from_view_layer_prepare(const Scene *scene, LISTBASE_FOREACH (Base *, base, object_bases) { Object *ob = base->object; if ((ob->type == object_type) && (ob->mode & OB_MODE_EDIT)) { - ID *id = ob->data; + ID *id = static_cast(ob->data); id->tag &= ~LIB_TAG_DOIT; } } @@ -879,7 +881,7 @@ static int undo_editmode_objects_from_view_layer_prepare(const Scene *scene, LISTBASE_FOREACH (Base *, base, object_bases) { Object *ob = base->object; if ((ob->type == object_type) && (ob->mode & OB_MODE_EDIT)) { - ID *id = ob->data; + ID *id = static_cast(ob->data); if ((id->tag & LIB_TAG_DOIT) == 0) { len += 1; id->tag |= LIB_TAG_DOIT; @@ -895,21 +897,23 @@ Object **ED_undo_editmode_objects_from_view_layer(const Scene *scene, { BKE_view_layer_synced_ensure(scene, view_layer); Base *baseact = BKE_view_layer_active_base_get(view_layer); - if ((baseact == NULL) || (baseact->object->mode & OB_MODE_EDIT) == 0) { - return MEM_mallocN(0, __func__); + if ((baseact == nullptr) || (baseact->object->mode & OB_MODE_EDIT) == 0) { + return static_cast(MEM_mallocN(0, __func__)); } const int len = undo_editmode_objects_from_view_layer_prepare( scene, view_layer, baseact->object); const short object_type = baseact->object->type; int i = 0; - Object **objects = MEM_malloc_arrayN(len, sizeof(*objects), __func__); + Object **objects = static_cast(MEM_malloc_arrayN(len, sizeof(*objects), __func__)); /* Base iteration, starting with the active-base to ensure it's the first item in the array. * Looping over the active-base twice is OK as the tag check prevents it being handled twice. */ - for (Base *base = baseact, *base_next = BKE_view_layer_object_bases_get(view_layer)->first; base; - base = base_next, base_next = base_next ? base_next->next : NULL) { + for (Base *base = baseact, + *base_next = static_cast(BKE_view_layer_object_bases_get(view_layer)->first); + base; + base = base_next, base_next = base_next ? base_next->next : nullptr) { Object *ob = base->object; if ((ob->type == object_type) && (ob->mode & OB_MODE_EDIT)) { - ID *id = ob->data; + ID *id = static_cast(ob->data); if (id->tag & LIB_TAG_DOIT) { objects[i++] = ob; id->tag &= ~LIB_TAG_DOIT; @@ -928,23 +932,23 @@ Base **ED_undo_editmode_bases_from_view_layer(const Scene *scene, { BKE_view_layer_synced_ensure(scene, view_layer); Base *baseact = BKE_view_layer_active_base_get(view_layer); - if ((baseact == NULL) || (baseact->object->mode & OB_MODE_EDIT) == 0) { - return MEM_mallocN(0, __func__); + if ((baseact == nullptr) || (baseact->object->mode & OB_MODE_EDIT) == 0) { + return static_cast(MEM_mallocN(0, __func__)); } const int len = undo_editmode_objects_from_view_layer_prepare( scene, view_layer, baseact->object); const short object_type = baseact->object->type; int i = 0; - Base **base_array = MEM_malloc_arrayN(len, sizeof(*base_array), __func__); + Base **base_array = static_cast(MEM_malloc_arrayN(len, sizeof(*base_array), __func__)); /* Base iteration, starting with the active-base to ensure it's the first item in the array. * Looping over the active-base twice is OK as the tag check prevents it being handled twice. */ for (Base *base = BKE_view_layer_active_base_get(view_layer), - *base_next = BKE_view_layer_object_bases_get(view_layer)->first; + *base_next = static_cast(BKE_view_layer_object_bases_get(view_layer)->first); base; - base = base_next, base_next = base_next ? base_next->next : NULL) { + base = base_next, base_next = base_next ? base_next->next : nullptr) { Object *ob = base->object; if ((ob->type == object_type) && (ob->mode & OB_MODE_EDIT)) { - ID *id = ob->data; + ID *id = static_cast(ob->data); if (id->tag & LIB_TAG_DOIT) { base_array[i++] = base; id->tag &= ~LIB_TAG_DOIT; diff --git a/source/blender/editors/undo/memfile_undo.c b/source/blender/editors/undo/memfile_undo.cc similarity index 90% rename from source/blender/editors/undo/memfile_undo.c rename to source/blender/editors/undo/memfile_undo.cc index 891719fde33..a4d05c31013 100644 --- a/source/blender/editors/undo/memfile_undo.c +++ b/source/blender/editors/undo/memfile_undo.cc @@ -41,7 +41,7 @@ #include "../blenloader/BLO_undofile.h" -#include "undo_intern.h" +#include "undo_intern.hh" #include @@ -64,13 +64,13 @@ static bool memfile_undosys_poll(bContext *C) /* Allow a single memfile undo step (the first). */ UndoStack *ustack = ED_undo_stack_get(); - if ((ustack->step_active != NULL) && (ED_undo_is_memfile_compatible(C) == false)) { + if ((ustack->step_active != nullptr) && (ED_undo_is_memfile_compatible(C) == false)) { return false; } return true; } -static bool memfile_undosys_step_encode(struct bContext *UNUSED(C), +static bool memfile_undosys_step_encode(struct bContext * /*C*/, struct Main *bmain, UndoStep *us_p) { @@ -83,10 +83,10 @@ static bool memfile_undosys_step_encode(struct bContext *UNUSED(C), ED_editors_flush_edits_ex(bmain, false, true); } - /* can be NULL, use when set. */ + /* can be null, use when set. */ MemFileUndoStep *us_prev = (MemFileUndoStep *)BKE_undosys_step_find_by_type( ustack, BKE_UNDOSYS_TYPE_MEMFILE); - us->data = BKE_memfile_undo_encode(bmain, us_prev ? us_prev->data : NULL); + us->data = BKE_memfile_undo_encode(bmain, us_prev ? us_prev->data : nullptr); us->step.data_size = us->data->undo_size; /* Store the fact that we should not re-use old data with that undo step, and reset the Main @@ -104,14 +104,14 @@ static int memfile_undosys_step_id_reused_cb(LibraryIDLinkCallbackData *cb_data) BLI_assert((id_self->tag & LIB_TAG_UNDO_OLD_ID_REUSED) != 0); ID *id = *id_pointer; - if (id != NULL && !ID_IS_LINKED(id) && (id->tag & LIB_TAG_UNDO_OLD_ID_REUSED) == 0) { + if (id != nullptr && !ID_IS_LINKED(id) && (id->tag & LIB_TAG_UNDO_OLD_ID_REUSED) == 0) { bool do_stop_iter = true; if (GS(id_self->name) == ID_OB) { Object *ob_self = (Object *)id_self; if (ob_self->type == OB_ARMATURE) { if (ob_self->data == id) { BLI_assert(GS(id->name) == ID_AR); - if (ob_self->pose != NULL) { + if (ob_self->pose != nullptr) { /* We have a changed/re-read armature used by an unchanged armature object: our beloved * Bone pointers from the object's pose need their usual special treatment. */ ob_self->pose->flag |= POSE_RECALC; @@ -151,7 +151,7 @@ static void memfile_undosys_unfinished_id_previews_restart(ID *id) } if (!BKE_previewimg_is_finished(preview, i)) { - ED_preview_restart_queue_add(id, i); + ED_preview_restart_queue_add(id, eIconSizes(i)); } } } @@ -160,7 +160,7 @@ static void memfile_undosys_step_decode(struct bContext *C, struct Main *bmain, UndoStep *us_p, const eUndoStepDir undo_direction, - bool UNUSED(is_final)) + bool /*is_final*/) { BLI_assert(undo_direction != STEP_INVALID); @@ -187,7 +187,7 @@ static void memfile_undosys_step_decode(struct bContext *C, * fine-grained update flags now. */ UndoStep *us_next = us_p->next; - if (us_next != NULL) { + if (us_next != nullptr) { if (us_next->use_old_bmain_data == false) { use_old_bmain_data = false; } @@ -196,7 +196,7 @@ static void memfile_undosys_step_decode(struct bContext *C, /* Extract depsgraphs from current bmain (which may be freed during undo step reading), * and store them for re-use. */ - GHash *depsgraphs = NULL; + GHash *depsgraphs = nullptr; if (use_old_bmain_data) { depsgraphs = BKE_scene_undo_depsgraphs_extract(bmain); } @@ -232,11 +232,11 @@ static void memfile_undosys_step_decode(struct bContext *C, /* We need to inform depsgraph about re-used old IDs that would be using newly read * data-blocks, at least COW evaluated copies need to be updated... */ - ID *id = NULL; + ID *id = nullptr; FOREACH_MAIN_ID_BEGIN (bmain, id) { if (id->tag & LIB_TAG_UNDO_OLD_ID_REUSED) { BKE_library_foreach_ID_link( - bmain, id, memfile_undosys_step_id_reused_cb, NULL, IDWALK_READONLY); + bmain, id, memfile_undosys_step_id_reused_cb, nullptr, IDWALK_READONLY); } /* Tag depsgraph to update data-block for changes that happened between the @@ -246,12 +246,12 @@ static void memfile_undosys_step_decode(struct bContext *C, } bNodeTree *nodetree = ntreeFromID(id); - if (nodetree != NULL && nodetree->id.recalc != 0) { + if (nodetree != nullptr && nodetree->id.recalc != 0) { DEG_id_tag_update_ex(bmain, &nodetree->id, nodetree->id.recalc); } if (GS(id->name) == ID_SCE) { Scene *scene = (Scene *)id; - if (scene->master_collection != NULL && scene->master_collection->id.recalc != 0) { + if (scene->master_collection != nullptr && scene->master_collection->id.recalc != 0) { DEG_id_tag_update_ex( bmain, &scene->master_collection->id, scene->master_collection->id.recalc); } @@ -271,12 +271,12 @@ static void memfile_undosys_step_decode(struct bContext *C, * loop because DEG_id_tag_update may set tags on other datablocks. */ id->recalc_after_undo_push = 0; bNodeTree *nodetree = ntreeFromID(id); - if (nodetree != NULL) { + if (nodetree != nullptr) { nodetree->id.recalc_after_undo_push = 0; } if (GS(id->name) == ID_SCE) { Scene *scene = (Scene *)id; - if (scene->master_collection != NULL) { + if (scene->master_collection != nullptr) { scene->master_collection->id.recalc_after_undo_push = 0; } } @@ -284,7 +284,7 @@ static void memfile_undosys_step_decode(struct bContext *C, FOREACH_MAIN_ID_END; } else { - ID *id = NULL; + ID *id = nullptr; FOREACH_MAIN_ID_BEGIN (bmain, id) { /* Restart preview generation if the undo state was generating previews. */ memfile_undosys_unfinished_id_previews_restart(id); @@ -300,9 +300,9 @@ static void memfile_undosys_step_free(UndoStep *us_p) /* To avoid unnecessary slow down, free backwards * (so we don't need to merge when clearing all). */ MemFileUndoStep *us = (MemFileUndoStep *)us_p; - if (us_p->next != NULL) { + if (us_p->next != nullptr) { UndoStep *us_next_p = BKE_undosys_step_same_type_next(us_p); - if (us_next_p != NULL) { + if (us_next_p != nullptr) { MemFileUndoStep *us_next = (MemFileUndoStep *)us_next_p; BLO_memfile_merge(&us->data->memfile, &us_next->data->memfile); } @@ -346,13 +346,13 @@ struct MemFile *ED_undosys_stack_memfile_get_active(UndoStack *ustack) if (us) { return ed_undosys_step_get_memfile(us); } - return NULL; + return nullptr; } void ED_undosys_stack_memfile_id_changed_tag(UndoStack *ustack, ID *id) { UndoStep *us = ustack->step_active; - if (id == NULL || us == NULL || us->type != BKE_UNDOSYS_TYPE_MEMFILE) { + if (id == nullptr || us == nullptr || us->type != BKE_UNDOSYS_TYPE_MEMFILE) { return; } diff --git a/source/blender/editors/undo/undo_intern.h b/source/blender/editors/undo/undo_intern.hh similarity index 91% rename from source/blender/editors/undo/undo_intern.h rename to source/blender/editors/undo/undo_intern.hh index b7fd4dff5ba..30efd76be30 100644 --- a/source/blender/editors/undo/undo_intern.h +++ b/source/blender/editors/undo/undo_intern.hh @@ -10,7 +10,7 @@ struct UndoType; -/* memfile_undo.c */ +/* memfile_undo.cc */ /** Export for ED_undo_sys. */ void ED_memfile_undosys_type(struct UndoType *ut); diff --git a/source/blender/editors/undo/undo_system_types.c b/source/blender/editors/undo/undo_system_types.cc similarity index 98% rename from source/blender/editors/undo/undo_system_types.c rename to source/blender/editors/undo/undo_system_types.cc index af74a7f3c04..f125d2e3c12 100644 --- a/source/blender/editors/undo/undo_system_types.c +++ b/source/blender/editors/undo/undo_system_types.cc @@ -19,7 +19,7 @@ #include "ED_sculpt.h" #include "ED_text.h" #include "ED_undo.h" -#include "undo_intern.h" +#include "undo_intern.hh" /* Keep last */ #include "BKE_undo_system.h" diff --git a/source/blender/editors/uvedit/uvedit_clipboard.cc b/source/blender/editors/uvedit/uvedit_clipboard.cc index 9c8722b36a0..bb3c4460d46 100644 --- a/source/blender/editors/uvedit/uvedit_clipboard.cc +++ b/source/blender/editors/uvedit/uvedit_clipboard.cc @@ -36,9 +36,7 @@ #include "uvedit_clipboard_graph_iso.hh" #include "uvedit_intern.h" /* linker, extern "C" */ -extern "C" { -void UV_clipboard_free(void); -} +void UV_clipboard_free(); class UV_ClipboardBuffer { public: diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index 7dca7ce7ead..2db80049e05 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -41,11 +41,11 @@ set(SRC intern/wm_draw.c intern/wm_event_query.c intern/wm_event_system.cc - intern/wm_files.c + intern/wm_files.cc intern/wm_files_link.c intern/wm_gesture.c intern/wm_gesture_ops.c - intern/wm_init_exit.c + intern/wm_init_exit.cc intern/wm_jobs.c intern/wm_keymap.c intern/wm_keymap_utils.c @@ -105,6 +105,10 @@ set(LIB bf_sequencer ) +if(WIN32) + add_definitions(-DNOMINMAX) +endif() + if(WITH_AUDASPACE) list(APPEND INC_SYS ${AUDASPACE_C_INCLUDE_DIRS} diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index ee0cba5ec7c..02f465c319a 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -274,7 +274,7 @@ void WM_window_set_dpi(const wmWindow *win); bool WM_stereo3d_enabled(struct wmWindow *win, bool only_fullscreen_test); -/* wm_files.c */ +/* wm_files.cc */ void WM_file_autoexec_init(const char *filepath); bool WM_file_read(struct bContext *C, const char *filepath, struct ReportList *reports); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 085ddaac5a5..e49441ed42a 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -1270,7 +1270,7 @@ typedef struct RecentFile { /* Logging */ struct CLG_LogRef; -/* wm_init_exit.c */ +/* wm_init_exit.cc */ extern struct CLG_LogRef *WM_LOG_OPERATORS; extern struct CLG_LogRef *WM_LOG_HANDLERS; diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.cc similarity index 87% rename from source/blender/windowmanager/intern/wm_files.c rename to source/blender/windowmanager/intern/wm_files.cc index 712bee6ef8b..75c9ea42e3a 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.cc @@ -151,11 +151,11 @@ static CLG_LogRef LOG = {"wm.files"}; void WM_file_tag_modified(void) { - wmWindowManager *wm = G_MAIN->wm.first; + wmWindowManager *wm = static_cast(G_MAIN->wm.first); if (wm->file_saved) { wm->file_saved = 0; /* notifier that data changed, for save-over warning or header */ - WM_main_add_notifier(NC_WM | ND_DATACHANGED, NULL); + WM_main_add_notifier(NC_WM | ND_DATACHANGED, nullptr); } } @@ -185,7 +185,7 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist) wmWindow *active_win = CTX_wm_window(C); /* first wrap up running stuff */ - /* code copied from wm_init_exit.c */ + /* code copied from wm_init_exit.cc */ LISTBASE_FOREACH (wmWindowManager *, wm, wmlist) { WM_jobs_kill_all(wm); @@ -201,14 +201,14 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist) * However it's _not_ cleared when the UI is kept. This complicates use from add-ons * which can re-register subscribers on file-load. To support this use case, * it's best to have predictable behavior - always clear. */ - if (wm->message_bus != NULL) { + if (wm->message_bus != nullptr) { WM_msgbus_destroy(wm->message_bus); - wm->message_bus = NULL; + wm->message_bus = nullptr; } } BLI_listbase_clear(&G_MAIN->wm); - if (G_MAIN->name_map != NULL) { + if (G_MAIN->name_map != nullptr) { BKE_main_namemap_destroy(&G_MAIN->name_map); } @@ -219,10 +219,10 @@ static void wm_window_match_init(bContext *C, ListBase *wmlist) * above frees the active menu (at least, in the 'startup splash' case), * causing use-after-free error in later handling of the button callbacks in UI code * (see ui_apply_but_funcs_after()). - * Tried solving this by always NULL-ing context's menu when setting wm/win/etc., + * Tried solving this by always nullptr-ing context's menu when setting wm/win/etc., * but it broke popups refreshing (see T47632), * so for now just handling this specific case here. */ - CTX_wm_menu_set(C, NULL); + CTX_wm_menu_set(C, nullptr); ED_editors_exit(G_MAIN, true); @@ -244,23 +244,23 @@ static void wm_window_substitute_old(wmWindowManager *oldwm, wm->winactive = win; } if (oldwm->windrawable == oldwin) { - oldwm->windrawable = NULL; + oldwm->windrawable = nullptr; wm->windrawable = win; } /* File loading in background mode still calls this. */ if (!G.background) { /* Pointer back. */ - GHOST_SetWindowUserData(win->ghostwin, win); + GHOST_SetWindowUserData(static_cast(win->ghostwin), win); } - oldwin->ghostwin = NULL; - oldwin->gpuctx = NULL; + oldwin->ghostwin = nullptr; + oldwin->gpuctx = nullptr; win->eventstate = oldwin->eventstate; win->event_last_handled = oldwin->event_last_handled; - oldwin->eventstate = NULL; - oldwin->event_last_handled = NULL; + oldwin->eventstate = nullptr; + oldwin->event_last_handled = nullptr; /* Ensure proper screen re-scaling. */ win->sizex = oldwin->sizex; @@ -275,8 +275,8 @@ static void wm_window_match_keep_current_wm(const bContext *C, ListBase *r_new_wm_list) { Main *bmain = CTX_data_main(C); - wmWindowManager *wm = current_wm_list->first; - bScreen *screen = NULL; + wmWindowManager *wm = static_cast(current_wm_list->first); + bScreen *screen = nullptr; /* match oldwm to new dbase, only old files */ wm->initialized &= ~WM_WINDOW_IS_INIT; @@ -321,8 +321,9 @@ static void wm_window_match_replace_by_file_wm(bContext *C, ListBase *readfile_wm_list, ListBase *r_new_wm_list) { - wmWindowManager *oldwm = current_wm_list->first; - wmWindowManager *wm = readfile_wm_list->first; /* will become our new WM */ + wmWindowManager *oldwm = static_cast(current_wm_list->first); + /* will become our new WM */ + wmWindowManager *wm = static_cast(readfile_wm_list->first); /* Support window-manager ID references being held between file load operations by keeping * #Main.wm.first memory address in-place, while swapping all of it's contents. @@ -334,7 +335,7 @@ static void wm_window_match_replace_by_file_wm(bContext *C, * however it's possible with ID-properties & animation-drivers. * At some point we could check on disallowing this since it doesn't seem practical. */ Main *bmain = G_MAIN; - BLI_assert(bmain->relations == NULL); + BLI_assert(bmain->relations == nullptr); BKE_libblock_remap(bmain, wm, oldwm, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_USER_CLEAR); /* Maintain the undo-depth between file loads. Useful so Python can perform @@ -364,13 +365,13 @@ static void wm_window_match_replace_by_file_wm(bContext *C, wm->userconf = oldwm->userconf; BLI_listbase_clear(&oldwm->keyconfigs); - oldwm->addonconf = NULL; - oldwm->defaultconf = NULL; - oldwm->userconf = NULL; + oldwm->addonconf = nullptr; + oldwm->defaultconf = nullptr; + oldwm->userconf = nullptr; /* ensure making new keymaps and set space types */ wm->initialized = 0; - wm->winactive = NULL; + wm->winactive = nullptr; /* Clearing drawable of before deleting any context * to avoid clearing the wrong wm. */ @@ -388,7 +389,10 @@ static void wm_window_match_replace_by_file_wm(bContext *C, } /* make sure at least one window is kept open so we don't lose the context, check T42303 */ if (!has_match) { - wm_window_substitute_old(oldwm, wm, oldwm->windows.first, wm->windows.first); + wm_window_substitute_old(oldwm, + wm, + static_cast(oldwm->windows.first), + static_cast(wm->windows.first)); } wm_close_and_free_all(C, current_wm_list); @@ -452,7 +456,7 @@ static void wm_gpu_backend_override_from_userdef(void) return; } - GPU_backend_type_selection_set_override(U.gpu_backend); + GPU_backend_type_selection_set_override(eGPUBackendType(U.gpu_backend)); } /** @@ -528,7 +532,7 @@ static int wm_read_exotic(const char *name) } FileReader *rawfile = BLI_filereader_new_file(filedes); - if (rawfile == NULL) { + if (rawfile == nullptr) { return BKE_READ_EXOTIC_FAIL_OPEN; } @@ -547,7 +551,7 @@ static int wm_read_exotic(const char *name) } /* check for compressed .blend */ - FileReader *compressed_file = NULL; + FileReader *compressed_file = nullptr; if (BLI_file_magic_is_gzip(header)) { /* In earlier versions of Blender (before 3.0), compressed files used `Gzip` instead of `Zstd`. * While these files will no longer be written, there still needs to be reading support. */ @@ -558,7 +562,7 @@ static int wm_read_exotic(const char *name) } /* If a compression signature matches, try decompressing the start and check if it's a .blend */ - if (compressed_file != NULL) { + if (compressed_file != nullptr) { size_t len = compressed_file->read(compressed_file, header, sizeof(header)); compressed_file->close(compressed_file); if (len == sizeof(header) && STREQLEN(header, "BLENDER", 7)) { @@ -597,11 +601,12 @@ void WM_file_autoexec_init(const char *filepath) void wm_file_read_report(bContext *C, Main *bmain) { - ReportList *reports = NULL; + ReportList *reports = nullptr; LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) { if (scene->r.engine[0] && - BLI_findstring(&R_engines, scene->r.engine, offsetof(RenderEngineType, idname)) == NULL) { - if (reports == NULL) { + BLI_findstring(&R_engines, scene->r.engine, offsetof(RenderEngineType, idname)) == + nullptr) { + if (reports == nullptr) { reports = CTX_wm_reports(C); } @@ -627,7 +632,7 @@ void wm_file_read_report(bContext *C, Main *bmain) * \note In the case of #WM_file_read the file may fail to load. * Change here shouldn't cause user-visible changes in that case. */ -static void wm_file_read_pre(bContext *C, bool use_data, bool UNUSED(use_userdef)) +static void wm_file_read_pre(bContext *C, bool use_data, bool /*use_userdef*/) { if (use_data) { BKE_callback_exec_null(CTX_data_main(C), BKE_CB_EVT_LOAD_PRE); @@ -674,7 +679,7 @@ static void wm_file_read_post(bContext *C, const struct wmFileReadPost_Params *p /* remove windows which failed to be added via WM_check */ wm_window_ghostwindows_remove_invalid(C, wm); } - CTX_wm_window_set(C, wm->windows.first); + CTX_wm_window_set(C, static_cast(wm->windows.first)); } #ifdef WITH_PYTHON @@ -688,15 +693,16 @@ static void wm_file_read_post(bContext *C, const struct wmFileReadPost_Params *p if (use_userdef || reset_app_template) { /* Only run when we have a template path found. */ if (BKE_appdir_app_template_any()) { - BPY_run_string_eval( - C, (const char *[]){"bl_app_template_utils", NULL}, "bl_app_template_utils.reset()"); + const char *imports[] = {"bl_app_template_utils", nullptr}; + BPY_run_string_eval(C, imports, "bl_app_template_utils.reset()"); reset_all = true; } } if (reset_all) { + const char *imports[] = {"bpy", "addon_utils", nullptr}; BPY_run_string_exec( C, - (const char *[]){"bpy", "addon_utils", NULL}, + imports, /* Refresh scripts as the preferences may have changed the user-scripts path. * * This is needed when loading settings from the previous version, @@ -739,7 +745,7 @@ static void wm_file_read_post(bContext *C, const struct wmFileReadPost_Params *p } if (use_data) { - /* important to do before NULL'ing the context */ + /* important to do before nullptr'ing the context */ BKE_callback_exec_null(bmain, BKE_CB_EVT_VERSION_UPDATE); BKE_callback_exec_null(bmain, BKE_CB_EVT_LOAD_POST); if (is_factory_startup) { @@ -757,7 +763,7 @@ static void wm_file_read_post(bContext *C, const struct wmFileReadPost_Params *p ED_editors_init(C); #if 1 - WM_event_add_notifier(C, NC_WM | ND_FILEREAD, NULL); + WM_event_add_notifier(C, NC_WM | ND_FILEREAD, nullptr); #else WM_msg_publish_static(CTX_wm_message_bus(C), WM_MSG_STATICTYPE_FILE_READ); #endif @@ -771,7 +777,7 @@ static void wm_file_read_post(bContext *C, const struct wmFileReadPost_Params *p if (use_data) { if (!G.background) { - if (wm->undo_stack == NULL) { + if (wm->undo_stack == nullptr) { wm->undo_stack = BKE_undosys_stack_create(); } else { @@ -787,10 +793,10 @@ static void wm_file_read_post(bContext *C, const struct wmFileReadPost_Params *p /* in background mode this makes it hard to load * a blend file and do anything since the screen * won't be set to a valid value again */ - CTX_wm_window_set(C, NULL); /* exits queues */ + CTX_wm_window_set(C, nullptr); /* exits queues */ /* Ensure auto-run action is not used from a previous blend file load. */ - wm_test_autorun_revert_action_set(NULL, NULL); + wm_test_autorun_revert_action_set(nullptr, nullptr); /* Ensure tools are registered. */ WM_toolsystem_init(C); @@ -814,35 +820,35 @@ static void file_read_reports_finalize(BlendFileReadReport *bf_reports) duration_lib_override_recursive_resync_seconds; BLI_math_time_seconds_decompose(bf_reports->duration.whole, - NULL, - NULL, + nullptr, + nullptr, &duration_whole_minutes, &duration_whole_seconds, - NULL); + nullptr); BLI_math_time_seconds_decompose(bf_reports->duration.libraries, - NULL, - NULL, + nullptr, + nullptr, &duration_libraries_minutes, &duration_libraries_seconds, - NULL); + nullptr); BLI_math_time_seconds_decompose(bf_reports->duration.lib_overrides, - NULL, - NULL, + nullptr, + nullptr, &duration_lib_override_minutes, &duration_lib_override_seconds, - NULL); + nullptr); BLI_math_time_seconds_decompose(bf_reports->duration.lib_overrides_resync, - NULL, - NULL, + nullptr, + nullptr, &duration_lib_override_resync_minutes, &duration_lib_override_resync_seconds, - NULL); + nullptr); BLI_math_time_seconds_decompose(bf_reports->duration.lib_overrides_recursive_resync, - NULL, - NULL, + nullptr, + nullptr, &duration_lib_override_recursive_resync_minutes, &duration_lib_override_recursive_resync_seconds, - NULL); + nullptr); CLOG_INFO( &LOG, 0, "Blender file read in %.0fm%.2fs", duration_whole_minutes, duration_whole_seconds); @@ -867,9 +873,9 @@ static void file_read_reports_finalize(BlendFileReadReport *bf_reports) duration_lib_override_recursive_resync_seconds); if (bf_reports->resynced_lib_overrides_libraries_count != 0) { - for (LinkNode *node_lib = bf_reports->resynced_lib_overrides_libraries; node_lib != NULL; + for (LinkNode *node_lib = bf_reports->resynced_lib_overrides_libraries; node_lib != nullptr; node_lib = node_lib->next) { - Library *library = node_lib->link; + Library *library = static_cast(node_lib->link); BKE_reportf( bf_reports->reports, RPT_INFO, "Library %s needs overrides resync", library->filepath); } @@ -924,8 +930,8 @@ static void file_read_reports_finalize(BlendFileReadReport *bf_reports) MAXSEQ); } - BLI_linklist_free(bf_reports->resynced_lib_overrides_libraries, NULL); - bf_reports->resynced_lib_overrides_libraries = NULL; + BLI_linklist_free(bf_reports->resynced_lib_overrides_libraries, nullptr); + bf_reports->resynced_lib_overrides_libraries = nullptr; } bool WM_file_read(bContext *C, const char *filepath, ReportList *reports) @@ -950,18 +956,18 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports) /* we didn't succeed, now try to read Blender file */ if (retval == BKE_READ_EXOTIC_OK_BLEND) { - const struct BlendFileReadParams params = { - .is_startup = false, - /* Loading preferences when the user intended to load a regular file is a security - * risk, because the excluded path list is also loaded. Further it's just confusing - * if a user loads a file and various preferences change. */ - .skip_flags = BLO_READ_SKIP_USERDEF, - }; + BlendFileReadParams params{}; + params.is_startup = false; + /* Loading preferences when the user intended to load a regular file is a security + * risk, because the excluded path list is also loaded. Further it's just confusing + * if a user loads a file and various preferences change. */ + params.skip_flags = BLO_READ_SKIP_USERDEF; - BlendFileReadReport bf_reports = {.reports = reports, - .duration.whole = PIL_check_seconds_timer()}; + BlendFileReadReport bf_reports{}; + bf_reports.reports = reports; + bf_reports.duration.whole = PIL_check_seconds_timer(); struct BlendFileData *bfd = BKE_blendfile_read(filepath, ¶ms, &bf_reports); - if (bfd != NULL) { + if (bfd != nullptr) { wm_file_read_pre(C, use_data, use_userdef); /* Put aside screens to match with persistent windows later, @@ -992,14 +998,13 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports) wm_history_file_update(); } - wm_file_read_post(C, - &(const struct wmFileReadPost_Params){ - .use_data = use_data, - .use_userdef = use_userdef, - .is_startup_file = false, - .is_factory_startup = false, - .reset_app_template = false, - }); + wmFileReadPost_Params read_file_post_params{}; + read_file_post_params.use_data = use_data; + read_file_post_params.use_userdef = use_userdef; + read_file_post_params.is_startup_file = false; + read_file_post_params.is_factory_startup = false; + read_file_post_params.reset_app_template = false; + wm_file_read_post(C, &read_file_post_params); bf_reports.duration.whole = PIL_check_seconds_timer() - bf_reports.duration.whole; file_read_reports_finalize(&bf_reports); @@ -1067,7 +1072,7 @@ void WM_init_state_app_template_set(const char *app_template) const char *WM_init_state_app_template_get(void) { - return wm_init_state_app_template.override ? wm_init_state_app_template.app_template : NULL; + return wm_init_state_app_template.override ? wm_init_state_app_template.app_template : nullptr; } /** \} */ @@ -1113,7 +1118,7 @@ void wm_homefile_read_ex(bContext *C, * '{BLENDER_SYSTEM_SCRIPTS}/startup/bl_app_templates_system/{app_template}' */ char app_template_config[FILE_MAX]; - eBLOReadSkip skip_flags = 0; + eBLOReadSkip skip_flags = eBLOReadSkip(0); if (use_data == false) { skip_flags |= BLO_READ_SKIP_DATA; @@ -1126,10 +1131,10 @@ void wm_homefile_read_ex(bContext *C, * or use app-template startup.blend which the user hasn't saved. */ bool is_factory_startup = true; - const char *app_template = NULL; + const char *app_template = nullptr; bool update_defaults = false; - if (filepath_startup_override != NULL) { + if (filepath_startup_override != nullptr) { /* pass */ } else if (app_template_override) { @@ -1167,7 +1172,8 @@ void wm_homefile_read_ex(bContext *C, * * Note that this fits into 'wm_file_read_pre' function but gets messy * since we need to know if 'reset_app_template' is true. */ - BPY_run_string_eval(C, (const char *[]){"addon_utils", NULL}, "addon_utils.disable_all()"); + const char *imports[] = {"addon_utils", nullptr}; + BPY_run_string_eval(C, imports, "addon_utils.disable_all()"); } #endif /* WITH_PYTHON */ } @@ -1187,7 +1193,7 @@ void wm_homefile_read_ex(bContext *C, app_template_system[0] = '\0'; app_template_config[0] = '\0'; - const char *const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL); + const char *const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, nullptr); if (!use_factory_settings) { if (cfgdir) { BLI_path_join(filepath_startup, sizeof(filepath_startup), cfgdir, BLENDER_STARTUP_FILE); @@ -1213,10 +1219,10 @@ void wm_homefile_read_ex(bContext *C, skip_flags |= BLO_READ_SKIP_USERDEF; } else if (!use_factory_settings && BLI_exists(filepath_userdef)) { - UserDef *userdef = BKE_blendfile_userdef_read(filepath_userdef, NULL); - if (userdef != NULL) { + UserDef *userdef = BKE_blendfile_userdef_read(filepath_userdef, nullptr); + if (userdef != nullptr) { BKE_blender_userdef_data_set_and_free(userdef); - userdef = NULL; + userdef = nullptr; skip_flags |= BLO_READ_SKIP_USERDEF; printf("Read prefs: %s\n", filepath_userdef); @@ -1224,7 +1230,7 @@ void wm_homefile_read_ex(bContext *C, } } - if ((app_template != NULL) && (app_template[0] != '\0')) { + if ((app_template != nullptr) && (app_template[0] != '\0')) { if (!BKE_appdir_app_template_id_search( app_template, app_template_system, sizeof(app_template_system))) { /* Can safely continue with code below, just warn it's not found. */ @@ -1260,14 +1266,14 @@ void wm_homefile_read_ex(bContext *C, if (!use_factory_settings || (filepath_startup[0] != '\0')) { if (BLI_access(filepath_startup, R_OK) == 0) { - const struct BlendFileReadParams params = { - .is_startup = true, - .skip_flags = skip_flags | BLO_READ_SKIP_USERDEF, - }; - BlendFileReadReport bf_reports = {.reports = reports}; + BlendFileReadParams params{}; + params.is_startup = true; + params.skip_flags = skip_flags | BLO_READ_SKIP_USERDEF; + BlendFileReadReport bf_reports{}; + bf_reports.reports = reports; struct BlendFileData *bfd = BKE_blendfile_read(filepath_startup, ¶ms, &bf_reports); - if (bfd != NULL) { + if (bfd != nullptr) { BKE_blendfile_read_setup_ex( C, bfd, ¶ms, &bf_reports, update_defaults && use_data, app_template); success = true; @@ -1292,14 +1298,14 @@ void wm_homefile_read_ex(bContext *C, } if (success == false) { - const struct BlendFileReadParams params = { - .is_startup = true, - .skip_flags = skip_flags, - }; + BlendFileReadParams read_file_params{}; + read_file_params.is_startup = true; + read_file_params.skip_flags = skip_flags; struct BlendFileData *bfd = BKE_blendfile_read_from_memory( - datatoc_startup_blend, datatoc_startup_blend_size, ¶ms, NULL); - if (bfd != NULL) { - BKE_blendfile_read_setup_ex(C, bfd, ¶ms, &(BlendFileReadReport){NULL}, true, NULL); + datatoc_startup_blend, datatoc_startup_blend_size, &read_file_params, nullptr); + if (bfd != nullptr) { + BlendFileReadReport read_report{}; + BKE_blendfile_read_setup_ex(C, bfd, &read_file_params, &read_report, true, nullptr); success = true; } @@ -1330,18 +1336,18 @@ void wm_homefile_read_ex(bContext *C, } if (use_userdef) { - UserDef *userdef_template = NULL; + UserDef *userdef_template = nullptr; /* just avoids missing file warning */ if (BLI_exists(temp_path)) { - userdef_template = BKE_blendfile_userdef_read(temp_path, NULL); + userdef_template = BKE_blendfile_userdef_read(temp_path, nullptr); } - if (userdef_template == NULL) { + if (userdef_template == nullptr) { /* we need to have preferences load to overwrite preferences from previous template */ userdef_template = BKE_blendfile_userdef_from_defaults(); } if (userdef_template) { BKE_blender_userdef_app_template_data_set_and_free(userdef_template); - userdef_template = NULL; + userdef_template = nullptr; } } } @@ -1379,22 +1385,23 @@ void wm_homefile_read_ex(bContext *C, } { - const struct wmFileReadPost_Params params_file_read_post = { - .use_data = use_data, - .use_userdef = use_userdef, - .is_startup_file = true, - .is_factory_startup = is_factory_startup, - .reset_app_template = reset_app_template, - }; - if (r_params_file_read_post == NULL) { + wmFileReadPost_Params params_file_read_post{}; + params_file_read_post.use_data = use_data; + params_file_read_post.use_userdef = use_userdef; + params_file_read_post.is_startup_file = true; + params_file_read_post.is_factory_startup = is_factory_startup; + params_file_read_post.reset_app_template = reset_app_template; + + if (r_params_file_read_post == nullptr) { wm_file_read_post(C, ¶ms_file_read_post); } else { - *r_params_file_read_post = MEM_mallocN(sizeof(struct wmFileReadPost_Params), __func__); + *r_params_file_read_post = static_cast( + MEM_mallocN(sizeof(wmFileReadPost_Params), __func__)); **r_params_file_read_post = params_file_read_post; /* Match #wm_file_read_post which leaves the window cleared too. */ - CTX_wm_window_set(C, NULL); + CTX_wm_window_set(C, nullptr); } } } @@ -1403,7 +1410,7 @@ void wm_homefile_read(bContext *C, const struct wmHomeFileRead_Params *params_homefile, ReportList *reports) { - wm_homefile_read_ex(C, params_homefile, reports, NULL); + wm_homefile_read_ex(C, params_homefile, reports, nullptr); } void wm_homefile_read_post(struct bContext *C, @@ -1421,7 +1428,7 @@ void wm_homefile_read_post(struct bContext *C, void wm_history_file_read(void) { - const char *const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL); + const char *const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, nullptr); if (!cfgdir) { return; } @@ -1438,7 +1445,7 @@ void wm_history_file_read(void) /* read list of recent opened files from recent-files.txt to memory */ for (l = lines, num = 0; l && (num < U.recent_files); l = l->next) { - const char *line = l->link; + const char *line = static_cast(l->link); /* don't check if files exist, causes slow startup for remote/external drives */ if (line[0]) { struct RecentFile *recent = (RecentFile *)MEM_mallocN(sizeof(RecentFile), "RecentFile"); @@ -1453,7 +1460,7 @@ void wm_history_file_read(void) static RecentFile *wm_history_file_new(const char *filepath) { - RecentFile *recent = MEM_mallocN(sizeof(RecentFile), "RecentFile"); + RecentFile *recent = static_cast(MEM_mallocN(sizeof(RecentFile), "RecentFile")); recent->filepath = BLI_strdup(filepath); return recent; } @@ -1474,7 +1481,8 @@ static void wm_history_files_free(void) static RecentFile *wm_file_history_find(const char *filepath) { - return BLI_findstring_ptr(&G.recent_files, filepath, offsetof(RecentFile, filepath)); + return static_cast( + BLI_findstring_ptr(&G.recent_files, filepath, offsetof(RecentFile, filepath))); } /** @@ -1487,8 +1495,8 @@ static void wm_history_file_write(void) char name[FILE_MAX]; FILE *fp; - /* will be NULL in background mode */ - user_config_dir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL); + /* will be nullptr in background mode */ + user_config_dir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, nullptr); if (!user_config_dir) { return; } @@ -1517,7 +1525,7 @@ static void wm_history_file_update(void) return; } - recent = G.recent_files.first; + recent = static_cast(G.recent_files.first); /* refresh recent-files.txt of recent opened files, when current file was changed */ if (!(recent) || (BLI_path_cmp(recent->filepath, blendfile_path) != 0)) { @@ -1527,7 +1535,8 @@ static void wm_history_file_update(void) } else { RecentFile *recent_next; - for (recent = BLI_findlink(&G.recent_files, U.recent_files - 1); recent; + for (recent = static_cast(BLI_findlink(&G.recent_files, U.recent_files - 1)); + recent; recent = recent_next) { recent_next = recent->next; wm_history_file_free(recent); @@ -1574,11 +1583,11 @@ static void wm_history_file_update(void) */ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **r_thumb) { - *r_thumb = NULL; + *r_thumb = nullptr; wmWindow *win = CTX_wm_window(C); - if (G.background || (win == NULL)) { - return NULL; + if (G.background || (win == nullptr)) { + return nullptr; } /* The window to capture should be a main window (without parent). */ @@ -1588,7 +1597,7 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **r_t int win_size[2]; uint *buffer = WM_window_pixels_read(CTX_wm_manager(C), win, win_size); - ImBuf *ibuf = IMB_allocFromBufferOwn(buffer, NULL, win_size[0], win_size[1], 24); + ImBuf *ibuf = IMB_allocFromBufferOwn(buffer, nullptr, win_size[0], win_size[1], 24); if (ibuf) { int ex, ey; @@ -1608,7 +1617,7 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **r_t ImBuf *thumb_ibuf = IMB_dupImBuf(ibuf); IMB_scaleImBuf(thumb_ibuf, ex, ey); - BlendThumbnail *thumb = BKE_main_thumbnail_from_imbuf(NULL, thumb_ibuf); + BlendThumbnail *thumb = BKE_main_thumbnail_from_imbuf(nullptr, thumb_ibuf); IMB_freeImBuf(thumb_ibuf); *r_thumb = thumb; } @@ -1620,18 +1629,18 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **r_t /** * Render the current scene with the active camera. * - * \param screen: can be NULL. + * \param screen: can be nullptr. */ static ImBuf *blend_file_thumb_from_camera(const bContext *C, Scene *scene, bScreen *screen, BlendThumbnail **r_thumb) { - *r_thumb = NULL; + *r_thumb = nullptr; - /* Scene can be NULL if running a script at startup and calling the save operator. */ - if (G.background || scene == NULL) { - return NULL; + /* Scene can be nullptr if running a script at startup and calling the save operator. */ + if (G.background || scene == nullptr) { + return nullptr; } /* will be scaled down, but gives some nice oversampling */ @@ -1643,20 +1652,20 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C, char err_out[256] = "unknown"; /* screen if no camera found */ - ScrArea *area = NULL; - ARegion *region = NULL; - View3D *v3d = NULL; + ScrArea *area = nullptr; + ARegion *region = nullptr; + View3D *v3d = nullptr; - if (screen != NULL) { + if (screen != nullptr) { area = BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0); if (area) { - v3d = area->spacedata.first; + v3d = static_cast(area->spacedata.first); region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW); } } - if (scene->camera == NULL && v3d == NULL) { - return NULL; + if (scene->camera == nullptr && v3d == nullptr) { + return nullptr; } Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); @@ -1668,8 +1677,8 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C, if (scene->camera) { ibuf = ED_view3d_draw_offscreen_imbuf_simple(depsgraph, scene, - (v3d) ? &v3d->shading : NULL, - (v3d) ? v3d->shading.type : OB_SOLID, + (v3d) ? &v3d->shading : nullptr, + (v3d) ? eDrawType(v3d->shading.type) : OB_SOLID, scene->camera, PREVIEW_RENDER_LARGE_HEIGHT * 2, PREVIEW_RENDER_LARGE_HEIGHT * 2, @@ -1677,8 +1686,8 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C, (v3d) ? V3D_OFSDRAW_OVERRIDE_SCENE_SETTINGS : V3D_OFSDRAW_NONE, R_ALPHAPREMUL, - NULL, - NULL, + nullptr, + nullptr, err_out); } else { @@ -1691,9 +1700,9 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C, PREVIEW_RENDER_LARGE_HEIGHT * 2, IB_rect, R_ALPHAPREMUL, - NULL, + nullptr, true, - NULL, + nullptr, err_out); } @@ -1713,15 +1722,15 @@ static ImBuf *blend_file_thumb_from_camera(const bContext *C, thumb_ibuf = IMB_dupImBuf(ibuf); /* BLEN_THUMB_SIZE is size of thumbnail inside blend file: 128x128. */ IMB_scaleImBuf(thumb_ibuf, BLEN_THUMB_SIZE, BLEN_THUMB_SIZE); - thumb = BKE_main_thumbnail_from_imbuf(NULL, thumb_ibuf); + thumb = BKE_main_thumbnail_from_imbuf(nullptr, thumb_ibuf); IMB_freeImBuf(thumb_ibuf); /* Thumbnail saved to file-system should be 256x256. */ IMB_scaleImBuf(ibuf, PREVIEW_RENDER_LARGE_HEIGHT, PREVIEW_RENDER_LARGE_HEIGHT); } else { - /* '*r_thumb' needs to stay NULL to prevent a bad thumbnail from being handled. */ + /* '*r_thumb' needs to stay nullptr to prevent a bad thumbnail from being handled. */ CLOG_WARN(&LOG, "failed to create thumbnail: %s", err_out); - thumb = NULL; + thumb = nullptr; } /* must be freed by caller */ @@ -1742,7 +1751,8 @@ bool write_crash_blend(void) BLI_strncpy(path, BKE_main_blendfile_path_from_global(), sizeof(path)); BLI_path_extension_replace(path, sizeof(path), "_crash.blend"); - if (BLO_write_file(G_MAIN, path, G.fileflags, &(const struct BlendFileWriteParams){0}, NULL)) { + BlendFileWriteParams params{}; + if (BLO_write_file(G_MAIN, path, G.fileflags, ¶ms, nullptr)) { printf("written: %s\n", path); return 1; } @@ -1763,8 +1773,8 @@ static bool wm_file_write(bContext *C, Main *bmain = CTX_data_main(C); int len; int ok = false; - BlendThumbnail *thumb = NULL, *main_thumb = NULL; - ImBuf *ibuf_thumb = NULL; + BlendThumbnail *thumb = nullptr, *main_thumb = nullptr; + ImBuf *ibuf_thumb = nullptr; len = strlen(filepath); @@ -1802,7 +1812,7 @@ static bool wm_file_write(bContext *C, ED_assets_pre_save(bmain); /* Enforce full override check/generation on file save. */ - BKE_lib_override_library_main_operations_create(bmain, true, NULL); + BKE_lib_override_library_main_operations_create(bmain, true, nullptr); /* NOTE: Ideally we would call `WM_redraw_windows` here to remove any open menus. * But we can crash if saving from a script, see T92704 & T97627. @@ -1822,9 +1832,9 @@ static bool wm_file_write(bContext *C, * useful for background-mode or thumbnail customization. */ main_thumb = thumb = bmain->blen_thumb; - if (thumb != NULL) { + if (thumb != nullptr) { /* In case we are given a valid thumbnail data, just generate image from it. */ - ibuf_thumb = BKE_main_thumbnail_to_imbuf(NULL, thumb); + ibuf_thumb = BKE_main_thumbnail_to_imbuf(nullptr, thumb); } else if (BLI_thread_is_main()) { int file_preview_type = U.file_preview_type; @@ -1832,8 +1842,8 @@ static bool wm_file_write(bContext *C, if (file_preview_type == USER_FILE_PREVIEW_AUTO) { Scene *scene = CTX_data_scene(C); bScreen *screen = CTX_wm_screen(C); - bool do_render = (scene != NULL && scene->camera != NULL && screen != NULL && - (BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0) != NULL)); + bool do_render = (scene != nullptr && scene->camera != nullptr && screen != nullptr && + (BKE_screen_find_big_area(screen, SPACE_VIEW3D, 0) != nullptr)); file_preview_type = do_render ? USER_FILE_PREVIEW_CAMERA : USER_FILE_PREVIEW_SCREENSHOT; } @@ -1864,16 +1874,12 @@ static bool wm_file_write(bContext *C, /* XXX(ton): temp solution to solve bug, real fix coming. */ bmain->recovered = false; - if (BLO_write_file(bmain, - filepath, - fileflags, - &(const struct BlendFileWriteParams){ - .remap_mode = remap_mode, - .use_save_versions = true, - .use_save_as_copy = use_save_as_copy, - .thumb = thumb, - }, - reports)) { + BlendFileWriteParams blend_write_params{}; + blend_write_params.remap_mode = remap_mode; + blend_write_params.use_save_versions = true; + blend_write_params.use_save_as_copy = use_save_as_copy; + blend_write_params.thumb = thumb; + if (BLO_write_file(bmain, filepath, fileflags, &blend_write_params, reports)) { const bool do_history_file_update = (G.background == false) && (CTX_wm_manager(C)->op_undo_depth == 0); @@ -1926,10 +1932,10 @@ static void wm_autosave_location(char filepath[FILE_MAX]) const int pid = abs(getpid()); char path[1024]; - /* Normally there is no need to check for this to be NULL, + /* Normally there is no need to check for this to be nullptr, * however this runs on exit when it may be cleared. */ Main *bmain = G_MAIN; - const char *blendfile_path = bmain ? BKE_main_blendfile_path(bmain) : NULL; + const char *blendfile_path = bmain ? BKE_main_blendfile_path(bmain) : nullptr; if (blendfile_path && (blendfile_path[0] != '\0')) { const char *basename = BLI_path_basename(blendfile_path); @@ -1947,7 +1953,7 @@ static void wm_autosave_location(char filepath[FILE_MAX]) * We could support #BLENDER_USER_AUTOSAVE on all platforms or remove it entirely. */ #ifdef WIN32 if (!BLI_exists(tempdir_base)) { - const char *savedir = BKE_appdir_folder_id_create(BLENDER_USER_AUTOSAVE, NULL); + const char *savedir = BKE_appdir_folder_id_create(BLENDER_USER_AUTOSAVE, nullptr); if (savedir) { tempdir_base = savedir; } @@ -1965,8 +1971,8 @@ static void wm_autosave_write(Main *bmain, wmWindowManager *wm) /* Fast save of last undo-buffer, now with UI. */ const bool use_memfile = (U.uiflag & USER_GLOBALUNDO) != 0; - MemFile *memfile = use_memfile ? ED_undosys_stack_memfile_get_active(wm->undo_stack) : NULL; - if (memfile != NULL) { + MemFile *memfile = use_memfile ? ED_undosys_stack_memfile_get_active(wm->undo_stack) : nullptr; + if (memfile != nullptr) { BLO_memfile_write_file(memfile, filepath); } else { @@ -1981,7 +1987,8 @@ static void wm_autosave_write(Main *bmain, wmWindowManager *wm) ED_editors_flush_edits(bmain); /* Error reporting into console. */ - BLO_write_file(bmain, filepath, fileflags, &(const struct BlendFileWriteParams){0}, NULL); + BlendFileWriteParams params{}; + BLO_write_file(bmain, filepath, fileflags, ¶ms, nullptr); } } @@ -1990,7 +1997,7 @@ static void wm_autosave_timer_begin_ex(wmWindowManager *wm, double timestep) wm_autosave_timer_end(wm); if (U.flag & USER_AUTOSAVE) { - wm->autosavetimer = WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, timestep); + wm->autosavetimer = WM_event_add_timer(wm, nullptr, TIMERAUTOSAVE, timestep); } } @@ -2002,8 +2009,8 @@ void wm_autosave_timer_begin(wmWindowManager *wm) void wm_autosave_timer_end(wmWindowManager *wm) { if (wm->autosavetimer) { - WM_event_remove_timer(wm, NULL, wm->autosavetimer); - wm->autosavetimer = NULL; + WM_event_remove_timer(wm, nullptr, wm->autosavetimer); + wm->autosavetimer = nullptr; } } @@ -2012,7 +2019,7 @@ void WM_file_autosave_init(wmWindowManager *wm) wm_autosave_timer_begin(wm); } -void wm_autosave_timer(Main *bmain, wmWindowManager *wm, wmTimer *UNUSED(wt)) +void wm_autosave_timer(Main *bmain, wmWindowManager *wm, wmTimer * /*wt*/) { wm_autosave_timer_end(wm); @@ -2073,7 +2080,7 @@ static void read_factory_reset_props(wmOperatorType *ot) false, "Factory Startup App-Template Only", ""); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE)); } /** \} */ @@ -2128,9 +2135,9 @@ static int wm_homefile_write_exec(bContext *C, wmOperator *op) char filepath[FILE_MAX]; int fileflags; - const char *app_template = U.app_template[0] ? U.app_template : NULL; + const char *app_template = U.app_template[0] ? U.app_template : nullptr; const char *const cfgdir = BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, app_template); - if (cfgdir == NULL) { + if (cfgdir == nullptr) { BKE_report(op->reports, RPT_ERROR, "Unable to create user config path"); return OPERATOR_CANCELLED; } @@ -2155,18 +2162,14 @@ static int wm_homefile_write_exec(bContext *C, wmOperator *op) /* Force save as regular blend file. */ fileflags = G.fileflags & ~G_FILE_COMPRESS; - if (BLO_write_file(bmain, - filepath, - fileflags, - &(const struct BlendFileWriteParams){ - /* Make all paths absolute when saving the startup file. - * On load the `G.main->filepath` will be empty so the paths - * won't have a base for resolving the relative paths. */ - .remap_mode = BLO_WRITE_PATH_REMAP_ABSOLUTE, - /* Don't apply any path changes to the current blend file. */ - .use_save_as_copy = true, - }, - op->reports) == 0) { + BlendFileWriteParams blend_write_params{}; + /* Make all paths absolute when saving the startup file. + * On load the `G.main->filepath` will be empty so the paths + * won't have a base for resolving the relative paths. */ + blend_write_params.remap_mode = BLO_WRITE_PATH_REMAP_ABSOLUTE; + /* Don't apply any path changes to the current blend file. */ + blend_write_params.use_save_as_copy = true; + if (BLO_write_file(bmain, filepath, fileflags, &blend_write_params, op->reports) == 0) { printf("fail\n"); return OPERATOR_CANCELLED; } @@ -2251,7 +2254,7 @@ static void rna_struct_update_when_changed(bContext *C, BLI_assert(ptr_a->type == ptr_b->type); RNA_property_collection_begin(ptr_a, iterprop, &iter); for (; iter.valid; RNA_property_collection_next(&iter)) { - PropertyRNA *prop = iter.ptr.data; + PropertyRNA *prop = static_cast(iter.ptr.data); if (STREQ(RNA_property_identifier(prop), "rna_type")) { continue; } @@ -2281,8 +2284,8 @@ static void wm_userpref_update_when_changed(bContext *C, UserDef *userdef_curr) { PointerRNA ptr_a, ptr_b; - RNA_pointer_create(NULL, &RNA_Preferences, userdef_prev, &ptr_a); - RNA_pointer_create(NULL, &RNA_Preferences, userdef_curr, &ptr_b); + RNA_pointer_create(nullptr, &RNA_Preferences, userdef_prev, &ptr_a); + RNA_pointer_create(nullptr, &RNA_Preferences, userdef_curr, &ptr_b); const bool is_dirty = userdef_curr->runtime.is_dirty; rna_struct_update_when_changed(C, bmain, &ptr_a, &ptr_b); @@ -2303,18 +2306,16 @@ static int wm_userpref_read_exec(bContext *C, wmOperator *op) UserDef U_backup = U; - wm_homefile_read( - C, - &(const struct wmHomeFileRead_Params){ - .use_data = use_data, - .use_userdef = use_userdef, - .use_factory_settings = use_factory_settings, - .use_factory_settings_app_template_only = use_factory_settings_app_template_only, - .use_empty_data = false, - .filepath_startup_override = NULL, - .app_template_override = WM_init_state_app_template_get(), - }, - op->reports); + wmHomeFileRead_Params read_homefile_params{}; + read_homefile_params.use_data = use_data; + read_homefile_params.use_userdef = use_userdef; + read_homefile_params.use_factory_settings = use_factory_settings; + read_homefile_params.use_factory_settings_app_template_only = + use_factory_settings_app_template_only; + read_homefile_params.use_empty_data = false; + read_homefile_params.filepath_startup_override = nullptr; + read_homefile_params.app_template_override = WM_init_state_app_template_get(); + wm_homefile_read(C, &read_homefile_params, op->reports); wm_userpref_read_exceptions(&U, &U_backup); SET_FLAG_FROM_TEST(G.f, use_factory_settings, G_FLAG_USERPREF_NO_SAVE_ON_EXIT); @@ -2328,9 +2329,9 @@ static int wm_userpref_read_exec(bContext *C, wmOperator *op) } /* Needed to recalculate UI scaling values (eg, #UserDef.inv_dpi_fac). */ - wm_window_clear_drawable(bmain->wm.first); + wm_window_clear_drawable(static_cast(bmain->wm.first)); - WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_WINDOW, nullptr); return OPERATOR_FINISHED; } @@ -2365,7 +2366,7 @@ void WM_OT_read_factory_userpref(wmOperatorType *ot) /** \name Read File History Operator * \{ */ -static int wm_history_file_read_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)) +static int wm_history_file_read_exec(bContext * /*C*/, wmOperator * /*op*/) { ED_file_read_bookmarks(); wm_history_file_read(); @@ -2405,7 +2406,7 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op) bool use_userdef = false; char filepath_buf[FILE_MAX]; - const char *filepath = NULL; + const char *filepath = nullptr; UserDef U_backup = U; if (!use_factory_settings) { @@ -2452,25 +2453,23 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op) } /* Turn override off, since we're explicitly loading a different app-template. */ - WM_init_state_app_template_set(NULL); + WM_init_state_app_template_set(nullptr); } else { - /* Normally NULL, only set when overriding from the command-line. */ + /* Normally nullptr, only set when overriding from the command-line. */ app_template = WM_init_state_app_template_get(); } - wm_homefile_read( - C, - &(const struct wmHomeFileRead_Params){ - .use_data = true, - .use_userdef = use_userdef, - .use_factory_settings = use_factory_settings, - .use_factory_settings_app_template_only = use_factory_settings_app_template_only, - .use_empty_data = use_empty_data, - .filepath_startup_override = filepath, - .app_template_override = app_template, - }, - op->reports); + wmHomeFileRead_Params read_homefile_params{}; + read_homefile_params.use_data = true; + read_homefile_params.use_userdef = use_userdef; + read_homefile_params.use_factory_settings = use_factory_settings; + read_homefile_params.use_factory_settings_app_template_only = + use_factory_settings_app_template_only; + read_homefile_params.use_empty_data = use_empty_data; + read_homefile_params.filepath_startup_override = filepath; + read_homefile_params.app_template_override = app_template; + wm_homefile_read(C, &read_homefile_params, op->reports); if (use_splash) { WM_init_splash(C); @@ -2495,10 +2494,10 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op) static void wm_homefile_read_after_dialog_callback(bContext *C, void *user_data) { WM_operator_name_call_with_properties( - C, "WM_OT_read_homefile", WM_OP_EXEC_DEFAULT, (IDProperty *)user_data, NULL); + C, "WM_OT_read_homefile", WM_OP_EXEC_DEFAULT, (IDProperty *)user_data, nullptr); } -static int wm_homefile_read_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int wm_homefile_read_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { if (wm_operator_close_file_dialog_if_needed(C, op, wm_homefile_read_after_dialog_callback)) { return OPERATOR_INTERFACE; @@ -2511,10 +2510,10 @@ static void read_homefile_props(wmOperatorType *ot) PropertyRNA *prop; prop = RNA_def_string(ot->srna, "app_template", "Template", sizeof(U.app_template), "", ""); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE)); prop = RNA_def_boolean(ot->srna, "use_empty", false, "Empty", ""); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE)); } void WM_OT_read_homefile(wmOperatorType *ot) @@ -2527,24 +2526,28 @@ void WM_OT_read_homefile(wmOperatorType *ot) ot->invoke = wm_homefile_read_invoke; ot->exec = wm_homefile_read_exec; - prop = RNA_def_string_file_path( - ot->srna, "filepath", NULL, FILE_MAX, "File Path", "Path to an alternative start-up file"); + prop = RNA_def_string_file_path(ot->srna, + "filepath", + nullptr, + FILE_MAX, + "File Path", + "Path to an alternative start-up file"); RNA_def_property_flag(prop, PROP_HIDDEN); /* So scripts can use an alternative start-up file without the UI */ prop = RNA_def_boolean( ot->srna, "load_ui", true, "Load UI", "Load user interface setup from the .blend file"); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE)); /* So the splash can be kept open after loading a file (for templates). */ prop = RNA_def_boolean(ot->srna, "use_splash", false, "Splash", ""); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE)); /* So scripts can load factory-startup without resetting preferences * (which has other implications such as reloading all add-ons). * Match naming for `--factory-startup` command line argument. */ prop = RNA_def_boolean(ot->srna, "use_factory_startup", false, "Factory Startup", ""); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE)); read_factory_reset_props(ot); read_homefile_props(ot); @@ -2584,7 +2587,7 @@ static bool wm_file_read_opwrap(bContext *C, const char *filepath, ReportList *r /* XXX wm in context is not set correctly after WM_file_read -> crash */ /* do it before for now, but is this correct with multiple windows? */ - WM_event_add_notifier(C, NC_WINDOW, NULL); + WM_event_add_notifier(C, NC_WINDOW, nullptr); /* Set by the "use_scripts" property on file load. */ if ((G.f & G_FLAG_SCRIPT_AUTOEXEC) == 0) { @@ -2651,7 +2654,7 @@ static int wm_open_mainfile_dispatch(bContext *C, wmOperator *op); static void wm_open_mainfile_after_dialog_callback(bContext *C, void *user_data) { WM_operator_name_call_with_properties( - C, "WM_OT_open_mainfile", WM_OP_INVOKE_DEFAULT, (IDProperty *)user_data, NULL); + C, "WM_OT_open_mainfile", WM_OP_INVOKE_DEFAULT, (IDProperty *)user_data, nullptr); } static int wm_open_mainfile__discard_changes(bContext *C, wmOperator *op) @@ -2676,7 +2679,7 @@ static int wm_open_mainfile__select_file_path(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); const char *blendfile_path = BKE_main_blendfile_path(bmain); - if (CTX_wm_window(C) == NULL) { + if (CTX_wm_window(C) == nullptr) { /* in rare cases this could happen, when trying to invoke in background * mode on load for example. Don't use poll for this because exec() * can still run without a window */ @@ -2686,14 +2689,14 @@ static int wm_open_mainfile__select_file_path(bContext *C, wmOperator *op) /* if possible, get the name of the most recently used .blend file */ if (G.recent_files.first) { - struct RecentFile *recent = G.recent_files.first; + RecentFile *recent = static_cast(G.recent_files.first); blendfile_path = recent->filepath; } RNA_string_set(op->ptr, "filepath", blendfile_path); wm_open_init_load_ui(op, true); wm_open_init_use_scripts(op, true); - op->customdata = NULL; + op->customdata = nullptr; WM_event_add_fileselect(C, op); @@ -2732,7 +2735,7 @@ static OperatorDispatchTarget wm_open_mainfile_dispatch_targets[] = { {OPEN_MAINFILE_STATE_DISCARD_CHANGES, wm_open_mainfile__discard_changes}, {OPEN_MAINFILE_STATE_SELECT_FILE_PATH, wm_open_mainfile__select_file_path}, {OPEN_MAINFILE_STATE_OPEN, wm_open_mainfile__open}, - {0, NULL}, + {0, nullptr}, }; static int wm_open_mainfile_dispatch(bContext *C, wmOperator *op) @@ -2740,7 +2743,7 @@ static int wm_open_mainfile_dispatch(bContext *C, wmOperator *op) return operator_state_dispatch(C, op, wm_open_mainfile_dispatch_targets); } -static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { return wm_open_mainfile_dispatch(C, op); } @@ -2750,12 +2753,12 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op) return wm_open_mainfile__open(C, op); } -static char *wm_open_mainfile_description(struct bContext *UNUSED(C), - struct wmOperatorType *UNUSED(op), +static char *wm_open_mainfile_description(struct bContext * /*C*/, + struct wmOperatorType * /*op*/, struct PointerRNA *params) { if (!RNA_struct_property_is_set(params, "filepath")) { - return NULL; + return nullptr; } /* Filepath. */ @@ -2772,14 +2775,14 @@ static char *wm_open_mainfile_description(struct bContext *UNUSED(C), char time_st[FILELIST_DIRENTRY_TIME_LEN]; bool is_today, is_yesterday; BLI_filelist_entry_datetime_to_string( - NULL, (int64_t)stats.st_mtime, false, time_st, date_st, &is_today, &is_yesterday); + nullptr, (int64_t)stats.st_mtime, false, time_st, date_st, &is_today, &is_yesterday); if (is_today || is_yesterday) { BLI_strncpy(date_st, is_today ? TIP_("Today") : TIP_("Yesterday"), sizeof(date_st)); } /* Size. */ char size_str[FILELIST_DIRENTRY_SIZE_LEN]; - BLI_filelist_entry_size_to_string(NULL, (uint64_t)stats.st_size, false, size_str); + BLI_filelist_entry_size_to_string(nullptr, (uint64_t)stats.st_size, false, size_str); return BLI_sprintfN( "%s\n\n%s: %s %s\n%s: %s", path, TIP_("Modified"), date_st, time_st, TIP_("Size"), size_str); @@ -2792,7 +2795,7 @@ struct FileRuntime { BLI_STATIC_ASSERT(sizeof(struct FileRuntime) <= sizeof(void *), "Struct must not exceed pointer size"); -static bool wm_open_mainfile_check(bContext *UNUSED(C), wmOperator *op) +static bool wm_open_mainfile_check(bContext * /*C*/, wmOperator *op) { struct FileRuntime *file_info = (struct FileRuntime *)&op->customdata; PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_scripts"); @@ -2822,13 +2825,13 @@ static bool wm_open_mainfile_check(bContext *UNUSED(C), wmOperator *op) return is_untrusted; } -static void wm_open_mainfile_ui(bContext *UNUSED(C), wmOperator *op) +static void wm_open_mainfile_ui(bContext * /*C*/, wmOperator *op) { struct FileRuntime *file_info = (struct FileRuntime *)&op->customdata; uiLayout *layout = op->layout; const char *autoexec_text; - uiItemR(layout, op->ptr, "load_ui", 0, NULL, ICON_NONE); + uiItemR(layout, op->ptr, "load_ui", 0, nullptr, ICON_NONE); uiLayout *col = uiLayoutColumn(layout, false); if (file_info->is_untrusted) { @@ -2911,7 +2914,7 @@ static int wm_revert_mainfile_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } -static bool wm_revert_mainfile_poll(bContext *UNUSED(C)) +static bool wm_revert_mainfile_poll(bContext * /*C*/) { const char *blendfile_path = BKE_main_blendfile_path_from_global(); return (blendfile_path[0] != '\0'); @@ -2953,7 +2956,7 @@ static int wm_recover_last_session_exec(bContext *C, wmOperator *op) if (WM_file_recover_last_session(C, op->reports)) { if (!G.background) { wmOperatorType *ot = op->type; - PointerRNA *props_ptr = MEM_callocN(sizeof(PointerRNA), __func__); + PointerRNA *props_ptr = MEM_cnew(__func__); WM_operator_properties_create_ptr(props_ptr, ot); RNA_boolean_set(props_ptr, "use_scripts", true); wm_test_autorun_revert_action_set(ot, props_ptr); @@ -2966,12 +2969,10 @@ static int wm_recover_last_session_exec(bContext *C, wmOperator *op) static void wm_recover_last_session_after_dialog_callback(bContext *C, void *user_data) { WM_operator_name_call_with_properties( - C, "WM_OT_recover_last_session", WM_OP_EXEC_DEFAULT, (IDProperty *)user_data, NULL); + C, "WM_OT_recover_last_session", WM_OP_EXEC_DEFAULT, (IDProperty *)user_data, nullptr); } -static int wm_recover_last_session_invoke(bContext *C, - wmOperator *op, - const wmEvent *UNUSED(event)) +static int wm_recover_last_session_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { /* Keep the current setting instead of using the preferences since a file selector * doesn't give us the option to change the setting. */ @@ -3021,7 +3022,7 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op) if (success) { if (!G.background) { wmOperatorType *ot = op->type; - PointerRNA *props_ptr = MEM_callocN(sizeof(PointerRNA), __func__); + PointerRNA *props_ptr = MEM_cnew(__func__); WM_operator_properties_create_ptr(props_ptr, ot); RNA_boolean_set(props_ptr, "use_scripts", true); wm_test_autorun_revert_action_set(ot, props_ptr); @@ -3031,7 +3032,7 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } -static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { char filepath[FILE_MAX]; @@ -3107,7 +3108,7 @@ static void save_set_filepath(bContext *C, wmOperator *op) const char *blendfile_path = BKE_main_blendfile_path(bmain); /* if not saved before, get the name of the most recently used .blend file */ if ((blendfile_path[0] == '\0') && G.recent_files.first) { - struct RecentFile *recent = G.recent_files.first; + RecentFile *recent = static_cast(G.recent_files.first); STRNCPY(filepath, recent->filepath); } else { @@ -3119,7 +3120,7 @@ static void save_set_filepath(bContext *C, wmOperator *op) } } -static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { save_set_compress(op); @@ -3193,7 +3194,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - WM_event_add_notifier(C, NC_WM | ND_FILESAVE, NULL); + WM_event_add_notifier(C, NC_WM | ND_FILESAVE, nullptr); if (!is_save_as && RNA_boolean_get(op->ptr, "exit")) { wm_exit_schedule_delayed(C); @@ -3203,7 +3204,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) } /* function used for WM_OT_save_mainfile too */ -static bool blend_save_check(bContext *UNUSED(C), wmOperator *op) +static bool blend_save_check(bContext * /*C*/, wmOperator *op) { char filepath[FILE_MAX]; RNA_string_get(op->ptr, "filepath", filepath); @@ -3222,18 +3223,18 @@ static const char *wm_save_as_mainfile_get_name(wmOperatorType *ot, PointerRNA * if (RNA_boolean_get(ptr, "copy")) { return CTX_IFACE_(ot->translation_context, "Save Copy"); } - return NULL; + return nullptr; } -static char *wm_save_as_mainfile_get_description(bContext *UNUSED(C), - wmOperatorType *UNUSED(ot), +static char *wm_save_as_mainfile_get_description(bContext * /*C*/, + wmOperatorType * /*ot*/, PointerRNA *ptr) { if (RNA_boolean_get(ptr, "copy")) { return BLI_strdup(TIP_( "Save the current file in the desired location but do not make the saved file active")); } - return NULL; + return nullptr; } void WM_OT_save_as_mainfile(wmOperatorType *ot) @@ -3273,12 +3274,12 @@ void WM_OT_save_as_mainfile(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } -static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/) { int ret; /* cancel if no active window */ - if (CTX_wm_window(C) == NULL) { + if (CTX_wm_window(C) == nullptr) { return OPERATOR_CANCELLED; } @@ -3337,7 +3338,7 @@ void WM_OT_save_mainfile(wmOperatorType *ot) "Remap relative paths when saving to a different directory"); prop = RNA_def_boolean(ot->srna, "exit", false, "Exit", "Exit Blender after saving"); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); + RNA_def_property_flag(prop, PropertyFlag(PROP_HIDDEN | PROP_SKIP_SAVE)); } /** \} */ @@ -3346,26 +3347,26 @@ void WM_OT_save_mainfile(wmOperatorType *ot) /** \name Auto Script Execution Warning Dialog * \{ */ -static void wm_block_autorun_warning_ignore(bContext *C, void *arg_block, void *UNUSED(arg)) +static void wm_block_autorun_warning_ignore(bContext *C, void *arg_block, void * /*arg*/) { wmWindow *win = CTX_wm_window(C); - UI_popup_block_close(C, win, arg_block); + UI_popup_block_close(C, win, static_cast(arg_block)); /* Free the data as it's no longer needed. */ - wm_test_autorun_revert_action_set(NULL, NULL); + wm_test_autorun_revert_action_set(nullptr, nullptr); } static void wm_block_autorun_warning_reload_with_scripts(bContext *C, void *arg_block, - void *UNUSED(arg)) + void * /*arg*/) { wmWindow *win = CTX_wm_window(C); - UI_popup_block_close(C, win, arg_block); + UI_popup_block_close(C, win, static_cast(arg_block)); /* Save user preferences for permanent execution. */ if ((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0) { - WM_operator_name_call(C, "WM_OT_save_userpref", WM_OP_EXEC_DEFAULT, NULL, NULL); + WM_operator_name_call(C, "WM_OT_save_userpref", WM_OP_EXEC_DEFAULT, nullptr, nullptr); } /* Load file again with scripts enabled. @@ -3373,18 +3374,16 @@ static void wm_block_autorun_warning_reload_with_scripts(bContext *C, wm_test_autorun_revert_action_exec(C); } -static void wm_block_autorun_warning_enable_scripts(bContext *C, - void *arg_block, - void *UNUSED(arg)) +static void wm_block_autorun_warning_enable_scripts(bContext *C, void *arg_block, void * /*arg*/) { wmWindow *win = CTX_wm_window(C); Main *bmain = CTX_data_main(C); - UI_popup_block_close(C, win, arg_block); + UI_popup_block_close(C, win, static_cast(arg_block)); /* Save user preferences for permanent execution. */ if ((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0) { - WM_operator_name_call(C, "WM_OT_save_userpref", WM_OP_EXEC_DEFAULT, NULL, NULL); + WM_operator_name_call(C, "WM_OT_save_userpref", WM_OP_EXEC_DEFAULT, nullptr, nullptr); } /* Force a full refresh, but without reloading the file. */ @@ -3396,7 +3395,7 @@ static void wm_block_autorun_warning_enable_scripts(bContext *C, /* Build the autorun warning dialog UI */ static uiBlock *block_create_autorun_warning(struct bContext *C, struct ARegion *region, - void *UNUSED(arg1)) + void * /*arg1*/) { const char *blendfile_path = BKE_main_blendfile_path_from_global(); wmWindowManager *wm = CTX_wm_manager(C); @@ -3423,7 +3422,7 @@ static uiBlock *block_create_autorun_warning(struct bContext *C, uiItemS(layout); PointerRNA pref_ptr; - RNA_pointer_create(NULL, &RNA_PreferencesFilePaths, &U, &pref_ptr); + RNA_pointer_create(nullptr, &RNA_PreferencesFilePaths, &U, &pref_ptr); uiItemR(layout, &pref_ptr, "use_scripts_auto_execute", @@ -3456,13 +3455,13 @@ static uiBlock *block_create_autorun_warning(struct bContext *C, 0, 50, UI_UNIT_Y, - NULL, + nullptr, 0, 0, 0, 0, TIP_("Reload file with execution of Python scripts enabled")); - UI_but_func_set(but, wm_block_autorun_warning_reload_with_scripts, block, NULL); + UI_but_func_set(but, wm_block_autorun_warning_reload_with_scripts, block, nullptr); } else { but = uiDefIconTextBut(block, @@ -3474,13 +3473,13 @@ static uiBlock *block_create_autorun_warning(struct bContext *C, 0, 50, UI_UNIT_Y, - NULL, + nullptr, 0, 0, 0, 0, TIP_("Enable scripts")); - UI_but_func_set(but, wm_block_autorun_warning_enable_scripts, block, NULL); + UI_but_func_set(but, wm_block_autorun_warning_enable_scripts, block, nullptr); } UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT); @@ -3494,13 +3493,13 @@ static uiBlock *block_create_autorun_warning(struct bContext *C, 0, 50, UI_UNIT_Y, - NULL, + nullptr, 0, 0, 0, 0, TIP_("Continue using file without Python scripts")); - UI_but_func_set(but, wm_block_autorun_warning_ignore, block, NULL); + UI_but_func_set(but, wm_block_autorun_warning_ignore, block, nullptr); UI_but_drawflag_disable(but, UI_BUT_TEXT_LEFT); UI_but_flag_enable(but, UI_BUT_ACTIVE_DEFAULT); @@ -3512,26 +3511,23 @@ static uiBlock *block_create_autorun_warning(struct bContext *C, /** * Store the action needed if the user needs to reload the file with Python scripts enabled. * - * When left to NULL, this is simply revert. + * When left to nullptr, this is simply revert. * When loading files through the recover auto-save or session, * we need to revert using other operators. */ static struct { wmOperatorType *ot; PointerRNA *ptr; -} wm_test_autorun_revert_action_data = { - .ot = NULL, - .ptr = NULL, -}; +} wm_test_autorun_revert_action_data = {nullptr, nullptr}; void wm_test_autorun_revert_action_set(wmOperatorType *ot, PointerRNA *ptr) { BLI_assert(!G.background); - wm_test_autorun_revert_action_data.ot = NULL; - if (wm_test_autorun_revert_action_data.ptr != NULL) { + wm_test_autorun_revert_action_data.ot = nullptr; + if (wm_test_autorun_revert_action_data.ptr != nullptr) { WM_operator_properties_free(wm_test_autorun_revert_action_data.ptr); MEM_freeN(wm_test_autorun_revert_action_data.ptr); - wm_test_autorun_revert_action_data.ptr = NULL; + wm_test_autorun_revert_action_data.ptr = nullptr; } wm_test_autorun_revert_action_data.ot = ot; wm_test_autorun_revert_action_data.ptr = ptr; @@ -3543,9 +3539,9 @@ void wm_test_autorun_revert_action_exec(bContext *C) PointerRNA *ptr = wm_test_autorun_revert_action_data.ptr; /* Use regular revert. */ - if (ot == NULL) { + if (ot == nullptr) { ot = WM_operatortype_find("WM_OT_revert_mainfile", false); - ptr = MEM_callocN(sizeof(PointerRNA), __func__); + ptr = MEM_cnew(__func__); WM_operator_properties_create_ptr(ptr, ot); RNA_boolean_set(ptr, "use_scripts", true); @@ -3553,8 +3549,8 @@ void wm_test_autorun_revert_action_exec(bContext *C) wm_test_autorun_revert_action_set(ot, ptr); } - WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, ptr, NULL); - wm_test_autorun_revert_action_set(NULL, NULL); + WM_operator_name_call_ptr(C, ot, WM_OP_EXEC_DEFAULT, ptr, nullptr); + wm_test_autorun_revert_action_set(nullptr, nullptr); } void wm_test_autorun_warning(bContext *C) @@ -3572,12 +3568,12 @@ void wm_test_autorun_warning(bContext *C) G.f |= G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET; wmWindowManager *wm = CTX_wm_manager(C); - wmWindow *win = (wm->winactive) ? wm->winactive : wm->windows.first; + wmWindow *win = (wm->winactive) ? wm->winactive : static_cast(wm->windows.first); if (win) { wmWindow *prevwin = CTX_wm_window(C); CTX_wm_window_set(C, win); - UI_popup_block_invoke(C, block_create_autorun_warning, NULL, NULL); + UI_popup_block_invoke(C, block_create_autorun_warning, nullptr, nullptr); CTX_wm_window_set(C, prevwin); } } @@ -3590,10 +3586,10 @@ void wm_test_autorun_warning(bContext *C) static char save_images_when_file_is_closed = true; -static void wm_block_file_close_cancel(bContext *C, void *arg_block, void *UNUSED(arg_data)) +static void wm_block_file_close_cancel(bContext *C, void *arg_block, void * /*arg_data*/) { wmWindow *win = CTX_wm_window(C); - UI_popup_block_close(C, win, arg_block); + UI_popup_block_close(C, win, static_cast(arg_block)); } static void wm_block_file_close_discard(bContext *C, void *arg_block, void *arg_data) @@ -3604,7 +3600,7 @@ static void wm_block_file_close_discard(bContext *C, void *arg_block, void *arg_ * the popup might be closed by the callback, which will lead * to a crash. */ wmWindow *win = CTX_wm_window(C); - UI_popup_block_close(C, win, arg_block); + UI_popup_block_close(C, win, static_cast(arg_block)); callback->exec(C, callback->user_data); WM_generic_callback_free(callback); @@ -3617,9 +3613,9 @@ static void wm_block_file_close_save(bContext *C, void *arg_block, void *arg_dat bool execute_callback = true; wmWindow *win = CTX_wm_window(C); - UI_popup_block_close(C, win, arg_block); + UI_popup_block_close(C, win, static_cast(arg_block)); - int modified_images_count = ED_image_save_all_modified_info(CTX_data_main(C), NULL); + int modified_images_count = ED_image_save_all_modified_info(CTX_data_main(C), nullptr); if (modified_images_count > 0 && save_images_when_file_is_closed) { if (ED_image_should_save_modified(bmain)) { ReportList *reports = CTX_wm_reports(C); @@ -3634,13 +3630,13 @@ static void wm_block_file_close_save(bContext *C, void *arg_block, void *arg_dat bool file_has_been_saved_before = BKE_main_blendfile_path(bmain)[0] != '\0'; if (file_has_been_saved_before) { - if (WM_operator_name_call(C, "WM_OT_save_mainfile", WM_OP_EXEC_DEFAULT, NULL, NULL) & + if (WM_operator_name_call(C, "WM_OT_save_mainfile", WM_OP_EXEC_DEFAULT, nullptr, nullptr) & OPERATOR_CANCELLED) { execute_callback = false; } } else { - WM_operator_name_call(C, "WM_OT_save_mainfile", WM_OP_INVOKE_DEFAULT, NULL, NULL); + WM_operator_name_call(C, "WM_OT_save_mainfile", WM_OP_INVOKE_DEFAULT, nullptr, nullptr); execute_callback = false; } @@ -3677,11 +3673,9 @@ static void wm_block_file_close_save_button(uiBlock *block, wmGenericCallback *p static const char *close_file_dialog_name = "file_close_popup"; -static void save_catalogs_when_file_is_closed_set_fn(bContext *UNUSED(C), - void *arg1, - void *UNUSED(arg2)) +static void save_catalogs_when_file_is_closed_set_fn(bContext * /*C*/, void *arg1, void * /*arg2*/) { - char *save_catalogs_when_file_is_closed = arg1; + char *save_catalogs_when_file_is_closed = static_cast(arg1); ED_asset_catalogs_set_save_catalogs_when_file_is_saved(*save_catalogs_when_file_is_closed != 0); } @@ -3794,8 +3788,10 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, 0, 0, ""); - UI_but_func_set( - but, save_catalogs_when_file_is_closed_set_fn, &save_catalogs_when_file_is_closed, NULL); + UI_but_func_set(but, + save_catalogs_when_file_is_closed_set_fn, + &save_catalogs_when_file_is_closed, + nullptr); has_extra_checkboxes = true; } @@ -3879,7 +3875,7 @@ bool wm_operator_close_file_dialog_if_needed(bContext *C, { if (U.uiflag & USER_SAVE_PROMPT && wm_file_or_session_data_has_unsaved_changes(CTX_data_main(C), CTX_wm_manager(C))) { - wmGenericCallback *callback = MEM_callocN(sizeof(*callback), __func__); + wmGenericCallback *callback = MEM_cnew(__func__); callback->exec = post_action_fn; callback->user_data = IDP_CopyProperty(op->properties); callback->free_user_data = wm_free_operator_properties_callback; diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.cc similarity index 91% rename from source/blender/windowmanager/intern/wm_init_exit.c rename to source/blender/windowmanager/intern/wm_init_exit.cc index 8e1f3c14208..7ad481669d9 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.cc @@ -190,7 +190,7 @@ static void sound_jack_sync_callback(Main *bmain, int mode, double time) return; } - wmWindowManager *wm = bmain->wm.first; + wmWindowManager *wm = static_cast(bmain->wm.first); LISTBASE_FOREACH (wmWindow *, window, &wm->windows) { Scene *scene = WM_window_get_active_scene(window); @@ -199,7 +199,7 @@ static void sound_jack_sync_callback(Main *bmain, int mode, double time) } ViewLayer *view_layer = WM_window_get_active_view_layer(window); Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer); - if (depsgraph == NULL) { + if (depsgraph == nullptr) { continue; } BKE_sound_lock(); @@ -250,7 +250,7 @@ void WM_init(bContext *C, int argc, const char **argv) BLT_lang_init(); /* Must call first before doing any `.blend` file reading, * since versioning code may create new IDs. See T57066. */ - BLT_lang_set(NULL); + BLT_lang_set(nullptr); /* Init icons before reading .blend files for preview icons, which can * get triggered by the depsgraph. This is also done in background mode @@ -287,25 +287,23 @@ void WM_init(bContext *C, int argc, const char **argv) * Creating a dummy window-manager early, or moving the key-maps into the preferences * would resolve this and may be worth looking into long-term, see: D12184 for details. */ - struct wmFileReadPost_Params *params_file_read_post = NULL; - wm_homefile_read_ex(C, - &(const struct wmHomeFileRead_Params){ - .use_data = true, - .use_userdef = true, - .use_factory_settings = G.factory_startup, - .use_empty_data = false, - .filepath_startup_override = NULL, - .app_template_override = WM_init_state_app_template_get(), - }, - NULL, - ¶ms_file_read_post); + struct wmFileReadPost_Params *params_file_read_post = nullptr; + wmHomeFileRead_Params read_homefile_params{}; + read_homefile_params.use_data = true; + read_homefile_params.use_userdef = true; + read_homefile_params.use_factory_settings = G.factory_startup; + read_homefile_params.use_empty_data = false; + read_homefile_params.filepath_startup_override = nullptr; + read_homefile_params.app_template_override = WM_init_state_app_template_get(); + + wm_homefile_read_ex(C, &read_homefile_params, nullptr, ¶ms_file_read_post); /* NOTE: leave `G_MAIN->filepath` set to an empty string since this * matches behavior after loading a new file. */ BLI_assert(G_MAIN->filepath[0] == '\0'); /* Call again to set from preferences. */ - BLT_lang_set(NULL); + BLT_lang_set(nullptr); /* For file-system. Called here so can include user preference paths if needed. */ ED_file_init(); @@ -367,8 +365,8 @@ void WM_init_splash(bContext *C) wmWindow *prevwin = CTX_wm_window(C); if (wm->windows.first) { - CTX_wm_window_set(C, wm->windows.first); - WM_operator_name_call(C, "WM_OT_splash", WM_OP_INVOKE_DEFAULT, NULL, NULL); + CTX_wm_window_set(C, static_cast(wm->windows.first)); + WM_operator_name_call(C, "WM_OT_splash", WM_OP_INVOKE_DEFAULT, nullptr, nullptr); CTX_wm_window_set(C, prevwin); } } @@ -390,7 +388,8 @@ static void wait_for_console_key(void) { HANDLE hConsoleInput = GetStdHandle(STD_INPUT_HANDLE); - if (!ELEM(hConsoleInput, NULL, INVALID_HANDLE_VALUE) && FlushConsoleInputBuffer(hConsoleInput)) { + if (!ELEM(hConsoleInput, nullptr, INVALID_HANDLE_VALUE) && + FlushConsoleInputBuffer(hConsoleInput)) { for (;;) { INPUT_RECORD buffer; DWORD ignored; @@ -424,25 +423,26 @@ void wm_exit_schedule_delayed(const bContext *C) /* Use modal UI handler for now. * Could add separate WM handlers or so, but probably not worth it. */ - WM_event_add_ui_handler(C, &win->modalhandlers, wm_exit_handler, NULL, NULL, 0); + WM_event_add_ui_handler( + C, &win->modalhandlers, wm_exit_handler, nullptr, nullptr, eWM_EventHandlerFlag(0)); WM_event_add_mousemove(win); /* ensure handler actually gets called */ } -void UV_clipboard_free(void); +void UV_clipboard_free(); void WM_exit_ex(bContext *C, const bool do_python) { - wmWindowManager *wm = C ? CTX_wm_manager(C) : NULL; + wmWindowManager *wm = C ? CTX_wm_manager(C) : nullptr; /* first wrap up running stuff, we assume only the active WM is running */ /* modal handlers are on window level freed, others too? */ - /* NOTE: same code copied in `wm_files.c`. */ + /* NOTE: same code copied in `wm_files.cc`. */ if (C && wm) { if (!G.background) { struct MemFile *undo_memfile = wm->undo_stack ? ED_undosys_stack_memfile_get_active(wm->undo_stack) : - NULL; - if (undo_memfile != NULL) { + nullptr; + if (undo_memfile != nullptr) { /* save the undo state as quit.blend */ Main *bmain = CTX_data_main(C); char filepath[FILE_MAX]; @@ -453,9 +453,9 @@ void WM_exit_ex(bContext *C, const bool do_python) has_edited = ED_editors_flush_edits(bmain); + BlendFileWriteParams blend_file_write_params{}; if ((has_edited && - BLO_write_file( - bmain, filepath, fileflags, &(const struct BlendFileWriteParams){0}, NULL)) || + BLO_write_file(bmain, filepath, fileflags, &blend_file_write_params, nullptr)) || BLO_memfile_write_file(undo_memfile, filepath)) { printf("Saved session recovery to '%s'\n", filepath); } @@ -474,12 +474,12 @@ void WM_exit_ex(bContext *C, const bool do_python) if (!G.background) { if ((U.pref_flag & USER_PREF_FLAG_SAVE) && ((G.f & G_FLAG_USERPREF_NO_SAVE_ON_EXIT) == 0)) { if (U.runtime.is_dirty) { - BKE_blendfile_userdef_write_all(NULL); + BKE_blendfile_userdef_write_all(nullptr); } } /* Free the callback data used on file-open * (will be set when a recover operation has run). */ - wm_test_autorun_revert_action_set(NULL, NULL); + wm_test_autorun_revert_action_set(nullptr, nullptr); } } @@ -492,7 +492,8 @@ void WM_exit_ex(bContext *C, const bool do_python) * Don't run this code when built as a Python module as this runs when Python is in the * process of shutting down, where running a snippet like this will crash, see T82675. * Instead use the `atexit` module, installed by #BPY_python_start */ - BPY_run_string_eval(C, (const char *[]){"addon_utils", NULL}, "addon_utils.disable_all()"); + const char *imports[2] = {"addon_utils", nullptr}; + BPY_run_string_eval(C, imports, "addon_utils.disable_all()"); #endif BLI_timer_free(); @@ -584,7 +585,7 @@ void WM_exit_ex(bContext *C, const bool do_python) #ifdef WITH_PYTHON /* option not to close python so we can use 'atexit' */ - if (do_python && ((C == NULL) || CTX_py_init_get(C))) { + if (do_python && ((C == nullptr) || CTX_py_init_get(C))) { /* NOTE: (old note) * before BKE_blender_free so Python's garbage-collection happens while library still exists. * Needed at least for a rare crash that can happen in python-drivers. diff --git a/source/blender/windowmanager/intern/wm_platform_support.h b/source/blender/windowmanager/intern/wm_platform_support.h index 389ce1afa88..54b541e8148 100644 --- a/source/blender/windowmanager/intern/wm_platform_support.h +++ b/source/blender/windowmanager/intern/wm_platform_support.h @@ -8,4 +8,12 @@ #include "BLI_sys_types.h" +#ifdef __cplusplus +extern "C" { +#endif + bool WM_platform_support_perform_checks(void); + +#ifdef __cplusplus +} +#endif diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 7e245236fe0..26dbd6ce96f 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1644,7 +1644,7 @@ void wm_ghost_init(bContext *C) GHOST_UseWindowFocus(wm_init_state.window_focus); } -/* TODO move this to wm_init_exit.c. */ +/* TODO move this to wm_init_exit.cc. */ void wm_ghost_init_background(void) { if (g_system) { diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h index 0a27b9c1cfd..373b0fbee27 100644 --- a/source/blender/windowmanager/wm.h +++ b/source/blender/windowmanager/wm.h @@ -88,7 +88,7 @@ void wm_jobs_timer(wmWindowManager *wm, wmTimer *wt); */ void wm_jobs_timer_end(wmWindowManager *wm, wmTimer *wt); -/* wm_files.c */ +/* wm_files.cc */ /** * Run the auto-save timer action. diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h index 1ab8808b70b..da8ec0ef82a 100644 --- a/source/blender/windowmanager/wm_files.h +++ b/source/blender/windowmanager/wm_files.h @@ -16,7 +16,7 @@ struct wmOperatorType; extern "C" { #endif -/* wm_files.c */ +/* wm_files.cc */ void wm_history_file_read(void); From 93a840360a025df7830f48e4d7c398c3e45ff41c Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 23 Jan 2023 00:55:15 +0100 Subject: [PATCH 0864/1522] Cleanup: quiet clang warnings --- source/blender/blenkernel/intern/blendfile.cc | 2 +- source/blender/makesdna/DNA_userdef_types.h | 2 ++ source/blender/windowmanager/intern/wm_files.cc | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/blendfile.cc b/source/blender/blenkernel/intern/blendfile.cc index 9ccd3e7541a..2ac2ae43684 100644 --- a/source/blender/blenkernel/intern/blendfile.cc +++ b/source/blender/blenkernel/intern/blendfile.cc @@ -641,7 +641,7 @@ UserDef *BKE_blendfile_userdef_read_from_memory(const void *filebuf, UserDef *BKE_blendfile_userdef_from_defaults(void) { UserDef *userdef = MEM_cnew(__func__); - memcpy(userdef, &U_default, sizeof(*userdef)); + *userdef = blender::dna::shallow_copy(U_default); /* Add-ons. */ { diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 4c9568d9228..0e96e1db30c 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -659,6 +659,8 @@ typedef struct UserDef_Experimental { (((userdef)->flag & USER_DEVELOPER_UI) && ((userdef)->experimental).member) typedef struct UserDef { + DNA_DEFINE_CXX_METHODS(UserDef) + /** UserDef has separate do-version handling, and can be read from other files. */ int versionfile, subversionfile; diff --git a/source/blender/windowmanager/intern/wm_files.cc b/source/blender/windowmanager/intern/wm_files.cc index 75c9ea42e3a..8a0e206b5e7 100644 --- a/source/blender/windowmanager/intern/wm_files.cc +++ b/source/blender/windowmanager/intern/wm_files.cc @@ -2304,7 +2304,7 @@ static int wm_userpref_read_exec(bContext *C, wmOperator *op) const bool use_factory_settings_app_template_only = (use_factory_settings && RNA_boolean_get(op->ptr, "use_factory_startup_app_template_only")); - UserDef U_backup = U; + UserDef U_backup = blender::dna::shallow_copy(U); wmHomeFileRead_Params read_homefile_params{}; read_homefile_params.use_data = use_data; @@ -2407,7 +2407,7 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op) bool use_userdef = false; char filepath_buf[FILE_MAX]; const char *filepath = nullptr; - UserDef U_backup = U; + UserDef U_backup = blender::dna::shallow_copy(U); if (!use_factory_settings) { PropertyRNA *prop = RNA_struct_find_property(op->ptr, "filepath"); From c68d4bf8393895cb57c7e0cd4e9d65cf0b482cf9 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 23 Jan 2023 02:16:35 +0100 Subject: [PATCH 0865/1522] Cleanup: fix msvc compilation issue --- source/blender/blenkernel/intern/blendfile.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/blendfile.cc b/source/blender/blenkernel/intern/blendfile.cc index 2ac2ae43684..68f37df9ca9 100644 --- a/source/blender/blenkernel/intern/blendfile.cc +++ b/source/blender/blenkernel/intern/blendfile.cc @@ -640,7 +640,7 @@ UserDef *BKE_blendfile_userdef_read_from_memory(const void *filebuf, UserDef *BKE_blendfile_userdef_from_defaults(void) { - UserDef *userdef = MEM_cnew(__func__); + UserDef *userdef = static_cast(MEM_callocN(sizeof(UserDef), __func__)); *userdef = blender::dna::shallow_copy(U_default); /* Add-ons. */ From ab0be6ec2482da9c6495c4d8af992d01c44a2fbd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 23 Jan 2023 17:31:44 +1100 Subject: [PATCH 0866/1522] Cleanup: quiet clang warnings --- source/blender/blenkernel/intern/volume.cc | 2 +- .../editors/uvedit/uvedit_unwrap_ops.cc | 18 +++++++++--------- .../blender_interface/BlenderFileLoader.cpp | 2 +- .../intern/MOD_solidify_nonmanifold.cc | 17 ++++++++++------- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/source/blender/blenkernel/intern/volume.cc b/source/blender/blenkernel/intern/volume.cc index 0d8d66d69a9..7bf0c6f18a2 100644 --- a/source/blender/blenkernel/intern/volume.cc +++ b/source/blender/blenkernel/intern/volume.cc @@ -1489,7 +1489,7 @@ void BKE_volume_grid_transform_matrix_set(const Volume *volume, grid->setTransform(std::make_shared( std::make_shared(mat_openvdb))); #else - UNUSED_VARS(volume_grid, mat); + UNUSED_VARS(volume, volume_grid, mat); #endif } diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc index 208268c71c1..de98e3c48f7 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.cc +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.cc @@ -1842,16 +1842,16 @@ void ED_uvedit_live_unwrap(const Scene *scene, Object **objects, int objects_len uvedit_unwrap_multi(scene, objects, objects_len, &options, nullptr); UVPackIsland_Params pack_island_params{}; - pack_island_params.rotate = true, - pack_island_params.only_selected_uvs = options.only_selected_uvs, - pack_island_params.only_selected_faces = options.only_selected_faces, + pack_island_params.rotate = true; + pack_island_params.only_selected_uvs = options.only_selected_uvs; + pack_island_params.only_selected_faces = options.only_selected_faces; pack_island_params.use_seams = !options.topology_from_uvs || - options.topology_from_uvs_use_seams, - pack_island_params.correct_aspect = options.correct_aspect, - pack_island_params.ignore_pinned = true, - pack_island_params.pin_unselected = options.pin_unselected, - pack_island_params.margin_method = ED_UVPACK_MARGIN_SCALED, - pack_island_params.margin = scene->toolsettings->uvcalc_margin, + options.topology_from_uvs_use_seams; + pack_island_params.correct_aspect = options.correct_aspect; + pack_island_params.ignore_pinned = true; + pack_island_params.pin_unselected = options.pin_unselected; + pack_island_params.margin_method = ED_UVPACK_MARGIN_SCALED; + pack_island_params.margin = scene->toolsettings->uvcalc_margin; ED_uvedit_pack_islands_multi( scene, objects, objects_len, nullptr, nullptr, &pack_island_params); diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp index 1529c943963..53e25fb4a62 100644 --- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp +++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp @@ -202,7 +202,7 @@ void BlenderFileLoader::clipTriangle(int numTris, float n1[3], float n2[3], float n3[3], - bool edgeMarks[], + bool edgeMarks[5], bool em1, bool em2, bool em3, diff --git a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc index 53ebf814a26..18d62b8b327 100644 --- a/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc +++ b/source/blender/modifiers/intern/MOD_solidify_nonmanifold.cc @@ -1267,15 +1267,18 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md, memcpy(edges, g.edges, uint(first_split) * sizeof(*edges)); EdgeGroup edge_group_a{}; - edge_group_a.valid = true, edge_group_a.edges = edges, - edge_group_a.edges_len = uint(first_split), - edge_group_a.open_face_edge = MOD_SOLIDIFY_EMPTY_TAG, - edge_group_a.is_orig_closed = g.is_orig_closed, - edge_group_a.is_even_split = first_even_split, edge_group_a.split = 1, - edge_group_a.is_singularity = false, edge_group_a.topo_group = g.topo_group, + edge_group_a.valid = true; + edge_group_a.edges = edges; + edge_group_a.edges_len = uint(first_split); + edge_group_a.open_face_edge = MOD_SOLIDIFY_EMPTY_TAG; + edge_group_a.is_orig_closed = g.is_orig_closed; + edge_group_a.is_even_split = first_even_split; + edge_group_a.split = 1; + edge_group_a.is_singularity = false; + edge_group_a.topo_group = g.topo_group; zero_v3(edge_group_a.co); zero_v3(edge_group_a.no); - edge_group_a.new_vert = MOD_SOLIDIFY_EMPTY_TAG, + edge_group_a.new_vert = MOD_SOLIDIFY_EMPTY_TAG; edge_groups[j + prior_index] = edge_group_a; add_index++; From eca4b991d8b57f721827d76d78073fb5017df61f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 23 Jan 2023 17:31:46 +1100 Subject: [PATCH 0867/1522] Cleanup: use function style casts --- source/blender/blenkernel/intern/deform.cc | 6 +- .../blender/blenkernel/intern/dynamicpaint.cc | 84 +++++++------- source/blender/blenkernel/intern/fluid.cc | 106 +++++++++--------- .../blenkernel/intern/subdiv_foreach.cc | 14 +-- .../blender/blenkernel/intern/subsurf_ccg.cc | 16 +-- .../blender/editors/armature/meshlaplacian.cc | 10 +- .../blender/editors/object/object_bake_api.cc | 8 +- .../editors/sculpt_paint/sculpt_geodesic.cc | 2 +- .../editors/sculpt_paint/sculpt_undo.cc | 24 ++-- source/blender/editors/undo/ed_undo.cc | 2 +- .../blender/windowmanager/intern/wm_files.cc | 10 +- 11 files changed, 141 insertions(+), 141 deletions(-) diff --git a/source/blender/blenkernel/intern/deform.cc b/source/blender/blenkernel/intern/deform.cc index a01c6d724a4..dda4d098126 100644 --- a/source/blender/blenkernel/intern/deform.cc +++ b/source/blender/blenkernel/intern/deform.cc @@ -1053,7 +1053,7 @@ void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert, if (dvert && defgroup != -1) { int i = edges_num; float *tmp_weights = static_cast( - MEM_mallocN(sizeof(*tmp_weights) * (size_t)verts_num, __func__)); + MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__)); BKE_defvert_extract_vgroup_to_vertweights( dvert, defgroup, verts_num, invert_vgroup, tmp_weights); @@ -1082,7 +1082,7 @@ void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert, if (dvert && defgroup != -1) { int i = loops_num; float *tmp_weights = static_cast( - MEM_mallocN(sizeof(*tmp_weights) * (size_t)verts_num, __func__)); + MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__)); BKE_defvert_extract_vgroup_to_vertweights( dvert, defgroup, verts_num, invert_vgroup, tmp_weights); @@ -1113,7 +1113,7 @@ void BKE_defvert_extract_vgroup_to_polyweights(const MDeformVert *dvert, if (dvert && defgroup != -1) { int i = polys_num; float *tmp_weights = static_cast( - MEM_mallocN(sizeof(*tmp_weights) * (size_t)verts_num, __func__)); + MEM_mallocN(sizeof(*tmp_weights) * size_t(verts_num), __func__)); BKE_defvert_extract_vgroup_to_vertweights( dvert, defgroup, verts_num, invert_vgroup, tmp_weights); diff --git a/source/blender/blenkernel/intern/dynamicpaint.cc b/source/blender/blenkernel/intern/dynamicpaint.cc index 4c6cad1f5e6..9b30d34aabb 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.cc +++ b/source/blender/blenkernel/intern/dynamicpaint.cc @@ -768,12 +768,12 @@ static void surfaceGenerateGrid(DynamicPaintSurface *surface) volume = td[0] * td[1] * td[2]; /* determine final grid size by trying to fit average 10.000 points per grid cell */ - dim_factor = (float)pow((double)volume / ((double)sData->total_points / 10000.0), - 1.0 / (double)axis); + dim_factor = (float)pow(double(volume) / (double(sData->total_points) / 10000.0), + 1.0 / double(axis)); /* define final grid size using dim_factor, use min 3 for active axes */ for (i = 0; i < 3; i++) { - grid->dim[i] = (int)floor(td[i] / dim_factor); + grid->dim[i] = int(floor(td[i] / dim_factor)); CLAMP(grid->dim[i], (dim[i] >= min_dim) ? 3 : 1, 100); } grid_cells = grid->dim[0] * grid->dim[1] * grid->dim[2]; @@ -2101,7 +2101,7 @@ static void dynamicPaint_frameUpdate( /* loop through surfaces */ for (; surface; surface = surface->next) { - int current_frame = (int)scene->r.cfra; + int current_frame = int(scene->r.cfra); bool no_surface_data; /* free bake data if not required anymore */ @@ -2123,7 +2123,7 @@ static void dynamicPaint_frameUpdate( CLAMP(current_frame, surface->start_frame, surface->end_frame); if (no_surface_data || current_frame != surface->current_frame || - (int)scene->r.cfra == surface->start_frame) { + int(scene->r.cfra) == surface->start_frame) { PointCache *cache = surface->pointcache; PTCacheID pid; surface->current_frame = current_frame; @@ -2132,21 +2132,21 @@ static void dynamicPaint_frameUpdate( BKE_ptcache_id_from_dynamicpaint(&pid, ob, surface); pid.cache->startframe = surface->start_frame; pid.cache->endframe = surface->end_frame; - BKE_ptcache_id_time(&pid, scene, (float)scene->r.cfra, nullptr, nullptr, nullptr); + BKE_ptcache_id_time(&pid, scene, float(scene->r.cfra), nullptr, nullptr, nullptr); /* reset non-baked cache at first frame */ - if ((int)scene->r.cfra == surface->start_frame && !(cache->flag & PTCACHE_BAKED)) { + if (int(scene->r.cfra) == surface->start_frame && !(cache->flag & PTCACHE_BAKED)) { cache->flag |= PTCACHE_REDO_NEEDED; BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); cache->flag &= ~PTCACHE_REDO_NEEDED; } /* try to read from cache */ - bool can_simulate = ((int)scene->r.cfra == current_frame) && + bool can_simulate = (int(scene->r.cfra) == current_frame) && !(cache->flag & PTCACHE_BAKED); - if (BKE_ptcache_read(&pid, (float)scene->r.cfra, can_simulate)) { - BKE_ptcache_validate(cache, (int)scene->r.cfra); + if (BKE_ptcache_read(&pid, float(scene->r.cfra), can_simulate)) { + BKE_ptcache_validate(cache, int(scene->r.cfra)); } /* if read failed and we're on surface range do recalculate */ else if (can_simulate) { @@ -2238,24 +2238,24 @@ static void dynamic_paint_create_uv_surface_direct_cb(void *__restrict userdata, tPoint->pixel_index = index; /* Actual pixel center, used when collision is found */ - point[0][0] = ((float)tx + 0.5f) / w; - point[0][1] = ((float)ty + 0.5f) / h; + point[0][0] = (float(tx) + 0.5f) / w; + point[0][1] = (float(ty) + 0.5f) / h; /* * A pixel middle sample isn't enough to find very narrow polygons * So using 4 samples of each corner too */ - point[1][0] = ((float)tx) / w; - point[1][1] = ((float)ty) / h; + point[1][0] = (float(tx)) / w; + point[1][1] = (float(ty)) / h; - point[2][0] = ((float)tx + 1) / w; - point[2][1] = ((float)ty) / h; + point[2][0] = (float(tx) + 1) / w; + point[2][1] = (float(ty)) / h; - point[3][0] = ((float)tx) / w; - point[3][1] = ((float)ty + 1) / h; + point[3][0] = (float(tx)) / w; + point[3][1] = (float(ty) + 1) / h; - point[4][0] = ((float)tx + 1) / w; - point[4][1] = ((float)ty + 1) / h; + point[4][0] = (float(tx) + 1) / w; + point[4][1] = (float(ty) + 1) / h; /* Loop through samples, starting from middle point */ for (int sample = 0; sample < 5; sample++) { @@ -2337,8 +2337,8 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(void *__restrict userdat const int v_min = (ty > 0) ? -1 : 0; const int v_max = (ty < (h - 1)) ? 1 : 0; - point[0] = ((float)tx + 0.5f) / w; - point[1] = ((float)ty + 0.5f) / h; + point[0] = (float(tx) + 0.5f) / w; + point[1] = (float(ty) + 0.5f) / h; /* search through defined area for neighbor, checking grid directions first */ for (int ni = 0; ni < 8; ni++) { @@ -2505,8 +2505,8 @@ static int dynamic_paint_find_neighbor_pixel(const DynamicPaintCreateUVSurfaceDa float pixel[2]; - pixel[0] = ((float)(px + neighX[n_index]) + 0.5f) / (float)w; - pixel[1] = ((float)(py + neighY[n_index]) + 0.5f) / (float)h; + pixel[0] = (float(px + neighX[n_index]) + 0.5f) / float(w); + pixel[1] = (float(py + neighY[n_index]) + 0.5f) / float(h); /* Do a small recursive search for the best island edge. */ dynamic_paint_find_island_border(data, &bdata, cPoint->tri_index, pixel, -1, 5); @@ -2646,7 +2646,7 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa int w = bdata->w, h = bdata->h, px = bdata->px, py = bdata->py; - const int final_pixel[2] = {(int)floorf(tgt_pixel[0] * w), (int)floorf(tgt_pixel[1] * h)}; + const int final_pixel[2] = {int(floorf(tgt_pixel[0] * w)), int(floorf(tgt_pixel[1] * h))}; /* If current pixel uv is outside of texture */ if (final_pixel[0] < 0 || final_pixel[0] >= w || final_pixel[1] < 0 || final_pixel[1] >= h) { @@ -3124,7 +3124,7 @@ int dynamicPaint_createUVSurface(Scene *scene, sData->total_points = 0; } else { - sData->total_points = (int)active_points; + sData->total_points = int(active_points); sData->format_data = f_data; for (int index = 0, cursor = 0; index < (w * h); index++) { @@ -3960,7 +3960,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(void *__restrict userdata, const int index = grid->t_index[grid->s_pos[c_index] + id]; const int samples = bData->s_num[index]; int ss; - float total_sample = (float)samples; + float total_sample = float(samples); float brushStrength = 0.0f; /* brush influence factor */ float depth = 0.0f; /* brush intersection depth */ float velocity_val = 0.0f; @@ -4322,7 +4322,7 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph, } if (brush->flags & MOD_DPAINT_PROX_PROJECT && brush->collision != MOD_DPAINT_COL_VOLUME) { - mul_v3_fl(avg_brushNor, 1.0f / (float)numOfVerts); + mul_v3_fl(avg_brushNor, 1.0f / float(numOfVerts)); /* instead of null vector use positive z */ if (UNLIKELY(normalize_v3(avg_brushNor) == 0.0f)) { avg_brushNor[2] = 1.0f; @@ -4878,7 +4878,7 @@ static void dynamicPaint_prepareAdjacencyData(DynamicPaintSurface *surface, cons int numOfNeighs = adj_data->n_num[index]; for (int i = 0; i < numOfNeighs; i++) { - bData->average_dist += (double)bNeighs[adj_data->n_index[index] + i].dist; + bData->average_dist += double(bNeighs[adj_data->n_index[index] + i].dist); } } bData->average_dist /= adj_data->total_targets; @@ -4959,11 +4959,11 @@ static void surface_determineForceTargetPoints(const PaintSurfaceData *sData, /* and multiply depending on how deeply force intersects surface */ temp = fabsf(force_intersect); CLAMP(temp, 0.0f, 1.0f); - mul_v2_fl(closest_d, acosf(temp) / (float)M_PI_2); + mul_v2_fl(closest_d, acosf(temp) / float(M_PI_2)); } else { /* if only single neighbor, still linearize force intersection effect */ - closest_d[0] = 1.0f - acosf(closest_d[0]) / (float)M_PI_2; + closest_d[0] = 1.0f - acosf(closest_d[0]) / float(M_PI_2); } } @@ -4986,9 +4986,9 @@ static void dynamicPaint_doSmudge(DynamicPaintSurface *surface, CLAMP_MIN(max_velocity, vel); } - int steps = (int)ceil((double)max_velocity / bData->average_dist * (double)timescale); + int steps = int(ceil(double(max_velocity) / bData->average_dist * double(timescale))); CLAMP(steps, 0, 12); - float eff_scale = brush->smudge_strength / (float)steps * timescale; + float eff_scale = brush->smudge_strength / float(steps) * timescale; for (int step = 0; step < steps; step++) { for (int index = 0; index < sData->total_points; index++) { @@ -5188,9 +5188,9 @@ static int dynamicPaint_prepareEffectStep(Depsgraph *depsgraph, } fastest_effect = max_fff(spread_speed, shrink_speed, average_force); - avg_dist = bData->average_dist * (double)CANVAS_REL_SIZE / (double)getSurfaceDimension(sData); + avg_dist = bData->average_dist * double(CANVAS_REL_SIZE) / double(getSurfaceDimension(sData)); - steps = (int)ceilf(1.5f * EFF_MOVEMENT_PER_FRAME * fastest_effect / avg_dist * timescale); + steps = int(ceilf(1.5f * EFF_MOVEMENT_PER_FRAME * fastest_effect / avg_dist * timescale)); CLAMP(steps, 1, 20); return steps; @@ -5369,7 +5369,7 @@ static void dynamic_paint_effect_drip_cb(void *__restrict userdata, float dir_factor, a_factor; const float speed_scale = eff_scale * force[index * 4 + 3] / bNeighs[n_idx].dist; - const uint n_trgt = (uint)n_target[n_idx]; + const uint n_trgt = uint(n_target[n_idx]); /* Sort of spin-lock, but only for given ePoint. * Since the odds a same ePoint is modified at the same time by several threads is very low, @@ -5740,14 +5740,14 @@ static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescal int numOfNeighs = sData->adj_data->n_num[index]; for (int i = 0; i < numOfNeighs; i++) { - average_dist += (double)bNeighs[sData->adj_data->n_index[index] + i].dist; + average_dist += double(bNeighs[sData->adj_data->n_index[index] + i].dist); } } - average_dist *= (double)wave_scale / sData->adj_data->total_targets; + average_dist *= double(wave_scale) / sData->adj_data->total_targets; /* determine number of required steps */ - steps = (int)ceil((double)(WAVE_TIME_FAC * timescale * surface->wave_timescale) / - (average_dist / (double)wave_speed / 3)); + steps = (int)ceil(double(WAVE_TIME_FAC * timescale * surface->wave_timescale) / + (average_dist / double(wave_speed) / 3)); CLAMP(steps, 1, 20); timescale /= steps; @@ -6346,7 +6346,7 @@ static int dynamicPaint_doStep(Depsgraph *depsgraph, /* Prepare effects and get number of required steps */ steps = dynamicPaint_prepareEffectStep(depsgraph, surface, scene, ob, &force, timescale); for (s = 0; s < steps; s++) { - dynamicPaint_doEffectStep(surface, force, prevPoint, timescale, (float)steps); + dynamicPaint_doEffectStep(surface, force, prevPoint, timescale, float(steps)); } /* Free temporary effect data */ @@ -6386,7 +6386,7 @@ int dynamicPaint_calculateFrame( timescale = 1.0f / (surface->substeps + 1); for (st = 1; st <= surface->substeps; st++) { - float subframe = ((float)st) / (surface->substeps + 1); + float subframe = (float(st)) / (surface->substeps + 1); if (!dynamicPaint_doStep(depsgraph, scene, cObject, surface, timescale, subframe)) { return 0; } diff --git a/source/blender/blenkernel/intern/fluid.cc b/source/blender/blenkernel/intern/fluid.cc index 20f3171271a..912775f3bd1 100644 --- a/source/blender/blenkernel/intern/fluid.cc +++ b/source/blender/blenkernel/intern/fluid.cc @@ -441,28 +441,28 @@ static void manta_set_domain_from_mesh(FluidDomainSettings *fds, scale = res / size[0]; fds->scale = size[0] / fabsf(ob->scale[0]); fds->base_res[0] = res; - fds->base_res[1] = max_ii((int)(size[1] * scale + 0.5f), 4); - fds->base_res[2] = max_ii((int)(size[2] * scale + 0.5f), 4); + fds->base_res[1] = max_ii(int(size[1] * scale + 0.5f), 4); + fds->base_res[2] = max_ii(int(size[2] * scale + 0.5f), 4); } else if (size[1] >= MAX2(size[0], size[2])) { scale = res / size[1]; fds->scale = size[1] / fabsf(ob->scale[1]); - fds->base_res[0] = max_ii((int)(size[0] * scale + 0.5f), 4); + fds->base_res[0] = max_ii(int(size[0] * scale + 0.5f), 4); fds->base_res[1] = res; - fds->base_res[2] = max_ii((int)(size[2] * scale + 0.5f), 4); + fds->base_res[2] = max_ii(int(size[2] * scale + 0.5f), 4); } else { scale = res / size[2]; fds->scale = size[2] / fabsf(ob->scale[2]); - fds->base_res[0] = max_ii((int)(size[0] * scale + 0.5f), 4); - fds->base_res[1] = max_ii((int)(size[1] * scale + 0.5f), 4); + fds->base_res[0] = max_ii(int(size[0] * scale + 0.5f), 4); + fds->base_res[1] = max_ii(int(size[1] * scale + 0.5f), 4); fds->base_res[2] = res; } /* Set cell size. */ - fds->cell_size[0] /= (float)fds->base_res[0]; - fds->cell_size[1] /= (float)fds->base_res[1]; - fds->cell_size[2] /= (float)fds->base_res[2]; + fds->cell_size[0] /= float(fds->base_res[0]); + fds->cell_size[1] /= float(fds->base_res[1]); + fds->cell_size[2] /= float(fds->base_res[2]); } static void update_final_gravity(FluidDomainSettings *fds, Scene *scene) @@ -479,7 +479,7 @@ static void update_final_gravity(FluidDomainSettings *fds, Scene *scene) static bool fluid_modifier_init( FluidModifierData *fmd, Depsgraph *depsgraph, Object *ob, Scene *scene, Mesh *me) { - int scene_framenr = (int)DEG_get_ctime(depsgraph); + int scene_framenr = int(DEG_get_ctime(depsgraph)); if ((fmd->type & MOD_FLUID_TYPE_DOMAIN) && fmd->domain && !fmd->domain->fluid) { FluidDomainSettings *fds = fmd->domain; @@ -590,10 +590,10 @@ static void clamp_bounds_in_domain(FluidDomainSettings *fds, /* Adapt to velocity. */ if (min_vel && min_vel[i] < 0.0f) { - min[i] += (int)floor(min_vel[i] * dt); + min[i] += int(floor(min_vel[i] * dt)); } if (max_vel && max_vel[i] > 0.0f) { - max[i] += (int)ceil(max_vel[i] * dt); + max[i] += int(ceil(max_vel[i] * dt)); } /* Clamp within domain max size. */ @@ -650,18 +650,18 @@ static void bb_boundInsert(FluidObjectBB *bb, const float point[3]) int i = 0; if (!bb->valid) { for (; i < 3; i++) { - bb->min[i] = (int)floor(point[i]); - bb->max[i] = (int)ceil(point[i]); + bb->min[i] = int(floor(point[i])); + bb->max[i] = int(ceil(point[i])); } bb->valid = 1; } else { for (; i < 3; i++) { if (point[i] < bb->min[i]) { - bb->min[i] = (int)floor(point[i]); + bb->min[i] = int(floor(point[i])); } if (point[i] > bb->max[i]) { - bb->max[i] = (int)ceil(point[i]); + bb->max[i] = int(ceil(point[i])); } } } @@ -960,7 +960,7 @@ static void obstacles_from_mesh_task_cb(void *__restrict userdata, for (int y = data->min[1]; y < data->max[1]; y++) { const int index = manta_get_index( x - bb->min[0], bb->res[0], y - bb->min[1], bb->res[1], z - bb->min[2]); - const float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; + const float ray_start[3] = {float(x) + 0.5f, float(y) + 0.5f, float(z) + 0.5f}; /* Calculate levelset values from meshes. Result in bb->distances. */ update_distances(index, @@ -1055,7 +1055,7 @@ static void obstacles_from_mesh(Object *coll_ob, /* Set emission map. * Use 3 cell diagonals as margin (3 * 1.732 = 5.196). */ - int bounds_margin = (int)ceil(5.196); + int bounds_margin = int(ceil(5.196)); clamp_bounds_in_domain(fds, bb->min, bb->max, nullptr, nullptr, bounds_margin, dt); bb_allocateData(bb, true, false); @@ -1216,7 +1216,7 @@ static void compute_obstaclesemission(Scene *scene, } /* More splitting because of emission subframe: If no subframes present, sample_size is 1. */ - float sample_size = 1.0f / (float)(subframes + 1); + float sample_size = 1.0f / float(subframes + 1); float subframe_dt = dt * sample_size; /* Emission loop. When not using subframes this will loop only once. */ @@ -1484,7 +1484,7 @@ static void emit_from_particles_task_cb(void *__restrict userdata, for (int y = data->min[1]; y < data->max[1]; y++) { const int index = manta_get_index( x - bb->min[0], bb->res[0], y - bb->min[1], bb->res[1], z - bb->min[2]); - const float ray_start[3] = {((float)x) + 0.5f, ((float)y) + 0.5f, ((float)z) + 0.5f}; + const float ray_start[3] = {(float(x)) + 0.5f, (float(y)) + 0.5f, (float(z)) + 0.5f}; /* Find particle distance from the kdtree. */ KDTreeNearest_3d nearest; @@ -1554,7 +1554,7 @@ static void emit_from_particles(Object *flow_ob, /* setup particle radius emission if enabled */ if (ffs->flags & FLUID_FLOW_USE_PART_SIZE) { tree = BLI_kdtree_3d_new(psys->totpart + psys->totchild); - bounds_margin = (int)ceil(solid + smooth); + bounds_margin = int(ceil(solid + smooth)); } /* calculate local position for each particle */ @@ -2008,7 +2008,7 @@ static void emit_from_mesh_task_cb(void *__restrict userdata, for (int y = data->min[1]; y < data->max[1]; y++) { const int index = manta_get_index( x - bb->min[0], bb->res[0], y - bb->min[1], bb->res[1], z - bb->min[2]); - const float ray_start[3] = {((float)x) + 0.5f, ((float)y) + 0.5f, ((float)z) + 0.5f}; + const float ray_start[3] = {(float(x)) + 0.5f, (float(y)) + 0.5f, (float(z)) + 0.5f}; /* Compute emission only for flow objects that produce fluid (i.e. skip outflow objects). * Result in bb->influence. Also computes initial velocities. Result in bb->velocity. */ @@ -2031,9 +2031,9 @@ static void emit_from_mesh_task_cb(void *__restrict userdata, data->has_velocity, data->defgrp_index, data->dvert, - (float)x, - (float)y, - (float)z); + float(x), + float(y), + float(z)); } /* Calculate levelset values from meshes. Result in bb->distances. */ @@ -2123,7 +2123,7 @@ static void emit_from_mesh( /* Set emission map. * Use 3 cell diagonals as margin (3 * 1.732 = 5.196). */ - int bounds_margin = (int)ceil(5.196); + int bounds_margin = int(ceil(5.196)); clamp_bounds_in_domain(fds, bb->min, bb->max, nullptr, nullptr, bounds_margin, dt); bb_allocateData(bb, ffs->flags & FLUID_FLOW_INITVELOCITY, true); @@ -2199,9 +2199,9 @@ static void adaptive_domain_adjust( /* add to total shift */ add_v3_v3(fds->shift_f, frame_shift_f); /* convert to integer */ - total_shift[0] = (int)floorf(fds->shift_f[0]); - total_shift[1] = (int)floorf(fds->shift_f[1]); - total_shift[2] = (int)floorf(fds->shift_f[2]); + total_shift[0] = int(floorf(fds->shift_f[0])); + total_shift[1] = int(floorf(fds->shift_f[1])); + total_shift[2] = int(floorf(fds->shift_f[2])); int temp_shift[3]; copy_v3_v3_int(temp_shift, fds->shift); sub_v3_v3v3_int(new_shift, total_shift, fds->shift); @@ -2733,7 +2733,7 @@ static void compute_flowsemission(Scene *scene, } /* More splitting because of emission subframe: If no subframes present, sample_size is 1. */ - float sample_size = 1.0f / (float)(subframes + 1); + float sample_size = 1.0f / float(subframes + 1); float subframe_dt = dt * sample_size; /* Emission loop. When not using subframes this will loop only once. */ @@ -3135,9 +3135,9 @@ static void update_effectors_task_cb(void *__restrict userdata, normalize_v3(vel); mul_v3_fl(vel, mag); - voxel_center[0] = fds->p0[0] + fds->cell_size[0] * ((float)(x + fds->res_min[0]) + 0.5f); - voxel_center[1] = fds->p0[1] + fds->cell_size[1] * ((float)(y + fds->res_min[1]) + 0.5f); - voxel_center[2] = fds->p0[2] + fds->cell_size[2] * ((float)(z + fds->res_min[2]) + 0.5f); + voxel_center[0] = fds->p0[0] + fds->cell_size[0] * (float(x + fds->res_min[0]) + 0.5f); + voxel_center[1] = fds->p0[1] + fds->cell_size[1] * (float(y + fds->res_min[1]) + 0.5f); + voxel_center[2] = fds->p0[2] + fds->cell_size[2] * (float(z + fds->res_min[2]) + 0.5f); mul_m4_v3(fds->obmat, voxel_center); /* Do effectors. */ @@ -3297,7 +3297,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds, positions[i][2] = manta_liquid_get_vertex_z_at(fds->fluid, i); /* Adjust coordinates from Mantaflow to match viewport scaling. */ - float tmp[3] = {(float)fds->res[0], (float)fds->res[1], (float)fds->res[2]}; + float tmp[3] = {float(fds->res[0]), float(fds->res[1]), float(fds->res[2])}; /* Scale to unit cube around 0. */ mul_v3_fl(tmp, fds->mesh_scale * 0.5f); sub_v3_v3(positions[i], tmp); @@ -4078,7 +4078,7 @@ static void fluid_modifier_processDomain(FluidModifierData *fmd, static void fluid_modifier_process( FluidModifierData *fmd, Depsgraph *depsgraph, Scene *scene, Object *ob, Mesh *me) { - const int scene_framenr = (int)DEG_get_ctime(depsgraph); + const int scene_framenr = int(DEG_get_ctime(depsgraph)); if (fmd->type & MOD_FLUID_TYPE_FLOW) { fluid_modifier_processFlow(fmd, depsgraph, scene, ob, me, scene_framenr); @@ -4304,15 +4304,15 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, /* Convert light pos to sim cell space. */ mul_m4_v3(fds->imat, light); - light[0] = (light[0] - fds->p0[0]) / fds->cell_size[0] - 0.5f - (float)fds->res_min[0]; - light[1] = (light[1] - fds->p0[1]) / fds->cell_size[1] - 0.5f - (float)fds->res_min[1]; - light[2] = (light[2] - fds->p0[2]) / fds->cell_size[2] - 0.5f - (float)fds->res_min[2]; + light[0] = (light[0] - fds->p0[0]) / fds->cell_size[0] - 0.5f - float(fds->res_min[0]); + light[1] = (light[1] - fds->p0[1]) / fds->cell_size[1] - 0.5f - float(fds->res_min[1]); + light[2] = (light[2] - fds->p0[2]) / fds->cell_size[2] - 0.5f - float(fds->res_min[2]); /* Calculate domain bounds in sim cell space. */ /* 0,2,4 = 0.0f */ - bv[1] = (float)fds->res[0]; /* X */ - bv[3] = (float)fds->res[1]; /* Y */ - bv[5] = (float)fds->res[2]; /* Z */ + bv[1] = float(fds->res[0]); /* X */ + bv[3] = float(fds->res[1]); /* Y */ + bv[5] = float(fds->res[2]); /* Z */ for (int z = 0; z < fds->res[2]; z++) { size_t index = z * slabsize; @@ -4327,22 +4327,22 @@ static void manta_smoke_calc_transparency(FluidDomainSettings *fds, /* Reset shadow value. */ shadow[index] = -1.0f; - voxel_center[0] = (float)x; - voxel_center[1] = (float)y; - voxel_center[2] = (float)z; + voxel_center[0] = float(x); + voxel_center[1] = float(y); + voxel_center[2] = float(z); /* Get starting cell (light pos). */ if (BLI_bvhtree_bb_raycast(bv, light, voxel_center, pos) > FLT_EPSILON) { /* We're outside -> use point on side of domain. */ - cell[0] = (int)floor(pos[0]); - cell[1] = (int)floor(pos[1]); - cell[2] = (int)floor(pos[2]); + cell[0] = int(floor(pos[0])); + cell[1] = int(floor(pos[1])); + cell[2] = int(floor(pos[2])); } else { /* We're inside -> use light itself. */ - cell[0] = (int)floor(light[0]); - cell[1] = (int)floor(light[1]); - cell[2] = (int)floor(light[2]); + cell[0] = int(floor(light[0])); + cell[1] = int(floor(light[1])); + cell[2] = int(floor(light[2])); } /* Clamp within grid bounds */ CLAMP(cell[0], 0, fds->res[0] - 1); @@ -4394,9 +4394,9 @@ float BKE_fluid_get_velocity_at(Object *ob, float position[3], float velocity[3] } /* map pos between 0.0 - 1.0 */ - pos[0] = (pos[0] - fds->res_min[0]) / ((float)fds->res[0]); - pos[1] = (pos[1] - fds->res_min[1]) / ((float)fds->res[1]); - pos[2] = (pos[2] - fds->res_min[2]) / ((float)fds->res[2]); + pos[0] = (pos[0] - fds->res_min[0]) / (float(fds->res[0])); + pos[1] = (pos[1] - fds->res_min[1]) / (float(fds->res[1])); + pos[2] = (pos[2] - fds->res_min[2]) / (float(fds->res[2])); /* Check if position is outside active area. */ if (fds->type == FLUID_DOMAIN_TYPE_GAS && fds->flags & FLUID_DOMAIN_USE_ADAPTIVE_DOMAIN) { diff --git a/source/blender/blenkernel/intern/subdiv_foreach.cc b/source/blender/blenkernel/intern/subdiv_foreach.cc index c39c8717968..86a1c18c416 100644 --- a/source/blender/blenkernel/intern/subdiv_foreach.cc +++ b/source/blender/blenkernel/intern/subdiv_foreach.cc @@ -424,7 +424,7 @@ static void subdiv_foreach_edge_vertices_regular_do(SubdivForeachTaskContext *ct { const int resolution = ctx->settings->resolution; const int resolution_1 = resolution - 1; - const float inv_resolution_1 = 1.0f / (float)resolution_1; + const float inv_resolution_1 = 1.0f / float(resolution_1); const int num_subdiv_vertices_per_coarse_edge = resolution - 2; const int coarse_poly_index = coarse_poly - ctx->coarse_polys; const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; @@ -487,7 +487,7 @@ static void subdiv_foreach_edge_vertices_special_do(SubdivForeachTaskContext *ct const int resolution = ctx->settings->resolution; const int num_subdiv_vertices_per_coarse_edge = resolution - 2; const int num_vertices_per_ptex_edge = ((resolution >> 1) + 1); - const float inv_ptex_resolution_1 = 1.0f / (float)(num_vertices_per_ptex_edge - 1); + const float inv_ptex_resolution_1 = 1.0f / float(num_vertices_per_ptex_edge - 1); const int coarse_poly_index = coarse_poly - ctx->coarse_polys; const int ptex_face_start_index = ctx->face_ptex_offset[coarse_poly_index]; int ptex_face_index = ptex_face_start_index; @@ -598,7 +598,7 @@ static void subdiv_foreach_inner_vertices_regular(SubdivForeachTaskContext *ctx, const MPoly *coarse_poly) { const int resolution = ctx->settings->resolution; - const float inv_resolution_1 = 1.0f / (float)(resolution - 1); + const float inv_resolution_1 = 1.0f / float(resolution - 1); const int coarse_poly_index = coarse_poly - ctx->coarse_polys; const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; const int start_vertex_index = ctx->subdiv_vertex_offset[coarse_poly_index]; @@ -625,7 +625,7 @@ static void subdiv_foreach_inner_vertices_special(SubdivForeachTaskContext *ctx, { const int resolution = ctx->settings->resolution; const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution); - const float inv_ptex_face_resolution_1 = 1.0f / (float)(ptex_face_resolution - 1); + const float inv_ptex_face_resolution_1 = 1.0f / float(ptex_face_resolution - 1); const int coarse_poly_index = coarse_poly - ctx->coarse_polys; int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; const int start_vertex_index = ctx->subdiv_vertex_offset[coarse_poly_index]; @@ -1096,7 +1096,7 @@ static void subdiv_foreach_loops_regular(SubdivForeachTaskContext *ctx, const int ptex_inner_resolution = ptex_resolution - 2; const int num_subdiv_edges_per_coarse_edge = resolution - 1; const int num_subdiv_vertices_per_coarse_edge = resolution - 2; - const float inv_ptex_resolution_1 = 1.0f / (float)(ptex_resolution - 1); + const float inv_ptex_resolution_1 = 1.0f / float(ptex_resolution - 1); const int ptex_face_index = ctx->face_ptex_offset[coarse_poly_index]; const int start_vertex_index = ctx->vertices_inner_offset + ctx->subdiv_vertex_offset[coarse_poly_index]; @@ -1285,7 +1285,7 @@ static void subdiv_foreach_loops_special(SubdivForeachTaskContext *ctx, const int coarse_poly_index = coarse_poly - ctx->coarse_polys; const int ptex_face_resolution = ptex_face_resolution_get(coarse_poly, resolution); const int ptex_face_inner_resolution = ptex_face_resolution - 2; - const float inv_ptex_resolution_1 = 1.0f / (float)(ptex_face_resolution - 1); + const float inv_ptex_resolution_1 = 1.0f / float(ptex_face_resolution - 1); const int num_inner_vertices_per_ptex = (ptex_face_resolution - 1) * (ptex_face_resolution - 2); const int num_inner_edges_per_ptex_face = num_inner_edges_per_ptex_face_get( ptex_face_inner_resolution + 1); @@ -1685,7 +1685,7 @@ static void subdiv_foreach_vertices_of_loose_edges_task(void *__restrict userdat } const int resolution = ctx->settings->resolution; const int resolution_1 = resolution - 1; - const float inv_resolution_1 = 1.0f / (float)resolution_1; + const float inv_resolution_1 = 1.0f / float(resolution_1); const int num_subdiv_vertices_per_coarse_edge = resolution - 2; const MEdge *coarse_edge = &ctx->coarse_edges[coarse_edge_index]; /* Subdivision vertices which corresponds to edge's v1 and v2. */ diff --git a/source/blender/blenkernel/intern/subsurf_ccg.cc b/source/blender/blenkernel/intern/subsurf_ccg.cc index a3c634bff89..6a1d9baf63a 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.cc +++ b/source/blender/blenkernel/intern/subsurf_ccg.cc @@ -482,13 +482,13 @@ static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen) wtable->weight_table[faceLen].w = w = static_cast( MEM_callocN(sizeof(float) * faceLen * faceLen * (gridCuts + 2) * (gridCuts + 2), "weight table alloc")); - fac = 1.0f / (float)faceLen; + fac = 1.0f / float(faceLen); for (i = 0; i < faceLen; i++) { for (x = 0; x < gridCuts + 2; x++) { for (y = 0; y < gridCuts + 2; y++) { - fx = 0.5f - (float)x / (float)(gridCuts + 1) / 2.0f; - fy = 0.5f - (float)y / (float)(gridCuts + 1) / 2.0f; + fx = 0.5f - float(x) / float(gridCuts + 1) / 2.0f; + fy = 0.5f - float(y) / float(gridCuts + 1) / 2.0f; fac2 = faceLen - 4; w1 = (1.0f - fx) * (1.0f - fy) + (-fac2 * fx * fy * fac); @@ -498,7 +498,7 @@ static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen) /* these values aren't used for tri's and cause divide by zero */ if (faceLen > 3) { fac2 = 1.0f - (w1 + w2 + w4); - fac2 = fac2 / (float)(faceLen - 3); + fac2 = fac2 / float(faceLen - 3); for (j = 0; j < faceLen; j++) { w[j] = fac2; } @@ -537,7 +537,7 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss, float (*vertexCos)[3], int useFlatSubdiv) { - float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss); + float creaseFactor = float(ccgSubSurf_getSubdivisionLevels(ss)); blender::Vector fverts; float(*positions)[3] = (float(*)[3])dm->getVertArray(dm); MEdge *medge = dm->getEdgeArray(dm); @@ -1004,7 +1004,7 @@ static void copyFinalLoopArray_task_cb(void *__restrict userdata, CCGFace *f = ccgdm->faceMap[iter].face; const int num_verts = ccgSubSurf_getFaceNumVerts(f); const int grid_index = data->grid_offset[iter]; - const size_t loop_index = 4 * (size_t)grid_index * (grid_size - 1) * (grid_size - 1); + const size_t loop_index = 4 * size_t(grid_index) * (grid_size - 1) * (grid_size - 1); MLoop *ml = &data->mloop[loop_index]; for (int S = 0; S < num_verts; S++) { for (int y = 0; y < grid_size - 1; y++) { @@ -1755,7 +1755,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, for (x = 1; x < edgeSize - 1; x++) { float w[2]; - w[1] = (float)x / (edgeSize - 1); + w[1] = float(x) / (edgeSize - 1); w[0] = 1 - w[1]; DM_interp_vert_data(dm, &ccgdm->dm, vertIdx, w, 2, vertNum); if (vertOrigIndex) { @@ -2036,7 +2036,7 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*r_positions)[3]) /* ad-hoc correction for boundary vertices, to at least avoid them * moving completely out of place (brecht) */ if (numFaces && numFaces != N) { - mul_v3_fl(face_sum, (float)N / (float)numFaces); + mul_v3_fl(face_sum, float(N) / float(numFaces)); } const float *co = static_cast(ccgSubSurf_getVertData(ss, v)); diff --git a/source/blender/editors/armature/meshlaplacian.cc b/source/blender/editors/armature/meshlaplacian.cc index 5c9c6b9ec78..d29338a3eb4 100644 --- a/source/blender/editors/armature/meshlaplacian.cc +++ b/source/blender/editors/armature/meshlaplacian.cc @@ -108,16 +108,16 @@ static void laplacian_increase_edge_count(EdgeHash *edgehash, int v1, int v2) void **p; if (BLI_edgehash_ensure_p(edgehash, v1, v2, &p)) { - *p = (void *)((intptr_t)*p + (intptr_t)1); + *p = (void *)(intptr_t(*p) + intptr_t(1)); } else { - *p = (void *)((intptr_t)1); + *p = (void *)(intptr_t(1)); } } static int laplacian_edge_count(EdgeHash *edgehash, int v1, int v2) { - return (int)(intptr_t)BLI_edgehash_lookup(edgehash, v1, v2); + return int(intptr_t(BLI_edgehash_lookup(edgehash, v1, v2))); } static void laplacian_triangle_area(LaplacianSystem *sys, int i1, int i2, int i3) @@ -1248,7 +1248,7 @@ static float meshdeform_interp_w(MeshDeformBind *mdb, float totweight = 0.0f; for (int i = 0; i < 3; i++) { - ivec[i] = (int)gridvec[i]; + ivec[i] = int(gridvec[i]); dvec[i] = gridvec[i] - ivec[i]; } @@ -1564,7 +1564,7 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind "Mesh deform solve %d / %d |||", a + 1, mdb->cage_verts_num); - progress_bar((float)(a + 1) / (float)(mdb->cage_verts_num), message); + progress_bar(float(a + 1) / float(mdb->cage_verts_num), message); } #if 0 diff --git a/source/blender/editors/object/object_bake_api.cc b/source/blender/editors/object/object_bake_api.cc index 453432cb1e7..d3b8e0e0eed 100644 --- a/source/blender/editors/object/object_bake_api.cc +++ b/source/blender/editors/object/object_bake_api.cc @@ -187,7 +187,7 @@ static bool write_internal_bake_pixels(Image *image, void *lock; bool is_float; char *mask_buffer = nullptr; - const size_t pixels_num = (size_t)width * (size_t)height; + const size_t pixels_num = size_t(width) * size_t(height); ImageUser iuser; BKE_imageuser_default(&iuser); @@ -383,7 +383,7 @@ static bool write_external_bake_pixels(const char *filepath, /* margins */ if (margin > 0) { char *mask_buffer = nullptr; - const size_t pixels_num = (size_t)width * (size_t)height; + const size_t pixels_num = size_t(width) * size_t(height); mask_buffer = static_cast(MEM_callocN(sizeof(char) * pixels_num, "Bake Mask")); RE_bake_mask_fill(pixel_array, pixels_num, mask_buffer); @@ -765,7 +765,7 @@ static bool bake_targets_init_internal(const BakeAPIRender *bkr, bk_image->offset = targets->pixels_num; BKE_image_get_tile_uv(bk_image->image, bk_image->tile_number, bk_image->uv_offset); - targets->pixels_num += (size_t)ibuf->x * (size_t)ibuf->y; + targets->pixels_num += size_t(ibuf->x) * size_t(ibuf->y); } else { BKE_image_release_ibuf(bk_image->image, ibuf, lock); @@ -840,7 +840,7 @@ static bool bake_targets_init_external(const BakeAPIRender *bkr, bk_image->height = bkr->height; bk_image->offset = targets->pixels_num; - targets->pixels_num += (size_t)bkr->width * (size_t)bkr->height; + targets->pixels_num += size_t(bkr->width) * size_t(bkr->height); if (!bkr->is_split_materials) { break; diff --git a/source/blender/editors/sculpt_paint/sculpt_geodesic.cc b/source/blender/editors/sculpt_paint/sculpt_geodesic.cc index a8cac7dd7e5..3c72f59477c 100644 --- a/source/blender/editors/sculpt_paint/sculpt_geodesic.cc +++ b/source/blender/editors/sculpt_paint/sculpt_geodesic.cc @@ -195,7 +195,7 @@ static float *SCULPT_geodesic_mesh_create(Object *ob, edge_map_index++) { const int e_other = ss->vemap[v_other].indices[edge_map_index]; int ev_other; - if (edges[e_other].v1 == (uint)v_other) { + if (edges[e_other].v1 == uint(v_other)) { ev_other = edges[e_other].v2; } else { diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.cc b/source/blender/editors/sculpt_paint/sculpt_undo.cc index e27c9058751..16a83870115 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -1235,7 +1235,7 @@ static size_t sculpt_undo_alloc_and_store_hidden(PBVH *pbvh, SculptUndoNode *uno int *grid_indices, totgrid; BKE_pbvh_node_get_grids(pbvh, node, &grid_indices, &totgrid, NULL, NULL, NULL); - size_t alloc_size = sizeof(*unode->grid_hidden) * (size_t)totgrid; + size_t alloc_size = sizeof(*unode->grid_hidden) * size_t(totgrid); unode->grid_hidden = static_cast(MEM_callocN(alloc_size, "unode->grid_hidden")); for (int i = 0; i < totgrid; i++) { @@ -1335,24 +1335,24 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt unode->maxloop = 0; unode->totloop = totloop; - size_t alloc_size = sizeof(int) * (size_t)totloop; + size_t alloc_size = sizeof(int) * size_t(totloop); usculpt->undo_size += alloc_size; } if (need_faces) { sculpt_undo_store_faces(ss, unode); - const size_t alloc_size = sizeof(*unode->faces) * (size_t)unode->faces_num; + const size_t alloc_size = sizeof(*unode->faces) * size_t(unode->faces_num); usculpt->undo_size += alloc_size; } switch (type) { case SCULPT_UNDO_COORDS: { - size_t alloc_size = sizeof(*unode->co) * (size_t)allvert; + size_t alloc_size = sizeof(*unode->co) * size_t(allvert); unode->co = static_cast(MEM_callocN(alloc_size, "SculptUndoNode.co")); usculpt->undo_size += alloc_size; /* Needed for original data lookup. */ - alloc_size = sizeof(*unode->no) * (size_t)allvert; + alloc_size = sizeof(*unode->no) * size_t(allvert); unode->no = static_cast(MEM_callocN(alloc_size, "SculptUndoNode.no")); usculpt->undo_size += alloc_size; break; @@ -1369,7 +1369,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt break; } case SCULPT_UNDO_MASK: { - const size_t alloc_size = sizeof(*unode->mask) * (size_t)allvert; + const size_t alloc_size = sizeof(*unode->mask) * size_t(allvert); unode->mask = static_cast(MEM_callocN(alloc_size, "SculptUndoNode.mask")); usculpt->undo_size += alloc_size; break; @@ -1377,13 +1377,13 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt case SCULPT_UNDO_COLOR: { /* Allocate vertex colors, even for loop colors we still * need this for original data lookup. */ - const size_t alloc_size = sizeof(*unode->col) * (size_t)allvert; + const size_t alloc_size = sizeof(*unode->col) * size_t(allvert); unode->col = static_cast(MEM_callocN(alloc_size, "SculptUndoNode.col")); usculpt->undo_size += alloc_size; /* Allocate loop colors separately too. */ if (ss->vcol_domain == ATTR_DOMAIN_CORNER) { - size_t alloc_size_loop = sizeof(float) * 4 * (size_t)unode->totloop; + size_t alloc_size_loop = sizeof(float) * 4 * size_t(unode->totloop); unode->loop_col = static_cast( MEM_calloc_arrayN(unode->totloop, sizeof(float) * 4, "SculptUndoNode.loop_col")); @@ -1399,7 +1399,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt case SCULPT_UNDO_GEOMETRY: break; case SCULPT_UNDO_FACE_SETS: { - const size_t alloc_size = sizeof(*unode->face_sets) * (size_t)unode->faces_num; + const size_t alloc_size = sizeof(*unode->face_sets) * size_t(unode->faces_num); usculpt->undo_size += alloc_size; break; } @@ -1411,7 +1411,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt unode->totgrid = totgrid; unode->gridsize = gridsize; - const size_t alloc_size = sizeof(*unode->grids) * (size_t)totgrid; + const size_t alloc_size = sizeof(*unode->grids) * size_t(totgrid); unode->grids = static_cast(MEM_callocN(alloc_size, "SculptUndoNode.grids")); usculpt->undo_size += alloc_size; } @@ -1419,13 +1419,13 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node, Sculpt /* Regular mesh. */ unode->maxvert = ss->totvert; - const size_t alloc_size = sizeof(*unode->index) * (size_t)allvert; + const size_t alloc_size = sizeof(*unode->index) * size_t(allvert); unode->index = static_cast(MEM_callocN(alloc_size, "SculptUndoNode.index")); usculpt->undo_size += alloc_size; } if (ss->deform_modifiers_active) { - const size_t alloc_size = sizeof(*unode->orig_co) * (size_t)allvert; + const size_t alloc_size = sizeof(*unode->orig_co) * size_t(allvert); unode->orig_co = static_cast(MEM_callocN(alloc_size, "undoSculpt orig_cos")); usculpt->undo_size += alloc_size; } diff --git a/source/blender/editors/undo/ed_undo.cc b/source/blender/editors/undo/ed_undo.cc index 25f6d2aa274..a6e78d15744 100644 --- a/source/blender/editors/undo/ed_undo.cc +++ b/source/blender/editors/undo/ed_undo.cc @@ -138,7 +138,7 @@ void ED_undo_push(bContext *C, const char *str) push_retval = BKE_undosys_step_push(wm->undo_stack, C, str); if (U.undomemory != 0) { - const size_t memory_limit = (size_t)U.undomemory * 1024 * 1024; + const size_t memory_limit = size_t(U.undomemory) * 1024 * 1024; BKE_undosys_stack_limit_steps_and_memory(wm->undo_stack, -1, memory_limit); } diff --git a/source/blender/windowmanager/intern/wm_files.cc b/source/blender/windowmanager/intern/wm_files.cc index 8a0e206b5e7..4fb30ca3d9e 100644 --- a/source/blender/windowmanager/intern/wm_files.cc +++ b/source/blender/windowmanager/intern/wm_files.cc @@ -482,7 +482,7 @@ static void wm_init_userdef(Main *bmain) SET_FLAG_FROM_TEST(G.f, (U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0, G_FLAG_SCRIPT_AUTOEXEC); } - MEM_CacheLimiter_set_maximum(((size_t)U.memcachelimit) * 1024 * 1024); + MEM_CacheLimiter_set_maximum((size_t(U.memcachelimit)) * 1024 * 1024); BKE_sound_init(bmain); /* Update the temporary directory from the preferences or fallback to the system default. */ @@ -1603,10 +1603,10 @@ static ImBuf *blend_file_thumb_from_screenshot(bContext *C, BlendThumbnail **r_t int ex, ey; if (ibuf->x > ibuf->y) { ex = BLEN_THUMB_SIZE; - ey = max_ii(1, (int)(((float)ibuf->y / (float)ibuf->x) * BLEN_THUMB_SIZE)); + ey = max_ii(1, int((float(ibuf->y) / float(ibuf->x)) * BLEN_THUMB_SIZE)); } else { - ex = max_ii(1, (int)(((float)ibuf->x / (float)ibuf->y) * BLEN_THUMB_SIZE)); + ex = max_ii(1, int((float(ibuf->x) / float(ibuf->y)) * BLEN_THUMB_SIZE)); ey = BLEN_THUMB_SIZE; } @@ -2775,14 +2775,14 @@ static char *wm_open_mainfile_description(struct bContext * /*C*/, char time_st[FILELIST_DIRENTRY_TIME_LEN]; bool is_today, is_yesterday; BLI_filelist_entry_datetime_to_string( - nullptr, (int64_t)stats.st_mtime, false, time_st, date_st, &is_today, &is_yesterday); + nullptr, int64_t(stats.st_mtime), false, time_st, date_st, &is_today, &is_yesterday); if (is_today || is_yesterday) { BLI_strncpy(date_st, is_today ? TIP_("Today") : TIP_("Yesterday"), sizeof(date_st)); } /* Size. */ char size_str[FILELIST_DIRENTRY_SIZE_LEN]; - BLI_filelist_entry_size_to_string(nullptr, (uint64_t)stats.st_size, false, size_str); + BLI_filelist_entry_size_to_string(nullptr, uint64_t(stats.st_size), false, size_str); return BLI_sprintfN( "%s\n\n%s: %s %s\n%s: %s", path, TIP_("Modified"), date_st, time_st, TIP_("Size"), size_str); From 64dbfe714bbae4b4dc0ee2b179243fe1a821d89d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 23 Jan 2023 17:31:47 +1100 Subject: [PATCH 0868/1522] Fix T99963: Fallback actions are used in RCS on left click The right mouse-select action no longer changes the dragging behavior of the left mouse button. --- release/scripts/presets/keyconfig/Blender.py | 3 +- .../keyconfig/keymap_data/blender_default.py | 55 ++++++++++--------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/release/scripts/presets/keyconfig/Blender.py b/release/scripts/presets/keyconfig/Blender.py index 2e77f233ca4..e77fde4c39c 100644 --- a/release/scripts/presets/keyconfig/Blender.py +++ b/release/scripts/presets/keyconfig/Blender.py @@ -352,8 +352,7 @@ def load(): use_v3d_tab_menu=kc_prefs.use_v3d_tab_menu, use_v3d_shade_ex_pie=kc_prefs.use_v3d_shade_ex_pie, use_gizmo_drag=(is_select_left and kc_prefs.gizmo_action == 'DRAG'), - use_fallback_tool=True, - use_fallback_tool_rmb=(False if is_select_left else kc_prefs.rmb_action == 'FALLBACK_TOOL'), + use_fallback_tool=True if is_select_left else (kc_prefs.rmb_action == 'FALLBACK_TOOL'), use_tweak_select_passthrough=(show_developer_ui and kc_prefs.use_tweak_select_passthrough), use_tweak_tool_lmb_interaction=( False if is_select_left else diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 4149377581c..8f659449315 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -11,7 +11,7 @@ __all__ = ( # - This script should run without Blender (no references to the `bpy` module for example). # - All configuration must be passed into the `generate_keymaps` function (via `Params`). # - Supporting some combinations of options is becoming increasingly complex, -# especially `Params.select_mouse` & `Params.use_fallback_tool_rmb`. +# especially `Params.select_mouse` & `Params.use_fallback_tool`. # To ensure changes don't unintentionally break other configurations, see: # `source/tools/utils/blender_keyconfig_export_permutations.py --help` # @@ -52,8 +52,6 @@ class Params: "use_gizmo_drag", # Use the fallback tool instead of tweak for RMB select. "use_fallback_tool", - # Only set for RMB select. - "use_fallback_tool_rmb", # Use pie menu for tab by default (swap 'Tab/Ctrl-Tab'). "use_v3d_tab_menu", # Use extended pie menu for shading. @@ -78,9 +76,9 @@ class Params: # (derived from other settings). # # The fallback tool is activated on the same button as selection. - # Shorthand for: `(True if (select_mouse == 'LEFT') else self.use_fallback_tool_rmb)` + # Shorthand for: `(True if (select_mouse == 'LEFT') else self.use_fallback_tool)` "use_fallback_tool_select_mouse", - # Shorthand for: `('CLICK' if self.use_fallback_tool_rmb else self.select_mouse_value)`. + # Shorthand for: `('CLICK' if self.use_fallback_tool and select_mouse == 'RIGHT' else self.select_mouse_value)`. "select_mouse_value_fallback", # Shorthand for: `{"type": params.select_mouse, "value": 'CLICK_DRAG'}`. "select_tweak_event", @@ -110,7 +108,6 @@ class Params: use_select_all_toggle=False, use_gizmo_drag=True, use_fallback_tool=False, - use_fallback_tool_rmb=False, use_tweak_select_passthrough=False, use_tweak_tool_lmb_interaction=False, use_v3d_tab_menu=False, @@ -202,11 +199,12 @@ class Params: self.use_tweak_select_passthrough = use_tweak_select_passthrough self.use_fallback_tool = use_fallback_tool - self.use_fallback_tool_rmb = use_fallback_tool_rmb # Convenience variables: - self.use_fallback_tool_select_mouse = True if (select_mouse == 'LEFT') else self.use_fallback_tool_rmb - self.select_mouse_value_fallback = 'CLICK' if self.use_fallback_tool_rmb else self.select_mouse_value + self.use_fallback_tool_select_mouse = True if (select_mouse == 'LEFT') else self.use_fallback_tool + self.select_mouse_value_fallback = ( + 'CLICK' if (self.use_fallback_tool and select_mouse == 'RIGHT') else self.select_mouse_value + ) self.select_tweak_event = {"type": self.select_mouse, "value": 'CLICK_DRAG'} self.pie_value = 'CLICK_DRAG' if use_pie_click_drag else 'PRESS' self.tool_tweak_event = {"type": self.tool_mouse, "value": 'CLICK_DRAG'} @@ -4720,7 +4718,7 @@ def _template_paint_radial_control(paint, rotation=False, secondary_rotation=Fal def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_mod=None): # NOTE: `exclude_mod` is needed since we don't want this tool to exclude Control-RMB actions when this is used - # as a tool key-map with RMB-select and `use_fallback_tool_rmb` is enabled. See T92467. + # as a tool key-map with RMB-select and `use_fallback_tool` is enabled with RMB select. See T92467. props_vert_without_handles = () if select_passthrough: @@ -6501,11 +6499,12 @@ def km_image_editor_tool_uv_select(params, *, fallback): {"items": [ *([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select( params, "uv.select", "uv.cursor_set", fallback=fallback)), - *([] if (not params.use_fallback_tool_rmb) else _template_uv_select( - type=params.select_mouse, - value=params.select_mouse_value, - select_passthrough=params.use_tweak_select_passthrough, - legacy=params.legacy, + *([] if (not (params.use_fallback_tool and params.select_mouse == 'RIGHTMOUSE')) else + _template_uv_select( + type=params.select_mouse, + value=params.select_mouse_value, + select_passthrough=params.use_tweak_select_passthrough, + legacy=params.legacy, )), ]}, ) @@ -6720,12 +6719,13 @@ def km_3d_view_tool_select(params, *, fallback): {"items": [ *([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select( params, "view3d.select", "view3d.cursor3d", operator_props=operator_props, fallback=fallback)), - *([] if (not params.use_fallback_tool_rmb) else _template_view3d_select( - type=params.select_mouse, - value=params.select_mouse_value, - legacy=params.legacy, - select_passthrough=params.use_tweak_select_passthrough, - exclude_mod="ctrl", + *([] if (not (params.use_fallback_tool and params.select_mouse == 'RIGHTMOUSE')) else + _template_view3d_select( + type=params.select_mouse, + value=params.select_mouse_value, + legacy=params.legacy, + select_passthrough=params.use_tweak_select_passthrough, + exclude_mod="ctrl", )), ]}, ) @@ -7664,8 +7664,12 @@ def km_3d_view_tool_edit_gpencil_select(params, *, fallback): {"items": [ *([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select( params, "gpencil.select", "view3d.cursor3d", fallback=fallback)), - *([] if (not params.use_fallback_tool_rmb) else _template_view3d_gpencil_select( - type=params.select_mouse, value=params.select_mouse_value, legacy=params.legacy)), + *([] if (not (params.use_fallback_tool and params.select_mouse == 'RIGHTMOUSE')) else + _template_view3d_gpencil_select( + type=params.select_mouse, + value=params.select_mouse_value, + legacy=params.legacy, + )), ]}, ) @@ -7843,8 +7847,9 @@ def km_sequencer_editor_tool_generic_select(params, *, fallback): *([] if (fallback and (params.select_mouse == 'RIGHTMOUSE')) else _template_items_tool_select( params, "sequencer.select", "sequencer.cursor_set", cursor_prioritize=True, fallback=fallback)), - *([] if (not params.use_fallback_tool_rmb) else _template_sequencer_preview_select( - type=params.select_mouse, value=params.select_mouse_value, legacy=params.legacy)), + *([] if (not (params.use_fallback_tool and params.select_mouse == 'RIGHTMOUSE')) else + _template_sequencer_preview_select( + type=params.select_mouse, value=params.select_mouse_value, legacy=params.legacy)), # Ignored for preview. *_template_items_change_frame(params), ]}, From f5c081dafc79041dab7985a66f4546a30149121b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 23 Jan 2023 20:23:55 +1100 Subject: [PATCH 0869/1522] Fix T104033: UV edges not selecting when selecting faces Regression in [0] replaced edge with vertex selection. [0]: 6c774feba2c9a1eb5834646f597a0f2c63177914 --- source/blender/editors/uvedit/uvedit_select.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index 7595577e160..50185049fe1 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -3315,12 +3315,12 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (select) { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, true); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, true); uv_select_flush_from_tag_sticky_loc_internal( scene, em, vmap, efa_index, l, select, offsets); } else { - BM_ELEM_CD_SET_BOOL(l, offsets.select_vert, false); + BM_ELEM_CD_SET_BOOL(l, offsets.select_edge, false); if (!uvedit_vert_is_face_select_any_other(scene, l, offsets)) { uv_select_flush_from_tag_sticky_loc_internal( scene, em, vmap, efa_index, l, select, offsets); From e0c8fa4ab9511c3661ca621843df94a2a6033855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Thu, 19 Jan 2023 19:29:50 +0100 Subject: [PATCH 0870/1522] DRW: Fix Texture.ensure() function always recreating the texture This was caused by recent change of the `size()` method which now return 1 for missing dimensions. --- source/blender/draw/intern/DRW_gpu_wrapper.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/intern/DRW_gpu_wrapper.hh b/source/blender/draw/intern/DRW_gpu_wrapper.hh index 0bb005dd160..1653dedebba 100644 --- a/source/blender/draw/intern/DRW_gpu_wrapper.hh +++ b/source/blender/draw/intern/DRW_gpu_wrapper.hh @@ -866,7 +866,8 @@ class Texture : NonCopyable { /* TODO(@fclem): In the future, we need to check if mip_count did not change. * For now it's ok as we always define all MIP level. */ if (tx_) { - int3 size = this->size(); + int3 size(0); + GPU_texture_get_mipmap_size(tx_, 0, size); if (size != int3(w, h, d) || GPU_texture_format(tx_) != format || GPU_texture_cube(tx_) != cubemap || GPU_texture_array(tx_) != layered) { free(); From 607b814096549c6ebff04c7e242bc552c4d3eb40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 23 Jan 2023 11:04:53 +0100 Subject: [PATCH 0871/1522] DRW: Debug Print: Fix print of vec3 --- .../draw/intern/shaders/common_debug_print_lib.glsl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/draw/intern/shaders/common_debug_print_lib.glsl b/source/blender/draw/intern/shaders/common_debug_print_lib.glsl index 859e44d7dd2..36ff3a90622 100644 --- a/source/blender/draw/intern/shaders/common_debug_print_lib.glsl +++ b/source/blender/draw/intern/shaders/common_debug_print_lib.glsl @@ -334,7 +334,7 @@ void drw_print_value(vec2 value) void drw_print_value(vec3 value) { - drw_print_no_endl("vec3(", value[0], ", ", value[1], ", ", value[1], ")"); + drw_print_no_endl("vec3(", value[0], ", ", value[1], ", ", value[2], ")"); } void drw_print_value(vec4 value) @@ -349,7 +349,7 @@ void drw_print_value(ivec2 value) void drw_print_value(ivec3 value) { - drw_print_no_endl("ivec3(", value[0], ", ", value[1], ", ", value[1], ")"); + drw_print_no_endl("ivec3(", value[0], ", ", value[1], ", ", value[2], ")"); } void drw_print_value(ivec4 value) @@ -364,7 +364,7 @@ void drw_print_value(uvec2 value) void drw_print_value(uvec3 value) { - drw_print_no_endl("uvec3(", value[0], ", ", value[1], ", ", value[1], ")"); + drw_print_no_endl("uvec3(", value[0], ", ", value[1], ", ", value[2], ")"); } void drw_print_value(uvec4 value) @@ -379,7 +379,7 @@ void drw_print_value(bvec2 value) void drw_print_value(bvec3 value) { - drw_print_no_endl("bvec3(", value[0], ", ", value[1], ", ", value[1], ")"); + drw_print_no_endl("bvec3(", value[0], ", ", value[1], ", ", value[2], ")"); } void drw_print_value(bvec4 value) From 59ee5add1283c8a7bbe7d3e6ada521a6c41e47e7 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 23 Jan 2023 12:31:43 +0100 Subject: [PATCH 0872/1522] Usual UI messages fixes & tweaks. --- source/blender/windowmanager/intern/wm_window.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 26dbd6ce96f..1c029a6902d 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1723,14 +1723,13 @@ static uiBlock *block_create_opengl_usage_warning(struct bContext *C, /* Title and explanation text. */ uiLayout *col = uiLayoutColumn(layout, false); - uiItemL_ex(col, TIP_("Python script uses OpenGL for drawing."), ICON_NONE, true, false); + uiItemL_ex(col, TIP_("Python script uses OpenGL for drawing"), ICON_NONE, true, false); uiItemL(col, TIP_("This may lead to unexpected behavior"), ICON_NONE); - uiItemL( - col, - TIP_("One of the add-ons or scripts is using OpenGL and will not work correct on Metal."), - ICON_NONE); uiItemL(col, - TIP_("Please contact the developer of the add-on to migrate to use 'gpu' module."), + TIP_("One of the add-ons or scripts is using OpenGL and will not work correct on Metal"), + ICON_NONE); + uiItemL(col, + TIP_("Please contact the developer of the add-on to migrate to use 'gpu' module"), ICON_NONE); if (G.opengl_deprecation_usage_filename) { char location[1024]; @@ -1738,7 +1737,7 @@ static uiBlock *block_create_opengl_usage_warning(struct bContext *C, location, "%s:%d", G.opengl_deprecation_usage_filename, G.opengl_deprecation_usage_lineno); uiItemL(col, location, ICON_NONE); } - uiItemL(col, TIP_("See system tab in preferences to switch to OpenGL backend."), ICON_NONE); + uiItemL(col, TIP_("See system tab in preferences to switch to OpenGL backend"), ICON_NONE); uiItemS(layout); @@ -1769,7 +1768,7 @@ void wm_test_opengl_deprecation_warning(bContext *C) &wm->reports, RPT_ERROR, TIP_("One of the add-ons or scripts is using OpenGL and will not work correct on Metal. " - "Please contact the developer of the add-on to migrate to use 'gpu' module.")); + "Please contact the developer of the add-on to migrate to use 'gpu' module")); if (win) { wmWindow *prevwin = CTX_wm_window(C); From 6043ed9e62ec9c72f04930c711e65142675b4187 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Mon, 23 Jan 2023 13:52:21 +0100 Subject: [PATCH 0873/1522] Build: checkout assets directory automatically This changes `make update` to download the assets repository automatically if it does not exist already. If it does exist, it is updated. Precompiled libraries have the same behavior. This is required for T103620. `pipeline_config.yaml` is updated as well for the builtbot. Differential Revision: https://developer.blender.org/D17090 --- build_files/config/pipeline_config.yaml | 4 ++++ build_files/utils/make_update.py | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/build_files/config/pipeline_config.yaml b/build_files/config/pipeline_config.yaml index 392bd842586..88ca5108e8b 100644 --- a/build_files/config/pipeline_config.yaml +++ b/build_files/config/pipeline_config.yaml @@ -43,6 +43,10 @@ update-code: branch: trunk commit_id: HEAD path: lib/benchmarks + assets: + branch: trunk + commit_id: HEAD + path: lib/assets # # Buildbot only configs diff --git a/build_files/utils/make_update.py b/build_files/utils/make_update.py index fbadeecd597..2288a9972b8 100755 --- a/build_files/utils/make_update.py +++ b/build_files/utils/make_update.py @@ -104,17 +104,30 @@ def svn_update(args: argparse.Namespace, release_version: Optional[str]) -> None svn_url_tests = svn_url + lib_tests call(svn_non_interactive + ["checkout", svn_url_tests, lib_tests_dirpath]) - # Update precompiled libraries and tests + lib_assets = "assets" + lib_assets_dirpath = os.path.join(lib_dirpath, lib_assets) + + if not os.path.exists(lib_assets_dirpath): + print_stage("Checking out Assets") + + if make_utils.command_missing(args.svn_command): + sys.stderr.write("svn not found, can't checkout assets\n") + sys.exit(1) + + svn_url_assets = svn_url + lib_assets + call(svn_non_interactive + ["checkout", svn_url_assets, lib_assets_dirpath]) + + # Update precompiled libraries, assets and tests if not os.path.isdir(lib_dirpath): print("Library path: %r, not found, skipping" % lib_dirpath) else: paths_local_and_remote = [] if os.path.exists(os.path.join(lib_dirpath, ".svn")): - print_stage("Updating Precompiled Libraries and Tests (one repository)") + print_stage("Updating Precompiled Libraries, Assets and Tests (one repository)") paths_local_and_remote.append((lib_dirpath, svn_url)) else: - print_stage("Updating Precompiled Libraries and Tests (multiple repositories)") + print_stage("Updating Precompiled Libraries, Assets and Tests (multiple repositories)") # Separate paths checked out. for dirname in os.listdir(lib_dirpath): if dirname.startswith("."): From b44a8f6749a5eed3fea980a413b1cd179dea2781 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Mon, 23 Jan 2023 16:25:04 +0100 Subject: [PATCH 0874/1522] Fix: Draw: Negative scaled objects cause wrong resource indexing In the new Draw Manager, when the same DrawGroup has both front and back facing instances, the front facing instances don't offset their indices accordingly. Differential Revision: https://developer.blender.org/D17069 --- .../intern/shaders/draw_command_generate_comp.glsl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/intern/shaders/draw_command_generate_comp.glsl b/source/blender/draw/intern/shaders/draw_command_generate_comp.glsl index 75e5cda29d2..11bf862a911 100644 --- a/source/blender/draw/intern/shaders/draw_command_generate_comp.glsl +++ b/source/blender/draw/intern/shaders/draw_command_generate_comp.glsl @@ -13,7 +13,8 @@ void write_draw_call(DrawGroup group, uint group_id) DrawCommand cmd; cmd.vertex_len = group.vertex_len; cmd.vertex_first = group.vertex_first; - if (group.base_index != -1) { + bool indexed_draw = group.base_index != -1; + if (indexed_draw) { cmd.base_index = group.base_index; cmd.instance_first_indexed = group.start; } @@ -23,7 +24,15 @@ void write_draw_call(DrawGroup group, uint group_id) /* Back-facing command. */ cmd.instance_len = group_buf[group_id].back_facing_counter; command_buf[group_id * 2 + 0] = cmd; + /* Front-facing command. */ + uint front_facing_start = group.start + (group.len - group.front_facing_len); + if (indexed_draw) { + cmd.instance_first_indexed = front_facing_start; + } + else { + cmd._instance_first_array = front_facing_start; + } cmd.instance_len = group_buf[group_id].front_facing_counter; command_buf[group_id * 2 + 1] = cmd; From 48b82a6ea312b7dca0e9c8c97e26eb56ff46ddb6 Mon Sep 17 00:00:00 2001 From: Tomoaki Nakano Date: Mon, 23 Jan 2023 16:55:34 +0100 Subject: [PATCH 0875/1522] Fix Metal GPU backend shader compile errors in certain language environments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes an issue where Blender 3.5 alpha with the Metal GPU backend enabled on Japanese macOS fails to compile shaders and crashes on startup. In a Japanese environment, `defaultCStringEncoding` is the legacy MacJapanese encoding, and it erroneously converts backslashes (0x5c) to Yen symbols (¥). Therefore, Metal shader compile fails with the following log and Blender crashes. ``` 2022-12-29 13:50:10.200 Blender[13404:246707] Compile Error - Metal Shader Library (Stage: 0), error Error Domain=MTLLibraryErrorDomain Code=3 "program_source:225:74: error: non-ASCII characters are not allowed outside of literals and identifiers template struct STRUCT_NAME { ¥ ^ program_source:226:14: error: no template named 'TEX_TYPE' thread TEX_TYPE *texture; ¥ ^ program_source:226:39: error: non-ASCII characters are not allowed outside of literals and identifiers thread TEX_TYPE *texture; ¥ ^ program_source:227:29: error: non-ASCII characters are not allowed outside of literals and identifiers thread sampler *samp; ¥ ^ ... ``` We can use `stringWithUTF8String` instead. Reviewed By: fclem, MichaelPW Differential Revision: https://developer.blender.org/D16881 --- source/blender/gpu/metal/mtl_shader_generator.mm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm index 006e0fbd9cf..fbdf9422ced 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.mm +++ b/source/blender/gpu/metal/mtl_shader_generator.mm @@ -1049,12 +1049,10 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info) #endif /* Set MSL source NSString's. Required by Metal API. */ - NSString *msl_final_vert = [NSString stringWithCString:ss_vertex.str().c_str() - encoding:[NSString defaultCStringEncoding]]; + NSString *msl_final_vert = [NSString stringWithUTF8String:ss_vertex.str().c_str()]; NSString *msl_final_frag = (msl_iface.uses_transform_feedback) ? (@"") : - ([NSString stringWithCString:ss_fragment.str().c_str() - encoding:[NSString defaultCStringEncoding]]); + ([NSString stringWithUTF8String:ss_fragment.str().c_str()]); this->shader_source_from_msl(msl_final_vert, msl_final_frag); shader_debug_printf("[METAL] BSL Converted into MSL\n"); From cd2926fb05b0179a405a5406d6b87f5bff36d15a Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Mon, 23 Jan 2023 16:57:26 +0100 Subject: [PATCH 0876/1522] Fix T103412: Resolve selection outline rendering with Metal backend on AMD. AMD GPUs do not appear to produce consistent results with other GPUs when using textureGather in the Metal backend. Disabling for now to ensure correct function of outline rendering. This may require an additional sub-pixel offset in the texture sampling calls, to achieve correct behaviour. Authored by Apple: Michael Parkin-White Ref T103412 Ref T96261 Reviewed By: fclem Maniphest Tasks: T103412, T96261 Differential Revision: https://developer.blender.org/D16934 --- .../overlay/shaders/overlay_outline_detect_frag.glsl | 4 ++++ source/blender/gpu/metal/mtl_backend.mm | 3 +++ source/blender/gpu/metal/mtl_capabilities.hh | 1 + source/blender/gpu/metal/mtl_shader_generator.mm | 12 +++++++++--- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/source/blender/draw/engines/overlay/shaders/overlay_outline_detect_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_outline_detect_frag.glsl index 18914b0276f..b6d68628811 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_outline_detect_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_outline_detect_frag.glsl @@ -254,7 +254,11 @@ void main() edge_case += int(has_edge_neg_y) * YNEG; if (edge_case == ALL || edge_case == NONE) { + /* NOTE(Metal): Discards are not explicit returns in Metal. We should also return to avoid + * erroneous derivatives which can manifest during texture sampling in + * non-uniform-control-flow. */ discard; + return; } if (!doAntiAliasing) { diff --git a/source/blender/gpu/metal/mtl_backend.mm b/source/blender/gpu/metal/mtl_backend.mm index e6bd8456605..432db09005e 100644 --- a/source/blender/gpu/metal/mtl_backend.mm +++ b/source/blender/gpu/metal/mtl_backend.mm @@ -358,6 +358,9 @@ void MTLBackend::capabilities_init(MTLContext *ctx) supportsFamily:MTLGPUFamilyMacCatalyst1]; MTLBackend::capabilities.supports_family_mac_catalyst2 = [device supportsFamily:MTLGPUFamilyMacCatalyst2]; + /* NOTE(Metal): Texture gather is supported on AMD, but results are non consistent + * with Apple Silicon GPUs. Disabling for now to avoid erroneous rendering. */ + MTLBackend::capabilities.supports_texture_gather = [device hasUnifiedMemory]; /* Common Global Capabilities. */ GCaps.max_texture_size = ([device supportsFamily:MTLGPUFamilyApple3] || diff --git a/source/blender/gpu/metal/mtl_capabilities.hh b/source/blender/gpu/metal/mtl_capabilities.hh index 36536438bf5..7e6b12cba43 100644 --- a/source/blender/gpu/metal/mtl_capabilities.hh +++ b/source/blender/gpu/metal/mtl_capabilities.hh @@ -36,6 +36,7 @@ struct MTLCapabilities { bool supports_memory_barriers = false; bool supports_sampler_border_color = false; bool supports_argument_buffers_tier2 = false; + bool supports_texture_gather = false; /* GPU Family */ bool supports_family_mac1 = false; diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm index fbdf9422ced..880016589fc 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.mm +++ b/source/blender/gpu/metal/mtl_shader_generator.mm @@ -569,10 +569,16 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info) /* Concatenate msl_shader_defines to provide functionality mapping * from GLSL to MSL. Also include additional GPU defines for * optional high-level feature support. */ - const std::string msl_defines_string = + std::string msl_defines_string = "#define GPU_ARB_texture_cube_map_array 1\n\ - #define GPU_ARB_shader_draw_parameters 1\n\ - #define GPU_ARB_texture_gather 1\n"; + #define GPU_ARB_shader_draw_parameters 1\n"; + + /* NOTE(Metal): textureGather appears to not function correctly on non-Apple-silicon GPUs. + * Manifests as selection outlines not showing up (T103412). Disable texture gather if + * not suitable for use. */ + if (MTLBackend::get_capabilities().supports_texture_gather) { + msl_defines_string += "#define GPU_ARB_texture_gather 1\n"; + } shd_builder_->glsl_vertex_source_ = msl_defines_string + shd_builder_->glsl_vertex_source_; if (!msl_iface.uses_transform_feedback) { From 8e56ded86d6261e8a937ab6ca8d724f0f42814c2 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Mon, 23 Jan 2023 11:56:12 +0100 Subject: [PATCH 0877/1522] Cycles: temporarily disable AMD Vega GPU rendering due to compiler bug To make daily builds pass while we figure this out. Ref T104097 --- CMakeLists.txt | 2 +- intern/cycles/blender/addon/properties.py | 4 ++-- intern/cycles/device/hip/util.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 94bad8c20fc..df1a5a88550 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -506,7 +506,7 @@ endif() if(NOT APPLE) option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON) option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF) - set(CYCLES_HIP_BINARIES_ARCH gfx900 gfx906 gfx90c gfx902 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for") + set(CYCLES_HIP_BINARIES_ARCH gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for") mark_as_advanced(WITH_CYCLES_DEVICE_HIP) mark_as_advanced(CYCLES_HIP_BINARIES_ARCH) endif() diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 9c1cb0a1b4a..62d5ce8a572 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1671,10 +1671,10 @@ class CyclesPreferences(bpy.types.AddonPreferences): elif device_type == 'HIP': import sys if sys.platform[:3] == "win": - col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1') + col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1') col.label(text="and AMD Radeon Pro 21.Q4 driver or newer", icon='BLANK1') elif sys.platform.startswith("linux"): - col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1') + col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1') col.label(text="and AMD driver version 22.10 or newer", icon='BLANK1') elif device_type == 'ONEAPI': import sys diff --git a/intern/cycles/device/hip/util.h b/intern/cycles/device/hip/util.h index 4e4906171d1..c8b4b67ded8 100644 --- a/intern/cycles/device/hip/util.h +++ b/intern/cycles/device/hip/util.h @@ -51,7 +51,7 @@ static inline bool hipSupportsDevice(const int hipDevId) hipDeviceGetAttribute(&major, hipDeviceAttributeComputeCapabilityMajor, hipDevId); hipDeviceGetAttribute(&minor, hipDeviceAttributeComputeCapabilityMinor, hipDevId); - return (major >= 9); + return (major >= 10); } CCL_NAMESPACE_END From 0ba5954bb27b4fee5d0ed1a14feb91118b6f3fad Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Mon, 23 Jan 2023 17:32:22 +0100 Subject: [PATCH 0878/1522] Fix T103635: Fix failing EEVEE and OCIO shader compilations in Metal. Affecting render output preview when tone mapping is used, and EEVEE scenes such as Mr Elephant rendering in pink due to missing shaders. Authored by Apple: Michael Parkin-White Ref T103635 Ref T96261 Reviewed By: fclem Maniphest Tasks: T103635, T96261 Differential Revision: https://developer.blender.org/D16923 --- .../common/gpu_shader_common_color_utils.glsl | 8 ++-- .../gpu/shaders/metal/mtl_shader_defines.msl | 37 +------------------ 2 files changed, 6 insertions(+), 39 deletions(-) diff --git a/source/blender/gpu/shaders/common/gpu_shader_common_color_utils.glsl b/source/blender/gpu/shaders/common/gpu_shader_common_color_utils.glsl index 33108d3a989..9e8a40fa41a 100644 --- a/source/blender/gpu/shaders/common/gpu_shader_common_color_utils.glsl +++ b/source/blender/gpu/shaders/common/gpu_shader_common_color_utils.glsl @@ -146,7 +146,7 @@ void ycca_to_rgba_itu_601(vec4 ycca, out vec4 color) { ycca.xyz *= 255.0; ycca.xyz -= vec3(16.0, 128.0, 128.0); - color.rgb = mat3(vec3(1.164), 0.0, -0.392, 2.017, 1.596, -0.813, 0.0) * ycca.xyz; + color.rgb = mat3(1.164, 1.164, 1.164, 0.0, -0.392, 2.017, 1.596, -0.813, 0.0) * ycca.xyz; color.rgb /= 255.0; color.a = ycca.a; } @@ -155,7 +155,7 @@ void ycca_to_rgba_itu_709(vec4 ycca, out vec4 color) { ycca.xyz *= 255.0; ycca.xyz -= vec3(16.0, 128.0, 128.0); - color.rgb = mat3(vec3(1.164), 0.0, -0.213, 2.115, 1.793, -0.534, 0.0) * ycca.xyz; + color.rgb = mat3(1.164, 1.164, 1.164, 0.0, -0.213, 2.115, 1.793, -0.534, 0.0) * ycca.xyz; color.rgb /= 255.0; color.a = ycca.a; } @@ -163,7 +163,7 @@ void ycca_to_rgba_itu_709(vec4 ycca, out vec4 color) void ycca_to_rgba_jpeg(vec4 ycca, out vec4 color) { ycca.xyz *= 255.0; - color.rgb = mat3(vec3(1.0), 0.0, -0.34414, 1.772, 1.402, -0.71414, 0.0) * ycca.xyz; + color.rgb = mat3(1.0, 1.0, 1.0, 0.0, -0.34414, 1.772, 1.402, -0.71414, 0.0) * ycca.xyz; color.rgb += vec3(-179.456, 135.45984, -226.816); color.rgb /= 255.0; color.a = ycca.a; @@ -203,7 +203,7 @@ void rgba_to_ycca_jpeg(vec4 rgba, out vec4 ycca) void yuva_to_rgba_itu_709(vec4 yuva, out vec4 color) { - color.rgb = mat3(vec3(1.0), 0.0, -0.21482, 2.12798, 1.28033, -0.38059, 0.0) * yuva.xyz; + color.rgb = mat3(1.0, 1.0, 1.0, 0.0, -0.21482, 2.12798, 1.28033, -0.38059, 0.0) * yuva.xyz; color.a = yuva.a; } diff --git a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl index f1a8af63d72..69202a7a70e 100644 --- a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl +++ b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl @@ -210,7 +210,7 @@ template inline vec _texelFetch_internal(thread _mtl_combined_image_sampler_1d tex, T texel, uint lod, - T offset = 0) + T offset) { float w = tex.texture->get_width(); if ((texel + offset) >= 0 && (texel + offset) < w) { @@ -222,38 +222,6 @@ inline vec _texelFetch_internal(thread _mtl_combined_image_sampler_1d -inline vec _texelFetch_internal(thread _mtl_combined_image_sampler_1d tex, - vec texel, - uint lod, - vec offset = 0) -{ - float w = tex.texture->get_width(); - if ((texel + offset) >= 0 && (texel + offset) < w) { - /* LODs not supported for 1d textures. This must be zero. */ - return tex.texture->read(uint(texel + offset), 0); - } - else { - return vec(0); - } -} - -template -inline vec _texelFetch_internal(thread _mtl_combined_image_sampler_1d tex, - vec texel, - uint lod, - vec offset = vec(0)) -{ - float w = tex.texture->get_width(); - if ((texel.x + offset.x) >= 0 && (texel.x + offset.x) < w) { - /* LODs not supported for 1d textures. This must be zero. */ - return tex.texture->read(uint(texel.x + offset.x), 0); - } - else { - return vec(0); - } -} - template inline vec _texelFetch_internal(thread _mtl_combined_image_sampler_1d_array tex, vec texel, @@ -1236,8 +1204,7 @@ mat3 MAT3x3( { return mat3(vec3(a1, a2, a3), vec3(b1, b2, b3), vec3(c1, c2, c3)); } -mat3 MAT3x3( - vec3 a, float b1, float b2, float b3, float c1, float c2, float c3) +mat3 MAT3x3(vec3 a, float b1, float b2, float b3, float c1, float c2, float c3) { return mat3(a, vec3(b1, b2, b3), vec3(c1, c2, c3)); } From 1c672f3d1dae4f79d327c0fd38c440f3bf23d35c Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Mon, 23 Jan 2023 17:40:44 +0100 Subject: [PATCH 0879/1522] Fix T103433: Ensure Metal memory allocator is safe for multi-threaded allocation. Resolves crash when baking indirect lighting. Also applies correct texture usage flag to light bake texture. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem, jbakker Maniphest Tasks: T96261, T103433 Differential Revision: https://developer.blender.org/D17018 --- .../draw/engines/eevee/eevee_lightcache.c | 3 ++- source/blender/gpu/metal/mtl_memory.hh | 12 ++++++++---- source/blender/gpu/metal/mtl_memory.mm | 17 +++++++++++++++-- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index eead1a39ea2..b3b4b5a6dec 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -716,7 +716,8 @@ static void eevee_lightbake_create_resources(EEVEE_LightBake *lbake) lbake->irr_size[1], lbake->irr_size[2], IRRADIANCE_FORMAT, - GPU_TEXTURE_USAGE_SHADER_READ, + GPU_TEXTURE_USAGE_SHADER_READ | + GPU_TEXTURE_USAGE_ATTACHMENT, DRW_TEX_FILTER, NULL); diff --git a/source/blender/gpu/metal/mtl_memory.hh b/source/blender/gpu/metal/mtl_memory.hh index bd354376b12..cce5edeafef 100644 --- a/source/blender/gpu/metal/mtl_memory.hh +++ b/source/blender/gpu/metal/mtl_memory.hh @@ -339,10 +339,10 @@ class MTLSafeFreeList { class MTLBufferPool { private: - /* Memory statistics. */ - int64_t total_allocation_bytes_ = 0; - #if MTL_DEBUG_MEMORY_STATISTICS == 1 + /* Memory statistics. */ + std::atomic total_allocation_bytes_; + /* Debug statistics. */ std::atomic per_frame_allocation_count_; std::atomic allocations_in_pool_; @@ -368,10 +368,14 @@ class MTLBufferPool { * - A size-ordered list (MultiSet) of allocated buffers is kept per MTLResourceOptions * permutation. This allows efficient lookup for buffers of a given requested size. * - MTLBufferHandle wraps a gpu::MTLBuffer pointer to achieve easy size-based sorting - * via CompareMTLBuffer. */ + * via CompareMTLBuffer. + * + * NOTE: buffer_pool_lock_ guards against concurrent access to the memory allocator. This + * can occur during light baking or rendering operations. */ using MTLBufferPoolOrderedList = std::multiset; using MTLBufferResourceOptions = uint64_t; + std::mutex buffer_pool_lock_; blender::Map buffer_pools_; blender::Vector allocations_; diff --git a/source/blender/gpu/metal/mtl_memory.mm b/source/blender/gpu/metal/mtl_memory.mm index a7717bfef89..101dee2794e 100644 --- a/source/blender/gpu/metal/mtl_memory.mm +++ b/source/blender/gpu/metal/mtl_memory.mm @@ -25,6 +25,7 @@ void MTLBufferPool::init(id mtl_device) #if MTL_DEBUG_MEMORY_STATISTICS == 1 /* Debug statistics. */ + total_allocation_bytes_ = 0; per_frame_allocation_count_ = 0; allocations_in_pool_ = 0; buffers_in_pool_ = 0; @@ -43,7 +44,7 @@ MTLBufferPool::~MTLBufferPool() void MTLBufferPool::free() { - + buffer_pool_lock_.lock(); for (auto buffer : allocations_) { BLI_assert(buffer); delete buffer; @@ -55,6 +56,7 @@ void MTLBufferPool::free() delete buffer_pool; } buffer_pools_.clear(); + buffer_pool_lock_.unlock(); } gpu::MTLBuffer *MTLBufferPool::allocate(uint64_t size, bool cpu_visible) @@ -96,6 +98,8 @@ gpu::MTLBuffer *MTLBufferPool::allocate_aligned(uint64_t size, /* Check if we have a suitable buffer */ gpu::MTLBuffer *new_buffer = nullptr; + buffer_pool_lock_.lock(); + std::multiset **pool_search = buffer_pools_.lookup_ptr( (uint64_t)options); @@ -142,7 +146,9 @@ gpu::MTLBuffer *MTLBufferPool::allocate_aligned(uint64_t size, /* Track allocation in context. */ allocations_.append(new_buffer); +#if MTL_DEBUG_MEMORY_STATISTICS == 1 total_allocation_bytes_ += aligned_alloc_size; +#endif } else { /* Re-use suitable buffer. */ @@ -165,6 +171,9 @@ gpu::MTLBuffer *MTLBufferPool::allocate_aligned(uint64_t size, per_frame_allocation_count_++; #endif + /* Release lock. */ + buffer_pool_lock_.unlock(); + return new_buffer; } @@ -209,8 +218,11 @@ void MTLBufferPool::update_memory_pools() { /* Ensure thread-safe access to `completed_safelist_queue_`, which contains * the list of MTLSafeFreeList's whose buffers are ready to be - * re-inserted into the Memory Manager pools. */ + * re-inserted into the Memory Manager pools. + * we also need to lock access to general buffer pools, to ensure allocations + * are not simultaneously happening on background threads. */ safelist_lock_.lock(); + buffer_pool_lock_.lock(); #if MTL_DEBUG_MEMORY_STATISTICS == 1 int num_buffers_added = 0; @@ -302,6 +314,7 @@ void MTLBufferPool::update_memory_pools() /* Clear safe pools list */ completed_safelist_queue_.clear(); + buffer_pool_lock_.unlock(); safelist_lock_.unlock(); } From 139fb38d4fb4317a467a0abd28557f1713eb15af Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Mon, 23 Jan 2023 17:46:28 +0100 Subject: [PATCH 0880/1522] DRW: Add texture usage host read to Lightcache texture. Required by Metal backend to have correct usage flags for textures which are read by host. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D17020 --- source/blender/draw/engines/eevee/eevee_lightcache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/engines/eevee/eevee_lightcache.c b/source/blender/draw/engines/eevee/eevee_lightcache.c index b3b4b5a6dec..b28189973da 100644 --- a/source/blender/draw/engines/eevee/eevee_lightcache.c +++ b/source/blender/draw/engines/eevee/eevee_lightcache.c @@ -395,7 +395,8 @@ static bool eevee_lightcache_static_load(LightCache *lcache) } if (lcache->grid_tx.tex == NULL) { - eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT; + eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT | + GPU_TEXTURE_USAGE_HOST_READ; lcache->grid_tx.tex = GPU_texture_create_2d_array_ex("lightcache_irradiance", UNPACK3(lcache->grid_tx.tex_size), 1, From 84c25fdcaa42ae1ac7a937d4021095273f08603d Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Mon, 23 Jan 2023 17:47:11 +0100 Subject: [PATCH 0881/1522] Metal: Improve command buffer handling and workload scheduling. Improve handling for cases where maximum in-flight command buffer count is exceeded. This can occur during light-baking operations. Ensures the application handles this gracefully and also improves workload pipelining by situationally stalling until GPU work has completed, if too much work is queued up. This may have a tangible benefit for T103742 by ensuring Blender does not queue up too much GPU work. Authored by Apple: Michael Parkin-White Ref T96261 Ref T103742 Depends on D17018 Reviewed By: fclem Maniphest Tasks: T103742, T96261 Differential Revision: https://developer.blender.org/D17019 --- intern/ghost/intern/GHOST_ContextCGL.h | 16 +++++++++++ intern/ghost/intern/GHOST_ContextCGL.mm | 3 ++- source/blender/editors/screen/glutil.c | 5 +++- .../blender/gpu/metal/mtl_command_buffer.mm | 27 ++++++++++++++++--- source/blender/gpu/metal/mtl_common.hh | 1 - 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h index d19fffffb43..60098c99fe3 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.h +++ b/intern/ghost/intern/GHOST_ContextCGL.h @@ -23,6 +23,22 @@ @class NSView; class GHOST_ContextCGL : public GHOST_Context { + + public: + /* Defines the number of simultaneous command buffers which can be in flight. + * The default limit of `64` is considered to be optimal for Blender. Too many command buffers + * will result in workload fragmnetation and additional system-level overhead. This limit should + * also only be increased if the application is consistently exceeding the limit, and there are + * no command buffer leaks. + * + * If this limit is reached, starting a new command buffer will fail. The Metal backend will + * therefore stall until completion and log a warning when this limit is reached in order to + * ensure correct function of the app. + * + * It is generally preferable to reduce the prevalence of GPU_flush or GPU Context switches + * (which will both break command submissions), rather than increasing this limit. */ + static const int max_command_buffer_count = 64; + public: /** * Constructor. diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm index 9dad337a5d6..1aa0cb9def4 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.mm +++ b/intern/ghost/intern/GHOST_ContextCGL.mm @@ -529,7 +529,8 @@ void GHOST_ContextCGL::metalInit() id device = m_metalLayer.device; /* Create a command queue for blit/present operation. */ - m_metalCmdQueue = (MTLCommandQueue *)[device newCommandQueue]; + m_metalCmdQueue = (MTLCommandQueue *)[device + newCommandQueueWithMaxCommandBufferCount:GHOST_ContextCGL::max_command_buffer_count]; [m_metalCmdQueue retain]; /* Create shaders for blit operation. */ diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 4382fd3d1c2..dc5a9885e16 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -26,6 +26,7 @@ #include "GPU_texture.h" #ifdef __APPLE__ +# include "GPU_context.h" # include "GPU_state.h" #endif @@ -281,7 +282,9 @@ void immDrawPixelsTexTiled_scaling_clipping(IMMDrawPixelsTexState *state, * This doesn't seem to be too slow, * but still would be nice to have fast and nice solution. */ #ifdef __APPLE__ - GPU_flush(); + if (GPU_type_matches_ex(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL)) { + GPU_flush(); + } #endif } } diff --git a/source/blender/gpu/metal/mtl_command_buffer.mm b/source/blender/gpu/metal/mtl_command_buffer.mm index b78540241ad..d9dd14392c9 100644 --- a/source/blender/gpu/metal/mtl_command_buffer.mm +++ b/source/blender/gpu/metal/mtl_command_buffer.mm @@ -8,6 +8,8 @@ #include "mtl_debug.hh" #include "mtl_framebuffer.hh" +#include "intern/GHOST_ContextCGL.h" + #include using namespace blender; @@ -45,9 +47,15 @@ id MTLCommandBufferManager::ensure_begin() if (active_command_buffer_ == nil) { /* Verify number of active command buffers is below limit. - * Exceeding this limit will mean we either have a leak/GPU hang - * or we should increase the command buffer limit during MTLQueue creation */ - BLI_assert(MTLCommandBufferManager::num_active_cmd_bufs < MTL_MAX_COMMAND_BUFFERS); + * Exceeding this limit will mean we either have a command buffer leak/GPU hang + * or we should increase the command buffer limit during MTLQueue creation. + * Excessive command buffers can also be caused by frequent GPUContext switches, which cause + * the GPU pipeline to flush. This is common during indirect light baking operations. + * + * NOTE: We currently stall until completion of GPU work upon ::submit if we have reached the + * in-flight command buffer limit. */ + BLI_assert(MTLCommandBufferManager::num_active_cmd_bufs < + GHOST_ContextCGL::max_command_buffer_count); if (G.debug & G_DEBUG_GPU) { /* Debug: Enable Advanced Errors for GPU work execution. */ @@ -137,6 +145,19 @@ bool MTLCommandBufferManager::submit(bool wait) /* Submit command buffer to GPU. */ [active_command_buffer_ commit]; + /* If we have too many active command buffers in flight, wait until completed to avoid running + * out. We can increase */ + if (MTLCommandBufferManager::num_active_cmd_bufs >= + (GHOST_ContextCGL::max_command_buffer_count - 1)) { + wait = true; + MTL_LOG_WARNING( + "Maximum number of command buffers in flight. Host will wait until GPU work has " + "completed. Consider increasing GHOST_ContextCGL::max_command_buffer_count or reducing " + "work fragmentation to better utilise system hardware. Command buffers are flushed upon " + "GPUContext switches, this is the most common cause of excessive command buffer " + "generation.\n"); + } + if (wait || (G.debug & G_DEBUG_GPU)) { /* Wait until current GPU work has finished executing. */ [active_command_buffer_ waitUntilCompleted]; diff --git a/source/blender/gpu/metal/mtl_common.hh b/source/blender/gpu/metal/mtl_common.hh index 5c322efa3f9..8fa3be16556 100644 --- a/source/blender/gpu/metal/mtl_common.hh +++ b/source/blender/gpu/metal/mtl_common.hh @@ -9,7 +9,6 @@ #define MTL_MAX_DRAWABLES 3 #define MTL_MAX_SET_BYTES_SIZE 4096 #define MTL_FORCE_WAIT_IDLE 0 -#define MTL_MAX_COMMAND_BUFFERS 64 /* Number of frames for which we retain in-flight resources such as scratch buffers. * Set as number of GPU frames in flight, plus an additional value for extra possible CPU frame. */ From ba982119cdcacfa8e603457face1d8ebc763ef75 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Mon, 23 Jan 2023 17:59:07 +0100 Subject: [PATCH 0882/1522] Workbench Next MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrite of the Workbench engine using C++ and the new Draw Manager API. The new engine can be enabled in Blender `Preferences > Experimental > Workbench Next`. After that, the engine can be selected in `Properties > Scene > Render Engine`. When `Workbench Next` is the active engine, it also handles the `Solid` viewport mode rendering. The rewrite aims to be functionally equivalent to the current Workbench engine, but it also includes some small fixes/tweaks: - `In Front` rendered objects now work correctly with DoF and Shadows. - The `Sampling > Viewport` setting is actually used when the viewport is in `Render Mode`. - In `Texture` mode, textured materials also use the material properties. (Previously, only non textured materials would) To do: - Sculpt PBVH. - Volume rendering. - Hair rendering. - Use the "no_geom" shader versions for shadow rendering. - Decide the final API for custom visibility culling (Needed for shadows). - Profile/optimize. Known Issues: - Matcaps are not loaded until they’re shown elsewhere. (e.g. when opening the `Viewort Shading` UI) - Outlines are drawn between different materials of the same object. (Each material submesh has its own object handle) Reviewed By: fclem Maniphest Tasks: T101619 Differential Revision: https://developer.blender.org/D16826 --- .../startup/bl_ui/properties_data_armature.py | 2 +- .../startup/bl_ui/properties_data_bone.py | 2 +- .../startup/bl_ui/properties_data_camera.py | 30 +- .../startup/bl_ui/properties_data_curve.py | 4 +- .../startup/bl_ui/properties_data_curves.py | 8 +- .../startup/bl_ui/properties_data_lattice.py | 2 +- .../startup/bl_ui/properties_data_light.py | 8 +- .../startup/bl_ui/properties_data_mesh.py | 24 +- .../startup/bl_ui/properties_data_metaball.py | 4 +- .../bl_ui/properties_data_pointcloud.py | 6 +- .../startup/bl_ui/properties_data_speaker.py | 10 +- .../startup/bl_ui/properties_data_volume.py | 14 +- .../startup/bl_ui/properties_freestyle.py | 22 +- .../startup/bl_ui/properties_material.py | 4 +- .../bl_ui/properties_material_gpencil.py | 2 +- .../startup/bl_ui/properties_object.py | 4 +- .../startup/bl_ui/properties_output.py | 28 +- .../startup/bl_ui/properties_particle.py | 102 +-- .../startup/bl_ui/properties_physics_cloth.py | 26 +- .../bl_ui/properties_physics_common.py | 2 +- .../bl_ui/properties_physics_dynamicpaint.py | 42 +- .../startup/bl_ui/properties_physics_field.py | 20 +- .../startup/bl_ui/properties_physics_fluid.py | 44 +- .../bl_ui/properties_physics_rigidbody.py | 16 +- ...properties_physics_rigidbody_constraint.py | 26 +- .../bl_ui/properties_physics_softbody.py | 30 +- .../startup/bl_ui/properties_render.py | 26 +- .../startup/bl_ui/properties_texture.py | 42 +- .../startup/bl_ui/properties_view_layer.py | 21 +- .../scripts/startup/bl_ui/properties_world.py | 4 +- release/scripts/startup/bl_ui/space_node.py | 2 +- .../scripts/startup/bl_ui/space_sequencer.py | 2 +- .../scripts/startup/bl_ui/space_userpref.py | 1 + source/blender/blenkernel/intern/scene.cc | 4 +- source/blender/draw/CMakeLists.txt | 21 + .../shaders/infos/workbench_composite_info.hh | 85 +- .../infos/workbench_effect_cavity_info.hh | 2 +- .../infos/workbench_effect_outline_info.hh | 2 +- .../infos/workbench_merge_infront_info.hh | 7 + .../shaders/infos/workbench_prepass_info.hh | 140 +++- .../shaders/infos/workbench_shadow_info.hh | 94 ++- .../shaders/workbench_cavity_lib.glsl | 6 + .../shaders/workbench_composite_frag.glsl | 6 +- .../shaders/workbench_curvature_lib.glsl | 4 + .../shaders/workbench_image_lib.glsl | 27 +- .../shaders/workbench_matcap_lib.glsl | 11 + .../shaders/workbench_material_lib.glsl | 22 +- .../workbench_next_composite_frag.glsl | 81 ++ .../workbench_next_merge_depth_frag.glsl | 11 + .../shaders/workbench_prepass_frag.glsl | 37 +- .../shaders/workbench_prepass_hair_vert.glsl | 11 +- .../workbench_prepass_pointcloud_vert.glsl | 7 +- .../shaders/workbench_prepass_vert.glsl | 7 +- .../shaders/workbench_shadow_vert.glsl | 16 +- .../workbench_shadow_visibility_comp.glsl | 93 +++ .../workbench_transparent_accum_frag.glsl | 66 +- .../engines/workbench/workbench_defines.hh | 10 + .../workbench_effect_antialiasing.cc | 311 ++++++++ .../workbench/workbench_effect_cavity.cc | 89 +++ .../engines/workbench/workbench_effect_dof.cc | 271 +++++++ .../workbench/workbench_effect_outline.cc | 52 ++ .../engines/workbench/workbench_engine.cc | 737 ++++++++++++++++++ .../draw/engines/workbench/workbench_engine.h | 1 + .../draw/engines/workbench/workbench_enums.hh | 96 +++ .../workbench/workbench_materials_next.cc | 95 +++ .../workbench/workbench_mesh_passes.cc | 406 ++++++++++ .../engines/workbench/workbench_private.h | 6 +- .../engines/workbench/workbench_private.hh | 436 +++++++++++ .../engines/workbench/workbench_resources.cc | 171 ++++ .../workbench/workbench_shader_cache.cc | 132 ++++ .../workbench/workbench_shader_shared.h | 22 +- .../engines/workbench/workbench_shadow.cc | 461 +++++++++++ .../draw/engines/workbench/workbench_state.cc | 301 +++++++ source/blender/draw/intern/DRW_gpu_wrapper.hh | 10 + source/blender/draw/intern/draw_manager.c | 8 + source/blender/draw/intern/draw_manager.cc | 9 +- source/blender/draw/intern/draw_pass.hh | 7 + source/blender/draw/intern/draw_view.cc | 13 + source/blender/draw/intern/draw_view.hh | 15 +- .../draw/intern/shaders/draw_view_info.hh | 3 + source/blender/draw/intern/smaa_textures.h | 9 + source/blender/editors/include/ED_view3d.h | 22 +- .../editors/space_view3d/view3d_utils.c | 2 +- source/blender/gpu/CMakeLists.txt | 1 + .../blender/gpu/intern/gpu_texture_private.hh | 2 +- source/blender/makesdna/DNA_scene_types.h | 1 + source/blender/makesdna/DNA_userdef_types.h | 4 +- source/blender/makesrna/intern/rna_space.c | 2 +- source/blender/makesrna/intern/rna_userdef.c | 7 + 89 files changed, 4657 insertions(+), 395 deletions(-) create mode 100644 source/blender/draw/engines/workbench/shaders/workbench_next_composite_frag.glsl create mode 100644 source/blender/draw/engines/workbench/shaders/workbench_next_merge_depth_frag.glsl create mode 100644 source/blender/draw/engines/workbench/shaders/workbench_shadow_visibility_comp.glsl create mode 100644 source/blender/draw/engines/workbench/workbench_defines.hh create mode 100644 source/blender/draw/engines/workbench/workbench_effect_antialiasing.cc create mode 100644 source/blender/draw/engines/workbench/workbench_effect_cavity.cc create mode 100644 source/blender/draw/engines/workbench/workbench_effect_dof.cc create mode 100644 source/blender/draw/engines/workbench/workbench_effect_outline.cc create mode 100644 source/blender/draw/engines/workbench/workbench_engine.cc create mode 100644 source/blender/draw/engines/workbench/workbench_enums.hh create mode 100644 source/blender/draw/engines/workbench/workbench_materials_next.cc create mode 100644 source/blender/draw/engines/workbench/workbench_mesh_passes.cc create mode 100644 source/blender/draw/engines/workbench/workbench_private.hh create mode 100644 source/blender/draw/engines/workbench/workbench_resources.cc create mode 100644 source/blender/draw/engines/workbench/workbench_shader_cache.cc create mode 100644 source/blender/draw/engines/workbench/workbench_shadow.cc create mode 100644 source/blender/draw/engines/workbench/workbench_state.cc diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index d1a6c0165e0..aefcb53fb56 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -248,7 +248,7 @@ class DATA_PT_motion_paths_display(MotionPathButtonsPanel_display, Panel): class DATA_PT_custom_props_arm(ArmatureButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Armature diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index 14f6da83be2..465a1854528 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -444,7 +444,7 @@ class BONE_PT_deform(BoneButtonsPanel, Panel): class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _property_type = bpy.types.Bone, bpy.types.EditBone, bpy.types.PoseBone @property diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 0a9a16999b8..6ecfa9dfbb4 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -21,7 +21,7 @@ class CAMERA_PT_presets(PresetPanel, Panel): preset_subdir = "camera" preset_operator = "script.execute_preset" preset_add_operator = "camera.preset_add" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} class CAMERA_PT_safe_areas_presets(PresetPanel, Panel): @@ -29,13 +29,13 @@ class CAMERA_PT_safe_areas_presets(PresetPanel, Panel): preset_subdir = "safe_areas" preset_operator = "script.execute_preset" preset_add_operator = "camera.safe_areas_preset_add" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} class DATA_PT_context_camera(CameraButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -52,7 +52,7 @@ class DATA_PT_context_camera(CameraButtonsPanel, Panel): class DATA_PT_lens(CameraButtonsPanel, Panel): bl_label = "Lens" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -100,7 +100,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): col.prop(ccam, "fisheye_polynomial_k3", text="K3") col.prop(ccam, "fisheye_polynomial_k4", text="K4") - elif engine in {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'}: + elif engine in {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}: if cam.lens_unit == 'MILLIMETERS': col.prop(cam, "lens") elif cam.lens_unit == 'FOV': @@ -122,7 +122,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): bl_label = "Stereoscopy" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -171,7 +171,7 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): class DATA_PT_camera(CameraButtonsPanel, Panel): bl_label = "Camera" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header_preset(self, _context): CAMERA_PT_presets.draw_panel_header(self.layout) @@ -201,7 +201,7 @@ class DATA_PT_camera(CameraButtonsPanel, Panel): class DATA_PT_camera_dof(CameraButtonsPanel, Panel): bl_label = "Depth of Field" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cam = context.camera @@ -228,7 +228,7 @@ class DATA_PT_camera_dof(CameraButtonsPanel, Panel): class DATA_PT_camera_dof_aperture(CameraButtonsPanel, Panel): bl_label = "Aperture" bl_parent_id = "DATA_PT_camera_dof" - COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -252,7 +252,7 @@ class DATA_PT_camera_dof_aperture(CameraButtonsPanel, Panel): class DATA_PT_camera_background_image(CameraButtonsPanel, Panel): bl_label = "Background Images" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cam = context.camera @@ -359,7 +359,7 @@ class DATA_PT_camera_background_image(CameraButtonsPanel, Panel): class DATA_PT_camera_display(CameraButtonsPanel, Panel): bl_label = "Viewport Display" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -392,7 +392,7 @@ class DATA_PT_camera_display_composition_guides(CameraButtonsPanel, Panel): bl_label = "Composition Guides" bl_parent_id = "DATA_PT_camera_display" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -419,7 +419,7 @@ class DATA_PT_camera_display_composition_guides(CameraButtonsPanel, Panel): class DATA_PT_camera_safe_areas(CameraButtonsPanel, Panel): bl_label = "Safe Areas" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cam = context.camera @@ -449,7 +449,7 @@ class DATA_PT_camera_safe_areas_center_cut(CameraButtonsPanel, Panel): bl_label = "Center-Cut Safe Areas" bl_parent_id = "DATA_PT_camera_safe_areas" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cam = context.camera @@ -473,7 +473,7 @@ class DATA_PT_camera_safe_areas_center_cut(CameraButtonsPanel, Panel): class DATA_PT_custom_props_camera(CameraButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Camera diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index 88dd3caaa74..fc02d15d267 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -116,7 +116,7 @@ class DATA_PT_shape_curve(CurveButtonsPanel, Panel): class DATA_PT_curve_texture_space(CurveButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -475,7 +475,7 @@ class DATA_PT_text_boxes(CurveButtonsPanelText, Panel): class DATA_PT_custom_props_curve(CurveButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Curve diff --git a/release/scripts/startup/bl_ui/properties_data_curves.py b/release/scripts/startup/bl_ui/properties_data_curves.py index e17d749acd5..99f5bc2e33e 100644 --- a/release/scripts/startup/bl_ui/properties_data_curves.py +++ b/release/scripts/startup/bl_ui/properties_data_curves.py @@ -18,7 +18,7 @@ class DataButtonsPanel: class DATA_PT_context_curves(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -35,7 +35,7 @@ class DATA_PT_context_curves(DataButtonsPanel, Panel): class DATA_PT_curves_surface(DataButtonsPanel, Panel): bl_label = "Surface" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -118,7 +118,7 @@ class CURVES_UL_attributes(UIList): class DATA_PT_CURVES_attributes(DataButtonsPanel, Panel): bl_label = "Attributes" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): curves = context.curves @@ -143,7 +143,7 @@ class DATA_PT_CURVES_attributes(DataButtonsPanel, Panel): class DATA_PT_custom_props_curves(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Curves if hasattr(bpy.types, "Curves") else None diff --git a/release/scripts/startup/bl_ui/properties_data_lattice.py b/release/scripts/startup/bl_ui/properties_data_lattice.py index e57b46989fe..acd83b08c6a 100644 --- a/release/scripts/startup/bl_ui/properties_data_lattice.py +++ b/release/scripts/startup/bl_ui/properties_data_lattice.py @@ -64,7 +64,7 @@ class DATA_PT_lattice(DataButtonsPanel, Panel): class DATA_PT_custom_props_lattice(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Lattice diff --git a/release/scripts/startup/bl_ui/properties_data_light.py b/release/scripts/startup/bl_ui/properties_data_light.py index b313ae4dcb9..1e8baca3c24 100644 --- a/release/scripts/startup/bl_ui/properties_data_light.py +++ b/release/scripts/startup/bl_ui/properties_data_light.py @@ -18,7 +18,7 @@ class DataButtonsPanel: class DATA_PT_context_light(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -44,7 +44,7 @@ class DATA_PT_preview(DataButtonsPanel, Panel): class DATA_PT_light(DataButtonsPanel, Panel): bl_label = "Light" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -230,7 +230,7 @@ class DATA_PT_EEVEE_shadow_contact(DataButtonsPanel, Panel): class DATA_PT_spot(DataButtonsPanel, Panel): bl_label = "Spot Shape" bl_parent_id = "DATA_PT_EEVEE_light" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -275,7 +275,7 @@ class DATA_PT_falloff_curve(DataButtonsPanel, Panel): class DATA_PT_custom_props_light(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Light diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 61027f68f19..714dcca9673 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -171,7 +171,7 @@ class MeshButtonsPanel: class DATA_PT_context_mesh(MeshButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -189,7 +189,7 @@ class DATA_PT_context_mesh(MeshButtonsPanel, Panel): class DATA_PT_normals(MeshButtonsPanel, Panel): bl_label = "Normals" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -211,7 +211,7 @@ class DATA_PT_normals(MeshButtonsPanel, Panel): class DATA_PT_texture_space(MeshButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -231,7 +231,7 @@ class DATA_PT_texture_space(MeshButtonsPanel, Panel): class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): bl_label = "Vertex Groups" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -288,7 +288,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): class DATA_PT_face_maps(MeshButtonsPanel, Panel): bl_label = "Face Maps" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -331,7 +331,7 @@ class DATA_PT_face_maps(MeshButtonsPanel, Panel): class DATA_PT_shape_keys(MeshButtonsPanel, Panel): bl_label = "Shape Keys" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -428,7 +428,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel): class DATA_PT_uv_texture(MeshButtonsPanel, Panel): bl_label = "UV Maps" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -448,7 +448,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel): class DATA_PT_remesh(MeshButtonsPanel, Panel): bl_label = "Remesh" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -478,7 +478,7 @@ class DATA_PT_remesh(MeshButtonsPanel, Panel): class DATA_PT_customdata(MeshButtonsPanel, Panel): bl_label = "Geometry Data" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -519,7 +519,7 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel): class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Mesh @@ -568,7 +568,7 @@ class MESH_UL_attributes(UIList): class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel): bl_label = "Attributes" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): mesh = context.mesh @@ -692,7 +692,7 @@ class MESH_UL_color_attributes_selector(UIList, ColorAttributesListBase): class DATA_PT_vertex_colors(DATA_PT_mesh_attributes, Panel): bl_label = "Color Attributes" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): mesh = context.mesh diff --git a/release/scripts/startup/bl_ui/properties_data_metaball.py b/release/scripts/startup/bl_ui/properties_data_metaball.py index eba5676535f..1493e6177a6 100644 --- a/release/scripts/startup/bl_ui/properties_data_metaball.py +++ b/release/scripts/startup/bl_ui/properties_data_metaball.py @@ -56,7 +56,7 @@ class DATA_PT_metaball(DataButtonsPanel, Panel): class DATA_PT_mball_texture_space(DataButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -111,7 +111,7 @@ class DATA_PT_metaball_element(DataButtonsPanel, Panel): class DATA_PT_custom_props_metaball(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.MetaBall diff --git a/release/scripts/startup/bl_ui/properties_data_pointcloud.py b/release/scripts/startup/bl_ui/properties_data_pointcloud.py index db1b83f0cf4..f83735ec3dd 100644 --- a/release/scripts/startup/bl_ui/properties_data_pointcloud.py +++ b/release/scripts/startup/bl_ui/properties_data_pointcloud.py @@ -18,7 +18,7 @@ class DataButtonsPanel: class DATA_PT_context_pointcloud(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -97,7 +97,7 @@ class POINTCLOUD_UL_attributes(UIList): class DATA_PT_pointcloud_attributes(DataButtonsPanel, Panel): bl_label = "Attributes" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): pointcloud = context.pointcloud @@ -122,7 +122,7 @@ class DATA_PT_pointcloud_attributes(DataButtonsPanel, Panel): class DATA_PT_custom_props_pointcloud(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.PointCloud if hasattr(bpy.types, "PointCloud") else None diff --git a/release/scripts/startup/bl_ui/properties_data_speaker.py b/release/scripts/startup/bl_ui/properties_data_speaker.py index 9bdf0e22c2f..4bdbc0ab7e3 100644 --- a/release/scripts/startup/bl_ui/properties_data_speaker.py +++ b/release/scripts/startup/bl_ui/properties_data_speaker.py @@ -18,7 +18,7 @@ class DataButtonsPanel: class DATA_PT_context_speaker(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -35,7 +35,7 @@ class DATA_PT_context_speaker(DataButtonsPanel, Panel): class DATA_PT_speaker(DataButtonsPanel, Panel): bl_label = "Sound" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -57,7 +57,7 @@ class DATA_PT_speaker(DataButtonsPanel, Panel): class DATA_PT_distance(DataButtonsPanel, Panel): bl_label = "Distance" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -81,7 +81,7 @@ class DATA_PT_distance(DataButtonsPanel, Panel): class DATA_PT_cone(DataButtonsPanel, Panel): bl_label = "Cone" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -103,7 +103,7 @@ class DATA_PT_cone(DataButtonsPanel, Panel): class DATA_PT_custom_props_speaker(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Speaker diff --git a/release/scripts/startup/bl_ui/properties_data_volume.py b/release/scripts/startup/bl_ui/properties_data_volume.py index 148bb60de85..f0c1d16b7fd 100644 --- a/release/scripts/startup/bl_ui/properties_data_volume.py +++ b/release/scripts/startup/bl_ui/properties_data_volume.py @@ -18,7 +18,7 @@ class DataButtonsPanel: class DATA_PT_context_volume(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -35,7 +35,7 @@ class DATA_PT_context_volume(DataButtonsPanel, Panel): class DATA_PT_volume_file(DataButtonsPanel, Panel): bl_label = "OpenVDB File" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -80,7 +80,7 @@ class VOLUME_UL_grids(UIList): class DATA_PT_volume_grids(DataButtonsPanel, Panel): bl_label = "Grids" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -93,7 +93,7 @@ class DATA_PT_volume_grids(DataButtonsPanel, Panel): class DATA_PT_volume_render(DataButtonsPanel, Panel): bl_label = "Render" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -125,7 +125,7 @@ class DATA_PT_volume_render(DataButtonsPanel, Panel): class DATA_PT_volume_viewport_display(DataButtonsPanel, Panel): bl_label = "Viewport Display" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -149,7 +149,7 @@ class DATA_PT_volume_viewport_display(DataButtonsPanel, Panel): class DATA_PT_volume_viewport_display_slicing(DataButtonsPanel, Panel): bl_label = "" bl_parent_id = 'DATA_PT_volume_viewport_display' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): layout = self.layout @@ -175,7 +175,7 @@ class DATA_PT_volume_viewport_display_slicing(DataButtonsPanel, Panel): class DATA_PT_custom_props_volume(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Volume diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py index e74e1725aa2..2b948765943 100644 --- a/release/scripts/startup/bl_ui/properties_freestyle.py +++ b/release/scripts/startup/bl_ui/properties_freestyle.py @@ -21,7 +21,7 @@ class RENDER_PT_freestyle(RenderFreestyleButtonsPanel, Panel): bl_label = "Freestyle" bl_options = {'DEFAULT_CLOSED'} bl_order = 10 - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): rd = context.scene.render @@ -79,7 +79,7 @@ class ViewLayerFreestyleEditorButtonsPanel(ViewLayerFreestyleButtonsPanel): class ViewLayerFreestyleLineStyle(ViewLayerFreestyleEditorButtonsPanel): # Freestyle Linestyle Panels - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -123,7 +123,7 @@ class RENDER_MT_lineset_context_menu(Menu): class VIEWLAYER_PT_freestyle(ViewLayerFreestyleButtonsPanel, Panel): bl_label = "Freestyle" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): view_layer = context.view_layer @@ -153,7 +153,7 @@ class VIEWLAYER_PT_freestyle(ViewLayerFreestyleButtonsPanel, Panel): class VIEWLAYER_PT_freestyle_edge_detection(ViewLayerFreestyleButtonsPanel, Panel): bl_label = "Edge Detection" bl_parent_id = "VIEWLAYER_PT_freestyle" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -183,7 +183,7 @@ class VIEWLAYER_PT_freestyle_edge_detection(ViewLayerFreestyleButtonsPanel, Pane class VIEWLAYER_PT_freestyle_style_modules(ViewLayerFreestyleButtonsPanel, Panel): bl_label = "Style Modules" bl_parent_id = "VIEWLAYER_PT_freestyle" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -219,7 +219,7 @@ class VIEWLAYER_PT_freestyle_style_modules(ViewLayerFreestyleButtonsPanel, Panel class VIEWLAYER_PT_freestyle_lineset(ViewLayerFreestyleEditorButtonsPanel, Panel): bl_label = "Freestyle Line Set" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_edge_type_buttons(self, box, lineset, edge_type): # property names @@ -282,7 +282,7 @@ class VIEWLAYER_PT_freestyle_lineset(ViewLayerFreestyleEditorButtonsPanel, Panel class VIEWLAYER_PT_freestyle_lineset_visibilty(ViewLayerFreestyleLineStyle, Panel): bl_label = "Visibility" bl_parent_id = "VIEWLAYER_PT_freestyle_lineset" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): layout = self.layout @@ -316,7 +316,7 @@ class VIEWLAYER_PT_freestyle_lineset_visibilty(ViewLayerFreestyleLineStyle, Pane class VIEWLAYER_PT_freestyle_lineset_edgetype(ViewLayerFreestyleLineStyle, Panel): bl_label = "Edge Type" bl_parent_id = "VIEWLAYER_PT_freestyle_lineset" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): layout = self.layout @@ -366,7 +366,7 @@ class VIEWLAYER_PT_freestyle_lineset_edgetype(ViewLayerFreestyleLineStyle, Panel class VIEWLAYER_PT_freestyle_lineset_facemarks(ViewLayerFreestyleLineStyle, Panel): bl_label = "Face Marks" bl_parent_id = "VIEWLAYER_PT_freestyle_lineset" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): @@ -395,7 +395,7 @@ class VIEWLAYER_PT_freestyle_lineset_facemarks(ViewLayerFreestyleLineStyle, Pane class VIEWLAYER_PT_freestyle_lineset_collection(ViewLayerFreestyleLineStyle, Panel): bl_label = "Collection" bl_parent_id = "VIEWLAYER_PT_freestyle_lineset" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): @@ -1236,7 +1236,7 @@ class MaterialFreestyleButtonsPanel: class MATERIAL_PT_freestyle_line(MaterialFreestyleButtonsPanel, Panel): bl_label = "Freestyle Line" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index afcd1b753d2..f9b9450277b 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -60,7 +60,7 @@ class MATERIAL_PT_preview(MaterialButtonsPanel, Panel): class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "material" _property_type = bpy.types.Material @@ -69,7 +69,7 @@ class EEVEE_MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): bl_label = "" bl_context = "material" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_material_gpencil.py b/release/scripts/startup/bl_ui/properties_material_gpencil.py index de1df732b7e..b0d717fa168 100644 --- a/release/scripts/startup/bl_ui/properties_material_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_material_gpencil.py @@ -228,7 +228,7 @@ class MATERIAL_PT_gpencil_preview(GPMaterialButtonsPanel, Panel): class MATERIAL_PT_gpencil_custom_props(GPMaterialButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "object.active_material" _property_type = bpy.types.Material diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index 7afa2f81b97..85a90d61aa8 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -366,7 +366,7 @@ class OBJECT_PT_motion_paths_display(MotionPathButtonsPanel_display, Panel): class OBJECT_PT_visibility(ObjectButtonsPanel, Panel): bl_label = "Visibility" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -395,7 +395,7 @@ class OBJECT_PT_visibility(ObjectButtonsPanel, Panel): class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "object" _property_type = bpy.types.Object diff --git a/release/scripts/startup/bl_ui/properties_output.py b/release/scripts/startup/bl_ui/properties_output.py index 00c81d0dc87..427eec67b98 100644 --- a/release/scripts/startup/bl_ui/properties_output.py +++ b/release/scripts/startup/bl_ui/properties_output.py @@ -42,7 +42,7 @@ class RenderOutputButtonsPanel: class RENDER_PT_format(RenderOutputButtonsPanel, Panel): bl_label = "Format" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _frame_rate_args_prev = None _preset_class = None @@ -120,7 +120,7 @@ class RENDER_PT_format(RenderOutputButtonsPanel, Panel): class RENDER_PT_frame_range(RenderOutputButtonsPanel, Panel): bl_label = "Frame Range" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -139,7 +139,7 @@ class RENDER_PT_time_stretching(RenderOutputButtonsPanel, Panel): bl_label = "Time Stretching" bl_parent_id = "RENDER_PT_frame_range" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -156,7 +156,7 @@ class RENDER_PT_time_stretching(RenderOutputButtonsPanel, Panel): class RENDER_PT_post_processing(RenderOutputButtonsPanel, Panel): bl_label = "Post Processing" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -174,7 +174,7 @@ class RENDER_PT_post_processing(RenderOutputButtonsPanel, Panel): class RENDER_PT_stamp(RenderOutputButtonsPanel, Panel): bl_label = "Metadata" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -208,7 +208,7 @@ class RENDER_PT_stamp_note(RenderOutputButtonsPanel, Panel): bl_label = "Note" bl_parent_id = "RENDER_PT_stamp" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): rd = context.scene.render @@ -228,7 +228,7 @@ class RENDER_PT_stamp_burn(RenderOutputButtonsPanel, Panel): bl_label = "Burn Into Image" bl_parent_id = "RENDER_PT_stamp" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): rd = context.scene.render @@ -252,7 +252,7 @@ class RENDER_PT_stamp_burn(RenderOutputButtonsPanel, Panel): class RENDER_PT_output(RenderOutputButtonsPanel, Panel): bl_label = "Output" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -281,7 +281,7 @@ class RENDER_PT_output(RenderOutputButtonsPanel, Panel): class RENDER_PT_output_views(RenderOutputButtonsPanel, Panel): bl_label = "Views" bl_parent_id = "RENDER_PT_output" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -301,7 +301,7 @@ class RENDER_PT_output_color_management(RenderOutputButtonsPanel, Panel): bl_label = "Color Management" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "RENDER_PT_output" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): scene = context.scene @@ -336,7 +336,7 @@ class RENDER_PT_encoding(RenderOutputButtonsPanel, Panel): bl_label = "Encoding" bl_parent_id = "RENDER_PT_output" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header_preset(self, _context): RENDER_PT_ffmpeg_presets.draw_panel_header(self.layout) @@ -361,7 +361,7 @@ class RENDER_PT_encoding(RenderOutputButtonsPanel, Panel): class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel): bl_label = "Video" bl_parent_id = "RENDER_PT_encoding" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -437,7 +437,7 @@ class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel): class RENDER_PT_encoding_audio(RenderOutputButtonsPanel, Panel): bl_label = "Audio" bl_parent_id = "RENDER_PT_encoding" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -479,7 +479,7 @@ class RENDER_UL_renderviews(UIList): class RENDER_PT_stereoscopy(RenderOutputButtonsPanel, Panel): bl_label = "Stereoscopy" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index 8464578ea25..bef8931c8ce 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -52,7 +52,7 @@ def particle_get_settings(context): class PARTICLE_MT_context_menu(Menu): bl_label = "Particle Specials" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -92,7 +92,7 @@ class PARTICLE_PT_hair_dynamics_presets(PresetPanel, Panel): preset_subdir = "hair_dynamics" preset_operator = "script.execute_preset" preset_add_operator = "particle.hair_dynamics_preset_add" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} class ParticleButtonsPanel: @@ -146,7 +146,7 @@ class PARTICLE_UL_particle_systems(bpy.types.UIList): class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -240,7 +240,7 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): class PARTICLE_PT_emission(ParticleButtonsPanel, Panel): bl_label = "Emission" bl_translation_context = i18n_contexts.id_particlesettings - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -292,7 +292,7 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel): bl_label = "Source" bl_parent_id = "PARTICLE_PT_emission" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -329,7 +329,7 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel): class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel): bl_label = "Hair Dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -412,7 +412,7 @@ class PARTICLE_PT_hair_dynamics_collision(ParticleButtonsPanel, Panel): bl_label = "Collisions" bl_parent_id = "PARTICLE_PT_hair_dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -444,7 +444,7 @@ class PARTICLE_PT_hair_dynamics_structure(ParticleButtonsPanel, Panel): bl_label = "Structure" bl_parent_id = "PARTICLE_PT_hair_dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -475,7 +475,7 @@ class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel): bl_label = "Volume" bl_parent_id = "PARTICLE_PT_hair_dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -506,7 +506,7 @@ class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel): class PARTICLE_PT_cache(ParticleButtonsPanel, Panel): bl_label = "Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -539,7 +539,7 @@ class PARTICLE_PT_cache(ParticleButtonsPanel, Panel): class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel): bl_label = "Velocity" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -588,7 +588,7 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel): class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel): bl_label = "Rotation" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -643,7 +643,7 @@ class PARTICLE_PT_rotation_angular_velocity(ParticleButtonsPanel, Panel): bl_label = "Angular Velocity" bl_parent_id = "PARTICLE_PT_rotation" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -668,7 +668,7 @@ class PARTICLE_PT_rotation_angular_velocity(ParticleButtonsPanel, Panel): class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): bl_label = "Physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -721,7 +721,7 @@ class PARTICLE_PT_physics_fluid_advanced(ParticleButtonsPanel, Panel): bl_label = "Advanced" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -766,7 +766,7 @@ class PARTICLE_PT_physics_fluid_springs(ParticleButtonsPanel, Panel): bl_label = "Springs" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -790,7 +790,7 @@ class PARTICLE_PT_physics_fluid_springs_viscoelastic(ParticleButtonsPanel, Panel bl_label = "Viscoelastic Springs" bl_parent_id = "PARTICLE_PT_physics_fluid_springs" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -826,7 +826,7 @@ class PARTICLE_PT_physics_fluid_springs_advanced(ParticleButtonsPanel, Panel): bl_label = "Advanced" bl_parent_id = "PARTICLE_PT_physics_fluid_springs" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -850,7 +850,7 @@ class PARTICLE_PT_physics_boids_movement(ParticleButtonsPanel, Panel): bl_label = "Movement" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -903,7 +903,7 @@ class PARTICLE_PT_physics_boids_battle(ParticleButtonsPanel, Panel): bl_label = "Battle" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -930,7 +930,7 @@ class PARTICLE_PT_physics_boids_misc(ParticleButtonsPanel, Panel): bl_label = "Misc" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -955,7 +955,7 @@ class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel): bl_label = "Relations" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1010,7 +1010,7 @@ class PARTICLE_PT_physics_fluid_interaction(ParticleButtonsPanel, Panel): bl_label = "Fluid Interaction" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1051,7 +1051,7 @@ class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel): bl_label = "Deflection" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1077,7 +1077,7 @@ class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel): class PARTICLE_PT_physics_forces(ParticleButtonsPanel, Panel): bl_label = "Forces" bl_parent_id = "PARTICLE_PT_physics" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1104,7 +1104,7 @@ class PARTICLE_PT_physics_integration(ParticleButtonsPanel, Panel): bl_label = "Integration" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_physics" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1138,7 +1138,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel): bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_physics" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1236,7 +1236,7 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel): class PARTICLE_PT_render(ParticleButtonsPanel, Panel): bl_label = "Render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1283,7 +1283,7 @@ class PARTICLE_PT_render_extra(ParticleButtonsPanel, Panel): bl_label = "Extra" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1307,7 +1307,7 @@ class PARTICLE_PT_render_extra(ParticleButtonsPanel, Panel): class PARTICLE_PT_render_path(ParticleButtonsPanel, Panel): bl_label = "Path" bl_parent_id = "PARTICLE_PT_render" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1329,7 +1329,7 @@ class PARTICLE_PT_render_path_timing(ParticleButtonsPanel, Panel): bl_label = "Timing" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1357,7 +1357,7 @@ class PARTICLE_PT_render_path_timing(ParticleButtonsPanel, Panel): class PARTICLE_PT_render_object(ParticleButtonsPanel, Panel): bl_label = "Object" bl_parent_id = "PARTICLE_PT_render" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1382,7 +1382,7 @@ class PARTICLE_PT_render_object(ParticleButtonsPanel, Panel): class PARTICLE_PT_render_collection(ParticleButtonsPanel, Panel): bl_label = "Collection" bl_parent_id = "PARTICLE_PT_render" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1412,7 +1412,7 @@ class PARTICLE_PT_render_collection_use_count(ParticleButtonsPanel, Panel): bl_label = "Use Count" bl_parent_id = "PARTICLE_PT_render_collection" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1460,7 +1460,7 @@ class PARTICLE_PT_render_collection_use_count(ParticleButtonsPanel, Panel): class PARTICLE_PT_draw(ParticleButtonsPanel, Panel): bl_label = "Viewport Display" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1519,7 +1519,7 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel): bl_label = "Children" bl_translation_context = i18n_contexts.id_particlesettings bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1572,7 +1572,7 @@ class PARTICLE_PT_children_parting(ParticleButtonsPanel, Panel): bl_label = "Parting" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1603,7 +1603,7 @@ class PARTICLE_PT_children_clumping(ParticleButtonsPanel, Panel): bl_label = "Clumping" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1639,7 +1639,7 @@ class PARTICLE_PT_children_clumping_noise(ParticleButtonsPanel, Panel): bl_label = "Clump Noise" bl_parent_id = "PARTICLE_PT_children_clumping" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): @@ -1663,7 +1663,7 @@ class PARTICLE_PT_children_roughness(ParticleButtonsPanel, Panel): bl_translation_context = i18n_contexts.id_particlesettings bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1704,7 +1704,7 @@ class PARTICLE_PT_children_kink(ParticleButtonsPanel, Panel): bl_label = "Kink" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1754,7 +1754,7 @@ class PARTICLE_PT_children_kink(ParticleButtonsPanel, Panel): class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel): bl_label = "Field Weights" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1775,7 +1775,7 @@ class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel): class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel): bl_label = "Force Field Settings" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -1791,7 +1791,7 @@ class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel): class PARTICLE_PT_force_fields_type1(ParticleButtonsPanel, Panel): bl_label = "Type 1" bl_parent_id = "PARTICLE_PT_force_fields" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -1808,7 +1808,7 @@ class PARTICLE_PT_force_fields_type1(ParticleButtonsPanel, Panel): class PARTICLE_PT_force_fields_type2(ParticleButtonsPanel, Panel): bl_label = "Type 2" bl_parent_id = "PARTICLE_PT_force_fields" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -1826,7 +1826,7 @@ class PARTICLE_PT_force_fields_type1_falloff(ParticleButtonsPanel, Panel): bl_label = "Falloff" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_force_fields_type1" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -1842,7 +1842,7 @@ class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel): bl_label = "Falloff" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_force_fields_type2" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -1857,7 +1857,7 @@ class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel): class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): bl_label = "Vertex Groups" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1946,7 +1946,7 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): class PARTICLE_PT_textures(ParticleButtonsPanel, Panel): bl_label = "Textures" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1978,7 +1978,7 @@ class PARTICLE_PT_textures(ParticleButtonsPanel, Panel): class PARTICLE_PT_hair_shape(ParticleButtonsPanel, Panel): bl_label = "Hair Shape" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -2006,7 +2006,7 @@ class PARTICLE_PT_hair_shape(ParticleButtonsPanel, Panel): class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "particle_system.settings" _property_type = bpy.types.ParticleSettings diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index 335cf08a715..c1c55f39eca 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -35,7 +35,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): bl_label = "Cloth" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header_preset(self, _context): CLOTH_PT_presets.draw_panel_header(self.layout) @@ -60,7 +60,7 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_physical_properties(PhysicButtonsPanel, Panel): bl_label = "Physical Properties" bl_parent_id = 'PHYSICS_PT_cloth' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -84,7 +84,7 @@ class PHYSICS_PT_cloth_physical_properties(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): bl_label = "Stiffness" bl_parent_id = 'PHYSICS_PT_cloth_physical_properties' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -115,7 +115,7 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_damping(PhysicButtonsPanel, Panel): bl_label = "Damping" bl_parent_id = 'PHYSICS_PT_cloth_physical_properties' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -146,7 +146,7 @@ class PHYSICS_PT_cloth_damping(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_internal_springs(PhysicButtonsPanel, Panel): bl_label = "Internal Springs" bl_parent_id = 'PHYSICS_PT_cloth_physical_properties' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cloth = context.cloth.settings @@ -188,7 +188,7 @@ class PHYSICS_PT_cloth_internal_springs(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_pressure(PhysicButtonsPanel, Panel): bl_label = "Pressure" bl_parent_id = 'PHYSICS_PT_cloth_physical_properties' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cloth = context.cloth.settings @@ -232,7 +232,7 @@ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): md = context.cloth @@ -243,7 +243,7 @@ class PHYSICS_PT_cloth_shape(PhysicButtonsPanel, Panel): bl_label = "Shape" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -293,7 +293,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel): bl_label = "Collisions" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -313,7 +313,7 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_object_collision(PhysicButtonsPanel, Panel): bl_label = "Object Collisions" bl_parent_id = 'PHYSICS_PT_cloth_collision' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cloth = context.cloth.collision_settings @@ -349,7 +349,7 @@ class PHYSICS_PT_cloth_object_collision(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_self_collision(PhysicButtonsPanel, Panel): bl_label = "Self Collisions" bl_parent_id = 'PHYSICS_PT_cloth_collision' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cloth = context.cloth.collision_settings @@ -386,7 +386,7 @@ class PHYSICS_PT_cloth_property_weights(PhysicButtonsPanel, Panel): bl_label = "Property Weights" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -440,7 +440,7 @@ class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): cloth = context.cloth.settings diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 4146a8ca51a..5a6eb9916e6 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -50,7 +50,7 @@ def physics_add_special(layout, data, name, addop, removeop, typeicon): class PHYSICS_PT_add(PhysicButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index f71fc56a9f0..40abbb825ee 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -83,7 +83,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -104,7 +104,7 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): class PHYSICS_PT_dynamic_paint_settings(PhysicButtonsPanel, Panel): bl_label = "Settings" bl_parent_id = 'PHYSICS_PT_dynamic_paint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -188,7 +188,7 @@ class PHYSICS_PT_dynamic_paint_settings(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_surface_canvas(PhysicButtonsPanel, Panel): bl_label = "Surface" bl_parent_id = "PHYSICS_PT_dynamic_paint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -251,7 +251,7 @@ class PHYSICS_PT_dp_surface_canvas_paint_dry(PhysicButtonsPanel, Panel): bl_label = "Dry" bl_parent_id = "PHYSICS_PT_dp_surface_canvas" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -287,7 +287,7 @@ class PHYSICS_PT_dp_surface_canvas_paint_dissolve(PhysicButtonsPanel, Panel): bl_label = "Dissolve" bl_parent_id = "PHYSICS_PT_dp_surface_canvas" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -324,7 +324,7 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): bl_label = "Output" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -400,7 +400,7 @@ class PHYSICS_PT_dp_canvas_output_paintmaps(PhysicButtonsPanel, Panel): bl_label = "Paintmaps" bl_parent_id = "PHYSICS_PT_dp_canvas_output" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -430,7 +430,7 @@ class PHYSICS_PT_dp_canvas_output_wetmaps(PhysicButtonsPanel, Panel): bl_label = "Wetmaps" bl_parent_id = "PHYSICS_PT_dp_canvas_output" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -460,7 +460,7 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel): bl_label = "Initial Color" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -500,7 +500,7 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): bl_label = "Effects" bl_parent_id = 'PHYSICS_PT_dynamic_paint' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -517,7 +517,7 @@ class PHYSICS_PT_dp_effects_spread(PhysicButtonsPanel, Panel): bl_label = "Spread" bl_parent_id = "PHYSICS_PT_dp_effects" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -552,7 +552,7 @@ class PHYSICS_PT_dp_effects_drip(PhysicButtonsPanel, Panel): bl_label = "Drip" bl_parent_id = "PHYSICS_PT_dp_effects" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -588,7 +588,7 @@ class PHYSICS_PT_dp_effects_drip_weights(PhysicButtonsPanel, Panel): bl_label = "Weights" bl_parent_id = "PHYSICS_PT_dp_effects_drip" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -612,7 +612,7 @@ class PHYSICS_PT_dp_effects_shrink(PhysicButtonsPanel, Panel): bl_label = "Shrink" bl_parent_id = "PHYSICS_PT_dp_effects" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -642,7 +642,7 @@ class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -662,7 +662,7 @@ class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): bl_label = "Source" bl_parent_id = "PHYSICS_PT_dynamic_paint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -725,7 +725,7 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_brush_source_color_ramp(PhysicButtonsPanel, Panel): bl_label = "Falloff Ramp" bl_parent_id = "PHYSICS_PT_dp_brush_source" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -752,7 +752,7 @@ class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel): bl_label = "Velocity" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -783,7 +783,7 @@ class PHYSICS_PT_dp_brush_velocity_color_ramp(PhysicButtonsPanel, Panel): bl_label = "Ramp" bl_parent_id = "PHYSICS_PT_dp_brush_velocity" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -804,7 +804,7 @@ class PHYSICS_PT_dp_brush_velocity_smudge(PhysicButtonsPanel, Panel): bl_label = "Smudge" bl_parent_id = "PHYSICS_PT_dp_brush_velocity" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -832,7 +832,7 @@ class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel): bl_label = "Waves" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 36d5dc7f68d..4e3bff3640a 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -27,7 +27,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_field(PhysicButtonsPanel, Panel): bl_label = "Force Fields" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -49,7 +49,7 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel): bl_label = "Settings" bl_parent_id = 'PHYSICS_PT_field' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -136,7 +136,7 @@ class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_settings_kink(PhysicButtonsPanel, Panel): bl_label = "Kink" bl_parent_id = 'PHYSICS_PT_field_settings' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -170,7 +170,7 @@ class PHYSICS_PT_field_settings_kink(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_settings_texture_select(PhysicButtonsPanel, Panel): bl_label = "Texture" bl_parent_id = 'PHYSICS_PT_field_settings' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -192,7 +192,7 @@ class PHYSICS_PT_field_settings_texture_select(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_falloff(PhysicButtonsPanel, Panel): bl_label = "Falloff" bl_parent_id = "PHYSICS_PT_field" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -217,7 +217,7 @@ class PHYSICS_PT_field_falloff(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel): bl_label = "Angular" bl_parent_id = "PHYSICS_PT_field_falloff" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -256,7 +256,7 @@ class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_falloff_radial(PhysicButtonsPanel, Panel): bl_label = "Radial" bl_parent_id = "PHYSICS_PT_field_falloff" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -300,7 +300,7 @@ def collision_warning(layout): class PHYSICS_PT_collision(PhysicButtonsPanel, Panel): bl_label = "Collision" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -331,7 +331,7 @@ class PHYSICS_PT_collision(PhysicButtonsPanel, Panel): class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel): bl_label = "Particle" bl_parent_id = "PHYSICS_PT_collision" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -377,7 +377,7 @@ class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel): class PHYSICS_PT_collision_softbody(PhysicButtonsPanel, Panel): bl_label = "Softbody & Cloth" bl_parent_id = "PHYSICS_PT_collision" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index ef8ee7712e5..42bc3299e6c 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -98,7 +98,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel): bl_label = "Fluid" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -122,7 +122,7 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel): class PHYSICS_PT_settings(PhysicButtonsPanel, Panel): bl_label = "Settings" bl_parent_id = 'PHYSICS_PT_fluid' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -285,7 +285,7 @@ class PHYSICS_PT_settings(PhysicButtonsPanel, Panel): class PHYSICS_PT_borders(PhysicButtonsPanel, Panel): bl_label = "Border Collisions" bl_parent_id = 'PHYSICS_PT_settings' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -318,7 +318,7 @@ class PHYSICS_PT_borders(PhysicButtonsPanel, Panel): class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): bl_label = "Gas" bl_parent_id = 'PHYSICS_PT_fluid' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -351,7 +351,7 @@ class PHYSICS_PT_smoke_dissolve(PhysicButtonsPanel, Panel): bl_label = "Dissolve" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -395,7 +395,7 @@ class PHYSICS_PT_fire(PhysicButtonsPanel, Panel): bl_label = "Fire" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -434,7 +434,7 @@ class PHYSICS_PT_fire(PhysicButtonsPanel, Panel): class PHYSICS_PT_liquid(PhysicButtonsPanel, Panel): bl_label = "Liquid" bl_parent_id = 'PHYSICS_PT_fluid' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -497,7 +497,7 @@ class PHYSICS_PT_flow_source(PhysicButtonsPanel, Panel): bl_label = "Flow Source" bl_parent_id = 'PHYSICS_PT_settings' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -538,7 +538,7 @@ class PHYSICS_PT_flow_source(PhysicButtonsPanel, Panel): class PHYSICS_PT_flow_initial_velocity(PhysicButtonsPanel, Panel): bl_label = "Initial Velocity" bl_parent_id = 'PHYSICS_PT_settings' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -580,7 +580,7 @@ class PHYSICS_PT_flow_texture(PhysicButtonsPanel, Panel): bl_label = "Texture" bl_parent_id = 'PHYSICS_PT_settings' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -631,7 +631,7 @@ class PHYSICS_PT_adaptive_domain(PhysicButtonsPanel, Panel): bl_label = "Adaptive Domain" bl_parent_id = 'PHYSICS_PT_settings' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -683,7 +683,7 @@ class PHYSICS_PT_noise(PhysicButtonsPanel, Panel): bl_label = "Noise" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -763,7 +763,7 @@ class PHYSICS_PT_mesh(PhysicButtonsPanel, Panel): bl_label = "Mesh" bl_parent_id = 'PHYSICS_PT_liquid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -858,7 +858,7 @@ class PHYSICS_PT_particles(PhysicButtonsPanel, Panel): bl_label = "Particles" bl_parent_id = 'PHYSICS_PT_liquid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -989,7 +989,7 @@ class PHYSICS_PT_viscosity(PhysicButtonsPanel, Panel): bl_label = "Viscosity" bl_parent_id = 'PHYSICS_PT_liquid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1029,7 +1029,7 @@ class PHYSICS_PT_diffusion(PhysicButtonsPanel, Panel): bl_label = "Diffusion" bl_parent_id = 'PHYSICS_PT_liquid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1076,7 +1076,7 @@ class PHYSICS_PT_guide(PhysicButtonsPanel, Panel): bl_label = "Guides" bl_parent_id = 'PHYSICS_PT_fluid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1142,7 +1142,7 @@ class PHYSICS_PT_collections(PhysicButtonsPanel, Panel): bl_label = "Collections" bl_parent_id = 'PHYSICS_PT_fluid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1169,7 +1169,7 @@ class PHYSICS_PT_collections(PhysicButtonsPanel, Panel): class PHYSICS_PT_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = 'PHYSICS_PT_fluid' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1253,7 +1253,7 @@ class PHYSICS_PT_export(PhysicButtonsPanel, Panel): bl_label = "Advanced" bl_parent_id = 'PHYSICS_PT_cache' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1298,7 +1298,7 @@ class PHYSICS_PT_field_weights(PhysicButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = 'PHYSICS_PT_fluid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1487,7 +1487,7 @@ class PHYSICS_PT_fluid_domain_render(PhysicButtonsPanel, Panel): bl_label = "Render" bl_parent_id = 'PHYSICS_PT_fluid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py index 85d1c883b50..8df348026ea 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py @@ -19,7 +19,7 @@ class PHYSICS_PT_rigidbody_panel: class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Rigid Body" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -54,7 +54,7 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): class PHYSICS_PT_rigid_body_settings(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Settings" bl_parent_id = 'PHYSICS_PT_rigid_body' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -86,7 +86,7 @@ class PHYSICS_PT_rigid_body_settings(PHYSICS_PT_rigidbody_panel, Panel): class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Collisions" bl_parent_id = 'PHYSICS_PT_rigid_body' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -136,7 +136,7 @@ class PHYSICS_PT_rigid_body_collisions_surface(PHYSICS_PT_rigidbody_panel, Panel bl_label = "Surface Response" bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -164,7 +164,7 @@ class PHYSICS_PT_rigid_body_collisions_sensitivity(PHYSICS_PT_rigidbody_panel, P bl_label = "Sensitivity" bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -201,7 +201,7 @@ class PHYSICS_PT_rigid_body_collisions_collections(PHYSICS_PT_rigidbody_panel, P bl_label = "Collections" bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -223,7 +223,7 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Dynamics" bl_parent_id = 'PHYSICS_PT_rigid_body' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -256,7 +256,7 @@ class PHYSICS_PT_rigid_body_dynamics_deactivation(PHYSICS_PT_rigidbody_panel, Pa bl_label = "Deactivation" bl_parent_id = 'PHYSICS_PT_rigid_body_dynamics' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py index 12b64abec8f..9e867b674e1 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py @@ -13,7 +13,7 @@ class PHYSICS_PT_rigidbody_constraint_panel: class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Rigid Body Constraint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -33,7 +33,7 @@ class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Pa class PHYSICS_PT_rigid_body_constraint_settings(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Settings" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -64,7 +64,7 @@ class PHYSICS_PT_rigid_body_constraint_settings(PHYSICS_PT_rigidbody_constraint_ class PHYSICS_PT_rigid_body_constraint_objects(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Objects" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -85,7 +85,7 @@ class PHYSICS_PT_rigid_body_constraint_objects(PHYSICS_PT_rigidbody_constraint_p class PHYSICS_PT_rigid_body_constraint_override_iterations(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Override Iterations" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -111,7 +111,7 @@ class PHYSICS_PT_rigid_body_constraint_override_iterations(PHYSICS_PT_rigidbody_ class PHYSICS_PT_rigid_body_constraint_limits(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Limits" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -128,7 +128,7 @@ class PHYSICS_PT_rigid_body_constraint_limits(PHYSICS_PT_rigidbody_constraint_pa class PHYSICS_PT_rigid_body_constraint_limits_linear(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Linear" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_limits' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -185,7 +185,7 @@ class PHYSICS_PT_rigid_body_constraint_limits_linear(PHYSICS_PT_rigidbody_constr class PHYSICS_PT_rigid_body_constraint_limits_angular(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Angular" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_limits' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -251,7 +251,7 @@ class PHYSICS_PT_rigid_body_constraint_limits_angular(PHYSICS_PT_rigidbody_const class PHYSICS_PT_rigid_body_constraint_motor(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Motor" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -268,7 +268,7 @@ class PHYSICS_PT_rigid_body_constraint_motor(PHYSICS_PT_rigidbody_constraint_pan class PHYSICS_PT_rigid_body_constraint_motor_angular(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Angular" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_motor' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -304,7 +304,7 @@ class PHYSICS_PT_rigid_body_constraint_motor_angular(PHYSICS_PT_rigidbody_constr class PHYSICS_PT_rigid_body_constraint_motor_linear(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Linear" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_motor' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -340,7 +340,7 @@ class PHYSICS_PT_rigid_body_constraint_motor_linear(PHYSICS_PT_rigidbody_constra class PHYSICS_PT_rigid_body_constraint_springs(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Springs" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -364,7 +364,7 @@ class PHYSICS_PT_rigid_body_constraint_springs(PHYSICS_PT_rigidbody_constraint_p class PHYSICS_PT_rigid_body_constraint_springs_angular(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Angular" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_springs' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -412,7 +412,7 @@ class PHYSICS_PT_rigid_body_constraint_springs_angular(PHYSICS_PT_rigidbody_cons class PHYSICS_PT_rigid_body_constraint_springs_linear(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Linear" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_springs' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py index ade331ac649..e4a627e5c9e 100644 --- a/release/scripts/startup/bl_ui/properties_physics_softbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py @@ -28,7 +28,7 @@ class PhysicButtonsPanel: class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel): bl_label = "Soft Body" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -44,7 +44,7 @@ class PHYSICS_PT_softbody_object(PhysicButtonsPanel, Panel): bl_label = "Object" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -72,7 +72,7 @@ class PHYSICS_PT_softbody_simulation(PhysicButtonsPanel, Panel): bl_label = "Simulation" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -90,7 +90,7 @@ class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): md = context.soft_body @@ -101,7 +101,7 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, Panel): bl_label = "Goal" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): softbody = context.soft_body.settings @@ -126,7 +126,7 @@ class PHYSICS_PT_softbody_goal_strengths(PhysicButtonsPanel, Panel): bl_label = "Strengths" bl_parent_id = 'PHYSICS_PT_softbody_goal' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -152,7 +152,7 @@ class PHYSICS_PT_softbody_goal_settings(PhysicButtonsPanel, Panel): bl_label = "Settings" bl_parent_id = 'PHYSICS_PT_softbody_goal' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -175,7 +175,7 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, Panel): bl_label = "Edges" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): softbody = context.soft_body.settings @@ -226,7 +226,7 @@ class PHYSICS_PT_softbody_edge_aerodynamics(PhysicButtonsPanel, Panel): bl_label = "Aerodynamics" bl_parent_id = 'PHYSICS_PT_softbody_edge' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -249,7 +249,7 @@ class PHYSICS_PT_softbody_edge_stiffness(PhysicButtonsPanel, Panel): bl_label = "Stiffness" bl_parent_id = 'PHYSICS_PT_softbody_edge' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): softbody = context.soft_body.settings @@ -273,7 +273,7 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, Panel): bl_label = "Self Collision" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): softbody = context.soft_body.settings @@ -308,7 +308,7 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, Panel): bl_label = "Solver" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -333,7 +333,7 @@ class PHYSICS_PT_softbody_solver_diagnostics(PhysicButtonsPanel, Panel): bl_label = "Diagnostics" bl_parent_id = 'PHYSICS_PT_softbody_solver' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -352,7 +352,7 @@ class PHYSICS_PT_softbody_solver_helpers(PhysicButtonsPanel, Panel): bl_label = "Helpers" bl_parent_id = 'PHYSICS_PT_softbody_solver' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -375,7 +375,7 @@ class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): md = context.soft_body diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index dafe32c5e5d..2d24918eb72 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -47,7 +47,7 @@ class RENDER_PT_color_management(RenderButtonsPanel, Panel): bl_label = "Color Management" bl_options = {'DEFAULT_CLOSED'} bl_order = 100 - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -80,7 +80,7 @@ class RENDER_PT_color_management_curves(RenderButtonsPanel, Panel): bl_label = "Use Curves" bl_parent_id = "RENDER_PT_color_management" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): @@ -640,7 +640,7 @@ class RENDER_PT_eevee_hair(RenderButtonsPanel, Panel): class RENDER_PT_eevee_performance(RenderButtonsPanel, Panel): bl_label = "Performance" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -661,7 +661,7 @@ class RENDER_PT_gpencil(RenderButtonsPanel, Panel): bl_label = "Grease Pencil" bl_options = {'DEFAULT_CLOSED'} bl_order = 10 - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -677,7 +677,7 @@ class RENDER_PT_gpencil(RenderButtonsPanel, Panel): class RENDER_PT_opengl_sampling(RenderButtonsPanel, Panel): bl_label = "Sampling" - COMPAT_ENGINES = {'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -699,7 +699,7 @@ class RENDER_PT_opengl_sampling(RenderButtonsPanel, Panel): class RENDER_PT_opengl_film(RenderButtonsPanel, Panel): bl_label = "Film" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -712,7 +712,7 @@ class RENDER_PT_opengl_film(RenderButtonsPanel, Panel): class RENDER_PT_opengl_lighting(RenderButtonsPanel, Panel): bl_label = "Lighting" - COMPAT_ENGINES = {'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -724,7 +724,7 @@ class RENDER_PT_opengl_lighting(RenderButtonsPanel, Panel): class RENDER_PT_opengl_color(RenderButtonsPanel, Panel): bl_label = "Color" - COMPAT_ENGINES = {'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -736,7 +736,7 @@ class RENDER_PT_opengl_color(RenderButtonsPanel, Panel): class RENDER_PT_opengl_options(RenderButtonsPanel, Panel): bl_label = "Options" - COMPAT_ENGINES = {'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -749,7 +749,7 @@ class RENDER_PT_opengl_options(RenderButtonsPanel, Panel): class RENDER_PT_simplify(RenderButtonsPanel, Panel): bl_label = "Simplify" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): rd = context.scene.render @@ -762,7 +762,7 @@ class RENDER_PT_simplify(RenderButtonsPanel, Panel): class RENDER_PT_simplify_viewport(RenderButtonsPanel, Panel): bl_label = "Viewport" bl_parent_id = "RENDER_PT_simplify" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -787,7 +787,7 @@ class RENDER_PT_simplify_viewport(RenderButtonsPanel, Panel): class RENDER_PT_simplify_render(RenderButtonsPanel, Panel): bl_label = "Render" bl_parent_id = "RENDER_PT_simplify" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -815,7 +815,7 @@ class RENDER_PT_simplify_greasepencil(RenderButtonsPanel, Panel, GreasePencilSim 'BLENDER_CLAY', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', - 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT', } bl_options = {'DEFAULT_CLOSED'} diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index d9c51397d6e..4d42e432cc8 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -67,7 +67,7 @@ class TextureButtonsPanel: class TEXTURE_PT_preview(TextureButtonsPanel, Panel): bl_label = "Preview" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -96,7 +96,7 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel): bl_label = "" bl_context = "texture" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -135,7 +135,7 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel): class TEXTURE_PT_node(TextureButtonsPanel, Panel): bl_label = "Node" bl_context = "texture" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -164,7 +164,7 @@ class TextureTypePanel(TextureButtonsPanel): class TEXTURE_PT_clouds(TextureTypePanel, Panel): bl_label = "Clouds" tex_type = 'CLOUDS' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -196,7 +196,7 @@ class TEXTURE_PT_clouds(TextureTypePanel, Panel): class TEXTURE_PT_wood(TextureTypePanel, Panel): bl_label = "Wood" tex_type = 'WOOD' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -233,7 +233,7 @@ class TEXTURE_PT_wood(TextureTypePanel, Panel): class TEXTURE_PT_marble(TextureTypePanel, Panel): bl_label = "Marble" tex_type = 'MARBLE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -267,7 +267,7 @@ class TEXTURE_PT_marble(TextureTypePanel, Panel): class TEXTURE_PT_magic(TextureTypePanel, Panel): bl_label = "Magic" tex_type = 'MAGIC' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -286,7 +286,7 @@ class TEXTURE_PT_magic(TextureTypePanel, Panel): class TEXTURE_PT_blend(TextureTypePanel, Panel): bl_label = "Blend" tex_type = 'BLEND' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -308,7 +308,7 @@ class TEXTURE_PT_blend(TextureTypePanel, Panel): class TEXTURE_PT_stucci(TextureTypePanel, Panel): bl_label = "Stucci" tex_type = 'STUCCI' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -339,7 +339,7 @@ class TEXTURE_PT_stucci(TextureTypePanel, Panel): class TEXTURE_PT_image(TextureTypePanel, Panel): bl_label = "Image" tex_type = 'IMAGE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, _context): # TODO: maybe expose the template_ID from the template image here. @@ -351,7 +351,7 @@ class TEXTURE_PT_image_settings(TextureTypePanel, Panel): bl_label = "Settings" bl_parent_id = 'TEXTURE_PT_image' tex_type = 'IMAGE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -506,7 +506,7 @@ class TEXTURE_PT_image_mapping_crop(TextureTypePanel, Panel): class TEXTURE_PT_musgrave(TextureTypePanel, Panel): bl_label = "Musgrave" tex_type = 'MUSGRAVE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -551,7 +551,7 @@ class TEXTURE_PT_musgrave(TextureTypePanel, Panel): class TEXTURE_PT_voronoi(TextureTypePanel, Panel): bl_label = "Voronoi" tex_type = 'VORONOI' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -584,7 +584,7 @@ class TEXTURE_PT_voronoi_feature_weights(TextureTypePanel, Panel): bl_label = "Feature Weights" bl_parent_id = "TEXTURE_PT_voronoi" tex_type = 'VORONOI' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -605,7 +605,7 @@ class TEXTURE_PT_voronoi_feature_weights(TextureTypePanel, Panel): class TEXTURE_PT_distortednoise(TextureTypePanel, Panel): bl_label = "Distorted Noise" tex_type = 'DISTORTED_NOISE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -630,7 +630,7 @@ class TEXTURE_PT_distortednoise(TextureTypePanel, Panel): class TextureSlotPanel(TextureButtonsPanel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -642,7 +642,7 @@ class TextureSlotPanel(TextureButtonsPanel): class TEXTURE_PT_mapping(TextureSlotPanel, Panel): bl_label = "Mapping" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -710,7 +710,7 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel): class TEXTURE_PT_influence(TextureSlotPanel, Panel): bl_label = "Influence" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -792,7 +792,7 @@ class TextureColorsPoll: class TEXTURE_PT_colors(TextureButtonsPanel, TextureColorsPoll, Panel): bl_label = "Colors" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -821,7 +821,7 @@ class TEXTURE_PT_colors_ramp(TextureButtonsPanel, TextureColorsPoll, Panel): bl_label = "Color Ramp" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = 'TEXTURE_PT_colors' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): tex = context.texture @@ -842,7 +842,7 @@ class TEXTURE_PT_colors_ramp(TextureButtonsPanel, TextureColorsPoll, Panel): class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "texture" _property_type = Texture diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py index c6d1ee2a065..c45cafa07fa 100644 --- a/release/scripts/startup/bl_ui/properties_view_layer.py +++ b/release/scripts/startup/bl_ui/properties_view_layer.py @@ -26,7 +26,7 @@ class ViewLayerButtonsPanel: class VIEWLAYER_PT_layer(ViewLayerButtonsPanel, Panel): bl_label = "View Layer" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -44,7 +44,7 @@ class VIEWLAYER_PT_layer(ViewLayerButtonsPanel, Panel): class VIEWLAYER_PT_layer_passes(ViewLayerButtonsPanel, Panel): bl_label = "Passes" - COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): pass @@ -94,6 +94,23 @@ class VIEWLAYER_PT_eevee_next_layer_passes_data(ViewLayerButtonsPanel, Panel): sub.active = not scene.eevee.use_motion_blur sub.prop(view_layer, "use_pass_vector") +class VIEWLAYER_PT_eevee_next_layer_passes_data(ViewLayerButtonsPanel, Panel): + bl_label = "Data" + bl_parent_id = "VIEWLAYER_PT_layer_passes" + + COMPAT_ENGINES = {'BLENDER_WORKBENCH_NEXT'} + + def draw(self, context): + layout = self.layout + layout.use_property_split = True + layout.use_property_decorate = False + + view_layer = context.view_layer + + col = layout.column() + col.prop(view_layer, "use_pass_combined") + col.prop(view_layer, "use_pass_z") + class VIEWLAYER_PT_eevee_layer_passes_light(ViewLayerButtonsPanel, Panel): bl_label = "Light" diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py index b0ea36abd6b..8dd4e36b750 100644 --- a/release/scripts/startup/bl_ui/properties_world.py +++ b/release/scripts/startup/bl_ui/properties_world.py @@ -19,7 +19,7 @@ class WorldButtonsPanel: class WORLD_PT_context_world(WorldButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -63,7 +63,7 @@ class EEVEE_WORLD_PT_mist(WorldButtonsPanel, Panel): class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "world" _property_type = bpy.types.World diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index bf8a39ea26f..95851a78184 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -670,7 +670,7 @@ class NODE_PT_texture_mapping(Panel): bl_category = "Node" bl_label = "Texture Mapping" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 56781b8c6d7..557105e0e84 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -2607,7 +2607,7 @@ class SEQUENCER_PT_annotation_onion(AnnotationOnionSkin, SequencerButtonsPanel_O class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} _context_path = "active_sequence_strip" _property_type = (bpy.types.Sequence,) bl_category = "Strip" diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 945abe3f5a4..38db569915c 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -2339,6 +2339,7 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel): ({"property": "use_sculpt_texture_paint"}, "T96225"), ({"property": "use_full_frame_compositor"}, "T88150"), ({"property": "enable_eevee_next"}, "T93220"), + ({"property": "enable_workbench_next"}, "T101619"), ), ) diff --git a/source/blender/blenkernel/intern/scene.cc b/source/blender/blenkernel/intern/scene.cc index cdffbcea527..445a1517965 100644 --- a/source/blender/blenkernel/intern/scene.cc +++ b/source/blender/blenkernel/intern/scene.cc @@ -1748,6 +1748,7 @@ IDTypeInfo IDType_ID_SCE = get_type_info(); const char *RE_engine_id_BLENDER_EEVEE = "BLENDER_EEVEE"; const char *RE_engine_id_BLENDER_WORKBENCH = "BLENDER_WORKBENCH"; +const char *RE_engine_id_BLENDER_WORKBENCH_NEXT = "BLENDER_WORKBENCH_NEXT"; const char *RE_engine_id_CYCLES = "CYCLES"; void free_avicodecdata(AviCodecData *acd) @@ -2939,7 +2940,8 @@ bool BKE_scene_uses_blender_eevee(const Scene *scene) bool BKE_scene_uses_blender_workbench(const Scene *scene) { - return STREQ(scene->r.engine, RE_engine_id_BLENDER_WORKBENCH); + return STREQ(scene->r.engine, RE_engine_id_BLENDER_WORKBENCH) || + STREQ(scene->r.engine, RE_engine_id_BLENDER_WORKBENCH_NEXT); } bool BKE_scene_uses_cycles(const Scene *scene) diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 2ced6f2d1bf..d2835639686 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -157,15 +157,26 @@ set(SRC engines/eevee_next/eevee_world.cc engines/workbench/workbench_data.c engines/workbench/workbench_effect_antialiasing.c + engines/workbench/workbench_effect_antialiasing.cc engines/workbench/workbench_effect_cavity.c + engines/workbench/workbench_effect_cavity.cc engines/workbench/workbench_effect_dof.c + engines/workbench/workbench_effect_dof.cc engines/workbench/workbench_effect_outline.c + engines/workbench/workbench_effect_outline.cc engines/workbench/workbench_engine.c + engines/workbench/workbench_engine.cc engines/workbench/workbench_materials.cc + engines/workbench/workbench_materials_next.cc + engines/workbench/workbench_mesh_passes.cc engines/workbench/workbench_opaque.c engines/workbench/workbench_render.c + engines/workbench/workbench_resources.cc engines/workbench/workbench_shader.cc + engines/workbench/workbench_shader_cache.cc engines/workbench/workbench_shadow.c + engines/workbench/workbench_shadow.cc + engines/workbench/workbench_state.cc engines/workbench/workbench_transparent.c engines/workbench/workbench_volume.c engines/external/external_engine.c @@ -289,8 +300,11 @@ set(SRC engines/image/image_space_node.hh engines/image/image_texture_info.hh engines/image/image_usage.hh + engines/workbench/workbench_defines.hh engines/workbench/workbench_engine.h + engines/workbench/workbench_enums.hh engines/workbench/workbench_private.h + engines/workbench/workbench_private.hh engines/workbench/workbench_shader_shared.h engines/select/select_engine.h engines/select/select_private.h @@ -461,6 +475,7 @@ set(GLSL_SRC engines/workbench/shaders/workbench_cavity_lib.glsl engines/workbench/shaders/workbench_common_lib.glsl engines/workbench/shaders/workbench_composite_frag.glsl + engines/workbench/shaders/workbench_next_composite_frag.glsl engines/workbench/shaders/workbench_curvature_lib.glsl engines/workbench/shaders/workbench_effect_cavity_frag.glsl engines/workbench/shaders/workbench_effect_dof_frag.glsl @@ -472,6 +487,7 @@ set(GLSL_SRC engines/workbench/shaders/workbench_matcap_lib.glsl engines/workbench/shaders/workbench_material_lib.glsl engines/workbench/shaders/workbench_merge_infront_frag.glsl + engines/workbench/shaders/workbench_next_merge_depth_frag.glsl engines/workbench/shaders/workbench_prepass_frag.glsl engines/workbench/shaders/workbench_prepass_hair_vert.glsl engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl @@ -481,6 +497,7 @@ set(GLSL_SRC engines/workbench/shaders/workbench_shadow_debug_frag.glsl engines/workbench/shaders/workbench_shadow_geom.glsl engines/workbench/shaders/workbench_shadow_vert.glsl + engines/workbench/shaders/workbench_shadow_visibility_comp.glsl engines/workbench/shaders/workbench_shadow_vert_no_geom.glsl engines/workbench/shaders/workbench_transparent_accum_frag.glsl engines/workbench/shaders/workbench_transparent_resolve_frag.glsl @@ -689,6 +706,7 @@ set(GLSL_SRC ) set(GLSL_C) + foreach(GLSL_FILE ${GLSL_SRC}) data_to_c_simple(${GLSL_FILE} GLSL_C) endforeach() @@ -700,6 +718,7 @@ list(APPEND LIB ) set(GLSL_SOURCE_CONTENT "") + foreach(GLSL_FILE ${GLSL_SRC}) get_filename_component(GLSL_FILE_NAME ${GLSL_FILE} NAME) string(REPLACE "." "_" GLSL_FILE_NAME_UNDERSCORES ${GLSL_FILE_NAME}) @@ -752,11 +771,13 @@ endif() if(WITH_TBB) add_definitions(-DWITH_TBB) + if(WIN32) # TBB includes Windows.h which will define min/max macros # that will collide with the stl versions. add_definitions(-DNOMINMAX) endif() + list(APPEND INC_SYS ${TBB_INCLUDE_DIRS} ) diff --git a/source/blender/draw/engines/workbench/shaders/infos/workbench_composite_info.hh b/source/blender/draw/engines/workbench/shaders/infos/workbench_composite_info.hh index 2cd4a874b58..c437605574d 100644 --- a/source/blender/draw/engines/workbench/shaders/infos/workbench_composite_info.hh +++ b/source/blender/draw/engines/workbench/shaders/infos/workbench_composite_info.hh @@ -1,15 +1,16 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "gpu_shader_create_info.hh" +#include "workbench_defines.hh" /* -------------------------------------------------------------------- */ /** \name Base Composite * \{ */ GPU_SHADER_CREATE_INFO(workbench_composite) - .sampler(0, ImageType::FLOAT_2D, "normalBuffer", Frequency::PASS) - .sampler(1, ImageType::FLOAT_2D, "materialBuffer", Frequency::PASS) - .uniform_buf(4, "WorldData", "world_data", Frequency::PASS) + .sampler(0, ImageType::FLOAT_2D, "normalBuffer") + .sampler(1, ImageType::FLOAT_2D, "materialBuffer") + .uniform_buf(WB_WORLD_SLOT, "WorldData", "world_data") .push_constant(Type::BOOL, "forceShadowing") .fragment_out(0, Type::VEC4, "fragColor") .typedef_source("workbench_shader_shared.h") @@ -23,20 +24,88 @@ GPU_SHADER_CREATE_INFO(workbench_composite) * \{ */ GPU_SHADER_CREATE_INFO(workbench_composite_studio) - .define("V3D_LIGHTING_STUDIO") + .define("WORKBENCH_LIGHTING_STUDIO") .additional_info("workbench_composite") .do_static_compilation(true); GPU_SHADER_CREATE_INFO(workbench_composite_matcap) - .define("V3D_LIGHTING_MATCAP") - .sampler(2, ImageType::FLOAT_2D, "matcap_diffuse_tx", Frequency::PASS) - .sampler(3, ImageType::FLOAT_2D, "matcap_specular_tx", Frequency::PASS) + .define("WORKBENCH_LIGHTING_MATCAP") + .sampler(2, ImageType::FLOAT_2D, "matcap_diffuse_tx") + .sampler(3, ImageType::FLOAT_2D, "matcap_specular_tx") .additional_info("workbench_composite") .do_static_compilation(true); GPU_SHADER_CREATE_INFO(workbench_composite_flat) - .define("V3D_LIGHTING_FLAT") + .define("WORKBENCH_LIGHTING_FLAT") .additional_info("workbench_composite") .do_static_compilation(true); /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Workbench Next + * \{ */ + +GPU_SHADER_CREATE_INFO(workbench_next_composite) + .sampler(3, ImageType::FLOAT_2D, "normal_tx") + .sampler(4, ImageType::FLOAT_2D, "material_tx") + .sampler(5, ImageType::DEPTH_2D, "depth_tx") + .sampler(6, ImageType::UINT_2D, "stencil_tx") + .uniform_buf(WB_WORLD_SLOT, "WorldData", "world_data") + .typedef_source("workbench_shader_shared.h") + .push_constant(Type::BOOL, "forceShadowing") + .fragment_out(0, Type::VEC4, "fragColor") + .fragment_source("workbench_next_composite_frag.glsl") + .additional_info("draw_fullscreen", "draw_view"); + +/* Lighting */ + +GPU_SHADER_CREATE_INFO(workbench_next_resolve_opaque_studio).define("WORKBENCH_LIGHTING_STUDIO"); + +GPU_SHADER_CREATE_INFO(workbench_next_resolve_opaque_matcap) + .define("WORKBENCH_LIGHTING_MATCAP") + .sampler(WB_MATCAP_SLOT, ImageType::FLOAT_2D_ARRAY, "matcap_tx"); + +GPU_SHADER_CREATE_INFO(workbench_next_resolve_opaque_flat).define("WORKBENCH_LIGHTING_FLAT"); + +/* Effects */ + +GPU_SHADER_CREATE_INFO(workbench_next_resolve_curvature) + .define("WORKBENCH_CURVATURE") + .sampler(7, ImageType::UINT_2D, "object_id_tx"); + +GPU_SHADER_CREATE_INFO(workbench_next_resolve_cavity) + .define("WORKBENCH_CAVITY") + .sampler(8, ImageType::FLOAT_2D, "jitter_tx") /* TODO(Miguel Pozo): GPU_SAMPLER_REPEAT is set + in CavityEffect, it doesn't work here ? */ + .uniform_buf(5, "vec4", "cavity_samples[512]"); + +/* Variations */ + +#define WORKBENCH_FINAL_VARIATION(name, ...) \ + GPU_SHADER_CREATE_INFO(name).additional_info(__VA_ARGS__).do_static_compilation(true); + +#define WORKBENCH_CURVATURE_VARIATIONS(prefix, ...) \ + WORKBENCH_FINAL_VARIATION(prefix##_curvature, "workbench_next_resolve_curvature", __VA_ARGS__) \ + WORKBENCH_FINAL_VARIATION(prefix##_no_curvature, __VA_ARGS__) + +#define WORKBENCH_CAVITY_VARIATIONS(prefix, ...) \ + WORKBENCH_CURVATURE_VARIATIONS(prefix##_cavity, "workbench_next_resolve_cavity", __VA_ARGS__) \ + WORKBENCH_CURVATURE_VARIATIONS(prefix##_no_cavity, __VA_ARGS__) + +#define WORKBENCH_LIGHTING_VARIATIONS(prefix, ...) \ + WORKBENCH_CAVITY_VARIATIONS( \ + prefix##_opaque_studio, "workbench_next_resolve_opaque_studio", __VA_ARGS__) \ + WORKBENCH_CAVITY_VARIATIONS( \ + prefix##_opaque_matcap, "workbench_next_resolve_opaque_matcap", __VA_ARGS__) \ + WORKBENCH_CAVITY_VARIATIONS( \ + prefix##_opaque_flat, "workbench_next_resolve_opaque_flat", __VA_ARGS__) + +WORKBENCH_LIGHTING_VARIATIONS(workbench_next_resolve, "workbench_next_composite"); + +#undef WORKBENCH_FINAL_VARIATION +#undef WORKBENCH_CURVATURE_VARIATIONS +#undef WORKBENCH_CAVITY_VARIATIONS +#undef WORKBENCH_LIGHTING_VARIATIONS + +/** \} */ diff --git a/source/blender/draw/engines/workbench/shaders/infos/workbench_effect_cavity_info.hh b/source/blender/draw/engines/workbench/shaders/infos/workbench_effect_cavity_info.hh index 089644d20bc..5a54afc6bff 100644 --- a/source/blender/draw/engines/workbench/shaders/infos/workbench_effect_cavity_info.hh +++ b/source/blender/draw/engines/workbench/shaders/infos/workbench_effect_cavity_info.hh @@ -5,7 +5,7 @@ GPU_SHADER_CREATE_INFO(workbench_effect_cavity_common) .fragment_out(0, Type::VEC4, "fragColor") .sampler(0, ImageType::FLOAT_2D, "normalBuffer") - .uniform_buf(4, "WorldData", "world_data", Frequency::PASS) + .uniform_buf(WB_WORLD_SLOT, "WorldData", "world_data") .typedef_source("workbench_shader_shared.h") .fragment_source("workbench_effect_cavity_frag.glsl") .additional_info("draw_fullscreen") diff --git a/source/blender/draw/engines/workbench/shaders/infos/workbench_effect_outline_info.hh b/source/blender/draw/engines/workbench/shaders/infos/workbench_effect_outline_info.hh index e76875b3fa5..fe4b6de7347 100644 --- a/source/blender/draw/engines/workbench/shaders/infos/workbench_effect_outline_info.hh +++ b/source/blender/draw/engines/workbench/shaders/infos/workbench_effect_outline_info.hh @@ -6,7 +6,7 @@ GPU_SHADER_CREATE_INFO(workbench_effect_outline) .typedef_source("workbench_shader_shared.h") .fragment_source("workbench_effect_outline_frag.glsl") .sampler(0, ImageType::UINT_2D, "objectIdBuffer") - .uniform_buf(4, "WorldData", "world_data", Frequency::PASS) + .uniform_buf(WB_WORLD_SLOT, "WorldData", "world_data") .fragment_out(0, Type::VEC4, "fragColor") .additional_info("draw_fullscreen") .do_static_compilation(true); diff --git a/source/blender/draw/engines/workbench/shaders/infos/workbench_merge_infront_info.hh b/source/blender/draw/engines/workbench/shaders/infos/workbench_merge_infront_info.hh index 8322d6891b7..fdf8fb61d9c 100644 --- a/source/blender/draw/engines/workbench/shaders/infos/workbench_merge_infront_info.hh +++ b/source/blender/draw/engines/workbench/shaders/infos/workbench_merge_infront_info.hh @@ -9,3 +9,10 @@ GPU_SHADER_CREATE_INFO(workbench_merge_infront) .additional_info("draw_fullscreen") .depth_write(DepthWrite::ANY) .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(workbench_next_merge_depth) + .sampler(0, ImageType::DEPTH_2D, "depth_tx") + .fragment_source("workbench_next_merge_depth_frag.glsl") + .additional_info("draw_fullscreen") + .depth_write(DepthWrite::ANY) + .do_static_compilation(true); diff --git a/source/blender/draw/engines/workbench/shaders/infos/workbench_prepass_info.hh b/source/blender/draw/engines/workbench/shaders/infos/workbench_prepass_info.hh index 735e7b6d867..92452eefed2 100644 --- a/source/blender/draw/engines/workbench/shaders/infos/workbench_prepass_info.hh +++ b/source/blender/draw/engines/workbench/shaders/infos/workbench_prepass_info.hh @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "gpu_shader_create_info.hh" +#include "workbench_defines.hh" /* -------------------------------------------------------------------- */ /** \name Object Type @@ -29,6 +30,29 @@ GPU_SHADER_CREATE_INFO(workbench_pointcloud) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Object Type + * \{ */ + +GPU_SHADER_CREATE_INFO(workbench_next_mesh) + .vertex_in(0, Type::VEC3, "pos") + .vertex_in(1, Type::VEC3, "nor") + .vertex_in(2, Type::VEC4, "ac") + .vertex_in(3, Type::VEC2, "au") + .vertex_source("workbench_prepass_vert.glsl") + .additional_info("draw_modelmat_new") + .additional_info("draw_resource_handle_new"); + +GPU_SHADER_CREATE_INFO(workbench_next_curves) + /* TODO Adding workbench_next_mesh to avoid shader compilation errors */ + .additional_info("workbench_next_mesh"); + +GPU_SHADER_CREATE_INFO(workbench_next_pointcloud) + /* TODO Adding workbench_next_mesh to avoid shader compilation errors */ + .additional_info("workbench_next_mesh"); + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Texture Type * \{ */ @@ -39,15 +63,15 @@ GPU_SHADER_CREATE_INFO(workbench_texture_single) .sampler(2, ImageType::FLOAT_2D, "imageTexture", Frequency::BATCH) .push_constant(Type::BOOL, "imagePremult") .push_constant(Type::FLOAT, "imageTransparencyCutoff") - .define("V3D_SHADING_TEXTURE_COLOR"); + .define("WORKBENCH_COLOR_TEXTURE"); GPU_SHADER_CREATE_INFO(workbench_texture_tile) .sampler(2, ImageType::FLOAT_2D_ARRAY, "imageTileArray", Frequency::BATCH) .sampler(3, ImageType::FLOAT_1D_ARRAY, "imageTileData", Frequency::BATCH) .push_constant(Type::BOOL, "imagePremult") .push_constant(Type::FLOAT, "imageTransparencyCutoff") - .define("V3D_SHADING_TEXTURE_COLOR") - .define("TEXTURE_IMAGE_ARRAY"); + .define("WORKBENCH_COLOR_TEXTURE") + .define("WORKBENCH_TEXTURE_IMAGE_ARRAY"); /** \} */ @@ -55,12 +79,16 @@ GPU_SHADER_CREATE_INFO(workbench_texture_tile) /** \name Lighting Type (only for transparent) * \{ */ -GPU_SHADER_CREATE_INFO(workbench_lighting_flat).define("V3D_LIGHTING_FLAT"); -GPU_SHADER_CREATE_INFO(workbench_lighting_studio).define("V3D_LIGHTING_STUDIO"); +GPU_SHADER_CREATE_INFO(workbench_lighting_flat).define("WORKBENCH_LIGHTING_FLAT"); +GPU_SHADER_CREATE_INFO(workbench_lighting_studio).define("WORKBENCH_LIGHTING_STUDIO"); GPU_SHADER_CREATE_INFO(workbench_lighting_matcap) - .define("V3D_LIGHTING_MATCAP") - .sampler(4, ImageType::FLOAT_2D, "matcap_diffuse_tx", Frequency::PASS) - .sampler(5, ImageType::FLOAT_2D, "matcap_specular_tx", Frequency::PASS); + .define("WORKBENCH_LIGHTING_MATCAP") + .sampler(4, ImageType::FLOAT_2D, "matcap_diffuse_tx") + .sampler(5, ImageType::FLOAT_2D, "matcap_specular_tx"); + +GPU_SHADER_CREATE_INFO(workbench_next_lighting_matcap) + .define("WORKBENCH_LIGHTING_MATCAP") + .sampler(WB_MATCAP_SLOT, ImageType::FLOAT_2D_ARRAY, "matcap_tx"); /** \} */ @@ -78,12 +106,42 @@ GPU_SHADER_INTERFACE_INFO(workbench_material_iface, "") .flat(Type::FLOAT, "metallic"); GPU_SHADER_CREATE_INFO(workbench_material) - .uniform_buf(4, "WorldData", "world_data", Frequency::PASS) - .uniform_buf(5, "vec4", "materials_data[4096]", Frequency::PASS) + .uniform_buf(WB_WORLD_SLOT, "WorldData", "world_data") + .uniform_buf(5, "vec4", "materials_data[4096]") .push_constant(Type::INT, "materialIndex") .push_constant(Type::BOOL, "useMatcap") .vertex_out(workbench_material_iface); +GPU_SHADER_CREATE_INFO(workbench_next_prepass) + .define("WORKBENCH_NEXT") + .uniform_buf(WB_WORLD_SLOT, "WorldData", "world_data") + .vertex_out(workbench_material_iface) + .additional_info("draw_view"); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Material Interface + * \{ */ + +GPU_SHADER_CREATE_INFO(workbench_color_material) + .define("WORKBENCH_COLOR_MATERIAL") + .storage_buf(WB_MATERIAL_SLOT, Qualifier::READ, "vec4", "materials_data[]"); + +GPU_SHADER_CREATE_INFO(workbench_color_texture) + .define("WORKBENCH_COLOR_TEXTURE") + .define("WORKBENCH_TEXTURE_IMAGE_ARRAY") + .define("WORKBENCH_COLOR_MATERIAL") + .storage_buf(WB_MATERIAL_SLOT, Qualifier::READ, "vec4", "materials_data[]") + .sampler(1, ImageType::FLOAT_2D, "imageTexture", Frequency::BATCH) + .sampler(2, ImageType::FLOAT_2D_ARRAY, "imageTileArray", Frequency::BATCH) + .sampler(3, ImageType::FLOAT_1D_ARRAY, "imageTileData", Frequency::BATCH) + .push_constant(Type::BOOL, "isImageTile") + .push_constant(Type::BOOL, "imagePremult") + .push_constant(Type::FLOAT, "imageTransparencyCutoff"); + +GPU_SHADER_CREATE_INFO(workbench_color_vertex).define("WORKBENCH_COLOR_VERTEX"); + /** \} */ /* -------------------------------------------------------------------- */ @@ -93,17 +151,17 @@ GPU_SHADER_CREATE_INFO(workbench_material) GPU_SHADER_CREATE_INFO(workbench_transparent_accum) /* NOTE: Blending will be skipped on objectId because output is a * non-normalized integer buffer. */ - .fragment_out(0, Type::VEC4, "transparentAccum") - .fragment_out(1, Type::VEC4, "revealageAccum") - .fragment_out(2, Type::UINT, "objectId") + .fragment_out(0, Type::VEC4, "out_transparent_accum") + .fragment_out(1, Type::VEC4, "out_revealage_accum") + .fragment_out(2, Type::UINT, "out_object_id") .push_constant(Type::BOOL, "forceShadowing") .typedef_source("workbench_shader_shared.h") .fragment_source("workbench_transparent_accum_frag.glsl"); GPU_SHADER_CREATE_INFO(workbench_opaque) - .fragment_out(0, Type::VEC4, "materialData") - .fragment_out(1, Type::VEC2, "normalData") - .fragment_out(2, Type::UINT, "objectId") + .fragment_out(0, Type::VEC4, "out_material") + .fragment_out(1, Type::VEC2, "out_normal") + .fragment_out(2, Type::UINT, "out_object_id") .typedef_source("workbench_shader_shared.h") .fragment_source("workbench_prepass_frag.glsl"); @@ -147,4 +205,54 @@ GPU_SHADER_CREATE_INFO(workbench_opaque) WORKBENCH_PIPELINE_VARIATIONS(workbench, "workbench_material"); +#undef WORKBENCH_FINAL_VARIATION +#undef WORKBENCH_CLIPPING_VARIATIONS +#undef WORKBENCH_TEXTURE_VARIATIONS +#undef WORKBENCH_DATATYPE_VARIATIONS +#undef WORKBENCH_PIPELINE_VARIATIONS + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Variations Declaration + * \{ */ + +GPU_SHADER_CREATE_INFO(workbench_flat).define("WORKBENCH_SHADING_FLAT"); +GPU_SHADER_CREATE_INFO(workbench_studio).define("WORKBENCH_SHADING_STUDIO"); +GPU_SHADER_CREATE_INFO(workbench_matcap).define("WORKBENCH_SHADING_MATCAP"); + +#define WORKBENCH_FINAL_VARIATION(name, ...) \ + GPU_SHADER_CREATE_INFO(name).additional_info(__VA_ARGS__).do_static_compilation(true); + +#define WORKBENCH_CLIPPING_VARIATIONS(prefix, ...) \ + WORKBENCH_FINAL_VARIATION(prefix##_clip, "drw_clipped", __VA_ARGS__) \ + WORKBENCH_FINAL_VARIATION(prefix##_no_clip, __VA_ARGS__) + +#define WORKBENCH_COLOR_VARIATIONS(prefix, ...) \ + WORKBENCH_CLIPPING_VARIATIONS(prefix##_material, "workbench_color_material", __VA_ARGS__) \ + WORKBENCH_CLIPPING_VARIATIONS(prefix##_texture, "workbench_color_texture", __VA_ARGS__) \ + WORKBENCH_CLIPPING_VARIATIONS(prefix##_vertex, "workbench_color_vertex", __VA_ARGS__) + +#define WORKBENCH_SHADING_VARIATIONS(prefix, ...) \ + WORKBENCH_COLOR_VARIATIONS(prefix##_flat, "workbench_lighting_flat", __VA_ARGS__) \ + WORKBENCH_COLOR_VARIATIONS(prefix##_studio, "workbench_lighting_studio", __VA_ARGS__) \ + WORKBENCH_COLOR_VARIATIONS(prefix##_matcap, "workbench_next_lighting_matcap", __VA_ARGS__) + +#define WORKBENCH_PIPELINE_VARIATIONS(prefix, ...) \ + WORKBENCH_SHADING_VARIATIONS(prefix##_transparent, "workbench_transparent_accum", __VA_ARGS__) \ + WORKBENCH_SHADING_VARIATIONS(prefix##_opaque, "workbench_opaque", __VA_ARGS__) + +#define WORKBENCH_GEOMETRY_VARIATIONS(prefix, ...) \ + WORKBENCH_PIPELINE_VARIATIONS(prefix##_mesh, "workbench_next_mesh", __VA_ARGS__) \ + WORKBENCH_PIPELINE_VARIATIONS(prefix##_curves, "workbench_next_curves", __VA_ARGS__) \ + WORKBENCH_PIPELINE_VARIATIONS(prefix##_ptcloud, "workbench_next_pointcloud", __VA_ARGS__) + +WORKBENCH_GEOMETRY_VARIATIONS(workbench_next_prepass, "workbench_next_prepass"); + +#undef WORKBENCH_FINAL_VARIATION +#undef WORKBENCH_CLIPPING_VARIATIONS +#undef WORKBENCH_TEXTURE_VARIATIONS +#undef WORKBENCH_DATATYPE_VARIATIONS +#undef WORKBENCH_PIPELINE_VARIATIONS + /** \} */ diff --git a/source/blender/draw/engines/workbench/shaders/infos/workbench_shadow_info.hh b/source/blender/draw/engines/workbench/shaders/infos/workbench_shadow_info.hh index 3d86ef6e78c..a81c1b5712e 100644 --- a/source/blender/draw/engines/workbench/shaders/infos/workbench_shadow_info.hh +++ b/source/blender/draw/engines/workbench/shaders/infos/workbench_shadow_info.hh @@ -1,5 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "draw_defines.h" + #include "gpu_shader_create_info.hh" /* -------------------------------------------------------------------- */ @@ -9,7 +11,8 @@ GPU_SHADER_INTERFACE_INFO(workbench_shadow_iface, "vData") .smooth(Type::VEC3, "pos") .smooth(Type::VEC4, "frontPosition") - .smooth(Type::VEC4, "backPosition"); + .smooth(Type::VEC4, "backPosition") + .flat(Type::VEC3, "light_direction_os"); /*Workbench Next*/ GPU_SHADER_CREATE_INFO(workbench_shadow_common) .vertex_in(0, Type::VEC3, "pos") @@ -24,6 +27,43 @@ GPU_SHADER_CREATE_INFO(workbench_shadow_common_geom) .vertex_out(workbench_shadow_iface) .vertex_source("workbench_shadow_vert.glsl"); +GPU_SHADER_CREATE_INFO(workbench_next_shadow_common) + .vertex_in(0, Type::VEC3, "pos") + .vertex_out(workbench_shadow_iface) + .define("WORKBENCH_NEXT") + .uniform_buf(1, "ShadowPassData", "pass_data") + .define("lightDirection", "vData[0].light_direction_os") + .typedef_source("workbench_shader_shared.h") + .additional_info("draw_view") + .additional_info("draw_modelmat_new") + .additional_info("draw_resource_handle_new"); + +GPU_SHADER_CREATE_INFO(workbench_next_shadow_visibility_compute_common) + .local_group_size(DRW_VISIBILITY_GROUP_SIZE) + .define("DRW_VIEW_LEN", "64") + .storage_buf(0, Qualifier::READ, "ObjectBounds", "bounds_buf[]") + .uniform_buf(2, "ExtrudedFrustum", "extruded_frustum") + .push_constant(Type::INT, "resource_len") + .push_constant(Type::INT, "view_len") + .push_constant(Type::INT, "visibility_word_per_draw") + .push_constant(Type::BOOL, "force_fail_method") + .push_constant(Type::VEC3, "shadow_direction") + .typedef_source("workbench_shader_shared.h") + .compute_source("workbench_shadow_visibility_comp.glsl") + .additional_info("draw_view", "draw_view_culling"); + +GPU_SHADER_CREATE_INFO(workbench_next_shadow_visibility_compute_dynamic_pass_type) + .additional_info("workbench_next_shadow_visibility_compute_common") + .define("DYNAMIC_PASS_SELECTION") + .storage_buf(1, Qualifier::READ_WRITE, "uint", "pass_visibility_buf[]") + .storage_buf(2, Qualifier::READ_WRITE, "uint", "fail_visibility_buf[]") + .do_static_compilation(true); + +GPU_SHADER_CREATE_INFO(workbench_next_shadow_visibility_compute_static_pass_type) + .additional_info("workbench_next_shadow_visibility_compute_common") + .storage_buf(1, Qualifier::READ_WRITE, "uint", "visibility_buf[]") + .do_static_compilation(true); + /** \} */ /* -------------------------------------------------------------------- */ @@ -79,42 +119,64 @@ GPU_SHADER_CREATE_INFO(workbench_shadow_debug) .fragment_out(2, Type::UINT, "objectId") .fragment_source("workbench_shadow_debug_frag.glsl"); +GPU_SHADER_CREATE_INFO(workbench_next_shadow_no_debug) + .additional_info("workbench_shadow_no_debug"); + +GPU_SHADER_CREATE_INFO(workbench_next_shadow_debug).additional_info("workbench_shadow_debug"); + /** \} */ /* -------------------------------------------------------------------- */ /** \name Variations Declaration * \{ */ -#define WORKBENCH_SHADOW_VARIATIONS(suffix, ...) \ - GPU_SHADER_CREATE_INFO(workbench_shadow_pass_manifold_no_caps##suffix) \ +#define WORKBENCH_SHADOW_VARIATIONS(common, prefix, suffix, ...) \ + GPU_SHADER_CREATE_INFO(prefix##_pass_manifold_no_caps##suffix) \ .define("SHADOW_PASS") \ - .additional_info("workbench_shadow_common", "workbench_shadow_manifold", __VA_ARGS__) \ + .additional_info(common, "workbench_shadow_manifold", __VA_ARGS__) \ .do_static_compilation(true); \ - GPU_SHADER_CREATE_INFO(workbench_shadow_pass_no_manifold_no_caps##suffix) \ + GPU_SHADER_CREATE_INFO(prefix##_pass_no_manifold_no_caps##suffix) \ .define("SHADOW_PASS") \ .define("DOUBLE_MANIFOLD") \ - .additional_info("workbench_shadow_common", "workbench_shadow_no_manifold", __VA_ARGS__) \ + .additional_info(common, "workbench_shadow_no_manifold", __VA_ARGS__) \ .do_static_compilation(true); \ - GPU_SHADER_CREATE_INFO(workbench_shadow_fail_manifold_caps##suffix) \ + GPU_SHADER_CREATE_INFO(prefix##_fail_manifold_caps##suffix) \ .define("SHADOW_FAIL") \ - .additional_info("workbench_shadow_common", "workbench_shadow_caps", __VA_ARGS__) \ + .additional_info(common, "workbench_shadow_caps", __VA_ARGS__) \ .do_static_compilation(true); \ - GPU_SHADER_CREATE_INFO(workbench_shadow_fail_manifold_no_caps##suffix) \ + GPU_SHADER_CREATE_INFO(prefix##_fail_manifold_no_caps##suffix) \ .define("SHADOW_FAIL") \ - .additional_info("workbench_shadow_common", "workbench_shadow_manifold", __VA_ARGS__) \ + .additional_info(common, "workbench_shadow_manifold", __VA_ARGS__) \ .do_static_compilation(true); \ - GPU_SHADER_CREATE_INFO(workbench_shadow_fail_no_manifold_caps##suffix) \ + GPU_SHADER_CREATE_INFO(prefix##_fail_no_manifold_caps##suffix) \ .define("SHADOW_FAIL") \ .define("DOUBLE_MANIFOLD") \ - .additional_info("workbench_shadow_common", "workbench_shadow_caps", __VA_ARGS__) \ + .additional_info(common, "workbench_shadow_caps", __VA_ARGS__) \ .do_static_compilation(true); \ - GPU_SHADER_CREATE_INFO(workbench_shadow_fail_no_manifold_no_caps##suffix) \ + GPU_SHADER_CREATE_INFO(prefix##_fail_no_manifold_no_caps##suffix) \ .define("SHADOW_FAIL") \ .define("DOUBLE_MANIFOLD") \ - .additional_info("workbench_shadow_common", "workbench_shadow_no_manifold", __VA_ARGS__) \ + .additional_info(common, "workbench_shadow_no_manifold", __VA_ARGS__) \ .do_static_compilation(true); -WORKBENCH_SHADOW_VARIATIONS(, "workbench_shadow_no_debug") -WORKBENCH_SHADOW_VARIATIONS(_debug, "workbench_shadow_debug") +WORKBENCH_SHADOW_VARIATIONS("workbench_shadow_common", + workbench_shadow, + , + "workbench_shadow_no_debug") + +WORKBENCH_SHADOW_VARIATIONS("workbench_shadow_common", + workbench_shadow, + _debug, + "workbench_shadow_debug") + +WORKBENCH_SHADOW_VARIATIONS("workbench_next_shadow_common", + workbench_next_shadow, + , + "workbench_next_shadow_no_debug") + +WORKBENCH_SHADOW_VARIATIONS("workbench_next_shadow_common", + workbench_next_shadow, + _debug, + "workbench_next_shadow_debug") /** \} */ diff --git a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl index c705a8f12b5..a1a06f68592 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_cavity_lib.glsl @@ -5,6 +5,12 @@ /* From The Alchemy screen-space ambient obscurance algorithm * http://graphics.cs.williams.edu/papers/AlchemyHPG11/VV11AlchemyAO.pdf */ +#ifdef WORKBENCH_CAVITY +# define USE_CAVITY +# define cavityJitter jitter_tx +# define samples_coords cavity_samples +#endif + #ifdef USE_CAVITY void cavity_compute(vec2 screenco, diff --git a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl index 5e43fe27f38..9fd74dc7713 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_composite_frag.glsl @@ -16,18 +16,18 @@ void main() float roughness, metallic; workbench_float_pair_decode(mat_data.a, roughness, metallic); -#ifdef V3D_LIGHTING_MATCAP +#ifdef WORKBENCH_LIGHTING_MATCAP /* When using matcaps, mat_data.a is the back-face sign. */ N = (mat_data.a > 0.0) ? N : -N; fragColor.rgb = get_matcap_lighting(matcap_diffuse_tx, matcap_specular_tx, base_color, N, I); #endif -#ifdef V3D_LIGHTING_STUDIO +#ifdef WORKBENCH_LIGHTING_STUDIO fragColor.rgb = get_world_lighting(base_color, roughness, metallic, N, I); #endif -#ifdef V3D_LIGHTING_FLAT +#ifdef WORKBENCH_LIGHTING_FLAT fragColor.rgb = base_color; #endif diff --git a/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl index a6f7a1f522a..5d120560671 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_curvature_lib.glsl @@ -1,6 +1,10 @@ #pragma BLENDER_REQUIRE(workbench_common_lib.glsl) +#ifdef WORKBENCH_CURVATURE +# define USE_CURVATURE +#endif + #ifdef USE_CURVATURE float curvature_soft_clamp(float curvature, float control) diff --git a/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl index 78782bdc777..b107963575c 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl @@ -27,10 +27,27 @@ bool node_tex_tile_lookup(inout vec3 co, sampler2DArray ima, sampler1DArray map) vec3 workbench_image_color(vec2 uvs) { -#ifdef V3D_SHADING_TEXTURE_COLOR +#ifdef WORKBENCH_COLOR_TEXTURE vec4 color; -# ifdef TEXTURE_IMAGE_ARRAY +# ifdef WORKBENCH_NEXT + + vec3 co = vec3(uvs, 0.0); + if (isImageTile) { + if (node_tex_tile_lookup(co, imageTileArray, imageTileData)) { + color = texture(imageTileArray, co); + } + else { + color = vec4(1.0, 0.0, 1.0, 1.0); + } + } + else { + color = texture(imageTexture, uvs); + } + +# else // WORKBENCH_NEXT + +# ifdef WORKBENCH_TEXTURE_IMAGE_ARRAY vec3 co = vec3(uvs, 0.0); if (node_tex_tile_lookup(co, imageTileArray, imageTileData)) { color = texture(imageTileArray, co); @@ -38,10 +55,12 @@ vec3 workbench_image_color(vec2 uvs) else { color = vec4(1.0, 0.0, 1.0, 1.0); } -# else +# else color = texture(imageTexture, uvs); -# endif +# endif + +# endif // WORKBENCH_NEXT /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */ if (imagePremult && !(color.a == 0.0 || color.a == 1.0)) { diff --git a/source/blender/draw/engines/workbench/shaders/workbench_matcap_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_matcap_lib.glsl index a0cec54251d..b40d20cf8bc 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_matcap_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_matcap_lib.glsl @@ -24,3 +24,14 @@ vec3 get_matcap_lighting( return diffuse * base_color + specular * float(world_data.use_specular); } + +vec3 get_matcap_lighting(sampler2DArray matcap, vec3 base_color, vec3 N, vec3 I) +{ + bool flipped = world_data.matcap_orientation != 0; + vec2 uv = matcap_uv_compute(I, N, flipped); + + vec3 diffuse = textureLod(matcap, vec3(uv, 0.0), 0.0).rgb; + vec3 specular = textureLod(matcap, vec3(uv, 1.0), 0.0).rgb; + + return diffuse * base_color + specular * float(world_data.use_specular); +} diff --git a/source/blender/draw/engines/workbench/shaders/workbench_material_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_material_lib.glsl index b6dc26ecc65..59e30b310bb 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_material_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_material_lib.glsl @@ -1,10 +1,28 @@ -void workbench_material_data_get( - int handle, out vec3 color, out float alpha, out float roughness, out float metallic) + +void workbench_material_data_get(int handle, + vec3 vertex_color, + out vec3 color, + out float alpha, + out float roughness, + out float metallic) { +#ifndef WORKBENCH_NEXT handle = (materialIndex != -1) ? materialIndex : handle; vec4 data = materials_data[uint(handle) & 0xFFFu]; color = data.rgb; + if (materialIndex == 0) { + color_interp = vertex_color; + } +#else + +# ifdef WORKBENCH_COLOR_MATERIAL + vec4 data = materials_data[handle]; +# else + vec4 data = vec4(0.0); +# endif + color = (data.r == -1) ? vertex_color : data.rgb; +#endif uint encoded_data = floatBitsToUint(data.w); alpha = float((encoded_data >> 16u) & 0xFFu) * (1.0 / 255.0); diff --git a/source/blender/draw/engines/workbench/shaders/workbench_next_composite_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_next_composite_frag.glsl new file mode 100644 index 00000000000..7a5b66d0879 --- /dev/null +++ b/source/blender/draw/engines/workbench/shaders/workbench_next_composite_frag.glsl @@ -0,0 +1,81 @@ + +#pragma BLENDER_REQUIRE(common_view_lib.glsl) +#pragma BLENDER_REQUIRE(workbench_common_lib.glsl) +#pragma BLENDER_REQUIRE(workbench_matcap_lib.glsl) +#pragma BLENDER_REQUIRE(workbench_world_light_lib.glsl) +#pragma BLENDER_REQUIRE(workbench_cavity_lib.glsl) +#pragma BLENDER_REQUIRE(workbench_curvature_lib.glsl) + +void main() +{ + vec2 uv = uvcoordsvar.st; + /* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */ + vec3 V = get_view_vector_from_screen_uv(uv); + vec3 N = workbench_normal_decode(texture(normal_tx, uv)); + vec4 mat_data = texture(material_tx, uv); + float depth = texture(depth_tx, uv).r; + + vec3 base_color = mat_data.rgb; + vec4 color = world_data.background_color; + + /* Background pixels. */ + if (depth != 1.0) { +#ifdef WORKBENCH_LIGHTING_MATCAP + /* When using matcaps, mat_data.a is the back-face sign. */ + N = (mat_data.a > 0.0) ? N : -N; + color.rgb = get_matcap_lighting(matcap_tx, base_color, N, V); +#endif + +#ifdef WORKBENCH_LIGHTING_STUDIO + float roughness, metallic; + workbench_float_pair_decode(mat_data.a, roughness, metallic); + color.rgb = get_world_lighting(base_color, roughness, metallic, N, V); +#endif + +#ifdef WORKBENCH_LIGHTING_FLAT + color.rgb = base_color; +#endif + +#if defined(WORKBENCH_CAVITY) || defined(WORKBENCH_CURVATURE) + float cavity = 0.0, edges = 0.0, curvature = 0.0; + +# ifdef WORKBENCH_CAVITY + cavity_compute(uv, depth_tx, normal_tx, cavity, edges); +# endif + +# ifdef WORKBENCH_CURVATURE + curvature_compute(uv, object_id_tx, normal_tx, curvature); +# endif + + float final_cavity_factor = clamp( + (1.0 - cavity) * (1.0 + edges) * (1.0 + curvature), 0.0, 4.0); + + color.rgb *= final_cavity_factor; +#endif + + bool shadow = texture(stencil_tx, uv).r != 0; + color.rgb *= get_shadow(N, shadow); + + color.a = 1.0f; + } + +#ifdef WORKBENCH_OUTLINE + vec3 offset = vec3(world_data.viewport_size_inv, 0.0) * world_data.ui_scale; + + uint center_id = texture(object_id_tx, uv).r; + uvec4 adjacent_ids = uvec4(texture(object_id_tx, uv + offset.zy).r, + texture(object_id_tx, uv - offset.zy).r, + texture(object_id_tx, uv + offset.xz).r, + texture(object_id_tx, uv - offset.xz).r); + + float outline_opacity = 1.0 - dot(vec4(equal(uvec4(center_id), adjacent_ids)), vec4(0.25)); + color = mix(color, world_data.object_outline_color, outline_opacity); +#endif + + if (all(equal(color, world_data.background_color))) { + discard; + } + else { + fragColor = color; + } +} diff --git a/source/blender/draw/engines/workbench/shaders/workbench_next_merge_depth_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_next_merge_depth_frag.glsl new file mode 100644 index 00000000000..70e4c3c5071 --- /dev/null +++ b/source/blender/draw/engines/workbench/shaders/workbench_next_merge_depth_frag.glsl @@ -0,0 +1,11 @@ + +void main() +{ + float depth = texture(depth_tx, uvcoordsvar.xy).r; + if (depth != 1.0) { + gl_FragDepth = depth; + } + else { + discard; + } +} diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl index 82fa65449eb..7758d6d421c 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_frag.glsl @@ -3,20 +3,43 @@ #pragma BLENDER_REQUIRE(workbench_common_lib.glsl) #pragma BLENDER_REQUIRE(workbench_image_lib.glsl) +#ifdef WORKBENCH_NEXT + void main() { - normalData = workbench_normal_encode(gl_FrontFacing, normal_interp); + out_object_id = uint(object_id); + out_normal = workbench_normal_encode(gl_FrontFacing, normal_interp); - materialData = vec4(color_interp, workbench_float_pair_encode(_roughness, metallic)); + out_material = vec4(color_interp, workbench_float_pair_encode(_roughness, metallic)); - objectId = uint(object_id); +# ifdef WORKBENCH_COLOR_TEXTURE + out_material.rgb = workbench_image_color(uv_interp); +# endif + +# ifdef WORKBENCH_LIGHTING_MATCAP + /* For matcaps, save front facing in alpha channel. */ + out_material.a = float(gl_FrontFacing); +# endif +} + +#else + +void main() +{ + out_normal = workbench_normal_encode(gl_FrontFacing, normal_interp); + + out_material = vec4(color_interp, workbench_float_pair_encode(_roughness, metallic)); + + out_object_id = uint(object_id); if (useMatcap) { /* For matcaps, save front facing in alpha channel. */ - materialData.a = float(gl_FrontFacing); + out_material.a = float(gl_FrontFacing); } -#ifdef V3D_SHADING_TEXTURE_COLOR - materialData.rgb = workbench_image_color(uv_interp); -#endif +# ifdef WORKBENCH_COLOR_TEXTURE + out_material.rgb = workbench_image_color(uv_interp); +# endif } + +#endif diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_hair_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_hair_vert.glsl index 04fef8d8b32..afbbca465d4 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_hair_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_hair_vert.glsl @@ -68,11 +68,12 @@ void main() normal_interp = normalize(normal_world_to_view(nor)); - workbench_material_data_get(resource_handle, color_interp, alpha_interp, _roughness, metallic); - - if (materialIndex == 0) { - color_interp = hair_get_customdata_vec3(ac); - } + workbench_material_data_get(resource_handle, + hair_get_customdata_vec3(ac), + color_interp, + alpha_interp, + _roughness, + metallic); /* Hairs have lots of layer and can rapidly become the most prominent surface. * So we lower their alpha artificially. */ diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl index 366bc2f9105..1551b1c8084 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_pointcloud_vert.glsl @@ -19,11 +19,8 @@ void main() uv_interp = vec2(0.0); - workbench_material_data_get(resource_handle, color_interp, alpha_interp, _roughness, metallic); - - if (materialIndex == 0) { - color_interp = vec3(1.0); - } + workbench_material_data_get( + resource_handle, vec3(1.0), color_interp, alpha_interp, _roughness, metallic); object_id = int(uint(resource_handle) & 0xFFFFu) + 1; } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl index 0637f669961..7fcfb9b1c54 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_prepass_vert.glsl @@ -16,11 +16,8 @@ void main() normal_interp = normalize(normal_object_to_view(nor)); - workbench_material_data_get(resource_handle, color_interp, alpha_interp, _roughness, metallic); - - if (materialIndex == 0) { - color_interp = ac.rgb; - } + workbench_material_data_get( + resource_handle, ac.rgb, color_interp, alpha_interp, _roughness, metallic); object_id = int(uint(resource_handle) & 0xFFFFu) + 1; } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl index fa4d5ef4d96..1df514c9081 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_vert.glsl @@ -5,6 +5,18 @@ void main() { vData.pos = pos; vData.frontPosition = point_object_to_ndc(pos); - vec3 back_pos = pos + lightDirection * lightDistance; - vData.backPosition = point_object_to_ndc(back_pos); +#ifdef WORKBENCH_NEXT + vData.light_direction_os = normal_world_to_object(pass_data.light_direction_ws); + vec3 pos_ws = point_object_to_world(pos); + float extrude_distance = 1e5f; + float LDoFP = dot(pass_data.light_direction_ws, pass_data.far_plane.xyz); + if (LDoFP > 0) { + float signed_distance = dot(pass_data.far_plane.xyz, pos_ws) - pass_data.far_plane.w; + extrude_distance = -signed_distance / LDoFP; + } + vData.backPosition = point_world_to_ndc(pos_ws + + pass_data.light_direction_ws * extrude_distance); +#else + vData.backPosition = point_object_to_ndc(pos + lightDirection * lightDistance); +#endif } diff --git a/source/blender/draw/engines/workbench/shaders/workbench_shadow_visibility_comp.glsl b/source/blender/draw/engines/workbench/shaders/workbench_shadow_visibility_comp.glsl new file mode 100644 index 00000000000..aef73672a8a --- /dev/null +++ b/source/blender/draw/engines/workbench/shaders/workbench_shadow_visibility_comp.glsl @@ -0,0 +1,93 @@ + +#pragma BLENDER_REQUIRE(common_math_lib.glsl) +#pragma BLENDER_REQUIRE(common_intersect_lib.glsl) + +shared uint shared_result; + +#ifdef DYNAMIC_PASS_SELECTION +void set_visibility(bool pass, bool fail) +{ + if (!pass) { + atomicAnd(pass_visibility_buf[gl_WorkGroupID.x], ~(1u << gl_LocalInvocationID.x)); + } + if (!fail) { + atomicAnd(fail_visibility_buf[gl_WorkGroupID.x], ~(1u << gl_LocalInvocationID.x)); + } +} +#else +void set_visibility(bool visibility) +{ + if (!visibility) { + atomicAnd(visibility_buf[gl_WorkGroupID.x], ~(1u << gl_LocalInvocationID.x)); + } +} +#endif + +bool is_visible(IsectBox box) +{ + for (int i_plane = 0; i_plane < extruded_frustum.planes_count; i_plane++) { + vec4 plane = extruded_frustum.planes[i_plane]; + bool separating_axis = true; + for (int i_corner = 0; i_corner < 8; i_corner++) { + float signed_distance = dot(box.corners[i_corner], plane.xyz) - plane.w; + if (signed_distance <= 0) { + separating_axis = false; + break; + } + } + if (separating_axis) { + return false; + } + } + return true; +} + +bool intersects_near_plane(IsectBox box) +{ + vec4 near_plane = drw_view_culling.planes[4]; + bool on_positive_side = false; + bool on_negative_side = false; + + for (int i_corner = 0; i_corner < 8; i_corner++) { + for (int i_displace = 0; i_displace < 2; i_displace++) { + vec3 corner = box.corners[i_corner] + (shadow_direction * 1e5f * i_displace); + float signed_distance = dot(corner, -near_plane.xyz) - near_plane.w; + if (signed_distance <= 0) { + on_negative_side = true; + } + else { + on_positive_side = true; + } + if (on_negative_side && on_positive_side) { + return true; + } + } + } + + return false; +} + +void main() +{ + if (gl_GlobalInvocationID.x >= resource_len) { + return; + } + + ObjectBounds bounds = bounds_buf[gl_GlobalInvocationID.x]; + IsectBox box = isect_data_setup(bounds.bounding_corners[0].xyz, + bounds.bounding_corners[1].xyz, + bounds.bounding_corners[2].xyz, + bounds.bounding_corners[3].xyz); + +#ifdef DYNAMIC_PASS_SELECTION + if (is_visible(box)) { + bool use_fail_pass = force_fail_method || intersects_near_plane(box); + set_visibility(!use_fail_pass, use_fail_pass); + } + else { + set_visibility(false, false); + } +#else + set_visibility(is_visible(box)); +#endif +} diff --git a/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl b/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl index cd5ac21688c..ca5bd33bcef 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_transparent_accum_frag.glsl @@ -45,6 +45,8 @@ float calculate_transparent_weight(void) return clamp(w, 1e-2, 3e2); } +#ifdef WORKBENCH_NEXT + void main() { /* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */ @@ -54,28 +56,68 @@ void main() vec3 color = color_interp; -#ifdef V3D_SHADING_TEXTURE_COLOR +# ifdef WORKBENCH_COLOR_TEXTURE color = workbench_image_color(uv_interp); -#endif +# endif -#ifdef V3D_LIGHTING_MATCAP - vec3 shaded_color = get_matcap_lighting(matcap_diffuse_tx, matcap_specular_tx, color, N, I); -#endif +# ifdef WORKBENCH_LIGHTING_MATCAP + vec3 shaded_color = get_matcap_lighting(matcap_tx, color, N, I); +# endif -#ifdef V3D_LIGHTING_STUDIO +# ifdef WORKBENCH_LIGHTING_STUDIO vec3 shaded_color = get_world_lighting(color, _roughness, metallic, N, I); -#endif +# endif -#ifdef V3D_LIGHTING_FLAT +# ifdef WORKBENCH_LIGHTING_FLAT vec3 shaded_color = color; -#endif +# endif + + shaded_color *= get_shadow(N, forceShadowing); + + /* Listing 4 */ + float alpha = alpha_interp * world_data.xray_alpha; + float weight = calculate_transparent_weight() * alpha; + out_transparent_accum = vec4(shaded_color * weight, alpha); + out_revealage_accum = vec4(weight); + + out_object_id = uint(object_id); +} + +#else + +void main() +{ + /* Normal and Incident vector are in viewspace. Lighting is evaluated in viewspace. */ + vec2 uv_viewport = gl_FragCoord.xy * world_data.viewport_size_inv; + vec3 I = get_view_vector_from_screen_uv(uv_viewport); + vec3 N = normalize(normal_interp); + + vec3 color = color_interp; + +# ifdef WORKBENCH_COLOR_TEXTURE + color = workbench_image_color(uv_interp); +# endif + +# ifdef WORKBENCH_LIGHTING_MATCAP + vec3 shaded_color = get_matcap_lighting(matcap_diffuse_tx, matcap_specular_tx, color, N, I); +# endif + +# ifdef WORKBENCH_LIGHTING_STUDIO + vec3 shaded_color = get_world_lighting(color, _roughness, metallic, N, I); +# endif + +# ifdef WORKBENCH_LIGHTING_FLAT + vec3 shaded_color = color; +# endif shaded_color *= get_shadow(N, forceShadowing); /* Listing 4 */ float weight = calculate_transparent_weight() * alpha_interp; - transparentAccum = vec4(shaded_color * weight, alpha_interp); - revealageAccum = vec4(weight); + out_transparent_accum = vec4(shaded_color * weight, alpha_interp); + out_revealage_accum = vec4(weight); - objectId = uint(object_id); + out_object_id = uint(object_id); } + +#endif diff --git a/source/blender/draw/engines/workbench/workbench_defines.hh b/source/blender/draw/engines/workbench/workbench_defines.hh new file mode 100644 index 00000000000..4dfd69d9d50 --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_defines.hh @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#define WB_MATCAP_SLOT 0 +#define WB_TEXTURE_SLOT 1 +#define WB_TILE_ARRAY_SLOT 2 +#define WB_TILE_DATA_SLOT 3 +#define WB_MATERIAL_SLOT 0 +#define WB_WORLD_SLOT 4 + +#define WB_RESOLVE_GROUP_SIZE 8 diff --git a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.cc b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.cc new file mode 100644 index 00000000000..6b0b2e75c27 --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.cc @@ -0,0 +1,311 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "workbench_private.hh" + +#include "BLI_jitter_2d.h" +#include "smaa_textures.h" + +namespace blender::workbench { + +class TaaSamples { + void init_samples(Array &samples, const int size) + { + samples = Array(size); + BLI_jitter_init((float(*)[2])samples.begin(), size); + + /* Find closest element to center */ + int closest_index = 0; + float closest_squared_distance = 1.0f; + + for (int i : samples.index_range()) { + float2 sample = samples[i]; + const float squared_dist = len_squared_v2(sample); + if (squared_dist < closest_squared_distance) { + closest_squared_distance = squared_dist; + closest_index = i; + } + } + + float2 closest_sample = samples[closest_index]; + + for (float2 &sample : samples) { + /* Move jitter samples so that closest sample is in center */ + sample -= closest_sample; + /* Avoid samples outside range (wrap around). */ + sample = {fmodf(sample.x + 0.5f, 1.0f), fmodf(sample.y + 0.5f, 1.0f)}; + /* Recenter the distribution[-1..1]. */ + sample = (sample * 2.0f) - 1.0f; + } + + /* Swap center sample to the start of the array */ + if (closest_index != 0) { + std::swap(samples[0], samples[closest_index]); + } + + /* Sort list based on farthest distance with previous. */ + for (int i = 0; i < size - 2; i++) { + float squared_dist = 0.0; + int index = i; + for (int j = i + 1; j < size; j++) { + const float _squared_dist = len_squared_v2(samples[i] - samples[j]); + if (_squared_dist > squared_dist) { + squared_dist = _squared_dist; + index = j; + } + } + std::swap(samples[i + 1], samples[index]); + } + } + + public: + Array x5; + Array x8; + Array x11; + Array x16; + Array x32; + + TaaSamples() + { + init_samples(x5, 5); + init_samples(x8, 8); + init_samples(x11, 11); + init_samples(x16, 16); + init_samples(x32, 32); + } +}; + +static TaaSamples TAA_SAMPLES = TaaSamples(); + +static float filter_blackman_harris(float x, const float width) +{ + if (x > width * 0.5f) { + return 0.0f; + } + x = 2.0f * M_PI * clamp_f((x / width + 0.5f), 0.0f, 1.0f); + return 0.35875f - 0.48829f * math::cos(x) + 0.14128f * math::cos(2.0f * x) - + 0.01168f * math::cos(3.0f * x); +} + +/* Compute weights for the 3x3 neighborhood using a 1.5px filter. */ +static void setup_taa_weights(const float2 offset, float r_weights[9], float &r_weight_sum) +{ + /* NOTE: If filter width is bigger than 2.0f, then we need to sample more neighborhood. */ + const float filter_width = 2.0f; + r_weight_sum = 0.0f; + int i = 0; + for (int x = -1; x <= 1; x++) { + for (int y = -1; y <= 1; y++, i++) { + float2 sample_co = float2(x, y) - offset; + float r = len_v2(sample_co); + /* fclem: Is radial distance ok here? */ + float weight = filter_blackman_harris(r, filter_width); + r_weight_sum += weight; + r_weights[i] = weight; + } + } +} + +AntiAliasingPass::AntiAliasingPass() +{ + taa_accumulation_sh_ = GPU_shader_create_from_info_name("workbench_taa"); + smaa_edge_detect_sh_ = GPU_shader_create_from_info_name("workbench_smaa_stage_0"); + smaa_aa_weight_sh_ = GPU_shader_create_from_info_name("workbench_smaa_stage_1"); + smaa_resolve_sh_ = GPU_shader_create_from_info_name("workbench_smaa_stage_2"); + + smaa_search_tx_.ensure_2d( + GPU_R8, {SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT}, GPU_TEXTURE_USAGE_SHADER_READ); + GPU_texture_update(smaa_search_tx_, GPU_DATA_UBYTE, searchTexBytes); + GPU_texture_filter_mode(smaa_search_tx_, true); + + smaa_area_tx_.ensure_2d(GPU_RG8, {AREATEX_WIDTH, AREATEX_HEIGHT}, GPU_TEXTURE_USAGE_SHADER_READ); + GPU_texture_update(smaa_area_tx_, GPU_DATA_UBYTE, areaTexBytes); + GPU_texture_filter_mode(smaa_area_tx_, true); +} + +AntiAliasingPass::~AntiAliasingPass() +{ + DRW_SHADER_FREE_SAFE(taa_accumulation_sh_); + DRW_SHADER_FREE_SAFE(smaa_edge_detect_sh_); + DRW_SHADER_FREE_SAFE(smaa_aa_weight_sh_); + DRW_SHADER_FREE_SAFE(smaa_resolve_sh_); +} + +void AntiAliasingPass::init(const SceneState &scene_state) +{ + enabled_ = scene_state.draw_aa; + sample_ = scene_state.sample; + samples_len_ = scene_state.samples_len; +} + +void AntiAliasingPass::sync(SceneResources &resources, int2 resolution) +{ + if (!enabled_) { + taa_accumulation_tx_.free(); + sample0_depth_tx_.free(); + return; + } + + taa_accumulation_tx_.ensure_2d( + GPU_RGBA16F, resolution, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT); + sample0_depth_tx_.ensure_2d(GPU_DEPTH24_STENCIL8, + resolution, + GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT); + + taa_accumulation_ps_.init(); + taa_accumulation_ps_.state_set(sample_ == 0 ? DRW_STATE_WRITE_COLOR : + DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL); + taa_accumulation_ps_.shader_set(taa_accumulation_sh_); + taa_accumulation_ps_.bind_texture("colorBuffer", &resources.color_tx); + taa_accumulation_ps_.push_constant("samplesWeights", weights_, 9); + taa_accumulation_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); + + smaa_edge_detect_ps_.init(); + smaa_edge_detect_ps_.state_set(DRW_STATE_WRITE_COLOR); + smaa_edge_detect_ps_.shader_set(smaa_edge_detect_sh_); + smaa_edge_detect_ps_.bind_texture("colorTex", &taa_accumulation_tx_); + smaa_edge_detect_ps_.push_constant("viewportMetrics", &smaa_viewport_metrics_, 1); + smaa_edge_detect_ps_.clear_color(float4(0.0f)); + smaa_edge_detect_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); + + smaa_aa_weight_ps_.init(); + smaa_aa_weight_ps_.state_set(DRW_STATE_WRITE_COLOR); + smaa_aa_weight_ps_.shader_set(smaa_aa_weight_sh_); + smaa_aa_weight_ps_.bind_texture("edgesTex", &smaa_edge_tx_); + smaa_aa_weight_ps_.bind_texture("areaTex", smaa_area_tx_); + smaa_aa_weight_ps_.bind_texture("searchTex", smaa_search_tx_); + smaa_aa_weight_ps_.push_constant("viewportMetrics", &smaa_viewport_metrics_, 1); + smaa_aa_weight_ps_.clear_color(float4(0.0f)); + smaa_aa_weight_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); + + smaa_resolve_ps_.init(); + smaa_resolve_ps_.state_set(DRW_STATE_WRITE_COLOR); + smaa_resolve_ps_.shader_set(smaa_resolve_sh_); + smaa_resolve_ps_.bind_texture("blendTex", &smaa_weight_tx_); + smaa_resolve_ps_.bind_texture("colorTex", &taa_accumulation_tx_); + smaa_resolve_ps_.push_constant("viewportMetrics", &smaa_viewport_metrics_, 1); + smaa_resolve_ps_.push_constant("mixFactor", &smaa_mix_factor_, 1); + smaa_resolve_ps_.push_constant("taaAccumulatedWeight", &weight_accum_, 1); + smaa_resolve_ps_.clear_color(float4(0.0f)); + smaa_resolve_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); +} + +void AntiAliasingPass::setup_view(View &view, int2 resolution) +{ + if (!enabled_) { + return; + } + + float2 sample_offset; + switch (samples_len_) { + default: + case 5: + sample_offset = TAA_SAMPLES.x5[sample_]; + break; + case 8: + sample_offset = TAA_SAMPLES.x8[sample_]; + break; + case 11: + sample_offset = TAA_SAMPLES.x11[sample_]; + break; + case 16: + sample_offset = TAA_SAMPLES.x16[sample_]; + break; + case 32: + sample_offset = TAA_SAMPLES.x32[sample_]; + break; + } + + setup_taa_weights(sample_offset, weights_, weights_sum_); + + /* TODO(Miguel Pozo): New API equivalent? */ + const DRWView *default_view = DRW_view_default_get(); + float4x4 winmat, viewmat, persmat; + /* Construct new matrices from transform delta */ + DRW_view_winmat_get(default_view, winmat.ptr(), false); + DRW_view_viewmat_get(default_view, viewmat.ptr(), false); + DRW_view_persmat_get(default_view, persmat.ptr(), false); + + window_translate_m4( + winmat.ptr(), persmat.ptr(), sample_offset.x / resolution.x, sample_offset.y / resolution.y); + + view.sync(viewmat, winmat); +} + +void AntiAliasingPass::draw(Manager &manager, + View &view, + SceneResources &resources, + int2 resolution, + GPUTexture *depth_tx, + GPUTexture *color_tx) +{ + if (!enabled_) { + /* TODO(Miguel Pozo): Should render to the input color_tx and depth_tx in the first place. + * This requires the use of TextureRefs with stencil_view() support, + * but whether TextureRef will stay is still TBD. */ + GPU_texture_copy(color_tx, resources.color_tx); + GPU_texture_copy(depth_tx, resources.depth_tx); + return; + } + + /** + * We always do SMAA on top of TAA accumulation, unless the number of samples of TAA is already + * high. This ensure a smoother transition. + * If TAA accumulation is finished, we only blit the result. + */ + const bool last_sample = sample_ + 1 == samples_len_; + const bool taa_finished = sample_ >= samples_len_; + + if (!taa_finished) { + if (sample_ == 0) { + weight_accum_ = 0; + } + /* Accumulate result to the TAA buffer. */ + taa_accumulation_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(taa_accumulation_tx_)); + taa_accumulation_fb_.bind(); + manager.submit(taa_accumulation_ps_, view); + weight_accum_ += weights_sum_; + } + + if (sample_ == 0) { + if (sample0_depth_tx_.is_valid()) { + GPU_texture_copy(sample0_depth_tx_, resources.depth_tx); + } + /* TODO(Miguel Pozo): Should render to the input depth_tx in the first place + * This requires the use of TextureRef with stencil_view() support, + * but whether TextureRef will stay is still TBD. */ + + /* Copy back the saved depth buffer for correct overlays. */ + GPU_texture_copy(depth_tx, resources.depth_tx); + } + else { + /* Copy back the saved depth buffer for correct overlays. */ + GPU_texture_copy(depth_tx, sample0_depth_tx_); + } + + if (!DRW_state_is_image_render() || last_sample) { + smaa_weight_tx_.acquire( + resolution, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT); + smaa_mix_factor_ = 1.0f - clamp_f(sample_ / 4.0f, 0.0f, 1.0f); + smaa_viewport_metrics_ = float4(float2(1.0f / float2(resolution)), resolution); + + /* After a certain point SMAA is no longer necessary. */ + if (smaa_mix_factor_ > 0.0f) { + smaa_edge_tx_.acquire( + resolution, GPU_RG8, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT); + smaa_edge_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(smaa_edge_tx_)); + smaa_edge_fb_.bind(); + manager.submit(smaa_edge_detect_ps_, view); + + smaa_weight_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(smaa_weight_tx_)); + smaa_weight_fb_.bind(); + manager.submit(smaa_aa_weight_ps_, view); + smaa_edge_tx_.release(); + } + smaa_resolve_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(color_tx)); + smaa_resolve_fb_.bind(); + manager.submit(smaa_resolve_ps_, view); + smaa_weight_tx_.release(); + } +} + +} // namespace blender::workbench diff --git a/source/blender/draw/engines/workbench/workbench_effect_cavity.cc b/source/blender/draw/engines/workbench/workbench_effect_cavity.cc new file mode 100644 index 00000000000..30363b19681 --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_effect_cavity.cc @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup draw_engine + * + * Cavity Effect: + * + * We use Screen Space Ambient Occlusion (SSAO) to enhance geometric details of the surfaces. + * We also use a Curvature effect computed only using the surface normals. + * + * This is done as part of the opaque resolve pass. It only affects the opaque surfaces. + */ + +#include "BLI_rand.h" +#include "workbench_private.hh" + +namespace blender::workbench { + +void CavityEffect::init(const SceneState &scene_state, SceneResources &resources) +{ + cavity_enabled_ = scene_state.draw_cavity; + curvature_enabled_ = scene_state.draw_curvature; + + const int ssao_samples = scene_state.scene->display.matcap_ssao_samples; + int sample_count = min_ii(scene_state.samples_len * ssao_samples, max_samples_); + const int max_iter_count = sample_count / ssao_samples; + + sample_ = scene_state.sample % max_iter_count; + + UniformBuffer &world_buf = resources.world_buf; + + world_buf.cavity_sample_start = ssao_samples * sample_; + world_buf.cavity_sample_end = ssao_samples * (sample_ + 1); + + world_buf.cavity_sample_count_inv = 1.0f / (world_buf.cavity_sample_end - + world_buf.cavity_sample_start); + world_buf.cavity_jitter_scale = 1.0f / 64.0f; + + world_buf.cavity_valley_factor = scene_state.shading.cavity_valley_factor; + world_buf.cavity_ridge_factor = scene_state.shading.cavity_ridge_factor; + world_buf.cavity_attenuation = scene_state.scene->display.matcap_ssao_attenuation; + world_buf.cavity_distance = scene_state.scene->display.matcap_ssao_distance; + + world_buf.curvature_ridge = 0.5f / + max_ff(square_f(scene_state.shading.curvature_ridge_factor), 1e-4f); + world_buf.curvature_valley = 0.7f / max_ff(square_f(scene_state.shading.curvature_valley_factor), + 1e-4f); + + if (cavity_enabled_ && sample_count_ != sample_count) { + sample_count_ = sample_count; + load_samples_buf(ssao_samples); + resources.load_jitter_tx(sample_count_); + } +} + +void CavityEffect::load_samples_buf(int ssao_samples) +{ + const float iteration_samples_inv = 1.0f / ssao_samples; + + /* Create disk samples using Hammersley distribution */ + for (int i : IndexRange(sample_count_)) { + float it_add = (i / ssao_samples) * 0.499f; + float r = fmodf((i + 0.5f + it_add) * iteration_samples_inv, 1.0f); + double dphi; + BLI_hammersley_1d(i, &dphi); + + float phi = float(dphi) * 2.0f * M_PI + it_add; + samples_buf[i].x = math::cos(phi); + samples_buf[i].y = math::sin(phi); + /* This deliberately distribute more samples + * at the center of the disk (and thus the shadow). */ + samples_buf[i].z = r; + } + + samples_buf.push_update(); +} + +void CavityEffect::setup_resolve_pass(PassSimple &pass, SceneResources &resources) +{ + if (cavity_enabled_) { + pass.bind_ubo("cavity_samples", samples_buf); + pass.bind_texture("jitter_tx", &resources.jitter_tx, eGPUSamplerState::GPU_SAMPLER_REPEAT); + } + if (curvature_enabled_) { + pass.bind_texture("object_id_tx", &resources.object_id_tx); + } +} + +} // namespace blender::workbench diff --git a/source/blender/draw/engines/workbench/workbench_effect_dof.cc b/source/blender/draw/engines/workbench/workbench_effect_dof.cc new file mode 100644 index 00000000000..7d46703ad35 --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_effect_dof.cc @@ -0,0 +1,271 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup draw_engine + * + * Depth of Field Effect: + * + * We use a gather approach by sampling a lowres version of the color buffer. + * The process can be summarized like this: + * - down-sample the color buffer using a COC (Circle of Confusion) aware down-sample algorithm. + * - do a gather pass using the COC computed in the previous pass. + * - do a median filter to reduce noise amount. + * - composite on top of main color buffer. + * + * This is done after all passes and affects every surfaces. + */ + +#include "workbench_private.hh" + +#include "BKE_camera.h" +#include "DEG_depsgraph_query.h" + +namespace blender::workbench { +/** + * Transform [-1..1] square to unit circle. + */ +static void square_to_circle(float x, float y, float &r, float &T) +{ + if (x > -y) { + if (x > y) { + r = x; + T = M_PI_4 * (y / x); + } + else { + r = y; + T = M_PI_4 * (2 - (x / y)); + } + } + else { + if (x < y) { + r = -x; + T = M_PI_4 * (4 + (y / x)); + } + else { + r = -y; + if (y != 0) { + T = M_PI_4 * (6 - (x / y)); + } + else { + T = 0.0f; + } + } + } +} + +void DofPass::setup_samples() +{ + float4 *sample = samples_buf_.begin(); + for (int i = 0; i <= kernel_radius_; i++) { + for (int j = -kernel_radius_; j <= kernel_radius_; j++) { + for (int k = -kernel_radius_; k <= kernel_radius_; k++) { + if (abs(j) > i || abs(k) > i) { + continue; + } + if (abs(j) < i && abs(k) < i) { + continue; + } + + float2 coord = float2(j, k) / float2(kernel_radius_); + float r = 0; + float T = 0; + square_to_circle(coord.x, coord.y, r, T); + sample->z = r; + + /* Bokeh shape parameterization. */ + if (blades_ > 1.0f) { + float denom = T - (2.0 * M_PI / blades_) * floorf((blades_ * T + M_PI) / (2.0 * M_PI)); + r *= math::cos(M_PI / blades_) / math::cos(denom); + } + + T += rotation_; + + sample->x = r * math::cos(T) * ratio_; + sample->y = r * math::sin(T); + sample->w = 0; + sample++; + } + } + } + samples_buf_.push_update(); +} + +void DofPass::init(const SceneState &scene_state) +{ + enabled_ = scene_state.draw_dof; + + if (!enabled_) { + source_tx_.free(); + coc_halfres_tx_.free(); + return; + } + + if (prepare_sh_ == nullptr) { + prepare_sh_ = GPU_shader_create_from_info_name("workbench_effect_dof_prepare"); + downsample_sh_ = GPU_shader_create_from_info_name("workbench_effect_dof_downsample"); + blur1_sh_ = GPU_shader_create_from_info_name("workbench_effect_dof_blur1"); + blur2_sh_ = GPU_shader_create_from_info_name("workbench_effect_dof_blur2"); + resolve_sh_ = GPU_shader_create_from_info_name("workbench_effect_dof_resolve"); + } + + offset_ = scene_state.sample / float(scene_state.samples_len); + + int2 half_res = scene_state.resolution / 2; + half_res = {max_ii(half_res.x, 1), max_ii(half_res.y, 1)}; + + source_tx_.ensure_2d(GPU_RGBA16F, half_res, GPU_TEXTURE_USAGE_SHADER_READ, nullptr, 3); + source_tx_.ensure_mip_views(); + source_tx_.filter_mode(true); + coc_halfres_tx_.ensure_2d(GPU_RG8, half_res, GPU_TEXTURE_USAGE_SHADER_READ, nullptr, 3); + coc_halfres_tx_.ensure_mip_views(); + coc_halfres_tx_.filter_mode(true); + + Camera *camera = scene_state.camera; + + /* Parameters */ + float fstop = camera->dof.aperture_fstop; + float sensor = BKE_camera_sensor_size(camera->sensor_fit, camera->sensor_x, camera->sensor_y); + float focus_dist = BKE_camera_object_dof_distance(scene_state.camera_object); + float focal_len = camera->lens; + + /* TODO(fclem): De-duplicate with EEVEE. */ + const float scale_camera = 0.001f; + /* We want radius here for the aperture number. */ + float aperture = 0.5f * scale_camera * focal_len / fstop; + float focal_len_scaled = scale_camera * focal_len; + float sensor_scaled = scale_camera * sensor; + + if (RegionView3D *rv3d = DRW_context_state_get()->rv3d) { + sensor_scaled *= rv3d->viewcamtexcofac[0]; + } + + aperture_size_ = aperture * fabsf(focal_len_scaled / (focus_dist - focal_len_scaled)); + distance_ = -focus_dist; + invsensor_size_ = scene_state.resolution.x / sensor_scaled; + + near_ = -camera->clip_start; + far_ = -camera->clip_end; + + float blades = camera->dof.aperture_blades; + float rotation = camera->dof.aperture_rotation; + float ratio = 1.0f / camera->dof.aperture_ratio; + + if (blades_ != blades || rotation_ != rotation || ratio_ != ratio) { + blades_ = blades; + rotation_ = rotation; + ratio_ = ratio; + setup_samples(); + } +} + +void DofPass::sync(SceneResources &resources) +{ + if (!enabled_) { + return; + } + + eGPUSamplerState sampler_state = GPU_SAMPLER_FILTER | GPU_SAMPLER_MIPMAP; + + down_ps_.init(); + down_ps_.state_set(DRW_STATE_WRITE_COLOR); + down_ps_.shader_set(prepare_sh_); + down_ps_.bind_texture("sceneColorTex", &resources.color_tx); + down_ps_.bind_texture("sceneDepthTex", &resources.depth_tx); + down_ps_.push_constant("invertedViewportSize", float2(DRW_viewport_invert_size_get())); + down_ps_.push_constant("dofParams", float3(aperture_size_, distance_, invsensor_size_)); + down_ps_.push_constant("nearFar", float2(near_, far_)); + down_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); + + down2_ps_.init(); + down2_ps_.state_set(DRW_STATE_WRITE_COLOR); + down2_ps_.shader_set(downsample_sh_); + down2_ps_.bind_texture("sceneColorTex", &source_tx_, sampler_state); + down2_ps_.bind_texture("inputCocTex", &coc_halfres_tx_, sampler_state); + down2_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); + + blur_ps_.init(); + blur_ps_.state_set(DRW_STATE_WRITE_COLOR); + blur_ps_.shader_set(blur1_sh_); + blur_ps_.bind_ubo("samples", samples_buf_); + blur_ps_.bind_texture("noiseTex", resources.jitter_tx); + blur_ps_.bind_texture("inputCocTex", &coc_halfres_tx_, sampler_state); + blur_ps_.bind_texture("halfResColorTex", &source_tx_, sampler_state); + blur_ps_.push_constant("invertedViewportSize", float2(DRW_viewport_invert_size_get())); + blur_ps_.push_constant("noiseOffset", offset_); + blur_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); + + blur2_ps_.init(); + blur2_ps_.state_set(DRW_STATE_WRITE_COLOR); + blur2_ps_.shader_set(blur2_sh_); + blur2_ps_.bind_texture("inputCocTex", &coc_halfres_tx_, sampler_state); + blur2_ps_.bind_texture("blurTex", &blur_tx_); + blur2_ps_.push_constant("invertedViewportSize", float2(DRW_viewport_invert_size_get())); + blur2_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); + + resolve_ps_.init(); + resolve_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_CUSTOM); + resolve_ps_.shader_set(resolve_sh_); + resolve_ps_.bind_texture("halfResColorTex", &source_tx_, sampler_state); + resolve_ps_.bind_texture("sceneDepthTex", &resources.depth_tx); + resolve_ps_.push_constant("invertedViewportSize", float2(DRW_viewport_invert_size_get())); + resolve_ps_.push_constant("dofParams", float3(aperture_size_, distance_, invsensor_size_)); + resolve_ps_.push_constant("nearFar", float2(near_, far_)); + resolve_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); +} + +void DofPass::draw(Manager &manager, View &view, SceneResources &resources, int2 resolution) +{ + if (!enabled_) { + return; + } + + DRW_stats_group_start("Depth Of Field"); + + int2 half_res = {max_ii(resolution.x / 2, 1), max_ii(resolution.y / 2, 1)}; + blur_tx_.acquire( + half_res, GPU_RGBA16F, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT); + + downsample_fb_.ensure(GPU_ATTACHMENT_NONE, + GPU_ATTACHMENT_TEXTURE(source_tx_), + GPU_ATTACHMENT_TEXTURE(coc_halfres_tx_)); + downsample_fb_.bind(); + manager.submit(down_ps_, view); + + struct CallbackData { + Manager &manager; + View &view; + PassSimple &pass; + }; + CallbackData callback_data = {manager, view, down2_ps_}; + + auto downsample_level = [](void *callback_data, int /*level*/) { + CallbackData *cd = static_cast(callback_data); + cd->manager.submit(cd->pass, cd->view); + }; + + GPU_framebuffer_recursive_downsample( + downsample_fb_, 2, downsample_level, static_cast(&callback_data)); + + blur1_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(blur_tx_)); + blur1_fb_.bind(); + manager.submit(blur_ps_, view); + + blur2_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(source_tx_)); + blur2_fb_.bind(); + manager.submit(blur2_ps_, view); + + resolve_fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx)); + resolve_fb_.bind(); + manager.submit(resolve_ps_, view); + + blur_tx_.release(); + + DRW_stats_group_end(); +} + +bool DofPass::is_enabled() +{ + return enabled_; +} + +} // namespace blender::workbench diff --git a/source/blender/draw/engines/workbench/workbench_effect_outline.cc b/source/blender/draw/engines/workbench/workbench_effect_outline.cc new file mode 100644 index 00000000000..18b8b484aef --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_effect_outline.cc @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup draw_engine + * + * Outline Effect: + * + * Simple effect that just samples an object id buffer to detect objects outlines. + */ + +#include "workbench_private.hh" + +namespace blender::workbench { + +void OutlinePass::init(const SceneState &scene_state) +{ + enabled_ = scene_state.draw_outline; + if (!enabled_) { + return; + } + + if (sh_ == nullptr) { + sh_ = GPU_shader_create_from_info_name("workbench_effect_outline"); + } +} + +void OutlinePass::sync(SceneResources &resources) +{ + if (!enabled_) { + return; + } + + ps_.init(); + ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA_PREMUL); + ps_.shader_set(sh_); + ps_.bind_ubo("world_data", resources.world_buf); + ps_.bind_texture("objectIdBuffer", &resources.object_id_tx); + ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); +} + +void OutlinePass::draw(Manager &manager, View &view, SceneResources &resources, int2 resolution) +{ + if (!enabled_) { + return; + } + + fb_.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx)); + fb_.bind(); + manager.submit(ps_); +} + +} // namespace blender::workbench diff --git a/source/blender/draw/engines/workbench/workbench_engine.cc b/source/blender/draw/engines/workbench/workbench_engine.cc new file mode 100644 index 00000000000..a04f61418f6 --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_engine.cc @@ -0,0 +1,737 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BKE_editmesh.h" +#include "BKE_modifier.h" +#include "BKE_object.h" +#include "BKE_paint.h" +#include "BKE_particle.h" +#include "BKE_pbvh.h" +#include "BKE_report.h" +#include "DEG_depsgraph_query.h" +#include "DNA_fluid_types.h" +#include "ED_paint.h" +#include "ED_view3d.h" +#include "GPU_capabilities.h" + +#include "workbench_private.hh" + +namespace blender::workbench { + +using namespace draw; + +class Instance { + public: + View view = {"DefaultView"}; + + SceneState scene_state; + + SceneResources resources; + + OpaquePass opaque_ps; + TransparentPass transparent_ps; + TransparentDepthPass transparent_depth_ps; + + ShadowPass shadow_ps; + OutlinePass outline_ps; + DofPass dof_ps; + AntiAliasingPass anti_aliasing_ps; + + /* An array of nullptr GPUMaterial pointers so we can call DRW_cache_object_surface_material_get. + * They never get actually used. */ + Vector dummy_gpu_materials = {1, nullptr, {}}; + GPUMaterial **get_dummy_gpu_materials(int material_count) + { + if (material_count > dummy_gpu_materials.size()) { + dummy_gpu_materials.resize(material_count, nullptr); + } + return dummy_gpu_materials.begin(); + }; + + void init(Object *camera_ob = nullptr) + { + scene_state.init(camera_ob); + shadow_ps.init(scene_state, resources); + resources.init(scene_state); + + outline_ps.init(scene_state); + dof_ps.init(scene_state); + anti_aliasing_ps.init(scene_state); + } + + void begin_sync() + { + const float2 viewport_size = DRW_viewport_size_get(); + const int2 resolution = {int(viewport_size.x), int(viewport_size.y)}; + resources.depth_tx.ensure_2d(GPU_DEPTH24_STENCIL8, + resolution, + GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT | + GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW); + + opaque_ps.sync(scene_state, resources); + transparent_ps.sync(scene_state, resources); + transparent_depth_ps.sync(scene_state, resources); + + shadow_ps.sync(); + outline_ps.sync(resources); + dof_ps.sync(resources); + anti_aliasing_ps.sync(resources, scene_state.resolution); + } + + void end_sync() + { + resources.material_buf.push_update(); + } + + void object_sync(Manager &manager, ObjectRef &ob_ref) + { + if (scene_state.render_finished) { + return; + } + + Object *ob = ob_ref.object; + if (!DRW_object_is_renderable(ob)) { + return; + } + + const ObjectState object_state = ObjectState(scene_state, ob); + + /* Needed for mesh cache validation, to prevent two copies of + * of vertex color arrays from being sent to the GPU (e.g. + * when switching from eevee to workbench). + */ + if (ob_ref.object->sculpt && ob_ref.object->sculpt->pbvh) { + BKE_pbvh_is_drawing_set(ob_ref.object->sculpt->pbvh, object_state.sculpt_pbvh); + } + + if (ob->type == OB_MESH && ob->modifiers.first != nullptr) { + + LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) { + if (md->type != eModifierType_ParticleSystem) { + continue; + } + ParticleSystem *psys = ((ParticleSystemModifierData *)md)->psys; + if (!DRW_object_is_visible_psys_in_active_context(ob, psys)) { + continue; + } + ParticleSettings *part = psys->part; + const int draw_as = (part->draw_as == PART_DRAW_REND) ? part->ren_as : part->draw_as; + + if (draw_as == PART_DRAW_PATH) { + /* TODO(Miguel Pozo): + workbench_cache_hair_populate( + wpd, ob, psys, md, object_state.color_type, object_state.texture_paint_mode, + part->omat); + */ + } + } + } + + if (!(ob->base_flag & BASE_FROM_DUPLI)) { + ModifierData *md = BKE_modifiers_findby_type(ob, eModifierType_Fluid); + if (md && BKE_modifier_is_enabled(scene_state.scene, md, eModifierMode_Realtime)) { + FluidModifierData *fmd = (FluidModifierData *)md; + if (fmd->domain) { + /* TODO(Miguel Pozo): + workbench_volume_cache_populate(vedata, wpd->scene, ob, md, V3D_SHADING_SINGLE_COLOR); + */ + if (fmd->domain->type == FLUID_DOMAIN_TYPE_GAS) { + return; /* Do not draw solid in this case. */ + } + } + } + } + + if (!(DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF)) { + return; + } + + if ((ob->dt < OB_SOLID) && !DRW_state_is_scene_render()) { + return; + } + + if (ELEM(ob->type, OB_MESH, OB_POINTCLOUD)) { + mesh_sync(manager, ob_ref, object_state); + } + else if (ob->type == OB_CURVES) { + /* TODO(Miguel Pozo): + DRWShadingGroup *grp = workbench_material_hair_setup( + wpd, ob, CURVES_MATERIAL_NR, object_state.color_type); + DRW_shgroup_curves_create_sub(ob, grp, NULL); + */ + } + else if (ob->type == OB_VOLUME) { + if (scene_state.shading.type != OB_WIRE) { + /* TODO(Miguel Pozo): + workbench_volume_cache_populate(vedata, wpd->scene, ob, NULL, object_state.color_type); + */ + } + } + } + + void mesh_sync(Manager &manager, ObjectRef &ob_ref, const ObjectState &object_state) + { + ResourceHandle handle = manager.resource_handle(ob_ref); + bool has_transparent_material = false; + + if (object_state.sculpt_pbvh) { + /* TODO(Miguel Pozo): + workbench_cache_sculpt_populate(wpd, ob, object_state.color_type); + */ + } + else { + if (object_state.use_per_material_batches) { + const int material_count = DRW_cache_object_material_count_get(ob_ref.object); + + struct GPUBatch **batches; + if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) { + batches = DRW_cache_mesh_surface_texpaint_get(ob_ref.object); + } + else { + batches = DRW_cache_object_surface_material_get( + ob_ref.object, get_dummy_gpu_materials(material_count), material_count); + } + + if (batches) { + for (auto i : IndexRange(material_count)) { + if (batches[i] == nullptr) { + continue; + } + /* TODO(fclem): This create a cull-able instance for each sub-object. This is done + * for simplicity to reduce complexity. But this increase the overhead per object. + * Instead, we should use an indirection buffer to the material buffer. */ + ResourceHandle _handle = i == 0 ? handle : manager.resource_handle(ob_ref); + + Material &mat = resources.material_buf.get_or_resize(_handle.resource_index()); + + if (::Material *_mat = BKE_object_material_get_eval(ob_ref.object, i + 1)) { + mat = Material(*_mat); + } + else { + mat = Material(*BKE_material_default_empty()); + } + + has_transparent_material = has_transparent_material || mat.is_transparent(); + + ::Image *image = nullptr; + ImageUser *iuser = nullptr; + eGPUSamplerState sampler_state = eGPUSamplerState::GPU_SAMPLER_DEFAULT; + if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) { + get_material_image(ob_ref.object, i + 1, image, iuser, sampler_state); + } + + draw_mesh(ob_ref, mat, batches[i], _handle, image, sampler_state, iuser); + } + } + } + else { + struct GPUBatch *batch; + if (object_state.color_type == V3D_SHADING_TEXTURE_COLOR) { + batch = DRW_cache_mesh_surface_texpaint_single_get(ob_ref.object); + } + else if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) { + if (ob_ref.object->mode & OB_MODE_VERTEX_PAINT) { + batch = DRW_cache_mesh_surface_vertpaint_get(ob_ref.object); + } + else { + batch = DRW_cache_mesh_surface_sculptcolors_get(ob_ref.object); + } + } + else { + batch = DRW_cache_object_surface_get(ob_ref.object); + } + + if (batch) { + Material &mat = resources.material_buf.get_or_resize(handle.resource_index()); + + if (object_state.color_type == V3D_SHADING_OBJECT_COLOR) { + mat = Material(*ob_ref.object); + } + else if (object_state.color_type == V3D_SHADING_RANDOM_COLOR) { + mat = Material(*ob_ref.object, true); + } + else if (object_state.color_type == V3D_SHADING_SINGLE_COLOR) { + mat = scene_state.material_override; + } + else if (object_state.color_type == V3D_SHADING_VERTEX_COLOR) { + mat = scene_state.material_attribute_color; + } + else { + mat = Material(*BKE_material_default_empty()); + } + + has_transparent_material = has_transparent_material || mat.is_transparent(); + + draw_mesh(ob_ref, + mat, + batch, + handle, + object_state.image_paint_override, + object_state.override_sampler_state); + } + } + } + + if (object_state.draw_shadow) { + shadow_ps.object_sync(manager, scene_state, ob_ref, handle, has_transparent_material); + } + } + + void draw_mesh(ObjectRef &ob_ref, + Material &material, + GPUBatch *batch, + ResourceHandle handle, + ::Image *image = nullptr, + eGPUSamplerState sampler_state = GPU_SAMPLER_DEFAULT, + ImageUser *iuser = nullptr) + { + const bool in_front = (ob_ref.object->dtx & OB_DRAW_IN_FRONT) != 0; + + auto draw = [&](MeshPass &pass) { + pass.draw(ob_ref, batch, handle, image, sampler_state, iuser); + }; + + if (scene_state.xray_mode || material.is_transparent()) { + if (in_front) { + draw(transparent_ps.accumulation_in_front_ps_); + if (scene_state.draw_transparent_depth) { + draw(transparent_depth_ps.in_front_ps_); + } + } + else { + draw(transparent_ps.accumulation_ps_); + if (scene_state.draw_transparent_depth) { + draw(transparent_depth_ps.main_ps_); + } + } + } + else { + if (in_front) { + draw(opaque_ps.gbuffer_in_front_ps_); + } + else { + draw(opaque_ps.gbuffer_ps_); + } + } + } + + void draw(Manager &manager, GPUTexture *depth_tx, GPUTexture *color_tx) + { + view.sync(DRW_view_default_get()); + + int2 resolution = scene_state.resolution; + + if (scene_state.render_finished) { + /* Just copy back the already rendered result */ + anti_aliasing_ps.draw(manager, view, resources, resolution, depth_tx, color_tx); + return; + } + + anti_aliasing_ps.setup_view(view, resolution); + + resources.color_tx.acquire( + resolution, GPU_RGBA16F, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT); + resources.color_tx.clear(resources.world_buf.background_color); + if (scene_state.draw_object_id) { + resources.object_id_tx.acquire( + resolution, GPU_R16UI, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT); + resources.object_id_tx.clear(uint4(0)); + } + + Framebuffer fb = Framebuffer("Workbench.Clear"); + fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx)); + fb.bind(); + GPU_framebuffer_clear_depth_stencil(fb, 1.0f, 0x00); + + if (!transparent_ps.accumulation_in_front_ps_.is_empty()) { + resources.depth_in_front_tx.acquire(resolution, + GPU_DEPTH24_STENCIL8, + GPU_TEXTURE_USAGE_SHADER_READ | + GPU_TEXTURE_USAGE_ATTACHMENT); + if (opaque_ps.gbuffer_in_front_ps_.is_empty()) { + /* Clear only if it wont be overwitten by opaque_ps */ + Framebuffer fb = Framebuffer("Workbench.Clear"); + fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_in_front_tx)); + fb.bind(); + GPU_framebuffer_clear_depth_stencil(fb, 1.0f, 0x00); + } + } + + opaque_ps.draw(manager, + view, + resources, + resolution, + &shadow_ps, + transparent_ps.accumulation_ps_.is_empty()); + transparent_ps.draw(manager, view, resources, resolution); + transparent_depth_ps.draw(manager, view, resources, resolution); + + // volume_ps.draw_prepass(manager, view, resources.depth_tx); + + outline_ps.draw(manager, view, resources, resolution); + dof_ps.draw(manager, view, resources, resolution); + anti_aliasing_ps.draw(manager, view, resources, resolution, depth_tx, color_tx); + + resources.color_tx.release(); + resources.object_id_tx.release(); + resources.depth_in_front_tx.release(); + } + + void draw_viewport(Manager &manager, GPUTexture *depth_tx, GPUTexture *color_tx) + { + this->draw(manager, depth_tx, color_tx); + + if (scene_state.sample + 1 < scene_state.samples_len) { + DRW_viewport_request_redraw(); + } + } +}; + +} // namespace blender::workbench + +/* -------------------------------------------------------------------- */ +/** \name Interface with legacy C DRW manager + * \{ */ + +using namespace blender; + +struct WORKBENCH_Data { + DrawEngineType *engine_type; + DRWViewportEmptyList *fbl; + DRWViewportEmptyList *txl; + DRWViewportEmptyList *psl; + DRWViewportEmptyList *stl; + workbench::Instance *instance; + + char info[GPU_INFO_SIZE]; +}; + +static void workbench_engine_init(void *vedata) +{ + /* TODO(fclem): Remove once it is minimum required. */ + if (!GPU_shader_storage_buffer_objects_support()) { + return; + } + + WORKBENCH_Data *ved = reinterpret_cast(vedata); + if (ved->instance == nullptr) { + ved->instance = new workbench::Instance(); + } + + ved->instance->init(); +} + +static void workbench_cache_init(void *vedata) +{ + if (!GPU_shader_storage_buffer_objects_support()) { + return; + } + reinterpret_cast(vedata)->instance->begin_sync(); +} + +static void workbench_cache_populate(void *vedata, Object *object) +{ + if (!GPU_shader_storage_buffer_objects_support()) { + return; + } + draw::Manager *manager = DRW_manager_get(); + + draw::ObjectRef ref; + ref.object = object; + ref.dupli_object = DRW_object_get_dupli(object); + ref.dupli_parent = DRW_object_get_dupli_parent(object); + + reinterpret_cast(vedata)->instance->object_sync(*manager, ref); +} + +static void workbench_cache_finish(void *vedata) +{ + if (!GPU_shader_storage_buffer_objects_support()) { + return; + } + reinterpret_cast(vedata)->instance->end_sync(); +} + +static void workbench_draw_scene(void *vedata) +{ + WORKBENCH_Data *ved = reinterpret_cast(vedata); + if (!GPU_shader_storage_buffer_objects_support()) { + STRNCPY(ved->info, "Error: No shader storage buffer support"); + return; + } + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + draw::Manager *manager = DRW_manager_get(); + ved->instance->draw_viewport(*manager, dtxl->depth, dtxl->color); +} + +static void workbench_instance_free(void *instance) +{ + if (!GPU_shader_storage_buffer_objects_support()) { + return; + } + delete reinterpret_cast(instance); +} + +static void workbench_view_update(void *vedata) +{ + WORKBENCH_Data *ved = reinterpret_cast(vedata); + if (ved->instance) { + ved->instance->scene_state.reset_taa_next_sample = true; + } +} + +static void workbench_id_update(void *vedata, struct ID *id) +{ + UNUSED_VARS(vedata, id); +} + +/* RENDER */ + +static bool workbench_render_framebuffers_init(void) +{ + /* For image render, allocate own buffers because we don't have a viewport. */ + const float2 viewport_size = DRW_viewport_size_get(); + const int2 size = {int(viewport_size.x), int(viewport_size.y)}; + + DefaultTextureList *dtxl = DRW_viewport_texture_list_get(); + + /* When doing a multi view rendering the first view will allocate the buffers + * the other views will reuse these buffers */ + if (dtxl->color == nullptr) { + BLI_assert(dtxl->depth == nullptr); + dtxl->color = GPU_texture_create_2d("txl.color", size.x, size.y, 1, GPU_RGBA16F, nullptr); + dtxl->depth = GPU_texture_create_2d( + "txl.depth", size.x, size.y, 1, GPU_DEPTH24_STENCIL8, nullptr); + } + + if (!(dtxl->depth && dtxl->color)) { + return false; + } + + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + + GPU_framebuffer_ensure_config( + &dfbl->default_fb, + {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_TEXTURE(dtxl->color)}); + + GPU_framebuffer_ensure_config(&dfbl->depth_only_fb, + {GPU_ATTACHMENT_TEXTURE(dtxl->depth), GPU_ATTACHMENT_NONE}); + + GPU_framebuffer_ensure_config(&dfbl->color_only_fb, + {GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(dtxl->color)}); + + return GPU_framebuffer_check_valid(dfbl->default_fb, nullptr) && + GPU_framebuffer_check_valid(dfbl->color_only_fb, nullptr) && + GPU_framebuffer_check_valid(dfbl->depth_only_fb, nullptr); +} + +#ifdef DEBUG +/* This is just to ease GPU debugging when the frame delimiter is set to Finish */ +# define GPU_FINISH_DELIMITER() GPU_finish() +#else +# define GPU_FINISH_DELIMITER() +#endif + +static void write_render_color_output(struct RenderLayer *layer, + const char *viewname, + GPUFrameBuffer *fb, + const struct rcti *rect) +{ + RenderPass *rp = RE_pass_find_by_name(layer, RE_PASSNAME_COMBINED, viewname); + if (rp) { + GPU_framebuffer_bind(fb); + GPU_framebuffer_read_color(fb, + rect->xmin, + rect->ymin, + BLI_rcti_size_x(rect), + BLI_rcti_size_y(rect), + 4, + 0, + GPU_DATA_FLOAT, + rp->rect); + } +} + +static void write_render_z_output(struct RenderLayer *layer, + const char *viewname, + GPUFrameBuffer *fb, + const struct rcti *rect, + float4x4 winmat) +{ + RenderPass *rp = RE_pass_find_by_name(layer, RE_PASSNAME_Z, viewname); + if (rp) { + GPU_framebuffer_bind(fb); + GPU_framebuffer_read_depth(fb, + rect->xmin, + rect->ymin, + BLI_rcti_size_x(rect), + BLI_rcti_size_y(rect), + GPU_DATA_FLOAT, + rp->rect); + + int pix_num = BLI_rcti_size_x(rect) * BLI_rcti_size_y(rect); + + /* Convert ogl depth [0..1] to view Z [near..far] */ + if (DRW_view_is_persp_get(nullptr)) { + for (float &z : MutableSpan(rp->rect, pix_num)) { + if (z == 1.0f) { + z = 1e10f; /* Background */ + } + else { + z = z * 2.0f - 1.0f; + z = winmat[3][2] / (z + winmat[2][2]); + } + } + } + else { + /* Keep in mind, near and far distance are negatives. */ + float near = DRW_view_near_distance_get(nullptr); + float far = DRW_view_far_distance_get(nullptr); + float range = fabsf(far - near); + + for (float &z : MutableSpan(rp->rect, pix_num)) { + if (z == 1.0f) { + z = 1e10f; /* Background */ + } + else { + z = z * range - near; + } + } + } + } +} + +static void workbench_render_to_image(void *vedata, + struct RenderEngine *engine, + struct RenderLayer *layer, + const struct rcti *rect) +{ + /* TODO(fclem): Remove once it is minimum required. */ + if (!GPU_shader_storage_buffer_objects_support()) { + return; + } + + if (!workbench_render_framebuffers_init()) { + RE_engine_report(engine, RPT_ERROR, "Failed to allocate GPU buffers"); + return; + } + + GPU_FINISH_DELIMITER(); + + /* Setup */ + + DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get(); + const DRWContextState *draw_ctx = DRW_context_state_get(); + Depsgraph *depsgraph = draw_ctx->depsgraph; + + WORKBENCH_Data *ved = reinterpret_cast(vedata); + if (ved->instance == nullptr) { + ved->instance = new workbench::Instance(); + } + + /* TODO(sergey): Shall render hold pointer to an evaluated camera instead? */ + Object *camera_ob = DEG_get_evaluated_object(depsgraph, RE_GetCamera(engine->re)); + + /* Set the perspective, view and window matrix. */ + float4x4 winmat, viewmat, viewinv; + RE_GetCameraWindow(engine->re, camera_ob, winmat.ptr()); + RE_GetCameraModelMatrix(engine->re, camera_ob, viewinv.ptr()); + viewmat = viewinv.inverted(); + + DRWView *view = DRW_view_create(viewmat.ptr(), winmat.ptr(), nullptr, nullptr, nullptr); + DRW_view_default_set(view); + DRW_view_set_active(view); + + /* Render */ + do { + if (RE_engine_test_break(engine)) { + break; + } + + ved->instance->init(camera_ob); + + DRW_manager_get()->begin_sync(); + + workbench_cache_init(vedata); + auto workbench_render_cache = [](void *vedata, + struct Object *ob, + struct RenderEngine * /*engine*/, + struct Depsgraph * /*depsgraph*/) { + workbench_cache_populate(vedata, ob); + }; + DRW_render_object_iter(vedata, engine, depsgraph, workbench_render_cache); + workbench_cache_finish(vedata); + + DRW_manager_get()->end_sync(); + + /* Also we weed to have a correct FBO bound for #DRW_curves_update */ + // GPU_framebuffer_bind(dfbl->default_fb); + // DRW_curves_update(); /* TODO(Miguel Pozo): Check this once curves are implemented */ + + workbench_draw_scene(vedata); + + /* Perform render step between samples to allow + * flushing of freed GPUBackend resources. */ + GPU_render_step(); + GPU_FINISH_DELIMITER(); + } while (ved->instance->scene_state.sample + 1 < ved->instance->scene_state.samples_len); + + const char *viewname = RE_GetActiveRenderView(engine->re); + write_render_color_output(layer, viewname, dfbl->default_fb, rect); + write_render_z_output(layer, viewname, dfbl->default_fb, rect, winmat); +} + +static void workbench_render_update_passes(RenderEngine *engine, + Scene *scene, + ViewLayer *view_layer) +{ + if (view_layer->passflag & SCE_PASS_COMBINED) { + RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA); + } + if (view_layer->passflag & SCE_PASS_Z) { + RE_engine_register_pass(engine, scene, view_layer, RE_PASSNAME_Z, 1, "Z", SOCK_FLOAT); + } +} + +extern "C" { + +static const DrawEngineDataSize workbench_data_size = DRW_VIEWPORT_DATA_SIZE(WORKBENCH_Data); + +DrawEngineType draw_engine_workbench_next = { + nullptr, + nullptr, + N_("Workbench"), + &workbench_data_size, + &workbench_engine_init, + nullptr, + &workbench_instance_free, + &workbench_cache_init, + &workbench_cache_populate, + &workbench_cache_finish, + &workbench_draw_scene, + &workbench_view_update, + &workbench_id_update, + &workbench_render_to_image, + nullptr, +}; + +RenderEngineType DRW_engine_viewport_workbench_next_type = { + nullptr, + nullptr, + "BLENDER_WORKBENCH_NEXT", + N_("Workbench Next"), + RE_INTERNAL | RE_USE_STEREO_VIEWPORT | RE_USE_GPU_CONTEXT, + nullptr, + &DRW_render_to_image, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + &workbench_render_update_passes, + &draw_engine_workbench_next, + {nullptr, nullptr, nullptr}, +}; +} + +/** \} */ diff --git a/source/blender/draw/engines/workbench/workbench_engine.h b/source/blender/draw/engines/workbench/workbench_engine.h index 6f6f2143868..1b48acd8054 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.h +++ b/source/blender/draw/engines/workbench/workbench_engine.h @@ -8,3 +8,4 @@ #pragma once extern RenderEngineType DRW_engine_viewport_workbench_type; +extern RenderEngineType DRW_engine_viewport_workbench_next_type; diff --git a/source/blender/draw/engines/workbench/workbench_enums.hh b/source/blender/draw/engines/workbench/workbench_enums.hh new file mode 100644 index 00000000000..56f0c3accee --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_enums.hh @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "BLI_assert.h" +#include "DNA_object_types.h" +#include "DNA_view3d_enums.h" + +namespace blender::workbench { + +enum class eGeometryType { + MESH = 0, + CURVES, + POINTCLOUD, +}; +static constexpr int geometry_type_len = static_cast(eGeometryType::POINTCLOUD) + 1; + +static inline const char *get_name(eGeometryType type) +{ + switch (type) { + case eGeometryType::MESH: + return "Mesh"; + case eGeometryType::CURVES: + return "Curves"; + case eGeometryType::POINTCLOUD: + return "PointCloud"; + default: + BLI_assert_unreachable(); + return ""; + } +} + +static inline eGeometryType geometry_type_from_object(Object *ob) +{ + switch (ob->type) { + case OB_CURVES: + return eGeometryType::CURVES; + case OB_POINTCLOUD: + return eGeometryType::POINTCLOUD; + default: + return eGeometryType::MESH; + } +} + +enum class ePipelineType { + OPAQUE = 0, + TRANSPARENT, + SHADOW, +}; +static constexpr int pipeline_type_len = static_cast(ePipelineType::SHADOW) + 1; + +enum class eLightingType { + FLAT = 0, + STUDIO, + MATCAP, +}; +static constexpr int lighting_type_len = static_cast(eLightingType::MATCAP) + 1; + +static inline eLightingType lighting_type_from_v3d_lighting(char lighting) +{ + switch (lighting) { + case V3D_LIGHTING_FLAT: + return eLightingType::FLAT; + case V3D_LIGHTING_MATCAP: + return eLightingType::MATCAP; + case V3D_LIGHTING_STUDIO: + return eLightingType::STUDIO; + default: + BLI_assert_unreachable(); + return static_cast(-1); + } +} + +enum class eShaderType { + MATERIAL = 0, + TEXTURE, +}; +static constexpr int shader_type_len = static_cast(eShaderType::TEXTURE) + 1; + +static inline eShaderType shader_type_from_v3d_shading(char shading) +{ + return shading == V3D_SHADING_TEXTURE_COLOR ? eShaderType::TEXTURE : eShaderType::MATERIAL; +} + +static inline const char *get_name(eShaderType type) +{ + switch (type) { + case eShaderType::MATERIAL: + return "Material"; + case eShaderType::TEXTURE: + return "Texture"; + default: + BLI_assert_unreachable(); + return ""; + } +} + +} // namespace blender::workbench diff --git a/source/blender/draw/engines/workbench/workbench_materials_next.cc b/source/blender/draw/engines/workbench/workbench_materials_next.cc new file mode 100644 index 00000000000..74622882e52 --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_materials_next.cc @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "workbench_private.hh" + +#include "BLI_hash.h" +/* get_image */ +#include "BKE_node.h" +#include "DNA_node_types.h" +#include "ED_uvedit.h" +/* get_image */ + +namespace blender::workbench { + +Material::Material() = default; + +Material::Material(float3 color) +{ + base_color = color; + packed_data = Material::pack_data(0.0f, 0.4f, 1.0f); +} + +Material::Material(::Object &ob, bool random) +{ + if (random) { + uint hash = BLI_ghashutil_strhash_p_murmur(ob.id.name); + if (ob.id.lib) { + hash = (hash * 13) ^ BLI_ghashutil_strhash_p_murmur(ob.id.lib->filepath); + } + float3 hsv = float3(BLI_hash_int_01(hash), 0.5f, 0.8f); + hsv_to_rgb_v(hsv, base_color); + } + else { + base_color = ob.color; + } + packed_data = Material::pack_data(0.0f, 0.4f, ob.color[3]); +} + +Material::Material(::Material &mat) +{ + base_color = &mat.r; + packed_data = Material::pack_data(mat.metallic, mat.roughness, mat.a); +} + +bool Material::is_transparent() +{ + uint32_t full_alpha_ref = 0x00ff0000; + return (packed_data & full_alpha_ref) != full_alpha_ref; +} + +uint32_t Material::pack_data(float metallic, float roughness, float alpha) +{ + /* Remap to Disney roughness. */ + roughness = sqrtf(roughness); + uint32_t packed_roughness = unit_float_to_uchar_clamp(roughness); + uint32_t packed_metallic = unit_float_to_uchar_clamp(metallic); + uint32_t packed_alpha = unit_float_to_uchar_clamp(alpha); + return (packed_alpha << 16u) | (packed_roughness << 8u) | packed_metallic; +} + +void get_material_image(Object *ob, + int material_index, + ::Image *&image, + ImageUser *&iuser, + eGPUSamplerState &sampler_state) +{ + const ::bNode *node = nullptr; + + ED_object_get_active_image(ob, material_index, &image, &iuser, &node, nullptr); + if (node && image) { + switch (node->type) { + case SH_NODE_TEX_IMAGE: { + const NodeTexImage *storage = static_cast(node->storage); + const bool use_filter = (storage->interpolation != SHD_INTERP_CLOSEST); + const bool use_mirror = (storage->extension == SHD_IMAGE_EXTENSION_MIRROR); + const bool use_repeat = use_mirror || (storage->extension == SHD_IMAGE_EXTENSION_REPEAT); + const bool use_clip = (storage->extension == SHD_IMAGE_EXTENSION_CLIP); + SET_FLAG_FROM_TEST(sampler_state, use_filter, GPU_SAMPLER_FILTER); + SET_FLAG_FROM_TEST(sampler_state, use_repeat, GPU_SAMPLER_REPEAT); + SET_FLAG_FROM_TEST(sampler_state, use_clip, GPU_SAMPLER_CLAMP_BORDER); + SET_FLAG_FROM_TEST(sampler_state, use_mirror, GPU_SAMPLER_MIRROR_REPEAT); + break; + } + case SH_NODE_TEX_ENVIRONMENT: { + const NodeTexEnvironment *storage = static_cast(node->storage); + const bool use_filter = (storage->interpolation != SHD_INTERP_CLOSEST); + SET_FLAG_FROM_TEST(sampler_state, use_filter, GPU_SAMPLER_FILTER); + break; + } + default: + BLI_assert_msg(0, "Node type not supported by workbench"); + } + } +} + +} // namespace blender::workbench diff --git a/source/blender/draw/engines/workbench/workbench_mesh_passes.cc b/source/blender/draw/engines/workbench/workbench_mesh_passes.cc new file mode 100644 index 00000000000..bc90f26b33d --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_mesh_passes.cc @@ -0,0 +1,406 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "workbench_private.hh" + +namespace blender::workbench { + +/* -------------------------------------------------------------------- */ +/** \name MeshPass + * \{ */ + +MeshPass::MeshPass(const char *name) : PassMain(name){}; + +/* Move to draw::Pass */ +bool MeshPass::is_empty() const +{ + return is_empty_; +} + +void MeshPass::init_pass(SceneResources &resources, DRWState state, int clip_planes) +{ + is_empty_ = true; + PassMain::init(); + state_set(state, clip_planes); + bind_texture(WB_MATCAP_SLOT, resources.matcap_tx); + bind_ssbo(WB_MATERIAL_SLOT, &resources.material_buf); + bind_ubo(WB_WORLD_SLOT, resources.world_buf); + if (clip_planes > 0) { + bind_ubo(DRW_CLIPPING_UBO_SLOT, resources.clip_planes_buf); + } +} + +void MeshPass::init_subpasses(ePipelineType pipeline, + eLightingType lighting, + bool clip, + ShaderCache &shaders) +{ + texture_subpass_map_.clear(); + + static std::string pass_names[geometry_type_len][shader_type_len] = {}; + + for (auto geom : IndexRange(geometry_type_len)) { + for (auto shader : IndexRange(shader_type_len)) { + eGeometryType geom_type = static_cast(geom); + eShaderType shader_type = static_cast(shader); + if (pass_names[geom][shader].empty()) { + pass_names[geom][shader] = std::string(get_name(geom_type)) + + std::string(get_name(shader_type)); + } + GPUShader *sh = shaders.prepass_shader_get(pipeline, geom_type, shader_type, lighting, clip); + PassMain::Sub *pass = &sub(pass_names[geom][shader].c_str()); + pass->shader_set(sh); + passes_[geom][shader] = pass; + } + } +} + +void MeshPass::draw(ObjectRef &ref, + GPUBatch *batch, + ResourceHandle handle, + ::Image *image /* = nullptr */, + eGPUSamplerState sampler_state /* = GPU_SAMPLER_DEFAULT */, + ImageUser *iuser /* = nullptr */) +{ + is_empty_ = false; + + eGeometryType geometry_type = geometry_type_from_object(ref.object); + if (image) { + GPUTexture *texture = nullptr; + GPUTexture *tilemap = nullptr; + if (image->source == IMA_SRC_TILED) { + texture = BKE_image_get_gpu_tiles(image, iuser, nullptr); + tilemap = BKE_image_get_gpu_tilemap(image, iuser, nullptr); + } + else { + texture = BKE_image_get_gpu_texture(image, iuser, nullptr); + } + if (texture) { + auto add_cb = [&] { + PassMain::Sub *sub_pass = + passes_[static_cast(geometry_type)][static_cast(eShaderType::TEXTURE)]; + sub_pass = &sub_pass->sub(image->id.name); + if (tilemap) { + sub_pass->bind_texture(WB_TILE_ARRAY_SLOT, texture, sampler_state); + sub_pass->bind_texture(WB_TILE_DATA_SLOT, tilemap); + } + else { + sub_pass->bind_texture(WB_TEXTURE_SLOT, texture, sampler_state); + } + sub_pass->push_constant("isImageTile", tilemap != nullptr); + sub_pass->push_constant("imagePremult", image && image->alpha_mode == IMA_ALPHA_PREMUL); + /* TODO(Miguel Pozo): This setting should be exposed on the user side, + * either as a global parameter (and set it here) + * or by reading the Material Clipping Threshold (and set it per material) */ + sub_pass->push_constant("imageTransparencyCutoff", 0.1f); + return sub_pass; + }; + + texture_subpass_map_.lookup_or_add_cb(TextureSubPassKey(texture, geometry_type), add_cb) + ->draw(batch, handle); + return; + } + } + passes_[static_cast(geometry_type)][static_cast(eShaderType::MATERIAL)]->draw(batch, + handle); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name OpaquePass + * \{ */ + +void OpaquePass::sync(const SceneState &scene_state, SceneResources &resources) +{ + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | + scene_state.cull_state; + + bool clip = scene_state.clip_planes.size() > 0; + + DRWState in_front_state = state | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS; + gbuffer_in_front_ps_.init_pass(resources, in_front_state, scene_state.clip_planes.size()); + gbuffer_in_front_ps_.state_stencil(0xFF, 0xFF, 0x00); + gbuffer_in_front_ps_.init_subpasses( + ePipelineType::OPAQUE, scene_state.lighting_type, clip, resources.shader_cache); + + state |= DRW_STATE_STENCIL_NEQUAL; + gbuffer_ps_.init_pass(resources, state, scene_state.clip_planes.size()); + gbuffer_ps_.state_stencil(0x00, 0xFF, 0xFF); + gbuffer_ps_.init_subpasses( + ePipelineType::OPAQUE, scene_state.lighting_type, clip, resources.shader_cache); + + deferred_ps_.init(); + deferred_ps_.state_set(DRW_STATE_WRITE_COLOR); + deferred_ps_.shader_set(resources.shader_cache.resolve_shader_get(ePipelineType::OPAQUE, + scene_state.lighting_type, + scene_state.draw_cavity, + scene_state.draw_curvature)); + deferred_ps_.push_constant("forceShadowing", false); + deferred_ps_.bind_ubo(WB_WORLD_SLOT, resources.world_buf); + deferred_ps_.bind_texture(WB_MATCAP_SLOT, resources.matcap_tx); + deferred_ps_.bind_texture("normal_tx", &gbuffer_normal_tx); + deferred_ps_.bind_texture("material_tx", &gbuffer_material_tx); + deferred_ps_.bind_texture("depth_tx", &resources.depth_tx); + deferred_ps_.bind_texture("stencil_tx", &deferred_ps_stencil_tx); + resources.cavity.setup_resolve_pass(deferred_ps_, resources); + deferred_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); +} + +void OpaquePass::draw(Manager &manager, + View &view, + SceneResources &resources, + int2 resolution, + ShadowPass *shadow_pass, + bool accumulation_ps_is_empty) +{ + if (is_empty()) { + return; + } + gbuffer_material_tx.acquire( + resolution, GPU_RGBA16F, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT); + gbuffer_normal_tx.acquire( + resolution, GPU_RG16F, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT); + + GPUAttachment object_id_attachment = GPU_ATTACHMENT_NONE; + if (resources.object_id_tx.is_valid()) { + object_id_attachment = GPU_ATTACHMENT_TEXTURE(resources.object_id_tx); + } + + if (!gbuffer_in_front_ps_.is_empty()) { + opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx), + GPU_ATTACHMENT_TEXTURE(gbuffer_material_tx), + GPU_ATTACHMENT_TEXTURE(gbuffer_normal_tx), + object_id_attachment); + opaque_fb.bind(); + + manager.submit(gbuffer_in_front_ps_, view); + if (resources.depth_in_front_tx.is_valid()) { + /* Only needed when transparent infront is needed */ + GPU_texture_copy(resources.depth_in_front_tx, resources.depth_tx); + } + } + + if (!gbuffer_ps_.is_empty()) { + opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx), + GPU_ATTACHMENT_TEXTURE(gbuffer_material_tx), + GPU_ATTACHMENT_TEXTURE(gbuffer_normal_tx), + object_id_attachment); + opaque_fb.bind(); + + manager.submit(gbuffer_ps_, view); + } + + bool needs_stencil_copy = shadow_pass && !gbuffer_in_front_ps_.is_empty() && + !accumulation_ps_is_empty; + + if (needs_stencil_copy) { + shadow_depth_stencil_tx.ensure_2d(GPU_DEPTH24_STENCIL8, + resolution, + GPU_TEXTURE_USAGE_SHADER_READ | + GPU_TEXTURE_USAGE_ATTACHMENT | + GPU_TEXTURE_USAGE_MIP_SWIZZLE_VIEW); + GPU_texture_copy(shadow_depth_stencil_tx, resources.depth_tx); + + deferred_ps_stencil_tx = shadow_depth_stencil_tx.stencil_view(); + } + else { + shadow_depth_stencil_tx.free(); + + deferred_ps_stencil_tx = resources.depth_tx.stencil_view(); + } + + if (shadow_pass && !gbuffer_in_front_ps_.is_empty()) { + opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(deferred_ps_stencil_tx)); + opaque_fb.bind(); + GPU_framebuffer_clear_stencil(opaque_fb, 0); + } + + if (shadow_pass) { + shadow_pass->draw(manager, + view, + resources, + resolution, + *deferred_ps_stencil_tx, + !gbuffer_in_front_ps_.is_empty()); + } + + opaque_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx)); + opaque_fb.bind(); + manager.submit(deferred_ps_, view); + + if (shadow_pass && !needs_stencil_copy) { + opaque_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx)); + opaque_fb.bind(); + GPU_framebuffer_clear_stencil(opaque_fb, 0); + } + + gbuffer_normal_tx.release(); + gbuffer_material_tx.release(); +} + +bool OpaquePass::is_empty() const +{ + return gbuffer_ps_.is_empty() && gbuffer_in_front_ps_.is_empty(); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name TransparentPass + * \{ */ + +void TransparentPass::sync(const SceneState &scene_state, SceneResources &resources) +{ + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_OIT | + scene_state.cull_state; + + bool clip = scene_state.clip_planes.size() > 0; + + accumulation_ps_.init_pass( + resources, state | DRW_STATE_STENCIL_NEQUAL, scene_state.clip_planes.size()); + accumulation_ps_.state_stencil(0x00, 0xFF, 0xFF); + accumulation_ps_.clear_color(float4(0.0f, 0.0f, 0.0f, 1.0f)); + accumulation_ps_.init_subpasses( + ePipelineType::TRANSPARENT, scene_state.lighting_type, clip, resources.shader_cache); + + accumulation_in_front_ps_.init_pass(resources, state, scene_state.clip_planes.size()); + accumulation_in_front_ps_.clear_color(float4(0.0f, 0.0f, 0.0f, 1.0f)); + accumulation_in_front_ps_.init_subpasses( + ePipelineType::TRANSPARENT, scene_state.lighting_type, clip, resources.shader_cache); + + if (resolve_sh_ == nullptr) { + resolve_sh_ = GPU_shader_create_from_info_name("workbench_transparent_resolve"); + } + resolve_ps_.init(); + resolve_ps_.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA); + resolve_ps_.shader_set(resolve_sh_); + resolve_ps_.bind_texture("transparentAccum", &accumulation_tx); + resolve_ps_.bind_texture("transparentRevealage", &reveal_tx); + resolve_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); +} + +void TransparentPass::draw(Manager &manager, + View &view, + SceneResources &resources, + int2 resolution) +{ + if (is_empty()) { + return; + } + accumulation_tx.acquire( + resolution, GPU_RGBA16F, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT); + reveal_tx.acquire( + resolution, GPU_R16F, GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT); + + resolve_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx)); + + if (!accumulation_ps_.is_empty()) { + transparent_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx), + GPU_ATTACHMENT_TEXTURE(accumulation_tx), + GPU_ATTACHMENT_TEXTURE(reveal_tx)); + transparent_fb.bind(); + manager.submit(accumulation_ps_, view); + resolve_fb.bind(); + manager.submit(resolve_ps_, view); + } + if (!accumulation_in_front_ps_.is_empty()) { + transparent_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_in_front_tx), + GPU_ATTACHMENT_TEXTURE(accumulation_tx), + GPU_ATTACHMENT_TEXTURE(reveal_tx)); + transparent_fb.bind(); + manager.submit(accumulation_in_front_ps_, view); + resolve_fb.bind(); + manager.submit(resolve_ps_, view); + } + + accumulation_tx.release(); + reveal_tx.release(); +} + +bool TransparentPass::is_empty() const +{ + return accumulation_ps_.is_empty() && accumulation_in_front_ps_.is_empty(); +} + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name TransparentDepthPass + * \{ */ + +void TransparentDepthPass::sync(const SceneState &scene_state, SceneResources &resources) +{ + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | + scene_state.cull_state; + + bool clip = scene_state.clip_planes.size() > 0; + + DRWState in_front_state = state | DRW_STATE_WRITE_STENCIL | DRW_STATE_STENCIL_ALWAYS; + in_front_ps_.init_pass(resources, in_front_state, scene_state.clip_planes.size()); + in_front_ps_.state_stencil(0xFF, 0xFF, 0x00); + in_front_ps_.init_subpasses( + ePipelineType::OPAQUE, eLightingType::FLAT, clip, resources.shader_cache); + + if (merge_sh_ == nullptr) { + merge_sh_ = GPU_shader_create_from_info_name("workbench_next_merge_depth"); + } + merge_ps_.init(); + merge_ps_.shader_set(merge_sh_); + merge_ps_.state_set(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_WRITE_STENCIL | + DRW_STATE_STENCIL_ALWAYS); + merge_ps_.state_stencil(0xFF, 0xFF, 0x00); + merge_ps_.bind_texture("depth_tx", &resources.depth_in_front_tx); + merge_ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); + + state |= DRW_STATE_STENCIL_NEQUAL; + main_ps_.init_pass(resources, state, scene_state.clip_planes.size()); + main_ps_.state_stencil(0x00, 0xFF, 0xFF); + main_ps_.init_subpasses( + ePipelineType::OPAQUE, eLightingType::FLAT, clip, resources.shader_cache); +} + +void TransparentDepthPass::draw(Manager &manager, + View &view, + SceneResources &resources, + int2 resolution) +{ + if (is_empty()) { + return; + } + + GPUAttachment object_id_attachment = GPU_ATTACHMENT_NONE; + if (resources.object_id_tx.is_valid()) { + object_id_attachment = GPU_ATTACHMENT_TEXTURE(resources.object_id_tx); + } + + if (!in_front_ps_.is_empty()) { + in_front_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_in_front_tx), + GPU_ATTACHMENT_NONE, + GPU_ATTACHMENT_NONE, + object_id_attachment); + in_front_fb.bind(); + manager.submit(in_front_ps_, view); + + merge_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx)); + merge_fb.bind(); + manager.submit(merge_ps_, view); + } + + if (!main_ps_.is_empty()) { + main_fb.ensure(GPU_ATTACHMENT_TEXTURE(resources.depth_tx), + GPU_ATTACHMENT_NONE, + GPU_ATTACHMENT_NONE, + object_id_attachment); + main_fb.bind(); + manager.submit(main_ps_, view); + } +} + +bool TransparentDepthPass::is_empty() const +{ + return main_ps_.is_empty() && in_front_ps_.is_empty(); +} + +/** \} */ + +} // namespace blender::workbench diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index 4aedaf443b9..c6dbee68e58 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -200,8 +200,12 @@ typedef struct WORKBENCH_UBO_World { int matcap_orientation; int use_specular; /* Bools are 32bit ints in GLSL. */ - int _pad1; + float xray_alpha; /* Workbench Next */ int _pad2; + + /* Workbench Next data + * (Not used here, but needs to be kept in sync with workbench_shader_shared WorldData) */ + float background_color[4]; } WORKBENCH_UBO_World; BLI_STATIC_ASSERT_ALIGN(WORKBENCH_UBO_World, 16) diff --git a/source/blender/draw/engines/workbench/workbench_private.hh b/source/blender/draw/engines/workbench/workbench_private.hh new file mode 100644 index 00000000000..086553ca5c1 --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_private.hh @@ -0,0 +1,436 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "DNA_camera_types.h" +#include "DRW_render.h" +#include "draw_manager.hh" +#include "draw_pass.hh" + +#include "workbench_defines.hh" +#include "workbench_enums.hh" +#include "workbench_shader_shared.h" + +extern "C" DrawEngineType draw_engine_workbench_next; + +namespace blender::workbench { + +using namespace draw; + +class ShaderCache { + public: + ~ShaderCache(); + + GPUShader *prepass_shader_get(ePipelineType pipeline_type, + eGeometryType geometry_type, + eShaderType shader_type, + eLightingType lighting_type, + bool clip); + + GPUShader *resolve_shader_get(ePipelineType pipeline_type, + eLightingType lighting_type, + bool cavity = false, + bool curvature = false); + + private: + /* TODO(fclem): We might want to change to a Map since most shader will never be compiled. */ + GPUShader *prepass_shader_cache_[pipeline_type_len][geometry_type_len][shader_type_len] + [lighting_type_len][2 /*clip*/] = {{{{{nullptr}}}}}; + GPUShader *resolve_shader_cache_[pipeline_type_len][lighting_type_len][2 /*cavity*/] + [2 /*curvature*/] = {{{{nullptr}}}}; +}; + +struct Material { + float3 base_color = float3(0); + /* Packed data into a int. Decoded in the shader. */ + uint packed_data = 0; + + Material(); + Material(float3 color); + Material(::Object &ob, bool random = false); + Material(::Material &mat); + + static uint32_t pack_data(float metallic, float roughness, float alpha); + + bool is_transparent(); +}; + +void get_material_image(Object *ob, + int material_index, + ::Image *&image, + ImageUser *&iuser, + eGPUSamplerState &sampler_state); + +struct SceneState { + Scene *scene = nullptr; + + Object *camera_object = nullptr; + Camera *camera = nullptr; + float4x4 view_projection_matrix = float4x4::identity(); + int2 resolution = int2(0); + + eContextObjectMode object_mode = CTX_MODE_OBJECT; + + View3DShading shading = {}; + eLightingType lighting_type = eLightingType::STUDIO; + bool xray_mode = false; + + DRWState cull_state = DRW_STATE_NO_DRAW; + Vector clip_planes = {}; + + float4 background_color = float4(0); + + bool draw_cavity = false; + bool draw_curvature = false; + bool draw_shadows = false; + bool draw_outline = false; + bool draw_dof = false; + bool draw_aa = false; + + bool draw_object_id = false; + bool draw_transparent_depth = false; + + int sample = 0; + int samples_len = 0; + bool reset_taa_next_sample = false; + bool render_finished = false; + + /* Used when material_type == eMaterialType::SINGLE */ + Material material_override = Material(float3(1.0f)); + /* When r == -1.0 the shader uses the vertex color */ + Material material_attribute_color = Material(float3(-1.0f)); + + void init(Object *camera_ob = nullptr); +}; + +struct ObjectState { + eV3DShadingColorType color_type = V3D_SHADING_SINGLE_COLOR; + bool sculpt_pbvh = false; + bool texture_paint_mode = false; + ::Image *image_paint_override = nullptr; + eGPUSamplerState override_sampler_state = GPU_SAMPLER_DEFAULT; + bool draw_shadow = false; + bool use_per_material_batches = false; + + ObjectState(const SceneState &scene_state, Object *ob); +}; + +class CavityEffect { + private: + /* This value must be kept in sync with the one declared at + * workbench_composite_info.hh (cavity_samples) */ + static const int max_samples_ = 512; + + UniformArrayBuffer samples_buf = {}; + + int sample_ = 0; + int sample_count_ = 0; + bool curvature_enabled_ = false; + bool cavity_enabled_ = false; + + public: + void init(const SceneState &scene_state, struct SceneResources &resources); + void setup_resolve_pass(PassSimple &pass, struct SceneResources &resources); + + private: + void load_samples_buf(int ssao_samples); +}; + +struct SceneResources { + static const int jitter_tx_size = 64; + + ShaderCache shader_cache = {}; + + StringRefNull current_matcap = {}; + Texture matcap_tx = "matcap_tx"; + + TextureFromPool color_tx = "wb_color_tx"; + TextureFromPool object_id_tx = "wb_object_id_tx"; + Texture depth_tx = "wb_depth_tx"; + TextureFromPool depth_in_front_tx = "wb_depth_in_front_tx"; + + StorageVectorBuffer material_buf = {"material_buf"}; + UniformBuffer world_buf = {}; + UniformArrayBuffer clip_planes_buf; + + Texture jitter_tx = "wb_jitter_tx"; + + CavityEffect cavity = {}; + + void init(const SceneState &scene_state); + void load_jitter_tx(int total_samples); +}; + +class MeshPass : public PassMain { + private: + using TextureSubPassKey = std::pair; + + Map texture_subpass_map_ = {}; + + PassMain::Sub *passes_[geometry_type_len][shader_type_len] = {{nullptr}}; + + bool is_empty_ = false; + + public: + MeshPass(const char *name); + + /* TODO: Move to draw::Pass */ + bool is_empty() const; + + void init_pass(SceneResources &resources, DRWState state, int clip_planes); + void init_subpasses(ePipelineType pipeline, + eLightingType lighting, + bool clip, + ShaderCache &shaders); + + void draw(ObjectRef &ref, + GPUBatch *batch, + ResourceHandle handle, + ::Image *image = nullptr, + eGPUSamplerState sampler_state = eGPUSamplerState::GPU_SAMPLER_DEFAULT, + ImageUser *iuser = nullptr); +}; + +class OpaquePass { + public: + TextureFromPool gbuffer_normal_tx = {"gbuffer_normal_tx"}; + TextureFromPool gbuffer_material_tx = {"gbuffer_material_tx"}; + Framebuffer opaque_fb = {}; + + Texture shadow_depth_stencil_tx = {"shadow_depth_stencil_tx"}; + GPUTexture *deferred_ps_stencil_tx = nullptr; + + MeshPass gbuffer_ps_ = {"Opaque.Gbuffer"}; + MeshPass gbuffer_in_front_ps_ = {"Opaque.GbufferInFront"}; + PassSimple deferred_ps_ = {"Opaque.Deferred"}; + + void sync(const SceneState &scene_state, SceneResources &resources); + void draw(Manager &manager, + View &view, + SceneResources &resources, + int2 resolution, + class ShadowPass *shadow_pass, + bool accumulation_ps_is_empty); + bool is_empty() const; +}; + +class TransparentPass { + private: + GPUShader *resolve_sh_ = nullptr; + + public: + TextureFromPool accumulation_tx = {"accumulation_accumulation_tx"}; + TextureFromPool reveal_tx = {"accumulation_reveal_tx"}; + Framebuffer transparent_fb = {}; + + MeshPass accumulation_ps_ = {"Transparent.Accumulation"}; + MeshPass accumulation_in_front_ps_ = {"Transparent.AccumulationInFront"}; + PassSimple resolve_ps_ = {"Transparent.Resolve"}; + Framebuffer resolve_fb = {}; + + void sync(const SceneState &scene_state, SceneResources &resources); + void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution); + bool is_empty() const; +}; + +class TransparentDepthPass { + private: + GPUShader *merge_sh_ = nullptr; + + public: + MeshPass main_ps_ = {"TransparentDepth.Main"}; + Framebuffer main_fb = {"TransparentDepth.Main"}; + MeshPass in_front_ps_ = {"TransparentDepth.InFront"}; + Framebuffer in_front_fb = {"TransparentDepth.InFront"}; + PassSimple merge_ps_ = {"TransparentDepth.Merge"}; + Framebuffer merge_fb = {"TransparentDepth.Merge"}; + + void sync(const SceneState &scene_state, SceneResources &resources); + void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution); + bool is_empty() const; +}; + +class ShadowPass { + private: + enum PassType { PASS = 0, FAIL, FORCED_FAIL, MAX }; + + class ShadowView : public View { + bool force_fail_method_ = false; + float3 light_direction_ = float3(0); + UniformBuffer extruded_frustum_ = {}; + ShadowPass::PassType current_pass_type_ = PASS; + + VisibilityBuf pass_visibility_buf_ = {}; + VisibilityBuf fail_visibility_buf_ = {}; + + public: + void setup(View &view, float3 light_direction, bool force_fail_method); + bool debug_object_culling(Object *ob); + void set_mode(PassType type); + + ShadowView(); + + protected: + virtual void compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool debug_freeze); + virtual VisibilityBuf &get_visibility_buffer(); + } view_ = {}; + + bool enabled_; + + UniformBuffer pass_data_ = {}; + + /* Draws are added to both passes and the visibily compute shader selects one of them */ + PassMain pass_ps_ = {"Shadow.Pass"}; + PassMain fail_ps_ = {"Shadow.Fail"}; + + /* In some cases, we know beforehand that we need to use the fail technique */ + PassMain forced_fail_ps_ = {"Shadow.ForcedFail"}; + + /* [PassType][Is Manifold][Is Cap] */ + PassMain::Sub *passes_[PassType::MAX][2][2] = {{{nullptr}}}; + PassMain::Sub *&get_pass_ptr(PassType type, bool manifold, bool cap = false); + + /* [Is Pass Technique][Is Manifold][Is Cap] */ + GPUShader *shaders_[2][2][2] = {{{nullptr}}}; + GPUShader *get_shader(bool depth_pass, bool manifold, bool cap = false); + + TextureFromPool depth_tx_ = {}; + Framebuffer fb_ = {}; + + public: + void init(const SceneState &scene_state, SceneResources &resources); + void update(); + void sync(); + void object_sync(Manager &manager, + SceneState &scene_state, + ObjectRef &ob_ref, + ResourceHandle handle, + const bool has_transp_mat); + void draw(Manager &manager, + View &view, + SceneResources &resources, + int2 resolution, + GPUTexture &depth_stencil_tx, + /* Needed when there are opaque "In Front" objects in the scene */ + bool force_fail_method); +}; + +class OutlinePass { + private: + bool enabled_ = false; + + PassSimple ps_ = PassSimple("Workbench.Outline"); + GPUShader *sh_ = nullptr; + Framebuffer fb_ = Framebuffer("Workbench.Outline"); + + public: + void init(const SceneState &scene_state); + void sync(SceneResources &resources); + void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution); +}; + +class DofPass { + private: + static const int kernel_radius_ = 3; + static const int samples_len_ = (kernel_radius_ * 2 + 1) * (kernel_radius_ * 2 + 1); + + bool enabled_ = false; + + float offset_ = 0; + + UniformArrayBuffer samples_buf_ = {}; + + Texture source_tx_ = {}; + Texture coc_halfres_tx_ = {}; + TextureFromPool blur_tx_ = {}; + + Framebuffer downsample_fb_ = {}; + Framebuffer blur1_fb_ = {}; + Framebuffer blur2_fb_ = {}; + Framebuffer resolve_fb_ = {}; + + GPUShader *prepare_sh_ = nullptr; + GPUShader *downsample_sh_ = nullptr; + GPUShader *blur1_sh_ = nullptr; + GPUShader *blur2_sh_ = nullptr; + GPUShader *resolve_sh_ = nullptr; + + PassSimple down_ps_ = {"Workbench.DoF.DownSample"}; + PassSimple down2_ps_ = {"Workbench.DoF.DownSample2"}; + PassSimple blur_ps_ = {"Workbench.DoF.Blur"}; + PassSimple blur2_ps_ = {"Workbench.DoF.Blur2"}; + PassSimple resolve_ps_ = {"Workbench.DoF.Resolve"}; + + float aperture_size_ = 0; + float distance_ = 0; + float invsensor_size_ = 0; + float near_ = 0; + float far_ = 0; + float blades_ = 0; + float rotation_ = 0; + float ratio_ = 0; + + public: + void init(const SceneState &scene_state); + void sync(SceneResources &resources); + void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution); + bool is_enabled(); + + private: + void setup_samples(); +}; + +class AntiAliasingPass { + private: + bool enabled_ = false; + /* Current TAA sample index in [0..samples_len_] range. */ + int sample_ = 0; + /* Total number of samples to after which TAA stops accumulating samples. */ + int samples_len_ = 0; + /* Weight accumulated. */ + float weight_accum_ = 0; + /* Samples weight for this iteration. */ + float weights_[9] = {0}; + /* Sum of weights. */ + float weights_sum_ = 0; + + Texture sample0_depth_tx_ = {"sample0_depth_tx"}; + + Texture taa_accumulation_tx_ = {"taa_accumulation_tx"}; + Texture smaa_search_tx_ = {"smaa_search_tx"}; + Texture smaa_area_tx_ = {"smaa_area_tx"}; + TextureFromPool smaa_edge_tx_ = {"smaa_edge_tx"}; + TextureFromPool smaa_weight_tx_ = {"smaa_weight_tx"}; + + Framebuffer taa_accumulation_fb_ = {"taa_accumulation_fb"}; + Framebuffer smaa_edge_fb_ = {"smaa_edge_fb"}; + Framebuffer smaa_weight_fb_ = {"smaa_weight_fb"}; + Framebuffer smaa_resolve_fb_ = {"smaa_resolve_fb"}; + + float4 smaa_viewport_metrics_ = float4(0); + float smaa_mix_factor_ = 0; + + GPUShader *taa_accumulation_sh_ = nullptr; + GPUShader *smaa_edge_detect_sh_ = nullptr; + GPUShader *smaa_aa_weight_sh_ = nullptr; + GPUShader *smaa_resolve_sh_ = nullptr; + + PassSimple taa_accumulation_ps_ = {"TAA.Accumulation"}; + PassSimple smaa_edge_detect_ps_ = {"SMAA.EdgeDetect"}; + PassSimple smaa_aa_weight_ps_ = {"SMAA.BlendWeights"}; + PassSimple smaa_resolve_ps_ = {"SMAA.Resolve"}; + + public: + AntiAliasingPass(); + ~AntiAliasingPass(); + + void init(const SceneState &scene_state); + void sync(SceneResources &resources, int2 resolution); + void setup_view(View &view, int2 resolution); + void draw(Manager &manager, + View &view, + SceneResources &resources, + int2 resolution, + GPUTexture *depth_tx, + GPUTexture *color_tx); +}; + +} // namespace blender::workbench diff --git a/source/blender/draw/engines/workbench/workbench_resources.cc b/source/blender/draw/engines/workbench/workbench_resources.cc new file mode 100644 index 00000000000..98d3ca8f668 --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_resources.cc @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "../eevee/eevee_lut.h" /* TODO: find somewhere to share blue noise Table. */ +#include "BKE_studiolight.h" +#include "IMB_imbuf_types.h" + +#include "workbench_private.hh" + +namespace blender::workbench { + +bool get_matcap_tx(Texture &matcap_tx, const StudioLight &studio_light) +{ + ImBuf *matcap_diffuse = studio_light.matcap_diffuse.ibuf; + ImBuf *matcap_specular = studio_light.matcap_specular.ibuf; + if (matcap_diffuse && matcap_diffuse->rect_float) { + int layers = 1; + float *buffer = matcap_diffuse->rect_float; + Vector combined_buffer = {}; + + if (matcap_specular && matcap_specular->rect_float) { + int size = matcap_diffuse->x * matcap_diffuse->y * 4; + combined_buffer.extend(matcap_diffuse->rect_float, size); + combined_buffer.extend(matcap_specular->rect_float, size); + buffer = combined_buffer.begin(); + layers++; + } + + matcap_tx = Texture(studio_light.name, + GPU_RGBA16F, + GPU_TEXTURE_USAGE_SHADER_READ, + int2(matcap_diffuse->x, matcap_diffuse->y), + layers, + buffer); + return true; + } + return false; +} + +float4x4 get_world_shading_rotation_matrix(float studiolight_rot_z) +{ + /* TODO(Miguel Pozo) C++ API ? */ + float V[4][4], R[4][4]; + DRW_view_viewmat_get(nullptr, V, false); + axis_angle_to_mat4_single(R, 'Z', -studiolight_rot_z); + mul_m4_m4m4(R, V, R); + swap_v3_v3(R[2], R[1]); + negate_v3(R[2]); + return float4x4(R); +} + +LightData get_light_data_from_studio_solidlight(const SolidLight *sl, + float4x4 world_shading_rotation) +{ + LightData light = {}; + if (sl && sl->flag) { + float3 direction = world_shading_rotation.ref_3x3() * float3(sl->vec); + light.direction = float4(direction, 0.0f); + /* We should pre-divide the power by PI but that makes the lights really dim. */ + light.specular_color = float4(float3(sl->spec), 0.0f); + light.diffuse_color_wrap = float4(float3(sl->col), sl->smooth); + } + else { + light.direction = float4(1.0f, 0.0f, 0.0f, 0.0f); + light.specular_color = float4(0.0f); + light.diffuse_color_wrap = float4(0.0f); + } + return light; +} + +void SceneResources::load_jitter_tx(int total_samples) +{ + const int texel_count = jitter_tx_size * jitter_tx_size; + static float4 jitter[texel_count]; + + const float total_samples_inv = 1.0f / total_samples; + + /* Create blue noise jitter texture */ + for (int i = 0; i < texel_count; i++) { + float phi = blue_noise[i][0] * 2.0f * M_PI; + /* This rotate the sample per pixels */ + jitter[i].x = math::cos(phi); + jitter[i].y = math::sin(phi); + /* This offset the sample along its direction axis (reduce banding) */ + float bn = blue_noise[i][1] - 0.5f; + bn = clamp_f(bn, -0.499f, 0.499f); /* fix fireflies */ + jitter[i].z = bn * total_samples_inv; + jitter[i].w = blue_noise[i][1]; + } + + jitter_tx.free(); + jitter_tx.ensure_2d(GPU_RGBA16F, int2(jitter_tx_size), GPU_TEXTURE_USAGE_SHADER_READ, jitter[0]); +} + +void SceneResources::init(const SceneState &scene_state) +{ + const View3DShading &shading = scene_state.shading; + + world_buf.viewport_size = DRW_viewport_size_get(); + world_buf.viewport_size_inv = DRW_viewport_invert_size_get(); + world_buf.xray_alpha = shading.xray_alpha; + world_buf.background_color = scene_state.background_color; + world_buf.object_outline_color = float4(float3(shading.object_outline_color), 1.0f); + world_buf.ui_scale = DRW_state_is_image_render() ? 1.0f : G_draw.block.size_pixel; + world_buf.matcap_orientation = (shading.flag & V3D_SHADING_MATCAP_FLIP_X) != 0; + + StudioLight *studio_light = nullptr; + if (U.edit_studio_light) { + studio_light = BKE_studiolight_studio_edit_get(); + } + else { + if (shading.light == V3D_LIGHTING_MATCAP) { + studio_light = BKE_studiolight_find(shading.matcap, STUDIOLIGHT_TYPE_MATCAP); + if (studio_light && studio_light->name != current_matcap) { + if (get_matcap_tx(matcap_tx, *studio_light)) { + current_matcap = studio_light->name; + } + } + } + /* If matcaps are missing, use this as fallback. */ + if (studio_light == nullptr) { + studio_light = BKE_studiolight_find(shading.studio_light, STUDIOLIGHT_TYPE_STUDIO); + } + } + if (!matcap_tx.is_valid()) { + matcap_tx.ensure_2d_array(GPU_RGBA16F, int2(1), 1, GPU_TEXTURE_USAGE_SHADER_READ); + } + + float4x4 world_shading_rotation = float4x4::identity(); + if (shading.flag & V3D_SHADING_WORLD_ORIENTATION) { + world_shading_rotation = get_world_shading_rotation_matrix(shading.studiolight_rot_z); + } + + for (int i = 0; i < 4; i++) { + SolidLight *sl = (studio_light) ? &studio_light->light[i] : nullptr; + world_buf.lights[i] = get_light_data_from_studio_solidlight(sl, world_shading_rotation); + } + + if (studio_light != nullptr) { + world_buf.ambient_color = float4(float3(studio_light->light_ambient), 0.0f); + world_buf.use_specular = shading.flag & V3D_SHADING_SPECULAR_HIGHLIGHT && + studio_light->flag & STUDIOLIGHT_SPECULAR_HIGHLIGHT_PASS; + } + else { + world_buf.ambient_color = float4(1.0f, 1.0f, 1.0f, 0.0f); + world_buf.use_specular = false; + } + + /* TODO(Miguel Pozo) volumes_do */ + + cavity.init(scene_state, *this); + + if (scene_state.draw_dof && !jitter_tx.is_valid()) { + /* We don't care about total_samples in this case */ + load_jitter_tx(1); + } + + world_buf.push_update(); + + for (int i : IndexRange(6)) { + if (i < scene_state.clip_planes.size()) { + clip_planes_buf[i] = scene_state.clip_planes[i]; + } + else { + clip_planes_buf[i] = float4(0); + } + } + + clip_planes_buf.push_update(); +} + +} // namespace blender::workbench diff --git a/source/blender/draw/engines/workbench/workbench_shader_cache.cc b/source/blender/draw/engines/workbench/workbench_shader_cache.cc new file mode 100644 index 00000000000..6720fc1702b --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_shader_cache.cc @@ -0,0 +1,132 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "workbench_private.hh" + +namespace blender::workbench { + +ShaderCache::~ShaderCache() +{ + for (auto i : IndexRange(lighting_type_len)) { + for (auto j : IndexRange(shader_type_len)) { + for (auto k : IndexRange(geometry_type_len)) { + for (auto l : IndexRange(pipeline_type_len)) { + for (auto m : IndexRange(2)) { + DRW_SHADER_FREE_SAFE(prepass_shader_cache_[i][j][k][l][m]); + } + } + } + } + } + for (auto i : IndexRange(lighting_type_len)) { + for (auto j : IndexRange(pipeline_type_len)) { + for (auto k : IndexRange(2)) { + for (auto l : IndexRange(2)) { + DRW_SHADER_FREE_SAFE(resolve_shader_cache_[i][j][k][l]); + } + } + } + } +} + +GPUShader *ShaderCache::prepass_shader_get(ePipelineType pipeline_type, + eGeometryType geometry_type, + eShaderType shader_type, + eLightingType lighting_type, + bool clip) +{ + GPUShader *&shader_ptr = prepass_shader_cache_[static_cast(pipeline_type)][static_cast( + geometry_type)][static_cast(shader_type)][static_cast(lighting_type)] + [clip ? 1 : 0]; + + if (shader_ptr != nullptr) { + return shader_ptr; + } + std::string info_name = "workbench_next_prepass_"; + switch (geometry_type) { + case eGeometryType::MESH: + info_name += "mesh_"; + break; + case eGeometryType::CURVES: + info_name += "curves_"; + break; + case eGeometryType::POINTCLOUD: + info_name += "ptcloud_"; + break; + } + switch (pipeline_type) { + case ePipelineType::OPAQUE: + info_name += "opaque_"; + break; + case ePipelineType::TRANSPARENT: + info_name += "transparent_"; + break; + case ePipelineType::SHADOW: + info_name += "shadow_"; + break; + } + switch (lighting_type) { + case eLightingType::FLAT: + info_name += "flat_"; + break; + case eLightingType::STUDIO: + info_name += "studio_"; + break; + case eLightingType::MATCAP: + info_name += "matcap_"; + break; + } + switch (shader_type) { + case eShaderType::MATERIAL: + info_name += "material"; + break; + case eShaderType::TEXTURE: + info_name += "texture"; + break; + } + info_name += clip ? "_clip" : "_no_clip"; + shader_ptr = GPU_shader_create_from_info_name(info_name.c_str()); + return shader_ptr; +} + +GPUShader *ShaderCache::resolve_shader_get(ePipelineType pipeline_type, + eLightingType lighting_type, + bool cavity, + bool curvature) +{ + GPUShader *&shader_ptr = resolve_shader_cache_[static_cast(pipeline_type)][static_cast( + lighting_type)][cavity][curvature]; + + if (shader_ptr != nullptr) { + return shader_ptr; + } + std::string info_name = "workbench_next_resolve_"; + switch (pipeline_type) { + case ePipelineType::OPAQUE: + info_name += "opaque_"; + break; + case ePipelineType::TRANSPARENT: + info_name += "transparent_"; + break; + case ePipelineType::SHADOW: + BLI_assert_unreachable(); + break; + } + switch (lighting_type) { + case eLightingType::FLAT: + info_name += "flat"; + break; + case eLightingType::STUDIO: + info_name += "studio"; + break; + case eLightingType::MATCAP: + info_name += "matcap"; + break; + } + info_name += cavity ? "_cavity" : "_no_cavity"; + info_name += curvature ? "_curvature" : "_no_curvature"; + + shader_ptr = GPU_shader_create_from_info_name(info_name.c_str()); + return shader_ptr; +} + +} // namespace blender::workbench diff --git a/source/blender/draw/engines/workbench/workbench_shader_shared.h b/source/blender/draw/engines/workbench/workbench_shader_shared.h index b2e8fa30d85..d78e3408ccb 100644 --- a/source/blender/draw/engines/workbench/workbench_shader_shared.h +++ b/source/blender/draw/engines/workbench/workbench_shader_shared.h @@ -13,7 +13,8 @@ struct LightData { }; struct WorldData { - float4 viewport_size; + float2 viewport_size; + float2 viewport_size_inv; float4 object_outline_color; float4 shadow_direction_vs; float shadow_focus; @@ -41,8 +42,23 @@ struct WorldData { int matcap_orientation; bool use_specular; + float xray_alpha; int _pad1; - int _pad2; + + float4 background_color; }; -#define viewport_size_inv viewport_size.zw +struct ExtrudedFrustum { + /** \note vec3 array padded to vec4. */ + float4 corners[16]; + float4 planes[12]; + int corners_count; + int planes_count; + int _padding[2]; +}; + +struct ShadowPassData { + float4 far_plane; + float3 light_direction_ws; + int _padding; +}; diff --git a/source/blender/draw/engines/workbench/workbench_shadow.cc b/source/blender/draw/engines/workbench/workbench_shadow.cc new file mode 100644 index 00000000000..22c7b663220 --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_shadow.cc @@ -0,0 +1,461 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup draw_engine + * + * Shadow: + * + * Use stencil shadow buffer to cast a sharp shadow over opaque surfaces. + * + * After the main pre-pass we render shadow volumes using custom depth & stencil states to + * set the stencil of shadowed area to anything but 0. + * + * Then the shading pass will shade the areas with stencil not equal 0 differently. + */ + +#include "BKE_object.h" +#include "BLI_math.h" +#include "DRW_render.h" +#include "GPU_compute.h" + +#include "workbench_private.hh" + +#define DEBUG_SHADOW_VOLUME 0 + +namespace blender::workbench { + +ShadowPass::ShadowView::ShadowView() : View("ShadowPass.View"){}; + +void ShadowPass::ShadowView::setup(View &view, float3 light_direction, bool force_fail_method) +{ + force_fail_method_ = force_fail_method; + light_direction_ = light_direction; + sync(view.viewmat(), view.winmat()); + + /* Prepare frustum extruded in the negative light direction, + * so we can test regular bounding boxes against it for culling. */ + + /* Frustum Corners indices + * Z Y + * | / + * |/ + * .-----X + * 3----------7 + * /| /| + * / | / | + * 0----------4 | + * | | | | + * | 2-------|--6 + * | / | / + * |/ |/ + * 1----------5 + */ + + /* Frustum Planes indices */ + const int x_neg = 0; /* Left */ + const int x_pos = 5; /* Right */ + const int y_neg = 1; /* Bottom */ + const int y_pos = 3; /* Top */ + const int z_pos = 4; /* Near */ + const int z_neg = 2; /* Far */ + + int3 corner_faces[8] = {{x_neg, y_neg, z_pos}, + {x_neg, y_neg, z_neg}, + {x_neg, y_pos, z_neg}, + {x_neg, y_pos, z_pos}, + {x_pos, y_neg, z_pos}, + {x_pos, y_neg, z_neg}, + {x_pos, y_pos, z_neg}, + {x_pos, y_pos, z_pos}}; + + int2 edge_faces[12] = {{x_neg, y_neg}, + {x_neg, z_neg}, + {x_neg, y_pos}, + {x_neg, z_pos}, + {y_neg, x_pos}, + {z_neg, x_pos}, + {y_pos, x_pos}, + {z_pos, x_pos}, + {y_neg, z_pos}, + {z_neg, y_neg}, + {y_pos, z_neg}, + {z_pos, y_pos}}; + + int2 edge_corners[12] = {{0, 1}, + {1, 2}, + {2, 3}, + {3, 0}, + {4, 5}, + {5, 6}, + {6, 7}, + {7, 4}, + {0, 4}, + {1, 5}, + {2, 6}, + {3, 7}}; + + BoundBox frustum_corners; + DRW_culling_frustum_corners_get(nullptr, &frustum_corners); + float4 frustum_planes[6]; + DRW_culling_frustum_planes_get(nullptr, (float(*)[4])frustum_planes); + + Vector faces_result = {}; + Vector corners_result = {}; + + /* "Unlit" frustum faces are left "as-is" */ + + bool face_lit[6]; + for (int i : IndexRange(6)) { + /* Make the frustum normals face outwards */ + frustum_planes[i] *= float4(-1, -1, -1, 1); + + face_lit[i] = math::dot(float3(frustum_planes[i]), light_direction_) < 0; + if (!face_lit[i]) { + faces_result.append(frustum_planes[i]); + } + } + + /* Edges between lit and unlit faces are extruded "infinitely" towards the light source */ + + for (int i : IndexRange(12)) { + int2 f = edge_faces[i]; + bool a_lit = face_lit[f[0]]; + bool b_lit = face_lit[f[1]]; + if (a_lit != b_lit) { + /* Extrude Face */ + float3 corner_a = frustum_corners.vec[edge_corners[i][0]]; + float3 corner_b = frustum_corners.vec[edge_corners[i][1]]; + float3 edge_direction = math::normalize(corner_b - corner_a); + float3 normal = math::normalize(math::cross(light_direction_, edge_direction)); + + float4 extruded_face = float4(UNPACK3(normal), math::dot(normal, corner_a)); + + /* Ensure the plane faces outwards */ + bool flipped = false; + for (float3 corner : frustum_corners.vec) { + if (math::dot(float3(extruded_face), corner) > (extruded_face.w + 0.1)) { + BLI_assert(!flipped); + flipped = true; + extruded_face *= -1; + } + } + + faces_result.append(extruded_face); + } + } + + for (int i_corner : IndexRange(8)) { + int lit_faces = 0; + for (int i_face : IndexRange(3)) { + lit_faces += face_lit[corner_faces[i_corner][i_face]] ? 1 : 0; + } + if (lit_faces < 3) { + /* Add original corner */ + corners_result.append(frustum_corners.vec[i_corner]); + + if (lit_faces > 0) { + /* Add extruded corner */ + corners_result.append(float3(frustum_corners.vec[i_corner]) - (light_direction_ * 1e4f)); + } + } + } + + for (int i : corners_result.index_range()) { + extruded_frustum_.corners[i] = float4(corners_result[i], 1); + } + extruded_frustum_.corners_count = corners_result.size(); + + for (int i : faces_result.index_range()) { + extruded_frustum_.planes[i] = faces_result[i]; + } + extruded_frustum_.planes_count = faces_result.size(); + + extruded_frustum_.push_update(); +} + +bool ShadowPass::ShadowView::debug_object_culling(Object *ob) +{ + printf("Test %s\n", ob->id.name); + const BoundBox *_bbox = BKE_object_boundbox_get(ob); + for (int p : IndexRange(extruded_frustum_.planes_count)) { + float4 plane = extruded_frustum_.planes[p]; + bool separating_axis = true; + for (float3 corner : _bbox->vec) { + corner = float4x4(ob->object_to_world) * corner; + float signed_distance = math::dot(corner, float3(plane)) - plane.w; + if (signed_distance <= 0) { + separating_axis = false; + break; + } + } + if (separating_axis) { + printf("Sepatating Axis >>> x: %f, y: %f, z: %f, w: %f \n", UNPACK4(plane)); + return true; + } + } + return false; +} + +void ShadowPass::ShadowView::set_mode(ShadowPass::PassType type) +{ + current_pass_type_ = type; +} + +void ShadowPass::ShadowView::compute_visibility(ObjectBoundsBuf &bounds, + uint resource_len, + bool debug_freeze) +{ + GPU_debug_group_begin("ShadowView.compute_visibility"); + + uint word_per_draw = this->visibility_word_per_draw(); + /* Switch between tightly packed and set of whole word per instance. */ + uint words_len = (view_len_ == 1) ? divide_ceil_u(resource_len, 32) : + resource_len * word_per_draw; + words_len = ceil_to_multiple_u(max_ii(1, words_len), 4); + uint32_t data = 0xFFFFFFFFu; + + if (current_pass_type_ == ShadowPass::PASS) { + /* TODO(fclem): Resize to nearest pow2 to reduce fragmentation. */ + pass_visibility_buf_.resize(words_len); + GPU_storagebuf_clear(pass_visibility_buf_, GPU_R32UI, GPU_DATA_UINT, &data); + fail_visibility_buf_.resize(words_len); + GPU_storagebuf_clear(fail_visibility_buf_, GPU_R32UI, GPU_DATA_UINT, &data); + } + else if (current_pass_type_ == ShadowPass::FAIL) { + /* Already computed in the ShadowPass::PASS */ + GPU_debug_group_end(); + return; + } + else { + visibility_buf_.resize(words_len); + GPU_storagebuf_clear(visibility_buf_, GPU_R32UI, GPU_DATA_UINT, &data); + } + + if (do_visibility_) { + /* TODO(Miguel Pozo): Use regular culling for the caps pass */ + + static GPUShader *dynamic_pass_type_shader = GPU_shader_create_from_info_name( + "workbench_next_shadow_visibility_compute_dynamic_pass_type"); + static GPUShader *static_pass_type_shader = GPU_shader_create_from_info_name( + "workbench_next_shadow_visibility_compute_static_pass_type"); + + GPUShader *shader = current_pass_type_ == ShadowPass::FORCED_FAIL ? static_pass_type_shader : + dynamic_pass_type_shader; + GPU_shader_bind(shader); + GPU_shader_uniform_1i(shader, "resource_len", resource_len); + GPU_shader_uniform_1i(shader, "view_len", view_len_); + GPU_shader_uniform_1i(shader, "visibility_word_per_draw", word_per_draw); + GPU_shader_uniform_1b(shader, "force_fail_method", force_fail_method_); + GPU_shader_uniform_3fv(shader, "shadow_direction", light_direction_); + GPU_uniformbuf_bind(extruded_frustum_, + GPU_shader_get_uniform_block(shader, "extruded_frustum")); + GPU_storagebuf_bind(bounds, GPU_shader_get_ssbo(shader, "bounds_buf")); + if (current_pass_type_ == ShadowPass::FORCED_FAIL) { + GPU_storagebuf_bind(visibility_buf_, GPU_shader_get_ssbo(shader, "visibility_buf")); + } + else { + GPU_storagebuf_bind(pass_visibility_buf_, + GPU_shader_get_ssbo(shader, "pass_visibility_buf")); + GPU_storagebuf_bind(fail_visibility_buf_, + GPU_shader_get_ssbo(shader, "fail_visibility_buf")); + } + GPU_uniformbuf_bind(data_, DRW_VIEW_UBO_SLOT); + GPU_compute_dispatch(shader, divide_ceil_u(resource_len, DRW_VISIBILITY_GROUP_SIZE), 1, 1); + GPU_memory_barrier(GPU_BARRIER_SHADER_STORAGE); + } + + GPU_debug_group_end(); +} + +VisibilityBuf &ShadowPass::ShadowView::get_visibility_buffer() +{ + switch (current_pass_type_) { + case ShadowPass::PASS: + return pass_visibility_buf_; + case ShadowPass::FAIL: + return fail_visibility_buf_; + case ShadowPass::FORCED_FAIL: + return visibility_buf_; + default: + BLI_assert_unreachable(); + } + return visibility_buf_; +} + +PassMain::Sub *&ShadowPass::get_pass_ptr(PassType type, bool manifold, bool cap /*= false*/) +{ + return passes_[type][manifold][cap]; +} + +GPUShader *ShadowPass::get_shader(bool depth_pass, bool manifold, bool cap /*= false*/) +{ + GPUShader *&shader = shaders_[depth_pass][manifold][cap]; + + if (shader == nullptr) { + std::string create_info_name = "workbench_next_shadow"; + create_info_name += (depth_pass) ? "_pass" : "_fail"; + create_info_name += (manifold) ? "_manifold" : "_no_manifold"; + create_info_name += (cap) ? "_caps" : "_no_caps"; +#if DEBUG_SHADOW_VOLUME + create_info_name += "_debug"; +#endif + shader = GPU_shader_create_from_info_name(create_info_name.c_str()); + } + return shader; +} + +void ShadowPass::init(const SceneState &scene_state, SceneResources &resources) +{ + enabled_ = scene_state.draw_shadows; + if (!enabled_) { + resources.world_buf.shadow_mul = 0.0f; + resources.world_buf.shadow_add = 1.0f; + return; + } + const Scene &scene = *scene_state.scene; + + float3 direction_ws = scene.display.light_direction; + /* Turn the light in a way where it's more user friendly to control. */ + SWAP(float, direction_ws.y, direction_ws.z); + direction_ws *= float3(-1, 1, -1); + + float planes[6][4]; + DRW_culling_frustum_planes_get(nullptr, planes); + + pass_data_.light_direction_ws = direction_ws; + pass_data_.far_plane = planes[2] * float4(-1, -1, -1, 1); + pass_data_.push_update(); + + /* Shadow direction. */ + float4x4 view_matrix; + DRW_view_viewmat_get(NULL, view_matrix.ptr(), false); + resources.world_buf.shadow_direction_vs = float4(view_matrix.ref_3x3() * direction_ws); + + /* Clamp to avoid overshadowing and shading errors. */ + float focus = clamp_f(scene.display.shadow_focus, 0.0001f, 0.99999f); + resources.world_buf.shadow_shift = scene.display.shadow_shift; + resources.world_buf.shadow_focus = 1.0f - focus * (1.0f - resources.world_buf.shadow_shift); + resources.world_buf.shadow_mul = scene_state.shading.shadow_intensity; + resources.world_buf.shadow_add = 1.0f - resources.world_buf.shadow_mul; +} + +void ShadowPass::sync() +{ + if (!enabled_) { + return; + } + +#if DEBUG_SHADOW_VOLUME + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ADD_FULL; + DRWState depth_pass_state = state | DRW_STATE_DEPTH_LESS; + DRWState depth_fail_state = state | DRW_STATE_DEPTH_GREATER_EQUAL; +#else + DRWState state = DRW_STATE_DEPTH_LESS | DRW_STATE_STENCIL_ALWAYS; + DRWState depth_pass_state = state | DRW_STATE_WRITE_STENCIL_SHADOW_PASS; + DRWState depth_fail_state = state | DRW_STATE_WRITE_STENCIL_SHADOW_FAIL; +#endif + + pass_ps_.init(); + pass_ps_.state_set(depth_pass_state); + pass_ps_.state_stencil(0xFF, 0xFF, 0xFF); + + fail_ps_.init(); + fail_ps_.state_set(depth_fail_state); + fail_ps_.state_stencil(0xFF, 0xFF, 0xFF); + + forced_fail_ps_.init(); + forced_fail_ps_.state_set(depth_fail_state); + forced_fail_ps_.state_stencil(0xFF, 0xFF, 0xFF); + + /* Stencil Shadow passes. */ + for (bool manifold : {false, true}) { + PassMain::Sub *&ps = get_pass_ptr(PASS, manifold); + ps = &pass_ps_.sub(manifold ? "manifold" : "non_manifold"); + ps->shader_set(get_shader(true, manifold)); + ps->bind_ubo("pass_data", pass_data_); + + for (PassType fail_type : {FAIL, FORCED_FAIL}) { + PassMain &ps_main = fail_type == FAIL ? fail_ps_ : forced_fail_ps_; + + PassMain::Sub *&ps = get_pass_ptr(fail_type, manifold, false); + ps = &ps_main.sub(manifold ? "NoCaps.manifold" : "NoCaps.non_manifold"); + ps->shader_set(get_shader(false, manifold, false)); + ps->bind_ubo("pass_data", pass_data_); + + PassMain::Sub *&caps_ps = get_pass_ptr(fail_type, manifold, true); + caps_ps = &ps_main.sub(manifold ? "Caps.manifold" : "Caps.non_manifold"); + caps_ps->shader_set(get_shader(false, manifold, true)); + caps_ps->bind_ubo("pass_data", pass_data_); + } + } +} + +void ShadowPass::object_sync(Manager &manager, + SceneState &scene_state, + ObjectRef &ob_ref, + ResourceHandle handle, + const bool has_transp_mat) +{ + if (!enabled_) { + return; + } + + Object *ob = ob_ref.object; + bool is_manifold; + GPUBatch *geom_shadow = DRW_cache_object_edge_detection_get(ob, &is_manifold); + if (geom_shadow == nullptr) { + return; + } + +#define DEBUG_CULLING 0 +#if DEBUG_CULLING + View view = View("View", DRW_view_default_get()); + ShadowView shadow_view = ShadowView("ShadowView", view, pass_data_.light_direction_ws); + printf( + "%s culling : %s\n", ob->id.name, shadow_view.debug_object_culling(ob) ? "true" : "false"); +#endif + + /* Shadow pass technique needs object to be have all its surface opaque. */ + /* We cannot use the PASS technique on non-manifold object (see T76168). */ + bool force_fail_pass = has_transp_mat || (!is_manifold && (scene_state.cull_state != 0)); + + PassType fail_type = force_fail_pass ? FORCED_FAIL : FAIL; + + /* Unless we force the FAIL Method we add draw commands to both methods, + * then the visibility compute shader selects the one needed */ + + if (!force_fail_pass) { + PassMain::Sub &ps = *get_pass_ptr(PASS, is_manifold); + ps.draw(geom_shadow, handle); + } + + get_pass_ptr(fail_type, is_manifold, true)->draw(DRW_cache_object_surface_get(ob), handle); + get_pass_ptr(fail_type, is_manifold, false)->draw(geom_shadow, handle); +} + +void ShadowPass::draw(Manager &manager, + View &view, + SceneResources &resources, + int2 resolution, + GPUTexture &depth_stencil_tx, + bool force_fail_method) +{ + if (!enabled_) { + return; + } + + fb_.ensure(GPU_ATTACHMENT_TEXTURE(&depth_stencil_tx), + GPU_ATTACHMENT_TEXTURE(resources.color_tx)); + fb_.bind(); + + view_.setup(view, pass_data_.light_direction_ws, force_fail_method); + + view_.set_mode(PASS); + manager.submit(pass_ps_, view_); + view_.set_mode(FAIL); + manager.submit(fail_ps_, view_); + view_.set_mode(FORCED_FAIL); + manager.submit(forced_fail_ps_, view_); +} + +} // namespace blender::workbench diff --git a/source/blender/draw/engines/workbench/workbench_state.cc b/source/blender/draw/engines/workbench/workbench_state.cc new file mode 100644 index 00000000000..8dd20684e71 --- /dev/null +++ b/source/blender/draw/engines/workbench/workbench_state.cc @@ -0,0 +1,301 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "workbench_private.hh" + +#include "BKE_camera.h" +#include "BKE_editmesh.h" +#include "BKE_modifier.h" +#include "BKE_object.h" +#include "BKE_paint.h" +#include "BKE_particle.h" +#include "BKE_pbvh.h" +#include "DEG_depsgraph_query.h" +#include "DNA_fluid_types.h" +#include "ED_paint.h" +#include "ED_view3d.h" +#include "GPU_capabilities.h" + +namespace blender::workbench { + +void SceneState::init(Object *camera_ob /*= nullptr*/) +{ + bool reset_taa = reset_taa_next_sample; + reset_taa_next_sample = false; + + const DRWContextState *context = DRW_context_state_get(); + View3D *v3d = context->v3d; + RegionView3D *rv3d = context->rv3d; + + scene = DEG_get_evaluated_scene(context->depsgraph); + + GPUTexture *viewport_tx = DRW_viewport_texture_list_get()->color; + resolution = int2(GPU_texture_width(viewport_tx), GPU_texture_height(viewport_tx)); + + camera_object = camera_ob; + if (camera_object == nullptr && v3d && rv3d) { + camera_object = (rv3d->persp == RV3D_CAMOB) ? v3d->camera : nullptr; + } + camera = camera_object && camera_object->type == OB_CAMERA ? + static_cast(camera_object->data) : + nullptr; + + object_mode = CTX_data_mode_enum_ex(context->object_edit, context->obact, context->object_mode); + + /* TODO(Miguel Pozo): + * Check why Workbench Next exposes OB_MATERIAL, and Workbench exposes OB_RENDER */ + bool is_render_mode = !v3d || ELEM(v3d->shading.type, OB_RENDER, OB_MATERIAL); + + const View3DShading previous_shading = shading; + shading = is_render_mode ? scene->display.shading : v3d->shading; + + cull_state = shading.flag & V3D_SHADING_BACKFACE_CULLING ? DRW_STATE_CULL_BACK : + DRW_STATE_NO_DRAW; + + /* FIXME: This reproduce old behavior when workbench was separated in 2 engines. + * But this is a workaround for a missing update tagging. */ + DRWState new_clip_state = RV3D_CLIPPING_ENABLED(v3d, rv3d) ? DRW_STATE_CLIP_PLANES : + DRW_STATE_NO_DRAW; + DRWState old_clip_state = clip_planes.size() > 0 ? DRW_STATE_CLIP_PLANES : DRW_STATE_NO_DRAW; + if (new_clip_state != old_clip_state) { + reset_taa = true; + } + clip_planes.clear(); + if (new_clip_state & DRW_STATE_CLIP_PLANES) { + int plane_len = (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXCLIP) ? 4 : 6; + for (auto i : IndexRange(plane_len)) { + clip_planes.append(rv3d->clip[i]); + } + } + + if (!is_render_mode) { + if (shading.type < OB_SOLID) { + shading.light = V3D_LIGHTING_FLAT; + shading.color_type = V3D_SHADING_OBJECT_COLOR; + shading.xray_alpha = 0.0f; + } + else if (SHADING_XRAY_ENABLED(shading)) { + shading.xray_alpha = SHADING_XRAY_ALPHA(shading); + } + else { + shading.xray_alpha = 1.0f; + } + } + xray_mode = !is_render_mode && shading.xray_alpha != 1.0f; + + if (SHADING_XRAY_FLAG_ENABLED(shading)) { + /* Disable shading options that aren't supported in transparency mode. */ + shading.flag &= ~(V3D_SHADING_SHADOW | V3D_SHADING_CAVITY | V3D_SHADING_DEPTH_OF_FIELD); + } + if (SHADING_XRAY_ENABLED(shading) != SHADING_XRAY_ENABLED(previous_shading) || + shading.flag != previous_shading.flag) { + reset_taa = true; + } + + lighting_type = lighting_type_from_v3d_lighting(shading.light); + material_override = Material(shading.single_color); + + background_color = float4(0.0f); + if (is_render_mode && scene->r.alphamode != R_ALPHAPREMUL) { + if (World *w = scene->world) { + background_color = float4(w->horr, w->horg, w->horb, 1.0f); + } + } + + if (rv3d && rv3d->rflag & RV3D_GPULIGHT_UPDATE) { + reset_taa = true; + /* FIXME: This reproduce old behavior when workbench was separated in 2 engines. + * But this is a workaround for a missing update tagging. */ + rv3d->rflag &= ~RV3D_GPULIGHT_UPDATE; + } + + float4x4 matrix; + /*TODO(Miguel Pozo): New API ?*/ + DRW_view_persmat_get(nullptr, matrix.ptr(), false); + if (matrix != view_projection_matrix) { + view_projection_matrix = matrix; + reset_taa = true; + } + + bool is_playback = DRW_state_is_playback(); + bool is_navigating = DRW_state_is_navigating(); + + /* Reset complete drawing when navigating or during viewport playback or when + * leaving one of those states. In case of multires modifier the navigation + * mesh differs from the viewport mesh, so we need to be sure to restart. */ + if (is_playback || is_navigating) { + reset_taa = true; + reset_taa_next_sample = true; + } + + int _samples_len = U.viewport_aa; + if (v3d && ELEM(v3d->shading.type, OB_RENDER, OB_MATERIAL)) { + _samples_len = scene->display.viewport_aa; + } + else if (DRW_state_is_image_render()) { + _samples_len = scene->display.render_aa; + } + if (is_navigating || is_playback) { + /* Only draw using SMAA or no AA when navigating. */ + _samples_len = min_ii(_samples_len, 1); + } + /* 0 samples means no AA */ + draw_aa = _samples_len > 0; + _samples_len = max_ii(_samples_len, 1); + + /* Reset the TAA when we have already draw a sample, but the sample count differs from previous + * time. This removes render artifacts when the viewport anti-aliasing in the user preferences + * is set to a lower value. */ + if (samples_len != _samples_len) { + samples_len = _samples_len; + reset_taa = true; + } + + if (reset_taa || samples_len <= 1) { + sample = 0; + } + else { + sample++; + } + render_finished = sample >= samples_len && samples_len > 1; + + /* TODO(Miguel Pozo) volumes_do */ + + draw_cavity = shading.flag & V3D_SHADING_CAVITY && + ELEM(shading.cavity_type, V3D_SHADING_CAVITY_SSAO, V3D_SHADING_CAVITY_BOTH); + draw_curvature = shading.flag & V3D_SHADING_CAVITY && ELEM(shading.cavity_type, + V3D_SHADING_CAVITY_CURVATURE, + V3D_SHADING_CAVITY_BOTH); + draw_shadows = shading.flag & V3D_SHADING_SHADOW; + draw_outline = shading.flag & V3D_SHADING_OBJECT_OUTLINE; + draw_dof = camera && camera->dof.flag & CAM_DOF_ENABLED && + shading.flag & V3D_SHADING_DEPTH_OF_FIELD; + + draw_transparent_depth = draw_outline || draw_dof; + draw_object_id = draw_outline || draw_curvature; +}; + +static const CustomData *get_loop_custom_data(const Mesh *mesh) +{ + if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) { + BLI_assert(mesh->edit_mesh != nullptr); + BLI_assert(mesh->edit_mesh->bm != nullptr); + return &mesh->edit_mesh->bm->ldata; + } + return &mesh->ldata; +} + +static const CustomData *get_vert_custom_data(const Mesh *mesh) +{ + if (mesh->runtime->wrapper_type == ME_WRAPPER_TYPE_BMESH) { + BLI_assert(mesh->edit_mesh != nullptr); + BLI_assert(mesh->edit_mesh->bm != nullptr); + return &mesh->edit_mesh->bm->vdata; + } + return &mesh->vdata; +} + +ObjectState::ObjectState(const SceneState &scene_state, Object *ob) +{ + sculpt_pbvh = false; + texture_paint_mode = false; + image_paint_override = nullptr; + override_sampler_state = GPU_SAMPLER_DEFAULT; + draw_shadow = false; + + const DRWContextState *draw_ctx = DRW_context_state_get(); + const Mesh *me = (ob->type == OB_MESH) ? static_cast(ob->data) : nullptr; + const bool is_active = (ob == draw_ctx->obact); + /* TODO(Miguel Pozo) Is the double check needed? + * If it is, wouldn't be needed for sculpt_pbvh too? + */ + const bool is_render = DRW_state_is_image_render() && (draw_ctx->v3d == nullptr); + + color_type = (eV3DShadingColorType)scene_state.shading.color_type; + if (!(is_active && DRW_object_use_hide_faces(ob))) { + draw_shadow = (ob->dtx & OB_DRAW_NO_SHADOW_CAST) == 0 && scene_state.draw_shadows; + } + if (me == nullptr) { + if (color_type == V3D_SHADING_TEXTURE_COLOR) { + color_type = V3D_SHADING_MATERIAL_COLOR; + } + else if (color_type == V3D_SHADING_VERTEX_COLOR) { + color_type = V3D_SHADING_OBJECT_COLOR; + } + use_per_material_batches = color_type == V3D_SHADING_MATERIAL_COLOR; + /* Early return */ + return; + } + + sculpt_pbvh = BKE_sculptsession_use_pbvh_draw(ob, draw_ctx->rv3d) && + !DRW_state_is_image_render(); + + if (sculpt_pbvh) { + /* Shadows are unsupported in sculpt mode. We could revert to the slow + * method in this case but I'm not sure if it's a good idea given that + * sculpted meshes are heavy to begin with. */ + draw_shadow = false; + + if (color_type == V3D_SHADING_TEXTURE_COLOR && BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_FACES) { + /* Force use of material color for sculpt. */ + color_type = V3D_SHADING_MATERIAL_COLOR; + } + + /* Bad call C is required to access the tool system that is context aware. Cast to non-const + * due to current API. */ + bContext *C = (bContext *)DRW_context_state_get()->evil_C; + if (C != NULL) { + color_type = ED_paint_shading_color_override( + C, &scene_state.scene->toolsettings->paint_mode, ob, color_type); + } + } + else { + const CustomData *cd_vdata = get_vert_custom_data(me); + const CustomData *cd_ldata = get_loop_custom_data(me); + + bool has_color = (CustomData_has_layer(cd_vdata, CD_PROP_COLOR) || + CustomData_has_layer(cd_vdata, CD_PROP_BYTE_COLOR) || + CustomData_has_layer(cd_ldata, CD_PROP_COLOR) || + CustomData_has_layer(cd_ldata, CD_PROP_BYTE_COLOR)); + + bool has_uv = CustomData_has_layer(cd_ldata, CD_PROP_FLOAT2); + + if (color_type == V3D_SHADING_TEXTURE_COLOR) { + if (ob->dt < OB_TEXTURE || !has_uv) { + color_type = V3D_SHADING_MATERIAL_COLOR; + } + } + else if (color_type == V3D_SHADING_VERTEX_COLOR && !has_color) { + color_type = V3D_SHADING_OBJECT_COLOR; + } + + if (!is_render) { + /* Force texture or vertex mode if object is in paint mode. */ + const bool is_vertpaint_mode = is_active && + (scene_state.object_mode == CTX_MODE_PAINT_VERTEX); + const bool is_texpaint_mode = is_active && + (scene_state.object_mode == CTX_MODE_PAINT_TEXTURE); + if (is_vertpaint_mode && has_color) { + color_type = V3D_SHADING_VERTEX_COLOR; + } + else if (is_texpaint_mode && has_uv) { + color_type = V3D_SHADING_TEXTURE_COLOR; + texture_paint_mode = true; + + const ImagePaintSettings *imapaint = &scene_state.scene->toolsettings->imapaint; + if (imapaint->mode == IMAGEPAINT_MODE_IMAGE) { + image_paint_override = imapaint->canvas; + override_sampler_state = GPU_SAMPLER_REPEAT; + SET_FLAG_FROM_TEST(override_sampler_state, + imapaint->interp == IMAGEPAINT_INTERP_LINEAR, + GPU_SAMPLER_FILTER); + } + } + } + } + + use_per_material_batches = image_paint_override == nullptr && ELEM(color_type, + V3D_SHADING_TEXTURE_COLOR, + V3D_SHADING_MATERIAL_COLOR); +} + +} // namespace blender::workbench diff --git a/source/blender/draw/intern/DRW_gpu_wrapper.hh b/source/blender/draw/intern/DRW_gpu_wrapper.hh index 1653dedebba..6d8c4cc8e87 100644 --- a/source/blender/draw/intern/DRW_gpu_wrapper.hh +++ b/source/blender/draw/intern/DRW_gpu_wrapper.hh @@ -1085,6 +1085,16 @@ class Framebuffer : NonCopyable { GPU_framebuffer_default_size(fb_, UNPACK2(target_size)); } + void bind() + { + GPU_framebuffer_bind(fb_); + } + + void clear_depth(float depth) + { + GPU_framebuffer_clear_depth(fb_, depth); + } + Framebuffer &operator=(Framebuffer &&a) { if (*this != a) { diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 0cb89d94d41..289f4355a54 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -1183,6 +1183,11 @@ static void drw_engines_enable_from_engine(const RenderEngineType *engine_type, switch (drawtype) { case OB_WIRE: case OB_SOLID: + if (U.experimental.enable_workbench_next && + strcmp(engine_type->idname, "BLENDER_WORKBENCH_NEXT") == 0) { + use_drw_engine(DRW_engine_viewport_workbench_next_type.draw_engine); + break; + } use_drw_engine(DRW_engine_viewport_workbench_type.draw_engine); break; case OB_MATERIAL: @@ -2990,6 +2995,9 @@ void DRW_engines_register_experimental(void) if (U.experimental.enable_eevee_next) { RE_engines_register(&DRW_engine_viewport_eevee_next_type); } + if (U.experimental.enable_workbench_next) { + RE_engines_register(&DRW_engine_viewport_workbench_next_type); + } } void DRW_engines_register(void) diff --git a/source/blender/draw/intern/draw_manager.cc b/source/blender/draw/intern/draw_manager.cc index 7bf83872344..c222d52141c 100644 --- a/source/blender/draw/intern/draw_manager.cc +++ b/source/blender/draw/intern/draw_manager.cc @@ -178,7 +178,7 @@ void Manager::submit(PassMain &pass, View &view) pass.draw_commands_buf_.bind(state, pass.headers_, pass.commands_, - view.visibility_buf_, + view.get_visibility_buffer(), view.visibility_word_per_draw(), view.view_len_); @@ -221,7 +221,7 @@ Manager::SubmitDebugOutput Manager::submit_debug(PassSimple &pass, View &view) output.resource_id = {pass.draw_commands_buf_.resource_id_buf_.data(), pass.draw_commands_buf_.resource_id_count_}; /* There is no visibility data for PassSimple. */ - output.visibility = {(uint *)view.visibility_buf_.data(), 0}; + output.visibility = {(uint *)view.get_visibility_buffer().data(), 0}; return output; } @@ -232,12 +232,13 @@ Manager::SubmitDebugOutput Manager::submit_debug(PassMain &pass, View &view) GPU_finish(); pass.draw_commands_buf_.resource_id_buf_.read(); - view.visibility_buf_.read(); + view.get_visibility_buffer().read(); Manager::SubmitDebugOutput output; output.resource_id = {pass.draw_commands_buf_.resource_id_buf_.data(), pass.draw_commands_buf_.resource_id_count_}; - output.visibility = {(uint *)view.visibility_buf_.data(), divide_ceil_u(resource_len_, 32)}; + output.visibility = {(uint *)view.get_visibility_buffer().data(), + divide_ceil_u(resource_len_, 32)}; return output; } diff --git a/source/blender/draw/intern/draw_pass.hh b/source/blender/draw/intern/draw_pass.hh index 6244218f3ff..8fc8298491e 100644 --- a/source/blender/draw/intern/draw_pass.hh +++ b/source/blender/draw/intern/draw_pass.hh @@ -256,6 +256,7 @@ class PassBase { /** * Record a compute dispatch call. */ + void dispatch(int2 group_len); void dispatch(int3 group_len); void dispatch(int3 *group_len); void dispatch(StorageBuffer &indirect_buffer); @@ -709,6 +710,12 @@ inline void PassBase::draw_procedural_indirect( /** \name Compute Dispatch Implementation * \{ */ +template inline void PassBase::dispatch(int2 group_len) +{ + BLI_assert(shader_); + create_command(Type::Dispatch).dispatch = {int3(group_len.x, group_len.y, 1)}; +} + template inline void PassBase::dispatch(int3 group_len) { BLI_assert(shader_); diff --git a/source/blender/draw/intern/draw_view.cc b/source/blender/draw/intern/draw_view.cc index 58212d2b17f..8037d16fa5b 100644 --- a/source/blender/draw/intern/draw_view.cc +++ b/source/blender/draw/intern/draw_view.cc @@ -31,6 +31,14 @@ void View::sync(const float4x4 &view_mat, const float4x4 &win_mat, int view_id) dirty_ = true; } +void View::sync(const DRWView *view) +{ + float4x4 view_mat, win_mat; + DRW_view_viewmat_get(view, view_mat.ptr(), false); + DRW_view_winmat_get(view, win_mat.ptr(), false); + this->sync(view_mat, win_mat); +} + void View::frustum_boundbox_calc(int view_id) { /* Extract the 8 corners from a Projection Matrix. */ @@ -297,4 +305,9 @@ void View::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool d GPU_debug_group_end(); } +VisibilityBuf &View::get_visibility_buffer() +{ + return visibility_buf_; +} + } // namespace blender::draw diff --git a/source/blender/draw/intern/draw_view.hh b/source/blender/draw/intern/draw_view.hh index e18abf94fce..3e93e0043aa 100644 --- a/source/blender/draw/intern/draw_view.hh +++ b/source/blender/draw/intern/draw_view.hh @@ -32,7 +32,7 @@ using VisibilityBuf = StorageArrayBuffer; class View { friend Manager; - private: + protected: /** TODO(fclem): Maybe try to reduce the minimum cost if the number of view is lower. */ UniformArrayBuffer data_; @@ -64,14 +64,14 @@ class View { View(const char *name, const DRWView *view) : visibility_buf_(name), debug_name_(name), view_len_(1) { - float4x4 view_mat, win_mat; - DRW_view_viewmat_get(view, view_mat.ptr(), false); - DRW_view_winmat_get(view, win_mat.ptr(), false); - this->sync(view_mat, win_mat); + this->sync(view); } void sync(const float4x4 &view_mat, const float4x4 &win_mat, int view_id = 0); + /* For compatibility with old system. Will be removed at some point. */ + void sync(const DRWView *view); + /** Disable a range in the multi-view array. Disabled view will not produce any instances. */ void disable(IndexRange range); @@ -147,10 +147,11 @@ class View { return data_; } - private: + protected: /** Called from draw manager. */ void bind(); - void compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool debug_freeze); + virtual void compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool debug_freeze); + virtual VisibilityBuf &get_visibility_buffer(); void update_viewport_size(); diff --git a/source/blender/draw/intern/shaders/draw_view_info.hh b/source/blender/draw/intern/shaders/draw_view_info.hh index e18bd469ff0..ee274ef9d59 100644 --- a/source/blender/draw/intern/shaders/draw_view_info.hh +++ b/source/blender/draw/intern/shaders/draw_view_info.hh @@ -210,6 +210,9 @@ GPU_SHADER_CREATE_INFO(draw_resource_id_fallback) .define("UNIFORM_RESOURCE_ID_NEW") .vertex_in(15, Type::INT, "drw_ResourceID"); +/** TODO mask view id bits. */ +GPU_SHADER_CREATE_INFO(draw_resource_handle_new).define("resource_handle", "drw_ResourceID"); + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/draw/intern/smaa_textures.h b/source/blender/draw/intern/smaa_textures.h index a6541f6b164..f9a0bef7047 100644 --- a/source/blender/draw/intern/smaa_textures.h +++ b/source/blender/draw/intern/smaa_textures.h @@ -7,6 +7,10 @@ #pragma once +#ifdef __cplusplus +extern "C" { +#endif + #define AREATEX_WIDTH 160 #define AREATEX_HEIGHT 560 #define AREATEX_PITCH (AREATEX_WIDTH * 2) @@ -28,3 +32,8 @@ extern const unsigned char areaTexBytes[]; * - DX10: DXGI_FORMAT_R8_UNORM */ extern const unsigned char searchTexBytes[]; + +#ifdef __cplusplus +} +#endif + diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index def080b267e..57939bd1f46 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -1297,13 +1297,21 @@ void ED_scene_draw_fps(const struct Scene *scene, int xoffset, int *yoffset); void ED_view3d_stop_render_preview(struct wmWindowManager *wm, struct ARegion *region); void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrArea *area); -#define XRAY_ALPHA(v3d) \ - (((v3d)->shading.type == OB_WIRE) ? (v3d)->shading.xray_alpha_wire : (v3d)->shading.xray_alpha) -#define XRAY_FLAG(v3d) \ - (((v3d)->shading.type == OB_WIRE) ? V3D_SHADING_XRAY_WIREFRAME : V3D_SHADING_XRAY) -#define XRAY_FLAG_ENABLED(v3d) (((v3d)->shading.flag & XRAY_FLAG(v3d)) != 0) -#define XRAY_ENABLED(v3d) (XRAY_FLAG_ENABLED(v3d) && (XRAY_ALPHA(v3d) < 1.0f)) -#define XRAY_ACTIVE(v3d) (XRAY_ENABLED(v3d) && ((v3d)->shading.type < OB_MATERIAL)) +#define SHADING_XRAY_ALPHA(shading) \ + (((shading).type == OB_WIRE) ? (shading).xray_alpha_wire : (shading).xray_alpha) +#define SHADING_XRAY_FLAG(shading) \ + (((shading).type == OB_WIRE) ? V3D_SHADING_XRAY_WIREFRAME : V3D_SHADING_XRAY) +#define SHADING_XRAY_FLAG_ENABLED(shading) (((shading).flag & SHADING_XRAY_FLAG(shading)) != 0) +#define SHADING_XRAY_ENABLED(shading) \ + (SHADING_XRAY_FLAG_ENABLED(shading) && (SHADING_XRAY_ALPHA(shading) < 1.0f)) +#define SHADING_XRAY_ACTIVE(shading) \ + (SHADING_XRAY_ENABLED(shading) && ((shading).type < OB_MATERIAL)) + +#define XRAY_ALPHA(v3d) SHADING_XRAY_ALPHA((v3d)->shading) +#define XRAY_FLAG(v3d) SHADING_XRAY_FLAG((v3d)->shading) +#define XRAY_FLAG_ENABLED(v3d) SHADING_XRAY_FLAG_ENABLED((v3d)->shading) +#define XRAY_ENABLED(v3d) SHADING_XRAY_ENABLED((v3d)->shading) +#define XRAY_ACTIVE(v3d) SHADING_XRAY_ACTIVE((v3d)->shading) /* view3d_draw_legacy.c */ diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index fc26e6b4a06..d87a2730c7b 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -84,7 +84,7 @@ bool ED_view3d_has_workbench_in_texture_color(const Scene *scene, } } else if (v3d->shading.type == OB_RENDER) { - if (STREQ(scene->r.engine, RE_engine_id_BLENDER_WORKBENCH)) { + if (BKE_scene_uses_blender_workbench(scene)) { return scene->display.shading.color_type == V3D_SHADING_TEXTURE_COLOR; } } diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 4faa3aa718c..554ce065edb 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -29,6 +29,7 @@ set(INC # For *_info.hh includes. ../compositor/realtime_compositor ../draw/engines/eevee_next + ../draw/engines/workbench ../draw/intern # For node muting stuff. diff --git a/source/blender/gpu/intern/gpu_texture_private.hh b/source/blender/gpu/intern/gpu_texture_private.hh index 344ec911adc..1b3c04a78f9 100644 --- a/source/blender/gpu/intern/gpu_texture_private.hh +++ b/source/blender/gpu/intern/gpu_texture_private.hh @@ -41,7 +41,7 @@ typedef enum eGPUTextureType { GPU_TEXTURE_CUBE_ARRAY = (GPU_TEXTURE_CUBE | GPU_TEXTURE_ARRAY), } eGPUTextureType; -ENUM_OPERATORS(eGPUTextureType, GPU_TEXTURE_CUBE_ARRAY) +ENUM_OPERATORS(eGPUTextureType, GPU_TEXTURE_BUFFER) /* Format types for samplers within the shader. * This covers the sampler format type permutations within GLSL/MSL. */ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index a4076a4c4e6..c85b40a9342 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -2148,6 +2148,7 @@ enum { /** #RenderData.engine (scene.cc) */ extern const char *RE_engine_id_BLENDER_EEVEE; extern const char *RE_engine_id_BLENDER_WORKBENCH; +extern const char *RE_engine_id_BLENDER_WORKBENCH_NEXT; extern const char *RE_engine_id_CYCLES; /** \} */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 0e96e1db30c..d33272183bb 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -652,6 +652,8 @@ typedef struct UserDef_Experimental { char use_override_templates; char enable_eevee_next; char use_sculpt_texture_paint; + char enable_workbench_next; + char _pad[7]; /** `makesdna` does not allow empty structs. */ } UserDef_Experimental; @@ -957,7 +959,7 @@ extern UserDef U; /* ***************** USERDEF ****************** */ /* Toggles for unfinished 2.8 UserPref design. */ -//#define WITH_USERDEF_WORKSPACES +// #define WITH_USERDEF_WORKSPACES /** #UserDef_SpaceData.section_active (UI active_section) */ typedef enum eUserPref_Section { diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index a5f2f4a0892..38625c7416a 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1165,7 +1165,7 @@ static void rna_3DViewShading_type_update(Main *bmain, Scene *scene, PointerRNA View3DShading *shading = ptr->data; if (shading->type == OB_MATERIAL || - (shading->type == OB_RENDER && !STREQ(scene->r.engine, RE_engine_id_BLENDER_WORKBENCH))) { + (shading->type == OB_RENDER && !BKE_scene_uses_blender_workbench(scene))) { /* When switching from workbench to render or material mode the geometry of any * active sculpt session needs to be recalculated. */ for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index ba9d750f1bb..ca2e2e436c3 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -6426,6 +6426,13 @@ static void rna_def_userdef_experimental(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "enable_eevee_next", 1); RNA_def_property_ui_text(prop, "EEVEE Next", "Enable the new EEVEE codebase, requires restart"); + prop = RNA_def_property(srna, "enable_workbench_next", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "enable_workbench_next", 1); + RNA_def_property_ui_text(prop, + "Workbench Next", + "Enable the new Workbench codebase, requires " + "restart"); + prop = RNA_def_property(srna, "use_viewport_debug", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "use_viewport_debug", 1); RNA_def_property_ui_text(prop, From e49e5f6f081d9e58837e14131cd732e4ac8b1696 Mon Sep 17 00:00:00 2001 From: Michael Kowalski Date: Mon, 23 Jan 2023 11:58:15 -0500 Subject: [PATCH 0883/1522] Enable USD Preview Surface import by default The USD Preview Surface material import feature is now considered stable, so this patch removes this option from the Experimental category in the UI. The Import USD Preview option is now enabled by default. The Experimental box has been removed. A new Materials box has been added to group the Import USD Preview Surface, Set Material Blend and Material Collision Mode options. Reviewed by: Sybren Differential Revision: https://developer.blender.org/D17053 --- source/blender/editors/io/io_usd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c index c776fbf0dd7..acd60bbd40a 100644 --- a/source/blender/editors/io/io_usd.c +++ b/source/blender/editors/io/io_usd.c @@ -477,15 +477,15 @@ static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op) uiItemR(col, ptr, "relative_path", 0, NULL, ICON_NONE); uiItemR(col, ptr, "create_collection", 0, NULL, ICON_NONE); uiItemR(box, ptr, "light_intensity_scale", 0, NULL, ICON_NONE); - uiItemR(box, ptr, "mtl_name_collision_mode", 0, NULL, ICON_NONE); box = uiLayoutBox(layout); - col = uiLayoutColumnWithHeading(box, true, IFACE_("Experimental")); + col = uiLayoutColumnWithHeading(box, true, IFACE_("Materials")); uiItemR(col, ptr, "import_usd_preview", 0, NULL, ICON_NONE); uiLayoutSetEnabled(col, RNA_boolean_get(ptr, "import_materials")); uiLayout *row = uiLayoutRow(col, true); uiItemR(row, ptr, "set_material_blend", 0, NULL, ICON_NONE); uiLayoutSetEnabled(row, RNA_boolean_get(ptr, "import_usd_preview")); + uiItemR(col, ptr, "mtl_name_collision_mode", 0, NULL, ICON_NONE); } void WM_OT_usd_import(struct wmOperatorType *ot) @@ -581,7 +581,7 @@ void WM_OT_usd_import(struct wmOperatorType *ot) RNA_def_boolean(ot->srna, "import_usd_preview", - false, + true, "Import USD Preview", "Convert UsdPreviewSurface shaders to Principled BSDF shader networks"); From fe8bf5e0c7f03d755f1a39b02378f133bf965be6 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Mon, 23 Jan 2023 18:42:56 +0100 Subject: [PATCH 0884/1522] Fix T104039: GPencil Fill crash in multiframe The problem was that the stroke array was not reset for each iteration of the loop, so the second time around, the array was not initialized correctly and was left with a NaN value. --- source/blender/editors/gpencil/gpencil_fill.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index d08c95cd5ae..6b1f5ba1ad0 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -2919,6 +2919,7 @@ static int gpencil_fill_modal(bContext *C, wmOperator *op, const wmEvent *event) } if (extend_lines) { + stroke_array_free(tgpf); gpencil_delete_temp_stroke_extension(tgpf, true); } From 8afcecdf1fd1a7fe7dad232b58168d321f7086a1 Mon Sep 17 00:00:00 2001 From: Xavier Hallade Date: Mon, 23 Jan 2023 18:35:43 +0100 Subject: [PATCH 0885/1522] Cycles: update Intel Graphics compiler to 101.4032 on Windows A noticeable (>5%) performance regression in oneAPI backend came with a501a2dbff797829b61f21c5aeb9d19dba3e3874. Updating to latest graphics compiler from driver 101.4032 fixes it. I've tested it with current min-supported drivers and it runs well but since compatibility of graphics compiler with older drivers isn't guaranteed, I'm also bumping the min-supported driver versions. If end-users consider latest drivers too fresh to switch to (version isn't released as stable on Linux as of today but should be before Blender 3.5 release), CYCLES_ONEAPI_ALL_DEVICES=1 env variable can be used. Intel Graphics Compiler on Linux will be updated in a later commit so we can then close D16984. Reviewed By: sergey, LazyDodo --- build_files/config/pipeline_config.yaml | 2 +- intern/cycles/blender/addon/properties.py | 4 ++-- intern/cycles/device/oneapi/device_impl.cpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build_files/config/pipeline_config.yaml b/build_files/config/pipeline_config.yaml index 88ca5108e8b..29c0b131b3d 100644 --- a/build_files/config/pipeline_config.yaml +++ b/build_files/config/pipeline_config.yaml @@ -63,7 +63,7 @@ buildbot: optix: version: '7.3.0' ocloc: - version: '101.3430' + version: '101.4032' cmake: default: version: any diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 62d5ce8a572..eed51eed95f 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1680,10 +1680,10 @@ class CyclesPreferences(bpy.types.AddonPreferences): import sys if sys.platform.startswith("win"): col.label(text="Requires Intel GPU with Xe-HPG architecture", icon='BLANK1') - col.label(text="and Windows driver version 101.3430 or newer", icon='BLANK1') + col.label(text="and Windows driver version 101.4032 or newer", icon='BLANK1') elif sys.platform.startswith("linux"): col.label(text="Requires Intel GPU with Xe-HPG architecture and", icon='BLANK1') - col.label(text=" - intel-level-zero-gpu version 1.3.23904 or newer", icon='BLANK1') + col.label(text=" - intel-level-zero-gpu version 1.3.24931 or newer", icon='BLANK1') col.label(text=" - oneAPI Level-Zero Loader", icon='BLANK1') elif device_type == 'METAL': col.label(text="Requires Apple Silicon with macOS 12.2 or newer", icon='BLANK1') diff --git a/intern/cycles/device/oneapi/device_impl.cpp b/intern/cycles/device/oneapi/device_impl.cpp index edffd9525b1..1915ffc862c 100644 --- a/intern/cycles/device/oneapi/device_impl.cpp +++ b/intern/cycles/device/oneapi/device_impl.cpp @@ -631,9 +631,9 @@ bool OneapiDevice::enqueue_kernel(KernelContext *kernel_context, /* Compute-runtime (ie. NEO) version is what gets returned by sycl/L0 on Windows * since Windows driver 101.3268. */ /* The same min compute-runtime version is currently required across Windows and Linux. - * For Windows driver 101.3430, compute-runtime version is 23904. */ -static const int lowest_supported_driver_version_win = 1013430; -static const int lowest_supported_driver_version_neo = 23904; + * For Windows driver 101.4032, compute-runtime version is 24931. */ +static const int lowest_supported_driver_version_win = 1014032; +static const int lowest_supported_driver_version_neo = 24931; int OneapiDevice::parse_driver_build_version(const sycl::device &device) { From b6b6e47e1dbc2e4a175fb1a257e50dc0f51b2fc6 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Mon, 23 Jan 2023 10:29:40 -0800 Subject: [PATCH 0886/1522] Sculpt: PBVH node splitting for texture paint `PBVH_Leaf` nodes are now split into a new `PBVH_TexLeaf` node type when using the paint brush. These nodes are split by image pixels, not triangles. This greatly increases performance when working with large textures on low-poly meshes. Reviewed By: Jeroen Bakker Differential Revision: https://developer.blender.org/D14900 Ref: D14900 --- source/blender/blenkernel/BKE_pbvh.h | 10 +- source/blender/blenkernel/BKE_pbvh_pixels.hh | 4 + source/blender/blenkernel/intern/pbvh.c | 45 ++- .../blender/blenkernel/intern/pbvh_intern.h | 2 + .../blender/blenkernel/intern/pbvh_pixels.cc | 350 +++++++++++++++++- .../blender/draw/engines/basic/basic_engine.c | 12 + .../draw/engines/eevee/eevee_materials.c | 11 + source/blender/draw/intern/DRW_render.h | 4 + .../blender/draw/intern/draw_manager_data.cc | 7 +- .../blender/draw/intern/draw_shader_shared.h | 2 +- source/blender/editors/sculpt_paint/sculpt.cc | 72 +++- .../editors/sculpt_paint/sculpt_intern.h | 8 +- .../editors/sculpt_paint/sculpt_paint_color.c | 12 +- .../sculpt_paint/sculpt_paint_image.cc | 65 +++- .../editors/sculpt_paint/sculpt_undo.cc | 4 +- 15 files changed, 541 insertions(+), 67 deletions(-) diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 5a63b9bb126..7153f05c0c3 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -163,7 +163,8 @@ typedef enum { PBVH_UpdateTopology = 1 << 13, PBVH_UpdateColor = 1 << 14, PBVH_RebuildPixels = 1 << 15, - PBVH_TopologyUpdated = 1 << 16, /* Used internally by pbvh_bmesh.c */ + PBVH_TexLeaf = 1 << 16, + PBVH_TopologyUpdated = 1 << 17, /* Used internally by pbvh_bmesh.c */ } PBVHNodeFlags; @@ -337,7 +338,12 @@ void BKE_pbvh_search_callback(PBVH *pbvh, void BKE_pbvh_search_gather( PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot); - +void BKE_pbvh_search_gather_ex(PBVH *pbvh, + BKE_pbvh_SearchCallback scb, + void *search_data, + PBVHNode ***r_array, + int *r_tot, + PBVHNodeFlags leaf_flag); /* Ray-cast * the hit callback is called for all leaf nodes intersecting the ray; * it's up to the callback to find the primitive within the leaves that is diff --git a/source/blender/blenkernel/BKE_pbvh_pixels.hh b/source/blender/blenkernel/BKE_pbvh_pixels.hh index b6e006805ec..31dbad0abe1 100644 --- a/source/blender/blenkernel/BKE_pbvh_pixels.hh +++ b/source/blender/blenkernel/BKE_pbvh_pixels.hh @@ -200,6 +200,10 @@ struct NodeData { { undo_regions.clear(); for (UDIMTilePixels &tile : tiles) { + if (tile.pixel_rows.size() == 0) { + continue; + } + rcti region; BLI_rcti_init_minmax(®ion); for (PackedPixelRow &pixel_row : tile.pixel_rows) { diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index d18ef62c20c..e9461350448 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -1020,7 +1020,9 @@ void BKE_pbvh_free(PBVH *pbvh) if (node->bm_other_verts) { BLI_gset_free(node->bm_other_verts, NULL); } + } + if (node->flag & (PBVH_Leaf | PBVH_TexLeaf)) { pbvh_node_pixels_free(node); } } @@ -1094,7 +1096,7 @@ static void pbvh_stack_push(PBVHIter *iter, PBVHNode *node, bool revisiting) iter->stacksize++; } -static PBVHNode *pbvh_iter_next(PBVHIter *iter) +static PBVHNode *pbvh_iter_next(PBVHIter *iter, PBVHNodeFlags leaf_flag) { /* purpose here is to traverse tree, visiting child nodes before their * parents, this order is necessary for e.g. computing bounding boxes */ @@ -1121,7 +1123,7 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter) continue; /* don't traverse, outside of search zone */ } - if (node->flag & PBVH_Leaf) { + if (node->flag & leaf_flag) { /* immediately hit leaf node */ return node; } @@ -1166,8 +1168,12 @@ static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter) return NULL; } -void BKE_pbvh_search_gather( - PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***r_array, int *r_tot) +void BKE_pbvh_search_gather_ex(PBVH *pbvh, + BKE_pbvh_SearchCallback scb, + void *search_data, + PBVHNode ***r_array, + int *r_tot, + PBVHNodeFlags leaf_flag) { PBVHIter iter; PBVHNode **array = NULL, *node; @@ -1175,8 +1181,8 @@ void BKE_pbvh_search_gather( pbvh_iter_begin(&iter, pbvh, scb, search_data); - while ((node = pbvh_iter_next(&iter))) { - if (node->flag & PBVH_Leaf) { + while ((node = pbvh_iter_next(&iter, leaf_flag))) { + if (node->flag & leaf_flag) { if (UNLIKELY(tot == space)) { /* resize array if needed */ space = (tot == 0) ? 32 : space * 2; @@ -1199,6 +1205,12 @@ void BKE_pbvh_search_gather( *r_tot = tot; } +void BKE_pbvh_search_gather( + PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***r_array, int *r_tot) +{ + BKE_pbvh_search_gather_ex(pbvh, scb, search_data, r_array, r_tot, PBVH_Leaf); +} + void BKE_pbvh_search_callback(PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, @@ -1210,7 +1222,7 @@ void BKE_pbvh_search_callback(PBVH *pbvh, pbvh_iter_begin(&iter, pbvh, scb, search_data); - while ((node = pbvh_iter_next(&iter))) { + while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) { if (node->flag & PBVH_Leaf) { hcb(node, hit_data); } @@ -1946,7 +1958,7 @@ void BKE_pbvh_redraw_BB(PBVH *pbvh, float bb_min[3], float bb_max[3]) pbvh_iter_begin(&iter, pbvh, NULL, NULL); - while ((node = pbvh_iter_next(&iter))) { + while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) { if (node->flag & PBVH_UpdateRedraw) { BB_expand_with_bb(&bb, &node->vb); } @@ -1966,7 +1978,7 @@ void BKE_pbvh_get_grid_updates(PBVH *pbvh, bool clear, void ***r_gridfaces, int pbvh_iter_begin(&iter, pbvh, NULL, NULL); - while ((node = pbvh_iter_next(&iter))) { + while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) { if (node->flag & PBVH_UpdateNormals) { for (uint i = 0; i < node->totprim; i++) { void *face = pbvh->gridfaces[node->prim_indices[i]]; @@ -3147,9 +3159,24 @@ void BKE_pbvh_draw_debug_cb(PBVH *pbvh, PBVHNodeFlags flag), void *user_data) { + PBVHNodeFlags flag = PBVH_Leaf; + for (int a = 0; a < pbvh->totnode; a++) { PBVHNode *node = &pbvh->nodes[a]; + if (node->flag & PBVH_TexLeaf) { + flag = PBVH_TexLeaf; + break; + } + } + + for (int a = 0; a < pbvh->totnode; a++) { + PBVHNode *node = &pbvh->nodes[a]; + + if (!(node->flag & flag)) { + continue; + } + draw_fn(node, user_data, node->vb.bmin, node->vb.bmax, node->flag); } } diff --git a/source/blender/blenkernel/intern/pbvh_intern.h b/source/blender/blenkernel/intern/pbvh_intern.h index d3db65137de..4666504e94f 100644 --- a/source/blender/blenkernel/intern/pbvh_intern.h +++ b/source/blender/blenkernel/intern/pbvh_intern.h @@ -150,6 +150,8 @@ struct PBVH { int faces_num; /* Do not use directly, use BKE_pbvh_num_faces. */ int leaf_limit; + int pixel_leaf_limit; + int depth_limit; /* Mesh data */ struct Mesh *mesh; diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index b1d635f566e..ed87631ffe9 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -15,7 +15,9 @@ #include "BLI_math.h" #include "BLI_task.h" +#include "PIL_time.h" +#include "BKE_global.h" #include "BKE_image_wrappers.hh" #include "bmesh.h" @@ -25,12 +27,6 @@ namespace blender::bke::pbvh::pixels { -/** - * 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 neighbor UV coordinates in the given image buffer. */ @@ -57,6 +53,315 @@ static float2 calc_barycentric_delta_x(const ImBuf *image_buffer, return calc_barycentric_delta(uvs, start_uv, end_uv); } +static int count_node_pixels(PBVHNode &node) +{ + if (!node.pixels.node_data) { + return 0; + } + + NodeData &data = BKE_pbvh_pixels_node_data_get(node); + + int totpixel = 0; + + for (UDIMTilePixels &tile : data.tiles) { + for (PackedPixelRow &row : tile.pixel_rows) { + totpixel += row.num_pixels; + } + } + + return totpixel; +} + +struct SplitQueueData { + ThreadQueue *new_nodes; + TaskPool *pool; + + PBVH *pbvh; + Mesh *mesh; + Image *image; + ImageUser *image_user; +}; + +struct SplitNodePair { + SplitNodePair *parent; + PBVHNode node; + int children_offset = 0; + int depth = 0; + int source_index = -1; + bool is_old = false; + SplitQueueData *tdata; + + SplitNodePair(SplitNodePair *node_parent = nullptr) : parent(node_parent) + { + memset(static_cast(&node), 0, sizeof(PBVHNode)); + } +}; + +static void split_thread_job(TaskPool *__restrict pool, void *taskdata); + +static void split_pixel_node(PBVH *pbvh, + SplitNodePair *split, + Mesh *mesh, + Image *image, + ImageUser *image_user, + SplitQueueData *tdata) +{ + BB cb; + PBVHNode *node = &split->node; + + cb = node->vb; + + if (count_node_pixels(*node) <= pbvh->pixel_leaf_limit || split->depth >= pbvh->depth_limit) { + BKE_pbvh_pixels_node_data_get(split->node).rebuild_undo_regions(); + return; + } + + /* Find widest axis and its midpoint */ + const int axis = BB_widest_axis(&cb); + const float mid = (cb.bmax[axis] + cb.bmin[axis]) * 0.5f; + + node->flag = (PBVHNodeFlags)((int)node->flag & (int)~PBVH_TexLeaf); + + SplitNodePair *split1 = MEM_new("split_pixel_node split1", split); + SplitNodePair *split2 = MEM_new("split_pixel_node split1", split); + + split1->depth = split->depth + 1; + split2->depth = split->depth + 1; + + PBVHNode *child1 = &split1->node; + PBVHNode *child2 = &split2->node; + + child1->flag = PBVH_TexLeaf; + child2->flag = PBVH_TexLeaf; + + child1->vb = cb; + child1->vb.bmax[axis] = mid; + + child2->vb = cb; + child2->vb.bmin[axis] = mid; + + NodeData &data = BKE_pbvh_pixels_node_data_get(split->node); + + NodeData *data1 = MEM_new(__func__); + NodeData *data2 = MEM_new(__func__); + child1->pixels.node_data = static_cast(data1); + child2->pixels.node_data = static_cast(data2); + + data1->uv_primitives = data.uv_primitives; + data2->uv_primitives = data.uv_primitives; + + data1->tiles.resize(data.tiles.size()); + data2->tiles.resize(data.tiles.size()); + + for (int i : IndexRange(data.tiles.size())) { + UDIMTilePixels &tile = data.tiles[i]; + UDIMTilePixels &tile1 = data1->tiles[i]; + UDIMTilePixels &tile2 = data2->tiles[i]; + + tile1.tile_number = tile2.tile_number = tile.tile_number; + tile1.flags.dirty = tile2.flags.dirty = 0; + } + + ImageUser image_user2 = *image_user; + + for (int i : IndexRange(data.tiles.size())) { + const UDIMTilePixels &tile = data.tiles[i]; + + image_user2.tile = tile.tile_number; + + ImBuf *image_buffer = BKE_image_acquire_ibuf(image, &image_user2, nullptr); + if (image_buffer == nullptr) { + continue; + } + + const float(*vert_cos)[3] = BKE_pbvh_get_vert_positions(pbvh); + PBVHData &pbvh_data = BKE_pbvh_pixels_data_get(*pbvh); + + for (const PackedPixelRow &row : tile.pixel_rows) { + UDIMTilePixels *tile1 = &data1->tiles[i]; + UDIMTilePixels *tile2 = &data2->tiles[i]; + + UVPrimitivePaintInput &uv_prim = data.uv_primitives.paint_input[row.uv_primitive_index]; + int3 tri = pbvh_data.geom_primitives.vert_indices[uv_prim.geometry_primitive_index]; + + float verts[3][3]; + + copy_v3_v3(verts[0], vert_cos[tri[0]]); + copy_v3_v3(verts[1], vert_cos[tri[1]]); + copy_v3_v3(verts[2], vert_cos[tri[2]]); + + float2 delta = uv_prim.delta_barycentric_coord_u; + float2 uv1 = row.start_barycentric_coord; + float2 uv2 = row.start_barycentric_coord + delta * (float)row.num_pixels; + + float co1[3]; + float co2[3]; + + interp_barycentric_tri_v3(verts, uv1[0], uv1[1], co1); + interp_barycentric_tri_v3(verts, uv2[0], uv2[1], co2); + + /* Are we spanning the midpoint? */ + if ((co1[axis] <= mid) != (co2[axis] <= mid)) { + PackedPixelRow row1 = row; + float t; + + if (mid < co1[axis]) { + t = 1.0f - (mid - co2[axis]) / (co1[axis] - co2[axis]); + + SWAP(UDIMTilePixels *, tile1, tile2); + } + else { + t = (mid - co1[axis]) / (co2[axis] - co1[axis]); + } + + int num_pixels = (int)floorf((float)row.num_pixels * t); + + if (num_pixels) { + row1.num_pixels = num_pixels; + tile1->pixel_rows.append(row1); + } + + if (num_pixels != row.num_pixels) { + PackedPixelRow row2 = row; + + row2.num_pixels = row.num_pixels - num_pixels; + + row2.start_barycentric_coord = row.start_barycentric_coord + + uv_prim.delta_barycentric_coord_u * (float)num_pixels; + row2.start_image_coordinate = row.start_image_coordinate; + row2.start_image_coordinate[0] += num_pixels; + + tile2->pixel_rows.append(row2); + } + } + else if (co1[axis] <= mid && co2[axis] <= mid) { + tile1->pixel_rows.append(row); + } + else { + tile2->pixel_rows.append(row); + } + } + + BKE_image_release_ibuf(image, image_buffer, nullptr); + } + + data.undo_regions.clear(); + + if (node->flag & PBVH_Leaf) { + data.clear_data(); + } + else { + pbvh_node_pixels_free(node); + } + + BLI_thread_queue_push(tdata->new_nodes, static_cast(split1)); + BLI_thread_queue_push(tdata->new_nodes, static_cast(split2)); + + BLI_task_pool_push(tdata->pool, split_thread_job, static_cast(split1), false, nullptr); + BLI_task_pool_push(tdata->pool, split_thread_job, static_cast(split2), false, nullptr); +} + +static void split_flush_final_nodes(SplitQueueData *tdata) +{ + PBVH *pbvh = tdata->pbvh; + Vector splits; + + while (!BLI_thread_queue_is_empty(tdata->new_nodes)) { + SplitNodePair *newsplit = static_cast(BLI_thread_queue_pop(tdata->new_nodes)); + + splits.append(newsplit); + + if (newsplit->is_old) { + continue; + } + + if (!newsplit->parent->children_offset) { + newsplit->parent->children_offset = pbvh->totnode; + + pbvh_grow_nodes(pbvh, pbvh->totnode + 2); + newsplit->source_index = newsplit->parent->children_offset; + } + else { + newsplit->source_index = newsplit->parent->children_offset + 1; + } + } + + for (SplitNodePair *split : splits) { + BLI_assert(split->source_index != -1); + + split->node.children_offset = split->children_offset; + pbvh->nodes[split->source_index] = split->node; + } + + for (SplitNodePair *split : splits) { + MEM_delete(split); + } +} + +static void split_thread_job(TaskPool *__restrict pool, void *taskdata) +{ + + SplitQueueData *tdata = static_cast(BLI_task_pool_user_data(pool)); + SplitNodePair *split = static_cast(taskdata); + + split_pixel_node(tdata->pbvh, split, tdata->mesh, tdata->image, tdata->image_user, tdata); +} + +static void split_pixel_nodes(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image_user) +{ + if (G.debug_value == 891) { + return; + } + + if (!pbvh->depth_limit) { + pbvh->depth_limit = 40; /* TODO: move into a constant */ + } + + if (!pbvh->pixel_leaf_limit) { + pbvh->pixel_leaf_limit = 256 * 256; /* TODO: move into a constant */ + } + + SplitQueueData tdata; + TaskPool *pool = BLI_task_pool_create_suspended(&tdata, TASK_PRIORITY_HIGH); + + tdata.pool = pool; + tdata.pbvh = pbvh; + tdata.mesh = mesh; + tdata.image = image; + tdata.image_user = image_user; + + tdata.new_nodes = BLI_thread_queue_init(); + + /* Set up initial jobs before initializing threads. */ + for (int i : IndexRange(pbvh->totnode)) { + if (pbvh->nodes[i].flag & PBVH_TexLeaf) { + SplitNodePair *split = MEM_new("split_pixel_nodes split"); + + split->source_index = i; + split->is_old = true; + split->node = pbvh->nodes[i]; + split->tdata = &tdata; + + BLI_task_pool_push(pool, split_thread_job, static_cast(split), false, nullptr); + + BLI_thread_queue_push(tdata.new_nodes, static_cast(split)); + } + } + + BLI_task_pool_work_and_wait(pool); + BLI_task_pool_free(pool); + + split_flush_final_nodes(&tdata); + + BLI_thread_queue_free(tdata.new_nodes); +} + +/** + * 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; + static void extract_barycentric_pixels(UDIMTilePixels &tile_data, const ImBuf *image_buffer, const uv_islands::UVIslandsMask &uv_mask, @@ -233,7 +538,10 @@ static void do_encode_pixels(void *__restrict userdata, static bool should_pixels_be_updated(PBVHNode *node) { - if ((node->flag & PBVH_Leaf) == 0) { + if ((node->flag & (PBVH_Leaf | PBVH_TexLeaf)) == 0) { + return false; + } + if (node->children_offset != 0) { return false; } if ((node->flag & PBVH_RebuildPixels) != 0) { @@ -349,17 +657,17 @@ 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, Mesh *mesh, Image *image, ImageUser *image_user) +static bool update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image_user) { Vector nodes_to_update; if (!find_nodes_to_update(pbvh, nodes_to_update)) { - return; + return false; } const StringRef active_uv_name = CustomData_get_active_layer_name(&mesh->ldata, CD_PROP_FLOAT2); if (active_uv_name.is_empty()) { - return; + return false; } const AttributeAccessor attributes = mesh->attributes(); @@ -422,6 +730,15 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image node->flag = static_cast(node->flag & ~PBVH_RebuildPixels); } + /* Add PBVH_TexLeaf flag */ + for (int i : IndexRange(pbvh->totnode)) { + PBVHNode &node = pbvh->nodes[i]; + + if (node.flag & PBVH_Leaf) { + node.flag = (PBVHNodeFlags)((int)node.flag | (int)PBVH_TexLeaf); + } + } + //#define DO_PRINT_STATISTICS #ifdef DO_PRINT_STATISTICS /* Print some statistics about compression ratio. */ @@ -434,7 +751,6 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image continue; } NodeData *node_data = static_cast(node->pixels.node_data); - compressed_data_len += node_data->triangles.mem_size(); for (const UDIMTilePixels &tile_data : node_data->tiles) { compressed_data_len += tile_data.encoded_pixels.size() * sizeof(PackedPixelRow); for (const PackedPixelRow &encoded_pixels : tile_data.encoded_pixels) { @@ -448,6 +764,8 @@ static void update_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image float(compressed_data_len) / num_pixels); } #endif + + return true; } NodeData &BKE_pbvh_pixels_node_data_get(PBVHNode &node) @@ -484,7 +802,6 @@ void BKE_pbvh_pixels_mark_image_dirty(PBVHNode &node, Image &image, ImageUser &i node_data->flags.dirty = false; } } - } // namespace blender::bke::pbvh::pixels extern "C" { @@ -492,12 +809,19 @@ using namespace blender::bke::pbvh::pixels; void BKE_pbvh_build_pixels(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image_user) { - update_pixels(pbvh, mesh, image, image_user); + if (update_pixels(pbvh, mesh, image, image_user)) { + split_pixel_nodes(pbvh, mesh, image, image_user); + } } void pbvh_node_pixels_free(PBVHNode *node) { NodeData *node_data = static_cast(node->pixels.node_data); + + if (!node_data) { + return; + } + MEM_delete(node_data); node->pixels.node_data = nullptr; } diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c index 80dc12535a5..5ff596ca083 100644 --- a/source/blender/draw/engines/basic/basic_engine.c +++ b/source/blender/draw/engines/basic/basic_engine.c @@ -10,9 +10,11 @@ #include "DRW_render.h" +#include "BKE_global.h" #include "BKE_object.h" #include "BKE_paint.h" #include "BKE_particle.h" +#include "BKE_pbvh.h" #include "BLI_alloca.h" @@ -219,6 +221,16 @@ static void basic_cache_populate(void *vedata, Object *ob) DRW_shgroup_call(shgrp, geom, ob); } } + + if (G.debug_value == 889 && ob->sculpt && ob->sculpt->pbvh) { + int debug_node_nr = 0; + DRW_debug_modelmat(ob->object_to_world); + BKE_pbvh_draw_debug_cb( + ob->sculpt->pbvh, + (void (*)(void *d, const float min[3], const float max[3], PBVHNodeFlags f)) + DRW_sculpt_debug_cb, + &debug_node_nr); + } } } diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index b134d7f6dc6..c90ae397e57 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -15,6 +15,7 @@ #include "BLI_rand.h" #include "BLI_string_utils.h" +#include "BKE_global.h" #include "BKE_paint.h" #include "BKE_particle.h" @@ -883,6 +884,16 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, *cast_shadow = *cast_shadow || (matcache[i].shadow_grp != NULL); } } + + if (G.debug_value == 889 && ob->sculpt && ob->sculpt->pbvh) { + int debug_node_nr = 0; + DRW_debug_modelmat(ob->object_to_world); + BKE_pbvh_draw_debug_cb( + ob->sculpt->pbvh, + (void (*)(void *d, const float min[3], const float max[3], PBVHNodeFlags f)) + DRW_sculpt_debug_cb, + &debug_node_nr); + } } /* Motion Blur Vectors. */ diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index b9876a980c9..0d406646f2e 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -17,6 +17,7 @@ #include "BKE_context.h" #include "BKE_layer.h" #include "BKE_material.h" +#include "BKE_pbvh.h" #include "BKE_scene.h" #include "BLT_translation.h" @@ -1007,6 +1008,9 @@ void DRW_mesh_batch_cache_get_attributes(struct Object *object, struct DRW_Attributes **r_attrs, struct DRW_MeshCDMask **r_cd_needed); +void DRW_sculpt_debug_cb( + PBVHNode *node, void *user_data, const float bmin[3], const float bmax[3], PBVHNodeFlags flag); + #ifdef __cplusplus } #endif diff --git a/source/blender/draw/intern/draw_manager_data.cc b/source/blender/draw/intern/draw_manager_data.cc index 4e6c5ae1a65..63d7057af97 100644 --- a/source/blender/draw/intern/draw_manager_data.cc +++ b/source/blender/draw/intern/draw_manager_data.cc @@ -1255,7 +1255,7 @@ static void sculpt_draw_cb(DRWSculptCallbackData *scd, } } -static void sculpt_debug_cb( +void DRW_sculpt_debug_cb( PBVHNode *node, void *user_data, const float bmin[3], const float bmax[3], PBVHNodeFlags flag) { int *debug_node_nr = (int *)user_data; @@ -1270,7 +1270,8 @@ static void sculpt_debug_cb( DRW_debug_bbox(&bb, (float[4]){0.5f, 0.5f, 0.5f, 0.6f}); } #else /* Color coded leaf bounds. */ - if (flag & PBVH_Leaf) { + if (flag & (PBVH_Leaf | PBVH_TexLeaf)) { + DRW_debug_bbox(&bb, SCULPT_DEBUG_COLOR((*debug_node_nr)++)); int color = (*debug_node_nr)++; color += BKE_pbvh_debug_draw_gen_get(node); @@ -1370,7 +1371,7 @@ static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd) BKE_pbvh_draw_debug_cb( pbvh, (void (*)(PBVHNode * n, void *d, const float min[3], const float max[3], PBVHNodeFlags f)) - sculpt_debug_cb, + DRW_sculpt_debug_cb, &debug_node_nr); } } diff --git a/source/blender/draw/intern/draw_shader_shared.h b/source/blender/draw/intern/draw_shader_shared.h index 3b1afa0e6cb..28090ef2b46 100644 --- a/source/blender/draw/intern/draw_shader_shared.h +++ b/source/blender/draw/intern/draw_shader_shared.h @@ -333,7 +333,7 @@ struct DRWDebugVert { BLI_STATIC_ASSERT_ALIGN(DRWDebugVert, 16) /* Take the header (DrawCommand) into account. */ -#define DRW_DEBUG_DRAW_VERT_MAX (64 * 1024) - 1 +#define DRW_DEBUG_DRAW_VERT_MAX (64 * 8192) - 1 /* The debug draw buffer is laid-out as the following struct. * But we use plain array in shader code instead because of driver issues. */ diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 676f2de49ef..039f12ad594 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2775,15 +2775,21 @@ static PBVHNode **sculpt_pbvh_gather_cursor_update(Object *ob, return nodes; } -static PBVHNode **sculpt_pbvh_gather_generic(Object *ob, - Sculpt *sd, - const Brush *brush, - bool use_original, - float radius_scale, - int *r_totnode) +static PBVHNode **sculpt_pbvh_gather_generic_intern(Object *ob, + Sculpt *sd, + const Brush *brush, + bool use_original, + float radius_scale, + int *r_totnode, + PBVHNodeFlags flag) { SculptSession *ss = ob->sculpt; PBVHNode **nodes = nullptr; + PBVHNodeFlags leaf_flag = PBVH_Leaf; + + if (flag & PBVH_TexLeaf) { + leaf_flag = PBVH_TexLeaf; + } /* Build a list of all nodes that are potentially within the cursor or brush's area of influence. */ @@ -2795,7 +2801,7 @@ static PBVHNode **sculpt_pbvh_gather_generic(Object *ob, data.original = use_original; data.ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK; data.center = nullptr; - BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode); + BKE_pbvh_search_gather_ex(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode, leaf_flag); } else { DistRayAABB_Precalc dist_ray_to_aabb_precalc; @@ -2809,11 +2815,33 @@ static PBVHNode **sculpt_pbvh_gather_generic(Object *ob, data.original = use_original; data.dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc; data.ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK; - BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_circle_cb, &data, &nodes, r_totnode); + BKE_pbvh_search_gather_ex(ss->pbvh, SCULPT_search_circle_cb, &data, &nodes, r_totnode, leaf_flag); } return nodes; } +static PBVHNode **sculpt_pbvh_gather_generic(Object *ob, + Sculpt *sd, + const Brush *brush, + bool use_original, + float radius_scale, + int *r_totnode) +{ + return sculpt_pbvh_gather_generic_intern( + ob, sd, brush, use_original, radius_scale, r_totnode, PBVH_Leaf); +} + +static PBVHNode **sculpt_pbvh_gather_texpaint(Object *ob, + Sculpt *sd, + const Brush *brush, + bool use_original, + float radius_scale, + int *r_totnode) +{ + return sculpt_pbvh_gather_generic_intern( + ob, sd, brush, use_original, radius_scale, r_totnode, PBVH_TexLeaf); +} + /* Calculate primary direction of movement for many brushes. */ static void calc_sculpt_normal( Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_no[3]) @@ -3440,8 +3468,8 @@ static void do_brush_action(Sculpt *sd, PaintModeSettings *paint_mode_settings) { SculptSession *ss = ob->sculpt; - int totnode; - PBVHNode **nodes; + int totnode, texnodes_num = 0; + PBVHNode **nodes, **texnodes = NULL; /* Check for unsupported features. */ PBVHType type = BKE_pbvh_type(ss->pbvh); @@ -3454,6 +3482,20 @@ static void do_brush_action(Sculpt *sd, BKE_pbvh_ensure_node_loops(ss->pbvh); } + const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true : + ss->cache->original; + const bool use_pixels = sculpt_needs_pbvh_pixels(paint_mode_settings, brush, ob); + + if (sculpt_needs_pbvh_pixels(paint_mode_settings, brush, ob)) { + sculpt_pbvh_update_pixels(paint_mode_settings, ss, ob); + + texnodes = sculpt_pbvh_gather_texpaint(ob, sd, brush, use_original, 1.0f, &texnodes_num); + + if (!texnodes_num) { + return; + } + } + /* Build a list of all nodes that are potentially within the brush's area of influence */ if (SCULPT_tool_needs_all_pbvh_nodes(brush)) { @@ -3464,8 +3506,6 @@ static void do_brush_action(Sculpt *sd, nodes = SCULPT_cloth_brush_affected_nodes_gather(ss, brush, &totnode); } else { - const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true : - ss->cache->original; float radius_scale = 1.0f; /* Corners of square brushes can go outside the brush radius. */ @@ -3480,10 +3520,6 @@ static void do_brush_action(Sculpt *sd, } nodes = sculpt_pbvh_gather_generic(ob, sd, brush, use_original, radius_scale, &totnode); } - const bool use_pixels = sculpt_needs_pbvh_pixels(paint_mode_settings, brush, ob); - if (use_pixels) { - sculpt_pbvh_update_pixels(paint_mode_settings, ss, ob); - } /* Draw Face Sets in draw mode makes a single undo push, in alt-smooth mode deforms the * vertices and uses regular coords undo. */ @@ -3524,6 +3560,7 @@ static void do_brush_action(Sculpt *sd, /* Only act if some verts are inside the brush area. */ if (totnode == 0) { + MEM_SAFE_FREE(texnodes); return; } float location[3]; @@ -3671,7 +3708,7 @@ static void do_brush_action(Sculpt *sd, SCULPT_do_displacement_smear_brush(sd, ob, nodes, totnode); break; case SCULPT_TOOL_PAINT: - SCULPT_do_paint_brush(paint_mode_settings, sd, ob, nodes, totnode); + SCULPT_do_paint_brush(paint_mode_settings, sd, ob, nodes, totnode, texnodes, texnodes_num); break; case SCULPT_TOOL_SMEAR: SCULPT_do_smear_brush(sd, ob, nodes, totnode); @@ -3715,6 +3752,7 @@ static void do_brush_action(Sculpt *sd, } MEM_SAFE_FREE(nodes); + MEM_SAFE_FREE(texnodes); /* Update average stroke position. */ copy_v3_v3(location, ss->cache->true_location); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index ffd1554be89..a979a78a0ef 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -1789,7 +1789,9 @@ void SCULPT_do_paint_brush(struct PaintModeSettings *paint_mode_settings, Sculpt *sd, Object *ob, PBVHNode **nodes, - int totnode) ATTR_NONNULL(); + int totnode, + PBVHNode **texnodes, + int texnodes_num) ATTR_NONNULL(); /** * \brief Get the image canvas for painting on the given object. @@ -1806,7 +1808,9 @@ void SCULPT_do_paint_brush_image(struct PaintModeSettings *paint_mode_settings, Sculpt *sd, Object *ob, PBVHNode **nodes, - int totnode) ATTR_NONNULL(); + int totnode, + PBVHNode **texnodes, + int texnode_num) ATTR_NONNULL(); bool SCULPT_use_image_paint_brush(struct PaintModeSettings *settings, Object *ob) ATTR_NONNULL(); /* Smear Brush. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c index ee716d1107a..2826a7c4df3 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c @@ -249,11 +249,17 @@ static void sample_wet_paint_reduce(const void *__restrict UNUSED(userdata), add_v4_v4(join->color, swptd->color); } -void SCULPT_do_paint_brush( - PaintModeSettings *paint_mode_settings, Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings, + Sculpt *sd, + Object *ob, + PBVHNode **nodes, + int totnode, + PBVHNode **texnodes, + int texnodes_num) { if (SCULPT_use_image_paint_brush(paint_mode_settings, ob)) { - SCULPT_do_paint_brush_image(paint_mode_settings, sd, ob, nodes, totnode); + SCULPT_do_paint_brush_image( + paint_mode_settings, sd, ob, nodes, totnode, texnodes, texnodes_num); return; } diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc index 75c84c48f77..ebe4bcd4916 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc +++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc @@ -1,6 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-or-later * Copyright 2022 Blender Foundation. All rights reserved. */ +/* Paint a color made from hash of node pointer. */ +//#define DEBUG_PIXEL_NODES + #include "DNA_image_types.h" #include "DNA_object_types.h" @@ -9,6 +12,9 @@ #include "BLI_math.h" #include "BLI_math_color_blend.h" #include "BLI_task.h" +#ifdef DEBUG_PIXEL_NODES +# include "BLI_hash.h" +#endif #include "IMB_colormanagement.h" #include "IMB_imbuf.h" @@ -187,6 +193,15 @@ template class PaintingKernel { automask_data); float4 paint_color = brush_color * falloff_strength * brush_strength; float4 buffer_color; + +#ifdef DEBUG_PIXEL_NODES + if ((pixel_row.start_image_coordinate.y >> 3) & 1) { + paint_color[0] *= 0.5f; + paint_color[1] *= 0.5f; + paint_color[2] *= 0.5f; + } +#endif + blend_color_mix_float(buffer_color, color, paint_color); buffer_color *= brush->alpha; IMB_blend_color_float(color, color, buffer_color, static_cast(brush->blend)); @@ -199,20 +214,18 @@ template class PaintingKernel { return pixels_painted; } - void init_brush_color(ImBuf *image_buffer) + void init_brush_color(ImBuf *image_buffer, float in_brush_color[3]) { const char *to_colorspace = image_accessor.get_colorspace_name(image_buffer); if (last_used_color_space == to_colorspace) { return; } - copy_v3_v3(brush_color, - ss->cache->invert ? BKE_brush_secondary_color_get(ss->scene, brush) : - BKE_brush_color_get(ss->scene, brush)); + /* NOTE: Brush colors are stored in sRGB. We use math color to follow other areas that * use brush colors. From there on we use IMB_colormanagement to convert the brush color to the * colorspace of the texture. This isn't ideal, but would need more refactoring to make sure * that brush colors are stored in scene linear by default. */ - srgb_to_linearrgb_v3_v3(brush_color, brush_color); + srgb_to_linearrgb_v3_v3(brush_color, in_brush_color); brush_color[3] = 1.0f; const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get( @@ -336,6 +349,22 @@ static void do_paint_pixels(void *__restrict userdata, PaintingKernel kernel_float4(ss, brush, thread_id, positions); PaintingKernel kernel_byte4(ss, brush, thread_id, positions); + float brush_color[4]; + +#ifdef DEBUG_PIXEL_NODES + uint hash = BLI_hash_int(POINTER_AS_UINT(node)); + + brush_color[0] = (float)(hash & 255) / 255.0f; + brush_color[1] = (float)((hash >> 8) & 255) / 255.0f; + brush_color[2] = (float)((hash >> 16) & 255) / 255.0f; +#else + copy_v3_v3(brush_color, + ss->cache->invert ? BKE_brush_secondary_color_get(ss->scene, brush) : + BKE_brush_color_get(ss->scene, brush)); +#endif + + brush_color[3] = 1.0f; + AutomaskingNodeData automask_data; SCULPT_automasking_node_begin(ob, ss, ss->cache->automasking, &automask_data, data->nodes[n]); @@ -353,10 +382,10 @@ static void do_paint_pixels(void *__restrict userdata, } if (image_buffer->rect_float != nullptr) { - kernel_float4.init_brush_color(image_buffer); + kernel_float4.init_brush_color(image_buffer, brush_color); } else { - kernel_byte4.init_brush_color(image_buffer); + kernel_byte4.init_brush_color(image_buffer, brush_color); } for (const PackedPixelRow &pixel_row : tile_data.pixel_rows) { @@ -520,27 +549,33 @@ bool SCULPT_use_image_paint_brush(PaintModeSettings *settings, Object *ob) return BKE_paint_canvas_image_get(settings, ob, &image, &image_user); } -void SCULPT_do_paint_brush_image( - PaintModeSettings *paint_mode_settings, Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +void SCULPT_do_paint_brush_image(PaintModeSettings *paint_mode_settings, + Sculpt *sd, + Object *ob, + PBVHNode **nodes, + int totnode, + PBVHNode **texnodes, + int texnodes_num) { Brush *brush = BKE_paint_brush(&sd->paint); TexturePaintingUserData data = {nullptr}; data.ob = ob; data.brush = brush; - data.nodes = nodes; + data.nodes = texnodes; if (!ImageData::init_active_image(ob, &data.image_data, paint_mode_settings)) { return; } TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, totnode); - BLI_task_parallel_range(0, totnode, &data, do_push_undo_tile, &settings); - BLI_task_parallel_range(0, totnode, &data, do_paint_pixels, &settings); + BKE_pbvh_parallel_range_settings(&settings, true, texnodes_num); + BLI_task_parallel_range(0, texnodes_num, &data, do_push_undo_tile, &settings); + BLI_task_parallel_range(0, texnodes_num, &data, do_paint_pixels, &settings); TaskParallelSettings settings_flush; - BKE_pbvh_parallel_range_settings(&settings_flush, false, totnode); - BLI_task_parallel_range(0, totnode, &data, do_mark_dirty_regions, &settings_flush); + + BKE_pbvh_parallel_range_settings(&settings_flush, false, texnodes_num); + BLI_task_parallel_range(0, texnodes_num, &data, do_mark_dirty_regions, &settings_flush); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.cc b/source/blender/editors/sculpt_paint/sculpt_undo.cc index 16a83870115..24c49962df8 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.cc +++ b/source/blender/editors/sculpt_paint/sculpt_undo.cc @@ -193,7 +193,7 @@ static void print_sculpt_node(Object *ob, SculptUndoNode *node) printf(" %s:%s {applied=%d}\n", undo_type_to_str(node->type), node->idname, node->applied); if (node->bm_entry) { - BM_log_print_entry(ob->sculpt ? ob->sculpt->bm : NULL, node->bm_entry); + BM_log_print_entry(ob->sculpt ? ob->sculpt->bm : nullptr, node->bm_entry); } } @@ -2090,7 +2090,7 @@ static UndoSculpt *sculpt_undo_get_nodes(void) { UndoStack *ustack = ED_undo_stack_get(); UndoStep *us = BKE_undosys_stack_init_or_active_with_type(ustack, BKE_UNDOSYS_TYPE_SCULPT); - return sculpt_undosys_step_get_nodes(us); + return us ? sculpt_undosys_step_get_nodes(us) : NULL; } /** \} */ From 15575b953dfaea29e64788ebc0ce00425401de49 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Fri, 20 Jan 2023 00:03:22 -0300 Subject: [PATCH 0887/1522] Merge By Distance: Optimize algorithm to find duplicate polygons The most time-consuming operation in merge by distance is to find duplicate faces (faces that are different but have the same vertices). Therefore, some strategies were planned to optimize this algorithm: - Store the corner indices in an array thus avoiding multiple calls of `weld_iter_loop_of_poly_next`; - Create a map of polygons linked to edges instead of linked to vertices - this decreases the number of connections and reduces the calculation of the intersection of polygon indices. There are other fields to optimize, like reusing the `wpolys` array instead of creating a new array of corner offsets. And join some arrays as members of the same struct to be used in the same buffer. But for now, it is already a nice optimization. And the new `poly_find_doubles` function can be reused in the future to create a generic utility. The result of the optimization varies greatly depending on the number of polygons, the size of each polygon and the number of duplicates. On average it was something around 2 times faster. Worst case tested (old vs new): 0.1ms vs 0.3ms Best case tested (old vs new): 10.0ms vs 3.2ms Differential Revision: https://developer.blender.org/D17071 --- .../geometry/intern/mesh_merge_by_distance.cc | 335 +++++++++++------- 1 file changed, 213 insertions(+), 122 deletions(-) diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc index 5374a6c08cd..f0ec847d44a 100644 --- a/source/blender/geometry/intern/mesh_merge_by_distance.cc +++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc @@ -1,10 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "BLI_array.hh" +#include "BLI_bit_vector.hh" #include "BLI_index_mask.hh" #include "BLI_kdtree.h" #include "BLI_math_vector.h" #include "BLI_math_vector.hh" +#include "BLI_offset_indices.hh" #include "BLI_vector.hh" #include "DNA_mesh_types.h" @@ -462,7 +464,7 @@ static Vector weld_edge_ctx_alloc_and_find_collapsed(Span medge * \return r_edge_kill_len: Number of edges to be destroyed by merging or collapsing. */ static void weld_edge_find_doubles(int remain_edge_ctx_len, - MutableSpan r_vlinks, + int mvert_num, MutableSpan r_edge_dest_map, MutableSpan r_wedge, int *r_edge_kill_len) @@ -474,7 +476,8 @@ static void weld_edge_find_doubles(int remain_edge_ctx_len, /* Setup Edge Overlap. */ int edge_double_len = 0; - r_vlinks.fill(0); + /* Add +1 to allow calculation of the length of the last group. */ + Array v_links(mvert_num + 1, 0); for (WeldEdge &we : r_wedge) { if (we.flag == ELEM_COLLAPSED) { @@ -483,16 +486,16 @@ static void weld_edge_find_doubles(int remain_edge_ctx_len, } BLI_assert(we.vert_a != we.vert_b); - r_vlinks[we.vert_a]++; - r_vlinks[we.vert_b]++; + v_links[we.vert_a]++; + v_links[we.vert_b]++; } int link_len = 0; - for (const int i : IndexRange(r_vlinks.size() - 1)) { - link_len += r_vlinks[i]; - r_vlinks[i] = link_len; + for (const int i : IndexRange(v_links.size() - 1)) { + link_len += v_links[i]; + v_links[i] = link_len; } - r_vlinks.last() = link_len; + v_links.last() = link_len; BLI_assert(link_len > 0); Array link_edge_buffer(link_len); @@ -507,8 +510,8 @@ static void weld_edge_find_doubles(int remain_edge_ctx_len, int dst_vert_a = we.vert_a; int dst_vert_b = we.vert_b; - link_edge_buffer[--r_vlinks[dst_vert_a]] = i; - link_edge_buffer[--r_vlinks[dst_vert_b]] = i; + link_edge_buffer[--v_links[dst_vert_a]] = i; + link_edge_buffer[--v_links[dst_vert_b]] = i; } for (const int i : r_wedge.index_range()) { @@ -522,11 +525,11 @@ static void weld_edge_find_doubles(int remain_edge_ctx_len, int dst_vert_a = we.vert_a; int dst_vert_b = we.vert_b; - const int link_a = r_vlinks[dst_vert_a]; - const int link_b = r_vlinks[dst_vert_b]; + const int link_a = v_links[dst_vert_a]; + const int link_b = v_links[dst_vert_b]; - int edges_len_a = r_vlinks[dst_vert_a + 1] - link_a; - int edges_len_b = r_vlinks[dst_vert_b + 1] - link_b; + int edges_len_a = v_links[dst_vert_a + 1] - link_a; + int edges_len_b = v_links[dst_vert_b + 1] - link_b; if (edges_len_a <= 1 || edges_len_b <= 1) { continue; @@ -1093,12 +1096,162 @@ static void weld_poly_loop_ctx_setup_collapsed_and_split( #endif } +static int poly_find_doubles(const OffsetIndices poly_corners_offsets, + const int poly_num, + const Span corners, + const int corner_index_max, + Vector &r_doubles_offsets, + Array &r_doubles_buffer) +{ + /* Fills the `r_buffer` buffer with the intersection of the arrays in `buffer_a` and `buffer_b`. + * `buffer_a` and `buffer_b` have a sequence of sorted, non-repeating indices representing + * polygons. */ + const auto intersect = [](const Span buffer_a, const Span buffer_b, int *r_buffer) { + int result_num = 0; + int index_a = 0, index_b = 0; + while (index_a < buffer_a.size() && index_b < buffer_b.size()) { + const int value_a = buffer_a[index_a]; + const int value_b = buffer_b[index_b]; + if (value_a < value_b) { + index_a++; + } + else if (value_b < value_a) { + index_b++; + } + else { + /* Equality. */ + r_buffer[result_num++] = value_a; + index_a++; + index_b++; + } + } + + return result_num; + }; + + /* Add +1 to allow calculation of the length of the last group. */ + Array linked_polys_offset(corner_index_max + 1, 0); + + for (const int elem_index : corners) { + linked_polys_offset[elem_index]++; + } + + int link_polys_buffer_len = 0; + for (const int elem_index : IndexRange(corner_index_max)) { + link_polys_buffer_len += linked_polys_offset[elem_index]; + linked_polys_offset[elem_index] = link_polys_buffer_len; + } + linked_polys_offset[corner_index_max] = link_polys_buffer_len; + + if (link_polys_buffer_len == 0) { + return 0; + } + + Array linked_polys_buffer(link_polys_buffer_len); + + /* Use a reverse for loop to ensure that indexes are assigned in ascending order. */ + for (int poly_index = poly_num; poly_index--;) { + if (poly_corners_offsets[poly_index].size() == 0) { + continue; + } + + for (int corner_index = poly_corners_offsets[poly_index].last(); + corner_index >= poly_corners_offsets[poly_index].first(); + corner_index--) { + const int elem_index = corners[corner_index]; + linked_polys_buffer[--linked_polys_offset[elem_index]] = poly_index; + } + } + + Array doubles_buffer(poly_num); + + Vector doubles_offsets; + doubles_offsets.reserve((poly_num / 2) + 1); + doubles_offsets.append(0); + + BitVector<> is_double(poly_num, false); + + int doubles_buffer_num = 0; + int doubles_num = 0; + for (const int poly_index : IndexRange(poly_num)) { + if (is_double[poly_index]) { + continue; + } + + int corner_num = poly_corners_offsets[poly_index].size(); + if (corner_num == 0) { + continue; + } + + /* Set or overwrite the first slot of the possible group. */ + doubles_buffer[doubles_buffer_num] = poly_index; + + int corner_first = poly_corners_offsets[poly_index].first(); + int elem_index = corners[corner_first]; + int link_offs = linked_polys_offset[elem_index]; + int polys_a_num = linked_polys_offset[elem_index + 1] - link_offs; + if (polys_a_num == 1) { + BLI_assert(linked_polys_buffer[linked_polys_offset[elem_index]] == poly_index); + continue; + } + + const int *polys_a = &linked_polys_buffer[link_offs]; + int poly_to_test; + + /* Skip polygons with lower index as these have already been checked. */ + do { + poly_to_test = *polys_a; + polys_a++; + polys_a_num--; + } while (poly_to_test != poly_index); + + int *isect_result = doubles_buffer.data() + doubles_buffer_num + 1; + + for (int corner_index : IndexRange(corner_first + 1, corner_num - 1)) { + elem_index = corners[corner_index]; + link_offs = linked_polys_offset[elem_index]; + int polys_b_num = linked_polys_offset[elem_index + 1] - link_offs; + const int *polys_b = &linked_polys_buffer[link_offs]; + + /* Skip polygons with lower index as these have already been checked. */ + do { + poly_to_test = *polys_b; + polys_b++; + polys_b_num--; + } while (poly_to_test != poly_index); + + doubles_num = intersect( + Span{polys_a, polys_a_num}, Span{polys_b, polys_b_num}, isect_result); + + if (doubles_num == 0) { + break; + } + + /* Intersect the last result. */ + polys_a = isect_result; + polys_a_num = doubles_num; + } + + if (doubles_num) { + for (const int poly_double : Span{isect_result, doubles_num}) { + BLI_assert(poly_double > poly_index); + is_double[poly_double].set(); + } + doubles_buffer_num += doubles_num; + doubles_offsets.append(++doubles_buffer_num); + } + } + + r_doubles_buffer = std::move(doubles_buffer); + r_doubles_offsets = std::move(doubles_offsets); + return doubles_buffer_num - (r_doubles_offsets.size() - 1); +} + static void weld_poly_find_doubles(Span mloop, #ifdef USE_WELD_DEBUG const Span mpoly, #endif - const int mvert_len, - MutableSpan r_vlinks, + const int medge_len, WeldMesh *r_weld_mesh) { if (r_weld_mesh->poly_kill_len == r_weld_mesh->wpoly.size()) { @@ -1108,120 +1261,62 @@ static void weld_poly_find_doubles(Span mloop, WeldPoly *wpoly = r_weld_mesh->wpoly.data(); MutableSpan wloop = r_weld_mesh->wloop; Span loop_map = r_weld_mesh->loop_map; - int poly_kill_len = r_weld_mesh->poly_kill_len; - int loop_kill_len = r_weld_mesh->loop_kill_len; + int poly_index = 0; - /* Setup Polygon Overlap. */ - - r_vlinks.fill(0); + const int poly_len = r_weld_mesh->wpoly.size(); + Array poly_offs(poly_len + 1); + Vector corner_edges; + corner_edges.reserve(mloop.size() - r_weld_mesh->loop_kill_len); for (const WeldPoly &wp : r_weld_mesh->wpoly) { + poly_offs[poly_index++] = corner_edges.size(); + WeldLoopOfPolyIter iter; - if (weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr)) { - while (weld_iter_loop_of_poly_next(iter)) { - r_vlinks[iter.v]++; - } + if (!weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr)) { + continue; + } + + if (wp.poly_dst != OUT_OF_CONTEXT) { + continue; + } + + while (weld_iter_loop_of_poly_next(iter)) { + corner_edges.append(iter.e); } } - int link_len = 0; - for (const int i : IndexRange(mvert_len)) { - link_len += r_vlinks[i]; - r_vlinks[i] = link_len; - } - r_vlinks[mvert_len] = link_len; + poly_offs[poly_len] = corner_edges.size(); - if (link_len) { - Array link_poly_buffer(link_len); + Vector doubles_offsets; + Array doubles_buffer; + const int doubles_num = poly_find_doubles(OffsetIndices(poly_offs), + poly_len, + corner_edges, + medge_len, + doubles_offsets, + doubles_buffer); - /* Use a reverse for loop to ensure that indexes are assigned in ascending order. */ - for (int i = r_weld_mesh->wpoly.size(); i--;) { - const WeldPoly &wp = wpoly[i]; - WeldLoopOfPolyIter iter; - if (weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr)) { - while (weld_iter_loop_of_poly_next(iter)) { - link_poly_buffer[--r_vlinks[iter.v]] = i; - } + if (doubles_num) { + int loop_kill_num = 0; + + OffsetIndices doubles_offset_indices = OffsetIndices(doubles_offsets); + for (const int i : IndexRange(doubles_offset_indices.ranges_num())) { + const int poly_dst = wpoly[doubles_buffer[doubles_offsets[i]]].poly_orig; + + for (const int offset : doubles_offset_indices[i].drop_front(1)) { + const int wpoly_index = doubles_buffer[offset]; + WeldPoly &wp = wpoly[wpoly_index]; + + BLI_assert(wp.poly_dst == OUT_OF_CONTEXT); + wp.poly_dst = poly_dst; + loop_kill_num += wp.loop_len; } } - int polys_len_a, polys_len_b, *polys_ctx_a, *polys_ctx_b, p_ctx_a, p_ctx_b; - polys_len_b = p_ctx_b = 0; /* silence warnings */ - - for (const int i : IndexRange(r_weld_mesh->wpoly.size())) { - const WeldPoly &wp = wpoly[i]; - if (wp.poly_dst != OUT_OF_CONTEXT) { - /* No need to retest poly. - * (Already includes collapsed polygons). */ - continue; - } - - WeldLoopOfPolyIter iter; - weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr); - weld_iter_loop_of_poly_next(iter); - const int link_a = r_vlinks[iter.v]; - polys_len_a = r_vlinks[iter.v + 1] - link_a; - if (polys_len_a == 1) { - BLI_assert(link_poly_buffer[link_a] == i); - continue; - } - int wp_loop_len = wp.loop_len; - polys_ctx_a = &link_poly_buffer[link_a]; - for (; polys_len_a--; polys_ctx_a++) { - p_ctx_a = *polys_ctx_a; - if (p_ctx_a == i) { - continue; - } - - WeldPoly *wp_tmp = &wpoly[p_ctx_a]; - if (wp_tmp->loop_len != wp_loop_len) { - continue; - } - - WeldLoopOfPolyIter iter_b = iter; - while (weld_iter_loop_of_poly_next(iter_b)) { - const int link_b = r_vlinks[iter_b.v]; - polys_len_b = r_vlinks[iter_b.v + 1] - link_b; - if (polys_len_b == 1) { - BLI_assert(link_poly_buffer[link_b] == i); - polys_len_b = 0; - break; - } - - polys_ctx_b = &link_poly_buffer[link_b]; - for (; polys_len_b; polys_len_b--, polys_ctx_b++) { - p_ctx_b = *polys_ctx_b; - if (p_ctx_b < p_ctx_a) { - continue; - } - if (p_ctx_b >= p_ctx_a) { - if (p_ctx_b > p_ctx_a) { - polys_len_b = 0; - } - break; - } - } - if (polys_len_b == 0) { - break; - } - } - if (polys_len_b == 0) { - continue; - } - BLI_assert(p_ctx_a > i); - BLI_assert(p_ctx_a == p_ctx_b); - BLI_assert(wp_tmp->poly_dst == OUT_OF_CONTEXT); - BLI_assert(wp_tmp != &wp); - wp_tmp->poly_dst = wp.poly_orig; - loop_kill_len += wp_tmp->loop_len; - poly_kill_len++; - } - } + r_weld_mesh->poly_kill_len += doubles_num; + r_weld_mesh->loop_kill_len += loop_kill_num; } - r_weld_mesh->poly_kill_len = poly_kill_len; - r_weld_mesh->loop_kill_len = loop_kill_len; - #ifdef USE_WELD_DEBUG weld_assert_poly_and_loop_kill_len( r_weld_mesh, mloop, mpoly, r_weld_mesh->poly_kill_len, r_weld_mesh->loop_kill_len); @@ -1240,7 +1335,6 @@ static void weld_mesh_context_create(const Mesh &mesh, MutableSpan r_vert_group_map, WeldMesh *r_weld_mesh) { - const int mvert_len = mesh.totvert; const Span edges = mesh.edges(); const Span polys = mesh.polys(); const Span loops = mesh.loops(); @@ -1253,10 +1347,8 @@ static void weld_mesh_context_create(const Mesh &mesh, Vector wedge = weld_edge_ctx_alloc_and_find_collapsed( edges, vert_dest_map, edge_dest_map, edge_ctx_map, &r_weld_mesh->edge_kill_len); - /* Add +1 to allow calculation of the length of the last group. */ - Array v_links(mvert_len + 1); weld_edge_find_doubles(wedge.size() - r_weld_mesh->edge_kill_len, - v_links, + mesh.totvert, edge_dest_map, wedge, &r_weld_mesh->edge_kill_len); @@ -1276,8 +1368,7 @@ static void weld_mesh_context_create(const Mesh &mesh, #ifdef USE_WELD_DEBUG polys, #endif - mvert_len, - v_links, + edges.size(), r_weld_mesh); weld_vert_groups_setup(wvert, From 7fc395354cd1049157096ac97bee3a2745045624 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 23 Jan 2023 14:41:40 -0600 Subject: [PATCH 0888/1522] Cleanup: Use offset indices arguments for curves utilities Make the functions more flexible and more generic by changing the curves arguments to the curve offsets. This way, theoretically they could become normal utility functions in the future. Also do a consistency pass over the algorithms that generate new curves geometry for naming and code ordering, and use of utility functions. The functions are really quite similar, and it's much easier to tell this way. --- source/blender/blenkernel/BKE_curves_utils.hh | 40 +++-- .../blender/blenkernel/intern/curves_utils.cc | 32 ++-- .../geometry/intern/add_curves_on_mesh.cc | 7 +- .../blender/geometry/intern/fillet_curves.cc | 47 +++--- .../geometry/intern/resample_curves.cc | 53 ++++--- .../blender/geometry/intern/set_curve_type.cc | 142 +++++++++--------- .../geometry/intern/subdivide_curves.cc | 70 +++++---- source/blender/geometry/intern/trim_curves.cc | 25 +-- 8 files changed, 228 insertions(+), 188 deletions(-) diff --git a/source/blender/blenkernel/BKE_curves_utils.hh b/source/blender/blenkernel/BKE_curves_utils.hh index 6caf716c063..9549a643c05 100644 --- a/source/blender/blenkernel/BKE_curves_utils.hh +++ b/source/blender/blenkernel/BKE_curves_utils.hh @@ -471,54 +471,58 @@ class IndexRangeCyclic { * ranges, assuming that all curves have the same number of control points in #src_curves * and #dst_curves. */ -void copy_point_data(const CurvesGeometry &src_curves, - const CurvesGeometry &dst_curves, +void copy_point_data(OffsetIndices src_points_by_curve, + OffsetIndices dst_points_by_curve, Span curve_ranges, GSpan src, GMutableSpan dst); -void copy_point_data(const CurvesGeometry &src_curves, - const CurvesGeometry &dst_curves, +void copy_point_data(OffsetIndices src_points_by_curve, + OffsetIndices dst_points_by_curve, IndexMask src_curve_selection, GSpan src, GMutableSpan dst); template -void copy_point_data(const CurvesGeometry &src_curves, - const CurvesGeometry &dst_curves, +void copy_point_data(OffsetIndices src_points_by_curve, + OffsetIndices dst_points_by_curve, IndexMask src_curve_selection, Span src, MutableSpan dst) { - copy_point_data(src_curves, dst_curves, src_curve_selection, GSpan(src), GMutableSpan(dst)); + copy_point_data(src_points_by_curve, + dst_points_by_curve, + src_curve_selection, + GSpan(src), + GMutableSpan(dst)); } -void fill_points(const CurvesGeometry &curves, +void fill_points(OffsetIndices points_by_curve, IndexMask curve_selection, GPointer value, GMutableSpan dst); template -void fill_points(const CurvesGeometry &curves, +void fill_points(const OffsetIndices points_by_curve, IndexMask curve_selection, const T &value, MutableSpan dst) { - fill_points(curves, curve_selection, &value, dst); + fill_points(points_by_curve, curve_selection, &value, dst); } -void fill_points(const CurvesGeometry &curves, +void fill_points(const OffsetIndices points_by_curve, Span curve_ranges, GPointer value, GMutableSpan dst); template -void fill_points(const CurvesGeometry &curves, +void fill_points(const OffsetIndices points_by_curve, Span curve_ranges, const T &value, MutableSpan dst) { - fill_points(curves, curve_ranges, &value, dst); + fill_points(points_by_curve, curve_ranges, &value, dst); } /** @@ -533,9 +537,15 @@ void fill_points(const CurvesGeometry &curves, bke::CurvesGeometry copy_only_curve_domain(const bke::CurvesGeometry &src_curves); /** - * Copy the number of points in every curve in #curve_ranges to the corresponding index in #sizes. + * Copy the number of points in every curve in the mask to the corresponding index in #sizes. */ -void copy_curve_sizes(const bke::CurvesGeometry &curves, +void copy_curve_sizes(OffsetIndices points_by_curve, IndexMask mask, MutableSpan sizes); + +/** + * Copy the number of points in every curve in #curve_ranges to the corresponding index in + * #sizes. + */ +void copy_curve_sizes(OffsetIndices points_by_curve, Span curve_ranges, MutableSpan sizes); diff --git a/source/blender/blenkernel/intern/curves_utils.cc b/source/blender/blenkernel/intern/curves_utils.cc index ef2518cbc3f..55f41e412a6 100644 --- a/source/blender/blenkernel/intern/curves_utils.cc +++ b/source/blender/blenkernel/intern/curves_utils.cc @@ -10,11 +10,21 @@ namespace blender::bke::curves { -void copy_curve_sizes(const bke::CurvesGeometry &curves, +void copy_curve_sizes(const OffsetIndices points_by_curve, + const IndexMask mask, + MutableSpan sizes) +{ + threading::parallel_for(mask.index_range(), 4096, [&](IndexRange ranges_range) { + for (const int64_t i : mask.slice(ranges_range)) { + sizes[i] = points_by_curve.size(i); + } + }); +} + +void copy_curve_sizes(const OffsetIndices points_by_curve, const Span curve_ranges, MutableSpan sizes) { - const OffsetIndices points_by_curve = curves.points_by_curve(); threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange ranges_range) { for (const IndexRange curves_range : curve_ranges.slice(ranges_range)) { threading::parallel_for(curves_range, 4096, [&](IndexRange range) { @@ -26,14 +36,12 @@ void copy_curve_sizes(const bke::CurvesGeometry &curves, }); } -void copy_point_data(const CurvesGeometry &src_curves, - const CurvesGeometry &dst_curves, +void copy_point_data(const OffsetIndices src_points_by_curve, + const OffsetIndices dst_points_by_curve, const Span curve_ranges, const GSpan src, GMutableSpan dst) { - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); - const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange range) { for (const IndexRange range : curve_ranges.slice(range)) { const IndexRange src_points = src_points_by_curve[range]; @@ -44,14 +52,12 @@ void copy_point_data(const CurvesGeometry &src_curves, }); } -void copy_point_data(const CurvesGeometry &src_curves, - const CurvesGeometry &dst_curves, +void copy_point_data(const OffsetIndices src_points_by_curve, + const OffsetIndices dst_points_by_curve, const IndexMask src_curve_selection, const GSpan src, GMutableSpan dst) { - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); - const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(src_curve_selection.index_range(), 512, [&](IndexRange range) { for (const int i : src_curve_selection.slice(range)) { const IndexRange src_points = src_points_by_curve[i]; @@ -62,14 +68,13 @@ void copy_point_data(const CurvesGeometry &src_curves, }); } -void fill_points(const CurvesGeometry &curves, +void fill_points(const OffsetIndices points_by_curve, const IndexMask curve_selection, const GPointer value, GMutableSpan dst) { BLI_assert(*value.type() == dst.type()); const CPPType &type = dst.type(); - const OffsetIndices points_by_curve = curves.points_by_curve(); threading::parallel_for(curve_selection.index_range(), 512, [&](IndexRange range) { for (const int i : curve_selection.slice(range)) { const IndexRange points = points_by_curve[i]; @@ -78,14 +83,13 @@ void fill_points(const CurvesGeometry &curves, }); } -void fill_points(const CurvesGeometry &curves, +void fill_points(const OffsetIndices points_by_curve, Span curve_ranges, GPointer value, GMutableSpan dst) { BLI_assert(*value.type() == dst.type()); const CPPType &type = dst.type(); - const OffsetIndices points_by_curve = curves.points_by_curve(); threading::parallel_for(curve_ranges.index_range(), 512, [&](IndexRange range) { for (const IndexRange range : curve_ranges.slice(range)) { const IndexRange points = points_by_curve[range]; diff --git a/source/blender/geometry/intern/add_curves_on_mesh.cc b/source/blender/geometry/intern/add_curves_on_mesh.cc index e0f5076021b..2ef51867e07 100644 --- a/source/blender/geometry/intern/add_curves_on_mesh.cc +++ b/source/blender/geometry/intern/add_curves_on_mesh.cc @@ -286,7 +286,7 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, /* Compute new curve offsets. */ MutableSpan curve_offsets = curves.offsets_for_write(); - MutableSpan new_point_counts_per_curve = curve_offsets.take_back(added_curves_num); + MutableSpan new_point_counts_per_curve = curve_offsets.drop_front(old_curves_num); if (inputs.interpolate_point_count) { interpolate_from_neighbors( neighbors_per_curve, @@ -297,9 +297,8 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, else { new_point_counts_per_curve.fill(inputs.fallback_point_count); } - for (const int i : new_curves_range) { - curve_offsets[i + 1] += curve_offsets[i]; - } + offset_indices::accumulate_counts_to_offsets(curve_offsets.drop_front(old_curves_num), + old_points_num); const int new_points_num = curves.offsets().last(); curves.resize(new_points_num, new_curves_num); diff --git a/source/blender/geometry/intern/fillet_curves.cc b/source/blender/geometry/intern/fillet_curves.cc index 0107eafba9d..e43960db1e7 100644 --- a/source/blender/geometry/intern/fillet_curves.cc +++ b/source/blender/geometry/intern/fillet_curves.cc @@ -26,15 +26,13 @@ static void threaded_slice_fill(const Span src, } template -static void duplicate_fillet_point_data(const bke::CurvesGeometry &src_curves, - const bke::CurvesGeometry &dst_curves, +static void duplicate_fillet_point_data(const OffsetIndices src_points_by_curve, + const OffsetIndices dst_points_by_curve, const IndexMask curve_selection, const Span all_point_offsets, const Span src, MutableSpan dst) { - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); - const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(curve_selection.index_range(), 512, [&](IndexRange range) { for (const int curve_i : curve_selection.slice(range)) { const IndexRange src_points = src_points_by_curve[curve_i]; @@ -47,8 +45,8 @@ static void duplicate_fillet_point_data(const bke::CurvesGeometry &src_curves, }); } -static void duplicate_fillet_point_data(const bke::CurvesGeometry &src_curves, - const bke::CurvesGeometry &dst_curves, +static void duplicate_fillet_point_data(const OffsetIndices src_points_by_curve, + const OffsetIndices dst_points_by_curve, const IndexMask selection, const Span all_point_offsets, const GSpan src, @@ -56,12 +54,16 @@ static void duplicate_fillet_point_data(const bke::CurvesGeometry &src_curves, { attribute_math::convert_to_static_type(dst.type(), [&](auto dummy) { using T = decltype(dummy); - duplicate_fillet_point_data( - src_curves, dst_curves, selection, all_point_offsets, src.typed(), dst.typed()); + duplicate_fillet_point_data(src_points_by_curve, + dst_points_by_curve, + selection, + all_point_offsets, + src.typed(), + dst.typed()); }); } -static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, +static void calculate_result_offsets(const OffsetIndices src_points_by_curve, const IndexMask selection, const Span unselected_ranges, const VArray &radii, @@ -71,11 +73,10 @@ static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, MutableSpan dst_point_offsets) { /* Fill the offsets array with the curve point counts, then accumulate them to form offsets. */ - bke::curves::copy_curve_sizes(src_curves, unselected_ranges, dst_curve_offsets); - const OffsetIndices points_by_curve = src_curves.points_by_curve(); + bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_curve_offsets); threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int curve_i : selection.slice(range)) { - const IndexRange src_points = points_by_curve[curve_i]; + const IndexRange src_points = src_points_by_curve[curve_i]; const IndexRange offsets_range = bke::curves::per_curve_point_offsets_range(src_points, curve_i); @@ -403,18 +404,18 @@ static bke::CurvesGeometry fillet_curves( const bool use_bezier_mode, const bke::AnonymousAttributePropagationInfo &propagation_info) { - const Vector unselected_ranges = curve_selection.extract_ranges_invert( - src_curves.curves_range()); - + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); const Span positions = src_curves.positions(); const VArraySpan cyclic{src_curves.cyclic()}; const bke::AttributeAccessor src_attributes = src_curves.attributes(); + const Vector unselected_ranges = curve_selection.extract_ranges_invert( + src_curves.curves_range()); bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves); /* Stores the offset of every result point for every original point. * The extra length is used in order to store an extra zero for every curve. */ Array dst_point_offsets(src_curves.points_num() + src_curves.curves_num()); - calculate_result_offsets(src_curves, + calculate_result_offsets(src_points_by_curve, curve_selection, unselected_ranges, radius_input, @@ -422,6 +423,7 @@ static bke::CurvesGeometry fillet_curves( cyclic, dst_curves.offsets_for_write(), dst_point_offsets); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); const Span all_point_offsets = dst_point_offsets.as_span(); dst_curves.resize(dst_curves.offsets().last(), dst_curves.curves_num()); @@ -448,8 +450,6 @@ static bke::CurvesGeometry fillet_curves( dst_handles_r = dst_curves.handle_positions_right_for_write(); } - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); - const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(curve_selection.index_range(), 512, [&](IndexRange range) { Array directions; Array angles; @@ -525,8 +525,8 @@ static bke::CurvesGeometry fillet_curves( ATTR_DOMAIN_MASK_POINT, propagation_info, {"position", "handle_type_left", "handle_type_right", "handle_right", "handle_left"})) { - duplicate_fillet_point_data(src_curves, - dst_curves, + duplicate_fillet_point_data(src_points_by_curve, + dst_points_by_curve, curve_selection, all_point_offsets, attribute.src, @@ -537,8 +537,11 @@ static bke::CurvesGeometry fillet_curves( if (!unselected_ranges.is_empty()) { for (auto &attribute : bke::retrieve_attributes_for_transfer( src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info)) { - bke::curves::copy_point_data( - src_curves, dst_curves, unselected_ranges, attribute.src, attribute.dst.span); + bke::curves::copy_point_data(src_points_by_curve, + dst_points_by_curve, + unselected_ranges, + attribute.src, + attribute.dst.span); attribute.dst.finish(); } } diff --git a/source/blender/geometry/intern/resample_curves.cc b/source/blender/geometry/intern/resample_curves.cc index 00bd1898674..53677277a61 100644 --- a/source/blender/geometry/intern/resample_curves.cc +++ b/source/blender/geometry/intern/resample_curves.cc @@ -192,29 +192,36 @@ static void copy_or_defaults_for_unselected_curves(const CurvesGeometry &src_cur const AttributesForInterpolation &attributes, CurvesGeometry &dst_curves) { - bke::curves::copy_point_data(src_curves, - dst_curves, + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); + bke::curves::copy_point_data(src_points_by_curve, + dst_points_by_curve, unselected_ranges, src_curves.positions(), dst_curves.positions_for_write()); for (const int i : attributes.src.index_range()) { - bke::curves::copy_point_data( - src_curves, dst_curves, unselected_ranges, attributes.src[i], attributes.dst[i]); + bke::curves::copy_point_data(src_points_by_curve, + dst_points_by_curve, + unselected_ranges, + attributes.src[i], + attributes.dst[i]); } for (const int i : attributes.src_no_interpolation.index_range()) { - bke::curves::copy_point_data(src_curves, - dst_curves, + bke::curves::copy_point_data(src_points_by_curve, + dst_points_by_curve, unselected_ranges, attributes.src_no_interpolation[i], attributes.dst_no_interpolation[i]); } if (!attributes.dst_tangents.is_empty()) { - bke::curves::fill_points(dst_curves, unselected_ranges, float3(0), attributes.dst_tangents); + bke::curves::fill_points( + dst_points_by_curve, unselected_ranges, float3(0), attributes.dst_tangents); } if (!attributes.dst_normals.is_empty()) { - bke::curves::fill_points(dst_curves, unselected_ranges, float3(0), attributes.dst_normals); + bke::curves::fill_points( + dst_points_by_curve, unselected_ranges, float3(0), attributes.dst_normals); } } @@ -239,6 +246,12 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, const fn::Field &count_field, const ResampleCurvesOutputAttributeIDs &output_ids) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices evaluated_points_by_curve = src_curves.evaluated_points_by_curve(); + const VArray curves_cyclic = src_curves.cyclic(); + const VArray curve_types = src_curves.curve_types(); + const Span evaluated_positions = src_curves.evaluated_positions(); + CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves); MutableSpan dst_offsets = dst_curves.offsets_for_write(); @@ -252,18 +265,13 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, src_curves.curves_range(), nullptr); /* Fill the counts for the curves that aren't selected and accumulate the counts into offsets. */ - bke::curves::copy_curve_sizes(src_curves, unselected_ranges, dst_offsets); + bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_offsets); offset_indices::accumulate_counts_to_offsets(dst_offsets); dst_curves.resize(dst_offsets.last(), dst_curves.curves_num()); /* All resampled curves are poly curves. */ dst_curves.fill_curve_types(selection, CURVE_TYPE_POLY); - const OffsetIndices evaluated_points_by_curve = src_curves.evaluated_points_by_curve(); - const VArray curves_cyclic = src_curves.cyclic(); - const VArray curve_types = src_curves.curve_types(); - const Span evaluated_positions = src_curves.evaluated_positions(); - MutableSpan dst_positions = dst_curves.positions_for_write(); AttributesForInterpolation attributes; @@ -280,7 +288,6 @@ static CurvesGeometry resample_to_uniform(const CurvesGeometry &src_curves, Array sample_factors(dst_curves.points_num()); const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); /* Use a "for each group of curves: for each attribute: for each curve" pattern to work on * smaller sections of data that ideally fit into CPU cache better than simply one attribute at a @@ -403,6 +410,10 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, const fn::Field &selection_field, const ResampleCurvesOutputAttributeIDs &output_ids) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const OffsetIndices src_evaluated_points_by_curve = src_curves.evaluated_points_by_curve(); + const Span evaluated_positions = src_curves.evaluated_positions(); + const bke::CurvesFieldContext field_context{src_curves, ATTR_DOMAIN_CURVE}; fn::FieldEvaluator evaluator{field_context, src_curves.curves_num()}; evaluator.set_selection(selection_field); @@ -410,25 +421,17 @@ CurvesGeometry resample_to_evaluated(const CurvesGeometry &src_curves, const IndexMask selection = evaluator.get_evaluated_selection_as_mask(); const Vector unselected_ranges = selection.extract_ranges_invert( src_curves.curves_range(), nullptr); - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); - const OffsetIndices src_evaluated_points_by_curve = src_curves.evaluated_points_by_curve(); CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves); dst_curves.fill_curve_types(selection, CURVE_TYPE_POLY); MutableSpan dst_offsets = dst_curves.offsets_for_write(); - threading::parallel_for(selection.index_range(), 4096, [&](IndexRange range) { - for (const int i : selection.slice(range)) { - dst_offsets[i] = src_evaluated_points_by_curve.size(i); - } - }); - bke::curves::copy_curve_sizes(src_curves, unselected_ranges, dst_offsets); + bke::curves::copy_curve_sizes(src_evaluated_points_by_curve, selection, dst_offsets); + bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_offsets); offset_indices::accumulate_counts_to_offsets(dst_offsets); const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); dst_curves.resize(dst_offsets.last(), dst_curves.curves_num()); - /* Create the correct number of uniform-length samples for every selected curve. */ - const Span evaluated_positions = src_curves.evaluated_positions(); MutableSpan dst_positions = dst_curves.positions_for_write(); AttributesForInterpolation attributes; diff --git a/source/blender/geometry/intern/set_curve_type.cc b/source/blender/geometry/intern/set_curve_type.cc index 85f6325ea13..44e9d285034 100644 --- a/source/blender/geometry/intern/set_curve_type.cc +++ b/source/blender/geometry/intern/set_curve_type.cc @@ -277,43 +277,44 @@ static int to_nurbs_size(const CurveType src_type, const int src_size) } } -static void retrieve_curve_sizes(const bke::CurvesGeometry &curves, MutableSpan sizes) -{ - const OffsetIndices points_by_curve = curves.points_by_curve(); - threading::parallel_for(curves.curves_range(), 4096, [&](IndexRange range) { - for (const int i : range) { - sizes[i] = points_by_curve[i].size(); - } - }); -} - static bke::CurvesGeometry convert_curves_to_bezier( const bke::CurvesGeometry &src_curves, const IndexMask selection, const bke::AnonymousAttributePropagationInfo &propagation_info) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); const VArray src_knot_modes = src_curves.nurbs_knots_modes(); const VArray src_types = src_curves.curve_types(); const VArray src_cyclic = src_curves.cyclic(); const Span src_positions = src_curves.positions(); + const bke::AttributeAccessor src_attributes = src_curves.attributes(); + const Vector unselected_ranges = selection.extract_ranges_invert( + src_curves.curves_range()); bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves); dst_curves.fill_curve_types(selection, CURVE_TYPE_BEZIER); MutableSpan dst_offsets = dst_curves.offsets_for_write(); - retrieve_curve_sizes(src_curves, dst_curves.offsets_for_write()); + bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_offsets); threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) { for (const int i : selection.slice(range)) { - dst_offsets[i] = to_bezier_size( - CurveType(src_types[i]), src_cyclic[i], KnotsMode(src_knot_modes[i]), dst_offsets[i]); + dst_offsets[i] = to_bezier_size(CurveType(src_types[i]), + src_cyclic[i], + KnotsMode(src_knot_modes[i]), + src_points_by_curve.size(i)); } }); offset_indices::accumulate_counts_to_offsets(dst_offsets); dst_curves.resize(dst_offsets.last(), dst_curves.curves_num()); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); - const bke::AttributeAccessor src_attributes = src_curves.attributes(); + MutableSpan dst_positions = dst_curves.positions_for_write(); + MutableSpan dst_handles_l = dst_curves.handle_positions_left_for_write(); + MutableSpan dst_handles_r = dst_curves.handle_positions_right_for_write(); + MutableSpan dst_types_l = dst_curves.handle_types_left_for_write(); + MutableSpan dst_types_r = dst_curves.handle_types_right_for_write(); + MutableSpan dst_weights = dst_curves.nurbs_weights_for_write(); bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write(); - Vector generic_attributes = bke::retrieve_attributes_for_transfer( src_attributes, dst_attributes, @@ -326,20 +327,13 @@ static bke::CurvesGeometry convert_curves_to_bezier( "handle_left", "nurbs_weight"}); - MutableSpan dst_positions = dst_curves.positions_for_write(); - MutableSpan dst_handles_l = dst_curves.handle_positions_left_for_write(); - MutableSpan dst_handles_r = dst_curves.handle_positions_right_for_write(); - MutableSpan dst_types_l = dst_curves.handle_types_left_for_write(); - MutableSpan dst_types_r = dst_curves.handle_types_right_for_write(); - MutableSpan dst_weights = dst_curves.nurbs_weights_for_write(); - - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); - const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); - auto catmull_rom_to_bezier = [&](IndexMask selection) { - bke::curves::fill_points(dst_curves, selection, BEZIER_HANDLE_ALIGN, dst_types_l); - bke::curves::fill_points(dst_curves, selection, BEZIER_HANDLE_ALIGN, dst_types_r); - bke::curves::copy_point_data(src_curves, dst_curves, selection, src_positions, dst_positions); + bke::curves::fill_points( + dst_points_by_curve, selection, BEZIER_HANDLE_ALIGN, dst_types_l); + bke::curves::fill_points( + dst_points_by_curve, selection, BEZIER_HANDLE_ALIGN, dst_types_r); + bke::curves::copy_point_data( + src_points_by_curve, dst_points_by_curve, selection, src_positions, dst_positions); threading::parallel_for(selection.index_range(), 512, [&](IndexRange range) { for (const int i : selection.slice(range)) { @@ -354,18 +348,21 @@ static bke::CurvesGeometry convert_curves_to_bezier( for (bke::AttributeTransferData &attribute : generic_attributes) { bke::curves::copy_point_data( - src_curves, dst_curves, selection, attribute.src, attribute.dst.span); + src_points_by_curve, dst_points_by_curve, selection, attribute.src, attribute.dst.span); } }; auto poly_to_bezier = [&](IndexMask selection) { - bke::curves::copy_point_data(src_curves, dst_curves, selection, src_positions, dst_positions); - bke::curves::fill_points(dst_curves, selection, BEZIER_HANDLE_VECTOR, dst_types_l); - bke::curves::fill_points(dst_curves, selection, BEZIER_HANDLE_VECTOR, dst_types_r); + bke::curves::copy_point_data( + src_points_by_curve, dst_points_by_curve, selection, src_positions, dst_positions); + bke::curves::fill_points( + dst_points_by_curve, selection, BEZIER_HANDLE_VECTOR, dst_types_l); + bke::curves::fill_points( + dst_points_by_curve, selection, BEZIER_HANDLE_VECTOR, dst_types_r); dst_curves.calculate_bezier_auto_handles(); for (bke::AttributeTransferData &attribute : generic_attributes) { bke::curves::copy_point_data( - src_curves, dst_curves, selection, attribute.src, attribute.dst.span); + src_points_by_curve, dst_points_by_curve, selection, attribute.src, attribute.dst.span); } }; @@ -375,24 +372,31 @@ static bke::CurvesGeometry convert_curves_to_bezier( const Span src_handles_l = src_curves.handle_positions_left(); const Span src_handles_r = src_curves.handle_positions_right(); - bke::curves::copy_point_data(src_curves, dst_curves, selection, src_positions, dst_positions); - bke::curves::copy_point_data(src_curves, dst_curves, selection, src_handles_l, dst_handles_l); - bke::curves::copy_point_data(src_curves, dst_curves, selection, src_handles_r, dst_handles_r); - bke::curves::copy_point_data(src_curves, dst_curves, selection, src_types_l, dst_types_l); - bke::curves::copy_point_data(src_curves, dst_curves, selection, src_types_r, dst_types_r); + bke::curves::copy_point_data( + src_points_by_curve, dst_points_by_curve, selection, src_positions, dst_positions); + bke::curves::copy_point_data( + src_points_by_curve, dst_points_by_curve, selection, src_handles_l, dst_handles_l); + bke::curves::copy_point_data( + src_points_by_curve, dst_points_by_curve, selection, src_handles_r, dst_handles_r); + bke::curves::copy_point_data( + src_points_by_curve, dst_points_by_curve, selection, src_types_l, dst_types_l); + bke::curves::copy_point_data( + src_points_by_curve, dst_points_by_curve, selection, src_types_r, dst_types_r); dst_curves.calculate_bezier_auto_handles(); for (bke::AttributeTransferData &attribute : generic_attributes) { bke::curves::copy_point_data( - src_curves, dst_curves, selection, attribute.src, attribute.dst.span); + src_points_by_curve, dst_points_by_curve, selection, attribute.src, attribute.dst.span); } }; auto nurbs_to_bezier = [&](IndexMask selection) { - bke::curves::fill_points(dst_curves, selection, BEZIER_HANDLE_ALIGN, dst_types_l); - bke::curves::fill_points(dst_curves, selection, BEZIER_HANDLE_ALIGN, dst_types_r); - bke::curves::fill_points(dst_curves, selection, 0.0f, dst_weights); + bke::curves::fill_points( + dst_points_by_curve, selection, BEZIER_HANDLE_ALIGN, dst_types_l); + bke::curves::fill_points( + dst_points_by_curve, selection, BEZIER_HANDLE_ALIGN, dst_types_r); + bke::curves::fill_points(dst_points_by_curve, selection, 0.0f, dst_weights); threading::parallel_for(selection.index_range(), 64, [&](IndexRange range) { for (const int i : selection.slice(range)) { @@ -452,12 +456,12 @@ static bke::CurvesGeometry convert_curves_to_bezier( bezier_to_bezier, nurbs_to_bezier); - const Vector unselected_ranges = selection.extract_ranges_invert( - src_curves.curves_range()); - for (bke::AttributeTransferData &attribute : generic_attributes) { - bke::curves::copy_point_data( - src_curves, dst_curves, unselected_ranges, attribute.src, attribute.dst.span); + bke::curves::copy_point_data(src_points_by_curve, + dst_points_by_curve, + unselected_ranges, + attribute.src, + attribute.dst.span); } for (bke::AttributeTransferData &attribute : generic_attributes) { @@ -472,26 +476,30 @@ static bke::CurvesGeometry convert_curves_to_nurbs( const IndexMask selection, const bke::AnonymousAttributePropagationInfo &propagation_info) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); const VArray src_types = src_curves.curve_types(); const VArray src_cyclic = src_curves.cyclic(); const Span src_positions = src_curves.positions(); + const bke::AttributeAccessor src_attributes = src_curves.attributes(); + const Vector unselected_ranges = selection.extract_ranges_invert( + src_curves.curves_range()); bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves); dst_curves.fill_curve_types(selection, CURVE_TYPE_NURBS); MutableSpan dst_offsets = dst_curves.offsets_for_write(); - retrieve_curve_sizes(src_curves, dst_curves.offsets_for_write()); + bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_offsets); threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) { for (const int i : selection.slice(range)) { - dst_offsets[i] = to_nurbs_size(CurveType(src_types[i]), dst_offsets[i]); + dst_offsets[i] = to_nurbs_size(CurveType(src_types[i]), src_points_by_curve.size(i)); } }); offset_indices::accumulate_counts_to_offsets(dst_offsets); dst_curves.resize(dst_offsets.last(), dst_curves.curves_num()); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); - const bke::AttributeAccessor src_attributes = src_curves.attributes(); + MutableSpan dst_positions = dst_curves.positions_for_write(); bke::MutableAttributeAccessor dst_attributes = dst_curves.attributes_for_write(); - Vector generic_attributes = bke::retrieve_attributes_for_transfer( src_attributes, dst_attributes, @@ -504,17 +512,13 @@ static bke::CurvesGeometry convert_curves_to_nurbs( "handle_left", "nurbs_weight"}); - MutableSpan dst_positions = dst_curves.positions_for_write(); - auto fill_weights_if_necessary = [&](const IndexMask selection) { if (!src_curves.nurbs_weights().is_empty()) { - bke::curves::fill_points(dst_curves, selection, 1.0f, dst_curves.nurbs_weights_for_write()); + bke::curves::fill_points( + dst_points_by_curve, selection, 1.0f, dst_curves.nurbs_weights_for_write()); } }; - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); - const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); - auto catmull_rom_to_nurbs = [&](IndexMask selection) { dst_curves.nurbs_orders_for_write().fill_indices(selection, 4); dst_curves.nurbs_knots_modes_for_write().fill_indices(selection, NURBS_KNOT_MODE_BEZIER); @@ -543,7 +547,8 @@ static bke::CurvesGeometry convert_curves_to_nurbs( auto poly_to_nurbs = [&](IndexMask selection) { dst_curves.nurbs_orders_for_write().fill_indices(selection, 4); - bke::curves::copy_point_data(src_curves, dst_curves, selection, src_positions, dst_positions); + bke::curves::copy_point_data( + src_points_by_curve, dst_points_by_curve, selection, src_positions, dst_positions); fill_weights_if_necessary(selection); /* Avoid using "Endpoint" knots modes for cyclic curves, since it adds a sharp point at the @@ -565,7 +570,7 @@ static bke::CurvesGeometry convert_curves_to_nurbs( for (bke::AttributeTransferData &attribute : generic_attributes) { bke::curves::copy_point_data( - src_curves, dst_curves, selection, attribute.src, attribute.dst.span); + src_points_by_curve, dst_points_by_curve, selection, attribute.src, attribute.dst.span); } }; @@ -601,11 +606,12 @@ static bke::CurvesGeometry convert_curves_to_nurbs( }; auto nurbs_to_nurbs = [&](IndexMask selection) { - bke::curves::copy_point_data(src_curves, dst_curves, selection, src_positions, dst_positions); + bke::curves::copy_point_data( + src_points_by_curve, dst_points_by_curve, selection, src_positions, dst_positions); if (!src_curves.nurbs_weights().is_empty()) { - bke::curves::copy_point_data(src_curves, - dst_curves, + bke::curves::copy_point_data(src_points_by_curve, + dst_points_by_curve, selection, src_curves.nurbs_weights(), dst_curves.nurbs_weights_for_write()); @@ -613,7 +619,7 @@ static bke::CurvesGeometry convert_curves_to_nurbs( for (bke::AttributeTransferData &attribute : generic_attributes) { bke::curves::copy_point_data( - src_curves, dst_curves, selection, attribute.src, attribute.dst.span); + src_points_by_curve, dst_points_by_curve, selection, attribute.src, attribute.dst.span); } }; @@ -625,12 +631,12 @@ static bke::CurvesGeometry convert_curves_to_nurbs( bezier_to_nurbs, nurbs_to_nurbs); - const Vector unselected_ranges = selection.extract_ranges_invert( - src_curves.curves_range()); - for (bke::AttributeTransferData &attribute : generic_attributes) { - bke::curves::copy_point_data( - src_curves, dst_curves, unselected_ranges, attribute.src, attribute.dst.span); + bke::curves::copy_point_data(src_points_by_curve, + dst_points_by_curve, + unselected_ranges, + attribute.src, + attribute.dst.span); } for (bke::AttributeTransferData &attribute : generic_attributes) { diff --git a/source/blender/geometry/intern/subdivide_curves.cc b/source/blender/geometry/intern/subdivide_curves.cc index f062f720366..f2286d8f28c 100644 --- a/source/blender/geometry/intern/subdivide_curves.cc +++ b/source/blender/geometry/intern/subdivide_curves.cc @@ -20,8 +20,8 @@ static void calculate_result_offsets(const bke::CurvesGeometry &src_curves, MutableSpan dst_point_offsets) { /* Fill the array with each curve's point count, then accumulate them to the offsets. */ - bke::curves::copy_curve_sizes(src_curves, unselected_ranges, dst_curve_offsets); const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_curve_offsets); threading::parallel_for(selection.index_range(), 1024, [&](IndexRange range) { for (const int curve_i : selection.slice(range)) { const IndexRange src_points = src_points_by_curve[curve_i]; @@ -64,15 +64,13 @@ static inline void linear_interpolation(const T &a, const T &b, MutableSpan d } template -static void subdivide_attribute_linear(const bke::CurvesGeometry &src_curves, - const bke::CurvesGeometry &dst_curves, +static void subdivide_attribute_linear(const OffsetIndices src_points_by_curve, + const OffsetIndices dst_points_by_curve, const IndexMask selection, const Span all_point_offsets, const Span src, MutableSpan dst) { - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); - const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(selection.index_range(), 512, [&](IndexRange selection_range) { for (const int curve_i : selection.slice(selection_range)) { const IndexRange src_points = src_points_by_curve[curve_i]; @@ -96,8 +94,8 @@ static void subdivide_attribute_linear(const bke::CurvesGeometry &src_curves, }); } -static void subdivide_attribute_linear(const bke::CurvesGeometry &src_curves, - const bke::CurvesGeometry &dst_curves, +static void subdivide_attribute_linear(const OffsetIndices src_points_by_curve, + const OffsetIndices dst_points_by_curve, const IndexMask selection, const Span all_point_offsets, const GSpan src, @@ -105,22 +103,24 @@ static void subdivide_attribute_linear(const bke::CurvesGeometry &src_curves, { attribute_math::convert_to_static_type(dst.type(), [&](auto dummy) { using T = decltype(dummy); - subdivide_attribute_linear( - src_curves, dst_curves, selection, all_point_offsets, src.typed(), dst.typed()); + subdivide_attribute_linear(src_points_by_curve, + dst_points_by_curve, + selection, + all_point_offsets, + src.typed(), + dst.typed()); }); } template -static void subdivide_attribute_catmull_rom(const bke::CurvesGeometry &src_curves, - const bke::CurvesGeometry &dst_curves, +static void subdivide_attribute_catmull_rom(const OffsetIndices src_points_by_curve, + const OffsetIndices dst_points_by_curve, const IndexMask selection, const Span all_point_offsets, const Span cyclic, const Span src, MutableSpan dst) { - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); - const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); threading::parallel_for(selection.index_range(), 512, [&](IndexRange selection_range) { for (const int curve_i : selection.slice(selection_range)) { const IndexRange src_points = src_points_by_curve[curve_i]; @@ -135,8 +135,8 @@ static void subdivide_attribute_catmull_rom(const bke::CurvesGeometry &src_curve }); } -static void subdivide_attribute_catmull_rom(const bke::CurvesGeometry &src_curves, - const bke::CurvesGeometry &dst_curves, +static void subdivide_attribute_catmull_rom(const OffsetIndices src_points_by_curve, + const OffsetIndices dst_points_by_curve, const IndexMask selection, const Span all_point_offsets, const Span cyclic, @@ -145,8 +145,8 @@ static void subdivide_attribute_catmull_rom(const bke::CurvesGeometry &src_curve { attribute_math::convert_to_static_type(dst.type(), [&](auto dummy) { using T = decltype(dummy); - subdivide_attribute_catmull_rom(src_curves, - dst_curves, + subdivide_attribute_catmull_rom(src_points_by_curve, + dst_points_by_curve, selection, all_point_offsets, cyclic, @@ -300,11 +300,11 @@ bke::CurvesGeometry subdivide_curves( const VArray &cuts, const bke::AnonymousAttributePropagationInfo &propagation_info) { - const Vector unselected_ranges = selection.extract_ranges_invert( - src_curves.curves_range()); - + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); /* Cyclic is accessed a lot, it's probably worth it to make sure it's a span. */ const VArraySpan cyclic{src_curves.cyclic()}; + const Vector unselected_ranges = selection.extract_ranges_invert( + src_curves.curves_range()); bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves); @@ -331,6 +331,8 @@ bke::CurvesGeometry subdivide_curves( cyclic, dst_curves.offsets_for_write(), all_point_offset_data); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); + const Span all_point_offsets(all_point_offset_data); dst_curves.resize(dst_curves.offsets().last(), dst_curves.curves_num()); @@ -341,8 +343,8 @@ bke::CurvesGeometry subdivide_curves( auto subdivide_catmull_rom = [&](IndexMask selection) { for (auto &attribute : bke::retrieve_attributes_for_transfer( src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info)) { - subdivide_attribute_catmull_rom(src_curves, - dst_curves, + subdivide_attribute_catmull_rom(src_points_by_curve, + dst_points_by_curve, selection, all_point_offsets, cyclic, @@ -355,8 +357,12 @@ bke::CurvesGeometry subdivide_curves( auto subdivide_poly = [&](IndexMask selection) { for (auto &attribute : bke::retrieve_attributes_for_transfer( src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info)) { - subdivide_attribute_linear( - src_curves, dst_curves, selection, all_point_offsets, attribute.src, attribute.dst.span); + subdivide_attribute_linear(src_points_by_curve, + dst_points_by_curve, + selection, + all_point_offsets, + attribute.src, + attribute.dst.span); attribute.dst.finish(); } }; @@ -367,7 +373,6 @@ bke::CurvesGeometry subdivide_curves( const VArraySpan src_types_r{src_curves.handle_types_right()}; const Span src_handles_l = src_curves.handle_positions_left(); const Span src_handles_r = src_curves.handle_positions_right(); - const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); MutableSpan dst_positions = dst_curves.positions_for_write(); MutableSpan dst_types_l = dst_curves.handle_types_left_for_write(); @@ -406,8 +411,12 @@ bke::CurvesGeometry subdivide_curves( "handle_type_right", "handle_right", "handle_left"})) { - subdivide_attribute_linear( - src_curves, dst_curves, selection, all_point_offsets, attribute.src, attribute.dst.span); + subdivide_attribute_linear(src_points_by_curve, + dst_points_by_curve, + selection, + all_point_offsets, + attribute.src, + attribute.dst.span); attribute.dst.finish(); } }; @@ -427,8 +436,11 @@ bke::CurvesGeometry subdivide_curves( if (!unselected_ranges.is_empty()) { for (auto &attribute : bke::retrieve_attributes_for_transfer( src_attributes, dst_attributes, ATTR_DOMAIN_MASK_POINT, propagation_info)) { - bke::curves::copy_point_data( - src_curves, dst_curves, unselected_ranges, attribute.src, attribute.dst.span); + bke::curves::copy_point_data(src_points_by_curve, + dst_points_by_curve, + unselected_ranges, + attribute.src, + attribute.dst.span); attribute.dst.finish(); } } diff --git a/source/blender/geometry/intern/trim_curves.cc b/source/blender/geometry/intern/trim_curves.cc index 82b8199a168..810f950158a 100644 --- a/source/blender/geometry/intern/trim_curves.cc +++ b/source/blender/geometry/intern/trim_curves.cc @@ -212,7 +212,8 @@ static void fill_nurbs_data(bke::CurvesGeometry &dst_curves, const IndexMask sel if (!dst_curves.has_curve_with_type(CURVE_TYPE_NURBS)) { return; } - bke::curves::fill_points(dst_curves, selection, 0.0f, dst_curves.nurbs_weights_for_write()); + bke::curves::fill_points( + dst_curves.points_by_curve(), selection, 0.0f, dst_curves.nurbs_weights_for_write()); } template @@ -950,21 +951,21 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, const GeometryNodeCurveSampleMode mode, const bke::AnonymousAttributePropagationInfo &propagation_info) { + const OffsetIndices src_points_by_curve = src_curves.points_by_curve(); + const Vector unselected_ranges = selection.extract_ranges_invert( + src_curves.curves_range()); + BLI_assert(selection.size() > 0); BLI_assert(selection.last() <= src_curves.curves_num()); BLI_assert(starts.size() == src_curves.curves_num()); BLI_assert(starts.size() == ends.size()); src_curves.ensure_evaluated_lengths(); - const Vector inverse_selection = selection.extract_ranges_invert( - src_curves.curves_range()); - bke::CurvesGeometry dst_curves = bke::curves::copy_only_curve_domain(src_curves); MutableSpan dst_curve_offsets = dst_curves.offsets_for_write(); Array start_points(src_curves.curves_num()); Array end_points(src_curves.curves_num()); Array src_ranges(src_curves.curves_num()); - compute_curve_trim_parameters(src_curves, selection, starts, @@ -974,10 +975,9 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, start_points, end_points, src_ranges); - bke::curves::copy_curve_sizes(src_curves, inverse_selection, dst_curve_offsets); - - /* Finalize and update the geometry container. */ + bke::curves::copy_curve_sizes(src_points_by_curve, unselected_ranges, dst_curve_offsets); offset_indices::accumulate_counts_to_offsets(dst_curve_offsets); + const OffsetIndices dst_points_by_curve = dst_curves.points_by_curve(); dst_curves.resize(dst_curves.offsets().last(), dst_curves.curves_num()); /* Populate curve domain. */ @@ -1058,7 +1058,7 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, } /* Copy unselected */ - if (inverse_selection.is_empty()) { + if (unselected_ranges.is_empty()) { /* Since all curves were trimmed, none of them are cyclic and the attribute can be removed. */ dst_curves.attributes_for_write().remove("cyclic"); } @@ -1081,8 +1081,11 @@ bke::CurvesGeometry trim_curves(const bke::CurvesGeometry &src_curves, ATTR_DOMAIN_MASK_POINT, propagation_info, copy_point_skip)) { - bke::curves::copy_point_data( - src_curves, dst_curves, inverse_selection, attribute.src, attribute.dst.span); + bke::curves::copy_point_data(src_points_by_curve, + dst_points_by_curve, + unselected_ranges, + attribute.src, + attribute.dst.span); attribute.dst.finish(); } } From f24b9a7943d4a7e20008efc070bba4f879aa00dd Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 23 Jan 2023 14:47:08 -0600 Subject: [PATCH 0889/1522] Cleanup: Rename pbvh.cc to pbvh_colors.cc In preparation for moving pbvh.c to C++, give this file a different name so git will recognize that future commit as a rename. --- source/blender/blenkernel/CMakeLists.txt | 2 +- source/blender/blenkernel/intern/{pbvh.cc => pbvh_colors.cc} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename source/blender/blenkernel/intern/{pbvh.cc => pbvh_colors.cc} (100%) diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 1f4ab73911a..7052f362fc4 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -249,7 +249,7 @@ set(SRC intern/particle_distribute.c intern/particle_system.c intern/pbvh.c - intern/pbvh.cc + intern/pbvh_colors.cc intern/pbvh_bmesh.c intern/pbvh_pixels.cc intern/pbvh_uv_islands.cc diff --git a/source/blender/blenkernel/intern/pbvh.cc b/source/blender/blenkernel/intern/pbvh_colors.cc similarity index 100% rename from source/blender/blenkernel/intern/pbvh.cc rename to source/blender/blenkernel/intern/pbvh_colors.cc From 79ba1a1ac82d854d840e98141b2458e4c7e2a7dd Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 23 Jan 2023 14:57:26 -0600 Subject: [PATCH 0890/1522] Cleanup: Compiler warnings in new sculpt & workbench Set but unused variables, unused arguments, unnecessary/incorrect type casting, missing static qualifier. Unused arguments are removed. --- source/blender/blenkernel/intern/pbvh_pixels.cc | 10 +++------- source/blender/draw/engines/basic/basic_engine.c | 6 +----- source/blender/draw/engines/eevee/eevee_materials.c | 6 +----- .../engines/workbench/workbench_effect_outline.cc | 2 +- .../draw/engines/workbench/workbench_engine.cc | 6 +++--- .../draw/engines/workbench/workbench_mesh_passes.cc | 13 +++---------- .../draw/engines/workbench/workbench_private.hh | 10 ++++------ .../draw/engines/workbench/workbench_resources.cc | 8 ++++---- .../draw/engines/workbench/workbench_shadow.cc | 10 ++-------- source/blender/editors/sculpt_paint/sculpt_intern.h | 2 -- .../editors/sculpt_paint/sculpt_paint_color.c | 3 +-- .../editors/sculpt_paint/sculpt_paint_image.cc | 2 -- 12 files changed, 23 insertions(+), 55 deletions(-) diff --git a/source/blender/blenkernel/intern/pbvh_pixels.cc b/source/blender/blenkernel/intern/pbvh_pixels.cc index ed87631ffe9..0055cf1335f 100644 --- a/source/blender/blenkernel/intern/pbvh_pixels.cc +++ b/source/blender/blenkernel/intern/pbvh_pixels.cc @@ -99,12 +99,8 @@ struct SplitNodePair { static void split_thread_job(TaskPool *__restrict pool, void *taskdata); -static void split_pixel_node(PBVH *pbvh, - SplitNodePair *split, - Mesh *mesh, - Image *image, - ImageUser *image_user, - SplitQueueData *tdata) +static void split_pixel_node( + PBVH *pbvh, SplitNodePair *split, Image *image, ImageUser *image_user, SplitQueueData *tdata) { BB cb; PBVHNode *node = &split->node; @@ -304,7 +300,7 @@ static void split_thread_job(TaskPool *__restrict pool, void *taskdata) SplitQueueData *tdata = static_cast(BLI_task_pool_user_data(pool)); SplitNodePair *split = static_cast(taskdata); - split_pixel_node(tdata->pbvh, split, tdata->mesh, tdata->image, tdata->image_user, tdata); + split_pixel_node(tdata->pbvh, split, tdata->image, tdata->image_user, tdata); } static void split_pixel_nodes(PBVH *pbvh, Mesh *mesh, Image *image, ImageUser *image_user) diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c index 5ff596ca083..e8c2dc259fc 100644 --- a/source/blender/draw/engines/basic/basic_engine.c +++ b/source/blender/draw/engines/basic/basic_engine.c @@ -225,11 +225,7 @@ static void basic_cache_populate(void *vedata, Object *ob) if (G.debug_value == 889 && ob->sculpt && ob->sculpt->pbvh) { int debug_node_nr = 0; DRW_debug_modelmat(ob->object_to_world); - BKE_pbvh_draw_debug_cb( - ob->sculpt->pbvh, - (void (*)(void *d, const float min[3], const float max[3], PBVHNodeFlags f)) - DRW_sculpt_debug_cb, - &debug_node_nr); + BKE_pbvh_draw_debug_cb(ob->sculpt->pbvh, DRW_sculpt_debug_cb, &debug_node_nr); } } } diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c index c90ae397e57..e5645ac4a96 100644 --- a/source/blender/draw/engines/eevee/eevee_materials.c +++ b/source/blender/draw/engines/eevee/eevee_materials.c @@ -888,11 +888,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, if (G.debug_value == 889 && ob->sculpt && ob->sculpt->pbvh) { int debug_node_nr = 0; DRW_debug_modelmat(ob->object_to_world); - BKE_pbvh_draw_debug_cb( - ob->sculpt->pbvh, - (void (*)(void *d, const float min[3], const float max[3], PBVHNodeFlags f)) - DRW_sculpt_debug_cb, - &debug_node_nr); + BKE_pbvh_draw_debug_cb(ob->sculpt->pbvh, DRW_sculpt_debug_cb, &debug_node_nr); } } diff --git a/source/blender/draw/engines/workbench/workbench_effect_outline.cc b/source/blender/draw/engines/workbench/workbench_effect_outline.cc index 18b8b484aef..a1826d5ecf8 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_outline.cc +++ b/source/blender/draw/engines/workbench/workbench_effect_outline.cc @@ -38,7 +38,7 @@ void OutlinePass::sync(SceneResources &resources) ps_.draw_procedural(GPU_PRIM_TRIS, 1, 3); } -void OutlinePass::draw(Manager &manager, View &view, SceneResources &resources, int2 resolution) +void OutlinePass::draw(Manager &manager, SceneResources &resources) { if (!enabled_) { return; diff --git a/source/blender/draw/engines/workbench/workbench_engine.cc b/source/blender/draw/engines/workbench/workbench_engine.cc index a04f61418f6..d2743d5733b 100644 --- a/source/blender/draw/engines/workbench/workbench_engine.cc +++ b/source/blender/draw/engines/workbench/workbench_engine.cc @@ -272,7 +272,7 @@ class Instance { } if (object_state.draw_shadow) { - shadow_ps.object_sync(manager, scene_state, ob_ref, handle, has_transparent_material); + shadow_ps.object_sync(scene_state, ob_ref, handle, has_transparent_material); } } @@ -363,11 +363,11 @@ class Instance { &shadow_ps, transparent_ps.accumulation_ps_.is_empty()); transparent_ps.draw(manager, view, resources, resolution); - transparent_depth_ps.draw(manager, view, resources, resolution); + transparent_depth_ps.draw(manager, view, resources); // volume_ps.draw_prepass(manager, view, resources.depth_tx); - outline_ps.draw(manager, view, resources, resolution); + outline_ps.draw(manager, resources); dof_ps.draw(manager, view, resources, resolution); anti_aliasing_ps.draw(manager, view, resources, resolution, depth_tx, color_tx); diff --git a/source/blender/draw/engines/workbench/workbench_mesh_passes.cc b/source/blender/draw/engines/workbench/workbench_mesh_passes.cc index bc90f26b33d..a32127d66b0 100644 --- a/source/blender/draw/engines/workbench/workbench_mesh_passes.cc +++ b/source/blender/draw/engines/workbench/workbench_mesh_passes.cc @@ -216,12 +216,8 @@ void OpaquePass::draw(Manager &manager, } if (shadow_pass) { - shadow_pass->draw(manager, - view, - resources, - resolution, - *deferred_ps_stencil_tx, - !gbuffer_in_front_ps_.is_empty()); + shadow_pass->draw( + manager, view, resources, *deferred_ps_stencil_tx, !gbuffer_in_front_ps_.is_empty()); } opaque_fb.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(resources.color_tx)); @@ -359,10 +355,7 @@ void TransparentDepthPass::sync(const SceneState &scene_state, SceneResources &r ePipelineType::OPAQUE, eLightingType::FLAT, clip, resources.shader_cache); } -void TransparentDepthPass::draw(Manager &manager, - View &view, - SceneResources &resources, - int2 resolution) +void TransparentDepthPass::draw(Manager &manager, View &view, SceneResources &resources) { if (is_empty()) { return; diff --git a/source/blender/draw/engines/workbench/workbench_private.hh b/source/blender/draw/engines/workbench/workbench_private.hh index 086553ca5c1..94b609519d6 100644 --- a/source/blender/draw/engines/workbench/workbench_private.hh +++ b/source/blender/draw/engines/workbench/workbench_private.hh @@ -244,7 +244,7 @@ class TransparentDepthPass { Framebuffer merge_fb = {"TransparentDepth.Merge"}; void sync(const SceneState &scene_state, SceneResources &resources); - void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution); + void draw(Manager &manager, View &view, SceneResources &resources); bool is_empty() const; }; @@ -269,7 +269,7 @@ class ShadowPass { ShadowView(); protected: - virtual void compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, bool debug_freeze); + virtual void compute_visibility(ObjectBoundsBuf &bounds, uint resource_len); virtual VisibilityBuf &get_visibility_buffer(); } view_ = {}; @@ -299,15 +299,13 @@ class ShadowPass { void init(const SceneState &scene_state, SceneResources &resources); void update(); void sync(); - void object_sync(Manager &manager, - SceneState &scene_state, + void object_sync(SceneState &scene_state, ObjectRef &ob_ref, ResourceHandle handle, const bool has_transp_mat); void draw(Manager &manager, View &view, SceneResources &resources, - int2 resolution, GPUTexture &depth_stencil_tx, /* Needed when there are opaque "In Front" objects in the scene */ bool force_fail_method); @@ -324,7 +322,7 @@ class OutlinePass { public: void init(const SceneState &scene_state); void sync(SceneResources &resources); - void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution); + void draw(Manager &manager, SceneResources &resources); }; class DofPass { diff --git a/source/blender/draw/engines/workbench/workbench_resources.cc b/source/blender/draw/engines/workbench/workbench_resources.cc index 98d3ca8f668..d33b57b943e 100644 --- a/source/blender/draw/engines/workbench/workbench_resources.cc +++ b/source/blender/draw/engines/workbench/workbench_resources.cc @@ -8,7 +8,7 @@ namespace blender::workbench { -bool get_matcap_tx(Texture &matcap_tx, const StudioLight &studio_light) +static bool get_matcap_tx(Texture &matcap_tx, const StudioLight &studio_light) { ImBuf *matcap_diffuse = studio_light.matcap_diffuse.ibuf; ImBuf *matcap_specular = studio_light.matcap_specular.ibuf; @@ -36,7 +36,7 @@ bool get_matcap_tx(Texture &matcap_tx, const StudioLight &studio_light) return false; } -float4x4 get_world_shading_rotation_matrix(float studiolight_rot_z) +static float4x4 get_world_shading_rotation_matrix(float studiolight_rot_z) { /* TODO(Miguel Pozo) C++ API ? */ float V[4][4], R[4][4]; @@ -48,8 +48,8 @@ float4x4 get_world_shading_rotation_matrix(float studiolight_rot_z) return float4x4(R); } -LightData get_light_data_from_studio_solidlight(const SolidLight *sl, - float4x4 world_shading_rotation) +static LightData get_light_data_from_studio_solidlight(const SolidLight *sl, + float4x4 world_shading_rotation) { LightData light = {}; if (sl && sl->flag) { diff --git a/source/blender/draw/engines/workbench/workbench_shadow.cc b/source/blender/draw/engines/workbench/workbench_shadow.cc index 22c7b663220..533e32662a4 100644 --- a/source/blender/draw/engines/workbench/workbench_shadow.cc +++ b/source/blender/draw/engines/workbench/workbench_shadow.cc @@ -131,11 +131,9 @@ void ShadowPass::ShadowView::setup(View &view, float3 light_direction, bool forc float4 extruded_face = float4(UNPACK3(normal), math::dot(normal, corner_a)); /* Ensure the plane faces outwards */ - bool flipped = false; for (float3 corner : frustum_corners.vec) { if (math::dot(float3(extruded_face), corner) > (extruded_face.w + 0.1)) { BLI_assert(!flipped); - flipped = true; extruded_face *= -1; } } @@ -201,9 +199,7 @@ void ShadowPass::ShadowView::set_mode(ShadowPass::PassType type) current_pass_type_ = type; } -void ShadowPass::ShadowView::compute_visibility(ObjectBoundsBuf &bounds, - uint resource_len, - bool debug_freeze) +void ShadowPass::ShadowView::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len) { GPU_debug_group_begin("ShadowView.compute_visibility"); @@ -390,8 +386,7 @@ void ShadowPass::sync() } } -void ShadowPass::object_sync(Manager &manager, - SceneState &scene_state, +void ShadowPass::object_sync(SceneState &scene_state, ObjectRef &ob_ref, ResourceHandle handle, const bool has_transp_mat) @@ -436,7 +431,6 @@ void ShadowPass::object_sync(Manager &manager, void ShadowPass::draw(Manager &manager, View &view, SceneResources &resources, - int2 resolution, GPUTexture &depth_stencil_tx, bool force_fail_method) { diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index a979a78a0ef..2faf53072d6 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -1807,8 +1807,6 @@ bool SCULPT_paint_image_canvas_get(struct PaintModeSettings *paint_mode_settings void SCULPT_do_paint_brush_image(struct PaintModeSettings *paint_mode_settings, Sculpt *sd, Object *ob, - PBVHNode **nodes, - int totnode, PBVHNode **texnodes, int texnode_num) ATTR_NONNULL(); bool SCULPT_use_image_paint_brush(struct PaintModeSettings *settings, Object *ob) ATTR_NONNULL(); diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c index 2826a7c4df3..3a6f7319bdf 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c @@ -258,8 +258,7 @@ void SCULPT_do_paint_brush(PaintModeSettings *paint_mode_settings, int texnodes_num) { if (SCULPT_use_image_paint_brush(paint_mode_settings, ob)) { - SCULPT_do_paint_brush_image( - paint_mode_settings, sd, ob, nodes, totnode, texnodes, texnodes_num); + SCULPT_do_paint_brush_image(paint_mode_settings, sd, ob, texnodes, texnodes_num); return; } diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc index ebe4bcd4916..d9e982f4ff8 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc +++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc @@ -552,8 +552,6 @@ bool SCULPT_use_image_paint_brush(PaintModeSettings *settings, Object *ob) void SCULPT_do_paint_brush_image(PaintModeSettings *paint_mode_settings, Sculpt *sd, Object *ob, - PBVHNode **nodes, - int totnode, PBVHNode **texnodes, int texnodes_num) { From 42f8f98ee12b2733554b58b7773dd163859b281a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 23 Jan 2023 15:06:55 -0600 Subject: [PATCH 0891/1522] Fix T104088: Geometry nodes modifier boolean lost on undo After object-mode undo (memfile undo), the value wan't lost, but the property would be temporarily converted back to integer type in order to be forward compatible. Now only use the forward compatible writing when writing undo steps. Auto-saves and similar files are currently not forward compatible anyway. --- source/blender/modifiers/intern/MOD_nodes.cc | 34 +++++++++++--------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index e487abc4248..a23156dd3c8 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1873,16 +1873,18 @@ static void blendWrite(BlendWriter *writer, const ID * /*id_owner*/, const Modif BLO_write_struct(writer, NodesModifierData, nmd); if (nmd->settings.properties != nullptr) { - /* Boolean properties are added automatically for boolean node group inputs. Integer properties - * are automatically converted to boolean sockets where applicable as well. However, boolean - * properties will crash old versions of Blender, so convert them to integer properties for - * writing. The actual value is stored in the same variable for both types */ Map boolean_props; - LISTBASE_FOREACH (IDProperty *, prop, &nmd->settings.properties->data.group) { - if (prop->type == IDP_BOOLEAN) { - boolean_props.add_new(prop, reinterpret_cast(prop->ui_data)); - prop->type = IDP_INT; - prop->ui_data = nullptr; + if (!BLO_write_is_undo(writer)) { + /* Boolean properties are added automatically for boolean node group inputs. Integer + * properties are automatically converted to boolean sockets where applicable as well. + * However, boolean properties will crash old versions of Blender, so convert them to integer + * properties for writing. The actual value is stored in the same variable for both types */ + LISTBASE_FOREACH (IDProperty *, prop, &nmd->settings.properties->data.group) { + if (prop->type == IDP_BOOLEAN) { + boolean_props.add_new(prop, reinterpret_cast(prop->ui_data)); + prop->type = IDP_INT; + prop->ui_data = nullptr; + } } } @@ -1890,12 +1892,14 @@ static void blendWrite(BlendWriter *writer, const ID * /*id_owner*/, const Modif * and don't necessarily need to be written, but we can't just free them. */ IDP_BlendWrite(writer, nmd->settings.properties); - LISTBASE_FOREACH (IDProperty *, prop, &nmd->settings.properties->data.group) { - if (prop->type == IDP_INT) { - if (IDPropertyUIDataBool **ui_data = boolean_props.lookup_ptr(prop)) { - prop->type = IDP_BOOLEAN; - if (ui_data) { - prop->ui_data = reinterpret_cast(*ui_data); + if (!BLO_write_is_undo(writer)) { + LISTBASE_FOREACH (IDProperty *, prop, &nmd->settings.properties->data.group) { + if (prop->type == IDP_INT) { + if (IDPropertyUIDataBool **ui_data = boolean_props.lookup_ptr(prop)) { + prop->type = IDP_BOOLEAN; + if (ui_data) { + prop->ui_data = reinterpret_cast(*ui_data); + } } } } From f72969f377a05741ded8f8bfa325d5980a58d1a6 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Mon, 23 Jan 2023 22:10:40 +0100 Subject: [PATCH 0892/1522] Fix T103888: Regression: Side-by-side stereo renders ignore color management Looks like rB42937493d8253a295a97092315288f961e8c6dba accidentally dropped the colorspace copy. --- source/blender/imbuf/intern/stereoimbuf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/imbuf/intern/stereoimbuf.c b/source/blender/imbuf/intern/stereoimbuf.c index eb2701b5b9c..0c064a3ccc3 100644 --- a/source/blender/imbuf/intern/stereoimbuf.c +++ b/source/blender/imbuf/intern/stereoimbuf.c @@ -765,9 +765,11 @@ ImBuf *IMB_stereo3d_ImBuf(const ImageFormatData *im_format, ImBuf *ibuf_left, Im if (is_float) { imb_addrectfloatImBuf(ibuf_stereo, ibuf_left->channels); + ibuf_stereo->float_colorspace = ibuf_left->float_colorspace; } else { imb_addrectImBuf(ibuf_stereo); + ibuf_stereo->rect_colorspace = ibuf_left->rect_colorspace; } ibuf_stereo->flags = ibuf_left->flags; From 0ad4d07f10e29f5a6678615ebe0453c679856f18 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Mon, 23 Jan 2023 15:57:13 -0600 Subject: [PATCH 0893/1522] Fix: Debug build compile error after recent cleanup commit 79ba1a1ac82d854d84 missed that this variable was used in an assert. --- source/blender/draw/engines/workbench/workbench_shadow.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/draw/engines/workbench/workbench_shadow.cc b/source/blender/draw/engines/workbench/workbench_shadow.cc index 533e32662a4..e4a409f1457 100644 --- a/source/blender/draw/engines/workbench/workbench_shadow.cc +++ b/source/blender/draw/engines/workbench/workbench_shadow.cc @@ -131,9 +131,12 @@ void ShadowPass::ShadowView::setup(View &view, float3 light_direction, bool forc float4 extruded_face = float4(UNPACK3(normal), math::dot(normal, corner_a)); /* Ensure the plane faces outwards */ + bool flipped = false; for (float3 corner : frustum_corners.vec) { if (math::dot(float3(extruded_face), corner) > (extruded_face.w + 0.1)) { BLI_assert(!flipped); + UNUSED_VARS_NDEBUG(flipped); + flipped = true; extruded_face *= -1; } } From 67c48314baa54011464de979b25126afcd28dec2 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 24 Jan 2023 15:33:47 +1100 Subject: [PATCH 0894/1522] Revert "Fix T71137: curve minimum twist producing wrong geometry" This reverts commit cf721942149057684c089c0677c224dbe9d90c52. --- source/blender/blenkernel/intern/curve.cc | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index 1ac0e27a4a3..a18cd2f6314 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -2257,21 +2257,17 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl) bevp1 = bevp2 + (bl->nr - 1); bevp0 = bevp1 - 1; - /* The ordinal of the point being adjusted (bevp2). First point is 1. */ + nr = bl->nr; + while (nr--) { - /* First point is the reference, don't adjust. - * Skip this point in the following loop. */ - if (bl->nr > 0) { - vec_to_quat(bevp2->quat, bevp2->dir, 5, 1); + if (nr + 3 > bl->nr) { /* first time and second time, otherwise first point adjusts last */ + vec_to_quat(bevp1->quat, bevp1->dir, 5, 1); + } + else { + minimum_twist_between_two_points(bevp1, bevp0); + } - bevp0 = bevp1; /* bevp0 is unused */ - bevp1 = bevp2; - bevp2++; - } - for (nr = 1; nr < bl->nr; nr++) { - minimum_twist_between_two_points(bevp2, bevp1); - - bevp0 = bevp1; /* bevp0 is unused */ + bevp0 = bevp1; bevp1 = bevp2; bevp2++; } From 36a82314a0f5de65b54f6d8343a2899ed4e37010 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 24 Jan 2023 16:28:22 +1100 Subject: [PATCH 0895/1522] Fix T71137: curve minimum twist producing wrong geometry Only one point should be used to create a reference rotation for other points to follow. Using two caused the resulting twist to be asymmetric, especially noticeable on symmetrical, cyclic curves. Alternate fix to D11886 which caused T101843. --- source/blender/blenkernel/intern/curve.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index a18cd2f6314..7fe8174d864 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -2260,7 +2260,7 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl) nr = bl->nr; while (nr--) { - if (nr + 3 > bl->nr) { /* first time and second time, otherwise first point adjusts last */ + if (nr + 1 >= bl->nr) { /* First time, otherwise first point adjusts last. */ vec_to_quat(bevp1->quat, bevp1->dir, 5, 1); } else { From 6279042d215eaf4b5b2b09df1224349980f48b21 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 24 Jan 2023 16:38:04 +1100 Subject: [PATCH 0896/1522] Cleanup: use const, doc-string for BevList.poly & rename args It wasn't clear that BevList.poly was used to check cyclic BevList's. --- source/blender/blenkernel/intern/curve.cc | 16 ++++++++-------- source/blender/makesdna/DNA_curve_types.h | 4 +++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index 7fe8174d864..51902169366 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -2063,7 +2063,7 @@ static void bevel_list_calc_bisect(BevList *bl) { BevPoint *bevp2, *bevp1, *bevp0; int nr; - bool is_cyclic = bl->poly != -1; + const bool is_cyclic = bl->poly != -1; if (is_cyclic) { bevp2 = bl->bevpoints; @@ -2229,19 +2229,19 @@ static void make_bevel_list_3D_zup(BevList *bl) } } -static void minimum_twist_between_two_points(BevPoint *current_point, BevPoint *previous_point) +static void minimum_twist_between_two_points(BevPoint *bevp_curr, const BevPoint *bevp_prev) { - float angle = angle_normalized_v3v3(previous_point->dir, current_point->dir); - float q[4]; + float angle = angle_normalized_v3v3(bevp_prev->dir, bevp_curr->dir); if (angle > 0.0f) { /* otherwise we can keep as is */ + float q[4]; float cross_tmp[3]; - cross_v3_v3v3(cross_tmp, previous_point->dir, current_point->dir); + cross_v3_v3v3(cross_tmp, bevp_prev->dir, bevp_curr->dir); axis_angle_to_quat(q, cross_tmp, angle); - mul_qt_qtqt(current_point->quat, q, previous_point->quat); + mul_qt_qtqt(bevp_curr->quat, q, bevp_prev->quat); } else { - copy_qt_qt(current_point->quat, previous_point->quat); + copy_qt_qt(bevp_curr->quat, bevp_prev->quat); } } @@ -2894,7 +2894,7 @@ void BKE_curve_bevelList_make(Object *ob, const ListBase *nurbs, const bool for_ /* Scale the threshold so high resolution shapes don't get over reduced, see: T49850. */ const float threshold_resolu = 0.00001f / resolu; - bool is_cyclic = bl->poly != -1; + const bool is_cyclic = bl->poly != -1; nr = bl->nr; if (is_cyclic) { bevp1 = bl->bevpoints; diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index d8fdcd4e6e5..2203f7778bc 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -47,7 +47,9 @@ typedef struct BevPoint { typedef struct BevList { struct BevList *next, *prev; int nr, dupe_nr; - int poly, hole; + /** Cyclic when set to any value besides -1. */ + int poly; + int hole; int charidx; int *segbevcount; float *seglen; From 1c90f8209d4191792267d4f7df821c0911afe2d7 Mon Sep 17 00:00:00 2001 From: Xavier Hallade Date: Mon, 23 Jan 2023 16:22:24 +0100 Subject: [PATCH 0897/1522] Cycles: fix rendering with Nishita Sky Texture on Intel Arc GPUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Speckles and missing lights were experienced in scenes with Nishita Sky Texture and a Sun Size smaller than 1.5°, such as in Lone Monk and Attic scenes. Increasing the precision of cosf fixes it. --- intern/cycles/kernel/device/oneapi/compat.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/intern/cycles/kernel/device/oneapi/compat.h b/intern/cycles/kernel/device/oneapi/compat.h index 0691c01b3b5..a43b68e5b49 100644 --- a/intern/cycles/kernel/device/oneapi/compat.h +++ b/intern/cycles/kernel/device/oneapi/compat.h @@ -195,7 +195,15 @@ using sycl::half; #define fmodf(x, y) sycl::fmod((x), (y)) #define lgammaf(x) sycl::lgamma((x)) -#define cosf(x) sycl::native::cos(((float)(x))) +/* sycl::native::cos precision is not sufficient and -ffast-math lets + * the current DPC++ compiler overload sycl::cos with it. + * We work around this issue by directly calling the spirv implementation which + * provides greater precision. */ +#if defined(__SYCL_DEVICE_ONLY__) && defined(__SPIR__) +# define cosf(x) __spirv_ocl_cos(((float)(x))) +#else +# define cosf(x) sycl::cos(((float)(x))) +#endif #define sinf(x) sycl::native::sin(((float)(x))) #define powf(x, y) sycl::native::powr(((float)(x)), ((float)(y))) #define tanf(x) sycl::native::tan(((float)(x))) From 74aa960398def266e2064504a70d47c7f5440097 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Tue, 24 Jan 2023 10:52:37 +0100 Subject: [PATCH 0898/1522] Cleanup: add newline in Collada error message --- source/blender/io/collada/Materials.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/io/collada/Materials.cpp b/source/blender/io/collada/Materials.cpp index 997da31b939..cf63722c369 100644 --- a/source/blender/io/collada/Materials.cpp +++ b/source/blender/io/collada/Materials.cpp @@ -161,7 +161,7 @@ void MaterialNode::set_ior(COLLADAFW::FloatOrParam &val) if (ior < 0) { fprintf(stderr, "IOR of negative value is not allowed for materials (using Blender default value " - "instead)"); + "instead)\n"); return; } From a36e2a9b649eef7b21541bb397555b7d6eb6bd6d Mon Sep 17 00:00:00 2001 From: Amelie Fondevilla Date: Tue, 24 Jan 2023 11:57:49 +0100 Subject: [PATCH 0899/1522] Gpencil: Expose stroke and point time properties to API Two properties are now exposed in python API : time of each point, and inittime of each stroke. Reviewed by: Antonio Vazquez Differential Revision: https://developer.blender.org/D17104 --- source/blender/makesrna/intern/rna_gpencil.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index a9dc4f4dc12..544a7f73cab 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -1275,6 +1275,11 @@ static void rna_def_gpencil_stroke_point(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Select", "Point is selected for viewport editing"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + prop = RNA_def_property(srna, "time", PROP_FLOAT, PROP_TIME); + RNA_def_property_float_sdna(prop, NULL, "time"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Time", "Time relative to stroke start"); + /* Vertex color. */ prop = RNA_def_property(srna, "vertex_color", PROP_FLOAT, PROP_COLOR); RNA_def_property_float_sdna(prop, NULL, "vert_color"); @@ -1748,6 +1753,12 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna) prop = RNA_def_property(srna, "select_index", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "select_index"); RNA_def_property_ui_text(prop, "Select Index", "Index of selection used for interpolation"); + + /* Init time */ + prop = RNA_def_property(srna, "init_time", PROP_FLOAT, PROP_TIME); + RNA_def_property_float_sdna(prop, NULL, "inittime"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Init Time", "Initial time of the stroke"); } static void rna_def_gpencil_strokes_api(BlenderRNA *brna, PropertyRNA *cprop) From c16bd343168d72d9fea2c440d91565d7701b1cea Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 24 Jan 2023 13:07:54 +0100 Subject: [PATCH 0900/1522] Fix: memory allocation before guarded allocator is initialized Use the construct-on-first-use idiom to fix this. --- .../workbench/workbench_effect_antialiasing.cc | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.cc b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.cc index 6b0b2e75c27..75be8279037 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.cc +++ b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.cc @@ -74,7 +74,11 @@ class TaaSamples { } }; -static TaaSamples TAA_SAMPLES = TaaSamples(); +static const TaaSamples &get_taa_samples() +{ + static const TaaSamples taa_samples; + return taa_samples; +} static float filter_blackman_harris(float x, const float width) { @@ -195,23 +199,25 @@ void AntiAliasingPass::setup_view(View &view, int2 resolution) return; } + const TaaSamples &taa_samples = get_taa_samples(); + float2 sample_offset; switch (samples_len_) { default: case 5: - sample_offset = TAA_SAMPLES.x5[sample_]; + sample_offset = taa_samples.x5[sample_]; break; case 8: - sample_offset = TAA_SAMPLES.x8[sample_]; + sample_offset = taa_samples.x8[sample_]; break; case 11: - sample_offset = TAA_SAMPLES.x11[sample_]; + sample_offset = taa_samples.x11[sample_]; break; case 16: - sample_offset = TAA_SAMPLES.x16[sample_]; + sample_offset = taa_samples.x16[sample_]; break; case 32: - sample_offset = TAA_SAMPLES.x32[sample_]; + sample_offset = taa_samples.x32[sample_]; break; } From cf332e896fa86a13642a150f7e04419b60761c1e Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Tue, 24 Jan 2023 13:19:08 +0100 Subject: [PATCH 0901/1522] GPencil: Fix unreported double rotation in Fill circles The help circles to fill areas were rotated with the object rotation, but as the stroke is part of the object, apply the rot matrix again produced a double rotation, so it can be removed. --- source/blender/editors/gpencil/gpencil_fill.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 6b1f5ba1ad0..8a7e1c03e66 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -314,11 +314,6 @@ static void add_endpoint_radius_help(tGPDfill *tgpf, pt->z = endpoint[2] + radius * sinf(angle); pt->strength = 1.0f; pt->pressure = 1.0f; - - /* Rotate to object rotation. */ - sub_v3_v3(&pt->x, endpoint); - mul_mat3_m4_v3(tgpf->ob->object_to_world, &pt->x); - add_v3_v3(&pt->x, endpoint); } } From 33edef15ed405281debe6bc81ae822daff25bbf4 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 24 Jan 2023 14:06:43 +0100 Subject: [PATCH 0902/1522] Fix T104095: missing crazy space data while sculpting curves `remember_deformed_curve_positions_if_necessary` has to be called before topology changing operations on curves. Otherwise the crazy-space data is invalid. --- source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc | 4 ++++ .../nodes/geometry/nodes/node_geo_realize_instances.cc | 1 + 2 files changed, 5 insertions(+) diff --git a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc index d49f2583bde..18a662289aa 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_join_geometry.cc @@ -192,6 +192,10 @@ static void node_geo_exec(GeoNodeExecParams params) const AnonymousAttributePropagationInfo &propagation_info = params.get_output_propagation_info( "Geometry"); + for (GeometrySet &geometry : geometry_sets) { + GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry); + } + GeometrySet geometry_set_result; join_component_type(geometry_sets, geometry_set_result, propagation_info); join_component_type(geometry_sets, geometry_set_result, propagation_info); diff --git a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc index 385b47a2f1e..18311e9ca58 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_realize_instances.cc @@ -34,6 +34,7 @@ static void node_geo_exec(GeoNodeExecParams params) } GeometrySet geometry_set = params.extract_input("Geometry"); + GeometryComponentEditData::remember_deformed_curve_positions_if_necessary(geometry_set); geometry::RealizeInstancesOptions options; options.keep_original_ids = legacy_behavior; options.realize_instance_attributes = !legacy_behavior; From 246485b213fa5cdab17f2dd4f9b307070080df0c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jan 2023 00:21:11 +1100 Subject: [PATCH 0903/1522] BLI_path: make BLI_path_slash_is_native_compat into a public function --- source/blender/blenlib/BLI_path_util.h | 18 +++++++++++ source/blender/blenlib/intern/path_util.c | 39 +++++++---------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index 4ea059391b6..78f8e529740 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -516,6 +516,24 @@ int BLI_path_cmp_normalized(const char *p1, const char *p2) # define ALTSEP_STR "\\" #endif +/** + * Return true if the slash can be used as a separator on this platform. + */ +BLI_INLINE bool BLI_path_slash_is_native_compat(const char ch) +{ + /* On UNIX it only makes sense to treat `/` as a path separator. + * On WIN32 either may be used. */ + if (ch == SEP) { + return true; + } +#ifdef WIN32 + if (ch == ALTSEP) { + return true; + } +#endif + return false; +} + /* Parent and current dir helpers. */ #define FILENAME_PARENT ".." #define FILENAME_CURRENT "." diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index cba2377161a..a985e18cff5 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -51,23 +51,6 @@ static bool BLI_path_is_abs(const char *name); // #define DEBUG_STRSIZE -/** - * On UNIX it only makes sense to treat `/` as a path separator. - * On WIN32 either may be used. - */ -static bool is_sep_native_compat(const char ch) -{ - if (ch == SEP) { - return true; - } -#ifdef WIN32 - if (ch == ALTSEP) { - return true; - } -#endif - return false; -} - /* implementation */ int BLI_path_sequence_decode(const char *string, char *head, char *tail, ushort *r_digits_len) @@ -1467,7 +1450,7 @@ size_t BLI_path_append(char *__restrict dst, const size_t maxlen, const char *__ size_t dirlen = BLI_strnlen(dst, maxlen); /* Inline #BLI_path_slash_ensure. */ - if ((dirlen > 0) && !is_sep_native_compat(dst[dirlen - 1])) { + if ((dirlen > 0) && !BLI_path_slash_is_native_compat(dst[dirlen - 1])) { dst[dirlen++] = SEP; dst[dirlen] = '\0'; } @@ -1484,7 +1467,7 @@ size_t BLI_path_append_dir(char *__restrict dst, const size_t maxlen, const char size_t dirlen = BLI_path_append(dst, maxlen, dir); if (dirlen + 1 < maxlen) { /* Inline #BLI_path_slash_ensure. */ - if ((dirlen > 0) && !is_sep_native_compat(dst[dirlen - 1])) { + if ((dirlen > 0) && !BLI_path_slash_is_native_compat(dst[dirlen - 1])) { dst[dirlen++] = SEP; dst[dirlen] = '\0'; } @@ -1539,7 +1522,7 @@ size_t BLI_path_join_array(char *__restrict dst, bool has_trailing_slash = false; if (ofs != 0) { size_t len = ofs; - while ((len != 0) && is_sep_native_compat(path[len - 1])) { + while ((len != 0) && BLI_path_slash_is_native_compat(path[len - 1])) { len -= 1; } @@ -1553,18 +1536,18 @@ size_t BLI_path_join_array(char *__restrict dst, path = path_array[path_index]; has_trailing_slash = false; const char *path_init = path; - while (is_sep_native_compat(path[0])) { + while (BLI_path_slash_is_native_compat(path[0])) { path++; } size_t len = strlen(path); if (len != 0) { - while ((len != 0) && is_sep_native_compat(path[len - 1])) { + while ((len != 0) && BLI_path_slash_is_native_compat(path[len - 1])) { len -= 1; } if (len != 0) { /* the very first path may have a slash at the end */ - if (ofs && !is_sep_native_compat(dst[ofs - 1])) { + if (ofs && !BLI_path_slash_is_native_compat(dst[ofs - 1])) { dst[ofs++] = SEP; if (ofs == dst_last) { break; @@ -1587,7 +1570,7 @@ size_t BLI_path_join_array(char *__restrict dst, } if (has_trailing_slash) { - if ((ofs != dst_last) && (ofs != 0) && !is_sep_native_compat(dst[ofs - 1])) { + if ((ofs != dst_last) && (ofs != 0) && !BLI_path_slash_is_native_compat(dst[ofs - 1])) { dst[ofs++] = SEP; } } @@ -1615,7 +1598,7 @@ static bool path_name_at_index_forward(const char *__restrict path, int i = 0; while (true) { const char c = path[i]; - if ((c == '\0') || is_sep_native_compat(c)) { + if ((c == '\0') || BLI_path_slash_is_native_compat(c)) { if (prev + 1 != i) { prev += 1; /* Skip '/./' (behave as if they don't exist). */ @@ -1650,7 +1633,7 @@ static bool path_name_at_index_backward(const char *__restrict path, int i = prev - 1; while (true) { const char c = i >= 0 ? path[i] : '\0'; - if ((c == '\0') || is_sep_native_compat(c)) { + if ((c == '\0') || BLI_path_slash_is_native_compat(c)) { if (prev - 1 != i) { i += 1; /* Skip '/./' (behave as if they don't exist). */ @@ -1749,7 +1732,7 @@ int BLI_path_slash_ensure(char *string, size_t string_maxlen) { int len = strlen(string); BLI_assert(len < string_maxlen); - if (len == 0 || !is_sep_native_compat(string[len - 1])) { + if (len == 0 || !BLI_path_slash_is_native_compat(string[len - 1])) { /* Avoid unlikely buffer overflow. */ if (len + 1 < string_maxlen) { string[len] = SEP; @@ -1764,7 +1747,7 @@ void BLI_path_slash_rstrip(char *string) { int len = strlen(string); while (len) { - if (is_sep_native_compat(string[len - 1])) { + if (BLI_path_slash_is_native_compat(string[len - 1])) { string[len - 1] = '\0'; len--; } From 4815d0706fb57d6e4f897dbb4e9aba9d2323cdce Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jan 2023 00:21:13 +1100 Subject: [PATCH 0904/1522] Fix T103385: Asset Browser Thumbnails take long time to load Regression in [0] caused by a change where path joining would replace a forward slash with a back-slash when joining paths WIN32. Now the directory is always used as a prefix for the paths returned by BLI_filelist_dir_contents which resolves the regression. [0]: 9f6a045e23cf4ab132ef78eeaf070bd53d0c509f --- source/blender/blenlib/intern/BLI_filelist.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c index 4bcb023691a..06fb57842e0 100644 --- a/source/blender/blenlib/intern/BLI_filelist.c +++ b/source/blender/blenlib/intern/BLI_filelist.c @@ -114,6 +114,16 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) const struct dirent *fname; bool has_current = false, has_parent = false; + char dirname_with_slash[FILE_MAXDIR + 1]; + size_t dirname_with_slash_len = BLI_strncpy_rlen( + dirname_with_slash, dirname, sizeof(dirname_with_slash) - 1); + + if ((dirname_with_slash_len > 0) && + (BLI_path_slash_is_native_compat(dirname_with_slash_len - 1) == false)) { + dirname_with_slash[dirname_with_slash_len++] = SEP; + dirname_with_slash[dirname_with_slash_len] = '\0'; + } + while ((fname = readdir(dir)) != NULL) { struct dirlink *const dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); if (dlink != NULL) { @@ -172,9 +182,14 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) if (dir_ctx->files) { struct dirlink *dlink = (struct dirlink *)dirbase.first; struct direntry *file = &dir_ctx->files[dir_ctx->files_num]; + + char fullname[PATH_MAX]; + STRNCPY(fullname, dirname_with_slash); + char *fullname_name_part = fullname + dirname_with_slash_len; + const size_t fullname_name_part_len = sizeof(fullname) - dirname_with_slash_len; + while (dlink) { - char fullname[PATH_MAX]; - BLI_path_join(fullname, sizeof(fullname), dirname, dlink->name); + BLI_strncpy(fullname_name_part, dlink->name, fullname_name_part_len); memset(file, 0, sizeof(struct direntry)); file->relname = dlink->name; file->path = BLI_strdup(fullname); From 21eff2c0ac214215c9c404cea6a8ffbfb2608c59 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 24 Jan 2023 15:03:21 +0100 Subject: [PATCH 0905/1522] 3DTexturing: Improve fix seam bleeding for manifold parts of mesh. Current implementation had some faulty assumtions and had some work arounds for crashes that were actually limitation of the implementation. The main reason for this was that the implementation didn't add new primitives in the same direction it was already adding. Some when incorrect behavior was detected it was assumed that the part wasn't manifold (anymore) and didn't fix that part of the mesh. The new implementation will extract a solution and use this solution also as the order to generate primitives in uv space. This patch fixes several crashes and improves the overall quality when fixing seam bleeding. It also adds additional debug tools (print_debug) implementation in order to find issues faster in the future. --- .../blenkernel/intern/pbvh_uv_islands.cc | 386 ++++++++++++------ .../blenkernel/intern/pbvh_uv_islands.hh | 9 + 2 files changed, 271 insertions(+), 124 deletions(-) diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index 16091b32917..b94b50c5210 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -80,17 +80,6 @@ static int get_uv_loop(const MeshData &mesh_data, const MLoopTri &looptri, const return looptri.tri[0]; } -static bool has_vertex(const MeshData &mesh_data, const MLoopTri &looptri, const int vert) -{ - for (int i = 0; i < 3; i++) { - const int vert_i = mesh_data.loops[looptri.tri[i]].v; - if (vert_i == vert) { - return true; - } - } - return false; -} - static rctf primitive_uv_bounds(const MLoopTri &looptri, const Span uv_map) { rctf result; @@ -247,6 +236,21 @@ UVVertex::UVVertex(const MeshData &mesh_data, const int loop) uv_vertex_init_flags(*this); } +/** + * Get a list containing the indices of mesh primitives (primitive of the input mesh), that + * surround the given uv_vertex in uv-space. + */ +static Vector connecting_mesh_primitive_indices(const UVVertex &uv_vertex) +{ + Vector primitives_around_uv_vertex; + for (const UVEdge *uv_edge : uv_vertex.uv_edges) { + for (const UVPrimitive *uv_primitive : uv_edge->uv_primitives) { + primitives_around_uv_vertex.append_non_duplicates(uv_primitive->primitive_i); + } + } + return primitives_around_uv_vertex; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -496,7 +500,9 @@ static std::optional sharpest_border_corner(UVIsland &island) } /** The inner edge of a fan. */ +/* TODO: InnerEdge name is incorrect as it links to an edge and primitive. */ struct InnerEdge { + const int primitive_index; const MLoopTri *primitive; /* UVs order are already applied. So `uvs[0]` matches `primitive->vertices[vert_order[0]]`. */ float2 uvs[3]; @@ -506,8 +512,11 @@ struct InnerEdge { bool found : 1; } flags; - InnerEdge(const MeshData &mesh_data, const MLoopTri *primitive, int vertex) - : primitive(primitive) + InnerEdge(const MeshData &mesh_data, + const int primitive_index, + const MLoopTri *primitive, + int vertex) + : primitive_index(primitive_index), primitive(primitive) { flags.found = false; @@ -529,6 +538,23 @@ struct InnerEdge { vert_order[2] = 2; } } + + void print_debug(const MeshData &mesh_data) const + { + std::stringstream ss; + ss << "# p:" << primitive->poly; + ss << " v1:" << mesh_data.loops[primitive->tri[vert_order[0]]].v; + ss << " v2:" << mesh_data.loops[primitive->tri[vert_order[1]]].v; + ss << " v3:" << mesh_data.loops[primitive->tri[vert_order[2]]].v; + ss << " uv1:" << uvs[0]; + ss << " uv2:" << uvs[1]; + ss << " uv3:" << uvs[2]; + if (flags.found) { + ss << " *found"; + } + ss << "\n"; + std::cout << ss.str(); + } }; struct Fan { @@ -567,7 +593,7 @@ struct Fan { if (edge_i == current_edge || (edge.vert1 != vertex && edge.vert2 != vertex)) { continue; } - inner_edges.append(InnerEdge(mesh_data, &other_looptri, vertex)); + inner_edges.append(InnerEdge(mesh_data, other_primitive_i, &other_looptri, vertex)); current_edge = edge_i; previous_primitive = other_primitive_i; stop = true; @@ -584,7 +610,7 @@ struct Fan { } } - int count_num_to_add() const + int count_edges_not_added() const { int result = 0; for (const InnerEdge &fan_edge : inner_edges) { @@ -597,18 +623,11 @@ struct Fan { void mark_already_added_segments(const MeshData &mesh_data, const UVVertex &uv_vertex) { + Vector mesh_primitive_indices = connecting_mesh_primitive_indices(uv_vertex); + + /* Go over all fan edges to find if they can be found as primitive around the uv vertex. */ for (InnerEdge &fan_edge : inner_edges) { - fan_edge.flags.found = false; - const int v0 = mesh_data.loops[fan_edge.primitive->tri[fan_edge.vert_order[0]]].v; - const int v1 = mesh_data.loops[fan_edge.primitive->tri[fan_edge.vert_order[1]]].v; - for (const UVEdge *edge : uv_vertex.uv_edges) { - const int e0 = edge->vertices[0]->vertex; - const int e1 = edge->vertices[1]->vertex; - if ((e0 == v0 && e1 == v1) || (e0 == v1 && e1 == v0)) { - fan_edge.flags.found = true; - break; - } - } + fan_edge.flags.found = mesh_primitive_indices.contains(fan_edge.primitive_index); } } @@ -636,6 +655,150 @@ struct Fan { inner_edges[i].uvs[2] = inner_edges[i + 1].uvs[1]; } } + +#ifndef NDEBUG + /** + * Check if the given vertex is part of the outside of the fan. + * Return true if the given vertex is found on the outside of the fan, otherwise returns false. + */ + bool contains_vertex_on_outside(const MeshData &mesh_data, const int vertex_index) const + { + for (const InnerEdge &inner_edge : inner_edges) { + int v2 = mesh_data.loops[inner_edge.primitive->tri[inner_edge.vert_order[1]]].v; + if (vertex_index == v2) { + return true; + } + } + return false; + } + +#endif + + static bool is_path_valid(const Span &path, + const MeshData &mesh_data, + const int from_vertex, + const int to_vertex) + { + int current_vert = from_vertex; + for (InnerEdge *inner_edge : path) { + int v1 = mesh_data.loops[inner_edge->primitive->tri[inner_edge->vert_order[1]]].v; + int v2 = mesh_data.loops[inner_edge->primitive->tri[inner_edge->vert_order[2]]].v; + if (!ELEM(current_vert, v1, v2)) { + return false; + } + current_vert = v1 == current_vert ? v2 : v1; + } + return current_vert == to_vertex; + } + + /** + * Find the closest path over the fan between `from_vertex` and `to_vertex`. The result contains + * exclude the starting and final edge. + * + * Algorithm only uses the winding order of the given fan segments. + */ + static Vector path_between(const Span edge_order, + const MeshData &mesh_data, + const int from_vertex, + const int to_vertex, + const bool reversed) + { + const int from_vert_order = 1; + const int to_vert_order = 2; + const int index_increment = reversed ? -1 : 1; + + Vector result; + result.reserve(edge_order.size()); + int index = 0; + while (true) { + InnerEdge *inner_edge = edge_order[index]; + int v2 = + mesh_data.loops[inner_edge->primitive->tri[inner_edge->vert_order[from_vert_order]]].v; + if (v2 == from_vertex) { + break; + } + index = (index + index_increment + edge_order.size()) % edge_order.size(); + } + + while (true) { + InnerEdge *inner_edge = edge_order[index]; + result.append(inner_edge); + + int v3 = + mesh_data.loops[inner_edge->primitive->tri[inner_edge->vert_order[to_vert_order]]].v; + if (v3 == to_vertex) { + break; + } + + index = (index + index_increment + edge_order.size()) % edge_order.size(); + } + + return result; + } + + /** + * Score the given solution to be the best. Best solution would have the lowest score. + * + * Score is determined by counting the number of steps and subtracting that with steps that have + * not yet been visited. + */ + static int64_t score(const Span solution) + { + int64_t not_visited_steps = 0; + for (InnerEdge *inner_edge : solution) { + if (!inner_edge->flags.found) { + not_visited_steps++; + } + } + return solution.size() - not_visited_steps; + } + + Vector best_path_between(const MeshData &mesh_data, + const int from_vertex, + const int to_vertex) + { + BLI_assert_msg(contains_vertex_on_outside(mesh_data, from_vertex), + "Inconsistency detected, `from_vertex` isn't part of the outside of the fan."); + BLI_assert_msg(contains_vertex_on_outside(mesh_data, to_vertex), + "Inconsistency detected, `to_vertex` isn't part of the outside of the fan."); + if (to_vertex == from_vertex) { + return Vector(); + } + + Array edges(inner_edges.size()); + for (int64_t index : inner_edges.index_range()) { + edges[index] = &inner_edges[index]; + } + + Vector winding_1 = path_between(edges, mesh_data, from_vertex, to_vertex, false); + Vector winding_2 = path_between(edges, mesh_data, from_vertex, to_vertex, true); + + bool winding_1_valid = is_path_valid(winding_1, mesh_data, from_vertex, to_vertex); + bool winding_2_valid = is_path_valid(winding_2, mesh_data, from_vertex, to_vertex); + + if (winding_1_valid && !winding_2_valid) { + return winding_1; + } + if (!winding_1_valid && winding_2_valid) { + return winding_2; + } + if (!winding_1_valid && !winding_2_valid) { + BLI_assert_msg(false, "Both solutions aren't valid."); + return Vector(); + } + if (score(winding_1) < score(winding_2)) { + return winding_1; + } + return winding_2; + } + + void print_debug(const MeshData &mesh_data) const + { + for (const InnerEdge &inner_edge : inner_edges) { + inner_edge.print_debug(mesh_data); + } + std::cout << "\n"; + } }; static void add_uv_primitive_shared_uv_edge(const MeshData &mesh_data, @@ -679,25 +842,11 @@ static void add_uv_primitive_shared_uv_edge(const MeshData &mesh_data, uv_primitive_append_to_uv_vertices(prim1); island.uv_primitives.append(prim1); } - -static int find_fill_border(const MeshData &mesh_data, const int v1, const int v2, const int v3) -{ - for (const int edge_i : mesh_data.vert_to_edge_map[v1]) { - for (const int primitive_i : mesh_data.edge_to_primitive_map[edge_i]) { - const MLoopTri &looptri = mesh_data.looptris[primitive_i]; - if (has_vertex(mesh_data, looptri, v1) && has_vertex(mesh_data, looptri, v2) && - has_vertex(mesh_data, looptri, v3)) { - return primitive_i; - } - } - } - return -1; -} /** * Find a primitive that can be used to fill give corner. * Will return -1 when no primitive can be found. */ -static int find_fill_border(const MeshData &mesh_data, UVBorderCorner &corner) +static int find_fill_primitive(const MeshData &mesh_data, UVBorderCorner &corner) { if (corner.first->get_uv_vertex(1) != corner.second->get_uv_vertex(0)) { return -1; @@ -749,8 +898,12 @@ static void extend_at_vert(const MeshData &mesh_data, UVBorderCorner &corner, float min_uv_distance) { + int border_index = corner.first->border_index; UVBorder &border = island.borders[border_index]; + if (!corner.connected_in_mesh()) { + return; + } UVVertex *uv_vertex = corner.second->get_uv_vertex(0); Fan fan(mesh_data, uv_vertex->vertex); @@ -759,19 +912,31 @@ static void extend_at_vert(const MeshData &mesh_data, } fan.init_uv_coordinates(mesh_data, *uv_vertex); fan.mark_already_added_segments(mesh_data, *uv_vertex); - int num_to_add = fan.count_num_to_add(); + int num_to_add = fan.count_edges_not_added(); - if (num_to_add == 0) { + /* In 3d space everything can connected, but in uv space it may not. + * in this case in the space between we should extract the primitives to be added + * from the fan. */ + Vector winding_solution = fan.best_path_between( + mesh_data, corner.first->get_uv_vertex(0)->vertex, corner.second->get_uv_vertex(1)->vertex); + + /* + * When all edges are already added and its winding solution contains one segment to be added, + * the segment should be split into two segments in order one for both sides. + * + * Although the fill_primitive can fill the missing segment it could lead to a squashed + * triangle when the corner angle is near 180 degrees. In order to fix this we will + * always add two segments both using the same fill primitive. + */ + if ((num_to_add == 0 && winding_solution.size() == 1) || + (corner.angle > 1.0f && winding_solution.size() < 2)) { int fill_primitive_1_i = corner.second->uv_primitive->primitive_i; int fill_primitive_2_i = corner.first->uv_primitive->primitive_i; - const int fill_primitive_i = find_fill_border(mesh_data, corner); + const int fill_primitive_i = winding_solution.size() == 1 ? + winding_solution[0]->primitive_index : + find_fill_primitive(mesh_data, corner); - /* - * Although the fill_primitive can fill the missing segment it could lead to a squashed - * triangle when the corner angle is near 180 degrees. In order to fix this we will - * always add two segments both using the same fill primitive. - */ if (fill_primitive_i != -1) { fill_primitive_1_i = fill_primitive_i; fill_primitive_2_i = fill_primitive_i; @@ -811,91 +976,42 @@ static void extend_at_vert(const MeshData &mesh_data, } else { UVEdge *current_edge = corner.first->edge; - Vector new_border_edges; - for (int i = 0; i < num_to_add; i++) { + num_to_add = winding_solution.size(); + for (int64_t segment_index : winding_solution.index_range()) { + float2 old_uv = current_edge->get_other_uv_vertex(uv_vertex->vertex)->uv; int shared_edge_vertex = current_edge->get_other_uv_vertex(uv_vertex->vertex)->vertex; - float factor = (i + 1.0f) / (num_to_add + 1.0f); + float factor = (segment_index + 1.0f) / num_to_add; float2 new_uv = corner.uv(factor, min_uv_distance); - /* Find an segment that contains the 'current edge'. */ - for (InnerEdge &segment : fan.inner_edges) { - if (segment.flags.found) { - continue; - } + InnerEdge &segment = *winding_solution[segment_index]; - /* Find primitive that shares the current edge and the segment edge. */ - const int fill_primitive_i = find_fill_border( - mesh_data, - uv_vertex->vertex, - shared_edge_vertex, - mesh_data.loops[segment.primitive->tri[segment.vert_order[1]]].v); - if (fill_primitive_i == -1) { - continue; - } - const MLoopTri &fill_primitive = mesh_data.looptris[fill_primitive_i]; - const int other_prim_vertex = primitive_get_other_uv_vertex( - mesh_data, fill_primitive, uv_vertex->vertex, shared_edge_vertex); + const int fill_primitive_i = segment.primitive_index; + const MLoopTri &fill_primitive = mesh_data.looptris[fill_primitive_i]; + const int other_prim_vertex = primitive_get_other_uv_vertex( + mesh_data, fill_primitive, uv_vertex->vertex, shared_edge_vertex); - UVVertex uv_vertex_template; - uv_vertex_template.vertex = uv_vertex->vertex; - uv_vertex_template.uv = uv_vertex->uv; - UVVertex *vertex_1_ptr = island.lookup_or_create(uv_vertex_template); - uv_vertex_template.vertex = shared_edge_vertex; - uv_vertex_template.uv = old_uv; - UVVertex *vertex_2_ptr = island.lookup_or_create(uv_vertex_template); - uv_vertex_template.vertex = other_prim_vertex; - uv_vertex_template.uv = new_uv; - UVVertex *vertex_3_ptr = island.lookup_or_create(uv_vertex_template); + UVVertex uv_vertex_template; + uv_vertex_template.vertex = uv_vertex->vertex; + uv_vertex_template.uv = uv_vertex->uv; + UVVertex *vertex_1_ptr = island.lookup_or_create(uv_vertex_template); + uv_vertex_template.vertex = shared_edge_vertex; + uv_vertex_template.uv = old_uv; + UVVertex *vertex_2_ptr = island.lookup_or_create(uv_vertex_template); + uv_vertex_template.vertex = other_prim_vertex; + uv_vertex_template.uv = new_uv; + UVVertex *vertex_3_ptr = island.lookup_or_create(uv_vertex_template); - add_uv_primitive_fill( - island, *vertex_1_ptr, *vertex_2_ptr, *vertex_3_ptr, fill_primitive_i); + add_uv_primitive_fill(island, *vertex_1_ptr, *vertex_2_ptr, *vertex_3_ptr, fill_primitive_i); - segment.flags.found = true; - - UVPrimitive &new_prim = island.uv_primitives.last(); - current_edge = new_prim.get_uv_edge(uv_vertex->vertex, other_prim_vertex); - UVBorderEdge new_border(new_prim.get_uv_edge(shared_edge_vertex, other_prim_vertex), - &new_prim); - new_border_edges.append(new_border); - break; - } - } - - { - /* Add final segment. */ - float2 old_uv = current_edge->get_other_uv_vertex(uv_vertex->vertex)->uv; - int shared_edge_vertex = current_edge->get_other_uv_vertex(uv_vertex->vertex)->vertex; - const int fill_primitive_i = find_fill_border(mesh_data, - uv_vertex->vertex, - shared_edge_vertex, - corner.second->get_uv_vertex(1)->vertex); - if (fill_primitive_i != -1) { - const MLoopTri &fill_primitive = mesh_data.looptris[fill_primitive_i]; - const int other_prim_vertex = primitive_get_other_uv_vertex( - mesh_data, fill_primitive, uv_vertex->vertex, shared_edge_vertex); - - UVVertex uv_vertex_template; - uv_vertex_template.vertex = uv_vertex->vertex; - uv_vertex_template.uv = uv_vertex->uv; - UVVertex *vertex_1_ptr = island.lookup_or_create(uv_vertex_template); - uv_vertex_template.vertex = shared_edge_vertex; - uv_vertex_template.uv = old_uv; - UVVertex *vertex_2_ptr = island.lookup_or_create(uv_vertex_template); - uv_vertex_template.vertex = other_prim_vertex; - uv_vertex_template.uv = corner.second->get_uv_vertex(1)->uv; - UVVertex *vertex_3_ptr = island.lookup_or_create(uv_vertex_template); - add_uv_primitive_fill( - island, *vertex_1_ptr, *vertex_2_ptr, *vertex_3_ptr, fill_primitive_i); - - UVPrimitive &new_prim = island.uv_primitives.last(); - UVBorderEdge new_border(new_prim.get_uv_edge(shared_edge_vertex, other_prim_vertex), - &new_prim); - new_border_edges.append(new_border); - } + UVPrimitive &new_prim = island.uv_primitives.last(); + current_edge = new_prim.get_uv_edge(uv_vertex->vertex, other_prim_vertex); + UVBorderEdge new_border(new_prim.get_uv_edge(shared_edge_vertex, other_prim_vertex), + &new_prim); + new_border_edges.append(new_border); } int border_insert = corner.first->index; @@ -943,7 +1059,6 @@ void UVIsland::extend_border(const MeshData &mesh_data, for (UVBorder &border : borders) { border.update_indexes(border_index++); } - while (true) { std::optional extension_corner = sharpest_border_corner(*this); if (!extension_corner.has_value()) { @@ -1145,6 +1260,29 @@ float2 UVBorderCorner::uv(float factor, float min_uv_distance) return result; } +bool UVBorderCorner::connected_in_mesh() const +{ + return first->get_uv_vertex(1) == second->get_uv_vertex(0); +} + +void UVBorderCorner::print_debug() const +{ + std::stringstream ss; + ss << "# "; + if (connected_in_mesh()) { + ss << first->get_uv_vertex(0)->vertex << "-"; + ss << first->get_uv_vertex(1)->vertex << "-"; + ss << second->get_uv_vertex(1)->vertex << "\n"; + } + else { + ss << first->get_uv_vertex(0)->vertex << "-"; + ss << first->get_uv_vertex(1)->vertex << ", "; + ss << second->get_uv_vertex(0)->vertex << "-"; + ss << second->get_uv_vertex(1)->vertex << "\n"; + } + std::cout << ss.str(); +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.hh b/source/blender/blenkernel/intern/pbvh_uv_islands.hh index c1a0a4da5d8..b292c85bb01 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.hh +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.hh @@ -250,6 +250,15 @@ struct UVBorderCorner { * resulting uv coordinate. The distance is in uv space. */ float2 uv(float factor, float min_uv_distance); + + /** + * Does this corner exist as 2 connected edges of the mesh. + * + * During the extraction phase a connection can be made in uv-space that + * doesn't reflect to two connected edges inside the mesh. + */ + bool connected_in_mesh() const; + void print_debug() const; }; struct UVBorder { From 10a06dfd1173dfbd4b094773b772a7265053173b Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 24 Jan 2023 15:12:21 +0100 Subject: [PATCH 0906/1522] Code-style: Rename internal parts of pbvh_uv_islands. - InnerEdge -> FanSegment - full -> is_manifold --- .../blenkernel/intern/pbvh_uv_islands.cc | 105 +++++++++--------- 1 file changed, 51 insertions(+), 54 deletions(-) diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index b94b50c5210..9b6ad72bfa8 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -500,8 +500,7 @@ static std::optional sharpest_border_corner(UVIsland &island) } /** The inner edge of a fan. */ -/* TODO: InnerEdge name is incorrect as it links to an edge and primitive. */ -struct InnerEdge { +struct FanSegment { const int primitive_index; const MLoopTri *primitive; /* UVs order are already applied. So `uvs[0]` matches `primitive->vertices[vert_order[0]]`. */ @@ -512,10 +511,10 @@ struct InnerEdge { bool found : 1; } flags; - InnerEdge(const MeshData &mesh_data, - const int primitive_index, - const MLoopTri *primitive, - int vertex) + FanSegment(const MeshData &mesh_data, + const int primitive_index, + const MLoopTri *primitive, + int vertex) : primitive_index(primitive_index), primitive(primitive) { flags.found = false; @@ -559,20 +558,20 @@ struct InnerEdge { struct Fan { /* Blades of the fan. */ - Vector inner_edges; + Vector segments; struct { /** * Do all segments of the fan make a full fan, or are there parts missing. Non manifold meshes * can have missing parts. */ - bool full : 1; + bool is_manifold : 1; } flags; Fan(const MeshData &mesh_data, const int vertex) { - flags.full = true; + flags.is_manifold = true; int current_edge = mesh_data.vert_to_edge_map[vertex].first(); const int stop_primitive = mesh_data.edge_to_primitive_map[current_edge].first(); int previous_primitive = stop_primitive; @@ -593,7 +592,7 @@ struct Fan { if (edge_i == current_edge || (edge.vert1 != vertex && edge.vert2 != vertex)) { continue; } - inner_edges.append(InnerEdge(mesh_data, other_primitive_i, &other_looptri, vertex)); + segments.append(FanSegment(mesh_data, other_primitive_i, &other_looptri, vertex)); current_edge = edge_i; previous_primitive = other_primitive_i; stop = true; @@ -601,7 +600,7 @@ struct Fan { } } if (stop == false) { - flags.full = false; + flags.is_manifold = false; break; } if (stop_primitive == previous_primitive) { @@ -613,7 +612,7 @@ struct Fan { int count_edges_not_added() const { int result = 0; - for (const InnerEdge &fan_edge : inner_edges) { + for (const FanSegment &fan_edge : segments) { if (!fan_edge.flags.found) { result++; } @@ -626,14 +625,14 @@ struct Fan { Vector mesh_primitive_indices = connecting_mesh_primitive_indices(uv_vertex); /* Go over all fan edges to find if they can be found as primitive around the uv vertex. */ - for (InnerEdge &fan_edge : inner_edges) { + for (FanSegment &fan_edge : segments) { fan_edge.flags.found = mesh_primitive_indices.contains(fan_edge.primitive_index); } } void init_uv_coordinates(const MeshData &mesh_data, UVVertex &uv_vertex) { - for (InnerEdge &fan_edge : inner_edges) { + for (FanSegment &fan_edge : segments) { int other_v = mesh_data.loops[fan_edge.primitive->tri[fan_edge.vert_order[0]]].v; if (other_v == uv_vertex.vertex) { other_v = mesh_data.loops[fan_edge.primitive->tri[fan_edge.vert_order[1]]].v; @@ -650,9 +649,9 @@ struct Fan { } } - inner_edges.last().uvs[2] = inner_edges.first().uvs[1]; - for (int i = 0; i < inner_edges.size() - 1; i++) { - inner_edges[i].uvs[2] = inner_edges[i + 1].uvs[1]; + segments.last().uvs[2] = segments.first().uvs[1]; + for (int i = 0; i < segments.size() - 1; i++) { + segments[i].uvs[2] = segments[i + 1].uvs[1]; } } @@ -663,8 +662,8 @@ struct Fan { */ bool contains_vertex_on_outside(const MeshData &mesh_data, const int vertex_index) const { - for (const InnerEdge &inner_edge : inner_edges) { - int v2 = mesh_data.loops[inner_edge.primitive->tri[inner_edge.vert_order[1]]].v; + for (const FanSegment &segment : segments) { + int v2 = mesh_data.loops[segment.primitive->tri[segment.vert_order[1]]].v; if (vertex_index == v2) { return true; } @@ -674,15 +673,15 @@ struct Fan { #endif - static bool is_path_valid(const Span &path, + static bool is_path_valid(const Span &path, const MeshData &mesh_data, const int from_vertex, const int to_vertex) { int current_vert = from_vertex; - for (InnerEdge *inner_edge : path) { - int v1 = mesh_data.loops[inner_edge->primitive->tri[inner_edge->vert_order[1]]].v; - int v2 = mesh_data.loops[inner_edge->primitive->tri[inner_edge->vert_order[2]]].v; + for (FanSegment *segment : path) { + int v1 = mesh_data.loops[segment->primitive->tri[segment->vert_order[1]]].v; + int v2 = mesh_data.loops[segment->primitive->tri[segment->vert_order[2]]].v; if (!ELEM(current_vert, v1, v2)) { return false; } @@ -697,23 +696,22 @@ struct Fan { * * Algorithm only uses the winding order of the given fan segments. */ - static Vector path_between(const Span edge_order, - const MeshData &mesh_data, - const int from_vertex, - const int to_vertex, - const bool reversed) + static Vector path_between(const Span edge_order, + const MeshData &mesh_data, + const int from_vertex, + const int to_vertex, + const bool reversed) { const int from_vert_order = 1; const int to_vert_order = 2; const int index_increment = reversed ? -1 : 1; - Vector result; + Vector result; result.reserve(edge_order.size()); int index = 0; while (true) { - InnerEdge *inner_edge = edge_order[index]; - int v2 = - mesh_data.loops[inner_edge->primitive->tri[inner_edge->vert_order[from_vert_order]]].v; + FanSegment *segment = edge_order[index]; + int v2 = mesh_data.loops[segment->primitive->tri[segment->vert_order[from_vert_order]]].v; if (v2 == from_vertex) { break; } @@ -721,11 +719,10 @@ struct Fan { } while (true) { - InnerEdge *inner_edge = edge_order[index]; - result.append(inner_edge); + FanSegment *segment = edge_order[index]; + result.append(segment); - int v3 = - mesh_data.loops[inner_edge->primitive->tri[inner_edge->vert_order[to_vert_order]]].v; + int v3 = mesh_data.loops[segment->primitive->tri[segment->vert_order[to_vert_order]]].v; if (v3 == to_vertex) { break; } @@ -742,36 +739,36 @@ struct Fan { * Score is determined by counting the number of steps and subtracting that with steps that have * not yet been visited. */ - static int64_t score(const Span solution) + static int64_t score(const Span solution) { int64_t not_visited_steps = 0; - for (InnerEdge *inner_edge : solution) { - if (!inner_edge->flags.found) { + for (FanSegment *segment : solution) { + if (!segment->flags.found) { not_visited_steps++; } } return solution.size() - not_visited_steps; } - Vector best_path_between(const MeshData &mesh_data, - const int from_vertex, - const int to_vertex) + Vector best_path_between(const MeshData &mesh_data, + const int from_vertex, + const int to_vertex) { BLI_assert_msg(contains_vertex_on_outside(mesh_data, from_vertex), "Inconsistency detected, `from_vertex` isn't part of the outside of the fan."); BLI_assert_msg(contains_vertex_on_outside(mesh_data, to_vertex), "Inconsistency detected, `to_vertex` isn't part of the outside of the fan."); if (to_vertex == from_vertex) { - return Vector(); + return Vector(); } - Array edges(inner_edges.size()); - for (int64_t index : inner_edges.index_range()) { - edges[index] = &inner_edges[index]; + Array edges(segments.size()); + for (int64_t index : segments.index_range()) { + edges[index] = &segments[index]; } - Vector winding_1 = path_between(edges, mesh_data, from_vertex, to_vertex, false); - Vector winding_2 = path_between(edges, mesh_data, from_vertex, to_vertex, true); + Vector winding_1 = path_between(edges, mesh_data, from_vertex, to_vertex, false); + Vector winding_2 = path_between(edges, mesh_data, from_vertex, to_vertex, true); bool winding_1_valid = is_path_valid(winding_1, mesh_data, from_vertex, to_vertex); bool winding_2_valid = is_path_valid(winding_2, mesh_data, from_vertex, to_vertex); @@ -784,7 +781,7 @@ struct Fan { } if (!winding_1_valid && !winding_2_valid) { BLI_assert_msg(false, "Both solutions aren't valid."); - return Vector(); + return Vector(); } if (score(winding_1) < score(winding_2)) { return winding_1; @@ -794,8 +791,8 @@ struct Fan { void print_debug(const MeshData &mesh_data) const { - for (const InnerEdge &inner_edge : inner_edges) { - inner_edge.print_debug(mesh_data); + for (const FanSegment &segment : segments) { + segment.print_debug(mesh_data); } std::cout << "\n"; } @@ -907,7 +904,7 @@ static void extend_at_vert(const MeshData &mesh_data, UVVertex *uv_vertex = corner.second->get_uv_vertex(0); Fan fan(mesh_data, uv_vertex->vertex); - if (!fan.flags.full) { + if (!fan.flags.is_manifold) { return; } fan.init_uv_coordinates(mesh_data, *uv_vertex); @@ -917,7 +914,7 @@ static void extend_at_vert(const MeshData &mesh_data, /* In 3d space everything can connected, but in uv space it may not. * in this case in the space between we should extract the primitives to be added * from the fan. */ - Vector winding_solution = fan.best_path_between( + Vector winding_solution = fan.best_path_between( mesh_data, corner.first->get_uv_vertex(0)->vertex, corner.second->get_uv_vertex(1)->vertex); /* @@ -987,7 +984,7 @@ static void extend_at_vert(const MeshData &mesh_data, float factor = (segment_index + 1.0f) / num_to_add; float2 new_uv = corner.uv(factor, min_uv_distance); - InnerEdge &segment = *winding_solution[segment_index]; + FanSegment &segment = *winding_solution[segment_index]; const int fill_primitive_i = segment.primitive_index; const MLoopTri &fill_primitive = mesh_data.looptris[fill_primitive_i]; From 6e4e5f6484534aa38488d4605fd0e9c2432bbf68 Mon Sep 17 00:00:00 2001 From: Julian Eisel Date: Tue, 24 Jan 2023 15:30:10 +0100 Subject: [PATCH 0907/1522] UI: Allow spawning file browser dialog from regular file browser editor When some path property was displayed in the File Browser, clicking the icon to open a file browser dialog to choose a file/directory would show an error. While this makes sense when you are already in a file browser dialog (we don't support such nested file browser dialogs), allow it when the file browser is opened as a normal editor, not as a dialog. --- source/blender/editors/space_buttons/buttons_ops.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index 9c8d46a41f9..b45abcf8068 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -268,8 +268,9 @@ static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event) FileBrowseOp *fbo; char *str; - if (CTX_wm_space_file(C)) { - BKE_report(op->reports, RPT_ERROR, "Cannot activate a file selector, one already open"); + const SpaceFile *sfile = CTX_wm_space_file(C); + if (sfile && sfile->op) { + BKE_report(op->reports, RPT_ERROR, "Cannot activate a file selector dialog, one already open"); return OPERATOR_CANCELLED; } From 813425877b632e3e1ddeaaa9ef6f3a0367e46fb1 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 24 Jan 2023 16:24:00 +0100 Subject: [PATCH 0908/1522] Geometry Nodes: propagate material from guides in Interpolate Curves node This was missing from the original implementation. --- .../nodes/geometry/nodes/node_geo_interpolate_curves.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc b/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc index c4f275334a8..dc3b24e4fae 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_interpolate_curves.cc @@ -747,6 +747,11 @@ static GeometrySet generate_interpolated_curves( all_neighbor_indices, all_neighbor_weights); + if (guide_curves_id.mat != nullptr) { + child_curves_id->mat = static_cast(MEM_dupallocN(guide_curves_id.mat)); + child_curves_id->totcol = guide_curves_id.totcol; + } + return GeometrySet::create_with_curves(child_curves_id); } From 3956c4738f6071f3db6f882de55afa0e08dd93c6 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Tue, 24 Jan 2023 16:44:26 +0100 Subject: [PATCH 0909/1522] GPencil: Change range for Length value in Simplify modifier In some cases a smaller value is required. Anyways, the UI value soft limit is 0.005 --- source/blender/makesrna/intern/rna_gpencil_modifier.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index 58ecec54013..8c8a9dc4980 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -1425,8 +1425,8 @@ static void rna_def_modifier_gpencilsimplify(BlenderRNA *brna) /* Sample */ prop = RNA_def_property(srna, "length", PROP_FLOAT, PROP_DISTANCE); RNA_def_property_float_sdna(prop, NULL, "length"); - RNA_def_property_range(prop, 0.005, FLT_MAX); - RNA_def_property_ui_range(prop, 0, 1.0, 0.05, 3); + RNA_def_property_range(prop, 0, FLT_MAX); + RNA_def_property_ui_range(prop, 0.005, 1.0, 0.05, 3); RNA_def_property_ui_text(prop, "Length", "Length of each segment"); RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); From 0931d91ab6dc7bbb1acd0520ac9034775cc46447 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Tue, 24 Jan 2023 16:47:22 +0100 Subject: [PATCH 0910/1522] GPenciil: Small UI tweak Remove duplicate `Layer` word --- source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c index e40c6e9df4d..04f5bbeacf6 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c @@ -285,7 +285,7 @@ static void random_panel_draw(const bContext *UNUSED(C), Panel *panel) break; case GP_OFFSET_LAYER: uiItemR(layout, ptr, "stroke_step", 0, IFACE_("Layer Step"), ICON_NONE); - uiItemR(layout, ptr, "stroke_start_offset", 0, IFACE_("Layer Offset"), ICON_NONE); + uiItemR(layout, ptr, "stroke_start_offset", 0, IFACE_("Offset"), ICON_NONE); break; } gpencil_modifier_panel_end(layout, ptr); From 62743dde1117ef5a1ca37716047c6940c9fb1371 Mon Sep 17 00:00:00 2001 From: Antonio Vazquez Date: Tue, 24 Jan 2023 16:53:28 +0100 Subject: [PATCH 0911/1522] Gpencil: More UI tweaks in Offset modifier Remove more duplicate words --- source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c index 04f5bbeacf6..bc25c31b1ca 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c @@ -277,11 +277,11 @@ static void random_panel_draw(const bContext *UNUSED(C), Panel *panel) break; case GP_OFFSET_STROKE: uiItemR(layout, ptr, "stroke_step", 0, IFACE_("Stroke Step"), ICON_NONE); - uiItemR(layout, ptr, "stroke_start_offset", 0, IFACE_("Stroke Offset"), ICON_NONE); + uiItemR(layout, ptr, "stroke_start_offset", 0, IFACE_("Offset"), ICON_NONE); break; case GP_OFFSET_MATERIAL: uiItemR(layout, ptr, "stroke_step", 0, IFACE_("Material Step"), ICON_NONE); - uiItemR(layout, ptr, "stroke_start_offset", 0, IFACE_("Material Offset"), ICON_NONE); + uiItemR(layout, ptr, "stroke_start_offset", 0, IFACE_("Offset"), ICON_NONE); break; case GP_OFFSET_LAYER: uiItemR(layout, ptr, "stroke_step", 0, IFACE_("Layer Step"), ICON_NONE); From 6899474615dfb35b455fc05d91dadd066f60ae97 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 24 Jan 2023 17:30:24 +0100 Subject: [PATCH 0912/1522] Fix: crash when adding curves in curves sculpt mode with interpolation There were two issues: * The `new_point_counts_per_curve` was one too large, resulting in `interpolate_from_neighbors` reading invalid memory. * Writing the counts into the existing offsets array didn't quite work because there can be a collision at the offset right between the last old curve and the first new point. There was a race condition where this value could be read and written at the same time. --- .../geometry/intern/add_curves_on_mesh.cc | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/source/blender/geometry/intern/add_curves_on_mesh.cc b/source/blender/geometry/intern/add_curves_on_mesh.cc index 2ef51867e07..5f174558e29 100644 --- a/source/blender/geometry/intern/add_curves_on_mesh.cc +++ b/source/blender/geometry/intern/add_curves_on_mesh.cc @@ -286,19 +286,25 @@ AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, /* Compute new curve offsets. */ MutableSpan curve_offsets = curves.offsets_for_write(); - MutableSpan new_point_counts_per_curve = curve_offsets.drop_front(old_curves_num); - if (inputs.interpolate_point_count) { + Array new_point_counts_per_curve(added_curves_num); + if (inputs.interpolate_point_count && old_curves_num > 0) { + const OffsetIndices old_points_by_curve{curve_offsets.take_front(old_curves_num + 1)}; interpolate_from_neighbors( neighbors_per_curve, inputs.fallback_point_count, - [&](const int curve_i) { return curve_offsets[curve_i + 1] - curve_offsets[curve_i]; }, + [&](const int curve_i) { return old_points_by_curve.size(curve_i); }, new_point_counts_per_curve); } else { new_point_counts_per_curve.fill(inputs.fallback_point_count); } - offset_indices::accumulate_counts_to_offsets(curve_offsets.drop_front(old_curves_num), - old_points_num); + curve_offsets[old_curves_num] = old_points_num; + int offset = old_points_num; + for (const int i : new_point_counts_per_curve.index_range()) { + const int point_count_in_curve = new_point_counts_per_curve[i]; + curve_offsets[old_curves_num + i + 1] = offset + point_count_in_curve; + offset += point_count_in_curve; + } const int new_points_num = curves.offsets().last(); curves.resize(new_points_num, new_curves_num); From ae80a6696febe96b329cbad94502b643aba790b0 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 24 Jan 2023 17:45:47 +0100 Subject: [PATCH 0913/1522] Geometry Nodes: don't show warning in modifier with multiple geometry inputs Simon mentioned that this gets in the way more than it helps. No geometry sockets currently show up in the modifier panel. People may build node groups that have multiple geometry inputs that can be used when the group is used as node instead of as modifier. In the future we could also allow e.g. choosing an object to pass into a geometry socket. That has the problem that we'd also have to duplicate other functionality of the Object Info node (original vs. relative space). --- source/blender/modifiers/intern/MOD_nodes.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index a23156dd3c8..da623881548 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -1280,9 +1280,6 @@ static void check_property_socket_sync(const Object *ob, ModifierData *md) BKE_modifier_set_error(ob, md, "Node group's geometry input must be the first"); } } - else if (geometry_socket_count > 1) { - BKE_modifier_set_error(ob, md, "Node group can only have one geometry input"); - } } static void modifyGeometry(ModifierData *md, From b1c8889396c044a460be619c501ed789fe5cf3be Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Tue, 24 Jan 2023 17:58:58 +0100 Subject: [PATCH 0914/1522] Cleanup: format --- .../startup/bl_ui/properties_data_armature.py | 2 +- .../startup/bl_ui/properties_data_bone.py | 7 +- .../startup/bl_ui/properties_data_camera.py | 90 ++++- .../startup/bl_ui/properties_data_curve.py | 14 +- .../startup/bl_ui/properties_data_curves.py | 28 +- .../startup/bl_ui/properties_data_lattice.py | 7 +- .../startup/bl_ui/properties_data_light.py | 23 +- .../startup/bl_ui/properties_data_mesh.py | 24 +- .../startup/bl_ui/properties_data_metaball.py | 14 +- .../bl_ui/properties_data_pointcloud.py | 21 +- .../startup/bl_ui/properties_data_speaker.py | 35 +- .../startup/bl_ui/properties_data_volume.py | 49 ++- .../startup/bl_ui/properties_freestyle.py | 22 +- .../startup/bl_ui/properties_material.py | 9 +- .../bl_ui/properties_material_gpencil.py | 2 +- .../startup/bl_ui/properties_object.py | 4 +- .../startup/bl_ui/properties_output.py | 98 ++++- .../startup/bl_ui/properties_particle.py | 357 +++++++++++++++--- .../startup/bl_ui/properties_physics_cloth.py | 91 ++++- .../bl_ui/properties_physics_common.py | 7 +- .../bl_ui/properties_physics_dynamicpaint.py | 147 ++++++-- .../startup/bl_ui/properties_physics_field.py | 70 +++- .../startup/bl_ui/properties_physics_fluid.py | 154 ++++++-- .../bl_ui/properties_physics_rigidbody.py | 56 ++- ...properties_physics_rigidbody_constraint.py | 91 ++++- .../bl_ui/properties_physics_softbody.py | 105 +++++- .../startup/bl_ui/properties_render.py | 56 ++- .../startup/bl_ui/properties_texture.py | 147 ++++++-- .../startup/bl_ui/properties_view_layer.py | 8 +- .../scripts/startup/bl_ui/properties_world.py | 14 +- release/scripts/startup/bl_ui/space_node.py | 2 +- .../scripts/startup/bl_ui/space_sequencer.py | 2 +- source/blender/draw/intern/smaa_textures.h | 1 - source/blender/editors/sculpt_paint/sculpt.cc | 6 +- 34 files changed, 1480 insertions(+), 283 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index aefcb53fb56..06e44f7f09f 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -248,7 +248,7 @@ class DATA_PT_motion_paths_display(MotionPathButtonsPanel_display, Panel): class DATA_PT_custom_props_arm(ArmatureButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Armature diff --git a/release/scripts/startup/bl_ui/properties_data_bone.py b/release/scripts/startup/bl_ui/properties_data_bone.py index 465a1854528..8eedcc4961b 100644 --- a/release/scripts/startup/bl_ui/properties_data_bone.py +++ b/release/scripts/startup/bl_ui/properties_data_bone.py @@ -444,7 +444,12 @@ class BONE_PT_deform(BoneButtonsPanel, Panel): class BONE_PT_custom_props(BoneButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _property_type = bpy.types.Bone, bpy.types.EditBone, bpy.types.PoseBone @property diff --git a/release/scripts/startup/bl_ui/properties_data_camera.py b/release/scripts/startup/bl_ui/properties_data_camera.py index 6ecfa9dfbb4..7043c24ace1 100644 --- a/release/scripts/startup/bl_ui/properties_data_camera.py +++ b/release/scripts/startup/bl_ui/properties_data_camera.py @@ -21,7 +21,12 @@ class CAMERA_PT_presets(PresetPanel, Panel): preset_subdir = "camera" preset_operator = "script.execute_preset" preset_add_operator = "camera.preset_add" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} class CAMERA_PT_safe_areas_presets(PresetPanel, Panel): @@ -29,13 +34,23 @@ class CAMERA_PT_safe_areas_presets(PresetPanel, Panel): preset_subdir = "safe_areas" preset_operator = "script.execute_preset" preset_add_operator = "camera.safe_areas_preset_add" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} class DATA_PT_context_camera(CameraButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -52,7 +67,12 @@ class DATA_PT_context_camera(CameraButtonsPanel, Panel): class DATA_PT_lens(CameraButtonsPanel, Panel): bl_label = "Lens" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -100,7 +120,7 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): col.prop(ccam, "fisheye_polynomial_k3", text="K3") col.prop(ccam, "fisheye_polynomial_k4", text="K4") - elif engine in {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'}: + elif engine in {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'}: if cam.lens_unit == 'MILLIMETERS': col.prop(cam, "lens") elif cam.lens_unit == 'FOV': @@ -122,7 +142,12 @@ class DATA_PT_lens(CameraButtonsPanel, Panel): class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): bl_label = "Stereoscopy" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -171,7 +196,12 @@ class DATA_PT_camera_stereoscopy(CameraButtonsPanel, Panel): class DATA_PT_camera(CameraButtonsPanel, Panel): bl_label = "Camera" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header_preset(self, _context): CAMERA_PT_presets.draw_panel_header(self.layout) @@ -201,7 +231,7 @@ class DATA_PT_camera(CameraButtonsPanel, Panel): class DATA_PT_camera_dof(CameraButtonsPanel, Panel): bl_label = "Depth of Field" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cam = context.camera @@ -228,7 +258,7 @@ class DATA_PT_camera_dof(CameraButtonsPanel, Panel): class DATA_PT_camera_dof_aperture(CameraButtonsPanel, Panel): bl_label = "Aperture" bl_parent_id = "DATA_PT_camera_dof" - COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -252,7 +282,12 @@ class DATA_PT_camera_dof_aperture(CameraButtonsPanel, Panel): class DATA_PT_camera_background_image(CameraButtonsPanel, Panel): bl_label = "Background Images" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cam = context.camera @@ -359,7 +394,12 @@ class DATA_PT_camera_background_image(CameraButtonsPanel, Panel): class DATA_PT_camera_display(CameraButtonsPanel, Panel): bl_label = "Viewport Display" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -392,7 +432,12 @@ class DATA_PT_camera_display_composition_guides(CameraButtonsPanel, Panel): bl_label = "Composition Guides" bl_parent_id = "DATA_PT_camera_display" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -419,7 +464,12 @@ class DATA_PT_camera_display_composition_guides(CameraButtonsPanel, Panel): class DATA_PT_camera_safe_areas(CameraButtonsPanel, Panel): bl_label = "Safe Areas" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cam = context.camera @@ -449,7 +499,12 @@ class DATA_PT_camera_safe_areas_center_cut(CameraButtonsPanel, Panel): bl_label = "Center-Cut Safe Areas" bl_parent_id = "DATA_PT_camera_safe_areas" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cam = context.camera @@ -473,7 +528,12 @@ class DATA_PT_camera_safe_areas_center_cut(CameraButtonsPanel, Panel): class DATA_PT_custom_props_camera(CameraButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Camera diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py index fc02d15d267..bd239203123 100644 --- a/release/scripts/startup/bl_ui/properties_data_curve.py +++ b/release/scripts/startup/bl_ui/properties_data_curve.py @@ -116,7 +116,12 @@ class DATA_PT_shape_curve(CurveButtonsPanel, Panel): class DATA_PT_curve_texture_space(CurveButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -475,7 +480,12 @@ class DATA_PT_text_boxes(CurveButtonsPanelText, Panel): class DATA_PT_custom_props_curve(CurveButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Curve diff --git a/release/scripts/startup/bl_ui/properties_data_curves.py b/release/scripts/startup/bl_ui/properties_data_curves.py index 99f5bc2e33e..8064a9b5696 100644 --- a/release/scripts/startup/bl_ui/properties_data_curves.py +++ b/release/scripts/startup/bl_ui/properties_data_curves.py @@ -18,7 +18,12 @@ class DataButtonsPanel: class DATA_PT_context_curves(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -35,7 +40,12 @@ class DATA_PT_context_curves(DataButtonsPanel, Panel): class DATA_PT_curves_surface(DataButtonsPanel, Panel): bl_label = "Surface" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -118,7 +128,12 @@ class CURVES_UL_attributes(UIList): class DATA_PT_CURVES_attributes(DataButtonsPanel, Panel): bl_label = "Attributes" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): curves = context.curves @@ -143,7 +158,12 @@ class DATA_PT_CURVES_attributes(DataButtonsPanel, Panel): class DATA_PT_custom_props_curves(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Curves if hasattr(bpy.types, "Curves") else None diff --git a/release/scripts/startup/bl_ui/properties_data_lattice.py b/release/scripts/startup/bl_ui/properties_data_lattice.py index acd83b08c6a..f9b451a772a 100644 --- a/release/scripts/startup/bl_ui/properties_data_lattice.py +++ b/release/scripts/startup/bl_ui/properties_data_lattice.py @@ -64,7 +64,12 @@ class DATA_PT_lattice(DataButtonsPanel, Panel): class DATA_PT_custom_props_lattice(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Lattice diff --git a/release/scripts/startup/bl_ui/properties_data_light.py b/release/scripts/startup/bl_ui/properties_data_light.py index 1e8baca3c24..272191aebe5 100644 --- a/release/scripts/startup/bl_ui/properties_data_light.py +++ b/release/scripts/startup/bl_ui/properties_data_light.py @@ -18,7 +18,12 @@ class DataButtonsPanel: class DATA_PT_context_light(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_EEVEE', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -44,7 +49,7 @@ class DATA_PT_preview(DataButtonsPanel, Panel): class DATA_PT_light(DataButtonsPanel, Panel): bl_label = "Light" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -230,7 +235,12 @@ class DATA_PT_EEVEE_shadow_contact(DataButtonsPanel, Panel): class DATA_PT_spot(DataButtonsPanel, Panel): bl_label = "Spot Shape" bl_parent_id = "DATA_PT_EEVEE_light" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_EEVEE', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -275,7 +285,12 @@ class DATA_PT_falloff_curve(DataButtonsPanel, Panel): class DATA_PT_custom_props_light(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE_NEXT', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_EEVEE', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Light diff --git a/release/scripts/startup/bl_ui/properties_data_mesh.py b/release/scripts/startup/bl_ui/properties_data_mesh.py index 714dcca9673..1ff76a73e7e 100644 --- a/release/scripts/startup/bl_ui/properties_data_mesh.py +++ b/release/scripts/startup/bl_ui/properties_data_mesh.py @@ -171,7 +171,7 @@ class MeshButtonsPanel: class DATA_PT_context_mesh(MeshButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -189,7 +189,7 @@ class DATA_PT_context_mesh(MeshButtonsPanel, Panel): class DATA_PT_normals(MeshButtonsPanel, Panel): bl_label = "Normals" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -211,7 +211,7 @@ class DATA_PT_normals(MeshButtonsPanel, Panel): class DATA_PT_texture_space(MeshButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -231,7 +231,7 @@ class DATA_PT_texture_space(MeshButtonsPanel, Panel): class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): bl_label = "Vertex Groups" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -288,7 +288,7 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel): class DATA_PT_face_maps(MeshButtonsPanel, Panel): bl_label = "Face Maps" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -331,7 +331,7 @@ class DATA_PT_face_maps(MeshButtonsPanel, Panel): class DATA_PT_shape_keys(MeshButtonsPanel, Panel): bl_label = "Shape Keys" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -428,7 +428,7 @@ class DATA_PT_shape_keys(MeshButtonsPanel, Panel): class DATA_PT_uv_texture(MeshButtonsPanel, Panel): bl_label = "UV Maps" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -448,7 +448,7 @@ class DATA_PT_uv_texture(MeshButtonsPanel, Panel): class DATA_PT_remesh(MeshButtonsPanel, Panel): bl_label = "Remesh" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -478,7 +478,7 @@ class DATA_PT_remesh(MeshButtonsPanel, Panel): class DATA_PT_customdata(MeshButtonsPanel, Panel): bl_label = "Geometry Data" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -519,7 +519,7 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel): class DATA_PT_custom_props_mesh(MeshButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Mesh @@ -568,7 +568,7 @@ class MESH_UL_attributes(UIList): class DATA_PT_mesh_attributes(MeshButtonsPanel, Panel): bl_label = "Attributes" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): mesh = context.mesh @@ -692,7 +692,7 @@ class MESH_UL_color_attributes_selector(UIList, ColorAttributesListBase): class DATA_PT_vertex_colors(DATA_PT_mesh_attributes, Panel): bl_label = "Color Attributes" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): mesh = context.mesh diff --git a/release/scripts/startup/bl_ui/properties_data_metaball.py b/release/scripts/startup/bl_ui/properties_data_metaball.py index 1493e6177a6..2fc37617a21 100644 --- a/release/scripts/startup/bl_ui/properties_data_metaball.py +++ b/release/scripts/startup/bl_ui/properties_data_metaball.py @@ -56,7 +56,12 @@ class DATA_PT_metaball(DataButtonsPanel, Panel): class DATA_PT_mball_texture_space(DataButtonsPanel, Panel): bl_label = "Texture Space" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -111,7 +116,12 @@ class DATA_PT_metaball_element(DataButtonsPanel, Panel): class DATA_PT_custom_props_metaball(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.MetaBall diff --git a/release/scripts/startup/bl_ui/properties_data_pointcloud.py b/release/scripts/startup/bl_ui/properties_data_pointcloud.py index f83735ec3dd..7b9dd18cfa3 100644 --- a/release/scripts/startup/bl_ui/properties_data_pointcloud.py +++ b/release/scripts/startup/bl_ui/properties_data_pointcloud.py @@ -18,7 +18,12 @@ class DataButtonsPanel: class DATA_PT_context_pointcloud(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -97,7 +102,12 @@ class POINTCLOUD_UL_attributes(UIList): class DATA_PT_pointcloud_attributes(DataButtonsPanel, Panel): bl_label = "Attributes" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): pointcloud = context.pointcloud @@ -122,7 +132,12 @@ class DATA_PT_pointcloud_attributes(DataButtonsPanel, Panel): class DATA_PT_custom_props_pointcloud(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.PointCloud if hasattr(bpy.types, "PointCloud") else None diff --git a/release/scripts/startup/bl_ui/properties_data_speaker.py b/release/scripts/startup/bl_ui/properties_data_speaker.py index 4bdbc0ab7e3..9bd62106f74 100644 --- a/release/scripts/startup/bl_ui/properties_data_speaker.py +++ b/release/scripts/startup/bl_ui/properties_data_speaker.py @@ -18,7 +18,12 @@ class DataButtonsPanel: class DATA_PT_context_speaker(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -35,7 +40,12 @@ class DATA_PT_context_speaker(DataButtonsPanel, Panel): class DATA_PT_speaker(DataButtonsPanel, Panel): bl_label = "Sound" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -57,7 +67,12 @@ class DATA_PT_speaker(DataButtonsPanel, Panel): class DATA_PT_distance(DataButtonsPanel, Panel): bl_label = "Distance" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -81,7 +96,12 @@ class DATA_PT_distance(DataButtonsPanel, Panel): class DATA_PT_cone(DataButtonsPanel, Panel): bl_label = "Cone" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -103,7 +123,12 @@ class DATA_PT_cone(DataButtonsPanel, Panel): class DATA_PT_custom_props_speaker(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Speaker diff --git a/release/scripts/startup/bl_ui/properties_data_volume.py b/release/scripts/startup/bl_ui/properties_data_volume.py index f0c1d16b7fd..e79cebb606a 100644 --- a/release/scripts/startup/bl_ui/properties_data_volume.py +++ b/release/scripts/startup/bl_ui/properties_data_volume.py @@ -18,7 +18,12 @@ class DataButtonsPanel: class DATA_PT_context_volume(DataButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -35,7 +40,12 @@ class DATA_PT_context_volume(DataButtonsPanel, Panel): class DATA_PT_volume_file(DataButtonsPanel, Panel): bl_label = "OpenVDB File" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -80,7 +90,12 @@ class VOLUME_UL_grids(UIList): class DATA_PT_volume_grids(DataButtonsPanel, Panel): bl_label = "Grids" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -93,7 +108,12 @@ class DATA_PT_volume_grids(DataButtonsPanel, Panel): class DATA_PT_volume_render(DataButtonsPanel, Panel): bl_label = "Render" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -125,7 +145,12 @@ class DATA_PT_volume_render(DataButtonsPanel, Panel): class DATA_PT_volume_viewport_display(DataButtonsPanel, Panel): bl_label = "Viewport Display" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -149,7 +174,12 @@ class DATA_PT_volume_viewport_display(DataButtonsPanel, Panel): class DATA_PT_volume_viewport_display_slicing(DataButtonsPanel, Panel): bl_label = "" bl_parent_id = 'DATA_PT_volume_viewport_display' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): layout = self.layout @@ -175,7 +205,12 @@ class DATA_PT_volume_viewport_display_slicing(DataButtonsPanel, Panel): class DATA_PT_custom_props_volume(DataButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _context_path = "object.data" _property_type = bpy.types.Volume diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py index 2b948765943..4d5a8e45207 100644 --- a/release/scripts/startup/bl_ui/properties_freestyle.py +++ b/release/scripts/startup/bl_ui/properties_freestyle.py @@ -21,7 +21,7 @@ class RENDER_PT_freestyle(RenderFreestyleButtonsPanel, Panel): bl_label = "Freestyle" bl_options = {'DEFAULT_CLOSED'} bl_order = 10 - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): rd = context.scene.render @@ -79,7 +79,7 @@ class ViewLayerFreestyleEditorButtonsPanel(ViewLayerFreestyleButtonsPanel): class ViewLayerFreestyleLineStyle(ViewLayerFreestyleEditorButtonsPanel): # Freestyle Linestyle Panels - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -123,7 +123,7 @@ class RENDER_MT_lineset_context_menu(Menu): class VIEWLAYER_PT_freestyle(ViewLayerFreestyleButtonsPanel, Panel): bl_label = "Freestyle" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): view_layer = context.view_layer @@ -153,7 +153,7 @@ class VIEWLAYER_PT_freestyle(ViewLayerFreestyleButtonsPanel, Panel): class VIEWLAYER_PT_freestyle_edge_detection(ViewLayerFreestyleButtonsPanel, Panel): bl_label = "Edge Detection" bl_parent_id = "VIEWLAYER_PT_freestyle" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -183,7 +183,7 @@ class VIEWLAYER_PT_freestyle_edge_detection(ViewLayerFreestyleButtonsPanel, Pane class VIEWLAYER_PT_freestyle_style_modules(ViewLayerFreestyleButtonsPanel, Panel): bl_label = "Style Modules" bl_parent_id = "VIEWLAYER_PT_freestyle" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -219,7 +219,7 @@ class VIEWLAYER_PT_freestyle_style_modules(ViewLayerFreestyleButtonsPanel, Panel class VIEWLAYER_PT_freestyle_lineset(ViewLayerFreestyleEditorButtonsPanel, Panel): bl_label = "Freestyle Line Set" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw_edge_type_buttons(self, box, lineset, edge_type): # property names @@ -282,7 +282,7 @@ class VIEWLAYER_PT_freestyle_lineset(ViewLayerFreestyleEditorButtonsPanel, Panel class VIEWLAYER_PT_freestyle_lineset_visibilty(ViewLayerFreestyleLineStyle, Panel): bl_label = "Visibility" bl_parent_id = "VIEWLAYER_PT_freestyle_lineset" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): layout = self.layout @@ -316,7 +316,7 @@ class VIEWLAYER_PT_freestyle_lineset_visibilty(ViewLayerFreestyleLineStyle, Pane class VIEWLAYER_PT_freestyle_lineset_edgetype(ViewLayerFreestyleLineStyle, Panel): bl_label = "Edge Type" bl_parent_id = "VIEWLAYER_PT_freestyle_lineset" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): layout = self.layout @@ -366,7 +366,7 @@ class VIEWLAYER_PT_freestyle_lineset_edgetype(ViewLayerFreestyleLineStyle, Panel class VIEWLAYER_PT_freestyle_lineset_facemarks(ViewLayerFreestyleLineStyle, Panel): bl_label = "Face Marks" bl_parent_id = "VIEWLAYER_PT_freestyle_lineset" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): @@ -395,7 +395,7 @@ class VIEWLAYER_PT_freestyle_lineset_facemarks(ViewLayerFreestyleLineStyle, Pane class VIEWLAYER_PT_freestyle_lineset_collection(ViewLayerFreestyleLineStyle, Panel): bl_label = "Collection" bl_parent_id = "VIEWLAYER_PT_freestyle_lineset" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): @@ -1236,7 +1236,7 @@ class MaterialFreestyleButtonsPanel: class MATERIAL_PT_freestyle_line(MaterialFreestyleButtonsPanel, Panel): bl_label = "Freestyle Line" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py index f9b9450277b..efe67a0c294 100644 --- a/release/scripts/startup/bl_ui/properties_material.py +++ b/release/scripts/startup/bl_ui/properties_material.py @@ -60,7 +60,12 @@ class MATERIAL_PT_preview(MaterialButtonsPanel, Panel): class MATERIAL_PT_custom_props(MaterialButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _context_path = "material" _property_type = bpy.types.Material @@ -69,7 +74,7 @@ class EEVEE_MATERIAL_PT_context_material(MaterialButtonsPanel, Panel): bl_label = "" bl_context = "material" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_material_gpencil.py b/release/scripts/startup/bl_ui/properties_material_gpencil.py index b0d717fa168..3db7b9fb484 100644 --- a/release/scripts/startup/bl_ui/properties_material_gpencil.py +++ b/release/scripts/startup/bl_ui/properties_material_gpencil.py @@ -228,7 +228,7 @@ class MATERIAL_PT_gpencil_preview(GPMaterialButtonsPanel, Panel): class MATERIAL_PT_gpencil_custom_props(GPMaterialButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} _context_path = "object.active_material" _property_type = bpy.types.Material diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index 85a90d61aa8..6ab4bb3af69 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -366,7 +366,7 @@ class OBJECT_PT_motion_paths_display(MotionPathButtonsPanel_display, Panel): class OBJECT_PT_visibility(ObjectButtonsPanel, Panel): bl_label = "Visibility" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -395,7 +395,7 @@ class OBJECT_PT_visibility(ObjectButtonsPanel, Panel): class OBJECT_PT_custom_props(ObjectButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} _context_path = "object" _property_type = bpy.types.Object diff --git a/release/scripts/startup/bl_ui/properties_output.py b/release/scripts/startup/bl_ui/properties_output.py index 427eec67b98..9d6e527dbd8 100644 --- a/release/scripts/startup/bl_ui/properties_output.py +++ b/release/scripts/startup/bl_ui/properties_output.py @@ -42,7 +42,12 @@ class RenderOutputButtonsPanel: class RENDER_PT_format(RenderOutputButtonsPanel, Panel): bl_label = "Format" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _frame_rate_args_prev = None _preset_class = None @@ -120,7 +125,12 @@ class RENDER_PT_format(RenderOutputButtonsPanel, Panel): class RENDER_PT_frame_range(RenderOutputButtonsPanel, Panel): bl_label = "Frame Range" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -139,7 +149,12 @@ class RENDER_PT_time_stretching(RenderOutputButtonsPanel, Panel): bl_label = "Time Stretching" bl_parent_id = "RENDER_PT_frame_range" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -156,7 +171,12 @@ class RENDER_PT_time_stretching(RenderOutputButtonsPanel, Panel): class RENDER_PT_post_processing(RenderOutputButtonsPanel, Panel): bl_label = "Post Processing" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -174,7 +194,12 @@ class RENDER_PT_post_processing(RenderOutputButtonsPanel, Panel): class RENDER_PT_stamp(RenderOutputButtonsPanel, Panel): bl_label = "Metadata" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -208,7 +233,12 @@ class RENDER_PT_stamp_note(RenderOutputButtonsPanel, Panel): bl_label = "Note" bl_parent_id = "RENDER_PT_stamp" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): rd = context.scene.render @@ -228,7 +258,12 @@ class RENDER_PT_stamp_burn(RenderOutputButtonsPanel, Panel): bl_label = "Burn Into Image" bl_parent_id = "RENDER_PT_stamp" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): rd = context.scene.render @@ -252,7 +287,12 @@ class RENDER_PT_stamp_burn(RenderOutputButtonsPanel, Panel): class RENDER_PT_output(RenderOutputButtonsPanel, Panel): bl_label = "Output" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -281,7 +321,12 @@ class RENDER_PT_output(RenderOutputButtonsPanel, Panel): class RENDER_PT_output_views(RenderOutputButtonsPanel, Panel): bl_label = "Views" bl_parent_id = "RENDER_PT_output" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -301,7 +346,12 @@ class RENDER_PT_output_color_management(RenderOutputButtonsPanel, Panel): bl_label = "Color Management" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "RENDER_PT_output" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): scene = context.scene @@ -336,7 +386,12 @@ class RENDER_PT_encoding(RenderOutputButtonsPanel, Panel): bl_label = "Encoding" bl_parent_id = "RENDER_PT_output" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header_preset(self, _context): RENDER_PT_ffmpeg_presets.draw_panel_header(self.layout) @@ -361,7 +416,12 @@ class RENDER_PT_encoding(RenderOutputButtonsPanel, Panel): class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel): bl_label = "Video" bl_parent_id = "RENDER_PT_encoding" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -437,7 +497,12 @@ class RENDER_PT_encoding_video(RenderOutputButtonsPanel, Panel): class RENDER_PT_encoding_audio(RenderOutputButtonsPanel, Panel): bl_label = "Audio" bl_parent_id = "RENDER_PT_encoding" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -479,7 +544,12 @@ class RENDER_UL_renderviews(UIList): class RENDER_PT_stereoscopy(RenderOutputButtonsPanel, Panel): bl_label = "Stereoscopy" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} bl_options = {'DEFAULT_CLOSED'} def draw_header(self, context): diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index bef8931c8ce..cbe6b9f3e6d 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -52,7 +52,12 @@ def particle_get_settings(context): class PARTICLE_MT_context_menu(Menu): bl_label = "Particle Specials" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -92,7 +97,12 @@ class PARTICLE_PT_hair_dynamics_presets(PresetPanel, Panel): preset_subdir = "hair_dynamics" preset_operator = "script.execute_preset" preset_add_operator = "particle.hair_dynamics_preset_add" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} class ParticleButtonsPanel: @@ -146,7 +156,12 @@ class PARTICLE_UL_particle_systems(bpy.types.UIList): class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -240,7 +255,12 @@ class PARTICLE_PT_context_particles(ParticleButtonsPanel, Panel): class PARTICLE_PT_emission(ParticleButtonsPanel, Panel): bl_label = "Emission" bl_translation_context = i18n_contexts.id_particlesettings - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -292,7 +312,12 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel): bl_label = "Source" bl_parent_id = "PARTICLE_PT_emission" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -329,7 +354,12 @@ class PARTICLE_PT_emission_source(ParticleButtonsPanel, Panel): class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel): bl_label = "Hair Dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -412,7 +442,12 @@ class PARTICLE_PT_hair_dynamics_collision(ParticleButtonsPanel, Panel): bl_label = "Collisions" bl_parent_id = "PARTICLE_PT_hair_dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -444,7 +479,12 @@ class PARTICLE_PT_hair_dynamics_structure(ParticleButtonsPanel, Panel): bl_label = "Structure" bl_parent_id = "PARTICLE_PT_hair_dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -475,7 +515,12 @@ class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel): bl_label = "Volume" bl_parent_id = "PARTICLE_PT_hair_dynamics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -506,7 +551,12 @@ class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel): class PARTICLE_PT_cache(ParticleButtonsPanel, Panel): bl_label = "Cache" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -539,7 +589,12 @@ class PARTICLE_PT_cache(ParticleButtonsPanel, Panel): class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel): bl_label = "Velocity" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -588,7 +643,12 @@ class PARTICLE_PT_velocity(ParticleButtonsPanel, Panel): class PARTICLE_PT_rotation(ParticleButtonsPanel, Panel): bl_label = "Rotation" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -643,7 +703,12 @@ class PARTICLE_PT_rotation_angular_velocity(ParticleButtonsPanel, Panel): bl_label = "Angular Velocity" bl_parent_id = "PARTICLE_PT_rotation" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -668,7 +733,12 @@ class PARTICLE_PT_rotation_angular_velocity(ParticleButtonsPanel, Panel): class PARTICLE_PT_physics(ParticleButtonsPanel, Panel): bl_label = "Physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -721,7 +791,12 @@ class PARTICLE_PT_physics_fluid_advanced(ParticleButtonsPanel, Panel): bl_label = "Advanced" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -766,7 +841,12 @@ class PARTICLE_PT_physics_fluid_springs(ParticleButtonsPanel, Panel): bl_label = "Springs" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -790,7 +870,12 @@ class PARTICLE_PT_physics_fluid_springs_viscoelastic(ParticleButtonsPanel, Panel bl_label = "Viscoelastic Springs" bl_parent_id = "PARTICLE_PT_physics_fluid_springs" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -826,7 +911,12 @@ class PARTICLE_PT_physics_fluid_springs_advanced(ParticleButtonsPanel, Panel): bl_label = "Advanced" bl_parent_id = "PARTICLE_PT_physics_fluid_springs" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -850,7 +940,12 @@ class PARTICLE_PT_physics_boids_movement(ParticleButtonsPanel, Panel): bl_label = "Movement" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -903,7 +998,12 @@ class PARTICLE_PT_physics_boids_battle(ParticleButtonsPanel, Panel): bl_label = "Battle" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -930,7 +1030,12 @@ class PARTICLE_PT_physics_boids_misc(ParticleButtonsPanel, Panel): bl_label = "Misc" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -955,7 +1060,12 @@ class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel): bl_label = "Relations" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1010,7 +1120,12 @@ class PARTICLE_PT_physics_fluid_interaction(ParticleButtonsPanel, Panel): bl_label = "Fluid Interaction" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1051,7 +1166,12 @@ class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel): bl_label = "Deflection" bl_parent_id = "PARTICLE_PT_physics" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1077,7 +1197,12 @@ class PARTICLE_PT_physics_deflection(ParticleButtonsPanel, Panel): class PARTICLE_PT_physics_forces(ParticleButtonsPanel, Panel): bl_label = "Forces" bl_parent_id = "PARTICLE_PT_physics" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1104,7 +1229,12 @@ class PARTICLE_PT_physics_integration(ParticleButtonsPanel, Panel): bl_label = "Integration" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_physics" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1138,7 +1268,12 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel): bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_physics" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1236,7 +1371,12 @@ class PARTICLE_PT_boidbrain(ParticleButtonsPanel, Panel): class PARTICLE_PT_render(ParticleButtonsPanel, Panel): bl_label = "Render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1283,7 +1423,12 @@ class PARTICLE_PT_render_extra(ParticleButtonsPanel, Panel): bl_label = "Extra" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1307,7 +1452,12 @@ class PARTICLE_PT_render_extra(ParticleButtonsPanel, Panel): class PARTICLE_PT_render_path(ParticleButtonsPanel, Panel): bl_label = "Path" bl_parent_id = "PARTICLE_PT_render" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1329,7 +1479,12 @@ class PARTICLE_PT_render_path_timing(ParticleButtonsPanel, Panel): bl_label = "Timing" bl_parent_id = "PARTICLE_PT_render" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1357,7 +1512,12 @@ class PARTICLE_PT_render_path_timing(ParticleButtonsPanel, Panel): class PARTICLE_PT_render_object(ParticleButtonsPanel, Panel): bl_label = "Object" bl_parent_id = "PARTICLE_PT_render" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1382,7 +1542,12 @@ class PARTICLE_PT_render_object(ParticleButtonsPanel, Panel): class PARTICLE_PT_render_collection(ParticleButtonsPanel, Panel): bl_label = "Collection" bl_parent_id = "PARTICLE_PT_render" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1412,7 +1577,12 @@ class PARTICLE_PT_render_collection_use_count(ParticleButtonsPanel, Panel): bl_label = "Use Count" bl_parent_id = "PARTICLE_PT_render_collection" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1460,7 +1630,12 @@ class PARTICLE_PT_render_collection_use_count(ParticleButtonsPanel, Panel): class PARTICLE_PT_draw(ParticleButtonsPanel, Panel): bl_label = "Viewport Display" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1519,7 +1694,12 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel): bl_label = "Children" bl_translation_context = i18n_contexts.id_particlesettings bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1572,7 +1752,12 @@ class PARTICLE_PT_children_parting(ParticleButtonsPanel, Panel): bl_label = "Parting" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1603,7 +1788,12 @@ class PARTICLE_PT_children_clumping(ParticleButtonsPanel, Panel): bl_label = "Clumping" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1639,7 +1829,12 @@ class PARTICLE_PT_children_clumping_noise(ParticleButtonsPanel, Panel): bl_label = "Clump Noise" bl_parent_id = "PARTICLE_PT_children_clumping" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): @@ -1663,7 +1858,12 @@ class PARTICLE_PT_children_roughness(ParticleButtonsPanel, Panel): bl_translation_context = i18n_contexts.id_particlesettings bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1704,7 +1904,12 @@ class PARTICLE_PT_children_kink(ParticleButtonsPanel, Panel): bl_label = "Kink" bl_parent_id = "PARTICLE_PT_children" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1754,7 +1959,12 @@ class PARTICLE_PT_children_kink(ParticleButtonsPanel, Panel): class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel): bl_label = "Field Weights" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1775,7 +1985,12 @@ class PARTICLE_PT_field_weights(ParticleButtonsPanel, Panel): class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel): bl_label = "Force Field Settings" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -1791,7 +2006,12 @@ class PARTICLE_PT_force_fields(ParticleButtonsPanel, Panel): class PARTICLE_PT_force_fields_type1(ParticleButtonsPanel, Panel): bl_label = "Type 1" bl_parent_id = "PARTICLE_PT_force_fields" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -1808,7 +2028,12 @@ class PARTICLE_PT_force_fields_type1(ParticleButtonsPanel, Panel): class PARTICLE_PT_force_fields_type2(ParticleButtonsPanel, Panel): bl_label = "Type 2" bl_parent_id = "PARTICLE_PT_force_fields" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -1826,7 +2051,12 @@ class PARTICLE_PT_force_fields_type1_falloff(ParticleButtonsPanel, Panel): bl_label = "Falloff" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_force_fields_type1" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -1842,7 +2072,12 @@ class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel): bl_label = "Falloff" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = "PARTICLE_PT_force_fields_type2" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -1857,7 +2092,12 @@ class PARTICLE_PT_force_fields_type2_falloff(ParticleButtonsPanel, Panel): class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): bl_label = "Vertex Groups" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1946,7 +2186,12 @@ class PARTICLE_PT_vertexgroups(ParticleButtonsPanel, Panel): class PARTICLE_PT_textures(ParticleButtonsPanel, Panel): bl_label = "Textures" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1978,7 +2223,12 @@ class PARTICLE_PT_textures(ParticleButtonsPanel, Panel): class PARTICLE_PT_hair_shape(ParticleButtonsPanel, Panel): bl_label = "Hair Shape" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -2006,7 +2256,12 @@ class PARTICLE_PT_hair_shape(ParticleButtonsPanel, Panel): class PARTICLE_PT_custom_props(ParticleButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _context_path = "particle_system.settings" _property_type = bpy.types.ParticleSettings diff --git a/release/scripts/startup/bl_ui/properties_physics_cloth.py b/release/scripts/startup/bl_ui/properties_physics_cloth.py index c1c55f39eca..fb6eb653f25 100644 --- a/release/scripts/startup/bl_ui/properties_physics_cloth.py +++ b/release/scripts/startup/bl_ui/properties_physics_cloth.py @@ -35,7 +35,12 @@ class PhysicButtonsPanel: class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): bl_label = "Cloth" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header_preset(self, _context): CLOTH_PT_presets.draw_panel_header(self.layout) @@ -60,7 +65,12 @@ class PHYSICS_PT_cloth(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_physical_properties(PhysicButtonsPanel, Panel): bl_label = "Physical Properties" bl_parent_id = 'PHYSICS_PT_cloth' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -84,7 +94,12 @@ class PHYSICS_PT_cloth_physical_properties(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): bl_label = "Stiffness" bl_parent_id = 'PHYSICS_PT_cloth_physical_properties' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -115,7 +130,12 @@ class PHYSICS_PT_cloth_stiffness(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_damping(PhysicButtonsPanel, Panel): bl_label = "Damping" bl_parent_id = 'PHYSICS_PT_cloth_physical_properties' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -146,7 +166,12 @@ class PHYSICS_PT_cloth_damping(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_internal_springs(PhysicButtonsPanel, Panel): bl_label = "Internal Springs" bl_parent_id = 'PHYSICS_PT_cloth_physical_properties' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cloth = context.cloth.settings @@ -188,7 +213,12 @@ class PHYSICS_PT_cloth_internal_springs(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_pressure(PhysicButtonsPanel, Panel): bl_label = "Pressure" bl_parent_id = 'PHYSICS_PT_cloth_physical_properties' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cloth = context.cloth.settings @@ -232,7 +262,12 @@ class PHYSICS_PT_cloth_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): md = context.cloth @@ -243,7 +278,12 @@ class PHYSICS_PT_cloth_shape(PhysicButtonsPanel, Panel): bl_label = "Shape" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -293,7 +333,12 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel): bl_label = "Collisions" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -313,7 +358,12 @@ class PHYSICS_PT_cloth_collision(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_object_collision(PhysicButtonsPanel, Panel): bl_label = "Object Collisions" bl_parent_id = 'PHYSICS_PT_cloth_collision' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cloth = context.cloth.collision_settings @@ -349,7 +399,12 @@ class PHYSICS_PT_cloth_object_collision(PhysicButtonsPanel, Panel): class PHYSICS_PT_cloth_self_collision(PhysicButtonsPanel, Panel): bl_label = "Self Collisions" bl_parent_id = 'PHYSICS_PT_cloth_collision' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): cloth = context.cloth.collision_settings @@ -386,7 +441,12 @@ class PHYSICS_PT_cloth_property_weights(PhysicButtonsPanel, Panel): bl_label = "Property Weights" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -440,7 +500,12 @@ class PHYSICS_PT_cloth_field_weights(PhysicButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = 'PHYSICS_PT_cloth' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): cloth = context.cloth.settings diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 5a6eb9916e6..cae4687faac 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -50,7 +50,12 @@ def physics_add_special(layout, data, name, addop, removeop, typeicon): class PHYSICS_PT_add(PhysicButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py index 40abbb825ee..2dc79088167 100644 --- a/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py +++ b/release/scripts/startup/bl_ui/properties_physics_dynamicpaint.py @@ -83,7 +83,12 @@ class PhysicButtonsPanel: class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): bl_label = "Dynamic Paint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -104,7 +109,12 @@ class PHYSICS_PT_dynamic_paint(PhysicButtonsPanel, Panel): class PHYSICS_PT_dynamic_paint_settings(PhysicButtonsPanel, Panel): bl_label = "Settings" bl_parent_id = 'PHYSICS_PT_dynamic_paint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -188,7 +198,12 @@ class PHYSICS_PT_dynamic_paint_settings(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_surface_canvas(PhysicButtonsPanel, Panel): bl_label = "Surface" bl_parent_id = "PHYSICS_PT_dynamic_paint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -251,7 +266,12 @@ class PHYSICS_PT_dp_surface_canvas_paint_dry(PhysicButtonsPanel, Panel): bl_label = "Dry" bl_parent_id = "PHYSICS_PT_dp_surface_canvas" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -287,7 +307,12 @@ class PHYSICS_PT_dp_surface_canvas_paint_dissolve(PhysicButtonsPanel, Panel): bl_label = "Dissolve" bl_parent_id = "PHYSICS_PT_dp_surface_canvas" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -324,7 +349,12 @@ class PHYSICS_PT_dp_canvas_output(PhysicButtonsPanel, Panel): bl_label = "Output" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -400,7 +430,12 @@ class PHYSICS_PT_dp_canvas_output_paintmaps(PhysicButtonsPanel, Panel): bl_label = "Paintmaps" bl_parent_id = "PHYSICS_PT_dp_canvas_output" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -430,7 +465,12 @@ class PHYSICS_PT_dp_canvas_output_wetmaps(PhysicButtonsPanel, Panel): bl_label = "Wetmaps" bl_parent_id = "PHYSICS_PT_dp_canvas_output" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -460,7 +500,12 @@ class PHYSICS_PT_dp_canvas_initial_color(PhysicButtonsPanel, Panel): bl_label = "Initial Color" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -500,7 +545,12 @@ class PHYSICS_PT_dp_effects(PhysicButtonsPanel, Panel): bl_label = "Effects" bl_parent_id = 'PHYSICS_PT_dynamic_paint' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -517,7 +567,12 @@ class PHYSICS_PT_dp_effects_spread(PhysicButtonsPanel, Panel): bl_label = "Spread" bl_parent_id = "PHYSICS_PT_dp_effects" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -552,7 +607,12 @@ class PHYSICS_PT_dp_effects_drip(PhysicButtonsPanel, Panel): bl_label = "Drip" bl_parent_id = "PHYSICS_PT_dp_effects" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -588,7 +648,12 @@ class PHYSICS_PT_dp_effects_drip_weights(PhysicButtonsPanel, Panel): bl_label = "Weights" bl_parent_id = "PHYSICS_PT_dp_effects_drip" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -612,7 +677,12 @@ class PHYSICS_PT_dp_effects_shrink(PhysicButtonsPanel, Panel): bl_label = "Shrink" bl_parent_id = "PHYSICS_PT_dp_effects" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -642,7 +712,12 @@ class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -662,7 +737,12 @@ class PHYSICS_PT_dp_cache(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): bl_label = "Source" bl_parent_id = "PHYSICS_PT_dynamic_paint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -725,7 +805,12 @@ class PHYSICS_PT_dp_brush_source(PhysicButtonsPanel, Panel): class PHYSICS_PT_dp_brush_source_color_ramp(PhysicButtonsPanel, Panel): bl_label = "Falloff Ramp" bl_parent_id = "PHYSICS_PT_dp_brush_source" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -752,7 +837,12 @@ class PHYSICS_PT_dp_brush_velocity(PhysicButtonsPanel, Panel): bl_label = "Velocity" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -783,7 +873,12 @@ class PHYSICS_PT_dp_brush_velocity_color_ramp(PhysicButtonsPanel, Panel): bl_label = "Ramp" bl_parent_id = "PHYSICS_PT_dp_brush_velocity" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -804,7 +899,12 @@ class PHYSICS_PT_dp_brush_velocity_smudge(PhysicButtonsPanel, Panel): bl_label = "Smudge" bl_parent_id = "PHYSICS_PT_dp_brush_velocity" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -832,7 +932,12 @@ class PHYSICS_PT_dp_brush_wave(PhysicButtonsPanel, Panel): bl_label = "Waves" bl_parent_id = "PHYSICS_PT_dynamic_paint" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py index 4e3bff3640a..757ac57c171 100644 --- a/release/scripts/startup/bl_ui/properties_physics_field.py +++ b/release/scripts/startup/bl_ui/properties_physics_field.py @@ -27,7 +27,12 @@ class PhysicButtonsPanel: class PHYSICS_PT_field(PhysicButtonsPanel, Panel): bl_label = "Force Fields" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -49,7 +54,12 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel): bl_label = "Settings" bl_parent_id = 'PHYSICS_PT_field' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -136,7 +146,12 @@ class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_settings_kink(PhysicButtonsPanel, Panel): bl_label = "Kink" bl_parent_id = 'PHYSICS_PT_field_settings' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -170,7 +185,12 @@ class PHYSICS_PT_field_settings_kink(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_settings_texture_select(PhysicButtonsPanel, Panel): bl_label = "Texture" bl_parent_id = 'PHYSICS_PT_field_settings' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -192,7 +212,12 @@ class PHYSICS_PT_field_settings_texture_select(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_falloff(PhysicButtonsPanel, Panel): bl_label = "Falloff" bl_parent_id = "PHYSICS_PT_field" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -217,7 +242,12 @@ class PHYSICS_PT_field_falloff(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel): bl_label = "Angular" bl_parent_id = "PHYSICS_PT_field_falloff" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -256,7 +286,12 @@ class PHYSICS_PT_field_falloff_angular(PhysicButtonsPanel, Panel): class PHYSICS_PT_field_falloff_radial(PhysicButtonsPanel, Panel): bl_label = "Radial" bl_parent_id = "PHYSICS_PT_field_falloff" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -300,7 +335,12 @@ def collision_warning(layout): class PHYSICS_PT_collision(PhysicButtonsPanel, Panel): bl_label = "Collision" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -331,7 +371,12 @@ class PHYSICS_PT_collision(PhysicButtonsPanel, Panel): class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel): bl_label = "Particle" bl_parent_id = "PHYSICS_PT_collision" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -377,7 +422,12 @@ class PHYSICS_PT_collision_particle(PhysicButtonsPanel, Panel): class PHYSICS_PT_collision_softbody(PhysicButtonsPanel, Panel): bl_label = "Softbody & Cloth" bl_parent_id = "PHYSICS_PT_collision" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_fluid.py b/release/scripts/startup/bl_ui/properties_physics_fluid.py index 42bc3299e6c..cbf385adbc8 100644 --- a/release/scripts/startup/bl_ui/properties_physics_fluid.py +++ b/release/scripts/startup/bl_ui/properties_physics_fluid.py @@ -98,7 +98,12 @@ class PhysicButtonsPanel: class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel): bl_label = "Fluid" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -122,7 +127,12 @@ class PHYSICS_PT_fluid(PhysicButtonsPanel, Panel): class PHYSICS_PT_settings(PhysicButtonsPanel, Panel): bl_label = "Settings" bl_parent_id = 'PHYSICS_PT_fluid' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -285,7 +295,12 @@ class PHYSICS_PT_settings(PhysicButtonsPanel, Panel): class PHYSICS_PT_borders(PhysicButtonsPanel, Panel): bl_label = "Border Collisions" bl_parent_id = 'PHYSICS_PT_settings' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -318,7 +333,12 @@ class PHYSICS_PT_borders(PhysicButtonsPanel, Panel): class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel): bl_label = "Gas" bl_parent_id = 'PHYSICS_PT_fluid' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -351,7 +371,12 @@ class PHYSICS_PT_smoke_dissolve(PhysicButtonsPanel, Panel): bl_label = "Dissolve" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -395,7 +420,12 @@ class PHYSICS_PT_fire(PhysicButtonsPanel, Panel): bl_label = "Fire" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -434,7 +464,12 @@ class PHYSICS_PT_fire(PhysicButtonsPanel, Panel): class PHYSICS_PT_liquid(PhysicButtonsPanel, Panel): bl_label = "Liquid" bl_parent_id = 'PHYSICS_PT_fluid' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -497,7 +532,12 @@ class PHYSICS_PT_flow_source(PhysicButtonsPanel, Panel): bl_label = "Flow Source" bl_parent_id = 'PHYSICS_PT_settings' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -538,7 +578,12 @@ class PHYSICS_PT_flow_source(PhysicButtonsPanel, Panel): class PHYSICS_PT_flow_initial_velocity(PhysicButtonsPanel, Panel): bl_label = "Initial Velocity" bl_parent_id = 'PHYSICS_PT_settings' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -580,7 +625,12 @@ class PHYSICS_PT_flow_texture(PhysicButtonsPanel, Panel): bl_label = "Texture" bl_parent_id = 'PHYSICS_PT_settings' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -631,7 +681,12 @@ class PHYSICS_PT_adaptive_domain(PhysicButtonsPanel, Panel): bl_label = "Adaptive Domain" bl_parent_id = 'PHYSICS_PT_settings' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -683,7 +738,12 @@ class PHYSICS_PT_noise(PhysicButtonsPanel, Panel): bl_label = "Noise" bl_parent_id = 'PHYSICS_PT_smoke' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -763,7 +823,12 @@ class PHYSICS_PT_mesh(PhysicButtonsPanel, Panel): bl_label = "Mesh" bl_parent_id = 'PHYSICS_PT_liquid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -858,7 +923,12 @@ class PHYSICS_PT_particles(PhysicButtonsPanel, Panel): bl_label = "Particles" bl_parent_id = 'PHYSICS_PT_liquid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -989,7 +1059,12 @@ class PHYSICS_PT_viscosity(PhysicButtonsPanel, Panel): bl_label = "Viscosity" bl_parent_id = 'PHYSICS_PT_liquid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1029,7 +1104,12 @@ class PHYSICS_PT_diffusion(PhysicButtonsPanel, Panel): bl_label = "Diffusion" bl_parent_id = 'PHYSICS_PT_liquid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1076,7 +1156,12 @@ class PHYSICS_PT_guide(PhysicButtonsPanel, Panel): bl_label = "Guides" bl_parent_id = 'PHYSICS_PT_fluid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1142,7 +1227,12 @@ class PHYSICS_PT_collections(PhysicButtonsPanel, Panel): bl_label = "Collections" bl_parent_id = 'PHYSICS_PT_fluid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1169,7 +1259,12 @@ class PHYSICS_PT_collections(PhysicButtonsPanel, Panel): class PHYSICS_PT_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = 'PHYSICS_PT_fluid' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1253,7 +1348,12 @@ class PHYSICS_PT_export(PhysicButtonsPanel, Panel): bl_label = "Advanced" bl_parent_id = 'PHYSICS_PT_cache' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1298,7 +1398,12 @@ class PHYSICS_PT_field_weights(PhysicButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = 'PHYSICS_PT_fluid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -1487,7 +1592,12 @@ class PHYSICS_PT_fluid_domain_render(PhysicButtonsPanel, Panel): bl_label = "Render" bl_parent_id = 'PHYSICS_PT_fluid' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py index 8df348026ea..26e55311fa8 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py @@ -19,7 +19,12 @@ class PHYSICS_PT_rigidbody_panel: class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Rigid Body" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -54,7 +59,12 @@ class PHYSICS_PT_rigid_body(PHYSICS_PT_rigidbody_panel, Panel): class PHYSICS_PT_rigid_body_settings(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Settings" bl_parent_id = 'PHYSICS_PT_rigid_body' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -86,7 +96,12 @@ class PHYSICS_PT_rigid_body_settings(PHYSICS_PT_rigidbody_panel, Panel): class PHYSICS_PT_rigid_body_collisions(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Collisions" bl_parent_id = 'PHYSICS_PT_rigid_body' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -136,7 +151,12 @@ class PHYSICS_PT_rigid_body_collisions_surface(PHYSICS_PT_rigidbody_panel, Panel bl_label = "Surface Response" bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -164,7 +184,12 @@ class PHYSICS_PT_rigid_body_collisions_sensitivity(PHYSICS_PT_rigidbody_panel, P bl_label = "Sensitivity" bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -201,7 +226,12 @@ class PHYSICS_PT_rigid_body_collisions_collections(PHYSICS_PT_rigidbody_panel, P bl_label = "Collections" bl_parent_id = 'PHYSICS_PT_rigid_body_collisions' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -223,7 +253,12 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel): bl_label = "Dynamics" bl_parent_id = 'PHYSICS_PT_rigid_body' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -256,7 +291,12 @@ class PHYSICS_PT_rigid_body_dynamics_deactivation(PHYSICS_PT_rigidbody_panel, Pa bl_label = "Deactivation" bl_parent_id = 'PHYSICS_PT_rigid_body_dynamics' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py index 9e867b674e1..4c4c2f1f27a 100644 --- a/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py +++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody_constraint.py @@ -13,7 +13,12 @@ class PHYSICS_PT_rigidbody_constraint_panel: class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Rigid Body Constraint" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -33,7 +38,12 @@ class PHYSICS_PT_rigid_body_constraint(PHYSICS_PT_rigidbody_constraint_panel, Pa class PHYSICS_PT_rigid_body_constraint_settings(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Settings" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -64,7 +74,12 @@ class PHYSICS_PT_rigid_body_constraint_settings(PHYSICS_PT_rigidbody_constraint_ class PHYSICS_PT_rigid_body_constraint_objects(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Objects" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -85,7 +100,12 @@ class PHYSICS_PT_rigid_body_constraint_objects(PHYSICS_PT_rigidbody_constraint_p class PHYSICS_PT_rigid_body_constraint_override_iterations(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Override Iterations" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -111,7 +131,12 @@ class PHYSICS_PT_rigid_body_constraint_override_iterations(PHYSICS_PT_rigidbody_ class PHYSICS_PT_rigid_body_constraint_limits(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Limits" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -128,7 +153,12 @@ class PHYSICS_PT_rigid_body_constraint_limits(PHYSICS_PT_rigidbody_constraint_pa class PHYSICS_PT_rigid_body_constraint_limits_linear(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Linear" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_limits' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -185,7 +215,12 @@ class PHYSICS_PT_rigid_body_constraint_limits_linear(PHYSICS_PT_rigidbody_constr class PHYSICS_PT_rigid_body_constraint_limits_angular(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Angular" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_limits' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -251,7 +286,12 @@ class PHYSICS_PT_rigid_body_constraint_limits_angular(PHYSICS_PT_rigidbody_const class PHYSICS_PT_rigid_body_constraint_motor(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Motor" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -268,7 +308,12 @@ class PHYSICS_PT_rigid_body_constraint_motor(PHYSICS_PT_rigidbody_constraint_pan class PHYSICS_PT_rigid_body_constraint_motor_angular(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Angular" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_motor' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -304,7 +349,12 @@ class PHYSICS_PT_rigid_body_constraint_motor_angular(PHYSICS_PT_rigidbody_constr class PHYSICS_PT_rigid_body_constraint_motor_linear(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Linear" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_motor' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -340,7 +390,12 @@ class PHYSICS_PT_rigid_body_constraint_motor_linear(PHYSICS_PT_rigidbody_constra class PHYSICS_PT_rigid_body_constraint_springs(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Springs" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -364,7 +419,12 @@ class PHYSICS_PT_rigid_body_constraint_springs(PHYSICS_PT_rigidbody_constraint_p class PHYSICS_PT_rigid_body_constraint_springs_angular(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Angular" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_springs' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -412,7 +472,12 @@ class PHYSICS_PT_rigid_body_constraint_springs_angular(PHYSICS_PT_rigidbody_cons class PHYSICS_PT_rigid_body_constraint_springs_linear(PHYSICS_PT_rigidbody_constraint_panel, Panel): bl_label = "Linear" bl_parent_id = 'PHYSICS_PT_rigid_body_constraint_springs' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py index e4a627e5c9e..988ec0659dd 100644 --- a/release/scripts/startup/bl_ui/properties_physics_softbody.py +++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py @@ -28,7 +28,12 @@ class PhysicButtonsPanel: class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel): bl_label = "Soft Body" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -44,7 +49,12 @@ class PHYSICS_PT_softbody_object(PhysicButtonsPanel, Panel): bl_label = "Object" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -72,7 +82,12 @@ class PHYSICS_PT_softbody_simulation(PhysicButtonsPanel, Panel): bl_label = "Simulation" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -90,7 +105,12 @@ class PHYSICS_PT_softbody_cache(PhysicButtonsPanel, Panel): bl_label = "Cache" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): md = context.soft_body @@ -101,7 +121,12 @@ class PHYSICS_PT_softbody_goal(PhysicButtonsPanel, Panel): bl_label = "Goal" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): softbody = context.soft_body.settings @@ -126,7 +151,12 @@ class PHYSICS_PT_softbody_goal_strengths(PhysicButtonsPanel, Panel): bl_label = "Strengths" bl_parent_id = 'PHYSICS_PT_softbody_goal' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -152,7 +182,12 @@ class PHYSICS_PT_softbody_goal_settings(PhysicButtonsPanel, Panel): bl_label = "Settings" bl_parent_id = 'PHYSICS_PT_softbody_goal' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -175,7 +210,12 @@ class PHYSICS_PT_softbody_edge(PhysicButtonsPanel, Panel): bl_label = "Edges" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): softbody = context.soft_body.settings @@ -226,7 +266,12 @@ class PHYSICS_PT_softbody_edge_aerodynamics(PhysicButtonsPanel, Panel): bl_label = "Aerodynamics" bl_parent_id = 'PHYSICS_PT_softbody_edge' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -249,7 +294,12 @@ class PHYSICS_PT_softbody_edge_stiffness(PhysicButtonsPanel, Panel): bl_label = "Stiffness" bl_parent_id = 'PHYSICS_PT_softbody_edge' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): softbody = context.soft_body.settings @@ -273,7 +323,12 @@ class PHYSICS_PT_softbody_collision(PhysicButtonsPanel, Panel): bl_label = "Self Collision" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): softbody = context.soft_body.settings @@ -308,7 +363,12 @@ class PHYSICS_PT_softbody_solver(PhysicButtonsPanel, Panel): bl_label = "Solver" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -333,7 +393,12 @@ class PHYSICS_PT_softbody_solver_diagnostics(PhysicButtonsPanel, Panel): bl_label = "Diagnostics" bl_parent_id = 'PHYSICS_PT_softbody_solver' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -352,7 +417,12 @@ class PHYSICS_PT_softbody_solver_helpers(PhysicButtonsPanel, Panel): bl_label = "Helpers" bl_parent_id = 'PHYSICS_PT_softbody_solver' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -375,7 +445,12 @@ class PHYSICS_PT_softbody_field_weights(PhysicButtonsPanel, Panel): bl_label = "Field Weights" bl_parent_id = 'PHYSICS_PT_softbody' bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): md = context.soft_body diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 2d24918eb72..2296d7ad157 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -47,7 +47,12 @@ class RENDER_PT_color_management(RenderButtonsPanel, Panel): bl_label = "Color Management" bl_options = {'DEFAULT_CLOSED'} bl_order = 100 - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -80,7 +85,12 @@ class RENDER_PT_color_management_curves(RenderButtonsPanel, Panel): bl_label = "Use Curves" bl_parent_id = "RENDER_PT_color_management" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): @@ -640,7 +650,7 @@ class RENDER_PT_eevee_hair(RenderButtonsPanel, Panel): class RENDER_PT_eevee_performance(RenderButtonsPanel, Panel): bl_label = "Performance" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -661,7 +671,12 @@ class RENDER_PT_gpencil(RenderButtonsPanel, Panel): bl_label = "Grease Pencil" bl_options = {'DEFAULT_CLOSED'} bl_order = 10 - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -677,7 +692,7 @@ class RENDER_PT_gpencil(RenderButtonsPanel, Panel): class RENDER_PT_opengl_sampling(RenderButtonsPanel, Panel): bl_label = "Sampling" - COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -699,7 +714,7 @@ class RENDER_PT_opengl_sampling(RenderButtonsPanel, Panel): class RENDER_PT_opengl_film(RenderButtonsPanel, Panel): bl_label = "Film" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -712,7 +727,7 @@ class RENDER_PT_opengl_film(RenderButtonsPanel, Panel): class RENDER_PT_opengl_lighting(RenderButtonsPanel, Panel): bl_label = "Lighting" - COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -724,7 +739,7 @@ class RENDER_PT_opengl_lighting(RenderButtonsPanel, Panel): class RENDER_PT_opengl_color(RenderButtonsPanel, Panel): bl_label = "Color" - COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -736,7 +751,7 @@ class RENDER_PT_opengl_color(RenderButtonsPanel, Panel): class RENDER_PT_opengl_options(RenderButtonsPanel, Panel): bl_label = "Options" - COMPAT_ENGINES = {'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -749,7 +764,12 @@ class RENDER_PT_opengl_options(RenderButtonsPanel, Panel): class RENDER_PT_simplify(RenderButtonsPanel, Panel): bl_label = "Simplify" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): rd = context.scene.render @@ -762,7 +782,12 @@ class RENDER_PT_simplify(RenderButtonsPanel, Panel): class RENDER_PT_simplify_viewport(RenderButtonsPanel, Panel): bl_label = "Viewport" bl_parent_id = "RENDER_PT_simplify" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -787,7 +812,12 @@ class RENDER_PT_simplify_viewport(RenderButtonsPanel, Panel): class RENDER_PT_simplify_render(RenderButtonsPanel, Panel): bl_label = "Render" bl_parent_id = "RENDER_PT_simplify" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -815,7 +845,7 @@ class RENDER_PT_simplify_greasepencil(RenderButtonsPanel, Panel, GreasePencilSim 'BLENDER_CLAY', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', - 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT', + 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT', } bl_options = {'DEFAULT_CLOSED'} diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py index 4d42e432cc8..8abd8b61839 100644 --- a/release/scripts/startup/bl_ui/properties_texture.py +++ b/release/scripts/startup/bl_ui/properties_texture.py @@ -67,7 +67,12 @@ class TextureButtonsPanel: class TEXTURE_PT_preview(TextureButtonsPanel, Panel): bl_label = "Preview" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -96,7 +101,12 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel): bl_label = "" bl_context = "texture" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -135,7 +145,12 @@ class TEXTURE_PT_context(TextureButtonsPanel, Panel): class TEXTURE_PT_node(TextureButtonsPanel, Panel): bl_label = "Node" bl_context = "texture" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -164,7 +179,12 @@ class TextureTypePanel(TextureButtonsPanel): class TEXTURE_PT_clouds(TextureTypePanel, Panel): bl_label = "Clouds" tex_type = 'CLOUDS' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -196,7 +216,12 @@ class TEXTURE_PT_clouds(TextureTypePanel, Panel): class TEXTURE_PT_wood(TextureTypePanel, Panel): bl_label = "Wood" tex_type = 'WOOD' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -233,7 +258,12 @@ class TEXTURE_PT_wood(TextureTypePanel, Panel): class TEXTURE_PT_marble(TextureTypePanel, Panel): bl_label = "Marble" tex_type = 'MARBLE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -267,7 +297,12 @@ class TEXTURE_PT_marble(TextureTypePanel, Panel): class TEXTURE_PT_magic(TextureTypePanel, Panel): bl_label = "Magic" tex_type = 'MAGIC' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -286,7 +321,12 @@ class TEXTURE_PT_magic(TextureTypePanel, Panel): class TEXTURE_PT_blend(TextureTypePanel, Panel): bl_label = "Blend" tex_type = 'BLEND' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -308,7 +348,12 @@ class TEXTURE_PT_blend(TextureTypePanel, Panel): class TEXTURE_PT_stucci(TextureTypePanel, Panel): bl_label = "Stucci" tex_type = 'STUCCI' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -339,7 +384,12 @@ class TEXTURE_PT_stucci(TextureTypePanel, Panel): class TEXTURE_PT_image(TextureTypePanel, Panel): bl_label = "Image" tex_type = 'IMAGE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, _context): # TODO: maybe expose the template_ID from the template image here. @@ -351,7 +401,12 @@ class TEXTURE_PT_image_settings(TextureTypePanel, Panel): bl_label = "Settings" bl_parent_id = 'TEXTURE_PT_image' tex_type = 'IMAGE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -506,7 +561,12 @@ class TEXTURE_PT_image_mapping_crop(TextureTypePanel, Panel): class TEXTURE_PT_musgrave(TextureTypePanel, Panel): bl_label = "Musgrave" tex_type = 'MUSGRAVE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -551,7 +611,12 @@ class TEXTURE_PT_musgrave(TextureTypePanel, Panel): class TEXTURE_PT_voronoi(TextureTypePanel, Panel): bl_label = "Voronoi" tex_type = 'VORONOI' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -584,7 +649,12 @@ class TEXTURE_PT_voronoi_feature_weights(TextureTypePanel, Panel): bl_label = "Feature Weights" bl_parent_id = "TEXTURE_PT_voronoi" tex_type = 'VORONOI' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -605,7 +675,12 @@ class TEXTURE_PT_voronoi_feature_weights(TextureTypePanel, Panel): class TEXTURE_PT_distortednoise(TextureTypePanel, Panel): bl_label = "Distorted Noise" tex_type = 'DISTORTED_NOISE' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -630,7 +705,12 @@ class TEXTURE_PT_distortednoise(TextureTypePanel, Panel): class TextureSlotPanel(TextureButtonsPanel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -642,7 +722,12 @@ class TextureSlotPanel(TextureButtonsPanel): class TEXTURE_PT_mapping(TextureSlotPanel, Panel): bl_label = "Mapping" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -710,7 +795,12 @@ class TEXTURE_PT_mapping(TextureSlotPanel, Panel): class TEXTURE_PT_influence(TextureSlotPanel, Panel): bl_label = "Influence" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -792,7 +882,12 @@ class TextureColorsPoll: class TEXTURE_PT_colors(TextureButtonsPanel, TextureColorsPoll, Panel): bl_label = "Colors" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -821,7 +916,12 @@ class TEXTURE_PT_colors_ramp(TextureButtonsPanel, TextureColorsPoll, Panel): bl_label = "Color Ramp" bl_options = {'DEFAULT_CLOSED'} bl_parent_id = 'TEXTURE_PT_colors' - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw_header(self, context): tex = context.texture @@ -842,7 +942,12 @@ class TEXTURE_PT_colors_ramp(TextureButtonsPanel, TextureColorsPoll, Panel): class TEXTURE_PT_custom_props(TextureButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _context_path = "texture" _property_type = Texture diff --git a/release/scripts/startup/bl_ui/properties_view_layer.py b/release/scripts/startup/bl_ui/properties_view_layer.py index c45cafa07fa..50579fe2da2 100644 --- a/release/scripts/startup/bl_ui/properties_view_layer.py +++ b/release/scripts/startup/bl_ui/properties_view_layer.py @@ -26,7 +26,12 @@ class ViewLayerButtonsPanel: class VIEWLAYER_PT_layer(ViewLayerButtonsPanel, Panel): bl_label = "View Layer" - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} def draw(self, context): layout = self.layout @@ -94,6 +99,7 @@ class VIEWLAYER_PT_eevee_next_layer_passes_data(ViewLayerButtonsPanel, Panel): sub.active = not scene.eevee.use_motion_blur sub.prop(view_layer, "use_pass_vector") + class VIEWLAYER_PT_eevee_next_layer_passes_data(ViewLayerButtonsPanel, Panel): bl_label = "Data" bl_parent_id = "VIEWLAYER_PT_layer_passes" diff --git a/release/scripts/startup/bl_ui/properties_world.py b/release/scripts/startup/bl_ui/properties_world.py index 8dd4e36b750..691666f346a 100644 --- a/release/scripts/startup/bl_ui/properties_world.py +++ b/release/scripts/startup/bl_ui/properties_world.py @@ -19,7 +19,12 @@ class WorldButtonsPanel: class WORLD_PT_context_world(WorldButtonsPanel, Panel): bl_label = "" bl_options = {'HIDE_HEADER'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): @@ -63,7 +68,12 @@ class EEVEE_WORLD_PT_mist(WorldButtonsPanel, Panel): class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_EEVEE_NEXT', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} _context_path = "world" _property_type = bpy.types.World diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 95851a78184..7e221d63d4a 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -670,7 +670,7 @@ class NODE_PT_texture_mapping(Panel): bl_category = "Node" bl_label = "Texture Mapping" bl_options = {'DEFAULT_CLOSED'} - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index 557105e0e84..dd6f827e92d 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -2607,7 +2607,7 @@ class SEQUENCER_PT_annotation_onion(AnnotationOnionSkin, SequencerButtonsPanel_O class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel): - COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH','BLENDER_WORKBENCH_NEXT'} + COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} _context_path = "active_sequence_strip" _property_type = (bpy.types.Sequence,) bl_category = "Strip" diff --git a/source/blender/draw/intern/smaa_textures.h b/source/blender/draw/intern/smaa_textures.h index f9a0bef7047..e33ccf38227 100644 --- a/source/blender/draw/intern/smaa_textures.h +++ b/source/blender/draw/intern/smaa_textures.h @@ -36,4 +36,3 @@ extern const unsigned char searchTexBytes[]; #ifdef __cplusplus } #endif - diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 039f12ad594..43fdc56fe3d 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -2801,7 +2801,8 @@ static PBVHNode **sculpt_pbvh_gather_generic_intern(Object *ob, data.original = use_original; data.ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK; data.center = nullptr; - BKE_pbvh_search_gather_ex(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode, leaf_flag); + BKE_pbvh_search_gather_ex( + ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, r_totnode, leaf_flag); } else { DistRayAABB_Precalc dist_ray_to_aabb_precalc; @@ -2815,7 +2816,8 @@ static PBVHNode **sculpt_pbvh_gather_generic_intern(Object *ob, data.original = use_original; data.dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc; data.ignore_fully_ineffective = brush->sculpt_tool != SCULPT_TOOL_MASK; - BKE_pbvh_search_gather_ex(ss->pbvh, SCULPT_search_circle_cb, &data, &nodes, r_totnode, leaf_flag); + BKE_pbvh_search_gather_ex( + ss->pbvh, SCULPT_search_circle_cb, &data, &nodes, r_totnode, leaf_flag); } return nodes; } From ce25e3e58145b703f5aeacc9f906b7ac2ca3c9c8 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Tue, 24 Jan 2023 17:33:10 +0100 Subject: [PATCH 0915/1522] Cycles: Cleanup: Add general-purpose conversion between sin and cos --- .../cycles/kernel/closure/bsdf_hair_principled.h | 5 ----- intern/cycles/kernel/closure/bsdf_microfacet.h | 2 +- .../cycles/kernel/closure/bsdf_microfacet_multi.h | 2 +- intern/cycles/kernel/closure/volume.h | 2 +- intern/cycles/kernel/geom/curve_intersect.h | 2 +- intern/cycles/kernel/integrator/mnee.h | 4 ++-- .../kernel/integrator/subsurface_random_walk.h | 2 +- intern/cycles/kernel/light/area.h | 2 +- intern/cycles/kernel/light/tree.h | 5 ----- intern/cycles/kernel/light/triangle.h | 2 +- intern/cycles/kernel/sample/mapping.h | 15 ++++++++------- intern/cycles/util/math.h | 10 ++++++++++ 12 files changed, 27 insertions(+), 26 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h index a9e8abe0475..f7cf3b716f6 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_principled.h +++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h @@ -41,11 +41,6 @@ static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledHairBSDF), static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledHairExtra), "PrincipledHairExtra is too large!"); -ccl_device_inline float cos_from_sin(const float s) -{ - return safe_sqrtf(1.0f - s * s); -} - /* Gives the change in direction in the normal plane for the given angles and p-th-order * scattering. */ ccl_device_inline float delta_phi(int p, float gamma_o, float gamma_t) diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 80c47bc9542..db53a29cfc3 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -200,7 +200,7 @@ ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, if (wi_.z < 0.99999f) { costheta_ = wi_.z; - sintheta_ = safe_sqrtf(1.0f - costheta_ * costheta_); + sintheta_ = sin_from_cos(costheta_); float invlen = 1.0f / sintheta_; cosphi_ = wi_.x * invlen; diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h index 51fcd3340c6..defc46a389f 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h @@ -43,7 +43,7 @@ ccl_device_forceinline float2 mf_sampleP22_11(const float cosI, return make_float2(r * cosf(phi), r * sinf(phi)); } - const float sinI = safe_sqrtf(1.0f - cosI * cosI); + const float sinI = sin_from_cos(cosI); const float tanI = sinI / cosI; const float projA = 0.5f * (cosI + 1.0f); if (projA < 0.0001f) diff --git a/intern/cycles/kernel/closure/volume.h b/intern/cycles/kernel/closure/volume.h index e6af2c01fcc..a9a28c2fa4a 100644 --- a/intern/cycles/kernel/closure/volume.h +++ b/intern/cycles/kernel/closure/volume.h @@ -88,7 +88,7 @@ henyey_greenstrein_sample(float3 D, float g, float randu, float randv, ccl_priva } } - float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta); + float sin_theta = sin_from_cos(cos_theta); float phi = M_2PI_F * randv; float3 dir = make_float3(sin_theta * cosf(phi), sin_theta * sinf(phi), cos_theta); diff --git a/intern/cycles/kernel/geom/curve_intersect.h b/intern/cycles/kernel/geom/curve_intersect.h index 747d4ba4c3f..e8ce0c58c1e 100644 --- a/intern/cycles/kernel/geom/curve_intersect.h +++ b/intern/cycles/kernel/geom/curve_intersect.h @@ -720,7 +720,7 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg, const float3 tangent = normalize(dPdu); const float3 bitangent = normalize(cross(tangent, -D)); const float sine = sd->v; - const float cosine = safe_sqrtf(1.0f - sine * sine); + const float cosine = cos_from_sin(sine); sd->N = normalize(sine * bitangent - cosine * normalize(cross(tangent, bitangent))); # if 0 diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h index b6b07ad83a1..f50e3bc6e0c 100644 --- a/intern/cycles/kernel/integrator/mnee.h +++ b/intern/cycles/kernel/integrator/mnee.h @@ -704,9 +704,9 @@ ccl_device_forceinline bool mnee_compute_transfer_matrix(ccl_private const Shade float ilo = -eta * ilh; float cos_theta = dot(wo, m.n); - float sin_theta = safe_sqrtf(1.f - sqr(cos_theta)); + float sin_theta = sin_from_cos(cos_theta); float cos_phi = dot(wo, s); - float sin_phi = safe_sqrtf(1.f - sqr(cos_phi)); + float sin_phi = sin_from_cos(cos_phi); /* Wo = (cos_phi * sin_theta) * s + (sin_phi * sin_theta) * t + cos_theta * n. */ float3 dH_dtheta = ilo * (cos_theta * (cos_phi * s + sin_phi * t) - sin_theta * m.n); diff --git a/intern/cycles/kernel/integrator/subsurface_random_walk.h b/intern/cycles/kernel/integrator/subsurface_random_walk.h index fdcb66c32f5..70e2920349f 100644 --- a/intern/cycles/kernel/integrator/subsurface_random_walk.h +++ b/intern/cycles/kernel/integrator/subsurface_random_walk.h @@ -136,7 +136,7 @@ ccl_device_forceinline float diffusion_length_dwivedi(float alpha) ccl_device_forceinline float3 direction_from_cosine(float3 D, float cos_theta, float randv) { - float sin_theta = safe_sqrtf(1.0f - cos_theta * cos_theta); + float sin_theta = sin_from_cos(cos_theta); float phi = M_2PI_F * randv; float3 dir = make_float3(sin_theta * cosf(phi), sin_theta * sinf(phi), cos_theta); diff --git a/intern/cycles/kernel/light/area.h b/intern/cycles/kernel/light/area.h index 9c0ca0c8a70..a4badf907a0 100644 --- a/intern/cycles/kernel/light/area.h +++ b/intern/cycles/kernel/light/area.h @@ -102,7 +102,7 @@ ccl_device float area_light_spread_attenuation(const float3 D, /* The factor M_PI_F comes from integrating the radiance over the hemisphere */ return (cos_a > 0.9999997f) ? M_PI_F : 0.0f; } - const float sin_a = safe_sqrtf(1.0f - sqr(cos_a)); + const float sin_a = sin_from_cos(cos_a); const float tan_a = sin_a / cos_a; return max((tan_half_spread - tan_a) * normalize_spread, 0.0f); } diff --git a/intern/cycles/kernel/light/tree.h b/intern/cycles/kernel/light/tree.h index 423879bcddc..441e9758088 100644 --- a/intern/cycles/kernel/light/tree.h +++ b/intern/cycles/kernel/light/tree.h @@ -47,11 +47,6 @@ ccl_device float light_tree_cos_bounding_box_angle(const BoundingBox bbox, return cos_theta_u; } -ccl_device_forceinline float sin_from_cos(const float c) -{ - return safe_sqrtf(1.0f - sqr(c)); -} - /* Compute vector v as in Fig .8. P_v is the corresponding point along the ray. */ ccl_device float3 compute_v( const float3 centroid, const float3 P, const float3 D, const float3 bcone_axis, const float t) diff --git a/intern/cycles/kernel/light/triangle.h b/intern/cycles/kernel/light/triangle.h index 298a94566fc..b6724c6d6e1 100644 --- a/intern/cycles/kernel/light/triangle.h +++ b/intern/cycles/kernel/light/triangle.h @@ -218,7 +218,7 @@ ccl_device_forceinline bool triangle_light_sample(KernelGlobals kg, /* Finally, select a random point along the edge of the new triangle * That point on the spherical triangle is the sampled ray direction */ const float z = 1.0f - randv * (1.0f - dot(C_, B)); - ls->D = z * B + safe_sqrtf(1.0f - z * z) * safe_normalize(C_ - dot(C_, B) * B); + ls->D = z * B + sin_from_cos(z) * safe_normalize(C_ - dot(C_, B) * B); /* calculate intersection with the planar triangle */ if (!ray_triangle_intersect( diff --git a/intern/cycles/kernel/sample/mapping.h b/intern/cycles/kernel/sample/mapping.h index 94e691aa1a8..1cd7bce11d2 100644 --- a/intern/cycles/kernel/sample/mapping.h +++ b/intern/cycles/kernel/sample/mapping.h @@ -67,17 +67,18 @@ ccl_device_inline void sample_uniform_cone(const float3 N, ccl_private float3 *wo, ccl_private float *pdf) { - float zMin = cosf(angle); - float z = zMin - zMin * randu + randu; - float r = safe_sqrtf(1.0f - sqr(z)); - float phi = M_2PI_F * randv; - float x = r * cosf(phi); - float y = r * sinf(phi); + const float cosThetaMin = cosf(angle); + const float cosTheta = mix(cosThetaMin, 1.0f, randu); + const float sinTheta = sin_from_cos(cosTheta); + const float phi = M_2PI_F * randv; + const float x = sinTheta * cosf(phi); + const float y = sinTheta * sinf(phi); + const float z = cosTheta; float3 T, B; make_orthonormals(N, &T, &B); *wo = x * T + y * B + z * N; - *pdf = M_1_2PI_F / (1.0f - zMin); + *pdf = M_1_2PI_F / (1.0f - cosThetaMin); } ccl_device_inline float pdf_uniform_cone(const float3 N, float3 D, float angle) diff --git a/intern/cycles/util/math.h b/intern/cycles/util/math.h index 2eeb4aebd54..3618daa4ccb 100644 --- a/intern/cycles/util/math.h +++ b/intern/cycles/util/math.h @@ -750,6 +750,16 @@ ccl_device_inline float sqr(float a) return a * a; } +ccl_device_inline float sin_from_cos(const float c) +{ + return safe_sqrtf(1.0f - sqr(c)); +} + +ccl_device_inline float cos_from_sin(const float s) +{ + return safe_sqrtf(1.0f - sqr(s)); +} + ccl_device_inline float pow20(float a) { return sqr(sqr(sqr(sqr(a)) * a)); From fdcb55b28593f82b1d96c6df8f22de9ad5fdd2fa Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Tue, 24 Jan 2023 00:03:50 +0100 Subject: [PATCH 0916/1522] Cycles: Switch microfacet code to non-separable shadowing-masking term This gives closer results to what I've seen in papers and other renderers when using the code to precompute albedo later (to replace MultiGGX). It's usually a tiny difference, the only case where I've seen it matter is in the `shader/node_group_float.blend` test - but that's a (single-scatter) GGX closure with 0.9 roughness, so it's not too surprising. In any case, the new result looks closer to Eevee, so that's good I guess. Differential Revision: https://developer.blender.org/D17099 --- .../cycles/kernel/closure/bsdf_microfacet.h | 90 ++++++++++--------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index db53a29cfc3..75167b9d816 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -46,7 +46,7 @@ ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals kg, float randv, ccl_private float *slope_x, ccl_private float *slope_y, - ccl_private float *G1i) + ccl_private float *lambda_i) { /* Special case (normal incidence). */ if (cos_theta_i >= 0.99999f) { @@ -54,7 +54,7 @@ ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals kg, const float phi = M_2PI_F * randv; *slope_x = r * cosf(phi); *slope_y = r * sinf(phi); - *G1i = 1.0f; + *lambda_i = 0.0f; return; } @@ -67,9 +67,8 @@ ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals kg, const float exp_a2 = expf(-cot_theta_i * cot_theta_i); const float SQRT_PI_INV = 0.56418958354f; const float Lambda = 0.5f * (erf_a - 1.0f) + (0.5f * SQRT_PI_INV) * (exp_a2 * inv_a); - const float G1 = 1.0f / (1.0f + Lambda); /* masking */ - *G1i = G1; + *lambda_i = Lambda; /* Based on paper from Wenzel Jakob * An Improved Visible Normal Sampling Routine for the Beckmann Distribution @@ -132,7 +131,7 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, float randv, ccl_private float *slope_x, ccl_private float *slope_y, - ccl_private float *G1i) + ccl_private float *lambda_i) { /* Special case (normal incidence). */ if (cos_theta_i >= 0.99999f) { @@ -140,7 +139,7 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, const float phi = M_2PI_F * randv; *slope_x = r * cosf(phi); *slope_y = r * sinf(phi); - *G1i = 1.0f; + *lambda_i = 0.0f; return; } @@ -149,7 +148,7 @@ ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, const float tan_theta_i = sin_theta_i / cos_theta_i; const float G1_inv = 0.5f * (1.0f + safe_sqrtf(1.0f + tan_theta_i * tan_theta_i)); - *G1i = 1.0f / G1_inv; + *lambda_i = G1_inv - 1.0f; /* Sample slope_x. */ const float A = 2.0f * randu * G1_inv - 1.0f; @@ -186,7 +185,7 @@ ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, const float alpha_y, const float randu, const float randv, - ccl_private float *G1i) + ccl_private float *lambda_i) { /* 1. stretch wi */ float3 wi_ = make_float3(alpha_x * wi.x, alpha_y * wi.y, wi.z); @@ -212,10 +211,10 @@ ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, if (m_type == MicrofacetType::BECKMANN) { microfacet_beckmann_sample_slopes( - kg, costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i); + kg, costheta_, sintheta_, randu, randv, &slope_x, &slope_y, lambda_i); } else { - microfacet_ggx_sample_slopes(costheta_, sintheta_, randu, randv, &slope_x, &slope_y, G1i); + microfacet_ggx_sample_slopes(costheta_, sintheta_, randu, randv, &slope_x, &slope_y, lambda_i); } /* 3. rotate */ @@ -271,37 +270,48 @@ ccl_device_forceinline float bsdf_clearcoat_D(float alpha2, float cos_NH) return (alpha2 - 1.0f) / (M_PI_F * logf(alpha2) * t); } -/* Monodirectional shadowing-masking term. */ +/* Smith shadowing-masking term, here in the non-separable form. + * For details, see: + * Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs. + * Eric Heitz, JCGT Vol. 3, No. 2, 2014. + * https://jcgt.org/published/0003/02/03/ */ template -ccl_device_inline float bsdf_G1_from_sqr_alpha_tan_n(float sqr_alpha_tan_n) +ccl_device_inline float bsdf_lambda_from_sqr_alpha_tan_n(float sqr_alpha_tan_n) { if (m_type == MicrofacetType::GGX) { - return 2.0f / (1.0f + sqrtf(1.0f + sqr_alpha_tan_n)); + /* Equation 72. */ + return 0.5f * (sqrtf(1.0f + sqr_alpha_tan_n) - 1.0f); } else { - /* m_type == MicrofacetType::BECKMANN */ + /* m_type == MicrofacetType::BECKMANN + * Approximation from below Equation 69. */ + if (sqr_alpha_tan_n < 0.39f) { + /* Equivalent to a >= 1.6f, but also handles sqr_alpha_tan_n == 0.0f cleanly. */ + return 0.0f; + } + const float a = inversesqrtf(sqr_alpha_tan_n); - return (a > 1.6f) ? 1.0f : ((2.181f * a + 3.535f) * a) / ((2.577f * a + 2.276f) * a + 1.0f); + return ((0.396f * a - 1.259f) * a + 1.0f) / ((2.181f * a + 3.535f) * a); } } -template ccl_device_inline float bsdf_G1(float alpha2, float cos_N) +template ccl_device_inline float bsdf_lambda(float alpha2, float cos_N) { - return bsdf_G1_from_sqr_alpha_tan_n(alpha2 * fmaxf(1.0f / (cos_N * cos_N) - 1.0f, 0.0f)); + return bsdf_lambda_from_sqr_alpha_tan_n(alpha2 * fmaxf(1.0f / sqr(cos_N) - 1.0f, 0.0f)); } template -ccl_device_inline float bsdf_aniso_G1(float alpha_x, float alpha_y, float3 V) +ccl_device_inline float bsdf_aniso_lambda(float alpha_x, float alpha_y, float3 V) { - return bsdf_G1_from_sqr_alpha_tan_n((sqr(alpha_x * V.x) + sqr(alpha_y * V.y)) / - sqr(V.z)); + const float sqr_alpha_tan_n = (sqr(alpha_x * V.x) + sqr(alpha_y * V.y)) / sqr(V.z); + return bsdf_lambda_from_sqr_alpha_tan_n(sqr_alpha_tan_n); } -/* Smith's separable shadowing-masking term. */ +/* Combined shadowing-masking term. */ template ccl_device_inline float bsdf_G(float alpha2, float cos_NI, float cos_NO) { - return bsdf_G1(alpha2, cos_NI) * bsdf_G1(alpha2, cos_NO); + return 1.0f / (1.0f + bsdf_lambda(alpha2, cos_NI) + bsdf_lambda(alpha2, cos_NO)); } /* Normal distribution function. */ @@ -382,7 +392,7 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, H *= inv_len_H; const float cos_NH = dot(N, H); - float D, G1i, G1o; + float D, lambdaI, lambdaO; /* TODO: add support for anisotropic transmission. */ if (alpha_x == alpha_y || m_refractive) { /* Isotropic. */ @@ -399,8 +409,8 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, D = bsdf_D(alpha2, cos_NH); } - G1i = bsdf_G1(alpha2, cos_NI); - G1o = bsdf_G1(alpha2, cos_NO); + lambdaI = bsdf_lambda(alpha2, cos_NI); + lambdaO = bsdf_lambda(alpha2, cos_NO); } else { /* Anisotropic. */ float3 X, Y; @@ -412,20 +422,20 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, D = bsdf_aniso_D(alpha_x, alpha_y, local_H); - G1i = bsdf_aniso_G1(alpha_x, alpha_y, local_I); - G1o = bsdf_aniso_G1(alpha_x, alpha_y, local_O); + lambdaI = bsdf_aniso_lambda(alpha_x, alpha_y, local_I); + lambdaO = bsdf_aniso_lambda(alpha_x, alpha_y, local_O); } - const float common = G1i * D / cos_NI * + const float common = D / cos_NI * (m_refractive ? sqr(bsdf->ior * inv_len_H) * fabsf(dot(H, wi) * dot(H, wo)) : 0.25f); - *pdf = common; + *pdf = common / (1.0f + lambdaI); const Spectrum F = m_refractive ? one_spectrum() : reflection_color(bsdf, wo, H); - return F * G1o * common; + return F * common / (1.0f + lambdaO + lambdaI); } template @@ -466,10 +476,10 @@ ccl_device int bsdf_microfacet_sample(KernelGlobals kg, /* Importance sampling with distribution of visible normals. Vectors are transformed to local * space before and after sampling. */ - float G1i; + float lambdaI; const float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI); const float3 local_H = microfacet_sample_stretched( - kg, local_I, alpha_x, alpha_y, randu, randv, &G1i); + kg, local_I, alpha_x, alpha_y, randu, randv, &lambdaI); const float3 H = X * local_H.x + Y * local_H.y + N * local_H.z; const float cos_NH = local_H.z; @@ -514,7 +524,7 @@ ccl_device int bsdf_microfacet_sample(KernelGlobals kg, else { label |= LABEL_GLOSSY; float cos_NO = dot(N, *wo); - float D, G1o; + float D, lambdaO; /* TODO: add support for anisotropic transmission. */ if (alpha_x == alpha_y || m_refractive) { /* Isotropic. */ @@ -527,33 +537,33 @@ ccl_device int bsdf_microfacet_sample(KernelGlobals kg, * => alpha2 = 0.25 * 0.25 */ alpha2 = 0.0625f; - /* Recalculate G1i. */ - G1i = bsdf_G1(alpha2, cos_NI); + /* Recalculate lambdaI. */ + lambdaI = bsdf_lambda(alpha2, cos_NI); } else { D = bsdf_D(alpha2, cos_NH); } - G1o = bsdf_G1(alpha2, cos_NO); + lambdaO = bsdf_lambda(alpha2, cos_NO); } else { /* Anisotropic. */ const float3 local_O = make_float3(dot(X, *wo), dot(Y, *wo), cos_NO); D = bsdf_aniso_D(alpha_x, alpha_y, local_H); - G1o = bsdf_aniso_G1(alpha_x, alpha_y, local_O); + lambdaO = bsdf_aniso_lambda(alpha_x, alpha_y, local_O); } const float cos_HO = dot(H, *wo); - const float common = G1i * D / cos_NI * + const float common = D / cos_NI * (m_refractive ? fabsf(cos_HI * cos_HO) / sqr(cos_HO + cos_HI / m_eta) : 0.25f); - *pdf = common; + *pdf = common / (1.0f + lambdaI); Spectrum F = m_refractive ? one_spectrum() : reflection_color(bsdf, *wo, H); - *eval = G1o * common * F; + *eval = F * common / (1.0f + lambdaI + lambdaO); } *sampled_roughness = make_float2(alpha_x, alpha_y); From e308b891c8829e08ad023eff7ed43f7acac3ae03 Mon Sep 17 00:00:00 2001 From: Lukas Stockner Date: Tue, 24 Jan 2023 17:34:24 +0100 Subject: [PATCH 0917/1522] Cycles: Use faster and exact GGX VNDF sampling algorithm Based on "Sampling the GGX Distribution of Visible Normals" by Eric Heitz (https://jcgt.org/published/0007/04/01/). Also, this removes the lambdaI computation from the Beckmann sampling code and just recomputes it below. We already need to recompute for two other cases (GGX and clearcoat), so this makes the code more consistent. In terms of performance, I don't expect a notable impact since the earlier computation also was non-trivial, and while it probably was slightly more accurate, I'd argue that being consistent between evaluation and sampling is more important than absolute numerical accuracy anyways. Differential Revision: https://developer.blender.org/D17100 --- .../cycles/kernel/closure/bsdf_microfacet.h | 302 ++++++++---------- intern/cycles/util/math_float2.h | 5 + 2 files changed, 132 insertions(+), 175 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 75167b9d816..8cf4cfa244d 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -37,189 +37,100 @@ typedef struct MicrofacetBsdf { static_assert(sizeof(ShaderClosure) >= sizeof(MicrofacetBsdf), "MicrofacetBsdf is too large!"); -/* Beckmann and GGX microfacet importance sampling. */ - -ccl_device_inline void microfacet_beckmann_sample_slopes(KernelGlobals kg, - const float cos_theta_i, - const float sin_theta_i, - float randu, - float randv, - ccl_private float *slope_x, - ccl_private float *slope_y, - ccl_private float *lambda_i) -{ - /* Special case (normal incidence). */ - if (cos_theta_i >= 0.99999f) { - const float r = sqrtf(-logf(randu)); - const float phi = M_2PI_F * randv; - *slope_x = r * cosf(phi); - *slope_y = r * sinf(phi); - *lambda_i = 0.0f; - - return; - } - - /* Precomputations. */ - const float tan_theta_i = sin_theta_i / cos_theta_i; - const float inv_a = tan_theta_i; - const float cot_theta_i = 1.0f / tan_theta_i; - const float erf_a = fast_erff(cot_theta_i); - const float exp_a2 = expf(-cot_theta_i * cot_theta_i); - const float SQRT_PI_INV = 0.56418958354f; - const float Lambda = 0.5f * (erf_a - 1.0f) + (0.5f * SQRT_PI_INV) * (exp_a2 * inv_a); - - *lambda_i = Lambda; - - /* Based on paper from Wenzel Jakob - * An Improved Visible Normal Sampling Routine for the Beckmann Distribution - * - * http://www.mitsuba-renderer.org/~wenzel/files/visnormal.pdf - * - * Reformulation from OpenShadingLanguage which avoids using inverse - * trigonometric functions. - */ - - /* Sample slope X. - * - * Compute a coarse approximation using the approximation: - * exp(-ierf(x)^2) ~= 1 - x * x - * solve y = 1 + b + K * (1 - b * b) - */ - const float K = tan_theta_i * SQRT_PI_INV; - const float y_approx = randu * (1.0f + erf_a + K * (1 - erf_a * erf_a)); - const float y_exact = randu * (1.0f + erf_a + K * exp_a2); - float b = K > 0 ? (0.5f - sqrtf(K * (K - y_approx + 1.0f) + 0.25f)) / K : y_approx - 1.0f; - - float inv_erf = fast_ierff(b); - float2 begin = make_float2(-1.0f, -y_exact); - float2 end = make_float2(erf_a, 1.0f + erf_a + K * exp_a2 - y_exact); - float2 current = make_float2(b, 1.0f + b + K * expf(-sqr(inv_erf)) - y_exact); - - /* Find root in a monotonic interval using newton method, under given precision and maximal - * iterations. Falls back to bisection if newton step produces results outside of the valid - * interval.*/ - const float precision = 1e-6f; - const int max_iter = 3; - int iter = 0; - while (fabsf(current.y) > precision && iter++ < max_iter) { - if (signf(begin.y) == signf(current.y)) { - begin.x = current.x; - begin.y = current.y; - } - else { - end.x = current.x; - } - const float newton_x = current.x - current.y / (1.0f - inv_erf * tan_theta_i); - current.x = (newton_x >= begin.x && newton_x <= end.x) ? newton_x : 0.5f * (begin.x + end.x); - inv_erf = fast_ierff(current.x); - current.y = 1.0f + current.x + K * expf(-sqr(inv_erf)) - y_exact; - } - - *slope_x = inv_erf; - *slope_y = fast_ierff(2.0f * randv - 1.0f); -} - -/* GGX microfacet importance sampling from: - * +/* Beckmann VNDF importance sampling algorithm from: * Importance Sampling Microfacet-Based BSDFs using the Distribution of Visible Normals. - * E. Heitz and E. d'Eon, EGSR 2014 - */ + * Eric Heitz and Eugene d'Eon, EGSR 2014. + * https://hal.inria.fr/hal-00996995v2/document */ -ccl_device_inline void microfacet_ggx_sample_slopes(const float cos_theta_i, - const float sin_theta_i, - float randu, - float randv, - ccl_private float *slope_x, - ccl_private float *slope_y, - ccl_private float *lambda_i) -{ - /* Special case (normal incidence). */ - if (cos_theta_i >= 0.99999f) { - const float r = sqrtf(randu / (1.0f - randu)); - const float phi = M_2PI_F * randv; - *slope_x = r * cosf(phi); - *slope_y = r * sinf(phi); - *lambda_i = 0.0f; - - return; - } - - /* Precomputations. */ - const float tan_theta_i = sin_theta_i / cos_theta_i; - const float G1_inv = 0.5f * (1.0f + safe_sqrtf(1.0f + tan_theta_i * tan_theta_i)); - - *lambda_i = G1_inv - 1.0f; - - /* Sample slope_x. */ - const float A = 2.0f * randu * G1_inv - 1.0f; - const float AA = A * A; - const float tmp = 1.0f / (AA - 1.0f); - const float B = tan_theta_i; - const float BB = B * B; - const float D = safe_sqrtf(BB * (tmp * tmp) - (AA - BB) * tmp); - const float slope_x_1 = B * tmp - D; - const float slope_x_2 = B * tmp + D; - *slope_x = (A < 0.0f || slope_x_2 * tan_theta_i > 1.0f) ? slope_x_1 : slope_x_2; - - /* Sample slope_y. */ - float S; - - if (randv > 0.5f) { - S = 1.0f; - randv = 2.0f * (randv - 0.5f); - } - else { - S = -1.0f; - randv = 2.0f * (0.5f - randv); - } - - const float z = (randv * (randv * (randv * 0.27385f - 0.73369f) + 0.46341f)) / - (randv * (randv * (randv * 0.093073f + 0.309420f) - 1.000000f) + 0.597999f); - *slope_y = S * z * safe_sqrtf(1.0f + (*slope_x) * (*slope_x)); -} - -template -ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, - const float3 wi, - const float alpha_x, - const float alpha_y, - const float randu, - const float randv, - ccl_private float *lambda_i) +ccl_device_forceinline float3 microfacet_beckmann_sample_vndf(KernelGlobals kg, + const float3 wi, + const float alpha_x, + const float alpha_y, + const float randu, + const float randv) { /* 1. stretch wi */ float3 wi_ = make_float3(alpha_x * wi.x, alpha_y * wi.y, wi.z); wi_ = normalize(wi_); - /* Compute polar coordinates of wi_. */ - float costheta_ = 1.0f; - float sintheta_ = 0.0f; - float cosphi_ = 1.0f; - float sinphi_ = 0.0f; - - if (wi_.z < 0.99999f) { - costheta_ = wi_.z; - sintheta_ = sin_from_cos(costheta_); - - float invlen = 1.0f / sintheta_; - cosphi_ = wi_.x * invlen; - sinphi_ = wi_.y * invlen; - } - /* 2. sample P22_{wi}(x_slope, y_slope, 1, 1) */ float slope_x, slope_y; + float cos_phi_i = 1.0f; + float sin_phi_i = 0.0f; - if (m_type == MicrofacetType::BECKMANN) { - microfacet_beckmann_sample_slopes( - kg, costheta_, sintheta_, randu, randv, &slope_x, &slope_y, lambda_i); + if (wi_.z >= 0.99999f) { + /* Special case (normal incidence). */ + const float r = sqrtf(-logf(randu)); + const float phi = M_2PI_F * randv; + slope_x = r * cosf(phi); + slope_y = r * sinf(phi); } else { - microfacet_ggx_sample_slopes(costheta_, sintheta_, randu, randv, &slope_x, &slope_y, lambda_i); + /* Precomputations. */ + const float cos_theta_i = wi_.z; + const float sin_theta_i = sin_from_cos(cos_theta_i); + const float tan_theta_i = sin_theta_i / cos_theta_i; + const float cot_theta_i = 1.0f / tan_theta_i; + const float erf_a = fast_erff(cot_theta_i); + const float exp_a2 = expf(-cot_theta_i * cot_theta_i); + const float SQRT_PI_INV = 0.56418958354f; + + float invlen = 1.0f / sin_theta_i; + cos_phi_i = wi_.x * invlen; + sin_phi_i = wi_.y * invlen; + + /* Based on paper from Wenzel Jakob + * An Improved Visible Normal Sampling Routine for the Beckmann Distribution + * + * http://www.mitsuba-renderer.org/~wenzel/files/visnormal.pdf + * + * Reformulation from OpenShadingLanguage which avoids using inverse + * trigonometric functions. + */ + + /* Sample slope X. + * + * Compute a coarse approximation using the approximation: + * exp(-ierf(x)^2) ~= 1 - x * x + * solve y = 1 + b + K * (1 - b * b) + */ + const float K = tan_theta_i * SQRT_PI_INV; + const float y_approx = randu * (1.0f + erf_a + K * (1 - erf_a * erf_a)); + const float y_exact = randu * (1.0f + erf_a + K * exp_a2); + float b = K > 0 ? (0.5f - sqrtf(K * (K - y_approx + 1.0f) + 0.25f)) / K : y_approx - 1.0f; + + float inv_erf = fast_ierff(b); + float2 begin = make_float2(-1.0f, -y_exact); + float2 end = make_float2(erf_a, 1.0f + erf_a + K * exp_a2 - y_exact); + float2 current = make_float2(b, 1.0f + b + K * expf(-sqr(inv_erf)) - y_exact); + + /* Find root in a monotonic interval using newton method, under given precision and maximal + * iterations. Falls back to bisection if newton step produces results outside of the valid + * interval.*/ + const float precision = 1e-6f; + const int max_iter = 3; + int iter = 0; + while (fabsf(current.y) > precision && iter++ < max_iter) { + if (signf(begin.y) == signf(current.y)) { + begin.x = current.x; + begin.y = current.y; + } + else { + end.x = current.x; + } + const float newton_x = current.x - current.y / (1.0f - inv_erf * tan_theta_i); + current.x = (newton_x >= begin.x && newton_x <= end.x) ? newton_x : 0.5f * (begin.x + end.x); + inv_erf = fast_ierff(current.x); + current.y = 1.0f + current.x + K * expf(-sqr(inv_erf)) - y_exact; + } + + slope_x = inv_erf; + slope_y = fast_ierff(2.0f * randv - 1.0f); } /* 3. rotate */ - float tmp = cosphi_ * slope_x - sinphi_ * slope_y; - slope_y = sinphi_ * slope_x + cosphi_ * slope_y; + float tmp = cos_phi_i * slope_x - sin_phi_i * slope_y; + slope_y = sin_phi_i * slope_x + cos_phi_i * slope_y; slope_x = tmp; /* 4. unstretch */ @@ -230,6 +141,43 @@ ccl_device_forceinline float3 microfacet_sample_stretched(KernelGlobals kg, return normalize(make_float3(-slope_x, -slope_y, 1.0f)); } +/* GGX VNDF importance sampling algorithm from: + * Sampling the GGX Distribution of Visible Normals. + * Eric Heitz, JCGT Vol. 7, No. 4, 2018. + * https://jcgt.org/published/0007/04/01/ */ +ccl_device_forceinline float3 microfacet_ggx_sample_vndf(const float3 wi, + const float alpha_x, + const float alpha_y, + const float randu, + const float randv) +{ + /* Section 3.2: Transforming the view direction to the hemisphere configuration. */ + float3 wi_ = normalize(make_float3(alpha_x * wi.x, alpha_y * wi.y, wi.z)); + + /* Section 4.1: Orthonormal basis. */ + float lensq = sqr(wi_.x) + sqr(wi_.y); + float3 T1, T2; + if (lensq > 1e-7f) { + T1 = make_float3(-wi_.y, wi_.x, 0.0f) * inversesqrtf(lensq); + T2 = cross(wi_, T1); + } + else { + /* Normal incidence, any basis is fine. */ + T1 = make_float3(1.0f, 0.0f, 0.0f); + T2 = make_float3(0.0f, 1.0f, 0.0f); + } + + /* Section 4.2: Parameterization of the projected area. */ + float2 t = concentric_sample_disk(randu, randv); + t.y = mix(safe_sqrtf(1.0f - sqr(t.x)), t.y, 0.5f * (1.0f + wi_.z)); + + /* Section 4.3: Reprojection onto hemisphere. */ + float3 H_ = t.x * T1 + t.y * T2 + safe_sqrtf(1.0f - len_squared(t)) * wi_; + + /* Section 3.4: Transforming the normal back to the ellipsoid configuration. */ + return normalize(make_float3(alpha_x * H_.x, alpha_y * H_.y, max(0.0f, H_.z))); +} + /* Calculate the reflection color * * If fresnel is used, the color is an interpolation of the F0 color and white @@ -476,10 +424,15 @@ ccl_device int bsdf_microfacet_sample(KernelGlobals kg, /* Importance sampling with distribution of visible normals. Vectors are transformed to local * space before and after sampling. */ - float lambdaI; const float3 local_I = make_float3(dot(X, wi), dot(Y, wi), cos_NI); - const float3 local_H = microfacet_sample_stretched( - kg, local_I, alpha_x, alpha_y, randu, randv, &lambdaI); + float3 local_H; + if (m_type == MicrofacetType::GGX) { + local_H = microfacet_ggx_sample_vndf(local_I, alpha_x, alpha_y, randu, randv); + } + else { + /* m_type == MicrofacetType::BECKMANN */ + local_H = microfacet_beckmann_sample_vndf(kg, local_I, alpha_x, alpha_y, randu, randv); + } const float3 H = X * local_H.x + Y * local_H.y + N * local_H.z; const float cos_NH = local_H.z; @@ -524,7 +477,7 @@ ccl_device int bsdf_microfacet_sample(KernelGlobals kg, else { label |= LABEL_GLOSSY; float cos_NO = dot(N, *wo); - float D, lambdaO; + float D, lambdaI, lambdaO; /* TODO: add support for anisotropic transmission. */ if (alpha_x == alpha_y || m_refractive) { /* Isotropic. */ @@ -536,15 +489,13 @@ ccl_device int bsdf_microfacet_sample(KernelGlobals kg, /* The masking-shadowing term for clearcoat has a fixed alpha of 0.25 * => alpha2 = 0.25 * 0.25 */ alpha2 = 0.0625f; - - /* Recalculate lambdaI. */ - lambdaI = bsdf_lambda(alpha2, cos_NI); } else { D = bsdf_D(alpha2, cos_NH); } lambdaO = bsdf_lambda(alpha2, cos_NO); + lambdaI = bsdf_lambda(alpha2, cos_NI); } else { /* Anisotropic. */ const float3 local_O = make_float3(dot(X, *wo), dot(Y, *wo), cos_NO); @@ -552,6 +503,7 @@ ccl_device int bsdf_microfacet_sample(KernelGlobals kg, D = bsdf_aniso_D(alpha_x, alpha_y, local_H); lambdaO = bsdf_aniso_lambda(alpha_x, alpha_y, local_O); + lambdaI = bsdf_aniso_lambda(alpha_x, alpha_y, local_I); } const float cos_HO = dot(H, *wo); diff --git a/intern/cycles/util/math_float2.h b/intern/cycles/util/math_float2.h index ad806d0f08a..45391f6848a 100644 --- a/intern/cycles/util/math_float2.h +++ b/intern/cycles/util/math_float2.h @@ -134,6 +134,11 @@ ccl_device_inline float len(const float2 a) return sqrtf(dot(a, a)); } +ccl_device_inline float len_squared(const float2 a) +{ + return dot(a, a); +} + #if !defined(__KERNEL_METAL__) ccl_device_inline float distance(const float2 a, const float2 b) { From 30b34735e3158afac21c04da62b7f048918e062c Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 24 Jan 2023 17:22:57 +0100 Subject: [PATCH 0918/1522] Cleanup/refactor: Add a new flag for IDTypes that are not read in memfile undo. Currently only affects 'UI' IDs (WindowManager, Screen, etc.), but in the future other types may be affected as well. NOTE: this is only used in readfile code itself, not in the post-processing performed by `setup_app_data`, as this code is too specific for such generic handling. --- source/blender/blenkernel/BKE_idtype.h | 9 +++++++++ source/blender/blenkernel/intern/screen.c | 3 ++- source/blender/blenkernel/intern/workspace.cc | 3 ++- source/blender/blenloader/intern/readfile.cc | 4 ++-- source/blender/windowmanager/intern/wm.c | 3 ++- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/source/blender/blenkernel/BKE_idtype.h b/source/blender/blenkernel/BKE_idtype.h index 256ddec5505..be13a3c1d2a 100644 --- a/source/blender/blenkernel/BKE_idtype.h +++ b/source/blender/blenkernel/BKE_idtype.h @@ -39,6 +39,15 @@ enum { IDTYPE_FLAGS_APPEND_IS_REUSABLE = 1 << 3, /** Indicates that the given IDType does not have animation data. */ IDTYPE_FLAGS_NO_ANIMDATA = 1 << 4, + /** + * Indicates that the given IDType is not handled through memfile (aka global) undo. + * + * \note This currently only affect local data-blocks. + * + * \note Current readfile undo code expects these data-blocks to not be used by any 'regular' + * data-blocks. + */ + IDTYPE_FLAGS_NO_MEMFILE_UNDO = 1 << 5, }; typedef struct IDCacheKey { diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 2c896788b20..95ef6b7b925 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -279,7 +279,8 @@ IDTypeInfo IDType_ID_SCR = { .name = "Screen", .name_plural = "screens", .translation_context = BLT_I18NCONTEXT_ID_SCREEN, - .flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_ONLY_APPEND | IDTYPE_FLAGS_NO_ANIMDATA, + .flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_ONLY_APPEND | IDTYPE_FLAGS_NO_ANIMDATA | + IDTYPE_FLAGS_NO_MEMFILE_UNDO, .asset_type_info = NULL, .init_data = NULL, diff --git a/source/blender/blenkernel/intern/workspace.cc b/source/blender/blenkernel/intern/workspace.cc index 4b617a15e7e..fb5d4f09a2f 100644 --- a/source/blender/blenkernel/intern/workspace.cc +++ b/source/blender/blenkernel/intern/workspace.cc @@ -193,7 +193,8 @@ IDTypeInfo IDType_ID_WS = { /*name*/ "WorkSpace", /*name_plural*/ "workspaces", /*translation_context*/ BLT_I18NCONTEXT_ID_WORKSPACE, - /*flags*/ IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_ONLY_APPEND | IDTYPE_FLAGS_NO_ANIMDATA, + /*flags*/ IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_ONLY_APPEND | IDTYPE_FLAGS_NO_ANIMDATA | + IDTYPE_FLAGS_NO_MEMFILE_UNDO, /*asset_type_info*/ nullptr, /*init_data*/ workspace_init_data, diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index f4a5b6dd2fc..1b6c896458a 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -3195,7 +3195,7 @@ static bool read_libblock_undo_restore( { /* Get pointer to memory of new ID that we will be reading. */ const ID *id = static_cast(peek_struct_undo(fd, bhead)); - const short idcode = GS(id->name); + const IDTypeInfo *id_type = BKE_idtype_get_info_from_id(id); if (bhead->code == ID_LI) { /* Restore library datablock. */ @@ -3209,7 +3209,7 @@ static bool read_libblock_undo_restore( return true; } } - else if (ELEM(idcode, ID_WM, ID_SCR, ID_WS)) { + else if (id_type->flags & IDTYPE_FLAGS_NO_MEMFILE_UNDO) { /* Skip reading any UI datablocks, existing ones are kept. We don't * support pointers from other datablocks to UI datablocks so those * we also don't put UI datablocks in fd->libmap. */ diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index bd480526f9f..aad7cc6ac93 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -265,7 +265,8 @@ IDTypeInfo IDType_ID_WM = { .name = "WindowManager", .name_plural = "window_managers", .translation_context = BLT_I18NCONTEXT_ID_WINDOWMANAGER, - .flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_LIBLINKING | IDTYPE_FLAGS_NO_ANIMDATA, + .flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_LIBLINKING | IDTYPE_FLAGS_NO_ANIMDATA | + IDTYPE_FLAGS_NO_MEMFILE_UNDO, .asset_type_info = NULL, .init_data = NULL, From e56f284843e59810d53c0b7ebad826bf5296989a Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 24 Jan 2023 17:53:27 +0100 Subject: [PATCH 0919/1522] readfile: Fix 'virtual' issue in memfile case. In many cases when reading undo memfile, n the 'restore id from old main' part of the process, the 'id_old' is not set, which means that the call to `BKE_main_idmap_insert_id` would try to dereference a `nullptr`. In practice this is likely not an issue (see comment in code for details), but at least explicitely check for a nullptr `id_old` pointer. Would deffer actual cleanup of this area for after 3.5 is branched out. --- source/blender/blenloader/intern/readfile.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 1b6c896458a..2ffe8386166 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -3289,11 +3289,23 @@ static BHead *read_libblock(FileData *fd, * address and inherit recalc flags for the dependency graph. */ ID *id_old = nullptr; if (fd->flags & FD_FLAGS_IS_MEMFILE) { + /* FIXME `read_libblock_undo_restore` currently often skips setting `id_old` even if there + * would be a valid matching old ID (libraries, linked data, and `IDTYPE_FLAGS_NO_MEMFILE_UNDO` + * id types, at least). + * + * It is unclear whether this is currently an issue: + * * `r_id` is currently only requested by linking code (both independent one, and as part of + * loading .blend file through `read_library_linked_ids`). + * * `main->id_map` seems to always be `nullptr` in undo case at this point. + * + * So undo case does not seem to be affected by this. A future cleanup should try to remove + * most of this related code in the future, and instead assert that both `r_id` and + * `main->id_map` are `nullptr`. */ if (read_libblock_undo_restore(fd, main, bhead, tag, &id_old)) { if (r_id) { *r_id = id_old; } - if (main->id_map != nullptr) { + if (main->id_map != nullptr && id_old != nullptr) { BKE_main_idmap_insert_id(main->id_map, id_old); } From a73a2d345fffa89375e6838405b1e82cac76a8c2 Mon Sep 17 00:00:00 2001 From: Martijn Versteegh Date: Tue, 24 Jan 2023 11:14:41 +0100 Subject: [PATCH 0920/1522] Fix T104044: keep order of UVMaps on load Use a Vector , instead of a Set as a Set does not keep the same order when iterating over it. Differential Revision: https://developer.blender.org/D17103 --- source/blender/blenkernel/intern/mesh_legacy_convert.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index be68bfe7c65..a60dfa3a19c 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -1616,9 +1616,9 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh) const std::string default_uv = StringRef( CustomData_get_render_layer_name(&mesh->ldata, CD_MLOOPUV)); - Set uv_layers_to_convert; + Vector uv_layers_to_convert; for (const int uv_layer_i : IndexRange(CustomData_number_of_layers(&mesh->ldata, CD_MLOOPUV))) { - uv_layers_to_convert.add_as(CustomData_get_layer_name(&mesh->ldata, CD_MLOOPUV, uv_layer_i)); + uv_layers_to_convert.append(CustomData_get_layer_name(&mesh->ldata, CD_MLOOPUV, uv_layer_i)); } for (const StringRefNull name : uv_layers_to_convert) { From 789ab9b92aff9a576a3d926583b1446827937fa9 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Tue, 24 Jan 2023 11:03:21 -0800 Subject: [PATCH 0921/1522] Sculpt: Fix T104090: Automask topology not constrained by brush radius --- release/datafiles/locale | 2 +- release/scripts/addons | 2 +- .../sculpt_paint/sculpt_automasking.cc | 74 ++++++++++++++++++- .../editors/sculpt_paint/sculpt_intern.h | 2 + 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/release/datafiles/locale b/release/datafiles/locale index f1425d8a7fc..08b372721b9 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit f1425d8a7fc38e8111c2a9e125f0e7877dcd0fdf +Subproject commit 08b372721b9b33a16f380cab23b2e5ded738ea96 diff --git a/release/scripts/addons b/release/scripts/addons index c0a678d3686..d887a4ea6b2 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit c0a678d3686a591eb3041cc72b60aec2857d389a +Subproject commit d887a4ea6b2a9d64b926034d4e78ecf7a48ca979 diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.cc b/source/blender/editors/sculpt_paint/sculpt_automasking.cc index 62c27a5ffeb..6b030d8a5b7 100644 --- a/source/blender/editors/sculpt_paint/sculpt_automasking.cc +++ b/source/blender/editors/sculpt_paint/sculpt_automasking.cc @@ -177,11 +177,29 @@ static float sculpt_automasking_normal_calc(SculptSession *ss, return 1.0f; } +static bool sculpt_automasking_is_constrained_by_radius(const Brush *br) +{ + /* 2D falloff is not constrained by radius. */ + if (br->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) { + return false; + } + + if (ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE)) { + return true; + } + return false; +} + static bool SCULPT_automasking_needs_factors_cache(const Sculpt *sd, const Brush *brush) { const int automasking_flags = sculpt_automasking_mode_effective_bits(sd, brush); + if (automasking_flags & BRUSH_AUTOMASKING_TOPOLOGY && + sculpt_automasking_is_constrained_by_radius(brush)) { + return true; + } + if (automasking_flags & (BRUSH_AUTOMASKING_BOUNDARY_EDGES | BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS | BRUSH_AUTOMASKING_VIEW_NORMAL)) { return brush && brush->automasking_boundary_edges_propagation_steps != 1; @@ -537,7 +555,8 @@ float SCULPT_automasking_factor_get(AutomaskingCache *automasking, return automasking_factor_end(ss, automasking, vert, 0.0f); } - if (automasking->settings.flags & BRUSH_AUTOMASKING_TOPOLOGY && + if (!automasking->settings.topology_use_brush_limit && + automasking->settings.flags & BRUSH_AUTOMASKING_TOPOLOGY && SCULPT_vertex_island_get(ss, vert) != automasking->settings.initial_island_nr) { return 0.0f; } @@ -592,6 +611,53 @@ struct AutomaskFloodFillData { char symm; }; +static bool automask_floodfill_cb( + SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool /*is_duplicate*/, void *userdata) +{ + AutomaskFloodFillData *data = (AutomaskFloodFillData *)userdata; + + *(float *)SCULPT_vertex_attr_get(to_v, ss->attrs.automasking_factor) = 1.0f; + *(float *)SCULPT_vertex_attr_get(from_v, ss->attrs.automasking_factor) = 1.0f; + return (!data->use_radius || + SCULPT_is_vertex_inside_brush_radius_symm( + SCULPT_vertex_co_get(ss, to_v), data->location, data->radius, data->symm)); +} + +static void SCULPT_topology_automasking_init(Sculpt *sd, Object *ob) +{ + SculptSession *ss = ob->sculpt; + Brush *brush = BKE_paint_brush(&sd->paint); + + if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) { + BLI_assert_unreachable(); + return; + } + + const int totvert = SCULPT_vertex_count_get(ss); + for (int i : IndexRange(totvert)) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + (*(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor)) = 0.0f; + } + + /* Flood fill automask to connected vertices. Limited to vertices inside + * the brush radius if the tool requires it. */ + SculptFloodFill flood; + SCULPT_floodfill_init(ss, &flood); + const float radius = ss->cache ? ss->cache->radius : FLT_MAX; + SCULPT_floodfill_add_active(sd, ob, ss, &flood, radius); + + AutomaskFloodFillData fdata = {0}; + + fdata.radius = radius; + fdata.use_radius = ss->cache && sculpt_automasking_is_constrained_by_radius(brush); + fdata.symm = SCULPT_mesh_symmetry_xyz_get(ob); + + copy_v3_v3(fdata.location, SCULPT_active_vertex_co_get(ss)); + SCULPT_floodfill_execute(ss, &flood, automask_floodfill_cb, &fdata); + SCULPT_floodfill_free(&flood); +} + static void sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob) { SculptSession *ss = ob->sculpt; @@ -866,7 +932,13 @@ AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object /* Additive modes. */ if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_TOPOLOGY)) { SCULPT_vertex_random_access_ensure(ss); + + if (sculpt_automasking_is_constrained_by_radius(brush)) { + automasking->settings.topology_use_brush_limit = true; + SCULPT_topology_automasking_init(sd, ob); + } } + if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_FACE_SETS)) { SCULPT_vertex_random_access_ensure(ss); sculpt_face_sets_automasking_init(sd, ob); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 2faf53072d6..64529525099 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -418,6 +418,8 @@ typedef struct AutomaskingSettings { float start_normal_limit, start_normal_falloff; float view_normal_limit, view_normal_falloff; + + bool topology_use_brush_limit; } AutomaskingSettings; typedef struct AutomaskingCache { From 361ebe98d5147ea918335bce0347e19d10d7276b Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Tue, 24 Jan 2023 15:45:07 +0100 Subject: [PATCH 0922/1522] Draw: Workbench Next: Fix shadow culling after recent cleanup commit 79ba1a1ac82d854d840e98141b2458e4c7e2a7dd changed virtual function signatures so they didn't match their parents. --- source/blender/draw/engines/workbench/workbench_private.hh | 6 ++++-- source/blender/draw/engines/workbench/workbench_shadow.cc | 6 +++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/blender/draw/engines/workbench/workbench_private.hh b/source/blender/draw/engines/workbench/workbench_private.hh index 94b609519d6..5d9de764d56 100644 --- a/source/blender/draw/engines/workbench/workbench_private.hh +++ b/source/blender/draw/engines/workbench/workbench_private.hh @@ -269,8 +269,10 @@ class ShadowPass { ShadowView(); protected: - virtual void compute_visibility(ObjectBoundsBuf &bounds, uint resource_len); - virtual VisibilityBuf &get_visibility_buffer(); + virtual void compute_visibility(ObjectBoundsBuf &bounds, + uint resource_len, + bool debug_freeze) override; + virtual VisibilityBuf &get_visibility_buffer() override; } view_ = {}; bool enabled_; diff --git a/source/blender/draw/engines/workbench/workbench_shadow.cc b/source/blender/draw/engines/workbench/workbench_shadow.cc index e4a409f1457..d13d717832e 100644 --- a/source/blender/draw/engines/workbench/workbench_shadow.cc +++ b/source/blender/draw/engines/workbench/workbench_shadow.cc @@ -202,8 +202,12 @@ void ShadowPass::ShadowView::set_mode(ShadowPass::PassType type) current_pass_type_ = type; } -void ShadowPass::ShadowView::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len) +void ShadowPass::ShadowView::compute_visibility(ObjectBoundsBuf &bounds, + uint resource_len, + bool debug_freeze) { + UNUSED_VARS(debug_freeze); + GPU_debug_group_begin("ShadowView.compute_visibility"); uint word_per_draw = this->visibility_word_per_draw(); From 5cc9f07d5c56e7201f17a40659c3f4c4c5a83002 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Tue, 24 Jan 2023 20:42:14 +0100 Subject: [PATCH 0923/1522] Draw: Workbench Next: Fix shaders memory leaks Ensure all shaders are deleted --- .../engines/workbench/workbench_effect_dof.cc | 9 ++++++ .../workbench/workbench_effect_outline.cc | 5 +++ .../workbench/workbench_mesh_passes.cc | 10 ++++++ .../engines/workbench/workbench_private.hh | 18 +++++++++-- .../workbench/workbench_shader_cache.cc | 18 +++++------ .../engines/workbench/workbench_shadow.cc | 32 +++++++++++++++---- 6 files changed, 75 insertions(+), 17 deletions(-) diff --git a/source/blender/draw/engines/workbench/workbench_effect_dof.cc b/source/blender/draw/engines/workbench/workbench_effect_dof.cc index 7d46703ad35..d7f2edb3e90 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_dof.cc +++ b/source/blender/draw/engines/workbench/workbench_effect_dof.cc @@ -53,6 +53,15 @@ static void square_to_circle(float x, float y, float &r, float &T) } } +DofPass::~DofPass() +{ + DRW_SHADER_FREE_SAFE(prepare_sh_); + DRW_SHADER_FREE_SAFE(downsample_sh_); + DRW_SHADER_FREE_SAFE(blur1_sh_); + DRW_SHADER_FREE_SAFE(blur2_sh_); + DRW_SHADER_FREE_SAFE(resolve_sh_); +} + void DofPass::setup_samples() { float4 *sample = samples_buf_.begin(); diff --git a/source/blender/draw/engines/workbench/workbench_effect_outline.cc b/source/blender/draw/engines/workbench/workbench_effect_outline.cc index a1826d5ecf8..a4b321c44b5 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_outline.cc +++ b/source/blender/draw/engines/workbench/workbench_effect_outline.cc @@ -12,6 +12,11 @@ namespace blender::workbench { +OutlinePass::~OutlinePass() +{ + DRW_SHADER_FREE_SAFE(sh_); +} + void OutlinePass::init(const SceneState &scene_state) { enabled_ = scene_state.draw_outline; diff --git a/source/blender/draw/engines/workbench/workbench_mesh_passes.cc b/source/blender/draw/engines/workbench/workbench_mesh_passes.cc index a32127d66b0..2f4d785216d 100644 --- a/source/blender/draw/engines/workbench/workbench_mesh_passes.cc +++ b/source/blender/draw/engines/workbench/workbench_mesh_passes.cc @@ -245,6 +245,11 @@ bool OpaquePass::is_empty() const /** \name TransparentPass * \{ */ +TransparentPass::~TransparentPass() +{ + DRW_SHADER_FREE_SAFE(resolve_sh_); +} + void TransparentPass::sync(const SceneState &scene_state, SceneResources &resources) { DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND_OIT | @@ -324,6 +329,11 @@ bool TransparentPass::is_empty() const /** \name TransparentDepthPass * \{ */ +TransparentDepthPass::~TransparentDepthPass() +{ + DRW_SHADER_FREE_SAFE(merge_sh_); +} + void TransparentDepthPass::sync(const SceneState &scene_state, SceneResources &resources) { DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | diff --git a/source/blender/draw/engines/workbench/workbench_private.hh b/source/blender/draw/engines/workbench/workbench_private.hh index 5d9de764d56..20c07061b06 100644 --- a/source/blender/draw/engines/workbench/workbench_private.hh +++ b/source/blender/draw/engines/workbench/workbench_private.hh @@ -226,6 +226,8 @@ class TransparentPass { PassSimple resolve_ps_ = {"Transparent.Resolve"}; Framebuffer resolve_fb = {}; + ~TransparentPass(); + void sync(const SceneState &scene_state, SceneResources &resources); void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution); bool is_empty() const; @@ -243,6 +245,8 @@ class TransparentDepthPass { PassSimple merge_ps_ = {"TransparentDepth.Merge"}; Framebuffer merge_fb = {"TransparentDepth.Merge"}; + ~TransparentDepthPass(); + void sync(const SceneState &scene_state, SceneResources &resources); void draw(Manager &manager, View &view, SceneResources &resources); bool is_empty() const; @@ -261,13 +265,17 @@ class ShadowPass { VisibilityBuf pass_visibility_buf_ = {}; VisibilityBuf fail_visibility_buf_ = {}; + GPUShader *dynamic_pass_type_shader_; + GPUShader *static_pass_type_shader_; + public: + ShadowView(); + ~ShadowView(); + void setup(View &view, float3 light_direction, bool force_fail_method); bool debug_object_culling(Object *ob); void set_mode(PassType type); - ShadowView(); - protected: virtual void compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, @@ -298,6 +306,8 @@ class ShadowPass { Framebuffer fb_ = {}; public: + ~ShadowPass(); + void init(const SceneState &scene_state, SceneResources &resources); void update(); void sync(); @@ -322,6 +332,8 @@ class OutlinePass { Framebuffer fb_ = Framebuffer("Workbench.Outline"); public: + ~OutlinePass(); + void init(const SceneState &scene_state); void sync(SceneResources &resources); void draw(Manager &manager, SceneResources &resources); @@ -369,6 +381,8 @@ class DofPass { float ratio_ = 0; public: + ~DofPass(); + void init(const SceneState &scene_state); void sync(SceneResources &resources); void draw(Manager &manager, View &view, SceneResources &resources, int2 resolution); diff --git a/source/blender/draw/engines/workbench/workbench_shader_cache.cc b/source/blender/draw/engines/workbench/workbench_shader_cache.cc index 6720fc1702b..d544535d146 100644 --- a/source/blender/draw/engines/workbench/workbench_shader_cache.cc +++ b/source/blender/draw/engines/workbench/workbench_shader_cache.cc @@ -6,21 +6,21 @@ namespace blender::workbench { ShaderCache::~ShaderCache() { - for (auto i : IndexRange(lighting_type_len)) { - for (auto j : IndexRange(shader_type_len)) { - for (auto k : IndexRange(geometry_type_len)) { - for (auto l : IndexRange(pipeline_type_len)) { - for (auto m : IndexRange(2)) { + for (auto i : IndexRange(pipeline_type_len)) { + for (auto j : IndexRange(geometry_type_len)) { + for (auto k : IndexRange(shader_type_len)) { + for (auto l : IndexRange(lighting_type_len)) { + for (auto m : IndexRange(2) /*clip*/) { DRW_SHADER_FREE_SAFE(prepass_shader_cache_[i][j][k][l][m]); } } } } } - for (auto i : IndexRange(lighting_type_len)) { - for (auto j : IndexRange(pipeline_type_len)) { - for (auto k : IndexRange(2)) { - for (auto l : IndexRange(2)) { + for (auto i : IndexRange(pipeline_type_len)) { + for (auto j : IndexRange(lighting_type_len)) { + for (auto k : IndexRange(2) /*cavity*/) { + for (auto l : IndexRange(2) /*curvature*/) { DRW_SHADER_FREE_SAFE(resolve_shader_cache_[i][j][k][l]); } } diff --git a/source/blender/draw/engines/workbench/workbench_shadow.cc b/source/blender/draw/engines/workbench/workbench_shadow.cc index d13d717832e..15c18ffef9d 100644 --- a/source/blender/draw/engines/workbench/workbench_shadow.cc +++ b/source/blender/draw/engines/workbench/workbench_shadow.cc @@ -25,6 +25,11 @@ namespace blender::workbench { ShadowPass::ShadowView::ShadowView() : View("ShadowPass.View"){}; +ShadowPass::ShadowView::~ShadowView() +{ + DRW_SHADER_FREE_SAFE(dynamic_pass_type_shader_); + DRW_SHADER_FREE_SAFE(static_pass_type_shader_); +} void ShadowPass::ShadowView::setup(View &view, float3 light_direction, bool force_fail_method) { @@ -237,13 +242,17 @@ void ShadowPass::ShadowView::compute_visibility(ObjectBoundsBuf &bounds, if (do_visibility_) { /* TODO(Miguel Pozo): Use regular culling for the caps pass */ - static GPUShader *dynamic_pass_type_shader = GPU_shader_create_from_info_name( - "workbench_next_shadow_visibility_compute_dynamic_pass_type"); - static GPUShader *static_pass_type_shader = GPU_shader_create_from_info_name( - "workbench_next_shadow_visibility_compute_static_pass_type"); + if (dynamic_pass_type_shader_ == nullptr) { + dynamic_pass_type_shader_ = GPU_shader_create_from_info_name( + "workbench_next_shadow_visibility_compute_dynamic_pass_type"); + } + if (static_pass_type_shader_ == nullptr) { + static_pass_type_shader_ = GPU_shader_create_from_info_name( + "workbench_next_shadow_visibility_compute_static_pass_type"); + } - GPUShader *shader = current_pass_type_ == ShadowPass::FORCED_FAIL ? static_pass_type_shader : - dynamic_pass_type_shader; + GPUShader *shader = current_pass_type_ == ShadowPass::FORCED_FAIL ? static_pass_type_shader_ : + dynamic_pass_type_shader_; GPU_shader_bind(shader); GPU_shader_uniform_1i(shader, "resource_len", resource_len); GPU_shader_uniform_1i(shader, "view_len", view_len_); @@ -285,6 +294,17 @@ VisibilityBuf &ShadowPass::ShadowView::get_visibility_buffer() return visibility_buf_; } +ShadowPass::~ShadowPass() +{ + for (int depth_pass : IndexRange(2)) { + for (int manifold : IndexRange(2)) { + for (int cap : IndexRange(2)) { + DRW_SHADER_FREE_SAFE(shaders_[depth_pass][manifold][cap]); + } + } + } +} + PassMain::Sub *&ShadowPass::get_pass_ptr(PassType type, bool manifold, bool cap /*= false*/) { return passes_[type][manifold][cap]; From 0f52aa0954e75195188499d1d334b5af5731dd29 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Tue, 24 Jan 2023 16:44:31 -0300 Subject: [PATCH 0924/1522] Transform: Initialize 'transform_matrix' accordingly Some transform modes are changeable, so callbacks should be reset together. Currently the unchanged `transform_matrix` callback is not a major issue as it is only used for gizmos and gizmos stop updating when changing the operator type. --- source/blender/editors/transform/transform_mode_edge_slide.c | 1 + source/blender/editors/transform/transform_mode_resize.c | 1 + source/blender/editors/transform/transform_mode_vert_slide.c | 1 + 3 files changed, 3 insertions(+) diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index 6920deea574..f2ba8c4bd4d 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -1498,6 +1498,7 @@ void initEdgeSlide_ex( t->mode = TFM_EDGE_SLIDE; t->transform = applyEdgeSlide; t->handleEvent = handleEventEdgeSlide; + t->transform_matrix = NULL; t->tsnap.snap_mode_apply_fn = edge_slide_snap_apply; t->tsnap.snap_mode_distance_fn = transform_snap_distance_len_squared_fn; diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c index 355da21c253..bf9fba2b1e7 100644 --- a/source/blender/editors/transform/transform_mode_resize.c +++ b/source/blender/editors/transform/transform_mode_resize.c @@ -285,6 +285,7 @@ void initResize(TransInfo *t, float mouse_dir_constraint[3]) { t->mode = TFM_RESIZE; t->transform = applyResize; + t->transform_matrix = NULL; t->tsnap.snap_mode_apply_fn = ApplySnapResize; t->tsnap.snap_mode_distance_fn = ResizeBetween; diff --git a/source/blender/editors/transform/transform_mode_vert_slide.c b/source/blender/editors/transform/transform_mode_vert_slide.c index 3483f2b2bfa..f6e8c64af8f 100644 --- a/source/blender/editors/transform/transform_mode_vert_slide.c +++ b/source/blender/editors/transform/transform_mode_vert_slide.c @@ -610,6 +610,7 @@ void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp) t->mode = TFM_VERT_SLIDE; t->transform = applyVertSlide; t->handleEvent = handleEventVertSlide; + t->transform_matrix = NULL; t->tsnap.snap_mode_apply_fn = vert_slide_snap_apply; t->tsnap.snap_mode_distance_fn = transform_snap_distance_len_squared_fn; From 1ad11355a3578dc24496417a517d3ce2faebb248 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Tue, 24 Jan 2023 17:06:53 -0300 Subject: [PATCH 0925/1522] Transform: fix use of "snap_point" property There is not much documentation on the "snap_point" property, but by code it is possible to note that it serves to set a target snap point and is of internal use as it is hidden from the Redo panel. However, this property was still very dependent on Tools settings and if set to an operator's call, it changes the scene configurations inadequately. Therefore, - remove this dependency from UI for rotation and resize operators, - do not change the state of the snap in the scene and - cleanup the code. --- source/blender/editors/transform/transform.c | 2 +- source/blender/editors/transform/transform_snap.cc | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index c9cf572e9ad..3cff4c11cad 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1586,7 +1586,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op) /* Update `ToolSettings` for properties that change during modal. */ if (t->flag & T_MODAL) { /* Do we check for parameter? */ - if (transformModeUseSnap(t)) { + if (transformModeUseSnap(t) && !(t->tsnap.status & SNAP_FORCED)) { if (!(t->modifiers & MOD_SNAP) != !(t->tsnap.flag & SCE_SNAP)) { /* Type is #eSnapFlag, but type must match various snap attributes in #ToolSettings. */ short *snap_flag_ptr; diff --git a/source/blender/editors/transform/transform_snap.cc b/source/blender/editors/transform/transform_snap.cc index 2f5e1974d0b..8a1cb2d9788 100644 --- a/source/blender/editors/transform/transform_snap.cc +++ b/source/blender/editors/transform/transform_snap.cc @@ -147,6 +147,10 @@ bool transformModeUseSnap(const TransInfo *t) static bool doForceIncrementSnap(const TransInfo *t) { + if (t->tsnap.status & SNAP_FORCED) { + return false; + } + return !transformModeUseSnap(t); } @@ -525,13 +529,7 @@ void transform_snap_mixed_apply(TransInfo *t, float *vec) return; } - if (t->tsnap.status & SNAP_FORCED) { - t->tsnap.snap_source_fn(t); - - t->tsnap.snap_mode_apply_fn(t, vec); - } - else if (((t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) != 0) && - transform_snap_is_active(t)) { + if (t->tsnap.mode & ~(SCE_SNAP_MODE_INCREMENT | SCE_SNAP_MODE_GRID)) { double current = PIL_check_seconds_timer(); /* Time base quirky code to go around find-nearest slowness. */ From c5d9938adcffe9f552d84fc10cdcf7c0c305144e Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Tue, 24 Jan 2023 23:17:32 +0100 Subject: [PATCH 0926/1522] Fix T104073: Unable to add more than two strips in one channel Originally, function `sequencer_generic_invoke_xy_guess_channel` looked in what channel the last strip of the same type is and the channel used for new strip placement. This was changed as a workaround when sound strips were added below movie strips (58bea005c58956674c7f4a9a7a85ff943c140f03). Now these workarounds aren't necessary, but the function was left unchanged. Current logic is for adding movie strip to channel 1 is: - Sound is added to channel 1 - Video is added to channel 2 - If there is only video, it is added to channel 1 Since movie may, or may not contain sound, it is not possible to align added strips in a way that was done before, unless timeline is analyzed more in detail, but this would be quite inefficient. Also, note, that the code did not work, if strip is added next to previous one, so it mostly did not work as intended. This commit changes: - Fix alignment not working when strip is added right next to previous strip - Assume that movie strips have sound strip underneath it, so channel below last movie strip is picked - For other strip types, pick channel of the last strip of same type Ultimately, the code is still rather weak, and better system, like using channel where strip was manually moved, or concept of "typed channels" would improve this feature. --- source/blender/editors/space_sequencer/sequencer_add.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c index 2613df11c42..872a9afd89f 100644 --- a/source/blender/editors/space_sequencer/sequencer_add.c +++ b/source/blender/editors/space_sequencer/sequencer_add.c @@ -201,7 +201,7 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type) for (seq = ed->seqbasep->first; seq; seq = seq->next) { const int strip_end = SEQ_time_right_handle_frame_get(scene, seq); - if (ELEM(type, -1, seq->type) && (strip_end < timeline_frame) && + if (ELEM(type, -1, seq->type) && (strip_end <= timeline_frame) && (timeline_frame - strip_end < proximity)) { tgt = seq; proximity = timeline_frame - strip_end; @@ -209,7 +209,7 @@ static int sequencer_generic_invoke_xy_guess_channel(bContext *C, int type) } if (tgt) { - return tgt->machine + 1; + return (type == SEQ_TYPE_MOVIE) ? tgt->machine - 1 : tgt->machine; } return 1; } From d446809f964291d54c5311f5f8720f00cb6df27b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jan 2023 09:53:35 +1100 Subject: [PATCH 0927/1522] Cleanup: remove unused argument --- source/blender/blenkernel/intern/pbvh_uv_islands.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index 9b6ad72bfa8..07eb3137249 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -620,7 +620,7 @@ struct Fan { return result; } - void mark_already_added_segments(const MeshData &mesh_data, const UVVertex &uv_vertex) + void mark_already_added_segments(const UVVertex &uv_vertex) { Vector mesh_primitive_indices = connecting_mesh_primitive_indices(uv_vertex); @@ -908,7 +908,7 @@ static void extend_at_vert(const MeshData &mesh_data, return; } fan.init_uv_coordinates(mesh_data, *uv_vertex); - fan.mark_already_added_segments(mesh_data, *uv_vertex); + fan.mark_already_added_segments(*uv_vertex); int num_to_add = fan.count_edges_not_added(); /* In 3d space everything can connected, but in uv space it may not. From b8cb962fb2ea902d3c50a37f18ff7477ec04f071 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jan 2023 09:53:36 +1100 Subject: [PATCH 0928/1522] Cleanup: perform string join & allocation in a single step --- source/blender/blenlib/intern/BLI_filelist.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c index 06fb57842e0..2f7662e6220 100644 --- a/source/blender/blenlib/intern/BLI_filelist.c +++ b/source/blender/blenlib/intern/BLI_filelist.c @@ -37,6 +37,7 @@ #include "BLI_listbase.h" #include "BLI_path_util.h" #include "BLI_string.h" +#include "BLI_string_utils.h" #include "../imbuf/IMB_imbuf.h" @@ -183,17 +184,11 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) struct dirlink *dlink = (struct dirlink *)dirbase.first; struct direntry *file = &dir_ctx->files[dir_ctx->files_num]; - char fullname[PATH_MAX]; - STRNCPY(fullname, dirname_with_slash); - char *fullname_name_part = fullname + dirname_with_slash_len; - const size_t fullname_name_part_len = sizeof(fullname) - dirname_with_slash_len; - while (dlink) { - BLI_strncpy(fullname_name_part, dlink->name, fullname_name_part_len); memset(file, 0, sizeof(struct direntry)); file->relname = dlink->name; - file->path = BLI_strdup(fullname); - if (BLI_stat(fullname, &file->s) != -1) { + file->path = BLI_string_joinN(dirname_with_slash, dlink->name); + if (BLI_stat(file->path, &file->s) != -1) { file->type = file->s.st_mode; } else if (FILENAME_IS_CURRPAR(file->relname)) { From b51034b9cad3dc148b7377180c81a3350651c04a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jan 2023 09:53:38 +1100 Subject: [PATCH 0929/1522] Asset system: use native slash for AssetLibraryIndex.indices_base_path When constructing run-time paths native slashes are preferred as WIN32 doesn't have full support for forward slashes in paths. It can also cause problems when performing exact matches on paths which are normalized, where normalizing one of the paths makes comparisons fail. Using the system native slash would have avoided T103385. --- source/blender/editors/asset/intern/asset_indexer.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/asset/intern/asset_indexer.cc b/source/blender/editors/asset/intern/asset_indexer.cc index e1350b3119e..dd02e65791b 100644 --- a/source/blender/editors/asset/intern/asset_indexer.cc +++ b/source/blender/editors/asset/intern/asset_indexer.cc @@ -472,7 +472,7 @@ struct AssetLibraryIndex { BLI_path_append(index_path, sizeof(index_path), "asset-library-indices"); std::stringstream ss; - ss << std::setfill('0') << std::setw(16) << std::hex << hash() << "/"; + ss << std::setfill('0') << std::setw(16) << std::hex << hash() << SEP_STR; BLI_path_append(index_path, sizeof(index_path), ss.str().c_str()); indices_base_path = std::string(index_path); From d3967ce27c04b0e49a2c5daaa605c543b87266f3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jan 2023 10:48:56 +1100 Subject: [PATCH 0930/1522] Cleanup: use early return in bli_builddir, reduce right shift --- source/blender/blenlib/intern/BLI_filelist.c | 178 +++++++++---------- 1 file changed, 88 insertions(+), 90 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c index 2f7662e6220..69d07e52b08 100644 --- a/source/blender/blenlib/intern/BLI_filelist.c +++ b/source/blender/blenlib/intern/BLI_filelist.c @@ -45,7 +45,7 @@ * Ordering function for sorting lists of files/directories. Returns -1 if * entry1 belongs before entry2, 0 if they are equal, 1 if they should be swapped. */ -static int bli_compare(struct direntry *entry1, struct direntry *entry2) +static int direntry_cmp(struct direntry *entry1, struct direntry *entry2) { /* type is equal to stat.st_mode */ @@ -107,122 +107,120 @@ struct BuildDirCtx { */ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) { + DIR *dir = opendir(dirname); + if (UNLIKELY(dir == NULL)) { + printf("%s non-existent directory\n", dirname); + return; + } + struct ListBase dirbase = {NULL, NULL}; int newnum = 0; - DIR *dir; + const struct dirent *fname; + bool has_current = false, has_parent = false; - if ((dir = opendir(dirname)) != NULL) { - const struct dirent *fname; - bool has_current = false, has_parent = false; + char dirname_with_slash[FILE_MAXDIR + 1]; + size_t dirname_with_slash_len = BLI_strncpy_rlen( + dirname_with_slash, dirname, sizeof(dirname_with_slash) - 1); - char dirname_with_slash[FILE_MAXDIR + 1]; - size_t dirname_with_slash_len = BLI_strncpy_rlen( - dirname_with_slash, dirname, sizeof(dirname_with_slash) - 1); + if ((dirname_with_slash_len > 0) && + (BLI_path_slash_is_native_compat(dirname_with_slash_len - 1) == false)) { + dirname_with_slash[dirname_with_slash_len++] = SEP; + dirname_with_slash[dirname_with_slash_len] = '\0'; + } - if ((dirname_with_slash_len > 0) && - (BLI_path_slash_is_native_compat(dirname_with_slash_len - 1) == false)) { - dirname_with_slash[dirname_with_slash_len++] = SEP; - dirname_with_slash[dirname_with_slash_len] = '\0'; + while ((fname = readdir(dir)) != NULL) { + struct dirlink *const dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); + if (dlink != NULL) { + dlink->name = BLI_strdup(fname->d_name); + if (FILENAME_IS_PARENT(dlink->name)) { + has_parent = true; + } + else if (FILENAME_IS_CURRENT(dlink->name)) { + has_current = true; + } + BLI_addhead(&dirbase, dlink); + newnum++; } + } - while ((fname = readdir(dir)) != NULL) { + if (!has_parent) { + char pardir[FILE_MAXDIR]; + + BLI_strncpy(pardir, dirname, sizeof(pardir)); + if (BLI_path_parent_dir(pardir) && (BLI_access(pardir, R_OK) == 0)) { struct dirlink *const dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); if (dlink != NULL) { - dlink->name = BLI_strdup(fname->d_name); - if (FILENAME_IS_PARENT(dlink->name)) { - has_parent = true; - } - else if (FILENAME_IS_CURRENT(dlink->name)) { - has_current = true; - } + dlink->name = BLI_strdup(FILENAME_PARENT); BLI_addhead(&dirbase, dlink); newnum++; } } - - if (!has_parent) { - char pardir[FILE_MAXDIR]; - - BLI_strncpy(pardir, dirname, sizeof(pardir)); - if (BLI_path_parent_dir(pardir) && (BLI_access(pardir, R_OK) == 0)) { - struct dirlink *const dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); - if (dlink != NULL) { - dlink->name = BLI_strdup(FILENAME_PARENT); - BLI_addhead(&dirbase, dlink); - newnum++; - } - } + } + if (!has_current) { + struct dirlink *const dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); + if (dlink != NULL) { + dlink->name = BLI_strdup(FILENAME_CURRENT); + BLI_addhead(&dirbase, dlink); + newnum++; } - if (!has_current) { - struct dirlink *const dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); - if (dlink != NULL) { - dlink->name = BLI_strdup(FILENAME_CURRENT); - BLI_addhead(&dirbase, dlink); - newnum++; + } + + if (newnum) { + if (dir_ctx->files) { + void *const tmp = MEM_reallocN(dir_ctx->files, + (dir_ctx->files_num + newnum) * sizeof(struct direntry)); + if (tmp) { + dir_ctx->files = (struct direntry *)tmp; + } + else { /* realloc fail */ + MEM_freeN(dir_ctx->files); + dir_ctx->files = NULL; } } - if (newnum) { - if (dir_ctx->files) { - void *const tmp = MEM_reallocN(dir_ctx->files, - (dir_ctx->files_num + newnum) * sizeof(struct direntry)); - if (tmp) { - dir_ctx->files = (struct direntry *)tmp; + if (dir_ctx->files == NULL) { + dir_ctx->files = (struct direntry *)MEM_mallocN(newnum * sizeof(struct direntry), __func__); + } + + if (dir_ctx->files) { + struct dirlink *dlink = (struct dirlink *)dirbase.first; + struct direntry *file = &dir_ctx->files[dir_ctx->files_num]; + + while (dlink) { + memset(file, 0, sizeof(struct direntry)); + file->relname = dlink->name; + file->path = BLI_string_joinN(dirname_with_slash, dlink->name); + if (BLI_stat(file->path, &file->s) != -1) { + file->type = file->s.st_mode; } - else { /* realloc fail */ - MEM_freeN(dir_ctx->files); - dir_ctx->files = NULL; + else if (FILENAME_IS_CURRPAR(file->relname)) { + /* Hack around for UNC paths on windows: + * does not support stat on '\\SERVER\foo\..', sigh... */ + file->type |= S_IFDIR; } - } - - if (dir_ctx->files == NULL) { - dir_ctx->files = (struct direntry *)MEM_mallocN(newnum * sizeof(struct direntry), - __func__); - } - - if (dir_ctx->files) { - struct dirlink *dlink = (struct dirlink *)dirbase.first; - struct direntry *file = &dir_ctx->files[dir_ctx->files_num]; - - while (dlink) { - memset(file, 0, sizeof(struct direntry)); - file->relname = dlink->name; - file->path = BLI_string_joinN(dirname_with_slash, dlink->name); - if (BLI_stat(file->path, &file->s) != -1) { - file->type = file->s.st_mode; - } - else if (FILENAME_IS_CURRPAR(file->relname)) { - /* Hack around for UNC paths on windows: - * does not support stat on '\\SERVER\foo\..', sigh... */ - file->type |= S_IFDIR; - } - dir_ctx->files_num++; - file++; - dlink = dlink->next; - } - } - else { - printf("Couldn't get memory for dir\n"); - exit(1); - } - - BLI_freelist(&dirbase); - if (dir_ctx->files) { - qsort(dir_ctx->files, - dir_ctx->files_num, - sizeof(struct direntry), - (int (*)(const void *, const void *))bli_compare); + dir_ctx->files_num++; + file++; + dlink = dlink->next; } } else { - printf("%s empty directory\n", dirname); + printf("Couldn't get memory for dir\n"); + exit(1); } - closedir(dir); + BLI_freelist(&dirbase); + if (dir_ctx->files) { + qsort(dir_ctx->files, + dir_ctx->files_num, + sizeof(struct direntry), + (int (*)(const void *, const void *))direntry_cmp); + } } else { - printf("%s non-existent directory\n", dirname); + printf("%s empty directory\n", dirname); } + + closedir(dir); } uint BLI_filelist_dir_contents(const char *dirname, struct direntry **r_filelist) From 0c2b2cdb78c4a03386b36ab69491fa4f0cd22993 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jan 2023 10:48:59 +1100 Subject: [PATCH 0931/1522] BLI_filelist: minor changes to bli_builddir behavior - Don't call exit() when memory allocation fails, while unlikely internal failures should not be exiting the application. - Don't print a message when the directory is empty as it's unnecessarily noisy. - Print errors the the stderr & include the reason for opendir failing. --- source/blender/blenlib/intern/BLI_filelist.c | 30 ++++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c index 69d07e52b08..ae7f6f79a17 100644 --- a/source/blender/blenlib/intern/BLI_filelist.c +++ b/source/blender/blenlib/intern/BLI_filelist.c @@ -4,6 +4,7 @@ * \ingroup bli */ +#include #include #include #include @@ -109,7 +110,10 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) { DIR *dir = opendir(dirname); if (UNLIKELY(dir == NULL)) { - printf("%s non-existent directory\n", dirname); + fprintf(stderr, + "Failed to open dir (%s): %s\n", + errno ? strerror(errno) : "unknown error", + dirname); return; } @@ -172,7 +176,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) if (tmp) { dir_ctx->files = (struct direntry *)tmp; } - else { /* realloc fail */ + else { /* Reallocation may fail. */ MEM_freeN(dir_ctx->files); dir_ctx->files = NULL; } @@ -182,7 +186,11 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) dir_ctx->files = (struct direntry *)MEM_mallocN(newnum * sizeof(struct direntry), __func__); } - if (dir_ctx->files) { + if (UNLIKELY(dir_ctx->files == NULL)) { + fprintf(stderr, "Couldn't get memory for dir: %s\n", dirname); + dir_ctx->files_num = 0; + } + else { struct dirlink *dlink = (struct dirlink *)dirbase.first; struct direntry *file = &dir_ctx->files[dir_ctx->files_num]; @@ -194,30 +202,22 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) file->type = file->s.st_mode; } else if (FILENAME_IS_CURRPAR(file->relname)) { - /* Hack around for UNC paths on windows: - * does not support stat on '\\SERVER\foo\..', sigh... */ + /* Unfortunately a hack around UNC paths on WIN32, + * which does not support `stat` on `\\SERVER\foo\..`. */ file->type |= S_IFDIR; } dir_ctx->files_num++; file++; dlink = dlink->next; } - } - else { - printf("Couldn't get memory for dir\n"); - exit(1); - } - BLI_freelist(&dirbase); - if (dir_ctx->files) { qsort(dir_ctx->files, dir_ctx->files_num, sizeof(struct direntry), (int (*)(const void *, const void *))direntry_cmp); } - } - else { - printf("%s empty directory\n", dirname); + + BLI_freelist(&dirbase); } closedir(dir); From 9c71f5807ff0542c347b0c0d31da1c58ac32ea42 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jan 2023 11:03:17 +1100 Subject: [PATCH 0932/1522] Cleanup: remove unused argument, warnings --- source/blender/blenkernel/intern/image_gpu.cc | 2 +- source/blender/editors/gpencil/gpencil_fill.c | 7 +++---- source/blender/python/mathutils/mathutils_Vector.c | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/image_gpu.cc b/source/blender/blenkernel/intern/image_gpu.cc index 12f3287ef97..c9d34800227 100644 --- a/source/blender/blenkernel/intern/image_gpu.cc +++ b/source/blender/blenkernel/intern/image_gpu.cc @@ -264,7 +264,7 @@ static GPUTexture **get_image_gpu_texture_ptr(Image *ima, eGPUTextureTarget textarget, const int multiview_eye) { - const bool in_range = (textarget >= 0) && (textarget < TEXTARGET_COUNT); + const bool in_range = (int(textarget) >= 0) && (textarget < TEXTARGET_COUNT); BLI_assert(in_range); BLI_assert(ELEM(multiview_eye, 0, 1)); diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c index 8a7e1c03e66..058cc417cc0 100644 --- a/source/blender/editors/gpencil/gpencil_fill.c +++ b/source/blender/editors/gpencil/gpencil_fill.c @@ -288,8 +288,7 @@ static void add_stroke_extension(bGPDframe *gpf, bGPDstroke *gps, float p1[3], f pt->pressure = 1.0f; } -static void add_endpoint_radius_help(tGPDfill *tgpf, - bGPDframe *gpf, +static void add_endpoint_radius_help(bGPDframe *gpf, bGPDstroke *gps, const float endpoint[3], const float radius, @@ -834,8 +833,8 @@ static void gpencil_create_extensions_radius(tGPDfill *tgpf) bool start_connected = BLI_gset_haskey(connected_endpoints, stroke1_start); bool end_connected = BLI_gset_haskey(connected_endpoints, stroke1_end); - add_endpoint_radius_help(tgpf, gpf, gps, stroke1_start, connection_dist, start_connected); - add_endpoint_radius_help(tgpf, gpf, gps, stroke1_end, connection_dist, end_connected); + add_endpoint_radius_help(gpf, gps, stroke1_start, connection_dist, start_connected); + add_endpoint_radius_help(gpf, gps, stroke1_end, connection_dist, end_connected); } BLI_gset_free(connected_endpoints, NULL); diff --git a/source/blender/python/mathutils/mathutils_Vector.c b/source/blender/python/mathutils/mathutils_Vector.c index c5a002a6058..d01c3d8587c 100644 --- a/source/blender/python/mathutils/mathutils_Vector.c +++ b/source/blender/python/mathutils/mathutils_Vector.c @@ -2681,8 +2681,8 @@ static int Vector_swizzle_set(VectorObject *self, PyObject *value, void *closure size_from = axis_from; } else if ((void)PyErr_Clear(), /* run but ignore the result */ - (size_from = mathutils_array_parse( - vec_assign, 2, 4, value, "mathutils.Vector.**** = swizzle assignment")) == -1) { + (size_from = (size_t)mathutils_array_parse( + vec_assign, 2, 4, value, "Vector.**** = swizzle assignment")) == (size_t)-1) { return -1; } From adcb0edca0e25002981faa3db17e65f7f3dfa2a6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jan 2023 11:51:21 +1100 Subject: [PATCH 0933/1522] Cleanup: clang-tidy, replace defines with enum, redundant parenthesis --- intern/ghost/intern/GHOST_SystemWayland.cpp | 52 +++++++++++-------- source/blender/blenlib/intern/math_matrix.cc | 8 +-- .../blender/windowmanager/intern/wm_window.c | 5 +- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/intern/ghost/intern/GHOST_SystemWayland.cpp b/intern/ghost/intern/GHOST_SystemWayland.cpp index 3911014d8cb..496179fc826 100644 --- a/intern/ghost/intern/GHOST_SystemWayland.cpp +++ b/intern/ghost/intern/GHOST_SystemWayland.cpp @@ -215,13 +215,15 @@ static bool use_gnome_confine_hack = false; /** * The event codes are used to differentiate from which mouse button an event comes from. */ -#define BTN_LEFT 0x110 -#define BTN_RIGHT 0x111 -#define BTN_MIDDLE 0x112 -#define BTN_SIDE 0x113 -#define BTN_EXTRA 0x114 -#define BTN_FORWARD 0x115 -#define BTN_BACK 0x116 +enum { + BTN_LEFT = 0x110, + BTN_RIGHT = 0x111, + BTN_MIDDLE = 0x112, + BTN_SIDE = 0x113, + BTN_EXTRA = 0x114, + BTN_FORWARD = 0x115, + BTN_BACK = 0x116 +}; // #define BTN_TASK 0x117 /* UNUSED. */ /** @@ -232,28 +234,34 @@ static bool use_gnome_confine_hack = false; * at the Blender studio, having the button closest to the nib be MMB is preferable, * so use this as a default. If needs be - swapping these could be a preference. */ -#define BTN_STYLUS 0x14b /* Use as middle-mouse. */ -#define BTN_STYLUS2 0x14c /* Use as right-mouse. */ -/* NOTE(@campbellbarton): Map to an additional button (not sure which hardware uses this). */ -#define BTN_STYLUS3 0x149 +enum { + /** Use as middle-mouse. */ + BTN_STYLUS = 0x14b, + /** Use as right-mouse. */ + BTN_STYLUS2 = 0x14c, + /** NOTE(@campbellbarton): Map to an additional button (not sure which hardware uses this). */ + BTN_STYLUS3 = 0x149, +}; /** * Keyboard scan-codes. */ -#define KEY_GRAVE 41 +enum { + KEY_GRAVE = 41, #ifdef USE_NON_LATIN_KB_WORKAROUND -# define KEY_1 2 -# define KEY_2 3 -# define KEY_3 4 -# define KEY_4 5 -# define KEY_5 6 -# define KEY_6 7 -# define KEY_7 8 -# define KEY_8 9 -# define KEY_9 10 -# define KEY_0 11 + KEY_1 = 2, + KEY_2 = 3, + KEY_3 = 4, + KEY_4 = 5, + KEY_5 = 6, + KEY_6 = 7, + KEY_7 = 8, + KEY_8 = 9, + KEY_9 = 10, + KEY_0 = 11, #endif +}; /** \} */ diff --git a/source/blender/blenlib/intern/math_matrix.cc b/source/blender/blenlib/intern/math_matrix.cc index 9ab484d0d8a..e89b58b2a76 100644 --- a/source/blender/blenlib/intern/math_matrix.cc +++ b/source/blender/blenlib/intern/math_matrix.cc @@ -230,9 +230,9 @@ MatBase pseudo_invert(const MatBase &mat, T epsilo JacobiSVD svd( Eigen::Map(mat.base_ptr(), Size, Size), ComputeThinU | ComputeThinV); - (Eigen::Map(U.base_ptr())) = svd.matrixU(); + Eigen::Map(U.base_ptr()) = svd.matrixU(); (Eigen::Map(S_val)) = svd.singularValues(); - (Eigen::Map(V.base_ptr())) = svd.matrixV(); + Eigen::Map(V.base_ptr()) = svd.matrixV(); } /* Invert or nullify component based on epsilon comparison. */ @@ -290,9 +290,9 @@ static void polar_decompose(const MatBase &mat3, JacobiSVD svd( Eigen::Map(mat3.base_ptr(), 3, 3), ComputeThinU | ComputeThinV); - (Eigen::Map(W.base_ptr())) = svd.matrixU(); + Eigen::Map(W.base_ptr()) = svd.matrixU(); (Eigen::Map(S_val)) = svd.singularValues(); - (Map(V.base_ptr())) = svd.matrixV(); + Map(V.base_ptr()) = svd.matrixV(); } MatBase S = from_scale>(S_val); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 1c029a6902d..aa82a7d0b3a 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1143,7 +1143,7 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt wmWindow *win = GHOST_GetWindowUserData(ghostwin); switch (type) { - case GHOST_kEventWindowDeactivate: + case GHOST_kEventWindowDeactivate: { #ifdef USE_WIN_DEACTIVATE /* Release all held modifiers before de-activating the window. */ if (win->eventstate->modifier != 0) { @@ -1180,8 +1180,9 @@ static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_pt #endif /* USE_WIN_DEACTIVATE */ wm_event_add_ghostevent(wm, win, type, data); - win->active = 0; /* XXX */ + win->active = 0; break; + } case GHOST_kEventWindowActivate: { /* No context change! C->wm->windrawable is drawable, or for area queues. */ From 821dee6de42e5586847b993a2f0bd5ffdac508b5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jan 2023 11:53:50 +1100 Subject: [PATCH 0934/1522] CMake: de-duplicate option(..) for platform specific defaults Use a variable for the default instead, avoid duplicate descriptions. --- CMakeLists.txt | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index df1a5a88550..a631b3e6a60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,14 +167,26 @@ get_blender_version() option(WITH_BLENDER "Build blender (disable to build only the blender player)" ON) mark_as_advanced(WITH_BLENDER) -if(APPLE) - # In future, can be used with `quicklookthumbnailing/qlthumbnailreply` to create file - # thumbnails for say Finder. Turn it off for now. - option(WITH_BLENDER_THUMBNAILER "Build \"blender-thumbnailer\" thumbnail extraction utility" OFF) -elseif(WIN32) - option(WITH_BLENDER_THUMBNAILER "Build \"BlendThumb.dll\" helper for Windows explorer integration" ON) +if(WIN32) + option(WITH_BLENDER_THUMBNAILER "\ +Build \"BlendThumb.dll\" helper for Windows explorer integration to support extracting \ +thumbnails from `.blend` files." + ON + ) else() - option(WITH_BLENDER_THUMBNAILER "Build \"blender-thumbnailer\" thumbnail extraction utility" ON) + set(_option_default ON) + if(APPLE) + # In future, can be used with `quicklookthumbnailing/qlthumbnailreply` + # to create file thumbnails for say Finder. + # Turn it off for now, even though it can build on APPLE, it's not likely to be useful. + set(_option_default OFF) + endif() + option(WITH_BLENDER_THUMBNAILER "\ +Build stand-alone \"blender-thumbnailer\" command-line thumbnail extraction utility, \ +intended for use by file-managers to extract PNG images from `.blend` files." + ${_option_default} + ) + unset(_option_default) endif() option(WITH_INTERNATIONAL "Enable I18N (International fonts and text)" ON) @@ -214,14 +226,19 @@ option(WITH_BULLET "Enable Bullet (Physics Engine)" ON) option(WITH_SYSTEM_BULLET "Use the systems bullet library (currently unsupported due to missing features in upstream!)" ) mark_as_advanced(WITH_SYSTEM_BULLET) option(WITH_OPENCOLORIO "Enable OpenColorIO color management" ON) + +set(_option_default ON) if(APPLE) # There's no OpenXR runtime in sight for macOS, neither is code well # tested there -> disable it by default. - option(WITH_XR_OPENXR "Enable VR features through the OpenXR specification" OFF) - mark_as_advanced(WITH_XR_OPENXR) -else() - option(WITH_XR_OPENXR "Enable VR features through the OpenXR specification" ON) + set(_option_default OFF) endif() +option(WITH_XR_OPENXR "Enable VR features through the OpenXR specification" ${_option_default}) +if(APPLE) + mark_as_advanced(WITH_XR_OPENXR) +endif() +unset(_option_default) + option(WITH_GMP "Enable features depending on GMP (Exact Boolean)" ON) # Compositor @@ -353,12 +370,13 @@ else() set(WITH_COREAUDIO OFF) endif() if(NOT WIN32) + set(_option_default ON) if(APPLE) - option(WITH_JACK "Enable JACK Support (http://www.jackaudio.org)" OFF) - else() - option(WITH_JACK "Enable JACK Support (http://www.jackaudio.org)" ON) + set(_option_default OFF) endif() - option(WITH_JACK_DYNLOAD "Enable runtime dynamic JACK libraries loading" OFF) + option(WITH_JACK "Enable JACK Support (http://www.jackaudio.org)" ${_option_default}) + unset(_option_default) + option(WITH_JACK_DYNLOAD "Enable runtime dynamic JACK libraries loading" OFF) else() set(WITH_JACK OFF) endif() From 6c310acccc557fbe50503abe1366bfa1ba080847 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jan 2023 11:56:04 +1100 Subject: [PATCH 0935/1522] help now includes a GPU section & improve --gpu-backend error - Include available GPU backends in the GPU backend error. - Use stderr for the error message. --- source/creator/creator_args.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index e942c0d18ee..a53ee46b00a 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -598,6 +598,10 @@ static int arg_handle_print_help(int UNUSED(argc), const char **UNUSED(argv), vo BLI_args_print_arg_doc(ba, "--verbose"); + printf("\n"); + printf("GPU Options:\n"); + BLI_args_print_arg_doc(ba, "--gpu-backend"); + printf("\n"); printf("Misc Options:\n"); BLI_args_print_arg_doc(ba, "--open-last"); @@ -1126,29 +1130,37 @@ static const char arg_handle_gpu_backend_set_doc[] = static int arg_handle_gpu_backend_set(int argc, const char **argv, void *UNUSED(data)) { if (argc == 0) { - printf("\nError: GPU backend must follow '--gpu-backend'.\n"); + fprintf(stderr, "\nError: GPU backend must follow '--gpu-backend'.\n"); return 0; } + const char *backends_supported[3] = {NULL}; + int backends_supported_num = 0; eGPUBackendType gpu_backend = GPU_BACKEND_NONE; - if (STREQ(argv[1], "opengl")) { + /* NOLINTBEGIN: bugprone-assignment-in-if-condition */ + if (STREQ(argv[1], (backends_supported[backends_supported_num++] = "opengl"))) { gpu_backend = GPU_BACKEND_OPENGL; } # ifdef WITH_VULKAN_BACKEND - else if (STREQ(argv[1], "vulkan")) { + else if (STREQ(argv[1], (backends_supported[backends_supported_num++] = "vulkan"))) { gpu_backend = GPU_BACKEND_VULKAN; } # endif # ifdef WITH_METAL_BACKEND - else if (STREQ(argv[1], "metal")) { + else if (STREQ(argv[1], (backends_supported[backends_supported_num++] = "metal"))) { gpu_backend = GPU_BACKEND_METAL; } # endif else { - printf("\nError: Unrecognized GPU backend for '--gpu-backend'.\n"); + fprintf(stderr, "\nError: Unrecognized GPU backend for '--gpu-backend', expected one of ["); + for (int i = 0; i < backends_supported_num; i++) { + fprintf(stderr, (i + 1 != backends_supported_num) ? "%s, " : "%s", backends_supported[i]); + } + fprintf(stderr, "].\n"); return 0; } + /* NOLINTEND: bugprone-assignment-in-if-condition */ GPU_backend_type_selection_set_override(gpu_backend); From 7416021bf720f6f8a16a044e11be69d17e1680de Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jan 2023 12:20:48 +1100 Subject: [PATCH 0936/1522] Command Line Arguments: all errors now print to the stderr This was done by some callbacks but not all. Only use the stdout for status & information. --- source/creator/creator_args.c | 156 ++++++++++++++++++---------------- 1 file changed, 82 insertions(+), 74 deletions(-) diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c index a53ee46b00a..7eb37982086 100644 --- a/source/creator/creator_args.c +++ b/source/creator/creator_args.c @@ -792,7 +792,7 @@ static int arg_handle_log_level_set(int argc, const char **argv, void *UNUSED(da if (argc > 1) { const char *err_msg = NULL; if (!parse_int_clamp(argv[1], NULL, -1, INT_MAX, &G.log.level, &err_msg)) { - printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); + fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); } else { if (G.log.level == -1) { @@ -802,7 +802,7 @@ static int arg_handle_log_level_set(int argc, const char **argv, void *UNUSED(da } return 1; } - printf("\nError: '%s' no args given.\n", arg_id); + fprintf(stderr, "\nError: '%s' no args given.\n", arg_id); return 0; } @@ -852,7 +852,7 @@ static int arg_handle_log_file_set(int argc, const char **argv, void *UNUSED(dat FILE *fp = BLI_fopen(argv[1], "w"); if (fp == NULL) { const char *err_msg = errno ? strerror(errno) : "unknown"; - printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); + fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); } else { if (UNLIKELY(G.log.file != NULL)) { @@ -863,7 +863,7 @@ static int arg_handle_log_file_set(int argc, const char **argv, void *UNUSED(dat } return 1; } - printf("\nError: '%s' no args given.\n", arg_id); + fprintf(stderr, "\nError: '%s' no args given.\n", arg_id); return 0; } @@ -906,7 +906,7 @@ static int arg_handle_log_set(int argc, const char **argv, void *UNUSED(data)) } return 1; } - printf("\nError: '%s' no args given.\n", arg_id); + fprintf(stderr, "\nError: '%s' no args given.\n", arg_id); return 0; } @@ -1091,7 +1091,7 @@ static int arg_handle_debug_value_set(int argc, const char **argv, void *UNUSED( const char *err_msg = NULL; int value; if (!parse_int(argv[1], NULL, &value, &err_msg)) { - printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); + fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); return 1; } @@ -1099,7 +1099,7 @@ static int arg_handle_debug_value_set(int argc, const char **argv, void *UNUSED( return 1; } - printf("\nError: you must specify debug value to set.\n"); + fprintf(stderr, "\nError: you must specify debug value to set.\n"); return 0; } @@ -1188,7 +1188,7 @@ static int arg_handle_app_template(int argc, const char **argv, void *UNUSED(dat WM_init_state_app_template_set(app_template); return 1; } - printf("\nError: App template must follow '--app-template'.\n"); + fprintf(stderr, "\nError: App template must follow '--app-template'.\n"); return 0; } @@ -1234,7 +1234,7 @@ static int arg_handle_env_system_set(int argc, const char **argv, void *UNUSED(d const char *ch_src = argv[0] + 5; /* skip --env */ if (argc < 2) { - printf("%s requires one argument\n", argv[0]); + fprintf(stderr, "%s requires one argument\n", argv[0]); exit(1); } @@ -1303,7 +1303,7 @@ static int arg_handle_window_geometry(int argc, const char **argv, void *UNUSED( for (i = 0; i < 4; i++) { const char *err_msg = NULL; if (!parse_int(argv[i + 1], NULL, ¶ms[i], &err_msg)) { - printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); + fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); exit(1); } } @@ -1449,11 +1449,11 @@ static int arg_handle_output_set(int argc, const char **argv, void *data) DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); } else { - printf("\nError: no blend loaded. cannot use '-o / --render-output'.\n"); + fprintf(stderr, "\nError: no blend loaded. cannot use '-o / --render-output'.\n"); } return 1; } - printf("\nError: you must specify a path after '-o / --render-output'.\n"); + fprintf(stderr, "\nError: you must specify a path after '-o / --render-output'.\n"); return 0; } @@ -1481,20 +1481,20 @@ static int arg_handle_engine_set(int argc, const char **argv, void *data) DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); } else { - printf("\nError: engine not found '%s'\n", argv[1]); + fprintf(stderr, "\nError: engine not found '%s'\n", argv[1]); exit(1); } } else { - printf( - "\nError: no blend loaded. " - "order the arguments so '-E / --engine' is after a blend is loaded.\n"); + fprintf(stderr, + "\nError: no blend loaded. " + "order the arguments so '-E / --engine' is after a blend is loaded.\n"); } } return 1; } - printf("\nEngine not specified, give 'help' for a list of available engines.\n"); + fprintf(stderr, "\nEngine not specified, give 'help' for a list of available engines.\n"); return 0; } @@ -1516,9 +1516,9 @@ static int arg_handle_image_type_set(int argc, const char **argv, void *data) const char imtype_new = BKE_imtype_from_arg(imtype); if (imtype_new == R_IMF_IMTYPE_INVALID) { - printf( - "\nError: Format from '-F / --render-format' not known or not compiled in this " - "release.\n"); + fprintf(stderr, + "\nError: Format from '-F / --render-format' not known or not compiled in this " + "release.\n"); } else { scene->r.im_format.imtype = imtype_new; @@ -1526,13 +1526,13 @@ static int arg_handle_image_type_set(int argc, const char **argv, void *data) } } else { - printf( - "\nError: no blend loaded. " - "order the arguments so '-F / --render-format' is after the blend is loaded.\n"); + fprintf(stderr, + "\nError: no blend loaded. " + "order the arguments so '-F / --render-format' is after the blend is loaded.\n"); } return 1; } - printf("\nError: you must specify a format after '-F / --render-format'.\n"); + fprintf(stderr, "\nError: you must specify a format after '-F / --render-format'.\n"); return 0; } @@ -1548,19 +1548,24 @@ static int arg_handle_threads_set(int argc, const char **argv, void *UNUSED(data const char *err_msg = NULL; int threads; if (!parse_int_strict_range(argv[1], NULL, min, max, &threads, &err_msg)) { - printf("\nError: %s '%s %s', expected number in [%d..%d].\n", - err_msg, - arg_id, - argv[1], - min, - max); + fprintf(stderr, + "\nError: %s '%s %s', expected number in [%d..%d].\n", + err_msg, + arg_id, + argv[1], + min, + max); return 1; } BLI_system_num_threads_override_set(threads); return 1; } - printf("\nError: you must specify a number of threads in [%d..%d] '%s'.\n", min, max, arg_id); + fprintf(stderr, + "\nError: you must specify a number of threads in [%d..%d] '%s'.\n", + min, + max, + arg_id); return 0; } @@ -1574,7 +1579,7 @@ static int arg_handle_verbosity_set(int argc, const char **argv, void *UNUSED(da const char *err_msg = NULL; int level; if (!parse_int(argv[1], NULL, &level, &err_msg)) { - printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); + fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); } # ifdef WITH_LIBMV @@ -1587,7 +1592,7 @@ static int arg_handle_verbosity_set(int argc, const char **argv, void *UNUSED(da return 1; } - printf("\nError: you must specify a verbosity level.\n"); + fprintf(stderr, "\nError: you must specify a verbosity level.\n"); return 0; } @@ -1609,17 +1614,18 @@ static int arg_handle_extension_set(int argc, const char **argv, void *data) DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); } else { - printf("\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n"); + fprintf(stderr, + "\nError: Use '-x 1 / -x 0' To set the extension option or '--use-extension'\n"); } } else { - printf( - "\nError: no blend loaded. " - "order the arguments so '-o ' is after '-x '.\n"); + fprintf(stderr, + "\nError: no blend loaded. " + "order the arguments so '-o ' is after '-x '.\n"); } return 1; } - printf("\nError: you must specify a path after '- '.\n"); + fprintf(stderr, "\nError: you must specify a path after '- '.\n"); return 0; } @@ -1652,7 +1658,7 @@ static int arg_handle_render_frame(int argc, const char **argv, void *data) MAXFRAME, &frames_range_len, &err_msg)) == NULL) { - printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); + fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); return 1; } @@ -1663,7 +1669,7 @@ static int arg_handle_render_frame(int argc, const char **argv, void *data) /* We could pass in frame ranges, * but prefer having exact behavior as passing in multiple frames */ if ((frame_range_arr[i][0] <= frame_range_arr[i][1]) == 0) { - printf("\nWarning: negative range ignored '%s %s'.\n", arg_id, argv[1]); + fprintf(stderr, "\nWarning: negative range ignored '%s %s'.\n", arg_id, argv[1]); } for (int frame = frame_range_arr[i][0]; frame <= frame_range_arr[i][1]; frame++) { @@ -1675,10 +1681,10 @@ static int arg_handle_render_frame(int argc, const char **argv, void *data) MEM_freeN(frame_range_arr); return 1; } - printf("\nError: frame number must follow '%s'.\n", arg_id); + fprintf(stderr, "\nError: frame number must follow '%s'.\n", arg_id); return 0; } - printf("\nError: no blend loaded. cannot use '%s'.\n", arg_id); + fprintf(stderr, "\nError: no blend loaded. cannot use '%s'.\n", arg_id); return 0; } @@ -1700,7 +1706,7 @@ static int arg_handle_render_animation(int UNUSED(argc), const char **UNUSED(arg BKE_reports_clear(&reports); } else { - printf("\nError: no blend loaded. cannot use '-a'.\n"); + fprintf(stderr, "\nError: no blend loaded. cannot use '-a'.\n"); } return 0; } @@ -1728,7 +1734,7 @@ static int arg_handle_scene_set(int argc, const char **argv, void *data) } return 1; } - printf("\nError: Scene name must follow '-S / --scene'.\n"); + fprintf(stderr, "\nError: Scene name must follow '-S / --scene'.\n"); return 0; } @@ -1751,17 +1757,17 @@ static int arg_handle_frame_start_set(int argc, const char **argv, void *data) MAXFRAME, &scene->r.sfra, &err_msg)) { - printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); + fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); } else { DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); } return 1; } - printf("\nError: frame number must follow '%s'.\n", arg_id); + fprintf(stderr, "\nError: frame number must follow '%s'.\n", arg_id); return 0; } - printf("\nError: no blend loaded. cannot use '%s'.\n", arg_id); + fprintf(stderr, "\nError: no blend loaded. cannot use '%s'.\n", arg_id); return 0; } @@ -1784,17 +1790,17 @@ static int arg_handle_frame_end_set(int argc, const char **argv, void *data) MAXFRAME, &scene->r.efra, &err_msg)) { - printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); + fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); } else { DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); } return 1; } - printf("\nError: frame number must follow '%s'.\n", arg_id); + fprintf(stderr, "\nError: frame number must follow '%s'.\n", arg_id); return 0; } - printf("\nError: no blend loaded. cannot use '%s'.\n", arg_id); + fprintf(stderr, "\nError: no blend loaded. cannot use '%s'.\n", arg_id); return 0; } @@ -1810,17 +1816,17 @@ static int arg_handle_frame_skip_set(int argc, const char **argv, void *data) if (argc > 1) { const char *err_msg = NULL; if (!parse_int_clamp(argv[1], NULL, 1, MAXFRAME, &scene->r.frame_step, &err_msg)) { - printf("\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); + fprintf(stderr, "\nError: %s '%s %s'.\n", err_msg, arg_id, argv[1]); } else { DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); } return 1; } - printf("\nError: number of frames to step must follow '%s'.\n", arg_id); + fprintf(stderr, "\nError: number of frames to step must follow '%s'.\n", arg_id); return 0; } - printf("\nError: no blend loaded. cannot use '%s'.\n", arg_id); + fprintf(stderr, "\nError: no blend loaded. cannot use '%s'.\n", arg_id); return 0; } @@ -1842,18 +1848,18 @@ static int arg_handle_python_file_run(int argc, const char **argv, void *data) bool ok; BPY_CTX_SETUP(ok = BPY_run_filepath(C, filepath, NULL)); if (!ok && app_state.exit_code_on_error.python) { - printf("\nError: script failed, file: '%s', exiting.\n", argv[1]); + fprintf(stderr, "\nError: script failed, file: '%s', exiting.\n", argv[1]); BPY_python_end(); exit(app_state.exit_code_on_error.python); } return 1; } - printf("\nError: you must specify a filepath after '%s'.\n", argv[0]); + fprintf(stderr, "\nError: you must specify a filepath after '%s'.\n", argv[0]); return 0; # else UNUSED_VARS(argc, argv, data); - printf("This Blender was built without Python support\n"); + fprintf(stderr, "This Blender was built without Python support\n"); return 0; # endif /* WITH_PYTHON */ } @@ -1877,24 +1883,24 @@ static int arg_handle_python_text_run(int argc, const char **argv, void *data) BPY_CTX_SETUP(ok = BPY_run_text(C, text, NULL, false)); } else { - printf("\nError: text block not found %s.\n", argv[1]); + fprintf(stderr, "\nError: text block not found %s.\n", argv[1]); ok = false; } if (!ok && app_state.exit_code_on_error.python) { - printf("\nError: script failed, text: '%s', exiting.\n", argv[1]); + fprintf(stderr, "\nError: script failed, text: '%s', exiting.\n", argv[1]); BPY_python_end(); exit(app_state.exit_code_on_error.python); } return 1; } - printf("\nError: you must specify a text block after '%s'.\n", argv[0]); + fprintf(stderr, "\nError: you must specify a text block after '%s'.\n", argv[0]); return 0; # else UNUSED_VARS(argc, argv, data); - printf("This Blender was built without Python support\n"); + fprintf(stderr, "This Blender was built without Python support\n"); return 0; # endif /* WITH_PYTHON */ } @@ -1912,18 +1918,18 @@ static int arg_handle_python_expr_run(int argc, const char **argv, void *data) bool ok; BPY_CTX_SETUP(ok = BPY_run_string_exec(C, NULL, argv[1])); if (!ok && app_state.exit_code_on_error.python) { - printf("\nError: script failed, expr: '%s', exiting.\n", argv[1]); + fprintf(stderr, "\nError: script failed, expr: '%s', exiting.\n", argv[1]); BPY_python_end(); exit(app_state.exit_code_on_error.python); } return 1; } - printf("\nError: you must specify a Python expression after '%s'.\n", argv[0]); + fprintf(stderr, "\nError: you must specify a Python expression after '%s'.\n", argv[0]); return 0; # else UNUSED_VARS(argc, argv, data); - printf("This Blender was built without Python support\n"); + fprintf(stderr, "This Blender was built without Python support\n"); return 0; # endif /* WITH_PYTHON */ } @@ -1941,7 +1947,7 @@ static int arg_handle_python_console_run(int UNUSED(argc), const char **argv, vo return 0; # else UNUSED_VARS(argv, data); - printf("This Blender was built without python support\n"); + fprintf(stderr, "This Blender was built without python support\n"); return 0; # endif /* WITH_PYTHON */ } @@ -1958,19 +1964,20 @@ static int arg_handle_python_exit_code_set(int argc, const char **argv, void *UN const int min = 0, max = 255; int exit_code; if (!parse_int_strict_range(argv[1], NULL, min, max, &exit_code, &err_msg)) { - printf("\nError: %s '%s %s', expected number in [%d..%d].\n", - err_msg, - arg_id, - argv[1], - min, - max); + fprintf(stderr, + "\nError: %s '%s %s', expected number in [%d..%d].\n", + err_msg, + arg_id, + argv[1], + min, + max); return 1; } app_state.exit_code_on_error.python = (uchar)exit_code; return 1; } - printf("\nError: you must specify an exit code number '%s'.\n", arg_id); + fprintf(stderr, "\nError: you must specify an exit code number '%s'.\n", arg_id); return 0; } @@ -2014,7 +2021,7 @@ static int arg_handle_addons_set(int argc, const char **argv, void *data) # endif /* WITH_PYTHON */ return 1; } - printf("\nError: you must specify a comma separated list after '--addons'.\n"); + fprintf(stderr, "\nError: you must specify a comma separated list after '--addons'.\n"); return 0; } @@ -2068,7 +2075,8 @@ static int arg_handle_load_file(int UNUSED(argc), const char **argv, void *data) printf("... opened default scene instead; saving will write to: %s\n", filepath); } else { - printf( + fprintf( + stderr, "Error: argument has no '.blend' file extension, not using as new file, exiting! %s\n", filepath); G.is_break = true; @@ -2085,7 +2093,7 @@ static const char arg_handle_load_last_file_doc[] = static int arg_handle_load_last_file(int UNUSED(argc), const char **UNUSED(argv), void *data) { if (BLI_listbase_is_empty(&G.recent_files)) { - printf("Warning: no recent files known, opening default startup file instead.\n"); + fprintf(stderr, "Warning: no recent files known, opening default startup file instead.\n"); return -1; } From 72c012ab4a3d2a7f7f59334f4912402338c82e3c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 25 Jan 2023 12:41:59 +1100 Subject: [PATCH 0937/1522] Python: enable user site-packages without --python-use-system-env User site-packages were disabled unless `--python-use-system-env` argument was given. This was done to prevent Blender's Python unintentionally using modules that happened to be installed locally, however it meant so pip installing modules from Blender would fail to load those modules (for some users). Enable user site-packages since it's needed for installing additional packages via pip, see code-comments for details. Resolves T104000. --- source/blender/python/intern/bpy_interface.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index a83dc464e43..8f112c14bb2 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -371,8 +371,14 @@ void BPY_python_start(bContext *C, int argc, const char **argv) * While harmless, it's noisy. */ config.pathconfig_warnings = 0; - /* When using the system's Python, allow the site-directory as well. */ - config.user_site_directory = py_use_system_env; + /* Allow the user site directory because this is used + * when PIP installing packages from Blender, see: T104000. + * + * NOTE(@campbellbarton): While an argument can be made for isolating Blender's Python + * from the users home directory entirely, an alternative directory should be used in that + * case - so PIP can be used to install packages. Otherwise PIP will install packages to a + * directory which us not in the users `sys.path`, see `site.USER_BASE` for details. */ + // config.user_site_directory = py_use_system_env; /* While `sys.argv` is set, we don't want Python to interpret it. */ config.parse_argv = 0; From b898e00edce795d5b7414eb312503e7be5433ac3 Mon Sep 17 00:00:00 2001 From: Weizhen Huang Date: Wed, 25 Jan 2023 11:26:51 +0100 Subject: [PATCH 0938/1522] Cleanup: remove unused KernelGlobals in microfacet BSDF --- intern/cycles/kernel/closure/bsdf.h | 4 ++-- intern/cycles/kernel/closure/bsdf_microfacet.h | 18 +++++++----------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h index 2f53454d7dd..b0d01c427de 100644 --- a/intern/cycles/kernel/closure/bsdf.h +++ b/intern/cycles/kernel/closure/bsdf.h @@ -170,7 +170,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID: case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: label = bsdf_microfacet_ggx_sample( - kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); + sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); break; case CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID: case CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID: @@ -185,7 +185,7 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg, case CLOSURE_BSDF_MICROFACET_BECKMANN_ID: case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: label = bsdf_microfacet_beckmann_sample( - kg, sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); + sc, Ng, sd->wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); break; case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: label = bsdf_ashikhmin_shirley_sample( diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h index 8cf4cfa244d..be21bcd720e 100644 --- a/intern/cycles/kernel/closure/bsdf_microfacet.h +++ b/intern/cycles/kernel/closure/bsdf_microfacet.h @@ -42,8 +42,7 @@ static_assert(sizeof(ShaderClosure) >= sizeof(MicrofacetBsdf), "MicrofacetBsdf i * Eric Heitz and Eugene d'Eon, EGSR 2014. * https://hal.inria.fr/hal-00996995v2/document */ -ccl_device_forceinline float3 microfacet_beckmann_sample_vndf(KernelGlobals kg, - const float3 wi, +ccl_device_forceinline float3 microfacet_beckmann_sample_vndf(const float3 wi, const float alpha_x, const float alpha_y, const float randu, @@ -387,8 +386,7 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc, } template -ccl_device int bsdf_microfacet_sample(KernelGlobals kg, - ccl_private const ShaderClosure *sc, +ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 wi, float randu, @@ -431,7 +429,7 @@ ccl_device int bsdf_microfacet_sample(KernelGlobals kg, } else { /* m_type == MicrofacetType::BECKMANN */ - local_H = microfacet_beckmann_sample_vndf(kg, local_I, alpha_x, alpha_y, randu, randv); + local_H = microfacet_beckmann_sample_vndf(local_I, alpha_x, alpha_y, randu, randv); } const float3 H = X * local_H.x + Y * local_H.y + N * local_H.z; @@ -616,8 +614,7 @@ ccl_device Spectrum bsdf_microfacet_ggx_eval(ccl_private const ShaderClosure *sc return bsdf_microfacet_eval(sc, Ng, wi, wo, pdf); } -ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, - ccl_private const ShaderClosure *sc, +ccl_device int bsdf_microfacet_ggx_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 wi, float randu, @@ -629,7 +626,7 @@ ccl_device int bsdf_microfacet_ggx_sample(KernelGlobals kg, ccl_private float *eta) { return bsdf_microfacet_sample( - kg, sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); + sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); } /* Beckmann microfacet with Smith shadow-masking from: @@ -680,8 +677,7 @@ ccl_device Spectrum bsdf_microfacet_beckmann_eval(ccl_private const ShaderClosur return bsdf_microfacet_eval(sc, Ng, wi, wo, pdf); } -ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, - ccl_private const ShaderClosure *sc, +ccl_device int bsdf_microfacet_beckmann_sample(ccl_private const ShaderClosure *sc, float3 Ng, float3 wi, float randu, @@ -693,7 +689,7 @@ ccl_device int bsdf_microfacet_beckmann_sample(KernelGlobals kg, ccl_private float *eta) { return bsdf_microfacet_sample( - kg, sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); + sc, Ng, wi, randu, randv, eval, wo, pdf, sampled_roughness, eta); } CCL_NAMESPACE_END From e27d1d9bb6628a190eb9eab5f7029ac0e87c8db8 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 25 Jan 2023 12:31:00 +0100 Subject: [PATCH 0939/1522] Fix broken `listdir` code. Error in `bli_builddir` cahnges in B4815d0706fb5 commit. --- source/blender/blenlib/intern/BLI_filelist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c index ae7f6f79a17..7dca60128d3 100644 --- a/source/blender/blenlib/intern/BLI_filelist.c +++ b/source/blender/blenlib/intern/BLI_filelist.c @@ -127,7 +127,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) dirname_with_slash, dirname, sizeof(dirname_with_slash) - 1); if ((dirname_with_slash_len > 0) && - (BLI_path_slash_is_native_compat(dirname_with_slash_len - 1) == false)) { + (BLI_path_slash_is_native_compat(dirname[dirname_with_slash_len - 1]) == false)) { dirname_with_slash[dirname_with_slash_len++] = SEP; dirname_with_slash[dirname_with_slash_len] = '\0'; } From ef3225b9dafaf842a2c4ddfe672b796708b3d12b Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Wed, 25 Jan 2023 13:16:53 +0100 Subject: [PATCH 0940/1522] Cleanup: Workbench Next: Remove UNUSED_VARS --- source/blender/draw/engines/workbench/workbench_shadow.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/draw/engines/workbench/workbench_shadow.cc b/source/blender/draw/engines/workbench/workbench_shadow.cc index 15c18ffef9d..34db0a0dfe9 100644 --- a/source/blender/draw/engines/workbench/workbench_shadow.cc +++ b/source/blender/draw/engines/workbench/workbench_shadow.cc @@ -209,9 +209,9 @@ void ShadowPass::ShadowView::set_mode(ShadowPass::PassType type) void ShadowPass::ShadowView::compute_visibility(ObjectBoundsBuf &bounds, uint resource_len, - bool debug_freeze) + bool /*debug_freeze*/) { - UNUSED_VARS(debug_freeze); + /* TODO (Miguel Pozo): Add debug_freeze support */ GPU_debug_group_begin("ShadowView.compute_visibility"); From 12ca26afc272b883455bb99ee2add5deedcf740d Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Mon, 23 Jan 2023 13:50:34 +0100 Subject: [PATCH 0941/1522] Fix T104089: Removing greasepencil vertex group can leave no active We should always have an active vertexgroup (making sure this is the case was just not happening on the greasepencil side). Now do this (similar to what is done for other object types in `object_defgroup_remove_common`). Maniphest Tasks: T104089 Differential Revision: https://developer.blender.org/D17091 --- source/blender/blenkernel/intern/gpencil.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 97e3ff43cd9..b77f43276e7 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -1861,6 +1861,18 @@ void BKE_gpencil_vgroup_remove(Object *ob, bDeformGroup *defgroup) /* Remove the group */ BLI_freelinkN(&gpd->vertex_group_names, defgroup); + + /* Update the active deform index if necessary. */ + const int active_index = BKE_object_defgroup_active_index_get(ob); + if (active_index > def_nr) { + BKE_object_defgroup_active_index_set(ob, active_index - 1); + } + /* Keep a valid active index if we still have some vertex groups. */ + if (!BLI_listbase_is_empty(&gpd->vertex_group_names) && + BKE_object_defgroup_active_index_get(ob) < 1) { + BKE_object_defgroup_active_index_set(ob, 1); + } + DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); } From 69288daa74c101a0126a154a4c8a741e9c373636 Mon Sep 17 00:00:00 2001 From: Faheim Arslan M Date: Wed, 25 Jan 2023 16:22:58 +0100 Subject: [PATCH 0942/1522] Fix T100674: Use plural for axes option in object properties This commit fixes T100674, Renamed the "axis" label under viewport display panel to "axes" in object properties. Differential Revision: https://developer.blender.org/D16650 --- release/scripts/startup/bl_ui/properties_object.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py index 6ab4bb3af69..836ac2dcb75 100644 --- a/release/scripts/startup/bl_ui/properties_object.py +++ b/release/scripts/startup/bl_ui/properties_object.py @@ -200,7 +200,7 @@ class OBJECT_PT_display(ObjectButtonsPanel, Panel): col = layout.column(heading="Show") col.prop(obj, "show_name", text="Name") - col.prop(obj, "show_axis", text="Axis") + col.prop(obj, "show_axis", text="Axes") # Makes no sense for cameras, armatures, etc.! # but these settings do apply to dupli instances From ffe45ad87a564fd2cb7d53f222785ecb608a6e30 Mon Sep 17 00:00:00 2001 From: Michael Kowalski Date: Wed, 25 Jan 2023 10:46:07 -0500 Subject: [PATCH 0943/1522] USD import unused materials. Added a new Import All Materials USD import option. When this option is enabled, USD materials not used by any geometry will be included in the import. Imported materials with no users will have a fake user assigned. Maniphest Tasks: T97195 Differential Revision: https://developer.blender.org/D16172 --- source/blender/editors/io/io_usd.c | 14 +++- .../blender/io/usd/intern/usd_capi_import.cc | 8 ++ .../io/usd/intern/usd_reader_material.cc | 41 ++++++++++ .../io/usd/intern/usd_reader_material.h | 30 ++++++++ .../blender/io/usd/intern/usd_reader_mesh.cc | 54 +------------ .../blender/io/usd/intern/usd_reader_stage.cc | 77 +++++++++++++++++++ .../blender/io/usd/intern/usd_reader_stage.h | 15 ++++ source/blender/io/usd/usd.h | 1 + 8 files changed, 187 insertions(+), 53 deletions(-) diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c index acd60bbd40a..99d4e84cfd4 100644 --- a/source/blender/editors/io/io_usd.c +++ b/source/blender/editors/io/io_usd.c @@ -381,6 +381,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op) const bool import_proxy = RNA_boolean_get(op->ptr, "import_proxy"); const bool import_render = RNA_boolean_get(op->ptr, "import_render"); + const bool import_all_materials = RNA_boolean_get(op->ptr, "import_all_materials"); + const bool import_usd_preview = RNA_boolean_get(op->ptr, "import_usd_preview"); const bool set_material_blend = RNA_boolean_get(op->ptr, "set_material_blend"); @@ -427,7 +429,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op) .import_usd_preview = import_usd_preview, .set_material_blend = set_material_blend, .light_intensity_scale = light_intensity_scale, - .mtl_name_collision_mode = mtl_name_collision_mode}; + .mtl_name_collision_mode = mtl_name_collision_mode, + .import_all_materials = import_all_materials}; STRNCPY(params.prim_path_mask, prim_path_mask); @@ -480,6 +483,7 @@ static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op) box = uiLayoutBox(layout); col = uiLayoutColumnWithHeading(box, true, IFACE_("Materials")); + uiItemR(col, ptr, "import_all_materials", 0, NULL, ICON_NONE); uiItemR(col, ptr, "import_usd_preview", 0, NULL, ICON_NONE); uiLayoutSetEnabled(col, RNA_boolean_get(ptr, "import_materials")); uiLayout *row = uiLayoutRow(col, true); @@ -579,6 +583,14 @@ void WM_OT_usd_import(struct wmOperatorType *ot) RNA_def_boolean(ot->srna, "import_render", true, "Render", "Import final render geometry"); + RNA_def_boolean(ot->srna, + "import_all_materials", + false, + "Import All Materials", + "Also import materials that are not used by any geometry. " + "Note that when this option is false, materials referenced " + "by geometry will still be imported"); + RNA_def_boolean(ot->srna, "import_usd_preview", true, diff --git a/source/blender/io/usd/intern/usd_capi_import.cc b/source/blender/io/usd/intern/usd_capi_import.cc index 600d1f0a9eb..66319a7f04e 100644 --- a/source/blender/io/usd/intern/usd_capi_import.cc +++ b/source/blender/io/usd/intern/usd_capi_import.cc @@ -227,6 +227,10 @@ static void import_startjob(void *customdata, bool *stop, bool *do_update, float archive->collect_readers(data->bmain); + if (data->params.import_materials && data->params.import_all_materials) { + archive->import_all_materials(data->bmain); + } + *data->do_update = true; *data->progress = 0.2f; @@ -352,6 +356,10 @@ static void import_endjob(void *customdata) DEG_id_tag_update(&data->scene->id, ID_RECALC_BASE_FLAGS); DEG_relations_tag_update(data->bmain); + + if (data->params.import_materials && data->params.import_all_materials) { + data->archive->fake_users_for_unused_materials(); + } } WM_set_locked_interface(data->wm, false); diff --git a/source/blender/io/usd/intern/usd_reader_material.cc b/source/blender/io/usd/intern/usd_reader_material.cc index d1af4553083..351f9bc3438 100644 --- a/source/blender/io/usd/intern/usd_reader_material.cc +++ b/source/blender/io/usd/intern/usd_reader_material.cc @@ -757,4 +757,45 @@ void USDMaterialReader::convert_usd_primvar_reader_float2( link_nodes(ntree, uv_map, "UV", dest_node, dest_socket_name); } +void build_material_map(const Main *bmain, std::map *r_mat_map) +{ + BLI_assert_msg(r_mat_map, "..."); + + LISTBASE_FOREACH (Material *, material, &bmain->materials) { + std::string usd_name = pxr::TfMakeValidIdentifier(material->id.name + 2); + (*r_mat_map)[usd_name] = material; + } +} + +Material *find_existing_material(const pxr::SdfPath &usd_mat_path, + const USDImportParams ¶ms, + const std::map &mat_map, + const std::map &usd_path_to_mat_name) +{ + if (params.mtl_name_collision_mode == USD_MTL_NAME_COLLISION_MAKE_UNIQUE) { + /* Check if we've already created the Blender material with a modified name. */ + std::map::const_iterator path_to_name_iter = + usd_path_to_mat_name.find(usd_mat_path.GetAsString()); + + if (path_to_name_iter == usd_path_to_mat_name.end()) { + return nullptr; + } + + std::string mat_name = path_to_name_iter->second; + std::map::const_iterator mat_iter = mat_map.find(mat_name); + BLI_assert_msg(mat_iter != mat_map.end(), + "Previously created material cannot be found any more"); + return mat_iter->second; + } + + std::string mat_name = usd_mat_path.GetName(); + std::map::const_iterator mat_iter = mat_map.find(mat_name); + + if (mat_iter == mat_map.end()) { + return nullptr; + } + + return mat_iter->second; +} + } // namespace blender::io::usd diff --git a/source/blender/io/usd/intern/usd_reader_material.h b/source/blender/io/usd/intern/usd_reader_material.h index 24d80e99c38..6fd6d2f1213 100644 --- a/source/blender/io/usd/intern/usd_reader_material.h +++ b/source/blender/io/usd/intern/usd_reader_material.h @@ -6,6 +6,8 @@ #include +#include + struct Main; struct Material; struct bNode; @@ -129,4 +131,32 @@ class USDMaterialReader { NodePlacementContext *r_ctx) const; }; +/* Utility functions. */ + +/** + * Returns a map containing all the Blender materials which allows a fast + * lookup of the material by name. Note that the material name key + * might be modified to be a valid USD identifier, to match material + * names in the imported USD. + */ +void build_material_map(const Main *bmain, std::map *r_mat_map); + +/** + * Returns an existing Blender material that corresponds to the USD material with the given path. + * Returns null if no such material exists. + * + * \param mat_map Map a material name to a Blender material. Note that the name key + * might be the Blender material name modified to be a valid USD identifier, + * to match the material names in the imported USD. + * \param usd_path_to_mat_name Map a USD material path to the imported Blender material name. + * + * The usd_path_to_mat_name is needed to determine the name of the Blender + * material imported from a USD path in the case when a unique name was generated + * for the material due to a name collision. + */ +Material *find_existing_material(const pxr::SdfPath &usd_mat_path, + const USDImportParams ¶ms, + const std::map &mat_map, + const std::map &usd_path_to_mat_name); + } // namespace blender::io::usd diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index f961fa64a05..fd4b80b9137 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -49,20 +49,6 @@ static const pxr::TfToken normalsPrimvar("normals", pxr::TfToken::Immortal); } // namespace usdtokens namespace utils { -/* Very similar to #blender::io::alembic::utils. */ -static void build_mat_map(const Main *bmain, std::map *r_mat_map) -{ - if (r_mat_map == nullptr) { - return; - } - - Material *material = static_cast(bmain->materials.first); - - for (; material; material = static_cast(material->id.next)) { - /* We have to do this because the stored material name is coming directly from USD. */ - (*r_mat_map)[pxr::TfMakeValidIdentifier(material->id.name + 2)] = material; - } -} static pxr::UsdShadeMaterial compute_bound_material(const pxr::UsdPrim &prim) { @@ -84,42 +70,6 @@ static pxr::UsdShadeMaterial compute_bound_material(const pxr::UsdPrim &prim) return mtl; } -/* Returns an existing Blender material that corresponds to the USD material with the given path. - * Returns null if no such material exists. */ -static Material *find_existing_material( - const pxr::SdfPath &usd_mat_path, - const USDImportParams ¶ms, - const std::map &mat_map, - const std::map &usd_path_to_mat_name) -{ - if (params.mtl_name_collision_mode == USD_MTL_NAME_COLLISION_MAKE_UNIQUE) { - /* Check if we've already created the Blender material with a modified name. */ - std::map::const_iterator path_to_name_iter = - usd_path_to_mat_name.find(usd_mat_path.GetAsString()); - - if (path_to_name_iter != usd_path_to_mat_name.end()) { - std::string mat_name = path_to_name_iter->second; - std::map::const_iterator mat_iter = mat_map.find(mat_name); - if (mat_iter != mat_map.end()) { - return mat_iter->second; - } - /* We can't find the Blender material which was previously created for this USD - * material, which should never happen. */ - BLI_assert_unreachable(); - } - } - else { - std::string mat_name = usd_mat_path.GetName(); - std::map::const_iterator mat_iter = mat_map.find(mat_name); - - if (mat_iter != mat_map.end()) { - return mat_iter->second; - } - } - - return nullptr; -} - static void assign_materials(Main *bmain, Object *ob, const std::map &mat_index_map, @@ -142,7 +92,7 @@ static void assign_materials(Main *bmain, it != mat_index_map.end(); ++it) { - Material *assigned_mat = find_existing_material( + Material *assigned_mat = blender::io::usd::find_existing_material( it->first, params, mat_name_to_mat, usd_path_to_mat_name); if (!assigned_mat) { /* Blender material doesn't exist, so create it now. */ @@ -805,7 +755,7 @@ void USDMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, const double mot material_indices.finish(); /* Build material name map if it's not built yet. */ if (this->settings_->mat_name_to_mat.empty()) { - utils::build_mat_map(bmain, &this->settings_->mat_name_to_mat); + build_material_map(bmain, &this->settings_->mat_name_to_mat); } utils::assign_materials(bmain, object_, diff --git a/source/blender/io/usd/intern/usd_reader_stage.cc b/source/blender/io/usd/intern/usd_reader_stage.cc index df75be849e2..0c179ceae48 100644 --- a/source/blender/io/usd/intern/usd_reader_stage.cc +++ b/source/blender/io/usd/intern/usd_reader_stage.cc @@ -5,6 +5,7 @@ #include "usd_reader_camera.h" #include "usd_reader_curve.h" #include "usd_reader_light.h" +#include "usd_reader_material.h" #include "usd_reader_mesh.h" #include "usd_reader_nurbs.h" #include "usd_reader_prim.h" @@ -12,12 +13,14 @@ #include "usd_reader_xform.h" #include +#include #include #include #include #include #include #include +#include #if PXR_VERSION >= 2111 # include @@ -31,6 +34,10 @@ #include "BLI_sort.hh" #include "BLI_string.h" +#include "BKE_lib_id.h" + +#include "DNA_material_types.h" + namespace blender::io::usd { USDStageReader::USDStageReader(pxr::UsdStageRefPtr stage, @@ -249,6 +256,15 @@ USDPrimReader *USDStageReader::collect_readers(Main *bmain, const pxr::UsdPrim & } } + if (prim.IsA()) { + /* Record material path for later processing, if needed, + * e.g., when importing all materials. */ + material_paths_.push_back(prim.GetPath().GetAsString()); + + /* We don't create readers for materials, so return early. */ + return nullptr; + } + USDPrimReader *reader = create_reader_if_allowed(prim); if (!reader) { @@ -294,6 +310,67 @@ void USDStageReader::collect_readers(Main *bmain) collect_readers(bmain, root); } +void USDStageReader::import_all_materials(Main *bmain) +{ + BLI_assert(valid()); + + /* Build the material name map if it's not built yet. */ + if (settings_.mat_name_to_mat.empty()) { + build_material_map(bmain, &settings_.mat_name_to_mat); + } + + USDMaterialReader mtl_reader(params_, bmain); + + for (const std::string &mtl_path : material_paths_) { + pxr::UsdPrim prim = stage_->GetPrimAtPath(pxr::SdfPath(mtl_path)); + + pxr::UsdShadeMaterial usd_mtl(prim); + if (!usd_mtl) { + continue; + } + + if (blender::io::usd::find_existing_material( + prim.GetPath(), params_, settings_.mat_name_to_mat, settings_.usd_path_to_mat_name)) { + /* The material already exists. */ + continue; + } + + /* Add the material now. */ + Material *new_mtl = mtl_reader.add_material(usd_mtl); + BLI_assert_msg(new_mtl, "Failed to create material"); + + const std::string mtl_name = pxr::TfMakeValidIdentifier(new_mtl->id.name + 2); + settings_.mat_name_to_mat[mtl_name] = new_mtl; + + if (params_.mtl_name_collision_mode == USD_MTL_NAME_COLLISION_MAKE_UNIQUE) { + /* Record the unique name of the Blender material we created for the USD material + * with the given path, so we don't import the material again when assigning + * materials to objects elsewhere in the code. */ + settings_.usd_path_to_mat_name[prim.GetPath().GetAsString()] = mtl_name; + } + } +} + +void USDStageReader::fake_users_for_unused_materials() +{ + /* Iterate over the imported materials and set a fake user for any unused + * materials. */ + for (const std::pair &path_mat_pair : settings_.usd_path_to_mat_name) { + + std::map::iterator mat_it = settings_.mat_name_to_mat.find( + path_mat_pair.second); + + if (mat_it == settings_.mat_name_to_mat.end()) { + continue; + } + + Material *mat = mat_it->second; + if (mat->id.us == 0) { + id_fake_user_set(&mat->id); + } + } +} + void USDStageReader::clear_readers() { for (USDPrimReader *reader : readers_) { diff --git a/source/blender/io/usd/intern/usd_reader_stage.h b/source/blender/io/usd/intern/usd_reader_stage.h index 5f4a343f874..9b2c37132bc 100644 --- a/source/blender/io/usd/intern/usd_reader_stage.h +++ b/source/blender/io/usd/intern/usd_reader_stage.h @@ -27,6 +27,10 @@ class USDStageReader { std::vector readers_; + /* USD material prim paths encountered during stage + * traversal, for importing unused materials. */ + std::vector material_paths_; + public: USDStageReader(pxr::UsdStageRefPtr stage, const USDImportParams ¶ms, @@ -40,6 +44,17 @@ class USDStageReader { void collect_readers(struct Main *bmain); + /* Convert every material prim on the stage to a Blender + * material, including materials not used by any geometry. + * Note that collect_readers() must be called before calling + * import_all_materials(). */ + void import_all_materials(struct Main *bmain); + + /* Add fake users for any imported materials with no + * users. This is typically required when importing all + * materials. */ + void fake_users_for_unused_materials(); + bool valid() const; pxr::UsdStageRefPtr stage() diff --git a/source/blender/io/usd/usd.h b/source/blender/io/usd/usd.h index 9d5cda64424..ffd3bd6df4c 100644 --- a/source/blender/io/usd/usd.h +++ b/source/blender/io/usd/usd.h @@ -64,6 +64,7 @@ struct USDImportParams { bool set_material_blend; float light_intensity_scale; eUSDMtlNameCollisionMode mtl_name_collision_mode; + bool import_all_materials; }; /* The USD_export takes a as_background_job parameter, and returns a boolean. From e744673268a1144034631661ce8d897277454e25 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Wed, 25 Jan 2023 16:40:04 +0100 Subject: [PATCH 0944/1522] Draw: Improve Texture assignment operator Differential Revision: https://developer.blender.org/D17119 --- source/blender/draw/intern/DRW_gpu_wrapper.hh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/intern/DRW_gpu_wrapper.hh b/source/blender/draw/intern/DRW_gpu_wrapper.hh index 6d8c4cc8e87..22ad08b1cb9 100644 --- a/source/blender/draw/intern/DRW_gpu_wrapper.hh +++ b/source/blender/draw/intern/DRW_gpu_wrapper.hh @@ -560,10 +560,20 @@ class Texture : NonCopyable { Texture &operator=(Texture &&a) { - if (*this != a) { + if (this != std::addressof(a)) { + this->free(); + this->tx_ = a.tx_; this->name_ = a.name_; + this->stencil_view_ = a.stencil_view_; + this->mip_views_ = std::move(a.mip_views_); + this->layer_views_ = std::move(a.layer_views_); + a.tx_ = nullptr; + a.name_ = nullptr; + a.stencil_view_ = nullptr; + a.mip_views_.clear(); + a.layer_views_.clear(); } return *this; } From 405b08e00da6841e27739573e85240ba30c3633f Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Wed, 25 Jan 2023 17:12:14 +0100 Subject: [PATCH 0945/1522] Fix: Workbench Next: Ensure matcaps textures are loaded --- source/blender/draw/engines/workbench/workbench_resources.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/draw/engines/workbench/workbench_resources.cc b/source/blender/draw/engines/workbench/workbench_resources.cc index d33b57b943e..25a2b284c40 100644 --- a/source/blender/draw/engines/workbench/workbench_resources.cc +++ b/source/blender/draw/engines/workbench/workbench_resources.cc @@ -8,8 +8,11 @@ namespace blender::workbench { -static bool get_matcap_tx(Texture &matcap_tx, const StudioLight &studio_light) +static bool get_matcap_tx(Texture &matcap_tx, StudioLight &studio_light) { + BKE_studiolight_ensure_flag(&studio_light, + STUDIOLIGHT_MATCAP_DIFFUSE_GPUTEXTURE | + STUDIOLIGHT_MATCAP_SPECULAR_GPUTEXTURE); ImBuf *matcap_diffuse = studio_light.matcap_diffuse.ibuf; ImBuf *matcap_specular = studio_light.matcap_specular.ibuf; if (matcap_diffuse && matcap_diffuse->rect_float) { From f954029e97c866a971b62a2faadf35fdb80b73bf Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 25 Jan 2023 11:38:12 -0600 Subject: [PATCH 0946/1522] Curves Sculpt: Add report about missing surface for puff brush This is done in the other sculpt brushes that require a surface object. --- source/blender/editors/sculpt_paint/curves_sculpt_puff.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc index e44e97bc840..dcb7a3ae797 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_puff.cc @@ -92,6 +92,7 @@ struct PuffOperationExecutor { return; } if (curves_id_->surface == nullptr || curves_id_->surface->type != OB_MESH) { + report_missing_surface(stroke_extension.reports); return; } From 2f9346bc0af6c801bee15a6ddcf56369b4e4b3d9 Mon Sep 17 00:00:00 2001 From: Sibo Van Gool Date: Wed, 25 Jan 2023 11:42:10 -0600 Subject: [PATCH 0947/1522] Fix T104071: Mix up in Realize Instances tooltip text A mistake in the node type descriptions gave the node a description for the reverse curve node. Differential Revision: https://developer.blender.org/D17111 --- source/blender/nodes/NOD_static_types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 33fc7249fad..6b8b917f3e0 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -384,11 +384,11 @@ DefNode(GeometryNode, GEO_NODE_POINTS_TO_VOLUME, def_geo_points_to_volume, "POIN DefNode(GeometryNode, GEO_NODE_POINTS, 0, "POINTS", Points, "Points", "Generate a point cloud with positions and radii defined by fields") DefNode(GeometryNode, GEO_NODE_PROXIMITY, def_geo_proximity, "PROXIMITY", Proximity, "Geometry Proximity", "Compute the closest location on the target geometry") DefNode(GeometryNode, GEO_NODE_RAYCAST, def_geo_raycast, "RAYCAST", Raycast, "Raycast", "Cast rays from the context geometry onto a target geometry, and retrieve information from each hit point") -DefNode(GeometryNode, GEO_NODE_REALIZE_INSTANCES, def_geo_realize_instances,"REALIZE_INSTANCES", RealizeInstances, "Realize Instances", "Change the direction of the curve by swapping each spline's start and end data") +DefNode(GeometryNode, GEO_NODE_REALIZE_INSTANCES, def_geo_realize_instances,"REALIZE_INSTANCES", RealizeInstances, "Realize Instances", "Convert instances into real geometry data") DefNode(GeometryNode, GEO_NODE_REMOVE_ATTRIBUTE, 0, "REMOVE_ATTRIBUTE", RemoveAttribute, "Remove Named Attribute", "Delete an attribute with a specified name from a geometry. Typically used to optimize performance") DefNode(GeometryNode, GEO_NODE_REPLACE_MATERIAL, 0, "REPLACE_MATERIAL", ReplaceMaterial, "Replace Material", "Swap one material with another") DefNode(GeometryNode, GEO_NODE_RESAMPLE_CURVE, def_geo_curve_resample, "RESAMPLE_CURVE", ResampleCurve, "Resample Curve", "Generate a poly spline for each input spline") -DefNode(GeometryNode, GEO_NODE_REVERSE_CURVE, 0, "REVERSE_CURVE", ReverseCurve, "Reverse Curve", "Swap the start and end of splines") +DefNode(GeometryNode, GEO_NODE_REVERSE_CURVE, 0, "REVERSE_CURVE", ReverseCurve, "Reverse Curve", "Change the direction of curves by swapping their start and end data") DefNode(GeometryNode, GEO_NODE_ROTATE_INSTANCES, 0, "ROTATE_INSTANCES", RotateInstances, "Rotate Instances", "Rotate geometry instances in local or global space") DefNode(GeometryNode, GEO_NODE_SAMPLE_CURVE, def_geo_curve_sample, "SAMPLE_CURVE", SampleCurve, "Sample Curve", "Retrieve data from a point on a curve at a certain distance from its start") DefNode(GeometryNode, GEO_NODE_SAMPLE_INDEX, def_geo_sample_index, "SAMPLE_INDEX", SampleIndex, "Sample Index", "Retrieve values from specific geometry elements") From 9ad051140c102c76dbebe03d4a238b733034cfba Mon Sep 17 00:00:00 2001 From: Ray Molenkamp Date: Wed, 25 Jan 2023 10:58:42 -0700 Subject: [PATCH 0948/1522] Revert "Fix T71137: curve minimum twist producing wrong geometry" This reverts commit 36a82314a0f5de65b54f6d8343a2899ed4e37010. as it has broken tests for the last day and a half, it likely just needs a test file update, but we can't keep this failing longer than it already has. --- source/blender/blenkernel/intern/curve.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index 51902169366..744ef0e8009 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -2260,7 +2260,7 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl) nr = bl->nr; while (nr--) { - if (nr + 1 >= bl->nr) { /* First time, otherwise first point adjusts last. */ + if (nr + 3 > bl->nr) { /* first time and second time, otherwise first point adjusts last */ vec_to_quat(bevp1->quat, bevp1->dir, 5, 1); } else { From 6e0d58a68a866d632a6427d51f7ad41002566248 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Wed, 25 Jan 2023 12:56:05 -0600 Subject: [PATCH 0949/1522] Cleanup: Edit Mesh: Decrease variable scope, use bool instead of int --- source/blender/editors/mesh/editmesh_utils.c | 70 ++++++++------------ 1 file changed, 27 insertions(+), 43 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index f54284ef81a..c0815257afa 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -63,10 +63,8 @@ BMBackup EDBM_redo_state_store(BMEditMesh *em) void EDBM_redo_state_restore(BMBackup *backup, BMEditMesh *em, bool recalc_looptri) { - BMesh *tmpbm; - BM_mesh_data_free(em->bm); - tmpbm = BM_mesh_copy(backup->bmcopy); + BMesh *tmpbm = BM_mesh_copy(backup->bmcopy); *em->bm = *tmpbm; MEM_freeN(tmpbm); tmpbm = NULL; @@ -208,11 +206,9 @@ bool EDBM_op_call_and_selectf(BMEditMesh *em, const char *fmt, ...) { - BMOpSlot *slot_select_out; BMesh *bm = em->bm; BMOperator bmop; va_list list; - char hflag; va_start(list, fmt); @@ -224,8 +220,8 @@ bool EDBM_op_call_and_selectf(BMEditMesh *em, BMO_op_exec(bm, &bmop); - slot_select_out = BMO_slot_get(bmop.slots_out, select_slot_out); - hflag = slot_select_out->slot_subtype.elem & BM_ALL_NOLOOP; + BMOpSlot *slot_select_out = BMO_slot_get(bmop.slots_out, select_slot_out); + char hflag = slot_select_out->slot_subtype.elem & BM_ALL_NOLOOP; BLI_assert(hflag != 0); if (select_extend == false) { @@ -269,14 +265,12 @@ bool EDBM_op_call_silentf(BMEditMesh *em, const char *fmt, ...) void EDBM_mesh_make(Object *ob, const int select_mode, const bool add_key_index) { Mesh *me = ob->data; - BMesh *bm; - - bm = BKE_mesh_to_bmesh(me, - ob, - add_key_index, - &((struct BMeshCreateParams){ - .use_toolflags = true, - })); + BMesh *bm = BKE_mesh_to_bmesh(me, + ob, + add_key_index, + &((struct BMeshCreateParams){ + .use_toolflags = true, + })); if (me->edit_mesh) { /* this happens when switching shape keys */ @@ -456,21 +450,15 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us BMFace *efa; BMLoop *l; BMIter iter, liter; - /* vars from original func */ - UvVertMap *vmap; - UvMapVert *buf; - const float(*luv)[2]; uint a; - int totverts, i, totuv, totfaces; const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2); - bool *winding = NULL; BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE); BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE); - totfaces = bm->totface; - totverts = bm->totvert; - totuv = 0; + const int totfaces = bm->totface; + const int totverts = bm->totvert; + int totuv = 0; /* generate UvMapVert array */ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { @@ -482,13 +470,15 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us if (totuv == 0) { return NULL; } - vmap = (UvVertMap *)MEM_callocN(sizeof(*vmap), "UvVertMap"); + UvVertMap *vmap = (UvVertMap *)MEM_callocN(sizeof(*vmap), "UvVertMap"); if (!vmap) { return NULL; } vmap->vert = (UvMapVert **)MEM_callocN(sizeof(*vmap->vert) * totverts, "UvMapVert_pt"); - buf = vmap->buf = (UvMapVert *)MEM_callocN(sizeof(*vmap->buf) * totuv, "UvMapVert"); + UvMapVert *buf = vmap->buf = (UvMapVert *)MEM_callocN(sizeof(*vmap->buf) * totuv, "UvMapVert"); + + bool *winding = NULL; if (use_winding) { winding = MEM_callocN(sizeof(*winding) * totfaces, "winding"); } @@ -506,6 +496,7 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us tf_uv = (float(*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa->len); } + int i; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { buf->loop_of_poly_index = i; buf->poly_index = a; @@ -516,7 +507,7 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us buf++; if (use_winding) { - luv = BM_ELEM_CD_GET_FLOAT2_P(l, cd_loop_uv_offset); + const float(*luv)[2] = BM_ELEM_CD_GET_FLOAT2_P(l, cd_loop_uv_offset); copy_v2_v2(tf_uv[i], *luv); } } @@ -1263,14 +1254,10 @@ UvElement *BM_uv_element_get_head(UvElementMap *element_map, UvElement *child) BMFace *EDBM_uv_active_face_get(BMEditMesh *em, const bool sloppy, const bool selected) { - BMFace *efa = NULL; - if (!EDBM_uv_check(em)) { return NULL; } - - efa = BM_mesh_active_face_get(em->bm, sloppy, selected); - + BMFace *efa = BM_mesh_active_face_get(em->bm, sloppy, selected); if (efa) { return efa; } @@ -1765,10 +1752,10 @@ void EDBM_update_extern(struct Mesh *me, const bool do_tessellation, const bool bool EDBM_view3d_poll(bContext *C) { if (ED_operator_editmesh(C) && ED_operator_view3d_active(C)) { - return 1; + return true; } - return 0; + return false; } /** \} */ @@ -1779,19 +1766,16 @@ bool EDBM_view3d_poll(bContext *C) BMElem *EDBM_elem_from_selectmode(BMEditMesh *em, BMVert *eve, BMEdge *eed, BMFace *efa) { - BMElem *ele = NULL; - if ((em->selectmode & SCE_SELECT_VERTEX) && eve) { - ele = (BMElem *)eve; + return (BMElem *)eve; } - else if ((em->selectmode & SCE_SELECT_EDGE) && eed) { - ele = (BMElem *)eed; + if ((em->selectmode & SCE_SELECT_EDGE) && eed) { + return (BMElem *)eed; } - else if ((em->selectmode & SCE_SELECT_FACE) && efa) { - ele = (BMElem *)efa; + if ((em->selectmode & SCE_SELECT_FACE) && efa) { + return (BMElem *)efa; } - - return ele; + return NULL; } int EDBM_elem_to_index_any(BMEditMesh *em, BMElem *ele) From feae1c7d055f8817a9f0cedbb9a1432aede7f9cb Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 25 Jan 2023 13:54:51 +0100 Subject: [PATCH 0950/1522] Gitea: update issue template with new scoped labels and other tweaks --- .gitea/issue_template/bug.yaml | 7 +++++-- .gitea/issue_template/design.yaml | 3 ++- .gitea/issue_template/todo.yaml | 3 ++- .gitea/pull_request_template.yaml | 1 + 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.gitea/issue_template/bug.yaml b/.gitea/issue_template/bug.yaml index 9c4618c3223..4e3c550dae9 100644 --- a/.gitea/issue_template/bug.yaml +++ b/.gitea/issue_template/bug.yaml @@ -1,13 +1,15 @@ name: Bug Report about: File a bug report labels: - - bug + - "type::Report" + - "status::Needs Triage" + - "priority::Normal" body: - type: markdown attributes: value: | ### Instructions - First time reporting? See [tips](https://wiki.blender.org/wiki/Process/Bug_Reports) and [walkthrough video](https://www.youtube.com/watch?v=JTD0OJq_rF4). + First time reporting? See [tips](https://wiki.blender.org/wiki/Process/Bug_Reports). * Use **Help > Report a Bug** in Blender to fill system information and exact Blender version. * Test [daily builds](https://builder.blender.org/) to verify if the issue is already fixed. @@ -19,6 +21,7 @@ body: id: body attributes: label: "Description" + hide_label: true value: | **System Information** Operating system: diff --git a/.gitea/issue_template/design.yaml b/.gitea/issue_template/design.yaml index 8c2c6deef29..a1dcd8b0eda 100644 --- a/.gitea/issue_template/design.yaml +++ b/.gitea/issue_template/design.yaml @@ -1,9 +1,10 @@ name: Design about: Create a design task (for developers only) labels: - - design + - "type::Design" body: - type: textarea id: body attributes: label: "Description" + hide_label: true diff --git a/.gitea/issue_template/todo.yaml b/.gitea/issue_template/todo.yaml index e7fecf043ca..58e848c3e18 100644 --- a/.gitea/issue_template/todo.yaml +++ b/.gitea/issue_template/todo.yaml @@ -1,9 +1,10 @@ name: To Do about: Create a to do task (for developers only) labels: - - todo + - "type::To Do" body: - type: textarea id: body attributes: label: "Description" + hide_label: true diff --git a/.gitea/pull_request_template.yaml b/.gitea/pull_request_template.yaml index 6affe8cf8d2..a6f1f2db20f 100644 --- a/.gitea/pull_request_template.yaml +++ b/.gitea/pull_request_template.yaml @@ -14,6 +14,7 @@ body: id: body attributes: label: "Description" + hide_label: true value: | Description of the problem that is addressed in the patch. From fa57c691f663bf4b446ccf0f91ce82ed9a2078b2 Mon Sep 17 00:00:00 2001 From: Michael Kowalski Date: Wed, 25 Jan 2023 14:51:39 -0500 Subject: [PATCH 0951/1522] USD IO CI Tests Various new CI tests for USD Import / Export functionalty: Import: - Added mesh import tests for topology types and multiple UV sets. (Python) Export: - Added a verification tests for mesh topology. (C++) - Added a test to make sure UsdPreviewSurface export conversion of materials is correct. (C++) Reviewed by: Sybren and Hans. Differential Revision: https://developer.blender.org/D16274 --- .../tests/blendfile_loading_base_test.cc | 2 +- source/blender/io/usd/CMakeLists.txt | 5 + .../blender/io/usd/intern/usd_capi_export.cc | 8 +- .../blender/io/usd/intern/usd_capi_import.cc | 1 + .../io/usd/intern/usd_writer_material.cc | 12 + .../io/usd/intern/usd_writer_material.h | 4 + .../blender/io/usd/tests/usd_export_test.cc | 314 ++++++++++++++++++ tests/python/bl_usd_import_test.py | 122 ++++++- 8 files changed, 458 insertions(+), 10 deletions(-) create mode 100644 source/blender/io/usd/tests/usd_export_test.cc diff --git a/source/blender/blenloader/tests/blendfile_loading_base_test.cc b/source/blender/blenloader/tests/blendfile_loading_base_test.cc index 6f190ce427e..6613c65c42a 100644 --- a/source/blender/blenloader/tests/blendfile_loading_base_test.cc +++ b/source/blender/blenloader/tests/blendfile_loading_base_test.cc @@ -103,8 +103,8 @@ void BlendfileLoadingBaseTest::TearDownTestCase() void BlendfileLoadingBaseTest::TearDown() { BKE_mball_cubeTable_free(); - depsgraph_free(); blendfile_free(); + depsgraph_free(); testing::Test::TearDown(); } diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt index ebd292782c0..862bd41c087 100644 --- a/source/blender/io/usd/CMakeLists.txt +++ b/source/blender/io/usd/CMakeLists.txt @@ -163,13 +163,18 @@ target_link_libraries(bf_usd INTERFACE ${TBB_LIBRARIES}) if(WITH_GTESTS) set(TEST_SRC tests/usd_stage_creation_test.cc + tests/usd_export_test.cc tests/usd_tests_common.cc tests/usd_tests_common.h + + intern/usd_writer_material.h ) if(USD_IMAGING_HEADERS) list(APPEND TEST_SRC tests/usd_imaging_test.cc) endif() + include_directories(intern) + set(TEST_INC ) set(TEST_LIB diff --git a/source/blender/io/usd/intern/usd_capi_export.cc b/source/blender/io/usd/intern/usd_capi_export.cc index 28da9e388c5..1d33ca3a13c 100644 --- a/source/blender/io/usd/intern/usd_capi_export.cc +++ b/source/blender/io/usd/intern/usd_capi_export.cc @@ -66,7 +66,9 @@ static void export_startjob(void *customdata, data->start_time = timeit::Clock::now(); G.is_rendering = true; - WM_set_locked_interface(data->wm, true); + if (data->wm) { + WM_set_locked_interface(data->wm, true); + } G.is_break = false; /* Construct the depsgraph for exporting. */ @@ -160,7 +162,9 @@ static void export_endjob(void *customdata) } G.is_rendering = false; - WM_set_locked_interface(data->wm, false); + if (data->wm) { + WM_set_locked_interface(data->wm, false); + } report_job_duration(data); } diff --git a/source/blender/io/usd/intern/usd_capi_import.cc b/source/blender/io/usd/intern/usd_capi_import.cc index 66319a7f04e..fb870eb154c 100644 --- a/source/blender/io/usd/intern/usd_capi_import.cc +++ b/source/blender/io/usd/intern/usd_capi_import.cc @@ -207,6 +207,7 @@ static void import_startjob(void *customdata, bool *stop, bool *do_update, float if (!stage) { WM_reportf(RPT_ERROR, "USD Import: unable to open stage to read %s", data->filepath); data->import_ok = false; + data->error_code = USD_ARCHIVE_FAIL; return; } diff --git a/source/blender/io/usd/intern/usd_writer_material.cc b/source/blender/io/usd/intern/usd_writer_material.cc index 98cd4036fd0..7e744b74f61 100644 --- a/source/blender/io/usd/intern/usd_writer_material.cc +++ b/source/blender/io/usd/intern/usd_writer_material.cc @@ -748,4 +748,16 @@ static void export_texture(bNode *node, } } +const pxr::TfToken token_for_input(const char *input_name) +{ + const InputSpecMap &input_map = preview_surface_input_map(); + const InputSpecMap::const_iterator it = input_map.find(input_name); + + if (it == input_map.end()) { + return pxr::TfToken(); + } + + return it->second.input_name; +} + } // namespace blender::io::usd diff --git a/source/blender/io/usd/intern/usd_writer_material.h b/source/blender/io/usd/intern/usd_writer_material.h index fdfd13871ff..c6123b3cce2 100644 --- a/source/blender/io/usd/intern/usd_writer_material.h +++ b/source/blender/io/usd/intern/usd_writer_material.h @@ -14,6 +14,10 @@ namespace blender::io::usd { struct USDExporterContext; +/* Returns a USDPreviewSurface token name for a given Blender shader Socket name, + * or an empty TfToken if the input name is not found in the map. */ +const pxr::TfToken token_for_input(const char *input_name); + /** * Entry point to create an approximate USD Preview Surface network from a Cycles node graph. * Due to the limited nodes in the USD Preview Surface specification, only the following nodes diff --git a/source/blender/io/usd/tests/usd_export_test.cc b/source/blender/io/usd/tests/usd_export_test.cc new file mode 100644 index 00000000000..c13da695c87 --- /dev/null +++ b/source/blender/io/usd/tests/usd_export_test.cc @@ -0,0 +1,314 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "testing/testing.h" +#include "tests/blendfile_loading_base_test.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DNA_image_types.h" +#include "DNA_material_types.h" +#include "DNA_node_types.h" + +#include "BKE_context.h" +#include "BKE_lib_id.h" +#include "BKE_main.h" +#include "BKE_mesh.h" +#include "BKE_node.h" +#include "BLI_fileops.h" +#include "BLI_math.h" +#include "BLI_path_util.h" +#include "BLI_math_vector_types.hh" +#include "BLO_readfile.h" + +#include "BKE_node_runtime.hh" + +#include "DEG_depsgraph.h" + +#include "WM_api.h" + +#include "usd.h" +#include "usd_tests_common.h" +#include "usd_writer_material.h" + +namespace blender::io::usd { + +const StringRefNull simple_scene_filename = "usd/usd_simple_scene.blend"; +const StringRefNull materials_filename = "usd/usd_materials_export.blend"; +const StringRefNull output_filename = "output.usd"; + + +static const bNode *find_node_for_type_in_graph(const bNodeTree *nodetree, + const blender::StringRefNull type_idname); + + +class UsdExportTest : public BlendfileLoadingBaseTest { + protected: + struct bContext *context = nullptr; + + public: + bool load_file_and_depsgraph(const StringRefNull &filepath, + const eEvaluationMode eval_mode = DAG_EVAL_VIEWPORT) + { + if (!blendfile_load(filepath.c_str())) { + return false; + } + depsgraph_create(eval_mode); + + context = CTX_create(); + CTX_data_main_set(context, bfile->main); + CTX_data_scene_set(context, bfile->curscene); + + return true; + } + + virtual void SetUp() override + { + BlendfileLoadingBaseTest::SetUp(); + std::string usd_plugin_path = register_usd_plugins_for_tests(); + if (usd_plugin_path.empty()) { + FAIL() << "Unable to find the USD Plugins path."; + } + } + + virtual void TearDown() override + { + BlendfileLoadingBaseTest::TearDown(); + CTX_free(context); + context = nullptr; + + if (BLI_exists(output_filename.c_str())) { + BLI_delete(output_filename.c_str(), false, false); + } + } + + const pxr::UsdPrim get_first_child_mesh(const pxr::UsdPrim prim) + { + for (auto child : prim.GetChildren()) { + if (child.IsA()) { + return child; + } + } + return pxr::UsdPrim(); + } + + /* + * Loop the sockets on the Blender bNode, and fail if any of their values do + * not match the equivalent Attribtue values on the UsdPrim. + */ + const void compare_blender_node_to_usd_prim(const bNode *bsdf_node, const pxr::UsdPrim& bsdf_prim) { + ASSERT_NE(bsdf_node, nullptr); + ASSERT_TRUE(bool(bsdf_prim)); + + for (auto socket : bsdf_node->input_sockets()) { + const pxr::TfToken attribute_token = blender::io::usd::token_for_input(socket->name); + if (attribute_token.IsEmpty()) { + /* This socket is not translated between Blender and USD. */ + continue; + } + + const pxr::UsdAttribute bsdf_attribute = bsdf_prim.GetAttribute(attribute_token); + pxr::SdfPathVector paths; + bsdf_attribute.GetConnections(&paths); + if (!paths.empty() || !bsdf_attribute.IsValid()) { + /* Skip if the attribute is connected or has an error. */ + continue; + } + + const float socket_value_f = *socket->default_value_typed(); + const float3 socket_value_3f = *socket->default_value_typed(); + float attribute_value_f; + pxr::GfVec3f attribute_value_3f; + + switch (socket->type) { + case SOCK_FLOAT: + bsdf_attribute.Get(&attribute_value_f, 0.0); + EXPECT_FLOAT_EQ(socket_value_f, attribute_value_f); + break; + + case SOCK_VECTOR: + bsdf_attribute.Get(&attribute_value_3f, 0.0); + EXPECT_FLOAT_EQ(socket_value_3f[0], attribute_value_3f[0]); + EXPECT_FLOAT_EQ(socket_value_3f[1], attribute_value_3f[1]); + EXPECT_FLOAT_EQ(socket_value_3f[2], attribute_value_3f[2]); + break; + + case SOCK_RGBA: + bsdf_attribute.Get(&attribute_value_3f, 0.0); + EXPECT_FLOAT_EQ(socket_value_3f[0], attribute_value_3f[0]); + EXPECT_FLOAT_EQ(socket_value_3f[1], attribute_value_3f[1]); + EXPECT_FLOAT_EQ(socket_value_3f[2], attribute_value_3f[2]); + break; + + default: + FAIL() << "Socket " << socket->name << " has unsupported type " << socket->type; + break; + } + } + } + + const void compare_blender_image_to_usd_image_shader(const bNode *image_node, const pxr::UsdPrim& image_prim) { + const Image *image = reinterpret_cast(image_node->id); + + const pxr::UsdShadeShader image_shader(image_prim); + const pxr::UsdShadeInput file_input = image_shader.GetInput(pxr::TfToken("file")); + EXPECT_TRUE(bool(file_input)); + + pxr::VtValue file_val; + EXPECT_TRUE(file_input.Get(&file_val)); + EXPECT_TRUE(file_val.IsHolding()); + + pxr::SdfAssetPath image_prim_asset = file_val.Get(); + + /* The path is expected to be relative, but that means in Blender the + * path will start with //. + */ + EXPECT_EQ(BLI_path_cmp_normalized(image->filepath+2, image_prim_asset.GetAssetPath().c_str()), 0); + } + + /* + * Determine if a Blender Mesh matches a UsdGeomMesh prim by checking counts + * on vertices, faces, face indices, and normals. + */ + const void compare_blender_mesh_to_usd_prim(const Mesh *mesh, const pxr::UsdGeomMesh& mesh_prim) { + pxr::VtIntArray face_indices; + pxr::VtIntArray face_counts; + pxr::VtVec3fArray positions; + pxr::VtVec3fArray normals; + + /* Our export doesn't use 'primvars:normals' so we're not + * looking for that to be written here. */ + mesh_prim.GetFaceVertexIndicesAttr().Get(&face_indices, 0.0); + mesh_prim.GetFaceVertexCountsAttr().Get(&face_counts, 0.0); + mesh_prim.GetPointsAttr().Get(&positions, 0.0); + mesh_prim.GetNormalsAttr().Get(&normals, 0.0); + + EXPECT_EQ(mesh->totvert, positions.size()); + EXPECT_EQ(mesh->totpoly, face_counts.size()); + EXPECT_EQ(mesh->totloop, face_indices.size()); + EXPECT_EQ(mesh->totloop, normals.size()); + } + +}; + + +TEST_F(UsdExportTest, usd_export_rain_mesh) +{ + if (!load_file_and_depsgraph(simple_scene_filename)) { + FAIL() << "Unable to load file: " << simple_scene_filename; + return; + } + + /* File sanity check. */ + EXPECT_EQ(BLI_listbase_count(&bfile->main->objects), 3); + + USDExportParams params{}; + params.export_normals = true; + params.visible_objects_only = true; + params.evaluation_mode = eEvaluationMode::DAG_EVAL_VIEWPORT; + + bool result = USD_export(context, output_filename.c_str(), ¶ms, false); + ASSERT_TRUE(result) << "Writing to " << output_filename << " failed!"; + + pxr::UsdStageRefPtr stage = pxr::UsdStage::Open(output_filename); + ASSERT_TRUE(bool(stage)) << "Unable to load Stage from " << output_filename; + + /* + * Run the mesh comparison for all Meshes in the original scene. + */ + LISTBASE_FOREACH (Object *, object, &bfile->main->objects) { + const Mesh *mesh = static_cast(object->data); + const StringRefNull object_name(object->id.name + 2); + + const pxr::SdfPath sdf_path("/" + pxr::TfMakeValidIdentifier(object_name.c_str())); + pxr::UsdPrim prim = stage->GetPrimAtPath(sdf_path); + EXPECT_TRUE(bool(prim)); + + const pxr::UsdGeomMesh mesh_prim(get_first_child_mesh(prim)); + EXPECT_TRUE(bool(mesh_prim)); + + compare_blender_mesh_to_usd_prim(mesh, mesh_prim); + } +} + + +static const bNode *find_node_for_type_in_graph(const bNodeTree *nodetree, const blender::StringRefNull type_idname) +{ + auto found_nodes = nodetree->nodes_by_type(type_idname); + if (found_nodes.size() == 1) { + return found_nodes[0]; + } + + return nullptr; +} + + +/* + * Export Material test-- export a scene with a material, then read it back + * in and check that the BSDF and Image Texture nodes translated correctly + * by comparing values between the exported USD stage and the objects in + * memory. + */ +TEST_F(UsdExportTest, usd_export_material) +{ + if (!load_file_and_depsgraph(materials_filename)) { + FAIL() << "Unable to load file: " << materials_filename; + return; + } + + /* File sanity checks. */ + EXPECT_EQ(BLI_listbase_count(&bfile->main->objects), 1); + /* There are two materials because of the Dots Stroke. */ + EXPECT_EQ(BLI_listbase_count(&bfile->main->materials), 2); + + Material *material = reinterpret_cast(BKE_libblock_find_name(bfile->main, ID_MA, "Material")); + + EXPECT_TRUE(bool(material)); + + USDExportParams params{}; + params.export_normals = true; + params.export_materials = true; + params.generate_preview_surface = true; + params.export_uvmaps = true; + params.evaluation_mode = eEvaluationMode::DAG_EVAL_VIEWPORT; + + const bool result = USD_export(context, output_filename.c_str(), ¶ms, false); + ASSERT_TRUE(result) << "Unable to export stage to " << output_filename; + + pxr::UsdStageRefPtr stage = pxr::UsdStage::Open(output_filename); + ASSERT_NE(stage, nullptr) << "Unable to open exported stage: " << output_filename; + + material->nodetree->ensure_topology_cache(); + const bNode *bsdf_node = find_node_for_type_in_graph(material->nodetree, + "ShaderNodeBsdfPrincipled"); + + const std::string prim_name = pxr::TfMakeValidIdentifier(bsdf_node->name); + const pxr::UsdPrim bsdf_prim = stage->GetPrimAtPath( + pxr::SdfPath("/_materials/Material/preview/" + prim_name)); + + compare_blender_node_to_usd_prim(bsdf_node, bsdf_prim); + + const bNode *image_node = find_node_for_type_in_graph(material->nodetree, "ShaderNodeTexImage"); + ASSERT_NE(image_node, nullptr); + ASSERT_NE(image_node->storage, nullptr); + + + const std::string image_prim_name = pxr::TfMakeValidIdentifier(image_node->name); + + const pxr::UsdPrim image_prim = stage->GetPrimAtPath( + pxr::SdfPath("/_materials/Material/preview/" + image_prim_name)); + + ASSERT_TRUE(bool(image_prim)) << "Unable to find Material prim from exported stage " << output_filename; + + compare_blender_image_to_usd_image_shader(image_node, image_prim); +} + +} // namespace blender::io::usd diff --git a/tests/python/bl_usd_import_test.py b/tests/python/bl_usd_import_test.py index 95b2328b2aa..8639cbd61a2 100644 --- a/tests/python/bl_usd_import_test.py +++ b/tests/python/bl_usd_import_test.py @@ -24,24 +24,132 @@ class AbstractUSDTest(unittest.TestCase): class USDImportTest(AbstractUSDTest): + def test_import_operator(self): + """Test running the import operator on valid and invalid files.""" + + infile = str(self.testdir / "usd_mesh_polygon_types.usda") + res = bpy.ops.wm.usd_import(filepath=infile) + self.assertEqual({'FINISHED'}, res, f"Unable to import USD file {infile}") + + infile = str(self.testdir / "this_file_doesn't_exist.usda") + res = bpy.ops.wm.usd_import(filepath=infile) + self.assertEqual({'CANCELLED'}, res, "Was somehow able to import a non-existent USD file!") + def test_import_prim_hierarchy(self): """Test importing a simple object hierarchy from a USDA file.""" infile = str(self.testdir / "prim-hierarchy.usda") res = bpy.ops.wm.usd_import(filepath=infile) - self.assertEqual({'FINISHED'}, res) + self.assertEqual({'FINISHED'}, res, f"Unable to import USD file {infile}") objects = bpy.context.scene.collection.objects - self.assertEqual(5, len(objects)) + self.assertEqual(5, len(objects), f"Test scene {infile} should have five objects; found {len(objects)}") # Test the hierarchy. - self.assertIsNone(objects['World'].parent) - self.assertEqual(objects['World'], objects['Plane'].parent) - self.assertEqual(objects['World'], objects['Plane_001'].parent) - self.assertEqual(objects['World'], objects['Empty'].parent) - self.assertEqual(objects['Empty'], objects['Plane_002'].parent) + self.assertIsNone(objects['World'].parent, "/World should not be parented.") + self.assertEqual(objects['World'], objects['Plane'].parent, "Plane should be child of /World") + self.assertEqual(objects['World'], objects['Plane_001'].parent, "Plane_001 should be a child of /World") + self.assertEqual(objects['World'], objects['Empty'].parent, "Empty should be a child of /World") + self.assertEqual(objects['Empty'], objects['Plane_002'].parent, "Plane_002 should be a child of /World") + def test_import_mesh_topology(self): + """Test importing meshes with different polygon types.""" + + infile = str(self.testdir / "usd_mesh_polygon_types.usda") + res = bpy.ops.wm.usd_import(filepath=infile) + self.assertEqual({'FINISHED'}, res, f"Unable to import USD file {infile}") + + objects = bpy.context.scene.collection.objects + self.assertEqual(5, len(objects), f"Test scene {infile} should have five objects; found {len(objects)}") + + # Test topology counts. + self.assertIn("m_degenerate", objects, "Scene does not contain object m_degenerate") + mesh = objects["m_degenerate"].data + self.assertEqual(len(mesh.polygons), 2) + self.assertEqual(len(mesh.edges), 7) + self.assertEqual(len(mesh.vertices), 6) + + self.assertIn("m_triangles", objects, "Scene does not contain object m_triangles") + mesh = objects["m_triangles"].data + self.assertEqual(len(mesh.polygons), 2) + self.assertEqual(len(mesh.edges), 5) + self.assertEqual(len(mesh.vertices), 4) + self.assertEqual(len(mesh.polygons[0].vertices), 3) + + self.assertIn("m_quad", objects, "Scene does not contain object m_quad") + mesh = objects["m_quad"].data + self.assertEqual(len(mesh.polygons), 1) + self.assertEqual(len(mesh.edges), 4) + self.assertEqual(len(mesh.vertices), 4) + self.assertEqual(len(mesh.polygons[0].vertices), 4) + + self.assertIn("m_ngon_concave", objects, "Scene does not contain object m_ngon_concave") + mesh = objects["m_ngon_concave"].data + self.assertEqual(len(mesh.polygons), 1) + self.assertEqual(len(mesh.edges), 5) + self.assertEqual(len(mesh.vertices), 5) + self.assertEqual(len(mesh.polygons[0].vertices), 5) + + self.assertIn("m_ngon_convex", objects, "Scene does not contain object m_ngon_convex") + mesh = objects["m_ngon_convex"].data + self.assertEqual(len(mesh.polygons), 1) + self.assertEqual(len(mesh.edges), 5) + self.assertEqual(len(mesh.vertices), 5) + self.assertEqual(len(mesh.polygons[0].vertices), 5) + + def test_import_mesh_uv_maps(self): + """Test importing meshes with udim UVs and multiple UV sets.""" + + infile = str(self.testdir / "usd_mesh_udim.usda") + res = bpy.ops.wm.usd_import(filepath=infile) + self.assertEqual({'FINISHED'}, res, f"Unable to import USD file {infile}") + + objects = bpy.context.scene.collection.objects + if "preview" in bpy.data.objects: + bpy.data.objects.remove(bpy.data.objects["preview"]) + self.assertEqual(1, len(objects), f"File {infile} should contain one object, found {len(objects)}") + + mesh = bpy.data.objects["uvmap_plane"].data + self.assertEqual(len(mesh.uv_layers), 2, f"Object uvmap_plane should have two uv layers, found {len(mesh.uv_layers)}") + + expected_layer_names = {"udim_map", "uvmap"} + imported_layer_names = set(mesh.uv_layers.keys()) + self.assertEqual(expected_layer_names, imported_layer_names, f"Expected layer names ({expected_layer_names}) not found on uvmap_plane.") + + def get_coords(data): + coords = [x.uv for x in uvmap] + return coords + + def uv_min_max(data): + coords = get_coords(data) + uv_min_x = min([uv[0] for uv in coords]) + uv_max_x = max([uv[0] for uv in coords]) + uv_min_y = min([uv[1] for uv in coords]) + uv_max_y = max([uv[1] for uv in coords]) + return uv_min_x, uv_max_x, uv_min_y, uv_max_y + + ## Quick tests for point range. + uvmap = mesh.uv_layers["uvmap"].data + self.assertEqual(len(uvmap), 128) + min_x, max_x, min_y, max_y = uv_min_max(uvmap) + self.assertGreaterEqual(min_x, 0.0) + self.assertGreaterEqual(min_y, 0.0) + self.assertLessEqual(max_x, 1.0) + self.assertLessEqual(max_y, 1.0) + + uvmap = mesh.uv_layers["udim_map"].data + self.assertEqual(len(uvmap), 128) + min_x, max_x, min_y, max_y = uv_min_max(uvmap) + self.assertGreaterEqual(min_x, 0.0) + self.assertGreaterEqual(min_y, 0.0) + self.assertLessEqual(max_x, 2.0) + self.assertLessEqual(max_y, 1.0) + + ## Make sure at least some points are in a udim tile. + coords = get_coords(uvmap) + coords = list(filter(lambda x: x[0] > 1.0, coords)) + self.assertGreater(len(coords), 16) def main(): global args From f5d94f97e41e71b69927965ac7a66a6188217495 Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Wed, 25 Jan 2023 23:01:00 +0100 Subject: [PATCH 0952/1522] Fix T104132: Vertex colors no longer displaying in Workbench --- .../draw/engines/workbench/shaders/workbench_material_lib.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/draw/engines/workbench/shaders/workbench_material_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_material_lib.glsl index 59e30b310bb..b663c029d5e 100644 --- a/source/blender/draw/engines/workbench/shaders/workbench_material_lib.glsl +++ b/source/blender/draw/engines/workbench/shaders/workbench_material_lib.glsl @@ -12,7 +12,7 @@ void workbench_material_data_get(int handle, vec4 data = materials_data[uint(handle) & 0xFFFu]; color = data.rgb; if (materialIndex == 0) { - color_interp = vertex_color; + color = vertex_color; } #else From c1beaea80f97026442a2b81e51ea80ce9dfc492d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 26 Jan 2023 11:01:32 +1100 Subject: [PATCH 0953/1522] Fix T103587: Redo panel doesn't appear for spin operator Regression in [0] which cleared the redo-panel if an operator added its own undo step. This worked for sculpt to fix T101743, but caused the redo-panel to be cleared for actions who's undo steps where created by nested operators (which is the case for the spin operator). Fix by checking an undo-step is added without registering an operator. [0]: f68e50a263b8a970075c8fd540a985f2798e1d13 --- .../windowmanager/intern/wm_event_system.cc | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index bf549cd00c9..c1ee3d522b6 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -944,6 +944,14 @@ static intptr_t wm_operator_undo_active_id(const wmWindowManager *wm) return -1; } +static intptr_t wm_operator_register_active_id(const wmWindowManager *wm) +{ + if (wm->operators.last) { + return intptr_t(wm->operators.last); + } + return -1; +} + bool WM_operator_poll(bContext *C, wmOperatorType *ot) { @@ -1078,9 +1086,14 @@ static bool wm_operator_register_check(wmWindowManager *wm, wmOperatorType *ot) /** * \param has_undo_step: True when an undo step was added, * needed when the operator doesn't use #OPTYPE_UNDO, #OPTYPE_UNDO_GROUPED but adds an undo step. + * \param has_register: True when an operator was registered. */ -static void wm_operator_finished( - bContext *C, wmOperator *op, const bool repeat, const bool store, const bool has_undo_step) +static void wm_operator_finished(bContext *C, + wmOperator *op, + const bool repeat, + const bool store, + const bool has_undo_step, + const bool has_register) { wmWindowManager *wm = CTX_wm_manager(C); enum { @@ -1088,6 +1101,7 @@ static void wm_operator_finished( SET, CLEAR, } hud_status = NOP; + const bool do_register = (repeat == false) && wm_operator_register_check(wm, op->type); op->customdata = nullptr; @@ -1112,8 +1126,14 @@ static void wm_operator_finished( } } else if (has_undo_step) { - if (repeat == 0) { - hud_status = CLEAR; + /* An undo step was added but the operator wasn't registered (and won't register it's self), + * therefor a redo panel wouldn't redo this action but the previous registered action, + * causing the "redo" to remove/loose this operator. See: T101743. + * Register check is needed so nested operator calls don't clear the HUD. See: T103587. */ + if (!(has_register || do_register)) { + if (repeat == 0) { + hud_status = CLEAR; + } } } } @@ -1125,7 +1145,7 @@ static void wm_operator_finished( MEM_freeN(buf); } - if (wm_operator_register_check(wm, op->type)) { + if (do_register) { /* Take ownership of reports (in case python provided own). */ op->reports->flag |= RPT_FREE; @@ -1177,6 +1197,8 @@ static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, cons } const intptr_t undo_id_prev = wm_operator_undo_active_id(wm); + const intptr_t register_id_prev = wm_operator_register_active_id(wm); + if (op->type->exec) { if (op->type->flag & OPTYPE_UNDO) { wm->op_undo_depth++; @@ -1199,8 +1221,10 @@ static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, cons if (retval & OPERATOR_FINISHED) { const bool has_undo_step = (undo_id_prev != wm_operator_undo_active_id(wm)); + const bool has_register = (register_id_prev != wm_operator_register_active_id(wm)); - wm_operator_finished(C, op, repeat, store && wm->op_undo_depth == 0, has_undo_step); + wm_operator_finished( + C, op, repeat, store && wm->op_undo_depth == 0, has_undo_step, has_register); } else if (repeat == 0) { /* WARNING: modal from exec is bad practice, but avoid crashing. */ @@ -1442,6 +1466,7 @@ static int wm_operator_invoke(bContext *C, if (WM_operator_poll(C, ot)) { wmWindowManager *wm = CTX_wm_manager(C); const intptr_t undo_id_prev = wm_operator_undo_active_id(wm); + const intptr_t register_id_prev = wm_operator_register_active_id(wm); /* If `reports == nullptr`, they'll be initialized. */ wmOperator *op = wm_operator_create(wm, ot, properties, reports); @@ -1511,8 +1536,9 @@ static int wm_operator_invoke(bContext *C, } else if (retval & OPERATOR_FINISHED) { const bool has_undo_step = (undo_id_prev != wm_operator_undo_active_id(wm)); + const bool has_register = (register_id_prev != wm_operator_register_active_id(wm)); const bool store = !is_nested_call && use_last_properties; - wm_operator_finished(C, op, false, store, has_undo_step); + wm_operator_finished(C, op, false, store, has_undo_step, has_register); } else if (retval & OPERATOR_RUNNING_MODAL) { /* Take ownership of reports (in case python provided own). */ @@ -2402,6 +2428,7 @@ static int wm_handler_operator_call(bContext *C, wm_event_modalkeymap_begin(C, op, event, &event_backup); const intptr_t undo_id_prev = wm_operator_undo_active_id(wm); + const intptr_t register_id_prev = wm_operator_register_active_id(wm); if (ot->flag & OPTYPE_UNDO) { wm->op_undo_depth++; } @@ -2438,8 +2465,9 @@ static int wm_handler_operator_call(bContext *C, /* Important to run 'wm_operator_finished' before setting the context members to null. */ if (retval & OPERATOR_FINISHED) { const bool has_undo_step = (undo_id_prev != wm_operator_undo_active_id(wm)); + const bool has_register = (register_id_prev != wm_operator_register_active_id(wm)); - wm_operator_finished(C, op, false, true, has_undo_step); + wm_operator_finished(C, op, false, true, has_undo_step, has_register); handler->op = nullptr; } else if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) { From 564673b8ea2860cc0d0b3a0f673a315693d3f5eb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 26 Jan 2023 16:05:21 +1100 Subject: [PATCH 0954/1522] Fix T71137: curve minimum twist producing wrong geometry Only one point should be used to create a reference rotation for other points to follow. Using two caused the resulting twist to be asymmetric, especially noticeable on symmetrical, cyclic curves. An update to [0] which broke curve_to_mesh & deform_modifiers tests, now this change only applies to cyclic curves as the final result was much greater for non-cyclic curves because of a difference between how end-point directions are calculated (see code-comments for details). Alternate fix to D11886 which caused T101843. [0]: 36a82314a0f5de65b54f6d8343a2899ed4e37010. --- source/blender/blenkernel/intern/curve.cc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/curve.cc b/source/blender/blenkernel/intern/curve.cc index 744ef0e8009..61dc8a22077 100644 --- a/source/blender/blenkernel/intern/curve.cc +++ b/source/blender/blenkernel/intern/curve.cc @@ -2250,6 +2250,19 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl) BevPoint *bevp2, *bevp1, *bevp0; /* Standard for all make_bevel_list_3D_* functions. */ int nr; float q[4]; + const bool is_cyclic = bl->poly != -1; + /* NOTE(@campbellbarton): For non-cyclic curves only initialize the first direction + * (via `vec_to_quat`), necessary for symmetry, see T71137. + * Otherwise initialize the first and second points before propagating rotation forward. + * This is historical as changing this can cause significantly different output. + * Specifically: `deform_modifiers` test: (`CurveMeshDeform`). + * + * While it would seem correct to only use the first point for non-cyclic curves as well + * the end-points direction is initialized from the input handles (instead of the directions + * between points), there is often a bigger difference in the first and second directions + * than you'd otherwise expect. So using only the first direction breaks compatibility + * enough it's best to leave it as-is. */ + const int nr_init = bl->nr - (is_cyclic ? 1 : 2); bevel_list_calc_bisect(bl); @@ -2260,7 +2273,8 @@ static void make_bevel_list_3D_minimum_twist(BevList *bl) nr = bl->nr; while (nr--) { - if (nr + 3 > bl->nr) { /* first time and second time, otherwise first point adjusts last */ + if (nr >= nr_init) { + /* Initialize the rotation, otherwise propagate the previous rotation forward. */ vec_to_quat(bevp1->quat, bevp1->dir, 5, 1); } else { From ef39d85d7c94c28e952683c0ddd0f3b7435b8460 Mon Sep 17 00:00:00 2001 From: Amelie Fondevilla Date: Wed, 25 Jan 2023 17:00:10 +0100 Subject: [PATCH 0955/1522] Fix T104121: Grease pencil clear function in python not updated in viewport The clear functions for grease pencil data/frame/layer was not followed by immediate update in the viewport. Some notifiers were missing in the rna definition of these functions, which are added in by this patch. Reviewed By: Antonio Vazquez Differential Revision: https://developer.blender.org/D17120 --- source/blender/makesrna/intern/rna_gpencil.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 544a7f73cab..dd608ce9acb 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -1101,17 +1101,23 @@ static void rna_GPencil_layer_mask_remove(bGPDlayer *gpl, WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } -static void rna_GPencil_frame_clear(bGPDframe *frame) +static void rna_GPencil_frame_clear(ID *id, bGPDframe *frame) { BKE_gpencil_free_strokes(frame); + bGPdata *gpd = (bGPdata *)id; + DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } -static void rna_GPencil_layer_clear(bGPDlayer *layer) +static void rna_GPencil_layer_clear(ID *id, bGPDlayer *layer) { BKE_gpencil_free_frames(layer); + bGPdata *gpd = (bGPdata *)id; + DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } @@ -1119,6 +1125,8 @@ static void rna_GPencil_clear(bGPdata *gpd) { BKE_gpencil_free_layers(&gpd->layers); + DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } @@ -1841,6 +1849,7 @@ static void rna_def_gpencil_frame(BlenderRNA *brna) /* API */ func = RNA_def_function(srna, "clear", "rna_GPencil_frame_clear"); RNA_def_function_ui_description(func, "Remove all the grease pencil frame data"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); } static void rna_def_gpencil_frames_api(BlenderRNA *brna, PropertyRNA *cprop) @@ -2304,6 +2313,7 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) /* Layers API */ func = RNA_def_function(srna, "clear", "rna_GPencil_layer_clear"); RNA_def_function_ui_description(func, "Remove all the grease pencil layer data"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); } static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop) From a42f307915e49500ca7c2e18e2092dcef85f7f6e Mon Sep 17 00:00:00 2001 From: Martijn Versteegh Date: Mon, 23 Jan 2023 19:59:46 +0100 Subject: [PATCH 0956/1522] Shader Nodes: Use layers from evaluated mesh The list was populated from the base (unevaluated) object, but now that Geometry nodes can generate various layers this is impractical.. Differential Revision: https://developer.blender.org/D17093 --- .../blender/nodes/shader/nodes/node_shader_normal_map.cc | 8 +++++++- source/blender/nodes/shader/nodes/node_shader_tangent.cc | 8 +++++++- source/blender/nodes/shader/nodes/node_shader_uvmap.cc | 8 +++++++- .../nodes/shader/nodes/node_shader_vertex_color.cc | 7 ++++++- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.cc b/source/blender/nodes/shader/nodes/node_shader_normal_map.cc index 0bc1318a1f6..a29faff2093 100644 --- a/source/blender/nodes/shader/nodes/node_shader_normal_map.cc +++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.cc @@ -6,6 +6,8 @@ #include "BKE_context.h" #include "BKE_node_runtime.hh" +#include "DEG_depsgraph_query.h" + #include "UI_interface.h" #include "UI_resources.h" @@ -26,7 +28,11 @@ static void node_shader_buts_normal_map(uiLayout *layout, bContext *C, PointerRN PointerRNA obptr = CTX_data_pointer_get(C, "active_object"); if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) { - PointerRNA dataptr = RNA_pointer_get(&obptr, "data"); + PointerRNA eval_obptr; + + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + DEG_get_evaluated_rna_pointer(depsgraph, &obptr, &eval_obptr); + PointerRNA dataptr = RNA_pointer_get(&eval_obptr, "data"); uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE); } else { diff --git a/source/blender/nodes/shader/nodes/node_shader_tangent.cc b/source/blender/nodes/shader/nodes/node_shader_tangent.cc index 9b09eb09bba..cb0c3f34e40 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tangent.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tangent.cc @@ -5,6 +5,8 @@ #include "BKE_context.h" +#include "DEG_depsgraph_query.h" + #include "UI_interface.h" #include "UI_resources.h" @@ -29,7 +31,11 @@ static void node_shader_buts_tangent(uiLayout *layout, bContext *C, PointerRNA * PointerRNA obptr = CTX_data_pointer_get(C, "active_object"); if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) { - PointerRNA dataptr = RNA_pointer_get(&obptr, "data"); + PointerRNA eval_obptr; + + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + DEG_get_evaluated_rna_pointer(depsgraph, &obptr, &eval_obptr); + PointerRNA dataptr = RNA_pointer_get(&eval_obptr, "data"); uiItemPointerR(row, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE); } else { diff --git a/source/blender/nodes/shader/nodes/node_shader_uvmap.cc b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc index 483e06f1192..de8221e3e97 100644 --- a/source/blender/nodes/shader/nodes/node_shader_uvmap.cc +++ b/source/blender/nodes/shader/nodes/node_shader_uvmap.cc @@ -7,6 +7,8 @@ #include "DNA_customdata_types.h" +#include "DEG_depsgraph_query.h" + #include "UI_interface.h" #include "UI_resources.h" @@ -25,7 +27,11 @@ static void node_shader_buts_uvmap(uiLayout *layout, bContext *C, PointerRNA *pt PointerRNA obptr = CTX_data_pointer_get(C, "active_object"); if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) { - PointerRNA dataptr = RNA_pointer_get(&obptr, "data"); + PointerRNA eval_obptr; + + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + DEG_get_evaluated_rna_pointer(depsgraph, &obptr, &eval_obptr); + PointerRNA dataptr = RNA_pointer_get(&eval_obptr, "data"); uiItemPointerR(layout, ptr, "uv_map", &dataptr, "uv_layers", "", ICON_NONE); } } diff --git a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc index 8f7e30b99df..0e0f9496851 100644 --- a/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc +++ b/source/blender/nodes/shader/nodes/node_shader_vertex_color.cc @@ -5,6 +5,8 @@ #include "BKE_context.h" +#include "DEG_depsgraph_query.h" + #include "UI_interface.h" #include "UI_resources.h" @@ -20,8 +22,11 @@ static void node_shader_buts_vertex_color(uiLayout *layout, bContext *C, Pointer { PointerRNA obptr = CTX_data_pointer_get(C, "active_object"); if (obptr.data && RNA_enum_get(&obptr, "type") == OB_MESH) { - PointerRNA dataptr = RNA_pointer_get(&obptr, "data"); + PointerRNA eval_obptr; + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + DEG_get_evaluated_rna_pointer(depsgraph, &obptr, &eval_obptr); + PointerRNA dataptr = RNA_pointer_get(&eval_obptr, "data"); uiItemPointerR(layout, ptr, "layer_name", &dataptr, "color_attributes", "", ICON_GROUP_VCOL); } else { From 4a768a7857b57cb3ac0274564a510c2cf9fe00a7 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Thu, 26 Jan 2023 13:31:23 +0100 Subject: [PATCH 0957/1522] Cleanup: remove unused variable --- source/blender/blenkernel/intern/node.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index cb650c038e4..26b1f2f5096 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3803,8 +3803,6 @@ void BKE_node_instance_hash_remove_untagged(bNodeInstanceHash *hash, void ntreeUpdateAllNew(Main *main) { - Vector new_ntrees; - /* Update all new node trees on file read or append, to add/remove sockets * in groups nodes if the group changed, and handle any update flags that * might have been set in file reading or versioning. */ From f7dd7d545472b8571a64ec96eb94eed1aada0523 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Tue, 10 Jan 2023 18:25:58 +0200 Subject: [PATCH 0958/1522] Python API: add a method for reordering modifiers. Add an `object.modifiers.move()` method, similar to the one for constraints and some other collections. Currently reordering modifiers requires using operators, which depend on context. The implementation is straightforward, except for the need to make the severity of errors reported by the underlying editor code into a parameter, so that the new Python API function reports any problems as Python exceptions, and refactoring the code to allow aborting a blocked move before making any changes. I also turn the negative index condition from an assert into an error. Differential Revision: https://developer.blender.org/D16966 --- source/blender/editors/include/ED_object.h | 7 +- .../blender/editors/object/object_modifier.cc | 114 +++++++++++++----- .../space_outliner/outliner_dragdrop.cc | 8 +- source/blender/makesrna/intern/rna_object.c | 23 ++++ 4 files changed, 120 insertions(+), 32 deletions(-) diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 82f8505509a..baa84b550aa 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -10,6 +10,7 @@ #include "BLI_compiler_attrs.h" #include "DNA_object_enums.h" #include "DNA_userdef_enums.h" +#include "DNA_windowmanager_types.h" #ifdef __cplusplus extern "C" { @@ -558,15 +559,19 @@ bool ED_object_modifier_remove(struct ReportList *reports, struct ModifierData *md); void ED_object_modifier_clear(struct Main *bmain, struct Scene *scene, struct Object *ob); bool ED_object_modifier_move_down(struct ReportList *reports, + eReportType error_type, struct Object *ob, struct ModifierData *md); bool ED_object_modifier_move_up(struct ReportList *reports, + eReportType error_type, struct Object *ob, struct ModifierData *md); bool ED_object_modifier_move_to_index(struct ReportList *reports, + eReportType error_type, struct Object *ob, struct ModifierData *md, - int index); + int index, + bool allow_partial); bool ED_object_modifier_convert_psys_to_mesh(struct ReportList *reports, struct Main *bmain, diff --git a/source/blender/editors/object/object_modifier.cc b/source/blender/editors/object/object_modifier.cc index 1bfd156b664..9964d658994 100644 --- a/source/blender/editors/object/object_modifier.cc +++ b/source/blender/editors/object/object_modifier.cc @@ -415,83 +415,139 @@ void ED_object_modifier_clear(Main *bmain, Scene *scene, Object *ob) DEG_relations_tag_update(bmain); } -bool ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md) +static bool object_modifier_check_move_before(ReportList *reports, + eReportType error_type, + ModifierData *md, + ModifierData *md_prev) { - if (md->prev) { + if (md_prev) { const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type); if (mti->type != eModifierTypeType_OnlyDeform) { - const ModifierTypeInfo *nmti = BKE_modifier_get_info((ModifierType)md->prev->type); + const ModifierTypeInfo *nmti = BKE_modifier_get_info((ModifierType)md_prev->type); if (nmti->flags & eModifierTypeFlag_RequiresOriginalData) { - BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data"); + BKE_report(reports, error_type, "Cannot move above a modifier requiring original data"); return false; } } - - BLI_listbase_swaplinks(&ob->modifiers, md, md->prev); } else { - BKE_report(reports, RPT_WARNING, "Cannot move modifier beyond the start of the list"); + BKE_report(reports, error_type, "Cannot move modifier beyond the start of the list"); return false; } return true; } -bool ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md) +bool ED_object_modifier_move_up(ReportList *reports, + eReportType error_type, + Object *ob, + ModifierData *md) { - if (md->next) { + if (object_modifier_check_move_before(reports, error_type, md, md->prev)) { + BLI_listbase_swaplinks(&ob->modifiers, md, md->prev); + return true; + } + + return false; +} + +static bool object_modifier_check_move_after(ReportList *reports, + eReportType error_type, + ModifierData *md, + ModifierData *md_next) +{ + if (md_next) { const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type); if (mti->flags & eModifierTypeFlag_RequiresOriginalData) { - const ModifierTypeInfo *nmti = BKE_modifier_get_info((ModifierType)md->next->type); + const ModifierTypeInfo *nmti = BKE_modifier_get_info((ModifierType)md_next->type); if (nmti->type != eModifierTypeType_OnlyDeform) { - BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier"); + BKE_report(reports, error_type, "Cannot move beyond a non-deforming modifier"); return false; } } - - BLI_listbase_swaplinks(&ob->modifiers, md, md->next); } else { - BKE_report(reports, RPT_WARNING, "Cannot move modifier beyond the end of the list"); + BKE_report(reports, error_type, "Cannot move modifier beyond the end of the list"); return false; } return true; } +bool ED_object_modifier_move_down(ReportList *reports, + eReportType error_type, + Object *ob, + ModifierData *md) +{ + if (object_modifier_check_move_after(reports, error_type, md, md->next)) { + BLI_listbase_swaplinks(&ob->modifiers, md, md->next); + return true; + } + + return false; +} + bool ED_object_modifier_move_to_index(ReportList *reports, + eReportType error_type, Object *ob, ModifierData *md, - const int index) + const int index, + bool allow_partial) { BLI_assert(md != nullptr); - BLI_assert(index >= 0); - if (index >= BLI_listbase_count(&ob->modifiers)) { - BKE_report(reports, RPT_WARNING, "Cannot move modifier beyond the end of the stack"); + + if (index < 0 || index >= BLI_listbase_count(&ob->modifiers)) { + BKE_report(reports, error_type, "Cannot move modifier beyond the end of the stack"); return false; } int md_index = BLI_findindex(&ob->modifiers, md); BLI_assert(md_index != -1); + if (md_index < index) { /* Move modifier down in list. */ - for (; md_index < index; md_index++) { - if (!ED_object_modifier_move_down(reports, ob, md)) { + ModifierData *md_target = md; + + for (; md_index < index; md_index++, md_target = md_target->next) { + if (!object_modifier_check_move_after(reports, error_type, md, md_target->next)) { + if (!allow_partial || md == md_target) { + return false; + } + break; } } + + BLI_assert(md != md_target && md_target); + + BLI_remlink(&ob->modifiers, md); + BLI_insertlinkafter(&ob->modifiers, md_target, md); + } + else if (md_index > index) { + /* Move modifier up in list. */ + ModifierData *md_target = md; + + for (; md_index > index; md_index--, md_target = md_target->prev) { + if (!object_modifier_check_move_before(reports, error_type, md, md_target->prev)) { + if (!allow_partial || md == md_target) { + return false; + } + + break; + } + } + + BLI_assert(md != md_target && md_target); + + BLI_remlink(&ob->modifiers, md); + BLI_insertlinkbefore(&ob->modifiers, md_target, md); } else { - /* Move modifier up in list. */ - for (; md_index > index; md_index--) { - if (!ED_object_modifier_move_up(reports, ob, md)) { - break; - } - } + return true; } /* NOTE: Dependency graph only uses modifier nodes for visibility updates, and exact order of @@ -1518,7 +1574,7 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op) Object *ob = ED_object_active_context(C); ModifierData *md = edit_modifier_property_get(op, ob, 0); - if (!md || !ED_object_modifier_move_up(op->reports, ob, md)) { + if (!md || !ED_object_modifier_move_up(op->reports, RPT_WARNING, ob, md)) { return OPERATOR_CANCELLED; } @@ -1563,7 +1619,7 @@ static int modifier_move_down_exec(bContext *C, wmOperator *op) Object *ob = ED_object_active_context(C); ModifierData *md = edit_modifier_property_get(op, ob, 0); - if (!md || !ED_object_modifier_move_down(op->reports, ob, md)) { + if (!md || !ED_object_modifier_move_down(op->reports, RPT_WARNING, ob, md)) { return OPERATOR_CANCELLED; } @@ -1609,7 +1665,7 @@ static int modifier_move_to_index_exec(bContext *C, wmOperator *op) ModifierData *md = edit_modifier_property_get(op, ob, 0); int index = RNA_int_get(op->ptr, "index"); - if (!(md && ED_object_modifier_move_to_index(op->reports, ob, md, index))) { + if (!(md && ED_object_modifier_move_to_index(op->reports, RPT_WARNING, ob, md, index, true))) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.cc b/source/blender/editors/space_outliner/outliner_dragdrop.cc index 4be4233b24b..3ef63405fe4 100644 --- a/source/blender/editors/space_outliner/outliner_dragdrop.cc +++ b/source/blender/editors/space_outliner/outliner_dragdrop.cc @@ -1027,8 +1027,12 @@ static void datastack_drop_reorder(bContext *C, ReportList *reports, StackDropDa } else { index = outliner_get_insert_index(drag_te, drop_te, insert_type, &ob->modifiers); - ED_object_modifier_move_to_index( - reports, ob, static_cast(drop_data->drag_directdata), index); + ED_object_modifier_move_to_index(reports, + RPT_WARNING, + ob, + static_cast(drop_data->drag_directdata), + index, + true); } break; case TSE_CONSTRAINT: diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 17d2310b262..e70e87c53cf 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1759,6 +1759,19 @@ static void rna_Object_modifier_clear(Object *object, bContext *C) WM_main_add_notifier(NC_OBJECT | ND_MODIFIER | NA_REMOVED, object); } +static void rna_Object_modifier_move( + Object *object, Main *bmain, ReportList *reports, int from, int to) +{ + ModifierData *md = BLI_findlink(&object->modifiers, from); + + if (!md) { + BKE_reportf(reports, RPT_ERROR, "Invalid original modifier index '%d'", from); + return; + } + + ED_object_modifier_move_to_index(reports, RPT_ERROR, object, md, to, false); +} + static PointerRNA rna_Object_active_modifier_get(PointerRNA *ptr) { Object *ob = (Object *)ptr->owner_id; @@ -2635,6 +2648,16 @@ static void rna_def_object_modifiers(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_flag(func, FUNC_USE_CONTEXT); RNA_def_function_ui_description(func, "Remove all modifiers from the object"); + /* move a modifier */ + func = RNA_def_function(srna, "move", "rna_Object_modifier_move"); + RNA_def_function_ui_description(func, "Move a modifier to a different position"); + RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS); + parm = RNA_def_int( + func, "from_index", -1, INT_MIN, INT_MAX, "From Index", "Index to move", 0, 10000); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_int(func, "to_index", -1, INT_MIN, INT_MAX, "To Index", "Target index", 0, 10000); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + /* Active modifier. */ prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "Modifier"); From 6d79bc00732a506dbd6495bfe1dbe56d544234b6 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 26 Jan 2023 09:56:32 +0100 Subject: [PATCH 0959/1522] ImBuf: Use vector types in transform.cc. Replace array types with the vector types. No functional changes. --- source/blender/imbuf/intern/transform.cc | 107 ++++++++++------------- 1 file changed, 48 insertions(+), 59 deletions(-) diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc index 420cad06959..323460f4593 100644 --- a/source/blender/imbuf/intern/transform.cc +++ b/source/blender/imbuf/intern/transform.cc @@ -9,6 +9,7 @@ #include #include "BLI_math.h" +#include "BLI_math_vector.hh" #include "BLI_rect.h" #include "IMB_imbuf.h" @@ -22,19 +23,19 @@ struct TransformUserData { /** \brief Destination image buffer to write to. */ ImBuf *dst; /** \brief UV coordinates at the origin (0,0) in source image space. */ - double start_uv[2]; + double2 start_uv; /** * \brief delta UV coordinates along the source image buffer, when moving a single pixel in the X * axis of the dst image buffer. */ - double add_x[2]; + double2 add_x; /** * \brief delta UV coordinate along the source image buffer, when moving a single pixel in the Y * axes of the dst image buffer. */ - double add_y[2]; + double2 add_y; /** * \brief Cropping region in source image pixel space. @@ -54,45 +55,33 @@ struct TransformUserData { private: void init_start_uv(const float transform_matrix[4][4]) { - double start_uv_v3[3]; - double orig[3]; + double3 start_uv_v3; + double3 orig(0.0); double transform_matrix_double[4][4]; copy_m4d_m4(transform_matrix_double, transform_matrix); - zero_v3_db(orig); mul_v3_m4v3_db(start_uv_v3, transform_matrix_double, orig); - copy_v2_v2_db(start_uv, start_uv_v3); + start_uv = double2(start_uv_v3); } void init_add_x(const float transform_matrix[4][4]) { double transform_matrix_double[4][4]; copy_m4d_m4(transform_matrix_double, transform_matrix); - const int width = src->x; - double add_x_v3[3]; - double uv_max_x[3]; - zero_v3_db(uv_max_x); - uv_max_x[0] = width; - uv_max_x[1] = 0.0f; - mul_v3_m4v3_db(add_x_v3, transform_matrix_double, uv_max_x); - sub_v2_v2_db(add_x_v3, start_uv); - mul_v3db_db(add_x_v3, 1.0f / width); - copy_v2_v2_db(add_x, add_x_v3); + const double width = src->x; + double3 add_x_v3; + mul_v3_m4v3_db(add_x_v3, transform_matrix_double, double3(width, 0.0, 0.0)); + add_x = double2((add_x_v3 - double3(start_uv)) * (1.0 / width)); } void init_add_y(const float transform_matrix[4][4]) { double transform_matrix_double[4][4]; copy_m4d_m4(transform_matrix_double, transform_matrix); - const int height = src->y; - double add_y_v3[3]; - double uv_max_y[3]; - zero_v3_db(uv_max_y); - uv_max_y[0] = 0.0f; - uv_max_y[1] = height; - mul_v3_m4v3_db(add_y_v3, transform_matrix_double, uv_max_y); - sub_v2_v2_db(add_y_v3, start_uv); - mul_v3db_db(add_y_v3, 1.0f / height); - copy_v2_v2_db(add_y, add_y_v3); + const double height = src->y; + double3 add_y_v3; + double3 uv_max_y(0.0, height, 0.0); + mul_v3_m4v3_db(add_y_v3, transform_matrix_double, double3(0.0, height, 0.0)); + add_y = double2((add_y_v3 - double3(start_uv)) * (1.0 / height)); } }; @@ -110,7 +99,7 @@ class BaseDiscard { /** * \brief Should the source pixel at the given uv coordinate be discarded. */ - virtual bool should_discard(const TransformUserData &user_data, const double uv[2]) = 0; + virtual bool should_discard(const TransformUserData &user_data, const double2 uv) = 0; }; /** @@ -123,10 +112,10 @@ class CropSource : public BaseDiscard { * * Uses user_data.src_crop to determine if the uv coordinate should be skipped. */ - bool should_discard(const TransformUserData &user_data, const double uv[2]) override + bool should_discard(const TransformUserData &user_data, const double2 uv) override { - return uv[0] < user_data.src_crop.xmin || uv[0] >= user_data.src_crop.xmax || - uv[1] < user_data.src_crop.ymin || uv[1] >= user_data.src_crop.ymax; + return uv.x < user_data.src_crop.xmin || uv.x >= user_data.src_crop.xmax || + uv.y < user_data.src_crop.ymin || uv.y >= user_data.src_crop.ymax; } }; @@ -140,7 +129,7 @@ class NoDiscard : public BaseDiscard { * * Will never discard any pixels. */ - bool should_discard(const TransformUserData & /*user_data*/, const double /*uv*/[2]) override + bool should_discard(const TransformUserData & /*user_data*/, const double2 /*uv*/) override { return false; } @@ -168,9 +157,10 @@ class PixelPointer { StorageType *pointer; public: - void init_pixel_pointer(const ImBuf *image_buffer, int x, int y) + void init_pixel_pointer(const ImBuf *image_buffer, int2 start_coordinate) { - const size_t offset = (y * size_t(image_buffer->x) + x) * NumChannels; + const size_t offset = (start_coordinate.y * size_t(image_buffer->x) + start_coordinate.x) * + NumChannels; if constexpr (std::is_same_v) { pointer = image_buffer->rect_float + offset; @@ -214,6 +204,14 @@ class BaseUVWrapping { * \brief modify the given v coordinate. */ virtual double modify_v(const ImBuf *source_buffer, double v) = 0; + + /** + * \brief modify the given uv coordinate. + */ + double2 modify_uv(const ImBuf *source_buffer, double2 uv) + { + return double2(modify_u(source_buffer, uv.x), modify_v(source_buffer, uv.y)); + } }; /** @@ -290,25 +288,22 @@ class Sampler { static const int ChannelLen = NumChannels; using SampleType = std::array; - void sample(const ImBuf *source, const double u, const double v, SampleType &r_sample) + void sample(const ImBuf *source, const double2 uv, SampleType &r_sample) { if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v && NumChannels == 4) { - const double wrapped_u = uv_wrapper.modify_u(source, u); - const double wrapped_v = uv_wrapper.modify_v(source, v); - bilinear_interpolation_color_fl(source, nullptr, r_sample.data(), wrapped_u, wrapped_v); + const double2 wrapped_uv = uv_wrapper.modify_uv(source, uv); + bilinear_interpolation_color_fl(source, nullptr, r_sample.data(), UNPACK2(wrapped_uv)); } else if constexpr (Filter == IMB_FILTER_NEAREST && std::is_same_v && NumChannels == 4) { - const double wrapped_u = uv_wrapper.modify_u(source, u); - const double wrapped_v = uv_wrapper.modify_v(source, v); - nearest_interpolation_color_char(source, r_sample.data(), nullptr, wrapped_u, wrapped_v); + const double2 wrapped_uv = uv_wrapper.modify_uv(source, uv); + nearest_interpolation_color_char(source, r_sample.data(), nullptr, UNPACK2(wrapped_uv)); } else if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v && NumChannels == 4) { - const double wrapped_u = uv_wrapper.modify_u(source, u); - const double wrapped_v = uv_wrapper.modify_v(source, v); - bilinear_interpolation_color_char(source, r_sample.data(), nullptr, wrapped_u, wrapped_v); + const double2 wrapped_uv = uv_wrapper.modify_uv(source, uv); + bilinear_interpolation_color_char(source, r_sample.data(), nullptr, UNPACK2(wrapped_uv)); } else if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v) { if constexpr (std::is_same_v) { @@ -317,27 +312,23 @@ class Sampler { source->x, source->y, NumChannels, - u, - v, + UNPACK2(uv), true, true); } else { - const double wrapped_u = uv_wrapper.modify_u(source, u); - const double wrapped_v = uv_wrapper.modify_v(source, v); + const double2 wrapped_uv = uv_wrapper.modify_uv(source, uv); BLI_bilinear_interpolation_fl(source->rect_float, r_sample.data(), source->x, source->y, NumChannels, - wrapped_u, - wrapped_v); + UNPACK2(wrapped_uv)); } } else if constexpr (Filter == IMB_FILTER_NEAREST && std::is_same_v) { - const double wrapped_u = uv_wrapper.modify_u(source, u); - const double wrapped_v = uv_wrapper.modify_v(source, v); - sample_nearest_float(source, wrapped_u, wrapped_v, r_sample); + const double2 wrapped_uv = uv_wrapper.modify_uv(source, uv); + sample_nearest_float(source, UNPACK2(wrapped_uv), r_sample); } else { /* Unsupported sampler. */ @@ -466,19 +457,17 @@ class ScanlineProcessor { void process(const TransformUserData *user_data, int scanline) { const int width = user_data->dst->x; + double2 uv = user_data->start_uv + user_data->add_y * scanline; - double uv[2]; - madd_v2_v2db_db(uv, user_data->start_uv, user_data->add_y, scanline); - - output.init_pixel_pointer(user_data->dst, 0, scanline); + output.init_pixel_pointer(user_data->dst, int2(0, scanline)); for (int xi = 0; xi < width; xi++) { if (!discarder.should_discard(*user_data, uv)) { typename Sampler::SampleType sample; - sampler.sample(user_data->src, uv[0], uv[1], sample); + sampler.sample(user_data->src, uv, sample); channel_converter.convert_and_store(sample, output); } - add_v2_v2_db(uv, user_data->add_x); + uv += user_data->add_x; output.increase_pixel_pointer(); } } From f210842a725959d09e6dd87c9325c610aabbac00 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 26 Jan 2023 13:38:59 +0100 Subject: [PATCH 0960/1522] Sequencer: Improve Image Transform Quality When Exporting. Image Transform use linear or nearest sampling during editing and exporting. This gets sampling is fine for images that aren't scaled. When sequencing however you mostly want use some sort of scaling, that leads to poorer quality. This change will use sub-sampling to improve the quality. This is only enabled when rendering. During editing the subsampling is disabled to keep the user interface reacting as expected. Another improvement is that image transform is stopped at the moment it hadn't sampled at least 4 samples for a scan line. In that case we expect that there are no further samples that would change to result. In a future patch this could be replaced by a ray/bounding bo intersection as that would remove some unneeded loops in both the single sampled and sub sampled approach. --- .../draw/engines/image/image_drawing_mode.hh | 1 + source/blender/imbuf/IMB_imbuf.h | 3 + source/blender/imbuf/intern/transform.cc | 180 +++++++++++++++++- source/blender/sequencer/intern/render.c | 19 +- 4 files changed, 191 insertions(+), 12 deletions(-) diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh index 9345be800e8..d389ecd90af 100644 --- a/source/blender/draw/engines/image/image_drawing_mode.hh +++ b/source/blender/draw/engines/image/image_drawing_mode.hh @@ -516,6 +516,7 @@ template class ScreenSpaceDrawingMode : public AbstractD &texture_buffer, transform_mode, IMB_FILTER_NEAREST, + 1, uv_to_texel.ptr(), crop_rect_ptr); } diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index a5bb34392b1..79be739a205 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -846,6 +846,8 @@ typedef enum eIMBTransformMode { * - Only one data type buffer will be used (rect_float has priority over rect) * \param mode: Cropping/Wrap repeat effect to apply during transformation. * \param filter: Interpolation to use during sampling. + * \param num_subsamples: Number of subsamples to use. Increasing this would improve the quality, + * but reduces the performance. * \param transform_matrix: Transformation matrix to use. * The given matrix should transform between dst pixel space to src pixel space. * One unit is one pixel. @@ -860,6 +862,7 @@ void IMB_transform(const struct ImBuf *src, struct ImBuf *dst, eIMBTransformMode mode, eIMBInterpolationFilterMode filter, + const int num_subsamples, const float transform_matrix[4][4], const struct rctf *src_crop); diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc index 323460f4593..23aad5edf1d 100644 --- a/source/blender/imbuf/intern/transform.cc +++ b/source/blender/imbuf/intern/transform.cc @@ -9,6 +9,7 @@ #include #include "BLI_math.h" +#include "BLI_math_color_blend.h" #include "BLI_math_vector.hh" #include "BLI_rect.h" @@ -37,6 +38,14 @@ struct TransformUserData { */ double2 add_y; + struct { + int num; + double2 offset_x; + double2 offset_y; + double2 add_x; + double2 add_y; + } subsampling; + /** * \brief Cropping region in source image pixel space. */ @@ -45,11 +54,12 @@ struct TransformUserData { /** * \brief Initialize the start_uv, add_x and add_y fields based on the given transform matrix. */ - void init(const float transform_matrix[4][4]) + void init(const float transform_matrix[4][4], const int num_subsamples) { init_start_uv(transform_matrix); init_add_x(transform_matrix); init_add_y(transform_matrix); + init_subsampling(num_subsamples); } private: @@ -83,6 +93,15 @@ struct TransformUserData { mul_v3_m4v3_db(add_y_v3, transform_matrix_double, double3(0.0, height, 0.0)); add_y = double2((add_y_v3 - double3(start_uv)) * (1.0 / height)); } + + void init_subsampling(const int num_subsamples) + { + subsampling.num = max_ii(num_subsamples, 1); + subsampling.add_x = add_x / (subsampling.num); + subsampling.add_y = add_y / (subsampling.num); + subsampling.offset_x = -add_x * 0.5 + subsampling.add_x * 0.5; + subsampling.offset_y = -add_y * 0.5 + subsampling.add_y * 0.5; + } }; /** @@ -257,6 +276,39 @@ class WrapRepeatUV : public BaseUVWrapping { } }; +// TODO: should we use math_vectors for this. +template +class Pixel : public std::array { + public: + void clear() + { + for (int channel_index : IndexRange(NumChannels)) { + (*this)[channel_index] = 0; + } + } + + void add_subsample(const Pixel other, int sample_number) + { + BLI_STATIC_ASSERT((std::is_same_v) || (std::is_same_v), + "Only uchar and float channels supported."); + + float factor = 1.0 / (sample_number + 1); + if constexpr (std::is_same_v) { + BLI_STATIC_ASSERT(NumChannels == 4, "Pixels using uchar requires to have 4 channels."); + blend_color_interpolate_byte(this->data(), this->data(), other.data(), factor); + } + else if constexpr (std::is_same_v && NumChannels == 4) { + blend_color_interpolate_float(this->data(), this->data(), other.data(), factor); + } + else if constexpr (std::is_same_v) { + for (int channel_index : IndexRange(NumChannels)) { + (*this)[channel_index] = (*this)[channel_index] * (1.0 - factor) + + other[channel_index] * factor; + } + } + } +}; + /** * \brief Read a sample from an image buffer. * @@ -286,7 +338,7 @@ class Sampler { public: using ChannelType = StorageType; static const int ChannelLen = NumChannels; - using SampleType = std::array; + using SampleType = Pixel; void sample(const ImBuf *source, const double2 uv, SampleType &r_sample) { @@ -378,12 +430,12 @@ class Sampler { template class ChannelConverter { public: - using SampleType = std::array; + using SampleType = Pixel; using PixelType = PixelPointer; /** - * \brief Convert the number of channels of the given sample to match the pixel pointer and store - * it at the location the pixel_pointer points at. + * \brief Convert the number of channels of the given sample to match the pixel pointer and + * store it at the location the pixel_pointer points at. */ void convert_and_store(const SampleType &sample, PixelType &pixel_pointer) { @@ -413,6 +465,19 @@ class ChannelConverter { BLI_assert_unreachable(); } } + + void mix_and_store(const SampleType &sample, PixelType &pixel_pointer, const float mix_factor) + { + if constexpr (std::is_same_v) { + BLI_STATIC_ASSERT(SourceNumChannels == 4, "Unsigned chars always have 4 channels."); + BLI_STATIC_ASSERT(DestinationNumChannels == 4, "Unsigned chars always have 4 channels."); + blend_color_interpolate_byte( + pixel_pointer.get_pointer(), pixel_pointer.get_pointer(), sample.data(), mix_factor); + } + else { + BLI_assert_unreachable(); + } + } }; /** @@ -442,8 +507,8 @@ class ScanlineProcessor { Sampler sampler; /** - * \brief Channels sizzling logic to convert between the input image buffer and the output image - * buffer. + * \brief Channels sizzling logic to convert between the input image buffer and the output + * image buffer. */ ChannelConvertersubsampling.num > 1) { + process_with_subsampling(user_data, scanline); + // } + // else { + // process_one_sample_per_pixel(user_data, scanline); + // } + } + + private: + void process_one_sample_per_pixel(const TransformUserData *user_data, int scanline) { const int width = user_data->dst->x; double2 uv = user_data->start_uv + user_data->add_y * scanline; output.init_pixel_pointer(user_data->dst, int2(0, scanline)); - for (int xi = 0; xi < width; xi++) { + int xi = 0; + while (xi < width) { + const bool discard_pixel = discarder.should_discard(*user_data, uv); + if (!discard_pixel) { + break; + } + uv += user_data->add_x; + output.increase_pixel_pointer(); + xi += 1; + } + + /* + * Draw until we didn't draw for at least 4 pixels. + */ + int num_output_pixels_skipped = 0; + const int num_missing_output_pixels_allowed = 4; + for (; xi < width && num_output_pixels_skipped < num_missing_output_pixels_allowed; xi++) { if (!discarder.should_discard(*user_data, uv)) { typename Sampler::SampleType sample; sampler.sample(user_data->src, uv, sample); channel_converter.convert_and_store(sample, output); } + else { + num_output_pixels_skipped += 1; + } uv += user_data->add_x; output.increase_pixel_pointer(); } } + + void process_with_subsampling(const TransformUserData *user_data, int scanline) + { + const int width = user_data->dst->x; + double2 uv = user_data->start_uv + user_data->add_y * scanline; + + output.init_pixel_pointer(user_data->dst, int2(0, scanline)); + int xi = 0; + /* + * Skip leading pixels that would be fully discarded. + * + * NOTE: This could be improved by intersection between an ray and the image bounds. + */ + while (xi < width) { + const bool discard_pixel = discarder.should_discard(*user_data, uv) && + discarder.should_discard(*user_data, uv + user_data->add_x) && + discarder.should_discard(*user_data, uv + user_data->add_y) && + discarder.should_discard( + *user_data, uv + user_data->add_x + user_data->add_y); + if (!discard_pixel) { + break; + } + uv += user_data->add_x; + output.increase_pixel_pointer(); + xi += 1; + } + + /* + * Draw until we didn't draw for at least 4 pixels. + */ + int num_output_pixels_skipped = 0; + const int num_missing_output_pixels_allowed = 4; + for (; xi < width && num_output_pixels_skipped < num_missing_output_pixels_allowed; xi++) { + typename Sampler::SampleType sample; + sample.clear(); + int num_subsamples_added = 0; + + double2 subsample_uv_y = uv + user_data->subsampling.offset_y; + for (int subsample_yi : IndexRange(user_data->subsampling.num)) { + UNUSED_VARS(subsample_yi); + double2 subsample_uv = subsample_uv_y + user_data->subsampling.offset_x; + for (int subsample_xi : IndexRange(user_data->subsampling.num)) { + UNUSED_VARS(subsample_xi); + if (!discarder.should_discard(*user_data, subsample_uv)) { + typename Sampler::SampleType sub_sample; + sampler.sample(user_data->src, subsample_uv, sub_sample); + sample.add_subsample(sub_sample, num_subsamples_added); + num_subsamples_added += 1; + } + subsample_uv += user_data->subsampling.add_x; + } + subsample_uv_y += user_data->subsampling.add_y; + } + + if (num_subsamples_added != 0) { + float mix_weight = float(num_subsamples_added) / + (user_data->subsampling.num * user_data->subsampling.num); + channel_converter.mix_and_store(sample, output, mix_weight); + } + else { + num_output_pixels_skipped += 1; + } + uv += user_data->add_x; + output.increase_pixel_pointer(); + } + } }; /** @@ -562,6 +723,7 @@ void IMB_transform(const struct ImBuf *src, struct ImBuf *dst, const eIMBTransformMode mode, const eIMBInterpolationFilterMode filter, + const int num_subsamples, const float transform_matrix[4][4], const struct rctf *src_crop) { @@ -575,7 +737,7 @@ void IMB_transform(const struct ImBuf *src, if (mode == IMB_TRANSFORM_MODE_CROP_SRC) { user_data.src_crop = *src_crop; } - user_data.init(transform_matrix); + user_data.init(transform_matrix, num_subsamples); if (filter == IMB_FILTER_NEAREST) { transform_threaded(&user_data, mode); diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c index 5c6a59a5943..daca02b4f79 100644 --- a/source/blender/sequencer/intern/render.c +++ b/source/blender/sequencer/intern/render.c @@ -445,8 +445,14 @@ static void sequencer_thumbnail_transform(ImBuf *in, ImBuf *out) (const float[]){scale_x, scale_y, 1.0f}); transform_pivot_set_m4(transform_matrix, pivot); invert_m4(transform_matrix); - - IMB_transform(in, out, IMB_TRANSFORM_MODE_REGULAR, IMB_FILTER_NEAREST, transform_matrix, NULL); + const int num_subsamples = 1; + IMB_transform(in, + out, + IMB_TRANSFORM_MODE_REGULAR, + IMB_FILTER_NEAREST, + num_subsamples, + transform_matrix, + NULL); } /* Check whether transform introduces transparent ares in the result (happens when the transformed @@ -518,7 +524,14 @@ static void sequencer_preprocess_transform_crop( filter = IMB_FILTER_BILINEAR; } - IMB_transform(in, out, IMB_TRANSFORM_MODE_CROP_SRC, filter, transform_matrix, &source_crop); + const int num_subsamples = G.is_rendering ? 3 : 1; + IMB_transform(in, + out, + IMB_TRANSFORM_MODE_CROP_SRC, + filter, + num_subsamples, + transform_matrix, + &source_crop); if (!seq_image_transform_transparency_gained(context, seq)) { out->planes = in->planes; From 3b17d6c6192fa0c2a3d7f2fff9fe8584f857a926 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 26 Jan 2023 15:03:19 +0100 Subject: [PATCH 0961/1522] Sequencer: Made subsampling a transform option. There are cases where automatic selection of subsampling doesn't work This patch move adds a filtering option that can enable this. --- release/scripts/addons | 2 +- source/blender/makesdna/DNA_sequence_types.h | 1 + .../blender/makesrna/intern/rna_sequencer.c | 5 +++++ source/blender/sequencer/intern/render.c | 22 +++++++++++++------ 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/release/scripts/addons b/release/scripts/addons index d887a4ea6b2..9958ddb8799 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit d887a4ea6b2a9d64b926034d4e78ecf7a48ca979 +Subproject commit 9958ddb879934718cc2b379b556f0bc3b861bee5 diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index d8005b83383..47039c740c1 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -795,6 +795,7 @@ typedef enum SequenceColorTag { enum { SEQ_TRANSFORM_FILTER_NEAREST = 0, SEQ_TRANSFORM_FILTER_BILINEAR = 1, + SEQ_TRANSFORM_FILTER_NEAREST_3x3 = 2, }; typedef enum eSeqChannelFlag { diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index eab9f9c26da..7dd13324f88 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -1510,6 +1510,11 @@ static void rna_def_strip_crop(BlenderRNA *brna) static const EnumPropertyItem transform_filter_items[] = { {SEQ_TRANSFORM_FILTER_NEAREST, "NEAREST", 0, "Nearest", ""}, {SEQ_TRANSFORM_FILTER_BILINEAR, "BILINEAR", 0, "Bilinear", ""}, + {SEQ_TRANSFORM_FILTER_NEAREST_3x3, + "SUBSAMPLING_3x3", + 0, + "Subsampling (3x3)", + "Use nearest with 3x3 subsamples during rendering"}, {0, NULL, 0, NULL, NULL}, }; diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c index daca02b4f79..7f73a32a9c3 100644 --- a/source/blender/sequencer/intern/render.c +++ b/source/blender/sequencer/intern/render.c @@ -515,16 +515,24 @@ static void sequencer_preprocess_transform_crop( const float crop_scale_factor = do_scale_to_render_size ? preview_scale_factor : 1.0f; sequencer_image_crop_init(seq, in, crop_scale_factor, &source_crop); - eIMBInterpolationFilterMode filter; const StripTransform *transform = seq->strip->transform; - if (transform->filter == SEQ_TRANSFORM_FILTER_NEAREST) { - filter = IMB_FILTER_NEAREST; - } - else { - filter = IMB_FILTER_BILINEAR; + eIMBInterpolationFilterMode filter; + int num_subsamples = 1; + switch (transform->filter) { + case SEQ_TRANSFORM_FILTER_NEAREST: + filter = IMB_FILTER_NEAREST; + num_subsamples = 1; + break; + case SEQ_TRANSFORM_FILTER_BILINEAR: + filter = IMB_FILTER_BILINEAR; + num_subsamples = 1; + break; + case SEQ_TRANSFORM_FILTER_NEAREST_3x3: + filter = IMB_FILTER_NEAREST; + num_subsamples = G.is_rendering ? 3 : 1; + break; } - const int num_subsamples = G.is_rendering ? 3 : 1; IMB_transform(in, out, IMB_TRANSFORM_MODE_CROP_SRC, From c412c38f0de3fef5496637336576ca15d23ec658 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 26 Jan 2023 15:15:21 +0100 Subject: [PATCH 0962/1522] Fix missing code-paths in previous sequence/imbuf commits. --- source/blender/imbuf/intern/transform.cc | 25 +++++++----------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc index 23aad5edf1d..fc4d1c3a9e3 100644 --- a/source/blender/imbuf/intern/transform.cc +++ b/source/blender/imbuf/intern/transform.cc @@ -474,6 +474,11 @@ class ChannelConverter { blend_color_interpolate_byte( pixel_pointer.get_pointer(), pixel_pointer.get_pointer(), sample.data(), mix_factor); } + else if constexpr (std::is_same_v && SourceNumChannels == 4 && + DestinationNumChannels == 4) { + blend_color_interpolate_float( + pixel_pointer.get_pointer(), pixel_pointer.get_pointer(), sample.data(), mix_factor); + } else { BLI_assert_unreachable(); } @@ -547,20 +552,12 @@ class ScanlineProcessor { xi += 1; } - /* - * Draw until we didn't draw for at least 4 pixels. - */ - int num_output_pixels_skipped = 0; - const int num_missing_output_pixels_allowed = 4; - for (; xi < width && num_output_pixels_skipped < num_missing_output_pixels_allowed; xi++) { + for (; xi < width; xi++) { if (!discarder.should_discard(*user_data, uv)) { typename Sampler::SampleType sample; sampler.sample(user_data->src, uv, sample); channel_converter.convert_and_store(sample, output); } - else { - num_output_pixels_skipped += 1; - } uv += user_data->add_x; output.increase_pixel_pointer(); @@ -593,12 +590,7 @@ class ScanlineProcessor { xi += 1; } - /* - * Draw until we didn't draw for at least 4 pixels. - */ - int num_output_pixels_skipped = 0; - const int num_missing_output_pixels_allowed = 4; - for (; xi < width && num_output_pixels_skipped < num_missing_output_pixels_allowed; xi++) { + for (; xi < width; xi++) { typename Sampler::SampleType sample; sample.clear(); int num_subsamples_added = 0; @@ -625,9 +617,6 @@ class ScanlineProcessor { (user_data->subsampling.num * user_data->subsampling.num); channel_converter.mix_and_store(sample, output, mix_weight); } - else { - num_output_pixels_skipped += 1; - } uv += user_data->add_x; output.increase_pixel_pointer(); } From 1fd54204b0a1439ef21719d6bfd4efb84e08d27c Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Thu, 26 Jan 2023 15:17:37 +0100 Subject: [PATCH 0963/1522] Enable commented out code. Code was disabled for debugging purposes. --- source/blender/imbuf/intern/transform.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc index fc4d1c3a9e3..198d04cc5f6 100644 --- a/source/blender/imbuf/intern/transform.cc +++ b/source/blender/imbuf/intern/transform.cc @@ -526,12 +526,12 @@ class ScanlineProcessor { */ void process(const TransformUserData *user_data, int scanline) { - // if (user_data->subsampling.num > 1) { - process_with_subsampling(user_data, scanline); - // } - // else { - // process_one_sample_per_pixel(user_data, scanline); - // } + if (user_data->subsampling.num > 1) { + process_with_subsampling(user_data, scanline); + } + else { + process_one_sample_per_pixel(user_data, scanline); + } } private: From f19f50d288e2751bf36d7d4d1261008c7ea19da5 Mon Sep 17 00:00:00 2001 From: Michael Kowalski Date: Thu, 26 Jan 2023 10:35:14 -0500 Subject: [PATCH 0964/1522] USD export test format fixes. --- .../blender/io/usd/tests/usd_export_test.cc | 32 ++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/source/blender/io/usd/tests/usd_export_test.cc b/source/blender/io/usd/tests/usd_export_test.cc index c13da695c87..c34ab7cd6f7 100644 --- a/source/blender/io/usd/tests/usd_export_test.cc +++ b/source/blender/io/usd/tests/usd_export_test.cc @@ -25,8 +25,8 @@ #include "BKE_node.h" #include "BLI_fileops.h" #include "BLI_math.h" -#include "BLI_path_util.h" #include "BLI_math_vector_types.hh" +#include "BLI_path_util.h" #include "BLO_readfile.h" #include "BKE_node_runtime.hh" @@ -45,11 +45,9 @@ const StringRefNull simple_scene_filename = "usd/usd_simple_scene.blend"; const StringRefNull materials_filename = "usd/usd_materials_export.blend"; const StringRefNull output_filename = "output.usd"; - static const bNode *find_node_for_type_in_graph(const bNodeTree *nodetree, const blender::StringRefNull type_idname); - class UsdExportTest : public BlendfileLoadingBaseTest { protected: struct bContext *context = nullptr; @@ -104,7 +102,9 @@ class UsdExportTest : public BlendfileLoadingBaseTest { * Loop the sockets on the Blender bNode, and fail if any of their values do * not match the equivalent Attribtue values on the UsdPrim. */ - const void compare_blender_node_to_usd_prim(const bNode *bsdf_node, const pxr::UsdPrim& bsdf_prim) { + const void compare_blender_node_to_usd_prim(const bNode *bsdf_node, + const pxr::UsdPrim &bsdf_prim) + { ASSERT_NE(bsdf_node, nullptr); ASSERT_TRUE(bool(bsdf_prim)); @@ -155,7 +155,9 @@ class UsdExportTest : public BlendfileLoadingBaseTest { } } - const void compare_blender_image_to_usd_image_shader(const bNode *image_node, const pxr::UsdPrim& image_prim) { + const void compare_blender_image_to_usd_image_shader(const bNode *image_node, + const pxr::UsdPrim &image_prim) + { const Image *image = reinterpret_cast(image_node->id); const pxr::UsdShadeShader image_shader(image_prim); @@ -171,14 +173,16 @@ class UsdExportTest : public BlendfileLoadingBaseTest { /* The path is expected to be relative, but that means in Blender the * path will start with //. */ - EXPECT_EQ(BLI_path_cmp_normalized(image->filepath+2, image_prim_asset.GetAssetPath().c_str()), 0); + EXPECT_EQ( + BLI_path_cmp_normalized(image->filepath + 2, image_prim_asset.GetAssetPath().c_str()), 0); } /* * Determine if a Blender Mesh matches a UsdGeomMesh prim by checking counts * on vertices, faces, face indices, and normals. */ - const void compare_blender_mesh_to_usd_prim(const Mesh *mesh, const pxr::UsdGeomMesh& mesh_prim) { + const void compare_blender_mesh_to_usd_prim(const Mesh *mesh, const pxr::UsdGeomMesh &mesh_prim) + { pxr::VtIntArray face_indices; pxr::VtIntArray face_counts; pxr::VtVec3fArray positions; @@ -196,10 +200,8 @@ class UsdExportTest : public BlendfileLoadingBaseTest { EXPECT_EQ(mesh->totloop, face_indices.size()); EXPECT_EQ(mesh->totloop, normals.size()); } - }; - TEST_F(UsdExportTest, usd_export_rain_mesh) { if (!load_file_and_depsgraph(simple_scene_filename)) { @@ -239,8 +241,8 @@ TEST_F(UsdExportTest, usd_export_rain_mesh) } } - -static const bNode *find_node_for_type_in_graph(const bNodeTree *nodetree, const blender::StringRefNull type_idname) +static const bNode *find_node_for_type_in_graph(const bNodeTree *nodetree, + const blender::StringRefNull type_idname) { auto found_nodes = nodetree->nodes_by_type(type_idname); if (found_nodes.size() == 1) { @@ -250,7 +252,6 @@ static const bNode *find_node_for_type_in_graph(const bNodeTree *nodetree, const return nullptr; } - /* * Export Material test-- export a scene with a material, then read it back * in and check that the BSDF and Image Texture nodes translated correctly @@ -269,7 +270,8 @@ TEST_F(UsdExportTest, usd_export_material) /* There are two materials because of the Dots Stroke. */ EXPECT_EQ(BLI_listbase_count(&bfile->main->materials), 2); - Material *material = reinterpret_cast(BKE_libblock_find_name(bfile->main, ID_MA, "Material")); + Material *material = reinterpret_cast( + BKE_libblock_find_name(bfile->main, ID_MA, "Material")); EXPECT_TRUE(bool(material)); @@ -300,13 +302,13 @@ TEST_F(UsdExportTest, usd_export_material) ASSERT_NE(image_node, nullptr); ASSERT_NE(image_node->storage, nullptr); - const std::string image_prim_name = pxr::TfMakeValidIdentifier(image_node->name); const pxr::UsdPrim image_prim = stage->GetPrimAtPath( pxr::SdfPath("/_materials/Material/preview/" + image_prim_name)); - ASSERT_TRUE(bool(image_prim)) << "Unable to find Material prim from exported stage " << output_filename; + ASSERT_TRUE(bool(image_prim)) << "Unable to find Material prim from exported stage " + << output_filename; compare_blender_image_to_usd_image_shader(image_node, image_prim); } From 3b4486424a3299756dbe7eba923348c83304ca36 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Thu, 26 Jan 2023 07:54:04 -0300 Subject: [PATCH 0965/1522] Fix repeated transform constraint orientations On some occasions, as in cases where transform operations are triggered via gizmos, the constrain orientations that can be toggled with multiple clicks of X, Y or Z were repeated. There is no use in maintaining repeated orientations. --- .../editors/transform/transform_constraints.c | 15 ++++++++---- .../editors/transform/transform_generics.c | 24 +++++++++++++------ 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index 61adc98c258..f8e116e77b8 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -1001,6 +1001,9 @@ void postSelectConstraint(TransInfo *t) static void setNearestAxis2d(TransInfo *t) { + /* Clear any prior constraint flags. */ + t->con.mode &= ~(CON_AXIS0 | CON_AXIS1 | CON_AXIS2); + /* no correction needed... just use whichever one is lower */ if (abs(t->mval[0] - t->con.imval[0]) < abs(t->mval[1] - t->con.imval[1])) { t->con.mode |= CON_AXIS1; @@ -1014,6 +1017,9 @@ static void setNearestAxis2d(TransInfo *t) static void setNearestAxis3d(TransInfo *t) { + /* Clear any prior constraint flags. */ + t->con.mode &= ~(CON_AXIS0 | CON_AXIS1 | CON_AXIS2); + float zfac; float mvec[3], proj[3]; float len[3]; @@ -1090,10 +1096,7 @@ static void setNearestAxis3d(TransInfo *t) void setNearestAxis(TransInfo *t) { - /* clear any prior constraint flags */ - t->con.mode &= ~CON_AXIS0; - t->con.mode &= ~CON_AXIS1; - t->con.mode &= ~CON_AXIS2; + eTConstraint mode_prev = t->con.mode; /* constraint setting - depends on spacetype */ if (t->spacetype == SPACE_VIEW3D) { @@ -1105,7 +1108,9 @@ void setNearestAxis(TransInfo *t) setNearestAxis2d(t); } - projection_matrix_calc(t, t->con.pmtx); + if (mode_prev != t->con.mode) { + projection_matrix_calc(t, t->con.pmtx); + } } /** \} */ diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 968e2bca5b9..f09c919c8b7 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -440,6 +440,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve { short orient_types[3]; + short orient_type_apply = O_DEFAULT; float custom_matrix[3][3]; int orient_type_scene = V3D_ORIENT_GLOBAL; @@ -502,14 +503,23 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve t->is_orient_default_overwrite = true; } } - else if (t->con.mode & CON_APPLY) { - orient_type_set = orient_type_scene; - } - else if (orient_type_scene == V3D_ORIENT_GLOBAL) { - orient_type_set = V3D_ORIENT_LOCAL; + + if (orient_type_set == -1) { + if (orient_type_scene == V3D_ORIENT_GLOBAL) { + orient_type_set = V3D_ORIENT_LOCAL; + } + else { + orient_type_set = V3D_ORIENT_GLOBAL; + } + + if (t->con.mode & CON_APPLY) { + orient_type_apply = O_SCENE; + } } else { - orient_type_set = V3D_ORIENT_GLOBAL; + if (t->con.mode & CON_APPLY) { + orient_type_apply = O_SET; + } } BLI_assert(!ELEM(-1, orient_type_default, orient_type_set)); @@ -546,7 +556,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve } } - transform_orientations_current_set(t, (t->con.mode & CON_APPLY) ? 2 : 0); + transform_orientations_current_set(t, orient_type_apply); } if (op && ((prop = RNA_struct_find_property(op->ptr, "release_confirm")) && From d6c9cd445cb41480b40fc7a7c29bbf982a2a6446 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 26 Jan 2023 12:34:28 -0600 Subject: [PATCH 0966/1522] Geometry Nodes: Skip sorting in topology nodes if possible When the sort weights are a single value, they have no effect, so sorting the relevant indices for the element will be wasted work. The sorting is expensive compared to the rest of the node. In my simple test of the points of curve node, it became 6 times faster when the weights are a single value. --- ...node_geo_curve_topology_points_of_curve.cc | 40 ++++++++------- .../node_geo_mesh_topology_corners_of_face.cc | 37 ++++++++------ ...ode_geo_mesh_topology_corners_of_vertex.cc | 45 +++++++++-------- .../node_geo_mesh_topology_edges_of_vertex.cc | 50 +++++++++++-------- 4 files changed, 97 insertions(+), 75 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc index 0f9c14b0fee..8d9e4a07a76 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc @@ -49,6 +49,8 @@ class PointsOfCurveInput final : public bke::CurvesFieldInput { const eAttrDomain domain, const IndexMask mask) const final { + const OffsetIndices points_by_curve = curves.points_by_curve(); + const bke::CurvesFieldContext context{curves, domain}; fn::FieldEvaluator evaluator{context, &mask}; evaluator.add(curve_index_); @@ -62,7 +64,7 @@ class PointsOfCurveInput final : public bke::CurvesFieldInput { point_evaluator.add(sort_weight_); point_evaluator.evaluate(); const VArray all_sort_weights = point_evaluator.get_evaluated(0); - const OffsetIndices points_by_curve = curves.points_by_curve(); + const bool use_sorting = !all_sort_weights.is_single(); Array point_of_curve(mask.min_array_size()); threading::parallel_for(mask.index_range(), 256, [&](const IndexRange range) { @@ -77,25 +79,29 @@ class PointsOfCurveInput final : public bke::CurvesFieldInput { point_of_curve[selection_i] = 0; continue; } - const IndexRange points = points_by_curve[curve_i]; - /* Retrieve the weights for each point. */ - sort_weights.reinitialize(points.size()); - all_sort_weights.materialize_compressed(IndexMask(points), sort_weights.as_mutable_span()); - - /* Sort a separate array of compressed indices corresponding to the compressed weights. - * This allows using `materialize_compressed` to avoid virtual function call overhead - * when accessing values in the sort weights. However, it means a separate array of - * indices within the compressed array is necessary for sorting. */ - sort_indices.reinitialize(points.size()); - std::iota(sort_indices.begin(), sort_indices.end(), 0); - std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { - return sort_weights[a] < sort_weights[b]; - }); - const int index_in_sort_wrapped = mod_i(index_in_sort, points.size()); - point_of_curve[selection_i] = points[sort_indices[index_in_sort_wrapped]]; + if (use_sorting) { + /* Retrieve the weights for each point. */ + sort_weights.reinitialize(points.size()); + all_sort_weights.materialize_compressed(IndexMask(points), + sort_weights.as_mutable_span()); + + /* Sort a separate array of compressed indices corresponding to the compressed weights. + * This allows using `materialize_compressed` to avoid virtual function call overhead + * when accessing values in the sort weights. However, it means a separate array of + * indices within the compressed array is necessary for sorting. */ + sort_indices.reinitialize(points.size()); + std::iota(sort_indices.begin(), sort_indices.end(), 0); + std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { + return sort_weights[a] < sort_weights[b]; + }); + point_of_curve[selection_i] = points[sort_indices[index_in_sort_wrapped]]; + } + else { + point_of_curve[selection_i] = points[index_in_sort_wrapped]; + } } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc index d5b4b4869c1..55c70095236 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_face.cc @@ -64,6 +64,7 @@ class CornersOfFaceInput final : public bke::MeshFieldInput { corner_evaluator.add(sort_weight_); corner_evaluator.evaluate(); const VArray all_sort_weights = corner_evaluator.get_evaluated(0); + const bool use_sorting = !all_sort_weights.is_single(); Array corner_of_face(mask.min_array_size()); threading::parallel_for(mask.index_range(), 1024, [&](const IndexRange range) { @@ -82,23 +83,27 @@ class CornersOfFaceInput final : public bke::MeshFieldInput { const MPoly &poly = polys[poly_i]; const IndexRange corners(poly.loopstart, poly.totloop); - /* Retrieve the weights for each corner. */ - sort_weights.reinitialize(corners.size()); - all_sort_weights.materialize_compressed(IndexMask(corners), - sort_weights.as_mutable_span()); - - /* Sort a separate array of compressed indices corresponding to the compressed weights. - * This allows using `materialize_compressed` to avoid virtual function call overhead - * when accessing values in the sort weights. However, it means a separate array of - * indices within the compressed array is necessary for sorting. */ - sort_indices.reinitialize(corners.size()); - std::iota(sort_indices.begin(), sort_indices.end(), 0); - std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { - return sort_weights[a] < sort_weights[b]; - }); - const int index_in_sort_wrapped = mod_i(index_in_sort, corners.size()); - corner_of_face[selection_i] = corners[sort_indices[index_in_sort_wrapped]]; + if (use_sorting) { + /* Retrieve the weights for each corner. */ + sort_weights.reinitialize(corners.size()); + all_sort_weights.materialize_compressed(IndexMask(corners), + sort_weights.as_mutable_span()); + + /* Sort a separate array of compressed indices corresponding to the compressed weights. + * This allows using `materialize_compressed` to avoid virtual function call overhead + * when accessing values in the sort weights. However, it means a separate array of + * indices within the compressed array is necessary for sorting. */ + sort_indices.reinitialize(corners.size()); + std::iota(sort_indices.begin(), sort_indices.end(), 0); + std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { + return sort_weights[a] < sort_weights[b]; + }); + corner_of_face[selection_i] = corners[sort_indices[index_in_sort_wrapped]]; + } + else { + corner_of_face[selection_i] = corners[index_in_sort_wrapped]; + } } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc index 12310d6df15..8d7ebb4e105 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc @@ -77,6 +77,7 @@ class CornersOfVertInput final : public bke::MeshFieldInput { corner_evaluator.add(sort_weight_); corner_evaluator.evaluate(); const VArray all_sort_weights = corner_evaluator.get_evaluated(0); + const bool use_sorting = !all_sort_weights.is_single(); Array corner_of_vertex(mask.min_array_size()); threading::parallel_for(mask.index_range(), 1024, [&](const IndexRange range) { @@ -99,27 +100,31 @@ class CornersOfVertInput final : public bke::MeshFieldInput { continue; } - /* Retrieve the connected edge indices as 64 bit integers for #materialize_compressed. */ - corner_indices.reinitialize(corners.size()); - convert_span(corners, corner_indices); - - /* Retrieve a compressed array of weights for each edge. */ - sort_weights.reinitialize(corners.size()); - all_sort_weights.materialize_compressed(IndexMask(corner_indices), - sort_weights.as_mutable_span()); - - /* Sort a separate array of compressed indices corresponding to the compressed weights. - * This allows using `materialize_compressed` to avoid virtual function call overhead - * when accessing values in the sort weights. However, it means a separate array of - * indices within the compressed array is necessary for sorting. */ - sort_indices.reinitialize(corners.size()); - std::iota(sort_indices.begin(), sort_indices.end(), 0); - std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { - return sort_weights[a] < sort_weights[b]; - }); - const int index_in_sort_wrapped = mod_i(index_in_sort, corners.size()); - corner_of_vertex[selection_i] = corner_indices[sort_indices[index_in_sort_wrapped]]; + if (use_sorting) { + /* Retrieve the connected edge indices as 64 bit integers for #materialize_compressed. */ + corner_indices.reinitialize(corners.size()); + convert_span(corners, corner_indices); + + /* Retrieve a compressed array of weights for each edge. */ + sort_weights.reinitialize(corners.size()); + all_sort_weights.materialize_compressed(IndexMask(corner_indices), + sort_weights.as_mutable_span()); + + /* Sort a separate array of compressed indices corresponding to the compressed weights. + * This allows using `materialize_compressed` to avoid virtual function call overhead + * when accessing values in the sort weights. However, it means a separate array of + * indices within the compressed array is necessary for sorting. */ + sort_indices.reinitialize(corners.size()); + std::iota(sort_indices.begin(), sort_indices.end(), 0); + std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { + return sort_weights[a] < sort_weights[b]; + }); + corner_of_vertex[selection_i] = corner_indices[sort_indices[index_in_sort_wrapped]]; + } + else { + corner_of_vertex[selection_i] = corner_indices[index_in_sort_wrapped]; + } } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc index b16bbabfe0b..7c27a4b783d 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc @@ -61,8 +61,8 @@ class EdgesOfVertInput final : public bke::MeshFieldInput { { const IndexRange vert_range(mesh.totvert); const Span edges = mesh.edges(); - Array> vert_to_edge_map = bke::mesh_topology::build_vert_to_edge_map(edges, - mesh.totvert); + const Array> vert_to_edge_map = bke::mesh_topology::build_vert_to_edge_map( + edges, mesh.totvert); const bke::MeshFieldContext context{mesh, domain}; fn::FieldEvaluator evaluator{context, &mask}; @@ -77,6 +77,7 @@ class EdgesOfVertInput final : public bke::MeshFieldInput { edge_evaluator.add(sort_weight_); edge_evaluator.evaluate(); const VArray all_sort_weights = edge_evaluator.get_evaluated(0); + const bool use_sorting = !all_sort_weights.is_single(); Array edge_of_vertex(mask.min_array_size()); threading::parallel_for(mask.index_range(), 1024, [&](const IndexRange range) { @@ -99,27 +100,32 @@ class EdgesOfVertInput final : public bke::MeshFieldInput { continue; } - /* Retrieve the connected edge indices as 64 bit integers for #materialize_compressed. */ - edge_indices.reinitialize(edges.size()); - convert_span(edges, edge_indices); - - /* Retrieve a compressed array of weights for each edge. */ - sort_weights.reinitialize(edges.size()); - all_sort_weights.materialize_compressed(IndexMask(edge_indices), - sort_weights.as_mutable_span()); - - /* Sort a separate array of compressed indices corresponding to the compressed weights. - * This allows using `materialize_compressed` to avoid virtual function call overhead - * when accessing values in the sort weights. However, it means a separate array of - * indices within the compressed array is necessary for sorting. */ - sort_indices.reinitialize(edges.size()); - std::iota(sort_indices.begin(), sort_indices.end(), 0); - std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { - return sort_weights[a] < sort_weights[b]; - }); - const int index_in_sort_wrapped = mod_i(index_in_sort, edges.size()); - edge_of_vertex[selection_i] = edge_indices[sort_indices[index_in_sort_wrapped]]; + if (use_sorting) { + /* Retrieve the connected edge indices as 64 bit integers for #materialize_compressed. */ + edge_indices.reinitialize(edges.size()); + convert_span(edges, edge_indices); + + /* Retrieve a compressed array of weights for each edge. */ + sort_weights.reinitialize(edges.size()); + all_sort_weights.materialize_compressed(IndexMask(edge_indices), + sort_weights.as_mutable_span()); + + /* Sort a separate array of compressed indices corresponding to the compressed weights. + * This allows using `materialize_compressed` to avoid virtual function call overhead + * when accessing values in the sort weights. However, it means a separate array of + * indices within the compressed array is necessary for sorting. */ + sort_indices.reinitialize(edges.size()); + std::iota(sort_indices.begin(), sort_indices.end(), 0); + std::stable_sort(sort_indices.begin(), sort_indices.end(), [&](int a, int b) { + return sort_weights[a] < sort_weights[b]; + }); + + edge_of_vertex[selection_i] = edge_indices[sort_indices[index_in_sort_wrapped]]; + } + else { + edge_of_vertex[selection_i] = edge_indices[index_in_sort_wrapped]; + } } }); From 9a4c54e8b0a3b6be8360042bc3a755b7adef20fd Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Thu, 26 Jan 2023 13:01:03 -0600 Subject: [PATCH 0967/1522] Fix: Curve to Points node has wrong field interface status In 7536abbe16bd changes make possible to input field as Count field. But changes of declaration probably was forgotten. So now this input can take field and node will be work. But input link was red. This patch resolves this issue. Differential Revision: https://developer.blender.org/D17131 --- source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc index ab7a9bef8db..f17c8044995 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_points.cc @@ -25,6 +25,7 @@ static void node_declare(NodeDeclarationBuilder &b) b.add_input(N_("Count")) .default_value(10) .min(2) + .field_on_all() .max(100000) .make_available( [](bNode &node) { node_storage(node).mode = GEO_NODE_CURVE_RESAMPLE_COUNT; }); From cdef135f6f651c669f526a931a3cfd996d1e8cbd Mon Sep 17 00:00:00 2001 From: Michael Kowalski Date: Thu, 26 Jan 2023 18:08:45 -0500 Subject: [PATCH 0968/1522] USD import: Support importing USDZ. This addressed feature request T99811. Added the following features to fully support importing USDZ archives: - Added .usdz to the list of supported extensions. - Added new USD import options to copy textures from USDZ archives. The textures may be imported as packed data (the default) or to a directory on disk. - Extended the USD material import logic to handle package-relative texture assets paths by invoking the USD asset resolver to copy the textures from the USDZ archive to a directory on disk. When importing in Packed mode, the textures are first saved to Blender's temporary session directory prior to packing. The new USD import options are - Import Textures: Behavior when importing textures from a USDZ archive - Textures Directory: Path to the directory where imported textures will be copied - File Name Collision: Behavior when the name of an imported texture file conflicts with an existing file Import Textures menu options: - None: Don't import textures - Packed: Import textures as packed data (the default) - Copy: Copy files to Textures Directory File Name Collision menu options: - Use Existing: If a file with the same name already exists, use that instead of copying (the default) - Overwrite: Overwrite existing files Reviewed by: Bastien Differential Revision: https://developer.blender.org/D17074 --- release/scripts/startup/bl_ui/space_topbar.py | 2 +- source/blender/blenkernel/intern/cachefile.c | 2 +- source/blender/editors/io/io_usd.c | 62 ++++ source/blender/editors/space_file/filelist.cc | 2 +- source/blender/io/usd/CMakeLists.txt | 2 + .../blender/io/usd/intern/usd_asset_utils.cc | 301 ++++++++++++++++++ .../blender/io/usd/intern/usd_asset_utils.h | 57 ++++ .../io/usd/intern/usd_reader_material.cc | 54 +++- source/blender/io/usd/usd.h | 18 ++ 9 files changed, 492 insertions(+), 8 deletions(-) create mode 100644 source/blender/io/usd/intern/usd_asset_utils.cc create mode 100644 source/blender/io/usd/intern/usd_asset_utils.h diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 97f8a1bfad1..50bb1e42602 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -468,7 +468,7 @@ class TOPBAR_MT_file_import(Menu): self.layout.operator("wm.alembic_import", text="Alembic (.abc)") if bpy.app.build_options.usd: self.layout.operator( - "wm.usd_import", text="Universal Scene Description (.usd, .usdc, .usda)") + "wm.usd_import", text="Universal Scene Description (.usd*)") if bpy.app.build_options.io_gpencil: self.layout.operator("wm.gpencil_import_svg", text="SVG as Grease Pencil") diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c index 5d19db323f8..5968a6b7296 100644 --- a/source/blender/blenkernel/intern/cachefile.c +++ b/source/blender/blenkernel/intern/cachefile.c @@ -366,7 +366,7 @@ void BKE_cachefile_eval(Main *bmain, Depsgraph *depsgraph, CacheFile *cache_file } #endif #ifdef WITH_USD - if (BLI_path_extension_check_glob(filepath, "*.usd;*.usda;*.usdc")) { + if (BLI_path_extension_check_glob(filepath, "*.usd;*.usda;*.usdc;*.usdz")) { cache_file->type = CACHEFILE_TYPE_USD; cache_file->handle = USD_create_handle(bmain, filepath, &cache_file->object_paths); BLI_strncpy(cache_file->handle_filepath, filepath, FILE_MAX); diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c index 99d4e84cfd4..e6426732584 100644 --- a/source/blender/editors/io/io_usd.c +++ b/source/blender/editors/io/io_usd.c @@ -72,6 +72,23 @@ const EnumPropertyItem rna_enum_usd_mtl_name_collision_mode_items[] = { {0, NULL, 0, NULL, NULL}, }; +const EnumPropertyItem rna_enum_usd_tex_import_mode_items[] = { + {USD_TEX_IMPORT_NONE, "IMPORT_NONE", 0, "None", "Don't import textures"}, + {USD_TEX_IMPORT_PACK, "IMPORT_PACK", 0, "Packed", "Import textures as packed data"}, + {USD_TEX_IMPORT_COPY, "IMPORT_COPY", 0, "Copy", "Copy files to Textures Directory"}, + {0, NULL, 0, NULL, NULL}, +}; + +const EnumPropertyItem rna_enum_usd_tex_name_collision_mode_items[] = { + {USD_TEX_NAME_COLLISION_USE_EXISTING, + "USE_EXISTING", + 0, + "Use Existing", + "If a file with the same name already exists, use that instead of copying"}, + {USD_TEX_NAME_COLLISION_OVERWRITE, "OVERWRITE", 0, "Overwrite", "Overwrite existing files"}, + {0, NULL, 0, NULL, NULL}, +}; + /* Stored in the wmOperator's customdata field to indicate it should run as a background job. * This is set when the operator is invoked, and not set when it is only executed. */ enum { AS_BACKGROUND_JOB = 1 }; @@ -405,6 +422,14 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op) const bool validate_meshes = false; const bool use_instancing = false; + const eUSDTexImportMode import_textures_mode = RNA_enum_get(op->ptr, "import_textures_mode"); + + char import_textures_dir[FILE_MAXDIR]; + RNA_string_get(op->ptr, "import_textures_dir", import_textures_dir); + + const eUSDTexNameCollisionMode tex_name_collision_mode = RNA_enum_get(op->ptr, + "tex_name_collision_mode"); + struct USDImportParams params = {.scale = scale, .is_sequence = is_sequence, .set_frame_range = set_frame_range, @@ -430,9 +455,12 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op) .set_material_blend = set_material_blend, .light_intensity_scale = light_intensity_scale, .mtl_name_collision_mode = mtl_name_collision_mode, + .import_textures_mode = import_textures_mode, + .tex_name_collision_mode = tex_name_collision_mode, .import_all_materials = import_all_materials}; STRNCPY(params.prim_path_mask, prim_path_mask); + STRNCPY(params.import_textures_dir, import_textures_dir); const bool ok = USD_import(C, filename, ¶ms, as_background_job); @@ -490,6 +518,18 @@ static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op) uiItemR(row, ptr, "set_material_blend", 0, NULL, ICON_NONE); uiLayoutSetEnabled(row, RNA_boolean_get(ptr, "import_usd_preview")); uiItemR(col, ptr, "mtl_name_collision_mode", 0, NULL, ICON_NONE); + + box = uiLayoutBox(layout); + col = uiLayoutColumn(box, true); + uiItemR(col, ptr, "import_textures_mode", 0, NULL, ICON_NONE); + bool copy_textures = RNA_enum_get(op->ptr, "import_textures_mode") == USD_TEX_IMPORT_COPY; + row = uiLayoutRow(col, true); + uiItemR(row, ptr, "import_textures_dir", 0, NULL, ICON_NONE); + uiLayoutSetEnabled(row, copy_textures); + row = uiLayoutRow(col, true); + uiItemR(row, ptr, "tex_name_collision_mode", 0, NULL, ICON_NONE); + uiLayoutSetEnabled(row, copy_textures); + uiLayoutSetEnabled(col, RNA_boolean_get(ptr, "import_materials")); } void WM_OT_usd_import(struct wmOperatorType *ot) @@ -622,6 +662,28 @@ void WM_OT_usd_import(struct wmOperatorType *ot) USD_MTL_NAME_COLLISION_MAKE_UNIQUE, "Material Name Collision", "Behavior when the name of an imported material conflicts with an existing material"); + + RNA_def_enum(ot->srna, + "import_textures_mode", + rna_enum_usd_tex_import_mode_items, + USD_TEX_IMPORT_PACK, + "Import Textures", + "Behavior when importing textures from a USDZ archive"); + + RNA_def_string(ot->srna, + "import_textures_dir", + "//textures/", + FILE_MAXDIR, + "Textures Directory", + "Path to the directory where imported textures will be copied "); + + RNA_def_enum( + ot->srna, + "tex_name_collision_mode", + rna_enum_usd_tex_name_collision_mode_items, + USD_TEX_NAME_COLLISION_USE_EXISTING, + "File Name Collision", + "Behavior when the name of an imported texture file conflicts with an existing file"); } #endif /* WITH_USD */ diff --git a/source/blender/editors/space_file/filelist.cc b/source/blender/editors/space_file/filelist.cc index 57a4c5c052a..73de74ddaf6 100644 --- a/source/blender/editors/space_file/filelist.cc +++ b/source/blender/editors/space_file/filelist.cc @@ -2667,7 +2667,7 @@ int ED_path_extension_type(const char *path) if (BLI_path_extension_check(path, ".abc")) { return FILE_TYPE_ALEMBIC; } - if (BLI_path_extension_check_n(path, ".usd", ".usda", ".usdc", nullptr)) { + if (BLI_path_extension_check_n(path, ".usd", ".usda", ".usdc", ".usdz", nullptr)) { return FILE_TYPE_USD; } if (BLI_path_extension_check(path, ".vdb")) { diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt index 862bd41c087..b123eb251ab 100644 --- a/source/blender/io/usd/CMakeLists.txt +++ b/source/blender/io/usd/CMakeLists.txt @@ -60,6 +60,7 @@ set(INC_SYS ) set(SRC + intern/usd_asset_utils.cc intern/usd_capi_export.cc intern/usd_capi_import.cc intern/usd_common.cc @@ -88,6 +89,7 @@ set(SRC usd.h + intern/usd_asset_utils.h intern/usd_common.h intern/usd_exporter_context.h intern/usd_hierarchy_iterator.h diff --git a/source/blender/io/usd/intern/usd_asset_utils.cc b/source/blender/io/usd/intern/usd_asset_utils.cc new file mode 100644 index 00000000000..550d318cd94 --- /dev/null +++ b/source/blender/io/usd/intern/usd_asset_utils.cc @@ -0,0 +1,301 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 NVIDIA Corportation. All rights reserved. */ + +#include "usd_asset_utils.h" + +#include +#include +#include +#include + +#include "BKE_main.h" + +#include "BLI_fileops.h" +#include "BLI_path_util.h" +#include "BLI_string.h" + +#include "WM_api.h" +#include "WM_types.h" + +static const char UDIM_PATTERN[] = ""; +static const char UDIM_PATTERN2[] = "%3CUDIM%3E"; + +/* Maximum range of UDIM tiles, per the + * UsdPreviewSurface specifications. See + * https://graphics.pixar.com/usd/release/spec_usdpreviewsurface.html#texture-reader + */ +static const int UDIM_START_TILE = 1001; +static const int UDIM_END_TILE = 1100; + +namespace blender::io::usd { + +/* The following is copied from _SplitUdimPattern() in + * USD library source file materialParamsUtils.cpp. + * Split a udim file path such as /someDir/myFile..exr into a + * prefix (/someDir/myFile.) and suffix (.exr). */ +static std::pair split_udim_pattern(const std::string &path) +{ + static const std::vector patterns = {UDIM_PATTERN, UDIM_PATTERN2}; + + for (const std::string &pattern : patterns) { + const std::string::size_type pos = path.find(pattern); + if (pos != std::string::npos) { + return {path.substr(0, pos), path.substr(pos + pattern.size())}; + } + } + + return {std::string(), std::string()}; +} + +/* Return the asset file base name, with special handling of + * package relative paths. */ +static std::string get_asset_base_name(const char *src_path) +{ + char base_name[FILE_MAXFILE]; + + if (pxr::ArIsPackageRelativePath(src_path)) { + std::pair split = pxr::ArSplitPackageRelativePathInner(src_path); + if (split.second.empty()) { + WM_reportf(RPT_WARNING, + "%s: Couldn't determine package-relative file name from path %s", + __func__, + src_path); + return src_path; + } + BLI_split_file_part(split.second.c_str(), base_name, sizeof(base_name)); + } + else { + BLI_split_file_part(src_path, base_name, sizeof(base_name)); + } + + return base_name; +} + +/* Copy an asset to a destination directory. */ +static std::string copy_asset_to_directory(const char *src_path, + const char *dest_dir_path, + eUSDTexNameCollisionMode name_collision_mode) +{ + std::string base_name = get_asset_base_name(src_path); + + char dest_file_path[FILE_MAX]; + BLI_path_join(dest_file_path, sizeof(dest_file_path), dest_dir_path, base_name.c_str()); + BLI_path_normalize(NULL, dest_file_path); + + if (name_collision_mode == USD_TEX_NAME_COLLISION_USE_EXISTING && BLI_is_file(dest_file_path)) { + return dest_file_path; + } + + if (!copy_asset(src_path, dest_file_path, name_collision_mode)) { + WM_reportf( + RPT_WARNING, "%s: Couldn't copy file %s to %s.", __func__, src_path, dest_file_path); + return src_path; + } + + return dest_file_path; +} + +static std::string copy_udim_asset_to_directory(const char *src_path, + const char *dest_dir_path, + eUSDTexNameCollisionMode name_collision_mode) +{ + /* Get prefix and suffix from udim pattern. */ + std::pair splitPath = split_udim_pattern(src_path); + if (splitPath.first.empty() || splitPath.second.empty()) { + WM_reportf(RPT_ERROR, "%s: Couldn't split UDIM pattern %s", __func__, src_path); + return src_path; + } + + /* Copy the individual UDIM tiles. Since there is currently no way to query the contents + * of a directory using the USD resolver, we must take a brute force approach. We iterate + * over the allowed range of tile indices and copy any tiles that exist. The USDPreviewSurface + * specification stipulates "a maximum of ten tiles in the U direction" and that + * "the tiles must be within the range [1001, 1099]". See + * https://graphics.pixar.com/usd/release/spec_usdpreviewsurface.html#texture-reader + */ + for (int i = UDIM_START_TILE; i < UDIM_END_TILE; ++i) { + const std::string src_udim = splitPath.first + std::to_string(i) + splitPath.second; + if (asset_exists(src_udim.c_str())) { + copy_asset_to_directory(src_udim.c_str(), dest_dir_path, name_collision_mode); + } + } + + const std::string src_file_name = get_asset_base_name(src_path); + char ret_udim_path[FILE_MAX]; + BLI_path_join(ret_udim_path, sizeof(ret_udim_path), dest_dir_path, src_file_name.c_str()); + + /* Blender only recognizes the pattern, not the + * alternative UDIM_PATTERN2, so we make sure the returned + * path has the former. */ + splitPath = split_udim_pattern(ret_udim_path); + if (splitPath.first.empty() || splitPath.second.empty()) { + WM_reportf(RPT_ERROR, "%s: Couldn't split UDIM pattern %s", __func__, ret_udim_path); + return ret_udim_path; + } + + return splitPath.first + UDIM_PATTERN + splitPath.second; +} + +bool copy_asset(const char *src, const char *dst, eUSDTexNameCollisionMode name_collision_mode) +{ + if (!(src && dst)) { + return false; + } + + pxr::ArResolver &ar = pxr::ArGetResolver(); + + if (name_collision_mode != USD_TEX_NAME_COLLISION_OVERWRITE) { + if (!ar.Resolve(dst).IsEmpty()) { + /* The asset exists, so this is a no-op. */ + WM_reportf(RPT_INFO, "%s: Will not overwrite existing asset %s", __func__, dst); + return true; + } + } + + pxr::ArResolvedPath src_path = ar.Resolve(src); + + if (src_path.IsEmpty()) { + WM_reportf(RPT_ERROR, "%s: Can't resolve path %s", __func__, src); + return false; + } + + pxr::ArResolvedPath dst_path = ar.ResolveForNewAsset(dst); + + if (dst_path.IsEmpty()) { + WM_reportf(RPT_ERROR, "%s: Can't resolve path %s for writing", __func__, dst); + return false; + } + + if (src_path == dst_path) { + WM_reportf(RPT_ERROR, + "%s: Can't copy %s. The source and destination paths are the same", + __func__, + src_path.GetPathString().c_str()); + return false; + } + + std::string why_not; + if (!ar.CanWriteAssetToPath(dst_path, &why_not)) { + WM_reportf(RPT_ERROR, + "%s: Can't write to asset %s. %s.", + __func__, + dst_path.GetPathString().c_str(), + why_not.c_str()); + return false; + } + + std::shared_ptr src_asset = ar.OpenAsset(src_path); + if (!src_asset) { + WM_reportf( + RPT_ERROR, "%s: Can't open source asset %s", __func__, src_path.GetPathString().c_str()); + return false; + } + + const size_t size = src_asset->GetSize(); + + if (size == 0) { + WM_reportf(RPT_WARNING, + "%s: Will not copy zero size source asset %s", + __func__, + src_path.GetPathString().c_str()); + return false; + } + + std::shared_ptr buf = src_asset->GetBuffer(); + + if (!buf) { + WM_reportf(RPT_ERROR, + "%s: Null buffer for source asset %s", + __func__, + src_path.GetPathString().c_str()); + return false; + } + + std::shared_ptr dst_asset = ar.OpenAssetForWrite( + dst_path, pxr::ArResolver::WriteMode::Replace); + if (!dst_asset) { + WM_reportf(RPT_ERROR, + "%s: Can't open destination asset %s for writing", + __func__, + src_path.GetPathString().c_str()); + return false; + } + + size_t bytes_written = dst_asset->Write(src_asset->GetBuffer().get(), src_asset->GetSize(), 0); + + if (bytes_written == 0) { + WM_reportf(RPT_ERROR, + "%s: Error writing to destination asset %s", + __func__, + dst_path.GetPathString().c_str()); + } + + if (!dst_asset->Close()) { + WM_reportf(RPT_ERROR, + "%s: Couldn't close destination asset %s", + __func__, + dst_path.GetPathString().c_str()); + return false; + } + + return bytes_written > 0; +} + +bool asset_exists(const char *path) +{ + return path && !pxr::ArGetResolver().Resolve(path).IsEmpty(); +} + +std::string import_asset(const char *src, + const char *import_dir, + eUSDTexNameCollisionMode name_collision_mode) +{ + if (import_dir[0] == '\0') { + WM_reportf( + RPT_ERROR, "%s: Texture import directory path empty, couldn't import %s", __func__, src); + return src; + } + + char dest_dir_path[FILE_MAXDIR]; + STRNCPY(dest_dir_path, import_dir); + + const char *basepath = nullptr; + + if (BLI_path_is_rel(import_dir)) { + basepath = BKE_main_blendfile_path_from_global(); + + if (!basepath || basepath[0] == '\0') { + WM_reportf(RPT_ERROR, + "%s: import directory is relative " + "but the blend file path is empty. " + "Please save the blend file before importing the USD " + "or provide an absolute import directory path. " + "Can't import %s", + __func__, + src); + return src; + } + } + + BLI_path_normalize(basepath, dest_dir_path); + + if (!BLI_dir_create_recursive(dest_dir_path)) { + WM_reportf( + RPT_ERROR, "%s: Couldn't create texture import directory %s", __func__, dest_dir_path); + return src; + } + + if (is_udim_path(src)) { + return copy_udim_asset_to_directory(src, dest_dir_path, name_collision_mode); + } + + return copy_asset_to_directory(src, dest_dir_path, name_collision_mode); +} + +bool is_udim_path(const std::string &path) +{ + return path.find(UDIM_PATTERN) != std::string::npos || + path.find(UDIM_PATTERN2) != std::string::npos; +} + +} // namespace blender::io::usd diff --git a/source/blender/io/usd/intern/usd_asset_utils.h b/source/blender/io/usd/intern/usd_asset_utils.h new file mode 100644 index 00000000000..be4e95fba42 --- /dev/null +++ b/source/blender/io/usd/intern/usd_asset_utils.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later + * Copyright 2023 NVIDIA Corporation. All rights reserved. */ +#pragma once + +#include "usd.h" + +#include + +#include + +namespace blender::io::usd { + +/** + * Invoke the USD asset resolver to copy an asset. + * + * \param src: source path of the asset to copy + * \param dst: destination path of the copy + * \param name_collision_mode: behavior when `dst` already exists + * \return true if the copy succeeded, false otherwise + */ +bool copy_asset(const char *src, const char *dst, eUSDTexNameCollisionMode name_collision_mode); + +/** + * Invoke the USD asset resolver to determine if the + * asset with the given path exists. + * + * \param path: the path to resolve + * \return true if the asset exists, false otherwise + */ +bool asset_exists(const char *path); + +/** + * Invoke the USD asset resolver to copy an asset to a destination + * directory and return the path to the copied file. This function may + * be used to copy textures from a USDZ archive to a directory on disk. + * The destination directory will be created if it doesn't already exist. + * If the copy was unsuccessful, this function will log an error and + * return the original source file path unmodified. + * + * \param src: source path of the asset to import + * \param import_dir: path to the destination directory + * \param name_collision_mode: behavior when a file of the same name already exists + * \return path to copied file or the original `src` path if there was an error + */ +std::string import_asset(const char *src, + const char *import_dir, + eUSDTexNameCollisionMode name_collision_mode); + +/** + * Check if the given path contains a UDIM token. + * + * \param path: the path to check + * \return true if the path contains a UDIM token, false otherwise + */ +bool is_udim_path(const std::string &path); + +} // namespace blender::io::usd diff --git a/source/blender/io/usd/intern/usd_reader_material.cc b/source/blender/io/usd/intern/usd_reader_material.cc index 351f9bc3438..2c50f852a48 100644 --- a/source/blender/io/usd/intern/usd_reader_material.cc +++ b/source/blender/io/usd/intern/usd_reader_material.cc @@ -3,6 +3,9 @@ #include "usd_reader_material.h" +#include "usd_asset_utils.h" + +#include "BKE_appdir.h" #include "BKE_image.h" #include "BKE_lib_id.h" #include "BKE_main.h" @@ -19,6 +22,7 @@ #include "DNA_material_types.h" #include +#include #include #include @@ -63,6 +67,23 @@ static const pxr::TfToken UsdPrimvarReader_float2("UsdPrimvarReader_float2", static const pxr::TfToken UsdUVTexture("UsdUVTexture", pxr::TfToken::Immortal); } // namespace usdtokens +/* Temporary folder for saving imported textures prior to packing. + * CAUTION: this directory is recursively deleted after material + * import. */ +static const char *temp_textures_dir() +{ + static bool inited = false; + + static char temp_dir[FILE_MAXDIR] = {'\0'}; + + if (!inited) { + BLI_path_join(temp_dir, sizeof(temp_dir), BKE_tempdir_session(), "usd_textures_tmp", SEP_STR); + inited = true; + } + + return temp_dir; +} + /* Add a node of the given type at the given location coordinates. */ static bNode *add_node( const bContext *C, bNodeTree *ntree, const int type, const float locx, const float locy) @@ -112,11 +133,6 @@ static pxr::SdfLayerHandle get_layer_handle(const pxr::UsdAttribute &attribute) return pxr::SdfLayerHandle(); } -static bool is_udim_path(const std::string &path) -{ - return path.find("") != std::string::npos; -} - /* For the given UDIM path (assumed to contain the UDIM token), returns an array * containing valid tile indices. */ static blender::Vector get_udim_tiles(const std::string &file_path) @@ -676,6 +692,26 @@ void USDMaterialReader::load_tex_image(const pxr::UsdShadeShader &usd_shader, return; } + /* Optionally copy the asset if it's inside a USDZ package. */ + + const bool import_textures = params_.import_textures_mode != USD_TEX_IMPORT_NONE && + pxr::ArIsPackageRelativePath(file_path); + + if (import_textures) { + /* If we are packing the imported textures, we first write them + * to a temporary directory. */ + const char *textures_dir = params_.import_textures_mode == USD_TEX_IMPORT_PACK ? + temp_textures_dir() : + params_.import_textures_dir; + + const eUSDTexNameCollisionMode name_collision_mode = params_.import_textures_mode == + USD_TEX_IMPORT_PACK ? + USD_TEX_NAME_COLLISION_OVERWRITE : + params_.tex_name_collision_mode; + + file_path = import_asset(file_path.c_str(), textures_dir, name_collision_mode); + } + /* If this is a UDIM texture, this will store the * UDIM tile indices. */ blender::Vector udim_tiles; @@ -712,6 +748,14 @@ void USDMaterialReader::load_tex_image(const pxr::UsdShadeShader &usd_shader, if (ELEM(color_space, usdtokens::RAW, usdtokens::raw)) { STRNCPY(image->colorspace_settings.name, "Raw"); } + + if (import_textures && params_.import_textures_mode == USD_TEX_IMPORT_PACK && + !BKE_image_has_packedfile(image)) { + BKE_image_packfiles(nullptr, image, ID_BLEND_PATH(bmain_, &image->id)); + if (BLI_is_dir(temp_textures_dir())) { + BLI_delete(temp_textures_dir(), true, true); + } + } } void USDMaterialReader::convert_usd_primvar_reader_float2( diff --git a/source/blender/io/usd/usd.h b/source/blender/io/usd/usd.h index ffd3bd6df4c..36ad857c57e 100644 --- a/source/blender/io/usd/usd.h +++ b/source/blender/io/usd/usd.h @@ -21,6 +21,21 @@ typedef enum eUSDMtlNameCollisionMode { USD_MTL_NAME_COLLISION_REFERENCE_EXISTING = 1, } eUSDMtlNameCollisionMode; +/* Behavior when importing textures from a package + * (e.g., USDZ archive) or from a URI path. */ +typedef enum eUSDTexImportMode { + USD_TEX_IMPORT_NONE = 0, + USD_TEX_IMPORT_PACK, + USD_TEX_IMPORT_COPY, +} eUSDTexImportMode; + +/* Behavior when the name of an imported texture + * file conflicts with an existing file. */ +typedef enum eUSDTexNameCollisionMode { + USD_TEX_NAME_COLLISION_USE_EXISTING = 0, + USD_TEX_NAME_COLLISION_OVERWRITE = 1, +} eUSDTexNameCollisionMode; + struct USDExportParams { bool export_animation; bool export_hair; @@ -64,6 +79,9 @@ struct USDImportParams { bool set_material_blend; float light_intensity_scale; eUSDMtlNameCollisionMode mtl_name_collision_mode; + eUSDTexImportMode import_textures_mode; + char import_textures_dir[768]; /* FILE_MAXDIR */ + eUSDTexNameCollisionMode tex_name_collision_mode; bool import_all_materials; }; From 3e903909187002d40e122993597793ca3c7afa28 Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Thu, 26 Jan 2023 16:55:03 -0800 Subject: [PATCH 0969/1522] Sculpt: Resolve `Shift R` shortcut conflicts Based on T99607: - Existing Angle Control shortcuts are removed - Voxel, Dyntopo and Hair resolution shortcuts are remapped to `R` Since voxel remeshing is not compatible with dyntopo, each can use the shortcut `R` for the remeshing resolution without causing a conflict. The shortcut `R` is not currently used for anything important. The angle control menu is commonly not used. And sculpt mode is only coincidentally inheriting the rotate operator shortcut on `R` because nothing else is mapped to the key. Reviewed By: Julien Kaspar and Hans Goudey and Joseph Eagar Differential Revision: https://developer.blender.org/D16511 Ref D16511 --- release/scripts/addons | 2 +- .../keyconfig/keymap_data/blender_default.py | 9 ++--- .../keymap_data/industry_compatible_data.py | 2 -- release/scripts/startup/bl_ui/space_view3d.py | 35 ------------------- 4 files changed, 4 insertions(+), 44 deletions(-) diff --git a/release/scripts/addons b/release/scripts/addons index 9958ddb8799..d887a4ea6b2 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 9958ddb879934718cc2b379b556f0bc3b861bee5 +Subproject commit d887a4ea6b2a9d64b926034d4e78ecf7a48ca979 diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 8f659449315..ec89b61d47c 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -4913,7 +4913,6 @@ def km_image_paint(params): {"properties": [("data_path", 'image_paint_object.data.use_paint_mask')]}), ("wm.context_toggle", {"type": 'S', "value": 'PRESS', "shift": True}, {"properties": [("data_path", 'tool_settings.image_paint.brush.use_smooth_stroke')]}), - op_menu("VIEW3D_MT_angle_control", {"type": 'R', "value": 'PRESS'}), ("wm.context_menu_enum", {"type": 'E', "value": 'PRESS'}, {"properties": [("data_path", 'tool_settings.image_paint.brush.stroke_method')]}), *_template_items_context_panel("VIEW3D_PT_paint_texture_context_menu", params.context_menu_event), @@ -4962,7 +4961,6 @@ def km_vertex_paint(params): {"properties": [("data_path", 'vertex_paint_object.data.use_paint_mask')]}), ("wm.context_toggle", {"type": 'S', "value": 'PRESS', "shift": True}, {"properties": [("data_path", 'tool_settings.vertex_paint.brush.use_smooth_stroke')]}), - op_menu("VIEW3D_MT_angle_control", {"type": 'R', "value": 'PRESS'}), ("wm.context_menu_enum", {"type": 'E', "value": 'PRESS'}, {"properties": [("data_path", 'tool_settings.vertex_paint.brush.stroke_method')]}), ("paint.face_vert_reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None), @@ -5108,11 +5106,11 @@ def km_sculpt(params): {"properties": [("data_path", 'scene.tool_settings.sculpt.show_mask')]}), # Dynamic topology ("sculpt.dynamic_topology_toggle", {"type": 'D', "value": 'PRESS', "ctrl": True}, None), - ("sculpt.dyntopo_detail_size_edit", {"type": 'D', "value": 'PRESS', "shift": True}, None), + ("sculpt.dyntopo_detail_size_edit", {"type": 'R', "value": 'PRESS'}, None), ("sculpt.set_detail_size", {"type": 'D', "value": 'PRESS', "shift": True, "alt": True}, None), # Remesh ("object.voxel_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True}, None), - ("object.voxel_size_edit", {"type": 'R', "value": 'PRESS', "shift": True}, None), + ("object.voxel_size_edit", {"type": 'R', "value": 'PRESS'}, None), ("object.quadriflow_remesh", {"type": 'R', "value": 'PRESS', "ctrl": True, "alt": True}, None), # Color ("sculpt.sample_color", {"type": 'S', "value": 'PRESS'}, None), @@ -5163,7 +5161,6 @@ def km_sculpt(params): {"properties": [("data_path", 'tool_settings.sculpt.brush.stroke_method')]}), ("wm.context_toggle", {"type": 'S', "value": 'PRESS', "shift": True}, {"properties": [("data_path", 'tool_settings.sculpt.brush.use_smooth_stroke')]}), - op_menu("VIEW3D_MT_angle_control", {"type": 'R', "value": 'PRESS'}), op_menu_pie("VIEW3D_MT_sculpt_mask_edit_pie", {"type": 'A', "value": 'PRESS'}), op_menu_pie("VIEW3D_MT_sculpt_automasking_pie", {"type": 'A', "alt": True, "value": 'PRESS'}), op_menu_pie("VIEW3D_MT_sculpt_face_sets_edit_pie", {"type": 'W', "value": 'PRESS'}), @@ -5643,7 +5640,7 @@ def km_sculpt_curves(params): ("curves.set_selection_domain", {"type": 'TWO', "value": 'PRESS'}, {"properties": [("domain", 'CURVE')]}), *_template_paint_radial_control("curves_sculpt"), *_template_items_select_actions(params, "curves.select_all"), - ("sculpt_curves.min_distance_edit", {"type": 'R', "value": 'PRESS', "shift": True}, {}), + ("sculpt_curves.min_distance_edit", {"type": 'R', "value": 'PRESS'}, {}), ("sculpt_curves.select_grow", {"type": 'A', "value": 'PRESS', "shift": True}, {}), ]) diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py index 2f15d908364..0464f5dc317 100644 --- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py +++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py @@ -3281,7 +3281,6 @@ def km_image_paint(params): {"properties": [("data_path", 'image_paint_object.data.use_paint_mask')]}), ("wm.context_toggle", {"type": 'S', "value": 'PRESS', "shift": True}, {"properties": [("data_path", 'tool_settings.image_paint.brush.use_smooth_stroke')]}), - op_menu("VIEW3D_MT_angle_control", {"type": 'R', "value": 'PRESS'}), *_template_items_context_panel("VIEW3D_PT_paint_texture_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), # Tools @@ -3332,7 +3331,6 @@ def km_vertex_paint(params): {"properties": [("data_path", 'vertex_paint_object.data.use_paint_mask')]}), ("wm.context_toggle", {"type": 'S', "value": 'PRESS', "shift": True}, {"properties": [("data_path", 'tool_settings.vertex_paint.brush.use_smooth_stroke')]}), - op_menu("VIEW3D_MT_angle_control", {"type": 'R', "value": 'PRESS'}), ("paint.face_vert_reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None), *_template_items_context_panel("VIEW3D_PT_paint_vertex_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}), # Tools diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 2f5b70bb3da..c66acb0509f 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2067,40 +2067,6 @@ class VIEW3D_MT_select_sculpt_curves(Menu): layout.operator("sculpt_curves.select_grow", text="Grow") -class VIEW3D_MT_angle_control(Menu): - bl_label = "Angle Control" - - @classmethod - def poll(cls, context): - settings = UnifiedPaintPanel.paint_settings(context) - if not settings: - return False - - brush = settings.brush - tex_slot = brush.texture_slot - - return tex_slot.has_texture_angle and tex_slot.has_texture_angle_source - - def draw(self, context): - layout = self.layout - - settings = UnifiedPaintPanel.paint_settings(context) - brush = settings.brush - - sculpt = (context.sculpt_object is not None) - - tex_slot = brush.texture_slot - - layout.prop(tex_slot, "use_rake", text="Rake") - - if brush.brush_capabilities.has_random_texture_angle and tex_slot.has_random_texture_angle: - if sculpt: - if brush.sculpt_capabilities.has_random_texture_angle: - layout.prop(tex_slot, "use_random", text="Random") - else: - layout.prop(tex_slot, "use_random", text="Random") - - class VIEW3D_MT_mesh_add(Menu): bl_idname = "VIEW3D_MT_mesh_add" bl_label = "Mesh" @@ -8041,7 +8007,6 @@ classes = ( VIEW3D_MT_select_paint_mask_vertex, VIEW3D_MT_select_edit_curves, VIEW3D_MT_select_sculpt_curves, - VIEW3D_MT_angle_control, VIEW3D_MT_mesh_add, VIEW3D_MT_curve_add, VIEW3D_MT_surface_add, From 647cffc0016374088dcd8decbc065d7799028939 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 26 Jan 2023 16:57:28 -0800 Subject: [PATCH 0970/1522] Sculpt: Add numpad aliases for number keymap entries in expand modal map --- .../scripts/presets/keyconfig/keymap_data/blender_default.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index ec89b61d47c..9f25d421c9d 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -6281,6 +6281,8 @@ def km_sculpt_expand_modal(_params): ("MOVE_TOGGLE", {"type": 'SPACE', "value": 'ANY', "any": True}, None), *((e, {"type": NUMBERS_1[i], "value": 'PRESS', "any": True}, None) for i, e in enumerate( ("FALLOFF_GEODESICS", "FALLOFF_TOPOLOGY", "FALLOFF_TOPOLOGY_DIAGONALS", "FALLOFF_SPHERICAL"))), + *((e, {"type": "NUMPAD_%i" % (i+1), "value": 'PRESS', "any": True}, None) for i, e in enumerate( + ("FALLOFF_GEODESICS", "FALLOFF_TOPOLOGY", "FALLOFF_TOPOLOGY_DIAGONALS", "FALLOFF_SPHERICAL"))), ("SNAP_TOGGLE", {"type": 'LEFT_CTRL', "value": 'ANY'}, None), ("SNAP_TOGGLE", {"type": 'RIGHT_CTRL', "value": 'ANY'}, None), ("LOOP_COUNT_INCREASE", {"type": 'W', "value": 'PRESS', "any": True, "repeat": True}, None), From e735bf02cb5d73f7ab96f6ef4032ab758d890b60 Mon Sep 17 00:00:00 2001 From: Michael Kowalski Date: Thu, 26 Jan 2023 20:16:07 -0500 Subject: [PATCH 0971/1522] Fix linux/mac compiler warning. --- source/blender/io/usd/intern/usd_reader_stage.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/io/usd/intern/usd_reader_stage.cc b/source/blender/io/usd/intern/usd_reader_stage.cc index 0c179ceae48..3ee5e666d38 100644 --- a/source/blender/io/usd/intern/usd_reader_stage.cc +++ b/source/blender/io/usd/intern/usd_reader_stage.cc @@ -355,7 +355,7 @@ void USDStageReader::fake_users_for_unused_materials() { /* Iterate over the imported materials and set a fake user for any unused * materials. */ - for (const std::pair &path_mat_pair : settings_.usd_path_to_mat_name) { + for (const std::pair &path_mat_pair : settings_.usd_path_to_mat_name) { std::map::iterator mat_it = settings_.mat_name_to_mat.find( path_mat_pair.second); From 742c2e46bb1eee2d874b137e973658db57683f78 Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Fri, 27 Jan 2023 14:45:37 +1300 Subject: [PATCH 0972/1522] Cleanup: format --- source/blender/io/usd/intern/usd_reader_stage.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/blender/io/usd/intern/usd_reader_stage.cc b/source/blender/io/usd/intern/usd_reader_stage.cc index 3ee5e666d38..393d8acba4a 100644 --- a/source/blender/io/usd/intern/usd_reader_stage.cc +++ b/source/blender/io/usd/intern/usd_reader_stage.cc @@ -355,7 +355,8 @@ void USDStageReader::fake_users_for_unused_materials() { /* Iterate over the imported materials and set a fake user for any unused * materials. */ - for (const std::pair &path_mat_pair : settings_.usd_path_to_mat_name) { + for (const std::pair &path_mat_pair : + settings_.usd_path_to_mat_name) { std::map::iterator mat_it = settings_.mat_name_to_mat.find( path_mat_pair.second); From d76004f48f46164a73b107a11f115d3c45e312ad Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Thu, 26 Jan 2023 17:53:32 -0800 Subject: [PATCH 0973/1522] Sculpt: Fix sculpt expand not switching falloff types properly --- .../blender/editors/sculpt_paint/sculpt_expand.cc | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.cc b/source/blender/editors/sculpt_paint/sculpt_expand.cc index a125545c010..b6a71a69287 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.cc +++ b/source/blender/editors/sculpt_paint/sculpt_expand.cc @@ -388,11 +388,11 @@ static BLI_bitmap *sculpt_expand_boundary_from_enabled(SculptSession *ss, return boundary_verts; } -static void sculpt_expand_check_topology_islands(Object *ob) +static void sculpt_expand_check_topology_islands(Object *ob, eSculptExpandFalloffType falloff_type) { SculptSession *ss = ob->sculpt; - ss->expand_cache->check_islands = ELEM(ss->expand_cache->falloff_type, + ss->expand_cache->check_islands = ELEM(falloff_type, SCULPT_EXPAND_FALLOFF_GEODESIC, SCULPT_EXPAND_FALLOFF_TOPOLOGY, SCULPT_EXPAND_FALLOFF_TOPOLOGY_DIAGONALS, @@ -1865,8 +1865,7 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event return OPERATOR_FINISHED; } case SCULPT_EXPAND_MODAL_FALLOFF_GEODESIC: { - expand_cache->falloff_gradient = true; - sculpt_expand_check_topology_islands(ob); + sculpt_expand_check_topology_islands(ob, SCULPT_EXPAND_FALLOFF_GEODESIC); sculpt_expand_falloff_factors_from_vertex_and_symm_create( expand_cache, @@ -1877,8 +1876,7 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event break; } case SCULPT_EXPAND_MODAL_FALLOFF_TOPOLOGY: { - expand_cache->falloff_gradient = SCULPT_EXPAND_FALLOFF_TOPOLOGY; - sculpt_expand_check_topology_islands(ob); + sculpt_expand_check_topology_islands(ob, SCULPT_EXPAND_FALLOFF_TOPOLOGY); sculpt_expand_falloff_factors_from_vertex_and_symm_create( expand_cache, @@ -1889,8 +1887,7 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event break; } case SCULPT_EXPAND_MODAL_FALLOFF_TOPOLOGY_DIAGONALS: { - expand_cache->falloff_gradient = true; - sculpt_expand_check_topology_islands(ob); + sculpt_expand_check_topology_islands(ob, SCULPT_EXPAND_FALLOFF_TOPOLOGY_DIAGONALS); sculpt_expand_falloff_factors_from_vertex_and_symm_create( expand_cache, @@ -2247,7 +2244,7 @@ static int sculpt_expand_invoke(bContext *C, wmOperator *op, const wmEvent *even sculpt_expand_falloff_factors_from_vertex_and_symm_create( ss->expand_cache, sd, ob, ss->expand_cache->initial_active_vertex, falloff_type); - sculpt_expand_check_topology_islands(ob); + sculpt_expand_check_topology_islands(ob, falloff_type); /* Initial mesh data update, resets all target data in the sculpt mesh. */ sculpt_expand_update_for_vertex(C, ob, ss->expand_cache->initial_active_vertex); From 34a6591a073f90620b6bcff458a407368b5dd02f Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Fri, 27 Jan 2023 16:38:12 +1300 Subject: [PATCH 0974/1522] Fix T98594: missing uv editor redraw with geometry nodes modifier If an object has a geometry nodes modifier, the UVs on that object might change in response to any change on any other object. Now we will redraw the UV editor on any object change, not just the active object. Differential Revision: https://developer.blender.org/D17124 --- source/blender/editors/space_image/space_image.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 53e1bc0a1e5..fd8c161687e 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -405,7 +405,10 @@ static void image_listener(const wmSpaceTypeListenerParams *params) ViewLayer *view_layer = WM_window_get_active_view_layer(win); BKE_view_layer_synced_ensure(scene, view_layer); Object *ob = BKE_view_layer_active_object_get(view_layer); - if (ob && (ob == wmn->reference) && (ob->mode & OB_MODE_EDIT)) { + /* \note With a geometry nodes modifier, the UVs on `ob` can change in response to + * any change on `wmn->reference`. If we could track the upstream dependencies, + * unnecessary redraws could be reduced. Until then, just redraw. See T98594. */ + if (ob && (ob->mode & OB_MODE_EDIT)) { if (sima->lock && (sima->flag & SI_DRAWSHADOW)) { ED_area_tag_refresh(area); ED_area_tag_redraw(area); From 6c8db7c22ba48c49df0de0ab655b79342d866281 Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Fri, 27 Jan 2023 17:05:15 +1300 Subject: [PATCH 0975/1522] Fix T103868: render uv transform gizmo even if it has zero area Change the 2D Gizmo drawing function to provide a usable transform matrix, if it would otherwise be degenerate. Differential Revision: https://developer.blender.org/D17113 --- source/blender/editors/transform/transform_gizmo_2d.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/transform/transform_gizmo_2d.c b/source/blender/editors/transform/transform_gizmo_2d.c index a6eb25975e9..b99a650c3c0 100644 --- a/source/blender/editors/transform/transform_gizmo_2d.c +++ b/source/blender/editors/transform/transform_gizmo_2d.c @@ -604,8 +604,11 @@ static void gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup) UI_view2d_view_to_region_m4(®ion->v2d, ggd->cage->matrix_space); /* Define the bounding box of the gizmo in the offset transform matrix. */ unit_m4(ggd->cage->matrix_offset); - ggd->cage->matrix_offset[0][0] = (ggd->max[0] - ggd->min[0]); - ggd->cage->matrix_offset[1][1] = (ggd->max[1] - ggd->min[1]); + const float min_gizmo_pixel_size = 0.001f; /* Draw Gizmo larger than this many pixels. */ + const float min_scale_axis_x = min_gizmo_pixel_size / ggd->cage->matrix_space[0][0]; + const float min_scale_axis_y = min_gizmo_pixel_size / ggd->cage->matrix_space[1][1]; + ggd->cage->matrix_offset[0][0] = max_ff(min_scale_axis_x, ggd->max[0] - ggd->min[0]); + ggd->cage->matrix_offset[1][1] = max_ff(min_scale_axis_y, ggd->max[1] - ggd->min[1]); ScrArea *area = CTX_wm_area(C); From 2b4bafeac68ea6fbb7b42760c9fc864d094d67f8 Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Fri, 27 Jan 2023 17:52:31 +1300 Subject: [PATCH 0976/1522] UV: add "similar object" and "similar winding" to uv "select similar" Adds new options to UV Face selection in the UV Editor, with UV > Select > Select Similar In multi object edit mode, "Similar Object" selects faces which have the same object. "Similar Winding" will select faces which have the same winding, i.e. are they facing upwards or downwards. Resolves: T103975 Differential Revision: https://developer.blender.org/D17125 --- source/blender/bmesh/intern/bmesh_polygon.c | 12 +++++++++--- source/blender/bmesh/intern/bmesh_polygon.h | 7 ++++++- source/blender/editors/uvedit/uvedit_select.c | 19 ++++++++++++++----- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index a2aecf80456..8b185b17a3a 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -225,20 +225,26 @@ float BM_face_calc_area_with_mat3(const BMFace *f, const float mat3[3][3]) return len_v3(n) * 0.5f; } -float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset) +float BM_face_calc_area_uv_signed(const BMFace *f, int cd_loop_uv_offset) { /* inline 'area_poly_v2' logic, avoid creating a temp array */ const BMLoop *l_iter, *l_first; l_iter = l_first = BM_FACE_FIRST_LOOP(f); - /* The Trapezium Area Rule */ + /* Green's theorem applied to area of a polygon. + * TODO: `cross` should be of type `double` to reduce rounding error. */ float cross = 0.0f; do { const float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset); const float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l_iter->next, cd_loop_uv_offset); cross += (luv_next[0] - luv[0]) * (luv_next[1] + luv[1]); } while ((l_iter = l_iter->next) != l_first); - return fabsf(cross * 0.5f); + return cross * 0.5f; +} + +float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset) +{ + return fabsf(BM_face_calc_area_uv_signed(f, cd_loop_uv_offset)); } float BM_face_calc_perimeter(const BMFace *f) diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index 6262f185eca..bff1d1d587d 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -73,7 +73,12 @@ float BM_face_calc_area(const BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); float BM_face_calc_area_with_mat3(const BMFace *f, const float mat3[3][3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); /** - * get the area of UV face + * Calculate the signed area of UV face. + */ +float BM_face_calc_area_uv_signed(const BMFace *f, int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT + ATTR_NONNULL(); +/** + * Calculate the area of UV face. */ float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index 50185049fe1..99ee1ca0002 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -87,9 +87,11 @@ typedef enum { UV_SSIM_FACE, UV_SSIM_LENGTH_UV, UV_SSIM_LENGTH_3D, - UV_SSIM_SIDES, - UV_SSIM_PIN, UV_SSIM_MATERIAL, + UV_SSIM_OBJECT, + UV_SSIM_PIN, + UV_SSIM_SIDES, + UV_SSIM_WINDING, } eUVSelectSimilar; /* -------------------------------------------------------------------- */ @@ -4633,6 +4635,7 @@ static float get_uv_edge_needle(const eUVSelectSimilar type, static float get_uv_face_needle(const eUVSelectSimilar type, BMFace *face, + int ob_index, const float ob_m3[3][3], const BMUVOffsets offsets) { @@ -4646,6 +4649,8 @@ static float get_uv_face_needle(const eUVSelectSimilar type, return BM_face_calc_area_with_mat3(face, ob_m3); case UV_SSIM_SIDES: return face->len; + case UV_SSIM_OBJECT: + return ob_index; case UV_SSIM_PIN: { BMLoop *l; BMIter liter; @@ -4657,6 +4662,8 @@ static float get_uv_face_needle(const eUVSelectSimilar type, } break; case UV_SSIM_MATERIAL: return face->mat_nr; + case UV_SSIM_WINDING: + return signum_i(BM_face_calc_area_uv_signed(face, offsets.uv)); default: BLI_assert_unreachable(); return false; @@ -4966,7 +4973,7 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op) continue; } - float needle = get_uv_face_needle(type, face, ob_m3, offsets); + float needle = get_uv_face_needle(type, face, ob_index, ob_m3, offsets); if (tree_1d) { BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle); } @@ -5000,7 +5007,7 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op) continue; } - float needle = get_uv_face_needle(type, face, ob_m3, offsets); + float needle = get_uv_face_needle(type, face, ob_index, ob_m3, offsets); bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare); if (select) { @@ -5180,8 +5187,10 @@ static EnumPropertyItem prop_edge_similar_types[] = { static EnumPropertyItem prop_face_similar_types[] = { {UV_SSIM_AREA_UV, "AREA", 0, "Area", ""}, {UV_SSIM_AREA_3D, "AREA_3D", 0, "Area 3D", ""}, - {UV_SSIM_SIDES, "SIDES", 0, "Polygon Sides", ""}, {UV_SSIM_MATERIAL, "MATERIAL", 0, "Material", ""}, + {UV_SSIM_OBJECT, "OBJECT", 0, "Object", ""}, + {UV_SSIM_SIDES, "SIDES", 0, "Polygon Sides", ""}, + {UV_SSIM_WINDING, "WINDING", 0, "Winding", ""}, {0}}; static EnumPropertyItem prop_island_similar_types[] = { From b3fd169259ac5da8e6bcfa8076f541886cb7b75e Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 27 Jan 2023 08:39:26 +0100 Subject: [PATCH 0977/1522] ImBuf: Precalc subsamples to reduce branching. Micro improvement to store delta uv per subsample. This reduces branching that might happen on the CPU, but also makes it possible to add other sub-sampling filters as well. No changes for the end-user. --- source/blender/imbuf/intern/transform.cc | 55 ++++++++++++------------ 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc index 198d04cc5f6..260f1ea45f8 100644 --- a/source/blender/imbuf/intern/transform.cc +++ b/source/blender/imbuf/intern/transform.cc @@ -12,6 +12,7 @@ #include "BLI_math_color_blend.h" #include "BLI_math_vector.hh" #include "BLI_rect.h" +#include "BLI_vector.hh" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -39,11 +40,10 @@ struct TransformUserData { double2 add_y; struct { - int num; - double2 offset_x; - double2 offset_y; - double2 add_x; - double2 add_y; + /** + * Contains per sub-sample a delta to be added to the uv of the source image buffer. + */ + Vector delta_uvs; } subsampling; /** @@ -96,11 +96,19 @@ struct TransformUserData { void init_subsampling(const int num_subsamples) { - subsampling.num = max_ii(num_subsamples, 1); - subsampling.add_x = add_x / (subsampling.num); - subsampling.add_y = add_y / (subsampling.num); - subsampling.offset_x = -add_x * 0.5 + subsampling.add_x * 0.5; - subsampling.offset_y = -add_y * 0.5 + subsampling.add_y * 0.5; + double2 subsample_add_x = add_x / num_subsamples; + double2 subsample_add_y = add_y / num_subsamples; + double2 offset_x = -add_x * 0.5 + subsample_add_x * 0.5; + double2 offset_y = -add_y * 0.5 + subsample_add_y * 0.5; + + for (int y : IndexRange(0, num_subsamples)) { + for (int x : IndexRange(0, num_subsamples)) { + double2 delta_uv = -offset_x - offset_y; + delta_uv += x * subsample_add_x; + delta_uv += y * subsample_add_y; + subsampling.delta_uvs.append(delta_uv); + } + } } }; @@ -526,7 +534,7 @@ class ScanlineProcessor { */ void process(const TransformUserData *user_data, int scanline) { - if (user_data->subsampling.num > 1) { + if (user_data->subsampling.delta_uvs.size() > 1) { process_with_subsampling(user_data, scanline); } else { @@ -595,26 +603,19 @@ class ScanlineProcessor { sample.clear(); int num_subsamples_added = 0; - double2 subsample_uv_y = uv + user_data->subsampling.offset_y; - for (int subsample_yi : IndexRange(user_data->subsampling.num)) { - UNUSED_VARS(subsample_yi); - double2 subsample_uv = subsample_uv_y + user_data->subsampling.offset_x; - for (int subsample_xi : IndexRange(user_data->subsampling.num)) { - UNUSED_VARS(subsample_xi); - if (!discarder.should_discard(*user_data, subsample_uv)) { - typename Sampler::SampleType sub_sample; - sampler.sample(user_data->src, subsample_uv, sub_sample); - sample.add_subsample(sub_sample, num_subsamples_added); - num_subsamples_added += 1; - } - subsample_uv += user_data->subsampling.add_x; + for (double2 delta_uv : user_data->subsampling.delta_uvs) { + double2 subsample_uv = uv + delta_uv; + if (!discarder.should_discard(*user_data, subsample_uv)) { + typename Sampler::SampleType sub_sample; + sampler.sample(user_data->src, subsample_uv, sub_sample); + sample.add_subsample(sub_sample, num_subsamples_added); + num_subsamples_added += 1; } - subsample_uv_y += user_data->subsampling.add_y; } if (num_subsamples_added != 0) { - float mix_weight = float(num_subsamples_added) / - (user_data->subsampling.num * user_data->subsampling.num); + const float mix_weight = float(num_subsamples_added) / + user_data->subsampling.delta_uvs.size(); channel_converter.mix_and_store(sample, output, mix_weight); } uv += user_data->add_x; From 71d7c919c009ab0badfd767608f6aa9346c6ab78 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 27 Jan 2023 09:56:19 +0100 Subject: [PATCH 0978/1522] ImBuf: Limit transform region to pixels that are affected by the transformation. Only the area where the source buffer will be drawn on the destination buffer will be evaluated. This will improve performance in sequencer and image editors as less calcuations needs to happen. --- source/blender/imbuf/intern/transform.cc | 106 ++++++++++++++--------- 1 file changed, 64 insertions(+), 42 deletions(-) diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc index 260f1ea45f8..e3573bab851 100644 --- a/source/blender/imbuf/intern/transform.cc +++ b/source/blender/imbuf/intern/transform.cc @@ -8,10 +8,12 @@ #include #include +#include "BLI_float4x4.hh" #include "BLI_math.h" #include "BLI_math_color_blend.h" #include "BLI_math_vector.hh" #include "BLI_rect.h" +#include "BLI_task.hh" #include "BLI_vector.hh" #include "IMB_imbuf.h" @@ -46,6 +48,11 @@ struct TransformUserData { Vector delta_uvs; } subsampling; + struct { + IndexRange x_range; + IndexRange y_range; + } destination_region; + /** * \brief Cropping region in source image pixel space. */ @@ -54,12 +61,15 @@ struct TransformUserData { /** * \brief Initialize the start_uv, add_x and add_y fields based on the given transform matrix. */ - void init(const float transform_matrix[4][4], const int num_subsamples) + void init(const float transform_matrix[4][4], + const int num_subsamples, + const bool do_crop_destination_region) { init_start_uv(transform_matrix); init_add_x(transform_matrix); init_add_y(transform_matrix); init_subsampling(num_subsamples); + init_destination_region(transform_matrix, do_crop_destination_region); } private: @@ -110,6 +120,39 @@ struct TransformUserData { } } } + + void init_destination_region(const float4x4 &transform_matrix, + const bool do_crop_destination_region) + { + if (!do_crop_destination_region) { + destination_region.x_range = IndexRange(dst->x); + destination_region.y_range = IndexRange(dst->y); + return; + } + + /* Transform the src_crop to the destination buffer with a margin.*/ + const int2 margin(2); + rcti rect; + BLI_rcti_init_minmax(&rect); + float4x4 inverse = transform_matrix.inverted(); + for (const int2 &src_coords : { + int2(src_crop.xmin, src_crop.ymin), + int2(src_crop.xmax, src_crop.ymin), + int2(src_crop.xmin, src_crop.ymax), + int2(src_crop.xmax, src_crop.ymax), + }) { + float3 dst_co = inverse * float3(src_coords.x, src_coords.y, 0.0f); + BLI_rcti_do_minmax_v(&rect, int2(dst_co) + margin); + BLI_rcti_do_minmax_v(&rect, int2(dst_co) - margin); + } + + /* Clamp rect to fit inside the image buffer.*/ + rcti dest_rect; + BLI_rcti_init(&dest_rect, 0, dst->x, 0, dst->y); + BLI_rcti_isect(&rect, &dest_rect, &rect); + destination_region.x_range = IndexRange(rect.xmin, BLI_rcti_size_x(&rect)); + destination_region.y_range = IndexRange(rect.ymin, BLI_rcti_size_y(&rect)); + } }; /** @@ -545,22 +588,14 @@ class ScanlineProcessor { private: void process_one_sample_per_pixel(const TransformUserData *user_data, int scanline) { - const int width = user_data->dst->x; - double2 uv = user_data->start_uv + user_data->add_y * scanline; + double2 uv = user_data->start_uv + + user_data->destination_region.x_range.first() * user_data->add_x + + user_data->add_y * scanline; - output.init_pixel_pointer(user_data->dst, int2(0, scanline)); - int xi = 0; - while (xi < width) { - const bool discard_pixel = discarder.should_discard(*user_data, uv); - if (!discard_pixel) { - break; - } - uv += user_data->add_x; - output.increase_pixel_pointer(); - xi += 1; - } - - for (; xi < width; xi++) { + output.init_pixel_pointer(user_data->dst, + int2(user_data->destination_region.x_range.first(), scanline)); + for (int xi : user_data->destination_region.x_range) { + UNUSED_VARS(xi); if (!discarder.should_discard(*user_data, uv)) { typename Sampler::SampleType sample; sampler.sample(user_data->src, uv, sample); @@ -574,31 +609,14 @@ class ScanlineProcessor { void process_with_subsampling(const TransformUserData *user_data, int scanline) { - const int width = user_data->dst->x; - double2 uv = user_data->start_uv + user_data->add_y * scanline; + double2 uv = user_data->start_uv + + user_data->destination_region.x_range.first() * user_data->add_x + + user_data->add_y * scanline; - output.init_pixel_pointer(user_data->dst, int2(0, scanline)); - int xi = 0; - /* - * Skip leading pixels that would be fully discarded. - * - * NOTE: This could be improved by intersection between an ray and the image bounds. - */ - while (xi < width) { - const bool discard_pixel = discarder.should_discard(*user_data, uv) && - discarder.should_discard(*user_data, uv + user_data->add_x) && - discarder.should_discard(*user_data, uv + user_data->add_y) && - discarder.should_discard( - *user_data, uv + user_data->add_x + user_data->add_y); - if (!discard_pixel) { - break; - } - uv += user_data->add_x; - output.increase_pixel_pointer(); - xi += 1; - } - - for (; xi < width; xi++) { + output.init_pixel_pointer(user_data->dst, + int2(user_data->destination_region.x_range.first(), scanline)); + for (int xi : user_data->destination_region.x_range) { + UNUSED_VARS(xi); typename Sampler::SampleType sample; sample.clear(); int num_subsamples_added = 0; @@ -699,7 +717,11 @@ static void transform_threaded(TransformUserData *user_data, const eIMBTransform } if (scanline_func != nullptr) { - IMB_processor_apply_threaded_scanlines(user_data->dst->y, scanline_func, user_data); + threading::parallel_for(user_data->destination_region.y_range, 8, [&](IndexRange range) { + for (int scanline : range) { + scanline_func(user_data, scanline); + } + }); } } @@ -727,7 +749,7 @@ void IMB_transform(const struct ImBuf *src, if (mode == IMB_TRANSFORM_MODE_CROP_SRC) { user_data.src_crop = *src_crop; } - user_data.init(transform_matrix, num_subsamples); + user_data.init(transform_matrix, num_subsamples, ELEM(mode, IMB_TRANSFORM_MODE_CROP_SRC)); if (filter == IMB_FILTER_NEAREST) { transform_threaded(&user_data, mode); From 0cce6538926e48b7623d2ae43813aa9cfa20a242 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 27 Jan 2023 10:25:39 +0100 Subject: [PATCH 0979/1522] Cleanup: Pass double2 by reference. Just to be sure if compilers aren't inlining the function that at least the parameter isn't copied. --- source/blender/imbuf/intern/transform.cc | 25 +++++++++++------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/source/blender/imbuf/intern/transform.cc b/source/blender/imbuf/intern/transform.cc index e3573bab851..0370e29124d 100644 --- a/source/blender/imbuf/intern/transform.cc +++ b/source/blender/imbuf/intern/transform.cc @@ -169,7 +169,7 @@ class BaseDiscard { /** * \brief Should the source pixel at the given uv coordinate be discarded. */ - virtual bool should_discard(const TransformUserData &user_data, const double2 uv) = 0; + virtual bool should_discard(const TransformUserData &user_data, const double2 &uv) = 0; }; /** @@ -182,7 +182,7 @@ class CropSource : public BaseDiscard { * * Uses user_data.src_crop to determine if the uv coordinate should be skipped. */ - bool should_discard(const TransformUserData &user_data, const double2 uv) override + bool should_discard(const TransformUserData &user_data, const double2 &uv) override { return uv.x < user_data.src_crop.xmin || uv.x >= user_data.src_crop.xmax || uv.y < user_data.src_crop.ymin || uv.y >= user_data.src_crop.ymax; @@ -199,7 +199,7 @@ class NoDiscard : public BaseDiscard { * * Will never discard any pixels. */ - bool should_discard(const TransformUserData & /*user_data*/, const double2 /*uv*/) override + bool should_discard(const TransformUserData & /*user_data*/, const double2 & /*uv*/) override { return false; } @@ -278,7 +278,7 @@ class BaseUVWrapping { /** * \brief modify the given uv coordinate. */ - double2 modify_uv(const ImBuf *source_buffer, double2 uv) + double2 modify_uv(const ImBuf *source_buffer, const double2 &uv) { return double2(modify_u(source_buffer, uv.x), modify_v(source_buffer, uv.y)); } @@ -391,7 +391,7 @@ class Sampler { static const int ChannelLen = NumChannels; using SampleType = Pixel; - void sample(const ImBuf *source, const double2 uv, SampleType &r_sample) + void sample(const ImBuf *source, const double2 &uv, SampleType &r_sample) { if constexpr (Filter == IMB_FILTER_BILINEAR && std::is_same_v && NumChannels == 4) { @@ -431,7 +431,7 @@ class Sampler { } else if constexpr (Filter == IMB_FILTER_NEAREST && std::is_same_v) { const double2 wrapped_uv = uv_wrapper.modify_uv(source, uv); - sample_nearest_float(source, UNPACK2(wrapped_uv), r_sample); + sample_nearest_float(source, wrapped_uv, r_sample); } else { /* Unsupported sampler. */ @@ -440,16 +440,13 @@ class Sampler { } private: - void sample_nearest_float(const ImBuf *source, - const double u, - const double v, - SampleType &r_sample) + void sample_nearest_float(const ImBuf *source, const double2 &uv, SampleType &r_sample) { BLI_STATIC_ASSERT(std::is_same_v); /* ImBuf in must have a valid rect or rect_float, assume this is already checked */ - int x1 = int(u); - int y1 = int(v); + int x1 = int(uv.x); + int y1 = int(uv.y); /* Break when sample outside image is requested. */ if (x1 < 0 || x1 >= source->x || y1 < 0 || y1 >= source->y) { @@ -621,8 +618,8 @@ class ScanlineProcessor { sample.clear(); int num_subsamples_added = 0; - for (double2 delta_uv : user_data->subsampling.delta_uvs) { - double2 subsample_uv = uv + delta_uv; + for (const double2 &delta_uv : user_data->subsampling.delta_uvs) { + const double2 subsample_uv = uv + delta_uv; if (!discarder.should_discard(*user_data, subsample_uv)) { typename Sampler::SampleType sub_sample; sampler.sample(user_data->src, subsample_uv, sub_sample); From d5b026a16c38623ca60837e0862c347f5e2cf4a2 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 27 Jan 2023 11:11:18 +0100 Subject: [PATCH 0980/1522] Fix incorrect RNA path for GPencil brush settings, and add it for Curves brush settings. RNA paths should be relative to their owner ID, not to some other ID! --- source/blender/makesrna/intern/rna_brush.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index db38c3d4af7..8e6908841a6 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -968,7 +968,7 @@ static const EnumPropertyItem *rna_Brush_stroke_itemf(bContext *C, /* Grease Pencil Drawing Brushes Settings */ static char *rna_BrushGpencilSettings_path(const PointerRNA *UNUSED(ptr)) { - return BLI_strdup("tool_settings.gpencil_paint.brush.gpencil_settings"); + return BLI_strdup("gpencil_settings"); } static void rna_BrushGpencilSettings_default_eraser_update(Main *bmain, @@ -1123,6 +1123,11 @@ static void rna_Brush_automasking_cavity_set(PointerRNA *ptr, bool val) } } +static char *rna_BrushCurvesSculptSettings_path(const PointerRNA *UNUSED(ptr)) +{ + return BLI_strdup("curves_sculpt_settings"); +} + #else static void rna_def_brush_texture_slot(BlenderRNA *brna) @@ -2037,6 +2042,7 @@ static void rna_def_curves_sculpt_options(BlenderRNA *brna) }; srna = RNA_def_struct(brna, "BrushCurvesSculptSettings", NULL); + RNA_def_struct_path_func(srna, "rna_BrushCurvesSculptSettings_path"); RNA_def_struct_sdna(srna, "BrushCurvesSculptSettings"); RNA_def_struct_ui_text(srna, "Curves Sculpt Brush Settings", ""); From 79f70e48eb96609cff2f9bb45d762e230b6fe820 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Fri, 27 Jan 2023 12:40:08 +0100 Subject: [PATCH 0981/1522] Fix: crash in mesh topology nodes This was broken in rBd6c9cd445cb41480b40. --- .../geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc | 2 +- .../geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc index 8d7ebb4e105..81608271d5b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_corners_of_vertex.cc @@ -123,7 +123,7 @@ class CornersOfVertInput final : public bke::MeshFieldInput { corner_of_vertex[selection_i] = corner_indices[sort_indices[index_in_sort_wrapped]]; } else { - corner_of_vertex[selection_i] = corner_indices[index_in_sort_wrapped]; + corner_of_vertex[selection_i] = corners[index_in_sort_wrapped]; } } }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc index 7c27a4b783d..8fd1ffa5148 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_topology_edges_of_vertex.cc @@ -124,7 +124,7 @@ class EdgesOfVertInput final : public bke::MeshFieldInput { edge_of_vertex[selection_i] = edge_indices[sort_indices[index_in_sort_wrapped]]; } else { - edge_of_vertex[selection_i] = edge_indices[index_in_sort_wrapped]; + edge_of_vertex[selection_i] = edges[index_in_sort_wrapped]; } } }); From 454057f9df85fe36aaea57db41295e3bab074594 Mon Sep 17 00:00:00 2001 From: Iliya Katueshenock Date: Fri, 27 Jan 2023 14:47:02 +0100 Subject: [PATCH 0982/1522] Fix T104175: adding Blur Attribute node with link drag search fails The node does not support blurring booleans, but that was not handled property in link drag search. Differential Revision: https://developer.blender.org/D17139 --- .../geometry/nodes/node_geo_blur_attribute.cc | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc index 48062516784..77bfa7a2b58 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_blur_attribute.cc @@ -82,19 +82,32 @@ static void node_init(bNodeTree * /*tree*/, bNode *node) static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms) { - const NodeDeclaration &declaration = *params.node_type().fixed_declaration; + const bNodeType &node_type = params.node_type(); + const NodeDeclaration &declaration = *node_type.fixed_declaration; + + /* Weight and Iterations inputs don't change based on the data type. */ search_link_ops_for_declarations(params, declaration.inputs.as_span().take_back(2)); - const bNodeType &node_type = params.node_type(); - const std::optional type = node_data_type_to_custom_data_type( - (eNodeSocketDatatype)params.other_socket().type); - if (type && *type != CD_PROP_STRING) { - params.add_item(IFACE_("Value"), [node_type, type](LinkSearchOpParams ¶ms) { - bNode &node = params.add_node(node_type); - node.custom1 = *type; - params.update_and_connect_available_socket(node, "Value"); - }); + const eNodeSocketDatatype other_socket_type = static_cast( + params.other_socket().type); + const std::optional new_node_type = node_data_type_to_custom_data_type( + other_socket_type); + if (!new_node_type.has_value()) { + return; } + eCustomDataType fixed_data_type = *new_node_type; + if (fixed_data_type == CD_PROP_STRING) { + return; + } + if (fixed_data_type == CD_PROP_BOOL) { + /* This node does not support boolean sockets, use integer instead. */ + fixed_data_type = CD_PROP_INT32; + } + params.add_item(IFACE_("Value"), [node_type, fixed_data_type](LinkSearchOpParams ¶ms) { + bNode &node = params.add_node(node_type); + node.custom1 = fixed_data_type; + params.update_and_connect_available_socket(node, "Value"); + }); } static void node_update(bNodeTree *ntree, bNode *node) From 75d62285831636a1c2878dc2b5aa8a2836be4eb1 Mon Sep 17 00:00:00 2001 From: "demeterdzadik@gmail.com" Date: Fri, 27 Jan 2023 14:44:06 +0100 Subject: [PATCH 0983/1522] PyAPI: Generic UIList for CollectionProperties This patch adds a draw_ui_list() function, which is a wrapper around layout.template_list(). It implements generic add/remove/move buttons, passing the correct "row" integer to template_list(), as well as a drop-down menu, if provided, making it a complete solution for consistent UILists for addons. Differential Revision: https://developer.blender.org/D14119 --- release/scripts/startup/bl_ui/__init__.py | 1 + .../scripts/startup/bl_ui/generic_ui_list.py | 253 ++++++++++++++++++ .../scripts/templates_py/ui_list_generic.py | 46 ++++ 3 files changed, 300 insertions(+) create mode 100644 release/scripts/startup/bl_ui/generic_ui_list.py create mode 100644 release/scripts/templates_py/ui_list_generic.py diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 01ae0730fab..7d20962ae4e 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -52,6 +52,7 @@ _modules = [ "properties_texture", "properties_world", "properties_collection", + "generic_ui_list", # Generic Space Modules # diff --git a/release/scripts/startup/bl_ui/generic_ui_list.py b/release/scripts/startup/bl_ui/generic_ui_list.py new file mode 100644 index 00000000000..02157a4588d --- /dev/null +++ b/release/scripts/startup/bl_ui/generic_ui_list.py @@ -0,0 +1,253 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +import bpy +from bpy.types import Operator, UILayout, Context +from bpy.props import EnumProperty, StringProperty + +""" +This module (in particular the draw_ui_list function) lets you draw the commonly +used UIList layout, seen all over Blender. + +This includes the list itself, and a column of buttons to the right of it, which +contains buttons to add, remove, and move entries up or down, as well as a +drop-down menu. + +You can get an example of how to use this via the Blender Text Editor-> +Templates->Ui List Generic. +""" + + +def draw_ui_list( + layout: UILayout, + context: Context, + class_name="UI_UL_list", + *, + unique_id="", + list_path: str, + active_idx_path: str, + insertion_operators=True, + move_operators=True, + menu_class_name="", + **kwargs) -> UILayout: + """ + Draw a UIList with Add/Remove/Move buttons and a menu. + + :param layout: + UILayout to draw the list in. + :param context: + Blender context to get the list data from. + :param class_name: + Name of the UIList class to draw. The default is the + UIList class that ships with Blender. + :param unique_id: + Optional identifier, in case wanting to draw multiple unique copies of a list. + + :param list_path: + Data path of the list relative to context, eg. "object.vertex_groups". + :param active_idx_path: + Data path of the list active index integer relative to context, + eg. "object.vertex_groups.active_index". + + :param insertion_operators: + Whether to draw Add/Remove buttons. + :param move_operators: + Whether to draw Move Up/Down buttons. + :param menu_class_name: + Name of a Menu that should be drawn as a drop-down. + + Additional keyword arguments are passed to template_list(). + """ + row = layout.row() + + list_owner_path, list_prop_name = list_path.rsplit('.', 1) + list_owner = _get_context_attr(context, list_owner_path) + + idx_owner_path, idx_prop_name = active_idx_path.rsplit('.', 1) + idx_owner = _get_context_attr(context, idx_owner_path) + + list_to_draw = _get_context_attr(context, list_path) + + row.template_list( + class_name, + unique_id, + list_owner, list_prop_name, + idx_owner, idx_prop_name, + rows=4 if len(list_to_draw) > 0 else 1, + **kwargs + ) + + col = row.column() + + if insertion_operators: + _draw_add_remove_buttons( + layout=col, + list_path=list_path, + active_idx_path=active_idx_path, + list_length=len(list_to_draw) + ) + layout.separator() + + if menu_class_name: + col.menu(menu_class_name, icon='DOWNARROW_HLT', text="") + col.separator() + + if move_operators and len(list_to_draw) > 0: + _draw_move_buttons( + layout=col, + list_path=list_path, + active_idx_path=active_idx_path, + list_length=len(list_to_draw) + ) + + # Return the right-side column. + return col + + +def _draw_add_remove_buttons( + *, + layout: UILayout, + list_path: str, + active_idx_path: str, + list_length: int +) -> None: + """Draw the +/- buttons to add and remove list entries.""" + add_op = layout.operator(UILIST_OT_entry_add.bl_idname, text="", icon='ADD') + add_op.list_path = list_path + add_op.active_idx_path = active_idx_path + + row = layout.row() + row.enabled = list_length > 0 + remove_op = row.operator(UILIST_OT_entry_remove.bl_idname, text="", icon='REMOVE') + remove_op.list_path = list_path + remove_op.active_idx_path = active_idx_path + + +def _draw_move_buttons( + *, + layout: UILayout, + list_path: str, + active_idx_path: str, + list_length: int +) -> None: + """Draw the up/down arrows to move elements in the list.""" + col = layout.column() + col.enabled = list_length > 0 + move_up_op = layout.operator(UILIST_OT_entry_move.bl_idname, text="", icon='TRIA_UP') + move_up_op.direction = 'UP' + move_up_op.list_path = list_path + move_up_op.active_idx_path = active_idx_path + + move_down_op = layout.operator(UILIST_OT_entry_move.bl_idname, text="", icon='TRIA_DOWN') + move_down_op.direction = 'DOWN' + move_down_op.list_path = list_path + move_down_op.active_idx_path = active_idx_path + + +def _get_context_attr(context: Context, data_path: str) -> object: + """Return the value of a context member based on its data path.""" + return context.path_resolve(data_path) + + +def _set_context_attr(context: Context, data_path: str, value: object) -> None: + """Set the value of a context member based on its data path.""" + owner_path, attr_name = data_path.rsplit('.', 1) + owner = context.path_resolve(owner_path) + setattr(owner, attr_name, value) + + +class GenericUIListOperator: + """Mix-in class containing functionality shared by operators + that deal with managing Blender list entries.""" + bl_options = {'REGISTER', 'UNDO', 'INTERNAL'} + + list_path: StringProperty() + active_idx_path: StringProperty() + + def get_list(self, context) -> str: + return _get_context_attr(context, self.list_path) + + def get_active_index(self, context) -> str: + return _get_context_attr(context, self.active_idx_path) + + def set_active_index(self, context, index): + _set_context_attr(context, self.active_idx_path, index) + + +# noinspection PyPep8Naming +class UILIST_OT_entry_remove(GenericUIListOperator, Operator): + """Remove the selected entry from the list""" + + bl_idname = "uilist.entry_remove" + bl_label = "Remove Selected Entry" + + def execute(self, context): + my_list = self.get_list(context) + active_index = self.get_active_index(context) + + my_list.remove(active_index) + to_index = min(active_index, len(my_list) - 1) + self.set_active_index(context, to_index) + + return {'FINISHED'} + + +# noinspection PyPep8Naming +class UILIST_OT_entry_add(GenericUIListOperator, Operator): + """Add an entry to the list after the current active item""" + + bl_idname = "uilist.entry_add" + bl_label = "Add Entry" + + def execute(self, context): + my_list = self.get_list(context) + active_index = self.get_active_index(context) + + to_index = min(len(my_list), active_index + 1) + + my_list.add() + my_list.move(len(my_list) - 1, to_index) + self.set_active_index(context, to_index) + + return {'FINISHED'} + + +# noinspection PyPep8Naming +class UILIST_OT_entry_move(GenericUIListOperator, Operator): + """Move an entry in the list up or down""" + + bl_idname = "uilist.entry_move" + bl_label = "Move Entry" + + direction: EnumProperty( + name="Direction", + items=[('UP', 'UP', 'UP'), + ('DOWN', 'DOWN', 'DOWN')], + default='UP' + ) + + def execute(self, context): + my_list = self.get_list(context) + active_index = self.get_active_index(context) + + delta = { + "DOWN": 1, + "UP": -1, + }[self.direction] + + to_index = (active_index + delta) % len(my_list) + + my_list.move(active_index, to_index) + self.set_active_index(context, to_index) + + return {'FINISHED'} + + +# ============================================= +# Registration + +classes = ( + UILIST_OT_entry_remove, + UILIST_OT_entry_add, + UILIST_OT_entry_move, +) + +register, unregister = bpy.utils.register_classes_factory(classes) diff --git a/release/scripts/templates_py/ui_list_generic.py b/release/scripts/templates_py/ui_list_generic.py new file mode 100644 index 00000000000..ad370ec4305 --- /dev/null +++ b/release/scripts/templates_py/ui_list_generic.py @@ -0,0 +1,46 @@ +import bpy +from bl_ui.generic_ui_list import draw_ui_list + + +class MyPropGroup(bpy.types.PropertyGroup): + name: bpy.props.StringProperty() + + +class MyPanel(bpy.types.Panel): + bl_label = "My Label" + bl_idname = "SCENE_PT_list_demo" + bl_space_type = 'VIEW_3D' + bl_region_type = 'UI' + bl_category = 'My Category' + + def draw(self, context): + layout = self.layout + draw_ui_list( + layout, + context, + list_context_path="scene.my_list", + active_idx_context_path="scene.my_list_active_idx" + ) + + +classes = [ + MyPropGroup, + MyPanel +] + +class_register, class_unregister = bpy.utils.register_classes_factory(classes) + + +def register(): + class_register() + bpy.types.Scene.my_list = bpy.props.CollectionProperty(type=MyPropGroup) + bpy.types.Scene.my_list_active_idx = bpy.props.IntProperty() + + +def unregister(): + class_unregister() + del bpy.types.Scene.my_list + del bpy.types.Scene.my_list_active_idx + + +register() From 073cf46b2e7e903641ff1859d5308c11f6e786f3 Mon Sep 17 00:00:00 2001 From: "demeterdzadik@gmail.com" Date: Fri, 27 Jan 2023 14:56:53 +0100 Subject: [PATCH 0984/1522] Fix Generic List move ops clickable with 1 element Meant to include this piece of feedback from Sybren in D14119. --- release/datafiles/locale | 2 +- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- release/scripts/startup/bl_ui/generic_ui_list.py | 2 +- source/tools | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/release/datafiles/locale b/release/datafiles/locale index 08b372721b9..7084c4ecd97 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 08b372721b9b33a16f380cab23b2e5ded738ea96 +Subproject commit 7084c4ecd97d93459d9d23fd90f81589b09be5df diff --git a/release/scripts/addons b/release/scripts/addons index d887a4ea6b2..7b9dd0e1ef4 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit d887a4ea6b2a9d64b926034d4e78ecf7a48ca979 +Subproject commit 7b9dd0e1ef425ebe6f3aa9ce292acf0464c72028 diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index 9d538629bb8..bdcfdd47ec3 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit 9d538629bb8a425991c7d10a49bab1ba0788c18f +Subproject commit bdcfdd47ec3451822b21d1cff2ea2db751093c9a diff --git a/release/scripts/startup/bl_ui/generic_ui_list.py b/release/scripts/startup/bl_ui/generic_ui_list.py index 02157a4588d..2ca380ed657 100644 --- a/release/scripts/startup/bl_ui/generic_ui_list.py +++ b/release/scripts/startup/bl_ui/generic_ui_list.py @@ -130,7 +130,7 @@ def _draw_move_buttons( ) -> None: """Draw the up/down arrows to move elements in the list.""" col = layout.column() - col.enabled = list_length > 0 + col.enabled = list_length > 1 move_up_op = layout.operator(UILIST_OT_entry_move.bl_idname, text="", icon='TRIA_UP') move_up_op.direction = 'UP' move_up_op.list_path = list_path diff --git a/source/tools b/source/tools index 3582f5326d0..e1744b9bd82 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit 3582f5326d08ca05c2a19056597e49ec5511d854 +Subproject commit e1744b9bd82527cf7e8af63362b61bd309b5711b From 1fd1d24265dceced96f067c523d7b1d6b4647a42 Mon Sep 17 00:00:00 2001 From: "demeterdzadik@gmail.com" Date: Fri, 27 Jan 2023 15:05:44 +0100 Subject: [PATCH 0985/1522] Revert accidental changes to sub-modules When committing via VSCode's Git UI, my commit 073cf46b2e7e903641ff1859d5308c11f6e786f3 seems to have affected sub-modules. Gotta be more careful! --- release/datafiles/locale | 2 +- release/scripts/addons | 2 +- release/scripts/addons_contrib | 2 +- source/tools | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/release/datafiles/locale b/release/datafiles/locale index 7084c4ecd97..08b372721b9 160000 --- a/release/datafiles/locale +++ b/release/datafiles/locale @@ -1 +1 @@ -Subproject commit 7084c4ecd97d93459d9d23fd90f81589b09be5df +Subproject commit 08b372721b9b33a16f380cab23b2e5ded738ea96 diff --git a/release/scripts/addons b/release/scripts/addons index 7b9dd0e1ef4..d887a4ea6b2 160000 --- a/release/scripts/addons +++ b/release/scripts/addons @@ -1 +1 @@ -Subproject commit 7b9dd0e1ef425ebe6f3aa9ce292acf0464c72028 +Subproject commit d887a4ea6b2a9d64b926034d4e78ecf7a48ca979 diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib index bdcfdd47ec3..9d538629bb8 160000 --- a/release/scripts/addons_contrib +++ b/release/scripts/addons_contrib @@ -1 +1 @@ -Subproject commit bdcfdd47ec3451822b21d1cff2ea2db751093c9a +Subproject commit 9d538629bb8a425991c7d10a49bab1ba0788c18f diff --git a/source/tools b/source/tools index e1744b9bd82..3582f5326d0 160000 --- a/source/tools +++ b/source/tools @@ -1 +1 @@ -Subproject commit e1744b9bd82527cf7e8af63362b61bd309b5711b +Subproject commit 3582f5326d08ca05c2a19056597e49ec5511d854 From 138b3815e528b062844c5fa8ef0e2f00b1b21274 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 27 Jan 2023 15:01:29 +0100 Subject: [PATCH 0986/1522] Fix (unreported) missing clear of deprecated Window data on fileread. rB7f564d74f9ed (6 years ago!) forgot to clear the deprecated `Window->screen` pointer on file read for recent-enough .blend files. This is required since a valid value is always written in .blend files for that pointer, to ensure backward compatibility. The issue was never detected so far because that pointer is explicitely reset to NULL after filewrite, which includes any memfile undostep write, and usually existing UI data is re-used instead of loading the one from the .blend file, so thedden assert in `blo_lib_link_restore` would never be triggered. Now moved the assert at the end of `setup_app_data` to ensure it always get checked. --- source/blender/blenkernel/intern/blendfile.cc | 10 ++++++++++ source/blender/blenloader/intern/readfile.cc | 2 -- source/blender/blenloader/intern/versioning_280.c | 12 +++++++++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/blendfile.cc b/source/blender/blenkernel/intern/blendfile.cc index 68f37df9ca9..b7294156cb2 100644 --- a/source/blender/blenkernel/intern/blendfile.cc +++ b/source/blender/blenkernel/intern/blendfile.cc @@ -438,6 +438,16 @@ static void setup_app_data(bContext *C, /* We need to rebuild some of the deleted override rules (for UI feedback purpose). */ BKE_lib_override_library_main_operations_create(bmain, true, nullptr); } + + /* Sanity checks. */ +#ifndef NDEBUG + LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) { + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { + /* This pointer is deprecated and should always be nullptr. */ + BLI_assert(win->screen == nullptr); + } + } +#endif } static void setup_app_blend_file_data(bContext *C, diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 2ffe8386166..e2721820f96 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -2701,8 +2701,6 @@ void blo_lib_link_restore(Main *oldmain, * all workspaces), that one only focuses one current active screen, takes care of * potential local view, and needs window's scene pointer to be final... */ lib_link_window_scene_data_restore(win, win->scene, cur_view_layer); - - BLI_assert(win->screen == nullptr); } lib_link_wm_xr_data_restore(id_map, &curwm->xr); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 980c8894e10..2e9a16bc945 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -1297,7 +1297,7 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports)) } } - /* New workspace design */ + /* New workspace design. */ if (!MAIN_VERSION_ATLEAST(bmain, 280, 1)) { do_version_workspaces_after_lib_link(bmain); } @@ -1970,6 +1970,16 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } #endif + /* Files from this version included do get a valid `win->screen` pointer written for backward + * compatibility, however this should never be used nor needed, so clear these pointers here. */ + if (MAIN_VERSION_ATLEAST(bmain, 280, 1)) { + for (wmWindowManager *wm = bmain->wm.first; wm; wm = wm->id.next) { + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { + win->screen = NULL; + } + } + } + if (!MAIN_VERSION_ATLEAST(bmain, 280, 3)) { /* init grease pencil grids and paper */ if (!DNA_struct_elem_find(fd->filesdna, "View3DOverlay", "float", "gpencil_paper_color[3]")) { From 3d7697b3258384c52e6de52f93da567afb7917a4 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 27 Jan 2023 15:32:44 +0100 Subject: [PATCH 0987/1522] Tweak to previous commit: move checks on DNA deprecated data at the end of readfile code. BKE blendfile should not be allowed to deal with DNA deprectaed data, so move recent check in rB138b3815e528 into BLO readfile, in a new `blo_read_file_checks` util that is being called at the very end of main readfile code (`blo_read_file_internal` and `library_link_end`). --- source/blender/blenkernel/intern/blendfile.cc | 10 ---------- source/blender/blenloader/intern/readfile.cc | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/source/blender/blenkernel/intern/blendfile.cc b/source/blender/blenkernel/intern/blendfile.cc index b7294156cb2..68f37df9ca9 100644 --- a/source/blender/blenkernel/intern/blendfile.cc +++ b/source/blender/blenkernel/intern/blendfile.cc @@ -438,16 +438,6 @@ static void setup_app_data(bContext *C, /* We need to rebuild some of the deleted override rules (for UI feedback purpose). */ BKE_lib_override_library_main_operations_create(bmain, true, nullptr); } - - /* Sanity checks. */ -#ifndef NDEBUG - LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) { - LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { - /* This pointer is deprecated and should always be nullptr. */ - BLI_assert(win->screen == nullptr); - } - } -#endif } static void setup_app_blend_file_data(bContext *C, diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index e2721820f96..a007daa0e82 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -3781,6 +3781,20 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead) /** \name Read File (Internal) * \{ */ +/** Contains sanity/debug checks to be performed at the very end of the reading process (i.e. after + * data, liblink, linked data, etc. has been done). */ +static void blo_read_file_checks(Main *bmain) +{ +#ifndef NDEBUG + LISTBASE_FOREACH (wmWindowManager *, wm, &bmain->wm) { + LISTBASE_FOREACH (wmWindow *, win, &wm->windows) { + /* This pointer is deprecated and should always be nullptr. */ + BLI_assert(win->screen == nullptr); + } + } +#endif +} + BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) { BHead *bhead = blo_bhead_first(fd); @@ -3963,6 +3977,9 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) BLI_assert(bfd->main->id_map == nullptr); + /* Sanity checks. */ + blo_read_file_checks(bfd->main); + return bfd; } @@ -4582,6 +4599,9 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag) blo_filedata_free(*fd); *fd = nullptr; } + + /* Sanity checks. */ + blo_read_file_checks(mainvar); } void BLO_library_link_end(Main *mainl, BlendHandle **bh, const LibraryLink_Params *params) From 46c68c46a50eb17217787ebca0e140375006eb75 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 27 Jan 2023 14:39:58 +0100 Subject: [PATCH 0988/1522] 3D Texturing: Adding more cases where seams can be fixed. Case added where a corner in uv space share the same edge in 3d space. This used to work, but was lost when implementing the new approach. --- source/blender/blenkernel/intern/pbvh_uv_islands.cc | 6 +++--- source/blender/blenkernel/intern/pbvh_uv_islands.hh | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.cc b/source/blender/blenkernel/intern/pbvh_uv_islands.cc index 07eb3137249..522b11b58db 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.cc +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.cc @@ -925,8 +925,7 @@ static void extend_at_vert(const MeshData &mesh_data, * triangle when the corner angle is near 180 degrees. In order to fix this we will * always add two segments both using the same fill primitive. */ - if ((num_to_add == 0 && winding_solution.size() == 1) || - (corner.angle > 1.0f && winding_solution.size() < 2)) { + if (winding_solution.size() < 2 && (num_to_add == 0 || corner.angle > 2.0f)) { int fill_primitive_1_i = corner.second->uv_primitive->primitive_i; int fill_primitive_2_i = corner.first->uv_primitive->primitive_i; @@ -1460,9 +1459,10 @@ UVIslands::UVIslands(const MeshData &mesh_data) { islands.reserve(mesh_data.uv_island_len); - for (int64_t uv_island_id = 0; uv_island_id < mesh_data.uv_island_len; uv_island_id++) { + for (const int64_t uv_island_id : IndexRange(mesh_data.uv_island_len)) { islands.append_as(UVIsland()); UVIsland *uv_island = &islands.last(); + uv_island->id = uv_island_id; for (const int primitive_i : mesh_data.looptris.index_range()) { if (mesh_data.uv_island_ids[primitive_i] == uv_island_id) { add_primitive(mesh_data, *uv_island, primitive_i); diff --git a/source/blender/blenkernel/intern/pbvh_uv_islands.hh b/source/blender/blenkernel/intern/pbvh_uv_islands.hh index b292c85bb01..6324b742fc4 100644 --- a/source/blender/blenkernel/intern/pbvh_uv_islands.hh +++ b/source/blender/blenkernel/intern/pbvh_uv_islands.hh @@ -289,6 +289,12 @@ struct UVBorder { }; struct UVIsland { + /** + * Id (Index) of the UVIsland. Contains the index of this island in UVIslands. + * + * Useful during debugging to set a breaking condition on a specific island/vert. + */ + int id; VectorList uv_vertices; VectorList uv_edges; VectorList uv_primitives; From 2590de913d4d3e6cabe4546ce8ad470b23fa1373 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 27 Jan 2023 15:50:52 +0100 Subject: [PATCH 0989/1522] Cleanup: Silence compilation warning (unused parameter). --- source/blender/makesrna/intern/rna_object.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index e70e87c53cf..71ad8dda859 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1759,8 +1759,7 @@ static void rna_Object_modifier_clear(Object *object, bContext *C) WM_main_add_notifier(NC_OBJECT | ND_MODIFIER | NA_REMOVED, object); } -static void rna_Object_modifier_move( - Object *object, Main *bmain, ReportList *reports, int from, int to) +static void rna_Object_modifier_move(Object *object, ReportList *reports, int from, int to) { ModifierData *md = BLI_findlink(&object->modifiers, from); @@ -2651,7 +2650,7 @@ static void rna_def_object_modifiers(BlenderRNA *brna, PropertyRNA *cprop) /* move a modifier */ func = RNA_def_function(srna, "move", "rna_Object_modifier_move"); RNA_def_function_ui_description(func, "Move a modifier to a different position"); - RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS); + RNA_def_function_flag(func, FUNC_USE_REPORTS); parm = RNA_def_int( func, "from_index", -1, INT_MIN, INT_MAX, "From Index", "Index to move", 0, 10000); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); From 4635dd6aed4c97ea234508e774db991926a7b3cf Mon Sep 17 00:00:00 2001 From: Patrick Mours Date: Fri, 27 Jan 2023 15:58:03 +0100 Subject: [PATCH 0990/1522] Fix T104157: Deleting an active OSL node causes issues Removing all OSL script nodes from the shader graph would cause that graph to no longer report it using `KERNEL_FEATURE_SHADER_RAYTRACE` via `ShaderManager::get_graph_kernel_features`, but the shader object itself still would have the `has_surface_raytrace` field set. This caused kernels to be reloaded without shader raytracing support, but later the `DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE_RAYTRACE` kernel would still be invoked since the shader continued to report it requiring that through the `SD_HAS_RAYTRACE` flag set because of `has_surface_raytrace`. Fix that by ensuring `has_surface_raytrace` is reset on every shader update, so that when all OSL script nodes are deleted it is set to false, and only stays true when there are still OSL script nodes (or other nodes using it). Maniphest Tasks: T104157 Differential Revision: https://developer.blender.org/D17140 --- intern/cycles/scene/osl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp index 73a8553c5d5..53e993b8135 100644 --- a/intern/cycles/scene/osl.cpp +++ b/intern/cycles/scene/osl.cpp @@ -1241,6 +1241,7 @@ void OSLCompiler::compile(OSLGlobals *og, Shader *shader) shader->has_surface = false; shader->has_surface_transparent = false; + shader->has_surface_raytrace = false; shader->has_surface_bssrdf = false; shader->has_bump = has_bump; shader->has_bssrdf_bump = has_bump; From b67b84bd5d6dea88a8941abe4205556a4a74f549 Mon Sep 17 00:00:00 2001 From: Michael Kowalski Date: Fri, 27 Jan 2023 10:29:58 -0500 Subject: [PATCH 0991/1522] Fix T103984: USD exports pass usdchecker These changes were authored by Michael B Johnson (drwave). The default Blender USD export currently produces files that trigger errors in the usdchecker that ships with USD 22.11. The changes are: - Set the defaultPrim if no defaultPrim is set. This sets it to the first prim in the hierarchy which matches the behaviour of Pixar's referencing (where referencing a USD layer without a defaultPrim will pick the first prim) as well as matches the logic in Pixar's Maya USD exporter code. - Applies the MaterialBindingAPI to prims with material binding attributes. This is a relatively new requirement for USD as it will help for efficiency with upcoming changes to Hydra. - Removes the preview scope in the USD shader hierarchy, because it is no longer valid for shaders to have any non-container ancestors in their hierarchy up until the enclosing Material prim. Reviewed by: Michael Kowalski Differential Revision: https://developer.blender.org/D17041 --- source/blender/io/usd/intern/usd_capi_export.cc | 13 +++++++++++++ .../io/usd/intern/usd_writer_material.cc | 10 ++-------- source/blender/io/usd/intern/usd_writer_mesh.cc | 17 ++++++++++++++--- source/blender/io/usd/tests/usd_export_test.cc | 4 ++-- 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/source/blender/io/usd/intern/usd_capi_export.cc b/source/blender/io/usd/intern/usd_capi_export.cc index 1d33ca3a13c..7ab244f18f0 100644 --- a/source/blender/io/usd/intern/usd_capi_export.cc +++ b/source/blender/io/usd/intern/usd_capi_export.cc @@ -7,6 +7,8 @@ #include #include +#include +#include #include #include @@ -138,6 +140,17 @@ static void export_startjob(void *customdata, } iter.release_writers(); + + /* Set the default prim if it doesn't exist */ + if (!usd_stage->GetDefaultPrim()) { + /* Use TraverseAll since it's guaranteed to be depth first and will get the first top level + * prim, and is less verbose than getting the PseudoRoot + iterating its children.*/ + for (auto prim : usd_stage->TraverseAll()) { + usd_stage->SetDefaultPrim(prim); + break; + } + } + usd_stage->GetRootLayer()->Save(); /* Finish up by going back to the keyframe that was current before we started. */ diff --git a/source/blender/io/usd/intern/usd_writer_material.cc b/source/blender/io/usd/intern/usd_writer_material.cc index 7e744b74f61..3e2f34b1b1e 100644 --- a/source/blender/io/usd/intern/usd_writer_material.cc +++ b/source/blender/io/usd/intern/usd_writer_material.cc @@ -60,7 +60,6 @@ static const pxr::TfToken out("out", pxr::TfToken::Immortal); static const pxr::TfToken normal("normal", pxr::TfToken::Immortal); static const pxr::TfToken ior("ior", pxr::TfToken::Immortal); static const pxr::TfToken file("file", pxr::TfToken::Immortal); -static const pxr::TfToken preview("preview", pxr::TfToken::Immortal); static const pxr::TfToken raw("raw", pxr::TfToken::Immortal); static const pxr::TfToken sRGB("sRGB", pxr::TfToken::Immortal); static const pxr::TfToken sourceColorSpace("sourceColorSpace", pxr::TfToken::Immortal); @@ -124,10 +123,6 @@ void create_usd_preview_surface_material(const USDExporterContext &usd_export_co return; } - /* Define a 'preview' scope beneath the material which will contain the preview shaders. */ - pxr::UsdGeomScope::Define(usd_export_context.stage, - usd_material.GetPath().AppendChild(usdtokens::preview)); - /* Default map when creating UV primvar reader shaders. */ pxr::TfToken default_uv_sampler = default_uv.empty() ? cyclestokens::UVMap : pxr::TfToken(default_uv); @@ -470,9 +465,8 @@ static pxr::UsdShadeShader create_usd_preview_shader(const USDExporterContext &u const char *name, const int type) { - pxr::SdfPath shader_path = material.GetPath() - .AppendChild(usdtokens::preview) - .AppendChild(pxr::TfToken(pxr::TfMakeValidIdentifier(name))); + pxr::SdfPath shader_path = material.GetPath().AppendChild( + pxr::TfToken(pxr::TfMakeValidIdentifier(name))); pxr::UsdShadeShader shader = pxr::UsdShadeShader::Define(usd_export_context.stage, shader_path); switch (type) { diff --git a/source/blender/io/usd/intern/usd_writer_mesh.cc b/source/blender/io/usd/intern/usd_writer_mesh.cc index 7f3444d88f4..62656c902d0 100644 --- a/source/blender/io/usd/intern/usd_writer_mesh.cc +++ b/source/blender/io/usd/intern/usd_writer_mesh.cc @@ -350,7 +350,8 @@ void USDGenericMeshWriter::assign_materials(const HierarchyContext &context, * which is why we always bind the first material to the entire mesh. See * https://github.com/PixarAnimationStudios/USD/issues/542 for more info. */ bool mesh_material_bound = false; - pxr::UsdShadeMaterialBindingAPI material_binding_api(usd_mesh.GetPrim()); + auto mesh_prim = usd_mesh.GetPrim(); + pxr::UsdShadeMaterialBindingAPI material_binding_api(mesh_prim); for (int mat_num = 0; mat_num < context.object->totcol; mat_num++) { Material *material = BKE_object_material_get(context.object, mat_num + 1); if (material == nullptr) { @@ -369,7 +370,13 @@ void USDGenericMeshWriter::assign_materials(const HierarchyContext &context, break; } - if (!mesh_material_bound) { + if (mesh_material_bound) { + /* USD will require that prims with material bindings have the MaterialBindingAPI applied + * schema. While Bind() above will create the binding attribute, Apply() needs to be called as + * well to add the MaterialBindingAPI schema to the prim itself.*/ + material_binding_api.Apply(mesh_prim); + } + else { /* Blender defaults to double-sided, but USD to single-sided. */ usd_mesh.CreateDoubleSidedAttr(pxr::VtValue(true)); } @@ -396,7 +403,11 @@ void USDGenericMeshWriter::assign_materials(const HierarchyContext &context, pxr::UsdGeomSubset usd_face_subset = material_binding_api.CreateMaterialBindSubset( material_name, face_indices); - pxr::UsdShadeMaterialBindingAPI(usd_face_subset.GetPrim()).Bind(usd_material); + auto subset_prim = usd_face_subset.GetPrim(); + auto subset_material_api = pxr::UsdShadeMaterialBindingAPI(subset_prim); + subset_material_api.Bind(usd_material); + /* Apply the MaterialBindingAPI applied schema, as required by USD.*/ + subset_material_api.Apply(subset_prim); } } diff --git a/source/blender/io/usd/tests/usd_export_test.cc b/source/blender/io/usd/tests/usd_export_test.cc index c34ab7cd6f7..36ff45ccf7a 100644 --- a/source/blender/io/usd/tests/usd_export_test.cc +++ b/source/blender/io/usd/tests/usd_export_test.cc @@ -294,7 +294,7 @@ TEST_F(UsdExportTest, usd_export_material) const std::string prim_name = pxr::TfMakeValidIdentifier(bsdf_node->name); const pxr::UsdPrim bsdf_prim = stage->GetPrimAtPath( - pxr::SdfPath("/_materials/Material/preview/" + prim_name)); + pxr::SdfPath("/_materials/Material/" + prim_name)); compare_blender_node_to_usd_prim(bsdf_node, bsdf_prim); @@ -305,7 +305,7 @@ TEST_F(UsdExportTest, usd_export_material) const std::string image_prim_name = pxr::TfMakeValidIdentifier(image_node->name); const pxr::UsdPrim image_prim = stage->GetPrimAtPath( - pxr::SdfPath("/_materials/Material/preview/" + image_prim_name)); + pxr::SdfPath("/_materials/Material/" + image_prim_name)); ASSERT_TRUE(bool(image_prim)) << "Unable to find Material prim from exported stage " << output_filename; From e99ae0a75d7294fc29733636a5401addd845d1a5 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 27 Jan 2023 16:57:59 +0100 Subject: [PATCH 0992/1522] Vulkan: Tweaks to CMake configuration. MoltenVK wasn't found as it was previous part of lib/vulkan. as lib/vulkan now doesn't contain the full sdk, we will use a moltenvk folder. At this moment the moltenvk folder isn't filled, but will eventually be. --- build_files/cmake/Modules/FindMoltenVK.cmake | 2 +- build_files/cmake/platform/platform_apple.cmake | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/build_files/cmake/Modules/FindMoltenVK.cmake b/build_files/cmake/Modules/FindMoltenVK.cmake index aaaa6bcd87c..eea7d25819a 100644 --- a/build_files/cmake/Modules/FindMoltenVK.cmake +++ b/build_files/cmake/Modules/FindMoltenVK.cmake @@ -24,7 +24,7 @@ SET(_moltenvk_SEARCH_DIRS # FIXME: These finder modules typically don't use LIBDIR, # this should be set by `./build_files/cmake/platform/` instead. IF(DEFINED LIBDIR) - SET(_moltenvk_SEARCH_DIRS ${_moltenvk_SEARCH_DIRS} ${LIBDIR}/vulkan/MoltenVK) + SET(_moltenvk_SEARCH_DIRS ${_moltenvk_SEARCH_DIRS} ${LIBDIR}/moltenvk) ENDIF() FIND_PATH(MOLTENVK_INCLUDE_DIR diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index e9e07229b2d..09f9d79a6cf 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -100,12 +100,14 @@ if(WITH_VULKAN_BACKEND) if(EXISTS ${LIBDIR}/vulkan) set(VULKAN_FOUND On) - set(VULKAN_ROOT_DIR ${LIBDIR}/vulkan/macOS) + set(VULKAN_ROOT_DIR ${LIBDIR}/vulkan) set(VULKAN_INCLUDE_DIR ${VULKAN_ROOT_DIR}/include) - set(VULKAN_LIBRARY ${VULKAN_ROOT_DIR}/lib/libvulkan.1.dylib) - set(SHADERC_LIBRARY ${VULKAN_ROOT_DIR}/lib/libshaderc_combined.a) + set(VULKAN_LIBRARY ${VULKAN_ROOT_DIR}/lib/libvulkan.dylib) + set(SHADERC_ROOT_DIR ${LIBDIR}/shaderc) + set(SHADERC_INCLUDE_DIR ${SHADERC_ROOT_DIR}/include) + set(SHADERC_LIBRARY ${SHADERC_ROOT_DIR}/lib/libshaderc_combined.a) - set(VULKAN_INCLUDE_DIRS ${VULKAN_INCLUDE_DIR} ${MOLTENVK_INCLUDE_DIRS}) + set(VULKAN_INCLUDE_DIRS ${VULKAN_INCLUDE_DIR} ${SHADERC_INCLUDE_DIR} ${MOLTENVK_INCLUDE_DIRS}) set(VULKAN_LIBRARIES ${VULKAN_LIBRARY} ${SHADERC_LIBRARY} ${MOLTENVK_LIBRARIES}) else() message(WARNING "Vulkan SDK was not found, disabling WITH_VULKAN_BACKEND") From 000e722c7d99320ce51d1487147a2f275ae44b16 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 27 Jan 2023 09:44:30 -0600 Subject: [PATCH 0993/1522] Geometry Nodes: Optimize start point case of Points of Curve node In the node groups for T103730, the "Points of Curve" node is often used to retrieve the root point of every curve. Since the curve point offsets array already contains that data directly, we can detect this as a special case and avoid all the other work. Differential Revision: https://developer.blender.org/D17128 --- ...node_geo_curve_topology_points_of_curve.cc | 66 +++++++++++++++++-- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc index 8d9e4a07a76..820fa4856a4 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc @@ -174,6 +174,57 @@ class CurvePointCountInput final : public bke::CurvesFieldInput { } }; +/** + * The node is often used to retrieve the root point of the curve. If the curve indices are in + * order, the sort weights have no effect, and the sort index is the first point, then we can just + * return the curve offsets as a span directly. + */ +static bool use_start_point_special_case(const Field &curve_index, + const Field &sort_index, + const Field &sort_weights) +{ + if (!dynamic_cast(&curve_index.node())) { + return false; + } + if (sort_index.node().depends_on_input() || sort_weights.node().depends_on_input()) { + return false; + } + return fn::evaluate_constant_field(sort_index) == 0; +} + +class CurveStartPointInput final : public bke::CurvesFieldInput { + public: + CurveStartPointInput() : bke::CurvesFieldInput(CPPType::get(), "Point of Curve") + { + category_ = Category::Generated; + } + + GVArray get_varray_for_context(const bke::CurvesGeometry &curves, + const eAttrDomain /*domain*/, + const IndexMask /*mask*/) const final + { + return VArray::ForSpan(curves.offsets()); + } + + uint64_t hash() const final + { + return 2938459815345; + } + + bool is_equal_to(const fn::FieldNode &other) const final + { + if (dynamic_cast(&other)) { + return true; + } + return false; + } + + std::optional preferred_domain(const bke::CurvesGeometry & /*curves*/) + { + return ATTR_DOMAIN_CURVE; + } +}; + static void node_geo_exec(GeoNodeExecParams params) { const Field curve_index = params.extract_input>("Curve Index"); @@ -185,11 +236,16 @@ static void node_geo_exec(GeoNodeExecParams params) ATTR_DOMAIN_CURVE))); } if (params.output_is_required("Point Index")) { - params.set_output("Point Index", - Field(std::make_shared( - curve_index, - params.extract_input>("Sort Index"), - params.extract_input>("Weights")))); + Field sort_index = params.extract_input>("Sort Index"); + Field sort_weight = params.extract_input>("Weights"); + if (use_start_point_special_case(curve_index, sort_index, sort_weight)) { + params.set_output("Point Index", Field(std::make_shared())); + } + else { + params.set_output("Point Index", + Field(std::make_shared( + curve_index, std::move(sort_index), std::move(sort_weight)))); + } } } From 179605bd2dab1df3339ef6b625fd38f8bee84914 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 27 Jan 2023 09:56:14 -0600 Subject: [PATCH 0994/1522] Fix T104168: No active UV when reading auto-save files Similar to 6d12d43a054898bbffb, we should skip the legacy to generic conversion if there's nothing to convert. --- source/blender/blenkernel/intern/mesh_legacy_convert.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/blender/blenkernel/intern/mesh_legacy_convert.cc b/source/blender/blenkernel/intern/mesh_legacy_convert.cc index a60dfa3a19c..4926be66d27 100644 --- a/source/blender/blenkernel/intern/mesh_legacy_convert.cc +++ b/source/blender/blenkernel/intern/mesh_legacy_convert.cc @@ -1608,6 +1608,9 @@ void BKE_mesh_legacy_convert_uvs_to_generic(Mesh *mesh) { using namespace blender; using namespace blender::bke; + if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) { + return; + } /* Store layer names since they will be removed, used to set the active status of new layers. * Use intermediate #StringRef because the names can be null. */ From 8343e841fd5ef48a5a8ac85e74e67bf8acefd7ee Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 27 Jan 2023 09:59:38 -0600 Subject: [PATCH 0995/1522] Cleanup: Quiet unused variable warning in non-debug builds --- source/blender/blenloader/intern/readfile.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index a007daa0e82..f773f17dc2b 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -3793,6 +3793,7 @@ static void blo_read_file_checks(Main *bmain) } } #endif + UNUSED_VARS_NDEBUG(bmain); } BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) From 0050d6d39906649159a3d8f0bb95b3fc60dd2da7 Mon Sep 17 00:00:00 2001 From: Germano Cavalcante Date: Fri, 27 Jan 2023 14:10:43 -0300 Subject: [PATCH 0996/1522] Cleanup: move function to file where it is used `drawLine` is only used for constraint, so it should be in `transform_constraints.c` --- source/blender/editors/transform/transform.h | 2 - .../editors/transform/transform_constraints.c | 55 +++++++++++++++++++ .../editors/transform/transform_generics.c | 54 ------------------ 3 files changed, 55 insertions(+), 56 deletions(-) diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 637e4ef3b6e..82ab9039db5 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -809,8 +809,6 @@ void postTrans(struct bContext *C, TransInfo *t); void resetTransModal(TransInfo *t); void resetTransRestrictions(TransInfo *t); -void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis, short options); - /* DRAWLINE options flags */ #define DRAWLIGHT 1 diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c index f8e116e77b8..095c59f783b 100644 --- a/source/blender/editors/transform/transform_constraints.c +++ b/source/blender/editors/transform/transform_constraints.c @@ -735,6 +735,61 @@ void setUserConstraint(TransInfo *t, int mode, const char text_[]) /** \name Drawing Constraints * \{ */ +static void drawLine( + TransInfo *t, const float center[3], const float dir[3], char axis, short options) +{ + if (!ELEM(t->spacetype, SPACE_VIEW3D, SPACE_SEQ)) { + return; + } + + float v1[3], v2[3], v3[3]; + uchar col[3], col2[3]; + + if (t->spacetype == SPACE_VIEW3D) { + View3D *v3d = t->view; + + copy_v3_v3(v3, dir); + mul_v3_fl(v3, v3d->clip_end); + + sub_v3_v3v3(v2, center, v3); + add_v3_v3v3(v1, center, v3); + } + else if (t->spacetype == SPACE_SEQ) { + View2D *v2d = t->view; + + copy_v3_v3(v3, dir); + float max_dist = max_ff(BLI_rctf_size_x(&v2d->cur), BLI_rctf_size_y(&v2d->cur)); + mul_v3_fl(v3, max_dist); + + sub_v3_v3v3(v2, center, v3); + add_v3_v3v3(v1, center, v3); + } + + GPU_matrix_push(); + + if (options & DRAWLIGHT) { + col[0] = col[1] = col[2] = 220; + } + else { + UI_GetThemeColor3ubv(TH_GRID, col); + } + UI_make_axis_color(col, col2, axis); + + uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + + immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); + immUniformColor3ubv(col2); + + immBegin(GPU_PRIM_LINES, 2); + immVertex3fv(pos, v1); + immVertex3fv(pos, v2); + immEnd(); + + immUnbindProgram(); + + GPU_matrix_pop(); +} + void drawConstraint(TransInfo *t) { TransCon *tc = &(t->con); diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index f09c919c8b7..53e346ee86a 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -55,60 +55,6 @@ /* ************************** GENERICS **************************** */ -void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis, short options) -{ - if (!ELEM(t->spacetype, SPACE_VIEW3D, SPACE_SEQ)) { - return; - } - - float v1[3], v2[3], v3[3]; - uchar col[3], col2[3]; - - if (t->spacetype == SPACE_VIEW3D) { - View3D *v3d = t->view; - - copy_v3_v3(v3, dir); - mul_v3_fl(v3, v3d->clip_end); - - sub_v3_v3v3(v2, center, v3); - add_v3_v3v3(v1, center, v3); - } - else if (t->spacetype == SPACE_SEQ) { - View2D *v2d = t->view; - - copy_v3_v3(v3, dir); - float max_dist = max_ff(BLI_rctf_size_x(&v2d->cur), BLI_rctf_size_y(&v2d->cur)); - mul_v3_fl(v3, max_dist); - - sub_v3_v3v3(v2, center, v3); - add_v3_v3v3(v1, center, v3); - } - - GPU_matrix_push(); - - if (options & DRAWLIGHT) { - col[0] = col[1] = col[2] = 220; - } - else { - UI_GetThemeColor3ubv(TH_GRID, col); - } - UI_make_axis_color(col, col2, axis); - - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - - immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); - immUniformColor3ubv(col2); - - immBegin(GPU_PRIM_LINES, 2); - immVertex3fv(pos, v1); - immVertex3fv(pos, v2); - immEnd(); - - immUnbindProgram(); - - GPU_matrix_pop(); -} - void resetTransModal(TransInfo *t) { freeTransCustomDataForMode(t); From f5e76aa39e3ff40a4c85e79ff70e8e6b02fcfaa7 Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 27 Jan 2023 11:33:40 -0600 Subject: [PATCH 0997/1522] Cleanup: Array types, const, math API in workbench code Some miscellaneous cleanups left over from a fix/cleanup combo: - Use const variables - Use the C++ `math` namespace functions - Use `std::array` for arrays with size known at compile time - Use `MutableSpan` instead of reference to array Differential Revision: https://developer.blender.org/D17094 --- .../workbench_effect_antialiasing.cc | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.cc b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.cc index 75be8279037..e00d67d4d0f 100644 --- a/source/blender/draw/engines/workbench/workbench_effect_antialiasing.cc +++ b/source/blender/draw/engines/workbench/workbench_effect_antialiasing.cc @@ -8,25 +8,23 @@ namespace blender::workbench { class TaaSamples { - void init_samples(Array &samples, const int size) + void init_samples(MutableSpan samples) { - samples = Array(size); - BLI_jitter_init((float(*)[2])samples.begin(), size); + BLI_jitter_init(reinterpret_cast(samples.data()), samples.size()); /* Find closest element to center */ int closest_index = 0; float closest_squared_distance = 1.0f; - for (int i : samples.index_range()) { - float2 sample = samples[i]; - const float squared_dist = len_squared_v2(sample); + const float2 sample = samples[i]; + const float squared_dist = math::length_squared(sample); if (squared_dist < closest_squared_distance) { closest_squared_distance = squared_dist; closest_index = i; } } - float2 closest_sample = samples[closest_index]; + const float2 closest_sample = samples[closest_index]; for (float2 &sample : samples) { /* Move jitter samples so that closest sample is in center */ @@ -43,11 +41,11 @@ class TaaSamples { } /* Sort list based on farthest distance with previous. */ - for (int i = 0; i < size - 2; i++) { + for (int i = 0; i < samples.size() - 2; i++) { float squared_dist = 0.0; int index = i; - for (int j = i + 1; j < size; j++) { - const float _squared_dist = len_squared_v2(samples[i] - samples[j]); + for (int j = i + 1; j < samples.size(); j++) { + const float _squared_dist = math::length_squared(samples[i] - samples[j]); if (_squared_dist > squared_dist) { squared_dist = _squared_dist; index = j; @@ -58,19 +56,19 @@ class TaaSamples { } public: - Array x5; - Array x8; - Array x11; - Array x16; - Array x32; + std::array x5; + std::array x8; + std::array x11; + std::array x16; + std::array x32; TaaSamples() { - init_samples(x5, 5); - init_samples(x8, 8); - init_samples(x11, 11); - init_samples(x16, 16); - init_samples(x32, 32); + init_samples(x5); + init_samples(x8); + init_samples(x11); + init_samples(x16); + init_samples(x32); } }; From 328772f2d90ec7f98cf724dd832a1c211bb4b5eb Mon Sep 17 00:00:00 2001 From: Colin Basnett Date: Fri, 27 Jan 2023 11:00:36 -0800 Subject: [PATCH 0998/1522] Mesh: Add operator to flip quad tessellation This adds a new operator: bpy.ops.mesh.flip_quad_tessellation() This operator rotates the internal loops of the selected quads, allowing the user to control tessellation without destructively altering the mesh. {F14201995} This operator can be found in the "Face" menu (Ctrl+F) under "Face Data". {F14201997} Reviewed By: campbellbarton, dbystedt Differential Revision: https://developer.blender.org/D17056 --- release/scripts/startup/bl_ui/space_view3d.py | 3 ++ source/blender/bmesh/intern/bmesh_opdefines.c | 18 +++++++ .../bmesh/intern/bmesh_operators_private.h | 1 + source/blender/bmesh/intern/bmesh_polygon.h | 1 + source/blender/bmesh/operators/bmo_utils.c | 16 +++++++ source/blender/editors/mesh/editmesh_tools.c | 47 +++++++++++++++++++ source/blender/editors/mesh/mesh_intern.h | 1 + source/blender/editors/mesh/mesh_ops.c | 1 + 8 files changed, 88 insertions(+) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index c66acb0509f..cccb5389037 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -4274,7 +4274,10 @@ class VIEW3D_MT_edit_mesh_faces_data(Menu): layout.separator() + layout.operator("mesh.flip_quad_tessellation") + if with_freestyle: + layout.separator() layout.operator("mesh.mark_freestyle_face").clear = False layout.operator("mesh.mark_freestyle_face", text="Clear Freestyle Face").clear = True diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 0ffb3f6652e..4e0df875740 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -270,6 +270,23 @@ static BMOpDefine bmo_reverse_faces_def = { BMO_OPTYPE_FLAG_NORMALS_CALC), }; +/* + * Flip Quad Tessellation + * + * Flip the tessellation direction of the selected quads. +*/ +static BMOpDefine bmo_flip_quad_tessellation_def = { + "flip_quad_tessellation", + /* slot_in */ + { + {"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, + {{'\0'}} + }, + {{{'\0'}}}, /* no output */ + bmo_flip_quad_tessellation_exec, + (BMO_OPTYPE_FLAG_UNTAN_MULTIRES | BMO_OPTYPE_FLAG_NORMALS_CALC), +}; + /* * Edge Bisect. * @@ -2128,6 +2145,7 @@ const BMOpDefine *bmo_opdefines[] = { &bmo_extrude_face_region_def, &bmo_extrude_vert_indiv_def, &bmo_find_doubles_def, + &bmo_flip_quad_tessellation_def, &bmo_grid_fill_def, &bmo_inset_individual_def, &bmo_inset_region_def, diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h index 0f628c04d98..3562b4da71a 100644 --- a/source/blender/bmesh/intern/bmesh_operators_private.h +++ b/source/blender/bmesh/intern/bmesh_operators_private.h @@ -88,3 +88,4 @@ void bmo_triangulate_exec(BMesh *bm, BMOperator *op); void bmo_unsubdivide_exec(BMesh *bm, BMOperator *op); void bmo_weld_verts_exec(BMesh *bm, BMOperator *op); void bmo_wireframe_exec(BMesh *bm, BMOperator *op); +void bmo_flip_quad_tessellation_exec(BMesh *bm, BMOperator *op); diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index bff1d1d587d..5ca7c3bafaf 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -177,6 +177,7 @@ void BM_face_normal_flip_ex(BMesh *bm, int cd_loop_mdisp_offset, bool use_loop_mdisp_flip) ATTR_NONNULL(); void BM_face_normal_flip(BMesh *bm, BMFace *f) ATTR_NONNULL(); + /** * BM POINT IN FACE * diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index a821fa2b744..8d4ba5c11f8 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -147,6 +147,22 @@ void bmo_reverse_faces_exec(BMesh *bm, BMOperator *op) #define SEL_FLAG 1 #define SEL_ORIG 2 +void bmo_flip_quad_tessellation_exec(BMesh *bm, BMOperator *op) +{ + BMOIter siter; + BMFace *f; + bool changed = false; + BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) { + if (f->len == 4) { + f->l_first = f->l_first->next; + changed = true; + } + } + if (changed) { + bm->elem_index_dirty |= BM_LOOP; + } +} + static void bmo_face_flag_set_flush(BMesh *bm, BMFace *f, const short oflag, const bool value) { BMLoop *l_iter; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 620d6c2ea5e..f5c4bf6facc 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -2227,6 +2227,18 @@ static void edbm_flip_normals_custom_loop_normals(Object *obedit, BMEditMesh *em }); } +static void edbm_flip_quad_tessellation(wmOperator *op, Object *obedit, BMEditMesh *em) +{ + if (EDBM_op_callf(em, op, "flip_quad_tessellation faces=%hf", BM_ELEM_SELECT)) { + EDBM_update(obedit->data, + &(const struct EDBMUpdate_Params){ + .calc_looptri = true, + .calc_normals = false, + .is_destructive = false, + }); + } +} + static void edbm_flip_normals_face_winding(wmOperator *op, Object *obedit, BMEditMesh *em) { @@ -2253,6 +2265,27 @@ static void edbm_flip_normals_face_winding(wmOperator *op, Object *obedit, BMEdi } } +static int edbm_flip_quad_tessellation_exec(bContext *C, wmOperator *op) +{ + const Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data( + scene, view_layer, CTX_wm_view3d(C), &objects_len); + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + if (em->bm->totfacesel == 0) { + continue; + } + edbm_flip_quad_tessellation(op, obedit, em); + } + + MEM_freeN(objects); + return OPERATOR_FINISHED; +} + static int edbm_flip_normals_exec(bContext *C, wmOperator *op) { const bool only_clnors = RNA_boolean_get(op->ptr, "only_clnors"); @@ -9934,4 +9967,18 @@ void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot) "Strength to use for assigning or selecting face influence for weighted normal modifier"); } +void MESH_OT_flip_quad_tessellation(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Flip Quad Tessellation"; + ot->description = "Flips the tessellation of selected quads"; + ot->idname = "MESH_OT_flip_quad_tessellation"; + + ot->exec = edbm_flip_quad_tessellation_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /** \} */ diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 0e20bb18595..7386fe69b6c 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -294,6 +294,7 @@ void MESH_OT_set_normals_from_faces(struct wmOperatorType *ot); void MESH_OT_average_normals(struct wmOperatorType *ot); void MESH_OT_smooth_normals(struct wmOperatorType *ot); void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot); +void MESH_OT_flip_quad_tessellation(struct wmOperatorType *ot); /* *** editmesh_mask_extract.c *** */ diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index c3c3abd46a1..b9afeae275b 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -193,6 +193,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_average_normals); WM_operatortype_append(MESH_OT_smooth_normals); WM_operatortype_append(MESH_OT_mod_weighted_strength); + WM_operatortype_append(MESH_OT_flip_quad_tessellation); } #if 0 /* UNUSED, remove? */ From 9facc5067af9975f923d17993de15ddebbb5458a Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Fri, 27 Jan 2023 14:07:48 -0600 Subject: [PATCH 0999/1522] Cleanup: Simplify mesh and point cloud conversion Since mesh positions are stored as a generic attribute, the attribute doesn't need special handling here. --- source/blender/blenkernel/BKE_mesh.h | 2 +- .../blender/blenkernel/intern/mesh_convert.cc | 25 ++----------------- 2 files changed, 3 insertions(+), 24 deletions(-) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 557b70b8a11..c9928b9c4d6 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -212,7 +212,7 @@ void BKE_mesh_to_curve(struct Main *bmain, struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob); -void BKE_pointcloud_from_mesh(struct Mesh *me, struct PointCloud *pointcloud); +void BKE_pointcloud_from_mesh(const struct Mesh *me, struct PointCloud *pointcloud); void BKE_mesh_to_pointcloud(struct Main *bmain, struct Depsgraph *depsgraph, struct Scene *scene, diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc index ffc3365b908..d9a84e98326 100644 --- a/source/blender/blenkernel/intern/mesh_convert.cc +++ b/source/blender/blenkernel/intern/mesh_convert.cc @@ -627,29 +627,11 @@ void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/, Obj } } -void BKE_pointcloud_from_mesh(Mesh *me, PointCloud *pointcloud) +void BKE_pointcloud_from_mesh(const Mesh *me, PointCloud *pointcloud) { - using namespace blender; - - BLI_assert(me != nullptr); - /* The pointcloud should only contain the position attribute, otherwise more attributes would - * need to be initialized below. */ - BLI_assert(pointcloud->attributes().all_ids().size() == 1); - CustomData_realloc(&pointcloud->pdata, pointcloud->totpoint, me->totvert); + CustomData_free(&pointcloud->pdata, pointcloud->totpoint); pointcloud->totpoint = me->totvert; - - /* Copy over all attributes. */ CustomData_merge(&me->vdata, &pointcloud->pdata, CD_MASK_PROP_ALL, CD_DUPLICATE, me->totvert); - - bke::AttributeAccessor mesh_attributes = me->attributes(); - bke::MutableAttributeAccessor point_attributes = pointcloud->attributes_for_write(); - - const VArray vert_positions = mesh_attributes.lookup_or_default( - "position", ATTR_DOMAIN_POINT, float3(0)); - bke::SpanAttributeWriter point_positions = - point_attributes.lookup_or_add_for_write_only_span("position", ATTR_DOMAIN_POINT); - vert_positions.materialize(point_positions.span); - point_positions.finish(); } void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/, Object *ob) @@ -675,10 +657,7 @@ void BKE_mesh_to_pointcloud(Main *bmain, Depsgraph *depsgraph, Scene * /*scene*/ void BKE_mesh_from_pointcloud(const PointCloud *pointcloud, Mesh *me) { - BLI_assert(pointcloud != nullptr); - me->totvert = pointcloud->totpoint; - CustomData_merge( &pointcloud->pdata, &me->vdata, CD_MASK_PROP_ALL, CD_DUPLICATE, pointcloud->totpoint); } From 8336de03a685a177489b38f9e83055b87f1d13ec Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Fri, 27 Jan 2023 22:42:41 +0100 Subject: [PATCH 1000/1522] Cleanup: VSE: use `context->for_render` instead of `G.is_rendering` --- source/blender/sequencer/intern/render.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/sequencer/intern/render.c b/source/blender/sequencer/intern/render.c index 7f73a32a9c3..65ba8bf48fe 100644 --- a/source/blender/sequencer/intern/render.c +++ b/source/blender/sequencer/intern/render.c @@ -529,7 +529,7 @@ static void sequencer_preprocess_transform_crop( break; case SEQ_TRANSFORM_FILTER_NEAREST_3x3: filter = IMB_FILTER_NEAREST; - num_subsamples = G.is_rendering ? 3 : 1; + num_subsamples = context->for_render ? 3 : 1; break; } From cef03c867b050523bc374f28d3973ba0ca0038da Mon Sep 17 00:00:00 2001 From: Chris Blackbourn Date: Sat, 28 Jan 2023 10:50:59 +1300 Subject: [PATCH 1001/1522] UV: cleanup winding Simplify `BM_uv_element_map_create` by using `BM_face_calc_area_uv_signed`. Remove unused UV winding code in `BM_uv_vert_map_create`. Fixes unlikely memory leak in `BKE_mesh_uv_vert_map_create`. No functional changes. Differential Revision: https://developer.blender.org/D17137 --- .../blender/blenkernel/intern/mesh_mapping.cc | 9 ++-- source/blender/editors/include/ED_mesh.h | 2 +- source/blender/editors/mesh/editmesh_utils.c | 47 ++----------------- source/blender/editors/uvedit/uvedit_select.c | 13 ++--- 4 files changed, 13 insertions(+), 58 deletions(-) diff --git a/source/blender/blenkernel/intern/mesh_mapping.cc b/source/blender/blenkernel/intern/mesh_mapping.cc index 15bdf58849a..32c8638fbcf 100644 --- a/source/blender/blenkernel/intern/mesh_mapping.cc +++ b/source/blender/blenkernel/intern/mesh_mapping.cc @@ -47,7 +47,6 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly, uint a; int i, totuv, nverts; - bool *winding = nullptr; BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, 32); totuv = 0; @@ -67,15 +66,17 @@ UvVertMap *BKE_mesh_uv_vert_map_create(const MPoly *mpoly, vmap = (UvVertMap *)MEM_callocN(sizeof(*vmap), "UvVertMap"); buf = vmap->buf = (UvMapVert *)MEM_callocN(sizeof(*vmap->buf) * size_t(totuv), "UvMapVert"); vmap->vert = (UvMapVert **)MEM_callocN(sizeof(*vmap->vert) * totvert, "UvMapVert*"); - if (use_winding) { - winding = static_cast(MEM_callocN(sizeof(*winding) * totpoly, "winding")); - } if (!vmap->vert || !vmap->buf) { BKE_mesh_uv_vert_map_free(vmap); return nullptr; } + bool *winding = nullptr; + if (use_winding) { + winding = static_cast(MEM_callocN(sizeof(*winding) * totpoly, "winding")); + } + mp = mpoly; for (a = 0; a < totpoly; a++, mp++) { if (!selected || (!(hide_poly && hide_poly[a]) && (select_poly && select_poly[a]))) { diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 8ab6e31bef3..70e553abb50 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -167,7 +167,7 @@ struct UvMapVert *BM_uv_vert_map_at_index(struct UvVertMap *vmap, unsigned int v /** * Return a new #UvVertMap from the edit-mesh. */ -struct UvVertMap *BM_uv_vert_map_create(struct BMesh *bm, bool use_select, bool use_winding); +struct UvVertMap *BM_uv_vert_map_create(struct BMesh *bm, bool use_select); void EDBM_flag_enable_all(struct BMEditMesh *em, char hflag); void EDBM_flag_disable_all(struct BMEditMesh *em, char hflag); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index c0815257afa..a2343bb297e 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -444,7 +444,7 @@ void EDBM_flag_enable_all(BMEditMesh *em, const char hflag) /** \name UV Vertex Map API * \{ */ -UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool use_winding) +UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select) { BMVert *ev; BMFace *efa; @@ -452,7 +452,6 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us BMIter iter, liter; uint a; const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2); - BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE); BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE); @@ -478,11 +477,6 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us vmap->vert = (UvMapVert **)MEM_callocN(sizeof(*vmap->vert) * totverts, "UvMapVert_pt"); UvMapVert *buf = vmap->buf = (UvMapVert *)MEM_callocN(sizeof(*vmap->buf) * totuv, "UvMapVert"); - bool *winding = NULL; - if (use_winding) { - winding = MEM_callocN(sizeof(*winding) * totfaces, "winding"); - } - if (!vmap->vert || !vmap->buf) { BKE_mesh_uv_vert_map_free(vmap); return NULL; @@ -490,12 +484,6 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, a) { if ((use_select == false) || BM_elem_flag_test(efa, BM_ELEM_SELECT)) { - float(*tf_uv)[2] = NULL; - - if (use_winding) { - tf_uv = (float(*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa->len); - } - int i; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { buf->loop_of_poly_index = i; @@ -505,15 +493,6 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us buf->next = vmap->vert[BM_elem_index_get(l->v)]; vmap->vert[BM_elem_index_get(l->v)] = buf; buf++; - - if (use_winding) { - const float(*luv)[2] = BM_ELEM_CD_GET_FLOAT2_P(l, cd_loop_uv_offset); - copy_v2_v2(tf_uv[i], *luv); - } - } - - if (use_winding) { - winding[a] = cross_poly_v2(tf_uv, efa->len) > 0; } } } @@ -544,8 +523,7 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us l = BM_iter_at_index(bm, BM_LOOPS_OF_FACE, efa, iterv->loop_of_poly_index); uv2 = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset); - if (compare_v2v2(uv2, uv, STD_UV_CONNECT_LIMIT) && - (!use_winding || winding[iterv->poly_index] == winding[v->poly_index])) { + if (compare_v2v2(uv2, uv, STD_UV_CONNECT_LIMIT)) { if (lastv) { lastv->next = next; } @@ -568,12 +546,6 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select, const bool us vmap->vert[a] = newvlist; } - if (use_winding) { - MEM_freeN(winding); - } - - BLI_buffer_free(&tf_uv_buf); - return vmap; } @@ -1007,7 +979,6 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, BMVert *ev; BMFace *efa; BMIter iter, liter; - BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE); const BMUVOffsets offsets = BM_uv_map_get_offsets(bm); if (offsets.uv < 0) { @@ -1065,12 +1036,6 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, continue; } - float(*tf_uv)[2] = NULL; - - if (use_winding) { - tf_uv = (float(*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa->len); - } - int i; BMLoop *l; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { @@ -1086,19 +1051,13 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, buf->next = element_map->vertex[BM_elem_index_get(l->v)]; element_map->vertex[BM_elem_index_get(l->v)] = buf; - if (use_winding) { - const float *uv = BM_ELEM_CD_GET_FLOAT_P(l, offsets.uv); - copy_v2_v2(tf_uv[i], uv); - } - buf++; } if (winding) { - winding[j] = cross_poly_v2(tf_uv, efa->len) > 0; + winding[j] = BM_face_calc_area_uv_signed(efa, offsets.uv) > 0; } } - BLI_buffer_free(&tf_uv_buf); GSet *seam_visited_gset = use_seams ? BLI_gset_ptr_new(__func__) : NULL; diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index 99ee1ca0002..5ed68690253 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -1786,7 +1786,6 @@ static void uv_select_linked_multi(Scene *scene, BMFace *efa; BMLoop *l; BMIter iter, liter; - UvVertMap *vmap; UvMapVert *vlist, *iterv, *startv; int i, stacksize = 0, *stack; uint a; @@ -1807,8 +1806,7 @@ static void uv_select_linked_multi(Scene *scene, * * Better solve this by having a delimit option for select-linked operator, * keeping island-select working as is. */ - vmap = BM_uv_vert_map_create(em->bm, !uv_sync_select, false); - + UvVertMap *vmap = BM_uv_vert_map_create(em->bm, !uv_sync_select); if (vmap == NULL) { continue; } @@ -3304,11 +3302,10 @@ static void uv_select_flush_from_tag_face(const Scene *scene, Object *obedit, co if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ELEM(ts->uv_sticky, SI_STICKY_VERTEX, SI_STICKY_LOC)) { - struct UvVertMap *vmap; uint efa_index; BM_mesh_elem_table_ensure(em->bm, BM_FACE); - vmap = BM_uv_vert_map_create(em->bm, false, false); + struct UvVertMap *vmap = BM_uv_vert_map_create(em->bm, false); if (vmap == NULL) { return; } @@ -3394,11 +3391,10 @@ static void uv_select_flush_from_tag_loop(const Scene *scene, Object *obedit, co } } else if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ts->uv_sticky == SI_STICKY_LOC) { - struct UvVertMap *vmap; uint efa_index; BM_mesh_elem_table_ensure(em->bm, BM_FACE); - vmap = BM_uv_vert_map_create(em->bm, false, false); + struct UvVertMap *vmap = BM_uv_vert_map_create(em->bm, false); if (vmap == NULL) { return; } @@ -3449,13 +3445,12 @@ static void uv_select_flush_from_loop_edge_flag(const Scene *scene, BMEditMesh * if ((ts->uv_flag & UV_SYNC_SELECTION) == 0 && ELEM(ts->uv_sticky, SI_STICKY_LOC, SI_STICKY_VERTEX)) { /* Use UV edge selection to identify which verts must to be selected */ - struct UvVertMap *vmap; uint efa_index; /* Clear UV vert flags */ bm_clear_uv_vert_selection(scene, em->bm, offsets); BM_mesh_elem_table_ensure(em->bm, BM_FACE); - vmap = BM_uv_vert_map_create(em->bm, false, false); + struct UvVertMap *vmap = BM_uv_vert_map_create(em->bm, false); if (vmap == NULL) { return; } From d7e914270f75b2be68f065aa6f27bb9d60e48511 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Sat, 28 Jan 2023 00:02:51 +0100 Subject: [PATCH 1002/1522] Fix (unreported): Pasted strip is not active Broken by renaming strip before comparing name to reference. --- .../blender/editors/space_sequencer/sequencer_edit.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index a9e31de2096..96f8d2fe269 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2570,17 +2570,16 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) * in the new list. */ BLI_movelisttolist(ed->seqbasep, &nseqbase); - /* Make sure, that pasted strips have unique names. This has to be done immediately after adding - * strips to seqbase, for lookup cache to work correctly. */ - for (iseq = iseq_first; iseq; iseq = iseq->next) { - SEQ_ensure_unique_name(iseq, scene); - } - for (iseq = iseq_first; iseq; iseq = iseq->next) { if (SEQ_clipboard_pasted_seq_was_active(iseq)) { SEQ_select_active_set(scene, iseq); } + /* Make sure, that pasted strips have unique names. This has to be done after + * adding strips to seqbase, for lookup cache to work correctly. */ + SEQ_ensure_unique_name(iseq, scene); + } + for (iseq = iseq_first; iseq; iseq = iseq->next) { /* Translate after name has been changed, otherwise this will affect animdata of original * strip. */ SEQ_transform_translate_sequence(scene, iseq, ofs); From 3a9e5891420d57cb3b40be09c4ad0c711d1ed9e2 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Sat, 28 Jan 2023 00:25:56 +0100 Subject: [PATCH 1003/1522] Fix (Unreported): VSE side panel flickering when tweaking offset value Panel was split by factor calculated from property value string length. Since these properties have float type now, calculated length was incorrect. --- release/scripts/startup/bl_ui/space_sequencer.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index dd6f827e92d..c605ed5f835 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -1845,17 +1845,17 @@ class SEQUENCER_PT_time(SequencerButtonsPanel, Panel): frame_offset_end = strip.frame_offset_end length_list = ( - str(frame_start), - str(frame_final_end), - str(frame_final_duration), - str(frame_offset_start), - str(frame_offset_end), + str(round(frame_start, 0)), + str(round(frame_final_end, 0)), + str(round(frame_final_duration, 0)), + str(round(frame_offset_start, 0)), + str(round(frame_offset_end, 0)), ) if not is_effect: length_list = length_list + ( - str(strip.animation_offset_start), - str(strip.animation_offset_end), + str(round(strip.animation_offset_start, 0)), + str(round(strip.animation_offset_end, 0)), ) max_length = max(len(x) for x in length_list) From 4e9c6929c1d08e41702ac4341d08bf15d7de31b3 Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Sat, 28 Jan 2023 03:24:44 +0100 Subject: [PATCH 1004/1522] VSE: Handle drivers when duplicating strips Most operations where strips are duplicated use `SEQ_animation` API, which handles keyframe animation. Now drivers are handled as well. When group of strips is duplicated and driver references other strip, it will still reference original strip. However, this is much better, than previous behavior, when strip duplication results in "transfer" of driver from original strip to duplicated one. Fixes T104141 --- .../editors/space_sequencer/sequencer_edit.c | 48 +++++++++----- source/blender/sequencer/SEQ_animation.h | 21 ++++-- source/blender/sequencer/SEQ_clipboard.h | 1 + source/blender/sequencer/intern/animation.c | 65 +++++++++++-------- source/blender/sequencer/intern/clipboard.c | 6 ++ source/blender/sequencer/intern/strip_edit.c | 8 +-- 6 files changed, 95 insertions(+), 54 deletions(-) diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 96f8d2fe269..3865aee8327 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1606,8 +1606,8 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) * This way, when pasted strips are renamed, curves are renamed with them. Finally, restore * original curves from backup. */ - ListBase fcurves_original_backup = {NULL, NULL}; - SEQ_animation_backup_original(scene, &fcurves_original_backup); + SeqAnimationBackup animation_backup = {0}; + SEQ_animation_backup_original(scene, &animation_backup); Sequence *seq = duplicated_strips.first; @@ -1623,12 +1623,15 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) } seq->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK); seq->flag |= SEQ_IGNORE_CHANNEL_LOCK; - SEQ_animation_duplicate(scene, seq, &fcurves_original_backup); + + SEQ_animation_duplicate_backup_to_scene(scene, seq, &animation_backup); SEQ_ensure_unique_name(seq, scene); } - SEQ_animation_restore_original(scene, &fcurves_original_backup); + SEQ_animation_restore_original(scene, &animation_backup); + DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); + DEG_relations_tag_update(CTX_data_main(C)); WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene); return OPERATOR_FINISHED; } @@ -2393,33 +2396,41 @@ static void seq_copy_del_sound(Scene *scene, Sequence *seq) } } -static void sequencer_copy_animation(Scene *scene, Sequence *seq) +static void sequencer_copy_animation_listbase(Scene *scene, + Sequence *seq, + ListBase *clipboard, + ListBase *fcurve_base) { - if (scene->adt == NULL || scene->adt->action == NULL || - BLI_listbase_is_empty(&scene->adt->action->curves)) { - return; - } - /* Add curves for strips inside meta strip. */ if (seq->type == SEQ_TYPE_META) { LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) { - sequencer_copy_animation(scene, meta_child); + sequencer_copy_animation_listbase(scene, meta_child, clipboard, fcurve_base); } } - GSet *fcurves = SEQ_fcurves_by_strip_get(seq, &scene->adt->action->curves); + GSet *fcurves = SEQ_fcurves_by_strip_get(seq, fcurve_base); if (fcurves == NULL) { return; } GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) { - BLI_addtail(&fcurves_clipboard, BKE_fcurve_copy(fcu)); + BLI_addtail(clipboard, BKE_fcurve_copy(fcu)); } GSET_FOREACH_END(); BLI_gset_free(fcurves, NULL); } +static void sequencer_copy_animation(Scene *scene, Sequence *seq) +{ + if (SEQ_animation_curves_exist(scene)) { + sequencer_copy_animation_listbase(scene, seq, &fcurves_clipboard, &scene->adt->action->curves); + } + if (SEQ_animation_drivers_exist(scene)) { + sequencer_copy_animation_listbase(scene, seq, &drivers_clipboard, &scene->adt->drivers); + } +} + static int sequencer_copy_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); @@ -2496,7 +2507,7 @@ void ED_sequencer_deselect_all(Scene *scene) static void sequencer_paste_animation(bContext *C) { - if (BLI_listbase_is_empty(&fcurves_clipboard)) { + if (BLI_listbase_is_empty(&fcurves_clipboard) && BLI_listbase_is_empty(&drivers_clipboard)) { return; } @@ -2515,6 +2526,9 @@ static void sequencer_paste_animation(bContext *C) LISTBASE_FOREACH (FCurve *, fcu, &fcurves_clipboard) { BLI_addtail(&act->curves, BKE_fcurve_copy(fcu)); } + LISTBASE_FOREACH (FCurve *, fcu, &drivers_clipboard) { + BLI_addtail(&scene->adt->drivers, BKE_fcurve_copy(fcu)); + } } static int sequencer_paste_exec(bContext *C, wmOperator *op) @@ -2553,8 +2567,8 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) * curves from backup. */ - ListBase fcurves_original_backup = {NULL, NULL}; - SEQ_animation_backup_original(scene, &fcurves_original_backup); + SeqAnimationBackup animation_backup = {0}; + SEQ_animation_backup_original(scene, &animation_backup); sequencer_paste_animation(C); /* Copy strips, temporarily restoring pointers to actual data-blocks. This @@ -2589,7 +2603,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *op) } } - SEQ_animation_restore_original(scene, &fcurves_original_backup); + SEQ_animation_restore_original(scene, &animation_backup); DEG_id_tag_update(&scene->id, ID_RECALC_SEQUENCER_STRIPS); DEG_relations_tag_update(bmain); diff --git a/source/blender/sequencer/SEQ_animation.h b/source/blender/sequencer/SEQ_animation.h index b8f74e5a510..7d40cf44cfa 100644 --- a/source/blender/sequencer/SEQ_animation.h +++ b/source/blender/sequencer/SEQ_animation.h @@ -15,22 +15,31 @@ struct GSet; struct ListBase; struct Scene; struct Sequence; +struct SeqAnimationBackup; +bool SEQ_animation_curves_exist(struct Scene *scene); +bool SEQ_animation_drivers_exist(struct Scene *scene); void SEQ_free_animdata(struct Scene *scene, struct Sequence *seq); void SEQ_offset_animdata(struct Scene *scene, struct Sequence *seq, int ofs); struct GSet *SEQ_fcurves_by_strip_get(const struct Sequence *seq, struct ListBase *fcurve_base); +typedef struct SeqAnimationBackup { + ListBase curves; + ListBase drivers; +} SeqAnimationBackup; /** - * Move all `F-Curves` from `scene` to `list`. + * Move all F-Curves and drivers from `scene` to `backup`. */ -void SEQ_animation_backup_original(struct Scene *scene, struct ListBase *list); +void SEQ_animation_backup_original(struct Scene *scene, struct SeqAnimationBackup *backup); /** - * Move all `F-Curves` from `list` to `scene`. + * Move all F-Curves and drivers from `backup` to `scene`. */ -void SEQ_animation_restore_original(struct Scene *scene, struct ListBase *list); +void SEQ_animation_restore_original(struct Scene *scene, struct SeqAnimationBackup *backup); /** - * Duplicate `F-Curves` used by `seq` from `list` to `scene`. + * Duplicate F-Curves and drivers used by `seq` from `backup` to `scene`. */ -void SEQ_animation_duplicate(struct Scene *scene, struct Sequence *seq, struct ListBase *list); +void SEQ_animation_duplicate_backup_to_scene(struct Scene *scene, + struct Sequence *seq, + struct SeqAnimationBackup *backup); #ifdef __cplusplus } diff --git a/source/blender/sequencer/SEQ_clipboard.h b/source/blender/sequencer/SEQ_clipboard.h index 5625f8886c9..1e5b877204b 100644 --- a/source/blender/sequencer/SEQ_clipboard.h +++ b/source/blender/sequencer/SEQ_clipboard.h @@ -18,6 +18,7 @@ struct Sequence; extern struct ListBase seqbase_clipboard; extern struct ListBase fcurves_clipboard; +extern struct ListBase drivers_clipboard; extern int seqbase_clipboard_frame; void SEQ_clipboard_pointers_store(struct Main *bmain, struct ListBase *seqbase); void SEQ_clipboard_pointers_restore(struct ListBase *seqbase, struct Main *bmain); diff --git a/source/blender/sequencer/intern/animation.c b/source/blender/sequencer/intern/animation.c index 280d2177d89..ec9deb2acd7 100644 --- a/source/blender/sequencer/intern/animation.c +++ b/source/blender/sequencer/intern/animation.c @@ -22,13 +22,15 @@ #include "SEQ_animation.h" -static bool seq_animation_curves_exist(Scene *scene) +bool SEQ_animation_curves_exist(Scene *scene) { - if (scene->adt == NULL || scene->adt->action == NULL || - BLI_listbase_is_empty(&scene->adt->action->curves)) { - return false; - } - return true; + return scene->adt != NULL && scene->adt->action != NULL && + !BLI_listbase_is_empty(&scene->adt->action->curves); +} + +bool SEQ_animation_drivers_exist(Scene *scene) +{ + return scene->adt != NULL && !BLI_listbase_is_empty(&scene->adt->drivers); } /* r_prefix + [" + escaped_name + "] + \0 */ @@ -66,7 +68,7 @@ GSet *SEQ_fcurves_by_strip_get(const Sequence *seq, ListBase *fcurve_base) void SEQ_offset_animdata(Scene *scene, Sequence *seq, int ofs) { - if (!seq_animation_curves_exist(scene) || ofs == 0) { + if (!SEQ_animation_curves_exist(scene) || ofs == 0) { return; } GSet *fcurves = SEQ_fcurves_by_strip_get(seq, &scene->adt->action->curves); @@ -99,7 +101,7 @@ void SEQ_offset_animdata(Scene *scene, Sequence *seq, int ofs) void SEQ_free_animdata(Scene *scene, Sequence *seq) { - if (!seq_animation_curves_exist(scene)) { + if (!SEQ_animation_curves_exist(scene)) { return; } GSet *fcurves = SEQ_fcurves_by_strip_get(seq, &scene->adt->action->curves); @@ -115,46 +117,55 @@ void SEQ_free_animdata(Scene *scene, Sequence *seq) BLI_gset_free(fcurves, NULL); } -void SEQ_animation_backup_original(Scene *scene, ListBase *list) +void SEQ_animation_backup_original(Scene *scene, SeqAnimationBackup *backup) { - if (scene->adt == NULL || scene->adt->action == NULL || - BLI_listbase_is_empty(&scene->adt->action->curves)) { - return; + if (SEQ_animation_curves_exist(scene)) { + BLI_movelisttolist(&backup->curves, &scene->adt->action->curves); + } + if (SEQ_animation_drivers_exist(scene)) { + BLI_movelisttolist(&backup->drivers, &scene->adt->drivers); } - - BLI_movelisttolist(list, &scene->adt->action->curves); } -void SEQ_animation_restore_original(Scene *scene, ListBase *list) +void SEQ_animation_restore_original(Scene *scene, SeqAnimationBackup *backup) { - if (scene->adt == NULL || scene->adt->action == NULL || BLI_listbase_is_empty(list)) { - return; + if (!BLI_listbase_is_empty(&backup->curves)) { + BLI_movelisttolist(&scene->adt->action->curves, &backup->curves); + } + if (!BLI_listbase_is_empty(&backup->drivers)) { + BLI_movelisttolist(&scene->adt->drivers, &backup->drivers); } - - BLI_movelisttolist(&scene->adt->action->curves, list); } -void SEQ_animation_duplicate(Scene *scene, Sequence *seq, ListBase *list) +static void seq_animation_duplicate(Scene *scene, Sequence *seq, ListBase *dst, ListBase *src) { - if (BLI_listbase_is_empty(list)) { - return; - } - if (seq->type == SEQ_TYPE_META) { LISTBASE_FOREACH (Sequence *, meta_child, &seq->seqbase) { - SEQ_animation_duplicate(scene, meta_child, list); + seq_animation_duplicate(scene, meta_child, dst, src); } } - GSet *fcurves = SEQ_fcurves_by_strip_get(seq, list); + GSet *fcurves = SEQ_fcurves_by_strip_get(seq, src); if (fcurves == NULL) { return; } GSET_FOREACH_BEGIN (FCurve *, fcu, fcurves) { FCurve *fcu_cpy = BKE_fcurve_copy(fcu); - BLI_addtail(&scene->adt->action->curves, fcu_cpy); + BLI_addtail(dst, fcu_cpy); } GSET_FOREACH_END(); BLI_gset_free(fcurves, NULL); } + +void SEQ_animation_duplicate_backup_to_scene(Scene *scene, + Sequence *seq, + SeqAnimationBackup *backup) +{ + if (!BLI_listbase_is_empty(&backup->curves)) { + seq_animation_duplicate(scene, seq, &scene->adt->action->curves, &backup->curves); + } + if (!BLI_listbase_is_empty(&backup->drivers)) { + seq_animation_duplicate(scene, seq, &scene->adt->drivers, &backup->drivers); + } +} diff --git a/source/blender/sequencer/intern/clipboard.c b/source/blender/sequencer/intern/clipboard.c index dc3c82d1fdc..c8777dc9690 100644 --- a/source/blender/sequencer/intern/clipboard.c +++ b/source/blender/sequencer/intern/clipboard.c @@ -44,6 +44,7 @@ ListBase seqbase_clipboard; ListBase fcurves_clipboard; +ListBase drivers_clipboard; int seqbase_clipboard_frame; static char seq_clipboard_active_seq_name[SEQ_NAME_MAXSTR]; @@ -62,6 +63,11 @@ void SEQ_clipboard_free(void) BKE_fcurve_free(fcu); } BLI_listbase_clear(&fcurves_clipboard); + + LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &drivers_clipboard) { + BKE_fcurve_free(fcu); + } + BLI_listbase_clear(&drivers_clipboard); } #define ID_PT (*id_pt) diff --git a/source/blender/sequencer/intern/strip_edit.c b/source/blender/sequencer/intern/strip_edit.c index 5ac4bd03f43..d0f7521bd10 100644 --- a/source/blender/sequencer/intern/strip_edit.c +++ b/source/blender/sequencer/intern/strip_edit.c @@ -436,8 +436,8 @@ Sequence *SEQ_edit_strip_split(Main *bmain, } /* Store `F-Curves`, so original ones aren't renamed. */ - ListBase fcurves_original_backup = {NULL, NULL}; - SEQ_animation_backup_original(scene, &fcurves_original_backup); + SeqAnimationBackup animation_backup = {0}; + SEQ_animation_backup_original(scene, &animation_backup); ListBase left_strips = {NULL, NULL}; SEQ_ITERATOR_FOREACH (seq, collection) { @@ -446,7 +446,7 @@ Sequence *SEQ_edit_strip_split(Main *bmain, BLI_addtail(&left_strips, seq); /* Duplicate curves from backup, so they can be renamed along with split strips. */ - SEQ_animation_duplicate(scene, seq, &fcurves_original_backup); + SEQ_animation_duplicate_backup_to_scene(scene, seq, &animation_backup); } SEQ_collection_free(collection); @@ -489,7 +489,7 @@ Sequence *SEQ_edit_strip_split(Main *bmain, } SEQ_edit_remove_flagged_sequences(scene, seqbase); - SEQ_animation_restore_original(scene, &fcurves_original_backup); + SEQ_animation_restore_original(scene, &animation_backup); return return_seq; } From fe5c3a0ab382fd0f3f980ce9bcfcf4c42a185602 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 28 Jan 2023 16:41:12 +1100 Subject: [PATCH 1005/1522] GNUmakefile: add convenience target 'check_wiki_file_structure' This target ensures https://wiki.blender.org/wiki/Source/File_Structure follows Blender's source tree. --- GNUmakefile | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/GNUmakefile b/GNUmakefile index ba9ee978817..a6b041597c3 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -71,6 +71,13 @@ Static Source Code Checking * check_mypy: Checks all Python scripts using mypy, see: source/tools/check_source/check_mypy_config.py scripts which are included. +Documentation Checking + + * check_wiki_file_structure: + Check the WIKI documentation for the source-tree's file structure + matches Blender's source-code. + See: https://wiki.blender.org/wiki/Source/File_Structure + Spell Checkers This runs the spell checker from the developer tools repositor. @@ -481,6 +488,10 @@ check_smatch: .FORCE check_mypy: .FORCE @$(PYTHON) "$(BLENDER_DIR)/source/tools/check_source/check_mypy.py" +check_wiki_file_structure: .FORCE + @PYTHONIOENCODING=utf_8 $(PYTHON) \ + "$(BLENDER_DIR)/source/tools/check_wiki/check_wiki_file_structure.py" + check_spelling_py: .FORCE @cd "$(BUILD_DIR)" ; \ PYTHONIOENCODING=utf_8 $(PYTHON) \ From 89aae4ac82e0f58c79b70d1faaa37fa8a5877cf5 Mon Sep 17 00:00:00 2001 From: Leon Schittek Date: Sat, 28 Jan 2023 10:07:29 +0100 Subject: [PATCH 1006/1522] Node Editor: Controlled node link swapping Allow to explicitly swap node links by pressing the alt-key while reconnecting node links. This replaces the old auto-swapping based on matching prefixes in socket names. The new behavior works as follows: * By default plugging links into already occupied (single input) sockets will connect the dragged link and remove the existing one. * Pressing the alt-key while dragging an existing node link from one socket to another socket that is already connected will swap the links' destinations. * Pressing the alt-key while dragging a new node link into an already linked socket will try to reconnect the existing links into another socket of the same type and remove the links, if no matching socket is found on the node. This is similar to the old auto-swapping. Swapping links from or to multi input sockets is not supported. This commit also makes the link drag tooltip better visible, when using light themes by using the text theme color. Reviewed By: Hans Goudey, Simon Thommes Differential Revision: https://developer.blender.org/D16244 --- source/blender/blenkernel/BKE_node.h | 2 +- .../blender/editors/space_node/node_intern.hh | 12 +- .../editors/space_node/node_relationships.cc | 229 ++++++++++++++---- source/blender/nodes/intern/node_util.cc | 93 +------ source/blender/nodes/intern/node_util.h | 4 +- 5 files changed, 203 insertions(+), 137 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index d57857bfdf3..c358f56c0d9 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -298,7 +298,7 @@ typedef struct bNodeType { const struct bNodeTree *nodetree, const char **r_disabled_hint); - /* optional handling of link insertion. Returns false if the link shouldn't be created. */ + /* Optional handling of link insertion. Returns false if the link shouldn't be created. */ bool (*insert_link)(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link); void (*free_self)(struct bNodeType *ntype); diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index f9804144fb0..5be29e6f336 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -44,18 +44,24 @@ struct bNodeLinkDrag { Vector links; eNodeSocketInOut in_out; - /** Draw handler for the "+" icon when dragging a link in empty space. */ + /** Draw handler for the tooltip icon when dragging a link in empty space. */ void *draw_handle; /** Temporarily stores the last picked link from multi-input socket operator. */ bNodeLink *last_picked_multi_input_socket_link; /** - * Temporarily stores the last hovered socket for multi-input socket operator. + * Temporarily stores the last hovered node for multi-input socket operator. * Store it to recalculate sorting after it is no longer hovered. */ bNode *last_node_hovered_while_dragging_a_link; + /** + * Temporarily stores the currently hovered socket for link swapping to allow reliably swap links + * even when dragging multiple links at once. `nullptr`, when no socket is hovered. + */ + bNodeSocket *hovered_socket; + /* The cursor position, used for drawing a + icon when dragging a node link. */ std::array cursor; @@ -66,6 +72,8 @@ struct bNodeLinkDrag { /** The number of links connected to the #start_socket when the drag started. */ int start_link_count; + bool swap_links = false; + /* Data for edge panning */ View2DEdgePanData pan_data; }; diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index a591c8308a4..9f37233840b 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -785,6 +785,9 @@ static bool should_create_drag_link_search_menu(const bNodeTree &node_tree, if (!dragged_links_are_detached(nldrag)) { return false; } + if (nldrag.swap_links) { + return false; + } /* Don't create the search menu if the drag is disconnecting a link from an input node. */ if (nldrag.start_socket->in_out == SOCK_IN && nldrag.start_link_count > 0) { return false; @@ -799,18 +802,29 @@ static bool should_create_drag_link_search_menu(const bNodeTree &node_tree, return true; } +static bool need_drag_link_tooltip(const bNodeTree &node_tree, const bNodeLinkDrag &nldrag) +{ + return nldrag.swap_links || should_create_drag_link_search_menu(node_tree, nldrag); +} + static void draw_draglink_tooltip(const bContext * /*C*/, ARegion * /*region*/, void *arg) { bNodeLinkDrag *nldrag = static_cast(arg); - const uchar text_col[4] = {255, 255, 255, 255}; + uchar text_col[4]; + UI_GetThemeColor4ubv(TH_TEXT, text_col); + const int padding = 4 * UI_DPI_FAC; const float x = nldrag->in_out == SOCK_IN ? nldrag->cursor[0] - 3.3f * padding : nldrag->cursor[0]; const float y = nldrag->cursor[1] - 2.0f * UI_DPI_FAC; - UI_icon_draw_ex( - x, y, ICON_ADD, U.inv_dpi_fac, 1.0f, 0.0f, text_col, false, UI_NO_ICON_OVERLAY_TEXT); + const bool new_link = nldrag->in_out == nldrag->start_socket->in_out; + const bool swap_links = nldrag->swap_links; + + const int icon = !swap_links ? ICON_ADD : (new_link ? ICON_ANIM : ICON_UV_SYNC_SELECT); + + UI_icon_draw_ex(x, y, icon, U.inv_dpi_fac, 1.0f, 0.0f, text_col, false, UI_NO_ICON_OVERLAY_TEXT); } static void draw_draglink_tooltip_activate(const ARegion ®ion, bNodeLinkDrag &nldrag) @@ -833,11 +847,21 @@ static void node_link_update_header(bContext *C, bNodeLinkDrag & /*nldrag*/) { char header[UI_MAX_DRAW_STR]; - BLI_strncpy(header, TIP_("LMB: drag node link, RMB: cancel"), sizeof(header)); + const char *str_lmb = WM_key_event_string(LEFTMOUSE, true); + const char *str_rmb = WM_key_event_string(RIGHTMOUSE, true); + const char *str_alt = WM_key_event_string(EVT_LEFTALTKEY, true); + + BLI_snprintf(header, + sizeof(header), + TIP_("%s: drag node link, %s: cancel, %s: swap node links"), + str_lmb, + str_rmb, + str_alt); + ED_workspace_status_text(C, header); } -static int node_count_links(const bNodeTree &ntree, const bNodeSocket &socket) +static int node_socket_count_links(const bNodeTree &ntree, const bNodeSocket &socket) { int count = 0; LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { @@ -848,41 +872,139 @@ static int node_count_links(const bNodeTree &ntree, const bNodeSocket &socket) return count; } -static void node_remove_extra_links(SpaceNode &snode, bNodeLink &link) +static bNodeSocket *node_find_linkable_socket(const bNodeTree &ntree, + const bNode *node, + bNodeSocket *socket_to_match) { - bNodeTree &ntree = *snode.edittree; - bNodeSocket &from = *link.fromsock; - bNodeSocket &to = *link.tosock; - int to_count = node_count_links(ntree, to); - int from_count = node_count_links(ntree, from); - int to_link_limit = nodeSocketLinkLimit(&to); - int from_link_limit = nodeSocketLinkLimit(&from); + bNodeSocket *first_socket = socket_to_match->in_out == SOCK_IN ? + static_cast(node->inputs.first) : + static_cast(node->outputs.first); - LISTBASE_FOREACH_MUTABLE (bNodeLink *, tlink, &ntree.links) { - if (tlink == &link) { - continue; - } - - if (tlink && tlink->fromsock == &from) { - if (from_count > from_link_limit) { - nodeRemLink(&ntree, tlink); - tlink = nullptr; - from_count--; + bNodeSocket *socket = socket_to_match->next ? socket_to_match->next : first_socket; + while (socket != socket_to_match) { + if (!socket->is_hidden() && socket->is_available()) { + const bool sockets_are_compatible = socket->typeinfo == socket_to_match->typeinfo; + if (sockets_are_compatible) { + const int link_count = node_socket_count_links(ntree, *socket); + const bool socket_has_capacity = link_count < nodeSocketLinkLimit(socket); + if (socket_has_capacity) { + /* Found a valid free socket we can swap to. */ + return socket; + } } } + /* Wrap around the list end. */ + socket = socket->next ? socket->next : first_socket; + } - if (tlink && tlink->tosock == &to) { - if (to_count > to_link_limit) { - nodeRemLink(&ntree, tlink); - tlink = nullptr; - to_count--; + return nullptr; +} + +static void displace_links(bNodeTree *ntree, const bNode *node, bNodeLink *inserted_link) +{ + bNodeSocket *linked_socket = node == inserted_link->tonode ? inserted_link->tosock : + inserted_link->fromsock; + bNodeSocket *replacement_socket = node_find_linkable_socket(*ntree, node, linked_socket); + + if (linked_socket->is_input()) { + if (linked_socket->limit + 1 < nodeSocketLinkLimit(linked_socket)) { + return; + } + + LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { + if (link->tosock == linked_socket) { + if (!replacement_socket) { + nodeRemLink(ntree, link); + BKE_ntree_update_tag_link_removed(ntree); + return; + } + + link->tosock = replacement_socket; + if (replacement_socket->is_multi_input()) { + link->multi_input_socket_index = node_socket_count_links(*ntree, *replacement_socket) - + 1; + } + BKE_ntree_update_tag_link_changed(ntree); + return; } - else if (tlink->fromsock == &from) { - /* Also remove link if it comes from the same output. */ - nodeRemLink(&ntree, tlink); - tlink = nullptr; - to_count--; - from_count--; + } + } + + LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree->links) { + if (link->fromsock == linked_socket) { + if (replacement_socket) { + link->fromsock = replacement_socket; + BKE_ntree_update_tag_link_changed(ntree); + } + else { + nodeRemLink(ntree, link); + BKE_ntree_update_tag_link_removed(ntree); + } + } + } +} + +static void node_displace_existing_links(bNodeLinkDrag &nldrag, bNodeTree &ntree) +{ + bNodeLink &link = nldrag.links.first(); + if (nldrag.start_socket->is_input()) { + displace_links(&ntree, link.fromnode, &link); + } + else { + displace_links(&ntree, link.tonode, &link); + } +} + +static void node_swap_links(bNodeLinkDrag &nldrag, bNodeTree &ntree) +{ + bNodeSocket &linked_socket = *nldrag.hovered_socket; + bNodeSocket *start_socket = nldrag.start_socket; + bNode *start_node = nldrag.start_node; + + if (linked_socket.is_input()) { + LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { + if (link->tosock == &linked_socket) { + link->tosock = start_socket; + link->tonode = start_node; + } + } + } + else { + LISTBASE_FOREACH (bNodeLink *, link, &ntree.links) { + if (link->fromsock == &linked_socket) { + link->fromsock = start_socket; + link->fromnode = start_node; + } + } + } + + BKE_ntree_update_tag_link_changed(&ntree); +} + +static void node_remove_existing_links_if_needed(bNodeLinkDrag &nldrag, bNodeTree &ntree) +{ + bNodeSocket &linked_socket = *nldrag.hovered_socket; + + const int link_count = node_socket_count_links(ntree, linked_socket); + const int link_limit = nodeSocketLinkLimit(&linked_socket); + + if (link_count < link_limit) { + return; + } + + if (linked_socket.is_input()) { + LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) { + if (link->tosock == &linked_socket) { + nodeRemLink(&ntree, link); + return; + } + } + } + else { + LISTBASE_FOREACH_MUTABLE (bNodeLink *, link, &ntree.links) { + if (link->fromsock == &linked_socket) { + nodeRemLink(&ntree, link); + return; } } } @@ -895,29 +1017,47 @@ static void add_dragged_links_to_tree(bContext &C, bNodeLinkDrag &nldrag) SpaceNode &snode = *CTX_wm_space_node(&C); bNodeTree &ntree = *snode.edittree; + /* Handle node links already occupying the socket. */ + if (const bNodeSocket *linked_socket = nldrag.hovered_socket) { + /* Swapping existing links out of multi input sockets is not supported. */ + const bool connecting_to_multi_input = linked_socket->is_multi_input() || + nldrag.start_socket->is_multi_input(); + if (nldrag.swap_links && !connecting_to_multi_input) { + const bool is_new_link = nldrag.in_out == nldrag.start_socket->in_out; + if (is_new_link) { + node_displace_existing_links(nldrag, ntree); + } + else { + node_swap_links(nldrag, ntree); + } + } + else { + node_remove_existing_links_if_needed(nldrag, ntree); + } + } + for (const bNodeLink &link : nldrag.links) { if (!link.tosock || !link.fromsock) { continue; } + /* Before actually adding the link let nodes perform special link insertion handling. */ bNodeLink *new_link = MEM_new(__func__, link); if (link.fromnode->typeinfo->insert_link) { if (!link.fromnode->typeinfo->insert_link(&ntree, link.fromnode, new_link)) { + MEM_freeN(new_link); continue; } } if (link.tonode->typeinfo->insert_link) { if (!link.tonode->typeinfo->insert_link(&ntree, link.tonode, new_link)) { + MEM_freeN(new_link); continue; } } - /* Add link to the node tree. */ BLI_addtail(&ntree.links, new_link); BKE_ntree_update_tag_link_added(&ntree, new_link); - - /* We might need to remove a link. */ - node_remove_extra_links(snode, *new_link); } ED_node_tree_propagate_change(&C, bmain, &ntree); @@ -949,6 +1089,7 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur if (nldrag.in_out == SOCK_OUT) { if (bNodeSocket *tsock = node_find_indicated_socket(snode, cursor, SOCK_IN)) { + nldrag.hovered_socket = tsock; bNode &tnode = tsock->owner_node(); for (bNodeLink &link : nldrag.links) { /* Skip if socket is on the same node as the fromsock. */ @@ -981,6 +1122,7 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur } } else { + nldrag.hovered_socket = nullptr; for (bNodeLink &link : nldrag.links) { link.tonode = nullptr; link.tosock = nullptr; @@ -993,6 +1135,7 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur } else { if (bNodeSocket *tsock = node_find_indicated_socket(snode, cursor, SOCK_OUT)) { + nldrag.hovered_socket = tsock; bNode &node = tsock->owner_node(); for (bNodeLink &link : nldrag.links) { /* Skip if this is already the target socket. */ @@ -1010,6 +1153,7 @@ static void node_link_find_socket(bContext &C, wmOperator &op, const float2 &cur } } else { + nldrag.hovered_socket = nullptr; for (bNodeLink &link : nldrag.links) { link.fromnode = nullptr; link.fromsock = nullptr; @@ -1043,7 +1187,7 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event) ED_region_tag_redraw(region); } - if (should_create_drag_link_search_menu(*snode.edittree, nldrag)) { + if (need_drag_link_tooltip(*snode.edittree, nldrag)) { draw_draglink_tooltip_activate(*region, nldrag); } else { @@ -1075,6 +1219,9 @@ static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event) } break; } + case EVT_LEFTALTKEY: + nldrag.swap_links = (event->val == KM_PRESS); + break; case EVT_ESCKEY: { node_link_cancel(C, op); return OPERATOR_CANCELLED; @@ -1185,8 +1332,8 @@ static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event) UI_view2d_edge_pan_operator_init(C, &nldrag->pan_data, op); - /* Add "+" icon when the link is dragged in empty space. */ - if (should_create_drag_link_search_menu(*snode.edittree, *nldrag)) { + /* Add icons at the cursor when the link is dragged in empty space. */ + if (need_drag_link_tooltip(*snode.edittree, *nldrag)) { draw_draglink_tooltip_activate(*CTX_wm_region(C), *nldrag); } snode.runtime->linkdrag = std::move(nldrag); diff --git a/source/blender/nodes/intern/node_util.cc b/source/blender/nodes/intern/node_util.cc index d56e82a23eb..7699749e949 100644 --- a/source/blender/nodes/intern/node_util.cc +++ b/source/blender/nodes/intern/node_util.cc @@ -264,97 +264,10 @@ void node_combsep_color_label(const ListBase *sockets, NodeCombSepColorMode mode /** \name Link Insertion * \{ */ -static bool node_link_socket_match(const bNodeSocket *a, const bNodeSocket *b) +bool node_insert_link_default(bNodeTree * /*ntree*/, + bNode * /*node*/, + bNodeLink * /*inserted_link*/) { - /* Check if sockets are of the same type. */ - if (a->typeinfo != b->typeinfo) { - return false; - } - - /* Test if alphabetic prefix matches, allowing for imperfect matches, such as numeric suffixes - * like Color1/Color2. */ - int prefix_len = 0; - const char *ca = a->name, *cb = b->name; - for (; *ca != '\0' && *cb != '\0'; ca++, cb++) { - /* End of common prefix? */ - if (*ca != *cb) { - /* Prefix delimited by non-alphabetic char. */ - if (isalpha(*ca) || isalpha(*cb)) { - return false; - } - break; - } - prefix_len++; - } - return prefix_len > 0; -} - -static int node_count_links(const bNodeTree *ntree, const bNodeSocket *socket) -{ - int count = 0; - LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) { - if (ELEM(socket, link->fromsock, link->tosock)) { - count++; - } - } - return count; -} - -static bNodeSocket *node_find_linkable_socket(bNodeTree *ntree, - bNode *node, - bNodeSocket *to_socket) -{ - bNodeSocket *first = to_socket->in_out == SOCK_IN ? - static_cast(node->inputs.first) : - static_cast(node->outputs.first); - - /* Wrap around the list end. */ - bNodeSocket *socket_iter = to_socket->next ? to_socket->next : first; - while (socket_iter != to_socket) { - if (socket_iter->is_visible() && node_link_socket_match(socket_iter, to_socket)) { - const int link_count = node_count_links(ntree, socket_iter); - /* Add one to account for the new link being added. */ - if (link_count + 1 <= nodeSocketLinkLimit(socket_iter)) { - return socket_iter; /* Found a valid free socket we can swap to. */ - } - } - socket_iter = socket_iter->next ? socket_iter->next : first; /* Wrap around the list end. */ - } - - return nullptr; -} - -bool node_insert_link_default(bNodeTree *ntree, bNode *node, bNodeLink *link) -{ - bNodeSocket *socket = link->tosock; - - if (node != link->tonode) { - return true; - } - - /* If we're not at the link limit of the target socket, we can skip - * trying to move existing links to another socket. */ - const int to_link_limit = nodeSocketLinkLimit(socket); - if (socket->runtime->total_inputs + 1 < to_link_limit) { - return true; - } - - LISTBASE_FOREACH_MUTABLE (bNodeLink *, to_link, &ntree->links) { - if (socket == to_link->tosock) { - bNodeSocket *new_socket = node_find_linkable_socket(ntree, node, socket); - if (new_socket && new_socket != socket) { - /* Attempt to redirect the existing link to the new socket. */ - to_link->tosock = new_socket; - return true; - } - - if (new_socket == nullptr) { - /* No possible replacement, remove the existing link. */ - nodeRemLink(ntree, to_link); - return true; - } - } - } return true; } diff --git a/source/blender/nodes/intern/node_util.h b/source/blender/nodes/intern/node_util.h index b0f62eee849..0307a80ae25 100644 --- a/source/blender/nodes/intern/node_util.h +++ b/source/blender/nodes/intern/node_util.h @@ -70,9 +70,7 @@ void node_combsep_color_label(const ListBase *sockets, NodeCombSepColorMode mode /*** Link Handling */ /** - * The idea behind this is: When a user connects an input to a socket that is - * already linked (and if its not an Multi Input Socket), we try to find a replacement socket for - * the link that we try to overwrite and connect that previous link to the new socket. + * By default there are no links we don't want to connect, when inserting. */ bool node_insert_link_default(struct bNodeTree *ntree, struct bNode *node, struct bNodeLink *link); From 904357d67a29ccc7fb512f22619288d2db182b9e Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 28 Jan 2023 14:52:15 +0100 Subject: [PATCH 1007/1522] Fix: assert when converting between incompatible field types This results in a compile time error now which hopefully prevents this specific kind of mistake in the future. --- source/blender/functions/FN_field.hh | 10 ++++++++++ .../nodes/node_geo_curve_topology_points_of_curve.cc | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/source/blender/functions/FN_field.hh b/source/blender/functions/FN_field.hh index 993558b3a18..7d1fa855206 100644 --- a/source/blender/functions/FN_field.hh +++ b/source/blender/functions/FN_field.hh @@ -193,6 +193,16 @@ template class Field : public GField, detail::TypedFieldBase { BLI_assert(this->cpp_type().template is()); } + /** + * Generally, the constructor above would be sufficient, but this additional constructor ensures + * that trying to create e.g. a `Field` from a `Field` does not compile (instead of + * only failing at run-time). + */ + template Field(Field field) : GField(std::move(field)) + { + static_assert(std::is_same_v); + } + Field(std::shared_ptr node, const int node_output_index = 0) : Field(GField(std::move(node), node_output_index)) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc index 820fa4856a4..086a68401ed 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_curve_topology_points_of_curve.cc @@ -237,7 +237,7 @@ static void node_geo_exec(GeoNodeExecParams params) } if (params.output_is_required("Point Index")) { Field sort_index = params.extract_input>("Sort Index"); - Field sort_weight = params.extract_input>("Weights"); + Field sort_weight = params.extract_input>("Weights"); if (use_start_point_special_case(curve_index, sort_index, sort_weight)) { params.set_output("Point Index", Field(std::make_shared())); } From b2534fb8661e4168207f2ebee70925b2d6f27421 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 28 Jan 2023 14:55:39 +0100 Subject: [PATCH 1008/1522] Fix: anonymous attribute output requested even though it's not used The code removed here was intended to be an optimization that avoids creating an additional node to join multiple attribute sets. However, that optimization did not work, because it did not take into account whether the single attribute set is required or not. --- source/blender/nodes/intern/geometry_nodes_lazy_function.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 64551249e29..4c8a67f81b3 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -2523,9 +2523,6 @@ struct GeometryNodesLazyFunctionGraphBuilder { if (attribute_set_sockets.is_empty()) { return nullptr; } - if (attribute_set_sockets.size() == 1) { - return attribute_set_sockets[0]; - } Vector key; key.extend(attribute_set_sockets); From 90253ad2e753acde161b38d82bd650d54d3f6581 Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sat, 28 Jan 2023 15:28:55 +0100 Subject: [PATCH 1009/1522] Geometry Nodes: avoid creating a lazy function many times It's better to use some statically allocated functions instead of dynamically allocating them all the time. --- .../intern/geometry_nodes_lazy_function.cc | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 4c8a67f81b3..8075694edca 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -1078,6 +1078,33 @@ class LazyFunctionForAnonymousAttributeSetJoin : public lf::LazyFunction { { return 2 * i + 1; } + + /** + * Cache for functions small amounts to avoid to avoid building them many times. + */ + static const LazyFunctionForAnonymousAttributeSetJoin &get_cached( + const int amount, Vector> &r_functions) + { + constexpr int cache_amount = 16; + static std::array cached_functions = + get_cache(std::make_index_sequence{}); + if (amount <= cached_functions.size()) { + return cached_functions[amount]; + } + + auto fn = std::make_unique(amount); + const auto &fn_ref = *fn; + r_functions.append(std::move(fn)); + return fn_ref; + } + + private: + template + static std::array get_cache( + std::index_sequence /*indices*/) + { + return {LazyFunctionForAnonymousAttributeSetJoin(I)...}; + } }; enum class AttributeReferenceKeyType { @@ -2529,18 +2556,17 @@ struct GeometryNodesLazyFunctionGraphBuilder { key.extend(used_sockets); std::sort(key.begin(), key.end()); return cache.lookup_or_add_cb(key, [&]() { - auto lazy_function = std::make_unique( - attribute_set_sockets.size()); - lf::Node &lf_node = lf_graph_->add_function(*lazy_function); + const auto &lazy_function = LazyFunctionForAnonymousAttributeSetJoin::get_cached( + attribute_set_sockets.size(), lf_graph_info_->functions); + lf::Node &lf_node = lf_graph_->add_function(lazy_function); for (const int i : attribute_set_sockets.index_range()) { - lf::InputSocket &lf_use_input = lf_node.input(lazy_function->get_use_input(i)); + lf::InputSocket &lf_use_input = lf_node.input(lazy_function.get_use_input(i)); socket_usage_inputs_.add(&lf_use_input); lf::InputSocket &lf_attributes_input = lf_node.input( - lazy_function->get_attribute_set_input(i)); + lazy_function.get_attribute_set_input(i)); lf_graph_->add_link(*used_sockets[i], lf_use_input); lf_graph_->add_link(*attribute_set_sockets[i], lf_attributes_input); } - lf_graph_info_->functions.append(std::move(lazy_function)); return &lf_node.output(0); }); } From 52ed8bcb274e2b2fb636c03447ba4263fa9bdd24 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 28 Jan 2023 18:10:34 +0100 Subject: [PATCH 1010/1522] Gitea: fix pull request template so commit body can be set as description --- .gitea/pull_request_template.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitea/pull_request_template.yaml b/.gitea/pull_request_template.yaml index a6f1f2db20f..b3f45baf96b 100644 --- a/.gitea/pull_request_template.yaml +++ b/.gitea/pull_request_template.yaml @@ -15,7 +15,3 @@ body: attributes: label: "Description" hide_label: true - value: | - Description of the problem that is addressed in the patch. - - Description of the proposed solution and its implementation. From e497da5fda3547d794f0fecbbc126d34446661fb Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Sun, 29 Jan 2023 00:13:37 +0100 Subject: [PATCH 1011/1522] Fix: off by one error in previous commit Fixes rB90253ad2e753acde161b38d82bd650d54d3f6581. --- source/blender/nodes/intern/geometry_nodes_lazy_function.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc index 8075694edca..1a7f1520b12 100644 --- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc +++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc @@ -1088,7 +1088,7 @@ class LazyFunctionForAnonymousAttributeSetJoin : public lf::LazyFunction { constexpr int cache_amount = 16; static std::array cached_functions = get_cache(std::make_index_sequence{}); - if (amount <= cached_functions.size()) { + if (amount < cached_functions.size()) { return cached_functions[amount]; } From 042775ad482977a930528bf11eb26da5ce2810f0 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Sat, 28 Jan 2023 16:04:50 -0800 Subject: [PATCH 1012/1522] Sculpt: Fix T104068, depth calculation error in trim tools Also made the coplanar padding factor relative. --- source/blender/editors/sculpt_paint/paint_mask.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_mask.cc b/source/blender/editors/sculpt_paint/paint_mask.cc index c0f4ddf4218..177bc33bed5 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.cc +++ b/source/blender/editors/sculpt_paint/paint_mask.cc @@ -1148,13 +1148,16 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex float depth_front = trim_operation->depth_front; float depth_back = trim_operation->depth_back; + float pad_factor = 0.0f; if (!trim_operation->use_cursor_depth) { + pad_factor = (depth_back - depth_front) * 0.01f + 0.001f; + /* When using cursor depth, don't modify the depth set by the cursor radius. If full depth is * used, adding a little padding to the trimming shape can help avoiding booleans with coplanar * faces. */ - depth_front -= 0.1f; - depth_back += 0.1f; + depth_front -= pad_factor; + depth_back += pad_factor; } float shape_origin[3]; @@ -1198,7 +1201,9 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex } else { copy_v3_v3(new_point, positions[i]); - madd_v3_v3fl(new_point, shape_normal, depth_back); + float dist = dist_signed_to_plane_v3(new_point, shape_plane); + + madd_v3_v3fl(new_point, shape_normal, depth_back - dist); } copy_v3_v3(positions[i + tot_screen_points], new_point); From 11de4aa0cea7f0ab9ec1b2035094663db9dc0b8b Mon Sep 17 00:00:00 2001 From: Aaron Carlisle Date: Sun, 29 Jan 2023 19:00:14 -0500 Subject: [PATCH 1013/1522] Update RNA to User manual mappings --- .../scripts/modules/rna_manual_reference.py | 337 ++++++++++-------- 1 file changed, 198 insertions(+), 139 deletions(-) diff --git a/release/scripts/modules/rna_manual_reference.py b/release/scripts/modules/rna_manual_reference.py index 28091e119cb..fd7b7dbb786 100644 --- a/release/scripts/modules/rna_manual_reference.py +++ b/release/scripts/modules/rna_manual_reference.py @@ -50,6 +50,8 @@ url_manual_mapping = ( ("bpy.types.cyclesobjectsettings.shadow_terminator_geometry_offset*", "render/cycles/object_settings/object_data.html#bpy-types-cyclesobjectsettings-shadow-terminator-geometry-offset"), ("bpy.types.sequencertoolsettings.use_snap_current_frame_to_strips*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-use-snap-current-frame-to-strips"), ("bpy.types.clothcollisionsettings.vertex_group_object_collisions*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-vertex-group-object-collisions"), + ("bpy.types.gpencilsculptsettings.use_automasking_material_active*", "grease_pencil/modes/sculpting/introduction.html#bpy-types-gpencilsculptsettings-use-automasking-material-active"), + ("bpy.types.gpencilsculptsettings.use_automasking_material_stroke*", "grease_pencil/modes/sculpting/introduction.html#bpy-types-gpencilsculptsettings-use-automasking-material-stroke"), ("bpy.types.cycleslightsettings.use_multiple_importance_sampling*", "render/cycles/light_settings.html#bpy-types-cycleslightsettings-use-multiple-importance-sampling"), ("bpy.types.fluiddomainsettings.sndparticle_potential_max_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-max-energy"), ("bpy.types.fluiddomainsettings.sndparticle_potential_min_energy*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-potential-min-energy"), @@ -61,6 +63,8 @@ url_manual_mapping = ( ("bpy.types.cyclesrendersettings.preview_denoising_start_sample*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-preview-denoising-start-sample"), ("bpy.types.fluiddomainsettings.sndparticle_sampling_trappedair*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-trappedair"), ("bpy.types.fluiddomainsettings.sndparticle_sampling_wavecrest*", "physics/fluid/type/domain/liquid/particles.html#bpy-types-fluiddomainsettings-sndparticle-sampling-wavecrest"), + ("bpy.types.gpencilsculptsettings.use_automasking_layer_active*", "grease_pencil/modes/sculpting/introduction.html#bpy-types-gpencilsculptsettings-use-automasking-layer-active"), + ("bpy.types.gpencilsculptsettings.use_automasking_layer_stroke*", "grease_pencil/modes/sculpting/introduction.html#bpy-types-gpencilsculptsettings-use-automasking-layer-stroke"), ("bpy.types.lineartgpencilmodifier.use_image_boundary_trimming*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-image-boundary-trimming"), ("bpy.types.materiallineart.use_intersection_priority_override*", "render/materials/line_art.html#bpy-types-materiallineart-use-intersection-priority-override"), ("bpy.types.rigidbodyconstraint.use_override_solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-use-override-solver-iterations"), @@ -125,6 +129,7 @@ url_manual_mapping = ( ("bpy.types.cyclesrendersettings.min_transparent_bounces*", "render/cycles/render_settings/sampling.html#bpy-types-cyclesrendersettings-min-transparent-bounces"), ("bpy.types.fluiddomainsettings.use_collision_border_top*", "physics/fluid/type/domain/settings.html#bpy-types-fluiddomainsettings-use-collision-border-top"), ("bpy.types.gpencilsculptsettings.intersection_threshold*", "grease_pencil/modes/draw/tools/cutter.html#bpy-types-gpencilsculptsettings-intersection-threshold"), + ("bpy.types.gpencilsculptsettings.use_automasking_stroke*", "grease_pencil/modes/sculpting/introduction.html#bpy-types-gpencilsculptsettings-use-automasking-stroke"), ("bpy.types.gpencilsculptsettings.use_multiframe_falloff*", "grease_pencil/multiframe.html#bpy-types-gpencilsculptsettings-use-multiframe-falloff"), ("bpy.types.lineartgpencilmodifier.use_back_face_culling*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-back-face-culling"), ("bpy.types.lineartgpencilmodifier.use_intersection_mask*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-intersection-mask"), @@ -152,6 +157,7 @@ url_manual_mapping = ( ("bpy.types.linestylegeometrymodifier_backbonestretcher*", "render/freestyle/view_layer/line_style/modifiers/geometry/backbone_stretcher.html#bpy-types-linestylegeometrymodifier-backbonestretcher"), ("bpy.types.linestylegeometrymodifier_sinusdisplacement*", "render/freestyle/view_layer/line_style/modifiers/geometry/sinus_displacement.html#bpy-types-linestylegeometrymodifier-sinusdisplacement"), ("bpy.types.sequencertoolsettings.snap_to_current_frame*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-snap-to-current-frame"), + ("bpy.types.view3doverlay.sculpt_mode_face_sets_opacity*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-types-view3doverlay-sculpt-mode-face-sets-opacity"), ("bpy.ops.object.geometry_nodes_input_attribute_toggle*", "modeling/modifiers/generate/geometry_nodes.html#bpy-ops-object-geometry-nodes-input-attribute-toggle"), ("bpy.types.animvizmotionpaths.show_keyframe_highlight*", "animation/motion_paths.html#bpy-types-animvizmotionpaths-show-keyframe-highlight"), ("bpy.types.brushcurvessculptsettings.minimum_distance*", "sculpt_paint/curves_sculpting/tools/density_curves.html#bpy-types-brushcurvessculptsettings-minimum-distance"), @@ -290,8 +296,8 @@ url_manual_mapping = ( ("bpy.types.fluiddomainsettings.vector_display_type*", "physics/fluid/type/domain/gas/viewport_display.html#bpy-types-fluiddomainsettings-vector-display-type"), ("bpy.types.freestylelineset.select_by_image_border*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-image-border"), ("bpy.types.freestylesettings.kr_derivative_epsilon*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-kr-derivative-epsilon"), - ("bpy.types.geometrynodecurveprimitivebeziersegment*", "modeling/geometry_nodes/curve_primitives/bezier_segment.html#bpy-types-geometrynodecurveprimitivebeziersegment"), - ("bpy.types.geometrynodecurveprimitivequadrilateral*", "modeling/geometry_nodes/curve_primitives/quadrilateral.html#bpy-types-geometrynodecurveprimitivequadrilateral"), + ("bpy.types.geometrynodecurveprimitivebeziersegment*", "modeling/geometry_nodes/curve/primitives/bezier_segment.html#bpy-types-geometrynodecurveprimitivebeziersegment"), + ("bpy.types.geometrynodecurveprimitivequadrilateral*", "modeling/geometry_nodes/curve/primitives/quadrilateral.html#bpy-types-geometrynodecurveprimitivequadrilateral"), ("bpy.types.lineartgpencilmodifier.crease_threshold*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-crease-threshold"), ("bpy.types.lineartgpencilmodifier.smooth_tolerance*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-smooth-tolerance"), ("bpy.types.lineartgpencilmodifier.use_intersection*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-intersection"), @@ -403,8 +409,8 @@ url_manual_mapping = ( ("bpy.types.freestylelineset.select_by_collection*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-collection"), ("bpy.types.freestylelineset.select_by_edge_types*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-edge-types"), ("bpy.types.freestylelineset.select_by_face_marks*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-by-face-marks"), - ("bpy.types.geometrynodeinputcurvehandlepositions*", "modeling/geometry_nodes/curve/curve_handle_position.html#bpy-types-geometrynodeinputcurvehandlepositions"), - ("bpy.types.geometrynodeinputedgepathstoselection*", "modeling/geometry_nodes/mesh/edge_paths_to_selection.html#bpy-types-geometrynodeinputedgepathstoselection"), + ("bpy.types.geometrynodeinputcurvehandlepositions*", "modeling/geometry_nodes/curve/read/curve_handle_position.html#bpy-types-geometrynodeinputcurvehandlepositions"), + ("bpy.types.geometrynodeinputedgepathstoselection*", "modeling/geometry_nodes/mesh/operations/edge_paths_to_selection.html#bpy-types-geometrynodeinputedgepathstoselection"), ("bpy.types.linestyle*modifier_distancefromcamera*", "render/freestyle/view_layer/line_style/modifiers/color/distance_from_camera.html#bpy-types-linestyle-modifier-distancefromcamera"), ("bpy.types.linestyle*modifier_distancefromobject*", "render/freestyle/view_layer/line_style/modifiers/color/distance_from_object.html#bpy-types-linestyle-modifier-distancefromobject"), ("bpy.types.linestylegeometrymodifier_2dtransform*", "render/freestyle/view_layer/line_style/modifiers/geometry/2d_transform.html#bpy-types-linestylegeometrymodifier-2dtransform"), @@ -414,6 +420,7 @@ url_manual_mapping = ( ("bpy.types.movietrackingplanetrack.image_opacity*", "movie_clip/tracking/clip/sidebar/track/plane_track.html#bpy-types-movietrackingplanetrack-image-opacity"), ("bpy.types.particlesettings.use_parent_particles*", "physics/particles/emitter/render.html#bpy-types-particlesettings-use-parent-particles"), ("bpy.types.rigidbodyconstraint.solver_iterations*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-solver-iterations"), + ("bpy.types.rigidbodyobject.collision_collections*", "physics/rigid_body/properties/collisions.html#bpy-types-rigidbodyobject-collision-collections"), ("bpy.types.sculpt.automasking_start_normal_limit*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-automasking-start-normal-limit"), ("bpy.types.sculpt.use_automasking_boundary_edges*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-boundary-edges"), ("bpy.types.sequenceeditor.use_overlay_frame_lock*", "editors/video_sequencer/preview/sidebar.html#bpy-types-sequenceeditor-use-overlay-frame-lock"), @@ -456,9 +463,9 @@ url_manual_mapping = ( ("bpy.types.freestylelinestyle.material_boundary*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-material-boundary"), ("bpy.types.freestylelinestyle.use_split_pattern*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-split-pattern"), ("bpy.types.freestylesettings.use_view_map_cache*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-view-map-cache"), - ("bpy.types.geometrynodecurvehandletypeselection*", "modeling/geometry_nodes/curve/handle_type_selection.html#bpy-types-geometrynodecurvehandletypeselection"), + ("bpy.types.geometrynodecurvehandletypeselection*", "modeling/geometry_nodes/curve/read/handle_type_selection.html#bpy-types-geometrynodecurvehandletypeselection"), ("bpy.types.geometrynodedistributepointsinvolume*", "modeling/geometry_nodes/point/distribute_points_in_volume.html#bpy-types-geometrynodedistributepointsinvolume"), - ("bpy.types.geometrynodeinputmeshvertexneighbors*", "modeling/geometry_nodes/mesh/vertex_neighbors.html#bpy-types-geometrynodeinputmeshvertexneighbors"), + ("bpy.types.geometrynodeinputmeshvertexneighbors*", "modeling/geometry_nodes/mesh/read/vertex_neighbors.html#bpy-types-geometrynodeinputmeshvertexneighbors"), ("bpy.types.greasepencil.curve_edit_corner_angle*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-corner-angle"), ("bpy.types.imageformatsettings.color_management*", "render/output/properties/output.html#bpy-types-imageformatsettings-color-management"), ("bpy.types.lineartgpencilmodifier.source_camera*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-source-camera"), @@ -472,6 +479,8 @@ url_manual_mapping = ( ("bpy.types.movietrackingtrack.use_green_channel*", "movie_clip/tracking/clip/sidebar/track/track.html#bpy-types-movietrackingtrack-use-green-channel"), ("bpy.types.rendersettings.resolution_percentage*", "render/output/properties/format.html#bpy-types-rendersettings-resolution-percentage"), ("bpy.types.rendersettings_simplify_gpencil_tint*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-gpencil-tint"), + ("bpy.types.softbodysettings.use_estimate_matrix*", "physics/soft_body/settings/solver.html#bpy-types-softbodysettings-use-estimate-matrix"), + ("bpy.types.softbodysettings.vertex_group_spring*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-vertex-group-spring"), ("bpy.types.spaceimageeditor.show_gizmo_navigate*", "editors/image/introduction.html#bpy-types-spaceimageeditor-show-gizmo-navigate"), ("bpy.types.spaceoutliner.lib_override_view_mode*", "editors/outliner/interface.html#bpy-types-spaceoutliner-lib-override-view-mode"), ("bpy.types.spaceoutliner.use_filter_object_mesh*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-object-mesh"), @@ -527,7 +536,7 @@ url_manual_mapping = ( ("bpy.types.freestylelinestyle.integration_type*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-integration-type"), ("bpy.types.freestylelinestyle.use_split_length*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-split-length"), ("bpy.types.geometrynodedistributepointsonfaces*", "modeling/geometry_nodes/point/distribute_points_on_faces.html#bpy-types-geometrynodedistributepointsonfaces"), - ("bpy.types.geometrynodesetcurvehandlepositions*", "modeling/geometry_nodes/curve/set_handle_positions.html#bpy-types-geometrynodesetcurvehandlepositions"), + ("bpy.types.geometrynodesetcurvehandlepositions*", "modeling/geometry_nodes/curve/write/set_handle_positions.html#bpy-types-geometrynodesetcurvehandlepositions"), ("bpy.types.greasepencil.stroke_thickness_space*", "grease_pencil/properties/strokes.html#bpy-types-greasepencil-stroke-thickness-space"), ("bpy.types.lineartgpencilmodifier.use_material*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-material"), ("bpy.types.linestylegeometrymodifier_blueprint*", "render/freestyle/view_layer/line_style/modifiers/geometry/blueprint.html#bpy-types-linestylegeometrymodifier-blueprint"), @@ -540,6 +549,9 @@ url_manual_mapping = ( ("bpy.types.rendersettings.simplify_subdivision*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-subdivision"), ("bpy.types.sculpt.use_automasking_start_normal*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-start-normal"), ("bpy.types.sequencerpreviewoverlay.show_cursor*", "editors/video_sequencer/preview/display/overlays.html#bpy-types-sequencerpreviewoverlay-show-cursor"), + ("bpy.types.softbodysettings.use_edge_collision*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-use-edge-collision"), + ("bpy.types.softbodysettings.use_face_collision*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-use-face-collision"), + ("bpy.types.softbodysettings.use_self_collision*", "physics/soft_body/settings/self_collision.html#bpy-types-softbodysettings-use-self-collision"), ("bpy.types.spacegrapheditor.show_extrapolation*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-extrapolation"), ("bpy.types.spaceoutliner.use_filter_collection*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-collection"), ("bpy.types.spacesequenceeditor.cursor_location*", "editors/video_sequencer/preview/sidebar.html#bpy-types-spacesequenceeditor-cursor-location"), @@ -591,12 +603,12 @@ url_manual_mapping = ( ("bpy.types.freestylelinestyle.use_chain_count*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-chain-count"), ("bpy.types.freestylelinestyle.use_dashed_line*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-dashed-line"), ("bpy.types.freestylelinestyle.use_same_object*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-same-object"), - ("bpy.types.functionnodeinputspecialcharacters*", "modeling/geometry_nodes/text/special_characters.html#bpy-types-functionnodeinputspecialcharacters"), - ("bpy.types.geometrynodecurveendpointselection*", "modeling/geometry_nodes/curve/endpoint_selection.html#bpy-types-geometrynodecurveendpointselection"), - ("bpy.types.geometrynodeinputedgepathstocurves*", "modeling/geometry_nodes/mesh/edge_paths_to_curves.html#bpy-types-geometrynodeinputedgepathstocurves"), - ("bpy.types.geometrynodeinputmeshedgeneighbors*", "modeling/geometry_nodes/mesh/edge_neighbors.html#bpy-types-geometrynodeinputmeshedgeneighbors"), - ("bpy.types.geometrynodeinputmeshfaceneighbors*", "modeling/geometry_nodes/mesh/face_neighbors.html#bpy-types-geometrynodeinputmeshfaceneighbors"), - ("bpy.types.geometrynodeinputshortestedgepaths*", "modeling/geometry_nodes/mesh/shortest_edge_paths.html#bpy-types-geometrynodeinputshortestedgepaths"), + ("bpy.types.functionnodeinputspecialcharacters*", "modeling/geometry_nodes/utilities/text/special_characters.html#bpy-types-functionnodeinputspecialcharacters"), + ("bpy.types.geometrynodecurveendpointselection*", "modeling/geometry_nodes/curve/read/endpoint_selection.html#bpy-types-geometrynodecurveendpointselection"), + ("bpy.types.geometrynodeinputedgepathstocurves*", "modeling/geometry_nodes/mesh/operations/edge_paths_to_curves.html#bpy-types-geometrynodeinputedgepathstocurves"), + ("bpy.types.geometrynodeinputmeshedgeneighbors*", "modeling/geometry_nodes/mesh/read/edge_neighbors.html#bpy-types-geometrynodeinputmeshedgeneighbors"), + ("bpy.types.geometrynodeinputmeshfaceneighbors*", "modeling/geometry_nodes/mesh/read/face_neighbors.html#bpy-types-geometrynodeinputmeshfaceneighbors"), + ("bpy.types.geometrynodeinputshortestedgepaths*", "modeling/geometry_nodes/mesh/read/shortest_edge_paths.html#bpy-types-geometrynodeinputshortestedgepaths"), ("bpy.types.gpencilsculptguide.reference_point*", "grease_pencil/modes/draw/guides.html#bpy-types-gpencilsculptguide-reference-point"), ("bpy.types.greasepencil.edit_curve_resolution*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-edit-curve-resolution"), ("bpy.types.lineartgpencilmodifier.use_contour*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-contour"), @@ -613,6 +625,9 @@ url_manual_mapping = ( ("bpy.types.sculpt.use_automasking_view_normal*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-view-normal"), ("bpy.types.sequencertimelineoverlay.show_grid*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay-show-grid"), ("bpy.types.sequencertoolsettings.overlap_mode*", "video_editing/edit/montage/editing.html#bpy-types-sequencertoolsettings-overlap-mode"), + ("bpy.types.softbodysettings.aerodynamics_type*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-aerodynamics-type"), + ("bpy.types.softbodysettings.vertex_group_goal*", "physics/soft_body/settings/goal.html#bpy-types-softbodysettings-vertex-group-goal"), + ("bpy.types.softbodysettings.vertex_group_mass*", "physics/soft_body/settings/object.html#bpy-types-softbodysettings-vertex-group-mass"), ("bpy.types.spaceclipeditor.show_green_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-green-channel"), ("bpy.types.spacenodeoverlay.show_context_path*", "interface/controls/nodes/introduction.html#bpy-types-spacenodeoverlay-show-context-path"), ("bpy.types.spaceoutliner.show_restrict_column*", "editors/outliner/interface.html#bpy-types-spaceoutliner-show-restrict-column"), @@ -652,12 +667,12 @@ url_manual_mapping = ( ("bpy.types.freestylelineset.select_edge_mark*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-select-edge-mark"), ("bpy.types.freestylelinestyle.use_length_max*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-length-max"), ("bpy.types.freestylelinestyle.use_length_min*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-length-min"), - ("bpy.types.geometrynodedeformcurvesonsurface*", "modeling/geometry_nodes/curve/deform_curves_on_surface.html#bpy-types-geometrynodedeformcurvesonsurface"), + ("bpy.types.geometrynodedeformcurvesonsurface*", "modeling/geometry_nodes/curve/operations/deform_curves_on_surface.html#bpy-types-geometrynodedeformcurvesonsurface"), ("bpy.types.geometrynodeinputinstancerotation*", "modeling/geometry_nodes/instances/instance_rotation.html#bpy-types-geometrynodeinputinstancerotation"), - ("bpy.types.geometrynodeinputmeshedgevertices*", "modeling/geometry_nodes/mesh/edge_vertices.html#bpy-types-geometrynodeinputmeshedgevertices"), - ("bpy.types.geometrynodeinputmeshfaceisplanar*", "modeling/geometry_nodes/mesh/face_is_planar.html#bpy-types-geometrynodeinputmeshfaceisplanar"), - ("bpy.types.geometrynodeinputsplineresolution*", "modeling/geometry_nodes/curve/spline_resolution.html#bpy-types-geometrynodeinputsplineresolution"), - ("bpy.types.geometrynodemeshfacesetboundaries*", "modeling/geometry_nodes/mesh/face_set_boundaries.html#bpy-types-geometrynodemeshfacesetboundaries"), + ("bpy.types.geometrynodeinputmeshedgevertices*", "modeling/geometry_nodes/mesh/read/edge_vertices.html#bpy-types-geometrynodeinputmeshedgevertices"), + ("bpy.types.geometrynodeinputmeshfaceisplanar*", "modeling/geometry_nodes/mesh/read/face_is_planar.html#bpy-types-geometrynodeinputmeshfaceisplanar"), + ("bpy.types.geometrynodeinputsplineresolution*", "modeling/geometry_nodes/curve/read/spline_resolution.html#bpy-types-geometrynodeinputsplineresolution"), + ("bpy.types.geometrynodemeshfacesetboundaries*", "modeling/geometry_nodes/mesh/read/face_set_boundaries.html#bpy-types-geometrynodemeshfacesetboundaries"), ("bpy.types.greasepencil.curve_edit_threshold*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-threshold"), ("bpy.types.lineartgpencilmodifier.use_crease*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-crease"), ("bpy.types.lineartgpencilmodifier.use_shadow*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-shadow"), @@ -669,6 +684,7 @@ url_manual_mapping = ( ("bpy.types.rendersettings.use_crop_to_border*", "render/output/properties/format.html#bpy-types-rendersettings-use-crop-to-border"), ("bpy.types.rendersettings.use_file_extension*", "render/output/properties/output.html#bpy-types-rendersettings-use-file-extension"), ("bpy.types.sculpt.constant_detail_resolution*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-constant-detail-resolution"), + ("bpy.types.sequencemodifier.input_mask_strip*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-sequencemodifier-input-mask-strip"), ("bpy.types.sequencertoolsettings.pivot_point*", "editors/video_sequencer/preview/controls/pivot_point.html#bpy-types-sequencertoolsettings-pivot-point"), ("bpy.types.spaceclipeditor.annotation_source*", "movie_clip/tracking/clip/sidebar/view.html#bpy-types-spaceclipeditor-annotation-source"), ("bpy.types.spaceclipeditor.mask_display_type*", "editors/clip/display/mask_display.html#bpy-types-spaceclipeditor-mask-display-type"), @@ -676,6 +692,7 @@ url_manual_mapping = ( ("bpy.types.spaceclipeditor.show_blue_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-blue-channel"), ("bpy.types.spaceclipeditor.show_mask_overlay*", "editors/clip/display/mask_display.html#bpy-types-spaceclipeditor-show-mask-overlay"), ("bpy.types.spacefilebrowser.system_bookmarks*", "editors/file_browser.html#bpy-types-spacefilebrowser-system-bookmarks"), + ("bpy.types.spaceimageeditor.display_channels*", "editors/image/introduction.html#bpy-types-spaceimageeditor-display-channels"), ("bpy.types.spaceoutliner.use_filter_children*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-children"), ("bpy.types.spaceoutliner.use_filter_complete*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-filter-complete"), ("bpy.types.spacespreadsheet.attribute_domain*", "editors/spreadsheet.html#bpy-types-spacespreadsheet-attribute-domain"), @@ -730,10 +747,10 @@ url_manual_mapping = ( ("bpy.types.freestylelinestyle.use_angle_min*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-angle-min"), ("bpy.types.freestylesettings.as_render_pass*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-as-render-pass"), ("bpy.types.freestylesettings.use_smoothness*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-smoothness"), - ("bpy.types.geometrynodecurveprimitivecircle*", "modeling/geometry_nodes/curve_primitives/curve_circle.html#bpy-types-geometrynodecurveprimitivecircle"), - ("bpy.types.geometrynodecurvequadraticbezier*", "modeling/geometry_nodes/curve_primitives/quadratic_bezier.html#bpy-types-geometrynodecurvequadraticbezier"), + ("bpy.types.geometrynodecurveprimitivecircle*", "modeling/geometry_nodes/curve/primitives/curve_circle.html#bpy-types-geometrynodecurveprimitivecircle"), + ("bpy.types.geometrynodecurvequadraticbezier*", "modeling/geometry_nodes/curve/primitives/quadratic_bezier.html#bpy-types-geometrynodecurvequadraticbezier"), ("bpy.types.geometrynoderemovenamedattribute*", "modeling/geometry_nodes/attribute/remove_named_attribute.html#bpy-types-geometrynoderemovenamedattribute"), - ("bpy.types.geometrynodesamplenearestsurface*", "modeling/geometry_nodes/mesh/sample_nearest_surface.html#bpy-types-geometrynodesamplenearestsurface"), + ("bpy.types.geometrynodesamplenearestsurface*", "modeling/geometry_nodes/mesh/operations/sample_nearest_surface.html#bpy-types-geometrynodesamplenearestsurface"), ("bpy.types.gpencillayer.use_viewlayer_masks*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-viewlayer-masks"), ("bpy.types.greasepencil.onion_keyframe_type*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-keyframe-type"), ("bpy.types.lineartgpencilmodifier.use_cache*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-cache"), @@ -744,8 +761,12 @@ url_manual_mapping = ( ("bpy.types.movietrackingcamera.sensor_width*", "movie_clip/tracking/clip/sidebar/track/camera.html#bpy-types-movietrackingcamera-sensor-width"), ("bpy.types.posebone.use_ik_rotation_control*", "animation/armatures/posing/bone_constraints/inverse_kinematics/introduction.html#bpy-types-posebone-use-ik-rotation-control"), ("bpy.types.rendersettings.use_bake_multires*", "render/cycles/baking.html#bpy-types-rendersettings-use-bake-multires"), + ("bpy.types.rigidbodyobject.collision_margin*", "physics/rigid_body/properties/collisions.html#bpy-types-rigidbodyobject-collision-margin"), ("bpy.types.scenegpencil.antialias_threshold*", "render/cycles/render_settings/grease_pencil.html#bpy-types-scenegpencil-antialias-threshold"), ("bpy.types.sculpt.use_automasking_face_sets*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-face-sets"), + ("bpy.types.sequencemodifier.input_mask_type*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-sequencemodifier-input-mask-type"), + ("bpy.types.softbodysettings.error_threshold*", "physics/soft_body/settings/solver.html#bpy-types-softbodysettings-error-threshold"), + ("bpy.types.softbodysettings.use_stiff_quads*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-use-stiff-quads"), ("bpy.types.spaceclipeditor.show_mask_spline*", "editors/clip/display/mask_display.html#bpy-types-spaceclipeditor-show-mask-spline"), ("bpy.types.spaceclipeditor.show_red_channel*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-red-channel"), ("bpy.types.spaceclipeditor.use_mute_footage*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-use-mute-footage"), @@ -803,7 +824,7 @@ url_manual_mapping = ( ("bpy.types.freestylelinestyle.use_chaining*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-chaining"), ("bpy.types.freestylesettings.sphere_radius*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-sphere-radius"), ("bpy.types.geometrynodeattributedomainsize*", "modeling/geometry_nodes/attribute/domain_size.html#bpy-types-geometrynodeattributedomainsize"), - ("bpy.types.geometrynodesetsplineresolution*", "modeling/geometry_nodes/curve/set_spline_resolution.html#bpy-types-geometrynodesetsplineresolution"), + ("bpy.types.geometrynodesetsplineresolution*", "modeling/geometry_nodes/curve/write/set_spline_resolution.html#bpy-types-geometrynodesetsplineresolution"), ("bpy.types.geometrynodestorenamedattribute*", "modeling/geometry_nodes/attribute/store_named_attribute.html#bpy-types-geometrynodestorenamedattribute"), ("bpy.types.gpencillayer.annotation_opacity*", "interface/annotate_tool.html#bpy-types-gpencillayer-annotation-opacity"), ("bpy.types.gpencillayer.use_onion_skinning*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-onion-skinning"), @@ -825,8 +846,10 @@ url_manual_mapping = ( ("bpy.types.rendersettings.simplify_volumes*", "render/cycles/render_settings/simplify.html#bpy-types-rendersettings-simplify-volumes"), ("bpy.types.rendersettings.use_render_cache*", "render/output/properties/output.html#bpy-types-rendersettings-use-render-cache"), ("bpy.types.rendersettings.use_single_layer*", "render/layers/view_layer.html#bpy-types-rendersettings-use-single-layer"), + ("bpy.types.rigidbodyobject.collision_shape*", "physics/rigid_body/properties/collisions.html#bpy-types-rigidbodyobject-collision-shape"), ("bpy.types.sceneeevee.use_taa_reprojection*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-use-taa-reprojection"), ("bpy.types.sculpt.use_automasking_topology*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-topology"), + ("bpy.types.softbodysettings.collision_type*", "physics/soft_body/settings/self_collision.html#bpy-types-softbodysettings-collision-type"), ("bpy.types.spaceclipeditor.cursor_location*", "editors/clip/sidebar.html#bpy-types-spaceclipeditor-cursor-location"), ("bpy.types.spacefilebrowser.recent_folders*", "editors/file_browser.html#bpy-types-spacefilebrowser-recent-folders"), ("bpy.types.spacefilebrowser.system_folders*", "editors/file_browser.html#bpy-types-spacefilebrowser-system-folders"), @@ -885,17 +908,17 @@ url_manual_mapping = ( ("bpy.types.freestylelinestyle.chain_count*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-chain-count"), ("bpy.types.freestylelinestyle.use_sorting*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-use-sorting"), ("bpy.types.freestylesettings.crease_angle*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-crease-angle"), - ("bpy.types.functionnodealigneulertovector*", "modeling/geometry_nodes/utilities/align_euler_to_vector.html#bpy-types-functionnodealigneulertovector"), + ("bpy.types.functionnodealigneulertovector*", "modeling/geometry_nodes/utilities/rotation/align_euler_to_vector.html#bpy-types-functionnodealigneulertovector"), ("bpy.types.geometrynodeattributestatistic*", "modeling/geometry_nodes/attribute/attribute_statistic.html#bpy-types-geometrynodeattributestatistic"), - ("bpy.types.geometrynodecurveprimitiveline*", "modeling/geometry_nodes/curve_primitives/curve_line.html#bpy-types-geometrynodecurveprimitiveline"), + ("bpy.types.geometrynodecurveprimitiveline*", "modeling/geometry_nodes/curve/primitives/curve_line.html#bpy-types-geometrynodecurveprimitiveline"), ("bpy.types.geometrynodegeometrytoinstance*", "modeling/geometry_nodes/geometry/geometry_to_instance.html#bpy-types-geometrynodegeometrytoinstance"), ("bpy.types.geometrynodeinputinstancescale*", "modeling/geometry_nodes/instances/instance_scale.html#bpy-types-geometrynodeinputinstancescale"), ("bpy.types.geometrynodeinputmaterialindex*", "modeling/geometry_nodes/material/material_index.html#bpy-types-geometrynodeinputmaterialindex"), - ("bpy.types.geometrynodeinputmeshedgeangle*", "modeling/geometry_nodes/mesh/edge_angle.html#bpy-types-geometrynodeinputmeshedgeangle"), - ("bpy.types.geometrynodeoffsetcornerinface*", "modeling/geometry_nodes/mesh_topology/offset_corner_in_face.html#bpy-types-geometrynodeoffsetcornerinface"), - ("bpy.types.geometrynodeoffsetpointincurve*", "modeling/geometry_nodes/curve_topology/offset_point_in_curve.html#bpy-types-geometrynodeoffsetpointincurve"), - ("bpy.types.geometrynodeseparatecomponents*", "modeling/geometry_nodes/geometry/separate_components.html#bpy-types-geometrynodeseparatecomponents"), - ("bpy.types.geometrynodesubdivisionsurface*", "modeling/geometry_nodes/mesh/subdivision_surface.html#bpy-types-geometrynodesubdivisionsurface"), + ("bpy.types.geometrynodeinputmeshedgeangle*", "modeling/geometry_nodes/mesh/read/edge_angle.html#bpy-types-geometrynodeinputmeshedgeangle"), + ("bpy.types.geometrynodeoffsetcornerinface*", "modeling/geometry_nodes/mesh/topology/offset_corner_in_face.html#bpy-types-geometrynodeoffsetcornerinface"), + ("bpy.types.geometrynodeoffsetpointincurve*", "modeling/geometry_nodes/curve/topology/offset_point_in_curve.html#bpy-types-geometrynodeoffsetpointincurve"), + ("bpy.types.geometrynodeseparatecomponents*", "modeling/geometry_nodes/geometry/operations/separate_components.html#bpy-types-geometrynodeseparatecomponents"), + ("bpy.types.geometrynodesubdivisionsurface*", "modeling/geometry_nodes/mesh/operations/subdivision_surface.html#bpy-types-geometrynodesubdivisionsurface"), ("bpy.types.geometrynodetranslateinstances*", "modeling/geometry_nodes/instances/translate_instances.html#bpy-types-geometrynodetranslateinstances"), ("bpy.types.greasepencil.ghost_after_range*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-ghost-after-range"), ("bpy.types.greasepencil.use_ghosts_always*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-use-ghosts-always"), @@ -920,7 +943,11 @@ url_manual_mapping = ( ("bpy.types.rendersettings.use_compositing*", "render/output/properties/post_processing.html#bpy-types-rendersettings-use-compositing"), ("bpy.types.rendersettings.use_motion_blur*", "render/cycles/render_settings/motion_blur.html#bpy-types-rendersettings-use-motion-blur"), ("bpy.types.rendersettings.use_placeholder*", "render/output/properties/output.html#bpy-types-rendersettings-use-placeholder"), + ("bpy.types.sequencemodifier.input_mask_id*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-sequencemodifier-input-mask-id"), ("bpy.types.shadernodesubsurfacescattering*", "render/shader_nodes/shader/sss.html#bpy-types-shadernodesubsurfacescattering"), + ("bpy.types.softbodysettings.goal_friction*", "physics/soft_body/settings/goal.html#bpy-types-softbodysettings-goal-friction"), + ("bpy.types.softbodysettings.spring_length*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-spring-length"), + ("bpy.types.softbodysettings.use_auto_step*", "physics/soft_body/settings/solver.html#bpy-types-softbodysettings-use-auto-step"), ("bpy.types.spaceclipeditor.lock_selection*", "editors/clip/introduction.html#bpy-types-spaceclipeditor-lock-selection"), ("bpy.types.spacedopesheeteditor.auto_snap*", "editors/dope_sheet/editing.html#bpy-types-spacedopesheeteditor-auto-snap"), ("bpy.types.spacenodeoverlay.show_overlays*", "interface/controls/nodes/introduction.html#bpy-types-spacenodeoverlay-show-overlays"), @@ -989,9 +1016,9 @@ url_manual_mapping = ( ("bpy.types.freestylelinestyle.sort_order*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-sort-order"), ("bpy.types.freestylelinestyle.split_dash*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-split-dash"), ("bpy.types.freestylesettings.use_culling*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-use-culling"), - ("bpy.types.geometrynodeduplicateelements*", "modeling/geometry_nodes/geometry/duplicate_elements.html#bpy-types-geometrynodeduplicateelements"), - ("bpy.types.geometrynodeinputmeshfacearea*", "modeling/geometry_nodes/mesh/face_area.html#bpy-types-geometrynodeinputmeshfacearea"), - ("bpy.types.geometrynodeinputsplinecyclic*", "modeling/geometry_nodes/curve/is_spline_cyclic.html#bpy-types-geometrynodeinputsplinecyclic"), + ("bpy.types.geometrynodeduplicateelements*", "modeling/geometry_nodes/geometry/operations/duplicate_elements.html#bpy-types-geometrynodeduplicateelements"), + ("bpy.types.geometrynodeinputmeshfacearea*", "modeling/geometry_nodes/mesh/read/face_area.html#bpy-types-geometrynodeinputmeshfacearea"), + ("bpy.types.geometrynodeinputsplinecyclic*", "modeling/geometry_nodes/curve/read/is_spline_cyclic.html#bpy-types-geometrynodeinputsplinecyclic"), ("bpy.types.geometrynodeinstancestopoints*", "modeling/geometry_nodes/instances/instances_to_points.html#bpy-types-geometrynodeinstancestopoints"), ("bpy.types.gpencillayer.viewlayer_render*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-viewlayer-render"), ("bpy.types.imagepaint.use_normal_falloff*", "sculpt_paint/brush/falloff.html#bpy-types-imagepaint-use-normal-falloff"), @@ -1011,6 +1038,8 @@ url_manual_mapping = ( ("bpy.types.sceneeevee.taa_render_samples*", "render/eevee/render_settings/sampling.html#bpy-types-sceneeevee-taa-render-samples"), ("bpy.types.sculpt.use_automasking_cavity*", "sculpt_paint/sculpting/controls.html#bpy-types-sculpt-use-automasking-cavity"), ("bpy.types.sequence.frame_final_duration*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequence-frame-final-duration"), + ("bpy.types.softbodysettings.goal_default*", "physics/soft_body/settings/goal.html#bpy-types-softbodysettings-goal-default"), + ("bpy.types.softbodysettings.use_diagnose*", "physics/soft_body/settings/solver.html#bpy-types-softbodysettings-use-diagnose"), ("bpy.types.spaceoutliner.use_sync_select*", "editors/outliner/interface.html#bpy-types-spaceoutliner-use-sync-select"), ("bpy.types.spaceproperties.outliner_sync*", "editors/properties_editor.html#bpy-types-spaceproperties-outliner-sync"), ("bpy.types.spaceproperties.search_filter*", "editors/properties_editor.html#bpy-types-spaceproperties-search-filter"), @@ -1069,11 +1098,11 @@ url_manual_mapping = ( ("bpy.types.freestylelinestyle.split_gap*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-split-gap"), ("bpy.types.freestylelinestyle.use_nodes*", "render/freestyle/view_layer/line_style/texture.html#bpy-types-freestylelinestyle-use-nodes"), ("bpy.types.geometrynodecaptureattribute*", "modeling/geometry_nodes/attribute/capture_attribute.html#bpy-types-geometrynodecaptureattribute"), - ("bpy.types.geometrynodeinputshadesmooth*", "modeling/geometry_nodes/mesh/is_shade_smooth.html#bpy-types-geometrynodeinputshadesmooth"), + ("bpy.types.geometrynodeinputshadesmooth*", "modeling/geometry_nodes/mesh/read/is_shade_smooth.html#bpy-types-geometrynodeinputshadesmooth"), ("bpy.types.geometrynodeinstanceonpoints*", "modeling/geometry_nodes/instances/instance_on_points.html#bpy-types-geometrynodeinstanceonpoints"), ("bpy.types.geometrynodepointstovertices*", "modeling/geometry_nodes/point/points_to_vertices.html#bpy-types-geometrynodepointstovertices"), ("bpy.types.geometrynoderealizeinstances*", "modeling/geometry_nodes/instances/realize_instances.html#bpy-types-geometrynoderealizeinstances"), - ("bpy.types.geometrynodeseparategeometry*", "modeling/geometry_nodes/geometry/separate_geometry.html#bpy-types-geometrynodeseparategeometry"), + ("bpy.types.geometrynodeseparategeometry*", "modeling/geometry_nodes/geometry/operations/separate_geometry.html#bpy-types-geometrynodeseparategeometry"), ("bpy.types.geometrynodesetmaterialindex*", "modeling/geometry_nodes/material/set_material_index.html#bpy-types-geometrynodesetmaterialindex"), ("bpy.types.greasepencil.edit_line_color*", "grease_pencil/properties/display.html#bpy-types-greasepencil-edit-line-color"), ("bpy.types.material.preview_render_type*", "render/materials/preview.html#bpy-types-material-preview-render-type"), @@ -1094,6 +1123,7 @@ url_manual_mapping = ( ("bpy.types.sequencetimelinechannel.name*", "editors/video_sequencer/sequencer/channels.html#bpy-types-sequencetimelinechannel-name"), ("bpy.types.shadernodebsdfhairprincipled*", "render/shader_nodes/shader/hair_principled.html#bpy-types-shadernodebsdfhairprincipled"), ("bpy.types.shadernodevectordisplacement*", "render/shader_nodes/vector/vector_displacement.html#bpy-types-shadernodevectordisplacement"), + ("bpy.types.softbodysettings.goal_spring*", "physics/soft_body/settings/goal.html#bpy-types-softbodysettings-goal-spring"), ("bpy.types.spaceclipeditor.blend_factor*", "editors/clip/display/mask_display.html#bpy-types-spaceclipeditor-blend-factor"), ("bpy.types.spacegrapheditor.show_cursor*", "editors/graph_editor/introduction.html#bpy-types-spacegrapheditor-show-cursor"), ("bpy.types.spaceimageeditor.show_repeat*", "editors/image/sidebar.html#bpy-types-spaceimageeditor-show-repeat"), @@ -1141,6 +1171,7 @@ url_manual_mapping = ( ("bpy.types.brush.boundary_falloff_type*", "sculpt_paint/sculpting/tools/boundary.html#bpy-types-brush-boundary-falloff-type"), ("bpy.types.brush.cursor_color_subtract*", "sculpt_paint/brush/cursor.html#bpy-types-brush-cursor-color-subtract"), ("bpy.types.brush.texture_overlay_alpha*", "sculpt_paint/brush/cursor.html#bpy-types-brush-texture-overlay-alpha"), + ("bpy.types.brush.use_frontface_falloff*", "sculpt_paint/brush/falloff.html#bpy-types-brush-use-frontface-falloff"), ("bpy.types.brush.use_space_attenuation*", "sculpt_paint/brush/stroke.html#bpy-types-brush-use-space-attenuation"), ("bpy.types.brushgpencilsettings.aspect*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-aspect"), ("bpy.types.brushgpencilsettings.dilate*", "grease_pencil/modes/draw/tools/fill.html#bpy-types-brushgpencilsettings-dilate"), @@ -1172,17 +1203,17 @@ url_manual_mapping = ( ("bpy.types.freestylelineset.visibility*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-visibility"), ("bpy.types.freestylelinestyle.chaining*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-chaining"), ("bpy.types.freestylelinestyle.sort_key*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-sort-key"), - ("bpy.types.geometrynodeaccumulatefield*", "modeling/geometry_nodes/utilities/accumulate_field.html#bpy-types-geometrynodeaccumulatefield"), - ("bpy.types.geometrynodecornersofvertex*", "modeling/geometry_nodes/mesh_topology/corners_of_vertex.html#bpy-types-geometrynodecornersofvertex"), - ("bpy.types.geometrynodecurvesethandles*", "modeling/geometry_nodes/curve/set_handle_type.html#bpy-types-geometrynodecurvesethandles"), - ("bpy.types.geometrynodecurvesplinetype*", "modeling/geometry_nodes/curve/set_spline_type.html#bpy-types-geometrynodecurvesplinetype"), - ("bpy.types.geometrynodeinputmeshisland*", "modeling/geometry_nodes/mesh/mesh_island.html#bpy-types-geometrynodeinputmeshisland"), - ("bpy.types.geometrynodemergebydistance*", "modeling/geometry_nodes/geometry/merge_by_distance.html#bpy-types-geometrynodemergebydistance"), + ("bpy.types.geometrynodeaccumulatefield*", "modeling/geometry_nodes/utilities/field/accumulate_field.html#bpy-types-geometrynodeaccumulatefield"), + ("bpy.types.geometrynodecornersofvertex*", "modeling/geometry_nodes/mesh/topology/corners_of_vertex.html#bpy-types-geometrynodecornersofvertex"), + ("bpy.types.geometrynodecurvesethandles*", "modeling/geometry_nodes/curve/write/set_handle_type.html#bpy-types-geometrynodecurvesethandles"), + ("bpy.types.geometrynodecurvesplinetype*", "modeling/geometry_nodes/curve/write/set_spline_type.html#bpy-types-geometrynodecurvesplinetype"), + ("bpy.types.geometrynodeinputmeshisland*", "modeling/geometry_nodes/mesh/read/mesh_island.html#bpy-types-geometrynodeinputmeshisland"), + ("bpy.types.geometrynodemergebydistance*", "modeling/geometry_nodes/geometry/operations/merge_by_distance.html#bpy-types-geometrynodemergebydistance"), ("bpy.types.geometrynodereplacematerial*", "modeling/geometry_nodes/material/replace_material.html#bpy-types-geometrynodereplacematerial"), ("bpy.types.geometrynoderotateinstances*", "modeling/geometry_nodes/instances/rotate_instances.html#bpy-types-geometrynoderotateinstances"), - ("bpy.types.geometrynodesampleuvsurface*", "modeling/geometry_nodes/mesh/sample_uv_surface.html#bpy-types-geometrynodesampleuvsurface"), - ("bpy.types.geometrynodesetsplinecyclic*", "modeling/geometry_nodes/curve/set_spline_cyclic.html#bpy-types-geometrynodesetsplinecyclic"), - ("bpy.types.geometrynodesplineparameter*", "modeling/geometry_nodes/curve/spline_parameter.html#bpy-types-geometrynodesplineparameter"), + ("bpy.types.geometrynodesampleuvsurface*", "modeling/geometry_nodes/mesh/operations/sample_uv_surface.html#bpy-types-geometrynodesampleuvsurface"), + ("bpy.types.geometrynodesetsplinecyclic*", "modeling/geometry_nodes/curve/write/set_spline_cyclic.html#bpy-types-geometrynodesetsplinecyclic"), + ("bpy.types.geometrynodesplineparameter*", "modeling/geometry_nodes/curve/read/spline_parameter.html#bpy-types-geometrynodesplineparameter"), ("bpy.types.gpencillayer.use_mask_layer*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-mask-layer"), ("bpy.types.greasepencil.use_curve_edit*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-use-curve-edit"), ("bpy.types.greasepencil.use_onion_fade*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-use-onion-fade"), @@ -1202,12 +1233,15 @@ url_manual_mapping = ( ("bpy.types.rigidbodyconstraint.enabled*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-enabled"), ("bpy.types.rigidbodyconstraint.object1*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-object1"), ("bpy.types.rigidbodyconstraint.object2*", "physics/rigid_body/constraints/introduction.html#bpy-types-rigidbodyconstraint-object2"), + ("bpy.types.rigidbodyobject.mesh_source*", "physics/rigid_body/properties/collisions.html#bpy-types-rigidbodyobject-mesh-source"), + ("bpy.types.rigidbodyobject.restitution*", "physics/rigid_body/properties/collisions.html#bpy-types-rigidbodyobject-restitution"), ("bpy.types.sceneeevee.volumetric_light*", "render/eevee/render_settings/volumetrics.html#bpy-types-sceneeevee-volumetric-light"), ("bpy.types.sculpt.detail_refine_method*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-detail-refine-method"), ("bpy.types.sculpt.symmetrize_direction*", "sculpt_paint/sculpting/tool_settings/symmetry.html#bpy-types-sculpt-symmetrize-direction"), ("bpy.types.sequence.frame_offset_start*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequence-frame-offset-start"), ("bpy.types.sequenceeditor.show_overlay*", "editors/video_sequencer/preview/sidebar.html#bpy-types-sequenceeditor-show-overlay"), ("bpy.types.sequenceeditor.use_prefetch*", "editors/video_sequencer/preview/sidebar.html#bpy-types-sequenceeditor-use-prefetch"), + ("bpy.types.softbodysettings.ball_stiff*", "physics/soft_body/settings/self_collision.html#bpy-types-softbodysettings-ball-stiff"), ("bpy.types.soundsequence.show_waveform*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-soundsequence-show-waveform"), ("bpy.types.spaceclipeditor.show_stable*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-stable"), ("bpy.types.spaceimageeditor.show_gizmo*", "editors/image/introduction.html#bpy-types-spaceimageeditor-show-gizmo"), @@ -1267,20 +1301,20 @@ url_manual_mapping = ( ("bpy.types.fileselectparams.directory*", "editors/file_browser.html#bpy-types-fileselectparams-directory"), ("bpy.types.fluidflowsettings.use_flow*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-use-flow"), ("bpy.types.fmodifierfunctiongenerator*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierfunctiongenerator"), - ("bpy.types.geometrynodecollectioninfo*", "modeling/geometry_nodes/input/collection_info.html#bpy-types-geometrynodecollectioninfo"), - ("bpy.types.geometrynodedeletegeometry*", "modeling/geometry_nodes/geometry/delete_geometry.html#bpy-types-geometrynodedeletegeometry"), - ("bpy.types.geometrynodeinputcurvetilt*", "modeling/geometry_nodes/curve/curve_tilt.html#bpy-types-geometrynodeinputcurvetilt"), - ("bpy.types.geometrynodeinputscenetime*", "modeling/geometry_nodes/input/scene_time.html#bpy-types-geometrynodeinputscenetime"), - ("bpy.types.geometrynodenamedattribute*", "modeling/geometry_nodes/input/named_attribute.html#bpy-types-geometrynodenamedattribute"), + ("bpy.types.geometrynodecollectioninfo*", "modeling/geometry_nodes/input/scene/collection_info.html#bpy-types-geometrynodecollectioninfo"), + ("bpy.types.geometrynodedeletegeometry*", "modeling/geometry_nodes/geometry/operations/delete_geometry.html#bpy-types-geometrynodedeletegeometry"), + ("bpy.types.geometrynodeinputcurvetilt*", "modeling/geometry_nodes/curve/read/curve_tilt.html#bpy-types-geometrynodeinputcurvetilt"), + ("bpy.types.geometrynodeinputscenetime*", "modeling/geometry_nodes/input/scene/scene_time.html#bpy-types-geometrynodeinputscenetime"), + ("bpy.types.geometrynodenamedattribute*", "modeling/geometry_nodes/geometry/read/named_attribute.html#bpy-types-geometrynodenamedattribute"), ("bpy.types.geometrynodepointstovolume*", "modeling/geometry_nodes/point/points_to_volume.html#bpy-types-geometrynodepointstovolume"), ("bpy.types.geometrynodescaleinstances*", "modeling/geometry_nodes/instances/scale_instances.html#bpy-types-geometrynodescaleinstances"), - ("bpy.types.geometrynodesetcurvenormal*", "modeling/geometry_nodes/curve/set_curve_normal.html#bpy-types-geometrynodesetcurvenormal"), - ("bpy.types.geometrynodesetcurveradius*", "modeling/geometry_nodes/curve/set_curve_radius.html#bpy-types-geometrynodesetcurveradius"), + ("bpy.types.geometrynodesetcurvenormal*", "modeling/geometry_nodes/curve/write/set_curve_normal.html#bpy-types-geometrynodesetcurvenormal"), + ("bpy.types.geometrynodesetcurveradius*", "modeling/geometry_nodes/curve/write/set_curve_radius.html#bpy-types-geometrynodesetcurveradius"), ("bpy.types.geometrynodesetpointradius*", "modeling/geometry_nodes/point/set_point_radius.html#bpy-types-geometrynodesetpointradius"), - ("bpy.types.geometrynodesetshadesmooth*", "modeling/geometry_nodes/mesh/set_shade_smooth.html#bpy-types-geometrynodesetshadesmooth"), - ("bpy.types.geometrynodestringtocurves*", "modeling/geometry_nodes/text/string_to_curves.html#bpy-types-geometrynodestringtocurves"), - ("bpy.types.geometrynodesubdividecurve*", "modeling/geometry_nodes/curve/subdivide_curve.html#bpy-types-geometrynodesubdividecurve"), - ("bpy.types.geometrynodevertexofcorner*", "modeling/geometry_nodes/mesh_topology/vertex_of_corner.html#bpy-types-geometrynodevertexofcorner"), + ("bpy.types.geometrynodesetshadesmooth*", "modeling/geometry_nodes/mesh/write/set_shade_smooth.html#bpy-types-geometrynodesetshadesmooth"), + ("bpy.types.geometrynodestringtocurves*", "modeling/geometry_nodes/utilities/text/string_to_curves.html#bpy-types-geometrynodestringtocurves"), + ("bpy.types.geometrynodesubdividecurve*", "modeling/geometry_nodes/curve/operations/subdivide_curve.html#bpy-types-geometrynodesubdividecurve"), + ("bpy.types.geometrynodevertexofcorner*", "modeling/geometry_nodes/mesh/topology/vertex_of_corner.html#bpy-types-geometrynodevertexofcorner"), ("bpy.types.gpencillayer.channel_color*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-channel-color"), ("bpy.types.gpencillayer.use_solo_mode*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-use-solo-mode"), ("bpy.types.greasepencil.use_multiedit*", "grease_pencil/multiframe.html#bpy-types-greasepencil-use-multiedit"), @@ -1292,12 +1326,17 @@ url_manual_mapping = ( ("bpy.types.object.show_only_shape_key*", "animation/shape_keys/shape_keys_panel.html#bpy-types-object-show-only-shape-key"), ("bpy.types.regionview3d.lock_rotation*", "editors/3dview/navigate/views.html#bpy-types-regionview3d-lock-rotation"), ("bpy.types.rendersettings.hair_subdiv*", "render/eevee/render_settings/hair.html#bpy-types-rendersettings-hair-subdiv"), + ("bpy.types.rigidbodyobject.use_deform*", "physics/rigid_body/properties/collisions.html#bpy-types-rigidbodyobject-use-deform"), ("bpy.types.scene.audio_distance_model*", "scene_layout/scene/properties.html#bpy-types-scene-audio-distance-model"), ("bpy.types.scene.audio_doppler_factor*", "scene_layout/scene/properties.html#bpy-types-scene-audio-doppler-factor"), + ("bpy.types.sequencemodifier.mask_time*", "editors/video_sequencer/sequencer/sidebar/modifiers.html#bpy-types-sequencemodifier-mask-time"), ("bpy.types.sequencetransform.rotation*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-rotation"), ("bpy.types.shadernodeambientocclusion*", "render/shader_nodes/input/ao.html#bpy-types-shadernodeambientocclusion"), ("bpy.types.shadernodevolumeabsorption*", "render/shader_nodes/shader/volume_absorption.html#bpy-types-shadernodevolumeabsorption"), ("bpy.types.shadernodevolumeprincipled*", "render/shader_nodes/shader/volume_principled.html#bpy-types-shadernodevolumeprincipled"), + ("bpy.types.softbodysettings.ball_damp*", "physics/soft_body/settings/self_collision.html#bpy-types-softbodysettings-ball-damp"), + ("bpy.types.softbodysettings.ball_size*", "physics/soft_body/settings/self_collision.html#bpy-types-softbodysettings-ball-size"), + ("bpy.types.softbodysettings.use_edges*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-use-edges"), ("bpy.types.spacefilebrowser.bookmarks*", "editors/file_browser.html#bpy-types-spacefilebrowser-bookmarks"), ("bpy.types.spaceoutliner.display_mode*", "editors/outliner/interface.html#bpy-types-spaceoutliner-display-mode"), ("bpy.types.spaceoutliner.filter_state*", "editors/outliner/interface.html#bpy-types-spaceoutliner-filter-state"), @@ -1375,22 +1414,22 @@ url_manual_mapping = ( ("bpy.types.fluidflowsettings.density*", "physics/fluid/type/flow.html#bpy-types-fluidflowsettings-density"), ("bpy.types.freestylelineset.qi_start*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-qi-start"), ("bpy.types.freestylelinestyle.rounds*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-rounds"), - ("bpy.types.functionnodereplacestring*", "modeling/geometry_nodes/text/replace_string.html#bpy-types-functionnodereplacestring"), - ("bpy.types.functionnodeseparatecolor*", "modeling/geometry_nodes/color/separate_color.html#bpy-types-functionnodeseparatecolor"), - ("bpy.types.functionnodevaluetostring*", "modeling/geometry_nodes/text/value_to_string.html#bpy-types-functionnodevaluetostring"), - ("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/curve_to_points.html#bpy-types-geometrynodecurvetopoints"), - ("bpy.types.geometrynodeedgesofcorner*", "modeling/geometry_nodes/mesh_topology/edges_of_corner.html#bpy-types-geometrynodeedgesofcorner"), - ("bpy.types.geometrynodeedgesofvertex*", "modeling/geometry_nodes/mesh_topology/edges_of_vertex.html#bpy-types-geometrynodeedgesofvertex"), - ("bpy.types.geometrynodefieldondomain*", "modeling/geometry_nodes/utilities/interpolate_domain.html#bpy-types-geometrynodefieldondomain"), - ("bpy.types.geometrynodeinputmaterial*", "modeling/geometry_nodes/input/material.html#bpy-types-geometrynodeinputmaterial"), - ("bpy.types.geometrynodeinputposition*", "modeling/geometry_nodes/input/position.html#bpy-types-geometrynodeinputposition"), - ("bpy.types.geometrynodemeshicosphere*", "modeling/geometry_nodes/mesh_primitives/icosphere.html#bpy-types-geometrynodemeshicosphere"), - ("bpy.types.geometrynodepointsofcurve*", "modeling/geometry_nodes/curve_topology/points_of_curve.html#bpy-types-geometrynodepointsofcurve"), - ("bpy.types.geometrynoderesamplecurve*", "modeling/geometry_nodes/curve/resample_curve.html#bpy-types-geometrynoderesamplecurve"), - ("bpy.types.geometrynodesamplenearest*", "modeling/geometry_nodes/geometry/sample_nearest.html#bpy-types-geometrynodesamplenearest"), - ("bpy.types.geometrynodescaleelements*", "modeling/geometry_nodes/mesh/scale_elements.html#bpy-types-geometrynodescaleelements"), - ("bpy.types.geometrynodesubdividemesh*", "modeling/geometry_nodes/mesh/subdivide_mesh.html#bpy-types-geometrynodesubdividemesh"), - ("bpy.types.geometrynodeuvpackislands*", "modeling/geometry_nodes/uv/pack_uv_islands.html#bpy-types-geometrynodeuvpackislands"), + ("bpy.types.functionnodereplacestring*", "modeling/geometry_nodes/utilities/text/replace_string.html#bpy-types-functionnodereplacestring"), + ("bpy.types.functionnodeseparatecolor*", "modeling/geometry_nodes/utilities/color/separate_color.html#bpy-types-functionnodeseparatecolor"), + ("bpy.types.functionnodevaluetostring*", "modeling/geometry_nodes/utilities/text/value_to_string.html#bpy-types-functionnodevaluetostring"), + ("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/operations/curve_to_points.html#bpy-types-geometrynodecurvetopoints"), + ("bpy.types.geometrynodeedgesofcorner*", "modeling/geometry_nodes/mesh/topology/edges_of_corner.html#bpy-types-geometrynodeedgesofcorner"), + ("bpy.types.geometrynodeedgesofvertex*", "modeling/geometry_nodes/mesh/topology/edges_of_vertex.html#bpy-types-geometrynodeedgesofvertex"), + ("bpy.types.geometrynodefieldondomain*", "modeling/geometry_nodes/utilities/field/evaluate_on_domain.html#bpy-types-geometrynodefieldondomain"), + ("bpy.types.geometrynodeinputmaterial*", "modeling/geometry_nodes/input/constant/material.html#bpy-types-geometrynodeinputmaterial"), + ("bpy.types.geometrynodeinputposition*", "modeling/geometry_nodes/geometry/read/position.html#bpy-types-geometrynodeinputposition"), + ("bpy.types.geometrynodemeshicosphere*", "modeling/geometry_nodes/mesh/primitives/icosphere.html#bpy-types-geometrynodemeshicosphere"), + ("bpy.types.geometrynodepointsofcurve*", "modeling/geometry_nodes/curve/topology/points_of_curve.html#bpy-types-geometrynodepointsofcurve"), + ("bpy.types.geometrynoderesamplecurve*", "modeling/geometry_nodes/curve/operations/resample_curve.html#bpy-types-geometrynoderesamplecurve"), + ("bpy.types.geometrynodesamplenearest*", "modeling/geometry_nodes/geometry/sample/sample_nearest.html#bpy-types-geometrynodesamplenearest"), + ("bpy.types.geometrynodescaleelements*", "modeling/geometry_nodes/mesh/operations/scale_elements.html#bpy-types-geometrynodescaleelements"), + ("bpy.types.geometrynodesubdividemesh*", "modeling/geometry_nodes/mesh/operations/subdivide_mesh.html#bpy-types-geometrynodesubdividemesh"), + ("bpy.types.geometrynodeuvpackislands*", "modeling/geometry_nodes/mesh/uv/pack_uv_islands.html#bpy-types-geometrynodeuvpackislands"), ("bpy.types.greasepencil.before_color*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-before-color"), ("bpy.types.greasepencil.onion_factor*", "grease_pencil/properties/onion_skinning.html#bpy-types-greasepencil-onion-factor"), ("bpy.types.greasepencil.pixel_factor*", "grease_pencil/properties/strokes.html#bpy-types-greasepencil-pixel-factor"), @@ -1421,6 +1460,12 @@ url_manual_mapping = ( ("bpy.types.shadernodetexpointdensity*", "render/shader_nodes/textures/point_density.html#bpy-types-shadernodetexpointdensity"), ("bpy.types.shadernodevectortransform*", "render/shader_nodes/vector/transform.html#bpy-types-shadernodevectortransform"), ("bpy.types.shrinkwrapgpencilmodifier*", "grease_pencil/modifiers/deform/shrinkwrap.html#bpy-types-shrinkwrapgpencilmodifier"), + ("bpy.types.softbodysettings.friction*", "physics/soft_body/settings/object.html#bpy-types-softbodysettings-friction"), + ("bpy.types.softbodysettings.goal_max*", "physics/soft_body/settings/goal.html#bpy-types-softbodysettings-goal-max"), + ("bpy.types.softbodysettings.goal_min*", "physics/soft_body/settings/goal.html#bpy-types-softbodysettings-goal-min"), + ("bpy.types.softbodysettings.step_max*", "physics/soft_body/settings/solver.html#bpy-types-softbodysettings-step-max"), + ("bpy.types.softbodysettings.step_min*", "physics/soft_body/settings/solver.html#bpy-types-softbodysettings-step-min"), + ("bpy.types.softbodysettings.use_goal*", "physics/soft_body/settings/goal.html#bpy-types-softbodysettings-use-goal"), ("bpy.types.spaceclipeditor.show_grid*", "editors/clip/display/clip_display.html#bpy-types-spaceclipeditor-show-grid"), ("bpy.types.spaceoutliner.filter_text*", "editors/outliner/interface.html#bpy-types-spaceoutliner-filter-text"), ("bpy.types.spacetexteditor.find_text*", "editors/text_editor.html#bpy-types-spacetexteditor-find-text"), @@ -1496,21 +1541,21 @@ url_manual_mapping = ( ("bpy.types.freestylelineset.exclude*", "render/freestyle/view_layer/line_set.html#bpy-types-freestylelineset-exclude"), ("bpy.types.freestylelinestyle.alpha*", "render/freestyle/view_layer/line_style/alpha.html#bpy-types-freestylelinestyle-alpha"), ("bpy.types.freestylelinestyle.color*", "render/freestyle/view_layer/line_style/color.html#bpy-types-freestylelinestyle-color"), - ("bpy.types.functionnodecombinecolor*", "modeling/geometry_nodes/color/combine_color.html#bpy-types-functionnodecombinecolor"), - ("bpy.types.functionnodestringlength*", "modeling/geometry_nodes/text/string_length.html#bpy-types-functionnodestringlength"), - ("bpy.types.geometrynodecurveofpoint*", "modeling/geometry_nodes/curve_topology/curve_of_point.html#bpy-types-geometrynodecurveofpoint"), - ("bpy.types.geometrynodefaceofcorner*", "modeling/geometry_nodes/mesh_topology/face_of_corner.html#bpy-types-geometrynodefaceofcorner"), - ("bpy.types.geometrynodefieldatindex*", "modeling/geometry_nodes/utilities/field_at_index.html#bpy-types-geometrynodefieldatindex"), + ("bpy.types.functionnodecombinecolor*", "modeling/geometry_nodes/utilities/color/combine_color.html#bpy-types-functionnodecombinecolor"), + ("bpy.types.functionnodestringlength*", "modeling/geometry_nodes/utilities/text/string_length.html#bpy-types-functionnodestringlength"), + ("bpy.types.geometrynodecurveofpoint*", "modeling/geometry_nodes/curve/topology/curve_of_point.html#bpy-types-geometrynodecurveofpoint"), + ("bpy.types.geometrynodefaceofcorner*", "modeling/geometry_nodes/mesh/topology/face_of_corner.html#bpy-types-geometrynodefaceofcorner"), + ("bpy.types.geometrynodefieldatindex*", "modeling/geometry_nodes/utilities/field/evaluate_at_index.html#bpy-types-geometrynodefieldatindex"), ("bpy.types.geometrynodeimagetexture*", "modeling/geometry_nodes/texture/image.html#bpy-types-geometrynodeimagetexture"), - ("bpy.types.geometrynodeinputtangent*", "modeling/geometry_nodes/curve/curve_tangent.html#bpy-types-geometrynodeinputtangent"), + ("bpy.types.geometrynodeinputtangent*", "modeling/geometry_nodes/curve/read/curve_tangent.html#bpy-types-geometrynodeinputtangent"), ("bpy.types.geometrynodejoingeometry*", "modeling/geometry_nodes/geometry/join_geometry.html#bpy-types-geometrynodejoingeometry"), - ("bpy.types.geometrynodemeshcylinder*", "modeling/geometry_nodes/mesh_primitives/cylinder.html#bpy-types-geometrynodemeshcylinder"), - ("bpy.types.geometrynodemeshtopoints*", "modeling/geometry_nodes/mesh/mesh_to_points.html#bpy-types-geometrynodemeshtopoints"), - ("bpy.types.geometrynodemeshtovolume*", "modeling/geometry_nodes/mesh/mesh_to_volume.html#bpy-types-geometrynodemeshtovolume"), - ("bpy.types.geometrynodemeshuvsphere*", "modeling/geometry_nodes/mesh_primitives/uv_sphere.html#bpy-types-geometrynodemeshuvsphere"), - ("bpy.types.geometrynodereversecurve*", "modeling/geometry_nodes/curve/reverse_curve.html#bpy-types-geometrynodereversecurve"), - ("bpy.types.geometrynodesetcurvetilt*", "modeling/geometry_nodes/curve/set_curve_tilt.html#bpy-types-geometrynodesetcurvetilt"), - ("bpy.types.geometrynodesplinelength*", "modeling/geometry_nodes/curve/spline_length.html#bpy-types-geometrynodesplinelength"), + ("bpy.types.geometrynodemeshcylinder*", "modeling/geometry_nodes/mesh/primitives/cylinder.html#bpy-types-geometrynodemeshcylinder"), + ("bpy.types.geometrynodemeshtopoints*", "modeling/geometry_nodes/mesh/operations/mesh_to_points.html#bpy-types-geometrynodemeshtopoints"), + ("bpy.types.geometrynodemeshtovolume*", "modeling/geometry_nodes/mesh/operations/mesh_to_volume.html#bpy-types-geometrynodemeshtovolume"), + ("bpy.types.geometrynodemeshuvsphere*", "modeling/geometry_nodes/mesh/primitives/uv_sphere.html#bpy-types-geometrynodemeshuvsphere"), + ("bpy.types.geometrynodereversecurve*", "modeling/geometry_nodes/curve/operations/reverse_curve.html#bpy-types-geometrynodereversecurve"), + ("bpy.types.geometrynodesetcurvetilt*", "modeling/geometry_nodes/curve/write/set_curve_tilt.html#bpy-types-geometrynodesetcurvetilt"), + ("bpy.types.geometrynodesplinelength*", "modeling/geometry_nodes/curve/read/spline_length.html#bpy-types-geometrynodesplinelength"), ("bpy.types.geometrynodevolumetomesh*", "modeling/geometry_nodes/volume/volume_to_mesh.html#bpy-types-geometrynodevolumetomesh"), ("bpy.types.gpencillayer.line_change*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-line-change"), ("bpy.types.gpencillayer.parent_type*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-parent-type"), @@ -1530,6 +1575,7 @@ url_manual_mapping = ( ("bpy.types.particleinstancemodifier*", "modeling/modifiers/physics/particle_instance.html#bpy-types-particleinstancemodifier"), ("bpy.types.rendersettings.hair_type*", "render/eevee/render_settings/hair.html#bpy-types-rendersettings-hair-type"), ("bpy.types.rendersettings.tile_size*", "render/cycles/render_settings/performance.html#bpy-types-rendersettings-tile-size"), + ("bpy.types.rigidbodyobject.friction*", "physics/rigid_body/properties/collisions.html#bpy-types-rigidbodyobject-friction"), ("bpy.types.scenedisplay.viewport_aa*", "render/workbench/sampling.html#bpy-types-scenedisplay-viewport-aa"), ("bpy.types.sequencertimelineoverlay*", "editors/video_sequencer/sequencer/display.html#bpy-types-sequencertimelineoverlay"), ("bpy.types.sequencetransform.filter*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sequencetransform-filter"), @@ -1539,6 +1585,8 @@ url_manual_mapping = ( ("bpy.types.shadernodebsdfrefraction*", "render/shader_nodes/shader/refraction.html#bpy-types-shadernodebsdfrefraction"), ("bpy.types.shadernodeoutputmaterial*", "render/shader_nodes/output/material.html#bpy-types-shadernodeoutputmaterial"), ("bpy.types.shadernodetexenvironment*", "render/shader_nodes/textures/environment.html#bpy-types-shadernodetexenvironment"), + ("bpy.types.softbodysettings.damping*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-damping"), + ("bpy.types.softbodysettings.plastic*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-plastic"), ("bpy.types.spacesequenceeditor.show*", "editors/video_sequencer/preview/header.html#bpy-types-spacesequenceeditor-show"), ("bpy.types.spaceuveditor.show_faces*", "editors/uv/overlays.html#bpy-types-spaceuveditor-show-faces"), ("bpy.types.spaceuveditor.uv_opacity*", "editors/uv/overlays.html#bpy-types-spaceuveditor-uv-opacity"), @@ -1625,26 +1673,26 @@ url_manual_mapping = ( ("bpy.types.freestylelinestyle.caps*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-caps"), ("bpy.types.freestylelinestyle.dash*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-dash"), ("bpy.types.freestylemodulesettings*", "render/freestyle/python.html#bpy-types-freestylemodulesettings"), - ("bpy.types.functionnodebooleanmath*", "modeling/geometry_nodes/utilities/boolean_math.html#bpy-types-functionnodebooleanmath"), - ("bpy.types.functionnodeinputstring*", "modeling/geometry_nodes/input/string.html#bpy-types-functionnodeinputstring"), - ("bpy.types.functionnodeinputvector*", "modeling/geometry_nodes/input/vector.html#bpy-types-functionnodeinputvector"), + ("bpy.types.functionnodebooleanmath*", "modeling/geometry_nodes/utilities/math/boolean_math.html#bpy-types-functionnodebooleanmath"), + ("bpy.types.functionnodeinputstring*", "modeling/geometry_nodes/input/constant/string.html#bpy-types-functionnodeinputstring"), + ("bpy.types.functionnodeinputvector*", "modeling/geometry_nodes/input/constant/vector.html#bpy-types-functionnodeinputvector"), ("bpy.types.functionnoderandomvalue*", "modeling/geometry_nodes/utilities/random_value.html#bpy-types-functionnoderandomvalue"), - ("bpy.types.functionnoderotateeuler*", "modeling/geometry_nodes/utilities/rotate_euler.html#bpy-types-functionnoderotateeuler"), - ("bpy.types.functionnodeslicestring*", "modeling/geometry_nodes/text/slice_string.html#bpy-types-functionnodeslicestring"), - ("bpy.types.geometrynodecurvelength*", "modeling/geometry_nodes/curve/curve_length.html#bpy-types-geometrynodecurvelength"), - ("bpy.types.geometrynodecurvespiral*", "modeling/geometry_nodes/curve_primitives/curve_spiral.html#bpy-types-geometrynodecurvespiral"), - ("bpy.types.geometrynodecurvetomesh*", "modeling/geometry_nodes/curve/curve_to_mesh.html#bpy-types-geometrynodecurvetomesh"), - ("bpy.types.geometrynodeextrudemesh*", "modeling/geometry_nodes/mesh/extrude_mesh.html#bpy-types-geometrynodeextrudemesh"), - ("bpy.types.geometrynodefilletcurve*", "modeling/geometry_nodes/curve/fillet_curve.html#bpy-types-geometrynodefilletcurve"), - ("bpy.types.geometrynodeinputnormal*", "modeling/geometry_nodes/input/normal.html#bpy-types-geometrynodeinputnormal"), - ("bpy.types.geometrynodeinputradius*", "modeling/geometry_nodes/input/radius.html#bpy-types-geometrynodeinputradius"), - ("bpy.types.geometrynodemeshboolean*", "modeling/geometry_nodes/mesh/mesh_boolean.html#bpy-types-geometrynodemeshboolean"), - ("bpy.types.geometrynodemeshtocurve*", "modeling/geometry_nodes/mesh/mesh_to_curve.html#bpy-types-geometrynodemeshtocurve"), - ("bpy.types.geometrynodesamplecurve*", "modeling/geometry_nodes/curve/sample_curve.html#bpy-types-geometrynodesamplecurve"), - ("bpy.types.geometrynodesampleindex*", "modeling/geometry_nodes/geometry/sample_index.html#bpy-types-geometrynodesampleindex"), + ("bpy.types.functionnoderotateeuler*", "modeling/geometry_nodes/utilities/rotation/rotate_euler.html#bpy-types-functionnoderotateeuler"), + ("bpy.types.functionnodeslicestring*", "modeling/geometry_nodes/utilities/text/slice_string.html#bpy-types-functionnodeslicestring"), + ("bpy.types.geometrynodecurvelength*", "modeling/geometry_nodes/curve/read/curve_length.html#bpy-types-geometrynodecurvelength"), + ("bpy.types.geometrynodecurvespiral*", "modeling/geometry_nodes/curve/primitives/curve_spiral.html#bpy-types-geometrynodecurvespiral"), + ("bpy.types.geometrynodecurvetomesh*", "modeling/geometry_nodes/curve/operations/curve_to_mesh.html#bpy-types-geometrynodecurvetomesh"), + ("bpy.types.geometrynodeextrudemesh*", "modeling/geometry_nodes/mesh/operations/extrude_mesh.html#bpy-types-geometrynodeextrudemesh"), + ("bpy.types.geometrynodefilletcurve*", "modeling/geometry_nodes/curve/operations/fillet_curve.html#bpy-types-geometrynodefilletcurve"), + ("bpy.types.geometrynodeinputnormal*", "modeling/geometry_nodes/geometry/read/normal.html#bpy-types-geometrynodeinputnormal"), + ("bpy.types.geometrynodeinputradius*", "modeling/geometry_nodes/geometry/read/radius.html#bpy-types-geometrynodeinputradius"), + ("bpy.types.geometrynodemeshboolean*", "modeling/geometry_nodes/mesh/operations/mesh_boolean.html#bpy-types-geometrynodemeshboolean"), + ("bpy.types.geometrynodemeshtocurve*", "modeling/geometry_nodes/mesh/operations/mesh_to_curve.html#bpy-types-geometrynodemeshtocurve"), + ("bpy.types.geometrynodesamplecurve*", "modeling/geometry_nodes/curve/operations/sample_curve.html#bpy-types-geometrynodesamplecurve"), + ("bpy.types.geometrynodesampleindex*", "modeling/geometry_nodes/geometry/sample/sample_index.html#bpy-types-geometrynodesampleindex"), ("bpy.types.geometrynodesetmaterial*", "modeling/geometry_nodes/material/set_material.html#bpy-types-geometrynodesetmaterial"), - ("bpy.types.geometrynodesetposition*", "modeling/geometry_nodes/geometry/set_position.html#bpy-types-geometrynodesetposition"), - ("bpy.types.geometrynodetriangulate*", "modeling/geometry_nodes/mesh/triangulate.html#bpy-types-geometrynodetriangulate"), + ("bpy.types.geometrynodesetposition*", "modeling/geometry_nodes/geometry/write/set_position.html#bpy-types-geometrynodesetposition"), + ("bpy.types.geometrynodetriangulate*", "modeling/geometry_nodes/mesh/operations/triangulate.html#bpy-types-geometrynodetriangulate"), ("bpy.types.gpencillayer.blend_mode*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-blend-mode"), ("bpy.types.gpencillayer.pass_index*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-pass-index"), ("bpy.types.gpencillayer.tint_color*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-tint-color"), @@ -1724,7 +1772,6 @@ url_manual_mapping = ( ("bpy.ops.rigidbody.mass_calculate*", "scene_layout/object/editing/rigid_body.html#bpy-ops-rigidbody-mass-calculate"), ("bpy.ops.screen.spacedata_cleanup*", "advanced/operators.html#bpy-ops-screen-spacedata-cleanup"), ("bpy.ops.sculpt.detail_flood_fill*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-ops-sculpt-detail-flood-fill"), - ("bpy.ops.sculpt_curves.select_all*", "sculpt_paint/curves_sculpting/introduction.html#bpy-ops-sculpt-curves-select-all"), ("bpy.ops.sculpt_curves.select_end*", "sculpt_paint/curves_sculpting/introduction.html#bpy-ops-sculpt-curves-select-end"), ("bpy.ops.sequencer.duplicate_move*", "video_editing/edit/montage/editing.html#bpy-ops-sequencer-duplicate-move"), ("bpy.ops.sequencer.select_grouped*", "video_editing/edit/montage/selecting.html#bpy-ops-sequencer-select-grouped"), @@ -1779,17 +1826,17 @@ url_manual_mapping = ( ("bpy.types.fieldsettings.strength*", "physics/forces/force_fields/introduction.html#bpy-types-fieldsettings-strength"), ("bpy.types.freestylelinestyle.gap*", "render/freestyle/view_layer/line_style/strokes.html#bpy-types-freestylelinestyle-gap"), ("bpy.types.freestylesettings.mode*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings-mode"), - ("bpy.types.functionnodefloattoint*", "modeling/geometry_nodes/utilities/float_to_integer.html#bpy-types-functionnodefloattoint"), - ("bpy.types.functionnodeinputcolor*", "modeling/geometry_nodes/input/color.html#bpy-types-functionnodeinputcolor"), - ("bpy.types.geometrynodeconvexhull*", "modeling/geometry_nodes/geometry/convex_hull.html#bpy-types-geometrynodeconvexhull"), - ("bpy.types.geometrynodeimageinput*", "modeling/geometry_nodes/input/image_input.html#bpy-types-geometrynodeimageinput"), - ("bpy.types.geometrynodeinputindex*", "modeling/geometry_nodes/input/input_index.html#bpy-types-geometrynodeinputindex"), - ("bpy.types.geometrynodeisviewport*", "modeling/geometry_nodes/input/is_viewport.html#bpy-types-geometrynodeisviewport"), - ("bpy.types.geometrynodemeshcircle*", "modeling/geometry_nodes/mesh_primitives/mesh_circle.html#bpy-types-geometrynodemeshcircle"), - ("bpy.types.geometrynodeobjectinfo*", "modeling/geometry_nodes/input/object_info.html#bpy-types-geometrynodeobjectinfo"), - ("bpy.types.geometrynodeselfobject*", "modeling/geometry_nodes/input/self_object.html#bpy-types-geometrynodeselfobject"), - ("bpy.types.geometrynodesplitedges*", "modeling/geometry_nodes/mesh/split_edges.html#bpy-types-geometrynodesplitedges"), - ("bpy.types.geometrynodestringjoin*", "modeling/geometry_nodes/text/join_strings.html#bpy-types-geometrynodestringjoin"), + ("bpy.types.functionnodefloattoint*", "modeling/geometry_nodes/utilities/math/float_to_integer.html#bpy-types-functionnodefloattoint"), + ("bpy.types.functionnodeinputcolor*", "modeling/geometry_nodes/input/constant/color.html#bpy-types-functionnodeinputcolor"), + ("bpy.types.geometrynodeconvexhull*", "modeling/geometry_nodes/geometry/operations/convex_hull.html#bpy-types-geometrynodeconvexhull"), + ("bpy.types.geometrynodeimageinput*", "modeling/geometry_nodes/input/constant/image.html#bpy-types-geometrynodeimageinput"), + ("bpy.types.geometrynodeinputindex*", "modeling/geometry_nodes/geometry/read/input_index.html#bpy-types-geometrynodeinputindex"), + ("bpy.types.geometrynodeisviewport*", "modeling/geometry_nodes/input/scene/is_viewport.html#bpy-types-geometrynodeisviewport"), + ("bpy.types.geometrynodemeshcircle*", "modeling/geometry_nodes/mesh/primitives/mesh_circle.html#bpy-types-geometrynodemeshcircle"), + ("bpy.types.geometrynodeobjectinfo*", "modeling/geometry_nodes/input/scene/object_info.html#bpy-types-geometrynodeobjectinfo"), + ("bpy.types.geometrynodeselfobject*", "modeling/geometry_nodes/input/scene/self_object.html#bpy-types-geometrynodeselfobject"), + ("bpy.types.geometrynodesplitedges*", "modeling/geometry_nodes/mesh/operations/split_edges.html#bpy-types-geometrynodesplitedges"), + ("bpy.types.geometrynodestringjoin*", "modeling/geometry_nodes/utilities/text/join_strings.html#bpy-types-geometrynodestringjoin"), ("bpy.types.geometrynodevolumecube*", "modeling/geometry_nodes/volume/volume_cube.html#bpy-types-geometrynodevolumecube"), ("bpy.types.greasepencilgrid.color*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid-color"), ("bpy.types.greasepencilgrid.lines*", "grease_pencil/properties/display.html#bpy-types-greasepencilgrid-lines"), @@ -1821,6 +1868,10 @@ url_manual_mapping = ( ("bpy.types.shadernodeparticleinfo*", "render/shader_nodes/input/particle_info.html#bpy-types-shadernodeparticleinfo"), ("bpy.types.shadernodevectorrotate*", "render/shader_nodes/vector/vector_rotate.html#bpy-types-shadernodevectorrotate"), ("bpy.types.shapekey.interpolation*", "animation/shape_keys/shape_keys_panel.html#bpy-types-shapekey-interpolation"), + ("bpy.types.softbodysettings.choke*", "physics/soft_body/settings/solver.html#bpy-types-softbodysettings-choke"), + ("bpy.types.softbodysettings.fuzzy*", "physics/soft_body/settings/solver.html#bpy-types-softbodysettings-fuzzy"), + ("bpy.types.softbodysettings.shear*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-shear"), + ("bpy.types.softbodysettings.speed*", "physics/soft_body/settings/simulation.html#bpy-types-softbodysettings-speed"), ("bpy.types.sound.use_memory_cache*", "editors/video_sequencer/sequencer/sidebar/strip.html#bpy-types-sound-use-memory-cache"), ("bpy.types.spaceview3d.clip_start*", "editors/3dview/sidebar.html#bpy-types-spaceview3d-clip-start"), ("bpy.types.spaceview3d.show_gizmo*", "editors/3dview/display/gizmo.html#bpy-types-spaceview3d-show-gizmo"), @@ -1930,15 +1981,15 @@ url_manual_mapping = ( ("bpy.types.ffmpegsettings.format*", "render/output/properties/output.html#bpy-types-ffmpegsettings-format"), ("bpy.types.fluideffectorsettings*", "physics/fluid/type/effector.html#bpy-types-fluideffectorsettings"), ("bpy.types.followtrackconstraint*", "animation/constraints/motion_tracking/follow_track.html#bpy-types-followtrackconstraint"), - ("bpy.types.functionnodeinputbool*", "modeling/geometry_nodes/input/boolean.html#bpy-types-functionnodeinputbool"), - ("bpy.types.geometrycornersofface*", "modeling/geometry_nodes/mesh_topology/corners_of_face.html#bpy-types-geometrycornersofface"), - ("bpy.types.geometrynodecurvestar*", "modeling/geometry_nodes/curve_primitives/star.html#bpy-types-geometrynodecurvestar"), - ("bpy.types.geometrynodefillcurve*", "modeling/geometry_nodes/curve/fill_curve.html#bpy-types-geometrynodefillcurve"), - ("bpy.types.geometrynodeflipfaces*", "modeling/geometry_nodes/mesh/flip_faces.html#bpy-types-geometrynodeflipfaces"), - ("bpy.types.geometrynodeimageinfo*", "modeling/geometry_nodes/input/image_info.html#bpy-types-geometrynodeimageinfo"), - ("bpy.types.geometrynodeproximity*", "modeling/geometry_nodes/geometry/geometry_proximity.html#bpy-types-geometrynodeproximity"), - ("bpy.types.geometrynodetransform*", "modeling/geometry_nodes/geometry/transform_geometry.html#bpy-types-geometrynodetransform"), - ("bpy.types.geometrynodetrimcurve*", "modeling/geometry_nodes/curve/trim_curve.html#bpy-types-geometrynodetrimcurve"), + ("bpy.types.functionnodeinputbool*", "modeling/geometry_nodes/input/constant/boolean.html#bpy-types-functionnodeinputbool"), + ("bpy.types.geometrycornersofface*", "modeling/geometry_nodes/mesh/topology/corners_of_face.html#bpy-types-geometrycornersofface"), + ("bpy.types.geometrynodecurvestar*", "modeling/geometry_nodes/curve/primitives/star.html#bpy-types-geometrynodecurvestar"), + ("bpy.types.geometrynodefillcurve*", "modeling/geometry_nodes/curve/operations/fill_curve.html#bpy-types-geometrynodefillcurve"), + ("bpy.types.geometrynodeflipfaces*", "modeling/geometry_nodes/mesh/operations/flip_faces.html#bpy-types-geometrynodeflipfaces"), + ("bpy.types.geometrynodeimageinfo*", "modeling/geometry_nodes/input/scene/image_info.html#bpy-types-geometrynodeimageinfo"), + ("bpy.types.geometrynodeproximity*", "modeling/geometry_nodes/geometry/sample/geometry_proximity.html#bpy-types-geometrynodeproximity"), + ("bpy.types.geometrynodetransform*", "modeling/geometry_nodes/geometry/operations/transform_geometry.html#bpy-types-geometrynodetransform"), + ("bpy.types.geometrynodetrimcurve*", "modeling/geometry_nodes/curve/operations/trim_curve.html#bpy-types-geometrynodetrimcurve"), ("bpy.types.gpencillayer.location*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-location"), ("bpy.types.gpencillayer.rotation*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-rotation"), ("bpy.types.gpencilsculptsettings*", "grease_pencil/properties/index.html#bpy-types-gpencilsculptsettings"), @@ -1961,6 +2012,7 @@ url_manual_mapping = ( ("bpy.types.screen.show_statusbar*", "interface/window_system/topbar.html#bpy-types-screen-show-statusbar"), ("bpy.types.sculpt.detail_percent*", "sculpt_paint/sculpting/tool_settings/dyntopo.html#bpy-types-sculpt-detail-percent"), ("bpy.types.sculpt.gravity_object*", "sculpt_paint/sculpting/tool_settings/options.html#bpy-types-sculpt-gravity-object"), + ("bpy.types.sculpt.show_face_sets*", "sculpt_paint/sculpting/editing/face_sets.html#bpy-types-sculpt-show-face-sets"), ("bpy.types.shadernodebsdfdiffuse*", "render/shader_nodes/shader/diffuse.html#bpy-types-shadernodebsdfdiffuse"), ("bpy.types.shadernodelayerweight*", "render/shader_nodes/input/layer_weight.html#bpy-types-shadernodelayerweight"), ("bpy.types.shadernodenewgeometry*", "render/shader_nodes/input/geometry.html#bpy-types-shadernodenewgeometry"), @@ -1974,6 +2026,11 @@ url_manual_mapping = ( ("bpy.types.shapekey.relative_key*", "animation/shape_keys/shape_keys_panel.html#bpy-types-shapekey-relative-key"), ("bpy.types.shapekey.vertex_group*", "animation/shape_keys/shape_keys_panel.html#bpy-types-shapekey-vertex-group"), ("bpy.types.smoothgpencilmodifier*", "grease_pencil/modifiers/deform/smooth.html#bpy-types-smoothgpencilmodifier"), + ("bpy.types.softbodysettings.aero*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-aero"), + ("bpy.types.softbodysettings.bend*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-bend"), + ("bpy.types.softbodysettings.mass*", "physics/soft_body/settings/object.html#bpy-types-softbodysettings-mass"), + ("bpy.types.softbodysettings.pull*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-pull"), + ("bpy.types.softbodysettings.push*", "physics/soft_body/settings/edges.html#bpy-types-softbodysettings-push"), ("bpy.types.spline.use_endpoint_u*", "modeling/curves/properties/active_spline.html#bpy-types-spline-use-endpoint-u"), ("bpy.types.surfacedeformmodifier*", "modeling/modifiers/deform/surface_deform.html#bpy-types-surfacedeformmodifier"), ("bpy.types.texturenodetexvoronoi*", "editors/texture_node/types/textures/voronoi.html#bpy-types-texturenodetexvoronoi"), @@ -2003,6 +2060,7 @@ url_manual_mapping = ( ("bpy.ops.mesh.loop_multi_select*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-multi-select"), ("bpy.ops.mesh.vert_connect_path*", "modeling/meshes/editing/vertex/connect_vertex_path.html#bpy-ops-mesh-vert-connect-path"), ("bpy.ops.nla.action_sync_length*", "editors/nla/editing.html#bpy-ops-nla-action-sync-length"), + ("bpy.ops.node.move_detach_links*", "interface/controls/nodes/editing.html#bpy-ops-node-move-detach-links"), ("bpy.ops.object.make_links_data*", "scene_layout/object/editing/link_transfer/link_data.html#bpy-ops-object-make-links-data"), ("bpy.ops.object.modifier_remove*", "modeling/modifiers/introduction.html#bpy-ops-object-modifier-remove"), ("bpy.ops.object.paths_calculate*", "animation/motion_paths.html#bpy-ops-object-paths-calculate"), @@ -2048,17 +2106,17 @@ url_manual_mapping = ( ("bpy.types.editbone.use_connect*", "animation/armatures/bones/properties/relations.html#bpy-types-editbone-use-connect"), ("bpy.types.ffmpegsettings.codec*", "render/output/properties/output.html#bpy-types-ffmpegsettings-codec"), ("bpy.types.followpathconstraint*", "animation/constraints/relationship/follow_path.html#bpy-types-followpathconstraint"), - ("bpy.types.functionnodeinputint*", "modeling/geometry_nodes/input/integer.html#bpy-types-functionnodeinputint"), + ("bpy.types.functionnodeinputint*", "modeling/geometry_nodes/input/constant/integer.html#bpy-types-functionnodeinputint"), ("bpy.types.gaussianblursequence*", "video_editing/edit/montage/strips/effects/blur.html#bpy-types-gaussianblursequence"), - ("bpy.types.geometrynodeboundbox*", "modeling/geometry_nodes/geometry/bounding_box.html#bpy-types-geometrynodeboundbox"), - ("bpy.types.geometrynodecurvearc*", "modeling/geometry_nodes/curve_primitives/arc.html#bpy-types-geometrynodecurvearc"), - ("bpy.types.geometrynodedualmesh*", "modeling/geometry_nodes/mesh/dual_mesh.html#bpy-types-geometrynodedualmesh"), + ("bpy.types.geometrynodeboundbox*", "modeling/geometry_nodes/geometry/operations/bounding_box.html#bpy-types-geometrynodeboundbox"), + ("bpy.types.geometrynodecurvearc*", "modeling/geometry_nodes/curve/primitives/arc.html#bpy-types-geometrynodecurvearc"), + ("bpy.types.geometrynodedualmesh*", "modeling/geometry_nodes/mesh/operations/dual_mesh.html#bpy-types-geometrynodedualmesh"), ("bpy.types.geometrynodematerial*", "-1"), - ("bpy.types.geometrynodemeshcone*", "modeling/geometry_nodes/mesh_primitives/cone.html#bpy-types-geometrynodemeshcone"), - ("bpy.types.geometrynodemeshcube*", "modeling/geometry_nodes/mesh_primitives/cube.html#bpy-types-geometrynodemeshcube"), - ("bpy.types.geometrynodemeshgrid*", "modeling/geometry_nodes/mesh_primitives/grid.html#bpy-types-geometrynodemeshgrid"), - ("bpy.types.geometrynodemeshline*", "modeling/geometry_nodes/mesh_primitives/mesh_line.html#bpy-types-geometrynodemeshline"), - ("bpy.types.geometrynodeuvunwrap*", "modeling/geometry_nodes/uv/uv_unwrap.html#bpy-types-geometrynodeuvunwrap"), + ("bpy.types.geometrynodemeshcone*", "modeling/geometry_nodes/mesh/primitives/cone.html#bpy-types-geometrynodemeshcone"), + ("bpy.types.geometrynodemeshcube*", "modeling/geometry_nodes/mesh/primitives/cube.html#bpy-types-geometrynodemeshcube"), + ("bpy.types.geometrynodemeshgrid*", "modeling/geometry_nodes/mesh/primitives/grid.html#bpy-types-geometrynodemeshgrid"), + ("bpy.types.geometrynodemeshline*", "modeling/geometry_nodes/mesh/primitives/mesh_line.html#bpy-types-geometrynodemeshline"), + ("bpy.types.geometrynodeuvunwrap*", "modeling/geometry_nodes/mesh/uv/uv_unwrap.html#bpy-types-geometrynodeuvunwrap"), ("bpy.types.gpencillayer.opacity*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-opacity"), ("bpy.types.image.display_aspect*", "editors/image/sidebar.html#bpy-types-image-display-aspect"), ("bpy.types.keyframe.handle_left*", "editors/graph_editor/fcurves/properties.html#bpy-types-keyframe-handle-left"), @@ -2198,9 +2256,9 @@ url_manual_mapping = ( ("bpy.types.fieldsettings.noise*", "physics/forces/force_fields/introduction.html#bpy-types-fieldsettings-noise"), ("bpy.types.fieldsettings.shape*", "physics/forces/force_fields/introduction.html#bpy-types-fieldsettings-shape"), ("bpy.types.fluiddomainsettings*", "physics/fluid/type/domain/index.html#bpy-types-fluiddomainsettings"), - ("bpy.types.functionnodecompare*", "modeling/geometry_nodes/utilities/compare.html#bpy-types-functionnodecompare"), - ("bpy.types.geometrynodeinputid*", "modeling/geometry_nodes/input/id.html#bpy-types-geometrynodeinputid"), - ("bpy.types.geometrynoderaycast*", "modeling/geometry_nodes/geometry/raycast.html#bpy-types-geometrynoderaycast"), + ("bpy.types.functionnodecompare*", "modeling/geometry_nodes/utilities/math/compare.html#bpy-types-functionnodecompare"), + ("bpy.types.geometrynodeinputid*", "modeling/geometry_nodes/geometry/read/id.html#bpy-types-geometrynodeinputid"), + ("bpy.types.geometrynoderaycast*", "modeling/geometry_nodes/geometry/sample/raycast.html#bpy-types-geometrynoderaycast"), ("bpy.types.gpencillayer.parent*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-parent"), ("bpy.types.hookgpencilmodifier*", "grease_pencil/modifiers/deform/hook.html#bpy-types-hookgpencilmodifier"), ("bpy.types.imageformatsettings*", "files/media/image_formats.html#bpy-types-imageformatsettings"), @@ -2372,7 +2430,7 @@ url_manual_mapping = ( ("bpy.types.shadernodeemission*", "render/shader_nodes/shader/emission.html#bpy-types-shadernodeemission"), ("bpy.types.shadernodehairinfo*", "render/shader_nodes/input/hair_info.html#bpy-types-shadernodehairinfo"), ("bpy.types.shadernodemaprange*", "render/shader_nodes/converter/map_range.html#bpy-types-shadernodemaprange"), - ("bpy.types.shadernodergbcurve*", "modeling/geometry_nodes/color/rgb_curves.html#bpy-types-shadernodergbcurve"), + ("bpy.types.shadernodergbcurve*", "modeling/geometry_nodes/utilities/color/rgb_curves.html#bpy-types-shadernodergbcurve"), ("bpy.types.shadernodetexbrick*", "render/shader_nodes/textures/brick.html#bpy-types-shadernodetexbrick"), ("bpy.types.shadernodetexcoord*", "render/shader_nodes/input/texture_coordinate.html#bpy-types-shadernodetexcoord"), ("bpy.types.shadernodeteximage*", "render/shader_nodes/textures/image.html#bpy-types-shadernodeteximage"), @@ -2479,7 +2537,7 @@ url_manual_mapping = ( ("bpy.types.fmodifierenvelope*", "editors/graph_editor/fcurves/modifiers.html#bpy-types-fmodifierenvelope"), ("bpy.types.freestylesettings*", "render/freestyle/view_layer/freestyle.html#bpy-types-freestylesettings"), ("bpy.types.geometrynodegroup*", "modeling/geometry_nodes/group.html#bpy-types-geometrynodegroup"), - ("bpy.types.geometrynodesetid*", "modeling/geometry_nodes/geometry/set_id.html#bpy-types-geometrynodesetid"), + ("bpy.types.geometrynodesetid*", "modeling/geometry_nodes/geometry/write/set_id.html#bpy-types-geometrynodesetid"), ("bpy.types.gpencillayer.hide*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-hide"), ("bpy.types.gpencillayer.lock*", "grease_pencil/properties/layers.html#bpy-types-gpencillayer-lock"), ("bpy.types.imagepaint.dither*", "sculpt_paint/texture_paint/tool_settings/options.html#bpy-types-imagepaint-dither"), @@ -2570,7 +2628,7 @@ url_manual_mapping = ( ("bpy.ops.pose.select_mirror*", "animation/armatures/posing/selecting.html#bpy-ops-pose-select-mirror"), ("bpy.ops.screen.marker_jump*", "animation/markers.html#bpy-ops-screen-marker-jump"), ("bpy.ops.screen.repeat_last*", "interface/undo_redo.html#bpy-ops-screen-repeat-last"), - ("bpy.ops.sculpt.mask_expand*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-mask-expand"), + ("bpy.ops.sculpt.mask_expand*", "sculpt_paint/sculpting/editing/expand.html#bpy-ops-sculpt-mask-expand"), ("bpy.ops.sculpt.mask_filter*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-mask-filter"), ("bpy.ops.transform.tosphere*", "modeling/meshes/editing/mesh/transform/to_sphere.html#bpy-ops-transform-tosphere"), ("bpy.ops.view3d.clip_border*", "editors/3dview/navigate/regions.html#bpy-ops-view3d-clip-border"), @@ -2627,7 +2685,7 @@ url_manual_mapping = ( ("bpy.types.shaderfxcolorize*", "grease_pencil/visual_effects/colorize.html#bpy-types-shaderfxcolorize"), ("bpy.types.shaderfxpixelate*", "grease_pencil/visual_effects/pixelate.html#bpy-types-shaderfxpixelate"), ("bpy.types.shadernodeinvert*", "render/shader_nodes/color/invert.html#bpy-types-shadernodeinvert"), - ("bpy.types.shadernodemixrgb*", "modeling/geometry_nodes/color/mix_rgb.html#bpy-types-shadernodemixrgb"), + ("bpy.types.shadernodemixrgb*", "modeling/geometry_nodes/utilities/color/mix_rgb.html#bpy-types-shadernodemixrgb"), ("bpy.types.shadernodenormal*", "render/shader_nodes/vector/normal.html#bpy-types-shadernodenormal"), ("bpy.types.shadernodescript*", "render/shader_nodes/osl.html#bpy-types-shadernodescript"), ("bpy.types.shadernodetexies*", "render/shader_nodes/textures/ies.html#bpy-types-shadernodetexies"), @@ -2658,6 +2716,7 @@ url_manual_mapping = ( ("bpy.ops.clip.solve_camera*", "movie_clip/tracking/clip/editing/track.html#bpy-ops-clip-solve-camera"), ("bpy.ops.constraint.delete*", "animation/constraints/interface/header.html#bpy-ops-constraint-delete"), ("bpy.ops.curve.smooth_tilt*", "modeling/curves/editing/control_points.html#bpy-ops-curve-smooth-tilt"), + ("bpy.ops.curves.select_all*", "sculpt_paint/curves_sculpting/introduction.html#bpy-ops-curves-select-all"), ("bpy.ops.file.reset_recent*", "editors/file_browser.html#bpy-ops-file-reset-recent"), ("bpy.ops.fluid.bake_guides*", "physics/fluid/type/domain/guides.html#bpy-ops-fluid-bake-guides"), ("bpy.ops.fluid.free_guides*", "physics/fluid/type/domain/guides.html#bpy-ops-fluid-free-guides"), @@ -3053,7 +3112,7 @@ url_manual_mapping = ( ("bpy.ops.render.opengl*", "editors/3dview/viewport_render.html#bpy-ops-render-opengl"), ("bpy.ops.screen.header*", "interface/window_system/regions.html#bpy-ops-screen-header"), ("bpy.ops.script.reload*", "advanced/operators.html#bpy-ops-script-reload"), - ("bpy.ops.sculpt.expand*", "sculpt_paint/sculpting/editing/mask.html#bpy-ops-sculpt-expand"), + ("bpy.ops.sculpt.expand*", "sculpt_paint/sculpting/editing/expand.html#bpy-ops-sculpt-expand"), ("bpy.ops.sculpt_curves*", "sculpt_paint/curves_sculpting/index.html#bpy-ops-sculpt-curves"), ("bpy.ops.ui.eyedropper*", "interface/controls/buttons/eyedropper.html#bpy-ops-ui-eyedropper"), ("bpy.ops.view3d.select*", "editors/3dview/selecting.html#bpy-ops-view3d-select"), From ad146bd17a813fd1c40f83876141571ca221642a Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Mon, 30 Jan 2023 06:45:39 +0100 Subject: [PATCH 1014/1522] Fix T103852: Muting timeline channel does not update image Add RNA update function to invalidate cache for all strips in channel. --- .../blender/makesrna/intern/rna_sequencer.c | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 7dd13324f88..868fc98db40 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -1416,6 +1416,28 @@ static void rna_SequenceTimelineChannel_name_set(PointerRNA *ptr, const char *va sizeof(channel->name)); } +static void rna_SequenceTimelineChannel_mute_update(Main *bmain, + Scene *UNUSED(active_scene), + PointerRNA *ptr) +{ + Scene *scene = (Scene *)ptr->owner_id; + Editing *ed = SEQ_editing_get(scene); + SeqTimelineChannel *channel = (SeqTimelineChannel *)ptr; + + Sequence *channel_owner = rna_SeqTimelineChannel_owner_get(ed, channel); + ListBase *seqbase; + if (channel_owner == NULL) { + seqbase = &ed->seqbase; + } + else { + seqbase = &channel_owner->seqbase; + } + + LISTBASE_FOREACH (Sequence *, seq, seqbase) { + SEQ_relations_invalidate_cache_composite(scene, seq); + } +} + static char *rna_SeqTimelineChannel_path(const PointerRNA *ptr) { Scene *scene = (Scene *)ptr->owner_id; @@ -2165,7 +2187,8 @@ static void rna_def_channel(BlenderRNA *brna) prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_CHANNEL_MUTE); RNA_def_property_ui_text(prop, "Mute channel", ""); - RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_sound_update"); + RNA_def_property_update( + prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTimelineChannel_mute_update"); } static void rna_def_editor(BlenderRNA *brna) From 90e940686692060dfa2de55d1391970c1b99003f Mon Sep 17 00:00:00 2001 From: Richard Antalik Date: Mon, 30 Jan 2023 07:47:29 +0100 Subject: [PATCH 1015/1522] VSE: Add Update scene frame range operator This operator updates scene strip internal length to reflect target scene length. Previously scene strip had to be deleted and added from scratch. Scene strip length in timeline will not be changed. --- .../scripts/startup/bl_ui/space_sequencer.py | 2 + .../editors/space_sequencer/sequencer_edit.c | 48 +++++++++++++++++++ .../space_sequencer/sequencer_intern.h | 1 + .../editors/space_sequencer/sequencer_ops.c | 1 + 4 files changed, 52 insertions(+) diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index c605ed5f835..dfe73356bcd 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -946,6 +946,7 @@ class SEQUENCER_MT_strip(Menu): if strip and strip.type == 'SCENE': layout.operator("sequencer.delete", text="Delete Strip & Data").delete_data = True + layout.operator("sequencer.scene_frame_range_update") if has_sequencer: if strip: @@ -1068,6 +1069,7 @@ class SEQUENCER_MT_context_menu(Menu): strip = context.active_sequence_strip if strip and strip.type == 'SCENE': layout.operator("sequencer.delete", text="Delete Strip & Data").delete_data = True + layout.operator("sequencer.scene_frame_range_update") layout.separator() diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 3865aee8327..ac6fd73e99c 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -3565,3 +3565,51 @@ void SEQUENCER_OT_cursor_set(wmOperatorType *ot) } /** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Update scene strip frame range + * \{ */ + +static int sequencer_scene_frame_range_update_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Editing *ed = SEQ_editing_get(scene); + Sequence *seq = ed->act_seq; + + const int old_start = SEQ_time_left_handle_frame_get(scene, seq); + const int old_end = SEQ_time_right_handle_frame_get(scene, seq); + + Scene *target_scene = seq->scene; + + seq->len = target_scene->r.efra - target_scene->r.sfra + 1; + SEQ_time_left_handle_frame_set(scene, seq, old_start); + SEQ_time_right_handle_frame_set(scene, seq, old_end); + + SEQ_relations_invalidate_cache_raw(scene, seq); + DEG_id_tag_update(&scene->id, ID_RECALC_AUDIO | ID_RECALC_SEQUENCER_STRIPS); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_SEQUENCER, NULL); + return OPERATOR_FINISHED; +} + +static bool sequencer_scene_frame_range_update_poll(bContext *C) +{ + Editing *ed = SEQ_editing_get(CTX_data_scene(C)); + return (ed->act_seq != NULL && (ed->act_seq->type & SEQ_TYPE_SCENE) != 0); +} + +void SEQUENCER_OT_scene_frame_range_update(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Update Scene Frame Range"; + ot->description = "Update frame range of scene strip"; + ot->idname = "SEQUENCER_OT_scene_frame_range_update"; + + /* api callbacks */ + ot->exec = sequencer_scene_frame_range_update_exec; + ot->poll = sequencer_scene_frame_range_update_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + +/** \} */ diff --git a/source/blender/editors/space_sequencer/sequencer_intern.h b/source/blender/editors/space_sequencer/sequencer_intern.h index 644e897f631..c6bc2bf7dec 100644 --- a/source/blender/editors/space_sequencer/sequencer_intern.h +++ b/source/blender/editors/space_sequencer/sequencer_intern.h @@ -216,6 +216,7 @@ void SEQUENCER_OT_strip_transform_fit(struct wmOperatorType *ot); void SEQUENCER_OT_strip_color_tag_set(struct wmOperatorType *ot); void SEQUENCER_OT_cursor_set(struct wmOperatorType *ot); +void SEQUENCER_OT_scene_frame_range_update(struct wmOperatorType *ot); /* sequencer_select.c */ diff --git a/source/blender/editors/space_sequencer/sequencer_ops.c b/source/blender/editors/space_sequencer/sequencer_ops.c index f7a9bcf41e6..e0e2cfa42cc 100644 --- a/source/blender/editors/space_sequencer/sequencer_ops.c +++ b/source/blender/editors/space_sequencer/sequencer_ops.c @@ -66,6 +66,7 @@ void sequencer_operatortypes(void) WM_operatortype_append(SEQUENCER_OT_strip_color_tag_set); WM_operatortype_append(SEQUENCER_OT_cursor_set); + WM_operatortype_append(SEQUENCER_OT_scene_frame_range_update); /* sequencer_select.c */ WM_operatortype_append(SEQUENCER_OT_select_all); From 75c772391d358e8b69caab05aa4d48b39aab9669 Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Mon, 30 Jan 2023 09:31:25 +0100 Subject: [PATCH 1016/1522] I18n: construct report verbosely when moving objects to collection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When moving or linking an object to a collection, the report was not properly translatable. In French for instance, it would give nonsensical half-translated sentences such as " moved vers ", instead of " déplacé vers ". Instead, separate the report into the four possible translations (one or multiple objects, linking or moving). This is very verbose and less legible, but it ensure the sentences can be properly translated, including plurals in languages which use grammatical agreement. In addition, use BKE_collection_ui_name_get() to get the collection name, because the Scene Collection's name is hardcoded, but it can be localized. Reviewed By: mont29 Differential Revision: https://developer.blender.org/D17112 --- source/blender/editors/object/object_edit.c | 34 ++++++++++++++++----- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c index 2939c31bc5c..d1473f8dd7a 100644 --- a/source/blender/editors/object/object_edit.c +++ b/source/blender/editors/object/object_edit.c @@ -1927,7 +1927,7 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) RPT_ERROR, "%s already in %s", single_object->id.name + 2, - collection->id.name + 2); + BKE_collection_ui_name_get(collection)); BLI_freelistN(&objects); return OPERATOR_CANCELLED; } @@ -1944,12 +1944,32 @@ static int move_to_collection_exec(bContext *C, wmOperator *op) } BLI_freelistN(&objects); - BKE_reportf(op->reports, - RPT_INFO, - "%s %s to %s", - (single_object != NULL) ? single_object->id.name + 2 : "Objects", - is_link ? "linked" : "moved", - collection->id.name + 2); + if (is_link) { + if (single_object != NULL) { + BKE_reportf(op->reports, + RPT_INFO, + "%s linked to %s", + single_object->id.name + 2, + BKE_collection_ui_name_get(collection)); + } + else { + BKE_reportf( + op->reports, RPT_INFO, "Objects linked to %s", BKE_collection_ui_name_get(collection)); + } + } + else { + if (single_object != NULL) { + BKE_reportf(op->reports, + RPT_INFO, + "%s moved to %s", + single_object->id.name + 2, + BKE_collection_ui_name_get(collection)); + } + else { + BKE_reportf( + op->reports, RPT_INFO, "Objects moved to %s", BKE_collection_ui_name_get(collection)); + } + } DEG_relations_tag_update(bmain); DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT); From db87e2a638f97fa20e8b9bf054548b263c005c35 Mon Sep 17 00:00:00 2001 From: Damien Picard Date: Mon, 30 Jan 2023 09:32:47 +0100 Subject: [PATCH 1017/1522] I18n: extract and disambiguate a few messages Extract: - EEVEE: Compiling Shaders (the same message exists in EEVEE Next, but it uses string concatenation and I don't know yet how to deal with those--see T92758) Disambiguate: - Pan (audio, camera) - Box (TextSequence) - Mix (noun in constraints, GP materials) - Volume (object type, file system) - Floor (math integer part, 3D viewport horizontal plane) - Impossible to disambiguate the constraint name because bConstraintTypeInfo doesn't have a context field. - Show Overlay (in the sequence editor, use the same message as other editors to avoid a confusion with the Frame Overlay feature, also called "Show Overlay") Additionally, fix a few issues reported by Joan Pujolar (@jpujolar) in T101830. Reviewed By: mont29 Differential Revision: https://developer.blender.org/D17114 --- release/scripts/startup/bl_ui/properties_constraint.py | 9 +++++---- release/scripts/startup/bl_ui/space_filebrowser.py | 3 +++ release/scripts/startup/bl_ui/space_sequencer.py | 4 ++-- release/scripts/startup/bl_ui/space_view3d.py | 3 ++- source/blender/blentranslation/BLT_translation.h | 2 ++ source/blender/draw/engines/eevee/eevee_engine.c | 4 +++- source/blender/makesrna/intern/rna_material.c | 4 ++++ source/blender/makesrna/intern/rna_modifier.c | 2 +- source/blender/makesrna/intern/rna_nla.c | 4 ++-- source/blender/makesrna/intern/rna_nodetree.c | 2 ++ source/blender/makesrna/intern/rna_sequencer.c | 2 ++ source/blender/makesrna/intern/rna_space.c | 2 +- 12 files changed, 29 insertions(+), 12 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py index 38e5f5719d4..64dc64cd525 100644 --- a/release/scripts/startup/bl_ui/properties_constraint.py +++ b/release/scripts/startup/bl_ui/properties_constraint.py @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0-or-later from bpy.types import Panel +from bpy.app.translations import contexts as i18n_contexts class ObjectConstraintPanel: @@ -397,7 +398,7 @@ class ConstraintButtonsPanel: sub.prop(con, "invert_z", text="Z", toggle=True) row.label(icon='BLANK1') - layout.prop(con, "mix_mode", text="Mix") + layout.prop(con, "mix_mode", text="Mix", text_ctxt=i18n_contexts.constraint) self.space_template(layout, con) @@ -488,7 +489,7 @@ class ConstraintButtonsPanel: self.target_template(layout, con) layout.prop(con, "remove_target_shear") - layout.prop(con, "mix_mode", text="Mix") + layout.prop(con, "mix_mode", text="Mix", text_ctxt=i18n_contexts.constraint) self.space_template(layout, con) @@ -513,7 +514,7 @@ class ConstraintButtonsPanel: subsub.prop(con, "eval_time", text="") row.prop_decorator(con, "eval_time") - layout.prop(con, "mix_mode", text="Mix") + layout.prop(con, "mix_mode", text="Mix", text_ctxt=i18n_contexts.constraint) self.draw_influence(layout, con) @@ -1024,7 +1025,7 @@ class ConstraintButtonsSubPanel: col.prop(con, "to_min_z" + ext, text="Min") col.prop(con, "to_max_z" + ext, text="Max") - layout.prop(con, "mix_mode" + ext, text="Mix") + layout.prop(con, "mix_mode" + ext, text="Mix", text_ctxt=i18n_contexts.constraint) def draw_armature_bones(self, context): layout = self.layout diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index a7e9663d186..85313b14341 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -8,6 +8,8 @@ from bpy_extras import ( asset_utils, ) +from bpy.app.translations import contexts as i18n_contexts + class FILEBROWSER_HT_header(Header): bl_space_type = 'FILE_BROWSER' @@ -229,6 +231,7 @@ class FILEBROWSER_PT_bookmarks_volumes(Panel): bl_region_type = 'TOOLS' bl_category = "Bookmarks" bl_label = "Volumes" + bl_translation_context = i18n_contexts.editor_filebrowser @classmethod def poll(cls, context): diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index dfe73356bcd..8b08ec99d89 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -1579,7 +1579,7 @@ class SEQUENCER_PT_effect_text_style(SequencerButtonsPanel, Panel): subsub.prop(strip, "shadow_color", text="") row.prop_decorator(strip, "shadow_color") - row = layout.row(align=True, heading="Box") + row = layout.row(align=True, heading="Box", heading_ctxt=i18n_contexts.id_sequence) row.use_property_decorate = False sub = row.row(align=True) sub.prop(strip, "use_box", text="") @@ -1996,7 +1996,7 @@ class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel): split = col.split(factor=0.4) split.alignment = 'RIGHT' - split.label(text="Pan") + split.label(text="Pan", heading_ctxt=i18n_contexts.id_sound) split.prop(strip, "pan", text="") split.enabled = pan_enabled diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index cccb5389037..50629e70aae 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -2246,6 +2246,7 @@ class VIEW3D_MT_camera_add(Menu): class VIEW3D_MT_volume_add(Menu): bl_idname = "VIEW3D_MT_volume_add" bl_label = "Volume" + bl_translation_context = i18n_contexts.id_id def draw(self, _context): layout = self.layout @@ -6293,7 +6294,7 @@ class VIEW3D_PT_overlay_guides(Panel): (view.region_3d.is_orthographic_side_view and not view.region_3d.is_perspective) ) row_el.active = grid_active - row.prop(overlay, "show_floor", text="Floor") + row.prop(overlay, "show_floor", text="Floor", text_ctxt=i18n_contexts.editor_view3d) if overlay.show_floor or overlay.show_ortho_grid: sub = col.row(align=True) diff --git a/source/blender/blentranslation/BLT_translation.h b/source/blender/blentranslation/BLT_translation.h index a4554c4e0bd..b85169fb03c 100644 --- a/source/blender/blentranslation/BLT_translation.h +++ b/source/blender/blentranslation/BLT_translation.h @@ -124,6 +124,7 @@ const char *BLT_translate_do_new_dataname(const char *msgctxt, const char *msgid /* Editors-types contexts. */ #define BLT_I18NCONTEXT_EDITOR_VIEW3D "View3D" +#define BLT_I18NCONTEXT_EDITOR_FILEBROWSER "File browser" /* Helper for bpy.app.i18n object... */ typedef struct { @@ -188,6 +189,7 @@ typedef struct { BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_WORKSPACE, "id_workspace"), \ BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_ID_WINDOWMANAGER, "id_windowmanager"), \ BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_EDITOR_VIEW3D, "editor_view3d"), \ + BLT_I18NCONTEXTS_ITEM(BLT_I18NCONTEXT_EDITOR_FILEBROWSER, "editor_filebrowser"), \ { \ NULL, NULL, NULL \ } \ diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 0bdee957af2..9f70a2dd72b 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -11,6 +11,8 @@ #include "BLI_rand.h" +#include "BLT_translation.h" + #include "BKE_object.h" #include "DEG_depsgraph_query.h" @@ -174,7 +176,7 @@ static void eevee_cache_finish(void *vedata) } if (g_data->queued_shaders_count > 0) { - SNPRINTF(ved->info, "Compiling Shaders (%d remaining)", g_data->queued_shaders_count); + SNPRINTF(ved->info, TIP_("Compiling Shaders (%d remaining)"), g_data->queued_shaders_count); } } diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 7874f06da47..d1b601e6f96 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -13,6 +13,8 @@ #include "BLI_math.h" +#include "BLT_translation.h" + #include "BKE_customdata.h" #include "RNA_define.h" @@ -530,6 +532,7 @@ static void rna_def_material_greasepencil(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "mix_factor"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Mix", "Mix Factor"); + RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_GPENCIL); RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); /* Stroke Mix factor */ @@ -537,6 +540,7 @@ static void rna_def_material_greasepencil(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "mix_stroke_factor"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Mix", "Mix Stroke Factor"); + RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_GPENCIL); RNA_def_property_update(prop, NC_GPENCIL | ND_SHADING, "rna_MaterialGpencil_update"); /* Texture angle */ diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 0639ad29db4..aa7b1ae01dc 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -6826,7 +6826,7 @@ static void rna_def_modifier_normaledit(BlenderRNA *brna) prop = RNA_def_property(srna, "mix_factor", PROP_FLOAT, PROP_FACTOR); RNA_def_property_range(prop, 0.0, 1.0); RNA_def_property_ui_text( - prop, "Mix Factor", "How much of generated normals to mix with exiting ones"); + prop, "Mix Factor", "How much of generated normals to mix with existing ones"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "mix_limit", PROP_FLOAT, PROP_ANGLE); diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 3d8b5159323..b53b055cda8 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -954,7 +954,7 @@ static void rna_api_nlatrack_strips(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_property_srna(cprop, "NlaStrips"); srna = RNA_def_struct(brna, "NlaStrips", NULL); RNA_def_struct_sdna(srna, "NlaTrack"); - RNA_def_struct_ui_text(srna, "Nla Strips", "Collection of Nla Strips"); + RNA_def_struct_ui_text(srna, "NLA Strips", "Collection of NLA Strips"); func = RNA_def_function(srna, "new", "rna_NlaStrip_new"); RNA_def_function_flag(func, @@ -994,7 +994,7 @@ static void rna_def_nlatrack(BlenderRNA *brna) srna = RNA_def_struct(brna, "NlaTrack", NULL); RNA_def_struct_ui_text( - srna, "NLA Track", "A animation layer containing Actions referenced as NLA strips"); + srna, "NLA Track", "An animation layer containing Actions referenced as NLA strips"); RNA_def_struct_ui_icon(srna, ICON_NLA); /* strips collection */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index e007457297e..7ba3971b4ea 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -4968,6 +4968,7 @@ static void def_float_to_int(StructRNA *srna) RNA_def_property_enum_items(prop, rna_enum_node_float_to_int_items); RNA_def_property_ui_text( prop, "Rounding Mode", "Method used to convert the float to an integer"); + RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_NODETREE); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } @@ -4979,6 +4980,7 @@ static void def_vector_math(StructRNA *srna) RNA_def_property_enum_sdna(prop, NULL, "custom1"); RNA_def_property_enum_items(prop, rna_enum_node_vec_math_items); RNA_def_property_ui_text(prop, "Operation", ""); + RNA_def_struct_translation_context(srna, BLT_I18NCONTEXT_ID_NODETREE); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNode_socket_update"); } diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 868fc98db40..7149ae7bf64 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -2840,6 +2840,7 @@ static void rna_def_sound(BlenderRNA *brna) RNA_def_property_range(prop, -FLT_MAX, FLT_MAX); RNA_def_property_ui_range(prop, -2, 2, 1, 2); RNA_def_property_ui_text(prop, "Pan", "Playback panning of the sound (only for Mono sources)"); + RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SOUND); RNA_def_property_float_funcs(prop, NULL, NULL, "rna_Sequence_pan_range"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_audio_update"); @@ -3223,6 +3224,7 @@ static void rna_def_text(StructRNA *srna) prop = RNA_def_property(srna, "use_box", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_TEXT_BOX); RNA_def_property_ui_text(prop, "Box", "Display colored box behind text"); + RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_SEQUENCE); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_invalidate_raw_update"); prop = RNA_def_property(srna, "use_bold", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 38625c7416a..7bdbfe75684 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -5934,7 +5934,7 @@ static void rna_def_space_sequencer(BlenderRNA *brna) /* Overlay settings. */ prop = RNA_def_property(srna, "show_overlays", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SHOW_OVERLAY); - RNA_def_property_ui_text(prop, "Show Overlay", ""); + RNA_def_property_ui_text(prop, "Show Overlays", ""); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL); prop = RNA_def_property(srna, "preview_overlay", PROP_POINTER, PROP_NONE); From 3649c05f57936484939f62e935b1057160ce7c21 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 30 Jan 2023 09:40:17 +0100 Subject: [PATCH 1018/1522] Cleanup: Run `make format` on codebase. --- .../keyconfig/keymap_data/blender_default.py | 2 +- tests/python/bl_usd_import_test.py | 25 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index 9f25d421c9d..e1b34e4cc55 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -6281,7 +6281,7 @@ def km_sculpt_expand_modal(_params): ("MOVE_TOGGLE", {"type": 'SPACE', "value": 'ANY', "any": True}, None), *((e, {"type": NUMBERS_1[i], "value": 'PRESS', "any": True}, None) for i, e in enumerate( ("FALLOFF_GEODESICS", "FALLOFF_TOPOLOGY", "FALLOFF_TOPOLOGY_DIAGONALS", "FALLOFF_SPHERICAL"))), - *((e, {"type": "NUMPAD_%i" % (i+1), "value": 'PRESS', "any": True}, None) for i, e in enumerate( + *((e, {"type": "NUMPAD_%i" % (i + 1), "value": 'PRESS', "any": True}, None) for i, e in enumerate( ("FALLOFF_GEODESICS", "FALLOFF_TOPOLOGY", "FALLOFF_TOPOLOGY_DIAGONALS", "FALLOFF_SPHERICAL"))), ("SNAP_TOGGLE", {"type": 'LEFT_CTRL', "value": 'ANY'}, None), ("SNAP_TOGGLE", {"type": 'RIGHT_CTRL', "value": 'ANY'}, None), diff --git a/tests/python/bl_usd_import_test.py b/tests/python/bl_usd_import_test.py index 8639cbd61a2..70c1ac1c127 100644 --- a/tests/python/bl_usd_import_test.py +++ b/tests/python/bl_usd_import_test.py @@ -111,11 +111,15 @@ class USDImportTest(AbstractUSDTest): self.assertEqual(1, len(objects), f"File {infile} should contain one object, found {len(objects)}") mesh = bpy.data.objects["uvmap_plane"].data - self.assertEqual(len(mesh.uv_layers), 2, f"Object uvmap_plane should have two uv layers, found {len(mesh.uv_layers)}") - + self.assertEqual(len(mesh.uv_layers), 2, + f"Object uvmap_plane should have two uv layers, found {len(mesh.uv_layers)}") + expected_layer_names = {"udim_map", "uvmap"} imported_layer_names = set(mesh.uv_layers.keys()) - self.assertEqual(expected_layer_names, imported_layer_names, f"Expected layer names ({expected_layer_names}) not found on uvmap_plane.") + self.assertEqual( + expected_layer_names, + imported_layer_names, + f"Expected layer names ({expected_layer_names}) not found on uvmap_plane.") def get_coords(data): coords = [x.uv for x in uvmap] @@ -123,13 +127,13 @@ class USDImportTest(AbstractUSDTest): def uv_min_max(data): coords = get_coords(data) - uv_min_x = min([uv[0] for uv in coords]) - uv_max_x = max([uv[0] for uv in coords]) - uv_min_y = min([uv[1] for uv in coords]) - uv_max_y = max([uv[1] for uv in coords]) + uv_min_x = min([uv[0] for uv in coords]) + uv_max_x = max([uv[0] for uv in coords]) + uv_min_y = min([uv[1] for uv in coords]) + uv_max_y = max([uv[1] for uv in coords]) return uv_min_x, uv_max_x, uv_min_y, uv_max_y - ## Quick tests for point range. + # Quick tests for point range. uvmap = mesh.uv_layers["uvmap"].data self.assertEqual(len(uvmap), 128) min_x, max_x, min_y, max_y = uv_min_max(uvmap) @@ -145,12 +149,13 @@ class USDImportTest(AbstractUSDTest): self.assertGreaterEqual(min_y, 0.0) self.assertLessEqual(max_x, 2.0) self.assertLessEqual(max_y, 1.0) - - ## Make sure at least some points are in a udim tile. + + # Make sure at least some points are in a udim tile. coords = get_coords(uvmap) coords = list(filter(lambda x: x[0] > 1.0, coords)) self.assertGreater(len(coords), 16) + def main(): global args import argparse From be8778355a3436b62b4a1568de5e36653f2aae67 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 30 Jan 2023 09:45:42 +0100 Subject: [PATCH 1019/1522] Cleanup: Unused parameters and variables. --- source/blender/editors/mesh/editmesh_utils.c | 1 - source/blender/editors/space_sequencer/sequencer_edit.c | 2 +- source/blender/makesrna/intern/rna_sequencer.c | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index a2343bb297e..cee7f4a2dff 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -455,7 +455,6 @@ UvVertMap *BM_uv_vert_map_create(BMesh *bm, const bool use_select) BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE); - const int totfaces = bm->totface; const int totverts = bm->totvert; int totuv = 0; diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index ac6fd73e99c..be4bbc50aa9 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -3570,7 +3570,7 @@ void SEQUENCER_OT_cursor_set(wmOperatorType *ot) /** \name Update scene strip frame range * \{ */ -static int sequencer_scene_frame_range_update_exec(bContext *C, wmOperator *op) +static int sequencer_scene_frame_range_update_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); Editing *ed = SEQ_editing_get(scene); diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 7149ae7bf64..21843a5c223 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -1416,7 +1416,7 @@ static void rna_SequenceTimelineChannel_name_set(PointerRNA *ptr, const char *va sizeof(channel->name)); } -static void rna_SequenceTimelineChannel_mute_update(Main *bmain, +static void rna_SequenceTimelineChannel_mute_update(Main *UNUSED(bmain), Scene *UNUSED(active_scene), PointerRNA *ptr) { From 2ff08d6d9c352857c2a00ce8876c6275ba3a9d51 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 30 Jan 2023 10:41:42 +0100 Subject: [PATCH 1020/1522] Cleanup: Pass explicit type to `MEM_cnew`. Better avoid fancy implicit typing in this template, and be clear about what type is actually being allocated. --- source/blender/blenkernel/intern/brush.cc | 6 ++++-- source/blender/render/intern/render_result.cc | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/source/blender/blenkernel/intern/brush.cc b/source/blender/blenkernel/intern/brush.cc index 414a316ba7a..015b54f9e75 100644 --- a/source/blender/blenkernel/intern/brush.cc +++ b/source/blender/blenkernel/intern/brush.cc @@ -75,7 +75,8 @@ static void brush_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, cons brush_dst->automasking_cavity_curve = BKE_curvemapping_copy(brush_src->automasking_cavity_curve); if (brush_src->gpencil_settings != nullptr) { - brush_dst->gpencil_settings = MEM_cnew(__func__, *(brush_src->gpencil_settings)); + brush_dst->gpencil_settings = MEM_cnew(__func__, + *(brush_src->gpencil_settings)); brush_dst->gpencil_settings->curve_sensitivity = BKE_curvemapping_copy( brush_src->gpencil_settings->curve_sensitivity); brush_dst->gpencil_settings->curve_strength = BKE_curvemapping_copy( @@ -97,7 +98,8 @@ static void brush_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, cons brush_src->gpencil_settings->curve_rand_value); } if (brush_src->curves_sculpt_settings != nullptr) { - brush_dst->curves_sculpt_settings = MEM_cnew(__func__, *(brush_src->curves_sculpt_settings)); + brush_dst->curves_sculpt_settings = MEM_cnew( + __func__, *(brush_src->curves_sculpt_settings)); } /* enable fake user by default */ diff --git a/source/blender/render/intern/render_result.cc b/source/blender/render/intern/render_result.cc index 62b1ab158b1..7e2f627e5f5 100644 --- a/source/blender/render/intern/render_result.cc +++ b/source/blender/render/intern/render_result.cc @@ -1100,7 +1100,7 @@ RenderView *RE_RenderViewGetByName(RenderResult *rr, const char *viewname) static RenderPass *duplicate_render_pass(RenderPass *rpass) { - RenderPass *new_rpass = MEM_cnew("new render pass", *rpass); + RenderPass *new_rpass = MEM_cnew("new render pass", *rpass); new_rpass->next = new_rpass->prev = nullptr; if (new_rpass->rect != nullptr) { new_rpass->rect = static_cast(MEM_dupallocN(new_rpass->rect)); @@ -1110,7 +1110,7 @@ static RenderPass *duplicate_render_pass(RenderPass *rpass) static RenderLayer *duplicate_render_layer(RenderLayer *rl) { - RenderLayer *new_rl = MEM_cnew("new render layer", *rl); + RenderLayer *new_rl = MEM_cnew("new render layer", *rl); new_rl->next = new_rl->prev = nullptr; new_rl->passes.first = new_rl->passes.last = nullptr; new_rl->exrhandle = nullptr; @@ -1123,7 +1123,7 @@ static RenderLayer *duplicate_render_layer(RenderLayer *rl) static RenderView *duplicate_render_view(RenderView *rview) { - RenderView *new_rview = MEM_cnew("new render view", *rview); + RenderView *new_rview = MEM_cnew("new render view", *rview); if (new_rview->rectf != nullptr) { new_rview->rectf = static_cast(MEM_dupallocN(new_rview->rectf)); } @@ -1138,7 +1138,7 @@ static RenderView *duplicate_render_view(RenderView *rview) RenderResult *RE_DuplicateRenderResult(RenderResult *rr) { - RenderResult *new_rr = MEM_cnew("new duplicated render result", *rr); + RenderResult *new_rr = MEM_cnew("new duplicated render result", *rr); new_rr->next = new_rr->prev = nullptr; new_rr->layers.first = new_rr->layers.last = nullptr; new_rr->views.first = new_rr->views.last = nullptr; From d0f55aa671f7063298d3dc076aab5247aa669144 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 30 Jan 2023 10:53:20 +0100 Subject: [PATCH 1021/1522] Vulkan: Fix GLSL compilation errors. Recent changes in our GLSL libraries didn't compile on Vulkan. This change reverts a compile directive that was removed, but required in order to compile using the Vulkan backend. --- .../blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl index b3712f4077c..80d9f9d93fc 100644 --- a/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl +++ b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl @@ -469,6 +469,7 @@ mat4x4 invert(mat4x4 mat, out bool r_success) return r_success ? inverse(mat) : mat4x4(0.0); } +# ifdef GPU_METAL vec2 normalize(vec2 a) { return a * inversesqrt(length_squared(a)); @@ -481,6 +482,7 @@ vec4 normalize(vec4 a) { return a * inversesqrt(length_squared(a)); } +# endif mat2x2 normalize(mat2x2 mat) { From 57552f52b2987adfd1525c3e4109565e3641ef5d Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Mon, 30 Jan 2023 11:00:26 +0100 Subject: [PATCH 1022/1522] Metal: Realtime compositor enablement with addition of GPU Compute. This patch adds support for compilation and execution of GLSL compute shaders. This, along with a few systematic changes and fixes, enable realtime compositor functionality with the Metal backend on macOS. A number of GLSL source modifications have been made to add the required level of type explicitness, allowing all compilations to succeed. GLSL Compute shader compilation follows a similar path to Vertex/Fragment translation, with added support for shader atomics, shared memory blocks and barriers. Texture flags have also been updated to ensure correct read/write specification for textures used within the compositor pipeline. GPU command submission changes have also been made in the high level path, when Metal is used, to address command buffer time-outs caused by certain expensive compute shaders. Authored by Apple: Michael Parkin-White Ref T96261 Ref T99210 Reviewed By: fclem Maniphest Tasks: T99210, T96261 Differential Revision: https://developer.blender.org/D16990 --- .../intern/shader_operation.cc | 19 +- .../shaders/compositor_blur.glsl | 2 +- .../compositor_blur_variable_size.glsl | 4 +- .../shaders/compositor_directional_blur.glsl | 2 +- .../shaders/compositor_edge_filter.glsl | 4 +- .../shaders/compositor_filter.glsl | 2 +- .../compositor_glare_ghost_accumulate.glsl | 2 +- .../shaders/compositor_glare_ghost_base.glsl | 2 +- .../shaders/compositor_glare_highlights.glsl | 4 +- .../shaders/compositor_glare_mix.glsl | 2 +- .../compositor_glare_streaks_filter.glsl | 4 +- ...itor_morphological_distance_threshold.glsl | 3 +- .../compositor_parallel_reduction.glsl | 2 +- .../shaders/compositor_realize_on_domain.glsl | 4 +- .../compositor_screen_lens_distortion.glsl | 8 +- ...mpositor_symmetric_blur_variable_size.glsl | 8 +- .../infos/compositor_edge_filter_info.hh | 2 +- .../shaders/infos/compositor_filter_info.hh | 2 +- .../engines/compositor/compositor_engine.cc | 31 +- .../eevee_next/eevee_depth_of_field.cc | 2 +- .../engines/eevee_next/eevee_shader_shared.hh | 4 +- .../eevee_depth_of_field_accumulator_lib.glsl | 21 + .../eevee_depth_of_field_downsample_comp.glsl | 2 +- .../eevee_depth_of_field_filter_comp.glsl | 10 +- .../eevee_depth_of_field_reduce_comp.glsl | 2 +- .../eevee_depth_of_field_stabilize_comp.glsl | 25 +- .../eevee_film_cryptomatte_post_comp.glsl | 2 +- .../infos/eevee_depth_of_field_info.hh | 2 +- source/blender/draw/intern/draw_curves.cc | 2 +- source/blender/draw/intern/draw_hair.cc | 2 +- .../gpu/intern/gpu_shader_create_info.cc | 2 +- source/blender/gpu/intern/gpu_viewport.c | 12 +- source/blender/gpu/metal/mtl_backend.hh | 5 +- source/blender/gpu/metal/mtl_backend.mm | 20 +- source/blender/gpu/metal/mtl_capabilities.hh | 10 +- .../blender/gpu/metal/mtl_command_buffer.mm | 167 ++++- source/blender/gpu/metal/mtl_context.hh | 137 +++- source/blender/gpu/metal/mtl_context.mm | 392 +++++++++- source/blender/gpu/metal/mtl_shader.hh | 44 +- source/blender/gpu/metal/mtl_shader.mm | 234 +++++- .../blender/gpu/metal/mtl_shader_generator.hh | 66 +- .../blender/gpu/metal/mtl_shader_generator.mm | 703 +++++++++++++++--- .../blender/gpu/metal/mtl_shader_interface.hh | 21 +- .../blender/gpu/metal/mtl_shader_interface.mm | 32 +- source/blender/gpu/metal/mtl_state.mm | 8 - source/blender/gpu/metal/mtl_texture.mm | 77 +- .../gpu/shaders/metal/mtl_shader_common.msl | 3 + .../gpu/shaders/metal/mtl_shader_defines.msl | 113 +++ .../composite/nodes/node_composite_filter.cc | 2 +- 49 files changed, 1926 insertions(+), 303 deletions(-) diff --git a/source/blender/compositor/realtime_compositor/intern/shader_operation.cc b/source/blender/compositor/realtime_compositor/intern/shader_operation.cc index 88efdae1872..4ac997db42b 100644 --- a/source/blender/compositor/realtime_compositor/intern/shader_operation.cc +++ b/source/blender/compositor/realtime_compositor/intern/shader_operation.cc @@ -10,6 +10,7 @@ #include "DNA_customdata_types.h" +#include "GPU_context.h" #include "GPU_material.h" #include "GPU_shader.h" #include "GPU_texture.h" @@ -329,8 +330,11 @@ void ShaderOperation::generate_code(void *thunk, shader_create_info.compute_source("gpu_shader_compositor_main.glsl"); /* The main function is emitted in the shader before the evaluate function, so the evaluate - * function needs to be forward declared here. */ - shader_create_info.typedef_source_generated += "void evaluate();\n"; + * function needs to be forward declared here. + * NOTE(Metal): Metal does not require forward declarations. */ + if (GPU_backend_get_type() != GPU_BACKEND_METAL) { + shader_create_info.typedef_source_generated += "void evaluate();\n"; + } operation->generate_code_for_outputs(shader_create_info); @@ -383,10 +387,13 @@ void ShaderOperation::generate_code_for_outputs(ShaderCreateInfo &shader_create_ /* The store functions are used by the node_compositor_store_output_[float|vector|color] * functions but are only defined later as part of the compute source, so they need to be forward - * declared. */ - shader_create_info.typedef_source_generated += store_float_function_header + ";\n"; - shader_create_info.typedef_source_generated += store_vector_function_header + ";\n"; - shader_create_info.typedef_source_generated += store_color_function_header + ";\n"; + * declared. + * NOTE(Metal): Metal does not require forward declarations. */ + if (GPU_backend_get_type() != GPU_BACKEND_METAL) { + shader_create_info.typedef_source_generated += store_float_function_header + ";\n"; + shader_create_info.typedef_source_generated += store_vector_function_header + ";\n"; + shader_create_info.typedef_source_generated += store_color_function_header + ";\n"; + } /* Each of the store functions is essentially a single switch case on the given ID, so start by * opening the function with a curly bracket followed by opening a switch statement in each of diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl index c7ac620f99b..056ef91b08e 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_blur.glsl @@ -35,7 +35,7 @@ vec4 load_weight(ivec2 texel) * the texel into the normalized range [0, 1] needed to sample the weights sampler. Finally, * invert the textures coordinates by subtracting from 1 to maintain the shape of the weights as * mentioned in the function description. */ - return texture(weights_tx, 1.0 - ((texel + vec2(radius + 0.5)) / (radius * 2 + 1))); + return texture(weights_tx, 1.0 - ((vec2(texel) + vec2(radius + 0.5)) / (radius * 2.0 + 1.0))); } void main() diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl index 9383bbf9825..117991141b9 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_blur_variable_size.glsl @@ -17,7 +17,7 @@ vec4 load_weight(ivec2 texel, float radius) /* The center zero texel is always assigned a unit weight regardless of the corresponding weight * in the weights texture. That's to guarantee that at last the center pixel will be accumulated * even if the weights texture is zero at its center. */ - if (texel == ivec2(0)) { + if (texel.x == 0 && texel.y == 0) { return vec4(1.0); } @@ -26,7 +26,7 @@ vec4 load_weight(ivec2 texel, float radius) * the texel into the normalized range [0, 1] needed to sample the weights sampler. Finally, * invert the textures coordinates by subtracting from 1 to maintain the shape of the weights as * mentioned in the function description. */ - return texture(weights_tx, 1.0 - ((texel + vec2(radius + 0.5)) / (radius * 2 + 1))); + return texture(weights_tx, 1.0 - ((vec2(texel) + vec2(radius + 0.5)) / (radius * 2.0 + 1.0))); } void main() diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl index 1805cb5a7f5..75ca7c056a8 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_directional_blur.glsl @@ -12,7 +12,7 @@ void main() * input size, then transform the coordinates for the next iteration. */ vec4 accumulated_color = vec4(0.0); for (int i = 0; i < iterations; i++) { - accumulated_color += texture(input_tx, coordinates / input_size); + accumulated_color += texture(input_tx, coordinates / vec2(input_size)); coordinates = (mat3(inverse_transformation) * vec3(coordinates, 1.0)).xy; } diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl index 67e27c22602..29a46790b2a 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_edge_filter.glsl @@ -12,8 +12,8 @@ void main() for (int j = 0; j < 3; j++) { for (int i = 0; i < 3; i++) { vec3 color = texture_load(input_tx, texel + ivec2(i - 1, j - 1)).rgb; - color_x += color * kernel[j][i]; - color_y += color * kernel[i][j]; + color_x += color * ukernel[j][i]; + color_y += color * ukernel[i][j]; } } diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl index e501c563dda..b09470defda 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_filter.glsl @@ -8,7 +8,7 @@ void main() vec4 color = vec4(0); for (int j = 0; j < 3; j++) { for (int i = 0; i < 3; i++) { - color += texture_load(input_tx, texel + ivec2(i - 1, j - 1)) * kernel[j][i]; + color += texture_load(input_tx, texel + ivec2(i - 1, j - 1)) * ukernel[j][i]; } } diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_accumulate.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_accumulate.glsl index 83598fb8a63..0e6353cc066 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_accumulate.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_accumulate.glsl @@ -7,7 +7,7 @@ void main() /* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size * to get the coordinates into the sampler's expected [0, 1] range. */ - vec2 coordinates = (vec2(texel) + vec2(0.5)) / input_size; + vec2 coordinates = (vec2(texel) + vec2(0.5)) / vec2(input_size); /* We accumulate four variants of the input ghost texture, each is scaled by some amount and * possibly multiplied by some color as a form of color modulation. */ diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_base.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_base.glsl index 177b9a86210..ab53c5753b6 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_base.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_ghost_base.glsl @@ -7,7 +7,7 @@ void main() /* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size * to get the coordinates into the sampler's expected [0, 1] range. */ - vec2 coordinates = (vec2(texel) + vec2(0.5)) / input_size; + vec2 coordinates = (vec2(texel) + vec2(0.5)) / vec2(input_size); /* The small ghost is scaled down with the origin as the center of the image by a factor of 2.13, * while the big ghost is flipped and scaled up with the origin as the center of the image by a diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_highlights.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_highlights.glsl index c08b1ece366..6c1a7c20495 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_highlights.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_highlights.glsl @@ -12,11 +12,11 @@ void main() * the number of input pixels that covers a single output pixel. In case the input and output * have the same size, this will be 0.5, which is the offset required to evaluate the sampler at * the center of the pixel. */ - vec2 offset = (texture_size(input_tx) / imageSize(output_img)) / 2.0; + vec2 offset = vec2(texture_size(input_tx) / imageSize(output_img)) / 2.0; /* Add the aforementioned offset and divide by the output image size to get the coordinates into * the sampler's expected [0, 1] range. */ - vec2 normalized_coordinates = (vec2(texel) + offset) / imageSize(output_img); + vec2 normalized_coordinates = (vec2(texel) + offset) / vec2(imageSize(output_img)); vec4 input_color = texture(input_tx, normalized_coordinates); float luminance = dot(input_color.rgb, luminance_coefficients); diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_mix.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_mix.glsl index ab287be3f0b..598d6047315 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_mix.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_mix.glsl @@ -7,7 +7,7 @@ void main() /* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the input image * size to get the relevant coordinates into the sampler's expected [0, 1] range. Make sure the * input color is not negative to avoid a subtractive effect when mixing the glare. */ - vec2 normalized_coordinates = (vec2(texel) + vec2(0.5)) / texture_size(input_tx); + vec2 normalized_coordinates = (vec2(texel) + vec2(0.5)) / vec2(texture_size(input_tx)); vec4 glare_color = texture(glare_tx, normalized_coordinates); vec4 input_color = max(vec4(0.0), texture_load(input_tx, texel)); diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_streaks_filter.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_streaks_filter.glsl index 7fe7d45e4fd..da4e3a98147 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_glare_streaks_filter.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_glare_streaks_filter.glsl @@ -8,8 +8,8 @@ void main() /* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size * to get the coordinates into the sampler's expected [0, 1] range. Similarly, transform the * vector into the sampler's space by dividing by the input size. */ - vec2 coordinates = (vec2(texel) + vec2(0.5)) / input_size; - vec2 vector = streak_vector / input_size; + vec2 coordinates = (vec2(texel) + vec2(0.5)) / vec2(input_size); + vec2 vector = streak_vector / vec2(input_size); /* Load three equally spaced neighbours to the current pixel in the direction of the streak * vector. */ diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl index e6625e7419f..5612c1f6dc1 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_morphological_distance_threshold.glsl @@ -78,7 +78,8 @@ void main() /* Compute the actual distance from the squared distance and assign it an appropriate sign * depending on whether it lies in a masked region or not. */ - float signed_minimum_distance = sqrt(minimum_squared_distance) * (is_center_masked ? 1.0 : -1.0); + float signed_minimum_distance = sqrt(float(minimum_squared_distance)) * + (is_center_masked ? 1.0 : -1.0); /* Add the erode/dilate distance and divide by the inset amount as described in the discussion, * then clamp to the [0, 1] range. */ diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl index f6f84aa24c1..1e1ad19dce4 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_parallel_reduction.glsl @@ -44,7 +44,7 @@ * for reduction, so we just load the data in a 1D array to simplify reduction. The developer is * expected to define the TYPE macro to be a float or a vec4, depending on the type of data being * reduced. */ -const uint reduction_size = gl_WorkGroupSize.x * gl_WorkGroupSize.y; +#define reduction_size (gl_WorkGroupSize.x * gl_WorkGroupSize.y) shared TYPE reduction_data[reduction_size]; void main() diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl index b8561e5f059..4ae6e2fb700 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_realize_on_domain.glsl @@ -19,11 +19,11 @@ void main() * case the difference in sizes was odd. */ ivec2 domain_size = imageSize(domain_img); ivec2 input_size = texture_size(input_tx); - vec2 offset = floor((domain_size - input_size) / 2.0); + vec2 offset = floor(vec2(domain_size - input_size) / 2.0); /* Subtract the offset and divide by the input image size to get the relevant coordinates into * the sampler's expected [0, 1] range. */ - vec2 normalized_coordinates = (coordinates - offset) / input_size; + vec2 normalized_coordinates = (coordinates - offset) / vec2(input_size); imageStore(domain_img, texel, texture(input_tx, normalized_coordinates)); } diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl index 58c1d97e81d..5a33de03ddc 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_screen_lens_distortion.glsl @@ -22,7 +22,7 @@ vec3 compute_chromatic_distortion_scale(float distance_squared) * coordinates but outputs non-centered image coordinates. */ vec2 compute_distorted_uv(vec2 uv, float uv_scale) { - return (uv * uv_scale + 0.5) * texture_size(input_tx) - 0.5; + return (uv * uv_scale + 0.5) * vec2(texture_size(input_tx)) - 0.5; } /* Compute the number of integration steps that should be used to approximate the distorted pixel @@ -102,7 +102,7 @@ vec3 integrate_distortion(int start, int end, float distance_squared, vec2 uv, i /* Sample the color at the distorted coordinates and accumulate it weighted by the increment * value for both the start and end channels. */ vec2 distorted_uv = compute_distorted_uv(uv, distortion_scale); - vec4 color = texture(input_tx, distorted_uv / texture_size(input_tx)); + vec4 color = texture(input_tx, distorted_uv / vec2(texture_size(input_tx))); accumulated_color[start] += (1.0 - increment) * color[start]; accumulated_color[end] += increment * color[end]; } @@ -115,8 +115,8 @@ void main() /* Compute the UV image coordinates in the range [-1, 1] as well as the squared distance to the * center of the image, which is at (0, 0) in the UV coordinates. */ - vec2 center = texture_size(input_tx) / 2.0; - vec2 uv = scale * (texel + 0.5 - center) / center; + vec2 center = vec2(texture_size(input_tx)) / 2.0; + vec2 uv = scale * (vec2(texel) + vec2(0.5) - center) / center; float distance_squared = dot(uv, uv); /* If any of the color channels will get distorted outside of the screen beyond what is possible, diff --git a/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur_variable_size.glsl b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur_variable_size.glsl index 448f3739873..5e5a4b818e0 100644 --- a/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur_variable_size.glsl +++ b/source/blender/compositor/realtime_compositor/shaders/compositor_symmetric_blur_variable_size.glsl @@ -113,7 +113,7 @@ void main() /* Upper right quadrant. */ float upper_right_size = load_size(texel + ivec2(x, y)); - vec2 upper_right_blur_radius = upper_right_size * weights_size; + vec2 upper_right_blur_radius = upper_right_size * vec2(weights_size); if (x < upper_right_blur_radius.x && y < upper_right_blur_radius.y) { accumulated_color += load_input(texel + ivec2(x, y)) * weight; accumulated_weight += weight; @@ -121,7 +121,7 @@ void main() /* Upper left quadrant. */ float upper_left_size = load_size(texel + ivec2(-x, y)); - vec2 upper_left_blur_radius = upper_left_size * weights_size; + vec2 upper_left_blur_radius = upper_left_size * vec2(weights_size); if (x < upper_left_blur_radius.x && y < upper_left_blur_radius.y) { accumulated_color += load_input(texel + ivec2(-x, y)) * weight; accumulated_weight += weight; @@ -129,7 +129,7 @@ void main() /* Bottom right quadrant. */ float bottom_right_size = load_size(texel + ivec2(x, -y)); - vec2 bottom_right_blur_radius = bottom_right_size * weights_size; + vec2 bottom_right_blur_radius = bottom_right_size * vec2(weights_size); if (x < bottom_right_blur_radius.x && y < bottom_right_blur_radius.y) { accumulated_color += load_input(texel + ivec2(x, -y)) * weight; accumulated_weight += weight; @@ -137,7 +137,7 @@ void main() /* Bottom left quadrant. */ float bottom_left_size = load_size(texel + ivec2(-x, -y)); - vec2 bottom_left_blur_radius = bottom_left_size * weights_size; + vec2 bottom_left_blur_radius = bottom_left_size * vec2(weights_size); if (x < bottom_left_blur_radius.x && y < bottom_left_blur_radius.y) { accumulated_color += load_input(texel + ivec2(-x, -y)) * weight; accumulated_weight += weight; diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh index 916ec62bdba..bf22fc50ece 100644 --- a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_edge_filter_info.hh @@ -4,7 +4,7 @@ GPU_SHADER_CREATE_INFO(compositor_edge_filter) .local_group_size(16, 16) - .push_constant(Type::MAT4, "kernel") + .push_constant(Type::MAT4, "ukernel") .sampler(0, ImageType::FLOAT_2D, "input_tx") .sampler(1, ImageType::FLOAT_2D, "factor_tx") .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") diff --git a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh index 9d565cf4b8a..3b1f2f90a9d 100644 --- a/source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh +++ b/source/blender/compositor/realtime_compositor/shaders/infos/compositor_filter_info.hh @@ -4,7 +4,7 @@ GPU_SHADER_CREATE_INFO(compositor_filter) .local_group_size(16, 16) - .push_constant(Type::MAT4, "kernel") + .push_constant(Type::MAT4, "ukernel") .sampler(0, ImageType::FLOAT_2D, "input_tx") .sampler(1, ImageType::FLOAT_2D, "factor_tx") .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img") diff --git a/source/blender/draw/engines/compositor/compositor_engine.cc b/source/blender/draw/engines/compositor/compositor_engine.cc index 64d483768c2..9fc39cbd077 100644 --- a/source/blender/draw/engines/compositor/compositor_engine.cc +++ b/source/blender/draw/engines/compositor/compositor_engine.cc @@ -27,6 +27,7 @@ #include "COM_evaluator.hh" #include "COM_texture_pool.hh" +#include "GPU_context.h" #include "GPU_texture.h" #include "compositor_engine.h" /* Own include. */ @@ -226,12 +227,36 @@ static void compositor_engine_draw(void *data) COMPOSITOR_Data *compositor_data = static_cast(data); #if defined(__APPLE__) - blender::StringRef("Viewport compositor not supported on MacOS") - .copy(compositor_data->info, GPU_INFO_SIZE); - return; + if (GPU_backend_get_type() == GPU_BACKEND_METAL) { + /* NOTE(Metal): Isolate Compositor compute work in individual command buffer to improve + * workload scheduling. When expensive compositor nodes are in the graph, these can stall out + * the GPU for extended periods of time and suboptimally schedule work for execution. */ + GPU_flush(); + } + else { + /* Realtime Compositor is not supported on macOS with the OpenGL backend. */ + blender::StringRef("Viewport compositor is only supported on MacOS with the Metal Backend.") + .copy(compositor_data->info, GPU_INFO_SIZE); + return; + } #endif + /* Exceute Compositor render commands. */ compositor_data->instance_data->draw(); + +#if defined(__APPLE__) + /* NOTE(Metal): Following previous flush to break commmand stream, with compositor command + * buffers potentially being heavy, we avoid issuing subsequent commands until compositor work + * has completed. If subsequent work is prematurely queued up, the subsequent command buffers + * will be blocked behind compositor work and may trigger a command buffer time-out error. As a + * result, we should wait for compositor work to complete. + * + * This is not an efficient approach for peak performance, but a catch-all to prevent command + * buffer failure, until the offending cases can be resolved. */ + if (GPU_backend_get_type() == GPU_BACKEND_METAL) { + GPU_finish(); + } +#endif } static void compositor_engine_update(void *data) diff --git a/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc b/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc index ec89cdba0b1..c09cf251139 100644 --- a/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc +++ b/source/blender/draw/engines/eevee_next/eevee_depth_of_field.cc @@ -285,7 +285,7 @@ void DepthOfField::stabilize_pass_sync() stabilize_ps_.bind_texture("in_history_tx", &stabilize_input_, with_filter); stabilize_ps_.bind_texture("depth_tx", &render_buffers.depth_tx, no_filter); stabilize_ps_.bind_ubo("dof_buf", data_); - stabilize_ps_.push_constant("use_history", &stabilize_valid_history_, 1); + stabilize_ps_.push_constant("u_use_history", &stabilize_valid_history_, 1); stabilize_ps_.bind_image("out_coc_img", reduced_coc_tx_.mip_view(0)); stabilize_ps_.bind_image("out_color_img", reduced_color_tx_.mip_view(0)); stabilize_ps_.bind_image("out_history_img", &stabilize_output_tx_); diff --git a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh index 9a435366e97..1deb70857cb 100644 --- a/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh +++ b/source/blender/draw/engines/eevee_next/eevee_shader_shared.hh @@ -120,9 +120,9 @@ struct SamplingData { BLI_STATIC_ASSERT_ALIGN(SamplingData, 16) /* Returns total sample count in a web pattern of the given size. */ -static inline int sampling_web_sample_count_get(int web_density, int ring_count) +static inline int sampling_web_sample_count_get(int web_density, int in_ring_count) { - return ((ring_count * ring_count + ring_count) / 2) * web_density + 1; + return ((in_ring_count * in_ring_count + in_ring_count) / 2) * web_density + 1; } /* Returns lowest possible ring count that contains at least sample_count samples. */ diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl index 49a00b60abf..1da741d7609 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_accumulator_lib.glsl @@ -60,6 +60,27 @@ struct DofGatherData { float transparency; float layer_opacity; + +#ifdef GPU_METAL + /* Explicit constructors -- To support GLSL syntax. */ + inline DofGatherData() = default; + inline DofGatherData(vec4 in_color, + float in_weight, + float in_dist, + float in_coc, + float in_coc_sqr, + float in_transparency, + float in_layer_opacity) + : color(in_color), + weight(in_weight), + dist(in_dist), + coc(in_coc), + coc_sqr(in_coc_sqr), + transparency(in_transparency), + layer_opacity(in_layer_opacity) + { + } +#endif }; #define GATHER_DATA_INIT DofGatherData(vec4(0.0), 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_downsample_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_downsample_comp.glsl index 3d45f285da9..5e38d086fa4 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_downsample_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_downsample_comp.glsl @@ -12,7 +12,7 @@ void main() { vec2 halfres_texel_size = 1.0 / vec2(textureSize(color_tx, 0).xy); /* Center uv around the 4 halfres pixels. */ - vec2 quad_center = vec2(gl_GlobalInvocationID * 2 + 1) * halfres_texel_size; + vec2 quad_center = vec2(gl_GlobalInvocationID.xy * 2 + 1) * halfres_texel_size; vec4 colors[4]; vec4 cocs; diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_filter_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_filter_comp.glsl index 49c93ca63cd..836cd8945e6 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_filter_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_filter_comp.glsl @@ -9,13 +9,19 @@ struct FilterSample { vec4 color; float weight; + +#ifdef GPU_METAL + inline FilterSample() = default; + inline FilterSample(vec4 in_color, float in_weight) : color(in_color), weight(in_weight) + { + } +#endif }; /* -------------------------------------------------------------------- */ /** \name Pixel cache. * \{ */ - -const uint cache_size = gl_WorkGroupSize.x + 2; +#define cache_size (gl_WorkGroupSize.x + 2) shared vec4 color_cache[cache_size][cache_size]; shared float weight_cache[cache_size][cache_size]; diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl index 41a6fe466b9..1f7f172080a 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_reduce_comp.glsl @@ -73,7 +73,7 @@ float fast_luma(vec3 color) return (2.0 * color.g) + color.r + color.b; } -const uint cache_size = gl_WorkGroupSize.x; +#define cache_size (gl_WorkGroupSize.x) shared vec4 color_cache[cache_size][cache_size]; shared float coc_cache[cache_size][cache_size]; shared float do_scatter[cache_size][cache_size]; diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_stabilize_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_stabilize_comp.glsl index 46a25b84840..cab587339c9 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_stabilize_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_depth_of_field_stabilize_comp.glsl @@ -22,17 +22,24 @@ struct DofSample { vec4 color; float coc; + +#ifdef GPU_METAL + /* Explicit constructors -- To support GLSL syntax. */ + inline DofSample() = default; + inline DofSample(vec4 in_color, float in_coc) : color(in_color), coc(in_coc) + { + } +#endif }; /* -------------------------------------------------------------------- */ /** \name LDS Cache * \{ */ - -const uint cache_size = gl_WorkGroupSize.x + 2; +#define cache_size (gl_WorkGroupSize.x + 2) shared vec4 color_cache[cache_size][cache_size]; shared float coc_cache[cache_size][cache_size]; /* Need 2 pixel border for depth. */ -const uint cache_depth_size = gl_WorkGroupSize.x + 4; +#define cache_depth_size (gl_WorkGroupSize.x + 4) shared float depth_cache[cache_depth_size][cache_depth_size]; void dof_cache_init() @@ -146,6 +153,14 @@ DofSample dof_spatial_filtering() struct DofNeighborhoodMinMax { DofSample min; DofSample max; + +#ifdef GPU_METAL + /* Explicit constructors -- To support GLSL syntax. */ + inline DofNeighborhoodMinMax() = default; + inline DofNeighborhoodMinMax(DofSample in_min, DofSample in_max) : min(in_min), max(in_max) + { + } +#endif }; /* Return history clipping bounding box in YCoCg color space. */ @@ -216,7 +231,7 @@ vec2 dof_pixel_history_motion_vector(ivec2 texel_sample) DofSample dof_sample_history(vec2 input_texel) { #if 1 /* Bilinar. */ - vec2 uv = vec2(input_texel + 0.5) / textureSize(in_history_tx, 0); + vec2 uv = vec2(input_texel + 0.5) / vec2(textureSize(in_history_tx, 0)); vec4 color = textureLod(in_history_tx, uv, 0.0); #else /* Catmull Rom interpolation. 5 Bilinear Taps. */ @@ -308,7 +323,7 @@ float dof_history_blend_factor( blend = 1.0; } /* Discard history if invalid. */ - if (use_history == false) { + if (u_use_history == false) { blend = 1.0; } return blend; diff --git a/source/blender/draw/engines/eevee_next/shaders/eevee_film_cryptomatte_post_comp.glsl b/source/blender/draw/engines/eevee_next/shaders/eevee_film_cryptomatte_post_comp.glsl index 120edd9c35e..43d6fa1feec 100644 --- a/source/blender/draw/engines/eevee_next/shaders/eevee_film_cryptomatte_post_comp.glsl +++ b/source/blender/draw/engines/eevee_next/shaders/eevee_film_cryptomatte_post_comp.glsl @@ -45,7 +45,7 @@ void cryptomatte_normalize_weight(float total_weight, inout vec2 samples[CRYPTOM } } -void cryptomatte_store_samples(ivec2 texel, int layer, in vec2 samples[CRYPTOMATTE_LEVELS_MAX]) +void cryptomatte_store_samples(ivec2 texel, int layer, vec2 samples[CRYPTOMATTE_LEVELS_MAX]) { int pass_len = divide_ceil(cryptomatte_samples_per_layer, 2); int layer_id = layer * pass_len; diff --git a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_depth_of_field_info.hh b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_depth_of_field_info.hh index b689a7f53a2..5dc0be89185 100644 --- a/source/blender/draw/engines/eevee_next/shaders/infos/eevee_depth_of_field_info.hh +++ b/source/blender/draw/engines/eevee_next/shaders/infos/eevee_depth_of_field_info.hh @@ -38,7 +38,7 @@ GPU_SHADER_CREATE_INFO(eevee_depth_of_field_stabilize) .sampler(2, ImageType::FLOAT_2D, "velocity_tx") .sampler(3, ImageType::FLOAT_2D, "in_history_tx") .sampler(4, ImageType::DEPTH_2D, "depth_tx") - .push_constant(Type::BOOL, "use_history") + .push_constant(Type::BOOL, "u_use_history") .image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_color_img") .image(1, GPU_R16F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_coc_img") .image(2, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "out_history_img") diff --git a/source/blender/draw/intern/draw_curves.cc b/source/blender/draw/intern/draw_curves.cc index 8bb786827f3..1ee489c54c2 100644 --- a/source/blender/draw/intern/draw_curves.cc +++ b/source/blender/draw/intern/draw_curves.cc @@ -490,7 +490,7 @@ void DRW_curves_update() GPUFrameBuffer *temp_fb = nullptr; GPUFrameBuffer *prev_fb = nullptr; if (GPU_type_matches_ex(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_METAL)) { - if (!GPU_compute_shader_support()) { + if (!(GPU_compute_shader_support() && GPU_shader_storage_buffer_objects_support())) { prev_fb = GPU_framebuffer_active_get(); char errorOut[256]; /* if the frame-buffer is invalid we need a dummy frame-buffer to be bound. */ diff --git a/source/blender/draw/intern/draw_hair.cc b/source/blender/draw/intern/draw_hair.cc index a7632abeafc..da04f199157 100644 --- a/source/blender/draw/intern/draw_hair.cc +++ b/source/blender/draw/intern/draw_hair.cc @@ -386,7 +386,7 @@ void DRW_hair_update() GPUFrameBuffer *temp_fb = nullptr; GPUFrameBuffer *prev_fb = nullptr; if (GPU_type_matches_ex(GPU_DEVICE_ANY, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_METAL)) { - if (!GPU_compute_shader_support()) { + if (!(GPU_compute_shader_support() && GPU_shader_storage_buffer_objects_support())) { prev_fb = GPU_framebuffer_active_get(); char errorOut[256]; /* if the frame-buffer is invalid we need a dummy frame-buffer to be bound. */ diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc index 0e3057ee8c1..9a72dd74944 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.cc +++ b/source/blender/gpu/intern/gpu_shader_create_info.cc @@ -400,7 +400,7 @@ void gpu_shader_create_info_init() } /* TEST */ - // gpu_shader_create_info_compile_all(); + gpu_shader_create_info_compile_all(); } void gpu_shader_create_info_exit() diff --git a/source/blender/gpu/intern/gpu_viewport.c b/source/blender/gpu/intern/gpu_viewport.c index 89d9a2d0c22..c5202e597a7 100644 --- a/source/blender/gpu/intern/gpu_viewport.c +++ b/source/blender/gpu/intern/gpu_viewport.c @@ -124,8 +124,10 @@ static void gpu_viewport_textures_create(GPUViewport *viewport) if (viewport->color_render_tx[0] == NULL) { + /* NOTE: dtxl_color texture requires write support as it may be written to by the realtime + * compositor. */ viewport->color_render_tx[0] = GPU_texture_create_2d_ex( - "dtxl_color", UNPACK2(size), 1, GPU_RGBA16F, usage, NULL); + "dtxl_color", UNPACK2(size), 1, GPU_RGBA16F, usage | GPU_TEXTURE_USAGE_SHADER_WRITE, NULL); viewport->color_overlay_tx[0] = GPU_texture_create_2d_ex( "dtxl_color_overlay", UNPACK2(size), 1, GPU_SRGB8_A8, usage, NULL); @@ -136,8 +138,12 @@ static void gpu_viewport_textures_create(GPUViewport *viewport) } if ((viewport->flag & GPU_VIEWPORT_STEREO) != 0 && viewport->color_render_tx[1] == NULL) { - viewport->color_render_tx[1] = GPU_texture_create_2d_ex( - "dtxl_color_stereo", UNPACK2(size), 1, GPU_RGBA16F, usage, NULL); + viewport->color_render_tx[1] = GPU_texture_create_2d_ex("dtxl_color_stereo", + UNPACK2(size), + 1, + GPU_RGBA16F, + usage | GPU_TEXTURE_USAGE_SHADER_WRITE, + NULL); viewport->color_overlay_tx[1] = GPU_texture_create_2d_ex( "dtxl_color_overlay_stereo", UNPACK2(size), 1, GPU_SRGB8_A8, usage, NULL); diff --git a/source/blender/gpu/metal/mtl_backend.hh b/source/blender/gpu/metal/mtl_backend.hh index f94f1abae6d..b2ba5ce0fbf 100644 --- a/source/blender/gpu/metal/mtl_backend.hh +++ b/source/blender/gpu/metal/mtl_backend.hh @@ -51,10 +51,7 @@ class MTLBackend : public GPUBackend { } void samplers_update() override; - void compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len) override - { - /* Placeholder */ - } + void compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len) override; void compute_dispatch_indirect(StorageBuf *indirect_buf) override { diff --git a/source/blender/gpu/metal/mtl_backend.mm b/source/blender/gpu/metal/mtl_backend.mm index 432db09005e..a195876ab9a 100644 --- a/source/blender/gpu/metal/mtl_backend.mm +++ b/source/blender/gpu/metal/mtl_backend.mm @@ -398,7 +398,7 @@ void MTLBackend::capabilities_init(MTLContext *ctx) MTLBackend::capabilities.supports_family_mac2); /* TODO(Metal): Add support? */ GCaps.shader_draw_parameters_support = false; - GCaps.compute_shader_support = false; /* TODO(Metal): Add compute support. */ + GCaps.compute_shader_support = true; GCaps.geometry_shader_support = false; GCaps.shader_storage_buffer_objects_support = false; /* TODO(Metal): implement Storage Buffer support. */ @@ -442,4 +442,22 @@ void MTLBackend::capabilities_init(MTLContext *ctx) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Compute dispatch. + * \{ */ + +void MTLBackend::compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len) +{ + /* Fetch Context. + * With Metal, workload submission and resource management occurs within the context. + * Call compute dispatch on valid context. */ + MTLContext *ctx = MTLContext::get(); + BLI_assert(ctx != nullptr); + if (ctx) { + ctx->compute_dispatch(groups_x_len, groups_y_len, groups_z_len); + } +} + +/** \} */ + } // blender::gpu diff --git a/source/blender/gpu/metal/mtl_capabilities.hh b/source/blender/gpu/metal/mtl_capabilities.hh index 7e6b12cba43..f236bae4e92 100644 --- a/source/blender/gpu/metal/mtl_capabilities.hh +++ b/source/blender/gpu/metal/mtl_capabilities.hh @@ -16,10 +16,18 @@ namespace gpu { #define MTL_MAX_SAMPLER_SLOTS MTL_MAX_TEXTURE_SLOTS /* Max limit without using bind-less for samplers. */ #define MTL_MAX_DEFAULT_SAMPLERS 16 -#define MTL_MAX_UNIFORM_BUFFER_BINDINGS 31 +/* Total maximum buffers which can be bound to an encoder, for use within a shader. + * MTL_MAX_UNIFORM_BUFFER_BINDINGS + MTL_MAX_STORAGE_BUFFER_BINDINGS must be <= + * than MTL_MAX_BUFFER_BINDINGS. */ +#define MTL_MAX_BUFFER_BINDINGS 31 +#define MTL_MAX_UNIFORM_BUFFER_BINDINGS 16 +#define MTL_MAX_STORAGE_BUFFER_BINDINGS 12 #define MTL_MAX_VERTEX_INPUT_ATTRIBUTES 31 #define MTL_MAX_UNIFORMS_PER_BLOCK 64 +static_assert((MTL_MAX_UNIFORM_BUFFER_BINDINGS + MTL_MAX_STORAGE_BUFFER_BINDINGS) <= + MTL_MAX_BUFFER_BINDINGS); + /* Context-specific limits -- populated in 'MTLBackend::platform_init' */ struct MTLCapabilities { diff --git a/source/blender/gpu/metal/mtl_command_buffer.mm b/source/blender/gpu/metal/mtl_command_buffer.mm index d9dd14392c9..61b8edda93e 100644 --- a/source/blender/gpu/metal/mtl_command_buffer.mm +++ b/source/blender/gpu/metal/mtl_command_buffer.mm @@ -416,6 +416,9 @@ id MTLCommandBufferManager::ensure_begin_compute_encod /* Update command buffer encoder heuristics. */ this->register_encoder_counters(); + + /* Reset RenderPassState to ensure resource bindings are re-applied. */ + compute_state_.reset_state(); } BLI_assert(active_compute_command_encoder_ != nil); return active_compute_command_encoder_; @@ -496,11 +499,21 @@ bool MTLCommandBufferManager::insert_memory_barrier(eGPUBarrier barrier_bits, /* Only supporting Metal on 10.14 onward anyway - Check required for warnings. */ if (@available(macOS 10.14, *)) { + /* Apple Silicon does not support memory barriers for RenderCommandEncoder's. + * We do not currently need these due to implicit API guarantees. + * NOTE(Metal): MTLFence/MTLEvent may be required to synchronize work if + * untracked resources are ever used. */ + if ([context_.device hasUnifiedMemory] && + (active_command_encoder_type_ != MTL_COMPUTE_COMMAND_ENCODER)) { + return false; + } + /* Resolve scope. */ MTLBarrierScope scope = 0; if (barrier_bits & GPU_BARRIER_SHADER_IMAGE_ACCESS || barrier_bits & GPU_BARRIER_TEXTURE_FETCH) { - scope = scope | MTLBarrierScopeTextures | MTLBarrierScopeRenderTargets; + bool is_compute = (active_command_encoder_type_ != MTL_RENDER_COMMAND_ENCODER); + scope |= (is_compute ? 0 : MTLBarrierScopeRenderTargets) | MTLBarrierScopeTextures; } if (barrier_bits & GPU_BARRIER_SHADER_STORAGE || barrier_bits & GPU_BARRIER_VERTEX_ATTRIB_ARRAY || @@ -604,7 +617,7 @@ void MTLRenderPassState::reset_state() (uint)((fb != nullptr) ? fb->get_height() : 0)}; /* Reset cached resource binding state */ - for (int ubo = 0; ubo < MTL_MAX_UNIFORM_BUFFER_BINDINGS; ubo++) { + for (int ubo = 0; ubo < MTL_MAX_BUFFER_BINDINGS; ubo++) { this->cached_vertex_buffer_bindings[ubo].is_bytes = false; this->cached_vertex_buffer_bindings[ubo].metal_buffer = nil; this->cached_vertex_buffer_bindings[ubo].offset = -1; @@ -626,6 +639,26 @@ void MTLRenderPassState::reset_state() } } +void MTLComputeState::reset_state() +{ + /* Reset Cached pipeline state. */ + this->bound_pso = nil; + + /* Reset cached resource binding state */ + for (int ubo = 0; ubo < MTL_MAX_BUFFER_BINDINGS; ubo++) { + this->cached_compute_buffer_bindings[ubo].is_bytes = false; + this->cached_compute_buffer_bindings[ubo].metal_buffer = nil; + this->cached_compute_buffer_bindings[ubo].offset = -1; + } + + /* Reset cached texture and sampler state binding state. */ + for (int tex = 0; tex < MTL_MAX_TEXTURE_SLOTS; tex++) { + this->cached_compute_texture_bindings[tex].metal_texture = nil; + this->cached_compute_sampler_state_bindings[tex].sampler_state = nil; + this->cached_compute_sampler_state_bindings[tex].is_arg_buffer_binding = false; + } +} + /* Bind Texture to current RenderCommandEncoder. */ void MTLRenderPassState::bind_vertex_texture(id tex, uint slot) { @@ -647,6 +680,19 @@ void MTLRenderPassState::bind_fragment_texture(id tex, uint slot) } } +void MTLComputeState::bind_compute_texture(id tex, uint slot) +{ + if (this->cached_compute_texture_bindings[slot].metal_texture != tex) { + id rec = this->cmd.get_active_compute_command_encoder(); + BLI_assert(rec != nil); + [rec setTexture:tex atIndex:slot]; + [rec useResource:tex + usage:MTLResourceUsageRead | MTLResourceUsageWrite | MTLResourceUsageSample]; + + this->cached_compute_texture_bindings[slot].metal_texture = tex; + } +} + void MTLRenderPassState::bind_vertex_sampler(MTLSamplerBinding &sampler_binding, bool use_argument_buffer_for_samplers, uint slot) @@ -726,9 +772,49 @@ void MTLRenderPassState::bind_fragment_sampler(MTLSamplerBinding &sampler_bindin } } +void MTLComputeState::bind_compute_sampler(MTLSamplerBinding &sampler_binding, + bool use_argument_buffer_for_samplers, + uint slot) +{ + /* Range check. */ + const MTLShaderInterface *shader_interface = ctx.pipeline_state.active_shader->get_interface(); + BLI_assert(slot >= 0); + BLI_assert(slot <= shader_interface->get_max_texture_index()); + BLI_assert(slot < MTL_MAX_TEXTURE_SLOTS); + UNUSED_VARS_NDEBUG(shader_interface); + + /* If sampler state has not changed for the given slot, we do not need to fetch. */ + if (this->cached_compute_sampler_state_bindings[slot].sampler_state == nil || + !(this->cached_compute_sampler_state_bindings[slot].binding_state == + sampler_binding.state) || + use_argument_buffer_for_samplers) { + + id sampler_state = (sampler_binding.state == DEFAULT_SAMPLER_STATE) ? + ctx.get_default_sampler_state() : + ctx.get_sampler_from_state(sampler_binding.state); + if (!use_argument_buffer_for_samplers) { + /* Update binding and cached state. */ + id rec = this->cmd.get_active_compute_command_encoder(); + BLI_assert(rec != nil); + [rec setSamplerState:sampler_state atIndex:slot]; + this->cached_compute_sampler_state_bindings[slot].binding_state = sampler_binding.state; + this->cached_compute_sampler_state_bindings[slot].sampler_state = sampler_state; + } + + /* Flag last binding type */ + this->cached_compute_sampler_state_bindings[slot].is_arg_buffer_binding = + use_argument_buffer_for_samplers; + + /* Always assign to argument buffer samplers binding array - Efficiently ensures the value in + * the samplers array is always up to date. */ + ctx.samplers_.mtl_sampler[slot] = sampler_state; + ctx.samplers_.mtl_sampler_flags[slot] = sampler_binding.state; + } +} + void MTLRenderPassState::bind_vertex_buffer(id buffer, uint buffer_offset, uint index) { - BLI_assert(index >= 0); + BLI_assert(index >= 0 && index < MTL_MAX_BUFFER_BINDINGS); BLI_assert(buffer_offset >= 0); BLI_assert(buffer != nil); @@ -757,7 +843,7 @@ void MTLRenderPassState::bind_vertex_buffer(id buffer, uint buffer_of void MTLRenderPassState::bind_fragment_buffer(id buffer, uint buffer_offset, uint index) { - BLI_assert(index >= 0); + BLI_assert(index >= 0 && index < MTL_MAX_BUFFER_BINDINGS); BLI_assert(buffer_offset >= 0); BLI_assert(buffer != nil); @@ -784,10 +870,45 @@ void MTLRenderPassState::bind_fragment_buffer(id buffer, uint buffer_ } } +void MTLComputeState::bind_compute_buffer(id buffer, + uint buffer_offset, + uint index, + bool writeable) +{ + BLI_assert(index >= 0 && index < MTL_MAX_BUFFER_BINDINGS); + BLI_assert(buffer_offset >= 0); + BLI_assert(buffer != nil); + + BufferBindingCached ¤t_comp_ubo_binding = this->cached_compute_buffer_bindings[index]; + if (current_comp_ubo_binding.offset != buffer_offset || + current_comp_ubo_binding.metal_buffer != buffer || current_comp_ubo_binding.is_bytes) { + + id rec = this->cmd.get_active_compute_command_encoder(); + BLI_assert(rec != nil); + + if (current_comp_ubo_binding.metal_buffer == buffer) { + /* If buffer is the same, but offset has changed. */ + [rec setBufferOffset:buffer_offset atIndex:index]; + } + else { + /* Bind Fragment Buffer */ + [rec setBuffer:buffer offset:buffer_offset atIndex:index]; + } + [rec useResource:buffer + usage:((writeable) ? (MTLResourceUsageRead | MTLResourceUsageWrite) : + MTLResourceUsageRead)]; + + /* Update Bind-state cache */ + this->cached_compute_buffer_bindings[index].is_bytes = false; + this->cached_compute_buffer_bindings[index].metal_buffer = buffer; + this->cached_compute_buffer_bindings[index].offset = buffer_offset; + } +} + void MTLRenderPassState::bind_vertex_bytes(void *bytes, uint length, uint index) { /* Bytes always updated as source data may have changed. */ - BLI_assert(index >= 0 && index < MTL_MAX_UNIFORM_BUFFER_BINDINGS); + BLI_assert(index >= 0 && index < MTL_MAX_BUFFER_BINDINGS); BLI_assert(length > 0); BLI_assert(bytes != nullptr); @@ -812,7 +933,7 @@ void MTLRenderPassState::bind_vertex_bytes(void *bytes, uint length, uint index) void MTLRenderPassState::bind_fragment_bytes(void *bytes, uint length, uint index) { /* Bytes always updated as source data may have changed. */ - BLI_assert(index >= 0 && index < MTL_MAX_UNIFORM_BUFFER_BINDINGS); + BLI_assert(index >= 0 && index < MTL_MAX_BUFFER_BINDINGS); BLI_assert(length > 0); BLI_assert(bytes != nullptr); @@ -834,6 +955,40 @@ void MTLRenderPassState::bind_fragment_bytes(void *bytes, uint length, uint inde this->cached_fragment_buffer_bindings[index].offset = -1; } +void MTLComputeState::bind_compute_bytes(void *bytes, uint length, uint index) +{ + /* Bytes always updated as source data may have changed. */ + BLI_assert(index >= 0 && index < MTL_MAX_BUFFER_BINDINGS); + BLI_assert(length > 0); + BLI_assert(bytes != nullptr); + + if (length < MTL_MAX_SET_BYTES_SIZE) { + id rec = this->cmd.get_active_compute_command_encoder(); + [rec setBytes:bytes length:length atIndex:index]; + } + else { + /* We have run over the setBytes limit, bind buffer instead. */ + MTLTemporaryBuffer range = + ctx.get_scratchbuffer_manager().scratch_buffer_allocate_range_aligned(length, 256); + memcpy(range.data, bytes, length); + this->bind_compute_buffer(range.metal_buffer, range.buffer_offset, index); + } + + /* Update Bind-state cache. */ + this->cached_compute_buffer_bindings[index].is_bytes = true; + this->cached_compute_buffer_bindings[index].metal_buffer = nil; + this->cached_compute_buffer_bindings[index].offset = -1; +} + +void MTLComputeState::bind_pso(id pso) +{ + if (this->bound_pso != pso) { + id rec = this->cmd.get_active_compute_command_encoder(); + [rec setComputePipelineState:pso]; + this->bound_pso = pso; + } +} + /** \} */ } // blender::gpu diff --git a/source/blender/gpu/metal/mtl_context.hh b/source/blender/gpu/metal/mtl_context.hh index ce2fd357ca9..5b37fefa2d8 100644 --- a/source/blender/gpu/metal/mtl_context.hh +++ b/source/blender/gpu/metal/mtl_context.hh @@ -66,6 +66,40 @@ struct MTLSamplerBinding { } }; +/* Caching of resource bindings for active MTLRenderCommandEncoder. + * In Metal, resource bindings are local to the MTLCommandEncoder, + * not globally to the whole pipeline/cmd buffer. */ +struct MTLBoundShaderState { + MTLShader *shader_ = nullptr; + uint pso_index_; + void set(MTLShader *shader, uint pso_index) + { + shader_ = shader; + pso_index_ = pso_index; + } +}; + +/* Caching of CommandEncoder Vertex/Fragment buffer bindings. */ +struct BufferBindingCached { + /* Whether the given binding slot uses byte data (Push Constant equivalent) + * or an MTLBuffer. */ + bool is_bytes; + id metal_buffer; + int offset; +}; + +/* Caching of CommandEncoder textures bindings. */ +struct TextureBindingCached { + id metal_texture; +}; + +/* Cached of CommandEncoder sampler states. */ +struct SamplerStateBindingCached { + MTLSamplerState binding_state; + id sampler_state; + bool is_arg_buffer_binding; +}; + /* Metal Context Render Pass State -- Used to track active RenderCommandEncoder state based on * bound MTLFrameBuffer's.Owned by MTLContext. */ class MTLRenderPassState { @@ -80,52 +114,16 @@ class MTLRenderPassState { MTLContext &ctx; MTLCommandBufferManager &cmd; - /* Caching of resource bindings for active MTLRenderCommandEncoder. - * In Metal, resource bindings are local to the MTLCommandEncoder, - * not globally to the whole pipeline/cmd buffer. */ - struct MTLBoundShaderState { - MTLShader *shader_ = nullptr; - uint pso_index_; - void set(MTLShader *shader, uint pso_index) - { - shader_ = shader; - pso_index_ = pso_index; - } - }; - MTLBoundShaderState last_bound_shader_state; id bound_pso = nil; id bound_ds_state = nil; uint last_used_stencil_ref_value = 0; MTLScissorRect last_scissor_rect; - /* Caching of CommandEncoder Vertex/Fragment buffer bindings. */ - struct BufferBindingCached { - /* Whether the given binding slot uses byte data (Push Constant equivalent) - * or an MTLBuffer. */ - bool is_bytes; - id metal_buffer; - int offset; - }; - - BufferBindingCached cached_vertex_buffer_bindings[MTL_MAX_UNIFORM_BUFFER_BINDINGS]; - BufferBindingCached cached_fragment_buffer_bindings[MTL_MAX_UNIFORM_BUFFER_BINDINGS]; - - /* Caching of CommandEncoder textures bindings. */ - struct TextureBindingCached { - id metal_texture; - }; - + BufferBindingCached cached_vertex_buffer_bindings[MTL_MAX_BUFFER_BINDINGS]; + BufferBindingCached cached_fragment_buffer_bindings[MTL_MAX_BUFFER_BINDINGS]; TextureBindingCached cached_vertex_texture_bindings[MTL_MAX_TEXTURE_SLOTS]; TextureBindingCached cached_fragment_texture_bindings[MTL_MAX_TEXTURE_SLOTS]; - - /* Cached of CommandEncoder sampler states. */ - struct SamplerStateBindingCached { - MTLSamplerState binding_state; - id sampler_state; - bool is_arg_buffer_binding; - }; - SamplerStateBindingCached cached_vertex_sampler_state_bindings[MTL_MAX_TEXTURE_SLOTS]; SamplerStateBindingCached cached_fragment_sampler_state_bindings[MTL_MAX_TEXTURE_SLOTS]; @@ -151,6 +149,44 @@ class MTLRenderPassState { void bind_fragment_bytes(void *bytes, uint length, uint index); }; +/* Metal Context Compute Pass State -- Used to track active ComputeCommandEncoder state. */ +class MTLComputeState { + friend class MTLContext; + + public: + MTLComputeState(MTLContext &context, MTLCommandBufferManager &command_buffer_manager) + : ctx(context), cmd(command_buffer_manager){}; + + /* Given a ComputePassState is associated with a live ComputeCommandEncoder, + * this state sits within the MTLCommandBufferManager. */ + MTLContext &ctx; + MTLCommandBufferManager &cmd; + + id bound_pso = nil; + BufferBindingCached cached_compute_buffer_bindings[MTL_MAX_BUFFER_BINDINGS]; + TextureBindingCached cached_compute_texture_bindings[MTL_MAX_TEXTURE_SLOTS]; + SamplerStateBindingCached cached_compute_sampler_state_bindings[MTL_MAX_TEXTURE_SLOTS]; + + /* Reset ComputeCommandEncoder binding state. */ + void reset_state(); + + /* PSO Binding. */ + void bind_pso(id pso); + + /* Texture Binding (ComputeCommandEncoder). */ + void bind_compute_texture(id tex, uint slot); + /* Sampler Binding (ComputeCommandEncoder). */ + void bind_compute_sampler(MTLSamplerBinding &sampler_binding, + bool use_argument_buffer_for_samplers, + uint slot); + /* Buffer binding (ComputeCommandEncoder). */ + void bind_compute_buffer(id buffer, + uint buffer_offset, + uint index, + bool writeable = false); + void bind_compute_bytes(void *bytes, uint length, uint index); +}; + /* Depth Stencil State */ struct MTLContextDepthStencilState { @@ -521,6 +557,9 @@ class MTLCommandBufferManager { MTLFrameBuffer *active_frame_buffer_ = nullptr; MTLRenderPassDescriptor *active_pass_descriptor_ = nullptr; + /* State associated with active ComputeCommandEncoder. */ + MTLComputeState compute_state_; + /* Workload heuristics - We may need to split command buffers to optimize workload and balancing. */ int current_draw_call_count_ = 0; @@ -530,7 +569,7 @@ class MTLCommandBufferManager { public: MTLCommandBufferManager(MTLContext &context) - : context_(context), render_pass_state_(context, *this){}; + : context_(context), render_pass_state_(context, *this), compute_state_(context, *this){}; void prepare(bool supports_render = true); /* If wait is true, CPU will stall until GPU work has completed. */ @@ -553,6 +592,14 @@ class MTLCommandBufferManager { return render_pass_state_; } + /* RenderPassState for RenderCommandEncoder. */ + MTLComputeState &get_compute_state() + { + /* Render pass state should only be valid if we are inside a compute encoder. */ + BLI_assert(this->is_inside_compute()); + return compute_state_; + } + /* Rendering Heuristics. */ void register_draw_counters(int vertex_submission); void reset_counters(); @@ -593,6 +640,7 @@ class MTLCommandBufferManager { class MTLContext : public Context { friend class MTLBackend; friend class MTLRenderPassState; + friend class MTLComputeState; public: /* Swap-chain and latency management. */ @@ -745,9 +793,16 @@ class MTLContext : public Context { id rec, const MTLShaderInterface *shader_interface, const MTLRenderPipelineStateInstance *pipeline_state_instance); + bool ensure_uniform_buffer_bindings( + id rec, + const MTLShaderInterface *shader_interface, + const MTLComputePipelineStateInstance &pipeline_state_instance); void ensure_texture_bindings(id rec, MTLShaderInterface *shader_interface, const MTLRenderPipelineStateInstance *pipeline_state_instance); + void ensure_texture_bindings(id rec, + MTLShaderInterface *shader_interface, + const MTLComputePipelineStateInstance &pipeline_state_instance); void ensure_depth_stencil_state(MTLPrimitiveType prim_type); id get_null_buffer(); @@ -755,6 +810,10 @@ class MTLContext : public Context { gpu::MTLTexture *get_dummy_texture(eGPUTextureType type, eGPUSamplerFormat sampler_format); void free_dummy_resources(); + /* Compute. */ + bool ensure_compute_pipeline_state(); + void compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len); + /* State assignment. */ void set_viewport(int origin_x, int origin_y, int width, int height); void set_scissor(int scissor_x, int scissor_y, int scissor_width, int scissor_height); diff --git a/source/blender/gpu/metal/mtl_context.mm b/source/blender/gpu/metal/mtl_context.mm index 9ccb91f1104..2f0580a5f63 100644 --- a/source/blender/gpu/metal/mtl_context.mm +++ b/source/blender/gpu/metal/mtl_context.mm @@ -1034,6 +1034,7 @@ bool MTLContext::ensure_uniform_buffer_bindings( uint32_t block_size = push_constant_block.size; uint32_t buffer_index = pipeline_state_instance->base_uniform_buffer_index + push_constant_block.buffer_index; + BLI_assert(buffer_index >= 0 && buffer_index < MTL_MAX_BUFFER_BINDINGS); /* Only need to rebind block if push constants have been modified -- or if no data is bound for * the current RenderCommandEncoder. */ @@ -1156,15 +1157,13 @@ bool MTLContext::ensure_uniform_buffer_bindings( /* Bind Vertex UBO. */ if (bool(ubo.stage_mask & ShaderStage::VERTEX)) { - BLI_assert(buffer_bind_index >= 0 && - buffer_bind_index < MTL_MAX_UNIFORM_BUFFER_BINDINGS); + BLI_assert(buffer_bind_index >= 0 && buffer_bind_index < MTL_MAX_BUFFER_BINDINGS); rps.bind_vertex_buffer(ubo_buffer, ubo_offset, buffer_bind_index); } /* Bind Fragment UBOs. */ if (bool(ubo.stage_mask & ShaderStage::FRAGMENT)) { - BLI_assert(buffer_bind_index >= 0 && - buffer_bind_index < MTL_MAX_UNIFORM_BUFFER_BINDINGS); + BLI_assert(buffer_bind_index >= 0 && buffer_bind_index < MTL_MAX_BUFFER_BINDINGS); rps.bind_fragment_buffer(ubo_buffer, ubo_offset, buffer_bind_index); } } @@ -1181,6 +1180,115 @@ bool MTLContext::ensure_uniform_buffer_bindings( return true; } +/* Variant for compute. Bind uniform buffers to an active compute command encoder using the + * rendering state of the current context -> Active shader, Bound UBOs). */ +bool MTLContext::ensure_uniform_buffer_bindings( + id rec, + const MTLShaderInterface *shader_interface, + const MTLComputePipelineStateInstance &pipeline_state_instance) +{ + /* Fetch Compute Pass state. */ + MTLComputeState &cs = this->main_command_buffer.get_compute_state(); + + /* Fetch push constant block and bind. */ + const MTLShaderUniformBlock &push_constant_block = shader_interface->get_push_constant_block(); + if (push_constant_block.size > 0) { + + /* Fetch uniform buffer base binding index from pipeline_state_instance - There buffer index + * will be offset by the number of bound VBOs. */ + uint32_t block_size = push_constant_block.size; + uint32_t buffer_index = pipeline_state_instance.base_uniform_buffer_index + + push_constant_block.buffer_index; + BLI_assert(buffer_index >= 0 && buffer_index < MTL_MAX_BUFFER_BINDINGS); + + /* For compute, we must always re-bind the push constant block as other compute + * operations may have assigned reources over the top, outside of the compiled + * compute shader path. */ + /* Bind push constant data. */ + BLI_assert(this->pipeline_state.active_shader->get_push_constant_data() != nullptr); + cs.bind_compute_bytes( + this->pipeline_state.active_shader->get_push_constant_data(), block_size, buffer_index); + + /* Only need to rebind block if it has been modified. */ + this->pipeline_state.active_shader->push_constant_bindstate_mark_dirty(false); + } + + /* Bind Global GPUUniformBuffers */ + /* Iterate through expected UBOs in the shader interface, and check if the globally bound ones + * match. This is used to support the gpu_uniformbuffer module, where the uniform data is global, + * and not owned by the shader instance. */ + for (const uint ubo_index : IndexRange(shader_interface->get_total_uniform_blocks())) { + const MTLShaderUniformBlock &ubo = shader_interface->get_uniform_block(ubo_index); + + if (ubo.buffer_index >= 0) { + + /* Uniform Buffer index offset by 1 as the first shader buffer binding slot is reserved for + * the uniform PushConstantBlock. */ + const uint32_t buffer_index = ubo.buffer_index + 1; + int ubo_offset = 0; + id ubo_buffer = nil; + int ubo_size = 0; + + bool bind_dummy_buffer = false; + if (this->pipeline_state.ubo_bindings[ubo_index].bound) { + + /* Fetch UBO global-binding properties from slot. */ + ubo_offset = 0; + ubo_buffer = this->pipeline_state.ubo_bindings[ubo_index].ubo->get_metal_buffer( + &ubo_offset); + ubo_size = this->pipeline_state.ubo_bindings[ubo_index].ubo->get_size(); + UNUSED_VARS_NDEBUG(ubo_size); + + /* Use dummy zero buffer if no buffer assigned -- this is an optimization to avoid + * allocating zero buffers. */ + if (ubo_buffer == nil) { + bind_dummy_buffer = true; + } + else { + BLI_assert(ubo_buffer != nil); + BLI_assert(ubo_size > 0); + } + } + else { + MTL_LOG_INFO( + "[Warning][UBO] Shader '%s' expected UBO '%s' to be bound at buffer index: %d -- but " + "nothing was bound -- binding dummy buffer\n", + shader_interface->get_name(), + shader_interface->get_name_at_offset(ubo.name_offset), + buffer_index); + bind_dummy_buffer = true; + } + + if (bind_dummy_buffer) { + /* Perform Dummy binding. */ + ubo_offset = 0; + ubo_buffer = this->get_null_buffer(); + ubo_size = [ubo_buffer length]; + } + + if (ubo_buffer != nil) { + uint32_t buffer_bind_index = pipeline_state_instance.base_uniform_buffer_index + + buffer_index; + + /* Bind Vertex UBO. */ + if (bool(ubo.stage_mask & ShaderStage::COMPUTE)) { + BLI_assert(buffer_bind_index >= 0 && buffer_bind_index < MTL_MAX_BUFFER_BINDINGS); + cs.bind_compute_buffer(ubo_buffer, ubo_offset, buffer_bind_index); + } + } + else { + MTL_LOG_WARNING( + "[UBO] Compute Shader '%s' has UBO '%s' bound at buffer index: %d -- but MTLBuffer " + "is NULL!\n", + shader_interface->get_name(), + shader_interface->get_name_at_offset(ubo.name_offset), + buffer_index); + } + } + } + return true; +} + /* Ensure texture bindings are correct and up to date for current draw call. */ void MTLContext::ensure_texture_bindings( id rec, @@ -1198,8 +1306,11 @@ void MTLContext::ensure_texture_bindings( int fragment_arg_buffer_bind_index = -1; /* Argument buffers are used for samplers, when the limit of 16 is exceeded. */ - bool use_argument_buffer_for_samplers = shader_interface->get_use_argument_buffer_for_samplers( - &vertex_arg_buffer_bind_index, &fragment_arg_buffer_bind_index); + bool use_argument_buffer_for_samplers = shader_interface->uses_argument_buffer_for_samplers(); + vertex_arg_buffer_bind_index = shader_interface->get_argument_buffer_bind_index( + ShaderStage::VERTEX); + fragment_arg_buffer_bind_index = shader_interface->get_argument_buffer_bind_index( + ShaderStage::FRAGMENT); /* Loop through expected textures in shader interface and resolve bindings with currently * bound textures.. */ @@ -1396,6 +1507,200 @@ void MTLContext::ensure_texture_bindings( } } +/* Texture binding variant for compute command encoder. + * Ensure bound texture resources are bound to the active MTLComputeCommandEncoder. */ +void MTLContext::ensure_texture_bindings( + id rec, + MTLShaderInterface *shader_interface, + const MTLComputePipelineStateInstance &pipeline_state_instance) +{ + BLI_assert(shader_interface != nil); + BLI_assert(rec != nil); + + /* Fetch Render Pass state. */ + MTLComputeState &cs = this->main_command_buffer.get_compute_state(); + + @autoreleasepool { + int compute_arg_buffer_bind_index = -1; + int null_index = -1; + + /* Argument buffers are used for samplers, when the limit of 16 is exceeded. + * NOTE: Compute uses vertex argument for arg buffer bind index.*/ + bool use_argument_buffer_for_samplers = shader_interface->uses_argument_buffer_for_samplers(); + compute_arg_buffer_bind_index = shader_interface->get_argument_buffer_bind_index( + ShaderStage::COMPUTE); + + /* Loop through expected textures in shader interface and resolve bindings with currently + * bound textures.. */ + for (const uint t : IndexRange(shader_interface->get_max_texture_index() + 1)) { + /* Ensure the bound texture is compatible with the shader interface. If the + * shader does not expect a texture to be bound for the current slot, we skip + * binding. + * NOTE: Global texture bindings may be left over from prior draw calls. */ + const MTLShaderTexture &shader_texture_info = shader_interface->get_texture(t); + if (!shader_texture_info.used) { + /* Skip unused binding points if explicit indices are specified. */ + continue; + } + + int slot = shader_texture_info.slot_index; + if (slot >= 0 && slot < GPU_max_textures()) { + bool bind_dummy_texture = true; + if (this->pipeline_state.texture_bindings[slot].used) { + gpu::MTLTexture *bound_texture = + this->pipeline_state.texture_bindings[slot].texture_resource; + MTLSamplerBinding &bound_sampler = this->pipeline_state.sampler_bindings[slot]; + BLI_assert(bound_texture); + BLI_assert(bound_sampler.used); + + if (shader_texture_info.type == bound_texture->type_) { + /* Bind texture and sampler if the bound texture matches the type expected by the + * shader. */ + id tex = bound_texture->get_metal_handle(); + + if (bool(shader_texture_info.stage_mask & ShaderStage::COMPUTE)) { + cs.bind_compute_texture(tex, slot); + cs.bind_compute_sampler(bound_sampler, use_argument_buffer_for_samplers, slot); + } + + /* Texture state resolved, no need to bind dummy texture */ + bind_dummy_texture = false; + } + else { + /* Texture type for bound texture (e.g. Texture2DArray) does not match what was + * expected in the shader interface. This is a problem and we will need to bind + * a dummy texture to ensure correct API usage. */ + MTL_LOG_WARNING( + "(Shader '%s') Texture %p bound to slot %d is incompatible -- Wrong " + "texture target type. (Expecting type %d, actual type %d) (binding " + "name:'%s')(texture name:'%s')\n", + shader_interface->get_name(), + bound_texture, + slot, + shader_texture_info.type, + bound_texture->type_, + shader_interface->get_name_at_offset(shader_texture_info.name_offset), + bound_texture->get_name()); + } + } + else { + MTL_LOG_WARNING( + "Shader '%s' expected texture to be bound to slot %d -- No texture was " + "bound. (name:'%s')\n", + shader_interface->get_name(), + slot, + shader_interface->get_name_at_offset(shader_texture_info.name_offset)); + } + + /* Bind Dummy texture -- will temporarily resolve validation issues while incorrect formats + * are provided -- as certain configurations may not need any binding. These issues should + * be fixed in the high-level, if problems crop up. */ + if (bind_dummy_texture) { + if (bool(shader_texture_info.stage_mask & ShaderStage::COMPUTE)) { + cs.bind_compute_texture( + get_dummy_texture(shader_texture_info.type, shader_texture_info.sampler_format) + ->get_metal_handle(), + slot); + + /* Bind default sampler state. */ + MTLSamplerBinding default_binding = {true, DEFAULT_SAMPLER_STATE}; + cs.bind_compute_sampler(default_binding, use_argument_buffer_for_samplers, slot); + } + } + } + else { + MTL_LOG_WARNING( + "Shader %p expected texture to be bound to slot %d -- Slot exceeds the " + "hardware/API limit of '%d'. (name:'%s')\n", + this->pipeline_state.active_shader, + slot, + GPU_max_textures(), + shader_interface->get_name_at_offset(shader_texture_info.name_offset)); + } + } + + /* Construct and Bind argument buffer. + * NOTE(Metal): Samplers use an argument buffer when the limit of 16 samplers is exceeded. */ + if (use_argument_buffer_for_samplers) { +#ifndef NDEBUG + /* Debug check to validate each expected texture in the shader interface has a valid + * sampler object bound to the context. We will need all of these to be valid + * when constructing the sampler argument buffer. */ + for (const uint i : IndexRange(shader_interface->get_max_texture_index() + 1)) { + const MTLShaderTexture &texture = shader_interface->get_texture(i); + if (texture.used) { + BLI_assert(this->samplers_.mtl_sampler[i] != nil); + } + } +#endif + + /* Check to ensure the buffer binding index for the argument buffer has been assigned. + * This PSO property will be set if we expect to use argument buffers, and the shader + * uses any amount of textures. */ + BLI_assert(compute_arg_buffer_bind_index >= 0); + if (compute_arg_buffer_bind_index >= 0) { + /* Offset binding index to be relative to the start of static uniform buffer binding slots. + * The first N slots, prior to `pipeline_state_instance->base_uniform_buffer_index` are + * used by vertex and index buffer bindings, and the number of buffers present will vary + * between PSOs. */ + int arg_buffer_idx = (pipeline_state_instance.base_uniform_buffer_index + + compute_arg_buffer_bind_index); + assert(arg_buffer_idx < 32); + id argument_encoder = shader_interface->find_argument_encoder( + arg_buffer_idx); + if (argument_encoder == nil) { + argument_encoder = [pipeline_state_instance.compute + newArgumentEncoderWithBufferIndex:arg_buffer_idx]; + shader_interface->insert_argument_encoder(arg_buffer_idx, argument_encoder); + } + + /* Generate or Fetch argument buffer sampler configuration. + * NOTE(Metal): we need to base sampler counts off of the maximal texture + * index. This is not the most optimal, but in practice, not a use-case + * when argument buffers are required. + * This is because with explicit texture indices, the binding indices + * should match across draws, to allow the high-level to optimize bind-points. */ + gpu::MTLBuffer *encoder_buffer = nullptr; + this->samplers_.num_samplers = shader_interface->get_max_texture_index() + 1; + + gpu::MTLBuffer **cached_smp_buffer_search = this->cached_sampler_buffers_.lookup_ptr( + this->samplers_); + if (cached_smp_buffer_search != nullptr) { + encoder_buffer = *cached_smp_buffer_search; + } + else { + /* Populate argument buffer with current global sampler bindings. */ + int size = [argument_encoder encodedLength]; + int alignment = max_uu([argument_encoder alignment], 256); + int size_align_delta = (size % alignment); + int aligned_alloc_size = ((alignment > 1) && (size_align_delta > 0)) ? + size + (alignment - (size % alignment)) : + size; + + /* Allocate buffer to store encoded sampler arguments. */ + encoder_buffer = MTLContext::get_global_memory_manager()->allocate(aligned_alloc_size, + true); + BLI_assert(encoder_buffer); + BLI_assert(encoder_buffer->get_metal_buffer()); + [argument_encoder setArgumentBuffer:encoder_buffer->get_metal_buffer() offset:0]; + [argument_encoder + setSamplerStates:this->samplers_.mtl_sampler + withRange:NSMakeRange(0, shader_interface->get_max_texture_index() + 1)]; + encoder_buffer->flush(); + + /* Insert into cache. */ + this->cached_sampler_buffers_.add_new(this->samplers_, encoder_buffer); + } + + BLI_assert(encoder_buffer != nullptr); + int compute_buffer_index = (pipeline_state_instance.base_uniform_buffer_index + + compute_arg_buffer_bind_index); + cs.bind_compute_buffer(encoder_buffer->get_metal_buffer(), 0, compute_buffer_index); + } + } + } +} + /* Encode latest depth-stencil state. */ void MTLContext::ensure_depth_stencil_state(MTLPrimitiveType prim_type) { @@ -1531,6 +1836,81 @@ void MTLContext::ensure_depth_stencil_state(MTLPrimitiveType prim_type) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Compute dispatch. + * \{ */ + +bool MTLContext::ensure_compute_pipeline_state() +{ + /* Verify if bound shader is valid and fetch MTLComputePipelineStateInstance. */ + /* Check if an active shader is bound. */ + if (!this->pipeline_state.active_shader) { + MTL_LOG_WARNING("No Metal shader bound!\n"); + return false; + } + /* Also ensure active shader is valid. */ + if (!this->pipeline_state.active_shader->is_valid()) { + MTL_LOG_WARNING( + "Bound active shader is not valid (Missing/invalid implementation for Metal).\n", ); + return false; + } + /* Verify this is a compute shader. */ + + /* Fetch shader interface. */ + MTLShaderInterface *shader_interface = this->pipeline_state.active_shader->get_interface(); + if (shader_interface == nullptr) { + MTL_LOG_WARNING("Bound active shader does not have a valid shader interface!\n", ); + return false; + } + + bool success = this->pipeline_state.active_shader->bake_compute_pipeline_state(this); + const MTLComputePipelineStateInstance &compute_pso_inst = + this->pipeline_state.active_shader->get_compute_pipeline_state(); + if (!success || compute_pso_inst.pso == nil) { + MTL_LOG_WARNING("No valid compute PSO for compute dispatch!\n", ); + return false; + } + return true; +} + +void MTLContext::compute_dispatch(int groups_x_len, int groups_y_len, int groups_z_len) +{ + /* Ensure all resources required by upcoming compute submission are correctly bound. */ + if (this->ensure_compute_pipeline_state()) { + /* Shader instance. */ + MTLShaderInterface *shader_interface = this->pipeline_state.active_shader->get_interface(); + const MTLComputePipelineStateInstance &compute_pso_inst = + this->pipeline_state.active_shader->get_compute_pipeline_state(); + + /* Begin compute encoder. */ + id compute_encoder = + this->main_command_buffer.ensure_begin_compute_encoder(); + BLI_assert(compute_encoder != nil); + + /* Bind PSO. */ + MTLComputeState &cs = this->main_command_buffer.get_compute_state(); + cs.bind_pso(compute_pso_inst.pso); + + /* Bind buffers. */ + this->ensure_uniform_buffer_bindings(compute_encoder, shader_interface, compute_pso_inst); + /** Ensure resource bindings. */ + /* Texture Bindings. */ + /* We will iterate through all texture bindings on the context and determine if any of the + * active slots match those in our shader interface. If so, textures will be bound. */ + if (shader_interface->get_total_textures() > 0) { + this->ensure_texture_bindings(compute_encoder, shader_interface, compute_pso_inst); + } + + /* Dispatch compute. */ + [compute_encoder dispatchThreadgroups:MTLSizeMake(groups_x_len, groups_y_len, groups_z_len) + threadsPerThreadgroup:MTLSizeMake(compute_pso_inst.threadgroup_x_len, + compute_pso_inst.threadgroup_y_len, + compute_pso_inst.threadgroup_z_len)]; + } +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Visibility buffer control for MTLQueryPool. * \{ */ diff --git a/source/blender/gpu/metal/mtl_shader.hh b/source/blender/gpu/metal/mtl_shader.hh index 29df1f22ced..47e492dd69c 100644 --- a/source/blender/gpu/metal/mtl_shader.hh +++ b/source/blender/gpu/metal/mtl_shader.hh @@ -70,6 +70,8 @@ struct MTLRenderPipelineStateInstance { /* Base bind index for binding uniform buffers, offset based on other * bound buffers such as vertex buffers, as the count can vary. */ int base_uniform_buffer_index; + /* Base bind index for binding storage buffers. */ + int base_ssbo_buffer_index; /* buffer bind slot used for null attributes (-1 if not needed). */ int null_attribute_buffer_index; /* buffer bind used for transform feedback output buffer. */ @@ -86,14 +88,43 @@ struct MTLRenderPipelineStateInstance { blender::Vector buffer_bindings_reflection_data_frag; }; +/* Metal COmpute Pipeline State instance. */ +struct MTLComputePipelineStateInstance { + /* Function instances with specialization. + * Required for argument encoder construction. */ + id compute = nil; + /* PSO handle. */ + id pso = nil; + /* Base bind index for binding uniform buffers, offset based on other + * bound buffers such as vertex buffers, as the count can vary. */ + int base_uniform_buffer_index = -1; + /* Base bind index for binding storage buffers. */ + int base_ssbo_buffer_index = -1; + + int threadgroup_x_len = 1; + int threadgroup_y_len = 1; + int threadgroup_z_len = 1; + + inline void set_compute_workgroup_size(int workgroup_size_x, + int workgroup_size_y, + int workgroup_size_z) + { + this->threadgroup_x_len = workgroup_size_x; + this->threadgroup_y_len = workgroup_size_y; + this->threadgroup_z_len = workgroup_size_z; + } +}; + /* #MTLShaderBuilder source wrapper used during initial compilation. */ struct MTLShaderBuilder { NSString *msl_source_vert_ = @""; NSString *msl_source_frag_ = @""; + NSString *msl_source_compute_ = @""; /* Generated GLSL source used during compilation. */ std::string glsl_vertex_source_ = ""; std::string glsl_fragment_source_ = ""; + std::string glsl_compute_source_ = ""; /* Indicates whether source code has been provided via MSL directly. */ bool source_from_msl_ = false; @@ -141,10 +172,12 @@ class MTLShader : public Shader { MTLShaderBuilder *shd_builder_ = nullptr; NSString *vertex_function_name_ = @""; NSString *fragment_function_name_ = @""; + NSString *compute_function_name_ = @""; /** Compiled shader resources. */ id shader_library_vert_ = nil; id shader_library_frag_ = nil; + id shader_library_compute_ = nil; bool valid_ = false; /** Render pipeline state and PSO caching. */ @@ -156,6 +189,9 @@ class MTLShader : public Shader { /* Cache of compiled PipelineStateObjects. */ blender::Map pso_cache_; + /** Compute pipeline state and Compute PSO caching. */ + MTLComputePipelineStateInstance compute_pso_instance_; + /* True to enable multi-layered rendering support. */ bool uses_mtl_array_index_ = false; @@ -219,6 +255,7 @@ class MTLShader : public Shader { /* Compile and build - Return true if successful. */ bool finalize(const shader::ShaderCreateInfo *info = nullptr) override; + bool finalize_compute(const shader::ShaderCreateInfo *info); /* Utility. */ bool is_valid() @@ -289,11 +326,15 @@ class MTLShader : public Shader { /* Metal shader properties and source mapping. */ void set_vertex_function_name(NSString *vetex_function_name); - void set_fragment_function_name(NSString *fragment_function_name_); + void set_fragment_function_name(NSString *fragment_function_name); + void set_compute_function_name(NSString *compute_function_name); void shader_source_from_msl(NSString *input_vertex_source, NSString *input_fragment_source); + void shader_compute_source_from_msl(NSString *input_compute_source); void set_interface(MTLShaderInterface *interface); MTLRenderPipelineStateInstance *bake_current_pipeline_state(MTLContext *ctx, MTLPrimitiveTopologyClass prim_type); + bool bake_compute_pipeline_state(MTLContext *ctx); + const MTLComputePipelineStateInstance &get_compute_pipeline_state(); /* Transform Feedback. */ GPUVertBuf *get_transform_feedback_active_buffer(); @@ -302,6 +343,7 @@ class MTLShader : public Shader { private: /* Generate MSL shader from GLSL source. */ bool generate_msl_from_glsl(const shader::ShaderCreateInfo *info); + bool generate_msl_from_glsl_compute(const shader::ShaderCreateInfo *info); MEM_CXX_CLASS_ALLOC_FUNCS("MTLShader"); }; diff --git a/source/blender/gpu/metal/mtl_shader.mm b/source/blender/gpu/metal/mtl_shader.mm index 496f919d189..c1df57f618c 100644 --- a/source/blender/gpu/metal/mtl_shader.mm +++ b/source/blender/gpu/metal/mtl_shader.mm @@ -124,6 +124,15 @@ MTLShader::~MTLShader() } pso_cache_.clear(); + /* Free Compute pipeline state object. */ + if (compute_pso_instance_.compute) { + [compute_pso_instance_.compute release]; + compute_pso_instance_.compute = nil; + } + if (compute_pso_instance_.pso) { + [compute_pso_instance_.pso release]; + compute_pso_instance_.pso = nil; + } /* NOTE(Metal): #ShaderInterface deletion is handled in the super destructor `~Shader()`. */ } valid_ = false; @@ -181,12 +190,19 @@ void MTLShader::fragment_shader_from_glsl(MutableSpan sources) void MTLShader::compute_shader_from_glsl(MutableSpan sources) { + /* Flag source as not being compiled from native MSL. */ + BLI_assert(shd_builder_ != nullptr); + shd_builder_->source_from_msl_ = false; + /* Remove #version tag entry. */ sources[0] = ""; - /* TODO(Metal): Support compute shaders in Metal. */ - MTL_LOG_WARNING( - "MTLShader::compute_shader_from_glsl - Compute shaders currently unsupported!\n"); + /* Consolidate GLSL compute sources. */ + std::stringstream ss; + for (int i = 0; i < sources.size(); i++) { + ss << sources[i] << std::endl; + } + shd_builder_->glsl_compute_source_ = ss.str(); } bool MTLShader::finalize(const shader::ShaderCreateInfo *info) @@ -196,6 +212,14 @@ bool MTLShader::finalize(const shader::ShaderCreateInfo *info) MTL_LOG_ERROR("Shader (%p) '%s' has already been finalized!\n", this, this->name_get()); } + /* Compute shaders. */ + bool is_compute = false; + if (shd_builder_->glsl_compute_source_.size() > 0) { + BLI_assert_msg(info != nullptr, "Compute shaders must use CreateInfo.\n"); + BLI_assert_msg(!shd_builder_->source_from_msl_, "Compute shaders must compile from GLSL."); + is_compute = true; + } + /* Perform GLSL to MSL source translation. */ BLI_assert(shd_builder_ != nullptr); if (!shd_builder_->source_from_msl_) { @@ -226,12 +250,20 @@ bool MTLShader::finalize(const shader::ShaderCreateInfo *info) BLI_assert(device != nil); /* Ensure source and stage entry-point names are set. */ - BLI_assert([vertex_function_name_ length] > 0); - if (transform_feedback_type_ == GPU_SHADER_TFB_NONE) { - BLI_assert([fragment_function_name_ length] > 0); - } BLI_assert(shd_builder_ != nullptr); - BLI_assert([shd_builder_->msl_source_vert_ length] > 0); + if (is_compute) { + /* Compute path. */ + BLI_assert([compute_function_name_ length] > 0); + BLI_assert([shd_builder_->msl_source_compute_ length] > 0); + } + else { + /* Vertex/Fragment path. */ + BLI_assert([vertex_function_name_ length] > 0); + if (transform_feedback_type_ == GPU_SHADER_TFB_NONE) { + BLI_assert([fragment_function_name_ length] > 0); + } + BLI_assert([shd_builder_->msl_source_vert_ length] > 0); + } @autoreleasepool { MTLCompileOptions *options = [[[MTLCompileOptions alloc] init] autorelease]; @@ -239,13 +271,24 @@ bool MTLShader::finalize(const shader::ShaderCreateInfo *info) options.fastMathEnabled = YES; NSString *source_to_compile = shd_builder_->msl_source_vert_; - for (int src_stage = 0; src_stage <= 1; src_stage++) { - source_to_compile = (src_stage == 0) ? shd_builder_->msl_source_vert_ : - shd_builder_->msl_source_frag_; + /* Vertex/Fragment compile stages 0 and/or 1. + * Compute shaders compile as stage 2. */ + ShaderStage initial_stage = (is_compute) ? ShaderStage::COMPUTE : ShaderStage::VERTEX; + ShaderStage src_stage = initial_stage; + uint8_t total_stages = (is_compute) ? 1 : 2; + + for (int stage_count = 0; stage_count < total_stages; stage_count++) { + + source_to_compile = (src_stage == ShaderStage::VERTEX) ? + shd_builder_->msl_source_vert_ : + ((src_stage == ShaderStage::COMPUTE) ? + shd_builder_->msl_source_compute_ : + shd_builder_->msl_source_frag_); /* Transform feedback, skip compilation. */ - if (src_stage == 1 && (transform_feedback_type_ != GPU_SHADER_TFB_NONE)) { + if (src_stage == ShaderStage::FRAGMENT && + (transform_feedback_type_ != GPU_SHADER_TFB_NONE)) { shader_library_frag_ = nil; break; } @@ -276,8 +319,9 @@ bool MTLShader::finalize(const shader::ShaderCreateInfo *info) /* Only exit out if genuine error and not warning. */ if ([[error localizedDescription] rangeOfString:@"Compilation succeeded"].location == NSNotFound) { - NSLog( - @"Compile Error - Metal Shader Library (Stage: %d), error %@ \n", src_stage, error); + NSLog(@"Compile Error - Metal Shader Library (Stage: %hhu), error %@ \n", + src_stage, + error); BLI_assert(false); /* Release temporary compilation resources. */ @@ -287,30 +331,52 @@ bool MTLShader::finalize(const shader::ShaderCreateInfo *info) } } - MTL_LOG_INFO("Successfully compiled Metal Shader Library (Stage: %d) for shader; %s\n", - src_stage, - name); BLI_assert(library != nil); - if (src_stage == 0) { - /* Retain generated library and assign debug name. */ - shader_library_vert_ = library; - [shader_library_vert_ retain]; - shader_library_vert_.label = [NSString stringWithUTF8String:this->name]; - } - else { - /* Retain generated library for fragment shader and assign debug name. */ - shader_library_frag_ = library; - [shader_library_frag_ retain]; - shader_library_frag_.label = [NSString stringWithUTF8String:this->name]; + + switch (src_stage) { + case ShaderStage::VERTEX: { + /* Retain generated library and assign debug name. */ + shader_library_vert_ = library; + [shader_library_vert_ retain]; + shader_library_vert_.label = [NSString stringWithUTF8String:this->name]; + } break; + case ShaderStage::FRAGMENT: { + /* Retain generated library for fragment shader and assign debug name. */ + shader_library_frag_ = library; + [shader_library_frag_ retain]; + shader_library_frag_.label = [NSString stringWithUTF8String:this->name]; + } break; + case ShaderStage::COMPUTE: { + /* Retain generated library for fragment shader and assign debug name. */ + shader_library_compute_ = library; + [shader_library_compute_ retain]; + shader_library_compute_.label = [NSString stringWithUTF8String:this->name]; + } break; + case ShaderStage::ANY: { + /* Supress warnings. */ + BLI_assert_unreachable(); + } break; } [source_with_header autorelease]; - } - pso_descriptor_.label = [NSString stringWithUTF8String:this->name]; - /* Prepare descriptor. */ - pso_descriptor_ = [[MTLRenderPipelineDescriptor alloc] init]; - [pso_descriptor_ retain]; + /* Move onto next compilation stage. */ + if (!is_compute) { + src_stage = ShaderStage::FRAGMENT; + } + else { + break; + } + } + + /* Create descriptors. + * Each shader type requires a differing descriptor. */ + if (!is_compute) { + /* Prepare Render pipeline descriptor. */ + pso_descriptor_ = [[MTLRenderPipelineDescriptor alloc] init]; + [pso_descriptor_ retain]; + pso_descriptor_.label = [NSString stringWithUTF8String:this->name]; + } /* Shader has successfully been created. */ valid_ = true; @@ -324,6 +390,11 @@ bool MTLShader::finalize(const shader::ShaderCreateInfo *info) else { push_constant_data_ = nullptr; } + + /* If this is a compute shader, bake PSO for compute straight-away. */ + if (is_compute) { + this->bake_compute_pipeline_state(context_); + } } /* Release temporary compilation resources. */ @@ -332,6 +403,11 @@ bool MTLShader::finalize(const shader::ShaderCreateInfo *info) return true; } +const MTLComputePipelineStateInstance &MTLShader::get_compute_pipeline_state() +{ + return this->compute_pso_instance_; +} + void MTLShader::transform_feedback_names_set(Span name_list, const eGPUShaderTFBType geom_type) { @@ -556,6 +632,11 @@ void MTLShader::set_fragment_function_name(NSString *frag_function_name) fragment_function_name_ = frag_function_name; } +void MTLShader::set_compute_function_name(NSString *compute_function_name) +{ + compute_function_name_ = compute_function_name; +} + void MTLShader::shader_source_from_msl(NSString *input_vertex_source, NSString *input_fragment_source) { @@ -565,6 +646,13 @@ void MTLShader::shader_source_from_msl(NSString *input_vertex_source, shd_builder_->source_from_msl_ = true; } +void MTLShader::shader_compute_source_from_msl(NSString *input_compute_source) +{ + BLI_assert(shd_builder_ != nullptr); + shd_builder_->msl_source_compute_ = input_compute_source; + shd_builder_->source_from_msl_ = true; +} + void MTLShader::set_interface(MTLShaderInterface *interface) { /* Assign gpu::Shader super-class interface. */ @@ -985,7 +1073,6 @@ MTLRenderPipelineStateInstance *MTLShader::bake_current_pipeline_state( desc.stencilAttachmentPixelFormat = current_state.stencil_attachment_format; /* Compile PSO */ - MTLAutoreleasedRenderPipelineReflection reflection_data; id pso = [ctx->device newRenderPipelineStateWithDescriptor:desc @@ -1003,7 +1090,9 @@ MTLRenderPipelineStateInstance *MTLShader::bake_current_pipeline_state( return nullptr; } else { +#ifndef NDEBUG NSLog(@"Successfully compiled PSO for shader: %s (Metal Context: %p)\n", this->name, ctx); +#endif } /* Prepare pipeline state instance. */ @@ -1106,6 +1195,83 @@ MTLRenderPipelineStateInstance *MTLShader::bake_current_pipeline_state( return pso_inst; } } + +bool MTLShader::bake_compute_pipeline_state(MTLContext *ctx) +{ + /* NOTE(Metal): Bakes and caches a PSO for compute. */ + BLI_assert(this); + BLI_assert(this->is_valid()); + BLI_assert(shader_library_compute_ != nil); + + if (compute_pso_instance_.pso == nil) { + /* Prepare Compute Pipeline Descriptor. */ + + /* Setup function specialization constants, used to modify and optimize + * generated code based on current render pipeline configuration. */ + MTLFunctionConstantValues *values = [[MTLFunctionConstantValues new] autorelease]; + + /* Offset the bind index for Uniform buffers such that they begin after the VBO + * buffer bind slots. `MTL_uniform_buffer_base_index` is passed as a function + * specialization constant, customized per unique pipeline state permutation. + * + * For Compute shaders, this offset is always zero, but this needs setting as + * it is expected as part of the common Metal shader header.*/ + int MTL_uniform_buffer_base_index = 0; + [values setConstantValue:&MTL_uniform_buffer_base_index + type:MTLDataTypeInt + withName:@"MTL_uniform_buffer_base_index"]; + + /* TODO: SSBO binding base index. */ + + /* Compile compute function. */ + NSError *error = nullptr; + id compute_function = [shader_library_compute_ + newFunctionWithName:compute_function_name_ + constantValues:values + error:&error]; + if (error) { + NSLog(@"Compile Error - Metal Shader compute function, error %@", error); + + /* Only exit out if genuine error and not warning */ + if ([[error localizedDescription] rangeOfString:@"Compilation succeeded"].location == + NSNotFound) { + BLI_assert(false); + return false; + } + } + + /* Compile PSO. */ + id pso = [ctx->device + newComputePipelineStateWithFunction:compute_function + error:&error]; + if (error) { + NSLog(@"Failed to create PSO for compute shader: %s error %@\n", this->name, error); + BLI_assert(false); + return false; + } + else if (!pso) { + NSLog(@"Failed to create PSO for compute shader: %s, but no error was provided!\n", + this->name); + BLI_assert(false); + return false; + } + else { +#ifndef NDEBUG + NSLog(@"Successfully compiled compute PSO for shader: %s (Metal Context: %p)\n", + this->name, + ctx); +#endif + } + + /* Gather reflection data and create MTLComputePipelineStateInstance to store results. */ + compute_pso_instance_.compute = [compute_function retain]; + compute_pso_instance_.pso = [pso retain]; + compute_pso_instance_.base_uniform_buffer_index = MTL_uniform_buffer_base_index; + /* TODO: Add SSBO base buffer index support. */ + compute_pso_instance_.base_ssbo_buffer_index = -1; + } + return true; +} /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/gpu/metal/mtl_shader_generator.hh b/source/blender/gpu/metal/mtl_shader_generator.hh index 90f9a86b064..39772baf09b 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.hh +++ b/source/blender/gpu/metal/mtl_shader_generator.hh @@ -355,6 +355,14 @@ struct MSLFragmentOutputAttribute { } }; +struct MSLSharedMemoryBlock { + /* e.g. shared vec4 color_cache[cache_size][cache_size]; */ + std::string type_name; + std::string varname; + bool is_array; + std::string array_decl; /* String containing array declaration. e.g. [cache_size][cache_size]*/ +}; + class MSLGeneratorInterface { static char *msl_patch_default; @@ -375,6 +383,8 @@ class MSLGeneratorInterface { blender::Vector vertex_output_varyings_tf; /* Clip Distances. */ blender::Vector clip_distances; + /* Shared Memory Blocks. */ + blender::Vector shared_memory_blocks; /** GL Global usage. */ /* Whether GL position is used, or an alternative vertex output should be the default. */ @@ -397,12 +407,20 @@ class MSLGeneratorInterface { bool uses_mtl_array_index_; bool uses_transform_feedback; bool uses_barycentrics; + /* Compute shader global variables. */ + bool uses_gl_GlobalInvocationID; + bool uses_gl_WorkGroupSize; + bool uses_gl_WorkGroupID; + bool uses_gl_NumWorkGroups; + bool uses_gl_LocalInvocationIndex; + bool uses_gl_LocalInvocationID; /* Parameters. */ shader::DepthWrite depth_write; - /* Shader buffer bind indices for argument buffers. */ - int sampler_argument_buffer_bind_index[2] = {-1, -1}; + /* Shader buffer bind indices for argument buffers per shader stage. + * NOTE: Compute stage will re-use index 0. */ + int sampler_argument_buffer_bind_index[3] = {-1, -1, -1}; /*** SSBO Vertex fetch mode. ***/ /* Indicates whether to pass in Vertex Buffer's as a regular buffers instead of using vertex @@ -453,8 +471,10 @@ class MSLGeneratorInterface { std::string generate_msl_fragment_out_struct(); std::string generate_msl_vertex_inputs_string(); std::string generate_msl_fragment_inputs_string(); + std::string generate_msl_compute_inputs_string(); std::string generate_msl_vertex_entry_stub(); std::string generate_msl_fragment_entry_stub(); + std::string generate_msl_compute_entry_stub(); std::string generate_msl_global_uniform_population(ShaderStage stage); std::string generate_ubo_block_macro_chain(MSLUniformBlock block); std::string generate_msl_uniform_block_population(ShaderStage stage); @@ -482,13 +502,31 @@ class MSLGeneratorInterface { MEM_CXX_CLASS_ALLOC_FUNCS("MSLGeneratorInterface"); }; -inline std::string get_stage_class_name(ShaderStage stage) +inline const char *get_stage_class_name(ShaderStage stage) { switch (stage) { case ShaderStage::VERTEX: return "MTLShaderVertexImpl"; case ShaderStage::FRAGMENT: return "MTLShaderFragmentImpl"; + case ShaderStage::COMPUTE: + return "MTLShaderComputeImpl"; + default: + BLI_assert_unreachable(); + return ""; + } + return ""; +} + +inline const char *get_shader_stage_instance_name(ShaderStage stage) +{ + switch (stage) { + case ShaderStage::VERTEX: + return "vertex_shader_instance"; + case ShaderStage::FRAGMENT: + return "fragment_shader_instance"; + case ShaderStage::COMPUTE: + return "compute_shader_instance"; default: BLI_assert_unreachable(); return ""; @@ -726,4 +764,26 @@ inline const char *to_string(const shader::Type &type) } } +inline char *next_symbol_in_range(char *begin, char *end, char symbol) +{ + for (char *a = begin; a < end; a++) { + if (*a == symbol) { + return a; + } + } + return nullptr; +} + +inline char *next_word_in_range(char *begin, char *end) +{ + for (char *a = begin; a < end; a++) { + char chr = *a; + if ((chr >= 'a' && chr <= 'z') || (chr >= 'A' && chr <= 'Z') || (chr >= '0' && chr <= '9') || + (chr == '_')) { + return a; + } + } + return nullptr; +} + } // namespace blender::gpu diff --git a/source/blender/gpu/metal/mtl_shader_generator.mm b/source/blender/gpu/metal/mtl_shader_generator.mm index 880016589fc..15d451d0ddb 100644 --- a/source/blender/gpu/metal/mtl_shader_generator.mm +++ b/source/blender/gpu/metal/mtl_shader_generator.mm @@ -108,7 +108,6 @@ static eMTLDataType to_mtl_type(Type type) static std::regex remove_non_numeric_characters("[^0-9]"); -#ifndef NDEBUG static void remove_multiline_comments_func(std::string &str) { char *current_str_begin = &*str.begin(); @@ -158,7 +157,6 @@ static void remove_singleline_comments_func(std::string &str) } } } -#endif static bool is_program_word(const char *chr, int *len) { @@ -207,15 +205,36 @@ static void replace_outvars(std::string &str) if (is_program_word(word_base2, &len2)) { /* Match found. */ bool is_array = (*(word_base2 + len2) == '['); - - /* Generate out-variable pattern of form `THD type&var` from original `out vec4 var`. */ - *start = 'T'; - *(start + 1) = 'H'; - *(start + 2) = 'D'; - for (char *clear = start + 3; clear < c + 4; clear++) { - *clear = ' '; + if (is_array) { + /* Generate out-variable pattern for arrays, of form + * `OUT(vec2,samples,CRYPTOMATTE_LEVELS_MAX)` + * replacing original `out vec2 samples[SAMPLE_LEN]` + * using 'OUT' macro declared in mtl_shader_defines.msl*/ + char *array_end = strchr(word_base2 + len2, ']'); + if (array_end != nullptr) { + *start = 'O'; + *(start + 1) = 'U'; + *(start + 2) = 'T'; + *(start + 3) = '('; + for (char *clear = start + 4; clear < c + 4; clear++) { + *clear = ' '; + } + *(word_base2 - 1) = ','; + *(word_base2 + len2) = ','; + *array_end = ')'; + } + } + else { + /* Generate out-variable pattern of form `THD type&var` from original `out vec4 var`. + */ + *start = 'T'; + *(start + 1) = 'H'; + *(start + 2) = 'D'; + for (char *clear = start + 3; clear < c + 4; clear++) { + *clear = ' '; + } + *(word_base2 - 1) = '&'; } - *(word_base2 - 1) = is_array ? '*' : '&'; } } } @@ -387,6 +406,138 @@ static bool extract_ssbo_pragma_info(const MTLShader *shader, return false; } +/* Extract shared memory declaration and their parameters. + * Inserts extracted cases as entries in MSLGeneratorInterface's shared memory block + * list. These will later be used to generate shared memory declarations within the entry point. + * + * TODO(Metal/GPU): Move shared memory declarations to GPUShaderCreateInfo. This is currently a + * necessary workaround to match GLSL functionality and enable full compute shader support. In the + * long term, best to avoid needing to perform this operation. */ +void extract_shared_memory_blocks(MSLGeneratorInterface &msl_iface, + std::string &glsl_compute_source) +{ + msl_iface.shared_memory_blocks.clear(); + char *current_str_begin = &*glsl_compute_source.begin(); + char *current_str_end = &*glsl_compute_source.end(); + + for (char *c = current_str_begin; c < current_str_end - 6; c++) { + /* Find first instance of "shared ". */ + char *c_expr_start = strstr(c, "shared "); + if (c_expr_start == nullptr) { + break; + } + /* Check if "shared" was part of a previous word. If so, this is not valid. */ + if (next_word_in_range(c_expr_start - 1, c_expr_start) != nullptr) { + c += 7; /* Jump forward by length of "shared ". */ + continue; + } + + /* Jump to shared declaration and detect end of statement. */ + c = c_expr_start; + char *c_expr_end = strstr(c, ";"); + if (c_expr_end == nullptr) { + break; + } + + /* Prepare MSLSharedMemoryBlock instance. */ + MSLSharedMemoryBlock new_shared_block; + char buf[256]; + + /* Read type-name. */ + c += 7; /* Jump forward by length of "shared ". */ + c = next_word_in_range(c, c_expr_end); + if (c == nullptr) { + c = c_expr_end + 1; + continue; + } + + char *c_next_space = next_symbol_in_range(c, c_expr_end, ' '); + if (c_next_space == nullptr) { + c = c_expr_end + 1; + continue; + } + int len = c_next_space - c; + BLI_assert(len < 256); + strncpy(buf, c, len); + buf[len] = '\0'; + new_shared_block.type_name = std::string(buf); + + /* Read var-name. + * Varname can either come right before the final semi-colon, or + * with following array syntax. + * spaces may exist before closing symbol. */ + c = c_next_space + 1; + c = next_word_in_range(c, c_expr_end); + if (c == nullptr) { + c = c_expr_end + 1; + continue; + } + + char *c_array_begin = next_symbol_in_range(c, c_expr_end, '['); + c_next_space = next_symbol_in_range(c, c_expr_end, ' '); + + char *varname_end = nullptr; + if (c_array_begin != nullptr) { + /* Array path. */ + if (c_next_space != nullptr) { + varname_end = (c_next_space < c_array_begin) ? c_next_space : c_array_begin; + } + else { + varname_end = c_array_begin; + } + new_shared_block.is_array = true; + } + else { + /* Ending semi-colon. */ + if (c_next_space != nullptr) { + varname_end = (c_next_space < c_expr_end) ? c_next_space : c_expr_end; + } + else { + varname_end = c_expr_end; + } + new_shared_block.is_array = false; + } + len = varname_end - c; + BLI_assert(len < 256); + strncpy(buf, c, len); + buf[len] = '\0'; + new_shared_block.varname = std::string(buf); + + /* Determine if array. */ + if (new_shared_block.is_array) { + int len = c_expr_end - c_array_begin; + strncpy(buf, c_array_begin, len); + buf[len] = '\0'; + new_shared_block.array_decl = std::string(buf); + } + + /* Shared block is valid, add it to the list and replace declaration with class member. + * reference. This declaration needs to have one of the formats: + * TG int& varname; + * TG int (&varname)[len][len] + * + * In order to fit in the same space, replace `threadgroup` with `TG` macro. + */ + for (char *c = c_expr_start; c <= c_expr_end; c++) { + *c = ' '; + } + std::string out_str = "TG "; + out_str += new_shared_block.type_name; + out_str += (new_shared_block.is_array) ? "(&" : "&"; + out_str += new_shared_block.varname; + if (new_shared_block.is_array) { + out_str += ")" + new_shared_block.array_decl; + } + out_str += ";;"; + strncpy(c_expr_start, out_str.c_str(), out_str.length() - 1); + + /* Jump to end of statement. */ + c = c_expr_end + 1; + + msl_iface.shared_memory_blocks.append(new_shared_block); + } +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -501,8 +652,9 @@ std::string MTLShader::geometry_layout_declare(const shader::ShaderCreateInfo &i std::string MTLShader::compute_layout_declare(const ShaderCreateInfo &info) const { - /* TODO(Metal): Metal compute layout pending compute support. */ - BLI_assert_msg(false, "Compute shaders unsupported by Metal"); + /* Metal supports compute shaders. THis function is a pass-through. + * Compute shader interface population happens during mtl_shader_generator, as part of GLSL + * conversion. */ return ""; } @@ -543,6 +695,11 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info) return false; } + /* Compute shaders use differing compilation path. */ + if (shd_builder_->glsl_compute_source_.size() > 0) { + return this->generate_msl_from_glsl_compute(info); + } + /* #MSLGeneratorInterface is a class populated to describe all parameters, resources, bindings * and features used by the source GLSL shader. This information is then used to generate the * appropriate Metal entry points and perform any required source translation. */ @@ -1061,7 +1218,6 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info) ([NSString stringWithUTF8String:ss_fragment.str().c_str()]); this->shader_source_from_msl(msl_final_vert, msl_final_frag); - shader_debug_printf("[METAL] BSL Converted into MSL\n"); #ifndef NDEBUG /* In debug mode, we inject the name of the shader into the entry-point function @@ -1091,6 +1247,231 @@ bool MTLShader::generate_msl_from_glsl(const shader::ShaderCreateInfo *info) return true; } +bool MTLShader::generate_msl_from_glsl_compute(const shader::ShaderCreateInfo *info) +{ + /* #MSLGeneratorInterface is a class populated to describe all parameters, resources, bindings + * and features used by the source GLSL shader. This information is then used to generate the + * appropriate Metal entry points and perform any required source translation. */ + MSLGeneratorInterface msl_iface(*this); + BLI_assert(shd_builder_ != nullptr); + + /* Populate #MSLGeneratorInterface from Create-Info. + * NOTE: this is a separate path as #MSLGeneratorInterface can also be manually populated + * from parsing, if support for shaders without create-info is required. */ + msl_iface.prepare_from_createinfo(info); + + /* Verify Source sizes are greater than zero. */ + BLI_assert(shd_builder_->glsl_compute_source_.size() > 0); + + /*** Regex Commands ***/ + /* Source cleanup and syntax replacement. */ + static std::regex remove_excess_newlines("\\n+"); + static std::regex replace_matrix_construct("mat([234](x[234])?)\\s*\\("); + + /* Special condition - mat3 and array constructor replacement. + * Also replace excessive new lines to ensure cases are not missed. */ + shd_builder_->glsl_compute_source_ = std::regex_replace( + shd_builder_->glsl_compute_source_, remove_excess_newlines, "\n"); + shd_builder_->glsl_compute_source_ = std::regex_replace( + shd_builder_->glsl_compute_source_, replace_matrix_construct, "MAT$1("); + replace_array_initializers_func(shd_builder_->glsl_compute_source_); + + /**** Extract usage of GL globals. ****/ + /* NOTE(METAL): Currently still performing fallback string scan, as info->builtins_ does + * not always contain the usage flag. This can be removed once all appropriate create-info's + * have been updated. In some cases, this may incur a false positive if access is guarded + * behind a macro. Though in these cases, unused code paths and parameters will be + * optimized out by the Metal shader compiler. */ + + /* gl_GlobalInvocationID. */ + msl_iface.uses_gl_GlobalInvocationID = + bool(info->builtins_ & BuiltinBits::GLOBAL_INVOCATION_ID) || + shd_builder_->glsl_compute_source_.find("gl_GlobalInvocationID") != std::string::npos; + /* gl_WorkGroupSize. */ + msl_iface.uses_gl_WorkGroupSize = bool(info->builtins_ & BuiltinBits::WORK_GROUP_SIZE) || + shd_builder_->glsl_compute_source_.find("gl_WorkGroupSize") != + std::string::npos; + /* gl_WorkGroupID. */ + msl_iface.uses_gl_WorkGroupID = bool(info->builtins_ & BuiltinBits::WORK_GROUP_ID) || + shd_builder_->glsl_compute_source_.find("gl_WorkGroupID") != + std::string::npos; + /* gl_NumWorkGroups. */ + msl_iface.uses_gl_NumWorkGroups = bool(info->builtins_ & BuiltinBits::NUM_WORK_GROUP) || + shd_builder_->glsl_compute_source_.find("gl_NumWorkGroups") != + std::string::npos; + /* gl_LocalInvocationIndex. */ + msl_iface.uses_gl_LocalInvocationIndex = + bool(info->builtins_ & BuiltinBits::LOCAL_INVOCATION_INDEX) || + shd_builder_->glsl_compute_source_.find("gl_LocalInvocationIndex") != std::string::npos; + /* gl_LocalInvocationID. */ + msl_iface.uses_gl_LocalInvocationID = bool(info->builtins_ & BuiltinBits::LOCAL_INVOCATION_ID) || + shd_builder_->glsl_compute_source_.find( + "gl_LocalInvocationID") != std::string::npos; + + /* Performance warning: Extract global-scope expressions. + * NOTE: This is dependent on stripping out comments + * to remove false positives. */ + remove_multiline_comments_func(shd_builder_->glsl_compute_source_); + remove_singleline_comments_func(shd_builder_->glsl_compute_source_); + + /** Extract usage of shared memory. + * For Metal shaders to compile, shared (threadgroup) memory cannot be declared globally. + * It must reside within a function scope. Hence, we need to extract these uses and generate + * shared memory blocks within the entry point function, which can then be passed as references + * to the remaining shader via the class function scope. + * + * The existing block definitions are then replaced with references to threadgroup memory blocks, + * but kept in-line in case external macros are used to declare the dimensions. */ + extract_shared_memory_blocks(msl_iface, shd_builder_->glsl_compute_source_); + + /* Replace 'out' attribute on function parameters with pass-by-reference. */ + replace_outvars(shd_builder_->glsl_compute_source_); + + /** Generate Compute shader stage. **/ + std::stringstream ss_compute; + +#ifndef NDEBUG + extract_global_scope_constants(shd_builder_->glsl_compute_source_, ss_compute); +#endif + + /* Conditional defines. */ + if (msl_iface.use_argument_buffer_for_samplers()) { + ss_compute << "#define USE_ARGUMENT_BUFFER_FOR_SAMPLERS 1" << std::endl; + ss_compute << "#define ARGUMENT_BUFFER_NUM_SAMPLERS " + << msl_iface.num_samplers_for_stage(ShaderStage::COMPUTE) << std::endl; + } + + /* Inject static workgroup sizes. */ + if (msl_iface.uses_gl_WorkGroupSize) { + } + + /* Inject constant work group sizes. */ + if (msl_iface.uses_gl_WorkGroupSize) { + ss_compute << "#define MTL_USE_WORKGROUP_SIZE 1" << std::endl; + ss_compute << "#define MTL_WORKGROUP_SIZE_X " << info->compute_layout_.local_size_x + << std::endl; + ss_compute << "#define MTL_WORKGROUP_SIZE_Y " + << ((info->compute_layout_.local_size_y != -1) ? + info->compute_layout_.local_size_y : + 1) + << std::endl; + ss_compute << "#define MTL_WORKGROUP_SIZE_Z " + << ((info->compute_layout_.local_size_y != -1) ? + info->compute_layout_.local_size_y : + 1) + << std::endl; + } + + /* Inject common Metal header. */ + ss_compute << msl_iface.msl_patch_default_get() << std::endl << std::endl; + + /* Wrap entire GLSL source inside class to create + * a scope within the class to enable use of global variables. + * e.g. global access to attributes, uniforms, UBOs, textures etc; */ + ss_compute << "class " << get_stage_class_name(ShaderStage::COMPUTE) << " {" << std::endl; + ss_compute << "public:" << std::endl; + + /* Generate Uniform data structs. */ + ss_compute << msl_iface.generate_msl_uniform_structs(ShaderStage::VERTEX); + + /* Add Texture members. + * These members pack both a texture and a sampler into a single + * struct, as both are needed within texture functions. + * e.g. `_mtl_combined_image_sampler_2d` + * The exact typename is generated inside `get_msl_typestring_wrapper()`. */ + for (const MSLTextureSampler &tex : msl_iface.texture_samplers) { + if (bool(tex.stage & ShaderStage::COMPUTE)) { + ss_compute << "\tthread " << tex.get_msl_typestring_wrapper(false) << ";" << std::endl; + } + } + ss_compute << std::endl; + + /* Conditionally use global GL variables. */ + if (msl_iface.uses_gl_GlobalInvocationID) { + ss_compute << "uint3 gl_GlobalInvocationID;" << std::endl; + } + if (msl_iface.uses_gl_WorkGroupID) { + ss_compute << "uint3 gl_WorkGroupID;" << std::endl; + } + if (msl_iface.uses_gl_NumWorkGroups) { + ss_compute << "uint3 gl_NumWorkGroups;" << std::endl; + } + if (msl_iface.uses_gl_LocalInvocationIndex) { + ss_compute << "uint gl_LocalInvocationIndex;" << std::endl; + } + if (msl_iface.uses_gl_LocalInvocationID) { + ss_compute << "uint3 gl_LocalInvocationID;" << std::endl; + } + + /* Inject main GLSL source into output stream. */ + ss_compute << shd_builder_->glsl_compute_source_ << std::endl; + + /* Compute constructor for Shared memory blocks, as we must pass + * local references from entry-point function scope into the class + * instantiation. */ + ss_compute << get_stage_class_name(ShaderStage::COMPUTE) << "("; + bool first = true; + if (msl_iface.shared_memory_blocks.size() > 0) { + for (const MSLSharedMemoryBlock &block : msl_iface.shared_memory_blocks) { + if (!first) { + ss_compute << ","; + } + if (block.is_array) { + ss_compute << "TG " << block.type_name << " (&_" << block.varname << ")" + << block.array_decl; + } + else { + ss_compute << "TG " << block.type_name << " &_" << block.varname; + } + ss_compute << std::endl; + first = false; + } + ss_compute << ") : "; + first = true; + for (const MSLSharedMemoryBlock &block : msl_iface.shared_memory_blocks) { + if (!first) { + ss_compute << ","; + } + ss_compute << block.varname << "(_" << block.varname << ")"; + first = false; + } + } + else { + ss_compute << ") "; + } + ss_compute << "{ }" << std::endl; + + /* Class Closing Bracket to end shader global scope. */ + ss_compute << "};" << std::endl; + + /* Generate Vertex shader entry-point function containing resource bindings. */ + ss_compute << msl_iface.generate_msl_compute_entry_stub(); + +#ifndef NDEBUG + /* In debug mode, we inject the name of the shader into the entry-point function + * name, as these are what show up in the Xcode GPU debugger. */ + this->set_compute_function_name( + [[NSString stringWithFormat:@"compute_function_entry_%s", this->name] retain]); +#else + this->set_compute_function_name(@"compute_function_entry"); +#endif + + NSString *msl_final_compute = [NSString stringWithUTF8String:ss_compute.str().c_str()]; + this->shader_compute_source_from_msl(msl_final_compute); + + /* Bake shader interface. */ + this->set_interface(msl_iface.bake_shader_interface(this->name)); + + /* Compute dims. */ + this->compute_pso_instance_.set_compute_workgroup_size( + max_ii(info->compute_layout_.local_size_x, 1), + max_ii(info->compute_layout_.local_size_y, 1), + max_ii(info->compute_layout_.local_size_z, 1)); + + /* Successfully completed GLSL to MSL translation. */ + return true; +} + constexpr size_t const_strlen(const char *str) { return (*str == '\0') ? 0 : const_strlen(str + 1) + 1; @@ -1256,7 +1637,7 @@ void MSLGeneratorInterface::prepare_from_createinfo(const shader::ShaderCreateIn } MSLTextureSampler msl_tex( - ShaderStage::BOTH, res.sampler.type, res.sampler.name, access, used_slot); + ShaderStage::ANY, res.sampler.type, res.sampler.name, access, used_slot); texture_samplers.append(msl_tex); } break; @@ -1284,9 +1665,12 @@ void MSLGeneratorInterface::prepare_from_createinfo(const shader::ShaderCreateIn } BLI_assert(used_slot >= 0 && used_slot < MTL_MAX_TEXTURE_SLOTS); - /* Writeable image targets only assigned to Fragment shader. */ - MSLTextureSampler msl_tex( - ShaderStage::FRAGMENT, res.image.type, res.image.name, access, used_slot); + /* Writeable image targets only assigned to Fragment and compute shaders. */ + MSLTextureSampler msl_tex(ShaderStage::FRAGMENT | ShaderStage::COMPUTE, + res.image.type, + res.image.name, + access, + used_slot); texture_samplers.append(msl_tex); } break; @@ -1306,7 +1690,7 @@ void MSLGeneratorInterface::prepare_from_createinfo(const shader::ShaderCreateIn else { ubo.name = res.uniformbuf.name; } - ubo.stage = ShaderStage::VERTEX | ShaderStage::FRAGMENT; + ubo.stage = ShaderStage::ANY; uniform_blocks.append(ubo); } break; @@ -1381,7 +1765,10 @@ uint32_t MSLGeneratorInterface::num_samplers_for_stage(ShaderStage stage) const uint32_t MSLGeneratorInterface::get_sampler_argument_buffer_bind_index(ShaderStage stage) { - BLI_assert(stage == ShaderStage::VERTEX || stage == ShaderStage::FRAGMENT); + /* Note: Shader stage must be a singular index. Compound shader masks are not valid for this + * function. */ + BLI_assert(stage == ShaderStage::VERTEX || stage == ShaderStage::FRAGMENT || + stage == ShaderStage::COMPUTE); if (sampler_argument_buffer_bind_index[get_shader_stage_index(stage)] >= 0) { return sampler_argument_buffer_bind_index[get_shader_stage_index(stage)]; } @@ -1412,6 +1799,8 @@ void MSLGeneratorInterface::prepare_ssbo_vertex_fetch_uniforms() std::string MSLGeneratorInterface::generate_msl_vertex_entry_stub() { + static const char *shader_stage_inst_name = get_shader_stage_instance_name(ShaderStage::VERTEX); + std::stringstream out; out << std::endl << "/*** AUTO-GENERATED MSL VERETX SHADER STUB. ***/" << std::endl; @@ -1441,18 +1830,20 @@ std::string MSLGeneratorInterface::generate_msl_vertex_entry_stub() out << this->generate_msl_vertex_inputs_string(); out << ") {" << std::endl << std::endl; - out << "\tMTLShaderVertexImpl::VertexOut output;" << std::endl - << "\tMTLShaderVertexImpl vertex_shader_instance;" << std::endl; + out << "\t" << get_stage_class_name(ShaderStage::VERTEX) << "::VertexOut output;" << std::endl + << "\t" << get_stage_class_name(ShaderStage::VERTEX) << " " << shader_stage_inst_name << ";" + << std::endl; /* Copy Vertex Globals. */ if (this->uses_gl_VertexID) { - out << "vertex_shader_instance.gl_VertexID = gl_VertexID;" << std::endl; + out << shader_stage_inst_name << ".gl_VertexID = gl_VertexID;" << std::endl; } if (this->uses_gl_InstanceID) { - out << "vertex_shader_instance.gl_InstanceID = gl_InstanceID-gl_BaseInstanceARB;" << std::endl; + out << shader_stage_inst_name << ".gl_InstanceID = gl_InstanceID-gl_BaseInstanceARB;" + << std::endl; } if (this->uses_gl_BaseInstanceARB) { - out << "vertex_shader_instance.gl_BaseInstanceARB = gl_BaseInstanceARB;" << std::endl; + out << shader_stage_inst_name << ".gl_BaseInstanceARB = gl_BaseInstanceARB;" << std::endl; } /* Copy vertex attributes into local variables. */ @@ -1465,7 +1856,7 @@ std::string MSLGeneratorInterface::generate_msl_vertex_entry_stub() /* Execute original 'main' function within class scope. */ out << "\t/* Execute Vertex main function */\t" << std::endl - << "\tvertex_shader_instance.main();" << std::endl + << "\t" << shader_stage_inst_name << ".main();" << std::endl << std::endl; /* Populate Output values. */ @@ -1492,6 +1883,8 @@ std::string MSLGeneratorInterface::generate_msl_vertex_entry_stub() std::string MSLGeneratorInterface::generate_msl_fragment_entry_stub() { + static const char *shader_stage_inst_name = get_shader_stage_instance_name( + ShaderStage::FRAGMENT); std::stringstream out; out << std::endl << "/*** AUTO-GENERATED MSL FRAGMENT SHADER STUB. ***/" << std::endl; @@ -1515,15 +1908,17 @@ std::string MSLGeneratorInterface::generate_msl_fragment_entry_stub() #endif out << this->generate_msl_fragment_inputs_string(); out << ") {" << std::endl << std::endl; - out << "\tMTLShaderFragmentImpl::FragmentOut output;" << std::endl - << "\tMTLShaderFragmentImpl fragment_shader_instance;" << std::endl; + out << "\t" << get_stage_class_name(ShaderStage::FRAGMENT) << "::FragmentOut output;" + << std::endl + << "\t" << get_stage_class_name(ShaderStage::FRAGMENT) << " " << shader_stage_inst_name + << ";" << std::endl; /* Copy Fragment Globals. */ if (this->uses_gl_PointCoord) { - out << "fragment_shader_instance.gl_PointCoord = gl_PointCoord;" << std::endl; + out << shader_stage_inst_name << ".gl_PointCoord = gl_PointCoord;" << std::endl; } if (this->uses_gl_FrontFacing) { - out << "fragment_shader_instance.gl_FrontFacing = gl_FrontFacing;" << std::endl; + out << shader_stage_inst_name << ".gl_FrontFacing = gl_FrontFacing;" << std::endl; } if (this->uses_gl_PrimitiveID) { out << "fragment_shader_instance.gl_PrimitiveID = gl_PrimitiveID;" << std::endl; @@ -1536,11 +1931,11 @@ std::string MSLGeneratorInterface::generate_msl_fragment_entry_stub() if (this->uses_barycentrics) { /* Main barycentrics. */ - out << "fragment_shader_instance.gpu_BaryCoord = mtl_barycentric_coord.xyz;" << std::endl; + out << shader_stage_inst_name << ".gpu_BaryCoord = mtl_barycentric_coord.xyz;" << std::endl; /* barycentricDist represents the world-space distance from the current world-space position * to the opposite edge of the vertex. */ - out << "float3 worldPos = fragment_shader_instance.worldPosition.xyz;" << std::endl; + out << "float3 worldPos = " << shader_stage_inst_name << ".worldPosition.xyz;" << std::endl; out << "float3 wpChange = (length(dfdx(worldPos))+length(dfdy(worldPos)));" << std::endl; out << "float3 bcChange = " "(length(dfdx(mtl_barycentric_coord))+length(dfdy(mtl_barycentric_coord)));" @@ -1549,13 +1944,16 @@ std::string MSLGeneratorInterface::generate_msl_fragment_entry_stub() /* Distance to edge using inverse barycentric value, as rather than the length of 0.7 * contribution, we'd want the distance to the opposite side. */ - out << "fragment_shader_instance.gpu_BarycentricDist.x = length(rateOfChange * " + out << shader_stage_inst_name + << ".gpu_BarycentricDist.x = length(rateOfChange * " "(1.0-mtl_barycentric_coord.x));" << std::endl; - out << "fragment_shader_instance.gpu_BarycentricDist.y = length(rateOfChange * " + out << shader_stage_inst_name + << ".gpu_BarycentricDist.y = length(rateOfChange * " "(1.0-mtl_barycentric_coord.y));" << std::endl; - out << "fragment_shader_instance.gpu_BarycentricDist.z = length(rateOfChange * " + out << shader_stage_inst_name + << ".gpu_BarycentricDist.z = length(rateOfChange * " "(1.0-mtl_barycentric_coord.z));" << std::endl; } @@ -1567,7 +1965,7 @@ std::string MSLGeneratorInterface::generate_msl_fragment_entry_stub() /* Execute original 'main' function within class scope. */ out << "\t/* Execute Fragment main function */\t" << std::endl - << "\tfragment_shader_instance.main();" << std::endl + << "\t" << shader_stage_inst_name << ".main();" << std::endl << std::endl; /* Populate Output values. */ @@ -1577,11 +1975,98 @@ std::string MSLGeneratorInterface::generate_msl_fragment_entry_stub() return out.str(); } +std::string MSLGeneratorInterface::generate_msl_compute_entry_stub() +{ + static const char *shader_stage_inst_name = get_shader_stage_instance_name(ShaderStage::COMPUTE); + std::stringstream out; + out << std::endl << "/*** AUTO-GENERATED MSL COMPUTE SHADER STUB. ***/" << std::endl; + + /* Un-define texture defines from main source - avoid conflict with MSL texture. */ + out << "#undef texture" << std::endl; + out << "#undef textureLod" << std::endl; + + /* Disable special case for booleans being treated as ints in GLSL. */ + out << "#undef bool" << std::endl; + + /* Un-define uniform mappings to avoid name collisions. */ + out << generate_msl_uniform_undefs(ShaderStage::COMPUTE); + + /* Generate function entry point signature w/ resource bindings and inputs. */ + out << "kernel void "; +#ifndef NDEBUG + out << "compute_function_entry_" << parent_shader_.name_get() << "(\n\t"; +#else + out << "compute_function_entry(\n\t"; +#endif + + out << this->generate_msl_compute_inputs_string(); + out << ") {" << std::endl << std::endl; + /* Generate Compute shader instance constructor. If shared memory blocks are used, + * these must be declared and then passed into the constructor. */ + std::string stage_instance_constructor = ""; + bool first = true; + if (shared_memory_blocks.size() > 0) { + stage_instance_constructor += "("; + for (const MSLSharedMemoryBlock &block : shared_memory_blocks) { + if (block.is_array) { + out << "TG " << block.type_name << " " << block.varname << block.array_decl << ";"; + } + else { + out << "TG " << block.type_name << " " << block.varname << ";"; + } + stage_instance_constructor += ((!first) ? "," : "") + block.varname; + first = false; + + out << std::endl; + } + stage_instance_constructor += ")"; + } + out << "\t" << get_stage_class_name(ShaderStage::COMPUTE) << " " << shader_stage_inst_name + << stage_instance_constructor << ";" << std::endl; + + /* Copy global variables. */ + /* Entry point parameters for gl Globals. */ + if (this->uses_gl_GlobalInvocationID) { + out << shader_stage_inst_name << ".gl_GlobalInvocationID = gl_GlobalInvocationID;" + << std::endl; + } + if (this->uses_gl_WorkGroupID) { + out << shader_stage_inst_name << ".gl_WorkGroupID = gl_WorkGroupID;" << std::endl; + } + if (this->uses_gl_NumWorkGroups) { + out << shader_stage_inst_name << ".gl_NumWorkGroups = gl_NumWorkGroups;" << std::endl; + } + if (this->uses_gl_LocalInvocationIndex) { + out << shader_stage_inst_name << ".gl_LocalInvocationIndex = gl_LocalInvocationIndex;" + << std::endl; + } + if (this->uses_gl_LocalInvocationID) { + out << shader_stage_inst_name << ".gl_LocalInvocationID = gl_LocalInvocationID;" << std::endl; + } + + /* Populate Uniforms and uniform blocks. */ + out << this->generate_msl_texture_vars(ShaderStage::COMPUTE); + out << this->generate_msl_global_uniform_population(ShaderStage::COMPUTE); + out << this->generate_msl_uniform_block_population(ShaderStage::COMPUTE); + /* TODO(Metal): SSBO Population. */ + + /* Execute original 'main' function within class scope. */ + out << "\t/* Execute Compute main function */\t" << std::endl + << "\t" << shader_stage_inst_name << ".main();" << std::endl + << std::endl; + + out << "}"; + return out.str(); +} + void MSLGeneratorInterface::generate_msl_textures_input_string(std::stringstream &out, ShaderStage stage) { - BLI_assert(stage == ShaderStage::VERTEX || stage == ShaderStage::FRAGMENT); - /* Generate texture signatures. */ + /* Note: Shader stage must be specified as the singular stage index for which the input + * is generating. Compound stages are not valid inputs. */ + BLI_assert(stage == ShaderStage::VERTEX || stage == ShaderStage::FRAGMENT || + stage == ShaderStage::COMPUTE); + /* Generate texture signatures for textures used by this stage. */ BLI_assert(this->texture_samplers.size() <= GPU_max_textures_vert()); for (const MSLTextureSampler &tex : this->texture_samplers) { if (bool(tex.stage & stage)) { @@ -1714,6 +2199,37 @@ std::string MSLGeneratorInterface::generate_msl_fragment_inputs_string() return out.str(); } +std::string MSLGeneratorInterface::generate_msl_compute_inputs_string() +{ + std::stringstream out; + out << "constant " << get_stage_class_name(ShaderStage::COMPUTE) + << "::PushConstantBlock* uniforms[[buffer(MTL_uniform_buffer_base_index)]]"; + + this->generate_msl_uniforms_input_string(out, ShaderStage::COMPUTE); + + /* Generate texture signatures. */ + this->generate_msl_textures_input_string(out, ShaderStage::COMPUTE); + + /* Entry point parameters for gl Globals. */ + if (this->uses_gl_GlobalInvocationID) { + out << ",\n\tconst uint3 gl_GlobalInvocationID [[thread_position_in_grid]]"; + } + if (this->uses_gl_WorkGroupID) { + out << ",\n\tconst uint3 gl_WorkGroupID [[threadgroup_position_in_grid]]"; + } + if (this->uses_gl_NumWorkGroups) { + out << ",\n\tconst uint3 gl_NumWorkGroups [[threadgroups_per_grid]]"; + } + if (this->uses_gl_LocalInvocationIndex) { + out << ",\n\tconst uint gl_LocalInvocationIndex [[thread_index_in_threadgroup]]"; + } + if (this->uses_gl_LocalInvocationID) { + out << ",\n\tconst uint3 gl_LocalInvocationID [[thread_position_in_threadgroup]]"; + } + + return out.str(); +} + std::string MSLGeneratorInterface::generate_msl_uniform_structs(ShaderStage shader_stage) { BLI_assert(shader_stage == ShaderStage::VERTEX || shader_stage == ShaderStage::FRAGMENT); @@ -2029,8 +2545,7 @@ std::string MSLGeneratorInterface::generate_msl_global_uniform_population(Shader /* Copy UBO block ref. */ out << "\t/* Copy Uniform block member reference */" << std::endl; - out << "\t" - << ((stage == ShaderStage::VERTEX) ? "vertex_shader_instance." : "fragment_shader_instance.") + out << "\t" << get_shader_stage_instance_name(stage) << "." << "global_uniforms = uniforms;" << std::endl; return out.str(); @@ -2050,10 +2565,7 @@ std::string MSLGeneratorInterface::generate_msl_uniform_block_population(ShaderS * for the ubo to avoid name collision with the UBO accessor macro. * We only need to add this post-fix for the non-array access variant, * as the array is indexed directly, rather than requiring a dereference. */ - out << "\t" - << ((stage == ShaderStage::VERTEX) ? "vertex_shader_instance." : - "fragment_shader_instance.") - << ubo.name; + out << "\t" << get_shader_stage_instance_name(stage) << "." << ubo.name; if (!ubo.is_array) { out << "_local"; } @@ -2067,6 +2579,7 @@ std::string MSLGeneratorInterface::generate_msl_uniform_block_population(ShaderS /* Copy input attributes from stage_in into class local variables. */ std::string MSLGeneratorInterface::generate_msl_vertex_attribute_input_population() { + static const char *shader_stage_inst_name = get_shader_stage_instance_name(ShaderStage::VERTEX); /* SSBO Vertex Fetch mode does not require local attribute population, * we only need to pass over the buffer pointer references. */ @@ -2079,9 +2592,11 @@ std::string MSLGeneratorInterface::generate_msl_vertex_attribute_input_populatio out << "\t\tMTL_VERTEX_DATA_" << i << delimiter << std::endl; } out << "};" << std::endl; - out << "\tvertex_shader_instance.MTL_VERTEX_DATA = GLOBAL_MTL_VERTEX_DATA;" << std::endl; - out << "\tvertex_shader_instance.MTL_INDEX_DATA_U16 = MTL_INDEX_DATA;" << std::endl; - out << "\tvertex_shader_instance.MTL_INDEX_DATA_U32 = reinterpret_cast(MTL_INDEX_DATA);" << std::endl; return out.str(); @@ -2099,8 +2614,8 @@ std::string MSLGeneratorInterface::generate_msl_vertex_attribute_input_populatio * v_in.__internal_mat_attribute_type1, * v_in.__internal_mat_attribute_type2, * v_in.__internal_mat_attribute_type3). */ - out << "\tvertex_shader_instance." << this->vertex_input_attributes[attribute].name << " = " - << this->vertex_input_attributes[attribute].type << "(v_in.__internal_" + out << "\t" << shader_stage_inst_name << "." << this->vertex_input_attributes[attribute].name + << " = " << this->vertex_input_attributes[attribute].type << "(v_in.__internal_" << this->vertex_input_attributes[attribute].name << 0; for (int elem = 1; elem < get_matrix_location_count(this->vertex_input_attributes[attribute].type); @@ -2131,13 +2646,14 @@ std::string MSLGeneratorInterface::generate_msl_vertex_attribute_input_populatio if (do_attribute_conversion_on_read) { out << "\t" << attribute_conversion_func_name << "(MTL_AttributeConvert" << attribute - << ", v_in." << this->vertex_input_attributes[attribute].name - << ", vertex_shader_instance." << this->vertex_input_attributes[attribute].name << ");" - << std::endl; + << ", v_in." << this->vertex_input_attributes[attribute].name << ", " + << shader_stage_inst_name << "." << this->vertex_input_attributes[attribute].name + << ");" << std::endl; } else { - out << "\tvertex_shader_instance." << this->vertex_input_attributes[attribute].name - << " = v_in." << this->vertex_input_attributes[attribute].name << ";" << std::endl; + out << "\t" << shader_stage_inst_name << "." + << this->vertex_input_attributes[attribute].name << " = v_in." + << this->vertex_input_attributes[attribute].name << ";" << std::endl; } } } @@ -2148,13 +2664,14 @@ std::string MSLGeneratorInterface::generate_msl_vertex_attribute_input_populatio /* Copy post-main, modified, local class variables into vertex-output struct. */ std::string MSLGeneratorInterface::generate_msl_vertex_output_population() { - + static const char *shader_stage_inst_name = get_shader_stage_instance_name(ShaderStage::VERTEX); std::stringstream out; out << "\t/* Copy Vertex Outputs into output struct */" << std::endl; /* Output gl_Position with conversion to Metal coordinate-space. */ if (this->uses_gl_Position) { - out << "\toutput._default_position_ = vertex_shader_instance.gl_Position;" << std::endl; + out << "\toutput._default_position_ = " << shader_stage_inst_name << ".gl_Position;" + << std::endl; /* Invert Y and rescale depth range. * This is an alternative method to modifying all projection matrices. */ @@ -2166,14 +2683,14 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_population() /* Output Point-size. */ if (this->uses_gl_PointSize) { - out << "\toutput.pointsize = vertex_shader_instance.gl_PointSize;" << std::endl; + out << "\toutput.pointsize = " << shader_stage_inst_name << ".gl_PointSize;" << std::endl; } /* Output render target array Index. */ if (uses_mtl_array_index_) { out << "\toutput.MTLRenderTargetArrayIndex = " - "vertex_shader_instance.MTLRenderTargetArrayIndex;" - << std::endl; + "" + << shader_stage_inst_name << ".MTLRenderTargetArrayIndex;" << std::endl; } /* Output clip-distances. @@ -2186,12 +2703,13 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_population() for (int cd = 0; cd < this->clip_distances.size(); cd++) { /* Default value when clipping is disabled >= 0.0 to ensure primitive is not clipped. */ out << "\toutput.clipdistance[" << cd - << "] = (is_function_constant_defined(MTL_clip_distance_enabled" << cd - << "))?vertex_shader_instance.gl_ClipDistance_" << cd << ":1.0;" << std::endl; + << "] = (is_function_constant_defined(MTL_clip_distance_enabled" << cd << "))?" + << shader_stage_inst_name << ".gl_ClipDistance_" << cd << ":1.0;" << std::endl; } } else if (this->clip_distances.size() > 0) { - out << "\toutput.clipdistance = vertex_shader_instance.gl_ClipDistance_0;" << std::endl; + out << "\toutput.clipdistance = " << shader_stage_inst_name << ".gl_ClipDistance_0;" + << std::endl; } out << "}" << std::endl << "#endif" << std::endl; @@ -2201,8 +2719,8 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_population() if (v_out.is_array) { for (int i = 0; i < v_out.array_elems; i++) { - out << "\toutput." << v_out.instance_name << "_" << v_out.name << i - << " = vertex_shader_instance."; + out << "\toutput." << v_out.instance_name << "_" << v_out.name << i << " = " + << shader_stage_inst_name << "."; if (v_out.instance_name != "") { out << v_out.instance_name << "."; @@ -2216,8 +2734,8 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_population() /* Matrix types are split into vectors and need to be reconstructed. */ if (is_matrix_type(v_out.type)) { for (int elem = 0; elem < get_matrix_location_count(v_out.type); elem++) { - out << "\toutput." << v_out.instance_name << "__matrix_" << v_out.name << elem - << " = vertex_shader_instance."; + out << "\toutput." << v_out.instance_name << "__matrix_" << v_out.name << elem << " = " + << shader_stage_inst_name << "."; if (v_out.instance_name != "") { out << v_out.instance_name << "."; @@ -2231,8 +2749,8 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_population() * Ensure it is vec4. If transform feedback is enabled, we do not need position. */ if (!this->uses_gl_Position && output_id == 0 && !this->uses_transform_feedback) { - out << "\toutput." << v_out.instance_name << "_" << v_out.name - << " = to_vec4(vertex_shader_instance." << v_out.name << ");" << std::endl; + out << "\toutput." << v_out.instance_name << "_" << v_out.name << " = to_vec4(" + << shader_stage_inst_name << "." << v_out.name << ");" << std::endl; /* Invert Y */ out << "\toutput." << v_out.instance_name << "_" << v_out.name << ".y = -output." @@ -2241,8 +2759,8 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_population() else { /* Assign vertex output. */ - out << "\toutput." << v_out.instance_name << "_" << v_out.name - << " = vertex_shader_instance."; + out << "\toutput." << v_out.instance_name << "_" << v_out.name << " = " + << shader_stage_inst_name << "."; if (v_out.instance_name != "") { out << v_out.instance_name << "."; @@ -2261,7 +2779,7 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_population() /* Copy desired output varyings into transform feedback structure */ std::string MSLGeneratorInterface::generate_msl_vertex_output_tf_population() { - + static const char *shader_stage_inst_name = get_shader_stage_instance_name(ShaderStage::VERTEX); std::stringstream out; out << "\t/* Copy Vertex TF Outputs into transform feedback buffer */" << std::endl; @@ -2270,7 +2788,7 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_tf_population() * verify for other configurations if these occur in any cases. */ for (int v_output = 0; v_output < this->vertex_output_varyings_tf.size(); v_output++) { out << "transform_feedback_results[gl_VertexID]." - << this->vertex_output_varyings_tf[v_output].name << " = vertex_shader_instance." + << this->vertex_output_varyings_tf[v_output].name << " = " << shader_stage_inst_name << "." << this->vertex_output_varyings_tf[v_output].name << ";" << std::endl; } out << std::endl; @@ -2280,18 +2798,20 @@ std::string MSLGeneratorInterface::generate_msl_vertex_output_tf_population() /* Copy fragment stage inputs (Vertex Outputs) into local class variables. */ std::string MSLGeneratorInterface::generate_msl_fragment_input_population() { - + static const char *shader_stage_inst_name = get_shader_stage_instance_name( + ShaderStage::FRAGMENT); /* Populate local attribute variables. */ std::stringstream out; out << "\t/* Copy Fragment input into local variables. */" << std::endl; /* Special common case for gl_FragCoord, assigning to input position. */ if (this->uses_gl_Position) { - out << "\tfragment_shader_instance.gl_FragCoord = v_in._default_position_;" << std::endl; + out << "\t" << shader_stage_inst_name << ".gl_FragCoord = v_in._default_position_;" + << std::endl; } else { /* When gl_Position is not set, first VertexIn element is used for position. */ - out << "\tfragment_shader_instance.gl_FragCoord = v_in." + out << "\t" << shader_stage_inst_name << ".gl_FragCoord = v_in." << this->vertex_output_varyings[0].name << ";" << std::endl; } @@ -2323,7 +2843,7 @@ std::string MSLGeneratorInterface::generate_msl_fragment_input_population() } if (this->fragment_input_varyings[f_input].is_array) { for (int i = 0; i < this->fragment_input_varyings[f_input].array_elems; i++) { - out << "\tfragment_shader_instance."; + out << "\t" << shader_stage_inst_name << "."; if (this->fragment_input_varyings[f_input].instance_name != "") { out << this->fragment_input_varyings[f_input].instance_name << "."; @@ -2337,7 +2857,7 @@ std::string MSLGeneratorInterface::generate_msl_fragment_input_population() else { /* Matrix types are split into components and need to be regrouped into a matrix. */ if (is_matrix_type(this->fragment_input_varyings[f_input].type)) { - out << "\tfragment_shader_instance."; + out << "\t" << shader_stage_inst_name << "."; if (this->fragment_input_varyings[f_input].instance_name != "") { out << this->fragment_input_varyings[f_input].instance_name << "."; @@ -2355,7 +2875,7 @@ std::string MSLGeneratorInterface::generate_msl_fragment_input_population() out << ");" << std::endl; } else { - out << "\tfragment_shader_instance."; + out << "\t" << shader_stage_inst_name << "."; if (this->fragment_input_varyings[f_input].instance_name != "") { out << this->fragment_input_varyings[f_input].instance_name << "."; @@ -2374,21 +2894,22 @@ std::string MSLGeneratorInterface::generate_msl_fragment_input_population() /* Copy post-main, modified, local class variables into fragment-output struct. */ std::string MSLGeneratorInterface::generate_msl_fragment_output_population() { - + static const char *shader_stage_inst_name = get_shader_stage_instance_name( + ShaderStage::FRAGMENT); /* Populate output fragment variables. */ std::stringstream out; out << "\t/* Copy Fragment Outputs into output struct. */" << std::endl; /* Output gl_FragDepth. */ if (this->uses_gl_FragDepth) { - out << "\toutput.fragdepth = fragment_shader_instance.gl_FragDepth;" << std::endl; + out << "\toutput.fragdepth = " << shader_stage_inst_name << ".gl_FragDepth;" << std::endl; } /* Output attributes. */ for (int f_output = 0; f_output < this->fragment_outputs.size(); f_output++) { - out << "\toutput." << this->fragment_outputs[f_output].name << " = fragment_shader_instance." - << this->fragment_outputs[f_output].name << ";" << std::endl; + out << "\toutput." << this->fragment_outputs[f_output].name << " = " << shader_stage_inst_name + << "." << this->fragment_outputs[f_output].name << ";" << std::endl; } out << std::endl; return out.str(); @@ -2396,7 +2917,10 @@ std::string MSLGeneratorInterface::generate_msl_fragment_output_population() std::string MSLGeneratorInterface::generate_msl_texture_vars(ShaderStage shader_stage) { - BLI_assert(shader_stage == ShaderStage::VERTEX || shader_stage == ShaderStage::FRAGMENT); + /* NOTE: Shader stage must be a singualr stage index. Compound stage is not valid for this + * function. */ + BLI_assert(shader_stage == ShaderStage::VERTEX || shader_stage == ShaderStage::FRAGMENT || + shader_stage == ShaderStage::COMPUTE); std::stringstream out; out << "\t/* Populate local texture and sampler members */" << std::endl; @@ -2404,24 +2928,18 @@ std::string MSLGeneratorInterface::generate_msl_texture_vars(ShaderStage shader_ if (bool(this->texture_samplers[i].stage & shader_stage)) { /* Assign texture reference. */ - out << "\t" - << ((shader_stage == ShaderStage::VERTEX) ? "vertex_shader_instance." : - "fragment_shader_instance.") + out << "\t" << get_shader_stage_instance_name(shader_stage) << "." << this->texture_samplers[i].name << ".texture = &" << this->texture_samplers[i].name << ";" << std::endl; /* Assign sampler reference. */ if (this->use_argument_buffer_for_samplers()) { - out << "\t" - << ((shader_stage == ShaderStage::VERTEX) ? "vertex_shader_instance." : - "fragment_shader_instance.") + out << "\t" << get_shader_stage_instance_name(shader_stage) << "." << this->texture_samplers[i].name << ".samp = &samplers.sampler_args[" << this->texture_samplers[i].location << "];" << std::endl; } else { - out << "\t" - << ((shader_stage == ShaderStage::VERTEX) ? "vertex_shader_instance." : - "fragment_shader_instance.") + out << "\t" << get_shader_stage_instance_name(shader_stage) << "." << this->texture_samplers[i].name << ".samp = &" << this->texture_samplers[i].name << "_sampler;" << std::endl; } @@ -2659,7 +3177,8 @@ MTLShaderInterface *MSLGeneratorInterface::bake_shader_interface(const char *nam interface->set_sampler_properties( this->use_argument_buffer_for_samplers(), this->get_sampler_argument_buffer_bind_index(ShaderStage::VERTEX), - this->get_sampler_argument_buffer_bind_index(ShaderStage::FRAGMENT)); + this->get_sampler_argument_buffer_bind_index(ShaderStage::FRAGMENT), + this->get_sampler_argument_buffer_bind_index(ShaderStage::COMPUTE)); /* Map Metal bindings to standardized ShaderInput struct name/binding index. */ interface->prepare_common_shader_inputs(); diff --git a/source/blender/gpu/metal/mtl_shader_interface.hh b/source/blender/gpu/metal/mtl_shader_interface.hh index 4556d4d78c1..da9489685b8 100644 --- a/source/blender/gpu/metal/mtl_shader_interface.hh +++ b/source/blender/gpu/metal/mtl_shader_interface.hh @@ -65,12 +65,13 @@ namespace blender::gpu { * information to a specified buffer, and is unique to the shader's resource interface. */ -enum class ShaderStage : uint32_t { +enum class ShaderStage : uint8_t { VERTEX = 1 << 0, FRAGMENT = 1 << 1, - BOTH = (ShaderStage::VERTEX | ShaderStage::FRAGMENT), + COMPUTE = 2 << 1, + ANY = (ShaderStage::VERTEX | ShaderStage::FRAGMENT | ShaderStage::COMPUTE), }; -ENUM_OPERATORS(ShaderStage, ShaderStage::BOTH); +ENUM_OPERATORS(ShaderStage, ShaderStage::ANY); inline uint get_shader_stage_index(ShaderStage stage) { @@ -79,6 +80,8 @@ inline uint get_shader_stage_index(ShaderStage stage) return 0; case ShaderStage::FRAGMENT: return 1; + case ShaderStage::COMPUTE: + return 2; default: BLI_assert_unreachable(); return 0; @@ -182,8 +185,7 @@ class MTLShaderInterface : public ShaderInterface { /* Whether argument buffers are used for sampler bindings. */ bool sampler_use_argument_buffer_; - int sampler_argument_buffer_bind_index_vert_; - int sampler_argument_buffer_bind_index_frag_; + int sampler_argument_buffer_bind_index_[3]; /* Attribute Mask. */ uint32_t enabled_attribute_mask_; @@ -206,7 +208,7 @@ class MTLShaderInterface : public ShaderInterface { uint32_t add_uniform_block(uint32_t name_offset, uint32_t buffer_index, uint32_t size, - ShaderStage stage_mask = ShaderStage::BOTH); + ShaderStage stage_mask = ShaderStage::ANY); void add_uniform(uint32_t name_offset, eMTLDataType type, int array_len = 1); void add_texture(uint32_t name_offset, uint32_t texture_slot, @@ -219,7 +221,8 @@ class MTLShaderInterface : public ShaderInterface { void map_builtins(); void set_sampler_properties(bool use_argument_buffer, uint32_t argument_buffer_bind_index_vert, - uint32_t argument_buffer_bind_index_frag); + uint32_t argument_buffer_bind_index_frag, + uint32_t argument_buffer_bind_index_compute); /* Prepare #ShaderInput interface for binding resolution. */ void prepare_common_shader_inputs(); @@ -242,8 +245,8 @@ class MTLShaderInterface : public ShaderInterface { const MTLShaderTexture &get_texture(uint index) const; uint32_t get_total_textures() const; uint32_t get_max_texture_index() const; - bool get_use_argument_buffer_for_samplers(int *vertex_arg_buffer_bind_index, - int *fragment_arg_buffer_bind_index) const; + bool uses_argument_buffer_for_samplers() const; + int get_argument_buffer_bind_index(ShaderStage stage) const; /* Fetch Attributes. */ const MTLShaderInputAttribute &get_attribute(uint index) const; diff --git a/source/blender/gpu/metal/mtl_shader_interface.mm b/source/blender/gpu/metal/mtl_shader_interface.mm index 126279a39a8..5a66e541f3b 100644 --- a/source/blender/gpu/metal/mtl_shader_interface.mm +++ b/source/blender/gpu/metal/mtl_shader_interface.mm @@ -62,8 +62,9 @@ void MTLShaderInterface::init() enabled_attribute_mask_ = 0; total_vert_stride_ = 0; sampler_use_argument_buffer_ = false; - sampler_argument_buffer_bind_index_vert_ = -1; - sampler_argument_buffer_bind_index_frag_ = -1; + for (int i = 0; i < ARRAY_SIZE(sampler_argument_buffer_bind_index_); i++) { + sampler_argument_buffer_bind_index_[i] = -1; + } /* NULL initialize uniform location markers for builtins. */ for (const int u : IndexRange(GPU_NUM_UNIFORMS)) { @@ -121,7 +122,7 @@ uint32_t MTLShaderInterface::add_uniform_block(uint32_t name_offset, uni_block.buffer_index = buffer_index; uni_block.size = size; uni_block.current_offset = 0; - uni_block.stage_mask = ShaderStage::BOTH; + uni_block.stage_mask = ShaderStage::ANY; max_uniformbuf_index_ = max_ii(max_uniformbuf_index_, buffer_index); return (total_uniform_blocks_++); } @@ -135,7 +136,7 @@ void MTLShaderInterface::add_push_constant_block(uint32_t name_offset) push_constant_block_.size = 0; push_constant_block_.current_offset = 0; - push_constant_block_.stage_mask = ShaderStage::BOTH; + push_constant_block_.stage_mask = ShaderStage::ANY; } void MTLShaderInterface::add_uniform(uint32_t name_offset, eMTLDataType type, int array_len) @@ -367,11 +368,16 @@ void MTLShaderInterface::prepare_common_shader_inputs() void MTLShaderInterface::set_sampler_properties(bool use_argument_buffer, uint32_t argument_buffer_bind_index_vert, - uint32_t argument_buffer_bind_index_frag) + uint32_t argument_buffer_bind_index_frag, + uint32_t argument_buffer_bind_index_compute) { sampler_use_argument_buffer_ = use_argument_buffer; - sampler_argument_buffer_bind_index_vert_ = argument_buffer_bind_index_vert; - sampler_argument_buffer_bind_index_frag_ = argument_buffer_bind_index_frag; + sampler_argument_buffer_bind_index_[get_shader_stage_index(ShaderStage::VERTEX)] = + argument_buffer_bind_index_vert; + sampler_argument_buffer_bind_index_[get_shader_stage_index(ShaderStage::FRAGMENT)] = + argument_buffer_bind_index_frag; + sampler_argument_buffer_bind_index_[get_shader_stage_index(ShaderStage::COMPUTE)] = + argument_buffer_bind_index_compute; } /* Attributes. */ @@ -461,16 +467,16 @@ uint32_t MTLShaderInterface::get_max_texture_index() const return max_texture_index_; } -bool MTLShaderInterface::get_use_argument_buffer_for_samplers( - int *vertex_arg_buffer_bind_index, int *fragment_arg_buffer_bind_index) const +bool MTLShaderInterface::uses_argument_buffer_for_samplers() const { - /* Returns argument buffer binding slot for each shader stage. - * The exact bind slot may be different, as each stage has different buffer inputs. */ - *vertex_arg_buffer_bind_index = sampler_argument_buffer_bind_index_vert_; - *fragment_arg_buffer_bind_index = sampler_argument_buffer_bind_index_frag_; return sampler_use_argument_buffer_; } +int MTLShaderInterface::get_argument_buffer_bind_index(ShaderStage stage) const +{ + return sampler_argument_buffer_bind_index_[get_shader_stage_index(stage)]; +} + id MTLShaderInterface::find_argument_encoder(int buffer_index) const { id encoder = nil; diff --git a/source/blender/gpu/metal/mtl_state.mm b/source/blender/gpu/metal/mtl_state.mm index 95b7e5edc7a..7b23378130b 100644 --- a/source/blender/gpu/metal/mtl_state.mm +++ b/source/blender/gpu/metal/mtl_state.mm @@ -575,14 +575,6 @@ void MTLStateManager::issue_barrier(eGPUBarrier barrier_bits) MTLContext *ctx = reinterpret_cast(GPU_context_active_get()); BLI_assert(ctx); - /* Apple Silicon does not support memory barriers. - * We do not currently need these due to implicit API guarantees. - * NOTE(Metal): MTLFence/MTLEvent may be required to synchronize work if - * untracked resources are ever used. */ - if ([ctx->device hasUnifiedMemory]) { - return; - } - ctx->main_command_buffer.insert_memory_barrier(barrier_bits, before_stages, after_stages); } diff --git a/source/blender/gpu/metal/mtl_texture.mm b/source/blender/gpu/metal/mtl_texture.mm index 043033e6b0e..55e25f5be50 100644 --- a/source/blender/gpu/metal/mtl_texture.mm +++ b/source/blender/gpu/metal/mtl_texture.mm @@ -722,10 +722,13 @@ void gpu::MTLTexture::update_sub( ((ctx->pipeline_state.unpack_row_length == 0) ? extent[0] : ctx->pipeline_state.unpack_row_length)}; - [compute_encoder setComputePipelineState:pso]; - [compute_encoder setBytes:¶ms length:sizeof(params) atIndex:0]; - [compute_encoder setBuffer:staging_buffer offset:staging_buffer_offset atIndex:1]; - [compute_encoder setTexture:texture_handle atIndex:0]; + + /* Bind resources via compute state for optimal state caching performance. */ + MTLComputeState &cs = ctx->main_command_buffer.get_compute_state(); + cs.bind_pso(pso); + cs.bind_compute_bytes(¶ms, sizeof(params), 0); + cs.bind_compute_buffer(staging_buffer, staging_buffer_offset, 1); + cs.bind_compute_texture(texture_handle, 0); [compute_encoder dispatchThreads:MTLSizeMake(extent[0], 1, 1) /* Width, Height, Layer */ threadsPerThreadgroup:MTLSizeMake(64, 1, 1)]; @@ -739,10 +742,13 @@ void gpu::MTLTexture::update_sub( ((ctx->pipeline_state.unpack_row_length == 0) ? extent[0] : ctx->pipeline_state.unpack_row_length)}; - [compute_encoder setComputePipelineState:pso]; - [compute_encoder setBytes:¶ms length:sizeof(params) atIndex:0]; - [compute_encoder setBuffer:staging_buffer offset:staging_buffer_offset atIndex:1]; - [compute_encoder setTexture:texture_handle atIndex:0]; + + /* Bind resources via compute state for optimal state caching performance. */ + MTLComputeState &cs = ctx->main_command_buffer.get_compute_state(); + cs.bind_pso(pso); + cs.bind_compute_bytes(¶ms, sizeof(params), 0); + cs.bind_compute_buffer(staging_buffer, staging_buffer_offset, 1); + cs.bind_compute_texture(texture_handle, 0); [compute_encoder dispatchThreads:MTLSizeMake(extent[0], extent[1], 1) /* Width, layers, nil */ threadsPerThreadgroup:MTLSizeMake(8, 8, 1)]; @@ -796,10 +802,13 @@ void gpu::MTLTexture::update_sub( ((ctx->pipeline_state.unpack_row_length == 0) ? extent[0] : ctx->pipeline_state.unpack_row_length)}; - [compute_encoder setComputePipelineState:pso]; - [compute_encoder setBytes:¶ms length:sizeof(params) atIndex:0]; - [compute_encoder setBuffer:staging_buffer offset:staging_buffer_offset atIndex:1]; - [compute_encoder setTexture:texture_handle atIndex:0]; + + /* Bind resources via compute state for optimal state caching performance. */ + MTLComputeState &cs = ctx->main_command_buffer.get_compute_state(); + cs.bind_pso(pso); + cs.bind_compute_bytes(¶ms, sizeof(params), 0); + cs.bind_compute_buffer(staging_buffer, staging_buffer_offset, 1); + cs.bind_compute_texture(texture_handle, 0); [compute_encoder dispatchThreads:MTLSizeMake( extent[0], extent[1], 1) /* Width, Height, Layer */ @@ -814,10 +823,13 @@ void gpu::MTLTexture::update_sub( ((ctx->pipeline_state.unpack_row_length == 0) ? extent[0] : ctx->pipeline_state.unpack_row_length)}; - [compute_encoder setComputePipelineState:pso]; - [compute_encoder setBytes:¶ms length:sizeof(params) atIndex:0]; - [compute_encoder setBuffer:staging_buffer offset:staging_buffer_offset atIndex:1]; - [compute_encoder setTexture:texture_handle atIndex:0]; + + /* Bind resources via compute state for optimal state caching performance. */ + MTLComputeState &cs = ctx->main_command_buffer.get_compute_state(); + cs.bind_pso(pso); + cs.bind_compute_bytes(¶ms, sizeof(params), 0); + cs.bind_compute_buffer(staging_buffer, staging_buffer_offset, 1); + cs.bind_compute_texture(texture_handle, 0); [compute_encoder dispatchThreads:MTLSizeMake(extent[0], extent[1], extent[2]) /* Width, Height, Layer */ @@ -854,10 +866,13 @@ void gpu::MTLTexture::update_sub( ((ctx->pipeline_state.unpack_row_length == 0) ? extent[0] : ctx->pipeline_state.unpack_row_length)}; - [compute_encoder setComputePipelineState:pso]; - [compute_encoder setBytes:¶ms length:sizeof(params) atIndex:0]; - [compute_encoder setBuffer:staging_buffer offset:staging_buffer_offset atIndex:1]; - [compute_encoder setTexture:texture_handle atIndex:0]; + + /* Bind resources via compute state for optimal state caching performance. */ + MTLComputeState &cs = ctx->main_command_buffer.get_compute_state(); + cs.bind_pso(pso); + cs.bind_compute_bytes(¶ms, sizeof(params), 0); + cs.bind_compute_buffer(staging_buffer, staging_buffer_offset, 1); + cs.bind_compute_texture(texture_handle, 0); [compute_encoder dispatchThreads:MTLSizeMake( extent[0], extent[1], extent[2]) /* Width, Height, Depth */ @@ -1521,10 +1536,13 @@ void gpu::MTLTexture::read_internal(int mip, {width, height, 1}, {x_off, y_off, 0}, }; - [compute_encoder setComputePipelineState:pso]; - [compute_encoder setBytes:¶ms length:sizeof(params) atIndex:0]; - [compute_encoder setBuffer:destination_buffer offset:0 atIndex:1]; - [compute_encoder setTexture:read_texture atIndex:0]; + + /* Bind resources via compute state for optimal state caching performance. */ + MTLComputeState &cs = ctx->main_command_buffer.get_compute_state(); + cs.bind_pso(pso); + cs.bind_compute_bytes(¶ms, sizeof(params), 0); + cs.bind_compute_buffer(destination_buffer, 0, 1); + cs.bind_compute_texture(read_texture, 0); [compute_encoder dispatchThreads:MTLSizeMake(width, height, 1) /* Width, Height, Layer */ threadsPerThreadgroup:MTLSizeMake(8, 8, 1)]; copy_successful = true; @@ -1568,10 +1586,13 @@ void gpu::MTLTexture::read_internal(int mip, {width, height, depth}, {x_off, y_off, z_off}, }; - [compute_encoder setComputePipelineState:pso]; - [compute_encoder setBytes:¶ms length:sizeof(params) atIndex:0]; - [compute_encoder setBuffer:destination_buffer offset:0 atIndex:1]; - [compute_encoder setTexture:read_texture atIndex:0]; + + /* Bind resources via compute state for optimal state caching performance. */ + MTLComputeState &cs = ctx->main_command_buffer.get_compute_state(); + cs.bind_pso(pso); + cs.bind_compute_bytes(¶ms, sizeof(params), 0); + cs.bind_compute_buffer(destination_buffer, 0, 1); + cs.bind_compute_texture(read_texture, 0); [compute_encoder dispatchThreads:MTLSizeMake(width, height, depth) /* Width, Height, Layer */ threadsPerThreadgroup:MTLSizeMake(8, 8, 1)]; diff --git a/source/blender/gpu/shaders/metal/mtl_shader_common.msl b/source/blender/gpu/shaders/metal/mtl_shader_common.msl index 9ed320335c7..75d97c89f2c 100644 --- a/source/blender/gpu/shaders/metal/mtl_shader_common.msl +++ b/source/blender/gpu/shaders/metal/mtl_shader_common.msl @@ -58,6 +58,9 @@ constant int MTL_clip_distance_enabled3 [[function_constant(23)]]; constant int MTL_clip_distance_enabled4 [[function_constant(24)]]; constant int MTL_clip_distance_enabled5 [[function_constant(25)]]; +/* Compute and SSBOs. */ +constant int MTL_storage_buffer_base_index [[function_constant(26)]]; + /** Internal attribute conversion functionality. */ /* Following descriptions in mtl_shader.hh, Metal only supports some implicit * attribute type conversions. These conversions occur when there is a difference diff --git a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl index 69202a7a70e..f644f5a3722 100644 --- a/source/blender/gpu/shaders/metal/mtl_shader_defines.msl +++ b/source/blender/gpu/shaders/metal/mtl_shader_defines.msl @@ -59,9 +59,122 @@ using uvec4 = uint4; # define uniform #endif +/* Compute decorators. */ +#define TG threadgroup +#define barrier() threadgroup_barrier(mem_flags::mem_threadgroup) + +#ifdef MTL_USE_WORKGROUP_SIZE +/* Compute workgroup size. */ +struct constexp_uvec3 { + /* Type union to cover all syntax accessors: + * .x, .y, .z, .xy, .xyz + * Swizzle types invalid.*/ + union { + struct { + uint x, y, z; + }; + struct { + uint2 xy; + }; + uint3 xyz; + }; + + constexpr constexp_uvec3(uint _x, uint _y, uint _z) : x(_x), y(_y), z(_z) + { + } + constexpr uint operator[](int i) + { + /* Note: Need to switch on each elem value as array accessor triggers + * non-constant sizing error. This will be statically evaluated at compile time. */ + switch (i) { + case 0: + return x; + case 1: + return y; + case 2: + return z; + default: + return 0; + } + } + inline operator uint3() const + { + return xyz; + } +}; + +constexpr constexp_uvec3 __internal_workgroupsize_get() +{ + return constexp_uvec3(MTL_WORKGROUP_SIZE_X, MTL_WORKGROUP_SIZE_Y, MTL_WORKGROUP_SIZE_Z); +} + +# define gl_WorkGroupSize __internal_workgroupsize_get() +#endif + +/** Shader atomics: + * In order to emulate GLSL-style atomic operations, wherein variables can be used within atomic + * operations, even if they are not explicitly declared atomic, we can cast the pointer to atomic, + * to ensure that the load instruction follows atomic_load/store idioms. + * + * NOTE: We cannot hoist the address space into the template declaration, so these must be declared + * for each relevant address space. */ + +/* Threadgroup memory. */ +template T atomicMax(threadgroup T &mem, T data) +{ + return atomic_fetch_max_explicit((threadgroup _atomic *)&mem, data, memory_order_relaxed); +} +template T atomicMin(threadgroup T &mem, T data) +{ + return atomic_fetch_min_explicit((threadgroup _atomic *)&mem, data, memory_order_relaxed); +} +template T atomicAdd(threadgroup T &mem, T data) +{ + return atomic_fetch_add_explicit((threadgroup _atomic *)&mem, data, memory_order_relaxed); +} +template T atomicSub(threadgroup T &mem, T data) +{ + return atomic_fetch_sub_explicit((threadgroup _atomic *)&mem, data, memory_order_relaxed); +} +template T atomicOr(threadgroup T &mem, T data) +{ + return atomic_fetch_or_explicit((threadgroup _atomic *)&mem, data, memory_order_relaxed); +} +template T atomicXor(threadgroup T &mem, T data) +{ + return atomic_fetch_xor_explicit((threadgroup _atomic *)&mem, data, memory_order_relaxed); +} + +/* Device memory. */ +template T atomicMax(device T &mem, T data) +{ + return atomic_fetch_max_explicit((threadgroup _atomic *)&mem, data, memory_order_relaxed); +} +template T atomicMin(device T &mem, T data) +{ + return atomic_fetch_min_explicit((threadgroup _atomic *)&mem, data, memory_order_relaxed); +} +template T atomicAdd(device T &mem, T data) +{ + return atomic_fetch_add_explicit((threadgroup _atomic *)&mem, data, memory_order_relaxed); +} +template T atomicSub(device T &mem, T data) +{ + return atomic_fetch_sub_explicit((threadgroup _atomic *)&mem, data, memory_order_relaxed); +} +template T atomicOr(device T &mem, T data) +{ + return atomic_fetch_or_explicit((threadgroup _atomic *)&mem, data, memory_order_relaxed); +} +template T atomicXor(device T &mem, T data) +{ + return atomic_fetch_xor_explicit((threadgroup _atomic *)&mem, data, memory_order_relaxed); +} + /* Used to replace 'out' in function parameters with threadlocal reference * shortened to avoid expanding the glsl source string. */ #define THD thread +#define OUT(type, name, array) thread type(&name)[array] /* Generate wrapper structs for combined texture and sampler type. */ #ifdef USE_ARGUMENT_BUFFER_FOR_SAMPLERS diff --git a/source/blender/nodes/composite/nodes/node_composite_filter.cc b/source/blender/nodes/composite/nodes/node_composite_filter.cc index 816d1009ffe..3a2413d5554 100644 --- a/source/blender/nodes/composite/nodes/node_composite_filter.cc +++ b/source/blender/nodes/composite/nodes/node_composite_filter.cc @@ -49,7 +49,7 @@ class FilterOperation : public NodeOperation { GPUShader *shader = shader_manager().get(get_shader_name()); GPU_shader_bind(shader); - GPU_shader_uniform_mat3_as_mat4(shader, "kernel", get_filter_kernel().ptr()); + GPU_shader_uniform_mat3_as_mat4(shader, "ukernel", get_filter_kernel().ptr()); const Result &input_image = get_input("Image"); input_image.bind_as_texture(shader, "input_tx"); From 6dde185dc470498d3eb2676a96728b5aef5e60ed Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Mon, 30 Jan 2023 11:25:53 +0100 Subject: [PATCH 1023/1522] Metal: Fix edge-case with point primitive restart index removal where all indices are restarts. Metal backend does not support primtiive restart for point primtiives. Hence strip_restart_indices removes restart indices by swapping them to the end of the index buffer and reducing the length. An edge-case existed where all indices within the index buffer were restarts and no valid swap-index would be found, resulting in a buffer underflow. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D17088 --- source/blender/gpu/metal/mtl_index_buffer.mm | 38 +++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/source/blender/gpu/metal/mtl_index_buffer.mm b/source/blender/gpu/metal/mtl_index_buffer.mm index c32f9299d02..cf921e43a4b 100644 --- a/source/blender/gpu/metal/mtl_index_buffer.mm +++ b/source/blender/gpu/metal/mtl_index_buffer.mm @@ -475,7 +475,7 @@ void MTLIndexBuf::strip_restart_indices() /* Find swap index at end of index buffer. */ int swap_index = -1; - for (uint j = index_len_ - 1; j >= i; j--) { + for (uint j = index_len_ - 1; j >= i && index_len_ > 0; j--) { /* If end index is restart, just reduce length. */ if (uint_idx[j] == 0xFFFFFFFFu) { index_len_--; @@ -486,22 +486,26 @@ void MTLIndexBuf::strip_restart_indices() break; } - /* If swap index is not valid, then there were no valid non-restart indices - * to swap with. However, the above loop will have removed these indices by - * reducing the length of indices. Debug assertions verify that the restart - * index is no longer included. */ - if (swap_index == -1) { - BLI_assert(index_len_ <= i); - } - else { - /* If we have found an index we can swap with, flip the values. - * We also reduce the length. As per above loop, swap_index should - * now be outside the index length range. */ - uint32_t swap_index_value = uint_idx[swap_index]; - uint_idx[i] = swap_index_value; - uint_idx[swap_index] = 0xFFFFFFFFu; - index_len_--; - BLI_assert(index_len_ <= swap_index); + /* If index_len_ == 0, this means all indices were flagged as hidden, with restart index + * values. Hence we will entirely skip the draw. */ + if (index_len_ > 0) { + /* If swap index is not valid, then there were no valid non-restart indices + * to swap with. However, the above loop will have removed these indices by + * reducing the length of indices. Debug assertions verify that the restart + * index is no longer included. */ + if (swap_index == -1) { + BLI_assert(index_len_ <= i); + } + else { + /* If we have found an index we can swap with, flip the values. + * We also reduce the length. As per above loop, swap_index should + * now be outside the index length range. */ + uint32_t swap_index_value = uint_idx[swap_index]; + uint_idx[i] = swap_index_value; + uint_idx[swap_index] = 0xFFFFFFFFu; + index_len_--; + BLI_assert(index_len_ <= swap_index); + } } } } From 084dd110c97b51c0203400321e6a4d19fd2fea92 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 30 Jan 2023 11:19:06 +0100 Subject: [PATCH 1024/1522] Build: Remove unused `BLENDER_GL_LIBRARIES`. This CMAKE variable isn't used. --- CMakeLists.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a631b3e6a60..1445b0a87e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1241,13 +1241,6 @@ if(WITH_OPENGL) add_definitions(-DWITH_OPENGL) endif() -#----------------------------------------------------------------------------- -# Configure Vulkan. - -if(WITH_VULKAN_BACKEND) - list(APPEND BLENDER_GL_LIBRARIES ${VULKAN_LIBRARIES}) -endif() - # ----------------------------------------------------------------------------- # Configure Metal From a36c1cabce6e3f13f3e46d7064f191aa4a2a731c Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 30 Jan 2023 11:24:06 +0100 Subject: [PATCH 1025/1522] Vulkan: Changes to CMake config. Paths to vulkan libraries, paths and related components were hardcoded in the platform cmake file. This patch separates this by using adding CMake modules for Vulkan and ShaderC. This change has only been applied to the macOs configuration as that is currently our main platform for development. Other platforms will be added during the development of the Vulkan back-end. --- build_files/cmake/Modules/FindShaderC.cmake | 63 +++++++++++++++++++ build_files/cmake/Modules/FindVulkan.cmake | 63 +++++++++++++++++++ .../cmake/platform/platform_apple.cmake | 18 +----- extern/vulkan_memory_allocator/CMakeLists.txt | 1 + intern/ghost/CMakeLists.txt | 2 + source/blender/gpu/CMakeLists.txt | 4 ++ source/creator/CMakeLists.txt | 7 +++ 7 files changed, 142 insertions(+), 16 deletions(-) create mode 100644 build_files/cmake/Modules/FindShaderC.cmake create mode 100644 build_files/cmake/Modules/FindVulkan.cmake diff --git a/build_files/cmake/Modules/FindShaderC.cmake b/build_files/cmake/Modules/FindShaderC.cmake new file mode 100644 index 00000000000..e38ca137775 --- /dev/null +++ b/build_files/cmake/Modules/FindShaderC.cmake @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2023 Blender Foundation. + +# - Find ShaderC libraries +# Find the ShaderC includes and libraries +# This module defines +# SHADERC_INCLUDE_DIRS, where to find MoltenVK headers, Set when +# SHADERC_INCLUDE_DIR is found. +# SHADERC_LIBRARIES, libraries to link against to use ShaderC. +# SHADERC_ROOT_DIR, The base directory to search for ShaderC. +# This can also be an environment variable. +# SHADERC_FOUND, If false, do not try to use ShaderC. +# + +# If SHADERC_ROOT_DIR was defined in the environment, use it. +IF(NOT SHADERC_ROOT_DIR AND NOT $ENV{SHADERC_ROOT_DIR} STREQUAL "") + SET(SHADERC_ROOT_DIR $ENV{SHADERC_ROOT_DIR}) +ENDIF() + +SET(_shaderc_SEARCH_DIRS + ${SHADERC_ROOT_DIR} +) + +# FIXME: These finder modules typically don't use LIBDIR, +# this should be set by `./build_files/cmake/platform/` instead. +IF(DEFINED LIBDIR) + SET(_shaderc_SEARCH_DIRS ${_shaderc_SEARCH_DIRS} ${LIBDIR}/shaderc) +ENDIF() + +FIND_PATH(SHADERC_INCLUDE_DIR + NAMES + shaderc/shaderc.h + HINTS + ${_shaderc_SEARCH_DIRS} + PATH_SUFFIXES + include +) + +FIND_LIBRARY(SHADERC_LIBRARY + NAMES + shaderc_combined + HINTS + ${_shaderc_SEARCH_DIRS} + PATH_SUFFIXES + lib +) + +# handle the QUIETLY and REQUIRED arguments and set SHADERC_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ShaderC DEFAULT_MSG SHADERC_LIBRARY SHADERC_INCLUDE_DIR) + +IF(SHADERC_FOUND) + SET(SHADERC_LIBRARIES ${SHADERC_LIBRARY}) + SET(SHADERC_INCLUDE_DIRS ${SHADERC_INCLUDE_DIR}) +ENDIF() + +MARK_AS_ADVANCED( + SHADERC_INCLUDE_DIR + SHADERC_LIBRARY +) + +UNSET(_shaderc_SEARCH_DIRS) diff --git a/build_files/cmake/Modules/FindVulkan.cmake b/build_files/cmake/Modules/FindVulkan.cmake new file mode 100644 index 00000000000..37da42543db --- /dev/null +++ b/build_files/cmake/Modules/FindVulkan.cmake @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright 2023 Blender Foundation. + +# - Find Vulkan libraries +# Find the Vulkan includes and libraries +# This module defines +# VULKAN_INCLUDE_DIRS, where to find Vulkan headers, Set when +# VULKAN_INCLUDE_DIR is found. +# VULKAN_LIBRARIES, libraries to link against to use Vulkan. +# VULKAN_ROOT_DIR, The base directory to search for Vulkan. +# This can also be an environment variable. +# VULKAN_FOUND, If false, do not try to use Vulkan. +# + +# If VULKAN_ROOT_DIR was defined in the environment, use it. +IF(NOT VULKAN_ROOT_DIR AND NOT $ENV{VULKAN_ROOT_DIR} STREQUAL "") + SET(VULKAN_ROOT_DIR $ENV{VULKAN_ROOT_DIR}) +ENDIF() + +SET(_vulkan_SEARCH_DIRS + ${VULKAN_ROOT_DIR} +) + +# FIXME: These finder modules typically don't use LIBDIR, +# this should be set by `./build_files/cmake/platform/` instead. +IF(DEFINED LIBDIR) + SET(_vulkan_SEARCH_DIRS ${_vulkan_SEARCH_DIRS} ${LIBDIR}/vulkan) +ENDIF() + +FIND_PATH(VULKAN_INCLUDE_DIR + NAMES + vulkan/vulkan.h + HINTS + ${_vulkan_SEARCH_DIRS} + PATH_SUFFIXES + include +) + +FIND_LIBRARY(VULKAN_LIBRARY + NAMES + vulkan + HINTS + ${_vulkan_SEARCH_DIRS} + PATH_SUFFIXES + lib +) + +# handle the QUIETLY and REQUIRED arguments and set VULKAN_FOUND to TRUE if +# all listed variables are TRUE +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Vulkan DEFAULT_MSG VULKAN_LIBRARY VULKAN_INCLUDE_DIR) + +IF(VULKAN_FOUND) + SET(VULKAN_LIBRARIES ${VULKAN_LIBRARY}) + SET(VULKAN_INCLUDE_DIRS ${VULKAN_INCLUDE_DIR}) +ENDIF() + +MARK_AS_ADVANCED( + VULKAN_INCLUDE_DIR + VULKAN_LIBRARY +) + +UNSET(_vulkan_SEARCH_DIRS) diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake index 09f9d79a6cf..0b7ae0532d8 100644 --- a/build_files/cmake/platform/platform_apple.cmake +++ b/build_files/cmake/platform/platform_apple.cmake @@ -97,22 +97,8 @@ add_bundled_libraries(materialx/lib) if(WITH_VULKAN_BACKEND) find_package(MoltenVK REQUIRED) - - if(EXISTS ${LIBDIR}/vulkan) - set(VULKAN_FOUND On) - set(VULKAN_ROOT_DIR ${LIBDIR}/vulkan) - set(VULKAN_INCLUDE_DIR ${VULKAN_ROOT_DIR}/include) - set(VULKAN_LIBRARY ${VULKAN_ROOT_DIR}/lib/libvulkan.dylib) - set(SHADERC_ROOT_DIR ${LIBDIR}/shaderc) - set(SHADERC_INCLUDE_DIR ${SHADERC_ROOT_DIR}/include) - set(SHADERC_LIBRARY ${SHADERC_ROOT_DIR}/lib/libshaderc_combined.a) - - set(VULKAN_INCLUDE_DIRS ${VULKAN_INCLUDE_DIR} ${SHADERC_INCLUDE_DIR} ${MOLTENVK_INCLUDE_DIRS}) - set(VULKAN_LIBRARIES ${VULKAN_LIBRARY} ${SHADERC_LIBRARY} ${MOLTENVK_LIBRARIES}) - else() - message(WARNING "Vulkan SDK was not found, disabling WITH_VULKAN_BACKEND") - set(WITH_VULKAN_BACKEND OFF) - endif() + find_package(ShaderC REQUIRED) + find_package(Vulkan REQUIRED) endif() if(WITH_OPENSUBDIV) diff --git a/extern/vulkan_memory_allocator/CMakeLists.txt b/extern/vulkan_memory_allocator/CMakeLists.txt index 0b709e8dda1..666fb824322 100644 --- a/extern/vulkan_memory_allocator/CMakeLists.txt +++ b/extern/vulkan_memory_allocator/CMakeLists.txt @@ -7,6 +7,7 @@ set(INC set(INC_SYS ${VULKAN_INCLUDE_DIRS} + ${MOLTENVK_INCLUDE_DIRS} ) set(SRC diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index ac7dd6ca5cf..3ea91256a3d 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -85,10 +85,12 @@ if(WITH_VULKAN_BACKEND) list(APPEND INC_SYS ${VULKAN_INCLUDE_DIRS} + ${MOLTENVK_INCLUDE_DIRS} ) list(APPEND LIB ${VULKAN_LIBRARIES} + ${MOLTENVK_LIBRARIES} ) add_definitions(-DWITH_VULKAN_BACKEND) diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 554ce065edb..68e77ef9a92 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -287,6 +287,8 @@ if(WITH_VULKAN_BACKEND) ) list(APPEND INC_SYS ${VULKAN_INCLUDE_DIRS} + ${MOLTENVK_INCLUDE_DIRS} + ${SHADERC_INCLUDE_DIRS} ) list(APPEND SRC ${VULKAN_SRC} @@ -294,6 +296,8 @@ if(WITH_VULKAN_BACKEND) list(APPEND LIB ${VULKAN_LIBRARIES} + ${SHADERC_LIBRARIES} + ${MOLTENVK_LIBRARIES} extern_vulkan_memory_allocator ) add_definitions(-DWITH_VULKAN_BACKEND) diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index a0816f41724..22b3d197672 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -1373,6 +1373,13 @@ elseif(APPLE) ) endif() + if(WITH_VULKAN_BACKEND) + install( + FILES ${VULKAN_LIBRARY} ${MOLTENVK_LIBRARY} + DESTINATION ${TARGETDIR_LIB} + ) + endif() + # Python. if(WITH_PYTHON AND NOT WITH_PYTHON_MODULE AND NOT WITH_PYTHON_FRAMEWORK) # Copy the python libraries into the install directory. From 411345757c490fafc9d4aab224ae5e9b137d02a5 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 30 Jan 2023 11:27:23 +0100 Subject: [PATCH 1026/1522] Cleanup: Remove unused variable. Introduced in recent commit. --- source/blender/gpu/metal/mtl_context.mm | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/gpu/metal/mtl_context.mm b/source/blender/gpu/metal/mtl_context.mm index 2f0580a5f63..fc94a40e26d 100644 --- a/source/blender/gpu/metal/mtl_context.mm +++ b/source/blender/gpu/metal/mtl_context.mm @@ -1522,7 +1522,6 @@ void MTLContext::ensure_texture_bindings( @autoreleasepool { int compute_arg_buffer_bind_index = -1; - int null_index = -1; /* Argument buffers are used for samplers, when the limit of 16 is exceeded. * NOTE: Compute uses vertex argument for arg buffer bind index.*/ From 0da74d3ee9ad503be787a5ca5217aa40eda2e768 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 30 Jan 2023 12:23:02 +0100 Subject: [PATCH 1027/1522] GPU: Fix GLSL compilation on OpenGL backend. Regression in {d0f55aa671f7} --- .../blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl index 80d9f9d93fc..2df6ebc33a0 100644 --- a/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl +++ b/source/blender/gpu/shaders/common/gpu_shader_math_matrix_lib.glsl @@ -469,7 +469,7 @@ mat4x4 invert(mat4x4 mat, out bool r_success) return r_success ? inverse(mat) : mat4x4(0.0); } -# ifdef GPU_METAL +# if defined(GPU_OPENGL) || defined(GPU_METAL) vec2 normalize(vec2 a) { return a * inversesqrt(length_squared(a)); From dea924a91fc48ff80548678045d984fafb2d2602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Mon, 30 Jan 2023 12:30:14 +0100 Subject: [PATCH 1028/1522] GPU: Fix incorrectly commited test compilation of all shaders --- source/blender/gpu/intern/gpu_shader_create_info.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc index 9a72dd74944..0e3057ee8c1 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.cc +++ b/source/blender/gpu/intern/gpu_shader_create_info.cc @@ -400,7 +400,7 @@ void gpu_shader_create_info_init() } /* TEST */ - gpu_shader_create_info_compile_all(); + // gpu_shader_create_info_compile_all(); } void gpu_shader_create_info_exit() From 596ee79a9f590c1d66aa1cb5c19f994ddb0f0272 Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Mon, 30 Jan 2023 13:44:46 +0100 Subject: [PATCH 1029/1522] Metal: Optimize shader local memory usage. Due to shader global scope emulation via class interface, global constant arrays in shaders are allocated in per-thread shader local memory. To reduce memory pressure, placing these constant arrays inside function scope will ensure they only reside within device constant memory. This results in a tangible 1.5-2x performance uplift for the specific shaders affected. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D17089 --- .../lightprobe_filter_diffuse_frag.glsl | 17 +++-- .../shaders/overlay_background_frag.glsl | 11 ++- .../shaders/overlay_edit_uv_verts_vert.glsl | 6 +- .../overlay_volume_gridlines_vert.glsl | 19 ++--- .../shaders/overlay_volume_velocity_vert.glsl | 16 ++-- .../gpu_shader_2D_widget_shadow_vert.glsl | 75 ++++++++++--------- .../gpu/shaders/gpu_shader_text_frag.glsl | 44 ++++++----- 7 files changed, 101 insertions(+), 87 deletions(-) diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl index 39c19ad6f74..ce71a73ea75 100644 --- a/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/lightprobe_filter_diffuse_frag.glsl @@ -6,16 +6,17 @@ #define M_4PI 12.5663706143591729 -const mat3 CUBE_ROTATIONS[6] = mat3[]( - mat3(vec3(0.0, 0.0, -1.0), vec3(0.0, -1.0, 0.0), vec3(-1.0, 0.0, 0.0)), - mat3(vec3(0.0, 0.0, 1.0), vec3(0.0, -1.0, 0.0), vec3(1.0, 0.0, 0.0)), - mat3(vec3(1.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0), vec3(0.0, -1.0, 0.0)), - mat3(vec3(1.0, 0.0, 0.0), vec3(0.0, 0.0, -1.0), vec3(0.0, 1.0, 0.0)), - mat3(vec3(1.0, 0.0, 0.0), vec3(0.0, -1.0, 0.0), vec3(0.0, 0.0, -1.0)), - mat3(vec3(-1.0, 0.0, 0.0), vec3(0.0, -1.0, 0.0), vec3(0.0, 0.0, 1.0))); - vec3 get_cubemap_vector(vec2 co, int face) { + /* NOTE(Metal): Declaring constant array in function scope to avoid increasing local shader + * memory pressure. */ + const mat3 CUBE_ROTATIONS[6] = mat3[]( + mat3(vec3(0.0, 0.0, -1.0), vec3(0.0, -1.0, 0.0), vec3(-1.0, 0.0, 0.0)), + mat3(vec3(0.0, 0.0, 1.0), vec3(0.0, -1.0, 0.0), vec3(1.0, 0.0, 0.0)), + mat3(vec3(1.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0), vec3(0.0, -1.0, 0.0)), + mat3(vec3(1.0, 0.0, 0.0), vec3(0.0, 0.0, -1.0), vec3(0.0, 1.0, 0.0)), + mat3(vec3(1.0, 0.0, 0.0), vec3(0.0, -1.0, 0.0), vec3(0.0, 0.0, -1.0)), + mat3(vec3(-1.0, 0.0, 0.0), vec3(0.0, -1.0, 0.0), vec3(0.0, 0.0, 1.0))); return normalize(CUBE_ROTATIONS[face] * vec3(co * 2.0 - 1.0, 1.0)); } diff --git a/source/blender/draw/engines/overlay/shaders/overlay_background_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_background_frag.glsl index 960986bebd5..e104163c11c 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_background_frag.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_background_frag.glsl @@ -4,13 +4,16 @@ /* 4x4 bayer matrix prepared for 8bit UNORM precision error. */ #define P(x) (((x + 0.5) * (1.0 / 16.0) - 0.5) * (1.0 / 255.0)) -const vec4 dither_mat4x4[4] = vec4[4](vec4(P(0.0), P(8.0), P(2.0), P(10.0)), - vec4(P(12.0), P(4.0), P(14.0), P(6.0)), - vec4(P(3.0), P(11.0), P(1.0), P(9.0)), - vec4(P(15.0), P(7.0), P(13.0), P(5.0))); float dither(void) { + /* NOTE(Metal): Declaring constant array in function scope to avoid increasing local shader + * memory pressure. */ + const vec4 dither_mat4x4[4] = vec4[4](vec4(P(0.0), P(8.0), P(2.0), P(10.0)), + vec4(P(12.0), P(4.0), P(14.0), P(6.0)), + vec4(P(3.0), P(11.0), P(1.0), P(9.0)), + vec4(P(15.0), P(7.0), P(13.0), P(5.0))); + ivec2 co = ivec2(gl_FragCoord.xy) % 4; return dither_mat4x4[co.x][co.y]; } diff --git a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_verts_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_verts_vert.glsl index 2a59a623995..99d6c4fcad8 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_verts_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_edit_uv_verts_vert.glsl @@ -1,10 +1,10 @@ #pragma BLENDER_REQUIRE(common_view_lib.glsl) -/* TODO: Theme? */ -const vec4 pinned_col = vec4(1.0, 0.0, 0.0, 1.0); - void main() { + /* TODO: Theme? */ + const vec4 pinned_col = vec4(1.0, 0.0, 0.0, 1.0); + bool is_selected = (flag & (VERT_UV_SELECT | FACE_UV_SELECT)) != 0u; bool is_pinned = (flag & VERT_UV_PINNED) != 0u; vec4 deselect_col = (is_pinned) ? pinned_col : vec4(color.rgb, 1.0); diff --git a/source/blender/draw/engines/overlay/shaders/overlay_volume_gridlines_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_volume_gridlines_vert.glsl index 11a04dddd2a..d4a3059e08a 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_volume_gridlines_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_volume_gridlines_vert.glsl @@ -1,15 +1,6 @@ #pragma BLENDER_REQUIRE(common_view_lib.glsl) -/* Corners for cell outlines. 0.45 is arbitrary. Any value below 0.5 can be used to avoid - * overlapping of the outlines. */ -const vec3 corners[4] = vec3[4](vec3(-0.45, 0.45, 0.0), - vec3(0.45, 0.45, 0.0), - vec3(0.45, -0.45, 0.0), - vec3(-0.45, -0.45, 0.0)); - -const int indices[8] = int[8](0, 1, 1, 2, 2, 3, 3, 0); - vec4 flag_to_color(uint flag) { /* Color mapping for flags */ @@ -88,6 +79,16 @@ void main() } } #endif + /* NOTE(Metal): Declaring constant arrays in function scope to avoid increasing local shader + * memory pressure. */ + const int indices[8] = int[8](0, 1, 1, 2, 2, 3, 3, 0); + + /* Corners for cell outlines. 0.45 is arbitrary. Any value below 0.5 can be used to avoid + * overlapping of the outlines. */ + const vec3 corners[4] = vec3[4](vec3(-0.45, 0.45, 0.0), + vec3(0.45, 0.45, 0.0), + vec3(0.45, -0.45, 0.0), + vec3(-0.45, -0.45, 0.0)); vec3 pos = domainOriginOffset + cellSize * (vec3(cell_co + adaptiveCellOffset) + cell_offset); vec3 rotated_pos = rot_mat * corners[indices[gl_VertexID % 8]]; diff --git a/source/blender/draw/engines/overlay/shaders/overlay_volume_velocity_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_volume_velocity_vert.glsl index a33d27676c3..6cb4dfc903a 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_volume_velocity_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_volume_velocity_vert.glsl @@ -1,13 +1,6 @@ #pragma BLENDER_REQUIRE(common_view_lib.glsl) -const vec3 corners[4] = vec3[4](vec3(0.0, 0.2, -0.5), - vec3(-0.2 * 0.866, -0.2 * 0.5, -0.5), - vec3(0.2 * 0.866, -0.2 * 0.5, -0.5), - vec3(0.0, 0.0, 0.5)); - -const int indices[12] = int[12](0, 1, 1, 2, 2, 0, 0, 3, 1, 3, 2, 3); - /* Straight Port from BKE_defvert_weight_to_rgb() * TODO: port this to a color ramp. */ vec3 weight_to_color(float weight) @@ -177,6 +170,15 @@ void main() mat3 rot_mat = rotation_from_vector(vector); # ifdef USE_NEEDLE + /* NOTE(Metal): Declaring constant arrays in function scope to avoid increasing local shader + * memory pressure. */ + const vec3 corners[4] = vec3[4](vec3(0.0, 0.2, -0.5), + vec3(-0.2 * 0.866, -0.2 * 0.5, -0.5), + vec3(0.2 * 0.866, -0.2 * 0.5, -0.5), + vec3(0.0, 0.0, 0.5)); + + const int indices[12] = int[12](0, 1, 1, 2, 2, 0, 0, 3, 1, 3, 2, 3); + vec3 rotated_pos = rot_mat * corners[indices[gl_VertexID % 12]]; pos += rotated_pos * vector_length * displaySize * cellSize; # else diff --git a/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_vert.glsl b/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_vert.glsl index de1da01ff98..7b64f6b1bfe 100644 --- a/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_2D_widget_shadow_vert.glsl @@ -12,42 +12,6 @@ /* 4bits for corner id */ #define CORNER_VEC_OFS 2u #define CORNER_VEC_RANGE BIT_RANGE(4) -const vec2 cornervec[36] = vec2[36](vec2(0.0, 1.0), - vec2(0.02, 0.805), - vec2(0.067, 0.617), - vec2(0.169, 0.45), - vec2(0.293, 0.293), - vec2(0.45, 0.169), - vec2(0.617, 0.076), - vec2(0.805, 0.02), - vec2(1.0, 0.0), - vec2(-1.0, 0.0), - vec2(-0.805, 0.02), - vec2(-0.617, 0.067), - vec2(-0.45, 0.169), - vec2(-0.293, 0.293), - vec2(-0.169, 0.45), - vec2(-0.076, 0.617), - vec2(-0.02, 0.805), - vec2(0.0, 1.0), - vec2(0.0, -1.0), - vec2(-0.02, -0.805), - vec2(-0.067, -0.617), - vec2(-0.169, -0.45), - vec2(-0.293, -0.293), - vec2(-0.45, -0.169), - vec2(-0.617, -0.076), - vec2(-0.805, -0.02), - vec2(-1.0, 0.0), - vec2(1.0, 0.0), - vec2(0.805, -0.02), - vec2(0.617, -0.067), - vec2(0.45, -0.169), - vec2(0.293, -0.293), - vec2(0.169, -0.45), - vec2(0.076, -0.617), - vec2(0.02, -0.805), - vec2(0.0, -1.0)); #define INNER_FLAG uint(1 << 10) /* is inner vert */ @@ -60,6 +24,45 @@ const vec2 cornervec[36] = vec2[36](vec2(0.0, 1.0), void main() { + /* NOTE(Metal): Declaring constant array in function scope to avoid increasing local shader + * memory pressure.*/ + const vec2 cornervec[36] = vec2[36](vec2(0.0, 1.0), + vec2(0.02, 0.805), + vec2(0.067, 0.617), + vec2(0.169, 0.45), + vec2(0.293, 0.293), + vec2(0.45, 0.169), + vec2(0.617, 0.076), + vec2(0.805, 0.02), + vec2(1.0, 0.0), + vec2(-1.0, 0.0), + vec2(-0.805, 0.02), + vec2(-0.617, 0.067), + vec2(-0.45, 0.169), + vec2(-0.293, 0.293), + vec2(-0.169, 0.45), + vec2(-0.076, 0.617), + vec2(-0.02, 0.805), + vec2(0.0, 1.0), + vec2(0.0, -1.0), + vec2(-0.02, -0.805), + vec2(-0.067, -0.617), + vec2(-0.169, -0.45), + vec2(-0.293, -0.293), + vec2(-0.45, -0.169), + vec2(-0.617, -0.076), + vec2(-0.805, -0.02), + vec2(-1.0, 0.0), + vec2(1.0, 0.0), + vec2(0.805, -0.02), + vec2(0.617, -0.067), + vec2(0.45, -0.169), + vec2(0.293, -0.293), + vec2(0.169, -0.45), + vec2(0.076, -0.617), + vec2(0.02, -0.805), + vec2(0.0, -1.0)); + uint cflag = vflag & CNR_FLAG_RANGE; uint vofs = (vflag >> CORNER_VEC_OFS) & CORNER_VEC_RANGE; diff --git a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl index c1382e301c8..d31d160e776 100644 --- a/source/blender/gpu/shaders/gpu_shader_text_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_text_frag.glsl @@ -1,25 +1,5 @@ #pragma BLENDER_REQUIRE(gpu_shader_colorspace_lib.glsl) -const vec2 offsets4[4] = vec2[4]( - vec2(-0.5, 0.5), vec2(0.5, 0.5), vec2(-0.5, -0.5), vec2(-0.5, -0.5)); - -const vec2 offsets16[16] = vec2[16](vec2(-1.5, 1.5), - vec2(-0.5, 1.5), - vec2(0.5, 1.5), - vec2(1.5, 1.5), - vec2(-1.5, 0.5), - vec2(-0.5, 0.5), - vec2(0.5, 0.5), - vec2(1.5, 0.5), - vec2(-1.5, -0.5), - vec2(-0.5, -0.5), - vec2(0.5, -0.5), - vec2(1.5, -0.5), - vec2(-1.5, -1.5), - vec2(-0.5, -1.5), - vec2(0.5, -1.5), - vec2(1.5, -1.5)); - //#define GPU_NEAREST #define sample_glyph_offset(texel, ofs) \ texture_1D_custom_bilinear_filter(texCoord_interp + ofs * texel) @@ -92,6 +72,11 @@ void main() fragColor.a = 0.0; if (interp_size == 1) { + /* NOTE(Metal): Declaring constant array in function scope to avoid increasing local shader + * memory pressure.*/ + const vec2 offsets4[4] = vec2[4]( + vec2(-0.5, 0.5), vec2(0.5, 0.5), vec2(-0.5, -0.5), vec2(-0.5, -0.5)); + /* 3x3 blur */ /* Manual unroll for perf. (stupid glsl compiler) */ fragColor.a += sample_glyph_offset(texel, offsets4[0]); @@ -101,6 +86,25 @@ void main() fragColor.a *= (1.0 / 4.0); } else { + /* NOTE(Metal): Declaring constant array in function scope to avoid increasing local shader + * memory pressure.*/ + const vec2 offsets16[16] = vec2[16](vec2(-1.5, 1.5), + vec2(-0.5, 1.5), + vec2(0.5, 1.5), + vec2(1.5, 1.5), + vec2(-1.5, 0.5), + vec2(-0.5, 0.5), + vec2(0.5, 0.5), + vec2(1.5, 0.5), + vec2(-1.5, -0.5), + vec2(-0.5, -0.5), + vec2(0.5, -0.5), + vec2(1.5, -0.5), + vec2(-1.5, -1.5), + vec2(-0.5, -1.5), + vec2(0.5, -1.5), + vec2(1.5, -1.5)); + /* 5x5 blur */ /* Manual unroll for perf. (stupid glsl compiler) */ fragColor.a += sample_glyph_offset(texel, offsets16[0]); From 62dd0855a94816a23a00aa0705a7f9624c9d4036 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 30 Jan 2023 14:40:59 +0100 Subject: [PATCH 1030/1522] Cleanup: Remove special handling of 3DCursor in undo code. Such preserve-across-undo data handling is now done through the IDType callbacks, see e.g. `scene_undo_preserve` for the 3DCursor case. --- source/blender/blenloader/intern/readfile.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index f773f17dc2b..2e1619b4c9f 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -2692,9 +2692,6 @@ void blo_lib_link_restore(Main *oldmain, } BKE_workspace_active_set(win->workspace_hook, workspace); - /* keep cursor location through undo */ - memcpy(&win->scene->cursor, &oldscene->cursor, sizeof(win->scene->cursor)); - /* NOTE: even though that function seems to redo part of what is done by * `lib_link_workspace_layout_restore()` above, it seems to have a slightly different scope: * while the former updates the whole UI pointers from Main db (going over all layouts of From d4d4efd3d3c7f98a478df7f08e1eb196537e6e4c Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Mon, 30 Jan 2023 14:43:39 +0100 Subject: [PATCH 1031/1522] GPU: Use create info for compute test cases. Compute test case still used legacy API to construct GLSL shaders. This change will migrate it to use the GPUShaderCreateInfo's. In preparation to run test-cases against non-opengl back-ends. --- source/blender/gpu/tests/gpu_shader_test.cc | 78 ++++++++++----------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/source/blender/gpu/tests/gpu_shader_test.cc b/source/blender/gpu/tests/gpu_shader_test.cc index abf0a007b3a..6cf22dde014 100644 --- a/source/blender/gpu/tests/gpu_shader_test.cc +++ b/source/blender/gpu/tests/gpu_shader_test.cc @@ -24,6 +24,8 @@ namespace blender::gpu::tests { +using namespace blender::gpu::shader; + static void test_gpu_shader_compute_2d() { @@ -37,19 +39,20 @@ static void test_gpu_shader_compute_2d() /* Build compute shader. */ const char *compute_glsl = R"( - -layout(local_size_x = 1, local_size_y = 1) in; -layout(rgba32f, binding = 0) uniform image2D img_output; - void main() { vec4 pixel = vec4(1.0, 0.5, 0.2, 1.0); imageStore(img_output, ivec2(gl_GlobalInvocationID.xy), pixel); } - )"; - GPUShader *shader = GPU_shader_create_compute( - compute_glsl, nullptr, nullptr, "gpu_shader_compute_2d"); + ShaderCreateInfo info(__func__); + info.local_group_size(1, 1) + .image(0, GPU_RGBA32F, Qualifier::WRITE, ImageType::FLOAT_2D, "img_output") + /* Use actual file to not raise any asserts when checking for errors. */ + .compute_source("gpu_shader_common_hash.glsl"); + info.compute_source_generated = compute_glsl; + + GPUShader *shader = GPU_shader_create_from_info((GPUShaderCreateInfo *)&info); EXPECT_NE(shader, nullptr); /* Create texture to store result and attach to shader. */ @@ -96,21 +99,20 @@ static void test_gpu_shader_compute_1d() /* Build compute shader. */ const char *compute_glsl = R"( - -layout(local_size_x = 1) in; - -layout(rgba32f, binding = 1) uniform image1D outputVboData; - void main() { int index = int(gl_GlobalInvocationID.x); vec4 pos = vec4(gl_GlobalInvocationID.x); - imageStore(outputVboData, index, pos); + imageStore(img_output, index, pos); } - )"; - GPUShader *shader = GPU_shader_create_compute( - compute_glsl, nullptr, nullptr, "gpu_shader_compute_1d"); + ShaderCreateInfo info(__func__); + info.local_group_size(1) + .image(1, GPU_RGBA32F, Qualifier::WRITE, ImageType::FLOAT_1D, "img_output") + /* Use actual file to not raise any asserts when checking for errors. */ + .compute_source("gpu_shader_common_hash.glsl"); + info.compute_source_generated = compute_glsl; + GPUShader *shader = GPU_shader_create_from_info((GPUShaderCreateInfo *)&info); EXPECT_NE(shader, nullptr); /* Construct Texture. */ @@ -119,7 +121,7 @@ void main() { EXPECT_NE(texture, nullptr); GPU_shader_bind(shader); - GPU_texture_image_bind(texture, GPU_shader_get_texture_binding(shader, "outputVboData")); + GPU_texture_image_bind(texture, GPU_shader_get_texture_binding(shader, "img_output")); /* Dispatch compute task. */ GPU_compute_dispatch(shader, SIZE, 1, 1); @@ -160,24 +162,20 @@ static void test_gpu_shader_compute_vbo() /* Build compute shader. */ const char *compute_glsl = R"( - -layout(local_size_x = 1) in; - -layout(std430, binding = 0) writeonly buffer outputVboData -{ - vec4 out_positions[]; -}; - void main() { uint index = gl_GlobalInvocationID.x; vec4 pos = vec4(gl_GlobalInvocationID.x); out_positions[index] = pos; } - )"; - GPUShader *shader = GPU_shader_create_compute( - compute_glsl, nullptr, nullptr, "gpu_shader_compute_vbo"); + ShaderCreateInfo info(__func__); + info.local_group_size(1) + .storage_buf(0, Qualifier::WRITE, "vec4", "out_positions[]") + /* Use actual file to not raise any asserts when checking for errors. */ + .compute_source("gpu_shader_common_hash.glsl"); + info.compute_source_generated = compute_glsl; + GPUShader *shader = GPU_shader_create_from_info((GPUShaderCreateInfo *)&info); EXPECT_NE(shader, nullptr); GPU_shader_bind(shader); @@ -186,7 +184,7 @@ void main() { GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); GPUVertBuf *vbo = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_DEVICE_ONLY); GPU_vertbuf_data_alloc(vbo, SIZE); - GPU_vertbuf_bind_as_ssbo(vbo, GPU_shader_get_ssbo(shader, "outputVboData")); + GPU_vertbuf_bind_as_ssbo(vbo, GPU_shader_get_ssbo(shader, "out_positions")); /* Dispatch compute task. */ GPU_compute_dispatch(shader, SIZE, 1, 1); @@ -225,29 +223,25 @@ static void test_gpu_shader_compute_ibo() /* Build compute shader. */ const char *compute_glsl = R"( - -layout(local_size_x = 1) in; - -layout(std430, binding = 1) writeonly buffer outputIboData -{ - uint out_indexes[]; -}; - void main() { uint store_index = int(gl_GlobalInvocationID.x); - out_indexes[store_index] = store_index; + out_indices[store_index] = store_index; } - )"; - GPUShader *shader = GPU_shader_create_compute( - compute_glsl, nullptr, nullptr, "gpu_shader_compute_vbo"); + ShaderCreateInfo info(__func__); + info.local_group_size(1) + .storage_buf(0, Qualifier::WRITE, "uint", "out_indices[]") + /* Use actual file to not raise any asserts when checking for errors. */ + .compute_source("gpu_shader_common_hash.glsl"); + info.compute_source_generated = compute_glsl; + GPUShader *shader = GPU_shader_create_from_info((GPUShaderCreateInfo *)&info); EXPECT_NE(shader, nullptr); GPU_shader_bind(shader); /* Construct IBO. */ GPUIndexBuf *ibo = GPU_indexbuf_build_on_device(SIZE); - GPU_indexbuf_bind_as_ssbo(ibo, GPU_shader_get_ssbo(shader, "outputIboData")); + GPU_indexbuf_bind_as_ssbo(ibo, GPU_shader_get_ssbo(shader, "out_indices")); /* Dispatch compute task. */ GPU_compute_dispatch(shader, SIZE, 1, 1); From aca9c131fc812697575288e7ab3e2946ad62bddd Mon Sep 17 00:00:00 2001 From: Jason Fielder Date: Mon, 30 Jan 2023 14:05:29 +0100 Subject: [PATCH 1032/1522] Metal: Fix issue with premature safe buffer list flush and optimize memory manager overhead. Resolve an issue where released buffers were returned to the reusable memory pool before GPU work associated with these buffers had been encoded. Usually release of memory pools is dependent on successful completion of GPU work via command buffer callbacks. However, if the pool refresh operation occurs between encoding of work and submission, buffer ref-count is prematurely decremented. Patch also ensures safe buffer free lists are only flushed once a set number of buffers have been used. This reduces overhead of small and frequent flushes, without raising the memory ceiling significantly. Authored by Apple: Michael Parkin-White Ref T96261 Reviewed By: fclem Maniphest Tasks: T96261 Differential Revision: https://developer.blender.org/D17118 --- source/blender/gpu/metal/mtl_backend.mm | 6 ++++-- source/blender/gpu/metal/mtl_memory.hh | 13 ++++++++++--- source/blender/gpu/metal/mtl_memory.mm | 12 ++++++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/source/blender/gpu/metal/mtl_backend.mm b/source/blender/gpu/metal/mtl_backend.mm index a195876ab9a..c4a3f38b83b 100644 --- a/source/blender/gpu/metal/mtl_backend.mm +++ b/source/blender/gpu/metal/mtl_backend.mm @@ -152,8 +152,10 @@ void MTLBackend::render_step() * released. */ MTLSafeFreeList *cmd_free_buffer_list = MTLContext::get_global_memory_manager()->get_current_safe_list(); - MTLContext::get_global_memory_manager()->begin_new_safe_list(); - cmd_free_buffer_list->decrement_reference(); + if (cmd_free_buffer_list->should_flush()) { + MTLContext::get_global_memory_manager()->begin_new_safe_list(); + cmd_free_buffer_list->decrement_reference(); + } } bool MTLBackend::is_inside_render_boundary() diff --git a/source/blender/gpu/metal/mtl_memory.hh b/source/blender/gpu/metal/mtl_memory.hh index cce5edeafef..7827dd7607a 100644 --- a/source/blender/gpu/metal/mtl_memory.hh +++ b/source/blender/gpu/metal/mtl_memory.hh @@ -285,6 +285,7 @@ class MTLSafeFreeList { private: std::atomic reference_count_; std::atomic in_free_queue_; + std::atomic referenced_by_workload_; std::recursive_mutex lock_; /* Linked list of next MTLSafeFreeList chunk if current chunk is full. */ @@ -292,8 +293,12 @@ class MTLSafeFreeList { std::atomic next_; /* Lockless list. MAX_NUM_BUFFERS_ within a chunk based on considerations - * for performance and memory. */ + * for performance and memory. + * MIN_BUFFER_FLUSH_COUNT refers to the minimum count of buffers in the MTLSafeFreeList + * before buffers are returned to global memory pool. This is set at a point to reduce + * overhead of small pool flushes, while ensuring floating memory overhead is not excessive. */ static const int MAX_NUM_BUFFERS_ = 1024; + static const int MIN_BUFFER_FLUSH_COUNT = 120; std::atomic current_list_index_; gpu::MTLBuffer *safe_free_pool_[MAX_NUM_BUFFERS_]; @@ -304,11 +309,13 @@ class MTLSafeFreeList { * Performs a lockless list insert. */ void insert_buffer(gpu::MTLBuffer *buffer); + /* Whether we need ot start a new safe free list, or can carry on using the existing one. */ + bool should_flush(); + /* Increments command buffer reference count. */ void increment_reference(); - /* Decrement and return of buffers to pool occur on MTLCommandBuffer completion callback thread. - */ + /* Decrement and return of buffers to pool occur on MTLCommandBuffer completion callback. */ void decrement_reference(); void flag_in_queue() diff --git a/source/blender/gpu/metal/mtl_memory.mm b/source/blender/gpu/metal/mtl_memory.mm index 101dee2794e..1d6d4ad7330 100644 --- a/source/blender/gpu/metal/mtl_memory.mm +++ b/source/blender/gpu/metal/mtl_memory.mm @@ -433,6 +433,7 @@ void MTLSafeFreeList::increment_reference() lock_.lock(); BLI_assert(in_free_queue_ == false); reference_count_++; + referenced_by_workload_ = true; lock_.unlock(); } @@ -450,6 +451,17 @@ void MTLSafeFreeList::decrement_reference() lock_.unlock(); } +bool MTLSafeFreeList::should_flush() +{ + /* We should only consider refreshing a list if it has been referenced by active workloads, and + * contains a sufficient buffer count to avoid overheads associated with flushing the list. If + * the reference count is only equal to 1, buffers may have been added, but no command + * submissions will have been issued, hence buffers could be returned to the pool prematurely if + * associated workload submission occurs later. */ + return ((reference_count_ > 1 || referenced_by_workload_) && + current_list_index_ > MIN_BUFFER_FLUSH_COUNT); +} + /** \} */ /* -------------------------------------------------------------------- */ From 1a50f814e6aad72bb8da7e571cee49ac4022ed84 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 30 Jan 2023 15:40:29 +0100 Subject: [PATCH 1033/1522] Cleanup: Remove unused variable, use switch, and C++ casting. --- source/blender/blenloader/intern/readfile.cc | 409 ++++++++++--------- 1 file changed, 218 insertions(+), 191 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 2e1619b4c9f..c440dbf8c7a 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -2299,11 +2299,11 @@ static bool lib_link_seq_clipboard_cb(Sequence *seq, void *arg_pt) { IDNameLib_Map *id_map = static_cast(arg_pt); - lib_link_seq_clipboard_pt_restore((ID *)seq->scene, id_map); - lib_link_seq_clipboard_pt_restore((ID *)seq->scene_camera, id_map); - lib_link_seq_clipboard_pt_restore((ID *)seq->clip, id_map); - lib_link_seq_clipboard_pt_restore((ID *)seq->mask, id_map); - lib_link_seq_clipboard_pt_restore((ID *)seq->sound, id_map); + lib_link_seq_clipboard_pt_restore(reinterpret_cast(seq->scene), id_map); + lib_link_seq_clipboard_pt_restore(reinterpret_cast(seq->scene_camera), id_map); + lib_link_seq_clipboard_pt_restore(reinterpret_cast(seq->clip), id_map); + lib_link_seq_clipboard_pt_restore(reinterpret_cast(seq->mask), id_map); + lib_link_seq_clipboard_pt_restore(reinterpret_cast(seq->sound), id_map); return true; } @@ -2325,7 +2325,7 @@ static int lib_link_main_data_restore_cb(LibraryIDLinkCallbackData *cb_data) /* We probably need to add more cases here (hint: nodetrees), * but will wait for changes from D5559 to get in first. */ if (GS((*id_pointer)->name) == ID_GR) { - Collection *collection = (Collection *)*id_pointer; + Collection *collection = reinterpret_cast(*id_pointer); if (collection->flag & COLLECTION_IS_MASTER) { /* We should never reach that point anymore, since master collection private ID should be * properly tagged with IDWALK_CB_EMBEDDED. */ @@ -2357,7 +2357,7 @@ static void lib_link_main_data_restore(IDNameLib_Map *id_map, Main *newmain) static void lib_link_wm_xr_data_restore(IDNameLib_Map *id_map, wmXrData *xr_data) { xr_data->session_settings.base_pose_object = static_cast(restore_pointer_by_name( - id_map, (ID *)xr_data->session_settings.base_pose_object, USER_REAL)); + id_map, reinterpret_cast(xr_data->session_settings.base_pose_object), USER_REAL)); } static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene, ViewLayer *view_layer) @@ -2367,7 +2367,7 @@ static void lib_link_window_scene_data_restore(wmWindow *win, Scene *scene, View LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_VIEW3D) { - View3D *v3d = (View3D *)sl; + View3D *v3d = reinterpret_cast(sl); if (v3d->camera == nullptr || v3d->scenelock) { v3d->camera = scene->camera; @@ -2416,7 +2416,7 @@ static void lib_link_restore_viewer_path(IDNameLib_Map *id_map, ViewerPath *view if (elem->type == VIEWER_PATH_ELEM_TYPE_ID) { IDViewerPathElem *typed_elem = reinterpret_cast(elem); typed_elem->id = static_cast( - restore_pointer_by_name(id_map, (ID *)typed_elem->id, USER_IGNORE)); + restore_pointer_by_name(id_map, typed_elem->id, USER_IGNORE)); } } } @@ -2431,225 +2431,253 @@ static void lib_link_workspace_layout_restore(IDNameLib_Map *id_map, { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { - if (sl->spacetype == SPACE_VIEW3D) { - View3D *v3d = (View3D *)sl; + switch (static_cast(sl->spacetype)) { + case SPACE_VIEW3D: { + View3D *v3d = reinterpret_cast(sl); - v3d->camera = static_cast( - restore_pointer_by_name(id_map, (ID *)v3d->camera, USER_REAL)); - v3d->ob_center = static_cast( - restore_pointer_by_name(id_map, (ID *)v3d->ob_center, USER_REAL)); + v3d->camera = static_cast( + restore_pointer_by_name(id_map, reinterpret_cast(v3d->camera), USER_REAL)); + v3d->ob_center = static_cast(restore_pointer_by_name( + id_map, reinterpret_cast(v3d->ob_center), USER_REAL)); - lib_link_restore_viewer_path(id_map, &v3d->viewer_path); - } - else if (sl->spacetype == SPACE_GRAPH) { - SpaceGraph *sipo = (SpaceGraph *)sl; - bDopeSheet *ads = sipo->ads; + lib_link_restore_viewer_path(id_map, &v3d->viewer_path); + break; + } + case SPACE_GRAPH: { + SpaceGraph *sipo = reinterpret_cast(sl); + bDopeSheet *ads = sipo->ads; - if (ads) { - ads->source = static_cast( - restore_pointer_by_name(id_map, (ID *)ads->source, USER_REAL)); + if (ads) { + ads->source = static_cast( + restore_pointer_by_name(id_map, reinterpret_cast(ads->source), USER_REAL)); - if (ads->filter_grp) { - ads->filter_grp = static_cast( - restore_pointer_by_name(id_map, (ID *)ads->filter_grp, USER_IGNORE)); + if (ads->filter_grp) { + ads->filter_grp = static_cast(restore_pointer_by_name( + id_map, reinterpret_cast(ads->filter_grp), USER_IGNORE)); + } } + + /* force recalc of list of channels (i.e. includes calculating F-Curve colors) + * thus preventing the "black curves" problem post-undo + */ + sipo->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR; + break; } + case SPACE_PROPERTIES: { + SpaceProperties *sbuts = reinterpret_cast(sl); + sbuts->pinid = static_cast( + restore_pointer_by_name(id_map, sbuts->pinid, USER_IGNORE)); + if (sbuts->pinid == nullptr) { + sbuts->flag &= ~SB_PIN_CONTEXT; + } - /* force recalc of list of channels (i.e. includes calculating F-Curve colors) - * thus preventing the "black curves" problem post-undo - */ - sipo->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR; - } - else if (sl->spacetype == SPACE_PROPERTIES) { - SpaceProperties *sbuts = (SpaceProperties *)sl; - sbuts->pinid = static_cast( - restore_pointer_by_name(id_map, sbuts->pinid, USER_IGNORE)); - if (sbuts->pinid == nullptr) { - sbuts->flag &= ~SB_PIN_CONTEXT; + /* TODO: restore path pointers: T40046 + * (complicated because this contains data pointers too, not just ID). */ + MEM_SAFE_FREE(sbuts->path); + break; } - - /* TODO: restore path pointers: T40046 - * (complicated because this contains data pointers too, not just ID). */ - MEM_SAFE_FREE(sbuts->path); - } - else if (sl->spacetype == SPACE_FILE) { - SpaceFile *sfile = (SpaceFile *)sl; - sfile->op = nullptr; - sfile->tags = FILE_TAG_REBUILD_MAIN_FILES; - } - else if (sl->spacetype == SPACE_ACTION) { - SpaceAction *saction = (SpaceAction *)sl; - - saction->action = static_cast( - restore_pointer_by_name(id_map, (ID *)saction->action, USER_REAL)); - saction->ads.source = static_cast( - restore_pointer_by_name(id_map, (ID *)saction->ads.source, USER_REAL)); - - if (saction->ads.filter_grp) { - saction->ads.filter_grp = static_cast( - restore_pointer_by_name(id_map, (ID *)saction->ads.filter_grp, USER_IGNORE)); + case SPACE_FILE: { + SpaceFile *sfile = reinterpret_cast(sl); + sfile->op = nullptr; + sfile->tags = FILE_TAG_REBUILD_MAIN_FILES; + break; } + case SPACE_ACTION: { + SpaceAction *saction = reinterpret_cast(sl); - /* force recalc of list of channels, potentially updating the active action - * while we're at it (as it can only be updated that way) T28962. - */ - saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC; - } - else if (sl->spacetype == SPACE_IMAGE) { - SpaceImage *sima = (SpaceImage *)sl; + saction->action = static_cast(restore_pointer_by_name( + id_map, reinterpret_cast(saction->action), USER_REAL)); + saction->ads.source = static_cast(restore_pointer_by_name( + id_map, reinterpret_cast(saction->ads.source), USER_REAL)); - sima->image = static_cast( - restore_pointer_by_name(id_map, (ID *)sima->image, USER_REAL)); + if (saction->ads.filter_grp) { + saction->ads.filter_grp = static_cast(restore_pointer_by_name( + id_map, reinterpret_cast(saction->ads.filter_grp), USER_IGNORE)); + } - /* this will be freed, not worth attempting to find same scene, - * since it gets initialized later */ - sima->iuser.scene = nullptr; + /* force recalc of list of channels, potentially updating the active action + * while we're at it (as it can only be updated that way) T28962. + */ + saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC; + break; + } + case SPACE_IMAGE: { + SpaceImage *sima = reinterpret_cast(sl); + + sima->image = static_cast( + restore_pointer_by_name(id_map, reinterpret_cast(sima->image), USER_REAL)); + + /* this will be freed, not worth attempting to find same scene, + * since it gets initialized later */ + sima->iuser.scene = nullptr; #if 0 - /* Those are allocated and freed by space code, no need to handle them here. */ - MEM_SAFE_FREE(sima->scopes.waveform_1); - MEM_SAFE_FREE(sima->scopes.waveform_2); - MEM_SAFE_FREE(sima->scopes.waveform_3); - MEM_SAFE_FREE(sima->scopes.vecscope); + /* Those are allocated and freed by space code, no need to handle them here. */ + MEM_SAFE_FREE(sima->scopes.waveform_1); + MEM_SAFE_FREE(sima->scopes.waveform_2); + MEM_SAFE_FREE(sima->scopes.waveform_3); + MEM_SAFE_FREE(sima->scopes.vecscope); #endif - sima->scopes.ok = 0; + sima->scopes.ok = 0; - /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data - * so assume that here we're doing for undo only... - */ - sima->gpd = static_cast( - restore_pointer_by_name(id_map, (ID *)sima->gpd, USER_REAL)); - sima->mask_info.mask = static_cast( - restore_pointer_by_name(id_map, (ID *)sima->mask_info.mask, USER_REAL)); - } - else if (sl->spacetype == SPACE_SEQ) { - SpaceSeq *sseq = (SpaceSeq *)sl; + /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data + * so assume that here we're doing for undo only... + */ + sima->gpd = static_cast( + restore_pointer_by_name(id_map, reinterpret_cast(sima->gpd), USER_REAL)); + sima->mask_info.mask = static_cast(restore_pointer_by_name( + id_map, reinterpret_cast(sima->mask_info.mask), USER_REAL)); + break; + } + case SPACE_SEQ: { + SpaceSeq *sseq = reinterpret_cast(sl); - /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data - * so assume that here we're doing for undo only... - */ - sseq->gpd = static_cast( - restore_pointer_by_name(id_map, (ID *)sseq->gpd, USER_REAL)); - } - else if (sl->spacetype == SPACE_NLA) { - SpaceNla *snla = (SpaceNla *)sl; - bDopeSheet *ads = snla->ads; + /* NOTE: pre-2.5, this was local data not lib data, but now we need this as lib data + * so assume that here we're doing for undo only... + */ + sseq->gpd = static_cast( + restore_pointer_by_name(id_map, reinterpret_cast(sseq->gpd), USER_REAL)); + break; + } + case SPACE_NLA: { + SpaceNla *snla = reinterpret_cast(sl); + bDopeSheet *ads = snla->ads; - if (ads) { - ads->source = static_cast( - restore_pointer_by_name(id_map, (ID *)ads->source, USER_REAL)); + if (ads) { + ads->source = static_cast( + restore_pointer_by_name(id_map, reinterpret_cast(ads->source), USER_REAL)); - if (ads->filter_grp) { - ads->filter_grp = static_cast( - restore_pointer_by_name(id_map, (ID *)ads->filter_grp, USER_IGNORE)); + if (ads->filter_grp) { + ads->filter_grp = static_cast(restore_pointer_by_name( + id_map, reinterpret_cast(ads->filter_grp), USER_IGNORE)); + } } + break; } - } - else if (sl->spacetype == SPACE_TEXT) { - SpaceText *st = (SpaceText *)sl; + case SPACE_TEXT: { + SpaceText *st = reinterpret_cast(sl); - st->text = static_cast( - restore_pointer_by_name(id_map, (ID *)st->text, USER_IGNORE)); - if (st->text == nullptr) { - st->text = static_cast(newmain->texts.first); + st->text = static_cast( + restore_pointer_by_name(id_map, reinterpret_cast(st->text), USER_IGNORE)); + if (st->text == nullptr) { + st->text = static_cast(newmain->texts.first); + } + } break; + case SPACE_SCRIPT: { + SpaceScript *scpt = reinterpret_cast(sl); + + scpt->script = static_cast